KTutorial  0.5.1
UsingKTutorial.cpp
00001 /***************************************************************************
00002  *   Copyright (C) 2010 by Daniel Calviño Sánchez <danxuliu@gmail.com>     *
00003  *   Copyright (C) 2012 by Daniel Calviño Sánchez <danxuliu@gmail.com>     *
00004  *                                                                         *
00005  *   This program is free software; you can redistribute it and/or modify  *
00006  *   it under the terms of the GNU General Public License as published by  *
00007  *   the Free Software Foundation; either version 2 of the License, or     *
00008  *   (at your option) any later version.                                   *
00009  *                                                                         *
00010  *   This program is distributed in the hope that it will be useful,       *
00011  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00012  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00013  *   GNU General Public License for more details.                          *
00014  *                                                                         *
00015  *   You should have received a copy of the GNU General Public License     *
00016  *   along with this program; If not, see <http://www.gnu.org/licenses/>.  *
00017  ***************************************************************************/
00018 
00019 #include "UsingKTutorial.h"
00020 
00021 #include <QMouseEvent>
00022 
00023 #include <KLocalizedString>
00024 #include <KTextEdit>
00025 
00026 #include "../KTutorial.h"
00027 #include "../Option.h"
00028 #include "../Step.h"
00029 #include "../TutorialInformation.h"
00030 #include "../WaitForEvent.h"
00031 #include "../WaitForSignal.h"
00032 #include "../view/StepTextWidget.h"
00033 #include "../view/StepWidget.h"
00034 
00035 namespace ktutorial {
00036 
00037 class WaitForLeftMouseButtonPressed: public WaitForEvent {
00038 Q_OBJECT
00039 public:
00040 
00041     WaitForLeftMouseButtonPressed(QObject* object):
00042             WaitForEvent(object, QEvent::MouseButtonPress) {
00043     }
00044 
00045 protected:
00046 
00047     virtual void handleEvent(QEvent* event) {
00048         QMouseEvent* mouseEvent = static_cast<QMouseEvent*>(event);
00049         if (mouseEvent->button() == Qt::LeftButton) {
00050             WaitForEvent::handleEvent(event);
00051         }
00052     }
00053 
00054 };
00055 
00056 class ClearTextStep: public Step {
00057 public:
00058 
00059     ClearTextStep(UsingKTutorial* usingKTutorial):
00060             Step("clearText"),
00061         mUsingKTutorial(usingKTutorial) {
00062     }
00063 
00064     virtual void setup() {
00065         QTextEdit* textEdit = //krazy:exclude=qclasses
00066                     new KTextEdit(KTutorial::self()->mainApplicationWindow());
00067         textEdit->setAttribute(Qt::WA_DeleteOnClose);
00068         textEdit->setWindowFlags(Qt::Window | Qt::WindowStaysOnTopHint);
00069         textEdit->setObjectName("usingKTutorialTextEdit");
00070         textEdit->setText(i18nc("@info/plain Plain text in a KTextEdit",
00071                                 "Look at me! I am the text area!"));
00072         textEdit->show();
00073 
00074         addWaitFor(new WaitForSignal(textEdit, SIGNAL(textChanged())),
00075                    mUsingKTutorial, SLOT(clearTextTextModified()));
00076     }
00077 
00078 private:
00079 
00080     UsingKTutorial* mUsingKTutorial;
00081 
00082 };
00083 
00084 class HighlightTextEditStep: public Step {
00085 Q_OBJECT
00086 public:
00087 
00088     HighlightTextEditStep():
00089             Step("highlightTextEdit") {
00090     }
00091 
00092     virtual void setup() {
00093         KTextEdit* textEdit = KTutorial::self()->findObject<KTextEdit*>(
00094                                                     "usingKTutorialTextEdit");
00095 
00096         addWaitFor(new WaitForEvent(textEdit, QEvent::Close),
00097                    "moveWidgetPress");
00098     }
00099 
00100 };
00101 
00102 class MoveWidgetPressStep: public Step {
00103 Q_OBJECT
00104 public:
00105 
00106     MoveWidgetPressStep():
00107             Step("moveWidgetPress") {
00108     }
00109 
00110     virtual void setup() {
00111         QWidget* mStepWidget = KTutorial::self()->
00112                         findObject<view::StepWidget*>("ktutorial_StepWidget");
00113 
00114         addWaitFor(new WaitForLeftMouseButtonPressed(mStepWidget),
00115                    "moveWidgetRelease");
00116     }
00117 
00118 };
00119 
00120 class MoveWidgetReleaseStep: public Step {
00121 Q_OBJECT
00122 public:
00123 
00124     MoveWidgetReleaseStep():
00125             Step("moveWidgetRelease") {
00126     }
00127 
00128     virtual void setup() {
00129         QWidget* mStepWidget = KTutorial::self()->
00130                         findObject<view::StepWidget*>("ktutorial_StepWidget");
00131 
00132         addWaitFor(new WaitForEvent(mStepWidget, QEvent::MouseButtonRelease),
00133                    "end");
00134     }
00135 
00136 };
00137 
00138 //public:
00139 
00140 UsingKTutorial::UsingKTutorial(): Tutorial(0) {
00141     TutorialInformation* tutorialInformation =
00142                                     new TutorialInformation("usingKTutorial");
00143     tutorialInformation->setName(i18nc("@info/plain", "Using the tutorials"));
00144     tutorialInformation->setDescription(i18nc("@info/plain", "This tutorial "
00145                                                "shows how the tutorial system "
00146                                                "works"));
00147     setTutorialInformation(tutorialInformation);
00148 
00149     //Step start
00150     Step* startStep = new Step("start");
00151     startStep->setText(i18nc("@info",
00152 "<para>Welcome to the tutorial to learn how to use tutorials ;)</para>"
00153 "<para>But, what is a tutorial? A tutorial is a little guide to help you to "
00154 "learn how to use an application. For example, it shows you how some feature "
00155 "works, or how to accomplish some task.</para>"));
00156 
00157     startStep->addOption(new Option(i18nc("@action", "Continue")),
00158                          "singleOption");
00159 
00160     addStep(startStep);
00161 
00162     //Step singleOption
00163     Step* singleOptionStep = new Step("singleOption");
00164     singleOptionStep->setText(i18nc("@info",
00165 "<para>A tutorial is composed of several steps. Each step contains a bit of "
00166 "information.</para>"
00167 "<para>There are several ways to advance from one step to another. For "
00168 "example, clicking on the button below the tutorial will change to the next "
00169 "step.</para>"));
00170 
00171     singleOptionStep->addOption(new Option(i18nc("@action", "Continue")),
00172                                 "severalOptions");
00173 
00174     addStep(singleOptionStep);
00175 
00176     //Step severalOptions
00177     Step* severalOptionsStep = new Step("severalOptions");
00178     severalOptionsStep->setText(i18nc("@info",
00179 "<para>In other steps you may have more than one option to select. This can be "
00180 "used, for example, to follow one path or another in the tutorial, skip some "
00181 "part of the tutorial, etcetera. Which option do you prefer?</para>"));
00182 
00183     severalOptionsStep->addOption(new Option(i18nc("@action", "Option 1")),
00184                                   "option1Selected");
00185     severalOptionsStep->addOption(new Option(i18nc("@action", "Option 2")),
00186                                   "option2Selected");
00187 
00188     addStep(severalOptionsStep);
00189 
00190     //Step option1Selected
00191     Step* option1SelectedStep = new Step("option1Selected");
00192     option1SelectedStep->setText(i18nc("@info",
00193 "<para>You have selected <emphasis>%1</emphasis>. Do not worry, as this is "
00194 "just an example, selecting one option or the other makes no difference.</para>"
00195 "<para>In the next step you will learn the last way to advance from one step "
00196 "to another. To show this to you I will open a new window where text can be "
00197 "written.</para>", i18nc("@action", "Option 1")));
00198 
00199     option1SelectedStep->addOption(new Option(i18nc("@action", "Continue")),
00200                                    "clearText");
00201 
00202     addStep(option1SelectedStep);
00203 
00204     //Step option2Selected
00205     Step* option2SelectedStep = new Step("option2Selected");
00206     option2SelectedStep->setText(i18nc("@info",
00207 "<para>You have selected <emphasis>%1</emphasis>. Do not worry, as this is "
00208 "just an example, selecting one option or the other makes no difference.</para>"
00209 "<para>In the next step you will learn the last way to advance from one step "
00210 "to another. To show this to you I will open a new window where text can be "
00211 "written.</para>", i18nc("@action", "Option 2")));
00212 
00213     option2SelectedStep->addOption(new Option(i18nc("@action", "Continue")),
00214                                    "clearText");
00215 
00216     addStep(option2SelectedStep);
00217 
00218     //Step clearText
00219     Step* clearTextStep = new ClearTextStep(this);
00220     clearTextStep->setText(i18nc("@info",
00221 "<para>Do you see the new window that has appeared? Yes, the one that says "
00222 "that it is the text area. Well, the last way to advance from one step to "
00223 "another is just doing what you are asked for.</para>"
00224 "<para>In this case, empty the text area erasing all its text and once you "
00225 "have done it look again to the tutorial.</para>"));
00226 
00227     //WaitFor is added in step setup, as it has to create a QTextEdit when the
00228     //step is activated
00229 
00230     addStep(clearTextStep);
00231 
00232     //Step textCleared
00233     Step* textClearedStep = new Step("textCleared");
00234     textClearedStep->setText(i18nc("@info",
00235 "<para>Do you see? You are in a new step, but you did not tell the tutorial to "
00236 "continue to the next step, and neither you had to select between several "
00237 "options. The tutorial advanced automatically when you erased the text as "
00238 "requested. This will be the most common way to advance from one step to "
00239 "another.</para>"));
00240 
00241     textClearedStep->addOption(new Option(i18nc("@action", "Continue")),
00242                                "highlightTextEdit");
00243 
00244     addStep(textClearedStep);
00245 
00246     //Step highlightTextEdit
00247     //As changing to another step stops the highlighting in the currently
00248     //highlighted widget, it is not possible to use one step to show how to
00249     //highlight the widget and the next one to show how to stop highlighting it
00250     Step* highlightTextEditStep = new HighlightTextEditStep();
00251     highlightTextEditStep->setText(i18nc("@info",
00252 "<para>Sometimes, a tutorial may provide a link to a <emphasis>widget"
00253 "</emphasis> (an element of the graphical user interface, like a button). For "
00254 "example, <link url=\"widget:usingKTutorialTextEdit\">this is a link to the "
00255 "text area</link>.</para>"
00256 "<para>When you click on a link to a widget, the widget is highlighted to help "
00257 "you to spot it. If you click again on it, the highlighting will be stopped. "
00258 "In this example it is pretty clear what the text area refers to, but it can "
00259 "be useful in tutorials for more complex applications.</para>"
00260 "<para>Ok, close the window with the text area to continue with the "
00261 "tutorial.</para>"));
00262 
00263     //WaitFor is added in step setup, as it uses an object that isn't available
00264     //when the tutorial is created
00265 
00266     addStep(highlightTextEditStep);
00267 
00268     //Step moveWidgetPress
00269     Step* moveWidgetPressStep = new MoveWidgetPressStep();
00270     moveWidgetPressStep->setText(i18nc("@info",
00271 "<para>You may have noticed that the tutorial window has no border. Does that "
00272 "mean that it can not be moved? Not at all. It can be dragged using the mouse "
00273 "like any other window, but pressing in a different place. Let's see "
00274 "how.</para>"
00275 "<para>Above these paragraphs you can see an empty space, next to the button "
00276 "at the corner. Press with the left button of your mouse on that empty space. "
00277 "Just press, do not release the mouse button yet.</para>"));
00278 
00279     //WaitFor is added in step setup, as it uses an object that isn't available
00280     //when the tutorial is created
00281 
00282     addStep(moveWidgetPressStep);
00283 
00284     //Step moveWidgetRelease
00285     Step* moveWidgetReleaseStep = new MoveWidgetReleaseStep();
00286     moveWidgetReleaseStep->setText(i18nc("@info",
00287 "<para>Now, and without releasing the button, move the mouse and the window "
00288 "will be moved. Once you release the button, the window will be kept in the "
00289 "place it was. Of course, you can move it again dragging it like you "
00290 "have just done.</para>"));
00291 
00292     //WaitFor is added in step setup, as it uses an object that isn't available
00293     //when the tutorial is created
00294 
00295     addStep(moveWidgetReleaseStep);
00296 
00297     //Step end
00298     Step* endStep = new Step("end");
00299     endStep->setText(i18nc("@info",
00300 "<para>And that's all. You can now close the tutorial. In fact, you could have "
00301 "closed the tutorial in any other of the previous steps, but if you do that "
00302 "when the tutorial is started again it will not remember what you did. It will "
00303 "start from the beginning again.</para>"
00304 "<para>But how do you close the tutorial? Well, do you see that button above "
00305 "this text, in the corner, with an icon that looks like a close icon? Do you "
00306 "guess what it does? ;) Just click on it and you will return to the tutorial "
00307 "selection dialog. Bye!</para>"));
00308 
00309     addStep(endStep);
00310 }
00311 
00312 //public slots:
00313 
00314 void UsingKTutorial::clearTextTextModified() {
00315     KTextEdit* textEdit = KTutorial::self()->
00316                             findObject<KTextEdit*>("usingKTutorialTextEdit");
00317 
00318     if (textEdit->toPlainText().isEmpty()) {
00319         nextStep("textCleared");
00320     }
00321 }
00322 
00323 //protected:
00324 
00325 void UsingKTutorial::tearDown() {
00326     KTextEdit* textEdit = KTutorial::self()->findObject<KTextEdit*>(
00327                                                     "usingKTutorialTextEdit");
00328     if (textEdit) {
00329         textEdit->deleteLater();
00330     }
00331 }
00332 
00333 }
00334 
00335 #include "moc_UsingKTutorial.cpp"
00336 #include "UsingKTutorial.moc"