ktutorial-commits Mailing List for KTutorial (Page 5)
Status: Alpha
Brought to you by:
danxuliu
You can subscribe to this list here.
2010 |
Jan
(1) |
Feb
(36) |
Mar
(117) |
Apr
(11) |
May
(8) |
Jun
(1) |
Jul
|
Aug
(2) |
Sep
(21) |
Oct
(16) |
Nov
|
Dec
|
---|---|---|---|---|---|---|---|---|---|---|---|---|
2011 |
Jan
(1) |
Feb
|
Mar
(6) |
Apr
(6) |
May
(15) |
Jun
(15) |
Jul
(6) |
Aug
|
Sep
(1) |
Oct
(4) |
Nov
|
Dec
|
2012 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
(10) |
Jul
(4) |
Aug
(29) |
Sep
(4) |
Oct
|
Nov
|
Dec
(2) |
From: <dan...@us...> - 2011-03-08 02:59:44
|
Revision: 290 http://ktutorial.svn.sourceforge.net/ktutorial/?rev=290&view=rev Author: danxuliu Date: 2011-03-08 02:59:37 +0000 (Tue, 08 Mar 2011) Log Message: ----------- Add support for object paths instead of just object names in KTutorial::findObject(QString). Now the ancestor names can be included when finding an object to differentiate between several objects with the same name. Modified Paths: -------------- trunk/ktutorial/ktutorial-library/src/KTutorial.h trunk/ktutorial/ktutorial-library/tests/CMakeLists.txt Added Paths: ----------- trunk/ktutorial/ktutorial-library/tests/KTutorialTest.cpp Modified: trunk/ktutorial/ktutorial-library/src/KTutorial.h =================================================================== --- trunk/ktutorial/ktutorial-library/src/KTutorial.h 2011-03-08 02:47:15 UTC (rev 289) +++ trunk/ktutorial/ktutorial-library/src/KTutorial.h 2011-03-08 02:59:37 UTC (rev 290) @@ -1,5 +1,5 @@ /*************************************************************************** - * Copyright (C) 2008-2010 by Daniel Calviño Sánchez * + * Copyright (C) 2008-2011 by Daniel Calviño Sánchez * * dan...@gm... * * * * This program is free software; you can redistribute it and/or modify * @@ -123,6 +123,15 @@ * Returns the object with the specified name, if any. * Objects are searched in the children of the main window of the * application. + * When the name of the desired object is not unique the name of some + * ancestor must be included. Ancestor names are separated using a "/". That + * is, "Ancestor name/The object with a repeated name". As many ancestor + * names as desired can be included, not just one. + * The name of the ancestors does not need to be unique either; what has to + * be unique is the full path to the object to find. For example, "Ancestor + * name not unique/The object to find" is valid if, among all the objects + * called "Ancestor name not unique", there is only one that has a + * descendant called "The object to find". * * @param name The name of the object to find. * @return The object with the specified name, or null if there is none. @@ -131,7 +140,7 @@ */ template <typename T> T findObject(const QString& name) const { - return mParent->findChild<T>(name); + return findObject<T>(name, mParent); } private: @@ -167,6 +176,44 @@ mParent = 0; } + /** + * Returns the object with the specified name that is descendant of the + * given parent, if any. + * The name of the object can contain ancestor names separated by "/". The + * first object that matches the whole path is returned (note that ancestor + * are not necessarily direct parents). + * + * @param name The name of the object to find. + * @param parent The parent to look the object in. + * @return The object with the specified name, or null if there is none. + */ + template <typename T> + T findObject(const QString& name, const QObject* ancestor) const { + if (name.isEmpty() || ancestor == 0) { + return T(); + } + + if (name.indexOf('/') == -1) { + return ancestor->findChild<T>(name); + } + + QRegExp slashPattern("/+"); + QString ancestorName = name.left(name.indexOf(slashPattern)); + QString descendantName = name.mid(ancestorName.length() + + slashPattern.matchedLength()); + + QList<QObject*> namedAncestors = + ancestor->findChildren<QObject*>(ancestorName); + foreach (QObject* namedAncestor, namedAncestors) { + T object = findObject<T>(descendantName, namedAncestor); + if (object) { + return object; + } + } + + return 0; + } + private slots: /** Modified: trunk/ktutorial/ktutorial-library/tests/CMakeLists.txt =================================================================== --- trunk/ktutorial/ktutorial-library/tests/CMakeLists.txt 2011-03-08 02:47:15 UTC (rev 289) +++ trunk/ktutorial/ktutorial-library/tests/CMakeLists.txt 2011-03-08 02:59:37 UTC (rev 290) @@ -26,6 +26,7 @@ ENDMACRO(UNIT_TESTS) unit_tests( + KTutorial Option Step Tutorial @@ -48,6 +49,7 @@ ENDMACRO(MEM_TESTS) mem_tests( + KTutorial Option Step Tutorial Added: trunk/ktutorial/ktutorial-library/tests/KTutorialTest.cpp =================================================================== --- trunk/ktutorial/ktutorial-library/tests/KTutorialTest.cpp (rev 0) +++ trunk/ktutorial/ktutorial-library/tests/KTutorialTest.cpp 2011-03-08 02:59:37 UTC (rev 290) @@ -0,0 +1,185 @@ +/*************************************************************************** + * Copyright (C) 2011 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 <QAction> + +#include "KTutorial.h" + +class KTutorialTest: public QObject { +Q_OBJECT + +private slots: + + void initTestCase(); + void cleanupTestCase(); + + void testFindObjectSingleName(); + void testFindObjectSingleNameUnknown(); + void testFindObjectComplexNameDirectChild(); + void testFindObjectComplexNameNestedChild(); + void testFindObjectComplexNameAncestorNameNotUnique(); + void testFindObjectComplexNameUnknownParent(); + void testFindObjectEmptyName(); + void testFindObjectSingleSlash(); + void testFindObjectSlashEndedName(); + void testFindObjectSeveralSlashes(); + +private: + + KXmlGuiWindow* mMainWindow; + QObject* mObject1_1_1; + QAction* mAction1_1_2; + QObject* mObject1_2_1; + QObject* mObject2_1_1; + QObject* mObject2_1_2; + QAction* mAction2_1_3; + QAction* mAction2_1_4; + QObject* mObject3_1_1; + QObject* mObject3_2_1_1; + QAction* mAction3_3_1_1; + + void assertFindObject(const QString& objectName, QObject* object) const; + void assertFindAction(const QString& objectName, QAction* widget) const; + +}; + +void KTutorialTest::initTestCase() { + mMainWindow = new KXmlGuiWindow(); + KTutorial::self()->setup(mMainWindow); + + QObject* grandParent1 = new QObject(mMainWindow); + grandParent1->setObjectName("Grand parent1"); + QObject* parent1_1 = new QObject(grandParent1); + parent1_1->setObjectName("Parent1"); + mObject1_1_1 = new QObject(parent1_1); + mObject1_1_1->setObjectName("The object"); + mAction1_1_2 = new QAction(parent1_1); + mAction1_1_2->setObjectName("The widget"); + + QObject* parent1_2 = new QObject(grandParent1); + parent1_2->setObjectName("Parent2"); + mObject1_2_1 = new QObject(parent1_2); + mObject1_2_1->setObjectName("The object"); + + QObject* grandParent2 = new QObject(mMainWindow); + grandParent2->setObjectName("Grand parent2"); + QObject* parent2_1 = new QObject(grandParent2); + parent2_1->setObjectName("Parent1"); + mObject2_1_1 = new QObject(parent2_1); + mObject2_1_1->setObjectName("The object"); + mObject2_1_2 = new QObject(parent2_1); + mObject2_1_2->setObjectName("Another object"); + mAction2_1_3 = new QAction(parent2_1); + mAction2_1_3->setObjectName("The widget"); + mAction2_1_4 = new QAction(parent2_1); + mAction2_1_4->setObjectName("Another widget"); + + QObject* grandParent3 = new QObject(mMainWindow); + grandParent3->setObjectName("Grand parent3"); + QObject* parent3_1 = new QObject(grandParent3); + parent3_1->setObjectName("Parent1"); + mObject3_1_1 = new QObject(parent3_1); + mObject3_1_1->setObjectName("The object"); + + QObject* parent3_2 = new QObject(grandParent3); + parent3_2->setObjectName("Nested parent"); + QObject* parent3_2_1 = new QObject(parent3_2); + mObject3_2_1_1 = new QObject(parent3_2_1); + mObject3_2_1_1->setObjectName("Another object"); + + QTimer* parent3_3 = new QTimer(grandParent3); + parent3_3->setObjectName("Nested timer"); + QTimer* parent3_3_1 = new QTimer(parent3_3); + mAction3_3_1_1 = new QAction(parent3_3_1); + mAction3_3_1_1->setObjectName("Another widget"); +} + +void KTutorialTest::cleanupTestCase() { + delete mMainWindow; +} + +void KTutorialTest::testFindObjectSingleName() { + assertFindObject("The object", mObject1_1_1); +} + +void KTutorialTest::testFindObjectSingleNameUnknown() { + assertFindObject("Unknown object", 0); +} + +void KTutorialTest::testFindObjectComplexNameDirectChild() { + assertFindObject("Grand parent1/Parent1/The object", mObject1_1_1); + assertFindObject("Grand parent1/Parent2/The object", mObject1_2_1); + assertFindObject("Grand parent2/Parent1/The object", mObject2_1_1); + + assertFindAction("Grand parent1/Parent1/The widget", mAction1_1_2); + assertFindAction("Grand parent2/Parent1/The widget", mAction2_1_3); +} + +void KTutorialTest::testFindObjectComplexNameNestedChild() { + assertFindObject("Grand parent2/The object", mObject2_1_1); + assertFindObject("Nested parent/Another object", mObject3_2_1_1); + + assertFindAction("Grand parent2/The widget", mAction2_1_3); + assertFindAction("Nested timer/Another widget", mAction3_3_1_1); +} + +void KTutorialTest::testFindObjectComplexNameAncestorNameNotUnique() { + //The ancestor name is not unique, but the full path is + assertFindObject("Parent1/Another object", mObject2_1_2); + + assertFindAction("Parent1/Another widget", mAction2_1_4); +} + +void KTutorialTest::testFindObjectComplexNameUnknownParent() { + assertFindObject("Unknown grand parent/The object", 0); + assertFindObject("Grand parent1/Unknown parent/The object", 0); +} + +void KTutorialTest::testFindObjectEmptyName() { + assertFindObject("", 0); +} + +void KTutorialTest::testFindObjectSingleSlash() { + assertFindObject("/", 0); +} + +void KTutorialTest::testFindObjectSlashEndedName() { + assertFindObject("Parent/", 0); +} + +void KTutorialTest::testFindObjectSeveralSlashes() { + assertFindObject("Parent1///The object", mObject1_1_1); +} + +/////////////////////////////////Helpers//////////////////////////////////////// + +void KTutorialTest::assertFindObject(const QString& objectName, + QObject* object) const { + QCOMPARE(KTutorial::self()->findObject<QObject*>(objectName), object); +} + +void KTutorialTest::assertFindAction(const QString& objectName, + QAction* widget) const { + QCOMPARE(KTutorial::self()->findObject<QAction*>(objectName), widget); +} + +QTEST_MAIN(KTutorialTest) + +#include "KTutorialTest.moc" Property changes on: trunk/ktutorial/ktutorial-library/tests/KTutorialTest.cpp ___________________________________________________________________ Added: svn:eol-style + native This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dan...@us...> - 2011-03-08 02:47:21
|
Revision: 289 http://ktutorial.svn.sourceforge.net/ktutorial/?rev=289&view=rev Author: danxuliu Date: 2011-03-08 02:47:15 +0000 (Tue, 08 Mar 2011) Log Message: ----------- Modify how widgets are highlighted. Due to performance reasons (specially in interfaces with a lot of widgets) instead of tinting the whole widget now only a frame is tinted. The color used now is always got from the active palette, as the highlight color in the inactive palette could be too subtle. The animation interval was increased also for performance reasons, and now only the frame is updated instead of the whole widget. However, the duration of the animation was increased just for stylistic purposes (and StepTextWidgetTest had to be updated due to the new animation length). Modified Paths: -------------- trunk/ktutorial/ktutorial-library/src/extendedinformation/WidgetHighlighter.cpp trunk/ktutorial/ktutorial-library/src/extendedinformation/WidgetHighlighter.h trunk/ktutorial/ktutorial-library/tests/view/StepTextWidgetTest.cpp Modified: trunk/ktutorial/ktutorial-library/src/extendedinformation/WidgetHighlighter.cpp =================================================================== --- trunk/ktutorial/ktutorial-library/src/extendedinformation/WidgetHighlighter.cpp 2011-01-28 10:59:11 UTC (rev 288) +++ trunk/ktutorial/ktutorial-library/src/extendedinformation/WidgetHighlighter.cpp 2011-03-08 02:47:15 UTC (rev 289) @@ -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 * @@ -42,13 +42,15 @@ mIncreasing = true; mStopping = false; - int interval = 25; - int duration = 500; + int interval = 80; + int duration = 1000; mProgressForEachTick = interval / (qreal)duration; mTimer.setInterval(interval); connect(&mTimer, SIGNAL(timeout()), this, SLOT(updateProgress())); + mFrameWidth = 6; + show(); } @@ -86,11 +88,10 @@ void WidgetHighlighter::paintEvent(QPaintEvent* event) { //Painting the WidgetHighlighter over its parent widget with a - //semi-transpaernt color is the best I could get. However, it has some + //semi-transparent color is the best I could get. However, it has some //flaws. For example, a QMenu does not highlight its menu button. And some //widgets may be hardly highlighted if their background color is almost the - //same as the highlight color (like QStatusBar in Oxygen style and default - //colors). + //same as the highlight color (although it should not happen very often). // //Changing the parent widget palette does not work because some widgets //(like tool buttons) don't paint a background, only paint the text and get @@ -123,12 +124,33 @@ //quickly enough to be done in a realtime animation, so... a //semi-transparent colored child widget is good enough until someone makes //something better ;) + // + //However, filling the whole widget and animating it is too CPU intensive + //when tinting a parent widget with lots of child widgets (for example, the + //main widget in showfoto). So, instead of tinting the whole parent only + //a frame is painted and animated. In this case, the frame gets its full + //opacity at the peak of the animation, instead of half the opacity as used + //when tinting the whole widget. - QColor color = mTargetWidget->palette().color(QPalette::Highlight); + //The inactive palette does not usually have a lot of contrast between + //normal color and highlight color (for example, a QStatusBar in Oxygen + //style). The highlight color from the active palette is used in every case + //to ensure that the widget is clearly highlighted, even if the window is + //not the active one. + QColor color = mTargetWidget->palette().color(QPalette::Active, + QPalette::Highlight); QPainter painter(this); - painter.setOpacity(mProgress / 2.0f); - painter.fillRect(event->rect(), color); + painter.setOpacity(mProgress); + + QPen pen; + pen.setWidth(mFrameWidth); + pen.setColor(color); + painter.setPen(pen); + + //Third and fourth arguments are width and height, not end coordinates + painter.drawRect(pen.width() / 2, pen.width() / 2, + width() - pen.width(), height() - pen.width()); painter.end(); } @@ -145,7 +167,12 @@ mIncreasing = mProgress == 0; } - update(); + //Update just the frame of the widget instead of the whole widget for + //performance + update(0, 0, width(), mFrameWidth); + update(0, 0, mFrameWidth, height()); + update(width() - mFrameWidth, 0, width(), height()); + update(0, height() - mFrameWidth, width(), height()); if (mStopping && mProgress == 0) { mTimer.stop(); Modified: trunk/ktutorial/ktutorial-library/src/extendedinformation/WidgetHighlighter.h =================================================================== --- trunk/ktutorial/ktutorial-library/src/extendedinformation/WidgetHighlighter.h 2011-01-28 10:59:11 UTC (rev 288) +++ trunk/ktutorial/ktutorial-library/src/extendedinformation/WidgetHighlighter.h 2011-03-08 02:47:15 UTC (rev 289) @@ -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 * @@ -37,9 +37,10 @@ * stop animation is cancelled and a new highlight animation is started from * that point). * - * To tint the widget, the WidgetHighlighter paints itself over the whole parent - * widget with a semi-transparent highlight color, so the parent widget can - * still be seen but tinted with the highlight color. + * To tint the widget, the WidgetHighlighter paints itself over the parent + * widget with a semi-transparent highlight color. However, due to performance + * reasons, only a frame is tinted instead of the whole widget. The center of + * the frame is always transparent. * * WidgetHighlighter should not be created directly. Instead, * WidgetHighlighterManager should be used, as it takes care of deleting the @@ -99,7 +100,7 @@ protected: /** - * Fills the widget with a semi-transparent highlight color. + * Paints a frame with a semi-transparent highlight color. * The degree of opacity depends on the progress of the animation. * * @param event The paint event. @@ -139,6 +140,11 @@ */ bool mStopping; + /** + * The width of the frame used to highlight the widget. + */ + int mFrameWidth; + private Q_SLOTS: /** Modified: trunk/ktutorial/ktutorial-library/tests/view/StepTextWidgetTest.cpp =================================================================== --- trunk/ktutorial/ktutorial-library/tests/view/StepTextWidgetTest.cpp 2011-01-28 10:59:11 UTC (rev 288) +++ trunk/ktutorial/ktutorial-library/tests/view/StepTextWidgetTest.cpp 2011-03-08 02:47:15 UTC (rev 289) @@ -201,7 +201,7 @@ showContextMenuAndSelectFirstOption(widget, position); //Give the highlighter time to stop - QTest::qWait(500); + QTest::qWait(1000); QVERIFY(!widgetToHighlight->findChild<WidgetHighlighter*>("")); } @@ -260,7 +260,7 @@ position1, 500); //Give the highlighter time to stop - QTest::qWait(500); + QTest::qWait(1000); QVERIFY(!widgetToHighlight1->findChild<WidgetHighlighter*>("")); QVERIFY(!widgetToHighlight2->findChild<WidgetHighlighter*>("")); @@ -272,7 +272,7 @@ showContextMenuAndSelectFirstOption(widget, position2); //Give the highlighter time to stop - QTest::qWait(500); + QTest::qWait(1000); QVERIFY(!widgetToHighlight1->findChild<WidgetHighlighter*>("")); QVERIFY(!widgetToHighlight2->findChild<WidgetHighlighter*>("")); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dan...@us...> - 2011-01-28 10:59:17
|
Revision: 288 http://ktutorial.svn.sourceforge.net/ktutorial/?rev=288&view=rev Author: danxuliu Date: 2011-01-28 10:59:11 +0000 (Fri, 28 Jan 2011) Log Message: ----------- Fix crash when the StepTextWidget highlighted a widget, the widget was destroyed and then the StepTextWidget tried to stop the highlighting. Modified Paths: -------------- trunk/ktutorial/ktutorial-library/src/view/StepTextWidget.h trunk/ktutorial/ktutorial-library/tests/view/StepTextWidgetTest.cpp Modified: trunk/ktutorial/ktutorial-library/src/view/StepTextWidget.h =================================================================== --- trunk/ktutorial/ktutorial-library/src/view/StepTextWidget.h 2010-10-31 20:37:40 UTC (rev 287) +++ trunk/ktutorial/ktutorial-library/src/view/StepTextWidget.h 2011-01-28 10:59:11 UTC (rev 288) @@ -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 * @@ -19,6 +19,8 @@ #ifndef VIEW_STEPTEXTWIDGET_H #define VIEW_STEPTEXTWIDGET_H +#include <QPointer> + #include <KTextEdit> namespace view { @@ -136,7 +138,7 @@ * The widget currently being highlighted as a result of activating a link * in this StepTextWidget. */ - QWidget* mCurrentHighlightedWidget; + QPointer<QWidget> mCurrentHighlightedWidget; /** * Returns the size for the given text width. Modified: trunk/ktutorial/ktutorial-library/tests/view/StepTextWidgetTest.cpp =================================================================== --- trunk/ktutorial/ktutorial-library/tests/view/StepTextWidgetTest.cpp 2010-10-31 20:37:40 UTC (rev 287) +++ trunk/ktutorial/ktutorial-library/tests/view/StepTextWidgetTest.cpp 2011-01-28 10:59:11 UTC (rev 288) @@ -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 * @@ -60,6 +60,7 @@ void testSetTextWhenWidgetIsBeingHighlighted(); void testDeleteWhenWidgetIsBeingHighlighted(); + void testDeleteWhenHighlightedWidgetWasDestroyed(); private: @@ -359,6 +360,27 @@ QVERIFY(!widgetToHighlight->findChild<WidgetHighlighter*>("")); } +void StepTextWidgetTest::testDeleteWhenHighlightedWidgetWasDestroyed() { + KXmlGuiWindow mainWindow; + KTutorial::self()->setup(&mainWindow); + QWidget* widgetToHighlight = new QWidget(&mainWindow); + widgetToHighlight->setObjectName("widgetName"); + + StepTextWidget* widget = new StepTextWidget(); + 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); + + delete widgetToHighlight; + + delete widget; + + //No explicit check is made, if it does not crash everything is fine ;) +} + /////////////////////////////////// Helpers //////////////////////////////////// void StepTextWidgetTest::selectFirstContextMenuOption() { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dan...@us...> - 2010-10-31 20:37:46
|
Revision: 287 http://ktutorial.svn.sourceforge.net/ktutorial/?rev=287&view=rev Author: danxuliu Date: 2010-10-31 20:37:40 +0000 (Sun, 31 Oct 2010) Log Message: ----------- Update pages for release 0.4 Modified Paths: -------------- trunk/web-src/data/images/screenshots/MainWindow-192.png trunk/web-src/data/images/screenshots/MainWindow.png trunk/web-src/data/images/screenshots/NewCondition-192.png trunk/web-src/data/images/screenshots/NewCondition.png trunk/web-src/newsList.xml trunk/web-src/pages/development.xml trunk/web-src/pages/documentation.xml trunk/web-src/pages/download.xml trunk/web-src/pages/faq.xml trunk/web-src/pages/index.xml trunk/web-src/pages/news.xml trunk/web-src/pages/screenshotsGallery.xml trunk/web-src/screenshotsList.xml Added Paths: ----------- trunk/web-src/data/images/screenshots/SignalNameCompletion-192.png trunk/web-src/data/images/screenshots/SignalNameCompletion.png Modified: trunk/web-src/data/images/screenshots/MainWindow-192.png =================================================================== (Binary files differ) Modified: trunk/web-src/data/images/screenshots/MainWindow.png =================================================================== (Binary files differ) Modified: trunk/web-src/data/images/screenshots/NewCondition-192.png =================================================================== (Binary files differ) Modified: trunk/web-src/data/images/screenshots/NewCondition.png =================================================================== (Binary files differ) Added: trunk/web-src/data/images/screenshots/SignalNameCompletion-192.png =================================================================== (Binary files differ) Property changes on: trunk/web-src/data/images/screenshots/SignalNameCompletion-192.png ___________________________________________________________________ Added: svn:mime-type + image/png Added: trunk/web-src/data/images/screenshots/SignalNameCompletion.png =================================================================== (Binary files differ) Property changes on: trunk/web-src/data/images/screenshots/SignalNameCompletion.png ___________________________________________________________________ Added: svn:mime-type + image/png Modified: trunk/web-src/newsList.xml =================================================================== --- trunk/web-src/newsList.xml 2010-10-31 20:33:51 UTC (rev 286) +++ trunk/web-src/newsList.xml 2010-10-31 20:37:40 UTC (rev 287) @@ -38,4 +38,18 @@ <date>2010-03-24</date> </fullDate> </new> + + <new> + <title>KTutorial 0.4 released!</title> + <summary> + <div xmlns="http://www.w3.org/1999/xhtml"> + <p>This release was geared mostly towards improving KTutorial editor (for example, tutorials can be saved and loaded now), although improvements were made also to KTutorial library (like being able to highlight widgets).</p> + <p>The <a href="http://sourceforge.net/projects/ktutorial/files/ktutorial-0.4/Release notes/view" title="KTutorial 0.4 release notes">release notes</a> contain more information about the changes from 0.3 release.</p> + <p>Check the <a href="download.html" title="Download page in KTutorial web">download page</a> for information about downloading and building KTutorial.</p> + </div> + </summary> + <fullDate> + <date>2010-10-30</date> + </fullDate> + </new> </news> Modified: trunk/web-src/pages/development.xml =================================================================== --- trunk/web-src/pages/development.xml 2010-10-31 20:33:51 UTC (rev 286) +++ trunk/web-src/pages/development.xml 2010-10-31 20:37:40 UTC (rev 287) @@ -23,7 +23,8 @@ <h2><a id="documentation" class="anchorLink">Documentation</a></h2> </div> <p>This documentation is about KTutorial development. If you are a developer, but are looking for documentation about using KTutorial in your application, take a look in <a href="documentation.html#developers" title="Documentation for developers using KTutorial">developers section</a> in the documentation page.</p> - <p>Instead, if you are curious about how KTutorial is developed (design, implementation...), take a look in <a href="doc/design.html" title="KTutorial design document">KTutorial design</a>. However, I still need to work on it, as it is more a draft than a final document.</p> + <p>Instead, if you are curious about how KTutorial is developed (design, implementation...), take a look in <a href="doc/design.html" title="KTutorial design document">KTutorial design</a>. However, I still need to work on it, as it is more a draft than a final document, and it is also painfully outdated...</p> + <p>The UML diagrams (mostly class diagrams), on the other hand, are up to date: <a href="doc/Editor.xmi" title="KTutorial Editor UML diagrams">editor</a> and <a href="doc/Library.xmi" title="KTutorial Library UML diagrams">library</a>. Both files can be opened using <a href="http://uml.sourceforge.net/" title="Umbrello UML Modeller home page">Umbrello UML Modeller</a>.</p> <div class="h2Rounded"> <h2><a id="blog" class="anchorLink">Blog</a></h2> @@ -35,7 +36,7 @@ </div> <p>Right now, KTutorial is in a prototype state, but it is able to execute tutorials: it works!</p> <p>As well as the library itself, KTutorial provides a graphical editor for tutorials, not surprisingly named Ktutorial editor.</p> - <p>In KTutorial SVN there is also a little test application, KTutorial test app, which shows the different features of KTutorial in a "real" environment.</p> + <p>There is also a little test application, KTutorial test app, which shows several features of KTutorial in a "real" environment.</p> <p>Here it is the current features list:</p> <ul> <li> @@ -48,6 +49,9 @@ <p><em>Options in steps:</em> tutorials can show options to the user in the steps. It allows, for example, to make the user choose between one path or another when following a tutorial.</p> </li> <li> + <p><em>Widget highlighting:</em> tutorials can link to widgets in the text of their steps, and when the links are clicked the widgets are highlighted.</p> + </li> + <li> <p><em>Easy integration:</em> KTutorial was designed to ease its use in applications, so the developer only has to worry about coding the tutorial. Setting KTutorial up, merging the menus, managing the tutorials and things like that are done almost automatically.</p> </li> <li> @@ -57,8 +61,11 @@ <p><em>CMake build system:</em> KTutorial uses KDE 4 CMake build system, and also provides a CMake module to be used from applications using KTutorial to configure them as necessary.</p> </li> <li> - <p><em>Graphical editor:</em> KTutorial editor is a companion to KTutorial library to ease tutorial authoring. A tutorial can be defined using the editor and then exported to a scripted tutorial that can be understood by KTutorial library. However, the editor is still very basic at this time.</p> + <p><em>Graphical editor:</em> KTutorial editor is a companion to KTutorial library to ease tutorial authoring. A tutorial can be defined using the editor and then exported to a scripted tutorial that can be understood by KTutorial library.</p> </li> + <li> + <p><em>Application introspection:</em> KTutorial provides a system to introspect any application that uses KTutorial. Thanks to this, KTutorial editor can know, for example, the name of the objects accesible by KTutorial or the signals they can emit.</p> + </li> </ul> <div class="h2Rounded"> @@ -67,20 +74,20 @@ <p>Here you can see what (major) features I expect to include in the future.</p> <ul class="foldableList"> <li> - 0.4: + 0.5: <ul> - <li>Emphasize widgets to help the user finding them (provided it is technically viable)</li> - <li>In KTutorial editor, get the name of the objects that send signals or receive events from the application the tutorial documents, just clicking on the desired widget (provided it is technically viable)</li> + <li>Add support for custom conditions in KTutorial editor.</li> </ul> </li> <li> Someday? (these features need further investigation about their technical viability): <ul> - <li>Extended information in step texts (something like "What is this" help on specific words, for example)</li> + <li>Extended information in step texts (something like "What is this" help on specific words, for example).</li> + <li>Add a <a href="http://martinfowler.com/bliki/FluentInterface.html" title="Fluent Interface article in Martin Fowler's Bliki">fluent interface</a> to the library.</li> </ul> </li> </ul> - <p class="lastUpdated">Last updated: 2010-03-24</p> + <p class="lastUpdated">Last updated: 2010-10-30</p> </page:content> </page> Modified: trunk/web-src/pages/documentation.xml =================================================================== --- trunk/web-src/pages/documentation.xml 2010-10-31 20:33:51 UTC (rev 286) +++ trunk/web-src/pages/documentation.xml 2010-10-31 20:37:40 UTC (rev 287) @@ -26,7 +26,7 @@ <p>KTutorial provides a tutorial named <em>Using tutorials</em> which purpose is, well, show how to use tutorials ;)</p> <p>But, how you can start a tutorial? If you have an application that uses KTutorial, just go to <em>Help->Tutorials...</em> and a dialog with all the available tutorials will appear. Select one, click on <em>Start</em> button and now just follow it!</p> <p>If your application doesn't have a <em>Help->Tutorials...</em> menu item, sorry, it doesn't use KTutorial ;)</p> - <p>Note, however, that right now only KTutorial test application uses KTutorial :P</p> + <p>Note, however, that right now only KTutorial editor and KTutorial test application use KTutorial :P</p> <div class="h2Rounded"> <h2><a id="developers" class="anchorLink">For developers using KTutorial</a></h2> @@ -40,6 +40,6 @@ </div> <p>Refer to <a href="development.html" title="Development information">development</a> section of the web.</p> - <p class="lastUpdated">Last updated: 2010-03-24</p> + <p class="lastUpdated">Last updated: 2010-10-30</p> </page:content> </page> Modified: trunk/web-src/pages/download.xml =================================================================== --- trunk/web-src/pages/download.xml 2010-10-31 20:33:51 UTC (rev 286) +++ trunk/web-src/pages/download.xml 2010-10-31 20:37:40 UTC (rev 287) @@ -17,8 +17,8 @@ <div class="h2Rounded"> <h2><a id="releases" class="anchorLink">Releases</a></h2> </div> - <p>Current release is 0.3. You can download <a href="http://sourceforge.net/projects/ktutorial/files/ktutorial-0.3/ktutorial-0.3.tar.gz/download" title="KTutorial 0.3 release in tar.gz">ktutorial-0.3.tar.gz</a> from <a href="http://sourceforge.net/projects/ktutorial/files/" title="KTutorial project files">project's file list</a>.</p> - <p>You can also see the <a href="http://sourceforge.net/projects/ktutorial/files/ktutorial-0.3/Release%20notes/view" title="KTutorial 0.3 release notes">release notes</a> (although there isn't much to see ;) ).</p> + <p>Current release is 0.4. You can download <a href="http://sourceforge.net/projects/ktutorial/files/ktutorial-0.4/ktutorial-0.4.tar.gz/download" title="KTutorial 0.4 release in tar.gz">ktutorial-0.4.tar.gz</a> from <a href="http://sourceforge.net/projects/ktutorial/files/" title="KTutorial project files">project's file list</a>.</p> + <p>You can also see the <a href="http://sourceforge.net/projects/ktutorial/files/ktutorial-0.4/Release%20notes/view" title="KTutorial 0.4 release notes">release notes</a> (although there isn't much to see ;) ).</p> <p>See below for build instructions, in <a href="#build" title="Build instructions">building section</a>.</p> <p>If you do know what you are doing ;) , you can also checkout KTutorial sources from <acronym title="Subversion">SVN</acronym> repository. Go on reading to know how to do it.</p> @@ -37,10 +37,10 @@ <h2><a id="build" class="anchorLink">Building</a></h2> </div> <p>In order to build KTutorial, it doesn't matter if you downloaded it from a release or from <acronym title="Subversion">SVN</acronym>.</p> - <p>You will need <a href="http://www.cmake.org" title="CMake project web">CMake</a>, and Qt >= 4.5.3 and KDE 4 kdelibs development packages installed in your system. It can be built like any other KDE 4 library or application.</p> + <p>You will need <a href="http://www.cmake.org" title="CMake project web">CMake</a>, and Qt >= 4.6 and KDE 4 kdelibs development packages installed in your system. It can be built like any other KDE 4 library or application.</p> <p>Create a <em>build</em> subdirectory in <em>ktutorial</em> directory, and change to it. Now, in a terminal, just run <strong>cmake ../ && make</strong> and it will configure and build KTutorial in the <em>build</em> directory. Once built, execute <strong>make install</strong> and you are done (you will likely need to change to root user, as default KDE installation is usually only root writable).</p> <p>If you want to specify a prefix to install KTutorial to, instead of using KDE default installation directory, call CMake using the parameter <strong>-DCMAKE_INSTALL_PREFIX=/installation/prefix</strong>. For debugging purposes, use <strong>-DCMAKE_BUILD_TYPE=debugfull</strong>. To automatically build the unit tests when the library is built, use <strong>-DKDE4_BUILD_TESTS=ON</strong>.</p> - <p class="lastUpdated">Last updated: 2010-03-24</p> + <p class="lastUpdated">Last updated: 2010-10-30</p> </page:content> </page> Modified: trunk/web-src/pages/faq.xml =================================================================== --- trunk/web-src/pages/faq.xml 2010-10-31 20:33:51 UTC (rev 286) +++ trunk/web-src/pages/faq.xml 2010-10-31 20:37:40 UTC (rev 287) @@ -24,7 +24,7 @@ <div class="QandAentry"> <h3 class="question"><a id="whenRelease" class="anchorLink">When will a working version be released?</a></h3> <div class="answer"> - <p>Hopefully, a full working version will be out for May 2010, when the deadline to defend KTutorial as my final project in my Computer Engineering university course ends.</p> + <p>Version 0.4, released 2010-10-30, can be considered a working version. However, it still lacks several features, so it is a working version, but not a fully working version. I have no idea when, if ever, the fully working version will be ready.</p> <p>Meanwhile, some prototypes will be released which will gain functionality over releases. I hope I'll be able to follow the <a href="http://www.free-soft.org/literature/papers/esr/cathedral-bazaar/cathedral-bazaar-4.html" title="The Cathedral and the Bazaar: Release early, release often">Release early, release often</a> model. I can't promise it, however ;)</p> </div> </div> @@ -41,6 +41,6 @@ </div> </div> - <p class="lastUpdated">Last updated: 2010-01-30</p> + <p class="lastUpdated">Last updated: 2010-10-30</p> </page:content> </page> Modified: trunk/web-src/pages/index.xml =================================================================== --- trunk/web-src/pages/index.xml 2010-10-31 20:33:51 UTC (rev 286) +++ trunk/web-src/pages/index.xml 2010-10-31 20:37:40 UTC (rev 287) @@ -26,6 +26,21 @@ <div id="news"> <div class="new"> <h2 class="newTitle"> + <a id="newId4" class="anchorLink">KTutorial 0.4 released!</a> + </h2> + <div class="newBody"> + <p class="newDate">2010-10-30</p> + <div class="newContent"> + <div> + <p>This release was geared mostly towards improving KTutorial editor (for example, tutorials can be saved and loaded now), although improvements were made also to KTutorial library (like being able to highlight widgets).</p> + <p>The <a href="http://sourceforge.net/projects/ktutorial/files/ktutorial-0.4/Release notes/view" title="KTutorial 0.4 release notes">release notes</a> contain more information about the changes from 0.3 release.</p> + <p>Check the <a href="download.html" title="Download page in KTutorial web">download page</a> for information about downloading and building KTutorial.</p> + </div> + </div> + </div> + </div> + <div class="new"> + <h2 class="newTitle"> <a id="newId3" class="anchorLink">KTutorial 0.3 released!</a> </h2> <div class="newBody"> Modified: trunk/web-src/pages/news.xml =================================================================== --- trunk/web-src/pages/news.xml 2010-10-31 20:33:51 UTC (rev 286) +++ trunk/web-src/pages/news.xml 2010-10-31 20:37:40 UTC (rev 287) @@ -23,6 +23,21 @@ <div id="news"> <div class="new"> <h2 class="newTitle"> + <a id="newId4" class="anchorLink">KTutorial 0.4 released!</a> + </h2> + <div class="newBody"> + <p class="newDate">2010-10-30</p> + <div class="newContent"> + <div> + <p>This release was geared mostly towards improving KTutorial editor (for example, tutorials can be saved and loaded now), although improvements were made also to KTutorial library (like being able to highlight widgets).</p> + <p>The <a href="http://sourceforge.net/projects/ktutorial/files/ktutorial-0.4/Release notes/view" title="KTutorial 0.4 release notes">release notes</a> contain more information about the changes from 0.3 release.</p> + <p>Check the <a href="download.html" title="Download page in KTutorial web">download page</a> for information about downloading and building KTutorial.</p> + </div> + </div> + </div> + </div> + <div class="new"> + <h2 class="newTitle"> <a id="newId3" class="anchorLink">KTutorial 0.3 released!</a> </h2> <div class="newBody"> Modified: trunk/web-src/pages/screenshotsGallery.xml =================================================================== --- trunk/web-src/pages/screenshotsGallery.xml 2010-10-31 20:33:51 UTC (rev 286) +++ trunk/web-src/pages/screenshotsGallery.xml 2010-10-31 20:37:40 UTC (rev 287) @@ -27,6 +27,12 @@ <img src="images/screenshots/SetReactionData-192.png" alt="KTutorial editor dialog to set the trigger and response of a reaction" width="192" height="221"/> </a> </li> + <li> + <p>KTutorial editor: Signal name completion</p> + <a href="images/screenshots/SignalNameCompletion.png" title="Click for full size"> + <img src="images/screenshots/SignalNameCompletion-192.png" alt="KTutorial editor text completion of signal names emitted by an object in the target application" width="192" height="91"/> + </a> + </li> </ul> </page:content> </page> Modified: trunk/web-src/screenshotsList.xml =================================================================== --- trunk/web-src/screenshotsList.xml 2010-10-31 20:33:51 UTC (rev 286) +++ trunk/web-src/screenshotsList.xml 2010-10-31 20:37:40 UTC (rev 287) @@ -21,4 +21,10 @@ <img src="images/screenshots/SetReactionData-192.png" alt="KTutorial editor dialog to set the trigger and response of a reaction" width="192" height="221"/> </a> </li> + <li> + <p>KTutorial editor: Signal name completion</p> + <a href="images/screenshots/SignalNameCompletion.png" title="Click for full size"> + <img src="images/screenshots/SignalNameCompletion-192.png" alt="KTutorial editor text completion of signal names emitted by an object in the target application" width="192" height="91"/> + </a> + </li> </ul> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dan...@us...> - 2010-10-31 20:33:57
|
Revision: 286 http://ktutorial.svn.sourceforge.net/ktutorial/?rev=286&view=rev Author: danxuliu Date: 2010-10-31 20:33:51 +0000 (Sun, 31 Oct 2010) Log Message: ----------- Add Creative Commons license button in page footer. Modified Paths: -------------- trunk/web-src/data/style/style.css trunk/web-src/transformers/footer.xsl Added Paths: ----------- trunk/web-src/data/images/cc-by-sa-88x31.png trunk/web-src/data/images/cc-by-sa.png Added: trunk/web-src/data/images/cc-by-sa-88x31.png =================================================================== (Binary files differ) Property changes on: trunk/web-src/data/images/cc-by-sa-88x31.png ___________________________________________________________________ Added: svn:mime-type + image/png Added: trunk/web-src/data/images/cc-by-sa.png =================================================================== (Binary files differ) Property changes on: trunk/web-src/data/images/cc-by-sa.png ___________________________________________________________________ Added: svn:mime-type + image/png Modified: trunk/web-src/data/style/style.css =================================================================== --- trunk/web-src/data/style/style.css 2010-10-30 15:02:44 UTC (rev 285) +++ trunk/web-src/data/style/style.css 2010-10-31 20:33:51 UTC (rev 286) @@ -220,7 +220,7 @@ display: inline; } -#validation { +#buttons { text-align: center; } Modified: trunk/web-src/transformers/footer.xsl =================================================================== --- trunk/web-src/transformers/footer.xsl 2010-10-30 15:02:44 UTC (rev 285) +++ trunk/web-src/transformers/footer.xsl 2010-10-31 20:33:51 UTC (rev 286) @@ -21,8 +21,13 @@ <xsl:template name="footer"> <xsl:comment> Footer </xsl:comment> <div id="footer"> - <div id="validation"> + <div id="buttons"> <p> + <a href="http://creativecommons.org/licenses/by-sa/3.0/" title="Creative Commons Attribution-ShareAlike 3.0 Unported License"> + <img src="images/cc-by-sa.png" alt="This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License" height="15" width="80"/> + </a> + </p> + <p> <a href="http://validator.w3.org/check?uri=referer" title="Check XHTML"> <img src="images/valid-xhtml11.png" alt="Valid XHTML 1.1!" height="15" width="80"/> </a> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dan...@us...> - 2010-10-30 15:02:50
|
Revision: 285 http://ktutorial.svn.sourceforge.net/ktutorial/?rev=285&view=rev Author: danxuliu Date: 2010-10-30 15:02:44 +0000 (Sat, 30 Oct 2010) Log Message: ----------- 0.4 release tagged Added Paths: ----------- tags/ktutorial-0.4/ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dan...@us...> - 2010-10-29 23:05:23
|
Revision: 283 http://ktutorial.svn.sourceforge.net/ktutorial/?rev=283&view=rev Author: danxuliu Date: 2010-10-29 23:05:17 +0000 (Fri, 29 Oct 2010) Log Message: ----------- Make QueuedActionsHelper objects child of the test objects instead of deleting them using QTimer::singleShot(..., SLOT(deleteLater())). Modified Paths: -------------- trunk/ktutorial/ktutorial-editor/tests/unit/view/RemoteObjectChooserTest.cpp trunk/ktutorial/ktutorial-library/tests/WaitForWindowTest.cpp trunk/ktutorial/ktutorial-library/tests/view/StepWidgetTest.cpp trunk/ktutorial/ktutorial-library/tests/view/WindowOnTopEnforcerTest.cpp Modified: trunk/ktutorial/ktutorial-editor/tests/unit/view/RemoteObjectChooserTest.cpp =================================================================== --- trunk/ktutorial/ktutorial-editor/tests/unit/view/RemoteObjectChooserTest.cpp 2010-10-29 21:47:59 UTC (rev 282) +++ trunk/ktutorial/ktutorial-editor/tests/unit/view/RemoteObjectChooserTest.cpp 2010-10-29 23:05:17 UTC (rev 283) @@ -450,11 +450,14 @@ Q_OBJECT public: - QueuedActionsHelper(QWidget* widget = 0): - QObject(widget), - mWidget(widget) { + QueuedActionsHelper(QObject* parent = 0): QObject(parent), + mWidget(0) { } + void setWidget(QWidget* widget) { + mWidget = widget; + } + public slots: void closeInformation() const { @@ -497,22 +500,20 @@ }; void RemoteObjectChooserTest::closeInformationMessageBox(int timeToWait) { - QueuedActionsHelper* helper = new QueuedActionsHelper(); + QueuedActionsHelper* helper = new QueuedActionsHelper(this); QTimer::singleShot(timeToWait, helper, SLOT(closeInformation())); - QTimer::singleShot(timeToWait, helper, SLOT(deleteLater())); } void RemoteObjectChooserTest::closeSorryMessageBox(QWidget* widget, int timeToWait) { - QueuedActionsHelper* helper = new QueuedActionsHelper(widget); + QueuedActionsHelper* helper = new QueuedActionsHelper(this); + helper->setWidget(widget); QTimer::singleShot(timeToWait, helper, SLOT(closeSorry())); - QTimer::singleShot(timeToWait, helper, SLOT(deleteLater())); } void RemoteObjectChooserTest::killTargetApplication(int timeToWait) { - QueuedActionsHelper* helper = new QueuedActionsHelper(); + QueuedActionsHelper* helper = new QueuedActionsHelper(this); QTimer::singleShot(timeToWait, helper, SLOT(killTargetApplication())); - QTimer::singleShot(timeToWait, helper, SLOT(deleteLater())); } QTreeView* RemoteObjectChooserTest::remoteObjectsTreeView( Modified: trunk/ktutorial/ktutorial-library/tests/WaitForWindowTest.cpp =================================================================== --- trunk/ktutorial/ktutorial-library/tests/WaitForWindowTest.cpp 2010-10-29 21:47:59 UTC (rev 282) +++ trunk/ktutorial/ktutorial-library/tests/WaitForWindowTest.cpp 2010-10-29 23:05:17 UTC (rev 283) @@ -218,7 +218,7 @@ Q_OBJECT public: - QueuedActionsHelper(QObject* object = 0): QObject(object) { + QueuedActionsHelper(QObject* parent = 0): QObject(parent) { } void setWaitForWindow(WaitForWindow* waitForWindow) { @@ -246,11 +246,10 @@ void WaitForWindowTest::queueAssertConditionMet(WaitForWindow* waitForWindow, QSignalSpy* waitEndedSpy, int timeToWait) { - QueuedActionsHelper* helper = new QueuedActionsHelper(); + QueuedActionsHelper* helper = new QueuedActionsHelper(this); helper->setWaitForWindow(waitForWindow); helper->setWaitEndedSpy(waitEndedSpy); QTimer::singleShot(timeToWait, helper, SLOT(assertConditionMet())); - QTimer::singleShot(timeToWait, helper, SLOT(deleteLater())); } QTEST_MAIN(WaitForWindowTest) Modified: trunk/ktutorial/ktutorial-library/tests/view/StepWidgetTest.cpp =================================================================== --- trunk/ktutorial/ktutorial-library/tests/view/StepWidgetTest.cpp 2010-10-29 21:47:59 UTC (rev 282) +++ trunk/ktutorial/ktutorial-library/tests/view/StepWidgetTest.cpp 2010-10-29 23:05:17 UTC (rev 283) @@ -362,7 +362,7 @@ Q_OBJECT public: - QueuedActionsHelper(QObject* object = 0): QObject(object) { + QueuedActionsHelper(QObject* parent = 0): QObject(parent) { } void setStepWidget(StepWidget* stepWidget) { @@ -407,10 +407,9 @@ void StepWidgetTest::queueAssertWidgetDragged(StepWidget* stepWidget, int timeToWait) { - QueuedActionsHelper* helper = new QueuedActionsHelper(); + QueuedActionsHelper* helper = new QueuedActionsHelper(this); helper->setStepWidget(stepWidget); QTimer::singleShot(timeToWait, helper, SLOT(assertWidgetDragged())); - QTimer::singleShot(timeToWait + 1000, helper, SLOT(deleteLater())); } } Modified: trunk/ktutorial/ktutorial-library/tests/view/WindowOnTopEnforcerTest.cpp =================================================================== --- trunk/ktutorial/ktutorial-library/tests/view/WindowOnTopEnforcerTest.cpp 2010-10-29 21:47:59 UTC (rev 282) +++ trunk/ktutorial/ktutorial-library/tests/view/WindowOnTopEnforcerTest.cpp 2010-10-29 23:05:17 UTC (rev 283) @@ -780,7 +780,7 @@ Q_OBJECT public: - QueuedActionsHelper(QObject* object = 0): QObject(object) { + QueuedActionsHelper(QObject* parent = 0): QObject(parent) { } void setAssertWidget(QWidget* widget) { @@ -812,19 +812,17 @@ void WindowOnTopEnforcerTest::queueAssertParent(QWidget* widget, QWidget* parent, int timeToWait) { - QueuedActionsHelper* helper = new QueuedActionsHelper(); + QueuedActionsHelper* helper = new QueuedActionsHelper(this); helper->setAssertWidget(widget); helper->setAssertParent(parent); QTimer::singleShot(timeToWait, helper, SLOT(assertParent())); - QTimer::singleShot(timeToWait, helper, SLOT(deleteLater())); } void WindowOnTopEnforcerTest::queueAssertIsVisibleWindow(QWidget* widget, int timeToWait) { - QueuedActionsHelper* helper = new QueuedActionsHelper(); + QueuedActionsHelper* helper = new QueuedActionsHelper(this); helper->setAssertWidget(widget); QTimer::singleShot(timeToWait, helper, SLOT(assertIsVisibleWindow())); - QTimer::singleShot(timeToWait, helper, SLOT(deleteLater())); } void WindowOnTopEnforcerTest::assertWindow(QWidget* window, This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dan...@us...> - 2010-10-29 21:48:05
|
Revision: 282 http://ktutorial.svn.sourceforge.net/ktutorial/?rev=282&view=rev Author: danxuliu Date: 2010-10-29 21:47:59 +0000 (Fri, 29 Oct 2010) Log Message: ----------- Update English handbook. Modified Paths: -------------- trunk/ktutorial/ktutorial-editor/doc/en/commands.docbook trunk/ktutorial/ktutorial-editor/doc/en/installation.docbook trunk/ktutorial/ktutorial-editor/doc/en/main-window.png trunk/ktutorial/ktutorial-editor/doc/en/new-condition.png trunk/ktutorial/ktutorial-editor/doc/en/set-step-data.png trunk/ktutorial/ktutorial-editor/doc/en/using.docbook Added Paths: ----------- trunk/ktutorial/ktutorial-editor/doc/en/signal-name-completion.png Modified: trunk/ktutorial/ktutorial-editor/doc/en/commands.docbook =================================================================== --- trunk/ktutorial/ktutorial-editor/doc/en/commands.docbook 2010-10-29 21:43:09 UTC (rev 281) +++ trunk/ktutorial/ktutorial-editor/doc/en/commands.docbook 2010-10-29 21:47:59 UTC (rev 282) @@ -17,7 +17,81 @@ <varlistentry> <term> <menuchoice> + <shortcut> + <keycombo action="simul">&Ctrl;<keycap>N</keycap></keycombo> + </shortcut> <guimenu>File</guimenu> + <guimenuitem>New</guimenuitem> + </menuchoice> + </term> + <listitem> + <para> + <action>Creates a new tutorial.</action> + </para> + </listitem> + </varlistentry> + <varlistentry> + <term> + <menuchoice> + <shortcut> + <keycombo action="simul">&Ctrl;<keycap>O</keycap></keycombo> + </shortcut> + <guimenu>File</guimenu> + <guimenuitem>Open...</guimenuitem> + </menuchoice> + </term> + <listitem> + <para> + <action>Opens a saved tutorial.</action> + </para> + </listitem> + </varlistentry> + <varlistentry> + <term> + <menuchoice> + <guimenu>File</guimenu> + <guimenuitem>Open Recent</guimenuitem> + </menuchoice> + </term> + <listitem> + <para> + <action>Opens a tutorial from the list of the most recently used tutorials.</action> + </para> + </listitem> + </varlistentry> + <varlistentry> + <term> + <menuchoice> + <shortcut> + <keycombo action="simul">&Ctrl;<keycap>S</keycap></keycombo> + </shortcut> + <guimenu>File</guimenu> + <guimenuitem>Save</guimenuitem> + </menuchoice> + </term> + <listitem> + <para> + <action>Saves the tutorial to the current file.</action> + </para> + </listitem> + </varlistentry> + <varlistentry> + <term> + <menuchoice> + <guimenu>File</guimenu> + <guimenuitem>Save As...</guimenuitem> + </menuchoice> + </term> + <listitem> + <para> + <action>Saves the tutorial to the selected file.</action> + </para> + </listitem> + </varlistentry> + <varlistentry> + <term> + <menuchoice> + <guimenu>File</guimenu> <guimenuitem>Export...</guimenuitem> </menuchoice> </term> @@ -54,7 +128,39 @@ <varlistentry> <term> <menuchoice> + <shortcut> + <keycombo action="simul">&Ctrl;<keycap>Z</keycap></keycombo> + </shortcut> <guimenu>Edit</guimenu> + <guimenuitem>Undo</guimenuitem> + </menuchoice> + </term> + <listitem> + <para> + <action>Undoes the last edition action not undone yet.</action> + </para> + </listitem> + </varlistentry> + <varlistentry> + <term> + <menuchoice> + <shortcut> + <keycombo action="simul">&Ctrl;&Shift;<keycap>Z</keycap></keycombo> + </shortcut> + <guimenu>Edit</guimenu> + <guimenuitem>Redo</guimenuitem> + </menuchoice> + </term> + <listitem> + <para> + <action>Does again the last undone edition action not redone yet.</action> + </para> + </listitem> + </varlistentry> + <varlistentry> + <term> + <menuchoice> + <guimenu>Edit</guimenu> <guimenu>Tutorial</guimenu> <guimenuitem>Set information...</guimenuitem> </menuchoice> @@ -219,6 +325,19 @@ </para> </listitem> </varlistentry> + <varlistentry> + <term> + <menuchoice> + <guimenu>Edit</guimenu> + <guimenuitem>Test tutorial</guimenuitem> + </menuchoice> + </term> + <listitem> + <para> + <action>Starts the tutorial in the target application.</action> + </para> + </listitem> + </varlistentry> </variablelist> </para> </sect2> Modified: trunk/ktutorial/ktutorial-editor/doc/en/installation.docbook =================================================================== --- trunk/ktutorial/ktutorial-editor/doc/en/installation.docbook 2010-10-29 21:43:09 UTC (rev 281) +++ trunk/ktutorial/ktutorial-editor/doc/en/installation.docbook 2010-10-29 21:47:59 UTC (rev 282) @@ -7,7 +7,7 @@ <appendix id="installation"> <title>Installation</title> - <sect1 id="getting-klusi"> + <sect1 id="getting-ktutorial"> <title>How to obtain &ktutorial-editor;</title> <para>&ktutorial-editor; is part of KTutorial package, which is hosted at <ulink url="http://sourceforge.net/">SourceForge.net</ulink>.</para> @@ -24,6 +24,8 @@ <para>In order to successfully build and use KTutorial, you need &kde; (at least version 4.3) and, therefore, &Qt; (at least version 4.5.3).</para> + <para>To use the full feature set of &ktutorial-editor; you will also need the QtDBus module of Qt, only available in Unix systems. Without that module &ktutorial-editor; can not talk to the target application, for example to know the name of its objects.</para> + <para>Also, <application>CMake</application> build system is required to build KTutorial, as required to build any other &kde; application.</para> </sect1> Modified: trunk/ktutorial/ktutorial-editor/doc/en/main-window.png =================================================================== (Binary files differ) Modified: trunk/ktutorial/ktutorial-editor/doc/en/new-condition.png =================================================================== (Binary files differ) Modified: trunk/ktutorial/ktutorial-editor/doc/en/set-step-data.png =================================================================== (Binary files differ) Added: trunk/ktutorial/ktutorial-editor/doc/en/signal-name-completion.png =================================================================== (Binary files differ) Property changes on: trunk/ktutorial/ktutorial-editor/doc/en/signal-name-completion.png ___________________________________________________________________ Added: svn:mime-type + image/png Modified: trunk/ktutorial/ktutorial-editor/doc/en/using.docbook =================================================================== --- trunk/ktutorial/ktutorial-editor/doc/en/using.docbook 2010-10-29 21:43:09 UTC (rev 281) +++ trunk/ktutorial/ktutorial-editor/doc/en/using.docbook 2010-10-29 21:47:59 UTC (rev 282) @@ -24,7 +24,7 @@ <para>The most interesting feature is that, with KTutorial, applications can explain to the user how to do something in an interactive way. Each step contains one or more reactions. A reaction is composed by a trigger and a response: when the reaction is triggered, the response is executed.</para> - <para>There are two types of triggers: options and conditions to wait for. Options are shown to the user as buttons below the text of the step, and the response is executed when the user selects the option. Conditions to wait for are not show in any way to the user, and the response is executed when the condition is met. For example, when an object receives an event, or when an object emits a signal.</para> + <para>There are two types of triggers: options and conditions to wait for. Options are shown to the user as buttons below the text of the step, and the response is executed when the user selects the option. Conditions to wait for are not shown in any way to the user, and the response is executed when the condition is met. For example, when an object receives an event, or when an object emits a signal.</para> <para>There are also two types of responses: changing to another step, or executing some custom code.</para> @@ -40,7 +40,7 @@ <para>When the scripted tutorial is part of an application (it is installed with the rest of the application data when the application is installed), the strings in the scripted tutorial can be extracted to be localized before the installation like any other string in the C++ code, as explained in KTutorial documentation. Scripted tutorials that are added after the application was installed, however, can not be localized, as KTutorial uses the same translation file as the rest of the application where it is used.</para> - <para>As you may have guessed already, &ktutorial-editor; creates scripted tutorials. Right now, only Javascript is supported, as &kde; libraries offer out of the box support for Javascript scripts. Python or Ruby, on the other hand, require some specific packages to be installed in the system.</para> + <para>As you may have guessed already, &ktutorial-editor; creates scripted tutorials. Right now, only Javascript is supported by &ktutorial-editor;, as &kde; libraries offer out of the box support for Javascript scripts. Python or Ruby, on the other hand, require some specific packages to be installed in the system.</para> </sect1> <sect1 id="main-window"> @@ -56,6 +56,8 @@ <para>As well as being shown in the <guimenu>Edit</guimenu> menu, the actions to edit a tutorial, a step and a reaction are shown in three panels provided for convenience. The panels can be shown or hidden from <guimenu>View</guimenu> menu, and can be docked to the top, bottom, right or left side of the main window. If desired, they can also be dragged out of the window to make them floating panels.</para> + <para>Every edition action can be undone and redone using the typical undo/redo system. Note, however, that the whole action is undone/redone, and not each tiny change that make up the action. That is, when an edition dialog is opened, several changes are made in the dialog, the dialog is accepted and then the action is undone, the tutorial will get back to the state it had before the edition dialog was opened, no matter what or how many changes were made while the dialog was opened.</para> + <screenshot> <screeninfo>The main window of &ktutorial-editor; with a tutorial being worked on</screeninfo> <mediaobject> @@ -115,6 +117,11 @@ <title>Step edition</title> <para>The step data dialog is used to set the id and text of a step. The id and text are mandatory properties, as the id is used by other steps to change to this step, and the text is shown to the user to explain him what must be done. Thus, the id must be unique for every step in the same tutorial.</para> + <tip> + <title>Rich text and widget higlighting</title> + <para>When writing the text of a step you can use the <ulink url="http://doc.trolltech.com/richtext-html-subset.html">supported subset of HTML tags</ulink> or the <ulink url="http://techbase.kde.org/Development/Tutorials/Localization/i18n_Semantics#Semantic_Tags">KDE semantic markup tags</ulink> to enrich the text. For example, <emphasis><strong>Hello world!</strong></emphasis> will appear as <emphasis role="strong">Hello world!</emphasis> when shown in the tutorial.</para> + <para>KTutorial also provides a special type of link that highlights the referenced widget in order to be found easily. For example, <emphasis><a href="widget:theWidgetObjectName">this is a link</a></emphasis> (if the HTML subset is used) or <emphasis><link url="widget:theWidgetObjectName">this is a link</link></emphasis> (if KDE semantic markup is used) will show <emphasis>this is a link</emphasis> with a link appearance (underlined and with some special color) and, when the link is clicked, the widget with the given object name will be highlighted. Clicking the link again will stop highlighting the widget.</para> + </tip> <para>The step data dialog is also shown when a new step is added. If the dialog is accepted, the step is added. If the dialog is cancelled, the step is not added.</para> <para>Also note that, in every tutorial, there must be one step with id <emphasis>start</emphasis>, so KTutorial knows where to start the tutorial.</para> @@ -172,19 +179,90 @@ </mediaobject> </screenshot> - <para>Only simple conditions (waiting for an event and waiting for a signal) can be edited, showing specific dialogs for it. Composed conditions only group other conditions, so they don't have properties to be edited.</para> + <para>Only simple conditions (waiting for an event, waiting for a signal and waiting for a window to be shown) can be edited, showing specific dialogs for it. Composed conditions only group other conditions, so they don't have properties to be edited.</para> <para>Any condition can be removed from its parent composed condition, or from the reaction if it is the root condition.</para> <para>There is a special type of condition that verifies that its negated condition wasn't met which purpose is to be used only as a child of a composed condition that waits until all its child conditions were met. The idea is that, when the negated condition wasn't met, the special condition is met. When the negated condition is met, the special condition is no longer met. It can be used, for example, to make a reaction wait for the user to write something in a text line, provided he has not pressed a button before. Note that a fallback reaction should be added in cases like this one.</para> + + <important> + <title>Conditions and modal dialogs</title> + <para>Modal dialogs are those that block the interaction with the windows of the application under them (for example, an error message). When a modal dialog is shown by the application after the user clicks a button, the condition to wait for must be the dialog being shown, but never the button being clicked. The reason has to do with Qt's internals and it is out of the scope for this document.</para> + <para>Take, for example, an <emphasis>Open file</emphasis> dialog. If the condition to change to the next step is waiting for the <function>clicked()</function> signal to be emitted by the button that shows the dialog, the step will freeze until the <emphasis>Open file</emphasis> dialog is closed, and then it will change to the next step. Instead, the condition to change to the next step must be waiting for the <emphasis>Open file</emphasis> dialog to be shown.</para> + <para>The condition to wait for windows to be shown supports both windows and dialogs, so whenever a window or dialog is shown you can safely use that condition without worrying about whether it is a window, a modal dialog or a modeless dialog.</para> + </important> </sect3> </sect2> </sect1> + <sect1 id="target-application"> + <title>Interacting with the target application</title> + + <para>When a tutorial is being designed it is usually necessary to know some internals about the target application of the tutorial. For example, in order to wait for a signal emitted by an object the name of the object must be known. However, it is very unlikely that even the developers of the application know those things by heart.</para> + <para>To help with this problem &ktutorial-editor; is able to "talk" with any application using KTutorial to provide the tutorial designer internal information about the target application. For example, it can provide a list with the names of all the objects accessible by KTutorial in the target application.</para> + <para>Note, however, that the intercommunication system between &ktutorial-editor; and KTutorial works only if they were built with D-Bus system support. Don't worry, though, as it would be very unlikely that the packages of your GNU/Linux distribution were not built with D-Bus support, and if you are building it yourself you probably know what all this means ;)</para> + + <sect2 id="target-application-start"> + <title>Starting the target application</title> + + <para>&ktutorial-editor; requires an instance of the target application to be running in order to talk with it, although that instance must have been launched by &ktutorial-editor; itself.</para> + <para>So, how can the target application be started from &ktutorial-editor;? When you execute some action that requires &ktutorial-editor; to talk to the target application a dialog to choose the application is shown to you. The application can be selected from the proposed application list, or the full path to the application can be manually specified.</para> + <para>Note that the application list contains all the known KDE applications in the system, instead of just those that use KTutorial. &ktutorial-editor; will warn you after launching the application if it is not a valid application.</para> + <para>Once a valid target application has been specified it will be used automatically until the tutorial being designed is closed. If the target application instance is closed, &ktutorial-editor; will launch another instance automatically when it needs to talk again to the target application.</para> + </sect2> + + <sect2 id="target-application-object-choosing"> + <title>Choosing an object in the target application</title> + + <para>When you want to choose an object from the target application a list with all the objects accessible by &ktutorial-editor; in the target application is shown. The name and class of each object is shown in their entry of the list. The list is an hierarchical structure, thus the parent-child relationship between objects is also shown.</para> + <para>The list is updated when there are changes in the target application. For example, if a new dialog is shown in the target application, the dialog and all its children will be shown in the list.</para> + <para>Usually, the objects used in tutorials are widgets, so when a widget is selected in the list it is highlighted in the target application. Plain objects obviously are not, as they do not have a graphical representation.</para> + <para>When the list with the objects is shown, the rest of the &ktutorial-editor; windows are hidden. It is made to better view the widgets when they are highlighted in the target application. The &ktutorial-editor; windows are shown again once the selection list is closed.</para> + </sect2> + + <sect2 id="target-application-tutorial-testing"> + <title>Testing a tutorial in the target application</title> + + <para>Designing a tutorial is not a failproof task. Maybe your custom code does not work as expected, or you are not waiting for the right signal to be emitted, or you forgot some step, or... so the tutorial will have to be tested at least once, but more likely several times.</para> + <para>Exporting the tutorial to the application data directory and then starting the target application each time you want to test the tutorial can be very tedious. To ease testing the tutorial, &ktutorial-editor; is able to start the tutorial being designed directly in the target application.</para> + <para>Note, however, that after closing the tutorial the target application will know nothing about it. You will have to use the test action in &ktutorial-editor; to start it again, or <link linkend="export-tutorial">export</link> it to a directory known by KTutorial if you want to start it from the application itself.</para> + </sect2> + + <sect2 id="target-application-other"> + <title>Other less noticeable features</title> + + <para>Besides those already mentioned, &ktutorial-editor; uses a running target application to provide other small yet useful features.</para> + <para>The one-line text editors to set the name of an object have text completion, so if instead of choosing the object its name is written directly in the text editor it will suggest the name based on the objects in the target application.</para> + <para>The one-line text editor to set the name of a signal also has text completion, so when the object name was set, the text editor will suggest the signal name based on the signals that can be emitted by that object.</para> + <para>The text completion uses the standard KDE text completion system, so all the standard keyboard shortcuts can be used (like <keycombo action="simul">&Ctrl;<keycap>T</keycap></keycombo> to show all the available completions).</para> + + <screenshot> + <screeninfo>An example of text completion for a signal name</screeninfo> + <mediaobject> + <imageobject> + <imagedata fileref="signal-name-completion.png" format="PNG"/> + </imageobject> + <textobject> + <phrase>Signal name completion</phrase> + </textobject> + </mediaobject> + </screenshot> + </sect2> + </sect1> + + <sect1 id="save-load-tutorial"> + <title>Saving and loading again the tutorial</title> + + <para>&ktutorial-editor; supports saving a tutorial being designed so it can be loaded later to continue working on it. To do this, just use the standard <menuchoice><guimenu>File</guimenu><guimenuitem>Save</guimenuitem></menuchoice> and <menuchoice><guimenu>File</guimenu><guimenuitem>Open...</guimenuitem></menuchoice> menu entries.</para> + <para>Note that tutorials are saved in an XML format specific to &ktutorial-editor;. A tutorial saved by &ktutorial-editor; can not be used in KTutorial. The tutorial must be <link linkend="export-tutorial">exported</link> before KTutorial can understand it.</para> + <para>Also note that loading and saving a tutorial does not need to be done from or to a local file. Both the dialog to open a tutorial and the dialog to save it support remote directories (via <acronym>FTP</acronym>, <acronym>SSH</acronym>, etc).</para> + <para>When a tutorial is loaded or saved it is added to the recently used file list. <menuchoice><guimenu>File</guimenu><guimenuitem>Open Recent</guimenuitem></menuchoice> provides a quick way to load a recently used tutorial from that list.</para> + </sect1> + <sect1 id="export-tutorial"> <title>Exporting the tutorial</title> <para>Once you have finished designing the tutorial you can export it to a scripted tutorial. To do this, just use <menuchoice><guimenu>File</guimenu><guimenuitem>Export...</guimenuitem></menuchoice>, select where to save the file and you are done. Remember that you have to export the file to some specific directory to be found by KTutorial, as explained in <xref linkend="understanding-ktutorial"/>.</para> - <para>The export dialog supports exporting to remote directories (via <acronym>FTP</acronym>, <acronym>SSH</acronym>, etc), although it will be very strange that you need to use that.</para> + <para>The export dialog also supports exporting to remote directories, although it will be very strange that you need to use that.</para> </sect1> <sect1 id="command-line-options"> @@ -192,6 +270,10 @@ <para>Though &ktutorial-editor; will be usually started from the &kde; program menu, or a desktop icon, it can also be opened from the command line prompt of a terminal window. There are a few options that are available when doing this.</para> + <para>Apart from generic &kde; command line options, &ktutorial-editor; optionally accepts an URL to load a tutorial from it:</para> + <cmdsynopsis><command>ktutorial-editor</command> <arg choice="opt" rep="norepeat">URL</arg></cmdsynopsis> + <para>The URL does not need to be a local file; remote directories are also supported.</para> + <sect2 id="other-command-line-options"> <title>Default &kde; Command Line Options</title> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dan...@us...> - 2010-10-29 19:45:23
|
Revision: 280 http://ktutorial.svn.sourceforge.net/ktutorial/?rev=280&view=rev Author: danxuliu Date: 2010-10-29 19:45:17 +0000 (Fri, 29 Oct 2010) Log Message: ----------- Fix several bugs in WindowOnTopEnforcer behaviour. Modified Paths: -------------- trunk/ktutorial/ktutorial-library/src/view/WindowOnTopEnforcer.cpp trunk/ktutorial/ktutorial-library/src/view/WindowOnTopEnforcer.h trunk/ktutorial/ktutorial-library/tests/view/WindowOnTopEnforcerTest.cpp Modified: trunk/ktutorial/ktutorial-library/src/view/WindowOnTopEnforcer.cpp =================================================================== --- trunk/ktutorial/ktutorial-library/src/view/WindowOnTopEnforcer.cpp 2010-10-29 19:41:20 UTC (rev 279) +++ trunk/ktutorial/ktutorial-library/src/view/WindowOnTopEnforcer.cpp 2010-10-29 19:45:17 UTC (rev 280) @@ -46,40 +46,72 @@ this, SLOT(handleWindowHidden(QWidget*))); } +//private: + +bool WindowOnTopEnforcer::isAncestorOf(QObject* object, + QObject* childObject) const { + if (childObject->parent() == 0) { + return false; + } + + if (childObject->parent() == object) { + return true; + } + + return isAncestorOf(object, childObject->parent()); +} + +void WindowOnTopEnforcer::reparentWindowTo(QWidget* window, + QWidget* parent) const { + //When a widget is reparented it is hidden and its window flags are cleared, + //so they must be restored and the widget shown again + Qt::WindowFlags flags = window->windowFlags(); + window->setParent(parent); + window->setWindowFlags(flags); + window->show(); +} + //private slots: void WindowOnTopEnforcer::handleWindowShown(QWidget* window) { Q_ASSERT(window); - if (!window->isModal()) { + if (!window->isModal() || mParentStack.contains(window)) { return; } + //If the modal window shown is ancestor of any of the modal windows already + //shown just insert it at the appropriate place in the parent stack. + for (int i=1; i<mParentStack.size(); ++i) { + QWidget* widgetInStack = mParentStack[i]; + + if (!isAncestorOf(widgetInStack, window) && + isAncestorOf(window, widgetInStack)) { + mParentStack.insert(i, window); + return; + } + } + mParentStack.push(window); - //When a widget is reparented it is hidden and its window flags are cleared, - //so they must be restored and the widget shown again - Qt::WindowFlags flags = mWidgetToKeepOnTop->windowFlags(); - mWidgetToKeepOnTop->setParent(window); - mWidgetToKeepOnTop->setWindowFlags(flags); - mWidgetToKeepOnTop->show(); + reparentWindowTo(mWidgetToKeepOnTop, window); } void WindowOnTopEnforcer::handleWindowHidden(QWidget* window) { Q_ASSERT(window); - if (!window->isModal()) { + if (!window->isModal() || !mParentStack.contains(window)) { return; } + if (window != mParentStack.top()) { + mParentStack.remove(mParentStack.indexOf(window)); + return; + } + mParentStack.pop(); - //When a widget is reparented it is hidden and its window flags are cleared - //so they must be restored and the widget shown again - Qt::WindowFlags flags = mWidgetToKeepOnTop->windowFlags(); - mWidgetToKeepOnTop->setParent(mParentStack.top()); - mWidgetToKeepOnTop->setWindowFlags(flags); - mWidgetToKeepOnTop->show(); + reparentWindowTo(mWidgetToKeepOnTop, mParentStack.top()); } } Modified: trunk/ktutorial/ktutorial-library/src/view/WindowOnTopEnforcer.h =================================================================== --- trunk/ktutorial/ktutorial-library/src/view/WindowOnTopEnforcer.h 2010-10-29 19:41:20 UTC (rev 279) +++ trunk/ktutorial/ktutorial-library/src/view/WindowOnTopEnforcer.h 2010-10-29 19:45:17 UTC (rev 280) @@ -29,10 +29,10 @@ namespace view { /** - * Utility class to avoid windows being blocked by modal dialogs. - * When a modal dialog is shown, the widget to keep on top is reparented to the - * shown dialog. When the modal dialog is hidden, the widget is reparented to - * its previous parent. + * Utility class to avoid windows being blocked by modal widgets. + * When a modal widget is shown, the widget to keep on top is reparented to the + * shown widget (if necessary). When the modal widget is hidden, the widget is + * reparented to its first previous ancestor still visible. */ class WindowOnTopEnforcer: public QObject { Q_OBJECT @@ -64,14 +64,36 @@ /** * A stack with the parents of the widget to keep on top. * It is used to restore the previous parent when the latest one is hidden. + * It always contains, at least, the base window as its first item. */ QStack<QWidget*> mParentStack; + /** + * Checks whether the given object is ancestor of the given child object. + * + * @param object The object to check if it is the ancestor. + * @param childObject The child object. + * @return True if it is ancestor, false otherwise. + */ + bool isAncestorOf(QObject* object, QObject* childObject) const; + + /** + * Reparents the window to the given parent, preserving its window flags (as + * they are cleared when a new parent is set). + * + * @param window The window to reparent. + * @param parent The new parent. + */ + void reparentWindowTo(QWidget* window, QWidget* parent) const; + private Q_SLOTS: /** - * Reparents the widget to keep on top to the window if it is a modal - * dialog. + * Reparents the widget to keep on top to the window if it is the top most + * modal widget. + * If the window is modal but is parent of the top most modal widget the + * window is just inserted at the appropriate place in the stack. + * If the window is modal but it is already in the stack nothing is done. * * @param window The window that has been shown. */ @@ -79,7 +101,10 @@ /** * Reparents the widget to keep on top to its previous parent if the hidden - * window is a modal dialog. + * window is the top most modal widget. + * If the window is modal but is parent of the top most modal widget the + * window is just removed from the stack. + * If the window is modal but it is not part of the stack nothing is done. * * @param window The window that has been hidden. */ Modified: trunk/ktutorial/ktutorial-library/tests/view/WindowOnTopEnforcerTest.cpp =================================================================== --- trunk/ktutorial/ktutorial-library/tests/view/WindowOnTopEnforcerTest.cpp 2010-10-29 19:41:20 UTC (rev 279) +++ trunk/ktutorial/ktutorial-library/tests/view/WindowOnTopEnforcerTest.cpp 2010-10-29 19:45:17 UTC (rev 280) @@ -43,6 +43,22 @@ void testNestedModalDialogOnChildWindow(); + void testModalWidget(); + + void testModalWidgetSiblingOfParent(); + + void testShowModalWidgetTwice(); + + void testHideNestedModalWidgetsInOrder(); + + void testHideNestedModalWidgetsInReverseOrder(); + + void testShowNestedModalWidgetsInOrder(); + + void testShowNestedModalWidgetsInReverseOrder(); + + void testShowNestedModalWidgetsInMixedOrder(); + private: void queueAssertParent(QWidget* widget, QWidget* parent, int timeToWait); @@ -72,6 +88,14 @@ assertWindow(windowToKeepOnTop, window); + window->hide(); + + assertWindow(windowToKeepOnTop, window); + + window->show(); + + assertWindow(windowToKeepOnTop, window); + delete window; QVERIFY(!windowToKeepOnTop); @@ -94,6 +118,14 @@ assertWindow(windowToKeepOnTop, window); + childWindow->hide(); + + assertWindow(windowToKeepOnTop, window); + + childWindow->show(); + + assertWindow(windowToKeepOnTop, window); + delete childWindow; assertWindow(windowToKeepOnTop, window); @@ -316,6 +348,429 @@ QVERIFY(!windowToKeepOnTop); } +void WindowOnTopEnforcerTest::testModalWidget() { + QWidget* window = new QWidget(); + window->show(); + + QPointer<QWidget> windowToKeepOnTop = new QWidget(window); + windowToKeepOnTop->setWindowFlags(Qt::Window); + windowToKeepOnTop->show(); + + WindowOnTopEnforcer* enforcer = new WindowOnTopEnforcer(windowToKeepOnTop); + enforcer->setBaseWindow(window); + + QWidget* modalWidget = new QWidget(window); + modalWidget->setWindowFlags(Qt::Window); + modalWidget->setWindowModality(Qt::ApplicationModal); + modalWidget->show(); + + assertWindow(windowToKeepOnTop, modalWidget); + + modalWidget->hide(); + + assertWindow(windowToKeepOnTop, window); + + modalWidget->show(); + + assertWindow(windowToKeepOnTop, modalWidget); + + delete modalWidget; + + assertWindow(windowToKeepOnTop, window); + + delete window; + + QVERIFY(!windowToKeepOnTop); +} + +//This test may cause next test to fail (with a segmentation fault) when the +//modal widget in the next test is shown. +//The crash seems to be random, but has nothing to do (checked by isolating the +//code that crashes) with KTutorial classes. +//Under some unknown circumstances (I have yet to see the crash when GDB is +//recording the execution to analyze it properly :( ), "delete window" in +//testModalWidgetSiblingOfParent method makes qt_last_mouse_receiver (declared +//in qapplication_x11.cpp) to get the address of the window (or one of its child +//windows) when it is deleted. +//As the address is no longer valid, when that variable is used internally in +//the next modalWidget->show() ugly things happen. +//Hopefully I'll get enough information about this weird behavior to fill a bug. +void WindowOnTopEnforcerTest::testModalWidgetSiblingOfParent() { + QWidget* window = new QWidget(); + window->show(); + + QPointer<QWidget> windowToKeepOnTop = new QWidget(window); + windowToKeepOnTop->setWindowFlags(Qt::Window); + windowToKeepOnTop->show(); + + WindowOnTopEnforcer* enforcer = new WindowOnTopEnforcer(windowToKeepOnTop); + enforcer->setBaseWindow(window); + + QWidget* siblingModalWidget = new QWidget(window); + siblingModalWidget->setWindowFlags(Qt::Window); + siblingModalWidget->setWindowModality(Qt::ApplicationModal); + siblingModalWidget->show(); + + QWidget* modalWidget = new QWidget(window); + modalWidget->setWindowFlags(Qt::Window); + modalWidget->setWindowModality(Qt::ApplicationModal); + modalWidget->show(); + + assertWindow(windowToKeepOnTop, modalWidget); + + modalWidget->hide(); + + assertWindow(windowToKeepOnTop, siblingModalWidget); + + modalWidget->show(); + + assertWindow(windowToKeepOnTop, modalWidget); + + delete siblingModalWidget; + + assertWindow(windowToKeepOnTop, modalWidget); + + delete modalWidget; + + assertWindow(windowToKeepOnTop, window); + + delete window; + + QVERIFY(!windowToKeepOnTop); +} + +//If a step contains a WaitForWindow and the step it changes to adds two +//WaitForWindows or more in its setup, the WindowOnTopEnforcer will get the Show +//event for the new window twice. +//This is a pretty strange and complex phenomenon that involves some Qt +//internals (http://bugreports.qt.nokia.com/browse/QTBUG-14651): +//Each object contains an internal list with its event filters. When a new +//filter is installed, it is prepended to the list. This list is traversed when +//the events for the object are being filtered; the first filter in the list is +//executed, then the second filter, then the third... and so on until there are +//no more filters in the list (or some filter stopped the event from being +//handled further). +//If a new filter is installed in an object while an event for that object is +//being filtered, the new filter will be prepended, the list will be modified, +//and the filter being executed will now take the next position in the list. +//When the next filter to be executed is fetch it will be the same filter that +//has just been executed. +//When the window that WaitForWindow is waiting for is shown, WaitForWindow will +//change to the next step in the tutorial. When this new step is set up, it adds +//two new WaitForWindows. The WaitForWindows will install a filter for each +//widget, which includes the window that has been shown. So, although it happens +//deep in the call stack, two event filters are installed while an event filter +//for that object is being executed. +//But, why has it to be two and not just one? And why does it affect +//WindowOnTopEnforcer if they are installed in a WaitForWindow? +//The reason is that the filter of the WaitForWindow that changes to the next +//step is the last filter executed, just after the filter of the +//WindowOnTopEnforcer. When the tutorial changes to the next step, it deletes +//the WaitForWindow of the deactivated step, thus removing its filter. Then it +//activates the next step, which causes the two WaitForWindow to be setup, and +//thus two filters are prepended to the filter list. So, as the filter after +//the WindowOnTopEnforcer filter is removed and two new ones are prepended, the +//WindowOnTopEnforcer filter ends one place after the one that was being +//executed. When the execution of that one ends, the end of the list was not +//reached yet, so the loop executes the next filter, and thus causes the +//WindowOnTopEnforcer filter to be executed again. +//And that's all. Strange? I know, I was the one who had to debug it :P +//This test is a synthesized version of all the things explained above. +void WindowOnTopEnforcerTest::testShowModalWidgetTwice() { + QWidget* window = new QWidget(); + window->show(); + + QPointer<QWidget> windowToKeepOnTop = new QWidget(window); + windowToKeepOnTop->setWindowFlags(Qt::Window); + windowToKeepOnTop->show(); + + WindowOnTopEnforcer* enforcer = new WindowOnTopEnforcer(windowToKeepOnTop); + enforcer->setBaseWindow(window); + + QWidget* modalWidget = new QWidget(window); + modalWidget->setWindowFlags(Qt::Window); + modalWidget->setWindowModality(Qt::ApplicationModal); + modalWidget->show(); + + QShowEvent showEvent; + QCoreApplication::sendEvent(modalWidget, &showEvent); + + assertWindow(windowToKeepOnTop, modalWidget); + + modalWidget->hide(); + + assertWindow(windowToKeepOnTop, window); + + delete window; + + QVERIFY(!windowToKeepOnTop); +} + +void WindowOnTopEnforcerTest::testHideNestedModalWidgetsInOrder() { + QWidget* window = new QWidget(); + window->show(); + + QPointer<QWidget> windowToKeepOnTop = new QWidget(window); + windowToKeepOnTop->setWindowFlags(Qt::Window); + windowToKeepOnTop->show(); + + WindowOnTopEnforcer* enforcer = new WindowOnTopEnforcer(windowToKeepOnTop); + enforcer->setBaseWindow(window); + + QWidget* modalWidget = new QWidget(window); + modalWidget->setWindowFlags(Qt::Window); + modalWidget->setWindowModality(Qt::ApplicationModal); + modalWidget->show(); + + QWidget* nestedModalWidget = new QWidget(modalWidget); + nestedModalWidget->setWindowFlags(Qt::Window); + nestedModalWidget->setWindowModality(Qt::ApplicationModal); + nestedModalWidget->show(); + + assertWindow(windowToKeepOnTop, nestedModalWidget); + + nestedModalWidget->hide(); + + assertWindow(windowToKeepOnTop, modalWidget); + + modalWidget->hide(); + + assertWindow(windowToKeepOnTop, window); + + window->hide(); + + assertWindow(windowToKeepOnTop, window); + + delete window; + + QVERIFY(!windowToKeepOnTop); +} + +void WindowOnTopEnforcerTest::testHideNestedModalWidgetsInReverseOrder() { + QWidget* window = new QWidget(); + window->show(); + + QPointer<QWidget> windowToKeepOnTop = new QWidget(window); + windowToKeepOnTop->setWindowFlags(Qt::Window); + windowToKeepOnTop->show(); + + WindowOnTopEnforcer* enforcer = new WindowOnTopEnforcer(windowToKeepOnTop); + enforcer->setBaseWindow(window); + + QWidget* modalWidget = new QWidget(window); + modalWidget->setWindowFlags(Qt::Window); + modalWidget->setWindowModality(Qt::ApplicationModal); + modalWidget->show(); + + QWidget* nestedModalWidget = new QWidget(modalWidget); + nestedModalWidget->setWindowFlags(Qt::Window); + nestedModalWidget->setWindowModality(Qt::ApplicationModal); + nestedModalWidget->show(); + + assertWindow(windowToKeepOnTop, nestedModalWidget); + + window->hide(); + + assertWindow(windowToKeepOnTop, nestedModalWidget); + + modalWidget->hide(); + + assertWindow(windowToKeepOnTop, nestedModalWidget); + + nestedModalWidget->hide(); + + assertWindow(windowToKeepOnTop, window); + + delete window; + + QVERIFY(!windowToKeepOnTop); +} + +void WindowOnTopEnforcerTest::testShowNestedModalWidgetsInOrder() { + QWidget* window = new QWidget(); + window->show(); + + QPointer<QWidget> windowToKeepOnTop = new QWidget(window); + windowToKeepOnTop->setWindowFlags(Qt::Window); + windowToKeepOnTop->show(); + + WindowOnTopEnforcer* enforcer = new WindowOnTopEnforcer(windowToKeepOnTop); + enforcer->setBaseWindow(window); + + QWidget* modalWidget = new QWidget(window); + modalWidget->setWindowFlags(Qt::Window); + modalWidget->setWindowModality(Qt::ApplicationModal); + modalWidget->show(); + + QWidget* nestedModalWidget = new QWidget(modalWidget); + nestedModalWidget->setWindowFlags(Qt::Window); + nestedModalWidget->setWindowModality(Qt::ApplicationModal); + nestedModalWidget->show(); + + assertWindow(windowToKeepOnTop, nestedModalWidget); + + nestedModalWidget->hide(); + modalWidget->hide(); + window->hide(); + + window->show(); + + assertWindow(windowToKeepOnTop, window); + + modalWidget->show(); + + assertWindow(windowToKeepOnTop, modalWidget); + + nestedModalWidget->show(); + + assertWindow(windowToKeepOnTop, nestedModalWidget); + + delete nestedModalWidget; + + assertWindow(windowToKeepOnTop, modalWidget); + + delete modalWidget; + + assertWindow(windowToKeepOnTop, window); + + delete window; + + QVERIFY(!windowToKeepOnTop); +} + +void WindowOnTopEnforcerTest::testShowNestedModalWidgetsInReverseOrder() { + QWidget* window = new QWidget(); + window->show(); + + QPointer<QWidget> windowToKeepOnTop = new QWidget(window); + windowToKeepOnTop->setWindowFlags(Qt::Window); + windowToKeepOnTop->show(); + + WindowOnTopEnforcer* enforcer = new WindowOnTopEnforcer(windowToKeepOnTop); + enforcer->setBaseWindow(window); + + QWidget* modalWidget = new QWidget(window); + modalWidget->setWindowFlags(Qt::Window); + modalWidget->setWindowModality(Qt::ApplicationModal); + modalWidget->show(); + + QWidget* nestedModalWidget = new QWidget(modalWidget); + nestedModalWidget->setWindowFlags(Qt::Window); + nestedModalWidget->setWindowModality(Qt::ApplicationModal); + nestedModalWidget->show(); + + assertWindow(windowToKeepOnTop, nestedModalWidget); + + window->hide(); + modalWidget->hide(); + nestedModalWidget->hide(); + + nestedModalWidget->show(); + + assertWindow(windowToKeepOnTop, nestedModalWidget); + + modalWidget->show(); + + assertWindow(windowToKeepOnTop, nestedModalWidget); + + window->show(); + + assertWindow(windowToKeepOnTop, nestedModalWidget); + + delete nestedModalWidget; + + assertWindow(windowToKeepOnTop, modalWidget); + + delete modalWidget; + + assertWindow(windowToKeepOnTop, window); + + delete window; + + QVERIFY(!windowToKeepOnTop); +} + +void WindowOnTopEnforcerTest::testShowNestedModalWidgetsInMixedOrder() { + QWidget* window = new QWidget(); + window->show(); + + QPointer<QWidget> windowToKeepOnTop = new QWidget(window); + windowToKeepOnTop->setWindowFlags(Qt::Window); + windowToKeepOnTop->show(); + + WindowOnTopEnforcer* enforcer = new WindowOnTopEnforcer(windowToKeepOnTop); + enforcer->setBaseWindow(window); + + QWidget* modalWidget = new QWidget(window); + modalWidget->setWindowFlags(Qt::Window); + modalWidget->setWindowModality(Qt::ApplicationModal); + modalWidget->show(); + + QWidget* nestedModalWidget = new QWidget(modalWidget); + nestedModalWidget->setWindowFlags(Qt::Window); + nestedModalWidget->setWindowModality(Qt::ApplicationModal); + nestedModalWidget->show(); + + QWidget* nestedNestedModalWidget = new QWidget(nestedModalWidget); + nestedNestedModalWidget->setWindowFlags(Qt::Window); + nestedNestedModalWidget->setWindowModality(Qt::ApplicationModal); + nestedNestedModalWidget->show(); + + QWidget* nestedNestedNestedModalWidget = + new QWidget(nestedNestedModalWidget); + nestedNestedNestedModalWidget->setWindowFlags(Qt::Window); + nestedNestedNestedModalWidget->setWindowModality(Qt::ApplicationModal); + nestedNestedNestedModalWidget->show(); + + assertWindow(windowToKeepOnTop, nestedNestedNestedModalWidget); + + window->hide(); + modalWidget->hide(); + nestedModalWidget->hide(); + nestedNestedModalWidget->hide(); + nestedNestedNestedModalWidget->hide(); + + nestedNestedModalWidget->show(); + + assertWindow(windowToKeepOnTop, nestedNestedModalWidget); + + modalWidget->show(); + + assertWindow(windowToKeepOnTop, nestedNestedModalWidget); + + nestedNestedNestedModalWidget->show(); + + assertWindow(windowToKeepOnTop, nestedNestedNestedModalWidget); + + window->show(); + + assertWindow(windowToKeepOnTop, nestedNestedNestedModalWidget); + + nestedModalWidget->show(); + + assertWindow(windowToKeepOnTop, nestedNestedNestedModalWidget); + + delete nestedNestedNestedModalWidget; + + assertWindow(windowToKeepOnTop, nestedNestedModalWidget); + + delete nestedNestedModalWidget; + + assertWindow(windowToKeepOnTop, nestedModalWidget); + + delete nestedModalWidget; + + assertWindow(windowToKeepOnTop, modalWidget); + + delete modalWidget; + + assertWindow(windowToKeepOnTop, window); + + delete window; + + QVERIFY(!windowToKeepOnTop); +} + /////////////////////////////////// Helpers //////////////////////////////////// //The dialogs are modal, so they won't return to the test code until they are This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dan...@us...> - 2010-10-29 19:41:26
|
Revision: 279 http://ktutorial.svn.sourceforge.net/ktutorial/?rev=279&view=rev Author: danxuliu Date: 2010-10-29 19:41:20 +0000 (Fri, 29 Oct 2010) Log Message: ----------- Refactor tests: use QPointer instead of QSignalSpy with destroyed(QObject*) signal, and extract checks to an assertWindow(QWidget* window, QWidget* expectedParent) method. Modified Paths: -------------- trunk/ktutorial/ktutorial-library/tests/view/WindowOnTopEnforcerTest.cpp Modified: trunk/ktutorial/ktutorial-library/tests/view/WindowOnTopEnforcerTest.cpp =================================================================== --- trunk/ktutorial/ktutorial-library/tests/view/WindowOnTopEnforcerTest.cpp 2010-10-27 09:53:15 UTC (rev 278) +++ trunk/ktutorial/ktutorial-library/tests/view/WindowOnTopEnforcerTest.cpp 2010-10-29 19:41:20 UTC (rev 279) @@ -48,6 +48,8 @@ void queueAssertParent(QWidget* widget, QWidget* parent, int timeToWait); void queueAssertIsVisibleWindow(QWidget* widget, int timeToWait); + void assertWindow(QWidget* window, QWidget* expectedParent) const; + }; void WindowOnTopEnforcerTest::testConstructor() { @@ -61,28 +63,25 @@ QWidget* window = new QWidget(); window->show(); - QWidget* windowToKeepOnTop = new QWidget(window); + QPointer<QWidget> windowToKeepOnTop = new QWidget(window); windowToKeepOnTop->setWindowFlags(Qt::Window); windowToKeepOnTop->show(); WindowOnTopEnforcer* enforcer = new WindowOnTopEnforcer(windowToKeepOnTop); enforcer->setBaseWindow(window); - QSignalSpy destroyedSpy(windowToKeepOnTop, SIGNAL(destroyed(QObject*))); + assertWindow(windowToKeepOnTop, window); delete window; - QCOMPARE(destroyedSpy.count(), 1); - QVariant argument = destroyedSpy.at(0).at(0); - QCOMPARE(argument.userType(), (int)QMetaType::QObjectStar); - QCOMPARE(qvariant_cast<QObject*>(argument), windowToKeepOnTop); + QVERIFY(!windowToKeepOnTop); } void WindowOnTopEnforcerTest::testChildWindow() { QWidget* window = new QWidget(); window->show(); - QWidget* windowToKeepOnTop = new QWidget(window); + QPointer<QWidget> windowToKeepOnTop = new QWidget(window); windowToKeepOnTop->setWindowFlags(Qt::Window); windowToKeepOnTop->show(); @@ -93,31 +92,22 @@ childWindow->setWindowFlags(Qt::Window); childWindow->show(); - QCOMPARE(windowToKeepOnTop->parentWidget(), window); - QVERIFY(windowToKeepOnTop->isVisible()); - QVERIFY(windowToKeepOnTop->windowFlags() & Qt::Window); + assertWindow(windowToKeepOnTop, window); delete childWindow; - QCOMPARE(windowToKeepOnTop->parentWidget(), window); - QVERIFY(windowToKeepOnTop->isVisible()); - QVERIFY(windowToKeepOnTop->windowFlags() & Qt::Window); + assertWindow(windowToKeepOnTop, window); - QSignalSpy destroyedSpy(windowToKeepOnTop, SIGNAL(destroyed(QObject*))); - delete window; - QCOMPARE(destroyedSpy.count(), 1); - QVariant argument = destroyedSpy.at(0).at(0); - QCOMPARE(argument.userType(), (int)QMetaType::QObjectStar); - QCOMPARE(qvariant_cast<QObject*>(argument), windowToKeepOnTop); + QVERIFY(!windowToKeepOnTop); } void WindowOnTopEnforcerTest::testModalDialog() { QWidget* window = new QWidget(); window->show(); - QWidget* windowToKeepOnTop = new QWidget(window); + QPointer<QWidget> windowToKeepOnTop = new QWidget(window); windowToKeepOnTop->setWindowFlags(Qt::Window); windowToKeepOnTop->show(); @@ -137,25 +127,18 @@ timerAccept.start(); modalDialog->exec(); - QCOMPARE(windowToKeepOnTop->parentWidget(), window); - QVERIFY(windowToKeepOnTop->isVisible()); - QVERIFY(windowToKeepOnTop->windowFlags() & Qt::Window); + assertWindow(windowToKeepOnTop, window); - QSignalSpy destroyedSpy(windowToKeepOnTop, SIGNAL(destroyed(QObject*))); - delete window; - QCOMPARE(destroyedSpy.count(), 1); - QVariant argument = destroyedSpy.at(0).at(0); - QCOMPARE(argument.userType(), (int)QMetaType::QObjectStar); - QCOMPARE(qvariant_cast<QObject*>(argument), windowToKeepOnTop); + QVERIFY(!windowToKeepOnTop); } void WindowOnTopEnforcerTest::testNestedModalDialog() { QWidget* window = new QWidget(); window->show(); - QWidget* windowToKeepOnTop = new QWidget(window); + QPointer<QWidget> windowToKeepOnTop = new QWidget(window); windowToKeepOnTop->setWindowFlags(Qt::Window); windowToKeepOnTop->show(); @@ -192,25 +175,18 @@ timerAcceptNested.start(); modalDialog->exec(); - QCOMPARE(windowToKeepOnTop->parentWidget(), window); - QVERIFY(windowToKeepOnTop->isVisible()); - QVERIFY(windowToKeepOnTop->windowFlags() & Qt::Window); + assertWindow(windowToKeepOnTop, window); - QSignalSpy destroyedSpy(windowToKeepOnTop, SIGNAL(destroyed(QObject*))); - delete window; - QCOMPARE(destroyedSpy.count(), 1); - QVariant argument = destroyedSpy.at(0).at(0); - QCOMPARE(argument.userType(), (int)QMetaType::QObjectStar); - QCOMPARE(qvariant_cast<QObject*>(argument), windowToKeepOnTop); + QVERIFY(!windowToKeepOnTop); } void WindowOnTopEnforcerTest::testSeveralModalDialogs() { QWidget* window = new QWidget(); window->show(); - QWidget* windowToKeepOnTop = new QWidget(window); + QPointer<QWidget> windowToKeepOnTop = new QWidget(window); windowToKeepOnTop->setWindowFlags(Qt::Window); windowToKeepOnTop->show(); @@ -266,9 +242,7 @@ timerAcceptNested2.start(); modalDialog->exec(); - QCOMPARE(windowToKeepOnTop->parentWidget(), window); - QVERIFY(windowToKeepOnTop->isVisible()); - QVERIFY(windowToKeepOnTop->windowFlags() & Qt::Window); + assertWindow(windowToKeepOnTop, window); QDialog* modalDialog2 = new QDialog(window); QDialog* nestedModalDialog3 = new QDialog(modalDialog); @@ -300,25 +274,18 @@ timerAcceptNested3.start(); modalDialog2->exec(); - QCOMPARE(windowToKeepOnTop->parentWidget(), window); - QVERIFY(windowToKeepOnTop->isVisible()); - QVERIFY(windowToKeepOnTop->windowFlags() & Qt::Window); + assertWindow(windowToKeepOnTop, window); - QSignalSpy destroyedSpy(windowToKeepOnTop, SIGNAL(destroyed(QObject*))); - delete window; - QCOMPARE(destroyedSpy.count(), 1); - QVariant argument = destroyedSpy.at(0).at(0); - QCOMPARE(argument.userType(), (int)QMetaType::QObjectStar); - QCOMPARE(qvariant_cast<QObject*>(argument), windowToKeepOnTop); + QVERIFY(!windowToKeepOnTop); } void WindowOnTopEnforcerTest::testNestedModalDialogOnChildWindow() { QWidget* window = new QWidget(); window->show(); - QWidget* windowToKeepOnTop = new QWidget(window); + QPointer<QWidget> windowToKeepOnTop = new QWidget(window); windowToKeepOnTop->setWindowFlags(Qt::Window); windowToKeepOnTop->show(); @@ -342,18 +309,11 @@ timerAccept.start(); nestedModalDialog->exec(); - QCOMPARE(windowToKeepOnTop->parentWidget(), window); - QVERIFY(windowToKeepOnTop->isVisible()); - QVERIFY(windowToKeepOnTop->windowFlags() & Qt::Window); + assertWindow(windowToKeepOnTop, window); - QSignalSpy destroyedSpy(windowToKeepOnTop, SIGNAL(destroyed(QObject*))); - delete window; - QCOMPARE(destroyedSpy.count(), 1); - QVariant argument = destroyedSpy.at(0).at(0); - QCOMPARE(argument.userType(), (int)QMetaType::QObjectStar); - QCOMPARE(qvariant_cast<QObject*>(argument), windowToKeepOnTop); + QVERIFY(!windowToKeepOnTop); } /////////////////////////////////// Helpers //////////////////////////////////// @@ -412,8 +372,16 @@ QTimer::singleShot(timeToWait, helper, SLOT(deleteLater())); } +void WindowOnTopEnforcerTest::assertWindow(QWidget* window, + QWidget* expectedParent) const { + QVERIFY(window); + QCOMPARE(window->parentWidget(), expectedParent); + QVERIFY(window->isVisible()); + QVERIFY(window->windowFlags() & Qt::Window); } +} + QTEST_MAIN(view::WindowOnTopEnforcerTest) #include "WidgetOnTopEnforcerTest.moc" This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dan...@us...> - 2010-10-27 09:53:22
|
Revision: 278 http://ktutorial.svn.sourceforge.net/ktutorial/?rev=278&view=rev Author: danxuliu Date: 2010-10-27 09:53:15 +0000 (Wed, 27 Oct 2010) Log Message: ----------- Use "|" instead of "->" as delimiter in KDE Semantic Markup "interface" elements. Modified Paths: -------------- trunk/ktutorial/ktutorial-test-app/TutorialClearText.cpp trunk/ktutorial/ktutorial-test-app/TutorialClearText.js trunk/ktutorial/ktutorial-test-app/TutorialClearText.py trunk/ktutorial/ktutorial-test-app/TutorialMoveText.cpp trunk/ktutorial/ktutorial-test-app/TutorialMoveText.py trunk/ktutorial/ktutorial-test-app/po/es.po trunk/ktutorial/ktutorial-test-app/po/ktutorial-test-app.pot Modified: trunk/ktutorial/ktutorial-test-app/TutorialClearText.cpp =================================================================== --- trunk/ktutorial/ktutorial-test-app/TutorialClearText.cpp 2010-10-18 17:41:37 UTC (rev 277) +++ trunk/ktutorial/ktutorial-test-app/TutorialClearText.cpp 2010-10-27 09:53:15 UTC (rev 278) @@ -45,7 +45,7 @@ //Step 2 Step* clearTextStep = new Step("clearText"); - clearTextStep->setText(i18nc("@info", "Now, you must trigger the clear action.<nl/>To do this, you can click in <interface>File->Clear</interface>, or in the toolbar button called <interface>Clear</interface>")); + clearTextStep->setText(i18nc("@info", "Now, you must trigger the clear action.<nl/>To do this, you can click in <interface>File|Clear</interface>, or in the toolbar button called <interface>Clear</interface>")); QObject* clearAction = KTutorial::self()->findObject<QObject*>("clear"); clearTextStep->addWaitFor(new WaitForSignal(clearAction, SIGNAL(triggered(bool))), Modified: trunk/ktutorial/ktutorial-test-app/TutorialClearText.js =================================================================== --- trunk/ktutorial/ktutorial-test-app/TutorialClearText.js 2010-10-18 17:41:37 UTC (rev 277) +++ trunk/ktutorial/ktutorial-test-app/TutorialClearText.js 2010-10-27 09:53:15 UTC (rev 278) @@ -41,7 +41,7 @@ //Step 2 clearTextStep = ktutorial.newStep("clearText"); -clearTextStep.setText(t.i18nc("@info", "Now, you must trigger the clear action.<nl/>To do this, you can click in <interface>File->Clear</interface>, or in the toolbar button called <interface>Clear</interface>")); +clearTextStep.setText(t.i18nc("@info", "Now, you must trigger the clear action.<nl/>To do this, you can click in <interface>File|Clear</interface>, or in the toolbar button called <interface>Clear</interface>")); clearAction = ktutorial.findObject("clear"); Modified: trunk/ktutorial/ktutorial-test-app/TutorialClearText.py =================================================================== --- trunk/ktutorial/ktutorial-test-app/TutorialClearText.py 2010-10-18 17:41:37 UTC (rev 277) +++ trunk/ktutorial/ktutorial-test-app/TutorialClearText.py 2010-10-27 09:53:15 UTC (rev 278) @@ -42,7 +42,7 @@ #Step 2 clearTextStep = ktutorial.newStep("clearText") -clearTextStep.setText(t.i18nc("@info", "Now, you must trigger the clear action.<nl/>To do this, you can click in <interface>File->Clear</interface>, or in the toolbar button called <interface>Clear</interface>")) +clearTextStep.setText(t.i18nc("@info", "Now, you must trigger the clear action.<nl/>To do this, you can click in <interface>File|Clear</interface>, or in the toolbar button called <interface>Clear</interface>")) clearAction = ktutorial.findObject("clear") Modified: trunk/ktutorial/ktutorial-test-app/TutorialMoveText.cpp =================================================================== --- trunk/ktutorial/ktutorial-test-app/TutorialMoveText.cpp 2010-10-18 17:41:37 UTC (rev 277) +++ trunk/ktutorial/ktutorial-test-app/TutorialMoveText.cpp 2010-10-27 09:53:15 UTC (rev 278) @@ -91,7 +91,7 @@ //Step keyboardCut Step* keyboardCutStep = new Step("keyboardCut"); - keyboardCutStep->setText(i18nc("@info", "The next thing to do is cut the selected text. Cutting it will remove it from the text area, but in some Steps we will make it appear again. To cut the selected text, click in <interface>Edit->Cut</interface> or in the button of the toolbar")); + keyboardCutStep->setText(i18nc("@info", "The next thing to do is cut the selected text. Cutting it will remove it from the text area, but in some Steps we will make it appear again. To cut the selected text, click in <interface>Edit|Cut</interface> or in the button of the toolbar")); KAction* cutAction = KTutorial::self()->findObject<KAction*>("edit_cut"); keyboardCutStep->addWaitFor(new WaitForSignal(cutAction, SIGNAL(triggered(bool))), @@ -110,7 +110,7 @@ //Step keyboardPaste Step* keyboardPasteStep = new Step("keyboardPaste"); - keyboardPasteStep->setText(i18nc("@info", "Finally, paste the text you have cut previously. To do this, click in <interface>Edit->Paste</interface> or in the button in the toolbar")); + keyboardPasteStep->setText(i18nc("@info", "Finally, paste the text you have cut previously. To do this, click in <interface>Edit|Paste</interface> or in the button in the toolbar")); KAction* pasteAction = KTutorial::self()->findObject<KAction*>("edit_paste"); keyboardPasteStep->addWaitFor(new WaitForSignal(pasteAction, SIGNAL(triggered(bool))), Modified: trunk/ktutorial/ktutorial-test-app/TutorialMoveText.py =================================================================== --- trunk/ktutorial/ktutorial-test-app/TutorialMoveText.py 2010-10-18 17:41:37 UTC (rev 277) +++ trunk/ktutorial/ktutorial-test-app/TutorialMoveText.py 2010-10-27 09:53:15 UTC (rev 278) @@ -112,7 +112,7 @@ #Step keyboardCut keyboardCutStep = ktutorial.newStep("keyboardCut") -keyboardCutStep.setText(t.i18nc("@info", "The next thing to do is cut the selected text. Cutting it will remove it from the text area, but in some Steps we will make it appear again. To cut the selected text, click in <interface>Edit->Cut</interface> or in the button of the toolbar")) +keyboardCutStep.setText(t.i18nc("@info", "The next thing to do is cut the selected text. Cutting it will remove it from the text area, but in some Steps we will make it appear again. To cut the selected text, click in <interface>Edit|Cut</interface> or in the button of the toolbar")) cutAction = ktutorial.findObject("edit_cut") waitForCutTriggered = ktutorial.newWaitFor("WaitForSignal") @@ -137,7 +137,7 @@ #Step keyboardPaste keyboardPasteStep = ktutorial.newStep("keyboardPaste") -keyboardPasteStep.setText(t.i18nc("@info", "Finally, paste the text you have cut previously. To do this, click in <interface>Edit->Paste</interface> or in the button in the toolbar")) +keyboardPasteStep.setText(t.i18nc("@info", "Finally, paste the text you have cut previously. To do this, click in <interface>Edit|Paste</interface> or in the button in the toolbar")) pasteAction = ktutorial.findObject("edit_paste") waitForPasteTriggered = ktutorial.newWaitFor("WaitForSignal") Modified: trunk/ktutorial/ktutorial-test-app/po/es.po =================================================================== --- trunk/ktutorial/ktutorial-test-app/po/es.po 2010-10-18 17:41:37 UTC (rev 277) +++ trunk/ktutorial/ktutorial-test-app/po/es.po 2010-10-27 09:53:15 UTC (rev 278) @@ -8,8 +8,8 @@ "Project-Id-Version: es\n" "Report-Msgid-Bugs-To: http://sourceforge.net/tracker/?" "group_id=301227&atid=1270278\n" -"POT-Creation-Date: 2010-02-06 17:57+0100\n" -"PO-Revision-Date: 2010-02-06 18:09+0100\n" +"POT-Creation-Date: 2010-10-26 04:11+0200\n" +"PO-Revision-Date: 2010-10-25 19:02+0200\n" "Last-Translator: Daniel Calviño Sánchez <dan...@gm...>\n" "Language-Team: Español\n" "MIME-Version: 1.0\n" @@ -53,27 +53,41 @@ msgid "KTutorial integration and tutorials" msgstr "Integración con KTutorial y tutoriales" +#: po/rc.cpp:3 rc.cpp:3 +msgid "Main Toolbar" +msgstr "Barra de herramientas principal" + +#: po/rc.cpp:4 rc.cpp:4 +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Daniel Calviño Sánchez" + +#: po/rc.cpp:5 rc.cpp:5 +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "dan...@gm..." + #: TestApp.cpp:53 msgctxt "@action" msgid "Clear" msgstr "Limpiar" -#: TutorialClearText.cpp:32 TutorialClearText.js:21 TutorialClearText.py:24 +#: TutorialClearText.cpp:33 TutorialClearText.js:21 TutorialClearText.py:24 msgid "Clear the text area" msgstr "Limpiar el área de texto" -#: TutorialClearText.cpp:33 TutorialClearText.js:22 TutorialClearText.py:25 +#: TutorialClearText.cpp:34 TutorialClearText.js:22 TutorialClearText.py:25 msgid "This tutorial shows how to clean the text area with ease" msgstr "Este tutorial muestra cómo limpiar el área de texto con facilidad" -#: TutorialClearText.cpp:37 TutorialClearText.cpp:67 TutorialClearText.js:26 +#: TutorialClearText.cpp:38 TutorialClearText.cpp:68 TutorialClearText.js:26 #: TutorialClearText.js:35 TutorialClearText.py:29 TutorialClearText.py:38 -#: TutorialMoveText.cpp:57 TutorialMoveText.cpp:163 TutorialMoveText.py:84 +#: TutorialMoveText.cpp:76 TutorialMoveText.cpp:168 TutorialMoveText.py:84 #: TutorialMoveText.py:91 msgid "Hello world" msgstr "Hola mundo" -#: TutorialClearText.cpp:37 TutorialClearText.js:26 TutorialClearText.py:29 +#: TutorialClearText.cpp:38 TutorialClearText.js:26 TutorialClearText.py:29 msgctxt "@info" msgid "" "In this tutorial you will learn how to clear text in the test application." @@ -82,31 +96,31 @@ "En este tutorial aprenderás cómo limpiar el texto en la aplicación de prueba." "<nl/>Primero, escribe \"%1\" (sin las comillas) en el área de texto" -#: TutorialClearText.cpp:47 TutorialClearText.js:44 TutorialClearText.py:45 +#: TutorialClearText.cpp:48 TutorialClearText.js:44 TutorialClearText.py:45 msgctxt "@info" msgid "" "Now, you must trigger the clear action.<nl/>To do this, you can click in " -"<interface>File->Clear</interface>, or in the toolbar button called " +"<interface>File|Clear</interface>, or in the toolbar button called " "<interface>Clear</interface>" msgstr "" "Ahora, debes activar la acción de Limpiar.<nl/>Para hacer esto, puedes hacer " -"click en <interface>Archivo->Limpiar</interface>, o en el botón de la barra " +"click en <interface>Archivo|Limpiar</interface>, o en el botón de la barra " "de herramientas llamado <interface>Limpiar</interface>." -#: TutorialClearText.cpp:57 TutorialClearText.js:60 TutorialClearText.py:60 +#: TutorialClearText.cpp:58 TutorialClearText.js:56 TutorialClearText.py:57 msgctxt "@info" msgid "And that's all.<nl/>Now you can close the tutorial." msgstr "Y eso es todo.<nl/>Ahora puedes cerrar el tutorial." -#: TutorialMoveText.cpp:38 TutorialMoveText.py:24 +#: TutorialMoveText.cpp:58 TutorialMoveText.py:24 msgid "Move text in the text area" msgstr "Mover texto en el área de texto" -#: TutorialMoveText.cpp:39 TutorialMoveText.py:25 +#: TutorialMoveText.cpp:59 TutorialMoveText.py:25 msgid "This tutorial shows how to move text in the text area" msgstr "Este tutorial muestra cómo mover texto en el área de texto" -#: TutorialMoveText.cpp:48 TutorialMoveText.py:66 +#: TutorialMoveText.cpp:67 TutorialMoveText.py:66 msgctxt "@info" msgid "" "In this tutorial you will learn how to move text in the test application.<nl/" @@ -115,63 +129,63 @@ "En este tutorial aprenderás cómo mover texto en la aplicación de prueba.<nl/" ">El texto puede moverse utilizando el ratón o el teclado. ¿Qué prefieres?" -#: TutorialMoveText.cpp:50 TutorialMoveText.py:68 +#: TutorialMoveText.cpp:69 TutorialMoveText.py:68 msgid "Mouse" msgstr "Ratón" -#: TutorialMoveText.cpp:51 TutorialMoveText.py:74 +#: TutorialMoveText.cpp:70 TutorialMoveText.py:74 msgid "Keyboard" msgstr "Teclado" -#: TutorialMoveText.cpp:57 TutorialMoveText.py:84 +#: TutorialMoveText.cpp:76 TutorialMoveText.py:84 msgctxt "@info" msgid "First of all, clean the text area and write \"%1\" (without quotes)" msgstr "" "Lo primero de todo, limpia el área de texto y escribe \"%1\" (sin comillas)" -#: TutorialMoveText.cpp:66 TutorialMoveText.cpp:170 TutorialMoveText.py:98 +#: TutorialMoveText.cpp:85 TutorialMoveText.cpp:175 TutorialMoveText.py:98 #: TutorialMoveText.py:105 msgid "world" msgstr "mundo" -#: TutorialMoveText.cpp:66 TutorialMoveText.py:98 +#: TutorialMoveText.cpp:85 TutorialMoveText.py:98 msgctxt "@info" msgid "Now, select the text \"%1\" in the text area" msgstr "Ahora, selecciona el texto \"%1\" en el área de texto" -#: TutorialMoveText.cpp:75 TutorialMoveText.py:115 +#: TutorialMoveText.cpp:94 TutorialMoveText.py:115 msgctxt "@info" msgid "" "The next thing to do is cut the selected text. Cutting it will remove it " "from the text area, but in some Steps we will make it appear again. To cut " -"the selected text, click in <interface>Edit->Cut</interface> or in the " -"button of the toolbar" +"the selected text, click in <interface>Edit|Cut</interface> or in the button " +"of the toolbar" msgstr "" "Lo siguiente es cortar el texto seleccionado. Al cortarlo se eliminará del " "área de texto, pero dentro de unos pasos lo haremos aparecer de nuevo. Para " -"cortar el texto seleccionado, haz click en <interface>Editar->Cortar</" +"cortar el texto seleccionado, haz click en <interface>Editar|Cortar</" "interface> o en el botón de la barra de tareas" -#: TutorialMoveText.cpp:85 TutorialMoveText.py:129 +#: TutorialMoveText.cpp:104 TutorialMoveText.py:126 msgid "Hello" msgstr "Hola" -#: TutorialMoveText.cpp:85 TutorialMoveText.py:129 +#: TutorialMoveText.cpp:104 TutorialMoveText.py:126 msgctxt "@info" msgid "Move the cursor to the beginning of the document, before \"%1\" text" msgstr "Mueve el cursor al principio del documento, antes del texto \"%1\"" -#: TutorialMoveText.cpp:94 TutorialMoveText.py:143 +#: TutorialMoveText.cpp:113 TutorialMoveText.py:140 msgctxt "@info" msgid "" "Finally, paste the text you have cut previously. To do this, click in " -"<interface>Edit->Paste</interface> or in the button in the toolbar" +"<interface>Edit|Paste</interface> or in the button in the toolbar" msgstr "" "Finalmente, pega el texto que cortaste previamente. Para hacer esto, haz " -"click en <interface>Editar->Pegar</interface> o en el botón de la barra de " +"click en <interface>Editar|Pegar</interface> o en el botón de la barra de " "herramientas" -#: TutorialMoveText.cpp:104 +#: TutorialMoveText.cpp:123 msgctxt "@info" msgid "" "Press with the left button of the mouse on the selected text. You must press " @@ -182,7 +196,7 @@ "pulsar sobre él, o la selección cambiará, y deberás seleccionarlo de nuevo. " "No sueltes el botón aún." -#: TutorialMoveText.cpp:113 TutorialMoveText.py:175 +#: TutorialMoveText.cpp:132 TutorialMoveText.py:169 msgctxt "@info" msgid "" "Without releasing the mouse button, move the cursor to the desired position, " @@ -193,7 +207,7 @@ "ejemplo el principio del texto.<nl/>Una vez que el cursor esté ahí, puedes " "soltar el botón del ratón, y el texto será movido." -#: TutorialMoveText.cpp:122 TutorialMoveText.py:191 +#: TutorialMoveText.cpp:141 TutorialMoveText.py:185 msgctxt "@info" msgid "" "As explained, there are two ways to move text in a text area: using the " @@ -202,20 +216,20 @@ "Como se dijo, existen dos formas de mover el texto en un área de texto: " "usando el ratón y usando el teclado. ¿Quieres ver la otra forma?" -#: TutorialMoveText.cpp:124 TutorialMoveText.py:193 +#: TutorialMoveText.cpp:143 TutorialMoveText.py:187 msgid "Yes, please" msgstr "Sí, por favor" -#: TutorialMoveText.cpp:125 TutorialMoveText.py:203 +#: TutorialMoveText.cpp:144 TutorialMoveText.py:197 msgid "No, thanks" msgstr "No, gracias" -#: TutorialMoveText.cpp:131 TutorialMoveText.py:212 +#: TutorialMoveText.cpp:150 TutorialMoveText.py:203 msgctxt "@info" msgid "That's all.<nl/>Now you can close the tutorial." msgstr "Y eso es todo.<nl/>Ahora puedes cerrar el tutorial." -#: TutorialMoveText.py:160 +#: TutorialMoveText.py:157 msgctxt "@info" msgid "" "<para><emphasis>Warning:</emphasis> due to <link url=\"https://bugs.kde.org/" @@ -239,17 +253,3 @@ "con el botón izquierdo del ratón en el texto seleccionado. Debes pulsar " "sobre él, o la selección cambiará, y deberás seleccionarlo de nuevo. No " "sueltes el botón aún.</para>" - -#: rc.cpp:3 -msgid "Main Toolbar" -msgstr "Barra de herramientas principal" - -#: rc.cpp:4 -msgctxt "NAME OF TRANSLATORS" -msgid "Your names" -msgstr "Daniel Calviño Sánchez" - -#: rc.cpp:5 -msgctxt "EMAIL OF TRANSLATORS" -msgid "Your emails" -msgstr "dan...@gm..." Modified: trunk/ktutorial/ktutorial-test-app/po/ktutorial-test-app.pot =================================================================== --- trunk/ktutorial/ktutorial-test-app/po/ktutorial-test-app.pot 2010-10-18 17:41:37 UTC (rev 277) +++ trunk/ktutorial/ktutorial-test-app/po/ktutorial-test-app.pot 2010-10-27 09:53:15 UTC (rev 278) @@ -9,7 +9,7 @@ "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: http://sourceforge.net/tracker/?" "group_id=301227&atid=1270278\n" -"POT-Creation-Date: 2010-02-06 17:57+0100\n" +"POT-Creation-Date: 2010-10-26 04:11+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language-Team: LANGUAGE <LL...@li...>\n" @@ -49,110 +49,124 @@ msgid "KTutorial integration and tutorials" msgstr "" +#: po/rc.cpp:3 rc.cpp:3 +msgid "Main Toolbar" +msgstr "" + +#: po/rc.cpp:4 rc.cpp:4 +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "" + +#: po/rc.cpp:5 rc.cpp:5 +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "" + #: TestApp.cpp:53 msgctxt "@action" msgid "Clear" msgstr "" -#: TutorialClearText.cpp:32 TutorialClearText.js:21 TutorialClearText.py:24 +#: TutorialClearText.cpp:33 TutorialClearText.js:21 TutorialClearText.py:24 msgid "Clear the text area" msgstr "" -#: TutorialClearText.cpp:33 TutorialClearText.js:22 TutorialClearText.py:25 +#: TutorialClearText.cpp:34 TutorialClearText.js:22 TutorialClearText.py:25 msgid "This tutorial shows how to clean the text area with ease" msgstr "" -#: TutorialClearText.cpp:37 TutorialClearText.cpp:67 TutorialClearText.js:26 +#: TutorialClearText.cpp:38 TutorialClearText.cpp:68 TutorialClearText.js:26 #: TutorialClearText.js:35 TutorialClearText.py:29 TutorialClearText.py:38 -#: TutorialMoveText.cpp:57 TutorialMoveText.cpp:163 TutorialMoveText.py:84 +#: TutorialMoveText.cpp:76 TutorialMoveText.cpp:168 TutorialMoveText.py:84 #: TutorialMoveText.py:91 msgid "Hello world" msgstr "" -#: TutorialClearText.cpp:37 TutorialClearText.js:26 TutorialClearText.py:29 +#: TutorialClearText.cpp:38 TutorialClearText.js:26 TutorialClearText.py:29 msgctxt "@info" msgid "" "In this tutorial you will learn how to clear text in the test application." "<nl/>First, write \"%1\" (without quotes) in the text area" msgstr "" -#: TutorialClearText.cpp:47 TutorialClearText.js:44 TutorialClearText.py:45 +#: TutorialClearText.cpp:48 TutorialClearText.js:44 TutorialClearText.py:45 msgctxt "@info" msgid "" "Now, you must trigger the clear action.<nl/>To do this, you can click in " -"<interface>File->Clear</interface>, or in the toolbar button called " +"<interface>File|Clear</interface>, or in the toolbar button called " "<interface>Clear</interface>" msgstr "" -#: TutorialClearText.cpp:57 TutorialClearText.js:60 TutorialClearText.py:60 +#: TutorialClearText.cpp:58 TutorialClearText.js:56 TutorialClearText.py:57 msgctxt "@info" msgid "And that's all.<nl/>Now you can close the tutorial." msgstr "" -#: TutorialMoveText.cpp:38 TutorialMoveText.py:24 +#: TutorialMoveText.cpp:58 TutorialMoveText.py:24 msgid "Move text in the text area" msgstr "" -#: TutorialMoveText.cpp:39 TutorialMoveText.py:25 +#: TutorialMoveText.cpp:59 TutorialMoveText.py:25 msgid "This tutorial shows how to move text in the text area" msgstr "" -#: TutorialMoveText.cpp:48 TutorialMoveText.py:66 +#: TutorialMoveText.cpp:67 TutorialMoveText.py:66 msgctxt "@info" msgid "" "In this tutorial you will learn how to move text in the test application.<nl/" ">Text can be moved using the mouse or the keyboard. What do you prefer?" msgstr "" -#: TutorialMoveText.cpp:50 TutorialMoveText.py:68 +#: TutorialMoveText.cpp:69 TutorialMoveText.py:68 msgid "Mouse" msgstr "" -#: TutorialMoveText.cpp:51 TutorialMoveText.py:74 +#: TutorialMoveText.cpp:70 TutorialMoveText.py:74 msgid "Keyboard" msgstr "" -#: TutorialMoveText.cpp:57 TutorialMoveText.py:84 +#: TutorialMoveText.cpp:76 TutorialMoveText.py:84 msgctxt "@info" msgid "First of all, clean the text area and write \"%1\" (without quotes)" msgstr "" -#: TutorialMoveText.cpp:66 TutorialMoveText.cpp:170 TutorialMoveText.py:98 +#: TutorialMoveText.cpp:85 TutorialMoveText.cpp:175 TutorialMoveText.py:98 #: TutorialMoveText.py:105 msgid "world" msgstr "" -#: TutorialMoveText.cpp:66 TutorialMoveText.py:98 +#: TutorialMoveText.cpp:85 TutorialMoveText.py:98 msgctxt "@info" msgid "Now, select the text \"%1\" in the text area" msgstr "" -#: TutorialMoveText.cpp:75 TutorialMoveText.py:115 +#: TutorialMoveText.cpp:94 TutorialMoveText.py:115 msgctxt "@info" msgid "" "The next thing to do is cut the selected text. Cutting it will remove it " "from the text area, but in some Steps we will make it appear again. To cut " -"the selected text, click in <interface>Edit->Cut</interface> or in the " -"button of the toolbar" +"the selected text, click in <interface>Edit|Cut</interface> or in the button " +"of the toolbar" msgstr "" -#: TutorialMoveText.cpp:85 TutorialMoveText.py:129 +#: TutorialMoveText.cpp:104 TutorialMoveText.py:126 msgid "Hello" msgstr "" -#: TutorialMoveText.cpp:85 TutorialMoveText.py:129 +#: TutorialMoveText.cpp:104 TutorialMoveText.py:126 msgctxt "@info" msgid "Move the cursor to the beginning of the document, before \"%1\" text" msgstr "" -#: TutorialMoveText.cpp:94 TutorialMoveText.py:143 +#: TutorialMoveText.cpp:113 TutorialMoveText.py:140 msgctxt "@info" msgid "" "Finally, paste the text you have cut previously. To do this, click in " -"<interface>Edit->Paste</interface> or in the button in the toolbar" +"<interface>Edit|Paste</interface> or in the button in the toolbar" msgstr "" -#: TutorialMoveText.cpp:104 +#: TutorialMoveText.cpp:123 msgctxt "@info" msgid "" "Press with the left button of the mouse on the selected text. You must press " @@ -160,7 +174,7 @@ "Don't release the button yet." msgstr "" -#: TutorialMoveText.cpp:113 TutorialMoveText.py:175 +#: TutorialMoveText.cpp:132 TutorialMoveText.py:169 msgctxt "@info" msgid "" "Without releasing the mouse button, move the cursor to the desired position, " @@ -168,27 +182,27 @@ "release the mouse button, and the text will be moved." msgstr "" -#: TutorialMoveText.cpp:122 TutorialMoveText.py:191 +#: TutorialMoveText.cpp:141 TutorialMoveText.py:185 msgctxt "@info" msgid "" "As explained, there are two ways to move text in a text area: using the " "mouse and using the keyboard. Do you want to see the other way?" msgstr "" -#: TutorialMoveText.cpp:124 TutorialMoveText.py:193 +#: TutorialMoveText.cpp:143 TutorialMoveText.py:187 msgid "Yes, please" msgstr "" -#: TutorialMoveText.cpp:125 TutorialMoveText.py:203 +#: TutorialMoveText.cpp:144 TutorialMoveText.py:197 msgid "No, thanks" msgstr "" -#: TutorialMoveText.cpp:131 TutorialMoveText.py:212 +#: TutorialMoveText.cpp:150 TutorialMoveText.py:203 msgctxt "@info" msgid "That's all.<nl/>Now you can close the tutorial." msgstr "" -#: TutorialMoveText.py:160 +#: TutorialMoveText.py:157 msgctxt "@info" msgid "" "<para><emphasis>Warning:</emphasis> due to <link url=\"https://bugs.kde.org/" @@ -202,17 +216,3 @@ "selection will change, and you will have to select it again. Don't release " "the button yet.</para>" msgstr "" - -#: rc.cpp:3 -msgid "Main Toolbar" -msgstr "" - -#: rc.cpp:4 -msgctxt "NAME OF TRANSLATORS" -msgid "Your names" -msgstr "" - -#: rc.cpp:5 -msgctxt "EMAIL OF TRANSLATORS" -msgid "Your emails" -msgstr "" This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dan...@us...> - 2010-10-18 17:41:44
|
Revision: 277 http://ktutorial.svn.sourceforge.net/ktutorial/?rev=277&view=rev Author: danxuliu Date: 2010-10-18 17:41:37 +0000 (Mon, 18 Oct 2010) Log Message: ----------- Fix "unused variable" compilation warning. Modified Paths: -------------- trunk/ktutorial/ktutorial-library/tests/editorsupport/EditorSupportAdaptorTest.cpp Modified: trunk/ktutorial/ktutorial-library/tests/editorsupport/EditorSupportAdaptorTest.cpp =================================================================== --- trunk/ktutorial/ktutorial-library/tests/editorsupport/EditorSupportAdaptorTest.cpp 2010-10-18 15:39:12 UTC (rev 276) +++ trunk/ktutorial/ktutorial-library/tests/editorsupport/EditorSupportAdaptorTest.cpp 2010-10-18 17:41:37 UTC (rev 277) @@ -150,7 +150,7 @@ EditorSupportAdaptor* adaptor = new EditorSupportAdaptor(&editorSupport); //Tutorial* must be registered in order to be used with QSignalSpy - int tutorialStarType = qRegisterMetaType<Tutorial*>("Tutorial*"); + qRegisterMetaType<Tutorial*>("Tutorial*"); QSignalSpy startedSpy(&editorSupport, SIGNAL(started(Tutorial*))); adaptor->testScriptedTutorial(temporaryFile.fileName()); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dan...@us...> - 2010-10-18 15:39:18
|
Revision: 276 http://ktutorial.svn.sourceforge.net/ktutorial/?rev=276&view=rev Author: danxuliu Date: 2010-10-18 15:39:12 +0000 (Mon, 18 Oct 2010) Log Message: ----------- Update XML Schema with WaitForWindow elements (forgotten in commit 258). Modified Paths: -------------- trunk/ktutorial/ktutorial-editor/src/serialization/Tutorial.xsd Modified: trunk/ktutorial/ktutorial-editor/src/serialization/Tutorial.xsd =================================================================== --- trunk/ktutorial/ktutorial-editor/src/serialization/Tutorial.xsd 2010-10-17 22:53:21 UTC (rev 275) +++ trunk/ktutorial/ktutorial-editor/src/serialization/Tutorial.xsd 2010-10-18 15:39:12 UTC (rev 276) @@ -45,6 +45,7 @@ <xsd:element name="waitForEvent" type="WaitForEventType"/> <xsd:element name="waitForNot" type="WaitForNotType"/> <xsd:element name="waitForSignal" type="WaitForSignalType"/> + <xsd:element name="waitForWindow" type="WaitForWindowType"/> </xsd:choice> </xsd:group> @@ -96,4 +97,8 @@ <xsd:attribute name="signalName" type="xsd:string" use="optional"/> </xsd:complexType> + <xsd:complexType name="WaitForWindowType"> + <xsd:attribute name="windowObjectName" type="xsd:string" use="optional"/> + </xsd:complexType> + </xsd:schema> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dan...@us...> - 2010-10-17 22:53:27
|
Revision: 275 http://ktutorial.svn.sourceforge.net/ktutorial/?rev=275&view=rev Author: danxuliu Date: 2010-10-17 22:53:21 +0000 (Sun, 17 Oct 2010) Log Message: ----------- Force showing the RemoteObjectChooser before showing the information message box to ensure that the message box gets the proper parent (needed in Qt 4.7, which seems to give a 0 winId to a window if it wasn't shown yet). Modified Paths: -------------- trunk/ktutorial/ktutorial-editor/src/view/RemoteObjectChooser.cpp Modified: trunk/ktutorial/ktutorial-editor/src/view/RemoteObjectChooser.cpp =================================================================== --- trunk/ktutorial/ktutorial-editor/src/view/RemoteObjectChooser.cpp 2010-10-17 22:44:08 UTC (rev 274) +++ trunk/ktutorial/ktutorial-editor/src/view/RemoteObjectChooser.cpp 2010-10-17 22:53:21 UTC (rev 275) @@ -132,6 +132,13 @@ //private slots: void RemoteObjectChooser::handleTargetApplicationStarted() { + if (isHidden()) { + //In Qt 4.7 a window seems to need to be shown to get a winId. If the + //parent of a KMessageBox::information does not have a winId, the + //message box gets no parent. + show(); + } + QString text = i18nc("@label", "<para>The " "<application>KTutorial editor</application> windows will be hidden and only " "the list with the objects in the target application will be shown. It is made " This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dan...@us...> - 2010-10-17 22:44:14
|
Revision: 274 http://ktutorial.svn.sourceforge.net/ktutorial/?rev=274&view=rev Author: danxuliu Date: 2010-10-17 22:44:08 +0000 (Sun, 17 Oct 2010) Log Message: ----------- Fix QDbusConnection::registerObject assert when Qt is compiled in debug mode. Modified Paths: -------------- trunk/ktutorial/ktutorial-library/tests/WaitForWindowTest.cpp Modified: trunk/ktutorial/ktutorial-library/tests/WaitForWindowTest.cpp =================================================================== --- trunk/ktutorial/ktutorial-library/tests/WaitForWindowTest.cpp 2010-10-03 19:17:27 UTC (rev 273) +++ trunk/ktutorial/ktutorial-library/tests/WaitForWindowTest.cpp 2010-10-17 22:44:08 UTC (rev 274) @@ -57,6 +57,12 @@ }; void WaitForWindowTest::initTestCase() { + //The name of the application must be set to avoid failing an assert in + //QDBusConnection::registerObject (dbus/qdbusconnection.cpp:697) that checks + //for a proper object path. The path given is based on the application name, + //and the application name has to be set to be a valid path. + qApp->setApplicationName("WaitForWindowTest"); + mMainWindow = new KXmlGuiWindow(); KTutorial::self()->setup(mMainWindow); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dan...@us...> - 2010-10-03 19:17:33
|
Revision: 273 http://ktutorial.svn.sourceforge.net/ktutorial/?rev=273&view=rev Author: danxuliu Date: 2010-10-03 19:17:27 +0000 (Sun, 03 Oct 2010) Log Message: ----------- Fix Krazy2 i18ncheckarg issues. Modified Paths: -------------- trunk/ktutorial/ktutorial-editor/src/serialization/Serialization.cpp trunk/ktutorial/ktutorial-library/src/tutorials/UsingKTutorial.cpp trunk/ktutorial/ktutorial-library/src/view/TutorialManagerDialog.cpp Modified: trunk/ktutorial/ktutorial-editor/src/serialization/Serialization.cpp =================================================================== --- trunk/ktutorial/ktutorial-editor/src/serialization/Serialization.cpp 2010-10-03 19:14:30 UTC (rev 272) +++ trunk/ktutorial/ktutorial-editor/src/serialization/Serialization.cpp 2010-10-03 19:17:27 UTC (rev 273) @@ -38,8 +38,8 @@ Q_ASSERT(url.isValid()); if (url.fileName(KUrl::ObeyTrailingSlash).isEmpty()) { - throw IOException(i18n("A file was expected, but '%1' is a folder", - url.prettyUrl())); + throw IOException(i18nc("@info/plain", "A file was expected, but '%1' " + "is a folder", url.prettyUrl())); } QString temporaryFileName; Modified: trunk/ktutorial/ktutorial-library/src/tutorials/UsingKTutorial.cpp =================================================================== --- trunk/ktutorial/ktutorial-library/src/tutorials/UsingKTutorial.cpp 2010-10-03 19:14:30 UTC (rev 272) +++ trunk/ktutorial/ktutorial-library/src/tutorials/UsingKTutorial.cpp 2010-10-03 19:17:27 UTC (rev 273) @@ -64,7 +64,7 @@ textEdit->setAttribute(Qt::WA_DeleteOnClose); textEdit->setWindowFlags(Qt::Window); textEdit->setObjectName("usingKTutorialTextEdit"); - textEdit->setText(i18nc("Plain text in a QTextEdit", + textEdit->setText(i18nc("@info/plain Plain text in a QTextEdit", "Look at me! I am the text area!")); textEdit->show(); @@ -136,9 +136,10 @@ UsingKTutorial::UsingKTutorial(): Tutorial(0) { mTutorialInformation = new TutorialInformation("usingKTutorial"); - mTutorialInformation->setName(i18n("Using the tutorials")); - mTutorialInformation->setDescription(i18n("This tutorial shows how the " - "tutorial system works")); + mTutorialInformation->setName(i18nc("@info/plain", "Using the tutorials")); + mTutorialInformation->setDescription(i18nc("@info/plain", "This tutorial " + "shows how the tutorial system " + "works")); //Step start Step* startStep = new Step("start"); @@ -245,8 +246,8 @@ highlightTextEditStep->setText(i18nc("@info", "<para>Sometimes, a tutorial may provide a link to a <emphasis>widget" "</emphasis> (an element of the graphical user interface, like a button). For " -"example, <a href=\"widget:usingKTutorialTextEdit\">this is a link to the text " -"area</a>.</para>" +"example, <link url=\"widget:usingKTutorialTextEdit\">this is a link to the " +"text area</link>.</para>" "<para>When you click on a link to a widget, the widget is highlighted to help " "you to spot it. If you click again on it, the highlighting will be stopped. " "In this example it is pretty clear what the text area refers to, but it can " Modified: trunk/ktutorial/ktutorial-library/src/view/TutorialManagerDialog.cpp =================================================================== --- trunk/ktutorial/ktutorial-library/src/view/TutorialManagerDialog.cpp 2010-10-03 19:14:30 UTC (rev 272) +++ trunk/ktutorial/ktutorial-library/src/view/TutorialManagerDialog.cpp 2010-10-03 19:17:27 UTC (rev 273) @@ -44,7 +44,7 @@ ui->tutorialsList->setModel(new TutorialListModel(tutorialManager, this)); setButtonIcon(User1, KIcon("dialog-ok")); - setButtonText(User1, i18nc("@action:button", "Start")); + setButtonText(User1, i18nc("@action:button Used to start a tutorial", "Start")); setButtonToolTip(User1, i18nc("@info:tooltip", "Start the selected tutorial")); setButtonWhatsThis(User1, i18nc("@info:whatsthis", "Start the selected tutorial")); setDefaultButton(User1); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dan...@us...> - 2010-10-03 19:14:36
|
Revision: 272 http://ktutorial.svn.sourceforge.net/ktutorial/?rev=272&view=rev Author: danxuliu Date: 2010-10-03 19:14:30 +0000 (Sun, 03 Oct 2010) Log Message: ----------- Fix Krazy2 spelling issues. Modified Paths: -------------- trunk/ktutorial/ktutorial-editor/src/serialization/IOException.h trunk/ktutorial/ktutorial-editor/src/serialization/Serialization.h trunk/ktutorial/ktutorial-editor/src/view/RemoteObjectNameWidget.cpp trunk/ktutorial/ktutorial-editor/src/view/RemoteObjectNameWidget.ui trunk/ktutorial/ktutorial-library/src/view/TutorialListModel.h Modified: trunk/ktutorial/ktutorial-editor/src/serialization/IOException.h =================================================================== --- trunk/ktutorial/ktutorial-editor/src/serialization/IOException.h 2010-10-03 16:33:21 UTC (rev 271) +++ trunk/ktutorial/ktutorial-editor/src/serialization/IOException.h 2010-10-03 19:14:30 UTC (rev 272) @@ -22,7 +22,7 @@ #include "../util/Exception.h" /** - * Thrown when an input/ouput operation fails (for example, writing to an + * Thrown when an input/output operation fails (for example, writing to an * unwritable file, or reading from a file that does not exist). */ class IOException: public Exception { Modified: trunk/ktutorial/ktutorial-editor/src/serialization/Serialization.h =================================================================== --- trunk/ktutorial/ktutorial-editor/src/serialization/Serialization.h 2010-10-03 16:33:21 UTC (rev 271) +++ trunk/ktutorial/ktutorial-editor/src/serialization/Serialization.h 2010-10-03 19:14:30 UTC (rev 272) @@ -44,7 +44,7 @@ * file in a remote computer). It will be also used to automatically cache * and discard that information. * - * @param window The window associated with the input/ouput jobs, if any. + * @param window The window associated with the input/output jobs, if any. */ explicit Serialization(QWidget* window = 0); Modified: trunk/ktutorial/ktutorial-editor/src/view/RemoteObjectNameWidget.cpp =================================================================== --- trunk/ktutorial/ktutorial-editor/src/view/RemoteObjectNameWidget.cpp 2010-10-03 16:33:21 UTC (rev 271) +++ trunk/ktutorial/ktutorial-editor/src/view/RemoteObjectNameWidget.cpp 2010-10-03 19:14:30 UTC (rev 272) @@ -94,7 +94,7 @@ throw (DBusException) { Q_ASSERT(remoteObject); - //The remote object is no longer accesible, so name() can't be called + //The remote object is no longer accessible, so name() can't be called QString name = mRemoteObjectForName.key(remoteObject); KCompletion* completion = ui->objectNameLineEdit->completionObject(); Modified: trunk/ktutorial/ktutorial-editor/src/view/RemoteObjectNameWidget.ui =================================================================== --- trunk/ktutorial/ktutorial-editor/src/view/RemoteObjectNameWidget.ui 2010-10-03 16:33:21 UTC (rev 271) +++ trunk/ktutorial/ktutorial-editor/src/view/RemoteObjectNameWidget.ui 2010-10-03 19:14:30 UTC (rev 272) @@ -15,7 +15,7 @@ </property> <property name="whatsThis"> <string comment="@info:whatsthis"><para>Choose the name of the remote object.</para> -<para>If the name is known, it can be directly written. Else, it can be choosen from all the objects currently available in the target application.</para></string> +<para>If the name is known, it can be directly written. Else, it can be chosen from all the objects currently available in the target application.</para></string> </property> <layout class="QHBoxLayout" name="RemoteObjectNameWidgetHorizontalLayout"> <property name="margin"> Modified: trunk/ktutorial/ktutorial-library/src/view/TutorialListModel.h =================================================================== --- trunk/ktutorial/ktutorial-library/src/view/TutorialListModel.h 2010-10-03 16:33:21 UTC (rev 271) +++ trunk/ktutorial/ktutorial-library/src/view/TutorialListModel.h 2010-10-03 19:14:30 UTC (rev 272) @@ -28,7 +28,7 @@ /** * A ListModel that fetchs its data from a TutorialManager. - * This is a very basic read-only model. It just shows the tutorial informations + * This is a very basic read-only model. It just shows the TutorialInformations * registered in a TutorialManager as a list where each element is the name of * a TutorialInformation. * This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dan...@us...> - 2010-10-03 16:33:27
|
Revision: 271 http://ktutorial.svn.sourceforge.net/ktutorial/?rev=271&view=rev Author: danxuliu Date: 2010-10-03 16:33:21 +0000 (Sun, 03 Oct 2010) Log Message: ----------- Fix Krazy2 doublequote_chars issue. Modified Paths: -------------- trunk/ktutorial/ktutorial-editor/src/serialization/JavascriptExporter.cpp Modified: trunk/ktutorial/ktutorial-editor/src/serialization/JavascriptExporter.cpp =================================================================== --- trunk/ktutorial/ktutorial-editor/src/serialization/JavascriptExporter.cpp 2010-10-03 16:27:00 UTC (rev 270) +++ trunk/ktutorial/ktutorial-editor/src/serialization/JavascriptExporter.cpp 2010-10-03 16:33:21 UTC (rev 271) @@ -474,7 +474,7 @@ return ""; } - text.replace(QRegExp("[^\\w ]"), ""); + text.remove(QRegExp("[^\\w ]")); QStringList words = text.split(' ', QString::SkipEmptyParts); QString upperCamelCase; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dan...@us...> - 2010-10-03 16:27:07
|
Revision: 270 http://ktutorial.svn.sourceforge.net/ktutorial/?rev=270&view=rev Author: danxuliu Date: 2010-10-03 16:27:00 +0000 (Sun, 03 Oct 2010) Log Message: ----------- Fix Krazy2 foreach issue. Modified Paths: -------------- trunk/ktutorial/ktutorial-editor/src/view/WaitForSignalWidget.cpp Modified: trunk/ktutorial/ktutorial-editor/src/view/WaitForSignalWidget.cpp =================================================================== --- trunk/ktutorial/ktutorial-editor/src/view/WaitForSignalWidget.cpp 2010-09-30 15:53:32 UTC (rev 269) +++ trunk/ktutorial/ktutorial-editor/src/view/WaitForSignalWidget.cpp 2010-10-03 16:27:00 UTC (rev 270) @@ -95,7 +95,7 @@ completion->setOrder(KCompletion::Sorted); while (remoteClass) { - foreach (QString signal, remoteClass->signalList()) { + foreach (const QString& signal, remoteClass->signalList()) { completion->addItem(signal); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dan...@us...> - 2010-09-30 15:53:38
|
Revision: 269 http://ktutorial.svn.sourceforge.net/ktutorial/?rev=269&view=rev Author: danxuliu Date: 2010-09-30 15:53:32 +0000 (Thu, 30 Sep 2010) Log Message: ----------- Set object name for Ok and Cancel buttons in "New wait for" dialog. Modified Paths: -------------- trunk/ktutorial/ktutorial-editor/src/view/WaitForWidget.cpp Modified: trunk/ktutorial/ktutorial-editor/src/view/WaitForWidget.cpp =================================================================== --- trunk/ktutorial/ktutorial-editor/src/view/WaitForWidget.cpp 2010-09-30 15:43:08 UTC (rev 268) +++ trunk/ktutorial/ktutorial-editor/src/view/WaitForWidget.cpp 2010-09-30 15:53:32 UTC (rev 269) @@ -180,6 +180,8 @@ dialog->setMainWidget(widget); dialog->setWindowTitle(widget->windowTitle()); dialog->setObjectName("addWaitForDialog"); + dialog->button(KDialog::Ok)->setObjectName("okButton"); + dialog->button(KDialog::Cancel)->setObjectName("cancelButton"); if (DialogRunner(dialog).exec() == QDialog::Accepted) { newWaitFor = widget->waitFor(); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dan...@us...> - 2010-09-30 15:43:14
|
Revision: 268 http://ktutorial.svn.sourceforge.net/ktutorial/?rev=268&view=rev Author: danxuliu Date: 2010-09-30 15:43:08 +0000 (Thu, 30 Sep 2010) Log Message: ----------- Fix crash when using a link to try to highlight an unknown widget. Modified Paths: -------------- trunk/ktutorial/ktutorial-library/src/view/StepTextWidget.cpp 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 2010-09-30 15:38:20 UTC (rev 267) +++ trunk/ktutorial/ktutorial-library/src/view/StepTextWidget.cpp 2010-09-30 15:43:08 UTC (rev 268) @@ -193,6 +193,7 @@ void StepTextWidget::highlightCurrentWidget() { if (!mCurrentHighlightedWidget) { kWarning() << "The widget to highlight was not found!"; + return; } WidgetHighlighterManager::self()->highlight(mCurrentHighlightedWidget); @@ -203,6 +204,7 @@ void StepTextWidget::stopHighlightingCurrentWidget() { if (!mCurrentHighlightedWidget) { kWarning() << "The widget to stop highlighting was not found!"; + return; } WidgetHighlighterManager::self()->stopHighlighting(mCurrentHighlightedWidget); Modified: trunk/ktutorial/ktutorial-library/tests/view/StepTextWidgetTest.cpp =================================================================== --- trunk/ktutorial/ktutorial-library/tests/view/StepTextWidgetTest.cpp 2010-09-30 15:38:20 UTC (rev 267) +++ trunk/ktutorial/ktutorial-library/tests/view/StepTextWidgetTest.cpp 2010-09-30 15:43:08 UTC (rev 268) @@ -54,6 +54,7 @@ void testHighlightWidgetUsingContextMenu(); void testStopHighlightingWidgetUsingContextMenu(); void testHighlightSeveralWidgets(); + void testHighlightUnknownWidget(); void testStopHighlightingWidgetWhenFocused(); @@ -277,6 +278,23 @@ QVERIFY(!widgetToHighlight3->findChild<WidgetHighlighter*>("")); } +void StepTextWidgetTest::testHighlightUnknownWidget() { + KXmlGuiWindow mainWindow; + KTutorial::self()->setup(&mainWindow); + + 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); + + //No explicit check is made, if it does not crash everything is fine ;) +} + void StepTextWidgetTest::testStopHighlightingWidgetWhenFocused() { KXmlGuiWindow mainWindow; KTutorial::self()->setup(&mainWindow); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dan...@us...> - 2010-09-30 15:38:30
|
Revision: 267 http://ktutorial.svn.sourceforge.net/ktutorial/?rev=267&view=rev Author: danxuliu Date: 2010-09-30 15:38:20 +0000 (Thu, 30 Sep 2010) Log Message: ----------- Fix waiting for a signal emitted by a null object. It didn't crash before, but now it doesn't even try to connect the signal and warns when this happens, like WaitForEvent does. Modified Paths: -------------- trunk/ktutorial/ktutorial-library/src/WaitForSignal.cpp trunk/ktutorial/ktutorial-library/tests/WaitForSignalTest.cpp Modified: trunk/ktutorial/ktutorial-library/src/WaitForSignal.cpp =================================================================== --- trunk/ktutorial/ktutorial-library/src/WaitForSignal.cpp 2010-09-30 15:35:32 UTC (rev 266) +++ trunk/ktutorial/ktutorial-library/src/WaitForSignal.cpp 2010-09-30 15:38:20 UTC (rev 267) @@ -1,5 +1,5 @@ /*************************************************************************** - * Copyright (C) 2008 by Daniel Calviño Sánchez * + * Copyright (C) 2008-2010 by Daniel Calviño Sánchez * * dan...@gm... * * * * This program is free software; you can redistribute it and/or modify * @@ -18,6 +18,8 @@ #include "WaitForSignal.h" +#include <KDebug> + //public: WaitForSignal::WaitForSignal(): WaitFor(), @@ -30,6 +32,11 @@ } void WaitForSignal::setSignal(QObject* sender, const QString& signal) { + if (!sender) { + kWarning() << "The object that emits the signal to wait for is null!"; + return; + } + QString signalName = signal; if (!signalName.startsWith('2')) { signalName = QString("2%1").arg(signal); Modified: trunk/ktutorial/ktutorial-library/tests/WaitForSignalTest.cpp =================================================================== --- trunk/ktutorial/ktutorial-library/tests/WaitForSignalTest.cpp 2010-09-30 15:35:32 UTC (rev 266) +++ trunk/ktutorial/ktutorial-library/tests/WaitForSignalTest.cpp 2010-09-30 15:38:20 UTC (rev 267) @@ -1,5 +1,5 @@ /*************************************************************************** - * Copyright (C) 2009 by Daniel Calviño Sánchez * + * Copyright (C) 2009-2010 by Daniel Calviño Sánchez * * dan...@gm... * * * * This program is free software; you can redistribute it and/or modify * @@ -51,8 +51,10 @@ void testConstructor(); void testConstructorWithoutSignalMacro(); + void testConstructorWithNullObject(); void testConstructorDefault(); void testConstructorDefaultWithoutSignalMacro(); + void testConstructorDefaultWithNullObject(); void testSetActive(); @@ -77,6 +79,13 @@ QCOMPARE(mDummySignalConnectionCount, 1); } +void WaitForSignalTest::testConstructorWithNullObject() { + WaitForSignal waitForSignal(0, SIGNAL(dummySignal())); + + QVERIFY(!waitForSignal.isActive()); + QVERIFY(!waitForSignal.conditionMet()); +} + void WaitForSignalTest::testConstructorDefault() { WaitForSignal waitForSignal; waitForSignal.setSignal(this, SIGNAL(dummySignal())); @@ -95,6 +104,14 @@ QCOMPARE(mDummySignalConnectionCount, 1); } +void WaitForSignalTest::testConstructorDefaultWithNullObject() { + WaitForSignal waitForSignal; + waitForSignal.setSignal(0, SIGNAL(dummySignal())); + + QVERIFY(!waitForSignal.isActive()); + QVERIFY(!waitForSignal.conditionMet()); +} + void WaitForSignalTest::testSetActive() { WaitForSignal waitForSignal(this, SIGNAL(dummySignal())); waitForSignal.mConditionMet = true; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dan...@us...> - 2010-09-30 15:35:41
|
Revision: 266 http://ktutorial.svn.sourceforge.net/ktutorial/?rev=266&view=rev Author: danxuliu Date: 2010-09-30 15:35:32 +0000 (Thu, 30 Sep 2010) Log Message: ----------- Fix crash when waiting for an event received by a null object. Modified Paths: -------------- trunk/ktutorial/ktutorial-library/src/WaitForEvent.cpp trunk/ktutorial/ktutorial-library/tests/WaitForEventTest.cpp Modified: trunk/ktutorial/ktutorial-library/src/WaitForEvent.cpp =================================================================== --- trunk/ktutorial/ktutorial-library/src/WaitForEvent.cpp 2010-09-28 21:32:13 UTC (rev 265) +++ trunk/ktutorial/ktutorial-library/src/WaitForEvent.cpp 2010-09-30 15:35:32 UTC (rev 266) @@ -35,10 +35,20 @@ mEventType(type), mConditionMet(false) { + if (!object) { + kWarning() << "The object that receives the event to wait for is null!"; + return; + } + object->installEventFilter(this); } void WaitForEvent::setEvent(QObject* object, const QString& typeName) { + if (!object) { + kWarning() << "The object that receives the event to wait for is null!"; + return; + } + int index = QEvent::staticMetaObject.indexOfEnumerator("Type"); QMetaEnum eventTypeEnumerator = QEvent::staticMetaObject.enumerator(index); Modified: trunk/ktutorial/ktutorial-library/tests/WaitForEventTest.cpp =================================================================== --- trunk/ktutorial/ktutorial-library/tests/WaitForEventTest.cpp 2010-09-28 21:32:13 UTC (rev 265) +++ trunk/ktutorial/ktutorial-library/tests/WaitForEventTest.cpp 2010-09-30 15:35:32 UTC (rev 266) @@ -29,7 +29,9 @@ private slots: void testConstructor(); + void testConstructorWithNullObject(); void testConstructorDefault(); + void testConstructorDefaultWithNullObject(); void testSetActive(); @@ -74,6 +76,13 @@ QVERIFY(!waitForEvent.conditionMet()); } +void WaitForEventTest::testConstructorWithNullObject() { + WaitForEvent waitForEvent(0, QEvent::ChildAdded); + + QVERIFY(!waitForEvent.isActive()); + QVERIFY(!waitForEvent.conditionMet()); +} + void WaitForEventTest::testConstructorDefault() { WaitForEvent waitForEvent; waitForEvent.setEvent(this, "ChildAdded"); @@ -82,6 +91,14 @@ QVERIFY(!waitForEvent.conditionMet()); } +void WaitForEventTest::testConstructorDefaultWithNullObject() { + WaitForEvent waitForEvent; + waitForEvent.setEvent(0, "ChildAdded"); + + QVERIFY(!waitForEvent.isActive()); + QVERIFY(!waitForEvent.conditionMet()); +} + void WaitForEventTest::testSetActive() { WaitForEvent waitForEvent(this, QEvent::ChildAdded); waitForEvent.mConditionMet = true; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dan...@us...> - 2010-09-28 21:32:19
|
Revision: 265 http://ktutorial.svn.sourceforge.net/ktutorial/?rev=265&view=rev Author: danxuliu Date: 2010-09-28 21:32:13 +0000 (Tue, 28 Sep 2010) Log Message: ----------- Fix not stopping the highlighting of a widget when the StepTextWidget is deleted. 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 2010-09-28 20:55:26 UTC (rev 264) +++ trunk/ktutorial/ktutorial-library/src/view/StepTextWidget.cpp 2010-09-28 21:32:13 UTC (rev 265) @@ -59,6 +59,12 @@ connect(this, SIGNAL(textChanged()), this, SLOT(updateText())); } +StepTextWidget::~StepTextWidget() { + if (mCurrentHighlightedWidget) { + stopHighlightingCurrentWidget(); + } +} + bool StepTextWidget::eventFilter(QObject* watched, QEvent* event) { if (watched != mCurrentHighlightedWidget) { return false; Modified: trunk/ktutorial/ktutorial-library/src/view/StepTextWidget.h =================================================================== --- trunk/ktutorial/ktutorial-library/src/view/StepTextWidget.h 2010-09-28 20:55:26 UTC (rev 264) +++ trunk/ktutorial/ktutorial-library/src/view/StepTextWidget.h 2010-09-28 21:32:13 UTC (rev 265) @@ -59,6 +59,12 @@ explicit StepTextWidget(QWidget* parent = 0); /** + * Destroys this StepTextWidget. + * If there is a widget being highlighted, the highlighting is stopped. + */ + virtual ~StepTextWidget(); + + /** * Watches the widget currently being highlighted and stops the highlighting * when it is focused. * Modified: trunk/ktutorial/ktutorial-library/tests/view/StepTextWidgetTest.cpp =================================================================== --- trunk/ktutorial/ktutorial-library/tests/view/StepTextWidgetTest.cpp 2010-09-28 20:55:26 UTC (rev 264) +++ trunk/ktutorial/ktutorial-library/tests/view/StepTextWidgetTest.cpp 2010-09-28 21:32:13 UTC (rev 265) @@ -58,6 +58,7 @@ void testStopHighlightingWidgetWhenFocused(); void testSetTextWhenWidgetIsBeingHighlighted(); + void testDeleteWhenWidgetIsBeingHighlighted(); private: @@ -321,6 +322,25 @@ QVERIFY(!widgetToHighlight->findChild<WidgetHighlighter*>("")); } +void StepTextWidgetTest::testDeleteWhenWidgetIsBeingHighlighted() { + KXmlGuiWindow mainWindow; + KTutorial::self()->setup(&mainWindow); + QWidget* widgetToHighlight = new QWidget(&mainWindow); + widgetToHighlight->setObjectName("widgetName"); + + StepTextWidget* widget = new StepTextWidget(); + 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); + + delete widget; + + QVERIFY(!widgetToHighlight->findChild<WidgetHighlighter*>("")); +} + /////////////////////////////////// Helpers //////////////////////////////////// void StepTextWidgetTest::selectFirstContextMenuOption() { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dan...@us...> - 2010-09-28 20:55:32
|
Revision: 264 http://ktutorial.svn.sourceforge.net/ktutorial/?rev=264&view=rev Author: danxuliu Date: 2010-09-28 20:55:26 +0000 (Tue, 28 Sep 2010) Log Message: ----------- Fix the StepWidget not being deleted when the tutorial fails to start. Modified Paths: -------------- trunk/ktutorial/ktutorial-library/src/KTutorial.cpp Modified: trunk/ktutorial/ktutorial-library/src/KTutorial.cpp =================================================================== --- trunk/ktutorial/ktutorial-library/src/KTutorial.cpp 2010-09-27 16:17:07 UTC (rev 263) +++ trunk/ktutorial/ktutorial-library/src/KTutorial.cpp 2010-09-28 20:55:26 UTC (rev 264) @@ -114,6 +114,12 @@ connect(tutorial, SIGNAL(stepActivated(Step*)), stepWidget, SLOT(setStep(Step*))); connect(stepWidget, SIGNAL(finished()), tutorial, SLOT(finish())); + //Invalid tutorials finish just after being started. Deleting the StepWidget + //when the tutorial finishes ensures that it is deleted in those cases and, + //as deleteLater() is used, it does not interfere with the deletion when the + //StepWidget is closed by the user. + connect(tutorial, SIGNAL(finished(Tutorial*)), + stepWidget, SLOT(deleteLater())); } void KTutorial::disableTutorialsAction() { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |