projectwindow.cpp 11.5 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
26
** contact the sales department at http://www.qtsoftware.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 32

#include "project.h"
con's avatar
con committed
33 34 35 36 37 38 39 40 41
#include "projectexplorer.h"
#include "projectexplorerconstants.h"
#include "iprojectproperties.h"
#include "session.h"
#include "projecttreewidget.h"

#include <coreplugin/minisplitter.h>
#include <coreplugin/fileiconprovider.h>
#include <coreplugin/icore.h>
42
#include <extensionsystem/pluginmanager.h>
con's avatar
con committed
43
#include <utils/styledbar.h>
con's avatar
con committed
44 45

#include <QtCore/QDebug>
46
#include <QtGui/QApplication>
con's avatar
con committed
47 48
#include <QtGui/QBoxLayout>
#include <QtGui/QComboBox>
49
#include <QtGui/QScrollArea>
con's avatar
con committed
50 51 52
#include <QtGui/QTabWidget>
#include <QtGui/QTreeWidget>
#include <QtGui/QHeaderView>
dt's avatar
dt committed
53
#include <QtGui/QLabel>
con's avatar
con committed
54 55 56 57 58 59 60 61

using namespace ProjectExplorer;
using namespace ProjectExplorer::Internal;

namespace {
bool debug = false;
}

dt's avatar
dt committed
62 63 64
PanelsWidget::PanelsWidget(QWidget *parent)
    : QScrollArea(parent)
{
con's avatar
con committed
65 66 67 68 69 70 71 72 73 74 75 76
    QWidget *topwidget = new QWidget;
    QHBoxLayout *topwidgetLayout = new QHBoxLayout;
    topwidgetLayout->setMargin(0);
    topwidgetLayout->setSpacing(0);
    topwidget->setLayout(topwidgetLayout);

    QWidget *verticalWidget = new QWidget;
    verticalWidget->setMaximumWidth(800);
    m_layout = new QVBoxLayout;
    verticalWidget->setLayout(m_layout);
    topwidgetLayout->addWidget(verticalWidget);
    topwidgetLayout->addStretch(10);
dt's avatar
dt committed
77 78 79

    setWidgetResizable(true);
    setFrameStyle(QFrame::NoFrame);
con's avatar
con committed
80
    setWidget(topwidget);
dt's avatar
dt committed
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112
}

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();
}

dt's avatar
dt committed
113 114
ProjectWindow::ProjectWindow(QWidget *parent)
    : QWidget(parent), m_currentItemChanged(false)
con's avatar
con committed
115 116 117 118
{
    setWindowTitle(tr("Project Explorer"));
    setWindowIcon(QIcon(":/projectexplorer/images/projectexplorer.png"));

119 120
    m_projectExplorer = ProjectExplorerPlugin::instance();
    m_session = m_projectExplorer->session();
con's avatar
con committed
121 122

    m_treeWidget = new QTreeWidget(this);
dt's avatar
dt committed
123 124
    m_treeWidget->setSelectionMode(QAbstractItemView::SingleSelection);
    m_treeWidget->setSelectionBehavior(QAbstractItemView::SelectRows);
con's avatar
con committed
125 126 127 128 129 130 131 132 133 134
    m_treeWidget->setFrameStyle(QFrame::NoFrame);
    m_treeWidget->setRootIsDecorated(false);
    m_treeWidget->header()->setResizeMode(QHeaderView::ResizeToContents);
    m_treeWidget->setHeaderLabels(QStringList()
                                  << tr("Projects")
                                  << tr("Startup")
                                  << tr("Path")
        );

    connect(m_treeWidget, SIGNAL(itemChanged(QTreeWidgetItem*, int)),
dt's avatar
dt committed
135
            this, SLOT(handleItem(QTreeWidgetItem*, int)));
con's avatar
con committed
136 137 138
    connect(m_treeWidget, SIGNAL(currentItemChanged(QTreeWidgetItem*, QTreeWidgetItem *)),
            this, SLOT(handleCurrentItemChanged(QTreeWidgetItem*)));

dt's avatar
dt committed
139
    m_panelsWidget = new PanelsWidget(this);
con's avatar
con committed
140 141 142 143 144

    QWidget *dummy = new QWidget;
    QVBoxLayout *dummyLayout = new QVBoxLayout(dummy);
    dummyLayout->setMargin(0);
    dummyLayout->setSpacing(0);
con's avatar
con committed
145
    dummyLayout->addWidget(new Core::Utils::StyledBar(dummy));
con's avatar
con committed
146 147 148 149 150
    dummyLayout->addWidget(m_treeWidget);

    QSplitter *splitter = new Core::MiniSplitter;
    splitter->setOrientation(Qt::Vertical);
    splitter->addWidget(dummy);
dt's avatar
dt committed
151
    splitter->addWidget(m_panelsWidget);
con's avatar
con committed
152 153 154 155 156 157 158 159 160 161 162

    // make sure that the tree treewidget has same size policy as qtabwidget
    m_treeWidget->setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred));
    const int treeWidgetMinSize = m_treeWidget->minimumSizeHint().height();
    splitter->setSizes(QList<int>() << treeWidgetMinSize << splitter->height() - treeWidgetMinSize);

    QVBoxLayout *topLayout = new QVBoxLayout(this);
    topLayout->setMargin(0);
    topLayout->setSpacing(0);
    topLayout->addWidget(splitter);

