SUMO - Simulation of Urban MObility

MFXAddEditTypedTable.cpp

Go to the documentation of this file.
00001 /****************************************************************************/
00007 // missing_desc
00008 /****************************************************************************/
00009 // SUMO, Simulation of Urban MObility; see http://sumo.sourceforge.net/
00010 // Copyright (C) 2001-2011 DLR (http://www.dlr.de/) and contributors
00011 /****************************************************************************/
00012 //
00013 //   This program is free software; you can redistribute it and/or modify
00014 //   it under the terms of the GNU General Public License as published by
00015 //   the Free Software Foundation; either version 2 of the License, or
00016 //   (at your option) any later version.
00017 //
00018 /****************************************************************************/
00019 
00020 
00021 // ===========================================================================
00022 // included modules
00023 // ===========================================================================
00024 #ifdef _MSC_VER
00025 #include <windows_config.h>
00026 #else
00027 #include <config.h>
00028 #endif
00029 
00030 #include <fx.h>
00031 #include <fxkeys.h>
00032 #include <utils/common/TplConvert.h>
00033 #include <utils/common/ToString.h>
00034 #include "MFXAddEditTypedTable.h"
00035 #include <iostream>
00036 
00037 #ifdef CHECK_MEMORY_LEAKS
00038 #include <foreign/nvwa/debug_new.h>
00039 #endif // CHECK_MEMORY_LEAKS
00040 
00041 
00042 // Map
00043 FXDEFMAP(MFXAddEditTypedTable) MFXAddEditTypedTableMap[]= {
00044     FXMAPFUNC(SEL_CLICKED,0,MFXAddEditTypedTable::onClicked),
00045     FXMAPFUNC(SEL_DOUBLECLICKED,0,MFXAddEditTypedTable::onDoubleClicked),
00046     FXMAPFUNC(SEL_LEFTBUTTONRELEASE,0,MFXAddEditTypedTable::onLeftBtnRelease),
00047     FXMAPFUNC(SEL_LEFTBUTTONPRESS,0,MFXAddEditTypedTable::onLeftBtnPress),
00048 };
00049 // Object implementation
00050 FXIMPLEMENT(MFXAddEditTypedTable,FXTable,MFXAddEditTypedTableMap,ARRAYNUMBER(MFXAddEditTypedTableMap))
00051 
00052 
00053 MFXAddEditTypedTable::MFXAddEditTypedTable(FXComposite* p, FXObject* tgt,
00054         FXSelector sel, FXuint opts,
00055         FXint x, FXint y, FXint w, FXint h,
00056         FXint pl,FXint pr,FXint pt,FXint pb)
00057     : FXTable(p, tgt, sel, opts, x, y, w, h, pl, pr, pt, pb) {}
00058 
00059 
00060 MFXAddEditTypedTable::~MFXAddEditTypedTable() {}
00061 
00062 /*
00063 void
00064 MFXAddEditTypedTable::editItem(FXTableItem* item,FXint how)
00065 {
00066     if(item==0) {
00067         editEnd();
00068         return;
00069     }
00070     if(myWriteProtectedCols.find(myEditedCol)!=myWriteProtectedCols.end()) {
00071         editEnd();
00072         return;
00073     }
00074     FXTableItem* it= item;
00075     myPreviousText = item->getText();
00076     FXint x = getColumnX(myEditedCol) + getRowHeader()->getWidth() + xpos;
00077     FXint y = getRowY(myEditedRow) + getColumnHeader()->getHeight() + ypos;
00078     FXIcon* icon = item->getIcon();
00079     if(icon) x += icon->getWidth() + 4;
00080     FXint vw = getViewportWidth();
00081     if(vertical->shown()) vw -= vertical->getWidth();
00082     if(vw>getColumnWidth(myEditedCol)) {
00083         vw = getColumnWidth(myEditedCol) + x;
00084     }
00085     switch(getCellType(myEditedCol)) {
00086     case CT_UNDEFINED:
00087     case CT_STRING:
00088         myEditor->setText(it->getText());
00089         myEditor->move(x, y);
00090         myEditor->resize(vw - x + 1, getRowHeight(myEditedRow) + 1);
00091         myEditor->show();
00092         myEditor->raise();
00093         myEditor->enable();
00094         myEditor->setFocus();
00095         myEditor->grab();
00096         if(how == 'I') {
00097             myEditor->killSelection();
00098             myEditor->setCursorPos(0);
00099         } else if(how == 'A') {
00100             myEditor->killSelection();
00101             myEditor->setCursorPos(myEditor->getText().length());
00102         } else myEditor->selectAll();
00103         break;
00104     case CT_REAL:
00105         {
00106             try {
00107                 myNumberEditor->setValue(
00108                     TplConvert<char>::_2SUMOReal(it->getText().text()));
00109             } catch (NumberFormatException &) {
00110             } catch (EmptyData &) {
00111             }
00112             NumberCellParams p = getNumberCellParams(myEditedCol);
00113             if(p.format!="undefined") {
00114                 myNumberEditor->setFormatString((char*) p.format.c_str());
00115                 myNumberEditor->setIncrements(p.steps1, p.steps2, p.steps3);
00116                 myNumberEditor->setRange(p.min, p.max);
00117             }
00118             myNumberEditor->move(x, y);
00119             myNumberEditor->resize(vw - x + 1, getRowHeight(myEditedRow) + 1);
00120             myNumberEditor->show();
00121             myNumberEditor->raise();
00122             myNumberEditor->setFocus();
00123             myNumberEditor->selectAll();
00124         }
00125         //myNumberEditor->setRange(0,1000);
00126         break;
00127     case CT_INT:
00128         {
00129             try {
00130                 myNumberEditor->setValue(
00131                     TplConvert<char>::_2int(it->getText().text()));
00132             } catch (NumberFormatException &) {
00133             } catch (EmptyData &) {
00134             }
00135             NumberCellParams p = getNumberCellParams(myEditedCol);
00136             if(p.format!="undefined") {
00137                 myNumberEditor->setFormatString((char*) p.format.c_str());
00138                 myNumberEditor->setIncrements(p.steps1, p.steps2, p.steps3);
00139                 myNumberEditor->setRange(p.min, p.max);
00140             }
00141             myNumberEditor->move(x, y);
00142             myNumberEditor->resize(vw - x + 1, getRowHeight(myEditedRow) + 1);
00143             myNumberEditor->show();
00144             myNumberEditor->raise();
00145             myNumberEditor->setFocus();
00146             myNumberEditor->selectAll();
00147         }
00148         break;
00149     case CT_BOOL:
00150         try {
00151             myBoolEditor->setCheck(
00152                 TplConvert<char>::_2bool(it->getText().text())
00153                 ? true : false);
00154         } catch (NumberFormatException &) {
00155         } catch (EmptyData &) {
00156         }
00157         myBoolEditor->move(x, y);
00158         myBoolEditor->resize(vw - x + 1, getRowHeight(myEditedRow) + 1);
00159         myBoolEditor->show();
00160         myBoolEditor->raise();
00161         myBoolEditor->setFocus();
00162         break;
00163     case CT_ENUM:
00164         {
00165             myEnumEditor->hide();
00166             myEnumEditor->clearItems();
00167             if(myEnums.size()>myEditedCol) {
00168                 for(size_t i=0; i<myEnums[myEditedCol].size(); i++) {
00169                     myEnumEditor->appendItem(myEnums[myEditedCol][i].c_str());
00170                 }
00171             }
00172             if(myEnumEditor->findItem(it->getText())>=0) {
00173                 myEnumEditor->setCurrentItem(
00174                     myEnumEditor->findItem(it->getText()));
00175             } else {
00176                 myEnumEditor->setCurrentItem(0);
00177             }
00178             myEnumEditor->setNumVisible(
00179                 myEnums[myEditedCol].size()<10
00180                 ? myEnums[myEditedCol].size()
00181                 : 10);
00182             myEnumEditor->layout();
00183             y = getRowY(myEditedRow) + getColumnHeader()->getHeight() + ypos
00184                 - getRowHeight(myEditedRow);
00185             myEnumEditor->move(x, y);
00186             myEnumEditor->resize(vw - x + 1, getRowHeight(myEditedRow) + 1);
00187             myEnumEditor->show();
00188             myEnumEditor->raise();
00189             myEnumEditor->setFocus();
00190         }
00191         break;
00192     default:
00193         throw 1;
00194     }
00195     myEditedItem = it;
00196 }
00197 */
00198 
00199 
00200 FXWindow*
00201 MFXAddEditTypedTable::getControlForItem(FXint r,FXint c) {
00202     register FXTableItem* item=cells[r*ncols+c];
00203     if (item==NULL) {
00204         return 0;
00205         cells[r*ncols+c]=item=createItem("",NULL,NULL);
00206         if (isItemSelected(r,c)) {
00207             item->setSelected(FALSE);
00208         }
00209     }
00210     delete editor;
00211     editor=NULL;
00212     switch (getCellType(c)) {
00213     case CT_UNDEFINED:
00214     case CT_STRING: {
00215         register FXTextField* field;
00216         register FXuint justify=0;
00217         field=new FXTextField(this,1,NULL,0,TEXTFIELD_ENTER_ONLY,0,0,0,0,getMarginLeft(),getMarginRight(),getMarginTop(),getMarginBottom());
00218         // !!! if(state&LEFT) justify|=JUSTIFY_LEFT;
00219         // !!! if(state&RIGHT) justify|=JUSTIFY_RIGHT;
00220         // !!! if(state&TOP) justify|=JUSTIFY_TOP;
00221         // !!! if(state&BOTTOM) justify|=JUSTIFY_BOTTOM;
00222         field->create();
00223         field->setJustify(justify);
00224         field->setFont(getFont());
00225         field->setBackColor(getBackColor());
00226         field->setTextColor(getTextColor());
00227         field->setSelBackColor(getSelBackColor());
00228         field->setSelTextColor(getSelTextColor());
00229         field->setText(item->getText());
00230         field->selectAll();
00231         return field;
00232     }
00233     case CT_REAL:
00234 //        return myNumberEditor;
00235     case CT_INT: {
00236         register FXRealSpinDial* field;
00237         //register FXuint justify=0;
00238         field=new FXRealSpinDial(this,1,NULL,0,TEXTFIELD_ENTER_ONLY,0,0,0,0,getMarginLeft(),getMarginRight(),getMarginTop(),getMarginBottom());
00239         // !!! if(state&LEFT) justify|=JUSTIFY_LEFT;
00240         // !!! if(state&RIGHT) justify|=JUSTIFY_RIGHT;
00241         // !!! if(state&TOP) justify|=JUSTIFY_TOP;
00242         // !!! if(state&BOTTOM) justify|=JUSTIFY_BOTTOM;
00243         field->create();
00244 //            field->setJustify(justify);
00245         field->setFont(getFont());
00246         field->setBackColor(getBackColor());
00247         field->setTextColor(getTextColor());
00248         field->setSelBackColor(getSelBackColor());
00249         field->setSelTextColor(getSelTextColor());
00250         NumberCellParams p = getNumberCellParams(c);
00251         if (p.format!="undefined") {
00252             field->setFormatString((char*) p.format.c_str());
00253             field->setIncrements(p.steps1, p.steps2, p.steps3);
00254             field->setRange(p.min, p.max);
00255         }
00256         try {
00257             if (getCellType(c)==CT_REAL) {
00258                 field->setValue(TplConvert<char>::_2SUMOReal(item->getText().text()));
00259             } else {
00260                 field->setValue(TplConvert<char>::_2int(item->getText().text()));
00261             }
00262         } catch (NumberFormatException&) {
00263             field->setValue(0);
00264         }
00265         field->selectAll();
00266         return field;
00267     }
00268     case CT_BOOL:
00269 //        return myBoolEditor;
00270     case CT_ENUM:
00271 //        return myEnumEditor;
00272     default:
00273         throw 1;
00274     }
00275 }
00276 
00277 
00278 // Cancel editing cell
00279 void
00280 MFXAddEditTypedTable::cancelInput() {
00281     if (editor) {
00282         delete editor;
00283         input.fm.row=-1;
00284         input.to.row=-1;
00285         input.fm.col=-1;
00286         input.to.col=-1;
00287         editor=NULL;
00288     }
00289 }
00290 
00291 // Done with editing cell
00292 void
00293 MFXAddEditTypedTable::acceptInput(FXbool notify) {
00294     bool set = false;
00295     FXTableRange tablerange=input;
00296     if (editor) {
00297         //
00298         //
00299         FXRealSpinDial* dial = dynamic_cast<FXRealSpinDial*>(editor);
00300         if (dial!=0) {
00301             if (!dial->getDial().grabbed()) {
00302                 set = true;
00303             } else {
00304                 setItemFromControl_NoRelease(input.fm.row,input.fm.col,editor);
00305             }
00306         }
00307         if (dynamic_cast<FXTextField*>(editor)!=0) {
00308             set = true;
00309         }
00310     }
00311     if (set) {
00312         setItemFromControl(input.fm.row,input.fm.col,editor);
00313         cancelInput();
00314         if (notify && target) {
00315             target->tryHandle(this,FXSEL(SEL_REPLACED,message),(void*)&tablerange);
00316         }
00317     }
00318 }
00319 
00320 
00321 
00322 
00323 void
00324 MFXAddEditTypedTable::setItemFromControl(FXint r,FXint c,FXWindow* control) {
00325     register FXTableItem* item=cells[r*ncols+c];
00326     if (item==NULL) {
00327         cells[r*ncols+c]=item=createItem("",NULL,NULL);
00328         if (isItemSelected(r,c)) {
00329             item->setSelected(FALSE);
00330         }
00331     }
00332     switch (getCellType(c)) {
00333     case CT_UNDEFINED:
00334     case CT_STRING:
00335         item->setFromControl(control);
00336         break;
00337     case CT_REAL:
00338         item->setText(toString(static_cast<FXRealSpinDial*>(control)->getValue()).c_str());
00339         break;
00340     case CT_INT:
00341         item->setText(toString((int) static_cast<FXRealSpinDial*>(control)->getValue()).c_str());
00342         break;
00343     case CT_BOOL:
00344 //        return myBoolEditor;
00345     case CT_ENUM:
00346 //        return myEnumEditor;
00347     default:
00348         throw 1;
00349     }
00350 //    current.row = -1;
00351 //    current.col = -1;
00352     EditedTableItem edited;
00353     edited.item = item;
00354     edited.row = r;
00355     edited.col = c;
00356     edited.updateOnly = false;
00357     killSelection(true);
00358     bool accepted = true;
00359     if (target) {
00360         if (!target->handle(this,FXSEL(SEL_CHANGED, ID_TEXT_CHANGED), (void*) &edited)) {
00361             accepted = false;
00362             // !!! item->setText(myPreviousText);
00363         }
00364     }
00365     if (accepted) {
00366         if (edited.row==getNumRows()-1) {
00367             insertRows(getNumRows(), 1, true);
00368             for (int i=0; i<getNumColumns(); i++) {
00369                 setItemText(getNumRows()-1, i, "");
00370                 setItemJustify(getNumRows()-1, i, JUSTIFY_CENTER_X);
00371             }
00372         }
00373     }
00374     mode = MOUSE_NONE;
00375 }
00376 
00377 
00378 void
00379 MFXAddEditTypedTable::setItemFromControl_NoRelease(FXint r,FXint c,FXWindow* control) {
00380     register FXTableItem* item=cells[r*ncols+c];
00381     if (item==NULL) {
00382         return;
00383     }
00384     switch (getCellType(c)) {
00385     case CT_UNDEFINED:
00386     case CT_STRING:
00387         item->setFromControl(control);
00388         break;
00389     case CT_REAL:
00390         item->setText(toString(static_cast<FXRealSpinDial*>(control)->getValue()).c_str());
00391         break;
00392     case CT_INT:
00393         item->setText(toString((int) static_cast<FXRealSpinDial*>(control)->getValue()).c_str());
00394         break;
00395     case CT_BOOL:
00396 //        return myBoolEditor;
00397     case CT_ENUM:
00398 //        return myEnumEditor;
00399     default:
00400         throw 1;
00401     }
00402     EditedTableItem edited;
00403     edited.item = item;
00404     edited.row = r;
00405     edited.col = c;
00406     edited.updateOnly = true;
00407     bool accepted = true;
00408     if (target) {
00409         if (!target->handle(this,FXSEL(SEL_CHANGED, ID_TEXT_CHANGED), (void*) &edited)) {
00410             accepted = false;
00411             // !!! item->setText(myPreviousText);
00412         }
00413     }
00414 }
00415 
00416 
00417 // Released button
00418 long MFXAddEditTypedTable::onLeftBtnRelease(FXObject*,FXSelector,void* ptr) {
00419     FXEvent* event=(FXEvent*)ptr;
00420     if (isEnabled()) {
00421         ungrab();
00422         flags&=~FLAG_PRESSED;
00423         flags|=FLAG_UPDATE;
00424         mode=MOUSE_NONE;
00425         stopAutoScroll();
00426         setDragCursor(getApp()->getDefaultCursor(DEF_ARROW_CURSOR));
00427         if (target && target->tryHandle(this,FXSEL(SEL_LEFTBUTTONRELEASE,message),ptr)) {
00428             return 1;
00429         }
00430 
00431         // Scroll to make item visibke
00432         makePositionVisible(current.row,current.col);
00433 
00434         // Update anchor
00435         //setAnchorItem(current.row,current.col); // FIXME look into the selection stuff
00436 
00437         // Generate clicked callbacks
00438         if (event->click_count==1) {
00439             handle(this,FXSEL(SEL_CLICKED,0),(void*)&current);
00440         } else if (event->click_count==2) {
00441             handle(this,FXSEL(SEL_DOUBLECLICKED,0),(void*)&current);
00442         } else if (event->click_count==3) {
00443             handle(this,FXSEL(SEL_TRIPLECLICKED,0),(void*)&current);
00444         }
00445 
00446         // Command callback only when clicked on item
00447         if (0<=current.row && 0<=current.col && isItemEnabled(current.row,current.col)) {
00448             handle(this,FXSEL(SEL_COMMAND,0),(void*)&current);
00449         }
00450         return 1;
00451     }
00452     return 0;
00453 }
00454 
00455 
00456 // Pressed button
00457 long
00458 MFXAddEditTypedTable::onLeftBtnPress(FXObject*,FXSelector,void* ptr) {
00459     FXEvent* event=(FXEvent*)ptr;
00460     FXTablePos tablepos;
00461     flags&=~FLAG_TIP;
00462     handle(this,FXSEL(SEL_FOCUS_SELF,0),ptr);
00463     if (isEnabled()) {
00464         grab();
00465         if (target && target->tryHandle(this,FXSEL(SEL_LEFTBUTTONPRESS,message),ptr)) {
00466             return 1;
00467         }
00468 
00469         // Cell being clicked on
00470         tablepos.row=rowAtY(event->win_y);
00471         tablepos.col=colAtX(event->win_x);
00472 
00473         // Outside table
00474         if (tablepos.row<0 || tablepos.row>=nrows || tablepos.col<0 || tablepos.col>=ncols) {
00475             setCurrentItem(-1, -1,TRUE);
00476             return 0;
00477         }
00478 
00479         // Change current item
00480         bool wasEdited = editor!=0;
00481         setCurrentItem(tablepos.row,tablepos.col,TRUE);
00482         if (!wasEdited) {
00483 
00484             // Select or deselect
00485             if (event->state&SHIFTMASK) {
00486                 if (0<=anchor.row && 0<=anchor.col) {
00487                     if (isItemEnabled(anchor.row,anchor.col)) {
00488                         extendSelection(current.row,current.col,TRUE);
00489                     }
00490                 } else {
00491                     setAnchorItem(current.row,current.col);
00492                     if (isItemEnabled(current.row,current.col)) {
00493                         extendSelection(current.row,current.col,TRUE);
00494                     }
00495                 }
00496                 mode=MOUSE_SELECT;
00497             } else {
00498                 if (isItemEnabled(current.row,current.col)) {
00499                     killSelection(TRUE);
00500                     setAnchorItem(current.row,current.col);
00501                     extendSelection(current.row,current.col,TRUE);
00502                 } else {
00503                     setAnchorItem(current.row,current.col);
00504                 }
00505                 mode=MOUSE_SELECT;
00506             }
00507         }
00508         flags&=~FLAG_UPDATE;
00509         flags|=FLAG_PRESSED;
00510         return 1;
00511     }
00512     return 0;
00513 }
00514 
00515 
00516 
00517 // Clicked in list
00518 long
00519 MFXAddEditTypedTable::onClicked(FXObject*,FXSelector ,void* ptr) {
00520     if (editor) {
00521         delete editor;
00522         input.fm.row=-1;
00523         input.to.row=-1;
00524         input.fm.col=-1;
00525         input.to.col=-1;
00526         editor=NULL;
00527         current.row=-1;
00528         current.col=-1;
00529     }
00530     if (target && target->tryHandle(this,FXSEL(SEL_CLICKED,message),ptr)) {
00531         return 1;
00532     }
00533     handle(this,FXSEL(SEL_COMMAND,ID_START_INPUT),NULL);
00534     return 1;
00535 }
00536 
00537 
00538 // Double clicked in list; ptr may or may not point to an item
00539 long MFXAddEditTypedTable::onDoubleClicked(FXObject*,FXSelector,void* ptr) {
00540     if (editor) {
00541         delete editor;
00542         input.fm.row=-1;
00543         input.to.row=-1;
00544         input.fm.col=-1;
00545         input.to.col=-1;
00546         editor=NULL;
00547     } else {
00548         if (target && target->tryHandle(this,FXSEL(SEL_CLICKED,message),ptr)) {
00549             return 1;
00550         }
00551         handle(this,FXSEL(SEL_COMMAND,ID_START_INPUT),NULL);
00552     }
00553     return 1;
00554 }
00555 
00556 
00557 CellType
00558 MFXAddEditTypedTable::getCellType(size_t pos) const {
00559     if (myCellTypes.size()<=pos) {
00560         return CT_UNDEFINED;
00561     }
00562     return myCellTypes[pos];
00563 }
00564 
00565 
00566 void
00567 MFXAddEditTypedTable::setCellType(size_t pos, CellType t) {
00568     while (myCellTypes.size()<pos+1) {
00569         myCellTypes.push_back(CT_UNDEFINED);
00570     }
00571     myCellTypes[pos] = t;
00572 }
00573 
00574 void
00575 MFXAddEditTypedTable::setNumberCellParams(size_t pos, double min, double max,
00576         double steps1,
00577         double steps2,
00578         double steps3,
00579         const std::string& format) {
00580     while (myNumberCellParams.size()<=pos) {
00581         NumberCellParams np;
00582         np.format = "undefined";
00583         myNumberCellParams.push_back(np);
00584     }
00585     NumberCellParams np;
00586     np.pos = (int)(pos);
00587     np.min = min;
00588     np.max = max;
00589     np.steps1 = steps1;
00590     np.steps2 = steps2;
00591     np.steps3 = steps3;
00592     np.format = format;
00593     myNumberCellParams[pos] = np;
00594 }
00595 
00596 
00597 MFXAddEditTypedTable::NumberCellParams
00598 MFXAddEditTypedTable::getNumberCellParams(size_t pos) const {
00599     if (myNumberCellParams.size()<=pos) {
00600         NumberCellParams np;
00601         np.format = "undefined";
00602         return np;
00603     }
00604     return myNumberCellParams[pos];
00605 }
00606 
00607 
00608 
00609 void
00610 MFXAddEditTypedTable::setEnums(size_t pos,
00611                                const std::vector<std::string> &params) {
00612     while (myEnums.size()<=pos) {
00613         myEnums.push_back(std::vector<std::string>());
00614     }
00615     myEnums[pos] = params;
00616 }
00617 
00618 
00619 void
00620 MFXAddEditTypedTable::addEnum(size_t pos,
00621                               const std::string& e) {
00622     while (myEnums.size()<=pos) {
00623         myEnums.push_back(std::vector<std::string>());
00624     }
00625     myEnums[pos].push_back(e);
00626 }
00627 
00628 
00629 const std::vector<std::string> &
00630 MFXAddEditTypedTable::getEnums(size_t pos) const {
00631     return myEnums[pos];
00632 }
00633 
00634 
00635 
00636 /****************************************************************************/
00637 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Defines