Eclipse SUMO - Simulation of Urban MObility
GUIMessageWindow.cpp
Go to the documentation of this file.
1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3 // Copyright (C) 2003-2022 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials are made available under the
5 // terms of the Eclipse Public License 2.0 which is available at
6 // https://www.eclipse.org/legal/epl-2.0/
7 // This Source Code may also be made available under the following Secondary
8 // Licenses when the conditions for such availability set forth in the Eclipse
9 // Public License 2.0 are satisfied: GNU General Public License, version 2
10 // or later which is available at
11 // https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
12 // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
13 /****************************************************************************/
20 // A logging window for the gui
21 /****************************************************************************/
22 #include <config.h>
23 
24 #include <cassert>
30 #include <fxkeys.h>
31 #include "GUIMessageWindow.h"
32 
33 
34 // ===========================================================================
35 // static members
36 // ===========================================================================
39 
40 
41 // ===========================================================================
42 // method definitions
43 // ===========================================================================
44 GUIMessageWindow::GUIMessageWindow(FXComposite* parent, GUIMainWindow* mainWindow) :
45  FXText(parent, nullptr, 0, 0, 0, 0, 0, 50),
46  myMainWindow(mainWindow),
47  myStyles(new FXHiliteStyle[8]),
48  myErrorRetriever(nullptr),
49  myMessageRetriever(nullptr),
50  myWarningRetriever(nullptr) {
51  setStyled(true);
52  setEditable(false);
53  const FXColor white = FXRGB(0xff, 0xff, 0xff);
54  const FXColor blue = FXRGB(0x00, 0x00, 0x88);
55  const FXColor green = FXRGB(0x00, 0x88, 0x00);
56  const FXColor red = FXRGB(0x88, 0x00, 0x00);
57  const FXColor yellow = FXRGB(0xe6, 0x98, 0x00);
58  const FXColor fuchsia = FXRGB(0x88, 0x00, 0x88);
59  // set separator style
60  myStyles[0].normalForeColor = blue;
61  myStyles[0].normalBackColor = white;
62  myStyles[0].selectForeColor = white;
63  myStyles[0].selectBackColor = blue;
64  myStyles[0].hiliteForeColor = blue;
65  myStyles[0].hiliteBackColor = white;
66  myStyles[0].activeBackColor = white;
67  myStyles[0].style = 0;
68  // set message text style
69  myStyles[1] = myStyles[0];
70  myStyles[1].normalForeColor = green;
71  myStyles[1].selectBackColor = green;
72  myStyles[1].hiliteForeColor = green;
73  myStyles[4] = myStyles[1];
74  myStyles[4].style = STYLE_UNDERLINE;
75  // set error text style
76  myStyles[2] = myStyles[0];
77  myStyles[2].normalForeColor = red;
78  myStyles[2].selectBackColor = red;
79  myStyles[2].hiliteForeColor = red;
80  myStyles[5] = myStyles[2];
81  myStyles[5].style = STYLE_UNDERLINE;
82  // set warning text style
83  myStyles[3] = myStyles[0];
84  myStyles[3].normalForeColor = yellow;
85  myStyles[3].selectBackColor = yellow;
86  myStyles[3].hiliteForeColor = yellow;
87  myStyles[6] = myStyles[3];
88  myStyles[6].style = STYLE_UNDERLINE;
89  // set GLDebug text style
90  myStyles[7] = myStyles[0];
91  myStyles[7].normalForeColor = fuchsia;
92  myStyles[7].selectBackColor = fuchsia;
93  myStyles[7].hiliteForeColor = fuchsia;
94  //
95  setHiliteStyles(myStyles);
96 }
97 
98 
100  delete[] myStyles;
101  delete myMessageRetriever;
102  delete myErrorRetriever;
103  delete myWarningRetriever;
104 }
105 
106 
107 const GUIGlObject*
108 GUIMessageWindow::getActiveStringObject(const FXString& text, const FXint pos, const FXint lineS, const FXint lineE) const {
109  const FXint idS = MAX2(text.rfind(" '", pos), text.rfind("='", pos));
110  const FXint idE = text.find("'", pos);
111  if (idS >= 0 && idE >= 0 && idS >= lineS && idE <= lineE) {
112  FXint typeS = text.rfind(" ", idS - 1);
113  if (typeS >= 0) {
114  if (text.at(typeS + 1) == '(') {
115  typeS++;
116  }
117  std::string type(text.mid(typeS + 1, idS - typeS - 1).lower().text());
118  if (type == "tllogic") {
119  type = "tlLogic"; // see GUIGlObject.cpp
120  } else if (type == "busstop" || type == "trainstop") {
121  type = "busStop";
122  } else if (type == "containerstop") {
123  type = "containerStop";
124  } else if (type == "chargingstation") {
125  type = "chargingStation";
126  } else if (type == "overheadwiresegment") {
127  type = "overheadWireSegment";
128  } else if (type == "parkingarea") {
129  type = "parkingArea";
130  }
131  const std::string id(text.mid(idS + 2, idE - idS - 2).text());
132  return GUIGlObjectStorage::gIDStorage.getObjectBlocking(type + ":" + id);
133  }
134  }
135  return nullptr;
136 }
137 
138 SUMOTime
139 GUIMessageWindow::getTimeString(const FXString& text, const FXint pos, const FXint /*lineS*/, const FXint /*lineE*/) const {
140  const FXint end = text.find(" ", pos + 1);
141  std::string time;
142  if (end >= 0) {
143  time = text.mid(pos, end - pos).text();
144  } else {
145  time = text.mid(pos, text.length() - pos).text();
146  if (time.empty()) {
147  return -1;
148  }
149  if (time.back() == '\n') {
150  time.pop_back();
151  }
152  if (time.empty()) {
153  return -1;
154  }
155  if (time.back() == '.') {
156  time.pop_back();
157  }
158  }
159  if (time.empty()) {
160  return -1;
161  }
162  if (time.front() == ' ') {
163  time = time.substr(1);
164  }
165  //std::cout << "text='" << text.text() << "' pos=" << pos << " time='" << time << "'\n";
166  try {
167  //std::cout << " SUMOTime=" << string2time(time) << "\n";
168  return string2time(time);
169  } catch (...) {
170  return -1;
171  }
172 }
173 
174 
175 void
176 GUIMessageWindow::setCursorPos(FXint pos, FXbool notify) {
177  FXText::setCursorPos(pos, notify);
178  if (myLocateLinks) {
180  std::vector<std::string> viewIDs = main->getViewIDs();
181  if (viewIDs.empty()) {
182  return;
183  }
184  GUIGlChildWindow* const child = main->getViewByID(viewIDs[0]);
185  const FXString text = getText();
186  const GUIGlObject* const glObj = getActiveStringObject(text, pos, lineStart(pos), lineEnd(pos));
187  if (glObj != nullptr) {
188  child->setView(glObj->getGlID());
190  if (getApp()->getKeyState(KEY_Control_L)) {
192  }
193  } else {
194  const int lookback = MIN2(pos, 10);
195  const int start = MAX2(lineStart(pos), pos - lookback);
196  const FXString candidate = text.mid(start, lineEnd(pos) - start);
197  FXint timePos = candidate.find(" time");
198  SUMOTime t = -1;
199  if (pos >= 0) {
200  t = getTimeString(candidate, timePos + 6, 0, candidate.length());
201  if (t >= 0) {
202  t += myBreakPointOffset;
203  std::vector<SUMOTime> breakpoints = myMainWindow->retrieveBreakpoints();
204  if (std::find(breakpoints.begin(), breakpoints.end(), t) == breakpoints.end()) {
205  breakpoints.push_back(t);
206  std::sort(breakpoints.begin(), breakpoints.end());
207  myMainWindow->setBreakpoints(breakpoints);
208  }
209  }
210  }
211  }
212  }
213 }
214 
215 
216 void
217 GUIMessageWindow::appendMsg(GUIEventType eType, const std::string& msg) {
218  if (!isEnabled()) {
219  show();
220  }
221  // build the styled message
222  FXint style = 1;
223  switch (eType) {
225  // color: blue
226  style = 0;
227  break;
229  // color: fuchsia
230  style = 7;
231  break;
233  // color: red
234  style = 2;
235  break;
237  // color: yellow
238  style = 3;
239  break;
241  // color: green
242  style = 1;
243  break;
244  default:
245  assert(false);
246  }
247  FXString text(msg.c_str());
248  if (myLocateLinks) {
249  FXint pos = text.find("'");
250  while (pos >= 0) {
251  const GUIGlObject* const glObj = getActiveStringObject(text, pos + 1, 0, text.length());
252  if (glObj != nullptr) {
254  FXString insText = text.left(pos + 1);
255  FXText::appendStyledText(insText, style + 1);
256  text.erase(0, pos + 1);
257  pos = text.find("'");
258  insText = text.left(pos);
259  FXText::appendStyledText(insText, style + 4);
260  text.erase(0, pos);
261  }
262  pos = text.find("'", pos + 1);
263  }
264  // find time links
265  pos = text.find(" time");
266  SUMOTime t = -1;
267  if (pos >= 0) {
268  t = getTimeString(text, pos + 6, 0, text.length());
269  }
270  if (t >= 0) {
271  FXString insText = text.left(pos + 6);
272  FXText::appendStyledText(insText, style + 1);
273  text.erase(0, pos + 6);
274  pos = text.find(" ");
275  if (pos < 0) {
276  pos = text.rfind(".");
277  }
278  insText = text.left(pos);
279  FXText::appendStyledText(insText, style + 4);
280  text.erase(0, pos);
281  }
282  }
283  // insert rest of the message
284  FXText::appendStyledText(text, style + 1, true);
285  FXText::setCursorPos(getLength() - 1);
286  FXText::setBottomLine(getLength() - 1);
287  if (isEnabled()) {
288  layout();
289  update();
290  }
291 }
292 
293 
294 void
296  std::string msg = "----------------------------------------------------------------------------------------\n";
297  FXText::appendStyledText(msg.c_str(), (FXint) msg.length(), 1, true);
298  FXText::setCursorPos(getLength() - 1);
299  FXText::setBottomLine(getLength() - 1);
300  if (isEnabled()) {
301  layout();
302  update();
303  }
304 }
305 
306 
307 void
309  if (getLength() == 0) {
310  return;
311  }
312  FXText::removeText(0, getLength() - 1, true);
313  if (isEnabled()) {
314  layout();
315  update();
316  }
317 }
318 
319 
320 void
322  if (myMessageRetriever == nullptr) {
323  // initialize only if registration is requested
329  }
335 }
336 
337 
338 void
345 }
346 
347 
348 /****************************************************************************/
GUIEventType
Definition: GUIEvent.h:32
@ MESSAGE_OCCURRED
send when a message occured
@ GLDEBUG_OCCURRED
send when a gldebug occured
@ ERROR_OCCURRED
send when a error occured
@ DEBUG_OCCURRED
send when a debug occured
@ WARNING_OCCURRED
send when a warning occured
GUISelectedStorage gSelected
A global holder of selected objects.
SUMOTime string2time(const std::string &r)
convert string to SUMOTime
Definition: SUMOTime.cpp:45
#define TIME2STEPS(x)
Definition: SUMOTime.h:55
long long int SUMOTime
Definition: SUMOTime.h:32
T MIN2(T a, T b)
Definition: StdDefs.h:74
T MAX2(T a, T b)
Definition: StdDefs.h:80
int main(int argc, char *argv[])
void setView(GUIGlID id)
Centers the view onto the given artifact.
GUIGlID getGlID() const
Returns the numerical id of the object.
void unblockObject(GUIGlID id)
Marks an object as unblocked.
static GUIGlObjectStorage gIDStorage
A single static instance of this class.
GUIGlObject * getObjectBlocking(GUIGlID id)
Returns the object from the container locking it.
virtual const std::vector< SUMOTime > retrieveBreakpoints() const
retrieve breakpoints if provided by the application
virtual void setBreakpoints(const std::vector< SUMOTime > &)
Sets the breakpoints of the parent application.
static GUIMainWindow * getInstance()
get instance
GUIMainWindow * myMainWindow
OutputDevice * myGLDebugRetriever
void addSeparator()
Adds a a separator to this log window.
OutputDevice * myErrorRetriever
The instances of message retriever encapsulations.
void unregisterMsgHandlers()
unregister message handlers
static SUMOTime myBreakPointOffset
Offset when creating breakpoint by clicking on time links.
void clear()
Clears the window.
SUMOTime getTimeString(const FXString &text, const FXint pos, const FXint lineS, const FXint lineE) const
static bool myLocateLinks
whether messages are linked to the GUI elements
FXHiliteStyle * myStyles
The text colors used.
void appendMsg(GUIEventType eType, const std::string &msg)
Adds new text to the window.
virtual void setCursorPos(FXint pos, FXbool notify=FALSE)
set cursor position over a certain line
GUIMessageWindow(FXComposite *parent, GUIMainWindow *mainWindow)
Constructor.
OutputDevice * myWarningRetriever
OutputDevice * myMessageRetriever
OutputDevice * myDebugRetriever
~GUIMessageWindow()
Destructor.
const GUIGlObject * getActiveStringObject(const FXString &text, const FXint pos, const FXint lineS, const FXint lineE) const
get active string object
void registerMsgHandlers()
register message handlers
void toggleSelection(GUIGlID id)
Toggles selection of an object.
virtual void addRetriever(OutputDevice *retriever)
Adds a further retriever to the instance responsible for a certain msg type.
Definition: MsgHandler.cpp:186
static MsgHandler * getGLDebugInstance()
Returns the instance to add GLdebug to.
Definition: MsgHandler.cpp:98
static MsgHandler * getErrorInstance()
Returns the instance to add errors to.
Definition: MsgHandler.cpp:80
static MsgHandler * getDebugInstance()
Returns the instance to add debug to.
Definition: MsgHandler.cpp:89
static MsgHandler * getWarningInstance()
Returns the instance to add warnings to.
Definition: MsgHandler.cpp:67
virtual void removeRetriever(OutputDevice *retriever)
Removes the retriever from the handler.
Definition: MsgHandler.cpp:194
static MsgHandler * getMessageInstance()
Returns the instance to add normal messages to.
Definition: MsgHandler.cpp:54