Home · All Classes · Main Classes · Grouped Classes · Modules · Functions

launcher.cpp Example File
tools/qtdemo/launcher.cpp

 /****************************************************************************
 **
 ** Copyright (C) 2005-2007 Trolltech ASA. All rights reserved.
 **
 ** This file is part of the example classes of the Qt Toolkit.
 **
 ** This file may be used under the terms of the GNU General Public
 ** License version 2.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 GNU
 ** General Public Licensing requirements will be met:
 ** http://www.trolltech.com/products/qt/opensource.html
 **
 ** If you are unsure which license is appropriate for your use, please
 ** review the following information:
 ** http://www.trolltech.com/products/qt/licensing.html or contact the
 ** sales department at [email protected].
 **
 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 **
 ****************************************************************************/

 #include <QtGui>
 #include <QDomDocument>
 #include <QtAssistant/QAssistantClient>

 #include "displayshape.h"
 #include "displaywidget.h"
 #include "launcher.h"

 Launcher::Launcher(QWidget *parent)
     : QMainWindow(parent)
 {
     titleFont = font();
     titleFont.setWeight(QFont::Bold);
     buttonFont = font();
     fontRatio = 0.8;
     documentFont = font();
     inFullScreenResize = false;
     currentCategory = "[starting]";

     QAction *parentPageAction1 = new QAction(tr("Show Parent Page"), this);
     QAction *parentPageAction2 = new QAction(tr("Show Parent Page"), this);
     QAction *parentPageAction3 = new QAction(tr("Show Parent Page"), this);
     parentPageAction1->setShortcut(QKeySequence(tr("Escape")));
     parentPageAction2->setShortcut(QKeySequence(tr("Backspace")));
     parentPageAction3->setShortcut(QKeySequence(tr("Alt+Left")));

     QAction *fullScreenAction = new QAction(tr("Toggle &Full Screen"), this);
     fullScreenAction->setShortcut(QKeySequence(tr("Ctrl+F")));

     QAction *exitAction = new QAction(tr("E&xit"), this);
     exitAction->setShortcut(QKeySequence(tr("Ctrl+Q")));

     connect(parentPageAction1, SIGNAL(triggered()), this, SIGNAL(showPage()));
     connect(parentPageAction2, SIGNAL(triggered()), this, SIGNAL(showPage()));
     connect(parentPageAction3, SIGNAL(triggered()), this, SIGNAL(showPage()));
     connect(fullScreenAction, SIGNAL(triggered()),
             this, SLOT(toggleFullScreen()));
     connect(exitAction, SIGNAL(triggered()), this, SLOT(close()));

     display = new DisplayWidget;

     addAction(parentPageAction1);
     addAction(parentPageAction2);
     addAction(parentPageAction3);
     addAction(fullScreenAction);
     addAction(exitAction);

     slideshowTimer = new QTimer(this);
     slideshowTimer->setInterval(5000);
     resizeTimer = new QTimer(this);
     resizeTimer->setSingleShot(true);
     connect(resizeTimer, SIGNAL(timeout()), this, SLOT(redisplayWindow()));

     assistant = new QAssistantClient(
         QLibraryInfo::location(QLibraryInfo::BinariesPath), this);

     connect(display, SIGNAL(actionRequested(const QString &)),
             this, SLOT(executeAction(const QString &)));
     connect(display, SIGNAL(categoryRequested(const QString &)),
             this, SLOT(showExamples(const QString &)));
     connect(display, SIGNAL(documentationRequested(const QString &)),
             this, SLOT(showExampleDocumentation(const QString &)));
     connect(display, SIGNAL(exampleRequested(const QString &)),
             this, SLOT(showExampleSummary(const QString &)));

     connect(display, SIGNAL(launchRequested(const QString &)),
             this, SLOT(launchExample(const QString &)));

     connect(this, SIGNAL(showPage()), this, SLOT(showParentPage()),
             Qt::QueuedConnection);
     connect(this, SIGNAL(windowResized()), this, SLOT(redisplayWindow()),
             Qt::QueuedConnection);

     setCentralWidget(display);
     setMaximumSize(QApplication::desktop()->screenGeometry().size());
     setWindowTitle(tr("Qt Examples and Demos"));
     setWindowIcon(QPixmap(":/images/qt4-logo.png"));
 }

 bool Launcher::setup()
 {
     documentationDir = QDir(QLibraryInfo::location(
                             QLibraryInfo::DocumentationPath));

     if (!documentationDir.cd("html")) {
         // Failed to find the HTML documentation.
         // We can continue without it.
         QMessageBox::warning(this, tr("No Documentation Found"),
             tr("I could not find the Qt documentation."),
             QMessageBox::Cancel);
     }

     imagesDir = documentationDir;
     if (!imagesDir.cd("images")) {
         // Failed to find the accompanying images for the documentation.
         // We can continue without them.
         QMessageBox::warning(this, tr("No Images Found"),
             tr("I could not find any images for the Qt documentation."),
             QMessageBox::Cancel);
     }

     maximumLabels = 0;

     demosDir = QDir(QLibraryInfo::location(QLibraryInfo::DemosPath));
     int demoCategories = readInfo(":/demos.xml", demosDir);

     examplesDir = QDir(QLibraryInfo::location(QLibraryInfo::ExamplesPath));
     int exampleCategories = readInfo(":/examples.xml", examplesDir);

     if (demoCategories + exampleCategories <= 0) {
         // Failed to find the examples.
         QMessageBox::warning(this, tr("No Examples or Demos found"),
             tr("I could not find any Qt examples or demos.\n"
                "Please ensure that Qt is installed correctly."),
             QMessageBox::Cancel);
         return false;
     }

     maximumLabels = qMax(demoCategories + exampleCategories, maximumLabels);

     // For example menus, remember that the menu has to include a Back button.
     foreach (QString category, categories)
         maximumLabels = qMax(examples[category].size() + 1, maximumLabels);

     QString mainDescription = categoryDescriptions["[main]"];
     if (!mainDescription.isEmpty())
         mainDescription += tr("\n");

     categoryDescriptions["[main]"] = mainDescription + tr(
         "<p>Press <b>Escape</b>, <b>Backspace</b>, or <b>%1</b> to "
         "return to a previous menu.</p>\n"
         "<p>Press <b>%2</b> to switch between normal and full screen "
         "modes.</p>\n"
         "<p>Use <b>%3</b> to exit the launcher.</p>").arg(QString(
             QKeySequence(tr("Alt+Left")))).arg(QString(
             QKeySequence(tr("Ctrl+F")))).arg(QString(
             QKeySequence(tr("Ctrl+Q"))));

     emit showPage();
     return true;
 }

 void Launcher::findDescriptionAndImages(const QString &uniqueName,
                                         const QString &docName)
 {
     if (documentationDir.exists(docName)) {
         exampleDetails[uniqueName]["document path"] = \
             documentationDir.absoluteFilePath(docName);

         QDomDocument exampleDoc;
         QFile exampleFile(exampleDetails[uniqueName]["document path"]);
         exampleDoc.setContent(&exampleFile);

         QDomNodeList paragraphs = exampleDoc.elementsByTagName("p");
         QString description;

         for (int p = 0; p < int(paragraphs.length()); ++p) {
             QDomNode descriptionNode = paragraphs.item(p);
             description = readExampleDescription(descriptionNode);

             if (description.indexOf(QRegExp(QString(
                 "((The|This) )?(%1 )?.*(example|demo)").arg(
                     exampleDetails[uniqueName]["name"]),
                 Qt::CaseInsensitive)) != -1) {
                 exampleDetails[uniqueName]["description"] = description;
                 break;
             }
         }

         QDomNodeList images = exampleDoc.elementsByTagName("img");
         QStringList imageFiles;

         for (int i = 0; i < int(images.length()); ++i) {
             QDomElement imageElement = images.item(i).toElement();
             QString source = imageElement.attribute("src");
             if (!source.contains("-logo"))
                 imageFiles.append(documentationDir.absoluteFilePath(source));
         }

         if (imageFiles.size() > 0)
             imagePaths[uniqueName] = imageFiles;
     }
 }

 int Launcher::readInfo(const QString &resource, const QDir &dir)
 {
     QFile categoriesFile(resource);
     QDomDocument document;
     document.setContent(&categoriesFile);
     QDomElement documentElement = document.documentElement();
     QDomNodeList categoryNodes = documentElement.elementsByTagName("category");

     readCategoryDescription(dir, "[main]");
     qtLogo.load(imagesDir.absoluteFilePath(":/images/qt4-logo.png"));
     trolltechLogo.load(imagesDir.absoluteFilePath(":/images/trolltech-logo.png"));

     for (int i = 0; i < int(categoryNodes.length()); ++i) {

         QDomNode categoryNode = categoryNodes.item(i);
         QDomElement element = categoryNode.toElement();
         QString categoryName = element.attribute("name");
         QString categoryDirName = element.attribute("dirname");
         QString categoryDocName = element.attribute("docname");
         QString categoryColor = element.attribute("color", "#f0f0f0");

         QDir categoryDir = dir;
         if (categoryDir.cd(categoryDirName)) {

             readCategoryDescription(categoryDir, categoryName);

             examples[categoryName] = QStringList();

             QDomNodeList exampleNodes = element.elementsByTagName("example");
             maximumLabels = qMax(maximumLabels, int(exampleNodes.length()));

             for (int j = 0; j < int(exampleNodes.length()); ++j) {

                 QDir exampleDir = categoryDir;

                 QDomNode exampleNode = exampleNodes.item(j);
                 element = exampleNode.toElement();
                 QString exampleName = element.attribute("name");
                 QString exampleFileName = element.attribute("filename");
                 QString exampleDirName = element.attribute("dirname");

                 examples[categoryName].append(exampleName);

                 QString uniqueName = categoryName+"-"+exampleName;
                 exampleOptions[uniqueName] = QMap<QString,QString>();
                 exampleDetails[uniqueName] = QMap<QString,QString>();

                 QString docName;
                 if (!categoryDocName.isEmpty())
                     docName = categoryDocName+"-"+exampleFileName+".html";
                 else
                     docName = categoryDirName+"-"+exampleFileName+".html";

                 exampleDetails[uniqueName]["name"] = exampleName;
                 findDescriptionAndImages(uniqueName, docName);

                 exampleOptions[uniqueName]["changedirectory"] = element.attribute("changedirectory", "true");
                 exampleOptions[uniqueName]["color"] = element.attribute("color", "#f0f0f0");

                 if (!exampleDirName.isEmpty() && !exampleDir.cd(exampleDirName))
                     continue;

                 if (element.attribute("executable", "true") != "true")
                     continue;

                 if (exampleDir.cd(exampleFileName)) {
                     QString examplePath = findExecutable(exampleDir);
                     if (!examplePath.isNull()) {
                         exampleDetails[uniqueName]["absolute path"] = exampleDir.absolutePath();
                         exampleDetails[uniqueName]["path"] = examplePath;
                     }
                 }
             }

             categories.append(categoryName);
             categoryColors[categoryName] = categoryColor;
         }
     }

     return categories.size();
 }

 QString Launcher::findExecutable(const QDir &dir) const
 {
     QDir parentDir = dir;
     parentDir.cdUp();

     QFileInfo releaseDir(dir, "release");
     if (releaseDir.isDir()) {
         QDir currentDir(releaseDir.absoluteFilePath());
         QString path = findExecutable(currentDir);
         if (!path.isEmpty())
             return path;
     }

     foreach (QFileInfo info, dir.entryInfoList(QDir::Dirs)) {
         if (info.fileName().endsWith(".app"))
             return info.absoluteFilePath();
         QDir currentDir(info.absoluteFilePath());
         if (currentDir != dir && currentDir != parentDir &&
             currentDir.dirName() != "plugins") {
             QString path = findExecutable(currentDir);
             if (!path.isNull())
                 return path;
         }
     }

     foreach (QFileInfo info, dir.entryInfoList(QDir::Files)) {
         if (info.isExecutable())
             return info.absoluteFilePath();
     }
     return QString();
 }

 void Launcher::readCategoryDescription(const QDir &categoryDir,
                                        const QString &categoryName)
 {
     if (categoryDir.exists("README")) {
         QFile file(categoryDir.absoluteFilePath("README"));
         if (!file.open(QFile::ReadOnly))
             return;

         QTextStream inputStream(&file);

         QStringList paragraphs;
         QStringList currentPara;
         bool openQuote = true;

         while (!inputStream.atEnd()) {
             QString line = inputStream.readLine();
             int at = 0;
             while ((at = line.indexOf("\"", at)) != -1) {
                 if (openQuote)
                     line[at] = QChar::Punctuation_InitialQuote;
                 else
                     line[at] = QChar::Punctuation_FinalQuote;
                 openQuote = !openQuote;
             }

             if (!line.trimmed().isEmpty()) {
                 currentPara.append(line.trimmed());
             } else if (!currentPara.isEmpty()) {
                 paragraphs.append(currentPara.join(" "));
                 currentPara.clear();
             } else
                 break;
         }

         if (!currentPara.isEmpty())
             paragraphs.append(currentPara.join(" "));

         categoryDescriptions[categoryName] = "<p>" + \
             paragraphs.join("\n</p><p>") + "</p>\n";
     }
 }

 QString Launcher::readExampleDescription(const QDomNode &parentNode) const
 {
     QString description;
     QDomNode node = parentNode.firstChild();

     while (!node.isNull()) {
         QString beginTag;
         QString endTag;
         if (node.isText())
             description += node.nodeValue();
         else if (node.hasChildNodes()) {
             if (node.nodeName() == "b") {
                 beginTag = "<b>";
                 endTag = "</b>";
             } else if (node.nodeName() == "a") {
                 beginTag = "<font color=\"blue\">";
                 endTag = "</font>";
             } else if (node.nodeName() == "i") {
                 beginTag = "<i>";
                 endTag = "</i>";
             } else if (node.nodeName() == "tt") {
                 beginTag = "<tt>";
                 endTag = "</tt>";
             }
             description += beginTag + readExampleDescription(node) + endTag;
         }

         node = node.nextSibling();
     }

     return description;
 }

 void Launcher::launchExample(const QString &uniqueName)
 {
     if (runningExamples.contains(uniqueName))
         return;

     QProcess *process = new QProcess(this);
     connect(process, SIGNAL(finished(int)), this, SLOT(enableLaunching()));

 #ifdef Q_OS_WIN
     //make sure it finds the dlls on windows
     QString curpath = QString::fromLocal8Bit(qgetenv("PATH").constData());
     QString newpath = QString("PATH=%1;%2").arg(
         QLibraryInfo::location(QLibraryInfo::BinariesPath), curpath);
     process->setEnvironment(QStringList(newpath));
 #endif

     runningExamples.append(uniqueName);
     runningProcesses[process] = uniqueName;

     if (exampleOptions[uniqueName]["changedirectory"] == "true")
         process->setWorkingDirectory(exampleDetails[uniqueName]["absolute path"]);

     process->start(exampleDetails[uniqueName]["path"]);

     if (process->state() == QProcess::Starting)
         slideshowTimer->stop();
 }

 void Launcher::enableLaunching()
 {
     QProcess *process = static_cast<QProcess*>(sender());
     QString example = runningProcesses.take(process);
     process->deleteLater();
     runningExamples.removeAll(example);

     if (example == currentExample) {
         for (int i = 0; i < display->shapesCount(); ++i) {
             DisplayShape *shape = display->shape(i);
             if (shape->metaData("launch").toString() == example) {
                 shape->setMetaData("fade", 15);
                 display->enableUpdates();
             }
         }
         slideshowTimer->start();
     }
 }

 void Launcher::executeAction(const QString &action)
 {
     if (action == "parent")
         showParentPage();
     else if (action == "exit") {
         if (runningExamples.size() == 0) {
             connect(display, SIGNAL(displayEmpty()), this, SLOT(close()));
             display->reset();
         } else
             close();
     }
 }

 void Launcher::closeEvent(QCloseEvent *event)
 {
     if (runningExamples.size() > 0) {
         if (QMessageBox::warning(this, tr("Examples Running"),
                 tr("There are examples running. Do you really want to exit?"),
                 QMessageBox::Yes|QMessageBox::No) == QMessageBox::No)
             event->ignore();
             return;
     }

     foreach (QProcess *example, runningProcesses.keys()) {
         example->terminate();
         example->waitForFinished(1000);
     }

     qDeleteAll(runningProcesses.keys());
     resizeTimer->stop();
     slideshowTimer->stop();
 }

 void Launcher::showParentPage()
 {
     slideshowTimer->stop();
     disconnect(slideshowTimer, SIGNAL(timeout()), this, 0);

     if (!currentExample.isEmpty()) {
         currentExample = "";
         redisplayWindow();
     } else if (!currentCategory.isEmpty()) {
         currentCategory = "";
         redisplayWindow();
     }
 }

 void Launcher::newPage()
 {
     slideshowTimer->stop();
     disconnect(slideshowTimer, SIGNAL(timeout()), this, 0);
     disconnect(display, SIGNAL(displayEmpty()), this, 0);
 }

 DisplayShape *Launcher::addTitle(const QString &title, qreal verticalMargin)
 {
     QPointF titlePosition = QPointF(0.0, 2*verticalMargin);

     DisplayShape *newTitle = new TitleShape(title, titleFont,
         QPen(Qt::white), titlePosition,
         QSizeF(0.5 * width(), 2*verticalMargin),
         Qt::AlignHCenter | Qt::AlignTop);

     newTitle->setPosition(QPointF(-newTitle->rect().width(), titlePosition.y()));
     newTitle->setTarget(QPointF(0.25*width(), titlePosition.y()));
     newTitle->setMetaData("fade", 15);

     display->appendShape(newTitle);

     return newTitle;
 }

 DisplayShape *Launcher::addTitleBackground(DisplayShape *titleShape)
 {
     QPainterPath backgroundPath;
     backgroundPath.addRect(0, -titleShape->rect().height()*0.3,
                            width(), titleShape->rect().height()*1.6);

     DisplayShape *titleBackground = new PanelShape(backgroundPath,
         QBrush(QColor("#a6ce39")), QBrush(QColor("#a6ce39")), Qt::NoPen,
             QPointF(width(), titleShape->position().y()),
             backgroundPath.boundingRect().size());

     titleBackground->setTarget(QPointF(0.0, titleShape->position().y()));

     display->insertShape(0, titleBackground);

     return titleBackground;
 }

 void Launcher::addVersionAndCopyright(const QRectF &rect)
 {
     DisplayShape *versionCaption = new TitleShape(
         QString("Qt %1").arg(QT_VERSION_STR), font(),
         QPen(QColor(0,0,0,0)),
         QPointF(rect.center().x(), rect.top()),
         QSizeF(0.5*rect.width(), rect.height()),
         Qt::AlignRight | Qt::AlignVCenter);

     versionCaption->setMetaData("fade", 15);
     display->appendShape(versionCaption);

     DisplayShape *copyrightCaption = new TitleShape(
         QString("Copyright \xa9 2005-2007 Trolltech ASA"), font(),
         QPen(QColor(0,0,0,0)),
         rect.topLeft(), QSizeF(0.5*rect.width(), rect.height()),
         Qt::AlignLeft | Qt::AlignVCenter);

     copyrightCaption->setMetaData("fade", 15);
     display->appendShape(copyrightCaption);
 }

 void Launcher::fadeShapes()
 {
     for (int i = 0; i < display->shapesCount(); ++i) {
         DisplayShape *shape = display->shape(i);

         shape->setMetaData("fade", -15);
         shape->setMetaData("fade minimum", 0);
     }
 }

 void Launcher::showCategories()
 {
     newPage();
     fadeShapes();
     currentCategory = "";
     currentExample = "";

     qreal horizontalMargin = 0.025*width();
     qreal verticalMargin = 0.025*height();

     DisplayShape *title = new TitleShape(tr("Qt Examples and Demos"),
         titleFont, QPen(QColor("#a6ce39")), QPointF(),
         QSizeF(0.5*width(), 4*verticalMargin));

     title->setPosition(QPointF(width()/2 - title->rect().width()/2,
                                -title->rect().height()));
     title->setTarget(QPointF(title->position().x(), verticalMargin));

     display->appendShape(title);

     qreal topMargin = 6*verticalMargin;
     qreal bottomMargin = height() - 3.2*verticalMargin;
     qreal space = bottomMargin - topMargin;
     qreal step = qMin(title->rect().height() / fontRatio,
                       space/qreal(maximumLabels));
     qreal textHeight = fontRatio * step;

     QPointF startPosition = QPointF(0.0, topMargin);
     QSizeF maxSize(10.8*horizontalMargin, textHeight);
     qreal maxWidth = 0.0;

     QList<DisplayShape*> newShapes;

     foreach (QString category, categories) {

         DisplayShape *caption = new TitleShape(category, font(), QPen(),
             startPosition, maxSize);
         caption->setPosition(QPointF(-caption->rect().width(),
                                      caption->position().y()));
         caption->setTarget(QPointF(2*horizontalMargin, caption->position().y()));

         newShapes.append(caption);

         startPosition += QPointF(0.0, step);
         maxWidth = qMax(maxWidth, caption->rect().width());
     }

     DisplayShape *exitButton = new TitleShape(tr("Exit"), font(),
         QPen(Qt::white), startPosition, maxSize);

     exitButton->setTarget(QPointF(2*horizontalMargin, exitButton->position().y()));
     newShapes.append(exitButton);

     startPosition = QPointF(width(), topMargin);
     qreal extra = (step - textHeight)/4;

     QPainterPath backgroundPath;
     backgroundPath.addRect(-2*extra, -extra, maxWidth + 4*extra, textHeight + 2*extra);

     foreach (QString category, categories) {

         DisplayShape *background = new PanelShape(backgroundPath,
             QBrush(categoryColors[category]), QBrush(QColor("#e0e0ff")),
             Qt::NoPen, startPosition,
             QSizeF(maxWidth + 4*extra, textHeight + 2*extra));

         background->setMetaData("category", category);
         background->setInteractive(true);
         background->setTarget(QPointF(2*horizontalMargin,
                                       background->position().y()));
         display->insertShape(0, background);
         startPosition += QPointF(0.0, step);
     }

     QPainterPath exitPath;
     exitPath.moveTo(-2*extra, -extra);
     exitPath.lineTo(-8*extra, textHeight/2);
     exitPath.lineTo(-extra, textHeight + extra);
     exitPath.lineTo(maxWidth + 2*extra, textHeight + extra);
     exitPath.lineTo(maxWidth + 2*extra, -extra);
     exitPath.closeSubpath();

     DisplayShape *exitBackground = new PanelShape(exitPath,
         QBrush(QColor("#a6ce39")), QBrush(QColor("#c7f745")), Qt::NoPen,
         startPosition, QSizeF(maxWidth + 10*extra, textHeight + 2*extra));

     exitBackground->setMetaData("action", "exit");
     exitBackground->setInteractive(true);
     exitBackground->setTarget(QPointF(2*horizontalMargin,
                                       exitBackground->position().y()));
     display->insertShape(0, exitBackground);

     foreach (DisplayShape *caption, newShapes) {
         QPointF position = caption->target();
         QSizeF size = caption->rect().size();
         caption->setPosition(QPointF(-maxWidth, position.y()));
         display->appendShape(caption);
     }

     qreal leftMargin = 3*horizontalMargin + maxWidth;
     qreal rightMargin = width() - 3*horizontalMargin;

     DocumentShape *description = new DocumentShape(categoryDescriptions["[main]"],
         documentFont, QPointF(leftMargin, topMargin),
         QSizeF(rightMargin - leftMargin, space), 0);

     description->setMetaData("fade", 10);
     display->appendShape(description);

     qreal imageHeight = title->rect().height() + verticalMargin;

     qreal qtLength = qMin(imageHeight, title->rect().left()-3*horizontalMargin);
     QSizeF qtMaxSize = QSizeF(qtLength, qtLength);

     DisplayShape *qtShape = new ImageShape(qtLogo,
         QPointF(2*horizontalMargin-extra, -imageHeight), qtMaxSize, 0,
         Qt::AlignLeft | Qt::AlignVCenter);

     qtShape->setMetaData("fade", 15);
     qtShape->setTarget(QPointF(qtShape->rect().x(), verticalMargin));
     display->insertShape(0, qtShape);

     QSizeF trolltechMaxSize = QSizeF(
         width()-3*horizontalMargin-title->rect().right(), imageHeight);

     DisplayShape *trolltechShape = new ImageShape(trolltechLogo,
         QPointF(width()-2*horizontalMargin-trolltechMaxSize.width()+extra,
                 -imageHeight),
         trolltechMaxSize, 0, Qt::AlignRight | Qt::AlignVCenter);

     trolltechShape->setMetaData("fade", 15);
     trolltechShape->setTarget(QPointF(trolltechShape->rect().x(),
                                       verticalMargin));
     display->insertShape(0, trolltechShape);

     addVersionAndCopyright(QRectF(2*horizontalMargin,
                            height() - verticalMargin - textHeight,
                            width()-4*horizontalMargin, textHeight));
 }

 void Launcher::showExamples(const QString &category)
 {
     newPage();
     fadeShapes();
     currentCategory = category;
     currentExample = "";

     qreal horizontalMargin = 0.025*width();
     qreal verticalMargin = 0.025*height();

     DisplayShape *newTitle = addTitle(category, verticalMargin);
     addTitleBackground(newTitle);

     qreal topMargin = 6*verticalMargin;
     qreal bottomMargin = height() - 3.2*verticalMargin;
     qreal space = bottomMargin - topMargin;
     qreal step = qMin(newTitle->rect().height() / fontRatio,
                       space/qreal(maximumLabels));
     qreal textHeight = fontRatio * step;

     QPointF startPosition = QPointF(2*horizontalMargin, height() + topMargin);
     QPointF finishPosition = QPointF(2*horizontalMargin, topMargin);
     QSizeF maxSize(32*horizontalMargin, textHeight);
     qreal maxWidth = 0.0;

     foreach (QString example, examples[currentCategory]) {

         DisplayShape *caption = new TitleShape(example, font(), QPen(),
             startPosition, maxSize);
         caption->setTarget(finishPosition);

         display->appendShape(caption);

         startPosition += QPointF(0.0, step);
         finishPosition += QPointF(0.0, step);
         maxWidth = qMax(maxWidth, caption->rect().width());
     }

     DisplayShape *menuButton = new TitleShape(tr("Main Menu"), font(),
         QPen(Qt::white), startPosition, maxSize);
     menuButton->setTarget(finishPosition);

     display->appendShape(menuButton);
     maxWidth = qMax(maxWidth, menuButton->rect().width());

     startPosition = QPointF(width(), topMargin);
     qreal extra = (step - textHeight)/4;

     foreach (QString example, examples[currentCategory]) {

         QString uniqueName = currentCategory+"-"+example;
         QPainterPath path;
         path.addRect(-2*extra, -extra, maxWidth + 4*extra, textHeight + 2*extra);

         DisplayShape *background = new PanelShape(path,
             QBrush(QColor(exampleOptions[uniqueName]["color"])),
             QBrush(QColor("#e0e0ff")),
             Qt::NoPen, startPosition,
             QSizeF(maxWidth + 4*extra, textHeight + 2*extra));

         background->setMetaData("example", uniqueName);
         background->setInteractive(true);
         background->setTarget(QPointF(2*horizontalMargin,
                                       background->position().y()));
         display->insertShape(0, background);
         startPosition += QPointF(0.0, step);
     }

     QPainterPath backPath;
     backPath.moveTo(-2*extra, -extra);
     backPath.lineTo(-8*extra, textHeight/2);
     backPath.lineTo(-extra, textHeight + extra);
     backPath.lineTo(maxWidth + 2*extra, textHeight + extra);
     backPath.lineTo(maxWidth + 2*extra, -extra);
     backPath.closeSubpath();

     DisplayShape *buttonBackground = new PanelShape(backPath,
         QBrush(QColor("#a6ce39")), QBrush(QColor("#c7f745")), Qt::NoPen,
         startPosition, QSizeF(maxWidth + 10*extra, textHeight + 2*extra));

     buttonBackground->setMetaData("action", "parent");
     buttonBackground->setInteractive(true);
     buttonBackground->setTarget(QPointF(2*horizontalMargin,
                                         buttonBackground->position().y()));
     display->insertShape(0, buttonBackground);

     qreal leftMargin = 3*horizontalMargin + maxWidth;
     qreal rightMargin = width() - 3*horizontalMargin;

     DocumentShape *description = new DocumentShape(
         categoryDescriptions[currentCategory], documentFont,
         QPointF(leftMargin, topMargin), QSizeF(rightMargin - leftMargin, space),
         0);

     description->setMetaData("fade", 10);

     display->appendShape(description);

     addVersionAndCopyright(QRectF(2*horizontalMargin,
                            height() - verticalMargin - textHeight,
                            width()-4*horizontalMargin, textHeight));
 }

 void Launcher::showExampleDocumentation(const QString &uniqueName)
 {
     disconnect(display, SIGNAL(displayEmpty()), this, 0);
     currentExample = uniqueName;

     assistant->showPage(exampleDetails[uniqueName]["document path"]);
 }

 void Launcher::showExampleSummary(const QString &uniqueName)
 {
     newPage();
     fadeShapes();
     currentExample = uniqueName;

     qreal horizontalMargin = 0.025*width();
     qreal verticalMargin = 0.025*height();

     DisplayShape *newTitle = addTitle(exampleDetails[currentExample]["name"],
                                       verticalMargin);
     DisplayShape *titleBackground = addTitleBackground(newTitle);

     qreal topMargin = 2*verticalMargin + titleBackground->rect().bottom();
     qreal bottomMargin = height() - 8*verticalMargin;
     qreal space = bottomMargin - topMargin;
     qreal step = qMin(newTitle->rect().height() / fontRatio,
                       (bottomMargin + qreal(4.8)*verticalMargin - topMargin)
                       /qreal(maximumLabels));
     qreal textHeight = fontRatio * step;

     qreal leftMargin = 3*horizontalMargin;
     qreal rightMargin = width() - 3*horizontalMargin;

     if (exampleDetails[currentExample].contains("description")) {
         DocumentShape *description = new DocumentShape(
             exampleDetails[currentExample]["description"], documentFont,
             QPointF(leftMargin, topMargin),
             QSizeF(rightMargin-leftMargin, space), 0);

         description->setMetaData("fade", 10);

         description->setPosition(QPointF(description->position().x(),
             0.8*height() - description->rect().height()));

         display->appendShape(description);
         space = description->position().y() - topMargin - 2*verticalMargin;
     }

     if (imagePaths.contains(currentExample)) {

         QImage image(imagePaths[currentExample][0]);

         QSizeF imageMaxSize = QSizeF(width() - 8*horizontalMargin, space);

         currentFrame = new ImageShape(image,
             QPointF(width() - imageMaxSize.width()/2, topMargin),
             imageMaxSize);

         currentFrame->setMetaData("fade", 15);
         currentFrame->setTarget(QPointF(width()/2 - imageMaxSize.width()/2,
                                         topMargin));

         display->appendShape(currentFrame);

         if (imagePaths[currentExample].size() > 1) {
             connect(slideshowTimer, SIGNAL(timeout()),
                     this, SLOT(updateExampleSummary()));

             slideshowFrame = 0;
             slideshowTimer->start();
         }
     }

     QSizeF maxSize(0.3 * width(), 2*verticalMargin);
     leftMargin = 0.0;
     rightMargin = 0.0;

     if (true) {
         DisplayShape *backButton = new TitleShape(currentCategory, font(),
             QPen(Qt::white), QPointF(0.1*width(), height()), maxSize,
             Qt::AlignLeft | Qt::AlignTop);
         backButton->setTarget(QPointF(backButton->position().x(),
                                       height() - 5.2*verticalMargin));

         display->appendShape(backButton);

         qreal maxWidth = backButton->rect().width();
         qreal textHeight = backButton->rect().height();
         qreal extra = (3*verticalMargin - textHeight)/4;

         QPainterPath path;
         path.moveTo(-extra, -extra);
         path.lineTo(-4*extra, textHeight/2);
         path.lineTo(-extra, textHeight + extra);
         path.lineTo(maxWidth + 2*extra, textHeight + extra);
         path.lineTo(maxWidth + 2*extra, -extra);
         path.closeSubpath();

         DisplayShape *buttonBackground = new PanelShape(path,
             QBrush(QColor("#a6ce39")), QBrush(QColor("#c7f745")), Qt::NoPen,
             backButton->position(),
             QSizeF(maxWidth + 6*extra, textHeight + 2*extra));

         buttonBackground->setMetaData("category", currentCategory);
         buttonBackground->setInteractive(true);
         buttonBackground->setTarget(backButton->target());

         display->insertShape(0, buttonBackground);

         leftMargin = buttonBackground->rect().right();
     }

     if (exampleDetails[currentExample].contains("absolute path")) {

         DisplayShape *launchCaption = new TitleShape(tr("Launch"),
             font(), QPen(Qt::white), QPointF(0.0, 0.0), maxSize,
             Qt::AlignLeft | Qt::AlignTop);
         launchCaption->setPosition(QPointF(
             0.9*width() - launchCaption->rect().width(), height()));
         launchCaption->setTarget(QPointF(launchCaption->position().x(),
                                          height() - 5.2*verticalMargin));

         display->appendShape(launchCaption);

         qreal maxWidth = launchCaption->rect().width();
         qreal textHeight = launchCaption->rect().height();
         qreal extra = (3*verticalMargin - textHeight)/4;

         QPainterPath path;
         path.addRect(-2*extra, -extra, maxWidth + 4*extra, textHeight + 2*extra);

         QColor backgroundColor = QColor("#a63e39");
         QColor highlightedColor = QColor("#f95e56");

         DisplayShape *background = new PanelShape(path,
             QBrush(backgroundColor), QBrush(highlightedColor), Qt::NoPen,
             launchCaption->position(),
             QSizeF(maxWidth + 4*extra, textHeight + 2*extra));

         background->setMetaData("fade minimum", 120);
         background->setMetaData("launch", currentExample);
         background->setInteractive(true);
         background->setTarget(launchCaption->target());

         if (runningExamples.contains(currentExample)) {
             background->setMetaData("highlight", true);
             background->setMetaData("highlight scale", 0.99);
             background->animate();
             background->setMetaData("fade", -135);
             slideshowTimer->stop();
         }

         display->insertShape(0, background);

         rightMargin = background->rect().left();
     }

     if (exampleDetails[currentExample].contains("document path")) {

         DisplayShape *documentCaption = new TitleShape(tr("Show Documentation"),
             font(), QPen(Qt::white), QPointF(0.0, 0.0), maxSize,
             Qt::AlignLeft | Qt::AlignTop);

         if (rightMargin == 0.0) {
             documentCaption->setPosition(QPointF(
                 0.9*width() - documentCaption->rect().width(), height()));
         } else {
             documentCaption->setPosition(QPointF(
                 leftMargin/2 + rightMargin/2 - documentCaption->rect().width()/2,
                 height()));
         }
         documentCaption->setTarget(QPointF(documentCaption->position().x(),
                                            height() - 5.2*verticalMargin));

         display->appendShape(documentCaption);

         qreal maxWidth = documentCaption->rect().width();
         qreal textHeight = documentCaption->rect().height();
         qreal extra = (3*verticalMargin - textHeight)/4;

         QPainterPath path;
         path.addRect(-2*extra, -extra, maxWidth + 4*extra, textHeight + 2*extra);

         DisplayShape *background = new PanelShape(path,
             QBrush(QColor("#9c9cff")), QBrush(QColor("#cfcfff")), Qt::NoPen,
             documentCaption->position(),
             QSizeF(maxWidth + 4*extra, textHeight + 2*extra));

         background->setMetaData("fade minimum", 120);
         background->setMetaData("documentation", currentExample);
         background->setInteractive(true);
         background->setTarget(documentCaption->target());

         display->insertShape(0, background);
     }

     addVersionAndCopyright(QRectF(2*horizontalMargin,
                            height() - verticalMargin - textHeight,
                            width()-4*horizontalMargin, textHeight));
 }

 void Launcher::updateExampleSummary()
 {
     if (imagePaths.contains(currentExample)) {

         currentFrame->setMetaData("fade", -15);
         currentFrame->setTarget(currentFrame->position() - QPointF(0.5*width(),
                                 0));

         slideshowFrame = (slideshowFrame+1) % imagePaths[currentExample].size();
         QImage image(imagePaths[currentExample][slideshowFrame]);

         QSizeF imageSize = currentFrame->size();
         QPointF imagePosition = QPointF(width() - imageSize.width()/2,
                                         currentFrame->position().y());

         currentFrame = new ImageShape(image, imagePosition, imageSize);
         currentFrame->setMetaData("fade", 15);
         currentFrame->setTarget(QPointF(width()/2 - imageSize.width()/2,
                                         imagePosition.y()));

         display->appendShape(currentFrame);
     }
 }

 void Launcher::toggleFullScreen()
 {
     if (inFullScreenResize)
         return;

     inFullScreenResize = true;

     connect(display, SIGNAL(displayEmpty()), this, SLOT(resizeWindow()),
             Qt::QueuedConnection);
     display->reset();
 }

 void Launcher::resizeWindow()
 {
     disconnect(display, SIGNAL(displayEmpty()), this, 0);

     if (isFullScreen())
         showNormal();
     else
         showFullScreen();
 }

 void Launcher::resizeEvent(QResizeEvent *event)
 {
     Q_UNUSED(event);

     documentFont = font();
     documentFont.setPointSizeF(qMin(documentFont.pointSizeF()*width()/640.0,
                                     documentFont.pointSizeF()*height()/480.0));

     if (inFullScreenResize)
         inFullScreenResize = false;

     if (currentCategory != "[starting]")
         resizeTimer->start(500);
 }

 void Launcher::redisplayWindow()
 {
     if (!currentExample.isEmpty())
         showExampleSummary(currentExample);
     else if (!currentCategory.isEmpty())
         showExamples(currentCategory);
     else
         showCategories();
 }


Copyright © 2007 Trolltech Trademarks
Qt 4.2.3