|
SUMO - Simulation of Urban MObility
|
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*)¤t); 00440 } else if (event->click_count==2) { 00441 handle(this,FXSEL(SEL_DOUBLECLICKED,0),(void*)¤t); 00442 } else if (event->click_count==3) { 00443 handle(this,FXSEL(SEL_TRIPLECLICKED,0),(void*)¤t); 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*)¤t); 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> ¶ms) { 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