Power System Platform  2026w34a-beta
Loading...
Searching...
No Matches
Workspace Class Reference

This class manages the graphical and power elements. It is responsible for handling the user's interaction with the elements. More...

#include <Workspace.h>

Inheritance diagram for Workspace:
Collaboration diagram for Workspace:

Public Types

enum class  WorkspaceMode : int {
  MODE_EDIT = 0 , MODE_MOVE_ELEMENT , MODE_MOVE_PICKBOX , MODE_MOVE_NODE ,
  MODE_DRAG , MODE_DRAG_INSERT , MODE_DRAG_INSERT_TEXT , MODE_INSERT ,
  MODE_INSERT_TEXT , MODE_SELECTION_RECT , MODE_PASTE , MODE_DRAG_PASTE
}
 

Public Member Functions

 Workspace (wxWindow *parent, wxString name=wxEmptyString, wxStatusBar *statusBar=nullptr, wxAuiNotebook *auiNotebook=nullptr)
 
void SetColourTheme ()
 
wxString GetName () const
 
std::vector< Element * > GetElementList () const
 
std::vector< std::shared_ptr< PowerElement > > GetElementSharedList () const
 
std::vector< std::shared_ptr< Text > > GetTextList () const
 
std::vector< Element * > GetAllElements () const
 
WorkspaceMode GetWorkspaceMode () const
 
CameraGetCamera () const
 
void CopySelection ()
 
bool Paste ()
 
void SaveCurrentState ()
 
void SetNextState ()
 
void SetPreviousState ()
 
void CopyToClipboard ()
 
void ExportAsSVG (wxString path)
 
wxFileName GetSavedPath () const
 
void SetName (wxString name)
 
void SetElementList (std::vector< std::shared_ptr< PowerElement > > elementList)
 
void SetElementList (std::vector< Element * > elementList)
 
void SetTextList (const std::vector< std::shared_ptr< Text > > &textList)
 
void SetStatusBarText (wxString text)
 
void SetWorkspaceMode (WorkspaceMode mode)
 
void SetSavedPath (wxFileName savedPath)
 
void SetJustOpened (bool justOpened)
 
virtual void Redraw ()
 
void RotateSelectedElements (bool clockwise=true)
 
void DeleteSelectedElements ()
 
bool GetElementsCorners (wxPoint2DDouble &leftUpCorner, wxPoint2DDouble &rightDownCorner, std::vector< Element * > elementList)
 
void Fit ()
 
void UnselectAll ()
 
void EnableHeatMap (const bool &enable=true)
 
bool IsHeatMapEnable () const
 
HMPlaneGetHeatMap () const
 
void EnableAutoHeatMapLabel (const bool &enable=true)
 
bool IsHeatMapAutoLabelEnable () const
 
ControlEditorManagerGetControlEditorManager () const
 
ChartWindowManagerGetChartWindowManager () const
 
void EnableGrid (bool enable=true)
 
bool IsGridEnabled () const
 
void SetGridSize (double size)
 
double GetGridSize () const
 
wxPoint2DDouble SnapToGrid (const wxPoint2DDouble &pt) const
 
void AlignSelectedToGrid ()
 
bool InsertTextElement (int textID, Element *parentElement, ElectricalUnit unit=ElectricalUnit::UNIT_NONE, int precision=2)
 
ElementFindTextElement (Element *parentElement, int dataType)
 
void RemoveAllTextElements ()
 
void CheckSlackBusDuplication (Element *newSlackBus)
 
void ValidateBusesVoltages (Element *initialBus)
 
void ValidateElementsVoltages ()
 
void UpdateElementsID ()
 
bool UpdateTextElements ()
 
void UpdateHeatMap ()
 
int GetElementNumber (ElementID elementID)
 
void IncrementElementNumber (ElementID elementID)
 
PropertiesDataGetProperties () const
 
std::vector< double > GetStabilityTimeVector () const
 
bool IsContinuousCalculationActive () const
 
void SetContinuousCalculationActive (bool value=true)
 
void ResetAllVoltages ()
 
bool RunPowerFlow (bool resetVoltages=false, bool showBusyInfo=true)
 
bool RunFault ()
 
bool RunSCPower ()
 
bool RunStaticStudies ()
 
bool RunStability ()
 
bool RunHarmonicDistortion (bool runPowerFlowBefore=true)
 
bool RunFrequencyResponse ()
 
virtual void OnMiddleDoubleClick (wxMouseEvent &event)
 
virtual void OnIdle (wxIdleEvent &event)
 
virtual void OnTimer (wxTimerEvent &event)
 
virtual void OnLeftDoubleClick (wxMouseEvent &event)
 
virtual void OnRightClickDown (wxMouseEvent &event)
 
virtual void OnLeftClickUp (wxMouseEvent &event)
 
virtual void OnScroll (wxMouseEvent &event)
 
virtual void OnMiddleDown (wxMouseEvent &event)
 
virtual void OnMiddleUp (wxMouseEvent &event)
 
virtual void OnMouseMotion (wxMouseEvent &event)
 
virtual void OnKeyDown (wxKeyEvent &event)
 
virtual void OnLeftClickDown (wxMouseEvent &event)
 
virtual void OnPaint (wxPaintEvent &event)
 
virtual void OnPopupClick (wxCommandEvent &event)
 
virtual void OnResize (wxSizeEvent &event)
 

Protected Member Functions

virtual void OnHeatMapTime (wxTimerEvent &event)
 
void UpdateStatusBar ()
 
int GetElementNumberFromList (Element *element)
 
void GetStateListsCopy (const std::vector< std::shared_ptr< PowerElement > > &elementsList, const std::vector< std::shared_ptr< Text > > &textList, std::vector< std::shared_ptr< PowerElement > > &elementsListCopy, std::vector< std::shared_ptr< Text > > &textListCopy)
 
void DrawScene (wxGraphicsContext *gc)
 
void DrawScene (wxDC &dc)
 
void DrawGrid (wxGraphicsContext *gc)
 
void DrawGrid (wxDC &dc)
 

Protected Attributes

wxStatusBar * m_statusBar = nullptr
 
wxAuiNotebook * m_auiNotebook = nullptr
 
Cameram_camera = nullptr
 
wxTipWindow::Ref m_tipWindow
 
wxString m_name
 
WorkspaceMode m_mode = WorkspaceMode::MODE_EDIT
 
WorkspaceMode m_oldStatusMode = WorkspaceMode::MODE_EDIT
 
std::vector< std::shared_ptr< PowerElement > > m_elementList
 
int m_elementNumber [NUM_ELEMENTS]
 
std::vector< std::shared_ptr< Text > > m_textList
 
std::vector< std::vector< std::shared_ptr< PowerElement > > > m_elementListState
 
std::vector< std::vector< std::shared_ptr< Text > > > m_textListState
 
int m_currenteState = -1
 
int m_maxStates = 100
 
wxFileName m_savedPath
 
wxRect2DDouble m_selectionRect
 
wxPoint2DDouble m_startSelRect
 
PropertiesDatam_properties = nullptr
 
std::vector< double > m_stabilityTimeVector
 
bool m_continuousCalc = false
 
bool m_disconnectedElement = false
 
bool m_justOpened = false
 
float m_width = 0.0
 
float m_height = 0.0
 
HMPlanem_hmPlane = nullptr
 
bool m_showHM = false
 
bool m_showHMTimer = false
 
bool m_hmAutomaticLabel = false
 
bool m_showGrid = false
 
double m_gridSize = 20.0
 
std::unique_ptr< ControlEditorManagerm_CEMngr
 
std::unique_ptr< ChartWindowManagerm_CWMngr
 

Detailed Description

This class manages the graphical and power elements. It is responsible for handling the user's interaction with the elements.

Author
Thales Lima Oliveira thale.nosp@m.s@uf.nosp@m.u.br
Date
19/09/2017

Definition at line 104 of file Workspace.h.

Member Enumeration Documentation

◆ WorkspaceMode

enum class Workspace::WorkspaceMode : int
strong

Definition at line 107 of file Workspace.h.

107 : int {
108 MODE_EDIT = 0,
109 MODE_MOVE_ELEMENT,
110 MODE_MOVE_PICKBOX,
111 MODE_MOVE_NODE,
112 MODE_DRAG,
113 MODE_DRAG_INSERT,
114 MODE_DRAG_INSERT_TEXT,
115 MODE_INSERT,
116 MODE_INSERT_TEXT,
117 MODE_SELECTION_RECT,
118 MODE_PASTE,
119 MODE_DRAG_PASTE
120 };

Constructor & Destructor Documentation

◆ Workspace() [1/2]

Workspace::Workspace ( )

Definition at line 82 of file Workspace.cpp.

82 : WorkspaceBase(nullptr)
83{
84#ifdef _DEBUG
85#ifdef SHOW_DEBUG_PANEL
86 m_debugFrame = new DebugMainFrame(this);
87 m_debugFrame->SetTitle(_("Debug window: ") + m_name);
88 m_debugFrame->Show();
89 //m_debugFrame->SetSize(m_debugFrame->GetBestVirtualSize());
90#endif
91#endif
92 SetColourTheme();
93 m_workspacePanel->SetBackgroundStyle(wxBG_STYLE_PAINT); // To allow wxBufferedPaintDC works properly.
94}

◆ Workspace() [2/2]

Workspace::Workspace ( wxWindow *  parent,
wxString  name = wxEmptyString,
wxStatusBar *  statusBar = nullptr,
wxAuiNotebook *  auiNotebook = nullptr 
)

Definition at line 96 of file Workspace.cpp.

97 : WorkspaceBase(parent)
98{
99#ifdef _DEBUG
100#ifdef SHOW_DEBUG_PANEL
101 m_debugFrame = new DebugMainFrame(this);
102 m_debugFrame->SetTitle(_("Debug window: ") + m_name);
103 m_debugFrame->Show();
104 //m_debugFrame->SetSize(m_debugFrame->GetBestVirtualSize());
105#endif
106#endif
107
108 m_timer->Start();
109 m_name = name;
110 m_statusBar = statusBar;
111 m_auiNotebook = auiNotebook;
112 //m_glContext = new wxGLContext(m_glCanvas, sharedGLContext);
113 m_camera = new Camera();
114 m_selectionRect = wxRect2DDouble(0, 0, 0, 0);
115
116 for (int i = 0; i < NUM_ELEMENTS; ++i) { m_elementNumber[i] = 1; }
117
118 const int widths[4] = { -3, -1, 100, 100 };
119 m_statusBar->SetStatusWidths(4, widths);
120
121 m_properties = new PropertiesData();
122
123 //m_glCanvas->SetBackgroundStyle(wxBG_STYLE_CUSTOM);
124 SetColourTheme();
125 m_workspacePanel->SetBackgroundStyle(wxBG_STYLE_PAINT); // To allow wxBufferedPaintDC works properly.
126
127 //m_width = static_cast<float>(m_glCanvas->GetSize().x) - 1.0;
128 //m_height = static_cast<float>(m_glCanvas->GetSize().y) - 1.0;
129 m_width = static_cast<float>(m_workspacePanel->GetSize().x) - 1.0;
130 m_height = static_cast<float>(m_workspacePanel->GetSize().y) - 1.0;
131 //m_renderer = new Renderer();
132
133 m_CEMngr = std::make_unique<ControlEditorManager>(this);
134 m_CWMngr = std::make_unique<ChartWindowManager>(this);
135
136 SaveCurrentState();
137}
Class responsible for the correct visualization of the elements on screen.
Definition Camera.h:31
General and simulation data manager.

◆ ~Workspace()

Workspace::~Workspace ( )
virtual

Definition at line 139 of file Workspace.cpp.

140{
141 if (m_hmPlane) delete m_hmPlane;
142 if (m_camera) delete m_camera;
143 if (m_properties) delete m_properties;
144}

Member Function Documentation

◆ AlignSelectedToGrid()

void Workspace::AlignSelectedToGrid ( )

Definition at line 378 of file Workspace.cpp.

379{
380 bool anySelected = false;
381 for (const auto& elem : m_elementList) {
382 if (elem->IsSelected()) {
383 anySelected = true;
384 break;
385 }
386 }
387 if (!anySelected) {
388 for (const auto& txt : m_textList) {
389 if (txt->IsSelected()) {
390 anySelected = true;
391 break;
392 }
393 }
394 }
395
396 double gs = m_gridSize > 0.0 ? m_gridSize : 20.0;
397
398 // First pass: align buses
399 for (auto& elem : m_elementList) {
400 if (elem->GetElementType() == TYPE_BUS) {
401 if (!anySelected || elem->IsSelected()) {
402 wxPoint2DDouble oldPos = elem->GetPosition();
403 elem->AlignToGrid(gs);
404 wxPoint2DDouble delta = elem->GetPosition() - oldPos;
405 if (std::abs(delta.m_x) > 1e-4 || std::abs(delta.m_y) > 1e-4) {
406 for (auto& child : elem->GetChildList()) {
407 if (auto powerElem = dynamic_cast<PowerElement*>(child)) {
408 auto& ptList = powerElem->GetPointListRef();
409 auto parentList = powerElem->GetParentList();
410 if (parentList.size() > 0 && parentList[0] == elem.get() && ptList.size() > 0) {
411 ptList[0] += delta;
412 }
413 if (parentList.size() > 1 && parentList[1] == elem.get() && ptList.size() > 1) {
414 ptList.back() += delta;
415 }
416 powerElem->UpdateSwitchesPosition();
417 powerElem->UpdatePowerFlowArrowsPosition();
418 }
419 }
420 }
421 }
422 }
423 }
424
425 // Second pass: align non-bus elements (transformers, lines, machines, shunts, etc.)
426 for (auto& elem : m_elementList) {
427 if (elem->GetElementType() != TYPE_BUS) {
428 if (!anySelected || elem->IsSelected()) {
429 elem->AlignToGrid(gs);
430 }
431 }
432 }
433
434 // Third pass: align text
435 for (auto& txt : m_textList) {
436 if (!anySelected || txt->IsSelected()) {
437 txt->AlignToGrid(gs);
438 }
439 }
440
441 SaveCurrentState();
442 Redraw();
443}
Abstract class of power elements.

◆ CheckSlackBusDuplication()

void Workspace::CheckSlackBusDuplication ( Element newSlackBus)

Definition at line 2233 of file Workspace.cpp.

2234{
2235 Bus* newBus = dynamic_cast<Bus*>(newSlackBus);
2236 if (newBus) {
2237 if (!newBus->GetElectricalData().slackBus) return; // If the new bus is not set as slack bus, no need to check for duplication.
2238
2239 for (auto& element : m_elementList) {
2240 Bus* bus = dynamic_cast<Bus*>(element.get());
2241 if (!bus) continue;
2242 if (bus->GetElectricalData().slackBus && bus != newSlackBus) {
2243 wxMessageDialog msgDialog(this,
2244 wxString::Format(_("The system already has %s as the slack bus.\nDo you want to set %s as the new slack bus?"), bus->GetElectricalData().name, newBus->GetElectricalData().name),
2245 _("Warning"), wxYES_NO | wxCENTRE | wxICON_WARNING);
2246 if (msgDialog.ShowModal() == wxID_YES) {
2247 auto data = bus->GetElectricalData();
2248 data.slackBus = false;
2249 bus->SetElectricalData(data);
2250 return;
2251 }
2252 else {
2253 auto data = newBus->GetElectricalData();
2254 data.slackBus = false;
2255 newBus->SetElectricalData(data);
2256 return;
2257 }
2258 }
2259 }
2260 }
2261}
Node for power elements. All others power elements are connected through this.
Definition Bus.h:87

◆ CopySelection()

void Workspace::CopySelection ( )

Definition at line 2425 of file Workspace.cpp.

2426{
2427 UpdateElementsID();
2428 std::vector<Element*> selectedElements;
2429 // The buses need to be numerated to associate the child's parents to the copies.
2430 int busNumber = 0;
2431 for (auto& element : m_elementList) {
2432 if (auto bus = dynamic_cast<Bus*>(element.get())) {
2433 auto data = bus->GetElectricalData();
2434 data.number = busNumber;
2435 bus->SetElectricalData(data);
2436 busNumber++;
2437 }
2438 if (element->IsSelected()) { selectedElements.push_back(element.get()); }
2439 }
2440 for (auto& text : m_textList) {
2441 if (text->IsSelected()) { selectedElements.push_back(text.get()); }
2442 }
2443 ElementDataObject* dataObject = new ElementDataObject(selectedElements);
2444 if (wxTheClipboard->Open()) {
2445 wxTheClipboard->SetData(dataObject);
2446 wxTheClipboard->Close();
2447 }
2448}
Class to store the elements in the clipboard.

◆ CopyToClipboard()

void Workspace::CopyToClipboard ( )

Definition at line 445 of file Workspace.cpp.

446{
447 wxSize size = GetClientSize();
448
449 int scale = 2;
450
451 wxBitmap bitmap(size.x * scale, size.y * scale);
452 wxMemoryDC memDC(bitmap);
453
454 memDC.SetBackground(*wxWHITE_BRUSH);
455 memDC.Clear();
456
457 wxGraphicsContext* gc = wxGraphicsContext::Create(memDC);
458 if (!gc) return;
459 gc->Scale(scale, scale); // Increase the scale to improve the quality of the copied image.
460
461 DrawScene(gc);
462 delete gc;
463
464 memDC.SelectObject(wxNullBitmap);
465
466 if (wxTheClipboard->Open())
467 {
468 wxTheClipboard->SetData(new wxBitmapDataObject(bitmap));
469 wxTheClipboard->Close();
470 }
471}

◆ DeleteSelectedElements()

void Workspace::DeleteSelectedElements ( )

Definition at line 1829 of file Workspace.cpp.

1830{
1831 // Don't set the end of the list at the loop's begin.
1832 for (auto it = m_elementList.begin(); it != m_elementList.end();) {
1833 Element* element = it->get();
1834
1835 if (element->IsSelected()) {
1836 // Remove child/parent.
1837 std::vector<Element*> childList = element->GetChildList();
1838 for (auto itc = childList.begin(), itEnd = childList.end(); itc != itEnd; ++itc) {
1839 Element* child = *itc;
1840 if (child) {
1841 child->RemoveParent(element);
1842 element->RemoveChild(child);
1843 }
1844 }
1845 std::vector<Element*> parentList = element->GetParentList();
1846 for (auto itp = parentList.begin(), itEnd = parentList.end(); itp != itEnd; ++itp) {
1847 Element* parent = *itp;
1848 if (parent) { parent->RemoveChild(element); }
1849 }
1850
1851 //for (auto& text : m_textList) {
1852 // if (text->GetElement() == element) {
1853 // if (m_textList.size() == 1) {
1854 // m_textList.erase(itt);
1855 // break;
1856 // }
1857 // else m_textList.erase(itt--);
1858 // if (text) delete text;
1859 // }
1860 //}
1861 std::erase_if(m_textList, [&](const auto& text) {
1862 return text->GetElement() == element;
1863 });
1864
1865 it = m_elementList.erase(it);
1866 //if (element) delete element;
1867 }
1868 else it++;
1869 }
1870
1871 //for (auto it = m_textList.begin(); it != m_textList.end(); ++it) {
1872 // Text* text = *it;
1873 // if (text->IsSelected()) {
1874 // if (m_textList.size() == 1) {
1875 // m_textList.erase(it);
1876 // break;
1877 // }
1878 // else m_textList.erase(it--);
1879 // if (text) delete text;
1880 // }
1881 //}
1882 std::erase_if(m_textList, [](const auto& text) {
1883 return text->IsSelected();
1884 });
1885
1886 if (m_hmPlane && m_showHM) {
1887 m_hmPlane->Clear();
1888 m_showHMTimer = true;
1889 m_timerHeatMap->Start();
1890 }
1891 SaveCurrentState();
1892 Redraw();
1893}
Base class of all elements of the program. This class is responsible for manage graphical and his dat...
Definition Element.h:115
virtual std::vector< Element * > GetParentList() const
Get the parent list.
Definition Element.h:567
virtual std::vector< Element * > GetChildList() const
Get the Child list.
Definition Element.h:572
virtual void RemoveChild(Element *child)
Remove a child from the list.
Definition Element.cpp:582
virtual void RemoveParent(Element *parent)
Remove a parent.
Definition Element.h:377
bool IsSelected() const
Checks if the element is selected.
Definition Element.h:204

