diff options
-rw-r--r-- | src/app/app.pro | 4 | ||||
-rw-r--r-- | src/app/config-ui/config-ui.pro | 11 | ||||
-rw-r--r-- | src/app/config-ui/main.cpp | 60 | ||||
-rw-r--r-- | src/app/config-ui/mainwindow.cpp | 97 | ||||
-rw-r--r-- | src/app/config-ui/mainwindow.h | 59 | ||||
-rw-r--r-- | src/app/config-ui/mainwindow.ui | 37 | ||||
-rw-r--r-- | src/app/config-ui/settingsmodel.cpp | 165 | ||||
-rw-r--r-- | src/app/config-ui/settingsmodel.h | 51 | ||||
-rw-r--r-- | src/app/qbs/qbstool.cpp | 5 | ||||
-rw-r--r-- | src/app/qbs/qbstool.h | 2 | ||||
-rw-r--r-- | src/lib/tools/settings.cpp | 11 | ||||
-rw-r--r-- | src/lib/tools/settings.h | 1 |
12 files changed, 496 insertions, 7 deletions
diff --git a/src/app/app.pro b/src/app/app.pro index 839898686..4725a9a3b 100644 --- a/src/app/app.pro +++ b/src/app/app.pro @@ -5,4 +5,6 @@ SUBDIRS =\ setupmaddeplatforms \ qbs-setup-qt \ config \ - qbs-qmltypes \ + qbs-qmltypes + +lessThan(QT_MAJOR_VERSION, 5)|!isEmpty(QT.widgets.name):SUBDIRS += config-ui diff --git a/src/app/config-ui/config-ui.pro b/src/app/config-ui/config-ui.pro new file mode 100644 index 000000000..1a587587e --- /dev/null +++ b/src/app/config-ui/config-ui.pro @@ -0,0 +1,11 @@ +QT = core gui +greaterThan(QT_MAJOR_VERSION, 4):QT += widgets + +TARGET = qbs-config-ui +DESTDIR = ../../../bin + +HEADERS = settingsmodel.h mainwindow.h +SOURCES = settingsmodel.cpp mainwindow.cpp main.cpp +FORMS = mainwindow.ui + +include(../../lib/use.pri) diff --git a/src/app/config-ui/main.cpp b/src/app/config-ui/main.cpp new file mode 100644 index 000000000..43f6b300e --- /dev/null +++ b/src/app/config-ui/main.cpp @@ -0,0 +1,60 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the Qt Build Suite. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** 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, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ +#include "mainwindow.h" + +#include "../shared/qbssettings.h" + +#include <logging/consolelogger.h> +#include <logging/translator.h> + +#include <QApplication> +#include <cstdlib> + +using namespace qbs; + +int main(int argc, char *argv[]) +{ + QApplication app(argc, argv); + SettingsPtr settings = qbsSettings(); + ConsoleLogger cl(settings.data()); + + const QStringList args = app.arguments().mid(1); + if (args.count() == 1 && + (args.first() == QLatin1String("--help") || args.first() == QLatin1String("-h"))) { + qbsInfo() << DontPrintLogLevel << LogOutputStdOut + << Tr::tr("This tool displays qbs settings in a GUI.\n" + "If you have more than a few settings, this might be preferable to " + "plain \"qbs config\", as it presents a hierarchical view."); + return EXIT_SUCCESS; + } + + MainWindow mw; + mw.show(); + return app.exec(); +} diff --git a/src/app/config-ui/mainwindow.cpp b/src/app/config-ui/mainwindow.cpp new file mode 100644 index 000000000..1ea3729b5 --- /dev/null +++ b/src/app/config-ui/mainwindow.cpp @@ -0,0 +1,97 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the Qt Build Suite. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** 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, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ +#include "mainwindow.h" +#include "ui_mainwindow.h" + +#include "settingsmodel.h" + +#include <QAction> +#include <QKeySequence> +#include <QMenu> +#include <QMenuBar> + +MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) +{ + ui->setupUi(this); + m_model = new SettingsModel(this); + ui->treeView->setModel(m_model); + connect(ui->treeView, SIGNAL(expanded(QModelIndex)), SLOT(adjustColumns())); + adjustColumns(); + + QMenu * const fileMenu = menuBar()->addMenu(tr("&File")); + QMenu * const viewMenu = menuBar()->addMenu(tr("&View")); + + QAction * const reloadAction = new QAction(tr("&Reload"), this); + reloadAction->setShortcut(Qt::CTRL | Qt::Key_R); + connect(reloadAction, SIGNAL(triggered()), SLOT(reloadSettings())); + QAction * const expandAllAction = new QAction(tr("&Expand All"), this); + expandAllAction->setShortcut(Qt::CTRL | Qt::Key_E); + connect(expandAllAction, SIGNAL(triggered()), SLOT(expandAll())); + QAction * const collapseAllAction = new QAction(tr("C&ollapse All"), this); + collapseAllAction->setShortcut(Qt::CTRL | Qt::Key_O); + connect(collapseAllAction, SIGNAL(triggered()), SLOT(collapseAll())); + QAction * const exitAction = new QAction(tr("E&xit"), this); + exitAction->setShortcut(Qt::CTRL | Qt::Key_Q); + connect(exitAction, SIGNAL(triggered()), qApp, SLOT(quit())); + + fileMenu->addAction(reloadAction); + fileMenu->addSeparator(); + fileMenu->addAction(exitAction); + + viewMenu->addAction(expandAllAction); + viewMenu->addAction(collapseAllAction); +} + +MainWindow::~MainWindow() +{ + delete ui; +} + +void MainWindow::adjustColumns() +{ + for (int column = 0; column < m_model->columnCount(); ++column) + ui->treeView->resizeColumnToContents(column); +} + +void MainWindow::expandAll() +{ + ui->treeView->expandAll(); + adjustColumns(); +} + +void MainWindow::collapseAll() +{ + ui->treeView->collapseAll(); + adjustColumns(); +} + +void MainWindow::reloadSettings() +{ + m_model->reload(); +} diff --git a/src/app/config-ui/mainwindow.h b/src/app/config-ui/mainwindow.h new file mode 100644 index 000000000..e793f69dd --- /dev/null +++ b/src/app/config-ui/mainwindow.h @@ -0,0 +1,59 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the Qt Build Suite. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** 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, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ +#ifndef MAINWINDOW_H +#define MAINWINDOW_H + +#include <QMainWindow> + +QT_BEGIN_NAMESPACE +namespace Ui { class MainWindow; } +QT_END_NAMESPACE + +class SettingsModel; + +class MainWindow : public QMainWindow +{ + Q_OBJECT + +public: + explicit MainWindow(QWidget *parent = 0); + ~MainWindow(); + +private slots: + void adjustColumns(); + void expandAll(); + void collapseAll(); + void reloadSettings(); + +private: + Ui::MainWindow *ui; + SettingsModel *m_model; +}; + +#endif // MAINWINDOW_H diff --git a/src/app/config-ui/mainwindow.ui b/src/app/config-ui/mainwindow.ui new file mode 100644 index 000000000..7a3416ce4 --- /dev/null +++ b/src/app/config-ui/mainwindow.ui @@ -0,0 +1,37 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>MainWindow</class> + <widget class="QMainWindow" name="MainWindow"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>800</width> + <height>600</height> + </rect> + </property> + <property name="windowTitle"> + <string>Qbs Settings</string> + </property> + <widget class="QWidget" name="centralwidget"> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QTreeView" name="treeView"/> + </item> + </layout> + </widget> + <widget class="QMenuBar" name="menubar"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>800</width> + <height>27</height> + </rect> + </property> + </widget> + <widget class="QStatusBar" name="statusbar"/> + </widget> + <resources/> + <connections/> +</ui> diff --git a/src/app/config-ui/settingsmodel.cpp b/src/app/config-ui/settingsmodel.cpp new file mode 100644 index 000000000..f54ef5ac0 --- /dev/null +++ b/src/app/config-ui/settingsmodel.cpp @@ -0,0 +1,165 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the Qt Build Suite. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** 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, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ +#include "settingsmodel.h" + +#include "../shared/qbssettings.h" + +#include <QList> +#include <QString> + +struct Node +{ + Node() : parent(0) {} + ~Node() { qDeleteAll(children); } + + QString name; + QString value; + Node *parent; + QList<Node *> children; +}; + +class SettingsModel::SettingsModelPrivate +{ +public: + void readSettings(); + void addNode(qbs::Settings *settings, Node *parentNode, const QString &fullyQualifiedName); + Node *indexToNode(const QModelIndex &index); + + Node rootNode; +}; + +SettingsModel::SettingsModel(QObject *parent) + : QAbstractItemModel(parent), d(new SettingsModelPrivate) +{ + d->readSettings(); +} + +SettingsModel::~SettingsModel() +{ + delete d; +} + +void SettingsModel::reload() +{ + beginResetModel(); + d->readSettings(); + endResetModel(); +} + +Qt::ItemFlags SettingsModel::flags(const QModelIndex &index) const +{ + if (!index.isValid()) + return Qt::ItemFlags(); + return Qt::ItemIsEnabled | Qt::ItemIsSelectable; +} + +QVariant SettingsModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + if (orientation != Qt::Horizontal) + return QVariant(); + if (role != Qt::DisplayRole) + return QVariant(); + if (section == 0) + return tr("Key"); + return tr("Value"); +} + +int SettingsModel::columnCount(const QModelIndex &parent) const +{ + Q_UNUSED(parent); + return 2; +} + +int SettingsModel::rowCount(const QModelIndex &parent) const +{ + if (parent.column() > 0) + return 0; + const Node * const node = d->indexToNode(parent); + Q_ASSERT(node); + return node->children.count(); +} + +QVariant SettingsModel::data(const QModelIndex &index, int role) const +{ + if (role != Qt::DisplayRole) + return QVariant(); + const Node * const node = static_cast<Node *>(index.internalPointer()); + Q_ASSERT(node); + if (index.column() == 0) + return node->name; + return node->value; +} + +QModelIndex SettingsModel::index(int row, int column, const QModelIndex &parent) const +{ + const Node * const parentNode = d->indexToNode(parent); + Q_ASSERT(parentNode); + if (parentNode->children.count() <= row) + return QModelIndex(); + return createIndex(row, column, parentNode->children.at(row)); +} + +QModelIndex SettingsModel::parent(const QModelIndex &child) const +{ + Node * const childNode = static_cast<Node *>(child.internalPointer()); + Q_ASSERT(childNode); + Node * const parentNode = childNode->parent; + if (parentNode == &d->rootNode) + return QModelIndex(); + const Node * const grandParentNode = parentNode->parent; + Q_ASSERT(grandParentNode); + return createIndex(grandParentNode->children.indexOf(parentNode), 0, parentNode); +} + + +void SettingsModel::SettingsModelPrivate::readSettings() +{ + qDeleteAll(rootNode.children); + rootNode.children.clear(); + SettingsPtr settings = qbsSettings(); + foreach (const QString &topLevelKey, settings->directChildren(QString())) + addNode(settings.data(), &rootNode, topLevelKey); +} + +void SettingsModel::SettingsModelPrivate::addNode(qbs::Settings *settings, Node *parentNode, + const QString &fullyQualifiedName) +{ + Node * const node = new Node; + node->name = fullyQualifiedName.mid(fullyQualifiedName.lastIndexOf(QLatin1Char('.')) + 1); + node->value = settings->value(fullyQualifiedName).toString(); + node->parent = parentNode; + parentNode->children << node; + foreach (const QString &childKey, settings->directChildren(fullyQualifiedName)) + addNode(settings, node, fullyQualifiedName + QLatin1Char('.') + childKey); +} + +Node *SettingsModel::SettingsModelPrivate::indexToNode(const QModelIndex &index) +{ + return index.isValid() ? static_cast<Node *>(index.internalPointer()) : &rootNode; +} diff --git a/src/app/config-ui/settingsmodel.h b/src/app/config-ui/settingsmodel.h new file mode 100644 index 000000000..1052196e2 --- /dev/null +++ b/src/app/config-ui/settingsmodel.h @@ -0,0 +1,51 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the Qt Build Suite. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** 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, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ +#include <QAbstractItemModel> + +class SettingsModel : public QAbstractItemModel +{ + Q_OBJECT +public: + SettingsModel(QObject *parent = 0); + ~SettingsModel(); + + void reload(); + + Qt::ItemFlags flags(const QModelIndex &index) const; + QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; + int columnCount(const QModelIndex &parent = QModelIndex()) const; + int rowCount(const QModelIndex &parent = QModelIndex()) const; + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; + QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const; + QModelIndex parent(const QModelIndex &child) const; + +private: + class SettingsModelPrivate; + SettingsModelPrivate * const d; +}; diff --git a/src/app/qbs/qbstool.cpp b/src/app/qbs/qbstool.cpp index 512e2ed9b..3ed7e4950 100644 --- a/src/app/qbs/qbstool.cpp +++ b/src/app/qbs/qbstool.cpp @@ -44,14 +44,13 @@ static QString qbsToolFilePath(const QString &toolName) void QbsTool::runTool(const QString &toolName, const QStringList &arguments) { - m_failedToStart = m_failedToFinish = false; + m_failedToStart = false; m_exitCode = -1; QProcess toolProc; toolProc.start(qbsToolFilePath(toolName), arguments); if (!toolProc.waitForStarted()) m_failedToStart = true; - if (!toolProc.waitForFinished()) - m_failedToFinish = true; + toolProc.waitForFinished(-1); m_exitCode = toolProc.exitCode(); m_stdout = QString::fromLocal8Bit(toolProc.readAllStandardOutput()); m_stderr = QString::fromLocal8Bit(toolProc.readAllStandardError()); diff --git a/src/app/qbs/qbstool.h b/src/app/qbs/qbstool.h index 4e7b5e3f7..92520af6b 100644 --- a/src/app/qbs/qbstool.h +++ b/src/app/qbs/qbstool.h @@ -35,7 +35,6 @@ public: void runTool(const QString &toolName, const QStringList &arguments); bool failedToStart() const { return m_failedToStart; } - bool failedToFinish() const { return m_failedToFinish; } int exitCode() const { return m_exitCode; } QString stdOut() const { return m_stdout; } QString stdErr() const { return m_stderr; } @@ -46,7 +45,6 @@ public: private: bool m_failedToStart; - bool m_failedToFinish; int m_exitCode; QString m_stdout; QString m_stderr; diff --git a/src/lib/tools/settings.cpp b/src/lib/tools/settings.cpp index 255a78c98..147ec0693 100644 --- a/src/lib/tools/settings.cpp +++ b/src/lib/tools/settings.cpp @@ -69,6 +69,16 @@ QStringList Settings::allKeys() const return keys; } +QStringList Settings::directChildren(const QString &parentGroup) +{ + m_settings->beginGroup(internalRepresentation(parentGroup)); + QStringList children = m_settings->childGroups(); + children << m_settings->childKeys(); + m_settings->endGroup(); + fixupKeys(children); + return children; +} + QStringList Settings::allKeysWithPrefix(const QString &group) { m_settings->beginGroup(internalRepresentation(group)); @@ -118,7 +128,6 @@ QString Settings::externalRepresentation(const QString &internalKey) const void Settings::fixupKeys(QStringList &keys) const { keys.sort(); - std::unique(keys.begin(), keys.end()); keys.removeDuplicates(); for (QStringList::Iterator it = keys.begin(); it != keys.end(); ++it) *it = externalRepresentation(*it); diff --git a/src/lib/tools/settings.h b/src/lib/tools/settings.h index 2a6c93129..25e7bc0d6 100644 --- a/src/lib/tools/settings.h +++ b/src/lib/tools/settings.h @@ -47,6 +47,7 @@ public: QVariant value(const QString &key, const QVariant &defaultValue = QVariant()) const; QStringList allKeys() const; + QStringList directChildren(const QString &parentGroup); // Keys and groups. QStringList allKeysWithPrefix(const QString &group); void setValue(const QString &key, const QVariant &value); void remove(const QString &key); |