From c4d1553da4553da65ea7877af6ae7441528f1134 Mon Sep 17 00:00:00 2001 From: Daniel Molkentin <daniel.molkentin@nokia.com> Date: Thu, 21 Jan 2010 21:12:40 +0100 Subject: [PATCH] Add first version of a new sidebar, including project selector. The project selector also allows to select targets. However, this is not yet used, since the necessary changes are still being stabilized. Done-with: con --- src/plugins/coreplugin/coreimpl.cpp | 7 + src/plugins/coreplugin/coreimpl.h | 1 + src/plugins/coreplugin/fancyactionbar.cpp | 194 +++++++----- src/plugins/coreplugin/fancyactionbar.h | 5 +- src/plugins/coreplugin/fancyactionbar.qrc | 3 + src/plugins/coreplugin/icore.h | 2 + .../coreplugin/images/button_top_outline.png | Bin 0 -> 411 bytes .../images/fancytoolbutton_bottom_outline.png | Bin 0 -> 1811 bytes .../images/fancytoolbutton_normal_outline.png | Bin 0 -> 2407 bytes .../images/fancytoolbutton_top_outline.png | Bin 0 -> 411 bytes src/plugins/coreplugin/modemanager.cpp | 5 + src/plugins/coreplugin/modemanager.h | 3 + .../projectexplorer/metatypedeclarations.h | 1 - .../miniprojecttargetselector.cpp | 289 ++++++++++++++++++ .../miniprojecttargetselector.h | 102 +++++++ src/plugins/projectexplorer/project.h | 2 + .../projectexplorer/projectexplorer.cpp | 40 ++- src/plugins/projectexplorer/projectexplorer.h | 6 +- .../projectexplorer/projectexplorer.pro | 2 + 19 files changed, 580 insertions(+), 82 deletions(-) create mode 100644 src/plugins/coreplugin/images/button_top_outline.png create mode 100644 src/plugins/coreplugin/images/fancytoolbutton_bottom_outline.png create mode 100644 src/plugins/coreplugin/images/fancytoolbutton_normal_outline.png create mode 100644 src/plugins/coreplugin/images/fancytoolbutton_top_outline.png create mode 100644 src/plugins/projectexplorer/miniprojecttargetselector.cpp create mode 100644 src/plugins/projectexplorer/miniprojecttargetselector.h diff --git a/src/plugins/coreplugin/coreimpl.cpp b/src/plugins/coreplugin/coreimpl.cpp index 643cc4c5f0b..65916f8cac2 100644 --- a/src/plugins/coreplugin/coreimpl.cpp +++ b/src/plugins/coreplugin/coreimpl.cpp @@ -33,6 +33,8 @@ #include <QtCore/QCoreApplication> #include <QtCore/QSettings> +#include <QtGui/QStatusBar> + namespace Core { namespace Internal { @@ -179,6 +181,11 @@ QMainWindow *CoreImpl::mainWindow() const return m_mainwindow; } +QStatusBar *CoreImpl::statusBar() const +{ + return m_mainwindow->statusBar(); +} + // adds and removes additional active contexts, this context is appended to the // currently active contexts. call updateContext after changing void CoreImpl::addAdditionalContext(int context) diff --git a/src/plugins/coreplugin/coreimpl.h b/src/plugins/coreplugin/coreimpl.h index dd3a7d831e8..6e0540ec047 100644 --- a/src/plugins/coreplugin/coreimpl.h +++ b/src/plugins/coreplugin/coreimpl.h @@ -79,6 +79,7 @@ public: IContext *currentContextObject() const; QMainWindow *mainWindow() const; + QStatusBar *statusBar() const; // adds and removes additional active contexts, this context is appended to the // currently active contexts. call updateContext after changing diff --git a/src/plugins/coreplugin/fancyactionbar.cpp b/src/plugins/coreplugin/fancyactionbar.cpp index bcb75b6dc7c..18bca72f99c 100644 --- a/src/plugins/coreplugin/fancyactionbar.cpp +++ b/src/plugins/coreplugin/fancyactionbar.cpp @@ -1,4 +1,4 @@ -/************************************************************************** +/********************Q****************************************************** ** ** This file is part of Qt Creator ** @@ -29,53 +29,25 @@ #include "fancyactionbar.h" +#include <utils/stylehelper.h> + +#include <coreplugin/icore.h> +#include <coreplugin/mainwindow.h> + #include <QtGui/QHBoxLayout> #include <QtGui/QPainter> #include <QtGui/QPicture> #include <QtGui/QVBoxLayout> -#include <QtSvg/QSvgRenderer> #include <QtGui/QAction> +#include <QtGui/QStatusBar> +#include <QtGui/QStyle> +#include <QtGui/QStyleOption> using namespace Core; using namespace Internal; -static const char* const svgIdButtonBase = "ButtonBase"; -static const char* const svgIdButtonNormalBase = "ButtonNormalBase"; -static const char* const svgIdButtonNormalOverlay = "ButtonNormalOverlay"; -static const char* const svgIdButtonPressedBase = "ButtonPressedBase"; -static const char* const svgIdButtonPressedOverlay = "ButtonPressedOverlay"; -static const char* const svgIdButtonDisabledOverlay = "ButtonDisabledOverlay"; -static const char* const svgIdButtonHoverOverlay = "ButtonHoverOverlay"; - -static const char* const elementsSvgIds[] = { - svgIdButtonBase, - svgIdButtonNormalBase, - svgIdButtonNormalOverlay, - svgIdButtonPressedBase, - svgIdButtonPressedOverlay, - svgIdButtonDisabledOverlay, - svgIdButtonHoverOverlay -}; - -const QMap<QString, QPicture> &buttonElementsMap() -{ - static QMap<QString, QPicture> result; - if (result.isEmpty()) { - QSvgRenderer renderer(QLatin1String(":/fancyactionbar/images/fancytoolbutton.svg")); - for (size_t i = 0; i < sizeof(elementsSvgIds)/sizeof(elementsSvgIds[0]); i++) { - QString elementId(elementsSvgIds[i]); - QPicture elementPicture; - QPainter elementPainter(&elementPicture); - renderer.render(&elementPainter, elementId); - result.insert(elementId, elementPicture); - } - } - return result; -} - FancyToolButton::FancyToolButton(QWidget *parent) : QToolButton(parent) - , m_buttonElements(buttonElementsMap()) { setAttribute(Qt::WA_Hover, true); setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); @@ -85,40 +57,99 @@ void FancyToolButton::paintEvent(QPaintEvent *event) { Q_UNUSED(event) QPainter p(this); - QSize sh(sizeHint()); - double scale = (double)height() / sh.height(); - if (scale < 1) { - p.save(); - p.scale(1, scale); - } - p.drawPicture(0, 0, m_buttonElements.value(svgIdButtonBase)); - p.drawPicture(0, 0, m_buttonElements.value(isDown() ? svgIdButtonPressedBase : svgIdButtonNormalBase)); + + QLayout *parentLayout = qobject_cast<FancyActionBar*>(parentWidget())->actionsLayout(); + int lineHeight = fontMetrics().height(); + bool isTitledAction = defaultAction()->property("titledAction").toBool(); + #ifndef Q_WS_MAC // Mac UIs usually don't hover - if (underMouse() && isEnabled()) - p.drawPicture(0, 0, m_buttonElements.value(svgIdButtonHoverOverlay)); + if (underMouse() && isEnabled() && !isDown()) { + QColor whiteOverlay(Qt::white); + whiteOverlay.setAlpha(20); + p.fillRect(rect().adjusted(1, 1, -1, -1), whiteOverlay); + } #endif - if (scale < 1) - p.restore(); + if (isDown()) { + QColor whiteOverlay(Qt::black); + whiteOverlay.setAlpha(20); + p.fillRect(rect().adjusted(1, 1, -1, -1), whiteOverlay); + } - if (!icon().isNull()) { - icon().paint(&p, rect()); - } else { - const int margin = 4; - p.drawText(rect().adjusted(margin, margin, -margin, -margin), Qt::AlignCenter | Qt::TextWordWrap, text()); + QPixmap borderPixmap; + QMargins margins; + if (parentLayout && parentLayout->count() > 0 && + parentLayout->itemAt(parentLayout->count()-1)->widget() == this) { + margins = QMargins(3, 3, 2, 0); + borderPixmap = QPixmap( + QLatin1String(":/fancyactionbar/images/fancytoolbutton_bottom_outline.png")); + } else if (parentLayout && parentLayout->count() > 0 && + parentLayout->itemAt(0)->widget() == this) { + margins = QMargins(3, 3, 2, 3); + borderPixmap = QPixmap( + QLatin1String(":/fancyactionbar/images/fancytoolbutton_top_outline.png")); + } else { + margins = QMargins(3, 3, 2, 0); + borderPixmap = QPixmap( + QLatin1String(":/fancyactionbar/images/fancytoolbutton_normal_outline.png")); + } + QRect drawRect = rect(); + qDrawBorderPixmap(&p, drawRect, margins, borderPixmap); + + QPixmap pix = icon().pixmap(size() - QSize(15, 15), isEnabled() ? QIcon::Normal : QIcon::Disabled); + QPoint center = rect().center(); + QSize halfPixSize = pix.size()/2; + + p.drawPixmap(center-QPoint(halfPixSize.width()-1, halfPixSize.height()-1), pix); + + if (popupMode() == QToolButton::DelayedPopup && !isTitledAction) { + QPoint arrowOffset = center + QPoint(pix.rect().width()/2, pix.rect().height()/2); + QStyleOption opt; + if (isEnabled()) + opt.state &= QStyle::State_Enabled; + else + opt.state |= QStyle::State_Enabled; + opt.rect = QRect(arrowOffset.x(), arrowOffset.y(), 6, 6); + style()->drawPrimitive(QStyle::PE_IndicatorArrowDown, + &opt, &p, this); } - if (scale < 1) { - p.scale(1, scale); + if (isTitledAction) { + QRect r(0, lineHeight/2, rect().width(), lineHeight); + QColor penColor; + if (isEnabled()) + penColor = Qt::white; + else + penColor = Qt::gray; + p.setPen(penColor); + const QString projectName = defaultAction()->property("heading").toString(); + QFont f = font(); + f.setPointSize(f.pointSize()-1); + p.setFont(f); + QFontMetrics fm(f); + QString ellidedProjectName = fm.elidedText(projectName, Qt::ElideMiddle, r.width()); + if (isEnabled()) { + const QRect shadowR = r.translated(0, 1); + p.setPen(Qt::black); + p.drawText(shadowR, Qt::AlignVCenter|Qt::AlignHCenter, ellidedProjectName); + p.setPen(penColor); + } + p.drawText(r, Qt::AlignVCenter|Qt::AlignHCenter, ellidedProjectName); + r = QRect(0, rect().bottom()-lineHeight*1.5, rect().width(), lineHeight); + const QString buildConfiguration = defaultAction()->property("subtitle").toString(); + f.setBold(true); + p.setFont(f); + QString ellidedBuildConfiguration = fm.elidedText(buildConfiguration, Qt::ElideMiddle, r.width()); + if (isEnabled()) { + const QRect shadowR = r.translated(0, 1); + p.setPen(Qt::black); + p.drawText(shadowR, Qt::AlignVCenter|Qt::AlignHCenter, ellidedBuildConfiguration); + p.setPen(penColor); + } + p.drawText(r, Qt::AlignVCenter|Qt::AlignHCenter, ellidedBuildConfiguration); } - if (isEnabled()) { - p.drawPicture(0, 0, m_buttonElements.value(isDown() ? - svgIdButtonPressedOverlay : svgIdButtonNormalOverlay)); - } else { - p.drawPicture(0, 0, m_buttonElements.value(svgIdButtonDisabledOverlay)); - } } void FancyActionBar::paintEvent(QPaintEvent *event) @@ -128,7 +159,12 @@ void FancyActionBar::paintEvent(QPaintEvent *event) QSize FancyToolButton::sizeHint() const { - return m_buttonElements.value(svgIdButtonBase).boundingRect().size(); + QSize buttonSize = iconSize().expandedTo(QSize(64, 40)); + if (defaultAction()->property("titledAction").toBool()) { + int lineHeight = fontMetrics().height(); + buttonSize += QSize(0, lineHeight*4); + } + return buttonSize; } QSize FancyToolButton::minimumSizeHint() const @@ -149,13 +185,30 @@ FancyActionBar::FancyActionBar(QWidget *parent) { m_actionsLayout = new QVBoxLayout; - QHBoxLayout *centeringLayout = new QHBoxLayout; - centeringLayout->addStretch(); - centeringLayout->addLayout(m_actionsLayout); - centeringLayout->addStretch(); - setLayout(centeringLayout); + QVBoxLayout *spacerLayout = new QVBoxLayout; + spacerLayout->addLayout(m_actionsLayout); + int sbh = ICore::instance()->statusBar()->height(); + spacerLayout->addSpacing(sbh); + spacerLayout->setMargin(0); + spacerLayout->setSpacing(0); + + QHBoxLayout *orientRightLayout = new QHBoxLayout; + orientRightLayout->addStretch(); + orientRightLayout->setMargin(0); + orientRightLayout->setSpacing(0); + orientRightLayout->setContentsMargins(0, 0, 1, 0); + orientRightLayout->addLayout(spacerLayout); + setLayout(orientRightLayout); } +void FancyActionBar::addProjectSelector(QAction *action) +{ + FancyToolButton* toolButton = new FancyToolButton(this); + toolButton->setDefaultAction(action); + connect(action, SIGNAL(changed()), toolButton, SLOT(actionChanged())); + m_actionsLayout->insertWidget(0, toolButton); + +} void FancyActionBar::insertAction(int index, QAction *action, QMenu *menu) { FancyToolButton *toolButton = new FancyToolButton(this); @@ -187,3 +240,8 @@ void FancyActionBar::toolButtonContextMenuActionTriggered(QAction* action) button->defaultAction()->trigger(); } } + +QLayout *FancyActionBar::actionsLayout() const +{ + return m_actionsLayout; +} diff --git a/src/plugins/coreplugin/fancyactionbar.h b/src/plugins/coreplugin/fancyactionbar.h index 0f4f853e3a6..ad7807d9357 100644 --- a/src/plugins/coreplugin/fancyactionbar.h +++ b/src/plugins/coreplugin/fancyactionbar.h @@ -54,9 +54,6 @@ public: private slots: void actionChanged(); - -private: - const QMap<QString, QPicture> &m_buttonElements; }; class FancyActionBar : public QWidget @@ -68,6 +65,8 @@ public: void paintEvent(QPaintEvent *event); void insertAction(int index, QAction *action, QMenu *menu = 0); + void addProjectSelector(QAction *action); + QLayout *actionsLayout() const; private slots: void toolButtonContextMenuActionTriggered(QAction*); diff --git a/src/plugins/coreplugin/fancyactionbar.qrc b/src/plugins/coreplugin/fancyactionbar.qrc index 1d46626955e..f71f5d851de 100644 --- a/src/plugins/coreplugin/fancyactionbar.qrc +++ b/src/plugins/coreplugin/fancyactionbar.qrc @@ -6,5 +6,8 @@ <file>images/mode_Output.png</file> <file>images/mode_Project.png</file> <file>images/mode_Reference.png</file> + <file>images/fancytoolbutton_bottom_outline.png</file> + <file>images/fancytoolbutton_normal_outline.png</file> + <file>images/fancytoolbutton_top_outline.png</file> </qresource> </RCC> diff --git a/src/plugins/coreplugin/icore.h b/src/plugins/coreplugin/icore.h index de991cce82c..56851d655d7 100644 --- a/src/plugins/coreplugin/icore.h +++ b/src/plugins/coreplugin/icore.h @@ -40,6 +40,7 @@ QT_BEGIN_NAMESPACE class QMainWindow; class QPrinter; class QSettings; +class QStatusBar; template <class T> class QList; QT_END_NAMESPACE @@ -104,6 +105,7 @@ public: virtual QString resourcePath() const = 0; virtual QMainWindow *mainWindow() const = 0; + virtual QStatusBar *statusBar() const = 0; // adds and removes additional active contexts, this context is appended to the // currently active contexts. call updateContext after changing diff --git a/src/plugins/coreplugin/images/button_top_outline.png b/src/plugins/coreplugin/images/button_top_outline.png new file mode 100644 index 0000000000000000000000000000000000000000..edb50687ce30f063d513ec9548ba1d253bdb655e GIT binary patch literal 411 zcmeAS@N?(olHy`uVBq!ia0vp^?m(==!3HGFo0ql$DaPU;cPEB*=VV?2Ic!PZ?k)`f zL2$v|<&%LToCO|{#S9GmRzNJocq*kd11QK|;_2(kev45^K*k~~DD@vuNV3E=qQp5r zH#aq}gu%HeHL)Z$MWH;iBtya7(>EZzkxv|`=$ogDV@Srmw^zLLS_}kSFQ)TkDId$> zP`q}mPQW_3fwe4k(iRW)E2q+@?8|S`m_4a>!<#Sj5+!twt;oGSrFh!RTAq`Z%Qx3- z|2KW_xmWvF%DxT_J$dGd%F5SPx4*|uda^e>P~>~(akq0j_1~wTU)>t>b=R!VZ+@p| z|9B}kYgypA$aU|lqo=tlvfRxxpPIU|a^Cv-zuYM@?%tX!W3Gpm#;#tMUHRVB_p<k4 zncyQ5SGTQo;y7UQXvvg!%iC-o%(%IndxlJb0t35D!2w1v(cZw!XYl|=K*Z1`{(RrV Z82Zm_+1@8^Cx9Wq;OXk;vd$@?2>|X|qf`I@ literal 0 HcmV?d00001 diff --git a/src/plugins/coreplugin/images/fancytoolbutton_bottom_outline.png b/src/plugins/coreplugin/images/fancytoolbutton_bottom_outline.png new file mode 100644 index 0000000000000000000000000000000000000000..6cb32d87e3ef84253f4c924e4d8b59610f096b9b GIT binary patch literal 1811 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 BaQOfL literal 0 HcmV?d00001 diff --git a/src/plugins/coreplugin/images/fancytoolbutton_normal_outline.png b/src/plugins/coreplugin/images/fancytoolbutton_normal_outline.png new file mode 100644 index 0000000000000000000000000000000000000000..8e7958e99da79934d90aad9e2b3ba077a6c6ce7e GIT binary patch literal 2407 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 Z{{b&OLi%BctL6Xz002ovPDHLkV1oQud58c2 literal 0 HcmV?d00001 diff --git a/src/plugins/coreplugin/images/fancytoolbutton_top_outline.png b/src/plugins/coreplugin/images/fancytoolbutton_top_outline.png new file mode 100644 index 0000000000000000000000000000000000000000..55e0f2a08f01a57dfdc91abc86296c0a8288f981 GIT binary patch literal 411 zcmeAS@N?(olHy`uVBq!ia0vp^?m(==!3HGFo0ql$DaPU;cPEB*=VV?2Ic!PZ?k)`f zL2$v|<&%LToCO|{#S9GmRzNJocq*kd11QK|;_2(kev45^Kvd7)CHomrNV3E=qQp5r zH#aq}gu%HeHL)Z$MWH;iBtya7(>EZzkxv|`=$ogDV@Srmw^zLLS_}kSFQ)TkDId$> zP`q}mPQW_3fwe4k(iRW)E2q+@?8|S`m_4a>!<#Sj5+!twt;oGSrFh!RTAq`Z%Qx3- z|2KW_xmWvF%DxT_J$dGd%F5SPx4*|uda^e>P~>~(akq0j_1~wTU)>t>b=R!VZ+@p| z|9B}kYgypA$aU|lqo=tlvfRxxpPIU|a^Cv-zuYM@?%tX!W3Gpm#;#tMUHRVB_p<k4 zncyQ5SGTQo;y7UQXvvg!%iC-o%(%IndxlJb0t35D!2w1v(cZw!XYl|=K*Z1`{(RrV Z82Zm_+1@8^Cx9Wq;OXk;vd$@?2>_BfqX+;1 literal 0 HcmV?d00001 diff --git a/src/plugins/coreplugin/modemanager.cpp b/src/plugins/coreplugin/modemanager.cpp index df9d41d01c2..bede27cb535 100644 --- a/src/plugins/coreplugin/modemanager.cpp +++ b/src/plugins/coreplugin/modemanager.cpp @@ -205,6 +205,11 @@ void ModeManager::addAction(Command *command, int priority, QMenu *menu) m_actionBar->insertAction(index, command->action(), menu); } +void ModeManager::addProjectSelector(QAction *action) +{ + m_actionBar->addProjectSelector(action); +} + void ModeManager::currentTabAboutToChange(int index) { if (index >= 0) { diff --git a/src/plugins/coreplugin/modemanager.h b/src/plugins/coreplugin/modemanager.h index c2ad51a8a4f..4cf2d8a4043 100644 --- a/src/plugins/coreplugin/modemanager.h +++ b/src/plugins/coreplugin/modemanager.h @@ -38,6 +38,7 @@ #include <coreplugin/core_global.h> QT_BEGIN_NAMESPACE +class QAction; class QSignalMapper; class QMenu; QT_END_NAMESPACE @@ -50,6 +51,7 @@ class IMode; namespace Internal { class FancyTabWidget; class FancyActionBar; +class FancyConfigButton; class MainWindow; } // namespace Internal @@ -67,6 +69,7 @@ public: IMode* mode(const QString &id) const; void addAction(Command *command, int priority, QMenu *menu = 0); + void addProjectSelector(QAction *action); void addWidget(QWidget *widget); signals: diff --git a/src/plugins/projectexplorer/metatypedeclarations.h b/src/plugins/projectexplorer/metatypedeclarations.h index 57fccb55067..c575324c369 100644 --- a/src/plugins/projectexplorer/metatypedeclarations.h +++ b/src/plugins/projectexplorer/metatypedeclarations.h @@ -46,7 +46,6 @@ class CommandQObject; } } -Q_DECLARE_METATYPE(ProjectExplorer::Project*) Q_DECLARE_METATYPE(QList<ProjectExplorer::Project*>) Q_DECLARE_METATYPE(ProjectExplorer::SessionManager*) Q_DECLARE_METATYPE(ProjectExplorer::IProjectManager*) diff --git a/src/plugins/projectexplorer/miniprojecttargetselector.cpp b/src/plugins/projectexplorer/miniprojecttargetselector.cpp new file mode 100644 index 00000000000..d8de5905b92 --- /dev/null +++ b/src/plugins/projectexplorer/miniprojecttargetselector.cpp @@ -0,0 +1,289 @@ +#include "miniprojecttargetselector.h" + +#include <utils/qtcassert.h> +#include <utils/styledbar.h> +#include <utils/stylehelper.h> + +#include <coreplugin/icore.h> +#include <coreplugin/mainwindow.h> + +#include <projectexplorer/projectexplorer.h> +#include <projectexplorer/session.h> +#include <projectexplorer/project.h> +#include <projectexplorer/runconfiguration.h> +#include <projectexplorer/buildconfiguration.h> + +#include <QtGui/QLayout> +#include <QtGui/QFormLayout> +#include <QtGui/QLabel> +#include <QtGui/QComboBox> +#include <QtGui/QListWidget> +#include <QtGui/QStatusBar> +#include <QtGui/QStackedWidget> + +#include <QDebug> + +using namespace ProjectExplorer; +using namespace ProjectExplorer::Internal; + +MiniTargetWidget::MiniTargetWidget(Project *project, QWidget *parent) : + QWidget(parent), m_project(project) +{ + m_buildComboBox = new QComboBox; + m_buildComboBox->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Preferred); + m_runComboBox = new QComboBox; + m_runComboBox->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Preferred); + + int fontSize = font().pointSize(); + setStyleSheet(QString("QWidget { font-size: %1pt; color: white; } " + "QLabel#targetName { font-size: %2pt; font-weight: bold; } " + "QComboBox { background-color: transparent; margin: 0; border: none; } " + "QComboBox QWidget { background-color: %3 } " + "QComboBox::drop-down { border: none; }" + "QComboBox::down-arrow { image: url(:/welcome/images/combobox_arrow.png); } " + ).arg(fontSize-1).arg(fontSize).arg(Utils::StyleHelper::baseColor().name())); + + QGridLayout *gridLayout = new QGridLayout(this); + + m_targetName = new QLabel(tr("Target")); + m_targetName->setObjectName(QLatin1String("targetName")); + m_targetIcon = new QLabel(); + m_targetIcon->setPixmap(style()->standardIcon(QStyle::SP_ComputerIcon).pixmap(48, 48)); + + Q_FOREACH(BuildConfiguration* bc, project->buildConfigurations()) + addBuildConfiguration(bc); + + Q_FOREACH(RunConfiguration* rc, project->runConfigurations()) + addRunConfiguration(rc); + + connect(project, SIGNAL(addedBuildConfiguration(ProjectExplorer::BuildConfiguration*)), + SLOT(addBuildConfiguration(ProjectExplorer::BuildConfiguration*))); + connect(project, SIGNAL(removedBuildConfiguration(ProjectExplorer::BuildConfiguration*)), + SLOT(addBuildConfiguration(ProjectExplorer::BuildConfiguration*))); + + connect(project, SIGNAL(addedRunConfiguration(ProjectExplorer::RunConfiguration*)), + SLOT(addRunConfiguration(ProjectExplorer::RunConfiguration*))); + connect(project, SIGNAL(removedRunConfiguration(ProjectExplorer::RunConfiguration*)), + SLOT(removeRunConfiguration(ProjectExplorer::RunConfiguration*))); + + connect(m_buildComboBox, SIGNAL(currentIndexChanged(int)), SLOT(setActiveBuildConfiguration(int))); + connect(m_runComboBox, SIGNAL(currentIndexChanged(int)), SLOT(setActiveRunConfiguration(int))); + + connect(project, SIGNAL(activeBuildConfigurationChanged()), SLOT(setActiveBuildConfiguration())); + connect(project, SIGNAL(activeRunConfigurationChanged()), SLOT(setActiveRunConfiguration())); + + QHBoxLayout *runHelperLayout = new QHBoxLayout; + runHelperLayout->setMargin(0); + runHelperLayout->setSpacing(0); + QHBoxLayout *buildHelperLayout = new QHBoxLayout; + buildHelperLayout->setMargin(0); + buildHelperLayout->setSpacing(0); + + buildHelperLayout->addWidget(m_buildComboBox); + runHelperLayout->addWidget(m_runComboBox); + + QFormLayout *formLayout = new QFormLayout; + QLabel *lbl = new QLabel(tr("Build:")); + lbl->setIndent(6); + formLayout->addRow(lbl, buildHelperLayout); + lbl = new QLabel(tr("Run:")); + lbl->setIndent(6); + formLayout->addRow(lbl, runHelperLayout); + + gridLayout->addWidget(m_targetName, 0, 0); + gridLayout->addWidget(m_targetIcon, 0, 1, 2, 1, Qt::AlignTop|Qt::AlignHCenter); + gridLayout->addLayout(formLayout, 1, 0); +} + +void MiniTargetWidget::setActiveBuildConfiguration(int index) +{ + ProjectExplorer::BuildConfiguration* bc = + m_buildComboBox->itemData(index).value<ProjectExplorer::BuildConfiguration*>(); + m_project->setActiveBuildConfiguration(bc); + emit activeBuildConfigurationChanged(bc); +} + +void MiniTargetWidget::setActiveRunConfiguration(int index) +{ + m_project->setActiveRunConfiguration( + m_runComboBox->itemData(index).value<ProjectExplorer::RunConfiguration*>()); +} +void MiniTargetWidget::setActiveBuildConfiguration() +{ + m_buildComboBox->setCurrentIndex(m_buildComboBox->findData( + QVariant::fromValue(m_project->activeBuildConfiguration()))); +} + +void MiniTargetWidget::setActiveRunConfiguration() +{ + m_runComboBox->setCurrentIndex(m_runComboBox->findData( + QVariant::fromValue(m_project->activeRunConfiguration()))); +} + +void MiniTargetWidget::addRunConfiguration(ProjectExplorer::RunConfiguration* runConfig) +{ + connect(runConfig, SIGNAL(displayNameChanged()), SLOT(updateDisplayName())); + m_runComboBox->addItem(runConfig->displayName(), QVariant::fromValue(runConfig)); + if (m_project->activeRunConfiguration() == runConfig) + m_runComboBox->setCurrentIndex(m_runComboBox->count()-1); +} + +void MiniTargetWidget::removeRunConfiguration(ProjectExplorer::RunConfiguration* runConfig) +{ + m_runComboBox->removeItem(m_runComboBox->findData(QVariant::fromValue(runConfig))); +} + +void MiniTargetWidget::addBuildConfiguration(ProjectExplorer::BuildConfiguration* buildConfig) +{ + connect(buildConfig, SIGNAL(displayNameChanged()), SLOT(updateDisplayName())); + m_buildComboBox->addItem(buildConfig->displayName(), QVariant::fromValue(buildConfig)); + if (m_project->activeBuildConfiguration() == buildConfig) + m_buildComboBox->setCurrentIndex(m_buildComboBox->count()-1); +} + +void MiniTargetWidget::removeBuildConfiguration(ProjectExplorer::BuildConfiguration* buildConfig) +{ + m_buildComboBox->removeItem(m_buildComboBox->findData(QVariant::fromValue(buildConfig))); +} + +void MiniTargetWidget::updateDisplayName() +{ + QObject *obj = sender(); + if (RunConfiguration* runConfig = qobject_cast<RunConfiguration*>(obj)) + { + m_runComboBox->setItemText(m_runComboBox->findData(QVariant::fromValue(runConfig)), + runConfig->displayName()); + } else if (BuildConfiguration* buildConfig = qobject_cast<BuildConfiguration*>(obj)) + { + m_buildComboBox->setItemText(m_buildComboBox->findData(QVariant::fromValue(buildConfig)), + buildConfig->displayName()); + } +} + + +MiniProjectTargetSelector::MiniProjectTargetSelector(QAction *targetSelectorAction, QWidget *parent) : + QWidget(parent), m_projectAction(targetSelectorAction) +{ + setWindowFlags(Qt::Popup); + setFocusPolicy(Qt::NoFocus); + + targetSelectorAction->setIcon(style()->standardIcon(QStyle::SP_ComputerIcon)); + targetSelectorAction->setProperty("titledAction", true); + + QVBoxLayout *layout = new QVBoxLayout(this); + layout->setMargin(0); + layout->setSpacing(0); + + Utils::StyledBar *bar = new Utils::StyledBar; + bar->setSingleRow(true); + layout->addWidget(bar); + QHBoxLayout *toolLayout = new QHBoxLayout(bar); + toolLayout->setMargin(0); + toolLayout->setSpacing(0); + + QLabel *lbl = new QLabel(tr("Project")); + lbl->setIndent(6); + QFont f = lbl->font(); + f.setBold(true); + lbl->setFont(f); + m_projectsBox = new QComboBox; + m_projectsBox->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Preferred); + m_projectsBox->setMaximumWidth(200); + + toolLayout->addWidget(lbl); + toolLayout->addWidget(new Utils::StyledSeparator); + toolLayout->addWidget(m_projectsBox); + + m_widgetStack = new QStackedWidget; + m_widgetStack->setFocusPolicy(Qt::NoFocus); + layout->addWidget(m_widgetStack); + + connect(m_projectsBox, SIGNAL(activated(int)), this, SLOT(emitStartupProjectChanged(int))); +} + +void MiniProjectTargetSelector::setVisible(bool visible) +{ + if (visible) { + resize(sizeHint()); + QStatusBar *statusBar = Core::ICore::instance()->statusBar(); + QPoint moveTo = statusBar->mapToGlobal(QPoint(0,0)); + moveTo -= QPoint(0, sizeHint().height()); + move(moveTo); + } + QWidget::setVisible(visible); +} + +void MiniProjectTargetSelector::addProject(ProjectExplorer::Project* project) +{ + QTC_ASSERT(project, return); + ProjectListWidget *targetList = new ProjectListWidget(project); + targetList->setStyleSheet(QString("QListWidget { background: %1; border: none; }") + .arg(Utils::StyleHelper::baseColor().name())); + int pos = m_widgetStack->addWidget(targetList); + + m_projectsBox->addItem(project->displayName(), QVariant::fromValue(project)); + + QListWidgetItem *lwi = new QListWidgetItem(); + targetList->addItem(lwi); + MiniTargetWidget *targetWidget = new MiniTargetWidget(project); + targetWidget->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Preferred); + // width==0 size hint to avoid horizontal scrolling in list widget + lwi->setSizeHint(QSize(0, targetWidget->sizeHint().height())); + targetList->setItemWidget(lwi, targetWidget); + targetList->setCurrentItem(lwi); + + connect(project, SIGNAL(activeBuildConfigurationChanged()), SLOT(updateAction())); + + if (project == ProjectExplorerPlugin::instance()->startupProject()) { + m_projectsBox->setCurrentIndex(pos); + m_widgetStack->setCurrentIndex(pos); + } +} + +void MiniProjectTargetSelector::removeProject(ProjectExplorer::Project* project) +{ + for (int i = 0; i < m_widgetStack->count(); ++i) { + ProjectListWidget *plw = qobject_cast<ProjectListWidget*>(m_widgetStack->widget(i)); + if (plw && plw->project() == project) { + m_projectsBox->removeItem(i); + delete plw; + } + } +} + + +void MiniProjectTargetSelector::updateAction() +{ + Project *project = ProjectExplorerPlugin::instance()->startupProject(); + + QString projectName = tr("No Project"); + QString buildConfig = tr("None"); + + if (project) { + projectName = project->displayName(); + if (BuildConfiguration* bc = project->activeBuildConfiguration()) + buildConfig = bc->displayName(); + } + m_projectAction->setProperty("heading", projectName); + m_projectAction->setProperty("subtitle", buildConfig); + m_projectAction->setIcon(m_projectAction->icon()); // HACK TO FORCE UPDATE +} + +void MiniProjectTargetSelector::emitStartupProjectChanged(int index) +{ + Project *project = m_projectsBox->itemData(index).value<Project*>(); + QTC_ASSERT(project, return;) + emit startupProjectChanged(project); +} + +void MiniProjectTargetSelector::changeStartupProject(ProjectExplorer::Project *project) +{ + for (int i = 0; i < m_widgetStack->count(); ++i) { + ProjectListWidget *plw = qobject_cast<ProjectListWidget*>(m_widgetStack->widget(i)); + if (plw && plw->project() == project) { + m_projectsBox->setCurrentIndex(i); + m_widgetStack->setCurrentIndex(i); + } + } + updateAction(); +} diff --git a/src/plugins/projectexplorer/miniprojecttargetselector.h b/src/plugins/projectexplorer/miniprojecttargetselector.h new file mode 100644 index 00000000000..14f2dcd4c2b --- /dev/null +++ b/src/plugins/projectexplorer/miniprojecttargetselector.h @@ -0,0 +1,102 @@ +#ifndef MINIPROJECTTARGETSELECTOR_H +#define MINIPROJECTTARGETSELECTOR_H + +#include <QtGui/QListWidget> + + +QT_BEGIN_NAMESPACE +class QComboBox; +class QLabel; +class QStackedWidget; +QT_END_NAMESPACE + +namespace ProjectExplorer { +class Project; +class RunConfiguration; +class BuildConfiguration; + +namespace Internal { + +// helper classes + +class ProjectListWidget : public QListWidget +{ + Q_OBJECT +private: + ProjectExplorer::Project* m_project; + +public: + ProjectListWidget(ProjectExplorer::Project *project, QWidget *parent = 0) + : QListWidget(parent), m_project(project) + { + setFocusPolicy(Qt::NoFocus); + setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + } + + ProjectExplorer::Project *project() const + { + return m_project; + } + +}; + +class MiniTargetWidget : public QWidget +{ + Q_OBJECT +public: + // TODO: Pass target instead of project + MiniTargetWidget(Project *project, QWidget *parent = 0); + + +private slots: + void addRunConfiguration(ProjectExplorer::RunConfiguration *runConfig); + void removeRunConfiguration(ProjectExplorer::RunConfiguration *buildConfig); + void addBuildConfiguration(ProjectExplorer::BuildConfiguration *buildConfig); + void removeBuildConfiguration(ProjectExplorer::BuildConfiguration *buildConfig); + + void setActiveBuildConfiguration(int index); + void setActiveRunConfiguration(int index); + void setActiveBuildConfiguration(); + void setActiveRunConfiguration(); + + void updateDisplayName(); + +signals: + void activeBuildConfigurationChanged(ProjectExplorer::BuildConfiguration *buildConfig); + +private: + QLabel *m_targetName; + QLabel *m_targetIcon; + QComboBox *m_runComboBox; + QComboBox *m_buildComboBox; + ProjectExplorer::Project* m_project; +}; + +// main class + +class MiniProjectTargetSelector : public QWidget +{ + Q_OBJECT +public: + MiniProjectTargetSelector(QAction *projectAction,QWidget *parent = 0); + void setVisible(bool visible); + +signals: + void startupProjectChanged(ProjectExplorer::Project *project); + +private slots: + void addProject(ProjectExplorer::Project *project); + void removeProject(ProjectExplorer::Project *project); + void emitStartupProjectChanged(int index); + void changeStartupProject(ProjectExplorer::Project *project); + void updateAction(); + +private: + QAction *m_projectAction; + QComboBox *m_projectsBox; + QStackedWidget *m_widgetStack; +}; + +}; +}; +#endif // MINIPROJECTTARGETSELECTOR_H diff --git a/src/plugins/projectexplorer/project.h b/src/plugins/projectexplorer/project.h index 2923289ec75..2f18c82cb21 100644 --- a/src/plugins/projectexplorer/project.h +++ b/src/plugins/projectexplorer/project.h @@ -168,4 +168,6 @@ private: } // namespace ProjectExplorer +Q_DECLARE_METATYPE(ProjectExplorer::Project *) + #endif // PROJECT_H diff --git a/src/plugins/projectexplorer/projectexplorer.cpp b/src/plugins/projectexplorer/projectexplorer.cpp index 30b12e4cc3f..b08fda8cbcb 100644 --- a/src/plugins/projectexplorer/projectexplorer.cpp +++ b/src/plugins/projectexplorer/projectexplorer.cpp @@ -62,6 +62,7 @@ #include "projectwelcomepagewidget.h" #include "corelistenercheckingforrunningbuild.h" #include "buildconfiguration.h" +#include "miniprojecttargetselector.h" #include <coreplugin/basemode.h> #include <coreplugin/coreconstants.h> @@ -147,6 +148,7 @@ struct ProjectExplorerPluginPrivate { QAction *m_openTerminalHere; QAction *m_removeFileAction; QAction *m_renameFileAction; + QAction *m_projectSelectorAction; QMenu *m_buildConfigurationMenu; QActionGroup *m_buildConfigurationActionGroup; @@ -174,6 +176,7 @@ struct ProjectExplorerPluginPrivate { RunControl *m_debuggingRunControl; QString m_runMode; QString m_projectFilterString; + Internal::MiniProjectTargetSelector * m_targetSelector; Internal::ProjectExplorerSettings m_projectExplorerSettings; Internal::ProjectWelcomePage *m_welcomePlugin; Internal::ProjectWelcomePageWidget *m_welcomePage; @@ -697,6 +700,24 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er d->m_renameFileAction->setEnabled(false); d->m_renameFileAction->setVisible(false); + // target selector + d->m_projectSelectorAction = new QAction(this); + d->m_projectSelectorAction->setEnabled(false); + QWidget *mainWindow = Core::ICore::instance()->mainWindow(); + d->m_targetSelector = new Internal::MiniProjectTargetSelector(d->m_projectSelectorAction, mainWindow); + connect(d->m_projectSelectorAction, SIGNAL(triggered()), d->m_targetSelector, SLOT(show())); + modeManager->addProjectSelector(d->m_projectSelectorAction); + + + connect(d->m_session, SIGNAL(projectAdded(ProjectExplorer::Project*)), + d->m_targetSelector, SLOT(addProject(ProjectExplorer::Project*))); + connect(d->m_session, SIGNAL(projectRemoved(ProjectExplorer::Project*)), + d->m_targetSelector, SLOT(removeProject(ProjectExplorer::Project*))); + connect(d->m_targetSelector, SIGNAL(startupProjectChanged(ProjectExplorer::Project*)), + this, SLOT(setStartupProject(ProjectExplorer::Project*))); + connect(d->m_session, SIGNAL(startupProjectChanged(ProjectExplorer::Project*)), + d->m_targetSelector, SLOT(changeStartupProject(ProjectExplorer::Project*))); + connect(core, SIGNAL(saveSettingsRequested()), this, SLOT(savePersistentSettings())); @@ -1268,7 +1289,7 @@ void ProjectExplorerPlugin::startRunControl(RunControl *runControl, const QStrin d->m_debuggingRunControl = runControl; runControl->start(); - updateRunAction(); + updateToolBarActions(); } void ProjectExplorerPlugin::buildQueueFinished(bool success) @@ -1373,7 +1394,7 @@ void ProjectExplorerPlugin::updateActions() d->m_cleanSessionAction->setEnabled(hasProjects && !building); d->m_cancelBuildAction->setEnabled(building); - updateRunAction(); + updateToolBarActions(); } // NBS TODO check projectOrder() @@ -1568,7 +1589,7 @@ void ProjectExplorerPlugin::runProjectImpl(Project *pro, QString mode) configurations << pro->activeBuildConfiguration(); d->m_buildManager->buildProjects(configurations); - updateRunAction(); + updateToolBarActions(); } } else { // TODO this ignores RunConfiguration::isEnabled() @@ -1631,7 +1652,7 @@ void ProjectExplorerPlugin::runControlFinished() if (sender() == d->m_debuggingRunControl) d->m_debuggingRunControl = 0; - updateRunAction(); + updateToolBarActions(); } void ProjectExplorerPlugin::startupProjectChanged() @@ -1643,17 +1664,17 @@ void ProjectExplorerPlugin::startupProjectChanged() if (previousStartupProject) { disconnect(previousStartupProject, SIGNAL(activeRunConfigurationChanged()), - this, SLOT(updateRunAction())); + this, SLOT(updateToolBarActions())); } previousStartupProject = project; if (project) { connect(project, SIGNAL(activeRunConfigurationChanged()), - this, SLOT(updateRunAction())); + this, SLOT(updateToolBarActions())); } - updateRunAction(); + updateToolBarActions(); } // NBS TODO implement more than one runner @@ -1667,7 +1688,7 @@ IRunControlFactory *ProjectExplorerPlugin::findRunControlFactory(RunConfiguratio return 0; } -void ProjectExplorerPlugin::updateRunAction() +void ProjectExplorerPlugin::updateToolBarActions() { const Project *project = startupProject(); bool canRun = project && findRunControlFactory(project->activeRunConfiguration(), ProjectExplorer::Constants::RUNMODE); @@ -1679,6 +1700,9 @@ void ProjectExplorerPlugin::updateRunAction() d->m_runActionContextMenu->setEnabled(canRun && !building); d->m_debugAction->setEnabled(canDebug && !building); + + d->m_projectSelectorAction->setEnabled(!session()->projects().isEmpty()); + } void ProjectExplorerPlugin::cancelBuild() diff --git a/src/plugins/projectexplorer/projectexplorer.h b/src/plugins/projectexplorer/projectexplorer.h index c44fa2b38b9..c4d647986a3 100644 --- a/src/plugins/projectexplorer/projectexplorer.h +++ b/src/plugins/projectexplorer/projectexplorer.h @@ -116,7 +116,6 @@ public: void setCurrentNode(Node *node); Project *startupProject() const; - void setStartupProject(ProjectExplorer::Project *project = 0); BuildManager *buildManager() const; @@ -148,6 +147,9 @@ signals: void settingsChanged(); +public slots: + void setStartupProject(ProjectExplorer::Project *project = 0); + private slots: void buildStateChanged(ProjectExplorer::Project * pro); void buildQueueFinished(bool success); @@ -205,7 +207,7 @@ private slots: void runControlFinished(); void startupProjectChanged(); // Calls updateRunAction - void updateRunAction(); + void updateToolBarActions(); void addToApplicationOutputWindow(RunControl *, const QString &line); void addToApplicationOutputWindowInline(RunControl *, const QString &line); diff --git a/src/plugins/projectexplorer/projectexplorer.pro b/src/plugins/projectexplorer/projectexplorer.pro index d752fb82443..864b66f7ceb 100644 --- a/src/plugins/projectexplorer/projectexplorer.pro +++ b/src/plugins/projectexplorer/projectexplorer.pro @@ -67,6 +67,7 @@ HEADERS += projectexplorer.h \ projectwelcomepage.h \ projectwelcomepagewidget.h \ baseprojectwizarddialog.h \ + miniprojecttargetselector.h \ targetselector.h \ targetsettingswidget.h \ doubletabwidget.h @@ -124,6 +125,7 @@ SOURCES += projectexplorer.cpp \ projectwelcomepagewidget.cpp \ corelistenercheckingforrunningbuild.cpp \ baseprojectwizarddialog.cpp \ + miniprojecttargetselector.cpp \ targetselector.cpp \ targetsettingswidget.cpp \ doubletabwidget.cpp -- GitLab