source: src-qt4/life-preserver/LPTray.cpp @ 8516ff2

9.2-releasereleng/10.0releng/10.0.1releng/10.0.2releng/10.0.3
Last change on this file since 8516ff2 was 8516ff2, checked in by Ken Moore <ken@…>, 13 months ago

Setup the LPTray to use the new LPWatcher class (untested yet)

  • Property mode set to 100644
File size: 9.2 KB
Line 
1#include "LPTray.h"
2
3//PUBLIC
4LPTray::LPTray() : QSystemTrayIcon(){
5  initPhase = true; //flag that we are in the startup process
6  //Start up the log file watcher and connect the signals/slots
7  watcher = new LPWatcher();
8        connect(watcher,SIGNAL(MessageAvailable(QString)),this,SLOT(watcherMessage(QString)) );
9       
10  /*QString logfile = "/var/log/lpreserver/lpreserver.log";
11  watcher = new QFileSystemWatcher();
12        if(!QFile::exists(logfile)){
13          if(!QFile::exists("/var/log/lpreserver")){ system( "mkdir /var/log/lpreserver"); }
14          system( QString("touch "+logfile).toUtf8() );
15        }
16        watcher->addPath(logfile);
17  logFile = new QFile(logfile);
18        logFile->open(QIODevice::ReadOnly | QIODevice::Text); //open it now, for faster reading
19  LFStream = new QTextStream(logFile);
20        connect(watcher, SIGNAL(fileChanged(QString)),this,SLOT(slotNewLogMessage(QString)) ); //now connect the signal/slot
21        */
22  //Setup the context menu
23  menu = new QMenu;
24        menu->addAction(new QAction(QIcon(":/images/application-exit.png"),tr("Close Life Preserver Tray"),this) );
25        connect(menu, SIGNAL(triggered(QAction*)), this, SLOT(slotClose()) );
26  this->setContextMenu(menu);
27  //Setup the animated icon timer
28  /*
29  timer = new QTimer();
30        timer->setInterval(100);
31        connect(timer, SIGNAL(timeout()), this, SLOT(displayWorkingIcon()) );
32  */
33  //Setup initial icon for the tray
34  this->setIcon( QIcon(":/images/tray-icon-idle.png") );
35  //Create the configuration GUI
36  GUI = new mainUI();
37  //connect other signals/slots
38  connect(this, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), this, SLOT(slotTrayClicked(QSystemTrayIcon::ActivationReason)) );
39  //Make sure we check the latest line in the logfile
40  //QTimer::singleShot(1000, this,SLOT(firstCheck()));
41  //Start up the watcher
42  watcher->start();
43}
44
45LPTray::~LPTray(){
46  //if(statFile != 0){ statFile->close(); }
47  //logFile->close();
48  //delete statFile;
49  //delete logFile;
50  watcher->stop();
51  delete watcher;
52  //delete menu;
53  //delete timer;
54}
55
56// ===============
57//  PRIVATE FUNCTIONS
58// ===============
59/*
60void LPTray::parseLogMessage(QString log, bool quiet){
61  //Divide up the log into it's sections
62  QString timestamp = log.section(":",0,2).simplified();
63  QString time = timestamp.section(" ",3,3).simplified();
64  QString message = log.section(":",3,3).toLower().simplified();
65  QString dev = log.section(":",4,4).simplified(); //dataset/snapshot/nothing
66  //Now decide what to do/show because of the log message
67  qDebug() << "New Log Message:" << log;
68  if(message.contains("creating snapshot")){
69    dev = message.section(" ",-1).simplified();
70    if(!quiet){ this->showMessage( time, QString(tr("Creating snapshot for %1")).arg(dev), QSystemTrayIcon::Information, 5000); }
71    //Just set the standard idle icon
72    this->setIcon( QIcon(":/images/tray-icon-idle.png") );   
73    setIdleToolTip();
74  }else if(message.contains("starting replication")){
75    startWorkingIcon();
76    //Setup the file watcher for this new log file
77    sFile = dev;
78    if(!sFile.isEmpty()){
79      if(!QFile::exists(sFile)){ system( QString("touch "+sFile).toUtf8() ); }
80      statFile = new QFile(sFile);
81        statFile->open(QIODevice::ReadOnly | QIODevice::Text);
82        SFStream = new QTextStream(statFile);
83      watcher->addPath(sFile); //will update/set tooltips
84    }
85  }else if(message.contains("finished replication")){
86    stopWorkingIcon();
87    //Stop the file wather from watching the status file and clean up
88    if(!sFile.isEmpty()){
89      watcher->removePath(sFile);
90          statFile->close();
91          sFile.clear();
92    }
93    //Clean up and show messages
94    repTotK.clear();
95    setIdleToolTip();
96    dev = message.section(" ",-1).simplified();
97    if(!quiet){ this->showMessage( time, QString(tr("Finished replication for %1")).arg(dev), QSystemTrayIcon::Information, 5000); }
98  }else if( message.contains("FAILED replication") ){
99    stopWorkingIcon();
100    //Stop the file wather from watching the status file and clean up
101    if(!sFile.isEmpty()){
102      watcher->removePath(sFile);
103          statFile->close();
104          sFile.clear();
105    }
106    //Clean up and show messages
107    repTotK.clear();
108    dev = message.section(" ",-1).simplified();
109    QString file = log.section("LOGFILE:",1,1).simplified();
110    QString tt = QString(tr("%1: Replication Failed on %2")).arg(time,dev) +"\n"+ QString(tr("Logfile available at: %1")).arg(file);
111    this->setToolTip(tt);   
112    if(!quiet){ this->showMessage( time, QString(tr("Replication Error for %1")).arg(dev), QSystemTrayIcon::Information, 5000); }
113    this->setIcon(QIcon(":/images/tray-icon-failed.png"));
114  }else{
115    //Just set the standard idle icon
116    //this->setIcon( QIcon(":/images/tray-icon-idle.png") );   
117  }
118  if(GUI->isVisible()){
119    GUI->setupUI();
120  }
121}
122
123void LPTray::parseStatusMessage(QString stat){
124  qDebug() << "New Status Message:" << stat;
125  //Divide up the status message into sections
126  stat.replace("\t"," ");
127  QString dataset = stat.section(" ",2,2,QString::SectionSkipEmpty).section("/",0,0).simplified();
128  QString cSize = stat.section(" ",1,1,QString::SectionSkipEmpty);
129  //Now Setup the tooltip
130  if(cSize != lastSize){ //don't update the tooltip if the same size info
131    QString percent;
132    if(!repTotK.isEmpty()){
133      //calculate the percentage
134      double tot = displayToDoubleK(repTotK);
135      double c = displayToDoubleK(cSize);
136      if( tot!=-1 & c!=-1){
137        double p = (c*100)/tot;
138        p = int(p*10)/10.0; //round to 1 decimel places
139        percent = QString::number(p) + "%";
140      }
141    }
142    if(repTotK.isEmpty()){ repTotK = "??"; }
143    //Format the tooltip String
144    QString status = cSize+"/"+repTotK;
145    if(!percent.isEmpty()){ status.append(" ("+percent+")"); }
146    QString txt = QString(tr("Replicating %1: %2")).arg(dataset, status);
147    this->setToolTip(txt);
148    lastSize = cSize; //save the current size for later
149  }
150}
151
152void LPTray::setIdleToolTip(){
153  //Get the last snapshot created
154  QStringList dsList = LPBackend::listDatasets();
155  if(dsList.isEmpty()){
156    this->setToolTip(tr("Automatic Snapshots Disabled"));
157  }else{
158    //Grab the newest snapshot from each dataset
159    QString tt; //tooltip
160    for(int i=0; i<dsList.length(); i++){
161      QStringList snaps = LPBackend::listLPSnapshots(dsList[0]);
162      if(!tt.isEmpty()){ tt.append("\n"); } //put each dataset on a new line
163      if(snaps.isEmpty()){
164        tt.append( QString(tr("%1: No snapshots available")).arg(dsList[0]) );
165      }else{
166        tt.append( QString(tr("%1: Latest snapshot: %2")).arg(dsList[0],snaps[0]) );
167      }
168    }
169    this->setToolTip(tt);
170  }
171       
172}
173
174void LPTray::startWorkingIcon(){
175  this->setIcon( QIcon(":/images/tray-icon-active7.png"));
176  //wNum = 1; //start on the first image
177  //timer->start();
178}
179
180void LPTray::stopWorkingIcon(){
181  //timer->stop();
182  this->setIcon( QIcon(":/images/tray-icon-idle.png") );     
183}
184
185double LPTray::displayToDoubleK(QString displayNumber){
186  QStringList labels;
187    labels << "K" << "M" << "G" << "T" << "P" << "E";
188  QString clab = displayNumber.right(1); //last character is the size label
189        displayNumber.chop(1); //remove the label from the number
190  double num = displayNumber.toDouble();
191  //Now format the number properly
192  bool ok = false;
193  for(int i=0; i<labels.length(); i++){
194    if(labels[i] == clab){ ok = true; break; }
195    else{ num = num*1024; } //get ready for the next size
196  }
197  if(!ok){ num = -1; } //could not determine the size
198  return num;
199}
200*/
201
202// ===============
203//     PRIVATE SLOTS
204// ===============
205void LPTray::watcherMessage(QString type){
206  qDebug() << "New Watcher Message:" << type;
207}
208/*
209void LPTray::firstCheck(){
210  slotNewLogMessage("/var/log/lpreserver/lpreserver.log");
211  initPhase = false; //done with initializations
212}
213
214void LPTray::slotNewLogMessage(QString file){
215  //qDebug() << "New Log Message in file:" << file;
216  if(file == "/var/log/lpreserver/lpreserver.log"){
217    //Backend Status Update
218    //Now parse the log lines and do stuff with it
219    while( !LFStream->atEnd() ){ parseLogMessage(LFStream->readLine(), initPhase); }
220  }else{
221    //Replication status update
222      //get the last line from the file
223      QString stat;
224      while( !SFStream->atEnd() ){
225        QString line = SFStream->readLine();
226        if(line.contains("total estimated size")){ repTotK = line.section(" ",-1).simplified(); } //save the total size to replicate
227        else if(line.startsWith("send from ")){}
228        else if(line.startsWith("TIME ")){}
229        else{ stat = line; } //only save the relevant status line
230      }
231      //parse the status line
232      if(!stat.isEmpty()){ parseStatusMessage(stat); }
233  }
234}
235*/
236void LPTray::slotTrayClicked(QSystemTrayIcon::ActivationReason reason){
237  if(reason == QSystemTrayIcon::Trigger){ 
238    if(GUI->isVisible()){ GUI->hide(); }
239    else{ startGUI(); }
240  }else if( reason == QSystemTrayIcon::Context){
241    this->contextMenu()->popup(QCursor::pos());
242  }
243}
244
245void LPTray::slotClose(){
246  exit(0);
247}
248
249void LPTray::slotSingleInstance(){
250  this->show();
251  if(!GUI->isVisible()){ startGUI(); }
252  else{ 
253    GUI->raise(); 
254    GUI->show();
255  }
256}
257
258void LPTray::startGUI(){
259  //Start up the GUI
260    GUI->setupUI();
261    GUI->raise();
262    GUI->show();
263}
264
265/*void LPTray::displayWorkingIcon(){
266  QString ico = ":/images/tray-icon-active"+QString::number(wNum)+".png";
267  this->setIcon(QIcon(ico));
268  if(wNum == 16){ wNum = 1; } //go back to the beginning of the loop
269  else{ wNum++; }
270}*/
Note: See TracBrowser for help on using the repository browser.