projectwindow.cpp 10.4 KB
Newer Older
1
/**************************************************************************
con's avatar
con committed
2 3 4
**
** This file is part of Qt Creator
**
5
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
con's avatar
con committed
6
**
7
** Contact: Nokia Corporation (qt-info@nokia.com)
con's avatar
con committed
8
**
9
** Commercial Usage
10
**
11 12 13 14
** 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.
15
**
16
** GNU Lesser General Public License Usage
17
**
18 19 20 21 22 23
** 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.
24
**
25
** If you are unsure which license is appropriate for your use, please
hjk's avatar
hjk committed
26
** contact the sales department at http://qt.nokia.com/contact.
con's avatar
con committed
27
**
28
**************************************************************************/
hjk's avatar
hjk committed
29

con's avatar
con committed
30
#include "projectwindow.h"
hjk's avatar
hjk committed
31

con's avatar
con committed
32 33
#include "doubletabwidget.h"

hjk's avatar
hjk committed
34
#include "project.h"
35
#include "environment.h"
con's avatar
con committed
36 37 38 39
#include "projectexplorer.h"
#include "projectexplorerconstants.h"
#include "iprojectproperties.h"
#include "session.h"
Tobias Hunger's avatar
Tobias Hunger committed
40
#include "target.h"
con's avatar
con committed
41
#include "projecttreewidget.h"
dt's avatar
dt committed
42
#include "runconfiguration.h"
43
#include "buildconfiguration.h"
Tobias Hunger's avatar
Tobias Hunger committed
44 45 46
#include "buildsettingspropertiespage.h"
#include "runsettingspropertiespage.h"
#include "targetsettingspanel.h"
con's avatar
con committed
47 48 49 50

#include <coreplugin/minisplitter.h>
#include <coreplugin/fileiconprovider.h>
#include <coreplugin/icore.h>
51
#include <coreplugin/ifile.h>
52
#include <extensionsystem/pluginmanager.h>
Tobias Hunger's avatar
Tobias Hunger committed
53
#include <utils/qtcassert.h>
con's avatar
con committed
54
#include <utils/styledbar.h>
55
#include <utils/stylehelper.h>
con's avatar
con committed
56

57
#include <QtGui/QApplication>
con's avatar
con committed
58 59
#include <QtGui/QBoxLayout>
#include <QtGui/QComboBox>
60
#include <QtGui/QScrollArea>
dt's avatar
dt committed
61
#include <QtGui/QLabel>
dt's avatar
dt committed
62 63
#include <QtGui/QPainter>
#include <QtGui/QPaintEvent>
64 65
#include <QtGui/QMenu>

con's avatar
con committed
66 67 68 69
using namespace ProjectExplorer;
using namespace ProjectExplorer::Internal;

namespace {
Tobias Hunger's avatar
Tobias Hunger committed
70
const int ICON_SIZE(64);
Tobias Hunger's avatar
Tobias Hunger committed
71 72 73 74

const int ABOVE_HEADING_MARGIN(10);
const int ABOVE_CONTENTS_MARGIN(4);
const int BELOW_CONTENTS_MARGIN(16);
Tobias Hunger's avatar
Tobias Hunger committed
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94

bool skipPanelFactory(Project *project, IPanelFactory *factory)
{
    bool simplifyTargets(project->supportedTargetIds().count() <= 1);
    if (simplifyTargets) {
        // Do not show the targets list:
        if (factory->id() == QLatin1String(TARGETSETTINGS_PANEL_ID))
            return true;
        // Skip build settigns if none are available anyway:
        if (project->activeTarget() &&
            !project->activeTarget()->buildConfigurationFactory() &&
            factory->id() == QLatin1String(BUILDSETTINGS_PANEL_ID))
            return true;
    } else {
        // Skip panels embedded into the targets panel:
        if (factory->id() == QLatin1String(BUILDSETTINGS_PANEL_ID) ||
            factory->id() == QLatin1String(RUNSETTINGS_PANEL_ID))
            return true;
    }
    return false;
con's avatar
con committed
95 96
}

Tobias Hunger's avatar
Tobias Hunger committed
97 98
} // namespace

99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114
///
// OnePixelBlackLine
///

