SUMO - Simulation of Urban MObility
MFXAddEditTypedTable.cpp
Go to the documentation of this file.
1 /****************************************************************************/
7 // missing_desc
8 /****************************************************************************/
9 // SUMO, Simulation of Urban MObility; see http://sumo.dlr.de/
10 // Copyright (C) 2004-2017 DLR (http://www.dlr.de/) and contributors
11 /****************************************************************************/
12 //
13 // This file is part of SUMO.
14 // SUMO is free software: you can redistribute it and/or modify
15 // it under the terms of the GNU General Public License as published by
16 // the Free Software Foundation, either version 3 of the License, or
17 // (at your option) any later version.
18 //
19 /****************************************************************************/
20 
21 
22 // ===========================================================================
23 // included modules
24 // ===========================================================================
25 #ifdef _MSC_VER
26 #include <windows_config.h>
27 #else
28 #include <config.h>
29 #endif
30 
31 #include <fx.h>
32 #include <fxkeys.h>
34 #include <utils/common/ToString.h>
35 #include "MFXAddEditTypedTable.h"
36 #include <iostream>
37 
38 
39 // Map
40 FXDEFMAP(MFXAddEditTypedTable) MFXAddEditTypedTableMap[] = {
41  FXMAPFUNC(SEL_CLICKED, 0, MFXAddEditTypedTable::onClicked),
42  FXMAPFUNC(SEL_DOUBLECLICKED, 0, MFXAddEditTypedTable::onDoubleClicked),
43  FXMAPFUNC(SEL_LEFTBUTTONRELEASE, 0, MFXAddEditTypedTable::onLeftBtnRelease),
44  FXMAPFUNC(SEL_LEFTBUTTONPRESS, 0, MFXAddEditTypedTable::onLeftBtnPress),
45 };
46 // Object implementation
47 FXIMPLEMENT(MFXAddEditTypedTable, FXTable, MFXAddEditTypedTableMap, ARRAYNUMBER(MFXAddEditTypedTableMap))
48 
49 
50 MFXAddEditTypedTable::MFXAddEditTypedTable(FXComposite* p, FXObject* tgt,
51  FXSelector sel, FXuint opts,
52  FXint x, FXint y, FXint w, FXint h,
53  FXint pl, FXint pr, FXint pt, FXint pb)
54  : FXTable(p, tgt, sel, opts, x, y, w, h, pl, pr, pt, pb) {}
55 
56 
58 
59 /*
60 void
61 MFXAddEditTypedTable::editItem(FXTableItem* item,FXint how)
62 {
63  if(item==0) {
64  editEnd();
65  return;
66  }
67  if(myWriteProtectedCols.find(myEditedCol)!=myWriteProtectedCols.end()) {
68  editEnd();
69  return;
70  }
71  FXTableItem* it= item;
72  myPreviousText = item->getText();
73  FXint x = getColumnX(myEditedCol) + getRowHeader()->getWidth() + xpos;
74  FXint y = getRowY(myEditedRow) + getColumnHeader()->getHeight() + ypos;
75  FXIcon* icon = item->getIcon();
76  if(icon) x += icon->getWidth() + 4;
77  FXint vw = getViewportWidth();
78  if(vertical->shown()) vw -= vertical->getWidth();
79  if(vw>getColumnWidth(myEditedCol)) {
80  vw = getColumnWidth(myEditedCol) + x;
81  }
82  switch(getCellType(myEditedCol)) {
83  case CT_UNDEFINED:
84  case CT_STRING:
85  myEditor->setText(it->getText());
86  myEditor->move(x, y);
87  myEditor->resize(vw - x + 1, getRowHeight(myEditedRow) + 1);
88  myEditor->show();
89  myEditor->raise();
90  myEditor->enable();
91  myEditor->setFocus();
92  myEditor->grab();
93  if(how == 'I') {
94  myEditor->killSelection();
95  myEditor->setCursorPos(0);
96  } else if(how == 'A') {
97  myEditor->killSelection();
98  myEditor->setCursorPos(myEditor->getText().length());
99  } else myEditor->selectAll();
100  break;
101  case CT_REAL:
102  {
103  try {
104  myNumberEditor->setValue(
105  TplConvert::_2double(it->getText().text()));
106  } catch (NumberFormatException &) {
107  } catch (EmptyData &) {
108  }
109  NumberCellParams p = getNumberCellParams(myEditedCol);
110  if(p.format!="undefined") {
111  myNumberEditor->setFormatString((char*) p.format.c_str());
112  myNumberEditor->setIncrements(p.steps1, p.steps2, p.steps3);
113  myNumberEditor->setRange(p.min, p.max);
114  }
115  myNumberEditor->move(x, y);
116  myNumberEditor->resize(vw - x + 1, getRowHeight(myEditedRow) + 1);
117  myNumberEditor->show();
118  myNumberEditor->raise();
119  myNumberEditor->setFocus();
120  myNumberEditor->selectAll();
121  }
122  //myNumberEditor->setRange(0,1000);
123  break;
124  case CT_INT:
125  {
126  try {
127  myNumberEditor->setValue(
128  TplConvert::_2int(it->getText().text()));
129  } catch (NumberFormatException &) {
130  } catch (EmptyData &) {
131  }
132  NumberCellParams p = getNumberCellParams(myEditedCol);
133  if(p.format!="undefined") {
134  myNumberEditor->setFormatString((char*) p.format.c_str());
135  myNumberEditor->setIncrements(p.steps1, p.steps2, p.steps3);
136  myNumberEditor->setRange(p.min, p.max);
137  }
138  myNumberEditor->move(x, y);
139  myNumberEditor->resize(vw - x + 1, getRowHeight(myEditedRow) + 1);
140  myNumberEditor->show();
141  myNumberEditor->raise();
142  myNumberEditor->setFocus();
143  myNumberEditor->selectAll();
144  }
145  break;
146  case CT_BOOL:
147  try {
148  myBoolEditor->setCheck(
149  TplConvert::_2bool(it->getText().text())
150  ? true : false);
151  } catch (NumberFormatException &) {
152  } catch (EmptyData &) {
153  }
154  myBoolEditor->move(x, y);
155  myBoolEditor->resize(vw - x + 1, getRowHeight(myEditedRow) + 1);
156  myBoolEditor->show();
157  myBoolEditor->raise();
158  myBoolEditor->setFocus();
159  break;
160  case CT_ENUM:
161  {
162  myEnumEditor->hide();
163  myEnumEditor->clearItems();
164  if(myEnums.size()>myEditedCol) {
165  for(int i=0; i<myEnums[myEditedCol].size(); i++) {
166  myEnumEditor->appendItem(myEnums[myEditedCol][i].c_str());
167  }
168  }
169  if(myEnumEditor->findItem(it->getText())>=0) {
170  myEnumEditor->setCurrentItem(
171  myEnumEditor->findItem(it->getText()));
172  } else {
173  myEnumEditor->setCurrentItem(0);
174  }
175  myEnumEditor->setNumVisible(
176  myEnums[myEditedCol].size()<10
177  ? myEnums[myEditedCol].size()
178  : 10);
179  myEnumEditor->layout();
180  y = getRowY(myEditedRow) + getColumnHeader()->getHeight() + ypos
181  - getRowHeight(myEditedRow);
182  myEnumEditor->move(x, y);
183  myEnumEditor->resize(vw - x + 1, getRowHeight(myEditedRow) + 1);
184  myEnumEditor->show();
185  myEnumEditor->raise();
186  myEnumEditor->setFocus();
187  }
188  break;
189  default:
190  throw 1;
191  }
192  myEditedItem = it;
193 }
194 */
195 
196 
197 FXWindow*
199  register FXTableItem* item = cells[r * ncols + c];
200  if (item == NULL) {
201  return 0;
202 // cells[r * ncols + c] = item = createItem("", NULL, NULL);
203 // if (isItemSelected(r, c)) {
204 // item->setSelected(FALSE);
205 // }
206  }
207  delete editor;
208  editor = NULL;
209  switch (getCellType(c)) {
210  case CT_UNDEFINED:
211  case CT_STRING: {
212  register FXTextField* field;
213  register FXuint justify = 0;
214  field = new FXTextField(this, 1, NULL, 0, TEXTFIELD_ENTER_ONLY, 0, 0, 0, 0, getMarginLeft(), getMarginRight(), getMarginTop(), getMarginBottom());
215  // !!! if(state&LEFT) justify|=JUSTIFY_LEFT;
216  // !!! if(state&RIGHT) justify|=JUSTIFY_RIGHT;
217  // !!! if(state&TOP) justify|=JUSTIFY_TOP;
218  // !!! if(state&BOTTOM) justify|=JUSTIFY_BOTTOM;
219  field->create();
220  field->setJustify(justify);
221  field->setFont(getFont());
222  field->setBackColor(getBackColor());
223  field->setTextColor(getTextColor());
224  field->setSelBackColor(getSelBackColor());
225  field->setSelTextColor(getSelTextColor());
226  field->setText(item->getText());
227  field->selectAll();
228  return field;
229  }
230  case CT_REAL:
231 // return myNumberEditor;
232  case CT_INT: {
233  register FXRealSpinDial* field;
234  //register FXuint justify=0;
235  field = new FXRealSpinDial(this, 1, NULL, 0, TEXTFIELD_ENTER_ONLY, 0, 0, 0, 0, getMarginLeft(), getMarginRight(), getMarginTop(), getMarginBottom());
236  // !!! if(state&LEFT) justify|=JUSTIFY_LEFT;
237  // !!! if(state&RIGHT) justify|=JUSTIFY_RIGHT;
238  // !!! if(state&TOP) justify|=JUSTIFY_TOP;
239  // !!! if(state&BOTTOM) justify|=JUSTIFY_BOTTOM;
240  field->create();
241 // field->setJustify(justify);
242  field->setFont(getFont());
243  field->setBackColor(getBackColor());
244  field->setTextColor(getTextColor());
245  field->setSelBackColor(getSelBackColor());
246  field->setSelTextColor(getSelTextColor());
248  if (p.format != "undefined") {
249  field->setFormatString((char*) p.format.c_str());
250  field->setIncrements(p.steps1, p.steps2, p.steps3);
251  field->setRange(p.min, p.max);
252  }
253  try {
254  if (getCellType(c) == CT_REAL) {
255  field->setValue(TplConvert::_2double(item->getText().text()));
256  } else {
257  field->setValue(TplConvert::_2int(item->getText().text()));
258  }
259  } catch (NumberFormatException&) {
260  field->setValue(0);
261  }
262  field->selectAll();
263  return field;
264  }
265  case CT_BOOL:
266 // return myBoolEditor;
267  case CT_ENUM:
268 // return myEnumEditor;
269  default:
270  throw 1;
271  }
272 }
273 
274 
275 // Cancel editing cell
276 void
278  if (editor) {
279  delete editor;
280  input.fm.row = -1;
281  input.to.row = -1;
282  input.fm.col = -1;
283  input.to.col = -1;
284  editor = NULL;
285  }
286 }
287 
288 // Done with editing cell
289 void
291  bool set = false;
292  FXTableRange tablerange = input;
293  if (editor) {
294  //
295  //
296  FXRealSpinDial* dial = dynamic_cast<FXRealSpinDial*>(editor);
297  if (dial != 0) {
298  if (!dial->getDial().grabbed()) {
299  set = true;
300  } else {
301  setItemFromControl_NoRelease(input.fm.row, input.fm.col, editor);
302  }
303  }
304  if (dynamic_cast<FXTextField*>(editor) != 0) {
305  set = true;
306  }
307  }
308  if (set) {
309  setItemFromControl(input.fm.row, input.fm.col, editor);
310  cancelInput();
311  if (notify && target) {
312  target->tryHandle(this, FXSEL(SEL_REPLACED, message), (void*)&tablerange);
313  }
314  }
315 }
316 
317 
318 
319 
320 void
321 MFXAddEditTypedTable::setItemFromControl(FXint r, FXint c, FXWindow* control) {
322  register FXTableItem* item = cells[r * ncols + c];
323  if (item == NULL) {
324  cells[r * ncols + c] = item = createItem("", NULL, NULL);
325  if (isItemSelected(r, c)) {
326  item->setSelected(FALSE);
327  }
328  }
329  switch (getCellType(c)) {
330  case CT_UNDEFINED:
331  case CT_STRING:
332  item->setFromControl(control);
333  break;
334  case CT_REAL:
335  item->setText(toString(static_cast<FXRealSpinDial*>(control)->getValue()).c_str());
336  break;
337  case CT_INT:
338  item->setText(toString((int) static_cast<FXRealSpinDial*>(control)->getValue()).c_str());
339  break;
340  case CT_BOOL:
341 // return myBoolEditor;
342  case CT_ENUM:
343 // return myEnumEditor;
344  default:
345  throw 1;
346  }
347 // current.row = -1;
348 // current.col = -1;
349  EditedTableItem edited;
350  edited.item = item;
351  edited.row = r;
352  edited.col = c;
353  edited.updateOnly = false;
354  killSelection(true);
355  bool accepted = true;
356  if (target) {
357  if (!target->handle(this, FXSEL(SEL_CHANGED, ID_TEXT_CHANGED), (void*) &edited)) {
358  accepted = false;
359  // !!! item->setText(myPreviousText);
360  }
361  }
362  if (accepted) {
363  if (edited.row == getNumRows() - 1) {
364  insertRows(getNumRows(), 1, true);
365  for (int i = 0; i < getNumColumns(); i++) {
366  setItemText(getNumRows() - 1, i, "");
367  setItemJustify(getNumRows() - 1, i, JUSTIFY_CENTER_X);
368  }
369  }
370  }
371  mode = MOUSE_NONE;
372 }
373 
374 
375 void
376 MFXAddEditTypedTable::setItemFromControl_NoRelease(FXint r, FXint c, FXWindow* control) {
377  register FXTableItem* item = cells[r * ncols + c];
378  if (item == NULL) {
379  return;
380  }
381  switch (getCellType(c)) {
382  case CT_UNDEFINED:
383  case CT_STRING:
384  item->setFromControl(control);
385  break;
386  case CT_REAL:
387  item->setText(toString(static_cast<FXRealSpinDial*>(control)->getValue()).c_str());
388  break;
389  case CT_INT:
390  item->setText(toString((int) static_cast<FXRealSpinDial*>(control)->getValue()).c_str());
391  break;
392  case CT_BOOL:
393 // return myBoolEditor;
394  case CT_ENUM:
395 // return myEnumEditor;
396  default:
397  throw 1;
398  }
399  EditedTableItem edited;
400  edited.item = item;
401  edited.row = r;
402  edited.col = c;
403  edited.updateOnly = true;
404  if (target) {
405  if (!target->handle(this, FXSEL(SEL_CHANGED, ID_TEXT_CHANGED), (void*) &edited)) {
406  // !!! item->setText(myPreviousText);
407  }
408  }
409 }
410 
411 
412 // Released button
413 long MFXAddEditTypedTable::onLeftBtnRelease(FXObject*, FXSelector, void* ptr) {
414  FXEvent* event = (FXEvent*)ptr;
415  if (isEnabled()) {
416  ungrab();
417  flags &= ~FLAG_PRESSED;
418  flags |= FLAG_UPDATE;
419  mode = MOUSE_NONE;
420  stopAutoScroll();
421  setDragCursor(getApp()->getDefaultCursor(DEF_ARROW_CURSOR));
422  if (target && target->tryHandle(this, FXSEL(SEL_LEFTBUTTONRELEASE, message), ptr)) {
423  return 1;
424  }
425 
426  // Scroll to make item visibke
427  makePositionVisible(current.row, current.col);
428 
429  // Update anchor
430  //setAnchorItem(current.row,current.col); // FIXME look into the selection stuff
431 
432  // Generate clicked callbacks
433  if (event->click_count == 1) {
434  handle(this, FXSEL(SEL_CLICKED, 0), (void*)&current);
435  } else if (event->click_count == 2) {
436  handle(this, FXSEL(SEL_DOUBLECLICKED, 0), (void*)&current);
437  } else if (event->click_count == 3) {
438  handle(this, FXSEL(SEL_TRIPLECLICKED, 0), (void*)&current);
439  }
440 
441  // Command callback only when clicked on item
442  if (0 <= current.row && 0 <= current.col && isItemEnabled(current.row, current.col)) {
443  handle(this, FXSEL(SEL_COMMAND, 0), (void*)&current);
444  }
445  return 1;
446  }
447  return 0;
448 }
449 
450 
451 // Pressed button
452 long
453 MFXAddEditTypedTable::onLeftBtnPress(FXObject*, FXSelector, void* ptr) {
454  FXEvent* event = (FXEvent*)ptr;
455  FXTablePos tablepos;
456  flags &= ~FLAG_TIP;
457  handle(this, FXSEL(SEL_FOCUS_SELF, 0), ptr);
458  if (isEnabled()) {
459  grab();
460  if (target && target->tryHandle(this, FXSEL(SEL_LEFTBUTTONPRESS, message), ptr)) {
461  return 1;
462  }
463 
464  // Cell being clicked on
465  tablepos.row = rowAtY(event->win_y);
466  tablepos.col = colAtX(event->win_x);
467 
468  // Outside table
469  if (tablepos.row < 0 || tablepos.row >= nrows || tablepos.col < 0 || tablepos.col >= ncols) {
470  setCurrentItem(-1, -1, TRUE);
471  return 0;
472  }
473 
474  // Change current item
475  bool wasEdited = editor != 0;
476  setCurrentItem(tablepos.row, tablepos.col, TRUE);
477  if (!wasEdited) {
478 
479  // Select or deselect
480  if (event->state & SHIFTMASK) {
481  if (0 <= anchor.row && 0 <= anchor.col) {
482  if (isItemEnabled(anchor.row, anchor.col)) {
483  extendSelection(current.row, current.col, TRUE);
484  }
485  } else {
486  setAnchorItem(current.row, current.col);
487  if (isItemEnabled(current.row, current.col)) {
488  extendSelection(current.row, current.col, TRUE);
489  }
490  }
491  mode = MOUSE_SELECT;
492  } else {
493  if (isItemEnabled(current.row, current.col)) {
494  killSelection(TRUE);
495  setAnchorItem(current.row, current.col);
496  extendSelection(current.row, current.col, TRUE);
497  } else {
498  setAnchorItem(current.row, current.col);
499  }
500  mode = MOUSE_SELECT;
501  }
502  }
503  flags &= ~FLAG_UPDATE;
504  flags |= FLAG_PRESSED;
505  return 1;
506  }
507  return 0;
508 }
509 
510 
511 
512 // Clicked in list
513 long
514 MFXAddEditTypedTable::onClicked(FXObject*, FXSelector , void* ptr) {
515  if (editor) {
516  delete editor;
517  input.fm.row = -1;
518  input.to.row = -1;
519  input.fm.col = -1;
520  input.to.col = -1;
521  editor = NULL;
522  current.row = -1;
523  current.col = -1;
524  }
525  if (target && target->tryHandle(this, FXSEL(SEL_CLICKED, message), ptr)) {
526  return 1;
527  }
528  handle(this, FXSEL(SEL_COMMAND, ID_START_INPUT), NULL);
529  return 1;
530 }
531 
532 
533 // Double clicked in list; ptr may or may not point to an item
534 long MFXAddEditTypedTable::onDoubleClicked(FXObject*, FXSelector, void* ptr) {
535  if (editor) {
536  delete editor;
537  input.fm.row = -1;
538  input.to.row = -1;
539  input.fm.col = -1;
540  input.to.col = -1;
541  editor = NULL;
542  } else {
543  if (target && target->tryHandle(this, FXSEL(SEL_CLICKED, message), ptr)) {
544  return 1;
545  }
546  handle(this, FXSEL(SEL_COMMAND, ID_START_INPUT), NULL);
547  }
548  return 1;
549 }
550 
551 
552 CellType
554  if ((int)myCellTypes.size() <= pos) {
555  return CT_UNDEFINED;
556  }
557  return myCellTypes[pos];
558 }
559 
560 
561 void
563  while ((int)myCellTypes.size() < pos + 1) {
564  myCellTypes.push_back(CT_UNDEFINED);
565  }
566  myCellTypes[pos] = t;
567 }
568 
569 void
571  double steps1,
572  double steps2,
573  double steps3,
574  const std::string& format) {
575  while ((int)myNumberCellParams.size() <= pos) {
576  NumberCellParams np;
577  np.format = "undefined";
578  myNumberCellParams.push_back(np);
579  }
580  NumberCellParams np;
581  np.pos = (int)(pos);
582  np.min = min;
583  np.max = max;
584  np.steps1 = steps1;
585  np.steps2 = steps2;
586  np.steps3 = steps3;
587  np.format = format;
588  myNumberCellParams[pos] = np;
589 }
590 
591 
594  if ((int)myNumberCellParams.size() <= pos) {
595  NumberCellParams np;
596  np.format = "undefined";
597  return np;
598  }
599  return myNumberCellParams[pos];
600 }
601 
602 
603 
604 void
606  const std::vector<std::string>& params) {
607  while ((int)myEnums.size() <= pos) {
608  myEnums.push_back(std::vector<std::string>());
609  }
610  myEnums[pos] = params;
611 }
612 
613 
614 void
616  const std::string& e) {
617  while ((int)myEnums.size() <= pos) {
618  myEnums.push_back(std::vector<std::string>());
619  }
620  myEnums[pos].push_back(e);
621 }
622 
623 
624 const std::vector<std::string>&
626  return myEnums[pos];
627 }
628 
629 
630 
631 /****************************************************************************/
632 
std::vector< std::vector< std::string > > myEnums
void setItemFromControl_NoRelease(FXint r, FXint c, FXWindow *control)
#define min(a, b)
Definition: polyfonts.c:66
long onDoubleClicked(FXObject *, FXSelector, void *ptr)
void setEnums(int pos, const std::vector< std::string > &params)
std::vector< NumberCellParams > myNumberCellParams
std::vector< CellType > myCellTypes
void setNumberCellParams(int pos, double min, double max, double steps1, double steps2, double steps3, const std::string &format)
void acceptInput(FXbool notify)
void setCellType(int pos, CellType t)
#define max(a, b)
Definition: polyfonts.c:65
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:56
CellType getCellType(int pos) const
long onClicked(FXObject *, FXSelector, void *ptr)
long onLeftBtnRelease(FXObject *, FXSelector, void *ptr)
const std::vector< std::string > & getEnums(int pos) const
static int _2int(const E *const data)
converts a char-type array into the integer value described by it
Definition: TplConvert.h:149
NumberCellParams getNumberCellParams(int pos) const
long onLeftBtnPress(FXObject *, FXSelector, void *ptr)
static double _2double(const E *const data)
converts a char-type array into the double value described by it
Definition: TplConvert.h:297
void addEnum(int pos, const std::string &e)
virtual FXWindow * getControlForItem(FXint r, FXint c)
virtual void setItemFromControl(FXint r, FXint c, FXWindow *control)
FXDEFMAP(MFXAddEditTypedTable) MFXAddEditTypedTableMap[]