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 #include "TGTextEdit.h"
00034 #include "TGTextEditDialogs.h"
00035 #include "TGResourcePool.h"
00036 #include "TSystem.h"
00037 #include "TMath.h"
00038 #include "TTimer.h"
00039 #include "TGMenu.h"
00040 #include "TGMsgBox.h"
00041 #include "TGFileDialog.h"
00042 #include "TGScrollBar.h"
00043 #include "KeySymbols.h"
00044 #include "Riostream.h"
00045
00046
00047 static const char *gFiletypes[] = { "All files", "*",
00048 "Text files", "*.txt",
00049 "ROOT macros", "*.C",
00050 0, 0 };
00051 static char *gPrinter = 0;
00052 static char *gPrintCommand = 0;
00053
00054
00055 TGGC *TGTextEdit::fgCursor0GC;
00056 TGGC *TGTextEdit::fgCursor1GC;
00057
00058
00059
00060 class TGTextEditHist : public TList {
00061
00062 public:
00063 TGTextEditHist() {}
00064 virtual ~TGTextEditHist() { Delete(); }
00065
00066 Bool_t Notify() {
00067 TObject *obj = Last();
00068 if (!obj) return kFALSE;
00069
00070 obj->Notify();
00071 RemoveLast();
00072 delete obj;
00073 return kTRUE;
00074 }
00075 };
00076
00077
00078 class TGTextEditCommand : public TObject {
00079 protected:
00080 TGTextEdit *fEdit;
00081 TGLongPosition fPos;
00082
00083 public:
00084 TGTextEditCommand(TGTextEdit *te) : fEdit(te) {
00085 fPos = fEdit->GetCurrentPos();
00086 fEdit->GetHistory()->Add(this);
00087 }
00088 void SetPos(TGLongPosition pos) { fPos = pos; }
00089 };
00090
00091
00092 class TInsCharCom : public TGTextEditCommand {
00093
00094 public:
00095 TInsCharCom(TGTextEdit *te, char ch) : TGTextEditCommand(te) {
00096 fEdit->InsChar(ch);
00097 }
00098 Bool_t Notify() {
00099 fEdit->SetCurrent(fPos);
00100 fEdit->NextChar();
00101 fEdit->DelChar();
00102 return kTRUE;
00103 }
00104 };
00105
00106
00107 class TDelCharCom : public TGTextEditCommand {
00108
00109 private:
00110 char fChar;
00111
00112 public:
00113 TDelCharCom(TGTextEdit *te) : TGTextEditCommand(te) {
00114 fPos.fX--;
00115 fChar = fEdit->GetText()->GetChar(fPos);
00116 fEdit->DelChar();
00117 }
00118 Bool_t Notify() {
00119 if (fChar > 0) {
00120 fEdit->SetCurrent(fPos);
00121 fEdit->InsChar(fChar);
00122 } else {
00123 fPos.fY--;
00124 fEdit->BreakLine();
00125 }
00126 return kTRUE;
00127 }
00128 };
00129
00130
00131 class TBreakLineCom : public TGTextEditCommand {
00132
00133 public:
00134 TBreakLineCom(TGTextEdit *te) : TGTextEditCommand(te) {
00135 fEdit->BreakLine();
00136 fPos.fX = 0;
00137 fPos.fY++;
00138 }
00139
00140 Bool_t Notify() {
00141 fEdit->SetCurrent(fPos);
00142 fEdit->DelChar();
00143 return kTRUE;
00144 }
00145 };
00146
00147
00148 class TInsTextCom : public TGTextEditCommand {
00149 private:
00150 TGLongPosition fEndPos;
00151
00152 public:
00153 char fChar;
00154
00155 TInsTextCom(TGTextEdit *te) : TGTextEditCommand(te), fChar(0) {
00156 }
00157
00158 void SetEndPos(TGLongPosition end) {
00159 fEndPos = end;
00160 }
00161
00162 Bool_t Notify() {
00163 fEdit->GetText()->DelText(fPos, fEndPos);
00164
00165 if (fChar > 0) {
00166 fEdit->GetText()->InsChar(fPos, fChar);
00167 } else if (fPos.fY != fEndPos.fY) {
00168 fEdit->GetText()->BreakLine(fPos);
00169 }
00170 fEdit->SetCurrent(fPos);
00171 fEdit->Update();
00172 return kTRUE;
00173 }
00174 };
00175
00176
00177 class TDelTextCom : public TGTextEditCommand {
00178
00179 private:
00180 TGText *fText;
00181 TGLongPosition fEndPos;
00182 Bool_t fBreakLine;
00183
00184 public:
00185 TDelTextCom(TGTextEdit *te, TGText *txt) : TGTextEditCommand(te) {
00186 fText = new TGText(txt);
00187 fBreakLine = kFALSE;
00188 }
00189
00190 virtual ~TDelTextCom() { delete fText; }
00191
00192 void SetEndPos(TGLongPosition end) {
00193 fEndPos = end;
00194 }
00195
00196 void SetBreakLine(Bool_t on) { fBreakLine = on; }
00197
00198 Bool_t Notify() {
00199 TGLongPosition start_src, end_src;
00200 start_src.fX = start_src.fY = 0;
00201 end_src.fY = fText->RowCount() - 1;
00202 end_src.fX = fText->GetLineLength(end_src.fY) - 1;
00203
00204 fEdit->GetText()->InsText(fPos, fText, start_src, end_src);
00205
00206 if (fBreakLine) {
00207 fEndPos.fY++;
00208 fEdit->GetText()->BreakLine(fEndPos);
00209 fEndPos.fX = fEdit->GetText()->GetLineLength(fEndPos.fY);
00210 } else {
00211 fEndPos.fX++;
00212 }
00213
00214 fEdit->SetCurrent(fEndPos);
00215 fEdit->Update();
00216 return kTRUE;
00217 }
00218 };
00219
00220
00221 ClassImp(TGTextEdit)
00222
00223
00224
00225 TGTextEdit::TGTextEdit(const TGWindow *parent, UInt_t w, UInt_t h, Int_t id,
00226 UInt_t sboptions, ULong_t back) :
00227 TGTextView(parent, w, h, id, sboptions, back)
00228 {
00229
00230
00231 Init();
00232 }
00233
00234
00235 TGTextEdit::TGTextEdit(const TGWindow *parent, UInt_t w, UInt_t h, TGText *text,
00236 Int_t id, UInt_t sboptions, ULong_t back) :
00237 TGTextView(parent, w, h, text, id, sboptions, back)
00238 {
00239
00240
00241 Init();
00242 }
00243
00244
00245 TGTextEdit::TGTextEdit(const TGWindow *parent, UInt_t w, UInt_t h,
00246 const char *string, Int_t id, UInt_t sboptions,
00247 ULong_t back) :
00248 TGTextView(parent, w, h, string, id, sboptions, back)
00249 {
00250
00251
00252 Init();
00253 }
00254
00255
00256 TGTextEdit::~TGTextEdit()
00257 {
00258
00259
00260 if (TGSearchDialog::SearchDialog()) {
00261 TQObject::Disconnect(TGSearchDialog::SearchDialog(), 0, this);
00262 }
00263 delete fCurBlink;
00264 delete fMenu;
00265 delete fHistory;
00266 }
00267
00268
00269 void TGTextEdit::Init()
00270 {
00271
00272
00273 fCursor0GC = GetCursor0GC()();
00274 fCursor1GC = GetCursor1GC()();
00275 fCursorState = 1;
00276 fCurrent.fY = fCurrent.fX = 0;
00277 fInsertMode = kInsert;
00278 fCurBlink = 0;
00279 fSearch = 0;
00280 fEnableMenu = kTRUE;
00281 fEnableCursorWithoutFocus = kTRUE;
00282
00283 gVirtualX->SetCursor(fCanvas->GetId(), fClient->GetResourcePool()->GetTextCursor());
00284
00285
00286 fMenu = new TGPopupMenu(fClient->GetDefaultRoot());
00287 fMenu->AddEntry("New", kM_FILE_NEW);
00288 fMenu->AddEntry("Open...", kM_FILE_OPEN);
00289 fMenu->AddSeparator();
00290 fMenu->AddEntry("Close", kM_FILE_CLOSE);
00291 fMenu->AddEntry("Save", kM_FILE_SAVE);
00292 fMenu->AddEntry("Save As...", kM_FILE_SAVEAS);
00293 fMenu->AddSeparator();
00294 fMenu->AddEntry("Print...", kM_FILE_PRINT);
00295 fMenu->AddSeparator();
00296 fMenu->AddEntry("Cut", kM_EDIT_CUT);
00297 fMenu->AddEntry("Copy", kM_EDIT_COPY);
00298 fMenu->AddEntry("Paste", kM_EDIT_PASTE);
00299 fMenu->AddEntry("Select All", kM_EDIT_SELECTALL);
00300 fMenu->AddSeparator();
00301 fMenu->AddEntry("Find...", kM_SEARCH_FIND);
00302 fMenu->AddEntry("Find Again", kM_SEARCH_FINDAGAIN);
00303 fMenu->AddEntry("Goto...", kM_SEARCH_GOTO);
00304
00305 fMenu->Associate(this);
00306
00307 fHistory = new TGTextEditHist();
00308 }
00309
00310
00311 void TGTextEdit::SetMenuState()
00312 {
00313
00314
00315 if (fText->RowCount() == 1 && fText->GetLineLength(0) <= 0) {
00316 fMenu->DisableEntry(kM_FILE_CLOSE);
00317 fMenu->DisableEntry(kM_FILE_SAVE);
00318 fMenu->DisableEntry(kM_FILE_SAVEAS);
00319 fMenu->DisableEntry(kM_FILE_PRINT);
00320 fMenu->DisableEntry(kM_EDIT_SELECTALL);
00321 fMenu->DisableEntry(kM_SEARCH_FIND);
00322 fMenu->DisableEntry(kM_SEARCH_FINDAGAIN);
00323 fMenu->DisableEntry(kM_SEARCH_GOTO);
00324 } else {
00325 fMenu->EnableEntry(kM_FILE_CLOSE);
00326 fMenu->EnableEntry(kM_FILE_SAVE);
00327 fMenu->EnableEntry(kM_FILE_SAVEAS);
00328 fMenu->EnableEntry(kM_FILE_PRINT);
00329 fMenu->EnableEntry(kM_EDIT_SELECTALL);
00330 fMenu->EnableEntry(kM_SEARCH_FIND);
00331 fMenu->EnableEntry(kM_SEARCH_FINDAGAIN);
00332 fMenu->EnableEntry(kM_SEARCH_GOTO);
00333 }
00334
00335 if (IsSaved())
00336 fMenu->DisableEntry(kM_FILE_SAVE);
00337 else
00338 fMenu->EnableEntry(kM_FILE_SAVE);
00339
00340 if (fIsMarked) {
00341 fMenu->EnableEntry(kM_EDIT_CUT);
00342 fMenu->EnableEntry(kM_EDIT_COPY);
00343 } else {
00344 fMenu->DisableEntry(kM_EDIT_CUT);
00345 fMenu->DisableEntry(kM_EDIT_COPY);
00346 }
00347 }
00348
00349
00350 Long_t TGTextEdit::ReturnLongestLineWidth()
00351 {
00352
00353
00354 Long_t linewidth = TGTextView::ReturnLongestLineWidth();
00355 linewidth += 3*fScrollVal.fX;
00356 return linewidth;
00357 }
00358
00359
00360 void TGTextEdit::Clear(Option_t *)
00361 {
00362
00363
00364 fCursorState = 1;
00365 fCurrent.fY = fCurrent.fX = 0;
00366 TGTextView::Clear();
00367 }
00368
00369
00370 Bool_t TGTextEdit::SaveFile(const char *filename, Bool_t saveas)
00371 {
00372
00373
00374
00375
00376 if (!filename) {
00377 Bool_t untitled = !strlen(fText->GetFileName()) ? kTRUE : kFALSE;
00378 if (untitled || saveas) {
00379 static TString dir(".");
00380 static Bool_t overwr = kFALSE;
00381 TGFileInfo fi;
00382 fi.fFileTypes = gFiletypes;
00383 fi.fIniDir = StrDup(dir);
00384 fi.fOverwrite = overwr;
00385 new TGFileDialog(fClient->GetDefaultRoot(), this, kFDSave, &fi);
00386 overwr = fi.fOverwrite;
00387 if (fi.fFilename && strlen(fi.fFilename)) {
00388 dir = fi.fIniDir;
00389 return fText->Save(fi.fFilename);
00390 }
00391 return kFALSE;
00392 }
00393 return fText->Save(fText->GetFileName());
00394 }
00395
00396 return fText->Save(filename);
00397 }
00398
00399
00400 Bool_t TGTextEdit::Copy()
00401 {
00402
00403
00404 if (!fIsMarked || ((fMarkedStart.fX == fMarkedEnd.fX) &&
00405 (fMarkedStart.fY == fMarkedEnd.fY))) {
00406 return kFALSE;
00407 }
00408
00409 TGTextView::Copy();
00410
00411 Bool_t del = !fCurrent.fX && (fCurrent.fY == fMarkedEnd.fY) && !fMarkedEnd.fX;
00412 del = del || (!fMarkedEnd.fX && (fCurrent.fY != fMarkedEnd.fY));
00413 del = del && fClipText->AsString().Length() > 0;
00414
00415 if (del) {
00416 TGLongPosition pos;
00417 pos.fY = fClipText->RowCount();
00418 pos.fX = 0;
00419 fClipText->InsText(pos, 0);
00420 }
00421
00422 return kTRUE;
00423 }
00424
00425
00426 Bool_t TGTextEdit::Cut()
00427 {
00428
00429
00430 if (!Copy()) {
00431 return kFALSE;
00432 }
00433 Delete();
00434
00435 return kTRUE;
00436 }
00437
00438
00439 Bool_t TGTextEdit::Paste()
00440 {
00441
00442
00443 if (fReadOnly) {
00444 return kFALSE;
00445 }
00446
00447 if (fIsMarked) {
00448 TString sav = fClipText->AsString();
00449 TGTextView::Copy();
00450 Delete();
00451 fClipText->Clear();
00452 fClipText->LoadBuffer(sav.Data());
00453 }
00454
00455 gVirtualX->ConvertPrimarySelection(fId, fClipboard, 0);
00456
00457 return kTRUE;
00458 }
00459
00460
00461 void TGTextEdit::Print(Option_t *) const
00462 {
00463
00464
00465 TString msg;
00466
00467 msg.Form("%s -P%s\n", gPrintCommand, gPrinter);
00468 FILE *p = gSystem->OpenPipe(msg.Data(), "w");
00469 if (p) {
00470 char *buf1, *buf2;
00471 Long_t len;
00472 ULong_t i = 0;
00473 TGLongPosition pos;
00474
00475 pos.fX = pos.fY = 0;
00476 while (pos.fY < fText->RowCount()) {
00477 len = fText->GetLineLength(pos.fY);
00478 if (len < 0) len = 0;
00479 buf1 = fText->GetLine(pos, len);
00480 buf2 = new char[len + 2];
00481 strncpy(buf2, buf1, (UInt_t)len);
00482 buf2[len] = '\n';
00483 buf2[len+1] = '\0';
00484 while (buf2[i] != '\0') {
00485 if (buf2[i] == '\t') {
00486 ULong_t j = i+1;
00487 while (buf2[j] == 16)
00488 j++;
00489 strcpy(buf2+i+1, buf2+j);
00490 }
00491 i++;
00492 }
00493 fwrite(buf2, sizeof(char), strlen(buf2)+1, p);
00494
00495 delete [] buf1;
00496 delete [] buf2;
00497 pos.fY++;
00498 }
00499 gSystem->ClosePipe(p);
00500
00501 Bool_t untitled = !strlen(fText->GetFileName()) ? kTRUE : kFALSE;
00502 msg.Form("Printed: %s\nLines: %ld\nUsing: %s -P%s",
00503 untitled ? "Untitled" : fText->GetFileName(),
00504 fText->RowCount() - 1, gPrintCommand, gPrinter);
00505 new TGMsgBox(fClient->GetDefaultRoot(), this, "Editor", msg.Data(),
00506 kMBIconAsterisk, kMBOk, 0);
00507 } else {
00508 msg.Form("Could not execute: %s -P%s\n", gPrintCommand, gPrinter);
00509 new TGMsgBox(fClient->GetDefaultRoot(), this, "Editor", msg.Data(),
00510 kMBIconExclamation, kMBOk, 0);
00511 }
00512 }
00513
00514
00515 void TGTextEdit::Delete(Option_t *)
00516 {
00517
00518
00519 if (!fIsMarked || fReadOnly) {
00520 return;
00521 }
00522
00523 if (fMarkedStart.fX == fMarkedEnd.fX &&
00524 fMarkedStart.fY == fMarkedEnd.fY) {
00525 Long_t len = fText->GetLineLength(fCurrent.fY);
00526
00527 if (fCurrent.fY == fText->RowCount()-1 && fCurrent.fX == len) {
00528 gVirtualX->Bell(0);
00529 return;
00530 }
00531
00532 new TDelCharCom(this);
00533 return;
00534 }
00535
00536 TGLongPosition pos, endPos;
00537 Bool_t delast = kFALSE;
00538
00539 endPos.fX = fMarkedEnd.fX - 1;
00540 endPos.fY = fMarkedEnd.fY;
00541
00542 if (endPos.fX == -1) {
00543 pos = fCurrent;
00544 if (endPos.fY > 0) {
00545 SetCurrent(endPos);
00546 DelChar();
00547 endPos.fY--;
00548 SetCurrent(pos);
00549 }
00550 endPos.fX = fText->GetLineLength(endPos.fY);
00551 if (endPos.fX < 0) {
00552 endPos.fX = 0;
00553 }
00554 delast = kTRUE;
00555 }
00556
00557
00558 TDelTextCom *dcom = new TDelTextCom(this, fClipText);
00559 dcom->SetPos(fMarkedStart);
00560 dcom->SetEndPos(endPos);
00561
00562 if (delast || ((fText->GetLineLength(endPos.fY) == endPos.fX+1) &&
00563 (fClipText->RowCount() > 1))) {
00564 TGLongPosition p = endPos;
00565
00566 p.fY--;
00567 if (!delast) p.fX++;
00568 dcom->SetEndPos(p);
00569 dcom->SetBreakLine(kTRUE);
00570 }
00571
00572 fText->DelText(fMarkedStart, endPos);
00573
00574 pos.fY = ToObjYCoord(fVisible.fY);
00575
00576 if (fMarkedStart.fY < pos.fY) {
00577 pos.fY = fMarkedStart.fY;
00578 }
00579 pos.fX = ToObjXCoord(fVisible.fX, pos.fY);
00580 if (fMarkedStart.fX < pos.fX) {
00581 pos.fX = fMarkedStart.fX;
00582 }
00583
00584 Int_t th = (Int_t)ToScrYCoord(fText->RowCount());
00585 Int_t ys = (Int_t)ToScrYCoord(fMarkedStart.fY);
00586 th = th < 0 ? 0 : th;
00587 ys = ys < 0 ? 0 : ys;
00588
00589
00590 if ((th < 0) || (th < (Int_t)fCanvas->GetHeight())) {
00591 gVirtualX->ClearArea(fCanvas->GetId(), 0, ys,
00592 fCanvas->GetWidth(), fCanvas->GetHeight() - ys);
00593 }
00594
00595 UpdateRegion(0, ys, fCanvas->GetWidth(), UInt_t(fCanvas->GetHeight() - ys));
00596
00597 SetVsbPosition((ToScrYCoord(pos.fY) + fVisible.fY)/fScrollVal.fY);
00598 SetHsbPosition((ToScrXCoord(pos.fX, pos.fY) + fVisible.fX)/fScrollVal.fX);
00599 SetSBRange(kHorizontal);
00600 SetSBRange(kVertical);
00601 SetCurrent(fMarkedStart);
00602
00603 SendMessage(fMsgWindow, MK_MSG(kC_TEXTVIEW, kTXT_ISMARKED), fWidgetId, kFALSE);
00604 UnMark();
00605
00606
00607
00608 if (fText->RowCount() == 1 && fText->GetLineLength(0) == 0) {
00609 delete fText;
00610 fText = new TGText();
00611 fText->Clear();
00612 }
00613 }
00614
00615
00616 Bool_t TGTextEdit::Search(const char *string, Bool_t direction,
00617 Bool_t caseSensitive)
00618 {
00619
00620
00621
00622 if (!IsMapped()) return kFALSE;
00623
00624 if (gTQSender && (gTQSender == TGSearchDialog::SearchDialog())) {
00625 caseSensitive = TGSearchDialog::SearchDialog()->GetType()->fCaseSensitive;
00626 direction = TGSearchDialog::SearchDialog()->GetType()->fDirection;
00627 fSearch = TGSearchDialog::SearchDialog()->GetType();
00628 }
00629
00630 TGLongPosition pos;
00631 if (!fText->Search(&pos, fCurrent, string, direction, caseSensitive)) {
00632 fCurrent.fX = 1;
00633 fCurrent.fY = 1;
00634
00635 if (!fText->Search(&pos, fCurrent, string, direction, caseSensitive)) {
00636 TString msg;
00637 msg.Form("Couldn't find \"%s\"", string);
00638 gVirtualX->Bell(20);
00639 new TGMsgBox(fClient->GetDefaultRoot(), fCanvas, "TextEdit",
00640 msg.Data(), kMBIconExclamation, kMBOk, 0);
00641 return kFALSE;
00642 }
00643 return kTRUE;
00644 }
00645 UnMark();
00646 fIsMarked = kTRUE;
00647 fMarkedStart.fY = fMarkedEnd.fY = pos.fY;
00648 fMarkedStart.fX = pos.fX;
00649 fMarkedEnd.fX = fMarkedStart.fX + strlen(string);
00650
00651 if (direction) {
00652 SetCurrent(fMarkedEnd);
00653 } else {
00654 SetCurrent(fMarkedStart);
00655 }
00656
00657 pos.fY = ToObjYCoord(fVisible.fY);
00658 if (fCurrent.fY < pos.fY ||
00659 ToScrYCoord(fCurrent.fY) >= (Int_t)fCanvas->GetHeight()) {
00660 pos.fY = fMarkedStart.fY;
00661 }
00662 pos.fX = ToObjXCoord(fVisible.fX, pos.fY);
00663
00664 if (fCurrent.fX < pos.fX ||
00665 ToScrXCoord(fCurrent.fX, pos.fY) >= (Int_t)fCanvas->GetWidth()) {
00666 pos.fX = fMarkedStart.fX;
00667 }
00668
00669 SetVsbPosition((ToScrYCoord(pos.fY)+fVisible.fY)/fScrollVal.fY);
00670 SetHsbPosition((ToScrXCoord(pos.fX, pos.fY)+fVisible.fX)/fScrollVal.fX);
00671
00672 UpdateRegion(0, (Int_t)ToScrYCoord(fMarkedStart.fY), fCanvas->GetWidth(),
00673 UInt_t(ToScrYCoord(fMarkedEnd.fY+1)-ToScrYCoord(fMarkedEnd.fY)));
00674
00675 return kTRUE;
00676 }
00677
00678
00679 Bool_t TGTextEdit::Replace(TGLongPosition textPos, const char *oldText,
00680 const char *newText, Bool_t direction, Bool_t caseSensitive)
00681 {
00682
00683
00684 TGLongPosition pos;
00685 if (!fText->Replace(textPos, oldText, newText, direction, caseSensitive)) {
00686 return kFALSE;
00687 }
00688 UnMark();
00689 fIsMarked = kTRUE;
00690 fMarkedStart.fY = fMarkedEnd.fY = textPos.fY;
00691 fMarkedStart.fX = textPos.fX;
00692 fMarkedEnd.fX = fMarkedStart.fX + strlen(newText);
00693
00694 if (direction) {
00695 SetCurrent(fMarkedEnd);
00696 } else {
00697 SetCurrent(fMarkedStart);
00698 }
00699
00700 pos.fY = ToObjYCoord(fVisible.fY);
00701 if (fCurrent.fY < pos.fY ||
00702 ToScrYCoord(fCurrent.fY) >= (Int_t)fCanvas->GetHeight()) {
00703 pos.fY = fMarkedStart.fY;
00704 }
00705 pos.fX = ToObjXCoord(fVisible.fX, pos.fY);
00706 if (fCurrent.fX < pos.fX ||
00707 ToScrXCoord(fCurrent.fX, pos.fY) >= (Int_t)fCanvas->GetWidth()) {
00708 pos.fX = fMarkedStart.fX;
00709 }
00710
00711 SetVsbPosition((ToScrYCoord(pos.fY)+fVisible.fY)/fScrollVal.fY);
00712 SetHsbPosition((ToScrXCoord(pos.fX, pos.fY)+fVisible.fX)/fScrollVal.fX);
00713
00714 UpdateRegion(0, (Int_t)ToScrYCoord(fMarkedStart.fY), fCanvas->GetWidth(),
00715 UInt_t(ToScrYCoord(fMarkedEnd.fY+1)-ToScrYCoord(fMarkedEnd.fY)));
00716
00717 return kTRUE;
00718 }
00719
00720
00721 Bool_t TGTextEdit::Goto(Long_t line, Long_t column)
00722 {
00723
00724
00725 if (line < 0)
00726 line = 0;
00727 if (line >= fText->RowCount())
00728 line = fText->RowCount() - 1;
00729 if (column < 0)
00730 column = 0;
00731 if (column > fText->GetLineLength(line))
00732 column = fText->GetLineLength(line);
00733
00734 TGLongPosition gotopos, pos;
00735 gotopos.fY = line;
00736 gotopos.fX = column;
00737 SetCurrent(gotopos);
00738
00739 pos.fY = ToObjYCoord(fVisible.fY);
00740 if (fCurrent.fY < pos.fY ||
00741 ToScrYCoord(fCurrent.fY) >= (Int_t)fCanvas->GetHeight())
00742 pos.fY = gotopos.fY;
00743
00744 SetVsbPosition((ToScrYCoord(pos.fY)+fVisible.fY)/fScrollVal.fY);
00745 SetHsbPosition(0);
00746
00747 UnMark();
00748 fIsMarked = kTRUE;
00749 fMarkedStart.fY = fMarkedEnd.fY = line;
00750 fMarkedStart.fX = 0;
00751 fMarkedEnd.fX = fCanvas->GetWidth();
00752
00753 return kTRUE;
00754 }
00755
00756
00757 void TGTextEdit::SetInsertMode(EInsertMode mode)
00758 {
00759
00760
00761 if (fInsertMode == mode) return;
00762
00763 fInsertMode = mode;
00764 }
00765
00766
00767 void TGTextEdit::CursorOff()
00768 {
00769
00770
00771 if (fCursorState == 1) {
00772 DrawCursor(2);
00773 }
00774 fCursorState = 2;
00775 }
00776
00777
00778 void TGTextEdit::CursorOn()
00779 {
00780
00781
00782 DrawCursor(1);
00783 fCursorState = 1;
00784
00785 if (fCurBlink) {
00786 fCurBlink->Reset();
00787 }
00788 }
00789
00790
00791 void TGTextEdit::SetCurrent(TGLongPosition new_coord)
00792 {
00793
00794
00795 CursorOff();
00796
00797 fCurrent.fY = new_coord.fY;
00798 fCurrent.fX = new_coord.fX;
00799
00800 CursorOn();
00801
00802 SendMessage(fMsgWindow, MK_MSG(kC_TEXTVIEW, kTXT_DATACHANGE), fWidgetId, 0);
00803 DataChanged();
00804 }
00805
00806
00807 void TGTextEdit::DrawCursor(Int_t mode)
00808 {
00809
00810
00811 char count = -1;
00812 char cursor = ' ';
00813 if (fCurrent.fY >= fText->RowCount() || fCurrent.fX > fText->GetLineLength(fCurrent.fY) || fReadOnly) {
00814 return;
00815 }
00816
00817 if (fCurrent.fY >= ToObjYCoord(fVisible.fY) &&
00818 fCurrent.fY <= ToObjYCoord(fVisible.fY+fCanvas->GetHeight()) &&
00819 fCurrent.fX >= ToObjXCoord(fVisible.fX, fCurrent.fY) &&
00820 fCurrent.fX <= ToObjXCoord(fVisible.fX+fCanvas->GetWidth(),fCurrent.fY)) {
00821 if (fCurrent.fY < fText->RowCount()) {
00822 count = fText->GetChar(fCurrent);
00823 }
00824 if (count == -1 || count == '\t') {
00825 cursor = ' ';
00826 } else {
00827 cursor = count;
00828 }
00829
00830 if (mode == 2) {
00831 if (fIsMarked && count != -1) {
00832 if ((fCurrent.fY > fMarkedStart.fY && fCurrent.fY < fMarkedEnd.fY) ||
00833 (fCurrent.fY == fMarkedStart.fY && fCurrent.fX >= fMarkedStart.fX &&
00834 fCurrent.fY < fMarkedEnd.fY) ||
00835 (fCurrent.fY == fMarkedEnd.fY && fCurrent.fX < fMarkedEnd.fX &&
00836 fCurrent.fY > fMarkedStart.fY) ||
00837 (fCurrent.fY == fMarkedStart.fY && fCurrent.fY == fMarkedEnd.fY &&
00838 fCurrent.fX >= fMarkedStart.fX && fCurrent.fX < fMarkedEnd.fX &&
00839 fMarkedStart.fX != fMarkedEnd.fX)) {
00840
00841 gVirtualX->FillRectangle(fCanvas->GetId(), fSelbackGC(),
00842 Int_t(ToScrXCoord(fCurrent.fX, fCurrent.fY)),
00843 Int_t(ToScrYCoord(fCurrent.fY)),
00844 UInt_t(ToScrXCoord(fCurrent.fX+1, fCurrent.fY) -
00845 ToScrXCoord(fCurrent.fX, fCurrent.fY)),
00846 UInt_t(ToScrYCoord(fCurrent.fY+1)-ToScrYCoord(fCurrent.fY)));
00847 if (count != -1)
00848 gVirtualX->DrawString(fCanvas->GetId(), fSelGC(), (Int_t)ToScrXCoord(fCurrent.fX,fCurrent.fY),
00849 Int_t(ToScrYCoord(fCurrent.fY+1) - fMaxDescent), &cursor, 1);
00850 } else {
00851 gVirtualX->ClearArea(fCanvas->GetId(),
00852 Int_t(ToScrXCoord(fCurrent.fX, fCurrent.fY)),
00853 Int_t(ToScrYCoord(fCurrent.fY)),
00854 UInt_t(ToScrXCoord(fCurrent.fX+1, fCurrent.fY) -
00855 ToScrXCoord(fCurrent.fX, fCurrent.fY)),
00856 UInt_t(ToScrYCoord(fCurrent.fY+1)-ToScrYCoord(fCurrent.fY)));
00857 if (count != -1)
00858 gVirtualX->DrawString(fCanvas->GetId(), fNormGC(), (Int_t)ToScrXCoord(fCurrent.fX,fCurrent.fY),
00859 Int_t(ToScrYCoord(fCurrent.fY+1) - fMaxDescent), &cursor, 1);
00860 }
00861 } else {
00862 gVirtualX->ClearArea(fCanvas->GetId(),
00863 Int_t(ToScrXCoord(fCurrent.fX, fCurrent.fY)),
00864 Int_t(ToScrYCoord(fCurrent.fY)),
00865 UInt_t(ToScrXCoord(fCurrent.fX+1, fCurrent.fY) -
00866 ToScrXCoord(fCurrent.fX, fCurrent.fY)),
00867 UInt_t(ToScrYCoord(fCurrent.fY+1)-ToScrYCoord(fCurrent.fY)));
00868 gVirtualX->DrawString(fCanvas->GetId(), fNormGC(), (Int_t)ToScrXCoord(fCurrent.fX,fCurrent.fY),
00869 Int_t(ToScrYCoord(fCurrent.fY+1) - fMaxDescent), &cursor, 1);
00870 }
00871 } else {
00872 if (mode == 1) {
00873 gVirtualX->FillRectangle(fCanvas->GetId(), fCursor1GC,
00874 Int_t(ToScrXCoord(fCurrent.fX, fCurrent.fY)),
00875 Int_t(ToScrYCoord(fCurrent.fY)),
00876 2,
00877 UInt_t(ToScrYCoord(fCurrent.fY+1)-ToScrYCoord(fCurrent.fY)));
00878 }
00879 }
00880 }
00881 }
00882
00883
00884 void TGTextEdit::AdjustPos()
00885 {
00886
00887
00888 TGLongPosition pos;
00889 pos.fY = fCurrent.fY;
00890 pos.fX = fCurrent.fX;
00891
00892 if (pos.fY < ToObjYCoord(fVisible.fY)) {
00893 pos.fY = ToObjYCoord(fVisible.fY);
00894 } else if (ToScrYCoord(pos.fY+1) >= (Int_t) fCanvas->GetHeight()) {
00895 pos.fY = ToObjYCoord(fVisible.fY + fCanvas->GetHeight())-1;
00896 }
00897 if (pos.fX < ToObjXCoord(fVisible.fX, pos.fY)) {
00898 pos.fX = ToObjXCoord(fVisible.fX, pos.fY);
00899 } else if (ToScrXCoord(pos.fX, pos.fY) >= (Int_t) fCanvas->GetWidth()) {
00900 pos.fX = ToObjXCoord(fVisible.fX + fCanvas->GetWidth(), pos.fY)-1;
00901 }
00902 if (pos.fY != fCurrent.fY || pos.fX != fCurrent.fX) {
00903 SetCurrent(pos);
00904 }
00905 }
00906
00907
00908 Bool_t TGTextEdit::HandleTimer(TTimer *t)
00909 {
00910
00911
00912 if (t != fCurBlink) {
00913 TGTextView::HandleTimer(t);
00914 return kTRUE;
00915 }
00916
00917 if (fCursorState == 1) {
00918 fCursorState = 2;
00919 } else {
00920 fCursorState = 1;
00921 }
00922
00923 DrawCursor(fCursorState);
00924
00925 return kTRUE;
00926 }
00927
00928
00929 Bool_t TGTextEdit::HandleSelection(Event_t *event)
00930 {
00931
00932
00933 TString data;
00934 Int_t nchar;
00935
00936 gVirtualX->GetPasteBuffer((Window_t)event->fUser[0], (Atom_t)event->fUser[3],
00937 data, nchar, kFALSE);
00938
00939 if (!nchar) return kTRUE;
00940
00941 delete fClipText;
00942
00943 fClipText = new TGText;
00944 fClipText->LoadBuffer(data.Data());
00945
00946 TGLongPosition start_src, end_src, pos;
00947
00948 pos.fX = pos.fY = 0;
00949 start_src.fY = start_src.fX = 0;
00950 end_src.fY = fClipText->RowCount()-1;
00951 end_src.fX = fClipText->GetLineLength(end_src.fY)-1;
00952
00953 if (end_src.fX < 0) {
00954 end_src.fX = 0;
00955 }
00956
00957
00958 TInsTextCom *icom = new TInsTextCom(this);
00959 icom->fChar = fText->GetChar(fCurrent);
00960 fText->InsText(fCurrent, fClipText, start_src, end_src);
00961
00962 fIsMarked = kFALSE;
00963
00964 fExposedRegion.fX = 0;
00965 fExposedRegion.fY = ToScrYCoord(fCurrent.fY);
00966
00967 pos.fY = fCurrent.fY + fClipText->RowCount()-1;
00968 pos.fX = fClipText->GetLineLength(fClipText->RowCount()-1);
00969
00970 if (start_src.fY == end_src.fY) {
00971 pos.fX = pos.fX + fCurrent.fX;
00972 }
00973
00974 icom->SetEndPos(pos);
00975
00976
00977 fExposedRegion.fW = fCanvas->GetWidth();
00978 fExposedRegion.fH = fCanvas->GetHeight() - fExposedRegion.fY;
00979
00980 SetCurrent(pos);
00981
00982 if (ToScrYCoord(pos.fY) >= (Int_t)fCanvas->GetHeight()) {
00983 pos.fY = ToScrYCoord(pos.fY) + fVisible.fY - fCanvas->GetHeight()/2;
00984 fExposedRegion.fX = fExposedRegion.fY = 0;
00985 fExposedRegion.fH = fCanvas->GetHeight();
00986 } else {
00987 pos.fY = fVisible.fY;
00988 }
00989 if (ToScrXCoord(pos.fX, fCurrent.fY) >= (Int_t) fCanvas->GetWidth()) {
00990 pos.fX = ToScrXCoord(pos.fX, fCurrent.fY) + fVisible.fX + fCanvas->GetWidth()/2;
00991 } else if (ToScrXCoord(pos.fX, fCurrent.fY < 0) && pos.fX != 0) {
00992 if (fVisible.fX - (Int_t)fCanvas->GetWidth()/2 > 0) {
00993 pos.fX = fVisible.fX - fCanvas->GetWidth()/2;
00994 } else {
00995 pos.fX = 0;
00996 }
00997 } else {
00998 pos.fX = fVisible.fX;
00999 }
01000
01001 SetSBRange(kHorizontal);
01002 SetSBRange(kVertical);
01003 SetVsbPosition(pos.fY/fScrollVal.fY);
01004 SetHsbPosition(pos.fX/fScrollVal.fX);
01005
01006 fClient->NeedRedraw(this);
01007
01008 return kTRUE;
01009 }
01010
01011 static Bool_t gDbl_clk = kFALSE;
01012 static Bool_t gTrpl_clk = kFALSE;
01013
01014
01015 Bool_t TGTextEdit::HandleButton(Event_t *event)
01016 {
01017
01018
01019 if (event->fWindow != fCanvas->GetId()) {
01020 return kFALSE;
01021 }
01022
01023 TGLongPosition pos;
01024
01025 TGTextView::HandleButton(event);
01026
01027 if (event->fType == kButtonPress) {
01028 SetFocus();
01029
01030
01031 if (event->fCode == kButton1 || event->fCode == kButton2) {
01032 pos.fY = ToObjYCoord(fVisible.fY + event->fY);
01033 if (pos.fY >= fText->RowCount()) {
01034 pos.fY = fText->RowCount()-1;
01035 }
01036 pos.fX = ToObjXCoord(fVisible.fX+event->fX, pos.fY);
01037 if (pos.fX >= fText->GetLineLength(pos.fY)) {
01038 pos.fX = fText->GetLineLength(pos.fY);
01039 }
01040 while (fText->GetChar(pos) == 16) {
01041 pos.fX++;
01042 }
01043
01044 SetCurrent(pos);
01045
01046 TGTextLine *line = fText->GetCurrentLine();
01047 char *word = line->GetWord(pos.fX);
01048 Clicked((const char*)word);
01049 delete [] word;
01050 }
01051 if (event->fCode == kButton2) {
01052 if (gVirtualX->GetPrimarySelectionOwner() != kNone) {
01053 gVirtualX->ConvertPrimarySelection(fId, fClipboard, event->fTime);
01054 Update();
01055 return kTRUE;
01056 }
01057 }
01058 if (event->fCode == kButton3) {
01059
01060 if (fClient->IsEditable() || !fEnableMenu) {
01061 return kTRUE;
01062 }
01063 SetMenuState();
01064 fMenu->PlaceMenu(event->fXRoot, event->fYRoot, kFALSE, kTRUE);
01065 }
01066 gDbl_clk = kFALSE;
01067 gTrpl_clk = kFALSE;
01068 }
01069
01070 return kTRUE;
01071 }
01072
01073
01074 Bool_t TGTextEdit::HandleDoubleClick(Event_t *event)
01075 {
01076
01077
01078 if (event->fWindow != fCanvas->GetId()) {
01079 return kFALSE;
01080 }
01081
01082 if (event->fCode != kButton1) {
01083 return kFALSE;
01084 }
01085 if (!fText->GetCurrentLine()->GetText()) {
01086 return kFALSE;
01087 }
01088
01089 SetFocus();
01090 TGLongPosition pos;
01091 pos.fY = ToObjYCoord(fVisible.fY + event->fY);
01092
01093 if (gDbl_clk && (event->fTime - fgLastClick < 350)) {
01094 fgLastClick = event->fTime;
01095 gDbl_clk = kFALSE;
01096 gTrpl_clk = kTRUE;
01097 fMarkedStart.fY = fMarkedEnd.fY = pos.fY;
01098 fIsMarked = kTRUE;
01099 fMarkedStart.fX = 0;
01100 fMarkedEnd.fX = strlen(fText->GetCurrentLine()->GetText());
01101 Marked(kTRUE);
01102 UpdateRegion(0, (Int_t)ToScrYCoord(fMarkedStart.fY), fCanvas->GetWidth(),
01103 UInt_t(ToScrYCoord(fMarkedEnd.fY + 1) - ToScrYCoord(fMarkedStart.fY)));
01104 return kTRUE;
01105 }
01106
01107 if (gTrpl_clk && (event->fTime - fgLastClick < 350)) {
01108 fgLastClick = event->fTime;
01109 gTrpl_clk = kFALSE;
01110 fIsMarked = kTRUE;
01111 fMarkedStart.fY = 0;
01112 fMarkedStart.fX = 0;
01113 fMarkedEnd.fY = fText->RowCount()-1;
01114 fMarkedEnd.fX = fText->GetLineLength(fMarkedEnd.fY);
01115 if (fMarkedEnd.fX < 0) {
01116 fMarkedEnd.fX = 0;
01117 }
01118 UpdateRegion(0, 0, fCanvas->GetWidth(), fCanvas->GetHeight());
01119 return kTRUE;
01120 }
01121
01122 gDbl_clk = kTRUE;
01123 gTrpl_clk = kFALSE;
01124
01125 if (pos.fY >= fText->RowCount()) {
01126 pos.fY = fText->RowCount() - 1;
01127 }
01128 pos.fX = ToObjXCoord(fVisible.fX + event->fX, pos.fY);
01129
01130 if (pos.fX >= fText->GetLineLength(pos.fY)) {
01131 pos.fX = fText->GetLineLength(pos.fY);
01132 }
01133 while (fText->GetChar(pos) == 16) {
01134 pos.fX++;
01135 }
01136
01137 SetCurrent(pos);
01138
01139 fMarkedStart.fY = fMarkedEnd.fY = pos.fY;
01140 char *line = fText->GetCurrentLine()->GetText();
01141 UInt_t len = (UInt_t)fText->GetCurrentLine()->GetLineLength();
01142 Int_t start = pos.fX;
01143 Int_t end = pos.fX;
01144 Int_t i = pos.fX;
01145
01146 if (line[i] == ' ' || line[i] == '\t') {
01147 while (start >= 0) {
01148 if (line[start] == ' ' || line[start] == '\t') --start;
01149 else break;
01150 }
01151 ++start;
01152 while (end < (Int_t)len) {
01153 if (line[end] == ' ' || line[end] == '\t') ++end;
01154 else break;
01155 }
01156 } else if (isalnum(line[i])) {
01157 while (start >= 0) {
01158 if (isalnum(line[start])) --start;
01159 else break;
01160 }
01161 ++start;
01162 while (end < (Int_t)len) {
01163 if (isalnum(line[end])) ++end;
01164 else break;
01165 }
01166 } else {
01167 while (start >= 0) {
01168 if (isalnum(line[start]) || line[start] == ' ' || line[start] == '\t') {
01169 break;
01170 } else {
01171 --start;
01172 }
01173 }
01174 ++start;
01175 while (end < (Int_t)len) {
01176 if (isalnum(line[end]) || line[end] == ' ' || line[end] == '\t') {
01177 break;
01178 } else {
01179 ++end;
01180 }
01181 }
01182 }
01183
01184 fMarkedStart.fX = start;
01185 fIsMarked = kTRUE;
01186 fMarkedEnd.fX = end;
01187 Marked(kTRUE);
01188
01189 len = end - start;
01190 char *word = new char[len + 1];
01191 word[len] = '\0';
01192 strncpy(word, line+start, (UInt_t)len);
01193 DoubleClicked((const char *)word);
01194
01195 delete [] word;
01196
01197
01198 UpdateRegion(0, (Int_t)ToScrYCoord(fMarkedStart.fY), fCanvas->GetWidth(),
01199 UInt_t(ToScrYCoord(fMarkedEnd.fY + 1) - ToScrYCoord(fMarkedStart.fY)));
01200
01201 return kTRUE;
01202 }
01203
01204
01205 Bool_t TGTextEdit::HandleMotion(Event_t *event)
01206 {
01207
01208
01209 TGLongPosition pos;
01210 if (event->fWindow != fCanvas->GetId()) {
01211 return kTRUE;
01212 }
01213
01214 if (fScrolling == -1) {
01215 pos.fY = ToObjYCoord(fVisible.fY+event->fY);
01216 if (pos.fY >= fText->RowCount()) {
01217 pos.fY = fText->RowCount()-1;
01218 }
01219 pos.fX = ToObjXCoord(fVisible.fX+event->fX, pos.fY);
01220 if (pos.fX > fText->GetLineLength(pos.fY)) {
01221 pos.fX = fText->GetLineLength(pos.fY);
01222 }
01223 if (fText->GetChar(pos) == 16) {
01224 if (pos.fX < fCurrent.fX) {
01225 pos.fX = fCurrent.fX;
01226 }
01227 if (pos.fX > fCurrent.fX) {
01228 do {
01229 pos.fX++;
01230 } while (fText->GetChar(pos) == 16);
01231 }
01232 }
01233 event->fY = (Int_t)ToScrYCoord(pos.fY);
01234 event->fX = (Int_t)ToScrXCoord(pos.fX, pos.fY);
01235 if (pos.fY != fCurrent.fY || pos.fX != fCurrent.fX) {
01236 TGTextView::HandleMotion(event);
01237 SetCurrent(pos);
01238 }
01239 }
01240 return kTRUE;
01241 }
01242
01243
01244 Bool_t TGTextEdit::HandleKey(Event_t *event)
01245 {
01246
01247
01248
01249 Bool_t mark_ok = kFALSE;
01250 char input[10];
01251 Int_t n;
01252 UInt_t keysym;
01253
01254 if (event->fType == kGKeyPress) {
01255 gVirtualX->LookupString(event, input, sizeof(input), keysym);
01256 n = strlen(input);
01257
01258 AdjustPos();
01259
01260 switch ((EKeySym)keysym) {
01261 case kKey_Shift:
01262 case kKey_Control:
01263 case kKey_Meta:
01264 case kKey_Alt:
01265 case kKey_CapsLock:
01266 case kKey_NumLock:
01267 case kKey_ScrollLock:
01268 return kTRUE;
01269 default:
01270 break;
01271 }
01272 if (event->fState & kKeyControlMask) {
01273 switch((EKeySym)keysym & ~0x20) {
01274 case kKey_A:
01275 SelectAll();
01276 return kTRUE;
01277 case kKey_B:
01278 mark_ok = kTRUE;
01279 PrevChar();
01280 break;
01281 case kKey_C:
01282 Copy();
01283 return kTRUE;
01284 case kKey_D:
01285 if (fIsMarked) {
01286 Cut();
01287 } else {
01288 Long_t len = fText->GetLineLength(fCurrent.fY);
01289 if (fCurrent.fY == fText->RowCount()-1 && fCurrent.fX == len) {
01290 gVirtualX->Bell(0);
01291 return kTRUE;
01292 }
01293 NextChar();
01294 new TDelCharCom(this);
01295 }
01296 break;
01297 case kKey_E:
01298 mark_ok = kTRUE;
01299 End();
01300 break;
01301 case kKey_H:
01302 if (fCurrent.fX || fCurrent.fY) new TDelCharCom(this);
01303 else gVirtualX->Bell(0);
01304 break;
01305 case kKey_K:
01306 End();
01307 fIsMarked = kTRUE;
01308 Mark(fCurrent.fX, fCurrent.fY);
01309 Cut();
01310 break;
01311 case kKey_U:
01312 Home();
01313 UnMark();
01314 fMarkedStart.fY = fMarkedEnd.fY = fCurrent.fY;
01315 fMarkedStart.fX = fMarkedEnd.fX = fCurrent.fX;
01316 End();
01317 fIsMarked = kTRUE;
01318 Mark(fCurrent.fX, fCurrent.fY);
01319 Cut();
01320 break;
01321 case kKey_V:
01322 case kKey_Y:
01323 Paste();
01324 return kTRUE;
01325 case kKey_X:
01326 Cut();
01327 return kTRUE;
01328 case kKey_Z:
01329 fHistory->Notify();
01330 return kTRUE;
01331 case kKey_F:
01332 Search(kFALSE);
01333 return kTRUE;
01334 case kKey_L:
01335 {
01336 Long_t ret = fCurrent.fY+1;
01337 new TGGotoDialog(fClient->GetDefaultRoot(), this, 400, 150, &ret);
01338 if (ret > -1) {
01339 ret--;
01340 Goto(ret);
01341 }
01342 return kTRUE;
01343 }
01344 case kKey_Home:
01345 {
01346 TGLongPosition pos;
01347 pos.fY = 0;
01348 pos.fX = 0;
01349 SetHsbPosition(0);
01350 SetVsbPosition(0);
01351 SetCurrent(pos);
01352 }
01353 break;
01354 case kKey_End:
01355 {
01356 TGLongPosition pos;
01357 pos.fY = fText->RowCount()-1;
01358 pos.fX = fText->GetLineLength(pos.fY);
01359 if (fVsb && fVsb->IsMapped())
01360 SetVsbPosition((ToScrYCoord(pos.fY)+fVisible.fY)/fScrollVal.fY);
01361 SetCurrent(pos);
01362 }
01363 break;
01364 default:
01365 return kTRUE;
01366 }
01367 }
01368 if (n && keysym >= 32 && keysym < 127 &&
01369 !(event->fState & kKeyControlMask) &&
01370 (EKeySym)keysym != kKey_Delete &&
01371 (EKeySym)keysym != kKey_Backspace) {
01372
01373 if (fIsMarked) {
01374 Cut();
01375 }
01376 new TInsCharCom(this, input[0]);
01377
01378 } else {
01379
01380 switch ((EKeySym)keysym) {
01381 case kKey_F3:
01382
01383 SendMessage(fMsgWindow, MK_MSG(kC_TEXTVIEW, kTXT_F3), fWidgetId,
01384 kTRUE);
01385 SetMenuState();
01386 if (fMenu->IsEntryEnabled(kM_SEARCH_FINDAGAIN)) {
01387 SendMessage(this, MK_MSG(kC_COMMAND, kCM_MENU),
01388 kM_SEARCH_FINDAGAIN, 0);
01389 FindAgain();
01390 }
01391 break;
01392 case kKey_Delete:
01393 if (fIsMarked) {
01394 Cut();
01395 } else {
01396 Long_t len = fText->GetLineLength(fCurrent.fY);
01397 if (fCurrent.fY == fText->RowCount()-1 && fCurrent.fX == len) {
01398 gVirtualX->Bell(0);
01399 return kTRUE;
01400 }
01401 NextChar();
01402 new TDelCharCom(this);
01403 }
01404 break;
01405 case kKey_Return:
01406 case kKey_Enter:
01407 new TBreakLineCom(this);
01408 break;
01409 case kKey_Tab:
01410 new TInsCharCom(this, '\t');
01411 break;
01412 case kKey_Backspace:
01413 if (fIsMarked) {
01414 Cut();
01415 } else {
01416 if (fCurrent.fX || fCurrent.fY) {
01417 new TDelCharCom(this);
01418 } else {
01419 gVirtualX->Bell(0);
01420 }
01421 }
01422 break;
01423 case kKey_Left:
01424 mark_ok = kTRUE;
01425 PrevChar();
01426 break;
01427 case kKey_Right:
01428 mark_ok = kTRUE;
01429 NextChar();
01430 break;
01431 case kKey_Up:
01432 mark_ok = kTRUE;
01433 LineUp();
01434 break;
01435 case kKey_Down:
01436 mark_ok = kTRUE;
01437 LineDown();
01438 break;
01439 case kKey_PageUp:
01440 mark_ok = kTRUE;
01441 ScreenUp();
01442 break;
01443 case kKey_PageDown:
01444 mark_ok = kTRUE;
01445 ScreenDown();
01446 break;
01447 case kKey_Home:
01448 mark_ok = kTRUE;
01449 Home();
01450 break;
01451 case kKey_End:
01452 mark_ok = kTRUE;
01453 End();
01454 break;
01455 case kKey_Insert:
01456 SetInsertMode(GetInsertMode() == kInsert ? kReplace : kInsert);
01457 break;
01458 default:
01459 break;
01460 }
01461 }
01462 if ((event->fState & kKeyShiftMask) && mark_ok) {
01463 fIsMarked = kTRUE;
01464 Mark(fCurrent.fX, fCurrent.fY);
01465 Copy();
01466 SendMessage(fMsgWindow, MK_MSG(kC_TEXTVIEW, kTXT_ISMARKED), fWidgetId,
01467 kTRUE);
01468 Marked(kTRUE);
01469 } else {
01470 UnMark();
01471 SendMessage(fMsgWindow, MK_MSG(kC_TEXTVIEW, kTXT_ISMARKED),
01472 fWidgetId, kFALSE);
01473 fMarkedStart.fY = fMarkedEnd.fY = fCurrent.fY;
01474 fMarkedStart.fX = fMarkedEnd.fX = fCurrent.fX;
01475 }
01476 }
01477 return kTRUE;
01478 }
01479
01480
01481 Bool_t TGTextEdit::HandleCrossing(Event_t *event)
01482 {
01483
01484
01485 if (event->fWindow != fCanvas->GetId()) {
01486 return kTRUE;
01487 }
01488 if (gVirtualX->GetInputFocus() != fCanvas->GetId()) {
01489 if (event->fType == kEnterNotify) {
01490 if (!fCurBlink) {
01491 fCurBlink = new TViewTimer(this, 500);
01492 }
01493 fCurBlink->Reset();
01494 gSystem->AddTimer(fCurBlink);
01495 } else {
01496 if (fCurBlink) fCurBlink->Remove();
01497 if (!fEnableCursorWithoutFocus && (fCursorState == 1)) {
01498 DrawCursor(2);
01499 fCursorState = 2;
01500 } else if (fCursorState == 2) {
01501 DrawCursor(1);
01502 fCursorState = 1;
01503 }
01504 }
01505 }
01506
01507 TGTextView::HandleCrossing(event);
01508
01509 return kTRUE;
01510 }
01511
01512
01513 Bool_t TGTextEdit::HandleFocusChange(Event_t *event)
01514 {
01515
01516
01517 if (event->fWindow != fCanvas->GetId()) {
01518 return kTRUE;
01519 }
01520
01521
01522 if ((event->fCode == kNotifyNormal) && (event->fState != kNotifyPointer)) {
01523 if (event->fType == kFocusIn) {
01524 if (!fCurBlink) {
01525 fCurBlink = new TViewTimer(this, 500);
01526 }
01527 fCurBlink->Reset();
01528 gSystem->AddTimer(fCurBlink);
01529 } else {
01530 if (fCurBlink) fCurBlink->Remove();
01531 if (fCursorState == 2) {
01532 DrawCursor(1);
01533 fCursorState = 1;
01534 }
01535 }
01536 fClient->NeedRedraw(this);
01537 }
01538 return kTRUE;
01539 }
01540
01541
01542 void TGTextEdit::Search(Bool_t close)
01543 {
01544
01545
01546 static TGSearchType *srch = 0;
01547 Int_t ret = 0;
01548
01549 if (!srch) srch = new TGSearchType;
01550 srch->fClose = close;
01551
01552 if (!close) {
01553 if (!TGSearchDialog::SearchDialog()) {
01554 TGSearchDialog::SearchDialog() = new TGSearchDialog(fClient->GetDefaultRoot(),
01555 fCanvas, 400, 150, srch, &ret);
01556 }
01557 TGSearchDialog::SearchDialog()->Connect("TextEntered(char *)", "TGTextEdit",
01558 this, "Search(char *,Bool_t,Bool_t)");
01559 TGSearchDialog::SearchDialog()->MapRaised();
01560 } else {
01561 new TGSearchDialog(fClient->GetDefaultRoot(), fCanvas, 400, 150, srch, &ret);
01562 if (ret) {
01563 Search(srch->fBuffer);
01564 }
01565 }
01566 }
01567
01568
01569 Bool_t TGTextEdit::ProcessMessage(Long_t msg, Long_t parm1, Long_t parm2)
01570 {
01571
01572
01573 TString msg2;
01574 TGTextView::ProcessMessage(msg, parm1, parm2);
01575
01576 switch(GET_MSG(msg)) {
01577 case kC_COMMAND:
01578 switch(GET_SUBMSG(msg)) {
01579 case kCM_MENU:
01580 switch (parm1) {
01581 case kM_FILE_NEW:
01582 case kM_FILE_CLOSE:
01583 case kM_FILE_OPEN:
01584 if (!IsSaved()) {
01585 Int_t retval;
01586 Bool_t untitled = !strlen(fText->GetFileName()) ? kTRUE : kFALSE;
01587
01588 msg2.Form("Save \"%s\"?",
01589 untitled ? "Untitled" : fText->GetFileName());
01590 new TGMsgBox(fClient->GetDefaultRoot(), this, "Editor",
01591 msg2.Data(), kMBIconExclamation,
01592 kMBYes | kMBNo | kMBCancel, &retval);
01593
01594 if (retval == kMBCancel)
01595 return kTRUE;
01596 if (retval == kMBYes)
01597 if (!SaveFile(0))
01598 return kTRUE;
01599 }
01600 Clear();
01601 if (parm1 == kM_FILE_CLOSE) {
01602 SendMessage(fMsgWindow, MK_MSG(kC_TEXTVIEW, kTXT_CLOSE),
01603 fWidgetId, 0);
01604 Closed();
01605 }
01606 if (parm1 == kM_FILE_OPEN) {
01607 TGFileInfo fi;
01608 fi.fFileTypes = gFiletypes;
01609 new TGFileDialog(fClient->GetDefaultRoot(), this, kFDOpen, &fi);
01610 if (fi.fFilename && strlen(fi.fFilename)) {
01611 LoadFile(fi.fFilename);
01612 SendMessage(fMsgWindow, MK_MSG(kC_TEXTVIEW, kTXT_OPEN),
01613 fWidgetId, 0);
01614 Opened();
01615 }
01616 }
01617 break;
01618 case kM_FILE_SAVE:
01619 if (SaveFile(0)) {
01620 SendMessage(fMsgWindow, MK_MSG(kC_TEXTVIEW, kTXT_SAVE),
01621 fWidgetId, 0);
01622 Saved();
01623 }
01624 break;
01625 case kM_FILE_SAVEAS:
01626 if (SaveFile(0, kTRUE)) {
01627 SendMessage(fMsgWindow, MK_MSG(kC_TEXTVIEW, kTXT_SAVE),
01628 fWidgetId, 0);
01629 SavedAs();
01630 }
01631 break;
01632 case kM_FILE_PRINT:
01633 {
01634 Int_t ret = 0;
01635 if (!gPrinter) {
01636 gPrinter = StrDup("892_2_cor");
01637 gPrintCommand = StrDup("xprint");
01638 }
01639 new TGPrintDialog(fClient->GetDefaultRoot(), this, 400, 150,
01640 &gPrinter, &gPrintCommand, &ret);
01641 if (ret)
01642 Print();
01643 }
01644 break;
01645 case kM_EDIT_CUT:
01646 Cut();
01647 break;
01648 case kM_EDIT_COPY:
01649 Copy();
01650 break;
01651 case kM_EDIT_PASTE:
01652 Paste();
01653 break;
01654 case kM_EDIT_SELECTALL:
01655 SelectAll();
01656 break;
01657 case kM_SEARCH_FIND:
01658 {
01659 Search(kFALSE);
01660 }
01661 break;
01662 case kM_SEARCH_FINDAGAIN:
01663 if (!fSearch) {
01664 SendMessage(this, MK_MSG(kC_COMMAND, kCM_MENU),
01665 kM_SEARCH_FIND, 0);
01666 return kTRUE;
01667 }
01668 if (!Search(fSearch->fBuffer, fSearch->fDirection,
01669 fSearch->fCaseSensitive)) {
01670 msg2.Form("Couldn't find \"%s\"", fSearch->fBuffer);
01671 new TGMsgBox(fClient->GetDefaultRoot(), this, "Editor",
01672 msg2.Data(), kMBIconExclamation, kMBOk, 0);
01673 }
01674 break;
01675 case kM_SEARCH_GOTO:
01676 {
01677 Long_t ret = fCurrent.fY+1;
01678 new TGGotoDialog(fClient->GetDefaultRoot(), this, 400, 150, &ret);
01679 if (ret > -1) {
01680 ret--;
01681 Goto(ret);
01682 }
01683 }
01684 break;
01685 default:
01686 printf("No action implemented for menu id %ld\n", parm1);
01687 break;
01688 }
01689 default:
01690 break;
01691 }
01692 break;
01693
01694 default:
01695 break;
01696 }
01697 return kTRUE;
01698 }
01699
01700
01701 void TGTextEdit::InsChar(char character)
01702 {
01703
01704
01705 if (fReadOnly) return;
01706
01707 char *charstring = 0;
01708 TGLongPosition pos;
01709
01710 if (character == '\t') {
01711 pos.fX = fCurrent.fX;
01712 pos.fY = fCurrent.fY;
01713 fText->InsChar(pos, '\t');
01714 pos.fX++;
01715 while (pos.fX & 0x7) {
01716 pos.fX++;
01717 }
01718 fText->ReTab(pos.fY);
01719 UpdateRegion(0, (Int_t)ToScrYCoord(pos.fY), fCanvas->GetWidth(),
01720 UInt_t(ToScrYCoord(pos.fY+1) - ToScrYCoord(pos.fY)));
01721 SetSBRange(kHorizontal);
01722 if (ToScrXCoord(pos.fX, pos.fY) >= (Int_t)fCanvas->GetWidth()) {
01723 if (pos.fX != fText->GetLineLength(fCurrent.fY)) {
01724 SetHsbPosition((fVisible.fX+fCanvas->GetWidth()/2)/fScrollVal.fX);
01725 } else {
01726 SetHsbPosition(fVisible.fX/fScrollVal.fX);
01727 }
01728 }
01729 SetCurrent(pos);
01730 return;
01731 } else {
01732 if (fInsertMode == kReplace) {
01733 fCurrent.fX++;
01734 new TDelCharCom(this);
01735 }
01736 fText->InsChar(fCurrent, character);
01737 pos.fX = fCurrent.fX + 1;
01738 pos.fY = fCurrent.fY;
01739 charstring = new char[2];
01740 charstring[1] = '\0';
01741 charstring[0] = character;
01742 }
01743 SetSBRange(kHorizontal);
01744 if (ToScrXCoord(pos.fX, pos.fY) >= (Int_t)fCanvas->GetWidth()) {
01745 if (pos.fX != fText->GetLineLength(fCurrent.fY)) {
01746 SetHsbPosition((fVisible.fX+fCanvas->GetWidth()/2)/fScrollVal.fX);
01747 } else {
01748 SetHsbPosition(fVisible.fX/fScrollVal.fX+strlen(charstring));
01749 }
01750 if (!fHsb)
01751 gVirtualX->DrawString(fCanvas->GetId(), fNormGC(),
01752 (Int_t)ToScrXCoord(fCurrent.fX, fCurrent.fY),
01753 Int_t(ToScrYCoord(fCurrent.fY+1) - fMaxDescent),
01754 charstring, strlen(charstring));
01755 } else {
01756 gVirtualX->CopyArea(fCanvas->GetId(), fCanvas->GetId(), fNormGC(),
01757 (Int_t)ToScrXCoord(fCurrent.fX, fCurrent.fY),
01758 (Int_t)ToScrYCoord(fCurrent.fY), fCanvas->GetWidth(),
01759 UInt_t(ToScrYCoord(fCurrent.fY+1)-ToScrYCoord(fCurrent.fY)),
01760 (Int_t)ToScrXCoord(pos.fX, fCurrent.fY),
01761 (Int_t)ToScrYCoord(fCurrent.fY));
01762 gVirtualX->ClearArea(fCanvas->GetId(),
01763 Int_t(ToScrXCoord(fCurrent.fX, fCurrent.fY)),
01764 Int_t(ToScrYCoord(fCurrent.fY)),
01765 UInt_t(ToScrXCoord(fCurrent.fX+strlen(charstring), fCurrent.fY) -
01766 ToScrXCoord(fCurrent.fX, fCurrent.fY)),
01767 UInt_t(ToScrYCoord(fCurrent.fY+1)-ToScrYCoord(fCurrent.fY)));
01768 gVirtualX->DrawString(fCanvas->GetId(), fNormGC(),
01769 Int_t(ToScrXCoord(fCurrent.fX, fCurrent.fY)),
01770 Int_t(ToScrYCoord(fCurrent.fY+1) - fMaxDescent),
01771 charstring, strlen(charstring));
01772 fCursorState = 2;
01773 }
01774 delete [] charstring;
01775 SetCurrent(pos);
01776 }
01777
01778
01779 void TGTextEdit::DelChar()
01780 {
01781
01782
01783 if (fReadOnly) {
01784 return;
01785 }
01786
01787 char *buffer;
01788 TGLongPosition pos, pos2;
01789 Long_t len;
01790
01791 pos.fY = fCurrent.fY;
01792 pos.fX = fCurrent.fX;
01793 UInt_t h = 0;
01794
01795 if (fCurrent.fX > 0) {
01796 Int_t y = (Int_t)ToScrYCoord(pos.fY);
01797 h = UInt_t(ToScrYCoord(pos.fY+2) - y);
01798 if (!y) h = h << 1;
01799
01800 pos.fX--;
01801
01802 if (fText->GetChar(pos) == 16) {
01803 do {
01804 pos.fX++;
01805 fText->DelChar(pos);
01806 pos.fX -= 2;
01807 } while (fText->GetChar(pos) != '\t');
01808
01809 pos.fX++;
01810 fText->DelChar(pos);
01811 pos.fX--;
01812 fText->ReTab(pos.fY);
01813 UpdateRegion(0, y, fCanvas->GetWidth(), h);
01814 } else {
01815 pos.fX = fCurrent.fX;
01816 fText->DelChar(pos);
01817 pos.fX = fCurrent.fX - 1;
01818 }
01819 if (ToScrXCoord(fCurrent.fX-1, fCurrent.fY) < 0) {
01820 SetHsbPosition((fVisible.fX-fCanvas->GetWidth()/2)/fScrollVal.fX);
01821 }
01822 SetSBRange(kHorizontal);
01823 UpdateRegion(0, y, fCanvas->GetWidth(), h);
01824 } else {
01825 if (fCurrent.fY > 0) {
01826 len = fText->GetLineLength(fCurrent.fY);
01827 if (len > 0) {
01828 buffer = fText->GetLine(fCurrent, len);
01829 pos.fY--;
01830 pos.fX = fText->GetLineLength(fCurrent.fY-1);
01831 fText->InsText(pos, buffer);
01832 pos.fY++;
01833 delete [] buffer;
01834 } else {
01835 pos.fX = fText->GetLineLength(fCurrent.fY-1);
01836 }
01837
01838 pos2.fY = ToScrYCoord(fCurrent.fY+1);
01839 pos.fY = fCurrent.fY - 1;
01840 fText->DelLine(fCurrent.fY);
01841 len = fText->GetLineLength(fCurrent.fY-1);
01842
01843 if (ToScrXCoord(pos.fX, fCurrent.fY-1) >= (Int_t)fCanvas->GetWidth()) {
01844 SetHsbPosition((ToScrXCoord(pos.fX, pos.fY)+fVisible.fX-fCanvas->GetWidth()/2)/fScrollVal.fX);
01845 }
01846
01847 h = UInt_t(fCanvas->GetHeight() - ToScrYCoord(fCurrent.fY));
01848
01849 gVirtualX->CopyArea(fCanvas->GetId(), fCanvas->GetId(), fNormGC(), 0,
01850 Int_t(pos2.fY), fWidth, h, 0, (Int_t)ToScrYCoord(fCurrent.fY));
01851 if (ToScrYCoord(pos.fY) < 0) {
01852 SetVsbPosition(fVisible.fY/fScrollVal.fY-1);
01853 }
01854 UpdateRegion(0, (Int_t)ToScrYCoord(pos.fY), fCanvas->GetWidth(), h);
01855 SetSBRange(kVertical);
01856 SetSBRange(kHorizontal);
01857 }
01858 }
01859 SetCurrent(pos);
01860 }
01861
01862
01863 void TGTextEdit::BreakLine()
01864 {
01865
01866
01867 if (fReadOnly) return;
01868
01869 TGLongPosition pos;
01870 fText->BreakLine(fCurrent);
01871 if (ToScrYCoord(fCurrent.fY+2) <= (Int_t)fCanvas->GetHeight()) {
01872 gVirtualX->CopyArea(fCanvas->GetId(), fCanvas->GetId(), fNormGC(), 0,
01873 (Int_t)ToScrYCoord(fCurrent.fY+1), fCanvas->GetWidth(),
01874 UInt_t(fCanvas->GetHeight()-(ToScrYCoord(fCurrent.fY+2)-
01875 ToScrYCoord(fCurrent.fY))),
01876 0, (Int_t)ToScrYCoord(fCurrent.fY+2));
01877 UpdateRegion(0, (Int_t)ToScrYCoord(fCurrent.fY), fCanvas->GetWidth(),
01878 UInt_t(ToScrYCoord(fCurrent.fY+2) - ToScrYCoord(fCurrent.fY)));
01879
01880 if (fVisible.fX != 0) {
01881 SetHsbPosition(0);
01882 }
01883 SetSBRange(kHorizontal);
01884 SetSBRange(kVertical);
01885 } else {
01886 SetSBRange(kHorizontal);
01887 SetSBRange(kVertical);
01888 SetVsbPosition(fVisible.fY/fScrollVal.fY + 1);
01889 UpdateRegion(0, (Int_t)ToScrYCoord(fCurrent.fY), fCanvas->GetWidth(),
01890 UInt_t(ToScrYCoord(fCurrent.fY+1) - ToScrYCoord(fCurrent.fY)));
01891 }
01892 pos.fY = fCurrent.fY+1;
01893 pos.fX = 0;
01894 SetCurrent(pos);
01895 }
01896
01897
01898 void TGTextEdit::ScrollCanvas(Int_t new_top, Int_t direction)
01899 {
01900
01901
01902 CursorOff();
01903
01904 TGTextView::ScrollCanvas(new_top, direction);
01905
01906 CursorOn();
01907 }
01908
01909
01910 void TGTextEdit::DrawRegion(Int_t x, Int_t y, UInt_t width, UInt_t height)
01911 {
01912
01913
01914 CursorOff();
01915
01916 TGTextView::DrawRegion(x, y, width, height);
01917
01918 CursorOn();
01919 }
01920
01921
01922 void TGTextEdit::PrevChar()
01923 {
01924
01925
01926 if (fCurrent.fY == 0 && fCurrent.fX == 0) {
01927 gVirtualX->Bell(0);
01928 return;
01929 }
01930
01931 TGLongPosition pos;
01932 Long_t len;
01933
01934 pos.fY = fCurrent.fY;
01935 pos.fX = fCurrent.fX;
01936 if (fCurrent.fX > 0) {
01937 pos.fX--;
01938 while (fText->GetChar(pos) == 16) {
01939 pos.fX--;
01940 }
01941
01942 if (ToScrXCoord(pos.fX, pos.fY) < 0) {
01943 if (fVisible.fX-(Int_t)fCanvas->GetWidth()/2 >= 0) {
01944 SetHsbPosition((fVisible.fX-fCanvas->GetWidth()/2)/fScrollVal.fX);
01945 } else {
01946 SetHsbPosition(0);
01947 }
01948 }
01949 } else {
01950 if (fCurrent.fY > 0) {
01951 pos.fY = fCurrent.fY - 1;
01952 len = fText->GetLineLength(pos.fY);
01953 if (ToScrYCoord(fCurrent.fY) <= 0) {
01954 SetVsbPosition(fVisible.fY/fScrollVal.fY-1);
01955 }
01956 if (ToScrXCoord(len, pos.fY) >= (Int_t)fCanvas->GetWidth()) {
01957 SetHsbPosition((ToScrXCoord(len, pos.fY)+fVisible.fX -
01958 fCanvas->GetWidth()/2)/fScrollVal.fX);
01959 }
01960 pos.fX = len;
01961 }
01962 }
01963 SetCurrent(pos);
01964 }
01965
01966
01967 void TGTextEdit::NextChar()
01968 {
01969
01970
01971 Long_t len = fText->GetLineLength(fCurrent.fY);
01972
01973 if (fCurrent.fY == fText->RowCount()-1 && fCurrent.fX == len) {
01974 gVirtualX->Bell(0);
01975 return;
01976 }
01977
01978 TGLongPosition pos;
01979 pos.fY = fCurrent.fY;
01980 if (fCurrent.fX < len) {
01981 if (fText->GetChar(fCurrent) == '\t') {
01982 pos.fX = fCurrent.fX + 8 - (fCurrent.fX & 0x7);
01983 } else {
01984 pos.fX = fCurrent.fX + 1;
01985 }
01986
01987 if (ToScrXCoord(pos.fX, pos.fY) >= (Int_t)fCanvas->GetWidth()) {
01988 SetHsbPosition(fVisible.fX/fScrollVal.fX+(fCanvas->GetWidth()/2)/fScrollVal.fX);
01989 }
01990 } else {
01991 if (fCurrent.fY < fText->RowCount()-1) {
01992 pos.fY = fCurrent.fY + 1;
01993 if (ToScrYCoord(pos.fY+1) >= (Int_t)fCanvas->GetHeight()) {
01994 SetVsbPosition(fVisible.fY/fScrollVal.fY+1);
01995 }
01996 SetHsbPosition(0);
01997 pos.fX = 0;
01998 }
01999 }
02000 SetCurrent(pos);
02001 }
02002
02003
02004 void TGTextEdit::LineUp()
02005 {
02006
02007
02008 TGLongPosition pos;
02009 Long_t len;
02010 if (fCurrent.fY > 0) {
02011 pos.fY = fCurrent.fY - 1;
02012 if (ToScrYCoord(fCurrent.fY) <= 0) {
02013 SetVsbPosition(fVisible.fY/fScrollVal.fY-1);
02014 }
02015 len = fText->GetLineLength(fCurrent.fY-1);
02016 if (fCurrent.fX > len) {
02017 if (ToScrXCoord(len, pos.fY) <= 0) {
02018 if (ToScrXCoord(len, pos.fY) < 0) {
02019 SetHsbPosition(ToScrXCoord(len, pos.fY)+
02020 (fVisible.fX-fCanvas->GetWidth()/2)/fScrollVal.fX);
02021 } else {
02022 SetHsbPosition(0);
02023 }
02024 }
02025 pos.fX = len;
02026 } else {
02027 pos.fX = ToObjXCoord(ToScrXCoord(fCurrent.fX, fCurrent.fY)+fVisible.fX, pos.fY);
02028 }
02029
02030 while (fText->GetChar(pos) == 16) {
02031 pos.fX++;
02032 }
02033 SetCurrent(pos);
02034 }
02035 }
02036
02037
02038 void TGTextEdit::LineDown()
02039 {
02040
02041
02042 TGLongPosition pos;
02043 Long_t len;
02044 if (fCurrent.fY < fText->RowCount()-1) {
02045 len = fText->GetLineLength(fCurrent.fY+1);
02046 pos.fY = fCurrent.fY + 1;
02047 if (ToScrYCoord(pos.fY+1) > (Int_t)fCanvas->GetHeight()) {
02048 SetVsbPosition(fVisible.fY/fScrollVal.fY+1);
02049 }
02050 if (fCurrent.fX > len) {
02051 if (ToScrXCoord(len, pos.fY) <= 0) {
02052 if (ToScrXCoord(len, pos.fY) < 0) {
02053 SetHsbPosition((ToScrXCoord(len, pos.fY)+fVisible.fX-fCanvas->GetWidth()/2)/fScrollVal.fX);
02054 } else {
02055 SetHsbPosition(0);
02056 }
02057 }
02058 pos.fX = len;
02059 } else {
02060 pos.fX = ToObjXCoord(ToScrXCoord(fCurrent.fX, fCurrent.fY)+fVisible.fX, pos.fY);
02061 }
02062
02063 while (fText->GetChar(pos) == 16) {
02064 pos.fX++;
02065 }
02066 SetCurrent(pos);
02067 }
02068 }
02069
02070
02071 void TGTextEdit::ScreenUp()
02072 {
02073
02074
02075 TGLongPosition pos;
02076 pos.fX = fCurrent.fX;
02077 pos.fY = fCurrent.fY - (ToObjYCoord(fCanvas->GetHeight())-ToObjYCoord(0))-1;
02078 if (fVisible.fY - (Int_t)fCanvas->GetHeight() >= 0) {
02079 SetVsbPosition((fVisible.fY - fCanvas->GetHeight())/fScrollVal.fY);
02080 } else {
02081 pos.fY = 0;
02082 SetVsbPosition(0);
02083 }
02084 while (fText->GetChar(pos) == 16) {
02085 pos.fX++;
02086 }
02087 SetCurrent(pos);
02088 }
02089
02090
02091 void TGTextEdit::ScreenDown()
02092 {
02093
02094
02095 TGLongPosition pos;
02096 pos.fX = fCurrent.fX;
02097 pos.fY = fCurrent.fY + (ToObjYCoord(fCanvas->GetHeight()) - ToObjYCoord(0));
02098 Long_t count = fText->RowCount()-1;
02099 if ((Int_t)fCanvas->GetHeight() < ToScrYCoord(count)) {
02100 SetVsbPosition((fVisible.fY+fCanvas->GetHeight())/fScrollVal.fY);
02101 } else {
02102 pos.fY = count;
02103 }
02104 while (fText->GetChar(pos) == 16) {
02105 pos.fX++;
02106 }
02107 SetCurrent(pos);
02108 }
02109
02110
02111 void TGTextEdit::Home()
02112 {
02113
02114
02115 TGLongPosition pos;
02116 pos.fY = fCurrent.fY;
02117 pos.fX = 0;
02118 SetHsbPosition(0);
02119 SetCurrent(pos);
02120 }
02121
02122
02123 void TGTextEdit::End()
02124 {
02125
02126
02127 TGLongPosition pos;
02128 pos.fY = fCurrent.fY;
02129 pos.fX = fText->GetLineLength(pos.fY);
02130 if (ToScrXCoord(pos.fX, pos.fY) >= (Int_t)fCanvas->GetWidth()) {
02131 SetHsbPosition((ToScrXCoord(pos.fX, pos.fY) + fVisible.fX - fCanvas->GetWidth()/2)/fScrollVal.fX);
02132 }
02133 SetCurrent(pos);
02134 }
02135
02136
02137 const TGGC &TGTextEdit::GetCursor0GC()
02138 {
02139
02140
02141 if (!fgCursor0GC) {
02142 fgCursor0GC = new TGGC(GetDefaultSelectedGC());
02143 fgCursor0GC->SetFunction(kGXxor);
02144 }
02145 return *fgCursor0GC;
02146 }
02147
02148
02149 const TGGC &TGTextEdit::GetCursor1GC()
02150 {
02151
02152
02153 if (!fgCursor1GC) {
02154 fgCursor1GC = new TGGC(GetDefaultGC());
02155 fgCursor1GC->SetFunction(kGXand);
02156 }
02157 return *fgCursor1GC;
02158 }
02159
02160
02161 void TGTextEdit::SavePrimitive(ostream &out, Option_t *option )
02162 {
02163
02164
02165 char quote = '"';
02166 out << " TGTextEdit *";
02167 out << GetName() << " = new TGTextEdit(" << fParent->GetName()
02168 << "," << GetWidth() << "," << GetHeight()
02169 << ");"<< endl;
02170 if (option && strstr(option, "keep_names"))
02171 out << " " << GetName() << "->SetName(\"" << GetName() << "\");" << endl;
02172
02173 if (IsReadOnly()) {
02174 out << " " << GetName() << "->SetReadOnly(kTRUE);" << endl;
02175 }
02176
02177 if (!IsMenuEnabled()) {
02178 out << " " << GetName() << "->EnableMenu(kFALSE);" << endl;
02179 }
02180
02181 if (fCanvas->GetBackground() != TGFrame::fgWhitePixel) {
02182 out << " " << GetName() << "->ChangeBackground(" << fCanvas->GetBackground() << ");" << endl;
02183 }
02184
02185 TGText *txt = GetText();
02186 Bool_t fromfile = strlen(txt->GetFileName()) ? kTRUE : kFALSE;
02187 TString fn;
02188
02189 if (fromfile) {
02190 const char *filename = txt->GetFileName();
02191 fn = gSystem->ExpandPathName(gSystem->UnixPathName(filename));
02192 } else {
02193 fn = TString::Format("Txt%s", GetName()+5);
02194 txt->Save(fn.Data());
02195 }
02196 out << " " << GetName() << "->LoadFile(" << quote << fn.Data() << quote << ");" << endl;
02197 }