class OnePixelBlackLine : public QWidget
{
public:
    OnePixelBlackLine(QWidget *parent)
        : QWidget(parent)
    {
        setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
        setMinimumHeight(1);
        setMaximumHeight(1);
    }
    void paintEvent(QPaintEvent *e)
    {
Tobias Hunger's avatar
Tobias Hunger committed
115
        Q_UNUSED(e);
116
        QPainter p(this);
Tobias Hunger's avatar
Tobias Hunger committed
117
        p.fillRect(contentsRect(), QBrush(Utils::StyleHelper::borderColor()));
118 119 120 121 122 123 124
    }
};

///
// PanelsWidget
///

Tobias Hunger's avatar
Tobias Hunger committed
125 126 127
PanelsWidget::PanelsWidget(QWidget *parent) :
    QScrollArea(parent),
    m_root(new QWidget(this))
dt's avatar
dt committed
128
{
129
    // We want a 900px wide widget with and the scrollbar at the
Tobias Hunger's avatar
Tobias Hunger committed
130
    // side of the screen.
131
    m_root->setFixedWidth(900);
Tobias Hunger's avatar
Tobias Hunger committed
132
    // The layout holding the individual panels:
Tobias Hunger's avatar
Tobias Hunger committed
133 134 135
    m_layout = new QGridLayout(m_root);
    m_layout->setColumnMinimumWidth(0, ICON_SIZE + 4);
    m_layout->setSpacing(0);
Tobias Hunger's avatar
Tobias Hunger committed
136

137
    setWidget(m_root);
dt's avatar
dt committed
138
    setFrameStyle(QFrame::NoFrame);
dt's avatar
dt committed
139
    setWidgetResizable(true);
dt's avatar
dt committed
140 141 142 143
}

PanelsWidget::~PanelsWidget()
{
con's avatar
con committed
144
    qDeleteAll(m_panels);
dt's avatar
dt committed
145 146
}

Tobias Hunger's avatar
Tobias Hunger committed
147 148 149 150 151
/*
 * Add a widget with heading information into the grid
 * layout of the PanelsWidget.
 *
 *     ...
Tobias Hunger's avatar
Tobias Hunger committed
152
 * +--------+-------------------------------------------+ ABOVE_HEADING_MARGIN
Tobias Hunger's avatar
Tobias Hunger committed
153 154
 * | icon   | name                                      |
 * +        +-------------------------------------------+
Tobias Hunger's avatar
Tobias Hunger committed
155 156 157 158
 * |        | line                                      |
 * +--------+-------------------------------------------+ ABOVE_CONTENTS_MARGIN
 * |          widget (with contentsmargins adjusted!)   |
 * +--------+-------------------------------------------+ BELOW_CONTENTS_MARGIN
Tobias Hunger's avatar
Tobias Hunger committed
159
 */
con's avatar
con committed
160
void PanelsWidget::addPropertiesPanel(IPropertiesPanel *panel)
dt's avatar
dt committed
161
{
con's avatar
con committed
162
    QTC_ASSERT(panel, return);
Tobias Hunger's avatar
Tobias Hunger committed
163

Tobias Hunger's avatar
Tobias Hunger committed
164 165 166
    const int headerRow(m_layout->rowCount() - 1);
    m_layout->setRowStretch(headerRow, 0);

Tobias Hunger's avatar
Tobias Hunger committed
167
    // icon:
con's avatar
con committed
168 169 170 171
    if (!panel->icon().isNull()) {
        QLabel *iconLabel = new QLabel(m_root);
        iconLabel->setPixmap(panel->icon().pixmap(ICON_SIZE, ICON_SIZE));
        iconLabel->setContentsMargins(0, ABOVE_HEADING_MARGIN, 0, 0);
con's avatar
con committed
172
        m_layout->addWidget(iconLabel, headerRow, 0, 3, 1, Qt::AlignTop | Qt::AlignHCenter);
Tobias Hunger's avatar
Tobias Hunger committed
173 174 175
    }

    // name:
con's avatar
con committed
176 177 178 179
    QLabel *nameLabel = new QLabel(m_root);
    nameLabel->setText(panel->displayName());
    nameLabel->setContentsMargins(0, ABOVE_HEADING_MARGIN, 0, 0);
    QFont f = nameLabel->font();
dt's avatar
dt committed
180
    f.setBold(true);
con's avatar
con committed
181
    f.setPointSizeF(f.pointSizeF() * 1.6);
con's avatar
con committed
182
    nameLabel->setFont(f);
con's avatar
con committed
183
    m_layout->addWidget(nameLabel, headerRow, 1, 1, 1, Qt::AlignVCenter | Qt::AlignLeft);
Tobias Hunger's avatar
Tobias Hunger committed
184 185 186

    // line:
    const int lineRow(headerRow + 1);
con's avatar
con committed
187 188
    QWidget *line = new OnePixelBlackLine(m_root);
    m_layout->addWidget(line, lineRow, 1, 1, -1, Qt::AlignTop);
Tobias Hunger's avatar
Tobias Hunger committed
189

Tobias Hunger's avatar
Tobias Hunger committed
190
    // add the widget:
Tobias Hunger's avatar
Tobias Hunger committed
191
    const int widgetRow(lineRow + 1);
con's avatar
con committed
192
    addPanelWidget(panel, widgetRow);
dt's avatar
dt committed
193 194
}

