From 8b7ee8298f0f3fd6b7d44f5cf34f5fc616e24d2d Mon Sep 17 00:00:00 2001 From: Friedemann Kleint <Friedemann.Kleint@nokia.com> Date: Fri, 8 May 2009 12:21:18 +0200 Subject: [PATCH] Added a Path list editor widget. On this occasion, fixed qtcreatorwidgets plugin for lib64. --- src/libs/utils/pathlisteditor.cpp | 263 ++++++++++++++++++ src/libs/utils/pathlisteditor.h | 105 +++++++ src/libs/utils/utils.pro | 2 + src/tools/qtcreatorwidgets/customwidgets.cpp | 12 + src/tools/qtcreatorwidgets/customwidgets.h | 11 + .../qtcreatorwidgets/qtcreatorwidgets.pro | 6 +- 6 files changed, 398 insertions(+), 1 deletion(-) create mode 100644 src/libs/utils/pathlisteditor.cpp create mode 100644 src/libs/utils/pathlisteditor.h diff --git a/src/libs/utils/pathlisteditor.cpp b/src/libs/utils/pathlisteditor.cpp new file mode 100644 index 00000000000..618abe1857a --- /dev/null +++ b/src/libs/utils/pathlisteditor.cpp @@ -0,0 +1,263 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Qt Software Information (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** +**************************************************************************/ + +#include "pathlisteditor.h" + +#include <QtGui/QVBoxLayout> +#include <QtGui/QHBoxLayout> +#include <QtGui/QPlainTextEdit> +#include <QtGui/QPushButton> +#include <QtGui/QToolButton> +#include <QtGui/QSpacerItem> +#include <QtGui/QFileDialog> +#include <QtGui/QTextCursor> +#include <QtGui/QTextBlock> + +#include <QtCore/QSignalMapper> +#include <QtCore/QMimeData> +#include <QtCore/QSharedPointer> + +namespace Core { +namespace Utils { + +// ------------ PathListPlainTextEdit: +// Replaces the platform separator ';',':' by '\n' +// when inserting, allowing for pasting in paths +// from the terminal or such. + +class PathListPlainTextEdit : public QPlainTextEdit { +public: + explicit PathListPlainTextEdit(QWidget *parent = 0); +protected: + virtual void insertFromMimeData (const QMimeData *source); +}; + +PathListPlainTextEdit::PathListPlainTextEdit(QWidget *parent) : + QPlainTextEdit(parent) +{ + // No wrapping, scroll at all events + setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded); + setLineWrapMode(QPlainTextEdit::NoWrap); +} + +void PathListPlainTextEdit::insertFromMimeData(const QMimeData *source) +{ + if (source->hasText()) { + // replace separator + QString text = source->text().trimmed(); + text.replace(PathListEditor::separator(), QLatin1Char('\n')); + QSharedPointer<QMimeData> fixed(new QMimeData); + fixed->setText(text); + QPlainTextEdit::insertFromMimeData(fixed.data()); + } else { + QPlainTextEdit::insertFromMimeData(source); + } +} + +// ------------ PathListEditorPrivate +struct PathListEditorPrivate { + PathListEditorPrivate(); + + QHBoxLayout *layout; + QVBoxLayout *buttonLayout; + QPlainTextEdit *edit; + QSignalMapper *envVarMapper; + QString fileDialogTitle; +}; + +PathListEditorPrivate::PathListEditorPrivate() : + layout(new QHBoxLayout), + buttonLayout(new QVBoxLayout), + edit(new PathListPlainTextEdit), + envVarMapper(0) +{ + layout->addWidget(edit); + layout->addLayout(buttonLayout); + buttonLayout->addItem(new QSpacerItem(0, 0, QSizePolicy::Ignored, QSizePolicy::MinimumExpanding)); +} + +PathListEditor::PathListEditor(QWidget *parent) : + QWidget(parent), + m_d(new PathListEditorPrivate) +{ + setLayout(m_d->layout); + addButton(tr("Add..."), this, SLOT(slotAdd())); + addButton(tr("Delete"), this, SLOT(deletePathAtCursor())); + addButton(tr("Clear"), this, SLOT(clear())); +} + +PathListEditor::~PathListEditor() +{ + delete m_d; +} + +QAbstractButton *PathListEditor::addButton(const QString &text, QObject * receiver, const char *slotFunc) +{ + // before Spacer item + return insertButton(m_d->buttonLayout->count() - 1, text, receiver, slotFunc); +} + +QAbstractButton *PathListEditor::insertButton(int index, const QString &text, QObject * receiver, const char *slotFunc) +{ +#ifdef Q_OS_MAC + typedef QPushButton Button; +#else + typedef QToolButton Button; +#endif + Button *rc = new Button; + rc->setText(text); + connect(rc, SIGNAL(clicked()), receiver, slotFunc); + m_d->buttonLayout->insertWidget(index, rc); + return rc; +} + +QString PathListEditor::pathListString() const +{ + return pathList().join(separator()); +} + +QStringList PathListEditor::pathList() const +{ + const QString text = m_d->edit->toPlainText().trimmed(); + if (text.isEmpty()) + return QStringList(); + // trim each line + QStringList rc = text.split(QLatin1Char('\n'), QString::SkipEmptyParts); + const QStringList::iterator end = rc.end(); + for (QStringList::iterator it = rc.begin(); it != end; ++it) + *it = it->trimmed(); + return rc; +} + +void PathListEditor::setPathList(const QStringList &l) +{ + m_d->edit->setPlainText(l.join(QString(QLatin1Char('\n')))); +} + +void PathListEditor::setPathList(const QString &pathString) +{ + if (pathString.isEmpty()) { + clear(); + } else { + setPathList(pathString.split(separator(), QString::SkipEmptyParts)); + } +} + +void PathListEditor::setPathListFromEnvVariable(const QString &var) +{ + setPathList(qgetenv(var.toLocal8Bit())); +} + +QString PathListEditor::fileDialogTitle() const +{ + return m_d->fileDialogTitle; +} + +void PathListEditor::setFileDialogTitle(const QString &l) +{ + m_d->fileDialogTitle = l; +} + +void PathListEditor::clear() +{ + m_d->edit->clear(); +} + +void PathListEditor::slotAdd() +{ + const QString dir = QFileDialog::getExistingDirectory(this, m_d->fileDialogTitle); + if (!dir.isEmpty()) + insertPathAtCursor(dir); +} + +QChar PathListEditor::separator() +{ +#ifdef Q_OS_WIN + static const QChar rc(QLatin1Char(';')); +#else + static const QChar rc(QLatin1Char(':')); +#endif + return rc; +} + +// Add a button "Import from 'Path'" +void PathListEditor::addEnvVariableImportButton(const QString &var) +{ + if (!m_d->envVarMapper) { + m_d->envVarMapper = new QSignalMapper(this); + connect(m_d->envVarMapper, SIGNAL(mapped(QString)), this, SLOT(setPathListFromEnvVariable(QString))); + } + + QAbstractButton *b = addButton(tr("From \"%1\"").arg(var), m_d->envVarMapper, SLOT(map())); + m_d->envVarMapper->setMapping(b, var); +} + +QString PathListEditor::text() const +{ + return m_d->edit->toPlainText(); +} + +void PathListEditor::setText(const QString &t) +{ + m_d->edit->setPlainText(t); +} + +void PathListEditor::insertPathAtCursor(const QString &path) +{ + // If the cursor is at an empty line or at end(), + // just insert. Else insert line before + QTextCursor cursor = m_d->edit->textCursor(); + QTextBlock block = cursor.block(); + const bool needNewLine = !block.text().isEmpty(); + if (needNewLine) { + cursor.movePosition(QTextCursor::StartOfLine, QTextCursor::MoveAnchor); + cursor.insertBlock(); + cursor.movePosition(QTextCursor::PreviousBlock, QTextCursor::MoveAnchor); + } + cursor.insertText(path); + if (needNewLine) { + cursor.movePosition(QTextCursor::StartOfLine, QTextCursor::MoveAnchor); + m_d->edit->setTextCursor(cursor); + } +} + +void PathListEditor::deletePathAtCursor() +{ + // Delete current line + QTextCursor cursor = m_d->edit->textCursor(); + if (cursor.block().isValid()) { + cursor.select(QTextCursor::BlockUnderCursor); + cursor.removeSelectedText(); + cursor.movePosition(QTextCursor::StartOfLine, QTextCursor::MoveAnchor); + m_d->edit->setTextCursor(cursor); + } +} + +} // namespace Utils +} // namespace Core diff --git a/src/libs/utils/pathlisteditor.h b/src/libs/utils/pathlisteditor.h new file mode 100644 index 00000000000..b97a616bef6 --- /dev/null +++ b/src/libs/utils/pathlisteditor.h @@ -0,0 +1,105 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Qt Software Information (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** +**************************************************************************/ + +#ifndef PATHLISTEDITOR_H +#define PATHLISTEDITOR_H + +#include "utils_global.h" + +#include <QtGui/QWidget> +#include <QtCore/QStringList> + +QT_BEGIN_NAMESPACE +class QAbstractButton; +QT_END_NAMESPACE + +namespace Core { +namespace Utils { + +struct PathListEditorPrivate; + +/** + * A control that let's the user edit a list of (directory) paths + * using the platform separator (';',':'). Typically used for + * path lists controlled by environment variables, such as + * PATH. It is based on a QPlainTextEdit as it should + * allow for convenient editing and non-directory type elements like + * "etc/mydir1:$SPECIAL_SYNTAX:/etc/mydir2". + * When pasting text into it, the platform separator will be replaced + * by new line characters for convenience. + */ + +class QWORKBENCH_UTILS_EXPORT PathListEditor : public QWidget +{ + Q_DISABLE_COPY(PathListEditor) + Q_OBJECT + Q_PROPERTY(QStringList pathList READ pathList WRITE setPathList DESIGNABLE true) + Q_PROPERTY(QString fileDialogTitle READ fileDialogTitle WRITE setFileDialogTitle DESIGNABLE true) + +public: + explicit PathListEditor(QWidget *parent = 0); + virtual ~PathListEditor(); + + QString pathListString() const; + QStringList pathList() const; + QString fileDialogTitle() const; + + static QChar separator(); + + // Add a convenience button "Import from 'Path'" (environment variable) + void addEnvVariableImportButton(const QString &var); + +public slots: + void clear(); + void setPathList(const QStringList &l); + void setPathList(const QString &pathString); + void setPathListFromEnvVariable(const QString &var); + void setFileDialogTitle(const QString &l); + +protected: + QAbstractButton *insertButton(int index /* -1 */, const QString &text, QObject * receiver, const char *slotFunc); + QAbstractButton *addButton(const QString &text, QObject * receiver, const char *slotFunc); + QString text() const; + void setText(const QString &); + +protected slots: + void insertPathAtCursor(const QString &); + void deletePathAtCursor(); + +private slots: + void slotAdd(); + +private: + PathListEditorPrivate *m_d; +}; + +} // namespace Utils +} // namespace Core + +#endif // PATHLISTEDITOR_H diff --git a/src/libs/utils/utils.pro b/src/libs/utils/utils.pro index 6502e40d035..85c98bf1ecd 100644 --- a/src/libs/utils/utils.pro +++ b/src/libs/utils/utils.pro @@ -11,6 +11,7 @@ SOURCES += \ settingsutils.cpp \ filesearch.cpp \ pathchooser.cpp \ + pathlisteditor.cpp \ filewizardpage.cpp \ filewizarddialog.cpp \ projectintropage.cpp \ @@ -45,6 +46,7 @@ HEADERS += \ filesearch.h \ listutils.h \ pathchooser.h \ + pathlisteditor.h \ filewizardpage.h \ filewizarddialog.h \ projectintropage.h \ diff --git a/src/tools/qtcreatorwidgets/customwidgets.cpp b/src/tools/qtcreatorwidgets/customwidgets.cpp index ce78a732999..d25e97587b9 100644 --- a/src/tools/qtcreatorwidgets/customwidgets.cpp +++ b/src/tools/qtcreatorwidgets/customwidgets.cpp @@ -154,6 +154,17 @@ SubmitFieldWidget_CW::SubmitFieldWidget_CW(QObject *parent) : { } +PathListEditor_CW::PathListEditor_CW(QObject *parent) : + QObject(parent), + CustomWidget<Core::Utils::PathListEditor> + (QLatin1String("<utils/pathlisteditor.h>"), + false, + QLatin1String(groupC), + QIcon(), + QLatin1String("Edit a path list variable")) +{ +} + // -------------- WidgetCollection WidgetCollection::WidgetCollection(QObject *parent) : QObject(parent) @@ -169,6 +180,7 @@ WidgetCollection::WidgetCollection(QObject *parent) : m_plugins.push_back(new QtColorButton_CW(this)); m_plugins.push_back(new SubmitEditorWidget_CW(this)); m_plugins.push_back(new SubmitFieldWidget_CW(this)); + m_plugins.push_back(new PathListEditor_CW(this)); } QList<QDesignerCustomWidgetInterface*> WidgetCollection::customWidgets() const diff --git a/src/tools/qtcreatorwidgets/customwidgets.h b/src/tools/qtcreatorwidgets/customwidgets.h index 7f9bd4efeb8..f11d5253860 100644 --- a/src/tools/qtcreatorwidgets/customwidgets.h +++ b/src/tools/qtcreatorwidgets/customwidgets.h @@ -42,6 +42,7 @@ #include <utils/qtcolorbutton.h> #include <utils/submiteditorwidget.h> #include <utils/submitfieldwidget.h> +#include <utils/pathlisteditor.h> #include <QtDesigner/QDesignerCustomWidgetCollectionInterface> @@ -152,6 +153,16 @@ public: explicit SubmitFieldWidget_CW(QObject *parent = 0); }; +class PathListEditor_CW : + public QObject, + public CustomWidget<Core::Utils::PathListEditor> +{ + Q_OBJECT + Q_INTERFACES(QDesignerCustomWidgetInterface) +public: + explicit PathListEditor_CW(QObject *parent = 0); +}; + // Collection class WidgetCollection : public QObject, public QDesignerCustomWidgetCollectionInterface diff --git a/src/tools/qtcreatorwidgets/qtcreatorwidgets.pro b/src/tools/qtcreatorwidgets/qtcreatorwidgets.pro index aa727f405a3..ad78021f036 100644 --- a/src/tools/qtcreatorwidgets/qtcreatorwidgets.pro +++ b/src/tools/qtcreatorwidgets/qtcreatorwidgets.pro @@ -14,7 +14,11 @@ linux-* { QTC_LIBS=$$dirname(PWD) QTC_LIBS=$$dirname(QTC_LIBS) QTC_LIBS=$$dirname(QTC_LIBS) - QTC_LIBS=$$QTC_LIBS/lib/qtcreator + linux-*64 { + QTC_LIBS=$$QTC_LIBS/lib64/qtcreator + } else { + QTC_LIBS=$$QTC_LIBS/lib/qtcreator + } QMAKE_RPATHDIR *= $$QTC_LIBS } -- GitLab