dependenciespanel.cpp 9.28 KB
Newer Older
1
/**************************************************************************
2 3 4
**
** This file is part of Qt Creator
**
5
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
6
**
7
** Contact: Nokia Corporation (qt-info@nokia.com)
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.
27
**
28
**************************************************************************/
29 30 31 32 33 34

#include "dependenciespanel.h"
#include "project.h"
#include "session.h"

#include <coreplugin/fileiconprovider.h>
35
#include <coreplugin/ifile.h>
36
#include <utils/detailswidget.h>
37 38 39

#include <QtCore/QVector>
#include <QtCore/QDebug>
40 41 42
#include <QtCore/QSize>
#include <QtCore/QCoreApplication>

dt's avatar
dt committed
43
#include <QtGui/QLabel>
44
#include <QtGui/QApplication>
con's avatar
con committed
45 46 47
#include <QtGui/QHBoxLayout>
#include <QtGui/QTreeView>
#include <QtGui/QSpacerItem>
48 49 50
#include <QtGui/QHeaderView>
#include <QtGui/QMessageBox>
#include <QtGui/QPushButton>
dt's avatar
dt committed
51
#include <QtGui/QToolButton>
52 53
#include <QtGui/QWidget>
#include <QtGui/QLabel>
54 55 56 57 58 59 60 61 62 63 64 65 66 67

