dependenciespanel.cpp 9.85 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
37
38
39

#include <QtCore/QVector>
#include <QtCore/QDebug>
#include <QtCore/QAbstractListModel>
dt's avatar
dt committed
40
#include <QtGui/QLabel>
41
#include <QtGui/QApplication>
con's avatar
con committed
42
43
44
#include <QtGui/QHBoxLayout>
#include <QtGui/QTreeView>
#include <QtGui/QSpacerItem>
45
46
47
#include <QtGui/QHeaderView>
#include <QtGui/QMessageBox>
#include <QtGui/QPushButton>
dt's avatar
dt committed
48
#include <QtGui/QToolButton>
49
#include <QtCore/QCoreApplication>
50
51
52
53
54
55
56
57
58
59
60
61
62
63

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);
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
    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();
83
84
85
86
}

int DependenciesModel::rowCount(const QModelIndex &index) const
{
87
    return index.isValid() ? 0 : m_projects.isEmpty() ? 1 : m_projects.size();
88
89
90
91
92
93
94
95
96
}

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

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

102
103
104
105
    const Project *p = m_projects.at(index.row());

    switch (role) {
    case Qt::DisplayRole:
106
        return p->displayName();
107
108
109
110
111
112
113
114
115
116
117
118
    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
119
        Project *p = m_projects.at(index.row());
120
121
122
123
124
125
126
        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 {
127
128
                QMessageBox::warning(0, QCoreApplication::translate("DependenciesModel", "Unable to add dependency"),
                                     QCoreApplication::translate("DependenciesModel", "This would create a circular dependency."));
129
130
131
132
133
134
135
136
137
138
139
140
141
142
            }
        } 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
{
143
144
145
    if (m_projects.isEmpty())
        return Qt::NoItemFlags;

146
147
148
149
150
151
    Qt::ItemFlags rc = QAbstractListModel::flags(index);
    if (index.column() == 0)
        rc |= Qt::ItemIsUserCheckable | Qt::ItemIsEditable;
    return rc;
}

152
//
dt's avatar
dt committed
153
// DependenciesView
154
//
dt's avatar
dt committed
155
156
157
158
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
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();
}
201

dt's avatar
dt committed
202
void DependenciesView::updateSizeHint()
203
{
dt's avatar
dt committed
204
205
206
207
    if (!model()) {
        m_sizeHint = QSize(250, 250);
        return;
    }
208

dt's avatar
dt committed
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
    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
//
226
227
228
229
230
231

DependenciesWidget::DependenciesWidget(SessionManager *session,
                                       Project *project,
                                       QWidget *parent)
    : QWidget(parent)
    , m_session(session)
dt's avatar
dt committed
232
    , m_project(project)
233
234
    , m_model(new DependenciesModel(session, project, this))
{
dt's avatar
dt committed
235
236
    QVBoxLayout *vbox = new QVBoxLayout(this);
    vbox->setContentsMargins(0, 0, 0, 0);
dt's avatar
dt committed
237
238
    m_detailsContainer = new Utils::DetailsWidget(this);
    vbox->addWidget(m_detailsContainer);
dt's avatar
dt committed
239

dt's avatar
dt committed
240
241
242
    QWidget *detailsWidget = new QWidget(m_detailsContainer);
    m_detailsContainer->setWidget(detailsWidget);
    QHBoxLayout *layout = new QHBoxLayout(detailsWidget);
con's avatar
con committed
243
    layout->setContentsMargins(0, -1, 0, -1);
dt's avatar
dt committed
244
    DependenciesView *treeView = new DependenciesView(this);
dt's avatar
dt committed
245
246
247
248
    treeView->setModel(m_model);
    treeView->setHeaderHidden(true);
    layout->addWidget(treeView);
    layout->addSpacerItem(new QSpacerItem(0, 0 , QSizePolicy::Expanding, QSizePolicy::Fixed));
dt's avatar
dt committed
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268

    updateDetails();

    connect(session, SIGNAL(dependencyChanged(ProjectExplorer::Project*,ProjectExplorer::Project*)),
            this, SLOT(updateDetails()));

    connect(session, SIGNAL(projectRemoved(ProjectExplorer::Project*)),
            this, SLOT(updateDetails()));
    connect(session, SIGNAL(projectAdded(ProjectExplorer::Project*)),
            this, SLOT(updateDetails()));
    connect(session, SIGNAL(sessionLoaded()),
            this, SLOT(updateDetails()));
}

void DependenciesWidget::updateDetails()
{
    QStringList dependsOn;

    foreach(Project *other, m_session->projects()) {
        if (m_session->hasDependency(m_project, other)) {
269
            dependsOn.append(other->displayName());
dt's avatar
dt committed
270
271
272
273
        }
    }
    QString text;
    if (dependsOn.isEmpty()) {
274
        text = tr("%1 has no dependencies.").arg(m_project->displayName());
dt's avatar
dt committed
275
    } else if (dependsOn.count() == 1) {
276
        text =tr("%1 depends on %2.").arg(m_project->displayName(), dependsOn.first());
dt's avatar
dt committed
277
    } else {
278
        text = tr("%1 depends on: %2.").arg(m_project->displayName(), dependsOn.join(QLatin1String(", ")));
dt's avatar
dt committed
279
    }
dt's avatar
dt committed
280
    m_detailsContainer->setSummaryText(text);
281
282
}

283
284
285
//
// DependenciesPanel
//
286

287
288
289
DependenciesPanel::DependenciesPanel(SessionManager *session, Project *project) :
    m_widget(new DependenciesWidget(session, project)),
    m_icon(":/projectexplorer/images/session.png")
290
291
292
293
294
{
}

DependenciesPanel::~DependenciesPanel()
{
295
    delete m_widget;
296
297
}

298
QString DependenciesPanel::displayName() const
299
{
300
    return QApplication::tr("Dependencies");
301
302
}

303
QWidget *DependenciesPanel::widget() const
304
305
306
307
{
    return m_widget;
}

308
309
310
311
312
QIcon DependenciesPanel::icon() const
{
    return m_icon;
}

313
314
315
//
// DependenciesPanelFactory
//
316
317
318
319
320
321
322
323
324
325
326

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

bool DependenciesPanelFactory::supports(Project * /* project */)
{
    return true;
}

327
IPropertiesPanel *DependenciesPanelFactory::createPanel(Project *project)
328
329
330
331
332
333
{
    return new DependenciesPanel(m_session, project);
}

} // namespace Internal
} // namespace ProjectExplorer