TGTextView.cxx

Go to the documentation of this file.
00001 // @(#)root/gui:$Id: TGTextView.cxx 35582 2010-09-22 13:38:27Z bellenot $
00002 // Author: Fons Rademakers   1/7/2000
00003 
00004 /*************************************************************************
00005  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
00006  * All rights reserved.                                                  *
00007  *                                                                       *
00008  * For the licensing terms see $ROOTSYS/LICENSE.                         *
00009  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
00010  *************************************************************************/
00011 /**************************************************************************
00012 
00013     This source is based on Xclass95, a Win95-looking GUI toolkit.
00014     Copyright (C) 1996, 1997 David Barth, Ricky Ralston, Hector Peraza.
00015 
00016     Xclass95 is free software; you can redistribute it and/or
00017     modify it under the terms of the GNU Library General Public
00018     License as published by the Free Software Foundation; either
00019     version 2 of the License, or (at your option) any later version.
00020 
00021 **************************************************************************/
00022 
00023 //////////////////////////////////////////////////////////////////////////
00024 //                                                                      //
00025 // TGTextView                                                           //
00026 //                                                                      //
00027 // A TGTextView is a text viewer widget. It is a specialization of      //
00028 // TGView. It uses the TGText class (which contains all text            //
00029 // manipulation code, i.e. loading a file in memory, changing,          //
00030 // removing lines, etc.). Use a TGTextView to view non-editable text.   //
00031 // For supported messages see TGView.                                   //
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    // Notify when timer times out and reset the timer.
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    // Initialize a text view widget.
00072 
00073    // set in TGResourcePool via .rootrc
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    // define DND types
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    // Create a text view widget.
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    // Create a text view widget.
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    // Create a text view widget.
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    // Cleanup text view widget.
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    // set background  color
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    // set selected text background color
00178 
00179    fSelbackGC.SetBackground(p);
00180    fSelbackGC.SetForeground(p);
00181 }
00182 
00183 //______________________________________________________________________________
00184 void TGTextView::SetSelectFore(Pixel_t p)
00185 {
00186    // set selected text color 
00187 
00188    fSelGC.SetBackground(p);
00189    fSelGC.SetForeground(p);
00190 }
00191 
00192 //______________________________________________________________________________
00193 void TGTextView::SetText(TGText *text)
00194 {
00195    // Adopt a new text buffer. The text will be deleted by this object.
00196 
00197    Clear();
00198    delete fText;
00199    fText = text;
00200    Layout();
00201 }
00202 
00203 //______________________________________________________________________________
00204 void TGTextView::AddText(TGText *text)
00205 {
00206    // Add text to the view widget.
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    // Add a line of text to the view widget.
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    // Add a line of text to the view widget.
00248    // Fast version. Use it if you are going to add
00249    // several lines, than call Update().
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    // update the whole window of text view
00261 
00262    Layout();
00263    fExposedRegion.Empty();
00264    UpdateRegion(0, 0, fCanvas->GetWidth(), fCanvas->GetHeight());
00265 }
00266 
00267 //______________________________________________________________________________
00268 Long_t TGTextView::ReturnLongestLineWidth()
00269 {
00270    // Return width of longest line.
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    // Search for string in text. If direction is true search forward.
00288    // Returns true if string is found.
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    // Changes text entry font.
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    // Convert line number to screen coordinate.
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    // Convert column number in specified line to screen coordinate.
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    // Convert y screen coordinate to line number.
00383 
00384    return  yCoord / (fMaxAscent + fMaxDescent);
00385 }
00386 
00387 //______________________________________________________________________________
00388 Long_t TGTextView::ToObjXCoord(Long_t xCoord, Long_t line)
00389 {
00390    // Convert x screen coordinate to column in specified line.
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    // Clear text view widget.
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    // Load a file in the text view widget. Return false in case file does not
00451    // exist.
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    // Load text from a text buffer. Return false in case of failure.
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    // Copy selected text to clipboard.
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    // Select all text in the viewer.
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    // Draw lines in exposed region.
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;  // +1
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;  // +1
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    // Handle mouse crossing event.
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    // Handle scroll timer.
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       // where cursor
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          // Figure scroll amount y
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    // Handle mouse button event in text editor.
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       // move three lines up
00858       if (fVisible.fY > 0) {
00859          Long_t amount = fVisible.fY / fScrollVal.fY - 3;
00860          SetVsbPosition((amount >= 0) ? amount : 0);
00861          //Mark(fMousePos.fX, fMarkedStart.fY - 3);
00862       }
00863    } else if (event->fCode == kButton5) {
00864       // move three lines down
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          //Mark(fMousePos.fX, size.fY + 3);
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    // handle double click
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    // Handle mouse motion event in the text editor widget.
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 * /*event*/)
00952 {
00953    // Handle selection clear event.
00954 
00955    if (fIsMarked) {
00956       UnMark();
00957    }
00958    return kTRUE;
00959 }
00960 
00961 //______________________________________________________________________________
00962 Bool_t TGTextView::HandleSelectionRequest(Event_t *event)
00963 {
00964    // Handle request to send current clipboard contents to requestor window.
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];     // requestor
00976    reply.fUser[1] = event->fUser[1];     // selection
00977    reply.fUser[2] = event->fUser[2];     // target
00978    reply.fUser[3] = event->fUser[3];     // property
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--;  // remove \n for last line
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;   // \n
01008          prev_len += temp_len+1;
01009       } else
01010          prev_len += temp_len;
01011       delete [] temp_buffer;
01012    }
01013    buffer[len] = '\0';
01014 
01015    // get rid of special tab fillers
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    // Returns true if given a text file
01044    // Uses the specification given on p86 of the Camel book
01045    // - Text files have no NULLs in the first block
01046    // - and less than 30% of characters with high bit set
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       // Read a block
01062       nchars = fread(buffer, 1, 512, infile);
01063       fclose (infile);
01064       // Examine the block
01065       for (i = 0; i < nchars; i++) {
01066          if (buffer[i] & 128)
01067             weirdcount++;
01068          if (buffer[i] == '\0')
01069             // No NULLs in text files
01070             return kFALSE;
01071       }
01072       if ((nchars > 0) && ((weirdcount * 100 / nchars) > 30))
01073          return kFALSE;
01074    } else {
01075       // Couldn't open it. Not a text file then
01076       return kFALSE;
01077    }
01078    return kTRUE;
01079 }
01080 
01081 //______________________________________________________________________________
01082 Bool_t TGTextView::HandleDNDDrop(TDNDData *data)
01083 {
01084    // Handle Drop event
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 /*x*/, Int_t /*y*/, Atom_t action,
01132                                       Int_t /*xroot*/, Int_t /*yroot*/)
01133 {
01134    // Handle Drag position event
01135 
01136    return action;
01137 }
01138 
01139 //______________________________________________________________________________
01140 Atom_t TGTextView::HandleDNDEnter(Atom_t *typelist)
01141 {
01142    // Handle Drag Enter event
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    // Handle Drag Leave event
01160 
01161    return kTRUE;
01162 }
01163 
01164 //______________________________________________________________________________
01165 void TGTextView::Mark(Long_t xPos, Long_t yPos)
01166 {
01167    // Mark a text region from xPos to yPos.
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;  // -1
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;   // -1
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;  // -1
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;  // -1
01248                fMarkedFromY = 1;
01249                fMarkedFromX = 1;
01250                if (fMarkedEnd.fX == -1) {
01251                   fMarkedEnd.fY = pos.fY-1;
01252                   fMarkedEnd.fX = fText->GetLineLength(fMarkedEnd.fY); // -1
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);  // -1
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    // Clear marked region.
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    // update marked region
01303    UpdateRegion(0, y, fCanvas->GetWidth(), h);
01304 }
01305 
01306 //______________________________________________________________________________
01307 void TGTextView::AdjustWidth()
01308 {
01309    // Adjust widget width to longest line.
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    // Layout the components of view.
01327 
01328    VLayout();
01329    HLayout();
01330 }
01331 
01332 //______________________________________________________________________________
01333 void TGTextView::HLayout()
01334 {
01335    // Horizontal layout of widgets (canvas, scrollbar).
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    // Vertical layout of widgets (canvas, scrollbar).
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    // Set the range for the kVertical or kHorizontal scrollbar.
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    // Set position of horizontal scrollbar.
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    // Set position of vertical scrollbar.
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    // Return default font structure in use.
01478 
01479    if (!fgDefaultFont) {
01480       fgDefaultFont = gClient->GetResourcePool()->GetDocumentFixedFont();
01481    }
01482    return fgDefaultFont->GetFontStruct();
01483 }
01484 
01485 //______________________________________________________________________________
01486 void TGTextView::ShowBottom()
01487 {
01488    // Show bottom of the page.
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    // Show top of the page.
01506 
01507    SetVsbPosition(0);
01508    Layout();
01509 }
01510 
01511 //______________________________________________________________________________
01512 void TGTextView::SetForegroundColor(Pixel_t col)
01513 {
01514    // Set text color.
01515 
01516    fNormGC.SetBackground(col);
01517    fNormGC.SetForeground(col);
01518 }
01519 
01520 //______________________________________________________________________________
01521 const TGGC &TGTextView::GetDefaultGC()
01522 {
01523    // Return default graphics context in use.
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    // Return selection graphics context in use.
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    // Return graphics context for highlighted frame background.
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    // Save a text edit widget as a C++ statement(s) on output stream out
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 }

Generated on Tue Jul 5 14:22:06 2011 for ROOT_528-00b_version by  doxygen 1.5.1