//---------------------------------------------------------------------------- // $Id: QtRpl/RplBlockPanel.cpp 2017/07/23 16:20:44 philw $ //---------------------------------------------------------------------------- #include "RowOToggles.hpp" #include "RplBlockPanel.hpp" #include "RplFrame.hpp" #include "RplGUI.hpp" #include "RplIcons.hpp" #include "RplPrinter.hpp" // // Qt includes // #include "qt/ui_RplBlockPanelWidgets.h" #include "RplBlockMenus.hpp" #include #include #include // // Riverware non-GUI includes // #include "Selection.hpp" #include "RplObj.hpp" #include "RplBlock.hpp" #include "RplSet.hpp" #include "PolicyGroup.hpp" #include "VisualToken.hpp" #include "PrintStmt.hpp" #include "AssignStmt.hpp" #include "ForStmt.hpp" #include "RplExpression.hpp" #include "SimWS.hpp" #include "System.hpp" #include "DerivedObjStmt.hpp" #include "DocumentInfo.hpp" #include "rwError.hpp" //--- rwAssert #include "RplDebugger.hpp" #include "RplDlgMgr.hpp" #include "rwStr.hpp" #include "SlotGUIUtils.hpp" // Indices for items in the Set Value Flag QComboBox. static const int SET_FLAG_IS_RULE_INDEX(0); static const int SET_FLAG_IS_DMI_INPUT_INDEX(1); //-------------------------------------------------------------------------- //+class // // CLASS: // RplBlockPanel // // DESCRIPTION: // Editor dialogs for RplSet objects. // //-------------------------------------------------------------------------- RplBlockPanel::RplBlockPanel(RplBaseDlg* parent, RplBlock* rplBlock) : QFrame(parent), RplObjPanel(), _dlg(parent), _initialized(false), _rplBlock(rplBlock), _ui(new Ui_RplBlockPanelWidgets()), _mu(new RplBlockMenus(this, false)), // not RplViewer _bodyRplFrame(NULL), _constraintRplFrame(NULL), _undoStack(), _toggles(NULL), _showDescriptionToggleIndex(-1), _showNotesToggleIndex(-1), _showExecConstraintToggleIndex(-1), _showCommentsToggleIndex(-1) { _ui->setupUi(this); // Note: The client should call 'installMenuBar()'. This is not done // automatically because the new RplViewerDlg will want to do this // on its own (when switching to a RplBlock or RplFunction tab). // Note: Because of a sequence problem (the client dialog hasn't yet // recorded the pointer of this new instance), initialization must be // completed by calling the completeInit() method. (See below). } void RplBlockPanel::completeInit() { if (!_initialized) { _initialized = true; rplDlgMgr->addRplDlg(_rplBlock, _dlg); initWidgets(); initConnections(); } } void RplBlockPanel::installMenuBar() { if ( rwAssert (_dlg != NULL) && rwAssert (_mu != NULL) ) { QMenuBar* mbar = _dlg->menuBar(); // [QMainWindow] mbar->clear(); QList menus = _mu->topMenuList(); while (!menus.isEmpty()) mbar->addMenu (menus.takeFirst()); } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- RplBlockPanel::~RplBlockPanel() { // We don't want to be updating our edit actions because the stack changes. _undoStack.blockSignals(true); // We don't want the RplDlgMgr to be updating us or our frames. rplDlgMgr->removeRplFrame(_bodyRplFrame); rplDlgMgr->removeRplFrame(_constraintRplFrame); rplDlgMgr->removeRplDlg(getRplObj(), _dlg); delete _ui; _ui = NULL; delete _mu; _mu = NULL; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- bool RplBlockPanel::updateLoadStatus() { // Update the load-related widgets _dlg->updateLoadWidgets(_ui->_loadStateFrame, _ui->_loadButton); return true; //--- success } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- bool RplBlockPanel::update() { updateLoadStatus(); // Update the text updateDescr(); updateNotes(); _ui->_nameEdit->setText(_rplBlock->getName()); QString dlgTypeStr = RplDlgMgr::getObjTypeString(_rplBlock); setWindowTitle (dlgTypeStr + " Editor - \"" + _rplBlock->getParent()->getParent()->getName() + QString(" : ") + _rplBlock->getParent()->getName() + QString(" : ") + QString(_rplBlock->getName()) + "\""); // Initialize Icon Button: Show External Document _dlg->initExternalDocButton (_ui->_externalDocPushButton); _dlg->updateExternalDocOps (_ui->_externalDocPushButton, _mu->_extDocMenu, _mu->_viewExtDocAction, _mu->_editExtDocAction); const RplSet* rplSet (_rplBlock->getSet()); if (rplSet) { // Set RplSet Type Icon Pushbutton const QPixmap setIcon (RplIcons::getObjIcon (rplSet)); const QSize setIconSize (setIcon.size()); _ui->_rplSetTypeIconButton->setText (QString::null); _ui->_rplSetTypeIconButton->setIcon (setIcon); _ui->_rplSetTypeIconButton->setIconSize (setIconSize); _ui->_rplSetTypeIconButton->setFixedSize (setIconSize + QSize (4,4)); _ui->_rplSetTypeIconButton->setAutoDefault (false); _ui->_rplSetTypeIconButton->setDefault (false); _ui->_rplSetTypeIconButton->setToolTip (rplSet->getName()); } _ui->_rplSetTypeIconButton->setVisible (rplSet != NULL); const RplUtilityGroup* rplGrp (_rplBlock->getParent()); if (rplGrp) { // Set RplUtilityGroup Type Icon Pushbutton const QPixmap grpIcon (RplIcons::getObjIcon (rplGrp)); const QSize grpIconSize (grpIcon.size()); _ui->_rplGroupTypeIconButton->setText (QString::null); _ui->_rplGroupTypeIconButton->setIcon (grpIcon); _ui->_rplGroupTypeIconButton->setIconSize (grpIconSize); _ui->_rplGroupTypeIconButton->setFixedSize (grpIconSize + QSize (4,4)); _ui->_rplGroupTypeIconButton->setAutoDefault (false); _ui->_rplGroupTypeIconButton->setDefault (false); _ui->_rplGroupTypeIconButton->setToolTip (rplGrp->getName()); } _ui->_rplGroupTypeIconButton->setVisible ( SHOW_RPL_GROUP_TYPE_ICON_BUTTON && (rplGrp != NULL)); // Set RplObj Type Icon Label _ui->_rplObjTypeIconLabel->setText (QString::null); _ui->_rplObjTypeIconLabel->setPixmap ( RplIcons::getObjIcon(_rplBlock, rplSet)); return true; //--- success } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- bool RplBlockPanel::updateDescr() { const QString objText = _rplBlock->getDescription(); const QString widText = _ui->_descrEdit->toPlainText(); if (!_dlg->_inDescrEdit && (objText != widText)) { //------------------------------------------------- const bool saveIsSetting = _dlg->_settingDescrEdit; _dlg->_settingDescrEdit = true; //------------------------------------------------- const int saveVertPos = _ui->_descrEdit->verticalScrollBar()->value(); _ui->_descrEdit->setText (objText); _ui->_descrEdit->verticalScrollBar()->setValue (saveVertPos); //------------------------------------------------- _dlg->_settingDescrEdit = saveIsSetting; //------------------------------------------------- } updateDescriptionToggleRelevance(); return true; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- bool RplBlockPanel::updateNotes() { const QString objText = _rplBlock->getNotes(); const QString widText = _ui->_notesEdit->toPlainText(); if (!_dlg->_inNotesEdit && (objText != widText)) { const bool saveIsSetting = _dlg->_settingNotesEdit; _dlg->_settingNotesEdit = true; const int saveVertPos = _ui->_notesEdit->verticalScrollBar()->value(); _ui->_notesEdit->setText(objText); _ui->_notesEdit->verticalScrollBar()->setValue(saveVertPos); _dlg->_settingDescrEdit = saveIsSetting; } updateNotesToggleRelevance(); return true; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- bool RplBlockPanel::rebuild() { update(); return true; //--- success } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void RplBlockPanel::updateEditActions() { static const char (*mname) ("RplBlockPanel::updateEditActions"); // std::cout << mname << std::endl; bool editsOkGlobally(rplDlgMgr->objEditsAllowed()); bool addElseIfPossible(_bodyRplFrame->selSupportsAddIfStmtBranch(false)); bool addElsePossible(_bodyRplFrame->selSupportsAddIfStmtBranch(true)); _ui->_nameEdit -> setReadOnly (!editsOkGlobally); _ui->_descrEdit -> setReadOnly (!editsOkGlobally); _ui->_notesEdit -> setReadOnly (!editsOkGlobally); _ui->_preDmiEdit -> setEnabled (editsOkGlobally); _ui->_postDmiEdit -> setEnabled (editsOkGlobally); _mu->_newSetAction -> setEnabled (editsOkGlobally); _mu->_newGlobFuncSetAction -> setEnabled (editsOkGlobally); _mu->_saveSetAction -> setEnabled (editsOkGlobally); _mu->_saveSetAsAction -> setEnabled (editsOkGlobally); _mu->_addAssignmentAction -> setEnabled (editsOkGlobally); _mu->_addPrintAction -> setEnabled (editsOkGlobally); _mu->_addAssignmentAction -> setEnabled (editsOkGlobally); _mu->_addForEachAction -> setEnabled (editsOkGlobally); _mu->_addWithStmtAction -> setEnabled (editsOkGlobally); _mu->_addIfAction -> setEnabled (editsOkGlobally); _mu->_addIfElseAction -> setEnabled (editsOkGlobally); _mu->_addElseIfBranchAction -> setEnabled (editsOkGlobally && addElseIfPossible); _mu->_addElseBranchAction -> setEnabled (editsOkGlobally && addElsePossible); _mu->_addConstraintAction -> setEnabled (editsOkGlobally); _mu->_addFreezeAction -> setEnabled (editsOkGlobally); _mu->_addRewardTableAction -> setEnabled (editsOkGlobally); _mu->_addStopRunAction -> setEnabled (editsOkGlobally); _mu->_addWarningAction -> setEnabled (editsOkGlobally); _mu->_addPreDmiAction -> setEnabled (editsOkGlobally); _mu->_addPostDmiAction -> setEnabled (editsOkGlobally); _mu->_undoAction -> setEnabled (editsOkGlobally && _undoStack.canUndo()); _mu->_redoAction -> setEnabled (editsOkGlobally && _undoStack.canRedo()); // We update our frames before we start asking them questions // (most edit actions apply to the frame with the selection, // which might be neither of our frames). _bodyRplFrame->updateEditActions(); _constraintRplFrame->updateEditActions(); _mu->_cutAction ->setEnabled(editsOkGlobally && (_bodyRplFrame ->deleteEnabled() || _constraintRplFrame->deleteEnabled())); _mu->_copyAction ->setEnabled(editsOkGlobally && (_bodyRplFrame ->copyEnabled() || _constraintRplFrame->copyEnabled())); _mu->_pasteAction ->setEnabled(editsOkGlobally && (_bodyRplFrame ->pasteEnabled() || _constraintRplFrame->pasteEnabled())); _mu->_deleteAction->setEnabled(editsOkGlobally && (_bodyRplFrame ->deleteEnabled() || _constraintRplFrame->deleteEnabled())); _mu->_enableAction->setEnabled(editsOkGlobally && (_bodyRplFrame ->enableEnabled() || _constraintRplFrame->enableEnabled())); _mu->_insertAction->setEnabled(editsOkGlobally && (_bodyRplFrame ->insertEnabled() || _constraintRplFrame->insertEnabled())); _mu->_appendAction->setEnabled(editsOkGlobally && (_bodyRplFrame ->appendEnabled() || _constraintRplFrame->appendEnabled())); // I figure we might as well always provide access to the palette, // even if they might not currently be able to edit with it. _mu->_paletteAction->setEnabled(true); _ui->_loadButton->setEnabled(!rplDebugger->isExecutionPaused()); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void RplBlockPanel::rplSetTypeIconButton_clicked() { static const char (*mname) ("RplBlockPanel::rplSetTypeIconButton_clicked"); // std::cout << mname << std::endl; RplSet* rplSet (_rplBlock->getSet()); if (rplSet) { // NOTE: Using the BaseRWDlg parenting on these dialog doesn't work, // because we don't want the deletion behavior. rplDlgMgr->openRplDlgSelectRplObjViewRow (rplSet, _rplBlock, NULL); } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void RplBlockPanel::rplGroupTypeIconButton_clicked() { static const char (*mname) ("RplBlockPanel::rplGroupTypeIconButton_clicked"); // std::cout << mname << std::endl; RplUtilityGroup* rplGrp (_rplBlock->getParent()); if (rplGrp) { // NOTE: Using the BaseRWDlg parenting on these dialog doesn't work, // because we don't want the deletion behavior. rplDlgMgr->openRplDlgSelectRplObjViewRow (rplGrp, _rplBlock, NULL); } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void RplBlockPanel::preDmiHandler() { if (_rplBlock->hasPreExecDmiObj()) _rplBlock->setPreExecDmiObjName(_ui->_preDmiEdit->text()); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void RplBlockPanel::postDmiHandler() { if (_rplBlock->hasPostExecDmiObj()) _rplBlock->setPostExecDmiObjName(_ui->_postDmiEdit->text()); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void RplBlockPanel::togglePreDmiObj() { _rplBlock->setHasPreExecDmiObj(!_rplBlock->hasPreExecDmiObj()); updateDmiDisplay(); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void RplBlockPanel::togglePostDmiObj() { _rplBlock->setHasPostExecDmiObj(!_rplBlock->hasPostExecDmiObj()); updateDmiDisplay(); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- // // Set a breakpoint before the currently selected statement. // Breakpoints are associated with statements. If this dialog contains the // selection and it is a statement or is within a statement, use that // statement as the breakpoint location, otherwise go with the first // statement. If there are no statements, do nothing. // void RplBlockPanel::setBreakBeforeExec(bool doBreak) { if (_rplBlock->statementCount() == 0) { return; } // If the selection is or is contained within one of our statements, // then set the breakpoint for that statement, otherwise go with // the first statement. const RplStmtList* statements(_rplBlock->getStatements()); const RplStatement* statement(statements->get(0)); if (RplFrame::selection()->getFrame() == _bodyRplFrame) { VisualToken* selectedItem(RplFrame::selection()->getSelectedItem()); const RplObj* obj(selectedItem->getRplObj()); if (obj->isA(Rpl::RPL_STATEMENT)) { statement = static_cast(obj); } } RplDebugger::Location where(statement, NULL, RplDebugger::BEFORE_EXEC); RplDebugger::Breakpoint breakpoint(where, true); if (doBreak) { rplDebugger->addBreakpoint(breakpoint); } else { rplDebugger->removeBreakpoint(breakpoint); } _bodyRplFrame->reformat(); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void RplBlockPanel::setBreakAfterExec(bool doBreak) { if (_rplBlock->statementCount() == 0) { return; } // Always added to last statement. const RplStmtList* statements(_rplBlock->getStatements()); RplDebugger::Location where(statements->get(_rplBlock->statementCount()-1), NULL, RplDebugger::AFTER_EXEC); RplDebugger::Breakpoint breakpoint(where, true); if (doBreak) { rplDebugger->addBreakpoint(breakpoint); } else { rplDebugger->removeBreakpoint(breakpoint); } _bodyRplFrame->reformat(); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void RplBlockPanel::showOptionalFrames() { _ui->_descrGroupBox->setVisible( _mu->_showDescriptionAction->isChecked()); _ui->_notesGroupBox->setVisible( _mu->_showNotesAction->isChecked()); _ui->_execConstraintGroupBox->setVisible( _mu->_showConstraintAction->isChecked()); if (_mu->_showConstraintAction->isChecked()) _constraintRplFrame->reformat(); _toggles->setToggleOn(_showDescriptionToggleIndex, _mu->_showDescriptionAction->isChecked()); _toggles->setToggleOn(_showNotesToggleIndex, _mu->_showNotesAction->isChecked()); _toggles->setToggleOn(_showExecConstraintToggleIndex, _mu->_showConstraintAction->isChecked()); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void RplBlockPanel::initConnections() { connect(_ui->_rplSetTypeIconButton, SIGNAL (clicked()), SLOT (rplSetTypeIconButton_clicked())); connect(_ui->_rplGroupTypeIconButton, SIGNAL (clicked()), SLOT (rplGroupTypeIconButton_clicked())); // Now redundant with the 'config' methods in RplBaseDlg. // //-- connect(_mu->_newSetAction, SIGNAL(triggered()), //-- SLOT(newRplSetHandler())); //-- connect(_mu->_openSetAction, SIGNAL(triggered()), //-- SLOT(openRplSetHandler())); //-- connect(_mu->_saveSetAction, SIGNAL(triggered()), //-- SLOT(saveRplSetHandler())); //-- connect(_mu->_saveSetAsAction, SIGNAL(triggered()), //-- SLOT(saveRplSetAsHandler())); connect (_mu->_newGlobFuncSetAction, SIGNAL(triggered()), _dlg, SLOT (newGlobFuncSetHandler())); connect (_mu->_openGlobFuncSetAction, SIGNAL(triggered()), _dlg, SLOT (openGlobFuncSetHandler())); connect(_mu->_printRplSetAction, SIGNAL(triggered()), _dlg, SLOT(printHandler())); connect(_mu->_closeAction, SIGNAL(triggered()), _dlg, SLOT(close())); connect(_mu->_refreshAction, SIGNAL(triggered()), _dlg, SLOT(refreshHandler())); connect(_mu->_showDescriptionAction, SIGNAL(triggered(bool)), SLOT(showOptionalFrames())); connect(_mu->_showNotesAction, SIGNAL(triggered(bool)), SLOT(showOptionalFrames())); connect(_mu->_showConstraintAction, SIGNAL(triggered(bool)), SLOT(showOptionalFrames())); connect(_mu->_showCommentsAction, SIGNAL(triggered(bool)), _bodyRplFrame, SLOT(setShowComments(bool))); connect(_mu->_showCommentsAction, SIGNAL(triggered(bool)), _constraintRplFrame, SLOT(setShowComments(bool))); connect(_mu->_addIfAction,SIGNAL(triggered()), _bodyRplFrame, SLOT(addIfStmt())); connect(_mu->_addIfElseAction,SIGNAL(triggered()), _bodyRplFrame, SLOT(addIfElseStmt())); connect(_mu->_addElseIfBranchAction,SIGNAL(triggered()), _bodyRplFrame, SLOT(addElseIfBranchToIfStmt())); connect(_mu->_addElseBranchAction,SIGNAL(triggered()), _bodyRplFrame, SLOT(addElseBranchToIfStmt())); connect(_mu->_addForEachAction,SIGNAL(triggered()), _bodyRplFrame, SLOT(addForEachStmt())); connect(_mu->_addWithStmtAction,SIGNAL(triggered()), _bodyRplFrame, SLOT(addWithStmt())); connect(_mu->_addAssignmentAction,SIGNAL(triggered()), _bodyRplFrame, SLOT(addAssignStmt())); connect(_mu->_addPrintAction,SIGNAL(triggered()), _bodyRplFrame, SLOT(addPrintStmt())); connect(_mu->_addExecScriptAction,SIGNAL(triggered()), _bodyRplFrame, SLOT(addExecScriptStmt())); connect(_mu->_addObjectiveMaxAction,SIGNAL(triggered()), _bodyRplFrame, SLOT(addMaxObjectiveStmt())); connect(_mu->_addObjectiveMinAction,SIGNAL(triggered()), _bodyRplFrame, SLOT(addMinObjectiveStmt())); connect(_mu->_addSummationAction,SIGNAL(triggered()), _bodyRplFrame, SLOT(addSummationStmt())); connect(_mu->_addMaximinRepeatAction,SIGNAL(triggered()), _bodyRplFrame, SLOT(addMaximinRepeatStmt())); connect(_mu->_addMaximinSingleAction,SIGNAL(triggered()), _bodyRplFrame, SLOT(addMaximinSingleStmt())); connect(_mu->_addConstraintAction,SIGNAL(triggered()), _bodyRplFrame, SLOT(addConstraintStmt())); connect(_mu->_addFreezeAction,SIGNAL(triggered()), _bodyRplFrame, SLOT(addFreezeStmt())); connect(_mu->_addRewardTableAction,SIGNAL(triggered()), _bodyRplFrame, SLOT(addRewardTableStmt())); connect(_mu->_addStopRunAction,SIGNAL(triggered()), _bodyRplFrame, SLOT(addStopRunStmt())); connect(_mu->_addWarningAction,SIGNAL(triggered()), _bodyRplFrame, SLOT(addWarningStmt())); // Some menus need to be updated before they are shown. connect(_mu->_editMenu, SIGNAL(aboutToShow()), SLOT(aboutToShowEditMenu())); connect(_mu->_viewMenu, SIGNAL(aboutToShow()), SLOT(aboutToShowViewMenu())); connect(_mu->_ruleMenu, SIGNAL(aboutToShow()), SLOT(aboutToShowRuleMenu())); // Connect most edit action signals to both frames. The // frame's slot will do a no-op if the frame does not // contain the current selection. connect(_mu->_cutAction, SIGNAL(triggered()), _bodyRplFrame, SLOT(cut())); connect(_mu->_copyAction, SIGNAL(triggered()), _bodyRplFrame, SLOT(copy())); connect(_mu->_pasteAction, SIGNAL(triggered()), _bodyRplFrame, SLOT(paste())); connect(_mu->_deleteAction, SIGNAL(triggered()), _bodyRplFrame, SLOT(deleteHandler())); connect(_mu->_enableAction, SIGNAL(triggered(bool)), _bodyRplFrame, SLOT(enableHandler(bool))); connect(_mu->_insertAction, SIGNAL(triggered()), _bodyRplFrame, SLOT(insertStmt())); connect(_mu->_appendAction, SIGNAL(triggered()), _bodyRplFrame, SLOT(appendStmt())); connect(_mu->_cutAction, SIGNAL(triggered()), _constraintRplFrame, SLOT(cut())); connect(_mu->_copyAction, SIGNAL(triggered()), _constraintRplFrame, SLOT(copy())); connect(_mu->_pasteAction, SIGNAL(triggered()), _constraintRplFrame, SLOT(paste())); connect(_mu->_deleteAction, SIGNAL(triggered()), _constraintRplFrame, SLOT(deleteHandler())); connect(_mu->_enableAction, SIGNAL(triggered(bool)), _constraintRplFrame, SLOT(enableHandler(bool))); connect(_mu->_insertAction, SIGNAL(triggered()), _constraintRplFrame, SLOT(insertStmt())); connect(_mu->_appendAction, SIGNAL(triggered()), _constraintRplFrame, SLOT(appendStmt())); connect(_mu->_undoAction, SIGNAL(triggered()), &_undoStack, SLOT(undo())); connect(_mu->_redoAction, SIGNAL(triggered()), &_undoStack, SLOT(redo())); connect(_mu->_paletteAction, SIGNAL(triggered()), _dlg, SLOT(openPaletteHandler())); connect(_mu->_checkValidityAction, SIGNAL(triggered()), _dlg, SLOT(checkValidityHandler())); connect(_mu->_displaySettingsAction, SIGNAL(triggered()), _dlg, SLOT(openDisplaySettingsDlgHandler())); connect(_mu->_setAnalysisAction, SIGNAL(triggered()), _dlg, SLOT(openAnalysisDlgHandler())); connect(_mu->_compareSetAction, SIGNAL(triggered()), _dlg, SLOT(compareSetHandler())); _mu->_openDebuggerDlgAction->setIcon(RplIcons::bug()); connect(_mu->_openDebuggerDlgAction, SIGNAL(triggered()), _dlg, SLOT(openDebuggerDlgHandler())); connect(_mu->_closeAllEditorsAction, SIGNAL(triggered()), _dlg, SLOT(closeOtherEditors())); connect(_mu->_setEditorAction, SIGNAL(triggered()), _dlg, SLOT(openRplSetDlg())); connect(_mu->_addPreDmiAction, SIGNAL(triggered()), SLOT(togglePreDmiObj())); connect(_mu->_addPostDmiAction, SIGNAL(triggered()), SLOT(togglePostDmiObj())); connect(_ui->_externalDocPushButton, SIGNAL(clicked()), _dlg, SLOT(externalDocButtonHandler())); connect(_ui->_loadButton, SIGNAL(clicked()), _dlg, SLOT(loadButtonHandler())); connect(_ui->_nameEdit, SIGNAL(returnPressed()), _dlg, SLOT(nameHandler())); connect(_ui->_nameEdit, SIGNAL(editingFinished()), _dlg, SLOT(nameHandler())); connect(_ui->_preDmiEdit, SIGNAL(returnPressed()), SLOT(preDmiHandler())); connect(_ui->_preDmiEdit, SIGNAL(editingFinished()), SLOT(preDmiHandler())); connect(_ui->_postDmiEdit, SIGNAL(returnPressed()), SLOT(postDmiHandler())); connect(_ui->_postDmiEdit, SIGNAL(editingFinished()), SLOT(postDmiHandler())); connect(_ui->_descrEdit, SIGNAL(textChanged()), _dlg, SLOT(descriptionHandler())); connect(_ui->_notesEdit, SIGNAL(textChanged()), _dlg, SLOT(notesHandler())); connect(_mu->_searchReplaceAction, SIGNAL(triggered()), _dlg, SLOT(openSearchReplaceDlgHandler())); connect(&_undoStack, SIGNAL(canUndoChanged(bool)), SLOT(updateEditActions())); connect(&_undoStack, SIGNAL(canRedoChanged(bool)), SLOT(updateEditActions())); connect(_mu->_viewExtDocAction, SIGNAL(triggered()), _dlg, SLOT(viewExternalDocHandler())); connect(_mu->_editExtDocAction, SIGNAL(triggered()), _dlg, SLOT(editExternalDocHandler())); connect(_mu->_configExtDocAction, SIGNAL(triggered()), _dlg, SLOT(configureExternalDocHandler())); connect(_mu->_fileTypeAssocAction, SIGNAL(triggered()), _dlg, SLOT(fileTypeAssocHandler())); connect(_mu->_breakBeforeExecAction, SIGNAL(toggled(bool)), SLOT(setBreakBeforeExec(bool))); connect(_mu->_breakAfterExecAction, SIGNAL(toggled(bool)), SLOT(setBreakAfterExec(bool))); connect(_mu->_stopOnNaNAction, SIGNAL(triggered(bool)), SLOT(stopOnNaNHandler(bool))); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void RplBlockPanel::initWidgets() { resize(QSize(485, 300).expandedTo(minimumSizeHint())); // // Initialize the body RplFrame // _bodyRplFrame = new RplFrame(_undoStack, _rplBlock, true, _ui->_bodyPlaceholderWidget); // We want the frame to take up all available space. _bodyRplFrame->setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding)); QVBoxLayout *layout = new QVBoxLayout; layout->addWidget(_bodyRplFrame); layout->setContentsMargins(0, 0, 0, 0); _ui->_bodyPlaceholderWidget->setLayout(layout); // // Initialize the execution constraints frame // _constraintRplFrame = new RplFrame(_undoStack, _rplBlock, false, _ui->_execConstraintGroupBox); _constraintRplFrame->setCanShowDebuggingDecorations(false); layout = new QVBoxLayout; layout->addWidget(_constraintRplFrame); layout->setContentsMargins(9, 5, 9, 5); _ui->_execConstraintGroupBox->setLayout(layout); // Update the optional frame menu items based on whether their // contents are non-trivial. _mu->_showConstraintAction->setChecked( !_rplBlock->execConstraintIsTrivial()); _dlg->configureCloseDlgsButton (_ui->_closeDlgsButton); initForApplication(); initVisibilityToggles(); showOptionalFrames(); updateDmiDisplay(); update(); updateEditActions(); // Conditionally enable External Document menu and actions. const bool supportsDoc = DocumentInfo::supportsExternalDoc (_rplBlock); _mu->_extDocMenu->setEnabled (supportsDoc); // For testing, display the undo command stack. // QUndoView* undoView = new QUndoView(&_undoStack); // undoView->setWindowTitle(tr("Undo/Redo Command List")); // undoView->show(); // undoView->setAttribute(Qt::WA_QuitOnClose, false); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- extern bool rwPermitGoalAssignments; void RplBlockPanel::initForApplication() { const RplApplication::Type appType = _rplBlock->getLocalAppType(); _ui->_loadButton->setVisible ( appType == RplApplication::RBS || appType == RplApplication::OPT ); _dlg->configNewSetAction (appType, _mu->_newSetAction); _dlg->configOpenSetAction (appType, _mu->_openSetAction); _dlg->configSaveSetAction (appType, _mu->_saveSetAction); _dlg->configSaveSetAsAction (appType, _mu->_saveSetAsAction); _dlg->configReopenSetMenu (appType, _mu->_reopenSetMenu); if (appType == RplApplication::GLOBAL) { // The New/Open/Reopen menu items are redundant with the menu items // already customized to the current RplApplication::Type. _mu->_newGlobFuncSetAction -> setVisible (false); _mu->_openGlobFuncSetAction -> setVisible (false); _mu->_reopenGlobFuncSetMenu -> setVisible (false); QAction* mAction (_mu->_reopenGlobFuncSetMenu->menuAction()); if (mAction) mAction -> setVisible (false); } else { _dlg->configReopenGlobFuncSetMenu (_mu->_reopenGlobFuncSetMenu); } // How we refer to blocks varies with application (default is "Rule"). if (_rplBlock->appIsUDAM()) { // Modify the text of the "Rule" menu _mu->_ruleMenu->setTitle (tr ("Method")); _ui->_execConstraintGroupBox->setTitle("Execute Method Only When"); _ui->_descrGroupBox->setTitle("Method Description"); } else if (_rplBlock->appIsOpt()) { // Modify the text of the "Rule" menu _mu->_ruleMenu->setTitle (tr ("Goal")); _ui->_execConstraintGroupBox->setTitle("Execute Goal Only When"); _ui->_descrGroupBox->setTitle("Goal Description"); } // Some actions are only permitted within optimization goal sets. const bool isOpt (_rplBlock->appIsOpt()); _mu->_addConstraintAction->setVisible(isOpt); _mu->_addFreezeAction->setVisible(isOpt); _mu->_addRewardTableAction->setVisible(isOpt); // Hide non-optimization menus and menu-items for non-optimization // applications. if (!isOpt) { _mu->_addObjectiveMenu->menuAction()->setVisible (false); _mu->_softConstraintMenu->menuAction()->setVisible (false); } // Assignment statements are not permitted within an optimization goal set, // unless an unadvertised riverware command line argument was present. _mu->_addAssignmentAction->setVisible(!isOpt || rwPermitGoalAssignments); _dlg->updateFileMenuAppText(_mu->_printRplSetAction, _mu->_closeAction); QString setEditorText = RplDlgMgr::getObjTypeString(_rplBlock->getSet()) + " Editor..."; _mu->_setEditorAction->setText(setEditorText); // For the Initialization Rules application only, the user can // select among a few set value flag options. const bool isInitRule (_rplBlock->appIsInitRules()); _ui->_setValueFlagWidget->setVisible(isInitRule); if (isInitRule) { static const QString flag("%1 (%2)"); QString ruleFlagText( flag.arg(ValueState::flagAsString(ValueState::RULE)) .arg(SlotGUIUtils::getFlagStr(RULE_VALUE_STATE))); QString dmiInputFlagText( flag.arg(ValueState::flagAsString(ValueState::DMI_INPUT)) .arg(SlotGUIUtils::getFlagStr(DMI_INPUT_VALUE_STATE))); // Items are appended, so we should add them in index order // as defined at the top of the file. _ui->_setValueFlagComboBox-> addItem(ruleFlagText, QVariant(int(ValueState::RULE))); _ui->_setValueFlagComboBox-> addItem(dmiInputFlagText, QVariant(int(ValueState::DMI_INPUT))); if (_rplBlock->getSetValueFlag() == ValueState::DMI_INPUT) { _ui->_setValueFlagComboBox-> setCurrentIndex(SET_FLAG_IS_DMI_INPUT_INDEX); } else if (_rplBlock->getSetValueFlag() == ValueState::RULE) { _ui->_setValueFlagComboBox-> setCurrentIndex(SET_FLAG_IS_RULE_INDEX); } else { rwAssert(false); } connect(_ui->_setValueFlagComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(setValueFlagChangedHandler(int))); } // Executing scripts is only allowed in the MRM application if (appType == RplApplication::MRM) { _mu->_addExecScriptAction->setVisible(true); } else { _mu->_addExecScriptAction->setVisible(false); } } void RplBlockPanel::setValueFlagChangedHandler(int index) { switch(index) { case SET_FLAG_IS_RULE_INDEX: _rplBlock->setSetValueFlag(ValueState::RULE); break; case SET_FLAG_IS_DMI_INPUT_INDEX: _rplBlock->setSetValueFlag(ValueState::DMI_INPUT); break; default: rwAssert(false); } } // // Add a horizontal row of visibility toggles (check boxes which // control the display of optionally displayed aspects of this dialog). // void RplBlockPanel::initVisibilityToggles() { _toggles = new RowOToggles(this, tr("Show: ")); _ui->_bodyPlaceholderWidget->layout()->addWidget(_toggles); _showExecConstraintToggleIndex = _toggles->addToggle(tr("Execution Constraint")); _showDescriptionToggleIndex = _toggles->addToggle(tr("Description")); _showNotesToggleIndex = _toggles->addToggle(tr("Notes")); _showCommentsToggleIndex = _toggles->addToggle(tr("Comments")); _toggles->setToggleOn(_showDescriptionToggleIndex, _mu->_showDescriptionAction->isChecked()); _toggles->setToggleOn(_showNotesToggleIndex, _mu->_showNotesAction->isChecked()); _toggles->setToggleOn(_showExecConstraintToggleIndex, _mu->_showConstraintAction->isChecked()); _toggles->setToggleOn(_showCommentsToggleIndex, _bodyRplFrame->showComments()); // Notice when the user clicks a toggle. connect(_toggles, SIGNAL(stateChanged(int, bool)), this, SLOT(visibilityToggleChangedHandler(int, bool))); // The state of most toggles are updated in showOptionalFrames(), // but inline comments are different. connect(_bodyRplFrame, SIGNAL(showCommentsChanged(bool)), this, SLOT(showCommentsChangedHandler(bool))); // Each toggle provides a visual indication of whether there is non-trivial // content in the item whose display is controlled by the toggle. updateDescriptionToggleRelevance(); updateNotesToggleRelevance(); updateExecConstraintToggleRelevance(); updateCommentsToggleRelevance(); // Note: we maintain the appearance of some toggles using signals // directly, but others are updated in signal handler methods. connect(_bodyRplFrame, SIGNAL(editted()), this, SLOT(updateCommentsToggleRelevance())); connect(_constraintRplFrame, SIGNAL(editted()), this, SLOT(updateCommentsToggleRelevance())); connect(_constraintRplFrame, SIGNAL(editted()), this, SLOT(updateExecConstraintToggleRelevance())); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void RplBlockPanel::loadSettings() { } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void RplBlockPanel::saveSettings() const { } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- void RplBlockPanel::updateDmiDisplay() { const bool hasPreDmiObj = _rplBlock->hasPreExecDmiObj(); const bool hasPostDmiObj = _rplBlock->hasPostExecDmiObj(); // Update the text in the action if (hasPreDmiObj) _ui->_preDmiEdit->setText(_rplBlock->preExecDmiObjName()); if (hasPostDmiObj) _ui->_postDmiEdit->setText(_rplBlock->postExecDmiObjName()); // Show/hide the frame _ui->_preDmiWidget->setVisible(hasPreDmiObj); _ui->_postDmiWidget->setVisible(hasPostDmiObj); QString preDmiStr; if (!hasPreDmiObj) preDmiStr = "Add"; else preDmiStr = "Remove"; QString postDmiStr; if (!hasPostDmiObj) postDmiStr = "Add"; else postDmiStr = "Remove"; _mu->_addPreDmiAction->setText(preDmiStr + " Pre-execution DMI Group"); _mu->_addPostDmiAction->setText(postDmiStr + " Post-execution DMI Group"); } //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- // public, virtual from RplBaseDlg void RplBlockPanel::updateExternalDocButton() { _dlg->initExternalDocButton (_ui->_externalDocPushButton); } //---------------------------------------------------------------------------- // Update actions in the edit menu. //---------------------------------------------------------------------------- void RplBlockPanel::aboutToShowEditMenu() { // Which edit actions are available is fairly dynamic, depending for // example on the state of the run and the current selection, so we // update the enabled state of the edit actions every time. updateEditActions(); // Also the toggle state of the enabled action depends on the selection. _mu->_enableAction->setChecked(true); _bodyRplFrame ->updateEnableAction(_mu->_enableAction); _constraintRplFrame->updateEnableAction(_mu->_enableAction); } //---------------------------------------------------------------------------- // Update actions in the view menu. //---------------------------------------------------------------------------- void RplBlockPanel::aboutToShowViewMenu() { _mu->_showCommentsAction->setChecked(_bodyRplFrame->showComments()); _dlg->updateExternalDocOps (_ui->_externalDocPushButton, _mu->_extDocMenu, _mu->_viewExtDocAction, _mu->_editExtDocAction); } //---------------------------------------------------------------------------- // Update actions in the Rule menu. //---------------------------------------------------------------------------- void RplBlockPanel::aboutToShowRuleMenu() { // Breakpoint actions apply to a particular statement; which statement // depends on the action and the RPL selection. If one of our statements // contains the RPL selection, breakpoint actions apply to that statement. // Otherwise (in the absence of a statement selection), "Break Before" // applies to the first statement and "Break After" applies to the last // statement bool debuggingEnabled(rplDebugger->isDebuggingEnabled()); const RplStmtList* stmts(_rplBlock->getStatements()); bool aStmtExists(_rplBlock && (_rplBlock->statementCount() > 0)); bool breakBeforeExists(false); bool breakAfterExists(false); bool breakAfterStmtIsLast(false); if (aStmtExists) { const RplStatement* firstStmt(stmts->get(0)); const RplStatement* lastStmt(stmts->get(_rplBlock->statementCount()-1)); // Does one of our statements contain the RPL selection? const RplStatement* selectionStmt(NULL); VisualToken* selectedItem(RplFrame::selection()->getSelectedItem()); const RplObj* obj(selectedItem ? selectedItem->getRplObj() : NULL); if (obj && obj->isA(Rpl::RPL_STATEMENT) && (RplFrame::selection()->getFrame() == _bodyRplFrame)) { selectionStmt = static_cast(obj); } // To which statement does each action apply? const RplStatement* breakBeforeStmt; const RplStatement* breakAfterStmt; if (selectionStmt) { breakBeforeStmt = selectionStmt; breakAfterStmt = selectionStmt; } else { breakBeforeStmt = firstStmt; breakAfterStmt = lastStmt; } breakAfterStmtIsLast = (breakAfterStmt == lastStmt); // Are there already breakpoints at these statements? RplDebugger::Location beforeLocation(breakBeforeStmt, NULL, RplDebugger::BEFORE_EXEC); breakBeforeExists = rplDebugger->hasBreakpoint(beforeLocation); RplDebugger::Location afterLocation(breakAfterStmt, NULL, RplDebugger::AFTER_EXEC); breakAfterExists = rplDebugger->hasBreakpoint(afterLocation); } _mu->_breakBeforeExecAction->setChecked(breakBeforeExists); _mu->_breakAfterExecAction ->setChecked(breakAfterExists); _mu->_breakBeforeExecAction->setEnabled(debuggingEnabled && aStmtExists); _mu->_breakAfterExecAction ->setEnabled(debuggingEnabled && aStmtExists && breakAfterStmtIsLast); _mu->_stopOnNaNAction->setChecked(_rplBlock->stopOnNaN()); } //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- // The GUI's idea of the object's name (as opposed to the object's name). QString RplBlockPanel::nameEditorText() const { return _ui->_nameEdit->text(); } // // If our body frame includes the debug cursor (location at which debugging // is currently paused), scroll that cursor into view. // // Note: it's not possible to pause in our execution constraint frame. // void RplBlockPanel::scrollToDebugCursor() { if (_bodyRplFrame) { _bodyRplFrame->scrollToDebugCursor(); } } void RplBlockPanel::stopOnNaNHandler(bool stop) { _rplBlock->setStopOnNaN(stop); } void RplBlockPanel::updateDescriptionToggleRelevance() { bool emptyDescription(_ui->_descrEdit->toPlainText().isEmpty()); _toggles->setToggleRelevant(_showDescriptionToggleIndex, !emptyDescription); if ( !emptyDescription ) { QString desc = _ui->_descrEdit->toPlainText(); _toggles->setToggleToolTip( _showDescriptionToggleIndex, desc ); } else { _toggles->setToggleToolTip( _showDescriptionToggleIndex, QString() ); } } void RplBlockPanel::updateNotesToggleRelevance() { bool emptyNotes(_ui->_notesEdit->toPlainText().isEmpty()); _toggles->setToggleRelevant(_showNotesToggleIndex, !emptyNotes); if (!emptyNotes) { QString notes = _ui->_notesEdit->toPlainText(); _toggles->setToggleToolTip(_showNotesToggleIndex, notes); } else { _toggles->setToggleToolTip(_showNotesToggleIndex, QString()); } } void RplBlockPanel::updateExecConstraintToggleRelevance() { _toggles->setToggleRelevant(_showExecConstraintToggleIndex, !_rplBlock->execConstraintIsTrivial()); } void RplBlockPanel::updateCommentsToggleRelevance() { bool aCommentExists((_bodyRplFrame && _bodyRplFrame->containsAComment()) || (_constraintRplFrame && _constraintRplFrame->containsAComment())); _toggles->setToggleRelevant(_showCommentsToggleIndex, aCommentExists); } void RplBlockPanel::visibilityToggleChangedHandler(int toggleIndex, bool on) { if (toggleIndex == _showDescriptionToggleIndex) { _mu->_showDescriptionAction->setChecked(on); showOptionalFrames(); } else if (toggleIndex == _showExecConstraintToggleIndex) { _mu->_showConstraintAction->setChecked(on); showOptionalFrames(); } else if (toggleIndex == _showNotesToggleIndex) { _mu->_showNotesAction->setChecked(on); showOptionalFrames(); } else if (toggleIndex == _showCommentsToggleIndex) { _bodyRplFrame->setShowComments(on); if (_constraintRplFrame) { _constraintRplFrame->setShowComments(on); } // Note: we don't really need to update the state of the View menu // action because it is updated before the menu is shown, but what // the heck. _mu->_showCommentsAction->setChecked(on); } else { rwDebugAssert(false); } } void RplBlockPanel::showCommentsChangedHandler(bool show) { _toggles->setToggleOn(_showCommentsToggleIndex, show); } // virtual void RplBlockPanel::selectRplStatement(RplStatement* statement) { VisualToken* token(NULL); token = _bodyRplFrame->findRplObjToken(statement); if (!token) { return; } RplFrame::selection()->clear(); RplFrame::selection()->setSelectedItem(token, _bodyRplFrame, true); _bodyRplFrame->updateLayout(); } // virtual override of BaseRWDlg method void RplBlockPanel::showDescription(bool) { if (!_mu->_showDescriptionAction->isChecked()) { _mu->_showDescriptionAction->activate(QAction::Trigger); } } // virtual override of BaseRWDlg method void RplBlockPanel::showNotes(bool) { if (!_mu->_showNotesAction->isChecked()) { _mu->_showNotesAction->activate(QAction::Trigger); } } // virtual override void RplBlockPanel::selectStringInDescription( const Rpl::SearchSpec& searchSpec) { RplGUI::selectSearchSpecInQTextEdit(searchSpec, _ui->_descrEdit); } // virtual override void RplBlockPanel::selectStringInNotes( const Rpl::SearchSpec& searchSpec) { RplGUI::selectSearchSpecInQTextEdit(searchSpec, _ui->_notesEdit); } //--- (end RplBlockPanel.cpp) ---