[Ktutorial-commits] SF.net SVN: ktutorial:[238] trunk/ktutorial/ktutorial-library
Status: Alpha
Brought to you by:
danxuliu
|
From: <dan...@us...> - 2010-05-11 03:39:01
|
Revision: 238
http://ktutorial.svn.sourceforge.net/ktutorial/?rev=238&view=rev
Author: danxuliu
Date: 2010-05-11 03:38:55 +0000 (Tue, 11 May 2010)
Log Message:
-----------
Add StepTextWidget to show the text of a step. HTML links in the text with the format "widget:nameOfTheWidget" can be used to highlight the referenced widget when a tutorial is being executed.
Modified Paths:
--------------
trunk/ktutorial/ktutorial-library/src/view/CMakeLists.txt
trunk/ktutorial/ktutorial-library/src/view/StepWidget.cpp
trunk/ktutorial/ktutorial-library/src/view/StepWidget.ui
trunk/ktutorial/ktutorial-library/tests/view/CMakeLists.txt
trunk/ktutorial/ktutorial-library/tests/view/StepWidgetTest.cpp
Added Paths:
-----------
trunk/ktutorial/ktutorial-library/src/view/StepTextWidget.cpp
trunk/ktutorial/ktutorial-library/src/view/StepTextWidget.h
trunk/ktutorial/ktutorial-library/tests/view/StepTextWidgetTest.cpp
Modified: trunk/ktutorial/ktutorial-library/src/view/CMakeLists.txt
===================================================================
--- trunk/ktutorial/ktutorial-library/src/view/CMakeLists.txt 2010-04-26 05:30:40 UTC (rev 237)
+++ trunk/ktutorial/ktutorial-library/src/view/CMakeLists.txt 2010-05-11 03:38:55 UTC (rev 238)
@@ -1,6 +1,7 @@
-include_directories(${CMAKE_CURRENT_BINARY_DIR} ${KDE4_INCLUDES})
+include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ${KDE4_INCLUDES})
set(ktutorial_view_SRCS
+ StepTextWidget.cpp
StepWidget.cpp
TutorialListModel.cpp
TutorialManagerDialog.cpp
@@ -13,4 +14,4 @@
kde4_add_library(ktutorial_view ${ktutorial_view_SRCS})
-target_link_libraries(ktutorial_view ${KDE4_KDEUI_LIBS})
+target_link_libraries(ktutorial_view ktutorial_extendedinformation ${KDE4_KDEUI_LIBS})
Added: trunk/ktutorial/ktutorial-library/src/view/StepTextWidget.cpp
===================================================================
--- trunk/ktutorial/ktutorial-library/src/view/StepTextWidget.cpp (rev 0)
+++ trunk/ktutorial/ktutorial-library/src/view/StepTextWidget.cpp 2010-05-11 03:38:55 UTC (rev 238)
@@ -0,0 +1,208 @@
+/***************************************************************************
+ * Copyright (C) 2010 by Daniel Calviño Sánchez *
+ * dan...@gm... *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 3 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; If not, see <http://www.gnu.org/licenses/>. *
+ ***************************************************************************/
+
+#include <QContextMenuEvent>
+#include <QMenu>
+
+#include <KDebug>
+#include <KLocalizedString>
+
+#include "StepTextWidget.h"
+#include "../KTutorial.h"
+#include "../extendedinformation/WidgetHighlighterManager.h"
+
+using extendedinformation::WidgetHighlighterManager;
+
+namespace view {
+
+//public:
+
+StepTextWidget::StepTextWidget(QWidget* parent /*= 0*/):
+ KTextEdit(parent),
+ mCurrentHighlightedWidget(0) {
+ setReadOnly(true);
+ setFrameShape(QFrame::NoFrame);
+ setFrameShadow(QFrame::Plain);
+ setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+ setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+
+ viewport()->setCursor(Qt::ArrowCursor);
+
+ QPalette palette = this->palette();
+ palette.setColor(QPalette::Base, Qt::transparent);
+ setPalette(palette);
+
+ setAlignment(Qt::AlignJustify | Qt::AlignVCenter);
+
+ //Set a explicit text width to avoid some strange behavior: if the text
+ //width is set to QWIDGETSIZE_MAX without a previous text width set, the
+ //size returned by the document has weird values. Anyway, sizeHint is
+ //usually called before minimumSizeHint, so a text width will be already set
+ //when minimumSizeHint is called, but just in case.
+ document()->setTextWidth(0);
+
+ connect(this, SIGNAL(textChanged()), this, SLOT(updateText()));
+}
+
+bool StepTextWidget::eventFilter(QObject* watched, QEvent* event) {
+ if (watched != mCurrentHighlightedWidget) {
+ return false;
+ }
+
+ if (event->type() != QEvent::FocusIn) {
+ return false;
+ }
+
+ stopHighlightingCurrentWidget();
+
+ return false;
+}
+
+int StepTextWidget::heightForWidth(int width) const {
+ return sizeForWidth(width).height();
+}
+
+QSize StepTextWidget::minimumSizeHint() const {
+ QSize size;
+ size.setHeight(sizeForWidth(QWIDGETSIZE_MAX).height());
+ size.setWidth(sizeForWidth(0).width());
+
+ return size;
+}
+
+QSize StepTextWidget::sizeHint() const {
+ return sizeForWidth(-1);
+}
+
+//protected:
+
+void StepTextWidget::contextMenuEvent(QContextMenuEvent* event) {
+ QString anchor = anchorAt(event->pos());
+ if (!anchor.startsWith(QLatin1String("widget:"))) {
+ KTextEdit::contextMenuEvent(event);
+ return;
+ }
+
+ QMenu* menu = new QMenu(this);
+
+ if (mCurrentHighlightedWidget &&
+ mCurrentHighlightedWidget != widgetForAnchor(anchor)) {
+ stopHighlightingCurrentWidget();
+ }
+
+ if (!mCurrentHighlightedWidget) {
+ menu->addAction(i18nc("@item:inmenu", "Highlight"),
+ this, SLOT(highlightCurrentWidget()));
+
+ mCurrentHighlightedWidget = widgetForAnchor(anchor);
+ } else {
+ menu->addAction(i18nc("@item:inmenu", "Stop highlighting"),
+ this, SLOT(stopHighlightingCurrentWidget()));
+ }
+
+ menu->exec(event->globalPos());
+ delete menu;
+}
+
+void StepTextWidget::mouseMoveEvent(QMouseEvent* event) {
+ KTextEdit::mouseMoveEvent(event);
+
+ if (anchorAt(event->pos()).startsWith(QLatin1String("widget:"))) {
+ viewport()->setCursor(Qt::PointingHandCursor);
+ } else {
+ viewport()->setCursor(Qt::ArrowCursor);
+ }
+}
+
+void StepTextWidget::mousePressEvent(QMouseEvent* event) {
+ QString anchor = anchorAt(event->pos());
+ if (event->button() != Qt::LeftButton ||
+ !anchor.startsWith(QLatin1String("widget:"))) {
+ KTextEdit::mousePressEvent(event);
+ return;
+ }
+
+ if (mCurrentHighlightedWidget &&
+ mCurrentHighlightedWidget != widgetForAnchor(anchor)) {
+ stopHighlightingCurrentWidget();
+ }
+
+ if (!mCurrentHighlightedWidget) {
+ mCurrentHighlightedWidget = widgetForAnchor(anchor);
+
+ highlightCurrentWidget();
+ } else {
+ stopHighlightingCurrentWidget();
+ }
+}
+
+//private:
+
+QSize StepTextWidget::sizeForWidth(int width) const {
+ const qreal oldTextWidth = document()->textWidth();
+
+ if (width >= 0) {
+ document()->setTextWidth(width);
+ } else {
+ document()->adjustSize();
+ }
+
+ QSize size = document()->size().toSize();
+
+ document()->setTextWidth(oldTextWidth);
+
+ return size;
+}
+
+QWidget* StepTextWidget::widgetForAnchor(const QString& anchor) {
+ QString widgetName = anchor.mid(QString("widget:").length());
+ return KTutorial::self()->findObject<QWidget*>(widgetName);
+}
+
+//private slots:
+
+void StepTextWidget::updateText() {
+ updateGeometry();
+
+ if (mCurrentHighlightedWidget) {
+ stopHighlightingCurrentWidget();
+ }
+}
+
+void StepTextWidget::highlightCurrentWidget() {
+ if (!mCurrentHighlightedWidget) {
+ kWarning() << "The widget to highlight was not found!";
+ }
+
+ WidgetHighlighterManager::self()->highlight(mCurrentHighlightedWidget);
+
+ mCurrentHighlightedWidget->installEventFilter(this);
+}
+
+void StepTextWidget::stopHighlightingCurrentWidget() {
+ if (!mCurrentHighlightedWidget) {
+ kWarning() << "The widget to stop highlighting was not found!";
+ }
+
+ WidgetHighlighterManager::self()->stopHighlighting(mCurrentHighlightedWidget);
+
+ mCurrentHighlightedWidget->removeEventFilter(this);
+ mCurrentHighlightedWidget = 0;
+}
+
+}
Property changes on: trunk/ktutorial/ktutorial-library/src/view/StepTextWidget.cpp
___________________________________________________________________
Added: svn:eol-style
+ native
Added: trunk/ktutorial/ktutorial-library/src/view/StepTextWidget.h
===================================================================
--- trunk/ktutorial/ktutorial-library/src/view/StepTextWidget.h (rev 0)
+++ trunk/ktutorial/ktutorial-library/src/view/StepTextWidget.h 2010-05-11 03:38:55 UTC (rev 238)
@@ -0,0 +1,181 @@
+/***************************************************************************
+ * Copyright (C) 2010 by Daniel Calviño Sánchez *
+ * dan...@gm... *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 3 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; If not, see <http://www.gnu.org/licenses/>. *
+ ***************************************************************************/
+
+#ifndef VIEW_STEPTEXTWIDGET_H
+#define VIEW_STEPTEXTWIDGET_H
+
+#include <KTextEdit>
+
+namespace view {
+
+/**
+ * A TextEdit with the appearance of a label to show the text of a step.
+ * It behaves like a QLabel with custom behavior for links. However, as QLabel
+ * doesn't provide a way to easily extend its link related behavior, a KTextEdit
+ * with a QLabel appearance (read only, size fit to text, no scroll bars...) is
+ * used instead.
+ *
+ * Links that exhibit a custom behavior are those with the format
+ * "widget:nameOfTheWidget". When the link is pressed with the left mouse
+ * button, the widget with the specified name is highlighted. When it is pressed
+ * again, the highlighting is stopped. If the right button is pressed, a context
+ * menu with an item to highlight or stop highlighting is shown.
+ *
+ * If a widget was being highlighted when the highglighting is started in
+ * another widget, the highlighting in the previous widget is stopped. The
+ * highlighting is also stopped when the widget gets the focus, or when the text
+ * is changed in the StepTextWidget.
+ *
+ * When the mouse cursor is moved over a "widget:" link, the arrow cursor is
+ * changed to a pointing hand cursor.
+ *
+ * The links are specified using HTML markup, for example,
+ * <a href="widget:theNameOfTheWidget">the text of the link</a>
+ */
+class StepTextWidget: public KTextEdit {
+Q_OBJECT
+public:
+
+ /**
+ * Creates a new StepTextWidget.
+ *
+ * @param parent The parent widget.
+ */
+ explicit StepTextWidget(QWidget* parent = 0);
+
+ /**
+ * Watches the widget currently being highlighted and stops the highlighting
+ * when it is focused.
+ *
+ * @param watched The filtered object that received an event.
+ * @param event The event received.
+ * @return False, to allow the event to be handled further.
+ */
+ virtual bool eventFilter(QObject* watched, QEvent* event);
+
+ /**
+ * Returns the height of the size for the given width.
+ *
+ * @param width The width to get its height.
+ * @return The height for the width.
+ */
+ virtual int heightForWidth(int width) const;
+
+ /**
+ * Returns the recommended minimum size for this StepTextWidget.
+ * The size has the width of the longest word in the text and the height of
+ * a single line.
+ *
+ * @return The recommended minimum size.
+ */
+ virtual QSize minimumSizeHint() const;
+
+ /**
+ * Returns the recommended size for this StepTextWidget.
+ * The size is adjusted to fit the text as a rectangle, with a width bigger
+ * then the height.
+ *
+ * @return The recommended size.
+ */
+ virtual QSize sizeHint() const;
+
+protected:
+
+ /**
+ * Shows a custom context menu when a context menu is requested on a
+ * "widget:" anchor.
+ * The context menu will contain a "Stop highlighting" or a "Highlight" item
+ * depending on whether the widget is the one currently being highlighted or
+ * not. If the widget currently being highlighted is another one, it is
+ * stopped.
+ *
+ * @param event The context menu event.
+ */
+ virtual void contextMenuEvent(QContextMenuEvent* event);
+
+ /**
+ * Changes the cursor to a pointing hand when it is over a "widget:" anchor.
+ *
+ * @param event The mouse move event.
+ */
+ virtual void mouseMoveEvent(QMouseEvent* event);
+
+ /**
+ * When the mouse is pressed on a "widget:" anchor, it is highlighted or
+ * stopped being highlighted.
+ * If the widget currently being highlighted is another one, it is stopped.
+ *
+ * @param event The mouse press event.
+ */
+ virtual void mousePressEvent(QMouseEvent* event);
+
+private:
+
+ /**
+ * The widget currently being highlighted as a result of activating a link
+ * in this StepTextWidget.
+ */
+ QWidget* mCurrentHighlightedWidget;
+
+ /**
+ * Returns the size for the given text width.
+ * If the width is < 0, the size is adjusted to the text as a rectangle,
+ * with a width bigger than the height.
+ * If the width is >= 0, the size is the given width and a height bigger
+ * enough to show the whole text. The width may be bigger than the given one
+ * if the given one is not big enough to show the longest word in the text.
+ *
+ * @param width The width to get its size.
+ * @return The size for the width.
+ */
+ QSize sizeForWidth(int width) const;
+
+ /**
+ * Returns the widget referenced in the given anchor.
+ * The anchor must have a "widget:name" format. The widget is looked for
+ * using its name in KTutorial::findObject(QString).
+ *
+ * @param anchor The anchor to get its widget.
+ * @return The widget referenced in the anchor.
+ */
+ QWidget* widgetForAnchor(const QString& anchor);
+
+private Q_SLOTS:
+
+ /**
+ * Notifies the layout that the geometry of the widget has changed and stops
+ * the highlighting of the current widget, if any.
+ */
+ void updateText();
+
+ /**
+ * Starts highlighting the current widget.
+ */
+ void highlightCurrentWidget();
+
+ /**
+ * Stops highlighting the current widget.
+ * The current widget is cleared.
+ */
+ void stopHighlightingCurrentWidget();
+
+};
+
+};
+
+#endif
Property changes on: trunk/ktutorial/ktutorial-library/src/view/StepTextWidget.h
___________________________________________________________________
Added: svn:eol-style
+ native
Modified: trunk/ktutorial/ktutorial-library/src/view/StepWidget.cpp
===================================================================
--- trunk/ktutorial/ktutorial-library/src/view/StepWidget.cpp 2010-04-26 05:30:40 UTC (rev 237)
+++ trunk/ktutorial/ktutorial-library/src/view/StepWidget.cpp 2010-05-11 03:38:55 UTC (rev 238)
@@ -65,7 +65,7 @@
//public slots:
void StepWidget::setStep(Step* step) {
- ui->textLabel->setText(step->text());
+ ui->textWidget->setText(step->text());
setOptions(step->options());
adjustSize();
Modified: trunk/ktutorial/ktutorial-library/src/view/StepWidget.ui
===================================================================
--- trunk/ktutorial/ktutorial-library/src/view/StepWidget.ui 2010-04-26 05:30:40 UTC (rev 237)
+++ trunk/ktutorial/ktutorial-library/src/view/StepWidget.ui 2010-05-11 03:38:55 UTC (rev 238)
@@ -1,7 +1,8 @@
-<ui version="4.0" >
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
<class>StepWidget</class>
- <widget class="QWidget" name="StepWidget" >
- <property name="geometry" >
+ <widget class="QWidget" name="StepWidget">
+ <property name="geometry">
<rect>
<x>0</x>
<y>0</y>
@@ -9,39 +10,30 @@
<height>306</height>
</rect>
</property>
- <layout class="QVBoxLayout" >
- <property name="spacing" >
+ <layout class="QVBoxLayout">
+ <property name="spacing">
<number>0</number>
</property>
- <property name="leftMargin" >
+ <property name="margin">
<number>4</number>
</property>
- <property name="topMargin" >
- <number>4</number>
- </property>
- <property name="rightMargin" >
- <number>4</number>
- </property>
- <property name="bottomMargin" >
- <number>4</number>
- </property>
<item>
- <layout class="QHBoxLayout" >
- <property name="spacing" >
+ <layout class="QHBoxLayout">
+ <property name="spacing">
<number>0</number>
</property>
- <property name="leftMargin" >
+ <property name="leftMargin">
<number>0</number>
</property>
- <property name="topMargin" >
+ <property name="topMargin">
<number>0</number>
</property>
<item>
<spacer>
- <property name="orientation" >
+ <property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
- <property name="sizeHint" >
+ <property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
@@ -50,17 +42,17 @@
</spacer>
</item>
<item>
- <widget class="KPushButton" name="closeButton" >
- <property name="focusPolicy" >
+ <widget class="KPushButton" name="closeButton">
+ <property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
- <property name="toolTip" >
- <string comment="@info:tooltip" >Close this tutorial</string>
+ <property name="toolTip">
+ <string comment="@info:tooltip">Close this tutorial</string>
</property>
- <property name="whatsThis" >
- <string comment="@info:whatsthis" >Click here to close the tutorial.<nl/>The tutorial can be closed when you have finished it, or at any time to cancel it.</string>
+ <property name="whatsThis">
+ <string comment="@info:whatsthis">Click here to close the tutorial.<nl/>The tutorial can be closed when you have finished it, or at any time to cancel it.</string>
</property>
- <property name="flat" >
+ <property name="flat">
<bool>true</bool>
</property>
</widget>
@@ -68,32 +60,23 @@
</layout>
</item>
<item>
- <widget class="QLabel" name="textLabel" >
- <property name="sizePolicy" >
- <sizepolicy vsizetype="MinimumExpanding" hsizetype="MinimumExpanding" >
+ <widget class="view::StepTextWidget" name="textWidget">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
- <property name="toolTip" >
- <string comment="@info:tooltip" >The instructions for this step</string>
+ <property name="toolTip">
+ <string comment="@info:tooltip">The instructions for this step</string>
</property>
- <property name="whatsThis" >
- <string comment="@info:whatsthis" >Here appear the instructions for each step of the tutorial.<nl/>Once you complete one step, a new step with new instructions will be shown.</string>
+ <property name="whatsThis">
+ <string comment="@info:whatsthis">Here appear the instructions for each step of the tutorial.<nl/>Once you complete one step, a new step with new instructions will be shown.</string>
</property>
- <property name="text" >
- <string/>
- </property>
- <property name="alignment" >
- <set>Qt::AlignJustify|Qt::AlignVCenter</set>
- </property>
- <property name="wordWrap" >
- <bool>true</bool>
- </property>
</widget>
</item>
<item>
- <widget class="QWidget" native="1" name="optionsWidget" />
+ <widget class="QWidget" name="optionsWidget" native="true"/>
</item>
</layout>
</widget>
@@ -103,6 +86,11 @@
<extends>QPushButton</extends>
<header>kpushbutton.h</header>
</customwidget>
+ <customwidget>
+ <class>view::StepTextWidget</class>
+ <extends>QTextEdit</extends>
+ <header>StepTextWidget.h</header>
+ </customwidget>
</customwidgets>
<resources/>
<connections/>
Modified: trunk/ktutorial/ktutorial-library/tests/view/CMakeLists.txt
===================================================================
--- trunk/ktutorial/ktutorial-library/tests/view/CMakeLists.txt 2010-04-26 05:30:40 UTC (rev 237)
+++ trunk/ktutorial/ktutorial-library/tests/view/CMakeLists.txt 2010-05-11 03:38:55 UTC (rev 238)
@@ -17,6 +17,7 @@
ENDMACRO(UNIT_TESTS)
unit_tests(
+ StepTextWidget
StepWidget
TutorialListModel
TutorialManagerDialog
@@ -29,6 +30,7 @@
ENDMACRO(MEM_TESTS)
mem_tests(
+ StepTextWidget
StepWidget
TutorialListModel
TutorialManagerDialog
Added: trunk/ktutorial/ktutorial-library/tests/view/StepTextWidgetTest.cpp
===================================================================
--- trunk/ktutorial/ktutorial-library/tests/view/StepTextWidgetTest.cpp (rev 0)
+++ trunk/ktutorial/ktutorial-library/tests/view/StepTextWidgetTest.cpp 2010-05-11 03:38:55 UTC (rev 238)
@@ -0,0 +1,365 @@
+/***************************************************************************
+ * Copyright (C) 2010 by Daniel Calviño Sánchez *
+ * dan...@gm... *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 3 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; If not, see <http://www.gnu.org/licenses/>. *
+ ***************************************************************************/
+
+#include <QtTest>
+#include <qtest_kde.h>
+
+#include <KXmlGuiWindow>
+
+#include "StepTextWidget.h"
+#define protected public
+#define private public
+#include "../KTutorial.h"
+#undef private
+#undef protected
+#include "../extendedinformation/WidgetHighlighter.h"
+
+using extendedinformation::WidgetHighlighter;
+
+namespace view {
+
+class StepTextWidgetTest: public QObject {
+Q_OBJECT
+public slots:
+
+ void selectFirstContextMenuOption();
+
+private slots:
+
+ void init();
+ void cleanup();
+
+ void testConstructor();
+
+ void testSizeHintWithBiggerText();
+ void testSizeHintWithSmallerText();
+
+ void testHighlightWidgetClickingOnAnchor();
+ void testStopHighlightingWidgetClickingOnAnchor();
+ void testHighlightWidgetUsingContextMenu();
+ void testStopHighlightingWidgetUsingContextMenu();
+ void testHighlightSeveralWidgets();
+
+ void testStopHighlightingWidgetWhenFocused();
+
+ void testSetTextWhenWidgetIsBeingHighlighted();
+
+private:
+
+ QPoint centerOfText(const StepTextWidget& widget, const QString& text);
+
+ void showContextMenuAndSelectFirstOption(const StepTextWidget& widget,
+ const QPoint& position);
+
+};
+
+void StepTextWidgetTest::init() {
+ delete KTutorial::sSelf;
+ KTutorial::sSelf = new KTutorial();
+}
+
+void StepTextWidgetTest::cleanup() {
+}
+
+void StepTextWidgetTest::testConstructor() {
+ QWidget parent;
+ StepTextWidget* widget = new StepTextWidget(&parent);
+
+ QCOMPARE(widget->parentWidget(), &parent);
+ QVERIFY(widget->isReadOnly());
+ QCOMPARE(widget->frameShape(), QFrame::NoFrame);
+ QCOMPARE(widget->frameShadow(), QFrame::Plain);
+ QCOMPARE(widget->horizontalScrollBarPolicy(), Qt::ScrollBarAlwaysOff);
+ QCOMPARE(widget->verticalScrollBarPolicy(), Qt::ScrollBarAlwaysOff);
+ QCOMPARE(widget->palette().color(QPalette::Base), QColor(Qt::transparent));
+}
+
+void StepTextWidgetTest::testSizeHintWithBiggerText() {
+ StepTextWidget widget;
+ widget.setText("Some short text");
+
+ QSize oldSizeHint = widget.sizeHint();
+
+ widget.setText("Some bigger text to be shown hopefully in several lines");
+
+ QSize newSizeHint = widget.sizeHint();
+ QCOMPARE(widget.heightForWidth(newSizeHint.width()), newSizeHint.height());
+ QVERIFY(newSizeHint.width() > newSizeHint.height());
+ QVERIFY(newSizeHint.height() > widget.minimumSizeHint().height());
+ QVERIFY(newSizeHint.width() > widget.minimumSizeHint().width());
+ QVERIFY(newSizeHint.height() > oldSizeHint.height());
+ QVERIFY(newSizeHint.width() > oldSizeHint.width());
+}
+
+void StepTextWidgetTest::testSizeHintWithSmallerText() {
+ StepTextWidget widget;
+ widget.setText("Some bigger text to be shown hopefully in several lines");
+
+ QSize oldSizeHint = widget.sizeHint();
+
+ widget.setText("Some short text");
+
+ QSize newSizeHint = widget.sizeHint();
+ QCOMPARE(widget.heightForWidth(newSizeHint.width()), newSizeHint.height());
+ QVERIFY(newSizeHint.width() > newSizeHint.height());
+ QVERIFY(newSizeHint.height() < oldSizeHint.height());
+ QVERIFY(newSizeHint.width() < oldSizeHint.width());
+}
+
+void StepTextWidgetTest::testHighlightWidgetClickingOnAnchor() {
+ KXmlGuiWindow mainWindow;
+ KTutorial::self()->setup(&mainWindow);
+ QWidget* widgetToHighlight = new QWidget(&mainWindow);
+ widgetToHighlight->setObjectName("widgetName");
+
+ StepTextWidget widget;
+ widget.setText("The <a href=\"widget:widgetName\">widget to highlight</a>");
+ widget.show();
+
+ QPoint position = centerOfText(widget, "widget to highlight");
+ QTest::mouseClick(widget.viewport(), Qt::LeftButton, Qt::NoModifier,
+ position, 500);
+
+ QVERIFY(widgetToHighlight->findChild<WidgetHighlighter*>(""));
+}
+
+void StepTextWidgetTest::testStopHighlightingWidgetClickingOnAnchor() {
+ KXmlGuiWindow mainWindow;
+ KTutorial::self()->setup(&mainWindow);
+ QWidget* widgetToHighlight = new QWidget(&mainWindow);
+ widgetToHighlight->setObjectName("widgetName");
+
+ StepTextWidget widget;
+ widget.setText("The <a href=\"widget:widgetName\">widget to highlight</a>");
+ widget.show();
+
+ QPoint position = centerOfText(widget, "widget to highlight");
+ QTest::mouseClick(widget.viewport(), Qt::LeftButton, Qt::NoModifier,
+ position, 500);
+ QTest::mouseClick(widget.viewport(), Qt::LeftButton, Qt::NoModifier,
+ position, 500);
+
+ //Give the highlighter time to stop
+ QTest::qWait(500);
+
+ QVERIFY(!widgetToHighlight->findChild<WidgetHighlighter*>(""));
+}
+
+void StepTextWidgetTest::testHighlightWidgetUsingContextMenu() {
+ KXmlGuiWindow mainWindow;
+ KTutorial::self()->setup(&mainWindow);
+ QWidget* widgetToHighlight = new QWidget(&mainWindow);
+ widgetToHighlight->setObjectName("widgetName");
+
+ StepTextWidget widget;
+ widget.setText("The <a href=\"widget:widgetName\">widget to highlight</a>");
+ widget.show();
+
+ //Give the widget time to be shown
+ QTest::qWait(500);
+
+ QPoint position = centerOfText(widget, "widget to highlight");
+ showContextMenuAndSelectFirstOption(widget, position);
+
+ QVERIFY(widgetToHighlight->findChild<WidgetHighlighter*>(""));
+}
+
+void StepTextWidgetTest::testStopHighlightingWidgetUsingContextMenu() {
+ KXmlGuiWindow mainWindow;
+ KTutorial::self()->setup(&mainWindow);
+ QWidget* widgetToHighlight = new QWidget(&mainWindow);
+ widgetToHighlight->setObjectName("widgetName");
+
+ StepTextWidget widget;
+ widget.setText("The <a href=\"widget:widgetName\">widget to highlight</a>");
+ widget.show();
+
+ //Give the widget time to be shown
+ QTest::qWait(500);
+
+ QPoint position = centerOfText(widget, "widget to highlight");
+ showContextMenuAndSelectFirstOption(widget, position);
+ QTest::qWait(500);
+ showContextMenuAndSelectFirstOption(widget, position);
+
+ //Give the highlighter time to stop
+ QTest::qWait(500);
+
+ QVERIFY(!widgetToHighlight->findChild<WidgetHighlighter*>(""));
+}
+
+void StepTextWidgetTest::testHighlightSeveralWidgets() {
+ KXmlGuiWindow mainWindow;
+ KTutorial::self()->setup(&mainWindow);
+ QWidget* widgetToHighlight1 = new QWidget(&mainWindow);
+ widgetToHighlight1->setObjectName("widget1");
+ QWidget* widgetToHighlight2 = new QWidget(&mainWindow);
+ widgetToHighlight2->setObjectName("widget2");
+ QWidget* widgetToHighlight3 = new QWidget(&mainWindow);
+ widgetToHighlight3->setObjectName("widget3");
+
+ StepTextWidget widget;
+ widget.setText("The <a href=\"widget:widget1\">first widget</a>, "
+"<a href=\"widget:widget2\">second widget</a> and "
+"<a href=\"widget:widget3\">third widget</a>");
+ widget.show();
+
+ QPoint position1 = centerOfText(widget, "first widget");
+ QPoint position2 = centerOfText(widget, "second widget");
+ QPoint position3 = centerOfText(widget, "third widget");
+
+ QTest::mouseClick(widget.viewport(), Qt::LeftButton, Qt::NoModifier,
+ position1, 500);
+ QTest::mouseClick(widget.viewport(), Qt::LeftButton, Qt::NoModifier,
+ position2, 500);
+
+ //Give the highlighter time to stop
+ QTest::qWait(500);
+
+ QVERIFY(!widgetToHighlight1->findChild<WidgetHighlighter*>(""));
+ QVERIFY(widgetToHighlight2->findChild<WidgetHighlighter*>(""));
+ QVERIFY(!widgetToHighlight3->findChild<WidgetHighlighter*>(""));
+
+ showContextMenuAndSelectFirstOption(widget, position3);
+
+ //Give the highlighter time to stop
+ QTest::qWait(500);
+
+ QVERIFY(!widgetToHighlight1->findChild<WidgetHighlighter*>(""));
+ QVERIFY(!widgetToHighlight2->findChild<WidgetHighlighter*>(""));
+ QVERIFY(widgetToHighlight3->findChild<WidgetHighlighter*>(""));
+
+ showContextMenuAndSelectFirstOption(widget, position1);
+
+ //Give the highlighter time to stop
+ QTest::qWait(500);
+
+ QVERIFY(widgetToHighlight1->findChild<WidgetHighlighter*>(""));
+ QVERIFY(!widgetToHighlight2->findChild<WidgetHighlighter*>(""));
+ QVERIFY(!widgetToHighlight3->findChild<WidgetHighlighter*>(""));
+
+ QTest::mouseClick(widget.viewport(), Qt::LeftButton, Qt::NoModifier,
+ position1, 500);
+
+ //Give the highlighter time to stop
+ QTest::qWait(500);
+
+ QVERIFY(!widgetToHighlight1->findChild<WidgetHighlighter*>(""));
+ QVERIFY(!widgetToHighlight2->findChild<WidgetHighlighter*>(""));
+ QVERIFY(!widgetToHighlight3->findChild<WidgetHighlighter*>(""));
+
+ QTest::mouseClick(widget.viewport(), Qt::LeftButton, Qt::NoModifier,
+ position2, 500);
+ QTest::qWait(500);
+ showContextMenuAndSelectFirstOption(widget, position2);
+
+ //Give the highlighter time to stop
+ QTest::qWait(500);
+
+ QVERIFY(!widgetToHighlight1->findChild<WidgetHighlighter*>(""));
+ QVERIFY(!widgetToHighlight2->findChild<WidgetHighlighter*>(""));
+ QVERIFY(!widgetToHighlight3->findChild<WidgetHighlighter*>(""));
+}
+
+void StepTextWidgetTest::testStopHighlightingWidgetWhenFocused() {
+ KXmlGuiWindow mainWindow;
+ KTutorial::self()->setup(&mainWindow);
+ QWidget* widgetToHighlight = new QWidget(&mainWindow);
+ widgetToHighlight->setObjectName("widgetName");
+ mainWindow.setCentralWidget(widgetToHighlight);
+ mainWindow.show();
+
+ StepTextWidget widget;
+ widget.setText("The <a href=\"widget:widgetName\">widget to highlight</a>");
+ widget.show();
+
+ QPoint position = centerOfText(widget, "widget to highlight");
+ QTest::mouseClick(widget.viewport(), Qt::LeftButton, Qt::NoModifier,
+ position, 500);
+
+ //To get the focus, the parent window of the widget must be active
+ mainWindow.activateWindow();
+ widgetToHighlight->setFocus();
+
+ //Give the highlighter time to stop
+ QTest::qWait(500);
+
+ QVERIFY(!widgetToHighlight->findChild<WidgetHighlighter*>(""));
+}
+
+void StepTextWidgetTest::testSetTextWhenWidgetIsBeingHighlighted() {
+ KXmlGuiWindow mainWindow;
+ KTutorial::self()->setup(&mainWindow);
+ QWidget* widgetToHighlight = new QWidget(&mainWindow);
+ widgetToHighlight->setObjectName("widgetName");
+
+ StepTextWidget widget;
+ widget.setText("The <a href=\"widget:widgetName\">widget to highlight</a>");
+ widget.show();
+
+ QPoint position = centerOfText(widget, "widget to highlight");
+ QTest::mouseClick(widget.viewport(), Qt::LeftButton, Qt::NoModifier,
+ position, 500);
+
+ widget.setText("Another text");
+
+ QVERIFY(!widgetToHighlight->findChild<WidgetHighlighter*>(""));
+}
+
+/////////////////////////////////// Helpers ////////////////////////////////////
+
+void StepTextWidgetTest::selectFirstContextMenuOption() {
+ QVERIFY(QApplication::activePopupWidget());
+ QTest::keyClick(QApplication::activePopupWidget(), Qt::Key_Down);
+ QTest::keyClick(QApplication::activePopupWidget(), Qt::Key_Enter);
+}
+
+QPoint StepTextWidgetTest::centerOfText(const StepTextWidget& widget,
+ const QString& text) {
+ QTextCursor cursor = widget.document()->find(text);
+
+ //The cursor rect doesn't include the selection, just a tiny rectangle for
+ //the cursor position. To ensure that the menu is shown on the anchor, set
+ //the cursor in the middle of the selection
+ cursor.setPosition((cursor.selectionStart() + cursor.selectionEnd()) / 2);
+ return widget.cursorRect(cursor).center();
+}
+
+void StepTextWidgetTest::showContextMenuAndSelectFirstOption(
+ const StepTextWidget& widget, const QPoint& position) {
+ //The context menu can't be triggered sending a right mouse button press
+ //event, as that is platform dependent (that event is not handled by
+ //QTextEdit or its parents, but by the QApplication for the platform that
+ //creates a context menu event when needed). A explicit QContextMenuEvent
+ //must be sent for it to work.
+ QContextMenuEvent event(QContextMenuEvent::Mouse, position,
+ widget.mapToGlobal(position));
+
+ //The context menu contains its own event loop, so it won't return to the
+ //test code until it is closed. Thus, the commands to execute on the dialog
+ //must be "queued", as calling QTest::keyClick after the button click won't
+ //work.
+ QTimer::singleShot(500, this, SLOT(selectFirstContextMenuOption()));
+ QApplication::sendEvent(widget.viewport(), &event);
+}
+
+}
+
+QTEST_KDEMAIN(view::StepTextWidgetTest, GUI)
+
+#include "StepTextWidgetTest.moc"
Property changes on: trunk/ktutorial/ktutorial-library/tests/view/StepTextWidgetTest.cpp
___________________________________________________________________
Added: svn:eol-style
+ native
Modified: trunk/ktutorial/ktutorial-library/tests/view/StepWidgetTest.cpp
===================================================================
--- trunk/ktutorial/ktutorial-library/tests/view/StepWidgetTest.cpp 2010-04-26 05:30:40 UTC (rev 237)
+++ trunk/ktutorial/ktutorial-library/tests/view/StepWidgetTest.cpp 2010-05-11 03:38:55 UTC (rev 238)
@@ -28,6 +28,7 @@
#undef protected
#include "ui_StepWidget.h"
+#include "StepTextWidget.h"
#include "../Option.h"
#include "../Step.h"
@@ -76,7 +77,7 @@
int mDummySlotCallCount;
int mAnotherDummySlotCallCount;
- QLabel* textLabel(StepWidget* stepWidget);
+ StepTextWidget* textWidget(StepWidget* stepWidget);
KPushButton* closeButton(StepWidget* stepWidget);
};
@@ -88,8 +89,8 @@
i18n("Tutorial: %1", QString("Test tutorial")));
QCOMPARE(stepWidget.windowFlags(), Qt::Dialog | Qt::FramelessWindowHint);
QVERIFY(closeButton(&stepWidget));
- QVERIFY(textLabel(&stepWidget));
- QCOMPARE(textLabel(&stepWidget)->text(), QString(""));
+ QVERIFY(textWidget(&stepWidget));
+ QCOMPARE(textWidget(&stepWidget)->toPlainText(), QString(""));
QVERIFY(stepWidget.mOptionsLayout);
QCOMPARE(stepWidget.mOptionsLayout->count(), 0);
}
@@ -104,7 +105,7 @@
stepWidget.setStep(&step);
- QCOMPARE(textLabel(&stepWidget)->text(), QString("First step"));
+ QCOMPARE(textWidget(&stepWidget)->toPlainText(), QString("First step"));
QCOMPARE(stepWidget.mOptionsLayout->count(), 1);
KPushButton* button1 = qobject_cast<KPushButton*>(
stepWidget.mOptionsLayout->itemAt(0)->widget());
@@ -123,7 +124,7 @@
stepWidget.setStep(&step1);
- QCOMPARE(textLabel(&stepWidget)->text(), QString("First step"));
+ QCOMPARE(textWidget(&stepWidget)->toPlainText(), QString("First step"));
QCOMPARE(stepWidget.mOptionsLayout->count(), 1);
KPushButton* button = qobject_cast<KPushButton*>(
stepWidget.mOptionsLayout->itemAt(0)->widget());
@@ -138,7 +139,7 @@
stepWidget.setStep(&step2);
- QCOMPARE(textLabel(&stepWidget)->text(), QString("Second step"));
+ QCOMPARE(textWidget(&stepWidget)->toPlainText(), QString("Second step"));
QCOMPARE(stepWidget.mOptionsLayout->count(), 2);
button = qobject_cast<KPushButton*>(
stepWidget.mOptionsLayout->itemAt(0)->widget());
@@ -155,7 +156,7 @@
stepWidget.setStep(&step3);
- QCOMPARE(textLabel(&stepWidget)->text(), QString("Third step"));
+ QCOMPARE(textWidget(&stepWidget)->toPlainText(), QString("Third step"));
QCOMPARE(stepWidget.mOptionsLayout->count(), 0);
QVERIFY(stepWidget.isVisible());
}
@@ -169,7 +170,7 @@
stepWidget.setStep(&step);
- QCOMPARE(textLabel(&stepWidget)->text(), QString("First step"));
+ QCOMPARE(textWidget(&stepWidget)->toPlainText(), QString("First step"));
QCOMPARE(stepWidget.mOptionsLayout->count(), 1);
KPushButton* button1 = qobject_cast<KPushButton*>(
stepWidget.mOptionsLayout->itemAt(0)->widget());
@@ -312,8 +313,8 @@
/////////////////////////////////// Helpers ////////////////////////////////////
-QLabel* StepWidgetTest::textLabel(StepWidget* stepWidget) {
- return stepWidget->ui->textLabel;
+StepTextWidget* StepWidgetTest::textWidget(StepWidget* stepWidget) {
+ return stepWidget->ui->textWidget;
}
KPushButton* StepWidgetTest::closeButton(StepWidget* stepWidget) {
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|