1 /*
2  * Copyright 2012       Alessandro Russo <axela74@yahoo.it>
3  * Copyright 2017       Łukasz Wojniłowicz <lukasz.wojnilowicz@gmail.com>
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License as
7  * published by the Free Software Foundation; either version 2 of
8  * the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
17  */
18 
19 #ifndef KTAGSVIEW_P_H
20 #define KTAGSVIEW_P_H
21 
22 #include "ktagsview.h"
23 
24 // ----------------------------------------------------------------------------
25 // QT Includes
26 
27 #include <QList>
28 
29 // ----------------------------------------------------------------------------
30 // KDE Includes
31 
32 #include <KLocalizedString>
33 #include <KSharedConfig>
34 #include <KConfigGroup>
35 #include <KListWidgetSearchLine>
36 
37 // ----------------------------------------------------------------------------
38 // Project Includes
39 
40 #include "ui_ktagsview.h"
41 
42 #include "kmymoneyviewbase_p.h"
43 #include "mymoneyaccount.h"
44 #include "mymoneyfile.h"
45 #include "mymoneytag.h"
46 #include "mymoneytransactionfilter.h"
47 #include "icons.h"
48 #include "viewenums.h"
49 #include "widgetenums.h"
50 
51 using namespace Icons;
52 namespace Ui { class KTagsView; }
53 
54 // *** KTagListItem Implementation ***
55 
56 /**
57   * This class represents an item in the tags list view.
58   */
59 class KTagListItem : public QListWidgetItem
60 {
61 public:
62   /**
63     * Constructor to be used to construct a tag entry object.
64     *
65     * @param parent pointer to the QListWidget object this entry should be
66     *               added to.
67     * @param tag    const reference to MyMoneyTag for which
68     *               the QListWidget entry is constructed
69     */
KTagListItem(QListWidget * parent,const MyMoneyTag & tag)70   explicit KTagListItem(QListWidget *parent, const MyMoneyTag& tag) :
71     QListWidgetItem(parent, QListWidgetItem::UserType),
72     m_tag(tag)
73   {
74     setText(tag.name());
75     // allow in column rename
76     setFlags(Qt::ItemIsEditable | Qt::ItemIsSelectable | Qt::ItemIsEnabled);
77   }
78 
~KTagListItem()79   ~KTagListItem() {}
80 
tag()81   MyMoneyTag tag() const
82   {
83     return m_tag;
84   }
85 
86 private:
87   MyMoneyTag  m_tag;
88 };
89 
90 class KTagsViewPrivate : public KMyMoneyViewBasePrivate
91 {
Q_DECLARE_PUBLIC(KTagsView)92   Q_DECLARE_PUBLIC(KTagsView)
93 
94 public:
95   explicit KTagsViewPrivate(KTagsView *qq) :
96     q_ptr(qq),
97     ui(new Ui::KTagsView),
98     m_needLoad(true),
99     m_searchWidget(nullptr),
100     m_inSelection(false),
101     m_allowEditing(true),
102     m_tagFilterType(0)
103   {
104   }
105 
~KTagsViewPrivate()106   ~KTagsViewPrivate() override
107   {
108     if (!m_needLoad) {
109       // remember the splitter settings for startup
110       KConfigGroup grp = KSharedConfig::openConfig()->group("Last Use Settings");
111       grp.writeEntry("KTagsViewSplitterSize", ui->m_splitter->saveState());
112       grp.sync();
113     }
114     delete ui;
115   }
116 
init()117   void init()
118   {
119     Q_Q(KTagsView);
120     m_needLoad = false;
121     ui->setupUi(q);
122 
123     // create the searchline widget
124     // and insert it into the existing layout
125     m_searchWidget = new KListWidgetSearchLine(q, ui->m_tagsList);
126     m_searchWidget->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed));
127     ui->m_tagsList->setContextMenuPolicy(Qt::CustomContextMenu);
128     ui->m_listTopHLayout->insertWidget(0, m_searchWidget);
129 
130     //load the filter type
131     ui->m_filterBox->addItem(i18nc("@item Show all tags", "All"));
132     ui->m_filterBox->addItem(i18nc("@item Show only used tags", "Used"));
133     ui->m_filterBox->addItem(i18nc("@item Show only unused tags", "Unused"));
134     ui->m_filterBox->addItem(i18nc("@item Show only opened tags", "Opened"));
135     ui->m_filterBox->addItem(i18nc("@item Show only closed tags", "Closed"));
136     ui->m_filterBox->setSizeAdjustPolicy(QComboBox::AdjustToContents);
137 
138     ui->m_newButton->setIcon(Icons::get(Icon::ListAddTag));
139     ui->m_renameButton->setIcon(Icons::get(Icon::EditRename));
140     ui->m_deleteButton->setIcon(Icons::get(Icon::ListRemoveTag));
141     ui->m_updateButton->setIcon(Icons::get(Icon::DialogOK));
142     ui->m_updateButton->setEnabled(false);
143 
144     ui->m_register->setupRegister(MyMoneyAccount(),
145                                   QList<eWidgets::eTransaction::Column> { eWidgets::eTransaction::Column::Date,
146                                                                           eWidgets::eTransaction::Column::Account,
147                                                                           eWidgets::eTransaction::Column::Detail,
148                                                                           eWidgets::eTransaction::Column::ReconcileFlag,
149                                                                           eWidgets::eTransaction::Column::Payment,
150                                                                           eWidgets::eTransaction::Column::Deposit
151                                   });
152     ui->m_register->setSelectionMode(QTableWidget::SingleSelection);
153     ui->m_register->setDetailsColumnType(eWidgets::eRegister::DetailColumn::AccountFirst);
154     ui->m_balanceLabel->hide();
155 
156     q->connect(ui->m_tagsList, &QListWidget::currentItemChanged, q, static_cast<void (KTagsView::*)(QListWidgetItem *, QListWidgetItem *)>(&KTagsView::slotSelectTag));
157     q->connect(ui->m_tagsList, &QListWidget::itemSelectionChanged, q, static_cast<void (KTagsView::*)()>(&KTagsView::slotSelectTag));
158     q->connect(ui->m_tagsList, &QListWidget::itemDoubleClicked, q, &KTagsView::slotStartRename);
159     q->connect(ui->m_tagsList, &QListWidget::itemChanged, q, &KTagsView::slotRenameSingleTag);
160     q->connect(ui->m_tagsList, &QWidget::customContextMenuRequested, q, &KTagsView::slotShowTagsMenu);
161 
162     q->connect(ui->m_newButton,    &QAbstractButton::clicked, q, &KTagsView::slotNewTag);
163     q->connect(ui->m_renameButton, &QAbstractButton::clicked, q, &KTagsView::slotRenameTag);
164     q->connect(ui->m_deleteButton, &QAbstractButton::clicked, q, &KTagsView::slotDeleteTag);
165 
166     q->connect(ui->m_colorbutton, &KColorButton::changed,   q, &KTagsView::slotTagDataChanged);
167     q->connect(ui->m_closed,      &QCheckBox::stateChanged, q, &KTagsView::slotTagDataChanged);
168     q->connect(ui->m_notes,       &QTextEdit::textChanged,  q, &KTagsView::slotTagDataChanged);
169 
170     q->connect(ui->m_updateButton, &QAbstractButton::clicked, q, &KTagsView::slotUpdateTag);
171     q->connect(ui->m_helpButton, &QAbstractButton::clicked,   q, &KTagsView::slotHelp);
172 
173     q->connect(ui->m_register, &KMyMoneyRegister::Register::editTransaction, q, &KTagsView::slotSelectTransaction);
174 
175     q->connect(MyMoneyFile::instance(), &MyMoneyFile::dataChanged, q, &KTagsView::refresh);
176 
177     q->connect(ui->m_filterBox, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), q, &KTagsView::slotChangeFilter);
178 
179     // use the size settings of the last run (if any)
180     auto grp = KSharedConfig::openConfig()->group("Last Use Settings");
181     ui->m_splitter->restoreState(grp.readEntry("KTagsViewSplitterSize", QByteArray()));
182     ui->m_splitter->setChildrenCollapsible(false);
183 
184     // At start we haven't any tag selected
185     ui->m_tabWidget->setEnabled(false); // disable tab widget
186     ui->m_deleteButton->setEnabled(false); // disable delete and rename button
187     ui->m_renameButton->setEnabled(false);
188     m_tag = MyMoneyTag(); // make sure we don't access an undefined tag
189     q->clearItemData();
190   }
191 
192   /**
193     * Check if a list contains a tag with a given id
194     *
195     * @param list const reference to value list
196     * @param id const reference to id
197     *
198     * @retval true object has been found
199     * @retval false object is not in list
200     */
tagInList(const QList<MyMoneyTag> & list,const QString & id)201   bool tagInList(const QList<MyMoneyTag>& list, const QString& id) const
202   {
203     bool rc = false;
204     QList<MyMoneyTag>::const_iterator it_p = list.begin();
205     while (it_p != list.end()) {
206       if ((*it_p).id() == id) {
207         rc = true;
208         break;
209       }
210       ++it_p;
211     }
212     return rc;
213   }
214 
215   KTagsView       *q_ptr;
216   Ui::KTagsView   *ui;
217 
218   MyMoneyTag   m_tag;
219   QString      m_newName;
220 
221   /**
222       * This member holds a list of all transactions
223       */
224   QList<QPair<MyMoneyTransaction, MyMoneySplit> > m_transactionList;
225 
226   /**
227       * This member holds the load state of page
228       */
229   bool m_needLoad;
230 
231   /**
232       * Search widget for the list
233       */
234   KListWidgetSearchLine*  m_searchWidget;
235 
236   /**
237      * Semaphore to suppress loading during selection
238      */
239   bool m_inSelection;
240 
241   /**
242      * This signals whether a tag can be edited
243      **/
244   bool m_allowEditing;
245 
246   /**
247       * This holds the filter type
248       */
249   int m_tagFilterType;
250 
251   QList<MyMoneyTag> m_selectedTags;
252 };
253 
254 
255 #endif
256