dt's avatar
dt committed
163 164 165 166 167 168 169 170
    connect(m_session, SIGNAL(sessionLoaded()), this, SLOT(restoreStatus()));
    connect(m_session, SIGNAL(aboutToSaveSession()), this, SLOT(saveStatus()));

    connect(m_session, SIGNAL(startupProjectChanged(ProjectExplorer::Project*)), this, SLOT(updateTreeWidgetStatupProjectChanged(ProjectExplorer::Project*)));
    connect(m_session, SIGNAL(projectAdded(ProjectExplorer::Project*)), this, SLOT(updateTreeWidgetProjectAdded(ProjectExplorer::Project*)));
    connect(m_session, SIGNAL(projectRemoved(ProjectExplorer::Project*)), this, SLOT(updateTreeWidgetProjectRemoved(ProjectExplorer::Project*)));
    connect(m_session, SIGNAL(aboutToRemoveProject(ProjectExplorer::Project*)), this, SLOT(updateTreeWidgetAboutToRemoveProject(ProjectExplorer::Project*)));

con's avatar
con committed
171 172 173 174 175 176 177 178
}

ProjectWindow::~ProjectWindow()
{
}

void ProjectWindow::restoreStatus()
{
dt's avatar
dt committed
179 180 181 182
    if (!m_treeWidget->currentItem() && m_treeWidget->topLevelItemCount()) {
        m_treeWidget->setCurrentItem(m_treeWidget->topLevelItem(0), 0, QItemSelectionModel::SelectCurrent | QItemSelectionModel::Rows);
    }

dt's avatar
dt committed
183 184 185 186 187 188 189 190 191 192
    // 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);
con's avatar
con committed
193 194 195 196
}

void ProjectWindow::saveStatus()
{
dt's avatar
dt committed
197 198
    // TODO
//    m_session->setValue(QLatin1String("ProjectWindow/Panel"), m_panelsTabWidget->currentIndex());
con's avatar
con committed
199 200 201 202 203 204 205 206
}

void ProjectWindow::showProperties(ProjectExplorer::Project *project, const QModelIndex & /* subIndex */)
{
    if (debug)
        qDebug() << "ProjectWindow - showProperties called";

    // Remove the tabs from the tab widget first
dt's avatar
dt committed
207
    m_panelsWidget->clear();
con's avatar
con committed
208 209 210 211 212 213 214 215 216

    if (project) {
        QList<IPanelFactory *> pages =
                ExtensionSystem::PluginManager::instance()->getObjects<IPanelFactory>();
        foreach (IPanelFactory *panelFactory, pages) {
            if (panelFactory->supports(project)) {
                PropertiesPanel *panel = panelFactory->createPanel(project);
                if (debug)
                  qDebug() << "ProjectWindow - setting up project properties tab " << panel->name();
dt's avatar
dt committed
217
                m_panelsWidget->addWidget(panel->name(), panel->widget());
con's avatar
con committed
218 219 220 221 222
            }
        }
    }
}

dt's avatar
dt committed
223
void ProjectWindow::updateTreeWidgetStatupProjectChanged(ProjectExplorer::Project *startupProject)
con's avatar
con committed
224
{
dt's avatar
dt committed
225 226 227
    int count = m_treeWidget->topLevelItemCount();
    for (int i = 0; i < count; ++i) {
        QTreeWidgetItem *item = m_treeWidget->topLevelItem(i);
228
        if (Project *project = findProject(item->data(2, Qt::UserRole).toString())) {
dt's avatar
dt committed
229 230 231 232 233
            bool checked = (startupProject == project);
            if (item->checkState(1) != (checked ? Qt::Checked : Qt::Unchecked))
                item->setCheckState(1, checked ? Qt::Checked : Qt::Unchecked);
        } else {
            item->setCheckState(1, Qt::Unchecked);
234 235
        }
    }
dt's avatar
dt committed
236
}
con's avatar
con committed
237

