Power System Platform  2026w34a-beta
Loading...
Searching...
No Matches
Text.cpp
1/*
2 * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <https://www.gnu.org/licenses/>.
16 */
17
18#include "Text.h"
19
20#include "../forms/TextForm.h"
21
22#include "../simulation/ElectricCalculation.h"
23
24#include "../editors/Workspace.h"
25
26#include "powerElement/Bus.h"
30#include "powerElement/Line.h"
31#include "powerElement/Load.h"
35
36#ifdef USING_WX_3_0_X
37#include "../utils/DegreesAndRadians.h"
38#endif
39
40Text::Text() : GraphicalElement()
41{
42 m_elementType = TYPE_TEXT;
43 SetText(m_text);
44 m_inserted = true;
45}
46Text::Text(wxPoint2DDouble position, wxString fontName, int fontSize) : GraphicalElement()
47{
48 m_elementType = TYPE_TEXT;
49 m_position = position;
50 m_fontName = fontName;
51 m_fontSize = fontSize;
52 SetText(m_text);
53 m_inserted = true;
54}
55
56Text::~Text()
57{
58 //for (auto& openGLText : m_openGLTextList) {
59 // if (openGLText) delete openGLText;
60 //}
61 //m_openGLTextList.clear();
62
63 for (auto& gcText : m_gcTextList) {
64 if (gcText) delete gcText;
65 }
66 m_gcTextList.clear();
67}
68
69bool Text::Contains(wxPoint2DDouble position) const
70{
71 wxPoint2DDouble ptR = RotateAtPosition(position, -m_angle);
72 return m_rect.Contains(ptR);
73}
74
75//void Text::Draw(wxPoint2DDouble translation, double scale)
76//{
77// // Draw selection rectangle
78//
79// // Push the current matrix on stack.
80// glPushMatrix();
81// // Rotate the matrix around the object position.
82// glTranslated(m_position.m_x, m_position.m_y, 0.0);
83// glRotated(m_angle, 0.0, 0.0, 1.0);
84// glTranslated(-m_position.m_x, -m_position.m_y, 0.0);
85//
86// if (m_selected) {
87// if (m_useAltSelectionColour) glColor4d(0.0, 0.8, 0.0, 0.5);
88// else glColor4d(0.0, 0.5, 1.0, 0.5);
89// DrawRectangle(m_position + wxPoint2DDouble(m_borderSize / 2.0, m_borderSize / 2.0), m_rect.m_width,
90// m_rect.m_height);
91// }
92//
93// // Draw text (layer 2)
94// glColor4d(0.0, 0.0, 0.0, 1.0);
95// if (m_isMultlineText) {
96// for (unsigned int i = 0; i < m_openGLTextList.size(); ++i) {
97// m_openGLTextList[i]->Draw(
98// m_position +
99// wxPoint2DDouble(0.0, (m_height * static_cast<double>(i) / static_cast<double>(m_numberOfLines)) -
100// (m_height * static_cast<double>(m_numberOfLines - 1) /
101// static_cast<double>(2 * m_numberOfLines))));
102// }
103// }
104// else if (m_openGLTextList.size() > 0) {
105// m_openGLTextList[0]->Draw(m_position);
106// }
107// glPopMatrix();
108//}
109
110void Text::DrawDC(GUIColour* guiColour, wxPoint2DDouble translation, double scale, wxGraphicsContext* gc)
111{
112 // Update text extent using correct context
113 if (m_updateTextRectangle) {
114 for (GCText* gcText : m_gcTextList) {
115 if (gcText) delete gcText;
116 }
117 m_gcTextList.clear();
118
119 m_numberOfLines = m_text.Freq('\n') + 1;
120 m_isMultlineText = m_numberOfLines > 1;
121 m_width = 0.0;
122 m_height = 0.0;
123 wxFont font = wxFont(m_fontSize,
124 wxFONTFAMILY_DEFAULT,
125 wxFONTSTYLE_NORMAL,
126 wxFONTWEIGHT_NORMAL,
127 false,
128 m_fontName);
129 gc->SetFont(font, guiColour->text);
130
131 wxString multText = m_text;
132 for (int i = 0; i < m_numberOfLines; ++i) {
133 wxString nextLine;
134 wxString currentLine = multText.BeforeFirst('\n', &nextLine);
135 multText = nextLine;
136
137 double w, h;
138 gc->GetTextExtent(currentLine, &w, &h);
139
140 if (w > m_width) m_width = w;
141 m_height += h;
142
143 GCText* gcText = new GCText();
144 gcText->SetFont(font);
145 gcText->SetText(currentLine, wxSize(static_cast<int>(w), static_cast<int>(h)));
146 m_gcTextList.push_back(gcText);
147 }
148 SetPosition(m_position); // Update element rectangle.
149 m_updateTextRectangle = false;
150 }
151
152 // Draw selection rectangle
153
154 // Push the current matrix on stack.
155 gc->PushState();
156 // Rotate the matrix around the object position.
157 gc->Translate(m_position.m_x, m_position.m_y);
158 gc->Rotate(wxDegToRad(m_angle));
159 gc->Translate(-m_position.m_x, -m_position.m_y);
160
161 if (m_selected) {
162 //glColor4d(0.0, 0.5, 1.0, 0.5);
163 gc->SetPen(*wxTRANSPARENT_PEN);
164 if (m_useAltSelectionColour) gc->SetBrush(wxBrush(guiColour->altSelection));
165 else gc->SetBrush(wxBrush(guiColour->selection));
166
167 wxPoint2DDouble pos = m_position - wxPoint2DDouble(m_borderSize / 2.0 + m_width / 2, m_borderSize / 2.0 + m_height / 2);
168 gc->DrawRectangle(pos.m_x, pos.m_y, m_rect.m_width, m_rect.m_height);
169 }
170
171 // Draw text (layer 2)
172 //gc->SetPen(wxPen(wxColour(0, 0, 0, 255)));
173 //gc->SetBrush(*wxTRANSPARENT_BRUSH);
174 wxPoint2DDouble pos = m_position - wxPoint2DDouble(m_width / 2, m_height / 2);
175 if (m_isMultlineText) {
176 for (unsigned int i = 0; i < m_gcTextList.size(); ++i) {
177 m_gcTextList[i]->Draw(
178 pos +
179 wxPoint2DDouble(0.0, (m_height * static_cast<double>(i) / static_cast<double>(m_numberOfLines))), gc, 0, guiColour->text);
180 }
181 }
182 else if (m_gcTextList.size() > 0) {
183 m_gcTextList[0]->Draw(pos, gc, 0, guiColour->text);
184 }
185 gc->PopState();
186}
187
188void Text::DrawDC(GUIColour* guiColour, wxPoint2DDouble translation, double scale, wxDC& dc)
189{
190 // Update text extent using correct context
191 if (m_updateTextRectangle) {
192 for (GCText* gcText : m_gcTextList) {
193 if (gcText) delete gcText;
194 }
195 m_gcTextList.clear();
196
197 m_numberOfLines = m_text.Freq('\n') + 1;
198 m_isMultlineText = m_numberOfLines > 1;
199 m_width = 0.0;
200 m_height = 0.0;
201 wxFont font = wxFont(m_fontSize,
202 wxFONTFAMILY_DEFAULT,
203 wxFONTSTYLE_NORMAL,
204 wxFONTWEIGHT_NORMAL,
205 false,
206 m_fontName);
207 dc.SetFont(font);
208
209 wxString multText = m_text;
210 for (int i = 0; i < m_numberOfLines; ++i) {
211 wxString nextLine;
212 wxString currentLine = multText.BeforeFirst('\n', &nextLine);
213 multText = nextLine;
214
215 wxSize txtSize = dc.GetTextExtent(currentLine);
216
217 if (txtSize.GetWidth() > m_width) m_width = txtSize.GetWidth();
218 m_height += txtSize.GetHeight();
219
220 GCText* gcText = new GCText();
221 gcText->SetFont(font);
222 gcText->SetText(currentLine, txtSize);
223 m_gcTextList.push_back(gcText);
224 }
225 SetPosition(m_position); // Update element rectangle.
226 m_updateTextRectangle = false;
227 }
228
229 // Draw selection rectangle
230 if (m_selected) {
231 dc.SetPen(*wxTRANSPARENT_PEN);
232 if (m_useAltSelectionColour) dc.SetBrush(wxBrush(guiColour->altSelection));
233 else dc.SetBrush(wxBrush(guiColour->selection));
234
235 DrawDCRectangle(m_position, m_rect.m_width, m_rect.m_height, m_angle, dc);
236 }
237
238 // Draw text (layer 2)
239 //wxPoint2DDouble pos = m_position - wxPoint2DDouble(m_width / 2, m_height / 2);
240 if (m_isMultlineText) {
241 for (unsigned int i = 0; i < m_gcTextList.size(); ++i) {
242 m_gcTextList[i]->Draw(
243 m_position +
244 wxPoint2DDouble(0.0, (m_height * static_cast<double>(i) / static_cast<double>(m_numberOfLines))), m_width, m_height, dc, m_angle);
245 }
246 }
247 else if (m_gcTextList.size() > 0) {
248 m_gcTextList[0]->Draw(m_position, m_width, m_height, dc, m_angle, guiColour->text);
249 }
250}
251
252bool Text::Intersects(wxRect2DDouble rect) const
253{
254 if (m_angle == 0.0 || m_angle == 180.0) return m_rect.Intersects(rect);
255 return RotatedRectanglesIntersects(m_rect, rect, m_angle, 0.0);
256}
257
258void Text::SetText(wxString text)
259{
260 if (m_text == text) return;
261
262 m_text = text;
263 m_updateTextRectangle = true;
264}
265
266void Text::Rotate(bool clockwise)
267{
268 if (!m_allowRotation) return;
269
270 double rotAngle = m_rotationAngle;
271 if (!clockwise) rotAngle = -m_rotationAngle;
272
273 m_angle += rotAngle;
274 if (m_angle >= 360 || m_angle <= -360) m_angle = 0.0;
275}
276
277bool Text::ShowForm(wxWindow* parent, std::vector<Element*> elementList, wxWindow* workspace)
278{
279 Workspace* ws = dynamic_cast<Workspace*>(workspace);
280 if (!ws) return false;
281 double systemPowerBase = ws->GetProperties()->GetSimulationPropertiesData().basePower;
282 if (ws->GetProperties()->GetSimulationPropertiesData().basePowerUnit == ElectricalUnit::UNIT_MVA)
283 systemPowerBase *= 1e6;
284 else if (ws->GetProperties()->GetSimulationPropertiesData().basePowerUnit == ElectricalUnit::UNIT_kVA)
285 systemPowerBase *= 1e3;
286
287 TextForm textForm(parent, this, elementList, systemPowerBase);
288 if (textForm.ShowModal() == wxID_OK) {
289 return true;
290 }
291 return false;
292}
293
294void Text::UpdateText(double systemPowerBase)
295{
296 switch (m_elementTypeText) {
297 case TYPE_NONE:
298 SetText(m_text);
299 break;
300 case TYPE_BUS: {
301 Bus* bus = static_cast<Bus*>(m_element);
302 if (bus) {
303 BusElectricalData data = bus->GetElectricalData();
304 double baseVoltage = data.nominalVoltage;
305 if (data.nominalVoltageUnit == ElectricalUnit::UNIT_kV) baseVoltage *= 1e3;
306 double baseCurrent = systemPowerBase / (std::sqrt(3.0) * baseVoltage);
307
308 switch (m_dataType) {
309 case DATA_NAME: {
310 SetText(bus->GetElectricalData().name);
311 } break;
312 case DATA_VOLTAGE: {
313 double voltage = std::abs(data.voltage);
314 switch (m_unit) {
315 case ElectricalUnit::UNIT_PU: {
316 SetText(wxString::FromDouble(voltage, m_decimalPlaces) + " p.u.");
317 } break;
318 case ElectricalUnit::UNIT_V: {
319 SetText(wxString::FromDouble(voltage * baseVoltage, m_decimalPlaces) + " V");
320 } break;
321 case ElectricalUnit::UNIT_kV: {
322 SetText(wxString::FromDouble(voltage * baseVoltage / 1e3, m_decimalPlaces) + " kV");
323 } break;
324 default:
325 break;
326 }
327 } break;
328 case DATA_ANGLE: {
329 double angle = std::arg(data.voltage);
330 switch (m_unit) {
331 case ElectricalUnit::UNIT_RADIAN: {
332 SetText(wxString::FromDouble(angle, m_decimalPlaces) + " rad");
333 } break;
334 case ElectricalUnit::UNIT_DEGREE: {
335 SetText(wxString::FromDouble(wxRadToDeg(angle), m_decimalPlaces) + (wxString)L'\u00B0');
336 } break;
337 default:
338 break;
339 }
340 } break;
341 case DATA_SC_CURRENT: {
342 double faultCurrent[3] = { std::abs(data.faultCurrent[0]), std::abs(data.faultCurrent[1]),
343 std::abs(data.faultCurrent[2]) };
344 switch (m_unit) {
345 case ElectricalUnit::UNIT_PU: {
346 wxString str =
347 "Ia = " + wxString::FromDouble(faultCurrent[0], m_decimalPlaces) + " p.u.";
348 str += "\nIb = " + wxString::FromDouble(faultCurrent[1], m_decimalPlaces) + " p.u.";
349 str += "\nIc = " + wxString::FromDouble(faultCurrent[2], m_decimalPlaces) + " p.u.";
350 SetText(str);
351 } break;
352 case ElectricalUnit::UNIT_A: {
353 wxString str =
354 "Ia = " + wxString::FromDouble(faultCurrent[0] * baseCurrent, m_decimalPlaces) +
355 " A";
356 str += "\nIb = " +
357 wxString::FromDouble(faultCurrent[1] * baseCurrent, m_decimalPlaces) + " A";
358 str += "\nIc = " +
359 wxString::FromDouble(faultCurrent[2] * baseCurrent, m_decimalPlaces) + " A";
360 SetText(str);
361 } break;
362 case ElectricalUnit::UNIT_kA: {
363 wxString str =
364 "Ia = " +
365 wxString::FromDouble(faultCurrent[0] * baseCurrent / 1e3, m_decimalPlaces) + " kA";
366 str += "\nIb = " +
367 wxString::FromDouble(faultCurrent[1] * baseCurrent / 1e3, m_decimalPlaces) +
368 " kA";
369 str += "\nIc = " +
370 wxString::FromDouble(faultCurrent[2] * baseCurrent / 1e3, m_decimalPlaces) +
371 " kA";
372 SetText(str);
373 } break;
374 default:
375 break;
376 }
377 } break;
378 case DATA_SC_VOLTAGE: {
379 double faultVoltage[3] = { std::abs(data.faultVoltage[0]), std::abs(data.faultVoltage[1]),
380 std::abs(data.faultVoltage[2]) };
381 switch (m_unit) {
382 case ElectricalUnit::UNIT_PU: {
383 wxString str =
384 "Va = " + wxString::FromDouble(faultVoltage[0], m_decimalPlaces) + " p.u.";
385 str += "\nVb = " + wxString::FromDouble(faultVoltage[1], m_decimalPlaces) + " p.u.";
386 str += "\nVc = " + wxString::FromDouble(faultVoltage[2], m_decimalPlaces) + " p.u.";
387 SetText(str);
388 } break;
389 case ElectricalUnit::UNIT_V: {
390 wxString str =
391 "Va = " + wxString::FromDouble(faultVoltage[0] * baseVoltage, m_decimalPlaces) +
392 " V";
393 str += "\nVb = " +
394 wxString::FromDouble(faultVoltage[1] * baseVoltage, m_decimalPlaces) + " V";
395 str += "\nVc = " +
396 wxString::FromDouble(faultVoltage[2] * baseVoltage, m_decimalPlaces) + " V";
397 SetText(str);
398 } break;
399 case ElectricalUnit::UNIT_kV: {
400 wxString str =
401 "Va = " +
402 wxString::FromDouble(faultVoltage[0] * baseVoltage / 1e3, m_decimalPlaces) + " kV";
403 str += "\nVb = " +
404 wxString::FromDouble(faultVoltage[1] * baseVoltage / 1e3, m_decimalPlaces) +
405 " kV";
406 str += "\nVc = " +
407 wxString::FromDouble(faultVoltage[2] * baseVoltage / 1e3, m_decimalPlaces) +
408 " kV";
409 SetText(str);
410 } break;
411 default:
412 break;
413 }
414 } break;
415 case DATA_SC_POWER: {
416 double scPower = data.scPower;
417 if (!data.isConnected) scPower = 0.0;
418 switch (m_unit) {
419 case ElectricalUnit::UNIT_PU: {
420 SetText(wxString::FromDouble(scPower, m_decimalPlaces) + " p.u.");
421 } break;
422 case ElectricalUnit::UNIT_VA: {
423 SetText(wxString::FromDouble(scPower * systemPowerBase, m_decimalPlaces) + " VA");
424 } break;
425 case ElectricalUnit::UNIT_kVA: {
426 SetText(wxString::FromDouble(scPower * systemPowerBase / 1e3, m_decimalPlaces) +
427 " kVA");
428 } break;
429 case ElectricalUnit::UNIT_MVA: {
430 SetText(wxString::FromDouble(scPower * systemPowerBase / 1e6, m_decimalPlaces) +
431 " MVA");
432 } break;
433 default:
434 break;
435 }
436 } break;
437 case DATA_PQ_THD: {
438 SetText(_("THD = ") + wxString::FromDouble(data.thd, m_decimalPlaces) + "%");
439 } break;
440 default:
441 break;
442 }
443 }
444 } break;
445 case TYPE_SYNC_GENERATOR: {
446 SyncGenerator* syncGenerator = static_cast<SyncGenerator*>(m_element);
447 if (syncGenerator) {
448 SyncGeneratorElectricalData data = syncGenerator->GetPUElectricalData(systemPowerBase);
449 double baseVoltage = syncGenerator->GetValueFromUnit(data.nominalVoltage, data.nominalVoltageUnit);
450 double baseCurrent = systemPowerBase / (std::sqrt(3.0) * baseVoltage);
451 bool busParentOnline = false;
452 auto parentList = syncGenerator->GetParentList();
453 if (parentList.size() == 1) {
454 Bus* busParent = dynamic_cast<Bus*>(parentList[0]);
455 if (busParent) busParentOnline = busParent->GetElectricalData().isConnected;
456 }
457 switch (m_dataType) {
458 case DATA_NAME: {
459 SetText(data.name);
460 } break;
461 case DATA_ACTIVE_POWER: {
462 double activePower = data.activePower;
463 if (!syncGenerator->IsOnline() || !busParentOnline) activePower = 0.0;
464 switch (m_unit) {
465 case ElectricalUnit::UNIT_PU: {
466 SetText(wxString::FromDouble(activePower, m_decimalPlaces) + " p.u.");
467 } break;
468 case ElectricalUnit::UNIT_W: {
469 SetText(wxString::FromDouble(activePower * systemPowerBase, m_decimalPlaces) + " W");
470 } break;
471 case ElectricalUnit::UNIT_kW: {
472 SetText(wxString::FromDouble(activePower * systemPowerBase / 1e3, m_decimalPlaces) +
473 " kW");
474 } break;
475 case ElectricalUnit::UNIT_MW: {
476 SetText(wxString::FromDouble(activePower * systemPowerBase / 1e6, m_decimalPlaces) +
477 " MW");
478 } break;
479 default:
480 break;
481 }
482 } break;
483 case DATA_REACTIVE_POWER: {
484 double reactivePower = data.reactivePower;
485 if (!syncGenerator->IsOnline() || !busParentOnline) reactivePower = 0.0;
486 switch (m_unit) {
487 case ElectricalUnit::UNIT_PU: {
488 SetText(wxString::FromDouble(reactivePower, m_decimalPlaces) + " p.u.");
489 } break;
490 case ElectricalUnit::UNIT_var: {
491 SetText(wxString::FromDouble(reactivePower * systemPowerBase, m_decimalPlaces) +
492 " var");
493 } break;
494 case ElectricalUnit::UNIT_kvar: {
495 SetText(wxString::FromDouble(reactivePower * systemPowerBase / 1e3, m_decimalPlaces) +
496 " kvar");
497 } break;
498 case ElectricalUnit::UNIT_Mvar: {
499 SetText(wxString::FromDouble(reactivePower * systemPowerBase / 1e6, m_decimalPlaces) +
500 " Mvar");
501 } break;
502 default:
503 break;
504 }
505 } break;
506 case DATA_SC_CURRENT: {
507 double faultCurrent[3] = { std::abs(data.faultCurrent[0]), std::abs(data.faultCurrent[1]),
508 std::abs(data.faultCurrent[2]) };
509 switch (m_unit) {
510 case ElectricalUnit::UNIT_PU: {
511 wxString str =
512 "Ia = " + wxString::FromDouble(faultCurrent[0], m_decimalPlaces) + " p.u.";
513 str += "\nIb = " + wxString::FromDouble(faultCurrent[1], m_decimalPlaces) + " p.u.";
514 str += "\nIc = " + wxString::FromDouble(faultCurrent[2], m_decimalPlaces) + " p.u.";
515 SetText(str);
516 } break;
517 case ElectricalUnit::UNIT_A: {
518 wxString str =
519 "Ia = " + wxString::FromDouble(faultCurrent[0] * baseCurrent, m_decimalPlaces) +
520 " A";
521 str += "\nIb = " +
522 wxString::FromDouble(faultCurrent[1] * baseCurrent, m_decimalPlaces) + " A";
523 str += "\nIc = " +
524 wxString::FromDouble(faultCurrent[2] * baseCurrent, m_decimalPlaces) + " A";
525 SetText(str);
526 } break;
527 case ElectricalUnit::UNIT_kA: {
528 wxString str =
529 "Ia = " +
530 wxString::FromDouble(faultCurrent[0] * baseCurrent / 1e3, m_decimalPlaces) + " kA";
531 str += "\nIb = " +
532 wxString::FromDouble(faultCurrent[1] * baseCurrent / 1e3, m_decimalPlaces) +
533 " kA";
534 str += "\nIc = " +
535 wxString::FromDouble(faultCurrent[2] * baseCurrent / 1e3, m_decimalPlaces) +
536 " kA";
537 SetText(str);
538 } break;
539 default:
540 break;
541 }
542 } break;
543 default:
544 break;
545 }
546 }
547 } break;
548 case TYPE_LINE: {
549 Line* line = static_cast<Line*>(m_element);
550 if (line) {
551 LineElectricalData data = line->GetElectricalData();
552 double baseVoltage = data.nominalVoltage;
553 if (data.nominalVoltageUnit == ElectricalUnit::UNIT_kV) baseVoltage *= 1e3;
554 double baseCurrent = systemPowerBase / (std::sqrt(3.0) * baseVoltage);
555 bool busParentOnline = false;
556 auto parentList = line->GetParentList();
557 if (parentList.size() == 2) {
558 Bus* busParent1 = dynamic_cast<Bus*>(parentList[0]);
559 Bus* busParent2 = dynamic_cast<Bus*>(parentList[1]);
560 if (busParent1 && busParent2) {
561 if (busParent1->GetElectricalData().isConnected && busParent1->GetElectricalData().isConnected)
562 busParentOnline = true;
563 }
564 }
565 switch (m_dataType) {
566 case DATA_NAME: {
567 SetText(data.name);
568 } break;
569 case DATA_PF_ACTIVE: {
570 double activePF = std::real(data.powerFlow[m_direction]);
571 if (!line->IsOnline() || !busParentOnline) activePF = 0.0;
572 switch (m_unit) {
573 case ElectricalUnit::UNIT_PU: {
574 SetText(wxString::FromDouble(activePF, m_decimalPlaces) + " p.u.");
575 } break;
576 case ElectricalUnit::UNIT_W: {
577 SetText(wxString::FromDouble(activePF * systemPowerBase, m_decimalPlaces) + " W");
578 } break;
579 case ElectricalUnit::UNIT_kW: {
580 SetText(wxString::FromDouble(activePF * systemPowerBase / 1e3, m_decimalPlaces) +
581 " kW");
582 } break;
583 case ElectricalUnit::UNIT_MW: {
584 SetText(wxString::FromDouble(activePF * systemPowerBase / 1e6, m_decimalPlaces) +
585 " MW");
586 } break;
587 default:
588 break;
589 }
590 } break;
591 case DATA_PF_REACTIVE: {
592 double reactivePF = std::imag(data.powerFlow[m_direction]);
593 if (!line->IsOnline() || !busParentOnline) reactivePF = 0.0;
594 switch (m_unit) {
595 case ElectricalUnit::UNIT_PU: {
596 SetText(wxString::FromDouble(reactivePF, m_decimalPlaces) + " p.u.");
597 } break;
598 case ElectricalUnit::UNIT_var: {
599 SetText(wxString::FromDouble(reactivePF * systemPowerBase, m_decimalPlaces) + " var");
600 } break;
601 case ElectricalUnit::UNIT_kvar: {
602 SetText(wxString::FromDouble(reactivePF * systemPowerBase / 1e3, m_decimalPlaces) +
603 " kvar");
604 } break;
605 case ElectricalUnit::UNIT_Mvar: {
606 SetText(wxString::FromDouble(reactivePF * systemPowerBase / 1e6, m_decimalPlaces) +
607 " Mvar");
608 } break;
609 default:
610 break;
611 }
612 } break;
613 case DATA_PF_LOSSES: {
614 double losses = std::abs(std::real(data.powerFlow[0]) + std::real(data.powerFlow[1]));
615 if (!line->IsOnline() || !busParentOnline) losses = 0.0;
616 switch (m_unit) {
617 case ElectricalUnit::UNIT_PU: {
618 SetText(wxString::FromDouble(losses, m_decimalPlaces) + " p.u.");
619 } break;
620 case ElectricalUnit::UNIT_W: {
621 SetText(wxString::FromDouble(losses * systemPowerBase, m_decimalPlaces) + " W");
622 } break;
623 case ElectricalUnit::UNIT_kW: {
624 SetText(wxString::FromDouble(losses * systemPowerBase / 1e3, m_decimalPlaces) + " kW");
625 } break;
626 case ElectricalUnit::UNIT_MW: {
627 SetText(wxString::FromDouble(losses * systemPowerBase / 1e6, m_decimalPlaces) + " MW");
628 } break;
629 default:
630 break;
631 }
632 } break;
633 case DATA_PF_CURRENT: {
634 double current = std::abs(data.current[m_direction]);
635 if (!line->IsOnline() || !busParentOnline) current = 0.0;
636 switch (m_unit) {
637 case ElectricalUnit::UNIT_PU: {
638 SetText(wxString::FromDouble(current, m_decimalPlaces) + " p.u.");
639 } break;
640 case ElectricalUnit::UNIT_A: {
641 SetText(wxString::FromDouble(current * baseCurrent, m_decimalPlaces) + " A");
642 } break;
643 case ElectricalUnit::UNIT_kA: {
644 SetText(wxString::FromDouble(current * baseCurrent / 1e3, m_decimalPlaces) + " kA");
645 } break;
646 default:
647 break;
648 }
649 } break;
650 case DATA_SC_CURRENT: {
651 double faultCurrent[3] = { std::abs(data.faultCurrent[m_direction][0]),
652 std::abs(data.faultCurrent[m_direction][1]),
653 std::abs(data.faultCurrent[m_direction][2]) };
654 if (!line->IsOnline()) faultCurrent[0] = faultCurrent[1] = faultCurrent[2] = 0.0;
655 switch (m_unit) {
656 case ElectricalUnit::UNIT_PU: {
657 wxString str =
658 "Ia = " + wxString::FromDouble(faultCurrent[0], m_decimalPlaces) + " p.u.";
659 str += "\nIb = " + wxString::FromDouble(faultCurrent[1], m_decimalPlaces) + " p.u.";
660 str += "\nIc = " + wxString::FromDouble(faultCurrent[2], m_decimalPlaces) + " p.u.";
661 SetText(str);
662 } break;
663 case ElectricalUnit::UNIT_A: {
664 wxString str =
665 "Ia = " + wxString::FromDouble(faultCurrent[0] * baseCurrent, m_decimalPlaces) +
666 " A";
667 str += "\nIb = " +
668 wxString::FromDouble(faultCurrent[1] * baseCurrent, m_decimalPlaces) + " A";
669 str += "\nIc = " +
670 wxString::FromDouble(faultCurrent[2] * baseCurrent, m_decimalPlaces) + " A";
671 SetText(str);
672 } break;
673 case ElectricalUnit::UNIT_kA: {
674 wxString str =
675 "Ia = " +
676 wxString::FromDouble(faultCurrent[0] * baseCurrent / 1e3, m_decimalPlaces) + " kA";
677 str += "\nIb = " +
678 wxString::FromDouble(faultCurrent[1] * baseCurrent / 1e3, m_decimalPlaces) +
679 " kA";
680 str += "\nIc = " +
681 wxString::FromDouble(faultCurrent[2] * baseCurrent / 1e3, m_decimalPlaces) +
682 " kA";
683 SetText(str);
684 } break;
685 default:
686 break;
687 }
688 } break;
689 default:
690 break;
691 }
692 }
693 } break;
694 case TYPE_TRANSFORMER: {
695 Transformer* transformer = static_cast<Transformer*>(m_element);
696 if (transformer) {
697 TransformerElectricalData data = transformer->GetElectricalData();
698 double baseVoltage[2] = { data.primaryNominalVoltage, data.secondaryNominalVoltage };
699 bool busParentOnline = false;
700 auto parentList = transformer->GetParentList();
701 if (parentList.size() == 2) {
702 Bus* busParent1 = dynamic_cast<Bus*>(parentList[0]);
703 Bus* busParent2 = dynamic_cast<Bus*>(parentList[1]);
704 if (busParent1 && busParent2) {
705 if (busParent1->GetElectricalData().isConnected && busParent1->GetElectricalData().isConnected)
706 busParentOnline = true;
707 }
708 }
709
710 if (data.primaryNominalVoltageUnit == ElectricalUnit::UNIT_kV) baseVoltage[0] *= 1e3;
711 if (data.secondaryNominalVoltageUnit == ElectricalUnit::UNIT_kV) baseVoltage[1] *= 1e3;
712
713 double baseCurrent[2] = { systemPowerBase / (std::sqrt(3.0) * baseVoltage[0]),
714 systemPowerBase / (std::sqrt(3.0) * baseVoltage[1]) };
715 switch (m_dataType) {
716 case DATA_NAME: {
717 SetText(data.name);
718 } break;
719 case DATA_PF_ACTIVE: {
720 double activePF = std::real(data.powerFlow[m_direction]);
721 if (!transformer->IsOnline() || !busParentOnline) activePF = 0.0;
722 switch (m_unit) {
723 case ElectricalUnit::UNIT_PU: {
724 SetText(wxString::FromDouble(activePF, m_decimalPlaces) + " p.u.");
725 } break;
726 case ElectricalUnit::UNIT_W: {
727 SetText(wxString::FromDouble(activePF * systemPowerBase, m_decimalPlaces) + " W");
728 } break;
729 case ElectricalUnit::UNIT_kW: {
730 SetText(wxString::FromDouble(activePF * systemPowerBase / 1e3, m_decimalPlaces) +
731 " kW");
732 } break;
733 case ElectricalUnit::UNIT_MW: {
734 SetText(wxString::FromDouble(activePF * systemPowerBase / 1e6, m_decimalPlaces) +
735 " MW");
736 } break;
737 default:
738 break;
739 }
740 } break;
741 case DATA_PF_REACTIVE: {
742 double reactivePF = std::imag(data.powerFlow[m_direction]);
743 if (!transformer->IsOnline() || !busParentOnline) reactivePF = 0.0;
744 switch (m_unit) {
745 case ElectricalUnit::UNIT_PU: {
746 SetText(wxString::FromDouble(reactivePF, m_decimalPlaces) + " p.u.");
747 } break;
748 case ElectricalUnit::UNIT_var: {
749 SetText(wxString::FromDouble(reactivePF * systemPowerBase, m_decimalPlaces) + " var");
750 } break;
751 case ElectricalUnit::UNIT_kvar: {
752 SetText(wxString::FromDouble(reactivePF * systemPowerBase / 1e3, m_decimalPlaces) +
753 " kvar");
754 } break;
755 case ElectricalUnit::UNIT_Mvar: {
756 SetText(wxString::FromDouble(reactivePF * systemPowerBase / 1e6, m_decimalPlaces) +
757 " Mvar");
758 } break;
759 default:
760 break;
761 }
762 } break;
763 case DATA_PF_LOSSES: {
764 double losses = std::abs(std::real(data.powerFlow[0]) + std::real(data.powerFlow[1]));
765 if (!transformer->IsOnline() || !busParentOnline) losses = 0.0;
766 switch (m_unit) {
767 case ElectricalUnit::UNIT_PU: {
768 SetText(wxString::FromDouble(losses, m_decimalPlaces) + " p.u.");
769 } break;
770 case ElectricalUnit::UNIT_W: {
771 SetText(wxString::FromDouble(losses * systemPowerBase, m_decimalPlaces) + " W");
772 } break;
773 case ElectricalUnit::UNIT_kW: {
774 SetText(wxString::FromDouble(losses * systemPowerBase / 1e3, m_decimalPlaces) + " kW");
775 } break;
776 case ElectricalUnit::UNIT_MW: {
777 SetText(wxString::FromDouble(losses * systemPowerBase / 1e6, m_decimalPlaces) + " MW");
778 } break;
779 default:
780 break;
781 }
782 } break;
783 case DATA_PF_CURRENT: {
784 double current = std::abs(data.current[m_direction]);
785 if (!transformer->IsOnline() || !busParentOnline) current = 0.0;
786 switch (m_unit) {
787 case ElectricalUnit::UNIT_PU: {
788 SetText(wxString::FromDouble(current, m_decimalPlaces) + " p.u.");
789 } break;
790 case ElectricalUnit::UNIT_A: {
791 SetText(wxString::FromDouble(current * baseCurrent[m_direction], m_decimalPlaces) +
792 " A");
793 } break;
794 case ElectricalUnit::UNIT_kA: {
795 SetText(
796 wxString::FromDouble(current * baseCurrent[m_direction] / 1e3, m_decimalPlaces) +
797 " kA");
798 } break;
799 default:
800 break;
801 }
802 } break;
803 case DATA_SC_CURRENT: {
804 double faultCurrent[3] = { std::abs(data.faultCurrent[m_direction][0]),
805 std::abs(data.faultCurrent[m_direction][1]),
806 std::abs(data.faultCurrent[m_direction][2]) };
807 if (!transformer->IsOnline()) faultCurrent[0] = faultCurrent[1] = faultCurrent[2] = 0.0;
808 switch (m_unit) {
809 case ElectricalUnit::UNIT_PU: {
810 wxString str =
811 "Ia = " + wxString::FromDouble(faultCurrent[0], m_decimalPlaces) + " p.u.";
812 str += "\nIb = " + wxString::FromDouble(faultCurrent[1], m_decimalPlaces) + " p.u.";
813 str += "\nIc = " + wxString::FromDouble(faultCurrent[2], m_decimalPlaces) + " p.u.";
814 SetText(str);
815 } break;
816 case ElectricalUnit::UNIT_A: {
817 wxString str =
818 "Ia = " +
819 wxString::FromDouble(faultCurrent[0] * baseCurrent[m_direction], m_decimalPlaces) +
820 " A";
821 str +=
822 "\nIb = " +
823 wxString::FromDouble(faultCurrent[1] * baseCurrent[m_direction], m_decimalPlaces) +
824 " A";
825 str +=
826 "\nIc = " +
827 wxString::FromDouble(faultCurrent[2] * baseCurrent[m_direction], m_decimalPlaces) +
828 " A";
829 SetText(str);
830 } break;
831 case ElectricalUnit::UNIT_kA: {
832 wxString str = "Ia = " +
833 wxString::FromDouble(faultCurrent[0] * baseCurrent[m_direction] / 1e3,
834 m_decimalPlaces) +
835 " kA";
836 str += "\nIb = " +
837 wxString::FromDouble(faultCurrent[1] * baseCurrent[m_direction] / 1e3,
838 m_decimalPlaces) +
839 " kA";
840 str += "\nIc = " +
841 wxString::FromDouble(faultCurrent[2] * baseCurrent[m_direction] / 1e3,
842 m_decimalPlaces) +
843 " kA";
844 SetText(str);
845 } break;
846 default:
847 break;
848 }
849 } break;
850 case DATA_TRANSFORMER_TAP: {
851 double tap = data.turnsRatio;
852 if (m_unit == ElectricalUnit::UNIT_NONE)
853 SetText(_("Tap = ") + wxString::FromDouble(tap, m_decimalPlaces));
854 else
855 SetText(_("Tap = ") + wxString::FromDouble(tap, m_decimalPlaces) + " p.u.");
856 } break;
857 default:
858 break;
859 }
860 }
861 } break;
862 case TYPE_LOAD: {
863 Load* load = static_cast<Load*>(m_element);
864 if (load) {
865 LoadElectricalData data = load->GetPUElectricalData(systemPowerBase);
866 std::complex<double> sPower(data.activePower, data.reactivePower);
867 if (data.loadType == CONST_IMPEDANCE && load->IsOnline()) {
868 std::complex<double> v = static_cast<Bus*>(load->GetParentList()[0])->GetElectricalData().voltage;
869 sPower = std::pow(std::abs(v), 2) * sPower;
870 }
871 bool busParentOnline = false;
872 auto parentList = load->GetParentList();
873 if (parentList.size() == 1) {
874 Bus* busParent = dynamic_cast<Bus*>(parentList[0]);
875 if (busParent)
876 busParentOnline = busParent->GetElectricalData().isConnected;
877 }
878
879 if (!load->IsOnline() || !busParentOnline) sPower = std::complex<double>(0.0, 0.0);
880 switch (m_dataType) {
881 case DATA_NAME: {
882 SetText(data.name);
883 } break;
884 case DATA_ACTIVE_POWER: {
885 switch (m_unit) {
886 case ElectricalUnit::UNIT_PU: {
887 SetText(wxString::FromDouble(sPower.real(), m_decimalPlaces) + " p.u.");
888 } break;
889 case ElectricalUnit::UNIT_W: {
890 SetText(wxString::FromDouble(sPower.real() * systemPowerBase, m_decimalPlaces) + " W");
891 } break;
892 case ElectricalUnit::UNIT_kW: {
893 SetText(wxString::FromDouble(sPower.real() * systemPowerBase / 1e3, m_decimalPlaces) +
894 " kW");
895 } break;
896 case ElectricalUnit::UNIT_MW: {
897 SetText(wxString::FromDouble(sPower.real() * systemPowerBase / 1e6, m_decimalPlaces) +
898 " MW");
899 } break;
900 default:
901 break;
902 }
903 } break;
904 case DATA_REACTIVE_POWER: {
905 switch (m_unit) {
906 case ElectricalUnit::UNIT_PU: {
907 SetText(wxString::FromDouble(sPower.imag(), m_decimalPlaces) + " p.u.");
908 } break;
909 case ElectricalUnit::UNIT_var: {
910 SetText(wxString::FromDouble(sPower.imag() * systemPowerBase, m_decimalPlaces) +
911 " var");
912 } break;
913 case ElectricalUnit::UNIT_kvar: {
914 SetText(wxString::FromDouble(sPower.imag() * systemPowerBase / 1e3, m_decimalPlaces) +
915 " kvar");
916 } break;
917 case ElectricalUnit::UNIT_Mvar: {
918 SetText(wxString::FromDouble(sPower.imag() * systemPowerBase / 1e6, m_decimalPlaces) +
919 " Mvar");
920 } break;
921 default:
922 break;
923 }
924 } break;
925 default:
926 break;
927 }
928 }
929 } break;
930 case TYPE_SYNC_MOTOR: {
931 SyncMotor* syncMotor = static_cast<SyncMotor*>(m_element);
932
933 if (syncMotor) {
934 SyncMotorElectricalData data = syncMotor->GetPUElectricalData(systemPowerBase);
935 bool busParentOnline = false;
936 auto parentList = syncMotor->GetParentList();
937 if (parentList.size() == 1) {
938 Bus* busParent = dynamic_cast<Bus*>(parentList[0]);
939 if (busParent)
940 busParentOnline = busParent->GetElectricalData().isConnected;
941 }
942 std::complex<double> sPower(data.activePower, data.reactivePower);
943 if (!syncMotor->IsOnline() || !busParentOnline) sPower = std::complex<double>(0.0, 0.0);
944 switch (m_dataType) {
945 case DATA_NAME: {
946 SetText(data.name);
947 } break;
948 case DATA_ACTIVE_POWER: {
949 switch (m_unit) {
950 case ElectricalUnit::UNIT_PU: {
951 SetText(wxString::FromDouble(sPower.real(), m_decimalPlaces) + " p.u.");
952 } break;
953 case ElectricalUnit::UNIT_W: {
954 SetText(wxString::FromDouble(sPower.real() * systemPowerBase, m_decimalPlaces) + " W");
955 } break;
956 case ElectricalUnit::UNIT_kW: {
957 SetText(wxString::FromDouble(sPower.real() * systemPowerBase / 1e3, m_decimalPlaces) +
958 " kW");
959 } break;
960 case ElectricalUnit::UNIT_MW: {
961 SetText(wxString::FromDouble(sPower.real() * systemPowerBase / 1e6, m_decimalPlaces) +
962 " MW");
963 } break;
964 default:
965 break;
966 }
967 } break;
968 case DATA_REACTIVE_POWER: {
969 switch (m_unit) {
970 case ElectricalUnit::UNIT_PU: {
971 SetText(wxString::FromDouble(sPower.imag(), m_decimalPlaces) + " p.u.");
972 } break;
973 case ElectricalUnit::UNIT_var: {
974 SetText(wxString::FromDouble(sPower.imag() * systemPowerBase, m_decimalPlaces) +
975 " var");
976 } break;
977 case ElectricalUnit::UNIT_kvar: {
978 SetText(wxString::FromDouble(sPower.imag() * systemPowerBase / 1e3, m_decimalPlaces) +
979 " kvar");
980 } break;
981 case ElectricalUnit::UNIT_Mvar: {
982 SetText(wxString::FromDouble(sPower.imag() * systemPowerBase / 1e6, m_decimalPlaces) +
983 " Mvar");
984 } break;
985 default:
986 break;
987 }
988 } break;
989 default:
990 break;
991 }
992 }
993 } break;
994 case TYPE_IND_MOTOR: {
995 IndMotor* indMotor = static_cast<IndMotor*>(m_element);
996 if (indMotor) {
997 IndMotorElectricalData data = indMotor->GetPUElectricalData(systemPowerBase);
998 bool busParentOnline = false;
999 auto parentList = indMotor->GetParentList();
1000 if (parentList.size() == 1) {
1001 Bus* busParent = dynamic_cast<Bus*>(parentList[0]);
1002 if (busParent)
1003 busParentOnline = busParent->GetElectricalData().isConnected;
1004 }
1005 std::complex<double> sPower(data.activePower, data.reactivePower);
1006 if (!indMotor->IsOnline() || !busParentOnline) sPower = std::complex<double>(0.0, 0.0);
1007 switch (m_dataType) {
1008 case DATA_NAME: {
1009 SetText(data.name);
1010 } break;
1011 case DATA_ACTIVE_POWER: {
1012 switch (m_unit) {
1013 case ElectricalUnit::UNIT_PU: {
1014 SetText(wxString::FromDouble(sPower.real(), m_decimalPlaces) + " p.u.");
1015 } break;
1016 case ElectricalUnit::UNIT_W: {
1017 SetText(wxString::FromDouble(sPower.real() * systemPowerBase, m_decimalPlaces) + " W");
1018 } break;
1019 case ElectricalUnit::UNIT_kW: {
1020 SetText(wxString::FromDouble(sPower.real() * systemPowerBase / 1e3, m_decimalPlaces) +
1021 " kW");
1022 } break;
1023 case ElectricalUnit::UNIT_MW: {
1024 SetText(wxString::FromDouble(sPower.real() * systemPowerBase / 1e6, m_decimalPlaces) +
1025 " MW");
1026 } break;
1027 default:
1028 break;
1029 }
1030 } break;
1031 case DATA_REACTIVE_POWER: {
1032 switch (m_unit) {
1033 case ElectricalUnit::UNIT_PU: {
1034 SetText(wxString::FromDouble(sPower.imag(), m_decimalPlaces) + " p.u.");
1035 } break;
1036 case ElectricalUnit::UNIT_var: {
1037 SetText(wxString::FromDouble(sPower.imag() * systemPowerBase, m_decimalPlaces) +
1038 " var");
1039 } break;
1040 case ElectricalUnit::UNIT_kvar: {
1041 SetText(wxString::FromDouble(sPower.imag() * systemPowerBase / 1e3, m_decimalPlaces) +
1042 " kvar");
1043 } break;
1044 case ElectricalUnit::UNIT_Mvar: {
1045 SetText(wxString::FromDouble(sPower.imag() * systemPowerBase / 1e6, m_decimalPlaces) +
1046 " Mvar");
1047 }break;
1048 default:
1049 break;
1050 }
1051 } break;
1052 default:
1053 break;
1054 }
1055 }
1056 } break;
1057 case TYPE_CAPACITOR: {
1058 Capacitor* capacitor = static_cast<Capacitor*>(m_element);
1059 if (capacitor) {
1060 CapacitorElectricalData data = capacitor->GetPUElectricalData(systemPowerBase);
1061 double reativePower = data.reactivePower;
1062
1063 bool busParentOnline = false;
1064 auto parentList = capacitor->GetParentList();
1065 if (parentList.size() == 1) {
1066 Bus* busParent = dynamic_cast<Bus*>(parentList[0]);
1067 if (busParent)
1068 busParentOnline = busParent->GetElectricalData().isConnected;
1069 }
1070
1071 if (!capacitor->IsOnline() || !busParentOnline)
1072 reativePower = 0.0;
1073 else {
1074 std::complex<double> v =
1075 static_cast<Bus*>(capacitor->GetParentList()[0])->GetElectricalData().voltage;
1076 reativePower *= std::pow(std::abs(v), 2);
1077 }
1078 switch (m_dataType) {
1079 case DATA_NAME: {
1080 SetText(data.name);
1081 } break;
1082 case DATA_REACTIVE_POWER: {
1083 switch (m_unit) {
1084 case ElectricalUnit::UNIT_PU: {
1085 SetText(wxString::FromDouble(reativePower, m_decimalPlaces) + " p.u.");
1086 }break;
1087 case ElectricalUnit::UNIT_var: {
1088 SetText(wxString::FromDouble(reativePower * systemPowerBase, m_decimalPlaces) + " var");
1089 }break;
1090 case ElectricalUnit::UNIT_kvar: {
1091 SetText(wxString::FromDouble(reativePower * systemPowerBase / 1e3, m_decimalPlaces) +
1092 " kvar");
1093 }break;
1094 case ElectricalUnit::UNIT_Mvar: {
1095 SetText(wxString::FromDouble(reativePower * systemPowerBase / 1e6, m_decimalPlaces) +
1096 " Mvar");
1097 }break;
1098 default:
1099 break;
1100 }
1101 } break;
1102 default:
1103 break;
1104 }
1105 }
1106 } break;
1107 case TYPE_INDUCTOR: {
1108 Inductor* inductor = static_cast<Inductor*>(m_element);
1109 if (inductor) {
1110 InductorElectricalData data = inductor->GetPUElectricalData(systemPowerBase);
1111 double reativePower = data.reactivePower;
1112
1113 bool busParentOnline = false;
1114 auto parentList = inductor->GetParentList();
1115 if (parentList.size() == 1) {
1116 Bus* busParent = dynamic_cast<Bus*>(parentList[0]);
1117 if (busParent)
1118 busParentOnline = busParent->GetElectricalData().isConnected;
1119 }
1120
1121 if (!inductor->IsOnline() || !busParentOnline)
1122 reativePower = 0.0;
1123 else {
1124 std::complex<double> v =
1125 static_cast<Bus*>(inductor->GetParentList()[0])->GetElectricalData().voltage;
1126 reativePower *= std::pow(std::abs(v), 2);
1127 }
1128 switch (m_dataType) {
1129 case DATA_NAME: {
1130 SetText(data.name);
1131 } break;
1132 case DATA_REACTIVE_POWER: {
1133 switch (m_unit) {
1134 case ElectricalUnit::UNIT_PU: {
1135 SetText(wxString::FromDouble(reativePower, m_decimalPlaces) + " p.u.");
1136 }break;
1137 case ElectricalUnit::UNIT_var: {
1138 SetText(wxString::FromDouble(reativePower * systemPowerBase, m_decimalPlaces) + " var");
1139 }break;
1140 case ElectricalUnit::UNIT_kvar: {
1141 SetText(wxString::FromDouble(reativePower * systemPowerBase / 1e3, m_decimalPlaces) +
1142 " kvar");
1143 }break;
1144 case ElectricalUnit::UNIT_Mvar: {
1145 SetText(wxString::FromDouble(reativePower * systemPowerBase / 1e6, m_decimalPlaces) +
1146 " Mvar");
1147 } break;
1148 default:
1149 break;
1150 }
1151 } break;
1152 default:
1153 break;
1154 }
1155 }
1156 } break;
1157 case TYPE_HARMCURRENT: {
1158 HarmCurrent* harmCurrent = static_cast<HarmCurrent*>(m_element);
1159 if (harmCurrent) {
1160 auto data = harmCurrent->GetElectricalData();
1161 switch (m_dataType) {
1162 case DATA_NAME: {
1163 SetText(data.name);
1164 } break;
1165 default:
1166 break;
1167 }
1168 }
1169 } break;
1170 }
1171}
1172
1174{
1175 Text* copy = new Text();
1176 *copy = *this;
1177 copy->m_gcTextList.clear();
1178 copy->m_updateTextRectangle = true;
1179 return copy;
1180}
1181
1182//bool Text::IsGLTextOK()
1183//{
1184// bool isOk = true;
1185// for (auto it = m_openGLTextList.begin(), itEnd = m_openGLTextList.end(); it != itEnd; ++it) {
1186// if (!(*it)->IsTextureOK()) isOk = false;
1187// }
1188// return isOk;
1189//}
1190
1191rapidxml::xml_node<>* Text::SaveElement(rapidxml::xml_document<>& doc, rapidxml::xml_node<>* elementListNode)
1192{
1193 auto elementNode = XMLParser::AppendNode(doc, elementListNode, "Text");
1194 XMLParser::SetNodeAttribute(doc, elementNode, "ID", m_elementID);
1195
1196 SaveCADProperties(doc, elementNode);
1197
1198 auto textProperties = XMLParser::AppendNode(doc, elementNode, "TextProperties");
1199 auto elementType = XMLParser::AppendNode(doc, textProperties, "ElementType");
1200 XMLParser::SetNodeValue(doc, elementType, m_elementTypeText);
1201 auto elementNumber = XMLParser::AppendNode(doc, textProperties, "ElementNumber");
1202 XMLParser::SetNodeValue(doc, elementNumber, m_elementNumber);
1203 auto dataType = XMLParser::AppendNode(doc, textProperties, "DataType");
1204 XMLParser::SetNodeValue(doc, dataType, m_dataType);
1205 auto dataUnit = XMLParser::AppendNode(doc, textProperties, "DataUnit");
1206 XMLParser::SetNodeValue(doc, dataUnit, static_cast<int>(m_unit));
1207 auto direction = XMLParser::AppendNode(doc, textProperties, "Direction");
1208 XMLParser::SetNodeValue(doc, direction, m_direction);
1209 auto decimalPlaces = XMLParser::AppendNode(doc, textProperties, "DecimalPlaces");
1210 XMLParser::SetNodeValue(doc, decimalPlaces, m_decimalPlaces);
1211
1212 return elementNode;
1213}
1214
1215bool Text::OpenElement(rapidxml::xml_node<>* elementNode)
1216{
1217 if (!OpenCADProperties(elementNode)) return false;
1218
1219 auto textProperties = elementNode->first_node("TextProperties");
1220 if (!textProperties) return false;
1221
1222 SetElementTypeText(static_cast<ElementType>(XMLParser::GetNodeValueDouble(textProperties, "ElementType")));
1223 SetDataType(static_cast<DataType>(XMLParser::GetNodeValueDouble(textProperties, "DataType")));
1224 SetUnit(static_cast<ElectricalUnit>(XMLParser::GetNodeValueDouble(textProperties, "DataUnit")));
1225 SetDirection(XMLParser::GetNodeValueDouble(textProperties, "Direction"));
1226 SetDecimalPlaces(XMLParser::GetNodeValueDouble(textProperties, "DecimalPlaces"));
1227 SetElementNumber(XMLParser::GetNodeValueInt(textProperties, "ElementNumber"));
1228 SetInserted();
1229 return true;
1230}
Node for power elements. All others power elements are connected through this.
Definition Bus.h:87
Shunt capactior power element.
Definition Capacitor.h:39
Base class of all elements of the program. This class is responsible for manage graphical and his dat...
Definition Element.h:115
virtual bool RotatedRectanglesIntersects(wxRect2DDouble rect1, wxRect2DDouble rect2, double angle1, double angle2) const
Check if two roteted rectangles intersect.
Definition Element.cpp:377
virtual std::vector< Element * > GetParentList() const
Get the parent list.
Definition Element.h:567
bool IsOnline() const
Checks if the element is online or offline.
Definition Element.h:229
virtual void DrawDCRectangle(wxPoint2DDouble position, double width, double height, double angle, wxDC &dc) const
Draw a circle.
Definition Element.cpp:41
void SetPosition(const wxPoint2DDouble position)
Set the element position and update the rectangle.
Definition Element.cpp:33
virtual wxPoint2DDouble RotateAtPosition(wxPoint2DDouble pointToRotate, double angle, bool degrees=true) const
Rotate a point as element position being the origin.
Definition Element.cpp:298
void SetInserted(bool inserted=true)
Set if the element is properly inserted in the workspace.
Definition Element.h:639
Class to draw text on Graphics Context using wxWidgets.
Definition GCText.h:32
virtual void SetText(wxString text)
Set correctly a new text string.
Definition GCText.cpp:68
Abstract class for graphical elements shown with graphical elements in workspace.
Shunt Harmonic Corrent Source.
Definition HarmCurrent.h:24
Induction motor power element.
Definition IndMotor.h:119
Inductor shunt power element.
Definition Inductor.h:39
Power line element.
Definition Line.h:64
Loas shunt power element.
Definition Load.h:74
Synchronous generator power element.
Synchronous motor (synchronous compensator) power element.
Definition SyncMotor.h:135
Form to edit the text graphical data.
Definition TextForm.h:33
Element that shows power element informations in workspace.
Definition Text.h:71
virtual Element * GetCopy()
Get a the element copy.
Definition Text.cpp:1173
virtual bool Contains(wxPoint2DDouble position) const
Checks if the element contains a position.
Definition Text.cpp:69
virtual bool Intersects(wxRect2DDouble rect) const
Check if the element's rect intersects other rect.
Definition Text.cpp:252
virtual void Rotate(bool clockwise=true)
Rotate the element.
Definition Text.cpp:266
Two-winding transformer power element with OLTC support.
Definition Transformer.h:96
This class manages the graphical and power elements. It is responsible for handling the user's intera...
Definition Workspace.h:105