Commit d07fbc9a authored by Thomas Baumgart's avatar Thomas Baumgart
Browse files

Added the long awaited 'tags' feature

Thanks to the implementation provided by Alessandro Russo, we now have
the long awaited tagging feature.

REVIEW: 106846
FEATURE: 207761
DIGEST:
parent e492b209
ADD_SUBDIRECTORY( settings )
ADD_SUBDIRECTORY( settings )
########### next target ###############
SET(libdialogs_a_SOURCES
investactivities.cpp
investactivities.cpp
investtransactioneditor.cpp
kaccountselectdlg.cpp
kbackupdlg.cpp
kaccountselectdlg.cpp
kbackupdlg.cpp
kbalancechartdlg.cpp
kbalancewarning.cpp
kbalancewarning.cpp
kcategoryreassigndlg.cpp
kchooseimportexportdlg.cpp
kchooseimportexportdlg.cpp
kconfirmmanualenterdlg.cpp
kcurrencycalculator.cpp
kcurrencycalculator.cpp
kcurrencyeditdlg.cpp
keditscheduledlg.cpp
kenterscheduledlg.cpp
kequitypriceupdatedlg.cpp
kexportdlg.cpp
kfindtransactiondlg.cpp
kequitypriceupdatedlg.cpp
kexportdlg.cpp
kfindtransactiondlg.cpp
kgeneratesqldlg.cpp
kgncimportoptionsdlg.cpp
kgncimportoptionsdlg.cpp
kgncpricesourcedlg.cpp
kgpgkeyselectiondlg.cpp
kgpgkeyselectiondlg.cpp
kimportdlg.cpp
kloadtemplatedlg.cpp
kmergetransactionsdlg.cpp
kmergetransactionsdlg.cpp
kmymoneyfileinfodlg.cpp
kmymoneypricedlg.cpp
kmymoneysplittable.cpp
kmymoneypricedlg.cpp
kmymoneysplittable.cpp
knewaccountdlg.cpp
knewbankdlg.cpp
knewbudgetdlg.cpp
knewbankdlg.cpp
knewbudgetdlg.cpp
knewequityentrydlg.cpp
knewfiledlg.cpp
kpayeereassigndlg.cpp
knewfiledlg.cpp
kpayeereassigndlg.cpp
ktagreassigndlg.cpp
kreportconfigurationfilterdlg.cpp
kselectdatabasedlg.cpp
kselecttransactionsdlg.cpp
ksplittransactiondlg.cpp
kupdatestockpricedlg.cpp
kselecttransactionsdlg.cpp
ksplittransactiondlg.cpp
kupdatestockpricedlg.cpp
mymoneyqifprofileeditor.cpp
transactioneditor.cpp
transactioneditor.cpp
transactionmatcher.cpp
)
......@@ -62,6 +63,7 @@ SET(dialogs_UI
kmymoneyfileinfodlgdecl.ui kmymoneypricedlgdecl.ui
knewaccountdlgdecl.ui knewbankdlgdecl.ui knewbudgetdlgdecl.ui
knewequityentrydecl.ui knewfiledlgdecl.ui kpayeereassigndlgdecl.ui
ktagreassigndlgdecl.ui
kselectdatabasedlgdecl.ui kselecttransactionsdlgdecl.ui
ksortoptiondlg.ui ksplitcorrectiondlg.ui ksplittransactiondlgdecl.ui
kupdatestockpricedlgdecl.ui mymoneyqifprofileeditordecl.ui
......
......@@ -137,6 +137,7 @@ KFindTransactionDlg::KFindTransactionDlg(QWidget *parent) :
setupDatePage();
setupAmountPage();
setupPayeesPage();
setupTagsPage();
setupDetailsPage();
// We don't need to add the default into the list (see ::slotShowHelp() why)
......@@ -146,6 +147,7 @@ KFindTransactionDlg::KFindTransactionDlg(QWidget *parent) :
m_helpAnchor[m_ui->m_amountTab] = QString("details.search.amount");
m_helpAnchor[m_ui->m_categoryTab] = QString("details.search.category");
m_helpAnchor[m_ui->m_payeeTab] = QString("details.search.payee");
m_helpAnchor[m_ui->m_tagTab] = QString("details.search.tag"); //FIXME-ALEX update Help
m_helpAnchor[m_ui->m_detailsTab] = QString("details.search.details");
// setup the register
......@@ -210,6 +212,9 @@ void KFindTransactionDlg::slotReset(void)
m_ui->m_emptyPayeesButton->setChecked(false);
selectAllItems(m_ui->m_payeesView, true);
m_ui->m_emptyTagsButton->setChecked(false);
selectAllItems(m_ui->m_tagsView, true);
m_ui->m_typeBox->setCurrentIndex(MyMoneyTransactionFilter::allTypes);
m_ui->m_stateBox->setCurrentIndex(MyMoneyTransactionFilter::allStates);
m_ui->m_validityBox->setCurrentIndex(MyMoneyTransactionFilter::anyValidity);
......@@ -278,6 +283,15 @@ void KFindTransactionDlg::slotUpdateSelections(void)
txt += i18n("Category");
}
// Tags tab
if (!allItemsSelected(m_ui->m_tagsView)
|| m_ui->m_emptyTagsButton->isChecked()) {
if (!txt.isEmpty())
txt += ", ";
txt += i18n("Tags");
}
m_ui->m_tagsView->setEnabled(!m_ui->m_emptyTagsButton->isChecked());
// Payees tab
if (!allItemsSelected(m_ui->m_payeesView)
|| m_ui->m_emptyPayeesButton->isChecked()) {
......@@ -542,6 +556,48 @@ void KFindTransactionDlg::slotDeselectAllPayees(void)
selectAllItems(m_ui->m_payeesView, false);
}
void KFindTransactionDlg::setupTagsPage(void)
{
m_ui->m_tagsView->setSelectionMode(QAbstractItemView::SingleSelection);
m_ui->m_tagsView->header()->hide();
m_ui->m_tagsView->setAlternatingRowColors(true);
loadTags();
m_ui->m_tagsView->sortItems(0, Qt::AscendingOrder);
m_ui->m_emptyTagsButton->setCheckState(Qt::Unchecked);
connect(m_ui->m_allTagsButton, SIGNAL(clicked()), this, SLOT(slotSelectAllTags()));
connect(m_ui->m_clearTagsButton, SIGNAL(clicked()), this, SLOT(slotDeselectAllTags()));
connect(m_ui->m_emptyTagsButton, SIGNAL(stateChanged(int)), this, SLOT(slotUpdateSelections()));
connect(m_ui->m_tagsView, SIGNAL(itemChanged(QTreeWidgetItem*,int)), this, SLOT(slotUpdateSelections()));
}
void KFindTransactionDlg::loadTags(void)
{
MyMoneyFile* file = MyMoneyFile::instance();
QList<MyMoneyTag> list;
QList<MyMoneyTag>::Iterator it_l;
list = file->tagList();
// load view
for (it_l = list.begin(); it_l != list.end(); ++it_l) {
QTreeWidgetItem* item = new QTreeWidgetItem(m_ui->m_tagsView);
item->setText(0, (*it_l).name());
item->setData(0, ItemIdRole, (*it_l).id());
item->setCheckState(0, Qt::Checked);
}
}
void KFindTransactionDlg::slotSelectAllTags(void)
{
selectAllItems(m_ui->m_tagsView, true);
}
void KFindTransactionDlg::slotDeselectAllTags(void)
{
selectAllItems(m_ui->m_tagsView, false);
}
void KFindTransactionDlg::setupDetailsPage(void)
{
connect(m_ui->m_typeBox, SIGNAL(activated(int)), this, SLOT(slotUpdateSelections()));
......@@ -586,6 +642,9 @@ void KFindTransactionDlg::addItemToFilter(const opTypeE op, const QString& id)
case addPayeeToFilter:
m_filter.addPayee(id);
break;
case addTagToFilter:
m_filter.addTag(id);
break;
}
}
......@@ -684,6 +743,14 @@ void KFindTransactionDlg::setupFilter(void)
m_filter.addCategory(m_ui->m_categoriesView->selectedItems());
}
// Tags tab
if (m_ui->m_emptyTagsButton->isChecked()) {
m_filter.addTag(QString());
} else if (!allItemsSelected(m_ui->m_tagsView)) {
scanCheckListItems(m_ui->m_tagsView, addTagToFilter);
}
// Payees tab
if (m_ui->m_emptyPayeesButton->isChecked()) {
m_filter.addPayee(QString());
......
......@@ -131,6 +131,9 @@ protected slots:
virtual void slotSelectAllPayees(void);
virtual void slotDeselectAllPayees(void);
virtual void slotSelectAllTags(void);
virtual void slotDeselectAllTags(void);
virtual void slotNrSelected(void);
virtual void slotNrRangeSelected(void);
......@@ -161,7 +164,8 @@ protected:
enum opTypeE {
addAccountToFilter = 0,
addCategoryToFilter,
addPayeeToFilter
addPayeeToFilter,
addTagToFilter
};
void setupCategoriesPage(void);
......@@ -169,6 +173,7 @@ protected:
void setupAccountsPage(void);
void setupAmountPage(void);
void setupPayeesPage(void);
void setupTagsPage(void);
void setupDetailsPage(void);
void setupFilter(void);
......@@ -184,6 +189,12 @@ protected:
*/
void loadPayees(void);
/**
* This method loads the m_tagsView with the tags name
* found in the engine.
*/
void loadTags(void);
/**
* This method loads the register with the matching transactions
*/
......
......@@ -370,6 +370,94 @@
</item>
</layout>
</widget>
<widget class="QWidget" name="m_tagTab">
<attribute name="title">
<string>Tag</string>
</attribute>
<layout class="QHBoxLayout">
<property name="margin">
<number>11</number>
</property>
<property name="spacing">
<number>6</number>
</property>
<item>
<layout class="QVBoxLayout">
<property name="margin">
<number>0</number>
</property>
<property name="spacing">
<number>6</number>
</property>
<item>
<widget class="QTreeWidget" name="m_tagsView">
<property name="rootIsDecorated">
<bool>false</bool>
</property>
<column>
<property name="text">
<string>Tag</string>
</property>
<property name="clickable">
<bool>false</bool>
</property>
<property name="resizable">
<bool>true</bool>
</property>
</column>
</widget>
</item>
<item>
<widget class="QCheckBox" name="m_emptyTagsButton">
<property name="text">
<string>Select transactions without tags</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QVBoxLayout">
<property name="margin">
<number>0</number>
</property>
<property name="spacing">
<number>6</number>
</property>
<item>
<widget class="KPushButton" name="m_allTagsButton">
<property name="text">
<string>Select all</string>
</property>
</widget>
</item>
<item>
<widget class="KPushButton" name="m_clearTagsButton">
<property name="text">
<string>Select none</string>
</property>
</widget>
</item>
<item>
<spacer name="Spacer29">
<property name="sizeHint">
<size>
<width>0</width>
<height>42</height>
</size>
</property>
<property name="sizeType">
<enum>QSizePolicy::Expanding</enum>
</property>
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</widget>
<widget class="QWidget" name="m_payeeTab">
<attribute name="title">
<string>Payee</string>
......@@ -439,7 +527,7 @@
</widget>
</item>
<item>
<spacer name="Spacer29">
<spacer name="Spacer291">
<property name="sizeHint">
<size>
<width>0</width>
......
......@@ -195,7 +195,7 @@ void KReportConfigurationFilterDlg::slotSearch(void)
m_currentState.setMovingAverageDays(m_tab2->findChild<QSpinBox*>("m_movingAverageDays")->value());
}
} else if (m_tab3) {
MyMoneyReport::ERowType rtq[7] = { MyMoneyReport::eCategory, MyMoneyReport::eTopCategory, MyMoneyReport::ePayee, MyMoneyReport::eAccount, MyMoneyReport::eTopAccount, MyMoneyReport::eMonth, MyMoneyReport::eWeek };
MyMoneyReport::ERowType rtq[8] = { MyMoneyReport::eCategory, MyMoneyReport::eTopCategory, MyMoneyReport::eTag, MyMoneyReport::ePayee, MyMoneyReport::eAccount, MyMoneyReport::eTopAccount, MyMoneyReport::eMonth, MyMoneyReport::eWeek };
m_currentState.setRowType(rtq[m_tab3->findChild<KComboBox*>("m_comboOrganizeBy")->currentIndex()]);
unsigned qc = MyMoneyReport::eQCnone;
......@@ -208,6 +208,8 @@ void KReportConfigurationFilterDlg::slotSearch(void)
qc |= MyMoneyReport::eQCnumber;
if (m_tab3->findChild<QCheckBox*>("m_checkPayee")->isChecked())
qc |= MyMoneyReport::eQCpayee;
if (m_tab3->findChild<QCheckBox*>("m_checkTag")->isChecked())
qc |= MyMoneyReport::eQCtag;
if (m_tab3->findChild<QCheckBox*>("m_checkCategory")->isChecked())
qc |= MyMoneyReport::eQCcategory;
if (m_tab3->findChild<QCheckBox*>("m_checkMemo")->isChecked())
......@@ -384,6 +386,9 @@ void KReportConfigurationFilterDlg::slotReset(void)
case MyMoneyReport::eTopCategory:
combo->setCurrentItem(i18n("Top Categories"), false);
break;
case MyMoneyReport::eTag:
combo->setCurrentItem(i18n("Tags"), false);
break;
case MyMoneyReport::ePayee:
combo->setCurrentItem(i18n("Payees"), false);
break;
......@@ -406,6 +411,7 @@ void KReportConfigurationFilterDlg::slotReset(void)
unsigned qc = m_initialState.queryColumns();
m_tab3->findChild<QCheckBox*>("m_checkNumber")->setChecked(qc & MyMoneyReport::eQCnumber);
m_tab3->findChild<QCheckBox*>("m_checkPayee")->setChecked(qc & MyMoneyReport::eQCpayee);
m_tab3->findChild<QCheckBox*>("m_checkTag")->setChecked(qc & MyMoneyReport::eQCtag);
m_tab3->findChild<QCheckBox*>("m_checkCategory")->setChecked(qc & MyMoneyReport::eQCcategory);
m_tab3->findChild<QCheckBox*>("m_checkMemo")->setChecked(qc & MyMoneyReport::eQCmemo);
m_tab3->findChild<QCheckBox*>("m_checkAccount")->setChecked(qc & MyMoneyReport::eQCaccount);
......@@ -557,6 +563,22 @@ void KReportConfigurationFilterDlg::slotReset(void)
selectAllItems(m_ui->m_payeesView, true);
}
//
// Tags Filter
//
QStringList tags;
if (m_initialState.tags(tags)) {
if (tags.empty()) {
m_ui->m_emptyTagsButton->setChecked(true);
} else {
selectAllItems(m_ui->m_tagsView, false);
selectItems(m_ui->m_tagsView, tags, true);
}
} else {
selectAllItems(m_ui->m_tagsView, true);
}
//
// Accounts Filter
//
......
/***************************************************************************
ktagreassigndlg.cpp
-------------------
copyright : (C) 2011 by Alessandro Russo <axela74@yahoo.it>
***************************************************************************/
/***************************************************************************
* *
* 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. *
* *
***************************************************************************/
#include "ktagreassigndlg.h"
// ----------------------------------------------------------------------------
// QT Includes
#include <QList>
// ----------------------------------------------------------------------------
// KDE Includes
#include <kdialog.h>
#include <klocale.h>
#include <kstdguiitem.h>
#include <kpushbutton.h>
#include <kmessagebox.h>
// ----------------------------------------------------------------------------
// Project Includes
#include <kmymoneymvccombo.h>
#include <kguiutils.h>
KTagReassignDlg::KTagReassignDlg(QWidget* parent) :
KTagReassignDlgDecl(parent)
{
buttonOk->setGuiItem(KStandardGuiItem::ok());
buttonCancel->setGuiItem(KStandardGuiItem::cancel());
kMandatoryFieldGroup* mandatory = new kMandatoryFieldGroup(this);
mandatory->add(tagCombo);
mandatory->setOkButton(buttonOk);
}
KTagReassignDlg::~KTagReassignDlg()
{
}
QString KTagReassignDlg::show(const QList<MyMoneyTag>& tagslist)
{
if (tagslist.isEmpty())
return QString(); // no tag available? nothing can be selected...
tagCombo->loadTags(tagslist);
// execute dialog and if aborted, return empty string
if (this->exec() == QDialog::Rejected)
return QString();
// otherwise return index of selected tag
return tagCombo->selectedItem();
}
void KTagReassignDlg::accept(void)
{
// force update of tagCombo
buttonOk->setFocus();
if (tagCombo->selectedItem().isEmpty()) {
KMessageBox::information(this, i18n("This dialog does not allow new tags to be created. Please pick a tag from the list."), i18n("Tag creation"));
} else {
KTagReassignDlgDecl::accept();
}
}
#include "ktagreassigndlg.moc"
/***************************************************************************
ktagreassigndlg.cpp
-------------------
copyright : (C) 2012 by Alessandro Russo <axela74@yahoo.it>
***************************************************************************/
/***************************************************************************
* *
* 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 KTAGREASSIGNDLG_H
#define KTAGREASSIGNDLG_H
// ----------------------------------------------------------------------------
// QT Includes
#include <QCheckBox>
// ----------------------------------------------------------------------------
// KDE Includes
// ----------------------------------------------------------------------------
// Project Includes
#include <mymoneytag.h>
#include "ui_ktagreassigndlgdecl.h"
/**
* Implementation of the dialog that lets the user select a tag in order
* to re-assign transactions (for instance, if tags are deleted).
*/
class KTagReassignDlgDecl : public QDialog, public Ui::KTagReassignDlgDecl
{
public:
KTagReassignDlgDecl(QWidget *parent) : QDialog(parent) {
setupUi(this);
}
};
class KTagReassignDlg : public KTagReassignDlgDecl
{
Q_OBJECT
public:
/** Default constructor */
KTagReassignDlg(QWidget* parent = 0);
/** Destructor */
~KTagReassignDlg();
/**
* This function sets up the dialog, lets the user select a tag and returns
* the id of the selected tag in the tagslist.
*
* @param tagslist reference to QList of MyMoneyTag objects to be contained in the list
*
* @return Returns the id of the selected tag in the list or QString() if
* the dialog was aborted. QString() is also returned if the tagslist is empty.
*/
QString show(const QList<MyMoneyTag>& tagslist);
protected:
void accept(void);
};
#endif // KTAGREASSIGNDLG_H
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>KTagReassignDlgDecl</class>
<widget class="QDialog" name="KTagReassignDlgDecl">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>558</width>
<height>312</height>
</rect>
</property>
<property name="windowTitle">
<string>Reassign tags</string>
</property>
<property name="sizeGripEnabled">
<bool>false</bool>
</property>
<property name="modal">
<bool>true</bool>
</property>
<layout class="QVBoxLayout">
<item>
<widget class="QLabel" name="textLabel1">
<property name="minimumSize">
<size>
<width>300</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>The transactions associated with the selected tags need to be re-assigned to a different tag before the selected tags can be deleted. Please select a tag from the list below.</string>
</property>
<property name="alignment">
<set>Qt::AlignJustify|Qt::AlignTop</set>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<spacer name="spacer8">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>16</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="textLabel2">
<property name="text">