1 /**************************************************************************
3 ** This file is part of Qt Creator
5 ** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
7 ** Contact: Nokia Corporation (info@qt.nokia.com)
10 ** GNU Lesser General Public License Usage
12 ** This file may be used under the terms of the GNU Lesser General Public
13 ** License version 2.1 as published by the Free Software Foundation and
14 ** appearing in the file LICENSE.LGPL included in the packaging of this file.
15 ** Please review the following information to ensure the GNU Lesser General
16 ** Public License version 2.1 requirements will be met:
17 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
19 ** In addition, as a special exception, Nokia gives you certain additional
20 ** rights. These rights are described in the Nokia Qt LGPL Exception
21 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
25 ** Alternatively, this file may be used in accordance with the terms and
26 ** conditions contained in a signed written agreement between you and Nokia.
28 ** If you have questions regarding the use of this file, please contact
29 ** Nokia at qt-info@nokia.com.
31 **************************************************************************/
33 #include "openeditorsmodel.h"
37 #include <QtCore/QDir>
38 #include <QtGui/QIcon>
42 struct OpenEditorsModelPrivate {
43 OpenEditorsModelPrivate();
45 const QIcon m_lockedIcon;
46 const QIcon m_unlockedIcon;
48 QList<OpenEditorsModel::Entry> m_editors;
49 QList<IEditor *> m_duplicateEditors;
52 OpenEditorsModelPrivate::OpenEditorsModelPrivate() :
53 m_lockedIcon(QLatin1String(":/core/images/locked.png")),
54 m_unlockedIcon(QLatin1String(":/core/images/unlocked.png"))
58 OpenEditorsModel::Entry::Entry() :
63 OpenEditorsModel::OpenEditorsModel(QObject *parent) :
64 QAbstractItemModel(parent), d(new OpenEditorsModelPrivate)
68 OpenEditorsModel::~OpenEditorsModel()
72 QIcon OpenEditorsModel::lockedIcon() const
74 return d->m_lockedIcon;
77 QIcon OpenEditorsModel::unlockedIcon() const
79 return d->m_unlockedIcon;
82 QString OpenEditorsModel::Entry::fileName() const {
83 return editor ? editor->file()->fileName() : m_fileName;
86 QString OpenEditorsModel::Entry::displayName() const {
87 return editor ? editor->displayName() : m_displayName;
90 QString OpenEditorsModel::Entry::id() const
92 return editor ? editor->id() : m_id;
95 int OpenEditorsModel::columnCount(const QModelIndex &parent) const
101 int OpenEditorsModel::rowCount(const QModelIndex &parent) const
103 if (!parent.isValid())
104 return d->m_editors.count();
108 QList<IEditor *> OpenEditorsModel::editors() const
110 QList<IEditor *> result;
111 foreach (const Entry &entry, d->m_editors)
113 result += entry.editor;
117 void OpenEditorsModel::addEditor(IEditor *editor, bool isDuplicate)
123 d->m_duplicateEditors.append(editor);
128 entry.editor = editor;
132 void OpenEditorsModel::addRestoredEditor(const QString &fileName, const QString &displayName, const QString &id)
135 entry.m_fileName = fileName;
136 entry.m_displayName = displayName;
141 QModelIndex OpenEditorsModel::firstRestoredEditor() const
143 for (int i = 0; i < d->m_editors.count(); ++i)
144 if (!d->m_editors.at(i).editor)
145 return createIndex(i, 0);
146 return QModelIndex();
149 void OpenEditorsModel::addEntry(const Entry &entry)
151 QString fileName = entry.fileName();
153 int previousIndex = findFileName(fileName);
154 if (previousIndex >= 0) {
155 if (entry.editor && d->m_editors.at(previousIndex).editor == 0) {
156 d->m_editors[previousIndex] = entry;
157 connect(entry.editor, SIGNAL(changed()), this, SLOT(itemChanged()));
163 QString displayName = entry.displayName();
164 for (index = 0; index < d->m_editors.count(); ++index) {
165 if (displayName < d->m_editors.at(index).displayName())
169 beginInsertRows(QModelIndex(), index, index);
170 d->m_editors.insert(index, entry);
172 connect(entry.editor, SIGNAL(changed()), this, SLOT(itemChanged()));
177 int OpenEditorsModel::findEditor(IEditor *editor) const
179 for (int i = 0; i < d->m_editors.count(); ++i)
180 if (d->m_editors.at(i).editor == editor)
185 int OpenEditorsModel::findFileName(const QString &filename) const
187 if (filename.isEmpty())
189 for (int i = 0; i < d->m_editors.count(); ++i) {
190 if (d->m_editors.at(i).fileName() == filename)
196 void OpenEditorsModel::removeEditor(IEditor *editor)
198 d->m_duplicateEditors.removeAll(editor);
199 int idx = findEditor(editor);
202 beginRemoveRows(QModelIndex(), idx, idx);
203 d->m_editors.removeAt(idx);
205 disconnect(editor, SIGNAL(changed()), this, SLOT(itemChanged()));
208 void OpenEditorsModel::removeEditor(const QModelIndex &index)
210 int idx = index.row();
213 IEditor *editor= d->m_editors.at(idx).editor;
214 beginRemoveRows(QModelIndex(), idx, idx);
215 d->m_editors.removeAt(idx);
218 disconnect(editor, SIGNAL(changed()), this, SLOT(itemChanged()));
221 void OpenEditorsModel::removeAllRestoredEditors()
223 for (int i = d->m_editors.count()-1; i >= 0; --i) {
224 if (!d->m_editors.at(i).editor) {
225 beginRemoveRows(QModelIndex(), i, i);
226 d->m_editors.removeAt(i);
232 QList<OpenEditorsModel::Entry> OpenEditorsModel::restoredEditors() const
235 for (int i = d->m_editors.count()-1; i >= 0; --i) {
236 if (!d->m_editors.at(i).editor) {
237 result.append(d->m_editors.at(i));
243 bool OpenEditorsModel::isDuplicate(IEditor *editor) const
245 return editor && d->m_duplicateEditors.contains(editor);
248 IEditor *OpenEditorsModel::originalForDuplicate(IEditor *duplicate) const
250 IFile *file = duplicate->file();
251 foreach(const Entry &e, d->m_editors)
252 if (e.editor && e.editor->file() == file)
257 QList<IEditor *> OpenEditorsModel::duplicatesFor(IEditor *editor) const
259 QList<IEditor *> result;
260 IFile *file = editor->file();
261 foreach(IEditor *e, d->m_duplicateEditors)
262 if (e->file() == file)
267 void OpenEditorsModel::makeOriginal(IEditor *duplicate)
269 Q_ASSERT(duplicate && isDuplicate(duplicate));
270 IEditor *original = originalForDuplicate(duplicate);
272 int i = findEditor(original);
273 d->m_editors[i].editor = duplicate;
274 d->m_duplicateEditors.removeOne(duplicate);
275 d->m_duplicateEditors.append(original);
276 disconnect(original, SIGNAL(changed()), this, SLOT(itemChanged()));
277 connect(duplicate, SIGNAL(changed()), this, SLOT(itemChanged()));
280 void OpenEditorsModel::emitDataChanged(IEditor *editor)
282 int idx = findEditor(editor);
285 QModelIndex mindex = index(idx, 0);
286 emit dataChanged(mindex, mindex);
289 QModelIndex OpenEditorsModel::index(int row, int column, const QModelIndex &parent) const
292 if (column < 0 || column > 1 || row < 0 || row >= d->m_editors.count())
293 return QModelIndex();
294 return createIndex(row, column);
297 QVariant OpenEditorsModel::data(const QModelIndex &index, int role) const
299 if (!index.isValid() || (index.column() != 0 && role < Qt::UserRole))
301 Entry e = d->m_editors.at(index.row());
303 case Qt::DisplayRole:
304 return (e.editor && e.editor->file()->isModified())
305 ? e.displayName() + QLatin1Char('*')
307 case Qt::DecorationRole:
308 return (e.editor && e.editor->file()->isReadOnly())
309 ? d->m_lockedIcon : QIcon();
310 case Qt::ToolTipRole:
311 return e.fileName().isEmpty()
313 : QDir::toNativeSeparators(e.fileName());
315 return qVariantFromValue(e.editor);
316 case Qt::UserRole + 1:
318 case Qt::UserRole + 2:
319 return e.editor ? e.editor->id() : e.id();
326 QModelIndex OpenEditorsModel::indexOf(IEditor *editor) const
328 int idx = findEditor(originalForDuplicate(editor));
329 return createIndex(idx, 0);
332 QString OpenEditorsModel::displayNameForFile(IFile *file) const
334 for (int i = 0; i < d->m_editors.count(); ++i)
335 if (d->m_editors.at(i).editor && d->m_editors.at(i).editor->file() == file)
336 return d->m_editors.at(i).editor->displayName();
340 void OpenEditorsModel::itemChanged()
342 emitDataChanged(qobject_cast<IEditor*>(sender()));
345 QList<OpenEditorsModel::Entry> OpenEditorsModel::entries() const
350 IEditor *OpenEditorsModel::editorAt(int row) const
352 return d->m_editors.at(row).editor;