◆ DrawGrid() [1/2]

void Workspace::DrawGrid ( wxDC &  dc)
protected

Definition at line 340 of file Workspace.cpp.

341{
342 if (!m_showGrid) return;
343
344 wxSize clientSize = m_workspacePanel ? m_workspacePanel->GetClientSize() : wxSize(wxRound(m_width), wxRound(m_height));
345 if (clientSize.GetWidth() <= 0 || clientSize.GetHeight() <= 0) return;
346
347 wxPoint2DDouble tl = m_camera->ScreenToWorld(wxPoint2DDouble(0, 0));
348 wxPoint2DDouble br = m_camera->ScreenToWorld(wxPoint2DDouble(clientSize.GetWidth(), clientSize.GetHeight()));
349
350 double minX = std::min(tl.m_x, br.m_x);
351 double maxX = std::max(tl.m_x, br.m_x);
352 double minY = std::min(tl.m_y, br.m_y);
353 double maxY = std::max(tl.m_y, br.m_y);
354
355 double step = m_gridSize;
356 if (step <= 0.0) step = 20.0;
357 while (step * m_camera->GetScale() < 12.0) {
358 step *= 2.0;
359 }
360
361 double startX = std::floor(minX / step) * step;
362 double endX = std::ceil(maxX / step) * step;
363 double startY = std::floor(minY / step) * step;
364 double endY = std::ceil(maxY / step) * step;
365
366 wxColour gridColour = m_properties->GetGUIColour()->grid;
367 dc.SetPen(wxPen(gridColour, 1, wxPENSTYLE_SOLID));
368
369 for (double x = startX; x <= endX + (step * 0.1); x += step) {
370 dc.DrawLine(wxRound(x), wxRound(minY), wxRound(x), wxRound(maxY));
371 }
372
373 for (double y = startY; y <= endY + (step * 0.1); y += step) {
374 dc.DrawLine(wxRound(minX), wxRound(y), wxRound(maxX), wxRound(y));
375 }
376}

◆ DrawGrid() [2/2]

void Workspace::DrawGrid ( wxGraphicsContext *  gc)
protected

Definition at line 297 of file Workspace.cpp.

298{
299 if (!m_showGrid || !gc) return;
300
301 wxSize clientSize = m_workspacePanel ? m_workspacePanel->GetClientSize() : wxSize(wxRound(m_width), wxRound(m_height));
302 if (clientSize.GetWidth() <= 0 || clientSize.GetHeight() <= 0) return;
303
304 wxPoint2DDouble tl = m_camera->ScreenToWorld(wxPoint2DDouble(0, 0));
305 wxPoint2DDouble br = m_camera->ScreenToWorld(wxPoint2DDouble(clientSize.GetWidth(), clientSize.GetHeight()));
306
307 double minX = std::min(tl.m_x, br.m_x);
308 double maxX = std::max(tl.m_x, br.m_x);
309 double minY = std::min(tl.m_y, br.m_y);
310 double maxY = std::max(tl.m_y, br.m_y);
311
312 double step = m_gridSize;
313 if (step <= 0.0) step = 20.0;
314 while (step * m_camera->GetScale() < 12.0) {
315 step *= 2.0;
316 }
317
318 double startX = std::floor(minX / step) * step;
319 double endX = std::ceil(maxX / step) * step;
320 double startY = std::floor(minY / step) * step;
321 double endY = std::ceil(maxY / step) * step;
322
323 wxGraphicsPath path = gc->CreatePath();
324
325 for (double x = startX; x <= endX + (step * 0.1); x += step) {
326 path.MoveToPoint(x, minY);
327 path.AddLineToPoint(x, maxY);
328 }
329
330 for (double y = startY; y <= endY + (step * 0.1); y += step) {
331 path.MoveToPoint(minX, y);
332 path.AddLineToPoint(maxX, y);
333 }
334
335 wxColour gridColour = m_properties->GetGUIColour()->grid;
336 gc->SetPen(wxPen(gridColour, 1.0));
337 gc->StrokePath(path);
338}

◆ DrawScene() [1/2]

void Workspace::DrawScene ( wxDC &  dc)
protected

Definition at line 253 of file Workspace.cpp.

254{
255 // HMPlane
256 if (m_hmPlane && m_showHM) {
257 m_hmPlane->DrawDC(dc);
258 }
259
260 dc.SetUserScale(m_camera->GetScale(), m_camera->GetScale());
261 dc.SetDeviceOrigin(m_camera->GetTranslation().m_x * m_camera->GetScale(), m_camera->GetTranslation().m_y * m_camera->GetScale());
262 //dc.SetLogicalOrigin(-m_camera->GetTranslation().m_x, -m_camera->GetTranslation().m_y);
263
264 DrawGrid(dc);
265
266 // Elements
267 for (auto& element : m_elementList) {
268 element->DrawDC(m_properties->GetGUIColour(), m_camera->GetTranslation(), m_camera->GetScale(), dc);
269 }
270
271 // Dummy Text to set correct context
272 // TODO: Find a better way to do this.
273 Text* text = new Text(wxPoint2DDouble(0.0, 0.0), m_properties->GetGeneralPropertiesData().labelFont, m_properties->GetGeneralPropertiesData().labelFontSize);
274 text->SetText("");
275 text->DrawDC(m_properties->GetGUIColour(), m_camera->GetTranslation(), m_camera->GetScale(), dc);
276 delete text;
277
278 // Texts
279 for (auto& text : m_textList) {
280 text->DrawDC(m_properties->GetGUIColour(), m_camera->GetTranslation(), m_camera->GetScale(), dc);
281 }
282
283 if (m_hmPlane && m_showHM) {
284 m_hmPlane->DrawLabelDC(dc);
285 }
286}
Element that shows power element informations in workspace.
Definition Text.h:71

◆ DrawScene() [2/2]

void Workspace::DrawScene ( wxGraphicsContext *  gc)
protected

Definition at line 173 of file Workspace.cpp.

174{
175 // Draw
176 if (gc) {
177
178 // HMPlane
179 if (m_hmPlane && m_showHM) {
180 //#ifdef __WXMSW__
181 // const DWORD beforeHMPlane = GetWorkspaceGDIObjects();
182 //#endif
183 m_hmPlane->DrawDC(gc);
184 //#ifdef __WXMSW__
185 // LogWorkspaceGDIDelta("Workspace::DrawScene HMPlane", beforeHMPlane);
186 //#endif
187 }
188
189 gc->Scale(m_camera->GetScale(), m_camera->GetScale());
190 gc->Translate(m_camera->GetTranslation().m_x, m_camera->GetTranslation().m_y);
191
192 DrawGrid(gc);
193
194 // Elements
195 for (auto& element : m_elementList) {
196 //#ifdef __WXMSW__
197 // const DWORD beforeElement = GetWorkspaceGDIObjects();
198 //#endif
199 element->DrawDC(m_properties->GetGUIColour(), m_camera->GetTranslation(), m_camera->GetScale(), gc);
200 //#ifdef __WXMSW__
201 // LogWorkspaceGDIDelta(wxString::Format("Workspace::DrawScene element type %d", element->GetElementType()), beforeElement);
202 //#endif
203 }
204
205 // Dummy Text to set correct context
206 // TODO: Find a better way to do this.
207//#ifdef __WXMSW__
208// const DWORD beforeDummyText = GetWorkspaceGDIObjects();
209//#endif
210 Text* text = new Text(wxPoint2DDouble(0.0, 0.0), m_properties->GetGeneralPropertiesData().labelFont, m_properties->GetGeneralPropertiesData().labelFontSize);
211 text->SetText("");
212 text->DrawDC(m_properties->GetGUIColour(), m_camera->GetTranslation(), m_camera->GetScale(), gc);
213 delete text;
214 //#ifdef __WXMSW__
215 // LogWorkspaceGDIDelta("Workspace::DrawScene dummy text", beforeDummyText);
216 //#endif
217
218 // Texts
219 for (auto& text : m_textList) {
220 //#ifdef __WXMSW__
221 // const DWORD beforeText = GetWorkspaceGDIObjects();
222 //#endif
223 text->DrawDC(m_properties->GetGUIColour(), m_camera->GetTranslation(), m_camera->GetScale(), gc);
224 //#ifdef __WXMSW__
225 // LogWorkspaceGDIDelta("Workspace::DrawScene text", beforeText);
226 //#endif
227 }
228
229 // Selection rectangle
230//#ifdef __WXMSW__
231// const DWORD beforeSelectionRect = GetWorkspaceGDIObjects();
232//#endif
233 wxColour selectionColour = m_properties->GetGUIColour()->selection;
234 gc->SetPen(wxPen(selectionColour));
235 gc->SetBrush(wxBrush(selectionColour));
236 gc->DrawRectangle(m_selectionRect.m_x, m_selectionRect.m_y, m_selectionRect.m_width, m_selectionRect.m_height);
237 //#ifdef __WXMSW__
238 // LogWorkspaceGDIDelta("Workspace::DrawScene selection rectangle", beforeSelectionRect);
239 //#endif
240
241 if (m_hmPlane && m_showHM) {
242 //#ifdef __WXMSW__
243 // const DWORD beforeHMLabel = GetWorkspaceGDIObjects();
244 //#endif
245 m_hmPlane->DrawLabelDC(gc);
246 //#ifdef __WXMSW__
247 // LogWorkspaceGDIDelta("Workspace::DrawScene heatmap label", beforeHMLabel);
248 //#endif
249 }
250 }
251}

◆ EnableAutoHeatMapLabel()

void Workspace::EnableAutoHeatMapLabel ( const bool &  enable = true)
inline

Definition at line 164 of file Workspace.h.

164{ m_hmAutomaticLabel = enable; }

◆ EnableGrid()

void Workspace::EnableGrid ( bool  enable = true)
inline

Definition at line 169 of file Workspace.h.

169{ m_showGrid = enable; }

◆ EnableHeatMap()

void Workspace::EnableHeatMap ( const bool &  enable = true)

Definition at line 2748 of file Workspace.cpp.

2749{
2750 m_showHM = enable;
2751 if (m_showHM) {
2752 UpdateHeatMap();
2753 }
2754 Redraw();
2755}

◆ ExportAsSVG()

void Workspace::ExportAsSVG ( wxString  path)

Definition at line 473 of file Workspace.cpp.

474{
475 wxSize size = GetClientSize();
476
477 wxSVGFileDC svgDC(path, size.x, size.y);
478
479 svgDC.SetClippingRegion(wxRect(0, 0, size.x, size.y));
480
481 DrawScene(svgDC);
482}

◆ FindTextElement()

Element * Workspace::FindTextElement ( Element parentElement,
int  dataType 
)

Definition at line 2215 of file Workspace.cpp.

2216{
2217 for (auto& text : m_textList) {
2218 if (text->GetElement() == parentElement && text->GetDataType() == dataType)
2219 return text.get();
2220 }
2221 return nullptr;
2222}

◆ Fit()

void Workspace::Fit ( )

Definition at line 1916 of file Workspace.cpp.

1917{
1918 wxPoint2DDouble leftUpCorner(0, 0);
1919 wxPoint2DDouble rightDownCorner(0, 0);
1920 std::vector<Element*> elementList = GetElementList();
1921 for (const auto& text : m_textList) { elementList.push_back(text.get()); }
1922
1923 if (!GetElementsCorners(leftUpCorner, rightDownCorner, elementList)) return;
1924 wxPoint2DDouble middleCoords = (leftUpCorner + rightDownCorner) / 2.0;
1925
1926 int width = 0.0;
1927 int height = 0.0;
1928 GetSize(&width, &height);
1929
1930 const double scaleX = static_cast<double>(width) / (rightDownCorner.m_x - leftUpCorner.m_x);
1931 const double scaleY = static_cast<double>(height) / (rightDownCorner.m_y - leftUpCorner.m_y);
1932
1933 double scale = scaleX < scaleY ? scaleX : scaleY;
1934 scale = std::min(scale, m_camera->GetZoomMax());
1935 scale = std::max(scale, m_camera->GetZoomMin());
1936
1937 m_camera->SetScale(scale);
1938
1939 m_camera->StartTranslation(middleCoords);
1940 m_camera->SetTranslation(wxPoint2DDouble(width / 2.0, height / 2.0));
1941
1942 if (m_hmPlane && m_showHM) {
1943 UpdateHeatMap();
1944 }
1945
1946 Redraw();
1947}

◆ GetAllElements()

std::vector< Element * > Workspace::GetAllElements ( ) const

Definition at line 2854 of file Workspace.cpp.

2855{
2856 std::vector<Element*> allElements;
2857
2858 for (auto& element : m_elementList) allElements.push_back(element.get());
2859 for (auto& text : m_textList) allElements.push_back(text.get());
2860
2861 return allElements;
2862}

◆ GetCamera()

Camera * Workspace::GetCamera ( ) const
inline

Definition at line 133 of file Workspace.h.

133{ return m_camera; }

◆ GetChartWindowManager()

ChartWindowManager & Workspace::GetChartWindowManager ( ) const
inline

Definition at line 167 of file Workspace.h.

167{ return *m_CWMngr; }

◆ GetControlEditorManager()

ControlEditorManager & Workspace::GetControlEditorManager ( ) const
inline

Definition at line 166 of file Workspace.h.

166{ return *m_CEMngr; }

◆ GetElementList()

std::vector< Element * > Workspace::GetElementList ( ) const

Definition at line 2886 of file Workspace.cpp.

2887{
2888 std::vector<Element*> elementList;
2889 for (auto& element : m_elementList) elementList.push_back(element.get());
2890 return elementList;
2891}

◆ GetElementNumber()

int Workspace::GetElementNumber ( ElementID  elementID)
inline

Definition at line 189 of file Workspace.h.

189{ return m_elementNumber[elementID]; }

◆ GetElementNumberFromList()

int Workspace::GetElementNumberFromList ( Element element)
protected

Definition at line 1510 of file Workspace.cpp.

1511{
1512 int elementNum = 0;
1513 for (auto& elementFromList : m_elementList) {
1514 if (element->GetElementType() == elementFromList->GetElementType()) {
1515 if (element == elementFromList.get()) return elementNum;
1516 elementNum++;
1517 }
1518 }
1519 return 0;
1520}

◆ GetElementsCorners()

bool Workspace::GetElementsCorners ( wxPoint2DDouble &  leftUpCorner,
wxPoint2DDouble &  rightDownCorner,
std::vector< Element * >  elementList 
)

Definition at line 1895 of file Workspace.cpp.

1898{
1899 if (elementList.size() == 0) return false;
1900
1901 elementList[0]->CalculateBoundaries(leftUpCorner, rightDownCorner);
1902
1903 for (auto it = elementList.begin() + 1, itEnd = elementList.end(); it != itEnd; it++) {
1904 Element* element = *it;
1905 wxPoint2DDouble leftUp;
1906 wxPoint2DDouble rightDown;
1907 element->CalculateBoundaries(leftUp, rightDown);
1908 if (leftUp.m_x < leftUpCorner.m_x) leftUpCorner.m_x = leftUp.m_x;
1909 if (leftUp.m_y < leftUpCorner.m_y) leftUpCorner.m_y = leftUp.m_y;
1910 if (rightDown.m_x > rightDownCorner.m_x) rightDownCorner.m_x = rightDown.m_x;
1911 if (rightDown.m_y > rightDownCorner.m_y) rightDownCorner.m_y = rightDown.m_y;
1912 }
1913 return true;
1914}
virtual void CalculateBoundaries(wxPoint2DDouble &leftUp, wxPoint2DDouble &rightBottom) const
Calculate the element boundaries.
Definition Element.cpp:493

◆ GetElementSharedList()

std::vector< std::shared_ptr< PowerElement > > Workspace::GetElementSharedList ( ) const
inline

Definition at line 129 of file Workspace.h.

129{ return m_elementList; }

◆ GetGridSize()

double Workspace::GetGridSize ( ) const
inline

Definition at line 172 of file Workspace.h.

172{ return m_gridSize; }

◆ GetHeatMap()

HMPlane * Workspace::GetHeatMap ( ) const
inline

Definition at line 163 of file Workspace.h.

163{ return m_hmPlane; }

◆ GetName()

wxString Workspace::GetName ( ) const
inline

Definition at line 127 of file Workspace.h.

127{ return m_name; }

◆ GetProperties()

PropertiesData * Workspace::GetProperties ( ) const
inline

Definition at line 191 of file Workspace.h.

191{ return m_properties; }

◆ GetSavedPath()

wxFileName Workspace::GetSavedPath ( ) const
inline

Definition at line 142 of file Workspace.h.

142{ return m_savedPath; }

◆ GetStabilityTimeVector()

std::vector< double > Workspace::GetStabilityTimeVector ( ) const
inline

Definition at line 192 of file Workspace.h.

192{ return m_stabilityTimeVector; }

◆ GetStateListsCopy()

void Workspace::GetStateListsCopy ( const std::vector< std::shared_ptr< PowerElement > > &  elementsList,
const std::vector< std::shared_ptr< Text > > &  textList,
std::vector< std::shared_ptr< PowerElement > > &  elementsListCopy,
std::vector< std::shared_ptr< Text > > &  textListCopy 
)
protected

Definition at line 1522 of file Workspace.cpp.

1526{
1527 // Free copy lists first
1528 //for (auto& element : elementsListCopy) delete element;
1529 //for (auto& text : textListCopy) delete text;
1530 elementsListCopy.clear();
1531 textListCopy.clear();
1532
1533 std::map<Element*, Element*> elementMap;
1534
1535 for (auto& element : elementsList) {
1536 //#ifdef __WXMSW__
1537 // const DWORD beforeElementCopy = GetWorkspaceGDIObjects();
1538 //#endif
1539 PowerElement* copyElement = static_cast<PowerElement*>(element->GetCopy());
1540 //#ifdef __WXMSW__
1541 // LogWorkspaceGDIDelta(wxString::Format("Workspace::GetStateListsCopy element copy type %d", element->GetElementType()), beforeElementCopy);
1542 //#endif
1543 elementsListCopy.emplace_back(copyElement);
1544 elementMap[element.get()] = copyElement;
1545 }
1546 // Correct the parent and child pointers
1547 for (auto& copyElement : elementsListCopy) {
1548 // Parent
1549 int i = 0;
1550 for (Element* parent : copyElement->GetParentList()) {
1551 auto it = elementMap.find(parent);
1552
1553 if (it != elementMap.end())
1554 copyElement->SetParent(it->second, i);
1555
1556 i++;
1557 }
1558 // Child
1559 i = 0;
1560 for (Element* child : copyElement->GetChildList()) {
1561 auto it = elementMap.find(child);
1562
1563 if (it != elementMap.end())
1564 copyElement->SetChild(it->second, i);
1565
1566 i++;
1567 }
1568 }
1569
1570 for (const auto& text : textList) {
1571 //#ifdef __WXMSW__
1572 // const DWORD beforeTextCopy = GetWorkspaceGDIObjects();
1573 //#endif
1574 auto copyText = static_cast<Text*>(text->GetCopy());
1575 //#ifdef __WXMSW__
1576 // LogWorkspaceGDIDelta("Workspace::GetStateListsCopy text copy", beforeTextCopy);
1577 //#endif
1578 // Set text the correct element associated with the text
1579 auto it = elementMap.find(copyText->GetElement());
1580
1581 if (it != elementMap.end())
1582 copyText->SetElement(it->second);
1583 else
1584 copyText->SetElement(nullptr);
1585 textListCopy.emplace_back(copyText);
1586 }
1587}