namespace ProjectExplorer {
namespace Internal {

DependenciesModel::DependenciesModel(SessionManager *session,
                                     Project *project,
                                     QObject *parent)
    : QAbstractListModel(parent)
    , m_session(session)
    , m_project(project)
    , m_projects(session->projects())
{
    // We can't select ourselves as a dependency
    m_projects.removeAll(m_project);
68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86
    connect(session, SIGNAL(projectRemoved(ProjectExplorer::Project*)),
            this, SLOT(resetModel()));
    connect(session, SIGNAL(projectAdded(ProjectExplorer::Project*)),
            this, SLOT(resetModel()));
    connect(session, SIGNAL(sessionLoaded()),
            this, SLOT(resetModel()));
//    qDebug()<<"Dependencies Model"<<this<<"for project"<<project<<"("<<project->file()->fileName()<<")";
}

DependenciesModel::~DependenciesModel()
{
//    qDebug()<<"~DependenciesModel"<<this;
}

void DependenciesModel::resetModel()
{
    m_projects = m_session->projects();
    m_projects.removeAll(m_project);
    reset();
87 88 89 90
}

int DependenciesModel::rowCount(const QModelIndex &index) const
{
91
    return index.isValid() ? 0 : m_projects.isEmpty() ? 1 : m_projects.size();
92 93 94 95 96 97 98 99 100
}

int DependenciesModel::columnCount(const QModelIndex &index) const
{
    return index.isValid() ? 0 : 1;
}

QVariant DependenciesModel::data(const QModelIndex &index, int role) const
{
101 102 103 104 105
    if (m_projects.isEmpty())
        return role == Qt::DisplayRole
            ? tr("<No other projects in this session>")
            : QVariant();

106 107 108 109
    const Project *p = m_projects.at(index.row());

    switch (role) {
    case Qt::DisplayRole:
110
        return p->displayName();
111 112 113 114 115 116 117 118 119 120 121 122
    case Qt::CheckStateRole:
        return m_session->hasDependency(m_project, p) ? Qt::Checked : Qt::Unchecked;
    case Qt::DecorationRole:
        return Core::FileIconProvider::instance()->icon(QFileInfo(p->file()->fileName()));
    default:
        return QVariant();
    }
}

bool DependenciesModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
    if (role == Qt::CheckStateRole) {
dt's avatar
dt committed
123
        Project *p = m_projects.at(index.row());
124 125 126 127 128 129 130
        const Qt::CheckState c = static_cast<Qt::CheckState>(value.toInt());

        if (c == Qt::Checked) {
            if (m_session->addDependency(m_project, p)) {
                emit dataChanged(index, index);
                return true;
            } else {
131 132
                QMessageBox::warning(0, QCoreApplication::translate("DependenciesModel", "Unable to add dependency"),
                                     QCoreApplication::translate("DependenciesModel", "This would create a circular dependency."));
133 134 135 136 137 138 139 140 141 142 143 144 145 146
            }
        } else if (c == Qt::Unchecked) {
            if (m_session->hasDependency(m_project, p)) {
                m_session->removeDependency(m_project, p);
                emit dataChanged(index, index);
                return true;
            }
        }
    }
    return false;
}

Qt::ItemFlags DependenciesModel::flags(const QModelIndex &index) const
{
147 148 149
    if (m_projects.isEmpty())
        return Qt::NoItemFlags;

150 151 152 153 154 155
    Qt::ItemFlags rc = QAbstractListModel::flags(index);
    if (index.column() == 0)
        rc |= Qt::ItemIsUserCheckable | Qt::ItemIsEditable;
    return rc;
}

156
//
dt's avatar
dt committed
157
// DependenciesView
158
//
dt's avatar
dt committed
159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204
DependenciesView::DependenciesView(QWidget *parent)
    : QTreeView(parent)
{
    m_sizeHint = QSize(250, 250);
    setUniformRowHeights(true);
    setSizePolicy(QSizePolicy::Expanding, QSizePolicy::MinimumExpanding);
    setRootIsDecorated(false);
}

DependenciesView::~DependenciesView()
{

}

QSize DependenciesView::sizeHint() const
{
    return m_sizeHint;
}

void DependenciesView::setModel(QAbstractItemModel *newModel)
{
    if (QAbstractItemModel *oldModel = model()) {
        disconnect(oldModel, SIGNAL(rowsInserted(QModelIndex,int,int)),
                this, SLOT(updateSizeHint()));
        disconnect(oldModel, SIGNAL(rowsRemoved(QModelIndex,int,int)),
                this, SLOT(updateSizeHint()));
        disconnect(oldModel, SIGNAL(modelReset()),
                this, SLOT(updateSizeHint()));
        disconnect(oldModel, SIGNAL(layoutChanged()),
                this, SLOT(updateSizeHint()));
    }

    QTreeView::setModel(newModel);

    if (newModel) {
        connect(newModel, SIGNAL(rowsInserted(QModelIndex,int,int)),
                this, SLOT(updateSizeHint()));
        connect(newModel, SIGNAL(rowsRemoved(QModelIndex,int,int)),
                this, SLOT(updateSizeHint()));
        connect(newModel, SIGNAL(modelReset()),
                this, SLOT(updateSizeHint()));
        connect(newModel, SIGNAL(layoutChanged()),
                this, SLOT(updateSizeHint()));
    }
    updateSizeHint();
}
205

dt's avatar
dt committed
206
void DependenciesView::updateSizeHint()
207
{
dt's avatar
dt committed
208 209 210 211
    if (!model()) {
        m_sizeHint = QSize(250, 250);
        return;
    }
212

dt's avatar
dt committed
213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229
    int heightOffset = size().height() - viewport()->height();

    int heightPerRow = sizeHintForRow(0);
    if (heightPerRow == -1) {
        heightPerRow = 30;
    }
    int rows = qMin(qMax(model()->rowCount(), 2), 10);
    int height = rows * heightPerRow + heightOffset;
    if (m_sizeHint.height() != height) {
        m_sizeHint.setHeight(height);
        updateGeometry();
    }
}

//
// DependenciesWidget
//
230 231 232 233 234 235

DependenciesWidget::DependenciesWidget(SessionManager *session,
                                       Project *project,
                                       QWidget *parent)
    : QWidget(parent)
    , m_session(session)
dt's avatar
dt committed
236
    , m_project(project)
237 238
    , m_model(new DependenciesModel(session, project, this))
{
dt's avatar
dt committed
239 240
    QVBoxLayout *vbox = new QVBoxLayout(this);
    vbox->setContentsMargins(0, 0, 0, 0);
dt's avatar
dt committed
241
    m_detailsContainer = new Utils::DetailsWidget(this);
242
    m_detailsContainer->setState(Utils::DetailsWidget::NoSummary);
dt's avatar
dt committed
243
    vbox->addWidget(m_detailsContainer);
dt's avatar
dt committed
244

dt's avatar
dt committed
245 246 247
    QWidget *detailsWidget = new QWidget(m_detailsContainer);
    m_detailsContainer->setWidget(detailsWidget);
    QHBoxLayout *layout = new QHBoxLayout(detailsWidget);
con's avatar
con committed
248
    layout->setContentsMargins(0, -1, 0, -1);
dt's avatar
dt committed
249
    DependenciesView *treeView = new DependenciesView(this);
dt's avatar
dt committed
250 251 252 253
    treeView->setModel(m_model);
    treeView->setHeaderHidden(true);
    layout->addWidget(treeView);
    layout->addSpacerItem(new QSpacerItem(0, 0 , QSizePolicy::Expanding, QSizePolicy::Fixed));
254 255
}

256 257 258
//
// DependenciesPanel
//
259

260 261
DependenciesPanel::DependenciesPanel(SessionManager *session, Project *project) :
    m_widget(new DependenciesWidget(session, project)),
con's avatar
con committed
262
    m_icon(":/projectexplorer/images/ProjectDependencies.png")
263 264 265 266 267
{
}

DependenciesPanel::~DependenciesPanel()
{
268
    delete m_widget;
269 270
}

271
QString DependenciesPanel::displayName() const
272
{
273
    return QApplication::tr("Dependencies");
274 275
}

276
QWidget *DependenciesPanel::widget() const
277 278 279 280
{
    return m_widget;
}

281 282 283 284 285
QIcon DependenciesPanel::icon() const
{
    return m_icon;
}

286 287 288
//
// DependenciesPanelFactory
//
289 290 291 292 293 294

DependenciesPanelFactory::DependenciesPanelFactory(SessionManager *session)
    : m_session(session)
{
}

Tobias Hunger's avatar
Tobias Hunger committed
295 296 297 298 299
QString DependenciesPanelFactory::id() const
{
    return QLatin1String(DEPENDENCIES_PANEL_ID);
}

con's avatar
con committed
300 301 302 303 304
QString DependenciesPanelFactory::displayName() const
{
    return QApplication::tr("Dependencies");
}

Tobias Hunger's avatar
Tobias Hunger committed
305
bool DependenciesPanelFactory::supports(Project *project)
306
{
Tobias Hunger's avatar
Tobias Hunger committed
307
    Q_UNUSED(project);
308 309 310
    return true;
}

Tobias Hunger's avatar
Tobias Hunger committed
311 312 313 314 315 316
bool DependenciesPanelFactory::supports(Target *target)
{
    Q_UNUSED(target);
    return false;
}

317
IPropertiesPanel *DependenciesPanelFactory::createPanel(Project *project)
318 319 320 321
{
    return new DependenciesPanel(m_session, project);
}

Tobias Hunger's avatar
Tobias Hunger committed
322 323 324 325 326 327
IPropertiesPanel *DependenciesPanelFactory::createPanel(Target *target)
{
    Q_UNUSED(target);
    return 0;
}

328 329
} // namespace Internal
} // namespace ProjectExplorer