00001
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
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
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
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
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
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
00217
00218
00219
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
00233 case CT_INT: {
00234 register FXRealSpinDial *field;
00235
00236 field=new FXRealSpinDial(this,1,NULL,0,TEXTFIELD_ENTER_ONLY,0,0,0,0,getMarginLeft(),getMarginRight(),getMarginTop(),getMarginBottom());
00237
00238
00239
00240
00241 field->create();
00242
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
00268 case CT_ENUM:
00269
00270 default:
00271 throw 1;
00272 }
00273 }
00274
00275
00276
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
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
00341 case CT_ENUM:
00342
00343 default:
00344 throw 1;
00345 }
00346
00347
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
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
00393 case CT_ENUM:
00394
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
00408 }
00409 }
00410 }
00411
00412
00413
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
00426 makePositionVisible(current.row,current.col);
00427
00428
00429
00430
00431
00432 if (event->click_count==1) {
00433 handle(this,FXSEL(SEL_CLICKED,0),(void*)¤t);
00434 } else if (event->click_count==2) {
00435 handle(this,FXSEL(SEL_DOUBLECLICKED,0),(void*)¤t);
00436 } else if (event->click_count==3) {
00437 handle(this,FXSEL(SEL_TRIPLECLICKED,0),(void*)¤t);
00438 }
00439
00440
00441 if (0<=current.row && 0<=current.col && isItemEnabled(current.row,current.col)) {
00442 handle(this,FXSEL(SEL_COMMAND,0),(void*)¤t);
00443 }
00444 return 1;
00445 }
00446 return 0;
00447 }
00448
00449
00450
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
00462 tablepos.row=rowAtY(event->win_y);
00463 tablepos.col=colAtX(event->win_x);
00464
00465
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
00472 bool wasEdited = editor!=0;
00473 setCurrentItem(tablepos.row,tablepos.col,TRUE);
00474 if (!wasEdited) {
00475
00476
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
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
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> ¶ms) {
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