00001
00015 #include <kapp.h>
00016 #include <klocale.h>
00017 #include <kpopupmenu.h>
00018 #include <kiconloader.h>
00019
00020 #include <qtooltip.h>
00021 #include <qpainter.h>
00022 #include <qiconset.h>
00023
00024 #include "dockwidget.h"
00025 #include "setiloc.h"
00026
00027
00028 DockWidget::DockWidget(QWidget* parent, const char* name)
00029 : KSystemTray(parent,name), location(0), docked(false)
00030 {
00031 mini_seti = SmallIcon("mini-seti");
00032 mini_setigrey = SmallIcon("mini-setidockgrey");
00033 mini_setifinished = SmallIcon("mini-setidockfinished");
00034 mini_setistopped = SmallIcon("mini-setidockstopped");
00035 mini_setiloading = SmallIcon("mini-setidockloading");
00036 picsmall_pixmap = SmallIcon("ksetiwatch");
00037
00038 contextMenu()->changeTitle(contextMenu()->idAt(0), "Ksetiwatch");
00039 contextMenu()->insertItem(QIconSet(SmallIcon("mini-setirunning"), QIconSet::Small), i18n("Start Client"), StartClient);
00040 contextMenu()->insertItem(QIconSet(SmallIcon("mini-setistopped"), QIconSet::Small), i18n("Stop Client"), StopClient);
00041 connect(contextMenu(), SIGNAL(aboutToShow()), SLOT(preparePopupMenu()));
00042 connect(contextMenu(), SIGNAL(activated(int)), SLOT(handlePopupCommand(int)));
00043
00044 QToolTip::add(this, "Ksetiwatch");
00045
00046
00047 showIcon = true;
00048
00049 startTimer(1000);
00050 }
00051
00052
00053 DockWidget::~DockWidget()
00054 {
00055 }
00056
00057
00058 void DockWidget::timerEvent(QTimerEvent*)
00059 {
00060 slotBlinkIcon();
00061 }
00062
00063
00064 void DockWidget::dock(SetiLoc* loc)
00065 {
00066 if (!docked)
00067 {
00068
00069 location = loc;
00070 docked = true;
00071 this->show();
00072 }
00073 }
00074
00075
00076 void DockWidget::undock()
00077 {
00078 if (docked)
00079 {
00080 docked = false;
00081 this->hide();
00082 }
00083 }
00084
00085
00086 void DockWidget::paintEvent(QPaintEvent*)
00087 {
00088 paintIcon(0, 0);
00089 }
00090
00091
00092 void DockWidget::updateProgress()
00093 {
00094 if(location)
00095 {
00096 if(location->clientState() == SetiLoc::Running)
00097 updateState(location->clientState(), 0);
00098 }
00099 }
00100
00101
00102 void DockWidget::updateState(int st, int ls)
00103 {
00104
00105 if(location)
00106 {
00107 QString info;
00108 int state;
00109 if(st == 0)
00110 state = location->clientState();
00111 else
00112 state = st;
00113
00114 switch(state)
00115 {
00116 case SetiLoc::Stopped:
00117 if(location->progress() >= 0.0)
00118 info = i18n("stopped");
00119 else
00120 info = QString::null;
00121 break;
00122 case SetiLoc::Running:
00123 info = "-" + location->remainingTimeAsString();
00124 break;
00125 case SetiLoc::Loading:
00126 info = i18n("loading: %1%").arg(ls);
00127 break;
00128 case SetiLoc::Finished:
00129 info = i18n("finished");
00130 break;
00131 case SetiLoc::Connecting:
00132 info = i18n("connecting");
00133 break;
00134 default:
00135 info = QString::null;
00136 break;
00137 }
00138
00139 QString tip("Ksetiwatch - ");
00140 tip += location->description();
00141 if(!info.isEmpty()) tip += " (" + info + ")";
00142 QToolTip::remove(this);
00143 QToolTip::add(this, tip);
00144
00145 loadingState = ls;
00146 }
00147 else
00148 {
00149 QToolTip::remove(this);
00150 QToolTip::add(this, "Ksetiwatch");
00151 }
00152 paintIcon(st, ls);
00153 }
00154
00155
00156 void DockWidget::paintIcon(int st, int ls)
00157 {
00158 int x(0),y(0);
00159
00160
00161 erase();
00162 if(location == 0)
00163 {
00164 QSize s(picsmall_pixmap.size());
00165 if(s.width() < 24) x = (24 - s.width())/2;
00166 if(s.height() < 24) y = (24 - s.height())/2;
00167 bitBlt(this, x, y, &picsmall_pixmap);
00168 }
00169 else
00170 {
00171 QPixmap* icon;
00172
00173 int state;
00174 if(st == 0)
00175 state = location->clientState();
00176 else
00177 state = st;
00178
00179 if(showIcon)
00180 {
00181
00182 switch(state)
00183 {
00184 case SetiLoc::Stopped:
00185 icon = &mini_setistopped;
00186 break;
00187 case SetiLoc::Running:
00188 icon = &mini_seti;
00189 break;
00190 case SetiLoc::Loading:
00191 icon = &mini_setiloading;
00192 break;
00193 case SetiLoc::Finished:
00194 icon = &mini_setifinished;
00195 break;
00196 case SetiLoc::Connecting:
00197
00198 icon = &mini_setiloading;
00199 break;
00200 default:
00201 icon = &mini_setigrey;
00202 break;
00203 }
00204 }
00205 else
00206 {
00207 if(state == SetiLoc::Connecting)
00208 icon = &mini_setifinished;
00209 else
00210 icon = &mini_setigrey;
00211 }
00212
00213 QString prog;
00214 double progVal;
00215 switch(state)
00216 {
00217 case SetiLoc::Stopped:
00218 if(location->progress() >= 0.0)
00219 progVal = location->progress();
00220 else
00221 progVal = -1.0;
00222 break;
00223 case SetiLoc::Running:
00224 progVal = location->progress();
00225 break;
00226 case SetiLoc::Loading:
00227 progVal = (double)ls;
00228 break;
00229 case SetiLoc::Finished:
00230 progVal = 100.0;
00231 break;
00232 case SetiLoc::Connecting:
00233 progVal = 0.0;
00234 break;
00235 default:
00236
00237 progVal = -1.0;
00238 break;
00239 }
00240 if(progVal >= 0.0)
00241 prog.sprintf("%.0f%%", progVal);
00242 else
00243 prog = QString::null;
00244
00245 QSize s(icon->size());
00246 if(s.width() < 24) x = (24 - s.width())/2;
00247 bitBlt(this, x, 2, icon);
00248
00249 QRect pbar(0, 14, 23, 8);
00250 QPainter p(this);
00251 p.fillRect(pbar, darkGray);
00252 p.setPen(QColor(200, 200, 200));
00253 p.moveTo(0, 21);
00254 p.lineTo(23, 21);
00255 p.lineTo(23, 14);
00256 if(progVal >= 0.0)
00257 p.fillRect(0, 15, ((int)(progVal*24)/100), 6, QColor(180,100,0));
00258 p.setPen(white);
00259 p.setFont(QFont("system", 8));
00260 p.drawText( 0, 13, 23, 8, AlignCenter, prog);
00261 }
00262 }
00263
00264
00265 void DockWidget::handlePopupCommand(int id)
00266 {
00267 switch(id)
00268 {
00269 case StartClient:
00270 if(location) location->startClient();
00271 break;
00272 case StopClient:
00273 if(location) location->stopClient();
00274 break;
00275 }
00276 }
00277
00278
00279 void DockWidget::preparePopupMenu()
00280 {
00281
00282 contextMenu()->setItemEnabled(StartClient, false);
00283 contextMenu()->setItemEnabled(StopClient, false);
00284 if(location)
00285 {
00286 switch(location->clientState())
00287 {
00288 case SetiLoc::Running:
00289 case SetiLoc::Loading:
00290
00291 contextMenu()->setItemEnabled(StopClient, true);
00292 break;
00293 case SetiLoc::Stopped:
00294
00295 contextMenu()->setItemEnabled(StartClient, true);
00296 break;
00297 case SetiLoc::Finished:
00298 if(location->isClientRunning() == true)
00299 contextMenu()->setItemEnabled(StopClient, true);
00300 else
00301 contextMenu()->setItemEnabled(StartClient, true);
00302 break;
00303 }
00304 }
00305 }
00306
00307
00308 void DockWidget::updateDockWidget(SetiLoc* loc)
00309 {
00310
00311 if(location != loc && location != 0)
00312 {
00313 disconnect(location, SIGNAL(progressIncreased()),
00314 this, SLOT(updateProgress()));
00315 disconnect(location, SIGNAL(stateChanged(int,int)),
00316 this, SLOT(updateState(int,int)));
00317 }
00318
00319 if(location != loc)
00320 {
00321 location = loc;
00322 if(location)
00323 {
00324 connect(location, SIGNAL(progressIncreased()),
00325 this, SLOT(updateProgress()));
00326 connect(location, SIGNAL(stateChanged(int,int)),
00327 this, SLOT(updateState(int,int)));
00328 }
00329 }
00330 updateState(0, 0);
00331 }
00332
00333
00334 void DockWidget::slotBlinkIcon()
00335 {
00336 if(location)
00337 {
00338 if(location->clientState() != SetiLoc::Running)
00339 {
00340 showIcon ^= true;
00341 paintIcon(0, loadingState);
00342 }
00343 else
00344 {
00345 if(showIcon == false)
00346 {
00347 showIcon = true;
00348 paintIcon(0, 0);
00349 }
00350 }
00351 }
00352 }
00353
00354 #include "dockwidget.moc"
00355