// TODO ! // // ******************************************************************** // * License and Disclaimer * // * * // * The Geant4 software is copyright of the Copyright Holders of * // * the Geant4 Collaboration. It is provided under the terms and * // * conditions of the Geant4 Software License, included in the file * // * LICENSE and available at http://cern.ch/geant4/license . These * // * include a list of copyright holders. * // * * // * Neither the authors of this software system, nor their employing * // * institutes,nor the agencies providing financial support for this * // * work make any representation or warranty, express or implied, * // * regarding this software system or assume any liability for its * // * use. Please see the license in the file LICENSE and URL above * // * for the full disclaimer and the limitation of liability. * // * * // * This code implementation is the result of the scientific and * // * technical work of the GEANT4 collaboration. * // * By using, copying, modifying or distributing the software (or * // * any work based on the software) you agree to acknowledge its * // * use in resulting scientific publications, and indicate your * // * acceptance of all terms of the Geant4 Software license. * // ******************************************************************** // // // $Id: G4UIQt.cc,v 1.14 2007/05/29 11:09:49 $ // GEANT4 tag $Name: geant4-08-01 $ // // L. Garnier //#define DEBUG #ifdef G4UI_BUILD_QT_SESSION #include "G4Types.hh" #include #include "G4UIQt.hh" #include "G4UImanager.hh" #include "G4StateManager.hh" #include "G4UIcommandTree.hh" #include "G4UIcommandStatus.hh" #include "G4UIQtLineEdit.hh" #include "G4Qt.hh" #include #include #include #include #include #include #include #include #include #include #include // Pourquoi Static et non variables de classe ? static G4bool exitSession = true; static G4bool exitPause = true; /***************************************************************************/ /** Build a Qt window with a menubar, output area and promt area +-----------------------+ |exit menu| | | | | +-------------------+ | | | | | | | Output area | | | | | | | +-------------------+ | | | clear | | | +-------------------+ | | | promt history | | | +-------------------+ | | +-------------------+ | | |> promt area | | | +-------------------+ | +-----------------------+ */ G4UIQt::G4UIQt ( int argc, char** argv ) :fHelpDialog(NULL) /***************************************************************************/ /*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/ { G4Qt* interactorManager = G4Qt::getInstance (); G4UImanager* UI = G4UImanager::GetUIpointer(); if(UI!=NULL) UI->SetSession(this); fMainWindow = new QMainWindow(); fMainWindow->setWindowTitle( "G4UI Session" ); fMainWindow->resize(800,600); fMainWindow->move(QPoint(300,100)); QSplitter *splitter = new QSplitter(Qt::Vertical); fTextArea = new QTextEdit(); QPushButton *clearButton = new QPushButton("clear"); connect(clearButton, SIGNAL(clicked()), SLOT(clearButtonCallback())); fCommandHistoryArea = new QTextEdit(); fCommandLabel = new QLabel(); fCommandArea = new G4UIQtLineEdit(this); // must surcharge the keyPressEvent function fCommandArea->activateWindow(); connect(fCommandArea, SIGNAL(returnPressed()), SLOT(commandEnteredCallback())); fCommandArea->setFocusPolicy ( Qt::StrongFocus ); fCommandArea->setFocus(Qt::TabFocusReason); fTextArea->setReadOnly(true); fCommandHistoryArea->setReadOnly(true); // virtual void keyPressEvent(QKeyEvent *e) { // if (e->key == Qt::Key_F9) { // Do something //} //} // Set layouts QVBoxLayout *layoutSplitter = new QVBoxLayout; QWidget* topWidget = new QWidget(); QVBoxLayout *layoutTop = new QVBoxLayout; QWidget* bottomWidget = new QWidget(); QVBoxLayout *layoutBottom = new QVBoxLayout; layoutTop->addWidget(fTextArea); layoutTop->addWidget(clearButton); topWidget->setLayout(layoutTop); layoutBottom->addWidget(fCommandHistoryArea); layoutBottom->addWidget(fCommandLabel); layoutBottom->addWidget(fCommandArea); bottomWidget->setLayout(layoutBottom); layoutSplitter->addWidget(topWidget); layoutSplitter->addWidget(bottomWidget); splitter->setLayout(layoutSplitter); fMainWindow->setCentralWidget(splitter); // Add a quit subMenu QMenu *fileMenu = fMainWindow->menuBar()->addMenu("File"); fileMenu->addAction("Quitter", fMainWindow, SLOT(close())); // Add a Help menu QMenu *helpMenu = fMainWindow->menuBar()->addMenu("Help"); helpMenu->addAction("Show Help", this, SLOT(showHelpCallback())); // Set the splitter size. The fTextArea sould be 2/3 on the fMainWindow QList vals = splitter->sizes(); if(vals.size()==2) { vals[0] = (splitter->orientation()==Qt::Vertical ? splitter->height() : splitter->width())*3/4; vals[1] = (splitter->orientation()==Qt::Vertical ? splitter->height() : splitter->width())*1/4; splitter->setSizes(vals); } if(UI!=NULL) UI->SetCoutDestination(this); // TO KEEP } /***************************************************************************/ G4UIQt::~G4UIQt( ) /***************************************************************************/ /*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/ { G4UImanager* UI = G4UImanager::GetUIpointer(); // TO KEEP if(UI!=NULL) { // TO KEEP UI->SetSession(NULL); // TO KEEP UI->SetCoutDestination(NULL); // TO KEEP } if (fMainWindow!=NULL) delete fMainWindow; } /***************************************************************************/ /* Start the Qt main loop */ G4UIsession* G4UIQt::SessionStart ( ) /***************************************************************************/ /*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/ { G4Qt* interactorManager = G4Qt::getInstance (); fMainWindow->show(); Prompt("session"); exitSession = false; printf("disable secondary loop\n"); interactorManager->DisableSecondaryLoop (); // TO KEEP ((QApplication*)interactorManager->GetMainInteractor())->exec(); // on ne passe pas le dessous ? FIXME ???? // je ne pense pas 13/06 // void* event; // TO KEEP // while((event = interactorManager->GetEvent())!=NULL) { // TO KEEP // interactorManager->DispatchEvent(event); // TO KEEP // if(exitSession==true) break; // TO KEEP // } // TO KEEP interactorManager->EnableSecondaryLoop (); printf("enable secondary loop\n"); return this; } /***************************************************************************/ /** Display the prompt in the prompt area */ void G4UIQt::Prompt ( G4String aPrompt ) /***************************************************************************/ /*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/ { fCommandLabel->setText((char*)aPrompt.data()); } /***************************************************************************/ void G4UIQt::SessionTerminate ( ) /***************************************************************************/ /*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/ { G4Qt* interactorManager = G4Qt::getInstance (); fMainWindow->close(); ((QApplication*)interactorManager->GetMainInteractor())->exit(); } /***************************************************************************/ void G4UIQt::PauseSessionStart ( G4String a_state ) /***************************************************************************/ /*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/ { printf("G4UIQt::PauseSessionStart\n"); if(a_state=="G4_pause> ") { // TO KEEP SecondaryLoop ("Pause, type continue to exit this state"); // TO KEEP } // TO KEEP if(a_state=="EndOfEvent") { // TO KEEP // Picking with feed back in event data Done here !!! SecondaryLoop ("End of event, type continue to exit this state"); // TO KEEP } // TO KEEP } /***************************************************************************/ void G4UIQt::SecondaryLoop ( G4String a_prompt ) /***************************************************************************/ /*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/ { printf("G4UIQt::SecondaryLoop\n"); G4Qt* interactorManager = G4Qt::getInstance (); // TO KEEP ? Prompt(a_prompt); // TO KEEP exitPause = false; // TO KEEP void* event; // TO KEEP while((event = interactorManager->GetEvent())!=NULL) { // TO KEEP interactorManager->DispatchEvent(event); // TO KEEP if(exitPause==true) break; // TO KEEP } // TO KEEP Prompt("session"); // TO KEEP } /***************************************************************************/ /** Receive a cout from Geant4. We have to display it in the cout zone */ G4int G4UIQt::ReceiveG4cout ( G4String a_string ) /***************************************************************************/ /*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/ { fTextArea->append(QString((char*)a_string.data()).trimmed()); fTextArea->verticalScrollBar()->setSliderPosition(fTextArea->verticalScrollBar()->maximum()); return 0; } /***************************************************************************/ /** Receive a cerr from Geant4. We have to display it in the cout zone */ G4int G4UIQt::ReceiveG4cerr ( G4String a_string ) /***************************************************************************/ /*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/ { QColor previousColor = fTextArea->textColor(); fTextArea->setTextColor(Qt::red); fTextArea->append(QString((char*)a_string.data()).trimmed()); fTextArea->setTextColor(previousColor); fTextArea->verticalScrollBar()->setSliderPosition(fTextArea->verticalScrollBar()->maximum()); return 0; } /***************************************************************************/ void G4UIQt::AddMenu ( const char* a_name ,const char* a_label ) /***************************************************************************/ /*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/ { printf("G4UIQt::AddMenu %s %s\n",a_name,a_label); // QMenu *fileMenu = fMainWindow->menuBar()->addMenu(a_label); QMenu *fileMenu = new QMenu(a_label); fMainWindow->menuBar()->insertMenu(fMainWindow->menuBar()->actions().last(),fileMenu); AddInteractor (a_name,(G4Interactor)fileMenu); } /***************************************************************************/ void G4UIQt::AddButton ( const char* a_menu ,const char* a_label ,const char* a_command ) /***************************************************************************/ /*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/ { if(a_menu==NULL) return; // TO KEEP if(a_label==NULL) return; // TO KEEP if(a_command==NULL) return; // TO KEEP QMenu *parent = (QMenu*)GetInteractor(a_menu); if(parent==NULL) return; signalMapper = new QSignalMapper(this); QAction *action = parent->addAction(a_label, signalMapper, SLOT(map())); signalMapper->setMapping(action, QString(a_command)); connect(signalMapper, SIGNAL(mapped(const QString &)),this, SLOT(buttonCallback(const QString&))); } /** Open the help dialog in a separate window. This will be display as a tree widget Implementation of void G4VBasicShell::TerminalHelp(G4String newCommand) @param newCommand : open the tree widget item on this command if is set */ void G4UIQt::TerminalHelp(G4String newCommand) { if (!fHelpDialog) { fHelpDialog = new QDialog; QSplitter *splitter = new QSplitter(Qt::Horizontal); fHelpArea = new QTextEdit(); QPushButton *exitButton = new QPushButton("Exit"); connect(exitButton, SIGNAL(clicked()), fHelpDialog,SLOT(close())); fHelpArea->setReadOnly(true); // the help tree G4UImanager* UI = G4UImanager::GetUIpointer(); if(UI==NULL) return; G4UIcommandTree * treeTop = UI->GetTree(); // en test : creation de doc html treeTop->CreateHTML(); printf("************ create file : -%s-**********\n",((char*)treeTop->GetPathName().data())); // // build widget fHelpTreeWidget = new QTreeWidget(); fHelpTreeWidget->setSelectionMode(QAbstractItemView::SingleSelection); fHelpTreeWidget->setColumnCount(2); fHelpTreeWidget->setColumnHidden(1,true); QStringList labels; labels << QString("Command") << QString("Description"); fHelpTreeWidget->setHeaderLabels(labels); QList items; G4int treeSize = treeTop->GetTreeEntry(); QTreeWidgetItem * newItem; for (int a=0;aGetTree(a+1)->GetPathName()).data()).trimmed() ; stringList << QString((char*)(treeTop->GetTree(a+1)->GetTitle()).data()).trimmed() ; newItem = new QTreeWidgetItem(stringList); // look for childs CreateChildTree(newItem,treeTop->GetTree(a+1)); items.append(newItem); } fHelpTreeWidget->insertTopLevelItems(0, items); //connecting callback // QSignalMapper signalMapper = new QSignalMapper(this); connect(fHelpTreeWidget, SIGNAL(itemSelectionChanged ()),this, SLOT(helpTreeCallback())); // Set layouts QHBoxLayout *splitterLayout = new QHBoxLayout; QVBoxLayout *vLayout = new QVBoxLayout; splitterLayout->addWidget(fHelpTreeWidget); splitterLayout->addWidget(fHelpArea); splitter->setLayout(splitterLayout); vLayout->addWidget(splitter); vLayout->addWidget(exitButton); fHelpDialog->setLayout(vLayout); } // Look for the choosen command "newCommand" size_t i = newCommand.index(" "); G4String targetCom=""; if( i != std::string::npos ) { G4String newValue = newCommand(i+1,newCommand.length()-(i+1)); newValue.strip(G4String::both); targetCom = ModifyToFullPathCommand( newValue ); printf("test : av:%s-- ap:%s--\n",((char*)newValue.data()),((char*)targetCom.data())); } if (targetCom != "") { QList list = fHelpTreeWidget->findItems(QString(((char*)targetCom.data())),Qt::MatchFixedString,0); for (int a=0;a<13;a++) { printf("verif.... =%s= +%s+\n",fHelpTreeWidget->topLevelItem(a)->text(0).toStdString().c_str(),((char*)targetCom.data())); } if (!list.isEmpty()) { if (list.first()->childCount() >0) list.first()->setExpanded(true); //collapsed open item QList selected; selected = fHelpTreeWidget->selectedItems(); if ( selected.count() != 0 ) { fHelpTreeWidget->collapseItem (selected.at( 0 ) ); } // clear old selection fHelpTreeWidget->clearSelection(); list.first()->setSelected(true); // Call the update of the right textArea helpTreeCallback(); } } fHelpDialog->setWindowTitle("Help on commands"); fHelpDialog->resize(800,600); fHelpDialog->move(QPoint(400,150)); fHelpDialog->show(); fHelpDialog->raise(); fHelpDialog->activateWindow(); } void G4UIQt::CreateChildTree(QTreeWidgetItem *a_parent,G4UIcommandTree *a_commandTree) { // Creating new item QTreeWidgetItem * newItem; // Get the Sub directories for (int a=0;aGetTreeEntry();a++) { QStringList stringList; stringList << QString((char*)(a_commandTree->GetTree(a+1)->GetPathName()).data()).trimmed() ; stringList << QString((char*)(a_commandTree->GetTree(a+1)->GetTitle()).data()).trimmed() ; newItem = new QTreeWidgetItem(stringList); CreateChildTree(newItem,a_commandTree->GetTree(a+1)); a_parent->addChild(newItem); } // Get the Commands for (int a=0;aGetCommandEntry();a++) { QStringList stringList; stringList << QString((char*)(a_commandTree->GetCommand(a+1)->GetCommandPath()).data()).trimmed() ; stringList << QString((char*)(a_commandTree->GetCommand(a+1)->GetCommandPath()).data()).trimmed() ; newItem = new QTreeWidgetItem(stringList); a_parent->addChild(newItem); newItem->setExpanded(false); } } /** This fonction return the command list parameters in a QString */ /***************************************************************************/ QString G4UIQt::GetCommandList ( G4UIcommand *a_command ) /***************************************************************************/ /*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/ { QString txt; G4String commandPath = a_command->GetCommandPath(); G4String rangeString = a_command->GetRange(); if((commandPath.length()-1)!='/') { txt += "Command " + QString((char*)(commandPath).data()) + "\n"; } txt += "Guidance :\n"; G4int n_guidanceEntry = a_command->GetGuidanceEntries(); for( G4int i_thGuidance=0; i_thGuidance < n_guidanceEntry; i_thGuidance++ ) { txt += QString((char*)(a_command->GetGuidanceLine(i_thGuidance)).data()) + "\n"; } if( ! rangeString.isNull() ) { txt += " Range of parameters : " + QString((char*)(rangeString).data()) + "\n"; } G4int n_parameterEntry = a_command->GetParameterEntries(); if( n_parameterEntry > 0 ) { G4UIparameter *param; // Re-implementation of G4UIparameter.cc for( G4int i_thParameter=0; i_thParameterGetParameter(i_thParameter); txt += "\nParameter : " + QString((char*)(param->GetParameterName()).data()) + "\n"; if( ! param->GetParameterGuidance().isNull() ) txt += QString((char*)(param->GetParameterGuidance()).data())+ "\n" ; txt += " Parameter type : " + QString(param->GetParameterType())+ "\n"; if(param->IsOmittable()) { txt += " Omittable : True\n"; } else { txt += " Omittable : False\n"; } if( param->GetCurrentAsDefault() ) { txt += " Default value : taken from the current value\n"; } else if( ! param->GetDefaultValue().isNull() ) { txt += " Default value : " + QString((char*)(param->GetDefaultValue()).data())+ "\n"; } if( ! param->GetParameterRange().isNull() ) txt += " Parameter range : " + QString((char*)(param->GetParameterRange()).data())+ "\n"; if( ! param->GetParameterCandidates().isNull() ) txt += " Candidates : " + QString((char*)(param->GetParameterCandidates()).data())+ "\n"; } } return txt; } /***************************************************************************/ void G4UIQt::expandHelpItem ( QTreeWidgetItem *a_parent ,G4UIcommand* a_expandCommand ) /***************************************************************************/ /*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/ { } /***************************************************************************/ G4bool G4UIQt::GetHelpChoice( G4int& aInt ) /***************************************************************************/ /*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/ { printf("G4UIQt::GetHelpChoice SHOULD NEVER GO HERE"); } /***************************************************************************/ void G4UIQt::ExitHelp( ) /***************************************************************************/ /*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/ { printf("G4UIQt::ExitHelp SHOULD NEVER GO HERE"); } /***************************************************************************/ // // SLOTS DEFINITIONS // /***************************************************************************/ /***************************************************************************/ void G4UIQt::showHelpCallback ( ) /***************************************************************************/ /*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/ { TerminalHelp(""); } /***************************************************************************/ void G4UIQt::clearButtonCallback ( ) /***************************************************************************/ /*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/ { fTextArea->clear(); } /** Callback call when "click on a menu entry. Send the associated command to geant4 */ void G4UIQt::commandEnteredCallback ( ) /***************************************************************************/ /*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/ { printf ("debug : callback\n"); G4String command (fCommandArea->text().toStdString().c_str()); if (fCommandArea->text().toStdString().c_str() != "") { fCommandHistoryArea->append(fCommandArea->text()); if (command(0,4) != "help") { ApplyShellCommand (command,exitSession,exitPause); } else { printf ("terminal help\n"); TerminalHelp(command); } if(exitSession==true) SessionTerminate(); } fCommandArea->setText(""); } /** Callback call when "enter" clicked on the command zone. Send the command to geant4 */ void G4UIQt::buttonCallback ( const QString& a_command ) /***************************************************************************/ /*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/ { G4String ss = G4String(a_command.toStdString().c_str()); printf ("debug : execute:\n-%s- %d %d \n",ss.data(),exitSession,exitPause); ApplyShellCommand(ss,exitSession,exitPause); if(exitSession==true) SessionTerminate(); } /** This callback is activated when user selected a item in the help tree */ void G4UIQt::helpTreeCallback ( ) /***************************************************************************/ /*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/ { // G4bool GetHelpChoice(G4int&); QTreeWidgetItem* item = NULL; if (!fHelpTreeWidget) return ; if (!fHelpArea) return; QList list =fHelpTreeWidget->selectedItems(); if (list.isEmpty()) return; item = list.first(); if (!item) return; G4UImanager* UI = G4UImanager::GetUIpointer(); if(UI==NULL) return; G4UIcommandTree * treeTop = UI->GetTree(); G4UIcommand* command = treeTop->FindPath(item->text (1).toStdString().c_str()); if (command) { fHelpArea->setText(GetCommandList(command)); } else { // this is not a command, this is a sub directory // We display the Title fHelpArea->setText(item->text (1).toStdString().c_str()); } } #endif