◆ GetTextList()

std::vector< std::shared_ptr< Text > > Workspace::GetTextList ( ) const
inline

Definition at line 130 of file Workspace.h.

130{ return m_textList; }

◆ GetWorkspaceMode()

WorkspaceMode Workspace::GetWorkspaceMode ( ) const
inline

Definition at line 132 of file Workspace.h.

132{ return m_mode; }

◆ IncrementElementNumber()

void Workspace::IncrementElementNumber ( ElementID  elementID)
inline

Definition at line 190 of file Workspace.h.

190{ m_elementNumber[elementID]++; }

◆ InsertTextElement()

bool Workspace::InsertTextElement ( int  textID,
Element parentElement,
ElectricalUnit  unit = ElectricalUnit::UNIT_NONE,
int  precision = 2 
)

Definition at line 1949 of file Workspace.cpp.

1950{
1951 switch (textID) {
1952 case ID_TXT_NAME: {
1953 if (FindTextElement(parentElement, DATA_NAME)) return false; // Avoid inserting more than one text element of the same type for an element.
1954 //Text* newText = new Text(parentElement->GetPosition() + wxPoint2DDouble(40, -30), m_properties->GetGeneralPropertiesData().labelFont, m_properties->GetGeneralPropertiesData().labelFontSize);
1955 auto newText = std::make_shared<Text>(parentElement->GetPosition() + wxPoint2DDouble(40, -30), m_properties->GetGeneralPropertiesData().labelFont, m_properties->GetGeneralPropertiesData().labelFontSize);
1956 newText->SetElement(parentElement);
1957 newText->SetDataType(DATA_NAME);
1958 newText->SetElementTypeText(parentElement->GetElementType());
1959 newText->SetElementNumber(GetElementNumberFromList(parentElement));
1960
1961 m_textList.push_back(newText);
1962 } break;
1963 case ID_TXT_VOLTAGE: {
1964 if (FindTextElement(parentElement, DATA_VOLTAGE)) return false;
1965 //Text* newText = new Text(parentElement->GetPosition() + wxPoint2DDouble(40, 15), m_properties->GetGeneralPropertiesData().labelFont, m_properties->GetGeneralPropertiesData().labelFontSize);
1966 auto newText = std::make_shared<Text>(parentElement->GetPosition() + wxPoint2DDouble(40, 15), m_properties->GetGeneralPropertiesData().labelFont, m_properties->GetGeneralPropertiesData().labelFontSize);
1967 newText->SetElement(parentElement);
1968 newText->SetDataType(DATA_VOLTAGE);
1969 if (unit == ElectricalUnit::UNIT_NONE)
1970 newText->SetUnit(ElectricalUnit::UNIT_PU);
1971 else
1972 newText->SetUnit(unit);
1973 newText->SetDecimalPlaces(precision);
1974 newText->SetElementTypeText(parentElement->GetElementType());
1975 newText->SetElementNumber(GetElementNumberFromList(parentElement));
1976
1977 m_textList.emplace_back(newText);
1978 } break;
1979 case ID_TXT_ANGLE: {
1980 if (FindTextElement(parentElement, DATA_ANGLE)) return false;
1981 //Text* newText = new Text(parentElement->GetPosition() + wxPoint2DDouble(40, 30), m_properties->GetGeneralPropertiesData().labelFont, m_properties->GetGeneralPropertiesData().labelFontSize);
1982 auto newText = std::make_shared<Text>(parentElement->GetPosition() + wxPoint2DDouble(40, 30), m_properties->GetGeneralPropertiesData().labelFont, m_properties->GetGeneralPropertiesData().labelFontSize);
1983 newText->SetElement(parentElement);
1984 newText->SetDataType(DATA_ANGLE);
1985 if (unit == ElectricalUnit::UNIT_NONE)
1986 newText->SetUnit(ElectricalUnit::UNIT_DEGREE);
1987 else
1988 newText->SetUnit(unit);
1989 newText->SetDecimalPlaces(precision);
1990 newText->SetElementTypeText(parentElement->GetElementType());
1991 newText->SetElementNumber(GetElementNumberFromList(parentElement));
1992
1993 m_textList.emplace_back(newText);
1994 } break;
1995 case ID_TXT_FAULTCURRENT: {
1996 if (FindTextElement(parentElement, DATA_SC_CURRENT)) return false;
1997 //Text* newText = new Text(parentElement->GetPosition() + wxPoint2DDouble(-70, 30), m_properties->GetGeneralPropertiesData().labelFont, m_properties->GetGeneralPropertiesData().labelFontSize);
1998 auto newText = std::make_shared<Text>(parentElement->GetPosition() + wxPoint2DDouble(-70, 30), m_properties->GetGeneralPropertiesData().labelFont, m_properties->GetGeneralPropertiesData().labelFontSize);
1999 newText->SetElement(parentElement);
2000 newText->SetDataType(DATA_SC_CURRENT);
2001 if (unit == ElectricalUnit::UNIT_NONE)
2002 newText->SetUnit(ElectricalUnit::UNIT_A);
2003 else
2004 newText->SetUnit(unit);
2005 newText->SetDecimalPlaces(precision);
2006 newText->SetElementTypeText(parentElement->GetElementType());
2007 newText->SetElementNumber(GetElementNumberFromList(parentElement));
2008
2009 m_textList.emplace_back(newText);
2010 } break;
2011 case ID_TXT_FAULTVOLTAGE: {
2012 if (FindTextElement(parentElement, DATA_SC_VOLTAGE)) return false;
2013 //Text* newText = new Text(parentElement->GetPosition() + wxPoint2DDouble(-70, 75), m_properties->GetGeneralPropertiesData().labelFont, m_properties->GetGeneralPropertiesData().labelFontSize);
2014 auto newText = std::make_shared<Text>(parentElement->GetPosition() + wxPoint2DDouble(-70, 75), m_properties->GetGeneralPropertiesData().labelFont, m_properties->GetGeneralPropertiesData().labelFontSize);
2015 newText->SetElement(parentElement);
2016 newText->SetDataType(DATA_SC_VOLTAGE);
2017 if (unit == ElectricalUnit::UNIT_NONE)
2018 newText->SetUnit(ElectricalUnit::UNIT_PU);
2019 else
2020 newText->SetUnit(unit);
2021 newText->SetDecimalPlaces(precision);
2022 newText->SetElementTypeText(parentElement->GetElementType());
2023 newText->SetElementNumber(GetElementNumberFromList(parentElement));
2024
2025 m_textList.emplace_back(newText);
2026 } break;
2027 case ID_TXT_SCC: {
2028 if (FindTextElement(parentElement, DATA_SC_POWER)) return false;
2029 auto newText = std::make_shared<Text>(parentElement->GetPosition() + wxPoint2DDouble(-50, -30), m_properties->GetGeneralPropertiesData().labelFont, m_properties->GetGeneralPropertiesData().labelFontSize);
2030 newText->SetElement(parentElement);
2031 newText->SetDataType(DATA_SC_POWER);
2032 newText->SetUnit(ElectricalUnit::UNIT_MVA);
2033 if (unit == ElectricalUnit::UNIT_NONE)
2034 newText->SetUnit(ElectricalUnit::UNIT_MVA);
2035 else
2036 newText->SetUnit(unit);
2037 newText->SetDecimalPlaces(precision);
2038 newText->SetElementTypeText(parentElement->GetElementType());
2039 newText->SetElementNumber(GetElementNumberFromList(parentElement));
2040
2041 m_textList.emplace_back(newText);
2042 } break;
2043 case ID_TXT_THD: {
2044 if (FindTextElement(parentElement, DATA_PQ_THD)) return false;
2045 auto newText = std::make_shared<Text>(parentElement->GetPosition() + wxPoint2DDouble(-50, -15), m_properties->GetGeneralPropertiesData().labelFont, m_properties->GetGeneralPropertiesData().labelFontSize);
2046 newText->SetElement(parentElement);
2047 newText->SetDataType(DATA_PQ_THD);
2048 newText->SetDecimalPlaces(precision);
2049 newText->SetElementTypeText(parentElement->GetElementType());
2050 newText->SetElementNumber(GetElementNumberFromList(parentElement));
2051
2052 m_textList.emplace_back(newText);
2053 } break;
2054 case ID_TXT_ACTIVE_POWER: {
2055 if (FindTextElement(parentElement, DATA_ACTIVE_POWER)) return false;
2056 auto newText = std::make_shared<Text>(parentElement->GetPosition() + wxPoint2DDouble(0, 35), m_properties->GetGeneralPropertiesData().labelFont, m_properties->GetGeneralPropertiesData().labelFontSize);
2057 newText->SetElement(parentElement);
2058 newText->SetDataType(DATA_ACTIVE_POWER);
2059 if (unit == ElectricalUnit::UNIT_NONE)
2060 newText->SetUnit(ElectricalUnit::UNIT_MW);
2061 else
2062 newText->SetUnit(unit);
2063 newText->SetDecimalPlaces(precision);
2064 newText->SetElementTypeText(parentElement->GetElementType());
2065 newText->SetElementNumber(GetElementNumberFromList(parentElement));
2066
2067 m_textList.emplace_back(newText);
2068 } break;
2069 case ID_TXT_REACTIVE_POWER: {
2070 if (FindTextElement(parentElement, DATA_REACTIVE_POWER)) return false;
2071 auto newText = std::make_shared<Text>(parentElement->GetPosition() + wxPoint2DDouble(0, 50), m_properties->GetGeneralPropertiesData().labelFont, m_properties->GetGeneralPropertiesData().labelFontSize);
2072 newText->SetElement(parentElement);
2073 newText->SetDataType(DATA_REACTIVE_POWER);
2074 if (unit == ElectricalUnit::UNIT_NONE)
2075 newText->SetUnit(ElectricalUnit::UNIT_Mvar);
2076 else
2077 newText->SetUnit(unit);
2078 newText->SetDecimalPlaces(precision);
2079 newText->SetElementTypeText(parentElement->GetElementType());
2080 newText->SetElementNumber(GetElementNumberFromList(parentElement));
2081
2082 m_textList.emplace_back(newText);
2083 } break;
2084 case ID_TXT_BRANCH_ACTIVE_POWER_1_2:
2085 case ID_TXT_BRANCH_ACTIVE_POWER_2_1: {
2086 if (FindTextElement(parentElement, DATA_PF_ACTIVE)) return false;
2087 wxPoint2DDouble position(0.0, -10.0);
2088 if (textID == ID_TXT_BRANCH_ACTIVE_POWER_1_2)
2089 position += 2.0 * parentElement->GetPointList()[1] - parentElement->GetPointList()[0];
2090 else
2091 position += 2.0 * parentElement->GetPointList()[parentElement->GetPointList().size() - 2] - parentElement->GetPointList()[parentElement->GetPointList().size() - 1];
2092
2093 auto newText = std::make_shared<Text>(position, m_properties->GetGeneralPropertiesData().labelFont, m_properties->GetGeneralPropertiesData().labelFontSize);
2094 newText->SetElement(parentElement);
2095 newText->SetDataType(DATA_PF_ACTIVE);
2096 if (unit == ElectricalUnit::UNIT_NONE)
2097 newText->SetUnit(ElectricalUnit::UNIT_MW);
2098 else
2099 newText->SetUnit(unit);
2100 newText->SetDecimalPlaces(precision);
2101 newText->SetElementTypeText(parentElement->GetElementType());
2102 newText->SetElementNumber(GetElementNumberFromList(parentElement));
2103 if (textID == ID_TXT_BRANCH_ACTIVE_POWER_2_1)
2104 newText->SetDirection(1); // std is 0
2105
2106 m_textList.emplace_back(newText);
2107 } break;
2108 case ID_TXT_BRANCH_REACTIVE_POWER_1_2:
2109 case ID_TXT_BRANCH_REACTIVE_POWER_2_1: {
2110 if (FindTextElement(parentElement, DATA_PF_REACTIVE)) return false;
2111 wxPoint2DDouble position(0.0, 10.0);
2112 if (textID == ID_TXT_BRANCH_REACTIVE_POWER_1_2)
2113 position += 2.0 * parentElement->GetPointList()[1] - parentElement->GetPointList()[0];
2114 else
2115 position += 2.0 * parentElement->GetPointList()[parentElement->GetPointList().size() - 2] - parentElement->GetPointList()[parentElement->GetPointList().size() - 1];
2116
2117 auto newText = std::make_shared<Text>(position, m_properties->GetGeneralPropertiesData().labelFont, m_properties->GetGeneralPropertiesData().labelFontSize);
2118 newText->SetElement(parentElement);
2119 newText->SetDataType(DATA_PF_REACTIVE);
2120 if (unit == ElectricalUnit::UNIT_NONE)
2121 newText->SetUnit(ElectricalUnit::UNIT_Mvar);
2122 else
2123 newText->SetUnit(unit);
2124 newText->SetDecimalPlaces(precision);
2125 newText->SetElementTypeText(parentElement->GetElementType());
2126 newText->SetElementNumber(GetElementNumberFromList(parentElement));
2127 if (textID == ID_TXT_BRANCH_REACTIVE_POWER_2_1)
2128 newText->SetDirection(1); // std is 0
2129
2130 m_textList.emplace_back(newText);
2131 } break;
2132 case ID_TXT_BRANCH_LOSSES: {
2133 if (FindTextElement(parentElement, DATA_PF_LOSSES)) return false;
2134 wxPoint2DDouble position = wxPoint2DDouble(0, 35) + (parentElement->GetPointList()[0] + parentElement->GetPointList()[parentElement->GetPointList().size() - 1]) / 2.0;
2135 auto newText = std::make_shared<Text>(position, m_properties->GetGeneralPropertiesData().labelFont, m_properties->GetGeneralPropertiesData().labelFontSize);
2136 newText->SetElement(parentElement);
2137 newText->SetDataType(DATA_PF_LOSSES);
2138 if (unit == ElectricalUnit::UNIT_NONE)
2139 newText->SetUnit(ElectricalUnit::UNIT_MW);
2140 else
2141 newText->SetUnit(unit);
2142 newText->SetDecimalPlaces(precision);
2143 newText->SetElementTypeText(parentElement->GetElementType());
2144 newText->SetElementNumber(GetElementNumberFromList(parentElement));
2145
2146 m_textList.emplace_back(newText);
2147 } break;
2148 case ID_TXT_BRANCH_CURRENT_1_2:
2149 case ID_TXT_BRANCH_CURRENT_2_1: {
2150 if (FindTextElement(parentElement, DATA_PF_CURRENT)) return false;
2151 wxPoint2DDouble position(0.0, 10.0);
2152 if (textID == ID_TXT_BRANCH_CURRENT_1_2)
2153 position += 2.0 * parentElement->GetPointList()[1] - parentElement->GetPointList()[0];
2154 else
2155 position += 2.0 * parentElement->GetPointList()[parentElement->GetPointList().size() - 2] - parentElement->GetPointList()[parentElement->GetPointList().size() - 1];
2156
2157 auto newText = std::make_shared<Text>(position, m_properties->GetGeneralPropertiesData().labelFont, m_properties->GetGeneralPropertiesData().labelFontSize);
2158 newText->SetElement(parentElement);
2159 newText->SetDataType(DATA_PF_CURRENT);
2160 if (unit == ElectricalUnit::UNIT_NONE)
2161 newText->SetUnit(ElectricalUnit::UNIT_A);
2162 else
2163 newText->SetUnit(unit);
2164 newText->SetDecimalPlaces(precision);
2165 newText->SetElementTypeText(parentElement->GetElementType());
2166 newText->SetElementNumber(GetElementNumberFromList(parentElement));
2167 if (textID == ID_TXT_BRANCH_CURRENT_2_1)
2168 newText->SetDirection(1); // std is 0
2169
2170 m_textList.emplace_back(newText);
2171 } break;
2172 case ID_TXT_BRANCH_FAULT_CURRENT_1_2:
2173 case ID_TXT_BRANCH_FAULT_CURRENT_2_1: {
2174 if (FindTextElement(parentElement, DATA_SC_CURRENT)) return false;
2175 wxPoint2DDouble position(0.0, 25.0);
2176 if (textID == ID_TXT_BRANCH_FAULT_CURRENT_1_2)
2177 position += 2.0 * parentElement->GetPointList()[1] - parentElement->GetPointList()[0];
2178 else
2179 position += 2.0 * parentElement->GetPointList()[parentElement->GetPointList().size() - 2] - parentElement->GetPointList()[parentElement->GetPointList().size() - 1];
2180
2181 auto newText = std::make_shared<Text>(position, m_properties->GetGeneralPropertiesData().labelFont, m_properties->GetGeneralPropertiesData().labelFontSize);
2182 newText->SetElement(parentElement);
2183 newText->SetDataType(DATA_SC_CURRENT);
2184 if (unit == ElectricalUnit::UNIT_NONE)
2185 newText->SetUnit(ElectricalUnit::UNIT_kA);
2186 else
2187 newText->SetUnit(unit);
2188 newText->SetDecimalPlaces(precision);
2189 newText->SetElementTypeText(parentElement->GetElementType());
2190 newText->SetElementNumber(GetElementNumberFromList(parentElement));
2191 if (textID == ID_TXT_BRANCH_FAULT_CURRENT_2_1)
2192 newText->SetDirection(1); // std is 0
2193
2194 m_textList.emplace_back(newText);
2195 } break;
2196 case ID_TXT_TAP: {
2197 if (FindTextElement(parentElement, DATA_TRANSFORMER_TAP)) return false;
2198 auto newText = std::make_shared<Text>(parentElement->GetPosition() + wxPoint2DDouble(25, -15), m_properties->GetGeneralPropertiesData().labelFont, m_properties->GetGeneralPropertiesData().labelFontSize);
2199 newText->SetElement(parentElement);
2200 newText->SetDataType(DATA_TRANSFORMER_TAP);
2201 newText->SetUnit(unit == ElectricalUnit::UNIT_NONE ? ElectricalUnit::UNIT_PU : unit);
2202 newText->SetDecimalPlaces(precision);
2203 newText->SetElementTypeText(parentElement->GetElementType());
2204 newText->SetElementNumber(GetElementNumberFromList(parentElement));
2205
2206 m_textList.emplace_back(newText);
2207 } break;
2208 default:
2209 return false;
2210 break;
2211 }
2212 return true;
2213}
virtual std::vector< wxPoint2DDouble > GetPointList() const
Get the list of points that connect the element to bus.
Definition Element.h:234
wxPoint2DDouble GetPosition() const
Get the element position.
Definition Element.h:189

