Power System Platform  2026w11a-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)
 
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
 
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)
 

Protected Attributes

wxStatusBar * m_statusBar = nullptr
 
wxAuiNotebook * m_auiNotebook = nullptr
 
Cameram_camera = nullptr
 
wxTipWindow * m_tipWindow = nullptr
 
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
 

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 102 of file Workspace.h.

Member Enumeration Documentation

◆ WorkspaceMode

enum class Workspace::WorkspaceMode : int
strong

Definition at line 105 of file Workspace.h.

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

Constructor & Destructor Documentation

◆ Workspace() [1/2]

Workspace::Workspace ( )

Definition at line 58 of file Workspace.cpp.

58 : WorkspaceBase(nullptr)
59{
60#ifdef _DEBUG
61#ifdef SHOW_DEBUG_PANEL
62 m_debugFrame = new DebugMainFrame(this);
63 m_debugFrame->SetTitle(_("Debug window: ") + m_name);
64 m_debugFrame->Show();
65 //m_debugFrame->SetSize(m_debugFrame->GetBestVirtualSize());
66#endif
67#endif
68 SetBackgroundColour(wxColour(255, 255, 255));
69 SetBackgroundStyle(wxBG_STYLE_PAINT); // To allow wxBufferedPaintDC works properly.
70}

◆ Workspace() [2/2]

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

Definition at line 72 of file Workspace.cpp.

73 : WorkspaceBase(parent)
74{
75#ifdef _DEBUG
76#ifdef SHOW_DEBUG_PANEL
77 m_debugFrame = new DebugMainFrame(this);
78 m_debugFrame->SetTitle(_("Debug window: ") + m_name);
79 m_debugFrame->Show();
80 //m_debugFrame->SetSize(m_debugFrame->GetBestVirtualSize());
81#endif
82#endif
83
84 m_timer->Start();
85 m_name = name;
86 m_statusBar = statusBar;
87 m_auiNotebook = auiNotebook;
88 //m_glContext = new wxGLContext(m_glCanvas, sharedGLContext);
89 m_camera = new Camera();
90 m_selectionRect = wxRect2DDouble(0, 0, 0, 0);
91
92 for (int i = 0; i < NUM_ELEMENTS; ++i) { m_elementNumber[i] = 1; }
93
94 const int widths[4] = { -3, -1, 100, 100 };
95 m_statusBar->SetStatusWidths(4, widths);
96
97 m_properties = new PropertiesData();
98
99 //m_glCanvas->SetBackgroundStyle(wxBG_STYLE_CUSTOM);
100 m_workspacePanel->SetBackgroundColour(wxColour(255, 255, 255));
101 m_workspacePanel->SetBackgroundStyle(wxBG_STYLE_PAINT); // To allow wxBufferedPaintDC works properly.
102
103 //m_width = static_cast<float>(m_glCanvas->GetSize().x) - 1.0;
104 //m_height = static_cast<float>(m_glCanvas->GetSize().y) - 1.0;
105 m_width = static_cast<float>(m_workspacePanel->GetSize().x) - 1.0;
106 m_height = static_cast<float>(m_workspacePanel->GetSize().y) - 1.0;
107 //m_renderer = new Renderer();
108
109 SaveCurrentState();
110}
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 112 of file Workspace.cpp.

113{
114 //for (auto it = m_elementList.begin(), itEnd = m_elementList.end(); it != itEnd; ++it) {
115 // if (*it) delete* it;
116 //}
117 //for (auto it = m_textList.begin(), itEnd = m_textList.end(); it != itEnd; ++it) {
118 // if (*it) delete* it;
119 //}
120
121 if (m_hmPlane) delete m_hmPlane;
122
123 if (m_camera) delete m_camera;
124 //if (m_isThisContextShared) {
125 //delete m_glContext;
126 //m_glContext = nullptr;
127 //}
128 if (m_tipWindow) delete m_tipWindow;
129 if (m_properties) delete m_properties;
130}

Member Function Documentation

◆ CheckSlackBusDuplication()

void Workspace::CheckSlackBusDuplication ( Element newSlackBus)

Definition at line 1897 of file Workspace.cpp.

1898{
1899 Bus* newBus = dynamic_cast<Bus*>(newSlackBus);
1900 if (newBus) {
1901 if (!newBus->GetElectricalData().slackBus) return; // If the new bus is not set as slack bus, no need to check for duplication.
1902
1903 for (auto& element : m_elementList) {
1904 Bus* bus = dynamic_cast<Bus*>(element.get());
1905 if (!bus) continue;
1906 if (bus->GetElectricalData().slackBus && bus != newSlackBus) {
1907 wxMessageDialog msgDialog(this,
1908 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),
1909 _("Warning"), wxYES_NO | wxCENTRE | wxICON_WARNING);
1910 if (msgDialog.ShowModal() == wxID_YES) {
1911 auto data = bus->GetElectricalData();
1912 data.slackBus = false;
1913 bus->SetElectricalData(data);
1914 return;
1915 }
1916 else {
1917 auto data = newBus->GetElectricalData();
1918 data.slackBus = false;
1919 newBus->SetElectricalData(data);
1920 return;
1921 }
1922 }
1923 }
1924 }
1925}
Node for power elements. All others power elements are connected through this.
Definition Bus.h:86

◆ CopySelection()

void Workspace::CopySelection ( )

Definition at line 2089 of file Workspace.cpp.

2090{
2091 UpdateElementsID();
2092 std::vector<Element*> selectedElements;
2093 // The buses need to be numerated to associate the child's parents to the copies.
2094 int busNumber = 0;
2095 for (auto& element : m_elementList) {
2096 if (auto bus = dynamic_cast<Bus*>(element.get())) {
2097 auto data = bus->GetElectricalData();
2098 data.number = busNumber;
2099 bus->SetElectricalData(data);
2100 busNumber++;
2101 }
2102 if (element->IsSelected()) { selectedElements.push_back(element.get()); }
2103 }
2104 for (auto& text : m_textList) {
2105 if (text->IsSelected()) { selectedElements.push_back(text.get()); }
2106 }
2107 ElementDataObject* dataObject = new ElementDataObject(selectedElements);
2108 if (wxTheClipboard->Open()) {
2109 wxTheClipboard->SetData(dataObject);
2110 wxTheClipboard->Close();
2111 }
2112}
Class to store the elements in the clipboard.

◆ CopyToClipboard()

void Workspace::CopyToClipboard ( )

Definition at line 219 of file Workspace.cpp.

220{
221 wxSize size = GetClientSize();
222
223 int scale = 2;
224
225 wxBitmap bitmap(size.x * scale, size.y * scale);
226 wxMemoryDC memDC(bitmap);
227
228 memDC.SetBackground(*wxWHITE_BRUSH);
229 memDC.Clear();
230
231 wxGraphicsContext* gc = wxGraphicsContext::Create(memDC);
232 if (!gc) return;
233 gc->Scale(scale, scale); // Increase the scale to improve the quality of the copied image.
234
235 DrawScene(gc);
236 delete gc;
237
238 memDC.SelectObject(wxNullBitmap);
239
240 if (wxTheClipboard->Open())
241 {
242 wxTheClipboard->SetData(new wxBitmapDataObject(bitmap));
243 wxTheClipboard->Close();
244 }
245}

◆ DeleteSelectedElements()

void Workspace::DeleteSelectedElements ( )

Definition at line 1505 of file Workspace.cpp.

1506{
1507 // Don't set the end of the list at the loop's begin.
1508 for (auto it = m_elementList.begin(); it != m_elementList.end();) {
1509 Element* element = it->get();
1510
1511 if (element->IsSelected()) {
1512 // Remove child/parent.
1513 std::vector<Element*> childList = element->GetChildList();
1514 for (auto itc = childList.begin(), itEnd = childList.end(); itc != itEnd; ++itc) {
1515 Element* child = *itc;
1516 if (child) {
1517 child->RemoveParent(element);
1518 element->RemoveChild(child);
1519 }
1520 }
1521 std::vector<Element*> parentList = element->GetParentList();
1522 for (auto itp = parentList.begin(), itEnd = parentList.end(); itp != itEnd; ++itp) {
1523 Element* parent = *itp;
1524 if (parent) { parent->RemoveChild(element); }
1525 }
1526
1527 //for (auto& text : m_textList) {
1528 // if (text->GetElement() == element) {
1529 // if (m_textList.size() == 1) {
1530 // m_textList.erase(itt);
1531 // break;
1532 // }
1533 // else m_textList.erase(itt--);
1534 // if (text) delete text;
1535 // }
1536 //}
1537 std::erase_if(m_textList, [&](const auto& text) {
1538 return text->GetElement() == element;
1539 });
1540
1541 it = m_elementList.erase(it);
1542 //if (element) delete element;
1543 }
1544 else it++;
1545 }
1546
1547 //for (auto it = m_textList.begin(); it != m_textList.end(); ++it) {
1548 // Text* text = *it;
1549 // if (text->IsSelected()) {
1550 // if (m_textList.size() == 1) {
1551 // m_textList.erase(it);
1552 // break;
1553 // }
1554 // else m_textList.erase(it--);
1555 // if (text) delete text;
1556 // }
1557 //}
1558 std::erase_if(m_textList, [](const auto& text) {
1559 return text->IsSelected();
1560 });
1561
1562 if (m_hmPlane && m_showHM) {
1563 m_hmPlane->Clear();
1564 m_showHMTimer = true;
1565 m_timerHeatMap->Start();
1566 }
1567 SaveCurrentState();
1568 Redraw();
1569}
Base class of all elements of the program. This class is responsible for manage graphical and his dat...
Definition Element.h:112
virtual std::vector< Element * > GetParentList() const
Get the parent list.
Definition Element.h:559
virtual std::vector< Element * > GetChildList() const
Get the Child list.
Definition Element.h:564
virtual void RemoveChild(Element *child)
Remove a child from the list.
Definition Element.cpp:495
virtual void RemoveParent(Element *parent)
Remove a parent.
Definition Element.h:371
bool IsSelected() const
Checks if the element is selected.
Definition Element.h:201

◆ DrawScene() [1/2]

void Workspace::DrawScene ( wxDC &  dc)
protected

Definition at line 186 of file Workspace.cpp.

187{
188 // HMPlane
189 if (m_hmPlane && m_showHM) {
190 m_hmPlane->DrawDC(dc);
191 }
192
193 dc.SetUserScale(m_camera->GetScale(), m_camera->GetScale());
194 dc.SetDeviceOrigin(m_camera->GetTranslation().m_x * m_camera->GetScale(), m_camera->GetTranslation().m_y * m_camera->GetScale());
195 //dc.SetLogicalOrigin(-m_camera->GetTranslation().m_x, -m_camera->GetTranslation().m_y);
196
197 // Elements
198 for (auto& element : m_elementList) {
199 element->DrawDC(m_camera->GetTranslation(), m_camera->GetScale(), dc);
200 }
201
202 // Dummy Text to set correct context
203 // TODO: Find a better way to do this.
204 Text* text = new Text(wxPoint2DDouble(0.0, 0.0), m_properties->GetGeneralPropertiesData().labelFont, m_properties->GetGeneralPropertiesData().labelFontSize);
205 text->SetText("");
206 text->DrawDC(m_camera->GetTranslation(), m_camera->GetScale(), dc);
207 delete text;
208
209 // Texts
210 for (auto& text : m_textList) {
211 text->DrawDC(m_camera->GetTranslation(), m_camera->GetScale(), dc);
212 }
213
214 if (m_hmPlane && m_showHM) {
215 m_hmPlane->DrawLabelDC(dc);
216 }
217}
Element that shows power element informations in workspace.
Definition Text.h:70

◆ DrawScene() [2/2]

void Workspace::DrawScene ( wxGraphicsContext *  gc)
protected

Definition at line 145 of file Workspace.cpp.

146{
147 // Draw
148 if (gc) {
149
150 // HMPlane
151 if (m_hmPlane && m_showHM) {
152 m_hmPlane->DrawDC(gc);
153 }
154
155 gc->Scale(m_camera->GetScale(), m_camera->GetScale());
156 gc->Translate(m_camera->GetTranslation().m_x, m_camera->GetTranslation().m_y);
157
158 // Elements
159 for (auto& element : m_elementList) {
160 element->DrawDC(m_camera->GetTranslation(), m_camera->GetScale(), gc);
161 }
162
163 // Dummy Text to set correct context
164 // TODO: Find a better way to do this.
165 Text* text = new Text(wxPoint2DDouble(0.0, 0.0), m_properties->GetGeneralPropertiesData().labelFont, m_properties->GetGeneralPropertiesData().labelFontSize);
166 text->SetText("");
167 text->DrawDC(m_camera->GetTranslation(), m_camera->GetScale(), gc);
168 delete text;
169
170 // Texts
171 for (auto& text : m_textList) {
172 text->DrawDC(m_camera->GetTranslation(), m_camera->GetScale(), gc);
173 }
174
175 // Selection rectangle
176 gc->SetPen(wxPen(wxColour(0, 125, 255, 255)));
177 gc->SetBrush(wxBrush(wxColour(0, 125, 255, 125)));
178 gc->DrawRectangle(m_selectionRect.m_x, m_selectionRect.m_y, m_selectionRect.m_width, m_selectionRect.m_height);
179
180 if (m_hmPlane && m_showHM) {
181 m_hmPlane->DrawLabelDC(gc);
182 }
183 }
184}

◆ EnableAutoHeatMapLabel()

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

Definition at line 161 of file Workspace.h.

161{ m_hmAutomaticLabel = enable; }

◆ EnableHeatMap()

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

Definition at line 2397 of file Workspace.cpp.

2398{
2399 m_showHM = enable;
2400 if (m_showHM) {
2401 UpdateHeatMap();
2402 }
2403 Redraw();
2404}

◆ ExportAsSVG()

void Workspace::ExportAsSVG ( wxString  path)

Definition at line 247 of file Workspace.cpp.

248{
249 wxSize size = GetClientSize();
250
251 wxSVGFileDC svgDC(path, size.x, size.y);
252
253 svgDC.SetClippingRegion(wxRect(0, 0, size.x, size.y));
254
255 DrawScene(svgDC);
256}

◆ FindTextElement()

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

Definition at line 1879 of file Workspace.cpp.

1880{
1881 for (auto& text : m_textList) {
1882 if (text->GetElement() == parentElement && text->GetDataType() == dataType)
1883 return text.get();
1884 }
1885 return nullptr;
1886}

◆ Fit()

void Workspace::Fit ( )

Definition at line 1592 of file Workspace.cpp.

1593{
1594 wxPoint2DDouble leftUpCorner(0, 0);
1595 wxPoint2DDouble rightDownCorner(0, 0);
1596 std::vector<Element*> elementList = GetElementList();
1597 for (const auto& text : m_textList) { elementList.push_back(text.get()); }
1598
1599 if (!GetElementsCorners(leftUpCorner, rightDownCorner, elementList)) return;
1600 wxPoint2DDouble middleCoords = (leftUpCorner + rightDownCorner) / 2.0;
1601
1602 int width = 0.0;
1603 int height = 0.0;
1604 GetSize(&width, &height);
1605
1606 double scaleX = double(width) / (rightDownCorner.m_x - leftUpCorner.m_x);
1607 double scaleY = double(height) / (rightDownCorner.m_y - leftUpCorner.m_y);
1608
1609 double scale = scaleX < scaleY ? scaleX : scaleY;
1610 if (scale > m_camera->GetZoomMax()) scale = m_camera->GetZoomMax();
1611 if (scale < m_camera->GetZoomMin()) scale = m_camera->GetZoomMin();
1612
1613 m_camera->SetScale(scale);
1614
1615 m_camera->StartTranslation(middleCoords);
1616 m_camera->SetTranslation(wxPoint2DDouble(width / 2, height / 2));
1617
1618 if (m_hmPlane && m_showHM) {
1619 UpdateHeatMap();
1620 }
1621
1622 Redraw();
1623}

