author | Eckhart Koeppen <eckhart.koppen@nokia.com> |
Thu, 22 Apr 2010 16:15:11 +0300 | |
branch | RCL_3 |
changeset 14 | 8c4229025c0b |
parent 4 | 3b1da2848fc7 |
permissions | -rw-r--r-- |
0 | 1 |
/**************************************************************************** |
2 |
** |
|
4
3b1da2848fc7
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
3
diff
changeset
|
3 |
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). |
0 | 4 |
** All rights reserved. |
5 |
** Contact: Nokia Corporation (qt-info@nokia.com) |
|
6 |
** |
|
7 |
** This file is part of the tools applications of the Qt Toolkit. |
|
8 |
** |
|
9 |
** $QT_BEGIN_LICENSE:LGPL$ |
|
10 |
** No Commercial Usage |
|
11 |
** This file contains pre-release code and may not be distributed. |
|
12 |
** You may use this file in accordance with the terms and conditions |
|
13 |
** contained in the Technology Preview License Agreement accompanying |
|
14 |
** this package. |
|
15 |
** |
|
16 |
** GNU Lesser General Public License Usage |
|
17 |
** Alternatively, this file may be used under the terms of the GNU Lesser |
|
18 |
** General Public License version 2.1 as published by the Free Software |
|
19 |
** Foundation and appearing in the file LICENSE.LGPL included in the |
|
20 |
** packaging of this file. Please review the following information to |
|
21 |
** ensure the GNU Lesser General Public License version 2.1 requirements |
|
22 |
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. |
|
23 |
** |
|
24 |
** In addition, as a special exception, Nokia gives you certain additional |
|
25 |
** rights. These rights are described in the Nokia Qt LGPL Exception |
|
26 |
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. |
|
27 |
** |
|
28 |
** If you have questions regarding the use of this file, please contact |
|
29 |
** Nokia at qt-info@nokia.com. |
|
30 |
** |
|
31 |
** |
|
32 |
** |
|
33 |
** |
|
34 |
** |
|
35 |
** |
|
36 |
** |
|
37 |
** |
|
38 |
** $QT_END_LICENSE$ |
|
39 |
** |
|
40 |
****************************************************************************/ |
|
41 |
||
42 |
#include "graphics.h" |
|
43 |
#include "feature.h" |
|
44 |
#include "featuretreemodel.h" |
|
45 |
||
46 |
#include <QtGui> |
|
47 |
||
48 |
QT_BEGIN_NAMESPACE |
|
49 |
||
50 |
static QString defaultPath; |
|
51 |
||
52 |
class FeatureTextBrowser : public QTextBrowser { |
|
53 |
Q_OBJECT |
|
54 |
public: |
|
55 |
FeatureTextBrowser(QWidget *parent) : QTextBrowser(parent) { |
|
56 |
QString docRoot; |
|
57 |
docRoot = QLibraryInfo::location(QLibraryInfo::DocumentationPath) |
|
58 |
+ "/html"; |
|
59 |
setSearchPaths(searchPaths() << docRoot); |
|
60 |
} |
|
61 |
||
62 |
signals: |
|
63 |
void featureClicked(const QString &feature); |
|
64 |
||
65 |
public slots: |
|
66 |
void setSource(const QUrl &url) |
|
67 |
{ |
|
68 |
if (url.scheme() == "feature") |
|
69 |
emit featureClicked(url.authority()); |
|
70 |
else |
|
71 |
QTextBrowser::setSource(url); |
|
72 |
} |
|
73 |
}; |
|
74 |
||
75 |
class Main : public QMainWindow { |
|
76 |
Q_OBJECT |
|
77 |
public: |
|
78 |
Main(); |
|
79 |
~Main(); |
|
80 |
void loadFeatures(const QString& filename); |
|
81 |
void loadConfig(const QString& filename); |
|
82 |
||
83 |
public slots: |
|
84 |
void modelChanged(); |
|
85 |
void showInfo(const QModelIndex &index); |
|
86 |
void showInfo(const QString &feature); |
|
87 |
void openConfig(); |
|
88 |
void saveConfig(); |
|
89 |
void expandView(); |
|
90 |
void collapseView(); |
|
91 |
void about(); |
|
92 |
void aboutQt(); |
|
93 |
void quit(); |
|
94 |
void clear(); |
|
95 |
void enableAll(); |
|
96 |
void disableAll(); |
|
97 |
||
98 |
private: |
|
99 |
QTextBrowser *textBrowser; |
|
100 |
QTreeView *featureTree; |
|
101 |
FeatureTreeModel *featureModel; |
|
102 |
||
103 |
void init(); |
|
104 |
void updateStatus(int numFeatures = -1); |
|
105 |
void completelyExpandIndex(const QModelIndex &parent); |
|
106 |
}; |
|
107 |
||
108 |
template<typename Func> |
|
109 |
void foreachIndex_helper(const QModelIndex &parent, Func func) |
|
110 |
{ |
|
111 |
const QAbstractItemModel *model = parent.model(); |
|
112 |
const int rows = model->rowCount(parent); |
|
113 |
for (int i = 0; i < rows; ++i) { |
|
114 |
const QModelIndex child = model->index(i, 0, parent); |
|
115 |
func(child); |
|
116 |
foreachIndex_helper(child, func); |
|
117 |
} |
|
118 |
} |
|
119 |
||
120 |
template<typename Func> |
|
121 |
void foreachIndex(const QAbstractItemModel *model, Func func) |
|
122 |
{ |
|
123 |
const int rows = model->rowCount(QModelIndex()); |
|
124 |
for (int i = 0; i < rows; ++i) { |
|
125 |
const QModelIndex child = model->index(i, 0, QModelIndex()); |
|
126 |
func(child); |
|
127 |
foreachIndex_helper(child, func); |
|
128 |
} |
|
129 |
} |
|
130 |
||
131 |
struct CheckStateSetter { |
|
132 |
||
133 |
CheckStateSetter(Qt::CheckState state, QAbstractItemModel *m) |
|
134 |
: checkState(state), model(m) {} |
|
135 |
||
136 |
void operator()(const QModelIndex &index) { |
|
137 |
model->setData(index, checkState, Qt::CheckStateRole); |
|
138 |
} |
|
139 |
||
140 |
Qt::CheckState checkState; |
|
141 |
QAbstractItemModel *model; |
|
142 |
}; |
|
143 |
||
144 |
void Main::disableAll() |
|
145 |
{ |
|
146 |
QAbstractItemModel *model = featureTree->model(); |
|
147 |
foreachIndex(model, CheckStateSetter(Qt::Unchecked, model)); |
|
148 |
} |
|
149 |
||
150 |
void Main::enableAll() |
|
151 |
{ |
|
152 |
QAbstractItemModel *model = featureTree->model(); |
|
153 |
foreachIndex(model, CheckStateSetter(Qt::Checked, model)); |
|
154 |
} |
|
155 |
||
156 |
Main::Main() |
|
157 |
{ |
|
158 |
setWindowIcon(QIcon(QPixmap(logo_xpm))); |
|
159 |
||
160 |
QSplitter *splitter = new QSplitter(this); |
|
161 |
||
162 |
featureModel = new FeatureTreeModel(this); |
|
163 |
featureTree = new QTreeView(splitter); |
|
164 |
splitter->addWidget(featureTree); |
|
165 |
featureTree->setRootIsDecorated(true); |
|
166 |
featureTree->setModel(featureModel); |
|
167 |
featureTree->show(); |
|
168 |
||
169 |
textBrowser = new FeatureTextBrowser(splitter); |
|
170 |
textBrowser->setFrameStyle(QFrame::WinPanel|QFrame::Sunken); |
|
171 |
splitter->addWidget(textBrowser); |
|
172 |
textBrowser->show(); |
|
173 |
||
3
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
174 |
connect(textBrowser, SIGNAL(featureClicked(QString)), |
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
175 |
this, SLOT(showInfo(QString))); |
0 | 176 |
connect(featureTree, SIGNAL(activated(QModelIndex)), |
177 |
this, SLOT(showInfo(QModelIndex))); |
|
3
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
178 |
connect(featureModel, SIGNAL(dataChanged(QModelIndex,QModelIndex)), |
0 | 179 |
this, SLOT(modelChanged())); |
180 |
connect(featureTree, SIGNAL(clicked(QModelIndex)), |
|
181 |
this, SLOT(showInfo(QModelIndex))); |
|
182 |
||
183 |
setCentralWidget(splitter); |
|
184 |
||
185 |
QMenu *file = menuBar()->addMenu("&File"); |
|
186 |
file->addAction("&Open...", this, SLOT(openConfig()), |
|
187 |
Qt::CTRL + Qt::Key_O); |
|
188 |
file->addAction("&Save As...", this, SLOT(saveConfig()), |
|
189 |
Qt::CTRL + Qt::Key_S); |
|
190 |
file->addSeparator(); |
|
191 |
file->addAction("&Reset", this, SLOT(clear())); |
|
192 |
file->addSeparator(); |
|
193 |
file->addAction("E&xit", this, SLOT(quit()), Qt::CTRL + Qt::Key_Q); |
|
194 |
||
195 |
QMenu *edit = menuBar()->addMenu("&Tools"); |
|
196 |
edit->addAction("&Enable all features", this, SLOT(enableAll())); |
|
197 |
edit->addAction("&Disable all features", this, SLOT(disableAll())); |
|
198 |
||
199 |
menuBar()->addSeparator(); |
|
200 |
||
201 |
QMenu *help = menuBar()->addMenu("&Help"); |
|
202 |
help->addAction("&About", this, SLOT(about())); |
|
203 |
help->addAction("About &Qt", this, SLOT(aboutQt())); |
|
204 |
||
205 |
QToolBar *tb = new QToolBar("Expand/Collapse features"); |
|
206 |
QToolButton *button; |
|
207 |
||
208 |
button = new QToolButton(tb); |
|
209 |
button->setIcon(QIcon(QPixmap(collapsed_xpm))); |
|
210 |
button->setText("Collapse"); |
|
211 |
button->setToolTip("Collapse"); |
|
212 |
connect(button, SIGNAL(clicked()), this, SLOT(collapseView())); |
|
213 |
tb->addWidget(button); |
|
214 |
||
215 |
button = new QToolButton(tb); |
|
216 |
button->setIcon(QIcon(QPixmap(expanded_xpm))); |
|
217 |
button->setText("Expand"); |
|
218 |
button->setToolTip("Expand"); |
|
219 |
connect(button, SIGNAL(clicked()), this, SLOT(expandView())); |
|
220 |
tb->addWidget(button); |
|
221 |
addToolBar(tb); |
|
222 |
||
223 |
init(); |
|
224 |
} |
|
225 |
||
226 |
Main::~Main() |
|
227 |
{ |
|
228 |
delete textBrowser; |
|
229 |
delete featureModel; |
|
230 |
delete featureTree; |
|
231 |
} |
|
232 |
||
233 |
void Main::clear() |
|
234 |
{ |
|
235 |
QSettings settings; |
|
236 |
settings.clear(); |
|
237 |
featureModel->clear(); |
|
238 |
featureTree->reset(); |
|
239 |
init(); |
|
240 |
} |
|
241 |
||
242 |
void Main::quit() |
|
243 |
{ |
|
244 |
if (isWindowModified()) { |
|
245 |
int button = QMessageBox::question(this, "Quit Program", |
|
246 |
"You have unsaved changes.\n" |
|
247 |
"Do you want to quit anyway?", |
|
248 |
QMessageBox::Yes, |
|
249 |
QMessageBox::No); |
|
250 |
if (static_cast<QMessageBox::Button>(button) != QMessageBox::Yes) |
|
251 |
return; |
|
252 |
} |
|
253 |
QApplication::instance()->quit(); |
|
254 |
} |
|
255 |
||
256 |
/* |
|
257 |
Recursively expand expand \a parent and all of its children. |
|
258 |
*/ |
|
259 |
void Main::completelyExpandIndex(const QModelIndex &parent) |
|
260 |
{ |
|
261 |
featureTree->setExpanded(parent, true); |
|
262 |
||
263 |
const QAbstractItemModel *model = featureTree->model(); |
|
264 |
const int rows = model->rowCount(parent); |
|
265 |
for (int i = 0; i < rows; ++i) |
|
266 |
completelyExpandIndex(model->index(i, 0, parent)); |
|
267 |
} |
|
268 |
||
269 |
void Main::expandView() |
|
270 |
{ |
|
271 |
completelyExpandIndex(QModelIndex()); |
|
272 |
} |
|
273 |
||
274 |
void Main::collapseView() |
|
275 |
{ |
|
276 |
const QAbstractItemModel *model = featureTree->model(); |
|
277 |
const int rows = model->rowCount(QModelIndex()); |
|
278 |
for (int i = 0; i < rows; ++i) { |
|
279 |
QModelIndex index = model->index(i, 0, QModelIndex()); |
|
280 |
featureTree->setExpanded(index, false); |
|
281 |
} |
|
282 |
} |
|
283 |
||
284 |
void Main::updateStatus(int numFeatures) |
|
285 |
{ |
|
286 |
QSettings settings; |
|
287 |
QString featureFile = settings.value("featureFile").toString(); |
|
288 |
QString configFile = settings.value("lastConfig").toString(); |
|
289 |
QString message("Using features from %1"); |
|
290 |
||
291 |
if (numFeatures >= 0) { |
|
292 |
QString s("%1 features loaded from %2"); |
|
293 |
statusBar()->showMessage(s.arg(numFeatures).arg(featureFile)); |
|
294 |
} |
|
295 |
QString appName = QApplication::applicationName(); |
|
296 |
if (configFile.isEmpty()) |
|
297 |
configFile = "New File"; |
|
298 |
setWindowTitle(appName + " - " + configFile + "[*]"); |
|
299 |
} |
|
300 |
||
301 |
void Main::modelChanged() |
|
302 |
{ |
|
303 |
setWindowModified(true); |
|
304 |
} |
|
305 |
||
306 |
void Main::init() |
|
307 |
{ |
|
308 |
QSettings settings; |
|
309 |
QString features = settings.value("featureFile").toString(); |
|
310 |
||
311 |
if (features.isEmpty() || !QFileInfo(features).isFile()) { |
|
312 |
features = QFileDialog::getOpenFileName(this, |
|
313 |
"Open a feature file", |
|
314 |
defaultPath, |
|
315 |
"Qt Features (qfeatures.txt)"); |
|
316 |
} |
|
317 |
settings.setValue("featureFile", features); |
|
318 |
loadFeatures(features); |
|
319 |
||
320 |
expandView(); |
|
321 |
collapseView(); |
|
322 |
||
323 |
QString confFile = settings.value("lastConfig").toString(); |
|
324 |
if (confFile.isEmpty()) |
|
325 |
return; |
|
326 |
loadConfig(confFile); |
|
327 |
} |
|
328 |
||
329 |
void Main::openConfig() |
|
330 |
{ |
|
331 |
QSettings settings; |
|
332 |
QString configDir; |
|
333 |
||
334 |
QString prevFile = settings.value("lastConfig").toString(); |
|
335 |
if (!prevFile.isEmpty()) |
|
336 |
configDir = QFileInfo(prevFile).path(); |
|
337 |
||
338 |
if (configDir.isEmpty()) |
|
339 |
configDir = defaultPath; |
|
340 |
||
341 |
QString configFile; |
|
342 |
configFile = QFileDialog::getOpenFileName(this, |
|
343 |
"Open a configuration file", |
|
344 |
configDir, |
|
345 |
"Header files (*.h)"); |
|
346 |
enableAll(); |
|
347 |
if (!configFile.isEmpty()) |
|
348 |
loadConfig(configFile); |
|
349 |
settings.setValue("lastConfig", QFileInfo(configFile).absoluteFilePath()); |
|
350 |
} |
|
351 |
||
352 |
void Main::saveConfig() |
|
353 |
{ |
|
354 |
QSettings settings; |
|
355 |
QString configDir; |
|
356 |
||
357 |
QString prevFile = settings.value("lastConfig").toString(); |
|
358 |
if (!prevFile.isEmpty()) |
|
359 |
configDir = QFileInfo(prevFile).path(); |
|
360 |
||
361 |
if (configDir.isEmpty()) |
|
362 |
configDir = defaultPath; |
|
363 |
||
364 |
QString configFile; |
|
365 |
configFile = QFileDialog::getSaveFileName(this, |
|
366 |
"Save configuration file", |
|
367 |
configDir, |
|
368 |
"Header files (*.h)"); |
|
369 |
if (configFile.isEmpty()) |
|
370 |
return; |
|
371 |
||
372 |
QFile file(configFile); |
|
373 |
if (!file.open(QIODevice::WriteOnly)) { |
|
374 |
QMessageBox::warning(this,"Warning", |
|
375 |
"Cannot write to file " + configFile); |
|
376 |
return; |
|
377 |
} |
|
378 |
||
379 |
QTextStream stream(&file); |
|
380 |
FeatureTreeModel *model; |
|
381 |
model = static_cast<FeatureTreeModel*>(featureTree->model()); |
|
382 |
model->writeConfig(stream); |
|
383 |
||
384 |
settings.setValue("lastConfig", QFileInfo(configFile).absoluteFilePath()); |
|
385 |
setWindowModified(false); |
|
386 |
updateStatus(); |
|
387 |
} |
|
388 |
||
389 |
void Main::loadConfig(const QString &filename) |
|
390 |
{ |
|
391 |
if (!QFileInfo(filename).isFile()) |
|
392 |
return; |
|
393 |
||
394 |
QFile file(filename); |
|
395 |
if (!file.open(QIODevice::ReadOnly)) { |
|
396 |
QMessageBox::warning(this,"Warning", "Cannot open file " + filename); |
|
397 |
return; |
|
398 |
} |
|
399 |
||
400 |
QTextStream stream(&file); |
|
401 |
FeatureTreeModel *model; |
|
402 |
model = static_cast<FeatureTreeModel*>(featureTree->model()); |
|
403 |
model->readConfig(stream); |
|
404 |
||
405 |
QSettings settings; |
|
406 |
settings.setValue("lastConfig", QFileInfo(filename).absoluteFilePath()); |
|
407 |
setWindowModified(false); |
|
408 |
updateStatus(); |
|
409 |
} |
|
410 |
||
411 |
void Main::loadFeatures(const QString &filename) |
|
412 |
{ |
|
413 |
Feature::clear(); |
|
414 |
||
415 |
QFile file(filename); |
|
416 |
if (!file.open(QIODevice::ReadOnly)) { |
|
417 |
QMessageBox::warning(this,"Warning", "Cannot open file " + filename); |
|
418 |
return; |
|
419 |
} |
|
420 |
||
421 |
Feature *feature = 0; |
|
422 |
int numFeatures = 0; |
|
423 |
updateStatus(numFeatures); |
|
424 |
QTextStream s(&file); |
|
425 |
for (QString line = s.readLine(); !s.atEnd(); line = s.readLine()) { |
|
426 |
line = line.simplified(); |
|
427 |
if (line.isEmpty()) |
|
428 |
continue; |
|
429 |
if (line.startsWith('#')) |
|
430 |
continue; |
|
431 |
||
432 |
int colon = line.indexOf(':'); |
|
433 |
if (colon < 0) { // assume description |
|
434 |
QString description = feature->description().simplified(); |
|
435 |
description += " " + line; |
|
436 |
feature->setDescription(description); |
|
437 |
continue; |
|
438 |
} |
|
439 |
||
440 |
QString tag = line.left(colon); |
|
441 |
QString value = line.mid(colon+1).simplified(); |
|
442 |
if (tag == "Feature") { |
|
443 |
if (feature) |
|
444 |
featureModel->addFeature(feature); |
|
445 |
feature = Feature::getInstance(value); |
|
446 |
updateStatus(++numFeatures); |
|
447 |
} else if (tag == "Requires") { |
|
448 |
Q_ASSERT(feature); |
|
449 |
feature->setDependencies(value.split(' ', QString::SkipEmptyParts)); |
|
450 |
} else if (tag == "Name") { |
|
451 |
Q_ASSERT(feature); |
|
452 |
feature->setTitle(value); |
|
453 |
} else if (tag == "Section") { |
|
454 |
Q_ASSERT(feature); |
|
455 |
feature->setSection(value); |
|
456 |
} else if (tag == "SeeAlso") { |
|
457 |
Q_ASSERT(feature); |
|
458 |
feature->setRelations(value.split(' ', QString::SkipEmptyParts)); |
|
459 |
} else if (tag == "Description") { |
|
460 |
Q_ASSERT(feature); |
|
461 |
feature->setDescription(value); |
|
462 |
} |
|
463 |
} |
|
464 |
if (feature) |
|
465 |
featureModel->addFeature(feature); |
|
466 |
||
467 |
featureTree->resizeColumnToContents(0); |
|
468 |
||
469 |
QSettings settings; |
|
470 |
settings.setValue("featureFile", QFileInfo(filename).absoluteFilePath()); |
|
471 |
||
472 |
updateStatus(); |
|
473 |
} |
|
474 |
||
475 |
void Main::showInfo(const QModelIndex &index) |
|
476 |
{ |
|
477 |
FeatureTreeModel *model; |
|
478 |
model = static_cast<FeatureTreeModel*>(featureTree->model()); |
|
479 |
||
480 |
if (const Feature *feature = model->getFeature(index)) |
|
481 |
textBrowser->setHtml(feature->toHtml()); |
|
482 |
||
483 |
// Ensure index is visible |
|
484 |
QModelIndex parent = model->parent(index); |
|
485 |
while (parent.isValid()) { |
|
486 |
featureTree->setExpanded(parent, true); |
|
487 |
parent = model->parent(parent); |
|
488 |
} |
|
489 |
||
490 |
featureTree->scrollTo(index); |
|
491 |
featureTree->setCurrentIndex(index); |
|
492 |
} |
|
493 |
||
494 |
void Main::showInfo(const QString &feature) |
|
495 |
{ |
|
496 |
const Feature *f = Feature::getInstance(feature); |
|
497 |
FeatureTreeModel *model; |
|
498 |
model = static_cast<FeatureTreeModel*>(featureTree->model()); |
|
499 |
showInfo(model->index(f)); |
|
500 |
} |
|
501 |
||
502 |
void Main::about() |
|
503 |
{ |
|
504 |
QMessageBox::about(this, "About qconfig", |
|
505 |
"<p><b><font size=\"+2\">Qtopia Core build configuration</font></b></p>" |
|
506 |
"<p></p>" |
|
507 |
"<p>Version 2.0</p>" |
|
4
3b1da2848fc7
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
3
diff
changeset
|
508 |
"<p>Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).</p>" |
0 | 509 |
"<p></p>" |
510 |
); |
|
511 |
} |
|
512 |
||
513 |
void Main::aboutQt() |
|
514 |
{ |
|
515 |
QMessageBox::aboutQt( this, tr("qconfig") ); |
|
516 |
} |
|
517 |
||
518 |
QT_END_NAMESPACE |
|
519 |
||
520 |
int main(int argc, char** argv) |
|
521 |
{ |
|
522 |
QT_USE_NAMESPACE |
|
523 |
QApplication app(argc,argv); |
|
524 |
app.setOrganizationDomain("trolltech.com"); |
|
525 |
app.setOrganizationName("Trolltech"); |
|
526 |
app.setApplicationName("QConfig"); |
|
527 |
Main m; |
|
528 |
||
529 |
defaultPath = QLibraryInfo::location(QLibraryInfo::PrefixPath) |
|
530 |
+ "/src/corelib/global"; |
|
531 |
||
532 |
for (int i = 1; i < argc; ++i) { |
|
533 |
QString arg = argv[i]; |
|
534 |
if (arg == "-f" && i+1 < argc) |
|
535 |
m.loadFeatures(argv[++i]); |
|
536 |
else if (arg == "-c" && i+1 < argc) |
|
537 |
m.loadConfig(argv[++i]); |
|
538 |
} |
|
539 |
m.resize(m.sizeHint() + QSize(500,300)); |
|
540 |
m.show(); |
|
541 |
return app.exec(); |
|
542 |
} |
|
543 |
||
544 |
#include "main.moc" |