20#include <wx/settings.h>
38#include "forms/ProjectPropertiesForm.h"
40#include "forms/StabilityEventList.h"
41#include "forms/LabelManager.h"
48#include "extLibs/artProvider/ArtMetro.h"
56 m_generalProperties = initProperties;
61 EnableCurrentProjectRibbon();
62 Workspace* newWorkspace =
new Workspace(
this, _(
"Open project"), this->GetStatusBar(), this->GetAuiNotebook());
66 if (fileHandling.OpenProject(openPath)) {
67 newWorkspace->SetSavedPath(openPath);
69 m_workspaceList.push_back(newWorkspace);
71 m_ribbonButtonBarContinuous->ToggleButton(ID_RIBBON_DISABLESOL,
true);
72 m_ribbonButtonBarContinuous->ToggleButton(ID_RIBBON_ENABLESOL,
false);
74 m_auiNotebook->AddPage(newWorkspace, newWorkspace->GetName(),
true);
75 m_auiNotebook->Layout();
76 newWorkspace->Redraw();
77 newWorkspace->SetJustOpened(
true);
89 if (m_addElementsMenu) {
90 m_addElementsMenu->Disconnect(wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainFrame::OnAddElementsClick),
92 delete m_addElementsMenu;
94 if (m_stabilityMenu) {
95 m_stabilityMenu->Disconnect(wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainFrame::OnStabilityMenuClick),
97 delete m_stabilityMenu;
100 m_snapshotMenu->Disconnect(wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainFrame::OnSnapshotMenuClick),
102 delete m_snapshotMenu;
105 if (m_locale)
delete m_locale;
106 if (m_generalProperties)
delete m_generalProperties;
109void MainFrame::Init()
111 this->SetSize(800, 600);
113 m_generalProperties->SetGUIColourTheme();
115 CreateDropdownMenus();
117 EnableCurrentProjectRibbon(
false);
119 if (wxSystemSettings::GetAppearance().IsDark())
121 auto* darkArt = m_ribbonBar->GetArtProvider();
122 wxColour stdBlue = wxColour(53, 132, 228);
123 wxColour darkBlue = wxColour(6, 68, 140);
124 wxColour stdGrey = wxColour(59, 59, 59);
125 wxColour darkGrey = wxColour(40, 40, 40);
127 darkArt->SetColor(wxRIBBON_ART_PAGE_BACKGROUND_TOP_COLOUR, stdGrey);
128 darkArt->SetColor(wxRIBBON_ART_PAGE_BACKGROUND_TOP_GRADIENT_COLOUR, stdGrey);
129 darkArt->SetColor(wxRIBBON_ART_PAGE_BACKGROUND_COLOUR, stdGrey);
130 darkArt->SetColor(wxRIBBON_ART_PAGE_BACKGROUND_GRADIENT_COLOUR, stdGrey);
132 darkArt->SetColor(wxRIBBON_ART_PAGE_HOVER_BACKGROUND_TOP_COLOUR, darkGrey);
133 darkArt->SetColor(wxRIBBON_ART_PAGE_HOVER_BACKGROUND_TOP_GRADIENT_COLOUR, darkGrey);
134 darkArt->SetColor(wxRIBBON_ART_PAGE_HOVER_BACKGROUND_COLOUR, darkGrey);
135 darkArt->SetColor(wxRIBBON_ART_PAGE_HOVER_BACKGROUND_GRADIENT_COLOUR, darkGrey);
137 darkArt->SetColor(wxRIBBON_ART_TAB_HOVER_BACKGROUND_TOP_COLOUR, stdBlue);
138 darkArt->SetColor(wxRIBBON_ART_TAB_HOVER_BACKGROUND_TOP_GRADIENT_COLOUR, stdBlue);
139 darkArt->SetColor(wxRIBBON_ART_TAB_HOVER_BACKGROUND_COLOUR, stdBlue);
140 darkArt->SetColor(wxRIBBON_ART_TAB_HOVER_BACKGROUND_GRADIENT_COLOUR, stdBlue);
142 darkArt->SetColor(wxRIBBON_ART_BUTTON_BAR_ACTIVE_BACKGROUND_TOP_COLOUR, stdBlue);
143 darkArt->SetColor(wxRIBBON_ART_BUTTON_BAR_ACTIVE_BACKGROUND_TOP_GRADIENT_COLOUR, stdBlue);
144 darkArt->SetColor(wxRIBBON_ART_BUTTON_BAR_ACTIVE_BACKGROUND_COLOUR, stdBlue);
145 darkArt->SetColor(wxRIBBON_ART_BUTTON_BAR_ACTIVE_BACKGROUND_GRADIENT_COLOUR, stdBlue);
147 darkArt->SetColor(wxRIBBON_ART_BUTTON_BAR_HOVER_BACKGROUND_TOP_COLOUR, darkBlue);
148 darkArt->SetColor(wxRIBBON_ART_BUTTON_BAR_HOVER_BACKGROUND_TOP_GRADIENT_COLOUR, darkBlue);
149 darkArt->SetColor(wxRIBBON_ART_BUTTON_BAR_HOVER_BACKGROUND_COLOUR, darkBlue);
150 darkArt->SetColor(wxRIBBON_ART_BUTTON_BAR_HOVER_BACKGROUND_GRADIENT_COLOUR, darkBlue);
151 m_ribbonBar->Realize();
155 m_artMetro =
new wxRibbonMetroArtProvider();
156 m_ribbonBar->SetArtProvider(m_artMetro);
157 m_ribbonBar->Realize();
163void MainFrame::EnableCurrentProjectRibbon(
bool enable)
165 m_ribbonButtonBarCircuit->EnableButton(ID_RIBBON_ADDELEMENT, enable);
166 m_ribbonButtonBarReports->EnableButton(ID_RIBBON_CHARTS, enable);
167 m_ribbonButtonBarCProject->EnableButton(ID_RIBBON_CLOSE, enable);
168 m_ribbonButtonBarClipboard->EnableButton(ID_RIBBON_COPY, enable);
169 m_ribbonButtonBarReports->EnableButton(ID_RIBBON_DATAREPORT, enable);
170 m_ribbonButtonBarCircuit->EnableButton(ID_RIBBON_DELETE, enable);
171 m_ribbonButtonBarContinuous->EnableButton(ID_RIBBON_DISABLESOL, enable);
172 m_ribbonButtonBarCircuit->EnableButton(ID_RIBBON_DRAG, enable);
173 m_ribbonButtonBarContinuous->EnableButton(ID_RIBBON_ENABLESOL, enable);
174 m_ribbonButtonBarSimulations->EnableButton(ID_RIBBON_FAULT, enable);
175 m_ribbonButtonBarCircuit->EnableButton(ID_RIBBON_FIT, enable);
176 m_ribbonButtonBarCircuit->EnableButton(ID_RIBBON_MOVE, enable);
177 m_ribbonButtonBarClipboard->EnableButton(ID_RIBBON_PASTE, enable);
178 m_ribbonButtonBarSimulations->EnableButton(ID_RIBBON_POWERFLOW, enable);
179 m_ribbonButtonBarClipboard->EnableButton(ID_RIBBON_REDO, enable);
180 m_ribbonButtonBarContinuous->EnableButton(ID_RIBBON_RESETVOLT, enable);
181 m_ribbonButtonBarSimulations->EnableButton(ID_RIBBON_RUNSTAB, enable);
182 m_ribbonButtonBarCProject->EnableButton(ID_RIBBON_SAVE, enable);
183 m_ribbonButtonBarCProject->EnableButton(ID_RIBBON_SAVEAS, enable);
184 m_ribbonButtonBarSimulations->EnableButton(ID_RIBBON_SCPOWER, enable);
185 m_ribbonButtonBarCircuit->EnableButton(ID_RIBBON_PROJSETTINGS, enable);
186 m_ribbonButtonBarReports->EnableButton(ID_RIBBON_HEATMAP, enable);
187 m_ribbonButtonBarReports->EnableButton(ID_RIBBON_SNAPSHOT, enable);
188 m_ribbonButtonBarSimulations->EnableButton(ID_RIBBON_SIMULSETTINGS, enable);
189 m_ribbonButtonBarClipboard->EnableButton(ID_RIBBON_UNDO, enable);
190 m_ribbonButtonBarCircuit->EnableButton(ID_RIBBON_ROTATEC, enable);
191 m_ribbonButtonBarCircuit->EnableButton(ID_RIBBON_ROTATECC, enable);
192 m_ribbonButtonBarCircuit->EnableButton(ID_RIBBON_LABELMNGR, enable);
193 m_ribbonButtonBarSimulations->EnableButton(ID_RIBBON_HARMDIST, enable);
194 m_ribbonButtonBarSimulations->EnableButton(ID_RIBBON_FREQRESP, enable);
202void MainFrame::CreateDropdownMenus()
204 m_addElementsMenu =
new wxMenu();
206 wxMenuItem* busElement =
207 new wxMenuItem(m_addElementsMenu, ID_ADDMENU_BUS, _(
"&Bus\tB"), _(
"Adds a bus at the circuit"));
209 wxMenuItem* lineElement =
210 new wxMenuItem(m_addElementsMenu, ID_ADDMENU_LINE, _(
"&Line\tL"), _(
"Adds a power line at the circuit"));
211 wxMenuItem* transformerElement =
new wxMenuItem(m_addElementsMenu, ID_ADDMENU_TRANSFORMER, _(
"&Transformer\tT"),
212 _(
"Adds a transformer at the circuit"));
213 wxMenuItem* generatorElement =
new wxMenuItem(m_addElementsMenu, ID_ADDMENU_GENERATOR, _(
"&Generator\tG"),
214 _(
"Adds a generator at the circuit"));
215 wxMenuItem* indMotorElement =
new wxMenuItem(m_addElementsMenu, ID_ADDMENU_INDMOTOR, _(
"&Induction motor\tI"),
216 _(
"Adds an induction motor at the circuit"));
217 wxMenuItem* syncCompElement =
218 new wxMenuItem(m_addElementsMenu, ID_ADDMENU_SYNCCOMP, _(
"&Synchronous compensator \tK"),
219 _(
"Adds an induction motor at the circuit"));
220 wxMenuItem* loadElement =
221 new wxMenuItem(m_addElementsMenu, ID_ADDMENU_LOAD, _(
"&Load\tShift-L"), _(
"Adds a load at the circuit"));
222 wxMenuItem* capacitorElement =
new wxMenuItem(m_addElementsMenu, ID_ADDMENU_CAPACITOR, _(
"&Capacitor\tShift-C"),
223 _(
"Adds a shunt capacitor at the circuit"));
224 wxMenuItem* inductorElement =
new wxMenuItem(m_addElementsMenu, ID_ADDMENU_INDUCTOR, _(
"&Inductor\tShift-I"),
225 _(
"Adds a shunt inductor at the circuit"));
226 wxMenuItem* harmCurrentElement =
227 new wxMenuItem(m_addElementsMenu, ID_ADDMENU_HARMCURRENT, _(
"&Harmonic current\tShift-H"),
228 _(
"Adds a harmonic current source at the circuit"));
229 wxMenuItem* emtElement =
230 new wxMenuItem(m_addElementsMenu, ID_ADDMENU_EMTELEMENT, _(
"&Electromagnetic Transient Element\tShift-E"), _(
"Adds an electromagnetic transient element that connects with ATP"));
231 wxMenuItem* textElement =
232 new wxMenuItem(m_addElementsMenu, ID_ADDMENU_TEXT, _(
"&Label\tA"), _(
"Adds a linked element label"));
235 m_addElementsMenu->Append(busElement);
236 m_addElementsMenu->Append(lineElement);
237 m_addElementsMenu->Append(transformerElement);
238 m_addElementsMenu->Append(generatorElement);
239 m_addElementsMenu->Append(indMotorElement);
240 m_addElementsMenu->Append(syncCompElement);
241 m_addElementsMenu->Append(loadElement);
242 m_addElementsMenu->Append(capacitorElement);
243 m_addElementsMenu->Append(inductorElement);
244 m_addElementsMenu->Append(harmCurrentElement);
245 m_addElementsMenu->Append(emtElement);
246 m_addElementsMenu->Append(textElement);
248 m_addElementsMenu->Bind(wxEVT_COMMAND_MENU_SELECTED, &MainFrame::OnAddElementsClick,
this);
250 m_stabilityMenu =
new wxMenu();
252 wxMenuItem* stabilityList =
new wxMenuItem(m_stabilityMenu, ID_STABMENU_LIST, _(
"&Stability event list"),
253 _(
"Show the stability event list"));
254 m_stabilityMenu->Append(stabilityList);
256 m_stabilityMenu->Bind(wxEVT_COMMAND_MENU_SELECTED, &MainFrame::OnStabilityMenuClick,
this);
258 m_snapshotMenu =
new wxMenu();
260 wxMenuItem* snapshotList =
new wxMenuItem(m_stabilityMenu, ID_SNAPSHOTMENU_LIST, _(
"&Export as SVG"),
261 _(
"Export the diagram as SVG file."));
262 m_snapshotMenu->Append(snapshotList);
264 m_snapshotMenu->Bind(wxEVT_COMMAND_MENU_SELECTED, &MainFrame::OnSnapshotMenuClick,
this);
267void MainFrame::OnNewClick(wxRibbonButtonBarEvent& event)
269 EnableCurrentProjectRibbon();
273 newWorkspace =
new Workspace(m_auiNotebook, wxString::Format(_(
"New project %d"), m_projectNumber), this->GetStatusBar(), this->GetAuiNotebook());
275 newWorkspace->GetProperties()->SetGeneralPropertiesData(m_generalProperties->GetGeneralPropertiesData());
276 newWorkspace->SetColourTheme();
278 m_workspaceList.push_back(newWorkspace);
280 m_ribbonButtonBarContinuous->ToggleButton(ID_RIBBON_DISABLESOL,
true);
281 m_ribbonButtonBarContinuous->ToggleButton(ID_RIBBON_ENABLESOL,
false);
283 m_auiNotebook->AddPage(newWorkspace, newWorkspace->GetName(),
true);
284 newWorkspace->Redraw();
285 newWorkspace->SetJustOpened(
true);
289void MainFrame::OnAboutClick(wxRibbonButtonBarEvent& event)
295void MainFrame::OnAddElementDropdown(wxRibbonButtonBarEvent& event) {
event.PopupMenu(m_addElementsMenu); }
296void MainFrame::OnChartsClick(wxRibbonButtonBarEvent& event)
298 if (
Workspace* workspace =
dynamic_cast<Workspace*
>(m_auiNotebook->GetCurrentPage())) {
299 std::vector<ElementPlotData> plotDataList;
300 auto elementList = workspace->GetElementList();
301 for (
auto it = elementList.begin(), itEnd = elementList.end(); it != itEnd; ++it) {
304 if (powerElement->GetPlotData(plotData)) plotDataList.push_back(plotData);
307 ChartView* cView =
new ChartView(workspace, plotDataList, workspace->GetStabilityTimeVector(), m_generalProperties->GetGeneralPropertiesData().plotLib);
312void MainFrame::OnCloseClick(wxRibbonButtonBarEvent& event)
314 auto it = m_workspaceList.begin();
315 while (it != m_workspaceList.end()) {
316 if (*it == m_auiNotebook->GetCurrentPage()) {
318 m_workspaceList.erase(it);
319 m_auiNotebook->DeletePage(m_auiNotebook->GetPageIndex(m_auiNotebook->GetCurrentPage()));
327 if (m_workspaceList.empty()) {
328 EnableCurrentProjectRibbon(
false);
331void MainFrame::OnCopyClick(wxRibbonButtonBarEvent& event)
334 if (workspace) { workspace->CopySelection(); }
337void MainFrame::OnDataReportClick(wxRibbonButtonBarEvent& event)
339 if (
Workspace* workspace =
dynamic_cast<Workspace*
>(m_auiNotebook->GetCurrentPage())) {
344void MainFrame::OnDeleteClick(wxRibbonButtonBarEvent& event)
347 if (workspace) { workspace->DeleteSelectedElements(); }
349void MainFrame::OnDisableSolutionClick(wxRibbonButtonBarEvent& event)
351 if (
Workspace* workspace =
dynamic_cast<Workspace*
>(m_auiNotebook->GetCurrentPage())) {
352 workspace->SetContinuousCalculationActive(
false);
354 m_ribbonButtonBarContinuous->ToggleButton(ID_RIBBON_DISABLESOL,
true);
355 m_ribbonButtonBarContinuous->ToggleButton(ID_RIBBON_ENABLESOL,
false);
358void MainFrame::OnDragClick(wxRibbonButtonBarEvent& event)
362 workspace->SetWorkspaceMode(Workspace::WorkspaceMode::MODE_DRAG);
366void MainFrame::OnEnableSolutionClick(wxRibbonButtonBarEvent& event)
368 if (
Workspace* workspace =
dynamic_cast<Workspace*
>(m_auiNotebook->GetCurrentPage())) {
369 workspace->SetContinuousCalculationActive(
true);
370 workspace->RunStaticStudies();
372 m_ribbonButtonBarContinuous->ToggleButton(ID_RIBBON_ENABLESOL,
true);
373 m_ribbonButtonBarContinuous->ToggleButton(ID_RIBBON_DISABLESOL,
false);
377void MainFrame::OnFaultClick(wxRibbonButtonBarEvent& event)
379 if (
Workspace* workspace =
dynamic_cast<Workspace*
>(m_auiNotebook->GetCurrentPage())) { workspace->RunFault(); }
382void MainFrame::OnFitClick(wxRibbonButtonBarEvent& event)
385 if (workspace) { workspace->Fit(); }
388void MainFrame::OnMoveClick(wxRibbonButtonBarEvent& event)
392 auto elementList = workspace->GetAllElements();
394 wxPoint2DDouble averagePos(0, 0);
395 int numSelElements = 0;
396 for (
auto it = elementList.begin(), itEnd = elementList.end(); it != itEnd; ++it) {
403 averagePos = wxPoint2DDouble(averagePos.m_x /
double(numSelElements), averagePos.m_y /
double(numSelElements));
405 for (
auto it = elementList.begin(), itEnd = elementList.end(); it != itEnd; ++it) {
409 workspace->SetWorkspaceMode(Workspace::WorkspaceMode::MODE_MOVE_ELEMENT);
413void MainFrame::OnOpenClick(wxRibbonButtonBarEvent& event)
415 wxFileDialog openFileDialog(
this, _(
"Open PSP file"),
"",
"",
"PSP files (*.psp)|*.psp",
416 wxFD_OPEN | wxFD_FILE_MUST_EXIST);
417 if (openFileDialog.ShowModal() == wxID_CANCEL)
return;
419 wxFileName fileName(openFileDialog.GetPath());
421 EnableCurrentProjectRibbon();
424 Workspace* newWorkspace =
new Workspace(m_auiNotebook, wxString::Format(_(
"New project %d"), m_projectNumber), this->GetStatusBar(), this->GetAuiNotebook());
427 newWorkspace->GetProperties()->SetGeneralPropertiesData(m_generalProperties->GetGeneralPropertiesData());
428 newWorkspace->SetColourTheme();
431 if (fileHandling.OpenProject(fileName)) {
432 newWorkspace->SetSavedPath(fileName);
434 m_workspaceList.push_back(newWorkspace);
436 m_ribbonButtonBarContinuous->ToggleButton(ID_RIBBON_DISABLESOL,
true);
437 m_ribbonButtonBarContinuous->ToggleButton(ID_RIBBON_ENABLESOL,
false);
439 m_auiNotebook->AddPage(newWorkspace, newWorkspace->GetName(),
true);
440 m_auiNotebook->Layout();
441 newWorkspace->Redraw();
442 newWorkspace->SetJustOpened(
true);
443 newWorkspace->SaveCurrentState();
448 wxMessageDialog msgDialog(
this, _(
"It was not possible to open the selected file."), _(
"Error"),
449 wxOK | wxCENTRE | wxICON_ERROR);
450 msgDialog.ShowModal();
455void MainFrame::OnPSPGuideClick(wxRibbonButtonBarEvent& event)
457 wxLaunchDefaultBrowser(
"https://thales1330.github.io/PSP/docs/");
459void MainFrame::OnPasteClick(wxRibbonButtonBarEvent& event)
462 if (workspace) { workspace->Paste(); }
465void MainFrame::OnPowerFlowClick(wxRibbonButtonBarEvent& event)
468 if (workspace) { workspace->RunPowerFlow(); }
471void MainFrame::OnRedoClick(wxRibbonButtonBarEvent& event)
475 workspace->SetNextState();
478void MainFrame::OnResetVoltagesClick(wxRibbonButtonBarEvent& event)
481 if (workspace) { workspace->ResetAllVoltages(); }
484void MainFrame::OnRunStabilityClick(wxRibbonButtonBarEvent& event)
487 if (workspace) { workspace->RunStability(); }
490void MainFrame::OnSCPowerClick(wxRibbonButtonBarEvent& event)
493 if (workspace) { workspace->RunSCPower(); }
496void MainFrame::OnSaveAsClick(wxRibbonButtonBarEvent& event)
502 wxFileDialog saveFileDialog(
this, _(
"Save PSP file"),
"",
"",
"PSP files (*.psp)|*.psp",
503 wxFD_SAVE | wxFD_OVERWRITE_PROMPT);
504 if (saveFileDialog.ShowModal() == wxID_CANCEL)
return;
506 fileHandling.SaveProject(saveFileDialog.GetPath());
507 wxFileName fileName(saveFileDialog.GetPath());
508 workspace->SetName(fileName.GetName());
509 m_auiNotebook->SetPageText(m_auiNotebook->GetPageIndex(workspace), workspace->GetName());
510 workspace->SetSavedPath(fileName);
514void MainFrame::OnSaveClick(wxRibbonButtonBarEvent& event)
520 if (workspace->GetSavedPath().IsOk()) {
521 fileHandling.SaveProject(workspace->GetSavedPath());
524 wxFileDialog saveFileDialog(
this, _(
"Save PSP file"),
"",
"",
"PSP files (*.psp)|*.psp",
525 wxFD_SAVE | wxFD_OVERWRITE_PROMPT);
526 if (saveFileDialog.ShowModal() == wxID_CANCEL)
return;
528 fileHandling.SaveProject(saveFileDialog.GetPath());
529 wxFileName fileName(saveFileDialog.GetPath());
530 workspace->SetName(fileName.GetName());
531 m_auiNotebook->SetPageText(m_auiNotebook->GetPageIndex(workspace), workspace->GetName());
532 workspace->SetSavedPath(fileName);
537void MainFrame::OnSnapshotClick(wxRibbonButtonBarEvent& event)
541 workspace->CopyToClipboard();
545void MainFrame::OnUndoClick(wxRibbonButtonBarEvent& event)
549 workspace->SetPreviousState();
553void MainFrame::OnAddElementsClick(wxCommandEvent& event)
558 if (workspace->GetWorkspaceMode() != Workspace::WorkspaceMode::MODE_INSERT) {
559 auto elementList = workspace->GetElementSharedList();
560 auto textList = workspace->GetTextList();
561 wxString statusBarText =
"";
562 bool newElement =
false;
565 switch (event.GetId()) {
566 case ID_ADDMENU_BUS: {
567 auto newBus = std::make_shared<Bus>(wxPoint2DDouble(0, 0),
568 wxString::Format(_(
"Bus %d"), workspace->GetElementNumber(ID_BUS)));
569 workspace->IncrementElementNumber(ID_BUS);
570 elementList.push_back(newBus);
571 statusBarText = _(
"Insert Bus: Click to insert, ESC to cancel.");
574 case ID_ADDMENU_LINE: {
575 auto newLine = std::make_shared<Line>(wxString::Format(_(
"Line %d"), workspace->GetElementNumber(ID_LINE)));
576 elementList.push_back(newLine);
577 workspace->IncrementElementNumber(ID_LINE);
578 statusBarText = _(
"Insert Line: Click on two buses, ESC to cancel.");
581 case ID_ADDMENU_TRANSFORMER: {
582 auto newTransformer = std::make_shared <Transformer>(
583 wxString::Format(_(
"Transformer %d"), workspace->GetElementNumber(ID_TRANSFORMER)));
584 workspace->IncrementElementNumber(ID_TRANSFORMER);
585 elementList.push_back(newTransformer);
586 statusBarText = _(
"Insert Transformer: Click on two buses, ESC to cancel.");
589 case ID_ADDMENU_GENERATOR: {
590 auto newGenerator = std::make_shared<SyncGenerator>(
591 wxString::Format(_(
"Generator %d"), workspace->GetElementNumber(ID_SYNCGENERATOR)));
592 workspace->IncrementElementNumber(ID_SYNCGENERATOR);
593 elementList.push_back(newGenerator);
594 statusBarText = _(
"Insert Generator: Click on a bus, ESC to cancel.");
597 case ID_ADDMENU_LOAD: {
598 auto newLoad = std::make_shared<Load>(wxString::Format(_(
"Load %d"), workspace->GetElementNumber(ID_LOAD)));
599 workspace->IncrementElementNumber(ID_LOAD);
600 elementList.push_back(newLoad);
601 statusBarText = _(
"Insert Load: Click on a bus, ESC to cancel.");
604 case ID_ADDMENU_CAPACITOR: {
605 auto newCapacitor = std::make_shared<Capacitor>(wxString::Format(_(
"Capacitor %d"), workspace->GetElementNumber(ID_CAPACITOR)));
606 workspace->IncrementElementNumber(ID_CAPACITOR);
607 elementList.push_back(newCapacitor);
608 statusBarText = _(
"Insert Capacitor: Click on a bus, ESC to cancel.");
611 case ID_ADDMENU_INDUCTOR: {
612 auto newInductor = std::make_shared<Inductor>(wxString::Format(_(
"Inductor %d"), workspace->GetElementNumber(ID_INDUCTOR)));
613 workspace->IncrementElementNumber(ID_INDUCTOR);
614 elementList.push_back(newInductor);
615 statusBarText = _(
"Insert Inductor: Click on a bus, ESC to cancel.");
618 case ID_ADDMENU_HARMCURRENT: {
619 auto newHarmCurrent = std::make_shared<HarmCurrent>(
620 wxString::Format(_(
"Harmonic Current %d"), workspace->GetElementNumber(ID_INDUCTOR)));
621 workspace->IncrementElementNumber(ID_HARMCURRENT);
622 elementList.push_back(newHarmCurrent);
623 statusBarText = _(
"Insert Harmonic Current Source: Click on a bus, ESC to cancel.");
626 case ID_ADDMENU_INDMOTOR: {
627 auto newIndMotor = std::make_shared<IndMotor>(
628 wxString::Format(_(
"Induction motor %d"), workspace->GetElementNumber(ID_INDMOTOR)));
629 workspace->IncrementElementNumber(ID_INDMOTOR);
630 elementList.push_back(newIndMotor);
631 statusBarText = _(
"Insert Induction Motor: Click on a bus, ESC to cancel.");
634 case ID_ADDMENU_SYNCCOMP: {
635 auto newSyncCondenser = std::make_shared<SyncMotor>(
636 wxString::Format(_(
"Synchronous condenser %d"), workspace->GetElementNumber(ID_SYNCMOTOR)));
637 workspace->IncrementElementNumber(ID_SYNCMOTOR);
638 elementList.push_back(newSyncCondenser);
639 statusBarText = _(
"Insert Synchronous Condenser: Click on a bus, ESC to cancel.");
642 case ID_ADDMENU_EMTELEMENT: {
643 auto newEMTElement = std::make_shared<EMTElement>(wxString::Format(_(
"Electromagnetic Transient %d"), workspace->GetElementNumber(ID_EMTELEMENT)));
644 workspace->IncrementElementNumber(ID_EMTELEMENT);
645 elementList.push_back(newEMTElement);
646 statusBarText = _(
"Insert Electromagnetic Transient Element: Click on a bus, ESC to cancel.");
649 case ID_ADDMENU_TEXT: {
651 auto newText = std::make_shared<Text>();
652 textList.push_back(newText);
653 statusBarText = _(
"Insert Label: Click to insert, ESC to cancel.");
659 workspace->SetElementList(elementList);
660 workspace->SetTextList(textList);
662 workspace->SetWorkspaceMode(Workspace::WorkspaceMode::MODE_INSERT);
664 workspace->SetWorkspaceMode(Workspace::WorkspaceMode::MODE_INSERT_TEXT);
665 workspace->SetStatusBarText(statusBarText);
672void MainFrame::OnImportClick(wxRibbonButtonBarEvent& event)
675 EnableCurrentProjectRibbon();
678 Workspace* newWorkspace =
new Workspace(m_auiNotebook, wxString::Format(_(
"New project %d"), m_projectNumber), this->GetStatusBar(), this->GetAuiNotebook());
680 newWorkspace->GetProperties()->SetGeneralPropertiesData(m_generalProperties->GetGeneralPropertiesData());
681 newWorkspace->SetColourTheme();
683 m_workspaceList.push_back(newWorkspace);
685 m_ribbonButtonBarContinuous->ToggleButton(ID_RIBBON_DISABLESOL,
true);
686 m_ribbonButtonBarContinuous->ToggleButton(ID_RIBBON_ENABLESOL,
false);
688 m_auiNotebook->AddPage(newWorkspace, newWorkspace->GetName(),
true);
689 newWorkspace->Redraw();
694 if (importForm.ShowModal() == wxID_OK) {
695 m_auiNotebook->Layout();
696 newWorkspace->Redraw();
697 newWorkspace->SetJustOpened(
true);
702void MainFrame::NotebookPageClosed(wxAuiNotebookEvent& event)
704 if (m_auiNotebook->GetPageCount() == 0) EnableCurrentProjectRibbon(
false);
708void MainFrame::NotebookPageClosing(wxAuiNotebookEvent& event)
710 auto it = m_workspaceList.begin();
711 while (it != m_workspaceList.end()) {
712 if (*it == m_auiNotebook->GetCurrentPage()) {
714 m_workspaceList.erase(it);
725void MainFrame::OnRotClockClick(wxRibbonButtonBarEvent& event)
728 if (workspace) { workspace->RotateSelectedElements(); }
731void MainFrame::OnRotCounterClockClick(wxRibbonButtonBarEvent& event)
734 if (workspace) { workspace->RotateSelectedElements(
false); }
737void MainFrame::OnGeneralSettingsClick(wxRibbonButtonBarEvent& event)
740 genPropForm.SetInitialSize();
741 genPropForm.ShowModal();
742 for (
auto& workspace : m_workspaceList) {
743 workspace->GetProperties()->SetGeneralPropertiesData(m_generalProperties->GetGeneralPropertiesData());
744 workspace->GetProperties()->SetGUIColourTheme();
745 workspace->SetColourTheme();
746 workspace->UpdateTextElements();
751void MainFrame::OnSimulationSettingsClick(wxRibbonButtonBarEvent& event)
756 simulSettingsForm.SetInitialSize();
757 simulSettingsForm.ShowModal();
760void MainFrame::OnFreqResponseClick(wxRibbonButtonBarEvent& event)
763 if (workspace) { workspace->RunFrequencyResponse(); }
765void MainFrame::OnHarmDistortionsClick(wxRibbonButtonBarEvent& event)
768 if (workspace) { workspace->RunHarmonicDistortion(); }
771void MainFrame::OnStabilityDropdown(wxRibbonButtonBarEvent& event) {
event.PopupMenu(m_stabilityMenu); }
773void MainFrame::OnStabilityMenuClick(wxCommandEvent& event)
778 auto elementList = workspace->GetElementList();
780 switch (event.GetId()) {
781 case ID_STABMENU_LIST: {
783 stabEventList.ShowModal();
789void MainFrame::OnSnapshotMenuClick(wxCommandEvent& event)
794 auto elementList = workspace->GetElementList();
796 switch (event.GetId()) {
797 case ID_SNAPSHOTMENU_LIST: {
799 wxFileDialog saveFileDialog(
this, _(
"Save diagram as SVG"),
"",
"",
"SVG files (*.svg)|*.svg",
800 wxFD_SAVE | wxFD_OVERWRITE_PROMPT);
801 if (saveFileDialog.ShowModal() == wxID_CANCEL)
return;
802 workspace->ExportAsSVG(saveFileDialog.GetPath());
808int MainFrame::RunPSPTest()
810 wxMessageOutput::Get()->Printf(
"Main frame setup OK!\n");
813 EnableCurrentProjectRibbon();
815 Workspace* newWorkspace =
new Workspace(
this, wxString::Format(_(
"New project %d"), m_projectNumber),
816 this->GetStatusBar(), this->GetAuiNotebook());
820 m_workspaceList.push_back(newWorkspace);
822 m_ribbonButtonBarContinuous->ToggleButton(ID_RIBBON_DISABLESOL,
true);
823 m_ribbonButtonBarContinuous->ToggleButton(ID_RIBBON_ENABLESOL,
false);
825 m_auiNotebook->AddPage(newWorkspace, newWorkspace->GetName(),
true);
826 newWorkspace->Redraw();
828 wxMessageOutput::Get()->Printf(
"Project creation OK!\n");
829 wxMessageOutput::Get()->Printf(
"Test done!\n");
833void MainFrame::OnClose(wxCloseEvent& event)
837 wxMessageDialog dialog(
this,
838 _(
"Are you sure you want to close the program?\nAny unsaved changes will be lost."),
839 _(
"Closing PSP-UFU..."),
840 wxYES_NO | wxICON_EXCLAMATION);
842 if (dialog.ShowModal() == wxID_YES) {
843 if (!m_workspaceList.empty())
844 m_workspaceList[m_workspaceList.size() - 1]->Show();
847 else event.Skip(
false);
849void MainFrame::OnHeatmapClick(wxRibbonButtonBarEvent& event)
853 const bool enabled = workspace->IsHeatMapEnable();
854 m_ribbonButtonBarReports->ToggleButton(ID_RIBBON_HEATMAP, !enabled);
855 workspace->EnableHeatMap(!enabled);
858void MainFrame::OnNotebookPageChanged(wxAuiNotebookEvent& event)
862 m_ribbonButtonBarReports->ToggleButton(ID_RIBBON_HEATMAP, workspace->IsHeatMapEnable());
863 m_ribbonButtonBarContinuous->ToggleButton(ID_RIBBON_ENABLESOL, workspace->IsContinuousCalculationActive());
864 m_ribbonButtonBarContinuous->ToggleButton(ID_RIBBON_DISABLESOL, !workspace->IsContinuousCalculationActive());
867void MainFrame::OnProjectSettingsClick(wxRibbonButtonBarEvent& event)
873 workspace->UpdateHeatMap();
877void MainFrame::OnSnapshotDropdown(wxRibbonButtonBarEvent& event)
879 event.PopupMenu(m_snapshotMenu);
881void MainFrame::OnLabelMngrClick(wxRibbonButtonBarEvent& event)
887 if (labelMngr.ShowModal() == wxID_OK) {
888 workspace->UpdateTextElements();
This class is responsible to manage the charts generated in the transient electromechanical studies.
Form that shows the results of power flow and fault calculations.
Base class of all elements of the program. This class is responsible for manage graphical and his dat...
wxPoint2DDouble GetPosition() const
Get the element position.
virtual void StartMove(wxPoint2DDouble position)
Update the element attributes related to the movement.
bool IsSelected() const
Checks if the element is selected.
Save and opens the projects created on disk.
~MainFrame()
Default destructor.
MainFrame()
Default constructor.
Abstract class of power elements.
General and simulation data manager.
This class manages the graphical and power elements. It is responsible for handling the user's intera...