con's avatar
con committed
195
void PanelsWidget::addPanelWidget(IPropertiesPanel *panel, int row)
Tobias Hunger's avatar
Tobias Hunger committed
196
{
con's avatar
con committed
197
    QWidget *widget = panel->widget();
Tobias Hunger's avatar
Tobias Hunger committed
198 199 200 201 202
    int leftMargin = (panel->flags() & IPropertiesPanel::NoLeftMargin)
                     ? 0 : Constants::PANEL_LEFT_MARGIN;
    widget->setContentsMargins(leftMargin,
                               ABOVE_CONTENTS_MARGIN, 0,
                               BELOW_CONTENTS_MARGIN);
con's avatar
con committed
203 204
    widget->setParent(m_root);
    m_layout->addWidget(widget, row, 0, 1, 2);
Tobias Hunger's avatar
Tobias Hunger committed
205 206 207 208 209 210 211

    const int stretchRow(row + 1);
    m_layout->setRowStretch(stretchRow, 10);

    m_panels.append(panel);
}

dt's avatar
dt committed
212 213 214 215
///
// ProjectWindow
///

dt's avatar
dt committed
216
ProjectWindow::ProjectWindow(QWidget *parent)
con's avatar
con committed
217
    : QWidget(parent),
Tobias Hunger's avatar
Tobias Hunger committed
218 219
    m_currentWidget(0),
    m_currentPanel(0)
con's avatar
con committed
220
{
221
    ProjectExplorer::SessionManager *session = ProjectExplorerPlugin::instance()->session();
con's avatar
con committed
222

Tobias Hunger's avatar
Tobias Hunger committed
223 224 225 226
    // Setup overall layout:
    QVBoxLayout *viewLayout = new QVBoxLayout(this);
    viewLayout->setMargin(0);
    viewLayout->setSpacing(0);
dt's avatar
dt committed
227

con's avatar
con committed
228 229 230
    m_tabWidget = new DoubleTabWidget(this);
    m_tabWidget->setTitle(tr("Select a Project:"));
    viewLayout->addWidget(m_tabWidget);
231

Tobias Hunger's avatar
Tobias Hunger committed
232
    // Setup our container for the contents:
con's avatar
con committed
233 234
    m_centralWidget = new QStackedWidget(this);
    viewLayout->addWidget(m_centralWidget);
Tobias Hunger's avatar
Tobias Hunger committed
235 236

    // connects:
con's avatar
con committed
237 238
    connect(m_tabWidget, SIGNAL(currentIndexChanged(int,int)),
            this, SLOT(showProperties(int,int)));
dt's avatar
dt committed
239

240 241 242 243
    connect(session, SIGNAL(sessionLoaded()), this, SLOT(restoreStatus()));
    connect(session, SIGNAL(aboutToSaveSession()), this, SLOT(saveStatus()));

    connect(session, SIGNAL(projectAdded(ProjectExplorer::Project*)),
con's avatar
con committed
244 245 246
            this, SLOT(projectAdded(ProjectExplorer::Project*)));
    connect(session, SIGNAL(aboutToRemoveProject(ProjectExplorer::Project*)),
            this, SLOT(aboutToRemoveProject(ProjectExplorer::Project*)));
247 248

    // Update properties to empty project for now:
con's avatar
con committed
249
    showProperties(-1, -1);
con's avatar
con committed
250 251 252 253 254 255
}

