00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
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 #include "Varargs.h"
00107 #include "TQCommand.h"
00108 #include "TQConnection.h"
00109 #include "TDataType.h"
00110 #include "stdarg.h"
00111 #include "TROOT.h"
00112
00113 ClassImp(TQCommand)
00114 ClassImp(TQUndoManager)
00115
00116 static TQCommand *gActiveCommand = 0;
00117
00118
00119
00120 static char *ResolveTypes(const char *method)
00121 {
00122
00123
00124
00125
00126 if (!method || !*method) return 0;
00127
00128 char *str = new char[strlen(method)+1];
00129 if (str) strcpy(str, method);
00130
00131 TString res;
00132
00133 char *s = strtok(str, "(");
00134 res = s;
00135 res += "(";
00136
00137 Bool_t first = kTRUE;
00138 while ((s = strtok(0, ",)"))) {
00139 char *s1, s2 = 0;
00140 if ((s1 = strchr(s, '*'))) {
00141 *s1 = 0;
00142 s2 = '*';
00143 }
00144 if (!s1 && (s1 = strchr(s, '&'))) {
00145 *s1 = 0;
00146 s2 = '&';
00147 }
00148 TDataType *dt = gROOT->GetType(s);
00149 if (s1) *s1 = s2;
00150 if (!first) res += ",";
00151 if (dt) {
00152 res += dt->GetFullTypeName();
00153 if (s1) res += s1;
00154 } else
00155 res += s;
00156 first = kFALSE;
00157 }
00158
00159 res += ")";
00160
00161 delete [] str;
00162 str = new char[res.Length()+1];
00163 strcpy(str, res.Data());
00164
00165 return str;
00166 }
00167
00168
00169 static char *CompressName(const char *method_name)
00170 {
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180 if (!method_name || !*method_name) return 0;
00181
00182 char *str = new char[strlen(method_name)+1];
00183 if (str) strcpy(str, method_name);
00184
00185 char *tmp = str;
00186
00187
00188 while ((tmp = strstr(tmp,"const"))) {
00189 for (int i = 0; i < 5; i++) *(tmp+i) = ' ';
00190 }
00191
00192 tmp = str;
00193 char *s;
00194 s = str;
00195
00196 Bool_t quote = kFALSE;
00197 while (*tmp) {
00198 if (*tmp == '\"')
00199 quote = quote ? kFALSE : kTRUE;
00200 if (*tmp != ' ' || quote)
00201 *s++ = *tmp;
00202 tmp++;
00203 }
00204 *s = '\0';
00205
00206 s = ResolveTypes(str);
00207
00208 delete [] str;
00209
00210 return s;
00211 }
00212
00213
00214
00215 void TQCommand::Init(const char *clname, void *obj, const char *redo, const char *undo)
00216 {
00217
00218
00219 char *credo = CompressName(redo);
00220 char *cundo = CompressName(undo);
00221
00222 fNRargs = fNUargs = -1;
00223 fNewDelete = kFALSE;
00224 fObject = obj;
00225
00226 fRedo = redo ? new TQConnection(clname, obj, credo) : 0;
00227 fUndo = undo ? new TQConnection(clname, obj, cundo) : fRedo;
00228
00229 fRedoArgs = 0;
00230 fUndoArgs = 0;
00231 fStatus = 0;
00232 fState = 0;
00233
00234 delete [] credo;
00235 delete [] cundo;
00236
00237 if (!obj && !redo && !undo) {
00238 fName = clname;
00239 }
00240 }
00241
00242
00243 TQCommand::TQCommand(const char *clname, void *obj, const char *redo,
00244 const char *undo) : TList(), TQObject()
00245 {
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268 Init(clname, obj, redo, undo);
00269 }
00270
00271
00272 TQCommand::TQCommand(TObject *obj, const char *redo, const char *undo) :
00273 TList(), TQObject()
00274 {
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295 if (obj) Init(obj->ClassName(), obj, redo, undo);
00296 else Init(0, 0, redo, undo);
00297 }
00298
00299
00300 TQCommand::TQCommand(const TQCommand &com) : TList(), TQObject()
00301 {
00302
00303
00304 fRedo = new TQConnection(*(com.fRedo));
00305 fUndo = new TQConnection(*(com.fUndo));
00306
00307 fRedoArgs = 0;
00308 fUndoArgs = 0;
00309 fNRargs = com.fNRargs;
00310 fNUargs = com.fNUargs;
00311
00312 if (fNRargs > 0) {
00313 fRedoArgs = new Long_t[fNRargs];
00314 for (int i = 0; i< fNRargs; i++) {
00315 fRedoArgs[i] = com.fRedoArgs[i];
00316 }
00317 }
00318 if (fNUargs > 0) {
00319 fUndoArgs = new Long_t[fNUargs];
00320 for (int i = 0; i < fNUargs; i++) {
00321 fUndoArgs[i] = com.fUndoArgs[i];
00322 }
00323 }
00324 fStatus = com.fStatus;
00325 fNewDelete = com.fNewDelete;
00326 fName = com.fName;
00327 fTitle = com.fTitle;
00328 fObject = com.fObject;
00329 fState = com.fState;
00330
00331
00332 TIter next(&com);
00333 TQCommand *obj;
00334 while ((obj = (TQCommand*)next())) {
00335 TList::Add(new TQCommand(*obj));
00336 }
00337 }
00338
00339
00340 TQCommand::~TQCommand()
00341 {
00342
00343
00344 if (fRedo != fUndo) delete fUndo;
00345
00346 delete fRedo;
00347 delete fRedoArgs;
00348 delete fUndoArgs;
00349
00350 Delete();
00351 }
00352
00353
00354 TQCommand *TQCommand::GetCommand()
00355 {
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370 return gActiveCommand;
00371 }
00372
00373
00374 void TQCommand::Delete(Option_t *opt)
00375 {
00376
00377
00378
00379 if (!opt) {
00380 TList::Delete();
00381 return;
00382 }
00383
00384 TObjLink *lnk = fFirst;
00385 TObjLink *sav;
00386
00387 while (lnk) {
00388 sav = lnk->Next();
00389 TString ostr = lnk->GetOption();
00390 if (ostr.Contains(opt)) {
00391 delete lnk->GetObject();
00392 Remove(lnk);
00393 }
00394 lnk = sav;
00395 }
00396 }
00397
00398
00399 Bool_t TQCommand::CanMerge(TQCommand *) const
00400 {
00401
00402
00403
00404
00405
00406 return (!fRedo && !fUndo);
00407 }
00408
00409
00410 void TQCommand::Merge(TQCommand *c)
00411 {
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421 Add(c, "merge");
00422 }
00423
00424
00425 void TQCommand::Add(TObject *obj, Option_t *opt)
00426 {
00427
00428
00429
00430
00431
00432
00433
00434 if (!obj->InheritsFrom(TQCommand::Class())) return;
00435
00436 TQCommand *o = (TQCommand *)obj;
00437 TQCommand *c = (TQCommand *)Last();
00438 TString ostr = opt;
00439
00440 if (c) {
00441 if (c->CanCompress(o) || (c->IsEqual(o) && ostr.Contains("compress"))) {
00442 c->Compress(o);
00443 return;
00444 }
00445 }
00446 TList::AddLast(o, opt);
00447 if (o->CanRedo() && ostr.Contains("radd")) o->Redo();
00448 if (o->CanUndo() && ostr.Contains("uadd")) o->Undo();
00449 }
00450
00451
00452 Bool_t TQCommand::CanCompress(TQCommand *c) const
00453 {
00454
00455
00456
00457
00458
00459
00460
00461 return (IsEqual(c) && IsSetter());
00462 }
00463
00464
00465 void TQCommand::Compress(TQCommand *c)
00466 {
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476 for (int i = 0; i < fNRargs; i++) {
00477 fRedoArgs[i] = c->fRedoArgs[i];
00478 }
00479 Redo();
00480 fStatus--;
00481 delete c;
00482 }
00483
00484
00485 Bool_t TQCommand::IsEqual(const TObject* obj) const
00486 {
00487
00488
00489
00490
00491
00492 if (!obj->InheritsFrom(TQCommand::Class())) return kFALSE;
00493 TQCommand *c = (TQCommand *)obj;
00494 if (!fRedo || !fUndo || (c->GetObject() != fObject)) return kFALSE;
00495
00496 TString cname = fRedo->GetClassName();
00497 TString rname = fRedo->GetName();
00498
00499 return ((cname == c->GetRedo()->GetClassName()) &&
00500 (rname == c->GetRedo()->GetName()));
00501 }
00502
00503
00504 Bool_t TQCommand::IsSetter() const
00505 {
00506
00507
00508
00509
00510
00511
00512
00513
00514 TString redo = GetRedoName();
00515 TString undo = GetUndoName();
00516
00517 if (!redo || !undo || (redo != undo)) return kFALSE;
00518
00519 return (redo.BeginsWith("Set") ||
00520 redo.BeginsWith("set") ||
00521 redo.BeginsWith("Move") ||
00522 redo.BeginsWith("move") ||
00523 redo.BeginsWith("Resize") ||
00524 redo.BeginsWith("resize"));
00525 }
00526
00527
00528 void TQCommand::SetArgs(Int_t narg, ...)
00529 {
00530
00531
00532
00533
00534
00535
00536
00537 if (narg < 0) {
00538 return;
00539 } else if (!narg) {
00540 fNRargs = fNUargs = narg;
00541 return;
00542 }
00543
00544 va_list ap;
00545 va_start(ap, narg);
00546
00547 if (fNRargs != narg ) {
00548 delete fRedoArgs;
00549 }
00550 fRedoArgs = new Long_t[narg];
00551
00552 if (fNUargs != narg ) {
00553 delete fUndoArgs;
00554 }
00555 fUndoArgs = new Long_t[narg];
00556
00557 fNRargs = fNUargs = narg;
00558
00559 Int_t i;
00560 for (i = 0; i < fNRargs; i++) {
00561 fRedoArgs[i] = va_arg(ap, Long_t);
00562 }
00563 for (i = 0; i < fNUargs; i++) {
00564 fUndoArgs[i] = va_arg(ap, Long_t);
00565 }
00566 va_end(ap);
00567 }
00568
00569
00570 void TQCommand::SetRedoArgs(Int_t narg, ...)
00571 {
00572
00573
00574
00575
00576
00577
00578 if (narg < 0) {
00579 return;
00580 } else if (!narg) {
00581 fNRargs = 0;
00582 return;
00583 }
00584
00585 va_list ap;
00586 va_start(ap, narg);
00587
00588 if (fNRargs != narg ) {
00589 delete fRedoArgs;
00590 }
00591 fRedoArgs = new Long_t[narg];
00592
00593 fNRargs = narg;
00594
00595 for (int i = 0; i < fNRargs; i++) {
00596 fRedoArgs[i] = va_arg(ap, Long_t);
00597 }
00598 va_end(ap);
00599 }
00600
00601
00602 void TQCommand::SetUndoArgs(Int_t narg, ...)
00603 {
00604
00605
00606
00607
00608
00609
00610 if (narg < 0) {
00611 return;
00612 } else if (!narg) {
00613 fNUargs = narg;
00614 return;
00615 }
00616
00617 va_list ap;
00618 va_start(ap, narg);
00619
00620 if (fNUargs != narg ) {
00621 delete fUndoArgs;
00622 }
00623 fUndoArgs = new Long_t[narg];
00624
00625 fNUargs = narg;
00626
00627 for (int i = 0; i < fNUargs; i++) {
00628 fUndoArgs[i] = va_arg(ap, Long_t);
00629 }
00630 va_end(ap);
00631 }
00632
00633
00634 Bool_t TQCommand::CanRedo() const
00635 {
00636
00637
00638
00639 return (fStatus <= 0);
00640 }
00641
00642
00643 Bool_t TQCommand::CanUndo() const
00644 {
00645
00646
00647
00648 return (fStatus > 0);
00649 }
00650
00651
00652 void TQCommand::Redo(Option_t *)
00653 {
00654
00655
00656 Bool_t done = kFALSE;
00657 fState = 1;
00658
00659 gActiveCommand = this;
00660
00661 if (fNRargs > 0) {
00662 if (fRedo) {
00663 fRedo->ExecuteMethod(fRedoArgs, fNRargs);
00664 done = kTRUE;
00665 }
00666 } else if (!fNRargs) {
00667 if (fRedo) {
00668 fRedo->ExecuteMethod();
00669 done = kTRUE;
00670 }
00671 }
00672
00673
00674 TObjLink *lnk = fFirst;
00675 while (lnk) {
00676 TQCommand *c = (TQCommand *)lnk->GetObject();
00677 c->Redo();
00678 done = kTRUE;
00679 lnk = lnk->Next();
00680 }
00681
00682 if (done) Emit("Redo()");
00683 fStatus++;
00684 fState = 0;
00685 gActiveCommand = 0;
00686 }
00687
00688
00689 void TQCommand::Undo(Option_t *)
00690 {
00691
00692
00693
00694 Bool_t done = kFALSE;
00695 fState = -1;
00696
00697 gActiveCommand = this;
00698
00699
00700 TObjLink *lnk = fLast;
00701 while (lnk) {
00702 TQCommand *c = (TQCommand *)lnk->GetObject();
00703 TString opt = lnk->GetOption();
00704 TObjLink *sav = lnk->Prev();
00705 c->Undo();
00706 done = kTRUE;
00707 if (opt.Contains("remove")) {
00708 delete lnk->GetObject();
00709 Remove(lnk);
00710 }
00711 lnk = sav;
00712 }
00713 if (fNUargs > 0) {
00714 if (fUndo) {
00715 fUndo->ExecuteMethod(fUndoArgs, fNUargs);
00716 done = kTRUE;
00717 }
00718 } else if (!fNUargs) {
00719 if (fUndo) {
00720 fUndo->ExecuteMethod();
00721 done = kTRUE;
00722 }
00723 }
00724
00725 if (done) Emit("Undo()");
00726 fStatus--;
00727 fState = 0;
00728 gActiveCommand = 0;
00729 }
00730
00731
00732 const char *TQCommand::GetName() const
00733 {
00734
00735
00736
00737
00738 const Int_t maxname = 100;
00739
00740 if (!fName.IsNull()) return fName.Data();
00741
00742 TString name;
00743
00744 if (fRedo) {
00745 if (fRedo->GetClassName()) {
00746 name = fRedo->GetClassName();
00747 }
00748 name += "::";
00749 name += fRedo->GetName();
00750 }
00751 TQCommand *c;
00752 TObjLink *lnk = fFirst;
00753
00754 while (lnk && (fName.Length() < maxname)) {
00755 c = (TQCommand *)lnk->GetObject();
00756 name += ":";
00757 name += c->GetName();
00758 lnk = lnk->Next();
00759 }
00760
00761
00762 TQCommand *m = (TQCommand *)this;
00763 m->fName = name;
00764
00765 return name.Data();
00766 }
00767
00768
00769 const char *TQCommand::GetTitle() const
00770 {
00771
00772
00773
00774 if (!fTitle.IsNull()) return fTitle.Data();
00775
00776 TString title = GetName();
00777
00778 if (fUndo) {
00779 title += "_";
00780 title += fUndo->GetClassName();
00781 title += "::";
00782 if (fUndo->GetName()) title += fUndo->GetName();
00783 }
00784 return title.Data();
00785 }
00786
00787
00788 const char *TQCommand::GetRedoName() const
00789 {
00790
00791
00792 return (fRedo ? fRedo->GetName() : 0);
00793 }
00794
00795
00796 const char *TQCommand::GetUndoName() const
00797 {
00798
00799
00800 return (fUndo ? fUndo->GetName() : 0);
00801 }
00802
00803
00804 Long_t *TQCommand::GetRedoArgs() const
00805 {
00806
00807
00808 return fRedoArgs;
00809 }
00810
00811
00812 Long_t *TQCommand::GetUndoArgs() const
00813 {
00814
00815
00816 return fUndoArgs;
00817 }
00818
00819
00820 Int_t TQCommand::GetNRargs() const
00821 {
00822
00823
00824 return fNRargs;
00825 }
00826
00827
00828 Int_t TQCommand::GetNUargs() const
00829 {
00830
00831
00832 return fNUargs;
00833 }
00834
00835
00836 void *TQCommand::GetObject() const
00837 {
00838
00839
00840 return fObject;
00841 }
00842
00843
00844 Int_t TQCommand::GetStatus() const
00845 {
00846
00847
00848 return fStatus;
00849 }
00850
00851
00852 Bool_t TQCommand::IsMacro() const
00853 {
00854
00855
00856 return (!fRedo && !fUndo);
00857 }
00858
00859
00860 Bool_t TQCommand::IsUndoing() const
00861 {
00862
00863
00864 return (fState < 0);
00865 }
00866
00867
00868 Bool_t TQCommand::IsRedoing() const
00869 {
00870
00871
00872 return (fState > 0);
00873 }
00874
00875
00876 Bool_t TQCommand::IsExecuting() const
00877 {
00878
00879
00880 return fState;
00881 }
00882
00883
00884 void TQCommand::SetName(const char *name)
00885 {
00886
00887
00888 fName = name;
00889 }
00890
00891
00892 void TQCommand::SetTitle(const char *title)
00893 {
00894
00895
00896 fTitle = title;
00897 }
00898
00899
00900 void TQCommand::ls(Option_t *) const
00901 {
00902
00903
00904 TString name = GetName();
00905 printf("%d %s\n", fStatus, name.Data());
00906
00907 TObjLink *lnk = fFirst;
00908 while (lnk) {
00909 printf("\t");
00910 lnk->GetObject()->ls();
00911 lnk = lnk->Next();
00912 }
00913 }
00914
00915
00916 void TQCommand::PrintCollectionHeader(Option_t* ) const
00917 {
00918
00919
00920 TROOT::IndentLevel();
00921 printf("%d %s\n", fStatus, GetName());
00922 }
00923
00924
00925
00926 TQUndoManager::TQUndoManager() : TQCommand(0, 0, 0, 0)
00927 {
00928
00929
00930 fCursor = 0;
00931 fLimit = kMaxUInt;
00932 fLogging = kFALSE;
00933 fLogBook = 0;
00934 fCurrent = 0;
00935 }
00936
00937
00938 TQUndoManager::~TQUndoManager()
00939 {
00940
00941
00942 Delete();
00943
00944 if (fLogBook) {
00945 delete fLogBook;
00946 }
00947 }
00948
00949
00950 void TQUndoManager::ls(Option_t *option) const
00951 {
00952
00953
00954 if (!IsEmpty()) {
00955 TObjLink *lnk = fFirst;
00956 while (lnk) {
00957 if (lnk == fCursor) {
00958 printf("->");
00959 } else {
00960 printf(" ");
00961 }
00962 TQCommand *com = (TQCommand*)lnk->GetObject();
00963 com->ls(option);
00964 lnk = lnk->Next();
00965 }
00966 }
00967 }
00968
00969
00970 void TQUndoManager::PrintCollectionEntry(TObject* entry, Option_t* option,
00971 Int_t ) const
00972 {
00973
00974
00975 TQCommand *com = (TQCommand*) entry;
00976 TROOT::IndentLevel();
00977 if (fCursor && fCursor->GetObject() == entry) {
00978 printf("->");
00979 } else {
00980 printf(" ");
00981 }
00982 com->ls(option);
00983 }
00984
00985
00986 void TQUndoManager::SetLogging(Bool_t on)
00987 {
00988
00989
00990
00991 fLogging = on;
00992
00993 if (fLogging) {
00994 if (fLogBook) {
00995 fLogBook->Delete();
00996 } else {
00997 fLogBook = new TList();
00998 }
00999 }
01000 }
01001
01002
01003 void TQUndoManager::Add(TObject *obj, Option_t *opt)
01004 {
01005
01006
01007
01008
01009
01010
01011
01012 if (!obj->InheritsFrom(TQCommand::Class())) return;
01013
01014 TQCommand *o = (TQCommand *)obj;
01015 TQCommand *c;
01016 Bool_t onredo = fCursor && fCursor->Next();
01017 TString ostr = onredo ? "1radd" : "0radd";
01018 if (opt) ostr += opt;
01019
01020 if (fState) {
01021 c = fCurrent;
01022 if (c) {
01023 fCurrent = o;
01024 c->Add(o, "remove");
01025 }
01026 return;
01027 }
01028
01029
01030 if (fCursor && fCursor->Next()) {
01031 TObjLink *lnk = fCursor->Next();
01032 TObjLink *sav;
01033 while (lnk) {
01034 sav = lnk->Next();
01035 delete lnk->GetObject();
01036 Remove(lnk);
01037 lnk = sav;
01038 }
01039 }
01040
01041 c = GetCursor();
01042 if (c) {
01043 if (c->CanCompress(o) || c->CanMerge(o) ||
01044 ostr.Contains("merge") || ostr.Contains("compress")) {
01045 fState = 1;
01046 c->Add(o, ostr.Data());
01047 fState = 0;
01048 return;
01049 }
01050 }
01051
01052 TList::AddLast(obj, ostr.Data());
01053 fCursor = fLast;
01054 Redo(ostr.Data());
01055
01056 if ((fSize > 0) && ((UInt_t)fSize > fLimit)) {
01057 Remove(fFirst);
01058 }
01059 }
01060
01061
01062 void TQUndoManager::CurrentChanged(TQCommand *c)
01063 {
01064
01065
01066 Emit("CurrentChanged(TQCommand*)", (long)c);
01067 }
01068
01069
01070 void TQUndoManager::Undo(Option_t *option)
01071 {
01072
01073
01074 Bool_t done = kFALSE;
01075 if (!CanUndo()) return;
01076
01077 TQCommand *sav = fCurrent;
01078 TQCommand *c = (TQCommand*)fCursor->GetObject();
01079
01080 if (c->CanUndo()) {
01081 fState = -1;
01082 fCurrent = c;
01083 fCurrent->Undo(option);
01084 fState = 0;
01085 done = kTRUE;
01086 fCursor = fCursor->Prev() ? fCursor->Prev() : fFirst;
01087 } else {
01088 fCursor = fCursor->Prev();
01089 fCurrent = (TQCommand*)fCursor->GetObject();
01090 fState = -1;
01091 fCurrent->Undo(option);
01092 fState = 0;
01093 done = kTRUE;
01094 }
01095 if (done && fLogging && fLogBook) {
01096 fLogBook->Add(new TQCommand(*fCurrent));
01097 }
01098 if (sav != fCurrent) CurrentChanged(fCurrent);
01099 }
01100
01101
01102 void TQUndoManager::Redo(Option_t *option)
01103 {
01104
01105
01106 Bool_t done = kFALSE;
01107 if (!CanRedo()) return;
01108
01109 TQCommand *sav = fCurrent;
01110 TQCommand *c = (TQCommand*)fCursor->GetObject();
01111
01112 if (c->CanRedo()) {
01113 fState = 1;
01114 fCurrent = c;
01115 fCurrent->Redo(option);
01116 fState = 0;
01117 done = kTRUE;
01118 fCursor = fCursor->Next() ? fCursor->Next() : fLast;
01119 } else {
01120 fCursor = fCursor->Next();
01121 fCurrent = (TQCommand*)fCursor->GetObject();
01122 fState = 1;
01123 fCurrent->Redo(option);
01124 fState = 0;
01125 done = kTRUE;
01126 }
01127 if (done && fLogging && fLogBook) {
01128 fLogBook->Add(new TQCommand(*fCurrent));
01129 }
01130 if (sav != fCurrent) CurrentChanged(fCurrent);
01131 }
01132
01133
01134 Bool_t TQUndoManager::CanRedo() const
01135 {
01136
01137
01138 if (!fCursor) return kFALSE;
01139
01140 TQCommand *c = (TQCommand*)fCursor->GetObject();
01141 if (c->CanRedo()) return kTRUE;
01142
01143 c = fCursor->Next() ? (TQCommand*)fCursor->Next()->GetObject() : 0;
01144 return (c && c->CanRedo());
01145 }
01146
01147
01148 Bool_t TQUndoManager::CanUndo() const
01149 {
01150
01151
01152 if (!fCursor) return kFALSE;
01153
01154 TQCommand *c = (TQCommand*)fCursor->GetObject();
01155 if (c->CanUndo()) return kTRUE;
01156
01157 c = fCursor->Prev() ? (TQCommand*)fCursor->Prev()->GetObject() : 0;
01158 return (c && c->CanUndo());
01159 }
01160
01161
01162 Bool_t TQUndoManager::IsLogging() const
01163 {
01164
01165
01166 return fLogging;
01167 }
01168
01169
01170 TQCommand *TQUndoManager::GetCurrent() const
01171 {
01172
01173
01174 return fCurrent;
01175 }
01176
01177
01178 TQCommand *TQUndoManager::GetCursor() const
01179 {
01180
01181
01182 return (TQCommand*)(fCursor ? fCursor->GetObject() : 0);
01183 }
01184
01185
01186 void TQUndoManager::SetLimit(UInt_t limit)
01187 {
01188
01189
01190 fLimit = limit;
01191 }
01192
01193
01194 UInt_t TQUndoManager::GetLimit() const
01195 {
01196
01197
01198 return fLimit;
01199 }