1 /****************************************************************************
3 ** Copyright (C) 2015 The Qt Company Ltd.
4 ** Contact: http://www.qt.io/licensing/
6 ** This file is part of the demonstration applications of the Qt Toolkit.
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see http://www.qt.io/terms-conditions. For further
15 ** information use the contact form at http://www.qt.io/contact-us.
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 or version 3 as published by the Free
20 ** Software Foundation and appearing in the file LICENSE.LGPLv21 and
21 ** LICENSE.LGPLv3 included in the packaging of this file. Please review the
22 ** following information to ensure the GNU Lesser General Public License
23 ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
24 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
26 ** As a special exception, The Qt Company gives you certain additional
27 ** rights. These rights are described in The Qt Company LGPL Exception
28 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
30 ** GNU General Public License Usage
31 ** Alternatively, this file may be used under the terms of the GNU
32 ** General Public License version 3.0 as published by the Free Software
33 ** Foundation and appearing in the file LICENSE.GPL included in the
34 ** packaging of this file. Please review the following information to
35 ** ensure the GNU General Public License version 3.0 requirements will be
36 ** met: http://www.gnu.org/copyleft/gpl.html.
40 ****************************************************************************/
42 #include <QXmlStreamReader>
44 #include "fluidlauncher.h"
47 #define DEFAULT_INPUT_TIMEOUT 10000
48 #define SIZING_FACTOR_HEIGHT 6/10
49 #define SIZING_FACTOR_WIDTH 6/10
51 FluidLauncher::FluidLauncher(QStringList* args)
53 pictureFlowWidget = new PictureFlow();
54 slideShowWidget = new SlideShow();
55 inputTimer = new QTimer();
57 addWidget(pictureFlowWidget);
58 addWidget(slideShowWidget);
59 setCurrentWidget(pictureFlowWidget);
60 pictureFlowWidget->setFocus();
62 QRect screen_size = QApplication::desktop()->screenGeometry();
64 QObject::connect(pictureFlowWidget, SIGNAL(itemActivated(int)), this, SLOT(launchApplication(int)));
65 QObject::connect(pictureFlowWidget, SIGNAL(inputReceived()), this, SLOT(resetInputTimeout()));
66 QObject::connect(slideShowWidget, SIGNAL(inputReceived()), this, SLOT(switchToLauncher()));
67 QObject::connect(inputTimer, SIGNAL(timeout()), this, SLOT(inputTimedout()));
69 inputTimer->setSingleShot(true);
70 inputTimer->setInterval(DEFAULT_INPUT_TIMEOUT);
72 const int h = screen_size.height() * SIZING_FACTOR_HEIGHT;
73 const int w = screen_size.width() * SIZING_FACTOR_WIDTH;
74 const int hh = qMin(h, w);
75 const int ww = hh / 3 * 2;
76 pictureFlowWidget->setSlideSize(QSize(ww, hh));
79 int configIndex = args->indexOf("-config");
80 if ( (configIndex != -1) && (configIndex != args->count()-1) )
81 success = loadConfig(args->at(configIndex+1));
83 success = loadConfig("config.xml");
86 populatePictureFlow();
91 pictureFlowWidget->setAttribute(Qt::WA_DeleteOnClose, true);
92 pictureFlowWidget->close();
97 FluidLauncher::~FluidLauncher()
99 delete pictureFlowWidget;
100 delete slideShowWidget;
103 bool FluidLauncher::loadConfig(QString configPath)
105 QFile xmlFile(configPath);
107 if (!xmlFile.exists() || (xmlFile.error() != QFile::NoError)) {
108 qDebug() << "ERROR: Unable to open config file " << configPath;
112 slideShowWidget->clearImages();
114 xmlFile.open(QIODevice::ReadOnly);
115 QXmlStreamReader reader(&xmlFile);
116 while (!reader.atEnd()) {
119 if (reader.isStartElement()) {
120 if (reader.name() == "demos")
122 else if(reader.name() == "slideshow")
123 parseSlideshow(reader);
127 if (reader.hasError()) {
128 qDebug() << QString("Error parsing %1 on line %2 column %3: \n%4")
130 .arg(reader.lineNumber())
131 .arg(reader.columnNumber())
132 .arg(reader.errorString());
135 // Append an exit Item
136 DemoApplication* exitItem = new DemoApplication(QString(), QLatin1String("Exit Embedded Demo"), QString(), QStringList());
137 demoList.append(exitItem);
143 void FluidLauncher::parseDemos(QXmlStreamReader& reader)
145 while (!reader.atEnd()) {
147 if (reader.isStartElement() && reader.name() == "example") {
148 QXmlStreamAttributes attrs = reader.attributes();
149 QStringRef filename = attrs.value("filename");
150 if (!filename.isEmpty()) {
151 QStringRef name = attrs.value("name");
152 QStringRef image = attrs.value("image");
153 QStringRef args = attrs.value("args");
155 DemoApplication* newDemo = new DemoApplication(
157 name.isEmpty() ? "Unnamed Demo" : name.toString(),
159 args.toString().split(" "));
160 demoList.append(newDemo);
162 } else if(reader.isEndElement() && reader.name() == "demos") {
168 void FluidLauncher::parseSlideshow(QXmlStreamReader& reader)
170 QXmlStreamAttributes attrs = reader.attributes();
172 QStringRef timeout = attrs.value("timeout");
174 if (!timeout.isEmpty()) {
175 int t = timeout.toString().toInt(&valid);
177 inputTimer->setInterval(t);
180 QStringRef interval = attrs.value("interval");
181 if (!interval.isEmpty()) {
182 int i = interval.toString().toInt(&valid);
184 slideShowWidget->setSlideInterval(i);
187 while (!reader.atEnd()) {
189 if (reader.isStartElement()) {
190 QXmlStreamAttributes attrs = reader.attributes();
191 if (reader.name() == "imagedir") {
192 QStringRef dir = attrs.value("dir");
193 slideShowWidget->addImageDir(dir.toString());
194 } else if(reader.name() == "image") {
195 QStringRef image = attrs.value("image");
196 slideShowWidget->addImage(image.toString());
198 } else if(reader.isEndElement() && reader.name() == "slideshow") {
205 void FluidLauncher::populatePictureFlow()
207 pictureFlowWidget->setSlideCount(demoList.count());
209 for (int i=demoList.count()-1; i>=0; --i) {
210 pictureFlowWidget->setSlide(i, *(demoList[i]->getImage()));
211 pictureFlowWidget->setSlideCaption(i, demoList[i]->getCaption());
214 pictureFlowWidget->setCurrentSlide(demoList.count()/2);
218 void FluidLauncher::launchApplication(int index)
220 // NOTE: Clearing the caches will free up more memory for the demo but will cause
221 // a delay upon returning, as items are reloaded.
222 //pictureFlowWidget->clearCaches();
224 if (index == demoList.size() -1) {
231 QObject::connect(demoList[index], SIGNAL(demoFinished()), this, SLOT(demoFinished()));
233 demoList[index]->launch();
237 void FluidLauncher::switchToLauncher()
239 slideShowWidget->stopShow();
241 setCurrentWidget(pictureFlowWidget);
245 void FluidLauncher::resetInputTimeout()
247 if (inputTimer->isActive())
251 void FluidLauncher::inputTimedout()
257 void FluidLauncher::switchToSlideshow()
260 slideShowWidget->startShow();
261 setCurrentWidget(slideShowWidget);
264 void FluidLauncher::demoFinished()
266 setCurrentWidget(pictureFlowWidget);
269 // Bring the Fluidlauncher to the foreground to allow selecting another demo
274 void FluidLauncher::changeEvent(QEvent* event)
276 if (event->type() == QEvent::ActivationChange) {
277 if (isActiveWindow()) {
278 if(currentWidget() == pictureFlowWidget) {
281 slideShowWidget->startShow();
285 slideShowWidget->stopShow();
288 QStackedWidget::changeEvent(event);