◆ IsContinuousCalculationActive()

bool Workspace::IsContinuousCalculationActive ( ) const
inline

Definition at line 193 of file Workspace.h.

193{ return m_continuousCalc; }

◆ IsGridEnabled()

bool Workspace::IsGridEnabled ( ) const
inline

Definition at line 170 of file Workspace.h.

170{ return m_showGrid; }

◆ IsHeatMapAutoLabelEnable()

bool Workspace::IsHeatMapAutoLabelEnable ( ) const
inline

Definition at line 165 of file Workspace.h.

165{ return m_hmAutomaticLabel; }

◆ IsHeatMapEnable()

bool Workspace::IsHeatMapEnable ( ) const
inline

Definition at line 162 of file Workspace.h.

162{ return m_showHM; }

◆ OnHeatMapTime()

void Workspace::OnHeatMapTime ( wxTimerEvent &  event)
protectedvirtual

Definition at line 3144 of file Workspace.cpp.

3145{
3146 if (m_showHMTimer) {
3147 UpdateHeatMap();
3148 Redraw();
3149 m_showHMTimer = false;
3150 }
3151}

◆ OnIdle()

void Workspace::OnIdle ( wxIdleEvent &  event)
virtual

Definition at line 2824 of file Workspace.cpp.

2825{
2826 /*
2827 // The OpenGL element (m_glCanvas) must be completely initialized (showed) to draw properly the textures and init glew.
2828 // TODO(?): Find other solution to text displayed wrong on opened file.
2829 if (m_justOpened) {
2830 if (UpdateTextElements()) m_justOpened = false;
2831 if (glewInit() != GLEW_OK)
2832 wxMessageBox("Erro ao iniciar glew ='(");
2833 else
2834 {
2835 // Load and create shader
2836 m_basicShader = new Shader("..//data//shaders//Basic.shader");
2837 m_hmLabelShader = new Shader("..//data//shaders//HMLabel.shader");
2838 float limits[2] = { 1.05, 0.95 };
2839 m_hmPlane = new HMPlane(m_basicShader, m_hmLabelShader, m_width, m_height, limits);
2840 }
2841
2842 Redraw();
2843 }
2844 */
2845 if (m_justOpened) {
2846 m_justOpened = false;
2847 double limits[2] = { 1.05, 0.95 };
2848 m_hmPlane = new HMPlane(m_width, m_height, limits);
2849
2850 Redraw();
2851 }
2852}

◆ OnKeyDown()

void Workspace::OnKeyDown ( wxKeyEvent &  event)
virtual

Definition at line 1187 of file Workspace.cpp.

1188{
1189 bool insertingElement = false;
1190 if (m_mode == WorkspaceMode::MODE_INSERT || m_mode == WorkspaceMode::MODE_INSERT_TEXT) insertingElement = true;
1191
1192 int key = event.GetKeyCode();
1193 if (key != WXK_NONE) {
1194 switch (key) {
1195 case WXK_ESCAPE: // Cancel operations.
1196 {
1197 if (m_mode == WorkspaceMode::MODE_INSERT) {
1198 //Element* elementToDelete = m_elementList[m_elementList.size() - 1];
1199 auto elementToDelete = m_elementList.back();
1200
1201 // Remove child element that has to be deleted (specially buses)
1202 for (auto& element : m_elementList) {
1203 element->RemoveChild(elementToDelete.get());
1204 }
1205
1206 m_elementList.pop_back(); // Removes the last element being inserted.
1207 m_mode = WorkspaceMode::MODE_EDIT;
1208 Redraw();
1209 }
1210 else if (m_mode == WorkspaceMode::MODE_INSERT_TEXT) {
1211 m_textList.pop_back();
1212 m_mode = WorkspaceMode::MODE_EDIT;
1213 Redraw();
1214 }
1215 UnselectAll();
1216 } break;
1217 case WXK_DELETE: // Delete selected elements
1218 {
1219 DeleteSelectedElements();
1220 } break;
1221 case 'A': {
1222 if (!insertingElement) {
1223 if (!event.ControlDown()) {
1224 auto newText = std::make_shared<Text>(
1225 m_camera->ScreenToWorld(event.GetPosition()),
1226 m_properties->GetGeneralPropertiesData().labelFont,
1227 m_properties->GetGeneralPropertiesData().labelFontSize);
1228 m_textList.push_back(newText);
1229 m_mode = WorkspaceMode::MODE_INSERT_TEXT;
1230 m_statusBar->SetStatusText(_("Insert Text: Click to insert, ESC to cancel."));
1231 if (m_hmPlane && m_showHM) {
1232 m_hmPlane->Clear();
1233 }
1234 Redraw();
1235 }
1236 else {
1237 AlignSelectedToGrid();
1238 }
1239 }
1240 } break;
1241 case 'F': {
1242 if (event.GetModifiers() == wxMOD_SHIFT) { Fit(); }
1243 } break;
1244 case 'R': // Rotate the selected elements.
1245 {
1246 RotateSelectedElements(event.GetModifiers() != wxMOD_SHIFT);
1247 } break;
1248 case 'B': // Insert a bus.
1249 {
1250 if (!insertingElement) {
1251 auto newBus = std::make_shared<Bus>(m_camera->ScreenToWorld(event.GetPosition()),
1252 wxString::Format(_("Bus %d"), GetElementNumber(ID_BUS)));
1253 IncrementElementNumber(ID_BUS);
1254 m_elementList.push_back(newBus);
1255 m_mode = WorkspaceMode::MODE_INSERT;
1256 m_statusBar->SetStatusText(_("Insert Bus: Click to insert, ESC to cancel."));
1257 if (m_hmPlane && m_showHM) {
1258 m_hmPlane->Clear();
1259 }
1260 Redraw();
1261 }
1262 } break;
1263 case 'L': {
1264 if (!insertingElement) {
1265 if (!event.ControlDown() && event.ShiftDown()) { // Insert a load.
1266 auto newLoad = std::make_shared<Load>(wxString::Format(_("Load %d"), GetElementNumber(ID_LOAD)));
1267 IncrementElementNumber(ID_LOAD);
1268 m_elementList.push_back(newLoad);
1269 m_mode = WorkspaceMode::MODE_INSERT;
1270 m_statusBar->SetStatusText(_("Insert Load: Click on a bus, ESC to cancel."));
1271 }
1272 else if (!event.ControlDown() && !event.ShiftDown()) { // Insert a power line.
1273 auto newLine = std::make_shared<Line>(wxString::Format(_("Line %d"), GetElementNumber(ID_LINE)));
1274 IncrementElementNumber(ID_LINE);
1275 m_elementList.push_back(newLine);
1276 m_mode = WorkspaceMode::MODE_INSERT;
1277 m_statusBar->SetStatusText(_("Insert Line: Click on two buses, ESC to cancel."));
1278 }
1279 if (m_hmPlane && m_showHM) {
1280 m_hmPlane->Clear();
1281 }
1282 Redraw();
1283 }
1284 // Tests - Ctrl + Shift + L
1285 } break;
1286 case 'T': // Insert a transformer.
1287 {
1288 if (!insertingElement) {
1289 auto newTransformer = std::make_shared<Transformer>(wxString::Format(_("Transformer %d"), GetElementNumber(ID_TRANSFORMER)));
1290 IncrementElementNumber(ID_TRANSFORMER);
1291 m_elementList.push_back(newTransformer);
1292 m_mode = WorkspaceMode::MODE_INSERT;
1293 m_statusBar->SetStatusText(_("Insert Transformer: Click on two buses, ESC to cancel."));
1294 if (m_hmPlane && m_showHM) {
1295 m_hmPlane->Clear();
1296 }
1297 Redraw();
1298 }
1299 } break;
1300 case 'G': // Insert a generator.
1301 {
1302 if (!insertingElement) {
1303 auto newGenerator = std::make_shared<SyncGenerator>(wxString::Format(_("Generator %d"), GetElementNumber(ID_SYNCGENERATOR)));
1304 IncrementElementNumber(ID_SYNCGENERATOR);
1305 m_elementList.push_back(newGenerator);
1306 m_mode = WorkspaceMode::MODE_INSERT;
1307 m_statusBar->SetStatusText(_("Insert Generator: Click on a bus, ESC to cancel."));
1308 if (m_hmPlane && m_showHM) {
1309 m_hmPlane->Clear();
1310 }
1311 Redraw();
1312 }
1313 } break;
1314 case 'I': {
1315 if (!insertingElement) {
1316 if (event.GetModifiers() == wxMOD_SHIFT) { // Insert an inductor.
1317 auto newInductor = std::make_shared<Inductor>(wxString::Format(_("Inductor %d"), GetElementNumber(ID_INDUCTOR)));
1318 IncrementElementNumber(ID_INDUCTOR);
1319 m_elementList.push_back(newInductor);
1320 m_mode = WorkspaceMode::MODE_INSERT;
1321 m_statusBar->SetStatusText(_("Insert Inductor: Click on a bus, ESC to cancel."));
1322 }
1323 else // Insert an induction motor.
1324 {
1325 auto newIndMotor = std::make_shared<IndMotor>(wxString::Format(_("Induction motor %d"), GetElementNumber(ID_INDMOTOR)));
1326 IncrementElementNumber(ID_INDMOTOR);
1327 m_elementList.push_back(newIndMotor);
1328 m_mode = WorkspaceMode::MODE_INSERT;
1329 m_statusBar->SetStatusText(_("Insert Induction Motor: Click on a bus, ESC to cancel."));
1330 }
1331 if (m_hmPlane && m_showHM) {
1332 m_hmPlane->Clear();
1333 }
1334 Redraw();
1335 }
1336 } break;
1337 case 'K': // Insert a synchronous condenser.
1338 {
1339 if (!insertingElement) {
1340 auto newSyncCondenser = std::make_shared<SyncMotor>(wxString::Format(_("Synchronous condenser %d"), GetElementNumber(ID_SYNCMOTOR)));
1341 IncrementElementNumber(ID_SYNCMOTOR);
1342 m_elementList.push_back(newSyncCondenser);
1343 m_mode = WorkspaceMode::MODE_INSERT;
1344 m_statusBar->SetStatusText(_("Insert Synchronous Condenser: Click on a bus, ESC to cancel."));
1345 if (m_hmPlane && m_showHM) {
1346 m_hmPlane->Clear();
1347 }
1348 Redraw();
1349 }
1350 } break;
1351 case 'C': {
1352 if (!insertingElement) {
1353 if (event.GetModifiers() == wxMOD_SHIFT) { // Insert a capacitor.
1354 auto newCapacitor = std::make_shared<Capacitor>(wxString::Format(_("Capacitor %d"), GetElementNumber(ID_CAPACITOR)));
1355 IncrementElementNumber(ID_CAPACITOR);
1356 m_elementList.push_back(newCapacitor);
1357 m_mode = WorkspaceMode::MODE_INSERT;
1358 m_statusBar->SetStatusText(_("Insert Capacitor: Click on a bus, ESC to cancel."));
1359 if (m_hmPlane && m_showHM) {
1360 m_hmPlane->Clear();
1361 }
1362 Redraw();
1363 }
1364 else if (event.GetModifiers() == wxMOD_CONTROL) { // Copy.
1365 CopySelection();
1366 }
1367 }
1368 } break;
1369 case 'H': {
1370 if (!insertingElement) {
1371 if (event.ShiftDown() && event.ControlDown()) {
1372 if (!m_showHM) {
1373 m_showHM = true;
1374 UpdateHeatMap();
1375 }
1376 else {
1377 m_showHM = false;
1378 }
1379
1380 }
1381 else if (event.GetModifiers() == wxMOD_SHIFT) { // Insert an harmonic current source.
1382 auto newHarmCurrent = std::make_shared<HarmCurrent>(
1383 wxString::Format(_("Harmonic Current %d"), GetElementNumber(ID_HARMCURRENT)));
1384 IncrementElementNumber(ID_HARMCURRENT);
1385 m_elementList.push_back(newHarmCurrent);
1386 m_mode = WorkspaceMode::MODE_INSERT;
1387 m_statusBar->SetStatusText(
1388 _("Insert Harmonic Current Source: Click on a bus, ESC to cancel."));
1389 }
1390 if (m_hmPlane && m_showHM) {
1391 m_hmPlane->Clear();
1392 }
1393 Redraw();
1394 }
1395 } break;
1396 case 'V': {
1397 if (!insertingElement) {
1398 if (event.GetModifiers() == wxMOD_CONTROL) { Paste(); }
1399 }
1400 } break;
1401 case 'S': {
1402 if (!insertingElement) {
1403 if (event.GetModifiers() == wxMOD_CONTROL) {
1404 // Save the workspace.
1405 FileHanding fileHandling(this);
1406
1407 if (GetSavedPath().IsOk()) {
1408 fileHandling.SaveProject(GetSavedPath());
1409 }
1410 else {
1411 wxFileDialog saveFileDialog(this, _("Save PSP file"), "", "", "PSP files (*.psp)|*.psp",
1412 wxFD_SAVE | wxFD_OVERWRITE_PROMPT);
1413 if (saveFileDialog.ShowModal() == wxID_CANCEL) return;
1414
1415 fileHandling.SaveProject(saveFileDialog.GetPath());
1416 wxFileName fileName(saveFileDialog.GetPath());
1417 SetName(fileName.GetName());
1418 if (m_auiNotebook) m_auiNotebook->SetPageText(m_auiNotebook->GetPageIndex(this), GetName());
1419 SetSavedPath(fileName);
1420 }
1421 }
1422 }
1423 } break;
1424 case 'Z': {
1425 if (!insertingElement) {
1426 if (event.ControlDown() && !event.ShiftDown()) { SetPreviousState(); }
1427 if (event.ControlDown() && event.ShiftDown()) { SetNextState(); }
1428 }
1429 } break;
1430 case 'Y': {
1431 if (!insertingElement) {
1432 if (event.GetModifiers() == wxMOD_CONTROL) { SetNextState(); }
1433 }
1434 } break;
1435 case 'E': {
1436 if (!insertingElement) {
1437 if (event.GetModifiers() == wxMOD_SHIFT) {
1438
1439 if (!insertingElement) {
1440 auto newEMTElement = std::make_shared<EMTElement>(wxString::Format(_("Electromagnetic Element %d"), GetElementNumber(ID_EMTELEMENT)));
1441 IncrementElementNumber(ID_EMTELEMENT);
1442 m_elementList.push_back(newEMTElement);
1443 m_mode = WorkspaceMode::MODE_INSERT;
1444 m_statusBar->SetStatusText(_("Insert Electromagnetic Transient Element: Click on a bus, ESC to cancel."));
1445 if (m_hmPlane && m_showHM) {
1446 m_hmPlane->Clear();
1447 }
1448 Redraw();
1449 }
1450 }
1451 }
1452 } break;
1453#ifdef _DEBUG
1454#ifdef SHOW_DEBUG_PANEL
1455 case 'D': {
1456 if (event.GetModifiers() == wxMOD_CONTROL) {
1457 if (m_debugFrame) {
1458 m_debugFrame->SetFocus();
1459 }
1460 }
1461 } break;
1462#endif
1463#endif
1464 default:
1465 break;
1466 }
1467 }
1468
1469 UpdateStatusBar();
1470 event.Skip();
1471}
Save and opens the projects created on disk.
Definition FileHanding.h:43

◆ OnLeftClickDown()

void Workspace::OnLeftClickDown ( wxMouseEvent &  event)
virtual

Definition at line 484 of file Workspace.cpp.

485{
486 wxWindow* dialogParent = wxGetTopLevelParent(this);
487 if (!dialogParent) dialogParent = this;
488 //wxWindow* dialogParent = this;
489
490 wxPoint clickPoint = event.GetPosition();
491 bool foundElement = false;
492 Element* newElement = nullptr;
493 bool showNewElementForm = false;
494 bool clickOnSwitch = false;
495 bool unselectAll = true;
496 std::vector<Element*> notUnselectElementList;
497 std::vector<Text*> notUnselectTextList;
498
499 if (m_mode == WorkspaceMode::MODE_INSERT_TEXT || m_mode == WorkspaceMode::MODE_PASTE || m_mode == WorkspaceMode::MODE_DRAG_PASTE) {
500 m_mode = WorkspaceMode::MODE_EDIT;
501 SaveCurrentState();
502 }
503 else if (m_mode == WorkspaceMode::MODE_INSERT || m_mode == WorkspaceMode::MODE_DRAG_INSERT || m_mode == WorkspaceMode::MODE_DRAG_INSERT_TEXT) {
504 wxPoint2DDouble clickPointWorld = m_camera->ScreenToWorld(clickPoint);
505 if (m_showGrid) clickPointWorld = SnapToGrid(clickPointWorld);
506
507 if (!m_elementList.empty()) {
508 // Get the last element inserted on the list.
509 newElement = m_elementList.back().get();
510 for (auto& element : m_elementList) {
511 // Clicked in any element.
512 if (element->Contains(clickPointWorld)) {
513 // Click at a bus.
514 if (auto bus = dynamic_cast<Bus*>(element.get())) {
515 // Select the bus.
516 bus->SetSelected();
517 foundElement = true; // Element found.
518 // Add the new element's parent. If the element being inserted returns true, back to
519 // edit mode.
520 if (newElement->AddParent(bus, clickPointWorld)) {
521 ValidateElementsVoltages();
522 m_timer->Stop();
523 showNewElementForm = true;
524 m_mode = WorkspaceMode::MODE_EDIT;
525 bus->SetInserted();
526 }
527 }
528 }
529 }
530
531 // The line element can have an undefined number of points.
532 if (!foundElement) {
533 if (auto line = dynamic_cast<Line*>(newElement)) { line->AddPoint(clickPointWorld); }
534 }
535 foundElement = true;
536 unselectAll = false;
537 }
538 }
539 else {
540
541 bool clickPickbox = false;
542
543 for (auto& element : m_elementList) {
544 element->ResetPickboxes(); // Reset pickbox state.
545
546 // Set movement initial position (not necessarily will be moved).
547 element->StartMove(m_camera->ScreenToWorld(clickPoint));
548
549 // Click in selected element node.
550 if (element->NodeContains(m_camera->ScreenToWorld(clickPoint)) != 0 && element->IsSelected()) {
551 m_mode = WorkspaceMode::MODE_MOVE_NODE;
552 m_disconnectedElement = true;
553 foundElement = true;
554 unselectAll = false;
555 if (m_hmPlane && m_showHM) {
556 m_hmPlane->Clear();
557 }
558 }
559
560 // Click in an element.
561 else if (element->Contains(m_camera->ScreenToWorld(clickPoint))) {
562 notUnselectElementList.emplace_back(element.get());
563 if (!foundElement) {
564 if (element->IsSelected()) unselectAll = false;
565 // Select and show pickbox.
566 element->SetSelected();
567 element->ShowPickbox();
568 foundElement = true;
569 // Select the associated text
570 for (auto& text : m_textList) {
571 if (text->GetElement() == element.get()) {
572 notUnselectTextList.emplace_back(text.get());
573 text->SetSelected();
574 text->SetAllowRotation(false);
575 if (unselectAll) text->SetAltSelectionColour();
576 }
577 }
578 }
579 // If pickbox contains the click, move the pickbox
580 if (element->PickboxContains(m_camera->ScreenToWorld(clickPoint))) {
581 m_mode = WorkspaceMode::MODE_MOVE_PICKBOX;
582 clickPickbox = true;
583 }
584 // If didn't found a pickbox, move the element
585 if (!clickPickbox) { m_mode = WorkspaceMode::MODE_MOVE_ELEMENT; }
586
587 if (m_hmPlane && m_showHM) {
588 m_hmPlane->Clear();
589 }
590 }
591
592 // Click in a switch.
593 else if (element->SwitchesContains(m_camera->ScreenToWorld(clickPoint))) {
594 element->SetOnline(element->IsOnline() ? false : true);
595 clickOnSwitch = true;
596 }
597 }
598
599 // Text element
600 for (auto& text : m_textList) {
601 text->StartMove(m_camera->ScreenToWorld(clickPoint));
602
603 if (text->Contains(m_camera->ScreenToWorld(clickPoint))) {
604 notUnselectTextList.emplace_back(text.get());
605 if (!foundElement) {
606 if (text->IsSelected()) unselectAll = false;
607 text->SetSelected();
608 text->SetAltSelectionColour(false);
609 text->SetAllowRotation();
610 m_mode = WorkspaceMode::MODE_MOVE_ELEMENT;
611 foundElement = true;
612 if (m_hmPlane && m_showHM) {
613 m_hmPlane->Clear();
614 }
615 }
616 }
617 }
618 }
619
620 // Unselect all elements
621 if (!event.ControlDown() && unselectAll) {
622 for (auto& element : m_elementList) {
623 bool select = false;
624 for (Element* notUnselectElement : notUnselectElementList) {
625 if (notUnselectElement == element.get()) select = true;
626 }
627 element->SetSelected(select);
628 }
629 for (auto& text : m_textList) {
630 bool select = false;
631 for (auto& notUnselectText : notUnselectTextList) {
632 if (notUnselectText == text.get()) select = true;
633 }
634 text->SetSelected(select);
635 }
636 }
637
638 if (!foundElement && !clickOnSwitch) {
639 m_mode = WorkspaceMode::MODE_SELECTION_RECT;
640 m_startSelRect = m_camera->ScreenToWorld(clickPoint);
641 if (m_hmPlane && m_showHM) {
642 m_hmPlane->Clear();
643 }
644 }
645
646 Redraw();
647 UpdateStatusBar();
648
649 if (showNewElementForm) {
650 if (newElement) {
651 newElement->ShowForm(dialogParent, newElement, this);
652 // Modal dialogs can steal focus; restore it to the workspace panel to keep mouse/keyboard handling consistent.
653 if (m_workspacePanel) m_workspacePanel->SetFocus();
654 CheckSlackBusDuplication(newElement);
655 SaveCurrentState();
656 if (m_continuousCalc) RunStaticStudies();
657 }
658 }
659 if (clickOnSwitch && m_continuousCalc) RunStaticStudies();
660
661 event.Skip();
662}
virtual bool ShowForm(wxWindow *parent, Element *element, wxWindow *workspace=nullptr)
Show element data form.
Definition Element.h:595
virtual bool AddParent(Element *parent, wxPoint2DDouble position, bool isOpening=false)
Add a parent to the element. This method must be used on power elements that connect to a bus,...
Definition Element.h:243
Power line element.
Definition Line.h:64

