1 /*
2 * Copyright 2006-2018 Thomas Baumgart <tbaumgart@kde.org>
3 * Copyright 2017-2018 Ł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 #include "stdtransaction.h"
20 #include "stdtransaction_p.h"
21
22 // ----------------------------------------------------------------------------
23 // QT Includes
24
25 #include <QString>
26 #include <QPainter>
27 #include <QWidget>
28 #include <QList>
29 #include <QBoxLayout>
30 #include <QPushButton>
31
32 // ----------------------------------------------------------------------------
33 // KDE Includes
34
35 #include <KLocalizedString>
36
37 // ----------------------------------------------------------------------------
38 // Project Includes
39
40 #include "kmymoneypayeecombo.h"
41 #include "kmymoneycombo.h"
42 #include "kmymoneytagcombo.h"
43 #include "tabbar.h"
44 #include "ktagcontainer.h"
45 #include "mymoneytransaction.h"
46 #include "mymoneysplit.h"
47 #include "mymoneyexception.h"
48 #include "mymoneyfile.h"
49 #include "register.h"
50 #include "transactionform.h"
51 #include "kmymoneylineedit.h"
52 #include "kmymoneyutils.h"
53 #ifndef KMM_DESIGNER
54 #include "stdtransactioneditor.h"
55 #endif
56
57 #include "kmymoneysettings.h"
58 #include "widgetenums.h"
59 #include "mymoneyenums.h"
60
61 using namespace eWidgets;
62 using namespace KMyMoneyRegister;
63 using namespace KMyMoneyTransactionForm;
64
StdTransaction(Register * parent,const MyMoneyTransaction & transaction,const MyMoneySplit & split,int uniqueId)65 StdTransaction::StdTransaction(Register *parent, const MyMoneyTransaction& transaction, const MyMoneySplit& split, int uniqueId) :
66 Transaction(*new StdTransactionPrivate, parent, transaction, split, uniqueId)
67 {
68 Q_D(StdTransaction);
69 d->m_showAccountRow = false;
70 try {
71 d->m_categoryHeader = i18n("Category");
72 switch (transaction.splitCount()) {
73 default:
74 d->m_category = i18nc("Split transaction (category replacement)", "Split transaction");
75 break;
76
77 case 0: // the empty transaction
78 case 1:
79 break;
80
81 case 2:
82 setupFormHeader(d->m_transaction.splitByAccount(d->m_split.accountId(), false).accountId());
83 break;
84 }
85 } catch (const MyMoneyException &e) {
86 qDebug() << "Problem determining the category for transaction '" << d->m_transaction.id() << "'. Reason: " << e.what() << "\n";
87 }
88 d->m_rowsForm = 6;
89
90 if (KMyMoneyUtils::transactionType(d->m_transaction) == KMyMoneyUtils::InvestmentTransaction) {
91 MyMoneySplit stockSplit = KMyMoneyUtils::stockSplit(d->m_transaction);
92 d->m_payee = MyMoneyFile::instance()->account(stockSplit.accountId()).name();
93 QString addon;
94 if (stockSplit.action() == MyMoneySplit::actionName(eMyMoney::Split::Action::BuyShares)) {
95 if (stockSplit.value().isNegative()) {
96 addon = i18n("Sell");
97 } else {
98 addon = i18n("Buy");
99 }
100 } else if (stockSplit.action() == MyMoneySplit::actionName(eMyMoney::Split::Action::Dividend)) {
101 addon = i18n("Dividend");
102 } else if (stockSplit.action() == MyMoneySplit::actionName(eMyMoney::Split::Action::Yield)) {
103 addon = i18n("Yield");
104 } else if (stockSplit.action() == MyMoneySplit::actionName(eMyMoney::Split::Action::InterestIncome)) {
105 addon = i18n("Interest Income");
106 }
107 if (!addon.isEmpty()) {
108 d->m_payee += QString(" (%1)").arg(addon);
109 }
110 d->m_payeeHeader = i18n("Activity");
111 d->m_category = i18n("Investment transaction");
112 }
113
114 // setup initial size
115 setNumRowsRegister(numRowsRegister(KMyMoneySettings::showRegisterDetailed()));
116
117 emit parent->itemAdded(this);
118 }
119
~StdTransaction()120 StdTransaction::~StdTransaction()
121 {
122 }
123
className()124 const char* StdTransaction::className()
125 {
126 return "StdTransaction";
127 }
128
setupFormHeader(const QString & id)129 void StdTransaction::setupFormHeader(const QString& id)
130 {
131 Q_D(StdTransaction);
132 d->m_category = MyMoneyFile::instance()->accountToCategory(id);
133 switch (MyMoneyFile::instance()->account(id).accountGroup()) {
134 case eMyMoney::Account::Type::Asset:
135 case eMyMoney::Account::Type::Liability:
136 d->m_categoryHeader = d->m_split.shares().isNegative() ? i18n("Transfer to") : i18n("Transfer from");
137 break;
138
139 default:
140 d->m_categoryHeader = i18n("Category");
141 break;
142 }
143 }
144
actionType() const145 eRegister::Action StdTransaction::actionType() const
146 {
147 Q_D(const StdTransaction);
148 eRegister::Action action = eRegister::Action::None;
149
150 // if at least one split is referencing an income or
151 // expense account, we will not call it a transfer
152
153 auto found = false;
154 foreach (const auto split, d->m_transaction.splits()) {
155 if (split.accountId() == d->m_split.accountId())
156 continue;
157 auto acc = MyMoneyFile::instance()->account(split.accountId());
158 if (acc.accountGroup() == eMyMoney::Account::Type::Income
159 || acc.accountGroup() == eMyMoney::Account::Type::Expense) {
160 // otherwise, we have to determine between deposit and withdrawal
161 action = d->m_split.shares().isNegative() ? eRegister::Action::Withdrawal : eRegister::Action::Deposit;
162 found = true;
163 break;
164 }
165 }
166 // otherwise, it's a transfer
167 if (!found)
168 action = eRegister::Action::Transfer;
169
170 return action;
171 }
172
loadTab(TransactionForm * form)173 void StdTransaction::loadTab(TransactionForm* form)
174 {
175 Q_D(StdTransaction);
176 KMyMoneyTransactionForm::TabBar* bar = form->getTabBar();
177 bar->setSignalEmission(eTabBar::SignalEmission::Never);
178 for (auto i = 0; i < bar->count(); ++i) {
179 bar->setTabEnabled(i, true);
180 }
181
182 if (d->m_transaction.splitCount() > 0) {
183 bar->setCurrentIndex((int)actionType());
184 }
185 bar->setSignalEmission(eTabBar::SignalEmission::Always);
186 }
187
numColsForm() const188 int StdTransaction::numColsForm() const
189 {
190 return 4;
191 }
192
setupForm(TransactionForm * form)193 void StdTransaction::setupForm(TransactionForm* form)
194 {
195 Transaction::setupForm(form);
196 form->setSpan(4, (int)eTransactionForm::Column::Value1, 3, 1);
197 }
198
showRowInForm(int row) const199 bool StdTransaction::showRowInForm(int row) const
200 {
201 Q_D(const StdTransaction);
202 return row == 0 ? d->m_showAccountRow : true;
203 }
204
setShowRowInForm(int row,bool show)205 void StdTransaction::setShowRowInForm(int row, bool show)
206 {
207 Q_D(StdTransaction);
208 if (row == 0)
209 d->m_showAccountRow = show;
210 }
211
formCellText(QString & txt,Qt::Alignment & align,int row,int col,QPainter *)212 bool StdTransaction::formCellText(QString& txt, Qt::Alignment& align, int row, int col, QPainter* /* painter */)
213 {
214 Q_D(const StdTransaction);
215 // if(m_transaction != MyMoneyTransaction()) {
216 switch (row) {
217 case 0:
218 switch (col) {
219 case (int)eTransactionForm::Column::Label1:
220 align |= Qt::AlignLeft;
221 txt = i18n("Account");
222 break;
223 }
224 break;
225
226 case 1:
227 switch (col) {
228 case (int)eTransactionForm::Column::Label1:
229 align |= Qt::AlignLeft;
230 txt = d->m_payeeHeader;
231 break;
232
233 case (int)eTransactionForm::Column::Value1:
234 align |= Qt::AlignLeft;
235 txt = d->m_payee;
236 break;
237
238 case (int)eTransactionForm::Column::Label2:
239 align |= Qt::AlignLeft;
240 if (haveNumberField())
241 txt = i18n("Number");
242 break;
243
244 case (int)eTransactionForm::Column::Value2:
245 align |= Qt::AlignRight;
246 if (haveNumberField())
247 txt = d->m_split.number();
248 break;
249 }
250 break;
251
252 case 2:
253 switch (col) {
254 case (int)eTransactionForm::Column::Label1:
255 align |= Qt::AlignLeft;
256 txt = d->m_categoryHeader;
257 break;
258
259 case (int)eTransactionForm::Column::Value1:
260 align |= Qt::AlignLeft;
261 txt = d->m_category;
262 if (!d->m_transaction.id().isEmpty()) {
263 if (txt.isEmpty() && !d->m_split.value().isZero())
264 txt = i18n("*** UNASSIGNED ***");
265 }
266 break;
267
268 case (int)eTransactionForm::Column::Label2:
269 align |= Qt::AlignLeft;
270 txt = i18n("Date");
271 break;
272
273 case (int)eTransactionForm::Column::Value2:
274 align |= Qt::AlignRight;
275 if (!d->m_transaction.id().isEmpty())
276 txt = QLocale().toString(d->m_transaction.postDate(), QLocale::ShortFormat);
277 break;
278 }
279 break;
280
281 case 3:
282 switch (col) {
283 case (int)eTransactionForm::Column::Label1:
284 align |= Qt::AlignLeft;
285 txt = i18n("Tags");
286 break;
287
288 case (int)eTransactionForm::Column::Value1:
289 align |= Qt::AlignLeft;
290 if (!d->m_tagList.isEmpty()) {
291 for (auto i = 0; i < d->m_tagList.size() - 1; ++i)
292 txt += d->m_tagList[i] + ", ";
293 txt += d->m_tagList.last();
294 }
295 //if (m_transaction != MyMoneyTransaction())
296 // txt = m_split.tagId();
297 break;
298
299 case (int)eTransactionForm::Column::Label2:
300 align |= Qt::AlignLeft;
301 txt = i18n("Amount");
302 break;
303
304 case (int)eTransactionForm::Column::Value2:
305 align |= Qt::AlignRight;
306 if (!d->m_transaction.id().isEmpty()) {
307 txt = (d->m_split.value(d->m_transaction.commodity(), d->m_splitCurrencyId).abs()).formatMoney(d->m_account.fraction());
308 }
309 break;
310 }
311 break;
312
313 case 4:
314 switch (col) {
315 case (int)eTransactionForm::Column::Label1:
316 align |= Qt::AlignLeft;
317 txt = i18n("Memo");
318 break;
319
320 case (int)eTransactionForm::Column::Value1:
321 align &= ~Qt::AlignVCenter;
322 align |= Qt::AlignTop;
323 align |= Qt::AlignLeft;
324 if (!d->m_transaction.id().isEmpty())
325 txt = d->m_split.memo().section('\n', 0, 2);
326 break;
327 }
328 break;
329
330 case 5:
331 switch (col) {
332 case (int)eTransactionForm::Column::Label2:
333 align |= Qt::AlignLeft;
334 txt = i18n("Status");
335 break;
336
337 case (int)eTransactionForm::Column::Value2:
338 align |= Qt::AlignRight;
339 txt = reconcileState();
340 break;
341 }
342 }
343
344 // }
345 if (col == (int)eTransactionForm::Column::Value2 && row == 1) {
346 return haveNumberField();
347 }
348 return (col == (int)eTransactionForm::Column::Value1 && row < 5) || (col == (int)eTransactionForm::Column::Value2 && row > 0 && row != 4);
349 }
350
registerCellText(QString & txt,Qt::Alignment & align,int row,int col,QPainter * painter)351 void StdTransaction::registerCellText(QString& txt, Qt::Alignment& align, int row, int col, QPainter* painter)
352 {
353 Q_D(const StdTransaction);
354 switch (row) {
355 case 0:
356 switch (col) {
357 case (int)eTransaction::Column::Number:
358 align |= Qt::AlignLeft;
359 if (haveNumberField())
360 txt = d->m_split.number();
361 break;
362
363 case (int)eTransaction::Column::Date:
364 align |= Qt::AlignLeft;
365 txt = QLocale().toString(d->m_transaction.postDate(), QLocale::ShortFormat);
366 break;
367
368 case (int)eTransaction::Column::Detail:
369 switch (d->m_parent->getDetailsColumnType()) {
370 case eRegister::DetailColumn::PayeeFirst:
371 txt = d->m_payee;
372 break;
373 case eRegister::DetailColumn::AccountFirst:
374 txt = d->m_category;
375 if (!d->m_tagList.isEmpty()) {
376 txt += " ( ";
377 for (auto i = 0; i < d->m_tagList.size() - 1; ++i) {
378 txt += "<span style='color: " + d->m_tagColorList[i].name() + "'>●</span> " + d->m_tagList[i] + ", ";
379 }
380 txt += "<span style='color: " + d->m_tagColorList.last().name() + "'>●</span> " + d->m_tagList.last() + " )";
381 }
382 break;
383 }
384 align |= Qt::AlignLeft;
385 if (txt.isEmpty() && d->m_rowsRegister < 3) {
386 singleLineMemo(txt, d->m_split);
387 }
388 if (txt.isEmpty() && d->m_rowsRegister < 2) {
389 if (d->m_account.accountType() != eMyMoney::Account::Type::Income
390 && d->m_account.accountType() != eMyMoney::Account::Type::Expense) {
391 txt = d->m_category;
392 if (txt.isEmpty() && !d->m_split.value().isZero()) {
393 txt = i18n("*** UNASSIGNED ***");
394 if (painter)
395 painter->setPen(KMyMoneySettings::schemeColor(SchemeColor::TransactionErroneous));
396 }
397
398 if (!d->m_tagList.isEmpty()) {
399 txt += " ( ";
400 for (auto i = 0; i < d->m_tagList.size() - 1; ++i) {
401 txt += "<span style='color: " + d->m_tagColorList[i].name() + "'>●</span> " + d->m_tagList[i] + ", ";
402 }
403 txt += "<span style='color: " + d->m_tagColorList.last().name() + "'>●</span> " + d->m_tagList.last() + " )";
404 }
405 }
406 }
407 break;
408
409 case (int)eTransaction::Column::ReconcileFlag:
410 align |= Qt::AlignHCenter;
411 txt = reconcileState(false);
412 break;
413
414 case (int)eTransaction::Column::Payment:
415 align |= Qt::AlignRight;
416 if (d->m_split.value().isNegative()) {
417 txt = (-d->m_split.value(d->m_transaction.commodity(), d->m_splitCurrencyId)).formatMoney(d->m_account.fraction());
418 }
419 break;
420
421 case (int)eTransaction::Column::Deposit:
422 align |= Qt::AlignRight;
423 if (!d->m_split.value().isNegative()) {
424 txt = d->m_split.value(d->m_transaction.commodity(), d->m_splitCurrencyId).formatMoney(d->m_account.fraction());
425 }
426 break;
427
428 case (int)eTransaction::Column::Balance:
429 align |= Qt::AlignRight;
430 if (d->m_showBalance)
431 txt = d->m_balance.formatMoney(d->m_account.fraction());
432 else
433 txt = "----";
434 break;
435
436 case (int)eTransaction::Column::Account:
437 // txt = m_objects->account(m_transaction.splits()[0].accountId()).name();
438 txt = MyMoneyFile::instance()->account(d->m_split.accountId()).name();
439 break;
440
441 default:
442 break;
443 }
444 break;
445
446 case 1:
447 switch (col) {
448 case (int)eTransaction::Column::Detail:
449 switch (d->m_parent->getDetailsColumnType()) {
450 case eRegister::DetailColumn::PayeeFirst:
451 txt = d->m_category;
452 if (txt.isEmpty() && !d->m_split.value().isZero()) {
453 txt = i18n("*** UNASSIGNED ***");
454 if (painter)
455 painter->setPen(KMyMoneySettings::schemeColor(SchemeColor::TransactionErroneous));
456 }
457 if (!d->m_tagList.isEmpty()) {
458 txt += " ( ";
459 for (auto i = 0; i < d->m_tagList.size() - 1; ++i) {
460 txt += "<span style='color: " + d->m_tagColorList[i].name() + "'>●</span> " + d->m_tagList[i] + ", ";
461 }
462 txt += "<span style='color: " + d->m_tagColorList.last().name() + "'>●</span> " + d->m_tagList.last() + " )";
463 }
464 break;
465 case eRegister::DetailColumn::AccountFirst:
466 txt = d->m_payee;
467 if (txt.isEmpty()) {
468 singleLineMemo(txt, d->m_split);
469 }
470 break;
471 }
472 align |= Qt::AlignLeft;
473 break;
474
475 default:
476 break;
477 }
478 break;
479
480 case 2:
481 switch (col) {
482 case (int)eTransaction::Column::Detail:
483 align |= Qt::AlignLeft;
484 singleLineMemo(txt, d->m_split);
485 break;
486
487 default:
488 break;
489 }
490 break;
491 }
492 }
493
registerColWidth(int col,const QFontMetrics & cellFontMetrics)494 int StdTransaction::registerColWidth(int col, const QFontMetrics& cellFontMetrics)
495 {
496 QString txt;
497 int firstRow = 0, lastRow = numRowsRegister();
498
499 int nw = 0;
500 for (int i = firstRow; i <= lastRow; ++i) {
501 Qt::Alignment align;
502 registerCellText(txt, align, i, col, 0);
503 int w = cellFontMetrics.width(txt + " ");
504 if (w > nw)
505 nw = w;
506 }
507 return nw;
508 }
509
arrangeWidgetsInForm(QMap<QString,QWidget * > & editWidgets)510 void StdTransaction::arrangeWidgetsInForm(QMap<QString, QWidget*>& editWidgets)
511 {
512 Q_D(StdTransaction);
513 if (!d->m_form || !d->m_parent)
514 return;
515
516 setupFormPalette(editWidgets);
517
518 arrangeWidget(d->m_form, 0, (int)eTransactionForm::Column::Label1, editWidgets["account-label"]);
519 arrangeWidget(d->m_form, 0, (int)eTransactionForm::Column::Value1, editWidgets["account"]);
520 arrangeWidget(d->m_form, 1, (int)eTransactionForm::Column::Label1, editWidgets["cashflow"]);
521 arrangeWidget(d->m_form, 1, (int)eTransactionForm::Column::Value1, editWidgets["payee"]);
522 arrangeWidget(d->m_form, 2, (int)eTransactionForm::Column::Label1, editWidgets["category-label"]);
523 arrangeWidget(d->m_form, 2, (int)eTransactionForm::Column::Value1, editWidgets["category"]->parentWidget());
524 arrangeWidget(d->m_form, 3, (int)eTransactionForm::Column::Label1, editWidgets["tag-label"]);
525 arrangeWidget(d->m_form, 3, (int)eTransactionForm::Column::Value1, editWidgets["tag"]);
526 arrangeWidget(d->m_form, 4, (int)eTransactionForm::Column::Label1, editWidgets["memo-label"]);
527 arrangeWidget(d->m_form, 4, (int)eTransactionForm::Column::Value1, editWidgets["memo"]);
528 if (haveNumberField()) {
529 arrangeWidget(d->m_form, 1, (int)eTransactionForm::Column::Label2, editWidgets["number-label"]);
530 arrangeWidget(d->m_form, 1, (int)eTransactionForm::Column::Value2, editWidgets["number"]);
531 }
532 arrangeWidget(d->m_form, 2, (int)eTransactionForm::Column::Label2, editWidgets["date-label"]);
533 arrangeWidget(d->m_form, 2, (int)eTransactionForm::Column::Value2, editWidgets["postdate"]);
534 arrangeWidget(d->m_form, 3, (int)eTransactionForm::Column::Label2, editWidgets["amount-label"]);
535 arrangeWidget(d->m_form, 3, (int)eTransactionForm::Column::Value2, editWidgets["amount"]);
536 arrangeWidget(d->m_form, 5, (int)eTransactionForm::Column::Label2, editWidgets["status-label"]);
537 arrangeWidget(d->m_form, 5, (int)eTransactionForm::Column::Value2, editWidgets["status"]);
538
539 // get rid of the hints. we don't need them for the form
540 QMap<QString, QWidget*>::iterator it;
541 for (it = editWidgets.begin(); it != editWidgets.end(); ++it) {
542 KMyMoneyCombo* combo = dynamic_cast<KMyMoneyCombo*>(*it);
543 KMyMoneyLineEdit* edit = dynamic_cast<KMyMoneyLineEdit*>(*it);
544 KMyMoneyPayeeCombo* payee = dynamic_cast<KMyMoneyPayeeCombo*>(*it);
545 KTagContainer* tag = dynamic_cast<KTagContainer*>(*it);
546 if (combo)
547 combo->setPlaceholderText(QString());
548 if (edit)
549 edit->setPlaceholderText(QString());
550 if (payee)
551 payee->setPlaceholderText(QString());
552 if (tag)
553 tag->tagCombo()->setPlaceholderText(QString());
554 }
555
556 auto form = dynamic_cast<KMyMoneyTransactionForm::TransactionForm*>(d->m_form);
557 auto w = dynamic_cast<KMyMoneyTransactionForm::TabBar*>(editWidgets["tabbar"]);
558 if (w && form) {
559 // insert the tabbar in the boxlayout so it will take the place of the original tabbar which was hidden
560 if (auto boxLayout = dynamic_cast<QBoxLayout*>(form->getTabBar()->parentWidget()->layout()))
561 boxLayout->insertWidget(0, w);
562 }
563 }
564
tabOrderInForm(QWidgetList & tabOrderWidgets) const565 void StdTransaction::tabOrderInForm(QWidgetList& tabOrderWidgets) const
566 {
567 Q_D(const StdTransaction);
568 QStringList taborder = KMyMoneySettings::stdTransactionFormTabOrder().split(',', QString::SkipEmptyParts);
569 QStringList::const_iterator it_s = taborder.constBegin();
570 QWidget* w;
571 while (it_s != taborder.constEnd()) {
572 if (*it_s == "account") {
573 tabOrderWidgets.append(focusWidget(d->m_form->cellWidget(0, (int)eTransactionForm::Column::Value1)));
574 } else if (*it_s == "cashflow") {
575 tabOrderWidgets.append(focusWidget(d->m_form->cellWidget(1, (int)eTransactionForm::Column::Label1)));
576 } else if (*it_s == "payee") {
577 tabOrderWidgets.append(focusWidget(d->m_form->cellWidget(1, (int)eTransactionForm::Column::Value1)));
578 } else if (*it_s == "category") {
579 // make sure to have the category field and the split button as separate tab order widgets
580 // ok, we have to have some internal knowledge about the KMyMoneyCategory object, but
581 // it's one of our own widgets, so we actually don't care. Just make sure, that we don't
582 // go haywire when someone changes the KMyMoneyCategory object ...
583 w = d->m_form->cellWidget(2, (int)eTransactionForm::Column::Value1);
584 tabOrderWidgets.append(focusWidget(w));
585 w = w->findChild<QPushButton*>("splitButton");
586 if (w)
587 tabOrderWidgets.append(w);
588 } else if (*it_s == "tag") {
589 tabOrderWidgets.append(focusWidget(d->m_form->cellWidget(3, (int)eTransactionForm::Column::Value1)));
590 } else if (*it_s == "memo") {
591 tabOrderWidgets.append(focusWidget(d->m_form->cellWidget(4, (int)eTransactionForm::Column::Value1)));
592 } else if (*it_s == "number") {
593 if (haveNumberField()) {
594 if ((w = focusWidget(d->m_form->cellWidget(1, (int)eTransactionForm::Column::Value2))))
595 tabOrderWidgets.append(w);
596 }
597 } else if (*it_s == "date") {
598 tabOrderWidgets.append(focusWidget(d->m_form->cellWidget(2, (int)eTransactionForm::Column::Value2)));
599 } else if (*it_s == "amount") {
600 tabOrderWidgets.append(focusWidget(d->m_form->cellWidget(3, (int)eTransactionForm::Column::Value2)));
601 } else if (*it_s == "state") {
602 tabOrderWidgets.append(focusWidget(d->m_form->cellWidget(5, (int)eTransactionForm::Column::Value2)));
603 }
604 ++it_s;
605 }
606 }
607
arrangeWidgetsInRegister(QMap<QString,QWidget * > & editWidgets)608 void StdTransaction::arrangeWidgetsInRegister(QMap<QString, QWidget*>& editWidgets)
609 {
610 Q_D(StdTransaction);
611 if (!d->m_parent)
612 return;
613
614 setupRegisterPalette(editWidgets);
615
616 if (haveNumberField())
617 arrangeWidget(d->m_parent, d->m_startRow + 0, (int)eTransaction::Column::Number, editWidgets["number"]);
618 arrangeWidget(d->m_parent, d->m_startRow + 0, (int)eTransaction::Column::Date, editWidgets["postdate"]);
619 arrangeWidget(d->m_parent, d->m_startRow + 1, (int)eTransaction::Column::Date, editWidgets["status"]);
620 arrangeWidget(d->m_parent, d->m_startRow + 0, (int)eTransaction::Column::Detail, editWidgets["payee"]);
621 arrangeWidget(d->m_parent, d->m_startRow + 1, (int)eTransaction::Column::Detail, editWidgets["category"]->parentWidget());
622 arrangeWidget(d->m_parent, d->m_startRow + 2, (int)eTransaction::Column::Detail, editWidgets["tag"]);
623 arrangeWidget(d->m_parent, d->m_startRow + 3, (int)eTransaction::Column::Detail, editWidgets["memo"]);
624 arrangeWidget(d->m_parent, d->m_startRow + 0, (int)eTransaction::Column::Payment, editWidgets["payment"]);
625 arrangeWidget(d->m_parent, d->m_startRow + 0, (int)eTransaction::Column::Deposit, editWidgets["deposit"]);
626
627 // increase the height of the row containing the memo widget
628 d->m_parent->setRowHeight(d->m_startRow + 3, d->m_parent->rowHeightHint() * 3);
629 }
630
tabOrderInRegister(QWidgetList & tabOrderWidgets) const631 void StdTransaction::tabOrderInRegister(QWidgetList& tabOrderWidgets) const
632 {
633 Q_D(const StdTransaction);
634 QStringList taborder = KMyMoneySettings::stdTransactionRegisterTabOrder().split(',', QString::SkipEmptyParts);
635 QStringList::const_iterator it_s = taborder.constBegin();
636 QWidget* w;
637 while (it_s != taborder.constEnd()) {
638 if (*it_s == "number") {
639 if (haveNumberField()) {
640 if ((w = focusWidget(d->m_parent->cellWidget(d->m_startRow + 0, (int)eTransaction::Column::Number))))
641 tabOrderWidgets.append(w);
642 }
643 } else if (*it_s == "date") {
644 tabOrderWidgets.append(focusWidget(d->m_parent->cellWidget(d->m_startRow + 0, (int)eTransaction::Column::Date)));
645 } else if (*it_s == "payee") {
646 tabOrderWidgets.append(focusWidget(d->m_parent->cellWidget(d->m_startRow + 0, (int)eTransaction::Column::Detail)));
647 } else if (*it_s == "category") {
648 // make sure to have the category field and the split button as separate tab order widgets
649 // ok, we have to have some internal knowledge about the KMyMoneyCategory object, but
650 // it's one of our own widgets, so we actually don't care. Just make sure, that we don't
651 // go haywire when someone changes the KMyMoneyCategory object ...
652 w = d->m_parent->cellWidget(d->m_startRow + 1, (int)eTransaction::Column::Detail);
653 tabOrderWidgets.append(focusWidget(w));
654 w = w->findChild<QPushButton*>("splitButton");
655 if (w)
656 tabOrderWidgets.append(w);
657 } else if (*it_s == "tag") {
658 tabOrderWidgets.append(focusWidget(d->m_parent->cellWidget(d->m_startRow + 2, (int)eTransaction::Column::Detail)));
659 } else if (*it_s == "memo") {
660 tabOrderWidgets.append(focusWidget(d->m_parent->cellWidget(d->m_startRow + 3, (int)eTransaction::Column::Detail)));
661 } else if (*it_s == "payment") {
662 tabOrderWidgets.append(focusWidget(d->m_parent->cellWidget(d->m_startRow + 0, (int)eTransaction::Column::Payment)));
663 } else if (*it_s == "deposit") {
664 tabOrderWidgets.append(focusWidget(d->m_parent->cellWidget(d->m_startRow + 0, (int)eTransaction::Column::Deposit)));
665 } else if (*it_s == "state") {
666 tabOrderWidgets.append(focusWidget(d->m_parent->cellWidget(d->m_startRow + 1, (int)eTransaction::Column::Date)));
667 }
668 ++it_s;
669 }
670 }
671
numRowsRegister(bool expanded) const672 int StdTransaction::numRowsRegister(bool expanded) const
673 {
674 Q_D(const StdTransaction);
675 int numRows = 1;
676 if (expanded) {
677 numRows = 4;
678 if (!d->m_inEdit) {
679 //When not in edit Tags haven't a separate row;
680 numRows--;
681 if (d->m_payee.isEmpty()) {
682 numRows--;
683 }
684 if (d->m_split.memo().isEmpty()) {
685 numRows--;
686 }
687 // For income and expense accounts that only have
688 // two splits we only show one line, because the
689 // account name is already contained in the account column.
690 if (d->m_account.accountType() == eMyMoney::Account::Type::Income
691 || d->m_account.accountType() == eMyMoney::Account::Type::Expense) {
692 if (numRows > 2 && d->m_transaction.splitCount() == 2)
693 numRows = 1;
694 }
695 }
696 }
697 return numRows;
698 }
699
numRowsRegister() const700 int StdTransaction::numRowsRegister() const
701 {
702 return RegisterItem::numRowsRegister();
703 }
704
createEditor(TransactionEditorContainer * regForm,const KMyMoneyRegister::SelectedTransactions & list,const QDate & lastPostDate)705 TransactionEditor* StdTransaction::createEditor(TransactionEditorContainer* regForm, const KMyMoneyRegister::SelectedTransactions& list, const QDate& lastPostDate)
706 {
707 #ifndef KMM_DESIGNER
708 Q_D(StdTransaction);
709 d->m_inRegisterEdit = regForm == d->m_parent;
710 return new StdTransactionEditor(regForm, this, list, lastPostDate);
711 #else
712 return NULL;
713 #endif
714 }
715