00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include "TGo4AnalysisWindow.h"
00015
00016 #include "TSystem.h"
00017 #include "Riostream.h"
00018
00019 #include "qimage.h"
00020 #include "qlabel.h"
00021 #include "qpushbutton.h"
00022
00023 #include <QtCore/QTimer>
00024 #include <QtCore/QTextStream>
00025 #include <QtCore/QProcess>
00026
00027 #include <QHBoxLayout>
00028 #include <QGridLayout>
00029 #include <QTextEdit>
00030 #include <QToolTip>
00031 #include <QMessageBox>
00032 #include <QFileDialog>
00033 #include <QToolButton>
00034
00035 #include "TGo4QSettings.h"
00036 #include "TGo4AnalysisProxy.h"
00037 #include "TGo4BrowserProxy.h"
00038 #include "TGo4AnalysisObjectResult.h"
00039 #include "QGo4CommandsHistory.h"
00040
00041 TGo4AnalysisWindow::TGo4AnalysisWindow(QWidget* parent, const char* name, bool needoutput, bool needkillbtn) :
00042 QGo4Widget( parent, name)
00043 {
00044
00045 setCanDestroyWidget(false);
00046 setAcceptDrops(false);
00047
00048 fAnalysisProcess = 0;
00049 fxOutput = 0;
00050 outputBuffer = "";
00051 fiMaxOuputSize = 0;
00052 fxCmdHist = 0;
00053
00054 fNewObjectForEditor = true;
00055
00056 setWindowTitle("Analysis Terminal");
00057
00058 setFont(go4sett->getTermFont());
00059
00060 if (needoutput) {
00061
00062 resize(700, 400);
00063 setWindowIcon(QIcon(":/icons/analysiswin.png"));
00064 QGridLayout* layout = new QGridLayout( this );
00065 layout->setMargin(11);
00066 layout->setSpacing(6);
00067
00068 fxOutput = new QTextEdit(this);
00069 fxOutput->setUndoRedoEnabled(false);
00070 fxOutput->setAutoFormatting(QTextEdit::AutoNone);
00071 fxOutput->setWordWrapMode(QTextOption::NoWrap);
00072 fxOutput->setReadOnly(true);
00073 layout->addWidget( fxOutput, 0, 0 );
00074
00075 fiMaxOuputSize = go4sett->getTermHistorySize();
00076
00077 QHBoxLayout *box1 = new QHBoxLayout(this);
00078 box1->addWidget(new QLabel("Press enter to execute.", this), 1);
00079 CreateCmdLine(box1);
00080 layout->addLayout(box1, 1, 0);
00081
00082 QHBoxLayout *box2 = new QHBoxLayout(this);
00083 CreateButtons(box2, needkillbtn);
00084 layout->addLayout(box2, 2, 0);
00085
00086 updateTerminalOutput();
00087 } else {
00088
00089 QHBoxLayout *box = new QHBoxLayout(this);
00090
00091 CreateButtons(box, needkillbtn);
00092
00093 CreateCmdLine(box);
00094
00095 adjustSize();
00096 }
00097 }
00098
00099 void TGo4AnalysisWindow::CreateCmdLine(QHBoxLayout* box)
00100 {
00101 fxCmdHist = new QGo4CommandsHistory(this, "commandslist");
00102 fxCmdHist->setToolTip("CINT command for analysis process. Note: '@' means 'TGo4Analysis::Instance()->' .");
00103 connect(fxCmdHist, SIGNAL(enterPressedSingal()), this, SLOT(CommandSlot()));
00104 fxCmdHist->setMinimumSize( QSize( 220, 25 ) );
00105
00106 QStringList histlist = go4sett->getCommandsHistoryAnalysis();
00107 fxCmdHist->addItems(histlist);
00108 fxCmdHist->setEditText(QString());
00109
00110 box->addWidget(fxCmdHist, HasOutput() ? 3 : 1);
00111
00112 QToolButton* MacroSearch = new QToolButton( this );
00113 MacroSearch->setMinimumSize( QSize( 30, 25 ) );
00114 MacroSearch->setMaximumSize( QSize( 30, 25 ) );
00115 MacroSearch->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
00116 MacroSearch->setIcon( QIcon(":/icons/findfile.png" ) );
00117 MacroSearch->setToolTip("Search root macro on disk.");
00118 connect(MacroSearch, SIGNAL(clicked()), this, SLOT(FileDialog_Macro()));
00119 box->addWidget(MacroSearch,1);
00120 }
00121
00122 void TGo4AnalysisWindow::CreateButtons(QHBoxLayout* box, bool needkillbtn)
00123 {
00124 if (needkillbtn) {
00125 QToolButton* KillProcess = new QToolButton( this );
00126 KillProcess->setMinimumSize( QSize( 30, 25 ) );
00127 KillProcess->setMaximumSize( QSize( 30, 25 ) );
00128 KillProcess->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
00129 KillProcess->setIcon( QIcon( ":/icons/killanal.png" ) );
00130 KillProcess->setToolTip("Apply Ctrl+C in the analysis terminal.");
00131 connect(KillProcess, SIGNAL(clicked()), this, SLOT(RequestTerminate()));
00132 box->addWidget(KillProcess);
00133 }
00134
00135 if (HasOutput()) {
00136 QToolButton* ClearButton = new QToolButton( this );
00137 ClearButton->setMinimumSize( QSize( 30, 25 ) );
00138 ClearButton->setMaximumSize( QSize( 30, 25 ) );
00139 ClearButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
00140 ClearButton->setIcon( QIcon( ":/icons/clear.png" ) );
00141 ClearButton->setToolTip("Clear Terminal Window.");
00142 connect(ClearButton, SIGNAL(clicked()), this, SLOT(ClearAnalysisOutput()));
00143 box->addItem(new QSpacerItem(1,1));
00144 box->addWidget(ClearButton,1);
00145 }
00146
00147 QToolButton* PrintHistoButton = new QToolButton( this );
00148 PrintHistoButton->setMinimumSize( QSize( 30, 25 ) );
00149 PrintHistoButton->setMaximumSize( QSize( 30, 25 ) );
00150 PrintHistoButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
00151 PrintHistoButton->setIcon( QIcon( ":/icons/hislist.png" ) );
00152 PrintHistoButton->setToolTip("Print list of all histograms.");
00153 connect(PrintHistoButton, SIGNAL(clicked()), this, SLOT(PrintHistograms()));
00154 box->addWidget(PrintHistoButton,1);
00155
00156 QToolButton* PrintConnyButton = new QToolButton( this );
00157 PrintConnyButton->setMinimumSize( QSize( 30, 25 ) );
00158 PrintConnyButton->setMaximumSize( QSize( 30, 25 ) );
00159 PrintConnyButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
00160 PrintConnyButton->setIcon( QIcon( ":/icons/condlist.png" ) );
00161 PrintConnyButton->setToolTip("Print list of all conditions.");
00162 connect(PrintConnyButton, SIGNAL(clicked()), this, SLOT(PrintConditions()));
00163 box->addWidget(PrintConnyButton,1);
00164
00165 QToolButton* PrintEventButton = new QToolButton( this );
00166 PrintEventButton->setMinimumSize( QSize( 30, 25 ) );
00167 PrintEventButton->setMaximumSize( QSize( 30, 25 ) );
00168 PrintEventButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
00169 PrintEventButton->setIcon( QIcon( ":/icons/zoom.png" ) );
00170 PrintEventButton->setToolTip("Start Event Inspection panel");
00171 connect(PrintEventButton, SIGNAL(clicked()), this, SLOT(PrintEvent()));
00172 box->addWidget(PrintEventButton,1);
00173 }
00174
00175 TGo4AnalysisWindow::~TGo4AnalysisWindow()
00176 {
00177
00178 if (Browser()!=0)
00179 Browser()->ToggleMonitoring(0);
00180 }
00181
00182 bool TGo4AnalysisWindow::HasOutput()
00183 {
00184 return fxOutput!=0;
00185 }
00186
00187 void TGo4AnalysisWindow::SetHistorySize(int sz)
00188 {
00189 fiMaxOuputSize = sz;
00190 }
00191
00192 void TGo4AnalysisWindow::updateTerminalOutput()
00193 {
00194 if (fxOutput==0) return;
00195
00196 unsigned int buflen = outputBuffer.length();
00197
00198 if (fiMaxOuputSize>0) {
00199
00200
00201 unsigned int cutlength = fiMaxOuputSize / 2;
00202
00203 if (buflen > 0) {
00204 unsigned int outlen = fxOutput->toPlainText().length();
00205 if (buflen + outlen < fiMaxOuputSize)
00206 fxOutput->append(outputBuffer);
00207 else
00208 if (buflen>=cutlength) {
00209 outputBuffer.remove(0, buflen-cutlength);
00210 fxOutput->setText(outputBuffer);
00211 fxOutput->moveCursor(QTextCursor::End);
00212 } else {
00213 QString curr = fxOutput->toPlainText();
00214 curr.remove(0, cutlength - buflen);
00215 curr+=outputBuffer;
00216 fxOutput->setText(curr);
00217 fxOutput->moveCursor(QTextCursor::End);
00218 }
00219 }
00220 } else {
00221 if (buflen>0)
00222 fxOutput->append(outputBuffer);
00223 }
00224
00225 outputBuffer = "";
00226 QTimer::singleShot(100, this, SLOT(updateTerminalOutput()));
00227 }
00228
00229 void TGo4AnalysisWindow::readFromStdout()
00230 {
00231 if (fAnalysisProcess!=0) {
00232 QByteArray ba = fAnalysisProcess->readAllStandardOutput();
00233 QString buf(ba);
00234 AppendOutputBuffer(buf);
00235 }
00236 }
00237
00238
00239 void TGo4AnalysisWindow::readFromStderr()
00240 {
00241 if (fAnalysisProcess!=0) {
00242 QByteArray ba = fAnalysisProcess->readAllStandardError();
00243 QString buf(ba);
00244 AppendOutputBuffer(buf);
00245 }
00246 }
00247
00248 void TGo4AnalysisWindow::AppendOutputBuffer(const QString& value)
00249 {
00250 outputBuffer.append(value);
00251 }
00252
00253 void TGo4AnalysisWindow::StartAnalysisShell(const char* text, const char* workdir)
00254 {
00255 if (fAnalysisProcess!=0) delete fAnalysisProcess;
00256
00257 fAnalysisProcess = new QProcess();
00258 connect(fAnalysisProcess, SIGNAL(readyReadStandardOutput()), this, SLOT(readFromStdout()));
00259 connect(fAnalysisProcess, SIGNAL(readyReadStandardError()), this, SLOT(readFromStderr()));
00260 if (workdir!=0) fAnalysisProcess->setWorkingDirectory(workdir);
00261
00262 fAnalysisProcess->start(text);
00263
00264 if (fAnalysisProcess->state() == QProcess::NotRunning) {
00265 std::cerr << "Fatal error. Could not start the Analysis" << std::endl;
00266 TerminateAnalysisProcess();
00267 }
00268 }
00269
00270 void TGo4AnalysisWindow::RequestTerminate()
00271 {
00272 ServiceCall("TerminateAnalysis");
00273 }
00274
00275 void TGo4AnalysisWindow::TerminateAnalysisProcess()
00276 {
00277 if (fAnalysisProcess==0) return;
00278 AppendOutputBuffer("\nTerminate process ... \n\n");
00279 fAnalysisProcess->terminate();
00280 if (fAnalysisProcess->state() == QProcess::Running) fAnalysisProcess->kill();
00281 delete fAnalysisProcess;
00282 fAnalysisProcess = 0;
00283 }
00284
00285 void TGo4AnalysisWindow::ClearAnalysisOutput()
00286 {
00287 if (fxOutput!=0)
00288 fxOutput->clear();
00289 }
00290
00291 void TGo4AnalysisWindow::SaveAnalysisOutput()
00292 {
00293 if (fxOutput==0) return;
00294 QFileDialog fd(this,
00295 "Save analysis terminal output",
00296 "", "Plain text (*.txt)");
00297 fd.setFileMode( QFileDialog::AnyFile );
00298 fd.setAcceptMode(QFileDialog::AcceptSave);
00299
00300 if (fd.exec() != QDialog::Accepted) return;
00301
00302 QStringList flst = fd.selectedFiles();
00303 if (flst.isEmpty()) return;
00304 QString fileName = flst[0];
00305
00306 if(!fileName.endsWith(".txt")) fileName.append(".txt");
00307 QFile NewFile(fileName);
00308 NewFile.open( QIODevice::ReadWrite | QIODevice::Append );
00309 QTextStream t( &NewFile );
00310 t << fxOutput->toPlainText() << "\n";
00311 NewFile.close();
00312 }
00313
00314 void TGo4AnalysisWindow::CommandSlot()
00315 {
00316 QString cmd = fxCmdHist->currentText();
00317 if (cmd.length()==0) return;
00318
00319 TGo4AnalysisProxy* anal = GetAnalysis();
00320 if (anal!=0) {
00321 anal->ExecuteLine(cmd.toLatin1().constData());
00322 go4sett->setCommandsHistoryAnalysis(fxCmdHist->getHistory(50));
00323 }
00324 }
00325
00326
00327 void TGo4AnalysisWindow::FileDialog_Macro()
00328 {
00329 QFileDialog fd( this,
00330 "Select ROOT macro for analysis task"
00331 "", "CINT Macro (*.C)");
00332 fd.setFileMode( QFileDialog::ExistingFile);
00333
00334 if (fd.exec() != QDialog::Accepted) return;
00335
00336 QStringList flst = fd.selectedFiles();
00337 if (flst.isEmpty()) return;
00338
00339 QString cmd = QString(".x ") + flst[0];
00340 if(!cmd.endsWith(".C")) cmd.append(".C");
00341
00342 fxCmdHist->addItem(cmd);
00343 fxCmdHist->setCurrentIndex(fxCmdHist->findText(cmd));
00344 }
00345
00346 void TGo4AnalysisWindow::PrintHistograms()
00347 {
00348 const QString cmd = "@PrintHistograms()";
00349 fxCmdHist->addItem(cmd);
00350 fxCmdHist->setCurrentIndex(fxCmdHist->findText(cmd));
00351 CommandSlot();
00352 }
00353
00354 void TGo4AnalysisWindow::PrintConditions()
00355 {
00356 const QString cmd = "@PrintConditions()";
00357 fxCmdHist->addItem(cmd);
00358 fxCmdHist->setCurrentIndex(fxCmdHist->findText(cmd));
00359 CommandSlot();
00360 }
00361
00362 void TGo4AnalysisWindow::PrintEvent()
00363 {
00364 ServiceCall("StartEventInfo");
00365 }
00366
00367 void TGo4AnalysisWindow::WorkWithUpdateObjectCmd(TGo4Slot* slot)
00368 {
00369
00370 AddLink(slot, "ObjectUpdateCmd");
00371 }
00372
00373 void TGo4AnalysisWindow::WaitForNewObject(bool isobjectforeditor)
00374 {
00375 fNewObjectForEditor = isobjectforeditor;
00376 }
00377
00378 void TGo4AnalysisWindow::linkedObjectUpdated(const char* linkname, TObject* obj)
00379 {
00380 if (strcmp(linkname, "ObjectUpdateCmd")!=0) return;
00381 TGo4AnalysisObjectResult* res = dynamic_cast<TGo4AnalysisObjectResult*>(obj);
00382 if (res==0) return;
00383 Browser()->SyncBrowserSlots();
00384 const char* itemname = res->GetObjectFullName();
00385 TClass* cl = Browser()->ItemClass(itemname);
00386 if (cl!=0) InformThatObjectCreated(itemname, cl);
00387 if (!fNewObjectForEditor) EditItem(itemname);
00388 fNewObjectForEditor = true;
00389 }
00390
00391 void TGo4AnalysisWindow::linkedObjectRemoved(const char* linkname)
00392 {
00393 if (!HasOutput())
00394 ServiceCall("CloseAnalysisWindow");
00395 }
00396
00397 void TGo4AnalysisWindow::resizeEvent(QResizeEvent * e)
00398 {
00399
00400
00401 go4sett->storePanelSize(parentWidget(), "AnalysisWindow");
00402 }
00403