◆ OnLeftClickUp()

void Workspace::OnLeftClickUp ( wxMouseEvent &  event)
virtual

Definition at line 784 of file Workspace.cpp.

785{
786 // This event (under certain conditions) deselects the elements and back to edit mode or select the elements using
787 // the selection rectangle.
788 bool foundPickbox = false;
789 bool findNewParent = false;
790 bool updateVoltages = false;
791 bool saveCurrentState = false;
792 auto itnp = m_elementList.begin();
793
794 for (auto it = m_elementList.begin(); it != m_elementList.end(); ++it) {
795 auto& element = *it;
796 // The user was moving a pickbox.
797 if (m_mode == WorkspaceMode::MODE_MOVE_PICKBOX) {
798 // Catch only the element that have the pickbox shown.
799 if (element->IsPickboxShown()) {
800 saveCurrentState = true;
801 // If the element is a bus, check if a node is outside.
802 if (auto bus = dynamic_cast<Bus*>(element.get())) {
803 // Get all the bus children.
804 for (auto child : m_elementList) {
805 for (auto parent : child->GetParentList()) {
806 // The child have a parent that is the element (bus).
807 if (parent == bus) {
808 child->UpdateNodes();
809 m_disconnectedElement = true;
810 }
811 }
812 }
813 //for (int i = 0; i < (int)m_elementList.size(); i++) {
814 // Element* child = m_elementList[i];
815 // for (int j = 0; j < (int)child->GetParentList().size(); j++) {
816 // Element* parent = child->GetParentList()[j];
817 // // The child have a parent that is the element.
818 // if (parent == element) {
819 // child->UpdateNodes();
820 // m_disconnectedElement = true;
821 // }
822 // }
823 //}
824 }
825 }
826 }
827
828 if (m_mode == WorkspaceMode::MODE_SELECTION_RECT) {
829 if (element->Intersects(m_selectionRect)) {
830 element->SetSelected();
831 // Select the associated text
832 for (auto& text : m_textList) {
833 if (text->GetElement() == element.get()) {
834 text->SetSelected();
835 text->SetAltSelectionColour(false);
836 text->SetAllowRotation();
837 }
838 }
839 }
840 //else if (!event.ControlDown()) {
841 // element->SetSelected(false);
842 //}
843 }
844 else if (m_mode == WorkspaceMode::MODE_MOVE_NODE) {
845 if (element->IsSelected()) {
846 saveCurrentState = true;
847 for (auto parent : m_elementList) {
848 if (auto bus = dynamic_cast<Bus*>(parent.get())) {
849 if (element->SetNodeParent(bus)) {
850 parent->AddChild(element.get());
851 findNewParent = true;
852 itnp = it;
853 element->ResetNodes();
854 break;
855 }
856 }
857 }
858 // element->ResetNodes();
859 }
860 }
861 else {
862 // Deselect
863 //if (!event.ControlDown()) {
864 // if (!element->Contains(m_camera->ScreenToWorld(event.GetPosition()))) { element->SetSelected(false); }
865 //}
866
867 if (element->PickboxContains(m_camera->ScreenToWorld(event.GetPosition()))) {
868 foundPickbox = true;
869 }
870 else {
871 element->ShowPickbox(false);
872 element->ResetPickboxes();
873 }
874 }
875 }
876
877 // Text element
878 for (auto& text : m_textList) {
879 if (m_mode == WorkspaceMode::MODE_SELECTION_RECT) {
880 if (text->Intersects(m_selectionRect)) {
881 text->SetSelected();
882 text->SetAltSelectionColour(false);
883 text->SetAllowRotation();
884 }
885 //else if (!event.ControlDown()) {
886 // text->SetSelected(false);
887 //}
888 }
889 //else if (!event.ControlDown()) {
890 // if (!text->Contains(m_camera->ScreenToWorld(event.GetPosition()))) { text->SetSelected(false); }
891 //}
892 }
893 if (m_mode == WorkspaceMode::MODE_MOVE_ELEMENT) saveCurrentState = true;
894
895 if (findNewParent) {
896 std::rotate(itnp, itnp + 1, m_elementList.end());
897 updateVoltages = true;
898 }
899 if (!foundPickbox) { SetCursor(wxCURSOR_ARROW); }
900
901 if (m_mode != WorkspaceMode::MODE_INSERT) { m_mode = WorkspaceMode::MODE_EDIT; }
902
903 if (updateVoltages) { ValidateElementsVoltages(); }
904
905 if (saveCurrentState) SaveCurrentState();
906
907 if (m_continuousCalc && m_disconnectedElement) {
908 m_disconnectedElement = false;
909 RunStaticStudies();
910 }
911
912 m_selectionRect = wxRect2DDouble(0, 0, 0, 0);
913
914 if (m_hmPlane && m_showHM) {
915 m_showHMTimer = true;
916 m_timerHeatMap->Start();
917 }
918
919 Redraw();
920 UpdateStatusBar();
921}

◆ OnLeftDoubleClick()

void Workspace::OnLeftDoubleClick ( wxMouseEvent &  event)
virtual

Definition at line 664 of file Workspace.cpp.

665{
666 wxWindow* dialogParent = wxGetTopLevelParent(this);
667 if (!dialogParent) dialogParent = this;
668 //wxWindow* dialogParent = this;
669
670 bool elementEdited = false;
671 bool clickOnSwitch = false;
672 bool redraw = false;
673
674 for (auto& element : m_elementList) {
675 // Click in an element.
676 if (element->Contains(m_camera->ScreenToWorld(event.GetPosition()))) {
677 bool elementIsBus = false;
678 Bus oldBus;
679 Bus* currentBus = nullptr;
680 if ((currentBus = dynamic_cast<Bus*>(element.get()))) {
681 elementIsBus = true;
682 oldBus = *currentBus;
683 }
684 m_timer->Stop();
685 if (element->ShowForm(dialogParent, element.get(), this)) {
686 CheckSlackBusDuplication(element.get());
687 SaveCurrentState();
688 }
689 // Modal dialogs can steal focus; restore it to the workspace panel to keep mouse/keyboard handling consistent.
690 if (m_workspacePanel) m_workspacePanel->SetFocus();
691 elementEdited = true;
692 redraw = true;
693
694 // If the edited element is a bus and was changed the rated voltage, this voltage must be
695 // propagated through the lines
696 if (elementIsBus) {
697 // The voltage was changed
698 if (oldBus.GetElectricalData().nominalVoltage != currentBus->GetElectricalData().nominalVoltage ||
699 oldBus.GetElectricalData().nominalVoltageUnit !=
700 currentBus->GetElectricalData().nominalVoltageUnit) {
701 // Check if the bus has line as child.
702 std::vector<Element*> childList = element->GetChildList();
703 for (auto itc = childList.begin(), itcEnd = childList.end(); itc != itcEnd; ++itc) {
704 Element* child = *itc;
705 if (typeid(*child) == typeid(Line)) {
706 wxMessageDialog msgDialog(dialogParent, _("Do you want to change the rated voltage of the path?"),
707 _("Warning"), wxYES_NO | wxCENTRE | wxICON_WARNING);
708 if (msgDialog.ShowModal() == wxID_YES)
709 ValidateBusesVoltages(element.get());
710 else {
711 auto data = currentBus->GetElectricalData();
712 data.nominalVoltage = oldBus.GetElectricalData().nominalVoltage;
713 data.nominalVoltageUnit = oldBus.GetElectricalData().nominalVoltageUnit;
714 currentBus->SetElectricalData(data);
715 }
716 break;
717 }
718 }
719 }
720 ValidateElementsVoltages();
721 }
722
723 // Handle only one element per double-click to avoid opening multiple modals in sequence.
724 break;
725 }
726
727 // Click in a switch.
728 else if (element->SwitchesContains(m_camera->ScreenToWorld(event.GetPosition()))) {
729 element->SetOnline(element->IsOnline() ? false : true);
730 clickOnSwitch = true;
731 }
732 }
733
734 // Text element
735 for (auto& text : m_textList) {
736 if (text->Contains(m_camera->ScreenToWorld(event.GetPosition()))) {
737 if (text->ShowForm(dialogParent, GetElementList(), this)) SaveCurrentState();
738 // Modal dialogs can steal focus; restore it to the workspace panel to keep mouse/keyboard handling consistent.
739 if (m_workspacePanel) m_workspacePanel->SetFocus();
740 redraw = true;
741 break;
742 }
743 }
744 if (elementEdited) {
745 UpdateTextElements();
746 if (m_continuousCalc) RunStaticStudies();
747 }
748 if (clickOnSwitch && m_continuousCalc) RunStaticStudies();
749
750 if (redraw) Redraw();
751 m_timer->Start();
752}

◆ OnMiddleDoubleClick()

void Workspace::OnMiddleDoubleClick ( wxMouseEvent &  event)
virtual

Definition at line 2965 of file Workspace.cpp.

2966{
2967 Fit();
2968 event.Skip();
2969}

◆ OnMiddleDown()

void Workspace::OnMiddleDown ( wxMouseEvent &  event)
virtual

Definition at line 1112 of file Workspace.cpp.

1113{
1114 // Set to drag mode.
1115 switch (m_mode) {
1116 case WorkspaceMode::MODE_INSERT: {
1117 m_mode = WorkspaceMode::MODE_DRAG_INSERT;
1118 } break;
1119 case WorkspaceMode::MODE_INSERT_TEXT: {
1120 m_mode = WorkspaceMode::MODE_DRAG_INSERT_TEXT;
1121 } break;
1122 case WorkspaceMode::MODE_PASTE: {
1123 m_mode = WorkspaceMode::MODE_DRAG_PASTE;
1124 } break;
1125 default: {
1126 m_mode = WorkspaceMode::MODE_DRAG;
1127 } break;
1128 }
1129 m_camera->StartTranslation(m_camera->ScreenToWorld(event.GetPosition()));
1130 UpdateStatusBar();
1131
1132 if (m_hmPlane && m_showHM) {
1133 m_hmPlane->Clear();
1134 }
1135
1136 event.Skip();
1137}

◆ OnMiddleUp()

void Workspace::OnMiddleUp ( wxMouseEvent &  event)
virtual

Definition at line 1139 of file Workspace.cpp.

1140{
1141 switch (m_mode) {
1142 case WorkspaceMode::MODE_DRAG_INSERT: {
1143 m_mode = WorkspaceMode::MODE_INSERT;
1144 } break;
1145 case WorkspaceMode::MODE_DRAG_INSERT_TEXT: {
1146 m_mode = WorkspaceMode::MODE_INSERT_TEXT;
1147 } break;
1148 case WorkspaceMode::MODE_DRAG_PASTE: {
1149 m_mode = WorkspaceMode::MODE_PASTE;
1150 } break;
1151 case WorkspaceMode::MODE_INSERT:
1152 case WorkspaceMode::MODE_INSERT_TEXT:
1153 case WorkspaceMode::MODE_PASTE: {
1154 // Does nothing.
1155 } break;
1156 default: {
1157 m_mode = WorkspaceMode::MODE_EDIT;
1158 } break;
1159 }
1160 UpdateStatusBar();
1161
1162 if (m_hmPlane && m_showHM) {
1163 UpdateHeatMap();
1164 Redraw();
1165 }
1166
1167 event.Skip();
1168}

◆ OnMouseMotion()

void Workspace::OnMouseMotion ( wxMouseEvent &  event)
virtual

Definition at line 923 of file Workspace.cpp.

924{
925 bool redraw = false;
926 switch (m_mode) {
927 case WorkspaceMode::MODE_INSERT: {
928 auto& newElement = m_elementList.back(); // Get the last element in the list.
929 wxPoint2DDouble pos = m_camera->ScreenToWorld(event.GetPosition());
930 if (m_showGrid) pos = SnapToGrid(pos);
931 newElement->SetPosition(pos);
932 redraw = true;
933 } break;
934
935 case WorkspaceMode::MODE_INSERT_TEXT: {
936 auto& newText = m_textList.back();
937 wxPoint2DDouble pos = m_camera->ScreenToWorld(event.GetPosition());
938 if (m_showGrid) pos = SnapToGrid(pos);
939 newText->SetPosition(pos);
940 redraw = true;
941 } break;
942
943 case WorkspaceMode::MODE_DRAG:
944 case WorkspaceMode::MODE_DRAG_INSERT:
945 case WorkspaceMode::MODE_DRAG_INSERT_TEXT:
946 case WorkspaceMode::MODE_DRAG_PASTE: {
947 m_camera->SetTranslation(event.GetPosition());
948 redraw = true;
949 } break;
950
951 case WorkspaceMode::MODE_EDIT: {
952 bool foundPickbox = false;
953 for (auto& element : m_elementList) {
954 if (element->IsSelected()) {
955 // Show element pickbox (when it has) if the mouse is over the selected object.
956 if (element->Contains(m_camera->ScreenToWorld(event.GetPosition()))) {
957 element->ShowPickbox();
958 redraw = true;
959
960 // If the mouse is over a pickbox set correct mouse cursor.
961 if (element->PickboxContains(m_camera->ScreenToWorld(event.GetPosition()))) {
962 foundPickbox = true;
963 //#ifdef __WXMSW__
964 // const DWORD beforeCursor = GetWorkspaceGDIObjects();
965 //#endif
966 SetCursor(element->GetBestPickboxCursor());
967 //#ifdef __WXMSW__
968 // LogWorkspaceGDIDelta(wxString::Format("Workspace::OnMouseMotion pickbox cursor type %d", element->GetElementType()), beforeCursor);
969 //#endif
970 }
971 else if (!foundPickbox) {
972 //#ifdef __WXMSW__
973 // const DWORD beforeCursor = GetWorkspaceGDIObjects();
974 //#endif
975 SetCursor(wxCURSOR_ARROW);
976 //#ifdef __WXMSW__
977 // LogWorkspaceGDIDelta("Workspace::OnMouseMotion arrow cursor", beforeCursor);
978 //#endif
979 element->ResetPickboxes();
980 }
981 }
982 else if (!foundPickbox) {
983 if (element->IsPickboxShown()) redraw = true;
984
985 element->ShowPickbox(false);
986 element->ResetPickboxes();
987 //#ifdef __WXMSW__
988 // const DWORD beforeCursor = GetWorkspaceGDIObjects();
989 //#endif
990 SetCursor(wxCURSOR_ARROW);
991 //#ifdef __WXMSW__
992 // LogWorkspaceGDIDelta("Workspace::OnMouseMotion arrow cursor", beforeCursor);
993 //#endif
994 }
995 }
996 }
997 } break;
998
999 case WorkspaceMode::MODE_MOVE_NODE: {
1000 wxPoint2DDouble pos = m_camera->ScreenToWorld(event.GetPosition());
1001 if (m_showGrid) pos = SnapToGrid(pos);
1002 for (auto& element : m_elementList) {
1003 if (element->IsSelected()) {
1004 element->MoveNode(nullptr, pos);
1005 redraw = true;
1006 }
1007 }
1008 } break;
1009
1010 case WorkspaceMode::MODE_MOVE_PICKBOX: {
1011 wxPoint2DDouble pos = m_camera->ScreenToWorld(event.GetPosition());
1012 if (m_showGrid) pos = SnapToGrid(pos);
1013 for (auto& element : m_elementList) {
1014 if (element->IsSelected()) {
1015 element->MovePickbox(pos);
1016 redraw = true;
1017 }
1018 }
1019 if (m_hmPlane && m_showHM) {
1020 m_hmPlane->Clear();
1021 }
1022 } break;
1023
1024 case WorkspaceMode::MODE_MOVE_ELEMENT:
1025 case WorkspaceMode::MODE_PASTE: {
1026 wxPoint2DDouble mouseWorld = m_camera->ScreenToWorld(event.GetPosition());
1027 wxPoint2DDouble effectivePos = mouseWorld;
1028 if (m_showGrid) {
1029 Element* refElement = nullptr;
1030 for (auto& element : m_elementList) {
1031 if (element->IsSelected()) {
1032 refElement = element.get();
1033 break;
1034 }
1035 }
1036 if (!refElement) {
1037 for (auto& text : m_textList) {
1038 if (text->IsSelected()) {
1039 refElement = text.get();
1040 break;
1041 }
1042 }
1043 }
1044 if (refElement) {
1045 wxPoint2DDouble rawTarget = refElement->GetPosition() + (mouseWorld - refElement->GetMoveStartPosition());
1046 wxPoint2DDouble snappedTarget = SnapToGrid(rawTarget);
1047 effectivePos = refElement->GetMoveStartPosition() + (snappedTarget - refElement->GetPosition());
1048 }
1049 else {
1050 effectivePos = SnapToGrid(mouseWorld);
1051 }
1052 }
1053
1054 for (auto it = m_elementList.begin(), itEnd = m_elementList.end(); it != itEnd; ++it) {
1055 auto element = *it;
1056 if (element->IsSelected()) {
1057 element->Move(effectivePos);
1058 // Move child nodes
1059 std::vector<Element*> childList = element->GetChildList();
1060 for (auto it = childList.begin(), itEnd = childList.end(); it != itEnd; ++it) {
1061 (*it)->MoveNode(element.get(), effectivePos);
1062 }
1063 redraw = true;
1064 }
1065 }
1066 // Text element motion
1067 for (auto& text : m_textList) {
1068 if (text->IsSelected()) {
1069 text->Move(effectivePos);
1070 redraw = true;
1071 }
1072 }
1073 if (m_hmPlane && m_showHM) {
1074 m_hmPlane->Clear();
1075 }
1076 } break;
1077
1078 case WorkspaceMode::MODE_SELECTION_RECT: {
1079 wxPoint2DDouble currentPos = m_camera->ScreenToWorld(event.GetPosition());
1080 double x, y, w, h;
1081 if (currentPos.m_x < m_startSelRect.m_x) {
1082 x = currentPos.m_x;
1083 w = m_startSelRect.m_x - currentPos.m_x;
1084 }
1085 else {
1086 x = m_startSelRect.m_x;
1087 w = currentPos.m_x - m_startSelRect.m_x;
1088 }
1089 if (currentPos.m_y < m_startSelRect.m_y) {
1090 y = currentPos.m_y;
1091 h = m_startSelRect.m_y - currentPos.m_y;
1092 }
1093 else {
1094 y = m_startSelRect.m_y;
1095 h = currentPos.m_y - m_startSelRect.m_y;
1096 }
1097
1098 m_selectionRect = wxRect2DDouble(x, y, w, h);
1099 redraw = true;
1100 } break;
1101 }
1102
1103 if (redraw) {
1104 Redraw();
1105 }
1106 m_camera->UpdateMousePosition(event.GetPosition());
1107 UpdateStatusBar();
1108 m_timer->Start(); // Restart the timer.
1109 event.Skip();
1110}

◆ OnPaint()

void Workspace::OnPaint ( wxPaintEvent &  event)
virtual

Definition at line 152 of file Workspace.cpp.

153{
154 //#ifdef __WXMSW__
155 // const DWORD beforePaint = GetWorkspaceGDIObjects();
156 //#endif
157 //{
158 wxAutoBufferedPaintDC dc(m_workspacePanel);
159 dc.Clear();
160 wxGraphicsContext* gc = wxGraphicsContext::Create(dc);
161
162 // Draw
163 DrawScene(gc);
164 delete gc;
165 //}
166//#ifdef __WXMSW__
167// LogWorkspaceGDIDelta("Workspace::OnPaint", beforePaint);
168//#endif
169
170 event.Skip();
171}

◆ OnPopupClick()

void Workspace::OnPopupClick ( wxCommandEvent &  event)
virtual

Definition at line 1650 of file Workspace.cpp.

1651{
1652 wxWindow* dialogParent = wxGetTopLevelParent(this);
1653 if (!dialogParent) dialogParent = this;
1654 //wxWindow* dialogParent = this;
1655
1656 bool redrawHM = false;
1657
1658 wxMenu* menu = static_cast<wxMenu*>(event.GetEventObject());
1659 Element* element = static_cast<Element*>(menu->GetClientData());
1660 int eventID = event.GetId();
1661 switch (eventID) {
1662 case ID_EDIT_ELEMENT: {
1663 if (element->ShowForm(dialogParent, element, this)) {
1664 CheckSlackBusDuplication(element);
1665 UpdateTextElements();
1666 SaveCurrentState();
1667 }
1668 // Modal dialogs can steal focus; restore it to the workspace panel to keep mouse/keyboard handling consistent.
1669 if (m_workspacePanel) m_workspacePanel->SetFocus();
1670 } break;
1671 case ID_LINE_ADD_NODE: {
1672 Line* line = static_cast<Line*>(element);
1673 line->AddNode(m_camera->GetMousePosition());
1674 SaveCurrentState();
1675 Redraw();
1676 } break;
1677 case ID_LINE_REMOVE_NODE: {
1678 Line* line = static_cast<Line*>(element);
1679 line->RemoveNode(m_camera->GetMousePosition());
1680 SaveCurrentState();
1681 Redraw();
1682 } break;
1683 case ID_ROTATE_CLOCK: {
1684 element->Rotate();
1685 for (auto& iElement : m_elementList) {
1686 // Parent's element rotating...
1687 for (int i = 0; i < (int)iElement->GetParentList().size(); i++) {
1688 Element* parent = iElement->GetParentList()[i];
1689 if (parent == element) { iElement->RotateNode(parent); }
1690 }
1691 }
1692 redrawHM = true;
1693 SaveCurrentState();
1694 Redraw();
1695 } break;
1697 element->Rotate(false);
1698 for (auto& iElement : m_elementList) {
1699 // Parent's element rotating...
1700 for (int i = 0; i < (int)iElement->GetParentList().size(); i++) {
1701 Element* parent = iElement->GetParentList()[i];
1702 if (parent == element) { iElement->RotateNode(parent, false); }
1703 }
1704 }
1705 redrawHM = true;
1706 SaveCurrentState();
1707 Redraw();
1708 } break;
1709 case ID_DELETE: {
1710 //for (auto& iElement : m_elementList) {
1711 // if (element == iElement.get()) {
1712 // // Remove child/parent.
1713 // std::vector<Element*> childList = element->GetChildList();
1714 // for (auto& child : childList) {
1715 // if (child) {
1716 // child->RemoveParent(element);
1717 // element->RemoveChild(child);
1718 // }
1719 // }
1720 // std::vector<Element*> parentList = element->GetParentList();
1721 // for (auto& parent : parentList) {
1722 // if (parent) { parent->RemoveChild(element); }
1723 // }
1724 //
1725 // //for (auto itt = m_textList.begin(); itt != m_textList.end(); ++itt) {
1726 // // Text* text = *itt;
1727 // // if (text->GetElement() == element) {
1728 // // m_textList.erase(itt--);
1729 // // if (text) delete text;
1730 // // }
1731 // //}
1732 // std::erase_if(m_textList, [&](const auto& text) {
1733 // return text->GetElement() == element;
1734 // });
1735 //
1736 // std::erase_if(m_elementList, [&](const auto& delElement) {
1737 // return delElement.get() == element;
1738 // });
1739 //
1740 // //m_elementList.erase(it);
1741 // //if (element) delete element;
1742 // menu->SetClientData(nullptr);
1743 // break;
1744 // }
1745 //}
1746 //SaveCurrentState();
1747
1748 // Remove child/parent.
1749 std::vector<Element*> childList = element->GetChildList();
1750 for (auto child : childList) {
1751 if (child) {
1752 child->RemoveParent(element);
1753 element->RemoveChild(child);
1754 }
1755 }
1756
1757 std::vector<Element*> parentList = element->GetParentList();
1758 for (auto parent : parentList) {
1759 if (parent)
1760 parent->RemoveChild(element);
1761 }
1762
1763 std::erase_if(m_textList, [&](const auto& text) {
1764 return text->GetElement() == element;
1765 });
1766
1767 std::erase_if(m_elementList, [&](const auto& delElement) {
1768 return delElement.get() == element;
1769 });
1770
1771 menu->SetClientData(nullptr);
1772 SaveCurrentState();
1773 } break;
1774 default:
1775 if (InsertTextElement(eventID, element)) {
1776 UpdateTextElements();
1777 SaveCurrentState();
1778 }
1779 break;
1780 }
1781 if (redrawHM && m_hmPlane && m_showHM) {
1782 m_hmPlane->Clear();
1783 m_showHMTimer = true;
1784 m_timerHeatMap->Start();
1785 }
1786}
@ ID_LINE_REMOVE_NODE
Definition Element.h:79
@ ID_DELETE
Definition Element.h:82
@ ID_ROTATE_CLOCK
Definition Element.h:80
@ ID_EDIT_ELEMENT
Definition Element.h:77
@ ID_ROTATE_COUNTERCLOCK
Definition Element.h:81
@ ID_LINE_ADD_NODE
Definition Element.h:78
virtual void Rotate(bool clockwise=true)
Rotate the element.
Definition Element.h:321

◆ OnResize()

void Workspace::OnResize ( wxSizeEvent &  event)
virtual

Definition at line 3131 of file Workspace.cpp.

3132{
3133 m_width = static_cast<float>(GetSize().x) - 1.0f;
3134 m_height = static_cast<float>(GetSize().y) - 1.0f;
3135
3136 if (m_hmPlane && m_showHM) {
3137 m_hmPlane->ResizeDC(m_width, m_height);
3138 m_showHMTimer = true;
3139 m_timerHeatMap->Start();
3140 }
3141
3142 event.Skip();
3143}

◆ OnRightClickDown()

void Workspace::OnRightClickDown ( wxMouseEvent &  event)
virtual

Definition at line 754 of file Workspace.cpp.

755{
756 bool redraw = false;
757 if (m_mode == WorkspaceMode::MODE_EDIT) {
758 for (auto& element : m_elementList) {
759 if (element->IsSelected()) {
760 // Show context menu.
761 if (element->Contains(m_camera->ScreenToWorld(event.GetPosition()))) {
762 element->ShowPickbox(false);
763 wxMenu menu;
764 menu.SetClientData(element.get());
765 if (element->GetContextMenu(menu)) {
766 m_timer->Stop();
767 menu.Bind(wxEVT_COMMAND_MENU_SELECTED, &Workspace::OnPopupClick, this);
768 PopupMenu(&menu);
769 // Context menus can steal focus; restore it so subsequent mouse events keep working.
770 if (m_workspacePanel) m_workspacePanel->SetFocus();
771 redraw = true;
772
773 if (!menu.GetClientData()) break;
774 }
775 element->ResetPickboxes();
776 }
777 }
778 }
779 }
780 if (redraw) Redraw();
781 m_timer->Start();
782}

◆ OnScroll()

void Workspace::OnScroll ( wxMouseEvent &  event)
virtual

Definition at line 1170 of file Workspace.cpp.

1171{
1172 if (event.GetWheelRotation() > 0)
1173 m_camera->SetScale(event.GetPosition(), +0.05);
1174 else
1175 m_camera->SetScale(event.GetPosition(), -0.05);
1176
1177 if (m_hmPlane && m_showHM) {
1178 m_hmPlane->Clear();
1179 m_showHMTimer = true;
1180 m_timerHeatMap->Start();
1181 }
1182
1183 UpdateStatusBar();
1184 Redraw();
1185}

◆ OnTimer()

void Workspace::OnTimer ( wxTimerEvent &  event)
virtual

Definition at line 2769 of file Workspace.cpp.

2770{
2771 if (m_tipWindow) {
2772 m_tipWindow->Close();
2773 m_tipWindow = nullptr;
2774 }
2775 if (m_mode == WorkspaceMode::MODE_EDIT) {
2776 for (auto& element : m_elementList) {
2777 if (element->Contains(m_camera->GetMousePosition())) {
2778 wxString tipText = element->GetTipText();
2779 if (!tipText.IsEmpty()) {
2780 //m_tipWindow = new wxTipWindow(this, tipText, 10000, &m_tipWindow);
2781 m_tipWindow = wxTipWindow::New(this, tipText, 10000);
2782 // Creates a very tiny bounding rect to remove the tip on any mouse movement.
2783 m_tipWindow->SetBoundingRect(wxRect(wxGetMousePosition(), wxSize(1, 1)));
2784 break;
2785 }
2786 }
2787 }
2788 }
2789
2790 m_timer->Stop();
2791}

◆ Paste()

bool Workspace::Paste ( )

Definition at line 2450 of file Workspace.cpp.

2451{
2452 if (wxTheClipboard->Open()) {
2453 ElementDataObject dataObject;
2454
2455 if (wxTheClipboard->IsSupported(dataObject.GetFormat())) {
2456 if (!wxTheClipboard->GetData(dataObject)) {
2457 wxMessageDialog dialog(this, _("It was not possible to paste from clipboard."), _("Error"),
2458 wxOK | wxCENTER | wxICON_ERROR, wxDefaultPosition);
2459 dialog.ShowModal();
2460 wxTheClipboard->Close();
2461 return false;
2462 }
2463 }
2464 else {
2465 wxTheClipboard->Close();
2466 return false;
2467 }
2468 wxTheClipboard->Close();
2469
2470 UnselectAll();
2471
2472 std::vector<Element*> pastedElements;
2473 ElementsLists* elementsLists = dataObject.GetElementsLists();
2474
2475 // Paste buses (parents).
2476 auto parentList = elementsLists->parentList;
2477 std::vector<Bus*> pastedBusList; // To set new parents;
2478 for (auto it = parentList.begin(), itEnd = parentList.end(); it != itEnd; ++it) {
2479 Element* copy = (*it)->GetCopy();
2480 if (copy) {
2481 pastedElements.push_back(copy);
2482 pastedBusList.push_back(static_cast<Bus*>(copy));
2483 m_elementList.emplace_back(static_cast<PowerElement*>(copy));
2484 }
2485 }
2486
2487 // Paste other elements.
2488 auto elementLists = elementsLists->elementList;
2489 for (auto it = elementLists.begin(), itEnd = elementLists.end(); it != itEnd; ++it) {
2490 Element* copy = (*it)->GetCopy();
2491 if (copy) {
2492 // Check if is text element
2493 if (Text* text = dynamic_cast<Text*>(copy)) {
2494 // Check if element associated with the text exists.
2495 bool elementExist = false;
2496 for (auto& element : m_elementList) {
2497 if (text->GetElement() == element.get()) {
2498 elementExist = true;
2499 break;
2500 }
2501 }
2502 if (elementExist) {
2503 pastedElements.push_back(copy);
2504 m_textList.emplace_back(text);
2505 }
2506 }
2507 else {
2508 // Change the parent if copied, otherwise remove it.
2509 for (size_t j = 0; j < copy->GetParentList().size(); j++) {
2510 Bus* currentParent = static_cast<Bus*>(copy->GetParentList()[j]);
2511 if (currentParent) {
2512 int parentID = currentParent->GetID();
2513 bool parentCopied = false;
2514 for (size_t k = 0; k < pastedBusList.size(); k++) {
2515 Bus* newParent = pastedBusList[k];
2516 if (parentID == newParent->GetID()) {
2517 parentCopied = true;
2518 copy->ReplaceParent(currentParent, newParent);
2519 break;
2520 }
2521 }
2522 if (!parentCopied) copy->RemoveParent(currentParent);
2523 }
2524 }
2525
2526 pastedElements.push_back(copy);
2527 m_elementList.emplace_back(static_cast<PowerElement*>(copy));
2528 }
2529 }
2530 }
2531
2532 // Update buses childs
2533 for (auto it = pastedBusList.begin(), itEnd = pastedBusList.end(); it != itEnd; ++it) {
2534 Bus* bus = *it;
2535 std::vector<Element*> childList = bus->GetChildList();
2536 for (auto it = childList.begin(), itEnd = childList.end(); it != itEnd; ++it) {
2537 Element* currentChild = *it;
2538 int childID = currentChild->GetID();
2539 bool childCopied = false;
2540 for (int i = 0; i < (int)pastedElements.size(); i++) {
2541 Element* newChild = pastedElements[i];
2542 if (childID == newChild->GetID()) {
2543 childCopied = true;
2544 bus->ReplaceChild(currentChild, newChild);
2545 break;
2546 }
2547 }
2548 if (!childCopied) bus->RemoveChild(currentChild);
2549 }
2550 }
2551
2552 // Move elements (and nodes) to the mouse position.
2553 // The start position it's the center of the pasted objects.
2554 wxPoint2DDouble leftUpCorner, rightDownCorner;
2555 GetElementsCorners(leftUpCorner, rightDownCorner, pastedElements);
2556 wxPoint2DDouble startPosition = (leftUpCorner + rightDownCorner) / 2.0;
2557 for (auto it = pastedElements.begin(), itEnd = pastedElements.end(); it != itEnd; ++it) {
2558 Element* element = *it;
2559 element->StartMove(startPosition);
2560 element->Move(m_camera->GetMousePosition());
2561 for (int i = 0; i < (int)element->GetParentList().size(); i++) {
2562 Element* parent = element->GetParentList()[i];
2563 element->MoveNode(parent, m_camera->GetMousePosition());
2564 }
2565 }
2566 }
2567 else {
2568 wxMessageDialog dialog(this, _("It was not possible to paste from clipboard."), _("Error"),
2569 wxOK | wxCENTER | wxICON_ERROR, wxDefaultPosition);
2570 dialog.ShowModal();
2571 return false;
2572 }
2573
2574 UpdateElementsID();
2575 m_mode = WorkspaceMode::MODE_PASTE;
2576 m_statusBar->SetStatusText(_("Click to paste."));
2577 UpdateStatusBar();
2578 Redraw();
2579 return true;
2580}
virtual Element * GetCopy()
Get a the element copy.
Definition Element.h:265
virtual int GetID() const
Get the element ID.
Definition Element.h:275
virtual void ReplaceParent(Element *oldParent, Element *newParent)
Replace a parent.
Definition Element.cpp:574
virtual void StartMove(wxPoint2DDouble position)
Update the element attributes related to the movement.
Definition Element.cpp:335
virtual void MoveNode(Element *parent, wxPoint2DDouble position)
Move a node. StartMove(wxPoint2DDouble position) before start moving.
Definition Element.h:352
virtual void Move(wxPoint2DDouble position)
Move the element other position.
Definition Element.cpp:341
virtual void ReplaceChild(Element *oldChild, Element *newChild)
Replace a child from the list.
Definition Element.cpp:590

◆ Redraw()

virtual void Workspace::Redraw ( )
inlinevirtual

Definition at line 152 of file Workspace.h.

152{ m_workspacePanel->Refresh(); }

◆ RemoveAllTextElements()

void Workspace::RemoveAllTextElements ( )

Definition at line 2224 of file Workspace.cpp.

2225{
2226 //for (auto* text : m_textList) {
2227 // if (text) delete text;
2228 //}
2229 m_textList.clear();
2230 SaveCurrentState();
2231}

◆ ResetAllVoltages()

void Workspace::ResetAllVoltages ( )

Definition at line 2311 of file Workspace.cpp.

2312{
2313 PowerFlow pf(GetElementList());
2314 pf.ResetVoltages();
2315 UpdateTextElements();
2316 Redraw();
2317}
Calculate the power flow (including OLTC tap adjustment).
Definition PowerFlow.h:37

◆ RotateSelectedElements()

void Workspace::RotateSelectedElements ( bool  clockwise = true)

Definition at line 1788 of file Workspace.cpp.

