Geant4 10.7.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4UIQt.cc
Go to the documentation of this file.
1//
2// ********************************************************************
3// * License and Disclaimer *
4// * *
5// * The Geant4 software is copyright of the Copyright Holders of *
6// * the Geant4 Collaboration. It is provided under the terms and *
7// * conditions of the Geant4 Software License, included in the file *
8// * LICENSE and available at http://cern.ch/geant4/license . These *
9// * include a list of copyright holders. *
10// * *
11// * Neither the authors of this software system, nor their employing *
12// * institutes,nor the agencies providing financial support for this *
13// * work make any representation or warranty, express or implied, *
14// * regarding this software system or assume any liability for its *
15// * use. Please see the license in the file LICENSE and URL above *
16// * for the full disclaimer and the limitation of liability. *
17// * *
18// * This code implementation is the result of the scientific and *
19// * technical work of the GEANT4 collaboration. *
20// * By using, copying, modifying or distributing the software (or *
21// * any work based on the software) you agree to acknowledge its *
22// * use in resulting scientific publications, and indicate your *
23// * acceptance of all terms of the Geant4 Software license. *
24// ********************************************************************
25//
26//
27//
28// L. Garnier
29
30#ifdef G4UI_BUILD_QT_SESSION
31
32#include "G4Types.hh"
33
34#include <string.h>
35
36#include "G4UIQt.hh"
37#include "G4UImanager.hh"
38#include "G4UIcommand.hh"
39#include "G4StateManager.hh"
40#include "G4UIcommandTree.hh"
41#include "G4UIcommandStatus.hh"
43#include "G4Qt.hh"
44
45#include <qapplication.h>
46#include <qmessagebox.h>
47#include <qlineedit.h>
48#include <qwidget.h>
49#include <qmenubar.h>
50#include <qlayout.h>
51#include <qpushbutton.h>
52#include <qlabel.h>
53#include <qsplitter.h>
54#include <qscrollbar.h>
55#include <qdialog.h>
56#include <qevent.h>
57#include <qtextedit.h>
58#if QT_VERSION < 0x050600
59#include <qsignalmapper.h>
60#endif
61#include <qtabwidget.h>
62#include <qtabbar.h>
63#include <qstringlist.h>
64#include <qtextstream.h>
65
66#include <qmainwindow.h>
67#include <qmenu.h>
68#include <qlistwidget.h>
69#include <qtreewidget.h>
70#include <qheaderview.h>
71#include <qgroupbox.h>
72#include <qscrollarea.h>
73#include <qtoolbox.h>
74#include <qradiobutton.h>
75#include <qbuttongroup.h>
76#include <qcombobox.h>
77#include <qpainter.h>
78#include <qcolordialog.h>
79#include <qtoolbar.h>
80#include <qfiledialog.h>
81#include <qdesktopwidget.h>
82#include <qtablewidget.h>
83#include <qcompleter.h>
84#include <qstandarditemmodel.h>
85#include <qboxlayout.h>
86#include <stdlib.h>
87
88#ifndef G4GMAKE
89#include "moc_G4UIQt.cpp"
90#endif
91
92// Pourquoi Static et non variables de classe ?
93static G4bool exitSession = true;
94static G4bool exitPause = true;
95
96/** Build a Qt window with a menubar, output area and promt area<br>
97<pre>
98 +-----------------------+
99 |exit menu| |
100 | |
101 | +-------------------+ |
102 | | | |
103 | | Output area | |
104 | | | |
105 | +-------------------+ |
106 | | clear | |
107 | +-------------------+ |
108 | | promt history | |
109 | +-------------------+ |
110 | +-------------------+ |
111 | |> promt area | |
112 | +-------------------+ |
113 +-----------------------+
114</pre>
115*/
116G4UIQt::G4UIQt (
117 int argc
118,char** argv
119)
120:fMainWindow(NULL)
121,fCommandLabel(NULL)
122,fCommandArea(NULL)
123,fCoutTBTextArea(NULL)
124,fUITabWidget(NULL)
125,fCoutFilter(NULL)
126,fCompleter(NULL)
127,fDefaultIcons(true)
128,fHistoryTBTableList(NULL)
129,fHelpTreeWidget(NULL)
130,fHelpTBWidget(NULL)
131,fHistoryTBWidget(NULL)
132,fCoutDockWidget(NULL)
133,fUIDockWidget(NULL)
134,fSceneTreeWidget(NULL)
135,fViewerPropertiesWidget(NULL)
136,fPickInfosWidget(NULL)
137,fHelpLine(NULL)
138,fViewerTabWidget(NULL)
139,fCoutText("Output")
140,fStartPage(NULL)
141,fHelpVSplitter(NULL)
142,fParameterHelpLabel(NULL)
143,fParameterHelpTable(NULL)
144,fToolbarApp(NULL)
145,fToolbarUser(NULL)
146,fStringSeparator("__$$$@%%###__")
147,fLastOpenPath("")
148,fSearchIcon(NULL)
149,fClearIcon(NULL)
150,fSaveIcon(NULL)
151,fOpenIcon(NULL)
152,fMoveIcon(NULL)
153,fRotateIcon(NULL)
154,fPickIcon(NULL)
155,fZoomInIcon(NULL)
156,fZoomOutIcon(NULL)
157,fWireframeIcon(NULL)
158,fSolidIcon(NULL)
159,fHiddenLineRemovalIcon(NULL)
160,fHiddenLineAndSurfaceRemovalIcon(NULL)
161,fPerspectiveIcon(NULL)
162,fOrthoIcon(NULL)
163,fCommandIcon(NULL)
164,fDirIcon(NULL)
165,fRunIcon(NULL)
166,fParamIcon(NULL)
167,fPickTargetIcon(NULL)
168#ifdef G4MULTITHREADED
169,fThreadsFilterComboBox(NULL)
170#endif
171,fDefaultViewerFirstPageHTMLText("")
172,fViewerPropertiesDialog(NULL)
173,fPickInfosDialog(NULL)
174,fLastCompleteCommand("")
175,fMoveSelected(false)
176,fRotateSelected(true)
177,fPickSelected(false)
178,fZoomInSelected(false)
179,fZoomOutSelected(false)
180{
181
182 G4Qt* interactorManager = G4Qt::getInstance (argc,argv,(char*)"Qt");
183 if (!(QApplication*)interactorManager->GetMainInteractor()) {
185 G4int verbose = UImanager->GetVerboseLevel();
186
187 if (verbose >= 2) {
188 G4cout << "G4UIQt : Unable to init Qt. Aborted" << G4endl;
189 }
190 }
191
193 if(UI!=NULL) UI->SetSession(this);
194 if(UI!=NULL) UI->SetG4UIWindow(this);
195
196 // Check if already define in external app QMainWindow
197 bool found = false;
198 Q_FOREACH (QWidget *widget, QApplication::allWidgets()) {
199 if ((found== false) && (widget->inherits("QMainWindow"))) {
200 found = true;
201 }
202 }
203
204 if (found) {
206 G4int verbose = UImanager->GetVerboseLevel();
207
208 if (verbose >= 2) {
209 G4cout << "G4UIQt : Found an external App with a QMainWindow already defined. Aborted" << G4endl;
210 }
211 return ;
212 }
213 CreateIcons();
214
215 fMainWindow = new QMainWindow();
216 fMainWindow->setAttribute(Qt::WA_DeleteOnClose);
217
218 fMainWindow->setCorner( Qt::TopLeftCorner, Qt::LeftDockWidgetArea );
219 fMainWindow->setCorner( Qt::TopRightCorner, Qt::RightDockWidgetArea );
220 fMainWindow->setCorner( Qt::BottomLeftCorner, Qt::LeftDockWidgetArea );
221 fMainWindow->setCorner( Qt::BottomRightCorner, Qt::RightDockWidgetArea );
222
223 CreateViewerWidget();
224 fMainWindow->addDockWidget(Qt::LeftDockWidgetArea, CreateUITabWidget());
225 fMainWindow->addDockWidget(Qt::BottomDockWidgetArea, CreateCoutTBWidget());
226
227
228 // add defaults icons
229 SetDefaultIconsToolbar();
230
231 if(UI!=NULL) UI->SetCoutDestination(this); // TO KEEP
232
233#ifdef G4MULTITHREADED
234 // explicitly request that cout/cerr messages from threads are ALSO propagated to the master.
235 masterG4coutDestination = this;
236#endif
237
238 fMainWindow->setWindowTitle(QFileInfo( QCoreApplication::applicationFilePath() ).fileName());
239 fMainWindow->move(QPoint(50,50));
240
241 // force the size at be correct at the beggining
242 // because the widget is not realized yet, the size of the main window is not up to date. But
243 // we need it in order to add some viewer inside
244 fMainWindow->resize(fUIDockWidget->width()+fCoutDockWidget->width()+20,
245 fUIDockWidget->height()+fCoutDockWidget->height()+20);
246
247 // set last focus on command line
248 fCommandArea->setFocus(Qt::TabFocusReason);
249
250 // Allow QTextCursor to be called by another thread :
251 // http://qt-project.org/doc/qt-4.8/qmetatype.html#qRegisterMetaType
252 qRegisterMetaType<QTextCursor>("QTextCursor");
253
254 // add some tips
255 AddTabWidget(fStartPage,"Useful tips");
256
257 // Set not visible until session start
258 #if QT_VERSION < 0x040200
259 fMainWindow->hide();
260 #else
261 fMainWindow->setVisible(false);
262 #endif
263}
264
265
266
267G4UIQt::~G4UIQt(
268)
269{
270 G4UImanager* UI = G4UImanager::GetUIpointer(); // TO KEEP
271 if(UI!=NULL) { // TO KEEP
272 UI->SetSession(NULL); // TO KEEP
273 UI->SetG4UIWindow(NULL);
274 UI->SetCoutDestination(0); // TO KEEP
275#ifdef G4MULTITHREADED
276 masterG4coutDestination = 0; // set to cout when UI is deleted
277#endif
278 }
279}
280
281
282void G4UIQt::DefaultIcons(bool aVal)
283{
284 fDefaultIcons = aVal;
285
286#if QT_VERSION < 0x040200
287 if (!fMainWindow->isHidden()) {
288#else
289 if (!fMainWindow->isVisible()) {
290#endif
291 return;
292 }
293
294 if (fToolbarApp) {
295 if (aVal) {
296#if QT_VERSION < 0x040200
297 fToolbarApp->show();
298#else
299 fToolbarApp->setVisible(true);
300#endif
301 } else {
302 // Set not visible until session start
303#if QT_VERSION < 0x040200
304 fToolbarApp->hide();
305#else
306 fToolbarApp->setVisible(false);
307#endif
308 }
309 }
310}
311
312
313void G4UIQt::SetDefaultIconsToolbar(
314) {
315
316 if (fDefaultIcons) {
317 if (fToolbarApp == NULL) {
318 fToolbarApp = new QToolBar();
319 fToolbarApp->setIconSize (QSize(20,20));
320 fMainWindow->addToolBar(Qt::TopToolBarArea, fToolbarApp);
321 }
322
323 // Open/Save Icons
324 AddIcon("Open macro file","open", "/control/execute");
325 AddIcon("Save viewer state", "save", "/vis/viewer/save");
326
327 // View parameters
328#if QT_VERSION < 0x050600
329 QSignalMapper *signalMapperViewerProperties = new QSignalMapper(this);
330 QAction *actionViewerProperties = fToolbarApp->addAction(QIcon(*fParamIcon),"Viewer properties", signalMapperViewerProperties, SLOT(map()));
331 connect(signalMapperViewerProperties, SIGNAL(mapped(int)),this, SLOT(ViewerPropertiesIconCallback(int)));
332 int intVP = 0;
333 signalMapperViewerProperties->setMapping(actionViewerProperties, intVP);
334#else
335 fToolbarApp->addAction(QIcon(*fParamIcon),"Viewer properties", this, [=](){ this->ViewerPropertiesIconCallback(0); });
336#endif
337
338 // Cursors style icons
339 AddIcon("Move", "move", "");
340 AddIcon("Pick", "pick", "");
341 AddIcon("Zoom out", "zoom_out", "");
342 AddIcon("Zoom in", "zoom_in", "");
343 AddIcon("Rotate", "rotate", "");
344
345 // Surface Style icons
346 AddIcon("Hidden line removal", "hidden_line_removal", "");
347 AddIcon("Hidden line and hidden surface removal", "hidden_line_and_surface_removal", "");
348 AddIcon("Surfaces", "solid", "");
349 AddIcon("Wireframe", "wireframe", "");
350
351 // Perspective/Ortho icons
352 AddIcon("Perspective", "perspective","");
353 AddIcon("Orthographic", "ortho","");
354 AddIcon("Run beam on", "runBeamOn","/run/beamOn 1");
355 }
356}
357
358
359void G4UIQt::CreateIcons(
360)
361{
362 const char * const save[]={
363 "32 32 24 1",
364 " c None",
365 "+ c #000200",
366 "@ c #141E43",
367 "# c #000C56",
368 "$ c #494A47",
369 "% c #636662",
370 "& c #312F2A",
371 "* c #191B19",
372 "= c #002992",
373 "- c #003DFF",
374 "; c #041DA5",
375 "> c #A8A9A3",
376 ", c #FDFFFC",
377 "' c #DDE0DD",
378 ") c #818783",
379 "! c #C9CBC8",
380 "~ c #0116C3",
381 "{ c #C5C8FA",
382 "] c #6596FC",
383 "^ c #A0B4F9",
384 "/ c #0B2AFD",
385 "( c #799BE3",
386 "_ c #5F4826",
387 ": c #D5D8D5",
388 " ",
389 " ",
390 " +++++++++++++++++++++++++ ",
391 " +@##+$%%%%%%%%%%%%%%%&*$%&+ ",
392 " +=-;@>,,''',,,,,,,',,)&!,)+ ",
393 " +;-~@>,,,,,,,,,,,,,,,>$!,)+ ",
394 " +=-~@>,,,,,{]]]]]^,,,>*&$&+ ",
395 " +=-~@>,,,,,'{^{^^{,,,>*#=#+ ",
396 " +=-~@>,,,,,,,,,,,,,,,>@~/=+ ",
397 " +=-~@>,,,{{{''''{',,,>@~-=+ ",
398 " +=-~@>,,'^]]]]]]({,,,>@~-=+ ",
399 " +=-~@>,,,{{{{{{{{{,,,>@~-=+ ",
400 " +=-~@>,,,,,'{^{{^{,,,>@~-=+ ",
401 " +=-~@>,,,,,]]]]]]],,,>@~-=+ ",
402 " +=-~*>,,,,,,,,,,,,,,,>@~-=+ ",
403 " +=-~@>,,,,,,,,,,,,,,,>@~-=+ ",
404 " +=-/=$%%%%%%%%%%%%%%%$=/-=+ ",
405 " +=---;###############;---=+ ",
406 " +=---////////////////----=+ ",
407 " +=----------------///----=+ ",
408 " +=---=@##############@#--=+ ",
409 " +=---@+++++++++++*%))_+~-=+ ",
410 " +=---#+++++++++++&:,,>@~-=+ ",
411 " +=---#+++++++++++$',,>@~-=+ ",
412 " +=---#+++++++++++&!,,>@~-=+ ",
413 " +=/--#+++++++++++&',,>@~-=+ ",
414 " @;--#+++++++++++$',,>@~-=+ ",
415 " @;;@+++++++++++*)!>%@=;#+ ",
416 " @++++++++++++++*&**++@++ ",
417 " ",
418 " ",
419 " "}
420 ;
421 fSaveIcon = new QPixmap(save);
422
423 const char * const search[] = {
424 /* columns rows colors chars-per-pixel */
425 "19 19 8 1",
426 " c #5C5C5C",
427 ". c #7D7D7D",
428 "X c #9B9B9B",
429 "o c #C3C3C3",
430 "O c None",
431 "+ c #000000",
432 "@ c #000000",
433 "# c None",
434 /* pixels */
435 "OOOOOOOOOOOOOOOOOOO",
436 "OOOOOOOOOOOOOOOOOOO",
437 "OOOOOOOo. .oOOOOOO",
438 "OOOOOOX XOOOOO",
439 "OOOOOo XOOX oOOOO",
440 "OOOOO. XOOOOX .OOOO",
441 "OOOOO OOOOOO OOOO",
442 "OOOOO OOOOOO OOOO",
443 "OOOOO. XOOOOo .OOOO",
444 "OOOOOo oOOo oOOOO",
445 "OOOOOOX XOOOO",
446 "OOOOOOOo. . XOOO",
447 "OOOOOOOOOOOOO. XOO",
448 "OOOOOOOOOOOOOO. XOO",
449 "OOOOOOOOOOOOOOOoOOO",
450 "OOOOOOOOOOOOOOOOOOO",
451 "OOOOOOOOOOOOOOOOOOO",
452 "OOOOOOOOOOOOOOOOOOO",
453 "OOOOOOOOOOOOOOOOOOO"
454 };
455 fSearchIcon = new QPixmap(search);
456
457 const char * const clear[] = {
458 /* columns rows colors chars-per-pixel */
459 "20 20 8 1",
460 " c #020202",
461 ". c #202020",
462 "X c #2C2C2C",
463 "o c #797979",
464 "O c None",
465 "+ c #797979",
466 "@ c #797979",
467 "# c #797979",
468 /* pixels */
469 "OOOOOOOOOOOOOOOOOOOO",
470 "OOOOOOOo oOOOOOOO",
471 "OOOOOXX XXOOOOO",
472 "OOOOOOOOOOOOOOOOOOOO",
473 "OOOOOOOOOOOOOOOOOOOO",
474 "OOOO XXXXXXXXXX OOOO",
475 "OOO XOOOOOOOOOO OOO",
476 "OOOOXOooOooOooO OOOO",
477 "OOOOXOooOooOooO OOOO",
478 "OOOOXOooOooOooO OOOO",
479 "OOOOXOooOooOooO OOOO",
480 "OOOOXOooOooOooO OOOO",
481 "OOOOXOooOooOooO OOOO",
482 "OOOOXOooOooOooO OOOO",
483 "OOOOXOooOooOooO OOOO",
484 "OOOOXOooOooOooO OOOO",
485 "OOOOXOooOooOooO OOOO",
486 "OOOOXOOOOOOOOOO OOOO",
487 "OOOOOooooooooooOOOOO",
488 "OOOOOO........OOOOOO"
489 };
490
491 fClearIcon = new QPixmap(clear);
492
493
494 const char * const open[]={
495 "32 32 33 1",
496 " c None",
497 "+ c #09091E",
498 "@ c #191B18",
499 "# c #5F615F",
500 "$ c #777977",
501 "% c #AEB1AF",
502 "& c #929491",
503 "* c #515250",
504 "= c #858784",
505 "- c #333533",
506 "; c #000100",
507 "> c #272926",
508 ", c #424341",
509 "' c #696C6A",
510 ") c #5F4927",
511 "! c #583D18",
512 "~ c #6E6A5B",
513 "{ c #47351D",
514 "] c #E0A554",
515 "^ c #FFD67B",
516 "/ c #EFB465",
517 "( c #FDBF6C",
518 "_ c #FFCD76",
519 ": c #806238",
520 "< c #362611",
521 "[ c #0B0D0A",
522 "} c #68471B",
523 "| c #523E22",
524 "1 c #B78A51",
525 "2 c #A17B44",
526 "3 c #D6A45E",
527 "4 c #C29354",
528 "5 c #A1A3A0",
529 " ",
530 " ",
531 " +@@@# ",
532 " $% +& * ",
533 " #= $ -; ",
534 " %>;+ ",
535 " ,;;+ ",
536 " &#$''#' >;;;+ ",
537 " =)!)!!!!~ *#$'' ",
538 " {]^/((_({- %%%%%%%%%%% ",
539 " {(^_^^^^:<{{{{{{{{{{{{{[& ",
540 " {/_/(((((/]]]]]]]]]]]/]!# ",
541 " {/^(((((_^^^^^^^^^^^^^^:# ",
542 " {/^(((_^^____________^^}$ ",
543 " {/^(((((/////////////((!# ",
544 " {/^/^_:<|||||||||||||||@@****1 ",
545 " {/^/^(<[)||||||||||||||))!!}<; ",
546 " {/^_(:|234444444444444444432)1 ",
547 " {/_^/<)34444444444444444443}, ",
548 " {/^(2{:41111111111111111142|5 ",
549 " {3^3<:31111111111111111143}- ",
550 " {/^2<:31111111111111111441|' ",
551 " {_/<:41111111111111111143}, ",
552 " {(4<:31111111111111111144!# ",
553 " )4))44111111111111111144}, ",
554 " )2<:31111111111111111144{# ",
555 " @|:14444444444444444444}* ",
556 " ;@434444444444444444434<# ",
557 " ;[))))))))))))))))))))!~ ",
558 " ++++++++++++++++++++++;% ",
559 " ",
560 " "}
561 ;
562 fOpenIcon = new QPixmap(open);
563
564
565 const char * const move[]={
566 "32 32 16 1",
567 " c None",
568 ". c #F1F1F1",
569 "+ c #939393",
570 "@ c #282828",
571 "# c #787878",
572 "$ c #000000",
573 "% c #CCCCCC",
574 "& c #1A1A1A",
575 "* c #0D0D0D",
576 "= c #5D5D5D",
577 "- c #AEAEAE",
578 "; c #BBBBBB",
579 "> c #C9C9C9",
580 ", c #D6D6D6",
581 "' c #FFFFFF",
582 ") c #999999",
583 " ",
584 " ",
585 " ",
586 " ",
587 " .. ",
588 " ++ ",
589 " .@@. ",
590 " #$$# ",
591 " %&$$*% ",
592 " =$$$$= ",
593 " -**$$**- ",
594 " %;%&*>;% ",
595 " -% @& %- ",
596 " ,=*; @& ;*=, ",
597 " .#*$$> >$$*#. ",
598 " ')&$$$$*@@ @@*$$$$&)' ",
599 " ')&$$$$*@@ @@*$$$$&+' ",
600 " .#*$$> >$$*#. ",
601 " ,=*; @& ;*=, ",
602 " -% @& %- ",
603 " %;%&*>>% ",
604 " -**$$**- ",
605 " =$$$$= ",
606 " %&$$*% ",
607 " #$$# ",
608 " .@@. ",
609 " ++ ",
610 " .. ",
611 " ",
612 " ",
613 " ",
614 " "}
615 ;
616 fMoveIcon = new QPixmap(move);
617
618 const char * const rotate[]={
619 "32 32 27 1",
620 " c None",
621 ". c #003333",
622 "+ c #000066",
623 "@ c #1A1A1A",
624 "# c #003399",
625 "$ c #3333CC",
626 "% c #000033",
627 "& c #353535",
628 "* c #434343",
629 "= c #336699",
630 "- c #3399FF",
631 "; c #003366",
632 "> c #5D5D5D",
633 ", c #282828",
634 "' c #3399CC",
635 ") c #333333",
636 "! c #3366CC",
637 "~ c #333399",
638 "{ c #505050",
639 "] c #666666",
640 "^ c #333366",
641 "/ c #0033CC",
642 "( c #3366FF",
643 "_ c #336666",
644 ": c #787878",
645 "< c #868686",
646 "[ c #6B6B6B",
647 " .++@ ",
648 " #$$%&* ",
649 " =--; *>, ",
650 " '-= )>& ",
651 " !-', ,>* ",
652 " !!=--= >* ",
653 " =------!!~@&)@ ",
654 " --------!*{{{*&, ",
655 " -------=){*{{{>>{) ",
656 " ,!-----= ){& ,&{{@",
657 " ,*>!----= &>& )@",
658 " ){>)~---= *]) @",
659 " @*>, --! ,&@ ",
660 " @{* '! ,-!=~^,@ ",
661 " @& == {/(----!^ ",
662 " _ ]:;(----' ",
663 " ==_ >{+(----~ ",
664 " !-!!======!!(((---! ",
665 " ='--------------! ",
666 " =!!!!'!!=; !-! ",
667 " &<* !~ ",
668 " @. *[* ; ",
669 " ;+)>* ",
670 " @@ ",
671 " ",
672 " ",
673 " ",
674 " ",
675 " ",
676 " ",
677 " ",
678 " "}
679 ;
680 fRotateIcon = new QPixmap(rotate);
681
682 const char * const pick[]={
683 /* columns rows colors chars-per-pixel */
684 "20 20 12 1 ",
685 " c #050804",
686 ". c #222321",
687 "X c #3B3C3A",
688 "o c #4C4E4B",
689 "O c #616360",
690 "+ c #747673",
691 "@ c #8A8C89",
692 "# c #9FA19E",
693 "$ c #BABCB9",
694 "% c #CED0CD",
695 "& c #E4E6E3",
696 "* c None",
697 /* pixels */
698 "*********oo*********",
699 "*********oo*********",
700 "******$O. .O%******",
701 "****&o .O..O O*****",
702 "***&X @**oo**@ X****",
703 "***o $***oo***$ O***",
704 "**% @**********@ %**",
705 "**O.***********& +**",
706 "**.O*****@@*****o.**",
707 "oo .oo**@ #*&XX. oo",
708 "oo .oo**@ #*&oo. oO",
709 "**.O*****##*****oX**",
710 "**O ***********& +**",
711 "**% @****&&****+ &**",
712 "***O $***Xo***# +***",
713 "****X @&*Xo*&+ o****",
714 "*****O o..o +*****",
715 "******%+. X+&******",
716 "*********oo*********",
717 "*********oO*********"
718 };
719 fPickIcon = new QPixmap(pick);
720
721 const char * const zoom_in[]={
722 "32 32 11 1",
723 " c None",
724 ". c #C9CBC8",
725 "+ c #A8A9A3",
726 "@ c #818783",
727 "# c #D5D8D5",
728 "$ c #9BCCCC",
729 "% c #5FC7F4",
730 "& c #FDFFFC",
731 "* c #636662",
732 "= c #9599CE",
733 "- c #DDE0DD",
734 " ",
735 " ",
736 " ",
737 " ",
738 " ",
739 " .++@@++. ",
740 " +++..#.+++ ",
741 " .@+...++++#+@. ",
742 " @$.%%+&&&@%..@ ",
743 " ++.%%%+&&&*%%.++ ",
744 " .+#%%%%+&&&*%%.#+ ",
745 " ++..%%%+&&&*%%%.++ ",
746 " +#.+++++&&&*++++.+ ",
747 " @.+&&&&&&&&&&&&&+@ ",
748 " @#+&&&&&&&&&&&&&+@ ",
749 " @.+&&&&&&&&&&&&&+. ",
750 " +++@***+&&&****@+. ",
751 " ....++++&&&*++++.. ",
752 " ++.===+&&&*%=.++ ",
753 " @..==+&&&*=..@#& ",
754 " .@+#.+&&&@-+@@*@ ",
755 " +++.++++++ *+@* ",
756 " .+@@@++. @**+* ",
757 " .*@*+* ",
758 " .*@*+* ",
759 " +*@@* ",
760 " .**+ ",
761 " ",
762 " ",
763 " ",
764 " ",
765 " "}
766 ;
767 fZoomInIcon = new QPixmap(zoom_in);
768
769 const char * const zoom_out[]={
770 "32 32 11 1",
771 " c None",
772 ". c #C9CBC8",
773 "+ c #A8A9A3",
774 "@ c #818783",
775 "# c #D5D8D5",
776 "$ c #5FC7F4",
777 "% c #9BCCCC",
778 "& c #FDFFFC",
779 "* c #636662",
780 "= c #9599CE",
781 "- c #DDE0DD",
782 " ",
783 " ",
784 " ",
785 " ",
786 " ",
787 " .++@@++. ",
788 " +++..#.+++ ",
789 " .@+..$$$$.#+@. ",
790 " @%.$$$$$$$$..@ ",
791 " ++.$$$$$$$$$$.++ ",
792 " .+#$$$$$$$$$$$.#+ ",
793 " ++..$$$$$$$$$$$.++ ",
794 " +#.+++++++++++++.+ ",
795 " @.+&&&&&&&&&&&&&+@ ",
796 " @#+&&&&&&&&&&&&&+@ ",
797 " @.+&&&&&&&&&&&&&+. ",
798 " +++@***********@+. ",
799 " ....++++++++++++.. ",
800 " ++.===$$$$$$=.++ ",
801 " @..===$$$$=..@#& ",
802 " .@+#.$$$..-+@@*@ ",
803 " +++#--.+++ *+@* ",
804 " .+@@@++. @**+* ",
805 " .*@*+* ",
806 " .*@*+* ",
807 " +*@@* ",
808 " .**+ ",
809 " ",
810 " ",
811 " ",
812 " ",
813 " "}
814 ;
815 fZoomOutIcon = new QPixmap(zoom_out);
816
817 const char * const wireframe[]={
818 "32 32 24 1",
819 " c None",
820 "+ c #E4E4E4",
821 "@ c #D5D5D5",
822 "# c #E1E1E1",
823 "$ c #E7E7E7",
824 "% c #D8D8D8",
825 "& c #A7A7A7",
826 "* c #000000",
827 "= c #989898",
828 "- c #8A8A8A",
829 "; c #B5B5B5",
830 "> c #1B1B1B",
831 ", c #676767",
832 "' c #959595",
833 ") c #4A4A4A",
834 "! c #878787",
835 "~ c #D3D3D3",
836 "{ c #C4C4C4",
837 "] c #A4A4A4",
838 "^ c #5B5B5B",
839 "/ c #B3B3B3",
840 "( c #787878",
841 "_ c #C7C7C7",
842 ": c #585858",
843 " ",
844 " +@@# ",
845 " $%@@@@@&****=+ ",
846 " +&********&@-***; ",
847 " +@@@&**&@@@@@@$ @*-&>&+ ",
848 " +*****&+ %*@ ,**'# ",
849 " @***)!~ @*{&*****+ ",
850 " @*!]***&+ +-*^**'~!*@ ",
851 " @*~ +@&**&@@@@@@&****&+ ~*@ ",
852 " @*@ +&********&-*= @*@ ",
853 " @*@ $%@-*-@$ @*@ @*@ ",
854 " @*@ @*@ %*% @*@ ",
855 " @*@ %*% %*% @*@ ",
856 " @*@ %*% %*% @*@ ",
857 " @*@ %*% %*% @*@ ",
858 " @*@ %*% %*% @*@ ",
859 " @*@ %*% %*% @*@ ",
860 " @*@ @*@ %*% @*@ ",
861 " @*@ =*-+ @*@ @*@ ",
862 " @*@ $%@@&****&@-*-+ @*@ ",
863 " @*@ $@&*****&@@&******&~~!*@ ",
864 " @*{/***&@@%$ $@-*-&*****+ ",
865 " @*)*)(-~ @*@ ~)**] ",
866 " +*******&@@@@+ %*_+]**] ",
867 " +@@@@@&******&@%+_*^**]# ",
868 " $%@@@&****:**&+ ",
869 " +%@&**& ",
870 " ++ ",
871 " ",
872 " ",
873 " ",
874 " "}
875 ;
876 fWireframeIcon = new QPixmap(wireframe);
877
878 const char * const solid[]={
879 "32 32 33 1",
880 " c None",
881 "+ c #C2DEDE",
882 "@ c #B5D7DF",
883 "# c #ACD6E6",
884 "$ c #60C0EC",
885 "% c #4EB7EE",
886 "& c #53B9ED",
887 "* c #82CEEA",
888 "= c #CFDDDA",
889 "- c #94C9E8",
890 "; c #0960FF",
891 "> c #0943FF",
892 ", c #0949FF",
893 "' c #3CB3F0",
894 ") c #71C7EB",
895 "! c #73CBE5",
896 "~ c #D3DDDB",
897 "{ c #C4DDDE",
898 "] c #B7D5DF",
899 "^ c #2DACF5",
900 "/ c #59C1ED",
901 "( c #5FC0ED",
902 "_ c #85CEE9",
903 ": c #096BFF",
904 "< c #2AACF6",
905 "[ c #5CBEEC",
906 "} c #7ACAE4",
907 "| c #73CAEB",
908 "1 c #71C8E5",
909 "2 c #D1DDDA",
910 "3 c #CBDDD9",
911 "4 c #67C1EB",
912 "5 c #80CDEA",
913 " ",
914 " ",
915 " +@@@@@@#$%&*= ",
916 " +-;>>>>>>>>>,')!~ ",
917 " {]@@-;>>>>>>>>>>>>^/(_= ",
918 " {:>>>>>>>>>>>>>>>>><//[)!= ",
919 " ]>>>>>>>>>>>>>>>>>><////[)} ",
920 " @>>>>>>>>>>>>>>>>>><//////| ",
921 " @>>>>>>>>>>>>>>>>>><//////| ",
922 " @>>>>>>>>>>>>>>>>>><//////| ",
923 " @>>>>>>>>>>>>>>>>>><//////| ",
924 " @>>>>>>>>>>>>>>>>>><//////| ",
925 " @>>>>>>>>>>>>>>>>>><//////| ",
926 " @>>>>>>>>>>>>>>>>>><//////| ",
927 " @>>>>>>>>>>>>>>>>>><//////| ",
928 " @>>>>>>>>>>>>>>>>>><//////| ",
929 " @>>>>>>>>>>>>>>>>>><//////| ",
930 " @>>>>>>>>>>>>>>>>>><//////| ",
931 " @>>>>>>>>>>>>>>>>>><//////| ",
932 " @>>>>>>>>>>>>>>>>>><//////| ",
933 " @>>>>>>>>>>>>>>>>>><//////| ",
934 " @>>>>>>>>>>>>>>>>>></////[1 ",
935 " @>>>>>>>>>>>>>>>>>><////[*2 ",
936 " {:>>>>>>>>>>>>>>>>><//[)12 ",
937 " +@@@@@-;>>>>>>>>>><[)13 ",
938 " {]@@@-;>>>,'*3 ",
939 " +@@#452 ",
940 " ",
941 " ",
942 " ",
943 " ",
944 " "}
945 ;
946 fSolidIcon = new QPixmap(solid);
947
948 const char * const hidden_line_removal[]={
949 "32 32 15 1",
950 " c None",
951 "+ c #D5D5D5",
952 "@ c #C7C7C7",
953 "# c #9C9C9C",
954 "$ c #000000",
955 "% c #8E8E8E",
956 "& c #808080",
957 "* c #A9A9A9",
958 "= c #D8D8D8",
959 "- c #CACACA",
960 "; c #181818",
961 "> c #9F9F9F",
962 ", c #ACACAC",
963 "' c #B9B9B9",
964 ") c #555555",
965 " ",
966 " +@@+ ",
967 " +@@@@@@#$$$$%+ ",
968 " +#$$$$$$$$#@&$$$* ",
969 " =-@@#$$#@@@@@-= @$&#;>= ",
970 " =$$$$$#+ -$@ *$$%+ ",
971 " -$&@-= -$- #$$$= ",
972 " -$@ -$- +&$- ",
973 " @$@ @$@ @$@ ",
974 " @$@ @$@ @$@ ",
975 " @$@ @$@ @$@ ",
976 " @$@ @$@ @$@ ",
977 " @$@ @$@ @$@ ",
978 " @$@ @$@ @$@ ",
979 " @$@ @$@ @$@ ",
980 " @$@ @$@ @$@ ",
981 " @$@ @$@ @$@ ",
982 " @$@ @$@ @$@ ",
983 " @$@ @$@ @$@ ",
984 " @$@ @$@ @$@ ",
985 " @$@ @$@ @$@ ",
986 " @$@ @$@ #$= ",
987 " -$&@@@-= -$- =>;, ",
988 " =$$$$$$$#@@@-= -$'+#$$, ",
989 " =-@@@@#$$$$$$#@-+'$)$$#+ ",
990 " =-@@@#$$$$)$$#+ ",
991 " +@@#$$# ",
992 " ++ ",
993 " ",
994 " ",
995 " ",
996 " "}
997 ;
998 fHiddenLineRemovalIcon = new QPixmap(hidden_line_removal);
999
1000 const char * const hidden_line_and_surface_removal[]={
1001 "32 32 40 1",
1002 " c None",
1003 "+ c #FFFFFF",
1004 "@ c #89A2E9",
1005 "# c #5378E3",
1006 "$ c #A2B5ED",
1007 "% c #5379E3",
1008 "& c #5076E3",
1009 "* c #3E69E4",
1010 "= c #0C43F8",
1011 "- c #043FFE",
1012 "; c #CDD9ED",
1013 "> c #BDCDE9",
1014 ", c #FBFCFC",
1015 "' c #406AE4",
1016 ") c #0439FE",
1017 "! c #0137FF",
1018 "~ c #4F75E3",
1019 "{ c #9EB5E3",
1020 "] c #829FE0",
1021 "^ c #B6C6E7",
1022 "/ c #9DB4E3",
1023 "( c #7E9CE0",
1024 "_ c #B2C3E9",
1025 ": c #7E9AE0",
1026 "< c #86A2E1",
1027 "[ c #CAD6ED",
1028 "} c #5177E3",
1029 "| c #829CE0",
1030 "1 c #BCCCE9",
1031 "2 c #3A67E6",
1032 "3 c #0A43FA",
1033 "4 c #95ACE1",
1034 "5 c #BBCBE9",
1035 "6 c #A9BBE5",
1036 "7 c #96AFE1",
1037 "8 c #BDCBE9",
1038 "9 c #4067E4",
1039 "0 c #6485E5",
1040 "a c #E3EAF3",
1041 "b c #CAD6F3",
1042 " ",
1043 " ",
1044 " ++++ ",
1045 " ++++++++@#$+++ ",
1046 " ++@%####&*=-#+;>, ",
1047 " +++++@'=)))))))!)~+{]^++ ",
1048 " +$%&*=)!!!!!!!!!)~+/(]_+++ ",
1049 " +#-))!!!!!!!!!!!)~+/(::<[+ ",
1050 " +#)!!!!!!!!!!!!!!}+/::::{+ ",
1051 " +#)!!!!!!!!!!!!!!}+/::::{+ ",
1052 " +#)!!!!!!!!!!!!!!}+/::::{+ ",
1053 " +#)!!!!!!!!!!!!!!}+/::::{+ ",
1054 " +#)!!!!!!!!!!!!!!}+/::::{+ ",
1055 " +#)!!!!!!!!!!!!!!}+/::::{+ ",
1056 " +#)!!!!!!!!!!!!!!}+/::::{+ ",
1057 " +#)!!!!!!!!!!!!!!}+/::::{+ ",
1058 " +#)!!!!!!!!!!!!!!}+/::::{+ ",
1059 " +#)!!!!!!!!!!!!!!}+/::::{+ ",
1060 " +#)!!!!!!!!!!!!!!}+/::::{+ ",
1061 " +#)!!!!!!!!!!!!!!}+/::::{+ ",
1062 " +#)!!!!!!!!!!!!!!}+/::::{+ ",
1063 " +#)!!!!!!!!!!!!!!}+/:::|1+ ",
1064 " +$#}}~23!!!!!!!!)~+/(]45, ",
1065 " +++++++@#}}~23!!)~+678++ ",
1066 " ++++++@#~90+a++ ",
1067 " ++++b++ ",
1068 " ++ ",
1069 " ",
1070 " ",
1071 " ",
1072 " ",
1073 " "}
1074 ;
1075 fHiddenLineAndSurfaceRemovalIcon = new QPixmap(hidden_line_and_surface_removal);
1076
1077 const char * const perspective[]={
1078 "32 32 3 1",
1079 " c None",
1080 ". c #D5D8D5",
1081 "+ c #000000",
1082 " ",
1083 " ",
1084 " ",
1085 " ",
1086 " ",
1087 " ................ ",
1088 " ....+++++++++++++++. ",
1089 " ...++++..+.........+++. ",
1090 " ..++..............++..+. ",
1091 " .+++++++++++++++++.. .+. ",
1092 " .+...............+. .+. ",
1093 " .+. .+. .+. .+. ",
1094 " .+. .+. .+. .+. ",
1095 " .+. .+. .+. .+. ",
1096 " .+. .+. .+. .+. ",
1097 " .+. .+. .+. .+. ",
1098 " .+. .+. .+. .+. ",
1099 " .+. .+. .+. .+. ",
1100 " .+. .+. .+. .+. ",
1101 " .+. .+......+....+. ",
1102 " .+. ..++++++.+.++++. ",
1103 " .+. .++.......+...+.. ",
1104 " .+. .++. .+..++. ",
1105 " .+. ..+.. .+..+. ",
1106 " .+..++. .+.+. ",
1107 " .+.++. .+++. ",
1108 " .+++.............++. ",
1109 " .+++++++++++++++++. ",
1110 " ................... ",
1111 " ",
1112 " ",
1113 " "}
1114 ;
1115 fPerspectiveIcon = new QPixmap(perspective);
1116
1117 const char * const ortho[]={
1118 "32 32 3 1",
1119 " c None",
1120 ". c #D5D8D5",
1121 "@ c #000000",
1122 " ",
1123 " ",
1124 " ",
1125 " ................... ",
1126 " ..@@@@@@@@@@@@@@@@@. ",
1127 " ..@@@.............@@@. ",
1128 " ..@@.@. ..@..@. ",
1129 " ..@@ ..@. .@@...@. ",
1130 " ..@@..............@@.. .@. ",
1131 " .@@@@@@@@@@@@@@@@@.. .@. ",
1132 " .@...............@. .@. ",
1133 " .@. .@. .@. .@. ",
1134 " .@. .@. .@. .@. ",
1135 " .@. .@. .@. .@. ",
1136 " .@. .@. .@. .@. ",
1137 " .@. .@. .@. .@. ",
1138 " .@. .@. .@. .@. ",
1139 " .@. .@. .@. .@. ",
1140 " .@. .@. .@. .@. ",
1141 " .@. .@. .@. .@. ",
1142 " .@. .@. .@. .@. ",
1143 " .@. .@........@......@. ",
1144 " .@. .@@@@@@@@@.@.@@@@@@. ",
1145 " .@. .@@+........@....@@.. ",
1146 " .@...@. .@...@... ",
1147 " .@.@@. .@.@@ . ",
1148 " .@@@.............@@@.. ",
1149 " .@@@@@@@@@@@@@@@@@... ",
1150 " ................... ",
1151 " ",
1152 " ",
1153 " "}
1154 ;
1155 fOrthoIcon = new QPixmap(ortho);
1156
1157 const char * const commandIcon[]={
1158 "20 20 25 1 ",
1159 " c #4ED17F",
1160 ". c #4FD280",
1161 "X c #50D381",
1162 "o c #5BD181",
1163 "O c #5DD382",
1164 "+ c #59D48A",
1165 "@ c #66D68C",
1166 "# c #6FD895",
1167 "$ c #85DEA4",
1168 "% c #8CE0AC",
1169 "& c #96E4B8",
1170 "* c #9EE3B8",
1171 "= c #A8E5BB",
1172 "- c #A7E8C4",
1173 "; c #B2EAC8",
1174 ": c #B9ECD1",
1175 "> c #C2EDD3",
1176 ", c #CBF1DF",
1177 "< c #D4F3E3",
1178 "1 c #DDF4E5",
1179 "2 c #DBF5EC",
1180 "3 c #E5F7F0",
1181 "4 c #EDFAFB",
1182 "5 c #F6FBFE",
1183 "6 c #FEFFFC",
1184 /* pixels */
1185 "66666666666666666666",
1186 "66%++++++++++++++&56",
1187 "6$ o..o......o..o *6",
1188 "6+o...o*<441;@.o..+6",
1189 "6+..o@1553<354$..o+6",
1190 "6+..o<5<@ .*54#o.+6",
1191 "6+o.*52X :5-..@6",
1192 "6+..15% o$+o.+6",
1193 "6+.+55@ .o.+6",
1194 "6O.#54 .X.+6",
1195 "6O #54 .X.+6",
1196 "6O.+55@ .o.+6",
1197 "6+..25% @,*o.@6",
1198 "6+o.*52X :5>.o+6",
1199 "6+..O25<@ X=54#o.+6",
1200 "6+.o.@1553<354$...@6",
1201 "6+o..oo*<44<;@o..o+6",
1202 "6$ .o..o.....o..o *6",
1203 "66%+++++OOOO+++++*66",
1204 "66666666666666666666"
1205 };
1206 fCommandIcon = new QPixmap(commandIcon);
1207
1208 const char * const dirIcon[]={
1209 "20 20 25 1 ",
1210 " c #DF5959",
1211 ". c #DD5F5F",
1212 "X c #DE7370",
1213 "o c #E06360",
1214 "O c #E06467",
1215 "+ c #E06C6C",
1216 "@ c #E57979",
1217 "# c #E08886",
1218 "$ c #E18D91",
1219 "% c #E19D9B",
1220 "& c #E99B9D",
1221 "* c #E8A2A2",
1222 "= c #EEB2B0",
1223 "- c #EDBBBC",
1224 "; c #EDCBC7",
1225 ": c #E9CDD1",
1226 "> c #F1D5D6",
1227 ", c #F9DFE2",
1228 "< c #EFE8E7",
1229 "1 c #F3E3E4",
1230 "2 c #F8EEEC",
1231 "3 c #FCF6F4",
1232 "4 c #F6F3F9",
1233 "5 c #F2F8FC",
1234 "6 c #FEFFFD",
1235 /* pixels */
1236 "66666666666666666666",
1237 "66$oOOOOOOOOOOOOo%66",
1238 "6# %6",
1239 "6o +,666663:+ o6",
1240 "6o =635533666$ o6",
1241 "6o -65:+ +165X o6",
1242 "6o >6<. 36; O6",
1243 "6o 26- &6>. o6",
1244 "6. o56* @63. o6",
1245 "6. X56& o66. o6",
1246 "6. X56& +63. o6",
1247 "6. o56* @62. o6",
1248 "6o 26- =61 O6",
1249 "6o >6<. o36: o6",
1250 "6o -65:+ @265X o6",
1251 "6o =635543665# O6",
1252 "6o +1666662;+ o6",
1253 "6# %6",
1254 "66$OOOoo....OOOOo%66",
1255 "66666666666666666666"}
1256 ;
1257 fDirIcon = new QPixmap(dirIcon);
1258
1259
1260 const char * const runIcon[]={
1261 /* columns rows colors chars-per-pixel */
1262 "20 20 33 1 ",
1263 " c #5CA323",
1264 ". c #5EA03F",
1265 "X c #6DB620",
1266 "o c #66AD3F",
1267 "O c #70B73C",
1268 "+ c #7CC13F",
1269 "@ c #569B41",
1270 "# c #61A14E",
1271 "$ c #70A95D",
1272 "% c #7EB55C",
1273 "& c #85B94E",
1274 "* c #90BE49",
1275 "= c #81B669",
1276 "- c #81B370",
1277 "; c #95CA46",
1278 ": c #A1CD40",
1279 "> c #AED045",
1280 ", c #B3D558",
1281 "< c #9BC87E",
1282 "1 c #AED668",
1283 "2 c #A2D075",
1284 "3 c #C2DC73",
1285 "4 c #A5C98F",
1286 "5 c #C1DC9F",
1287 "6 c #CAE18E",
1288 "7 c #CCE39A",
1289 "8 c #C4DCB6",
1290 "9 c #E3ECBA",
1291 "0 c #EEF3D3",
1292 "q c #F0F7DE",
1293 "w c #F8FAE9",
1294 "e c #FCFFFB",
1295 "r c None",
1296 /* pixels */
1297 "rrrrrrrr%<<2rrrrrrrr",
1298 "rrrrr5=$$$$===rrrrrr",
1299 "rrrr<##$$$$$---&rrrr",
1300 "rrr=###$$$$-----%rrr",
1301 "rr=####$$$$------&rr",
1302 "r2@####7##$-------rr",
1303 "r.@####048$-------Or",
1304 "r.@####[email protected]",
1305 " .@@###w4eee5%$#@@@X",
1306 " .@@@..w4eeeeqo..@@X",
1307 " [email protected]<eeee7Oooo@X",
1308 " ..oooOe2eee6OOOooo ",
1309 "rOooOO+e2ew2+++++O+r",
1310 "r:oO+++e30,;;;;;++Or",
1311 "r :++;:9,>,,>>:;;1rr",
1312 "rr*1;:>,333333,>32rr",
1313 "rrr66,1367777637<rrr",
1314 "rrrr509799999905rrrr",
1315 "rrrrr=8wqwwww8-rrrrr",
1316 "rrrrrrrr4444rrrrrrrr"
1317 };
1318 fRunIcon = new QPixmap(runIcon);
1319
1320 const char * const paramIcon[]={
1321 /* columns rows colors chars-per-pixel */
1322 "20 20 35 1 ",
1323 " c #2E2525",
1324 ". c #403737",
1325 "X c #423A3A",
1326 "o c #443C3C",
1327 "O c #473F3F",
1328 "+ c #4C4444",
1329 "@ c #4F4848",
1330 "# c #514949",
1331 "$ c #544D4D",
1332 "% c #595252",
1333 "& c #625B5B",
1334 "* c #696262",
1335 "= c #6D6666",
1336 "- c #716B6B",
1337 "; c #726C6C",
1338 ": c #767171",
1339 "> c #7E7878",
1340 ", c #8B8787",
1341 "< c #8C8787",
1342 "1 c #8D8888",
1343 "2 c #918D8D",
1344 "3 c #928E8E",
1345 "4 c #948F8F",
1346 "5 c #9C9898",
1347 "6 c #9D9999",
1348 "7 c #D5D4D4",
1349 "8 c #D8D6D6",
1350 "9 c #DDDBDB",
1351 "0 c #EFEFEF",
1352 "q c #F6F6F6",
1353 "w c None",
1354 "e c None",
1355 "r c None",
1356 "t c gray99",
1357 "y c None",
1358 /* pixels */
1359 "wwwwwwww5 5wwwwwwww",
1360 "wwwwwwww, ,wwwwwwww",
1361 "www&;ww7+ +9ww=-www",
1362 "ww& O# OX *ww",
1363 "ww; >ww",
1364 "wwwO .%%X +www",
1365 "www# 3wwww3 Owww",
1366 "ww7 3wwwwww3 7ww",
1367 "5<+ .wwwwwww0. +<5",
1368 " %wwwwwwww$ ",
1369 " %wwwwwwww$ ",
1370 "5<+ .wwwwwww0X +<5",
1371 "ww9 4wwwwww1 9ww",
1372 "wwwO 30ww03 Owww",
1373 "wwwX X#$X @www",
1374 "ww= =ww",
1375 "ww- +O ++ :ww",
1376 "www*>ww7+ +7ww=:www",
1377 "wwwwwwww1 1wwwwwwww",
1378 "wwwwwwww5 5wwwwwwww"
1379 };
1380 fParamIcon = new QPixmap(paramIcon);
1381
1382}
1383
1384
1385/** Create the History ToolBox Widget
1386 */
1387QWidget* G4UIQt::CreateHistoryTBWidget(
1388)
1389{
1390 fHistoryTBWidget = new QWidget();
1391
1392 QVBoxLayout *layoutHistoryTB = new QVBoxLayout();
1393 fHistoryTBTableList = new QListWidget();
1394 fHistoryTBTableList->setSelectionMode(QAbstractItemView::SingleSelection);
1395 connect(fHistoryTBTableList, SIGNAL(itemSelectionChanged()), SLOT(CommandHistoryCallback()));
1396
1397 layoutHistoryTB->addWidget(fHistoryTBTableList);
1398
1399 fHistoryTBWidget->setLayout(layoutHistoryTB);
1400 return fHistoryTBWidget;
1401}
1402
1403
1404/** Create the Help ToolBox Widget
1405 */
1406QWidget* G4UIQt::CreateHelpTBWidget(
1407)
1408{
1409 fHelpTBWidget = new QWidget();
1410
1411 QWidget *helpWidget = new QWidget();
1412 QHBoxLayout *helpLayout = new QHBoxLayout();
1413 QVBoxLayout *vLayout = new QVBoxLayout();
1414 fHelpVSplitter = new QSplitter(Qt::Vertical);
1415 fHelpLine = new QLineEdit();
1416 helpLayout->addWidget(new QLabel("Search :"));
1417 helpLayout->addWidget(fHelpLine);
1418 connect( fHelpLine, SIGNAL( editingFinished () ), this, SLOT( LookForHelpStringCallback() ) );
1419
1420 // Create Help tree
1421 FillHelpTree();
1422
1423 fParameterHelpLabel = new QTextEdit();
1424 fParameterHelpLabel->setReadOnly(true);
1425 fParameterHelpTable = new QTableWidget();
1426
1427 // Set layouts
1428
1429 if (fHelpTreeWidget) {
1430 fHelpVSplitter->addWidget(fHelpTreeWidget);
1431 }
1432 fHelpVSplitter->addWidget(fParameterHelpLabel);
1433 fHelpVSplitter->addWidget(fParameterHelpTable);
1434
1435 fParameterHelpLabel->setVisible(false);
1436 fParameterHelpTable->setVisible(false);
1437 QSizePolicy policy = QSizePolicy(QSizePolicy::Maximum,QSizePolicy::Maximum);
1438 policy.setVerticalStretch(4);
1439 if (fHelpTreeWidget) {
1440 fHelpTreeWidget->setSizePolicy(policy);
1441 }
1442 policy = QSizePolicy(QSizePolicy::Minimum,QSizePolicy::Preferred);
1443 policy.setVerticalStretch(1);
1444 fParameterHelpLabel->setSizePolicy(policy);
1445 fParameterHelpTable->setSizePolicy(policy);
1446
1447 vLayout->addWidget(helpWidget);
1448 vLayout->addWidget(fHelpVSplitter,1);
1449 vLayout->setContentsMargins(5,5,5,5);
1450
1451 helpWidget->setLayout(helpLayout);
1452 fHelpTBWidget->setLayout(vLayout);
1453
1454 return fHelpTBWidget;
1455}
1456
1457
1458/** Create the Cout ToolBox Widget
1459 */
1460G4UIDockWidget* G4UIQt::CreateCoutTBWidget(
1461)
1462{
1463 QWidget* coutTBWidget = new QWidget();
1464
1465 QVBoxLayout *layoutCoutTB = new QVBoxLayout();
1466
1467 fCoutTBTextArea = new QTextEdit();
1468
1469 fCoutFilter = new QLineEdit();
1470 fCoutFilter->setToolTip("Filter output by...");
1471
1472#if QT_VERSION > 0x050100
1473 fCoutFilter->addAction(*fSearchIcon,QLineEdit::TrailingPosition);
1474 fCoutFilter->setStyleSheet ("border-radius:7px;");
1475#else
1476 QPushButton *coutTBFilterButton = new QPushButton();
1477 coutTBFilterButton->setIcon(QIcon(*fSearchIcon));
1478 coutTBFilterButton->setStyleSheet ("padding-left: 0px; border:0px;");
1479 fCoutFilter->setStyleSheet ("padding-right: 0px;");
1480#endif
1481
1482 QPushButton *coutTBClearButton = new QPushButton();
1483 coutTBClearButton->setIcon(*fClearIcon);
1484 coutTBClearButton->setToolTip("Clear console output");
1485 coutTBClearButton->setStyleSheet ("border-radius:7px;");
1486 connect(coutTBClearButton, SIGNAL(clicked()), SLOT(ClearButtonCallback()));
1487 connect(fCoutFilter, SIGNAL(textEdited ( const QString &)), SLOT(CoutFilterCallback( const QString &)));
1488
1489 QPushButton *coutTBSaveOutputButton = new QPushButton();
1490 coutTBSaveOutputButton->setIcon(*fSaveIcon);
1491 coutTBSaveOutputButton->setToolTip("Save console output");
1492 coutTBSaveOutputButton->setStyleSheet ("border-radius:7px;");
1493 connect(coutTBSaveOutputButton, SIGNAL(clicked()), SLOT(SaveOutputCallback()));
1494
1495 fCoutTBTextArea->setReadOnly(true);
1496
1497 QWidget* coutButtonWidget = new QWidget();
1498 QHBoxLayout* layoutCoutTBButtons = new QHBoxLayout();
1499
1500#ifdef G4MULTITHREADED
1501 // add all candidates to widget
1502 fThreadsFilterComboBox = new QComboBox();
1503 fThreadsFilterComboBox->setInsertPolicy(QComboBox::InsertAlphabetically);
1504 connect(fThreadsFilterComboBox, SIGNAL(activated(int)), this, SLOT(ThreadComboBoxCallback(int)));
1505
1506 UpdateCoutThreadFilter();
1507
1508 fThreadsFilterComboBox->setToolTip("Thread selection in output");
1509 layoutCoutTBButtons->addWidget(new QLabel(" Threads:"));
1510 layoutCoutTBButtons->addWidget(fThreadsFilterComboBox);
1511#endif
1512
1513 layoutCoutTBButtons->addWidget(fCoutFilter);
1514#if QT_VERSION <= 0x050100
1515 layoutCoutTBButtons->addWidget(coutTBFilterButton);
1516#endif
1517 layoutCoutTBButtons->addWidget(coutTBClearButton);
1518 layoutCoutTBButtons->addWidget(coutTBSaveOutputButton);
1519 coutButtonWidget->setLayout(layoutCoutTBButtons);
1520
1521 // reduce margins
1522 layoutCoutTBButtons->setContentsMargins(3,3,3,0);
1523
1524 layoutCoutTB->addWidget(coutButtonWidget);
1525 layoutCoutTB->addWidget(fCoutTBTextArea);
1526
1527 coutTBWidget->setLayout(layoutCoutTB);
1528
1529 fCoutTBTextArea->setMinimumSize(100,100);
1530
1531 // Command line :
1532 QWidget* commandLineWidget = new QWidget();
1533 QHBoxLayout *layoutCommandLine = new QHBoxLayout();
1534
1535 // fill them
1536
1537 fCommandLabel = new QLabel("");
1538 fCommandArea = new QLineEdit();
1539
1540 // The QCompleter will be append at SessionStart()
1541
1542 fCommandArea->activateWindow();
1543
1544 fCommandArea->setFocusPolicy ( Qt::StrongFocus );
1545 fCommandArea->setFocus(Qt::TabFocusReason);
1546 fCommandArea->setToolTip("Apply command");
1547
1548
1549 layoutCommandLine->addWidget(fCommandLabel);
1550 layoutCommandLine->addWidget(fCommandArea);
1551
1552 // Connect signal
1553 connect(fCommandArea, SIGNAL(returnPressed()), SLOT(CommandEnteredCallback()));
1554 connect(fCommandArea, SIGNAL(textEdited(const QString &)), SLOT(CommandEditedCallback(const QString &)));
1555
1556
1557 commandLineWidget->setLayout(layoutCommandLine);
1558 commandLineWidget->setMinimumSize(50,50);
1559
1560 layoutCoutTB->addWidget(commandLineWidget);
1561
1562 fCoutDockWidget = new G4UIDockWidget ("Output");
1563 fCoutDockWidget->setAllowedAreas(Qt::TopDockWidgetArea | Qt::BottomDockWidgetArea);
1564
1565 fCoutDockWidget->setWidget(coutTBWidget);
1566 return fCoutDockWidget;
1567}
1568
1569
1570/** Create the VisParameters ToolBox Widget
1571 */
1572QWidget* G4UIQt::CreateVisParametersTBWidget(
1573)
1574{
1575 return NULL;
1576}
1577
1578
1579/** Create the VisParameters ToolBox Widget
1580 */
1581G4UIDockWidget* G4UIQt::CreateUITabWidget(
1582)
1583{
1584 fUITabWidget = new QTabWidget();
1585
1586 // the left dock
1587 fUITabWidget->addTab(CreateSceneTreeWidget(),"Scene tree");
1588 fUITabWidget->addTab(CreateHelpTBWidget(),"Help");
1589 fUITabWidget->addTab(CreateHistoryTBWidget(),"History");
1590 fUITabWidget->setCurrentWidget(fHelpTBWidget);
1591
1592 fUITabWidget->setTabToolTip (0,"Scene component tree. Only available in Stored mode");
1593 fUITabWidget->setTabToolTip (1,"Help widget");
1594 fUITabWidget->setTabToolTip (2,"All commands history");
1595 connect(fUITabWidget, SIGNAL(currentChanged(int)), SLOT(ToolBoxActivated(int)));
1596
1597 fUIDockWidget = new G4UIDockWidget ("Scene tree, Help, History");
1598 fUIDockWidget->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
1599
1600 fUIDockWidget->setWidget(fUITabWidget);
1601
1602 return fUIDockWidget;
1603}
1604
1605
1606QWidget* G4UIQt::CreateSceneTreeWidget(){
1607
1608 fSceneTreeWidget = new QWidget();
1609 QVBoxLayout* layout = new QVBoxLayout();
1610 fSceneTreeWidget->setLayout(layout);
1611
1612#if QT_VERSION < 0x040200
1613 fSceneTreeWidget->hide();
1614#else
1615 fSceneTreeWidget->setVisible(false);
1616#endif
1617
1618 return fSceneTreeWidget;
1619}
1620
1621
1622void G4UIQt::CreateViewerWidget(){
1623
1624 // Set layouts
1625
1626 SetStartPage(std::string("<table width='100%'><tr><td width='30%'></td><td><div ")+
1627 "style='color: rgb(140, 31, 31); font-size: xx-large; font-family: Garamond, serif; padding-bottom: 0px; font-weight: normal'>Geant4: "+
1628 QApplication::applicationName ().toStdString()+
1629 "</div></td><td width='40%'>&nbsp;<br/><i>http://cern.ch/geant4/</i></td></tr></table>"+
1630 "<p>&nbsp;</p>"+
1631 "<div style='background:#EEEEEE;'><b>Tooltips :</b><ul>"+
1632 "<li><b>Start a new viewer :</b><br />"+
1633 "<i>'/vis/open/...'<br />"+
1634 "For example '/vis/open OGL'</i></li>"+
1635 "<li><b>Execute a macro file :</b><br />"+
1636 "<i>'/control/execute my_macro_file'</i></li>"+
1637 "</ul></div>"+
1638
1639 "<div style='background:#EEEEEE;'><b>Documentation :</b><ul>"+
1640 "<li><b>Visualisation publication :</b><br />"+
1641 "<i><a href='http://www.worldscientific.com/doi/abs/10.1142/S1793962313400011'>The Geant4 Visualization System - A Multi-Driver Graphics System</b><br />, Allison, J. et al., International Journal of Modeling, Simulation, and Scientific Computing, Vol. 4, Suppl. 1 (2013) 1340001</a>:<br/> http://www.worldscientific.com/doi/abs/10.1142/S1793962313400011</i></li>"+
1642 "</ul></div>"+
1643
1644 "<div style='background:#EEEEEE;'><b>Getting Help :</b><ul>"+
1645 "<li><b>If problems arise, try <a href='https://cern.ch/geant4-forum'>browsing the user forum</a> to see whether or not your problem has already been encountered.<br /> If it hasn't, you can post it and Geant4 developers will do their best to find a solution. This is also a good place to<br /> discuss Geant4 topics in general.</b> https://cern.ch/geant4-forum"+
1646 "<li><b>Get a look at <a href='http://cern.ch/geant4/support'>Geant4 User support pages</a>: <i>http://cern.ch/geant4/support</i></b></li>"+
1647 "</ul></div>"
1648 );
1649
1650
1651 // fill right splitter
1652 if (fViewerTabWidget == NULL) {
1653 fViewerTabWidget = new G4QTabWidget();
1654 fMainWindow->setCentralWidget(fViewerTabWidget);
1655#if QT_VERSION < 0x040500
1656#else
1657 fViewerTabWidget->setTabsClosable (true);
1658#endif
1659
1660#if QT_VERSION < 0x040200
1661#else
1662 fViewerTabWidget->setUsesScrollButtons (true);
1663#endif
1664
1665#if QT_VERSION < 0x040500
1666#else
1667 connect(fViewerTabWidget, SIGNAL(tabCloseRequested(int)), this, SLOT(TabCloseCallback(int)));
1668#endif
1669 connect(fViewerTabWidget, SIGNAL(currentChanged ( int ) ), SLOT(UpdateTabWidget(int)));
1670 }
1671
1672// set the QGLWidget size policy
1673 QSizePolicy policy = QSizePolicy(QSizePolicy::Preferred,QSizePolicy::Preferred);
1674 policy.setVerticalStretch(4);
1675 fViewerTabWidget->setSizePolicy(policy);
1676
1677 fViewerTabWidget->setMinimumSize(40,40);
1678}
1679
1680
1681/** Get the ViewerComponents ToolBox Widget
1682 */
1683QWidget* G4UIQt::GetSceneTreeWidget(
1684)
1685{
1686 return fSceneTreeWidget;
1687}
1688
1689/** Get the Viewer properties Widget
1690 */
1691QWidget* G4UIQt::GetViewerPropertiesWidget(
1692)
1693{
1694 if (!fViewerPropertiesDialog) {
1695 CreateViewerPropertiesDialog();
1696 }
1697 return fViewerPropertiesWidget;
1698}
1699
1700/** Get the Pick Widget
1701 */
1702QWidget* G4UIQt::GetPickInfosWidget(
1703)
1704{
1705 if (!fPickInfosDialog) {
1706 CreatePickInfosDialog();
1707 }
1708 return fPickInfosWidget;
1709}
1710
1711
1712/** Add a new tab in the viewer
1713 */
1714bool G4UIQt::AddViewerTab(
1715 QWidget* aWidget
1716 ,std::string title
1717 )
1718{
1719 if (fViewerTabWidget == NULL) {
1720 return false;
1721 }
1722 fViewerTabWidget->addTab(aWidget,title.c_str());
1723
1724 return true;
1725}
1726
1727
1728/** Add a new tab in the viewer
1729 */
1730bool G4UIQt::AddViewerTabFromFile(
1731 std::string fileName
1732 ,std::string title
1733 )
1734{
1735 if (fViewerTabWidget == NULL) {
1736 return false;
1737 }
1738
1740 if(UI==NULL) return 0;
1741 std::ifstream file(UI->FindMacroPath(fileName.c_str()).data());
1742 if (file) {
1743
1744 std::string content( (std::istreambuf_iterator<char>(file) ),
1745 (std::istreambuf_iterator<char>() ) );
1746
1747 QTextEdit* text = new QTextEdit();
1748 text->setAcceptRichText (true);
1749 text->setContentsMargins(5,5,5,5);
1750 text->setText(QString("<pre>")+content.c_str()+"</pre>");
1751 text->setReadOnly(true);
1752 fViewerTabWidget->addTab(text,title.c_str());
1753 } else {
1754 return false;
1755 }
1756 return true;
1757}
1758
1759
1760/** Add a new tab widget.
1761 Create the tab if it was not done
1762*/
1763bool G4UIQt::AddTabWidget(
1764 QWidget* aWidget
1765,QString name
1766)
1767{
1768 // Special case for Qt version between 5.0 and 5.1 on Mac OSX
1769 // Due to a bug in this Qt version, we can't put a OpenGL Widget inside the QTabWidget.
1770 // A work around is to put it outside. Returning false will fore the wiewer to put the QGLWidget
1771 // inside a new QWindow.
1772
1773#ifdef Q_OS_MAC
1774 #if QT_VERSION < 0x050100
1775 #if QT_VERSION >= 0x050000
1776 QString message = QString(
1777 "This Qt version [")+qVersion ()+"] has some issues with the OpenGL viewer.\n"+
1778 "To prevent problems, you are not allowed to open a Stored nor Immediate viewer.\n" +
1779 "\n" +
1780 "Please upgrade to Qt version >= 5.1\n";
1781
1782 QMessageBox::warning(fMainWindow, tr("Warning"),
1783 tr(message.toStdString().c_str()),
1784 QMessageBox::Ok);
1785 return false;
1786 #endif
1787 #endif
1788#endif
1789
1790 if (fViewerTabWidget == NULL) {
1791 CreateViewerWidget();
1792 }
1793
1794 if (!aWidget) {
1795 return false;
1796 }
1797// Has to be added before we put it into the fViewerTabWidget widget
1798 aWidget->setParent(fViewerTabWidget); // Will create in some cases widget outside
1799 // of UI for a really short moment
1800
1801 fViewerTabWidget->addTab(aWidget,name);
1802
1803 fViewerTabWidget->setCurrentIndex(fViewerTabWidget->count()-1);
1804
1805 // Set visible
1806 #if QT_VERSION < 0x040200
1807 fViewerTabWidget->setLastTabCreated(fViewerTabWidget->currentIndex());
1808 #else
1809 fViewerTabWidget->setLastTabCreated(fViewerTabWidget->currentIndex());
1810 #endif
1811
1812 // Not the good solution, but ensure that the help tree is correctly build when launching a viewer
1813 // It should be done by a notification when adding a command, but that's nit done yet (Geant4.10.1)␓
1814 FillHelpTree();
1815
1816 return true;
1817}
1818
1819
1820void G4UIQt::SetStartPage(
1821const std::string& text)
1822{
1823 if (text != "") {
1824 fDefaultViewerFirstPageHTMLText = text;
1825 }
1826 if (!fStartPage) {
1827 fStartPage = new QTextEdit();
1828 fStartPage->setAcceptRichText (true);
1829 fStartPage->setContentsMargins(5,5,5,5);
1830 fStartPage->setReadOnly(true);
1831 }
1832 fStartPage->setText(fDefaultViewerFirstPageHTMLText.c_str());
1833}
1834
1835
1836void G4UIQt::UpdateTabWidget(int tabNumber) {
1837 if ( fViewerTabWidget == NULL) {
1838 fViewerTabWidget = new G4QTabWidget;
1839 }
1840
1841 fViewerTabWidget->setCurrentIndex(tabNumber);
1842
1843 // Send this signal to unblock graphic updates !
1844 fViewerTabWidget->setTabSelected(false);
1845
1846 #if QT_VERSION < 0x040200
1847 fViewerTabWidget->show();
1848 #else
1849 fViewerTabWidget->setVisible(true);
1850 #endif
1851
1852 // This will send a paintEvent to OGL Viewers
1853 fViewerTabWidget->setTabSelected(true);
1854}
1855
1856
1857/** Send resize event to all tabs
1858 */
1859void G4UIQt::ResizeTabWidget( QResizeEvent* e) {
1860 if ( fViewerTabWidget) {
1861 for (G4int a=0;a<fViewerTabWidget->count() ;a++) {
1862 fViewerTabWidget->widget(a)->resize(e->size());
1863 }
1864 }
1865}
1866
1867
1868/** Start the Qt main loop
1869*/
1870G4UIsession* G4UIQt::SessionStart (
1871)
1872{
1873 G4Qt* interactorManager = G4Qt::getInstance ();
1874 Prompt("Session :");
1875 exitSession = false;
1876
1877 QCoreApplication::sendPostedEvents () ;
1878
1879 #if QT_VERSION < 0x040200
1880 fMainWindow->show();
1881 #else
1882 fMainWindow->setVisible(true);
1883 #endif
1884
1885 if (fDefaultIcons) {
1886#if QT_VERSION < 0x040200
1887 fToolbarApp->show();
1888#else
1889 fToolbarApp->setVisible(true);
1890#endif
1891 } else {
1892 // Set not visible until session start
1893#if QT_VERSION < 0x040200
1894 fToolbarApp->hide();
1895#else
1896 fToolbarApp->setVisible(false);
1897#endif
1898 }
1899 // Rebuild help tree (new command could be registered)
1900 FillHelpTree();
1901
1902 // Rebuild command completion (new command could be registered)
1903 UpdateCommandCompleter();
1904
1905 // Set event filters
1906 fHistoryTBTableList->installEventFilter(this);
1907 fCommandArea->installEventFilter(this);
1908
1909 // Focus on command line
1910 fCommandArea->setFocus();
1911
1912 interactorManager->DisableSecondaryLoop (); // TO KEEP
1913 if ((QApplication*)interactorManager->GetMainInteractor())
1914 ((QApplication*)interactorManager->GetMainInteractor())->exec();
1915
1916 interactorManager->EnableSecondaryLoop ();
1917 return this;
1918}
1919
1920
1921/** Display the prompt in the prompt area
1922 @param aPrompt : string to display as the promt label
1923*/
1924void G4UIQt::Prompt (
1925 G4String aPrompt
1926)
1927{
1928 if (!aPrompt) return;
1929
1930 fCommandLabel->setText((char*)aPrompt.data());
1931}
1932
1933
1934
1935void G4UIQt::SessionTerminate (
1936)
1937{
1938 G4Qt* interactorManager = G4Qt::getInstance ();
1939 fMainWindow->close();
1940 ((QApplication*)interactorManager->GetMainInteractor())->exit();
1941}
1942
1943
1944
1945/**
1946 Called by intercoms/src/G4UImanager.cc<br>
1947 Called by visualization/management/src/G4VisCommands.cc with "EndOfEvent" argument<br>
1948 It have to pause the session command terminal.<br>
1949 Call SecondaryLoop to wait for exit event<br>
1950 @param aState
1951 @see : G4VisCommandReviewKeptEvents::SetNewValue
1952*/
1953void G4UIQt::PauseSessionStart (
1954 const G4String& aState
1955)
1956{
1957 if (!aState) return;
1958
1959 if(aState=="G4_pause> ") { // TO KEEP
1960 SecondaryLoop ("Pause, type continue to exit this state"); // TO KEEP
1961 } // TO KEEP
1962
1963 if(aState=="EndOfEvent") { // TO KEEP
1964 // Picking with feed back in event data Done here !!!
1965 SecondaryLoop ("End of event, type continue to exit this state"); // TO KEEP
1966 } // TO KEEP
1967}
1968
1969
1970
1971/**
1972 Begin the secondary loop
1973 @param a_prompt : label to display as the prompt label
1974 */
1975void G4UIQt::SecondaryLoop (
1976 G4String aPrompt
1977)
1978{
1979 if (!aPrompt) return;
1980
1981 G4Qt* interactorManager = G4Qt::getInstance (); // TO KEEP ?
1982 Prompt(aPrompt); // TO KEEP
1983 exitPause = false; // TO KEEP
1984 while(1) {
1985 ((QApplication*)interactorManager)->processEvents(QEventLoop::WaitForMoreEvents);
1986 if(exitPause==true) break; // TO KEEP
1987 } // TO KEEP
1988 Prompt("Session :"); // TO KEEP
1989}
1990
1991#ifdef G4MULTITHREADED
1992#include "G4Threading.hh"
1993#include "G4AutoLock.hh"
1994namespace {
1995 G4Mutex ReceiveG4coutMutex = G4MUTEX_INITIALIZER;
1996 G4Mutex ReceiveG4cerrMutex = G4MUTEX_INITIALIZER;
1997}
1998#endif
1999
2000/**
2001 Receive a cout from Geant4. We have to display it in the cout zone
2002 @param aString : label to add in the display area
2003 @return 0
2004*/
2005G4int G4UIQt::ReceiveG4cout (
2006 const G4String& aString
2007 )
2008{
2009 if (!aString) return 0;
2010
2011#ifdef G4MULTITHREADED
2012 G4AutoLock al(&ReceiveG4coutMutex);
2013#endif
2014
2015 // Try to be smart :
2016 // "*** This is just a warning message. ***"
2017 if (aString.contains("*** This is just a warning message. ***")) {
2018 return ReceiveG4cerr(aString);
2019 }
2020
2021 // Workaround so that output is not lost after crash or G4Exception
2022 // It seems workers write to std::cout anyway, so limit this to the master
2023#ifdef G4MULTITHREADED
2025#endif
2026 std::cout << aString;
2027
2028 QStringList newStr;
2029
2030 // Add to string
2031 G4UIOutputString txt = G4UIOutputString(QString((char*)aString.data()).trimmed(),GetThreadPrefix());
2032 fG4OutputString.push_back(txt);
2033
2034#ifdef G4MULTITHREADED
2035 QString result = FilterOutput(txt,fThreadsFilterComboBox->currentText(),fCoutFilter->text());
2036#else
2037 QString result = FilterOutput(txt,"",fCoutFilter->text());
2038#endif
2039
2040 if (result.isEmpty()) {
2041 return 0;
2042 }
2043 fCoutTBTextArea->append(result);
2044 fCoutTBTextArea->ensureCursorVisible ();
2045
2046#ifdef G4MULTITHREADED
2047 UpdateCoutThreadFilter();
2048#endif
2049
2050 // reset error stack
2051 fLastErrMessage = aString;
2052 return 0;
2053}
2054
2055
2056/**
2057 Receive a cerr from Geant4. We have to display it in the cout zone
2058 @param aString : label to add in the display area
2059 @return 0
2060*/
2061G4int G4UIQt::ReceiveG4cerr (
2062 const G4String& aString
2063)
2064{
2065 if (!aString) return 0;
2066
2067#ifdef G4MULTITHREADED
2068 G4AutoLock al(&ReceiveG4cerrMutex);
2069#endif
2070
2071 // Workaround so that output is not lost after crash or G4Exception
2072 // It seems workers write to std::cerr anyway, so limit this to the master
2073#ifdef G4MULTITHREADED
2075#endif
2076 std::cerr << aString;
2077
2078 QStringList newStr;
2079
2080 // Add to string
2081
2082 G4UIOutputString txt = G4UIOutputString(QString((char*)aString.data()).trimmed(),
2083 GetThreadPrefix(),
2084 "error");
2085 fG4OutputString.push_back(txt);
2086
2087#ifdef G4MULTITHREADED
2088 QString result = FilterOutput(txt,fThreadsFilterComboBox->currentText(),fCoutFilter->text());
2089#else
2090 QString result = FilterOutput(txt,"",fCoutFilter->text());
2091#endif
2092 if (result.isEmpty()) {
2093 return 0;
2094 }
2095
2096 // Suppress space, \n,\t,\r...
2097 if (QString(aString.data()).trimmed() != "") {
2098 if ((G4StateManager::GetStateManager()->GetCurrentState() == G4State_Abort) ||
2099 (G4StateManager::GetStateManager()->GetCurrentState() == G4State_Quit )) {
2100 // In case of Abort or Quit, the useful error message should be in the last error message !
2101 fLastErrMessage += "\n"+aString;
2102 QString criticalMessage = fLastErrMessage.data();
2103#if QT_VERSION < 0x050000
2104 criticalMessage = Qt::escape(criticalMessage);
2105#else
2106 criticalMessage = criticalMessage.toHtmlEscaped();
2107#endif
2108 QMessageBox::critical(fMainWindow, "Error",QString(fLastErrMessage));
2109 }
2110 }
2111 fCoutTBTextArea->append(QString("<font color=\"Red\">") +
2112 result + QString("</font>"));
2113 fCoutTBTextArea->ensureCursorVisible ();
2114
2115 if (QString(aString.data()).trimmed() != "") {
2116 fLastErrMessage += aString;
2117 }
2118#ifdef G4MULTITHREADED
2119 UpdateCoutThreadFilter();
2120#endif
2121 return 0;
2122}
2123
2124
2125G4String G4UIQt::GetThreadPrefix() {
2126 G4String threadPrefix = "";
2127#ifdef G4MULTITHREADED
2129 if(UI==NULL) return "";
2130 if (UI->GetThreadCout() != NULL) {
2131 threadPrefix = UI->GetThreadCout()->GetFullPrefixString().data();
2132 if (UI->GetThreadCout()->GetPrefixString() == G4String("G4VIS")) {
2133 return "G4VIS";
2134 }
2135 }
2136#endif
2137 return threadPrefix;
2138}
2139
2140
2141#ifdef G4MULTITHREADED
2142void G4UIQt::UpdateCoutThreadFilter() {
2144 if(UI==NULL) return;
2145
2146 // add "All" and "Master"
2147 if (fThreadsFilterComboBox->count() < 2) {
2148 if ( fThreadsFilterComboBox->findText("All", Qt::MatchExactly) == -1) {
2149 fThreadsFilterComboBox->addItem("All");
2150 }
2151 }
2152 if (fThreadsFilterComboBox->count() < 2) {
2153 if ( fThreadsFilterComboBox->findText("Master", Qt::MatchExactly) == -1) {
2154 fThreadsFilterComboBox->addItem("Master");
2155 }
2156 }
2157 // Add current Cout
2158 G4String prefix = GetThreadPrefix();
2159 if (prefix != "") {
2160 if ( fThreadsFilterComboBox->findText(prefix.data(), Qt::MatchExactly) == -1) {
2161 fThreadsFilterComboBox->addItem(prefix.data());
2162 }
2163 }
2164}
2165#endif
2166
2167
2168/**
2169 Add a new menu to the menu bar
2170 @param aName name of menu
2171 @param aLabel label to display
2172 */
2173void G4UIQt::AddMenu (
2174 const char* aName
2175,const char* aLabel
2176)
2177{
2178 if (aName == NULL) return;
2179 if (aLabel == NULL) return;
2180
2181 QMenu *fileMenu = new QMenu(aLabel);
2182 fMainWindow->menuBar()->addMenu(fileMenu);
2183
2184 AddInteractor (aName,(G4Interactor)fileMenu);
2185}
2186
2187
2188/**
2189 Add a new button to a menu
2190 @param aMenu : parent menu
2191 @param aLabel : label to display
2192 @param aCommand : command to execute as a callback
2193 */
2194void G4UIQt::AddButton (
2195 const char* aMenu
2196,const char* aLabel
2197,const char* aCommand
2198)
2199{
2200 if(aMenu==NULL) return; // TO KEEP
2201 if(aLabel==NULL) return; // TO KEEP
2202 if(aCommand==NULL) return; // TO KEEP
2203
2204 QMenu *parentTmp = (QMenu*)GetInteractor(aMenu);
2205
2206 if(parentTmp==NULL) {
2208 G4int verbose = UImanager->GetVerboseLevel();
2209
2210 if (verbose >= 2) {
2211 G4cout << "Menu name " << aMenu<< " does not exist, please define it before using it."<< G4endl;
2212 }
2213 return;
2214 }
2215
2216 // Find the command in the command tree
2218 if(UI==NULL) return;
2219 G4UIcommandTree * treeTop = UI->GetTree();
2220
2221 G4String cmd = aCommand;
2222 G4int cmdEndPos = cmd.find_first_of(" \t");
2223 if(cmdEndPos!=G4int(std::string::npos)) {
2224 cmd.erase(cmdEndPos);
2225 }
2226
2227 if(treeTop->FindPath(cmd) == NULL) {
2228 if(cmd != "ls" &&
2229 cmd(0,3) != "ls " &&
2230 cmd != "pwd" &&
2231 cmd != "cd" &&
2232 cmd(0,3) != "cd " &&
2233 cmd != "help" &&
2234 cmd(0,5) != "help " &&
2235 cmd(0) != '?' &&
2236 cmd != "hist" &&
2237 cmd != "history" &&
2238 cmd(0) != '!' &&
2239 cmd != "exit" &&
2240 cmd != "cont" &&
2241 cmd != "continue"){
2243 G4int verbose = UImanager->GetVerboseLevel();
2244
2245 if (verbose >= 2) {
2246 G4cout << "Warning: command '"<< cmd <<"' does not exist, please define it before using it."<< G4endl;
2247 }
2248 }
2249 }
2250
2251#if QT_VERSION < 0x050600
2252 QSignalMapper *signalMapper = new QSignalMapper(this);
2253 QAction *action = parentTmp->addAction(aLabel, signalMapper, SLOT(map()));
2254
2255 connect(signalMapper, SIGNAL(mapped(const QString &)),this, SLOT(ButtonCallback(const QString&)));
2256 signalMapper->setMapping(action, QString(aCommand));
2257#else
2258 QString cmd_tmp = QString(aCommand);
2259 parentTmp->addAction(aLabel, this, [=](){ this->ButtonCallback(cmd_tmp); });
2260#endif
2261}
2262
2263
2264
2265
2266/**
2267 special case for the "open" icon. It will open a file selector and map the return file to the given command.
2268*/
2269void G4UIQt::AddIcon(const char* aLabel, const char* aIconFile, const char* aCommand, const char* aFileName){
2270 if(aLabel==NULL) return; // TO KEEP
2271 // special case, aCommand could be NULL if aIconFile is not user_icon
2272 if (aCommand==NULL) {
2273 if (std::string(aIconFile) == "user_icon") {
2274 return; // TO KEEP
2275 }
2276 }
2277 QPixmap* pix;
2278 bool userToolBar = false;
2279
2280 if (!fDefaultIcons) {
2281 userToolBar = true;
2282 }
2283 if (std::string(aIconFile) == "user_icon") {
2284 // try to open a file
2286 pix = new QPixmap(UImanager->FindMacroPath(aFileName).data());
2287 if (pix->isNull()) {
2288 G4int verbose = UImanager->GetVerboseLevel();
2289
2290 if (verbose >= 2) {
2291 G4cout << "Warning: file '"<< aFileName <<"' is incorrect or does not exist, this command will not be build"<< G4endl;
2292 }
2293 return;
2294 }
2295 } else if (std::string(aIconFile) == "open") {
2296 pix = fOpenIcon;
2297 } else if (std::string(aIconFile) == "save") {
2298 pix = fSaveIcon;
2299 } else if (std::string(aIconFile) == "move") {
2300 pix = fMoveIcon;
2301 } else if (std::string(aIconFile) == "rotate") {
2302 pix = fRotateIcon;
2303 } else if (std::string(aIconFile) == "pick") {
2304 pix = fPickIcon;
2305 } else if (std::string(aIconFile) == "zoom_in") {
2306 pix = fZoomInIcon;
2307 } else if (std::string(aIconFile) == "zoom_out") {
2308 pix = fZoomOutIcon;
2309 } else if (std::string(aIconFile) == "wireframe") {
2310 pix = fWireframeIcon;
2311 } else if (std::string(aIconFile) == "solid") {
2312 pix = fSolidIcon;
2313 } else if (std::string(aIconFile) == "hidden_line_removal") {
2314 pix = fHiddenLineRemovalIcon;
2315 } else if (std::string(aIconFile) == "hidden_line_and_surface_removal") {
2316 pix = fHiddenLineAndSurfaceRemovalIcon;
2317 } else if (std::string(aIconFile) == "perspective") {
2318 pix = fPerspectiveIcon;
2319 } else if (std::string(aIconFile) == "ortho") {
2320 pix = fOrthoIcon;
2321 } else if (std::string(aIconFile) == "runBeamOn") {
2322 pix = fRunIcon;
2323 } else {
2325 G4int verbose = UImanager->GetVerboseLevel();
2326
2327 if (verbose >= 2) {
2328 G4cout << "Parameter"<< aIconFile <<" not defined"<< G4endl;
2329 }
2330 return;
2331 }
2332 QToolBar *currentToolbar = NULL;
2333 if (userToolBar) {
2334 if (fToolbarUser == NULL) {
2335 fToolbarUser = new QToolBar();
2336 fToolbarUser->setIconSize (QSize(20,20));
2337 fMainWindow->addToolBar(Qt::TopToolBarArea, fToolbarUser);
2338 }
2339 currentToolbar = fToolbarUser;
2340 } else {
2341 if (fToolbarApp == NULL) {
2342 fToolbarApp = new QToolBar();
2343 fToolbarApp->setIconSize (QSize(20,20));
2344 fMainWindow->addToolBar(Qt::TopToolBarArea, fToolbarApp);
2345 }
2346 currentToolbar = fToolbarApp;
2347 }
2348
2349 // Check if already present
2350
2351 QList<QAction*> list = currentToolbar->actions();
2352
2353 for (int i = 0; i < list.size(); ++i) {
2354 if (list.at(i)->text() == QString(aLabel)) {
2356 if(UI==NULL) return;
2357 G4int verbose = UI->GetVerboseLevel();
2358 if (verbose >= 2) {
2359 G4cout << "Warning: A toolBar icon \""<< aLabel<< "\" already exists with the same name!" << G4endl;
2360 }
2361 }
2362 }
2363
2364#if QT_VERSION < 0x050600
2365 QSignalMapper *signalMapper = new QSignalMapper(this);
2366 QAction *action = currentToolbar->addAction(QIcon(*pix),aLabel, signalMapper, SLOT(map()));
2367#endif
2368 // special cases :"open"
2369 if (std::string(aIconFile) == "open") {
2370 QString txt = aCommand + fStringSeparator + aLabel;
2371#if QT_VERSION < 0x050600
2372 connect(signalMapper, SIGNAL(mapped(const QString &)),this, SLOT(OpenIconCallback(const QString &)));
2373 signalMapper->setMapping(action, QString(txt));
2374#else
2375 currentToolbar->addAction(QIcon(*pix), aIconFile, this, [=](){ this->OpenIconCallback(txt); });
2376#endif
2377
2378 // special cases :"save"
2379 } else if (std::string(aIconFile) == "save") {
2380 QString txt = aCommand + fStringSeparator + aLabel;
2381#if QT_VERSION < 0x050600
2382 connect(signalMapper, SIGNAL(mapped(const QString &)),this, SLOT(SaveIconCallback(const QString&)));
2383 signalMapper->setMapping(action, QString(txt));
2384#else
2385 currentToolbar->addAction(QIcon(*pix), aIconFile, this, [=](){ this->SaveIconCallback(txt); });
2386#endif
2387
2388 // special cases : cursor style
2389 } else if ((std::string(aIconFile) == "move") ||
2390 (std::string(aIconFile) == "rotate") ||
2391 (std::string(aIconFile) == "pick") ||
2392 (std::string(aIconFile) == "zoom_out") ||
2393 (std::string(aIconFile) == "zoom_in")) {
2394#if QT_VERSION < 0x050600
2395 connect(signalMapper, SIGNAL(mapped(const QString &)),this, SLOT(ChangeCursorAction(const QString&)));
2396 signalMapper->setMapping(action, QString(aIconFile));
2397#else
2398 QString txt = QString(aIconFile);
2399 QAction* action = currentToolbar->addAction(QIcon(*pix), aIconFile, this, [=](){ this->ChangeCursorAction(txt); });
2400#endif
2401 action->setCheckable(TRUE);
2402 action->setChecked(TRUE);
2403 action->setData(aIconFile);
2404
2405 if (std::string(aIconFile) == "move") {
2406 SetIconMoveSelected();
2407 }
2408 if (std::string(aIconFile) == "rotate") {
2409 SetIconRotateSelected();
2410 }
2411 if (std::string(aIconFile) == "pick") {
2412 SetIconPickSelected();
2413 }
2414 if (std::string(aIconFile) == "zoom_in") {
2415 SetIconZoomInSelected();
2416 }
2417 if (std::string(aIconFile) == "zoom_out") {
2418 SetIconZoomOutSelected();
2419 }
2420
2421 // special case : surface style
2422 } else if ((std::string(aIconFile) == "hidden_line_removal") ||
2423 (std::string(aIconFile) == "hidden_line_and_surface_removal") ||
2424 (std::string(aIconFile) == "solid") ||
2425 (std::string(aIconFile) == "wireframe")) {
2426#if QT_VERSION < 0x050600
2427 connect(signalMapper, SIGNAL(mapped(const QString &)),this, SLOT(ChangeSurfaceStyle(const QString&)));
2428 signalMapper->setMapping(action, QString(aIconFile));
2429#else
2430 QString txt = QString(aIconFile);
2431 QAction* action = currentToolbar->addAction(QIcon(*pix), aIconFile, this, [=](){ this->ChangeSurfaceStyle(txt); });
2432#endif
2433 action->setCheckable(TRUE);
2434 action->setChecked(TRUE);
2435 action->setData(aIconFile);
2436
2437 if (std::string(aIconFile) == "hidden_line_removal") {
2438 SetIconHLRSelected();
2439 }
2440 if (std::string(aIconFile) == "hidden_line_and_surface_removal") {
2441 SetIconHLHSRSelected();
2442 }
2443 if (std::string(aIconFile) == "solid") {
2444 SetIconSolidSelected();
2445 }
2446 if (std::string(aIconFile) == "wireframe") {
2447 SetIconWireframeSelected();
2448 }
2449
2450 // special case : perspective/ortho
2451 } else if ((std::string(aIconFile) == "perspective") ||
2452 (std::string(aIconFile) == "ortho")) {
2453#if QT_VERSION < 0x050600
2454 connect(signalMapper, SIGNAL(mapped(const QString &)),this, SLOT(ChangePerspectiveOrtho(const QString&)));
2455 signalMapper->setMapping(action, QString(aIconFile));
2456#else
2457 QString txt = QString(aIconFile);
2458 QAction* action = currentToolbar->addAction(QIcon(*pix), aIconFile, this, [=](){ this->ChangePerspectiveOrtho(txt); });
2459#endif
2460 action->setCheckable(TRUE);
2461 action->setChecked(TRUE);
2462 action->setData(aIconFile);
2463
2464 if (std::string(aIconFile) == "perspective") {
2465 SetIconPerspectiveSelected();
2466 }
2467 if (std::string(aIconFile) == "ortho") {
2468 SetIconOrthoSelected();
2469 }
2470
2471 } else {
2472
2473 // Find the command in the command tree
2475 if(UI==NULL) return;
2476 G4UIcommandTree * treeTop = UI->GetTree();
2477 if (aCommand != NULL) {
2478 std::string str = aCommand;
2479 std::string::size_type pos = str.find(" ");
2480 if (pos != std::string::npos)
2481 {
2482 str = str.substr(0,pos).c_str();
2483 }
2484 if(treeTop->FindPath(str.c_str()) == NULL) {
2486 G4int verbose = UImanager->GetVerboseLevel();
2487
2488 if (verbose >= 2) {
2489 G4cout << "Warning: command '"<< aCommand <<"' does not exist, please define it before using it."<< G4endl;
2490 }
2491 }
2492 }
2493
2494#if QT_VERSION < 0x050600
2495 connect(signalMapper, SIGNAL(mapped(const QString &)),this, SLOT(ButtonCallback(const QString&)));
2496 signalMapper->setMapping(action, QString(aCommand));
2497#else
2498 QString txt = QString(aCommand);
2499 currentToolbar->addAction(QIcon(*pix), aCommand, this, [=](){ this->ButtonCallback(txt); });
2500#endif
2501 }
2502}
2503
2504
2505
2506void G4UIQt::ActivateCommand(
2507 G4String newCommand
2508)
2509{
2510 if (!fHelpTreeWidget) {
2511 return;
2512 }
2513 // Look for the choosen command "newCommand"
2514 size_t i = newCommand.index(" ");
2515 G4String targetCom ="";
2516 if( i != std::string::npos )
2517 {
2518 G4String newValue = newCommand(i+1,newCommand.length()-(i+1));
2519 newValue.strip(G4String::both);
2520 targetCom = ModifyToFullPathCommand( newValue );
2521 }
2522 if (targetCom != "") {
2523 OpenHelpTreeOnCommand(targetCom.data());
2524 }
2525
2526 fUITabWidget->setCurrentWidget(fHelpTBWidget);
2527}
2528
2529
2530
2531/**
2532 Create the help tree widget
2533 @param parent : parent of tree widget
2534 @return the widget containing the tree or NULL if it could not have beeen created
2535 */
2536
2537void G4UIQt::InitHelpTreeAndVisParametersWidget()
2538{
2539
2540 if (! fHelpTreeWidget ) {
2541 fHelpTreeWidget = new QTreeWidget();
2542 }
2543
2544 // build widget
2545 fHelpTreeWidget->setSelectionMode(QAbstractItemView::SingleSelection);
2546 QStringList labels;
2547 labels << QString("Command");
2548 fHelpTreeWidget->setHeaderLabels(labels);
2549
2550
2551 connect(fHelpTreeWidget, SIGNAL(itemSelectionChanged ()),this, SLOT(HelpTreeClicCallback()));
2552 connect(fHelpTreeWidget, SIGNAL(itemDoubleClicked (QTreeWidgetItem*,int)),this, SLOT(HelpTreeDoubleClicCallback()));
2553
2554}
2555/**
2556 Create the help tree widget
2557 @param parent : parent of tree widget
2558 @return the widget containing the tree or NULL if it could not have beeen created
2559 */
2560
2561void G4UIQt::FillHelpTree()
2562{
2563 if (! fHelpTreeWidget ) {
2564 InitHelpTreeAndVisParametersWidget();
2565 }
2566
2567 QString searchText = fHelpLine->text();
2568
2569 if (searchText =="") {
2570 // clear old help tree
2571 // fHelpTreeWidget->clear();
2572 } else {
2573 return;
2574 }
2575
2576 if (fParameterHelpLabel) {
2577 fParameterHelpLabel->setText("Choose a command in the command tree");
2578 fParameterHelpTable->setVisible(false);
2579 }
2580
2581 if (fHelpLine) {
2582#if QT_VERSION < 0x040200
2583 fHelpLine->clear();
2584#else
2585 fHelpLine->setText("");
2586#endif
2587 }
2588
2590 if(UI==NULL) return;
2591 G4UIcommandTree * treeTop = UI->GetTree();
2592
2593 G4int treeSize = treeTop->GetTreeEntry();
2594 QTreeWidgetItem * newItem = NULL;
2595 QString commandText = "";
2596 for (int a=0;a<treeSize;a++) {
2597 // Creating new item
2598 newItem = NULL;
2599
2600 commandText = QString((char*)(treeTop->GetTree(a+1)->GetPathName()).data()).trimmed();
2601
2602 // if already exist, don't create it !
2603 for (int b=0;b<fHelpTreeWidget->topLevelItemCount();b++) {
2604 if (!newItem)
2605 newItem = FindTreeItem(fHelpTreeWidget->topLevelItem(b),commandText);
2606 }
2607
2608 if (newItem == NULL) {
2609
2610 newItem = new QTreeWidgetItem();
2611 newItem->setText(0,GetShortCommandPath(commandText));
2612 fHelpTreeWidget->addTopLevelItem(newItem);
2613 }
2614
2615 // look for childs
2616 CreateHelpTree(newItem,treeTop->GetTree(a+1));
2617 }
2618
2619}
2620
2621
2622
2623/** Fill the Help Tree Widget
2624 @param aParent : parent item to fill
2625 @param aCommandTree : commandTree node associate with this part of the Tree
2626*/
2627void G4UIQt::CreateHelpTree(
2628 QTreeWidgetItem *aParent
2629,G4UIcommandTree *aCommandTree
2630)
2631{
2632 if (aParent == NULL) return;
2633 if (aCommandTree == NULL) return;
2634
2635
2636 // Creating new item
2637 QTreeWidgetItem * newItem;
2638
2639 QString commandText = "";
2640 // Get the Sub directories
2641 for (int a=0;a<aCommandTree->GetTreeEntry();a++) {
2642
2643 commandText = QString((char*)(aCommandTree->GetTree(a+1)->GetPathName()).data()).trimmed();
2644
2645 // if already exist, don't create it !
2646 newItem = FindTreeItem(aParent,commandText);
2647 if (newItem == NULL) {
2648 newItem = new QTreeWidgetItem();
2649 newItem->setText(0,GetShortCommandPath(commandText));
2650 aParent->addChild(newItem);
2651 }
2652 CreateHelpTree(newItem,aCommandTree->GetTree(a+1));
2653 }
2654
2655 // Get the Commands
2656
2657 for (int a=0;a<aCommandTree->GetCommandEntry();a++) {
2658
2659 QStringList stringList;
2660 commandText = QString((char*)(aCommandTree->GetCommand(a+1)->GetCommandPath()).data()).trimmed();
2661
2662 // if already exist, don't create it !
2663 newItem = FindTreeItem(aParent,commandText);
2664 if (newItem == NULL) {
2665 newItem = new QTreeWidgetItem();
2666 newItem->setText(0,GetShortCommandPath(commandText));
2667 aParent->addChild(newItem);
2668
2669#if QT_VERSION < 0x040202
2670 fHelpTreeWidget->setItemExpanded(newItem,false);
2671#else
2672 newItem->setExpanded(false);
2673#endif
2674 }
2675 }
2676}
2677
2678
2679
2680
2681/**
2682 Add the following command to the corresponding groupbox
2683 If depthLevel is 1 : create ToolBox
2684 If depthLevel is 2 or more : create GroupBox
2685*/
2686bool G4UIQt::CreateVisCommandGroupAndToolBox(
2687 G4UIcommand* aCommand
2688,QWidget* aParent
2689,int aDepthLevel
2690,bool isDialog
2691)
2692{
2693 QString commandText = QString((char*)(aCommand->GetCommandPath().data())).section("/",-aDepthLevel);
2694
2695 if (commandText == NULL) {
2696 return false;
2697 }
2698
2699 // Look if groupBox is create
2700 // QGroupBox* gBoxCommandWidget;
2701 QWidget* newParentWidget = NULL;
2702 bool found = false;
2703 QString commandSection = commandText.left(commandText.indexOf("/"));
2704
2705 if (aDepthLevel == 1) {
2706 QToolBox* currentParent = dynamic_cast<QToolBox*>(aParent);
2707 if (currentParent != 0){
2708
2709 // already exists ?
2710 for (int a=0; a<currentParent->count(); a++) {
2711 if (currentParent->itemText(a) == commandSection) {
2712 found = true;
2713 newParentWidget = currentParent->widget(a);
2714 }
2715 }
2716 }
2717 // Not found ? create it
2718 if (!found) {
2719 newParentWidget = new QGroupBox();
2720 newParentWidget->setLayout(new QVBoxLayout());
2721 if (currentParent != 0){
2722 currentParent->addItem(newParentWidget,commandSection);
2723 } else {
2724 if (!aParent->layout()) {
2725 aParent->setLayout(new QVBoxLayout());
2726 }
2727 aParent->layout()->addWidget(newParentWidget);
2728 }
2729
2730 if (commandText.indexOf("/") == -1) {
2731
2732 // Guidance
2733 QString guidance;
2734 G4int n_guidanceEntry = aCommand->GetGuidanceEntries();
2735 for( G4int i_thGuidance=0; i_thGuidance < n_guidanceEntry; i_thGuidance++ ) {
2736 guidance += QString((char*)(aCommand->GetGuidanceLine(i_thGuidance)).data()) + "\n";
2737 }
2738 newParentWidget->setToolTip(guidance);
2739 }
2740
2741 QScrollArea* sc = dynamic_cast<QScrollArea*>(newParentWidget->parent()->parent());
2742 if (sc != 0) {
2743 sc->ensureWidgetVisible(newParentWidget);
2744
2745 }
2746 }
2747 } else {
2748
2749 // try to know if this level is already there
2750 QGroupBox* currentParent = dynamic_cast<QGroupBox*>(aParent);
2751 if (currentParent != 0){
2752
2753 // if depth==2, then we add a [more parameters inside] to the toolBoxItem parent
2754 // QGroupBox > QWidget > QScrollArea > QToolBox
2755 if (aDepthLevel == 2){
2756 QToolBox* parentToolBox = dynamic_cast<QToolBox*>(currentParent->parent()->parent()->parent());
2757 if (parentToolBox != 0) {
2758 // parentToolBox->setItemText(parentToolBox->indexOf(currentParent),"[more parameters inside]");
2759 }
2760 }
2761 for (int a=0; a<aParent->layout()->count(); a++) {
2762 QGroupBox* gb = dynamic_cast<QGroupBox*>(aParent->layout()->itemAt(a)->widget());
2763 if (gb != 0) {
2764 if (gb->title() == commandSection) {
2765 found = true;
2766 newParentWidget = gb;
2767 }
2768 }
2769 }
2770 }
2771
2772 // Not found ? create it
2773 if (!found) {
2774 newParentWidget = new QGroupBox();
2775 newParentWidget->setLayout(new QVBoxLayout());
2776 if (!aParent->layout()) {
2777 aParent->setLayout(new QVBoxLayout());
2778 }
2779 aParent->layout()->addWidget(newParentWidget);
2780
2781 // set toolTip
2782 // Guidance
2783 QString guidance;
2784 G4int n_guidanceEntry = aCommand->GetGuidanceEntries();
2785 for( G4int i_thGuidance=0; i_thGuidance < n_guidanceEntry; i_thGuidance++ ) {
2786 guidance += QString((char*)(aCommand->GetGuidanceLine(i_thGuidance)).data()) + "\n";
2787 }
2788 newParentWidget->setToolTip(guidance);
2789 }
2790 }
2791
2792 // fill command groupbox
2793 if (commandText.indexOf("/") == -1) {
2794 if (CreateCommandWidget(aCommand, newParentWidget,isDialog)) {
2795 return true;
2796 }
2797 } else {
2798 CreateVisCommandGroupAndToolBox(aCommand,newParentWidget, aDepthLevel-1,isDialog);
2799 }
2800
2801 return true;
2802}
2803
2804
2805
2806/** Create a widget with the command parameters inside
2807 @param command: command line
2808 @parent : parent widget
2809 @isDialog : true if we want apply/cancel button and close at end, false if we want only apply
2810*/
2811bool G4UIQt::CreateCommandWidget(G4UIcommand* aCommand, QWidget* aParent, bool isDialog) {
2812
2813 if (aCommand == NULL) {
2814 return false;
2815 }
2816
2817
2818 // parameters
2819 G4int n_parameterEntry = aCommand->GetParameterEntries();
2820 if( n_parameterEntry > 0 ) {
2821 G4UIparameter *param;
2822
2823 // Re-implementation of G4UIparameter.cc
2824 QWidget* paramWidget = new QWidget();
2825 QGridLayout* gridLayout = new QGridLayout();
2826 paramWidget->setLayout(gridLayout);
2827
2828 // Special case for colour, try to display a color chooser if we found red/green/blue parameter
2829 unsigned int nbColorParameter = 0;
2830 bool isStillColorParameter = false;
2831 bool isColorDialogAdded = false;
2832 QLabel* redLabel = NULL;
2833 QLabel* greenLabel = NULL;
2834 QString redDefaultStr = "";
2835 QString greenDefaultStr = "";
2836 QString blueDefaultStr = "";
2837 QWidget* redInput = NULL;
2838 QWidget* greenInput = NULL;
2839
2840 for( G4int i_thParameter=0; i_thParameter<n_parameterEntry; i_thParameter++ ) {
2841 QString txt;
2842 param = aCommand->GetParameter(i_thParameter);
2843 QLabel* label = new QLabel(QString((char*)(param->GetParameterName()).data()));
2844
2845 if ((label->text() == "red") || (label->text() == "red_or_string")){
2846 nbColorParameter ++;
2847 isStillColorParameter = true;
2848 } else if ((label->text() == "green") && isStillColorParameter) {
2849 nbColorParameter ++;
2850 } else if ((label->text() == "blue") && isStillColorParameter) {
2851 nbColorParameter ++;
2852 } else if (!isColorDialogAdded) {
2853
2854 // not following red/green/blue parameters ?
2855 if (nbColorParameter == 1) {
2856 gridLayout->addWidget(redLabel,i_thParameter-1,0);
2857 gridLayout->addWidget(redInput,i_thParameter-1,1);
2858 } else if (nbColorParameter == 2) {
2859 gridLayout->addWidget(redLabel,i_thParameter-2,0);
2860 gridLayout->addWidget(redInput,i_thParameter-2,1);
2861 gridLayout->addWidget(greenLabel,i_thParameter-1,0);
2862 gridLayout->addWidget(greenInput,i_thParameter-1,1);
2863 }
2864 nbColorParameter = 0;
2865 }
2866 // Check parameter type, could be NULL if not found
2867 QWidget* input = NULL;
2868 if ((QString(QChar(param->GetParameterType())) == "d") || (QString(QChar(param->GetParameterType())) == "i")) {
2869 input = new QLineEdit();
2870 // set default value
2871 dynamic_cast<QLineEdit*>(input)->setText(QString((char*)(param->GetDefaultValue()).data()));
2872
2873 if (((label->text() == "red") || (label->text() == "red_or_string")) && isStillColorParameter) {
2874 redDefaultStr = QString((char*)(param->GetDefaultValue()).data());
2875 } else if ((label->text() == "green") && isStillColorParameter) {
2876 greenDefaultStr = QString((char*)(param->GetDefaultValue()).data());
2877 } else if ((label->text() == "green") && isStillColorParameter) {
2878 blueDefaultStr = QString((char*)(param->GetDefaultValue()).data());
2879 }
2880
2881 } else if (QString(QChar(param->GetParameterType())) == "b") {
2882 input = new QWidget();
2883 QHBoxLayout* layout = new QHBoxLayout();
2884 input->setLayout(layout);
2885
2886 QButtonGroup* buttons = new QButtonGroup();
2887 QRadioButton* radioOff = new QRadioButton("0");
2888 QRadioButton* radioOn = new QRadioButton("1");
2889 buttons->addButton(radioOn);
2890 buttons->addButton(radioOff);
2891 layout->addWidget(radioOn);
2892 layout->addWidget(radioOff);
2893
2894 // set default value
2895 QString defaultValue = QString((char*)(param->GetDefaultValue()).data());
2896 if (defaultValue == "0") {
2897 radioOff->setChecked(true);
2898 } else if (defaultValue == "1") {
2899 radioOn->setChecked(true);
2900 }
2901 } else if ((QString(QChar(param->GetParameterType())) == "s") && (!param->GetParameterCandidates().isNull())) {
2902 input = new QComboBox();
2903 QString candidates = QString((char*)(param->GetParameterCandidates()).data());
2904 QStringList list = candidates.split (" ");
2905
2906 // add all candidates to widget
2907 QString defaultValue = QString((char*)(param->GetDefaultValue()).data());
2908 for (int a=0; a<list.size(); a++) {
2909 dynamic_cast<QComboBox*>(input)->addItem(list.at(a));
2910 if (list.at(a) == defaultValue) {
2911 dynamic_cast<QComboBox*>(input)->setCurrentIndex(a);
2912 }
2913 }
2914
2915 } else if ((QString(QChar(param->GetParameterType())) == "s")) { // string
2916 input = new QLineEdit();
2917 // set default value
2918 dynamic_cast<QLineEdit*>(input)->setText(QString((char*)(param->GetDefaultValue()).data()));
2919
2920 } else if ((QString(QChar(param->GetParameterType())) == "c")) { // on/off
2921 input = new QWidget();
2922 QHBoxLayout* layout = new QHBoxLayout();
2923 input->setLayout(layout);
2924
2925 QButtonGroup* buttons = new QButtonGroup();
2926 QRadioButton* radioOff = new QRadioButton("off");
2927 QRadioButton* radioOn = new QRadioButton("on");
2928 buttons->addButton(radioOn);
2929 buttons->addButton(radioOff);
2930 layout->addWidget(radioOn);
2931 layout->addWidget(radioOff);
2932
2933 // set default value
2934 QString defaultValue = QString((char*)(param->GetDefaultValue()).data());
2935 if (defaultValue == "off") {
2936 radioOff->setChecked(true);
2937 } else if (defaultValue == "on") {
2938 radioOn->setChecked(true);
2939 }
2940
2941 } else {
2942 input = new QLineEdit();
2943 dynamic_cast<QLineEdit*>(input)->setText(QString((char*)(param->GetDefaultValue()).data()));
2944 }
2945
2946 txt += "\nParameter : " + QString((char*)(param->GetParameterName()).data()) + "\n";
2947 if( ! param->GetParameterGuidance().isNull() )
2948 txt += QString((char*)(param->GetParameterGuidance()).data())+ "\n" ;
2949
2950 txt += " Parameter type : " + QString(QChar(param->GetParameterType())) + "\n";
2951 if(param->IsOmittable()){
2952 txt += " Omittable : True\n";
2953 } else {
2954 txt += " Omittable : False\n";
2955 }
2956 if( param->GetCurrentAsDefault() ) {
2957 txt += " Default value : taken from the current value\n";
2958 } else if( ! param->GetDefaultValue().isNull() ) {
2959 txt += " Default value : " + QString((char*)(param->GetDefaultValue()).data())+ "\n";
2960 }
2961 if( ! param->GetParameterRange().isNull() ) {
2962 txt += " Parameter range : " + QString((char*)(param->GetParameterRange()).data())+ "\n";
2963 }
2964 if( ! param->GetParameterCandidates().isNull() ) {
2965 txt += " Candidates : " + QString((char*)(param->GetParameterCandidates()).data())+ "\n";
2966 }
2967
2968 if (isStillColorParameter && (nbColorParameter != 0)) {
2969 if ((label->text() == "red") || (label->text() == "red_or_string")) {
2970 redLabel = label;
2971 redInput = input;
2972 } else if (label->text() == "green") {
2973 greenLabel = label;
2974 greenInput = input;
2975 } else if (label->text() == "blue") {
2976
2977 // we have all, then add a color chooser
2978
2979 // Create a pixmap with the default color
2980 QColor qc;
2981 if ((redDefaultStr != "") && (redDefaultStr != "") && (redDefaultStr != "")) {
2982 qc.setRgbF(redDefaultStr.toDouble(),
2983 greenDefaultStr.toDouble(),
2984 blueDefaultStr.toDouble());
2985 }
2986 QPixmap pixmap = QPixmap(QSize(16, 16));
2987 pixmap.fill (qc);
2988 QPainter painter(&pixmap);
2989 painter.setPen(Qt::black);
2990 painter.drawRect(0,0,15,15); // Draw contour
2991
2992 input = new QPushButton("Change color");
2993 dynamic_cast<QPushButton*>(input)->setIcon(pixmap);
2994 dynamic_cast<QPushButton*>(input)->setAccessibleName(redDefaultStr+" "+greenDefaultStr+" "+blueDefaultStr);
2995 label = new QLabel("Choose color");
2996
2997 // less 1 because we have to add one to the row number
2998 nbColorParameter--;
2999 gridLayout->addWidget(label,i_thParameter-nbColorParameter,0);
3000 input->setToolTip("Select the current color");
3001 gridLayout->addWidget(input,i_thParameter-nbColorParameter,1);
3002
3003 // Connect pushButton to ColorDialog in callback
3004#if QT_VERSION < 0x050600
3005 QSignalMapper* signalMapper = new QSignalMapper(this);
3006 signalMapper->setMapping(input,input);
3007 connect(input, SIGNAL(clicked()), signalMapper, SLOT(map()));
3008 connect(signalMapper, SIGNAL(mapped(QWidget*)),this, SLOT(ChangeColorCallback(QWidget*)));
3009#else
3010 connect(dynamic_cast<QPushButton*>(input), &QPushButton::clicked , [=](){ this->ChangeColorCallback(input);});
3011#endif
3012 isColorDialogAdded = true;
3013 isStillColorParameter = false;
3014 }
3015 } else {
3016 gridLayout->addWidget(label,i_thParameter-nbColorParameter,0);
3017 input->setToolTip(txt);
3018 gridLayout->addWidget(input,i_thParameter-nbColorParameter,1);
3019 }
3020 }
3021 // add command name in hidden value at last line position 0
3022 QLabel* name = new QLabel(QString((char*)(aCommand->GetCommandPath().data())));
3023 name->hide();
3024 gridLayout->addWidget(name,n_parameterEntry-nbColorParameter,0);
3025
3026 QPushButton* applyButton = new QPushButton("Apply");
3027 if (!isDialog) {
3028
3029 gridLayout->addWidget(applyButton,n_parameterEntry-nbColorParameter,1);
3030
3031#if QT_VERSION < 0x050600
3032 QSignalMapper* signalMapper = new QSignalMapper(this);
3033 signalMapper->setMapping(applyButton, paramWidget);
3034 connect(applyButton, SIGNAL(clicked()), signalMapper, SLOT(map()));
3035 connect(signalMapper, SIGNAL(mapped(QWidget*)),this, SLOT(VisParameterCallback(QWidget*)));
3036#else
3037 connect(applyButton, &QPushButton::clicked , [=](){ this->VisParameterCallback(paramWidget);});
3038#endif
3039 } else {
3040 // Apply/Cancel buttons
3041
3042 applyButton->setAutoDefault( TRUE );
3043 applyButton->setDefault( TRUE );
3044
3045 QPushButton* cancelButton = new QPushButton( tr( "&Cancel" ));
3046 cancelButton->setAutoDefault( TRUE );
3047 gridLayout->addWidget(cancelButton,n_parameterEntry-nbColorParameter,1);
3048 gridLayout->addWidget(applyButton,n_parameterEntry-nbColorParameter,0);
3049
3050#if QT_VERSION < 0x050600
3051 QSignalMapper* signalMapper = new QSignalMapper(this);
3052 signalMapper->setMapping(applyButton, paramWidget);
3053 connect(applyButton, SIGNAL(clicked()), signalMapper, SLOT(map()));
3054 connect(signalMapper, SIGNAL(mapped(QWidget*)),this, SLOT(VisParameterCallback(QWidget*)));
3055#else
3056 connect(applyButton, &QPushButton::clicked , [=](){ this->VisParameterCallback(paramWidget);});
3057#endif
3058
3059 QWidget * parentCheck = aParent;
3060 QDialog* parentDialog = NULL;
3061 bool found = false;
3062 while ((parentCheck->parentWidget()) != NULL) {
3063 parentCheck = parentCheck->parentWidget();
3064 parentDialog = dynamic_cast<QDialog*>(parentCheck);
3065 if (parentDialog) {
3066 connect( applyButton, SIGNAL( clicked() ), parentDialog, SLOT( accept() ) );
3067 connect( cancelButton, SIGNAL( clicked() ), parentDialog, SLOT( reject() ) );
3068 found = true;
3069 }
3070 }
3071 if (!found) {
3072 return false;
3073 }
3074 }
3075
3076 if (!aParent->layout()) {
3077 aParent->setLayout(new QVBoxLayout());
3078 }
3079 aParent->layout()->addWidget(paramWidget);
3080 }
3081
3082 return true;
3083}
3084
3085
3086/** Find a treeItemWidget in the help tree
3087 @param aCommand item's String to look for
3088 @return item if found, NULL if not
3089*/
3090QTreeWidgetItem* G4UIQt::FindTreeItem(
3091 QTreeWidgetItem *aParent
3092,const QString& aCommand
3093)
3094{
3095 if (aParent == NULL) return NULL;
3096
3097 // Suppress last "/"
3098 QString myCommand = aCommand;
3099
3100 if (myCommand.lastIndexOf("/") == (myCommand.size()-1)) {
3101 myCommand = myCommand.left(myCommand.size()-1);
3102 }
3103
3104 if (GetLongCommandPath(aParent) == myCommand)
3105 return aParent;
3106
3107 QTreeWidgetItem * tmp = NULL;
3108 for (int a=0;a<aParent->childCount();a++) {
3109 if (!tmp)
3110 tmp = FindTreeItem(aParent->child(a),myCommand);
3111 }
3112 return tmp;
3113}
3114
3115
3116
3117/** Build the command list parameters in a QString<br>
3118 Reimplement partialy the G4UIparameter.cc
3119 @param aCommand : command to list parameters
3120 @see G4UIparameter::List()
3121 @see G4UIcommand::List()
3122 @return the command list parameters, or "" if nothing
3123 */
3124QString G4UIQt::GetCommandList (
3125 const G4UIcommand *aCommand
3126 )
3127{
3128
3129 QString txt ="";
3130 if (aCommand == NULL)
3131 return txt;
3132
3133 G4String commandPath = aCommand->GetCommandPath();
3134 G4String rangeString = aCommand->GetRange();
3135 G4int n_guidanceEntry = aCommand->GetGuidanceEntries();
3136 G4int n_parameterEntry = aCommand->GetParameterEntries();
3137
3138 if ((commandPath == "") &&
3139 (rangeString == "") &&
3140 (n_guidanceEntry == 0) &&
3141 (n_parameterEntry == 0)) {
3142 return txt;
3143 }
3144
3145 if((commandPath.length()-1)!='/') {
3146 txt += "Command " + QString((char*)(commandPath).data()) + "\n";
3147 }
3148 txt += "Guidance :\n";
3149
3150 for( G4int i_thGuidance=0; i_thGuidance < n_guidanceEntry; i_thGuidance++ ) {
3151 txt += QString((char*)(aCommand->GetGuidanceLine(i_thGuidance)).data()) + "\n";
3152 }
3153 if( ! rangeString.isNull() ) {
3154 txt += " Range of parameters : " + QString((char*)(rangeString).data()) + "\n";
3155 }
3156 if( n_parameterEntry > 0 ) {
3157 G4UIparameter *param;
3158
3159 // Re-implementation of G4UIparameter.cc
3160
3161 for( G4int i_thParameter=0; i_thParameter<n_parameterEntry; i_thParameter++ ) {
3162 param = aCommand->GetParameter(i_thParameter);
3163 txt += "\nParameter : " + QString((char*)(param->GetParameterName()).data()) + "\n";
3164 if( ! param->GetParameterGuidance().isNull() )
3165 txt += QString((char*)(param->GetParameterGuidance()).data())+ "\n" ;
3166 txt += " Parameter type : " + QString(QChar(param->GetParameterType())) + "\n";
3167 if(param->IsOmittable()){
3168 txt += " Omittable : True\n";
3169 } else {
3170 txt += " Omittable : False\n";
3171 }
3172 if( param->GetCurrentAsDefault() ) {
3173 txt += " Default value : taken from the current value\n";
3174 } else if( ! param->GetDefaultValue().isNull() ) {
3175 txt += " Default value : " + QString((char*)(param->GetDefaultValue()).data())+ "\n";
3176 }
3177 if( ! param->GetParameterRange().isNull() ) {
3178 txt += " Parameter range : " + QString((char*)(param->GetParameterRange()).data())+ "\n";
3179 }
3180 if( ! param->GetParameterCandidates().isNull() ) {
3181 txt += " Candidates : " + QString((char*)(param->GetParameterCandidates()).data())+ "\n";
3182 }
3183 }
3184 }
3185 return txt;
3186}
3187
3188
3189/** Build the command list parameters in a QString with HTML<br>
3190 Reimplement partialy the G4UIparameter.cc
3191 @param aCommand : command to list parameters
3192 @see G4UIparameter::List()
3193 @see G4UIcommand::List()
3194 @return the command list parameters, or "" if nothing
3195*/
3196void G4UIQt::updateHelpArea (
3197 const G4UIcommand *aCommand
3198)
3199{
3200 if (!fParameterHelpLabel)
3201 return;
3202 if (!fParameterHelpTable)
3203 return;
3204
3205 fParameterHelpLabel->setTextInteractionFlags(Qt::NoTextInteraction);
3206 QString txt;
3207 if (aCommand == NULL)
3208 return;
3209
3210 G4String commandPath = aCommand->GetCommandPath();
3211 G4String rangeString = aCommand->GetRange();
3212 G4int n_guidanceEntry = aCommand->GetGuidanceEntries();
3213 G4int n_parameterEntry = aCommand->GetParameterEntries();
3214
3215 if ((commandPath == "") &&
3216 (rangeString == "") &&
3217 (n_guidanceEntry == 0) &&
3218 (n_parameterEntry == 0)) {
3219 return;
3220 }
3221
3222 if((commandPath.length()-1)!='/') {
3223 txt += "<b>Command </b> " + QString((char*)(commandPath).data()) + "<br />";
3224 }
3225 txt += "<b>Guidance :</b> ";
3226 QString tmpGuidance = "";
3227 for( G4int i_thGuidance=0; i_thGuidance < n_guidanceEntry; i_thGuidance++ ) {
3228 tmpGuidance = QString((char*)(aCommand->GetGuidanceLine(i_thGuidance)).data());
3229#if QT_VERSION < 0x050000
3230 tmpGuidance = Qt::escape(tmpGuidance);
3231#else
3232 tmpGuidance = tmpGuidance.toHtmlEscaped();
3233#endif
3234 tmpGuidance.replace("\n","<br />");
3235 txt += tmpGuidance + "<br />";
3236 }
3237 if( ! rangeString.isNull() ) {
3238 QString range = QString((char*)(rangeString).data());
3239#if QT_VERSION < 0x050000
3240 range = Qt::escape(range);
3241#else
3242 range = range.toHtmlEscaped();
3243#endif
3244
3245 txt += "<b>Range of parameters : </b> " + range + "<br />";
3246 } else {
3247 txt += "<br />";
3248 }
3249 fParameterHelpLabel->setHtml(txt);
3250
3251 if( n_parameterEntry > 0 ) {
3252 G4UIparameter *param;
3253
3254 // Re-implementation of G4UIparameter.cc
3255
3256 fParameterHelpTable->clear();
3257 fParameterHelpTable->setRowCount(n_parameterEntry);
3258 fParameterHelpTable->setColumnCount(8);
3259 fParameterHelpTable->setHorizontalHeaderLabels(QStringList() <<
3260 tr("") <<
3261 tr("Parameter") <<
3262 tr("Guidance") <<
3263 tr("Type") <<
3264 tr("Ommitable") <<
3265 tr("Default") <<
3266 tr("Range") <<
3267 tr("Candidate"));
3268 fParameterHelpTable->setColumnWidth(2,60);
3269
3270 fParameterHelpTable->verticalHeader()->setVisible(false);
3271 fParameterHelpTable->setAlternatingRowColors (true);
3272#if QT_VERSION < 0x050000
3273 fParameterHelpTable->verticalHeader()->setResizeMode(QHeaderView::ResizeToContents);
3274 fParameterHelpTable->horizontalHeader()->setResizeMode(2, QHeaderView::Stretch);
3275#else
3276 fParameterHelpTable->verticalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);
3277 fParameterHelpTable->horizontalHeader()->setSectionResizeMode(2, QHeaderView::Stretch);
3278#endif
3279 fParameterHelpTable->setWordWrap(true);
3280
3281 QTableWidgetItem* t = fParameterHelpTable->horizontalHeaderItem(1);
3282 QFont fnt = t->font();
3283 int size = fnt.pointSize();
3284 fnt.setPointSize(size-2);
3285
3286 for( G4int a=0; a<n_parameterEntry; a++ ) {
3287 param = aCommand->GetParameter(a);
3288 fParameterHelpTable->setItem(a, 0, new QTableWidgetItem(QString::number(a+1)));
3289
3290 fParameterHelpTable->setItem(a, 1, new QTableWidgetItem(QString((char*)(param->GetParameterName()).data())));
3291 if( ! param->GetParameterGuidance().isNull() ) {
3292 fParameterHelpTable->setItem(a, 2, new QTableWidgetItem(QString((char*)(param->GetParameterGuidance()).data())));
3293 }
3294 fParameterHelpTable->setItem(a, 3, new QTableWidgetItem(QString(QChar(param->GetParameterType()))));
3295
3296 if(param->IsOmittable()){
3297 fParameterHelpTable->setItem(a, 4, new QTableWidgetItem(QString("True")));
3298 } else {
3299 fParameterHelpTable->setItem(a, 4, new QTableWidgetItem(QString("False")));
3300 }
3301 if( param->GetCurrentAsDefault() ) {
3302 fParameterHelpTable->setItem(a, 5, new QTableWidgetItem(QString("taken from the current value")));
3303 } else if( ! param->GetDefaultValue().isNull() ) {
3304 fParameterHelpTable->setItem(a, 5, new QTableWidgetItem(QString((char*)(param->GetDefaultValue()).data())));
3305 }
3306 if( ! param->GetParameterRange().isNull() ) {
3307 fParameterHelpTable->setItem(a, 6, new QTableWidgetItem(QString((char*)(param->GetParameterRange()).data())));
3308 }
3309 if( ! param->GetParameterCandidates().isNull() ) {
3310 fParameterHelpTable->setItem(a, 7, new QTableWidgetItem(QString((char*)(param->GetParameterCandidates()).data())));
3311 }
3312 // tooltips
3313 for (int b=0; b<8; b++) {
3314 QTableWidgetItem* tmp = fParameterHelpTable->item(a,b);
3315 if (tmp) {
3316 tmp->setToolTip(tmp->text());
3317 tmp->setFlags(Qt::NoItemFlags);
3318 }
3319 }
3320 fParameterHelpTable->resizeRowToContents(a);
3321 }
3322 for (int c=0; c<8; c++) {
3323 if (c !=2) {
3324 fParameterHelpTable->resizeColumnToContents(c);
3325 }
3326 }
3327 fParameterHelpLabel->setVisible(true);
3328 fParameterHelpTable->setVisible(true);
3329
3330 }
3331}
3332
3333
3334/**
3335 Return true if this command takes almost a number (int, double, bool,
3336 string) as an input
3337 or a string with a candidate list
3338 */
3339G4bool G4UIQt::IsGUICommand(
3340 const G4UIcommand *aCommand
3341)
3342{
3343 if (aCommand == NULL)
3344 return false;
3345
3346 G4int n_parameterEntry = aCommand->GetParameterEntries();
3347
3348 if( n_parameterEntry > 0 ) {
3349 G4UIparameter *param;
3350
3351 // Re-implementation of G4UIparameter.cc
3352
3353 for( G4int i_thParameter=0; i_thParameter<n_parameterEntry; i_thParameter++ ) {
3354 param = aCommand->GetParameter(i_thParameter);
3355 if (QString(QChar(param->GetParameterType())) == "d") {
3356 return true;
3357 }
3358 if (QString(QChar(param->GetParameterType())) == "b") {
3359 return true;
3360 }
3361 if (QString(QChar(param->GetParameterType())) == "i") {
3362 return true;
3363 }
3364 if (QString(QChar(param->GetParameterType())) == "s") {
3365 return true;
3366 }
3367 }
3368 }
3369 return false;
3370}
3371
3372
3373/** Implement G4VBasicShell vurtual function
3374 */
3375G4bool G4UIQt::GetHelpChoice(
3376 G4int&
3377)
3378{
3379 return true;
3380}
3381
3382
3383/** Event filter method. Every event from QtApplication goes here.<br/>
3384 We apply a filter only for the Up and Down Arrow press when the QLineEdit<br/>
3385 is active. If this filter match, Up arrow we give the previous command<br/>
3386 and Down arrow will give the next if exist.<br/>
3387 @param obj Emitter of the event
3388 @param event Kind of event
3389*/
3390bool G4UIQt::eventFilter( // Should stay with a minuscule eventFilter because of Qt
3391 QObject *aObj
3392,QEvent *aEvent
3393)
3394{
3395 bool tabKeyPress = false;
3396 bool moveCommandCursor = false;
3397 if (aObj == NULL) return false;
3398 if (aEvent == NULL) return false;
3399
3400 if (aObj == fHistoryTBTableList) {
3401 if (aEvent->type() == QEvent::KeyPress) {
3402 fCommandArea->setFocus();
3403 }
3404 }
3405
3406 if (aObj == fCompleter->popup()) {
3407 if (aEvent->type() == QEvent::KeyPress) {
3408 QKeyEvent *e = static_cast<QKeyEvent*>(aEvent);
3409 if (e->key() == (Qt::Key_Tab)) {
3410 tabKeyPress = true;
3411 }
3412 } else if ( aEvent->type() == QEvent::Hide ) {
3413 // Store this value
3414 QString c = fCommandArea->text();
3415 fLastCompleteCommand = c.left(c.indexOf("<"));
3416 }
3417 }
3418
3419 if (aObj == fCommandArea) {
3420 if (aEvent->type() == QEvent::KeyPress) {
3421 QKeyEvent *e = static_cast<QKeyEvent*>(aEvent);
3422 if ((e->key() == (Qt::Key_Down)) ||
3423 (e->key() == (Qt::Key_PageDown)) ||
3424 (e->key() == (Qt::Key_Up)) ||
3425 (e->key() == (Qt::Key_PageUp))) {
3426 int selection = fHistoryTBTableList->currentRow();
3427 if (fHistoryTBTableList->count()) {
3428 if (selection == -1) {
3429 selection = fHistoryTBTableList->count()-1;
3430 } else {
3431 if (e->key() == (Qt::Key_Down)) {
3432 if (selection <(fHistoryTBTableList->count()-1))
3433 selection++;
3434 } else if (e->key() == (Qt::Key_PageDown)) {
3435 selection = fHistoryTBTableList->count()-1;
3436 } else if (e->key() == (Qt::Key_Up)) {
3437 if (selection >0)
3438 selection --;
3439 } else if (e->key() == (Qt::Key_PageUp)) {
3440 selection = 0;
3441 }
3442 }
3443 fHistoryTBTableList->clearSelection();
3444#if QT_VERSION < 0x040202
3445 fHistoryTBTableList->setItemSelected(fHistoryTBTableList->item(selection),true);
3446#else
3447 fHistoryTBTableList->item(selection)->setSelected(true);
3448#endif
3449 fHistoryTBTableList->setCurrentItem(fHistoryTBTableList->item(selection));
3450 }
3451 moveCommandCursor = true;
3452 } else if (e->key() == (Qt::Key_Tab)) {
3453 tabKeyPress = true;
3454 } else if (((e->modifiers () == Qt::ControlModifier) || (e->modifiers () == Qt::MetaModifier)) && (e->key() == Qt::Key_A)) {
3455 fCommandArea->home(false);
3456 return true;
3457 } else if (((e->modifiers () == Qt::ControlModifier) || (e->modifiers () == Qt::MetaModifier)) && (e->key() == Qt::Key_E)) {
3458 fCommandArea->end(false);
3459 return true;
3460 }
3461 } else if (aEvent->type() == QEvent::Paint) {
3462 if (fLastCompleteCommand != "") {
3463 fCommandArea->setText(fLastCompleteCommand);
3464 fLastCompleteCommand = "";
3465 }
3466 }
3467 }
3468 if (tabKeyPress == true) {
3469 G4String ss = Complete(fCommandArea->text().toStdString().c_str());
3470 fCommandArea->setText((char*)(ss.data()));
3471 fCommandArea->setFocus();
3472 // do not pass by parent, it will disable widget tab focus !
3473 return true;
3474 // L.Garnier : MetaModifier is CTRL for MAC, but I don't want to put a MAC
3475 // specific #ifdef
3476 }
3477
3478 bool res= false;
3479 // change cursor position if needed
3480 if (moveCommandCursor == true) {
3481 fCommandArea->setCursorPosition ( fCommandArea->text().length() );
3482 fCommandArea->setCursorPosition (4);
3483 } else {
3484 // pass the event on to the parent class
3485 res = QObject::eventFilter(aObj, aEvent);
3486 }
3487 return res;
3488}
3489
3490
3491void G4UIQt::UpdateCommandCompleter() {
3492 if (!fCommandArea) return;
3493
3494 // remove previous one
3495 fCommandArea->setCompleter(NULL);
3496 if (fCompleter) {
3497 if (fCompleter->popup()) {
3498 fCompleter->popup()->removeEventFilter(this);
3499 }
3500 }
3501
3502 QStandardItemModel* model = CreateCompleterModel("/");
3503 fCompleter = new QCompleter(model);
3504
3505 // set all dir visibles in completion
3507 G4UIcommandTree * commandTreeTop = UI->GetTree();
3508 G4UIcommandTree* aTree = commandTreeTop->FindCommandTree("/");
3509 if (aTree) {
3510 int Ndir= aTree-> GetTreeEntry();
3511 fCompleter->setMaxVisibleItems(Ndir);
3512 }
3513 fCommandArea->setCompleter(fCompleter);
3514 fCompleter->popup()->installEventFilter(this);
3515}
3516
3517
3518QStandardItemModel* G4UIQt::CreateCompleterModel(G4String aCmd) {
3519
3520 QList< QStandardItem*> dirModelList;
3521 QList< QStandardItem*> commandModelList;
3522 QList< QStandardItem*> subDirModelList;
3523 QList< QStandardItem*> subCommandModelList;
3524
3525 G4String strtmp;
3526 G4int nMatch= 0;
3527
3528 G4String pName = aCmd;
3529 G4String remainingPath = aCmd;
3530 G4String empty = "";
3531 G4String matchingPath = empty;
3532
3533 // find the tree
3534 G4int jpre= pName.last('/');
3535 if(jpre != G4int(G4String::npos)) pName.remove(jpre+1);
3537 G4UIcommandTree * commandTreeTop = UI->GetTree();
3538 G4UIcommandTree* aTree = commandTreeTop->FindCommandTree(pName);
3539 if (aTree) {
3540 int Ndir= aTree-> GetTreeEntry();
3541 int Ncmd= aTree-> GetCommandEntry();
3542
3543 // directory ...
3544 for(G4int idir=1; idir<=Ndir; idir++) {
3545 G4String fpdir= aTree-> GetTree(idir)-> GetPathName();
3546 // matching test
3547 if( fpdir.index(remainingPath, 0) == 0) {
3548 if(nMatch==0) {
3549 matchingPath = fpdir;
3550 } else {
3551 matchingPath = aTree->GetFirstMatchedString(fpdir,matchingPath);
3552 }
3553 nMatch++;
3554
3555 // append to dir model list
3556 QStandardItem* item1 = new QStandardItem(fpdir.data());
3557 QIcon i = QIcon(*fDirIcon);
3558 item1->setData(1); // dir
3559 item1->setIcon(QIcon(*fDirIcon));
3560 dirModelList.append(item1);
3561
3562 // Go recursively
3563 QStandardItemModel* subModel = CreateCompleterModel(fpdir.data());
3564 for (int a=0; a< subModel->rowCount(); a++) {
3565
3566 // copy item (an item could only be part of one model
3567 QStandardItem* tempItem = new QStandardItem(subModel->item(a)->text());
3568 tempItem->setIcon(subModel->item(a)->icon());
3569 tempItem->setToolTip(subModel->item(a)->toolTip());
3570 tempItem->setData(subModel->item(a)->data());
3571
3572 // dir
3573 if (tempItem->data() == 1) {
3574 subModel->item(a);
3575 subDirModelList.append(tempItem);
3576 }
3577 // command
3578 else if (tempItem->data() == 0) {
3579 subCommandModelList.append(tempItem);
3580 }
3581 }
3582 }
3583 }
3584
3585 // command ...
3586 G4int n_parameterEntry;
3587 G4String rangeString;
3588 G4int n_guidanceEntry;
3589 G4UIcommand * command;
3590 G4UIparameter *param;
3591 std::string tooltip;
3592 G4String params;
3593
3594 for(G4int icmd=1; icmd<=Ncmd; icmd++){
3595 tooltip = "";
3596 params = " ";
3597 command = aTree-> GetCommand(icmd);
3598 G4String longCommandName= aTree-> GetPathName() +
3599 command -> GetCommandName();
3600 rangeString = command->GetRange();
3601 n_guidanceEntry = command->GetGuidanceEntries();
3602 n_parameterEntry = command->GetParameterEntries();
3603
3604
3605 // matching test
3606 if( longCommandName.index(remainingPath, 0) ==0) {
3607 if(nMatch==0) {
3608 matchingPath= longCommandName + " ";
3609 } else {
3610 strtmp= longCommandName + " ";
3611 matchingPath= aTree->GetFirstMatchedString(matchingPath, strtmp);
3612 }
3613
3614 // guidance
3615 for( G4int i_thGuidance=0; i_thGuidance < n_guidanceEntry; i_thGuidance++ ) {
3616 tooltip += std::string((command->GetGuidanceLine(i_thGuidance)).data());
3617 if (i_thGuidance < n_guidanceEntry-1 ) {
3618 tooltip += "\n";
3619 }
3620 }
3621
3622 // parameters
3623 for( G4int a=0; a<n_parameterEntry; a++ ) {
3624 param = command->GetParameter(a);
3625 if (param->IsOmittable()) {
3626 params += "[<" + param->GetParameterName()+">] ";
3627 } else {
3628 params += "<" + param->GetParameterName()+"> ";
3629 }
3630 }
3631 nMatch++;
3632
3633 // Append to command model list
3634 QStandardItem* item = new QStandardItem(G4String(longCommandName + params).data());
3635 item->setData(0); // command
3636 item->setIcon(QIcon(*fCommandIcon));
3637 item->setToolTip(tooltip.c_str());
3638
3639 commandModelList.append(item);
3640 }
3641 }
3642 }
3643
3644 QStandardItemModel* model = new QStandardItemModel();
3645 // initialize the model
3646 model->setColumnCount(1);
3647
3648 // concat models
3649 for (int a= 0; a< dirModelList.size(); a++) {
3650 model->appendRow(dirModelList.at(a));
3651 }
3652 for (int a= 0; a< subDirModelList.size(); a++) {
3653 model->appendRow(subDirModelList.at(a));
3654 }
3655 for (int a= 0; a< commandModelList.size(); a++) {
3656 model->appendRow(commandModelList.at(a));
3657 }
3658 for (int a= 0; a< subCommandModelList.size(); a++) {
3659 model->appendRow(subCommandModelList.at(a));
3660 }
3661
3662 return model;
3663}
3664
3665
3666/***************************************************************************/
3667//
3668// SLOTS DEFINITIONS
3669//
3670/***************************************************************************/
3671
3672/** Called when user give "help" command.
3673*/
3674void G4UIQt::ShowHelpCallback (
3675)
3676{
3677 TerminalHelp("");
3678}
3679
3680
3681/** Called when user click on clear button. Clear the text Output area
3682*/
3683void G4UIQt::ClearButtonCallback (
3684)
3685{
3686 fCoutTBTextArea->clear();
3687 fG4OutputString.clear();
3688}
3689
3690/** Called when user exit session
3691*/
3692void G4UIQt::ExitSession (
3693)
3694{
3695 SessionTerminate();
3696}
3697
3698void G4UIQt::ExitHelp(
3699) const
3700{
3701}
3702
3703/** Callback call when "click on a menu entry.<br>
3704 Send the associated command to geant4
3705*/
3706void G4UIQt::CommandEnteredCallback (
3707)
3708{
3709 // split by any new line character
3710 fCommandArea->setText(fCommandArea->text().trimmed());
3711#if QT_VERSION < 0x050F00
3712 // Before Qt5.15
3713 QStringList list = fCommandArea->text().split(QRegExp("[\r\n]"),QString::SkipEmptyParts);
3714#else
3715 // Qt5.15 and beyond
3716 QStringList list = fCommandArea->text().split(QRegExp("[\r\n]"),Qt::SkipEmptyParts);
3717#endif
3718
3719 // Apply for all commands
3720 for (int a=0; a< list.size(); a++) {
3721 QString txt (list[a].trimmed());
3722 if (txt != "") {
3723 fHistoryTBTableList->addItem(txt);
3724 fHistoryTBTableList->clearSelection();
3725 fHistoryTBTableList->setCurrentItem(NULL);
3726 fCommandArea->setText("");
3727 G4Qt* interactorManager = G4Qt::getInstance ();
3728 if (interactorManager) {
3729 interactorManager->FlushAndWaitExecution();
3730 }
3731
3732 G4String command = txt.toStdString().c_str();
3733 if (command(0,4) != "help") {
3734 ApplyShellCommand (command,exitSession,exitPause);
3735 } else {
3736 ActivateCommand(command);
3737 }
3738 }
3739 }
3740 // set the focus to the command line
3741 fCommandArea->setFocus();
3742
3743 // Rebuild help tree
3744 FillHelpTree();
3745
3746 // Rebuild command completion
3747 UpdateCommandCompleter();
3748
3749 if(exitSession==true)
3750 SessionTerminate();
3751}
3752
3753
3754/** Callback when the text in the line edit is changed.
3755 When a newline is inserted, trigger the Activate Command
3756 on this text end set unchanged the end of the line after the newline.
3757 */
3758void G4UIQt::CommandEditedCallback(const QString &)
3759{
3760#if QT_VERSION < 0x050F00
3761 // Before Qt5.15
3762 QStringList list = fCommandArea->text().split(QRegExp("[\r\n]"),QString::SkipEmptyParts);
3763#else
3764 // Qt5.15 and beyond
3765 QStringList list = fCommandArea->text().split(QRegExp("[\r\n]"),Qt::SkipEmptyParts);
3766#endif
3767
3768 if (list.size() > 1) { // trigger ActivateCommand
3769 for (int a=0; a<list.size()-1; a++) {
3770 // set only the first part
3771 fCommandArea->setText(list[a]);
3772 // trigger callback
3773 CommandEnteredCallback();
3774 }
3775 // reset unfinished command
3776 fCommandArea->setText(list[list.size()-1]);
3777 }
3778}
3779
3780
3781/** Callback when one of the scene/vis parameters has changed
3782 */
3783void G4UIQt::VisParameterCallback(QWidget* widget){
3784 if (widget == NULL) {
3785 return;
3786 }
3787
3788 // Look in all the Grid layout, but only column 1 (0 is the parameter name)
3789 QGridLayout* grid = dynamic_cast<QGridLayout*>(widget->layout());
3790 if (grid == 0) {
3791 return;
3792 }
3793 QString command;
3794#if QT_VERSION < 0x040400
3795 QWidget* name = grid->itemAt(grid->columnCount()*(grid->rowCount()-2))->widget();
3796#else
3797 QWidget* name = grid->itemAtPosition(grid->rowCount()-1,0)->widget();
3798#endif
3799 if (dynamic_cast<QLabel*>(name) == 0) {
3800 return;
3801 }
3802 command += (dynamic_cast<QLabel*>(name))->text()+" ";
3803
3804 for (int a=0;a<grid->rowCount()-1; a++) {
3805#if QT_VERSION < 0x040400
3806 QWidget* widgetTmp = grid->itemAt(a*grid->columnCount()+1)->widget();
3807#else
3808 QWidget* widgetTmp = grid->itemAtPosition(a,1)->widget();
3809#endif
3810
3811 // 4 kind of widgets : QLineEdit / QComboBox / radioButtonsGroup / QPushButton (color chooser)
3812 if (widgetTmp != NULL) {
3813
3814 if (dynamic_cast<QLineEdit*>(widgetTmp) != 0) {
3815 command += (dynamic_cast<QLineEdit*>(widgetTmp))->text()+" ";
3816
3817 } else if (dynamic_cast<QComboBox*>(widgetTmp) != 0){
3818 command += (dynamic_cast<QComboBox*>(widgetTmp))->itemText((dynamic_cast<QComboBox*>(widgetTmp))->currentIndex())+" ";
3819
3820 // Color chooser
3821 } else if (dynamic_cast<QPushButton*>(widgetTmp) != 0){
3822 command += widgetTmp->accessibleName()+" ";
3823
3824 // Check for Button group
3825 } else if (dynamic_cast<QWidget*>(widgetTmp) != 0){
3826 if (widgetTmp->layout()->count() > 0){
3827 if (dynamic_cast<QRadioButton*>(widgetTmp->layout()->itemAt(0)->widget()) != 0) {
3828 QAbstractButton * checked = (dynamic_cast<QRadioButton*>(widgetTmp->layout()->itemAt(0)->widget()))->group()->checkedButton();
3829 if (checked != 0) {
3830 command += (dynamic_cast<QRadioButton*>(widgetTmp->layout()->itemAt(0)->widget()))->group()->checkedButton()->text()+" ";
3831 }
3832 }
3833 }
3834
3835 }
3836 }
3837 }
3838 if (command != "") {
3840 if(UI != NULL) {
3841 UI->ApplyCommand(command.toStdString().c_str());
3842 }
3843 }
3844}
3845
3846
3847/** Callback call when "enter" clicked on the command zone.<br>
3848 If command has no parameters :send the command to geant4
3849 Else, open a dialog for parameters input
3850 @param aCommand
3851*/
3852void G4UIQt::ButtonCallback (
3853 const QString& aCommand
3854)
3855{
3856 G4String ss = G4String(aCommand.toStdString().c_str());
3857 ss = ss.strip(G4String::leading);
3858
3860 if(UI==NULL) return;
3861 G4UIcommandTree * treeTop = UI->GetTree();
3862
3863 G4UIcommand* command = treeTop->FindPath(ss);
3864
3865 if (command) {
3866 // if is GUI, then open a dialog
3867 if (IsGUICommand(command)) {
3868 QDialog* menuParameterDialog = new QDialog();
3869
3870 if (CreateVisCommandGroupAndToolBox(command,menuParameterDialog,1,true)) {
3871 menuParameterDialog->setWindowTitle (aCommand);
3872 menuParameterDialog->setSizePolicy (QSizePolicy(QSizePolicy::Minimum,QSizePolicy::Minimum));
3873
3874 // exec this dialog, apply the command automaticaly, and return
3875 menuParameterDialog->exec();
3876 return;
3877 }
3878 delete menuParameterDialog;
3879 }
3880 }
3881
3882 ApplyShellCommand(ss,exitSession,exitPause);
3883
3884 // Rebuild help tree
3885 FillHelpTree();
3886
3887 if(exitSession==true)
3888 SessionTerminate();
3889}
3890
3891
3892
3893/** This callback is activated when user selected a item in the help tree
3894*/
3895void G4UIQt::HelpTreeClicCallback (
3896)
3897{
3898 QTreeWidgetItem* item = NULL;
3899 if (!fHelpTreeWidget)
3900 return ;
3901
3902 QList<QTreeWidgetItem *> list =fHelpTreeWidget->selectedItems();
3903 if (list.isEmpty())
3904 return;
3905 item = list.first();
3906 if (!item)
3907 return;
3908
3910 if(UI==NULL) return;
3911 G4UIcommandTree * treeTop = UI->GetTree();
3912
3913 std::string itemText = GetLongCommandPath(item).toStdString();
3914
3915 // check if it is a command path
3916 if (item->childCount() > 0) {
3917 itemText +="/";
3918 }
3919 G4UIcommand* command = treeTop->FindPath(itemText.c_str());
3920
3921 if (command) {
3922 updateHelpArea(command);
3923 } else { // this is a command
3924 G4UIcommandTree* path = treeTop->FindCommandTree(itemText.c_str());
3925 if ( path) {
3926 // this is not a command, this is a sub directory
3927 // We display the Title
3928 fParameterHelpLabel->setVisible(true);
3929 fParameterHelpLabel->setText(path->GetTitle().data());
3930 fParameterHelpTable->setVisible(false);
3931 }
3932 }
3933}
3934
3935/** This callback is activated when user double clic on a item in the help tree
3936*/
3937void G4UIQt::HelpTreeDoubleClicCallback (
3938)
3939{
3940 HelpTreeClicCallback();
3941
3942 QTreeWidgetItem* item = NULL;
3943 if (!fHelpTreeWidget)
3944 return ;
3945
3946 QList<QTreeWidgetItem *> list =fHelpTreeWidget->selectedItems();
3947 if (list.isEmpty())
3948 return;
3949 item = list.first();
3950 if (!item)
3951 return;
3952
3953 fCommandArea->clear();
3954 fCommandArea->setText(GetLongCommandPath(item));
3955}
3956
3957
3958/** Callback called when user select an old command in the command history<br>
3959 Give it to the command area.
3960*/
3961void G4UIQt::CommandHistoryCallback(
3962)
3963{
3964 QListWidgetItem* item = NULL;
3965 if (!fHistoryTBTableList)
3966 return ;
3967
3968
3969 QList<QListWidgetItem *> list =fHistoryTBTableList->selectedItems();
3970 if (list.isEmpty())
3971 return;
3972 item = list.first();
3973 if (!item)
3974 return;
3975 fCommandArea->setText(item->text());
3976}
3977
3978
3979void G4UIQt::ThreadComboBoxCallback(int) {
3980 CoutFilterCallback("");
3981}
3982
3983
3984void G4UIQt::CoutFilterCallback(
3985const QString &) {
3986
3987 FilterAllOutputTextArea();
3988
3989 fCoutTBTextArea->repaint();
3990 fCoutTBTextArea->verticalScrollBar()->setSliderPosition(fCoutTBTextArea->verticalScrollBar()->maximum());
3991
3992 }
3993
3994
3995void G4UIQt::SaveOutputCallback(){
3996 QString fileName = QFileDialog::getSaveFileName(fMainWindow, "Save console output as...", fLastOpenPath, "Save output as...");
3997 if (fileName != "") {
3998
3999 QFile data(fileName);
4000 if (data.open(QFile::WriteOnly | QFile::Truncate)) {
4001 QTextStream out(&data);
4002 out << fCoutTBTextArea->toPlainText();
4003 out.flush();
4004 }
4005 data.close();
4006 }
4007}
4008
4009
4010QString G4UIQt::FilterOutput(
4011 const G4UIOutputString& output
4012,const QString& currentThread
4013,const QString& filter
4014) {
4015
4016#ifdef G4MULTITHREADED
4017 if ((currentThread == "All") ||
4018 (currentThread == output.fThread)) {
4019#else
4020 if (currentThread == "") {
4021#endif
4022 if (output.fText.contains(QRegExp(filter))) {
4023 return output.fText;
4024 }
4025 }
4026 return "";
4027}
4028
4029
4030void G4UIQt::FilterAllOutputTextArea() {
4031
4032 QString currentThread = "";
4033#ifdef G4MULTITHREADED
4034 currentThread = fThreadsFilterComboBox->currentText();
4035 if (currentThread == "Master") {
4036 currentThread = "";
4037 }
4038#endif
4039 QString filter = fCoutFilter->text();
4040 G4String previousOutputStream = "";
4041
4042 QString pref = "";
4043 QString post = "";
4044
4045 fCoutTBTextArea->clear();
4046
4047 for (unsigned int a=0; a<fG4OutputString.size(); a++) {
4048 G4UIOutputString out = fG4OutputString[a];
4049 if (FilterOutput(out,currentThread,filter) != "") {
4050
4051 // changing color ?
4052 if (out.fOutputStream != previousOutputStream) {
4053 previousOutputStream = out.fOutputStream;
4054 if (out.fOutputStream == "info") {
4055 pref = "";
4056 post = "";
4057 } else if (out.fOutputStream == "warning") {
4058 pref = "<font color=\"DarkYellow\">";
4059 post = "</font>";
4060 } else {
4061 pref = "<font color=\"Red\">";
4062 post = "</font>";
4063 }
4064 }
4065 fCoutTBTextArea->append(pref + out.fText + post);
4066 }
4067 }
4068}
4069
4070
4071/** Callback called when user give a new string to look for<br>
4072 Display a list of matching commands descriptions. If no string is set,
4073 will display the complete help tree
4074*/
4075void G4UIQt::LookForHelpStringCallback(
4076)
4077{
4078 fHelpLine->setText(fHelpLine->text().trimmed());
4079 QString searchText = fHelpLine->text();
4080
4081 fParameterHelpLabel->setText("");
4082 fParameterHelpTable->setVisible(false);
4083 if (searchText =="") {
4084 // clear old help tree
4085 fHelpTreeWidget->clear();
4086
4087 FillHelpTree();
4088
4089 return;
4090 } else {
4091 OpenHelpTreeOnCommand(searchText);
4092 }
4093}
4094
4095
4096void G4UIQt::OpenHelpTreeOnCommand(
4097 const QString & searchText
4098)
4099{
4100 // the help tree
4102 if(UI==NULL) return;
4103 G4UIcommandTree * treeTop = UI->GetTree();
4104
4105 G4int treeSize = treeTop->GetTreeEntry();
4106
4107 // clear old help tree
4108 fHelpTreeWidget->clear();
4109
4110 // look for new items
4111
4112 int tmp = 0;
4113
4114#if QT_VERSION < 0x050F00
4115 // Before Qt5.15
4116 QMap<int,QString> commandResultMap;
4117 QMap<int,QString> commandChildResultMap;
4118 for (int a=0;a<treeSize;a++) {
4119 G4UIcommand* command = treeTop->FindPath(treeTop->GetTree(a+1)->GetPathName().data());
4120 tmp = GetCommandList (command).count(searchText,Qt::CaseInsensitive);
4121 if (tmp >0) {
4122 commandResultMap.insertMulti(tmp,QString((char*)(treeTop->GetTree(a+1)->GetPathName()).data()));
4123 }
4124 // look for childs
4125 commandChildResultMap = LookForHelpStringInChildTree(treeTop->GetTree(a+1),searchText);
4126 // insert new childs
4127 if (!commandChildResultMap.empty()) {
4128 QMap<int,QString>::const_iterator i = commandChildResultMap.constBegin();
4129 while (i != commandChildResultMap.constEnd()) {
4130 commandResultMap.insertMulti(i.key(),i.value());
4131 i++;
4132 }
4133 commandChildResultMap.clear();
4134 }
4135 }
4136#else
4137 // Qt5.15 and beyond
4138 QMultiMap<int,QString> commandResultMap;
4139 QMultiMap<int,QString> commandChildResultMap;
4140 for (int a=0;a<treeSize;a++) {
4141 G4UIcommand* command = treeTop->FindPath(treeTop->GetTree(a+1)->GetPathName().data());
4142 tmp = GetCommandList (command).count(searchText,Qt::CaseInsensitive);
4143 if (tmp >0) {
4144 commandResultMap.insert(tmp,QString((char*)(treeTop->GetTree(a+1)->GetPathName()).data()));
4145 }
4146 // look for childs
4147 commandChildResultMap = LookForHelpStringInChildTree(treeTop->GetTree(a+1),searchText);
4148 // insert new childs
4149 if (!commandChildResultMap.empty()) {
4150 QMap<int,QString>::const_iterator i = commandChildResultMap.constBegin();
4151 while (i != commandChildResultMap.constEnd()) {
4152 commandResultMap.insert(i.key(),i.value());
4153 i++;
4154 }
4155 commandChildResultMap.clear();
4156 }
4157 }
4158#endif
4159
4160 // build new help tree
4161 fHelpTreeWidget->setSelectionMode(QAbstractItemView::SingleSelection);
4162 fHelpTreeWidget->setColumnCount(2);
4163 QStringList labels;
4164 labels << QString("Command") << QString("Match");
4165 fHelpTreeWidget->setHeaderLabels(labels);
4166
4167 if (commandResultMap.empty()) {
4168 fParameterHelpLabel->setText("No match found");
4169 fParameterHelpTable->setVisible(false);
4170 return;
4171 }
4172
4173 QMap<int,QString>::const_iterator i = commandResultMap.constEnd();
4174 i--;
4175 // 10 maximum progress values
4176 float multValue = 10.0/(float)(i.key());
4177 QString progressChar = "|";
4178 QString progressStr = "|";
4179
4180 QTreeWidgetItem * newItem;
4181 bool end = false;
4182 while (!end) {
4183 if (i == commandResultMap.constBegin()) {
4184 end = true;
4185 }
4186 for(int a=0;a<int(i.key()*multValue);a++) {
4187 progressStr += progressChar;
4188 }
4189 newItem = new QTreeWidgetItem();
4190 QString commandStr = i.value().trimmed();
4191
4192 if (commandStr.indexOf("/") == 0) {
4193 commandStr = commandStr.right(commandStr.size()-1);
4194 }
4195
4196 newItem->setText(0,commandStr);
4197 newItem->setText(1,progressStr);
4198 fHelpTreeWidget->addTopLevelItem(newItem);
4199#if QT_VERSION < 0x040200
4200#else
4201 newItem->setForeground ( 1, QBrush(Qt::blue) );
4202#endif
4203 progressStr = "|";
4204 i--;
4205 }
4206 fHelpTreeWidget->resizeColumnToContents (0);
4207 fHelpTreeWidget->sortItems(1,Qt::DescendingOrder);
4208 // fHelpTreeWidget->setColumnWidth(1,10);//resizeColumnToContents (1);
4209}
4210
4211#if QT_VERSION < 0x050F00
4212// Before Qt5.15
4213QMap<int,QString> G4UIQt::LookForHelpStringInChildTree(
4214 G4UIcommandTree *aCommandTree
4215,const QString & text
4216 )
4217{
4218 QMap<int,QString> commandResultMap;
4219 if (aCommandTree == NULL) return commandResultMap;
4220 // Get the Sub directories
4221 int tmp = 0;
4222 QMap<int,QString> commandChildResultMap;
4223 for (int a=0;a<aCommandTree->GetTreeEntry();a++) {
4224 const G4UIcommand* command = aCommandTree->GetGuidance();
4225 tmp = GetCommandList (command).count(text,Qt::CaseInsensitive);
4226 if (tmp >0) {
4227 commandResultMap.insertMulti(tmp,QString((char*)(aCommandTree->GetTree(a+1)->GetPathName()).data()));
4228 }
4229 // look for childs
4230 commandChildResultMap = LookForHelpStringInChildTree(aCommandTree->GetTree(a+1),text);
4231 if (!commandChildResultMap.empty()) {
4232 // insert new childs
4233 QMap<int,QString>::const_iterator i = commandChildResultMap.constBegin();
4234 while (i != commandChildResultMap.constEnd()) {
4235 commandResultMap.insertMulti(i.key(),i.value());
4236 i++;
4237 }
4238 commandChildResultMap.clear();
4239 }
4240 }
4241 // Get the Commands
4242 for (int a=0;a<aCommandTree->GetCommandEntry();a++) {
4243 const G4UIcommand* command = aCommandTree->GetCommand(a+1);
4244 tmp = GetCommandList (command).count(text,Qt::CaseInsensitive);
4245 if (tmp >0) {
4246 commandResultMap.insertMulti(tmp,QString((char*)(aCommandTree->GetCommand(a+1)->GetCommandPath()).data()));
4247 }
4248 }
4249 return commandResultMap;
4250}
4251#else
4252// Qt5.15 and beyond
4253QMultiMap<int,QString> G4UIQt::LookForHelpStringInChildTree(
4254 G4UIcommandTree *aCommandTree
4255,const QString & text
4256 )
4257{
4258 QMultiMap<int,QString> commandResultMap;
4259 if (aCommandTree == NULL) return commandResultMap;
4260 // Get the Sub directories
4261 int tmp = 0;
4262 QMultiMap<int,QString> commandChildResultMap;
4263 for (int a=0;a<aCommandTree->GetTreeEntry();a++) {
4264 const G4UIcommand* command = aCommandTree->GetGuidance();
4265 tmp = GetCommandList (command).count(text,Qt::CaseInsensitive);
4266 if (tmp >0) {
4267 commandResultMap.insert(tmp,QString((char*)(aCommandTree->GetTree(a+1)->GetPathName()).data()));
4268 }
4269 // look for childs
4270 commandChildResultMap = LookForHelpStringInChildTree(aCommandTree->GetTree(a+1),text);
4271 if (!commandChildResultMap.empty()) {
4272 // insert new childs
4273 QMap<int,QString>::const_iterator i = commandChildResultMap.constBegin();
4274 while (i != commandChildResultMap.constEnd()) {
4275 commandResultMap.insert(i.key(),i.value());
4276 i++;
4277 }
4278 commandChildResultMap.clear();
4279 }
4280 }
4281 // Get the Commands
4282 for (int a=0;a<aCommandTree->GetCommandEntry();a++) {
4283 const G4UIcommand* command = aCommandTree->GetCommand(a+1);
4284 tmp = GetCommandList (command).count(text,Qt::CaseInsensitive);
4285 if (tmp >0) {
4286 commandResultMap.insert(tmp,QString((char*)(aCommandTree->GetCommand(a+1)->GetCommandPath()).data()));
4287 }
4288 }
4289 return commandResultMap;
4290}
4291#endif
4292
4293
4294QString G4UIQt::GetShortCommandPath(
4295QString commandPath
4296)
4297{
4298 if (commandPath.indexOf("/") == 0) {
4299 commandPath = commandPath.right(commandPath.size()-1);
4300 }
4301
4302 commandPath = commandPath.right(commandPath.size()-commandPath.lastIndexOf("/",-2)-1);
4303
4304 if (commandPath.lastIndexOf("/") == (commandPath.size()-1)) {
4305 commandPath = commandPath.left(commandPath.size()-1);
4306 }
4307
4308 return commandPath;
4309}
4310
4311
4312QString G4UIQt::GetLongCommandPath(
4313 QTreeWidgetItem* item
4314)
4315{
4316 if (item == NULL) return "";
4317
4318 // rebuild path:
4319 QString itemText = "";
4320 itemText = item->text(0);
4321
4322 while (item->parent() != NULL) {
4323 itemText = item->parent()->text(0)+"/"+itemText;
4324 item = item->parent();
4325 }
4326 itemText = "/"+itemText;
4327
4328 return itemText;
4329}
4330
4331
4332void G4UIQt::ChangeColorCallback(QWidget* widget) {
4333 if (widget == NULL) {
4334 return;
4335 }
4336
4337 QPushButton* button = dynamic_cast<QPushButton*>(widget);
4338 if (button == 0) {
4339 return;
4340 }
4341 QString value = button->accessibleName();
4342
4343 QColor old;
4344 old.setRgbF(value.section(" ",0,1).toDouble(),
4345 value.section(" ",1,2).toDouble(),
4346 value.section(" ",2,3).toDouble());
4347#if QT_VERSION < 0x040500
4348 bool a;
4349 QColor color = QColor(QColorDialog::getRgba (old.rgba(),&a,fUITabWidget));
4350#else
4351 QColor color = QColorDialog::getColor(old,
4352 fUITabWidget,
4353 "Change color",
4354 QColorDialog::ShowAlphaChannel);
4355#endif
4356
4357
4358 if (color.isValid()) {
4359 // rebuild the widget icon
4360 QPixmap pixmap = QPixmap(QSize(16, 16));
4361 pixmap.fill (color);
4362 QPainter painter(&pixmap);
4363 painter.setPen(Qt::black);
4364 painter.drawRect(0,0,15,15); // Draw contour
4365
4366 button->setAccessibleName(QString::number(color.redF())+" "+
4367 QString::number(color.greenF())+" "+
4368 QString::number(color.blueF())+" "
4369 );
4370 button->setIcon(pixmap);
4371
4372
4373 }
4374}
4375
4376
4377void G4UIQt::ChangeCursorAction(const QString& action) {
4378
4379 // Theses actions should be in the app toolbar
4380
4381 fMoveSelected = true;
4382 fPickSelected = true;
4383 fRotateSelected = true;
4384 fZoomInSelected = true;
4385 fZoomOutSelected = true;
4386
4387 if (fToolbarApp == NULL) return;
4388 QList<QAction *> list = fToolbarApp->actions ();
4389 for (int i = 0; i < list.size(); ++i) {
4390 if (list.at(i)->data().toString () == action) {
4391 list.at(i)->setChecked(TRUE);
4392 if (list.at(i)->data().toString () == "pick") {
4393 G4UImanager::GetUIpointer()->ApplyCommand("/vis/viewer/set/picking true");
4394 CreatePickInfosDialog();
4395
4396 fPickInfosDialog->show();
4397 fPickInfosDialog->raise();
4398 fPickInfosDialog->activateWindow();
4399 }
4400 } else if (list.at(i)->data().toString () == "move") {
4401 fMoveSelected = false;
4402 list.at(i)->setChecked(FALSE);
4403 } else if (list.at(i)->data().toString () == "pick") {
4404 fPickSelected = false;
4405 list.at(i)->setChecked(FALSE);
4406 G4UImanager::GetUIpointer()->ApplyCommand("/vis/viewer/set/picking false");
4407 if (fPickInfosDialog) {
4408 fPickInfosDialog->hide();
4409 }
4410 } else if (list.at(i)->data().toString () == "rotate") {
4411 fRotateSelected = false;
4412 list.at(i)->setChecked(FALSE);
4413 } else if (list.at(i)->data().toString () == "zoom_in") {
4414 fZoomInSelected = false;
4415 list.at(i)->setChecked(FALSE);
4416 } else if (list.at(i)->data().toString () == "zoom_out") {
4417 fZoomOutSelected = false;
4418 list.at(i)->setChecked(FALSE);
4419 }
4420 }
4421 // FIXME : Should connect this to Vis
4422}
4423
4424
4425/* A little bit like "void G4OpenGLQtViewer::toggleDrawingAction(int aAction)"
4426 But for all viewers, not only Qt
4427
4428FIXME : Should be a feedback when changing viewer !
4429
4430 */
4431void G4UIQt::ChangeSurfaceStyle(const QString& action) {
4432
4433 // Theses actions should be in the app toolbar
4434
4435 if (fToolbarApp == NULL) return;
4436 QList<QAction *> list = fToolbarApp->actions ();
4437 for (int i = 0; i < list.size(); ++i) {
4438 if (list.at(i)->data().toString () == action) {
4439 list.at(i)->setChecked(TRUE);
4440 } else if (list.at(i)->data().toString () == "hidden_line_removal") {
4441 list.at(i)->setChecked(FALSE);
4442 } else if (list.at(i)->data().toString () == "hidden_line_and_surface_removal") {
4443 list.at(i)->setChecked(FALSE);
4444 } else if (list.at(i)->data().toString () == "solid") {
4445 list.at(i)->setChecked(FALSE);
4446 } else if (list.at(i)->data().toString () == "wireframe") {
4447 list.at(i)->setChecked(FALSE);
4448 }
4449 }
4450 // FIXME : Should connect this to Vis
4451
4452 if (action == "hidden_line_removal") {
4453 G4UImanager::GetUIpointer()->ApplyCommand("/vis/viewer/set/style w");
4454 G4UImanager::GetUIpointer()->ApplyCommand("/vis/viewer/set/hiddenEdge 1");
4455
4456 } else if (action == "hidden_line_and_surface_removal") {
4457 G4UImanager::GetUIpointer()->ApplyCommand("/vis/viewer/set/style s");
4458 G4UImanager::GetUIpointer()->ApplyCommand("/vis/viewer/set/hiddenEdge 1");
4459
4460 } else if (action == "solid") {
4461 G4UImanager::GetUIpointer()->ApplyCommand("/vis/viewer/set/style s");
4462 G4UImanager::GetUIpointer()->ApplyCommand("/vis/viewer/set/hiddenEdge 0");
4463
4464 } else if (action == "wireframe") {
4465 G4UImanager::GetUIpointer()->ApplyCommand("/vis/viewer/set/style w");
4466 G4UImanager::GetUIpointer()->ApplyCommand("/vis/viewer/set/hiddenEdge 0");
4467 }
4468}
4469
4470
4471void G4UIQt::OpenIconCallback(const QString& aParam) {
4472
4473 QString aCommand = aParam.left(aParam.indexOf(fStringSeparator));
4474 QString aLabel = aParam.mid(aParam.indexOf(fStringSeparator)+fStringSeparator.length());
4475
4476 QString nomFich = QFileDialog::getOpenFileName(fMainWindow, aLabel, fLastOpenPath, "Macro files (*.mac)");
4477 if (nomFich != "") {
4478 G4UImanager::GetUIpointer()->ApplyCommand((QString(aCommand)+ QString(" ")+ nomFich).toStdString().c_str());
4479 QDir dir;
4480 fLastOpenPath = dir.absoluteFilePath(nomFich);
4481 }
4482}
4483
4484
4485void G4UIQt::SaveIconCallback(const QString& aParam) {
4486
4487 QString aCommand = aParam.left(aParam.indexOf(fStringSeparator));
4488 QString aLabel = aParam.mid(aParam.indexOf(fStringSeparator)+fStringSeparator.length());
4489
4490 QString nomFich = QFileDialog::getSaveFileName(fMainWindow, aLabel, fLastOpenPath, "Macro files (*.mac)");
4491 if (nomFich != "") {
4492 G4UImanager::GetUIpointer()->ApplyCommand((QString(aCommand)+ QString(" ")+nomFich).toStdString().c_str());
4493 QDir dir;
4494 fLastOpenPath = dir.absoluteFilePath(nomFich);
4495 }
4496}
4497
4498
4499void G4UIQt::CreateViewerPropertiesDialog() {
4500
4501 if (fViewerPropertiesDialog != NULL) {
4502 return;
4503 }
4504 fViewerPropertiesDialog = new QDialog();
4505
4506 fViewerPropertiesDialog->setWindowTitle("Viewer properties");
4507 fViewerPropertiesDialog->setSizePolicy (QSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding));
4508
4509 if (!fViewerPropertiesWidget) {
4510 fViewerPropertiesWidget = new QWidget();
4511 QVBoxLayout* layoutPropertiesWidget = new QVBoxLayout();
4512 fViewerPropertiesWidget->setLayout(layoutPropertiesWidget);
4513
4514 CreateEmptyViewerPropertiesWidget();
4515 }
4516
4517 QVBoxLayout* layoutDialog = new QVBoxLayout();
4518
4519 layoutDialog->addWidget(fViewerPropertiesWidget);
4520 layoutDialog->setContentsMargins(0,0,0,0);
4521 fViewerPropertiesDialog->setLayout(layoutDialog);
4522}
4523
4524
4525void G4UIQt::CreatePickInfosDialog() {
4526
4527 if (fPickInfosDialog != NULL) {
4528 return;
4529 }
4530 fPickInfosDialog = new QDialog();
4531
4532 fPickInfosDialog->setWindowTitle("Pick infos");
4533 fPickInfosDialog->setSizePolicy (QSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding));
4534
4535 if (!fPickInfosWidget) {
4536 fPickInfosWidget = new QWidget();
4537 QVBoxLayout* layoutPickInfos = new QVBoxLayout();
4538 fPickInfosWidget->setLayout(layoutPickInfos);
4539
4540 CreateEmptyPickInfosWidget();
4541 }
4542
4543 QVBoxLayout* layoutDialog = new QVBoxLayout();
4544
4545 layoutDialog->addWidget(fPickInfosWidget);
4546 layoutDialog->setContentsMargins(0,0,0,0);
4547 fPickInfosDialog->setLayout(layoutDialog);
4548 fPickInfosDialog->setWindowFlags(Qt::WindowStaysOnTopHint);
4549
4550}
4551
4552
4553void G4UIQt::CreateEmptyViewerPropertiesWidget() {
4554 QLayoutItem * wItem;
4555 if (fViewerPropertiesWidget->layout()->count()) {
4556 while ((wItem = fViewerPropertiesWidget->layout()->takeAt(0)) != 0) {
4557 delete wItem->widget();
4558 delete wItem;
4559 }
4560 }
4561 // Add empty one
4562 QLabel* label = new QLabel("No viewer - Please open a viewer first");
4563 fViewerPropertiesWidget->layout()->addWidget(label);
4564 fViewerPropertiesDialog->setWindowTitle("No viewer");
4565}
4566
4567
4568void G4UIQt::CreateEmptyPickInfosWidget() {
4569 QLayoutItem * wItem;
4570 if (fPickInfosWidget->layout()->count()) {
4571 while ((wItem = fPickInfosWidget->layout()->takeAt(0)) != 0) {
4572 delete wItem->widget();
4573 delete wItem;
4574 }
4575 }
4576 // Add empty one
4577 QLabel* label = new QLabel("Click on the object you want to pick");
4578 fPickInfosWidget->layout()->addWidget(label);
4579 fPickInfosDialog->setWindowTitle("Nothing to pick");
4580}
4581
4582
4583void G4UIQt::ViewerPropertiesIconCallback(int) {
4584
4585 CreateViewerPropertiesDialog();
4586
4587 fViewerPropertiesDialog->show();
4588 fViewerPropertiesDialog->raise();
4589 fViewerPropertiesDialog->activateWindow();
4590}
4591
4592
4593void G4UIQt::ChangePerspectiveOrtho(const QString& action) {
4594
4595 // Theses actions should be in the app toolbar
4596
4597 if (fToolbarApp == NULL) return;
4598 QList<QAction *> list = fToolbarApp->actions ();
4599 QString checked = "";
4600 for (int i = 0; i < list.size(); ++i) {
4601 if (list.at(i)->data().toString () == action) {
4602 list.at(i)->setChecked(TRUE);
4603 checked = list.at(i)->data().toString ();
4604 } else if (list.at(i)->data().toString () == "perspective") {
4605 list.at(i)->setChecked(FALSE);
4606 } else if (list.at(i)->data().toString () == "ortho") {
4607 list.at(i)->setChecked(FALSE);
4608 }
4609 }
4610
4611 if ((action == "ortho") && (checked == "ortho")) {
4612 G4UImanager::GetUIpointer()->ApplyCommand("/vis/viewer/set/projection o");
4613 } else if ((action == "perspective") && (checked == "perspective")) {
4614 G4UImanager::GetUIpointer()->ApplyCommand("/vis/viewer/set/projection p");
4615 }
4616}
4617
4618
4619
4620void G4UIQt::SetIconMoveSelected() {
4621 // Theses actions should be in the app toolbar
4622 fMoveSelected = true;
4623 fRotateSelected = false;
4624 fPickSelected = false;
4625 fZoomInSelected = false;
4626 fZoomOutSelected = false;
4627
4628 if (fToolbarApp == NULL) return;
4629 QList<QAction *> list = fToolbarApp->actions ();
4630 for (int i = 0; i < list.size(); ++i) {
4631 if (list.at(i)->data().toString () == "move") {
4632 list.at(i)->setChecked(TRUE);
4633 } else if (list.at(i)->data().toString () == "rotate") {
4634 list.at(i)->setChecked(FALSE);
4635 } else if (list.at(i)->data().toString () == "pick") {
4636 list.at(i)->setChecked(FALSE);
4637 } else if (list.at(i)->data().toString () == "zoom_in") {
4638 list.at(i)->setChecked(FALSE);
4639 } else if (list.at(i)->data().toString () == "zoom_out") {
4640 list.at(i)->setChecked(FALSE);
4641 }
4642 }
4643}
4644
4645
4646void G4UIQt::SetIconRotateSelected() {
4647 // Theses actions should be in the app toolbar
4648 fRotateSelected = true;
4649 fMoveSelected = false;
4650 fPickSelected = false;
4651 fZoomInSelected = false;
4652 fZoomOutSelected = false;
4653
4654 if (fToolbarApp == NULL) return;
4655 QList<QAction *> list = fToolbarApp->actions ();
4656 for (int i = 0; i < list.size(); ++i) {
4657 if (list.at(i)->data().toString () == "rotate") {
4658 list.at(i)->setChecked(TRUE);
4659 } else if (list.at(i)->data().toString () == "move") {
4660 list.at(i)->setChecked(FALSE);
4661 } else if (list.at(i)->data().toString () == "pick") {
4662 list.at(i)->setChecked(FALSE);
4663 } else if (list.at(i)->data().toString () == "zoom_in") {
4664 list.at(i)->setChecked(FALSE);
4665 } else if (list.at(i)->data().toString () == "zoom_out") {
4666 list.at(i)->setChecked(FALSE);
4667 }
4668 }
4669}
4670
4671
4672void G4UIQt::SetIconPickSelected() {
4673 // Theses actions should be in the app toolbar
4674 fPickSelected = true;
4675 fMoveSelected = false;
4676 fRotateSelected = false;
4677 fZoomInSelected = false;
4678 fZoomOutSelected = false;
4679
4680 QToolBar* bar = fToolbarApp;
4681 if (!fDefaultIcons) {
4682 bar = fToolbarUser;
4683 }
4684 if (!bar) return;
4685
4686 QList<QAction *> list = bar->actions ();
4687 for (int i = 0; i < list.size(); ++i) {
4688 if (list.at(i)->data().toString () == "pick") {
4689 list.at(i)->setChecked(TRUE);
4690 } else if (list.at(i)->data().toString () == "move") {
4691 list.at(i)->setChecked(FALSE);
4692 } else if (list.at(i)->data().toString () == "rotate") {
4693 list.at(i)->setChecked(FALSE);
4694 } else if (list.at(i)->data().toString () == "zoom_in") {
4695 list.at(i)->setChecked(FALSE);
4696 } else if (list.at(i)->data().toString () == "zoom_out") {
4697 list.at(i)->setChecked(FALSE);
4698 }
4699 }
4700}
4701
4702
4703void G4UIQt::SetIconZoomInSelected() {
4704 // Theses actions should be in the app toolbar
4705 fZoomInSelected = true;
4706 fMoveSelected = false;
4707 fRotateSelected = false;
4708 fPickSelected = false;
4709 fZoomOutSelected = false;
4710
4711 QToolBar* bar = fToolbarApp;
4712 if (!fDefaultIcons) {
4713 bar = fToolbarUser;
4714 }
4715 if (!bar) return;
4716
4717 QList<QAction *> list = bar->actions ();
4718 for (int i = 0; i < list.size(); ++i) {
4719 if (list.at(i)->data().toString () == "zoom_in") {
4720 list.at(i)->setChecked(TRUE);
4721 } else if (list.at(i)->data().toString () == "move") {
4722 list.at(i)->setChecked(FALSE);
4723 } else if (list.at(i)->data().toString () == "rotate") {
4724 list.at(i)->setChecked(FALSE);
4725 } else if (list.at(i)->data().toString () == "pick") {
4726 list.at(i)->setChecked(FALSE);
4727 } else if (list.at(i)->data().toString () == "zoom_out") {
4728 list.at(i)->setChecked(FALSE);
4729 }
4730 }
4731}
4732
4733
4734void G4UIQt::SetIconZoomOutSelected() {
4735 // Theses actions should be in the app toolbar
4736 fZoomOutSelected = true;
4737 fMoveSelected = false;
4738 fRotateSelected = false;
4739 fPickSelected = false;
4740 fZoomInSelected = false;
4741
4742 QToolBar* bar = fToolbarApp;
4743 if (!fDefaultIcons) {
4744 bar = fToolbarUser;
4745 }
4746 if (!bar) return;
4747
4748 QList<QAction *> list = bar->actions ();
4749 for (int i = 0; i < list.size(); ++i) {
4750 if (list.at(i)->data().toString () == "zoom_out") {
4751 list.at(i)->setChecked(TRUE);
4752 } else if (list.at(i)->data().toString () == "move") {
4753 list.at(i)->setChecked(FALSE);
4754 } else if (list.at(i)->data().toString () == "rotate") {
4755 list.at(i)->setChecked(FALSE);
4756 } else if (list.at(i)->data().toString () == "pick") {
4757 list.at(i)->setChecked(FALSE);
4758 } else if (list.at(i)->data().toString () == "zoom_in") {
4759 list.at(i)->setChecked(FALSE);
4760 }
4761 }
4762}
4763
4764
4765void G4UIQt::SetIconSolidSelected() {
4766 // Theses actions should be in the app toolbar
4767
4768 QToolBar* bar = fToolbarApp;
4769 if (!fDefaultIcons) {
4770 bar = fToolbarUser;
4771 }
4772 if (!bar) return;
4773
4774 QList<QAction *> list = bar->actions ();
4775 for (int i = 0; i < list.size(); ++i) {
4776 if (list.at(i)->data().toString () == "solid") {
4777 list.at(i)->setChecked(TRUE);
4778 } else if (list.at(i)->data().toString () == "hidden_line_removal") {
4779 list.at(i)->setChecked(FALSE);
4780 } else if (list.at(i)->data().toString () == "hidden_line_and_surface_removal") {
4781 list.at(i)->setChecked(FALSE);
4782 } else if (list.at(i)->data().toString () == "wireframe") {
4783 list.at(i)->setChecked(FALSE);
4784 }
4785 }
4786}
4787
4788
4789void G4UIQt::SetIconWireframeSelected() {
4790 // Theses actions should be in the app toolbar
4791
4792 QToolBar* bar = fToolbarApp;
4793 if (!fDefaultIcons) {
4794 bar = fToolbarUser;
4795 }
4796 if (!bar) return;
4797
4798 QList<QAction *> list = bar->actions ();
4799 for (int i = 0; i < list.size(); ++i) {
4800 if (list.at(i)->data().toString () == "wireframe") {
4801 list.at(i)->setChecked(TRUE);
4802 } else if (list.at(i)->data().toString () == "hidden_line_removal") {
4803 list.at(i)->setChecked(FALSE);
4804 } else if (list.at(i)->data().toString () == "hidden_line_and_surface_removal") {
4805 list.at(i)->setChecked(FALSE);
4806 } else if (list.at(i)->data().toString () == "solid") {
4807 list.at(i)->setChecked(FALSE);
4808 }
4809 }
4810}
4811
4812
4813void G4UIQt::SetIconHLRSelected() {
4814 // Theses actions should be in the app toolbar
4815
4816 QToolBar* bar = fToolbarApp;
4817 if (!fDefaultIcons) {
4818 bar = fToolbarUser;
4819 }
4820 if (!bar) return;
4821
4822
4823 QList<QAction *> list = bar->actions ();
4824 for (int i = 0; i < list.size(); ++i) {
4825 if (list.at(i)->data().toString () == "hidden_line_removal") {
4826 list.at(i)->setChecked(TRUE);
4827 } else if (list.at(i)->data().toString () == "solid") {
4828 list.at(i)->setChecked(FALSE);
4829 } else if (list.at(i)->data().toString () == "hidden_line_and_surface_removal") {
4830 list.at(i)->setChecked(FALSE);
4831 } else if (list.at(i)->data().toString () == "wireframe") {
4832 list.at(i)->setChecked(FALSE);
4833 }
4834 }
4835}
4836
4837
4838void G4UIQt::SetIconHLHSRSelected() {
4839 // Theses actions should be in the app toolbar
4840
4841 QToolBar* bar = fToolbarApp;
4842 if (!fDefaultIcons) {
4843 bar = fToolbarUser;
4844 }
4845
4846 if (!bar) return;
4847
4848 QList<QAction *> list = bar->actions ();
4849 for (int i = 0; i < list.size(); ++i) {
4850 if (list.at(i)->data().toString () == "hidden_line_and_surface_removal") {
4851 list.at(i)->setChecked(TRUE);
4852 } else if (list.at(i)->data().toString () == "solid") {
4853 list.at(i)->setChecked(FALSE);
4854 } else if (list.at(i)->data().toString () == "hidden_line_removal") {
4855 list.at(i)->setChecked(FALSE);
4856 } else if (list.at(i)->data().toString () == "wireframe") {
4857 list.at(i)->setChecked(FALSE);
4858 }
4859 }
4860}
4861
4862
4863void G4UIQt::SetIconPerspectiveSelected() {
4864 // Theses actions should be in the app toolbar
4865
4866 QToolBar* bar = fToolbarApp;
4867 if (!fDefaultIcons) {
4868 bar = fToolbarUser;
4869 }
4870 if (!bar) return;
4871
4872
4873 QList<QAction *> list = bar->actions ();
4874 for (int i = 0; i < list.size(); ++i) {
4875 if (list.at(i)->data().toString () == "perspective") {
4876 list.at(i)->setChecked(TRUE);
4877 } else if (list.at(i)->data().toString () == "ortho") {
4878 list.at(i)->setChecked(FALSE);
4879 }
4880 }
4881}
4882
4883
4884
4885void G4UIQt::SetIconOrthoSelected() {
4886 // Theses actions should be in the app toolbar
4887
4888 QToolBar* bar = fToolbarApp;
4889 if (!fDefaultIcons) {
4890 bar = fToolbarUser;
4891 }
4892
4893 if (!bar) return;
4894
4895 QList<QAction *> list = bar->actions ();
4896 for (int i = 0; i < list.size(); ++i) {
4897 if (list.at(i)->data().toString () == "ortho") {
4898 list.at(i)->setChecked(TRUE);
4899 } else if (list.at(i)->data().toString () == "perspective") {
4900 list.at(i)->setChecked(FALSE);
4901 }
4902 }
4903}
4904
4905
4906
4907G4QTabWidget::G4QTabWidget(
4908QWidget* aParent,
4909int sizeX,
4910int sizeY
4911):QTabWidget(aParent)
4912 ,fTabSelected(false)
4913 ,fLastCreated(-1)
4914,fPreferedSizeX(sizeX+6) // margin left+right
4915,fPreferedSizeY(sizeY+58) // tab label height + margin left+right
4916{
4917 setMinimumSize(100,100);
4918 QSizePolicy policy = QSizePolicy(QSizePolicy::Preferred,QSizePolicy::Preferred);
4919 setSizePolicy(policy);
4920}
4921
4922G4QTabWidget::G4QTabWidget(
4923):QTabWidget()
4924 ,fTabSelected(false)
4925 ,fLastCreated(-1)
4926,fPreferedSizeX(0)
4927,fPreferedSizeY(0)
4928{
4929}
4930
4931
4932G4UIOutputString::G4UIOutputString(
4933QString text,
4934G4String origine,
4935G4String outputStream
4936):
4937 fText(text)
4938,fThread(origine)
4939{
4940 if (!GetOutputList().contains(QString(" ")+outputStream+" ")) {
4941 fOutputStream = "info";
4942 } else {
4943 fOutputStream = outputStream;
4944 }
4945}
4946
4947
4948#if QT_VERSION < 0x040500
4949void G4UIQt::TabCloseCallback(int){
4950#else
4951void G4UIQt::TabCloseCallback(int a){
4952#endif
4953#if QT_VERSION < 0x040500
4954#else
4955 if (fViewerTabWidget == NULL) return;
4956
4957 // get the address of the widget
4958 QWidget* temp = fViewerTabWidget->widget(a);
4959 // remove the tab
4960 fViewerTabWidget->removeTab (a);
4961
4962 // if last QWidget : Add empty string
4963 bool lastTab = true;
4964 for (int c=0; c<fViewerTabWidget->count(); c++) {
4965 if (fViewerTabWidget->tabText(c).contains("viewer")) {
4966 lastTab = false;
4967 }
4968 }
4969
4970 if (lastTab) {
4971 CreateEmptyViewerPropertiesWidget();
4972 }
4973 // delete the widget
4974 delete temp;
4975#endif
4976}
4977
4978
4979void G4UIQt::ToolBoxActivated(int a){
4980
4981 if (fUITabWidget->widget(a) == fHelpTBWidget) {
4982 // Rebuild the help tree
4983 FillHelpTree();
4984 } else if (fUITabWidget->widget(a) == fSceneTreeWidget) {
4985#if QT_VERSION < 0x040200
4986 fSceneTreeWidget->show();
4987#else
4988 fSceneTreeWidget->setVisible(true);
4989#endif
4990 }
4991}
4992
4993
4994void G4QTabWidget::paintEvent(
4995QPaintEvent *
4996)
4997{
4998
4999 if (currentWidget()) {
5000
5001 if ( isTabSelected()) {
5002
5003 // QCoreApplication::sendPostedEvents () ;
5004
5005 QString text = tabText (currentIndex());
5006
5007 if (fLastCreated == -1) {
5008 QTextEdit* edit = dynamic_cast<QTextEdit*>(currentWidget());
5009 if (!edit){
5010 QString paramSelect = QString("/vis/viewer/select ")+text;
5012 if(UI != NULL) {
5013 UI->ApplyCommand(paramSelect.toStdString().c_str());
5014 }
5015 }
5016 } else {
5017 fLastCreated = -1;
5018 }
5019 setTabSelected(false);
5020 }
5021 }
5022}
5023
5024
5025G4UIDockWidget::G4UIDockWidget(QString txt):
5026 QDockWidget(txt)
5027{}
5028
5029
5030void G4UIDockWidget::closeEvent(QCloseEvent *aEvent) {
5031 setFloating (false);
5032
5033 //prevent from closing
5034 aEvent->ignore();
5035 // hide them instead
5036 hide();
5037}
5038
5039 #endif
@ G4State_Quit
@ G4State_Abort
#define G4MUTEX_INITIALIZER
Definition: G4Threading.hh:85
std::mutex G4Mutex
Definition: G4Threading.hh:81
bool G4bool
Definition: G4Types.hh:86
int G4int
Definition: G4Types.hh:85
void * G4Interactor
#define G4endl
Definition: G4ios.hh:57
G4GLOB_DLL std::ostream G4cout
#define TRUE
Definition: Globals.hh:27
#define FALSE
Definition: Globals.hh:23
G4String GetFullPrefixString() const
G4String GetPrefixString() const
static G4StateManager * GetStateManager()
@ leading
Definition: G4String.hh:64
G4String & remove(str_size)
G4String & append(const G4String &)
str_size index(const char *, G4int pos=0) const
G4bool isNull() const
std::size_t last(char) const
G4bool contains(const std::string &) const
G4String strip(G4int strip_Type=trailing, char c=' ')
const char * data() const
G4int GetCommandEntry() const
const G4UIcommand * GetGuidance() const
G4UIcommand * GetCommand(G4int i)
const G4String & GetPathName() const
G4int GetTreeEntry() const
G4UIcommandTree * GetTree(G4int i)
G4UIcommandTree * FindCommandTree(const char *commandPath)
const G4String GetTitle() const
G4String GetFirstMatchedString(const G4String &, const G4String &) const
G4UIcommand * FindPath(const char *commandPath) const
std::size_t GetParameterEntries() const
Definition: G4UIcommand.hh:138
const G4String & GetGuidanceLine(G4int i) const
Definition: G4UIcommand.hh:132
G4UIparameter * GetParameter(G4int i) const
Definition: G4UIcommand.hh:139
const G4String & GetCommandPath() const
Definition: G4UIcommand.hh:136
std::size_t GetGuidanceEntries() const
Definition: G4UIcommand.hh:128
const G4String & GetRange() const
Definition: G4UIcommand.hh:127
void SetCoutDestination(G4UIsession *const value)
Definition: G4UImanager.cc:699
G4UIcommandTree * GetTree() const
Definition: G4UImanager.hh:179
G4int ApplyCommand(const char *aCommand)
Definition: G4UImanager.cc:485
G4int GetVerboseLevel() const
Definition: G4UImanager.hh:193
G4String FindMacroPath(const G4String &fname) const
Definition: G4UImanager.cc:793
static G4UImanager * GetUIpointer()
Definition: G4UImanager.cc:77
G4MTcoutDestination * GetThreadCout()
Definition: G4UImanager.hh:242
void SetSession(G4UIsession *const value)
Definition: G4UImanager.hh:183
void SetG4UIWindow(G4UIsession *const value)
Definition: G4UImanager.hh:184
const G4String & GetParameterCandidates() const
const G4String & GetParameterGuidance() const
G4bool IsOmittable() const
const G4String & GetParameterRange() const
G4bool GetCurrentAsDefault() const
char GetParameterType() const
const G4String & GetParameterName() const
const G4String & GetDefaultValue() const
const char * name(G4int ptype)
G4bool IsMasterThread()
Definition: G4Threading.cc:124