// @(#)root/proof:$Name: $:$Id: TProofProgressDialog.cxx,v 1.19 2005/12/12 12:54:27 rdm Exp $
// Author: Fons Rademakers 21/03/03
/*************************************************************************
* Copyright (C) 1995-2003, Rene Brun and Fons Rademakers. *
* All rights reserved. *
* *
* For the licensing terms see $ROOTSYS/LICENSE. *
* For the list of contributors see $ROOTSYS/README/CREDITS. *
*************************************************************************/
//////////////////////////////////////////////////////////////////////////
// //
// TProofProgressDialog //
// //
// This class provides a query progress bar. //
// //
//////////////////////////////////////////////////////////////////////////
#include "TProofProgressDialog.h"
#include "TProofProgressLog.h"
#include "TError.h"
#include "TGLabel.h"
#include "TGButton.h"
#include "TGTextBuffer.h"
#include "TGTextEntry.h"
#include "TGProgressBar.h"
#include "TProof.h"
#include "TSystem.h"
#include "TTimer.h"
Bool_t TProofProgressDialog::fgKeepDefault = kTRUE;
Bool_t TProofProgressDialog::fgLogQueryDefault = kFALSE;
TString TProofProgressDialog::fgTextQueryDefault = "last";
ClassImp(TProofProgressDialog)
//______________________________________________________________________________
TProofProgressDialog::TProofProgressDialog(TVirtualProof *proof,
const char *selector,
Int_t files,
Long64_t first,
Long64_t entries)
{
// Create PROOF processing progress dialog.
fProof = proof;
fFiles = files;
fFirst = first;
fEntries = entries;
fPrevProcessed = 0;
fPrevTotal = 0;
fLogWindow = 0;
fStatus = kRunning;
fKeep = fgKeepDefault;
fLogQuery = fgLogQueryDefault;
const TGWindow *main = gClient->GetRoot();
fDialog = new TGTransientFrame(main, main, 10, 10);
fDialog->Connect("CloseWindow()", "TProofProgressDialog", this, "DoClose()");
fDialog->DontCallClose();
// title label
char buf[256];
sprintf(buf, "Executing on PROOF cluster \"%s\" with %d parallel workers:",
fProof ? fProof->GetMaster() : "<dummy>",
fProof ? fProof->GetParallel() : 0);
fTitleLab = new TGLabel(fDialog, buf),
fDialog->AddFrame(fTitleLab,
new TGLayoutHints(kLHintsNormal, 10, 10, 20, 0));
sprintf(buf,"Selector: %s", selector);
fSelector = new TGLabel(fDialog, buf);
fDialog->AddFrame(fSelector,
new TGLayoutHints(kLHintsNormal, 10, 10, 5, 0));
sprintf(buf, "%d files, number of events %lld, starting event %lld",
fFiles, fEntries, fFirst);
fFilesEvents = new TGLabel(fDialog, buf);
fDialog->AddFrame(fFilesEvents, new TGLayoutHints(kLHintsNormal, 10, 10, 5, 0));
// progress bar
fBar = new TGHProgressBar(fDialog, TGProgressBar::kFancy, 450);
fBar->SetBarColor("green");
fDialog->AddFrame(fBar, new TGLayoutHints(kLHintsTop | kLHintsLeft |
kLHintsExpandX, 10, 10, 20, 20));
// status labels
TGHorizontalFrame *hf1 = new TGHorizontalFrame(fDialog, 0, 0);
TGCompositeFrame *cf1 = new TGCompositeFrame(hf1, 110, 0, kFixedWidth);
fProcessed = new TGLabel(cf1, "Estimated time left:");
cf1->AddFrame(fProcessed);
hf1->AddFrame(cf1);
fTotal= new TGLabel(hf1, "- sec (- events of - processed)");
hf1->AddFrame(fTotal, new TGLayoutHints(kLHintsNormal, 10, 10, 0, 0));
fDialog->AddFrame(hf1, new TGLayoutHints(kLHintsNormal, 10, 10, 5, 0));
TGHorizontalFrame *hf2 = new TGHorizontalFrame(fDialog, 0, 0);
TGCompositeFrame *cf2 = new TGCompositeFrame(hf2, 110, 0, kFixedWidth);
cf2->AddFrame(new TGLabel(cf2, "Processing rate:"));
hf2->AddFrame(cf2);
fRate = new TGLabel(hf2, "- events/sec");
hf2->AddFrame(fRate, new TGLayoutHints(kLHintsNormal, 10, 10, 0, 0));
fDialog->AddFrame(hf2, new TGLayoutHints(kLHintsNormal, 10, 10, 5, 0));
// Keep toggle button
fKeepToggle = new TGCheckButton(fDialog,
new TGHotString("Close dialog when processing is complete"));
if (!fKeep) fKeepToggle->SetState(kButtonDown);
fKeepToggle->Connect("Toggled(Bool_t)",
"TProofProgressDialog", this, "DoKeep(Bool_t)");
fDialog->AddFrame(fKeepToggle, new TGLayoutHints(kLHintsNormal, 10, 10, 20, 0));
// logs-from-given-query-only toggle button
TGHorizontalFrame *hflog = new TGHorizontalFrame(fDialog, 200, 20, kFixedWidth);
fLogQueryToggle = new TGCheckButton(hflog,
new TGHotString("Show only logs from query"));
if (!fLogQuery) fLogQueryToggle->SetState(kButtonUp);
fLogQueryToggle->Connect("Toggled(Bool_t)",
"TProofProgressDialog", this, "DoSetLogQuery(Bool_t)");
hflog->AddFrame(fLogQueryToggle,
new TGLayoutHints(kLHintsCenterY | kLHintsLeft, 0, 0, 0, 0));
// text entry for logs-from-given-query-only toggle button
fTextQuery = new TGTextBuffer();
fTextQuery->AddText(0, fgTextQueryDefault, 32);
fEntry = new TGTextEntry(hflog, fTextQuery);
if (fLogQuery)
fEntry->SetToolTipText("Enter the query number ('last' for the last query)",50);
fEntry->SetEnabled(fLogQuery);
hflog->AddFrame(fEntry, new TGLayoutHints(kLHintsCenterY |
kLHintsExpandX, 2, 0, 0, 0));
fDialog->AddFrame(hflog, new TGLayoutHints(kLHintsNormal, 10, 10, 5, 0));
// stop, cancel and close buttons
TGHorizontalFrame *hf3 = new TGHorizontalFrame(fDialog, 60, 20, kFixedWidth);
UInt_t nb = 0, width = 0, height = 0;
fStop = new TGTextButton(hf3, "&Stop");
fStop->SetToolTipText("Stop processing, Terminate() will be executed");
fStop->Connect("Clicked()", "TProofProgressDialog", this, "DoStop()");
hf3->AddFrame(fStop, new TGLayoutHints(kLHintsCenterY | kLHintsExpandX, 7, 7, 0, 0));
height = TMath::Max(height, fStop->GetDefaultHeight());
width = TMath::Max(width, fStop->GetDefaultWidth()); ++nb;
fAbort = new TGTextButton(hf3, "&Cancel");
fAbort->SetToolTipText("Cancel processing, Terminate() will NOT be executed");
fAbort->Connect("Clicked()", "TProofProgressDialog", this, "DoAbort()");
hf3->AddFrame(fAbort, new TGLayoutHints(kLHintsCenterY | kLHintsExpandX, 7, 7, 0, 0));
height = TMath::Max(height, fAbort->GetDefaultHeight());
width = TMath::Max(width, fAbort->GetDefaultWidth()); ++nb;
fClose = new TGTextButton(hf3, "&Close");
fClose->SetToolTipText("Close this dialog");
fClose->SetState(kButtonDisabled);
fClose->Connect("Clicked()", "TProofProgressDialog", this, "DoClose()");
hf3->AddFrame(fClose, new TGLayoutHints(kLHintsCenterY | kLHintsExpandX, 7, 7, 0, 0));
height = TMath::Max(height, fClose->GetDefaultHeight());
width = TMath::Max(width, fClose->GetDefaultWidth()); ++nb;
fLog = new TGTextButton(hf3, "&Show Logs");
fLog->SetToolTipText("Show query log messages");
fLog->Connect("Clicked()", "TProofProgressDialog", this, "DoLog()");
hf3->AddFrame(fLog, new TGLayoutHints(kLHintsCenterY | kLHintsExpandX, 7, 7, 0, 0));
height = TMath::Max(height, fLog->GetDefaultHeight());
width = TMath::Max(width, fLog->GetDefaultWidth()); ++nb;
// place button frame (hf3) at the bottom
fDialog->AddFrame(hf3, new TGLayoutHints(kLHintsBottom | kLHintsCenterX, 10, 10, 20, 10));
// keep buttons centered and with the same width
hf3->Resize((width + 40) * nb, height);
// connect slot to proof progress signal
if (fProof) {
fProof->Connect("Progress(Long64_t,Long64_t)", "TProofProgressDialog",
this, "Progress(Long64_t,Long64_t)");
fProof->Connect("StopProcess(Bool_t)", "TProofProgressDialog", this,
"IndicateStop(Bool_t)");
fProof->Connect("ResetProgressDialog(const char*,Int_t,Long64_t,Long64_t)",
"TProofProgressDialog", this,
"ResetProgressDialog(const char*,Int_t,Long64_t,Long64_t)");
}
// set dialog title
fDialog->SetWindowName(Form("PROOF Query Progress: %s",
(fProof ? fProof->GetMaster() : "<dummy>")));
// map all widgets and calculate size of dialog
fDialog->MapSubwindows();
width = fDialog->GetDefaultWidth();
height = fDialog->GetDefaultHeight();
fDialog->Resize(width, height);
// position relative to the parent window (which is the root window)
Window_t wdum;
int ax, ay;
Int_t mw = ((TGFrame *) main)->GetWidth();
Int_t mh = ((TGFrame *) main)->GetHeight();
gVirtualX->TranslateCoordinates(main->GetId(), main->GetId(),
(mw - width), (mh - height) >> 1, ax, ay, wdum);
fDialog->Move(ax-5, ay - mh/4);
fDialog->SetWMPosition(ax-5, ay - mh/4);
// make the message box non-resizable
fDialog->SetWMSize(width, height);
fDialog->SetWMSizeHints(width, height, width, height, 0, 0);
fDialog->SetMWMHints(kMWMDecorAll | kMWMDecorResizeH | kMWMDecorMaximize |
kMWMDecorMinimize | kMWMDecorMenu,
kMWMFuncAll | kMWMFuncResize | kMWMFuncMaximize |
kMWMFuncMinimize,
kMWMInputModeless);
// popup dialog and wait till user replies
fDialog->MapWindow();
fStartTime = gSystem->Now();
//gClient->WaitFor(fDialog);
}
//______________________________________________________________________________
void TProofProgressDialog::ResetProgressDialog(const char *selec,
Int_t files, Long64_t first,
Long64_t entries)
{
// Reset dialog box preparing for new query
char buf[512];
// Update title
sprintf(buf, "Executing on PROOF cluster \"%s\" with %d parallel workers:",
fProof ? fProof->GetMaster() : "<dummy>",
fProof ? fProof->GetParallel() : 0);
fTitleLab->SetText(buf);
// Reset members
fFiles = files;
fFirst = first;
fEntries = entries;
fPrevProcessed = 0;
fPrevTotal = 0;
fStatus = kRunning;
// Update selector name
sprintf(buf,"Selector: %s", selec);
fSelector->SetText(buf);
// Update numbers
sprintf(buf, "%d files, number of events %lld, starting event %lld",
fFiles, fEntries, fFirst);
fFilesEvents->SetText(buf);
// Reset progress bar
fBar->SetBarColor("green");
fBar->Reset();
// Reset buttons
fStop->SetState(kButtonUp);
fAbort->SetState(kButtonUp);
fClose->SetState(kButtonDisabled);
// Reconnect the slots
if (fProof) {
fProof->Connect("Progress(Long64_t,Long64_t)", "TProofProgressDialog",
this, "Progress(Long64_t,Long64_t)");
fProof->Connect("StopProcess(Bool_t)", "TProofProgressDialog", this,
"IndicateStop(Bool_t)");
}
// Reset start time
fStartTime = gSystem->Now();
}
//______________________________________________________________________________
void TProofProgressDialog::Progress(Long64_t total, Long64_t processed)
{
// Update progress bar and status labels.
char buf[256];
static const char *cproc[] = { "running", "done", "STOPPED", "ABORTED" };
// Update title
sprintf(buf, "Executing on PROOF cluster \"%s\" with %d parallel workers:",
fProof ? fProof->GetMaster() : "<dummy>",
fProof ? fProof->GetParallel() : 0);
fTitleLab->SetText(buf);
if (total < 0)
total = fPrevTotal;
else
fPrevTotal = total;
if (fPrevProcessed == processed)
return;
if (fEntries != total) {
fEntries = total;
sprintf(buf, "%d files, number of events %lld, starting event %lld",
fFiles, fEntries, fFirst);
fFilesEvents->SetText(buf);
}
Float_t pos = Float_t(Double_t(processed * 100)/Double_t(total));
fBar->SetPosition(pos);
// get current time
fEndTime = gSystem->Now();
TTime tdiff = fEndTime - fStartTime;
Float_t eta = 0;
if (processed)
eta = ((Float_t)((Long_t)tdiff)*total/Float_t(processed) - Long_t(tdiff))/1000.;
if (processed == total) {
fProcessed->SetText("Processed:");
sprintf(buf, "%lld events in %.1f sec", total, Long_t(tdiff)/1000.);
fTotal->SetText(buf);
if (fProof) {
fProof->Disconnect("Progress(Long64_t,Long64_t)", this,
"Progress(Long64_t,Long64_t)");
fProof->Disconnect("StopProcess(Bool_t)", this,
"IndicateStop(Bool_t)");
}
// Set button state
fStop->SetState(kButtonDisabled);
fAbort->SetState(kButtonDisabled);
fClose->SetState(kButtonUp);
if (!fKeep)
DoClose();
} else {
if (fStatus > kDone) {
sprintf(buf, "%.1f sec (%lld events of %lld processed) - %s",
eta, processed, total, cproc[fStatus]);
} else {
sprintf(buf, "%.1f sec (%lld events of %lld processed)",
eta, processed, total);
}
fTotal->SetText(buf);
sprintf(buf, "%.1f events/sec", Float_t(processed)/Long_t(tdiff)*1000.);
fRate->SetText(buf);
}
fPrevProcessed = processed;
fDialog->Layout();
}
//______________________________________________________________________________
TProofProgressDialog::~TProofProgressDialog()
{
// Cleanup dialog.
if (fProof) {
fProof->Disconnect("Progress(Long64_t,Long64_t)", this,
"Progress(Long64_t,Long64_t)");
fProof->Disconnect("StopProcess(Bool_t)", this,
"IndicateStop(Bool_t)");
fProof->Disconnect("LogMessage(const char*,Bool_t)", this,
"LogMessage(const char*,Bool_t)");
fProof->Disconnect("ResetProgressDialog(const char*,Int_t,Long64_t,Long64_t)",
this,
"ResetProgressDialog(const char*,Int_t,Long64_t,Long64_t)");
fProof->ResetProgressDialogStatus();
}
if (fLogWindow)
delete fLogWindow;
fDialog->Cleanup();
delete fDialog;
}
//______________________________________________________________________________
void TProofProgressDialog::CloseWindow()
{
// Called when dialog is closed.
delete this;
}
//______________________________________________________________________________
void TProofProgressDialog::IndicateStop(Bool_t aborted)
{
// Indicate that Cancel or Stop was clicked.
if (aborted == kTRUE)
fBar->SetBarColor("red");
else
fBar->SetBarColor("yellow");
if (fProof) {
fProof->Disconnect("Progress(Long64_t,Long64_t)", this,
"Progress(Long64_t,Long64_t)");
fProof->Disconnect("StopProcess(Bool_t)", this,
"IndicateStop(Bool_t)");
// These buttons are meaningless at this point
fStop->SetState(kButtonDisabled);
fAbort->SetState(kButtonDisabled);
}
fClose->SetState(kButtonUp);
if (!fKeep)
DoClose();
}
//______________________________________________________________________________
void TProofProgressDialog::LogMessage(const char *msg, Bool_t all)
{
// Load/append a log msg in the log frame, if open
if (fLogWindow) {
if (all) {
// load buffer
fLogWindow->LoadBuffer(msg);
} else {
// append
fLogWindow->AddBuffer(msg);
}
}
}
//______________________________________________________________________________
void TProofProgressDialog::DoClose()
{
// Close dialog.
fClose->SetState(kButtonDisabled);
TTimer::SingleShot(50, "TProofProgressDialog", this, "CloseWindow()");
}
//______________________________________________________________________________
void TProofProgressDialog::DoLog()
{
// Ask proof session for logs
if (fProof) {
if (!fLogWindow) {
fLogWindow = new TProofProgressLog(this);
} else {
// Clear window
fLogWindow->Clear();
}
fProof->Connect("LogMessage(const char*,Bool_t)", "TProofProgressDialog",
this, "LogMessage(const char*,Bool_t)");
if (!fLogQuery) {
fProof->LogMessage(0, kTRUE);
} else {
Int_t qry = -2;
TString qs = fTextQuery->GetString();
if (qs != "last" && qs.IsDigit())
qry = qs.Atoi();
Bool_t logonly = fProof->SendingLogToWindow();
fProof->SendLogToWindow(kTRUE);
fProof->ShowLog(qry);
fProof->SendLogToWindow(logonly);
}
}
}
//______________________________________________________________________________
void TProofProgressDialog::DoKeep(Bool_t)
{
// Handle keep toggle button.
fKeep = !fKeep;
// Last choice will be the default for the future
fgKeepDefault = fKeep;
}
//______________________________________________________________________________
void TProofProgressDialog::DoSetLogQuery(Bool_t)
{
// Handle log-current-query-only toggle button.
fLogQuery = !fLogQuery;
fEntry->SetEnabled(fLogQuery);
if (fLogQuery)
fEntry->SetToolTipText("Enter the query number ('last' for the last query)",50);
else
fEntry->SetToolTipText(0);
// Last choice will be the default for the future
fgLogQueryDefault = fLogQuery;
}
//______________________________________________________________________________
void TProofProgressDialog::DoStop()
{
// Handle Stop button.
fProof->StopProcess(kFALSE);
fStatus = kStopped;
// Set buttons states
fStop->SetState(kButtonDisabled);
fAbort->SetState(kButtonDisabled);
fClose->SetState(kButtonUp);
}
//______________________________________________________________________________
void TProofProgressDialog::DoAbort()
{
// Handle Cancel button.
fProof->StopProcess(kTRUE);
fStatus = kAborted;
// Set buttons states
fStop->SetState(kButtonDisabled);
fAbort->SetState(kButtonDisabled);
fClose->SetState(kButtonUp);
}
ROOT page - Class index - Class Hierarchy - Top of the page
This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.