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 #include "TGTextView.h"
00036 #include "TGScrollBar.h"
00037 #include "TGResourcePool.h"
00038 #include "TSystem.h"
00039 #include "TGDNDManager.h"
00040 #include "TBufferFile.h"
00041 #include "TSystemFile.h"
00042 #include "TObjString.h"
00043 #include "TMacro.h"
00044 #include "TGMsgBox.h"
00045 #include "TUrl.h"
00046 #include "Riostream.h"
00047
00048
00049 const TGFont *TGTextView::fgDefaultFont = 0;
00050 TGGC *TGTextView::fgDefaultGC = 0;
00051 TGGC *TGTextView::fgDefaultSelectedGC = 0;
00052 const TGGC *TGTextView::fgDefaultSelectedBackgroundGC = 0;
00053
00054
00055
00056 Bool_t TViewTimer::Notify()
00057 {
00058
00059
00060 fView->HandleTimer(this);
00061 Reset();
00062 return kFALSE;
00063 }
00064
00065 ClassImp(TGTextView)
00066
00067
00068
00069 void TGTextView::Init(ULong_t back)
00070 {
00071
00072
00073
00074 fFont = GetDefaultFontStruct();
00075 fNormGC = GetDefaultGC();
00076 fSelGC = GetDefaultSelectedGC();
00077 fSelbackGC = GetDefaultSelectedBackgroundGC();
00078
00079 fWhiteGC = *fClient->GetResourcePool()->GetDocumentBckgndGC();
00080 fWhiteGC.SetGraphicsExposures(kTRUE);
00081 fWhiteGC.SetBackground(back);
00082 fWhiteGC.SetForeground(back);
00083
00084 fMarkedFromX = 0;
00085 fMarkedFromY = 0;
00086 fReadOnly = kFALSE;
00087 fIsMarked = kFALSE;
00088
00089 fText = new TGText();
00090 TGView::Clear();
00091
00092 fClipText = new TGText();
00093
00094 gVirtualX->GetFontProperties(fFont, fMaxAscent, fMaxDescent);
00095 fScrollVal.fY = fMaxAscent + fMaxDescent;
00096 fScrollVal.fX = fMaxWidth = gVirtualX->TextWidth(fFont, "@", 1);
00097
00098 fScrollTimer = new TViewTimer(this, 75);
00099 gSystem->AddTimer(fScrollTimer);
00100
00101
00102 fDNDTypeList = new Atom_t[3];
00103 fDNDTypeList[0] = gVirtualX->InternAtom("application/root", kFALSE);
00104 fDNDTypeList[1] = gVirtualX->InternAtom("text/uri-list", kFALSE);
00105 fDNDTypeList[2] = 0;
00106 gVirtualX->SetDNDAware(fId, fDNDTypeList);
00107 SetDNDTarget(kTRUE);
00108
00109 gVirtualX->ClearWindow(fCanvas->GetId());
00110 Layout();
00111 }
00112
00113
00114 TGTextView::TGTextView(const TGWindow *parent, UInt_t w, UInt_t h, Int_t id,
00115 UInt_t sboptions, ULong_t back) :
00116 TGView(parent, w, h, id, 3, 3, kSunkenFrame | kDoubleBorder, sboptions, back)
00117 {
00118
00119
00120 Init(back);
00121 }
00122
00123
00124 TGTextView::TGTextView(const TGWindow *parent, UInt_t w, UInt_t h, TGText *text,
00125 Int_t id, UInt_t sboptions, ULong_t back) :
00126 TGView(parent, w, h, id, 3, 3, kSunkenFrame | kDoubleBorder, sboptions, back)
00127 {
00128
00129
00130 Init(back);
00131 TGLongPosition pos, srcStart, srcEnd;
00132 pos.fX = pos.fY = 0;
00133 srcStart.fX = srcStart.fY = 0;
00134 srcEnd.fY = text->RowCount()-1;
00135 srcEnd.fX = text->GetLineLength(srcEnd.fY)-1;
00136 fText->InsText(pos, text, srcStart, srcEnd);
00137 }
00138
00139
00140 TGTextView::TGTextView(const TGWindow *parent, UInt_t w, UInt_t h,
00141 const char *string, Int_t id, UInt_t sboptions,
00142 ULong_t back) :
00143 TGView(parent, w, h, id, 3, 3, kSunkenFrame | kDoubleBorder, sboptions, back)
00144 {
00145
00146
00147 Init(back);
00148 TGLongPosition pos;
00149 pos.fX = pos.fY = 0;
00150 fText->InsText(pos, string);
00151 }
00152
00153
00154 TGTextView::~TGTextView()
00155 {
00156
00157
00158 delete fScrollTimer;
00159 delete fText;
00160 delete fClipText;
00161 delete [] fDNDTypeList;
00162 }
00163
00164
00165 void TGTextView::SetBackground(Pixel_t p)
00166 {
00167
00168
00169 fCanvas->SetBackgroundColor(p);
00170 fWhiteGC.SetBackground(p);
00171 fWhiteGC.SetForeground(p);
00172 }
00173
00174
00175 void TGTextView::SetSelectBack(Pixel_t p)
00176 {
00177
00178
00179 fSelbackGC.SetBackground(p);
00180 fSelbackGC.SetForeground(p);
00181 }
00182
00183
00184 void TGTextView::SetSelectFore(Pixel_t p)
00185 {
00186
00187
00188 fSelGC.SetBackground(p);
00189 fSelGC.SetForeground(p);
00190 }
00191
00192
00193 void TGTextView::SetText(TGText *text)
00194 {
00195
00196
00197 Clear();
00198 delete fText;
00199 fText = text;
00200 Layout();
00201 }
00202
00203
00204 void TGTextView::AddText(TGText *text)
00205 {
00206
00207
00208 UInt_t h1 = (UInt_t)ToScrYCoord(fText->RowCount());
00209
00210 fText->AddText(text);
00211 Layout();
00212
00213 UInt_t h2 = (UInt_t)ToScrYCoord(fText->RowCount());
00214
00215 if (h2 <= h1) {
00216 return;
00217 }
00218
00219 if (h2 < fCanvas->GetHeight()) {
00220 UpdateRegion(0, h1, fCanvas->GetWidth(), h2 - h1);
00221 }
00222 }
00223
00224
00225 void TGTextView::AddLine(const char *string)
00226 {
00227
00228
00229 UInt_t h1 = (UInt_t)ToScrYCoord(fText->RowCount());
00230
00231 AddLineFast(string);
00232 Layout();
00233
00234 UInt_t h2 = (UInt_t)ToScrYCoord(fText->RowCount());
00235
00236 if (h2 <= h1) {
00237 return;
00238 }
00239 if (h2 < fCanvas->GetHeight()) {
00240 UpdateRegion(0, h1, fCanvas->GetWidth(), h2 - h1);
00241 }
00242 }
00243
00244
00245 void TGTextView::AddLineFast(const char *string)
00246 {
00247
00248
00249
00250
00251 TGLongPosition pos;
00252 pos.fX = 0;
00253 pos.fY = fText->RowCount();
00254 fText->InsText(pos, string);
00255 }
00256
00257
00258 void TGTextView::Update()
00259 {
00260
00261
00262 Layout();
00263 fExposedRegion.Empty();
00264 UpdateRegion(0, 0, fCanvas->GetWidth(), fCanvas->GetHeight());
00265 }
00266
00267
00268 Long_t TGTextView::ReturnLongestLineWidth()
00269 {
00270
00271
00272 Long_t count = 0, longest = 0, width;
00273 Long_t rows = fText->RowCount();
00274 while (count < rows) {
00275 width = ToScrXCoord(fText->GetLineLength(count), count) + fVisible.fX;
00276 if (width > longest) {
00277 longest = width;
00278 }
00279 count++;
00280 }
00281 return longest;
00282 }
00283
00284
00285 Bool_t TGTextView::Search(const char *string, Bool_t direction, Bool_t caseSensitive)
00286 {
00287
00288
00289
00290 TGLongPosition pos, pos2;
00291 pos2.fX = pos2.fY = 0;
00292 if (fIsMarked) {
00293 if (!direction) {
00294 pos2.fX = fMarkedStart.fX;
00295 pos2.fY = fMarkedStart.fY;
00296 } else {
00297 pos2.fX = fMarkedEnd.fX + 1;
00298 pos2.fY = fMarkedEnd.fY;
00299 }
00300 }
00301 if (!fText->Search(&pos, pos2, string, direction, caseSensitive)) {
00302 return kFALSE;
00303 }
00304 UnMark();
00305 fIsMarked = kTRUE;
00306 fMarkedStart.fY = fMarkedEnd.fY = pos.fY;
00307 fMarkedStart.fX = pos.fX;
00308 fMarkedEnd.fX = fMarkedStart.fX + strlen(string) - 1;
00309 pos.fY = ToObjYCoord(fVisible.fY);
00310 if ((fMarkedStart.fY < pos.fY) ||
00311 (ToScrYCoord(fMarkedStart.fY) >= (Int_t)fCanvas->GetHeight())) {
00312 pos.fY = fMarkedStart.fY;
00313 }
00314 pos.fX = ToObjXCoord(fVisible.fX, pos.fY);
00315 if ((fMarkedStart.fX < pos.fX) ||
00316 (ToScrXCoord(fMarkedStart.fX, pos.fY) >= (Int_t)fCanvas->GetWidth())) {
00317 pos.fX = fMarkedStart.fX;
00318 }
00319
00320 SetVsbPosition((ToScrYCoord(pos.fY) + fVisible.fY)/fScrollVal.fY);
00321 SetHsbPosition((ToScrXCoord(pos.fX, pos.fY) + fVisible.fX)/fScrollVal.fX);
00322 UpdateRegion(0, (Int_t)ToScrYCoord(fMarkedStart.fY), fCanvas->GetWidth(),
00323 UInt_t(ToScrYCoord(fMarkedEnd.fY+1) - ToScrYCoord(fMarkedEnd.fY)));
00324
00325 return kTRUE;
00326 }
00327
00328
00329 void TGTextView::SetFont(FontStruct_t font)
00330 {
00331
00332
00333 if (font != fFont) {
00334 fFont = font;
00335 fNormGC.SetFont(gVirtualX->GetFontHandle(fFont));
00336 fSelGC.SetFont(gVirtualX->GetFontHandle(fFont));
00337 fClient->NeedRedraw(this);
00338 }
00339 }
00340
00341
00342 Long_t TGTextView::ToScrYCoord(Long_t yCoord)
00343 {
00344
00345
00346 if (yCoord * (fMaxAscent + fMaxDescent) <= 0) {
00347 return 0;
00348 }
00349 if (yCoord > fText->RowCount()) {
00350 return fText->RowCount() * (fMaxAscent + fMaxDescent);
00351 }
00352 return yCoord * (fMaxAscent + fMaxDescent) - fVisible.fY;
00353 }
00354
00355
00356 Long_t TGTextView::ToScrXCoord(Long_t xCoord, Long_t line)
00357 {
00358
00359
00360 TGLongPosition pos;
00361 char *buffer;
00362
00363 pos.fX = 0;
00364 pos.fY = line;
00365 Long_t width = fText->GetLineLength(line);
00366 if (xCoord <= 0 || pos.fY < 0 || width <= 0) {
00367 return 0;
00368 }
00369 if (xCoord > width) {
00370 xCoord = width;
00371 }
00372 buffer = fText->GetLine(pos, xCoord);
00373 width = gVirtualX->TextWidth(fFont, buffer, (Int_t)xCoord) - fVisible.fX;
00374 delete [] buffer;
00375
00376 return width;
00377 }
00378
00379
00380 Long_t TGTextView::ToObjYCoord(Long_t yCoord)
00381 {
00382
00383
00384 return yCoord / (fMaxAscent + fMaxDescent);
00385 }
00386
00387
00388 Long_t TGTextView::ToObjXCoord(Long_t xCoord, Long_t line)
00389 {
00390
00391
00392 TGLongPosition pos;
00393 char *buffer, *travelBuffer;
00394 char charBuffer;
00395
00396 if (line < 0 || line >= fText->RowCount()) {
00397 return 0;
00398 }
00399
00400 Long_t len = fText->GetLineLength(line);
00401 pos.fX = 0;
00402 pos.fY = line;
00403 if (len <= 0 || xCoord < 0) {
00404 return 0;
00405 }
00406
00407 Long_t viscoord = xCoord;
00408 buffer = fText->GetLine(pos, len);
00409 travelBuffer = buffer;
00410 charBuffer = *travelBuffer++;
00411 int cw = gVirtualX->TextWidth(fFont, &charBuffer, 1);
00412
00413 while (viscoord - cw >= 0 && pos.fX < len) {
00414 viscoord -= cw;
00415 pos.fX++;
00416 charBuffer = *travelBuffer++;
00417 cw = gVirtualX->TextWidth(fFont, &charBuffer, 1);
00418 }
00419
00420 delete [] buffer;
00421 return pos.fX;
00422 }
00423
00424
00425 void TGTextView::Clear(Option_t *)
00426 {
00427
00428
00429 TGView::Clear();
00430 fIsMarked = kFALSE;
00431 fIsSaved = kTRUE;
00432 fMarkedStart.fX = fMarkedStart.fY = 0;
00433 fMarkedEnd.fX = fMarkedEnd.fY = 0;
00434 fIsMarking = kFALSE;
00435
00436 delete fText;
00437 fText = new TGText();
00438 fText->Clear();
00439 SendMessage(fMsgWindow, MK_MSG(kC_TEXTVIEW, kTXT_ISMARKED), fWidgetId, kFALSE);
00440 Marked(kFALSE);
00441 gVirtualX->ClearWindow(fCanvas->GetId());
00442 SendMessage(fMsgWindow, MK_MSG(kC_TEXTVIEW, kTXT_DATACHANGE), fWidgetId, 0);
00443 DataChanged();
00444 Layout();
00445 }
00446
00447
00448 Bool_t TGTextView::LoadFile(const char *filename, Long_t startpos, Long_t length)
00449 {
00450
00451
00452
00453 FILE *fp;
00454 if (!(fp = fopen(filename, "r")))
00455 return kFALSE;
00456 fclose(fp);
00457
00458 Clear();
00459 fText->Load(filename, startpos, length);
00460 Update();
00461 return kTRUE;
00462 }
00463
00464
00465 Bool_t TGTextView::LoadBuffer(const char *txtbuf)
00466 {
00467
00468
00469 if (!txtbuf || !strlen(txtbuf)) {
00470 return kFALSE;
00471 }
00472
00473 Clear();
00474 fText->LoadBuffer(txtbuf);
00475 Update();
00476 return kTRUE;
00477 }
00478
00479
00480 Bool_t TGTextView::Copy()
00481 {
00482
00483
00484 TGLongPosition insPos, startPos, endPos;
00485
00486 if (!fIsMarked) {
00487 return kFALSE;
00488 }
00489 delete fClipText;
00490 fClipText = new TGText();
00491 insPos.fY = insPos.fX = 0;
00492 startPos.fX = fMarkedStart.fX;
00493 startPos.fY = fMarkedStart.fY;
00494 endPos.fX = fMarkedEnd.fX-1;
00495 endPos.fY = fMarkedEnd.fY;
00496 if (endPos.fX == -1) {
00497 if (endPos.fY > 0) {
00498 endPos.fY--;
00499 }
00500 endPos.fX = fText->GetLineLength(endPos.fY);
00501 if (endPos.fX < 0) {
00502 endPos.fX = 0;
00503 }
00504 }
00505 fClipText->InsText(insPos, fText, startPos, endPos);
00506 gVirtualX->SetPrimarySelectionOwner(fId);
00507 return kTRUE;
00508 }
00509
00510
00511 Bool_t TGTextView::SelectAll()
00512 {
00513
00514
00515 if (fText->RowCount() == 1 && fText->GetLineLength(0) == 0) {
00516 return kFALSE;
00517 }
00518 fIsMarked = kTRUE;
00519 fMarkedStart.fY = 0;
00520 fMarkedStart.fX = 0;
00521 fMarkedEnd.fY = fText->RowCount()-1;
00522 fMarkedEnd.fX = fText->GetLineLength(fMarkedEnd.fY);
00523 if (fMarkedEnd.fX < 0) {
00524 fMarkedEnd.fX = 0;
00525 }
00526 UpdateRegion(0, 0, fCanvas->GetWidth(), fCanvas->GetHeight());
00527 Copy();
00528
00529 return kTRUE;
00530 }
00531
00532
00533 void TGTextView::DrawRegion(Int_t x, Int_t y, UInt_t w, UInt_t h)
00534 {
00535
00536
00537 char *buffer;
00538
00539 TGLongPosition pos;
00540 Long_t xoffset, len, len1, len2;
00541 Long_t line_count = fText->RowCount();
00542 Rectangle_t rect;
00543 rect.fX = x;
00544 rect.fY = y;
00545 pos.fY = ToObjYCoord(fVisible.fY + h);
00546 rect.fHeight = UShort_t(h + ToScrYCoord(pos.fY + 1) - ToScrYCoord(pos.fY));
00547 pos.fX = ToObjXCoord(fVisible.fX + w, pos.fY);
00548 rect.fWidth = UShort_t(w + ToScrXCoord(pos.fX + 1, pos.fY) - ToScrXCoord(pos.fX, pos.fY));
00549 Int_t yloc = rect.fY + (Int_t)fScrollVal.fY;
00550 pos.fY = ToObjYCoord(fVisible.fY + rect.fY);
00551
00552 while (pos.fY <= line_count &&
00553 yloc - fScrollVal.fY <= (Int_t)fCanvas->GetHeight() &&
00554 yloc <= rect.fY + rect.fHeight) {
00555
00556 pos.fX = ToObjXCoord(fVisible.fX + rect.fX, pos.fY);
00557 xoffset = ToScrXCoord(pos.fX, pos.fY);
00558 len = fText->GetLineLength(pos.fY) - pos.fX;
00559
00560 gVirtualX->ClearArea(fCanvas->GetId(), x, Int_t(ToScrYCoord(pos.fY)),
00561 rect.fWidth, UInt_t(ToScrYCoord(pos.fY+1)-ToScrYCoord(pos.fY)));
00562
00563
00564 if (len > 0) {
00565 if (len > ToObjXCoord(fVisible.fX + rect.fX + rect.fWidth, pos.fY) - pos.fX) {
00566 len = ToObjXCoord(fVisible.fX + rect.fX + rect.fWidth, pos.fY) - pos.fX + 1;
00567 }
00568 if (pos.fX == 0) {
00569 xoffset = -fVisible.fX;
00570 }
00571 if (pos.fY >= ToObjYCoord(fVisible.fY)) {
00572 buffer = fText->GetLine(pos, len);
00573 Int_t i = 0;
00574 while (buffer[i] != '\0') {
00575 if (buffer[i] == '\t') {
00576 buffer[i] = ' ';
00577 Int_t j = i+1;
00578 while (buffer[j] == 16 && buffer[j] != '\0') {
00579 buffer[j++] = ' ';
00580 }
00581 }
00582 i++;
00583 }
00584
00585 if (!fIsMarked ||
00586 pos.fY < fMarkedStart.fY || pos.fY > fMarkedEnd.fY ||
00587 (pos.fY == fMarkedStart.fY &&
00588 fMarkedStart.fX >= pos.fX+len &&
00589 fMarkedStart.fY != fMarkedEnd.fY) ||
00590 (pos.fY == fMarkedEnd.fY &&
00591 fMarkedEnd.fX < pos.fX &&
00592 fMarkedStart.fY != fMarkedEnd.fY) ||
00593 (fMarkedStart.fY == fMarkedEnd.fY &&
00594 (fMarkedEnd.fX < pos.fX ||
00595 fMarkedStart.fX > pos.fX+len))) {
00596
00597 gVirtualX->DrawString(fCanvas->GetId(), fNormGC(), Int_t(xoffset),
00598 Int_t(ToScrYCoord(pos.fY+1) - fMaxDescent),
00599 buffer, Int_t(len));
00600 } else {
00601 if (pos.fY > fMarkedStart.fY && pos.fY < fMarkedEnd.fY) {
00602 len1 = 0;
00603 len2 = len;
00604 } else {
00605 if (fMarkedStart.fY == fMarkedEnd.fY) {
00606 if (fMarkedStart.fX >= pos.fX &&
00607 fMarkedStart.fX <= pos.fX + len) {
00608 len1 = fMarkedStart.fX - pos.fX;
00609 } else {
00610 len1 = 0;
00611 }
00612 if (fMarkedEnd.fX >= pos.fX &&
00613 fMarkedEnd.fX <= pos.fX + len) {
00614 len2 = fMarkedEnd.fX - pos.fX - len1;
00615 } else {
00616 len2 = len - len1;
00617 }
00618 } else {
00619 if (pos.fY == fMarkedStart.fY) {
00620 if (fMarkedStart.fX < pos.fX) {
00621 len1 = 0;
00622 len2 = len;
00623 } else {
00624 len1 = fMarkedStart.fX - pos.fX;
00625 len2 = len - len1;
00626 }
00627 } else {
00628 if (fMarkedEnd.fX > pos.fX+len) {
00629 len1 = 0;
00630 len2 = len;
00631 } else {
00632 len1 = 0 ;
00633 len2 = fMarkedEnd.fX - pos.fX;
00634 }
00635 }
00636 }
00637 }
00638 gVirtualX->DrawString(fCanvas->GetId(), fNormGC(),
00639 Int_t(ToScrXCoord(pos.fX, pos.fY)),
00640 Int_t(ToScrYCoord(pos.fY+1) - fMaxDescent),
00641 buffer, Int_t(len1));
00642 gVirtualX->FillRectangle(fCanvas->GetId(), fSelbackGC(),
00643 Int_t(ToScrXCoord(pos.fX+len1, pos.fY)),
00644 Int_t(ToScrYCoord(pos.fY)),
00645 UInt_t(ToScrXCoord(pos.fX+len1+len2, pos.fY) -
00646 ToScrXCoord(pos.fX+len1, pos.fY)),
00647 UInt_t(ToScrYCoord(pos.fY+1)-ToScrYCoord(pos.fY)));
00648 gVirtualX->DrawString(fCanvas->GetId(), fSelGC(),
00649 Int_t(ToScrXCoord(pos.fX+len1, pos.fY)),
00650 Int_t(ToScrYCoord(pos.fY+1) - fMaxDescent),
00651 buffer+len1, Int_t(len2));
00652 gVirtualX->DrawString(fCanvas->GetId(), fNormGC(),
00653 Int_t(ToScrXCoord(pos.fX+len1+len2, pos.fY)),
00654 Int_t(ToScrYCoord(pos.fY+1) - fMaxDescent),
00655 buffer+len1+len2, Int_t(len-(len1+len2)));
00656 }
00657 delete [] buffer;
00658 }
00659 }
00660 pos.fY++;
00661 yloc += Int_t(ToScrYCoord(pos.fY) - ToScrYCoord(pos.fY-1));
00662 }
00663 }
00664
00665
00666 Bool_t TGTextView::HandleCrossing(Event_t *event)
00667 {
00668
00669
00670 if (event->fWindow != fCanvas->GetId())
00671 return kTRUE;
00672
00673 fMousePos.fY = ToObjYCoord(fVisible.fY + event->fY);
00674 if (ToScrYCoord(fMousePos.fY+1) >= (Int_t)fCanvas->GetHeight()) {
00675 fMousePos.fY--;
00676 }
00677 fMousePos.fX = ToObjXCoord(fVisible.fX + event->fX, fMousePos.fY);
00678 if (fMousePos.fX >= ReturnLineLength(fMousePos.fY)) {
00679 fMousePos.fX--;
00680 }
00681 if ((event->fState & kButton1Mask) && fIsMarked && fIsMarking) {
00682 if (event->fType == kLeaveNotify) {
00683 if (event->fX < 0) {
00684 fScrolling = 0;
00685 return kFALSE;
00686 }
00687 if (event->fX >= (Int_t)fCanvas->GetWidth()) {
00688 fScrolling = 1;
00689 return kFALSE;
00690 }
00691 if (event->fY < 0) {
00692 fScrolling = 2;
00693 return kFALSE;
00694 }
00695 if (event->fY >= (Int_t)fCanvas->GetHeight()) {
00696 fScrolling = 3;
00697 return kFALSE;
00698 }
00699 } else {
00700 fScrolling = -1;
00701 Mark(fMousePos.fX, fMousePos.fY);
00702 }
00703 } else {
00704 fIsMarking = kFALSE;
00705 }
00706
00707 return kTRUE;
00708 }
00709
00710
00711 Bool_t TGTextView::HandleTimer(TTimer *)
00712 {
00713
00714
00715 static const Int_t kAutoScrollFudge = 10;
00716 static const Int_t kAcceleration[kAutoScrollFudge + 1] = {1, 1, 1, 1, 2, 3, 4, 6, 8, 12, 16};
00717
00718 TGLongPosition size;
00719 Window_t dum1, dum2;
00720 Event_t ev;
00721 ev.fType = kButtonPress;
00722 Int_t x, y;
00723 Int_t dy = 0;
00724
00725 if (fMarkedStart.fY == fMarkedEnd.fY) {
00726 return kFALSE;
00727 }
00728 if (fIsMarked && (fScrolling != -1)) {
00729
00730 gVirtualX->QueryPointer(fId, dum1, dum2, ev.fXRoot, ev.fYRoot, x, y, ev.fState);
00731
00732 fMousePos.fY = ToObjYCoord(fVisible.fY + y);
00733
00734 if (fMousePos.fY >= ReturnLineCount()) {
00735 fMousePos.fY = ReturnLineCount() - 1;
00736 }
00737 if (fMousePos.fY < 0) {
00738 fMousePos.fY = 0;
00739 }
00740 if (ev.fState & kButton1Mask) {
00741
00742
00743 if (y < kAutoScrollFudge) {
00744 dy = kAutoScrollFudge - y;
00745 } else if ((Int_t)fCanvas->GetHeight() - kAutoScrollFudge <= y) {
00746 dy = fCanvas->GetHeight() - kAutoScrollFudge - y;
00747 }
00748 Int_t ady = TMath::Abs(dy) >> 3;
00749
00750 if (dy) {
00751 if (ady > kAutoScrollFudge) ady = kAutoScrollFudge;
00752 dy = kAcceleration[ady];
00753 } else {
00754 dy = 1;
00755 }
00756
00757 if (y > (Int_t)fCanvas->GetHeight()) {
00758 fScrolling = 3;
00759 }
00760 if (y < 0) {
00761 fScrolling = 2;
00762 }
00763 } else {
00764 fScrolling = -1;
00765 }
00766
00767 size.fY = ToObjYCoord(fVisible.fY + fCanvas->GetHeight()) - 1;
00768 size.fX = ToObjXCoord(fVisible.fX + fCanvas->GetWidth(), fMousePos.fY) - 1;
00769 switch (fScrolling) {
00770 case -1:
00771 break;
00772 case 0:
00773 if (fVisible.fX == 0) {
00774 fScrolling = -1;
00775 break;
00776 } else {
00777 SetHsbPosition(fVisible.fX / fScrollVal.fX - 1);
00778 Mark(ToObjXCoord(fVisible.fX, fMousePos.fY) - 1, fMousePos.fY);
00779 }
00780 break;
00781 case 1:
00782 if ((Int_t)fCanvas->GetWidth() >= ToScrXCoord(ReturnLineLength(fMousePos.fY), fMousePos.fY)) {
00783 fScrolling = -1;
00784 break;
00785 } else {
00786 SetHsbPosition(fVisible.fX / fScrollVal.fX + 1);
00787 Mark(size.fX+1, fMousePos.fY);
00788 }
00789 break;
00790 case 2:
00791 if (fVisible.fY == 0) {
00792 fScrolling = -1;
00793 break;
00794 } else {
00795 SetVsbPosition(fVisible.fY/fScrollVal.fY - dy);
00796 Mark(fMousePos.fX, fMarkedStart.fY - 1);
00797 }
00798 break;
00799 case 3:
00800 if ((Int_t)fCanvas->GetHeight() >= ToScrYCoord(ReturnLineCount())) {
00801 fScrolling = -1;
00802 break;
00803 } else {
00804 SetVsbPosition(fVisible.fY/fScrollVal.fY + dy);
00805 Mark(fMousePos.fX, size.fY + 1);
00806 }
00807 break;
00808 default:
00809 break;
00810 }
00811 }
00812 return kTRUE;
00813 }
00814
00815
00816 Bool_t TGTextView::HandleButton(Event_t *event)
00817 {
00818
00819
00820 if (event->fWindow != fCanvas->GetId()) {
00821 return kFALSE;
00822 }
00823
00824 if (event->fCode == kButton1) {
00825 if (event->fType == kButtonPress) {
00826 if (fIsMarked) {
00827 if (event->fState & kKeyShiftMask) {
00828 fIsMarking = kTRUE;
00829 HandleMotion(event);
00830 return kTRUE;
00831 }
00832
00833 UnMark();
00834 }
00835 fIsMarked = kTRUE;
00836 fIsMarking = kTRUE;
00837 fMousePos.fY = ToObjYCoord(fVisible.fY + event->fY);
00838 fMousePos.fX = ToObjXCoord(fVisible.fX + event->fX, fMousePos.fY);
00839 fMarkedStart.fX = fMarkedEnd.fX = fMousePos.fX;
00840 fMarkedStart.fY = fMarkedEnd.fY = fMousePos.fY;
00841 } else {
00842 fScrolling = -1;
00843 if ((fMarkedStart.fX == fMarkedEnd.fX) &&
00844 (fMarkedStart.fY == fMarkedEnd.fY)) {
00845 fIsMarked = kFALSE;
00846 SendMessage(fMsgWindow, MK_MSG(kC_TEXTVIEW, kTXT_ISMARKED),
00847 fWidgetId, kFALSE);
00848 Marked(kFALSE);
00849 } else {
00850 SendMessage(fMsgWindow, MK_MSG(kC_TEXTVIEW, kTXT_ISMARKED),
00851 fWidgetId, kTRUE);
00852 Marked(kTRUE);
00853 }
00854 fIsMarking = kFALSE;
00855 }
00856 } else if (event->fCode == kButton4) {
00857
00858 if (fVisible.fY > 0) {
00859 Long_t amount = fVisible.fY / fScrollVal.fY - 3;
00860 SetVsbPosition((amount >= 0) ? amount : 0);
00861
00862 }
00863 } else if (event->fCode == kButton5) {
00864
00865 if ((Int_t)fCanvas->GetHeight() < ToScrYCoord(ReturnLineCount())) {
00866 TGLongPosition size;
00867 size.fY = ToObjYCoord(fVisible.fY + fCanvas->GetHeight()) - 1;
00868 SetVsbPosition(fVisible.fY / fScrollVal.fY + 3);
00869
00870 }
00871 } else if (event->fType == kButtonPress) {
00872 if (event->fCode == kButton2) {
00873 SendMessage(fMsgWindow, MK_MSG(kC_TEXTVIEW, kTXT_CLICK2),
00874 fWidgetId, (event->fYRoot << 16) | event->fXRoot);
00875 UnMark();
00876 } else if (event->fCode == kButton3) {
00877 SendMessage(fMsgWindow, MK_MSG(kC_TEXTVIEW, kTXT_CLICK3),
00878 fWidgetId, (event->fYRoot << 16) | event->fXRoot);
00879 }
00880 }
00881
00882 if (event->fType == kButtonRelease) {
00883 if (event->fCode == kButton1) {
00884 if (fIsMarked) {
00885 Copy();
00886 }
00887 }
00888 }
00889
00890 return kTRUE;
00891 }
00892
00893
00894 Bool_t TGTextView::HandleDoubleClick(Event_t *event)
00895 {
00896
00897
00898 if (event->fWindow != fCanvas->GetId()) {
00899 return kFALSE;
00900 }
00901 return kFALSE;
00902 }
00903
00904
00905 Bool_t TGTextView::HandleMotion(Event_t *event)
00906 {
00907
00908
00909 if ((ToObjYCoord(fVisible.fY+event->fY) == fMousePos.fY) &&
00910 (ToObjXCoord(fVisible.fX+event->fX, ToObjYCoord(fVisible.fY + event->fY)) == fMousePos.fX)) {
00911 return kTRUE;
00912 }
00913
00914 if (fScrolling != -1) {
00915 return kTRUE;
00916 }
00917
00918 fMousePos.fY = ToObjYCoord(fVisible.fY + event->fY);
00919 if (fMousePos.fY >= ReturnLineCount()) {
00920 fMousePos.fY = ReturnLineCount()-1;
00921 }
00922 fMousePos.fX = ToObjXCoord(fVisible.fX + event->fX, fMousePos.fY);
00923
00924 if (fMousePos.fX > ReturnLineLength(fMousePos.fY)) {
00925 fMousePos.fX = ReturnLineLength(fMousePos.fY);
00926 }
00927 if (event->fWindow != fCanvas->GetId()) {
00928 return kTRUE;
00929 }
00930
00931 if (!fIsMarking) {
00932 return kTRUE;
00933 }
00934 if (event->fX < 0) {
00935 return kTRUE;
00936 }
00937 if (event->fX >= (Int_t)fCanvas->GetWidth()) {
00938 return kTRUE;
00939 }
00940 if (event->fY < 0) {
00941 return kTRUE;
00942 }
00943 if (event->fY >= (Int_t)fCanvas->GetHeight()) {
00944 return kTRUE;
00945 }
00946 Mark(fMousePos.fX, fMousePos.fY);
00947 return kTRUE;
00948 }
00949
00950
00951 Bool_t TGTextView::HandleSelectionClear(Event_t * )
00952 {
00953
00954
00955 if (fIsMarked) {
00956 UnMark();
00957 }
00958 return kTRUE;
00959 }
00960
00961
00962 Bool_t TGTextView::HandleSelectionRequest(Event_t *event)
00963 {
00964
00965
00966 Event_t reply;
00967 char *buffer, *temp_buffer;
00968 Long_t len, prev_len, temp_len, count;
00969 TGLongPosition pos;
00970 Atom_t targets[2];
00971 Atom_t type;
00972
00973 reply.fType = kSelectionNotify;
00974 reply.fTime = event->fTime;
00975 reply.fUser[0] = event->fUser[0];
00976 reply.fUser[1] = event->fUser[1];
00977 reply.fUser[2] = event->fUser[2];
00978 reply.fUser[3] = event->fUser[3];
00979
00980 targets[0] = gVirtualX->InternAtom("TARGETS", kFALSE);
00981 targets[1] = gVirtualX->InternAtom("XA_STRING", kFALSE);
00982
00983 if ((Atom_t)event->fUser[2] == targets[0]) {
00984 type = gVirtualX->InternAtom("XA_ATOM", kFALSE);
00985 gVirtualX->ChangeProperty((Window_t) event->fUser[0], (Atom_t) event->fUser[3],
00986 type, (UChar_t*) targets, (Int_t) 2);
00987
00988 gVirtualX->SendEvent((Window_t)event->fUser[0], &reply);
00989 return kTRUE;
00990 }
00991
00992 len = 0;
00993 for (count = 0; count < fClipText->RowCount(); count++) {
00994 len += fClipText->GetLineLength(count)+1;
00995 }
00996 len--;
00997
00998 pos.fY = pos.fX = 0;
00999 buffer = new char[len+1];
01000 prev_len = temp_len = 0;
01001 for (pos.fY = 0; pos.fY < fClipText->RowCount(); pos.fY++) {
01002 temp_len = fClipText->GetLineLength(pos.fY);
01003 if (temp_len < 0) break;
01004 temp_buffer = fClipText->GetLine(pos, temp_len);
01005 strncpy(buffer+prev_len, temp_buffer, (UInt_t)temp_len);
01006 if (pos.fY < fClipText->RowCount()-1) {
01007 buffer[prev_len+temp_len] = 10;
01008 prev_len += temp_len+1;
01009 } else
01010 prev_len += temp_len;
01011 delete [] temp_buffer;
01012 }
01013 buffer[len] = '\0';
01014
01015
01016 ULong_t i = 0;
01017 while (buffer[i]) {
01018 if (buffer[i] == '\t') {
01019 ULong_t j = i + 1;
01020 while (buffer[j] == 16 && buffer[j]) {
01021 j++;
01022 }
01023 strcpy(buffer+i+1, buffer+j);
01024 len -= j - i - 1;
01025 }
01026 i++;
01027 }
01028
01029 gVirtualX->ChangeProperty((Window_t) event->fUser[0], (Atom_t) event->fUser[3],
01030 (Atom_t) event->fUser[2], (UChar_t*) buffer,
01031 (Int_t) len);
01032
01033 delete [] buffer;
01034
01035 gVirtualX->SendEvent((Window_t)event->fUser[0], &reply);
01036
01037 return kTRUE;
01038 }
01039
01040
01041 static Bool_t IsTextFile(const char *candidate)
01042 {
01043
01044
01045
01046
01047
01048 Int_t i;
01049 Int_t nchars;
01050 Int_t weirdcount = 0;
01051 char buffer[512];
01052 FILE *infile;
01053 FileStat_t buf;
01054
01055 gSystem->GetPathInfo(candidate, buf);
01056 if (!(buf.fMode & kS_IFREG))
01057 return kFALSE;
01058
01059 infile = fopen(candidate, "r");
01060 if (infile) {
01061
01062 nchars = fread(buffer, 1, 512, infile);
01063 fclose (infile);
01064
01065 for (i = 0; i < nchars; i++) {
01066 if (buffer[i] & 128)
01067 weirdcount++;
01068 if (buffer[i] == '\0')
01069
01070 return kFALSE;
01071 }
01072 if ((nchars > 0) && ((weirdcount * 100 / nchars) > 30))
01073 return kFALSE;
01074 } else {
01075
01076 return kFALSE;
01077 }
01078 return kTRUE;
01079 }
01080
01081
01082 Bool_t TGTextView::HandleDNDDrop(TDNDData *data)
01083 {
01084
01085
01086 static Atom_t rootObj = gVirtualX->InternAtom("application/root", kFALSE);
01087 static Atom_t uriObj = gVirtualX->InternAtom("text/uri-list", kFALSE);
01088
01089 if (fText->RowCount() > 1) {
01090 Int_t ret;
01091 new TGMsgBox(fClient->GetRoot(), GetMainFrame(),
01092 "Overvrite", "Do you want to replace existing text?",
01093 kMBIconExclamation, kMBYes | kMBNo, &ret);
01094 if (ret == kMBNo)
01095 return kTRUE;
01096 }
01097 if (data->fDataType == rootObj) {
01098 TBufferFile buf(TBuffer::kRead, data->fDataLength, (void *)data->fData);
01099 buf.SetReadMode();
01100 TObject *obj = (TObject *)buf.ReadObjectAny(TObject::Class());
01101 if (obj->InheritsFrom("TMacro")) {
01102 TMacro *macro = (TMacro *)obj;
01103 TIter next(macro->GetListOfLines());
01104 TObjString *objs;
01105 while ((objs = (TObjString*) next())) {
01106 AddLine(objs->GetName());
01107 }
01108 }
01109 else if (obj->InheritsFrom("TSystemFile")) {
01110 TSystemFile *sfile = (TSystemFile *)obj;
01111 LoadFile(sfile->GetName());
01112 DataDropped(sfile->GetName());
01113 }
01114 return kTRUE;
01115 }
01116 else if (data->fDataType == uriObj) {
01117 TString sfname((char *)data->fData);
01118 if (sfname.Length() > 7) {
01119 sfname.ReplaceAll("\r\n", "");
01120 TUrl uri(sfname.Data());
01121 if (IsTextFile(uri.GetFile())) {
01122 LoadFile(uri.GetFile());
01123 DataDropped(uri.GetFile());
01124 }
01125 }
01126 }
01127 return kFALSE;
01128 }
01129
01130
01131 Atom_t TGTextView::HandleDNDPosition(Int_t , Int_t , Atom_t action,
01132 Int_t , Int_t )
01133 {
01134
01135
01136 return action;
01137 }
01138
01139
01140 Atom_t TGTextView::HandleDNDEnter(Atom_t *typelist)
01141 {
01142
01143
01144 static Atom_t rootObj = gVirtualX->InternAtom("application/root", kFALSE);
01145 static Atom_t uriObj = gVirtualX->InternAtom("text/uri-list", kFALSE);
01146 Atom_t ret = kNone;
01147 for (int i = 0; typelist[i] != kNone; ++i) {
01148 if (typelist[i] == rootObj)
01149 ret = rootObj;
01150 if (typelist[i] == uriObj)
01151 ret = uriObj;
01152 }
01153 return ret;
01154 }
01155
01156
01157 Bool_t TGTextView::HandleDNDLeave()
01158 {
01159
01160
01161 return kTRUE;
01162 }
01163
01164
01165 void TGTextView::Mark(Long_t xPos, Long_t yPos)
01166 {
01167
01168
01169 TGLongPosition posStart, posEnd, pos;
01170
01171 pos.fY = yPos;
01172 pos.fX = xPos;
01173 if (pos.fY > fText->RowCount()-1) {
01174 pos.fY = fText->RowCount()-1;
01175 }
01176 if (pos.fX > fText->GetLineLength(pos.fY)) {
01177 pos.fX = fText->GetLineLength(pos.fY);
01178 }
01179 if (pos.fY < fMarkedStart.fY) {
01180 posEnd.fY = fMarkedStart.fY;
01181 if (fMarkedFromY == 1 || fMarkedFromX == 1) {
01182 posEnd.fY = fMarkedEnd.fY;
01183 fMarkedEnd.fX = fMarkedStart.fX;
01184 fMarkedEnd.fY = fMarkedStart.fY;
01185 }
01186 posStart.fY = pos.fY;
01187 fMarkedStart.fY = pos.fY;
01188 fMarkedStart.fX = pos.fX;
01189 fMarkedFromY = 0;
01190 fMarkedFromX = 0;
01191 } else if (pos.fY > fMarkedEnd.fY) {
01192 posStart.fY = fMarkedEnd.fY;
01193 if (fMarkedFromY == 0 || fMarkedFromX == 0) {
01194 if (fMarkedStart.fY != fMarkedEnd.fY) {
01195 posStart.fY = fMarkedStart.fY;
01196 fMarkedStart.fX = fMarkedEnd.fX;
01197 fMarkedStart.fY = fMarkedEnd.fY;
01198 }
01199 }
01200 fMarkedEnd.fY = pos.fY;
01201 fMarkedEnd.fX = pos.fX;
01202 fMarkedFromY = 1;
01203 fMarkedFromX = 1;
01204
01205 posEnd.fY = fMarkedEnd.fY;
01206 } else {
01207 if (pos.fX <= fMarkedStart.fX && pos.fY == fMarkedStart.fY) {
01208 posEnd.fY = fMarkedStart.fY;
01209 if (fMarkedFromY == 1 || fMarkedFromX == 1) {
01210 posEnd.fY = fMarkedEnd.fY;
01211 fMarkedEnd.fX = fMarkedStart.fX;
01212 fMarkedEnd.fY = fMarkedStart.fY;
01213 }
01214 fMarkedStart.fX = pos.fX;
01215 fMarkedFromY = 0;
01216 fMarkedFromX = 0;
01217 posStart.fY = fMarkedStart.fY;
01218 } else {
01219 if (pos.fX > fMarkedEnd.fX && pos.fY == fMarkedEnd.fY) {
01220 posStart.fY = fMarkedEnd.fY;
01221 if (fMarkedFromY == 0 || fMarkedFromX == 0) {
01222 posStart.fY = fMarkedStart.fY;
01223 fMarkedStart.fX = fMarkedEnd.fX;
01224 fMarkedStart.fY = fMarkedEnd.fY;
01225 }
01226 fMarkedEnd.fX = pos.fX;
01227 fMarkedFromY = 1;
01228 fMarkedFromX = 1;
01229 posEnd.fY = fMarkedEnd.fY;
01230 } else {
01231 if (fMarkedFromY == 0 || fMarkedFromX == 0) {
01232 posStart.fY = fMarkedStart.fY;
01233 fMarkedStart.fY = pos.fY;
01234 fMarkedStart.fX = pos.fX;
01235 posEnd.fY = fMarkedStart.fY;
01236 fMarkedFromX = 0;
01237 if (fMarkedStart.fY == fMarkedEnd.fY &&
01238 fMarkedStart.fX > fMarkedEnd.fX) {
01239 fMarkedStart.fX = fMarkedEnd.fX;
01240 fMarkedEnd.fX = pos.fX;
01241 fMarkedFromX = 1;
01242 }
01243 } else if (fMarkedFromX == 1 || fMarkedFromY == 1) {
01244 posStart.fY = pos.fY;
01245 posEnd.fY = fMarkedEnd.fY;
01246 fMarkedEnd.fY = pos.fY;
01247 fMarkedEnd.fX = pos.fX;
01248 fMarkedFromY = 1;
01249 fMarkedFromX = 1;
01250 if (fMarkedEnd.fX == -1) {
01251 fMarkedEnd.fY = pos.fY-1;
01252 fMarkedEnd.fX = fText->GetLineLength(fMarkedEnd.fY);
01253 if (fMarkedEnd.fX < 0) {
01254 fMarkedEnd.fX = 0;
01255 }
01256 }
01257 fMarkedFromX = 1;
01258 if (fMarkedStart.fY == fMarkedEnd.fY &&
01259 fMarkedStart.fX > fMarkedEnd.fX) {
01260 fMarkedEnd.fX = fMarkedStart.fX;
01261 fMarkedStart.fX = pos.fX;
01262 fMarkedFromX = 0;
01263 }
01264 }
01265 }
01266 }
01267 }
01268
01269 if (fMarkedEnd.fX == -1) {
01270 if (fMarkedEnd.fY > 0) {
01271 fMarkedEnd.fY--;
01272 }
01273 fMarkedEnd.fX = fText->GetLineLength(fMarkedEnd.fY);
01274 if (fMarkedEnd.fX < 0) {
01275 fMarkedEnd.fX = 0;
01276 }
01277 }
01278 fIsMarked = kTRUE;
01279
01280 Int_t yy = (Int_t)ToScrYCoord(posStart.fY);
01281 UInt_t hh = UInt_t(ToScrYCoord(posEnd.fY + 1) - ToScrYCoord(posStart.fY));
01282
01283 DrawRegion(0, yy, fCanvas->GetWidth(), hh);
01284 return;
01285 }
01286
01287
01288 void TGTextView::UnMark()
01289 {
01290
01291
01292 if (!fIsMarked ||
01293 ((fMarkedEnd.fY == fMarkedStart.fY) &&
01294 (fMarkedEnd.fX == fMarkedStart.fX))) {
01295 return;
01296 }
01297 fIsMarked = kFALSE;
01298
01299 Int_t y = (Int_t)ToScrYCoord(fMarkedStart.fY);
01300 UInt_t h = UInt_t(ToScrYCoord(fMarkedEnd.fY + 1) - y);
01301
01302
01303 UpdateRegion(0, y, fCanvas->GetWidth(), h);
01304 }
01305
01306
01307 void TGTextView::AdjustWidth()
01308 {
01309
01310
01311 Long_t line = fText->GetLongestLine();
01312 if (line <= 0) {
01313 return;
01314 }
01315 Long_t size = ToScrXCoord(fText->GetLineLength(line), line) + fVisible.fX;
01316 if (fVsb->IsMapped()) {
01317 size += fVsb->GetDefaultWidth();
01318 }
01319 size += (fBorderWidth << 1) + fXMargin+1;
01320 Resize((UInt_t)size, fHeight);
01321 }
01322
01323
01324 void TGTextView::Layout()
01325 {
01326
01327
01328 VLayout();
01329 HLayout();
01330 }
01331
01332
01333 void TGTextView::HLayout()
01334 {
01335
01336
01337 if (!fHsb) return;
01338
01339 Int_t tcw, tch;
01340 Long_t cols;
01341 tch = fHeight - (fBorderWidth << 1) - fYMargin-1;
01342 tcw = fWidth - (fBorderWidth << 1) - fXMargin-1;
01343
01344 if (fVsb && fVsb->IsMapped()) {
01345 tcw -= fVsb->GetDefaultWidth();
01346 if (tcw < 0) tcw = 0;
01347 }
01348 fCanvas->SetHeight(tch);
01349 fCanvas->SetWidth(tcw);
01350 cols = ReturnLongestLineWidth();
01351 if (cols <= tcw) {
01352 if (fHsb && fHsb->IsMapped()) {
01353 SetVisibleStart(0, kHorizontal);
01354 fHsb->UnmapWindow();
01355 VLayout();
01356 }
01357 fCanvas->MoveResize(fBorderWidth + fXMargin, fBorderWidth + fYMargin, tcw, tch);
01358 } else {
01359 if (fHsb) {
01360 tch -= fHsb->GetDefaultHeight();
01361 if (tch < 0) tch = 0;
01362 fHsb->MoveResize(fBorderWidth, fHeight - fHsb->GetDefaultHeight()-fBorderWidth,
01363 tcw+1+fBorderWidth, fHsb->GetDefaultHeight());
01364 fHsb->MapWindow();
01365 fHsb->SetRange(Int_t(cols/fScrollVal.fX), Int_t(tcw/fScrollVal.fX));
01366 }
01367 fCanvas->MoveResize(fBorderWidth + fXMargin, fBorderWidth + fYMargin, tcw, tch);
01368 }
01369 }
01370
01371
01372 void TGTextView::VLayout()
01373 {
01374
01375
01376 Int_t tcw, tch;
01377 Long_t lines;
01378
01379 tch = fHeight - (fBorderWidth << 1) - fYMargin-1;
01380 tcw = fWidth - (fBorderWidth << 1) - fXMargin-1;
01381 if (fHsb && fHsb->IsMapped()) {
01382 tch -= fHsb->GetDefaultHeight();
01383 if (tch < 0) tch = 0;
01384 }
01385 fCanvas->SetHeight(tch);
01386 fCanvas->SetWidth(tcw);
01387 lines = ReturnHeighestColHeight();
01388 if (lines <= tch) {
01389 if (fVsb && fVsb->IsMapped()) {
01390 SetVisibleStart(0, kVertical);
01391 fVsb->UnmapWindow();
01392 HLayout();
01393 }
01394 fCanvas->MoveResize(fBorderWidth + fXMargin, fBorderWidth + fYMargin, tcw, tch);
01395 } else {
01396 if (fVsb) {
01397 tcw -= fVsb->GetDefaultWidth();
01398 if (tcw < 0) tcw = 0;
01399 fVsb->MoveResize(fWidth - fVsb->GetDefaultWidth() - fBorderWidth, fBorderWidth,
01400 fVsb->GetDefaultWidth(), tch+1+fBorderWidth);
01401 fVsb->MapWindow();
01402 fVsb->SetRange(Int_t(lines/fScrollVal.fY), Int_t(tch/fScrollVal.fY));
01403 }
01404 fCanvas->MoveResize(fBorderWidth + fXMargin, fBorderWidth + fYMargin, tcw, tch);
01405 }
01406 }
01407
01408
01409 void TGTextView::SetSBRange(Int_t direction)
01410 {
01411
01412
01413 if (direction == kVertical) {
01414 if (!fVsb) {
01415 return;
01416 }
01417 if (ReturnHeighestColHeight() <= (Int_t)fCanvas->GetHeight()) {
01418 if (fVsb->IsMapped()) {
01419 VLayout();
01420 } else {
01421 return;
01422 }
01423 }
01424 if (!fVsb->IsMapped()) {
01425 VLayout();
01426 }
01427 fVsb->SetRange(Int_t(ReturnHeighestColHeight()/fScrollVal.fY),
01428 Int_t(fCanvas->GetHeight()/fScrollVal.fY));
01429 HLayout();
01430 } else {
01431 if (!fHsb) {
01432 return;
01433 }
01434 if (ReturnLongestLineWidth() <= (Int_t)fCanvas->GetWidth()) {
01435 if (fHsb->IsMapped()) {
01436 HLayout();
01437 } else {
01438 return;
01439 }
01440 }
01441 if (!fHsb->IsMapped()) {
01442 HLayout();
01443 }
01444 fHsb->SetRange(Int_t(ReturnLongestLineWidth()/fScrollVal.fX),
01445 Int_t(fCanvas->GetWidth()/fScrollVal.fX));
01446 VLayout();
01447 }
01448 }
01449
01450
01451 void TGTextView::SetHsbPosition(Long_t newPos)
01452 {
01453
01454
01455 if (fHsb && fHsb->IsMapped()) {
01456 fHsb->SetPosition(Int_t(newPos));
01457 } else {
01458 SetVisibleStart(Int_t(newPos * fScrollVal.fX), kHorizontal);
01459 }
01460 }
01461
01462
01463 void TGTextView::SetVsbPosition(Long_t newPos)
01464 {
01465
01466
01467 if (fVsb && fVsb->IsMapped()) {
01468 fVsb->SetPosition(Int_t(newPos));
01469 } else {
01470 SetVisibleStart(Int_t(newPos * fScrollVal.fY), kVertical);
01471 }
01472 }
01473
01474
01475 FontStruct_t TGTextView::GetDefaultFontStruct()
01476 {
01477
01478
01479 if (!fgDefaultFont) {
01480 fgDefaultFont = gClient->GetResourcePool()->GetDocumentFixedFont();
01481 }
01482 return fgDefaultFont->GetFontStruct();
01483 }
01484
01485
01486 void TGTextView::ShowBottom()
01487 {
01488
01489
01490 Int_t tch;
01491 Long_t lines, newPos;
01492
01493 tch = fCanvas->GetHeight();
01494 lines = ReturnHeighestColHeight();
01495 if (lines > tch) {
01496 newPos = lines / fScrollVal.fY;
01497 SetVsbPosition(newPos);
01498 }
01499 Layout();
01500 }
01501
01502
01503 void TGTextView::ShowTop()
01504 {
01505
01506
01507 SetVsbPosition(0);
01508 Layout();
01509 }
01510
01511
01512 void TGTextView::SetForegroundColor(Pixel_t col)
01513 {
01514
01515
01516 fNormGC.SetBackground(col);
01517 fNormGC.SetForeground(col);
01518 }
01519
01520
01521 const TGGC &TGTextView::GetDefaultGC()
01522 {
01523
01524
01525 if (!fgDefaultGC) {
01526 fgDefaultGC = new TGGC(*gClient->GetResourcePool()->GetFrameGC());
01527 fgDefaultGC->SetFont(fgDefaultFont->GetFontHandle());
01528 }
01529 return *fgDefaultGC;
01530 }
01531
01532
01533 const TGGC &TGTextView::GetDefaultSelectedGC()
01534 {
01535
01536
01537 if (!fgDefaultSelectedGC) {
01538 fgDefaultSelectedGC = new TGGC(*gClient->GetResourcePool()->GetSelectedGC());
01539 fgDefaultSelectedGC->SetFont(fgDefaultFont->GetFontHandle());
01540 }
01541 return *fgDefaultSelectedGC;
01542 }
01543
01544
01545 const TGGC &TGTextView::GetDefaultSelectedBackgroundGC()
01546 {
01547
01548
01549 if (!fgDefaultSelectedBackgroundGC) {
01550 fgDefaultSelectedBackgroundGC = gClient->GetResourcePool()->GetSelectedBckgndGC();
01551 }
01552 return *fgDefaultSelectedBackgroundGC;
01553 }
01554
01555
01556 void TGTextView::SavePrimitive(ostream &out, Option_t *option )
01557 {
01558
01559
01560 char quote = '"';
01561 out << " TGTextView *";
01562 out << GetName() << " = new TGTextView(" << fParent->GetName()
01563 << "," << GetWidth() << "," << GetHeight()
01564 << ");"<< endl;
01565
01566 if (option && strstr(option, "keep_names"))
01567 out << " " << GetName() << "->SetName(\"" << GetName() << "\");" << endl;
01568
01569 if (fCanvas->GetBackground() != TGFrame::fgWhitePixel) {
01570 out << " " << GetName() << "->ChangeBackground(" << fCanvas->GetBackground() << ");" << endl;
01571 }
01572
01573 TGText *txt = GetText();
01574 Bool_t fromfile = strlen(txt->GetFileName()) ? kTRUE : kFALSE;
01575 TString fn;
01576
01577 if (fromfile) {
01578 const char *filename = txt->GetFileName();
01579 fn = gSystem->ExpandPathName(gSystem->UnixPathName(filename));
01580 } else {
01581 fn = TString::Format("Txt%s", GetName()+5);
01582 txt->Save(fn.Data());
01583 }
01584 out << " " << GetName() << "->LoadFile(" << quote << fn.Data() << quote << ");" << endl;
01585 }