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 #include "TGListView.h"
00042 #include "TGPicture.h"
00043 #include "TGButton.h"
00044 #include "TGScrollBar.h"
00045 #include "TGResourcePool.h"
00046 #include "TList.h"
00047 #include "TSystem.h"
00048 #include "TGMimeTypes.h"
00049 #include "TObjString.h"
00050 #include "Riostream.h"
00051
00052 const TGFont *TGLVEntry::fgDefaultFont = 0;
00053 TGGC *TGLVEntry::fgDefaultGC = 0;
00054
00055 const TGFont *TGListView::fgDefaultFont = 0;
00056 TGGC *TGListView::fgDefaultGC = 0;
00057
00058
00059 ClassImp(TGLVEntry)
00060 ClassImp(TGLVContainer)
00061 ClassImp(TGListView)
00062
00063
00064 TGLVEntry::TGLVEntry(const TGWindow *p, const TGPicture *bigpic,
00065 const TGPicture *smallpic, TGString *name,
00066 TGString **subnames, EListViewMode viewMode,
00067 UInt_t options, ULong_t back) :
00068 TGFrame(p, 10, 10, options, back)
00069 {
00070
00071
00072 fSelPic = 0;
00073
00074 fCurrent =
00075 fBigPic = bigpic;
00076 fSmallPic = smallpic;
00077
00078 fCheckMark = fClient->GetPicture("checkmark_t.xpm");
00079 fChecked = kFALSE;
00080
00081 fItemName = name;
00082 fSubnames = subnames;
00083 fUserData = 0;
00084
00085 fCpos =
00086 fJmode = 0;
00087
00088 fActive = kFALSE;
00089
00090 fFontStruct = GetDefaultFontStruct();
00091 fNormGC = GetDefaultGC()();
00092
00093 Int_t max_ascent, max_descent;
00094 fTWidth = gVirtualX->TextWidth(fFontStruct,
00095 fItemName ? fItemName->GetString() : "",
00096 fItemName ? fItemName->GetLength() : 0);
00097 gVirtualX->GetFontProperties(fFontStruct, max_ascent, max_descent);
00098 fTHeight = max_ascent + max_descent;
00099
00100 if (fSubnames) {
00101 Int_t i;
00102 for (i = 0; fSubnames[i] != 0; ++i)
00103 ;
00104 fCtw = new int[i+1];
00105 fCtw[i] = 0;
00106 for (i = 0; fSubnames[i] != 0; ++i) {
00107 fCtw[i] = gVirtualX->TextWidth(fFontStruct, fSubnames[i]->GetString(),
00108 fSubnames[i]->GetLength());
00109 }
00110 } else {
00111 fCtw = 0;
00112 }
00113
00114 fViewMode = (EListViewMode)-1;
00115 SetViewMode(viewMode);
00116 }
00117
00118
00119 TGLVEntry::TGLVEntry(const TGLVContainer *p, const TString& name,
00120 const TString& cname, TGString **subnames,
00121 UInt_t options, Pixel_t back) :
00122 TGFrame(p, 10, 10, options, back)
00123 {
00124
00125
00126
00127
00128
00129
00130 fSelPic = 0;
00131
00132 fCurrent =
00133 fBigPic = fClient->GetMimeTypeList()->GetIcon(cname, kFALSE);
00134 fCheckMark = fClient->GetPicture("checkmark_t.xpm");
00135 fChecked = kFALSE;
00136
00137 if (!fBigPic) {
00138 fBigPic = fClient->GetPicture("doc_s.xpm");
00139 }
00140 fSmallPic = fClient->GetMimeTypeList()->GetIcon(cname, kTRUE);
00141 if (!fSmallPic) {
00142 fSmallPic = fClient->GetPicture("doc_t.xpm");
00143 }
00144
00145 fItemName = new TGString(name);
00146 fSubnames = subnames;
00147 fUserData = 0;
00148
00149 fCpos =
00150 fJmode = 0;
00151
00152 fActive = kFALSE;
00153
00154 fFontStruct = GetDefaultFontStruct();
00155 fNormGC = GetDefaultGC()();
00156
00157 Int_t max_ascent, max_descent;
00158 fTWidth = gVirtualX->TextWidth(fFontStruct, fItemName->GetString(), fItemName->GetLength());
00159 gVirtualX->GetFontProperties(fFontStruct, max_ascent, max_descent);
00160 fTHeight = max_ascent + max_descent;
00161
00162 if (fSubnames) {
00163 Int_t i;
00164 for (i = 0; fSubnames[i] != 0; ++i)
00165 ;
00166 fCtw = new int[i+1];
00167 fCtw[i] = 0;
00168 for (i = 0; fSubnames[i] != 0; ++i) {
00169 fCtw[i] = gVirtualX->TextWidth(fFontStruct, fSubnames[i]->GetString(),
00170 fSubnames[i]->GetLength());
00171 }
00172 } else {
00173 fCtw = 0;
00174 }
00175
00176 fViewMode = (EListViewMode)-1;
00177 SetViewMode((EListViewMode)p->GetViewMode());
00178 }
00179
00180
00181 TGLVEntry::~TGLVEntry()
00182 {
00183
00184
00185 if (fItemName) delete fItemName;
00186 if (fSelPic) delete fSelPic;
00187 if (fSubnames) {
00188 for (Int_t i = 0; fSubnames[i] != 0; ++i) delete fSubnames[i];
00189 delete [] fSubnames;
00190 delete [] fCtw;
00191 }
00192 }
00193
00194
00195 void TGLVEntry::SetSubnames(const char* n1,const char* n2,const char* n3,
00196 const char* n4,const char* n5,const char* n6,
00197 const char* n7,const char* n8,const char* n9,
00198 const char* n10,const char* n11,const char* n12)
00199 {
00200
00201
00202 if (fSubnames) {
00203 for (Int_t i = 0; fSubnames[i] != 0; ++i) delete fSubnames[i];
00204 delete [] fSubnames;
00205 delete [] fCtw;
00206 }
00207
00208 Int_t ncol = 0;
00209 fSubnames = 0;
00210
00211 if (n12 && strlen(n12)) ncol=12;
00212 else if (n11 && strlen(n11)) ncol=11;
00213 else if (n10 && strlen(n10)) ncol=10;
00214 else if (n9 && strlen(n9)) ncol=9;
00215 else if (n8 && strlen(n8)) ncol=8;
00216 else if (n7 && strlen(n7)) ncol=7;
00217 else if (n6 && strlen(n6)) ncol=6;
00218 else if (n5 && strlen(n5)) ncol=5;
00219 else if (n4 && strlen(n4)) ncol=4;
00220 else if (n3 && strlen(n3)) ncol=3;
00221 else if (n2 && strlen(n2)) ncol=2;
00222 else if (n1 && strlen(n1)) ncol=1;
00223
00224 if (!ncol) return;
00225
00226 fSubnames = new TGString* [ncol+1];
00227
00228 if (ncol>11) fSubnames[11] = new TGString(n12);
00229 if (ncol>10) fSubnames[10] = new TGString(n11);
00230 if (ncol>9) fSubnames[9] = new TGString(n10);
00231 if (ncol>8) fSubnames[8] = new TGString(n9);
00232 if (ncol>7) fSubnames[7] = new TGString(n8);
00233 if (ncol>6) fSubnames[6] = new TGString(n7);
00234 if (ncol>5) fSubnames[5] = new TGString(n6);
00235 if (ncol>4) fSubnames[4] = new TGString(n5);
00236 if (ncol>3) fSubnames[3] = new TGString(n4);
00237 if (ncol>2) fSubnames[2] = new TGString(n3);
00238 if (ncol>1) fSubnames[1] = new TGString(n2);
00239 if (ncol>0) fSubnames[0] = new TGString(n1);
00240 fSubnames[ncol] = 0;
00241
00242 fCtw = new int[ncol];
00243 fCtw[ncol-1] = 0;
00244
00245 for (int i = 0; i<ncol; i++) {
00246 fCtw[i] = gVirtualX->TextWidth(fFontStruct, fSubnames[i]->GetString(),
00247 fSubnames[i]->GetLength());
00248 }
00249 }
00250
00251
00252 void TGLVEntry::Activate(Bool_t a)
00253 {
00254
00255
00256 if (fActive == a) return;
00257 fActive = a;
00258
00259 if (fActive) {
00260 fSelPic = new TGSelectedPicture(gClient, fCurrent);
00261 } else {
00262 if (fSelPic) delete fSelPic;
00263 fSelPic = 0;
00264 }
00265 DoRedraw();
00266 }
00267
00268
00269 void TGLVEntry::SetViewMode(EListViewMode viewMode)
00270 {
00271
00272
00273 if (viewMode != fViewMode) {
00274 fViewMode = viewMode;
00275 if (viewMode == kLVLargeIcons)
00276 fCurrent = fBigPic;
00277 else
00278 fCurrent = fSmallPic;
00279 if (fActive) {
00280 if (fSelPic) delete fSelPic;
00281 fSelPic = new TGSelectedPicture(gClient, fCurrent);
00282 }
00283 gVirtualX->ClearWindow(fId);
00284 Resize(GetDefaultSize());
00285 fClient->NeedRedraw(this);
00286 }
00287 }
00288
00289
00290 void TGLVEntry::SetPictures(const TGPicture *bigpic, const TGPicture *smallpic)
00291 {
00292
00293
00294 if (!bigpic || !smallpic) return;
00295
00296 gVirtualX->ClearWindow(fId);
00297
00298 fBigPic = bigpic;
00299 fSmallPic = smallpic;
00300 fCurrent = fViewMode == kLVLargeIcons ? fBigPic : fSmallPic;
00301
00302 if (fSelPic) delete fSelPic;
00303 fSelPic = new TGSelectedPicture(gClient, fCurrent);
00304
00305 Resize();
00306 gVirtualX->ClearWindow(fId);
00307 }
00308
00309
00310 void TGLVEntry::DoRedraw()
00311 {
00312
00313
00314
00315
00316 DrawCopy(fId, 0, 0);
00317 }
00318
00319
00320 void TGLVEntry::DrawCopy(Handle_t id, Int_t x, Int_t y)
00321 {
00322
00323
00324
00325
00326 Int_t ix, iy, lx, ly;
00327 Int_t max_ascent, max_descent;
00328
00329 gVirtualX->GetFontProperties(fFontStruct, max_ascent, max_descent);
00330 fTWidth = gVirtualX->TextWidth(fFontStruct, fItemName->GetString(), fItemName->GetLength());
00331 fTHeight = max_ascent + max_descent;
00332
00333 if (fViewMode == kLVLargeIcons) {
00334 ix = (fWidth - fCurrent->GetWidth()) >> 1;
00335 iy = 0;
00336 lx = (fWidth - fTWidth) >> 1;
00337 ly = fHeight - (fTHeight + 1) - 2;
00338 } else {
00339 ix = 0;
00340 iy = (fHeight - fCurrent->GetHeight()) >> 1;
00341 lx = fCurrent->GetWidth() + 2;
00342 ly = (fHeight - (fTHeight + 1)) >> 1;
00343 }
00344
00345 if ((fChecked) && (fCheckMark)) {
00346 if (fViewMode == kLVLargeIcons) {
00347 fCheckMark->Draw(id, fNormGC, x + ix + 8, y + iy + 8);
00348 gVirtualX->SetForeground(fNormGC, fgWhitePixel);
00349 gVirtualX->FillRectangle(id, fNormGC, x + lx, y + ly, fTWidth, fTHeight + 1);
00350 gVirtualX->SetForeground(fNormGC, fgBlackPixel);
00351 }
00352 else {
00353 fCheckMark->Draw(id, fNormGC, x + ix, y + iy);
00354 gVirtualX->SetForeground(fNormGC, fgWhitePixel);
00355 gVirtualX->FillRectangle(id, fNormGC, x + lx, y + ly, fTWidth, fTHeight + 1);
00356 gVirtualX->SetForeground(fNormGC, fgBlackPixel);
00357 }
00358 }
00359
00360
00361 if (fViewMode == kLVDetails && fSubnames && fCpos && fJmode && fCtw) {
00362 TString tmpString = *fItemName;
00363 Int_t ftmpWidth = gVirtualX->TextWidth(fFontStruct, tmpString,
00364 tmpString.Length());
00365 if ( ftmpWidth > (fCpos[0] - lx) ) {
00366 for (Int_t j = fItemName->Length() - 1 ; j > 0; j--) {
00367 tmpString = (*fItemName)(0,j) + "...";
00368 ftmpWidth = gVirtualX->TextWidth(GetDefaultFontStruct(), tmpString,
00369 tmpString.Length());
00370 if ( ftmpWidth <= (fCpos[0] - lx) ) {
00371 break;
00372 }
00373 }
00374 }
00375 if (fActive) {
00376 if (fSelPic) fSelPic->Draw(id, fNormGC, x + ix, y + iy);
00377 gVirtualX->SetForeground(fNormGC, fgDefaultSelectedBackground);
00378 gVirtualX->FillRectangle(id, fNormGC, x + lx, y + ly, ftmpWidth, fTHeight + 1);
00379 gVirtualX->SetForeground(fNormGC, fClient->GetResourcePool()->GetSelectedFgndColor());
00380 } else {
00381 fCurrent->Draw(id, fNormGC, x + ix, y + iy);
00382 gVirtualX->SetForeground(fNormGC, fgWhitePixel);
00383 gVirtualX->FillRectangle(id, fNormGC, x + lx, y + ly, ftmpWidth, fTHeight + 1);
00384 gVirtualX->SetForeground(fNormGC, fgBlackPixel);
00385 }
00386
00387 TGString tmpTGString(tmpString);
00388 tmpTGString.Draw(id, fNormGC, x+lx, y+ly + max_ascent);
00389 } else {
00390 if (fActive) {
00391 if (fSelPic) fSelPic->Draw(id, fNormGC, x + ix, y + iy);
00392 gVirtualX->SetForeground(fNormGC, fgDefaultSelectedBackground);
00393 gVirtualX->FillRectangle(id, fNormGC, x + lx, y + ly, fTWidth, fTHeight + 1);
00394 gVirtualX->SetForeground(fNormGC, fClient->GetResourcePool()->GetSelectedFgndColor());
00395 } else {
00396 fCurrent->Draw(id, fNormGC, x + ix, y + iy);
00397 gVirtualX->SetForeground(fNormGC, fgWhitePixel);
00398 gVirtualX->FillRectangle(id, fNormGC, x + lx, y + ly, fTWidth, fTHeight + 1);
00399 gVirtualX->SetForeground(fNormGC, fgBlackPixel);
00400 }
00401 fItemName->Draw(id, fNormGC, x+lx, y+ly + max_ascent);
00402 }
00403 gVirtualX->SetForeground(fNormGC, fgBlackPixel);
00404
00405 if (fViewMode == kLVDetails) {
00406 if (fSubnames && fCpos && fJmode && fCtw) {
00407 int i;
00408
00409
00410 for (i = 0; fSubnames[i] != 0; ++i) {
00411 TString tmpString = *fSubnames[i];
00412 Int_t ftmpWidth = gVirtualX->TextWidth(fFontStruct, tmpString,
00413 tmpString.Length());
00414 if ( ftmpWidth > (fCpos[i+1] - fCpos[i]) ) {
00415 for (int j = fSubnames[i]->Length() - 1 ; j > 0; j--) {
00416 tmpString = (*fSubnames[i])(0,j) + "...";
00417 ftmpWidth = gVirtualX->TextWidth(GetDefaultFontStruct(),
00418 tmpString,
00419 tmpString.Length());
00420 if ( ftmpWidth <= (fCpos[i+1] - fCpos[i]) ) {
00421 break;
00422 }
00423 }
00424 }
00425 if (fCpos[i] == 0)
00426 break;
00427 if (fJmode[i] == kTextRight)
00428 lx = fCpos[i+1] - ftmpWidth - 2;
00429 else if (fJmode[i] == kTextCenterX)
00430 lx = (fCpos[i] + fCpos[i+1] - ftmpWidth) >> 1;
00431 else
00432 lx = fCpos[i] + 2;
00433
00434
00435 TGString tmpTGString(tmpString);
00436 tmpTGString.Draw(id, fNormGC, x + lx, y + ly + max_ascent);
00437 }
00438 }
00439 }
00440 }
00441
00442
00443 TGDimension TGLVEntry::GetDefaultSize() const
00444 {
00445
00446
00447 TGDimension size;
00448 TGDimension isize(fCurrent ? fCurrent->GetWidth() : 0,
00449 fCurrent ? fCurrent->GetHeight() : 0);
00450 TGDimension lsize(fTWidth, fTHeight+1);
00451
00452 switch (fViewMode) {
00453 default:
00454 case kLVLargeIcons:
00455 size.fWidth = TMath::Max(isize.fWidth, lsize.fWidth);
00456 size.fHeight = isize.fHeight + lsize.fHeight + 6;
00457 break;
00458
00459 case kLVSmallIcons:
00460 case kLVList:
00461 case kLVDetails:
00462 size.fWidth = isize.fWidth + lsize.fWidth + 4;
00463 size.fHeight = TMath::Max(isize.fHeight, lsize.fHeight);
00464 break;
00465 }
00466 return size;
00467 }
00468
00469
00470 FontStruct_t TGLVEntry::GetDefaultFontStruct()
00471 {
00472
00473
00474 if (!fgDefaultFont)
00475 fgDefaultFont = gClient->GetResourcePool()->GetIconFont();
00476 return fgDefaultFont->GetFontStruct();
00477 }
00478
00479
00480 const TGGC &TGLVEntry::GetDefaultGC()
00481 {
00482
00483
00484 if (!fgDefaultGC) {
00485 fgDefaultGC = new TGGC(*gClient->GetResourcePool()->GetFrameGC());
00486 fgDefaultGC->SetFont(fgDefaultFont->GetFontHandle());
00487 }
00488 return *fgDefaultGC;
00489 }
00490
00491
00492
00493 TGLVContainer::TGLVContainer(const TGWindow *p, UInt_t w, UInt_t h,
00494 UInt_t options, ULong_t back) :
00495 TGContainer(p, w, h, options, back)
00496 {
00497
00498
00499
00500
00501 fListView = 0;
00502 fLastActive = 0;
00503 fCpos = fJmode = 0;
00504 fMultiSelect = kFALSE;
00505
00506 fViewMode = kLVLargeIcons;
00507 fItemLayout = new TGLayoutHints(kLHintsExpandY | kLHintsCenterX);
00508
00509 SetLayoutManager(new TGTileLayout(this, 8));
00510 }
00511
00512
00513 TGLVContainer::TGLVContainer(TGCanvas *p,UInt_t options, ULong_t back) :
00514 TGContainer(p,options, back)
00515 {
00516
00517
00518
00519
00520 fListView = 0;
00521 fLastActive = 0;
00522 fCpos = fJmode = 0;
00523 fMultiSelect = kFALSE;
00524
00525 fViewMode = kLVLargeIcons;
00526 fItemLayout = new TGLayoutHints(kLHintsExpandY | kLHintsCenterX);
00527
00528 SetLayoutManager(new TGTileLayout(this, 8));
00529
00530 if (p->InheritsFrom(TGListView::Class())) fListView = (TGListView*)p;
00531 }
00532
00533
00534 TGLVContainer::~TGLVContainer()
00535 {
00536
00537
00538 if (!MustCleanup()) {
00539 RemoveAll();
00540 delete fItemLayout;
00541 }
00542 }
00543
00544
00545 void TGLVContainer::SetColHeaders(const char* n1,const char* n2,const char* n3,
00546 const char* n4,const char* n5,const char* n6,
00547 const char* n7,const char* n8,const char* n9,
00548 const char* n10,const char* n11,const char* n12)
00549 {
00550
00551
00552 if (!fListView) return;
00553
00554 Int_t ncol = -1;
00555 if (n12 && strlen(n12)) ncol=12;
00556 else if (n11 && strlen(n11)) ncol=11;
00557 else if (n10 && strlen(n10)) ncol=10;
00558 else if (n9 && strlen(n9)) ncol=9;
00559 else if (n8 && strlen(n8)) ncol=8;
00560 else if (n7 && strlen(n7)) ncol=7;
00561 else if (n6 && strlen(n6)) ncol=6;
00562 else if (n5 && strlen(n5)) ncol=5;
00563 else if (n4 && strlen(n4)) ncol=4;
00564 else if (n3 && strlen(n3)) ncol=3;
00565 else if (n2 && strlen(n2)) ncol=2;
00566 else if (n1 && strlen(n1)) ncol=1;
00567
00568 if (ncol<0) return;
00569
00570 fListView->SetHeaders(ncol);
00571 if (ncol>0) fListView->SetHeader(n1, kTextCenterX, kTextLeft , 0);
00572 if (ncol>1) fListView->SetHeader(n2, kTextCenterX, kTextLeft , 1);
00573 if (ncol>2) fListView->SetHeader(n3, kTextCenterX, kTextLeft , 2);
00574 if (ncol>3) fListView->SetHeader(n4, kTextCenterX, kTextLeft , 3);
00575 if (ncol>4) fListView->SetHeader(n5, kTextCenterX, kTextLeft , 4);
00576 if (ncol>5) fListView->SetHeader(n6, kTextCenterX, kTextLeft , 5);
00577 if (ncol>6) fListView->SetHeader(n7, kTextCenterX, kTextLeft , 6);
00578 if (ncol>7) fListView->SetHeader(n8, kTextCenterX, kTextLeft , 7);
00579 if (ncol>8) fListView->SetHeader(n9, kTextCenterX, kTextLeft , 8);
00580 if (ncol>9) fListView->SetHeader(n10, kTextCenterX, kTextLeft , 9);
00581 if (ncol>10) fListView->SetHeader(n11, kTextCenterX, kTextLeft , 10);
00582 if (ncol>11) fListView->SetHeader(n12, kTextCenterX, kTextLeft , 11);
00583
00584 fListView->Layout();
00585 }
00586
00587
00588 void TGLVContainer::SetViewMode(EListViewMode viewMode)
00589 {
00590
00591
00592 if (fViewMode != viewMode) {
00593 TGLayoutHints *oldLayout = fItemLayout;
00594
00595 EListViewMode old = fViewMode;
00596 fViewMode = viewMode;
00597 if (fListView) fListView->SetViewMode(viewMode);
00598
00599 if (viewMode == kLVLargeIcons)
00600 fItemLayout = new TGLayoutHints(kLHintsExpandY | kLHintsCenterX);
00601 else
00602 fItemLayout = new TGLayoutHints(kLHintsLeft | kLHintsCenterY);
00603
00604 TGFrameElement *el;
00605 TIter next(fList);
00606 while ((el = (TGFrameElement *) next())) {
00607 el->fLayout = fItemLayout;
00608 ((TGLVEntry *) el->fFrame)->SetViewMode(viewMode);
00609 }
00610 delete oldLayout;
00611
00612 switch (viewMode) {
00613 default:
00614 case kLVLargeIcons:
00615 SetLayoutManager(new TGTileLayout(this, 8));
00616 break;
00617
00618 case kLVSmallIcons:
00619 SetLayoutManager(new TGTileLayout(this, 2));
00620 break;
00621
00622 case kLVList:
00623 SetLayoutManager(new TGListLayout(this, 2));
00624 break;
00625
00626 case kLVDetails:
00627 SetLayoutManager(new TGListDetailsLayout(this, 2));
00628 break;
00629 }
00630
00631 TGCanvas *canvas = (TGCanvas *) this->GetParent()->GetParent();
00632
00633
00634 UInt_t height = fHeight;
00635 UInt_t width = fWidth;
00636 TGPosition pos = GetPagePosition();
00637 canvas->Layout();
00638 pos.fX = (pos.fX*fWidth)/width;
00639 pos.fY = (pos.fY*fHeight)/height;
00640
00641 if (old == kLVList) {
00642 SetVsbPosition(pos.fX);
00643 SetHsbPosition(0);
00644 } else if (fViewMode == kLVList) {
00645 SetHsbPosition(pos.fY);
00646 } else {
00647 SetVsbPosition(pos.fY);
00648 SetHsbPosition(pos.fX);
00649 }
00650 }
00651 }
00652
00653
00654 void TGLVContainer::SetColumns(Int_t *cpos, Int_t *jmode)
00655 {
00656
00657
00658 fCpos = cpos;
00659 fJmode = jmode;
00660
00661 TGFrameElement *el;
00662 TIter next(fList);
00663 while ((el = (TGFrameElement *) next())) {
00664 ((TGLVEntry *) el->fFrame)->SetColumns(fCpos, fJmode);
00665 }
00666 Layout();
00667 }
00668
00669
00670 TGDimension TGLVContainer::GetMaxItemSize() const
00671 {
00672
00673
00674 TGDimension csize, maxsize(0,0);
00675
00676 TGFrameElement *el;
00677 TIter next(fList);
00678 while ((el = (TGFrameElement *) next())) {
00679 csize = el->fFrame->GetDefaultSize();
00680 maxsize.fWidth = TMath::Max(maxsize.fWidth, csize.fWidth);
00681 maxsize.fHeight = TMath::Max(maxsize.fHeight, csize.fHeight);
00682 }
00683 if (fViewMode == kLVLargeIcons) {
00684 maxsize.fWidth += 8;
00685 maxsize.fHeight += 8;
00686 } else {
00687 maxsize.fWidth += 2;
00688 maxsize.fHeight += 2;
00689 }
00690 return maxsize;
00691 }
00692
00693
00694 Int_t TGLVContainer::GetMaxSubnameWidth(Int_t idx) const
00695 {
00696
00697
00698 if (idx == 0) {
00699 return GetMaxItemSize().fWidth;
00700 }
00701
00702 Int_t width, maxwidth = 0;
00703
00704 TGFrameElement *el;
00705 TIter next(fList);
00706 while ((el = (TGFrameElement *) next())) {
00707 TGLVEntry *entry = (TGLVEntry *) el->fFrame;
00708 width = entry->GetSubnameWidth(idx-1);
00709 maxwidth = TMath::Max(maxwidth, width);
00710 }
00711 return maxwidth;
00712 }
00713
00714
00715 void TGLVContainer::RemoveItemWithData(void *userData)
00716 {
00717
00718
00719 TGFrameElement *el;
00720 TIter next(fList);
00721 while ((el = (TGFrameElement *) next())) {
00722 TGLVEntry *f = (TGLVEntry *) el->fFrame;
00723 if (f->GetUserData() == userData) {
00724 RemoveItem(f);
00725 break;
00726 }
00727 }
00728 }
00729
00730
00731 void TGLVContainer::ActivateItem(TGFrameElement* el)
00732 {
00733
00734
00735 TGContainer::ActivateItem(el);
00736 fLastActive = (TGLVEntry*)el->fFrame;
00737 }
00738
00739
00740 void TGLVContainer::DeActivateItem(TGFrameElement* el)
00741 {
00742
00743
00744 TGContainer::DeActivateItem(el);
00745 fLastActive = (TGLVEntry*)el->fFrame;
00746 }
00747
00748
00749 Bool_t TGLVContainer::HandleButton(Event_t* event)
00750 {
00751
00752
00753 if ( !fMultiSelect ) {
00754 return TGContainer::HandleButton(event);
00755 }
00756
00757 Int_t total = 0, selected = fSelected, page = 0;
00758
00759 TGPosition pos = GetPagePosition();
00760 TGDimension dim = GetPageDimension();
00761 Int_t newpos;
00762 page = dim.fHeight/4;
00763
00764 if (event->fCode == kButton4) {
00765
00766 newpos = pos.fY - page;
00767 if (newpos < 0) newpos = 0;
00768 fCanvas->SetVsbPosition(newpos);
00769 return kTRUE;
00770 }
00771 if (event->fCode == kButton5) {
00772
00773 newpos = fCanvas->GetVsbPosition() + page;
00774 fCanvas->SetVsbPosition(newpos);
00775 return kTRUE;
00776 }
00777
00778 Int_t xx = pos.fX + event->fX;
00779 Int_t yy = pos.fY + event->fY;
00780
00781 if (event->fType == kButtonPress) {
00782 gVirtualX->SetInputFocus(fId);
00783
00784 fXp = pos.fX + event->fX;
00785 fYp = pos.fY + event->fY;
00786
00787 TGFrameElement *el;
00788 TIter next(fList);
00789 Bool_t select_frame = kFALSE;
00790
00791 if (event->fState & kKeyShiftMask) {
00792 Bool_t inSelection = kFALSE;
00793 TGLVEntry* last = fLastActive;
00794
00795 while ((el = (TGFrameElement *) next())) {
00796 select_frame = kFALSE;
00797
00798 if (!fMapSubwindows) {
00799 if ((Int_t(el->fFrame->GetY()) + (Int_t)el->fFrame->GetHeight() > yy ) &&
00800 (Int_t(el->fFrame->GetX()) + (Int_t)el->fFrame->GetWidth() > xx ) &&
00801 (Int_t(el->fFrame->GetY()) < yy) &&
00802 (Int_t(el->fFrame->GetX()) < xx)) {
00803 select_frame = kTRUE;
00804 }
00805 } else {
00806 if (el->fFrame->GetId() == (Window_t)event->fUser[0]) {
00807 select_frame = kTRUE;
00808 }
00809 }
00810
00811 if (select_frame || last==el->fFrame)
00812 inSelection = !inSelection;
00813 if (inSelection || select_frame) {
00814 if ( !el->fFrame->IsActive() ) {
00815 selected++;
00816 ActivateItem(el);
00817 }
00818 Clicked(el->fFrame, event->fCode);
00819 Clicked(el->fFrame, event->fCode, event->fXRoot, event->fYRoot);
00820 }
00821 total++;
00822 }
00823 } else if (event->fState & kKeyControlMask) {
00824
00825 } else {
00826 UnSelectAll();
00827 total = selected = 0;
00828 }
00829
00830 select_frame = kFALSE;
00831 while ((el = (TGFrameElement *) next())) {
00832 select_frame = kFALSE;
00833
00834 if (!fMapSubwindows) {
00835 if ((Int_t(el->fFrame->GetY()) + (Int_t)el->fFrame->GetHeight() > yy ) &&
00836 (Int_t(el->fFrame->GetX()) + (Int_t)el->fFrame->GetWidth() > xx ) &&
00837 (Int_t(el->fFrame->GetY()) < yy) &&
00838 (Int_t(el->fFrame->GetX()) < xx)) {
00839 select_frame = kTRUE;
00840 }
00841 } else {
00842 if (el->fFrame->GetId() == (Window_t)event->fUser[0]) {
00843 select_frame = kTRUE;
00844 }
00845 }
00846
00847 if (select_frame) {
00848 if ( el->fFrame->IsActive() ) {
00849 selected--;
00850 DeActivateItem(el);
00851 } else {
00852 selected++;
00853 ActivateItem(el);
00854 }
00855 Clicked(el->fFrame, event->fCode);
00856 Clicked(el->fFrame, event->fCode, event->fXRoot, event->fYRoot);
00857 }
00858 total++;
00859 }
00860
00861 if (fTotal != total || fSelected != selected) {
00862 fTotal = total;
00863 fSelected = selected;
00864 SendMessage(fMsgWindow, MK_MSG(kC_CONTAINER, kCT_SELCHANGED),
00865 fTotal, fSelected);
00866 }
00867
00868 if ( selected == 0 ) {
00869 fDragging = kTRUE;
00870 fX0 = fXf = fXp;
00871 fY0 = fYf = fYp;
00872
00873 gVirtualX->DrawRectangle(fId, GetLineGC()(), fX0, fY0, fXf-fX0,
00874 fYf-fY0);
00875 }
00876 }
00877
00878 if (event->fType == kButtonRelease) {
00879 gVirtualX->SetInputFocus(fId);
00880
00881 if (fDragging) {
00882 fDragging = kFALSE;
00883 fScrolling = kFALSE;
00884
00885 if (gSystem) gSystem->RemoveTimer(fScrollTimer);
00886
00887 gVirtualX->DrawRectangle(fId, GetLineGC()(), fX0, fY0, fXf-fX0,
00888 fYf-fY0);
00889 } else {
00890 SendMessage(fMsgWindow, MK_MSG(kC_CONTAINER, kCT_ITEMCLICK),
00891 event->fCode, (event->fYRoot << 16) | event->fXRoot);
00892 }
00893 }
00894 fClient->NeedRedraw(this);
00895 return kTRUE;
00896 }
00897
00898
00899 TList *TGLVContainer::GetSelectedItems()
00900 {
00901
00902
00903 TGFrameElement *el;
00904 TIter next(fList);
00905 TList *ret = new TList();
00906
00907 while ((el = (TGFrameElement *) next())) {
00908 if (el->fFrame->IsActive()) {
00909 ret->Add(new TObjString(((TGLVEntry*)el->fFrame)->GetItemName()->GetString()));
00910 }
00911 }
00912 return ret;
00913 }
00914
00915
00916 void TGLVContainer::LineLeft(Bool_t select)
00917 {
00918
00919
00920
00921 if (fViewMode == kLVDetails) return LineUp(select);
00922
00923 TGPosition pos = GetPagePosition();
00924 TGDimension dim = GetPageDimension();
00925
00926 TGFrameElement *fe = (TGFrameElement*)fList->First();
00927 if (!fe) return;
00928
00929 TGFrameElement *old = fLastActiveEl;
00930
00931 if (fViewMode == kLVSmallIcons && fe == old) return;
00932
00933 if (old) DeActivateItem(old);
00934 else fLastActiveEl = fe;
00935
00936 TGDimension ms = fListView->GetMaxItemSize();
00937 Int_t dx = ms.fWidth;
00938 Int_t dy = ms.fHeight;
00939
00940 Int_t y = fLastActiveEl->fFrame->GetY();
00941 Int_t x = fLastActiveEl->fFrame->GetX() - dx + 2;
00942
00943 Int_t hw = pos.fX + dim.fWidth;
00944
00945 TGHScrollBar *hb = GetHScrollbar();
00946 if (hb && hb->IsMapped()) {
00947 Int_t pg = (hb->GetPageSize()*GetWidth())/fViewPort->GetWidth();
00948 hw += pg;
00949 }
00950 if (x <= 0) {
00951 x = hw;
00952 y = y - dy;
00953 }
00954
00955 fe = FindFrame(x, y);
00956 if (fe && fe->fFrame->GetY() > fLastActiveEl->fFrame->GetY()) {
00957
00958 x = hw;
00959 y = y - dy;
00960 fe = FindFrame(x, y);
00961 }
00962 if (fViewMode == kLVList) {
00963 if (fe && fe->fFrame->GetY() <= fLastActiveEl->fFrame->GetY() - (2 * dy)) {
00964
00965 x = fe->fFrame->GetX() - dx;
00966 fe = FindFrame(x, y);
00967 }
00968
00969 if (fe && fe->fFrame->GetY() >= fLastActiveEl->fFrame->GetY() &&
00970 fe->fFrame->GetX() >= fLastActiveEl->fFrame->GetX())
00971 fe = fLastActiveEl;
00972 }
00973 if (!fe || fe->fFrame->GetY() > fLastActiveEl->fFrame->GetY())
00974 fe = (TGFrameElement*)fList->First();
00975 if (!select) fSelected=1;
00976
00977 ActivateItem(fe);
00978 AdjustPosition();
00979 }
00980
00981
00982 void TGLVContainer::LineRight(Bool_t select)
00983 {
00984
00985
00986
00987 if (fViewMode == kLVDetails) return LineDown(select);
00988
00989 TGPosition pos = GetPagePosition();
00990 TGDimension dim = GetPageDimension();
00991
00992 TGFrameElement *fe = (TGFrameElement*)fList->Last();
00993 if (!fe) return;
00994
00995 TGFrameElement *old = fLastActiveEl;
00996
00997 if (fViewMode == kLVSmallIcons && fe == old) return;
00998
00999 if (old) DeActivateItem(old);
01000 else fLastActiveEl = (TGFrameElement*)fList->First();
01001
01002 TGDimension ms = fListView->GetMaxItemSize();
01003 Int_t dx = ms.fWidth;
01004 Int_t dy = ms.fHeight;
01005
01006 Int_t y = fLastActiveEl->fFrame->GetY();
01007 Int_t x = fLastActiveEl->fFrame->GetX() + dx - 2;
01008
01009 Int_t hw = pos.fX + dim.fWidth - dx;
01010
01011 TGHScrollBar *hb = GetHScrollbar();
01012 if (x > hw && (hb && !hb->IsMapped())) {
01013 x = 0;
01014 y = y + dy;
01015 }
01016
01017 fe = FindFrame(x, y);
01018 if (fe && fe->fFrame->GetY() < fLastActiveEl->fFrame->GetY()) {
01019
01020 x = 0;
01021 y = y + dy;
01022 fe = FindFrame(x, y);
01023 }
01024 if (fViewMode == kLVList) {
01025
01026 if (fe && fe->fFrame->GetY() <= fLastActiveEl->fFrame->GetY() &&
01027 fe->fFrame->GetX() <= fLastActiveEl->fFrame->GetX())
01028 fe = fLastActiveEl;
01029 }
01030 if (!fe || fe->fFrame->GetY() < fLastActiveEl->fFrame->GetY())
01031 fe = (TGFrameElement*)fList->Last();
01032 if (!select) fSelected = 1;
01033
01034 ActivateItem(fe);
01035 AdjustPosition();
01036 }
01037
01038
01039 void TGLVContainer::LineUp(Bool_t select)
01040 {
01041
01042
01043 TGFrameElement *fe = (TGFrameElement*)fList->First();
01044 if (!fe) return;
01045
01046 TGFrameElement *old = fLastActiveEl;
01047
01048 if (old) {
01049 DeActivateItem(old);
01050 } else {
01051 fLastActiveEl = (TGFrameElement*)fList->First();
01052 }
01053
01054 TGDimension ms = fListView->GetMaxItemSize();
01055 Int_t dy = ms.fHeight;
01056
01057 Int_t y = fLastActiveEl->fFrame->GetY() - dy;
01058 Int_t x = fLastActiveEl->fFrame->GetX();
01059
01060 fe = FindFrame(x, y);
01061 if (!fe) fe = (TGFrameElement*)fList->First();
01062 if (fe->fFrame->GetY() > fLastActiveEl->fFrame->GetY()) fe = fLastActiveEl;
01063 if (!select) fSelected = 1;
01064
01065 ActivateItem(fe);
01066 AdjustPosition();
01067 }
01068
01069
01070 void TGLVContainer::LineDown(Bool_t select)
01071 {
01072
01073
01074 TGFrameElement *fe = (TGFrameElement*)fList->Last();
01075 if (!fe) return;
01076
01077 TGFrameElement *old = fLastActiveEl;
01078
01079 if (old) DeActivateItem(old);
01080 else fLastActiveEl = (TGFrameElement*)fList->First();
01081
01082 TGDimension ms = fListView->GetMaxItemSize();
01083 Int_t dy = ms.fHeight;
01084
01085 Int_t y = fLastActiveEl->fFrame->GetY() + dy;
01086 Int_t x = fLastActiveEl->fFrame->GetX();
01087
01088 fe = FindFrame(x, y);
01089 if (!fe) fe = (TGFrameElement*)fList->Last();
01090 if (fe->fFrame->GetY() < fLastActiveEl->fFrame->GetY()) fe = fLastActiveEl;
01091 if (!select) fSelected = 1;
01092
01093 ActivateItem(fe);
01094 AdjustPosition();
01095 }
01096
01097
01098
01099 TGDimension TGLVContainer::GetPageDimension() const
01100 {
01101
01102
01103 TGDimension ret;
01104 if (!fViewPort) return ret;
01105
01106 ret.fWidth = fViewPort->GetWidth();
01107 ret.fHeight = fViewPort->GetHeight();
01108 return ret;
01109 }
01110
01111
01112 TGListView::TGListView(const TGWindow *p, UInt_t w, UInt_t h,
01113 UInt_t options, ULong_t back) :
01114 TGCanvas(p, w, h, options, back)
01115 {
01116
01117
01118 fViewMode = kLVLargeIcons;
01119 fNColumns = 0;
01120 fColumns = 0;
01121 fJmode = 0;
01122 fColHeader = 0;
01123 fColNames = 0;
01124 fSplitHeader = 0;
01125 fJustChanged = kFALSE;
01126 fMinColumnSize = 25;
01127 fFontStruct = GetDefaultFontStruct();
01128 fNormGC = GetDefaultGC()();
01129 if (fHScrollbar)
01130 fHScrollbar->Connect("PositionChanged(Int_t)", "TGListView",
01131 this, "ScrollHeader(Int_t)");
01132 fHeader = new TGHeaderFrame(fVport, 20, 20, kChildFrame | kFixedWidth);
01133
01134 SetDefaultHeaders();
01135 }
01136
01137
01138 TGListView::~TGListView()
01139 {
01140
01141
01142 if (fNColumns) {
01143 delete [] fColumns;
01144 delete [] fJmode;
01145 for (int i = 0; i < fNColumns; i++) {
01146 delete fColHeader[i];
01147 delete fSplitHeader[i];
01148 }
01149 delete [] fColHeader;
01150 delete [] fColNames;
01151 delete [] fSplitHeader;
01152 delete fHeader;
01153 }
01154 }
01155
01156
01157 void TGListView::ScrollHeader(Int_t pos)
01158 {
01159
01160
01161 Int_t i, xl = - pos;
01162 if (fViewMode == kLVDetails) {
01163 for (i = 0; i < fNColumns-1; ++i) {
01164 fColHeader[i]->Move(xl, 0);
01165 xl += fColHeader[i]->GetWidth();
01166 fSplitHeader[i]->Move(xl,fSplitHeader[i]->GetHeight());
01167 }
01168 fColHeader[i]->Move(xl, 0);
01169 xl += fColHeader[i]->GetWidth();
01170 fSplitHeader[i]->Move(xl,fSplitHeader[i]->GetHeight());
01171 }
01172 }
01173
01174
01175 void TGListView::SetHeaders(Int_t ncolumns)
01176 {
01177
01178
01179
01180
01181
01182 if (ncolumns <= 0) {
01183 Error("SetHeaders", "number of columns must be > 0");
01184 return;
01185 }
01186
01187 if (fNColumns) {
01188 delete [] fColumns;
01189 delete [] fJmode;
01190 for (int i = 0; i < fNColumns; i++) {
01191 if (fColHeader[i]) fColHeader[i]->DestroyWindow();
01192 delete fColHeader[i];
01193 delete fSplitHeader[i];
01194 }
01195 delete [] fColHeader;
01196 delete [] fSplitHeader;
01197 delete [] fColNames;
01198 }
01199
01200 fNColumns = ncolumns+1;
01201 fColumns = new int[fNColumns];
01202 fJmode = new int[fNColumns];
01203 fColHeader = new TGTextButton* [fNColumns];
01204 fColNames = new TString [fNColumns];
01205 fSplitHeader = new TGVFileSplitter* [fNColumns];
01206
01207 for (int i = 0; i < fNColumns; i++) {
01208 fColHeader[i] = 0;
01209 fJmode[i] = kTextLeft;
01210 fSplitHeader[i] = new TGVFileSplitter(fHeader, 10);
01211 fSplitHeader[i]->Connect("LayoutListView()", "TGListView",
01212 this, "Layout()");
01213 fSplitHeader[i]->Connect("LayoutHeader(TGFrame *)", "TGListView",
01214 this, "LayoutHeader(TGFrame *)");
01215 fSplitHeader[i]->Connect("DoubleClicked(TGVFileSplitter*)", "TGListView",
01216 this, "SetDefaultColumnWidth(TGVFileSplitter*)");
01217 }
01218
01219
01220 fColNames[fNColumns-1] = "";
01221 fColHeader[fNColumns-1] = new TGTextButton(fHeader, new TGHotString(""), -1,
01222 fNormGC, fFontStruct, kRaisedFrame |
01223 kDoubleBorder | kFixedWidth);
01224 fColHeader[fNColumns-1]->Associate(this);
01225 fColHeader[fNColumns-1]->SetTextJustify(kTextCenterX | kTextCenterY);
01226 fColHeader[fNColumns-1]->SetState(kButtonDisabled);
01227 fColHeader[fNColumns-1]->SetState(kButtonDisabled);
01228 fJmode[fNColumns-1] = kTextCenterX;
01229 fColumns[fNColumns-1] = 0;
01230 fSplitHeader[fNColumns-1]->SetFrame(fColHeader[fNColumns-1], kTRUE);
01231 fHeader->SetColumnsInfo(fNColumns, fColHeader, fSplitHeader);
01232 fJustChanged = kTRUE;
01233 }
01234
01235
01236 void TGListView::SetHeader(const char *s, Int_t hmode, Int_t cmode, Int_t idx)
01237 {
01238
01239
01240
01241
01242 if (idx < 0 || idx >= fNColumns-1) {
01243 Error("SetHeader", "header index must be [0 - %d>", fNColumns-1);
01244 return;
01245 }
01246 delete fColHeader[idx];
01247
01248 fColNames[idx] = s;
01249 fColHeader[idx] = new TGTextButton(fHeader, new TGHotString(s), idx,
01250 fNormGC, fFontStruct, kRaisedFrame |
01251 kDoubleBorder | kFixedWidth);
01252 TString txt = s;
01253 txt.ToLower();
01254 if (txt.Contains("modified")) txt += " date";
01255 if (txt.Contains("attributes")) txt = "type";
01256 fColHeader[idx]->SetToolTipText(Form("Click to sort by %s", txt.Data()));
01257 fColHeader[idx]->Associate(this);
01258 fColHeader[idx]->SetTextJustify(hmode | kTextCenterY);
01259 fSplitHeader[idx]->SetFrame(fColHeader[idx], kTRUE);
01260
01261
01262
01263 if (idx > 0)
01264 fJmode[idx-1] = cmode;
01265
01266 if (!fColHeader[0]) return;
01267 int xl = fColHeader[0]->GetDefaultWidth() + 10 + fSplitHeader[0]->GetDefaultWidth();
01268 for (int i = 1; i < fNColumns; i++) {
01269 fColumns[i-1] = xl;
01270 if (!fColHeader[i]) break;
01271 xl += fColHeader[i]->GetDefaultWidth() + fSplitHeader[i]->GetDefaultWidth();
01272 }
01273 }
01274
01275
01276 const char *TGListView::GetHeader(Int_t idx) const
01277 {
01278
01279
01280
01281 if (idx >= 0 && idx < fNColumns-1 && fColHeader[idx])
01282 return (const char*) fColNames[idx];
01283 return 0;
01284 }
01285
01286
01287 void TGListView::SetDefaultHeaders()
01288 {
01289
01290
01291
01292 SetHeaders(6);
01293 SetHeader("Name", kTextLeft, kTextLeft, 0);
01294 SetHeader("Attributes", kTextCenterX, kTextCenterX, 1);
01295 SetHeader("Size", kTextRight, kTextRight, 2);
01296 SetHeader("Owner", kTextCenterX, kTextCenterX, 3);
01297 SetHeader("Group", kTextCenterX, kTextCenterX, 4);
01298 SetHeader("Modified", kTextCenterX, kTextCenterX, 5);
01299 }
01300
01301
01302 void TGListView::SetViewMode(EListViewMode viewMode)
01303 {
01304
01305
01306 TGLVContainer *container;
01307
01308 if (fViewMode != viewMode) {
01309 fJustChanged = kTRUE;
01310 fViewMode = viewMode;
01311 container = (TGLVContainer *) fVport->GetContainer();
01312 if (container) container->SetViewMode(viewMode);
01313 Layout();
01314 }
01315 }
01316
01317
01318 void TGListView::SetContainer(TGFrame *f)
01319 {
01320
01321
01322
01323 if (f->InheritsFrom(TGLVContainer::Class())) {
01324 TGCanvas::SetContainer(f);
01325 ((TGLVContainer *) f)->SetColumns(fColumns, fJmode);
01326 ((TGLVContainer *) f)->SetListView(this);
01327 } else
01328 Error("SetContainer", "frame must inherit from TGLVContainer");
01329 }
01330
01331
01332 void TGListView::SetIncrements(Int_t hInc, Int_t vInc)
01333 {
01334
01335
01336 fHScrollbar->SetSmallIncrement(hInc);
01337 fVScrollbar->SetSmallIncrement(vInc);
01338 }
01339
01340
01341 void TGListView::SetDefaultColumnWidth(TGVFileSplitter* splitter)
01342 {
01343
01344
01345 TGLVContainer *container = (TGLVContainer *) fVport->GetContainer();
01346
01347 if (!container) {
01348 Error("SetDefaultColumnWidth", "no listview container set yet");
01349 return;
01350 }
01351 container->ClearViewPort();
01352
01353 for (int i = 0; i < fNColumns; ++i) {
01354 if ( fSplitHeader[i] == splitter ) {
01355 TString dt = fColHeader[i]->GetString();
01356 UInt_t bsize = gVirtualX->TextWidth(fColHeader[i]->GetFontStruct(),
01357 dt.Data(), dt.Length());
01358 UInt_t w = TMath::Max(fColHeader[i]->GetDefaultWidth(), bsize + 20);
01359 if (i == 0) w = TMath::Max(fMaxSize.fWidth + 10, w);
01360 if (i > 0) w = TMath::Max(container->GetMaxSubnameWidth(i) + 40, (Int_t)w);
01361 fColHeader[i]->Resize(w, fColHeader[i]->GetHeight());
01362 Layout();
01363 }
01364 }
01365 }
01366
01367
01368 void TGListView::ResizeColumns()
01369 {
01370
01371
01372 for (int i = 0; i < fNColumns; ++i) {
01373 TGLVContainer *container = (TGLVContainer *) fVport->GetContainer();
01374 if (!container) {
01375 Error("ResizeColumns", "no listview container set yet");
01376 return;
01377 }
01378 fMaxSize = container->GetMaxItemSize();
01379 SetDefaultColumnWidth(fSplitHeader[i]);
01380 }
01381 }
01382
01383
01384 void TGListView::Layout()
01385 {
01386
01387
01388 Int_t i, xl = 0;
01389 UInt_t w, h = 0;
01390
01391 TGLVContainer *container = (TGLVContainer *) fVport->GetContainer();
01392
01393 if (!container) {
01394 Error("Layout", "no listview container set yet");
01395 return;
01396 }
01397
01398 fMaxSize = container->GetMaxItemSize();
01399
01400 if (fViewMode == kLVDetails) {
01401 h = fColHeader[0]->GetDefaultHeight()-4;
01402 fHeader->MoveResize(0, 0, fWidth, h);
01403 fHeader->MapWindow();
01404 for (i = 0; i < fNColumns-1; ++i) {
01405 fColHeader[i]->SetText(fColNames[i]);
01406
01407 if ( fJustChanged ) {
01408 w = TMath::Min(fMaxSize.fWidth + 10, fColHeader[i]->GetDefaultWidth());
01409 if (w < fMinColumnSize) w = fColHeader[i]->GetDefaultWidth();
01410 if (i == 0) w = TMath::Max(fMaxSize.fWidth + 10, w);
01411 if (i > 0) w = TMath::Max(container->GetMaxSubnameWidth(i) + 40, (Int_t)w);
01412 } else {
01413 w = fColHeader[i]->GetWidth();
01414 }
01415 w = TMath::Max(fMinColumnSize, w);
01416 if ( fColHeader[i]->GetDefaultWidth() > w ) {
01417 for (int j = fColNames[i].Length() - 1 ; j > 0; j--) {
01418 fColHeader[i]->SetText( fColNames[i](0,j) + "..." );
01419 if ( fColHeader[i]->GetDefaultWidth() < w )
01420 break;
01421 }
01422 }
01423
01424 fColHeader[i]->MoveResize(xl, 0, w, h);
01425 fColHeader[i]->MapWindow();
01426 xl += w;
01427 fSplitHeader[i]->Move(xl, 0);
01428 fSplitHeader[i]->MapWindow();
01429 fColumns[i] = xl-2;
01430 }
01431 fColHeader[i]->MoveResize(xl, 0, fVport->GetWidth()-xl, h);
01432 fColHeader[i]->MapWindow();
01433 fSplitHeader[i]->Move(fVport->GetWidth(), fSplitHeader[i]->GetHeight());
01434 fSplitHeader[i]->MapWindow();
01435 fVScrollbar->RaiseWindow();
01436
01437 container->SetColumns(fColumns, fJmode);
01438
01439 } else {
01440 for (i = 0; i < fNColumns; ++i) {
01441 fColHeader[i]->UnmapWindow();
01442 fSplitHeader[i]->UnmapWindow();
01443 }
01444 fHeader->UnmapWindow();
01445 }
01446 TGLayoutManager *lm = container->GetLayoutManager();
01447
01448 lm->SetDefaultWidth(xl);
01449 TGCanvas::Layout();
01450
01451 if (fViewMode == kLVDetails) {
01452 container->Resize(container->GetWidth(), container->GetHeight()+h);
01453 fVScrollbar->SetRange((Int_t)container->GetHeight(),
01454 (Int_t)fVport->GetHeight());
01455 if (fJustChanged) {
01456 fVport->MoveResize(fBorderWidth, fBorderWidth, fVport->GetWidth(),
01457 fVport->GetHeight());
01458 container->Move(0, h);
01459 } else {
01460 container->DrawRegion(0, 0, fVport->GetWidth(), fVport->GetHeight());
01461 }
01462 fColHeader[i]->MoveResize(xl, 0, fVport->GetWidth()-xl, h);
01463 fColHeader[i]->MapWindow();
01464 } else {
01465 fVport->MoveResize(fBorderWidth, fBorderWidth, fVport->GetWidth(),
01466 fVport->GetHeight());
01467 container->Move(0, 0);
01468 }
01469
01470 fJustChanged = kFALSE;
01471 }
01472
01473
01474 void TGListView::LayoutHeader(TGFrame *head)
01475 {
01476
01477
01478 Int_t i, xl = 0;
01479 UInt_t w, h = 0;
01480 static Int_t oldPos = 0;
01481 if (head == 0) oldPos = 0;
01482
01483 TGLVContainer *container = (TGLVContainer *) fVport->GetContainer();
01484
01485 if (!container) {
01486 Error("Layout", "no listview container set yet");
01487 return;
01488 }
01489 fMaxSize = container->GetMaxItemSize();
01490 Int_t posx = container->GetPagePosition().fX;
01491
01492 if (fViewMode == kLVDetails) {
01493 h = fColHeader[0]->GetDefaultHeight()-4;
01494 fHeader->MoveResize(0, 0, fWidth, h);
01495 fHeader->MapWindow();
01496 for (i = 0; i < fNColumns-1; ++i) {
01497 fColHeader[i]->SetText(fColNames[i]);
01498
01499 if ( fJustChanged ) {
01500 w = TMath::Min(fMaxSize.fWidth + 10, fColHeader[i]->GetDefaultWidth());
01501 if (w < fMinColumnSize) w = fColHeader[i]->GetDefaultWidth();
01502 if (i == 0) w = TMath::Max(fMaxSize.fWidth + 10, w);
01503 if (i > 0) w = TMath::Max(container->GetMaxSubnameWidth(i) + 40, (Int_t)w);
01504 } else {
01505 w = fColHeader[i]->GetWidth();
01506 }
01507 w = TMath::Max(fMinColumnSize, w);
01508 if ( fColHeader[i]->GetDefaultWidth() > w ) {
01509 for (int j = fColNames[i].Length() - 1 ; j > 0; j--) {
01510 fColHeader[i]->SetText( fColNames[i](0,j) + "..." );
01511 if ( fColHeader[i]->GetDefaultWidth() < w )
01512 break;
01513 }
01514 }
01515
01516 if ((TGFrame *)fColHeader[i] == head) {
01517 if (oldPos > 0) {
01518 gVirtualX->DrawLine(container->GetId(), container->GetLineGC()(),
01519 oldPos - posx, 0, oldPos - posx, fVport->GetHeight());
01520 }
01521 gVirtualX->DrawLine(container->GetId(), container->GetLineGC()(),
01522 xl + w - posx, 0, xl + w - posx, fVport->GetHeight());
01523 oldPos = xl + w;
01524 }
01525
01526 fColHeader[i]->MoveResize(xl - posx, 0, w, h);
01527 fColHeader[i]->MapWindow();
01528 xl += w;
01529 fSplitHeader[i]->Move(xl, 0);
01530 fSplitHeader[i]->MapWindow();
01531 fColumns[i] = xl-2;
01532 }
01533 fColHeader[i]->MoveResize(xl - posx, 0, fVport->GetWidth()-xl, h);
01534 fColHeader[i]->MapWindow();
01535 fSplitHeader[i]->Move(fVport->GetWidth(), fSplitHeader[i]->GetHeight());
01536 fSplitHeader[i]->MapWindow();
01537 fVScrollbar->RaiseWindow();
01538 }
01539 fJustChanged = kFALSE;
01540 }
01541
01542
01543 Bool_t TGListView::ProcessMessage(Long_t msg, Long_t parm1, Long_t parm2)
01544 {
01545
01546
01547 TGLVContainer *cnt = (TGLVContainer*)GetContainer();
01548
01549 const TGLVEntry *entry;
01550 void *p = 0;
01551
01552 entry = (TGLVEntry *) cnt->GetNextSelected(&p);
01553
01554 switch (GET_SUBMSG(msg)) {
01555 case kCT_ITEMCLICK:
01556 if ((cnt->NumSelected() == 1) && (entry != 0)) {
01557 Int_t x = (Int_t)(parm2 & 0xffff);
01558 Int_t y = (Int_t)((parm2 >> 16) & 0xffff);
01559 Clicked((TGLVEntry*)entry, (Int_t)parm1);
01560 Clicked((TGLVEntry*)entry, (Int_t)parm1, x, y);
01561 }
01562 break;
01563 case kCT_ITEMDBLCLICK:
01564 if ((cnt->NumSelected() == 1) && (entry!=0)) {
01565 Int_t x = (Int_t)(parm2 & 0xffff);
01566 Int_t y = (Int_t)((parm2 >> 16) & 0xffff);
01567 DoubleClicked((TGLVEntry*)entry, (Int_t)parm1);
01568 DoubleClicked((TGLVEntry*)entry, (Int_t)parm1, x, y);
01569 }
01570 break;
01571 case kCT_SELCHANGED:
01572 SelectionChanged();
01573 break;
01574 default:
01575 break;
01576 }
01577 return TGCanvas::ProcessMessage(msg, parm1, parm2);
01578 }
01579
01580
01581 void TGListView::Clicked(TGLVEntry *entry, Int_t btn)
01582 {
01583
01584
01585 Long_t args[2];
01586
01587 args[0] = (Long_t)entry;
01588 args[1] = btn;
01589
01590 Emit("Clicked(TGLVEntry*,Int_t)", args);
01591 }
01592
01593
01594 void TGListView::Clicked(TGLVEntry *entry, Int_t btn, Int_t x, Int_t y)
01595 {
01596
01597
01598 Long_t args[4];
01599
01600 args[0] = (Long_t)entry;
01601 args[1] = btn;
01602 args[2] = x;
01603 args[3] = y;
01604
01605 Emit("Clicked(TGLVEntry*,Int_t,Int_t,Int_t)", args);
01606 }
01607
01608
01609 void TGListView::DoubleClicked(TGLVEntry *entry, Int_t btn)
01610 {
01611
01612
01613 Long_t args[2];
01614
01615 args[0] = (Long_t)entry;
01616 args[1] = btn;
01617
01618 Emit("DoubleClicked(TGLVEntry*,Int_t)", args);
01619 }
01620
01621
01622 void TGListView::DoubleClicked(TGLVEntry *entry, Int_t btn, Int_t x, Int_t y)
01623 {
01624
01625
01626 Long_t args[4];
01627
01628 args[0] = (Long_t)entry;
01629 args[1] = btn;
01630 args[2] = x;
01631 args[3] = y;
01632
01633 Emit("DoubleClicked(TGLVEntry*,Int_t,Int_t,Int_t)", args);
01634 }
01635
01636
01637 FontStruct_t TGListView::GetDefaultFontStruct()
01638 {
01639
01640
01641 if (!fgDefaultFont)
01642 fgDefaultFont = gClient->GetResourcePool()->GetIconFont();
01643 return fgDefaultFont->GetFontStruct();
01644 }
01645
01646
01647 const TGGC &TGListView::GetDefaultGC()
01648 {
01649
01650
01651 if (!fgDefaultGC) {
01652 fgDefaultGC = new TGGC(*gClient->GetResourcePool()->GetFrameGC());
01653 fgDefaultGC->SetFont(fgDefaultFont->GetFontHandle());
01654 }
01655 return *fgDefaultGC;
01656 }
01657
01658
01659 void TGListView::SavePrimitive(ostream &out, Option_t *option )
01660 {
01661
01662
01663 if (fBackground != GetDefaultFrameBackground()) SaveUserColor(out, option);
01664
01665 out << endl << " // list view" << endl;
01666 out <<" TGListView *";
01667 out << GetName() << " = new TGListView(" << fParent->GetName()
01668 << "," << GetWidth() << "," << GetHeight();
01669
01670 if (fBackground == GetDefaultFrameBackground()) {
01671 if (GetOptions() == (kSunkenFrame | kDoubleBorder)) {
01672 out <<");" << endl;
01673 } else {
01674 out << "," << GetOptionString() <<");" << endl;
01675 }
01676 } else {
01677 out << "," << GetOptionString() << ",ucolor);" << endl;
01678 }
01679 if (option && strstr(option, "keep_names"))
01680 out << " " << GetName() << "->SetName(\"" << GetName() << "\");" << endl;
01681
01682 GetContainer()->SavePrimitive(out, option);
01683
01684 out << endl;
01685 out << " " << GetName() << "->SetContainer(" << GetContainer()->GetName()
01686 << ");" << endl;
01687 out << " " << GetName() << "->SetViewMode(";
01688 switch (fViewMode) {
01689 case kLVLargeIcons:
01690 out << "kLVLargeIcons";
01691 break;
01692 case kLVSmallIcons:
01693 out << "kLVSmallIcons";
01694 break;
01695 case kLVList:
01696 out << "kLVList";
01697 break;
01698 case kLVDetails:
01699 out << "kLVDetails";
01700 break;
01701 }
01702 out << ");" << endl;
01703
01704 out << " " << GetContainer()->GetName() << "->Resize();" << endl;
01705
01706 if (fHScrollbar && fHScrollbar->IsMapped()) {
01707 out << " " << GetName() << "->SetHsbPosition(" << GetHsbPosition()
01708 << ");" << endl;
01709 }
01710
01711 if (fVScrollbar && fVScrollbar->IsMapped()) {
01712 out << " " << GetName() << "->SetVsbPosition(" << GetVsbPosition()
01713 << ");" << endl;
01714 }
01715 }
01716
01717
01718 void TGLVContainer::SavePrimitive(ostream &out, Option_t *option )
01719 {
01720
01721
01722 if (fBackground != GetDefaultFrameBackground()) SaveUserColor(out, option);
01723
01724 out << endl << " // list view container" << endl;
01725 out << " TGLVContainer *";
01726
01727 if ((fParent->GetParent())->InheritsFrom(TGCanvas::Class())) {
01728 out << GetName() << " = new TGLVContainer(" << GetCanvas()->GetName();
01729 } else {
01730 out << GetName() << " = new TGLVContainer(" << fParent->GetName();
01731 out << "," << GetWidth() << "," << GetHeight();
01732 }
01733 if (fBackground == GetDefaultFrameBackground()) {
01734 if (GetOptions() == (kSunkenFrame | kDoubleBorder)) {
01735 out <<");" << endl;
01736 } else {
01737 out << "," << GetOptionString() <<");" << endl;
01738 }
01739 } else {
01740 out << "," << GetOptionString() << ",ucolor);" << endl;
01741 }
01742 if (option && strstr(option, "keep_names"))
01743 out << " " << GetName() << "->SetName(\"" << GetName() << "\");" << endl;
01744 }