source: trunk/examples/tools/plugandpaint/mainwindow.cpp@ 857

Last change on this file since 857 was 846, checked in by Dmitry A. Kuminov, 14 years ago

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

File size: 9.6 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation ([email protected])
6**
7** This file is part of the examples of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:BSD$
10** You may use this file under the terms of the BSD license as follows:
11**
12** "Redistribution and use in source and binary forms, with or without
13** modification, are permitted provided that the following conditions are
14** met:
15** * Redistributions of source code must retain the above copyright
16** notice, this list of conditions and the following disclaimer.
17** * Redistributions in binary form must reproduce the above copyright
18** notice, this list of conditions and the following disclaimer in
19** the documentation and/or other materials provided with the
20** distribution.
21** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
22** the names of its contributors may be used to endorse or promote
23** products derived from this software without specific prior written
24** permission.
25**
26** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
27** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
28** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
29** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
30** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
31** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
32** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
33** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
34** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
35** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
36** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
37** $QT_END_LICENSE$
38**
39****************************************************************************/
40
41
42#include "interfaces.h"
43#include "mainwindow.h"
44#include "paintarea.h"
45#include "plugindialog.h"
46
47#include <QPluginLoader>
48#include <QTimer>
49
50#include <QScrollArea>
51#include <QMessageBox>
52#include <QActionGroup>
53#include <QAction>
54#include <QMenu>
55#include <QMenuBar>
56#include <QFileDialog>
57#include <QColorDialog>
58#include <QInputDialog>
59#include <QApplication>
60
61MainWindow::MainWindow() :
62 paintArea(new PaintArea),
63 scrollArea(new QScrollArea)
64{
65 scrollArea->setBackgroundRole(QPalette::Dark);
66 scrollArea->setWidget(paintArea);
67 setCentralWidget(scrollArea);
68
69 createActions();
70 createMenus();
71 loadPlugins();
72
73 setWindowTitle(tr("Plug & Paint"));
74
75 if (!brushActionGroup->actions().isEmpty())
76 brushActionGroup->actions().first()->trigger();
77
78 QTimer::singleShot(500, this, SLOT(aboutPlugins()));
79}
80
81void MainWindow::open()
82{
83 const QString fileName = QFileDialog::getOpenFileName(this,
84 tr("Open File"),
85 QDir::currentPath());
86 if (!fileName.isEmpty()) {
87 if (!paintArea->openImage(fileName)) {
88 QMessageBox::information(this, tr("Plug & Paint"),
89 tr("Cannot load %1.").arg(fileName));
90 return;
91 }
92 paintArea->adjustSize();
93 }
94}
95
96bool MainWindow::saveAs()
97{
98 const QString initialPath = QDir::currentPath() + "/untitled.png";
99
100 const QString fileName = QFileDialog::getSaveFileName(this, tr("Save As"),
101 initialPath);
102 if (fileName.isEmpty()) {
103 return false;
104 } else {
105 return paintArea->saveImage(fileName, "png");
106 }
107}
108
109void MainWindow::brushColor()
110{
111 const QColor newColor = QColorDialog::getColor(paintArea->brushColor());
112 if (newColor.isValid())
113 paintArea->setBrushColor(newColor);
114}
115
116void MainWindow::brushWidth()
117{
118 bool ok;
119 const int newWidth = QInputDialog::getInteger(this, tr("Plug & Paint"),
120 tr("Select brush width:"),
121 paintArea->brushWidth(),
122 1, 50, 1, &ok);
123 if (ok)
124 paintArea->setBrushWidth(newWidth);
125}
126
127//! [0]
128void MainWindow::changeBrush()
129{
130 QAction *action = qobject_cast<QAction *>(sender());
131 BrushInterface *iBrush = qobject_cast<BrushInterface *>(action->parent());
132 const QString brush = action->text();
133
134 paintArea->setBrush(iBrush, brush);
135}
136//! [0]
137
138//! [1]
139void MainWindow::insertShape()
140{
141 QAction *action = qobject_cast<QAction *>(sender());
142 ShapeInterface *iShape = qobject_cast<ShapeInterface *>(action->parent());
143
144 const QPainterPath path = iShape->generateShape(action->text(), this);
145 if (!path.isEmpty())
146 paintArea->insertShape(path);
147}
148//! [1]
149
150//! [2]
151void MainWindow::applyFilter()
152{
153 QAction *action = qobject_cast<QAction *>(sender());
154 FilterInterface *iFilter =
155 qobject_cast<FilterInterface *>(action->parent());
156
157 const QImage image = iFilter->filterImage(action->text(), paintArea->image(),
158 this);
159 paintArea->setImage(image);
160}
161//! [2]
162
163void MainWindow::about()
164{
165 QMessageBox::about(this, tr("About Plug & Paint"),
166 tr("The <b>Plug & Paint</b> example demonstrates how to write Qt "
167 "applications that can be extended through plugins."));
168}
169
170//! [3]
171void MainWindow::aboutPlugins()
172{
173 PluginDialog dialog(pluginsDir.path(), pluginFileNames, this);
174 dialog.exec();
175}
176//! [3]
177
178void MainWindow::createActions()
179{
180 openAct = new QAction(tr("&Open..."), this);
181 openAct->setShortcuts(QKeySequence::Open);
182 connect(openAct, SIGNAL(triggered()), this, SLOT(open()));
183
184 saveAsAct = new QAction(tr("&Save As..."), this);
185 saveAsAct->setShortcuts(QKeySequence::SaveAs);
186 connect(saveAsAct, SIGNAL(triggered()), this, SLOT(saveAs()));
187
188 exitAct = new QAction(tr("E&xit"), this);
189 exitAct->setShortcuts(QKeySequence::Quit);
190 connect(exitAct, SIGNAL(triggered()), this, SLOT(close()));
191
192 brushColorAct = new QAction(tr("&Brush Color..."), this);
193 connect(brushColorAct, SIGNAL(triggered()), this, SLOT(brushColor()));
194
195 brushWidthAct = new QAction(tr("&Brush Width..."), this);
196 connect(brushWidthAct, SIGNAL(triggered()), this, SLOT(brushWidth()));
197
198 brushActionGroup = new QActionGroup(this);
199
200 aboutAct = new QAction(tr("&About"), this);
201 connect(aboutAct, SIGNAL(triggered()), this, SLOT(about()));
202
203 aboutQtAct = new QAction(tr("About &Qt"), this);
204 connect(aboutQtAct, SIGNAL(triggered()), qApp, SLOT(aboutQt()));
205
206 aboutPluginsAct = new QAction(tr("About &Plugins"), this);
207 connect(aboutPluginsAct, SIGNAL(triggered()), this, SLOT(aboutPlugins()));
208}
209
210void MainWindow::createMenus()
211{
212 fileMenu = menuBar()->addMenu(tr("&File"));
213 fileMenu->addAction(openAct);
214 fileMenu->addAction(saveAsAct);
215 fileMenu->addSeparator();
216 fileMenu->addAction(exitAct);
217
218 brushMenu = menuBar()->addMenu(tr("&Brush"));
219 brushMenu->addAction(brushColorAct);
220 brushMenu->addAction(brushWidthAct);
221 brushMenu->addSeparator();
222
223 shapesMenu = menuBar()->addMenu(tr("&Shapes"));
224
225 filterMenu = menuBar()->addMenu(tr("&Filter"));
226
227 menuBar()->addSeparator();
228
229 helpMenu = menuBar()->addMenu(tr("&Help"));
230 helpMenu->addAction(aboutAct);
231 helpMenu->addAction(aboutQtAct);
232 helpMenu->addAction(aboutPluginsAct);
233}
234
235//! [4]
236void MainWindow::loadPlugins()
237{
238 foreach (QObject *plugin, QPluginLoader::staticInstances())
239 populateMenus(plugin);
240//! [4] //! [5]
241
242 pluginsDir = QDir(qApp->applicationDirPath());
243
244#if defined(Q_OS_WIN)
245 if (pluginsDir.dirName().toLower() == "debug" || pluginsDir.dirName().toLower() == "release")
246 pluginsDir.cdUp();
247#elif defined(Q_OS_MAC)
248 if (pluginsDir.dirName() == "MacOS") {
249 pluginsDir.cdUp();
250 pluginsDir.cdUp();
251 pluginsDir.cdUp();
252 }
253#endif
254 pluginsDir.cd("plugins");
255//! [5]
256
257//! [6]
258 foreach (QString fileName, pluginsDir.entryList(QDir::Files)) {
259 QPluginLoader loader(pluginsDir.absoluteFilePath(fileName));
260 QObject *plugin = loader.instance();
261 if (plugin) {
262 populateMenus(plugin);
263 pluginFileNames += fileName;
264//! [6] //! [7]
265 }
266//! [7] //! [8]
267 }
268//! [8]
269
270//! [9]
271 brushMenu->setEnabled(!brushActionGroup->actions().isEmpty());
272 shapesMenu->setEnabled(!shapesMenu->actions().isEmpty());
273 filterMenu->setEnabled(!filterMenu->actions().isEmpty());
274}
275//! [9]
276
277//! [10]
278void MainWindow::populateMenus(QObject *plugin)
279{
280 BrushInterface *iBrush = qobject_cast<BrushInterface *>(plugin);
281 if (iBrush)
282 addToMenu(plugin, iBrush->brushes(), brushMenu, SLOT(changeBrush()),
283 brushActionGroup);
284
285 ShapeInterface *iShape = qobject_cast<ShapeInterface *>(plugin);
286 if (iShape)
287 addToMenu(plugin, iShape->shapes(), shapesMenu, SLOT(insertShape()));
288
289 FilterInterface *iFilter = qobject_cast<FilterInterface *>(plugin);
290 if (iFilter)
291 addToMenu(plugin, iFilter->filters(), filterMenu, SLOT(applyFilter()));
292}
293//! [10]
294
295void MainWindow::addToMenu(QObject *plugin, const QStringList &texts,
296 QMenu *menu, const char *member,
297 QActionGroup *actionGroup)
298{
299 foreach (QString text, texts) {
300 QAction *action = new QAction(text, plugin);
301 connect(action, SIGNAL(triggered()), this, member);
302 menu->addAction(action);
303
304 if (actionGroup) {
305 action->setCheckable(true);
306 actionGroup->addAction(action);
307 }
308 }
309}
Note: See TracBrowser for help on using the repository browser.