[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
41 : QObject(parent)
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}
87{
88}
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{
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{
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{
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}
246{
247}
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
280{
281}
282
283void KLFEnumComboBox::setEnumValues(const QList<int>& enumValues, const QStringList& enumTitles)
284{
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
364{
365}
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{
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
553{
554}
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{
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{
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)
Definition: klfguiutil.cpp:248
virtual ~KLFDelayedPleaseWaitPopup()
Definition: klfguiutil.cpp:245
KLFDelayedPleaseWaitPopup(const QString &text, QWidget *callingWidget=NULL)
Definition: klfguiutil.cpp:240
QString enumText(int enumValue) const
Definition: klfguiutil.cpp:311
void setSelectedValue(int val)
Definition: klfguiutil.cpp:320
void setEnumValues(const QList< int > &enumValues, const QStringList &enumTitles)
Definition: klfguiutil.cpp:283
virtual ~KLFEnumComboBox()
Definition: klfguiutil.cpp:279
KLFEnumComboBox(QWidget *parent=0)
Definition: klfguiutil.cpp:264
void selectedValueChanged(int enumValue)
A popup screen inviting the user to wait.
Definition: klfguiutil.h:238
virtual void paintEvent(QPaintEvent *event)
Definition: klfguiutil.cpp:229
virtual void setDisableUi(bool disableUi)
Definition: klfguiutil.cpp:196
virtual void showPleaseWait()
Definition: klfguiutil.cpp:201
virtual void mousePressEvent(QMouseEvent *event)
Definition: klfguiutil.cpp:223
KLFPleaseWaitPopup(const QString &text, QWidget *callingWidget=NULL, bool alwaysAbove=false)
Definition: klfguiutil.cpp:165
virtual ~KLFPleaseWaitPopup()
Definition: klfguiutil.cpp:190
virtual bool pleaseWaitShown() const
Definition: klfguiutil.h:272
virtual void setDescriptiveText(const QString &labelText)
Definition: klfguiutil.cpp:108
virtual void startReportingProgress(KLFProgressReporter *progressReporter, const QString &descriptiveText)
Definition: klfguiutil.cpp:113
virtual ~KLFProgressDialog()
Definition: klfguiutil.cpp:86
void paintEvent(QPaintEvent *event)
Definition: klfguiutil.cpp:147
virtual void setValue(int value)
Definition: klfguiutil.cpp:140
KLFProgressDialog(QString labelText=QString(), QWidget *parent=NULL)
Definition: klfguiutil.cpp:74
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()
Definition: klfguiutil.cpp:47
int min() const
Definition: klfguiutil.h:71
void doReportProgress(int value)
Definition: klfguiutil.cpp:55
KLFProgressReporter(int min, int max, QObject *parent=NULL)
Definition: klfguiutil.cpp:40
void setRelPointSize(int relps)
KLFWaitAnimationOverlay(QWidget *parent)
Definition: klfguiutil.cpp:338
virtual void timerEvent(QTimerEvent *event)
Definition: klfguiutil.cpp:429
void setBackgroundColor(const QColor &c)
Set the label background color.
Definition: klfguiutil.cpp:389
virtual ~KLFWaitAnimationOverlay()
Definition: klfguiutil.cpp:363
virtual void setWaitMovie(QMovie *movie)
Set which animation to display while searching.
Definition: klfguiutil.cpp:372
virtual QRect calcAnimationLabelGeometry()
Definition: klfguiutil.cpp:439
virtual void startWait()
Display the animation.
Definition: klfguiutil.cpp:396
virtual void stopWait()
Hide the animation.
Definition: klfguiutil.cpp:416
virtual bool eventFilter(QObject *obj, QEvent *event)
Definition: klfguiutil.cpp:556
virtual ~KLFWindowGeometryRestorer()
Definition: klfguiutil.cpp:552
KLFWindowGeometryRestorer(QWidget *window)
Definition: klfguiutil.cpp:546
#define KLF_DEBUG_BLOCK(msg)
Utility to debug the execution of a block.
#define KLF_DEBUG_TEE(expr)
Print the value of expression and return it.
#define KLF_FUNC_NAME
#define klfDbg(streamableItems)
print debug stream items
#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.
Definition: klfguiutil.cpp:461
KLF_EXPORT QRect klf_get_window_geometry(QWidget *w)
Definition: klfguiutil.cpp:527
KLF_EXPORT void klfHideWindows()
Definition: klfguiutil.cpp:597
KLF_EXPORT void klfRestoreWindows()
Definition: klfguiutil.cpp:636
QImage klfImageScaled(const QImage &source, const QSize &newSize)
Scale image, preserve aspect ratio and meta-information.
Definition: klfguiutil.cpp:512
KLF_EXPORT void klf_set_window_geometry(QWidget *w, QRect g)
Definition: klfguiutil.cpp:537
int alpha() const
int blue() const
int green() const
int red() const
QRgb rgba() 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
bool contains(const T &value) const
int size() const
bool contains(const Key &key) const
void setCacheMode(CacheMode mode)
QPixmap currentPixmap() const
bool jumpToFrame(int frameNumber)
bool jumpToNextFrame()
int nextFrameDelay() const
virtual bool event(QEvent *e)
void installEventFilter(QObject *filterObj)
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
QString arg(qlonglong a, int fieldWidth, int base, QChar fillChar) const
typedef WindowFlags
int elapsed() const
void start()
int timerId() const
T value() const

Generated by doxygen 1.9.5