projectwindow.cpp 11 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 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103
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();
}

dt's avatar
dt committed
104 105
ProjectWindow::ProjectWindow(QWidget *parent)
    : QWidget(parent), m_currentItemChanged(false)
con's avatar
con committed
106 107 108 109
{
    setWindowTitle(tr("Project Explorer"));
    setWindowIcon(QIcon(":/projectexplorer/images/projectexplorer.png"));

110 111
    m_projectExplorer = ProjectExplorerPlugin::instance();
    m_session = m_projectExplorer->session();
con's avatar
con committed
112 113

    m_treeWidget = new QTreeWidget(this);
dt's avatar
dt committed
114 115
    m_treeWidget->setSelectionMode(QAbstractItemView::SingleSelection);
    m_treeWidget->setSelectionBehavior(QAbstractItemView::SelectRows);
con's avatar
con committed
116 117 118 119 120 121 122 123 124 125
    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
126
            this, SLOT(handleItem(QTreeWidgetItem*, int)));
con's avatar
con committed
127 128 129
    connect(m_treeWidget, SIGNAL(currentItemChanged(QTreeWidgetItem*, QTreeWidgetItem *)),
            this, SLOT(handleCurrentItemChanged(QTreeWidgetItem*)));

dt's avatar
dt committed
130
    m_panelsWidget = new PanelsWidget(this);
con's avatar
con committed
131 132 133 134 135

    QWidget *dummy = new QWidget;
    QVBoxLayout *dummyLayout = new QVBoxLayout(dummy);
    dummyLayout->setMargin(0);
    dummyLayout->setSpacing(0);
con's avatar
con committed
136
    dummyLayout->addWidget(new Core::Utils::StyledBar(dummy));
con's avatar
con committed
137 138 139 140 141
    dummyLayout->addWidget(m_treeWidget);

    QSplitter *splitter = new Core::MiniSplitter;
    splitter->setOrientation(Qt::Vertical);
    splitter->addWidget(dummy);
dt's avatar
dt committed
142
    splitter->addWidget(m_panelsWidget);
con's avatar
con committed
143 144 145 146 147 148 149 150 151 152 153

    // 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
154 155 156 157 158 159 160 161
    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
162 163 164 165 166 167 168 169
}

ProjectWindow::~ProjectWindow()
{
}

void ProjectWindow::restoreStatus()
{
dt's avatar
dt committed
170 171 172 173
    if (!m_treeWidget->currentItem() && m_treeWidget->topLevelItemCount()) {
        m_treeWidget->setCurrentItem(m_treeWidget->topLevelItem(0), 0, QItemSelectionModel::SelectCurrent | QItemSelectionModel::Rows);
    }

dt's avatar
dt committed
174 175 176 177 178 179 180 181 182 183
    // 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
184 185 186 187
}

void ProjectWindow::saveStatus()
{
dt's avatar
dt committed
188 189
    // TODO
//    m_session->setValue(QLatin1String("ProjectWindow/Panel"), m_panelsTabWidget->currentIndex());
con's avatar
con committed
190 191 192 193 194 195 196 197
}

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
198
    m_panelsWidget->clear();
con's avatar
con committed
199 200 201 202 203 204 205 206 207

    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
208
                m_panelsWidget->addWidget(panel->name(), panel->widget());
con's avatar
con committed
209 210 211 212 213
            }
        }
    }
}

dt's avatar
dt committed
214
void ProjectWindow::updateTreeWidgetStatupProjectChanged(ProjectExplorer::Project *startupProject)
con's avatar
con committed
215
{
dt's avatar
dt committed
216 217 218
    int count = m_treeWidget->topLevelItemCount();
    for (int i = 0; i < count; ++i) {
        QTreeWidgetItem *item = m_treeWidget->topLevelItem(i);
219
        if (Project *project = findProject(item->data(2, Qt::UserRole).toString())) {
dt's avatar
dt committed
220 221 222 223 224
            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);
225 226
        }
    }
dt's avatar
dt committed
227
}
con's avatar
con committed
228

dt's avatar
dt committed
229 230 231 232
void ProjectWindow::updateTreeWidgetProjectAdded(ProjectExplorer::Project *projectAdded)
{
    int position = m_session->projects().indexOf(projectAdded);
    const QFileInfo fileInfo(projectAdded->file()->fileName());
con's avatar
con committed
233

dt's avatar
dt committed
234
    QTreeWidgetItem *item = new QTreeWidgetItem();
235
    item->setText(0, projectAdded->name());
dt's avatar
dt committed
236
    item->setIcon(0, Core::FileIconProvider::instance()->icon(fileInfo));
237 238
    item->setData(2, Qt::UserRole, fileInfo.filePath());
    item->setText(2, QDir::toNativeSeparators(fileInfo.filePath()));
con's avatar
con committed
239

dt's avatar
dt committed
240 241 242 243
    if (projectAdded->isApplication()) {
        bool checked = (m_session->startupProject() == projectAdded);
        item->setCheckState(1, checked ? Qt::Checked : Qt::Unchecked);
    }
con's avatar
con committed
244

dt's avatar
dt committed
245 246
    m_treeWidget->insertTopLevelItem(position, item);
}
con's avatar
con committed
247

dt's avatar
dt committed
248 249 250 251
void ProjectWindow::updateTreeWidgetAboutToRemoveProject(ProjectExplorer::Project *projectRemoved) {
    int count = m_treeWidget->topLevelItemCount();
    for (int i = 0; i < count; ++i) {
        QTreeWidgetItem *item = m_treeWidget->topLevelItem(i);
252
        if (item->data(2, Qt::UserRole).toString() == QFileInfo(projectRemoved->file()->fileName()).filePath()) {
dt's avatar
dt committed
253 254 255 256
            if (m_treeWidget->currentItem() == item) {
                    m_treeWidget->setCurrentItem(0);
            }
        }
con's avatar
con committed
257 258 259
    }
}

dt's avatar
dt committed
260 261 262 263 264
void ProjectWindow::updateTreeWidgetProjectRemoved(ProjectExplorer::Project *projectRemoved)
{    
    int count = m_treeWidget->topLevelItemCount();
    for (int i = 0; i < count; ++i) {
        QTreeWidgetItem *item = m_treeWidget->topLevelItem(i);
265
        if (item->data(2, Qt::UserRole).toString() == QFileInfo(projectRemoved->file()->fileName()).filePath()) {
dt's avatar
dt committed
266 267 268 269 270 271
            QTreeWidgetItem *it = m_treeWidget->takeTopLevelItem(i);
            delete it;
            break;
        }
    }
}
con's avatar
con committed
272 273 274 275

Project *ProjectWindow::findProject(const QString &path) const
{
    QList<Project*> projects = m_session->projects();
hjk's avatar
hjk committed
276
    foreach (Project* project, projects)
dt's avatar
dt committed
277
        if (QFileInfo(project->file()->fileName()).filePath() == path)
con's avatar
con committed
278 279
            return project;
    return 0;
hjk's avatar
hjk committed
280
}
con's avatar
con committed
281 282 283 284


void ProjectWindow::handleCurrentItemChanged(QTreeWidgetItem *current)
{
dt's avatar
dt committed
285 286 287
    if (m_currentItemChanged)
        return;
    m_currentItemChanged = true;
con's avatar
con committed
288
    if (current) {
289
        QString path = current->data(2, Qt::UserRole).toString();
con's avatar
con committed
290 291 292
        if (Project *project = findProject(path)) {
            m_projectExplorer->setCurrentFile(project, path);
            showProperties(project, QModelIndex());
dt's avatar
dt committed
293
            m_currentItemChanged = false;
con's avatar
con committed
294 295 296
            return;
        }
    }
dt's avatar
dt committed
297 298
    showProperties(0, QModelIndex());
    m_currentItemChanged = false;
con's avatar
con committed
299 300 301 302 303
}


void ProjectWindow::handleItem(QTreeWidgetItem *item, int column)
{
dt's avatar
dt committed
304

con's avatar
con committed
305 306 307
    if (!item || column != 1) // startup project
        return;

308
    const QString path = item->data(2, Qt::UserRole).toString();
con's avatar
con committed
309 310
    Project *project = findProject(path);
    if (project && project->isApplication()) {
dt's avatar
dt committed
311 312 313 314 315
        if (!(item->checkState(1) == Qt::Checked)) { // is now unchecked
            if (m_session->startupProject() == project) {
                item->setCheckState(1, Qt::Checked); // uncheck not supported
            }
        } else { // is now checked
con's avatar
con committed
316 317 318 319
            m_session->setStartupProject(project);
        }
    }
}