Ksetiwatch API Documentation


analysis.cpp

Go to the documentation of this file.
00001 /***************************************************************************/
00014 #include <kapp.h>
00015 #include <klocale.h>
00016 #include <kiconloader.h>
00017 #include <kmessagebox.h>
00018 #include <kaudioplayer.h>
00019 
00020 #include <qcursor.h>
00021 #include <qstring.h>
00022 #include <qstringlist.h>
00023 #include <qheader.h>
00024 #include <qlist.h>
00025 #include <qdir.h>
00026 #include <qpushbutton.h>
00027 #include <qpopupmenu.h>
00028 #include <qcombobox.h>
00029 #include <qtooltip.h>
00030 #include <qlabel.h>
00031 #include <qtimer.h>
00032 #include <qbitmap.h>
00033 #include <qpainter.h>
00034 
00035 #include "setiloc.h"
00036 #include "ksetiwatch.h"
00037 #include "analysis.h"
00038 #include "addsetilocdlg.h"
00039 #include "sigmsg.h"
00040 #include "poplistview.h"
00041 
00042 /*------------------------------------------------------------------------ */
00044 QString AnalysisListViewItem::key(int column, bool) const
00045 {
00046 // return value must be static
00047 static QString ret;
00048 QString val;
00049 double tmp;
00050 
00051 if(column == 2 || column == 3 || (column >= 6 && column <= 8))
00052   {
00053   val = text(column);
00054   tmp = val.toDouble();
00055   val.sprintf("%f", tmp);
00056   ret = val.rightJustify(32, '0');
00057   }
00058 else if(column == 4 || column == 5)
00059   {
00060   int colon;
00061   int d(0), h(0), m(0), s(0);
00062 
00063   val = text(column);
00064   colon = val.contains(':');
00065   if(colon == 2)
00066     {
00067     sscanf(text(column), "%d:%d:%d", &h, &m, &s);
00068     }
00069   else if(colon == 3)
00070     {
00071     sscanf(text(column), "%dd:%d:%d:%d", &d, &h, &m, &s);
00072     }
00073   tmp = 86400*d + 3600*h + 60*m + s;
00074   ret.sprintf("%032d", (int)tmp);
00075   }
00076 else if(column == 9)
00077   {
00078   if(text(column).isEmpty())
00079     tmp = 0.0;
00080   else
00081     sscanf(text(column), " scr=%lf", &tmp);
00082   val.sprintf("%f", tmp);
00083   ret = val.rightJustify(32, '0');
00084   }
00085 else if(column == 1)
00086   {
00087   SetiLoc* loc = Ksetiwatch::getLocation(this->text(0));
00088   ret.sprintf("%d", loc->clientState());
00089   }
00090 else
00091   {
00092   ret = text(column);
00093   }
00094 
00095 return(ret);
00096 }
00097 
00098 /***************************************************************************/
00099 
00100 Analysis::Analysis(QWidget *parent, const char *name) : QWidget(parent,name)
00101 {
00102 Ksetiwatch::TableColumn antc[] =
00103   {
00104   {i18n("Location"), -1, AlignLeft},
00105   {i18n("Status"), -1, AlignCenter},
00106   {i18n("Chirp Rate"), -1, AlignRight},
00107   {i18n("% Done"), -1, AlignRight},
00108   {i18n("CPU Time"), 65, AlignRight},
00109   {i18n("Time Left"), 60, AlignRight},
00110   {i18n("%/CPU Hour"), -1, AlignRight},
00111   {i18n("MFlops"), -1, AlignRight},
00112   {i18n("Spike"), 55, AlignRight},
00113   {i18n("Strongest Gaussian"), -1, AlignLeft},
00114   {i18n("Strongest Pulse"), -1, AlignLeft},
00115   {i18n("Strongest Triplet"), -1, AlignLeft}
00116   };
00117 
00118 const QStringList statusfilterList = QStringList() << i18n("All")
00119                                                    << i18n("Stopped")
00120                                                    << i18n("Running")
00121                                                    << i18n("Finished")
00122                                                    << i18n("Loading")
00123                                                    << i18n("Running+Finished");
00124 
00125 // Set up the list view with popup menu.
00126 LocListView = new popListView(this, globalopts->DrawGrid);
00127 LocListView->setShowSortIndicator(false);
00128 LocListView->popupSetTitle(i18n("Location"));
00129 LocListView->insertPopupItem(SmallIcon("mini-setiadd"),
00130                              i18n("Add...   "), PopupAdd);
00131 LocListView->setAccel(CTRL + Key_Plus, PopupAdd);
00132 LocListView->insertPopupItem(SmallIcon("configure"),
00133                              i18n("Edit..."), PopupEdit);
00134 LocListView->setAccel(CTRL + Key_Enter, PopupEdit);
00135 LocListView->insertPopupItem(SmallIcon("mini-setiremove"),
00136                              i18n("Delete"), PopupDelete);
00137 LocListView->setAccel(CTRL + Key_Minus, PopupDelete);
00138 LocListView->insertSeparator();
00139 LocListView->insertPopupItem(SmallIcon("mini-setirunning"),
00140                              i18n("Start Client"), PopupStart);
00141 LocListView->setAccel(CTRL + Key_R, PopupStart);
00142 LocListView->insertPopupItem(SmallIcon("mini-setistopped"),
00143                              i18n("Stop Client"), PopupStop);
00144 LocListView->setAccel(CTRL + Key_S, PopupStop);
00145 LocListView->insertSeparator();
00146 showOptions = new QPopupMenu(this);
00147 showOptions->insertItem(QIconSet(SmallIcon("mini-gaussian"), QIconSet::Small),
00148                         i18n("Gaussian"), SetiLoc::GaussianGraph);
00149 showOptions->insertItem(QIconSet(SmallIcon("mini-pulse"), QIconSet::Small),
00150                              i18n("Pulse"), SetiLoc::PulseGraph);
00151 showOptions->insertItem(QIconSet(SmallIcon("mini-triplet"), QIconSet::Small),
00152                              i18n("Triplet"), SetiLoc::TripletGraph);
00153 showOptions->insertSeparator();
00154 showOptions->insertItem(QIconSet(SmallIcon("leftjust"), QIconSet::Small),
00155                         i18n("Client Output"), SetiLoc::ClientOutput);
00156 LocListView->insertPopupItem(i18n("Show..."), showOptions, PopupShow);
00157 LocListView->setPopupStyle(popListView::ShowAnywhere);
00158 LocListView->move(5,1);
00159 connect(showOptions, SIGNAL(activated(int)),
00160                this, SLOT(handleShowPopupCommand(int)));
00161 connect(LocListView->popupMenu(), SIGNAL(activated(int)),
00162                             this, SLOT(handlePopupCommand(int)));
00163 connect(LocListView->popupMenu(), SIGNAL(aboutToShow()),
00164                             this, SLOT(checkPopupStatus()));
00165 connect(LocListView->header(), SIGNAL(sectionClicked(int)),
00166                          this, SLOT(toggleSorting(int)));
00167 sortingorder = true;
00168 connect(LocListView, SIGNAL(selectionChanged(QListViewItem*)),
00169                this, SLOT(handleNewSelection(QListViewItem*)));
00170 connect(LocListView->header(), SIGNAL(sizeChange(int, int, int)),
00171                          this, SLOT(slotAdjustAllStatusIcons(int, int, int)));
00172                
00173 LocListViewHidden = new QListView(this);
00174 LocListViewHidden->hide();
00175 
00176 // Add the columns to the list view.
00177 for(int i=0; i<(int)(sizeof(antc)/sizeof(antc[0])); i++)
00178   {
00179   LocListView->addColumn(antc[i].text, -1);
00180   LocListViewHidden->addColumn(antc[i].text, -1);
00181   if(antc[i].width != -1)
00182     LocListView->setColumnWidth(i, antc[i].width);
00183   LocListView->setColumnAlignment(i, antc[i].alignment);
00184   }
00185 
00186 // Create the control widgets at the bottom of this tab.
00187 StartAllBtn = new QPushButton(this);
00188 StartAllBtn->resize(35, 27);
00189 StartAllBtn->setPixmap(SmallIcon("mini-setirunning"));
00190 QToolTip::add(StartAllBtn, i18n("Start All"));
00191 connect(StartAllBtn, SIGNAL(clicked()), SLOT(slotStartAll()));
00192 
00193 RefreshBtn = new QPushButton(this);
00194 RefreshBtn->resize(35, 27);
00195 RefreshBtn->setPixmap(SmallIcon("reload"));
00196 QToolTip::add(RefreshBtn, i18n("Refresh"));
00197 connect(RefreshBtn, SIGNAL(clicked()), SLOT(refreshList()));
00198 
00199 StopAllBtn = new QPushButton(this);
00200 StopAllBtn->resize(35, 27);
00201 StopAllBtn->setPixmap(SmallIcon("mini-setistopped"));
00202 QToolTip::add(StopAllBtn, i18n("Stop All"));
00203 connect(StopAllBtn, SIGNAL(clicked()), SLOT(slotStopAll()));
00204 
00205 HelpBtn = new QPushButton(this);
00206 HelpBtn->setMinimumSize(HelpBtn->sizeHint().width() + 20, 27);
00207 HelpBtn->resize(HelpBtn->sizeHint());
00208 HelpBtn->setText(i18n("Help"));
00209 connect(HelpBtn, SIGNAL(clicked()), SLOT(slotShowHelp()) );
00210 
00211 // Create a pushbutton with an icon. Doesn't work with all KDE themes!
00212 HomepageBtn = new QPushButton(i18n("Homepage"), this);
00213 HomepageBtn->setIconSet(SmallIconSet("ksetiwatch"));
00214 HomepageBtn->setMinimumSize(HomepageBtn->sizeHint().width(), 27);
00215 HomepageBtn->resize(HomepageBtn->sizeHint().width(), 27);
00216 connect(HomepageBtn, SIGNAL(clicked()), SLOT(openBrowser()) );
00217 
00218 StatusFilter = new QComboBox(false, this);
00219 StatusFilter->insertStringList(statusfilterList);
00220 StatusFilter->setMinimumSize(StatusFilter->sizeHint().width(), 27);
00221 StatusFilter->resize(StatusFilter->sizeHint().width(), 27);
00222 ComboLabel = new QLabel(this);
00223 ComboLabel->setAutoResize(true);
00224 ComboLabel->setAlignment(AlignRight);
00225 ComboLabel->setText(i18n("Show:"));
00226 connect(StatusFilter, SIGNAL(activated(int)), SLOT(modifyStatusFilter(int)));
00227 
00228 // Load the status icons.
00229 StatusIcon[0] = SmallIcon("mini-setistopped");
00230 StatusIcon[1] = SmallIcon("mini-setirunning");  
00231 StatusIcon[2] = SmallIcon("mini-setifinished");
00232 StatusIcon[3] = SmallIcon("mini-setiloading");
00233 StatusIcon[4] = SmallIcon("connect_creating");
00234 
00235 // Single-shot timer in order to display a message box in case no location
00236 // is configured.
00237 QTimer::singleShot(1500, this, SLOT(slotAskForLocation()));
00238 
00239 // Fill the list.
00240 refreshList();
00241 }
00242 
00243 /*------------------------------------------------------------------------ */
00244 Analysis::~Analysis()
00245 {
00246 }
00247 
00248 /*------------------------------------------------------------------------ */
00249 void Analysis::resizeEvent(QResizeEvent*)
00250 {
00251 LocListView->resize(this->width()-10,
00252                     this->height()-HelpBtn->height()-5);
00253 StartAllBtn->move(5, LocListView->y()+LocListView->height()+
00254                      (HelpBtn->height()-StartAllBtn->height())/2+2);
00255 RefreshBtn->move(10+StartAllBtn->width(), LocListView->y()+
00256                  LocListView->height()+
00257                  (HelpBtn->height()-RefreshBtn->height())/2+2);
00258 StopAllBtn->move(15+StartAllBtn->width()+RefreshBtn->width(),
00259                   LocListView->y()+LocListView->height()+
00260                   (HelpBtn->height()-StopAllBtn->height())/2+2);
00261 ComboLabel->move(StopAllBtn->x()+StopAllBtn->width()+16,
00262                  LocListView->y()+LocListView->height()+
00263                  (HelpBtn->height()-ComboLabel->height())/2+2);
00264 StatusFilter->move(ComboLabel->x()+ComboLabel->width()+4,
00265                    LocListView->y()+LocListView->height()+2);
00266 HomepageBtn->move(width()-HomepageBtn->width()-5,
00267                LocListView->y()+LocListView->height()+2);
00268 HelpBtn->move(width()-HomepageBtn->width()-HelpBtn->width()-15,
00269            LocListView->y()+LocListView->height()+2);
00270 }
00271 
00272 /*------------------------------------------------------------------------ */
00273 void Analysis::paintEvent(QPaintEvent* e)
00274 {
00275 LocListView->setGridEnabled(globalopts->DrawGrid);
00276 QWidget::paintEvent(e);
00277 }
00278 
00279 /*------------------------------------------------------------------------ */
00280 void Analysis::handlePopupCommand(int id)
00281 {
00282 SetiLoc* loc = getLocation(selectedItem());
00283 
00284 switch(id)
00285   {
00286   case PopupAdd: // add a new SETI location
00287     {
00288     AddSetiLocDlg dlg(topLevelWidget());
00289     dlg.setCaption(i18n("Add SETI@home Location..."));
00290     if(dlg.exec() == QDialog::Accepted)
00291       {
00292       LocSettings ls = dlg.options();
00293       SetiLoc* loc = new SetiLoc(dlg.setiDirectory());
00294       loc->setOptions(ls);
00295       // Notifies the main Ksetiwatch object, which maintains the list of locations,
00296       // of the change.
00297       emit listChangeRequested(loc, Ksetiwatch::ListAdd);
00298       }
00299     break;
00300     }
00301   case PopupEdit: // edit an existing SETI location
00302     {
00303     if(loc)
00304       {
00305       // create the dialog and fill it with the corresponding data
00306       AddSetiLocDlg dlg(topLevelWidget());
00307       dlg.setCaption(i18n("Edit SETI@home Location..."));
00308       dlg.setOptions(loc->options());
00309       if(dlg.exec() == QDialog::Accepted)
00310         {
00311         loc->setOptions(dlg.options());
00312         // Notifies the main Ksetiwatch object, which maintains the list of locations,
00313         // of the change.
00314         emit listChangeRequested(loc, Ksetiwatch::ListEdit);
00315         }
00316       }
00317     break;
00318     }
00319   case PopupDelete: // remove a SETI location
00320     {
00321     if(loc)
00322       {
00323       emit selectionChanged(0);
00324       // Notifies the main Ksetiwatch object, which maintains the list of locations,
00325       // of the change.
00326       emit listChangeRequested(loc, Ksetiwatch::ListDelete);
00327       }
00328     break;
00329     }
00330   case PopupStart: // start the client
00331     {
00332     if(loc)
00333       loc->startClient();
00334     break;
00335     }
00336   case PopupStop: // stop the client
00337     {
00338     if(loc)
00339       loc->stopClient();
00340     break;
00341     }
00342   }
00343 }
00344 
00345 /*------------------------------------------------------------------------ */
00346 void Analysis::checkPopupStatus()
00347 {
00348 // convert global coords to local widget coords and subtract header height
00349 QPoint p = LocListView->mapFromGlobal(QCursor::pos()) -
00350            QPoint(0, LocListView->header()->height());
00351 // is an item below the mouse pointer? If so, enable Edit and Delete
00352 if(LocListView->itemAt(p))
00353   {
00354   LocListView->popupMenu()->setItemEnabled(PopupEdit, true);
00355   LocListView->popupMenu()->setItemEnabled(PopupDelete, true);
00356   // get the status of the clients and enable or disable the Start/Stop
00357   // menu items
00358   LocListView->popupMenu()->setItemEnabled(PopupStart, false);
00359   LocListView->popupMenu()->setItemEnabled(PopupStop, false);
00360   SetiLoc* loc = getLocation(static_cast<AnalysisListViewItem*>(LocListView->currentItem()));
00361   if(loc)
00362     {
00363     switch(loc->clientState())
00364       {
00365       case SetiLoc::Running:
00366       case SetiLoc::Loading:
00367       case SetiLoc::Connecting:
00368         {
00369         // enable stop
00370         LocListView->popupMenu()->setItemEnabled(PopupStop, true);
00371         break;
00372         }
00373       case SetiLoc::Stopped:
00374         {
00375         // enable start
00376         LocListView->popupMenu()->setItemEnabled(PopupStart, true);
00377         break;
00378         }
00379       case SetiLoc::Finished:
00380         {
00381         if(loc->isClientRunning() == true)
00382           LocListView->popupMenu()->setItemEnabled(PopupStop, true);
00383         else
00384           LocListView->popupMenu()->setItemEnabled(PopupStart, true);
00385         break;
00386         }
00387       }
00388     LocListView->popupMenu()->setItemEnabled(PopupShow, true);
00389     // enable Gaussian display only when a Gaussian has been found
00390     WUScore max = loc->wuScore();
00391     if(max.gaussian.score > 0.0 && loc->clientVersion() > 100)
00392       showOptions->setItemEnabled(soGaussian, true);
00393     else
00394       showOptions->setItemEnabled(soGaussian, false);
00395     // enable pulse display only when a pulse has been found
00396     if(max.pulse.score > 0.0 && loc->clientVersion() >= 300)
00397       showOptions->setItemEnabled(soPulse, true);
00398     else
00399       showOptions->setItemEnabled(soPulse, false);
00400     // enable triplet display only when a triplet has been found
00401     if(max.triplet.score > 0.0 && loc->clientVersion() >= 300)
00402       showOptions->setItemEnabled(soTriplet, true);
00403     else
00404       showOptions->setItemEnabled(soTriplet, false);
00405     }
00406   }
00407 else // disable everything except Add
00408   {
00409   LocListView->popupMenu()->setItemEnabled(PopupEdit, false);
00410   LocListView->popupMenu()->setItemEnabled(PopupDelete, false);
00411   LocListView->popupMenu()->setItemEnabled(PopupStart, false);
00412   LocListView->popupMenu()->setItemEnabled(PopupStop, false);
00413   LocListView->popupMenu()->setItemEnabled(PopupShow, false);
00414   }
00415 }
00416 
00417 /*------------------------------------------------------------------------ */
00418 void Analysis::handleShowPopupCommand(int id)
00419 {
00420 AnalysisListViewItem *it = selectedItem();
00421 SetiLoc* loc = getLocation(it);
00422 
00423 if(loc)
00424   loc->showGraph(id);
00425 }
00426 
00427 /*------------------------------------------------------------------------ */
00428 void Analysis::refreshList()
00429 {
00430 QList<SetiLoc> seli = Ksetiwatch::locationList();
00431 
00432 for(SetiLoc* loc=seli.first(); loc != 0; loc=seli.next())
00433   {
00434   AnalysisListViewItem* it = locationItemById(loc->id());
00435   if(it == 0)
00436     slotUpdateList(loc, Ksetiwatch::ListAdd);
00437   else
00438     refreshListItem(loc);
00439   }
00440 }
00441 
00442 /*------------------------------------------------------------------------ */
00443 void Analysis::refreshListItem(SetiLoc* loc)
00444 {
00445 updateStateIcon(loc, loc->clientState(), 0);
00446 updateListItemTimeData(loc);
00447 updateListItemSpikeData(loc);
00448 updateListItemGaussianData(loc);
00449 updateListItemPulseData(loc);
00450 updateListItemTripletData(loc);
00451 }
00452 
00453 /*------------------------------------------------------------------------ */
00454 void Analysis::slotUpdateList(SetiLoc* loc, int type)
00455 {
00456 AnalysisListViewItem* it;
00457 
00458 switch(type)
00459   {
00460   case Ksetiwatch::ListAdd:
00461     {
00462     it = lvDictHidden[loc->id()];
00463     if(it)
00464       {
00465       lvDictHidden.remove(loc->id());
00466       lvDict.insert(loc->id(), it);
00467       LocListViewHidden->takeItem(it);
00468       LocListView->insertItem(it);
00469       centerStatusIcon(it, loc->clientState());
00470       }
00471     else
00472       {
00473       it = new AnalysisListViewItem(LocListView);
00474       if(it)
00475         {
00476         lvDict.insert(loc->id(), it);
00477         connect(loc,  SIGNAL(stateChanged(int,int)),
00478                 this, SLOT(slotShowNewState(int,int)));
00479         connect(loc,  SIGNAL(progressIncreased()),
00480                 this, SLOT(slotUpdateAnalysisTimeData()));
00481         connect(loc,  SIGNAL(newSpike(SpikeScore)),
00482                 this, SLOT(slotUpdateAnalysisSpikeData(SpikeScore)));   
00483         connect(loc,  SIGNAL(newGaussian(GaussianScore)),
00484                 this, SLOT(slotUpdateAnalysisGaussianData(GaussianScore))); 
00485         connect(loc,  SIGNAL(newPulse(PulseScore)),
00486                 this, SLOT(slotUpdateAnalysisPulseData(PulseScore)));   
00487         connect(loc,  SIGNAL(newTriplet(TripletScore)),
00488                 this, SLOT(slotUpdateAnalysisTripletData(TripletScore)));
00489         loc->initMaxScore();
00490         refreshListItem(loc);
00491         }
00492       }
00493     break;
00494     }
00495   case Ksetiwatch::ListEdit:
00496     {
00497     refreshListItem(loc);
00498     break;
00499     }
00500   case Ksetiwatch::ListDelete:
00501     {
00502     disconnect(loc,  SIGNAL(stateChanged(int,int)),
00503                this, SLOT(slotShowNewState(int,int)));
00504     disconnect(loc,  SIGNAL(progressIncreased()),
00505                this, SLOT(slotUpdateAnalysisTimeData()));
00506     disconnect(loc,  SIGNAL(newSpike(SpikeScore)),
00507                this, SLOT(slotUpdateAnalysisSpikeData(SpikeScore)));    
00508     disconnect(loc,  SIGNAL(newGaussian(GaussianScore)),
00509                this, SLOT(slotUpdateAnalysisGaussianData(GaussianScore)));  
00510     disconnect(loc,  SIGNAL(newPulse(PulseScore)),
00511                this, SLOT(slotUpdateAnalysisPulseData(PulseScore)));    
00512     disconnect(loc,  SIGNAL(newTriplet(TripletScore)),
00513                this, SLOT(slotUpdateAnalysisTripletData(TripletScore)));
00514     it = lvDict[loc->id()];
00515     if(it)
00516       {
00517       lvDict.remove(loc->id());
00518       delete it;
00519       }
00520     break;
00521     }
00522   case Ksetiwatch::ListRemove:
00523     {
00524     it = lvDict[loc->id()];
00525     if(it)
00526       {
00527       LocListView->takeItem(it);
00528       LocListViewHidden->insertItem(it);
00529       lvDict.remove(loc->id());
00530       lvDictHidden.insert(loc->id(), it);
00531       }
00532     break;
00533     }
00534   }
00535 }
00536 
00537 /*------------------------------------------------------------------------ */
00538 void Analysis::updateListItemTimeData(SetiLoc* loc)
00539 {
00540 AnalysisListViewItem* it;
00541 
00542 if(loc && (it = locationItemById(loc->id())))
00543   {
00544   // set location text
00545   it->setText(ColLocation, loc->description());
00546 
00547   if(loc->exists(SetiLoc::SC_StateFile))
00548     {
00549     if(loc->clientState() != SetiLoc::Finished &&
00550        loc->clientState() != SetiLoc::Connecting)
00551       {
00552       // set the actual chirp rate
00553       it->setText(ColChirpRate, QString::number(loc->chirpRate(), 'f', 4));
00554       // set the progress in %
00555       it->setText(ColProgress, QString::number(loc->progress(), 'f', 3));
00556       // calculate and set the time required to finish this work unit
00557       it->setText(ColTimeLeft, (loc->remainingTime() > 0.0) ?
00558                      loc->convertTime(loc->remainingTime(), globalopts->hms) : QString::null);
00559       }
00560     // set the elapsed CPU time     
00561     it->setText(ColCpuTime, loc->convertTime(loc->cpuTime(), globalopts->hms));
00562     // calculate and set the progress rate
00563     it->setText(ColProgressRate, QString::number(loc->progressRate(), 'f', 5));
00564     // MFlops
00565     it->setText(ColMFlops, QString::number(loc->megaFlopsPerSecond(), 'f', 2));
00566     }
00567   else
00568     {
00569     it->setText(ColChirpRate,    QString::null);
00570     it->setText(ColProgress,     QString::null);
00571     it->setText(ColCpuTime,      QString::null);
00572     it->setText(ColTimeLeft,     QString::null);
00573     it->setText(ColProgressRate, QString::null);
00574     it->setText(ColMFlops,       QString::null);
00575     }
00576   }
00577 }
00578 
00579 /*------------------------------------------------------------------------ */
00580 void Analysis::updateListItemSpikeData(SetiLoc* loc)
00581 {
00582 AnalysisListViewItem* it;
00583 
00584 if(loc && (it = locationItemById(loc->id())))
00585   {
00586   WUScore max = loc->wuScore();
00587   // update the list view item
00588   if(loc->exists(SetiLoc::SC_StateFile) && max.spike.power > 0.0)
00589     it->setText(ColSpike, " " + ((max.spike.power > 1.0e6) ?
00590                           QString::number(max.spike.power, 'e', 6) :
00591                           QString::number(max.spike.power, 'f', 3)));
00592   else
00593     it->setText(ColSpike, QString::null);
00594   }
00595 }
00596 
00597 /*------------------------------------------------------------------------ */
00598 void Analysis::updateListItemGaussianData(SetiLoc* loc)
00599 {
00600 AnalysisListViewItem* it;
00601 
00602 if(loc && (it = locationItemById(loc->id())))
00603   {
00604   WUScore max = loc->wuScore();
00605   // update the list view item
00606   if(loc->exists(SetiLoc::SC_StateFile) && max.gaussian.score > 0.0)
00607     it->setText(ColGaussian, QString(" scr=%1, pwr=%2, fit=%3")
00608                              .arg(max.gaussian.score, 0, 'f', 4)
00609                              .arg(max.gaussian.power, 0, 'f', 2)
00610                              .arg(max.gaussian.chisq, 0, 'f', 2));
00611   else
00612     it->setText(9, QString::null);
00613   }
00614 }
00615 
00616 /*------------------------------------------------------------------------ */
00617 void Analysis::updateListItemPulseData(SetiLoc* loc)
00618 {
00619 AnalysisListViewItem* it;
00620 
00621 if(loc && (it = locationItemById(loc->id())))
00622   {
00623   WUScore max = loc->wuScore();
00624   // update the list view item
00625   if(loc->exists(SetiLoc::SC_StateFile) && max.pulse.score > 0.0)
00626     it->setText(ColPulse, QString(" scr=%1, pwr=%2, prd=%3")
00627                           .arg(max.pulse.score, 0, 'f', 4)
00628                           .arg(max.pulse.power, 0, 'f', 2)
00629                           .arg(max.pulse.period, 0, 'f', 4));
00630   else
00631     it->setText(ColPulse, QString::null);
00632   }
00633 }
00634 
00635 /*------------------------------------------------------------------------ */
00636 void Analysis::updateListItemTripletData(SetiLoc* loc)
00637 {
00638 AnalysisListViewItem* it;
00639 
00640 if(loc && (it = locationItemById(loc->id())))
00641   {
00642   WUScore max = loc->wuScore();
00643   // update the list view item
00644   if(loc->exists(SetiLoc::SC_StateFile) && max.triplet.score > 0.0)
00645     it->setText(ColTriplet, QString(" scr=%1, prd=%2")
00646                             .arg(max.triplet.score, 0, 'f', 4)
00647                             .arg(max.triplet.period, 0, 'f', 4));
00648   else
00649     it->setText(ColTriplet, QString::null);
00650   }
00651 }
00652 
00653 /*------------------------------------------------------------------------ */
00654 void Analysis::updateMaxScore(SetiLoc* loc, const SpikeScore& newspike)
00655 {
00656 WUScore max = loc->maxScore();
00657 // Display a message if a new record is found.
00658 if(globalopts->ReportSpike &&
00659    newspike.power > globalopts->Record.spike.power)
00660   {
00661   // play a sound if the option is enabled;
00662   if(globalopts->PlaySound && !globalopts->HighSignalSound.isEmpty())
00663     KAudioPlayer::play(globalopts->HighSignalSound);
00664   // display a message box
00665   QString msgbuf, title;
00666   msgbuf.sprintf(i18n("<b>New record spike:</b><br>"
00667                       "peak = %.3lf at %.4lf Hz/s,<br>"
00668                       "found in WU %s.<br><br>"
00669                       "<b>Previous spike:</b><br>"
00670                       "peak = %.3lf at %.4lf Hz/s,<br>"
00671                       "found in WU %s."),
00672                       newspike.power, newspike.chirprate,
00673                       (const char*)newspike.wu_name,
00674                       globalopts->Record.spike.power,
00675                       globalopts->Record.spike.chirprate,
00676                       (const char*)globalopts->Record.spike.wu_name);
00677   title = i18n("New Record Spike for %1").arg(loc->description());
00678   SigMsg* sm = new SigMsg(newspike, msgbuf, 0, "New Signal");
00679   sm->setCaption(title);
00680   sm->show();
00681   }
00682 
00683 // Display a message if a new high signal is found. Checking mymax for -1
00684 // ensures that the message is not shown when starting Ksetiwatch.
00685 if(!globalopts->ShowRecords && globalopts->ReportSpike &&
00686    max.spike.power != -1.0)
00687   {
00688   if(newspike.power > max.spike.power &&
00689      newspike.power <= globalopts->Record.spike.power)
00690     {
00691     // play a sound if the option is enabled;
00692     if(globalopts->PlaySound && !globalopts->HighSignalSound.isEmpty())
00693       KAudioPlayer::play(globalopts->HighSignalSound);
00694     // display a message box
00695     QString msgbuf, title;
00696     msgbuf.sprintf(i18n("<b>New high spike in the current WU:</b><br>"
00697                         "peak = %.3lf at %.4lf Hz/s.<br><br>"
00698                         "<b>Previous spike:</b><br>"
00699                         "peak = %.3lf at %.4lf Hz/s."),
00700                         newspike.power, newspike.chirprate,
00701                         max.spike.power, max.spike.chirprate);
00702     title = i18n("New High Spike for %1").arg(loc->description());
00703     SigMsg* sm = new SigMsg(newspike, msgbuf, 0, "New Signal");
00704     sm->setCaption(title);
00705     sm->show();
00706     }
00707   }
00708 
00709 // update highscores
00710 if(newspike.power > max.spike.power || max.spike.power == -1.0)
00711   {
00712   // only update if state.sah exists
00713   if(loc->exists(SetiLoc::SC_StateFile))
00714     {
00715     max.spike = newspike;
00716     loc->setMaxScore(max);
00717     }
00718   }
00719 if(newspike.power > globalopts->Record.spike.power)
00720   {
00721   globalopts->Record.spike = newspike;
00722   }
00723 }
00724 
00725 /*------------------------------------------------------------------------ */
00726 void Analysis::updateMaxScore(SetiLoc* loc, const GaussianScore& newgaussian)
00727 {
00728 WUScore max = loc->maxScore();
00729 // Display a message if a new record is found.
00730 if(globalopts->ReportGaussian &&
00731    newgaussian.score > globalopts->Record.gaussian.score)
00732   {
00733   // play a sound if the option is enabled;
00734   if(globalopts->PlaySound && !globalopts->HighSignalSound.isEmpty())
00735     KAudioPlayer::play(globalopts->HighSignalSound);
00736   // display a message box
00737   QString msgbuf, title;
00738   msgbuf.sprintf(i18n("<b>New record gaussian:</b><br>"
00739     "scr = %.4lf, pwr = %.2lf, fit = %.2lf at %.4lf Hz/s,<br>"
00740     "found in WU %s.<br><br>"
00741     "<b>Previous record gaussian:</b><br>"
00742     "scr = %.4lf, pwr = %.2lf, fit = %.2lf at %.4lf Hz/s,<br>"
00743     "found in WU %s."),
00744     newgaussian.score, newgaussian.power, newgaussian.chisq,
00745     newgaussian.chirprate, (const char*)newgaussian.wu_name,
00746     globalopts->Record.gaussian.score,
00747     globalopts->Record.gaussian.power,
00748     globalopts->Record.gaussian.chisq,
00749     globalopts->Record.gaussian.chirprate,
00750     (const char*)globalopts->Record.gaussian.wu_name);
00751   title = i18n("New Record Gaussian for %1").arg(loc->description());
00752   SigMsg* sm = new SigMsg(newgaussian, msgbuf, 0, "New Signal");
00753   sm->setCaption(title);
00754   sm->show();
00755   }
00756 
00757 // Display a message if a new high signal is found. Checking mymax for -1
00758 // ensures that the message is not shown when starting Ksetiwatch.
00759 if(!globalopts->ShowRecords && globalopts->ReportGaussian &&
00760    max.gaussian.score != -1.0)
00761   {
00762   if(newgaussian.score > max.gaussian.score &&
00763      newgaussian.score <= globalopts->Record.gaussian.score)
00764     {
00765     // play a sound if the option is enabled;
00766     if(globalopts->PlaySound && !globalopts->HighSignalSound.isEmpty())
00767       KAudioPlayer::play(globalopts->HighSignalSound);
00768     // display a message box
00769     QString msgbuf, title;
00770     msgbuf.sprintf(i18n("<b>New high gaussian in the current WU:</b><br>"
00771       "scr = %.4lf, pwr = %.2lf, fit = %.2lf at %.4lf Hz/s.<br><br>"
00772       "<b>Previous gaussian:</b><br>"
00773       "scr = %.4lf, pwr = %.2lf, fit = %.2lf at %.4lf Hz/s."),
00774       newgaussian.score, newgaussian.power, newgaussian.chisq,
00775       newgaussian.chirprate,
00776       max.gaussian.score, max.gaussian.power, max.gaussian.chisq,
00777       max.gaussian.chirprate);
00778     title = i18n("New High Gaussian for %1").arg(loc->description());
00779     SigMsg* sm = new SigMsg(newgaussian, msgbuf, 0, "New Signal");
00780     sm->setCaption(title);
00781     sm->show();
00782     }
00783   }
00784 
00785 // update highscores
00786 if(newgaussian.score > max.gaussian.score || max.gaussian.score == -1.0)
00787   {
00788   // only update if state.sah exists
00789   if(loc->exists(SetiLoc::SC_StateFile))
00790     {
00791     max.gaussian = newgaussian;
00792     loc->setMaxScore(max);
00793     }
00794   }
00795 if(newgaussian.score > globalopts->Record.gaussian.score)
00796   {
00797   globalopts->Record.gaussian = newgaussian;
00798   }
00799 }
00800 
00801 /*------------------------------------------------------------------------ */
00802 void Analysis::updateMaxScore(SetiLoc* loc, const PulseScore& newpulse)
00803 {
00804 WUScore max = loc->maxScore();
00805 // Display a message if a new record is found.
00806 if(globalopts->ReportPulse &&
00807    newpulse.score > globalopts->Record.pulse.score)
00808   {
00809   // play a sound if the option is enabled;
00810   if(globalopts->PlaySound && !globalopts->HighSignalSound.isEmpty())
00811     KAudioPlayer::play(globalopts->HighSignalSound);
00812   // display a message box
00813   QString msgbuf, title;
00814   msgbuf.sprintf(i18n("<b>New record pulse:</b><br>"
00815     "scr = %.4lf, pwr = %.2lf, prd = %.4lf at %.4lf Hz/s,<br>"
00816     "found in WU %s.<br><br>"
00817     "<b>Previous record pulse:</b><br>"
00818     "scr = %.4lf, pwr = %.2lf, prd = %.4lf at %.4lf Hz/s,<br>"
00819     "found in WU %s."),
00820     newpulse.score, newpulse.power, newpulse.period,
00821     newpulse.chirprate, (const char*)newpulse.wu_name,
00822     globalopts->Record.pulse.score,
00823     globalopts->Record.pulse.power,
00824     globalopts->Record.pulse.period,
00825     globalopts->Record.pulse.chirprate,
00826     (const char*)globalopts->Record.pulse.wu_name);
00827   title = i18n("New Record Pulse for %1").arg(loc->description());
00828   SigMsg* sm = new SigMsg(newpulse, msgbuf, 0, "New Signal");
00829   sm->setCaption(title);
00830   sm->show();
00831   }
00832 
00833 // Display a message if a new high signal is found. Checking mymax for -1
00834 // ensures that the message is not shown when starting Ksetiwatch.
00835 if(!globalopts->ShowRecords && globalopts->ReportPulse &&
00836    max.pulse.score != -1.0)
00837   {
00838   if(newpulse.score > max.pulse.score &&
00839      newpulse.score <= globalopts->Record.pulse.score)
00840     {
00841     // play a sound if the option is enabled;
00842     if(globalopts->PlaySound && !globalopts->HighSignalSound.isEmpty())
00843       KAudioPlayer::play(globalopts->HighSignalSound);
00844     // display a message box
00845     QString msgbuf, title;
00846     msgbuf.sprintf(i18n("<b>New high pulse in the current WU:</b><br>"
00847       "scr = %.4lf, pwr = %.2lf, prd = %.4lf at %.4lf Hz/s.<br><br>"
00848       "<b>Previous pulse:</b><br>"
00849       "scr = %.4lf, pwr = %.2lf, prd = %.4lf at %.4lf Hz/s."),
00850       newpulse.score, newpulse.power, newpulse.period,
00851       newpulse.chirprate,
00852       max.pulse.score, max.pulse.power, max.pulse.period,
00853       max.pulse.chirprate);
00854     title = i18n("New High Pulse for %1").arg(loc->description());
00855     SigMsg* sm = new SigMsg(newpulse, msgbuf, 0, "New Signal");
00856     sm->setCaption(title);
00857     sm->show();
00858     }
00859   }
00860 
00861 // update highscores
00862 if(newpulse.score > max.pulse.score || max.pulse.score == -1.0)
00863   {
00864   // only update if state.sah exists
00865   if(loc->exists(SetiLoc::SC_StateFile))
00866     {
00867     max.pulse = newpulse;
00868     loc->setMaxScore(max);
00869     }
00870   }
00871 if(newpulse.score > globalopts->Record.pulse.score)
00872   {
00873   globalopts->Record.pulse = newpulse;
00874   }
00875 }
00876 
00877 /*------------------------------------------------------------------------ */
00878 void Analysis::updateMaxScore(SetiLoc* loc, const TripletScore& newtriplet)
00879 {
00880 WUScore max = loc->maxScore();
00881 // Display a message if a new record is found.
00882 if(globalopts->ReportTriplet &&
00883    newtriplet.score > globalopts->Record.triplet.score)
00884   {
00885   // play a sound if the option is enabled;
00886   if(globalopts->PlaySound && !globalopts->HighSignalSound.isEmpty())
00887     KAudioPlayer::play(globalopts->HighSignalSound);
00888   // display a message box
00889   QString msgbuf, title;
00890   msgbuf.sprintf(i18n("<b>New record triplet:</b><br>"
00891     "scr = %.4lf, prd = %.4lf at %.4lf Hz/s,<br>"
00892     "found in WU %s.<br><br>"
00893     "<b>Previous triplet:</b><br>"
00894     "scr = %.4lf, prd = %.4lf at %.4lf Hz/s,<br>"
00895     "found in WU %s."),
00896     newtriplet.score, newtriplet.period, newtriplet.chirprate,
00897     (const char*)newtriplet.wu_name,
00898     globalopts->Record.triplet.score,
00899     globalopts->Record.triplet.period,
00900     globalopts->Record.triplet.chirprate,
00901     (const char*)globalopts->Record.triplet.wu_name);
00902   title = i18n("New Record Triplet for %1").arg(loc->description());
00903   SigMsg* sm = new SigMsg(newtriplet, msgbuf, 0, "New Signal");
00904   sm->setCaption(title);
00905   sm->show();
00906   }
00907 
00908 // Display a message if a new high signal is found. Checking mymax for -1
00909 // ensures that the message is not shown when starting Ksetiwatch.
00910 if(!globalopts->ShowRecords && globalopts->ReportTriplet &&
00911    max.triplet.score != -1.0)
00912   {
00913   if(newtriplet.score > max.triplet.score &&
00914      newtriplet.score <= globalopts->Record.triplet.score)
00915     {
00916     // play a sound if the option is enabled;
00917     if(globalopts->PlaySound && !globalopts->HighSignalSound.isEmpty())
00918       KAudioPlayer::play(globalopts->HighSignalSound);
00919     // display a message box
00920     QString msgbuf, title;
00921     msgbuf.sprintf(i18n("<b>New high triplet in the current WU:</b><br>"
00922       "scr = %.4lf, prd = %.4lf at %.4lf Hz/s.<br><br>"
00923       "<b>Previous triplet:</b><br>"
00924       "scr = %.4lf, prd = %.4lf at %.4lf Hz/s."),
00925       newtriplet.score, newtriplet.period, newtriplet.chirprate,
00926       max.triplet.score, max.triplet.period, max.triplet.chirprate);
00927     title = i18n("New High Triplet for %1").arg(loc->description());
00928     SigMsg* sm = new SigMsg(newtriplet, msgbuf, 0, "New Signal");
00929     sm->setCaption(title);
00930     sm->show();
00931     }
00932   }
00933 
00934 // update highscores
00935 if(newtriplet.score > max.triplet.score || max.triplet.score == -1.0)
00936   {
00937   // only update if state.sah exists
00938   if(loc->exists(SetiLoc::SC_StateFile))
00939     {
00940     // store the triplet data to merge them into the logs later
00941     if(max.triplet.score != -1.0) loc->storeTripletData(newtriplet);
00942     max.triplet = newtriplet;
00943     loc->setMaxScore(max);
00944     }
00945   }
00946 if(newtriplet.score > globalopts->Record.triplet.score)
00947   {
00948   globalopts->Record.triplet = newtriplet;
00949   }
00950 }
00951 
00952 /*------------------------------------------------------------------------ */
00953 void Analysis::slotUpdateAnalysisTimeData()
00954 {
00955 SetiLoc* loc = (SetiLoc*)(sender());
00956 if(loc)
00957   updateListItemTimeData(loc);
00958 }
00959 
00960 /*------------------------------------------------------------------------ */
00961 void Analysis::slotUpdateAnalysisSpikeData(SpikeScore newspike)
00962 {
00963 SetiLoc* loc = (SetiLoc*)(sender());
00964 
00965 if(loc)
00966   {
00967   updateMaxScore(loc, newspike);
00968   updateListItemSpikeData(loc);
00969   }
00970 }
00971 
00972 /*------------------------------------------------------------------------ */
00973 void Analysis::slotUpdateAnalysisGaussianData(GaussianScore newgaussian)
00974 {
00975 SetiLoc* loc = (SetiLoc*)(sender());
00976 
00977 if(loc)
00978   {
00979   updateMaxScore(loc, newgaussian);
00980   updateListItemGaussianData(loc);
00981   }
00982 }
00983 
00984 /*------------------------------------------------------------------------ */
00985 void Analysis::slotUpdateAnalysisPulseData(PulseScore newpulse)
00986 {
00987 SetiLoc* loc = (SetiLoc*)(sender());
00988 
00989 if(loc)
00990   {
00991   updateMaxScore(loc, newpulse);
00992   updateListItemPulseData(loc);
00993   }
00994 }
00995 
00996 /*------------------------------------------------------------------------ */
00997 void Analysis::slotUpdateAnalysisTripletData(TripletScore newtriplet)
00998 {
00999 SetiLoc* loc = (SetiLoc*)(sender());
01000 
01001 if(loc)
01002   {
01003   updateMaxScore(loc, newtriplet);
01004   updateListItemTripletData(loc);
01005   }
01006 }
01007 
01008 /*------------------------------------------------------------------------ */
01009 void Analysis::updateStateIcon(SetiLoc* loc, int state, int loadsize)
01010 {
01011 AnalysisListViewItem* it;
01012 
01013 if(loc)
01014   {
01015   updateAnalysisList(loc);
01016   it = locationItemById(loc->id());
01017   }
01018 if(loc && it)
01019   {
01020   // log the WU if necessary
01021   if(state == SetiLoc::Finished)
01022     {
01023     loc->checkWUStatus();
01024     }
01025 
01026   // first change the icon
01027   centerStatusIcon(it, state);
01028   
01029   // modify the columns in accordance to the new state
01030   switch(state)
01031     {
01032     case SetiLoc::Stopped:
01033       // Restart the client if the option is set and the client has crashed.
01034       if(loc->optionKeepClientAlive() && !loc->isStoppedNormally())
01035         loc->startClient();
01036       // Fallthrough
01037     case SetiLoc::Running:
01038       updateListItemTimeData(loc);
01039       updateListItemSpikeData(loc);
01040       updateListItemGaussianData(loc);
01041       updateListItemPulseData(loc);
01042       updateListItemTripletData(loc);
01043       break;
01044     case SetiLoc::Finished:
01045       updateListItemTimeData(loc);
01046       it->setText(ColChirpRate, QString::null);
01047       it->setText(ColProgress, "100.000");
01048       it->setText(ColTimeLeft, QString::null);
01049       break;
01050     case SetiLoc::Connecting:
01051       loadsize = 0;
01052       // Fallthrough
01053     case SetiLoc::Loading:
01054       it->setText(ColChirpRate,    QString::null);
01055       it->setText(ColProgress,     QString("%1 %").arg(loadsize));
01056       it->setText(ColCpuTime,      QString::null);
01057       it->setText(ColTimeLeft,     QString::null);
01058       it->setText(ColProgressRate, QString::null);
01059       it->setText(ColMFlops,       QString::null);
01060       it->setText(ColSpike,        QString::null);
01061       it->setText(ColGaussian,     QString::null);
01062       it->setText(ColPulse,        QString::null);
01063       it->setText(ColTriplet,      QString::null);
01064       break;
01065     }
01066   }
01067 }
01068 
01069 /*------------------------------------------------------------------------ */
01070 void Analysis::slotShowNewState(int state, int loadsize)
01071 {
01072 SetiLoc* loc = (SetiLoc*)(sender());
01073 updateStateIcon(loc, state, loadsize);
01074 }
01075 
01076 /*------------------------------------------------------------------------ */
01077 void Analysis::updateAnalysisList(SetiLoc* loc)
01078 {
01079 AnalysisListViewItem* it = lvDict[loc->id()];
01080 switch(globalopts->StatusFilterValue)
01081   {
01082   case 0: // All
01083     {
01084     if(it == 0)
01085       slotUpdateList(loc, Ksetiwatch::ListAdd);
01086     break;
01087     }
01088   case 5: // Running + Finished
01089     {
01090     if(it && (loc->clientState() != SetiLoc::Running &&
01091        loc->clientState() != SetiLoc::Finished))
01092       {
01093       if(it->isSelected())
01094         {
01095         LocListView->setSelected(LocListView->currentItem(), false);
01096         emit selectionChanged(0);
01097         }
01098       slotUpdateList(loc, Ksetiwatch::ListRemove);
01099       }
01100     else if(it == 0 && (loc->clientState() == SetiLoc::Running ||
01101             loc->clientState() == SetiLoc::Finished))
01102       {
01103       slotUpdateList(loc, Ksetiwatch::ListAdd);
01104       }
01105     break;
01106     }
01107   default: // Stopped, Running, Finished, Loading
01108     {
01109     if(it && loc->clientState() != globalopts->StatusFilterValue-1)
01110       {
01111       if(it->isSelected())
01112         {
01113         LocListView->setSelected(LocListView->currentItem(), false);
01114         emit selectionChanged(0);
01115         }
01116       slotUpdateList(loc, Ksetiwatch::ListRemove);
01117       }
01118     else if(it == 0 && loc->clientState() == globalopts->StatusFilterValue-1)
01119       {
01120       slotUpdateList(loc, Ksetiwatch::ListAdd);
01121       }
01122     break;
01123     }
01124   }
01125 }
01126 
01127 /*------------------------------------------------------------------------ */
01128 void Analysis::modifyStatusFilter(int sel)
01129 {
01130 globalopts->StatusFilterValue = sel;
01131 // Add or remove items according to the new filter selection.
01132 for(SetiLoc* loc=Ksetiwatch::locationList().first(); loc != 0;
01133     loc=Ksetiwatch::locationList().next())
01134   {
01135   updateAnalysisList(loc);
01136   }
01137 }
01138 
01139 /*------------------------------------------------------------------------ */
01140 void Analysis::toggleSorting(int column)
01141 {
01142 sortingorder = !sortingorder;
01143 LocListView->setSorting(column, sortingorder);
01144 }
01145 
01146 /*------------------------------------------------------------------------ */
01147 void Analysis::slotShowHelp()
01148 {
01149 kapp->invokeHelp();
01150 }
01151 
01152 /*------------------------------------------------------------------------ */
01153 void Analysis::openBrowser()
01154 {
01155 kapp->invokeBrowser("http://ksetiwatch.sourceforge.net");
01156 }
01157 
01158 /*------------------------------------------------------------------------ */
01159 AnalysisListViewItem* Analysis::selectedItem()
01160 {
01161 QListViewItem* it = LocListView->currentItem();
01162 
01163 if(LocListView->isSelected(it))
01164   return(static_cast<AnalysisListViewItem*>(it));
01165 else
01166   return(0);
01167 }
01168 
01169 /*------------------------------------------------------------------------ */
01170 AnalysisListViewItem* Analysis::locationItemByName(const QString& locName)
01171 {
01172 QListViewItem* it;
01173 
01174 // identify corresponding SetiLoc item
01175 for(it=LocListView->firstChild(); it != 0; it=it->nextSibling() )
01176   {
01177   if(it->text(ColLocation) == locName) break;
01178   }
01179 
01180 return( static_cast<AnalysisListViewItem*>(it) );
01181 }
01182 
01183 /*------------------------------------------------------------------------ */
01184 AnalysisListViewItem* Analysis::locationItemById(const QString& locId)
01185 {
01186 AnalysisListViewItem* it;
01187 
01188 it = lvDict[locId];
01189 if(it == 0)
01190   it = lvDictHidden[locId];
01191 
01192 return(it);
01193 }
01194 
01195 /*------------------------------------------------------------------------ */
01196 SetiLoc* Analysis::getLocation(AnalysisListViewItem* it)
01197 {
01198 SetiLoc* loc = 0;
01199 
01200 if(it)
01201   loc = Ksetiwatch::getLocation(it->text(ColLocation));
01202 
01203 return( loc );
01204 }
01205 
01206 /*------------------------------------------------------------------------ */
01207 SetiLoc* Analysis::selectedLocation()
01208 {
01209 return(getLocation(selectedItem()));
01210 }
01211 
01212 /*------------------------------------------------------------------------ */
01213 void Analysis::handleNewSelection(QListViewItem* it)
01214 {
01215 SetiLoc* loc(0);
01216 
01217 if(it) loc = getLocation((AnalysisListViewItem*)it);
01218 emit selectionChanged(loc);
01219 }
01220 
01221 /*------------------------------------------------------------------------ */
01222 void Analysis::setSelectedLocation(const QString& lid)
01223 {
01224 AnalysisListViewItem* it = lvDict[lid];
01225 if(it) LocListView->setSelected(it, true);
01226 }
01227 
01228 /*------------------------------------------------------------------------ */
01229 void Analysis::slotAskForLocation()
01230 {
01231 int retval;
01232 
01233 if(Ksetiwatch::locationList().count() == 0)
01234   {
01235   retval = KMessageBox::questionYesNo(this,
01236                              i18n("It appears that you haven't configured\n"
01237                                   "a SETI@home location. Would you like\n"
01238                                   "to add one to the list?"));
01239   if(retval == KMessageBox::Yes)
01240     {
01241     handlePopupCommand(PopupAdd);
01242     }
01243   }
01244 }
01245 
01246 /*------------------------------------------------------------------------ */
01247 void Analysis::slotStartAll()
01248 {
01249 for(SetiLoc* loc=Ksetiwatch::locationList().first(); loc != 0;
01250     loc=Ksetiwatch::locationList().next())
01251   {
01252   if(loc->isClientRunning(true) == false) loc->startClient();
01253   }
01254 }
01255 
01256 /*------------------------------------------------------------------------ */
01257 void Analysis::slotStopAll()
01258 {
01259 for(SetiLoc* loc=Ksetiwatch::locationList().first(); loc != 0;
01260     loc=Ksetiwatch::locationList().next())
01261   {
01262   if(loc->isClientRunning(true)) loc->stopClient();
01263   }
01264 }
01265 
01266 /*------------------------------------------------------------------------ */
01267 void Analysis::slotAdjustAllStatusIcons(int col, int, int)
01268 {
01269 if(col == ColStatus)
01270   {
01271   for(SetiLoc* loc=Ksetiwatch::locationList().first(); loc != 0;
01272       loc=Ksetiwatch::locationList().next())
01273     {  
01274     centerStatusIcon(locationItemById(loc->id()), loc->clientState());
01275     }
01276   }
01277 }
01278 
01279 /*------------------------------------------------------------------------ */
01280 void Analysis::centerStatusIcon(QListViewItem* it, int state)
01281 {
01282 if(it)
01283   {
01284   // center the pixmap in the column (why can't Qt handle this?)
01285   int cw = it->listView()->columnWidth(ColStatus);
01286   if(cw < 24)
01287     cw = 24;
01288 
01289   QPixmap stpix((cw + StatusIcon[state].width())/2, 16);
01290   QPainter p(&stpix);
01291   p.fillRect(0, 0, (cw + StatusIcon[state].width())/2, 16, white);
01292   p.drawPixmap((cw - StatusIcon[state].width())/2, 0, StatusIcon[state]);
01293   p.end();
01294 
01295   stpix.setMask( stpix.createHeuristicMask() );
01296   it->setPixmap(ColStatus, stpix);
01297   }
01298 }
01299 
01300 #include "analysis.moc"
01301 
KDE Logo
This file is part of the documentation for Ksetiwatch API Version 2.6.1.
Documentation copyright © 2000-2003 Gordon Machel.
Generated on Fri Jun 6 00:28:13 2003 by doxygen 1.2.18, written by Dimitri van Heesch, © 1997-2002