◆ GetAllElements()

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

Definition at line 2502 of file Workspace.cpp.

2503{
2504 std::vector<Element*> allElements;
2505
2506 for (auto& element : m_elementList) allElements.push_back(element.get());
2507 for (auto& text : m_textList) allElements.push_back(text.get());
2508
2509 return allElements;
2510}

◆ GetCamera()

Camera * Workspace::GetCamera ( ) const
inline

Definition at line 130 of file Workspace.h.

130{ return m_camera; }

◆ GetElementList()

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

Definition at line 2534 of file Workspace.cpp.

2535{
2536 std::vector<Element*> elementList;
2537 for (auto& element : m_elementList) elementList.push_back(element.get());
2538 return elementList;
2539}

◆ GetElementNumber()

int Workspace::GetElementNumber ( ElementID  elementID)
inline

Definition at line 175 of file Workspace.h.

175{ return m_elementNumber[elementID]; }

◆ GetElementNumberFromList()

int Workspace::GetElementNumberFromList ( Element element)
protected

Definition at line 1204 of file Workspace.cpp.

1205{
1206 int elementNum = 0;
1207 for (auto& elementFromList : m_elementList) {
1208 if (element->GetElementType() == elementFromList->GetElementType()) {
1209 if (element == elementFromList.get()) return elementNum;
1210 elementNum++;
1211 }
1212 }
1213 return 0;
1214}

◆ GetElementsCorners()

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

Definition at line 1571 of file Workspace.cpp.

1574{
1575 if (elementList.size() == 0) return false;
1576
1577 elementList[0]->CalculateBoundaries(leftUpCorner, rightDownCorner);
1578
1579 for (auto it = elementList.begin() + 1, itEnd = elementList.end(); it != itEnd; it++) {
1580 Element* element = *it;
1581 wxPoint2DDouble leftUp;
1582 wxPoint2DDouble rightDown;
1583 element->CalculateBoundaries(leftUp, rightDown);
1584 if (leftUp.m_x < leftUpCorner.m_x) leftUpCorner.m_x = leftUp.m_x;
1585 if (leftUp.m_y < leftUpCorner.m_y) leftUpCorner.m_y = leftUp.m_y;
1586 if (rightDown.m_x > rightDownCorner.m_x) rightDownCorner.m_x = rightDown.m_x;
1587 if (rightDown.m_y > rightDownCorner.m_y) rightDownCorner.m_y = rightDown.m_y;
1588 }
1589 return true;
1590}
virtual void CalculateBoundaries(wxPoint2DDouble &leftUp, wxPoint2DDouble &rightBottom) const
Calculate the element boundaries.
Definition Element.cpp:406

◆ GetElementSharedList()

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

Definition at line 126 of file Workspace.h.

126{ return m_elementList; }

◆ GetHeatMap()

HMPlane * Workspace::GetHeatMap ( ) const
inline

Definition at line 160 of file Workspace.h.

160{ return m_hmPlane; }

◆ GetName()

wxString Workspace::GetName ( ) const
inline

Definition at line 124 of file Workspace.h.

124{ return m_name; }

◆ GetProperties()

PropertiesData * Workspace::GetProperties ( ) const
inline

Definition at line 177 of file Workspace.h.

177{ return m_properties; }

◆ GetSavedPath()

wxFileName Workspace::GetSavedPath ( ) const
inline

Definition at line 139 of file Workspace.h.

139{ return m_savedPath; }

◆ GetStabilityTimeVector()

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

Definition at line 178 of file Workspace.h.

