1 | /* $Id: QIWizard.cpp 35234 2010-12-20 09:40:31Z vboxsync $ */
|
---|
2 | /** @file
|
---|
3 | *
|
---|
4 | * VBox frontends: Qt4 GUI ("VirtualBox"):
|
---|
5 | * QIWizard class implementation
|
---|
6 | */
|
---|
7 |
|
---|
8 | /*
|
---|
9 | * Copyright (C) 2009-2010 Oracle Corporation
|
---|
10 | *
|
---|
11 | * This file is part of VirtualBox Open Source Edition (OSE), as
|
---|
12 | * available from http://www.virtualbox.org. This file is free software;
|
---|
13 | * you can redistribute it and/or modify it under the terms of the GNU
|
---|
14 | * General Public License (GPL) as published by the Free Software
|
---|
15 | * Foundation, in version 2 as it comes in the "COPYING" file of the
|
---|
16 | * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
|
---|
17 | * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
|
---|
18 | */
|
---|
19 |
|
---|
20 | /* Global includes */
|
---|
21 | #include <QAbstractButton>
|
---|
22 | #include <QLayout>
|
---|
23 | #include <QTextEdit>
|
---|
24 |
|
---|
25 | /* Local includes */
|
---|
26 | #include "QIWizard.h"
|
---|
27 | #include "QILabel.h"
|
---|
28 | #include "VBoxGlobal.h"
|
---|
29 |
|
---|
30 | /* System includes */
|
---|
31 | #include <math.h>
|
---|
32 |
|
---|
33 | QIWizard::QIWizard(QWidget *pParent) : QIWithRetranslateUI<QWizard>(pParent)
|
---|
34 | {
|
---|
35 | #ifdef Q_WS_MAC
|
---|
36 | /* I'm really not sure why there shouldn't be any default button on Mac OS
|
---|
37 | * X. This prevents the using of Enter to jump to the next page. */
|
---|
38 | setOptions(options() ^ QWizard::NoDefaultButton);
|
---|
39 | #endif /* Q_WS_MAC */
|
---|
40 | }
|
---|
41 |
|
---|
42 | void QIWizard::resizeToGoldenRatio()
|
---|
43 | {
|
---|
44 | /* Random initial QILabel width() to be adjusted! */
|
---|
45 | int iLabelsWidth = 400;
|
---|
46 | resizeAccordingLabelWidth(iLabelsWidth);
|
---|
47 |
|
---|
48 | /* Label delta for 'golden ratio' calculation. */
|
---|
49 | int iLabelDelta = width() - iLabelsWidth;
|
---|
50 |
|
---|
51 | /* Calculating nearest 'golden ratio' width. */
|
---|
52 | int iGoldRatioWidth = (int)sqrt(1.61 * width() * height());
|
---|
53 | int iNewLabelWidth = iGoldRatioWidth - iLabelDelta;
|
---|
54 | resizeAccordingLabelWidth(iNewLabelWidth);
|
---|
55 | }
|
---|
56 |
|
---|
57 | void QIWizard::assignWatermark(const QString &strWatermark)
|
---|
58 | {
|
---|
59 | /* Create initial watermark. */
|
---|
60 | QPixmap pixWaterMark(strWatermark);
|
---|
61 |
|
---|
62 | /* Convert watermark to image which
|
---|
63 | * allows to manage pixel data directly. */
|
---|
64 | QImage imgWatermark = pixWaterMark.toImage();
|
---|
65 |
|
---|
66 | /* Use the right-top watermark pixel as frame color */
|
---|
67 | QRgb rgbFrame = imgWatermark.pixel(imgWatermark.width() - 1, 0);
|
---|
68 |
|
---|
69 | /* Take into account button's height */
|
---|
70 | int iPageHeight = height() - button(QWizard::CancelButton)->height();
|
---|
71 |
|
---|
72 | /* Create final image on the basis of incoming, applying the rules. */
|
---|
73 | QImage imgWatermarkNew(imgWatermark.width(), qMax(imgWatermark.height(), iPageHeight), imgWatermark.format());
|
---|
74 | for (int y = 0; y < imgWatermarkNew.height(); ++ y)
|
---|
75 | {
|
---|
76 | for (int x = 0; x < imgWatermarkNew.width(); ++ x)
|
---|
77 | {
|
---|
78 | /* Border rule 1 - draw border for ClassicStyle */
|
---|
79 | if (wizardStyle() == QWizard::ClassicStyle &&
|
---|
80 | (x == 0 || y == 0 || x == imgWatermarkNew.width() - 1 || y == imgWatermarkNew.height() - 1))
|
---|
81 | imgWatermarkNew.setPixel(x, y, rgbFrame);
|
---|
82 | /* Border rule 2 - draw border for ModernStyle */
|
---|
83 | else if (wizardStyle() == QWizard::ModernStyle && x == imgWatermarkNew.width() - 1)
|
---|
84 | imgWatermarkNew.setPixel(x, y, rgbFrame);
|
---|
85 | /* Horizontal extension rule - use last used color */
|
---|
86 | else if (x >= imgWatermark.width() && y < imgWatermark.height())
|
---|
87 | imgWatermarkNew.setPixel(x, y, imgWatermark.pixel(imgWatermark.width() - 1, y));
|
---|
88 | /* Vertical extension rule - use last used color */
|
---|
89 | else if (y >= imgWatermark.height() && x < imgWatermark.width())
|
---|
90 | imgWatermarkNew.setPixel(x, y, imgWatermark.pixel(x, imgWatermark.height() - 1));
|
---|
91 | /* Common extension rule - use last used color */
|
---|
92 | else if (x >= imgWatermark.width() && y >= imgWatermark.height())
|
---|
93 | imgWatermarkNew.setPixel(x, y, imgWatermark.pixel(imgWatermark.width() - 1, imgWatermark.height() - 1));
|
---|
94 | /* Else just copy color */
|
---|
95 | else
|
---|
96 | imgWatermarkNew.setPixel(x, y, imgWatermark.pixel(x, y));
|
---|
97 | }
|
---|
98 | }
|
---|
99 |
|
---|
100 | /* Convert processed image to pixmap and assign it to wizard's watermark. */
|
---|
101 | QPixmap pixWatermarkNew = QPixmap::fromImage(imgWatermarkNew);
|
---|
102 | setPixmap(QWizard::WatermarkPixmap, pixWatermarkNew);
|
---|
103 | }
|
---|
104 |
|
---|
105 | void QIWizard::assignBackground(const QString &strBg)
|
---|
106 | {
|
---|
107 | setPixmap(QWizard::BackgroundPixmap, strBg);
|
---|
108 | }
|
---|
109 |
|
---|
110 | void QIWizard::resizeAccordingLabelWidth(int iLabelsWidth)
|
---|
111 | {
|
---|
112 | /* Update QILabels size-hints */
|
---|
113 | QList<QILabel*> labels = findChildren<QILabel*>();
|
---|
114 | foreach (QILabel *pLabel, labels)
|
---|
115 | {
|
---|
116 | pLabel->useSizeHintForWidth(iLabelsWidth);
|
---|
117 | pLabel->updateGeometry();
|
---|
118 | }
|
---|
119 |
|
---|
120 | /* Unfortunately QWizard hides some of useful API in private part,
|
---|
121 | * BUT it also have few layouting bugs which could be easy fixed
|
---|
122 | * by that API, so we will use QWizard::restart() method
|
---|
123 | * to call the same functionality indirectly...
|
---|
124 | * Early call restart() which is usually goes on show()! */
|
---|
125 | restart();
|
---|
126 |
|
---|
127 | /* Now we have correct size-hints calculated for all the pages.
|
---|
128 | * We have to make sure all the pages uses maximum size-hint
|
---|
129 | * of all the available. */
|
---|
130 | QSize maxOfSizeHints;
|
---|
131 | QList<QIWizardPage*> pages = findChildren<QIWizardPage*>();
|
---|
132 | /* Search for the maximum available size-hint */
|
---|
133 | foreach (QIWizardPage *pPage, pages)
|
---|
134 | {
|
---|
135 | maxOfSizeHints.rwidth() = pPage->sizeHint().width() > maxOfSizeHints.width() ?
|
---|
136 | pPage->sizeHint().width() : maxOfSizeHints.width();
|
---|
137 | maxOfSizeHints.rheight() = pPage->sizeHint().height() > maxOfSizeHints.height() ?
|
---|
138 | pPage->sizeHint().height() : maxOfSizeHints.height();
|
---|
139 | }
|
---|
140 | /* Use that size-hint for all the pages */
|
---|
141 | foreach (QIWizardPage *pPage, pages)
|
---|
142 | {
|
---|
143 | pPage->setMinimumSizeHint(maxOfSizeHints);
|
---|
144 | pPage->updateGeometry();
|
---|
145 | }
|
---|
146 |
|
---|
147 | /* Reactivate layouts tree */
|
---|
148 | QList<QLayout*> layouts = findChildren<QLayout*>();
|
---|
149 | foreach (QLayout *pLayout, layouts)
|
---|
150 | pLayout->activate();
|
---|
151 |
|
---|
152 | /* Unfortunately QWizard hides some of useful API in private part,
|
---|
153 | * BUT it also have few layouting bugs which could be easy fixed
|
---|
154 | * by that API, so we will use QWizard::restart() method
|
---|
155 | * to call the same functionality indirectly...
|
---|
156 | * And now we call restart() after layout update procedure! */
|
---|
157 | restart();
|
---|
158 |
|
---|
159 | /* Resize to minimum possible size */
|
---|
160 | resize(minimumSizeHint());
|
---|
161 | }
|
---|
162 |
|
---|
163 | void QIWizard::retranslateAllPages()
|
---|
164 | {
|
---|
165 | QList<QIWizardPage*> pages = findChildren<QIWizardPage*>();
|
---|
166 | for(int i=0; i < pages.size(); ++i)
|
---|
167 | static_cast<QIWizardPage*>(pages.at((i)))->retranslateUi();
|
---|
168 | }
|
---|
169 |
|
---|
170 | QIWizardPage::QIWizardPage()
|
---|
171 | {
|
---|
172 | }
|
---|
173 |
|
---|
174 | QSize QIWizardPage::minimumSizeHint() const
|
---|
175 | {
|
---|
176 | return m_MinimumSizeHint.isValid() ? m_MinimumSizeHint : QWizardPage::minimumSizeHint();
|
---|
177 | }
|
---|
178 |
|
---|
179 | void QIWizardPage::setMinimumSizeHint(const QSize &minimumSizeHint)
|
---|
180 | {
|
---|
181 | m_MinimumSizeHint = minimumSizeHint;
|
---|
182 | }
|
---|
183 |
|
---|
184 | void QIWizardPage::setSummaryFieldLinesNumber(QTextEdit *pSummaryField, int iNumber)
|
---|
185 | {
|
---|
186 | /* Set the minimum height for the <pSummaryField> to <iNumber> lines of text including text margins */
|
---|
187 | int lineHeight = pSummaryField->fontMetrics().height();
|
---|
188 | int textMargin = 4; /* QTextDocument::documentMargin() returns '4' but available only since Qt 4.5 */
|
---|
189 | pSummaryField->setFixedHeight(lineHeight * iNumber + textMargin * 2);
|
---|
190 | }
|
---|
191 |
|
---|
192 | QString QIWizardPage::standardHelpText() const
|
---|
193 | {
|
---|
194 | return tr("Use the <b>%1</b> button to go to the next page of the wizard and the "
|
---|
195 | "<b>%2</b> button to return to the previous page. "
|
---|
196 | "You can also press <b>%3</b> if you want to cancel the execution "
|
---|
197 | "of this wizard.</p>")
|
---|
198 | .arg(VBoxGlobal::replaceHtmlEntities(VBoxGlobal::removeAccelMark(wizard()->buttonText(QWizard::NextButton).remove(" >"))))
|
---|
199 | .arg(VBoxGlobal::replaceHtmlEntities(VBoxGlobal::removeAccelMark(wizard()->buttonText(QWizard::BackButton).remove("< "))))
|
---|
200 | #ifdef Q_WS_MAC
|
---|
201 | .arg(QKeySequence("ESC").toString()); /* There is no button shown on Mac OS X, so just say the key sequence. */
|
---|
202 | #else /* Q_WS_MAC */
|
---|
203 | .arg(VBoxGlobal::replaceHtmlEntities(VBoxGlobal::removeAccelMark(wizard()->buttonText(QWizard::CancelButton))));
|
---|
204 | #endif /* Q_WS_MAC */
|
---|
205 | }
|
---|
206 |
|
---|
207 | void QIWizardPage::startProcessing()
|
---|
208 | {
|
---|
209 | if (isFinalPage())
|
---|
210 | wizard()->button(QWizard::FinishButton)->setEnabled(false);
|
---|
211 | }
|
---|
212 |
|
---|
213 | void QIWizardPage::endProcessing()
|
---|
214 | {
|
---|
215 | if (isFinalPage())
|
---|
216 | wizard()->button(QWizard::FinishButton)->setEnabled(true);
|
---|
217 | }
|
---|
218 |
|
---|