TGTextEditor.cxx

Go to the documentation of this file.
00001 // @(#)root/gui:$Id: TGTextEditor.cxx 33875 2010-06-14 12:57:10Z bellenot $
00002 // Author: Bertrand Bellenot   20/06/06
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 //  TGTextEditor                                                        //
00026 //                                                                      //
00027 //  A simple text editor that uses the TGTextEdit widget.               //
00028 //  It provides all functionalities of TGTextEdit as copy, paste, cut,  //
00029 //  search, go to a given line number. In addition, it provides the     //
00030 //  possibilities for compiling, executing or interrupting a running    //
00031 //  macro.                                                              //
00032 //                                                                      //
00033 //  This class can be used in following ways:                           //
00034 //  - with file name as argument:                                       //
00035 //    new TGTextEditor("hsimple.C");                                    //
00036 //  - with a TMacro* as argument:                                       //
00037 //    TMacro *macro = new TMacro("hsimple.C");                          //
00038 //    new TGTextEditor(macro);                                          //
00039 //                                                                      //
00040 //  Basic Features:                                                     //
00041 //                                                                      //
00042 //  New Document                                                        //
00043 //                                                                      //
00044 //  To create a new blank document, select File menu / New, or click    //
00045 //  the New toolbar button. It will create a new instance of            //
00046 //  TGTextEditor.                                                       //
00047 //                                                                      //
00048 //  Open/Save File                                                      //
00049 //                                                                      //
00050 //  To open a file, select File menu / Open or click on the Open        //
00051 //  toolbar button. This will bring up the standard File Dialog for     //
00052 //  opening files.                                                      //
00053 //  If the current document has not been saved yet, you will be asked   //
00054 //  either to save or abandon the changes.                              //
00055 //  To save the file using the same name, select File menu / Save or    //
00056 //  the toolbar Save button. To change the file name use File menu /    //
00057 //  Save As... or corresponding SaveAs button on the toolbar.           //
00058 //                                                                      //
00059 //  Text Selection                                                      //
00060 //                                                                      //
00061 //  You can move the cursor by simply clicking on the desired location  //
00062 //  with the left mouse button. To highlight some text, press the mouse //
00063 //  and drag the mouse while holding the left button pressed.           //
00064 //  To select a word, double-click on it;                               //
00065 //  to select the text line - triple-click on it;                       //
00066 //  to select all  do quadruple-click.                                  //
00067 //                                                                      //
00068 //  Cut, Copy, Paste                                                    //
00069 //                                                                      //
00070 //  After selecting some text, you can cut or copy it to the clipboard. //
00071 //  A subsequent paste operation will insert the contents of the        //
00072 //  clipboard at the current cursor location.                           //
00073 //                                                                      //
00074 //  Text Search                                                         //
00075 //                                                                      //
00076 //  The editor uses a standard Search dialog. You can specify a forward //
00077 //  or backward search direction starting from the current cursor       //
00078 //  location according to the selection made of a case sensitive mode   //
00079 //  or not. The last search can be repeated by pressing F3.             //
00080 //                                                                      //
00081 //  Text Font                                                           //
00082 //                                                                      //
00083 //  You can change the text font by selecting Edit menu / Set Font.     //
00084 //  The Font Dialog pops up and shows the Name, Style, and Size of any  //
00085 //  available font. The selected font sample is shown in the preview    //
00086 //  area.                                                               //
00087 //                                                                      //
00088 //  Executing Macros                                                    //
00089 //                                                                      //
00090 //  You can execute the currently loaded macro in the editor by         //
00091 //  selecting Tools menu / Execute Macro; by clicking on the            //
00092 //  corresponding toolbar button, or by using Ctrl+F5 accelerator keys. //
00093 //  This is identical to the command ".x macro.C" in the root prompt    //
00094 //  command line.                                                       //
00095 //                                                                      //
00096 //  Compiling Macros                                                    //
00097 //                                                                      //
00098 //  The currently loaded macro can be compiled with ACLiC if you select //
00099 //  Tools menu / Compile Macro; by clicking on the corresponding        //
00100 //  toolbar button, or by using Ctrl+F7 accelerator keys.               //
00101 //  This is identical to the command ".L macro.C++" in the root prompt  //
00102 //  command line.                                                       //
00103 //                                                                      //
00104 //  Interrupting a Running Macro                                        //
00105 //                                                                      //
00106 //  You can interrupt a running macro by selecting the Tools menu /     //
00107 //  Interrupt; by clicking on the corresponding toolbar button, or by   //
00108 //  using Shift+F5 accelerator keys.                                    //
00109 //                                                                      //
00110 //  Interface to CINT Interpreter                                       //
00111 //                                                                      //
00112 //  Any command entered in the Command combo box will be passed to      //
00113 //  the CINT interpreter. This combo box will keep the commands history //
00114 //  and will allow you to re-execute the same commands during an editor //
00115 //  session.                                                            //
00116 //                                                                      //
00117 //  Keyboard Bindings                                                   //
00118 //                                                                      //
00119 //  The following table lists the keyboard shortcuts and accelerator    //
00120 //  keys.                                                               //
00121 //                                                                      //
00122 //  Key:              Action:                                           //
00123 //  ====              =======                                           //
00124 //                                                                      //
00125 //  Up                Move cursor up.                                   //
00126 //  Shift+Up          Move cursor up and extend selection.              //
00127 //  Down              Move cursor down.                                 //
00128 //  Shift+Down        Move cursor down and extend selection.            //
00129 //  Left              Move cursor left.                                 //
00130 //  Shift+Left        Move cursor left and extend selection.            //
00131 //  Right             Move cursor right.                                //
00132 //  Shift+Right       Move cursor right and extend selection.           //
00133 //  Home              Move cursor to begin of line.                     //
00134 //  Shift+Home        Move cursor to begin of line and extend selection.//
00135 //  Ctrl+Home         Move cursor to top of page.                       //
00136 //  End               Move cursor to end of line.                       //
00137 //  Shift+End         Move cursor to end of line and extend selection.  //
00138 //  Ctrl+End          Move cursor to end of page.                       //
00139 //  PgUp              Move cursor up one page.                          //
00140 //  Shift+PgUp        Move cursor up one page and extend selection.     //
00141 //  PgDn              Move cursor down one page.                        //
00142 //  Shift+PgDn        Move cursor down one page and extend selection.   //
00143 //  Delete            Delete character after cursor, or text selection. //
00144 //  BackSpace         Delete character before cursor, or text selection.//
00145 //  Ctrl+B            Move cursor left.                                 //
00146 //  Ctrl+D            Delete character after cursor, or text selection. //
00147 //  Ctrl+E            Move cursor to end of line.                       //
00148 //  Ctrl+H            Delete character before cursor, or text selection.//
00149 //  Ctrl+K            Delete characters from current position to the    //
00150 //                    end of line.                                      //
00151 //  Ctrl+U            Delete current line.                              //
00152 //                                                                      //
00153 //Begin_Html
00154 /*
00155 <img src="gif/TGTextEditor.gif">
00156 */
00157 //End_Html
00158 //                                                                      //
00159 //////////////////////////////////////////////////////////////////////////
00160 
00161 
00162 #include "TROOT.h"
00163 #include "TSystem.h"
00164 #include "TMacro.h"
00165 #include "TInterpreter.h"
00166 #include "TGMsgBox.h"
00167 #include "TGFileDialog.h"
00168 #include "TGFontDialog.h"
00169 #include "TGTextEdit.h"
00170 #include "TGMenu.h"
00171 #include "TGButton.h"
00172 #include "TGStatusBar.h"
00173 #include "KeySymbols.h"
00174 #include "TGToolBar.h"
00175 #include "TG3DLine.h"
00176 #include "TGLabel.h"
00177 #include "TGTextEntry.h"
00178 #include "TGTextEditDialogs.h"
00179 #include "TGTextEditor.h"
00180 #include "TGComboBox.h"
00181 #include "TObjString.h"
00182 #include "TRootHelpDialog.h"
00183 #include "HelpText.h"
00184 #ifdef WIN32
00185 #include "TWin32SplashThread.h"
00186 #endif
00187 
00188 const char *ed_filetypes[] = {
00189    "ROOT Macros",  "*.C",
00190    "Source files", "*.cxx",
00191    "Text files",   "*.txt",
00192    "All files",    "*",
00193    0, 0
00194 };
00195 
00196 enum ETextEditorCommands {
00197    kM_FILE_NEW, kM_FILE_OPEN, kM_FILE_SAVE, kM_FILE_SAVEAS, kM_FILE_PRINT,
00198    kM_FILE_EXIT, kM_EDIT_CUT, kM_EDIT_COPY, kM_EDIT_PASTE, kM_EDIT_DELETE,
00199    kM_EDIT_SELECTALL, kM_SEARCH_FIND, kM_SEARCH_FINDNEXT, kM_SEARCH_GOTO,
00200    kM_TOOLS_COMPILE, kM_TOOLS_EXECUTE, kM_TOOLS_INTERRUPT, kM_HELP_CONTENTS,
00201    kM_HELP_ABOUT, kM_EDIT_SELFONT
00202 };
00203 
00204 ToolBarData_t fTbData[] = {
00205   { "ed_new.png",       "New File",         kFALSE, kM_FILE_NEW,         0 },
00206   { "ed_open.png",      "Open File",        kFALSE, kM_FILE_OPEN,        0 },
00207   { "ed_save.png",      "Save File",        kFALSE, kM_FILE_SAVE,        0 },
00208   { "ed_saveas.png",    "Save File As...",  kFALSE, kM_FILE_SAVEAS,      0 },
00209   { "",                 0,                  0,      -1,                  0 },
00210   { "ed_print.png",     "Print",            kFALSE, kM_FILE_PRINT,       0 },
00211   { "",                 0,                  0,      -1,                  0 },
00212   { "ed_cut.png",       "Cut selection",    kFALSE, kM_EDIT_CUT,         0 },
00213   { "ed_copy.png",      "Copy selection",   kFALSE, kM_EDIT_COPY,        0 },
00214   { "ed_paste.png",     "Paste selection",  kFALSE, kM_EDIT_PASTE,       0 },
00215   { "ed_delete.png",    "Delete selection", kFALSE, kM_EDIT_DELETE,      0 },
00216   { "",                 0,                  0,      -1,                  0 },
00217   { "ed_find.png",      "Find...",          kFALSE, kM_SEARCH_FIND,      0 },
00218   { "ed_findnext.png",  "Find next",        kFALSE, kM_SEARCH_FINDNEXT,  0 },
00219   { "ed_goto.png",      "Goto...",          kFALSE, kM_SEARCH_GOTO,      0 },
00220   { "",                 0,                  0,      -1,                  0 },
00221   { "ed_compile.png",   "Compile Macro",    kFALSE, kM_TOOLS_COMPILE,    0 },
00222   { "ed_execute.png",   "Execute Macro",    kFALSE, kM_TOOLS_EXECUTE,    0 },
00223   { "ed_interrupt.png", "Interrupt",        kFALSE, kM_TOOLS_INTERRUPT,  0 },
00224   { "",                 0,                  0,      -1,                  0 },
00225   { "ed_help.png",      "Help Contents",    kFALSE, kM_HELP_CONTENTS,    0 },
00226   { "",                 0,                  0,      -1,                  0 },
00227   { "ed_quit.png",      "Close Editor",     kFALSE, kM_FILE_EXIT,        0 },
00228   {  0,                 0,                  0,      0,                   0 }
00229 };
00230 
00231 static char *gEPrinter      = 0;
00232 static char *gEPrintCommand = 0;
00233 
00234 ClassImp(TGTextEditor)
00235 
00236 //______________________________________________________________________________
00237 TGTextEditor::TGTextEditor(const char *filename, const TGWindow *p, UInt_t w,
00238                            UInt_t h) : TGMainFrame(p, w, h)
00239 {
00240    // TGTextEditor constructor with file name as first argument.
00241 
00242    Build();
00243    if (p && p != gClient->GetDefaultRoot()) {
00244       // special case for TRootBrowser
00245       // remove the command line combo box and its associated label
00246       fComboCmd->UnmapWindow();
00247       fToolBar->RemoveFrame(fComboCmd);
00248       fLabel->UnmapWindow();
00249       fToolBar->RemoveFrame(fLabel);
00250       fToolBar->GetButton(kM_FILE_EXIT)->SetState(kButtonDisabled);
00251       fToolBar->Layout();
00252    }
00253    if (filename) {
00254       LoadFile((char *)filename);
00255    }
00256    MapWindow();
00257 }
00258 
00259 //______________________________________________________________________________
00260 TGTextEditor::TGTextEditor(TMacro *macro, const TGWindow *p, UInt_t w, UInt_t h) :
00261               TGMainFrame(p, w, h)
00262 {
00263    // TGTextEditor constructor with pointer to a TMacro as first argument.
00264 
00265    TString tmp;
00266    Build();
00267    if (p && p != gClient->GetDefaultRoot()) {
00268       // special case for TRootBrowser
00269       // remove the command line combo box and its associated label
00270       fComboCmd->UnmapWindow();
00271       fLabel->UnmapWindow();
00272       fToolBar->GetButton(kM_FILE_EXIT)->SetState(kButtonDisabled);
00273       fToolBar->Layout();
00274    }
00275    if (macro) {
00276       fMacro = macro;
00277       TIter next(macro->GetListOfLines());
00278       TObjString *obj;
00279       while ((obj = (TObjString*) next())) {
00280          fTextEdit->AddLine(obj->GetName());
00281       }
00282       tmp.Form("TMacro : %s: %ld lines read.",
00283                macro->GetName(), fTextEdit->ReturnLineCount());
00284       fStatusBar->SetText(tmp.Data(), 0);
00285       fFilename = macro->GetName();
00286       fFilename += ".C";
00287       tmp.Form("TMacro : %s - TGTextEditor", macro->GetName());
00288       SetWindowName(tmp.Data());
00289    }
00290    MapWindow();
00291 }
00292 
00293 //______________________________________________________________________________
00294 TGTextEditor::~TGTextEditor()
00295 {
00296    // TGTextEditor destructor.
00297 
00298    if (fTimer) delete fTimer;
00299    if (fMenuFile) delete fMenuFile;
00300    if (fMenuEdit) delete fMenuEdit;
00301    if (fMenuSearch) delete fMenuSearch;
00302    if (fMenuTools) delete fMenuTools;
00303    if (fMenuHelp) delete fMenuHelp;
00304 }
00305 
00306 //______________________________________________________________________________
00307 void TGTextEditor::DeleteWindow()
00308 {
00309    // Delete TGTextEditor Window.
00310 
00311    delete fTimer; fTimer = 0;
00312    delete fMenuFile; fMenuFile = 0;
00313    delete fMenuEdit; fMenuEdit = 0;
00314    delete fMenuSearch; fMenuSearch = 0;
00315    delete fMenuTools; fMenuTools = 0;
00316    delete fMenuHelp; fMenuHelp = 0;
00317    Cleanup();
00318    TGMainFrame::DeleteWindow();
00319 }
00320 
00321 //______________________________________________________________________________
00322 void TGTextEditor::Build()
00323 {
00324    // Build TGTextEditor widget.
00325 
00326    SetCleanup(kDeepCleanup);
00327    fMenuBarLayout = new TGLayoutHints(kLHintsTop | kLHintsExpandX, 0, 0, 1, 1);
00328    fMenuBarItemLayout = new TGLayoutHints(kLHintsTop | kLHintsLeft, 0, 4, 0, 0);
00329 
00330    fMenuFile = new TGPopupMenu(fClient->GetDefaultRoot());
00331    fMenuFile->AddEntry("&New", kM_FILE_NEW);
00332    fMenuFile->AddSeparator();
00333    fMenuFile->AddEntry("&Open...", kM_FILE_OPEN);
00334    fMenuFile->AddEntry("&Save", kM_FILE_SAVE);
00335    fMenuFile->AddEntry("Save &As...", kM_FILE_SAVEAS);
00336    fMenuFile->AddSeparator();
00337    fMenuFile->AddEntry("&Print...", kM_FILE_PRINT);
00338    fMenuFile->AddSeparator();
00339    fMenuFile->AddEntry("E&xit", kM_FILE_EXIT);
00340 
00341    fMenuEdit = new TGPopupMenu(fClient->GetDefaultRoot());
00342    fMenuEdit->AddEntry("Cu&t\tCtrl+X", kM_EDIT_CUT);
00343    fMenuEdit->AddEntry("&Copy\tCtrl+C", kM_EDIT_COPY);
00344    fMenuEdit->AddEntry("&Paste\tCtrl+V", kM_EDIT_PASTE);
00345    fMenuEdit->AddEntry("De&lete\tDel", kM_EDIT_DELETE);
00346    fMenuEdit->AddSeparator();
00347    fMenuEdit->AddEntry("Select &All\tCtrl+A", kM_EDIT_SELECTALL);
00348    fMenuEdit->AddSeparator();
00349    fMenuEdit->AddEntry("Set &Font", kM_EDIT_SELFONT);
00350 
00351    fMenuTools = new TGPopupMenu(fClient->GetDefaultRoot());
00352    fMenuTools->AddEntry("&Compile Macro\tCtrl+F7", kM_TOOLS_COMPILE);
00353    fMenuTools->AddEntry("&Execute Macro\tCtrl+F5", kM_TOOLS_EXECUTE);
00354    fMenuTools->AddEntry("&Interrupt\tShift+F5", kM_TOOLS_INTERRUPT);
00355 
00356    fMenuEdit->DisableEntry(kM_EDIT_CUT);
00357    fMenuEdit->DisableEntry(kM_EDIT_COPY);
00358    fMenuEdit->DisableEntry(kM_EDIT_DELETE);
00359    fMenuEdit->DisableEntry(kM_EDIT_PASTE);
00360 
00361    fMenuSearch = new TGPopupMenu(fClient->GetDefaultRoot());
00362    fMenuSearch->AddEntry("&Find...\tCtrl+F", kM_SEARCH_FIND);
00363    fMenuSearch->AddEntry("Find &Next\tF3", kM_SEARCH_FINDNEXT);
00364    fMenuSearch->AddSeparator();
00365    fMenuSearch->AddEntry("&Goto Line...\tCtrl+L", kM_SEARCH_GOTO);
00366 
00367    fMenuHelp = new TGPopupMenu(fClient->GetDefaultRoot());
00368    fMenuHelp->AddEntry("&Help Topics\tF1", kM_HELP_CONTENTS);
00369    fMenuHelp->AddSeparator();
00370    fMenuHelp->AddEntry("&About...", kM_HELP_ABOUT);
00371 
00372    fMenuFile->Associate(this);
00373    fMenuEdit->Associate(this);
00374    fMenuSearch->Associate(this);
00375    fMenuTools->Associate(this);
00376    fMenuHelp->Associate(this);
00377 
00378    fMenuBar = new TGMenuBar(this, 1, 1, kHorizontalFrame);
00379    fMenuBar->SetCleanup(kDeepCleanup);
00380    fMenuBar->AddPopup("&File", fMenuFile, fMenuBarItemLayout);
00381    fMenuBar->AddPopup("&Edit", fMenuEdit, fMenuBarItemLayout);
00382    fMenuBar->AddPopup("&Search", fMenuSearch, fMenuBarItemLayout);
00383    fMenuBar->AddPopup("&Tools", fMenuTools, fMenuBarItemLayout);
00384    fMenuBar->AddPopup("&Help", fMenuHelp, new TGLayoutHints(kLHintsTop |
00385                       kLHintsRight));
00386    AddFrame(fMenuBar, fMenuBarLayout);
00387 
00388    //---- toolbar
00389 
00390    AddFrame(new TGHorizontal3DLine(this),
00391             new TGLayoutHints(kLHintsTop | kLHintsExpandX, 0,0,2,2));
00392    Int_t i,spacing = 8;
00393    fToolBar = new TGToolBar(this, 60, 20, kHorizontalFrame);
00394    fToolBar->SetCleanup(kDeepCleanup);
00395    for (i = 0; fTbData[i].fPixmap; i++) {
00396       if (strlen(fTbData[i].fPixmap) == 0) {
00397          spacing = 8;
00398          continue;
00399       }
00400       fToolBar->AddButton(this, &fTbData[i], spacing);
00401       spacing = 0;
00402    }
00403    fComboCmd   = new TGComboBox(fToolBar, "");
00404    fCommand    = fComboCmd->GetTextEntry();
00405    fCommandBuf = fCommand->GetBuffer();
00406    fCommand->Associate(this);
00407    fComboCmd->Resize(200, fCommand->GetDefaultHeight());
00408    fToolBar->AddFrame(fComboCmd, new TGLayoutHints(kLHintsCenterY |
00409             kLHintsRight, 5, 5, 1, 1));
00410 
00411    fToolBar->AddFrame(fLabel = new TGLabel(fToolBar, "Command :"),
00412             new TGLayoutHints(kLHintsCenterY | kLHintsRight, 5, 5, 1, 1));
00413    AddFrame(fToolBar, new TGLayoutHints(kLHintsTop | kLHintsExpandX,
00414             0, 0, 0, 0));
00415    AddFrame(new TGHorizontal3DLine(this),
00416             new TGLayoutHints(kLHintsTop | kLHintsExpandX, 0,0,2,2));
00417 
00418    fToolBar->GetButton(kM_EDIT_CUT)->SetState(kButtonDisabled);
00419    fToolBar->GetButton(kM_EDIT_COPY)->SetState(kButtonDisabled);
00420    fToolBar->GetButton(kM_EDIT_DELETE)->SetState(kButtonDisabled);
00421    fToolBar->GetButton(kM_EDIT_PASTE)->SetState(kButtonDisabled);
00422 
00423    fTextEdit = new TGTextEdit(this, 10, 10, 1);
00424    Pixel_t pxl;
00425    gClient->GetColorByName("#ccccff", pxl);
00426    fTextEdit->SetSelectBack(pxl);
00427    fTextEdit->SetSelectFore(TGFrame::GetBlackPixel());
00428    fTextEdit->Associate(this);
00429    AddFrame(fTextEdit, new TGLayoutHints(kLHintsExpandX | kLHintsExpandY));
00430 
00431    Int_t parts[] = { 75, 25 };
00432    fStatusBar = new TGStatusBar(this);
00433    fStatusBar->SetCleanup(kDeepCleanup);
00434    fStatusBar->SetParts(parts, 2);
00435    AddFrame(fStatusBar, new TGLayoutHints(kLHintsBottom | kLHintsExpandX, 0, 0, 3, 0));
00436 
00437    SetClassHints("TGTextEditor", "TGTextEditor");
00438    SetWindowName("Untitled - TGTextEditor");
00439 
00440    fMacro = 0;
00441    fFilename = "Untitled";
00442    fStatusBar->SetText(fFilename.Data(), 0);
00443 
00444    fTextEdit->SetFocus();
00445    fTextEdit->Connect("DataChanged()", "TGTextEditor", this, "DataChanged()");
00446    fTextEdit->Connect("DataDropped(char *)", "TGTextEditor", this, "DataDropped(char *)");
00447    fTextEdit->MapWindow();
00448 
00449    MapSubwindows();
00450    Resize(GetDefaultWidth() + 50, GetDefaultHeight() > 500 ? GetDefaultHeight() : 500);
00451    Layout();
00452 
00453    gVirtualX->GrabKey(fId, gVirtualX->KeysymToKeycode(kKey_F3), 0, kTRUE);
00454 
00455    AddInput(kKeyPressMask | kEnterWindowMask | kLeaveWindowMask |
00456             kFocusChangeMask | kStructureNotifyMask);
00457 
00458    fTimer = new TTimer(this, 250);
00459    fTimer->Reset();
00460    fTimer->TurnOn();
00461 
00462    fExiting = kFALSE;
00463    fTextChanged = kFALSE;
00464 }
00465 
00466 //______________________________________________________________________________
00467 void TGTextEditor::DataDropped(char *fname)
00468 {
00469    // Update file informations when receiving the signal
00470    // DataDropped from TGTextEdit widget.
00471 
00472    TString tmp;
00473    fFilename = fname;
00474    tmp.Form("%s: %ld lines read.", fname, fTextEdit->ReturnLineCount());
00475    fStatusBar->SetText(tmp, 0);
00476    tmp.Form("%s - TGTextEditor", fname);
00477    SetWindowName(tmp.Data());
00478 }
00479 
00480 //______________________________________________________________________________
00481 void TGTextEditor::LoadFile(char *fname)
00482 {
00483    // Load a file into the editor. If fname is 0, a TGFileDialog will popup.
00484 
00485    TString tmp;
00486    TGFileInfo fi;
00487    fi.fFileTypes = ed_filetypes;
00488    if (fname == 0) {
00489       new TGFileDialog(fClient->GetDefaultRoot(), this, kFDOpen, &fi);
00490       if (fi.fFilename && strlen(fi.fFilename)) {
00491          fname = fi.fFilename;
00492       }
00493    }
00494    if (fname) {
00495       if (!fTextEdit->LoadFile(fname)) {
00496          tmp.Form("Error opening file \"%s\"", fname);
00497          new TGMsgBox(fClient->GetRoot(), this, "TGTextEditor",
00498                       tmp.Data(), kMBIconExclamation, kMBOk);
00499       } else {
00500          fFilename = fname;
00501          tmp.Form("%s: %ld lines read.", fname, fTextEdit->ReturnLineCount());
00502          fStatusBar->SetText(tmp.Data(), 0);
00503          tmp.Form("%s - TGTextEditor", fname);
00504          SetWindowName(tmp.Data());
00505       }
00506    }
00507    fTextEdit->Layout();
00508    fTextChanged = kFALSE;
00509 }
00510 
00511 //______________________________________________________________________________
00512 void TGTextEditor::SaveFile(const char *fname)
00513 {
00514    // Save the edited text in the file "fname".
00515 
00516    char *p;
00517    TString tmp;
00518 
00519    if (!fTextEdit->SaveFile(fname)) {
00520       tmp.Form("Error saving file \"%s\"", fname);
00521       new TGMsgBox(fClient->GetRoot(), this, "TGTextEditor",
00522                    tmp.Data(), kMBIconExclamation, kMBOk);
00523       return;
00524    }
00525    if ((p = (char *)strrchr(fname, '/')) == 0) {
00526       p = (char *)fname;
00527    } else {
00528       ++p;
00529    }
00530    tmp.Form("%s: %ld lines written.", p, fTextEdit->ReturnLineCount());
00531    fStatusBar->SetText(tmp.Data(), 0);
00532 
00533    tmp.Form("%s - TGTextEditor", p);
00534    SetWindowName(tmp.Data());
00535    fTextChanged = kFALSE;
00536 }
00537 
00538 //______________________________________________________________________________
00539 Bool_t TGTextEditor::SaveFileAs()
00540 {
00541    // Save the edited text in a file selected with TGFileDialog.
00542    // Shouldn't we create a backup file?
00543 
00544    static TString dir(".");
00545    static Bool_t overwr = kFALSE;
00546    TGFileInfo fi;
00547    fi.fFileTypes = ed_filetypes;
00548    fi.fIniDir    = StrDup(dir);
00549    fi.fOverwrite = overwr;
00550    new TGFileDialog(fClient->GetDefaultRoot(), this, kFDSave, &fi);
00551    overwr = fi.fOverwrite;
00552    if (fi.fFilename && strlen(fi.fFilename)) {
00553       SaveFile(fi.fFilename);
00554       fFilename = fi.fFilename;
00555       return kTRUE;
00556    }
00557    return kFALSE;
00558 }
00559 
00560 //______________________________________________________________________________
00561 Int_t TGTextEditor::IsSaved()
00562 {
00563    // Check if file has to be saved in case of modifications.
00564 
00565    Int_t ret;
00566    TString tmp;
00567    Int_t opt = (kMBYes | kMBNo);
00568 
00569    tmp.Form("The text has been modified. Do you want to save the changes?");
00570 
00571    if (!fTextChanged) {
00572       return kMBNo;
00573    } else {
00574       if (fParent == gClient->GetDefaultRoot())
00575          opt |= kMBCancel;
00576       new TGMsgBox(fClient->GetRoot(), this, "TGTextEditor",
00577                    tmp.Data(), kMBIconExclamation, opt, &ret);
00578       return ret;
00579    }
00580 }
00581 
00582 //______________________________________________________________________________
00583 void TGTextEditor::PrintText()
00584 {
00585    // Open the print dialog and send current buffer to printer.
00586 
00587    TString tmp;
00588    Int_t ret = 0;
00589    if (!gEPrinter) {
00590       gEPrinter = StrDup("892_2_cor"); // use gEnv
00591       gEPrintCommand = StrDup("xprint");
00592    }
00593    new TGPrintDialog(fClient->GetDefaultRoot(), this, 400, 150,
00594                      &gEPrinter, &gEPrintCommand, &ret);
00595    if (ret) {
00596       fTextEdit->Print();
00597       tmp.Form("Printed: %s", fFilename.Data());
00598       fStatusBar->SetText(tmp.Data(), 0);
00599    }
00600 }
00601 
00602 //______________________________________________________________________________
00603 void TGTextEditor::CloseWindow()
00604 {
00605    // Close TGTextEditor window.
00606 
00607    if (fExiting) {
00608       return;
00609    }
00610    fExiting = kTRUE;
00611    switch (IsSaved()) {
00612       case kMBYes:
00613          if (!fFilename.CompareTo("Untitled"))
00614             SaveFileAs();
00615          else
00616             SaveFile(fFilename.Data());
00617          if ((fTextChanged) && (fParent == gClient->GetDefaultRoot()))
00618             break;
00619       case kMBCancel:
00620          if (fParent == gClient->GetDefaultRoot())
00621             break;
00622       case kMBNo:
00623          TGMainFrame::CloseWindow();
00624    }
00625    fExiting = kFALSE;
00626 }
00627 
00628 //______________________________________________________________________________
00629 Bool_t TGTextEditor::HandleKey(Event_t *event)
00630 {
00631    // Keyboard event handler.
00632 
00633    char   input[10];
00634    Int_t  n;
00635    UInt_t keysym;
00636 
00637    if (event->fType == kGKeyPress) {
00638       gVirtualX->LookupString(event, input, sizeof(input), keysym);
00639       n = strlen(input);
00640 
00641       switch ((EKeySym)keysym) {   // ignore these keys
00642          case kKey_Shift:
00643          case kKey_Control:
00644          case kKey_Meta:
00645          case kKey_Alt:
00646          case kKey_CapsLock:
00647          case kKey_NumLock:
00648          case kKey_ScrollLock:
00649             return kTRUE;
00650          case kKey_F1:
00651             SendMessage(this, MK_MSG(kC_COMMAND, kCM_MENU),
00652                         kM_HELP_CONTENTS, 0);
00653             return kTRUE;
00654          case kKey_F3:
00655             Search(kTRUE);
00656             return kTRUE;
00657          default:
00658             break;
00659       }
00660       if (event->fState & kKeyControlMask) {   // Ctrl key modifier pressed
00661          switch((EKeySym)keysym) {
00662             case kKey_F5:
00663                ExecuteMacro();
00664                return kTRUE;
00665             case kKey_F7:
00666                CompileMacro();
00667                return kTRUE;
00668             default:
00669                break;
00670          }
00671       }
00672       if (event->fState & kKeyShiftMask) {   // Shift key modifier pressed
00673          switch((EKeySym)keysym) {
00674             case kKey_F5:
00675                InterruptMacro();
00676                return kTRUE;
00677             default:
00678                break;
00679          }
00680       }
00681    }
00682    return TGMainFrame::HandleKey(event);
00683 }
00684 
00685 //______________________________________________________________________________
00686 void TGTextEditor::ClearText()
00687 {
00688    // Clear text edit widget.
00689 
00690    fTextEdit->Clear();
00691    fMacro = 0;
00692    fFilename = "Untitled";
00693    SetWindowName("Untitled - TGTextEditor");
00694    fStatusBar->SetText("New File", 0);
00695    fTextChanged = kFALSE;
00696 }
00697 
00698 //______________________________________________________________________________
00699 void TGTextEditor::Search(Bool_t again)
00700 {
00701    // Invokes search dialog, or just search previous string if again is true.
00702 
00703    if (again) {
00704       SendMessage(fTextEdit, MK_MSG(kC_COMMAND, kCM_MENU),
00705                   TGTextEdit::kM_SEARCH_FINDAGAIN, 0);
00706    }
00707    else {
00708       fTextEdit->Search(kFALSE);
00709    }
00710 }
00711 
00712 //______________________________________________________________________________
00713 void TGTextEditor::Goto()
00714 {
00715    // Invokes goto dialog, and go to the specified line.
00716 
00717    Long_t ret;
00718 
00719    new TGGotoDialog(fClient->GetDefaultRoot(), this, 400, 150, &ret);
00720 
00721    if (ret >= 0)
00722       fTextEdit->Goto(ret-1);
00723 }
00724 
00725 //______________________________________________________________________________
00726 void TGTextEditor::CompileMacro()
00727 {
00728    // Save the edited text in a temporary macro, then compile it.
00729 
00730    if (fTextEdit->ReturnLineCount() < 3)
00731       return;
00732    if ((fMacro) || (!fFilename.CompareTo("Untitled"))) {
00733       if (!SaveFileAs())
00734          return;
00735    }
00736    char *tmpfile = gSystem->ConcatFileName(gSystem->TempDirectory(),
00737                                 gSystem->BaseName(fFilename.Data()));
00738    fTextEdit->SaveFile(tmpfile, kFALSE);
00739    gSystem->CompileMacro(tmpfile);
00740    gSystem->Unlink(tmpfile);
00741    delete [] tmpfile;
00742 }
00743 
00744 //______________________________________________________________________________
00745 void TGTextEditor::ExecuteMacro()
00746 {
00747    // Save the edited text in a temporary macro, execute it, and then delete
00748    // the temporary file.
00749 
00750    if (fTextEdit->ReturnLineCount() < 3)
00751       return;
00752    if (fMacro) {
00753       fMacro->Exec();
00754       return;
00755    }
00756    if (fTextChanged) {
00757       Int_t ret;
00758       new TGMsgBox(fClient->GetRoot(), this, "TGTextEditor",
00759             "The text has been modified. Do you want to save the changes?",
00760             kMBIconExclamation, kMBYes | kMBNo | kMBCancel, &ret);
00761       if (ret == kMBYes) {
00762          if (!fFilename.CompareTo("Untitled"))
00763             SaveFileAs();
00764          else
00765             SaveFile(fFilename.Data());
00766          fTextChanged = kFALSE;
00767       }
00768       if (ret == kMBCancel)
00769          return;
00770    }
00771    if (!fFilename.CompareTo("Untitled")) {
00772       //if (!SaveFileAs())
00773       //   return;
00774       fFilename += ".C";
00775    }
00776    gInterpreter->SaveContext();
00777    TString savdir = gSystem->WorkingDirectory();
00778    TString tmpfile = gSystem->BaseName(fFilename.Data());
00779    tmpfile += "_exec";
00780    gSystem->ChangeDirectory(gSystem->DirName(fFilename.Data()));
00781    fTextEdit->SaveFile(tmpfile.Data(), kFALSE);
00782    gROOT->SetExecutingMacro(kTRUE);
00783    gROOT->Macro(tmpfile.Data());
00784    gROOT->SetExecutingMacro(kFALSE);
00785    if (gInterpreter->IsLoaded(tmpfile.Data()))
00786       gInterpreter->UnloadFile(tmpfile.Data());
00787    gSystem->Unlink(tmpfile.Data());
00788    gSystem->ChangeDirectory(savdir.Data());
00789    gInterpreter->Reset();
00790 }
00791 
00792 //______________________________________________________________________________
00793 void TGTextEditor::InterruptMacro()
00794 {
00795    // Interrupt execution of a macro.
00796 
00797    gROOT->SetInterrupt(kTRUE);
00798 }
00799 
00800 //______________________________________________________________________________
00801 void TGTextEditor::About()
00802 {
00803    // Display ROOT splash screen.
00804 
00805 #ifdef R__UNIX
00806    TString rootx;
00807 # ifdef ROOTBINDIR
00808    rootx = ROOTBINDIR;
00809 # else
00810    rootx = gSystem->Getenv("ROOTSYS");
00811    if (!rootx.IsNull()) rootx += "/bin";
00812 # endif
00813    rootx += "/root -a &";
00814    gSystem->Exec(rootx);
00815 #else
00816 #ifdef WIN32
00817    new TWin32SplashThread(kTRUE);
00818 #else
00819    char str[32];
00820    sprintf(str, "About ROOT %s...", gROOT->GetVersion());
00821    TRootHelpDialog *hd = new TRootHelpDialog(this, str, 600, 400);
00822    hd->SetText(gHelpAbout);
00823    hd->Popup();
00824 #endif
00825 #endif
00826 }
00827 
00828 //______________________________________________________________________________
00829 Bool_t TGTextEditor::HandleTimer(TTimer *t)
00830 {
00831    // Handle timer event.
00832 
00833    TString tmp;
00834    if (t != fTimer) return kTRUE;
00835    // check if some text is available in the clipboard
00836    if ((gVirtualX->InheritsFrom("TGX11")) &&
00837       (gVirtualX->GetPrimarySelectionOwner() == kNone)) {
00838       fMenuEdit->DisableEntry(kM_EDIT_PASTE);
00839       fToolBar->GetButton(kM_EDIT_PASTE)->SetState(kButtonDisabled);
00840    }
00841    else {
00842       fMenuEdit->EnableEntry(kM_EDIT_PASTE);
00843       if (fToolBar->GetButton(kM_EDIT_PASTE)->GetState() == kButtonDisabled)
00844          fToolBar->GetButton(kM_EDIT_PASTE)->SetState(kButtonUp);
00845    }
00846    // check if text is selected in the editor
00847    if (fTextEdit->IsMarked()) {
00848       fMenuEdit->EnableEntry(kM_EDIT_CUT);
00849       fMenuEdit->EnableEntry(kM_EDIT_COPY);
00850       fMenuEdit->EnableEntry(kM_EDIT_DELETE);
00851       if (fToolBar->GetButton(kM_EDIT_CUT)->GetState() == kButtonDisabled) {
00852          fToolBar->GetButton(kM_EDIT_CUT)->SetState(kButtonUp);
00853          fToolBar->GetButton(kM_EDIT_COPY)->SetState(kButtonUp);
00854          fToolBar->GetButton(kM_EDIT_DELETE)->SetState(kButtonUp);
00855       }
00856    }
00857    else {
00858       fMenuEdit->DisableEntry(kM_EDIT_CUT);
00859       fMenuEdit->DisableEntry(kM_EDIT_COPY);
00860       fMenuEdit->DisableEntry(kM_EDIT_DELETE);
00861       if (fToolBar->GetButton(kM_EDIT_CUT)->GetState() == kButtonUp) {
00862          fToolBar->GetButton(kM_EDIT_CUT)->SetState(kButtonDisabled);
00863          fToolBar->GetButton(kM_EDIT_COPY)->SetState(kButtonDisabled);
00864          fToolBar->GetButton(kM_EDIT_DELETE)->SetState(kButtonDisabled);
00865       }
00866    }
00867    // get cursor position
00868    TGLongPosition pos = fTextEdit->GetCurrentPos();
00869    tmp.Form("Ln %ld, Ch %ld", pos.fY, pos.fX);
00870    fStatusBar->SetText(tmp.Data(), 1);
00871    fTimer->Reset();
00872    return kTRUE;
00873 }
00874 
00875 //______________________________________________________________________________
00876 Bool_t TGTextEditor::ProcessMessage(Long_t msg, Long_t parm1, Long_t)
00877 {
00878    // Handle menu and other command generated by the user.
00879 
00880    TRootHelpDialog *hd;
00881 
00882    switch(GET_MSG(msg)) {
00883       case kC_COMMAND:
00884          switch(GET_SUBMSG(msg)) {
00885             case kCM_BUTTON:
00886             case kCM_MENU:
00887                switch (parm1) {
00888                   // "File" menu related events
00889                   case kM_FILE_NEW:
00890                      new TGTextEditor();
00891                      break;
00892                   case kM_FILE_OPEN:
00893                      switch (IsSaved()) {
00894                         case kMBCancel:
00895                            break;
00896                         case kMBYes:
00897                            if (!fFilename.CompareTo("Untitled"))
00898                               SaveFileAs();
00899                            else
00900                               SaveFile(fFilename.Data());
00901                            if (fTextChanged)
00902                               break;
00903                         case kMBNo:
00904                            LoadFile();
00905                            break;
00906                      }
00907                      break;
00908                   case kM_FILE_SAVE:
00909                      if (!fFilename.CompareTo("Untitled"))
00910                         SaveFileAs();
00911                      else
00912                         SaveFile(fFilename.Data());
00913                      break;
00914                   case kM_FILE_SAVEAS:
00915                      SaveFileAs();
00916                      break;
00917                   case kM_FILE_PRINT:
00918                      PrintText();
00919                      break;
00920                   case kM_FILE_EXIT:
00921                      CloseWindow();
00922                      break;
00923 
00924                   // "Edit" menu related events
00925                   case kM_EDIT_CUT:
00926                      fTextEdit->Cut();
00927                      break;
00928                   case kM_EDIT_COPY:
00929                      fTextEdit->Copy();
00930                      break;
00931                   case kM_EDIT_PASTE:
00932                      fTextEdit->Paste();
00933                      break;
00934                   case kM_EDIT_DELETE:
00935                      fTextEdit->Delete();
00936                      break;
00937                   case kM_EDIT_SELECTALL:
00938                      fTextEdit->SelectAll();
00939                      if (fTextEdit->IsMarked()) {
00940                         fMenuEdit->EnableEntry(kM_EDIT_CUT);
00941                         fMenuEdit->EnableEntry(kM_EDIT_COPY);
00942                         fMenuEdit->EnableEntry(kM_EDIT_DELETE);
00943                         if (fToolBar->GetButton(kM_EDIT_CUT)->GetState() == kButtonDisabled) {
00944                            fToolBar->GetButton(kM_EDIT_CUT)->SetState(kButtonUp);
00945                            fToolBar->GetButton(kM_EDIT_COPY)->SetState(kButtonUp);
00946                            fToolBar->GetButton(kM_EDIT_DELETE)->SetState(kButtonUp);
00947                         }
00948                      }
00949                      break;
00950                   case kM_EDIT_SELFONT:
00951                      {
00952                         Int_t count;
00953                         TString fontname;
00954                         TGFontDialog::FontProp_t prop;
00955                         new TGFontDialog(fClient->GetRoot(), this, &prop);
00956                         if (prop.fName != "") {
00957                            fontname.Form("-*-%s-%s-%c-*-*-%d-*-*-*-*-*-*-*",
00958                                          prop.fName.Data(), 
00959                                          prop.fBold ? "bold" : "medium",
00960                                          prop.fItalic ? 'i' : 'r',
00961                                          prop.fSize);
00962                            if (!gVirtualX->ListFonts(fontname, 10, count)) {
00963                               fontname.Form("-*-%s-%s-%c-*-*-%d-*-*-*-*-*-*-*",
00964                                             prop.fName.Data(), 
00965                                             prop.fBold ? "bold" : "medium",
00966                                             prop.fItalic ? 'o' : 'r',
00967                                             prop.fSize);
00968                            }
00969                            TGFont *font = fClient->GetFont(fontname);
00970                            if (font) {
00971                               FontStruct_t editorfont = font->GetFontStruct();
00972                               fTextEdit->SetFont(editorfont);
00973                               fTextEdit->Update();
00974                            }
00975                         }
00976                      }
00977                      break;
00978 
00979                   // "Tools" menu related events
00980                   case kM_TOOLS_COMPILE:
00981                      CompileMacro();
00982                      break;
00983                   case kM_TOOLS_EXECUTE:
00984                      ExecuteMacro();
00985                      break;
00986                   case kM_TOOLS_INTERRUPT:
00987                      InterruptMacro();
00988                      break;
00989 
00990                   // "Search" menu related events
00991                   case kM_SEARCH_FIND:
00992                      Search(kFALSE);
00993                      break;
00994                   case kM_SEARCH_FINDNEXT:
00995                      Search(kTRUE);
00996                      break;
00997                   case kM_SEARCH_GOTO:
00998                      Goto();
00999                      break;
01000 
01001                   // "Help" menu related events
01002                   case kM_HELP_CONTENTS:
01003                      hd = new TRootHelpDialog(this, "Help on Editor...", 600, 400);
01004                      hd->SetText(gHelpTextEditor);
01005                      hd->Popup();
01006                      break;
01007                   case kM_HELP_ABOUT:
01008                      About();
01009                      break;
01010                }
01011                break;
01012          }
01013          break;
01014       case kC_TEXTENTRY:
01015          switch (GET_SUBMSG(msg)) {
01016             case kTE_ENTER:
01017                {
01018                   // here copy the string from text buffer to return variable
01019                   const char *string = fCommandBuf->GetString();
01020                   if(strlen(string) > 1) {
01021                      gROOT->ProcessLine(string);
01022                      fComboCmd->ReturnPressed();
01023                   }
01024                }
01025                break;
01026             default:
01027                break;
01028          }
01029          break;
01030 
01031       default:
01032          break;
01033    }
01034    return kTRUE;
01035 }

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