178{ 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 1216 of file Workspace.cpp.

1220{
1221 // Free copy lists first
1222 //for (auto& element : elementsListCopy) delete element;
1223 //for (auto& text : textListCopy) delete text;
1224 elementsListCopy.clear();
1225 textListCopy.clear();
1226
1227 std::map<Element*, Element*> elementMap;
1228
1229 for (auto& element : elementsList) {
1230 PowerElement* copyElement = static_cast<PowerElement*>(element->GetCopy());
1231 elementsListCopy.emplace_back(copyElement);
1232 elementMap[element.get()] = copyElement;
1233 }
1234 // Correct the parent and child pointers
1235 for (auto& copyElement : elementsListCopy) {
1236 // Parent
1237 int i = 0;
1238 for (Element* parent : copyElement->GetParentList()) {
1239 auto it = elementMap.find(parent);
1240
1241 if (it != elementMap.end())
1242 copyElement->SetParent(it->second, i);
1243
1244 i++;
1245 }
1246 // Child
1247 i = 0;
1248 for (Element* child : copyElement->GetChildList()) {
1249 auto it = elementMap.find(child);
1250
1251 if (it != elementMap.end())
1252 copyElement->SetChild(it->second, i);
1253
1254 i++;
1255 }
1256 }
1257
1258 for (const auto& text : textList) {
1259 auto copyText = static_cast<Text*>(text->GetCopy());
1260 // Set text the correct element associated with the text
1261 auto it = elementMap.find(copyText->GetElement());
1262
1263 if (it != elementMap.end())
1264 copyText->SetElement(it->second);
1265 else
1266 copyText->SetElement(nullptr);
1267 textListCopy.emplace_back(copyText);
1268 }
1269}
Abstract class of power elements.

◆ GetTextList()

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

Definition at line 127 of file Workspace.h.

127{ return m_textList; }

◆ GetWorkspaceMode()

WorkspaceMode Workspace::GetWorkspaceMode ( ) const
inline

Definition at line 129 of file Workspace.h.

129{ return m_mode; }

◆ IncrementElementNumber()

void Workspace::IncrementElementNumber ( ElementID  elementID)
inline

Definition at line 176 of file Workspace.h.

176{ m_elementNumber[elementID]++; }

◆ InsertTextElement()

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

Definition at line 1625 of file Workspace.cpp.

1626{
1627 switch (textID) {
1628 case ID_TXT_NAME: {
1629 if (FindTextElement(parentElement, DATA_NAME)) return false; // Avoid inserting more than one text element of the same type for an element.
1630 //Text* newText = new Text(parentElement->GetPosition() + wxPoint2DDouble(40, -30), m_properties->GetGeneralPropertiesData().labelFont, m_properties->GetGeneralPropertiesData().labelFontSize);
1631 auto newText = std::make_shared<Text>(parentElement->GetPosition() + wxPoint2DDouble(40, -30), m_properties->GetGeneralPropertiesData().labelFont, m_properties->GetGeneralPropertiesData().labelFontSize);
1632 newText->SetElement(parentElement);
1633 newText->SetDataType(DATA_NAME);
1634 newText->SetElementTypeText(parentElement->GetElementType());
1635 newText->SetElementNumber(GetElementNumberFromList(parentElement));
1636
1637 m_textList.push_back(newText);
1638 } break;
1639 case ID_TXT_VOLTAGE: {
1640 if (FindTextElement(parentElement, DATA_VOLTAGE)) return false;
1641 //Text* newText = new Text(parentElement->GetPosition() + wxPoint2DDouble(40, 15), m_properties->GetGeneralPropertiesData().labelFont, m_properties->GetGeneralPropertiesData().labelFontSize);
1642 auto newText = std::make_shared<Text>(parentElement->GetPosition() + wxPoint2DDouble(40, 15), m_properties->GetGeneralPropertiesData().labelFont, m_properties->GetGeneralPropertiesData().labelFontSize);
1643 newText->SetElement(parentElement);
1644 newText->SetDataType(DATA_VOLTAGE);
1645 if (unit == ElectricalUnit::UNIT_NONE)
1646 newText->SetUnit(ElectricalUnit::UNIT_PU);
1647 else
1648 newText->SetUnit(unit);
1649 newText->SetDecimalPlaces(precision);
1650 newText->SetElementTypeText(parentElement->GetElementType());
1651 newText->SetElementNumber(GetElementNumberFromList(parentElement));
1652
1653 m_textList.emplace_back(newText);
1654 } break;
1655 case ID_TXT_ANGLE: {
1656 if (FindTextElement(parentElement, DATA_ANGLE)) return false;
1657 //Text* newText = new Text(parentElement->GetPosition() + wxPoint2DDouble(40, 30), m_properties->GetGeneralPropertiesData().labelFont, m_properties->GetGeneralPropertiesData().labelFontSize);
1658 auto newText = std::make_shared<Text>(parentElement->GetPosition() + wxPoint2DDouble(40, 30), m_properties->GetGeneralPropertiesData().labelFont, m_properties->GetGeneralPropertiesData().labelFontSize);
1659 newText->SetElement(parentElement);
1660 newText->SetDataType(DATA_ANGLE);
1661 if (unit == ElectricalUnit::UNIT_NONE)
1662 newText->SetUnit(ElectricalUnit::UNIT_DEGREE);
1663 else
1664 newText->SetUnit(unit);
1665 newText->SetDecimalPlaces(precision);
1666 newText->SetElementTypeText(parentElement->GetElementType());
1667 newText->SetElementNumber(GetElementNumberFromList(parentElement));
1668
1669 m_textList.emplace_back(newText);
1670 } break;
1671 case ID_TXT_FAULTCURRENT: {
1672 if (FindTextElement(parentElement, DATA_SC_CURRENT)) return false;
1673 //Text* newText = new Text(parentElement->GetPosition() + wxPoint2DDouble(-70, 30), m_properties->GetGeneralPropertiesData().labelFont, m_properties->GetGeneralPropertiesData().labelFontSize);
1674 auto newText = std::make_shared<Text>(parentElement->GetPosition() + wxPoint2DDouble(-70, 30), m_properties->GetGeneralPropertiesData().labelFont, m_properties->GetGeneralPropertiesData().labelFontSize);
1675 newText->SetElement(parentElement);
1676 newText->SetDataType(DATA_SC_CURRENT);
1677 if (unit == ElectricalUnit::UNIT_NONE)
1678 newText->SetUnit(ElectricalUnit::UNIT_A);
1679 else
1680 newText->SetUnit(unit);
1681 newText->SetDecimalPlaces(precision);
1682 newText->SetElementTypeText(parentElement->GetElementType());
1683 newText->SetElementNumber(GetElementNumberFromList(parentElement));
1684
1685 m_textList.emplace_back(newText);
1686 } break;
1687 case ID_TXT_FAULTVOLTAGE: {
1688 if (FindTextElement(parentElement, DATA_SC_VOLTAGE)) return false;
1689 //Text* newText = new Text(parentElement->GetPosition() + wxPoint2DDouble(-70, 75), m_properties->GetGeneralPropertiesData().labelFont, m_properties->GetGeneralPropertiesData().labelFontSize);
1690 auto newText = std::make_shared<Text>(parentElement->GetPosition() + wxPoint2DDouble(-70, 75), m_properties->GetGeneralPropertiesData().labelFont, m_properties->GetGeneralPropertiesData().labelFontSize);
1691 newText->SetElement(parentElement);
1692 newText->SetDataType(DATA_SC_VOLTAGE);
1693 if (unit == ElectricalUnit::UNIT_NONE)
1694 newText->SetUnit(ElectricalUnit::UNIT_PU);
1695 else
1696 newText->SetUnit(unit);
1697 newText->SetDecimalPlaces(precision);
1698 newText->SetElementTypeText(parentElement->GetElementType());
1699 newText->SetElementNumber(GetElementNumberFromList(parentElement));
1700
1701 m_textList.emplace_back(newText);
1702 } break;
1703 case ID_TXT_SCC: {
1704 if (FindTextElement(parentElement, DATA_SC_POWER)) return false;
1705 auto newText = std::make_shared<Text>(parentElement->GetPosition() + wxPoint2DDouble(-50, -30), m_properties->GetGeneralPropertiesData().labelFont, m_properties->GetGeneralPropertiesData().labelFontSize);
1706 newText->SetElement(parentElement);
1707 newText->SetDataType(DATA_SC_POWER);
1708 newText->SetUnit(ElectricalUnit::UNIT_MVA);
1709 if (unit == ElectricalUnit::UNIT_NONE)
1710 newText->SetUnit(ElectricalUnit::UNIT_MVA);
1711 else
1712 newText->SetUnit(unit);
1713 newText->SetDecimalPlaces(precision);
1714 newText->SetElementTypeText(parentElement->GetElementType());
1715 newText->SetElementNumber(GetElementNumberFromList(parentElement));
1716
1717 m_textList.emplace_back(newText);
1718 } break;
1719 case ID_TXT_THD: {
1720 if (FindTextElement(parentElement, DATA_PQ_THD)) return false;
1721 auto newText = std::make_shared<Text>(parentElement->GetPosition() + wxPoint2DDouble(-50, -15), m_properties->GetGeneralPropertiesData().labelFont, m_properties->GetGeneralPropertiesData().labelFontSize);
1722 newText->SetElement(parentElement);
1723 newText->SetDataType(DATA_PQ_THD);
1724 newText->SetDecimalPlaces(precision);
1725 newText->SetElementTypeText(parentElement->GetElementType());
1726 newText->SetElementNumber(GetElementNumberFromList(parentElement));
1727
1728 m_textList.emplace_back(newText);
1729 } break;
1730 case ID_TXT_ACTIVE_POWER: {
1731 if (FindTextElement(parentElement, DATA_ACTIVE_POWER)) return false;
1732 auto newText = std::make_shared<Text>(parentElement->GetPosition() + wxPoint2DDouble(0, 35), m_properties->GetGeneralPropertiesData().labelFont, m_properties->GetGeneralPropertiesData().labelFontSize);
1733 newText->SetElement(parentElement);
1734 newText->SetDataType(DATA_ACTIVE_POWER);
1735 if (unit == ElectricalUnit::UNIT_NONE)
1736 newText->SetUnit(ElectricalUnit::UNIT_MW);
1737 else
1738 newText->SetUnit(unit);
1739 newText->SetDecimalPlaces(precision);
1740 newText->SetElementTypeText(parentElement->GetElementType());
1741 newText->SetElementNumber(GetElementNumberFromList(parentElement));
1742
1743 m_textList.emplace_back(newText);
1744 } break;
1745 case ID_TXT_REACTIVE_POWER: {
1746 if (FindTextElement(parentElement, DATA_REACTIVE_POWER)) return false;
1747 auto newText = std::make_shared<Text>(parentElement->GetPosition() + wxPoint2DDouble(0, 50), m_properties->GetGeneralPropertiesData().labelFont, m_properties->GetGeneralPropertiesData().labelFontSize);
1748 newText->SetElement(parentElement);
1749 newText->SetDataType(DATA_REACTIVE_POWER);
1750 if (unit == ElectricalUnit::UNIT_NONE)
1751 newText->SetUnit(ElectricalUnit::UNIT_Mvar);
1752 else
1753 newText->SetUnit(unit);
1754 newText->SetDecimalPlaces(precision);
1755 newText->SetElementTypeText(parentElement->GetElementType());
1756 newText->SetElementNumber(GetElementNumberFromList(parentElement));
1757
1758 m_textList.emplace_back(newText);
1759 } break;
1760 case ID_TXT_BRANCH_ACTIVE_POWER_1_2:
1761 case ID_TXT_BRANCH_ACTIVE_POWER_2_1: {
1762 if (FindTextElement(parentElement, DATA_PF_ACTIVE)) return false;
1763 wxPoint2DDouble position(0.0, -10.0);
1764 if (textID == ID_TXT_BRANCH_ACTIVE_POWER_1_2)
1765 position += 2.0 * parentElement->GetPointList()[1] - parentElement->GetPointList()[0];
1766 else
1767 position += 2.0 * parentElement->GetPointList()[parentElement->GetPointList().size() - 2] - parentElement->GetPointList()[parentElement->GetPointList().size() - 1];
1768
1769 auto newText = std::make_shared<Text>(position, m_properties->GetGeneralPropertiesData().labelFont, m_properties->GetGeneralPropertiesData().labelFontSize);
1770 newText->SetElement(parentElement);
1771 newText->SetDataType(DATA_PF_ACTIVE);
1772 if (unit == ElectricalUnit::UNIT_NONE)
1773 newText->SetUnit(ElectricalUnit::UNIT_MW);
1774 else
1775 newText->SetUnit(unit);
1776 newText->SetDecimalPlaces(precision);
1777 newText->SetElementTypeText(parentElement->GetElementType());
1778 newText->SetElementNumber(GetElementNumberFromList(parentElement));
1779 if (textID == ID_TXT_BRANCH_ACTIVE_POWER_2_1)
1780 newText->SetDirection(1); // std is 0
1781
1782 m_textList.emplace_back(newText);
1783 } break;
1784 case ID_TXT_BRANCH_REACTIVE_POWER_1_2:
1785 case ID_TXT_BRANCH_REACTIVE_POWER_2_1: {
1786 if (FindTextElement(parentElement, DATA_PF_REACTIVE)) return false;
1787 wxPoint2DDouble position(0.0, 10.0);
1788 if (textID == ID_TXT_BRANCH_REACTIVE_POWER_1_2)
1789 position += 2.0 * parentElement->GetPointList()[1] - parentElement->GetPointList()[0];
1790 else
1791 position += 2.0 * parentElement->GetPointList()[parentElement->GetPointList().size() - 2] - parentElement->GetPointList()[parentElement->GetPointList().size() - 1];
1792
1793 auto newText = std::make_shared<Text>(position, m_properties->GetGeneralPropertiesData().labelFont, m_properties->GetGeneralPropertiesData().labelFontSize);
1794 newText->SetElement(parentElement);
1795 newText->SetDataType(DATA_PF_REACTIVE);
1796 if (unit == ElectricalUnit::UNIT_NONE)
1797 newText->SetUnit(ElectricalUnit::UNIT_Mvar);
1798 else
1799 newText->SetUnit(unit);
1800 newText->SetDecimalPlaces(precision);
1801 newText->SetElementTypeText(parentElement->GetElementType());
1802 newText->SetElementNumber(GetElementNumberFromList(parentElement));
1803 if (textID == ID_TXT_BRANCH_REACTIVE_POWER_2_1)
1804 newText->SetDirection(1); // std is 0
1805
1806 m_textList.emplace_back(newText);
1807 } break;
1808 case ID_TXT_BRANCH_LOSSES: {
1809 if (FindTextElement(parentElement, DATA_PF_LOSSES)) return false;
1810 wxPoint2DDouble position = wxPoint2DDouble(0, 35) + (parentElement->GetPointList()[0] + parentElement->GetPointList()[parentElement->GetPointList().size() - 1]) / 2.0;
1811 auto newText = std::make_shared<Text>(position, m_properties->GetGeneralPropertiesData().labelFont, m_properties->GetGeneralPropertiesData().labelFontSize);
1812 newText->SetElement(parentElement);
1813 newText->SetDataType(DATA_PF_LOSSES);
1814 if (unit == ElectricalUnit::UNIT_NONE)
1815 newText->SetUnit(ElectricalUnit::UNIT_MW);
1816 else
1817 newText->SetUnit(unit);
1818 newText->SetDecimalPlaces(precision);
1819 newText->SetElementTypeText(parentElement->GetElementType());
1820 newText->SetElementNumber(GetElementNumberFromList(parentElement));
1821
1822 m_textList.emplace_back(newText);
1823 } break;
1824 case ID_TXT_BRANCH_CURRENT_1_2:
1825 case ID_TXT_BRANCH_CURRENT_2_1: {
1826 if (FindTextElement(parentElement, DATA_PF_CURRENT)) return false;
1827 wxPoint2DDouble position(0.0, 10.0);
1828 if (textID == ID_TXT_BRANCH_CURRENT_1_2)
1829 position += 2.0 * parentElement->GetPointList()[1] - parentElement->GetPointList()[0];
1830 else
1831 position += 2.0 * parentElement->GetPointList()[parentElement->GetPointList().size() - 2] - parentElement->GetPointList()[parentElement->GetPointList().size() - 1];
1832
1833 auto newText = std::make_shared<Text>(position, m_properties->GetGeneralPropertiesData().labelFont, m_properties->GetGeneralPropertiesData().labelFontSize);
1834 newText->SetElement(parentElement);
1835 newText->SetDataType(DATA_PF_CURRENT);
1836 if (unit == ElectricalUnit::UNIT_NONE)
1837 newText->SetUnit(ElectricalUnit::UNIT_A);
1838 else
1839 newText->SetUnit(unit);
1840 newText->SetDecimalPlaces(precision);
1841 newText->SetElementTypeText(parentElement->GetElementType());
1842 newText->SetElementNumber(GetElementNumberFromList(parentElement));
1843 if (textID == ID_TXT_BRANCH_CURRENT_2_1)
1844 newText->SetDirection(1); // std is 0
1845
1846 m_textList.emplace_back(newText);
1847 } break;
1848 case ID_TXT_BRANCH_FAULT_CURRENT_1_2:
1849 case ID_TXT_BRANCH_FAULT_CURRENT_2_1: {
1850 if (FindTextElement(parentElement, DATA_SC_CURRENT)) return false;
1851 wxPoint2DDouble position(0.0, 25.0);
1852 if (textID == ID_TXT_BRANCH_FAULT_CURRENT_1_2)
1853 position += 2.0 * parentElement->GetPointList()[1] - parentElement->GetPointList()[0];
1854 else
1855 position += 2.0 * parentElement->GetPointList()[parentElement->GetPointList().size() - 2] - parentElement->GetPointList()[parentElement->GetPointList().size() - 1];
1856
1857 auto newText = std::make_shared<Text>(position, m_properties->GetGeneralPropertiesData().labelFont, m_properties->GetGeneralPropertiesData().labelFontSize);
1858 newText->SetElement(parentElement);
1859 newText->SetDataType(DATA_SC_CURRENT);
1860 if (unit == ElectricalUnit::UNIT_NONE)
1861 newText->SetUnit(ElectricalUnit::UNIT_kA);
1862 else
1863 newText->SetUnit(unit);
1864 newText->SetDecimalPlaces(precision);
1865 newText->SetElementTypeText(parentElement->GetElementType());
1866 newText->SetElementNumber(GetElementNumberFromList(parentElement));
1867 if (textID == ID_TXT_BRANCH_FAULT_CURRENT_2_1)
1868 newText->SetDirection(1); // std is 0
1869
1870 m_textList.emplace_back(newText);
1871 } break;
1872 default:
1873 return false;
1874 break;
1875 }
1876 return true;
1877}
virtual std::vector< wxPoint2DDouble > GetPointList() const
Get the list of points that connect the element to bus.
Definition Element.h:231
wxPoint2DDouble GetPosition() const
Get the element position.
Definition Element.h:186

◆ IsContinuousCalculationActive()

bool Workspace::IsContinuousCalculationActive ( ) const
inline

Definition at line 179 of file Workspace.h.

179{ return m_continuousCalc; }

◆ IsHeatMapAutoLabelEnable()

bool Workspace::IsHeatMapAutoLabelEnable ( ) const
inline

Definition at line 162 of file Workspace.h.

162{ return m_hmAutomaticLabel; }

◆ IsHeatMapEnable()

bool Workspace::IsHeatMapEnable ( ) const
inline

Definition at line 159 of file Workspace.h.

159{ return m_showHM; }

◆ OnHeatMapTime()

void Workspace::OnHeatMapTime ( wxTimerEvent &  event)
protectedvirtual

Definition at line 2794 of file Workspace.cpp.

2795{
2796 if (m_showHMTimer) {
2797 UpdateHeatMap();
2798 Redraw();
2799 m_showHMTimer = false;
2800 }
2801}

◆ OnIdle()

void Workspace::OnIdle ( wxIdleEvent &  event)
virtual

Definition at line 2472 of file Workspace.cpp.

2473{
2474 /*
2475 // The OpenGL element (m_glCanvas) must be completely initialized (showed) to draw properly the textures and init glew.
2476 // TODO(?): Find other solution to text displayed wrong on opened file.
2477 if (m_justOpened) {
2478 if (UpdateTextElements()) m_justOpened = false;
2479 if (glewInit() != GLEW_OK)
2480 wxMessageBox("Erro ao iniciar glew ='(");
2481 else
2482 {
2483 // Load and create shader
2484 m_basicShader = new Shader("..//data//shaders//Basic.shader");
2485 m_hmLabelShader = new Shader("..//data//shaders//HMLabel.shader");
2486 float limits[2] = { 1.05, 0.95 };
2487 m_hmPlane = new HMPlane(m_basicShader, m_hmLabelShader, m_width, m_height, limits);
2488 }
2489
2490 Redraw();
2491 }
2492 */
2493 if (m_justOpened) {
2494 m_justOpened = false;
2495 double limits[2] = { 1.05, 0.95 };
2496 m_hmPlane = new HMPlane(m_width, m_height, limits);
2497
2498 Redraw();
2499 }
2500}

◆ OnKeyDown()

void Workspace::OnKeyDown ( wxKeyEvent &  event)
virtual

Definition at line 886 of file Workspace.cpp.

887{
888 bool insertingElement = false;
889 if (m_mode == WorkspaceMode::MODE_INSERT || m_mode == WorkspaceMode::MODE_INSERT_TEXT) insertingElement = true;
890
891 char key = event.GetUnicodeKey();
892 if (key != WXK_NONE) {
893 switch (key) {
894 case WXK_ESCAPE: // Cancel operations.
895 {
896 if (m_mode == WorkspaceMode::MODE_INSERT) {
897 //Element* elementToDelete = m_elementList[m_elementList.size() - 1];
898 auto elementToDelete = m_elementList.back();
899
900 // Remove child element that has to be deleted (specially buses)
901 for (auto& element : m_elementList) {
902 element->RemoveChild(elementToDelete.get());
903 }
904
905 m_elementList.pop_back(); // Removes the last element being inserted.
906 m_mode = WorkspaceMode::MODE_EDIT;
907 Redraw();
908 }
909 else if (m_mode == WorkspaceMode::MODE_INSERT_TEXT) {
910 m_textList.pop_back();
911 m_mode = WorkspaceMode::MODE_EDIT;
912 Redraw();
913 }
914 } break;
915 case WXK_DELETE: // Delete selected elements
916 {
917 DeleteSelectedElements();
918 } break;
919 case 'A': {
920 if (!insertingElement) {
921 //Text* newText = new Text(m_camera->ScreenToWorld(event.GetPosition()), m_properties->GetGeneralPropertiesData().labelFont, m_properties->GetGeneralPropertiesData().labelFontSize);
922 auto newText = std::make_shared<Text>(
923 m_camera->ScreenToWorld(event.GetPosition()),
924 m_properties->GetGeneralPropertiesData().labelFont,
925 m_properties->GetGeneralPropertiesData().labelFontSize);
926 m_textList.push_back(newText);
927 m_mode = WorkspaceMode::MODE_INSERT_TEXT;
928 m_statusBar->SetStatusText(_("Insert Text: Click to insert, ESC to cancel."));
929 if (m_hmPlane && m_showHM) {
930 m_hmPlane->Clear();
931 }
932 Redraw();
933 }
934 } break;
935 case 'F': {
936 if (event.GetModifiers() == wxMOD_SHIFT) { Fit(); }
937 } break;
938 case 'R': // Rotate the selected elements.
939 {
940 RotateSelectedElements(event.GetModifiers() != wxMOD_SHIFT);
941 } break;
942 case 'B': // Insert a bus.
943 {
944 if (!insertingElement) {
945 auto newBus = std::make_shared<Bus>(m_camera->ScreenToWorld(event.GetPosition()),
946 wxString::Format(_("Bus %d"), GetElementNumber(ID_BUS)));
947 IncrementElementNumber(ID_BUS);
948 m_elementList.push_back(newBus);
949 m_mode = WorkspaceMode::MODE_INSERT;
950 m_statusBar->SetStatusText(_("Insert Bus: Click to insert, ESC to cancel."));
951 if (m_hmPlane && m_showHM) {
952 m_hmPlane->Clear();
953 }
954 Redraw();
955 }
956 } break;
957 case 'L': {
958 if (!insertingElement) {
959 if (!event.ControlDown() && event.ShiftDown()) { // Insert a load.
960 auto newLoad = std::make_shared<Load>(wxString::Format(_("Load %d"), GetElementNumber(ID_LOAD)));
961 IncrementElementNumber(ID_LOAD);
962 m_elementList.push_back(newLoad);
963 m_mode = WorkspaceMode::MODE_INSERT;
964 m_statusBar->SetStatusText(_("Insert Load: Click on a bus, ESC to cancel."));
965 }
966 else if (!event.ControlDown() && !event.ShiftDown()) { // Insert a power line.
967 auto newLine = std::make_shared<Line>(wxString::Format(_("Line %d"), GetElementNumber(ID_LINE)));
968 IncrementElementNumber(ID_LINE);
969 m_elementList.push_back(newLine);
970 m_mode = WorkspaceMode::MODE_INSERT;
971 m_statusBar->SetStatusText(_("Insert Line: Click on two buses, ESC to cancel."));
972 }
973 if (m_hmPlane && m_showHM) {
974 m_hmPlane->Clear();
975 }
976 Redraw();
977 }
978 // Tests - Ctrl + Shift + L
979 } break;
980 case 'T': // Insert a transformer.
981 {
982 if (!insertingElement) {
983 auto newTransformer = std::make_shared<Transformer>(wxString::Format(_("Transformer %d"), GetElementNumber(ID_TRANSFORMER)));
984 IncrementElementNumber(ID_TRANSFORMER);
985 m_elementList.push_back(newTransformer);
986 m_mode = WorkspaceMode::MODE_INSERT;
987 m_statusBar->SetStatusText(_("Insert Transformer: Click on two buses, ESC to cancel."));
988 if (m_hmPlane && m_showHM) {
989 m_hmPlane->Clear();
990 }
991 Redraw();
992 }
993 } break;
994 case 'G': // Insert a generator.
995 {
996 if (!insertingElement) {
997 auto newGenerator = std::make_shared<SyncGenerator>(wxString::Format(_("Generator %d"), GetElementNumber(ID_SYNCGENERATOR)));
998 IncrementElementNumber(ID_SYNCGENERATOR);
999 m_elementList.push_back(newGenerator);
1000 m_mode = WorkspaceMode::MODE_INSERT;
1001 m_statusBar->SetStatusText(_("Insert Generator: Click on a bus, ESC to cancel."));
1002 if (m_hmPlane && m_showHM) {
1003 m_hmPlane->Clear();
1004 }
1005 Redraw();
1006 }
1007 } break;
1008 case 'I': {
1009 if (!insertingElement) {
1010 if (event.GetModifiers() == wxMOD_SHIFT) { // Insert an inductor.
1011 auto newInductor = std::make_shared<Inductor>(wxString::Format(_("Inductor %d"), GetElementNumber(ID_INDUCTOR)));
1012 IncrementElementNumber(ID_INDUCTOR);
1013 m_elementList.push_back(newInductor);
1014 m_mode = WorkspaceMode::MODE_INSERT;
1015 m_statusBar->SetStatusText(_("Insert Inductor: Click on a bus, ESC to cancel."));
1016 }
1017 else // Insert an induction motor.
1018 {
1019 auto newIndMotor = std::make_shared<IndMotor>(wxString::Format(_("Induction motor %d"), GetElementNumber(ID_INDMOTOR)));
1020 IncrementElementNumber(ID_INDMOTOR);
1021 m_elementList.push_back(newIndMotor);
1022 m_mode = WorkspaceMode::MODE_INSERT;
1023 m_statusBar->SetStatusText(_("Insert Induction Motor: Click on a bus, ESC to cancel."));
1024 }
1025 if (m_hmPlane && m_showHM) {
1026 m_hmPlane->Clear();
1027 }
1028 Redraw();
1029 }
1030 } break;
1031 case 'K': // Insert a synchronous condenser.
1032 {
1033 if (!insertingElement) {
1034 auto newSyncCondenser = std::make_shared<SyncMotor>(wxString::Format(_("Synchronous condenser %d"), GetElementNumber(ID_SYNCMOTOR)));
1035 IncrementElementNumber(ID_SYNCMOTOR);
1036 m_elementList.push_back(newSyncCondenser);
1037 m_mode = WorkspaceMode::MODE_INSERT;
1038 m_statusBar->SetStatusText(_("Insert Synchronous Condenser: Click on a bus, ESC to cancel."));
1039 if (m_hmPlane && m_showHM) {
1040 m_hmPlane->Clear();
1041 }
1042 Redraw();
1043 }
1044 } break;
1045 case 'C': {
1046 if (!insertingElement) {
1047 if (event.GetModifiers() == wxMOD_SHIFT) { // Insert a capacitor.
1048 auto newCapacitor = std::make_shared<Capacitor>(wxString::Format(_("Capacitor %d"), GetElementNumber(ID_CAPACITOR)));
1049 IncrementElementNumber(ID_CAPACITOR);
1050 m_elementList.push_back(newCapacitor);
1051 m_mode = WorkspaceMode::MODE_INSERT;
1052 m_statusBar->SetStatusText(_("Insert Capacitor: Click on a bus, ESC to cancel."));
1053 if (m_hmPlane && m_showHM) {
1054 m_hmPlane->Clear();
1055 }
1056 Redraw();
1057 }
1058 else if (event.GetModifiers() == wxMOD_CONTROL) { // Copy.
1059 CopySelection();
1060 }
1061 }
1062 } break;
1063 case 'H': {
1064 if (!insertingElement) {
1065 if (event.ShiftDown() && event.ControlDown()) {
1066 if (!m_showHM) {
1067 m_showHM = true;
1068 UpdateHeatMap();
1069 }
1070 else {
1071 m_showHM = false;
1072 }
1073
1074 }
1075 else if (event.GetModifiers() == wxMOD_SHIFT) { // Insert an harmonic current source.
1076 auto newHarmCurrent = std::make_shared<HarmCurrent>(
1077 wxString::Format(_("Harmonic Current %d"), GetElementNumber(ID_HARMCURRENT)));
1078 IncrementElementNumber(ID_HARMCURRENT);
1079 m_elementList.push_back(newHarmCurrent);
1080 m_mode = WorkspaceMode::MODE_INSERT;
1081 m_statusBar->SetStatusText(
1082 _("Insert Harmonic Current Source: Click on a bus, ESC to cancel."));
1083 }
1084 if (m_hmPlane && m_showHM) {
1085 m_hmPlane->Clear();
1086 }
1087 Redraw();
1088 }
1089 } break;
1090 case 'V': {
1091 if (!insertingElement) {
1092 if (event.GetModifiers() == wxMOD_CONTROL) { Paste(); }
1093 }
1094 } break;
1095 case 'S': {
1096 if (!insertingElement) {
1097 if (event.GetModifiers() == wxMOD_CONTROL) {
1098 // Save the workspace.
1099 FileHanding fileHandling(this);
1100
1101 if (GetSavedPath().IsOk()) {
1102 fileHandling.SaveProject(GetSavedPath());
1103 }
1104 else {
1105 wxFileDialog saveFileDialog(this, _("Save PSP file"), "", "", "PSP files (*.psp)|*.psp",
1106 wxFD_SAVE | wxFD_OVERWRITE_PROMPT);
1107 if (saveFileDialog.ShowModal() == wxID_CANCEL) return;
1108
1109 fileHandling.SaveProject(saveFileDialog.GetPath());
1110 wxFileName fileName(saveFileDialog.GetPath());
1111 SetName(fileName.GetName());
1112 if (m_auiNotebook) m_auiNotebook->SetPageText(m_auiNotebook->GetPageIndex(this), GetName());
1113 SetSavedPath(fileName);
1114 }
1115 }
1116 }
1117 } break;
1118 case 'Z': {
1119 if (!insertingElement) {
1120 if (event.ControlDown() && !event.ShiftDown()) { SetPreviousState(); }
1121 if (event.ControlDown() && event.ShiftDown()) { SetNextState(); }
1122 }
1123 } break;
1124 case 'Y': {
1125 if (!insertingElement) {
1126 if (event.GetModifiers() == wxMOD_CONTROL) { SetNextState(); }
1127 }
1128 } break;
1129 case 'E': {
1130 if (!insertingElement) {
1131 if (event.GetModifiers() == wxMOD_SHIFT) {
1132
1133 if (!insertingElement) {
1134 auto newEMTElement = std::make_shared<EMTElement>(wxString::Format(_("Electromagnetic Element %d"), GetElementNumber(ID_EMTELEMENT)));
1135 IncrementElementNumber(ID_EMTELEMENT);
1136 m_elementList.push_back(newEMTElement);
1137 m_mode = WorkspaceMode::MODE_INSERT;
1138 m_statusBar->SetStatusText(_("Insert Electromagnetic Transient Element: Click on a bus, ESC to cancel."));
1139 if (m_hmPlane && m_showHM) {
1140 m_hmPlane->Clear();
1141 }
1142 Redraw();
1143 }
1144 }
1145 }
1146 } break;
1147#ifdef _DEBUG
1148#ifdef SHOW_DEBUG_PANEL
1149 case 'D': {
1150 if (event.GetModifiers() == wxMOD_CONTROL) {
1151 if (m_debugFrame) {
1152 m_debugFrame->SetFocus();
1153 }
1154 }
1155 } break;
1156#endif
1157#endif
1158 default:
1159 break;
1160 }
1161 }
1162
1163 UpdateStatusBar();
1164 event.Skip();
1165}
Save and opens the projects created on disk.
Definition FileHanding.h:43

◆ OnLeftClickDown()

void Workspace::OnLeftClickDown ( wxMouseEvent &  event)
virtual

Definition at line 258 of file Workspace.cpp.

259{
260 wxPoint clickPoint = event.GetPosition();
261 bool foundElement = false;
262 Element* newElement = nullptr;
263 bool showNewElementForm = false;
264 bool clickOnSwitch = false;
265 bool unselectAll = true;
266 std::vector<Element*> notUnselectElementList;
267 std::vector<Text*> notUnselectTextList;
268
269 if (m_mode == WorkspaceMode::MODE_INSERT_TEXT || m_mode == WorkspaceMode::MODE_PASTE || m_mode == WorkspaceMode::MODE_DRAG_PASTE) {
270 m_mode = WorkspaceMode::MODE_EDIT;
271 SaveCurrentState();
272 }
273 else if (m_mode == WorkspaceMode::MODE_INSERT || m_mode == WorkspaceMode::MODE_DRAG_INSERT || m_mode == WorkspaceMode::MODE_DRAG_INSERT_TEXT) {
274 wxPoint2DDouble clickPointWorld = m_camera->ScreenToWorld(clickPoint);
275
276 if (!m_elementList.empty()) {
277 // Get the last element inserted on the list.
278 newElement = m_elementList.back().get();
279 for (auto& element : m_elementList) {
280 // Clicked in any element.
281 if (element->Contains(clickPointWorld)) {
282 // Click at a bus.
283 if (auto bus = dynamic_cast<Bus*>(element.get())) {
284 // Select the bus.
285 bus->SetSelected();
286 foundElement = true; // Element found.
287 // Add the new element's parent. If the element being inserted returns true, back to
288 // edit mode.
289 if (newElement->AddParent(bus, clickPointWorld)) {
290 ValidateElementsVoltages();
291 m_timer->Stop();
292 showNewElementForm = true;
293 m_mode = WorkspaceMode::MODE_EDIT;
294 bus->SetInserted();
295 }
296 }
297 }
298 }
299
300 // The line element can have an undefined number of points.
301 if (!foundElement) {
302 if (auto line = dynamic_cast<Line*>(newElement)) { line->AddPoint(clickPointWorld); }
303 }
304 foundElement = true;
305 unselectAll = false;
306 }
307 }
308 else {
309
310 bool clickPickbox = false;
311
312 for (auto& element : m_elementList) {
313 element->ResetPickboxes(); // Reset pickbox state.
314
315 // Set movement initial position (not necessarily will be moved).
316 element->StartMove(m_camera->ScreenToWorld(clickPoint));
317
318 // Click in selected element node.
319 if (element->NodeContains(m_camera->ScreenToWorld(clickPoint)) != 0 && element->IsSelected()) {
320 m_mode = WorkspaceMode::MODE_MOVE_NODE;
321 m_disconnectedElement = true;
322 foundElement = true;
323 unselectAll = false;
324 if (m_hmPlane && m_showHM) {
325 m_hmPlane->Clear();
326 }
327 }
328
329 // Click in an element.
330 else if (element->Contains(m_camera->ScreenToWorld(clickPoint))) {
331 notUnselectElementList.emplace_back(element.get());
332 if (!foundElement) {
333 if (element->IsSelected()) unselectAll = false;
334 // Select and show pickbox.
335 element->SetSelected();
336 element->ShowPickbox();
337 foundElement = true;
338 // Select the associated text
339 for (auto& text : m_textList) {
340 if (text->GetElement() == element.get()) {
341 notUnselectTextList.emplace_back(text.get());
342 text->SetSelected();
343 text->SetAllowRotation(false);
344 if (unselectAll) text->SetAltSelectionColour();
345 }
346 }
347 }
348 // If pickbox contains the click, move the pickbox
349 if (element->PickboxContains(m_camera->ScreenToWorld(clickPoint))) {
350 m_mode = WorkspaceMode::MODE_MOVE_PICKBOX;
351 clickPickbox = true;
352 }
353 // If didn't found a pickbox, move the element
354 if (!clickPickbox) { m_mode = WorkspaceMode::MODE_MOVE_ELEMENT; }
355
356 if (m_hmPlane && m_showHM) {
357 m_hmPlane->Clear();
358 }
359 }
360
361 // Click in a switch.
362 else if (element->SwitchesContains(m_camera->ScreenToWorld(clickPoint))) {
363 element->SetOnline(element->IsOnline() ? false : true);
364 clickOnSwitch = true;
365 }
366 }
367
368 // Text element
369 for (auto& text : m_textList) {
370 text->StartMove(m_camera->ScreenToWorld(clickPoint));
371
372 if (text->Contains(m_camera->ScreenToWorld(clickPoint))) {
373 notUnselectTextList.emplace_back(text.get());
374 if (!foundElement) {
375 if (text->IsSelected()) unselectAll = false;
376 text->SetSelected();
377 text->SetAltSelectionColour(false);
378 text->SetAllowRotation();
379 m_mode = WorkspaceMode::MODE_MOVE_ELEMENT;
380 foundElement = true;
381 if (m_hmPlane && m_showHM) {
382 m_hmPlane->Clear();
383 }
384 }
385 }
386 }
387 }
388
389 // Unselect all elements
390 if (!event.ControlDown() && unselectAll) {
391 for (auto& element : m_elementList) {
392 bool select = false;
393 for (Element* notUnselectElement : notUnselectElementList) {
394 if (notUnselectElement == element.get()) select = true;
395 }
396 element->SetSelected(select);
397 }
398 for (auto& text : m_textList) {
399 bool select = false;
400 for (auto& notUnselectText : notUnselectTextList) {
401 if (notUnselectText == text.get()) select = true;
402 }
403 text->SetSelected(select);
404 }
405 }
406
407 if (!foundElement && !clickOnSwitch) {
408 m_mode = WorkspaceMode::MODE_SELECTION_RECT;
409 m_startSelRect = m_camera->ScreenToWorld(clickPoint);
410 if (m_hmPlane && m_showHM) {
411 m_hmPlane->Clear();
412 }
413 }
414
415 Redraw();
416 UpdateStatusBar();
417
418 if (showNewElementForm) {
419 if (newElement) {
420 newElement->ShowForm(this, newElement);
421 CheckSlackBusDuplication(newElement);
422 SaveCurrentState();
423 if (m_continuousCalc) RunStaticStudies();
424 }
425 }
426 if (clickOnSwitch && m_continuousCalc) RunStaticStudies();
427
428 event.Skip();
429}
virtual bool AddParent(Element *parent, wxPoint2DDouble position)
Add a parent to the element. This method must be used on power elements that connect to a bus,...
Definition Element.h:239
virtual bool ShowForm(wxWindow *parent, Element *element)
Show element data form.
Definition Element.h:587
Power line element.
Definition Line.h:64

◆ OnLeftClickUp()

void Workspace::OnLeftClickUp ( wxMouseEvent &  event)
virtual

Definition at line 537 of file Workspace.cpp.

538{
539 // This event (under certain conditions) deselects the elements and back to edit mode or select the elements using
540 // the selection rectangle.
541 bool foundPickbox = false;
542 bool findNewParent = false;
543 bool updateVoltages = false;
544 bool saveCurrentState = false;
545 auto itnp = m_elementList.begin();
546
547 for (auto it = m_elementList.begin(); it != m_elementList.end(); ++it) {
548 auto& element = *it;
549 // The user was moving a pickbox.
550 if (m_mode == WorkspaceMode::MODE_MOVE_PICKBOX) {
551 // Catch only the element that have the pickbox shown.
552 if (element->IsPickboxShown()) {
553 saveCurrentState = true;
554 // If the element is a bus, check if a node is outside.
555 if (auto bus = dynamic_cast<Bus*>(element.get())) {
556 // Get all the bus children.
557 for (auto child : m_elementList) {
558 for (auto parent : child->GetParentList()) {
559 // The child have a parent that is the element (bus).
560 if (parent == bus) {
561 child->UpdateNodes();
562 m_disconnectedElement = true;
563 }
564 }
565 }
566 //for (int i = 0; i < (int)m_elementList.size(); i++) {
567 // Element* child = m_elementList[i];
568 // for (int j = 0; j < (int)child->GetParentList().size(); j++) {
569 // Element* parent = child->GetParentList()[j];
570 // // The child have a parent that is the element.
571 // if (parent == element) {
572 // child->UpdateNodes();
573 // m_disconnectedElement = true;
574 // }
575 // }
576 //}
577 }
578 }
579 }
580
581 if (m_mode == WorkspaceMode::MODE_SELECTION_RECT) {
582 if (element->Intersects(m_selectionRect)) {
583 element->SetSelected();
584 // Select the associated text
585 for (auto& text : m_textList) {
586 if (text->GetElement() == element.get()) {
587 text->SetSelected();
588 text->SetAltSelectionColour(false);
589 text->SetAllowRotation();
590 }
591 }
592 }
593 //else if (!event.ControlDown()) {
594 // element->SetSelected(false);
595 //}
596 }
597 else if (m_mode == WorkspaceMode::MODE_MOVE_NODE) {
598 if (element->IsSelected()) {
599 saveCurrentState = true;
600 for (auto parent : m_elementList) {
601 if (auto bus = dynamic_cast<Bus*>(parent.get())) {
602 if (element->SetNodeParent(bus)) {
603 parent->AddChild(element.get());
604 findNewParent = true;
605 itnp = it;
606 element->ResetNodes();
607 break;
608 }
609 }
610 }
611 // element->ResetNodes();
612 }
613 }
614 else {
615 // Deselect
616 //if (!event.ControlDown()) {
617 // if (!element->Contains(m_camera->ScreenToWorld(event.GetPosition()))) { element->SetSelected(false); }
618 //}
619
620 if (element->PickboxContains(m_camera->ScreenToWorld(event.GetPosition()))) {
621 foundPickbox = true;
622 }
623 else {
624 element->ShowPickbox(false);
625 element->ResetPickboxes();
626 }
627 }
628 }
629
630 // Text element
631 for (auto& text : m_textList) {
632 if (m_mode == WorkspaceMode::MODE_SELECTION_RECT) {
633 if (text->Intersects(m_selectionRect)) {
634 text->SetSelected();
635 text->SetAltSelectionColour(false);
636 text->SetAllowRotation();
637 }
638 //else if (!event.ControlDown()) {
639 // text->SetSelected(false);
640 //}
641 }
642 //else if (!event.ControlDown()) {
643 // if (!text->Contains(m_camera->ScreenToWorld(event.GetPosition()))) { text->SetSelected(false); }
644 //}
645 }
646 if (m_mode == WorkspaceMode::MODE_MOVE_ELEMENT) saveCurrentState = true;
647
648 if (findNewParent) {
649 std::rotate(itnp, itnp + 1, m_elementList.end());
650 updateVoltages = true;
651 }
652 if (!foundPickbox) { SetCursor(wxCURSOR_ARROW); }
653
654 if (m_mode != WorkspaceMode::MODE_INSERT) { m_mode = WorkspaceMode::MODE_EDIT; }
655
656 if (updateVoltages) { ValidateElementsVoltages(); }
657
658 if (saveCurrentState) SaveCurrentState();
659
660 if (m_continuousCalc && m_disconnectedElement) {
661 m_disconnectedElement = false;
662 RunStaticStudies();
663 }
664
665 m_selectionRect = wxRect2DDouble(0, 0, 0, 0);
666
667 if (m_hmPlane && m_showHM) {
668 m_showHMTimer = true;
669 m_timerHeatMap->Start();
670 }
671
672 Redraw();
673 UpdateStatusBar();
674}

◆ OnLeftDoubleClick()

void Workspace::OnLeftDoubleClick ( wxMouseEvent &  event)
virtual

Definition at line 431 of file Workspace.cpp.

432{
433 bool elementEdited = false;
434 bool clickOnSwitch = false;
435 bool redraw = false;
436
437 for (auto& element : m_elementList) {
438 // Click in an element.
439 if (element->Contains(m_camera->ScreenToWorld(event.GetPosition()))) {
440 bool elementIsBus = false;
441 Bus oldBus;
442 Bus* currentBus = nullptr;
443 if ((currentBus = dynamic_cast<Bus*>(element.get()))) {
444 elementIsBus = true;
445 oldBus = *currentBus;
446 }
447 m_timer->Stop();
448 if (element->ShowForm(this, element.get())) {
449 CheckSlackBusDuplication(element.get());
450 SaveCurrentState();
451 }
452 elementEdited = true;
453 redraw = true;
454
455 // If the edited element is a bus and was changed the rated voltage, this voltage must be
456 // propagated through the lines
457 if (elementIsBus) {
458 // The voltage was changed
459 if (oldBus.GetElectricalData().nominalVoltage != currentBus->GetElectricalData().nominalVoltage ||
460 oldBus.GetElectricalData().nominalVoltageUnit !=
461 currentBus->GetElectricalData().nominalVoltageUnit) {
462 // Check if the bus has line as child.
463 std::vector<Element*> childList = element->GetChildList();
464 for (auto itc = childList.begin(), itcEnd = childList.end(); itc != itcEnd; ++itc) {
465 Element* child = *itc;
466 if (typeid(*child) == typeid(Line)) {
467 wxMessageDialog msgDialog(this, _("Do you want to change the rated voltage of the path?"),
468 _("Warning"), wxYES_NO | wxCENTRE | wxICON_WARNING);
469 if (msgDialog.ShowModal() == wxID_YES)
470 ValidateBusesVoltages(element.get());
471 else {
472 auto data = currentBus->GetElectricalData();
473 data.nominalVoltage = oldBus.GetElectricalData().nominalVoltage;
474 data.nominalVoltageUnit = oldBus.GetElectricalData().nominalVoltageUnit;
475 currentBus->SetElectricalData(data);
476 }
477 break;
478 }
479 }
480 }
481 ValidateElementsVoltages();
482 }
483 }
484
485 // Click in a switch.
486 else if (element->SwitchesContains(m_camera->ScreenToWorld(event.GetPosition()))) {
487 element->SetOnline(element->IsOnline() ? false : true);
488 clickOnSwitch = true;
489 }
490 }
491
492 // Text element
493 for (auto& text : m_textList) {
494 if (text->Contains(m_camera->ScreenToWorld(event.GetPosition()))) {
495 if (text->ShowForm(this, GetElementList())) SaveCurrentState();
496 redraw = true;
497 }
498 }
499 if (elementEdited) {
500 UpdateTextElements();
501 if (m_continuousCalc) RunStaticStudies();
502 }
503 if (clickOnSwitch && m_continuousCalc) RunStaticStudies();
504
505 if (redraw) Redraw();
506 m_timer->Start();
507}

◆ OnMiddleDoubleClick()

void Workspace::OnMiddleDoubleClick ( wxMouseEvent &  event)
virtual

Definition at line 2605 of file Workspace.cpp.

2606{
2607 Fit();
2608 event.Skip();
2609}

◆ OnMiddleDown()

void Workspace::OnMiddleDown ( wxMouseEvent &  event)
virtual

Definition at line 811 of file Workspace.cpp.

812{
813 // Set to drag mode.
814 switch (m_mode) {
815 case WorkspaceMode::MODE_INSERT: {
816 m_mode = WorkspaceMode::MODE_DRAG_INSERT;
817 } break;
818 case WorkspaceMode::MODE_INSERT_TEXT: {
819 m_mode = WorkspaceMode::MODE_DRAG_INSERT_TEXT;
820 } break;
821 case WorkspaceMode::MODE_PASTE: {
822 m_mode = WorkspaceMode::MODE_DRAG_PASTE;
823 } break;
824 default: {
825 m_mode = WorkspaceMode::MODE_DRAG;
826 } break;
827 }
828 m_camera->StartTranslation(m_camera->ScreenToWorld(event.GetPosition()));
829 UpdateStatusBar();
830
831 if (m_hmPlane && m_showHM) {
832 m_hmPlane->Clear();
833 }
834
835 event.Skip();
836}

◆ OnMiddleUp()

void Workspace::OnMiddleUp ( wxMouseEvent &  event)
virtual

Definition at line 838 of file Workspace.cpp.

839{
840 switch (m_mode) {
841 case WorkspaceMode::MODE_DRAG_INSERT: {
842 m_mode = WorkspaceMode::MODE_INSERT;
843 } break;
844 case WorkspaceMode::MODE_DRAG_INSERT_TEXT: {
845 m_mode = WorkspaceMode::MODE_INSERT_TEXT;
846 } break;
847 case WorkspaceMode::MODE_DRAG_PASTE: {
848 m_mode = WorkspaceMode::MODE_PASTE;
849 } break;
850 case WorkspaceMode::MODE_INSERT:
851 case WorkspaceMode::MODE_INSERT_TEXT:
852 case WorkspaceMode::MODE_PASTE: {
853 // Does nothing.
854 } break;
855 default: {
856 m_mode = WorkspaceMode::MODE_EDIT;
857 } break;
858 }
859 UpdateStatusBar();
860
861 if (m_hmPlane && m_showHM) {
862 UpdateHeatMap();
863 Redraw();
864 }
865
866 event.Skip();
867}

◆ OnMouseMotion()

void Workspace::OnMouseMotion ( wxMouseEvent &  event)
virtual

Definition at line 676 of file Workspace.cpp.

677{
678 bool redraw = false;
679 switch (m_mode) {
680 case WorkspaceMode::MODE_INSERT: {
681 auto& newElement = m_elementList.back(); // Get the last element in the list.
682 newElement->SetPosition(m_camera->ScreenToWorld(event.GetPosition()));
683 redraw = true;
684 } break;
685
686 case WorkspaceMode::MODE_INSERT_TEXT: {
687 auto& newText = m_textList.back();
688 newText->SetPosition(m_camera->ScreenToWorld(event.GetPosition()));
689 redraw = true;
690 } break;
691
692 case WorkspaceMode::MODE_DRAG:
693 case WorkspaceMode::MODE_DRAG_INSERT:
694 case WorkspaceMode::MODE_DRAG_INSERT_TEXT:
695 case WorkspaceMode::MODE_DRAG_PASTE: {
696 m_camera->SetTranslation(event.GetPosition());
697 redraw = true;
698 } break;
699
700 case WorkspaceMode::MODE_EDIT: {
701 bool foundPickbox = false;
702 for (auto& element : m_elementList) {
703 if (element->IsSelected()) {
704 // Show element pickbox (when it has) if the mouse is over the selected object.
705 if (element->Contains(m_camera->ScreenToWorld(event.GetPosition()))) {
706 element->ShowPickbox();
707 redraw = true;
708
709 // If the mouse is over a pickbox set correct mouse cursor.
710 if (element->PickboxContains(m_camera->ScreenToWorld(event.GetPosition()))) {
711 foundPickbox = true;
712 SetCursor(element->GetBestPickboxCursor());
713 }
714 else if (!foundPickbox) {
715 SetCursor(wxCURSOR_ARROW);
716 element->ResetPickboxes();
717 }
718 }
719 else if (!foundPickbox) {
720 if (element->IsPickboxShown()) redraw = true;
721
722 element->ShowPickbox(false);
723 element->ResetPickboxes();
724 SetCursor(wxCURSOR_ARROW);
725 }
726 }
727 }
728 } break;
729
730 case WorkspaceMode::MODE_MOVE_NODE: {
731 for (auto& element : m_elementList) {
732 if (element->IsSelected()) {
733 element->MoveNode(nullptr, m_camera->ScreenToWorld(event.GetPosition()));
734 redraw = true;
735 }
736 }
737 } break;
738
739 case WorkspaceMode::MODE_MOVE_PICKBOX: {
740 for (auto& element : m_elementList) {
741 if (element->IsSelected()) {
742 element->MovePickbox(m_camera->ScreenToWorld(event.GetPosition()));
743 redraw = true;
744 }
745 }
746 if (m_hmPlane && m_showHM) {
747 m_hmPlane->Clear();
748 }
749 } break;
750
751 case WorkspaceMode::MODE_MOVE_ELEMENT:
752 case WorkspaceMode::MODE_PASTE: {
753 for (auto it = m_elementList.begin(), itEnd = m_elementList.end(); it != itEnd; ++it) {
754 auto element = *it;
755 if (element->IsSelected()) {
756 element->Move(m_camera->ScreenToWorld(event.GetPosition()));
757 // Move child nodes
758 std::vector<Element*> childList = element->GetChildList();
759 for (auto it = childList.begin(), itEnd = childList.end(); it != itEnd; ++it) {
760 (*it)->MoveNode(element.get(), m_camera->ScreenToWorld(event.GetPosition()));
761 }
762 redraw = true;
763 }
764 }
765 // Text element motion
766 for (auto& text : m_textList) {
767 if (text->IsSelected()) {
768 text->Move(m_camera->ScreenToWorld(event.GetPosition()));
769 redraw = true;
770 }
771 }
772 if (m_hmPlane && m_showHM) {
773 m_hmPlane->Clear();
774 }
775 } break;
776
777 case WorkspaceMode::MODE_SELECTION_RECT: {
778 wxPoint2DDouble currentPos = m_camera->ScreenToWorld(event.GetPosition());
779 double x, y, w, h;
780 if (currentPos.m_x < m_startSelRect.m_x) {
781 x = currentPos.m_x;
782 w = m_startSelRect.m_x - currentPos.m_x;
783 }
784 else {
785 x = m_startSelRect.m_x;
786 w = currentPos.m_x - m_startSelRect.m_x;
787 }
788 if (currentPos.m_y < m_startSelRect.m_y) {
789 y = currentPos.m_y;
790 h = m_startSelRect.m_y - currentPos.m_y;
791 }
792 else {
793 y = m_startSelRect.m_y;
794 h = currentPos.m_y - m_startSelRect.m_y;
795 }
796
797 m_selectionRect = wxRect2DDouble(x, y, w, h);
798 redraw = true;
799 } break;
800 }
801
802 if (redraw) {
803 Redraw();
804 }
805 m_camera->UpdateMousePosition(event.GetPosition());
806 UpdateStatusBar();
807 m_timer->Start(); // Restart the timer.
808 event.Skip();
809}

◆ OnPaint()

void Workspace::OnPaint ( wxPaintEvent &  event)
virtual

Definition at line 132 of file Workspace.cpp.

133{
134 wxBufferedPaintDC dc(m_workspacePanel);
135 dc.Clear();
136 wxGraphicsContext* gc = wxGraphicsContext::Create(dc);
137
138 // Draw
139 DrawScene(gc);
140 delete gc;
141
142 event.Skip();
143}

◆ OnPopupClick()

void Workspace::OnPopupClick ( wxCommandEvent &  event)
virtual

Definition at line 1332 of file Workspace.cpp.

1333{
1334 bool redrawHM = false;
1335
1336 wxMenu* menu = static_cast<wxMenu*>(event.GetEventObject());
1337 Element* element = static_cast<Element*>(menu->GetClientData());
1338 int eventID = event.GetId();
1339 switch (eventID) {
1340 case ID_EDIT_ELEMENT: {
1341 if (element->ShowForm(this, element)) {
1342 CheckSlackBusDuplication(element);
1343 UpdateTextElements();
1344 SaveCurrentState();
1345 }
1346 } break;
1347 case ID_LINE_ADD_NODE: {
1348 Line* line = static_cast<Line*>(element);
1349 line->AddNode(m_camera->GetMousePosition());
1350 SaveCurrentState();
1351 Redraw();
1352 } break;
1353 case ID_LINE_REMOVE_NODE: {
1354 Line* line = static_cast<Line*>(element);
1355 line->RemoveNode(m_camera->GetMousePosition());
1356 SaveCurrentState();
1357 Redraw();
1358 } break;
1359 case ID_ROTATE_CLOCK: {
1360 element->Rotate();
1361 for (auto& iElement : m_elementList) {
1362 // Parent's element rotating...
1363 for (int i = 0; i < (int)iElement->GetParentList().size(); i++) {
1364 Element* parent = iElement->GetParentList()[i];
1365 if (parent == element) { iElement->RotateNode(parent); }
1366 }
1367 }
1368 redrawHM = true;
1369 SaveCurrentState();
1370 Redraw();
1371 } break;
1373 element->Rotate(false);
1374 for (auto& iElement : m_elementList) {
1375 // Parent's element rotating...
1376 for (int i = 0; i < (int)iElement->GetParentList().size(); i++) {
1377 Element* parent = iElement->GetParentList()[i];
1378 if (parent == element) { iElement->RotateNode(parent, false); }
1379 }
1380 }
1381 redrawHM = true;
1382 SaveCurrentState();
1383 Redraw();
1384 } break;
1385 case ID_DELETE: {
1386 //for (auto& iElement : m_elementList) {
1387 // if (element == iElement.get()) {
1388 // // Remove child/parent.
1389 // std::vector<Element*> childList = element->GetChildList();
1390 // for (auto& child : childList) {
1391 // if (child) {
1392 // child->RemoveParent(element);
1393 // element->RemoveChild(child);
1394 // }
1395 // }
1396 // std::vector<Element*> parentList = element->GetParentList();
1397 // for (auto& parent : parentList) {
1398 // if (parent) { parent->RemoveChild(element); }
1399 // }
1400 //
1401 // //for (auto itt = m_textList.begin(); itt != m_textList.end(); ++itt) {
1402 // // Text* text = *itt;
1403 // // if (text->GetElement() == element) {
1404 // // m_textList.erase(itt--);
1405 // // if (text) delete text;
1406 // // }
1407 // //}
1408 // std::erase_if(m_textList, [&](const auto& text) {
1409 // return text->GetElement() == element;
1410 // });
1411 //
1412 // std::erase_if(m_elementList, [&](const auto& delElement) {
1413 // return delElement.get() == element;
1414 // });
1415 //
1416 // //m_elementList.erase(it);
1417 // //if (element) delete element;
1418 // menu->SetClientData(nullptr);
1419 // break;
1420 // }
1421 //}
1422 //SaveCurrentState();
1423
1424 // Remove child/parent.
1425 std::vector<Element*> childList = element->GetChildList();
1426 for (auto child : childList) {
1427 if (child) {
1428 child->RemoveParent(element);
1429 element->RemoveChild(child);
1430 }
1431 }
1432
1433 std::vector<Element*> parentList = element->GetParentList();
1434 for (auto parent : parentList) {
1435 if (parent)
1436 parent->RemoveChild(element);
1437 }
1438
1439 std::erase_if(m_textList, [&](const auto& text) {
1440 return text->GetElement() == element;
1441 });
1442
1443 std::erase_if(m_elementList, [&](const auto& delElement) {
1444 return delElement.get() == element;
1445 });
1446
1447 menu->SetClientData(nullptr);
1448 SaveCurrentState();
1449 } break;
1450 default:
1451 if (InsertTextElement(eventID, element)) {
1452 UpdateTextElements();
1453 SaveCurrentState();
1454 }
1455 break;
1456 }
1457 if (redrawHM && m_hmPlane && m_showHM) {
1458 m_hmPlane->Clear();
1459 m_showHMTimer = true;
1460 m_timerHeatMap->Start();
1461 }
1462}
@ ID_LINE_REMOVE_NODE
Definition Element.h:77
@ ID_DELETE
Definition Element.h:80
@ ID_ROTATE_CLOCK
Definition Element.h:78
@ ID_EDIT_ELEMENT
Definition Element.h:75
@ ID_ROTATE_COUNTERCLOCK
Definition Element.h:79
@ ID_LINE_ADD_NODE
Definition Element.h:76
virtual void Rotate(bool clockwise=true)
Rotate the element.
Definition Element.h:316