1789{
1790 bool saveCurrrentState = false;
1791 for (auto& element : m_elementList) {
1792 // Parent's element rotating...
1793 for (int i = 0; i < (int)element->GetParentList().size(); i++) {
1794 Element* parent = element->GetParentList()[i];
1795 if (parent) { // Check if parent is not null
1796 if (parent->IsSelected()) {
1797 element->RotateNode(parent, clockwise);
1798 // Update the positions used on motion action, the element will not be necessarily
1799 // moved.
1800 element->StartMove(m_camera->GetMousePosition());
1801 }
1802 }
1803 }
1804 if (element->IsSelected()) {
1805 saveCurrrentState = true;
1806 element->Rotate(clockwise);
1807 element->StartMove(m_camera->GetMousePosition());
1808 }
1809 }
1810
1811 // Rotate text element
1812 for (auto& text : m_textList) {
1813 if (text->IsSelected()) {
1814 saveCurrrentState = true;
1815 text->Rotate(clockwise);
1816 text->StartMove(m_camera->GetMousePosition());
1817 }
1818 }
1819 if (saveCurrrentState) SaveCurrentState();
1820
1821 if (m_hmPlane && m_showHM) {
1822 m_hmPlane->Clear();
1823 m_showHMTimer = true;
1824 m_timerHeatMap->Start();
1825 }
1826 Redraw();
1827}

◆ RunFault()

bool Workspace::RunFault ( )

Definition at line 2864 of file Workspace.cpp.

2865{
2866 auto simProp = m_properties->GetSimulationPropertiesData();
2867 double basePower = simProp.basePower;
2868 if (simProp.basePowerUnit == ElectricalUnit::UNIT_MVA)
2869 basePower *= 1e6;
2870 else if (simProp.basePowerUnit == ElectricalUnit::UNIT_kVA)
2871 basePower *= 1e3;
2872
2873 Fault fault(GetElementList());
2874 bool result = fault.RunFaultCalculation(basePower);
2875 if (!result) {
2876 wxMessageDialog msgDialog(this, fault.GetErrorMessage(), _("Error"), wxOK | wxCENTRE | wxICON_ERROR);
2877 msgDialog.ShowModal();
2878 }
2879
2880 UpdateTextElements();
2881 Redraw();
2882
2883 return result;
2884}
Calculate the fault of the system and update the elements data.
Definition Fault.h:31

◆ RunFrequencyResponse()

bool Workspace::RunFrequencyResponse ( )

Definition at line 3080 of file Workspace.cpp.

3081{
3082 // Get bus list
3083 std::vector<Bus*> busList;
3084 for (auto& element : m_elementList) {
3085 if (Bus* bus = dynamic_cast<Bus*>(element.get())) { busList.push_back(bus); }
3086 }
3087
3088 auto data = m_properties->GetFreqRespData();
3089
3090 FrequencyResponseForm frForm(this, busList, data.injBusNumber, data.initFreq, data.finalFreq, data.stepFreq);
3091
3092 if (frForm.ShowModal() == wxID_OK) {
3093 data.initFreq = frForm.GetInitFreq();
3094 data.finalFreq = frForm.GetEndFreq();
3095 data.stepFreq = frForm.GetStepFreq();
3096 data.injBusNumber = frForm.GetInjBusNumber();
3097 m_properties->SetFreqRespData(data);
3098 }
3099 else
3100 return false;
3101
3102 auto simProp = m_properties->GetSimulationPropertiesData();
3103 double basePower = simProp.basePower;
3104 if (simProp.basePowerUnit == ElectricalUnit::UNIT_MVA)
3105 basePower *= 1e6;
3106 else if (simProp.basePowerUnit == ElectricalUnit::UNIT_kVA)
3107 basePower *= 1e3;
3108 PowerQuality pq(GetElementList());
3109 bool result = pq.CalculateFrequencyResponse(simProp.stabilityFrequency, data.initFreq, data.finalFreq,
3110 data.stepFreq, data.injBusNumber, basePower, simProp.harmLoadConnection);
3111
3112 wxMessageDialog msgDialog(
3113 this, wxString::Format(_("Calculations done.\nDo you wish to open the frequency response graphics?")),
3114 _("Question"), wxYES_NO | wxCENTRE | wxICON_QUESTION);
3115 if (msgDialog.ShowModal() == wxID_YES) {
3116 std::vector<ElementPlotData> plotDataList;
3117 for (auto& element : m_elementList) {
3118 ElementPlotData plotData;
3119 if (element->GetPlotData(plotData, PlotStudy::FREQRESPONSE)) plotDataList.push_back(plotData);
3120 }
3121
3122 ChartView* cView = new ChartView(this, plotDataList, pq.GetFrequencies(), m_properties->GetGeneralPropertiesData().plotLib);
3123 cView->Show();
3124 }
3125
3126 UpdateTextElements();
3127 Redraw();
3128
3129 return result;
3130}
This class is responsible to manage the charts generated in the transient electromechanical studies.
Definition ChartView.h:49
Responsible for the power quality calculations.

◆ RunHarmonicDistortion()

bool Workspace::RunHarmonicDistortion ( bool  runPowerFlowBefore = true)

Definition at line 3006 of file Workspace.cpp.

3007{
3008 auto simProp = m_properties->GetSimulationPropertiesData();
3009 double basePower = simProp.basePower;
3010 if (simProp.basePowerUnit == ElectricalUnit::UNIT_MVA)
3011 basePower *= 1e6;
3012 else if (simProp.basePowerUnit == ElectricalUnit::UNIT_kVA)
3013 basePower *= 1e3;
3014 if (runPowerFlowBefore) {
3015 if (!RunPowerFlow(true)) return false;
3016 }
3017
3018 bool hasEMTElement = false;
3019 for (auto& element : m_elementList) {
3020 if (auto emtElement = dynamic_cast<EMTElement*>(element.get())) {
3021 if (emtElement->IsOnline()) hasEMTElement = true;
3022 }
3023 }
3024
3025 HarmLoadConnection loadConnection = simProp.harmLoadConnection;
3026
3027 PowerQuality pq(GetElementList());
3028 bool result = pq.CalculateDistortions(basePower, loadConnection);
3029
3030 // If has EMT element, repeat the Power Flow and Harmonics calculation untion DHT converge.
3031 if (hasEMTElement && result) {
3032 wxBusyInfo info(
3033 wxBusyInfoFlags()
3034 .Parent(this)
3035 .Icon(wxIcon(Paths::GetDataPath() + "/images/ribbon/harmDist32.png", wxBITMAP_TYPE_PNG))
3036 .Title(_("<b>Calculating Harmonic Flow</b>"))
3037 .Text(_("Please wait..."))
3038 .Foreground(*wxWHITE)
3039 .Background(*wxBLACK)
3040 .Transparency(4 * wxALPHA_OPAQUE / 5)
3041 );
3042 std::vector<double> thdList;
3043 for (auto const& bus : pq.GetBusList())
3044 thdList.emplace_back(bus->GetElectricalData().thd);
3045 double error = 1e3;
3046 while (error > 1e-3) {
3047 // Run Power Flow
3048 if (!RunPowerFlow(false, false)) return false;
3049
3050 // Run Harmonic Distortion
3051 bool result = pq.CalculateDistortions(basePower, loadConnection);
3052 if (!result) break;
3053
3054 // Calculate error
3055 int i = 0;
3056 for (auto const& bus : pq.GetBusList()) {
3057 double errorBus = std::abs(bus->GetElectricalData().thd - thdList[i]);
3058 if (i == 0)
3059 error = errorBus;
3060 else if (errorBus > error)
3061 error = errorBus;
3062 thdList[i] = bus->GetElectricalData().thd;
3063 i++;
3064 }
3065 }
3066 }
3067
3068 if (!result) {
3069 wxMessageDialog msgDialog(this, pq.GetErrorMessage(), _("Error"), wxOK | wxCENTRE | wxICON_ERROR);
3070 msgDialog.ShowModal();
3071 }
3072 else {
3073 UpdateTextElements();
3074 Redraw();
3075 }
3076
3077 return result;
3078}
Element to connect ATP-EMTP.
Definition EMTElement.h:83

◆ RunPowerFlow()

bool Workspace::RunPowerFlow ( bool  resetVoltages = false,
bool  showBusyInfo = true 
)

Definition at line 2319 of file Workspace.cpp.

2320{
2321 auto simProp = m_properties->GetSimulationPropertiesData();
2322 double basePower = simProp.basePower;
2323 if (simProp.basePowerUnit == ElectricalUnit::UNIT_MVA)
2324 basePower *= 1e6;
2325 else if (simProp.basePowerUnit == ElectricalUnit::UNIT_kVA)
2326 basePower *= 1e3;
2327
2328 // Update EMTElements
2329 for (auto& element : m_elementList) {
2330 if (auto emtElement = dynamic_cast<EMTElement*>(element.get())) {
2331 if (emtElement->IsOnline()) {
2332 emtElement->UpdateData(m_properties, true);
2333 }
2334 }
2335 }
2336 bool result = false;
2337 wxString errorMsg = "";
2338 int numIt = 0;
2339
2340 wxStopWatch sw;
2341 {
2342 wxBusyInfo* info = nullptr;
2343 if (showBusyInfo)
2344 info = new wxBusyInfo(
2345 wxBusyInfoFlags()
2346 .Parent(this)
2347 .Icon(wxIcon(Paths::GetDataPath() + "/images/ribbon/powerFLow32.png", wxBITMAP_TYPE_PNG))
2348 .Title(_("<b>Calculating Power Flow</b>"))
2349 .Text(_("Please wait..."))
2350 .Foreground(*wxWHITE)
2351 .Background(*wxBLACK)
2352 .Transparency(4 * wxALPHA_OPAQUE / 5)
2353 );
2354 //wxBusyInfo info
2355 //(
2356 // wxBusyInfoFlags()
2357 // .Parent(this)
2358 // .Icon(wxIcon(wxT("..\\data\\images\\ribbon\\powerFLow32.png"), wxBITMAP_TYPE_PNG))
2359 // .Title(_("<b>Calculating Power Flow</b>"))
2360 // .Text(_("Please wait..."))
2361 // .Foreground(*wxWHITE)
2362 // .Background(*wxBLACK)
2363 // .Transparency(4 * wxALPHA_OPAQUE / 5)
2364 //);
2365
2366 PowerFlow pf(GetElementList());
2367 if (resetVoltages) pf.ResetVoltages();
2368
2369 switch (simProp.powerFlowMethod) {
2370 case GAUSS_SEIDEL: {
2371 result = pf.RunGaussSeidel(basePower, simProp.powerFlowMaxIterations, simProp.powerFlowTolerance,
2372 simProp.initAngle, simProp.accFator);
2373 } break;
2374 case NEWTON_RAPHSON: {
2375 result = pf.RunNewtonRaphson(basePower, simProp.powerFlowMaxIterations, simProp.powerFlowTolerance,
2376 simProp.initAngle, simProp.newtonInertia);
2377 } break;
2378 case GAUSS_NEWTON: {
2379 result =
2380 pf.RunGaussNewton(basePower, simProp.powerFlowMaxIterations, simProp.powerFlowTolerance,
2381 simProp.initAngle, simProp.accFator, simProp.gaussTolerance, simProp.newtonInertia);
2382 } break;
2383 }
2384
2385 errorMsg = pf.GetErrorMessage();
2386 numIt = pf.GetIterations();
2387
2388 if (showBusyInfo) delete info;
2389 }
2390 sw.Pause();
2391
2392 if (!result) {
2393 wxMessageDialog msgDialog(this, errorMsg, _("Error"), wxOK | wxCENTRE | wxICON_ERROR);
2394 msgDialog.ShowModal();
2395 }
2396 else {
2397 m_statusBar->SetStatusText(
2398 wxString::Format(_("Power flow converge with %d iterations (%ld ms)"), numIt, sw.Time()));
2399 }
2400
2401 UpdateTextElements();
2402 UpdateHeatMap();
2403 Redraw();
2404
2405 return result;
2406}

◆ RunSCPower()

bool Workspace::RunSCPower ( )

Definition at line 2893 of file Workspace.cpp.

2894{
2895 Fault fault(GetElementList());
2896
2897 auto simProp = m_properties->GetSimulationPropertiesData();
2898 double basePower = simProp.basePower;
2899 if (simProp.basePowerUnit == ElectricalUnit::UNIT_MVA)
2900 basePower *= 1e6;
2901 else if (simProp.basePowerUnit == ElectricalUnit::UNIT_kVA)
2902 basePower *= 1e3;
2903
2904 bool result = fault.RunSCPowerCalcutation(basePower);
2905 if (!result) {
2906 wxMessageDialog msgDialog(this, fault.GetErrorMessage(), _("Error"), wxOK | wxCENTRE | wxICON_ERROR);
2907 msgDialog.ShowModal();
2908 }
2909
2910 UpdateTextElements();
2911 Redraw();
2912
2913 return result;
2914}

◆ RunStability()

bool Workspace::RunStability ( )

Definition at line 2916 of file Workspace.cpp.

2917{
2918 // Run power flow before stability.
2919 RunPowerFlow();
2920
2921 Electromechanical stability(this, GetElementList(), m_properties->GetSimulationPropertiesData());
2922 wxStopWatch sw;
2923 bool result = stability.RunStabilityCalculation();
2924#ifdef _DEBUG
2925#ifdef SHOW_DEBUG_PANEL
2926 m_debugFrame->AppendDebugMessage(stability.GetDebugMessage());
2927#endif
2928#endif // _DEBUG
2929
2930 sw.Pause();
2931 if (!result) {
2932 wxMessageDialog msgDialog(this, stability.GetErrorMessage(), _("Error"), wxOK | wxCENTRE | wxICON_ERROR);
2933 msgDialog.ShowModal();
2934 }
2935 m_stabilityTimeVector.clear();
2936 m_stabilityTimeVector = stability.GetTimeVector();
2937
2938 // Run power flow after stability.
2939 RunPowerFlow();
2940
2941 wxMessageDialog msgDialog(
2942 this,
2943 wxString::Format(_("The program took %ld ms to run this system.\nDo you wish to open the stability graphics?"),
2944 sw.Time()),
2945 _("Question"), wxYES_NO | wxCENTRE | wxICON_QUESTION);
2946 if (msgDialog.ShowModal() == wxID_YES) {
2947 std::vector<ElementPlotData> plotDataList;
2948 for (auto& element : m_elementList) {
2949 ElementPlotData plotData;
2950 if (element->GetPlotData(plotData)) plotDataList.push_back(plotData);
2951 }
2952#ifdef SHOW_SIMULATION_PARAMETERS
2953 ElementPlotData plotData;
2954 plotData.SetName(_("Simulation parameters"));
2955 plotData.SetCurveType(ElementPlotData::CurveType::CT_TEST);
2956 plotData.AddData(stability.GetIterationVector(), _("Iterations number"));
2957 plotDataList.push_back(plotData);
2958#endif
2959 ChartView* cView = new ChartView(this, plotDataList, m_stabilityTimeVector, m_properties->GetGeneralPropertiesData().plotLib);
2960 cView->Show();
2961 }
2962
2963 return result;
2964}
Calculates the electromechanical transient based on disturbances (e.g. system fault).

◆ RunStaticStudies()

bool Workspace::RunStaticStudies ( )

Definition at line 2971 of file Workspace.cpp.

2972{
2973 bool pfStatus, faultStatus, scStatus, harmStatus;
2974 pfStatus = faultStatus = scStatus = harmStatus = false;
2975
2976 bool runHarmDistortion = m_properties->GetSimulationPropertiesData().harmDistortionAfterPowerFlow;
2977
2978 pfStatus = RunPowerFlow(runHarmDistortion);
2979
2980 if (m_properties->GetSimulationPropertiesData().faultAfterPowerFlow) {
2981 if (pfStatus) faultStatus = RunFault();
2982 }
2983 else {
2984 faultStatus = true;
2985 }
2986
2987 if (m_properties->GetSimulationPropertiesData().scPowerAfterPowerFlow) {
2988 if (pfStatus) scStatus = RunSCPower();
2989 }
2990 else {
2991 scStatus = true;
2992 }
2993
2994 if (runHarmDistortion) {
2995 if (pfStatus) harmStatus = RunHarmonicDistortion(false);
2996 }
2997 else {
2998 harmStatus = true;
2999 }
3000
3001 if (pfStatus && faultStatus && scStatus && harmStatus) return true;
3002
3003 return false;
3004}

◆ SaveCurrentState()

void Workspace::SaveCurrentState ( )

Definition at line 2582 of file Workspace.cpp.

2583{
2584 //return;
2585//#ifdef __WXMSW__
2586// const DWORD beforeSaveState = GetWorkspaceGDIObjects();
2587//#endif
2588 // Setup current state
2589 std::vector< std::shared_ptr<PowerElement> > currentStateElementList;
2590 std::vector< std::shared_ptr<Text> > currentStateTextList;
2591
2592 GetStateListsCopy(m_elementList, m_textList, currentStateElementList, currentStateTextList);
2593 //#ifdef __WXMSW__
2594 // LogWorkspaceGDIDelta("Workspace::SaveCurrentState after copy", beforeSaveState);
2595 //#endif
2596
2597 // Delete all states after the current one
2598 //auto itE = m_elementListState.begin();
2599 //std::advance(itE, m_currenteState + 1);
2600 //for (; itE != m_elementListState.end(); ++itE) {
2601 // auto& elementList = *itE;
2602 // for (auto& element : elementList) delete element;
2603 // elementList.clear();
2604 //}
2605 m_elementListState.resize(m_currenteState + 1);
2606
2607 //auto itT = m_textListState.begin();
2608 //std::advance(itT, m_currenteState + 1);
2609 //for (; itT != m_textListState.end(); ++itT) {
2610 // auto& textList = *itT;
2611 // for (auto& text : textList) delete text;
2612 // textList.clear();
2613 //}
2614 m_textListState.resize(m_currenteState + 1);
2615
2616 m_currenteState++;
2617 if (m_currenteState >= m_maxStates) {
2618 m_currenteState = m_maxStates - 1;
2619 // Erase the first sate on the list
2620 //auto itE = m_elementListState.begin();
2622 //auto& elementList = *itE;
2624 //for (auto& element : elementList) delete element;
2625 //elementList.clear();
2628 //
2629 //m_elementListState.erase(itE);
2630 //m_textListState.erase(itT);
2631 m_elementListState.erase(m_elementListState.begin());
2632 m_textListState.erase(m_textListState.begin());
2633 }
2634
2635 m_elementListState.emplace_back(currentStateElementList);
2636 m_textListState.emplace_back(currentStateTextList);
2637 //#ifdef __WXMSW__
2638 // LogWorkspaceGDIDelta(wxString::Format("Workspace::SaveCurrentState stored states=%zu elements=%zu texts=%zu",
2639 // m_elementListState.size(),
2640 // currentStateElementList.size(),
2641 // currentStateTextList.size()),
2642 // beforeSaveState);
2643 //#endif
2644
2645#ifdef _DEBUG
2646 wxString msg = "";
2647 wxString pointerStr;
2648 pointerStr.Printf("[%d S saved s%d] ", m_currenteState, m_elementListState.size());
2649 msg += pointerStr;
2650 for (auto& element : currentStateElementList) {
2651 pointerStr.Printf("%p ", element.get());
2652 msg += pointerStr;
2653 }
2654 msg += "\n";
2655 pointerStr.Printf("[%d S curr s%d] ", m_currenteState, m_elementListState.size());
2656 msg += pointerStr;
2657 for (auto& element : m_elementList) {
2658 pointerStr.Printf("%p ", element.get());
2659 msg += pointerStr;
2660 }
2661 msg += "\n";
2662 //m_debugFrame->AppendDebugMessage(msg);
2663#endif
2664}

◆ SetColourTheme()

void Workspace::SetColourTheme ( )

Definition at line 146 of file Workspace.cpp.

