SUMO - Simulation of Urban MObility
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
MFXAddEditTypedTable.cpp
Go to the documentation of this file.
1 /****************************************************************************/
7 // missing_desc
8 /****************************************************************************/
9 // SUMO, Simulation of Urban MObility; see http://sumo.sourceforge.net/
10 // Copyright (C) 2001-2012 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 
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
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