diff --git a/src/cataloglistview/cataloglistview.cpp b/src/cataloglistview/cataloglistview.cpp index a6f7162..564647a 100644 --- a/src/cataloglistview/cataloglistview.cpp +++ b/src/cataloglistview/cataloglistview.cpp @@ -1,315 +1,329 @@ /* **************************************************************************** This file is part of Lokalize Copyright (C) 2007-2009 by Nick Shaforostoff This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License or (at your option) version 3 or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 14 of version 3 of the license. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . **************************************************************************** */ #include "cataloglistview.h" #include "lokalize_debug.h" #include "catalogmodel.h" #include "catalog.h" #include "project.h" #include "prefs.h" #include "headerviewmenu.h" #include #include #include #include #include #include #include #include #include #include #include #include #include class CatalogTreeView: public QTreeView { public: CatalogTreeView(QWidget * parent) : QTreeView(parent) {} ~CatalogTreeView() {} protected: void keyReleaseEvent(QKeyEvent *e) override { if (e->key() == Qt::Key_Return && currentIndex().isValid()) { emit clicked(currentIndex()); e->accept(); } else { QTreeView::keyReleaseEvent(e); } } }; CatalogView::CatalogView(QWidget* parent, Catalog* catalog) : QDockWidget(i18nc("@title:window aka Message Tree", "Translation Units"), parent) , m_browser(new CatalogTreeView(this)) , m_lineEdit(new QLineEdit(this)) , m_model(new CatalogTreeModel(this, catalog)) , m_proxyModel(new CatalogTreeFilterModel(this)) { setObjectName(QStringLiteral("catalogTreeView")); QWidget* w = new QWidget(this); QVBoxLayout* layout = new QVBoxLayout(w); layout->setContentsMargins(0, 0, 0, 0); QHBoxLayout* l = new QHBoxLayout; l->setContentsMargins(0, 0, 0, 0); l->setSpacing(0); layout->addLayout(l); m_lineEdit->setClearButtonEnabled(true); m_lineEdit->setPlaceholderText(i18n("Quick search...")); m_lineEdit->setToolTip(i18nc("@info:tooltip", "Activated by Ctrl+L.") + ' ' + i18nc("@info:tooltip", "Accepts regular expressions")); connect(m_lineEdit, &QLineEdit::textChanged, this, &CatalogView::setFilterRegExp, Qt::QueuedConnection); // QShortcut* ctrlEsc=new QShortcut(QKeySequence(Qt::META+Qt::Key_Escape),this,SLOT(reset()),0,Qt::WidgetWithChildrenShortcut); QShortcut* esc = new QShortcut(QKeySequence(Qt::Key_Escape), this, 0, 0, Qt::WidgetWithChildrenShortcut); connect(esc, &QShortcut::activated, this, &CatalogView::escaped); QToolButton* btn = new QToolButton(w); btn->setPopupMode(QToolButton::InstantPopup); btn->setText(i18n("options")); //btn->setArrowType(Qt::DownArrow); btn->setMenu(new QMenu(this)); m_filterOptionsMenu = btn->menu(); connect(m_filterOptionsMenu, &QMenu::aboutToShow, this, &CatalogView::fillFilterOptionsMenu); connect(m_filterOptionsMenu, &QMenu::triggered, this, &CatalogView::filterOptionToggled); l->addWidget(m_lineEdit); l->addWidget(btn); layout->addWidget(m_browser); setTabOrder(m_lineEdit, btn); setTabOrder(btn, m_browser); setFocusProxy(m_lineEdit); setWidget(w); connect(m_browser, &CatalogTreeView::clicked, this, &CatalogView::slotItemActivated); m_browser->setRootIsDecorated(false); m_browser->setAllColumnsShowFocus(true); m_browser->setAlternatingRowColors(true); m_browser->viewport()->setBackgroundRole(QPalette::Background); #ifdef Q_OS_DARWIN QPalette p; p.setColor(QPalette::AlternateBase, p.color(QPalette::Background).darker(110)); p.setColor(QPalette::Highlight, p.color(QPalette::Background).darker(150)); m_browser->setPalette(p); #endif m_proxyModel->setSourceModel(m_model); m_browser->setModel(m_proxyModel); m_browser->setColumnWidth(0, m_browser->columnWidth(0) / 3); m_browser->setSortingEnabled(true); m_browser->sortByColumn(0, Qt::AscendingOrder); m_browser->setWordWrap(false); m_browser->setUniformRowHeights(true); m_browser->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel); new HeaderViewMenuHandler(m_browser->header()); m_browser->header()->restoreState(readUiState("CatalogTreeViewState")); } CatalogView::~CatalogView() { writeUiState("CatalogTreeViewState", m_browser->header()->saveState()); } void CatalogView::setFocus() { QDockWidget::setFocus(); m_lineEdit->selectAll(); } void CatalogView::slotNewEntryDisplayed(const DocPosition& pos) { QModelIndex item = m_proxyModel->mapFromSource(m_model->index(pos.entry, 0)); m_browser->setCurrentIndex(item); m_browser->scrollTo(item/*,QAbstractItemView::PositionAtCenter*/); + m_lastKnownDocPosition = pos.entry; } void CatalogView::setFilterRegExp() { QString expr = m_lineEdit->text(); if (m_proxyModel->filterRegExp().pattern() != expr) - m_proxyModel->setFilterRegExp(m_proxyModel->filerOptions()&CatalogTreeFilterModel::IgnoreAccel ? expr.remove(Project::instance()->accel()) : expr); + m_proxyModel->setFilterRegExp(m_proxyModel->filterOptions()&CatalogTreeFilterModel::IgnoreAccel ? expr.remove(Project::instance()->accel()) : expr); + refreshCurrentIndex(); +} + +void CatalogView::refreshCurrentIndex() +{ + QModelIndex newPositionOfSelectedItem = m_proxyModel->mapFromSource(m_model->index(m_lastKnownDocPosition, 0)); + m_browser->setCurrentIndex(newPositionOfSelectedItem); + m_browser->scrollTo(newPositionOfSelectedItem); } void CatalogView::slotItemActivated(const QModelIndex& idx) { emit gotoEntry(DocPosition(m_proxyModel->mapToSource(idx).row()), 0); } void CatalogView::filterOptionToggled(QAction* action) { if (action->data().isNull()) return; int opt = action->data().toInt(); if (opt > 0) - m_proxyModel->setFilerOptions(m_proxyModel->filerOptions()^opt); + m_proxyModel->setFilterOptions(m_proxyModel->filterOptions()^opt); else { if (opt != -1) opt = -opt - 2; m_proxyModel->setFilterKeyColumn(opt); } m_filterOptionsMenu->clear(); + refreshCurrentIndex(); } void CatalogView::fillFilterOptionsMenu() { m_filterOptionsMenu->clear(); if (m_proxyModel->individualRejectFilterEnabled()) m_filterOptionsMenu->addAction(i18n("Reset individual filter"), this, SLOT(setEntriesFilteredOut())); bool extStates = m_model->catalog()->capabilities()&ExtendedStates; const char* const basicTitles[] = { I18N_NOOP("Case insensitive"), I18N_NOOP("Ignore accelerator marks"), I18N_NOOP("Ready"), I18N_NOOP("Non-ready"), I18N_NOOP("Non-empty"), I18N_NOOP("Empty"), I18N_NOOP("Changed since file open"), I18N_NOOP("Unchanged since file open"), I18N_NOOP("Same in sync file"), I18N_NOOP("Different in sync file"), I18N_NOOP("Not in sync file"), I18N_NOOP("Plural"), I18N_NOOP("Non-plural"), }; const char* const* extTitles = Catalog::states(); const char* const* alltitles[2] = {basicTitles, extTitles}; QMenu* basicMenu = m_filterOptionsMenu->addMenu(i18nc("@title:inmenu", "Basic")); QMenu* extMenu = extStates ? m_filterOptionsMenu->addMenu(i18nc("@title:inmenu", "States")) : 0; QMenu* allmenus[2] = {basicMenu, extMenu}; QMenu* columnsMenu = m_filterOptionsMenu->addMenu(i18nc("@title:inmenu", "Searchable column")); QAction* txt; txt = m_filterOptionsMenu->addAction(i18nc("@title:inmenu", "Resort and refilter on content change"), m_proxyModel, &CatalogTreeFilterModel::setDynamicSortFilter); txt->setCheckable(true); txt->setChecked(m_proxyModel->dynamicSortFilter()); for (int i = 0; (1 << i) < CatalogTreeFilterModel::MaxOption; ++i) { bool ext = (1 << i) >= CatalogTreeFilterModel::New; if (!extStates && ext) break; txt = allmenus[ext]->addAction(i18n(alltitles[ext][i - ext * FIRSTSTATEPOSITION])); txt->setData(1 << i); txt->setCheckable(true); - txt->setChecked(m_proxyModel->filerOptions() & (1 << i)); + txt->setChecked(m_proxyModel->filterOptions() & (1 << i)); if ((1 << i) == CatalogTreeFilterModel::IgnoreAccel) basicMenu->addSeparator(); } if (!extStates) m_filterOptionsMenu->addSeparator(); for (int i = -1; i < CatalogTreeModel::DisplayedColumnCount; ++i) { qCWarning(LOKALIZE_LOG) << i; txt = columnsMenu->addAction((i == -1) ? i18nc("@item:inmenu all columns", "All") : m_model->headerData(i, Qt::Horizontal, Qt::DisplayRole).toString()); txt->setData(-i - 2); txt->setCheckable(true); txt->setChecked(m_proxyModel->filterKeyColumn() == i); } + refreshCurrentIndex(); } void CatalogView::reset() { m_proxyModel->setFilterKeyColumn(-1); - m_proxyModel->setFilerOptions(CatalogTreeFilterModel::AllStates); + m_proxyModel->setFilterOptions(CatalogTreeFilterModel::AllStates); m_lineEdit->clear(); + refreshCurrentIndex(); //emit gotoEntry(DocPosition(m_proxyModel->mapToSource(m_browser->currentIndex()).row()),0); slotItemActivated(m_browser->currentIndex()); } void CatalogView::setMergeCatalogPointer(MergeCatalog* pointer) { m_proxyModel->setMergeCatalogPointer(pointer); } int CatalogView::siblingEntryNumber(int step) { QModelIndex item = m_browser->currentIndex(); int lastRow = m_proxyModel->rowCount() - 1; if (!item.isValid()) { if (lastRow == -1) return -1; item = m_proxyModel->index((step == 1) ? 0 : lastRow, 0); m_browser->setCurrentIndex(item); } else { if (item.row() == ((step == -1) ? 0 : lastRow)) return -1; item = item.sibling(item.row() + step, 0); } return m_proxyModel->mapToSource(item).row(); } int CatalogView::nextEntryNumber() { return siblingEntryNumber(1); } int CatalogView::prevEntryNumber() { return siblingEntryNumber(-1); } static int edgeEntry(CatalogTreeFilterModel* m_proxyModel, int row) { if (!m_proxyModel->rowCount()) return -1; return m_proxyModel->mapToSource(m_proxyModel->index(row, 0)).row(); } int CatalogView::firstEntryNumber() { return edgeEntry(m_proxyModel, 0); } int CatalogView::lastEntryNumber() { return edgeEntry(m_proxyModel, m_proxyModel->rowCount() - 1); } void CatalogView::setEntryFilteredOut(int entry, bool filteredOut) { m_proxyModel->setEntryFilteredOut(entry, filteredOut); + refreshCurrentIndex(); } void CatalogView::setEntriesFilteredOut(bool filteredOut) { show(); m_proxyModel->setEntriesFilteredOut(filteredOut); + refreshCurrentIndex(); } diff --git a/src/cataloglistview/cataloglistview.h b/src/cataloglistview/cataloglistview.h index 49d4ceb..af2b3ed 100644 --- a/src/cataloglistview/cataloglistview.h +++ b/src/cataloglistview/cataloglistview.h @@ -1,83 +1,85 @@ /* **************************************************************************** This file is part of Lokalize Copyright (C) 2007-2009 by Nick Shaforostoff This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License or (at your option) version 3 or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 14 of version 3 of the license. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . **************************************************************************** */ #ifndef CATALOGLISTVIEW_H #define CATALOGLISTVIEW_H #include "pos.h" #include "mergecatalog.h" #include class QTreeView; class CatalogTreeFilterModel; class CatalogTreeModel; class Catalog; class QLineEdit; class QMenu; class QAction; class QModelIndex; class CatalogTreeView; class CatalogView: public QDockWidget { Q_OBJECT public: explicit CatalogView(QWidget*, Catalog*); ~CatalogView(); void setEntryFilteredOut(int entry, bool filteredOut); int nextEntryNumber(); int prevEntryNumber(); int firstEntryNumber(); int lastEntryNumber(); private: int siblingEntryNumber(int step); + void refreshCurrentIndex(); public slots: void slotNewEntryDisplayed(const DocPosition&); void setEntriesFilteredOut(bool filteredOut = false); void setFocus(); void reset(); void setMergeCatalogPointer(MergeCatalog* pointer); signals: void gotoEntry(const DocPosition&, int selection); void escaped(); private slots: void slotItemActivated(const QModelIndex&); void setFilterRegExp(); void fillFilterOptionsMenu(); void filterOptionToggled(QAction*); private: CatalogTreeView* m_browser; QLineEdit* m_lineEdit; QMenu* m_filterOptionsMenu; CatalogTreeModel* m_model; CatalogTreeFilterModel* m_proxyModel; + int m_lastKnownDocPosition; }; #endif diff --git a/src/cataloglistview/catalogmodel.cpp b/src/cataloglistview/catalogmodel.cpp index f5ecea8..18b2a47 100644 --- a/src/cataloglistview/catalogmodel.cpp +++ b/src/cataloglistview/catalogmodel.cpp @@ -1,297 +1,297 @@ /* **************************************************************************** This file is part of Lokalize Copyright (C) 2007-2014 by Nick Shaforostoff This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License or (at your option) version 3 or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 14 of version 3 of the license. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . **************************************************************************** */ #include "catalogmodel.h" #include "lokalize_debug.h" #include "catalog.h" #include "project.h" #include #include #include #include #include #define DYNAMICFILTER_LIMIT 256 QVector CatalogTreeModel::m_fonts; CatalogTreeModel::CatalogTreeModel(QObject* parent, Catalog* catalog) : QAbstractItemModel(parent) , m_catalog(catalog) , m_ignoreAccel(true) { if (m_fonts.isEmpty()) { QVector fonts(4, QApplication::font()); fonts[1].setItalic(true); //fuzzy fonts[2].setBold(true); //modified fonts[3].setItalic(true); //fuzzy fonts[3].setBold(true); //modified m_fonts.reserve(4); for (int i = 0; i < 4; i++) m_fonts << fonts.at(i); } connect(catalog, &Catalog::signalEntryModified, this, &CatalogTreeModel::reflectChanges); connect(catalog, QOverload<>::of(&Catalog::signalFileLoaded), this, &CatalogTreeModel::fileLoaded); } QModelIndex CatalogTreeModel::index(int row, int column, const QModelIndex& /*parent*/) const { return createIndex(row, column); } QModelIndex CatalogTreeModel::parent(const QModelIndex& /*index*/) const { return QModelIndex(); } int CatalogTreeModel::columnCount(const QModelIndex& parent) const { Q_UNUSED(parent); return DisplayedColumnCount; } void CatalogTreeModel::fileLoaded() { beginResetModel(); endResetModel(); } void CatalogTreeModel::reflectChanges(DocPosition pos) { emit dataChanged(index(pos.entry, 0), index(pos.entry, DisplayedColumnCount - 1)); #if 0 I disabled dynamicSortFilter function //lazy sorting/filtering if (rowCount() < DYNAMICFILTER_LIMIT || m_prevChanged != pos) { qCWarning(LOKALIZE_LOG) << "first dataChanged emitment" << pos.entry; emit dataChanged(index(pos.entry, 0), index(pos.entry, DisplayedColumnCount - 1)); if (!(rowCount() < DYNAMICFILTER_LIMIT)) { qCWarning(LOKALIZE_LOG) << "second dataChanged emitment" << m_prevChanged.entry; emit dataChanged(index(m_prevChanged.entry, 0), index(m_prevChanged.entry, DisplayedColumnCount - 1)); } } m_prevChanged = pos; #endif } int CatalogTreeModel::rowCount(const QModelIndex& parent) const { if (parent.isValid()) return 0; return m_catalog->numberOfEntries(); } QVariant CatalogTreeModel::headerData(int section, Qt::Orientation /*orientation*/, int role) const { if (role != Qt::DisplayRole) return QVariant(); switch (section) { case Key: return i18nc("@title:column", "Entry"); case Source: return i18nc("@title:column Original text", "Source"); case Target: return i18nc("@title:column Text in target language", "Target"); case Notes: return i18nc("@title:column", "Notes"); case Context: return i18nc("@title:column", "Context"); case TranslationStatus: return i18nc("@title:column", "Translation Status"); } return QVariant(); } QVariant CatalogTreeModel::data(const QModelIndex& index, int role) const { if (m_catalog->numberOfEntries() <= index.row()) return QVariant(); if (role == Qt::SizeHintRole) { //no need to cache because of uniform row heights return QFontMetrics(QApplication::font()).size(Qt::TextSingleLine, QString::fromLatin1(" ")); } else if (role == Qt::FontRole/* && index.column()==Target*/) { bool fuzzy = !m_catalog->isApproved(index.row()); bool modified = m_catalog->isModified(index.row()); return m_fonts.at(fuzzy * 1 | modified * 2); } else if (role == Qt::ForegroundRole) { if (m_catalog->isBookmarked(index.row())) { static KColorScheme colorScheme(QPalette::Normal); return colorScheme.foreground(KColorScheme::LinkText); } if (m_catalog->isObsolete(index.row())) { static KColorScheme colorScheme(QPalette::Normal); return colorScheme.foreground(KColorScheme::InactiveText); } } else if (role == Qt::UserRole) { switch (index.column()) { case TranslationStatus: return m_catalog->isApproved(index.row()); case IsEmpty: return m_catalog->isEmpty(index.row()); case State: return int(m_catalog->state(index.row())); case IsModified: return m_catalog->isModified(index.row()); case IsPlural: return m_catalog->isPlural(index.row()); default: role = Qt::DisplayRole; } } else if (role == StringFilterRole) { //exclude UI strings if (index.column() >= TranslationStatus) return QVariant(); else if (index.column() == Source || index.column() == Target) { QString str = index.column() == Source ? m_catalog->msgidWithPlurals(index.row()) : m_catalog->msgstrWithPlurals(index.row()); return m_ignoreAccel ? str.remove(Project::instance()->accel()) : str; } role = Qt::DisplayRole; } if (role != Qt::DisplayRole) return QVariant(); switch (index.column()) { case Key: return index.row() + 1; case Source: return m_catalog->msgidWithPlurals(index.row()); case Target: return m_catalog->msgstrWithPlurals(index.row()); case Notes: { QString result; foreach (const Note ¬e, m_catalog->notes(index.row())) result += note.content; return result; } case Context: return m_catalog->context(index.row()); case TranslationStatus: static QString statuses[] = {i18nc("@info:status 'non-fuzzy' in gettext terminology", "Ready"), i18nc("@info:status 'fuzzy' in gettext terminology", "Needs review"), i18nc("@info:status", "Untranslated") }; if (m_catalog->isEmpty(index.row())) return statuses[2]; return statuses[!m_catalog->isApproved(index.row())]; } return QVariant(); } CatalogTreeFilterModel::CatalogTreeFilterModel(QObject* parent) : QSortFilterProxyModel(parent) - , m_filerOptions(AllStates) + , m_filterOptions(AllStates) , m_individualRejectFilterEnable(false) , m_mergeCatalog(NULL) { setFilterKeyColumn(-1); setFilterCaseSensitivity(Qt::CaseInsensitive); setFilterRole(CatalogTreeModel::StringFilterRole); setDynamicSortFilter(false); } void CatalogTreeFilterModel::setSourceModel(QAbstractItemModel* sourceModel) { QSortFilterProxyModel::setSourceModel(sourceModel); connect(sourceModel, &QAbstractItemModel::modelReset, this, QOverload<>::of(&CatalogTreeFilterModel::setEntriesFilteredOut)); setEntriesFilteredOut(false); } void CatalogTreeFilterModel::setEntriesFilteredOut() { return setEntriesFilteredOut(false); } void CatalogTreeFilterModel::setEntriesFilteredOut(bool filteredOut) { m_individualRejectFilter.fill(filteredOut, sourceModel()->rowCount()); m_individualRejectFilterEnable = filteredOut; invalidateFilter(); } void CatalogTreeFilterModel::setEntryFilteredOut(int entry, bool filteredOut) { // if (entry>=m_individualRejectFilter.size()) // sourceModelReset(); m_individualRejectFilter[entry] = filteredOut; m_individualRejectFilterEnable = true; invalidateFilter(); } -void CatalogTreeFilterModel::setFilerOptions(int o) +void CatalogTreeFilterModel::setFilterOptions(int o) { - m_filerOptions = o; + m_filterOptions = o; setFilterCaseSensitivity(o & CaseInsensitive ? Qt::CaseInsensitive : Qt::CaseSensitive); static_cast(sourceModel())->setIgnoreAccel(o & IgnoreAccel); invalidateFilter(); } bool CatalogTreeFilterModel::filterAcceptsRow(int source_row, const QModelIndex& source_parent) const { - int filerOptions = m_filerOptions; + int filerOptions = m_filterOptions; bool accepts = true; if (bool(filerOptions & Ready) != bool(filerOptions & NotReady)) { bool ready = sourceModel()->index(source_row, CatalogTreeModel::TranslationStatus, source_parent).data(Qt::UserRole).toBool(); accepts = (ready == bool(filerOptions & Ready) || ready != bool(filerOptions & NotReady)); } if (accepts && bool(filerOptions & NonEmpty) != bool(filerOptions & Empty)) { bool untr = sourceModel()->index(source_row, CatalogTreeModel::IsEmpty, source_parent).data(Qt::UserRole).toBool(); accepts = (untr == bool(filerOptions & Empty) || untr != bool(filerOptions & NonEmpty)); } if (accepts && bool(filerOptions & Modified) != bool(filerOptions & NonModified)) { bool modified = sourceModel()->index(source_row, CatalogTreeModel::IsModified, source_parent).data(Qt::UserRole).toBool(); accepts = (modified == bool(filerOptions & Modified) || modified != bool(filerOptions & NonModified)); } if (accepts && bool(filerOptions & Plural) != bool(filerOptions & NonPlural)) { bool modified = sourceModel()->index(source_row, CatalogTreeModel::IsPlural, source_parent).data(Qt::UserRole).toBool(); accepts = (modified == bool(filerOptions & Plural) || modified != bool(filerOptions & NonPlural)); } // These are the possible sync options of a row: // * SameInSync: The sync file contains a row with the same msgid and the same msgstr. // * DifferentInSync: The sync file contains a row with the same msgid and different msgstr. // * NotInSync: The sync file does not contain any row with the same msgid. // // The code below takes care of filtering rows when any of those options is not checked. // const int mask = (SameInSync | DifferentInSync | NotInSync); if (accepts && m_mergeCatalog && (filerOptions & mask) && (filerOptions & mask) != mask) { bool isPresent = m_mergeCatalog->isPresent(source_row); bool isDifferent = m_mergeCatalog->isDifferent(source_row); accepts = ! ((isPresent && !isDifferent && !bool(filerOptions & SameInSync)) || (isPresent && isDifferent && !bool(filerOptions & DifferentInSync)) || (!isPresent && !bool(filerOptions & NotInSync)) ); } if (accepts && (filerOptions & STATES) != STATES) { int state = sourceModel()->index(source_row, CatalogTreeModel::State, source_parent).data(Qt::UserRole).toInt(); accepts = (filerOptions & (1 << (state + FIRSTSTATEPOSITION))); } accepts = accepts && !(m_individualRejectFilterEnable && source_row < m_individualRejectFilter.size() && m_individualRejectFilter.at(source_row)); return accepts && QSortFilterProxyModel::filterAcceptsRow(source_row, source_parent); } void CatalogTreeFilterModel::setMergeCatalogPointer(MergeCatalog* pointer) { m_mergeCatalog = pointer; } diff --git a/src/cataloglistview/catalogmodel.h b/src/cataloglistview/catalogmodel.h index 656e170..0532219 100644 --- a/src/cataloglistview/catalogmodel.h +++ b/src/cataloglistview/catalogmodel.h @@ -1,182 +1,182 @@ /* **************************************************************************** This file is part of Lokalize Copyright (C) 2007-2013 by Nick Shaforostoff This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License or (at your option) version 3 or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 14 of version 3 of the license. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . **************************************************************************** */ #ifndef CATALOGMODEL_H #define CATALOGMODEL_H #include "mergecatalog.h" #include "pos.h" #include #include #include class Catalog; /** * MVC wrapper for Catalog */ class CatalogTreeModel: public QAbstractItemModel { Q_OBJECT public: enum CatalogModelColumns { Key = 0, Source, Target, Notes, Context, TranslationStatus, IsEmpty, State, IsModified, IsPlural, ColumnCount, DisplayedColumnCount = TranslationStatus + 1 }; enum Roles { StringFilterRole = Qt::UserRole + 1 }; explicit CatalogTreeModel(QObject* parent, Catalog* catalog); ~CatalogTreeModel() override {} QModelIndex index(int row, int column, const QModelIndex& parent = QModelIndex())const override; QModelIndex parent(const QModelIndex&) const override; int rowCount(const QModelIndex& parent = QModelIndex()) const override; int columnCount(const QModelIndex& parent = QModelIndex()) const override; QVariant data(const QModelIndex&, int role = Qt::DisplayRole) const override; QVariant headerData(int section, Qt::Orientation, int role = Qt::DisplayRole) const override; Catalog* catalog()const { return m_catalog; } void setIgnoreAccel(bool n) { m_ignoreAccel = n; } public slots: void reflectChanges(DocPosition); void fileLoaded(); private: Catalog* m_catalog; bool m_ignoreAccel; static QVector m_fonts; //DocPos m_prevChanged; }; class CatalogTreeFilterModel: public QSortFilterProxyModel { Q_OBJECT public: enum FilterOptions { CaseInsensitive = 1 << 0, IgnoreAccel = 1 << 1, Ready = 1 << 2, NotReady = 1 << 3, NonEmpty = 1 << 4, Empty = 1 << 5, Modified = 1 << 6, NonModified = 1 << 7, SameInSync = 1 << 8, DifferentInSync = 1 << 9, NotInSync = 1 << 10, Plural = 1 << 11, NonPlural = 1 << 12, //states (see defines below) New = 1 << 13, NeedsTranslation = 1 << 14, NeedsL10n = 1 << 15, NeedsAdaptation = 1 << 16, Translated = 1 << 17, NeedsReviewTranslation = 1 << 18, NeedsReviewL10n = 1 << 19, NeedsReviewAdaptation = 1 << 20, Final = 1 << 21, SignedOff = 1 << 22, MaxOption = 1 << 23, AllStates = MaxOption - 1 }; #define STATES ((0xffff<<13)&(AllStates)) #define FIRSTSTATEPOSITION 13 explicit CatalogTreeFilterModel(QObject* parent); ~CatalogTreeFilterModel() {} bool filterAcceptsRow(int source_row, const QModelIndex& source_parent) const override; - void setFilerOptions(int o); - int filerOptions()const + void setFilterOptions(int o); + int filterOptions()const { - return m_filerOptions; + return m_filterOptions; } void setSourceModel(QAbstractItemModel* sourceModel) override; bool individualRejectFilterEnabled() { return m_individualRejectFilterEnable; } void setEntryFilteredOut(int entry, bool filteredOut); void setMergeCatalogPointer(MergeCatalog* pointer); public slots: void setEntriesFilteredOut(); void setEntriesFilteredOut(bool filteredOut); void setDynamicSortFilter(bool enabled) { QSortFilterProxyModel::setDynamicSortFilter(enabled); } private: - int m_filerOptions; + int m_filterOptions; bool m_individualRejectFilterEnable; QVector m_individualRejectFilter; //used from kross scripts MergeCatalog* m_mergeCatalog; }; #endif