◆ OnResize()

void Workspace::OnResize ( wxSizeEvent &  event)
virtual

Definition at line 2771 of file Workspace.cpp.

2772{
2773 //m_width = static_cast<float>(m_glCanvas->GetSize().x) - 1.0f;
2774 //m_height = static_cast<float>(m_glCanvas->GetSize().y) - 1.0f;
2775 //
2776 //if (m_hmPlane && m_showHM) {
2777 // m_hmPlane->Resize(m_width, m_height);
2778 // m_showHMTimer = true;
2779 // m_timerHeatMap->Start();
2780 //}
2781 //
2782 //event.Skip();
2783 m_width = static_cast<float>(GetSize().x) - 1.0f;
2784 m_height = static_cast<float>(GetSize().y) - 1.0f;
2785
2786 if (m_hmPlane && m_showHM) {
2787 m_hmPlane->ResizeDC(m_width, m_height);
2788 m_showHMTimer = true;
2789 m_timerHeatMap->Start();
2790 }
2791
2792 event.Skip();
2793}

◆ OnRightClickDown()

void Workspace::OnRightClickDown ( wxMouseEvent &  event)
virtual

Definition at line 509 of file Workspace.cpp.

510{
511 bool redraw = false;
512 if (m_mode == WorkspaceMode::MODE_EDIT) {
513 for (auto& element : m_elementList) {
514 if (element->IsSelected()) {
515 // Show context menu.
516 if (element->Contains(m_camera->ScreenToWorld(event.GetPosition()))) {
517 element->ShowPickbox(false);
518 wxMenu menu;
519 menu.SetClientData(element.get());
520 if (element->GetContextMenu(menu)) {
521 m_timer->Stop();
522 menu.Bind(wxEVT_COMMAND_MENU_SELECTED, &Workspace::OnPopupClick, this);
523 PopupMenu(&menu);
524 redraw = true;
525
526 if (!menu.GetClientData()) break;
527 }
528 element->ResetPickboxes();
529 }
530 }
531 }
532 }
533 if (redraw) Redraw();
534 m_timer->Start();
535}

