summaryrefslogtreecommitdiffstats
path: root/old/plugins/qtuitest_widgets/qtwidgets/testmenu.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'old/plugins/qtuitest_widgets/qtwidgets/testmenu.cpp')
-rw-r--r--old/plugins/qtuitest_widgets/qtwidgets/testmenu.cpp398
1 files changed, 398 insertions, 0 deletions
diff --git a/old/plugins/qtuitest_widgets/qtwidgets/testmenu.cpp b/old/plugins/qtuitest_widgets/qtwidgets/testmenu.cpp
new file mode 100644
index 0000000..66e1e58
--- /dev/null
+++ b/old/plugins/qtuitest_widgets/qtwidgets/testmenu.cpp
@@ -0,0 +1,398 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of QtUiTest.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "testmenu.h"
+#include "testwidgetslog.h"
+
+#include <QMenu>
+#include <QAction>
+
+namespace QtUiTest {
+
+TestMenu::TestMenu(QObject *_q)
+ : TestWidget(_q), q(qobject_cast<QMenu*>(_q)), lastAction(0)
+{
+ // For accurate ordering of events recording, these connections
+ // must come before all others.
+ QtUiTest::connectFirst(q, SIGNAL(hovered(QAction*)),
+ this, SLOT(on_hovered(QAction*)));
+}
+
+void TestMenu::on_hovered(QAction* a)
+{
+ if (lastAction)
+ QtUiTest::disconnectFirst(lastAction, 0, this, 0);
+ lastAction = a;
+ if (lastAction) {
+ QtUiTest::connectFirst(lastAction, SIGNAL(toggled(bool)),
+ this, SLOT(on_toggled(bool)));
+ QtUiTest::connectFirst(lastAction, SIGNAL(triggered(bool)),
+ this, SLOT(on_triggered(bool)));
+ }
+}
+
+void TestMenu::on_toggled(bool state)
+{ emit stateChanged(state); }
+
+QString textForAction(QMenu* m, QAction* a)
+{
+ QString ret;
+ foreach (QAction* child, m->actions()) {
+ if (child == a) {
+ ret = a->text();
+ ret.replace("/","\\/");
+ } else if (child->menu()) {
+ ret = textForAction(child->menu(), a);
+ if (!ret.isEmpty())
+ ret.prepend(child->menu()->title().replace("/","\\/") + "/");
+ }
+ if (!ret.isEmpty())
+ break;
+ }
+ return ret;
+}
+
+void TestMenu::on_triggered(bool)
+{
+ /*
+ Both the top level and submenus emit the triggered() signal.
+ We only want to emit selected() if we are the top level menu.
+ */
+ bool top_level = true;
+ if (q->menuAction()) {
+ foreach (QWidget* w, q->menuAction()->associatedWidgets()) {
+ if (qobject_cast<QMenu*>(w)) {
+ top_level = false;
+ break;
+ }
+ }
+ }
+
+ if (!top_level) return;
+
+ emit selected(textForAction(q,lastAction));
+}
+
+QString TestMenu::text() const
+{
+ return list().join("\n");
+}
+
+QString TestMenu::selectedText() const
+{
+ QString ret;
+
+ QAction *active = q->activeAction();
+ if (!active) return ret;
+
+ QMenu *child = active->menu();
+ if (!child || !child->activeAction())
+ return active->text().replace("/", "\\/");
+
+ return active->text().replace("/", "\\/") + "/" + qtuitest_cast<QtUiTest::TextWidget*>(child)->selectedText();
+}
+
+QStringList TestMenu::list() const
+{
+ QStringList ret;
+
+ /* Iterate through every action */
+ foreach( QAction *a, q->actions() ) {
+ if (!a->isEnabled() || a->isSeparator())
+ continue;
+ QString t = a->text();
+ t.replace("/","\\/");
+ if (!t.isEmpty()) ret << t;
+ if (a->menu() && a->menu() != q) {
+ QStringList sub = qtuitest_cast<QtUiTest::ListWidget*>(a->menu())->list();
+ foreach (QString s, sub) {
+ if (!s.isEmpty()) ret << t + "/" + s;
+ }
+ }
+ }
+
+ return ret;
+}
+
+QRect TestMenu::visualRect(QString const &item) const
+{
+ TestWidgetsLog() << item;
+ static QRegExp slashRe("[^\\\\]/");
+ QRect ret;
+
+ int ind;
+ if (0 != (ind = item.indexOf(slashRe)+1)) {
+ QString top(item.left(ind));
+ QString rest(item.mid(ind+1));
+
+ QAction *a(q->activeAction());
+ QString t = a->text();
+ t.replace("/","\\/");
+ if (!a || t != top || !a->menu()) {
+ TestWidgetsLog() << "The desired submenu" << item << "is not visible";
+ return ret;
+ }
+
+ ret = qtuitest_cast<QtUiTest::ListWidget*>(a->menu())->visualRect(rest);
+ ret.moveTopLeft( q->mapFromGlobal( a->menu()->mapToGlobal( ret.topLeft() ) ) );
+ return ret;
+ }
+
+ QAction *a = actionForItem(item);
+ if (a) ret = q->actionGeometry(a);
+
+ return ret;
+}
+
+QAction *TestMenu::actionForItem(QString const &item) const
+{
+ static QRegExp amperRe("&(.)");
+ QAction *ret = 0;
+ foreach( QAction *a, q->actions() ) {
+ QString t = a->text();
+ t.replace("/","\\/");
+ if (t == item) {
+ ret = a;
+ break;
+ } else {
+ t.replace(amperRe, "\\1");
+ if (t == item) {
+ ret = a;
+ }
+ }
+ }
+
+ if (!ret) {
+ setErrorString("Item \"" + item + "\" is not available");
+ } else if (!ret->isEnabled()) {
+ setErrorString("Item \"" + item + "\" is not enabled");
+ ret = 0;
+ }
+
+ return ret;
+}
+
+Qt::CheckState TestMenu::checkState() const
+{
+ QAction *active = q->activeAction();
+ return (active && active->isChecked()) ? Qt::Checked : Qt::Unchecked;
+}
+
+bool TestMenu::ensureVisible(QString const&)
+{ return false; }
+
+bool TestMenu::canSelect(QString const &item) const
+{
+ QStringList l = list();
+ return l.contains(item) || l.contains(labelText(item));
+}
+
+bool TestMenu::select(QString const &item)
+{
+ if (!isVisible()) {
+ setErrorString("Can't select \"" + item + "\" because menu is not visible");
+ return false;
+ }
+
+ TestWidgetsLog() << item;
+ static QRegExp slashRe("[^\\\\]/");
+
+ QString topItem = item;
+ QString rest;
+
+ int ind;
+ if (0 != (ind = item.indexOf(slashRe)+1)) {
+ topItem = item.left(ind);
+ rest = item.mid(ind+1);
+ }
+
+ QRect r = visualRect(topItem);
+ if (r.isNull()) {
+ if (errorString().isEmpty()) {
+ setErrorString("Can't find visual rect for item \"" + topItem + "\" in menu");
+ }
+ return false;
+ }
+
+ QPoint pos = r.center();
+
+ bool useMouse = mousePreferred();
+ if (useMouse) {
+ while (!rect().contains(pos)) {
+ QRect visibleRect = visibleRegion().boundingRect();
+ QPoint globalPos = mapToGlobal(visibleRect.topLeft());
+ if (pos.y() < globalPos.y()) {
+ TestWidgetsLog() << "click to scroll up";
+ mouseClick(QPoint(globalPos.x() + visibleRect.width() / 2, globalPos.y() + 8));
+ QtUiTest::wait(200);
+ } else {
+ TestWidgetsLog() << "click to scroll down";
+ mouseClick(QPoint(globalPos.x() + visibleRect.width() / 2, globalPos.y() + visibleRect.height() - 8));
+ QtUiTest::wait(200);
+ }
+
+ pos = visualRect(topItem).center();
+ }
+ TestWidgetsLog() << "click on item";
+ if (!mouseClick(q, mapToGlobal(pos)))
+ return false;
+// waitForSignal(q, SIGNAL(triggered(QAction*)));
+ } else {
+ Qt::Key key;
+ if ( pos.y() > q->actionGeometry(q->activeAction()).center().y() )
+ key = Qt::Key_Down;
+ else
+ key = Qt::Key_Up;
+
+ while ( selectedText() != topItem ) {
+ TestWidgetsLog() << "key" << ((key == Qt::Key_Down) ? "down" : "up");
+ if (!keyClick(q, key)) return false;
+ }
+
+ TestWidgetsLog() << "select key";
+ // If this is the last item, it should be trigged...
+ if (item == topItem) {
+ if (!keyClick(q->activeAction(), SIGNAL(triggered(bool)), QtUiTest::Key_Activate))
+ return false;
+ }
+ // ...but if it has a submenu, it won't be; rather, its menu will be shown.
+ else if (q->activeAction() && q->activeAction()->menu()) {
+ if (!keyClick(q->activeAction()->menu(), QtUiTest::Key_Activate))
+ return false;
+ }
+
+ // And if it doesn't have a submenu and isn't the final item... well, that shouldn't
+ // happen, but that will be caught below.
+ }
+
+ if (topItem != item) {
+ QAction *a(q->activeAction());
+ if (!a || !a->menu()) {
+ setErrorString("Failed to select \"" + item + "\" because " +
+ (!a ? "focus could not be given to a parent item."
+ : "an item was expected to have a submenu, but didn't."));
+ return false;
+ }
+
+ // Wait until the menu is visible
+ if (!a->menu()->isVisible() && !waitForEvent(a->menu(), QEvent::Show)) {
+ setErrorString("Failed to select \"" + item + "\" because a submenu did not become "
+ "visible when it should have.");
+ return false;
+ }
+
+ TestWidgetsLog() << "calling select() on child";
+ return qtuitest_cast<SelectWidget*>(a->menu())->select(rest);
+ }
+ return true;
+}
+
+bool TestMenu::isCheckable(const QString &item)
+{
+ static QRegExp slashRe("[^\\\\]/");
+ bool ret = false;
+ int ind;
+ if (0 != (ind = item.indexOf(slashRe)+1)) {
+ QString top(item.left(ind));
+ QString rest(item.mid(ind+1));
+
+ QAction *a = actionForItem(top);
+ if (!a || !a->menu()) {
+ TestWidgetsLog() << "The desired submenu" << item << "is not valid";
+ return ret;
+ }
+
+ return qtuitest_cast<QtUiTest::CheckItemWidget*>(a->menu())->isCheckable(rest);
+ }
+
+ QAction *a = actionForItem(item);
+ if (a) ret = a->isCheckable();
+
+ return ret;
+}
+
+bool TestMenu::isChecked(const QString &item) const
+{
+ static QRegExp slashRe("[^\\\\]/");
+
+ bool ret = false;
+ int ind;
+ if (0 != (ind = item.indexOf(slashRe)+1)) {
+ QString top(item.left(ind));
+ QString rest(item.mid(ind+1));
+
+ QAction *a = actionForItem(top);
+ if (!a || !a->menu()) {
+ TestWidgetsLog() << "The desired submenu" << item << "is not valid";
+ return ret;
+ }
+
+ return qtuitest_cast<QtUiTest::CheckItemWidget*>(a->menu())->isChecked(rest);
+ }
+
+ QAction *a = actionForItem(item);
+ if (a) {
+ ret = a->isChecked();
+ } else {
+ setErrorString("Cannot get check status for item \"" + item + "\"");
+ }
+
+ return ret;
+}
+
+bool TestMenu::setChecked(const QString &item, bool value)
+{
+ if (isChecked(item) == value) {
+ return true;
+ }
+
+ return select(item);
+}
+
+bool TestMenu::hasFocus() const
+{
+ return !q->isHidden();
+}
+
+bool TestMenu::canWrap(QObject *o)
+{ return qobject_cast<QMenu*>(o); }
+
+}