HelpViewer.cpp
Go to the documentation of this file.
00001 /*
00002         Aseba - an event-based framework for distributed robot control
00003         Copyright (C) 2007--2012:
00004                 Stephane Magnenat <stephane at magnenat dot net>
00005                 (http://stephane.magnenat.net)
00006                 and other contributors, see authors.txt for details
00007         
00008         This program is free software: you can redistribute it and/or modify
00009         it under the terms of the GNU Lesser General Public License as published
00010         by the Free Software Foundation, version 3 of the License.
00011         
00012         This program is distributed in the hope that it will be useful,
00013         but WITHOUT ANY WARRANTY; without even the implied warranty of
00014         MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015         GNU Lesser General Public License for more details.
00016         
00017         You should have received a copy of the GNU Lesser General Public License
00018         along with this program. If not, see <http://www.gnu.org/licenses/>.
00019 */
00020 
00021 #include "HelpViewer.h"
00022 
00023 #include <QtHelp/QHelpContentWidget>
00024 #include <QCoreApplication>
00025 #include <QDir>
00026 #include <QHBoxLayout>
00027 #include <QVBoxLayout>
00028 #include <QSplitter>
00029 #include <QFile>
00030 #include <QIODevice>
00031 #include <QUrl>
00032 #include <QVariant>
00033 #include <QSettings>
00034 #include <QDesktopServices>
00035 #include <QMessageBox>
00036 
00037 #include <QDebug>
00038 
00039 #include <HelpViewer.moc>
00040 
00041 namespace Aseba
00042 {
00043         const QString HelpViewer::DEFAULT_LANGUAGE = "en";
00044 
00045         HelpViewer::HelpViewer(QWidget* parent):
00046                 QWidget(parent),
00047                 tmpHelpSubDir(QString("aseba-studio-%1").arg(QCoreApplication::applicationPid())),
00048                 tmpHelpFileNameHC(QDir::temp().filePath(tmpHelpSubDir + "/aseba-doc.qhc")),
00049                 tmpHelpFileNameCH(QDir::temp().filePath(tmpHelpSubDir + "/aseba-doc.qch"))
00050         {
00051                 // expanding help files into tmp
00052                 QDir::temp().mkdir(tmpHelpSubDir);
00053                 QFile(":aseba-doc.qhc").copy(tmpHelpFileNameHC);
00054                 QFile(":aseba-doc.qch").copy(tmpHelpFileNameCH);
00055                 
00056                 // open files from tmp
00057                 helpEngine = new QHelpEngine(tmpHelpFileNameHC, this);
00058                 if (helpEngine->setupData() == false)
00059                 {
00060                         helpFound = false;
00061                         QString message = tr("The help file %0 was not loaded successfully. " \
00062                                 "The error was: %1." \
00063                                 "The help file should be available in the temporary directory of your system. " \
00064                                 "Please check your installation, or report a bug.").arg(tmpHelpFileNameHC).arg(helpEngine->error());
00065                         QMessageBox::warning(this, tr("Help file not found"), message);
00066                 }
00067                 else
00068                         helpFound = true;
00069 
00070                 // navigation buttons
00071                 previous = new QPushButton(tr("Previous"));
00072                 previous->setEnabled(false);
00073                 next = new QPushButton(tr("Next"));
00074                 next->setEnabled(false);
00075                 home = new QPushButton(tr("Home"));
00076                 QHBoxLayout* buttonLayout = new QHBoxLayout();
00077                 buttonLayout->addWidget(previous);
00078                 buttonLayout->addWidget(home);
00079                 buttonLayout->addWidget(next);
00080                 buttonLayout->addStretch();
00081 
00082                 // QTextBrower
00083                 viewer = new HelpBrowser(helpEngine);
00084 
00085                 // set default language
00086                 setLanguage();
00087 
00088                 // help layout
00089                 QSplitter *helpSplitter = new QSplitter(Qt::Horizontal);
00090                 helpSplitter->addWidget(helpEngine->contentWidget());
00091                 helpSplitter->addWidget(viewer);
00092                 helpSplitter->setStretchFactor(helpSplitter->indexOf(viewer), 1);
00093 
00094                 // main layout
00095                 QVBoxLayout* mainLayout = new QVBoxLayout();
00096                 mainLayout->addLayout(buttonLayout);
00097                 //mainLayout->addWidget(viewer);
00098                 mainLayout->addWidget(helpSplitter);
00099 
00100                 setLayout(mainLayout);
00101 
00102                 // connect
00103                 connect(previous, SIGNAL(clicked()), this, SLOT(previousClicked()));
00104                 connect(next, SIGNAL(clicked()), this, SLOT(nextClicked()));
00105                 connect(home, SIGNAL(clicked()), this, SLOT(homeClicked()));
00106                 connect(viewer, SIGNAL(backwardAvailable(bool)), this, SLOT(backwardAvailable(bool)));
00107                 connect(viewer, SIGNAL(forwardAvailable(bool)), this, SLOT(forwardAvailable(bool)));
00108                 connect(helpEngine->contentWidget(), SIGNAL(linkActivated(const QUrl&)), viewer, SLOT(setSource(const QUrl&)));
00109 
00110                 // restore window state, if available
00111                 if (readSettings() == false)
00112                         resize(800, 500);
00113 
00114                 setWindowTitle(tr("Aseba Studio Help"));
00115         }
00116 
00117         HelpViewer::~HelpViewer()
00118         {
00119                 writeSettings();
00120                 // remove help files from tmp
00121                 QFile(tmpHelpFileNameHC).remove();
00122                 QFile(tmpHelpFileNameCH).remove();
00123                 QDir::temp().rmdir(tmpHelpSubDir);
00124         }
00125 
00126         void HelpViewer::setLanguage(const QString& lang)
00127         {
00128                 if (!helpFound)
00129                         return;
00130 
00131                 // check if the language is part of the existing filters
00132                 if (selectLanguage(lang) == false)
00133                 {
00134                         // rollback to default language
00135                         QString message = tr("The help filter for the langauge \"%0\" has not been found. " \
00136                                              "Falling back to the default language (%1). " \
00137                                              "This is probably a bug, please report it.").arg(lang).arg(DEFAULT_LANGUAGE);
00138                         QMessageBox::warning(this, tr("Help filter not found"), message);
00139                         helpEngine->setCurrentFilter(DEFAULT_LANGUAGE);
00140                         this->language = DEFAULT_LANGUAGE;
00141                 }
00142         }
00143         
00144         bool HelpViewer::selectLanguage(const QString& reqLang)
00145         {
00146                 const QStringList& langList(helpEngine->customFilters());
00147                 for (QStringList::const_iterator it = langList.constBegin(); it != langList.constEnd(); ++it)
00148                 {
00149                         const QString& availableLang(*it);
00150                         if (reqLang.startsWith(availableLang))
00151                         {
00152                                 helpEngine->setCurrentFilter(availableLang);
00153                                 this->language = availableLang;
00154                                 return true;
00155                         }
00156                 }
00157                 return false;
00158         }
00159 
00160         void HelpViewer::showHelp(helpType type)
00161         {
00162                 if (!helpFound)
00163                 {
00164                         this->show();   // show anyway, but will be blank
00165                         return;
00166                 }
00167 
00168                 QString filename = "qthelp:///doc/doc/" + this->language + "_";
00169                 switch (type)
00170                 {
00171                         // help files generated by the wikidot parser
00172                         case HelpViewer::USERMANUAL:
00173                                 filename += "asebausermanual.html";
00174                                 break;
00175                         case HelpViewer::STUDIO:
00176                                 filename += "asebastudio.html";
00177                                 break;
00178                         case HelpViewer::LANGUAGE:
00179                                 filename += "asebalanguage.html";
00180                                 break;
00181                 }
00182 
00183                 QUrl result = helpEngine->findFile(QUrl(filename));
00184                 viewer->setSource(result);
00185                 viewer->setWindowTitle(tr("Aseba Studio Help"));
00186                 this->show();
00187         }
00188 
00189         bool HelpViewer::readSettings()
00190         {
00191                 bool result;
00192 
00193                 QSettings settings;
00194                 result = restoreGeometry(settings.value("HelpViewer/geometry").toByteArray());
00195                 move(settings.value("HelpViewer/position").toPoint());
00196                 return result;
00197         }
00198 
00199         void HelpViewer::writeSettings()
00200         {
00201                 QSettings settings;
00202                 settings.setValue("HelpViewer/geometry", saveGeometry());
00203                 settings.setValue("HelpViewer/position", pos());
00204         }
00205 
00206 
00207         void HelpViewer::previousClicked()
00208         {
00209                 viewer->backward();
00210         }
00211 
00212         void HelpViewer::backwardAvailable(bool state)
00213         {
00214                 previous->setEnabled(state);
00215         }
00216 
00217         void HelpViewer::nextClicked()
00218         {
00219                 viewer->forward();
00220         }
00221 
00222         void HelpViewer::forwardAvailable(bool state)
00223         {
00224                 next->setEnabled(state);
00225         }
00226 
00227         void HelpViewer::homeClicked()
00228         {
00229                 showHelp(HelpViewer::USERMANUAL);
00230         }
00231 
00232 
00233         HelpBrowser::HelpBrowser(QHelpEngine* helpEngine, QWidget* parent):
00234                 QTextBrowser(parent), helpEngine(helpEngine)
00235         {
00236                 setReadOnly(true);
00237         }
00238 
00239         void HelpBrowser::setSource(const QUrl &url)
00240         {
00241                 if (url.scheme() == "http")
00242                 {
00243                         QDesktopServices::openUrl(url);
00244                 }
00245                 else
00246                         QTextBrowser::setSource(url);
00247         }
00248 
00249         QVariant HelpBrowser::loadResource(int type, const QUrl& url)
00250         {
00251                 //qDebug() << "Loading " << url;
00252 
00253                 // from Qt Quarterly 28:
00254                 // "Using QtHelp to Lend a Helping Hand"
00255                 if (url.scheme() == "qthelp")
00256                         return QVariant(helpEngine->fileData(url));
00257                 else
00258                         return QTextBrowser::loadResource(type, url);
00259         }
00260 }
00261 


aseba
Author(s): Stéphane Magnenat
autogenerated on Thu Jan 2 2014 11:17:16