KTutorial  0.5.1
Tutorial.cpp
00001 /***************************************************************************
00002  *   Copyright (C) 2008 by Daniel Calviño Sánchez <danxuliu@gmail.com>     *
00003  *   Copyright (C) 2009 by Daniel Calviño Sánchez <danxuliu@gmail.com>     *
00004  *   Copyright (C) 2010 by Daniel Calviño Sánchez <danxuliu@gmail.com>     *
00005  *   Copyright (C) 2011 by Daniel Calviño Sánchez <danxuliu@gmail.com>     *
00006  *   Copyright (C) 2012 by Daniel Calviño Sánchez <danxuliu@gmail.com>     *
00007  *                                                                         *
00008  *   This program is free software; you can redistribute it and/or modify  *
00009  *   it under the terms of the GNU General Public License as published by  *
00010  *   the Free Software Foundation; either version 2 of the License, or     *
00011  *   (at your option) any later version.                                   *
00012  *                                                                         *
00013  *   This program is distributed in the hope that it will be useful,       *
00014  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00015  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00016  *   GNU General Public License for more details.                          *
00017  *                                                                         *
00018  *   You should have received a copy of the GNU General Public License     *
00019  *   along with this program; If not, see <http://www.gnu.org/licenses/>.  *
00020  ***************************************************************************/
00021 
00022 #include "Tutorial.h"
00023 #include "Tutorial_p.h"
00024 
00025 #include <KDebug>
00026 
00027 #include "Step.h"
00028 #include "TutorialInformation.h"
00029 
00030 namespace ktutorial {
00031 extern int debugArea();
00032 }
00033 
00034 namespace ktutorial {
00035 
00036 //public:
00037 
00038 Tutorial::Tutorial(TutorialInformation* tutorialInformation): QObject(),
00039     d(new TutorialPrivate()) {
00040     d->mTutorialInformation = tutorialInformation;
00041     d->mCurrentStep = 0;
00042 }
00043 
00044 Tutorial::~Tutorial() {
00045     delete d->mTutorialInformation;
00046     delete d;
00047 }
00048 
00049 TutorialInformation* Tutorial::tutorialInformation() const {
00050     return d->mTutorialInformation;
00051 }
00052 
00053 void Tutorial::addStep(Step* step) {
00054     if (d->mSteps.contains(step->id())) {
00055         kWarning(debugArea()) << "Step with id" << step->id()
00056                               << "already added in tutorial"
00057                               << d->mTutorialInformation->id();
00058         return;
00059     }
00060 
00061     step->setParent(this);
00062 
00063     d->mSteps.insert(step->id(), step);
00064 
00065     connect(step, SIGNAL(nextStepRequested(QString)),
00066             this, SLOT(nextStep(QString)));
00067 }
00068 
00069 void Tutorial::start() {
00070     setup();
00071 
00072     if (!d->mSteps.contains("start")) {
00073         kError(debugArea()) << "No start step found in tutorial"
00074                             << d->mTutorialInformation->id();
00075         finish();
00076         return;
00077     }
00078 
00079     nextStep("start");
00080 }
00081 
00082 void Tutorial::nextStep(const QString& id) {
00083     if (!d->mSteps.contains(id)) {
00084         kError(debugArea()) << "No step" << id << "found in tutorial"
00085                             << d->mTutorialInformation->id();
00086         return;
00087     }
00088 
00089     nextStep(d->mSteps.value(id));
00090 }
00091 
00092 void Tutorial::nextStep(Step* step) {
00093     d->mQueuedSteps.append(step);
00094 
00095     if (d->mQueuedSteps.count() > 1) {
00096         //Nested call to nextStep(Step*) (that is, something called by
00097         //nextStep(Step*) caused the method to be called again before its
00098         //previous execution ended). Once that previous call continues its
00099         //execution it will change to the next queued step.
00100         return;
00101     }
00102 
00103     while (d->mQueuedSteps.count() > 0) {
00104         changeToStep(d->mQueuedSteps[0]);
00105         d->mQueuedSteps.removeFirst();
00106     }
00107 }
00108 
00109 //public slots:
00110 
00111 void Tutorial::finish() {
00112     if (d->mCurrentStep != 0) {
00113         d->mCurrentStep->setActive(false);
00114         d->mCurrentStep = 0;
00115     }
00116 
00117     tearDown();
00118 
00119     emit finished(this);
00120 }
00121 
00122 //protected:
00123 
00124 void Tutorial::setTutorialInformation(
00125                                     TutorialInformation* tutorialInformation) {
00126     d->mTutorialInformation = tutorialInformation;
00127 }
00128 
00129 void Tutorial::setup() {
00130 }
00131 
00132 void Tutorial::tearDown() {
00133 }
00134 
00135 //private:
00136 
00137 void Tutorial::changeToStep(Step* step) {
00138     if (d->mSteps.key(step).isEmpty()) {
00139         kError(debugArea()) << "Activate step" << step->id()
00140                             << "which doesn't belong to tutorial"
00141                             << d->mTutorialInformation->id();
00142         return;
00143     }
00144 
00145     if (d->mCurrentStep != 0) {
00146         d->mCurrentStep->setActive(false);
00147     }
00148 
00149     kDebug(debugArea()) << "Next step:" << step->id();
00150 
00151     d->mCurrentStep = step;
00152     d->mCurrentStep->setActive(true);
00153 
00154     emit stepActivated(step);
00155 }
00156 
00157 }