Power System Platform  2026w34a-beta
Loading...
Searching...
No Matches
LabelManager.cpp
1#include "LabelManager.h"
2
3#include <wx/msgdlg.h>
4#include <array>
5
6#include "../editors/Workspace.h"
7
8LabelManager::LabelManager(wxWindow* parent, Workspace* workspace)
9 : LabelManagerBase(parent), m_workspace(workspace)
10{
11 std::vector<wxString> branchOptions = { _(L"Name"),
12 _(L"Active power (i → j)"), _(L"Active power (j → i)"),
13 _(L"Rective power (i → j)"), _(L"Rective power (j → i)"),
14 _(L"Losses"),
15 _(L"Current (i → j)"), _(L"Current (j → i)"),
16 _(L"Fault current (i → j)"), _(L"Fault current (j → i)") };
17
18 m_checkListBoxLine->Append(branchOptions);
19 std::vector<wxString> transformerOptions = branchOptions;
20 transformerOptions.push_back(_(L"Tap"));
21 m_checkListBoxTransformer->Append(transformerOptions);
22
23 m_textCtrlPrecision->SetValue(wxString::Format("%d", m_precision));
24
25 Layout();
26 SetSize(GetBestSize());
27}
28
29LabelManager::~LabelManager()
30{
31}
32
33void LabelManager::OnCheckListSelected(wxCommandEvent& event)
34{
35 //wxMessageBox(wxString::Format("%d", event.GetId()));
36 UpdatePreview(m_choicebook->GetSelection());
37
38 event.Skip();
39}
40
41void LabelManager::UpdatePreview(int selection)
42{
43 std::vector<wxCheckListBox*> checkListBoxes = { m_checkListBoxBus, m_checkListBoxGenerator,
44 m_checkListBoxLoad, m_checkListBoxLine, m_checkListBoxTransformer, m_checkListBoxCapacitor,
45 m_checkListBoxInductor, m_checkListBoxIndMotor, m_checkListBoxSyncMotor };
46
47 m_richTextCtrlPreview->Clear();
48 for (auto* checkListBox : checkListBoxes) {
49 SetPreviewText(checkListBox);
50 }
51}
52
53wxString LabelManager::GetBusPreviewText(int dataID)
54{
55 switch (dataID)
56 {
57 case 0: { // Name
58 return _("Bus 1\n");
59 } break;
60 case 1: { // Voltage
61 switch (m_radioBoxVoltage->GetSelection())
62 {
63 case 0: {
64 return wxString::Format("%.*f p.u.\n", m_precision, 1.0);
65 } break;
66 case 1: {
67 return wxString::Format("%.*f V\n", m_precision, 13800.0);
68 } break;
69 case 2: {
70 return wxString::Format("%.*f kV\n", m_precision, 13.8);
71 } break;
72 default:
73 break;
74 }
75 } break;
76 case 2: { // Angle
77 switch (m_radioBoxAngle->GetSelection())
78 {
79 case 0: {
80 return wxString::Format("%.*f°\n", m_precision, 30.0);
81 } break;
82 case 1: {
83 return wxString::Format("%.*f rad\n", m_precision, 0.5235987756);
84 } break;
85 default:
86 break;
87 }
88 } break;
89 case 3: { // Fault current
90 return GetCurrent3fText({ 25.54, 0.0, 0.0 });
91 } break;
92 case 4: { // Fault voltage
93 switch (m_radioBoxVoltage->GetSelection())
94 {
95 case 0: {
96 return wxString::Format("Va = %.*f p.u.\t Vb = %.*f p.u.\t Vc = %.*f p.u.\n", m_precision, 0.0, m_precision, 1.0404, m_precision, 1.0246);
97 } break;
98 case 1: {
99 return wxString::Format("Va = %.*f V\t Vb = %.*f V\t Vc = %.*f V\n", m_precision, 0.0, m_precision, 14356.91, m_precision, 14140.11);
100 } break;
101 case 2: {
102 return wxString::Format("Va = %.*f kV\t Vb = %.*f kV\t Vc = %.*f kV\n", m_precision, 0.0, m_precision, 14.35691, m_precision, 14.14011);
103 } break;
104 default:
105 break;
106 }
107 } break;
108 case 5: { // Short-circuit power
109 return GetPowerText(_("VA"), 5.0);
110 } break;
111 case 6: { // Voltage THD
112 return wxString::Format(_("THD = %.*f%%\n"), m_precision, 5.36);
113 } break;
114 default:
115 break;
116 }
117 return wxString();
118}
119
120wxString LabelManager::GetGeneratorPreviewText(int dataID)
121{
122 switch (dataID)
123 {
124 case 0: { // Name
125 return _("Generator 1\n");
126 } break;
127 case 1: { // Active power
128 return GetPowerText(_("W"), 1.0);
129 } break;
130 case 2: { // Reactive power
131 return GetPowerText(_("var"), 0.3);
132 } break;
133 case 3: { // Fault current
134 return GetCurrent3fText({ 22.54, 0.0, 0.0 });
135 } break;
136 default:
137 break;
138 }
139 return wxString();
140}
141
142wxString LabelManager::GetPowerText(wxString unit, double puValue)
143{
144 switch (m_radioBoxPower->GetSelection()) {
145 case 0: {
146 return wxString::Format("%.*f p.u.\n", m_precision, puValue);
147 } break;
148 case 1: {
149 return wxString::Format("%.*f %s\n", m_precision, puValue * 1.0e8, unit);
150 } break;
151 case 2: {
152 return wxString::Format("%.*f k%s\n", m_precision, puValue * 1.0e5, unit);
153 } break;
154 case 3: {
155 return wxString::Format("%.*f M%s\n", m_precision, puValue * 1.0e2, unit);
156 } break;
157 default:
158 break;
159 }
160 return wxString();
161}
162
163wxString LabelManager::GetCurrent3fText(const std::array<double, 3>& puCurrents)
164{
165 switch (m_radioBoxCurrent->GetSelection())
166 {
167 case 0: {
168 return wxString::Format("Ia = %.*f p.u.\t Ib = %.*f p.u.\t Ic = %.*f p.u.\n", m_precision, puCurrents[0], m_precision, puCurrents[1], m_precision, puCurrents[2]);
169 } break;
170 case 1: {
171 return wxString::Format("Ia = %.*f A\t Ib = %.*f A\t Ic = %.*f A\n", m_precision, puCurrents[0] * 1e3, m_precision, puCurrents[1] * 1e3, m_precision, puCurrents[2] * 1e3);
172 } break;
173 case 2: {
174 return wxString::Format("Ia = %.*f kA\t Ib = %.*f kA\t Ic = %.*f kA\n", m_precision, puCurrents[0], m_precision, puCurrents[1], m_precision, puCurrents[2]);
175 } break;
176 default:
177 break;
178 }
179 return wxString();
180}
181
182wxString LabelManager::GetCurrentOrVoltageText(wxString unit, double puValue)
183{
184 if (unit == _("V"))
185 {
186 switch (m_radioBoxVoltage->GetSelection())
187 {
188 case 0: {
189 return wxString::Format("%.*f p.u.\n", m_precision, puValue);
190 } break;
191 case 1: {
192 return wxString::Format("%.*f V\n", m_precision, puValue * 13800.0);
193 } break;
194 case 2: {
195 return wxString::Format("%.*f kV\n", m_precision, puValue * 13.8);
196 } break;
197 default:
198 break;
199 }
200 }
201 else if (unit == _("A"))
202 {
203 switch (m_radioBoxCurrent->GetSelection())
204 {
205 case 0: {
206 return wxString::Format("%.*f p.u.\n", m_precision, puValue);
207 } break;
208 case 1: {
209 return wxString::Format("%.*f A\n", m_precision, puValue * 1e3);
210 } break;
211 case 2: {
212 return wxString::Format("%.*f kA\n", m_precision, puValue);
213 } break;
214 default:
215 break;
216 }
217 }
218
219 return wxString();
220}
221
222void LabelManager::SetPreviewText(wxCheckListBox* checkListBox)
223{
224 int id = checkListBox->GetId();
225 wxString name = "";
226 wxString text = "";
227 wxArrayInt checked;
228 checkListBox->GetCheckedItems(checked);
229 switch (id)
230 {
231 case ID_CL_BUS: {
232 name = _("Bus label");
233 for (int i : checked) {
234 text += GetBusPreviewText(i);
235 }
236 } break;
237 case ID_CL_GENERATOR: {
238 name = _("Generator label");
239 for (int i : checked) {
240 text += GetGeneratorPreviewText(i);
241 }
242 } break;
243 case ID_CL_LOAD: {
244 name = _("Load label");
245 for (int i : checked) {
246 text += GetLoadPreviewText(i);
247 }
248 } break;
249 case ID_CL_LINE: {
250 name = _("Line label");
251 for (int i : checked) {
252 text += GetLinePreviewText(i);
253 }
254 } break;
255 case ID_CL_TRANSFORMER: {
256 name = _("Transformer label");
257 for (int i : checked) {
258 text += GetTransformerPreviewText(i);
259 }
260 } break;
261 case ID_CL_CAPACITOR: {
262 name = _("Capacitor label");
263 for (int i : checked) {
264 text += GetCapacitorPreviewText(i);
265 }
266 } break;
267 case ID_CL_INDUCTOR: {
268 name = _("Inductor label");
269 for (int i : checked) {
270 text += GetInductorPreviewText(i);
271 }
272 } break;
273 case ID_CL_INDMOTOR: {
274 name = _("Induction motor label");
275 for (int i : checked) {
276 text += GetIndMotorPreviewText(i);
277 }
278 } break;
279 case ID_CL_SYNCMOTOR: {
280 name = _("Synchronous motor label");
281 for (int i : checked) {
282 text += GetSyncMotorPreviewText(i);
283 }
284 } break;
285 default:
286 break;
287 }
288
289 if (!checked.IsEmpty()) {
290 m_richTextCtrlPreview->BeginUnderline();
291 m_richTextCtrlPreview->BeginBold();
292 m_richTextCtrlPreview->WriteText(name);
293 m_richTextCtrlPreview->EndBold();
294 m_richTextCtrlPreview->EndUnderline();
295 m_richTextCtrlPreview->Newline();
296 m_richTextCtrlPreview->BeginLeftIndent(60);
297 m_richTextCtrlPreview->WriteText(text);
298 m_richTextCtrlPreview->EndLeftIndent();
299 m_richTextCtrlPreview->Newline();
300 }
301}
302
303wxString LabelManager::GetLoadPreviewText(int dataID)
304{
305 switch (dataID)
306 {
307 case 0: { // Name
308 return _("Load 1\n");
309 } break;
310 case 1: { // Active power
311 return GetPowerText(_("W"), 1.0);
312 } break;
313 case 2: { // Reactive power
314 return GetPowerText(_("var"), 0.3);
315 } break;
316 return wxString();
317 default:
318 break;
319 }
320 return wxString();
321}
322
323wxString LabelManager::GetLinePreviewText(int dataID)
324{
325 switch (dataID)
326 {
327 case 0: { // Name
328 return _("Line 1\n");
329 } break;
330 case 1: { // Active power (i → j)
331 return GetPowerText(_("W"), 1.0);
332 } break;
333 case 2: { // Active power (j → i)
334 return GetPowerText(_("W"), -1.0);
335 } break;
336 case 3: { // Reactive power (i → j)
337 return GetPowerText(_("var"), 0.3);
338 } break;
339 case 4: { // Reactive power (j → i)
340 return GetPowerText(_("var"), -0.3);
341 } break;
342 case 5: { // Losses
343 return GetPowerText(_("W"), 0.02);
344 } break;
345 case 6: { // Current (i → j)
346 return GetCurrentOrVoltageText(_("A"), 0.5);
347 } break;
348 case 7: { // Current (j → i)
349 return GetCurrentOrVoltageText(_("A"), -0.5);
350 } break;
351 case 8: { // Fault current (i → j)
352 return GetCurrent3fText({ 25.56, 0.0, 0.0 });
353 } break;
354 case 9: { // Fault current (j → i)
355 return GetCurrent3fText({ -25.56, 0.0, 0.0 });
356 } break;
357 default:
358 break;
359 }
360 return wxString();
361}
362
363wxString LabelManager::GetTransformerPreviewText(int dataID)
364{
365 switch (dataID)
366 {
367 case 0: { // Name
368 return _("Transformer 1\n");
369 } break;
370 case 1: { // Active power (i → j)
371 return GetPowerText(_("W"), 1.0);
372 } break;
373 case 2: { // Active power (j → i)
374 return GetPowerText(_("W"), -1.0);
375 } break;
376 case 3: { // Reactive power (i → j)
377 return GetPowerText(_("var"), 0.3);
378 } break;
379 case 4: { // Reactive power (j → i)
380 return GetPowerText(_("var"), -0.3);
381 } break;
382 case 5: { // Losses
383 return GetPowerText(_("W"), 0.02);
384 } break;
385 case 6: { // Current (i → j)
386 return GetCurrentOrVoltageText(_("A"), 0.5);
387 } break;
388 case 7: { // Current (j → i)
389 return GetCurrentOrVoltageText(_("A"), -0.5);
390 } break;
391 case 8: { // Fault current (i → j)
392 return GetCurrent3fText({ 25.56, 0.0, 0.0 });
393 } break;
394 case 9: { // Fault current (j → i)
395 return GetCurrent3fText({ -25.56, 0.0, 0.0 });
396 } break;
397 case 10: { // Tap
398 return wxString::Format(_("Tap = %.*f p.u.\n"), m_precision, 1.0);
399 } break;
400 default:
401 break;
402 }
403 return wxString();
404}
405
406wxString LabelManager::GetCapacitorPreviewText(int dataID)
407{
408 switch (dataID)
409 {
410 case 0: { // Name
411 return _("Capacitor 1\n");
412 } break;
413 case 1: { // Reactive power
414 return GetPowerText(_("var"), 1.0);
415 } break;
416 return wxString();
417 default:
418 break;
419 }
420 return wxString();
421}
422
423wxString LabelManager::GetInductorPreviewText(int dataID)
424{
425 switch (dataID)
426 {
427 case 0: { // Name
428 return _("Inductor 1\n");
429 } break;
430 case 1: { // Reactive power
431 return GetPowerText(_("var"), 1.0);
432 } break;
433 return wxString();
434 default:
435 break;
436 }
437 return wxString();
438}
439
440wxString LabelManager::GetIndMotorPreviewText(int dataID)
441{
442 switch (dataID)
443 {
444 case 0: { // Name
445 return _("Induction Motor 1\n");
446 } break;
447 case 1: { // Active power
448 return GetPowerText(_("W"), 1.0);
449 } break;
450 case 2: { // Reactive power
451 return GetPowerText(_("var"), 0.3);
452 } break;
453 return wxString();
454 default:
455 break;
456 }
457 return wxString();
458}
459
460wxString LabelManager::GetSyncMotorPreviewText(int dataID)
461{
462 switch (dataID)
463 {
464 case 0: { // Name
465 return _("Synchronous Compensator 1\n");
466 } break;
467 case 1: { // Active power
468 return GetPowerText(_("W"), 0.01);
469 } break;
470 case 2: { // Reactive power
471 return GetPowerText(_("var"), 1.0);
472 } break;
473 return wxString();
474 default:
475 break;
476 }
477 return wxString();
478}
479
480void LabelManager::OnChoicebookChanged(wxChoicebookEvent& event)
481{
482 UpdatePreview(m_choicebook->GetSelection());
483 event.Skip();
484}
485
486void LabelManager::OnUnitChanged(wxCommandEvent& event)
487{
488 UpdatePreview(m_choicebook->GetSelection());
489 event.Skip();
490}
491
492void LabelManager::OnPrecisionTextUpdate(wxCommandEvent& event)
493{
494 long precision;
495 if (m_textCtrlPrecision->GetValue().ToLong(&precision) && precision >= 0) {
496 m_precision = static_cast<size_t>(precision);
497 UpdatePreview(m_choicebook->GetSelection());
498 }
499 event.Skip();
500}
501
502void LabelManager::OnApplyButtonClick(wxCommandEvent& event)
503{
504 if (m_checkBoxReplace->GetValue()) {
505 m_workspace->RemoveAllTextElements();
506 }
507 ElectricalUnit voltageUnitList[3] = { ElectricalUnit::UNIT_PU, ElectricalUnit::UNIT_V, ElectricalUnit::UNIT_kV };
508 ElectricalUnit currentUnitList[3] = { ElectricalUnit::UNIT_PU, ElectricalUnit::UNIT_A, ElectricalUnit::UNIT_kA };
509 ElectricalUnit sUnitList[4] = { ElectricalUnit::UNIT_PU, ElectricalUnit::UNIT_VA, ElectricalUnit::UNIT_kVA, ElectricalUnit::UNIT_MVA };
510 ElectricalUnit pUnitList[4] = { ElectricalUnit::UNIT_PU, ElectricalUnit::UNIT_W, ElectricalUnit::UNIT_kW, ElectricalUnit::UNIT_MW };
511 ElectricalUnit qUnitList[4] = { ElectricalUnit::UNIT_PU, ElectricalUnit::UNIT_var, ElectricalUnit::UNIT_kvar, ElectricalUnit::UNIT_Mvar };
512 ElectricalUnit angleUnitList[2] = { ElectricalUnit::UNIT_DEGREE, ElectricalUnit::UNIT_RADIAN };
513
514 ElectricalUnit voltageUnit = voltageUnitList[m_radioBoxVoltage->GetSelection()];
515 ElectricalUnit currentUnit = currentUnitList[m_radioBoxCurrent->GetSelection()];
516 ElectricalUnit sUnit = sUnitList[m_radioBoxPower->GetSelection()];
517 ElectricalUnit pUnit = pUnitList[m_radioBoxPower->GetSelection()];
518 ElectricalUnit qUnit = qUnitList[m_radioBoxPower->GetSelection()];
519 ElectricalUnit angleUnit = angleUnitList[m_radioBoxAngle->GetSelection()];
520
521 auto elementList = m_workspace->GetElementList();
522 int numTxtElements = 0;
523 for (auto* element : elementList) {
524 ElementType elementType = element->GetElementType();
525 wxArrayInt checked;
526 switch (elementType)
527 {
528 case TYPE_BUS: {
529 TextID textOptions[7] = { ID_TXT_NAME, ID_TXT_VOLTAGE, ID_TXT_ANGLE, ID_TXT_FAULTCURRENT, ID_TXT_FAULTVOLTAGE, ID_TXT_SCC, ID_TXT_THD };
530 ElectricalUnit textUnits[7] = { ElectricalUnit::UNIT_NONE, voltageUnit, angleUnit, currentUnit, voltageUnit, sUnit, ElectricalUnit::UNIT_NONE };
531 m_checkListBoxBus->GetCheckedItems(checked);
532 for (int i : checked) {
533 m_workspace->InsertTextElement(textOptions[i], element, textUnits[i], m_precision);
534 numTxtElements++;
535 }
536 } break;
537 case TYPE_CAPACITOR: {
538 TextID textOptions[2] = { ID_TXT_NAME, ID_TXT_REACTIVE_POWER };
539 ElectricalUnit textUnits[2] = { ElectricalUnit::UNIT_NONE, qUnit };
540 m_checkListBoxCapacitor->GetCheckedItems(checked);
541 for (int i : checked) {
542 m_workspace->InsertTextElement(textOptions[i], element, textUnits[i], m_precision);
543 numTxtElements++;
544 }
545 } break;
546 case TYPE_IND_MOTOR: {
547 TextID textOptions[3] = { ID_TXT_NAME, ID_TXT_ACTIVE_POWER, ID_TXT_REACTIVE_POWER };
548 ElectricalUnit textUnits[3] = { ElectricalUnit::UNIT_NONE, pUnit, qUnit };
549 m_checkListBoxIndMotor->GetCheckedItems(checked);
550 for (int i : checked) {
551 m_workspace->InsertTextElement(textOptions[i], element, textUnits[i], m_precision);
552 numTxtElements++;
553 }
554 } break;
555 case TYPE_INDUCTOR: {
556 TextID textOptions[2] = { ID_TXT_NAME, ID_TXT_REACTIVE_POWER };
557 ElectricalUnit textUnits[2] = { ElectricalUnit::UNIT_NONE, qUnit };
558 m_checkListBoxInductor->GetCheckedItems(checked);
559 for (int i : checked) {
560 m_workspace->InsertTextElement(textOptions[i], element, textUnits[i], m_precision);
561 numTxtElements++;
562 }
563 } break;
564 case TYPE_LINE: {
565 TextID lineTextOptions[10] = { ID_TXT_NAME, ID_TXT_BRANCH_ACTIVE_POWER_1_2, ID_TXT_BRANCH_ACTIVE_POWER_2_1,
566 ID_TXT_BRANCH_REACTIVE_POWER_1_2, ID_TXT_BRANCH_REACTIVE_POWER_2_1, ID_TXT_BRANCH_LOSSES,
567 ID_TXT_BRANCH_CURRENT_1_2, ID_TXT_BRANCH_CURRENT_2_1, ID_TXT_BRANCH_FAULT_CURRENT_1_2, ID_TXT_BRANCH_FAULT_CURRENT_2_1 };
568 ElectricalUnit textUnits[10] = { ElectricalUnit::UNIT_NONE, pUnit, pUnit, qUnit, qUnit, pUnit, currentUnit, currentUnit, currentUnit, currentUnit };
569 m_checkListBoxLine->GetCheckedItems(checked);
570 for (int i : checked) {
571 m_workspace->InsertTextElement(lineTextOptions[i], element, textUnits[i], m_precision);
572 numTxtElements++;
573 }
574 } break;
575 case TYPE_LOAD: {
576 TextID textOptions[3] = { ID_TXT_NAME, ID_TXT_ACTIVE_POWER, ID_TXT_REACTIVE_POWER };
577 ElectricalUnit textUnits[3] = { ElectricalUnit::UNIT_NONE, pUnit, qUnit };
578 m_checkListBoxLoad->GetCheckedItems(checked);
579 for (int i : checked) {
580 m_workspace->InsertTextElement(textOptions[i], element, textUnits[i], m_precision);
581 numTxtElements++;
582 }
583 } break;
584 case TYPE_SYNC_GENERATOR: {
585 TextID textOptions[4] = { ID_TXT_NAME, ID_TXT_ACTIVE_POWER, ID_TXT_REACTIVE_POWER, ID_TXT_FAULTCURRENT };
586 ElectricalUnit textUnits[4] = { ElectricalUnit::UNIT_NONE, pUnit, qUnit, currentUnit };
587 m_checkListBoxGenerator->GetCheckedItems(checked);
588 for (int i : checked) {
589 m_workspace->InsertTextElement(textOptions[i], element, textUnits[i], m_precision);
590 numTxtElements++;
591 }
592 } break;
593 case TYPE_SYNC_MOTOR: {
594 TextID textOptions[3] = { ID_TXT_NAME, ID_TXT_ACTIVE_POWER, ID_TXT_REACTIVE_POWER };
595 ElectricalUnit textUnits[3] = { ElectricalUnit::UNIT_NONE, pUnit, qUnit };
596 m_checkListBoxSyncMotor->GetCheckedItems(checked);
597 for (int i : checked) {
598 m_workspace->InsertTextElement(textOptions[i], element, textUnits[i], m_precision);
599 numTxtElements++;
600 }
601 } break;
602 case TYPE_TRANSFORMER: {
603 TextID lineTextOptions[11] = { ID_TXT_NAME, ID_TXT_BRANCH_ACTIVE_POWER_1_2, ID_TXT_BRANCH_ACTIVE_POWER_2_1,
604 ID_TXT_BRANCH_REACTIVE_POWER_1_2, ID_TXT_BRANCH_REACTIVE_POWER_2_1, ID_TXT_BRANCH_LOSSES,
605 ID_TXT_BRANCH_CURRENT_1_2, ID_TXT_BRANCH_CURRENT_2_1, ID_TXT_BRANCH_FAULT_CURRENT_1_2, ID_TXT_BRANCH_FAULT_CURRENT_2_1,
606 ID_TXT_TAP };
607 ElectricalUnit textUnits[11] = { ElectricalUnit::UNIT_NONE, pUnit, pUnit, qUnit, qUnit, pUnit, currentUnit, currentUnit, currentUnit, currentUnit,
608 ElectricalUnit::UNIT_PU };
609 m_checkListBoxTransformer->GetCheckedItems(checked);
610 for (int i : checked) {
611 m_workspace->InsertTextElement(lineTextOptions[i], element, textUnits[i], m_precision);
612 numTxtElements++;
613 }
614 } break;
615 default:
616 break;
617 }
618 }
619 if (numTxtElements != 0) {
620 m_workspace->SaveCurrentState();
621 m_workspace->UpdateTextElements();
622 }
623 EndModal(wxID_OK);
624}
625
626void LabelManager::OnCancelButtonClick(wxCommandEvent& event)
627{
628 EndModal(wxID_CANCEL);
629}
This class manages the graphical and power elements. It is responsible for handling the user's intera...
Definition Workspace.h:105