147{
148 m_properties->SetGUIColourTheme();
149 m_workspacePanel->SetBackgroundColour(m_properties->GetGUIColour()->background);
150}

◆ SetContinuousCalculationActive()

void Workspace::SetContinuousCalculationActive ( bool  value = true)
inline

Definition at line 194 of file Workspace.h.

194{ m_continuousCalc = value; }

◆ SetElementList() [1/2]

void Workspace::SetElementList ( std::vector< Element * >  elementList)

Definition at line 2817 of file Workspace.cpp.

2818{
2819 m_elementList.clear();
2820 for (auto it = elementList.begin(), itEnd = elementList.end(); it != itEnd; ++it)
2821 m_elementList.emplace_back(static_cast<PowerElement*>(*it));
2822}

◆ SetElementList() [2/2]

void Workspace::SetElementList ( std::vector< std::shared_ptr< PowerElement > >  elementList)

Definition at line 2812 of file Workspace.cpp.

2813{
2814 m_elementList = std::move(elementList);
2815}

◆ SetGridSize()

void Workspace::SetGridSize ( double  size)
inline

Definition at line 171 of file Workspace.h.

171{ m_gridSize = size; }

◆ SetJustOpened()

void Workspace::SetJustOpened ( bool  justOpened)
inline

Definition at line 150 of file Workspace.h.

150{ m_justOpened = justOpened; }

◆ SetName()

void Workspace::SetName ( wxString  name)

Definition at line 2802 of file Workspace.cpp.

2803{
2804 m_name = name;
2805#ifdef _DEBUG
2806#ifdef SHOW_DEBUG_PANEL
2807 m_debugFrame->SetTitle(_("Debug window: ") + m_name);
2808#endif
2809#endif
2810}

◆ SetNextState()

void Workspace::SetNextState ( )

Definition at line 2666 of file Workspace.cpp.

2667{
2668 m_currenteState++;
2669 if (m_currenteState >= 0 &&
2670 static_cast<size_t>(m_currenteState) < m_elementListState.size() &&
2671 static_cast<size_t>(m_currenteState) < m_textListState.size()) {
2672 //m_elementList = m_elementListState[m_currenteState];
2673 //m_textList = m_textListState[m_currenteState];
2674 GetStateListsCopy(m_elementListState[m_currenteState], m_textListState[m_currenteState], m_elementList, m_textList);
2675
2676#ifdef _DEBUG
2677#ifdef SHOW_DEBUG_PANEL
2678 wxString msg = "";
2679 wxString pointerStr;
2680 pointerStr.Printf("[%d N curr s%d] ", m_currenteState, m_elementListState.size());
2681 msg += pointerStr;
2682 for (Element* element : m_elementList) {
2683 pointerStr.Printf("%p ", element);
2684 msg += pointerStr;
2685 }
2686 msg += "\n";
2687 //m_debugFrame->AppendDebugMessage(msg);
2688#endif
2689#endif
2690
2691 UpdateTextElements();
2692 Redraw();
2693 }
2694 else {
2695 m_currenteState--;
2696 }
2697}

◆ SetPreviousState()

void Workspace::SetPreviousState ( )

Definition at line 2699 of file Workspace.cpp.

2700{
2701 m_currenteState--;
2702 if (m_currenteState >= 0) {
2703 //m_elementList = m_elementListState[m_currenteState];
2704 //m_textList = m_textListState[m_currenteState];
2705 GetStateListsCopy(m_elementListState[m_currenteState], m_textListState[m_currenteState], m_elementList, m_textList);
2706
2707#ifdef _DEBUG
2708#ifdef SHOW_DEBUG_PANEL
2709 wxString msg = "";
2710 wxString pointerStr;
2711 pointerStr.Printf("[%d P curr s%d] ", m_currenteState, m_elementListState.size());
2712 msg += pointerStr;
2713 for (Element* element : m_elementListState[m_currenteState]) {
2714 pointerStr.Printf("%p ", element);
2715 msg += pointerStr;
2716 }
2717 msg += "\n";
2718 pointerStr.Printf("[%d P list s%d] ", m_currenteState, m_elementListState.size());
2719 msg += pointerStr;
2720 for (Element* element : m_elementList) {
2721 pointerStr.Printf("%p ", element);
2722 msg += pointerStr;
2723 }
2724 msg += "\n";
2725 //m_debugFrame->AppendDebugMessage(msg);
2726#endif
2727#endif
2728
2729 UpdateTextElements();
2730 Redraw();
2731 }
2732 else {
2733 m_currenteState++;
2734 }
2735}

◆ SetSavedPath()

void Workspace::SetSavedPath ( wxFileName  savedPath)
inline

Definition at line 149 of file Workspace.h.

149{ m_savedPath = savedPath; }

◆ SetStatusBarText()

void Workspace::SetStatusBarText ( wxString  text)
inline

Definition at line 147 of file Workspace.h.

147{ m_statusBar->SetStatusText(text); }

◆ SetTextList()

void Workspace::SetTextList ( const std::vector< std::shared_ptr< Text > > &  textList)

Definition at line 2793 of file Workspace.cpp.

2794{
2795 //m_textList.clear();
2796 //for (auto it = textList.begin(), itEnd = textList.end(); it != itEnd; ++it) m_textList.push_back(*it);
2797 m_textList = std::move(textList);
2798
2799 UpdateTextElements();
2800}

◆ SetWorkspaceMode()

void Workspace::SetWorkspaceMode ( WorkspaceMode  mode)
inline

Definition at line 148 of file Workspace.h.

148{ m_mode = mode; }

◆ SnapToGrid()

wxPoint2DDouble Workspace::SnapToGrid ( const wxPoint2DDouble &  pt) const

Definition at line 288 of file Workspace.cpp.

289{
290 if (!m_showGrid || m_gridSize <= 0.0) return pt;
291 return wxPoint2DDouble(
292 std::round(pt.m_x / m_gridSize) * m_gridSize,
293 std::round(pt.m_y / m_gridSize) * m_gridSize
294 );
295}

◆ UnselectAll()

void Workspace::UnselectAll ( )

Definition at line 2737 of file Workspace.cpp.

2738{
2739 for (auto& element : m_elementList) {
2740 element->SetSelected(false);
2741 }
2742 for (auto& text : m_textList) {
2743 text->SetSelected(false);
2744 }
2745 Redraw();
2746}

◆ UpdateElementsID()

void Workspace::UpdateElementsID ( )

Definition at line 2757 of file Workspace.cpp.

2758{
2759 int id = 0;
2760 for (auto& element : m_elementList) {
2761 element->SetID(id);
2762 id++;
2763 }
2764 for (auto& text : m_textList) {
2765 text->SetID(id);
2766 id++;
2767 }
2768}

◆ UpdateHeatMap()

void Workspace::UpdateHeatMap ( )

Definition at line 1589 of file Workspace.cpp.

1590{
1591 if (m_hmPlane && m_showHM) {
1592 m_hmPlane->Clear();
1593
1594 wxRect2DDouble screenRect(-100, -100, m_width + 200.0, m_height + 200.0);
1595
1596 // Get new voltage range
1597 std::vector<Bus*> busList;
1598 float minVoltage, maxVoltage;
1599 if (m_hmAutomaticLabel) {
1600 minVoltage = 10.0f;
1601 maxVoltage = 0.0f;
1602 }
1603 else {
1604 minVoltage = m_hmPlane->GetMinLimit();
1605 maxVoltage = m_hmPlane->GetMaxLimit();
1606 }
1607
1608 for (auto& element : m_elementList) {
1609 if (Bus* bus = dynamic_cast<Bus*>(element.get())) {
1610 if (m_hmAutomaticLabel) {
1611 const float voltage = std::abs(bus->GetElectricalData().voltage);
1612 if (minVoltage > voltage) minVoltage = voltage;
1613 if (maxVoltage < voltage) maxVoltage = voltage;
1614 }
1615 busList.push_back(bus);
1616 }
1617 }
1618 if (m_hmAutomaticLabel) {
1619 m_hmPlane->SetLabelLimits(minVoltage, maxVoltage);
1620 }
1621
1622 for (Bus* bus : busList) {
1623 const float voltage = std::abs(bus->GetElectricalData().voltage);
1624 float depth = 2.0f * (voltage - (maxVoltage + minVoltage) / 2.0f) / (maxVoltage - minVoltage);
1625 if (depth < -1.0) depth = -1.0;
1626 if (depth > 1.0) depth = 1.0;
1627
1628 wxRect2DDouble rect = bus->GetRect();
1629 rect = wxRect2DDouble(
1630 (rect.m_x - 100.0f) * m_camera->GetScale() + m_camera->GetTranslation().m_x * m_camera->GetScale(),
1631 (rect.m_y - 50.0f) * m_camera->GetScale() + m_camera->GetTranslation().m_y * m_camera->GetScale(),
1632 (rect.m_width + 200.0f) * m_camera->GetScale(),
1633 (rect.m_height + 100.0f) * m_camera->GetScale());
1634
1635 if (screenRect.Contains(rect))
1636 m_hmPlane->SetRectSlope(rect, M_PI * static_cast<float>(bus->GetAngle()) / 180.0f, depth);
1637 }
1638
1639 //m_hmPlane->UpdateCoords();
1640
1641 //int iterations = std::lround(3.3 * std::pow(m_camera->GetScale(), 0.62));
1642 int iterations = std::lround(10 * std::pow(m_camera->GetScale(), 2));
1643 //int iterations = std::lround(1 * std::pow(m_camera->GetScale(), 0.2));
1644 //int iterations = 1;
1645 if (iterations < 1) iterations = 1;
1646 m_hmPlane->SmoothPlane(iterations);
1647 }
1648}

◆ UpdateStatusBar()

void Workspace::UpdateStatusBar ( )
protected

Definition at line 1473 of file Workspace.cpp.

1474{
1475 switch (m_mode) {
1476 case WorkspaceMode::MODE_DRAG: {
1477 m_statusBar->SetStatusText(_("MODE: DRAG"), 1);
1478 } break;
1479
1480 case WorkspaceMode::MODE_PASTE:
1481 case WorkspaceMode::MODE_DRAG_PASTE: {
1482 m_statusBar->SetStatusText(_("MODE: PASTE"), 1);
1483 } break;
1484
1485 case WorkspaceMode::MODE_INSERT:
1486 case WorkspaceMode::MODE_INSERT_TEXT:
1487 case WorkspaceMode::MODE_DRAG_INSERT:
1488 case WorkspaceMode::MODE_DRAG_INSERT_TEXT: {
1489 m_statusBar->SetStatusText(_("MODE: INSERT"), 1);
1490 } break;
1491
1492 case WorkspaceMode::MODE_MOVE_ELEMENT:
1493 case WorkspaceMode::MODE_MOVE_PICKBOX:
1494 case WorkspaceMode::MODE_MOVE_NODE:
1495 case WorkspaceMode::MODE_SELECTION_RECT:
1496 case WorkspaceMode::MODE_EDIT: {
1497 if (m_oldStatusMode != m_mode)
1498 m_statusBar->SetStatusText(wxT(""));
1499 m_statusBar->SetStatusText(_("MODE: EDIT"), 1);
1500 } break;
1501 }
1502
1503 m_statusBar->SetStatusText(wxString::Format(_("ZOOM: %d%%"), (int)(m_camera->GetScale() * 100.0)), 2);
1504 m_statusBar->SetStatusText(
1505 wxString::Format(wxT("X: %.1f Y: %.1f"), m_camera->GetMousePosition().m_x, m_camera->GetMousePosition().m_y),
1506 3);
1507 m_oldStatusMode = m_mode;
1508}

◆ UpdateTextElements()

bool Workspace::UpdateTextElements ( )

Definition at line 2408 of file Workspace.cpp.

2409{
2410 bool isTexturesOK = true;
2411 double basePower = m_properties->GetSimulationPropertiesData().basePower;
2412 if (m_properties->GetSimulationPropertiesData().basePowerUnit == ElectricalUnit::UNIT_kVA)
2413 basePower *= 1e3;
2414 else if (m_properties->GetSimulationPropertiesData().basePowerUnit == ElectricalUnit::UNIT_MVA)
2415 basePower *= 1e6;
2416 for (auto& text : m_textList) {
2417 text->SetFontName(m_properties->GetGeneralPropertiesData().labelFont);
2418 text->SetFontSize(m_properties->GetGeneralPropertiesData().labelFontSize);
2419 text->UpdateText(basePower);
2420 //if (!text->IsGLTextOK()) isTexturesOK = false;
2421 }
2422 return isTexturesOK;
2423}

◆ ValidateBusesVoltages()

void Workspace::ValidateBusesVoltages ( Element initialBus)

Definition at line 2263 of file Workspace.cpp.

2264{
2265 double nominalVoltage = static_cast<Bus*>(initialBus)->GetElectricalData().nominalVoltage;
2266 ElectricalUnit nominalVoltageUnit = static_cast<Bus*>(initialBus)->GetElectricalData().nominalVoltageUnit;
2267
2268 for (auto it = m_elementList.begin(); it != m_elementList.end(); it++) {
2269 Element* child = it->get();
2270
2271 if (auto line = dynamic_cast<Line*>(child)) {
2272 if (line->GetParentList()[0] && line->GetParentList()[1]) {
2273 BusElectricalData data1 = static_cast<Bus*>(line->GetParentList()[0])->GetElectricalData();
2274 BusElectricalData data2 = static_cast<Bus*>(line->GetParentList()[1])->GetElectricalData();
2275
2276 if (data1.nominalVoltage != data2.nominalVoltage ||
2277 data1.nominalVoltageUnit != data2.nominalVoltageUnit) {
2278 data1.nominalVoltage = nominalVoltage;
2279 data2.nominalVoltage = nominalVoltage;
2280 data1.nominalVoltageUnit = nominalVoltageUnit;
2281 data2.nominalVoltageUnit = nominalVoltageUnit;
2282
2283 static_cast<Bus*>(line->GetParentList()[0])->SetElectricalData(data1);
2284 static_cast<Bus*>(line->GetParentList()[1])->SetElectricalData(data2);
2285
2286 it = m_elementList.begin(); // Restart search.
2287 }
2288 }
2289 }
2290 }
2291
2292 // ValidateElementsVoltages();
2293}

◆ ValidateElementsVoltages()

void Workspace::ValidateElementsVoltages ( )

Definition at line 2295 of file Workspace.cpp.

2296{
2297 for (auto& child : m_elementList) {
2298 std::vector<double> nominalVoltage;
2299 std::vector<ElectricalUnit> nominalVoltageUnit;
2300 for (int i = 0; i < (int)child->GetParentList().size(); i++) {
2301 Bus* parent = static_cast<Bus*>(child->GetParentList()[i]);
2302 if (parent) {
2303 nominalVoltage.push_back(parent->GetElectricalData().nominalVoltage);
2304 nominalVoltageUnit.push_back(parent->GetElectricalData().nominalVoltageUnit);
2305 }
2306 }
2307 child->SetNominalVoltage(nominalVoltage, nominalVoltageUnit);
2308 }
2309}
virtual void SetNominalVoltage(std::vector< double > nominalVoltage, std::vector< ElectricalUnit > nominalVoltageUnit)
Set nominal voltage of the element.

Member Data Documentation

◆ m_auiNotebook

wxAuiNotebook* Workspace::m_auiNotebook = nullptr
protected

Definition at line 238 of file Workspace.h.

◆ m_camera

Camera* Workspace::m_camera = nullptr
protected

Definition at line 239 of file Workspace.h.

◆ m_CEMngr

std::unique_ptr<ControlEditorManager> Workspace::m_CEMngr
protected

Definition at line 287 of file Workspace.h.

◆ m_continuousCalc

bool Workspace::m_continuousCalc = false
protected

Definition at line 269 of file Workspace.h.

◆ m_currenteState

int Workspace::m_currenteState = -1
protected

Definition at line 257 of file Workspace.h.

◆ m_CWMngr

std::unique_ptr<ChartWindowManager> Workspace::m_CWMngr
protected

Definition at line 288 of file Workspace.h.

◆ m_disconnectedElement

bool Workspace::m_disconnectedElement = false
protected

Definition at line 270 of file Workspace.h.

◆ m_elementList

std::vector< std::shared_ptr<PowerElement> > Workspace::m_elementList
protected

Definition at line 247 of file Workspace.h.

◆ m_elementListState

std::vector< std::vector< std::shared_ptr<PowerElement> > > Workspace::m_elementListState
protected

Definition at line 254 of file Workspace.h.

◆ m_elementNumber

int Workspace::m_elementNumber[NUM_ELEMENTS]
protected

Definition at line 248 of file Workspace.h.

◆ m_gridSize

double Workspace::m_gridSize = 20.0
protected

Definition at line 285 of file Workspace.h.

◆ m_height

float Workspace::m_height = 0.0
protected

Definition at line 274 of file Workspace.h.

◆ m_hmAutomaticLabel

bool Workspace::m_hmAutomaticLabel = false
protected

Definition at line 283 of file Workspace.h.

◆ m_hmPlane

HMPlane* Workspace::m_hmPlane = nullptr
protected

Definition at line 277 of file Workspace.h.

◆ m_justOpened

bool Workspace::m_justOpened = false
protected

Definition at line 271 of file Workspace.h.

◆ m_maxStates

int Workspace::m_maxStates = 100
protected

Definition at line 258 of file Workspace.h.

◆ m_mode

WorkspaceMode Workspace::m_mode = WorkspaceMode::MODE_EDIT
protected

Definition at line 243 of file Workspace.h.

◆ m_name

wxString Workspace::m_name
protected

Definition at line 241 of file Workspace.h.

◆ m_oldStatusMode

WorkspaceMode Workspace::m_oldStatusMode = WorkspaceMode::MODE_EDIT
protected

Definition at line 244 of file Workspace.h.

◆ m_properties

PropertiesData* Workspace::m_properties = nullptr
protected

Definition at line 265 of file Workspace.h.

◆ m_savedPath

wxFileName Workspace::m_savedPath
protected

Definition at line 260 of file Workspace.h.

◆ m_selectionRect

wxRect2DDouble Workspace::m_selectionRect
protected

Definition at line 262 of file Workspace.h.

◆ m_showGrid

bool Workspace::m_showGrid = false
protected

Definition at line 284 of file Workspace.h.

◆ m_showHM

bool Workspace::m_showHM = false
protected

Definition at line 281 of file Workspace.h.

◆ m_showHMTimer

bool Workspace::m_showHMTimer = false
protected

Definition at line 282 of file Workspace.h.

◆ m_stabilityTimeVector

std::vector<double> Workspace::m_stabilityTimeVector
protected

Definition at line 267 of file Workspace.h.

◆ m_startSelRect

wxPoint2DDouble Workspace::m_startSelRect
protected

Definition at line 263 of file Workspace.h.

◆ m_statusBar

wxStatusBar* Workspace::m_statusBar = nullptr
protected

Definition at line 237 of file Workspace.h.

◆ m_textList

std::vector< std::shared_ptr<Text> > Workspace::m_textList
protected

Definition at line 251 of file Workspace.h.

◆ m_textListState

std::vector< std::vector< std::shared_ptr<Text> > > Workspace::m_textListState
protected

Definition at line 256 of file Workspace.h.

◆ m_tipWindow

wxTipWindow::Ref Workspace::m_tipWindow
protected

Definition at line 240 of file Workspace.h.

◆ m_width

float Workspace::m_width = 0.0
protected

Definition at line 273 of file Workspace.h.


The documentation for this class was generated from the following files: