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 2001-2010 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)) item->setSelected(FALSE);
00207     }
00208     delete editor;
00209     editor=NULL;
00210     switch (getCellType(c)) {
00211     case CT_UNDEFINED:
00212     case CT_STRING: {
00213         register FXTextField *field;
00214         register FXuint justify=0;
00215         field=new FXTextField(this,1,NULL,0,TEXTFIELD_ENTER_ONLY,0,0,0,0,getMarginLeft(),getMarginRight(),getMarginTop(),getMarginBottom());
00216         // !!! if(state&LEFT) justify|=JUSTIFY_LEFT;
00217         // !!! if(state&RIGHT) justify|=JUSTIFY_RIGHT;
00218         // !!! if(state&TOP) justify|=JUSTIFY_TOP;
00219         // !!! if(state&BOTTOM) justify|=JUSTIFY_BOTTOM;
00220         field->create();
00221         field->setJustify(justify);
00222         field->setFont(getFont());
00223         field->setBackColor(getBackColor());
00224         field->setTextColor(getTextColor());
00225         field->setSelBackColor(getSelBackColor());
00226         field->setSelTextColor(getSelTextColor());
00227         field->setText(item->getText());
00228         field->selectAll();
00229         return field;
00230     }
00231     case CT_REAL:
00232 //        return myNumberEditor;
00233     case CT_INT: {
00234         register FXRealSpinDial *field;
00235         //register FXuint justify=0;
00236         field=new FXRealSpinDial(this,1,NULL,0,TEXTFIELD_ENTER_ONLY,0,0,0,0,getMarginLeft(),getMarginRight(),getMarginTop(),getMarginBottom());
00237         // !!! if(state&LEFT) justify|=JUSTIFY_LEFT;
00238         // !!! if(state&RIGHT) justify|=JUSTIFY_RIGHT;
00239         // !!! if(state&TOP) justify|=JUSTIFY_TOP;
00240         // !!! if(state&BOTTOM) justify|=JUSTIFY_BOTTOM;
00241         field->create();
00242 //            field->setJustify(justify);
00243         field->setFont(getFont());
00244         field->setBackColor(getBackColor());
00245         field->setTextColor(getTextColor());
00246         field->setSelBackColor(getSelBackColor());
00247         field->setSelTextColor(getSelTextColor());
00248         NumberCellParams p = getNumberCellParams(c);
00249         if (p.format!="undefined") {
00250             field->setFormatString((char*) p.format.c_str());
00251             field->setIncrements(p.steps1, p.steps2, p.steps3);
00252             field->setRange(p.min, p.max);
00253         }
00254         try {
00255             if (getCellType(c)==CT_REAL) {
00256                 field->setValue(TplConvert<char>::_2SUMOReal(item->getText().text()));
00257             } else {
00258                 field->setValue(TplConvert<char>::_2int(item->getText().text()));
00259             }
00260         } catch (NumberFormatException &) {
00261             field->setValue(0);
00262         }
00263         field->selectAll();
00264         return field;
00265     }
00266     case CT_BOOL:
00267 //        return myBoolEditor;
00268     case CT_ENUM:
00269 //        return myEnumEditor;
00270     default:
00271         throw 1;
00272     }
00273 }
00274 
00275 
00276 // Cancel editing cell
00277 void
00278 MFXAddEditTypedTable::cancelInput() {
00279     if (editor) {
00280         delete editor;
00281         input.fm.row=-1;
00282         input.to.row=-1;
00283         input.fm.col=-1;
00284         input.to.col=-1;
00285         editor=NULL;
00286     }
00287 }
00288 
00289 // Done with editing cell
00290 void
00291 MFXAddEditTypedTable::acceptInput(FXbool notify) {
00292     bool set = false;
00293     FXTableRange tablerange=input;
00294     if (editor) {
00295         //
00296         //
00297         FXRealSpinDial *dial = dynamic_cast<FXRealSpinDial*>(editor);
00298         if (dial!=0) {
00299             if (!dial->getDial().grabbed()) {
00300                 set = true;
00301             } else {
00302                 setItemFromControl_NoRelease(input.fm.row,input.fm.col,editor);
00303             }
00304         }
00305         if (dynamic_cast<FXTextField*>(editor)!=0) {
00306             set = true;
00307         }
00308     }
00309     if (set) {
00310         setItemFromControl(input.fm.row,input.fm.col,editor);
00311         cancelInput();
00312         if (notify && target) {
00313             target->tryHandle(this,FXSEL(SEL_REPLACED,message),(void*)&tablerange);
00314         }
00315     }
00316 }
00317 
00318 
00319 
00320 
00321 void
00322 MFXAddEditTypedTable::setItemFromControl(FXint r,FXint c,FXWindow *control) {
00323     register FXTableItem* item=cells[r*ncols+c];
00324     if (item==NULL) {
00325         cells[r*ncols+c]=item=createItem("",NULL,NULL);
00326         if (isItemSelected(r,c)) item->setSelected(FALSE);
00327     }
00328     switch (getCellType(c)) {
00329     case CT_UNDEFINED:
00330     case CT_STRING:
00331         item->setFromControl(control);
00332         break;
00333     case CT_REAL:
00334         item->setText(toString(static_cast<FXRealSpinDial*>(control)->getValue()).c_str());
00335         break;
00336     case CT_INT:
00337         item->setText(toString((int) static_cast<FXRealSpinDial*>(control)->getValue()).c_str());
00338         break;
00339     case CT_BOOL:
00340 //        return myBoolEditor;
00341     case CT_ENUM:
00342 //        return myEnumEditor;
00343     default:
00344         throw 1;
00345     }
00346 //    current.row = -1;
00347 //    current.col = -1;
00348     EditedTableItem edited;
00349     edited.item = item;
00350     edited.row = r;
00351     edited.col = c;
00352     edited.updateOnly = false;
00353     killSelection(true);
00354     bool accepted = true;
00355     if (target) {
00356         if (!target->handle(this,FXSEL(SEL_CHANGED, ID_TEXT_CHANGED), (void*) &edited)) {
00357             accepted = false;
00358             // !!! item->setText(myPreviousText);
00359         }
00360     }
00361     if (accepted) {
00362         if (edited.row==getNumRows()-1) {
00363             insertRows(getNumRows(), 1, true);
00364             for (int i=0; i<getNumColumns(); i++) {
00365                 setItemText(getNumRows()-1, i, "");
00366                 setItemJustify(getNumRows()-1, i, JUSTIFY_CENTER_X);
00367             }
00368         }
00369     }
00370     mode = MOUSE_NONE;
00371 }
00372 
00373 
00374 void
00375 MFXAddEditTypedTable::setItemFromControl_NoRelease(FXint r,FXint c,FXWindow *control) {
00376     register FXTableItem* item=cells[r*ncols+c];
00377     if (item==NULL) {
00378         return;
00379     }
00380     switch (getCellType(c)) {
00381     case CT_UNDEFINED:
00382     case CT_STRING:
00383         item->setFromControl(control);
00384         break;
00385     case CT_REAL:
00386         item->setText(toString(static_cast<FXRealSpinDial*>(control)->getValue()).c_str());
00387         break;
00388     case CT_INT:
00389         item->setText(toString((int) static_cast<FXRealSpinDial*>(control)->getValue()).c_str());
00390         break;
00391     case CT_BOOL:
00392 //        return myBoolEditor;
00393     case CT_ENUM:
00394 //        return myEnumEditor;
00395     default:
00396         throw 1;
00397     }
00398     EditedTableItem edited;
00399     edited.item = item;
00400     edited.row = r;
00401     edited.col = c;
00402     edited.updateOnly = true;
00403     bool accepted = true;
00404     if (target) {
00405         if (!target->handle(this,FXSEL(SEL_CHANGED, ID_TEXT_CHANGED), (void*) &edited)) {
00406             accepted = false;
00407             // !!! item->setText(myPreviousText);
00408         }
00409     }
00410 }
00411 
00412 
00413 // Released button
00414 long MFXAddEditTypedTable::onLeftBtnRelease(FXObject*,FXSelector,void* ptr) {
00415     FXEvent* event=(FXEvent*)ptr;
00416     if (isEnabled()) {
00417         ungrab();
00418         flags&=~FLAG_PRESSED;
00419         flags|=FLAG_UPDATE;
00420         mode=MOUSE_NONE;
00421         stopAutoScroll();
00422         setDragCursor(getApp()->getDefaultCursor(DEF_ARROW_CURSOR));
00423         if (target && target->tryHandle(this,FXSEL(SEL_LEFTBUTTONRELEASE,message),ptr)) return 1;
00424 
00425         // Scroll to make item visibke
00426         makePositionVisible(current.row,current.col);
00427 
00428         // Update anchor
00429         //setAnchorItem(current.row,current.col); // FIXME look into the selection stuff
00430 
00431         // Generate clicked callbacks
00432         if (event->click_count==1) {
00433             handle(this,FXSEL(SEL_CLICKED,0),(void*)&current);
00434         } else if (event->click_count==2) {
00435             handle(this,FXSEL(SEL_DOUBLECLICKED,0),(void*)&current);
00436         } else if (event->click_count==3) {
00437             handle(this,FXSEL(SEL_TRIPLECLICKED,0),(void*)&current);
00438         }
00439 
00440         // Command callback only when clicked on item
00441         if (0<=current.row && 0<=current.col && isItemEnabled(current.row,current.col)) {
00442             handle(this,FXSEL(SEL_COMMAND,0),(void*)&current);
00443         }
00444         return 1;
00445     }
00446     return 0;
00447 }
00448 
00449 
00450 // Pressed button
00451 long
00452 MFXAddEditTypedTable::onLeftBtnPress(FXObject*,FXSelector,void* ptr) {
00453     FXEvent* event=(FXEvent*)ptr;
00454     FXTablePos tablepos;
00455     flags&=~FLAG_TIP;
00456     handle(this,FXSEL(SEL_FOCUS_SELF,0),ptr);
00457     if (isEnabled()) {
00458         grab();
00459         if (target && target->tryHandle(this,FXSEL(SEL_LEFTBUTTONPRESS,message),ptr)) return 1;
00460 
00461         // Cell being clicked on
00462         tablepos.row=rowAtY(event->win_y);
00463         tablepos.col=colAtX(event->win_x);
00464 
00465         // Outside table
00466         if (tablepos.row<0 || tablepos.row>=nrows || tablepos.col<0 || tablepos.col>=ncols) {
00467             setCurrentItem(-1, -1,TRUE);
00468             return 0;
00469         }
00470 
00471         // Change current item
00472         bool wasEdited = editor!=0;
00473         setCurrentItem(tablepos.row,tablepos.col,TRUE);
00474         if (!wasEdited) {
00475 
00476             // Select or deselect
00477             if (event->state&SHIFTMASK) {
00478                 if (0<=anchor.row && 0<=anchor.col) {
00479                     if (isItemEnabled(anchor.row,anchor.col)) {
00480                         extendSelection(current.row,current.col,TRUE);
00481                     }
00482                 } else {
00483                     setAnchorItem(current.row,current.col);
00484                     if (isItemEnabled(current.row,current.col)) {
00485                         extendSelection(current.row,current.col,TRUE);
00486                     }
00487                 }
00488                 mode=MOUSE_SELECT;
00489             } else {
00490                 if (isItemEnabled(current.row,current.col)) {
00491                     killSelection(TRUE);
00492                     setAnchorItem(current.row,current.col);
00493                     extendSelection(current.row,current.col,TRUE);
00494                 } else {
00495                     setAnchorItem(current.row,current.col);
00496                 }
00497                 mode=MOUSE_SELECT;
00498             }
00499         }
00500         flags&=~FLAG_UPDATE;
00501         flags|=FLAG_PRESSED;
00502         return 1;
00503     }
00504     return 0;
00505 }
00506 
00507 
00508 
00509 // Clicked in list
00510 long
00511 MFXAddEditTypedTable::onClicked(FXObject*,FXSelector ,void* ptr) {
00512     if (editor) {
00513         delete editor;
00514         input.fm.row=-1;
00515         input.to.row=-1;
00516         input.fm.col=-1;
00517         input.to.col=-1;
00518         editor=NULL;
00519         current.row=-1;
00520         current.col=-1;
00521     }
00522     if (target && target->tryHandle(this,FXSEL(SEL_CLICKED,message),ptr)) return 1;
00523     handle(this,FXSEL(SEL_COMMAND,ID_START_INPUT),NULL);
00524     return 1;
00525 }
00526 
00527 
00528 // Double clicked in list; ptr may or may not point to an item
00529 long MFXAddEditTypedTable::onDoubleClicked(FXObject*,FXSelector,void* ptr) {
00530     if (editor) {
00531         delete editor;
00532         input.fm.row=-1;
00533         input.to.row=-1;
00534         input.fm.col=-1;
00535         input.to.col=-1;
00536         editor=NULL;
00537     } else {
00538         if (target && target->tryHandle(this,FXSEL(SEL_CLICKED,message),ptr)) return 1;
00539         handle(this,FXSEL(SEL_COMMAND,ID_START_INPUT),NULL);
00540     }
00541     return 1;
00542 }
00543 
00544 
00545 CellType
00546 MFXAddEditTypedTable::getCellType(size_t pos) const {
00547     if (myCellTypes.size()<=pos) {
00548         return CT_UNDEFINED;
00549     }
00550     return myCellTypes[pos];
00551 }
00552 
00553 
00554 void
00555 MFXAddEditTypedTable::setCellType(size_t pos, CellType t) {
00556     while (myCellTypes.size()<pos+1) {
00557         myCellTypes.push_back(CT_UNDEFINED);
00558     }
00559     myCellTypes[pos] = t;
00560 }
00561 
00562 void
00563 MFXAddEditTypedTable::setNumberCellParams(size_t pos, double min, double max,
00564         double steps1,
00565         double steps2,
00566         double steps3,
00567         const std::string &format) {
00568     while (myNumberCellParams.size()<=pos) {
00569         NumberCellParams np;
00570         np.format = "undefined";
00571         myNumberCellParams.push_back(np);
00572     }
00573     NumberCellParams np;
00574     np.pos = pos;
00575     np.min = min;
00576     np.max = max;
00577     np.steps1 = steps1;
00578     np.steps2 = steps2;
00579     np.steps3 = steps3;
00580     np.format = format;
00581     myNumberCellParams[pos] = np;
00582 }
00583 
00584 
00585 MFXAddEditTypedTable::NumberCellParams
00586 MFXAddEditTypedTable::getNumberCellParams(size_t pos) const {
00587     if (myNumberCellParams.size()<=pos) {
00588         NumberCellParams np;
00589         np.format = "undefined";
00590         return np;
00591     }
00592     return myNumberCellParams[pos];
00593 }
00594 
00595 
00596 
00597 void
00598 MFXAddEditTypedTable::setEnums(size_t pos,
00599                                const std::vector<std::string> &params) {
00600     while (myEnums.size()<=pos) {
00601         myEnums.push_back(std::vector<std::string>());
00602     }
00603     myEnums[pos] = params;
00604 }
00605 
00606 
00607 void
00608 MFXAddEditTypedTable::addEnum(size_t pos,
00609                               const std::string &e) {
00610     while (myEnums.size()<=pos) {
00611         myEnums.push_back(std::vector<std::string>());
00612     }
00613     myEnums[pos].push_back(e);
00614 }
00615 
00616 
00617 const std::vector<std::string> &
00618 MFXAddEditTypedTable::getEnums(size_t pos) const {
00619     return myEnums[pos];
00620 }
00621 
00622 
00623 
00624 /****************************************************************************/
00625 

Generated on Wed May 5 00:06:30 2010 for Sumo - Simulation of Urban MObility by  doxygen 1.5.6