ProjectWindow::~ProjectWindow()
{
}

con's avatar
con committed
256
void ProjectWindow::shutdown()
257
{
con's avatar
con committed
258 259 260
    showProperties(-1, -1); // TODO that's a bit stupid, but otherwise stuff is still
                             // connected to the session
    disconnect(ProjectExplorerPlugin::instance()->session(), 0, this, 0);
261 262
}

con's avatar
con committed
263
void ProjectWindow::projectAdded(ProjectExplorer::Project *project)
264
{
con's avatar
con committed
265 266
    QList<Project *> projects = ProjectExplorerPlugin::instance()->session()->projects();
    int index = projects.indexOf(project);
Tobias Hunger's avatar
Tobias Hunger committed
267 268 269
    if (index < 0)
        return;

con's avatar
con committed
270 271
    QStringList subtabs;
    foreach (IPanelFactory *panelFactory, ExtensionSystem::PluginManager::instance()->getObjects<IPanelFactory>()) {
Tobias Hunger's avatar
Tobias Hunger committed
272 273 274
        if (skipPanelFactory(project, panelFactory))
            continue;
        subtabs << panelFactory->displayName();
275
    }
Tobias Hunger's avatar
Tobias Hunger committed
276

con's avatar
con committed
277 278 279 280 281 282 283 284 285
    m_tabIndexToProject.insert(index, project);
    m_tabWidget->insertTab(index, project->displayName(), subtabs);
}

void ProjectWindow::aboutToRemoveProject(ProjectExplorer::Project *project)
{
    int index = m_tabIndexToProject.indexOf(project);
    m_tabIndexToProject.removeAt(index);
    m_tabWidget->removeTab(index);
286 287
}

con's avatar
con committed
288 289
void ProjectWindow::restoreStatus()
{
dt's avatar
dt committed
290
    // TODO
con's avatar
con committed
291 292 293 294
}

void ProjectWindow::saveStatus()
{
dt's avatar
dt committed
295
    // TODO
con's avatar
con committed
296 297
}

con's avatar
con committed
298
void ProjectWindow::showProperties(int index, int subIndex)
con's avatar
con committed
299
{
300
    if (index < 0 || index >= m_tabIndexToProject.count())
con's avatar
con committed
301
        return;
302

con's avatar
con committed
303
    Project *project = m_tabIndexToProject.at(index);
dt's avatar
dt committed
304

305
    // Set up custom panels again:
Tobias Hunger's avatar
Tobias Hunger committed
306 307 308 309 310 311 312 313 314 315 316 317
    int pos = 0;
    foreach (IPanelFactory *panelFactory, ExtensionSystem::PluginManager::instance()->getObjects<IPanelFactory>()) {
        if (skipPanelFactory(project, panelFactory))
            continue;
        if (pos == subIndex) {
            removeCurrentWidget();
            IPropertiesPanel *panel(panelFactory->createPanel(project));
            if (panel->flags() & IPropertiesPanel::NoAutomaticStyle) {
                m_currentWidget = panel->widget();
                m_currentPanel = panel;
            } else {
                PanelsWidget *panelsWidget = new PanelsWidget(m_centralWidget);
con's avatar
con committed
318
                panelsWidget->addPropertiesPanel(panel);
Tobias Hunger's avatar
Tobias Hunger committed
319
                m_currentWidget = panelsWidget;
con's avatar
con committed
320
            }
Tobias Hunger's avatar
Tobias Hunger committed
321 322 323
            m_centralWidget->addWidget(m_currentWidget);
            m_centralWidget->setCurrentWidget(m_currentWidget);
            break;
con's avatar
con committed
324
        }
Tobias Hunger's avatar
Tobias Hunger committed
325
        ++pos;
con's avatar
con committed
326
    }
Tobias Hunger's avatar
Tobias Hunger committed
327 328 329 330 331 332 333 334 335 336 337 338 339
}

void ProjectWindow::removeCurrentWidget()
{
    if (m_currentWidget) {
        m_centralWidget->removeWidget(m_currentWidget);
        if (m_currentPanel) {
            delete m_currentPanel;
            m_currentPanel = 0;
            m_currentWidget = 0; // is deleted by the panel
        } else if (m_currentWidget) {
            delete m_currentWidget;
            m_currentWidget = 0;
con's avatar
con committed
340 341 342
        }
    }
}