diff options
author | axis <qt-info@nokia.com> | 2009-04-24 11:34:15 (GMT) |
---|---|---|
committer | axis <qt-info@nokia.com> | 2009-04-24 11:34:15 (GMT) |
commit | 8f427b2b914d5b575a4a7c0ed65d2fb8f45acc76 (patch) | |
tree | a17e1a767a89542ab59907462206d7dcf2e504b2 /tests/auto/xmlpatternsview/view/MainWindow.cpp | |
download | Qt-8f427b2b914d5b575a4a7c0ed65d2fb8f45acc76.zip Qt-8f427b2b914d5b575a4a7c0ed65d2fb8f45acc76.tar.gz Qt-8f427b2b914d5b575a4a7c0ed65d2fb8f45acc76.tar.bz2 |
Long live Qt for S60!
Diffstat (limited to 'tests/auto/xmlpatternsview/view/MainWindow.cpp')
-rw-r--r-- | tests/auto/xmlpatternsview/view/MainWindow.cpp | 531 |
1 files changed, 531 insertions, 0 deletions
diff --git a/tests/auto/xmlpatternsview/view/MainWindow.cpp b/tests/auto/xmlpatternsview/view/MainWindow.cpp new file mode 100644 index 0000000..57aaca0 --- /dev/null +++ b/tests/auto/xmlpatternsview/view/MainWindow.cpp @@ -0,0 +1,531 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the Patternist project on Trolltech Labs. +** +** $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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +*************************************************************************** +*/ + +#include <QCloseEvent> +#include <QFileDialog> +#include <QFileInfo> +#include <QHeaderView> +#include <QMenu> +#include <QMessageBox> +#include <QProcess> +#include <QSettings> +#include <QTextStream> + +#include "ASTItem.h" +#include "FunctionSignaturesView.h" +#include "Global.h" +#include "TestCaseView.h" +#include "TestResultView.h" +#include "TestSuite.h" +#include "TreeModel.h" +#include "TreeSortFilter.h" +#include "UserTestCase.h" + +#include "MainWindow.h" + +using namespace QPatternistSDK; + +MainWindow::MainWindow() : m_userTC(new UserTestCase()), + m_currentTC(0) +{ + setupUi(this); + + /* I want to do this in Designer.. */ + testSuiteView->header()->setSortIndicator(0, Qt::AscendingOrder); + testSuiteView->header()->setSortIndicatorShown(true); + testSuiteView->header()->setClickable(true); + + setupActions(); + + QStringList suiteHeaders; + suiteHeaders << QLatin1String("Name") + << QLatin1String("Pass") + << QLatin1String("Fail") + << QLatin1String("Total"); + + TreeSortFilter *const proxy = new TreeSortFilter(this); + connect(searchInput, SIGNAL(textChanged(const QString &)), + proxy, SLOT(setFilterFixedString(const QString &))); + + proxy->setSourceModel(new TreeModel(suiteHeaders, this)); + testSuiteView->setModel(proxy); + + /* --------- Test Result View ---------- */ + testResultView = new TestResultView(this); + testResultView->setAllowedAreas(Qt::AllDockWidgetAreas); + addDockWidget(Qt::RightDockWidgetArea, testResultView); + /* ----------------------------------- */ + + /* --------- Test Case View ---------- */ + testCaseView = new TestCaseView(this); + testCaseView->setAllowedAreas(Qt::AllDockWidgetAreas); + addDockWidget(Qt::LeftDockWidgetArea, testCaseView); + + connect(this, SIGNAL(testCaseSelected(TestCase *const)), + testCaseView, SLOT(displayTestCase(TestCase *const))); + connect(this, SIGNAL(testCaseSelected(TestCase *const)), + testResultView, SLOT(displayTestResult(TestCase *const))); + connect(focusURI, SIGNAL(textChanged(const QString &)), + m_userTC, SLOT(focusDocumentChanged(const QString &))); + /* ----------------------------------- */ + + /* ----- Function Signature View ----- */ + functionView = new FunctionSignaturesView(this); + functionView->setAllowedAreas(Qt::AllDockWidgetAreas); + addDockWidget(Qt::RightDockWidgetArea, functionView); + /* ----------------------------------- */ + + /* Appears here, because the menu uses actions in the QDockWidgets. */ + setupMenu(); + + readSettings(); + + /* Connect this after readSettings(), otherwise readSettings() triggers writeSettings(). */ + connect(sourceTab, SIGNAL(currentChanged(int)), + SLOT(writeSettings())); + connect(testSuiteView, SIGNAL(clicked(const QModelIndex &)), + SLOT(writeSettings())); + connect(sourceInput, SIGNAL(textChanged()), + SLOT(writeSettings())); +} + +MainWindow::~MainWindow() +{ + delete m_userTC; +} + +QModelIndex MainWindow::sourceIndex(const QModelIndex &proxyIndex) const +{ + return static_cast<TreeSortFilter *>(testSuiteView->model())->mapToSource(proxyIndex); +} + +TreeModel *MainWindow::sourceModel() const +{ + const TreeSortFilter *const proxy = static_cast<TreeSortFilter *>(testSuiteView->model()); + return static_cast<TreeModel *>(proxy->sourceModel()); +} + +void MainWindow::on_testSuiteView_clicked(const QModelIndex &index) +{ + if(index.isValid()) + { + TestItem *const node = static_cast<TestItem *>(sourceIndex(index).internalPointer()); + Q_ASSERT(node); + + if(node->isFinalNode()) + { + m_currentTC = static_cast<TestCase *>(node); + testCaseSelected(m_currentTC); + return; + } + } + + /* In all other cases: */ + m_currentTC = 0; + testCaseSelected(0); +} + +void MainWindow::on_sourceInput_textChanged() +{ + m_userTC->setSourceCode(sourceInput->toPlainText()); +} + +void MainWindow::on_actionOpen_triggered() +{ + const QString fileName(QFileDialog::getOpenFileName(this, + QLatin1String("Open Test Suite Catalog"), + m_previousOpenedCatalog.toLocalFile(), + QLatin1String("Test Suite Catalog file (*.xml)"))); + + /* "If the user presses Cancel, it returns a null string." */ + if(fileName.isNull()) + return; + + openCatalog(QUrl::fromLocalFile(fileName), true, false); +} + +void MainWindow::on_actionOpenXSLTSCatalog_triggered() +{ + const QString fileName(QFileDialog::getOpenFileName(this, + QLatin1String("Open Test Suite Catalog"), + m_previousOpenedCatalog.toLocalFile(), + QLatin1String("Test Suite Catalog file (*.xml)"))); + + /* "If the user presses Cancel, it returns a null string." */ + if(fileName.isNull()) + return; + + openCatalog(QUrl::fromLocalFile(fileName), true, true); +} + +void MainWindow::openCatalog(const QUrl &fileName, + const bool reportError, + const bool isXSLT) +{ + setCurrentFile(fileName); + m_previousOpenedCatalog = fileName; + + QString errorMsg; + TestSuite *const loadedSuite = TestSuite::openCatalog(fileName, errorMsg, false, isXSLT); + + if(!loadedSuite) + { + if(reportError) + { + QMessageBox::information(this, QLatin1String("Failed to load catalog file"), + errorMsg, QMessageBox::Ok); + } + + return; + } + + TreeModel *const prevModel = sourceModel(); + prevModel->setRoot(loadedSuite); + m_currentTC = 0; + + testCaseCount->setText(QString::number(loadedSuite->resultSummary().second)); + /* Switch to the tab containing the loaded test suite. */ + sourceTab->setCurrentIndex(0); + + setWindowTitle(QCoreApplication::applicationName() + + QLatin1String(" -- ") + + QFileInfo(fileName.toLocalFile()).fileName()); + + /* @p reportError is set when not auto-loading on startup, and + * we only want to save when the user opens from the GUI. */ + if(reportError) + writeSettings(); +} + +void MainWindow::on_sourceTab_currentChanged(int index) +{ + if(index == 1) + { + m_currentTC = m_userTC; + testCaseSelected(m_userTC); + } + else + on_testSuiteView_clicked(testSuiteView->currentIndex()); +} + +void MainWindow::on_actionExecute_triggered() +{ + Q_ASSERT(testCaseView); + TestSuite *const ts = static_cast<TestSuite *>(sourceModel()->root()); + + const TestItem::ExecutionStage stage = compileOnly->isChecked() ? TestItem::CompileOnly + : TestItem::CompileAndRun; + + m_userTC->setLanguage(isXSLT20->isChecked() ? QXmlQuery::XSLT20 : QXmlQuery::XQuery10); + + if(m_currentTC) + { + const TestResult::List rlist(m_currentTC->execute(stage, ts)); + Q_ASSERT(rlist.count() == 1); + const TestResult *const result = rlist.first(); + Q_ASSERT(result); + testResultView->displayTestResult(result); + } + else + { + const QModelIndexList indexes = testSuiteView->selectionModel()->selectedIndexes(); + for (int i = 0; i < indexes.count(); ++i) { + const QModelIndex source(sourceIndex(indexes.at(i))); + + TestItem *const ti = static_cast<TestItem *>(source.internalPointer()); + if(!ti) + return; + + /* ti is a TestGroup. It now executes its children, changed(TreeItem *) signals is + * emitted which the view receives, and thus updates. */ + ti->execute(stage, ts); + } + } +} + +void MainWindow::readSettings() +{ + QSettings settings; + + settings.beginGroup(QLatin1String("MainWindow")); + restoreState(settings.value(QLatin1String("state")).toByteArray(), Global::versionNumber); + resize(settings.value(QLatin1String("size"), QSize(400, 400)).toSize()); + move(settings.value(QLatin1String("pos"), QPoint(200, 200)).toPoint()); + m_previousOpenedCatalog = settings.value(QLatin1String("PreviousOpenedCatalogFile")).toUrl(); + focusURI->setText(settings.value(QLatin1String("focusURI")).toString()); + isXSLT20->setChecked(settings.value(QLatin1String("isXSLT20")).toBool()); + compileOnly->setChecked(settings.value(QLatin1String("compileOnly")).toBool()); + + /* Open the previously opened catalog. */ + if(!m_previousOpenedCatalog.isEmpty()) + { + /* We don't know what kind of catalog it is, so we just take a chance. */ + openCatalog(m_previousOpenedCatalog, false, isXSLT20->isChecked()); + } + + sourceInput->setPlainText(settings.value(QLatin1String("sourceInput")).toString()); + testResultView->resultViewSelection->setCurrentIndex( + settings.value(QLatin1String("ResultViewMethod"), 0).toInt()); + testResultView->outputStack->setCurrentIndex(settings.value( + QLatin1String("ResultViewMethod"), 0).toInt()); + + /* Restore the selected test case/group. */ + const QStringList rows(settings.value(QLatin1String("SelectedTestSuiteRow"), + QString()) + .toString().split(QLatin1Char(','))); + + if(!rows.isEmpty()) /* Ok, we have a selection. */ + { + QAbstractItemModel *const model = testSuiteView->model(); + Q_ASSERT(model); + QModelIndex p; + + for(int i = rows.count() - 1; i >= 0; --i) + { + const QModelIndex childIndex(model->index(rows.at(i).toInt(), 0 , p)); + + if(childIndex.isValid()) + { + testSuiteView->scrollTo(p); /* Work around for Qt issue #87575. */ + p = childIndex; + } + } + + testSuiteView->scrollTo(p); /* Scrolls to it. */ + testSuiteView->setCurrentIndex(p); /* Selects it. */ + on_testSuiteView_clicked(p); /* Loads the test case in the Test Case View. */ + } + + /* Do it here. In this way the user-entered test case gets selected, if that tab + * was previously used. */ + sourceTab->setCurrentIndex(settings.value(QLatin1String("SelectedTab"), 0).toInt()); + on_sourceTab_currentChanged(sourceTab->currentIndex()); + + settings.endGroup(); +} + +void MainWindow::writeSettings() +{ + QSettings settings; + + settings.beginGroup(QLatin1String("MainWindow")); + settings.setValue(QLatin1String("state"), saveState(Global::versionNumber)); + settings.setValue(QLatin1String("pos"), pos()); + settings.setValue(QLatin1String("size"), size()); + settings.setValue(QLatin1String("sourceInput"), sourceInput->toPlainText()); + settings.setValue(QLatin1String("PreviousOpenedCatalogFile"), m_previousOpenedCatalog); + settings.setValue(QLatin1String("SelectedTab"), sourceTab->currentIndex()); + settings.setValue(QLatin1String("ResultViewMethod"), + testResultView->resultViewSelection->currentIndex()); + settings.setValue(QLatin1String("focusURI"), + focusURI->text()); + settings.setValue(QLatin1String("isXSLT20"), + isXSLT20->isChecked()); + settings.setValue(QLatin1String("compileOnly"), + compileOnly->isChecked()); + + /* Store the selected test case/group. */ + QModelIndex selected(sourceIndex(testSuiteView->currentIndex())); + if(selected.isValid()) + { + QString result; + + do + { + result.append(QString::number(selected.row())); + selected = selected.parent(); + + if(selected.isValid()) + result.append(QLatin1Char(',')); + else + break; + } + while(true); + + settings.setValue(QLatin1String("SelectedTestSuiteRow"), result); + } + + settings.endGroup(); +} + +void MainWindow::setCurrentFile(const QUrl &f) +{ + const QString fileName(f.toLocalFile()); + QSettings settings; + settings.beginGroup(QLatin1String("MainWindow")); + QStringList files(settings.value(QLatin1String("RecentFileList")).toStringList()); + + files.removeAll(fileName); + files.prepend(fileName); + while(files.size() > MaximumRecentFiles) + files.removeLast(); + + settings.setValue(QLatin1String("RecentFileList"), files); + settings.endGroup(); + + updateRecentFileActions(); +} + +void MainWindow::updateRecentFileActions() +{ + QSettings settings; + settings.beginGroup(QLatin1String("MainWindow")); + const QStringList files(settings.value(QLatin1String("RecentFileList")).toStringList()); + settings.endGroup(); + + const int numRecentFiles = qMin(files.size(), static_cast<int>(MaximumRecentFiles)); + + for(int i = 0; i < numRecentFiles; ++i) + { + const QString text(QString::fromLatin1("&%1 %2").arg(i + 1).arg(QFileInfo(files[i]).filePath())); + m_recentFileActs[i]->setText(text); + m_recentFileActs[i]->setData(QUrl::fromLocalFile(files[i])); + m_recentFileActs[i]->setVisible(true); + } + + for(int j = numRecentFiles; j < MaximumRecentFiles; ++j) + m_recentFileActs[j]->setVisible(false); +} + +void MainWindow::openRecentFile() +{ + const QAction *const action = qobject_cast<QAction *>(sender()); + if(action) + openCatalog(action->data().toUrl(), true, false); +} + +void MainWindow::closeEvent(QCloseEvent *ev) +{ + writeSettings(); + ev->accept(); +} + +void MainWindow::setupActions() +{ + connect(actionQuit, SIGNAL(triggered()), qApp, SLOT(closeAllWindows())); + + for(int i = 0; i < MaximumRecentFiles; ++i) + { + m_recentFileActs[i] = new QAction(this); + m_recentFileActs[i]->setVisible(false); + connect(m_recentFileActs[i], SIGNAL(triggered()), + this, SLOT(openRecentFile())); + } +} + +void MainWindow::setupMenu() +{ + QMenu *const menFile = findChild<QMenu *>(QLatin1String("menuFile")); + Q_ASSERT(menFile); + QAction *const actOpen = findChild<QAction *>(QLatin1String("actionExecute")); + Q_ASSERT(actOpen); + QMenu *const recent = new QMenu(QLatin1String("O&pen Recent"), this); + + menFile->insertMenu(actOpen, recent); + menFile->insertSeparator(actOpen); + + for(int i = 0; i < MaximumRecentFiles; ++i) + recent->addAction(m_recentFileActs[i]); + + updateRecentFileActions(); + + QMenu *const menWindows = findChild<QMenu *>(QLatin1String("menuWindows")); + Q_ASSERT(menWindows); + + menWindows->addAction(testCaseView->toggleViewAction()); + menWindows->addAction(testResultView->toggleViewAction()); + menWindows->addAction(functionView->toggleViewAction()); +} + +void MainWindow::on_actionRestart_triggered() +{ + if(QProcess::startDetached(QCoreApplication::applicationFilePath())) + QApplication::closeAllWindows(); + else + { + QTextStream err(stderr); + err << "Failed to start " << qPrintable(QCoreApplication::applicationFilePath()) << endl; + } +} + + +// vim: et:ts=4:sw=4:sts=4 |