4#include "moc_DynExpManager.cpp"
5#include "ui_DynExpManager.h"
9 : QMainWindow(parent), DynExpCore(DynExpCore),
10 ui(std::make_unique<
Ui::DynExpManagerClass>()),
11 UpdateUITimer(new QTimer(this)),
13 ModuleWindowsActionGroup(new QActionGroup(this)),
14 UIThemeActionGroup(new QActionGroup(this)), UIBrightThemeAction(nullptr), UIDarkThemeAction(nullptr),
15 LogContextMenu(new QMenu(this)),
16 ItemTreeContextMenu(new QMenu(this)), ClearWarningAction(nullptr),
17 ItemTreeHardwareAdapters(nullptr), ItemTreeInstruments(nullptr), ItemTreeModules(nullptr),
18 StatusBar(this), IsResetting(false), ShouldRedrawCircuitDiagram(true), ShouldUpdateCircuitDiagram(false)
44 ui->tableLog->horizontalHeader()->setDefaultAlignment(Qt::AlignLeft);
45 ui->tableLog->verticalHeader()->setMinimumSectionSize(18);
46 ui->tableLog->verticalHeader()->setDefaultSectionSize(
ui->tableLog->verticalHeader()->minimumSectionSize());
47 ui->tableLog->setColumnWidth(0, 140);
71 ui->treeItems->header()->resizeSection(0, 120);
72 ui->treeItems->header()->resizeSection(1, 180);
73 ui->treeItems->header()->resizeSection(2, 100);
74 ui->splitterInstrListMain->setStretchFactor(0, 16);
75 ui->splitterInstrListMain->setStretchFactor(1, 5);
100 : NumItemsInWarningState(0), NumItemsInErrorState(0),
101 State(new QPushButton(Owner)),
102 NumRunningInstrGroup(new QWidget(Owner)), NumRunningInstrLayout(new QHBoxLayout),
103 NumRunningInstrImage(new QLabel(Owner)), NumRunningInstr(new QLabel(Owner)),
104 NumRunningModuleGroup(new QWidget(Owner)), NumRunningModuleLayout(new QHBoxLayout),
105 NumRunningModuleImage(new QLabel(Owner)), NumRunningModule(new QLabel(Owner))
107 constexpr int Height = 16;
109 State->setFlat(
true);
110 State->setMinimumHeight(24);
111 State->setFocusPolicy(Qt::FocusPolicy::NoFocus);
115 NumRunningInstrImage->setSizePolicy({ QSizePolicy::Policy::Minimum, QSizePolicy::Policy::Minimum });
118 NumRunningInstr->setSizePolicy({ QSizePolicy::Policy::Expanding, QSizePolicy::Policy::Expanding });
122 NumRunningModuleImage->setSizePolicy({ QSizePolicy::Policy::Minimum, QSizePolicy::Policy::Minimum });
125 NumRunningModule->setSizePolicy({ QSizePolicy::Policy::Expanding, QSizePolicy::Policy::Expanding });
139 std::string ObjectName =
"< Unknown >";
149 ObjectName =
"< Error while fetching name >";
161 std::string ErrorMessage =
"";
169 ErrorMessage = e.what();
171 catch (
const std::exception& e)
173 ErrorMessage = e.what();
177 ErrorMessage =
"Unknown Error";
180 if (!ErrorMessage.empty())
182 QMessageBox::warning(
this,
"DynExp - Error",
183 QString::fromStdString(
184 "Starting up the item " +
GetObjectNameSafe(Object) +
", the following error occurred:\n\n"
195 std::string ErrorMessage =
"";
203 ErrorMessage = e.what();
205 catch (
const std::exception& e)
207 ErrorMessage = e.what();
211 ErrorMessage =
"Unknown Error";
214 if (!ErrorMessage.empty())
218 QMessageBox::warning(
this,
"DynExp - Error",
219 QString::fromStdString(
220 "Resetting the item " + ObjectName +
", the following error occurred:\n\n"
229 if (EventLogSize >= std::numeric_limits<int>::max())
232 if (
ui->tableLog->rowCount() <
static_cast<int>(EventLogSize))
235 for (
const auto& LogEntry : Log)
237 const auto Row =
ui->tableLog->rowCount();
239 ui->tableLog->setRowCount(Row + 1);
240 ui->tableLog->setItem(Row, 0,
new QTableWidgetItem(QString::fromStdString(
Util::ToStr(LogEntry.TimePoint))));
242 ui->tableLog->setItem(Row, 2,
new QTableWidgetItem(QString::fromStdString(LogEntry.Message)));
244 for (
int i = 0; i < 3; ++i)
247 ui->tableLog->resizeColumnToContents(2);
248 ui->tableLog->scrollToBottom();
255 for (
auto i =
ui->tableLog->rowCount() - 1; i >= 0; --i)
256 for (
int j = 0; j < 3; ++j)
264 for (
auto ModuleIter = ModuleManager.cbegin(); ModuleIter != ModuleManager.cend(); ++ModuleIter)
268 auto Module = ModuleIter->second.ResourcePointer.get();
271 if (!Module->HasUI())
277 if (!QModule.IsRunning())
279 else if (QModule.IsPaused())
297 catch (
const std::exception& e)
314 setWindowTitle(QString::fromStdString(std::string(
"DynExp Manager - ") + ProjectFilename.string()));
317 setWindowTitle(
"DynExp Manager");
349 if (NumRunningInstr + NumRunningModule > 0)
409 ItemToSelect = LastAdded;
412 ItemToSelect = LastAdded;
416 ui->treeItems->clearSelection();
417 ItemToSelect->setSelected(
true);
431 std::string ObjectName;
432 if (ExceptionPtr || Warning)
455 else if (!IsConnected)
459 "This hardware adapter is not connected yet, and thus it cannot be used now.");
468 constexpr auto Msg =
"This hardware adapter does not respond.";
486 std::string ObjectName;
487 if (ExceptionPtr || Warning)
519 "This instrument is ready to be run.",
"Stopped");
524 constexpr auto Msg =
"This instrument does not respond.";
537 static constexpr auto PausedString =
"This module is paused because one or more linked instruments have been terminated. Restart these instruments in order to continue.";
538 static bool DisplayWarning =
false;
539 static auto DisplayWarningLastSwitchTime = std::chrono::system_clock::now();
541 if (DisplayWarningLastSwitchTime <= std::chrono::system_clock::now() - std::chrono::seconds(2))
543 DisplayWarning = !DisplayWarning;
544 DisplayWarningLastSwitchTime = std::chrono::system_clock::now();
552 std::string ObjectName;
576 ErrorEntries.emplace_back(QString::fromStdString(ObjectName),
577 QString(PausedString) +
"\n\n" + QString::fromStdString(Resource.
ResourcePointer->GetReasonWhyPaused().Description),
581 if ((Warning && !Resource.
ResourcePointer->IsPaused()) || (Warning && DisplayWarning))
601 "This module is ready to be run.",
"Stopped");
606 constexpr auto Msg =
"This module does not respond.";
618 bool FetchingObjectNameFailed =
false;
622 ObjectName = QString::fromStdString(Object->
GetObjectName());
626 ObjectName =
"< Error >";
627 FetchingObjectNameFailed =
true;
630 Item->setText(0, ObjectName);
631 Item->setToolTip(0, ObjectName);
632 Item->setData(0, Qt::ItemDataRole::UserRole, QVariant::fromValue(FetchingObjectNameFailed));
640 for (
int i = 0; i <
ui->treeItems->topLevelItemCount(); ++i)
642 QTreeWidgetItem* ParentItem =
ui->treeItems->topLevelItem(i);
643 for (
int j = 0; j < ParentItem->childCount(); ++j)
645 QTreeWidgetItem* ChildItem = ParentItem->child(j);
646 if (ChildItem->data(1, Qt::ItemDataRole::UserRole).value<
decltype(SelectedEntry)>() == SelectedEntry)
650 ui->treeItems->clearSelection();
651 ui->treeItems->setFocus();
652 ChildItem->setSelected(
true);
661 const QString& Description,
const QString& StateTitle,
const char* IconPath)
663 ItemTreeItem.setData(2, Qt::ItemDataRole::UserRole,
665 ItemTreeItem.setIcon(2, QIcon(IconPath));
666 ItemTreeItem.setText(2, StateTitle);
667 ItemTreeItem.setForeground(2, QApplication::palette().text().color());
668 ItemTreeItem.setToolTip(2, Description);
677 const QString& Description)
679 ItemTreeItem.setData(2, Qt::ItemDataRole::UserRole,
682 ItemTreeItem.setText(2,
"Running");
684 ItemTreeItem.setToolTip(2, Description);
693 const QString& Description)
695 ItemTreeItem.setData(2, Qt::ItemDataRole::UserRole,
698 ItemTreeItem.setText(2,
"Paused");
700 ItemTreeItem.setToolTip(2, Description);
709 const QString& Description)
711 ItemTreeItem.setData(2, Qt::ItemDataRole::UserRole,
714 ItemTreeItem.setText(2,
"Warning");
716 ItemTreeItem.setToolTip(2, Description);
725 const std::exception_ptr& ExceptionPtr)
727 ItemTreeItem.setData(2, Qt::ItemDataRole::UserRole,
730 ItemTreeItem.setText(2,
"Error");
741 const QString& Description)
743 ItemTreeItem.setData(2, Qt::ItemDataRole::UserRole,
746 ItemTreeItem.setText(2,
"Connecting...");
747 ItemTreeItem.setForeground(2, QApplication::palette().text().color());
748 ItemTreeItem.setToolTip(2, Description);
754 const QString& Description)
756 ItemTreeItem.setData(2, Qt::ItemDataRole::UserRole,
759 ItemTreeItem.setText(2,
"Not responding");
761 ItemTreeItem.setToolTip(2, Description);
771 QString HTMLColorQ = QString::fromStdString(HTMLColor);
775 if (HTMLColorQ.toLower() ==
"blue")
777 if (HTMLColorQ.toLower() ==
"green")
781 return QColor(HTMLColorQ);
789 return QColor(
"blue");
793 if (Color == QColor(
"blue"))
822 if (QMessageBox::question(
this,
"DynExp - Close project?",
823 "Really close the current project? All running items will be stopped and unsaved changes will be lost.",
824 QMessageBox::StandardButton::Yes | QMessageBox::StandardButton::No, QMessageBox::StandardButton::No)
825 != QMessageBox::StandardButton::Yes)
828 std::string ErrorMessage =
"";
836 ErrorMessage = e.what();
838 catch (
const std::exception& e)
840 ErrorMessage = e.what();
844 ErrorMessage =
"Unknown Error";
847 if (!ErrorMessage.empty())
849 auto Result = QMessageBox::critical(
this,
"DynExp - Critical error",
850 QString::fromStdString(
851 "Closing a project and stopping all running items, the following error occurred:\n\n"
852 + ErrorMessage +
"\n\n- Click 'Retry' to try again to close the project."
853 +
"\n- Click 'Ignore' to force the project to be closed. This may cause DynExp to be terminated without properly shutting down."
854 +
"\n- Click 'Cancel' to return to the project without closing it."
855 ), QMessageBox::StandardButton::Cancel | QMessageBox::StandardButton::Retry | QMessageBox::StandardButton::Ignore,
856 QMessageBox::StandardButton::Cancel);
860 case QMessageBox::StandardButton::Cancel:
return false;
861 case QMessageBox::StandardButton::Ignore:
return true;
873 std::string ErrorMessage =
"";
881 ErrorMessage = e.what();
883 catch (
const std::exception& e)
885 ErrorMessage = e.what();
889 ErrorMessage =
"Unknown Error";
892 if (!ErrorMessage.empty())
894 auto Result = QMessageBox::critical(
this,
"DynExp - Critical error",
895 QString::fromStdString(
896 "Stopping a worker thread, the following error occurred:\n\n"
897 + ErrorMessage +
"\n\n- Click 'Retry' to try again to stop the thread."
898 +
"\n- Click 'Ignore' to force DynExp to be terminated without properly shutting down."
899 +
"\n- Click 'Cancel' to return to DynExp without closing it."
900 ), QMessageBox::StandardButton::Cancel | QMessageBox::StandardButton::Retry | QMessageBox::StandardButton::Ignore,
901 QMessageBox::StandardButton::Cancel);
905 case QMessageBox::StandardButton::Cancel:
return false;
906 case QMessageBox::StandardButton::Ignore: std::terminate();
916 std::string ErrorMessage =
"";
924 ErrorMessage = e.what();
926 catch (
const std::exception& e)
928 ErrorMessage = e.what();
932 ErrorMessage =
"Unknown Error";
935 if (!ErrorMessage.empty())
937 QMessageBox::warning(
this,
"DynExp - Error",
938 QString::fromStdString(
939 std::string(
"Saving the project to file ").append(Filename)
940 +
", the following error occurred:\n\n" + ErrorMessage
947 ui->action_Run_Item->setEnabled(
false);
948 ui->action_Stop_Item->setEnabled(
false);
949 ui->action_Force_Stop_Item->setEnabled(
false);
950 ui->action_Reset_Item->setEnabled(
false);
951 ui->action_Configure_Item->setEnabled(
false);
952 ui->action_Delete_Item->setEnabled(
false);
962 for (std::remove_const_t<
decltype(NumModules)> i = 0; i < NumModules; ++i)
975 for (
auto ModuleIter = ModuleManager.cbegin(); ModuleIter != ModuleManager.cend(); ++ModuleIter)
979 auto Module = ModuleIter->second.ResourcePointer.get();
982 if (!Module->IsRunning() || !Module->HasUI())
994 catch (
const std::exception& e)
1010 for (
auto ModuleIter = ModuleManager.cbegin(); ModuleIter != ModuleManager.cend(); ++ModuleIter)
1014 auto Module = ModuleIter->second.ResourcePointer.get();
1017 if (!Module->IsRunning() || !Module->HasUI())
1022 if (QModule.IsActiveWindow())
1030 catch (
const std::exception& e)
1071 if (!Module->IsRunning())
1076 auto const Action = &Module->InitUI(*
this,
ui->mdiMain);
1079 ui->menu_Window->addAction(Action);
1095 std::string ErrorMessage =
"";
1096 std::string ObjectName =
"< Unknown >";
1100 Object->Terminate(Force);
1108 if (QMessageBox::warning(
this,
"DynExp - Force-terminate item?",
1109 QString(
"This runnable is currently being used by at least another item. Force-terminate the item?\n\n")
1111 QMessageBox::StandardButton::Yes | QMessageBox::StandardButton::No, QMessageBox::StandardButton::No)
1112 == QMessageBox::StandardButton::Yes)
1120 ErrorMessage = e.what();
1122 catch (
const std::exception& e)
1124 ErrorMessage = e.what();
1128 ErrorMessage =
"Unknown Error";
1131 if (!ErrorMessage.empty())
1133 QMessageBox::warning(
this,
"DynExp - Error",
1134 QString::fromStdString(
1135 "Stopping the item " + ObjectName +
", the following error occurred:\n\n"
1154 QCoreApplication::postEvent(
this, Event->clone());
1160 if (std::uncaught_exceptions())
1184 catch (
const std::exception& e)
1207 qApp->setPalette(QPalette());
1208 qApp->setStyleSheet(
"");
1235 auto Filename =
Util::PromptOpenFilePath(
this,
"Open project",
".dynp",
"DynExp project files (*.dynp)").toStdString();
1236 if (Filename.empty())
1239 std::string ErrorMessage =
"";
1247 ErrorMessage = e.what();
1249 catch (
const std::exception& e)
1251 ErrorMessage = e.what();
1255 ErrorMessage =
"Unknown Error";
1258 if (!ErrorMessage.empty())
1260 QMessageBox::warning(
this,
"DynExp - Error",
1261 QString::fromStdString(
1262 "Opening a project from file " + Filename +
", the following error occurred:\n\n"
1273 Util::EventLog().
Log(
"Error occurred while resetting project. Execution cannot continue.",
1308 auto Filename =
Util::PromptSaveFilePath(
this,
"Save project as",
".dynp",
"DynExp project files (*.dynp)").toStdString();
1309 if (Filename.empty())
1319 std::string ErrorMessage =
"";
1325 auto BusyDlg = std::make_unique<BusyDialog>(
this);
1326 BusyDlg->SetDescriptionText(
"Connecting hardware adapters...");
1330 auto Result = BusyDlg->exec();
1331 ConnectingHardwareAdaptersFuture.wait();
1333 if (Result == QDialog::Accepted)
1335 BusyDlg->SetDescriptionText(
"Starting instruments...");
1339 Result = BusyDlg->exec();
1341 if (Result == QDialog::Accepted)
1343 else if (BusyDlg->GetException())
1344 std::rethrow_exception(BusyDlg->GetException());
1346 else if (BusyDlg->GetException())
1347 std::rethrow_exception(BusyDlg->GetException());
1352 ErrorMessage = e.what();
1354 catch (
const std::exception& e)
1356 ErrorMessage = e.what();
1360 ErrorMessage =
"Unknown Error";
1363 if (!ErrorMessage.empty())
1365 QMessageBox::warning(
this,
"DynExp - Error",
1366 QString::fromStdString(
1367 "Starting up the project, the following error occurred:\n\n"
1377 std::string ErrorMessage =
"";
1385 ErrorMessage = e.what();
1387 catch (
const std::exception& e)
1389 ErrorMessage = e.what();
1393 ErrorMessage =
"Unknown Error";
1396 if (!ErrorMessage.empty())
1398 QMessageBox::warning(
this,
"DynExp - Error",
1399 QString::fromStdString(
1400 "Shutting down the project, the following error occurred:\n\n"
1410 std::string ErrorMessage =
"";
1418 ErrorMessage = e.what();
1420 catch (
const std::exception& e)
1422 ErrorMessage = e.what();
1426 ErrorMessage =
"Unknown Error";
1429 if (!ErrorMessage.empty())
1431 QMessageBox::warning(
this,
"DynExp - Error",
1432 QString::fromStdString(
1433 "Resetting the project's failed items, the following error occurred:\n\n"
1443 std::string ErrorMessage =
"";
1451 ErrorMessage = e.what();
1453 catch (
const std::exception& e)
1455 ErrorMessage = e.what();
1459 ErrorMessage =
"Unknown Error";
1462 if (!ErrorMessage.empty())
1464 QMessageBox::warning(
this,
"DynExp - Error",
1465 QString::fromStdString(
1466 "Restoring the main and module windows' geometries and states from the project file, the following error occurred:\n\n"
1474 std::string ErrorMessage =
"";
1482 ErrorMessage = e.what();
1484 catch (
const std::exception& e)
1486 ErrorMessage = e.what();
1490 ErrorMessage =
"Unknown Error";
1493 if (!ErrorMessage.empty())
1495 QMessageBox::warning(
this,
"DynExp - Error",
1496 QString::fromStdString(
1497 "Editing the project settings, the following error occurred:\n\n"
1505 if (
ui->treeItems->selectedItems().length() != 1)
1508 auto Item =
ui->treeItems->selectedItems()[0];
1511 std::string ErrorMessage =
"";
1512 std::string ObjectName =
"< Unknown >";
1533 ErrorMessage = e.what();
1535 catch (
const std::exception& e)
1537 ErrorMessage = e.what();
1541 ErrorMessage =
"Unknown Error";
1544 if (!ErrorMessage.empty())
1546 QMessageBox::warning(
this,
"DynExp - Error",
1547 QString::fromStdString(
1548 "Starting the item " + ObjectName +
", the following error occurred:\n\n"
1558 if (
ui->treeItems->selectedItems().length() != 1)
1561 auto Item =
ui->treeItems->selectedItems()[0];
1565 std::string ErrorMessage =
"";
1576 ErrorMessage = e.what();
1578 catch (
const std::exception& e)
1580 ErrorMessage = e.what();
1584 ErrorMessage =
"Unknown Error";
1587 if (!ErrorMessage.empty())
1589 QMessageBox::warning(
this,
"DynExp - Error",
1590 QString::fromStdString(
1591 "Determining the object to be stopped, the following error occurred:\n\n"
1606 if (
ui->treeItems->selectedItems().length() != 1)
1609 auto Item =
ui->treeItems->selectedItems()[0];
1613 std::string ErrorMessage =
"";
1626 ErrorMessage = e.what();
1628 catch (
const std::exception& e)
1630 ErrorMessage = e.what();
1634 ErrorMessage =
"Unknown Error";
1637 if (!ErrorMessage.empty())
1641 QMessageBox::warning(
this,
"DynExp - Error",
1642 QString::fromStdString(
1643 "Resetting the item " + ObjectName +
", the following error occurred:\n\n"
1655 if (
ui->treeItems->selectedItems().length() != 1)
1658 auto Item =
ui->treeItems->selectedItems()[0];
1662 bool ResetRequired =
false;
1664 std::string ErrorMessage =
"";
1672 Object = RunnableObject;
1677 Object = RunnableObject;
1693 ErrorMessage = e.what();
1695 catch (
const std::exception& e)
1697 ErrorMessage = e.what();
1701 ErrorMessage =
"Unknown Error";
1706 if (!ErrorMessage.empty())
1707 QMessageBox::warning(
this,
"DynExp - Error",
1708 QString::fromStdString(
1709 "Configuring the item " + ObjectName +
", the following error occurred:\n\n"
1717 if ((Object && !RunnableObject) || (RunnableObject && RunnableObject->
IsRunning()) )
1719 if (QMessageBox::question(
this,
"DynExp - Reset item?",
1720 QString::fromStdString(
"The item " + ObjectName +
" needs to be reset in order to apply the changes. Should it be reset now?"),
1721 QMessageBox::StandardButton::Yes | QMessageBox::StandardButton::No, QMessageBox::StandardButton::No)
1722 == QMessageBox::StandardButton::Yes)
1735 if (
ui->treeItems->selectedItems().length() != 1)
1738 auto Item =
ui->treeItems->selectedItems()[0];
1741 std::string ErrorMessage =
"";
1742 std::string ObjectName =
"< Unknown >";
1770 if (QMessageBox::question(
this,
"DynExp - Stop item?",
1771 QString::fromStdString(
"The item " + ObjectName +
" is currently running. Should it be stopped in order to be deleted?"),
1772 QMessageBox::StandardButton::Yes | QMessageBox::StandardButton::No, QMessageBox::StandardButton::No)
1773 != QMessageBox::StandardButton::Yes)
1793 ErrorMessage = e.what();
1795 catch (
const std::exception& e)
1797 ErrorMessage = e.what();
1801 ErrorMessage =
"Unknown Error";
1806 if (!ErrorMessage.empty())
1808 QMessageBox::warning(
this,
"DynExp - Error",
1809 QString::fromStdString(
1810 "Deleting the item " + ObjectName +
", the following error occurred:\n\n"
1828 ui->action_Dock_Undock_Window->setEnabled(
true);
1836 QModule->DockUndockWindow();
1876 std::string ErrorMessage =
"";
1880 ui->tableLog->setRowCount(0);
1885 ErrorMessage = e.what();
1887 catch (
const std::exception& e)
1889 ErrorMessage = e.what();
1893 ErrorMessage =
"Unknown Error";
1896 if (!ErrorMessage.empty())
1898 QMessageBox::warning(
this,
"DynExp - Error",
1899 QString::fromStdString(
1900 "Clearing the event log, the following error occurred:\n\n"
1908 if (
ui->treeItems->selectedItems().length() != 1)
1911 auto Item =
ui->treeItems->selectedItems()[0];
1927 Object->ClearWarning();
1955 if (
ui->treeItems->selectedItems().length() != 1)
1961 auto Item =
ui->treeItems->selectedItems()[0];
1966 ui->action_Reset_Item->setEnabled(
true);
1967 ui->action_Configure_Item->setEnabled(
true);
1968 ui->action_Delete_Item->setEnabled(
true);
1975 ui->action_Run_Item->setEnabled(
false);
1976 ui->action_Stop_Item->setEnabled(
false);
1977 ui->action_Force_Stop_Item->setEnabled(
false);
1986 bool IsRunning =
false;
1999 ui->action_Run_Item->setEnabled(!IsRunning);
2000 ui->action_Stop_Item->setEnabled(IsRunning);
2001 ui->action_Force_Stop_Item->setEnabled(IsRunning);
2023 ui->treeItems->clearSelection();
Implements DynExp's main UI window called DynExpManager.
Implements DynExp's main window as a Qt-based user interface (UI).
void SelectItemTreeItem(QTreeWidgetItem *SelectedEntry)
Selects the given QTreeWidgetItem instance and brings this DynExpManager window to the front.
DynExpAbout * AboutDialog
Dialog showing license and copyright information.
void ChangeItemTreeItemToRunningState(QTreeWidgetItem &ItemTreeItem, const ItemTreeItemDataType &ItemTreeItemData, const QString &Description)
void OnProjectSettingsClicked()
QColor HTMLColorStringToThemeColor(const std::string &HTMLColor) const
Constructs a QColor instance from an HTML color string depending on the currently active UI theme.
void Reset(bool Force=false)
Resets the currently loaded project removing all resources from the resource managers....
void UpdateCircuitDiagram()
void OnAddHardwareAdapter()
void OnStatusBarStateClicked()
void OnWindowMenuClosed()
void OnItemDoubleClicked(QTreeWidgetItem *Item, int Column)
QMenu * ItemTreeContextMenu
Context menu appearing when right-clicking on the main tree widget showing DynExp::Object instances.
ErrorListDialog * ErrorListDlg
Dialog showing the list of currently active warnings and errors (ErrorEntries)
void MakeItem(QAction *SenderAction, LibraryVectorT &Lib, ManagerT &ResourceManager)
Creates a DynExp::Object instance according to a QAction instance SenderAction, which contains the in...
DynExp::DynExpCore & DynExpCore
Handle to DynExp's internal data.
QTreeWidgetItem * ItemTreeHardwareAdapters
Item for the hardware adapters section within the main tree widget showing DynExp::Object instances.
QColor AdjustColorToThemeColor(const QColor &Color) const
Transforms a QColor instance depending on the currently active UI theme.
void OnResetFailedItems()
void OnItemSelectionChanged()
bool Shutdown() noexcept
Terminates DynExpCore::WorkerThread and waits until the thread has ended.
static std::string GetObjectNameSafe(DynExp::Object *Object)
Retrieves the name of a DynExp::Object instance from its parameter class instance.
void OnWindowMenuOpened()
void OnStopItem(bool Force=false)
void ChangeItemTreeItemToNotRespondingState(QTreeWidgetItem &ItemTreeItem, const ItemTreeItemDataType &ItemTreeItemData, const QString &Description)
void OnDockUndockWindow()
void ResetItem(DynExp::Object *Object)
Calls DynExp::Object::Reset() on a DynExp::Object instance.
void OnRestoreWindowStatesFromParams()
void RegisterItemsFromLibrary(const LibraryVectorT &Lib, QMenu *const MenuBase, const QString IconPath, void(DynExpManager::*Slot)())
Adds the library entries from Lib to submenus below MenuBase and assigns actions to them invoking Slo...
void UpdateModuleWindowsActionShortcuts() noexcept
Establishes shortcuts to switch between module windows. Refer to ModuleWindowsActionGroup.
QTreeWidgetItem * ItemTreeModules
Item for the modules section within the main tree widget showing DynExp::Object instances.
virtual void closeEvent(QCloseEvent *event) override
bool UpdateItemConfig(DynExp::Object *Object, LibraryVectorT &Lib, ManagerT &ResourceManager)
Invokes a configuration dialog to let the user adjust the parameters of a DynExp::Object instance.
void OnLogContextMenuRequested(const QPoint &Position)
void ChangeItemTreeItemToNotConnectedState(QTreeWidgetItem &ItemTreeItem, const ItemTreeItemDataType &ItemTreeItemData, const QString &Description)
void OnModuleWindowActivated(QMdiSubWindow *Window)
void PostKeyPressEvent(QKeyEvent *Event) noexcept
Delegates a Qt key press event (e.g. the key sequences Ctrl+1 - Ctrl+9) from module widgets to the ma...
void FocusMainWindow() noexcept
Focuses/activates DynExp's main window and moves it on top of other windows if possible.
void DisableAllActions() noexcept
Disables all user interface actions such that item-specific ones can be reenabled upon a selection ch...
void OnShowCircuitDiagram()
struct DynExpManager::StatusBarType StatusBar
DynExp::QModuleBase * GetModuleByActiveUIWindow() noexcept
Determines the DynExp::QModuleBase instance of the current project whose UI window is active (has the...
void UpdateItemTreeItemObjectName(QTreeWidgetItem *Item, const DynExp::Object *Object)
Updates the text of a QTreeWidgetItem instance to match it to the related DynExp::Object instance.
QMenu * LogContextMenu
Context menu appearing when right-clicking on the message log widget.
std::unique_ptr< Ui::DynExpManagerClass > ui
Qt widgets belonging to the main window's user interface.
void UpdateModuleWindowsActionIcons() noexcept
Invokes DynExp::QModuleBase::UpdateModuleWindowFocusAction() on each module.
QActionGroup * UIThemeActionGroup
Actions to switch in between different UI themes.
std::unique_ptr< CircuitDiagram > CircuitDiagramDlg
Dialog showing the circuit diagram of the current project. It has no parent to not stay on top of the...
bool IsResetting
Indicates whether DynExpManager is currently deleting all resources to empty the project.
QActionGroup * ModuleWindowsActionGroup
Actions to switch between module windows with CTRL + < number key > shortcuts.
QAction * UIBrightThemeAction
Action for a bright UI theme.
void ChangeItemTreeItemToPausedState(QTreeWidgetItem &ItemTreeItem, const ItemTreeItemDataType &ItemTreeItemData, const QString &Description)
QTreeWidgetItem * ItemTreeInstruments
Item for the instruments section within the main tree widget showing DynExp::Object instances.
void UpdateModulesUI() noexcept
void OnUIThemeChanged(QAction *ThemeAction)
void UpdateItemTreeItem(const DynExp::HardwareAdapterManager::ResourceType &Resource)
void RegisterModuleUI(DynExp::Object *const Object)
Initializes the UI of the module Object (expecting that Object is a DynExp::QModuleBase instance....
void SaveProject(std::string_view Filename) noexcept
Saves the current DynExp project to an XML project file.
QAction * ClearWarningAction
Action to clear the warning of an item within the main tree widget showing DynExp::Object instances.
QTreeWidgetItem * UpdateItemTreeSection(QTreeWidgetItem *Section, ManagerT &ResourceManager)
Loops through resources managed by ResourceManager and adds respective QTreeWidgetItem instances as c...
void ChangeItemTreeItemToErrorState(QTreeWidgetItem &ItemTreeItem, const ItemTreeItemDataType &ItemTreeItemData, const std::exception_ptr &ExceptionPtr)
bool StopItem(DynExp::RunnableObject *Object, bool Force=false) noexcept
Calls DynExp::RunnableObject::Terminate() on a DynExp::RunnableObject instance.
void ChangeItemTreeItemToNormalState(QTreeWidgetItem &ItemTreeItem, const ItemTreeItemDataType &ItemTreeItemData, const QString &Description, const QString &StateTitle, const char *IconPath=DynExpUI::Icons::Stopped)
bool ShouldRedrawCircuitDiagram
Indicates whether the circuit diagram has to be rebuilt. Particularly, this must be set to true direc...
void EnsureItemReadyState(DynExp::Object *Object)
Calls DynExp::Object::EnsureReadyState() on a DynExp::Object instance.
void OnItemTreeContextMenuRequested(const QPoint &Position)
void ChangeItemTreeItemToWarningState(QTreeWidgetItem &ItemTreeItem, const ItemTreeItemDataType &ItemTreeItemData, const QString &Description)
ErrorListDialog::ErrorEntriesType ErrorEntries
List of all currently active warnings and errors.
bool CloseProject() noexcept
Closes the current project and opens a new, empty one.
DynExpManager(DynExp::DynExpCore &DynExpCore, QWidget *parent=Q_NULLPTR)
Constructs a DynExpManager instance.
bool ShouldUpdateCircuitDiagram
Indicates whether any item state has changed. Set to true to update the circuit diagram....
QAction * UIDarkThemeAction
Action for a dark UI theme.
QTimer * UpdateUITimer
Timer for periodically updating the user interface.
DynExp's core class acts as the interface between the user interface and DynExp's internal data like ...
void SaveProject(std::string_view Filename, const QMainWindow &MainWindow, const QDialog &CircuitDiagramDlg, QSplitter &HSplitter, QSplitter &VSplitter)
Saves the current DynExp project to an XML project file.
auto & GetHardwareAdapterLib() const noexcept
Getter for the hardware adapter library.
auto ConnectHardwareAdapters(CommonResourceManagerBase::FunctionToCallWhenObjectStartedType FunctionToCallWhenHardwareAdapterConnecting=nullptr)
Connects all hardware adapters contained in HardwareAdapterMgr asynchronously calling ResourceManager...
void ShutdownProject()
Terminates all running instruments and modules.
bool AllInstrumentsInitialized() const
Checks whether all instruments contained in InstrumentMgr have been initialized successfully.
auto & GetInstrumentLib() const noexcept
Getter for the instrument library.
void OpenProject(std::string_view Filename)
Loads a DynExp project from an XML project file.
auto & GetInstrumentManager() noexcept
Getter for the instrument manager.
bool IsProjectOpened(const std::chrono::milliseconds Timeout=GetParamsTimeoutDefault) const noexcept
Locks Params and determines whether a project has been openend from a project file.
auto & GetModuleManager() noexcept
Getter for the module manager.
void EditProjectSettings(QWidget *const DialogParent)
Opens a settings dialog (ParamsConfigDialog) to let the user configure the parameter values of the cu...
void RestoreWindowStatesFromParams(QMainWindow &MainWindow, QDialog &CircuitDiagramDlg, QSplitter &HSplitter, QSplitter &VSplitter, bool OnlyMainWindow=false)
Sets module and main windows' positions, sizes and styles according to parameters stored in the curre...
void Reset(bool Force=false)
Resets the currently loaded project removing all resources from the resource managers....
bool HasLoadedProjectFromCommandlineParams() noexcept
Indicates whether a DynExp project has been loaded from a path specified as a command line argument w...
auto & GetHardwareAdapterManager() noexcept
Getter for the hardware adapter manager.
auto GetProjectFilename(const std::chrono::milliseconds Timeout=GetParamsTimeoutDefault) const
Locks Params and returns the current DynExp project's filename.
void RunModules(CommonResourceManagerBase::FunctionToCallWhenObjectStartedType FunctionToCallWhenModuleStarted=nullptr)
Runs all modules contained in ModuleMgr with RunnableObjectParams::StartupType::OnCreation startup se...
void RunInstruments(CommonResourceManagerBase::FunctionToCallWhenObjectStartedType FunctionToCallWhenInstrumentStarted=nullptr)
Runs all instruments contained in InstrumentMgr with RunnableObjectParams::StartupType::OnCreation st...
bool AllHardwareAdaptersConnected() const
Checks whether all hardware adapters contained in HardwareAdapterMgr have been connected successfully...
void ResetFailedItems(QWidget &ParentWindow)
Calls Object::Reset() and Object::ClearWarning() on all owned DynExp::Object instances which are in a...
void Shutdown()
Terminates DynExpCore::WorkerThread and waits until the thread has ended.
auto & GetModuleLib() const noexcept
Getter for the module library.
Base class for all DynExp Objects like hardware adapters (DynExp::HardwareAdapterBase),...
void Reset()
Resets this Object instance (including all its derived classes) by calling ResetImpl()....
void EnsureReadyState(bool IsAutomaticStartup)
Ensures that this Object instance is ready by possibly starting its worker thread or by opening conne...
auto GetObjectName(const std::chrono::milliseconds Timeout=GetParamsTimeoutDefault) const
Returns the name of this Object instance.
@ ApplyStoredWindowStates
Base class for modules with a Qt-based user interface. Derive from this class to implement modules wi...
void HideUI()
Removes MdiSubWindow, DockWidget, and ModuleWindowFocusAction setting them to nullptr.
void UpdateModuleWindowFocusAction()
Updates the icon assigned to ModuleWindowFocusAction depending on whether Widget is docked to or undo...
Exception type thrown by TerminateImpl() if the RunnableObject cannot be terminated for being used by...
std::string_view GetUserNames() const
Getter for UserNames.
std::string GetErrorMessage() const
Genereates a user-readable error message containing the content of UserNames.
Defines an Object which possesses a thread it runs in. The RunnableObject can be started and stopped ...
bool Run(QWidget *ParentWidget=nullptr)
Starts the RunnableObject instance's thread and ensures that all Object instances linked to this inst...
bool IsRunning() const noexcept
Returns Running.
void Terminate(bool Force=false, const std::chrono::milliseconds Timeout=TerminateTimeoutDefault)
Notifies the RunnableObject instance's thread to terminate and waits until it has ended....
QTreeWidgetItem * GetSelectedEntry()
void SetErrorEntries(const ErrorEntriesType &ErrorEntries)
void ResetClosedByClickingOpenWidget() noexcept
bool HasBeenClosedByClickingOpenWidget() const noexcept
void Log(const std::string &Message, const ErrorType Type=ErrorType::Info, const size_t Line=0, const std::string &Function="", const std::string &File="", const int ErrorCode=0, const std::stacktrace &Trace={}) noexcept
Logs an event from information specified manually.
auto GetLogSize() const
Determines the number of entries in the internal event log.
void ClearLog()
Clears the internal event log.
std::vector< LogEntry > GetLog(size_t FirstElement=0) const
Returns the internal event log starting from the n-th stored element.
DynExp exceptions are derived from this class. It contains basic information about the cause of the e...
constexpr const char * GetErrorLabelColor() const
const ErrorType Type
DynExp error type from Util::ErrorType
constexpr const char * GetErrorLabel() const
An invalid argument like a null pointer has been passed to a function.
Thrown when an operation timed out before it could be completed, especially used for locking shared d...
const QColor green("lime")
constexpr auto GetStyleSheet()
const QColor blue(42, 130, 218)
constexpr auto Instrument
constexpr auto HardwareAdapter
constexpr auto NotResponding
const auto PushButtonReadyStyleSheetBright
const auto PushButtonRunningStyleSheet
const auto PushButtonErrorStyleSheet
const auto PushButtonReadyStyleSheetDark
const auto PushButtonWarningStyleSheet
std::string ToStr(const T &Value, int Precision=-1)
Converts a (numeric) value of type T to a std::string using operator<< of std::stringstream.
std::string ExceptionToStr(const std::exception_ptr ExceptionPtr)
Returns the what() information of an exception derived from std::exception and stored in an exception...
EventLogger & EventLog()
This function holds a static EventLogger instance and returns a reference to it. DynExp uses only one...
QString PromptOpenFilePath(QWidget *Parent, const QString &Title, const QString &DefaultSuffix, const QString &NameFilter, const QString &InitialDirectory)
Opens a file dialog to ask the user to select a single existing file.
void ActivateWindow(QWidget &Widget)
Renders a window active and brings it to the front.
QString PromptSaveFilePath(QWidget *Parent, const QString &Title, const QString &DefaultSuffix, const QString &NameFilter, const QString &InitialDirectory)
Works as PromptOpenFilePath() but asks the user to select a single file which does not need to exist.
Accumulates include statements to provide a precompiled header.
Bundles data which is assigned to items of the main QTreeWidget. Each item refers to a DynExp::Object...
const DynExp::ItemIDType ID
ID of the DynExp::Object instance assigned to this item.
QLabel * NumRunningModule
QWidget * NumRunningInstrGroup
StatusBarType(DynExpManager *Owner)
Constructs a StatusBarType instance.
QHBoxLayout * NumRunningInstrLayout
QHBoxLayout * NumRunningModuleLayout
QLabel * NumRunningInstrImage
size_t NumItemsInErrorState
QWidget * NumRunningModuleGroup
QLabel * NumRunningModuleImage
size_t NumItemsInWarningState
Defines a DynExp resource, which mainly owns a DynExp::Object instance wrapping a pointer to it.
std::unique_ptr< QTreeWidgetItem > TreeWidgetItem
For visualization of the resource and its state in DynExp's main window (DynExpManager)....
PointerType ResourcePointer
Pointer to the DynExp::Object instance owned by this resource.