◆ OnScroll()

void Workspace::OnScroll ( wxMouseEvent &  event)
virtual

Definition at line 869 of file Workspace.cpp.

870{
871 if (event.GetWheelRotation() > 0)
872 m_camera->SetScale(event.GetPosition(), +0.05);
873 else
874 m_camera->SetScale(event.GetPosition(), -0.05);
875
876 if (m_hmPlane && m_showHM) {
877 m_hmPlane->Clear();
878 m_showHMTimer = true;
879 m_timerHeatMap->Start();
880 }
881
882 UpdateStatusBar();
883 Redraw();
884}

◆ OnTimer()

void Workspace::OnTimer ( wxTimerEvent &  event)
virtual

Definition at line 2418 of file Workspace.cpp.

2419{
2420 if (m_tipWindow) {
2421 m_tipWindow->Close();
2422 m_tipWindow = nullptr;
2423 }
2424 if (m_mode == WorkspaceMode::MODE_EDIT) {
2425 for (auto& element : m_elementList) {
2426 if (element->Contains(m_camera->GetMousePosition())) {
2427 wxString tipText = element->GetTipText();
2428 if (!tipText.IsEmpty()) {
2429 m_tipWindow = new wxTipWindow(this, tipText, 10000, &m_tipWindow);
2430 // Creates a very tiny bounding rect to remove the tip on any mouse movement.
2431 m_tipWindow->SetBoundingRect(wxRect(wxGetMousePosition(), wxSize(1, 1)));
2432 break;
2433 }
2434 }
2435 }
2436 }
2437
2438 m_timer->Stop();
2439}

