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<char>::_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<char>::_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<char>::_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<char>::_2SUMOReal(item->getText().text()));
260  } else {
261  field->setValue(TplConvert<char>::_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  bool accepted = true;
409  if (target) {
410  if (!target->handle(this, FXSEL(SEL_CHANGED, ID_TEXT_CHANGED), (void*) &edited)) {
411  accepted = false;
412  // !!! item->setText(myPreviousText);
413  }
414  }
415 }
416 
417 
418 // Released button
419 long MFXAddEditTypedTable::onLeftBtnRelease(FXObject*, FXSelector, void* ptr) {
420  FXEvent* event = (FXEvent*)ptr;
421  if (isEnabled()) {
422  ungrab();
423  flags &= ~FLAG_PRESSED;
424  flags |= FLAG_UPDATE;
425  mode = MOUSE_NONE;
426  stopAutoScroll();
427  setDragCursor(getApp()->getDefaultCursor(DEF_ARROW_CURSOR));
428  if (target && target->tryHandle(this, FXSEL(SEL_LEFTBUTTONRELEASE, message), ptr)) {
429  return 1;
430  }
431 
432  // Scroll to make item visibke
433  makePositionVisible(current.row, current.col);
434 
435  // Update anchor
436  //setAnchorItem(current.row,current.col); // FIXME look into the selection stuff
437 
438  // Generate clicked callbacks
439  if (event->click_count == 1) {
440  handle(this, FXSEL(SEL_CLICKED, 0), (void*)&current);
441  } else if (event->click_count == 2) {
442  handle(this, FXSEL(SEL_DOUBLECLICKED, 0), (void*)&current);
443  } else if (event->click_count == 3) {
444  handle(this, FXSEL(SEL_TRIPLECLICKED, 0), (void*)&current);
445  }
446 
447  // Command callback only when clicked on item
448  if (0 <= current.row && 0 <= current.col && isItemEnabled(current.row, current.col)) {
449  handle(this, FXSEL(SEL_COMMAND, 0), (void*)&current);
450  }
451  return 1;
452  }
453  return 0;
454 }
455 
456 
457 // Pressed button
458 long
460  FXEvent* event = (FXEvent*)ptr;
461  FXTablePos tablepos;
462  flags &= ~FLAG_TIP;
463  handle(this, FXSEL(SEL_FOCUS_SELF, 0), ptr);
464  if (isEnabled()) {
465  grab();
466  if (target && target->tryHandle(this, FXSEL(SEL_LEFTBUTTONPRESS, message), ptr)) {
467  return 1;
468  }
469 
470  // Cell being clicked on
471  tablepos.row = rowAtY(event->win_y);
472  tablepos.col = colAtX(event->win_x);
473 
474  // Outside table
475  if (tablepos.row < 0 || tablepos.row >= nrows || tablepos.col < 0 || tablepos.col >= ncols) {
476  setCurrentItem(-1, -1, TRUE);
477  return 0;
478  }
479 
480  // Change current item
481  bool wasEdited = editor != 0;
482  setCurrentItem(tablepos.row, tablepos.col, TRUE);
483  if (!wasEdited) {
484 
485  // Select or deselect
486  if (event->state & SHIFTMASK) {
487  if (0 <= anchor.row && 0 <= anchor.col) {
488  if (isItemEnabled(anchor.row, anchor.col)) {
489  extendSelection(current.row, current.col, TRUE);
490  }
491  } else {
492  setAnchorItem(current.row, current.col);
493  if (isItemEnabled(current.row, current.col)) {
494  extendSelection(current.row, current.col, TRUE);
495  }
496  }
497  mode = MOUSE_SELECT;
498  } else {
499  if (isItemEnabled(current.row, current.col)) {
500  killSelection(TRUE);
501  setAnchorItem(current.row, current.col);
502  extendSelection(current.row, current.col, TRUE);
503  } else {
504  setAnchorItem(current.row, current.col);
505  }
506  mode = MOUSE_SELECT;
507  }
508  }
509  flags &= ~FLAG_UPDATE;
510  flags |= FLAG_PRESSED;
511  return 1;
512  }
513  return 0;
514 }
515 
516 
517 
518 // Clicked in list
519 long
520 MFXAddEditTypedTable::onClicked(FXObject*, FXSelector , void* ptr) {
521  if (editor) {
522  delete editor;
523  input.fm.row = -1;
524  input.to.row = -1;
525  input.fm.col = -1;
526  input.to.col = -1;
527  editor = NULL;
528  current.row = -1;
529  current.col = -1;
530  }
531  if (target && target->tryHandle(this, FXSEL(SEL_CLICKED, message), ptr)) {
532  return 1;
533  }
534  handle(this, FXSEL(SEL_COMMAND, ID_START_INPUT), NULL);
535  return 1;
536 }
537 
538 
539 // Double clicked in list; ptr may or may not point to an item
540 long MFXAddEditTypedTable::onDoubleClicked(FXObject*, FXSelector, void* ptr) {
541  if (editor) {
542  delete editor;
543  input.fm.row = -1;
544  input.to.row = -1;
545  input.fm.col = -1;
546  input.to.col = -1;
547  editor = NULL;
548  } else {
549  if (target && target->tryHandle(this, FXSEL(SEL_CLICKED, message), ptr)) {
550  return 1;
551  }
552  handle(this, FXSEL(SEL_COMMAND, ID_START_INPUT), NULL);
553  }
554  return 1;
555 }
556 
557 
558 CellType
560  if (myCellTypes.size() <= pos) {
561  return CT_UNDEFINED;
562  }
563  return myCellTypes[pos];
564 }
565 
566 
567 void
569  while (myCellTypes.size() < pos + 1) {
570  myCellTypes.push_back(CT_UNDEFINED);
571  }
572  myCellTypes[pos] = t;
573 }
574 
575 void
577  double steps1,
578  double steps2,
579  double steps3,
580  const std::string& format) {
581  while (myNumberCellParams.size() <= pos) {
582  NumberCellParams np;
583  np.format = "undefined";
584  myNumberCellParams.push_back(np);
585  }
586  NumberCellParams np;
587  np.pos = (int)(pos);
588  np.min = min;
589  np.max = max;
590  np.steps1 = steps1;
591  np.steps2 = steps2;
592  np.steps3 = steps3;
593  np.format = format;
594  myNumberCellParams[pos] = np;
595 }
596 
597 
600  if (myNumberCellParams.size() <= pos) {
601  NumberCellParams np;
602  np.format = "undefined";
603  return np;
604  }
605  return myNumberCellParams[pos];
606 }
607 
608 
609 
610 void
612  const std::vector<std::string> &params) {
613  while (myEnums.size() <= pos) {
614  myEnums.push_back(std::vector<std::string>());
615  }
616  myEnums[pos] = params;
617 }
618 
619 
620 void
622  const std::string& e) {
623  while (myEnums.size() <= pos) {
624  myEnums.push_back(std::vector<std::string>());
625  }
626  myEnums[pos].push_back(e);
627 }
628 
629 
630 const std::vector<std::string> &
632  return myEnums[pos];
633 }
634 
635 
636 
637 /****************************************************************************/
638