KTutorial  0.5.1
Step.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) 2012 by Daniel Calviño Sánchez <danxuliu@gmail.com>     *
00006  *                                                                         *
00007  *   This program is free software; you can redistribute it and/or modify  *
00008  *   it under the terms of the GNU General Public License as published by  *
00009  *   the Free Software Foundation; either version 2 of the License, or     *
00010  *   (at your option) any later version.                                   *
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 General Public License for more details.                          *
00016  *                                                                         *
00017  *   You should have received a copy of the GNU General Public License     *
00018  *   along with this program; If not, see <http://www.gnu.org/licenses/>.  *
00019  ***************************************************************************/
00020 
00021 #include "Step.h"
00022 #include "Step_p.h"
00023 
00024 #include <KDebug>
00025 
00026 #include "Option.h"
00027 #include "WaitFor.h"
00028 #include "WaitForSignal.h"
00029 
00030 namespace ktutorial {
00031 extern int debugArea();
00032 }
00033 
00034 namespace ktutorial {
00035 
00036 //public:
00037 
00038 Step::Step(const QString& id): QObject(),
00039     d(new StepPrivate()) {
00040     d->mId = id;
00041     d->mActive = false;
00042     d->mDeleteAddedObjectsInTearDown = false;
00043 }
00044 
00045 Step::~Step() {
00046     delete d;
00047 }
00048 
00049 QString Step::id() const {
00050     return d->mId;
00051 }
00052 
00053 QList<Option*> Step::options() const {
00054     return d->mOptions;
00055 }
00056 
00057 QString Step::text() const {
00058     return d->mText;
00059 }
00060 
00061 void Step::setText(const QString& text) {
00062     d->mText = text;
00063 }
00064 
00065 bool Step::isActive() const {
00066     return d->mActive;
00067 }
00068 
00069 void Step::setActive(bool active) {
00070     if (active) {
00071         setupWrapper();
00072     } else {
00073         tearDownWrapper();
00074     }
00075 
00076     d->mActive = active;
00077 
00078     QListIterator<WaitFor*> it(d->mWaitsFor);
00079     while (it.hasNext()) {
00080         it.next()->setActive(active);
00081     }
00082 }
00083 
00084 void Step::addOption(Option* option, QObject* receiver, const QString& slot) {
00085     if (!addOption(option)) {
00086         return;
00087     }
00088 
00089     bool deleteAddedObjectsInTearDownValue = d->mDeleteAddedObjectsInTearDown;
00090     d->mDeleteAddedObjectsInTearDown = false;
00091 
00092     WaitForSignal* waitFor = new WaitForSignal(option, SIGNAL(selected()));
00093     addWaitFor(waitFor, receiver, slot);
00094 
00095     d->mOptionsWaitsFor.append(waitFor);
00096 
00097     d->mDeleteAddedObjectsInTearDown = deleteAddedObjectsInTearDownValue;
00098 }
00099 
00100 void Step::addOption(Option* option, const QString& nextStepId) {
00101     if (!addOption(option)) {
00102         return;
00103     }
00104 
00105     bool deleteAddedObjectsInTearDownValue = d->mDeleteAddedObjectsInTearDown;
00106     d->mDeleteAddedObjectsInTearDown = false;
00107 
00108     WaitForSignal* waitFor = new WaitForSignal(option, SIGNAL(selected()));
00109     addWaitFor(waitFor, nextStepId);
00110 
00111     d->mOptionsWaitsFor.append(waitFor);
00112 
00113     d->mDeleteAddedObjectsInTearDown = deleteAddedObjectsInTearDownValue;
00114 }
00115 
00116 void Step::addWaitFor(WaitFor* waitFor, QObject* receiver, const QString& slot) {
00117     if (!addWaitFor(waitFor)) {
00118         return;
00119     }
00120 
00121     connectWaitFor(waitFor, receiver, slot);
00122 }
00123 
00124 void Step::addWaitFor(WaitFor* waitFor, const QString& nextStepId) {
00125     if (!addWaitFor(waitFor)) {
00126         return;
00127     }
00128 
00129     d->mNextStepForWaitFor.insert(waitFor, nextStepId);
00130 
00131     connect(waitFor, SIGNAL(waitEnded(WaitFor*)),
00132             this, SLOT(requestNextStepForWaitFor(WaitFor*)));
00133 }
00134 
00135 void Step::removeOption(Option* option) {
00136     if (!d->mOptions.contains(option)) {
00137         kWarning(debugArea()) << "Tried to remove an Option not added in step"
00138                               << d->mId;
00139         return;
00140     }
00141 
00142     option->setParent(0);
00143 
00144     int index = d->mOptions.indexOf(option);
00145     d->mOptions.removeAt(index);
00146 
00147     WaitFor* waitFor = d->mOptionsWaitsFor[index];
00148     removeWaitFor(waitFor);
00149 
00150     d->mOptionsWaitsFor.removeAt(index);
00151     delete waitFor;
00152 }
00153 
00154 void Step::removeWaitFor(WaitFor* waitFor) {
00155     if (!d->mWaitsFor.contains(waitFor)) {
00156         kWarning(debugArea()) << "Tried to remove a WaitFor not added in step"
00157                               << d->mId;
00158         return;
00159     }
00160 
00161     waitFor->setActive(false);
00162 
00163     waitFor->setParent(0);
00164 
00165     d->mWaitsFor.removeAt(d->mWaitsFor.indexOf(waitFor));
00166     disconnectWaitFor(waitFor);
00167 
00168     if (d->mNextStepForWaitFor.contains(waitFor)) {
00169         d->mNextStepForWaitFor.remove(waitFor);
00170         disconnect(waitFor, SIGNAL(waitEnded(WaitFor*)),
00171                    this, SLOT(requestNextStepForWaitFor(WaitFor*)));
00172     }
00173 }
00174 
00175 //protected:
00176 
00177 void Step::setup() {
00178 }
00179 
00180 void Step::tearDown() {
00181 }
00182 
00183 void Step::connectWaitFor(WaitFor* waitFor, QObject* receiver,
00184                           const QString& slot) {
00185     QString slotName = slot;
00186     if (!slotName.startsWith('1')) {
00187         slotName = QString("1%1").arg(slot);
00188     }
00189 
00190     connect(waitFor, SIGNAL(waitEnded(WaitFor*)),
00191             receiver, slotName.toLatin1());
00192 }
00193 
00194 void Step::disconnectWaitFor(WaitFor* waitFor) {
00195     disconnect(waitFor, SIGNAL(waitEnded(WaitFor*)), 0, 0);
00196 }
00197 
00198 //private:
00199 
00200 void Step::setupWrapper() {
00201     d->mDeleteAddedObjectsInTearDown = true;
00202     setup();
00203     d->mDeleteAddedObjectsInTearDown = false;
00204 }
00205 
00206 void Step::tearDownWrapper() {
00207     tearDown();
00208 
00209     foreach (Option* option, d->mOptionsToBeDeletedInTearDown) {
00210         removeOption(option);
00211         delete option;
00212     }
00213     d->mOptionsToBeDeletedInTearDown.clear();
00214 
00215     foreach (WaitFor* waitFor, d->mWaitsForToBeDeletedInTearDown) {
00216         removeWaitFor(waitFor);
00217         delete waitFor;
00218     }
00219     d->mWaitsForToBeDeletedInTearDown.clear();
00220 }
00221 
00222 bool Step::addOption(Option* option) {
00223     if (d->mOptions.contains(option)) {
00224         kWarning(debugArea()) << "Option" << option->name()
00225                               << "already added in step" << d->mId;
00226         return false;
00227     }
00228 
00229     QListIterator<Option*> it(d->mOptions);
00230     while (it.hasNext()) {
00231         if (it.next()->name() == option->name()) {
00232             kWarning(debugArea()) << "Option named" << option->name()
00233                                   << "already added in step" << d->mId;
00234             return false;
00235         }
00236     }
00237 
00238     option->setParent(this);
00239 
00240     d->mOptions.append(option);
00241 
00242     if (d->mDeleteAddedObjectsInTearDown) {
00243         d->mOptionsToBeDeletedInTearDown.append(option);
00244     }
00245 
00246     return true;
00247 }
00248 
00249 bool Step::addWaitFor(WaitFor* waitFor) {
00250     if (d->mWaitsFor.contains(waitFor)) {
00251         kWarning(debugArea()) << "Same WaitFor already added in step" << d->mId;
00252         return false;
00253     }
00254 
00255     waitFor->setActive(false);
00256 
00257     waitFor->setParent(this);
00258 
00259     d->mWaitsFor.append(waitFor);
00260 
00261     if (d->mDeleteAddedObjectsInTearDown) {
00262         d->mWaitsForToBeDeletedInTearDown.append(waitFor);
00263     }
00264 
00265     return true;
00266 }
00267 
00268 //private slots:
00269 
00270 void Step::requestNextStepForWaitFor(WaitFor* waitFor) {
00271     emit nextStepRequested(d->mNextStepForWaitFor.value(waitFor));
00272 }
00273 
00274 }