◆ Paste()

bool Workspace::Paste ( )

Definition at line 2114 of file Workspace.cpp.

2115{
2116 if (wxTheClipboard->Open()) {
2117 ElementDataObject dataObject;
2118
2119 if (wxTheClipboard->IsSupported(dataObject.GetFormat())) {
2120 if (!wxTheClipboard->GetData(dataObject)) {
2121 wxMessageDialog dialog(this, _("It was not possible to paste from clipboard."), _("Error"),
2122 wxOK | wxCENTER | wxICON_ERROR, wxDefaultPosition);
2123 dialog.ShowModal();
2124 wxTheClipboard->Close();
2125 return false;
2126 }
2127 }
2128 else {
2129 wxTheClipboard->Close();
2130 return false;
2131 }
2132 wxTheClipboard->Close();
2133
2134 UnselectAll();
2135
2136 std::vector<Element*> pastedElements;
2137 ElementsLists* elementsLists = dataObject.GetElementsLists();
2138
2139 // Paste buses (parents).
2140 auto parentList = elementsLists->parentList;
2141 std::vector<Bus*> pastedBusList; // To set new parents;
2142 for (auto it = parentList.begin(), itEnd = parentList.end(); it != itEnd; ++it) {
2143 Element* copy = (*it)->GetCopy();
2144 if (copy) {
2145 pastedElements.push_back(copy);
2146 pastedBusList.push_back(static_cast<Bus*>(copy));
2147 m_elementList.emplace_back(static_cast<PowerElement*>(copy));
2148 }
2149 }
2150
2151 // Paste other elements.
2152 auto elementLists = elementsLists->elementList;
2153 for (auto it = elementLists.begin(), itEnd = elementLists.end(); it != itEnd; ++it) {
2154 Element* copy = (*it)->GetCopy();
2155 if (copy) {
2156 // Check if is text element
2157 if (Text* text = dynamic_cast<Text*>(copy)) {
2158 // Check if element associated with the text exists.
2159 bool elementExist = false;
2160 for (auto& element : m_elementList) {
2161 if (text->GetElement() == element.get()) {
2162 elementExist = true;
2163 break;
2164 }
2165 }
2166 if (elementExist) {
2167 pastedElements.push_back(copy);
2168 m_textList.emplace_back(text);
2169 }
2170 }
2171 else {
2172 // Change the parent if copied, otherwise remove it.
2173 for (size_t j = 0; j < copy->GetParentList().size(); j++) {
2174 Bus* currentParent = static_cast<Bus*>(copy->GetParentList()[j]);
2175 if (currentParent) {
2176 int parentID = currentParent->GetID();
2177 bool parentCopied = false;
2178 for (size_t k = 0; k < pastedBusList.size(); k++) {
2179 Bus* newParent = pastedBusList[k];
2180 if (parentID == newParent->GetID()) {
2181 parentCopied = true;
2182 copy->ReplaceParent(currentParent, newParent);
2183 break;
2184 }
2185 }
2186 if (!parentCopied) copy->RemoveParent(currentParent);
2187 }
2188 }
2189
2190 pastedElements.push_back(copy);
2191 m_elementList.emplace_back(static_cast<PowerElement*>(copy));
2192 }
2193 }
2194 }
2195
2196 // Update buses childs
2197 for (auto it = pastedBusList.begin(), itEnd = pastedBusList.end(); it != itEnd; ++it) {
2198 Bus* bus = *it;
2199 std::vector<Element*> childList = bus->GetChildList();
2200 for (auto it = childList.begin(), itEnd = childList.end(); it != itEnd; ++it) {
2201 Element* currentChild = *it;
2202 int childID = currentChild->GetID();
2203 bool childCopied = false;
2204 for (int i = 0; i < (int)pastedElements.size(); i++) {
2205 Element* newChild = pastedElements[i];
2206 if (childID == newChild->GetID()) {
2207 childCopied = true;
2208 bus->ReplaceChild(currentChild, newChild);
2209 break;
2210 }
2211 }
2212 if (!childCopied) bus->RemoveChild(currentChild);
2213 }
2214 }
2215
2216 // Move elements (and nodes) to the mouse position.
2217 // The start position it's the center of the pasted objects.
2218 wxPoint2DDouble leftUpCorner, rightDownCorner;
2219 GetElementsCorners(leftUpCorner, rightDownCorner, pastedElements);
2220 wxPoint2DDouble startPosition = (leftUpCorner + rightDownCorner) / 2.0;
2221 for (auto it = pastedElements.begin(), itEnd = pastedElements.end(); it != itEnd; ++it) {
2222 Element* element = *it;
2223 element->StartMove(startPosition);
2224 element->Move(m_camera->GetMousePosition());
2225 for (int i = 0; i < (int)element->GetParentList().size(); i++) {
2226 Element* parent = element->GetParentList()[i];
2227 element->MoveNode(parent, m_camera->GetMousePosition());
2228 }
2229 }
2230 }
2231 else {
2232 wxMessageDialog dialog(this, _("It was not possible to paste from clipboard."), _("Error"),
2233 wxOK | wxCENTER | wxICON_ERROR, wxDefaultPosition);
2234 dialog.ShowModal();
2235 return false;
2236 }
2237
2238 UpdateElementsID();
2239 m_mode = WorkspaceMode::MODE_PASTE;
2240 m_statusBar->SetStatusText(_("Click to paste."));
2241 UpdateStatusBar();
2242 Redraw();
2243 return true;
2244}
virtual Element * GetCopy()
Get a the element copy.
Definition Element.h:261
virtual int GetID() const
Get the element ID.
Definition Element.h:271
virtual void ReplaceParent(Element *oldParent, Element *newParent)
Replace a parent.
Definition Element.cpp:487
virtual void StartMove(wxPoint2DDouble position)
Update the element attributes related to the movement.
Definition Element.cpp:260
virtual void MoveNode(Element *parent, wxPoint2DDouble position)
Move a node. StartMove(wxPoint2DDouble position) before start moving.
Definition Element.h:346
virtual void Move(wxPoint2DDouble position)
Move the element other position.
Definition Element.cpp:266
virtual void ReplaceChild(Element *oldChild, Element *newChild)
Replace a child from the list.
Definition Element.cpp:503

◆ Redraw()

virtual void Workspace::Redraw ( )
inlinevirtual

Definition at line 149 of file Workspace.h.

149{ m_workspacePanel->Refresh(); }

◆ RemoveAllTextElements()

void Workspace::RemoveAllTextElements ( )

Definition at line 1888 of file Workspace.cpp.

1889{
1890 //for (auto* text : m_textList) {
1891 // if (text) delete text;
1892 //}
1893 m_textList.clear();
1894 SaveCurrentState();
1895}

◆ ResetAllVoltages()

void Workspace::ResetAllVoltages ( )

Definition at line 1975 of file Workspace.cpp.

1976{
1977 PowerFlow pf(GetElementList());
1978 pf.ResetVoltages();
1979 UpdateTextElements();
1980 Redraw();
1981}
Calculate the power flow.
Definition PowerFlow.h:36

◆ RotateSelectedElements()

void Workspace::RotateSelectedElements ( bool  clockwise = true)

Definition at line 1464 of file Workspace.cpp.

1465{
1466 bool saveCurrrentState = false;
1467 for (auto& element : m_elementList) {
1468 // Parent's element rotating...
1469 for (int i = 0; i < (int)element->GetParentList().size(); i++) {
1470 Element* parent = element->GetParentList()[i];
1471 if (parent) { // Check if parent is not null
1472 if (parent->IsSelected()) {
1473 element->RotateNode(parent, clockwise);
1474 // Update the positions used on motion action, the element will not be necessarily
1475 // moved.
1476 element->StartMove(m_camera->GetMousePosition());
1477 }
1478 }
1479 }
1480 if (element->IsSelected()) {
1481 saveCurrrentState = true;
1482 element->Rotate(clockwise);
1483 element->StartMove(m_camera->GetMousePosition());
1484 }
1485 }
1486
1487 // Rotate text element
1488 for (auto& text : m_textList) {
1489 if (text->IsSelected()) {
1490 saveCurrrentState = true;
1491 text->Rotate(clockwise);
1492 text->StartMove(m_camera->GetMousePosition());
1493 }
1494 }
1495 if (saveCurrrentState) SaveCurrentState();
1496
1497 if (m_hmPlane && m_showHM) {
1498 m_hmPlane->Clear();
1499 m_showHMTimer = true;
1500 m_timerHeatMap->Start();
1501 }
1502 Redraw();
1503}

◆ RunFault()

bool Workspace::RunFault ( )

Definition at line 2512 of file Workspace.cpp.

2513{
2514 auto simProp = m_properties->GetSimulationPropertiesData();
2515 double basePower = simProp.basePower;
2516 if (simProp.basePowerUnit == ElectricalUnit::UNIT_MVA)
2517 basePower *= 1e6;
2518 else if (simProp.basePowerUnit == ElectricalUnit::UNIT_kVA)
2519 basePower *= 1e3;
2520
2521 Fault fault(GetElementList());
2522 bool result = fault.RunFaultCalculation(basePower);
2523 if (!result) {
2524 wxMessageDialog msgDialog(this, fault.GetErrorMessage(), _("Error"), wxOK | wxCENTRE | wxICON_ERROR);
2525 msgDialog.ShowModal();
2526 }
2527
2528 UpdateTextElements();
2529 Redraw();
2530
2531 return result;
2532}
Calculate the fault of the system and update the elements data.
Definition Fault.h:31

◆ RunFrequencyResponse()

bool Workspace::RunFrequencyResponse ( )

Definition at line 2720 of file Workspace.cpp.

2721{
2722 // Get bus list
2723 std::vector<Bus*> busList;
2724 for (auto& element : m_elementList) {
2725 if (Bus* bus = dynamic_cast<Bus*>(element.get())) { busList.push_back(bus); }
2726 }
2727
2728 auto data = m_properties->GetFreqRespData();
2729
2730 FrequencyResponseForm frForm(this, busList, data.injBusNumber, data.initFreq, data.finalFreq, data.stepFreq);
2731
2732 if (frForm.ShowModal() == wxID_OK) {
2733 data.initFreq = frForm.GetInitFreq();
2734 data.finalFreq = frForm.GetEndFreq();
2735 data.stepFreq = frForm.GetStepFreq();
2736 data.injBusNumber = frForm.GetInjBusNumber();
2737 m_properties->SetFreqRespData(data);
2738 }
2739 else
2740 return false;
2741
2742 auto simProp = m_properties->GetSimulationPropertiesData();
2743 double basePower = simProp.basePower;
2744 if (simProp.basePowerUnit == ElectricalUnit::UNIT_MVA)
2745 basePower *= 1e6;
2746 else if (simProp.basePowerUnit == ElectricalUnit::UNIT_kVA)
2747 basePower *= 1e3;
2748 PowerQuality pq(GetElementList());
2749 bool result = pq.CalculateFrequencyResponse(simProp.stabilityFrequency, data.initFreq, data.finalFreq,
2750 data.stepFreq, data.injBusNumber, basePower, simProp.harmLoadConnection);
2751
2752 wxMessageDialog msgDialog(
2753 this, wxString::Format(_("Calculations done.\nDo you wish to open the frequency response graphics?")),
2754 _("Question"), wxYES_NO | wxCENTRE | wxICON_QUESTION);
2755 if (msgDialog.ShowModal() == wxID_YES) {
2756 std::vector<ElementPlotData> plotDataList;
2757 for (auto& element : m_elementList) {
2758 ElementPlotData plotData;
2759 if (element->GetPlotData(plotData, PlotStudy::FREQRESPONSE)) plotDataList.push_back(plotData);
2760 }
2761
2762 ChartView* cView = new ChartView(this, plotDataList, pq.GetFrequencies(), m_properties->GetGeneralPropertiesData().plotLib);
2763 cView->Show();
2764 }
2765
2766 UpdateTextElements();
2767 Redraw();
2768
2769 return result;
2770}
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 2646 of file Workspace.cpp.

