• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdesdk API Reference
  • KDE Home
  • Contact Us
 

lokalize

  • sources
  • kde-4.14
  • kdesdk
  • lokalize
  • src
  • cataloglistview
catalogmodel.cpp
Go to the documentation of this file.
1 /* ****************************************************************************
2  This file is part of Lokalize
3 
4  Copyright (C) 2007-2013 by Nick Shaforostoff <shafff@ukr.net>
5 
6  This program is free software; you can redistribute it and/or
7  modify it under the terms of the GNU General Public License as
8  published by the Free Software Foundation; either version 2 of
9  the License or (at your option) version 3 or any later version
10  accepted by the membership of KDE e.V. (or its successor approved
11  by the membership of KDE e.V.), which shall act as a proxy
12  defined in Section 14 of version 3 of the license.
13 
14  This program is distributed in the hope that it will be useful,
15  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  GNU General Public License for more details.
18 
19  You should have received a copy of the GNU General Public License
20  along with this program. If not, see <http://www.gnu.org/licenses/>.
21 
22 **************************************************************************** */
23 
24 #include "catalogmodel.h"
25 
26 #include "catalog.h"
27 #include "project.h"
28 
29 #include <kdebug.h>
30 #include <klocale.h>
31 
32 #include <QApplication>
33 #include <QFontMetrics>
34 #include <kcolorscheme.h>
35 
36 #define DYNAMICFILTER_LIMIT 256
37 
38 QVector<QVariant> CatalogTreeModel::m_fonts;
39 
40 
41 CatalogTreeModel::CatalogTreeModel(QObject* parent, Catalog* catalog)
42  : QAbstractItemModel(parent)
43  , m_catalog(catalog)
44  , m_ignoreAccel(true)
45 {
46  if (m_fonts.isEmpty())
47  {
48  QVector<QFont> fonts(4, QApplication::font());
49  fonts[1].setItalic(true); //fuzzy
50 
51  fonts[2].setBold(true); //modified
52 
53  fonts[3].setItalic(true); //fuzzy
54  fonts[3].setBold(true); //modified
55 
56  m_fonts.reserve(4);
57  for(int i=0;i<4;i++) m_fonts<<fonts.at(i);
58  }
59  connect(catalog,SIGNAL(signalEntryModified(DocPosition)),this,SLOT(reflectChanges(DocPosition)));
60  connect(catalog,SIGNAL(signalFileLoaded()),this,SLOT(fileLoaded()));
61 }
62 
63 QModelIndex CatalogTreeModel::index(int row,int column,const QModelIndex& /*parent*/) const
64 {
65  return createIndex(row, column);
66 }
67 
68 QModelIndex CatalogTreeModel::parent(const QModelIndex& /*index*/) const
69 {
70  return QModelIndex();
71 }
72 
73 int CatalogTreeModel::columnCount(const QModelIndex& parent) const
74 {
75  Q_UNUSED(parent);
76  return DisplayedColumnCount;
77 }
78 
79 void CatalogTreeModel::fileLoaded()
80 {
81  reset();
82 }
83 
84 void CatalogTreeModel::reflectChanges(DocPosition pos)
85 {
86  emit dataChanged(index(pos.entry,0),index(pos.entry,DisplayedColumnCount-1));
87 
88 #if 0
89  I disabled dynamicSortFilter function
90  //lazy sorting/filtering
91  if (rowCount()<DYNAMICFILTER_LIMIT || m_prevChanged!=pos)
92  {
93  kWarning()<<"first dataChanged emitment"<<pos.entry;
94  emit dataChanged(index(pos.entry,0),index(pos.entry,DisplayedColumnCount-1));
95  if (!( rowCount()<DYNAMICFILTER_LIMIT ))
96  {
97  kWarning()<<"second dataChanged emitment"<<m_prevChanged.entry;
98  emit dataChanged(index(m_prevChanged.entry,0),index(m_prevChanged.entry,DisplayedColumnCount-1));
99  }
100  }
101  m_prevChanged=pos;
102 #endif
103 }
104 
105 int CatalogTreeModel::rowCount(const QModelIndex& parent) const
106 {
107  if (parent.isValid())
108  return 0;
109  return m_catalog->numberOfEntries();
110 }
111 
112 QVariant CatalogTreeModel::headerData(int section, Qt::Orientation /*orientation*/, int role) const
113 {
114  if (role!=Qt::DisplayRole)
115  return QVariant();
116 
117  switch (section)
118  {
119  case Key: return i18nc("@title:column","Entry");
120  case Source: return i18nc("@title:column Original text","Source");
121  case Target: return i18nc("@title:column Text in target language","Target");
122  case Notes: return i18nc("@title:column","Notes");
123  case TranslationStatus: return i18nc("@title:column","Translation Status");
124  }
125  return QVariant();
126 }
127 
128 QVariant CatalogTreeModel::data(const QModelIndex& index, int role) const
129 {
130  if (m_catalog->numberOfEntries()<=index.row() )
131  return QVariant();
132 
133  if (role==Qt::SizeHintRole)
134  {
135  //no need to cache because of uniform row heights
136  return QFontMetrics(QApplication::font()).size(Qt::TextSingleLine, QString::fromLatin1(" "));
137  }
138  else if (role==Qt::FontRole/* && index.column()==Target*/)
139  {
140  bool fuzzy=!m_catalog->isApproved(index.row());
141  bool modified=m_catalog->isModified(index.row());
142  return m_fonts.at(fuzzy*1 | modified*2);
143  }
144  else if (role==Qt::ForegroundRole)
145  {
146  if (m_catalog->isBookmarked(index.row()))
147  {
148  static KColorScheme colorScheme(QPalette::Normal);
149  return colorScheme.foreground(KColorScheme::LinkText);
150  }
151  if (m_catalog->isObsolete(index.row()))
152  {
153  static KColorScheme colorScheme(QPalette::Normal);
154  return colorScheme.foreground(KColorScheme::InactiveText);
155  }
156  }
157  else if (role==Qt::UserRole)
158  {
159  switch (index.column())
160  {
161  case TranslationStatus: return m_catalog->isApproved(index.row());
162  case Empty: return m_catalog->isEmpty(index.row());
163  case State: return int(m_catalog->state(index.row()));
164  case Modified: return m_catalog->isModified(index.row());
165  default: role=Qt::DisplayRole;
166  }
167  }
168  else if (role==StringFilterRole) //exclude UI strings
169  {
170  if (index.column()>Notes)
171  return QVariant();
172  else if (index.column()) //>Key
173  {
174  static const DocPosition::Part parts[]={DocPosition::Source, DocPosition::Target};
175  QString str=m_catalog->catalogString(DocPosition(index.row(),parts[index.column()==Target])).string;
176  return m_ignoreAccel?str.remove(Project::instance()->accel()):str;
177  }
178  role=Qt::DisplayRole;
179  }
180  if (role!=Qt::DisplayRole)
181  return QVariant();
182 
183 
184 
185  switch (index.column())
186  {
187  case Key: return index.row()+1;
188  case Source: return m_catalog->msgid(index.row());
189  case Target: return m_catalog->msgstr(index.row());
190  case Notes:
191  {
192  QString result;
193  foreach(const Note &note, m_catalog->notes(index.row()))
194  result+=note.content;
195  return result;
196  }
197  case TranslationStatus:
198  static QString statuses[]={i18nc("@info:status 'non-fuzzy' in gettext terminology","Ready"),
199  i18nc("@info:status 'fuzzy' in gettext terminology","Needs review"),
200  i18nc("@info:status","Untranslated")};
201  if (m_catalog->isEmpty(index.row()))
202  return statuses[2];
203  return statuses[!m_catalog->isApproved(index.row())];
204  }
205  return QVariant();
206 }
207 
208 CatalogTreeFilterModel::CatalogTreeFilterModel(QObject* parent)
209  : QSortFilterProxyModel(parent)
210  , m_filerOptions(AllStates)
211  , m_individualRejectFilterEnable(false)
212  , m_mergeCatalog(NULL)
213 {
214  setFilterKeyColumn(-1);
215  setFilterCaseSensitivity(Qt::CaseInsensitive);
216  setFilterRole(CatalogTreeModel::StringFilterRole);
217  //setDynamicSortFilter(true);
218 }
219 
220 void CatalogTreeFilterModel::setSourceModel(QAbstractItemModel* sourceModel)
221 {
222  QSortFilterProxyModel::setSourceModel(sourceModel);
223  connect(sourceModel,SIGNAL(modelReset()),SLOT(setEntriesFilteredOut()));
224  setEntriesFilteredOut(false);
225 }
226 
227 void CatalogTreeFilterModel::setEntriesFilteredOut(bool filteredOut)
228 {
229  m_individualRejectFilter.fill(filteredOut, sourceModel()->rowCount());
230  m_individualRejectFilterEnable=filteredOut;
231  invalidateFilter();
232 }
233 
234 void CatalogTreeFilterModel::setEntryFilteredOut(int entry, bool filteredOut)
235 {
236 // if (entry>=m_individualRejectFilter.size())
237 // sourceModelReset();
238  m_individualRejectFilter[entry]=filteredOut;
239  m_individualRejectFilterEnable=true;
240  invalidateFilter();
241 }
242 
243 void CatalogTreeFilterModel::setFilerOptions(int o)
244 {
245  m_filerOptions=o;
246  setFilterCaseSensitivity(o&CaseInsensitive?Qt::CaseInsensitive:Qt::CaseSensitive);
247  static_cast<CatalogTreeModel*>(sourceModel())->setIgnoreAccel(o&IgnoreAccel);
248  invalidateFilter();
249 }
250 
251 bool CatalogTreeFilterModel::filterAcceptsRow(int source_row, const QModelIndex& source_parent) const
252 {
253  int filerOptions=m_filerOptions;
254  bool accepts=true;
255  if (bool(filerOptions&Ready)!=bool(filerOptions&NotReady))
256  {
257  bool ready=sourceModel()->index(source_row,CatalogTreeModel::TranslationStatus,source_parent).data(Qt::UserRole).toBool();
258  accepts=(ready==bool(filerOptions&Ready) || ready!=bool(filerOptions&NotReady));
259  }
260  if (accepts&&bool(filerOptions&NonEmpty)!=bool(filerOptions&Empty))
261  {
262  bool untr=sourceModel()->index(source_row,CatalogTreeModel::Empty,source_parent).data(Qt::UserRole).toBool();
263  accepts=(untr==bool(filerOptions&Empty) || untr!=bool(filerOptions&NonEmpty));
264  }
265  if (accepts&&bool(filerOptions&Modified)!=bool(filerOptions&NonModified))
266  {
267  bool modified=sourceModel()->index(source_row,CatalogTreeModel::Modified,source_parent).data(Qt::UserRole).toBool();
268  accepts=(modified==bool(filerOptions&Modified) || modified!=bool(filerOptions&NonModified));
269  }
270 
271  // These are the possible sync options of a row:
272  // * SameInSync: The sync file contains a row with the same msgid and the same msgstr.
273  // * DifferentInSync: The sync file contains a row with the same msgid and different msgstr.
274  // * NotInSync: The sync file does not contain any row with the same msgid.
275  //
276  // The code below takes care of filtering rows when any of those options is not checked.
277  //
278  const int mask=(SameInSync|DifferentInSync|NotInSync);
279  if (accepts && m_mergeCatalog && (filerOptions&mask) && (filerOptions&mask)!=mask)
280  {
281  bool isPresent = m_mergeCatalog->isPresent(source_row);
282  bool isDifferent = m_mergeCatalog->isDifferent(source_row);
283 
284  accepts = !
285  ( isPresent && !isDifferent && !bool(filerOptions&SameInSync) ||
286  isPresent && isDifferent && !bool(filerOptions&DifferentInSync) ||
287  !isPresent && !bool(filerOptions&NotInSync)
288  );
289  }
290 
291  if (accepts && (filerOptions&STATES)!=STATES)
292  {
293  int state=sourceModel()->index(source_row,CatalogTreeModel::State,source_parent).data(Qt::UserRole).toInt();
294  accepts=(filerOptions&(1<<(state+FIRSTSTATEPOSITION)));
295  }
296 
297  accepts=accepts&&!(m_individualRejectFilterEnable && source_row<m_individualRejectFilter.size() && m_individualRejectFilter.at(source_row));
298 
299  return accepts&&QSortFilterProxyModel::filterAcceptsRow(source_row,source_parent);
300 }
301 
302 void CatalogTreeFilterModel::setMergeCatalogPointer(MergeCatalog* pointer)
303 {
304  m_mergeCatalog = pointer;
305 }
catalogmodel.h
QModelIndex
MergeCatalog
Merge source container.
Definition: mergecatalog.h:71
project.h
CatalogTreeFilterModel::SameInSync
Definition: catalogmodel.h:112
QSortFilterProxyModel::setFilterCaseSensitivity
void setFilterCaseSensitivity(Qt::CaseSensitivity cs)
QAbstractItemModel::index
virtual QModelIndex index(int row, int column, const QModelIndex &parent) const =0
CatalogTreeModel::headerData
QVariant headerData(int section, Qt::Orientation, int role=Qt::DisplayRole) const
Definition: catalogmodel.cpp:112
DocPosition::Target
Definition: pos.h:44
DocPosition::Part
Part
Definition: pos.h:40
QSortFilterProxyModel::setSourceModel
virtual void setSourceModel(QAbstractItemModel *sourceModel)
CatalogTreeModel::TranslationStatus
Definition: catalogmodel.h:52
QVector::fill
QVector< T > & fill(const T &value, int size)
Project::instance
static Project * instance()
Definition: project.cpp:67
CatalogTreeModel::data
QVariant data(const QModelIndex &, int role=Qt::DisplayRole) const
Definition: catalogmodel.cpp:128
CatalogTreeFilterModel::Modified
Definition: catalogmodel.h:110
MergeCatalog::isPresent
bool isPresent(const short int &entry) const
whether 'merge source' has entry with such msgid
Definition: mergecatalog.cpp:110
Note
Definition: note.h:29
CatalogTreeFilterModel::setMergeCatalogPointer
void setMergeCatalogPointer(MergeCatalog *pointer)
Definition: catalogmodel.cpp:302
QAbstractItemModel::modelReset
void modelReset()
QFontMetrics
CatalogString::string
QString string
Definition: catalogstring.h:130
QString::remove
QString & remove(int position, int n)
Catalog::catalogString
CatalogString catalogString(const DocPosition &pos) const
Definition: catalog.cpp:219
CatalogTreeFilterModel::IgnoreAccel
Definition: catalogmodel.h:104
CatalogTreeModel::Source
Definition: catalogmodel.h:49
CatalogTreeModel::Target
Definition: catalogmodel.h:50
Catalog::isEmpty
bool isEmpty(uint index) const
Definition: catalog.cpp:432
QSortFilterProxyModel::rowCount
virtual int rowCount(const QModelIndex &parent) const
CatalogTreeModel::reflectChanges
void reflectChanges(DocPosition)
Definition: catalogmodel.cpp:84
Catalog::isModified
bool isModified(DocPos entry) const
Definition: catalog.cpp:928
DocPosition::entry
int entry
Definition: pos.h:48
CatalogTreeModel::index
QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const
Definition: catalogmodel.cpp:63
DocPosition
This struct represents a position in a catalog.
Definition: pos.h:38
CatalogTreeModel::rowCount
int rowCount(const QModelIndex &parent=QModelIndex()) const
Definition: catalogmodel.cpp:105
CatalogTreeModel::StringFilterRole
Definition: catalogmodel.h:62
QAbstractItemModel::reset
void reset()
QModelIndex::isValid
bool isValid() const
QSortFilterProxyModel::setFilterRole
void setFilterRole(int role)
MergeCatalog::isDifferent
int isDifferent(uint index) const
Definition: mergecatalog.h:84
QApplication::font
QFont font()
QVariant::toInt
int toInt(bool *ok) const
QAbstractItemModel::dataChanged
void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight)
CatalogTreeModel::Empty
Definition: catalogmodel.h:53
CatalogTreeFilterModel::setSourceModel
void setSourceModel(QAbstractItemModel *sourceModel)
Definition: catalogmodel.cpp:220
QObject
catalog.h
STATES
#define STATES
Definition: catalogmodel.h:131
Catalog::isObsolete
bool isObsolete(int entry) const
Definition: catalog.cpp:1015
CatalogTreeFilterModel::CatalogTreeFilterModel
CatalogTreeFilterModel(QObject *parent)
Definition: catalogmodel.cpp:208
Catalog::isBookmarked
bool isBookmarked(uint index) const
Definition: catalog.h:147
CatalogTreeModel::Modified
Definition: catalogmodel.h:55
CatalogTreeFilterModel::setFilerOptions
void setFilerOptions(int o)
Definition: catalogmodel.cpp:243
QModelIndex::row
int row() const
CatalogTreeModel
MVC wrapper for Catalog.
Definition: catalogmodel.h:41
QSortFilterProxyModel::invalidateFilter
void invalidateFilter()
FIRSTSTATEPOSITION
#define FIRSTSTATEPOSITION
Definition: catalogmodel.h:132
CatalogTreeModel::columnCount
int columnCount(const QModelIndex &parent=QModelIndex()) const
Definition: catalogmodel.cpp:73
CatalogTreeFilterModel::setEntriesFilteredOut
void setEntriesFilteredOut(bool filteredOut=false)
Definition: catalogmodel.cpp:227
DYNAMICFILTER_LIMIT
#define DYNAMICFILTER_LIMIT
Definition: catalogmodel.cpp:36
QString
CatalogTreeModel::State
Definition: catalogmodel.h:54
CatalogTreeFilterModel::filerOptions
int filerOptions() const
Definition: catalogmodel.h:141
QAbstractItemModel::createIndex
QModelIndex createIndex(int row, int column, void *ptr) const
QVector::reserve
void reserve(int size)
CatalogTreeModel::Notes
Definition: catalogmodel.h:51
QSortFilterProxyModel
CatalogTreeFilterModel::NotReady
Definition: catalogmodel.h:107
Catalog::msgid
QString msgid(const DocPosition &) const
Definition: catalog.cpp:187
Note::content
QString content
Definition: note.h:33
QSortFilterProxyModel::filterAcceptsRow
virtual bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const
QVector::at
const T & at(int i) const
QAbstractProxyModel::sourceModel
QAbstractItemModel * sourceModel() const
QVector< QVariant >
QModelIndex::data
QVariant data(int role) const
CatalogTreeFilterModel::filterAcceptsRow
bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const
Definition: catalogmodel.cpp:251
QVector::isEmpty
bool isEmpty() const
CatalogTreeModel::Key
Definition: catalogmodel.h:48
DocPosition::Source
Definition: pos.h:43
Catalog::isApproved
bool isApproved(uint index) const
Definition: catalog.cpp:410
CatalogTreeFilterModel::Ready
Definition: catalogmodel.h:106
CatalogTreeModel::fileLoaded
void fileLoaded()
Definition: catalogmodel.cpp:79
Catalog::numberOfEntries
int numberOfEntries() const
Definition: catalog.cpp:171
QModelIndex::column
int column() const
QVariant::toBool
bool toBool() const
CatalogTreeModel::CatalogTreeModel
CatalogTreeModel(QObject *parent, Catalog *catalog)
Definition: catalogmodel.cpp:41
QAbstractItemModel
QString::fromLatin1
QString fromLatin1(const char *str, int size)
Catalog
This class represents a catalog It uses CatalogStorage interface to work with catalogs in different f...
Definition: catalog.h:74
Catalog::state
TargetState state(const DocPosition &pos) const
Definition: catalog.cpp:421
QFontMetrics::size
QSize size(int flags, const QString &text, int tabStops, int *tabArray) const
CatalogTreeFilterModel::NonEmpty
Definition: catalogmodel.h:108
Catalog::notes
QVector< Note > notes(const DocPosition &pos) const
Definition: catalog.cpp:228
CatalogTreeFilterModel::DifferentInSync
Definition: catalogmodel.h:113
CatalogTreeFilterModel::Empty
Definition: catalogmodel.h:109
QObject::connect
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
QObject::parent
QObject * parent() const
QVector::size
int size() const
Catalog::msgstr
virtual QString msgstr(const DocPosition &) const
Definition: catalog.cpp:195
CatalogTreeFilterModel::NotInSync
Definition: catalogmodel.h:114
CatalogTreeModel::DisplayedColumnCount
Definition: catalogmodel.h:57
QSortFilterProxyModel::setFilterKeyColumn
void setFilterKeyColumn(int column)
CatalogTreeFilterModel::CaseInsensitive
Definition: catalogmodel.h:103
CatalogTreeFilterModel::setEntryFilteredOut
void setEntryFilteredOut(int entry, bool filteredOut)
Definition: catalogmodel.cpp:234
QVariant
CatalogTreeFilterModel::NonModified
Definition: catalogmodel.h:111
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Mon Jun 22 2020 13:40:06 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

lokalize

Skip menu "lokalize"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members

kdesdk API Reference

Skip menu "kdesdk API Reference"
  • kapptemplate
  • kcachegrind
  • kompare
  • lokalize
  • umbrello
  •   umbrello

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal