/************************************************************************** ** ** 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 "projectwindow.h" #include "project.h" #include "projectexplorer.h" #include "projectexplorerconstants.h" #include "iprojectproperties.h" #include "session.h" #include "projecttreewidget.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace ProjectExplorer; using namespace ProjectExplorer::Internal; namespace { bool debug = false; } PanelsWidget::PanelsWidget(QWidget *parent) : QScrollArea(parent) { 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); setWidgetResizable(true); setFrameStyle(QFrame::NoFrame); setWidget(topwidget); } 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) { setWindowTitle(tr("Project Explorer")); setWindowIcon(QIcon(":/projectexplorer/images/projectexplorer.png")); m_projectExplorer = ProjectExplorerPlugin::instance(); m_session = m_projectExplorer->session(); m_treeWidget = new QTreeWidget(this); m_treeWidget->setSelectionMode(QAbstractItemView::SingleSelection); m_treeWidget->setSelectionBehavior(QAbstractItemView::SelectRows); 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)), this, SLOT(handleItem(QTreeWidgetItem*, int))); connect(m_treeWidget, SIGNAL(currentItemChanged(QTreeWidgetItem*, QTreeWidgetItem *)), this, SLOT(handleCurrentItemChanged(QTreeWidgetItem*))); m_panelsWidget = new PanelsWidget(this); QWidget *dummy = new QWidget; QVBoxLayout *dummyLayout = new QVBoxLayout(dummy); dummyLayout->setMargin(0); dummyLayout->setSpacing(0); 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(m_panelsWidget); // 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() << treeWidgetMinSize << splitter->height() - treeWidgetMinSize); QVBoxLayout *topLayout = new QVBoxLayout(this); topLayout->setMargin(0); topLayout->setSpacing(0); topLayout->addWidget(splitter); 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*))); } ProjectWindow::~ProjectWindow() { } void ProjectWindow::restoreStatus() { if (!m_treeWidget->currentItem() && m_treeWidget->topLevelItemCount()) { m_treeWidget->setCurrentItem(m_treeWidget->topLevelItem(0), 0, QItemSelectionModel::SelectCurrent | QItemSelectionModel::Rows); } // 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() { // TODO // m_session->setValue(QLatin1String("ProjectWindow/Panel"), m_panelsTabWidget->currentIndex()); } void ProjectWindow::showProperties(ProjectExplorer::Project *project, const QModelIndex & /* subIndex */) { if (debug) qDebug() << "ProjectWindow - showProperties called"; // Remove the tabs from the tab widget first m_panelsWidget->clear(); if (project) { QList pages = ExtensionSystem::PluginManager::instance()->getObjects(); foreach (IPanelFactory *panelFactory, pages) { if (panelFactory->supports(project)) { PropertiesPanel *panel = panelFactory->createPanel(project); if (debug) qDebug() << "ProjectWindow - setting up project properties tab " << panel->name(); m_panelsWidget->addWidget(panel->name(), panel->widget()); } } } } void ProjectWindow::updateTreeWidgetStatupProjectChanged(ProjectExplorer::Project *startupProject) { int count = m_treeWidget->topLevelItemCount(); for (int i = 0; i < count; ++i) { QTreeWidgetItem *item = m_treeWidget->topLevelItem(i); if (Project *project = findProject(item->data(2, Qt::UserRole).toString())) { 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); } } } void ProjectWindow::updateTreeWidgetProjectAdded(ProjectExplorer::Project *projectAdded) { int position = m_session->projects().indexOf(projectAdded); const QFileInfo fileInfo(projectAdded->file()->fileName()); QTreeWidgetItem *item = new QTreeWidgetItem(); item->setText(0, projectAdded->name()); item->setIcon(0, Core::FileIconProvider::instance()->icon(fileInfo)); item->setData(2, Qt::UserRole, fileInfo.filePath()); item->setText(2, QDir::toNativeSeparators(fileInfo.filePath())); if (projectAdded->isApplication()) { bool checked = (m_session->startupProject() == projectAdded); item->setCheckState(1, checked ? Qt::Checked : Qt::Unchecked); } m_treeWidget->insertTopLevelItem(position, item); } void ProjectWindow::updateTreeWidgetAboutToRemoveProject(ProjectExplorer::Project *projectRemoved) { int count = m_treeWidget->topLevelItemCount(); for (int i = 0; i < count; ++i) { QTreeWidgetItem *item = m_treeWidget->topLevelItem(i); if (item->data(2, Qt::UserRole).toString() == QFileInfo(projectRemoved->file()->fileName()).filePath()) { if (m_treeWidget->currentItem() == item) { m_treeWidget->setCurrentItem(0); } } } } void ProjectWindow::updateTreeWidgetProjectRemoved(ProjectExplorer::Project *projectRemoved) { int count = m_treeWidget->topLevelItemCount(); for (int i = 0; i < count; ++i) { QTreeWidgetItem *item = m_treeWidget->topLevelItem(i); if (item->data(2, Qt::UserRole).toString() == QFileInfo(projectRemoved->file()->fileName()).filePath()) { QTreeWidgetItem *it = m_treeWidget->takeTopLevelItem(i); delete it; break; } } } Project *ProjectWindow::findProject(const QString &path) const { QList projects = m_session->projects(); foreach (Project* project, projects) if (QFileInfo(project->file()->fileName()).filePath() == path) return project; return 0; } void ProjectWindow::handleCurrentItemChanged(QTreeWidgetItem *current) { if (m_currentItemChanged) return; m_currentItemChanged = true; if (current) { QString path = current->data(2, Qt::UserRole).toString(); if (Project *project = findProject(path)) { m_projectExplorer->setCurrentFile(project, path); showProperties(project, QModelIndex()); m_currentItemChanged = false; return; } } showProperties(0, QModelIndex()); m_currentItemChanged = false; } void ProjectWindow::handleItem(QTreeWidgetItem *item, int column) { if (!item || column != 1) // startup project return; const QString path = item->data(2, Qt::UserRole).toString(); Project *project = findProject(path); 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 } }