2647{
2648 auto simProp = m_properties->GetSimulationPropertiesData();
2649 double basePower = simProp.basePower;
2650 if (simProp.basePowerUnit == ElectricalUnit::UNIT_MVA)
2651 basePower *= 1e6;
2652 else if (simProp.basePowerUnit == ElectricalUnit::UNIT_kVA)
2653 basePower *= 1e3;
2654 if (runPowerFlowBefore) {
2655 if (!RunPowerFlow(true)) return false;
2656 }
2657
2658 bool hasEMTElement = false;
2659 for (auto& element : m_elementList) {
2660 if (auto emtElement = dynamic_cast<EMTElement*>(element.get())) {
2661 if (emtElement->IsOnline()) hasEMTElement = true;
2662 }
2663 }
2664
2665 HarmLoadConnection loadConnection = simProp.harmLoadConnection;
2666
2667 PowerQuality pq(GetElementList());
2668 bool result = pq.CalculateDistortions(basePower, loadConnection);
2669
2670 // If has EMT element, repeat the Power Flow and Harmonics calculation untion DHT converge.
2671 if (hasEMTElement && result) {
2672 wxBusyInfo info(
2673 wxBusyInfoFlags()
2674 .Parent(this)
2675 .Icon(wxIcon(Paths::GetDataPath() + "/images/ribbon/harmDist32.png", wxBITMAP_TYPE_PNG))
2676 .Title(_("<b>Calculating Harmonic Flow</b>"))
2677 .Text(_("Please wait..."))
2678 .Foreground(*wxWHITE)
2679 .Background(*wxBLACK)
2680 .Transparency(4 * wxALPHA_OPAQUE / 5)
2681 );
2682 std::vector<double> thdList;
2683 for (auto const& bus : pq.GetBusList())
2684 thdList.emplace_back(bus->GetElectricalData().thd);
2685 double error = 1e3;
2686 while (error > 1e-3) {
2687 // Run Power Flow
2688 if (!RunPowerFlow(false, false)) return false;
2689
2690 // Run Harmonic Distortion
2691 bool result = pq.CalculateDistortions(basePower, loadConnection);
2692 if (!result) break;
2693
2694 // Calculate error
2695 int i = 0;
2696 for (auto const& bus : pq.GetBusList()) {
2697 double errorBus = std::abs(bus->GetElectricalData().thd - thdList[i]);
2698 if (i == 0)
2699 error = errorBus;
2700 else if (errorBus > error)
2701 error = errorBus;
2702 thdList[i] = bus->GetElectricalData().thd;
2703 i++;
2704 }
2705 }
2706 }
2707
2708 if (!result) {
2709 wxMessageDialog msgDialog(this, pq.GetErrorMessage(), _("Error"), wxOK | wxCENTRE | wxICON_ERROR);
2710 msgDialog.ShowModal();
2711 }
2712 else {
2713 UpdateTextElements();
2714 Redraw();
2715 }
2716
2717 return result;
2718}
Element to connect ATP-EMTP.
Definition EMTElement.h:65

◆ RunPowerFlow()

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

Definition at line 1983 of file Workspace.cpp.

1984{
1985 auto simProp = m_properties->GetSimulationPropertiesData();
1986 double basePower = simProp.basePower;
1987 if (simProp.basePowerUnit == ElectricalUnit::UNIT_MVA)
1988 basePower *= 1e6;
1989 else if (simProp.basePowerUnit == ElectricalUnit::UNIT_kVA)
1990 basePower *= 1e3;
1991
1992 // Update EMTElements
1993 for (auto& element : m_elementList) {
1994 if (auto emtElement = dynamic_cast<EMTElement*>(element.get())) {
1995 if (emtElement->IsOnline()) {
1996 emtElement->UpdateData(m_properties, true);
1997 }
1998 }
1999 }
2000 bool result = false;
2001 wxString errorMsg = "";
2002 int numIt = 0;
2003
2004 wxStopWatch sw;
2005 {
2006 wxBusyInfo* info = nullptr;
2007 if (showBusyInfo)
2008 info = new wxBusyInfo(
2009 wxBusyInfoFlags()
2010 .Parent(this)
2011 .Icon(wxIcon(Paths::GetDataPath() + "/images/ribbon/powerFLow32.png", wxBITMAP_TYPE_PNG))
2012 .Title(_("<b>Calculating Power Flow</b>"))
2013 .Text(_("Please wait..."))
2014 .Foreground(*wxWHITE)
2015 .Background(*wxBLACK)
2016 .Transparency(4 * wxALPHA_OPAQUE / 5)
2017 );
2018 //wxBusyInfo info
2019 //(
2020 // wxBusyInfoFlags()
2021 // .Parent(this)
2022 // .Icon(wxIcon(wxT("..\\data\\images\\ribbon\\powerFLow32.png"), wxBITMAP_TYPE_PNG))
2023 // .Title(_("<b>Calculating Power Flow</b>"))
2024 // .Text(_("Please wait..."))
2025 // .Foreground(*wxWHITE)
2026 // .Background(*wxBLACK)
2027 // .Transparency(4 * wxALPHA_OPAQUE / 5)
2028 //);
2029
2030 PowerFlow pf(GetElementList());
2031 if (resetVoltages) pf.ResetVoltages();
2032
2033 switch (simProp.powerFlowMethod) {
2034 case GAUSS_SEIDEL: {
2035 result = pf.RunGaussSeidel(basePower, simProp.powerFlowMaxIterations, simProp.powerFlowTolerance,
2036 simProp.initAngle, simProp.accFator);
2037 } break;
2038 case NEWTON_RAPHSON: {
2039 result = pf.RunNewtonRaphson(basePower, simProp.powerFlowMaxIterations, simProp.powerFlowTolerance,
2040 simProp.initAngle, simProp.newtonInertia);
2041 } break;
2042 case GAUSS_NEWTON: {
2043 result =
2044 pf.RunGaussNewton(basePower, simProp.powerFlowMaxIterations, simProp.powerFlowTolerance,
2045 simProp.initAngle, simProp.accFator, simProp.gaussTolerance, simProp.newtonInertia);
2046 } break;
2047 }
2048
2049 errorMsg = pf.GetErrorMessage();
2050 numIt = pf.GetIterations();
2051
2052 if (showBusyInfo) delete info;
2053 }
2054 sw.Pause();
2055
2056 if (!result) {
2057 wxMessageDialog msgDialog(this, errorMsg, _("Error"), wxOK | wxCENTRE | wxICON_ERROR);
2058 msgDialog.ShowModal();
2059 }
2060 else {
2061 m_statusBar->SetStatusText(
2062 wxString::Format(_("Power flow converge with %d iterations (%ld ms)"), numIt, sw.Time()));
2063 }
2064
2065 UpdateTextElements();
2066 UpdateHeatMap();
2067 Redraw();
2068
2069 return result;
2070}

◆ RunSCPower()

bool Workspace::RunSCPower ( )

Definition at line 2541 of file Workspace.cpp.

2542{
2543 Fault fault(GetElementList());
2544 bool result = fault.RunSCPowerCalcutation(100e6);
2545 if (!result) {
2546 wxMessageDialog msgDialog(this, fault.GetErrorMessage(), _("Error"), wxOK | wxCENTRE | wxICON_ERROR);
2547 msgDialog.ShowModal();
2548 }
2549
2550 UpdateTextElements();
2551 Redraw();
2552
2553 return result;
2554}

◆ RunStability()

bool Workspace::RunStability ( )

Definition at line 2556 of file Workspace.cpp.

2557{
2558 // Run power flow before stability.
2559 RunPowerFlow();
2560
2561 Electromechanical stability(this, GetElementList(), m_properties->GetSimulationPropertiesData());
2562 wxStopWatch sw;
2563 bool result = stability.RunStabilityCalculation();
2564#ifdef _DEBUG
2565#ifdef SHOW_DEBUG_PANEL
2566 m_debugFrame->AppendDebugMessage(stability.GetDebugMessage());
2567#endif
2568#endif // _DEBUG
2569
2570 sw.Pause();
2571 if (!result) {
2572 wxMessageDialog msgDialog(this, stability.GetErrorMessage(), _("Error"), wxOK | wxCENTRE | wxICON_ERROR);
2573 msgDialog.ShowModal();
2574 }
2575 m_stabilityTimeVector.clear();
2576 m_stabilityTimeVector = stability.GetTimeVector();
2577
2578 // Run power flow after stability.
2579 RunPowerFlow();
2580
2581 wxMessageDialog msgDialog(
2582 this,
2583 wxString::Format(_("The program took %ld ms to run this system.\nDo you wish to open the stability graphics?"),
2584 sw.Time()),
2585 _("Question"), wxYES_NO | wxCENTRE | wxICON_QUESTION);
2586 if (msgDialog.ShowModal() == wxID_YES) {
2587 std::vector<ElementPlotData> plotDataList;
2588 for (auto& element : m_elementList) {
2589 ElementPlotData plotData;
2590 if (element->GetPlotData(plotData)) plotDataList.push_back(plotData);
2591 }
2592#ifdef SHOW_SIMULATION_PARAMETERS
2593 ElementPlotData plotData;
2594 plotData.SetName(_("Simulation parameters"));
2595 plotData.SetCurveType(ElementPlotData::CurveType::CT_TEST);
2596 plotData.AddData(stability.GetIterationVector(), _("Iterations number"));
2597 plotDataList.push_back(plotData);
2598#endif
2599 ChartView* cView = new ChartView(this, plotDataList, m_stabilityTimeVector, m_properties->GetGeneralPropertiesData().plotLib);
2600 cView->Show();
2601 }
2602
2603 return result;
2604}
Calculates the electromechanical transient based on disturbances (e.g. system fault).

◆ RunStaticStudies()

bool Workspace::RunStaticStudies ( )

Definition at line 2611 of file Workspace.cpp.

2612{
2613 bool pfStatus, faultStatus, scStatus, harmStatus;
2614 pfStatus = faultStatus = scStatus = harmStatus = false;
2615
2616 bool runHarmDistortion = m_properties->GetSimulationPropertiesData().harmDistortionAfterPowerFlow;
2617
2618 pfStatus = RunPowerFlow(runHarmDistortion);
2619
2620 if (m_properties->GetSimulationPropertiesData().faultAfterPowerFlow) {
2621 if (pfStatus) faultStatus = RunFault();
2622 }
2623 else {
2624 faultStatus = true;
2625 }
2626
2627 if (m_properties->GetSimulationPropertiesData().scPowerAfterPowerFlow) {
2628 if (pfStatus) scStatus = RunSCPower();
2629 }
2630 else {
2631 scStatus = true;
2632 }
2633
2634 if (runHarmDistortion) {
2635 if (pfStatus) harmStatus = RunHarmonicDistortion(false);
2636 }
2637 else {
2638 harmStatus = true;
2639 }
2640
2641 if (pfStatus && faultStatus && scStatus && harmStatus) return true;
2642
2643 return false;
2644}

◆ SaveCurrentState()

void Workspace::SaveCurrentState ( )

Definition at line 2246 of file Workspace.cpp.

2247{
2248 // Setup current state
2249 std::vector< std::shared_ptr<PowerElement> > currentStateElementList;
2250 std::vector< std::shared_ptr<Text> > currentStateTextList;
2251
2252 GetStateListsCopy(m_elementList, m_textList, currentStateElementList, currentStateTextList);
2253
2254 // Delete all states after the current one
2255 //auto itE = m_elementListState.begin();
2256 //std::advance(itE, m_currenteState + 1);
2257 //for (; itE != m_elementListState.end(); ++itE) {
2258 // auto& elementList = *itE;
2259 // for (auto& element : elementList) delete element;
2260 // elementList.clear();
2261 //}
2262 m_elementListState.resize(m_currenteState + 1);
2263
2264 //auto itT = m_textListState.begin();
2265 //std::advance(itT, m_currenteState + 1);
2266 //for (; itT != m_textListState.end(); ++itT) {
2267 // auto& textList = *itT;
2268 // for (auto& text : textList) delete text;
2269 // textList.clear();
2270 //}
2271 m_textListState.resize(m_currenteState + 1);
2272
2273 m_currenteState++;
2274 if (m_currenteState >= m_maxStates) {
2275 m_currenteState = m_maxStates - 1;
2276 // Erase the first sate on the list
2277 //auto itE = m_elementListState.begin();
2279 //auto& elementList = *itE;
2281 //for (auto& element : elementList) delete element;
2282 //elementList.clear();
2285 //
2286 //m_elementListState.erase(itE);
2287 //m_textListState.erase(itT);
2288 m_elementListState.erase(m_elementListState.begin());
2289 m_textListState.erase(m_textListState.begin());
2290 }
2291
2292 m_elementListState.emplace_back(currentStateElementList);
2293 m_textListState.emplace_back(currentStateTextList);
2294
2295#ifdef _DEBUG
2296 wxString msg = "";
2297 wxString pointerStr;
2298 pointerStr.Printf("[%d S saved s%d] ", m_currenteState, m_elementListState.size());
2299 msg += pointerStr;
2300 for (auto& element : currentStateElementList) {
2301 pointerStr.Printf("%p ", element.get());
2302 msg += pointerStr;
2303 }
2304 msg += "\n";
2305 pointerStr.Printf("[%d S curr s%d] ", m_currenteState, m_elementListState.size());
2306 msg += pointerStr;
2307 for (auto& element : m_elementList) {
2308 pointerStr.Printf("%p ", element.get());
2309 msg += pointerStr;
2310 }
2311 msg += "\n";
2312 //m_debugFrame->AppendDebugMessage(msg);
2313#endif
2314}

◆ SetContinuousCalculationActive()

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

Definition at line 180 of file Workspace.h.

180{ m_continuousCalc = value; }

◆ SetElementList() [1/2]

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

Definition at line 2465 of file Workspace.cpp.

2466{
2467 m_elementList.clear();
2468 for (auto it = elementList.begin(), itEnd = elementList.end(); it != itEnd; ++it)
2469 m_elementList.emplace_back(static_cast<PowerElement*>(*it));
2470}

◆ SetElementList() [2/2]

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

Definition at line 2460 of file Workspace.cpp.

2461{
2462 m_elementList = std::move(elementList);
2463}

◆ SetJustOpened()

void Workspace::SetJustOpened ( bool  justOpened)
inline

Definition at line 147 of file Workspace.h.

147{ m_justOpened = justOpened; }

◆ SetName()

void Workspace::SetName ( wxString  name)

Definition at line 2450 of file Workspace.cpp.

2451{
2452 m_name = name;
2453#ifdef _DEBUG
2454#ifdef SHOW_DEBUG_PANEL
2455 m_debugFrame->SetTitle(_("Debug window: ") + m_name);
2456#endif
2457#endif
2458}

◆ SetNextState()

void Workspace::SetNextState ( )

Definition at line 2316 of file Workspace.cpp.

