diff --git a/doc/addressbook-sdk.qdoc b/doc/addressbook-sdk.qdoc index 259512694f7b83e26c522db0d8ceaf82da459c89..f8fbc4c0fd580ddfd2ab7f62b514e3b76052d5ba 100644 --- a/doc/addressbook-sdk.qdoc +++ b/doc/addressbook-sdk.qdoc @@ -310,27 +310,17 @@ \snippet examples/addressbook-sdk/part2/addressbook.h slot definition - Next, we have to provide private members for the \c AddressBook class so - that we can access these widgets freely throughout the class. - - \snippet examples/addressbook-sdk/part2/addressbook.h members1 - - The Qt types used for our private members, e.g., QPushButton, QLineEdit, - QTextEdit, etc., need to be included with the \c include directive, as - shown below: + Since the \c AddressBook class is a subclass of QWidget, Qt Creator + includes QWidget in the hedaer file. \snippet examples/addressbook-sdk/part2/addressbook.h include - \note The names, e.g., \c addButton etc., correspond to the name of the - actual object. You can modify them by double-clicking on their names within - \QD's \gui{Object Inspector}. - We need a container to store our address book contacts, so that we can traverse and display them. A QMap object, \c contacts, is used for this purpose as it holds a key-value pair: the contact's name as the \e key, and the contact's address as the \e value. - \snippet examples/addressbook-sdk/part2/addressbook.h members2 + \snippet examples/addressbook-sdk/part2/addressbook.h members We also declare two private QString objects, \c oldName and \c oldAddress. These objects are needed to hold the name and address of hte contact that @@ -339,16 +329,15 @@ contact. Let's move on to implementing the slots we defined earlier. Within the - constructor of \c AddressBook, we extract the widgets from the form using - the \c ui object by pointing our private members to them. + constructor of \c AddressBook, we set up our fields by ensuring that + \c nameLine and \c addressText are read-only, so that we can only display + but not edit existing contact details. - \snippet examples/addressbook-sdk/part2/addressbook.cpp extract objects + \snippet examples/addressbook-sdk/part2/addressbook.cpp setup fields - Then we set \c nameLine and \c addressText to read-only, so that we can - only display but not edit existing contact details. We also hide - \c submitButton and \c cancelButton as they will only be be displayed - when the user clicks \gui Add, and this is handled by the \c addContact() - function discussed below. + We also hide both \c submitButton and \c cancelButton as they will only be + displayed when the user clicks \gui Add, and this is handled by the + \c addContact() function discussed below. \snippet examples/addressbook-sdk/part2/addressbook.cpp signal slot diff --git a/doc/examples/addressbook-sdk/part2/addressbook.cpp b/doc/examples/addressbook-sdk/part2/addressbook.cpp index 6c68e40d32cf2140cf0ab49c4e66b6e804645801..0e47c9002bd01ef7829084db226f908a91df9bc4 100644 --- a/doc/examples/addressbook-sdk/part2/addressbook.cpp +++ b/doc/examples/addressbook-sdk/part2/addressbook.cpp @@ -6,33 +6,19 @@ AddressBook::AddressBook(QWidget *parent) { ui->setupUi(this); - //! [extract objects] - nameLine = new QLineEdit; - nameLine = ui->nameLine; - nameLine->setReadOnly(true); - - addressText = new QTextEdit; - addressText = ui->addressText; - addressText->setReadOnly(true); - - addButton = new QPushButton; - addButton = ui->addButton; - - submitButton = new QPushButton; - submitButton = ui->submitButton; - submitButton->hide(); - - cancelButton = new QPushButton; - cancelButton = ui->cancelButton; - cancelButton->hide(); - //! [extract objects] + //! [setup fields] + ui->nameLine->setReadOnly(true); + ui->addressText->setReadOnly(true); + ui->submitButton->hide(); + ui->cancelButton->hide(); + //! [setup fields] //! [signal slot] - connect(addButton, SIGNAL(clicked()), this, + connect(ui->addButton, SIGNAL(clicked()), this, SLOT(addContact())); - connect(submitButton, SIGNAL(clicked()), this, + connect(ui->submitButton, SIGNAL(clicked()), this, SLOT(submitContact())); - connect(cancelButton, SIGNAL(clicked()), this, + connect(ui->cancelButton, SIGNAL(clicked()), this, SLOT(cancel())); //! [signal slot] @@ -49,27 +35,27 @@ AddressBook::~AddressBook() //! [addContact] void AddressBook::addContact() { - oldName = nameLine->text(); - oldAddress = addressText->toPlainText(); + oldName = ui->nameLine->text(); + oldAddress = ui->addressText->toPlainText(); - nameLine->clear(); - addressText->clear(); + ui->nameLine->clear(); + ui->addressText->clear(); - nameLine->setReadOnly(false); - nameLine->setFocus(Qt::OtherFocusReason); - addressText->setReadOnly(false); + ui->nameLine->setReadOnly(false); + ui->nameLine->setFocus(Qt::OtherFocusReason); + ui->addressText->setReadOnly(false); - addButton->setEnabled(false); - submitButton->show(); - cancelButton->show(); + ui->addButton->setEnabled(false); + ui->submitButton->show(); + ui->cancelButton->show(); } //! [addContact] //! [submitContact part1] void AddressBook::submitContact() { - QString name = nameLine->text(); - QString address = addressText->toPlainText(); + QString name = ui->nameLine->text(); + QString address = ui->addressText->toPlainText(); if (name == "" || address == "") { QMessageBox::information(this, tr("Empty Field"), @@ -93,29 +79,29 @@ void AddressBook::submitContact() //! [submitContact part3] if (contacts.isEmpty()) { - nameLine->clear(); - addressText->clear(); + ui->nameLine->clear(); + ui->addressText->clear(); } - nameLine->setReadOnly(true); - addressText->setReadOnly(true); - addButton->setEnabled(true); - submitButton->hide(); - cancelButton->hide(); + ui->nameLine->setReadOnly(true); + ui->addressText->setReadOnly(true); + ui->addButton->setEnabled(true); + ui->submitButton->hide(); + ui->cancelButton->hide(); } //! [submitContact part3] //! [cancel] void AddressBook::cancel() { - nameLine->setText(oldName); - nameLine->setReadOnly(true); + ui->nameLine->setText(oldName); + ui->nameLine->setReadOnly(true); - addressText->setText(oldAddress); - addressText->setReadOnly(true); + ui->addressText->setText(oldAddress); + ui->addressText->setReadOnly(true); - addButton->setEnabled(true); - submitButton->hide(); - cancelButton->hide(); + ui->addButton->setEnabled(true); + ui->submitButton->hide(); + ui->cancelButton->hide(); } //! [cancel] diff --git a/doc/examples/addressbook-sdk/part2/addressbook.h b/doc/examples/addressbook-sdk/part2/addressbook.h index 69486cb8cf2684d67472f98bc4fe7d1b0d3072ea..6bd342769071716b97da4ce29579ce10017eb67a 100644 --- a/doc/examples/addressbook-sdk/part2/addressbook.h +++ b/doc/examples/addressbook-sdk/part2/addressbook.h @@ -3,9 +3,7 @@ //! [include] #include <QtGui/QWidget> -#include <QtGui/QPushButton> -#include <QtGui/QLineEdit> -#include <QtGui/QTextEdit> +#include <QtCore/QMap> #include <QtGui/QMessageBox> //! [include] @@ -32,19 +30,11 @@ public slots: private: Ui::AddressBook *ui; -//! [members1] - QPushButton *addButton; - QPushButton *submitButton; - QPushButton *cancelButton; - QLineEdit *nameLine; - QTextEdit *addressText; -//! [members1] - -//! [members2] +//! [members] QMap<QString, QString> contacts; QString oldName; QString oldAddress; -//! [members2] +//! [members] }; #endif // ADDRESSBOOK_H diff --git a/examples/scripting/demo.js b/examples/scripting/demo.js deleted file mode 100644 index 6f134a05ab044bd67dfa450f663f1a28b81cefe3..0000000000000000000000000000000000000000 --- a/examples/scripting/demo.js +++ /dev/null @@ -1,375 +0,0 @@ -/************************************************************************** -** -** This file is part of Qt Creator -** -** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). -** -** Contact: Nokia Corporation (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 http://www.qtsoftware.com/contact. -** -**************************************************************************/ - -// This script file demos the scripting features -// of Qt Creator. -// Choose "Run" from the context menu. - -function introspect(o, indent) -{ - core.messageManager.printToOutputPane(indent + "+++++++++++++ Class " + o); - for (i in o) { - var member = o[i]; - var t = typeof member; - core.messageManager.printToOutputPane(indent + typeof o[i] + " " + i); - if (t == "object") - introspect(i, indent + " "); - } - -} - -function introspectToString(o) -{ - var rc = ""; - for (i in o) { - rc = rc + " " + typeof o[i] + " " + i; - } - return rc; -} - -function demoInputDialogs() -{ - var t = getText(core.mainWindow, "Input dialogs", "text", "default"); - if (t == null) - return; - - core.messageManager.printToOutputPane("Input :" +t); - var i = getInteger(core.mainWindow, "Input dialogs", "integer", 42, 0, 1000); - if (i == null) - return; - - core.messageManager.printToOutputPane("Input :" +i); - var d = getDouble(core.mainWindow, "Input dialogs", "double", 42.0, 0.0, 1000.0); - if (d == null) - return; - core.messageManager.printToOutputPane("Input :" +d); -} - -function demoFileDialogs() -{ - var f = getOpenFileName(core.mainWindow, "Choose file", "", "All files (*.*)"); - if (f == null) - return; - - core.messageManager.printToOutputPane("File:" + f); - - f = getOpenFileNames(core.mainWindow, "Choose files", "", "All files (*.*)"); - - if (f == null) - return; - - core.messageManager.printToOutputPane("Files:" + f); - - f = getSaveFileName(core.mainWindow, "Choose file to write to", "", "All files (*.*)"); - - if (f == null) - return; - - core.messageManager.printToOutputPane("File:" + f); - - f = getExistingDirectory(core.mainWindow, "Choose directory", ""); - - if (f == null) - return; - - core.messageManager.printToOutputPane("Directory:" + f); -} - - -function demoMessageBoxes() -{ - critical(core.mainWindow, "Critical", "critical"); - warning(core.mainWindow, "warning", "warning"); - information(core.mainWindow, "information", "information"); - var a = yesNoQuestion(core.mainWindow, "Question", "question"); - core.messageManager.printToOutputPane("Answer:" +a); -} - -function demoWizard() -{ - var filters = new Array("ProjectExplorer.WizardType.Project", "QtCreator::WizardType::File"); - core.showNewItemDialog(filters); -} - -function demoWidgets() -{ - core.mainWindow.windowTitle = "Accessing MainWindow"; - core.statusBar.showMessage("Accessing StatusBar", 0); -} - -function demoIntrospect() -{ - // Not perfect yet - introspect(core, ""); -} - -function demoFileManager() -{ - core.messageManager.printToOutputPane("Recent files:" + core.fileManager.recentFiles); - var name = getText(core.mainWindow, "Input file name", "name", ""); - - if (core.fileManager.isFileManaged(name) == 0) { - core.messageManager.printToOutputPane(name + " is not managed."); - return; - } - - var mf = core.fileManager.managedFiles(name); - var s = mf.length; - core.messageManager.printToOutputPane(s + " managed files match " + name); - for (var i = 0; i < mf.length; i++) { - core.messageManager.printToOutputPane(mf[i].fileName); - } -} - -function printEditor(e, indent) -{ - var m = indent + "Editor " + e.displayName + ", " + e.kind ; - var f = e.file; - m = m + " (" + f.fileName + ")"; - core.messageManager.printToOutputPane(m); -} - -function printEditorList(header, l, indent) -{ - core.messageManager.printToOutputPane(header + " (" + l.length + ")"); - for (var i = 0; i < l.length; i++) { - printEditor(l[i]," "); - } -} - -function printEditorGroup(g) -{ - var m = "Editor Group: " + g.editorCount + " editor(s)"; - core.messageManager.printToOutputPane(m); - printEditorList("Editors of the group", g.editors); - var ce = g.currentEditor; - if (ce == null) { - core.messageManager.printToOutputPane("No current editor in group"); - } else { - printEditor(ce, " "); - } -} - -function demoEditorManager() -{ - var og = core.editorManager.editorGroups; - core.messageManager.printToOutputPane("Editor groups " + og.length); - for (var i = 0; i < og.length; i++) { - printEditorGroup(og[i]); - } - - printEditorList("Opened editors", core.editorManager.openedEditors); - - var ce = core.editorManager.currentEditor; - if (ce == null) { - core.messageManager.printToOutputPane("No current editor"); - return; - } - - core.messageManager.printToOutputPane("Current editor"); - printEditor(ce, ""); - - var f = getOpenFileName(core.mainWindow, "Choose file to open", "", "All files (*.*)"); - if (f == null) - return; - - printEditor(core.editorManager.openEditor(f, ""), ""); -// printEditor(core.editorManager.newFile("Text", "title", "contents")); -// var dup = ce.duplicate(core.mainWindow); -} - -function demoDebugger() -{ - var state = gdbdebugger.status; - core.messageManager.printToOutputPane("State " + state); - // TODO: Start debugger on demand? - if (state != 0) - gdbdebugger.sendCommand("help"); -} - -// -- ProjectExplorer -function printProjectItem(pi, indent, recursively) -{ - var m = indent + "ProjectItem " + pi.kind + " " + pi.name; - core.messageManager.printToOutputPane(m); - if (recursively != 0) { - var rIndent = indent + " "; - var c = projectExplorer.childrenOf(pi); - for (var i = 0; i < c.length; i++) { - printProjectItem(c[i], rIndent, 1); - } - } -} - -function printSession(s, indent) -{ - core.messageManager.printToOutputPane(indent + "Session " + s.name + " startup project " + s.startupProject); - var p = s.projects; - var pIndent = indent + " "; - for (var i = 0; i < p.length; i++) { - printProjectItem(p[i], pIndent, 1); - } -} - -function demoProjectExplorer() -{ - core.messageManager.printToOutputPane("ProjectExplorer"); - projectExplorer.buildManager.showOutputWindow(1); - projectExplorer.buildManager.addMessage("Build manager message"); - projectExplorer.applicationOutputWindow.clear(); - projectExplorer.applicationOutputWindow.appendOutput("Hi, there! .. This the projectExplorer demo"); - - var ci = projectExplorer.currentItem; - if (ci != null) { - core.messageManager.printToOutputPane("Current Item"); - printProjectItem(ci, " ", 0); - } else { - core.messageManager.printToOutputPane("No current Item"); - } - var cp = projectExplorer.currentProject; - if (cp != null) { - core.messageManager.printToOutputPane("Current Project"); - printProjectItem(cp, " ", 0); - } else { - core.messageManager.printToOutputPane("No current Project"); - } - - var cs = projectExplorer.session; - if (cs != null) { - core.messageManager.printToOutputPane("Current Session"); - printSession(cs, " "); - // Ask to build - var p = projectExplorer.needsBuild(cs.projects[0]); - for (var i = 0; i < p.length; i++) { - if (yesNoQuestion(core.mainWindow, "Rebuild", "Do you want to rebuild " + p[i].name + "?") != 65536) { - if (p[i].supportsProjectCommand(2)) { - p[i].executeProjectCommand(2); - } else { - core.messageManager.printToOutputPane("Build not supported."); - } - } - } - } else { - core.messageManager.printToOutputPane("No current Session"); - var a = yesNoQuestion(core.mainWindow, "Open Session", "Do you want to open a session?"); - if (a != 65536) { - var f = getOpenFileNames(core.mainWindow, "Choose a session", "", "All projects (*.qws *.pro)"); - if (f == null) - return; - var o = projectExplorer.openProject(f); - return; - } - } - if (yesNoQuestion(core.mainWindow, "Build manager", "Do you want run a command using build mananger?") != 65536) { - var cmd = new BuildManagerCommand("ls", "-l"); - var cmds =new Array(cmd); - core.messageManager.printToOutputPane("Let build mananger run a command " + cmds + " (see compile window)"); - projectExplorer.buildManager.start(cmds); - } -} - -// --------------- MAIN - -var features = new Array("Input dialogs", - "File dialogs", - "Messages", - "Project Explorer", - "Message Manager", - "Wizard", - "Editor manager", - "File manager", - "Introspect", - "Widgets magic", - "Debugger"); - -core.messageManager.printToOutputPane(" +++ demo.js " + Date()); - -while (1) { - var f = getItem(core.mainWindow, "Choose a demo", "Available demos", features, 0); - if (f == null) - return; - - while (1) { - if (f == features[0]) { - demoInputDialogs(); - break; - } - - if (f == features[1]) { - demoFileDialogs(); - break; - } - - if (f == features[2]) { - demoMessageBoxes(); - break; - } - - if (f == features[3]) { - demoProjectExplorer(); - break; - } - - if (f == features[4]) { - core.messageManager.printToOutputPane("Hi there!",1); - break; - } - - if (f == features[5]) { - demoWizard(); - break; - } - - if (f == features[6]) { - demoEditorManager(); - break; - } - - if (f == features[7]) { - demoFileManager(); - break; - } - - if (f == features[8]) { - demoIntrospect(); - break; - } - - if (f == features[9]) { - demoWidgets(); - break; - } - - if (f == features[10]) { - demoDebugger(); - break; - } - break; - } -} diff --git a/src/libs/cplusplus/cplusplus.pri b/src/libs/cplusplus/cplusplus.pri index 0b8fac85fe36a47a6a33a0c819e00548a13a984f..7554994991b3acd9972271d7722743d2094c3726 100644 --- a/src/libs/cplusplus/cplusplus.pri +++ b/src/libs/cplusplus/cplusplus.pri @@ -1,2 +1,3 @@ INCLUDEPATH += $$PWD/../../shared/cplusplus +DEPENDPATH += $$PWD/../../shared/cplusplus LIBS *= -l$$qtLibraryTarget(CPlusPlus) diff --git a/src/libs/extensionsystem/extensionsystem.pro b/src/libs/extensionsystem/extensionsystem.pro index bdaffbe0f4a0c34dadc56f56a4aa42586bb1326e..81f3bc8fc79284e905bd1ff1171ad66fc82d007a 100644 --- a/src/libs/extensionsystem/extensionsystem.pro +++ b/src/libs/extensionsystem/extensionsystem.pro @@ -1,6 +1,5 @@ TEMPLATE = lib TARGET = ExtensionSystem -QT += xml DEFINES += EXTENSIONSYSTEM_LIBRARY include(../../qtcreatorlibrary.pri) include(extensionsystem_dependencies.pri) diff --git a/src/libs/utils/styledbar.cpp b/src/libs/utils/styledbar.cpp index 39326a17cbf69be6402017b61f3bf38d8424b4bf..8911af6d6fe49214c4066131b8b4f5e0c186652b 100644 --- a/src/libs/utils/styledbar.cpp +++ b/src/libs/utils/styledbar.cpp @@ -5,6 +5,8 @@ #include <QtCore/QVariant> #include <QtGui/QPainter> #include <QtGui/QPixmapCache> +#include <QtGui/QStyle> +#include <QtGui/QStyleOption> using namespace Core::Utils; @@ -12,54 +14,42 @@ StyledBar::StyledBar(QWidget *parent) : QWidget(parent) { setProperty("panelwidget", true); + setProperty("panelwidget_singlerow", true); +} + +void StyledBar::setSingleRow(bool singleRow) +{ + setProperty("panelwidget_singlerow", singleRow); +} + +bool StyledBar::isSingleRow() const +{ + return property("panelwidget_singlerow").toBool(); } void StyledBar::paintEvent(QPaintEvent *event) { - // Currently from the style - // Goal should be to migrate that into a Utils::StyledWidget class Q_UNUSED(event) QPainter painter(this); + QStyleOption option; + option.rect = rect(); + option.state = QStyle::State_Horizontal; + style()->drawControl(QStyle::CE_ToolBar, &option, &painter, this); +} - QRect selfRect = rect(); - QString key; - key.sprintf("mh_toolbar %d %d %d", selfRect.width(), selfRect.height(), StyleHelper::baseColor().rgb());; - - QPixmap pixmap; - QPainter *p = &painter; - if (StyleHelper::usePixmapCache() && !QPixmapCache::find(key, pixmap)) { - pixmap = QPixmap(selfRect.size()); - p = new QPainter(&pixmap); - selfRect = QRect(0, 0, selfRect.width(), selfRect.height()); - } - - // Map offset for global window gradient - QPoint offset = window()->mapToGlobal(selfRect.topLeft()) - - mapToGlobal(selfRect.topLeft()); - QRect gradientSpan; - gradientSpan = QRect(offset, window()->size()); - StyleHelper::horizontalGradient(p, gradientSpan, selfRect); - - p->setPen(StyleHelper::borderColor()); - - // Note: This is a hack to determine if the - // toolbar should draw the top or bottom outline - // (needed for the find toolbar for instance) - QColor lighter(255, 255, 255, 40); - if (property("topBorder").toBool()) { - p->drawLine(selfRect.topLeft(), selfRect.topRight()); - p->setPen(lighter); - p->drawLine(selfRect.topLeft() + QPoint(0, 1), selfRect.topRight() + QPoint(0, 1)); - } else { - p->drawLine(selfRect.bottomLeft(), selfRect.bottomRight()); - p->setPen(lighter); - p->drawLine(selfRect.topLeft(), selfRect.topRight()); - } +StyledSeparator::StyledSeparator(QWidget *parent) + : QWidget(parent) +{ + setFixedWidth(10); +} - if (StyleHelper::usePixmapCache() && !QPixmapCache::find(key, pixmap)) { - painter.drawPixmap(selfRect.topLeft(), pixmap); - p->end(); - delete p; - QPixmapCache::insert(key, pixmap); - } +void StyledSeparator::paintEvent(QPaintEvent *event) +{ + Q_UNUSED(event) + QPainter painter(this); + QStyleOption option; + option.rect = rect(); + option.state = QStyle::State_Horizontal; + option.palette = palette(); + style()->drawPrimitive(QStyle::PE_IndicatorToolBarSeparator, &option, &painter, this); } diff --git a/src/libs/utils/styledbar.h b/src/libs/utils/styledbar.h index 6b93ffe5568a7c29cc10dc5170695900d2e2b525..2e8964b8f2f1159d67ce73a880b7636ad4823173 100644 --- a/src/libs/utils/styledbar.h +++ b/src/libs/utils/styledbar.h @@ -12,7 +12,16 @@ class QTCREATOR_UTILS_EXPORT StyledBar : public QWidget { public: StyledBar(QWidget *parent = 0); + void setSingleRow(bool singleRow); + bool isSingleRow() const; +protected: + void paintEvent(QPaintEvent *event); +}; +class QTCREATOR_UTILS_EXPORT StyledSeparator : public QWidget +{ +public: + StyledSeparator(QWidget *parent = 0); protected: void paintEvent(QPaintEvent *event); }; diff --git a/src/plugins/bineditor/bineditorplugin.cpp b/src/plugins/bineditor/bineditorplugin.cpp index c0a17eb94349c75e7ea71da1f5ddc121cb95336f..4f854b713815ba1fd48acd1f7b55b1c5c3377b94 100644 --- a/src/plugins/bineditor/bineditorplugin.cpp +++ b/src/plugins/bineditor/bineditorplugin.cpp @@ -37,6 +37,7 @@ #include <QtGui/QAction> #include <QtGui/QMainWindow> #include <QtGui/QHBoxLayout> +#include <QtGui/QToolBar> #include <coreplugin/actionmanager/actionmanager.h> #include <coreplugin/coreconstants.h> @@ -287,7 +288,7 @@ public: QByteArray saveState() const { return QByteArray(); } // TODO bool restoreState(const QByteArray & /* state */) { return false; } // TODO - QToolBar *toolBar() { return m_toolBar; } + QWidget *toolBar() { return m_toolBar; } bool isTemporary() const { return false; } diff --git a/src/plugins/coreplugin/actionmanager/actioncontainer.cpp b/src/plugins/coreplugin/actionmanager/actioncontainer.cpp index e6760f4b240c54c7e7d2526acbeb80a2bb076f82..eab8a818483d81aafb22bb66ae0659417736279b 100644 --- a/src/plugins/coreplugin/actionmanager/actioncontainer.cpp +++ b/src/plugins/coreplugin/actionmanager/actioncontainer.cpp @@ -37,7 +37,6 @@ #include <QtCore/QDebug> #include <QtGui/QAction> -#include <QtGui/QToolBar> #include <QtGui/QMenuBar> Q_DECLARE_METATYPE(Core::Internal::MenuActionContainer*) diff --git a/src/plugins/coreplugin/actionmanager/actioncontainer.h b/src/plugins/coreplugin/actionmanager/actioncontainer.h index 7539b91ee0cdb4b2bda8846f0b987ad835ef47b6..050e3ee3d62662b4c77d3c58ceb561f5c3aab484 100644 --- a/src/plugins/coreplugin/actionmanager/actioncontainer.h +++ b/src/plugins/coreplugin/actionmanager/actioncontainer.h @@ -32,7 +32,6 @@ #include <QtCore/QObject> #include <QtGui/QMenu> -#include <QtGui/QToolBar> #include <QtGui/QMenuBar> #include <QtGui/QAction> diff --git a/src/plugins/coreplugin/editormanager/editorview.cpp b/src/plugins/coreplugin/editormanager/editorview.cpp index b98b7a15e870df7a26f9e0ae5df61152e1bb3291..4d952fd18e4ad15bd005f238c9e799a225b4222c 100644 --- a/src/plugins/coreplugin/editormanager/editorview.cpp +++ b/src/plugins/coreplugin/editormanager/editorview.cpp @@ -34,6 +34,7 @@ #include "openeditorsmodel.h" #include <utils/qtcassert.h> +#include <utils/styledbar.h> #include <QtCore/QDebug> #include <QtCore/QDir> @@ -49,7 +50,6 @@ #include <QtGui/QStackedWidget> #include <QtGui/QStyle> #include <QtGui/QStyleOption> -#include <QtGui/QToolBar> #include <QtGui/QToolButton> #include <QtGui/QMenu> #include <QtGui/QClipboard> @@ -74,7 +74,7 @@ EditorView::EditorView(OpenEditorsModel *model, QWidget *parent) : m_editorList(new QComboBox), m_closeButton(new QToolButton), m_lockButton(new QToolButton), - m_defaultToolBar(new QToolBar(this)), + m_defaultToolBar(new QWidget(this)), m_infoWidget(new QFrame(this)), m_editorForInfoWidget(0), m_statusHLine(new QFrame(this)), @@ -94,12 +94,7 @@ EditorView::EditorView(OpenEditorsModel *model, QWidget *parent) : m_editorList->setMaxVisibleItems(40); m_editorList->setContextMenuPolicy(Qt::CustomContextMenu); - QToolBar *editorListToolBar = new QToolBar; - - editorListToolBar->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Ignored); - editorListToolBar->addWidget(m_editorList); - - m_defaultToolBar->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); + m_defaultToolBar->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); m_activeToolBar = m_defaultToolBar; QHBoxLayout *toolBarLayout = new QHBoxLayout; @@ -107,31 +102,23 @@ EditorView::EditorView(OpenEditorsModel *model, QWidget *parent) : toolBarLayout->setSpacing(0); toolBarLayout->addWidget(m_defaultToolBar); m_toolBar->setLayout(toolBarLayout); + m_toolBar->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); m_lockButton->setAutoRaise(true); - m_lockButton->setProperty("type", QLatin1String("dockbutton")); m_closeButton->setAutoRaise(true); m_closeButton->setIcon(QIcon(":/core/images/closebutton.png")); - m_closeButton->setProperty("type", QLatin1String("dockbutton")); - - QToolBar *rightToolBar = new QToolBar; - rightToolBar->setLayoutDirection(Qt::RightToLeft); - rightToolBar->addWidget(m_closeButton); - rightToolBar->addWidget(m_lockButton); QHBoxLayout *toplayout = new QHBoxLayout; toplayout->setSpacing(0); toplayout->setMargin(0); - toplayout->addWidget(editorListToolBar); + toplayout->addWidget(m_editorList); toplayout->addWidget(m_toolBar, 1); // Custom toolbar stretches - toplayout->addWidget(rightToolBar); + toplayout->addWidget(m_lockButton); + toplayout->addWidget(m_closeButton); - QWidget *top = new QWidget; - QVBoxLayout *vlayout = new QVBoxLayout(top); - vlayout->setSpacing(0); - vlayout->setMargin(0); - vlayout->addLayout(toplayout); + Core::Utils::StyledBar *top = new Core::Utils::StyledBar; + top->setLayout(toplayout); tl->addWidget(top); connect(m_editorList, SIGNAL(activated(int)), this, SLOT(listSelectionActivated(int))); @@ -258,7 +245,7 @@ void EditorView::addEditor(IEditor *editor) m_container->addWidget(editor->widget()); m_widgetEditorMap.insert(editor->widget(), editor); - QToolBar *toolBar = editor->toolBar(); + QWidget *toolBar = editor->toolBar(); if (toolBar) { toolBar->setVisible(false); // will be made visible in setCurrentEditor m_toolBar->layout()->addWidget(toolBar); @@ -297,7 +284,7 @@ void EditorView::removeEditor(IEditor *editor) m_widgetEditorMap.remove(editor->widget()); editor->widget()->setParent(0); disconnect(editor, SIGNAL(changed()), this, SLOT(checkEditorStatus())); - QToolBar *toolBar = editor->toolBar(); + QWidget *toolBar = editor->toolBar(); if (toolBar != 0) { if (m_activeToolBar == toolBar) { m_activeToolBar = m_defaultToolBar; @@ -375,7 +362,7 @@ void EditorView::updateEditorStatus(IEditor *editor) void EditorView::updateToolBar(IEditor *editor) { - QToolBar *toolBar = editor->toolBar(); + QWidget *toolBar = editor->toolBar(); if (!toolBar) toolBar = m_defaultToolBar; if (m_activeToolBar == toolBar) diff --git a/src/plugins/coreplugin/editormanager/editorview.h b/src/plugins/coreplugin/editormanager/editorview.h index 6315a810215593d4e1eb187292879c6562a79b72..996ec8df944346c4584d9f3d9bda798e7a2da944 100644 --- a/src/plugins/coreplugin/editormanager/editorview.h +++ b/src/plugins/coreplugin/editormanager/editorview.h @@ -46,7 +46,6 @@ QT_BEGIN_NAMESPACE class QComboBox; -class QToolBar; class QToolButton; class QLabel; class QStackedWidget; @@ -105,12 +104,12 @@ private: OpenEditorsModel *m_model; QWidget *m_toolBar; - QToolBar *m_activeToolBar; + QWidget *m_activeToolBar; QStackedWidget *m_container; QComboBox *m_editorList; QToolButton *m_closeButton; QToolButton *m_lockButton; - QToolBar *m_defaultToolBar; + QWidget *m_defaultToolBar; QString m_infoWidgetKind; QFrame *m_infoWidget; QLabel *m_infoWidgetLabel; diff --git a/src/plugins/coreplugin/editormanager/ieditor.h b/src/plugins/coreplugin/editormanager/ieditor.h index befd67445a6f13341a4c7dbaead65bc335b158ab..23f2e6535c9805d1c04d7466c519da9f4dd49982 100644 --- a/src/plugins/coreplugin/editormanager/ieditor.h +++ b/src/plugins/coreplugin/editormanager/ieditor.h @@ -34,10 +34,6 @@ #include <coreplugin/icontext.h> #include <coreplugin/ifile.h> -QT_BEGIN_NAMESPACE -class QToolBar; -QT_END_NAMESPACE - namespace Core { class CORE_EXPORT IEditor : public IContext @@ -65,7 +61,7 @@ public: virtual bool isTemporary() const = 0; - virtual QToolBar *toolBar() = 0; + virtual QWidget *toolBar() = 0; signals: void changed(); diff --git a/src/plugins/coreplugin/editormanager/openeditorsview.ui b/src/plugins/coreplugin/editormanager/openeditorsview.ui index 00962bcbec6e247538dbfdf13e21b0faa8362100..a94a803135d10b9d925cd8f24d003ea34e29f2ca 100644 --- a/src/plugins/coreplugin/editormanager/openeditorsview.ui +++ b/src/plugins/coreplugin/editormanager/openeditorsview.ui @@ -1,7 +1,8 @@ -<ui version="4.0" > +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> <class>OpenEditorsView</class> - <widget class="QWidget" name="OpenEditorsView" > - <property name="geometry" > + <widget class="QWidget" name="OpenEditorsView"> + <property name="geometry"> <rect> <x>0</x> <y>0</y> @@ -9,22 +10,16 @@ <height>217</height> </rect> </property> - <property name="minimumSize" > - <size> - <width>200</width> - <height>100</height> - </size> - </property> - <layout class="QGridLayout" > - <property name="margin" > + <layout class="QGridLayout"> + <property name="margin"> <number>0</number> </property> - <property name="spacing" > + <property name="spacing"> <number>0</number> </property> - <item row="0" column="0" > - <widget class="QTreeView" name="editorList" > - <property name="uniformRowHeights" > + <item row="0" column="0"> + <widget class="QTreeView" name="editorList"> + <property name="uniformRowHeights"> <bool>true</bool> </property> </widget> diff --git a/src/plugins/coreplugin/fancytabwidget.cpp b/src/plugins/coreplugin/fancytabwidget.cpp index 1767b88febf5553362c36c7a1e1256a67a241301..403644f9a4c2fe7f0f5f7111e0c7873116b2ba2a 100644 --- a/src/plugins/coreplugin/fancytabwidget.cpp +++ b/src/plugins/coreplugin/fancytabwidget.cpp @@ -29,6 +29,7 @@ #include "fancytabwidget.h" #include <utils/stylehelper.h> +#include <utils/styledbar.h> #include <QDebug> @@ -41,7 +42,6 @@ #include <QtGui/QSplitter> #include <QtGui/QStackedLayout> #include <QtGui/QStatusBar> -#include <QtGui/QToolBar> #include <QtGui/QToolButton> #include <QtGui/QToolTip> @@ -298,9 +298,11 @@ FancyTabWidget::FancyTabWidget(QWidget *parent) selectionLayout->setSpacing(0); selectionLayout->setMargin(0); - QToolBar *bar = new QToolBar; - bar->addWidget(new FancyColorButton(this)); - bar->setFixedHeight(StyleHelper::navigationWidgetHeight()); + Core::Utils::StyledBar *bar = new Core::Utils::StyledBar; + QHBoxLayout *layout = new QHBoxLayout(bar); + layout->setMargin(0); + layout->setSpacing(0); + layout->addWidget(new FancyColorButton(this)); selectionLayout->addWidget(bar); selectionLayout->addWidget(m_tabBar, 1); @@ -329,12 +331,12 @@ FancyTabWidget::FancyTabWidget(QWidget *parent) vlayout->addLayout(m_modesStack); vlayout->addWidget(m_statusBar); - QHBoxLayout *layout = new QHBoxLayout; - layout->setMargin(0); - layout->setSpacing(1); - layout->addWidget(m_selectionWidget); - layout->addLayout(vlayout); - setLayout(layout); + QHBoxLayout *mainLayout = new QHBoxLayout; + mainLayout->setMargin(0); + mainLayout->setSpacing(1); + mainLayout->addWidget(m_selectionWidget); + mainLayout->addLayout(vlayout); + setLayout(mainLayout); connect(m_tabBar, SIGNAL(currentChanged(int)), this, SLOT(showWidget(int))); } diff --git a/src/plugins/coreplugin/mainwindow.cpp b/src/plugins/coreplugin/mainwindow.cpp index e84147941095c9e97b239856d81b2458a33376ec..0dc130d845e0820f341fdd796510864db67bbcaf 100644 --- a/src/plugins/coreplugin/mainwindow.cpp +++ b/src/plugins/coreplugin/mainwindow.cpp @@ -84,7 +84,6 @@ #include <QtGui/QPrinter> #include <QtGui/QShortcut> #include <QtGui/QStatusBar> -#include <QtGui/QToolBar> #include <QtGui/QWizard> /* @@ -197,7 +196,6 @@ MainWindow::MainWindow() : connect(QApplication::instance(), SIGNAL(focusChanged(QWidget*,QWidget*)), this, SLOT(updateFocusWidget(QWidget*,QWidget*))); // Add a small Toolbutton for toggling the navigation widget - m_toggleSideBarButton->setProperty("type", QLatin1String("dockbutton")); statusBar()->insertPermanentWidget(0, m_toggleSideBarButton); // setUnifiedTitleAndToolBarOnMac(true); diff --git a/src/plugins/coreplugin/manhattanstyle.cpp b/src/plugins/coreplugin/manhattanstyle.cpp index fda4e51bab2076815d8feef09e7efef42ffb4b9b..cbff6256393a7eee6ef59f766f336816de872343 100644 --- a/src/plugins/coreplugin/manhattanstyle.cpp +++ b/src/plugins/coreplugin/manhattanstyle.cpp @@ -31,7 +31,6 @@ #include "styleanimator.h" -#include <QtCore/QDebug> #include <QtCore/QLibrary> #include <utils/qtcassert.h> @@ -100,8 +99,6 @@ public: { style = QStyleFactory::create(baseStyleName); QTC_ASSERT(style, /**/); - buttonImage_pressed = QImage(":/core/images/pushbutton_pressed.png"); - buttonImage = QImage(":/core/images/pushbutton.png"); lineeditImage = QImage(":/core/images/inputfield.png"); lineeditImage_disabled = QImage(":/core/images/inputfield_disabled.png"); @@ -117,8 +114,6 @@ public: public: QStyle *style; - QImage buttonImage; - QImage buttonImage_pressed; QImage lineeditImage; QImage lineeditImage_disabled; @@ -314,10 +309,10 @@ void ManhattanStyle::polish(QWidget *widget) widget->removeEventFilter(d->style); } if (panelWidget(widget)) { + widget->setAttribute(Qt::WA_LayoutUsesWidgetRect, true); if (qobject_cast<QToolButton*>(widget)) { widget->setAttribute(Qt::WA_Hover); widget->setMaximumHeight(StyleHelper::navigationWidgetHeight() - 2); - widget->setAttribute(Qt::WA_Hover); } else if (qobject_cast<QLineEdit*>(widget)) { widget->setAttribute(Qt::WA_Hover); @@ -325,8 +320,8 @@ void ManhattanStyle::polish(QWidget *widget) } else if (qobject_cast<QLabel*>(widget)) widget->setPalette(panelPalette(widget->palette())); - else if (qobject_cast<QToolBar*>(widget)) - widget->setMinimumHeight(StyleHelper::navigationWidgetHeight()); + else if (qobject_cast<QToolBar*>(widget) || widget->property("panelwidget_singlerow").toBool()) + widget->setFixedHeight(StyleHelper::navigationWidgetHeight()); else if (qobject_cast<QStatusBar*>(widget)) widget->setFixedHeight(StyleHelper::navigationWidgetHeight() + 2); else if (qobject_cast<QComboBox*>(widget)) { @@ -340,6 +335,7 @@ void ManhattanStyle::unpolish(QWidget *widget) { d->style->unpolish(widget); if (panelWidget(widget)) { + widget->setAttribute(Qt::WA_LayoutUsesWidgetRect, false); if (qobject_cast<QTabBar*>(widget)) widget->setAttribute(Qt::WA_Hover, false); else if (qobject_cast<QToolBar*>(widget)) @@ -906,7 +902,6 @@ void ManhattanStyle::drawComplexControl(ComplexControl control, const QStyleOpti switch (control) { case CC_ToolButton: if (const QStyleOptionToolButton *toolbutton = qstyleoption_cast<const QStyleOptionToolButton *>(option)) { - QString buttonType = widget->property("type").toString(); QRect button, menuarea; button = subControlRect(control, toolbutton, SC_ToolButton, widget); menuarea = subControlRect(control, toolbutton, SC_ToolButtonMenu, widget); @@ -929,24 +924,9 @@ void ManhattanStyle::drawComplexControl(ComplexControl control, const QStyleOpti QStyleOption tool(0); tool.palette = toolbutton->palette; if (toolbutton->subControls & SC_ToolButton) { - if (buttonType == "dockbutton") { - tool.rect = button; - tool.state = bflags; - drawPrimitive(PE_PanelButtonTool, &tool, painter, widget); - } else { // paint status bar button style - if (bflags & State_Sunken || bflags & State_On) - drawCornerImage(d->buttonImage_pressed, painter, option->rect, 2, 2, 2, 2); - else if (bflags & State_Enabled) { -#ifndef Q_WS_MAC - if (bflags & State_MouseOver) { - drawCornerImage(d->buttonImage, painter, option->rect, 2, 2, 2, 2); - QColor shade(255, 255, 255, 50); - painter->fillRect(button.adjusted(1, 1, -1, -1), shade); - } -#endif - } - - } + tool.rect = button; + tool.state = bflags; + drawPrimitive(PE_PanelButtonTool, &tool, painter, widget); } if (toolbutton->state & State_HasFocus) { diff --git a/src/plugins/coreplugin/navigationwidget.cpp b/src/plugins/coreplugin/navigationwidget.cpp index 5f2231f627bde6970f61abe3174b3cce28a566d0..44cf905b35708d0d9049b7d2daf5019ea839f4e7 100644 --- a/src/plugins/coreplugin/navigationwidget.cpp +++ b/src/plugins/coreplugin/navigationwidget.cpp @@ -44,7 +44,6 @@ #include <QtGui/QAction> #include <QtGui/QHBoxLayout> #include <QtGui/QResizeEvent> -#include <QtGui/QToolBar> #include <QtGui/QToolButton> Q_DECLARE_METATYPE(Core::INavigationWidgetFactory *) @@ -363,27 +362,26 @@ NavigationSubWidget::NavigationSubWidget(NavigationWidget *parentWidget) this, SLOT(aboutToRemoveObject(QObject*))); m_navigationComboBox = new NavComboBox(this); + m_navigationComboBox->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored); + m_navigationComboBox->setMinimumContentsLength(0); m_navigationWidget = 0; -#ifdef Q_WS_MAC - // this is to avoid ugly tool bar behavior - m_navigationComboBox->setMaximumWidth(130); -#endif - m_toolBar = new QToolBar(this); - m_toolBar->setContentsMargins(0, 0, 0, 0); - m_toolBar->addWidget(m_navigationComboBox); + m_toolBar = new Core::Utils::StyledBar(this); + QHBoxLayout *toolBarLayout = new QHBoxLayout; + toolBarLayout->setMargin(0); + toolBarLayout->setSpacing(0); + m_toolBar->setLayout(toolBarLayout); + toolBarLayout->addWidget(m_navigationComboBox); - m_splitAction = new QAction(QIcon(":/core/images/splitbutton_horizontal.png"), tr("Split"), this); - QAction *close = new QAction(QIcon(":/core/images/closebutton.png"), tr("Close"), this); + QToolButton *splitAction = new QToolButton(); + splitAction->setIcon(QIcon(":/core/images/splitbutton_horizontal.png")); + splitAction->setToolTip(tr("Split")); + QToolButton *close = new QToolButton(); + close->setIcon(QIcon(":/core/images/closebutton.png")); + close->setToolTip(tr("Close")); - QWidget *spacerItem = new QWidget(this); - spacerItem->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum); - m_toolBar->addWidget(spacerItem); - m_toolBar->addAction(m_splitAction); - m_toolBar->addAction(close); - - m_toolBar->widgetForAction(m_splitAction)->setProperty("type", QLatin1String("dockbutton")); - m_toolBar->widgetForAction(close)->setProperty("type", QLatin1String("dockbutton")); + toolBarLayout->addWidget(splitAction); + toolBarLayout->addWidget(close); QVBoxLayout *lay = new QVBoxLayout(); lay->setMargin(0); @@ -391,8 +389,8 @@ NavigationSubWidget::NavigationSubWidget(NavigationWidget *parentWidget) setLayout(lay); lay->addWidget(m_toolBar); - connect(m_splitAction, SIGNAL(triggered()), this, SIGNAL(split())); - connect(close, SIGNAL(triggered()), this, SIGNAL(close())); + connect(splitAction, SIGNAL(clicked()), this, SIGNAL(split())); + connect(close, SIGNAL(clicked()), this, SIGNAL(close())); connect(m_navigationComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(setCurrentIndex(int))); @@ -426,8 +424,9 @@ void NavigationSubWidget::setCurrentIndex(int index) // Add Toolbutton m_additionalToolBarWidgets = n.doockToolBarWidgets; + QHBoxLayout *layout = qobject_cast<QHBoxLayout *>(m_toolBar->layout()); foreach (QToolButton *w, m_additionalToolBarWidgets) { - m_toolBar->insertWidget(m_splitAction, w); + layout->insertWidget(layout->count()-2, w); } } diff --git a/src/plugins/coreplugin/navigationwidget.h b/src/plugins/coreplugin/navigationwidget.h index aaa287882479f4251a2db226c46996f1aaaa0077..47c0a3e1fafd6675f97f89f1293aab97701e5fc3 100644 --- a/src/plugins/coreplugin/navigationwidget.h +++ b/src/plugins/coreplugin/navigationwidget.h @@ -30,12 +30,13 @@ #ifndef NAVIGATIONWIDGET_H #define NAVIGATIONWIDGET_H +#include <coreplugin/minisplitter.h> +#include <utils/styledbar.h> + #include <QtGui/QWidget> #include <QtGui/QComboBox> #include <QtGui/QSplitter> -#include <QtGui/QToolBar> #include <QtGui/QToolButton> -#include <coreplugin/minisplitter.h> QT_BEGIN_NAMESPACE class QSettings; @@ -147,8 +148,7 @@ private: NavigationWidget *m_parentWidget; QComboBox *m_navigationComboBox; QWidget *m_navigationWidget; - QToolBar *m_toolBar; - QAction *m_splitAction; + Core::Utils::StyledBar *m_toolBar; QList<QToolButton *> m_additionalToolBarWidgets; }; diff --git a/src/plugins/coreplugin/outputpane.cpp b/src/plugins/coreplugin/outputpane.cpp index ea1ad6a9c0fd8cb0954160aa2ec123f22b959557..7033ffd6857be7852cb5bf1fe0f4b6fc79cc05a7 100644 --- a/src/plugins/coreplugin/outputpane.cpp +++ b/src/plugins/coreplugin/outputpane.cpp @@ -40,6 +40,8 @@ #include <extensionsystem/pluginmanager.h> +#include <utils/styledbar.h> + #include <QtCore/QDebug> #include <QtGui/QAction> @@ -50,7 +52,6 @@ #include <QtGui/QMenu> #include <QtGui/QPainter> #include <QtGui/QPushButton> -#include <QtGui/QToolBar> #include <QtGui/QToolButton> #include <QtGui/QStackedWidget> @@ -163,7 +164,6 @@ OutputPaneManager::OutputPaneManager(QWidget *parent) : m_closeButton(new QToolButton), m_nextAction(0), m_prevAction(0), - m_closeAction(0), m_lastIndex(-1), m_outputWidgetPane(new QStackedWidget), m_opToolBarWidgets(new QStackedWidget) @@ -177,29 +177,32 @@ OutputPaneManager::OutputPaneManager(QWidget *parent) : m_nextAction = new QAction(this); m_nextAction->setIcon(QIcon(":/core/images/next.png")); - m_nextAction->setProperty("type", QLatin1String("dockbutton")); m_nextAction->setText(tr("Next Item")); connect(m_nextAction, SIGNAL(triggered()), this, SLOT(slotNext())); m_prevAction = new QAction(this); m_prevAction->setIcon(QIcon(":/core/images/prev.png")); - m_prevAction->setProperty("type", QLatin1String("dockbutton")); m_prevAction->setText(tr("Previous Item")); connect(m_prevAction, SIGNAL(triggered()), this, SLOT(slotPrev())); m_closeButton->setIcon(QIcon(":/core/images/closebutton.png")); - m_closeButton->setProperty("type", QLatin1String("dockbutton")); connect(m_closeButton, SIGNAL(clicked()), this, SLOT(slotHide())); QVBoxLayout *mainlayout = new QVBoxLayout; mainlayout->setSpacing(0); mainlayout->setMargin(0); - m_toolBar = new QToolBar; - m_toolBar->addWidget(m_widgetComboBox); - m_toolBar->addWidget(m_clearButton); - - m_opToolBarAction = m_toolBar->addWidget(m_opToolBarWidgets); - m_closeAction = m_toolBar->addWidget(m_closeButton); + m_toolBar = new Core::Utils::StyledBar; + QHBoxLayout *toolLayout = new QHBoxLayout(m_toolBar); + toolLayout->setMargin(0); + toolLayout->setSpacing(0); + toolLayout->addWidget(m_widgetComboBox); + toolLayout->addWidget(m_clearButton); + m_prevToolButton = new QToolButton; + toolLayout->addWidget(m_prevToolButton); + m_nextToolButton = new QToolButton; + toolLayout->addWidget(m_nextToolButton); + toolLayout->addWidget(m_opToolBarWidgets); + toolLayout->addWidget(m_closeButton); mainlayout->addWidget(m_toolBar); mainlayout->addWidget(m_outputWidgetPane, 10); setLayout(mainlayout); @@ -248,11 +251,11 @@ void OutputPaneManager::init() cmd = am->registerAction(m_prevAction, "Coreplugin.OutputPane.previtem", globalcontext); cmd->setDefaultKeySequence(QKeySequence("Shift+F6")); - m_toolBar->insertAction(m_opToolBarAction ,cmd->action()); + m_prevToolButton->setDefaultAction(cmd->action()); mpanes->addAction(cmd, "Coreplugin.OutputPane.ActionsGroup"); cmd = am->registerAction(m_nextAction, "Coreplugin.OutputPane.nextitem", globalcontext); - m_toolBar->insertAction(m_opToolBarAction, cmd->action()); + m_nextToolButton->setDefaultAction(cmd->action()); cmd->setDefaultKeySequence(QKeySequence("F6")); mpanes->addAction(cmd, "Coreplugin.OutputPane.ActionsGroup"); @@ -492,7 +495,7 @@ void OutputPaneManager::togglePage(bool focus) void OutputPaneManager::setCloseable(bool b) { - m_closeAction->setVisible(b); + m_closeButton->setVisible(b); } bool OutputPaneManager::closeable() diff --git a/src/plugins/coreplugin/outputpane.h b/src/plugins/coreplugin/outputpane.h index 102060bf9e14ce45733dd5b73473762c7af82ea0..a839c24be76b9acb50b0af8b91e4a67d3a89ef94 100644 --- a/src/plugins/coreplugin/outputpane.h +++ b/src/plugins/coreplugin/outputpane.h @@ -39,7 +39,6 @@ QT_BEGIN_NAMESPACE class QAction; class QComboBox; class QToolButton; -class QToolBar; class QStackedWidget; class QPushButton; QT_END_NAMESPACE @@ -125,15 +124,15 @@ private: QAction *m_nextAction; QAction *m_prevAction; - QAction *m_closeAction; - QToolBar *m_toolBar; + QToolButton *m_prevToolButton; + QToolButton *m_nextToolButton; + QWidget *m_toolBar; QMap<int, Core::IOutputPane*> m_pageMap; int m_lastIndex; QStackedWidget *m_outputWidgetPane; QStackedWidget *m_opToolBarWidgets; - QAction *m_opToolBarAction; QWidget *m_buttonsWidget; QMap<int, QPushButton *> m_buttons; QMap<QAction *, int> m_actions; diff --git a/src/plugins/coreplugin/scriptmanager/metatypedeclarations.h b/src/plugins/coreplugin/scriptmanager/metatypedeclarations.h index 9287e3c6ba8722bee2258a5d30791704e24a8d12..430ab61a3f54841797c7162f41af13169af443b8 100644 --- a/src/plugins/coreplugin/scriptmanager/metatypedeclarations.h +++ b/src/plugins/coreplugin/scriptmanager/metatypedeclarations.h @@ -43,7 +43,6 @@ QT_BEGIN_NAMESPACE class QMainWindow; class QStatusBar; -class QToolBar; class QSettings; QT_END_NAMESPACE @@ -60,7 +59,6 @@ Q_DECLARE_METATYPE(Core::ICore*) Q_DECLARE_METATYPE(QMainWindow*) Q_DECLARE_METATYPE(QStatusBar*) -Q_DECLARE_METATYPE(QToolBar*) Q_DECLARE_METATYPE(QSettings*) #endif // METATYPEDECLARATIONS_H diff --git a/src/plugins/coreplugin/scriptmanager/qworkbench_wrapper.cpp b/src/plugins/coreplugin/scriptmanager/qworkbench_wrapper.cpp index 65a7ddcbea289ad1211aa59abbf6ce99d70a55d9..df8f7352adbf6b28307223f4e3e7c55f5964ea9a 100644 --- a/src/plugins/coreplugin/scriptmanager/qworkbench_wrapper.cpp +++ b/src/plugins/coreplugin/scriptmanager/qworkbench_wrapper.cpp @@ -39,7 +39,6 @@ #include <QtCore/QSettings> #include <QtGui/QMainWindow> -#include <QtGui/QToolBar> #include <QtScript/QScriptEngine> @@ -346,7 +345,7 @@ Core::IFile *EditorPrototype::file() const return callee()->file(); } -QToolBar* EditorPrototype::toolBar() const +QWidget* EditorPrototype::toolBar() const { return callee()->toolBar(); } diff --git a/src/plugins/coreplugin/scriptmanager/qworkbench_wrapper.h b/src/plugins/coreplugin/scriptmanager/qworkbench_wrapper.h index 5e4b10c37b18cb6aaf41e81fe08da436445164f5..a8d386bbf96596d0151503e5e2faac8b1014dcfd 100644 --- a/src/plugins/coreplugin/scriptmanager/qworkbench_wrapper.h +++ b/src/plugins/coreplugin/scriptmanager/qworkbench_wrapper.h @@ -198,7 +198,7 @@ class EditorPrototype : public QObject, public QScriptable Q_PROPERTY(QString kind READ kind DESIGNABLE false SCRIPTABLE true STORED false) Q_PROPERTY(bool duplicateSupported READ duplicateSupported DESIGNABLE false SCRIPTABLE true STORED false) Q_PROPERTY(Core::IFile* file READ file DESIGNABLE false SCRIPTABLE true STORED false) - Q_PROPERTY(QToolBar* toolBar READ toolBar DESIGNABLE false SCRIPTABLE true STORED false) + Q_PROPERTY(QWidget* toolBar READ toolBar DESIGNABLE false SCRIPTABLE true STORED false) public: EditorPrototype(QObject *parent = 0); @@ -210,7 +210,7 @@ public: bool duplicateSupported() const; Core::IFile *file() const; - QToolBar* toolBar() const; + QWidget* toolBar() const; public slots: bool createNew(const QString &contents); diff --git a/src/plugins/coreplugin/scriptmanager/scriptmanager.cpp b/src/plugins/coreplugin/scriptmanager/scriptmanager.cpp index a7fd500acbd8570993c4d15247ceab383c14c2c3..cb18913f690e7d2a46be4210aa471d88c971ce4e 100644 --- a/src/plugins/coreplugin/scriptmanager/scriptmanager.cpp +++ b/src/plugins/coreplugin/scriptmanager/scriptmanager.cpp @@ -247,7 +247,6 @@ void ScriptManagerPrivate::ensureEngineInitialized() // register QObjects that occur as properties SharedTools::registerQObject<QMainWindow>(m_engine); SharedTools::registerQObject<QStatusBar>(m_engine); - SharedTools::registerQObject<QToolBar>(m_engine); SharedTools::registerQObject<QSettings>(m_engine); // WB interfaces // SharedTools::registerQObjectInterface<Core::MessageManager, MessageManagerPrototype>(m_engine); diff --git a/src/plugins/coreplugin/sidebar.cpp b/src/plugins/coreplugin/sidebar.cpp index 45e8712fd66ab05072749f7c86c14ce8714f630c..b637f24e85d28d504d70b1ccd6cdfb9df08e2e29 100644 --- a/src/plugins/coreplugin/sidebar.cpp +++ b/src/plugins/coreplugin/sidebar.cpp @@ -237,13 +237,11 @@ SideBarWidget::SideBarWidget(SideBar *sideBar, const QString &title) m_toolbar->addWidget(m_comboBox); m_splitButton = new QToolButton; - m_splitButton->setProperty("type", QLatin1String("dockbutton")); m_splitButton->setIcon(QIcon(":/core/images/splitbutton_horizontal.png")); m_splitButton->setToolTip(tr("Split")); connect(m_splitButton, SIGNAL(clicked(bool)), this, SIGNAL(split())); m_closeButton = new QToolButton; - m_closeButton->setProperty("type", QLatin1String("dockbutton")); m_closeButton->setIcon(QIcon(":/core/images/closebutton.png")); m_closeButton->setToolTip(tr("Close")); diff --git a/src/plugins/coreplugin/welcomemode.cpp b/src/plugins/coreplugin/welcomemode.cpp index e1489eba8103e44a609143e4e8af0eb5be9d0438..27cbd4e9c3bb680427497e31e9aea8d697871117 100644 --- a/src/plugins/coreplugin/welcomemode.cpp +++ b/src/plugins/coreplugin/welcomemode.cpp @@ -36,7 +36,8 @@ #include "newdialog.h" #include "rssfetcher.h" -#include <QtGui/QToolBar> +#include <utils/styledbar.h> + #include <QtGui/QDesktopServices> #include <QtGui/QMouseEvent> #include <QtGui/QScrollArea> @@ -121,7 +122,7 @@ WelcomeMode::WelcomeMode() : QVBoxLayout *l = new QVBoxLayout(m_d->m_widget); l->setMargin(0); l->setSpacing(0); - l->addWidget(new QToolBar(m_d->m_widget)); + l->addWidget(new Core::Utils::StyledBar(m_d->m_widget)); m_d->rssFetcher = new RSSFetcher(7, this); m_d->m_welcomePage = new QWidget(m_d->m_widget); m_d->ui.setupUi(m_d->m_welcomePage); diff --git a/src/plugins/cppeditor/cppeditor.cpp b/src/plugins/cppeditor/cppeditor.cpp index ea682127e589370e6281cd3a781cf4a74960c13a..ff9975e013f0918792d35c7d24d27b71473d99e3 100644 --- a/src/plugins/cppeditor/cppeditor.cpp +++ b/src/plugins/cppeditor/cppeditor.cpp @@ -80,6 +80,7 @@ #include <QtGui/QShortcut> #include <QtGui/QTextEdit> #include <QtGui/QComboBox> +#include <QtGui/QToolBar> #include <QtGui/QTreeView> #include <QtGui/QSortFilterProxyModel> @@ -640,7 +641,7 @@ void CPPEditor::createToolBar(CPPEditorEditable *editable) connect(m_semanticHighlighter, SIGNAL(changed(SemanticInfo)), this, SLOT(updateSemanticInfo(SemanticInfo))); - QToolBar *toolBar = editable->toolBar(); + QToolBar *toolBar = static_cast<QToolBar*>(editable->toolBar()); QList<QAction*> actions = toolBar->actions(); QWidget *w = toolBar->widgetForAction(actions.first()); static_cast<QHBoxLayout*>(w->layout())->insertWidget(0, m_methodCombo, 1); diff --git a/src/plugins/cpptools/cppmodelmanager.cpp b/src/plugins/cpptools/cppmodelmanager.cpp index 175c97498e50624563115b20eb86ddee93e13aba..f23fd06209fde0444058e51e4cd22999b6cd7485 100644 --- a/src/plugins/cpptools/cppmodelmanager.cpp +++ b/src/plugins/cpptools/cppmodelmanager.cpp @@ -146,6 +146,7 @@ static const char pp_configuration[] = "#define __asm__(a...)\n" "#define restrict\n" "#define __restrict\n" + "#define __restrict__\n" "#define __complex__\n" "#define __imag__\n" diff --git a/src/plugins/cvs/checkoutwizard.cpp b/src/plugins/cvs/checkoutwizard.cpp new file mode 100644 index 0000000000000000000000000000000000000000..7e7eb026b24651fc334548db2802488c47cd1f21 --- /dev/null +++ b/src/plugins/cvs/checkoutwizard.cpp @@ -0,0 +1,89 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (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 http://www.qtsoftware.com/contact. +** +**************************************************************************/ + +#include "checkoutwizard.h" +#include "checkoutwizardpage.h" +#include "cvsplugin.h" + +#include <vcsbase/checkoutjobs.h> +#include <utils/qtcassert.h> + +#include <QtGui/QIcon> + +namespace CVS { +namespace Internal { + +CheckoutWizard::CheckoutWizard(QObject *parent) : + VCSBase::BaseCheckoutWizard(parent) +{ +} + +QIcon CheckoutWizard::icon() const +{ + return QIcon(); +} + +QString CheckoutWizard::description() const +{ + return tr("Check-out a project from a CVS repository."); +} + +QString CheckoutWizard::name() const +{ + return tr("CVS Checkout"); +} + +QWizardPage *CheckoutWizard::createParameterPage(const QString &path) +{ + CheckoutWizardPage *cwp = new CheckoutWizardPage; + cwp->setPath(path); + return cwp; +} + +QSharedPointer<VCSBase::AbstractCheckoutJob> CheckoutWizard::createJob(const QWizardPage *parameterPage, + QString *checkoutPath) +{ + // Collect parameters for the checkout command. + // CVS does not allow for checking out into a different directory. + const CheckoutWizardPage *cwp = qobject_cast<const CheckoutWizardPage *>(parameterPage); + QTC_ASSERT(cwp, return QSharedPointer<VCSBase::AbstractCheckoutJob>()) + const CVSSettings settings = CVSPlugin::cvsPluginInstance()->settings(); + const QString binary = settings.cvsCommand; + QStringList args; + const QString repository = cwp->repository(); + args << QLatin1String("checkout") << repository; + const QString workingDirectory = cwp->path(); + *checkoutPath = workingDirectory + QLatin1Char('/') + repository; + VCSBase::AbstractCheckoutJob *job = new VCSBase::ProcessCheckoutJob(binary, settings.addOptions(args), + workingDirectory); + return QSharedPointer<VCSBase::AbstractCheckoutJob>(job); +} + +} // namespace Internal +} // namespace CVS diff --git a/src/plugins/cvs/checkoutwizard.h b/src/plugins/cvs/checkoutwizard.h new file mode 100644 index 0000000000000000000000000000000000000000..53c7f86a96117ea367ab01c707bc8c56a4ab432a --- /dev/null +++ b/src/plugins/cvs/checkoutwizard.h @@ -0,0 +1,58 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (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 http://www.qtsoftware.com/contact. +** +**************************************************************************/ + +#ifndef CHECKOUTWIZARD_H +#define CHECKOUTWIZARD_H + +#include <vcsbase/basecheckoutwizard.h> + +namespace CVS { +namespace Internal { + +class CheckoutWizard : public VCSBase::BaseCheckoutWizard +{ +public: + explicit CheckoutWizard(QObject *parent = 0); + + // IWizard + virtual QIcon icon() const; + virtual QString description() const; + virtual QString name() const; + +protected: + // BaseCheckoutWizard + virtual QWizardPage *createParameterPage(const QString &path); + virtual QSharedPointer<VCSBase::AbstractCheckoutJob> createJob(const QWizardPage *parameterPage, + QString *checkoutPath); +}; + +} // namespace Internal +} // namespace CVS + +#endif // CHECKOUTWIZARD_H diff --git a/src/plugins/cvs/checkoutwizardpage.cpp b/src/plugins/cvs/checkoutwizardpage.cpp new file mode 100644 index 0000000000000000000000000000000000000000..70c97a721aa1e368e2b013e6a70c7de1f779bc4d --- /dev/null +++ b/src/plugins/cvs/checkoutwizardpage.cpp @@ -0,0 +1,44 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (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 http://www.qtsoftware.com/contact. +** +**************************************************************************/ + +#include "checkoutwizardpage.h" + +namespace CVS { +namespace Internal { + +CheckoutWizardPage::CheckoutWizardPage(QWidget *parent) : + VCSBase::BaseCheckoutWizardPage(parent) +{ + setSubTitle(tr("Specify repository and path.")); + setRepositoryLabel(tr("Repository:")); + setDirectoryVisible(false); +} + +} // namespace Internal +} // namespace CVS diff --git a/src/plugins/cvs/checkoutwizardpage.h b/src/plugins/cvs/checkoutwizardpage.h new file mode 100644 index 0000000000000000000000000000000000000000..cfab3a30403ae15f2f9e3dc58ca33419e7d50f7a --- /dev/null +++ b/src/plugins/cvs/checkoutwizardpage.h @@ -0,0 +1,46 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (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 http://www.qtsoftware.com/contact. +** +**************************************************************************/ + +#ifndef CHECKOUTWIZARDPAGE_H +#define CHECKOUTWIZARDPAGE_H + +#include <vcsbase/basecheckoutwizardpage.h> + +namespace CVS { +namespace Internal { + +class CheckoutWizardPage : public VCSBase::BaseCheckoutWizardPage { + Q_OBJECT +public: + CheckoutWizardPage(QWidget *parent = 0); +}; + +} // namespace Internal +} // namespace CVS +#endif // CHECKOUTWIZARDPAGE_H diff --git a/src/plugins/cvs/cvs.pro b/src/plugins/cvs/cvs.pro index 86244a20aacf31464bd93eb4c95344689c44f5ec..a0d6f04602cdaa079bb178cee957c1b1b6912844 100644 --- a/src/plugins/cvs/cvs.pro +++ b/src/plugins/cvs/cvs.pro @@ -17,7 +17,9 @@ HEADERS += annotationhighlighter.h \ cvssubmiteditor.h \ cvssettings.h \ cvsutils.h \ - cvsconstants.h + cvsconstants.h \ + checkoutwizard.h \ + checkoutwizardpage.h SOURCES += annotationhighlighter.cpp \ cvsplugin.cpp \ @@ -27,7 +29,9 @@ SOURCES += annotationhighlighter.cpp \ cvseditor.cpp \ cvssubmiteditor.cpp \ cvssettings.cpp \ - cvsutils.cpp + cvsutils.cpp \ + checkoutwizard.cpp \ + checkoutwizardpage.cpp FORMS += settingspage.ui diff --git a/src/plugins/cvs/cvsplugin.cpp b/src/plugins/cvs/cvsplugin.cpp index 8e0e4785a1e5452225fd074fb2f7a671935052ca..83d10fe004f9dd294a720103524dba093765c3cd 100644 --- a/src/plugins/cvs/cvsplugin.cpp +++ b/src/plugins/cvs/cvsplugin.cpp @@ -34,6 +34,7 @@ #include "cvssubmiteditor.h" #include "cvsconstants.h" #include "cvscontrol.h" +#include "checkoutwizard.h" #include <vcsbase/basevcseditorfactory.h> #include <vcsbase/vcsbaseeditor.h> @@ -241,6 +242,8 @@ bool CVSPlugin::initialize(const QStringList &arguments, QString *errorMessage) m_cvsOutputWindow = new CVSOutputWindow(this); addAutoReleasedObject(m_cvsOutputWindow); + addAutoReleasedObject(new CheckoutWizard); + //register actions Core::ActionManager *ami = core->actionManager(); Core::ActionContainer *toolsContainer = ami->actionContainer(M_TOOLS); @@ -797,7 +800,7 @@ static QString previousRevision(const QString &rev) // Is "[1.2...].1"? static inline bool isFirstRevision(const QString &r) { - return r.endsWith(QLatin1Char('1')); + return r.endsWith(QLatin1String(".1")); } void CVSPlugin::slotDescribe(const QString &source, const QString &changeNr) diff --git a/src/plugins/cvs/cvssettings.h b/src/plugins/cvs/cvssettings.h index ff37307f2bb62224045d159be9dbf230d17a8e93..b6822674ffa89c0542fc7819b0337fe3380a5f07 100644 --- a/src/plugins/cvs/cvssettings.h +++ b/src/plugins/cvs/cvssettings.h @@ -39,7 +39,6 @@ QT_END_NAMESPACE namespace CVS { namespace Internal { -// Todo: Add user name and password? struct CVSSettings { CVSSettings(); diff --git a/src/plugins/debugger/debuggermanager.cpp b/src/plugins/debugger/debuggermanager.cpp index a4dadb51919075e8df2368e85959e97c86ca720f..b3ca55f0dc17e9fe36133f9e37038103f8b8fd48 100644 --- a/src/plugins/debugger/debuggermanager.cpp +++ b/src/plugins/debugger/debuggermanager.cpp @@ -80,7 +80,6 @@ #include <QtGui/QStatusBar> #include <QtGui/QTextBlock> #include <QtGui/QTextCursor> -#include <QtGui/QToolBar> #include <QtGui/QToolButton> #include <QtGui/QToolTip> diff --git a/src/plugins/debugger/debuggerplugin.cpp b/src/plugins/debugger/debuggerplugin.cpp index 904e548188bf8cb8de89895e8bf6dfaf383520b7..33c204355b15ea15d1952a2b8bd8d3b9474397ec 100644 --- a/src/plugins/debugger/debuggerplugin.cpp +++ b/src/plugins/debugger/debuggerplugin.cpp @@ -70,6 +70,7 @@ #include <texteditor/texteditorconstants.h> #include <utils/qtcassert.h> +#include <utils/styledbar.h> #include <QtCore/QDebug> #include <QtCore/QObject> @@ -162,6 +163,13 @@ static QSettings *settings() return ICore::instance()->settings(); } +static QToolButton *toolButton(QAction *action) +{ + QToolButton *button = new QToolButton; + button->setDefaultAction(action); + return button; +} + /////////////////////////////////////////////////////////////////////// // // DebugMode @@ -821,33 +829,32 @@ bool DebuggerPlugin::initialize(const QStringList &arguments, QString *errorMess m_debugMode->setWidget(splitter2); - QToolBar *debugToolBar = new QToolBar; + Core::Utils::StyledBar *debugToolBar = new Core::Utils::StyledBar; debugToolBar->setProperty("topBorder", true); - debugToolBar->addAction(am->command(ProjectExplorer::Constants::DEBUG)->action()); - debugToolBar->addAction(am->command(Constants::INTERRUPT)->action()); - debugToolBar->addAction(am->command(Constants::NEXT)->action()); - debugToolBar->addAction(am->command(Constants::STEP)->action()); - debugToolBar->addAction(am->command(Constants::STEPOUT)->action()); - debugToolBar->addSeparator(); - debugToolBar->addAction(am->command(Constants::STEPI)->action()); - debugToolBar->addAction(am->command(Constants::NEXTI)->action()); + QHBoxLayout *debugToolBarLayout = new QHBoxLayout(debugToolBar); + debugToolBarLayout->setMargin(0); + debugToolBarLayout->setSpacing(0); + debugToolBarLayout->addWidget(toolButton(am->command(ProjectExplorer::Constants::DEBUG)->action())); + debugToolBarLayout->addWidget(toolButton(am->command(Constants::INTERRUPT)->action())); + debugToolBarLayout->addWidget(toolButton(am->command(Constants::NEXT)->action())); + debugToolBarLayout->addWidget(toolButton(am->command(Constants::STEP)->action())); + debugToolBarLayout->addWidget(toolButton(am->command(Constants::STEPOUT)->action())); + debugToolBarLayout->addWidget(new Core::Utils::StyledSeparator); + debugToolBarLayout->addWidget(toolButton(am->command(Constants::STEPI)->action())); + debugToolBarLayout->addWidget(toolButton(am->command(Constants::NEXTI)->action())); #ifdef USE_REVERSE_DEBUGGING - debugToolBar->addSeparator(); - debugToolBar->addAction(am->command(Constants::REVERSE)->action()); + debugToolBarLayout->addWidget(new Core::Utils::StyledSeparator); + debugToolBarLayout->addWidget(toolButton(am->command(Constants::REVERSE)->action())); #endif - debugToolBar->addSeparator(); - debugToolBar->addWidget(new QLabel(tr("Threads:"))); + debugToolBarLayout->addWidget(new Core::Utils::StyledSeparator); + debugToolBarLayout->addWidget(new QLabel(tr("Threads:"))); QComboBox *threadBox = new QComboBox; threadBox->setModel(m_manager->threadsModel()); connect(threadBox, SIGNAL(activated(int)), m_manager->threadsWindow(), SIGNAL(threadSelected(int))); - debugToolBar->addWidget(threadBox); - debugToolBar->addWidget(m_manager->statusLabel()); - - QWidget *stretch = new QWidget; - stretch->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum); - debugToolBar->addWidget(stretch); + debugToolBarLayout->addWidget(threadBox); + debugToolBarLayout->addWidget(m_manager->statusLabel(), 10); QBoxLayout *toolBarAddingLayout = new QVBoxLayout(centralWidget); toolBarAddingLayout->setMargin(0); diff --git a/src/plugins/debugger/script/scriptengine.h b/src/plugins/debugger/script/scriptengine.h index ae4a434efc007c71a1d6f0107917de3a6c7bf2f4..a54687df7c07514352681b9b7b13d6150db56cd1 100644 --- a/src/plugins/debugger/script/scriptengine.h +++ b/src/plugins/debugger/script/scriptengine.h @@ -43,7 +43,6 @@ QT_BEGIN_NAMESPACE class QAction; class QAbstractItemModel; class QSplitter; -class QToolBar; class QScriptEngine; class QScriptValue; QT_END_NAMESPACE diff --git a/src/plugins/designer/formeditorw.cpp b/src/plugins/designer/formeditorw.cpp index bd63c74eb1e1c2a2a34b1a2165ca4889ffdc51a7..b2c1fb27070516136c261eeee03c86492a9480eb 100644 --- a/src/plugins/designer/formeditorw.cpp +++ b/src/plugins/designer/formeditorw.cpp @@ -467,8 +467,7 @@ void FormEditorW::setupActions() QToolBar *FormEditorW::createEditorToolBar() const { - QToolBar *rc = new QToolBar; - rc->addSeparator(); + QToolBar *toolBar = new QToolBar; Core::ActionManager *am = m_core->actionManager(); const QStringList::const_iterator cend = m_toolActionIds.constEnd(); for (QStringList::const_iterator it = m_toolActionIds.constBegin(); it != cend; ++it) { @@ -476,11 +475,12 @@ QToolBar *FormEditorW::createEditorToolBar() const QTC_ASSERT(cmd, continue); QAction *action = cmd->action(); if (!action->icon().isNull()) // Simplify grid has no action yet - rc->addAction(action); + toolBar->addAction(action); } - int size = rc->style()->pixelMetric(QStyle::PM_SmallIconSize); - rc->setIconSize(QSize(size, size)); - return rc; + int size = toolBar->style()->pixelMetric(QStyle::PM_SmallIconSize); + toolBar->setIconSize(QSize(size, size)); + toolBar->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); + return toolBar; } Core::ActionContainer *FormEditorW::createPreviewStyleMenu(Core::ActionManager *am, diff --git a/src/plugins/designer/formwindoweditor.cpp b/src/plugins/designer/formwindoweditor.cpp index 6f2283590fe20fbe61e3c3ccda794251ce997e12..f9bc92558d1e8cb9fe0b32e3e2bec9ffaa4c24ff 100644 --- a/src/plugins/designer/formwindoweditor.cpp +++ b/src/plugins/designer/formwindoweditor.cpp @@ -274,7 +274,7 @@ void FormWindowEditor::setDisplayName(const QString &title) m_displayName = title; } -QToolBar *FormWindowEditor::toolBar() +QWidget *FormWindowEditor::toolBar() { if (!m_toolBar) m_toolBar = FormEditorW::instance()->createEditorToolBar(); diff --git a/src/plugins/designer/formwindoweditor.h b/src/plugins/designer/formwindoweditor.h index 123cfa0e31a5bae1ce354e67dc4a6253fff61aed..2be6d7c45be40f5d360e765c8460eff525f428cc 100644 --- a/src/plugins/designer/formwindoweditor.h +++ b/src/plugins/designer/formwindoweditor.h @@ -41,6 +41,7 @@ QT_BEGIN_NAMESPACE class QDesignerFormWindowInterface; class QDesignerFormWindowManagerInterface; class QFile; +class QToolBar; QT_END_NAMESPACE namespace ProjectExplorer { @@ -76,7 +77,7 @@ public: const char *kind() const; QString displayName() const; void setDisplayName(const QString &title); - QToolBar *toolBar(); + QWidget *toolBar(); QByteArray saveState() const; bool restoreState(const QByteArray &state); virtual bool isTemporary() const { return false; } diff --git a/src/plugins/duieditor/duieditor.cpp b/src/plugins/duieditor/duieditor.cpp index 58624f55617452a855bab03eb84770c64760e3e4..14bb84845710158ffff75d014b31505f5705abd2 100644 --- a/src/plugins/duieditor/duieditor.cpp +++ b/src/plugins/duieditor/duieditor.cpp @@ -56,6 +56,7 @@ #include <QtGui/QComboBox> #include <QtGui/QInputDialog> #include <QtGui/QMainWindow> +#include <QtGui/QToolBar> enum { UPDATE_DOCUMENT_DEFAULT_INTERVAL = 250 @@ -677,7 +678,7 @@ void ScriptEditor::createToolBar(ScriptEditorEditable *editable) connect(file(), SIGNAL(changed()), this, SLOT(updateFileName())); - QToolBar *toolBar = editable->toolBar(); + QToolBar *toolBar = static_cast<QToolBar*>(editable->toolBar()); QList<QAction*> actions = toolBar->actions(); toolBar->insertWidget(actions.first(), m_methodCombo); diff --git a/src/plugins/find/findtoolbar.cpp b/src/plugins/find/findtoolbar.cpp index 4e19745403aaed8845c963c6d74e540def97261c..2e8df6b263cfc99721314423b8927465ed9b5c95 100644 --- a/src/plugins/find/findtoolbar.cpp +++ b/src/plugins/find/findtoolbar.cpp @@ -76,21 +76,15 @@ FindToolBar::FindToolBar(FindPlugin *plugin, CurrentDocumentFind *currentDocumen m_ui.setupUi(this); setFocusProxy(m_ui.findEdit); setProperty("topBorder", true); + setSingleRow(false); m_ui.findEdit->setAttribute(Qt::WA_MacShowFocusRect, false); m_ui.replaceEdit->setAttribute(Qt::WA_MacShowFocusRect, false); connect(m_ui.findEdit, SIGNAL(editingFinished()), this, SLOT(invokeResetIncrementalSearch())); - m_ui.close->setProperty("type", QLatin1String("dockbutton")); m_ui.close->setIcon(QIcon(":/core/images/closebutton.png")); connect(m_ui.close, SIGNAL(clicked()), this, SLOT(hideAndResetFocus())); - m_ui.findPreviousButton->setProperty("type", QLatin1String("dockbutton")); - m_ui.findNextButton->setProperty("type", QLatin1String("dockbutton")); - m_ui.replacePreviousButton->setProperty("type", QLatin1String("dockbutton")); - m_ui.replaceNextButton->setProperty("type", QLatin1String("dockbutton")); - m_ui.replaceAllButton->setProperty("type", QLatin1String("dockbutton")); - m_findCompleter->setModel(m_plugin->findCompletionModel()); m_replaceCompleter->setModel(m_plugin->replaceCompletionModel()); m_ui.findEdit->setCompleter(m_findCompleter); diff --git a/src/plugins/find/findtoolbar.h b/src/plugins/find/findtoolbar.h index f1cab5e314f636e003b290bed95528f855cf6c56..8985b3419c3efce9399a42e2e4805052f20a776a 100644 --- a/src/plugins/find/findtoolbar.h +++ b/src/plugins/find/findtoolbar.h @@ -38,7 +38,6 @@ #include <QtGui/QStringListModel> #include <QtGui/QWidget> -#include <QtGui/QToolBar> #include <QtGui/QLabel> namespace Find { diff --git a/src/plugins/git/clonewizard.cpp b/src/plugins/git/clonewizard.cpp new file mode 100644 index 0000000000000000000000000000000000000000..80d3112504d3b608142e43558485b4fbad35056a --- /dev/null +++ b/src/plugins/git/clonewizard.cpp @@ -0,0 +1,91 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (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 http://www.qtsoftware.com/contact. +** +**************************************************************************/ + +#include "clonewizard.h" +#include "clonewizardpage.h" +#include "gitplugin.h" +#include "gitclient.h" + +#include <vcsbase/checkoutjobs.h> +#include <utils/qtcassert.h> + +#include <QtGui/QIcon> + +namespace Git { +namespace Internal { + +CloneWizard::CloneWizard(QObject *parent) : + VCSBase::BaseCheckoutWizard(parent) +{ +} + +QIcon CloneWizard::icon() const +{ + return QIcon(); +} + +QString CloneWizard::description() const +{ + return tr("Clones a project from a git repository."); +} + +QString CloneWizard::name() const +{ + return tr("Git Repository Clone"); +} + +QWizardPage *CloneWizard::createParameterPage(const QString &path) +{ + CloneWizardPage *cwp = new CloneWizardPage; + cwp->setPath(path); + return cwp; +} + +QSharedPointer<VCSBase::AbstractCheckoutJob> CloneWizard::createJob(const QWizardPage *parameterPage, + QString *checkoutPath) +{ + // Collect parameters for the clone command. + const CloneWizardPage *cwp = qobject_cast<const CloneWizardPage *>(parameterPage); + QTC_ASSERT(cwp, return QSharedPointer<VCSBase::AbstractCheckoutJob>()) + const GitClient *client = GitPlugin::instance()->gitClient(); + QStringList args = client->binary(); + const QString workingDirectory = cwp->path(); + const QString directory = cwp->directory(); + *checkoutPath = workingDirectory + QLatin1Char('/') + directory; + args << QLatin1String("clone") << cwp->repository() << directory; + const QString binary = args.front(); + args.pop_front(); + + VCSBase::AbstractCheckoutJob *job = new VCSBase::ProcessCheckoutJob(binary, args, workingDirectory, + client->processEnvironment()); + return QSharedPointer<VCSBase::AbstractCheckoutJob>(job); +} + +} // namespace Internal +} // namespace Git diff --git a/src/plugins/git/clonewizard.h b/src/plugins/git/clonewizard.h new file mode 100644 index 0000000000000000000000000000000000000000..2a1c0ff3b55b4a8ba9a10a912a38c1253eed7d9b --- /dev/null +++ b/src/plugins/git/clonewizard.h @@ -0,0 +1,58 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (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 http://www.qtsoftware.com/contact. +** +**************************************************************************/ + +#ifndef CLONEWIZARD_H +#define CLONEWIZARD_H + +#include <vcsbase/basecheckoutwizard.h> + +namespace Git { +namespace Internal { + +class CloneWizard : public VCSBase::BaseCheckoutWizard +{ +public: + explicit CloneWizard(QObject *parent = 0); + + // IWizard + virtual QIcon icon() const; + virtual QString description() const; + virtual QString name() const; + +protected: + // BaseCheckoutWizard + virtual QWizardPage *createParameterPage(const QString &path); + virtual QSharedPointer<VCSBase::AbstractCheckoutJob> createJob(const QWizardPage *parameterPage, + QString *checkoutPath); +}; + +} // namespace Internal +} // namespace Git + +#endif // CLONEWIZARD_H diff --git a/src/plugins/git/clonewizardpage.cpp b/src/plugins/git/clonewizardpage.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6f78ab278f566baa5172ad8384e155e72063c304 --- /dev/null +++ b/src/plugins/git/clonewizardpage.cpp @@ -0,0 +1,83 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (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 http://www.qtsoftware.com/contact. +** +**************************************************************************/ + +#include "clonewizardpage.h" + +namespace Git { +namespace Internal { + +CloneWizardPage::CloneWizardPage(QWidget *parent) : + VCSBase::BaseCheckoutWizardPage(parent), + m_mainLinePostfix(QLatin1String("/mainline.git")), + m_gitPostFix(QLatin1String(".git")), + m_protocolDelimiter(QLatin1String("://")) +{ + setSubTitle(tr("Specify repository URL, checkout directory and path.")); + setRepositoryLabel(tr("Clone URL:")); +} + +QString CloneWizardPage::directoryFromRepository(const QString &urlIn) const +{ + /* Try to figure out a good directory name from something like: + * 'user@host:qt/qt.git', 'http://host/qt/qt.git' 'local repo' + * ------> 'qt' . */ + + QString url = urlIn.trimmed(); + const QChar slash = QLatin1Char('/'); + // remove host + const int protocolDelimiterPos = url.indexOf(m_protocolDelimiter); // "://" + const int startRepoSearchPos = protocolDelimiterPos == -1 ? 0 : protocolDelimiterPos + m_protocolDelimiter.size(); + int repoPos = url.indexOf(QLatin1Char(':'), startRepoSearchPos); + if (repoPos == -1) + repoPos = url.indexOf(slash, startRepoSearchPos); + if (repoPos != -1) + url.remove(0, repoPos + 1); + // Remove postfixes + if (url.endsWith(m_mainLinePostfix)) { + url.truncate(url.size() - m_mainLinePostfix.size()); + } else { + if (url.endsWith(m_gitPostFix)) { + url.truncate(url.size() - m_gitPostFix.size()); + } + } + // Check for equal parts, something like "qt/qt" -> "qt" + const int slashPos = url.indexOf(slash); + if (slashPos != -1 && slashPos == (url.size() - 1) / 2) { + if (url.leftRef(slashPos) == url.rightRef(slashPos)) + url.truncate(slashPos); + } + // fix invalid characters + const QChar dash = QLatin1Char('-'); + url.replace(slash, dash); + url.replace(QLatin1Char('.'), dash); + return url; +} + +} // namespace Internal +} // namespace Git diff --git a/src/plugins/git/clonewizardpage.h b/src/plugins/git/clonewizardpage.h new file mode 100644 index 0000000000000000000000000000000000000000..4d8797e6f0f46bdd9522c6f6af92c7c38bd69ad9 --- /dev/null +++ b/src/plugins/git/clonewizardpage.h @@ -0,0 +1,56 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (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 http://www.qtsoftware.com/contact. +** +**************************************************************************/ + +#ifndef CLONEWIZARDPAGE_H +#define CLONEWIZARDPAGE_H + +#include <vcsbase/basecheckoutwizardpage.h> + +namespace Git { +namespace Internal { + +class CloneWizardPage : public VCSBase::BaseCheckoutWizardPage +{ + Q_OBJECT +public: + CloneWizardPage(QWidget *parent = 0); + +protected: + virtual QString directoryFromRepository(const QString &r) const; + +private: + const QString m_mainLinePostfix; + const QString m_gitPostFix; + const QString m_protocolDelimiter; +}; + +} // namespace Internal +} // namespace Git +#endif // CLONEWIZARDPAGE_H + diff --git a/src/plugins/git/git.pro b/src/plugins/git/git.pro index 8b9a6171e8865d2c75e45903bd4248efe9b4ce5b..618b7810b4ead3df8d0a87aa4086a1311a6698a1 100644 --- a/src/plugins/git/git.pro +++ b/src/plugins/git/git.pro @@ -21,7 +21,9 @@ HEADERS += gitplugin.h \ gitsettings.h \ branchdialog.h \ branchmodel.h \ - gitcommand.h + gitcommand.h \ + clonewizard.h \ + clonewizardpage.h SOURCES += gitplugin.cpp \ gitoutputwindow.cpp \ gitclient.cpp \ @@ -36,7 +38,9 @@ SOURCES += gitplugin.cpp \ gitsettings.cpp \ branchdialog.cpp \ branchmodel.cpp \ - gitcommand.cpp + gitcommand.cpp \ + clonewizard.cpp \ + clonewizardpage.cpp FORMS += changeselectiondialog.ui \ settingspage.ui \ gitsubmitpanel.ui \ diff --git a/src/plugins/git/gitclient.cpp b/src/plugins/git/gitclient.cpp index 0486522fd1ea32aebdde081734a24775cc116c11..6b900a5d8f54f0e011181281f2c459e99f25e756 100644 --- a/src/plugins/git/gitclient.cpp +++ b/src/plugins/git/gitclient.cpp @@ -480,11 +480,7 @@ GitCommand *GitClient::createCommand(const QString &workingDirectory, GitOutputWindow *outputWindow = m_plugin->outputWindow(); - ProjectExplorer::Environment environment = ProjectExplorer::Environment::systemEnvironment(); - if (m_settings.adoptPath) - environment.set(QLatin1String("PATH"), m_settings.path); - - GitCommand* command = new GitCommand(m_binaryPath, workingDirectory, environment); + GitCommand* command = new GitCommand(binary(), workingDirectory, processEnvironment()); if (outputToWindow) { if (!editor) { // assume that the commands output is the important thing connect(command, SIGNAL(outputData(QByteArray)), this, SLOT(appendDataAndPopup(QByteArray))); @@ -527,6 +523,26 @@ void GitClient::appendAndPopup(const QString &text) m_plugin->outputWindow()->popup(false); } +// Return fixed arguments required to run +QStringList GitClient::binary() const +{ +#ifdef Q_OS_WIN + QStringList args; + args << QLatin1String("cmd.exe") << QLatin1String("/c") << m_binaryPath; + return args; +#else + return QStringList(m_binaryPath); +#endif +} + +QStringList GitClient::processEnvironment() const +{ + ProjectExplorer::Environment environment = ProjectExplorer::Environment::systemEnvironment(); + if (m_settings.adoptPath) + environment.set(QLatin1String("PATH"), m_settings.path); + return environment.toStringList(); +} + bool GitClient::synchronousGit(const QString &workingDirectory, const QStringList &arguments, QByteArray* outputText, @@ -541,19 +557,13 @@ bool GitClient::synchronousGit(const QString &workingDirectory, QProcess process; process.setWorkingDirectory(workingDirectory); + process.setEnvironment(processEnvironment()); - ProjectExplorer::Environment environment = ProjectExplorer::Environment::systemEnvironment(); - if (m_settings.adoptPath) - environment.set(QLatin1String("PATH"), m_settings.path); - process.setEnvironment(environment.toStringList()); - -#ifdef Q_OS_WIN - QStringList args; - args << "/c" << m_binaryPath << arguments; - process.start(QLatin1String("cmd.exe"), args); -#else - process.start(m_binaryPath, arguments); -#endif + QStringList args = binary(); + const QString executable = args.front(); + args.pop_front(); + args.append(arguments); + process.start(executable, arguments); process.closeWriteChannel(); if (!process.waitForFinished()) { diff --git a/src/plugins/git/gitclient.h b/src/plugins/git/gitclient.h index ce65fd778654c044eb4236425199089ce483fda0..cfe14269671ca5f52ad1035d86cd9c513e4c7fbc 100644 --- a/src/plugins/git/gitclient.h +++ b/src/plugins/git/gitclient.h @@ -135,6 +135,9 @@ public: GitSettings settings() const; void setSettings(const GitSettings &s); + QStringList binary() const; // Executable + basic arguments + QStringList processEnvironment() const; + static QString msgNoChangedFiles(); static const char *noColorOption; diff --git a/src/plugins/git/gitcommand.cpp b/src/plugins/git/gitcommand.cpp index 7e16fc3864e1a49aaf2221ddbfcc67aae7696024..6374328633dde0cdf2cc5949ca95bbb12abf76e7 100644 --- a/src/plugins/git/gitcommand.cpp +++ b/src/plugins/git/gitcommand.cpp @@ -44,15 +44,6 @@ namespace Git { namespace Internal { -// Convert environment to list, default to system one. -static inline QStringList environmentToList(const ProjectExplorer::Environment &environment) -{ - const QStringList list = environment.toStringList(); - if (!list.empty()) - return list; - return ProjectExplorer::Environment::systemEnvironment().toStringList(); -} - static QString msgTermination(int exitCode, const QString &binaryPath, const QStringList &args) { QString cmd = QFileInfo(binaryPath).baseName(); @@ -71,14 +62,16 @@ GitCommand::Job::Job(const QStringList &a, int t) : { } -GitCommand::GitCommand(const QString &binaryPath, - const QString &workingDirectory, - ProjectExplorer::Environment &environment) : - m_binaryPath(binaryPath), +GitCommand::GitCommand(const QStringList &binary, + const QString &workingDirectory, + const QStringList &environment) : + m_binaryPath(binary.front()), + m_basicArguments(binary), m_workingDirectory(workingDirectory), - m_environment(environmentToList(environment)), + m_environment(environment), m_reportTerminationMode(NoReport) { + m_basicArguments.pop_front(); } GitCommand::TerminationReportMode GitCommand::reportTerminationMode() const @@ -132,13 +125,7 @@ void GitCommand::run() if (Git::Constants::debug) qDebug() << "GitCommand::run" << j << '/' << count << m_jobs.at(j).arguments; -#ifdef Q_OS_WIN - QStringList args; - args << "/c" << m_binaryPath << m_jobs.at(j).arguments; - process.start(QLatin1String("cmd.exe"), args); -#else - process.start(m_binaryPath, m_jobs.at(j).arguments); -#endif + process.start(m_binaryPath, m_basicArguments + m_jobs.at(j).arguments); if(!process.waitForStarted()) { ok = false; error += QString::fromLatin1("Error: \"%1\" could not be started: %2").arg(m_binaryPath, process.errorString()); diff --git a/src/plugins/git/gitcommand.h b/src/plugins/git/gitcommand.h index a9c95bd6634439c3cb431e5b302e8cd789a936d6..e589789b39b13fad07e7b66ef09cd472ce25cbb7 100644 --- a/src/plugins/git/gitcommand.h +++ b/src/plugins/git/gitcommand.h @@ -30,9 +30,8 @@ #ifndef GITCOMMAND_H #define GITCOMMAND_H -#include <projectexplorer/environment.h> - #include <QtCore/QObject> +#include <QtCore/QStringList> namespace Git { namespace Internal { @@ -47,9 +46,9 @@ public: ReportStdout, // This assumes UTF8 ReportStderr }; - explicit GitCommand(const QString &binaryPath, + explicit GitCommand(const QStringList &binary, const QString &workingDirectory, - ProjectExplorer::Environment &environment); + const QStringList &environment); void addJob(const QStringList &arguments, int timeout); @@ -79,6 +78,7 @@ private: }; const QString m_binaryPath; + QStringList m_basicArguments; const QString m_workingDirectory; const QStringList m_environment; diff --git a/src/plugins/git/gitplugin.cpp b/src/plugins/git/gitplugin.cpp index 90f19261940a2c728bea8ac62dfa90dec8d56499..8359329819a38aba6ae55a4676d6ee9a6d883552 100644 --- a/src/plugins/git/gitplugin.cpp +++ b/src/plugins/git/gitplugin.cpp @@ -37,6 +37,7 @@ #include "gitsubmiteditor.h" #include "gitversioncontrol.h" #include "branchdialog.h" +#include "clonewizard.h" #include <coreplugin/icore.h> #include <coreplugin/coreconstants.h> @@ -139,10 +140,6 @@ GitPlugin::GitPlugin() : m_gitClient(0), m_outputWindow(0), m_changeSelectionDialog(0), - m_settingsPage(0), - m_coreListener(0), - m_submitEditorFactory(0), - m_versionControl(0), m_changeTmpFile(0), m_submitActionTriggered(false) { @@ -151,42 +148,6 @@ GitPlugin::GitPlugin() : GitPlugin::~GitPlugin() { - if (m_outputWindow) { - removeObject(m_outputWindow); - delete m_outputWindow; - m_outputWindow = 0; - } - - if (m_settingsPage) { - removeObject(m_settingsPage); - delete m_settingsPage; - m_settingsPage = 0; - } - - if (!m_editorFactories.empty()) { - foreach (Core::IEditorFactory* pf, m_editorFactories) - removeObject(pf); - qDeleteAll(m_editorFactories); - } - - if (m_coreListener) { - removeObject(m_coreListener); - delete m_coreListener; - m_coreListener = 0; - } - - if (m_submitEditorFactory) { - removeObject(m_submitEditorFactory); - delete m_submitEditorFactory; - m_submitEditorFactory = 0; - } - - if (m_versionControl) { - removeObject(m_versionControl); - delete m_versionControl; - m_versionControl = 0; - } - cleanChangeTmpFile(); delete m_gitClient; m_instance = 0; @@ -231,33 +192,30 @@ bool GitPlugin::initialize(const QStringList &arguments, QString *errorMessage) m_core = Core::ICore::instance(); m_gitClient = new GitClient(this); - // Create the globalcontext list to register actions accordingly + // Create the globalco6664324b12a3339d18251df1cd69a1da06d1e2dcntext list to register actions accordingly QList<int> globalcontext; globalcontext << m_core->uniqueIDManager()->uniqueIdentifier(Core::Constants::C_GLOBAL); // Create the output Window m_outputWindow = new GitOutputWindow(); - addObject(m_outputWindow); + addAutoReleasedObject(m_outputWindow); // Create the settings Page - m_settingsPage = new SettingsPage(); - addObject(m_settingsPage); + addAutoReleasedObject(new SettingsPage()); static const char *describeSlot = SLOT(show(QString,QString)); const int editorCount = sizeof(editorParameters)/sizeof(VCSBase::VCSBaseEditorParameters); - for (int i = 0; i < editorCount; i++) { - m_editorFactories.push_back(new GitEditorFactory(editorParameters + i, m_gitClient, describeSlot)); - addObject(m_editorFactories.back()); - } + for (int i = 0; i < editorCount; i++) + addAutoReleasedObject(new GitEditorFactory(editorParameters + i, m_gitClient, describeSlot)); - m_coreListener = new CoreListener(this); - addObject(m_coreListener); + addAutoReleasedObject(new CoreListener(this)); - m_submitEditorFactory = new GitSubmitEditorFactory(&submitParameters); - addObject(m_submitEditorFactory); + addAutoReleasedObject(new GitSubmitEditorFactory(&submitParameters)); - m_versionControl = new GitVersionControl(m_gitClient); - addObject(m_versionControl); + GitVersionControl *versionControl = new GitVersionControl(m_gitClient); + addAutoReleasedObject(versionControl); + + addAutoReleasedObject(new CloneWizard); //register actions Core::ActionManager *actionManager = m_core->actionManager(); @@ -270,8 +228,8 @@ bool GitPlugin::initialize(const QStringList &arguments, QString *errorMessage) gitContainer->menu()->setTitle(tr("&Git")); toolsContainer->addMenu(gitContainer); if (QAction *ma = gitContainer->menu()->menuAction()) { - ma->setEnabled(m_versionControl->isEnabled()); - connect(m_versionControl, SIGNAL(enabledChanged(bool)), ma, SLOT(setVisible(bool))); + ma->setEnabled(versionControl->isEnabled()); + connect(versionControl, SIGNAL(enabledChanged(bool)), ma, SLOT(setVisible(bool))); } Core::Command *command; @@ -888,4 +846,9 @@ void GitPlugin::setSettings(const GitSettings &s) m_gitClient->setSettings(s); } +GitClient *GitPlugin::gitClient() const +{ + return m_gitClient; +} + Q_EXPORT_PLUGIN(GitPlugin) diff --git a/src/plugins/git/gitplugin.h b/src/plugins/git/gitplugin.h index d5c935a55584d3f9390f537a8b923375e92b2040..d473697cd91474d37420454db8fd590bf01dd42d 100644 --- a/src/plugins/git/gitplugin.h +++ b/src/plugins/git/gitplugin.h @@ -96,10 +96,11 @@ public: GitOutputWindow *outputWindow() const; - GitSettings settings() const; void setSettings(const GitSettings &s); + GitClient *gitClient() const; + public slots: void updateActions(); bool editorAboutToClose(Core::IEditor *editor); @@ -166,11 +167,6 @@ private: GitClient *m_gitClient; GitOutputWindow *m_outputWindow; ChangeSelectionDialog *m_changeSelectionDialog; - SettingsPage *m_settingsPage; - QList<Core::IEditorFactory*> m_editorFactories; - CoreListener *m_coreListener; - Core::IEditorFactory *m_submitEditorFactory; - Core::IVersionControl *m_versionControl; QString m_submitRepository; QStringList m_submitOrigCommitFiles; QStringList m_submitOrigDeleteFiles; diff --git a/src/plugins/help/helpplugin.cpp b/src/plugins/help/helpplugin.cpp index fb1f5cf1bb0c387f71ebb400f877f9e959ecc94b..295e59fae2914a858b8eb482ba06db4dd5d1df01 100644 --- a/src/plugins/help/helpplugin.cpp +++ b/src/plugins/help/helpplugin.cpp @@ -57,6 +57,8 @@ #include <texteditor/texteditorconstants.h> +#include <utils/styledbar.h> + #include <QtCore/QDebug> #include <QtCore/qplugin.h> #include <QtCore/QFileInfo> @@ -448,25 +450,23 @@ void HelpPlugin::createRightPaneSideBar() SLOT(rightPaneForward())); QToolButton *closeButton = new QToolButton(); - closeButton->setProperty("type", QLatin1String("dockbutton")); closeButton->setIcon(QIcon(":/core/images/closebutton.png")); // Dummy layout to align the close button to the right QHBoxLayout *hboxLayout = new QHBoxLayout(); hboxLayout->setSpacing(0); hboxLayout->setMargin(0); + hboxLayout->addWidget(rightPaneToolBar); hboxLayout->addStretch(5); hboxLayout->addWidget(closeButton); - - QWidget *w = new QWidget(rightPaneToolBar); + Core::Utils::StyledBar *w = new Core::Utils::StyledBar; w->setLayout(hboxLayout); - rightPaneToolBar->addWidget(w); connect(closeButton, SIGNAL(clicked()), this, SLOT(slotHideRightPane())); QVBoxLayout *rightPaneLayout = new QVBoxLayout; rightPaneLayout->setMargin(0); rightPaneLayout->setSpacing(0); - rightPaneLayout->addWidget(rightPaneToolBar); + rightPaneLayout->addWidget(w); m_helpViewerForSideBar = new HelpViewer(m_helpEngine, 0); Aggregation::Aggregate *agg = new Aggregation::Aggregate(); diff --git a/src/plugins/projectexplorer/buildmanager.cpp b/src/plugins/projectexplorer/buildmanager.cpp index 461cfef6243e4863e5119ba9661c01eb5baaf0cf..6679199ead6773464231b0f2a87540e09d6b823d 100644 --- a/src/plugins/projectexplorer/buildmanager.cpp +++ b/src/plugins/projectexplorer/buildmanager.cpp @@ -333,6 +333,8 @@ void BuildManager::buildProjects(const QList<Project *> &projects, const QList<Q } } startBuildQueue(); + if (ProjectExplorerPlugin::instance()->projectExplorerSettings().showCompilerOutput) + m_outputWindow->popup(false); } void BuildManager::cleanProjects(const QList<Project *> &projects, const QList<QString> &configurations) @@ -349,6 +351,8 @@ void BuildManager::cleanProjects(const QList<Project *> &projects, const QList<Q } } startBuildQueue(); + if (ProjectExplorerPlugin::instance()->projectExplorerSettings().showCompilerOutput) + m_outputWindow->popup(false); } void BuildManager::buildProject(Project *p, const QString &configuration) diff --git a/src/plugins/projectexplorer/buildsettingspropertiespage.cpp b/src/plugins/projectexplorer/buildsettingspropertiespage.cpp index cc8311357dff79f65b2a488543e8127805951276..980b7ba4ec25b3d1f21fe9bbe0cd26e89797f88b 100644 --- a/src/plugins/projectexplorer/buildsettingspropertiespage.cpp +++ b/src/plugins/projectexplorer/buildsettingspropertiespage.cpp @@ -36,11 +36,10 @@ #include <extensionsystem/pluginmanager.h> #include <QtCore/QDebug> -#include <QtCore/QHash> #include <QtCore/QPair> #include <QtGui/QInputDialog> #include <QtGui/QLabel> -#include <QtGui/QMenu> +#include <QtGui/QVBoxLayout> using namespace ProjectExplorer; using namespace ProjectExplorer::Internal; @@ -84,6 +83,48 @@ QWidget *BuildSettingsPanel::widget() return m_widget; } +/// +// BuildSettingsSubWidgets +/// + +BuildSettingsSubWidgets::~BuildSettingsSubWidgets() +{ + clear(); +} + +void BuildSettingsSubWidgets::addWidget(const QString &name, QWidget *widget) +{ + QLabel *label = new QLabel(this); + label->setText(name); + QFont f = label->font(); + f.setBold(true); + f.setPointSizeF(f.pointSizeF() *1.2); + label->setFont(f); + + layout()->addWidget(label); + layout()->addWidget(widget); + + m_labels.append(label); + m_widgets.append(widget); +} + +void BuildSettingsSubWidgets::clear() +{ + qDeleteAll(m_widgets); + qDeleteAll(m_labels); +} + +QList<QWidget *> BuildSettingsSubWidgets::widgets() const +{ + return m_widgets; +} + +BuildSettingsSubWidgets::BuildSettingsSubWidgets(QWidget *parent) + : QGroupBox(parent) +{ + new QVBoxLayout(this); +} + /// /// BuildSettingsWidget /// @@ -95,62 +136,60 @@ BuildSettingsWidget::~BuildSettingsWidget() BuildSettingsWidget::BuildSettingsWidget(Project *project) : m_project(project) { - m_ui.setupUi(this); - m_ui.splitter->setStretchFactor(1,10); - m_ui.buildSettingsList->setContextMenuPolicy(Qt::CustomContextMenu); - - m_ui.addButton->setIcon(QIcon(Core::Constants::ICON_PLUS)); - m_ui.addButton->setText(""); - m_ui.removeButton->setIcon(QIcon(Core::Constants::ICON_MINUS)); - m_ui.removeButton->setText(""); + QVBoxLayout *vbox = new QVBoxLayout(this); + QHBoxLayout *hbox = new QHBoxLayout(); + hbox->addWidget(new QLabel(tr("Build Configuration:"), this)); + m_buildConfigurationComboBox = new QComboBox(this); + hbox->addWidget(m_buildConfigurationComboBox); + + m_addButton = new QPushButton(this); + m_addButton->setText("Add"); + m_addButton->setIcon(QIcon(Core::Constants::ICON_PLUS)); + m_addButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + hbox->addWidget(m_addButton); + + m_removeButton = new QPushButton(this); + m_removeButton->setText("Remove"); + m_removeButton->setIcon(QIcon(Core::Constants::ICON_MINUS)); + m_removeButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + hbox->addWidget(m_removeButton); + hbox->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Fixed)); + vbox->addLayout(hbox); + + m_subWidgets = new BuildSettingsSubWidgets(this); + vbox->addWidget(m_subWidgets); QMenu *addButtonMenu = new QMenu(this); addButtonMenu->addAction(tr("Create &New"), this, SLOT(createConfiguration())); addButtonMenu->addAction(tr("&Clone Selected"), this, SLOT(cloneConfiguration())); - m_ui.addButton->setMenu(addButtonMenu); + m_addButton->setMenu(addButtonMenu); + connect(m_buildConfigurationComboBox, SIGNAL(currentIndexChanged(int)), + this, SLOT(currentIndexChanged(int))); - connect(m_ui.buildSettingsList, SIGNAL(currentItemChanged(QTreeWidgetItem *, QTreeWidgetItem *)), - this, SLOT(updateSettingsWidget(QTreeWidgetItem *, QTreeWidgetItem *))); - connect(m_ui.buildSettingsList, SIGNAL(customContextMenuRequested (const QPoint &) ), - this, SLOT(showContextMenu(const QPoint &))); - connect(m_ui.buildSettingsList, SIGNAL(itemChanged(QTreeWidgetItem*,int) ), - this, SLOT(itemChanged(QTreeWidgetItem*)), Qt::QueuedConnection); + // TODO currentIndexChanged + // needs to change active configuration + // and set widgets - connect(m_ui.removeButton, SIGNAL(clicked()), + connect(m_removeButton, SIGNAL(clicked()), this, SLOT(deleteConfiguration())); connect(m_project, SIGNAL(activeBuildConfigurationChanged()), - this, SLOT(updateBuildSettings())); + this, SLOT(activeBuildConfigurationChanged())); connect(m_project, SIGNAL(buildConfigurationDisplayNameChanged(const QString &)), this, SLOT(buildConfigurationDisplayNameChanged(const QString &))); - - // remove dummy designer widget - while (QWidget *widget = m_ui.buildSettingsWidgets->currentWidget()) { - m_ui.buildSettingsWidgets->removeWidget(widget); - delete widget; - } - updateBuildSettings(); } void BuildSettingsWidget::buildConfigurationDisplayNameChanged(const QString &buildConfiguration) { - QTreeWidgetItem *rootItem = m_ui.buildSettingsList->invisibleRootItem(); - for (int i = 0; i < rootItem->childCount(); ++i) { - QTreeWidgetItem *child = rootItem->child(i); - if (child->data(0, Qt::UserRole).toString() == buildConfiguration) { - child->setText(0, m_project->displayNameFor(buildConfiguration)); - if (m_ui.buildSettingsList->currentItem() == child) { - QWidget *widget = m_itemToWidget.value(child); - if (BuildStepConfigWidget *buildStepWidget = qobject_cast<BuildStepConfigWidget*>(widget)) { - QString title; - title = buildStepWidget->displayName(); - m_ui.titleLabel->setText(tr("%1 - %2").arg(m_project->displayNameFor(buildConfiguration)).arg(title)); - } - } + + for (int i=0; i<m_buildConfigurationComboBox->count(); ++i) { + if (m_buildConfigurationComboBox->itemData(i).toString() == buildConfiguration) { + m_buildConfigurationComboBox->setItemText(i, m_project->displayNameFor(buildConfiguration)); + break; } } } @@ -158,180 +197,64 @@ void BuildSettingsWidget::buildConfigurationDisplayNameChanged(const QString &bu void BuildSettingsWidget::updateBuildSettings() { - QTreeWidgetItem *rootItem = m_ui.buildSettingsList->invisibleRootItem(); - // update buttons - m_ui.removeButton->setEnabled(m_project->buildConfigurations().size() > 1); - - // Save current selection - QString lastCurrentItem; - if (m_ui.buildSettingsList->currentItem()) - lastCurrentItem = m_ui.buildSettingsList->currentItem()->text(0); - - m_itemToWidget.clear(); + // TODO save position, entry from combbox // Delete old tree items - while (rootItem->childCount()) { - QTreeWidgetItem *configPageItem = rootItem->child(0); - rootItem->removeChild(configPageItem); - delete configPageItem; // does that delete also subitems? - } + m_buildConfigurationComboBox->blockSignals(true); // TODO ... + m_buildConfigurationComboBox->clear(); + m_subWidgets->clear(); - // Delete old pages - while (m_ui.buildSettingsWidgets->count()) { - QWidget *w = m_ui.buildSettingsWidgets->widget(0); - m_ui.buildSettingsWidgets->removeWidget(w); - delete w; - } + // update buttons + m_removeButton->setEnabled(m_project->buildConfigurations().size() > 1); // Add pages - QWidget *dummyWidget = new QWidget(this); - QWidget *buildStepsWidget = new BuildStepsPage(m_project); - QWidget *cleanStepsWidget = new BuildStepsPage(m_project, true); BuildStepConfigWidget *generalConfigWidget = m_project->createConfigWidget(); - QList<BuildStepConfigWidget *> subConfigWidgets = m_project->subConfigWidgets(); + m_subWidgets->addWidget(generalConfigWidget->displayName(), generalConfigWidget); + + m_subWidgets->addWidget(tr("Build Steps"), new BuildStepsPage(m_project)); + m_subWidgets->addWidget(tr("Clean Steps"), new BuildStepsPage(m_project, true)); - m_ui.buildSettingsWidgets->addWidget(dummyWidget); - m_ui.buildSettingsWidgets->addWidget(buildStepsWidget); - m_ui.buildSettingsWidgets->addWidget(cleanStepsWidget); - m_ui.buildSettingsWidgets->addWidget(generalConfigWidget); + QList<BuildStepConfigWidget *> subConfigWidgets = m_project->subConfigWidgets(); foreach (BuildStepConfigWidget *subConfigWidget, subConfigWidgets) - m_ui.buildSettingsWidgets->addWidget(subConfigWidget); + m_subWidgets->addWidget(subConfigWidget->displayName(), subConfigWidget); // Add tree items - QTreeWidgetItem *activeConfigurationItem = 0; QString activeBuildConfiguration = m_project->activeBuildConfiguration(); foreach (const QString &buildConfiguration, m_project->buildConfigurations()) { - QString displayName = m_project->displayNameFor(buildConfiguration); - QTreeWidgetItem *buildConfigItem = new QTreeWidgetItem(); - m_itemToWidget.insert(buildConfigItem, generalConfigWidget); - buildConfigItem->setText(0, displayName); - buildConfigItem->setData(0, Qt::UserRole, buildConfiguration); - buildConfigItem->setCheckState(0, Qt::Unchecked); - if (activeBuildConfiguration == buildConfiguration) { - QFont font = buildConfigItem->font(0); - font.setBold(true); - buildConfigItem->setFont(0, font); - buildConfigItem->setCheckState(0, Qt::Checked); - - activeConfigurationItem = buildConfigItem; - } - rootItem->addChild(buildConfigItem); - - QTreeWidgetItem *generalItem = new QTreeWidgetItem(); - m_itemToWidget.insert(generalItem, generalConfigWidget); - generalItem->setText(0, tr("General")); - buildConfigItem->addChild(generalItem); - - foreach (BuildStepConfigWidget *subConfigWidget, subConfigWidgets) { - QTreeWidgetItem *subConfigItem = new QTreeWidgetItem(); - m_itemToWidget.insert(subConfigItem, subConfigWidget); - subConfigItem->setText(0, subConfigWidget->displayName()); - buildConfigItem->addChild(subConfigItem); - } - - QTreeWidgetItem *buildStepsItem = new QTreeWidgetItem(); - m_itemToWidget.insert(buildStepsItem, buildStepsWidget); - buildStepsItem->setText(0, tr("Build Steps")); - buildConfigItem->addChild(buildStepsItem); - - QTreeWidgetItem *cleanStepsItem = new QTreeWidgetItem(); - m_itemToWidget.insert(cleanStepsItem, cleanStepsWidget); - cleanStepsItem->setText(0, tr("Clean Steps")); - buildConfigItem->addChild(cleanStepsItem); + m_buildConfigurationComboBox->addItem(m_project->displayNameFor(buildConfiguration), buildConfiguration); + if (buildConfiguration == activeBuildConfiguration) + m_buildConfigurationComboBox->setCurrentIndex(m_buildConfigurationComboBox->count() - 1); } - m_ui.buildSettingsList->expandAll(); + // TODO ... + m_buildConfigurationComboBox->blockSignals(false); - // Restore selection - if (!lastCurrentItem.isEmpty()) { - for (int i = rootItem->childCount() - 1; i >= 0; --i) { - if (rootItem->child(i)->text(0) == lastCurrentItem) { - m_ui.buildSettingsList->setCurrentItem(rootItem->child(i)); - break; - } - } - } - - if (!m_ui.buildSettingsList->currentItem()) { - if (activeConfigurationItem) - m_ui.buildSettingsList->setCurrentItem(activeConfigurationItem); - else - m_ui.buildSettingsList->setCurrentItem(m_ui.buildSettingsList->invisibleRootItem()->child(0)); - } + // TODO Restore position, entry from combbox + // TODO? select entry from combobox ? + activeBuildConfigurationChanged(); } -/* switch from one tree item / build step to another */ -void BuildSettingsWidget::updateSettingsWidget(QTreeWidgetItem *newItem, QTreeWidgetItem *oldItem) +void BuildSettingsWidget::currentIndexChanged(int index) { - if (oldItem == newItem) - return; - - if (!newItem) { - QWidget *dummyWidget = m_ui.buildSettingsWidgets->widget(0); - m_ui.buildSettingsWidgets->setCurrentWidget(dummyWidget); - m_ui.titleLabel->clear(); - return; - } - - if (QWidget *widget = m_itemToWidget.value(newItem)) { - QString buildConfiguration; - { - QTreeWidgetItem *configurationItem = newItem; - while (configurationItem && configurationItem->parent()) - configurationItem = configurationItem->parent(); - if (configurationItem) - buildConfiguration = configurationItem->data(0, Qt::UserRole).toString(); - } - - QString title; - if (BuildStepConfigWidget *buildStepWidget = qobject_cast<BuildStepConfigWidget*>(widget)) { - title = buildStepWidget->displayName(); - buildStepWidget->init(buildConfiguration); - } - - m_ui.titleLabel->setText(tr("%1 - %2").arg(m_project->displayNameFor(buildConfiguration)).arg(title)); - m_ui.buildSettingsWidgets->setCurrentWidget(widget); - } + QString buildConfiguration = m_buildConfigurationComboBox->itemData(index).toString(); + m_project->setActiveBuildConfiguration(buildConfiguration); } - -void BuildSettingsWidget::showContextMenu(const QPoint &point) +void BuildSettingsWidget::activeBuildConfigurationChanged() { - if (QTreeWidgetItem *item = m_ui.buildSettingsList->itemAt(point)) { - if (!item->parent()) { - const QString buildConfiguration = item->data(0, Qt::UserRole).toString(); - - QMenu menu; - QAction *setAsActiveAction = new QAction(tr("Set as Active"), &menu); - QAction *cloneAction = new QAction(tr("Clone"), &menu); - QAction *deleteAction = new QAction(tr("Delete"), &menu); - - if (m_project->activeBuildConfiguration() == buildConfiguration) - setAsActiveAction->setEnabled(false); - if (m_project->buildConfigurations().size() < 2) - deleteAction->setEnabled(false); - - menu.addActions(QList<QAction*>() << setAsActiveAction << cloneAction << deleteAction); - QPoint globalPoint = m_ui.buildSettingsList->mapToGlobal(point); - QAction *action = menu.exec(globalPoint); - if (action == setAsActiveAction) { - setActiveConfiguration(buildConfiguration); - } else if (action == cloneAction) { - cloneConfiguration(buildConfiguration); - } else if (action == deleteAction) { - deleteConfiguration(buildConfiguration); - } - - updateBuildSettings(); + const QString &activeBuildConfiguration = m_project->activeBuildConfiguration(); + for (int i = 0; i < m_buildConfigurationComboBox->count(); ++i) { + if (m_buildConfigurationComboBox->itemData(i).toString() == activeBuildConfiguration) { + m_buildConfigurationComboBox->setCurrentIndex(i); + break; + } + } + foreach (QWidget *widget, m_subWidgets->widgets()) { + if (BuildStepConfigWidget *buildStepWidget = qobject_cast<BuildStepConfigWidget*>(widget)) { + buildStepWidget->init(activeBuildConfiguration); } } -} - -void BuildSettingsWidget::setActiveConfiguration() -{ - const QString configuration = m_ui.buildSettingsList->currentItem()->data(0, Qt::UserRole).toString(); - setActiveConfiguration(configuration); } void BuildSettingsWidget::createConfiguration() @@ -373,40 +296,16 @@ void BuildSettingsWidget::createConfiguration() void BuildSettingsWidget::cloneConfiguration() { - QTreeWidgetItem *configItem = m_ui.buildSettingsList->currentItem(); - while (configItem->parent()) - configItem = configItem->parent(); - const QString configuration = configItem->data(0, Qt::UserRole).toString(); + const QString configuration = m_buildConfigurationComboBox->itemData(m_buildConfigurationComboBox->currentIndex()).toString(); cloneConfiguration(configuration); } void BuildSettingsWidget::deleteConfiguration() { - QTreeWidgetItem *configItem = m_ui.buildSettingsList->currentItem(); - while (configItem->parent()) - configItem = configItem->parent(); - const QString configuration = configItem->data(0, Qt::UserRole).toString(); + const QString configuration = m_buildConfigurationComboBox->itemData(m_buildConfigurationComboBox->currentIndex()).toString(); deleteConfiguration(configuration); } -void BuildSettingsWidget::itemChanged(QTreeWidgetItem *item) -{ - // do not allow unchecking - if (item->checkState(0) == Qt::Unchecked) - item->setCheckState(0, Qt::Checked); - else { - setActiveConfiguration(item->data(0, Qt::UserRole).toString()); - } -} - -void BuildSettingsWidget::setActiveConfiguration(const QString &configuration) -{ - if (configuration.isEmpty()) - return; - - m_project->setActiveBuildConfiguration(configuration); -} - void BuildSettingsWidget::cloneConfiguration(const QString &sourceConfiguration) { if (sourceConfiguration.isEmpty()) @@ -440,9 +339,10 @@ void BuildSettingsWidget::cloneConfiguration(const QString &sourceConfiguration) m_project->copyBuildConfiguration(sourceConfiguration, newBuildConfiguration); m_project->setDisplayNameFor(newBuildConfiguration, newDisplayName); - m_project->setActiveBuildConfiguration(newBuildConfiguration); updateBuildSettings(); + + m_project->setActiveBuildConfiguration(newBuildConfiguration); } void BuildSettingsWidget::deleteConfiguration(const QString &deleteConfiguration) diff --git a/src/plugins/projectexplorer/buildsettingspropertiespage.h b/src/plugins/projectexplorer/buildsettingspropertiespage.h index 378ddcbe24e8f993cac0b0f2c81974cd0d045e99..9fe45659bad08cc49bc4a6ffa683708adef24ae6 100644 --- a/src/plugins/projectexplorer/buildsettingspropertiespage.h +++ b/src/plugins/projectexplorer/buildsettingspropertiespage.h @@ -31,7 +31,12 @@ #define BUILDSETTINGSPROPERTIESPAGE_H #include "iprojectproperties.h" -#include "ui_buildsettingspropertiespage.h" + +#include <QtCore/QHash> +#include <QtGui/QComboBox> +#include <QtGui/QPushButton> +#include <QtGui/QLabel> +#include <QtGui/QGroupBox> namespace ProjectExplorer { @@ -39,6 +44,20 @@ class IBuildStepFactory; namespace Internal { +class BuildSettingsSubWidgets : public QGroupBox +{ + Q_OBJECT +public: + BuildSettingsSubWidgets(QWidget *parent); + ~BuildSettingsSubWidgets(); + void clear(); + void addWidget(const QString &name, QWidget *widget); + QList<QWidget *> widgets() const; +private: + QList<QWidget *> m_widgets; + QList<QLabel *> m_labels; +}; + class BuildSettingsPanelFactory : public IPanelFactory { public: @@ -73,24 +92,24 @@ public: private slots: void buildConfigurationDisplayNameChanged(const QString &buildConfiguration); void updateBuildSettings(); - void updateSettingsWidget(QTreeWidgetItem *newItem, QTreeWidgetItem *oldItem); - void showContextMenu(const QPoint & pos); + void currentIndexChanged(int index); + void activeBuildConfigurationChanged(); - void setActiveConfiguration(); void createConfiguration(); void cloneConfiguration(); void deleteConfiguration(); - void itemChanged(QTreeWidgetItem *item); private: void setActiveConfiguration(const QString &configuration); void cloneConfiguration(const QString &toClone); void deleteConfiguration(const QString &toDelete); - Ui::BuildSettingsPropertiesPage m_ui; Project *m_project; - QHash<QTreeWidgetItem*, QWidget*> m_itemToWidget; + QPushButton *m_addButton; + QPushButton *m_removeButton; + QComboBox *m_buildConfigurationComboBox; + BuildSettingsSubWidgets *m_subWidgets; }; } // namespace Internal diff --git a/src/plugins/projectexplorer/buildsettingspropertiespage.ui b/src/plugins/projectexplorer/buildsettingspropertiespage.ui deleted file mode 100644 index 3fabbcea90e0830eb69b4e23fc353b883a43c153..0000000000000000000000000000000000000000 --- a/src/plugins/projectexplorer/buildsettingspropertiespage.ui +++ /dev/null @@ -1,184 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<ui version="4.0"> - <class>ProjectExplorer::Internal::BuildSettingsPropertiesPage</class> - <widget class="QWidget" name="ProjectExplorer::Internal::BuildSettingsPropertiesPage"> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>799</width> - <height>525</height> - </rect> - </property> - <layout class="QHBoxLayout" name="horizontalLayout_4"> - <item> - <widget class="QSplitter" name="splitter"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <widget class="QWidget" name="layoutWidget1"> - <layout class="QVBoxLayout" name="verticalLayout_2" stretch="100,1,0"> - <item> - <widget class="QTreeWidget" name="buildSettingsList"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Preferred" vsizetype="Expanding"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="maximumSize"> - <size> - <width>16777215</width> - <height>800</height> - </size> - </property> - <property name="rootIsDecorated"> - <bool>false</bool> - </property> - <property name="uniformRowHeights"> - <bool>true</bool> - </property> - <property name="itemsExpandable"> - <bool>false</bool> - </property> - <property name="headerHidden"> - <bool>true</bool> - </property> - <property name="expandsOnDoubleClick"> - <bool>false</bool> - </property> - <attribute name="headerVisible"> - <bool>false</bool> - </attribute> - <column> - <property name="text"> - <string>Configurations</string> - </property> - </column> - </widget> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_3"> - <item> - <spacer name="horizontalSpacer"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>40</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - <item> - <widget class="QPushButton" name="addButton"> - <property name="text"> - <string>+</string> - </property> - </widget> - </item> - <item> - <widget class="QPushButton" name="removeButton"> - <property name="text"> - <string>-</string> - </property> - </widget> - </item> - </layout> - </item> - <item> - <spacer name="verticalSpacer"> - <property name="orientation"> - <enum>Qt::Vertical</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>20</width> - <height>0</height> - </size> - </property> - </spacer> - </item> - </layout> - </widget> - <widget class="QWidget" name="layoutWidget2"> - <layout class="QVBoxLayout" name="verticalLayout"> - <item> - <layout class="QHBoxLayout" name="horizontalLayout" stretch="0,0"> - <item> - <widget class="QLabel" name="titleLabel"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="font"> - <font> - <pointsize>16</pointsize> - <weight>50</weight> - <bold>false</bold> - </font> - </property> - </widget> - </item> - <item> - <spacer name="horizontalSpacer_2"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>40</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - </layout> - </item> - <item> - <widget class="QStackedWidget" name="buildSettingsWidgets"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Expanding" vsizetype="Expanding"> - <horstretch>10</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="currentIndex"> - <number>0</number> - </property> - <widget class="QWidget" name="page_2"/> - </widget> - </item> - </layout> - </widget> - </widget> - </item> - </layout> - </widget> - <resources> - <include location="../../libs/cplusplus/cplusplus.qrc"/> - <include location="../../libs/extensionsystem/pluginview.qrc"/> - <include location="../bookmarks/bookmarks.qrc"/> - <include location="../coreplugin/core.qrc"/> - <include location="../coreplugin/fancyactionbar.qrc"/> - <include location="../cppeditor/cppeditor.qrc"/> - <include location="../cpptools/cpptools.qrc"/> - <include location="../designer/designer.qrc"/> - <include location="../find/find.qrc"/> - <include location="../gdbdebugger/gdbdebugger.qrc"/> - <include location="../help/help.qrc"/> - <include location="../perforce/perforce.qrc"/> - <include location="projectexplorer.qrc"/> - <include location="../../../shared/proparser/proparser.qrc"/> - <include location="../qt4projectmanager/qt4projectmanager.qrc"/> - <include location="../qt4projectmanager/wizards/wizards.qrc"/> - <include location="../quickopen/quickopen.qrc"/> - <include location="../resourceeditor/resourceeditor.qrc"/> - <include location="../texteditor/texteditor.qrc"/> - </resources> - <connections/> -</ui> diff --git a/src/plugins/projectexplorer/buildstepspage.ui b/src/plugins/projectexplorer/buildstepspage.ui index fed7abeeeea02c3fb483efd6a7bcea9be6f59c0f..52a667f6b88b56a6b14221dcbf583372345c3900 100644 --- a/src/plugins/projectexplorer/buildstepspage.ui +++ b/src/plugins/projectexplorer/buildstepspage.ui @@ -45,11 +45,20 @@ </item> <item> <layout class="QHBoxLayout" name="horizontalLayout_2"> + <property name="spacing"> + <number>-1</number> + </property> <item> <spacer name="horizontalSpacer"> <property name="orientation"> <enum>Qt::Horizontal</enum> </property> + <property name="sizeHint" stdset="0"> + <size> + <width>0</width> + <height>0</height> + </size> + </property> </spacer> </item> <item> diff --git a/src/plugins/projectexplorer/dependenciespanel.cpp b/src/plugins/projectexplorer/dependenciespanel.cpp index 54665ae91bcf28a467a34e241ffec502a80b865c..a472e0e8287f3b7a9b7dde700cdea1476d750099 100644 --- a/src/plugins/projectexplorer/dependenciespanel.cpp +++ b/src/plugins/projectexplorer/dependenciespanel.cpp @@ -148,7 +148,6 @@ public: QWidget *parent = 0); private: - Ui::DependenciesWidget m_ui; SessionManager *m_session; DependenciesModel *m_model; }; @@ -160,9 +159,13 @@ DependenciesWidget::DependenciesWidget(SessionManager *session, , m_session(session) , m_model(new DependenciesModel(session, project, this)) { - m_ui.setupUi(this); - m_ui.dependenciesView->setModel(m_model); - m_ui.dependenciesView->setHeaderHidden(true); + QHBoxLayout *layout = new QHBoxLayout(this); + QTreeView *treeView = new QTreeView(this); + treeView->setModel(m_model); + treeView->setHeaderHidden(true); + treeView->setMinimumHeight(250); + layout->addWidget(treeView); + layout->addSpacerItem(new QSpacerItem(0, 0 , QSizePolicy::Expanding, QSizePolicy::Fixed)); } // diff --git a/src/plugins/projectexplorer/dependenciespanel.ui b/src/plugins/projectexplorer/dependenciespanel.ui deleted file mode 100644 index 83fc95b1a3bde674cd6fca9c4cb168370dc5a969..0000000000000000000000000000000000000000 --- a/src/plugins/projectexplorer/dependenciespanel.ui +++ /dev/null @@ -1,44 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<ui version="4.0"> - <class>ProjectExplorer::Internal::DependenciesWidget</class> - <widget class="QWidget" name="ProjectExplorer::Internal::DependenciesWidget"> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>502</width> - <height>375</height> - </rect> - </property> - <property name="windowTitle"> - <string>Project Dependencies</string> - </property> - <layout class="QGridLayout" name="gridLayout"> - <item row="1" column="0"> - <widget class="QTreeView" name="dependenciesView"/> - </item> - <item row="1" column="1"> - <spacer name="horizontalSpacer"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>40</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - <item row="0" column="0" colspan="2"> - <widget class="QLabel" name="label"> - <property name="text"> - <string>Project Dependencies:</string> - </property> - </widget> - </item> - </layout> - </widget> - <resources/> - <connections/> -</ui> diff --git a/src/plugins/projectexplorer/editorsettingspropertiespage.ui b/src/plugins/projectexplorer/editorsettingspropertiespage.ui index 640134cfcfbe3e2d1352720f3e31dfd5007b6eff..3ac801e2242c72dd905d55da70d7970e270d8bda 100644 --- a/src/plugins/projectexplorer/editorsettingspropertiespage.ui +++ b/src/plugins/projectexplorer/editorsettingspropertiespage.ui @@ -2,15 +2,10 @@ <ui version="4.0"> <class>ProjectExplorer::Internal::EditorSettingsPropertiesPage</class> <widget class="QWidget" name="ProjectExplorer::Internal::EditorSettingsPropertiesPage"> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>400</width> - <height>300</height> - </rect> - </property> - <layout class="QGridLayout" name="gridLayout"> + <layout class="QFormLayout" name="formLayout"> + <property name="fieldGrowthPolicy"> + <enum>QFormLayout::ExpandingFieldsGrow</enum> + </property> <item row="0" column="0"> <widget class="QLabel" name="encodingLabel"> <property name="text"> @@ -21,32 +16,6 @@ <item row="0" column="1"> <widget class="QComboBox" name="encodingComboBox"/> </item> - <item row="0" column="2"> - <spacer name="horizontalSpacer"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>232</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - <item row="1" column="0"> - <spacer name="verticalSpacer"> - <property name="orientation"> - <enum>Qt::Vertical</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>20</width> - <height>249</height> - </size> - </property> - </spacer> - </item> </layout> </widget> <resources/> diff --git a/src/plugins/projectexplorer/foldernavigationwidget.cpp b/src/plugins/projectexplorer/foldernavigationwidget.cpp index fe351913fea39efdff0a6dca7bd465e90e1f58f5..4f7b348da5089f4c2e0497b5f2e1b6d4f5075b11 100644 --- a/src/plugins/projectexplorer/foldernavigationwidget.cpp +++ b/src/plugins/projectexplorer/foldernavigationwidget.cpp @@ -204,7 +204,6 @@ Core::NavigationView FolderNavigationWidgetFactory::createWidget() FolderNavigationWidget *ptw = new FolderNavigationWidget; n.widget = ptw; QToolButton *toggleSync = new QToolButton; - toggleSync->setProperty("type", "dockbutton"); toggleSync->setIcon(QIcon(":/core/images/linkicon.png")); toggleSync->setCheckable(true); toggleSync->setChecked(ptw->autoSynchronization()); diff --git a/src/plugins/projectexplorer/projectexplorer.cpp b/src/plugins/projectexplorer/projectexplorer.cpp index e2cf36bd24ac28a6875751772d60ed3304b3595b..ea065c539434484fcac9c447eec5a061d74a5ebb 100644 --- a/src/plugins/projectexplorer/projectexplorer.cpp +++ b/src/plugins/projectexplorer/projectexplorer.cpp @@ -644,6 +644,7 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er if (QSettings *s = core->settings()) { m_projectExplorerSettings.buildBeforeRun = s->value("ProjectExplorer/Settings/BuildBeforeRun", true).toBool(); m_projectExplorerSettings.saveBeforeBuild = s->value("ProjectExplorer/Settings/SaveBeforeBuild", false).toBool(); + m_projectExplorerSettings.showCompilerOutput = s->value("ProjectExplorer/Settings/ShowCompilerOutput", false).toBool(); } if (Core::Internal::WelcomeMode *welcomeMode = qobject_cast<Core::Internal::WelcomeMode*> @@ -887,6 +888,7 @@ void ProjectExplorerPlugin::savePersistentSettings() s->setValue("ProjectExplorer/Settings/BuildBeforeRun", m_projectExplorerSettings.buildBeforeRun); s->setValue("ProjectExplorer/Settings/SaveBeforeBuild", m_projectExplorerSettings.saveBeforeBuild); + s->setValue("ProjectExplorer/Settings/ShowCompilerOutput", m_projectExplorerSettings.showCompilerOutput); } } diff --git a/src/plugins/projectexplorer/projectexplorer.h b/src/plugins/projectexplorer/projectexplorer.h index 2b5bf46676fb12db69d5e8bb283dc51fd92e0526..78c1d3c3ba8df879299a0cbdc2835a4ceefeb3c0 100644 --- a/src/plugins/projectexplorer/projectexplorer.h +++ b/src/plugins/projectexplorer/projectexplorer.h @@ -78,6 +78,7 @@ struct ProjectExplorerSettings { bool buildBeforeRun; bool saveBeforeBuild; + bool showCompilerOutput; }; } // namespace Internal diff --git a/src/plugins/projectexplorer/projectexplorer.pro b/src/plugins/projectexplorer/projectexplorer.pro index a246d2d52e370ea54c708173f42ea234f6dd8e1c..ffb0b081efc5df4cdb991fb069baf131fc96f679 100644 --- a/src/plugins/projectexplorer/projectexplorer.pro +++ b/src/plugins/projectexplorer/projectexplorer.pro @@ -112,9 +112,7 @@ SOURCES += projectexplorer.cpp \ debugginghelper.cpp \ abstractmakestep.cpp \ projectexplorersettingspage.cpp -FORMS += dependenciespanel.ui \ - buildsettingspropertiespage.ui \ - processstep.ui \ +FORMS += processstep.ui \ editorsettingspropertiespage.ui \ runsettingspropertiespage.ui \ sessiondialog.ui \ diff --git a/src/plugins/projectexplorer/projectexplorersettingspage.cpp b/src/plugins/projectexplorer/projectexplorersettingspage.cpp index 53df7ac32877bf009bd63b54ab0eeb18dd2aec8b..38b0964a8987946f6beee83b839ab99ab5d3d719 100644 --- a/src/plugins/projectexplorer/projectexplorersettingspage.cpp +++ b/src/plugins/projectexplorer/projectexplorersettingspage.cpp @@ -72,6 +72,7 @@ QWidget *ProjectExplorerSettingsPage::createPage(QWidget *parent) ProjectExplorerSettings pes = ProjectExplorerPlugin::instance()->projectExplorerSettings(); m_ui.buildProjectBeforeRunCheckBox->setChecked(pes.buildBeforeRun); m_ui.saveAllFilesCheckBox->setChecked(pes.saveBeforeBuild); + m_ui.showCompileOutputCheckBox->setChecked(pes.showCompilerOutput); return w; } @@ -80,6 +81,7 @@ void ProjectExplorerSettingsPage::apply() ProjectExplorerSettings pes; pes.buildBeforeRun = m_ui.buildProjectBeforeRunCheckBox->isChecked(); pes.saveBeforeBuild = m_ui.saveAllFilesCheckBox->isChecked(); + pes.showCompilerOutput = m_ui.showCompileOutputCheckBox->isChecked(); ProjectExplorerPlugin::instance()->setProjectExplorerSettings(pes); } diff --git a/src/plugins/projectexplorer/projectexplorersettingspage.ui b/src/plugins/projectexplorer/projectexplorersettingspage.ui index f3cfc1fe74f2a8b6bae53ae285df26789411af7e..b56006ba6bba393c95945611d9ab1a80ccac712b 100644 --- a/src/plugins/projectexplorer/projectexplorersettingspage.ui +++ b/src/plugins/projectexplorer/projectexplorersettingspage.ui @@ -31,6 +31,13 @@ </property> </widget> </item> + <item> + <widget class="QCheckBox" name="showCompileOutputCheckBox"> + <property name="text"> + <string>Show Compiler Output on building</string> + </property> + </widget> + </item> </layout> </widget> </item> diff --git a/src/plugins/projectexplorer/projectfilewizardextension.cpp b/src/plugins/projectexplorer/projectfilewizardextension.cpp index 33b7d37076004bf1da020b539ddf8b51e39c4966..277b98e564d48465fa2969235c83140c6c10311c 100644 --- a/src/plugins/projectexplorer/projectfilewizardextension.cpp +++ b/src/plugins/projectexplorer/projectfilewizardextension.cpp @@ -141,20 +141,8 @@ QList<QWizardPage *> ProjectFileWizardExtension::extensionPages(const Core::IWiz // Disable "add project to project" const bool hasProjects = !m_context->projects.empty(); if (hasProjects) { - // Compile list of names and find current project if there is one - QStringList projectNames; - ProjectNode *current = currentProject(); - int currentIndex = -1; - const int count = m_context->projects.size(); - for (int i = 0; i < count; i++) { - ProjectNode *pn = m_context->projects.at(i); - projectNames.push_back(QFileInfo(pn->path()).fileName()); - if (current == pn) - currentIndex = i; - } - m_context->page->setProjects(projectNames); - if (currentIndex != -1) - m_context->page->setCurrentProjectIndex(currentIndex); + m_context->page->setProjects(m_context->projects); + m_context->page->setCurrentProject(currentProject()); } m_context->page->setAddToProjectEnabled(hasProjects && wizard->kind() != Core::IWizard::ProjectWizard); @@ -166,7 +154,7 @@ bool ProjectFileWizardExtension::process(const QList<Core::GeneratedFile> &files typedef QMultiMap<FileType, QString> TypeFileMap; // Add files to project && version control if (m_context->page->addToProject()) { - ProjectNode *project = m_context->projects.at(m_context->page->currentProjectIndex()); + ProjectNode *project = m_context->page->currentProject(); // Split into lists by file type and add TypeFileMap typeFileMap; foreach (const Core::GeneratedFile &generatedFile, files) { diff --git a/src/plugins/projectexplorer/projecttreewidget.cpp b/src/plugins/projectexplorer/projecttreewidget.cpp index 486075eb16fee524fac5db35d376ddffba5c2a58..6b6ca87131138965720efa474ba8d3540e0d39c4 100644 --- a/src/plugins/projectexplorer/projecttreewidget.cpp +++ b/src/plugins/projectexplorer/projecttreewidget.cpp @@ -162,7 +162,6 @@ ProjectTreeWidget::ProjectTreeWidget(QWidget *parent) this, SLOT(startupProjectChanged(ProjectExplorer::Project *))); m_toggleSync = new QToolButton; - m_toggleSync->setProperty("type", "dockbutton"); m_toggleSync->setIcon(QIcon(":/core/images/linkicon.png")); m_toggleSync->setCheckable(true); m_toggleSync->setChecked(autoSynchronization()); @@ -372,7 +371,6 @@ Core::NavigationView ProjectTreeWidgetFactory::createWidget() n.widget = ptw; QToolButton *filter = new QToolButton; - filter->setProperty("type", "dockbutton"); filter->setIcon(QIcon(":/projectexplorer/images/filtericon.png")); filter->setToolTip(tr("Filter tree")); filter->setPopupMode(QToolButton::InstantPopup); diff --git a/src/plugins/projectexplorer/projectwindow.cpp b/src/plugins/projectexplorer/projectwindow.cpp index 504037661a57fa4e0a2175c3d86fef3f15cdcb73..4d5cf076a927895550520eebd2ad8c0e0239e2f3 100644 --- a/src/plugins/projectexplorer/projectwindow.cpp +++ b/src/plugins/projectexplorer/projectwindow.cpp @@ -40,6 +40,7 @@ #include <coreplugin/fileiconprovider.h> #include <coreplugin/icore.h> #include <extensionsystem/pluginmanager.h> +#include <utils/styledbar.h> #include <QtCore/QDebug> #include <QtGui/QApplication> @@ -47,9 +48,9 @@ #include <QtGui/QComboBox> #include <QtGui/QScrollArea> #include <QtGui/QTabWidget> -#include <QtGui/QToolBar> #include <QtGui/QTreeWidget> #include <QtGui/QHeaderView> +#include <QtGui/QLabel> using namespace ProjectExplorer; using namespace ProjectExplorer::Internal; @@ -58,6 +59,48 @@ namespace { bool debug = false; } +PanelsWidget::PanelsWidget(QWidget *parent) + : QScrollArea(parent) +{ + m_widget = new QWidget; + m_layout = new QVBoxLayout(m_widget); + + setWidgetResizable(true); + setFrameStyle(QFrame::NoFrame); + setWidget(m_widget); + +} + +PanelsWidget::~PanelsWidget() +{ + clear(); +} + +void PanelsWidget::addWidget(const QString &name, QWidget *widget) +{ + Panel p; + p.nameLabel = new QLabel(this); + p.nameLabel->setText(name); + QFont f = p.nameLabel->font(); + f.setBold(true); + f.setPointSizeF(f.pointSizeF() * 1.4); + p.nameLabel->setFont(f); + p.panelWidget = widget; + m_panels.append(p); + + m_layout->addWidget(p.nameLabel); + m_layout->addWidget(p.panelWidget); +} + +void PanelsWidget::clear() +{ + foreach(Panel p, m_panels) { + delete p.nameLabel; + delete p.panelWidget; + } + m_panels.clear(); +} + ProjectWindow::ProjectWindow(QWidget *parent) : QWidget(parent), m_currentItemChanged(false) { @@ -84,37 +127,19 @@ ProjectWindow::ProjectWindow(QWidget *parent) connect(m_treeWidget, SIGNAL(currentItemChanged(QTreeWidgetItem*, QTreeWidgetItem *)), this, SLOT(handleCurrentItemChanged(QTreeWidgetItem*))); - QWidget *panelsWidget = new QWidget; - m_panelsTabWidget = new QTabWidget; - m_panelsTabWidget->setDocumentMode(true); - QVBoxLayout *panelsLayout = new QVBoxLayout(panelsWidget); - - QWidget *marginWidget = new QWidget; - QVBoxLayout *marginLayout = new QVBoxLayout(marginWidget); - marginLayout->setContentsMargins(0, panelsLayout->margin(), 0, 0); - marginLayout->addWidget(m_panelsTabWidget); - - QScrollArea *scrollArea = new QScrollArea; - scrollArea->setWidgetResizable(true); - scrollArea->setFrameStyle(QFrame::NoFrame); - scrollArea->setWidget(marginWidget); - panelsLayout->setSpacing(0); - panelsLayout->setMargin(0); - panelsLayout->addWidget(scrollArea); + m_panelsWidget = new PanelsWidget(this); QWidget *dummy = new QWidget; QVBoxLayout *dummyLayout = new QVBoxLayout(dummy); dummyLayout->setMargin(0); dummyLayout->setSpacing(0); - dummyLayout->addWidget(new QToolBar(dummy)); + dummyLayout->addWidget(new Core::Utils::StyledBar(dummy)); dummyLayout->addWidget(m_treeWidget); QSplitter *splitter = new Core::MiniSplitter; splitter->setOrientation(Qt::Vertical); splitter->addWidget(dummy); - splitter->addWidget(panelsWidget); - - + splitter->addWidget(m_panelsWidget); // make sure that the tree treewidget has same size policy as qtabwidget m_treeWidget->setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred)); @@ -146,20 +171,22 @@ void ProjectWindow::restoreStatus() m_treeWidget->setCurrentItem(m_treeWidget->topLevelItem(0), 0, QItemSelectionModel::SelectCurrent | QItemSelectionModel::Rows); } - const QVariant lastPanel = m_session->value(QLatin1String("ProjectWindow/Panel")); - if (lastPanel.isValid()) { - const int index = lastPanel.toInt(); - if (index < m_panelsTabWidget->count()) - m_panelsTabWidget->setCurrentIndex(index); - } - - if ((m_panelsTabWidget->currentIndex() == -1) && m_panelsTabWidget->count()) - m_panelsTabWidget->setCurrentIndex(0); + // TODO +// const QVariant lastPanel = m_session->value(QLatin1String("ProjectWindow/Panel")); +// if (lastPanel.isValid()) { +// const int index = lastPanel.toInt(); +// if (index < m_panelsTabWidget->count()) +// m_panelsTabWidget->setCurrentIndex(index); +// } +// +// if ((m_panelsTabWidget->currentIndex() == -1) && m_panelsTabWidget->count()) +// m_panelsTabWidget->setCurrentIndex(0); } void ProjectWindow::saveStatus() { - m_session->setValue(QLatin1String("ProjectWindow/Panel"), m_panelsTabWidget->currentIndex()); + // TODO +// m_session->setValue(QLatin1String("ProjectWindow/Panel"), m_panelsTabWidget->currentIndex()); } void ProjectWindow::showProperties(ProjectExplorer::Project *project, const QModelIndex & /* subIndex */) @@ -168,14 +195,7 @@ void ProjectWindow::showProperties(ProjectExplorer::Project *project, const QMod qDebug() << "ProjectWindow - showProperties called"; // Remove the tabs from the tab widget first - while (m_panelsTabWidget->count() > 0) - m_panelsTabWidget->removeTab(0); - - while (m_panels.count()) { - PropertiesPanel *panel = m_panels.at(0); - m_panels.removeOne(panel); - delete panel; - } + m_panelsWidget->clear(); if (project) { QList<IPanelFactory *> pages = @@ -185,9 +205,7 @@ void ProjectWindow::showProperties(ProjectExplorer::Project *project, const QMod PropertiesPanel *panel = panelFactory->createPanel(project); if (debug) qDebug() << "ProjectWindow - setting up project properties tab " << panel->name(); - - m_panels.append(panel); - m_panelsTabWidget->addTab(panel->widget(), panel->name()); + m_panelsWidget->addWidget(panel->name(), panel->widget()); } } } diff --git a/src/plugins/projectexplorer/projectwindow.h b/src/plugins/projectexplorer/projectwindow.h index 341c6b7f7e1785f1e92c2492e4466b52baa8547a..bae2b8b78b62a502affafd923554db9efb6c531d 100644 --- a/src/plugins/projectexplorer/projectwindow.h +++ b/src/plugins/projectexplorer/projectwindow.h @@ -31,8 +31,11 @@ #define PROJECTWINDOW_H #include <QtGui/QWidget> +#include <QtGui/QScrollArea> QT_BEGIN_NAMESPACE +class QLabel; +class QVBoxLayout; class QModelIndex; class QTabWidget; class QTreeWidget; @@ -48,6 +51,29 @@ class SessionManager; namespace Internal { +class PanelsWidget : public QScrollArea +{ + Q_OBJECT +public: + PanelsWidget(QWidget *parent); + ~PanelsWidget(); + // Adds a widget + void addWidget(const QString &name, QWidget *widget); + + // Removes all widgets and deletes them + void clear(); +private: + + struct Panel + { + QLabel *nameLabel; + QWidget *panelWidget; + }; + QWidget *m_widget; + QVBoxLayout *m_layout; + QList<Panel> m_panels; +}; + class ProjectWindow : public QWidget { Q_OBJECT @@ -74,9 +100,7 @@ private: ProjectExplorerPlugin *m_projectExplorer; QTreeWidget* m_treeWidget; - QTabWidget *m_panelsTabWidget; - - QList<PropertiesPanel*> m_panels; + PanelsWidget *m_panelsWidget; Project *findProject(const QString &path) const; bool m_currentItemChanged; diff --git a/src/plugins/projectexplorer/projectwizardpage.cpp b/src/plugins/projectexplorer/projectwizardpage.cpp index ff4d2b6060a1b9a2bda7302b16d87fb9596b6e2f..57c1d512c7faeb26f0b6a2650d973599168f3aeb 100644 --- a/src/plugins/projectexplorer/projectwizardpage.cpp +++ b/src/plugins/projectexplorer/projectwizardpage.cpp @@ -29,13 +29,17 @@ #include "projectwizardpage.h" #include "ui_projectwizardpage.h" +#include "projectnodes.h" #include <QtCore/QDebug> +#include <QtCore/QFileInfo> #include <QtCore/QTextStream> using namespace ProjectExplorer; using namespace Internal; +Q_DECLARE_METATYPE(ProjectExplorer::ProjectNode*) + ProjectWizardPage::ProjectWizardPage(QWidget *parent) : QWizardPage(parent), m_ui(new Ui::WizardPage) @@ -51,13 +55,19 @@ ProjectWizardPage::~ProjectWizardPage() delete m_ui; } -void ProjectWizardPage::setProjects(const QStringList &l) +void ProjectWizardPage::setProjects(const QList<ProjectNode*> &projectNodes) { - QStringList list = l; - list.removeDuplicates(); - list.sort(); + QMap<QString,ProjectNode*> projectMap; + foreach (ProjectNode *node, projectNodes) { + QString name = QFileInfo(node->path()).fileName(); + if (!projectMap.contains(name)) + projectMap.insert(name, node); + } + m_ui->projectComboBox->clear(); - m_ui->projectComboBox->addItems(list); + foreach (const QString &name, projectMap.keys()) { + m_ui->projectComboBox->addItem(name, qVariantFromValue(projectMap.value(name))); + } } void ProjectWizardPage::setAddToProjectEnabled(bool b) @@ -69,14 +79,22 @@ void ProjectWizardPage::setAddToProjectEnabled(bool b) m_ui->projectComboBox->setEnabled(b); } -int ProjectWizardPage::currentProjectIndex() const +ProjectNode *ProjectWizardPage::currentProject() const { - return m_ui->projectComboBox->currentIndex(); + QVariant variant = m_ui->projectComboBox->itemData(m_ui->projectComboBox->currentIndex()); + return qVariantValue<ProjectNode*>(variant); } -void ProjectWizardPage::setCurrentProjectIndex(int i) +void ProjectWizardPage::setCurrentProject(ProjectNode *projectNode) { - m_ui->projectComboBox->setCurrentIndex(i); + if (!projectNode) + return; + for (int i = 0; i < m_ui->projectComboBox->count(); ++i) { + if (qVariantValue<ProjectNode*>(m_ui->projectComboBox->itemData(i)) == projectNode) { + m_ui->projectComboBox->setCurrentIndex(i); + return; + } + } } bool ProjectWizardPage::addToProject() const diff --git a/src/plugins/projectexplorer/projectwizardpage.h b/src/plugins/projectexplorer/projectwizardpage.h index cc018b5a932e78e1c22f8d5f8cc481e219a28289..7244a499ff823bbe6a8573240f129ead47d70179 100644 --- a/src/plugins/projectexplorer/projectwizardpage.h +++ b/src/plugins/projectexplorer/projectwizardpage.h @@ -55,9 +55,10 @@ public: explicit ProjectWizardPage(QWidget *parent = 0); virtual ~ProjectWizardPage(); - void setProjects(const QStringList &); - void setCurrentProjectIndex(int); - int currentProjectIndex() const; + void setProjects(const QList<ProjectNode *> &); + void setCurrentProject(ProjectNode *); + + ProjectNode *currentProject() const; void setAddToProjectEnabled(bool b); bool addToProject() const; diff --git a/src/plugins/projectexplorer/runsettingspropertiespage.cpp b/src/plugins/projectexplorer/runsettingspropertiespage.cpp index d0c0b3702c5609693aba2977ff8bb14150fb2b96..3166e7da8dea68adcc3a80ab054d7873c86b3c74 100644 --- a/src/plugins/projectexplorer/runsettingspropertiespage.cpp +++ b/src/plugins/projectexplorer/runsettingspropertiespage.cpp @@ -181,7 +181,9 @@ RunSettingsWidget::RunSettingsWidget(Project *project) m_addMenu = new QMenu(m_ui->addToolButton); m_ui->addToolButton->setIcon(QIcon(Core::Constants::ICON_PLUS)); m_ui->addToolButton->setMenu(m_addMenu); + m_ui->addToolButton->setText(tr("Add")); m_ui->removeToolButton->setIcon(QIcon(Core::Constants::ICON_MINUS)); + m_ui->removeToolButton->setText(tr("Remove")); m_ui->runConfigurationCombo->setModel(m_runConfigurationsModel); m_ui->activeRunConfigurationCombo->setModel(m_enabledRunConfigurationsModel); diff --git a/src/plugins/projectexplorer/runsettingspropertiespage.ui b/src/plugins/projectexplorer/runsettingspropertiespage.ui index c83a5a7709cdc8ee861f20ecdbc20dd5a647812d..2daaa3cfae3dc6c2a7cb3edeb7c1a7f850731e3d 100644 --- a/src/plugins/projectexplorer/runsettingspropertiespage.ui +++ b/src/plugins/projectexplorer/runsettingspropertiespage.ui @@ -6,31 +6,25 @@ <rect> <x>0</x> <y>0</y> - <width>551</width> + <width>621</width> <height>300</height> </rect> </property> - <layout class="QVBoxLayout" name="layout"> + <layout class="QVBoxLayout" name="verticalLayout"> <item> - <layout class="QHBoxLayout" name="horizontalLayout"> - <item> - <widget class="QLabel" name="label"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Maximum" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> + <layout class="QFormLayout" name="formLayout"> + <property name="fieldGrowthPolicy"> + <enum>QFormLayout::ExpandingFieldsGrow</enum> + </property> + <item row="0" column="0"> + <widget class="QLabel" name="label_2"> <property name="text"> - <string>Run &configuration:</string> - </property> - <property name="buddy"> - <cstring>runConfigurationCombo</cstring> + <string>Active run configuration:</string> </property> </widget> </item> - <item> - <widget class="QComboBox" name="runConfigurationCombo"> + <item row="0" column="1"> + <widget class="QComboBox" name="activeRunConfigurationCombo"> <property name="maximumSize"> <size> <width>500</width> @@ -45,65 +39,62 @@ </property> </widget> </item> - <item> - <widget class="QToolButton" name="addToolButton"> - <property name="text"> - <string>+</string> - </property> - <property name="popupMode"> - <enum>QToolButton::InstantPopup</enum> - </property> - </widget> - </item> - <item> - <widget class="QToolButton" name="removeToolButton"> - <property name="text"> - <string>-</string> + <item row="1" column="0"> + <widget class="QLabel" name="label"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Maximum" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> </property> - </widget> - </item> - <item> - <widget class="QLabel" name="label_2"> <property name="text"> - <string>Active run configuration:</string> + <string>Edit run configuration:</string> </property> - </widget> - </item> - <item> - <widget class="QComboBox" name="activeRunConfigurationCombo"> - <property name="maximumSize"> - <size> - <width>500</width> - <height>16777215</height> - </size> - </property> - <property name="sizeAdjustPolicy"> - <enum>QComboBox::AdjustToContents</enum> - </property> - <property name="minimumContentsLength"> - <number>15</number> + <property name="buddy"> + <cstring>runConfigurationCombo</cstring> </property> </widget> </item> - <item> - <spacer name="horizontalSpacer"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>40</width> - <height>20</height> - </size> - </property> - </spacer> + <item row="1" column="1"> + <layout class="QHBoxLayout" name="horizontalLayout"> + <item> + <widget class="QComboBox" name="runConfigurationCombo"> + <property name="maximumSize"> + <size> + <width>500</width> + <height>16777215</height> + </size> + </property> + <property name="sizeAdjustPolicy"> + <enum>QComboBox::AdjustToContents</enum> + </property> + <property name="minimumContentsLength"> + <number>15</number> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="addToolButton"> + <property name="text"> + <string>+</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="removeToolButton"> + <property name="text"> + <string>-</string> + </property> + </widget> + </item> + </layout> </item> </layout> </item> <item> <widget class="QGroupBox" name="groupBox"> <property name="title"> - <string>Settings</string> + <string/> </property> <layout class="QHBoxLayout" name="horizontalLayout_2"/> </widget> diff --git a/src/plugins/projectexplorer/taskwindow.cpp b/src/plugins/projectexplorer/taskwindow.cpp index 3a8b84d4c5bbc740757e5d30b67b335cc8f76bb4..0f085e8b67f66c010b27eea17a72a59ddb6292f2 100644 --- a/src/plugins/projectexplorer/taskwindow.cpp +++ b/src/plugins/projectexplorer/taskwindow.cpp @@ -314,7 +314,6 @@ static QToolButton *createFilterButton(ProjectExplorer::BuildParserInterface::Pa { QToolButton *button = new QToolButton; button->setIcon(model->iconFor(type)); - button->setProperty("type", "dockbutton"); button->setToolTip(toolTip); button->setCheckable(true); button->setChecked(true); diff --git a/src/plugins/qt4projectmanager/makestep.cpp b/src/plugins/qt4projectmanager/makestep.cpp index 2b3d7aadd44d39ea678dc41e52b29526239769f7..37501d873a8fbbf30981a6d0047059522bdf2384 100644 --- a/src/plugins/qt4projectmanager/makestep.cpp +++ b/src/plugins/qt4projectmanager/makestep.cpp @@ -185,8 +185,6 @@ void MakeStepConfigWidget::init(const QString &buildConfiguration) m_makeStep->setValue(buildConfiguration, "makeargs", QStringList() << "clean"); } - m_ui.stackedWidget->setCurrentIndex(1); - m_ui.makeLabel->setText(tr("Override %1:").arg(pro->makeCommand(buildConfiguration))); const QString &makeCmd = m_makeStep->value(buildConfiguration, "makeCmd").toString(); diff --git a/src/plugins/qt4projectmanager/makestep.ui b/src/plugins/qt4projectmanager/makestep.ui index 1a7189300be4644cf8f176aeb240e5559712d2cc..f2007e7e398422484f1f02abf1c6f2198900e548 100644 --- a/src/plugins/qt4projectmanager/makestep.ui +++ b/src/plugins/qt4projectmanager/makestep.ui @@ -6,71 +6,33 @@ <rect> <x>0</x> <y>0</y> - <width>428</width> - <height>384</height> + <width>235</width> + <height>64</height> </rect> </property> - <layout class="QVBoxLayout" name="verticalLayout"> - <property name="margin"> - <number>0</number> - </property> - <item> - <widget class="QStackedWidget" name="stackedWidget"> - <property name="currentIndex"> - <number>1</number> + <layout class="QFormLayout" name="formLayout"> + <item row="0" column="0"> + <widget class="QLabel" name="makeLabel"> + <property name="text"> + <string>Override %1:</string> </property> - <widget class="QWidget" name="page_1"> - <layout class="QFormLayout" name="formLayout_2"> - <property name="fieldGrowthPolicy"> - <enum>QFormLayout::ExpandingFieldsGrow</enum> - </property> - </layout> - </widget> - <widget class="QWidget" name="page_2"> - <layout class="QVBoxLayout" name="verticalLayout_2"> - <item> - <widget class="QLabel" name="makeLabel"> - <property name="text"> - <string>Override %1:</string> - </property> - </widget> - </item> - <item> - <widget class="QLineEdit" name="makeLineEdit"/> - </item> - <item> - <widget class="QLabel" name="makeArgumentsLabel"> - <property name="text"> - <string>Make arguments:</string> - </property> - </widget> - </item> - <item> - <widget class="QLineEdit" name="makeArgumentsLineEdit"/> - </item> - <item> - <spacer name="verticalSpacer"> - <property name="orientation"> - <enum>Qt::Vertical</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>20</width> - <height>255</height> - </size> - </property> - </spacer> - </item> - </layout> - </widget> </widget> </item> + <item row="0" column="1"> + <widget class="QLineEdit" name="makeLineEdit"/> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="makeArgumentsLabel"> + <property name="text"> + <string>Make arguments:</string> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QLineEdit" name="makeArgumentsLineEdit"/> + </item> </layout> </widget> - <tabstops> - <tabstop>makeLineEdit</tabstop> - <tabstop>makeArgumentsLineEdit</tabstop> - </tabstops> <resources/> <connections/> </ui> diff --git a/src/plugins/qt4projectmanager/qmakestep.cpp b/src/plugins/qt4projectmanager/qmakestep.cpp index 8ce0cef56a8d5af1e48c0e6c6ab09efedcc583a0..c9e315d21d0b3ba433f28849669e9c92fa577ebf 100644 --- a/src/plugins/qt4projectmanager/qmakestep.cpp +++ b/src/plugins/qt4projectmanager/qmakestep.cpp @@ -256,16 +256,11 @@ QString QMakeStepConfigWidget::displayName() const void QMakeStepConfigWidget::init(const QString &buildConfiguration) { m_buildConfiguration = buildConfiguration; - if (buildConfiguration.isEmpty()){ - m_ui.stackedWidget->setCurrentWidget(m_ui.page_2); - } else { - m_ui.stackedWidget->setCurrentWidget(m_ui.page_1); - QString qmakeArgs = ProjectExplorer::Environment::joinArgumentList(m_step->value(buildConfiguration, "qmakeArgs").toStringList()); - m_ui.qmakeAdditonalArgumentsLineEdit->setText(qmakeArgs); - m_ui.qmakeArgumentsEdit->setPlainText(ProjectExplorer::Environment::joinArgumentList(m_step->arguments(buildConfiguration))); - bool debug = QtVersion::QmakeBuildConfig(m_step->value(buildConfiguration, "buildConfiguration").toInt()) & QtVersion::DebugBuild; - m_ui.buildConfigurationComboBox->setCurrentIndex(debug? 0 : 1); - } + QString qmakeArgs = ProjectExplorer::Environment::joinArgumentList(m_step->value(buildConfiguration, "qmakeArgs").toStringList()); + m_ui.qmakeAdditonalArgumentsLineEdit->setText(qmakeArgs); + m_ui.qmakeArgumentsEdit->setPlainText(ProjectExplorer::Environment::joinArgumentList(m_step->arguments(buildConfiguration))); + bool debug = QtVersion::QmakeBuildConfig(m_step->value(buildConfiguration, "buildConfiguration").toInt()) & QtVersion::DebugBuild; + m_ui.buildConfigurationComboBox->setCurrentIndex(debug? 0 : 1); } //// diff --git a/src/plugins/qt4projectmanager/qmakestep.ui b/src/plugins/qt4projectmanager/qmakestep.ui index a28baf6448ff561c11110e7f9649a311d587a686..abb882d716475511a99b8a1672a7e29db095d102 100644 --- a/src/plugins/qt4projectmanager/qmakestep.ui +++ b/src/plugins/qt4projectmanager/qmakestep.ui @@ -6,111 +6,66 @@ <rect> <x>0</x> <y>0</y> - <width>414</width> - <height>442</height> + <width>436</width> + <height>187</height> </rect> </property> - <layout class="QVBoxLayout" name="verticalLayout"> - <property name="margin"> - <number>0</number> - </property> - <item> - <widget class="QStackedWidget" name="stackedWidget"> - <property name="currentIndex"> - <number>0</number> + <layout class="QFormLayout" name="formLayout"> + <item row="0" column="0"> + <widget class="QLabel" name="label_2"> + <property name="text"> + <string>QMake Build Configuration:</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QComboBox" name="buildConfigurationComboBox"> + <item> + <property name="text"> + <string>debug</string> + </property> + </item> + <item> + <property name="text"> + <string>release</string> + </property> + </item> + </widget> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="qmakeArgsLabel"> + <property name="text"> + <string>Additional arguments:</string> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QLineEdit" name="qmakeAdditonalArgumentsLineEdit"/> + </item> + <item row="2" column="0"> + <widget class="QLabel" name="label"> + <property name="text"> + <string>Effective qmake call:</string> + </property> + <property name="alignment"> + <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set> + </property> + </widget> + </item> + <item row="2" column="1"> + <widget class="QPlainTextEdit" name="qmakeArgumentsEdit"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="maximumSize"> + <size> + <width>16777215</width> + <height>120</height> + </size> + </property> + <property name="textInteractionFlags"> + <set>Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set> </property> - <widget class="QWidget" name="page_1"> - <layout class="QVBoxLayout" name="verticalLayout_2"> - <item> - <widget class="QLabel" name="label_2"> - <property name="text"> - <string>QMake Build Configuration:</string> - </property> - </widget> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout"> - <item> - <widget class="QComboBox" name="buildConfigurationComboBox"> - <item> - <property name="text"> - <string>debug</string> - </property> - </item> - <item> - <property name="text"> - <string>release</string> - </property> - </item> - </widget> - </item> - <item> - <spacer name="horizontalSpacer"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>40</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - </layout> - </item> - <item> - <widget class="QLabel" name="qmakeArgsLabel"> - <property name="text"> - <string>Additional arguments:</string> - </property> - </widget> - </item> - <item> - <widget class="QLineEdit" name="qmakeAdditonalArgumentsLineEdit"/> - </item> - <item> - <widget class="QLabel" name="label"> - <property name="text"> - <string>Effective qmake call:</string> - </property> - <property name="alignment"> - <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set> - </property> - </widget> - </item> - <item> - <widget class="QPlainTextEdit" name="qmakeArgumentsEdit"> - <property name="enabled"> - <bool>false</bool> - </property> - <property name="maximumSize"> - <size> - <width>16777215</width> - <height>120</height> - </size> - </property> - <property name="textInteractionFlags"> - <set>Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set> - </property> - </widget> - </item> - <item> - <spacer name="verticalSpacer"> - <property name="orientation"> - <enum>Qt::Vertical</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>393</width> - <height>179</height> - </size> - </property> - </spacer> - </item> - </layout> - </widget> - <widget class="QWidget" name="page_2"/> </widget> </item> </layout> diff --git a/src/plugins/qt4projectmanager/qt4project.cpp b/src/plugins/qt4projectmanager/qt4project.cpp index 79b68a71a53611e9fa651df30fb97cfd808ffdf8..11bd2b8a76f6a326b60fba88400c822c9bed51dd 100644 --- a/src/plugins/qt4projectmanager/qt4project.cpp +++ b/src/plugins/qt4projectmanager/qt4project.cpp @@ -239,13 +239,6 @@ Qt4Project::Qt4Project(Qt4Manager *manager, const QString& fileName) : { m_manager->registerProject(this); - QtVersionManager *vm = QtVersionManager::instance(); - - connect(vm, SIGNAL(defaultQtVersionChanged()), - this, SLOT(defaultQtVersionChanged())); - connect(vm, SIGNAL(qtVersionsChanged()), - this, SLOT(qtVersionsChanged())); - m_updateCodeModelTimer.setSingleShot(true); m_updateCodeModelTimer.setInterval(20); connect(&m_updateCodeModelTimer, SIGNAL(timeout()), this, SLOT(updateCodeModel())); @@ -334,6 +327,13 @@ bool Qt4Project::restoreSettingsImpl(PersistentSettingsReader &settingsReader) } // Now connect + QtVersionManager *vm = QtVersionManager::instance(); + connect(vm, SIGNAL(defaultQtVersionChanged()), + this, SLOT(defaultQtVersionChanged())); + connect(vm, SIGNAL(qtVersionsChanged()), + this, SLOT(qtVersionsChanged())); + + connect(m_nodesWatcher, SIGNAL(foldersAboutToBeAdded(FolderNode *, const QList<FolderNode*> &)), this, SLOT(foldersAboutToBeAdded(FolderNode *, const QList<FolderNode*> &))); connect(m_nodesWatcher, SIGNAL(foldersAdded()), this, SLOT(checkForNewApplicationProjects())); diff --git a/src/plugins/qt4projectmanager/qt4runconfiguration.cpp b/src/plugins/qt4projectmanager/qt4runconfiguration.cpp index 953f90a9ab9586e9bd1929a4c40ab2f576d08ee7..9096a58c5c5d14da37c04ed19c532747a593fa11 100644 --- a/src/plugins/qt4projectmanager/qt4runconfiguration.cpp +++ b/src/plugins/qt4projectmanager/qt4runconfiguration.cpp @@ -142,12 +142,12 @@ Qt4RunConfigurationWidget::Qt4RunConfigurationWidget(Qt4RunConfiguration *qt4Run boxlayout->addWidget(resetButton); toplayout->addRow(tr("Working Directory:"), boxlayout); - QLabel *argumentsLabel = new QLabel(tr("&Arguments:")); + QLabel *argumentsLabel = new QLabel(tr("Arguments:")); m_argumentsLineEdit = new QLineEdit(ProjectExplorer::Environment::joinArgumentList(qt4RunConfiguration->commandLineArguments())); argumentsLabel->setBuddy(m_argumentsLineEdit); toplayout->addRow(argumentsLabel, m_argumentsLineEdit); - m_useTerminalCheck = new QCheckBox(tr("Run in &Terminal")); + m_useTerminalCheck = new QCheckBox(tr("Run in Terminal")); m_useTerminalCheck->setChecked(m_qt4RunConfiguration->runMode() == ProjectExplorer::ApplicationRunConfiguration::Console); toplayout->addRow(QString(), m_useTerminalCheck); diff --git a/src/plugins/qtscripteditor/qtscripteditor.cpp b/src/plugins/qtscripteditor/qtscripteditor.cpp index 934e908f4fc07cf692c559bbebec2b29f9e74375..ca4e2976741f6a61bf513275d3c0898c6c16a1cc 100644 --- a/src/plugins/qtscripteditor/qtscripteditor.cpp +++ b/src/plugins/qtscripteditor/qtscripteditor.cpp @@ -55,6 +55,7 @@ #include <QtGui/QComboBox> #include <QtGui/QHBoxLayout> #include <QtGui/QMenu> +#include <QtGui/QToolBar> enum { UPDATE_DOCUMENT_DEFAULT_INTERVAL = 100 @@ -384,7 +385,7 @@ void ScriptEditor::createToolBar(ScriptEditorEditable *editable) connect(file(), SIGNAL(changed()), this, SLOT(updateFileName())); - QToolBar *toolBar = editable->toolBar(); + QToolBar *toolBar = static_cast<QToolBar*>(editable->toolBar()); QList<QAction*> actions = toolBar->actions(); QWidget *w = toolBar->widgetForAction(actions.first()); diff --git a/src/plugins/resourceeditor/resourceeditorw.h b/src/plugins/resourceeditor/resourceeditorw.h index 7a8a904b888727b78b48656f0b0ae2fe5b544819..98929febaa7cc182e319b0ec3b4bfb6bcfd1f1f6 100644 --- a/src/plugins/resourceeditor/resourceeditorw.h +++ b/src/plugins/resourceeditor/resourceeditorw.h @@ -96,7 +96,7 @@ public: const char *kind() const; QString displayName() const { return m_displayName; } void setDisplayName(const QString &title) { m_displayName = title; } - QToolBar *toolBar() { return 0; } + QWidget *toolBar() { return 0; } QByteArray saveState() const { return QByteArray(); } bool restoreState(const QByteArray &/*state*/) { return true; } diff --git a/src/plugins/subversion/checkoutwizard.cpp b/src/plugins/subversion/checkoutwizard.cpp new file mode 100644 index 0000000000000000000000000000000000000000..5285b704c3f8c42a992021249e130047fb2fc2a9 --- /dev/null +++ b/src/plugins/subversion/checkoutwizard.cpp @@ -0,0 +1,88 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (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 http://www.qtsoftware.com/contact. +** +**************************************************************************/ + +#include "checkoutwizard.h" +#include "checkoutwizardpage.h" +#include "subversionplugin.h" + +#include <vcsbase/checkoutjobs.h> +#include <utils/qtcassert.h> + +#include <QtGui/QIcon> + +namespace Subversion { +namespace Internal { + +CheckoutWizard::CheckoutWizard(QObject *parent) : + VCSBase::BaseCheckoutWizard(parent) +{ +} + +QIcon CheckoutWizard::icon() const +{ + return QIcon(); +} + +QString CheckoutWizard::description() const +{ + return tr("Check-out a project from a Subversion repository."); +} + +QString CheckoutWizard::name() const +{ + return tr("Subversion Checkout"); +} + +QWizardPage *CheckoutWizard::createParameterPage(const QString &path) +{ + CheckoutWizardPage *cwp = new CheckoutWizardPage; + cwp->setPath(path); + return cwp; +} + +QSharedPointer<VCSBase::AbstractCheckoutJob> CheckoutWizard::createJob(const QWizardPage *parameterPage, + QString *checkoutPath) +{ + // Collect parameters for the checkout command. + const CheckoutWizardPage *cwp = qobject_cast<const CheckoutWizardPage *>(parameterPage); + QTC_ASSERT(cwp, return QSharedPointer<VCSBase::AbstractCheckoutJob>()) + const SubversionSettings settings = SubversionPlugin::subversionPluginInstance()->settings(); + const QString binary = settings.svnCommand; + const QString directory = cwp->directory(); + QStringList args; + args << QLatin1String("checkout") << cwp->repository() << directory; + const QString workingDirectory = cwp->path(); + *checkoutPath = workingDirectory + QLatin1Char('/') + directory; + VCSBase::AbstractCheckoutJob *job = new VCSBase::ProcessCheckoutJob(binary, settings.addOptions(args), + workingDirectory); + return QSharedPointer<VCSBase::AbstractCheckoutJob>(job); +} + +} // namespace Internal +} // namespace Subversion diff --git a/src/plugins/subversion/checkoutwizard.h b/src/plugins/subversion/checkoutwizard.h new file mode 100644 index 0000000000000000000000000000000000000000..fbc9c1e1d36660ea688c658f7c99e5084f1b0d95 --- /dev/null +++ b/src/plugins/subversion/checkoutwizard.h @@ -0,0 +1,58 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (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 http://www.qtsoftware.com/contact. +** +**************************************************************************/ + +#ifndef CHECKOUTWIZARD_H +#define CHECKOUTWIZARD_H + +#include <vcsbase/basecheckoutwizard.h> + +namespace Subversion { +namespace Internal { + +class CheckoutWizard : public VCSBase::BaseCheckoutWizard +{ +public: + explicit CheckoutWizard(QObject *parent = 0); + + // IWizard + virtual QIcon icon() const; + virtual QString description() const; + virtual QString name() const; + +protected: + // BaseCheckoutWizard + virtual QWizardPage *createParameterPage(const QString &path); + virtual QSharedPointer<VCSBase::AbstractCheckoutJob> createJob(const QWizardPage *parameterPage, + QString *checkoutPath); +}; + +} // namespace Internal +} // namespace Subversion + +#endif // CHECKOUTWIZARD_H diff --git a/src/plugins/subversion/checkoutwizardpage.cpp b/src/plugins/subversion/checkoutwizardpage.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a6440250c0286a6f1713a0aa6590edf913c4462c --- /dev/null +++ b/src/plugins/subversion/checkoutwizardpage.cpp @@ -0,0 +1,60 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (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 http://www.qtsoftware.com/contact. +** +**************************************************************************/ + +#include "checkoutwizardpage.h" + +namespace Subversion { +namespace Internal { + +CheckoutWizardPage::CheckoutWizardPage(QWidget *parent) : + VCSBase::BaseCheckoutWizardPage(parent) +{ + setSubTitle(tr("Specify repository, checkout directory and path.")); + setRepositoryLabel(tr("Repository:")); +} + +QString CheckoutWizardPage::directoryFromRepository(const QString &repoIn) const +{ + /* Try to figure out a good directory name from something like: + * "svn://<server>/path1/project" -> project */ + + QString repo = repoIn.trimmed(); + const QChar slash = QLatin1Char('/'); + // remove host + const int slashPos = repo.lastIndexOf(slash); + if (slashPos != -1) + repo.remove(0, slashPos + 1); + // fix invalid characters + const QChar dash = QLatin1Char('-'); + repo.replace(QLatin1Char('.'), QLatin1Char('-')); + return repo; +} + +} // namespace Internal +} // namespace Subversion diff --git a/src/plugins/subversion/checkoutwizardpage.h b/src/plugins/subversion/checkoutwizardpage.h new file mode 100644 index 0000000000000000000000000000000000000000..9fe01007ec2ada4a7cc1db0e793f1c2dd50f297e --- /dev/null +++ b/src/plugins/subversion/checkoutwizardpage.h @@ -0,0 +1,49 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (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 http://www.qtsoftware.com/contact. +** +**************************************************************************/ + +#ifndef CHECKOUTWIZARDPAGE_H +#define CHECKOUTWIZARDPAGE_H + +#include <vcsbase/basecheckoutwizardpage.h> + +namespace Subversion { +namespace Internal { + +class CheckoutWizardPage : public VCSBase::BaseCheckoutWizardPage { + Q_OBJECT +public: + CheckoutWizardPage(QWidget *parent = 0); + +protected: + virtual QString directoryFromRepository(const QString &r) const; +}; + +} // namespace Internal +} // namespace Subversion +#endif // CHECKOUTWIZARDPAGE_H diff --git a/src/plugins/subversion/checkoutwizardpage.ui b/src/plugins/subversion/checkoutwizardpage.ui new file mode 100644 index 0000000000000000000000000000000000000000..74e5ed5069fec90bbc255a9ed68a18ffe3c7554f --- /dev/null +++ b/src/plugins/subversion/checkoutwizardpage.ui @@ -0,0 +1,84 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>Subversion::Internal::CheckoutWizardPage</class> + <widget class="QWizardPage" name="Subversion::Internal::CheckoutWizardPage"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>464</width> + <height>302</height> + </rect> + </property> + <property name="windowTitle"> + <string>WizardPage</string> + </property> + <property name="subTitle"> + <string>Specify path and repository URL.</string> + </property> + <layout class="QHBoxLayout" name="horizontalLayout"> + <item> + <layout class="QFormLayout" name="formLayout"> + <item row="0" column="0"> + <widget class="QLabel" name="repositoryLabel"> + <property name="text"> + <string>Clone URL:</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QLineEdit" name="repositoryLineEdit"/> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="checkoutDirectoryLabel"> + <property name="text"> + <string>Checkout Directory:</string> + </property> + </widget> + </item> + <item row="2" column="0"> + <widget class="QLabel" name="pathLabel"> + <property name="text"> + <string>Path:</string> + </property> + </widget> + </item> + <item row="2" column="1"> + <widget class="Core::Utils::PathChooser" name="pathChooser"/> + </item> + <item row="1" column="1"> + <widget class="Core::Utils::ProjectNameValidatingLineEdit" name="checkoutDirectoryLineEdit"/> + </item> + </layout> + </item> + <item> + <spacer name="horizontalSpacer"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + </layout> + </widget> + <customwidgets> + <customwidget> + <class>Core::Utils::ProjectNameValidatingLineEdit</class> + <extends>QLineEdit</extends> + <header location="global">utils/projectnamevalidatinglineedit.h</header> + </customwidget> + <customwidget> + <class>Core::Utils::PathChooser</class> + <extends>QWidget</extends> + <header location="global">utils/pathchooser.h</header> + <container>1</container> + </customwidget> + </customwidgets> + <resources/> + <connections/> +</ui> diff --git a/src/plugins/subversion/subversion.pro b/src/plugins/subversion/subversion.pro index 985a32648e1b5f49500fd0477e09f39b42a45aac..b046bec88656b7f24fcca85ad7b1a1ee98ffa0d6 100644 --- a/src/plugins/subversion/subversion.pro +++ b/src/plugins/subversion/subversion.pro @@ -15,7 +15,9 @@ HEADERS += annotationhighlighter.h \ settingspage.h \ subversioneditor.h \ subversionsubmiteditor.h \ - subversionsettings.h + subversionsettings.h \ + checkoutwizard.h \ + checkoutwizardpage.h SOURCES += annotationhighlighter.cpp \ subversionplugin.cpp \ @@ -24,9 +26,12 @@ SOURCES += annotationhighlighter.cpp \ settingspage.cpp \ subversioneditor.cpp \ subversionsubmiteditor.cpp \ - subversionsettings.cpp + subversionsettings.cpp \ + checkoutwizard.cpp \ + checkoutwizardpage.cpp -FORMS += settingspage.ui +FORMS += settingspage.ui \ + checkoutwizardpage.ui RESOURCES += subversion.qrc diff --git a/src/plugins/subversion/subversionplugin.cpp b/src/plugins/subversion/subversionplugin.cpp index 21c3e5b9a38a0ceb8425f8ccb42a2c8b9d88adda..e25750fe217ad4a4e13cbd68cd848688581bdb8a 100644 --- a/src/plugins/subversion/subversionplugin.cpp +++ b/src/plugins/subversion/subversionplugin.cpp @@ -36,6 +36,7 @@ #include "subversionsubmiteditor.h" #include "subversionconstants.h" #include "subversioncontrol.h" +#include "checkoutwizard.h" #include <vcsbase/basevcseditorfactory.h> #include <vcsbase/vcsbaseeditor.h> @@ -269,6 +270,8 @@ bool SubversionPlugin::initialize(const QStringList &arguments, QString *errorMe m_subversionOutputWindow = new SubversionOutputWindow(this); addAutoReleasedObject(m_subversionOutputWindow); + addAutoReleasedObject(new CheckoutWizard); + //register actions Core::ActionManager *ami = core->actionManager(); Core::ActionContainer *toolsContainer = ami->actionContainer(M_TOOLS); diff --git a/src/plugins/texteditor/basetexteditor.cpp b/src/plugins/texteditor/basetexteditor.cpp index 72c1f48b118a77a3b8798c2e56994013b0e6d69b..c53d617d7af274f76df773113a46b66918486ef6 100644 --- a/src/plugins/texteditor/basetexteditor.cpp +++ b/src/plugins/texteditor/basetexteditor.cpp @@ -4143,7 +4143,7 @@ BaseTextEditorEditable::~BaseTextEditorEditable() delete e; } -QToolBar *BaseTextEditorEditable::toolBar() +QWidget *BaseTextEditorEditable::toolBar() { return m_toolBar; } diff --git a/src/plugins/texteditor/basetexteditor.h b/src/plugins/texteditor/basetexteditor.h index 5bcf962ed9e1c411287576348f951130c82548a9..9fb764aae2f1ebc68e2240ae6bd39e642e0f04a8 100644 --- a/src/plugins/texteditor/basetexteditor.h +++ b/src/plugins/texteditor/basetexteditor.h @@ -573,7 +573,7 @@ public: inline QByteArray saveState() const { return e->saveState(); } inline bool restoreState(const QByteArray &state) { return e->restoreState(state); } - QToolBar *toolBar(); + QWidget *toolBar(); // ITextEditor int find(const QString &string) const; diff --git a/src/plugins/texteditor/editcolorschemedialog.cpp b/src/plugins/texteditor/editcolorschemedialog.cpp index 840908c7f9f5f3b00a40df13c364f208ba330e00..207cd50e43aa63b977bc702e11476a28118f786a 100644 --- a/src/plugins/texteditor/editcolorschemedialog.cpp +++ b/src/plugins/texteditor/editcolorschemedialog.cpp @@ -85,8 +85,6 @@ public: QColor background = m_scheme.formatFor(description.name()).background(); if (background.isValid()) return background; - else - return m_scheme.formatFor(QLatin1String(TextEditor::Constants::C_TEXT)).background(); } case Qt::FontRole: { QFont font = m_baseFont; @@ -141,6 +139,8 @@ EditColorSchemeDialog::EditColorSchemeDialog(const FormatDescriptions &fd, if (!m_descriptions.empty()) m_ui->itemList->setCurrentIndex(m_formatsModel->index(0)); + + setItemListBackground(m_scheme.formatFor(QLatin1String(TextEditor::Constants::C_TEXT)).background()); } EditColorSchemeDialog::~EditColorSchemeDialog() @@ -173,7 +173,6 @@ void EditColorSchemeDialog::itemChanged(const QModelIndex &index) const bool italicBlocked = m_ui->italicCheckBox->blockSignals(true); m_ui->italicCheckBox->setChecked(format.italic()); m_ui->italicCheckBox->blockSignals(italicBlocked); - updatePreview(); } void EditColorSchemeDialog::changeForeColor() @@ -193,8 +192,6 @@ void EditColorSchemeDialog::changeForeColor() m_scheme.formatFor(category).setForeground(newColor); m_formatsModel->emitDataChanged(index); } - - updatePreview(); } void EditColorSchemeDialog::changeBackColor() @@ -212,9 +209,10 @@ void EditColorSchemeDialog::changeBackColor() const QString category = m_descriptions[index.row()].name(); m_scheme.formatFor(category).setBackground(newColor); m_formatsModel->emitDataChanged(index); + // Synchronize item list background with text background + if (index.row() == 0) + setItemListBackground(newColor); } - - updatePreview(); } void EditColorSchemeDialog::eraseBackColor() @@ -230,8 +228,6 @@ void EditColorSchemeDialog::eraseBackColor() m_scheme.formatFor(category).setBackground(newColor); m_formatsModel->emitDataChanged(index); } - - updatePreview(); } void EditColorSchemeDialog::checkCheckBoxes() @@ -245,40 +241,11 @@ void EditColorSchemeDialog::checkCheckBoxes() m_scheme.formatFor(category).setItalic(m_ui->italicCheckBox->isChecked()); m_formatsModel->emitDataChanged(index); } - - updatePreview(); } -void EditColorSchemeDialog::updatePreview() +void EditColorSchemeDialog::setItemListBackground(const QColor &color) { - if (m_curItem == -1) - return; - - const Format ¤tFormat = m_scheme.formatFor(m_descriptions[m_curItem].name()); - const Format &baseFormat = m_scheme.formatFor(QLatin1String("Text")); - - QPalette pal = QApplication::palette(); - if (baseFormat.foreground().isValid()) { - pal.setColor(QPalette::Text, baseFormat.foreground()); - pal.setColor(QPalette::Foreground, baseFormat.foreground()); - } - if (baseFormat.background().isValid()) - pal.setColor(QPalette::Base, baseFormat.background()); - - m_ui->previewTextEdit->setPalette(pal); - - QTextCharFormat format; - if (currentFormat.foreground().isValid()) - format.setForeground(QBrush(currentFormat.foreground())); - if (currentFormat.background().isValid()) - format.setBackground(QBrush(currentFormat.background())); - format.setFontFamily(m_fontSettings.family()); - format.setFontStyleStrategy(m_fontSettings.antialias() ? QFont::PreferAntialias : QFont::NoAntialias); - format.setFontPointSize(m_fontSettings.fontSize()); - format.setFontItalic(currentFormat.italic()); - if (currentFormat.bold()) - format.setFontWeight(QFont::Bold); - m_ui->previewTextEdit->setCurrentCharFormat(format); - - m_ui->previewTextEdit->setPlainText(tr("\n\tThis is only an example.")); + QPalette pal = m_ui->itemList->palette(); + pal.setColor(QPalette::Base, color); + m_ui->itemList->setPalette(pal); } diff --git a/src/plugins/texteditor/editcolorschemedialog.h b/src/plugins/texteditor/editcolorschemedialog.h index 5aa5d9a8c6732de628af573811816cdc2a9ba565..ef637aea541fc6ef6321057b6b110b7712f14edd 100644 --- a/src/plugins/texteditor/editcolorschemedialog.h +++ b/src/plugins/texteditor/editcolorschemedialog.h @@ -69,9 +69,10 @@ private slots: void changeBackColor(); void eraseBackColor(); void checkCheckBoxes(); - void updatePreview(); private: + void setItemListBackground(const QColor &color); + const TextEditor::FormatDescriptions m_descriptions; const FontSettings m_fontSettings; diff --git a/src/plugins/texteditor/editcolorschemedialog.ui b/src/plugins/texteditor/editcolorschemedialog.ui index bb81b75a6be2ad5fb255df09121c32e0fbdea58c..a23d8e2ca2db2c117bcc96616a072fe9a9005c0e 100644 --- a/src/plugins/texteditor/editcolorschemedialog.ui +++ b/src/plugins/texteditor/editcolorschemedialog.ui @@ -6,8 +6,8 @@ <rect> <x>0</x> <y>0</y> - <width>425</width> - <height>461</height> + <width>461</width> + <height>352</height> </rect> </property> <property name="windowTitle"> @@ -157,37 +157,6 @@ </layout> </widget> </item> - <item> - <widget class="QGroupBox" name="groupBox_3"> - <property name="title"> - <string>Preview</string> - </property> - <layout class="QVBoxLayout" name="verticalLayout_2"> - <item> - <widget class="QTextEdit" name="previewTextEdit"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Expanding" vsizetype="Expanding"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="maximumSize"> - <size> - <width>16777215</width> - <height>75</height> - </size> - </property> - <property name="focusPolicy"> - <enum>Qt::NoFocus</enum> - </property> - <property name="readOnly"> - <bool>true</bool> - </property> - </widget> - </item> - </layout> - </widget> - </item> <item> <widget class="QDialogButtonBox" name="buttonBox"> <property name="orientation"> diff --git a/src/plugins/texteditor/fontsettingspage.cpp b/src/plugins/texteditor/fontsettingspage.cpp index 6698230b8747d978ed59b5d57e2e1f545fb9650f..b6f371594e6336a1e72042bd18b10a31f42214f2 100644 --- a/src/plugins/texteditor/fontsettingspage.cpp +++ b/src/plugins/texteditor/fontsettingspage.cpp @@ -55,6 +55,61 @@ namespace TextEditor { namespace Internal { +struct ColorSchemeEntry +{ + ColorSchemeEntry(const QString &fileName, + bool readOnly): + fileName(fileName), + name(ColorScheme::readNameOfScheme(fileName)), + readOnly(readOnly) + { } + + QString fileName; + QString name; + bool readOnly; +}; + + +class SchemeListModel : public QAbstractListModel +{ +public: + SchemeListModel(QObject *parent = 0): + QAbstractListModel(parent) + { + } + + int rowCount(const QModelIndex &parent) const + { return parent.isValid() ? 0 : m_colorSchemes.size(); } + + QVariant data(const QModelIndex &index, int role) const + { + if (role == Qt::DisplayRole) + return m_colorSchemes.at(index.row()).name; + + return QVariant(); + } + + void removeColorScheme(int index) + { + beginRemoveRows(QModelIndex(), index, index); + m_colorSchemes.removeAt(index); + endRemoveRows(); + } + + void setColorSchemes(const QList<ColorSchemeEntry> &colorSchemes) + { + m_colorSchemes = colorSchemes; + reset(); + } + + const ColorSchemeEntry &colorSchemeAt(int index) const + { return m_colorSchemes.at(index); } + +private: + QList<ColorSchemeEntry> m_colorSchemes; +}; + + class FontSettingsPagePrivate { public: @@ -62,6 +117,7 @@ public: const QString &name, const QString &category, const QString &trCategory); + ~FontSettingsPagePrivate(); public: const QString m_name; @@ -73,20 +129,12 @@ public: FontSettings m_value; FontSettings m_lastValue; Ui::FontSettingsPage ui; -}; - -struct ColorSchemeEntry -{ - QString fileName; - QString name; - bool readOnly; + SchemeListModel *m_schemeListModel; }; } // namespace Internal } // namespace TextEditor -Q_DECLARE_METATYPE(TextEditor::Internal::ColorSchemeEntry) - using namespace TextEditor; using namespace TextEditor::Internal; @@ -129,7 +177,8 @@ FontSettingsPagePrivate::FontSettingsPagePrivate(const TextEditor::FormatDescrip m_settingsGroup(Core::Utils::settingsKey(category)), m_category(category), m_trCategory(trCategory), - m_descriptions(fd) + m_descriptions(fd), + m_schemeListModel(new SchemeListModel) { bool settingsFound = false; QSettings *settings = Core::ICore::instance()->settings(); @@ -168,6 +217,11 @@ FontSettingsPagePrivate::FontSettingsPagePrivate(const TextEditor::FormatDescrip m_lastValue = m_value; } +FontSettingsPagePrivate::~FontSettingsPagePrivate() +{ + delete m_schemeListModel; +} + // ------- FormatDescription FormatDescription::FormatDescription(const QString &name, const QString &trName, const QColor &color) : @@ -282,10 +336,7 @@ QWidget *FontSettingsPage::createPage(QWidget *parent) { QWidget *w = new QWidget(parent); d_ptr->ui.setupUi(w); - - d_ptr->ui.schemeListWidget->addItem(tr("Default")); - d_ptr->ui.schemeListWidget->setCurrentIndex(d_ptr->ui.schemeListWidget->model()->index(0, 0)); - d_ptr->ui.editButton->setEnabled(true); + d_ptr->ui.schemeComboBox->setModel(d_ptr->m_schemeListModel); QFontDatabase db; const QStringList families = db.families(); @@ -296,8 +347,7 @@ QWidget *FontSettingsPage::createPage(QWidget *parent) d_ptr->ui.antialias->setChecked(d_ptr->m_value.antialias()); connect(d_ptr->ui.familyComboBox, SIGNAL(activated(int)), this, SLOT(updatePointSizes())); - connect(d_ptr->ui.schemeListWidget, SIGNAL(currentItemChanged(QListWidgetItem*,QListWidgetItem*)), - this, SLOT(colorSchemeSelected(QListWidgetItem*))); + connect(d_ptr->ui.schemeComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(colorSchemeSelected(int))); connect(d_ptr->ui.cloneButton, SIGNAL(clicked()), this, SLOT(cloneColorScheme())); connect(d_ptr->ui.editButton, SIGNAL(clicked()), this, SLOT(editColorScheme())); connect(d_ptr->ui.deleteButton, SIGNAL(clicked()), this, SLOT(deleteColorScheme())); @@ -332,25 +382,25 @@ void FontSettingsPage::updatePointSizes() d_ptr->ui.sizeComboBox->setCurrentIndex(idx); } -void FontSettingsPage::colorSchemeSelected(QListWidgetItem *item) +void FontSettingsPage::colorSchemeSelected(int index) { bool modifiable = false; - if (item) { - const ColorSchemeEntry entry = item->data(Qt::UserRole).value<ColorSchemeEntry>(); + if (index != -1) { + const ColorSchemeEntry &entry = d_ptr->m_schemeListModel->colorSchemeAt(index); modifiable = !entry.readOnly; } - d_ptr->ui.cloneButton->setEnabled(item != 0); + d_ptr->ui.cloneButton->setEnabled(index != -1); d_ptr->ui.deleteButton->setEnabled(modifiable); d_ptr->ui.editButton->setEnabled(modifiable); } void FontSettingsPage::cloneColorScheme() { - QListWidgetItem *item = d_ptr->ui.schemeListWidget->currentItem(); - if (!item) + int index = d_ptr->ui.schemeComboBox->currentIndex(); + if (index == -1) return; - const ColorSchemeEntry entry = item->data(Qt::UserRole).value<ColorSchemeEntry>(); + const ColorSchemeEntry &entry = d_ptr->m_schemeListModel->colorSchemeAt(index); // Load the currently selected color scheme if (!d_ptr->m_value.loadColorScheme(entry.fileName, d_ptr->m_descriptions)) @@ -372,11 +422,12 @@ void FontSettingsPage::cloneColorScheme() void FontSettingsPage::deleteColorScheme() { - QListWidgetItem *item = d_ptr->ui.schemeListWidget->currentItem(); - if (!item) + int index = d_ptr->ui.schemeComboBox->currentIndex(); + if (index == -1) return; - const ColorSchemeEntry entry = item->data(Qt::UserRole).value<ColorSchemeEntry>(); + const ColorSchemeEntry &entry = d_ptr->m_schemeListModel->colorSchemeAt(index); + if (!entry.readOnly) { int ret = QMessageBox::warning(d_ptr->ui.deleteButton->window(), tr("Delete Color Scheme"), @@ -384,17 +435,18 @@ void FontSettingsPage::deleteColorScheme() QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes); if (ret == QMessageBox::Yes && QFile::remove(entry.fileName)) - refreshColorSchemeList(); + d_ptr->m_schemeListModel->removeColorScheme(index); } } void FontSettingsPage::editColorScheme() { - QListWidgetItem *item = d_ptr->ui.schemeListWidget->currentItem(); - if (!item) + int index = d_ptr->ui.schemeComboBox->currentIndex(); + if (index == -1) return; - const ColorSchemeEntry entry = item->data(Qt::UserRole).value<ColorSchemeEntry>(); + const ColorSchemeEntry &entry = d_ptr->m_schemeListModel->colorSchemeAt(index); + if (entry.readOnly) return; @@ -421,21 +473,9 @@ void FontSettingsPage::editColorScheme() } } -void FontSettingsPage::addColorSchemeEntry(const QString &fileName, bool readOnly) -{ - ColorSchemeEntry entry; - entry.fileName = fileName; - entry.name = ColorScheme::readNameOfScheme(fileName); - entry.readOnly = readOnly; - - QListWidgetItem *item = new QListWidgetItem(entry.name); - item->setData(Qt::UserRole, QVariant::fromValue<ColorSchemeEntry>(entry)); - d_ptr->ui.schemeListWidget->addItem(item); -} - void FontSettingsPage::refreshColorSchemeList() { - d_ptr->ui.schemeListWidget->clear(); + QList<ColorSchemeEntry> colorSchemes; QString resourcePath = Core::ICore::instance()->resourcePath(); QDir styleDir(resourcePath + QLatin1String("/styles")); @@ -443,28 +483,25 @@ void FontSettingsPage::refreshColorSchemeList() styleDir.setFilter(QDir::Files); int selected = 0; - int count = 0; foreach (const QString &file, styleDir.entryList()) { const QString fileName = styleDir.absoluteFilePath(file); - addColorSchemeEntry(fileName, true); if (d_ptr->m_value.colorSchemeFileName() == fileName) - selected = count; - ++count; + selected = colorSchemes.size(); + colorSchemes.append(ColorSchemeEntry(fileName, true)); } styleDir.setPath(customStylesPath()); foreach (const QString &file, styleDir.entryList()) { const QString fileName = styleDir.absoluteFilePath(file); - addColorSchemeEntry(fileName, false); if (d_ptr->m_value.colorSchemeFileName() == fileName) - selected = count; - ++count; + selected = colorSchemes.size(); + colorSchemes.append(ColorSchemeEntry(fileName, false)); } - const QModelIndex s = d_ptr->ui.schemeListWidget->model()->index(selected, 0); - d_ptr->ui.schemeListWidget->setCurrentIndex(s); + d_ptr->m_schemeListModel->setColorSchemes(colorSchemes); + d_ptr->ui.schemeComboBox->setCurrentIndex(selected); } void FontSettingsPage::delayedChange() @@ -477,8 +514,9 @@ void FontSettingsPage::apply() d_ptr->m_value.setFamily(d_ptr->ui.familyComboBox->currentText()); d_ptr->m_value.setAntialias(d_ptr->ui.antialias->isChecked()); - if (QListWidgetItem *item = d_ptr->ui.schemeListWidget->currentItem()) { - const ColorSchemeEntry entry = item->data(Qt::UserRole).value<ColorSchemeEntry>(); + int index = d_ptr->ui.schemeComboBox->currentIndex(); + if (index != -1) { + const ColorSchemeEntry &entry = d_ptr->m_schemeListModel->colorSchemeAt(index); if (entry.fileName != d_ptr->m_value.colorSchemeFileName()) d_ptr->m_value.loadColorScheme(entry.fileName, d_ptr->m_descriptions); } diff --git a/src/plugins/texteditor/fontsettingspage.h b/src/plugins/texteditor/fontsettingspage.h index af009d75d443717b9e5328d1970abd7b3e3926d8..5ffc34218ce741e60103ecd8beb26f283e02e8ea 100644 --- a/src/plugins/texteditor/fontsettingspage.h +++ b/src/plugins/texteditor/fontsettingspage.h @@ -42,7 +42,6 @@ #include <QtCore/QVector> QT_BEGIN_NAMESPACE -class QListWidgetItem; class QWidget; QT_END_NAMESPACE @@ -111,13 +110,12 @@ signals: private slots: void delayedChange(); void updatePointSizes(); - void colorSchemeSelected(QListWidgetItem *item); + void colorSchemeSelected(int index); void cloneColorScheme(); void deleteColorScheme(); void editColorScheme(); private: - void addColorSchemeEntry(const QString &fileName, bool readOnly); void refreshColorSchemeList(); Internal::FontSettingsPagePrivate *d_ptr; diff --git a/src/plugins/texteditor/fontsettingspage.ui b/src/plugins/texteditor/fontsettingspage.ui index d6e249bd930bfcf1b1c81846567641a02b3e4811..2ff5268962bc3f35a90fa788da61925c7996abca 100644 --- a/src/plugins/texteditor/fontsettingspage.ui +++ b/src/plugins/texteditor/fontsettingspage.ui @@ -6,8 +6,8 @@ <rect> <x>0</x> <y>0</y> - <width>391</width> - <height>344</height> + <width>344</width> + <height>306</height> </rect> </property> <layout class="QVBoxLayout" name="verticalLayout"> @@ -107,25 +107,66 @@ <property name="title"> <string>Color Scheme</string> </property> - <layout class="QGridLayout" name="gridLayout_2"> - <item row="0" column="1"> - <widget class="QPushButton" name="cloneButton"> - <property name="text"> - <string>Clone</string> - </property> - </widget> + <layout class="QVBoxLayout" name="verticalLayout_2"> + <item> + <layout class="QHBoxLayout" name="horizontalLayout"> + <item> + <widget class="QComboBox" name="schemeComboBox"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> + <horstretch>1</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="cloneButton"> + <property name="text"> + <string>Clone</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="deleteButton"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="text"> + <string>Delete</string> + </property> + </widget> + </item> + </layout> </item> - <item row="2" column="1"> - <widget class="QPushButton" name="deleteButton"> - <property name="enabled"> - <bool>false</bool> - </property> - <property name="text"> - <string>Delete</string> - </property> - </widget> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_2"> + <item> + <widget class="QPushButton" name="editButton"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="text"> + <string>Edit</string> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + </layout> </item> - <item row="4" column="1"> + <item> <spacer name="verticalSpacer"> <property name="orientation"> <enum>Qt::Vertical</enum> @@ -138,19 +179,6 @@ </property> </spacer> </item> - <item row="0" column="0" rowspan="5"> - <widget class="QListWidget" name="schemeListWidget"/> - </item> - <item row="1" column="1"> - <widget class="QPushButton" name="editButton"> - <property name="enabled"> - <bool>false</bool> - </property> - <property name="text"> - <string>Edit</string> - </property> - </widget> - </item> </layout> </widget> </item> diff --git a/src/plugins/vcsbase/basecheckoutwizard.cpp b/src/plugins/vcsbase/basecheckoutwizard.cpp new file mode 100644 index 0000000000000000000000000000000000000000..384fea0a05b2a102aeaddd8332deba19c212af1f --- /dev/null +++ b/src/plugins/vcsbase/basecheckoutwizard.cpp @@ -0,0 +1,150 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (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 http://www.qtsoftware.com/contact. +** +**************************************************************************/ + +#include "basecheckoutwizard.h" +#include "vcsbaseconstants.h" +#include "checkoutwizarddialog.h" +#include "checkoutjobs.h" + +#include <projectexplorer/projectexplorer.h> +#include <projectexplorer/session.h> + +#include <QtCore/QCoreApplication> +#include <QtCore/QFileInfo> +#include <QtCore/QDir> +#include <QtGui/QMessageBox> + +namespace VCSBase { + +struct BaseCheckoutWizardPrivate { + BaseCheckoutWizardPrivate() : dialog(0), parameterPage(0) {} + void clear(); + + Internal::CheckoutWizardDialog *dialog; + QWizardPage *parameterPage; + QString checkoutPath; +}; + +void BaseCheckoutWizardPrivate::clear() +{ + parameterPage = 0; + dialog = 0; + checkoutPath.clear(); +} + +BaseCheckoutWizard::BaseCheckoutWizard(QObject *parent) : + Core::IWizard(parent), + d(new BaseCheckoutWizardPrivate) +{ +} + +BaseCheckoutWizard::~BaseCheckoutWizard() +{ + delete d; +} + +Core::IWizard::Kind BaseCheckoutWizard::kind() const +{ + return Core::IWizard::ProjectWizard; +} + +QString BaseCheckoutWizard::category() const +{ + return QLatin1String(VCSBase::Constants::VCS_WIZARD_CATEGORY); +} + +QString BaseCheckoutWizard::trCategory() const +{ + return QCoreApplication::translate("VCSBase", VCSBase::Constants::VCS_WIZARD_CATEGORY); +} + +QStringList BaseCheckoutWizard::runWizard(const QString &path, QWidget *parent) +{ + // Create dialog and launch + d->parameterPage = createParameterPage(path); + Internal::CheckoutWizardDialog dialog(d->parameterPage, parent); + d->dialog = &dialog; + connect(&dialog, SIGNAL(progressPageShown()), this, SLOT(slotProgressPageShown())); + dialog.setWindowTitle(name()); + if (dialog.exec() != QDialog::Accepted) + return QStringList(); + // Now try to find the project file and open + const QString checkoutPath = d->checkoutPath; + d->clear(); + QString errorMessage; + const QString projectFile = openProject(checkoutPath, &errorMessage); + if (projectFile.isEmpty()) { + QMessageBox msgBox(QMessageBox::Warning, tr("Cannot Open Project"), + tr("Failed to open project in '%1'").arg(checkoutPath)); + msgBox.setDetailedText(errorMessage); + msgBox.exec(); + return QStringList(); + } + return QStringList(projectFile); +} + +QString BaseCheckoutWizard::openProject(const QString &path, QString *errorMessage) +{ + ProjectExplorer::ProjectExplorerPlugin *pe = ProjectExplorer::ProjectExplorerPlugin::instance(); + if (!pe) { + *errorMessage = tr("The Project Explorer is not available."); + return QString(); + } + + // Search the directory for project files + const QDir dir(path); + if (!dir.exists()) { + *errorMessage = tr("'%1' does not exist.").arg(path); // Should not happen + return QString(); + } + // Hardcoded: Find *.pro/Cmakefiles + QStringList patterns; + patterns << QLatin1String("*.pro") << QLatin1String("CMakeList.txt"); + QFileInfoList projectFiles = dir.entryInfoList(patterns, QDir::Files|QDir::NoDotAndDotDot|QDir::Readable); + if (projectFiles.empty()) { + *errorMessage = tr("No project files could be found (%1).").arg(patterns.join(QLatin1String(", "))); + return QString(); + } + // Open! + const QString projectFile = projectFiles.front().absoluteFilePath(); + if (!pe->openProject(projectFile)) { + *errorMessage = tr("Unable to open the project '%1'.").arg(projectFile); + return QString(); + } + return projectFile; +} + +void BaseCheckoutWizard::slotProgressPageShown() +{ + const QSharedPointer<AbstractCheckoutJob> job = createJob(d->parameterPage, &(d->checkoutPath)); + if (!job.isNull()) + d->dialog->start(job); +} + +} // namespace VCSBase diff --git a/src/plugins/vcsbase/basecheckoutwizard.h b/src/plugins/vcsbase/basecheckoutwizard.h new file mode 100644 index 0000000000000000000000000000000000000000..a8091b2002401b219c84594516668030842b682b --- /dev/null +++ b/src/plugins/vcsbase/basecheckoutwizard.h @@ -0,0 +1,92 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (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 http://www.qtsoftware.com/contact. +** +**************************************************************************/ + +#ifndef BASECHECKOUTWIZARD_H +#define BASECHECKOUTWIZARD_H + +#include "vcsbase_global.h" +#include <coreplugin/dialogs/iwizard.h> + +#include <QtCore/QSharedPointer> + +QT_BEGIN_NAMESPACE +class QWizardPage; +QT_END_NAMESPACE + +namespace VCSBase { + +class AbstractCheckoutJob; +struct BaseCheckoutWizardPrivate; + +/* A Core::IWizard implementing a wizard for initially checking + * out a project using a version control system. + * Implements all of Core::IWizard with the exception of + * name()/description() and icon(). + * Pops up a QWizard consisting of a Parameter Page which is created + * by a virtual factory function and a progress + * page containing a log text. The factory function createJob() + * creates a job with the output connected to the log window, + * returning the path to the checkout. + * On success, the wizard tries to locate a project file + * and open it. + * BaseCheckoutWizardPage is provided as a convenience base class + * for parameter wizard pages. */ + +class VCSBASE_EXPORT BaseCheckoutWizard : public Core::IWizard +{ + Q_OBJECT + +public: + explicit BaseCheckoutWizard(QObject *parent = 0); + virtual ~BaseCheckoutWizard(); + + virtual Kind kind() const; + + virtual QString category() const; + virtual QString trCategory() const; + + virtual QStringList runWizard(const QString &path, QWidget *parent); + +protected: + virtual QWizardPage *createParameterPage(const QString &path) = 0; + virtual QSharedPointer<AbstractCheckoutJob> createJob(const QWizardPage *parameterPage, + QString *checkoutPath) = 0; + +private slots: + void slotProgressPageShown(); + +private: + QString openProject(const QString &path, QString *errorMessage); + + BaseCheckoutWizardPrivate *d; +}; + +} // namespace VCSBase + +#endif // BASECHECKOUTWIZARD_H diff --git a/src/plugins/vcsbase/basecheckoutwizardpage.cpp b/src/plugins/vcsbase/basecheckoutwizardpage.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f9fdb1a69774d3ee328a1cfa36d53cac284779a7 --- /dev/null +++ b/src/plugins/vcsbase/basecheckoutwizardpage.cpp @@ -0,0 +1,148 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (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 http://www.qtsoftware.com/contact. +** +**************************************************************************/ + +#include "basecheckoutwizardpage.h" +#include "ui_basecheckoutwizardpage.h" + +namespace VCSBase { + +struct BaseCheckoutWizardPagePrivate { + BaseCheckoutWizardPagePrivate() : m_valid(false), m_directoryEdited(false) {} + + Ui::BaseCheckoutWizardPage ui; + bool m_valid; + bool m_directoryEdited; +}; + +BaseCheckoutWizardPage::BaseCheckoutWizardPage(QWidget *parent) : + QWizardPage(parent), + d(new BaseCheckoutWizardPagePrivate) +{ + d->ui.setupUi(this); + d->ui.pathChooser->setExpectedKind(Core::Utils::PathChooser::Directory); + connect(d->ui.pathChooser, SIGNAL(validChanged()), this, SLOT(slotChanged())); + connect(d->ui.checkoutDirectoryLineEdit, SIGNAL(validChanged()), + this, SLOT(slotChanged())); + connect(d->ui.repositoryLineEdit, SIGNAL(textChanged(QString)), this, SLOT(slotRepositoryChanged(QString))); + connect(d->ui.checkoutDirectoryLineEdit, SIGNAL(textEdited(QString)), this, SLOT(slotDirectoryEdited())); +} + +BaseCheckoutWizardPage::~BaseCheckoutWizardPage() +{ + delete d; +} + +void BaseCheckoutWizardPage::setRepositoryLabel(const QString &l) +{ + d->ui.repositoryLabel->setText(l); +} + +QString BaseCheckoutWizardPage::path() const +{ + return d->ui.pathChooser->path(); +} + +void BaseCheckoutWizardPage::setPath(const QString &p) +{ + d->ui.pathChooser->setPath(p); +} + +QString BaseCheckoutWizardPage::directory() const +{ + return d->ui.checkoutDirectoryLineEdit->text(); +} + +void BaseCheckoutWizardPage::setDirectory(const QString &dir) +{ + d->ui.checkoutDirectoryLineEdit->setText(dir); +} + +void BaseCheckoutWizardPage::setDirectoryVisible(bool v) +{ + d->ui.checkoutDirectoryLabel->setVisible(v); + d->ui.checkoutDirectoryLineEdit->setVisible(v); +} + +QString BaseCheckoutWizardPage::repository() const +{ + return d->ui.repositoryLineEdit->text().trimmed(); +} + +void BaseCheckoutWizardPage::setRepository(const QString &r) +{ + d->ui.repositoryLineEdit->setText(r); +} + +void BaseCheckoutWizardPage::slotRepositoryChanged(const QString &repo) +{ + if (d->m_directoryEdited) + return; + d->ui.checkoutDirectoryLineEdit->setText(directoryFromRepository(repo)); +} + +QString BaseCheckoutWizardPage::directoryFromRepository(const QString &r) const +{ + return r; +} + +void BaseCheckoutWizardPage::slotDirectoryEdited() +{ + d->m_directoryEdited = true; +} + +void BaseCheckoutWizardPage::changeEvent(QEvent *e) +{ + QWizardPage::changeEvent(e); + switch (e->type()) { + case QEvent::LanguageChange: + d->ui.retranslateUi(this); + break; + default: + break; + } +} + +bool BaseCheckoutWizardPage::isComplete() const +{ + return d->m_valid; +} + +void BaseCheckoutWizardPage::slotChanged() +{ + const bool valid = d->ui.pathChooser->isValid() + && d->ui.checkoutDirectoryLineEdit->isValid() + && !d->ui.repositoryLineEdit->text().isEmpty(); + + if (valid != d->m_valid) { + d->m_valid = valid; + emit completeChanged(); + } +} + +} // namespace VCSBase diff --git a/src/plugins/vcsbase/basecheckoutwizardpage.h b/src/plugins/vcsbase/basecheckoutwizardpage.h new file mode 100644 index 0000000000000000000000000000000000000000..adf5d60dccc23548517dfabb30fb2a1c57d0cab5 --- /dev/null +++ b/src/plugins/vcsbase/basecheckoutwizardpage.h @@ -0,0 +1,88 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (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 http://www.qtsoftware.com/contact. +** +**************************************************************************/ + +#ifndef VCSBASE_CHECKOUTWIZARDPAGE_H +#define VCSBASE_CHECKOUTWIZARDPAGE_H + +#include "vcsbase_global.h" + +#include <QtGui/QWizardPage> + +namespace VCSBase { + +namespace Ui { + class BaseCheckoutWizardPage; +} + +struct BaseCheckoutWizardPagePrivate; + +/* Base class for a parameter page of a checkout wizard. + * Let's the user specify the repository, a checkout directory and + * the path. Contains a virtual to derive the checkout directory + * from the repository as it is entered. */ + +class VCSBASE_EXPORT BaseCheckoutWizardPage : public QWizardPage { + Q_OBJECT +public: + BaseCheckoutWizardPage(QWidget *parent = 0); + ~BaseCheckoutWizardPage(); + + QString path() const; + void setPath(const QString &); + + QString directory() const; + void setDirectory(const QString &d); + + QString repository() const; + void setRepository(const QString &r); + + virtual bool isComplete() const; + +protected: + void changeEvent(QEvent *e); + + void setRepositoryLabel(const QString &l); + void setDirectoryVisible(bool v); + + /* Determine a checkout directory name from + * repository URL, that is, "protocol:/project" -> "project". */ + virtual QString directoryFromRepository(const QString &r) const; + +private slots: + void slotRepositoryChanged(const QString &url); + void slotDirectoryEdited(); + void slotChanged(); + +private: + BaseCheckoutWizardPagePrivate *d; +}; + +} // namespace VCSBase + +#endif // VCSBASE_CHECKOUTWIZARDPAGE_H diff --git a/src/plugins/vcsbase/basecheckoutwizardpage.ui b/src/plugins/vcsbase/basecheckoutwizardpage.ui new file mode 100644 index 0000000000000000000000000000000000000000..46b1edfaf760cc8b10bedc0625f3138f2b5f4e00 --- /dev/null +++ b/src/plugins/vcsbase/basecheckoutwizardpage.ui @@ -0,0 +1,77 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>VCSBase::BaseCheckoutWizardPage</class> + <widget class="QWizardPage" name="VCSBase::BaseCheckoutWizardPage"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>464</width> + <height>302</height> + </rect> + </property> + <property name="windowTitle"> + <string>WizardPage</string> + </property> + <layout class="QHBoxLayout" name="horizontalLayout"> + <item> + <layout class="QFormLayout" name="formLayout"> + <item row="0" column="0"> + <widget class="QLabel" name="repositoryLabel"/> + </item> + <item row="0" column="1"> + <widget class="QLineEdit" name="repositoryLineEdit"/> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="checkoutDirectoryLabel"> + <property name="text"> + <string>Checkout Directory:</string> + </property> + </widget> + </item> + <item row="2" column="0"> + <widget class="QLabel" name="pathLabel"> + <property name="text"> + <string>Path:</string> + </property> + </widget> + </item> + <item row="2" column="1"> + <widget class="Core::Utils::PathChooser" name="pathChooser"/> + </item> + <item row="1" column="1"> + <widget class="Core::Utils::ProjectNameValidatingLineEdit" name="checkoutDirectoryLineEdit"/> + </item> + </layout> + </item> + <item> + <spacer name="horizontalSpacer"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + </layout> + </widget> + <customwidgets> + <customwidget> + <class>Core::Utils::ProjectNameValidatingLineEdit</class> + <extends>QLineEdit</extends> + <header location="global">utils/projectnamevalidatinglineedit.h</header> + </customwidget> + <customwidget> + <class>Core::Utils::PathChooser</class> + <extends>QWidget</extends> + <header location="global">utils/pathchooser.h</header> + <container>1</container> + </customwidget> + </customwidgets> + <resources/> + <connections/> +</ui> diff --git a/src/plugins/vcsbase/checkoutjobs.cpp b/src/plugins/vcsbase/checkoutjobs.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b3fe91e95f213b3922beaeecdad3379f26129839 --- /dev/null +++ b/src/plugins/vcsbase/checkoutjobs.cpp @@ -0,0 +1,138 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (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 http://www.qtsoftware.com/contact. +** +**************************************************************************/ + +#include "checkoutjobs.h" + +#include <QtCore/QDebug> + +enum { debug = 0 }; +namespace VCSBase { + +AbstractCheckoutJob::AbstractCheckoutJob(QObject *parent) : + QObject(parent) +{ +} + +struct ProcessCheckoutJobPrivate { + ProcessCheckoutJobPrivate(const QString &binary, + const QStringList &args, + const QString &workingDirectory, + const QStringList &env); + + QProcess process; + const QString binary; + const QStringList args; +}; + +ProcessCheckoutJobPrivate::ProcessCheckoutJobPrivate(const QString &b, + const QStringList &a, + const QString &workingDirectory, + const QStringList &env) : + binary(b), + args(a) +{ + if (!workingDirectory.isEmpty()) + process.setWorkingDirectory(workingDirectory); + if (!env.empty()) + process.setEnvironment(env); +} + +ProcessCheckoutJob::ProcessCheckoutJob(const QString &binary, + const QStringList &args, + const QString &workingDirectory, + const QStringList &env, + QObject *parent) : + AbstractCheckoutJob(parent), + d(new ProcessCheckoutJobPrivate(binary, args, workingDirectory, env)) +{ + if (debug) + qDebug() << "ProcessCheckoutJob" << binary << args << workingDirectory; + connect(&d->process, SIGNAL(error(QProcess::ProcessError)), this, SLOT(slotError(QProcess::ProcessError))); + connect(&d->process, SIGNAL(finished(int,QProcess::ExitStatus)), this, SLOT(slotFinished(int,QProcess::ExitStatus))); + connect(&d->process, SIGNAL(readyReadStandardOutput()), this, SLOT(slotOutput())); + d->process.setProcessChannelMode(QProcess::MergedChannels); + d->process.closeWriteChannel(); +} + +ProcessCheckoutJob::~ProcessCheckoutJob() +{ + delete d; +} + +void ProcessCheckoutJob::slotOutput() +{ + const QByteArray data = d->process.readAllStandardOutput(); + const QString s = QString::fromLocal8Bit(data, data.endsWith('\n') ? data.size() - 1: data.size()); + if (debug) + qDebug() << s; + emit output(s); +} + +void ProcessCheckoutJob::slotError(QProcess::ProcessError /* error */) +{ + emit failed(d->process.errorString()); +} + +void ProcessCheckoutJob::slotFinished (int exitCode, QProcess::ExitStatus exitStatus) +{ + if (debug) + qDebug() << "finished" << exitCode << exitStatus; + + switch (exitStatus) { + case QProcess::NormalExit: + emit output(tr("The process terminated with exit code %1.").arg(exitCode)); + if (exitCode == 0) { + emit succeeded(); + } else { + emit failed(tr("The process returned exit code %1.").arg(exitCode)); + } + break; + case QProcess::CrashExit: + emit failed(tr("The process terminated in an abnormal way.")); + break; + } +} + +void ProcessCheckoutJob::start() +{ + d->process.start(d->binary, d->args); +} + +void ProcessCheckoutJob::cancel() +{ + if (debug) + qDebug() << "ProcessCheckoutJob::start"; + + emit output(tr("Stopping...")); + d->process.terminate(); + if (!d->process.waitForFinished(5000)) + d->process.kill(); +} + +} // namespace VCSBase diff --git a/src/plugins/vcsbase/checkoutjobs.h b/src/plugins/vcsbase/checkoutjobs.h new file mode 100644 index 0000000000000000000000000000000000000000..fd1925648df3149d9e227d682bec1aa5275155b0 --- /dev/null +++ b/src/plugins/vcsbase/checkoutjobs.h @@ -0,0 +1,95 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (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 http://www.qtsoftware.com/contact. +** +**************************************************************************/ + +#ifndef CHECKOUTJOB_H +#define CHECKOUTJOB_H + +#include "vcsbase_global.h" + +#include <QtCore/QObject> +#include <QtCore/QStringList> +#include <QtCore/QProcess> + +QT_BEGIN_NAMESPACE +class QStringList; +class QByteArray; +QT_END_NAMESPACE + +namespace VCSBase { + +struct ProcessCheckoutJobPrivate; + +/* Abstract base class for a job creating an initial project checkout. + * It should be something that runs in the background producing log + * messages. */ + +class VCSBASE_EXPORT AbstractCheckoutJob : public QObject +{ + Q_OBJECT +public: + virtual void start() = 0; + virtual void cancel() = 0; + +protected: + explicit AbstractCheckoutJob(QObject *parent = 0); + +signals: + void succeeded(); + void failed(const QString &why); + void output(const QString &what); +}; + +/* Convenience implementation using a QProcess. */ + +class VCSBASE_EXPORT ProcessCheckoutJob : public AbstractCheckoutJob +{ + Q_OBJECT +public: + explicit ProcessCheckoutJob(const QString &binary, + const QStringList &args, + const QString &workingDirectory = QString(), + const QStringList &env = QStringList(), + QObject *parent = 0); + virtual ~ProcessCheckoutJob(); + + virtual void start(); + virtual void cancel(); + +private slots: + void slotError(QProcess::ProcessError error); + void slotFinished (int exitCode, QProcess::ExitStatus exitStatus); + void slotOutput(); + +private: + ProcessCheckoutJobPrivate *d; +}; + +} // namespace VCSBase + +#endif // CHECKOUTJOB_H diff --git a/src/plugins/vcsbase/checkoutprogresswizardpage.cpp b/src/plugins/vcsbase/checkoutprogresswizardpage.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ff727cac2de10a3db91ea30c017c47ce38613642 --- /dev/null +++ b/src/plugins/vcsbase/checkoutprogresswizardpage.cpp @@ -0,0 +1,118 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (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 http://www.qtsoftware.com/contact. +** +**************************************************************************/ + +#include "checkoutprogresswizardpage.h" +#include "checkoutjobs.h" +#include "ui_checkoutprogresswizardpage.h" + +#include <utils/qtcassert.h> + +#include <QtGui/QApplication> +#include <QtGui/QCursor> + +namespace VCSBase { +namespace Internal { + +CheckoutProgressWizardPage::CheckoutProgressWizardPage(QWidget *parent) : + QWizardPage(parent), + ui(new Ui::CheckoutProgressWizardPage), + m_state(Idle) +{ + ui->setupUi(this); +} + +CheckoutProgressWizardPage::~CheckoutProgressWizardPage() +{ + if (m_state == Running) // Paranoia! + QApplication::restoreOverrideCursor(); + delete ui; +} + +void CheckoutProgressWizardPage::start(const QSharedPointer<AbstractCheckoutJob> &job) +{ + QTC_ASSERT(m_state != Running, return) + m_job = job; + connect(job.data(), SIGNAL(output(QString)), ui->logPlainTextEdit, SLOT(appendPlainText(QString))); + connect(job.data(), SIGNAL(failed(QString)), this, SLOT(slotFailed(QString))); + connect(job.data(), SIGNAL(succeeded()), this, SLOT(slotSucceeded())); + QApplication::setOverrideCursor(Qt::WaitCursor); + ui->logPlainTextEdit->clear(); + setSubTitle(tr("Checkout started...")); + job->start(); + m_state = Running; + +} + +void CheckoutProgressWizardPage::slotFailed(const QString &why) +{ + ui->logPlainTextEdit->appendPlainText(why); + if (m_state == Running) { + m_state = Failed; + QApplication::restoreOverrideCursor(); + setSubTitle(tr("Failed.")); + emit terminated(false); + } +} + +void CheckoutProgressWizardPage::slotSucceeded() +{ + if (m_state == Running) { + m_state = Succeeded; + QApplication::restoreOverrideCursor(); + setSubTitle(tr("Succeeded.")); + emit completeChanged(); + emit terminated(true); + } +} + +void CheckoutProgressWizardPage::terminate() +{ + if (!m_job.isNull()) + m_job->cancel(); +} + +bool CheckoutProgressWizardPage::isComplete() const +{ + return m_state == Succeeded; +} + +void CheckoutProgressWizardPage::changeEvent(QEvent *e) +{ + QWizardPage::changeEvent(e); + switch (e->type()) { + case QEvent::LanguageChange: + ui->retranslateUi(this); + break; + default: + break; + } +} + +} // namespace Internal +} // namespace VCSBase diff --git a/src/plugins/vcsbase/checkoutprogresswizardpage.h b/src/plugins/vcsbase/checkoutprogresswizardpage.h new file mode 100644 index 0000000000000000000000000000000000000000..971bb29e901d96ffb7d30a8f3894b1a3238655c6 --- /dev/null +++ b/src/plugins/vcsbase/checkoutprogresswizardpage.h @@ -0,0 +1,84 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (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 http://www.qtsoftware.com/contact. +** +**************************************************************************/ + +#ifndef CHECKOUTPROGRESSWIZARDPAGE_H +#define CHECKOUTPROGRESSWIZARDPAGE_H + +#include <QtCore/QSharedPointer> +#include <QtGui/QWizardPage> + +namespace VCSBase { +class AbstractCheckoutJob; + +namespace Internal { + +namespace Ui { + class CheckoutProgressWizardPage; +} + +/* Page showing the progress of an initial project + * checkout. Turns complete when the job succeeds. */ + +class CheckoutProgressWizardPage : public QWizardPage { + Q_OBJECT + Q_DISABLE_COPY(CheckoutProgressWizardPage) + +public: + enum State { Idle, Running, Failed, Succeeded }; + + explicit CheckoutProgressWizardPage(QWidget *parent = 0); + ~CheckoutProgressWizardPage(); + + void start(const QSharedPointer<AbstractCheckoutJob> &job); + + virtual bool isComplete() const; + bool isRunning() const{ return m_state == Running; } + + void terminate(); + +signals: + void terminated(bool success); + +private slots: + void slotFailed(const QString &); + void slotSucceeded(); + +protected: + void changeEvent(QEvent *e); + +private: + Ui::CheckoutProgressWizardPage *ui; + QSharedPointer<AbstractCheckoutJob> m_job; + + State m_state; +}; + +} // namespace Internal +} // namespace VCSBase +#endif // CHECKOUTPROGRESSWIZARDPAGE_H diff --git a/src/plugins/vcsbase/checkoutprogresswizardpage.ui b/src/plugins/vcsbase/checkoutprogresswizardpage.ui new file mode 100644 index 0000000000000000000000000000000000000000..dc47d3b5c91ea2126eeac556257de2da5740705d --- /dev/null +++ b/src/plugins/vcsbase/checkoutprogresswizardpage.ui @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>VCSBase::Internal::CheckoutProgressWizardPage</class> + <widget class="QWizardPage" name="VCSBase::Internal::CheckoutProgressWizardPage"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>264</width> + <height>200</height> + </rect> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QPlainTextEdit" name="logPlainTextEdit"> + <property name="readOnly"> + <bool>true</bool> + </property> + </widget> + </item> + </layout> + </widget> + <resources/> + <connections/> +</ui> diff --git a/src/plugins/vcsbase/checkoutwizarddialog.cpp b/src/plugins/vcsbase/checkoutwizarddialog.cpp new file mode 100644 index 0000000000000000000000000000000000000000..23cac1009d878db88275ba51868bef86150347b5 --- /dev/null +++ b/src/plugins/vcsbase/checkoutwizarddialog.cpp @@ -0,0 +1,93 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (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 http://www.qtsoftware.com/contact. +** +**************************************************************************/ + +#include "checkoutwizarddialog.h" +#include "basecheckoutwizard.h" +#include "checkoutjobs.h" +#include "checkoutprogresswizardpage.h" + +#include <coreplugin/basefilewizard.h> + +#include <QtGui/QPushButton> + +namespace VCSBase { +namespace Internal { + +enum PageId { ParameterPageId, ProgressPageId }; + +CheckoutWizardDialog::CheckoutWizardDialog(QWizardPage *parameterPage, + QWidget *parent) : + QWizard(parent), + m_progressPage(new CheckoutProgressWizardPage) +{ + setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); + setPage(ParameterPageId, parameterPage); + setPage(ProgressPageId, m_progressPage); + connect(this, SIGNAL(currentIdChanged(int)), this, SLOT(slotPageChanged(int))); + connect(m_progressPage, SIGNAL(terminated(bool)), this, SLOT(slotTerminated(bool))); + Core::BaseFileWizard::setupWizard(this); +} + +void CheckoutWizardDialog::slotPageChanged(int id) +{ + if (id == ProgressPageId) + emit progressPageShown(); +} + +void CheckoutWizardDialog::slotTerminated(bool success) +{ + // Allow to correct parameters + if (!success) + button(QWizard::BackButton)->setEnabled(true); +} + +void CheckoutWizardDialog::start(const QSharedPointer<AbstractCheckoutJob> &job) +{ + m_progressPage->start(job); + // No "back" available while running. + button(QWizard::BackButton)->setEnabled(false); +} + +const QWizardPage *CheckoutWizardDialog::parameterPage() const +{ + return page(ParameterPageId); +} + +void CheckoutWizardDialog::reject() +{ + // First click kills, 2nd closes + if (currentId() == ProgressPageId && m_progressPage->isRunning()) { + m_progressPage->terminate(); + } else { + QWizard::reject(); + } +} + +} // namespace Internal +} // namespace VCSBase diff --git a/src/plugins/vcsbase/checkoutwizarddialog.h b/src/plugins/vcsbase/checkoutwizarddialog.h new file mode 100644 index 0000000000000000000000000000000000000000..624cacf03b5142854df00a037a4f8b135331ca99 --- /dev/null +++ b/src/plugins/vcsbase/checkoutwizarddialog.h @@ -0,0 +1,69 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (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 http://www.qtsoftware.com/contact. +** +**************************************************************************/ + +#ifndef CHECKOUTWIZARDDIALOG_H +#define CHECKOUTWIZARDDIALOG_H + +#include <QtCore/QSharedPointer> +#include <QtGui/QWizard> + +namespace VCSBase { +class AbstractCheckoutJob; + +namespace Internal { +class CheckoutProgressWizardPage; + +/* See BaseCheckoutWizard. + * Overwrites reject() to first kill the checkout + * and then close. */ + +class CheckoutWizardDialog : public QWizard { + Q_OBJECT +public: + CheckoutWizardDialog(QWizardPage *parameterPage, + QWidget *parent = 0); + + void start(const QSharedPointer<AbstractCheckoutJob> &job); + const QWizardPage *parameterPage() const; + +signals: + void progressPageShown(); + +private slots: + void slotPageChanged(int id); + void slotTerminated(bool success); + virtual void reject(); + +private: + CheckoutProgressWizardPage *m_progressPage; +}; + +} // namespace Internal +} // namespace VCSBase +#endif // CHECKOUTWIZARDDIALOG_H diff --git a/src/plugins/vcsbase/vcsbase.pro b/src/plugins/vcsbase/vcsbase.pro index be345d2ad54fe55bf298ab3d1977377652c8b6eb..1465c9db7f2fabdd27e2c95b4110e5e52948df0f 100644 --- a/src/plugins/vcsbase/vcsbase.pro +++ b/src/plugins/vcsbase/vcsbase.pro @@ -17,7 +17,12 @@ HEADERS += vcsbase_global.h \ submitfilemodel.h \ vcsbasesettings.h \ vcsbasesettingspage.h \ - nicknamedialog.h + nicknamedialog.h \ + basecheckoutwizard.h \ + checkoutwizarddialog.h \ + checkoutprogresswizardpage.h \ + checkoutjobs.h \ + basecheckoutwizardpage.h SOURCES += vcsbaseplugin.cpp \ baseannotationhighlighter.cpp \ @@ -31,11 +36,18 @@ SOURCES += vcsbaseplugin.cpp \ submitfilemodel.cpp \ vcsbasesettings.cpp \ vcsbasesettingspage.cpp \ - nicknamedialog.cpp + nicknamedialog.cpp \ + basecheckoutwizard.cpp \ + checkoutwizarddialog.cpp \ + checkoutprogresswizardpage.cpp \ + checkoutjobs.cpp \ + basecheckoutwizardpage.cpp RESOURCES += vcsbase.qrc FORMS += vcsbasesettingspage.ui \ - nicknamedialog.ui + nicknamedialog.ui \ + checkoutprogresswizardpage.ui \ + basecheckoutwizardpage.ui OTHER_FILES += VCSBase.pluginspec diff --git a/src/plugins/vcsbase/vcsbaseconstants.h b/src/plugins/vcsbase/vcsbaseconstants.h index 3362be5d49704681738ff828f6ce9d4b30a46fcb..82a9dff01ef803ea34bfa20c58e6bfa652e33488 100644 --- a/src/plugins/vcsbase/vcsbaseconstants.h +++ b/src/plugins/vcsbase/vcsbaseconstants.h @@ -38,6 +38,8 @@ namespace Constants { const char * const VCS_SETTINGS_CATEGORY = QT_TRANSLATE_NOOP("VCSBase", "Version Control"); const char * const VCS_COMMON_SETTINGS_ID = QT_TRANSLATE_NOOP("VCSBase", "Common"); +const char * const VCS_WIZARD_CATEGORY = QT_TRANSLATE_NOOP("VCSBase", "Version Control"); + namespace Internal { enum { debug = 0 }; } // namespace Internal diff --git a/src/plugins/vcsbase/vcsbaseeditor.cpp b/src/plugins/vcsbase/vcsbaseeditor.cpp index 119fe5e99ecf6e183ae845daea0b1eaf23085332..63449bd5cab9fbdd2dbfadbbe68c1019994a8c9f 100644 --- a/src/plugins/vcsbase/vcsbaseeditor.cpp +++ b/src/plugins/vcsbase/vcsbaseeditor.cpp @@ -104,7 +104,7 @@ public: VCSBaseDiffEditorEditable(VCSBaseEditor *, const VCSBaseEditorParameters *type); ~VCSBaseDiffEditorEditable(); - virtual QToolBar *toolBar() { return m_toolBar; } + virtual QWidget *toolBar() { return m_toolBar; } QComboBox *diffFileBrowseComboBox() const { return m_diffFileBrowseComboBox; } bool isTemporary() const { return true; } diff --git a/src/plugins/vcsbase/vcsbasesubmiteditor.cpp b/src/plugins/vcsbase/vcsbasesubmiteditor.cpp index 05cb57084732b6b19bfa8f5f524997d526e91cfd..baf2fdda70c9a739256c0c0ea79508a0c987c8dc 100644 --- a/src/plugins/vcsbase/vcsbasesubmiteditor.cpp +++ b/src/plugins/vcsbase/vcsbasesubmiteditor.cpp @@ -343,7 +343,7 @@ static QToolBar *createToolBar(const QWidget *someWidget, QAction *submitAction, return toolBar; } -QToolBar *VCSBaseSubmitEditor::toolBar() +QWidget *VCSBaseSubmitEditor::toolBar() { if (!wantToolBar) return 0; diff --git a/src/plugins/vcsbase/vcsbasesubmiteditor.h b/src/plugins/vcsbase/vcsbasesubmiteditor.h index 9a463c097b76c86127fbc3349d5ff78837067367..54d862f69cf4903ac672d95059b45c9d7fa619e2 100644 --- a/src/plugins/vcsbase/vcsbasesubmiteditor.h +++ b/src/plugins/vcsbase/vcsbasesubmiteditor.h @@ -142,7 +142,7 @@ public: virtual Core::IEditor *duplicate(QWidget * parent); virtual const char *kind() const; - virtual QToolBar *toolBar(); + virtual QWidget *toolBar(); virtual QList<int> context() const; virtual QWidget *widget(); diff --git a/src/shared/proparser/profileevaluator.cpp b/src/shared/proparser/profileevaluator.cpp index 46734d78e4da04a24214ab969e187fab2adffc84..3c26f93a8a13629df7db7563f26ab13ba5bdeccc 100644 --- a/src/shared/proparser/profileevaluator.cpp +++ b/src/shared/proparser/profileevaluator.cpp @@ -404,7 +404,7 @@ bool ProFileEvaluator::Private::parseLine(const QString &line) m_parens = parens; if (m_syntaxError) return false; - if (escaped) { + if (m_contNextLine) { --m_proitemPtr; updateItem(); } else { diff --git a/tests/auto/debugger/main.cpp b/tests/auto/debugger/main.cpp index 052c6534f5055acbe75bc08f00c9c9077d53fd0e..7dcc5753f19efe1f0f70872364e20837ecc6b1b3 100644 --- a/tests/auto/debugger/main.cpp +++ b/tests/auto/debugger/main.cpp @@ -8,6 +8,7 @@ #endif #include <QtCore/QStringList> #include <QtCore/QTextCodec> +#include <QtGui/QDialog> #include <QtGui/QImage> #include <QtGui/QStandardItemModel> #include <QtGui/QStringListModel> @@ -148,6 +149,8 @@ private slots: void dumpQList_QString3(); void dumpQList_Int3(); void dumpQObject(); + void dumpQObjectMethodList(); + void dumpQObjectPropertyList(); #if QT_VERSION >= 0x040500 void dumpQSharedPointer(); #endif @@ -176,6 +179,8 @@ private: void dumpQFileHelper(const QString &name, bool exists); void dumpQImageHelper(QImage &img); void dumpQImageDataHelper(QImage &img); + void dumpQObjectMethodListHelper(QObject &obj); + void dumpQObjectPropertyListHelper(QObject &obj); #if QT_VERSION >= 0x040500 template <typename T> void dumpQSharedPointerHelper(QSharedPointer<T> &ptr, bool isSimple); @@ -956,6 +961,103 @@ void tst_Debugger::dumpQObject() &child, NS"QObject", false); } +void tst_Debugger::dumpQObjectMethodListHelper(QObject &obj) +{ + const QMetaObject *mo = obj.metaObject(); + const int methodCount = mo->methodCount(); + QByteArray expected = QByteArray("addr='<synthetic>',type='"NS"QObjectMethodList',"). + append("numchild='").append(QString::number(methodCount)). + append("',childtype='QMetaMethod::Method',childnumchild='0',children=["); + for (int i = 0; i != methodCount; ++i) { + const QMetaMethod & method = mo->method(i); + int mt = method.methodType(); + expected.append("{name='").append(QString::number(i)).append(" "). + append(QString::number(mo->indexOfMethod(method.signature()))). + append(" ").append(method.signature()).append("',value='"). + append(mt == QMetaMethod::Signal ? "<Signal>" : "<Slot>"). + append(" (").append(QString::number(mt)).append(")'}"); + if (i != methodCount - 1) + expected.append(","); + } + expected.append("]"); + testDumper(expected, &obj, NS"QObjectMethodList", true); +} + +void tst_Debugger::dumpQObjectMethodList() +{ + QStringListModel m; + dumpQObjectMethodListHelper(m); +} + +void tst_Debugger::dumpQObjectPropertyListHelper(QObject &obj) +{ + const QMetaObject *mo = obj.metaObject(); + const QString propertyCount = QString::number(mo->propertyCount()); + QByteArray expected = QByteArray("addr='<synthetic>',type='"NS"QObjectPropertyList',"). + append("numchild='").append(propertyCount).append("',value='<"). + append(propertyCount).append(" items>',children=["); + for (int i = mo->propertyCount() - 1; i >= 0; --i) { + const QMetaProperty & prop = mo->property(i); + expected.append("{name='").append(prop.name()).append("',"); + switch (prop.type()) { + case QVariant::String: + expected.append("type='").append(prop.typeName()).append("',value='"). + append(utfToBase64(prop.read(&obj).toString())). + append("',valueencoded='2',numchild='0'"); + break; + case QVariant::Bool: + expected.append("type='").append(prop.typeName()).append("',value="). + append(boolToVal(prop.read(&obj).toBool())).append("numchild='0'"); + break; + case QVariant::Int: { + const int value = prop.read(&obj).toInt(); + const QString valueString = QString::number(value); + if (prop.isEnumType() || prop.isFlagType()) { + const QMetaEnum &me = prop.enumerator(); + QByteArray type = me.scope(); + if (!type.isEmpty()) + type += "::"; + type += me.name(); + expected.append("type='").append(type.constData()).append("',value='"); + if (prop.isEnumType()) { + if (const char *enumValue = me.valueToKey(value)) + expected.append(enumValue); + else + expected.append(valueString); + } else { + const QByteArray &flagsValue = me.valueToKeys(value); + expected.append(flagsValue.isEmpty() ? valueString : flagsValue.constData()); + } + } else { + expected.append("value='").append(valueString); + } + expected.append("',numchild='0'"); + break; + } + default: + expected.append("addr='").append(ptrToBa(&obj)). + append("',type'"NS"QObjectPropertyList',numchild='1'"); + break; + } + expected.append("}"); + if (i > 0) + expected.append(","); + } + expected.append("]"); + testDumper(expected, &obj, NS"QObjectPropertyList", true); +} + +void tst_Debugger::dumpQObjectPropertyList() +{ + // Case 1: Model without a parent. + QStringListModel m(QStringList() << "Test1" << "Test2"); + dumpQObjectPropertyListHelper(m); + + // Case 2: Model with a parent. + QStringListModel m2(&m); + dumpQObjectPropertyListHelper(m2); +} + #if QT_VERSION >= 0x040500 template<typename T> void tst_Debugger::dumpQSharedPointerHelper(QSharedPointer<T> &ptr, bool isSimple) diff --git a/tests/manual/trk/adapter.cpp b/tests/manual/trk/adapter.cpp index 5e1320d2bf967f9a21b04b45b185224326cf8c9b..a9e53d082be3f301b84e31c76d437ebd4a4c516a 100644 --- a/tests/manual/trk/adapter.cpp +++ b/tests/manual/trk/adapter.cpp @@ -30,6 +30,7 @@ #include "trkutils.h" #include <QtCore/QCoreApplication> +#include <QtCore/QQueue> #include <QtCore/QTimer> #include <QtNetwork/QTcpServer> @@ -50,6 +51,10 @@ void signalHandler(int) using namespace trk; +enum { TRK_SYNC = 0x7f }; + +#define CB(s) &Adapter::s + class Adapter : public QObject { Q_OBJECT @@ -61,24 +66,89 @@ public: void setTrkServerName(const QString &name) { m_trkServerName = name; } void startServer(); - private: // // TRK // Q_SLOT void readFromTrk(); - trk::TrkClient m_trkClient; + typedef void (Adapter::*TrkCallBack)(const TrkResult &); + + struct TrkMessage + { + TrkMessage() { code = token = 0; callBack = 0; } + byte code; + byte token; + QByteArray data; + QVariant cookie; + TrkCallBack callBack; + }; + + bool openTrkPort(const QString &port); // or server name for local server + void sendTrkMessage(byte code, + TrkCallBack callBack = 0, + const QByteArray &data = QByteArray(), + const QVariant &cookie = QVariant()); + // adds message to 'send' queue + void queueTrkMessage(const TrkMessage &msg); + void tryTrkWrite(); + void tryTrkRead(); + // actually writes a message to the device + void trkWrite(const TrkMessage &msg); + // convienience messages + void sendTrkInitialPing(); + void waitForTrkFinished(); + void sendTrkAck(byte token); + + // kill process and breakpoints + void cleanUp(); + + void timerEvent(QTimerEvent *ev); + byte nextTrkWriteToken(); + + void handleCpuType(const TrkResult &result); + void handleCreateProcess(const TrkResult &result); + void handleDeleteProcess(const TrkResult &result); + void handleSetBreakpoint(const TrkResult &result); + void handleClearBreakpoint(const TrkResult &result); + void handleContinue(const TrkResult &result); + void handleReadInfo(const TrkResult &result); + void handleWaitForFinished(const TrkResult &result); + void handleStep(const TrkResult &result); + void handleStop(const TrkResult &result); + void handleSupportMask(const TrkResult &result); + void handleDisconnect(const TrkResult &result); + + void handleAndReportCreateProcess(const TrkResult &result); + void handleAndReportReadRegisters(const TrkResult &result); + void handleReadMemory(const TrkResult &result); + void reportReadMemory(const TrkResult &result); + + void setTrkBreakpoint(const Breakpoint &bp); + void clearTrkBreakpoint(const Breakpoint &bp); + void handleResult(const TrkResult &data); + void readMemory(uint addr, uint len); + + QLocalSocket *m_trkDevice; + QString m_trkServerName; QByteArray m_trkReadBuffer; + unsigned char m_trkWriteToken; + QQueue<TrkMessage> m_trkWriteQueue; + QHash<byte, TrkMessage> m_writtenTrkMessages; + QByteArray m_trkReadQueue; + bool m_trkWriteBusy; + + QList<Breakpoint> m_breakpoints; + // // Gdb // Q_SLOT void handleGdbConnection(); Q_SLOT void readFromGdb(); void handleGdbResponse(const QByteArray &ba); - void writeToGdb(const QByteArray &msg, bool addAck = true); + void writeToGdb(const QByteArray &msg, const QByteArray &logNote = QByteArray()); void writeAckToGdb(); // @@ -89,22 +159,46 @@ private: QString m_gdbServerName; quint16 m_gdbServerPort; QByteArray m_gdbReadBuffer; - bool m_ackMode; + bool m_gdbAckMode; - uint m_registers[100]; + // Debuggee state + Session m_session; // global-ish data (process id, target information) + SnapShot m_snapshot; // local-ish data (memory and registers) }; Adapter::Adapter() { + // Trk +#if USE_NATIVE + m_hdevice = NULL; +#else + m_trkDevice = 0; +#endif + m_trkWriteToken = 0; + m_trkWriteBusy = false; + //m_breakpoints.append(Breakpoint(0x0370)); + //m_breakpoints.append(Breakpoint(0x0340)); + //m_breakpoints.append(Breakpoint(0x0040)); // E32Main + startTimer(100); + + // Gdb m_gdbConnection = 0; - m_ackMode = true; + m_gdbAckMode = true; } Adapter::~Adapter() { + // Trk +#if USE_NATIVE + CloseHandle(m_hdevice); +#else + delete m_trkDevice; +#endif + + // Gdb m_gdbServer.close(); - //m_trkClient->disconnectFromServer(); - m_trkClient.abort(); + //>disconnectFromServer(); + m_trkDevice->abort(); logMessage("Shutting down.\n"); } @@ -122,31 +216,23 @@ void Adapter::setGdbServerName(const QString &name) void Adapter::startServer() { - if (!m_trkClient.openPort(m_trkServerName)) { + if (!openTrkPort(m_trkServerName)) { logMessage("Unable to connect to TRK server"); return; } - m_trkClient.sendInitialPing(); - m_trkClient.sendMessage(0x01); // Connect - //m_trkClient.sendMessage(0x05, CB(handleSupportMask)); - //m_trkClient.sendMessage(0x06, CB(handleCpuType)); - m_trkClient.sendMessage(0x04); // Versions - //sendMessage(0x09); Unrecognized command - m_trkClient.sendMessage(0x4a, 0, - "10 " + formatString("C:\\data\\usingdlls.sisx")); // Open File - m_trkClient.sendMessage(0x4B, 0, "00 00 00 01 73 1C 3A C8"); // Close File - - QByteArray exe = "C:\\sys\\bin\\UsingDLLs.exe"; - exe.append('\0'); - exe.append('\0'); - //m_trkClient.sendMessage(0x40, CB(handleCreateProcess), - // "00 00 00 " + formatString(exe)); // Create Item + sendTrkInitialPing(); + sendTrkMessage(0x01); // Connect + sendTrkMessage(0x05, CB(handleSupportMask)); + sendTrkMessage(0x06, CB(handleCpuType)); + sendTrkMessage(0x04); // Versions + sendTrkMessage(0x09); // Unrecognized command + //sendTrkMessage(0x4a, 0, + // "10 " + formatString("C:\\data\\usingdlls.sisx")); // Open File + //sendTrkMessage(0x4B, 0, "00 00 00 01 73 1C 3A C8"); // Close File logMessage("Connected to TRK server"); -return; - if (!m_gdbServer.listen(QHostAddress(m_gdbServerName), m_gdbServerPort)) { logMessage(QString("Unable to start the gdb server at %1:%2: %3.") .arg(m_gdbServerName).arg(m_gdbServerPort) @@ -240,91 +326,129 @@ void Adapter::readFromGdb() void Adapter::writeAckToGdb() { - if (!m_ackMode) + if (!m_gdbAckMode) return; QByteArray packet = "+"; logMessage("gdb: <- " + packet); m_gdbConnection->write(packet); } -void Adapter::writeToGdb(const QByteArray &msg, bool addAck) +void Adapter::writeToGdb(const QByteArray &msg, const QByteArray &logNote) { - uint sum = 0; + ushort sum = 0; for (int i = 0; i != msg.size(); ++i) sum += msg.at(i); - QByteArray checkSum = QByteArray::number(sum % 256, 16); + + char checkSum[30]; + qsnprintf(checkSum, sizeof(checkSum) - 1, "%02x ", sum); + //logMessage(QString("Packet checksum: %1").arg(sum)); QByteArray packet; - if (addAck) + if (m_gdbAckMode) packet.append("+"); packet.append("$"); packet.append(msg); packet.append('#'); - if (checkSum.size() < 2) - packet.append('0'); packet.append(checkSum); - logMessage("gdb: <- " + packet); + int pad = qMax(0, 24 - packet.size()); + logMessage("gdb: <- " + packet + QByteArray(pad, ' ') + logNote); m_gdbConnection->write(packet); } void Adapter::handleGdbResponse(const QByteArray &response) { // http://sourceware.org/gdb/current/onlinedocs/gdb_34.html - if (response == "qSupported") { - //$qSupported#37 - //logMessage("Handling 'qSupported'"); - writeToGdb(QByteArray()); - } - - else if (response == "qAttached") { - //$qAttached#8f - // 1: attached to an existing process - // 0: created a new process - writeToGdb("0"); - } - - else if (response == "QStartNoAckMode") { - //$qSupported#37 - //logMessage("Handling 'QStartNoAckMode'"); - writeToGdb(QByteArray("OK")); - m_ackMode = false; - } - - else if (response == "g") { + if (response == "g") { // Read general registers. - writeToGdb("00000000"); + //writeToGdb("00000000", "read registers"); + QByteArray ba; + appendByte(&ba, 0); // ? + appendByte(&ba, 0); // ? + appendByte(&ba, 0); // ? + + appendByte(&ba, 0); // first register + // FIXME: off by one? + appendByte(&ba, registerCount - 1); // last register + appendInt(&ba, m_session.pid); + appendInt(&ba, m_session.tid); + + sendTrkMessage(0x12, CB(handleAndReportReadRegisters), ba); } else if (response.startsWith("Hc")) { // Set thread for subsequent operations (`m', `M', `g', `G', et.al.). // for step and continue operations //$Hc-1#09 - writeToGdb("OK"); + writeToGdb("OK", "set current thread for step & continue"); } else if (response.startsWith("Hg")) { // Set thread for subsequent operations (`m', `M', `g', `G', et.al.). // for 'other operations. 0 - any thread //$Hg0#df - writeToGdb("OK"); + m_session.currentThread = response.mid(2).toInt(); + writeToGdb("OK", "set current thread " + + QByteArray::number(m_session.currentThread)); + } + + else if (response.startsWith("m")) { + // m addr,length + int pos = response.indexOf(','); + bool ok = false; + uint addr = response.mid(1, pos - 1).toInt(&ok, 16); + uint len = response.mid(pos + 1).toInt(&ok, 16); + //qDebug() << "ADDR: " << QByteArray::number(addr, 16) << " " + // << QByteArray::number(len, 16); + readMemory(addr, len); } else if (response == "pf") { // current instruction pointer? - writeToGdb("0000"); + writeToGdb("0000", "current IP"); + } + + else if (response == "qAttached") { + //$qAttached#8f + // 1: attached to an existing process + // 0: created a new process + writeToGdb("0", "new process created"); + //writeToGdb("1", "attached to existing process"); } else if (response.startsWith("qC")) { // Return the current thread ID //$qC#b4 - writeToGdb("QC-1"); + + // It's not started yet + QByteArray ba; + appendByte(&ba, 0); // ? + appendByte(&ba, 0); // ? + appendByte(&ba, 0); // ? + + appendString(&ba, "C:\\sys\\bin\\filebrowseapp.exe", TargetByteOrder); + ba.append('\0'); + ba.append('\0'); + sendTrkMessage(0x40, CB(handleAndReportCreateProcess), ba); // Create Item + } + + else if (response == "qSupported") { + //$qSupported#37 + //logMessage("Handling 'qSupported'"); + writeToGdb(QByteArray()); + } + + else if (response == "QStartNoAckMode") { + //$qSupported#37 + //logMessage("Handling 'QStartNoAckMode'"); + writeToGdb("OK", "ack no-ack mode"); + m_gdbAckMode = false; } else if (response.startsWith("?")) { // Indicate the reason the target halted. // The reply is the same as for step and continue. - writeToGdb("S0b"); + writeToGdb("S0b", "target halted"); //$?#3f //$qAttached#8f //$qOffsets#4b @@ -341,6 +465,684 @@ void Adapter::readFromTrk() //logMessage("Read from gdb: " + ba); } +bool Adapter::openTrkPort(const QString &port) +{ + // QFile does not work with "COM3", so work around + /* + FILE *f = fopen("COM3", "r+"); + if (!f) { + logMessage("Could not open file "); + return; + } + m_trkDevice = new QFile; + if (!m_trkDevice->open(f, QIODevice::ReadWrite)) + */ + +#if 0 + m_trkDevice = new Win_QextSerialPort(port); + m_trkDevice->setBaudRate(BAUD115200); + m_trkDevice->setDataBits(DATA_8); + m_trkDevice->setParity(PAR_NONE); + //m_trkDevice->setStopBits(STO); + m_trkDevice->setFlowControl(FLOW_OFF); + m_trkDevice->setTimeout(0, 500); + + if (!m_trkDevice->open(QIODevice::ReadWrite)) { + QByteArray ba = m_trkDevice->errorString().toLatin1(); + logMessage("Could not open device " << ba); + return; + } +#else + m_trkDevice = new QLocalSocket(this); + m_trkDevice->connectToServer(port); + return m_trkDevice->waitForConnected(); +#endif +} + +void Adapter::timerEvent(QTimerEvent *) +{ + //qDebug("."); + tryTrkWrite(); + tryTrkRead(); +} + +unsigned char Adapter::nextTrkWriteToken() +{ + ++m_trkWriteToken; + if (m_trkWriteToken == 0) + ++m_trkWriteToken; + return m_trkWriteToken; +} + +void Adapter::sendTrkMessage(byte code, TrkCallBack callBack, + const QByteArray &data, const QVariant &cookie) +{ + TrkMessage msg; + msg.code = code; + msg.token = nextTrkWriteToken(); + msg.callBack = callBack; + msg.data = data; + msg.cookie = cookie; + queueTrkMessage(msg); +} + +void Adapter::sendTrkInitialPing() +{ + TrkMessage msg; + msg.code = 0x00; // Ping + msg.token = 0; // reset sequence count + queueTrkMessage(msg); +} + +void Adapter::waitForTrkFinished() +{ + TrkMessage msg; + // initiate one last roundtrip to ensure all is flushed + msg.code = 0x00; // Ping + msg.token = nextTrkWriteToken(); + msg.callBack = CB(handleWaitForFinished); + queueTrkMessage(msg); +} + +void Adapter::sendTrkAck(byte token) +{ + logMessage(QString("SENDING ACKNOWLEDGEMENT FOR TOKEN ").arg(int(token))); + TrkMessage msg; + msg.code = 0x80; + msg.token = token; + msg.data.append('\0'); + // The acknowledgement must not be queued! + //queueMessage(msg); + trkWrite(msg); + // 01 90 00 07 7e 80 01 00 7d 5e 7e +} + +void Adapter::queueTrkMessage(const TrkMessage &msg) +{ + m_trkWriteQueue.append(msg); +} + +void Adapter::tryTrkWrite() +{ + if (m_trkWriteBusy) + return; + if (m_trkWriteQueue.isEmpty()) + return; + + TrkMessage msg = m_trkWriteQueue.dequeue(); + if (msg.code == TRK_SYNC) { + //logMessage("TRK SYNC"); + TrkResult result; + result.code = msg.code; + result.token = msg.token; + result.data = msg.data; + result.cookie = msg.cookie; + TrkCallBack cb = msg.callBack; + if (cb) + (this->*cb)(result); + } else { + trkWrite(msg); + } +} + +void Adapter::trkWrite(const TrkMessage &msg) +{ + QByteArray ba = frameMessage(msg.code, msg.token, msg.data); + + m_writtenTrkMessages.insert(msg.token, msg); + m_trkWriteBusy = true; + +#if USE_NATIVE + + DWORD charsWritten; + if (!WriteFile(m_hdevice, ba.data(), ba.size(), &charsWritten, NULL)) + logMessage("WRITE ERROR: "); + + //logMessage("WRITE: " + stringFromArray(ba)); + FlushFileBuffers(m_hdevice); + +#else + + //logMessage("WRITE: " + stringFromArray(ba)); + if (!m_trkDevice->write(ba)) + logMessage("WRITE ERROR: " + m_trkDevice->errorString()); + m_trkDevice->flush(); + +#endif +} + +void Adapter::tryTrkRead() +{ + //logMessage("TRY READ: " << m_trkDevice->bytesAvailable() + // << stringFromArray(m_trkReadQueue); + +#if USE_NATIVE + + const int BUFFERSIZE = 1024; + char buffer[BUFFERSIZE]; + DWORD charsRead; + + while (ReadFile(m_hdevice, buffer, BUFFERSIZE, &charsRead, NULL) + && BUFFERSIZE == charsRead) { + m_trkReadQueue.append(buffer, charsRead); + } + m_trkReadQueue.append(buffer, charsRead); + +#else // USE_NATIVE + + if (m_trkDevice->bytesAvailable() == 0 && m_trkReadQueue.isEmpty()) + return; + + QByteArray res = m_trkDevice->readAll(); + m_trkReadQueue.append(res); + + +#endif // USE_NATIVE + + if (m_trkReadQueue.size() < 9) { + logMessage("ERROR READBUFFER INVALID (1): " + + stringFromArray(m_trkReadQueue)); + m_trkReadQueue.clear(); + return; + } + + while (!m_trkReadQueue.isEmpty()) + handleResult(extractResult(&m_trkReadQueue)); + + m_trkWriteBusy = false; +} + + +void Adapter::handleResult(const TrkResult &result) +{ + QByteArray prefix = "READ BUF: "; + QByteArray str = result.toString().toUtf8(); + switch (result.code) { + case 0x80: { // ACK + logMessage(prefix + "ACK: " + str); + if (!result.data.isEmpty() && result.data.at(0)) + logMessage(prefix + "ERR: " +QByteArray::number(result.data.at(0))); + //logMessage("READ RESULT FOR TOKEN: " << token); + if (!m_writtenTrkMessages.contains(result.token)) { + logMessage("NO ENTRY FOUND!"); + } + TrkMessage msg = m_writtenTrkMessages.take(result.token); + TrkResult result1 = result; + result1.cookie = msg.cookie; + TrkCallBack cb = msg.callBack; + if (cb) { + //logMessage("HANDLE: " << stringFromArray(result.data)); + (this->*cb)(result1); + } + break; + } + case 0xff: { // NAK + logMessage(prefix + "NAK: " + str); + //logMessage(prefix << "TOKEN: " << result.token); + logMessage(prefix + "ERROR: " + errorMessage(result.data.at(0))); + break; + } + case 0x90: { // Notified Stopped + logMessage(prefix + "NOTE: STOPPED" + str); + // 90 01 78 6a 40 40 00 00 07 23 00 00 07 24 00 00 + //const char *data = result.data.data(); +// uint addr = extractInt(data); //code address: 4 bytes; code base address for the library +// uint pid = extractInt(data + 4); // ProcessID: 4 bytes; +// uint tid = extractInt(data + 8); // ThreadID: 4 bytes + //logMessage(prefix << " ADDR: " << addr << " PID: " << pid << " TID: " << tid); + sendTrkAck(result.token); + //Sleep(10000); + //cleanUp(); + break; + } + case 0x91: { // Notify Exception (obsolete) + logMessage(prefix + "NOTE: EXCEPTION" + str); + sendTrkAck(result.token); + break; + } + case 0x92: { // + logMessage(prefix + "NOTE: INTERNAL ERROR: " + str); + sendTrkAck(result.token); + break; + } + + // target->host OS notification + case 0xa0: { // Notify Created + /* + const char *data = result.data.data(); + byte error = result.data.at(0); + byte type = result.data.at(1); // type: 1 byte; for dll item, this value is 2. + uint pid = extractInt(data + 2); // ProcessID: 4 bytes; + uint tid = extractInt(data + 6); //threadID: 4 bytes + uint codeseg = extractInt(data + 10); //code address: 4 bytes; code base address for the library + uint dataseg = extractInt(data + 14); //data address: 4 bytes; data base address for the library + uint len = extractShort(data + 18); //length: 2 bytes; length of the library name string to follow + QByteArray name = result.data.mid(20, len); // name: library name + + logMessage(prefix + "NOTE: LIBRARY LOAD: " + str); + logMessage(prefix + "TOKEN: " + result.token); + logMessage(prefix + "ERROR: " + int(error)); + logMessage(prefix + "TYPE: " + int(type)); + logMessage(prefix + "PID: " + pid); + logMessage(prefix + "TID: " + tid); + logMessage(prefix + "CODE: " + codeseg); + logMessage(prefix + "DATA: " + dataseg); + logMessage(prefix + "LEN: " + len); + logMessage(prefix + "NAME: " + name); + */ + + QByteArray ba; + appendInt(&ba, m_session.pid); + appendInt(&ba, m_session.tid); + sendTrkMessage(0x18, CB(handleContinue), ba); + //sendTrkAck(result.token) + break; + } + case 0xa1: { // NotifyDeleted + logMessage(prefix + "NOTE: LIBRARY UNLOAD: " + str); + sendTrkAck(result.token); + break; + } + case 0xa2: { // NotifyProcessorStarted + logMessage(prefix + "NOTE: PROCESSOR STARTED: " + str); + sendTrkAck(result.token); + break; + } + case 0xa6: { // NotifyProcessorStandby + logMessage(prefix + "NOTE: PROCESSOR STANDBY: " + str); + sendTrkAck(result.token); + break; + } + case 0xa7: { // NotifyProcessorReset + logMessage(prefix + "NOTE: PROCESSOR RESET: " + str); + sendTrkAck(result.token); + break; + } + default: { + logMessage(prefix + "INVALID: " + str); + break; + } + } +} + +void Adapter::handleCpuType(const TrkResult &result) +{ + logMessage("HANDLE CPU TYPE: " + result.toString()); + //---TRK------------------------------------------------------ + // Command: 0x80 Acknowledge + // Error: 0x00 + // [80 03 00 04 00 00 04 00 00 00] + m_session.cpuMajor = result.data[0]; + m_session.cpuMinor = result.data[1]; + m_session.bigEndian = result.data[2]; + m_session.defaultTypeSize = result.data[3]; + m_session.fpTypeSize = result.data[4]; + m_session.extended1TypeSize = result.data[5]; + //m_session.extended2TypeSize = result.data[6]; +} + +void Adapter::handleCreateProcess(const TrkResult &result) +{ + //---TRK------------------------------------------------------ + // Command: 0x80 Acknowledge + // Error: 0x00 + // [80 08 00 00 00 01 B5 00 00 01 B6 78 67 40 00 00 + // 40 00 00] + + logMessage(" RESULT: " + result.toString()); + const char *data = result.data.data(); + m_session.pid = extractInt(data); + m_session.tid = extractInt(data + 4); + m_session.codeseg = extractInt(data + 8); + m_session.dataseg = extractInt(data + 12); + + /* + logMessage("PID: " + formatInt(m_session.pid) + m_session.pid); + logMessage("TID: " + formatInt(m_session.tid) + m_session.tid); + logMessage("COD: " + formatInt(m_session.codeseg) + m_session.codeseg); + logMessage("DAT: " + formatInt(m_session.dataseg) + m_session.dataseg); + */ + + + //setTrkBreakpoint(0x0000, ArmMode); + //clearTrkBreakpoint(0x0000); + +#if 1 + foreach (const Breakpoint &bp, m_breakpoints) + setTrkBreakpoint(bp); +#endif + +#if 1 + //---IDE------------------------------------------------------ + // Command: 0x42 Read Info + // [42 0C 00 06 00 00 00 00 00 14 50 6F 6C 79 6D 6F + // 72 70 68 69 63 44 4C 4C 32 2E 64 6C 6C 00] + sendTrkMessage(0x42, CB(handleReadInfo), + "00 06 00 00 00 00 00 14 50 6F 6C 79 6D 6F " + "72 70 68 69 63 44 4C 4C 32 2E 64 6C 6C 00"); + //sendTrkMessage(0x42, CB(handleReadInfo), + // "00 01 00 00 00 00"); + //---TRK------------------------------------------------------ + // Command: 0x80 Acknowledge + // Error: 0x20 Unspecified general OS-related error + // [80 0C 20] + + + //---IDE------------------------------------------------------ + // Command: 0x42 Read Info + // [42 0D 00 06 00 00 00 00 00 14 50 6F 6C 79 6D 6F + // 72 70 68 69 63 44 4C 4C 31 2E 64 6C 6C 00] + sendTrkMessage(0x42, CB(handleReadInfo), + "00 06 00 00 00 00 00 14 50 6F 6C 79 6D 6F " + "72 70 68 69 63 44 4C 4C 31 2E 64 6C 6C 00"); + //---TRK------------------------------------------------------ + // Command: 0x80 Acknowledge + // Error: 0x20 Unspecified general OS-related error + // [80 0D 20] +#endif + + //sendTrkMessage(0x18, CB(handleStop), + // "01 " + formatInt(m_session.pid) + formatInt(m_session.tid)); + + //---IDE------------------------------------------------------ + // Command: 0x18 Continue + //ProcessID: 0x000001B5 (437) + // ThreadID: 0x000001B6 (438) + // [18 0E 00 00 01 B5 00 00 01 B6] + QByteArray ba; + appendInt(&ba, m_session.pid); + appendInt(&ba, m_session.tid); + sendTrkMessage(0x18, CB(handleContinue), ba); + //sendTrkMessage(0x18, CB(handleContinue), + // formatInt(m_session.pid) + "ff ff ff ff"); + //---TRK------------------------------------------------------ + // Command: 0x80 Acknowledge + // Error: 0x00 + // [80 0E 00] +} + +void Adapter::handleAndReportCreateProcess(const TrkResult &result) +{ + //logMessage(" RESULT: " + result.toString()); + // [80 08 00 00 00 01 B5 00 00 01 B6 78 67 40 00 00 40 00 00] + const char *data = result.data.data(); + m_session.pid = extractInt(data); + m_session.tid = extractInt(data + 4); + m_session.codeseg = extractInt(data + 8); + m_session.dataseg = extractInt(data + 12); + + char buf[30]; + qsnprintf(buf, sizeof(buf) - 1, "p%08x.%08x", m_session.pid, m_session.tid); + writeToGdb("QC" + QByteArray(buf), "current thread Id"); +} + +void Adapter::handleAndReportReadRegisters(const TrkResult &result) +{ + //logMessage(" RESULT: " + result.toString()); + // [80 0B 00 00 00 00 00 C9 24 FF BC 00 00 00 00 00 + // 60 00 00 00 00 00 00 78 67 79 70 00 00 00 00 00...] + QByteArray ba; +#if 0 + char buf[30]; + const char *data = result.data.data(); + for (int i = 0; i != registerCount; ++i) { + uint value = extractInt(data + 4 * i + 1); + qsnprintf(buf, sizeof(buf) - 1, "%08x", value); + ba.append(buf); + } +#else + ba = result.data.toHex(); +#endif + writeToGdb(ba, "register contents"); +} + +void Adapter::handleReadMemory(const TrkResult &result) +{ + //logMessage(" RESULT READ MEMORY: " + result.data.toHex()); + QByteArray ba = result.data.mid(1); + uint blockaddr = result.cookie.toInt(); + //qDebug() << "READING " << ba.size() << " BYTES: " + // << quoteUnprintableLatin1(ba) + // << "ADDR: " << QByteArray::number(blockaddr, 16) + // << "COOKIE: " << result.cookie; + m_snapshot.memory[blockaddr] = ba; +} + +void Adapter::reportReadMemory(const TrkResult &result) +{ + qulonglong cookie = result.cookie.toLongLong(); + uint addr = cookie >> 32; + uint len = uint(cookie); + + QByteArray ba; + uint blockaddr = (addr / memoryChunkSize) * memoryChunkSize; + for (; blockaddr < addr + len; blockaddr += memoryChunkSize) { + QByteArray blockdata = m_snapshot.memory[blockaddr]; + Q_ASSERT(!blockdata.isEmpty()); + ba.append(blockdata); + } + + ba = ba.mid(addr % memoryChunkSize, len); + // qDebug() << "REPORTING MEMORY " << ba.size() + // << " ADDR: " << QByteArray::number(blockaddr, 16) << " LEN: " << len + // << " BYTES: " << quoteUnprintableLatin1(ba); + + writeToGdb(ba.toHex(), "memory contents"); +} + +void Adapter::setTrkBreakpoint(const Breakpoint &bp) +{ + //---IDE------------------------------------------------------ + // Command: 0x1B Set Break + //BreakType: 0x82 + // Options: 0x00 + // Address: 0x78674340 (2020033344) i.e + 0x00000340 + // Length: 0x00000001 (1) + // Count: 0x00000000 (0) + //ProcessID: 0x000001b5 (437) + // ThreadID: 0xffffffff (-1) + // [1B 09 82 00 78 67 43 40 00 00 00 01 00 00 00 00 + // 00 00 01 B5 FF FF FF FF] + QByteArray ba; + appendByte(&ba, 0x82); + appendByte(&ba, bp.mode == ArmMode ? 0x00 : 0x01); + appendInt(&ba, m_session.codeseg + bp.offset); + appendInt(&ba, 0x00000001); + appendInt(&ba, 0x00000001); + appendInt(&ba, m_session.pid); + appendInt(&ba, 0xFFFFFFFF); + + sendTrkMessage(0x1B, CB(handleSetBreakpoint), ba); + //m_session.toekn + + //---TRK------------------------------------------------------ + // Command: 0x80 Acknowledge + // Error: 0x00 + // [80 09 00 00 00 00 0A] +} + +void Adapter::handleSetBreakpoint(const TrkResult &result) +{ + //---TRK------------------------------------------------------ + // Command: 0x80 Acknowledge + // Error: 0x00 + // [80 09 00 00 00 00 0A] + uint bpnr = extractInt(result.data.data()); + logMessage("SET BREAKPOINT " + bpnr + + stringFromArray(result.data.data())); +} + +void Adapter::clearTrkBreakpoint(const Breakpoint &bp) +{ + //---IDE------------------------------------------------------ + // Command: 0x1C Clear Break + // [1C 25 00 00 00 0A 78 6A 43 40] + QByteArray ba; + appendByte(&ba, 0x00); + appendShort(&ba, bp.number); + appendInt(&ba, m_session.codeseg + bp.offset); + sendTrkMessage(0x1C, CB(handleClearBreakpoint), ba); +} + +void Adapter::handleClearBreakpoint(const TrkResult &result) +{ + Q_UNUSED(result); + //---TRK------------------------------------------------------ + // Command: 0x80 Acknowledge + // Error: 0x00 + // [80 09 00 00 00 00 0A] + logMessage("CLEAR BREAKPOINT "); +} + +void Adapter::handleContinue(const TrkResult &result) +{ + logMessage(" HANDLE CONTINUE: " + stringFromArray(result.data)); + //if (result.result.token) + //logMessage(" ERROR: " + byte(result.result.token) + // sendTrkMessage(0x18, CB(handleContinue), + // formatInt(m_session.pid) + formatInt(m_session.tid)); + //} +} + +void Adapter::handleDisconnect(const TrkResult &result) +{ + logMessage(" HANDLE DISCONNECT: " + stringFromArray(result.data)); + //if (result.result.token) + //logMessage(" ERROR: " + byte(result.result.token) + // sendTrkMessage(0x18, CB(handleContinue), + // formatInt(m_session.pid) + formatInt(m_session.tid)); + //} +} + +void Adapter::handleDeleteProcess(const TrkResult &result) +{ + logMessage(" HANDLE DELETE PROCESS: " + stringFromArray(result.data)); + //if (result.result.token) + //logMessage(" ERROR: " + byte(result.token) + // sendTrkMessage(0x18, CB(handleContinue), + // formatInt(m_session.pid) + formatInt(m_session.tid)); + //} +} + +void Adapter::handleStep(const TrkResult &result) +{ + logMessage(" HANDLE STEP: " + stringFromArray(result.data)); +} + +void Adapter::handleStop(const TrkResult &result) +{ + logMessage(" HANDLE STOP: " + stringFromArray(result.data)); +} + + +void Adapter::handleReadInfo(const TrkResult &result) +{ + logMessage(" HANDLE READ INFO: " + stringFromArray(result.data)); +} + +void Adapter::handleWaitForFinished(const TrkResult &result) +{ + logMessage(" FINISHED: " + stringFromArray(result.data)); + //qApp->exit(1); +} + +void Adapter::handleSupportMask(const TrkResult &result) +{ + const char *data = result.data.data(); + QByteArray str; + for (int i = 0; i < 32; ++i) { + //str.append(" [" + formatByte(data[i]) + "]: "); + for (int j = 0; j < 8; ++j) + if (data[i] & (1 << j)) + str.append(QByteArray::number(i * 8 + j, 16)); + } + logMessage("SUPPORTED: " + str); +} + + +void Adapter::cleanUp() +{ + // + //---IDE------------------------------------------------------ + // Command: 0x41 Delete Item + // Sub Cmd: Delete Process + //ProcessID: 0x0000071F (1823) + // [41 24 00 00 00 00 07 1F] + QByteArray ba; + appendByte(&ba, 0x00); + appendByte(&ba, 0x00); + appendInt(&ba, m_session.pid); + sendTrkMessage(0x41, CB(handleDeleteProcess), ba); + + //---TRK------------------------------------------------------ + // Command: 0x80 Acknowledge + // Error: 0x00 + // [80 24 00] + + foreach (const Breakpoint &bp, m_breakpoints) + clearTrkBreakpoint(bp); + + //---IDE------------------------------------------------------ + // Command: 0x1C Clear Break + // [1C 25 00 00 00 0A 78 6A 43 40] + + //---TRK------------------------------------------------------ + // Command: 0xA1 Notify Deleted + // [A1 09 00 00 00 00 00 00 00 00 07 1F] + //---IDE------------------------------------------------------ + // Command: 0x80 Acknowledge + // Error: 0x00 + // [80 09 00] + + //---TRK------------------------------------------------------ + // Command: 0x80 Acknowledge + // Error: 0x00 + // [80 25 00] + + //---IDE------------------------------------------------------ + // Command: 0x1C Clear Break + // [1C 26 00 00 00 0B 78 6A 43 70] + //---TRK------------------------------------------------------ + // Command: 0x80 Acknowledge + // Error: 0x00 + // [80 26 00] + + + //---IDE------------------------------------------------------ + // Command: 0x02 Disconnect + // [02 27] + sendTrkMessage(0x02, CB(handleDisconnect)); + //---TRK------------------------------------------------------ + // Command: 0x80 Acknowledge + // Error: 0x00 +} + +void Adapter::readMemory(uint addr, uint len) +{ + Q_ASSERT(len < (2 << 16)); + + // We try to get medium-sized chunks of data from the device + + QList <uint> blocksToFetch; + uint blockaddr = (addr / memoryChunkSize) * memoryChunkSize; + for (; blockaddr < addr + len; blockaddr += memoryChunkSize) { + QByteArray blockdata = m_snapshot.memory[blockaddr]; + if (blockdata.isEmpty()) { + // fetch it + QByteArray ba; + appendByte(&ba, 0x08); // Options, FIXME: why? + appendShort(&ba, memoryChunkSize); + appendInt(&ba, blockaddr); + appendInt(&ba, m_session.pid); + appendInt(&ba, m_session.tid); + // Read Memory + sendTrkMessage(0x10, CB(handleReadMemory), ba, QVariant(blockaddr)); + } + } + qulonglong cookie = (qulonglong(addr) << 32) + len; + sendTrkMessage(TRK_SYNC, CB(reportReadMemory), QByteArray(), cookie); +} + int main(int argc, char *argv[]) { if (argc < 3) { diff --git a/tests/manual/trk/run.sh b/tests/manual/trk/run.sh index 3e84db45ff34d142977dd4918447c20f29934697..f3aeba721735717a6f633374644755dabfd64032 100755 --- a/tests/manual/trk/run.sh +++ b/tests/manual/trk/run.sh @@ -5,11 +5,14 @@ make || exit 1 killall -s USR1 adapter trkserver > /dev/null 2>&1 killall adapter trkserver > /dev/null 2>&1 -trkservername="TRKSERVER-3"; +trkservername="TRKSERVER-4"; gdbserverip=127.0.0.1 -gdbserverport=2225 +gdbserverport=2226 replaysource=dump.txt +fuser -n tcp -k ${gdbserverport} +rm /tmp/${trkservername} + ./trkserver ${trkservername} ${replaysource} & trkserverpid=$! diff --git a/tests/manual/trk/trkserver.cpp b/tests/manual/trk/trkserver.cpp index 764cacda368d98180906976ce6c706cdcb092430..ce3e6fb18feb77fcda5900ac31fe5280b0683ed6 100644 --- a/tests/manual/trk/trkserver.cpp +++ b/tests/manual/trk/trkserver.cpp @@ -59,6 +59,23 @@ using namespace trk; // [80 02 00 7E 00 4F 5F 01 00 00 00 0F 1F 00 00 00 // 00 00 00 01 00 11 00 03 00 00 00 00 00 03 00 00...] +struct Inferior +{ + Inferior(); + uint pid; + uint tid; + uint codeseg; + uint dataseg; +}; + +Inferior::Inferior() +{ + pid = 0x000008F5; + tid = 0x000008F6; + codeseg = 0x78674000; + dataseg = 0x00400000; +} + class TrkServer : public QObject { Q_OBJECT @@ -90,6 +107,7 @@ private: QLocalServer m_server; int m_lastSent; QLocalSocket *m_adapterConnection; + Inferior m_inferior; }; TrkServer::TrkServer() @@ -177,14 +195,51 @@ void TrkServer::writeToAdapter(byte command, byte token, const QByteArray &data) void TrkServer::handleAdapterMessage(const TrkResult &result) { QByteArray data; + data.append(char(0x00)); // No error switch (result.code) { case 0x00: { // Ping - data.append(char(0x00)); // No error writeToAdapter(0x80, 0x00, data); break; } + case 0x01: { // Connect + writeToAdapter(0x80, result.token, data); + break; + } + case 0x10: { // Read Memory + const char *p = result.data.data(); + byte option = p[0]; + Q_UNUSED(option); + ushort len = extractShort(p + 1); + uint addr = extractInt(p + 3); + qDebug() << "ADDR: " << QByteArray::number(addr, 16) << " " + << QByteArray::number(len, 16); + for (int i = 0; i != len; ++i) + appendByte(&data, i); + writeToAdapter(0x80, result.token, data); + break; + } + case 0x12: { // Read Registers + appendInt(&data, 0x00000000, BigEndian); + appendInt(&data, 0xC924FFBC, BigEndian); + appendInt(&data, 0x00000000, BigEndian); + appendInt(&data, 0x00600000, BigEndian); + appendInt(&data, 0x78677970, BigEndian); + for (int i = 5; i < registerCount - 1; ++i) + appendInt(&data, i + (i << 16), BigEndian); + appendInt(&data, 0x78676B00, BigEndian); + writeToAdapter(0x80, result.token, data); + break; + } + case 0x40: { // Create Item + appendInt(&data, m_inferior.pid, BigEndian); + appendInt(&data, m_inferior.tid, BigEndian); + appendInt(&data, m_inferior.codeseg, BigEndian); + appendInt(&data, m_inferior.dataseg, BigEndian); + writeToAdapter(0x80, result.token, data); + break; + } default: - data.append(char(0x10)); // Command not supported + data[0] = 0x10; // Command not supported writeToAdapter(0xff, result.token, data); break; } diff --git a/tests/manual/trk/trkutils.cpp b/tests/manual/trk/trkutils.cpp index 3277747d05314e40a98365553e43d4232be13574..8a3b67a9f39e0ef7cedea4c32f1e05e3dd73fcc7 100644 --- a/tests/manual/trk/trkutils.cpp +++ b/tests/manual/trk/trkutils.cpp @@ -117,7 +117,7 @@ TrkResult extractResult(QByteArray *buffer) result.code = data.at(0); result.token = data.at(1); - result.data = data.mid(2); + result.data = data.mid(2, data.size() - 3); //logMessage(" REST BUF: " << stringFromArray(*buffer)); //logMessage(" CURR DATA: " << stringFromArray(data)); //QByteArray prefix = "READ BUF: "; @@ -127,15 +127,15 @@ TrkResult extractResult(QByteArray *buffer) ushort extractShort(const char *data) { - return data[0] * 256 + data[1]; + return byte(data[0]) * 256 + byte(data[1]); } uint extractInt(const char *data) { - uint res = data[0]; - res *= 256; res += data[1]; - res *= 256; res += data[2]; - res *= 256; res += data[3]; + uint res = byte(data[0]); + res *= 256; res += byte(data[1]); + res *= 256; res += byte(data[2]); + res *= 256; res += byte(data[3]); return res; } @@ -192,8 +192,6 @@ QByteArray encode7d(const QByteArray &ba) return res; } -#define CB(s) &TrkClient::s - // FIXME: Use the QByteArray based version below? QString stringFromByte(byte c) { @@ -215,38 +213,47 @@ QString stringFromArray(const QByteArray &ba) return str + " " + ascii; } - -QByteArray formatByte(byte b) +void appendByte(QByteArray *ba, byte b) { - char buf[30]; - qsnprintf(buf, sizeof(buf) - 1, "%x ", b); - return buf; + ba->append(b); } -QByteArray formatShort(ushort s) +void appendShort(QByteArray *ba, ushort s, Endianness endian) { - char buf[30]; - qsnprintf(buf, sizeof(buf) - 1, "%x %x ", s / 256, s % 256); - return buf; + if (endian == BigEndian) { + ba->append(s / 256); + ba->append(s % 256); + } else { + ba->append(s % 256); + ba->append(s / 256); + } } -QByteArray formatInt(uint i) +void appendInt(QByteArray *ba, uint i, Endianness endian) { - char buf[30]; int b3 = i % 256; i -= b3; i /= 256; int b2 = i % 256; i -= b2; i /= 256; int b1 = i % 256; i -= b1; i /= 256; int b0 = i % 256; i -= b0; i /= 256; - qsnprintf(buf, sizeof(buf) - 1, "%x %x %x %x ", b0, b1, b2, b3); - return buf; + if (endian == BigEndian) { + ba->append(b3); + ba->append(b2); + ba->append(b1); + ba->append(b0); + } else { + ba->append(b0); + ba->append(b1); + ba->append(b2); + ba->append(b3); + } } -QByteArray formatString(const QByteArray &str) +void appendString(QByteArray *ba, const QByteArray &str, Endianness endian) { - QByteArray ba = formatShort(str.size()); - foreach (byte b, str) - ba.append(formatByte(b)); - return ba; + const int n = str.size(); + appendShort(ba, n, endian); + for (int i = 0; i != n; ++i) + ba->append(str.at(i)); } QByteArray errorMessage(byte code) @@ -278,608 +285,6 @@ QByteArray errorMessage(byte code) return "Unknown error"; } -TrkClient::TrkClient() -{ -#if USE_NATIVE - m_hdevice = NULL; -#else - m_device = 0; -#endif - m_writeToken = 0; - m_readToken = 0; - m_writeBusy = false; - //m_breakpoints.append(Breakpoint(0x0370)); - //m_breakpoints.append(Breakpoint(0x0340)); - //m_breakpoints.append(Breakpoint(0x0040)); // E32Main - startTimer(100); -} - -TrkClient::~TrkClient() -{ -#if USE_NATIVE - CloseHandle(m_hdevice); -#else - delete m_device; -#endif -} - -bool TrkClient::openPort(const QString &port) -{ - // QFile does not work with "COM3", so work around - /* - FILE *f = fopen("COM3", "r+"); - if (!f) { - logMessage("Could not open file "); - return; - } - m_device = new QFile; - if (!m_device->open(f, QIODevice::ReadWrite)) - */ - -#if 0 - m_device = new Win_QextSerialPort(port); - m_device->setBaudRate(BAUD115200); - m_device->setDataBits(DATA_8); - m_device->setParity(PAR_NONE); - //m_device->setStopBits(STO); - m_device->setFlowControl(FLOW_OFF); - m_device->setTimeout(0, 500); - - if (!m_device->open(QIODevice::ReadWrite)) { - QByteArray ba = m_device->errorString().toLatin1(); - logMessage("Could not open device " << ba); - return; - } -#else - m_device = new QLocalSocket(this); - m_device->connectToServer(port); - return m_device->waitForConnected(); -#endif -} - -void TrkClient::timerEvent(QTimerEvent *) -{ - //qDebug("."); - tryWrite(); - tryRead(); -} - -unsigned char TrkClient::nextWriteToken() -{ - ++m_writeToken; - if (m_writeToken == 0) - ++m_writeToken; - return m_writeToken; -} - -void TrkClient::sendMessage(byte command, - CallBack callBack, const QByteArray &lit) -{ - Message msg; - msg.command = command; - msg.token = nextWriteToken(); - msg.callBack = callBack; - QList<QByteArray> list = lit.split(' '); - foreach (const QByteArray &item, list) { - if (item.isEmpty()) - continue; - bool ok = false; - int i = item.toInt(&ok, 16); - msg.data.append(char(i)); - } - //logMessage("PARSED: " << lit << " -> " << stringFromArray(data).toLatin1().data()); - queueMessage(msg); -} - -void TrkClient::sendInitialPing() -{ - Message msg; - msg.command = 0x00; // Ping - msg.token = 0; // reset sequence count - queueMessage(msg); -} - -void TrkClient::waitForFinished() -{ - Message msg; - // initiate one last roundtrip to ensure all is flushed - msg.command = 0x00; // Ping - msg.token = nextWriteToken(); - msg.callBack = CB(handleWaitForFinished); - queueMessage(msg); -} - -void TrkClient::sendAck(byte token) -{ - logMessage(QString("SENDING ACKNOWLEDGEMENT FOR TOKEN ").arg(int(token))); - Message msg; - msg.command = 0x80; - msg.token = token; - msg.data.append('\0'); - // The acknowledgement must not be queued! - //queueMessage(msg); - doWrite(msg); - // 01 90 00 07 7e 80 01 00 7d 5e 7e -} - -void TrkClient::queueMessage(const Message &msg) -{ - m_writeQueue.append(msg); -} - -void TrkClient::tryWrite() -{ - if (m_writeBusy) - return; - if (m_writeQueue.isEmpty()) - return; - - doWrite(m_writeQueue.dequeue()); -} - -void TrkClient::doWrite(const Message &msg) -{ - QByteArray ba = frameMessage(msg.command, msg.token, msg.data); - - m_written.insert(msg.token, msg); - m_writeBusy = true; - -#if USE_NATIVE - - DWORD charsWritten; - - if (!WriteFile( m_hdevice, - ba.data(), - ba.size(), - &charsWritten, - NULL)){ - logMessage("WRITE ERROR: "); - } - - - logMessage("WRITE: " << qPrintable(stringFromArray(ba))); - FlushFileBuffers(m_hdevice); - -#else - - logMessage("WRITE: " << qPrintable(stringFromArray(ba))); - if (!m_device->write(ba)) - logMessage("WRITE ERROR: " << m_device->errorString()); - m_device->flush(); - -#endif - -} - -void TrkClient::tryRead() -{ - //logMessage("TRY READ: " << m_device->bytesAvailable() - // << stringFromArray(m_readQueue); - -#if USE_NATIVE - - const int BUFFERSIZE = 1024; - char buffer[BUFFERSIZE]; - DWORD charsRead; - - while (ReadFile(m_hdevice, buffer, BUFFERSIZE, &charsRead, NULL) - && BUFFERSIZE == charsRead) { - m_readQueue.append(buffer, charsRead); - } - m_readQueue.append(buffer, charsRead); - -#else // USE_NATIVE - - if (m_device->bytesAvailable() == 0 && m_readQueue.isEmpty()) - return; - - QByteArray res = m_device->readAll(); - m_readQueue.append(res); - - -#endif // USE_NATIVE - - if (m_readQueue.size() < 9) { - logMessage("ERROR READBUFFER INVALID (1): " - << stringFromArray(m_readQueue)); - m_readQueue.clear(); - return; - } - - while (!m_readQueue.isEmpty()) - handleResult(extractResult(&m_readQueue)); - - m_writeBusy = false; -} - - -void TrkClient::handleResult(const TrkResult &result) -{ - const char *prefix = "READ BUF: "; - QByteArray str = result.toString().toUtf8(); - switch (result.code) { - case 0x80: { // ACK - logMessage(prefix << "ACK: " << str.data()); - if (!result.data.isEmpty() && result.data.at(0)) - logMessage(prefix << "ERR: " << QByteArray::number(result.data.at(0))); - //logMessage("READ RESULT FOR TOKEN: " << token); - if (!m_written.contains(result.token)) { - logMessage("NO ENTRY FOUND!"); - } - Message msg = m_written.take(result.token); - CallBack cb = msg.callBack; - if (cb) { - //logMessage("HANDLE: " << stringFromArray(result.data)); - (this->*cb)(result); - } - break; - } - case 0xff: { // NAK - logMessage(prefix << "NAK: " << str.data()); - //logMessage(prefix << "TOKEN: " << result.token); - logMessage(prefix << "ERROR: " << errorMessage(result.data.at(0))); - break; - } - case 0x90: { // Notified Stopped - logMessage(prefix << "NOTE: STOPPED" << str.data()); - // 90 01 78 6a 40 40 00 00 07 23 00 00 07 24 00 00 - const char *data = result.data.data(); - uint addr = extractInt(data); //code address: 4 bytes; code base address for the library - uint pid = extractInt(data + 4); // ProcessID: 4 bytes; - uint tid = extractInt(data + 8); // ThreadID: 4 bytes - logMessage(prefix << " ADDR: " << addr << " PID: " << pid << " TID: " << tid); - sendAck(result.token); - //Sleep(10000); - //cleanUp(); - break; - } - case 0x91: { // Notify Exception (obsolete) - logMessage(prefix << "NOTE: EXCEPTION" << str.data()); - sendAck(result.token); - break; - } - case 0x92: { // - logMessage(prefix << "NOTE: INTERNAL ERROR: " << str.data()); - sendAck(result.token); - break; - } - - // target->host OS notification - case 0xa0: { // Notify Created - const char *data = result.data.data(); - byte error = result.data.at(0); - byte type = result.data.at(1); // type: 1 byte; for dll item, this value is 2. - uint pid = extractInt(data + 2); // ProcessID: 4 bytes; - uint tid = extractInt(data + 6); //threadID: 4 bytes - uint codeseg = extractInt(data + 10); //code address: 4 bytes; code base address for the library - uint dataseg = extractInt(data + 14); //data address: 4 bytes; data base address for the library - uint len = extractShort(data + 18); //length: 2 bytes; length of the library name string to follow - QByteArray name = result.data.mid(20, len); // name: library name - - logMessage(prefix << "NOTE: LIBRARY LOAD: " << str.data()); - logMessage(prefix << "TOKEN: " << result.token); - logMessage(prefix << "ERROR: " << int(error)); - logMessage(prefix << "TYPE: " << int(type)); - logMessage(prefix << "PID: " << pid); - logMessage(prefix << "TID: " << tid); - logMessage(prefix << "CODE: " << codeseg); - logMessage(prefix << "DATA: " << dataseg); - logMessage(prefix << "LEN: " << len); - logMessage(prefix << "NAME: " << name); - - sendMessage(0x18, CB(handleContinue), - formatInt(m_session.pid) + formatInt(m_session.tid)); - - //sendAck(result.token) - break; - } - case 0xa1: { // NotifyDeleted - logMessage(prefix << "NOTE: LIBRARY UNLOAD: " << str.data()); - sendAck(result.token); - break; - } - case 0xa2: { // NotifyProcessorStarted - logMessage(prefix << "NOTE: PROCESSOR STARTED: " << str.data()); - sendAck(result.token); - break; - } - case 0xa6: { // NotifyProcessorStandby - logMessage(prefix << "NOTE: PROCESSOR STANDBY: " << str.data()); - sendAck(result.token); - break; - } - case 0xa7: { // NotifyProcessorReset - logMessage(prefix << "NOTE: PROCESSOR RESET: " << str.data()); - sendAck(result.token); - break; - } - default: { - logMessage(prefix << "INVALID: " << str << result.data.size()); - break; - } - } -} - -void TrkClient::handleCpuType(const TrkResult &result) -{ - logMessage("HANDLE CPU TYPE: " << result.toString()); - //---TRK------------------------------------------------------ - // Command: 0x80 Acknowledge - // Error: 0x00 - // [80 03 00 04 00 00 04 00 00 00] - m_session.cpuMajor = result.data[0]; - m_session.cpuMinor = result.data[1]; - m_session.bigEndian = result.data[2]; - m_session.defaultTypeSize = result.data[3]; - m_session.fpTypeSize = result.data[4]; - m_session.extended1TypeSize = result.data[5]; - //m_session.extended2TypeSize = result.data[6]; -} - -void TrkClient::handleCreateProcess(const TrkResult &result) -{ - //---TRK------------------------------------------------------ - // Command: 0x80 Acknowledge - // Error: 0x00 - // [80 08 00 00 00 01 B5 00 00 01 B6 78 67 40 00 00 - // 40 00 00] - - logMessage(" RESULT: " << qPrintable(result.toString())); - const char *data = result.data.data(); - m_session.pid = extractInt(data); - m_session.tid = extractInt(data + 4); - m_session.codeseg = extractInt(data + 8); - m_session.dataseg = extractInt(data + 12); - - logMessage("PID: " << formatInt(m_session.pid) << m_session.pid); - logMessage("TID: " << formatInt(m_session.tid) << m_session.tid); - logMessage("COD: " << formatInt(m_session.codeseg) << m_session.codeseg); - logMessage("DAT: " << formatInt(m_session.dataseg) << m_session.dataseg); - - - //setBreakpoint(0x0000, ArmMode); - //clearBreakpoint(0x0000); - -#if 1 - foreach (const Breakpoint &bp, m_breakpoints) - setBreakpoint(bp); -#endif - -#if 1 - //---IDE------------------------------------------------------ - // Command: 0x42 Read Info - // [42 0C 00 06 00 00 00 00 00 14 50 6F 6C 79 6D 6F - // 72 70 68 69 63 44 4C 4C 32 2E 64 6C 6C 00] - sendMessage(0x42, CB(handleReadInfo), - "00 06 00 00 00 00 00 14 50 6F 6C 79 6D 6F " - "72 70 68 69 63 44 4C 4C 32 2E 64 6C 6C 00"); - //sendMessage(0x42, CB(handleReadInfo), - // "00 01 00 00 00 00"); - //---TRK------------------------------------------------------ - // Command: 0x80 Acknowledge - // Error: 0x20 Unspecified general OS-related error - // [80 0C 20] - - - //---IDE------------------------------------------------------ - // Command: 0x42 Read Info - // [42 0D 00 06 00 00 00 00 00 14 50 6F 6C 79 6D 6F - // 72 70 68 69 63 44 4C 4C 31 2E 64 6C 6C 00] - sendMessage(0x42, CB(handleReadInfo), - "00 06 00 00 00 00 00 14 50 6F 6C 79 6D 6F " - "72 70 68 69 63 44 4C 4C 31 2E 64 6C 6C 00"); - //---TRK------------------------------------------------------ - // Command: 0x80 Acknowledge - // Error: 0x20 Unspecified general OS-related error - // [80 0D 20] -#endif - - //sendMessage(0x18, CB(handleStop), - // "01 " + formatInt(m_session.pid) + formatInt(m_session.tid)); - - //---IDE------------------------------------------------------ - // Command: 0x18 Continue - //ProcessID: 0x000001B5 (437) - // ThreadID: 0x000001B6 (438) - // [18 0E 00 00 01 B5 00 00 01 B6] - sendMessage(0x18, CB(handleContinue), - formatInt(m_session.pid) + formatInt(m_session.tid)); - //sendMessage(0x18, CB(handleContinue), - // formatInt(m_session.pid) + "ff ff ff ff"); - //---TRK------------------------------------------------------ - // Command: 0x80 Acknowledge - // Error: 0x00 - // [80 0E 00] -} - -void TrkClient::setBreakpoint(const Breakpoint &bp) -{ - //---IDE------------------------------------------------------ - // Command: 0x1B Set Break - //BreakType: 0x82 - // Options: 0x00 - // Address: 0x78674340 (2020033344) i.e + 0x00000340 - // Length: 0x00000001 (1) - // Count: 0x00000000 (0) - //ProcessID: 0x000001b5 (437) - // ThreadID: 0xffffffff (-1) - // [1B 09 82 00 78 67 43 40 00 00 00 01 00 00 00 00 - // 00 00 01 B5 FF FF FF FF] - sendMessage(0x1B, CB(handleSetBreakpoint), - "82 " - + QByteArray(bp.mode == ArmMode ? "00 " : "01 ") - + formatInt(m_session.codeseg + bp.offset) - + "00 00 00 01 00 00 00 00 " + formatInt(m_session.pid) - + "FF FF FF FF"); - //m_session.toekn - - //---TRK------------------------------------------------------ - // Command: 0x80 Acknowledge - // Error: 0x00 - // [80 09 00 00 00 00 0A] -} - -void TrkClient::handleSetBreakpoint(const TrkResult &result) -{ - //---TRK------------------------------------------------------ - // Command: 0x80 Acknowledge - // Error: 0x00 - // [80 09 00 00 00 00 0A] - uint bpnr = extractInt(result.data.data()); - logMessage("SET BREAKPOINT " << bpnr - << stringFromArray(result.data.data())); -} - -void TrkClient::clearBreakpoint(const Breakpoint &bp) -{ - sendMessage(0x1C, CB(handleClearBreakpoint), - //formatInt(m_session.codeseg + bp.offset)); - "00 " + formatShort(bp.number) - + formatInt(m_session.codeseg + bp.offset)); - - //---IDE------------------------------------------------------ - // Command: 0x1C Clear Break - // [1C 25 00 00 00 0A 78 6A 43 40] -} - -void TrkClient::handleClearBreakpoint(const TrkResult &result) -{ - Q_UNUSED(result); - //---TRK------------------------------------------------------ - // Command: 0x80 Acknowledge - // Error: 0x00 - // [80 09 00 00 00 00 0A] - logMessage("CLEAR BREAKPOINT "); -} - -void TrkClient::handleContinue(const TrkResult &result) -{ - logMessage(" HANDLE CONTINUE: " << qPrintable(stringFromArray(result.data))); - //if (result.result.token) - //logMessage(" ERROR: " << byte(result.result.token) - // sendMessage(0x18, CB(handleContinue), - // formatInt(m_session.pid) + formatInt(m_session.tid)); - //} -} - -void TrkClient::handleDisconnect(const TrkResult &result) -{ - logMessage(" HANDLE DISCONNECT: " - << qPrintable(stringFromArray(result.data))); - //if (result.result.token) - //logMessage(" ERROR: " << byte(result.result.token) - // sendMessage(0x18, CB(handleContinue), - // formatInt(m_session.pid) + formatInt(m_session.tid)); - //} -} - -void TrkClient::handleDeleteProcess(const TrkResult &result) -{ - logMessage(" HANDLE DELETE PROCESS: " << -qPrintable(stringFromArray(result.data))); - //if (result.result.token) - //logMessage(" ERROR: " << byte(result.token) - // sendMessage(0x18, CB(handleContinue), - // formatInt(m_session.pid) + formatInt(m_session.tid)); - //} -} - -void TrkClient::handleStep(const TrkResult &result) -{ - logMessage(" HANDLE STEP: " << -qPrintable(stringFromArray(result.data))); -} - -void TrkClient::handleStop(const TrkResult &result) -{ - logMessage(" HANDLE STOP: " << -qPrintable(stringFromArray(result.data))); -} - - -void TrkClient::handleReadInfo(const TrkResult &result) -{ - logMessage(" HANDLE READ INFO: " << -qPrintable(stringFromArray(result.data))); -} - -void TrkClient::handleWaitForFinished(const TrkResult &result) -{ - logMessage(" FINISHED: " << qPrintable(stringFromArray(result.data))); - //qApp->exit(1); -} - -void TrkClient::handleSupportMask(const TrkResult &result) -{ - const char *data = result.data.data(); - QByteArray str; - for (int i = 0; i < 32; ++i) { - //str.append(" [" + formatByte(data[i]) + "]: "); - for (int j = 0; j < 8; ++j) - if (data[i] & (1 << j)) - str.append(formatByte(i * 8 + j)); - } - logMessage("SUPPORTED: " << str); -} - - -void TrkClient::cleanUp() -{ - // - //---IDE------------------------------------------------------ - // Command: 0x41 Delete Item - // Sub Cmd: Delete Process - //ProcessID: 0x0000071F (1823) - // [41 24 00 00 00 00 07 1F] - sendMessage(0x41, CB(handleDeleteProcess), - "00 00 " + formatInt(m_session.pid)); - //---TRK------------------------------------------------------ - // Command: 0x80 Acknowledge - // Error: 0x00 - // [80 24 00] - - foreach (const Breakpoint &bp, m_breakpoints) - clearBreakpoint(bp); - - //---IDE------------------------------------------------------ - // Command: 0x1C Clear Break - // [1C 25 00 00 00 0A 78 6A 43 40] - - //---TRK------------------------------------------------------ - // Command: 0xA1 Notify Deleted - // [A1 09 00 00 00 00 00 00 00 00 07 1F] - //---IDE------------------------------------------------------ - // Command: 0x80 Acknowledge - // Error: 0x00 - // [80 09 00] - - //---TRK------------------------------------------------------ - // Command: 0x80 Acknowledge - // Error: 0x00 - // [80 25 00] - - //---IDE------------------------------------------------------ - // Command: 0x1C Clear Break - // [1C 26 00 00 00 0B 78 6A 43 70] - //---TRK------------------------------------------------------ - // Command: 0x80 Acknowledge - // Error: 0x00 - // [80 26 00] - - - //---IDE------------------------------------------------------ - // Command: 0x02 Disconnect - // [02 27] - sendMessage(0x02, CB(handleDisconnect)); - //---TRK------------------------------------------------------ - // Command: 0x80 Acknowledge - // Error: 0x00 -} - -void TrkClient::onStopped(const TrkResult &result) -{ - Q_UNUSED(result); -} } // namespace trk diff --git a/tests/manual/trk/trkutils.h b/tests/manual/trk/trkutils.h index ee6530cadbb1058b8ef7449a733673d42fa763fd..81e50c66147249ececeb431146d53ea014fcc06d 100644 --- a/tests/manual/trk/trkutils.h +++ b/tests/manual/trk/trkutils.h @@ -32,11 +32,8 @@ #include <QtCore/QByteArray> #include <QtCore/QHash> -#include <QtCore/QObject> -#include <QtCore/QQueue> #include <QtCore/QString> - -#include <QtNetwork/QLocalSocket> +#include <QtCore/QVariant> namespace trk { @@ -55,10 +52,17 @@ QString stringFromByte(byte c); // produces "xx xx xx " QString stringFromArray(const QByteArray &ba); -QByteArray formatByte(byte b); -QByteArray formatShort(ushort s); -QByteArray formatInt(uint i); -QByteArray formatString(const QByteArray &str); +enum Endianness +{ + LittleEndian, + BigEndian, + TargetByteOrder = BigEndian, +}; + +void appendByte(QByteArray *ba, byte b); +void appendShort(QByteArray *ba, ushort s, Endianness = TargetByteOrder); +void appendInt(QByteArray *ba, uint i, Endianness = TargetByteOrder); +void appendString(QByteArray *ba, const QByteArray &str, Endianness = TargetByteOrder); enum CodeMode { @@ -66,6 +70,12 @@ enum CodeMode ThumbMode, }; +enum TargetConstants +{ + registerCount = 16, + memoryChunkSize = 256 +}; + struct Session { Session() { @@ -80,8 +90,11 @@ struct Session tid = 0; codeseg = 0; dataseg = 0; + + currentThread = 0; } + // Trk feedback byte cpuMajor; byte cpuMinor; byte bigEndian; @@ -94,6 +107,16 @@ struct Session uint codeseg; uint dataseg; QHash<uint, uint> tokenToBreakpointIndex; + + // Gdb request + uint currentThread; +}; + +struct SnapShot +{ + uint registers[registerCount]; + typedef QHash<uint, QByteArray> Memory; + Memory memory; }; struct Breakpoint @@ -111,97 +134,19 @@ struct Breakpoint struct TrkResult { - TrkResult() {} + TrkResult() { code = token = 0; } QString toString() const; byte code; byte token; QByteArray data; -}; - -class TrkClient : public QObject -{ - Q_OBJECT - -public: - TrkClient(); - ~TrkClient(); - struct Message; - typedef void (TrkClient::*CallBack)(const TrkResult &); - -public slots: - void abort() { m_device->abort(); } - bool openPort(const QString &port); // or server name for local server - void sendMessage(byte command, CallBack callBack = 0, - const QByteArray &lit = QByteArray()); - // adds message to 'send' queue - void queueMessage(const Message &msg); - void tryWrite(); - void tryRead(); - // actually writes a message to the device - void doWrite(const Message &msg); - // convienience messages - void sendInitialPing(); - void waitForFinished(); - void sendAck(byte token); - - // kill process and breakpoints - void cleanUp(); - -public: - struct Message - { - Message() { token = 0; callBack = 0; } - byte command; - byte token; - QByteArray data; - CallBack callBack; - }; - -private: - void timerEvent(QTimerEvent *ev); - byte nextWriteToken(); - - void handleCpuType(const TrkResult &result); - void handleCreateProcess(const TrkResult &result); - void handleDeleteProcess(const TrkResult &result); - void handleSetBreakpoint(const TrkResult &result); - void handleClearBreakpoint(const TrkResult &result); - void handleContinue(const TrkResult &result); - void handleReadInfo(const TrkResult &result); - void handleWaitForFinished(const TrkResult &result); - void handleStep(const TrkResult &result); - void handleStop(const TrkResult &result); - void handleReadRegisters(const TrkResult &result); - void handleWriteRegisters(const TrkResult &result); - void handleReadMemory(const TrkResult &result); - void handleWriteMemory(const TrkResult &result); - void handleSupportMask(const TrkResult &result); - void handleDisconnect(const TrkResult &result); - - - void setBreakpoint(const Breakpoint &bp); - void clearBreakpoint(const Breakpoint &bp); - void onStopped(const TrkResult &result); - void handleResult(const TrkResult &data); - - QLocalSocket *m_device; - - unsigned char m_writeToken; - QQueue<Message> m_writeQueue; - QHash<byte, Message> m_written; - unsigned char m_readToken; - QByteArray m_readQueue; - bool m_writeBusy; - - QList<Breakpoint> m_breakpoints; - Session m_session; + QVariant cookie; }; // returns a QByteArray containing 0x01 0x90 <len> 0x7e encoded7d(ba) 0x7e QByteArray frameMessage(byte command, byte token, const QByteArray &data); TrkResult extractResult(QByteArray *buffer); - +QByteArray errorMessage(byte code); } // namespace trk