[Ktutorial-commits] SF.net SVN: ktutorial:[333] trunk/ktutorial/ktutorial-library
Status: Alpha
Brought to you by:
danxuliu
From: <dan...@us...> - 2011-07-07 02:31:47
|
Revision: 333 http://ktutorial.svn.sourceforge.net/ktutorial/?rev=333&view=rev Author: danxuliu Date: 2011-07-07 02:31:41 +0000 (Thu, 07 Jul 2011) Log Message: ----------- Fix wrong behaviour of StepTextWidget highlighting of widgets after cancelling the context menu. Modified 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/StepTextWidget.cpp =================================================================== --- trunk/ktutorial/ktutorial-library/src/view/StepTextWidget.cpp 2011-07-06 19:40:06 UTC (rev 332) +++ trunk/ktutorial/ktutorial-library/src/view/StepTextWidget.cpp 2011-07-07 02:31:41 UTC (rev 333) @@ -1,5 +1,5 @@ /*************************************************************************** - * Copyright (C) 2010 by Daniel Calviño Sánchez * + * Copyright (C) 2010-2011 by Daniel Calviño Sánchez * * dan...@gm... * * * * This program is free software; you can redistribute it and/or modify * @@ -34,7 +34,8 @@ StepTextWidget::StepTextWidget(QWidget* parent /*= 0*/): KTextEdit(parent), - mCurrentHighlightedWidget(0) { + mCurrentWidget(0), + mCurrentWidgetIsBeingHighlighted(false) { setReadOnly(true); setFrameShape(QFrame::NoFrame); setFrameShadow(QFrame::Plain); @@ -60,13 +61,13 @@ } StepTextWidget::~StepTextWidget() { - if (mCurrentHighlightedWidget) { + if (mCurrentWidgetIsBeingHighlighted) { stopHighlightingCurrentWidget(); } } bool StepTextWidget::eventFilter(QObject* watched, QEvent* event) { - if (watched != mCurrentHighlightedWidget) { + if (watched != mCurrentWidget) { return false; } @@ -106,16 +107,16 @@ QMenu* menu = new QMenu(this); - if (mCurrentHighlightedWidget && - mCurrentHighlightedWidget != widgetForAnchor(anchor)) { + if (mCurrentWidgetIsBeingHighlighted && + mCurrentWidget != widgetForAnchor(anchor)) { stopHighlightingCurrentWidget(); } - if (!mCurrentHighlightedWidget) { + if (!mCurrentWidgetIsBeingHighlighted) { menu->addAction(i18nc("@item:inmenu", "Highlight"), this, SLOT(highlightCurrentWidget())); - mCurrentHighlightedWidget = widgetForAnchor(anchor); + mCurrentWidget = widgetForAnchor(anchor); } else { menu->addAction(i18nc("@item:inmenu", "Stop highlighting"), this, SLOT(stopHighlightingCurrentWidget())); @@ -143,13 +144,13 @@ return; } - if (mCurrentHighlightedWidget && - mCurrentHighlightedWidget != widgetForAnchor(anchor)) { + if (mCurrentWidgetIsBeingHighlighted && + mCurrentWidget != widgetForAnchor(anchor)) { stopHighlightingCurrentWidget(); } - if (!mCurrentHighlightedWidget) { - mCurrentHighlightedWidget = widgetForAnchor(anchor); + if (!mCurrentWidgetIsBeingHighlighted) { + mCurrentWidget = widgetForAnchor(anchor); highlightCurrentWidget(); } else { @@ -185,32 +186,36 @@ void StepTextWidget::updateText() { updateGeometry(); - if (mCurrentHighlightedWidget) { + if (mCurrentWidgetIsBeingHighlighted) { stopHighlightingCurrentWidget(); } } void StepTextWidget::highlightCurrentWidget() { - if (!mCurrentHighlightedWidget) { + if (!mCurrentWidget) { kWarning() << "The widget to highlight was not found!"; return; } - WidgetHighlighterManager::self()->highlight(mCurrentHighlightedWidget); + WidgetHighlighterManager::self()->highlight(mCurrentWidget); - mCurrentHighlightedWidget->installEventFilter(this); + mCurrentWidget->installEventFilter(this); + + mCurrentWidgetIsBeingHighlighted = true; } void StepTextWidget::stopHighlightingCurrentWidget() { - if (!mCurrentHighlightedWidget) { + if (!mCurrentWidget) { kWarning() << "The widget to stop highlighting was not found!"; return; } - WidgetHighlighterManager::self()->stopHighlighting(mCurrentHighlightedWidget); + WidgetHighlighterManager::self()->stopHighlighting(mCurrentWidget); - mCurrentHighlightedWidget->removeEventFilter(this); - mCurrentHighlightedWidget = 0; + mCurrentWidget->removeEventFilter(this); + mCurrentWidget = 0; + + mCurrentWidgetIsBeingHighlighted = false; } } Modified: trunk/ktutorial/ktutorial-library/src/view/StepTextWidget.h =================================================================== --- trunk/ktutorial/ktutorial-library/src/view/StepTextWidget.h 2011-07-06 19:40:06 UTC (rev 332) +++ trunk/ktutorial/ktutorial-library/src/view/StepTextWidget.h 2011-07-07 02:31:41 UTC (rev 333) @@ -135,12 +135,17 @@ private: /** - * The widget currently being highlighted as a result of activating a link - * in this StepTextWidget. + * The last widget referenced by a link activated or selected in this + * StepTextWidget. */ - QPointer<QWidget> mCurrentHighlightedWidget; + QPointer<QWidget> mCurrentWidget; /** + * Whether the current widget is being highlighted or not. + */ + bool mCurrentWidgetIsBeingHighlighted; + + /** * 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. Modified: trunk/ktutorial/ktutorial-library/tests/view/StepTextWidgetTest.cpp =================================================================== --- trunk/ktutorial/ktutorial-library/tests/view/StepTextWidgetTest.cpp 2011-07-06 19:40:06 UTC (rev 332) +++ trunk/ktutorial/ktutorial-library/tests/view/StepTextWidgetTest.cpp 2011-07-07 02:31:41 UTC (rev 333) @@ -19,6 +19,8 @@ #include <QtTest> #include <qtest_kde.h> +#include <QAction> + #include <KXmlGuiWindow> #include "StepTextWidget.h" @@ -35,14 +37,9 @@ class StepTextWidgetTest: public QObject { Q_OBJECT -public slots: - - void selectFirstContextMenuOption(); - private slots: void init(); - void cleanup(); void testConstructor(); @@ -53,6 +50,7 @@ void testStopHighlightingWidgetClickingOnAnchor(); void testHighlightWidgetUsingContextMenu(); void testStopHighlightingWidgetUsingContextMenu(); + void testCancelContextMenu(); void testHighlightSeveralWidgets(); void testHighlightUnknownWidget(); @@ -69,6 +67,10 @@ void showContextMenuAndSelectFirstOption(const StepTextWidget& widget, const QPoint& position); + void showContextMenuCheckFirstOptionAndCancel(const StepTextWidget& widget, + const QPoint& position, + const QString& text); + }; void StepTextWidgetTest::init() { @@ -76,9 +78,6 @@ KTutorial::sSelf = new KTutorial(); } -void StepTextWidgetTest::cleanup() { -} - void StepTextWidgetTest::testConstructor() { QWidget parent; StepTextWidget* widget = new StepTextWidget(&parent); @@ -206,6 +205,40 @@ QVERIFY(!widgetToHighlight->findChild<WidgetHighlighter*>("")); } +void StepTextWidgetTest::testCancelContextMenu() { + 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"); + showContextMenuCheckFirstOptionAndCancel(widget, position, + i18n("Highlight")); + + //Ensure that the option text is the right one after cancelling the menu + showContextMenuCheckFirstOptionAndCancel(widget, position, + i18n("Highlight")); + + //Check again when the widget is highlighted + showContextMenuAndSelectFirstOption(widget, position); + + QVERIFY(widgetToHighlight->findChild<WidgetHighlighter*>("")); + + showContextMenuCheckFirstOptionAndCancel(widget, position, + i18n("Stop highlighting")); + + //Ensure that the option text is the right one after cancelling the menu + showContextMenuCheckFirstOptionAndCancel(widget, position, + i18n("Stop highlighting")); +} + void StepTextWidgetTest::testHighlightSeveralWidgets() { KXmlGuiWindow mainWindow; KTutorial::self()->setup(&mainWindow); @@ -383,12 +416,6 @@ /////////////////////////////////// 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); @@ -400,6 +427,46 @@ return widget.cursorRect(cursor).center(); } +//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 menu must be +//"queued", as calling QTest::keyClick after showing the menu won't work. +class QueuedActionsHelper: public QObject { +Q_OBJECT +public: + + QueuedActionsHelper(QObject* parent = 0): QObject(parent) { + setObjectName("helper"); + } + + void setExpectedMenuItemName(const QString& menuItemName) { + mMenuItemName = menuItemName; + } + +public slots: + + void selectFirstContextMenuOption() { + QVERIFY(QApplication::activePopupWidget()); + QTest::keyClick(QApplication::activePopupWidget(), Qt::Key_Down); + QTest::keyClick(QApplication::activePopupWidget(), Qt::Key_Enter); + } + + void assertFirstContextMenuOptionName() { + QVERIFY(QApplication::activePopupWidget()); + QWidget* menu = QApplication::activePopupWidget(); + QCOMPARE(menu->actions()[0]->text(), mMenuItemName); + } + + void cancelContextMenu() { + QVERIFY(QApplication::activePopupWidget()); + QTest::keyClick(QApplication::activePopupWidget(), Qt::Key_Escape); + } + +private: + + QString mMenuItemName; + +}; + void StepTextWidgetTest::showContextMenuAndSelectFirstOption( const StepTextWidget& widget, const QPoint& position) { //The context menu can't be triggered sending a right mouse button press @@ -410,16 +477,34 @@ 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())); + QueuedActionsHelper* helper = new QueuedActionsHelper(this); + QTimer::singleShot(500, helper, SLOT(selectFirstContextMenuOption())); + QApplication::sendEvent(widget.viewport(), &event); } +void StepTextWidgetTest::showContextMenuCheckFirstOptionAndCancel( + const StepTextWidget& widget, + const QPoint& position, + const QString& text) { + //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). An explicit QContextMenuEvent + //must be sent for it to work. + QContextMenuEvent event(QContextMenuEvent::Mouse, position, + widget.mapToGlobal(position)); + + QueuedActionsHelper* helper = new QueuedActionsHelper(this); + helper->setExpectedMenuItemName(text); + QTimer::singleShot(500, helper, SLOT(assertFirstContextMenuOptionName())); + QTimer::singleShot(600, helper, SLOT(cancelContextMenu())); + + QApplication::sendEvent(widget.viewport(), &event); } +} + QTEST_KDEMAIN(view::StepTextWidgetTest, GUI) #include "StepTextWidgetTest.moc" This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |