[KLF Backend][KLF Tools][KLF Home]
KLatexFormula Project
klfguiutil.cpp
Go to the documentation of this file.
1/***************************************************************************
2 * file klfguiutil.cpp
3 * This file is part of the KLatexFormula Project.
4 * Copyright (C) 2011 by Philippe Faist
5 * philippe.faist at bluewin.ch
6 * *
7 * This program is free software; you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by *
9 * the Free Software Foundation; either version 2 of the License, or *
10 * (at your option) any later version. *
11 * *
12 * This program is distributed in the hope that it will be useful, *
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 * GNU General Public License for more details. *
16 * *
17 * You should have received a copy of the GNU General Public License *
18 * along with this program; if not, write to the *
19 * Free Software Foundation, Inc., *
20 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
21 ***************************************************************************/
22/* $Id$ */
23
24#include <cmath>
25
26#include <QApplication>
27#include <QDesktopWidget>
28#include <QIcon>
29#include <QPushButton>
30#include <QDebug>
31
32#include "klfutil.h"
33#include "klfrelativefont.h"
34#include "klfguiutil.h"
35
36
37// ----------------------------------------------
38
39
42{
43 pMin = min;
44 pMax = max;
45 pFinished = false;
46}
48{
49 if (!pFinished) { // make sure finished() is emitted.
50 emit progress(pMax); // some connected clients just wait for maximum value progress
51 emit finished();
52 }
53}
54
56{
57 if (pFinished) {
58 qWarning()<<KLF_FUNC_NAME<<": Operation is already finished!";
59 return;
60 }
61 emit progress(value);
62 if (value >= pMax) {
63 emit finished();
64 pFinished = true;
65 }
66}
67
68
69
70// ---------------------------------------------------------
71
72
73
75 : QProgressDialog(parent)
76{
77 setup(false);
78 init(labelText);
79}
80KLFProgressDialog::KLFProgressDialog(bool canCancel, QString labelText, QWidget *parent)
81 : QProgressDialog(parent)
82{
83 setup(canCancel);
84 init(labelText);
85}
89
90void KLFProgressDialog::setup(bool canCancel)
91{
92 pProgressReporter = NULL;
93 setAutoClose(true);
94 setAutoReset(true);
95 setModal(true);
96 // setWindowModality(Qt::ApplicationModal);
97 setWindowIcon(QIcon(":/pics/klatexformula-16.png"));
98 setWindowTitle(tr("Progress"));
99 QPushButton *cbtn = new QPushButton(tr("Cancel"), this);
100 setCancelButton(cbtn);
101 cbtn->setEnabled(canCancel);
102}
103void KLFProgressDialog::init(const QString& labelText)
104{
105 setDescriptiveText(labelText);
106}
107
109{
110 setLabelText(labelText);
111 setFixedSize((int)(sizeHint().width()*1.3), (int)(sizeHint().height()*1.1));
112}
114 const QString& descriptiveText)
115{
116 reset();
117 setDescriptiveText(descriptiveText);
118 setRange(progressReporter->min(), progressReporter->max());
119 setValue(0);
120
121 // disconnect any previous progress reporter object
122 if (pProgressReporter != NULL)
123 disconnect(pProgressReporter, 0, this, SLOT(setValue(int)));
124 // and connect to this new one
125 connect(progressReporter, SIGNAL(progress(int)), this, SLOT(setValue(int)));
126}
127
129{
130 reset();
131 setRange(progressReporter->min(), progressReporter->max());
132 setValue(0);
133 // disconnect any previous progress reporter object
134 if (pProgressReporter != NULL)
135 disconnect(pProgressReporter, 0, this, SLOT(setValue(int)));
136 // and connect to this new one
137 connect(progressReporter, SIGNAL(progress(int)), this, SLOT(setValue(int)));
138}
139
141{
142 // KLF_DEBUG_BLOCK(KLF_FUNC_NAME);
143 klfDbg("value="<<value);
144 QProgressDialog::setValue(value);
145}
146
148{
149 KLF_DEBUG_BLOCK(KLF_FUNC_NAME);
150 QProgressDialog::paintEvent(event);
151}
152
153
154// --------------------------
155
156
157static Qt::WindowFlags klfpleasewait_flagsForSettings(bool alwaysAbove)
158{
159 Qt::WindowFlags f = Qt::Window|Qt::SplashScreen|Qt::FramelessWindowHint;
160 if (alwaysAbove)
161 f |= Qt::WindowStaysOnTopHint|Qt::X11BypassWindowManagerHint;
162 return f;
163}
164
165KLFPleaseWaitPopup::KLFPleaseWaitPopup(const QString& text, QWidget *parent, bool alwaysAbove)
166 : QLabel(text, ((parent!=NULL)?parent->window():NULL), klfpleasewait_flagsForSettings(alwaysAbove)),
167 pParentWidget(parent), pDisableUi(false), pGotPaintEvent(false), pDiscarded(false)
168{
169 KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ;
170 KLFRelativeFont *relfont = new KLFRelativeFont(this);
171 relfont->setRelPointSize(+2);
172
173 setAlignment(Qt::AlignHCenter|Qt::AlignVCenter);
174 setWindowModality(Qt::ApplicationModal);
175 // let this window be styled by skins
176 setAttribute(Qt::WA_StyledBackground, true);
177 setProperty("klfTopLevelWidget", QVariant(true));
178
179 setFrameStyle(QFrame::Panel|QFrame::Sunken);
180
181 QWidget *pw = parentWidget(); // the one set in QLabel constructor, this is the top-level window
182 if (pw != NULL)
183 setStyleSheet(pw->window()->styleSheet());
184
185 int w = qMax( (int)(sizeHint().width() *1.3) , 500 );
186 int h = qMax( (int)(sizeHint().height()*1.1) , 100 );
187 setFixedSize(w, h);
188 setWindowOpacity(0.94);
189}
191{
192 if (pDisableUi && pParentWidget != NULL)
193 pParentWidget->setEnabled(true);
194}
195
197{
198 pDisableUi = disableUi;
199}
200
202{
203 KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ;
204
205 QSize desktopSize;
206 QDesktopWidget *dw = QApplication::desktop();
207 if (dw != NULL) {
208 desktopSize = dw->screenGeometry(this).size();
209 } else {
210 desktopSize = QSize(1024, 768); // assume some default, worst case widget is more left and higher
211 }
212 move(desktopSize.width()/2 - width()/2, desktopSize.height()/2 - height()/2);
213 show();
214 setStyleSheet(styleSheet());
215
216 if (pDisableUi && pParentWidget != NULL)
217 pParentWidget->setEnabled(false);
218
219 while (!pGotPaintEvent)
220 qApp->processEvents();
221}
222
224{
225 hide();
226 pDiscarded = true;
227}
228
230{
231 pGotPaintEvent = true;
232 QLabel::paintEvent(event);
233}
234
235
236
237// --------------------------
238
239
241 : KLFPleaseWaitPopup(text, callingWidget), pDelay(1000)
242{
243 timer.start();
244}
249{
250 pDelay = ms;
251}
253{
254 if (!pleaseWaitShown() && timer.elapsed() > pDelay)
256 qApp->processEvents();
257}
258
259
260
261// ------------------------------------------------
262
263
265 : QComboBox(parent)
266{
268 connect(this, SIGNAL(currentIndexChanged(int)), this, SLOT(internalCurrentIndexChanged(int)));
269}
270
271KLFEnumComboBox::KLFEnumComboBox(const QList<int>& enumValues, const QStringList& enumTitles,
272 QWidget *parent)
273 : QComboBox(parent)
274{
275 setEnumValues(enumValues, enumTitles);
276 connect(this, SIGNAL(currentIndexChanged(int)), this, SLOT(internalCurrentIndexChanged(int)));
277}
278
282
283void KLFEnumComboBox::setEnumValues(const QList<int>& enumValues, const QStringList& enumTitles)
284{
285 KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ;
286 klfDbg("enumValues="<<enumValues<<"; enumTitles="<<enumTitles);
287 blockSignals(true);
288 int savedCurrentIndex = currentIndex();
289 if (enumValues.size() != enumTitles.size()) {
290 qWarning()<<KLF_FUNC_NAME<<": enum value list and enum title list do not match!";
291 return;
292 }
293 pEnumValueList = enumValues;
294 clear();
295 int k;
296 for (k = 0; k < enumValues.size(); ++k) {
297 pEnumValues[enumValues[k]] = enumTitles[k];
298 insertItem(k, enumTitles[k], QVariant(enumValues[k]));
299 pEnumCbxIndexes[enumValues[k]] = k;
300 }
301 if (savedCurrentIndex >= 0 && savedCurrentIndex < count())
302 setCurrentIndex(savedCurrentIndex);
303 blockSignals(false);
304}
305
307{
308 return itemData(currentIndex()).toInt();
309}
310
312{
313 if (!pEnumValueList.contains(enumValue)) {
314 qWarning()<<KLF_FUNC_NAME<<": "<<enumValue<<" is not a registered valid enum value!";
315 return QString();
316 }
317 return pEnumValues[enumValue];
318}
319
321{
322 if (!pEnumCbxIndexes.contains(val)) {
323 qWarning()<<KLF_FUNC_NAME<<": "<<val<<" is not a registered valid enum value!";
324 return;
325 }
326 setCurrentIndex(pEnumCbxIndexes[val]);
327}
328
329void KLFEnumComboBox::internalCurrentIndexChanged(int index)
330{
331 emit selectedValueChanged(itemData(index).toInt());
332}
333
334
335// ------------------------
336
337
339 : QLabel(parent)
340{
341 pAnimMovie = NULL;
342 /*
343 pAnimMovie = new QMovie(":/pics/wait_anim.mng", "MNG", this);
344 pAnimMovie->setCacheMode(QMovie::CacheAll);
345 */
346
347 setAlignment(Qt::AlignHCenter|Qt::AlignVCenter);
348
349 hide();
350
351 pAnimTimerId = -1;
352 pIsWaiting = false;
353
354 // default values
355 pWidthPercent = 30;
356 pHeightPercent = 70;
357 pPositionXPercent = 50;
358 pPositionYPercent = 50;
359
360 setBackgroundColor(QColor(255,255,255,128));
361}
362
366
368{
369 return palette().color(QPalette::Window);
370}
371
373{
374 if (pAnimMovie != NULL) {
375 delete pAnimMovie;
376 }
377 pAnimMovie = movie;
378 pAnimMovie->setParent(this);
379}
380
382{
383 QMovie *m = new QMovie(filename);
384 m->setCacheMode(QMovie::CacheAll);
385 setWaitMovie(m);
386}
387
388
390{
391 setStyleSheet(QString("background-color: rgba(%1,%2,%3,%4)")
392 .arg(c.red()).arg(c.green()).arg(c.blue()).arg(c.alpha()));
393}
394
395
397{
398 if (pIsWaiting)
399 return;
400
401 pIsWaiting = true;
402 if (pAnimMovie == NULL)
403 return;
404
405 pAnimMovie->jumpToFrame(0);
406 setPixmap(pAnimMovie->currentPixmap());
407 setGeometry(calcAnimationLabelGeometry());
408 show();
409 update();
410
411 qApp->processEvents(QEventLoop::ExcludeUserInputEvents);
412
413 pAnimTimerId = startTimer(pAnimMovie->nextFrameDelay());
414}
415
417{
418 if (!pIsWaiting)
419 return;
420
421 hide();
422
423 if (pAnimTimerId >= 0)
424 killTimer(pAnimTimerId);
425 pAnimTimerId = -1;
426 pIsWaiting = false;
427}
428
430{
431 if (event->timerId() == pAnimTimerId) {
432 pAnimMovie->jumpToNextFrame();
433 setPixmap(pAnimMovie->currentPixmap());
434 repaint();
435 return;
436 }
437}
438
440{
441 QWidget * w = parentWidget();
442 if (w == NULL) {
443 qWarning()<<KLF_FUNC_NAME<<": this animation label MUST be used with a parent!";
444 return QRect();
445 }
446 QRect g = w->geometry();
447 QSize sz = QSize(w->width()*pWidthPercent/100,w->height()*pHeightPercent/100);
448
449 klfDbg("parent geometry: "<<g<<"; our size="<<sz) ;
450
451 return KLF_DEBUG_TEE( QRect(QPoint( (g.width()-sz.width())*pPositionXPercent/100,
452 (g.height()-sz.height())*pPositionYPercent/100),
453 sz) );
454}
455
456
457
458// -----------------------
459
460
461KLF_EXPORT void klfDrawGlowedImage(QPainter *p, const QImage& foreground, const QColor& glowcol,
462 int r, bool also_draw_image)
463{
464 KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ;
465
466 QImage fg = foreground;
467 if (fg.format() != QImage::Format_ARGB32_Premultiplied &&
468 fg.format() != QImage::Format_ARGB32)
469 fg = fg.convertToFormat(QImage::Format_ARGB32);
470
471 QRgb glow_color = glowcol.rgba();
472
473 qreal dpr = p->device()->devicePixelRatioF();
474 QSize userspace_size = fg.size() / dpr;
475
476 int r2 = r*dpr;
477
478 QImage glow(fg.size(), QImage::Format_ARGB32_Premultiplied);
479 int x, y;
480 qreal ga = qAlpha(glow_color) / qreal(255);
481 ga /= r*r; // heuristic scaling of alpha
482 for (x = 0; x < fg.width(); ++x) {
483 for (y = 0; y < fg.height(); ++y) {
484 qreal ai = qAlpha(fg.pixel(x,y)) * ga;
485 qreal a = ai / 255;
486 // glow format is argb32_premultiplied
487 glow.setPixel(x,y, qRgba(qRed(glow_color)*a, qGreen(glow_color)*a, qBlue(glow_color)*a, ai));
488 }
489 }
490 // now draw that glowed image a few times moving around the interest point to do a glow effect
491 // p->save();
492 // p->setOpacity(std::log(-numoverlaps));
493 // p->setCompositionMode(QPainter::CompositionMode_Plus);
494 int dx, dy;
495 for (dx = -r2; dx <= r2; dx += dpr) {
496 for (dy = -r2; dy <= r2; dy += dpr) {
497 if (dx*dx+dy*dy > r2*r2) // don't go beyond r2 device pixels from (0,0)
498 continue;
499 p->drawImage(QRectF(QPointF(dx/dpr,dy/dpr), userspace_size), glow);
500 }
501 }
502 // p->restore();
503 if (also_draw_image) {
504 p->drawImage(QRect(QPoint(0,0), userspace_size), fg);
505 }
506}
507
508
509
510// --------------------------
511
512QImage klfImageScaled(const QImage& source, const QSize& newSize)
513{
514 QImage img = source.scaled(newSize, Qt::KeepAspectRatio, Qt::SmoothTransformation);
515 // set text attributes
516 QStringList keys = source.textKeys();
517 int k;
518 for (k = 0; k < keys.size(); ++k) {
519 img.setText(keys[k], source.text(keys[k]));
520 }
521 return img;
522}
523
524
525// --------------------
526
528{
529#if defined(KLF_WS_X11)
530 QRect g = w->frameGeometry();
531#else
532 QRect g = w->geometry();
533#endif
534 return g;
535}
536
538{
539 if ( ! g.isValid() )
540 return;
541
542 w->setGeometry(g);
543}
544
545
547 : QObject(window), pWindow(window)
548{
549 window->installEventFilter(this);
550}
551
555
557{
558 if (obj == pWindow) {
559 if (event->type() == QEvent::Hide) {
560 // save geometry
561 pWindow->setProperty("klf_saved_geometry", klf_get_window_geometry(pWindow));
562 } else if (event->type() == QEvent::Show) {
563 QVariant val;
564 if ((val = pWindow->property("klf_saved_geometry")).isValid())
565 klf_set_window_geometry(pWindow, val.value<QRect>());
566 }
567 }
568
569 return false;
570}
571
572
573
578static QHash<QWidget*,bool> windowShownStates;
579
580/*
581inline bool has_ancestor_of_type(QObject *testobj, const char * type)
582{
583 klfDbg("testing if "<<testobj<<" is (grand-)child of object inheriting "<<type) ;
584 if (testobj == NULL)
585 return false;
586 do {
587 if (testobj->inherits(type)) {
588 klfDbg("inherits "<<type<<"!") ;
589 return true;
590 }
591 } while ((testobj = testobj->parent()) != NULL) ;
592 klfDbg("no.") ;
593 return false;
594}
595*/
596
598{
599 KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ;
600 // / ** \todo don't _FORCE_ this setting, remember and restore it.... * /
601 // qApp->setQuitOnLastWindowClosed(false);
602
603 // save the window states, while checking that not all the windows are already hidden
605 bool allalreadyhidden = true;
606 QWidgetList wlist = QApplication::topLevelWidgets();
607 foreach (QWidget *w, wlist) {
608 // if (w->inherits("QMenu"))
609 // continue;
610 uint wflags = w->windowFlags();
611 klfDbg("next widget in line: "<<w<<", wflags="<<wflags) ;
612 if ((wflags & Qt::Window) == 0) {
613 continue;
614 }
615 if (wflags & Qt::X11BypassWindowManagerHint) {
619 continue;
620 }
621 klfDbg("dealing with widget "<<w) ;
622 bool shown = w->isVisible();
623 states[w] = shown;
624 if (shown) {
625 klfDbg("hiding window "<<w<<", wflags="<<w->windowFlags()) ;
626 w->hide();
627 allalreadyhidden = false;
628 }
629 }
630 if (!allalreadyhidden) {
631 // don't overwrite the saved status list with an all-hidden state list
632 windowShownStates = states;
633 }
634}
635
637{
638 KLF_DEBUG_BLOCK(KLF_FUNC_NAME) ;
639 QWidgetList wlist = QApplication::topLevelWidgets();
640 foreach (QWidget *w, wlist) {
641 if (!windowShownStates.contains(w))
642 continue;
643 // restore this window
644 if (!w->isVisible()) {
645 klfDbg("Restoring window "<<w) ;
646 w->setVisible(windowShownStates[w]);
647 }
648 }
649}
virtual void setDelay(int ms)
KLFDelayedPleaseWaitPopup(const QString &text, QWidget *callingWidget=NULL)
QString enumText(int enumValue) const
void setSelectedValue(int val)
void setEnumValues(const QList< int > &enumValues, const QStringList &enumTitles)
virtual ~KLFEnumComboBox()
KLFEnumComboBox(QWidget *parent=0)
void selectedValueChanged(int enumValue)
virtual void paintEvent(QPaintEvent *event)
virtual void setDisableUi(bool disableUi)
virtual void showPleaseWait()
virtual void mousePressEvent(QMouseEvent *event)
KLFPleaseWaitPopup(const QString &text, QWidget *callingWidget=NULL, bool alwaysAbove=false)
virtual ~KLFPleaseWaitPopup()
virtual bool pleaseWaitShown() const
Definition klfguiutil.h:272
virtual void setDescriptiveText(const QString &labelText)
virtual void startReportingProgress(KLFProgressReporter *progressReporter, const QString &descriptiveText)
virtual ~KLFProgressDialog()
void paintEvent(QPaintEvent *event)
virtual void setValue(int value)
KLFProgressDialog(QString labelText=QString(), QWidget *parent=NULL)
Object that emits progress information of a (lengthy) operation.
Definition klfguiutil.h:64
void progress(int progressValue)
int max() const
Definition klfguiutil.h:72
virtual ~KLFProgressReporter()
int min() const
Definition klfguiutil.h:71
void doReportProgress(int value)
KLFProgressReporter(int min, int max, QObject *parent=NULL)
void setRelPointSize(int relps)
KLFRelativeFont(QWidget *parent)
KLFWaitAnimationOverlay(QWidget *parent)
virtual void timerEvent(QTimerEvent *event)
void setBackgroundColor(const QColor &c)
Set the label background color.
virtual ~KLFWaitAnimationOverlay()
virtual void setWaitMovie(QMovie *movie)
Set which animation to display while searching.
virtual QRect calcAnimationLabelGeometry()
virtual void startWait()
Display the animation.
virtual void stopWait()
Hide the animation.
virtual bool eventFilter(QObject *obj, QEvent *event)
KLFWindowGeometryRestorer(QWidget *window)
#define KLF_DEBUG_BLOCK(msg)
Utility to debug the execution of a block.
Definition klfdebug.h:152
#define KLF_DEBUG_TEE(expr)
Print the value of expression and return it.
Definition klfdebug.h:154
#define klfDbg(streamableItems)
print debug stream items
Definition klfdebug.h:158
#define KLF_EXPORT
Definition klfdefs.h:41
KLF_EXPORT void klfDrawGlowedImage(QPainter *p, const QImage &foreground, const QColor &glowcol, int r, bool also_draw_image)
Draws the given image with a glow effect.
KLF_EXPORT QRect klf_get_window_geometry(QWidget *w)
KLF_EXPORT void klfHideWindows()
KLF_EXPORT void klfRestoreWindows()
QImage klfImageScaled(const QImage &source, const QSize &newSize)
Scale image, preserve aspect ratio and meta-information.
KLF_EXPORT void klf_set_window_geometry(QWidget *w, QRect g)
int alpha() const
int blue() const
int green() const
int red() const
QRgb rgba() const
Type type() const
QImage convertToFormat(Format format, Qt::ImageConversionFlags flags) const
Format format() const
int height() const
QRgb pixel(int x, int y) const
QImage scaled(int width, int height, Qt::AspectRatioMode aspectRatioMode, Qt::TransformationMode transformMode) const
void setPixel(int x, int y, uint index_or_rgb)
void setText(const QString &key, const QString &text)
QSize size() const
QString text(const QString &key) const
QStringList textKeys() const
int width() const
int size() const
QMovie(QObject *parent)
void setCacheMode(CacheMode mode)
QObject(QObject *parent)
virtual bool event(QEvent *e)
QObject * parent() const
void setParent(QObject *parent)
qreal devicePixelRatioF() const
QPaintDevice * device() const
void drawImage(const QRectF &target, const QImage &image, const QRectF &source, Qt::ImageConversionFlags flags)
int height() const
bool isValid() const
int width() const
int height() const
int width() const
Qt::WindowType WindowFlags
int timerId() const
T value() const

Generated by doxygen 1.18.0