OSDN Git Service

Update license.
[qt-creator-jp/qt-creator-jp.git] / src / plugins / coreplugin / editormanager / openeditorsmodel.cpp
1 /**************************************************************************
2 **
3 ** This file is part of Qt Creator
4 **
5 ** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
6 **
7 ** Contact: Nokia Corporation (info@qt.nokia.com)
8 **
9 **
10 ** GNU Lesser General Public License Usage
11 **
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.
18 **
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.
22 **
23 ** Other Usage
24 **
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.
27 **
28 ** If you have questions regarding the use of this file, please contact
29 ** Nokia at qt-info@nokia.com.
30 **
31 **************************************************************************/
32
33 #include "openeditorsmodel.h"
34 #include "ieditor.h"
35 #include "ifile.h"
36
37 #include <QtCore/QDir>
38 #include <QtGui/QIcon>
39
40 namespace Core {
41
42 struct OpenEditorsModelPrivate {
43     OpenEditorsModelPrivate();
44
45     const QIcon m_lockedIcon;
46     const QIcon m_unlockedIcon;
47
48     QList<OpenEditorsModel::Entry> m_editors;
49     QList<IEditor *> m_duplicateEditors;
50 };
51
52 OpenEditorsModelPrivate::OpenEditorsModelPrivate() :
53     m_lockedIcon(QLatin1String(":/core/images/locked.png")),
54     m_unlockedIcon(QLatin1String(":/core/images/unlocked.png"))
55 {
56 }
57
58 OpenEditorsModel::Entry::Entry() :
59     editor(0)
60 {
61 }
62
63 OpenEditorsModel::OpenEditorsModel(QObject *parent) :
64     QAbstractItemModel(parent), d(new OpenEditorsModelPrivate)
65 {
66 }
67
68 OpenEditorsModel::~OpenEditorsModel()
69 {
70 }
71
72 QIcon OpenEditorsModel::lockedIcon() const
73 {
74     return d->m_lockedIcon;
75 }
76
77 QIcon OpenEditorsModel::unlockedIcon() const
78 {
79     return d->m_unlockedIcon;
80 }
81
82 QString OpenEditorsModel::Entry::fileName() const {
83     return editor ? editor->file()->fileName() : m_fileName;
84 }
85
86 QString OpenEditorsModel::Entry::displayName() const {
87     return editor ? editor->displayName() : m_displayName;
88 }
89
90 QString OpenEditorsModel::Entry::id() const
91 {
92     return editor ? editor->id() : m_id;
93 }
94
95 int OpenEditorsModel::columnCount(const QModelIndex &parent) const
96 {
97     Q_UNUSED(parent)
98     return 2;
99 }
100
101 int OpenEditorsModel::rowCount(const QModelIndex &parent) const
102 {
103     if (!parent.isValid())
104         return d->m_editors.count();
105     return 0;
106 }
107
108 QList<IEditor *> OpenEditorsModel::editors() const
109 {
110     QList<IEditor *> result;
111     foreach (const Entry &entry, d->m_editors)
112         if (entry.editor)
113             result += entry.editor;
114     return result;
115 }
116
117 void OpenEditorsModel::addEditor(IEditor *editor, bool isDuplicate)
118 {
119     if (!editor)
120         return;
121
122     if (isDuplicate) {
123         d->m_duplicateEditors.append(editor);
124         return;
125     }
126
127     Entry entry;
128     entry.editor = editor;
129     addEntry(entry);
130 }
131
132 void OpenEditorsModel::addRestoredEditor(const QString &fileName, const QString &displayName, const QString &id)
133 {
134     Entry entry;
135     entry.m_fileName = fileName;
136     entry.m_displayName = displayName;
137     entry.m_id = id;
138     addEntry(entry);
139 }
140
141 QModelIndex OpenEditorsModel::firstRestoredEditor() const
142 {
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();
147 }
148
149 void OpenEditorsModel::addEntry(const Entry &entry)
150 {
151     QString fileName = entry.fileName();
152
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()));
158         }
159         return;
160     }
161
162     int index;
163     QString displayName = entry.displayName();
164     for (index = 0; index < d->m_editors.count(); ++index) {
165         if (displayName < d->m_editors.at(index).displayName())
166             break;
167     }
168
169     beginInsertRows(QModelIndex(), index, index);
170     d->m_editors.insert(index, entry);
171     if (entry.editor)
172         connect(entry.editor, SIGNAL(changed()), this, SLOT(itemChanged()));
173     endInsertRows();
174 }
175
176
177 int OpenEditorsModel::findEditor(IEditor *editor) const
178 {
179     for (int i = 0; i < d->m_editors.count(); ++i)
180         if (d->m_editors.at(i).editor == editor)
181             return i;
182     return -1;
183 }
184
185 int OpenEditorsModel::findFileName(const QString &filename) const
186 {
187     if (filename.isEmpty())
188         return -1;
189     for (int i = 0; i < d->m_editors.count(); ++i) {
190         if (d->m_editors.at(i).fileName() == filename)
191             return i;
192     }
193     return -1;
194 }
195
196 void OpenEditorsModel::removeEditor(IEditor *editor)
197 {
198     d->m_duplicateEditors.removeAll(editor);
199     int idx = findEditor(editor);
200     if (idx < 0)
201         return;
202     beginRemoveRows(QModelIndex(), idx, idx);
203     d->m_editors.removeAt(idx);
204     endRemoveRows();
205     disconnect(editor, SIGNAL(changed()), this, SLOT(itemChanged()));
206 }
207
208 void OpenEditorsModel::removeEditor(const QModelIndex &index)
209 {
210     int idx = index.row();
211     if (idx < 0)
212         return;
213     IEditor *editor= d->m_editors.at(idx).editor;
214     beginRemoveRows(QModelIndex(), idx, idx);
215     d->m_editors.removeAt(idx);
216     endRemoveRows();
217     if (editor)
218         disconnect(editor, SIGNAL(changed()), this, SLOT(itemChanged()));
219 }
220
221 void OpenEditorsModel::removeAllRestoredEditors()
222 {
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);
227             endRemoveRows();
228         }
229     }
230 }
231
232 QList<OpenEditorsModel::Entry> OpenEditorsModel::restoredEditors() const
233 {
234     QList<Entry> result;
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));
238         }
239     }
240     return result;
241 }
242
243 bool OpenEditorsModel::isDuplicate(IEditor *editor) const
244 {
245     return editor && d->m_duplicateEditors.contains(editor);
246 }
247
248 IEditor *OpenEditorsModel::originalForDuplicate(IEditor *duplicate) const
249 {
250     IFile *file = duplicate->file();
251     foreach(const Entry &e, d->m_editors)
252         if (e.editor && e.editor->file() == file)
253             return e.editor;
254     return 0;
255 }
256
257 QList<IEditor *> OpenEditorsModel::duplicatesFor(IEditor *editor) const
258 {
259     QList<IEditor *> result;
260     IFile *file = editor->file();
261     foreach(IEditor *e, d->m_duplicateEditors)
262         if (e->file() == file)
263             result += e;
264     return result;
265 }
266
267 void OpenEditorsModel::makeOriginal(IEditor *duplicate)
268 {
269     Q_ASSERT(duplicate && isDuplicate(duplicate));
270     IEditor *original = originalForDuplicate(duplicate);
271     Q_ASSERT(original);
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()));
278 }
279
280 void OpenEditorsModel::emitDataChanged(IEditor *editor)
281 {
282     int idx = findEditor(editor);
283     if (idx < 0)
284         return;
285     QModelIndex mindex = index(idx, 0);
286     emit dataChanged(mindex, mindex);
287 }
288
289 QModelIndex OpenEditorsModel::index(int row, int column, const QModelIndex &parent) const
290 {
291     Q_UNUSED(parent)
292     if (column < 0 || column > 1 || row < 0 || row >= d->m_editors.count())
293         return QModelIndex();
294     return createIndex(row, column);
295 }
296
297 QVariant OpenEditorsModel::data(const QModelIndex &index, int role) const
298 {
299     if (!index.isValid() || (index.column() != 0 && role < Qt::UserRole))
300         return QVariant();
301     Entry e = d->m_editors.at(index.row());
302     switch (role) {
303     case Qt::DisplayRole:
304         return (e.editor && e.editor->file()->isModified())
305                 ? e.displayName() + QLatin1Char('*')
306                 : e.displayName();
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()
312                 ? e.displayName()
313                 : QDir::toNativeSeparators(e.fileName());
314     case Qt::UserRole:
315         return qVariantFromValue(e.editor);
316     case Qt::UserRole + 1:
317         return e.fileName();
318     case Qt::UserRole + 2:
319         return e.editor ? e.editor->id() : e.id();
320     default:
321         return QVariant();
322     }
323     return QVariant();
324 }
325
326 QModelIndex OpenEditorsModel::indexOf(IEditor *editor) const
327 {
328     int idx = findEditor(originalForDuplicate(editor));
329     return createIndex(idx, 0);
330 }
331
332 QString OpenEditorsModel::displayNameForFile(IFile *file) const
333 {
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();
337     return QString();
338 }
339
340 void OpenEditorsModel::itemChanged()
341 {
342     emitDataChanged(qobject_cast<IEditor*>(sender()));
343 }
344
345 QList<OpenEditorsModel::Entry> OpenEditorsModel::entries() const
346 {
347     return d->m_editors;
348 }
349
350 IEditor *OpenEditorsModel::editorAt(int row) const
351 {
352     return d->m_editors.at(row).editor;
353 }
354
355 } // namespace Core