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