dt's avatar
dt committed
238 239 240 241
void ProjectWindow::updateTreeWidgetProjectAdded(ProjectExplorer::Project *projectAdded)
{
    int position = m_session->projects().indexOf(projectAdded);
    const QFileInfo fileInfo(projectAdded->file()->fileName());
con's avatar
con committed
242

dt's avatar
dt committed
243
    QTreeWidgetItem *item = new QTreeWidgetItem();
244
    item->setText(0, projectAdded->name());
dt's avatar
dt committed
245
    item->setIcon(0, Core::FileIconProvider::instance()->icon(fileInfo));
246 247
    item->setData(2, Qt::UserRole, fileInfo.filePath());
    item->setText(2, QDir::toNativeSeparators(fileInfo.filePath()));
con's avatar
con committed
248

dt's avatar
dt committed
249 250 251 252
    if (projectAdded->isApplication()) {
        bool checked = (m_session->startupProject() == projectAdded);
        item->setCheckState(1, checked ? Qt::Checked : Qt::Unchecked);
    }
con's avatar
con committed
253

dt's avatar
dt committed
254 255
    m_treeWidget->insertTopLevelItem(position, item);
}
con's avatar
con committed
256

dt's avatar
dt committed
257 258 259 260
void ProjectWindow::updateTreeWidgetAboutToRemoveProject(ProjectExplorer::Project *projectRemoved) {
    int count = m_treeWidget->topLevelItemCount();
    for (int i = 0; i < count; ++i) {
        QTreeWidgetItem *item = m_treeWidget->topLevelItem(i);
261
        if (item->data(2, Qt::UserRole).toString() == QFileInfo(projectRemoved->file()->fileName()).filePath()) {
dt's avatar
dt committed
262 263 264 265
            if (m_treeWidget->currentItem() == item) {
                    m_treeWidget->setCurrentItem(0);
            }
        }
con's avatar
con committed
266 267 268
    }
}

dt's avatar
dt committed
269 270 271 272 273
void ProjectWindow::updateTreeWidgetProjectRemoved(ProjectExplorer::Project *projectRemoved)
{    
    int count = m_treeWidget->topLevelItemCount();
    for (int i = 0; i < count; ++i) {
        QTreeWidgetItem *item = m_treeWidget->topLevelItem(i);
274
        if (item->data(2, Qt::UserRole).toString() == QFileInfo(projectRemoved->file()->fileName()).filePath()) {
dt's avatar
dt committed
275 276 277 278 279 280
            QTreeWidgetItem *it = m_treeWidget->takeTopLevelItem(i);
            delete it;
            break;
        }
    }
}
con's avatar
con committed
281 282 283 284

Project *ProjectWindow::findProject(const QString &path) const
{
    QList<Project*> projects = m_session->projects();
hjk's avatar
hjk committed
285
    foreach (Project* project, projects)
dt's avatar
dt committed
286
        if (QFileInfo(project->file()->fileName()).filePath() == path)
con's avatar
con committed
287 288
            return project;
    return 0;
hjk's avatar
hjk committed
289
}
con's avatar
con committed
290 291 292 293


void ProjectWindow::handleCurrentItemChanged(QTreeWidgetItem *current)
{
dt's avatar
dt committed
294 295 296
    if (m_currentItemChanged)
        return;
    m_currentItemChanged = true;
con's avatar
con committed
297
    if (current) {
298
        QString path = current->data(2, Qt::UserRole).toString();
con's avatar
con committed
299 300 301
        if (Project *project = findProject(path)) {
            m_projectExplorer->setCurrentFile(project, path);
            showProperties(project, QModelIndex());
dt's avatar
dt committed
302
            m_currentItemChanged = false;
con's avatar
con committed
303 304 305
            return;
        }
    }
dt's avatar
dt committed
306 307
    showProperties(0, QModelIndex());
    m_currentItemChanged = false;
con's avatar
con committed
308 309 310 311 312 313 314 315
}


void ProjectWindow::handleItem(QTreeWidgetItem *item, int column)
{
    if (!item || column != 1) // startup project
        return;

316
    const QString path = item->data(2, Qt::UserRole).toString();
con's avatar
con committed
317
    Project *project = findProject(path);
dt's avatar
dt committed
318 319 320
    // Project no longer exists
    if (!project)
        return;
321 322 323 324 325 326 327 328 329
     if (!(item->checkState(1) == Qt::Checked)) { // is now unchecked
         if (m_session->startupProject() == project) {
             item->setCheckState(1, Qt::Checked); // uncheck not supported
         }
     } else if (project && project->isApplication()) { // is now checked
         m_session->setStartupProject(project);
     } else {
         item->setCheckState(1, Qt::Unchecked); // check not supported
     }
con's avatar
con committed
330
}