00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <cmath>
00025
00026 #include <QApplication>
00027 #include <QDesktopWidget>
00028 #include <QIcon>
00029 #include <QPushButton>
00030 #include <QDebug>
00031
00032 #include "klfutil.h"
00033 #include "klfrelativefont.h"
00034 #include "klfguiutil.h"
00035
00036
00037
00038
00039
00040 KLFProgressReporter::KLFProgressReporter(int min, int max, QObject *parent)
00041 : QObject(parent)
00042 {
00043 pMin = min;
00044 pMax = max;
00045 pFinished = false;
00046 }
00047 KLFProgressReporter::~KLFProgressReporter()
00048 {
00049 if (!pFinished) {
00050 emit progress(pMax);
00051 emit finished();
00052 }
00053 }
00054
00055 void KLFProgressReporter::doReportProgress(int value)
00056 {
00057 if (pFinished) {
00058 qWarning()<<KLF_FUNC_NAME<<": Operation is already finished!";
00059 return;
00060 }
00061 emit progress(value);
00062 if (value >= pMax) {
00063 emit finished();
00064 pFinished = true;
00065 }
00066 }
00067
00068
00069
00070
00071
00072
00073
00074 KLFProgressDialog::KLFProgressDialog(QString labelText, QWidget *parent)
00075 : QProgressDialog(parent)
00076 {
00077 setup(false);
00078 init(labelText);
00079 }
00080 KLFProgressDialog::KLFProgressDialog(bool canCancel, QString labelText, QWidget *parent)
00081 : QProgressDialog(parent)
00082 {
00083 setup(canCancel);
00084 init(labelText);
00085 }
00086 KLFProgressDialog::~KLFProgressDialog()
00087 {
00088 }
00089
00090 void KLFProgressDialog::setup(bool canCancel)
00091 {
00092 pProgressReporter = NULL;
00093 setAutoClose(true);
00094 setAutoReset(true);
00095 setModal(true);
00096
00097 setWindowIcon(QIcon(":/pics/klatexformula-16.png"));
00098 setWindowTitle(tr("Progress"));
00099 QPushButton *cbtn = new QPushButton(tr("Cancel"), this);
00100 setCancelButton(cbtn);
00101 cbtn->setEnabled(canCancel);
00102 }
00103 void KLFProgressDialog::init(const QString& labelText)
00104 {
00105 setDescriptiveText(labelText);
00106 }
00107
00108 void KLFProgressDialog::setDescriptiveText(const QString& labelText)
00109 {
00110 setLabelText(labelText);
00111 setFixedSize((int)(sizeHint().width()*1.3), (int)(sizeHint().height()*1.1));
00112 }
00113 void KLFProgressDialog::startReportingProgress(KLFProgressReporter *progressReporter,
00114 const QString& descriptiveText)
00115 {
00116 reset();
00117 setDescriptiveText(descriptiveText);
00118 setRange(progressReporter->min(), progressReporter->max());
00119 setValue(0);
00120
00121
00122 if (pProgressReporter != NULL)
00123 disconnect(pProgressReporter, 0, this, SLOT(setValue(int)));
00124
00125 connect(progressReporter, SIGNAL(progress(int)), this, SLOT(setValue(int)));
00126 }
00127
00128 void KLFProgressDialog::startReportingProgress(KLFProgressReporter *progressReporter)
00129 {
00130 reset();
00131 setRange(progressReporter->min(), progressReporter->max());
00132 setValue(0);
00133
00134 if (pProgressReporter != NULL)
00135 disconnect(pProgressReporter, 0, this, SLOT(setValue(int)));
00136
00137 connect(progressReporter, SIGNAL(progress(int)), this, SLOT(setValue(int)));
00138 }
00139
00140 void KLFProgressDialog::setValue(int value)
00141 {
00142
00143 klfDbg("value="<<value);
00144 QProgressDialog::setValue(value);
00145 }
00146
00147 void KLFProgressDialog::paintEvent(QPaintEvent *event)
00148 {
00149 KLF_DEBUG_BLOCK(KLF_FUNC_NAME);
00150 QProgressDialog::paintEvent(event);
00151 }
00152
00153
00154
00155
00156
00157 static Qt::WindowFlags klfpleasewait_flagsForSettings(bool alwaysAbove)
00158 {
00159 Qt::WindowFlags f = Qt::Window|Qt::SplashScreen|Qt::FramelessWindowHint;
00160 if (alwaysAbove)
00161 f |= Qt::WindowStaysOnTopHint|Qt::X11BypassWindowManagerHint;
00162 return f;
00163 }
00164
00165 KLFPleaseWaitPopup::KLFPleaseWaitPopup(const QString& text, QWidget *parent, bool alwaysAbove)
00166 : QLabel(text, ((parent!=NULL)?parent->window():NULL), klfpleasewait_flagsForSettings(alwaysAbove)),
00167 pParentWidget(parent), pDisableUi(false), pGotPaintEvent(false), pDiscarded(false)
00168 {
00169 KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ;
00170 KLFRelativeFont *relfont = new KLFRelativeFont(this);
00171 relfont->setRelPointSize(+2);
00172
00173 setAlignment(Qt::AlignHCenter|Qt::AlignVCenter);
00174 setWindowModality(Qt::ApplicationModal);
00175
00176 setAttribute(Qt::WA_StyledBackground, true);
00177 setProperty("klfTopLevelWidget", QVariant(true));
00178
00179 setFrameStyle(QFrame::Panel|QFrame::Sunken);
00180
00181 QWidget *pw = parentWidget();
00182 if (pw != NULL)
00183 setStyleSheet(pw->window()->styleSheet());
00184
00185 int w = qMax( (int)(sizeHint().width() *1.3) , 500 );
00186 int h = qMax( (int)(sizeHint().height()*1.1) , 100 );
00187 setFixedSize(w, h);
00188 setWindowOpacity(0.94);
00189 }
00190 KLFPleaseWaitPopup::~KLFPleaseWaitPopup()
00191 {
00192 if (pDisableUi && pParentWidget != NULL)
00193 pParentWidget->setEnabled(true);
00194 }
00195
00196 void KLFPleaseWaitPopup::setDisableUi(bool disableUi)
00197 {
00198 pDisableUi = disableUi;
00199 }
00200
00201 void KLFPleaseWaitPopup::showPleaseWait()
00202 {
00203 KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ;
00204
00205 QSize desktopSize;
00206 QDesktopWidget *dw = QApplication::desktop();
00207 if (dw != NULL) {
00208 desktopSize = dw->screenGeometry(this).size();
00209 } else {
00210 desktopSize = QSize(1024, 768);
00211 }
00212 move(desktopSize.width()/2 - width()/2, desktopSize.height()/2 - height()/2);
00213 show();
00214 setStyleSheet(styleSheet());
00215
00216 if (pDisableUi && pParentWidget != NULL)
00217 pParentWidget->setEnabled(false);
00218
00219 while (!pGotPaintEvent)
00220 qApp->processEvents();
00221 }
00222
00223 void KLFPleaseWaitPopup::mousePressEvent(QMouseEvent *)
00224 {
00225 hide();
00226 pDiscarded = true;
00227 }
00228
00229 void KLFPleaseWaitPopup::paintEvent(QPaintEvent *event)
00230 {
00231 pGotPaintEvent = true;
00232 QLabel::paintEvent(event);
00233 }
00234
00235
00236
00237
00238
00239
00240 KLFDelayedPleaseWaitPopup::KLFDelayedPleaseWaitPopup(const QString& text, QWidget *callingWidget)
00241 : KLFPleaseWaitPopup(text, callingWidget), pDelay(1000)
00242 {
00243 timer.start();
00244 }
00245 KLFDelayedPleaseWaitPopup::~KLFDelayedPleaseWaitPopup()
00246 {
00247 }
00248 void KLFDelayedPleaseWaitPopup::setDelay(int ms)
00249 {
00250 pDelay = ms;
00251 }
00252 void KLFDelayedPleaseWaitPopup::process()
00253 {
00254 if (!pleaseWaitShown() && timer.elapsed() > pDelay)
00255 showPleaseWait();
00256 qApp->processEvents();
00257 }
00258
00259
00260
00261
00262
00263
00264 KLFEnumComboBox::KLFEnumComboBox(QWidget *parent)
00265 : QComboBox(parent)
00266 {
00267 setEnumValues(QList<int>(), QStringList());
00268 connect(this, SIGNAL(currentIndexChanged(int)), this, SLOT(internalCurrentIndexChanged(int)));
00269 }
00270
00271 KLFEnumComboBox::KLFEnumComboBox(const QList<int>& enumValues, const QStringList& enumTitles,
00272 QWidget *parent)
00273 : QComboBox(parent)
00274 {
00275 setEnumValues(enumValues, enumTitles);
00276 connect(this, SIGNAL(currentIndexChanged(int)), this, SLOT(internalCurrentIndexChanged(int)));
00277 }
00278
00279 KLFEnumComboBox::~KLFEnumComboBox()
00280 {
00281 }
00282
00283 void KLFEnumComboBox::setEnumValues(const QList<int>& enumValues, const QStringList& enumTitles)
00284 {
00285 KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ;
00286 klfDbg("enumValues="<<enumValues<<"; enumTitles="<<enumTitles);
00287 blockSignals(true);
00288 int savedCurrentIndex = currentIndex();
00289 if (enumValues.size() != enumTitles.size()) {
00290 qWarning()<<KLF_FUNC_NAME<<": enum value list and enum title list do not match!";
00291 return;
00292 }
00293 pEnumValueList = enumValues;
00294 clear();
00295 int k;
00296 for (k = 0; k < enumValues.size(); ++k) {
00297 pEnumValues[enumValues[k]] = enumTitles[k];
00298 insertItem(k, enumTitles[k], QVariant(enumValues[k]));
00299 pEnumCbxIndexes[enumValues[k]] = k;
00300 }
00301 if (savedCurrentIndex >= 0 && savedCurrentIndex < count())
00302 setCurrentIndex(savedCurrentIndex);
00303 blockSignals(false);
00304 }
00305
00306 int KLFEnumComboBox::selectedValue() const
00307 {
00308 return itemData(currentIndex()).toInt();
00309 }
00310
00311 QString KLFEnumComboBox::enumText(int enumValue) const
00312 {
00313 if (!pEnumValueList.contains(enumValue)) {
00314 qWarning()<<KLF_FUNC_NAME<<": "<<enumValue<<" is not a registered valid enum value!";
00315 return QString();
00316 }
00317 return pEnumValues[enumValue];
00318 }
00319
00320 void KLFEnumComboBox::setSelectedValue(int val)
00321 {
00322 if (!pEnumCbxIndexes.contains(val)) {
00323 qWarning()<<KLF_FUNC_NAME<<": "<<val<<" is not a registered valid enum value!";
00324 return;
00325 }
00326 setCurrentIndex(pEnumCbxIndexes[val]);
00327 }
00328
00329 void KLFEnumComboBox::internalCurrentIndexChanged(int index)
00330 {
00331 emit selectedValueChanged(itemData(index).toInt());
00332 }
00333
00334
00335
00336
00337
00338 KLFWaitAnimationOverlay::KLFWaitAnimationOverlay(QWidget *parent)
00339 : QLabel(parent)
00340 {
00341 pAnimMovie = NULL;
00342
00343
00344
00345
00346
00347 setAlignment(Qt::AlignHCenter|Qt::AlignVCenter);
00348
00349 hide();
00350
00351 pAnimTimerId = -1;
00352 pIsWaiting = false;
00353
00354
00355 pWidthPercent = 30;
00356 pHeightPercent = 70;
00357 pPositionXPercent = 50;
00358 pPositionYPercent = 50;
00359
00360 setBackgroundColor(QColor(255,255,255,128));
00361 }
00362
00363 KLFWaitAnimationOverlay::~KLFWaitAnimationOverlay()
00364 {
00365 }
00366
00367 QColor KLFWaitAnimationOverlay::backgroundColor() const
00368 {
00369 return palette().color(QPalette::Window);
00370 }
00371
00372 void KLFWaitAnimationOverlay::setWaitMovie(QMovie *movie)
00373 {
00374 if (pAnimMovie != NULL) {
00375 delete pAnimMovie;
00376 }
00377 pAnimMovie = movie;
00378 pAnimMovie->setParent(this);
00379 }
00380
00381 void KLFWaitAnimationOverlay::setWaitMovie(const QString& filename)
00382 {
00383 QMovie *m = new QMovie(filename);
00384 m->setCacheMode(QMovie::CacheAll);
00385 setWaitMovie(m);
00386 }
00387
00388
00389 void KLFWaitAnimationOverlay::setBackgroundColor(const QColor& c)
00390 {
00391 setStyleSheet(QString("background-color: rgba(%1,%2,%3,%4)")
00392 .arg(c.red()).arg(c.green()).arg(c.blue()).arg(c.alpha()));
00393 }
00394
00395
00396 void KLFWaitAnimationOverlay::startWait()
00397 {
00398 if (pIsWaiting)
00399 return;
00400
00401 pIsWaiting = true;
00402 if (pAnimMovie == NULL)
00403 return;
00404
00405 pAnimMovie->jumpToFrame(0);
00406 setPixmap(pAnimMovie->currentPixmap());
00407 setGeometry(calcAnimationLabelGeometry());
00408 show();
00409 update();
00410
00411 qApp->processEvents(QEventLoop::ExcludeUserInputEvents);
00412
00413 pAnimTimerId = startTimer(pAnimMovie->nextFrameDelay());
00414 }
00415
00416 void KLFWaitAnimationOverlay::stopWait()
00417 {
00418 if (!pIsWaiting)
00419 return;
00420
00421 hide();
00422
00423 if (pAnimTimerId >= 0)
00424 killTimer(pAnimTimerId);
00425 pAnimTimerId = -1;
00426 pIsWaiting = false;
00427 }
00428
00429 void KLFWaitAnimationOverlay::timerEvent(QTimerEvent *event)
00430 {
00431 if (event->timerId() == pAnimTimerId) {
00432 pAnimMovie->jumpToNextFrame();
00433 setPixmap(pAnimMovie->currentPixmap());
00434 repaint();
00435 return;
00436 }
00437 }
00438
00439 QRect KLFWaitAnimationOverlay::calcAnimationLabelGeometry()
00440 {
00441 QWidget * w = parentWidget();
00442 if (w == NULL) {
00443 qWarning()<<KLF_FUNC_NAME<<": this animation label MUST be used with a parent!";
00444 return QRect();
00445 }
00446 QRect g = w->geometry();
00447 QSize sz = QSize(w->width()*pWidthPercent/100,w->height()*pHeightPercent/100);
00448
00449 klfDbg("parent geometry: "<<g<<"; our size="<<sz) ;
00450
00451 return KLF_DEBUG_TEE( QRect(QPoint( (g.width()-sz.width())*pPositionXPercent/100,
00452 (g.height()-sz.height())*pPositionYPercent/100),
00453 sz) );
00454 }
00455
00456
00457
00458
00459
00460
00461 KLF_EXPORT void klfDrawGlowedImage(QPainter *p, const QImage& foreground, const QColor& glowcol,
00462 int r, bool also_draw_image)
00463 {
00464 KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ;
00465
00466 QImage fg = foreground;
00467 if (fg.format() != QImage::Format_ARGB32_Premultiplied &&
00468 fg.format() != QImage::Format_ARGB32)
00469 fg = fg.convertToFormat(QImage::Format_ARGB32);
00470
00471 QRgb glow_color = glowcol.rgba();
00472
00473 qreal dpr = p->device()->devicePixelRatioF();
00474 QSize userspace_size = fg.size() / dpr;
00475
00476 int r2 = r*dpr;
00477
00478 QImage glow(fg.size(), QImage::Format_ARGB32_Premultiplied);
00479 int x, y;
00480 qreal ga = qAlpha(glow_color) / qreal(255);
00481 ga /= r*r;
00482 for (x = 0; x < fg.width(); ++x) {
00483 for (y = 0; y < fg.height(); ++y) {
00484 qreal ai = qAlpha(fg.pixel(x,y)) * ga;
00485 qreal a = ai / 255;
00486
00487 glow.setPixel(x,y, qRgba(qRed(glow_color)*a, qGreen(glow_color)*a, qBlue(glow_color)*a, ai));
00488 }
00489 }
00490
00491
00492
00493
00494 int dx, dy;
00495 for (dx = -r2; dx <= r2; dx += dpr) {
00496 for (dy = -r2; dy <= r2; dy += dpr) {
00497 if (dx*dx+dy*dy > r2*r2)
00498 continue;
00499 p->drawImage(QRectF(QPointF(dx/dpr,dy/dpr), userspace_size), glow);
00500 }
00501 }
00502
00503 if (also_draw_image) {
00504 p->drawImage(QRect(QPoint(0,0), userspace_size), fg);
00505 }
00506 }
00507
00508
00509
00510
00511
00512 QImage klfImageScaled(const QImage& source, const QSize& newSize)
00513 {
00514 QImage img = source.scaled(newSize, Qt::KeepAspectRatio, Qt::SmoothTransformation);
00515
00516 QStringList keys = source.textKeys();
00517 int k;
00518 for (k = 0; k < keys.size(); ++k) {
00519 img.setText(keys[k], source.text(keys[k]));
00520 }
00521 return img;
00522 }
00523
00524
00525
00526
00527 KLF_EXPORT QRect klf_get_window_geometry(QWidget *w)
00528 {
00529 #if defined(KLF_WS_X11)
00530 QRect g = w->frameGeometry();
00531 #else
00532 QRect g = w->geometry();
00533 #endif
00534 return g;
00535 }
00536
00537 KLF_EXPORT void klf_set_window_geometry(QWidget *w, QRect g)
00538 {
00539 if ( ! g.isValid() )
00540 return;
00541
00542 w->setGeometry(g);
00543 }
00544
00545
00546 KLFWindowGeometryRestorer::KLFWindowGeometryRestorer(QWidget *window)
00547 : QObject(window), pWindow(window)
00548 {
00549 window->installEventFilter(this);
00550 }
00551
00552 KLFWindowGeometryRestorer::~KLFWindowGeometryRestorer()
00553 {
00554 }
00555
00556 bool KLFWindowGeometryRestorer::eventFilter(QObject *obj, QEvent *event)
00557 {
00558 if (obj == pWindow) {
00559 if (event->type() == QEvent::Hide) {
00560
00561 pWindow->setProperty("klf_saved_geometry", klf_get_window_geometry(pWindow));
00562 } else if (event->type() == QEvent::Show) {
00563 QVariant val;
00564 if ((val = pWindow->property("klf_saved_geometry")).isValid())
00565 klf_set_window_geometry(pWindow, val.value<QRect>());
00566 }
00567 }
00568
00569 return false;
00570 }
00571
00572
00573
00578 static QHash<QWidget*,bool> windowShownStates;
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597 KLF_EXPORT void klfHideWindows()
00598 {
00599 KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ;
00600
00601
00602
00603
00604 QHash<QWidget*,bool> states;
00605 bool allalreadyhidden = true;
00606 QWidgetList wlist = QApplication::topLevelWidgets();
00607 foreach (QWidget *w, wlist) {
00608
00609
00610 uint wflags = w->windowFlags();
00611 klfDbg("next widget in line: "<<w<<", wflags="<<wflags) ;
00612 if ((wflags & Qt::Window) == 0) {
00613 continue;
00614 }
00615 if (wflags & Qt::X11BypassWindowManagerHint) {
00619 continue;
00620 }
00621 klfDbg("dealing with widget "<<w) ;
00622 bool shown = w->isVisible();
00623 states[w] = shown;
00624 if (shown) {
00625 klfDbg("hiding window "<<w<<", wflags="<<w->windowFlags()) ;
00626 w->hide();
00627 allalreadyhidden = false;
00628 }
00629 }
00630 if (!allalreadyhidden) {
00631
00632 windowShownStates = states;
00633 }
00634 }
00635
00636 KLF_EXPORT void klfRestoreWindows()
00637 {
00638 KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ;
00639 QWidgetList wlist = QApplication::topLevelWidgets();
00640 foreach (QWidget *w, wlist) {
00641 if (!windowShownStates.contains(w))
00642 continue;
00643
00644 if (!w->isVisible()) {
00645 klfDbg("Restoring window "<<w) ;
00646 w->setVisible(windowShownStates[w]);
00647 }
00648 }
00649 }