diff --git a/kmymoney/views/CMakeLists.txt b/kmymoney/views/CMakeLists.txt --- a/kmymoney/views/CMakeLists.txt +++ b/kmymoney/views/CMakeLists.txt @@ -49,7 +49,7 @@ kinvestmentview.ui kpayeesviewdecl.ui kscheduledviewdecl.ui - ktagsviewdecl.ui + ktagsview.ui konlinejoboutbox.ui kpayeeidentifierview.ui simpleledgerview.ui diff --git a/kmymoney/views/kmymoneyview.cpp b/kmymoney/views/kmymoneyview.cpp --- a/kmymoney/views/kmymoneyview.cpp +++ b/kmymoney/views/kmymoneyview.cpp @@ -195,18 +195,12 @@ connect(m_categoriesView, &KMyMoneyViewBase::aboutToShow, this, &KMyMoneyView::connectView); connect(m_categoriesView, &KMyMoneyViewBase::aboutToShow, this, &KMyMoneyView::resetViewSelection); -// Page 5 - m_tagsView = new KTagsView(); + // Page 5 + m_tagsView = new KTagsView; viewFrames[View::Tags] = m_model->addPage(m_tagsView, i18n("Tags")); viewFrames[View::Tags]->setIcon(QIcon::fromTheme(g_Icons[Icon::ViewTags])); - - connect(kmymoney, SIGNAL(tagCreated(QString)), m_tagsView, SLOT(slotSelectTagAndTransaction(QString))); - connect(kmymoney, SIGNAL(tagRename()), m_tagsView, SLOT(slotRenameButtonCliked())); - connect(m_tagsView, SIGNAL(openContextMenu(MyMoneyObject)), kmymoney, SLOT(slotShowTagContextMenu())); - connect(m_tagsView, SIGNAL(selectObjects(QList)), kmymoney, SLOT(slotSelectTags(QList))); - connect(m_tagsView, SIGNAL(transactionSelected(QString,QString)), - this, SLOT(slotLedgerSelected(QString,QString))); - connect(m_tagsView, SIGNAL(aboutToShow()), this, SIGNAL(aboutToChangeView())); + connect(m_tagsView, &KMyMoneyViewBase::aboutToShow, this, &KMyMoneyView::connectView); + connect(m_tagsView, &KMyMoneyViewBase::aboutToShow, this, &KMyMoneyView::resetViewSelection); // Page 6 m_payeesView = new KPayeesView(); @@ -1710,7 +1704,7 @@ m_institutionsView->refresh(); m_categoriesView->refresh(); m_payeesView->slotLoadPayees(); - m_tagsView->slotLoadTags(); + m_tagsView->refresh(); m_ledgerView->slotLoadView(); m_budgetView->refresh(); m_homeView->slotLoadView(); @@ -2298,6 +2292,15 @@ connect(MyMoneyFile::instance(), &MyMoneyFile::dataChanged, m_categoriesView, &KCategoriesView::refresh); break; + case View::Tags: + disconnect(m_tagsView, &KTagsView::aboutToShow, this, &KMyMoneyView::connectView); + connect(kmymoney, &KMyMoneyApp::tagCreated, m_tagsView, static_cast(&KTagsView::slotSelectTagAndTransaction)); + connect(kmymoney, &KMyMoneyApp::tagRename, m_tagsView, &KTagsView::slotRenameButtonCliked); + connect(m_tagsView, &KTagsView::openContextMenu, kmymoney, &KMyMoneyApp::slotShowTagContextMenu); + connect(m_tagsView, &KTagsView::selectObjects, kmymoney, &KMyMoneyApp::slotSelectTags); + connect(m_tagsView, &KTagsView::transactionSelected, this, &KMyMoneyView::slotLedgerSelected); + connect(m_tagsView, &KMyMoneyViewBase::aboutToShow, this, &KMyMoneyView::aboutToChangeView); + break; case View::Budget: disconnect(m_budgetView, &KBudgetView::aboutToShow, this, &KMyMoneyView::connectView); treeView = m_budgetView->getTreeView(); diff --git a/kmymoney/views/kmymoneyviewbase_p.h b/kmymoney/views/kmymoneyviewbase_p.h --- a/kmymoney/views/kmymoneyviewbase_p.h +++ b/kmymoney/views/kmymoneyviewbase_p.h @@ -23,8 +23,13 @@ // ---------------------------------------------------------------------------- // Project Includes +#ifndef KMYMONEYVIEWBASEPRIVATE_H +#define KMYMONEYVIEWBASEPRIVATE_H + class KMyMoneyViewBasePrivate { public: bool m_needsRefresh; }; + +#endif diff --git a/kmymoney/views/ktagsview.h b/kmymoney/views/ktagsview.h --- a/kmymoney/views/ktagsview.h +++ b/kmymoney/views/ktagsview.h @@ -3,6 +3,7 @@ ------------- begin : Sat Oct 13 2012 copyright : (C) 2012 by Alessandro Russo + (C) 2017 by Łukasz Wojniłowicz ***************************************************************************/ @@ -21,73 +22,44 @@ // ---------------------------------------------------------------------------- // QT Includes -#include -#include - // ---------------------------------------------------------------------------- // KDE Includes // ---------------------------------------------------------------------------- // Project Includes -#include "ui_ktagsviewdecl.h" -#include "mymoneytag.h" +#include "kmymoneyviewbase.h" +class QListWidgetItem; class KListWidgetSearchLine; +class MyMoneyObject; +class MyMoneyTag; -/** - * @author Alessandro Russo - */ +template class QList; /** - * This class represents an item in the tags list view. + * @author Alessandro Russo */ -class KTagListItem : public QListWidgetItem -{ -public: - /** - * Constructor to be used to construct a tag entry object. - * - * @param parent pointer to the QListWidget object this entry should be - * added to. - * @param tag const reference to MyMoneyTag for which - * the QListWidget entry is constructed - */ - KTagListItem(QListWidget *parent, const MyMoneyTag& tag); - ~KTagListItem(); - - const MyMoneyTag& tag() const { - return m_tag; - }; -private: - MyMoneyTag m_tag; -}; - -class KTagsView : public QWidget, private Ui::KTagsViewDecl +class KTagsViewPrivate; +class KTagsView : public KMyMoneyViewBase { Q_OBJECT public: - KTagsView(QWidget *parent = 0); + explicit KTagsView(QWidget *parent = nullptr); ~KTagsView(); - void setDefaultFocus(); + void setDefaultFocus() override; + void refresh() override; void showEvent(QShowEvent* event); - enum filterTypeE { - eAllTags = 0, - eReferencedTags, // used tags - eUnusedTags, // unused tags - eOpenedTags, // not closed tags - eClosedTags // closed tags - }; - public slots: - void slotSelectTagAndTransaction(const QString& tagId, const QString& accountId = QString(), const QString& transactionId = QString()); - void slotLoadTags(); + void slotSelectTagAndTransaction(const QString& tagId, const QString& accountId, const QString& transactionId); + void slotSelectTagAndTransaction(const QString& tagId); void slotStartRename(QListWidgetItem*); + void slotRenameButtonCliked(); void slotHelp(); protected: @@ -137,8 +109,7 @@ void slotSelectTransaction(); void slotTagNew(); - - void slotRenameButtonCliked(); + void slotTagDelete(); void slotChangeFilter(int index); @@ -156,57 +127,9 @@ void openContextMenu(const MyMoneyObject& obj); void selectObjects(const QList& tags); - /** - * This signal is emitted whenever the view is about to be shown. - */ - void aboutToShow(); - private: - MyMoneyTag m_tag; - QString m_newName; - - /** - * This member holds a list of all transactions - */ - QList > m_transactionList; - - - /** - * This member holds the state of the toggle switch used - * to suppress updates due to MyMoney engine data changes - */ - bool m_needReload; - - /** - * This member holds the load state of page - */ - bool m_needLoad; - - /** - * Search widget for the list - */ - KListWidgetSearchLine* m_searchWidget; - - /** - * Semaphore to suppress loading during selection - */ - bool m_inSelection; - - /** - * This signals whether a tag can be edited - **/ - bool m_allowEditing; - - /** - * This holds the filter type - */ - int m_tagFilterType; - - AccountNamesFilterProxyModel *m_filterProxyModel; - - /** Initializes page and sets its load status to initialized - */ - void init(); + Q_DISABLE_COPY(KTagsView) + Q_DECLARE_PRIVATE(KTagsView) }; #endif diff --git a/kmymoney/views/ktagsview.cpp b/kmymoney/views/ktagsview.cpp --- a/kmymoney/views/ktagsview.cpp +++ b/kmymoney/views/ktagsview.cpp @@ -1,8 +1,9 @@ /*************************************************************************** - ktagsview.h + ktagsview.cpp ------------- begin : Sat Oct 13 2012 copyright : (C) 2012 by Alessandro Russo + (C) 2017 by Łukasz Wojniłowicz ***************************************************************************/ /*************************************************************************** @@ -15,44 +16,27 @@ ***************************************************************************/ #include "ktagsview.h" +#include "ktagsview_p.h" // ---------------------------------------------------------------------------- // QT Includes -#include -#include -#include -#include -#include -#include -#include -#include #include -#include // ---------------------------------------------------------------------------- // KDE Includes -#include #include -#include #include -#include #include -#include // ---------------------------------------------------------------------------- // Project Includes -#include "mymoneyfile.h" #include "mymoneyprice.h" -#include "mymoneytransactionfilter.h" #include "kmymoneyglobalsettings.h" #include "kmymoney.h" -#include "models.h" -#include "accountsmodel.h" #include "mymoneysecurity.h" -#include "icons.h" using namespace Icons; @@ -62,6 +46,29 @@ // *** KTagListItem Implementation *** +/** + * This class represents an item in the tags list view. + */ +class KTagListItem : public QListWidgetItem +{ +public: + /** + * Constructor to be used to construct a tag entry object. + * + * @param parent pointer to the QListWidget object this entry should be + * added to. + * @param tag const reference to MyMoneyTag for which + * the QListWidget entry is constructed + */ + explicit KTagListItem(QListWidget *parent, const MyMoneyTag& tag); + ~KTagListItem(); + + MyMoneyTag tag() const; + +private: + MyMoneyTag m_tag; +}; + KTagListItem::KTagListItem(QListWidget *parent, const MyMoneyTag& tag) : QListWidgetItem(parent, QListWidgetItem::UserType), m_tag(tag) @@ -75,161 +82,81 @@ { } -// *** KTagsView Implementation *** +MyMoneyTag KTagListItem::tag() const +{ + return m_tag; +} +// *** KTagsView Implementation *** KTagsView::KTagsView(QWidget *parent) : - QWidget(parent), - m_needReload(false), - m_needLoad(true), - m_inSelection(false), - m_allowEditing(true), - m_tagFilterType(0) + KMyMoneyViewBase(*new KTagsViewPrivate(this), parent) { + Q_D(KTagsView); + d->m_needLoad = true; + d->m_inSelection = false; + d->m_allowEditing = true; + d->m_tagFilterType = 0; } KTagsView::~KTagsView() { - if (!m_needLoad) { + Q_D(KTagsView); + if (!d->m_needLoad) { // remember the splitter settings for startup KConfigGroup grp = KSharedConfig::openConfig()->group("Last Use Settings"); - grp.writeEntry("KTagsViewSplitterSize", m_splitter->saveState()); + grp.writeEntry("KTagsViewSplitterSize", d->ui->m_splitter->saveState()); grp.sync(); } } void KTagsView::setDefaultFocus() { - QTimer::singleShot(0, m_searchWidget, SLOT(setFocus())); + Q_D(KTagsView); + QTimer::singleShot(0, d->m_searchWidget, SLOT(setFocus())); } -void KTagsView::init() +void KTagsView::refresh() { - m_needLoad = false; - setupUi(this); - - m_filterProxyModel = new AccountNamesFilterProxyModel(this); - m_filterProxyModel->addAccountGroup(QVector {eMyMoney::Account::Asset, eMyMoney::Account::Liability, eMyMoney::Account::Income, eMyMoney::Account::Expense}); - auto const model = Models::instance()->accountsModel(); - m_filterProxyModel->setSourceModel(model); - m_filterProxyModel->setSourceColumns(model->getColumns()); - m_filterProxyModel->sort((int)eAccountsModel::Column::Account); - - // create the searchline widget - // and insert it into the existing layout - m_searchWidget = new KListWidgetSearchLine(this, m_tagsList); - m_searchWidget->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed)); - m_tagsList->setContextMenuPolicy(Qt::CustomContextMenu); - m_listTopHLayout->insertWidget(0, m_searchWidget); - - //load the filter type - m_filterBox->addItem(i18nc("@item Show all tags", "All")); - m_filterBox->addItem(i18nc("@item Show only used tags", "Used")); - m_filterBox->addItem(i18nc("@item Show only unused tags", "Unused")); - m_filterBox->addItem(i18nc("@item Show only opened tags", "Opened")); - m_filterBox->addItem(i18nc("@item Show only closed tags", "Closed")); - m_filterBox->setSizeAdjustPolicy(QComboBox::AdjustToContents); - - KGuiItem newButtonItem(QString(), - QIcon::fromTheme(g_Icons[Icon::ListAddTag]), - i18n("Creates a new tag"), - i18n("Use this to create a new tag.")); - KGuiItem::assign(m_newButton, newButtonItem); - m_newButton->setToolTip(newButtonItem.toolTip()); - - KGuiItem renameButtonItem(QString(), - QIcon::fromTheme(g_Icons[Icon::EditRename]), - i18n("Rename the current selected tag"), - i18n("Use this to start renaming the selected tag.")); - KGuiItem::assign(m_renameButton, renameButtonItem); - m_renameButton->setToolTip(renameButtonItem.toolTip()); - - KGuiItem deleteButtonItem(QString(), - QIcon::fromTheme(g_Icons[Icon::ListRemoveTag]), - i18n("Delete the current selected tag"), - i18n("Use this to delete the selected tag.")); - KGuiItem::assign(m_deleteButton, deleteButtonItem); - m_deleteButton->setToolTip(deleteButtonItem.toolTip()); - - KGuiItem updateButtonItem(i18nc("Update tag", "Update"), - QIcon::fromTheme(g_Icons[Icon::DialogOK]), - i18n("Accepts the entered data and stores it"), - i18n("Use this to accept the modified data.")); - KGuiItem::assign(m_updateButton, updateButtonItem); - - m_updateButton->setEnabled(false); - - QList cols; - cols << KMyMoneyRegister::DateColumn; - cols << KMyMoneyRegister::AccountColumn; - cols << KMyMoneyRegister::DetailColumn; - cols << KMyMoneyRegister::ReconcileFlagColumn; - cols << KMyMoneyRegister::PaymentColumn; - cols << KMyMoneyRegister::DepositColumn; - m_register->setupRegister(MyMoneyAccount(), cols); - m_register->setSelectionMode(QTableWidget::SingleSelection); - m_register->setDetailsColumnType(KMyMoneyRegister::AccountFirst); - m_balanceLabel->hide(); - - connect(m_tagsList, SIGNAL(currentItemChanged(QListWidgetItem*,QListWidgetItem*)), this, SLOT(slotSelectTag(QListWidgetItem*,QListWidgetItem*))); - connect(m_tagsList, SIGNAL(itemSelectionChanged()), this, SLOT(slotSelectTag())); - connect(m_tagsList, SIGNAL(itemDoubleClicked(QListWidgetItem*)), this, SLOT(slotStartRename(QListWidgetItem*))); - connect(m_tagsList, SIGNAL(itemChanged(QListWidgetItem*)), this, SLOT(slotRenameTag(QListWidgetItem*))); - connect(m_tagsList, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(slotOpenContextMenu(QPoint))); - - connect(m_renameButton, SIGNAL(clicked()), this, SLOT(slotRenameButtonCliked())); - connect(m_deleteButton, SIGNAL(clicked()), kmymoney->actionCollection()->action(kmymoney->s_Actions[Action::TagDelete]), SLOT(trigger())); - connect(m_newButton, SIGNAL(clicked()), this, SLOT(slotTagNew())); - - connect(m_colorbutton, SIGNAL(changed(QColor)), this, SLOT(slotTagDataChanged())); - connect(m_closed, SIGNAL(stateChanged(int)), this, SLOT(slotTagDataChanged())); - connect(m_notes, SIGNAL(textChanged()), this, SLOT(slotTagDataChanged())); - - connect(m_updateButton, SIGNAL(clicked()), this, SLOT(slotUpdateTag())); - connect(m_helpButton, SIGNAL(clicked()), this, SLOT(slotHelp())); - - connect(m_register, SIGNAL(editTransaction()), this, SLOT(slotSelectTransaction())); - - connect(MyMoneyFile::instance(), SIGNAL(dataChanged()), this, SLOT(slotLoadTags())); - - connect(m_filterBox, SIGNAL(currentIndexChanged(int)), this, SLOT(slotChangeFilter(int))); - - // use the size settings of the last run (if any) - KConfigGroup grp = KSharedConfig::openConfig()->group("Last Use Settings"); - m_splitter->restoreState(grp.readEntry("KTagsViewSplitterSize", QByteArray())); - m_splitter->setChildrenCollapsible(false); - - // At start we haven't any tag selected - m_tabWidget->setEnabled(false); // disable tab widget - m_deleteButton->setEnabled(false); // disable delete and rename button - m_renameButton->setEnabled(false); - m_tag = MyMoneyTag(); // make sure we don't access an undefined tag - clearItemData(); + + Q_D(KTagsView); + if (isVisible()) { + if (d->m_inSelection) + QTimer::singleShot(0, this, SLOT(refresh())); + else + loadTags(); + d->m_needsRefresh = false; + } else { + d->m_needsRefresh = true; + } } void KTagsView::slotStartRename(QListWidgetItem* item) { - m_allowEditing = true; - m_tagsList->editItem(item); + Q_D(KTagsView); + d->m_allowEditing = true; + d->ui->m_tagsList->editItem(item); } void KTagsView::slotRenameButtonCliked() { - if (m_tagsList->currentItem() && m_tagsList->selectedItems().count() == 1) { - slotStartRename(m_tagsList->currentItem()); + Q_D(KTagsView); + if (d->ui->m_tagsList->currentItem() && d->ui->m_tagsList->selectedItems().count() == 1) { + slotStartRename(d->ui->m_tagsList->currentItem()); } } // This variant is only called when a single tag is selected and renamed. void KTagsView::slotRenameTag(QListWidgetItem* ta) { + Q_D(KTagsView); //if there is no current item selected, exit - if (m_allowEditing == false || !m_tagsList->currentItem() || ta != m_tagsList->currentItem()) + if (d->m_allowEditing == false || !d->ui->m_tagsList->currentItem() || ta != d->ui->m_tagsList->currentItem()) return; //qDebug() << "[KTagsView::slotRenameTag]"; // create a copy of the new name without appended whitespaces QString new_name = ta->text(); - if (m_tag.name() != new_name) { + if (d->m_tag.name() != new_name) { MyMoneyFileTransaction ft; try { // check if we already have a tag with the new name @@ -242,16 +169,16 @@ i18n("A tag with the name '%1' already exists. It is not advisable to have " "multiple tags with the same identification name. Are you sure you would like " "to rename the tag?", new_name)) != KMessageBox::Yes) { - ta->setText(m_tag.name()); + ta->setText(d->m_tag.name()); return; } } catch (const MyMoneyException &) { // all ok, the name is unique } - m_tag.setName(new_name); - m_newName = new_name; - MyMoneyFile::instance()->modifyTag(m_tag); + d->m_tag.setName(new_name); + d->m_newName = new_name; + MyMoneyFile::instance()->modifyTag(d->m_tag); // the above call to modifyTag will reload the view so // all references and pointers to the view have to be @@ -259,7 +186,7 @@ // make sure, that the record is visible even if it moved // out of sight due to the rename operation - ensureTagVisible(m_tag.id()); + ensureTagVisible(d->m_tag.id()); ft.commit(); @@ -274,13 +201,14 @@ void KTagsView::ensureTagVisible(const QString& id) { - for (int i = 0; i < m_tagsList->count(); ++i) { - KTagListItem* ta = dynamic_cast(m_tagsList->item(0)); + Q_D(KTagsView); + for (int i = 0; i < d->ui->m_tagsList->count(); ++i) { + KTagListItem* ta = dynamic_cast(d->ui->m_tagsList->item(0)); if (ta && ta->tag().id() == id) { - m_tagsList->scrollToItem(ta, QAbstractItemView::PositionAtCenter); + d->ui->m_tagsList->scrollToItem(ta, QAbstractItemView::PositionAtCenter); - m_tagsList->setCurrentItem(ta); // active item and deselect all others - m_tagsList->setCurrentRow(i, QItemSelectionModel::ClearAndSelect); // and select it + d->ui->m_tagsList->setCurrentItem(ta); // active item and deselect all others + d->ui->m_tagsList->setCurrentRow(i, QItemSelectionModel::ClearAndSelect); // and select it break; } } @@ -288,7 +216,8 @@ void KTagsView::selectedTags(QList& tagsList) const { - QList selectedItems = m_tagsList->selectedItems(); + Q_D(const KTagsView); + QList selectedItems = d->ui->m_tagsList->selectedItems(); QList::ConstIterator itemsIt = selectedItems.constBegin(); while (itemsIt != selectedItems.constEnd()) { KTagListItem* item = dynamic_cast(*itemsIt); @@ -300,23 +229,25 @@ void KTagsView::slotSelectTag(QListWidgetItem* cur, QListWidgetItem* prev) { + Q_D(KTagsView); Q_UNUSED(cur); Q_UNUSED(prev); - m_allowEditing = false; + d->m_allowEditing = false; } void KTagsView::slotSelectTag() { + Q_D(KTagsView); // check if the content of a currently selected tag was modified // and ask to store the data - if (m_updateButton->isEnabled()) { + if (d->ui->m_updateButton->isEnabled()) { if (KMessageBox::questionYesNo(this, QString("%1").arg( - i18n("Do you want to save the changes for %1?", m_newName)), + i18n("Do you want to save the changes for %1?", d->m_newName)), i18n("Save changes")) == KMessageBox::Yes) { - m_inSelection = true; + d->m_inSelection = true; slotUpdateTag(); - m_inSelection = false; + d->m_inSelection = false; } } // loop over all tags and count the number of tags, also @@ -327,86 +258,88 @@ emit selectObjects(tagsList); if (tagsList.isEmpty()) { - m_tabWidget->setEnabled(false); // disable tab widget - m_balanceLabel->hide(); - m_deleteButton->setEnabled(false); //disable delete and rename button - m_renameButton->setEnabled(false); + d->ui->m_tabWidget->setEnabled(false); // disable tab widget + d->ui->m_balanceLabel->hide(); + d->ui->m_deleteButton->setEnabled(false); //disable delete and rename button + d->ui->m_renameButton->setEnabled(false); clearItemData(); - m_tag = MyMoneyTag(); + d->m_tag = MyMoneyTag(); return; // make sure we don't access an undefined tag } - m_deleteButton->setEnabled(true); //re-enable delete button + d->ui->m_deleteButton->setEnabled(true); //re-enable delete button // if we have multiple tags selected, clear and disable the tag information if (tagsList.count() > 1) { - m_tabWidget->setEnabled(false); // disable tab widget - m_renameButton->setEnabled(false); // disable also the rename button - m_balanceLabel->hide(); + d->ui->m_tabWidget->setEnabled(false); // disable tab widget + d->ui->m_renameButton->setEnabled(false); // disable also the rename button + d->ui->m_balanceLabel->hide(); clearItemData(); - } else m_renameButton->setEnabled(true); + } else d->ui->m_renameButton->setEnabled(true); // otherwise we have just one selected, enable tag information widget and renameButton - m_tabWidget->setEnabled(true); - m_balanceLabel->show(); + d->ui->m_tabWidget->setEnabled(true); + d->ui->m_balanceLabel->show(); // as of now we are updating only the last selected tag, and until // selection mode of the QListView has been changed to Extended, this // will also be the only selection and behave exactly as before - Andreas try { - m_tag = tagsList[0]; - - m_newName = m_tag.name(); - m_colorbutton->setEnabled(true); - m_colorbutton->setColor(m_tag.tagColor()); - m_closed->setEnabled(true); - m_closed->setChecked(m_tag.isClosed()); - m_notes->setEnabled(true); - m_notes->setText(m_tag.notes()); + d->m_tag = tagsList[0]; + + d->m_newName = d->m_tag.name(); + d->ui->m_colorbutton->setEnabled(true); + d->ui->m_colorbutton->setColor(d->m_tag.tagColor()); + d->ui->m_closed->setEnabled(true); + d->ui->m_closed->setChecked(d->m_tag.isClosed()); + d->ui->m_notes->setEnabled(true); + d->ui->m_notes->setText(d->m_tag.notes()); slotTagDataChanged(); showTransactions(); } catch (const MyMoneyException &e) { qDebug("exception during display of tag: %s at %s:%ld", qPrintable(e.what()), qPrintable(e.file()), e.line()); - m_register->clear(); - m_tag = MyMoneyTag(); + d->ui->m_register->clear(); + d->m_tag = MyMoneyTag(); } - m_allowEditing = true; + d->m_allowEditing = true; } void KTagsView::clearItemData() { - m_colorbutton->setColor(QColor()); - m_closed->setChecked(false); - m_notes->setText(QString()); + Q_D(KTagsView); + d->ui->m_colorbutton->setColor(QColor()); + d->ui->m_closed->setChecked(false); + d->ui->m_notes->setText(QString()); showTransactions(); } void KTagsView::showTransactions() { + Q_D(KTagsView); MyMoneyMoney balance; - MyMoneyFile *file = MyMoneyFile::instance(); + auto file = MyMoneyFile::instance(); MyMoneySecurity base = file->baseCurrency(); // setup sort order - m_register->setSortOrder(KMyMoneyGlobalSettings::sortSearchView()); + d->ui->m_register->setSortOrder(KMyMoneyGlobalSettings::sortSearchView()); // clear the register - m_register->clear(); + d->ui->m_register->clear(); - if (m_tag.id().isEmpty() || !m_tabWidget->isEnabled()) { - m_balanceLabel->setText(i18n("Balance: %1", balance.formatMoney(file->baseCurrency().smallestAccountFraction()))); + if (d->m_tag.id().isEmpty() || !d->ui->m_tabWidget->isEnabled()) { + d->ui->m_balanceLabel->setText(i18n("Balance: %1", balance.formatMoney(file->baseCurrency().smallestAccountFraction()))); return; } // setup the list and the pointer vector MyMoneyTransactionFilter filter; - filter.addTag(m_tag.id()); + filter.addTag(d->m_tag.id()); filter.setDateFilter(KMyMoneyGlobalSettings::startDate().date(), QDate()); // retrieve the list from the engine - file->transactionList(m_transactionList, filter); + file->transactionList(d->m_transactionList, filter); // create the elements for the register QList >::const_iterator it; @@ -415,13 +348,13 @@ int splitCount = 0; bool balanceAccurate = true; - for (it = m_transactionList.constBegin(); it != m_transactionList.constEnd(); ++it) { + for (it = d->m_transactionList.constBegin(); it != d->m_transactionList.constEnd(); ++it) { const MyMoneySplit& split = (*it).second; MyMoneyAccount acc = file->account(split.accountId()); ++splitCount; uniqueMap[(*it).first.id()]++; - KMyMoneyRegister::Register::transactionFactory(m_register, (*it).first, (*it).second, uniqueMap[(*it).first.id()]); + KMyMoneyRegister::Register::transactionFactory(d->ui->m_register, (*it).first, (*it).second, uniqueMap[(*it).first.id()]); // take care of foreign currencies MyMoneyMoney val = split.shares().abs(); @@ -445,50 +378,52 @@ balance = deposit - payment; // add the group markers - m_register->addGroupMarkers(); + d->ui->m_register->addGroupMarkers(); // sort the transactions according to the sort setting - m_register->sortItems(); + d->ui->m_register->sortItems(); // remove trailing and adjacent markers - m_register->removeUnwantedGroupMarkers(); + d->ui->m_register->removeUnwantedGroupMarkers(); - m_register->updateRegister(true); + d->ui->m_register->updateRegister(true); // we might end up here with updates disabled on the register so // make sure that we enable updates here - m_register->setUpdatesEnabled(true); - m_balanceLabel->setText(i18n("Balance: %1%2", + d->ui->m_register->setUpdatesEnabled(true); + d->ui->m_balanceLabel->setText(i18n("Balance: %1%2", balanceAccurate ? "" : "~", balance.formatMoney(file->baseCurrency().smallestAccountFraction()))); } void KTagsView::slotTagDataChanged() { - bool rc = false; - - if (m_tabWidget->isEnabled()) { - rc |= ((m_tag.tagColor().isValid() != m_colorbutton->color().isValid()) - || (m_colorbutton->color().isValid() && m_tag.tagColor() != m_colorbutton->color())); - rc |= (m_closed->isChecked() != m_tag.isClosed()); - rc |= ((m_tag.notes().isEmpty() != m_notes->toPlainText().isEmpty()) - || (!m_notes->toPlainText().isEmpty() && m_tag.notes() != m_notes->toPlainText())); + Q_D(KTagsView); + auto rc = false; + + if (d->ui->m_tabWidget->isEnabled()) { + rc |= ((d->m_tag.tagColor().isValid() != d->ui->m_colorbutton->color().isValid()) + || (d->ui->m_colorbutton->color().isValid() && d->m_tag.tagColor() != d->ui->m_colorbutton->color())); + rc |= (d->ui->m_closed->isChecked() != d->m_tag.isClosed()); + rc |= ((d->m_tag.notes().isEmpty() != d->ui->m_notes->toPlainText().isEmpty()) + || (!d->ui->m_notes->toPlainText().isEmpty() && d->m_tag.notes() != d->ui->m_notes->toPlainText())); } - m_updateButton->setEnabled(rc); + d->ui->m_updateButton->setEnabled(rc); } void KTagsView::slotUpdateTag() { - if (m_updateButton->isEnabled()) { + Q_D(KTagsView); + if (d->ui->m_updateButton->isEnabled()) { MyMoneyFileTransaction ft; - m_updateButton->setEnabled(false); + d->ui->m_updateButton->setEnabled(false); try { - m_tag.setName(m_newName); - m_tag.setTagColor(m_colorbutton->color()); - m_tag.setClosed(m_closed->isChecked()); - m_tag.setNotes(m_notes->toPlainText()); + d->m_tag.setName(d->m_newName); + d->m_tag.setTagColor(d->ui->m_colorbutton->color()); + d->m_tag.setClosed(d->ui->m_closed->isChecked()); + d->m_tag.setNotes(d->ui->m_notes->toPlainText()); - MyMoneyFile::instance()->modifyTag(m_tag); + MyMoneyFile::instance()->modifyTag(d->m_tag); ft.commit(); } catch (const MyMoneyException &e) { @@ -500,15 +435,14 @@ void KTagsView::showEvent(QShowEvent* event) { - if (m_needLoad) - init(); + Q_D(KTagsView); + if (d->m_needLoad) + d->init(); - emit aboutToShow(); + emit aboutToShow(View::Tags); - if (m_needReload) { - loadTags(); - m_needReload = false; - } + if (d->m_needsRefresh) + refresh(); // don't forget base class implementation QWidget::showEvent(event); @@ -518,21 +452,10 @@ emit selectObjects(list); } -void KTagsView::slotLoadTags() -{ - if (isVisible()) { - if (m_inSelection) - QTimer::singleShot(0, this, SLOT(slotLoadTags())); - else - loadTags(); - } else { - m_needReload = true; - } -} - void KTagsView::loadTags() { - if (m_inSelection) + Q_D(KTagsView); + if (d->m_inSelection) return; QMap isSelected; @@ -540,7 +463,7 @@ MyMoneyFile* file = MyMoneyFile::instance(); // remember which items are selected in the list - QList selectedItems = m_tagsList->selectedItems(); + QList selectedItems = d->ui->m_tagsList->selectedItems(); QList::const_iterator tagsIt = selectedItems.constBegin(); while (tagsIt != selectedItems.constEnd()) { @@ -551,50 +474,49 @@ } // keep current selected item - KTagListItem *currentItem = static_cast(m_tagsList->currentItem()); + KTagListItem *currentItem = static_cast(d->ui->m_tagsList->currentItem()); if (currentItem) id = currentItem->tag().id(); - m_allowEditing = false; + d->m_allowEditing = false; // clear the list - m_searchWidget->clear(); - m_searchWidget->updateSearch(); - m_tagsList->clear(); - m_register->clear(); + d->m_searchWidget->clear(); + d->m_searchWidget->updateSearch(); + d->ui->m_tagsList->clear(); + d->ui->m_register->clear(); currentItem = 0; QListlist = file->tagList(); QList::ConstIterator it; for (it = list.constBegin(); it != list.constEnd(); ++it) { - if (m_tagFilterType == eAllTags || - (m_tagFilterType == eReferencedTags && file->isReferenced(*it)) || - (m_tagFilterType == eUnusedTags && !file->isReferenced(*it)) || - (m_tagFilterType == eOpenedTags && !(*it).isClosed()) || - (m_tagFilterType == eClosedTags && (*it).isClosed())) { - KTagListItem* item = new KTagListItem(m_tagsList, *it); + if (d->m_tagFilterType == (int)eView::Tag::All || + (d->m_tagFilterType == (int)eView::Tag::Referenced && file->isReferenced(*it)) || + (d->m_tagFilterType == (int)eView::Tag::Unused && !file->isReferenced(*it)) || + (d->m_tagFilterType == (int)eView::Tag::Opened && !(*it).isClosed()) || + (d->m_tagFilterType == (int)eView::Tag::Closed && (*it).isClosed())) { + KTagListItem* item = new KTagListItem(d->ui->m_tagsList, *it); if (item->tag().id() == id) currentItem = item; if (isSelected[item->tag().id()]) item->setSelected(true); } } - m_tagsList->sortItems(); + d->ui->m_tagsList->sortItems(); if (currentItem) { - m_tagsList->setCurrentItem(currentItem); - m_tagsList->scrollToItem(currentItem); + d->ui->m_tagsList->setCurrentItem(currentItem); + d->ui->m_tagsList->scrollToItem(currentItem); } - m_filterProxyModel->invalidate(); - slotSelectTag(0, 0); - m_allowEditing = true; + d->m_allowEditing = true; } void KTagsView::slotSelectTransaction() { - QList list = m_register->selectedItems(); + Q_D(KTagsView); + QList list = d->ui->m_register->selectedItems(); if (!list.isEmpty()) { KMyMoneyRegister::Transaction* t = dynamic_cast(list[0]); if (t) @@ -607,13 +529,14 @@ if (!isVisible()) return; + Q_D(KTagsView); try { // clear filter - m_searchWidget->clear(); - m_searchWidget->updateSearch(); + d->m_searchWidget->clear(); + d->m_searchWidget->updateSearch(); // deselect all other selected items - QList selectedItems = m_tagsList->selectedItems(); + QList selectedItems = d->ui->m_tagsList->selectedItems(); QList::const_iterator tagsIt = selectedItems.constBegin(); while (tagsIt != selectedItems.constEnd()) { KTagListItem* item = dynamic_cast(*tagsIt); @@ -624,26 +547,26 @@ // find the tag in the list QListWidgetItem* it; - for (int i = 0; i < m_tagsList->count(); ++i) { - it = m_tagsList->item(i); + for (int i = 0; i < d->ui->m_tagsList->count(); ++i) { + it = d->ui->m_tagsList->item(i); KTagListItem* item = dynamic_cast(it); if (item && item->tag().id() == tagId) { - m_tagsList->scrollToItem(it, QAbstractItemView::PositionAtCenter); + d->ui->m_tagsList->scrollToItem(it, QAbstractItemView::PositionAtCenter); - m_tagsList->setCurrentItem(it); // active item and deselect all others - m_tagsList->setCurrentRow(i, QItemSelectionModel::ClearAndSelect); // and select it + d->ui->m_tagsList->setCurrentItem(it); // active item and deselect all others + d->ui->m_tagsList->setCurrentRow(i, QItemSelectionModel::ClearAndSelect); // and select it //make sure the tag selection is updated and transactions are updated accordingly slotSelectTag(); KMyMoneyRegister::RegisterItem *item = 0; - for (int i = 0; i < m_register->rowCount(); ++i) { - item = m_register->itemAtRow(i); + for (int i = 0; i < d->ui->m_register->rowCount(); ++i) { + item = d->ui->m_register->itemAtRow(i); KMyMoneyRegister::Transaction* t = dynamic_cast(item); if (t) { if (t->transaction().id() == transactionId && t->transaction().accountReferenced(accountId)) { - m_register->selectItem(item); - m_register->ensureItemVisible(item); + d->ui->m_register->selectItem(item); + d->ui->m_register->ensureItemVisible(item); break; } } @@ -657,9 +580,15 @@ } } +void KTagsView::slotSelectTagAndTransaction(const QString& tagId) +{ + slotSelectTagAndTransaction(tagId, QString(), QString()); +} + void KTagsView::slotOpenContextMenu(const QPoint& /*ta*/) { - KTagListItem* item = dynamic_cast(m_tagsList->currentItem()); + Q_D(KTagsView); + auto item = dynamic_cast(d->ui->m_tagsList->currentItem()); if (item) { slotSelectTag(); emit openContextMenu(item->tag()); @@ -671,6 +600,11 @@ kmymoney->actionCollection()->action(kmymoney->s_Actions[Action::TagNew])->trigger(); } +void KTagsView::slotTagDelete() +{ + kmymoney->actionCollection()->action(kmymoney->s_Actions[Action::TagDelete])->trigger(); +} + void KTagsView::slotHelp() { KHelpClient::invokeHelp("details.tags.attributes"); @@ -679,7 +613,8 @@ void KTagsView::slotChangeFilter(int index) { + Q_D(KTagsView); //update the filter type then reload the tags list - m_tagFilterType = index; + d->m_tagFilterType = index; loadTags(); } diff --git a/kmymoney/views/ktagsviewdecl.ui b/kmymoney/views/ktagsview.ui rename from kmymoney/views/ktagsviewdecl.ui rename to kmymoney/views/ktagsview.ui --- a/kmymoney/views/ktagsviewdecl.ui +++ b/kmymoney/views/ktagsview.ui @@ -1,7 +1,7 @@ - KTagsViewDecl - + KTagsView + 0 @@ -11,7 +11,16 @@ - + + 0 + + + 0 + + + 0 + + 0 @@ -39,6 +48,12 @@ + + Creates a new tag + + + Use this to create a new tag. + New @@ -46,6 +61,12 @@ + + Rename the current selected tag + + + Use this to start renaming the selected tag. + Ren @@ -53,6 +74,12 @@ + + Delete the current selected tag + + + Use this to delete the selected tag. + Del @@ -112,7 +139,16 @@ 6 - + + 11 + + + 11 + + + 11 + + 11 @@ -120,7 +156,16 @@ 6 - + + 0 + + + 0 + + + 0 + + 0 @@ -170,7 +215,16 @@ Tag configuration - + + 11 + + + 11 + + + 11 + + 11 @@ -300,6 +354,12 @@ 0 + + Accepts the entered data and stores it + + + Use this to accept the modified data. + @@ -319,25 +379,14 @@
kcolorbutton.h
- KComboBox - QComboBox -
kcombobox.h
-
- KTextEdit QTextEdit
ktextedit.h
- QListWidget - QListWidget -
klistwidget.h
-
- - QTabWidget - QTabWidget -
ktabwidget.h
- 1 + KComboBox + QComboBox +
kcombobox.h
KMyMoneyRegister::Register diff --git a/kmymoney/views/ktagsview_p.h b/kmymoney/views/ktagsview_p.h new file mode 100644 --- /dev/null +++ b/kmymoney/views/ktagsview_p.h @@ -0,0 +1,181 @@ +/*************************************************************************** + ktagsview_p.h + ------------- + begin : Sat Oct 13 2012 + copyright : (C) 2012 by Alessandro Russo + (C) 2017 by Łukasz Wojniłowicz + ***************************************************************************/ + +/*************************************************************************** + * * + * 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) any later version. * + * * + ***************************************************************************/ + +#ifndef KTAGSVIEW_P_H +#define KTAGSVIEW_P_H + +#include "ktagsview.h" + +// ---------------------------------------------------------------------------- +// QT Includes + +#include + +// ---------------------------------------------------------------------------- +// KDE Includes + +#include +#include +#include +#include + +// ---------------------------------------------------------------------------- +// Project Includes + +#include "ui_ktagsview.h" + +#include "kmymoneyviewbase_p.h" +#include "mymoneyfile.h" +#include "mymoneytag.h" +#include "mymoneytransactionfilter.h" +#include "icons.h" +#include "viewenums.h" + +using namespace Icons; +namespace Ui { class KTagsView; } + +class KTagsViewPrivate : public KMyMoneyViewBasePrivate +{ + Q_DECLARE_PUBLIC(KTagsView) + +public: + + KTagsViewPrivate(KTagsView *qq) : + q_ptr(qq), + ui(new Ui::KTagsView) + { + } + + ~KTagsViewPrivate() + { + delete ui; + } + + void init() + { + Q_Q(KTagsView); + m_needLoad = false; + ui->setupUi(q); + + // create the searchline widget + // and insert it into the existing layout + m_searchWidget = new KListWidgetSearchLine(q, ui->m_tagsList); + m_searchWidget->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed)); + ui->m_tagsList->setContextMenuPolicy(Qt::CustomContextMenu); + ui->m_listTopHLayout->insertWidget(0, m_searchWidget); + + //load the filter type + ui->m_filterBox->addItem(i18nc("@item Show all tags", "All")); + ui->m_filterBox->addItem(i18nc("@item Show only used tags", "Used")); + ui->m_filterBox->addItem(i18nc("@item Show only unused tags", "Unused")); + ui->m_filterBox->addItem(i18nc("@item Show only opened tags", "Opened")); + ui->m_filterBox->addItem(i18nc("@item Show only closed tags", "Closed")); + ui->m_filterBox->setSizeAdjustPolicy(QComboBox::AdjustToContents); + + ui->m_newButton->setIcon(QIcon::fromTheme(g_Icons[Icon::ListAddTag])); + ui->m_renameButton->setIcon(QIcon::fromTheme(g_Icons[Icon::EditRename])); + ui->m_deleteButton->setIcon(QIcon::fromTheme(g_Icons[Icon::ListRemoveTag])); + ui->m_updateButton->setIcon(QIcon::fromTheme(g_Icons[Icon::DialogOK])); + ui->m_updateButton->setEnabled(false); + + ui->m_register->setupRegister(MyMoneyAccount(), + QList { KMyMoneyRegister::DateColumn, + KMyMoneyRegister::AccountColumn, + KMyMoneyRegister::DetailColumn, + KMyMoneyRegister::ReconcileFlagColumn, + KMyMoneyRegister::PaymentColumn, + KMyMoneyRegister::DepositColumn + }); + ui->m_register->setSelectionMode(QTableWidget::SingleSelection); + ui->m_register->setDetailsColumnType(KMyMoneyRegister::AccountFirst); + ui->m_balanceLabel->hide(); + + q->connect(ui->m_tagsList, &QListWidget::currentItemChanged, q, static_cast(&KTagsView::slotSelectTag)); + q->connect(ui->m_tagsList, &QListWidget::itemSelectionChanged, q, static_cast(&KTagsView::slotSelectTag)); + q->connect(ui->m_tagsList, &QListWidget::itemDoubleClicked, q, &KTagsView::slotStartRename); + q->connect(ui->m_tagsList, &QListWidget::itemChanged, q, &KTagsView::slotRenameTag); + q->connect(ui->m_tagsList, &QWidget::customContextMenuRequested, q, &KTagsView::slotOpenContextMenu); + + q->connect(ui->m_renameButton, &QAbstractButton::clicked, q, &KTagsView::slotRenameButtonCliked); + q->connect(ui->m_deleteButton, &QAbstractButton::clicked, q, &KTagsView::slotTagDelete); + q->connect(ui->m_newButton, &QAbstractButton::clicked, q, &KTagsView::slotTagNew); + + q->connect(ui->m_colorbutton, &KColorButton::changed, q, &KTagsView::slotTagDataChanged); + q->connect(ui->m_closed, &QCheckBox::stateChanged, q, &KTagsView::slotTagDataChanged); + q->connect(ui->m_notes, &QTextEdit::textChanged, q, &KTagsView::slotTagDataChanged); + + q->connect(ui->m_updateButton, &QAbstractButton::clicked, q, &KTagsView::slotUpdateTag); + q->connect(ui->m_helpButton, &QAbstractButton::clicked, q, &KTagsView::slotHelp); + + q->connect(ui->m_register, &KMyMoneyRegister::Register::editTransaction, q, &KTagsView::slotSelectTransaction); + + q->connect(MyMoneyFile::instance(), &MyMoneyFile::dataChanged, q, &KTagsView::refresh); + + q->connect(ui->m_filterBox, static_cast(&QComboBox::currentIndexChanged), q, &KTagsView::slotChangeFilter); + + // use the size settings of the last run (if any) + auto grp = KSharedConfig::openConfig()->group("Last Use Settings"); + ui->m_splitter->restoreState(grp.readEntry("KTagsViewSplitterSize", QByteArray())); + ui->m_splitter->setChildrenCollapsible(false); + + // At start we haven't any tag selected + ui->m_tabWidget->setEnabled(false); // disable tab widget + ui->m_deleteButton->setEnabled(false); // disable delete and rename button + ui->m_renameButton->setEnabled(false); + m_tag = MyMoneyTag(); // make sure we don't access an undefined tag + q->clearItemData(); + } + + KTagsView *q_ptr; + Ui::KTagsView *ui; + + MyMoneyTag m_tag; + QString m_newName; + + /** + * This member holds a list of all transactions + */ + QList > m_transactionList; + + /** + * This member holds the load state of page + */ + bool m_needLoad; + + /** + * Search widget for the list + */ + KListWidgetSearchLine* m_searchWidget; + + /** + * Semaphore to suppress loading during selection + */ + bool m_inSelection; + + /** + * This signals whether a tag can be edited + **/ + bool m_allowEditing; + + /** + * This holds the filter type + */ + int m_tagFilterType; +}; + + +#endif diff --git a/kmymoney/views/viewenums.h b/kmymoney/views/viewenums.h --- a/kmymoney/views/viewenums.h +++ b/kmymoney/views/viewenums.h @@ -14,7 +14,7 @@ * * ***************************************************************************/ -#include +#include #ifndef VIEWENUMS_H #define VIEWENUMS_H @@ -24,4 +24,13 @@ inline uint qHash(const View key, uint seed) { return ::qHash(static_cast(key), seed); } +namespace eView { + enum class Tag { All = 0, + Referenced, // used tags + Unused, // unused tags + Opened, // not closed tags + Closed // closed tags + }; +} + #endif