Qt Reference Documentation

fluidlauncher.cpp Example File

demos/embedded/fluidlauncher/fluidlauncher.cpp
 /****************************************************************************
 **
 ** Copyright (C) 2015 The Qt Company Ltd.
 ** Contact: http://www.qt.io/licensing/
 **
 ** This file is part of the demonstration applications of the Qt Toolkit.
 **
 ** $QT_BEGIN_LICENSE:LGPL$
 ** Commercial License Usage
 ** Licensees holding valid commercial Qt licenses may use this file in
 ** accordance with the commercial license agreement provided with the
 ** Software or, alternatively, in accordance with the terms contained in
 ** a written agreement between you and The Qt Company. For licensing terms
 ** and conditions see http://www.qt.io/terms-conditions. For further
 ** information use the contact form at http://www.qt.io/contact-us.
 **
 ** GNU Lesser General Public License Usage
 ** Alternatively, this file may be used under the terms of the GNU Lesser
 ** General Public License version 2.1 or version 3 as published by the Free
 ** Software Foundation and appearing in the file LICENSE.LGPLv21 and
 ** LICENSE.LGPLv3 included in the packaging of this file. Please review the
 ** following information to ensure the GNU Lesser General Public License
 ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
 **
 ** As a special exception, The Qt Company gives you certain additional
 ** rights. These rights are described in The Qt Company LGPL Exception
 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
 **
 ** GNU General Public License Usage
 ** Alternatively, this file may be used under the terms of the GNU
 ** General Public License version 3.0 as published by the Free Software
 ** Foundation and appearing in the file LICENSE.GPL included in the
 ** packaging of this file.  Please review the following information to
 ** ensure the GNU General Public License version 3.0 requirements will be
 ** met: http://www.gnu.org/copyleft/gpl.html.
 **
 ** $QT_END_LICENSE$
 **
 ****************************************************************************/

 #include <QXmlStreamReader>

 #include "fluidlauncher.h"

 #define DEFAULT_INPUT_TIMEOUT 10000
 #define SIZING_FACTOR_HEIGHT 6/10
 #define SIZING_FACTOR_WIDTH 6/10

 FluidLauncher::FluidLauncher(QStringList* args)
 {
     pictureFlowWidget = new PictureFlow();
     slideShowWidget = new SlideShow();
     inputTimer = new QTimer();

     addWidget(pictureFlowWidget);
     addWidget(slideShowWidget);
     setCurrentWidget(pictureFlowWidget);
     pictureFlowWidget->setFocus();

     QRect screen_size = QApplication::desktop()->screenGeometry();

     QObject::connect(pictureFlowWidget, SIGNAL(itemActivated(int)), this, SLOT(launchApplication(int)));
     QObject::connect(pictureFlowWidget, SIGNAL(inputReceived()),    this, SLOT(resetInputTimeout()));
     QObject::connect(slideShowWidget,   SIGNAL(inputReceived()),    this, SLOT(switchToLauncher()));
     QObject::connect(inputTimer,        SIGNAL(timeout()),          this, SLOT(inputTimedout()));

     inputTimer->setSingleShot(true);
     inputTimer->setInterval(DEFAULT_INPUT_TIMEOUT);

     const int h = screen_size.height() * SIZING_FACTOR_HEIGHT;
     const int w = screen_size.width() * SIZING_FACTOR_WIDTH;
     const int hh = qMin(h, w);
     const int ww = hh / 3 * 2;
     pictureFlowWidget->setSlideSize(QSize(ww, hh));

     bool success;
     int configIndex = args->indexOf("-config");
     if ( (configIndex != -1) && (configIndex != args->count()-1) )
         success = loadConfig(args->at(configIndex+1));
     else
         success = loadConfig("config.xml");

     if (success) {
       populatePictureFlow();

       showFullScreen();
       inputTimer->start();
     } else {
         pictureFlowWidget->setAttribute(Qt::WA_DeleteOnClose, true);
         pictureFlowWidget->close();
     }

 }

 FluidLauncher::~FluidLauncher()
 {
     delete pictureFlowWidget;
     delete slideShowWidget;
 }

 bool FluidLauncher::loadConfig(QString configPath)
 {
     QFile xmlFile(configPath);

     if (!xmlFile.exists() || (xmlFile.error() != QFile::NoError)) {
         qDebug() << "ERROR: Unable to open config file " << configPath;
         return false;
     }

     slideShowWidget->clearImages();

     xmlFile.open(QIODevice::ReadOnly);
     QXmlStreamReader reader(&xmlFile);
     while (!reader.atEnd()) {
         reader.readNext();

         if (reader.isStartElement()) {
             if (reader.name() == "demos")
                 parseDemos(reader);
             else if(reader.name() == "slideshow")
                 parseSlideshow(reader);
         }
     }

     if (reader.hasError()) {
        qDebug() << QString("Error parsing %1 on line %2 column %3: \n%4")
                 .arg(configPath)
                 .arg(reader.lineNumber())
                 .arg(reader.columnNumber())
                 .arg(reader.errorString());
     }

     // Append an exit Item
     DemoApplication* exitItem = new DemoApplication(QString(), QLatin1String("Exit Embedded Demo"), QString(), QStringList());
     demoList.append(exitItem);

     return true;
 }

 void FluidLauncher::parseDemos(QXmlStreamReader& reader)
 {
     while (!reader.atEnd()) {
         reader.readNext();
         if (reader.isStartElement() && reader.name() == "example") {
             QXmlStreamAttributes attrs = reader.attributes();
             QStringRef filename = attrs.value("filename");
             if (!filename.isEmpty()) {
                 QStringRef name = attrs.value("name");
                 QStringRef image = attrs.value("image");
                 QStringRef args = attrs.value("args");

                 DemoApplication* newDemo = new DemoApplication(
                         filename.toString(),
                         name.isEmpty() ? "Unnamed Demo" : name.toString(),
                         image.toString(),
                         args.toString().split(" "));
                 demoList.append(newDemo);
             }
         } else if(reader.isEndElement() && reader.name() == "demos") {
             return;
         }
     }
 }

 void FluidLauncher::parseSlideshow(QXmlStreamReader& reader)
 {
     QXmlStreamAttributes attrs = reader.attributes();

     QStringRef timeout = attrs.value("timeout");
     bool valid;
     if (!timeout.isEmpty()) {
         int t = timeout.toString().toInt(&valid);
         if (valid)
             inputTimer->setInterval(t);
     }

     QStringRef interval = attrs.value("interval");
     if (!interval.isEmpty()) {
         int i = interval.toString().toInt(&valid);
         if (valid)
             slideShowWidget->setSlideInterval(i);
     }

     while (!reader.atEnd()) {
         reader.readNext();
         if (reader.isStartElement()) {
             QXmlStreamAttributes attrs = reader.attributes();
             if (reader.name() == "imagedir") {
                 QStringRef dir = attrs.value("dir");
                 slideShowWidget->addImageDir(dir.toString());
             } else if(reader.name() == "image") {
                 QStringRef image = attrs.value("image");
                 slideShowWidget->addImage(image.toString());
             }
         } else if(reader.isEndElement() && reader.name() == "slideshow") {
             return;
         }
     }

 }

 void FluidLauncher::populatePictureFlow()
 {
     pictureFlowWidget->setSlideCount(demoList.count());

     for (int i=demoList.count()-1; i>=0; --i) {
         pictureFlowWidget->setSlide(i, *(demoList[i]->getImage()));
         pictureFlowWidget->setSlideCaption(i, demoList[i]->getCaption());
     }

     pictureFlowWidget->setCurrentSlide(demoList.count()/2);
 }

 void FluidLauncher::launchApplication(int index)
 {
     // NOTE: Clearing the caches will free up more memory for the demo but will cause
     // a delay upon returning, as items are reloaded.
     //pictureFlowWidget->clearCaches();

     if (index == demoList.size() -1) {
         qApp->quit();
         return;
     }

     inputTimer->stop();

     QObject::connect(demoList[index], SIGNAL(demoFinished()), this, SLOT(demoFinished()));

     demoList[index]->launch();
 }

 void FluidLauncher::switchToLauncher()
 {
     slideShowWidget->stopShow();
     inputTimer->start();
     setCurrentWidget(pictureFlowWidget);
 }

 void FluidLauncher::resetInputTimeout()
 {
     if (inputTimer->isActive())
         inputTimer->start();
 }

 void FluidLauncher::inputTimedout()
 {
     switchToSlideshow();
 }

 void FluidLauncher::switchToSlideshow()
 {
     inputTimer->stop();
     slideShowWidget->startShow();
     setCurrentWidget(slideShowWidget);
 }

 void FluidLauncher::demoFinished()
 {
     setCurrentWidget(pictureFlowWidget);
     inputTimer->start();

     // Bring the Fluidlauncher to the foreground to allow selecting another demo
     raise();
     activateWindow();
 }

 void FluidLauncher::changeEvent(QEvent* event)
 {
     if (event->type() == QEvent::ActivationChange) {
         if (isActiveWindow()) {
             if(currentWidget() == pictureFlowWidget) {
                 resetInputTimeout();
             } else {
                 slideShowWidget->startShow();
             }
         } else {
             inputTimer->stop();
             slideShowWidget->stopShow();
         }
     }
     QStackedWidget::changeEvent(event);
 }