1 /**************************************************************************
3 ** This file is part of Qt Creator
5 ** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
7 ** Contact: Nokia Corporation (qt-info@nokia.com)
11 ** This file contains pre-release code and may not be distributed.
12 ** You may use this file in accordance with the terms and conditions
13 ** contained in the Technology Preview License Agreement accompanying
16 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25 ** In addition, as a special exception, Nokia gives you certain additional
26 ** rights. These rights are described in the Nokia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29 ** If you have questions regarding the use of this file, please contact
30 ** Nokia at qt-info@nokia.com.
32 **************************************************************************/
34 #include "openeditorsmodel.h"
38 #include <QtCore/QDir>
39 #include <QtGui/QIcon>
43 struct OpenEditorsModelPrivate {
44 OpenEditorsModelPrivate();
46 const QIcon m_lockedIcon;
47 const QIcon m_unlockedIcon;
49 QList<OpenEditorsModel::Entry> m_editors;
50 QList<IEditor *> m_duplicateEditors;
53 OpenEditorsModelPrivate::OpenEditorsModelPrivate() :
54 m_lockedIcon(QLatin1String(":/core/images/locked.png")),
55 m_unlockedIcon(QLatin1String(":/core/images/unlocked.png"))
59 OpenEditorsModel::Entry::Entry() :
64 OpenEditorsModel::OpenEditorsModel(QObject *parent) :
65 QAbstractItemModel(parent), d(new OpenEditorsModelPrivate)
69 OpenEditorsModel::~OpenEditorsModel()
73 QIcon OpenEditorsModel::lockedIcon() const
75 return d->m_lockedIcon;
78 QIcon OpenEditorsModel::unlockedIcon() const
80 return d->m_unlockedIcon;
83 QString OpenEditorsModel::Entry::fileName() const {
84 return editor ? editor->file()->fileName() : m_fileName;
87 QString OpenEditorsModel::Entry::displayName() const {
88 return editor ? editor->displayName() : m_displayName;
91 QString OpenEditorsModel::Entry::id() const
93 return editor ? editor->id() : m_id;
96 int OpenEditorsModel::columnCount(const QModelIndex &parent) const
102 int OpenEditorsModel::rowCount(const QModelIndex &parent) const
104 if (!parent.isValid())
105 return d->m_editors.count();
109 QList<IEditor *> OpenEditorsModel::editors() const
111 QList<IEditor *> result;
112 foreach (const Entry &entry, d->m_editors)
114 result += entry.editor;
118 void OpenEditorsModel::addEditor(IEditor *editor, bool isDuplicate)
124 d->m_duplicateEditors.append(editor);
129 entry.editor = editor;
133 void OpenEditorsModel::addRestoredEditor(const QString &fileName, const QString &displayName, const QString &id)
136 entry.m_fileName = fileName;
137 entry.m_displayName = displayName;
142 QModelIndex OpenEditorsModel::firstRestoredEditor() const
144 for (int i = 0; i < d->m_editors.count(); ++i)
145 if (!d->m_editors.at(i).editor)
146 return createIndex(i, 0);
147 return QModelIndex();
150 void OpenEditorsModel::addEntry(const Entry &entry)
152 QString fileName = entry.fileName();
154 int previousIndex = findFileName(fileName);
155 if (previousIndex >= 0) {
156 if (entry.editor && d->m_editors.at(previousIndex).editor == 0) {
157 d->m_editors[previousIndex] = entry;
158 connect(entry.editor, SIGNAL(changed()), this, SLOT(itemChanged()));
164 QString displayName = entry.displayName();
165 for (index = 0; index < d->m_editors.count(); ++index) {
166 if (displayName < d->m_editors.at(index).displayName())
170 beginInsertRows(QModelIndex(), index, index);
171 d->m_editors.insert(index, entry);
173 connect(entry.editor, SIGNAL(changed()), this, SLOT(itemChanged()));
178 int OpenEditorsModel::findEditor(IEditor *editor) const
180 for (int i = 0; i < d->m_editors.count(); ++i)
181 if (d->m_editors.at(i).editor == editor)
186 int OpenEditorsModel::findFileName(const QString &filename) const
188 if (filename.isEmpty())
190 for (int i = 0; i < d->m_editors.count(); ++i) {
191 if (d->m_editors.at(i).fileName() == filename)
197 void OpenEditorsModel::removeEditor(IEditor *editor)
199 d->m_duplicateEditors.removeAll(editor);
200 int idx = findEditor(editor);
203 beginRemoveRows(QModelIndex(), idx, idx);
204 d->m_editors.removeAt(idx);
206 disconnect(editor, SIGNAL(changed()), this, SLOT(itemChanged()));
209 void OpenEditorsModel::removeEditor(const QModelIndex &index)
211 int idx = index.row();
214 IEditor *editor= d->m_editors.at(idx).editor;
215 beginRemoveRows(QModelIndex(), idx, idx);
216 d->m_editors.removeAt(idx);
219 disconnect(editor, SIGNAL(changed()), this, SLOT(itemChanged()));
222 void OpenEditorsModel::removeAllRestoredEditors()
224 for (int i = d->m_editors.count()-1; i >= 0; --i) {
225 if (!d->m_editors.at(i).editor) {
226 beginRemoveRows(QModelIndex(), i, i);
227 d->m_editors.removeAt(i);
233 QList<OpenEditorsModel::Entry> OpenEditorsModel::restoredEditors() const
236 for (int i = d->m_editors.count()-1; i >= 0; --i) {
237 if (!d->m_editors.at(i).editor) {
238 result.append(d->m_editors.at(i));
244 bool OpenEditorsModel::isDuplicate(IEditor *editor) const
246 return editor && d->m_duplicateEditors.contains(editor);
249 IEditor *OpenEditorsModel::originalForDuplicate(IEditor *duplicate) const
251 IFile *file = duplicate->file();
252 foreach(const Entry &e, d->m_editors)
253 if (e.editor && e.editor->file() == file)
258 QList<IEditor *> OpenEditorsModel::duplicatesFor(IEditor *editor) const
260 QList<IEditor *> result;
261 IFile *file = editor->file();
262 foreach(IEditor *e, d->m_duplicateEditors)
263 if (e->file() == file)
268 void OpenEditorsModel::makeOriginal(IEditor *duplicate)
270 Q_ASSERT(duplicate && isDuplicate(duplicate));
271 IEditor *original = originalForDuplicate(duplicate);
273 int i = findEditor(original);
274 d->m_editors[i].editor = duplicate;
275 d->m_duplicateEditors.removeOne(duplicate);
276 d->m_duplicateEditors.append(original);
277 disconnect(original, SIGNAL(changed()), this, SLOT(itemChanged()));
278 connect(duplicate, SIGNAL(changed()), this, SLOT(itemChanged()));
281 void OpenEditorsModel::emitDataChanged(IEditor *editor)
283 int idx = findEditor(editor);
286 QModelIndex mindex = index(idx, 0);
287 emit dataChanged(mindex, mindex);
290 QModelIndex OpenEditorsModel::index(int row, int column, const QModelIndex &parent) const
293 if (column < 0 || column > 1 || row < 0 || row >= d->m_editors.count())
294 return QModelIndex();
295 return createIndex(row, column);
298 QVariant OpenEditorsModel::data(const QModelIndex &index, int role) const
300 if (!index.isValid() || (index.column() != 0 && role < Qt::UserRole))
302 Entry e = d->m_editors.at(index.row());
304 case Qt::DisplayRole:
305 return (e.editor && e.editor->file()->isModified())
306 ? e.displayName() + QLatin1Char('*')
308 case Qt::DecorationRole:
309 return (e.editor && e.editor->file()->isReadOnly())
310 ? d->m_lockedIcon : QIcon();
311 case Qt::ToolTipRole:
312 return e.fileName().isEmpty()
314 : QDir::toNativeSeparators(e.fileName());
316 return qVariantFromValue(e.editor);
317 case Qt::UserRole + 1:
319 case Qt::UserRole + 2:
320 return e.editor ? e.editor->id() : e.id();
327 QModelIndex OpenEditorsModel::indexOf(IEditor *editor) const
329 int idx = findEditor(originalForDuplicate(editor));
330 return createIndex(idx, 0);
333 QString OpenEditorsModel::displayNameForFile(IFile *file) const
335 for (int i = 0; i < d->m_editors.count(); ++i)
336 if (d->m_editors.at(i).editor && d->m_editors.at(i).editor->file() == file)
337 return d->m_editors.at(i).editor->displayName();
341 void OpenEditorsModel::itemChanged()
343 emitDataChanged(qobject_cast<IEditor*>(sender()));
346 QList<OpenEditorsModel::Entry> OpenEditorsModel::entries() const
351 IEditor *OpenEditorsModel::editorAt(int row) const
353 return d->m_editors.at(row).editor;