1 | /****************************************************************************
|
---|
2 | **
|
---|
3 | ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
|
---|
4 | ** All rights reserved.
|
---|
5 | ** Contact: Nokia Corporation (qt-info@nokia.com)
|
---|
6 | **
|
---|
7 | ** This file is part of the Qt Linguist of the Qt Toolkit.
|
---|
8 | **
|
---|
9 | ** $QT_BEGIN_LICENSE:LGPL$
|
---|
10 | ** Commercial Usage
|
---|
11 | ** Licensees holding valid Qt Commercial licenses may use this file in
|
---|
12 | ** accordance with the Qt Commercial License Agreement provided with the
|
---|
13 | ** Software or, alternatively, in accordance with the terms contained in
|
---|
14 | ** a written agreement between you and Nokia.
|
---|
15 | **
|
---|
16 | ** GNU Lesser General Public License Usage
|
---|
17 | ** Alternatively, this file may be used under the terms of the GNU Lesser
|
---|
18 | ** General Public License version 2.1 as published by the Free Software
|
---|
19 | ** Foundation and appearing in the file LICENSE.LGPL included in the
|
---|
20 | ** packaging of this file. Please review the following information to
|
---|
21 | ** ensure the GNU Lesser General Public License version 2.1 requirements
|
---|
22 | ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
---|
23 | **
|
---|
24 | ** In addition, as a special exception, Nokia gives you certain additional
|
---|
25 | ** rights. These rights are described in the Nokia Qt LGPL Exception
|
---|
26 | ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
---|
27 | **
|
---|
28 | ** GNU General Public License Usage
|
---|
29 | ** Alternatively, this file may be used under the terms of the GNU
|
---|
30 | ** General Public License version 3.0 as published by the Free Software
|
---|
31 | ** Foundation and appearing in the file LICENSE.GPL included in the
|
---|
32 | ** packaging of this file. Please review the following information to
|
---|
33 | ** ensure the GNU General Public License version 3.0 requirements will be
|
---|
34 | ** met: http://www.gnu.org/copyleft/gpl.html.
|
---|
35 | **
|
---|
36 | ** If you have questions regarding the use of this file, please contact
|
---|
37 | ** Nokia at qt-info@nokia.com.
|
---|
38 | ** $QT_END_LICENSE$
|
---|
39 | **
|
---|
40 | ****************************************************************************/
|
---|
41 |
|
---|
42 | #ifndef MESSAGEMODEL_H
|
---|
43 | #define MESSAGEMODEL_H
|
---|
44 |
|
---|
45 | #include "translator.h"
|
---|
46 |
|
---|
47 | #include <QtCore/QAbstractItemModel>
|
---|
48 | #include <QtCore/QList>
|
---|
49 | #include <QtCore/QHash>
|
---|
50 | #include <QtCore/QLocale>
|
---|
51 | #include <QtGui/QColor>
|
---|
52 | #include <QtGui/QBitmap>
|
---|
53 | #include <QtXml/QXmlDefaultHandler>
|
---|
54 |
|
---|
55 |
|
---|
56 | QT_BEGIN_NAMESPACE
|
---|
57 |
|
---|
58 | class DataModel;
|
---|
59 | class MultiDataModel;
|
---|
60 |
|
---|
61 | class MessageItem
|
---|
62 | {
|
---|
63 | public:
|
---|
64 | MessageItem(const TranslatorMessage &message);
|
---|
65 |
|
---|
66 | bool danger() const { return m_danger; }
|
---|
67 | void setDanger(bool danger) { m_danger = danger; }
|
---|
68 |
|
---|
69 | void setTranslation(const QString &translation)
|
---|
70 | { m_message.setTranslation(translation); }
|
---|
71 |
|
---|
72 | QString context() const { return m_message.context(); }
|
---|
73 | QString text() const { return m_message.sourceText(); }
|
---|
74 | QString pluralText() const { return m_message.extra(QLatin1String("po-msgid_plural")); }
|
---|
75 | QString comment() const { return m_message.comment(); }
|
---|
76 | QString fileName() const { return m_message.fileName(); }
|
---|
77 | QString extraComment() const { return m_message.extraComment(); }
|
---|
78 | QString translatorComment() const { return m_message.translatorComment(); }
|
---|
79 | void setTranslatorComment(const QString &cmt) { m_message.setTranslatorComment(cmt); }
|
---|
80 | int lineNumber() const { return m_message.lineNumber(); }
|
---|
81 | QString translation() const { return m_message.translation(); }
|
---|
82 | QStringList translations() const { return m_message.translations(); }
|
---|
83 | void setTranslations(const QStringList &translations)
|
---|
84 | { m_message.setTranslations(translations); }
|
---|
85 |
|
---|
86 | TranslatorMessage::Type type() const { return m_message.type(); }
|
---|
87 | void setType(TranslatorMessage::Type type) { m_message.setType(type); }
|
---|
88 |
|
---|
89 | bool isFinished() const { return type() == TranslatorMessage::Finished; }
|
---|
90 | bool isObsolete() const { return type() == TranslatorMessage::Obsolete; }
|
---|
91 | const TranslatorMessage &message() const { return m_message; }
|
---|
92 |
|
---|
93 | bool compare(const QString &findText, bool matchSubstring,
|
---|
94 | Qt::CaseSensitivity cs) const;
|
---|
95 |
|
---|
96 | private:
|
---|
97 | TranslatorMessage m_message;
|
---|
98 | bool m_danger;
|
---|
99 | };
|
---|
100 |
|
---|
101 |
|
---|
102 | class ContextItem
|
---|
103 | {
|
---|
104 | public:
|
---|
105 | ContextItem(const QString &context);
|
---|
106 |
|
---|
107 | int finishedDangerCount() const { return m_finishedDangerCount; }
|
---|
108 | int unfinishedDangerCount() const { return m_unfinishedDangerCount; }
|
---|
109 |
|
---|
110 | int finishedCount() const { return m_finishedCount; }
|
---|
111 | int unfinishedCount() const { return m_nonobsoleteCount - m_finishedCount; }
|
---|
112 | int nonobsoleteCount() const { return m_nonobsoleteCount; }
|
---|
113 |
|
---|
114 | QString context() const { return m_context; }
|
---|
115 | QString comment() const { return m_comment; }
|
---|
116 | QString fullContext() const { return m_comment.trimmed(); }
|
---|
117 |
|
---|
118 | // For item status in context list
|
---|
119 | bool isObsolete() const { return !nonobsoleteCount(); }
|
---|
120 | bool isFinished() const { return unfinishedCount() == 0; }
|
---|
121 |
|
---|
122 | MessageItem *messageItem(int i) const;
|
---|
123 | int messageCount() const { return msgItemList.count(); }
|
---|
124 |
|
---|
125 | MessageItem *findMessage(const QString &sourcetext, const QString &comment) const;
|
---|
126 |
|
---|
127 | private:
|
---|
128 | friend class DataModel;
|
---|
129 | friend class MultiDataModel;
|
---|
130 | void appendMessage(const MessageItem &msg) { msgItemList.append(msg); }
|
---|
131 | void appendToComment(const QString &x);
|
---|
132 | void incrementFinishedCount() { ++m_finishedCount; }
|
---|
133 | void decrementFinishedCount() { --m_finishedCount; }
|
---|
134 | void incrementFinishedDangerCount() { ++m_finishedDangerCount; }
|
---|
135 | void decrementFinishedDangerCount() { --m_finishedDangerCount; }
|
---|
136 | void incrementUnfinishedDangerCount() { ++m_unfinishedDangerCount; }
|
---|
137 | void decrementUnfinishedDangerCount() { --m_unfinishedDangerCount; }
|
---|
138 | void incrementNonobsoleteCount() { ++m_nonobsoleteCount; }
|
---|
139 |
|
---|
140 | QString m_comment;
|
---|
141 | QString m_context;
|
---|
142 | int m_finishedCount;
|
---|
143 | int m_finishedDangerCount;
|
---|
144 | int m_unfinishedDangerCount;
|
---|
145 | int m_nonobsoleteCount;
|
---|
146 | QList<MessageItem> msgItemList;
|
---|
147 | };
|
---|
148 |
|
---|
149 |
|
---|
150 | class DataIndex
|
---|
151 | {
|
---|
152 | public:
|
---|
153 | DataIndex() : m_context(-1), m_message(-1) {}
|
---|
154 | DataIndex(int context, int message) : m_context(context), m_message(message) {}
|
---|
155 | int context() const { return m_context; }
|
---|
156 | int message() const { return m_message; }
|
---|
157 | bool isValid() const { return m_context >= 0; }
|
---|
158 | protected:
|
---|
159 | int m_context;
|
---|
160 | int m_message;
|
---|
161 | };
|
---|
162 |
|
---|
163 |
|
---|
164 | class DataModelIterator : public DataIndex
|
---|
165 | {
|
---|
166 | public:
|
---|
167 | DataModelIterator(DataModel *model, int contextNo = 0, int messageNo = 0);
|
---|
168 | MessageItem *current() const;
|
---|
169 | bool isValid() const;
|
---|
170 | void operator++();
|
---|
171 | private:
|
---|
172 | DataModelIterator() {}
|
---|
173 | DataModel *m_model; // not owned
|
---|
174 | };
|
---|
175 |
|
---|
176 |
|
---|
177 | class DataModel : public QObject
|
---|
178 | {
|
---|
179 | Q_OBJECT
|
---|
180 | public:
|
---|
181 | DataModel(QObject *parent = 0);
|
---|
182 |
|
---|
183 | enum FindLocation { NoLocation = 0, SourceText = 0x1, Translations = 0x2, Comments = 0x4 };
|
---|
184 |
|
---|
185 | // Specializations
|
---|
186 | int contextCount() const { return m_contextList.count(); }
|
---|
187 | ContextItem *findContext(const QString &context) const;
|
---|
188 | MessageItem *findMessage(const QString &context, const QString &sourcetext,
|
---|
189 | const QString &comment) const;
|
---|
190 |
|
---|
191 | ContextItem *contextItem(int index) const;
|
---|
192 | MessageItem *messageItem(const DataIndex &index) const;
|
---|
193 |
|
---|
194 | int messageCount() const { return m_numMessages; }
|
---|
195 | bool isEmpty() const { return m_numMessages == 0; }
|
---|
196 | bool isModified() const { return m_modified; }
|
---|
197 | void setModified(bool dirty);
|
---|
198 | bool isWritable() const { return m_writable; }
|
---|
199 | void setWritable(bool writable) { m_writable = writable; }
|
---|
200 |
|
---|
201 | bool isWellMergeable(const DataModel *other) const;
|
---|
202 | bool load(const QString &fileName, bool *langGuessed, QWidget *parent);
|
---|
203 | bool save(QWidget *parent) { return save(m_srcFileName, parent); }
|
---|
204 | bool saveAs(const QString &newFileName, QWidget *parent);
|
---|
205 | bool release(const QString &fileName, bool verbose,
|
---|
206 | bool ignoreUnfinished, TranslatorSaveMode mode, QWidget *parent);
|
---|
207 | QString srcFileName(bool pretty = false) const
|
---|
208 | { return pretty ? prettifyPlainFileName(m_srcFileName) : m_srcFileName; }
|
---|
209 |
|
---|
210 | static QString prettifyPlainFileName(const QString &fn);
|
---|
211 | static QString prettifyFileName(const QString &fn);
|
---|
212 |
|
---|
213 | bool setLanguageAndCountry(QLocale::Language lang, QLocale::Country country);
|
---|
214 | QLocale::Language language() const { return m_language; }
|
---|
215 | QLocale::Country country() const { return m_country; }
|
---|
216 | void setSourceLanguageAndCountry(QLocale::Language lang, QLocale::Country country);
|
---|
217 | QLocale::Language sourceLanguage() const { return m_sourceLanguage; }
|
---|
218 | QLocale::Country sourceCountry() const { return m_sourceCountry; }
|
---|
219 |
|
---|
220 | const QString &localizedLanguage() const { return m_localizedLanguage; }
|
---|
221 | const QStringList &numerusForms() const { return m_numerusForms; }
|
---|
222 | const QList<bool> &countRefNeeds() const { return m_countRefNeeds; }
|
---|
223 |
|
---|
224 | QStringList normalizedTranslations(const MessageItem &m) const;
|
---|
225 | void doCharCounting(const QString& text, int& trW, int& trC, int& trCS);
|
---|
226 | void updateStatistics();
|
---|
227 |
|
---|
228 | int getSrcWords() const { return m_srcWords; }
|
---|
229 | int getSrcChars() const { return m_srcChars; }
|
---|
230 | int getSrcCharsSpc() const { return m_srcCharsSpc; }
|
---|
231 |
|
---|
232 | signals:
|
---|
233 | void statsChanged(int words, int characters, int cs, int words2, int characters2, int cs2);
|
---|
234 | void progressChanged(int finishedCount, int oldFinishedCount);
|
---|
235 | void languageChanged();
|
---|
236 | void modifiedChanged();
|
---|
237 |
|
---|
238 | private:
|
---|
239 | friend class DataModelIterator;
|
---|
240 | QList<ContextItem> m_contextList;
|
---|
241 |
|
---|
242 | bool save(const QString &fileName, QWidget *parent);
|
---|
243 | void updateLocale();
|
---|
244 |
|
---|
245 | bool m_writable;
|
---|
246 | bool m_modified;
|
---|
247 |
|
---|
248 | int m_numMessages;
|
---|
249 |
|
---|
250 | // For statistics
|
---|
251 | int m_srcWords;
|
---|
252 | int m_srcChars;
|
---|
253 | int m_srcCharsSpc;
|
---|
254 |
|
---|
255 | QString m_srcFileName;
|
---|
256 | QLocale::Language m_language;
|
---|
257 | QLocale::Language m_sourceLanguage;
|
---|
258 | QLocale::Country m_country;
|
---|
259 | QLocale::Country m_sourceCountry;
|
---|
260 | QByteArray m_codecName;
|
---|
261 | bool m_relativeLocations;
|
---|
262 | Translator::ExtraData m_extra;
|
---|
263 |
|
---|
264 | QString m_localizedLanguage;
|
---|
265 | QStringList m_numerusForms;
|
---|
266 | QList<bool> m_countRefNeeds;
|
---|
267 | };
|
---|
268 |
|
---|
269 |
|
---|
270 | struct MultiMessageItem
|
---|
271 | {
|
---|
272 | public:
|
---|
273 | MultiMessageItem(const MessageItem *m);
|
---|
274 | QString text() const { return m_text; }
|
---|
275 | QString pluralText() const { return m_pluralText; }
|
---|
276 | QString comment() const { return m_comment; }
|
---|
277 | bool isEmpty() const { return !m_nonnullCount; }
|
---|
278 | // The next two include also read-only
|
---|
279 | bool isObsolete() const { return m_nonnullCount && !m_nonobsoleteCount; }
|
---|
280 | int countNonobsolete() const { return m_nonobsoleteCount; }
|
---|
281 | // The next three include only read-write
|
---|
282 | int countEditable() const { return m_editableCount; }
|
---|
283 | bool isUnfinished() const { return m_unfinishedCount != 0; }
|
---|
284 | int countUnfinished() const { return m_unfinishedCount; }
|
---|
285 |
|
---|
286 | private:
|
---|
287 | friend class MultiDataModel;
|
---|
288 | void incrementNonnullCount() { ++m_nonnullCount; }
|
---|
289 | void decrementNonnullCount() { --m_nonnullCount; }
|
---|
290 | void incrementNonobsoleteCount() { ++m_nonobsoleteCount; }
|
---|
291 | void decrementNonobsoleteCount() { --m_nonobsoleteCount; }
|
---|
292 | void incrementEditableCount() { ++m_editableCount; }
|
---|
293 | void decrementEditableCount() { --m_editableCount; }
|
---|
294 | void incrementUnfinishedCount() { ++m_unfinishedCount; }
|
---|
295 | void decrementUnfinishedCount() { --m_unfinishedCount; }
|
---|
296 |
|
---|
297 | QString m_text;
|
---|
298 | QString m_pluralText;
|
---|
299 | QString m_comment;
|
---|
300 | int m_nonnullCount; // all
|
---|
301 | int m_nonobsoleteCount; // all
|
---|
302 | int m_editableCount; // read-write
|
---|
303 | int m_unfinishedCount; // read-write
|
---|
304 | };
|
---|
305 |
|
---|
306 | struct MultiContextItem
|
---|
307 | {
|
---|
308 | public:
|
---|
309 | MultiContextItem(int oldCount, ContextItem *ctx, bool writable);
|
---|
310 |
|
---|
311 | ContextItem *contextItem(int model) const { return m_contextList[model]; }
|
---|
312 |
|
---|
313 | MultiMessageItem *multiMessageItem(int msgIdx) const
|
---|
314 | { return const_cast<MultiMessageItem *>(&m_multiMessageList[msgIdx]); }
|
---|
315 | MessageItem *messageItem(int model, int msgIdx) const { return m_messageLists[model][msgIdx]; }
|
---|
316 | int firstNonobsoleteMessageIndex(int msgIdx) const;
|
---|
317 | int findMessage(const QString &sourcetext, const QString &comment) const;
|
---|
318 |
|
---|
319 | QString context() const { return m_context; }
|
---|
320 | QString comment() const { return m_comment; }
|
---|
321 | int messageCount() const { return m_messageLists.isEmpty() ? 0 : m_messageLists[0].count(); }
|
---|
322 | // For item count in context list
|
---|
323 | int getNumFinished() const { return m_finishedCount; }
|
---|
324 | int getNumEditable() const { return m_editableCount; }
|
---|
325 | // For background in context list
|
---|
326 | bool isObsolete() const { return messageCount() && !m_nonobsoleteCount; }
|
---|
327 |
|
---|
328 | private:
|
---|
329 | friend class MultiDataModel;
|
---|
330 | void appendEmptyModel();
|
---|
331 | void assignLastModel(ContextItem *ctx, bool writable);
|
---|
332 | void removeModel(int pos);
|
---|
333 | void moveModel(int oldPos, int newPos); // newPos is *before* removing at oldPos
|
---|
334 | void putMessageItem(int pos, MessageItem *m);
|
---|
335 | void appendMessageItems(const QList<MessageItem *> &m);
|
---|
336 | void removeMultiMessageItem(int pos);
|
---|
337 | void incrementFinishedCount() { ++m_finishedCount; }
|
---|
338 | void decrementFinishedCount() { --m_finishedCount; }
|
---|
339 | void incrementEditableCount() { ++m_editableCount; }
|
---|
340 | void decrementEditableCount() { --m_editableCount; }
|
---|
341 | void incrementNonobsoleteCount() { ++m_nonobsoleteCount; }
|
---|
342 | void decrementNonobsoleteCount() { --m_nonobsoleteCount; }
|
---|
343 |
|
---|
344 | QString m_context;
|
---|
345 | QString m_comment;
|
---|
346 | QList<MultiMessageItem> m_multiMessageList;
|
---|
347 | QList<ContextItem *> m_contextList;
|
---|
348 | // The next two could be in the MultiMessageItems, but are here for efficiency
|
---|
349 | QList<QList<MessageItem *> > m_messageLists;
|
---|
350 | QList<QList<MessageItem *> *> m_writableMessageLists;
|
---|
351 | int m_finishedCount; // read-write
|
---|
352 | int m_editableCount; // read-write
|
---|
353 | int m_nonobsoleteCount; // all (note: this counts messages, not multi-messages)
|
---|
354 | };
|
---|
355 |
|
---|
356 |
|
---|
357 | class MultiDataIndex
|
---|
358 | {
|
---|
359 | public:
|
---|
360 | MultiDataIndex() : m_model(-1), m_context(-1), m_message(-1) {}
|
---|
361 | MultiDataIndex(int model, int context, int message)
|
---|
362 | : m_model(model), m_context(context), m_message(message) {}
|
---|
363 | void setModel(int model) { m_model = model; }
|
---|
364 | int model() const { return m_model; }
|
---|
365 | int context() const { return m_context; }
|
---|
366 | int message() const { return m_message; }
|
---|
367 | bool isValid() const { return m_context >= 0; }
|
---|
368 | bool operator==(const MultiDataIndex &other) const
|
---|
369 | { return m_model == other.m_model && m_context == other.m_context && m_message == other.m_message; }
|
---|
370 | bool operator!=(const MultiDataIndex &other) const { return !(*this == other); }
|
---|
371 | protected:
|
---|
372 | int m_model;
|
---|
373 | int m_context;
|
---|
374 | int m_message;
|
---|
375 | };
|
---|
376 |
|
---|
377 |
|
---|
378 | class MultiDataModelIterator : public MultiDataIndex
|
---|
379 | {
|
---|
380 | public:
|
---|
381 | MultiDataModelIterator(MultiDataModel *model, int modelNo, int contextNo = 0, int messageNo = 0);
|
---|
382 | MessageItem *current() const;
|
---|
383 | bool isValid() const;
|
---|
384 | void operator++();
|
---|
385 | private:
|
---|
386 | MultiDataModelIterator() {}
|
---|
387 | MultiDataModel *m_dataModel; // not owned
|
---|
388 | };
|
---|
389 |
|
---|
390 |
|
---|
391 | class MessageModel;
|
---|
392 |
|
---|
393 | class MultiDataModel : public QObject
|
---|
394 | {
|
---|
395 | Q_OBJECT
|
---|
396 |
|
---|
397 | public:
|
---|
398 | MultiDataModel(QObject *parent = 0);
|
---|
399 | ~MultiDataModel();
|
---|
400 |
|
---|
401 | bool isWellMergeable(const DataModel *dm) const;
|
---|
402 | void append(DataModel *dm, bool readWrite);
|
---|
403 | bool save(int model, QWidget *parent) { return m_dataModels[model]->save(parent); }
|
---|
404 | bool saveAs(int model, const QString &newFileName, QWidget *parent)
|
---|
405 | { return m_dataModels[model]->saveAs(newFileName, parent); }
|
---|
406 | bool release(int model, const QString &fileName, bool verbose, bool ignoreUnfinished, TranslatorSaveMode mode, QWidget *parent)
|
---|
407 | { return m_dataModels[model]->release(fileName, verbose, ignoreUnfinished, mode, parent); }
|
---|
408 | void close(int model);
|
---|
409 | void closeAll();
|
---|
410 | int isFileLoaded(const QString &name) const;
|
---|
411 | void moveModel(int oldPos, int newPos); // newPos is *before* removing at oldPos; note that this does not emit update signals
|
---|
412 |
|
---|
413 | // Entire multi-model
|
---|
414 | int modelCount() const { return m_dataModels.count(); }
|
---|
415 | int contextCount() const { return m_multiContextList.count(); }
|
---|
416 | int messageCount() const { return m_numMessages; }
|
---|
417 | // Next two needed for progress indicator in main window
|
---|
418 | int getNumFinished() const { return m_numFinished; }
|
---|
419 | int getNumEditable() const { return m_numEditable; }
|
---|
420 | bool isModified() const;
|
---|
421 | QStringList srcFileNames(bool pretty = false) const;
|
---|
422 | QString condensedSrcFileNames(bool pretty = false) const;
|
---|
423 |
|
---|
424 | // Per submodel
|
---|
425 | QString srcFileName(int model, bool pretty = false) const { return m_dataModels[model]->srcFileName(pretty); }
|
---|
426 | bool isModelWritable(int model) const { return m_dataModels[model]->isWritable(); }
|
---|
427 | bool isModified(int model) const { return m_dataModels[model]->isModified(); }
|
---|
428 | void setModified(int model, bool dirty) { m_dataModels[model]->setModified(dirty); }
|
---|
429 | QLocale::Language language(int model) const { return m_dataModels[model]->language(); }
|
---|
430 | QLocale::Language sourceLanguage(int model) const { return m_dataModels[model]->sourceLanguage(); }
|
---|
431 |
|
---|
432 | // Per message
|
---|
433 | void setTranslation(const MultiDataIndex &index, const QString &translation);
|
---|
434 | void setFinished(const MultiDataIndex &index, bool finished);
|
---|
435 | void setDanger(const MultiDataIndex &index, bool danger);
|
---|
436 |
|
---|
437 | // Retrieve items
|
---|
438 | DataModel *model(int i) { return m_dataModels[i]; }
|
---|
439 | MultiContextItem *multiContextItem(int ctxIdx) const
|
---|
440 | { return const_cast<MultiContextItem *>(&m_multiContextList[ctxIdx]); }
|
---|
441 | MultiMessageItem *multiMessageItem(const MultiDataIndex &index) const
|
---|
442 | { return multiContextItem(index.context())->multiMessageItem(index.message()); }
|
---|
443 | MessageItem *messageItem(const MultiDataIndex &index, int model) const;
|
---|
444 | MessageItem *messageItem(const MultiDataIndex &index) const { return messageItem(index, index.model()); }
|
---|
445 |
|
---|
446 | static QString condenseFileNames(const QStringList &names);
|
---|
447 | static QStringList prettifyFileNames(const QStringList &names);
|
---|
448 |
|
---|
449 | QBrush brushForModel(int model) const;
|
---|
450 |
|
---|
451 | signals:
|
---|
452 | void modelAppended();
|
---|
453 | void modelDeleted(int model);
|
---|
454 | void allModelsDeleted();
|
---|
455 | void languageChanged(int model);
|
---|
456 | void statsChanged(int words, int characters, int cs, int words2, int characters2, int cs2);
|
---|
457 | void modifiedChanged(bool);
|
---|
458 | void multiContextDataChanged(const MultiDataIndex &index);
|
---|
459 | void contextDataChanged(const MultiDataIndex &index);
|
---|
460 | void messageDataChanged(const MultiDataIndex &index);
|
---|
461 | void translationChanged(const MultiDataIndex &index); // Only the primary one
|
---|
462 |
|
---|
463 | private slots:
|
---|
464 | void onModifiedChanged();
|
---|
465 | void onLanguageChanged();
|
---|
466 |
|
---|
467 | private:
|
---|
468 | friend class MultiDataModelIterator;
|
---|
469 | friend class MessageModel;
|
---|
470 |
|
---|
471 | int findContextIndex(const QString &context) const;
|
---|
472 | MultiContextItem *findContext(const QString &context) const;
|
---|
473 |
|
---|
474 | ContextItem *contextItem(const MultiDataIndex &index) const
|
---|
475 | { return multiContextItem(index.context())->contextItem(index.model()); }
|
---|
476 |
|
---|
477 | void updateCountsOnAdd(int model, bool writable);
|
---|
478 | void updateCountsOnRemove(int model, bool writable);
|
---|
479 | void incrementFinishedCount() { ++m_numFinished; }
|
---|
480 | void decrementFinishedCount() { --m_numFinished; }
|
---|
481 | void incrementEditableCount() { ++m_numEditable; }
|
---|
482 | void decrementEditableCount() { --m_numEditable; }
|
---|
483 |
|
---|
484 | int m_numFinished;
|
---|
485 | int m_numEditable;
|
---|
486 | int m_numMessages;
|
---|
487 |
|
---|
488 | bool m_modified;
|
---|
489 |
|
---|
490 | QList<MultiContextItem> m_multiContextList;
|
---|
491 | QList<DataModel *> m_dataModels;
|
---|
492 |
|
---|
493 | MessageModel *m_msgModel;
|
---|
494 |
|
---|
495 | QColor m_colors[7];
|
---|
496 | QBitmap m_bitmap;
|
---|
497 | };
|
---|
498 |
|
---|
499 | class MessageModel : public QAbstractItemModel
|
---|
500 | {
|
---|
501 | Q_OBJECT
|
---|
502 |
|
---|
503 | public:
|
---|
504 | enum { SortRole = Qt::UserRole };
|
---|
505 |
|
---|
506 | MessageModel(QObject *parent, MultiDataModel *data);
|
---|
507 |
|
---|
508 | // QAbstractItemModel
|
---|
509 | QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const;
|
---|
510 | QModelIndex parent(const QModelIndex& index) const;
|
---|
511 | int rowCount(const QModelIndex &parent = QModelIndex()) const;
|
---|
512 | int columnCount(const QModelIndex &parent = QModelIndex()) const;
|
---|
513 | QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
|
---|
514 |
|
---|
515 | // Convenience
|
---|
516 | MultiDataIndex dataIndex(const QModelIndex &index, int model) const;
|
---|
517 | MultiDataIndex dataIndex(const QModelIndex &index) const
|
---|
518 | { return dataIndex(index, index.column() - 1 < m_data->modelCount() ? index.column() - 1 : -1); }
|
---|
519 | QModelIndex modelIndex(const MultiDataIndex &index);
|
---|
520 |
|
---|
521 | private slots:
|
---|
522 | void reset() { QAbstractItemModel::reset(); }
|
---|
523 | void multiContextItemChanged(const MultiDataIndex &index);
|
---|
524 | void contextItemChanged(const MultiDataIndex &index);
|
---|
525 | void messageItemChanged(const MultiDataIndex &index);
|
---|
526 |
|
---|
527 | private:
|
---|
528 | friend class MultiDataModel;
|
---|
529 |
|
---|
530 | MultiDataModel *m_data; // not owned
|
---|
531 | };
|
---|
532 |
|
---|
533 | QT_END_NAMESPACE
|
---|
534 |
|
---|
535 | #endif // MESSAGEMODEL_H
|
---|