2317{
2318 m_currenteState++;
2319 if (m_currenteState >= 0 &&
2320 static_cast<size_t>(m_currenteState) < m_elementListState.size() &&
2321 static_cast<size_t>(m_currenteState) < m_textListState.size()) {
2322 //m_elementList = m_elementListState[m_currenteState];
2323 //m_textList = m_textListState[m_currenteState];
2324 GetStateListsCopy(m_elementListState[m_currenteState], m_textListState[m_currenteState], m_elementList, m_textList);
2325
2326#ifdef _DEBUG
2327#ifdef SHOW_DEBUG_PANEL
2328 wxString msg = "";
2329 wxString pointerStr;
2330 pointerStr.Printf("[%d N curr s%d] ", m_currenteState, m_elementListState.size());
2331 msg += pointerStr;
2332 for (Element* element : m_elementList) {
2333 pointerStr.Printf("%p ", element);
2334 msg += pointerStr;
2335 }
2336 msg += "\n";
2337 //m_debugFrame->AppendDebugMessage(msg);
2338#endif
2339#endif
2340
2341 UpdateTextElements();
2342 Redraw();
2343 }
2344 else {
2345 m_currenteState--;
2346 }
2347}

◆ SetPreviousState()

void Workspace::SetPreviousState ( )

Definition at line 2349 of file Workspace.cpp.

2350{
2351 m_currenteState--;
2352 if (m_currenteState >= 0) {
2353 //m_elementList = m_elementListState[m_currenteState];
2354 //m_textList = m_textListState[m_currenteState];
2355 GetStateListsCopy(m_elementListState[m_currenteState], m_textListState[m_currenteState], m_elementList, m_textList);
2356
2357#ifdef _DEBUG
2358#ifdef SHOW_DEBUG_PANEL
2359 wxString msg = "";
2360 wxString pointerStr;
2361 pointerStr.Printf("[%d P curr s%d] ", m_currenteState, m_elementListState.size());
2362 msg += pointerStr;
2363 for (Element* element : m_elementListState[m_currenteState]) {
2364 pointerStr.Printf("%p ", element);
2365 msg += pointerStr;
2366 }
2367 msg += "\n";
2368 pointerStr.Printf("[%d P list s%d] ", m_currenteState, m_elementListState.size());
2369 msg += pointerStr;
2370 for (Element* element : m_elementList) {
2371 pointerStr.Printf("%p ", element);
2372 msg += pointerStr;
2373 }
2374 msg += "\n";
2375 //m_debugFrame->AppendDebugMessage(msg);
2376#endif
2377#endif
2378
2379 UpdateTextElements();
2380 Redraw();
2381 }
2382 else {
2383 m_currenteState++;
2384 }
2385}

◆ SetSavedPath()

void Workspace::SetSavedPath ( wxFileName  savedPath)
inline

Definition at line 146 of file Workspace.h.

146{ m_savedPath = savedPath; }

◆ SetStatusBarText()

void Workspace::SetStatusBarText ( wxString  text)
inline

Definition at line 144 of file Workspace.h.

144{ m_statusBar->SetStatusText(text); }

◆ SetTextList()

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

Definition at line 2441 of file Workspace.cpp.

2442{
2443 //m_textList.clear();
2444 //for (auto it = textList.begin(), itEnd = textList.end(); it != itEnd; ++it) m_textList.push_back(*it);
2445 m_textList = std::move(textList);
2446
2447 UpdateTextElements();
2448}

◆ SetWorkspaceMode()

void Workspace::SetWorkspaceMode ( WorkspaceMode  mode)
inline

Definition at line 145 of file Workspace.h.

145{ m_mode = mode; }

◆ UnselectAll()

void Workspace::UnselectAll ( )

Definition at line 2387 of file Workspace.cpp.

2388{
2389 for (auto& element : m_elementList) {
2390 element->SetSelected(false);
2391 }
2392 for (auto& text : m_textList) {
2393 text->SetSelected(false);
2394 }
2395}

◆ UpdateElementsID()

void Workspace::UpdateElementsID ( )

Definition at line 2406 of file Workspace.cpp.

2407{
2408 int id = 0;
2409 for (auto& element : m_elementList) {
2410 element->SetID(id);
2411 id++;
2412 }
2413 for (auto& text : m_textList) {
2414 text->SetID(id);
2415 id++;
2416 }
2417}

◆ UpdateHeatMap()

void Workspace::UpdateHeatMap ( )

Definition at line 1271 of file Workspace.cpp.

1272{
1273 if (m_hmPlane && m_showHM) {
1274 m_hmPlane->Clear();
1275
1276 wxRect2DDouble screenRect(-100, -100, m_width + 200.0, m_height + 200.0);
1277
1278 // Get new voltage range
1279 std::vector<Bus*> busList;
1280 float minVoltage, maxVoltage;
1281 if (m_hmAutomaticLabel) {
1282 minVoltage = 10.0f;
1283 maxVoltage = 0.0f;
1284 }
1285 else {
1286 minVoltage = m_hmPlane->GetMinLimit();
1287 maxVoltage = m_hmPlane->GetMaxLimit();
1288 }
1289
1290 for (auto& element : m_elementList) {
1291 if (Bus* bus = dynamic_cast<Bus*>(element.get())) {
1292 if (m_hmAutomaticLabel) {
1293 const float voltage = std::abs(bus->GetElectricalData().voltage);
1294 if (minVoltage > voltage) minVoltage = voltage;
1295 if (maxVoltage < voltage) maxVoltage = voltage;
1296 }
1297 busList.push_back(bus);
1298 }
1299 }
1300 if (m_hmAutomaticLabel) {
1301 m_hmPlane->SetLabelLimits(minVoltage, maxVoltage);
1302 }
1303
1304 for (Bus* bus : busList) {
1305 const float voltage = std::abs(bus->GetElectricalData().voltage);
1306 float depth = 2.0f * (voltage - (maxVoltage + minVoltage) / 2.0f) / (maxVoltage - minVoltage);
1307 if (depth < -1.0) depth = -1.0;
1308 if (depth > 1.0) depth = 1.0;
1309
1310 wxRect2DDouble rect = bus->GetRect();
1311 rect = wxRect2DDouble(
1312 (rect.m_x - 100.0f) * m_camera->GetScale() + m_camera->GetTranslation().m_x * m_camera->GetScale(),
1313 (rect.m_y - 50.0f) * m_camera->GetScale() + m_camera->GetTranslation().m_y * m_camera->GetScale(),
1314 (rect.m_width + 200.0f) * m_camera->GetScale(),
1315 (rect.m_height + 100.0f) * m_camera->GetScale());
1316
1317 if (screenRect.Contains(rect))
1318 m_hmPlane->SetRectSlope(rect, M_PI * static_cast<float>(bus->GetAngle()) / 180.0f, depth);
1319 }
1320
1321 //m_hmPlane->UpdateCoords();
1322
1323 //int iterations = std::lround(3.3 * std::pow(m_camera->GetScale(), 0.62));
1324 int iterations = std::lround(10 * std::pow(m_camera->GetScale(), 2));
1325 //int iterations = std::lround(1 * std::pow(m_camera->GetScale(), 0.2));
1326 //int iterations = 1;
1327 if (iterations < 1) iterations = 1;
1328 m_hmPlane->SmoothPlane(iterations);
1329 }
1330}

◆ UpdateStatusBar()

void Workspace::UpdateStatusBar ( )
protected

Definition at line 1167 of file Workspace.cpp.

1168{
1169 switch (m_mode) {
1170 case WorkspaceMode::MODE_DRAG: {
1171 m_statusBar->SetStatusText(_("MODE: DRAG"), 1);
1172 } break;
1173
1174 case WorkspaceMode::MODE_PASTE:
1175 case WorkspaceMode::MODE_DRAG_PASTE: {
1176 m_statusBar->SetStatusText(_("MODE: PASTE"), 1);
1177 } break;
1178
1179 case WorkspaceMode::MODE_INSERT:
1180 case WorkspaceMode::MODE_INSERT_TEXT:
1181 case WorkspaceMode::MODE_DRAG_INSERT:
1182 case WorkspaceMode::MODE_DRAG_INSERT_TEXT: {
1183 m_statusBar->SetStatusText(_("MODE: INSERT"), 1);
1184 } break;
1185
1186 case WorkspaceMode::MODE_MOVE_ELEMENT:
1187 case WorkspaceMode::MODE_MOVE_PICKBOX:
1188 case WorkspaceMode::MODE_MOVE_NODE:
1189 case WorkspaceMode::MODE_SELECTION_RECT:
1190 case WorkspaceMode::MODE_EDIT: {
1191 if (m_oldStatusMode != m_mode)
1192 m_statusBar->SetStatusText(wxT(""));
1193 m_statusBar->SetStatusText(_("MODE: EDIT"), 1);
1194 } break;
1195 }
1196
1197 m_statusBar->SetStatusText(wxString::Format(_("ZOOM: %d%%"), (int)(m_camera->GetScale() * 100.0)), 2);
1198 m_statusBar->SetStatusText(
1199 wxString::Format(wxT("X: %.1f Y: %.1f"), m_camera->GetMousePosition().m_x, m_camera->GetMousePosition().m_y),
1200 3);
1201 m_oldStatusMode = m_mode;
1202}

◆ UpdateTextElements()

bool Workspace::UpdateTextElements ( )

Definition at line 2072 of file Workspace.cpp.

2073{
2074 bool isTexturesOK = true;
2075 double basePower = m_properties->GetSimulationPropertiesData().basePower;
2076 if (m_properties->GetSimulationPropertiesData().basePowerUnit == ElectricalUnit::UNIT_kVA)
2077 basePower *= 1e3;
2078 else if (m_properties->GetSimulationPropertiesData().basePowerUnit == ElectricalUnit::UNIT_MVA)
2079 basePower *= 1e6;
2080 for (auto& text : m_textList) {
2081 text->SetFontName(m_properties->GetGeneralPropertiesData().labelFont);
2082 text->SetFontSize(m_properties->GetGeneralPropertiesData().labelFontSize);
2083 text->UpdateText(basePower);
2084 //if (!text->IsGLTextOK()) isTexturesOK = false;
2085 }
2086 return isTexturesOK;
2087}

◆ ValidateBusesVoltages()

void Workspace::ValidateBusesVoltages ( Element initialBus)

Definition at line 1927 of file Workspace.cpp.

1928{
1929 double nominalVoltage = static_cast<Bus*>(initialBus)->GetElectricalData().nominalVoltage;
1930 ElectricalUnit nominalVoltageUnit = static_cast<Bus*>(initialBus)->GetElectricalData().nominalVoltageUnit;
1931
1932 for (auto it = m_elementList.begin(); it != m_elementList.end(); it++) {
1933 Element* child = it->get();
1934
1935 if (auto line = dynamic_cast<Line*>(child)) {
1936 if (line->GetParentList()[0] && line->GetParentList()[1]) {
1937 BusElectricalData data1 = static_cast<Bus*>(line->GetParentList()[0])->GetElectricalData();
1938 BusElectricalData data2 = static_cast<Bus*>(line->GetParentList()[1])->GetElectricalData();
1939
1940 if (data1.nominalVoltage != data2.nominalVoltage ||
1941 data1.nominalVoltageUnit != data2.nominalVoltageUnit) {
1942 data1.nominalVoltage = nominalVoltage;
1943 data2.nominalVoltage = nominalVoltage;
1944 data1.nominalVoltageUnit = nominalVoltageUnit;
1945 data2.nominalVoltageUnit = nominalVoltageUnit;
1946
1947 static_cast<Bus*>(line->GetParentList()[0])->SetElectricalData(data1);
1948 static_cast<Bus*>(line->GetParentList()[1])->SetElectricalData(data2);
1949
1950 it = m_elementList.begin(); // Restart search.
1951 }
1952 }
1953 }
1954 }
1955
1956 // ValidateElementsVoltages();
1957}
ElectricalUnit
Electrical units.

◆ ValidateElementsVoltages()

void Workspace::ValidateElementsVoltages ( )

Definition at line 1959 of file Workspace.cpp.

1960{
1961 for (auto& child : m_elementList) {
1962 std::vector<double> nominalVoltage;
1963 std::vector<ElectricalUnit> nominalVoltageUnit;
1964 for (int i = 0; i < (int)child->GetParentList().size(); i++) {
1965 Bus* parent = static_cast<Bus*>(child->GetParentList()[i]);
1966 if (parent) {
1967 nominalVoltage.push_back(parent->GetElectricalData().nominalVoltage);
1968 nominalVoltageUnit.push_back(parent->GetElectricalData().nominalVoltageUnit);
1969 }
1970 }
1971 child->SetNominalVoltage(nominalVoltage, nominalVoltageUnit);
1972 }
1973}
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 222 of file Workspace.h.

◆ m_camera

Camera* Workspace::m_camera = nullptr
protected

Definition at line 223 of file Workspace.h.

◆ m_continuousCalc

bool Workspace::m_continuousCalc = false
protected

Definition at line 253 of file Workspace.h.

◆ m_currenteState

int Workspace::m_currenteState = -1
protected

Definition at line 241 of file Workspace.h.

◆ m_disconnectedElement

bool Workspace::m_disconnectedElement = false
protected

Definition at line 254 of file Workspace.h.

◆ m_elementList

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

Definition at line 231 of file Workspace.h.

◆ m_elementListState

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

Definition at line 238 of file Workspace.h.

◆ m_elementNumber

int Workspace::m_elementNumber[NUM_ELEMENTS]
protected

Definition at line 232 of file Workspace.h.

◆ m_height

float Workspace::m_height = 0.0
protected

Definition at line 258 of file Workspace.h.

◆ m_hmAutomaticLabel

bool Workspace::m_hmAutomaticLabel = false
protected

Definition at line 267 of file Workspace.h.

◆ m_hmPlane

HMPlane* Workspace::m_hmPlane = nullptr
protected

Definition at line 261 of file Workspace.h.

◆ m_justOpened

bool Workspace::m_justOpened = false
protected

Definition at line 255 of file Workspace.h.

◆ m_maxStates

int Workspace::m_maxStates = 100
protected

Definition at line 242 of file Workspace.h.

◆ m_mode

WorkspaceMode Workspace::m_mode = WorkspaceMode::MODE_EDIT
protected

Definition at line 227 of file Workspace.h.

◆ m_name

wxString Workspace::m_name
protected

Definition at line 225 of file Workspace.h.

◆ m_oldStatusMode

WorkspaceMode Workspace::m_oldStatusMode = WorkspaceMode::MODE_EDIT
protected

Definition at line 228 of file Workspace.h.

◆ m_properties

PropertiesData* Workspace::m_properties = nullptr
protected

Definition at line 249 of file Workspace.h.

◆ m_savedPath

wxFileName Workspace::m_savedPath
protected

Definition at line 244 of file Workspace.h.

◆ m_selectionRect

wxRect2DDouble Workspace::m_selectionRect
protected

Definition at line 246 of file Workspace.h.

◆ m_showHM

bool Workspace::m_showHM = false
protected

Definition at line 265 of file Workspace.h.

◆ m_showHMTimer

bool Workspace::m_showHMTimer = false
protected

Definition at line 266 of file Workspace.h.

◆ m_stabilityTimeVector

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

Definition at line 251 of file Workspace.h.

◆ m_startSelRect

wxPoint2DDouble Workspace::m_startSelRect
protected

Definition at line 247 of file Workspace.h.

◆ m_statusBar

wxStatusBar* Workspace::m_statusBar = nullptr
protected

Definition at line 221 of file Workspace.h.

◆ m_textList

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

Definition at line 235 of file Workspace.h.

◆ m_textListState

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

Definition at line 240 of file Workspace.h.

◆ m_tipWindow

wxTipWindow* Workspace::m_tipWindow = nullptr
protected

Definition at line 224 of file Workspace.h.

◆ m_width

float Workspace::m_width = 0.0
protected

Definition at line 257 of file Workspace.h.


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