Changeset View
Changeset View
Standalone View
Standalone View
kmymoney/dialogs/investtransactioneditor.cpp
Context not available. | |||||
4 | begin : Fri Dec 15 2006 | 4 | begin : Fri Dec 15 2006 | ||
---|---|---|---|---|---|
5 | copyright : (C) 2006 by Thomas Baumgart | 5 | copyright : (C) 2006 by Thomas Baumgart | ||
6 | email : Thomas Baumgart <ipwizard@users.sourceforge.net> | 6 | email : Thomas Baumgart <ipwizard@users.sourceforge.net> | ||
7 | (C) 2017 by Łukasz Wojniłowicz <lukasz.wojnilowicz@gmail.com> | ||||
7 | ***************************************************************************/ | 8 | ***************************************************************************/ | ||
8 | 9 | | |||
9 | /*************************************************************************** | 10 | /*************************************************************************** | ||
Context not available. | |||||
16 | ***************************************************************************/ | 17 | ***************************************************************************/ | ||
17 | 18 | | |||
18 | #include "investtransactioneditor.h" | 19 | #include "investtransactioneditor.h" | ||
20 | #include "transactioneditor_p.h" | ||||
19 | 21 | | |||
20 | #include <typeinfo> | 22 | #include <typeinfo> | ||
21 | 23 | | |||
Context not available. | |||||
46 | #include "kcurrencycalculator.h" | 48 | #include "kcurrencycalculator.h" | ||
47 | #include "kmymoneyglobalsettings.h" | 49 | #include "kmymoneyglobalsettings.h" | ||
48 | #include "investactivities.h" | 50 | #include "investactivities.h" | ||
49 | #include "kmymoneyutils.h" | | |||
50 | #include "kmymoneycompletion.h" | 51 | #include "kmymoneycompletion.h" | ||
52 | #include "dialogenums.h" | ||||
51 | 53 | | |||
54 | using namespace eMyMoney; | ||||
52 | using namespace KMyMoneyRegister; | 55 | using namespace KMyMoneyRegister; | ||
53 | using namespace KMyMoneyTransactionForm; | 56 | using namespace KMyMoneyTransactionForm; | ||
54 | using namespace Invest; | 57 | using namespace Invest; | ||
55 | 58 | | |||
56 | class InvestTransactionEditor::Private | 59 | class InvestTransactionEditorPrivate : public TransactionEditorPrivate | ||
57 | { | 60 | { | ||
61 | Q_DISABLE_COPY(InvestTransactionEditorPrivate) | ||||
62 | Q_DECLARE_PUBLIC(InvestTransactionEditor) | ||||
58 | friend class Invest::Activity; | 63 | friend class Invest::Activity; | ||
59 | 64 | | |||
60 | public: | 65 | public: | ||
61 | Private(InvestTransactionEditor* parent) : | 66 | InvestTransactionEditorPrivate(InvestTransactionEditor* qq) : | ||
62 | m_parent(parent), | 67 | TransactionEditorPrivate(qq), | ||
63 | m_activity(0) { | 68 | m_activity(0) | ||
69 | { | ||||
64 | m_phonyAccount = MyMoneyAccount("Phony-ID", MyMoneyAccount()); | 70 | m_phonyAccount = MyMoneyAccount("Phony-ID", MyMoneyAccount()); | ||
65 | } | 71 | } | ||
66 | 72 | | |||
67 | ~Private() { | 73 | ~InvestTransactionEditorPrivate() | ||
74 | { | ||||
68 | delete m_activity; | 75 | delete m_activity; | ||
69 | } | 76 | } | ||
70 | 77 | | |||
71 | QWidget* haveWidget(const QString& name) { | 78 | QWidget* haveWidget(const QString& name) | ||
72 | return m_parent->haveWidget(name); | 79 | { | ||
80 | Q_Q(InvestTransactionEditor); | ||||
81 | return q->haveWidget(name); | ||||
73 | } | 82 | } | ||
74 | 83 | | |||
75 | void hideCategory(const QString& name) { | 84 | void hideCategory(const QString& name) | ||
85 | { | ||||
76 | if (KMyMoneyCategory* cat = dynamic_cast<KMyMoneyCategory*>(haveWidget(name))) { | 86 | if (KMyMoneyCategory* cat = dynamic_cast<KMyMoneyCategory*>(haveWidget(name))) { | ||
77 | cat->hide(); | 87 | cat->hide(); | ||
78 | cat->splitButton()->hide(); | 88 | cat->splitButton()->hide(); | ||
79 | } | 89 | } | ||
80 | } | 90 | } | ||
81 | 91 | | |||
82 | InvestTransactionEditor* m_parent; | 92 | void activityFactory(eMyMoney::Split::InvestmentTransactionType type) | ||
83 | Activity* m_activity; | 93 | { | ||
84 | MyMoneyAccount m_phonyAccount; | 94 | Q_Q(InvestTransactionEditor); | ||
85 | MyMoneySplit m_phonySplit; | 95 | if (!m_activity || type != m_activity->type()) { | ||
96 | delete m_activity; | ||||
97 | switch (type) { | ||||
98 | default: | ||||
99 | case eMyMoney::Split::InvestmentTransactionType::BuyShares: | ||||
100 | m_activity = new Buy(q); | ||||
101 | break; | ||||
102 | case eMyMoney::Split::InvestmentTransactionType::SellShares: | ||||
103 | m_activity = new Sell(q); | ||||
104 | break; | ||||
105 | case eMyMoney::Split::InvestmentTransactionType::Dividend: | ||||
106 | case eMyMoney::Split::InvestmentTransactionType::Yield: | ||||
107 | m_activity = new Div(q); | ||||
108 | break; | ||||
109 | case eMyMoney::Split::InvestmentTransactionType::ReinvestDividend: | ||||
110 | m_activity = new Reinvest(q); | ||||
111 | break; | ||||
112 | case eMyMoney::Split::InvestmentTransactionType::AddShares: | ||||
113 | m_activity = new Add(q); | ||||
114 | break; | ||||
115 | case eMyMoney::Split::InvestmentTransactionType::RemoveShares: | ||||
116 | m_activity = new Remove(q); | ||||
117 | break; | ||||
118 | case eMyMoney::Split::InvestmentTransactionType::SplitShares: | ||||
119 | m_activity = new Invest::Split(q); | ||||
120 | break; | ||||
121 | case eMyMoney::Split::InvestmentTransactionType::InterestIncome: | ||||
122 | m_activity = new IntInc(q); | ||||
123 | break; | ||||
124 | } | ||||
125 | } | ||||
126 | } | ||||
127 | | ||||
128 | MyMoneyMoney subtotal(const QList<MyMoneySplit>& splits) const | ||||
129 | { | ||||
130 | QList<MyMoneySplit>::const_iterator it_s; | ||||
131 | MyMoneyMoney sum; | ||||
132 | | ||||
133 | for (it_s = splits.begin(); it_s != splits.end(); ++it_s) { | ||||
134 | sum += (*it_s).value(); | ||||
135 | } | ||||
136 | | ||||
137 | return sum; | ||||
138 | } | ||||
139 | | ||||
140 | /** | ||||
141 | * This method creates a transaction to be used for the split fee/interest editor. | ||||
142 | * It has a reference to a phony account and the splits contained in @a splits . | ||||
143 | */ | ||||
144 | bool createPseudoTransaction(MyMoneyTransaction& t, const QList<MyMoneySplit>& splits) | ||||
145 | { | ||||
146 | t.removeSplits(); | ||||
147 | | ||||
148 | MyMoneySplit split; | ||||
149 | split.setAccountId(m_phonyAccount.id()); | ||||
150 | split.setValue(-subtotal(splits)); | ||||
151 | split.setShares(split.value()); | ||||
152 | t.addSplit(split); | ||||
153 | m_phonySplit = split; | ||||
154 | | ||||
155 | QList<MyMoneySplit>::const_iterator it_s; | ||||
156 | for (it_s = splits.begin(); it_s != splits.end(); ++it_s) { | ||||
157 | split = *it_s; | ||||
158 | split.clearId(); | ||||
159 | t.addSplit(split); | ||||
160 | } | ||||
161 | return true; | ||||
162 | } | ||||
163 | | ||||
164 | /** | ||||
165 | * Convenience method used by slotEditInterestSplits() and slotEditFeeSplits(). | ||||
166 | * | ||||
167 | * @param categoryWidgetName name of the category widget | ||||
168 | * @param amountWidgetName name of the amount widget | ||||
169 | * @param splits the splits that make up the transaction to be edited | ||||
170 | * @param isIncome @c false for fees, @c true for interest | ||||
171 | * @param slotEditSplits name of the slot to be connected to the focusIn signal of the | ||||
172 | * category widget named @p categoryWidgetName in case of multiple splits | ||||
173 | * in @p splits . | ||||
174 | */ | ||||
175 | | ||||
176 | int editSplits(const QString& categoryWidgetName, | ||||
177 | const QString& amountWidgetName, | ||||
178 | QList<MyMoneySplit>& splits, | ||||
179 | bool isIncome, | ||||
180 | const char* slotEditSplits) | ||||
181 | { | ||||
182 | Q_Q(InvestTransactionEditor); | ||||
183 | int rc = QDialog::Rejected; | ||||
184 | | ||||
185 | if (!m_openEditSplits) { | ||||
186 | // only get in here in a single instance | ||||
187 | m_openEditSplits = true; | ||||
188 | | ||||
189 | // force focus change to update all data | ||||
190 | KMyMoneyCategory* category = dynamic_cast<KMyMoneyCategory*>(m_editWidgets[categoryWidgetName]); | ||||
191 | QWidget* w = category->splitButton(); | ||||
192 | if (w) | ||||
193 | w->setFocus(); | ||||
194 | | ||||
195 | kMyMoneyEdit* amount = dynamic_cast<kMyMoneyEdit*>(haveWidget(amountWidgetName)); | ||||
196 | | ||||
197 | MyMoneyTransaction transaction; | ||||
198 | transaction.setCommodity(m_currency.id()); | ||||
199 | if (splits.count() == 0 && !category->selectedItem().isEmpty()) { | ||||
200 | MyMoneySplit s; | ||||
201 | s.setAccountId(category->selectedItem()); | ||||
202 | s.setShares(amount->value()); | ||||
203 | s.setValue(s.shares()); | ||||
204 | splits << s; | ||||
205 | } | ||||
206 | // use the transactions commodity as the currency indicator for the splits | ||||
207 | // this is used to allow some useful setting for the fractions in the amount fields | ||||
208 | try { | ||||
209 | m_phonyAccount.setCurrencyId(m_transaction.commodity()); | ||||
210 | m_phonyAccount.fraction(MyMoneyFile::instance()->security(m_transaction.commodity())); | ||||
211 | } catch (const MyMoneyException &) { | ||||
212 | qDebug("Unable to setup precision"); | ||||
213 | } | ||||
214 | | ||||
215 | if (createPseudoTransaction(transaction, splits)) { | ||||
216 | MyMoneyMoney value; | ||||
217 | | ||||
218 | QPointer<KSplitTransactionDlg> dlg = new KSplitTransactionDlg(transaction, | ||||
219 | m_phonySplit, | ||||
220 | m_phonyAccount, | ||||
221 | false, | ||||
222 | isIncome, | ||||
223 | MyMoneyMoney(), | ||||
224 | m_priceInfo, | ||||
225 | m_regForm); | ||||
226 | // q->connect(dlg, SIGNAL(newCategory(MyMoneyAccount&)), q, SIGNAL(newCategory(MyMoneyAccount&))); | ||||
227 | | ||||
228 | if ((rc = dlg->exec()) == QDialog::Accepted) { | ||||
229 | transaction = dlg->transaction(); | ||||
230 | // collect splits out of the transaction | ||||
231 | splits.clear(); | ||||
232 | QList<MyMoneySplit>::const_iterator it_s; | ||||
233 | MyMoneyMoney fees; | ||||
234 | for (it_s = transaction.splits().constBegin(); it_s != transaction.splits().constEnd(); ++it_s) { | ||||
235 | if ((*it_s).accountId() == m_phonyAccount.id()) | ||||
236 | continue; | ||||
237 | splits << *it_s; | ||||
238 | fees += (*it_s).shares(); | ||||
239 | } | ||||
240 | if (isIncome) | ||||
241 | fees = -fees; | ||||
242 | | ||||
243 | QString categoryId; | ||||
244 | q->setupCategoryWidget(category, splits, categoryId, slotEditSplits); | ||||
245 | amount->setValue(fees); | ||||
246 | q->slotUpdateTotalAmount(); | ||||
247 | } | ||||
248 | | ||||
249 | delete dlg; | ||||
250 | } | ||||
251 | | ||||
252 | // focus jumps into the memo field | ||||
253 | if ((w = haveWidget("memo")) != 0) { | ||||
254 | w->setFocus(); | ||||
255 | } | ||||
256 | | ||||
257 | m_openEditSplits = false; | ||||
258 | } | ||||
259 | return rc; | ||||
260 | } | ||||
261 | | ||||
262 | void updatePriceMode(const MyMoneySplit& split = MyMoneySplit()) | ||||
263 | { | ||||
264 | Q_Q(InvestTransactionEditor); | ||||
265 | auto label = dynamic_cast<QLabel*>(haveWidget("price-label")); | ||||
266 | if (label) { | ||||
267 | auto sharesEdit = dynamic_cast<kMyMoneyEdit*>(haveWidget("shares")); | ||||
268 | auto priceEdit = dynamic_cast<kMyMoneyEdit*>(haveWidget("price")); | ||||
269 | MyMoneyMoney price; | ||||
270 | if (!split.id().isEmpty()) | ||||
271 | price = split.price().reduce(); | ||||
272 | else | ||||
273 | price = priceEdit->value().abs(); | ||||
274 | | ||||
275 | if (q->priceMode() == eDialogs::PriceMode::PricePerTransaction) { | ||||
276 | priceEdit->setPrecision(m_currency.pricePrecision()); | ||||
277 | label->setText(i18n("Transaction amount")); | ||||
278 | if (!sharesEdit->value().isZero()) | ||||
279 | priceEdit->setValue(sharesEdit->value().abs() * price); | ||||
280 | | ||||
281 | } else if (q->priceMode() == eDialogs::PriceMode::PricePerShare) { | ||||
282 | priceEdit->setPrecision(m_security.pricePrecision()); | ||||
283 | label->setText(i18n("Price/Share")); | ||||
284 | priceEdit->setValue(price); | ||||
285 | } else | ||||
286 | priceEdit->setValue(price); | ||||
287 | } | ||||
288 | } | ||||
289 | | ||||
290 | // InvestTransactionEditor* q_ptr; | ||||
291 | Activity* m_activity; | ||||
292 | MyMoneyAccount m_phonyAccount; | ||||
293 | MyMoneySplit m_phonySplit; | ||||
294 | MyMoneySplit m_assetAccountSplit; | ||||
295 | QList<MyMoneySplit> m_interestSplits; | ||||
296 | QList<MyMoneySplit> m_feeSplits; | ||||
297 | MyMoneySecurity m_security; | ||||
298 | MyMoneySecurity m_currency; | ||||
299 | eMyMoney::Split::InvestmentTransactionType m_transactionType; | ||||
86 | }; | 300 | }; | ||
87 | 301 | | |||
88 | 302 | | |||
89 | InvestTransactionEditor::InvestTransactionEditor() : | 303 | InvestTransactionEditor::InvestTransactionEditor() : | ||
90 | m_transactionType(eMyMoney::Split::InvestmentTransactionType::UnknownTransactionType), | 304 | TransactionEditor(*new InvestTransactionEditorPrivate(this)) | ||
91 | d(new Private(this)) | | |||
92 | { | 305 | { | ||
306 | Q_D(InvestTransactionEditor); | ||||
307 | d->m_transactionType = eMyMoney::Split::InvestmentTransactionType::UnknownTransactionType; | ||||
93 | } | 308 | } | ||
94 | 309 | | |||
95 | InvestTransactionEditor::~InvestTransactionEditor() | 310 | InvestTransactionEditor::~InvestTransactionEditor() | ||
96 | { | 311 | { | ||
97 | delete d; | | |||
98 | } | 312 | } | ||
99 | 313 | | |||
100 | InvestTransactionEditor::InvestTransactionEditor(TransactionEditorContainer* regForm, KMyMoneyRegister::InvestTransaction* item, const KMyMoneyRegister::SelectedTransactions& list, const QDate& lastPostDate) : | 314 | InvestTransactionEditor::InvestTransactionEditor(TransactionEditorContainer* regForm, | ||
101 | TransactionEditor(regForm, item, list, lastPostDate), | 315 | KMyMoneyRegister::InvestTransaction* item, | ||
102 | d(new Private(this)) | 316 | const KMyMoneyRegister::SelectedTransactions& list, | ||
317 | const QDate& lastPostDate) : | ||||
318 | TransactionEditor(*new InvestTransactionEditorPrivate(this), | ||||
319 | regForm, | ||||
320 | item, | ||||
321 | list, | ||||
322 | lastPostDate) | ||||
103 | { | 323 | { | ||
324 | Q_D(InvestTransactionEditor); | ||||
104 | // after the gometries of the container are updated hide the widgets which are not needed by the current activity | 325 | // after the gometries of the container are updated hide the widgets which are not needed by the current activity | ||
105 | connect(m_regForm, SIGNAL(geometriesUpdated()), this, SLOT(slotTransactionContainerGeometriesUpdated())); | 326 | connect(d->m_regForm, &TransactionEditorContainer::geometriesUpdated, this, &InvestTransactionEditor::slotTransactionContainerGeometriesUpdated); | ||
106 | 327 | | |||
107 | // dissect the transaction into its type, splits, currency, security etc. | 328 | // dissect the transaction into its type, splits, currency, security etc. | ||
108 | KMyMoneyUtils::dissectTransaction(m_transaction, m_split, | 329 | KMyMoneyUtils::dissectTransaction(d->m_transaction, d->m_split, | ||
109 | m_assetAccountSplit, | 330 | d->m_assetAccountSplit, | ||
110 | m_feeSplits, | 331 | d->m_feeSplits, | ||
111 | m_interestSplits, | 332 | d->m_interestSplits, | ||
112 | m_security, | 333 | d->m_security, | ||
113 | m_currency, | 334 | d->m_currency, | ||
114 | m_transactionType); | 335 | d->m_transactionType); | ||
115 | 336 | | |||
116 | // determine initial activity object | 337 | // determine initial activity object | ||
117 | activityFactory(m_transactionType); | 338 | d->activityFactory(d->m_transactionType); | ||
118 | } | | |||
119 | | ||||
120 | void InvestTransactionEditor::activityFactory(eMyMoney::Split::InvestmentTransactionType type) | | |||
121 | { | | |||
122 | if (!d->m_activity || type != d->m_activity->type()) { | | |||
123 | delete d->m_activity; | | |||
124 | switch (type) { | | |||
125 | default: | | |||
126 | case eMyMoney::Split::InvestmentTransactionType::BuyShares: | | |||
127 | d->m_activity = new Buy(this); | | |||
128 | break; | | |||
129 | case eMyMoney::Split::InvestmentTransactionType::SellShares: | | |||
130 | d->m_activity = new Sell(this); | | |||
131 | break; | | |||
132 | case eMyMoney::Split::InvestmentTransactionType::Dividend: | | |||
133 | case eMyMoney::Split::InvestmentTransactionType::Yield: | | |||
134 | d->m_activity = new Div(this); | | |||
135 | break; | | |||
136 | case eMyMoney::Split::InvestmentTransactionType::ReinvestDividend: | | |||
137 | d->m_activity = new Reinvest(this); | | |||
138 | break; | | |||
139 | case eMyMoney::Split::InvestmentTransactionType::AddShares: | | |||
140 | d->m_activity = new Add(this); | | |||
141 | break; | | |||
142 | case eMyMoney::Split::InvestmentTransactionType::RemoveShares: | | |||
143 | d->m_activity = new Remove(this); | | |||
144 | break; | | |||
145 | case eMyMoney::Split::InvestmentTransactionType::SplitShares: | | |||
146 | d->m_activity = new Split(this); | | |||
147 | break; | | |||
148 | case eMyMoney::Split::InvestmentTransactionType::InterestIncome: | | |||
149 | d->m_activity = new IntInc(this); | | |||
150 | break; | | |||
151 | } | | |||
152 | } | | |||
153 | } | 339 | } | ||
154 | 340 | | |||
155 | void InvestTransactionEditor::createEditWidgets() | 341 | void InvestTransactionEditor::createEditWidgets() | ||
156 | { | 342 | { | ||
157 | KMyMoneyActivityCombo* activity = new KMyMoneyActivityCombo(); | 343 | Q_D(InvestTransactionEditor); | ||
158 | m_editWidgets["activity"] = activity; | 344 | auto activity = new KMyMoneyActivityCombo(); | ||
159 | connect(activity, SIGNAL(activitySelected(eMyMoney::Split::InvestmentTransactionType)), this, SLOT(slotUpdateActivity(eMyMoney::Split::InvestmentTransactionType))); | 345 | d->m_editWidgets["activity"] = activity; | ||
160 | connect(activity, SIGNAL(activitySelected(eMyMoney::Split::InvestmentTransactionType)), this, SLOT(slotUpdateButtonState())); | 346 | connect(activity, &KMyMoneyActivityCombo::activitySelected, this, &InvestTransactionEditor::slotUpdateActivity); | ||
347 | connect(activity, &KMyMoneyActivityCombo::activitySelected, this, &InvestTransactionEditor::slotUpdateButtonState); | ||||
161 | 348 | | |||
162 | m_editWidgets["postdate"] = new kMyMoneyDateInput; | 349 | d->m_editWidgets["postdate"] = new kMyMoneyDateInput; | ||
163 | 350 | | |||
164 | KMyMoneySecurity* security = new KMyMoneySecurity; | 351 | auto security = new KMyMoneySecurity; | ||
165 | security->setPlaceholderText(i18n("Security")); | 352 | security->setPlaceholderText(i18n("Security")); | ||
166 | m_editWidgets["security"] = security; | 353 | d->m_editWidgets["security"] = security; | ||
167 | connect(security, SIGNAL(itemSelected(QString)), this, SLOT(slotUpdateSecurity(QString))); | 354 | connect(security, &KMyMoneyCombo::itemSelected, this, &InvestTransactionEditor::slotUpdateSecurity); | ||
168 | connect(security, SIGNAL(editTextChanged(QString)), this, SLOT(slotUpdateButtonState())); | 355 | connect(security, &QComboBox::editTextChanged, this, &InvestTransactionEditor::slotUpdateButtonState); | ||
169 | connect(security, SIGNAL(createItem(QString,QString&)), this, SLOT(slotCreateSecurity(QString,QString&))); | 356 | connect(security, &KMyMoneyCombo::createItem, this, &InvestTransactionEditor::slotCreateSecurity); | ||
170 | connect(security, SIGNAL(objectCreation(bool)), this, SIGNAL(objectCreation(bool))); | 357 | connect(security, &KMyMoneyCombo::objectCreation, this, &TransactionEditor::objectCreation); | ||
171 | 358 | | |||
172 | KMyMoneyCategory* asset = new KMyMoneyCategory(0, false); | 359 | auto asset = new KMyMoneyCategory(0, false); | ||
173 | asset->setPlaceholderText(i18n("Asset account")); | 360 | asset->setPlaceholderText(i18n("Asset account")); | ||
174 | m_editWidgets["asset-account"] = asset; | 361 | d->m_editWidgets["asset-account"] = asset; | ||
175 | connect(asset, SIGNAL(editTextChanged(QString)), this, SLOT(slotUpdateButtonState())); | 362 | connect(asset, &QComboBox::editTextChanged, this, &InvestTransactionEditor::slotUpdateButtonState); | ||
176 | connect(asset, SIGNAL(objectCreation(bool)), this, SIGNAL(objectCreation(bool))); | 363 | connect(asset, &KMyMoneyCombo::objectCreation, this, &TransactionEditor::objectCreation); | ||
177 | 364 | | |||
178 | KMyMoneyCategory* fees = new KMyMoneyCategory(0, true); | 365 | auto fees = new KMyMoneyCategory(0, true); | ||
179 | fees->setPlaceholderText(i18n("Fees")); | 366 | fees->setPlaceholderText(i18n("Fees")); | ||
180 | m_editWidgets["fee-account"] = fees; | 367 | d->m_editWidgets["fee-account"] = fees; | ||
181 | connect(fees, SIGNAL(itemSelected(QString)), this, SLOT(slotUpdateFeeCategory(QString))); | 368 | connect(fees, &KMyMoneyCombo::itemSelected, this, &InvestTransactionEditor::slotUpdateFeeCategory); | ||
182 | connect(fees, SIGNAL(editTextChanged(QString)), this, SLOT(slotUpdateButtonState())); | 369 | connect(fees, &QComboBox::editTextChanged, this, &InvestTransactionEditor::slotUpdateButtonState); | ||
183 | connect(fees, SIGNAL(editTextChanged(QString)), this, SLOT(slotUpdateFeeVisibility(QString))); | 370 | connect(fees, &QComboBox::editTextChanged, this, &InvestTransactionEditor::slotUpdateFeeVisibility); | ||
184 | connect(fees, SIGNAL(createItem(QString,QString&)), this, SLOT(slotCreateFeeCategory(QString,QString&))); | 371 | connect(fees, &KMyMoneyCombo::createItem, this, &InvestTransactionEditor::slotCreateFeeCategory); | ||
185 | connect(fees, SIGNAL(objectCreation(bool)), this, SIGNAL(objectCreation(bool))); | 372 | connect(fees, &KMyMoneyCombo::objectCreation, this, &TransactionEditor::objectCreation); | ||
186 | connect(fees->splitButton(), SIGNAL(clicked()), this, SLOT(slotEditFeeSplits())); | 373 | connect(fees->splitButton(), &QAbstractButton::clicked, this, &InvestTransactionEditor::slotEditFeeSplits); | ||
187 | 374 | | |||
188 | KMyMoneyCategory* interest = new KMyMoneyCategory(0, true); | 375 | auto interest = new KMyMoneyCategory(0, true); | ||
189 | interest->setPlaceholderText(i18n("Interest")); | 376 | interest->setPlaceholderText(i18n("Interest")); | ||
190 | m_editWidgets["interest-account"] = interest; | 377 | d->m_editWidgets["interest-account"] = interest; | ||
191 | connect(interest, SIGNAL(itemSelected(QString)), this, SLOT(slotUpdateInterestCategory(QString))); | 378 | connect(interest, &KMyMoneyCombo::itemSelected, this, &InvestTransactionEditor::slotUpdateInterestCategory); | ||
192 | connect(interest, SIGNAL(editTextChanged(QString)), this, SLOT(slotUpdateButtonState())); | 379 | connect(interest, &QComboBox::editTextChanged, this, &InvestTransactionEditor::slotUpdateButtonState); | ||
193 | connect(interest, SIGNAL(editTextChanged(QString)), this, SLOT(slotUpdateInterestVisibility(QString))); | 380 | connect(interest, &QComboBox::editTextChanged, this, &InvestTransactionEditor::slotUpdateInterestVisibility); | ||
194 | connect(interest, SIGNAL(createItem(QString,QString&)), this, SLOT(slotCreateInterestCategory(QString,QString&))); | 381 | connect(interest, &KMyMoneyCombo::createItem, this, &InvestTransactionEditor::slotCreateInterestCategory); | ||
195 | connect(interest, SIGNAL(objectCreation(bool)), this, SIGNAL(objectCreation(bool))); | 382 | connect(interest, &KMyMoneyCombo::objectCreation, this, &TransactionEditor::objectCreation); | ||
196 | connect(interest->splitButton(), SIGNAL(clicked()), this, SLOT(slotEditInterestSplits())); | 383 | connect(interest->splitButton(), &QAbstractButton::clicked, this, &InvestTransactionEditor::slotEditInterestSplits); | ||
197 | 384 | | |||
198 | KTagContainer* tag = new KTagContainer; | 385 | auto tag = new KTagContainer; | ||
199 | tag->tagCombo()->setPlaceholderText(i18n("Tag")); | 386 | tag->tagCombo()->setPlaceholderText(i18n("Tag")); | ||
200 | tag->tagCombo()->setObjectName(QLatin1String("Tag")); | 387 | tag->tagCombo()->setObjectName(QLatin1String("Tag")); | ||
201 | m_editWidgets["tag"] = tag; | 388 | d->m_editWidgets["tag"] = tag; | ||
202 | connect(tag->tagCombo(), SIGNAL(editTextChanged(QString)), this, SLOT(slotUpdateButtonState())); | 389 | connect(tag->tagCombo(), &QComboBox::editTextChanged, this, &InvestTransactionEditor::slotUpdateButtonState); | ||
203 | connect(tag->tagCombo(), SIGNAL(createItem(QString,QString&)), this, SIGNAL(createTag(QString,QString&))); | 390 | connect(tag->tagCombo(), &KMyMoneyMVCCombo::createItem, this, &TransactionEditor::createTag); | ||
204 | connect(tag->tagCombo(), SIGNAL(objectCreation(bool)), this, SIGNAL(objectCreation(bool))); | 391 | connect(tag->tagCombo(), &KMyMoneyMVCCombo::objectCreation, this, &TransactionEditor::objectCreation); | ||
205 | 392 | | |||
206 | KTextEdit* memo = new KTextEdit; | 393 | auto memo = new KTextEdit; | ||
207 | memo->setTabChangesFocus(true); | 394 | memo->setTabChangesFocus(true); | ||
208 | m_editWidgets["memo"] = memo; | 395 | d->m_editWidgets["memo"] = memo; | ||
209 | connect(memo, SIGNAL(textChanged()), this, SLOT(slotUpdateInvestMemoState())); | 396 | connect(memo, &QTextEdit::textChanged, this, &InvestTransactionEditor::slotUpdateInvestMemoState); | ||
210 | connect(memo, SIGNAL(textChanged()), this, SLOT(slotUpdateButtonState())); | 397 | connect(memo, &QTextEdit::textChanged, this, &InvestTransactionEditor::slotUpdateButtonState); | ||
211 | 398 | | |||
212 | d->m_activity->m_memoText.clear(); | 399 | d->m_activity->memoText().clear(); | ||
213 | d->m_activity->m_memoChanged = false; | 400 | d->m_activity->memoChanged() = false; | ||
214 | 401 | | |||
215 | kMyMoneyEdit* value = new kMyMoneyEdit; | 402 | kMyMoneyEdit* value = new kMyMoneyEdit; | ||
216 | value->setPlaceholderText(i18n("Shares")); | 403 | value->setPlaceholderText(i18n("Shares")); | ||
217 | value->setResetButtonVisible(false); | 404 | value->setResetButtonVisible(false); | ||
218 | m_editWidgets["shares"] = value; | 405 | d->m_editWidgets["shares"] = value; | ||
219 | connect(value, SIGNAL(textChanged(QString)), this, SLOT(slotUpdateButtonState())); | 406 | connect(value, &kMyMoneyEdit::textChanged, this, &InvestTransactionEditor::slotUpdateButtonState); | ||
220 | connect(value, SIGNAL(valueChanged(QString)), this, SLOT(slotUpdateTotalAmount())); | 407 | connect(value, &kMyMoneyEdit::valueChanged, this, &InvestTransactionEditor::slotUpdateTotalAmount); | ||
221 | 408 | | |||
222 | value = new kMyMoneyEdit; | 409 | value = new kMyMoneyEdit; | ||
223 | value->setPlaceholderText(i18n("Price")); | 410 | value->setPlaceholderText(i18n("Price")); | ||
224 | value->setResetButtonVisible(false); | 411 | value->setResetButtonVisible(false); | ||
225 | m_editWidgets["price"] = value; | 412 | d->m_editWidgets["price"] = value; | ||
226 | connect(value, SIGNAL(textChanged(QString)), this, SLOT(slotUpdateButtonState())); | 413 | connect(value, &kMyMoneyEdit::textChanged, this, &InvestTransactionEditor::slotUpdateButtonState); | ||
227 | connect(value, SIGNAL(valueChanged(QString)), this, SLOT(slotUpdateTotalAmount())); | 414 | connect(value, &kMyMoneyEdit::valueChanged, this, &InvestTransactionEditor::slotUpdateTotalAmount); | ||
228 | 415 | | |||
229 | value = new kMyMoneyEdit; | 416 | value = new kMyMoneyEdit; | ||
230 | // TODO once we have the selected transactions as array of Transaction | 417 | // TODO once we have the selected transactions as array of Transaction | ||
231 | // we can allow multiple splits for fee and interest | 418 | // we can allow multiple splits for fee and interest | ||
232 | value->setResetButtonVisible(false); | 419 | value->setResetButtonVisible(false); | ||
233 | m_editWidgets["fee-amount"] = value; | 420 | d->m_editWidgets["fee-amount"] = value; | ||
234 | connect(value, SIGNAL(textChanged(QString)), this, SLOT(slotUpdateButtonState())); | 421 | connect(value, &kMyMoneyEdit::textChanged, this, &InvestTransactionEditor::slotUpdateButtonState); | ||
235 | connect(value, SIGNAL(valueChanged(QString)), this, SLOT(slotUpdateTotalAmount())); | 422 | connect(value, &kMyMoneyEdit::valueChanged, this, &InvestTransactionEditor::slotUpdateTotalAmount); | ||
236 | 423 | | |||
237 | value = new kMyMoneyEdit; | 424 | value = new kMyMoneyEdit; | ||
238 | // TODO once we have the selected transactions as array of Transaction | 425 | // TODO once we have the selected transactions as array of Transaction | ||
239 | // we can allow multiple splits for fee and interest | 426 | // we can allow multiple splits for fee and interest | ||
240 | value->setResetButtonVisible(false); | 427 | value->setResetButtonVisible(false); | ||
241 | m_editWidgets["interest-amount"] = value; | 428 | d->m_editWidgets["interest-amount"] = value; | ||
242 | connect(value, SIGNAL(textChanged(QString)), this, SLOT(slotUpdateButtonState())); | 429 | connect(value, &kMyMoneyEdit::textChanged, this, &InvestTransactionEditor::slotUpdateButtonState); | ||
243 | connect(value, SIGNAL(valueChanged(QString)), this, SLOT(slotUpdateTotalAmount())); | 430 | connect(value, &kMyMoneyEdit::valueChanged, this, &InvestTransactionEditor::slotUpdateTotalAmount); | ||
244 | 431 | | |||
245 | KMyMoneyReconcileCombo* reconcile = new KMyMoneyReconcileCombo; | 432 | auto reconcile = new KMyMoneyReconcileCombo; | ||
246 | m_editWidgets["status"] = reconcile; | 433 | d->m_editWidgets["status"] = reconcile; | ||
247 | connect(reconcile, SIGNAL(itemSelected(QString)), this, SLOT(slotUpdateButtonState())); | 434 | connect(reconcile, &KMyMoneyMVCCombo::itemSelected, this, &InvestTransactionEditor::slotUpdateButtonState); | ||
248 | 435 | | |||
249 | KMyMoneyRegister::QWidgetContainer::iterator it_w; | 436 | KMyMoneyRegister::QWidgetContainer::iterator it_w; | ||
250 | for (it_w = m_editWidgets.begin(); it_w != m_editWidgets.end(); ++it_w) { | 437 | for (it_w = d->m_editWidgets.begin(); it_w != d->m_editWidgets.end(); ++it_w) { | ||
251 | (*it_w)->installEventFilter(this); | 438 | (*it_w)->installEventFilter(this); | ||
252 | } | 439 | } | ||
253 | 440 | | |||
254 | QLabel* label; | 441 | QLabel* label; | ||
255 | 442 | | |||
256 | m_editWidgets["activity-label"] = label = new QLabel(i18n("Activity")); | 443 | d->m_editWidgets["activity-label"] = label = new QLabel(i18n("Activity")); | ||
257 | label->setAlignment(Qt::AlignVCenter); | 444 | label->setAlignment(Qt::AlignVCenter); | ||
258 | 445 | | |||
259 | m_editWidgets["postdate-label"] = label = new QLabel(i18n("Date")); | 446 | d->m_editWidgets["postdate-label"] = label = new QLabel(i18n("Date")); | ||
260 | label->setAlignment(Qt::AlignVCenter); | 447 | label->setAlignment(Qt::AlignVCenter); | ||
261 | 448 | | |||
262 | m_editWidgets["security-label"] = label = new QLabel(i18n("Security")); | 449 | d->m_editWidgets["security-label"] = label = new QLabel(i18n("Security")); | ||
263 | label->setAlignment(Qt::AlignVCenter); | 450 | label->setAlignment(Qt::AlignVCenter); | ||
264 | 451 | | |||
265 | m_editWidgets["shares-label"] = label = new QLabel(i18n("Shares")); | 452 | d->m_editWidgets["shares-label"] = label = new QLabel(i18n("Shares")); | ||
266 | label->setAlignment(Qt::AlignVCenter); | 453 | label->setAlignment(Qt::AlignVCenter); | ||
267 | 454 | | |||
268 | m_editWidgets["asset-label"] = label = new QLabel(i18n("Account")); | 455 | d->m_editWidgets["asset-label"] = label = new QLabel(i18n("Account")); | ||
269 | label->setAlignment(Qt::AlignVCenter); | 456 | label->setAlignment(Qt::AlignVCenter); | ||
270 | 457 | | |||
271 | m_editWidgets["price-label"] = label = new QLabel(i18n("Price/share")); | 458 | d->m_editWidgets["price-label"] = label = new QLabel(i18n("Price/share")); | ||
272 | label->setAlignment(Qt::AlignVCenter); | 459 | label->setAlignment(Qt::AlignVCenter); | ||
273 | 460 | | |||
274 | m_editWidgets["fee-label"] = label = new QLabel(i18n("Fees")); | 461 | d->m_editWidgets["fee-label"] = label = new QLabel(i18n("Fees")); | ||
275 | label->setAlignment(Qt::AlignVCenter); | 462 | label->setAlignment(Qt::AlignVCenter); | ||
276 | 463 | | |||
277 | m_editWidgets["fee-amount-label"] = label = new QLabel(""); | 464 | d->m_editWidgets["fee-amount-label"] = label = new QLabel(""); | ||
278 | label->setAlignment(Qt::AlignVCenter); | 465 | label->setAlignment(Qt::AlignVCenter); | ||
279 | 466 | | |||
280 | m_editWidgets["interest-label"] = label = new QLabel(i18n("Interest")); | 467 | d->m_editWidgets["interest-label"] = label = new QLabel(i18n("Interest")); | ||
281 | label->setAlignment(Qt::AlignVCenter); | 468 | label->setAlignment(Qt::AlignVCenter); | ||
282 | 469 | | |||
283 | m_editWidgets["interest-amount-label"] = label = new QLabel(i18n("Interest")); | 470 | d->m_editWidgets["interest-amount-label"] = label = new QLabel(i18n("Interest")); | ||
284 | label->setAlignment(Qt::AlignVCenter); | 471 | label->setAlignment(Qt::AlignVCenter); | ||
285 | 472 | | |||
286 | m_editWidgets["memo-label"] = label = new QLabel(i18n("Memo")); | 473 | d->m_editWidgets["memo-label"] = label = new QLabel(i18n("Memo")); | ||
287 | label->setAlignment(Qt::AlignVCenter); | 474 | label->setAlignment(Qt::AlignVCenter); | ||
288 | 475 | | |||
289 | m_editWidgets["total"] = label = new QLabel(""); | 476 | d->m_editWidgets["total"] = label = new QLabel(""); | ||
290 | label->setAlignment(Qt::AlignVCenter | Qt::AlignRight); | 477 | label->setAlignment(Qt::AlignVCenter | Qt::AlignRight); | ||
291 | 478 | | |||
292 | m_editWidgets["total-label"] = label = new QLabel(i18nc("Total value", "Total")); | 479 | d->m_editWidgets["total-label"] = label = new QLabel(i18nc("Total value", "Total")); | ||
293 | label->setAlignment(Qt::AlignVCenter); | 480 | label->setAlignment(Qt::AlignVCenter); | ||
294 | 481 | | |||
295 | m_editWidgets["status-label"] = label = new QLabel(i18n("Status")); | 482 | d->m_editWidgets["status-label"] = label = new QLabel(i18n("Status")); | ||
296 | label->setAlignment(Qt::AlignVCenter); | 483 | label->setAlignment(Qt::AlignVCenter); | ||
297 | 484 | | |||
298 | // if we don't have more than 1 selected transaction, we don't need | 485 | // if we don't have more than 1 selected transaction, we don't need | ||
299 | // the "don't change" item in some of the combo widgets | 486 | // the "don't change" item in some of the combo widgets | ||
300 | if (m_transactions.count() < 2) { | 487 | if (d->m_transactions.count() < 2) { | ||
301 | reconcile->removeDontCare(); | 488 | reconcile->removeDontCare(); | ||
302 | } | 489 | } | ||
303 | } | 490 | } | ||
304 | 491 | | |||
305 | int InvestTransactionEditor::slotEditFeeSplits() | 492 | int InvestTransactionEditor::slotEditFeeSplits() | ||
306 | { | 493 | { | ||
307 | return editSplits("fee-account", "fee-amount", m_feeSplits, false, SLOT(slotEditFeeSplits())); | 494 | Q_D(InvestTransactionEditor); | ||
495 | return d->editSplits("fee-account", "fee-amount", d->m_feeSplits, false, SLOT(slotEditFeeSplits())); | ||||
308 | } | 496 | } | ||
309 | 497 | | |||
310 | int InvestTransactionEditor::slotEditInterestSplits() | 498 | int InvestTransactionEditor::slotEditInterestSplits() | ||
311 | { | 499 | { | ||
312 | return editSplits("interest-account", "interest-amount", m_interestSplits, true, SLOT(slotEditInterestSplits())); | 500 | Q_D(InvestTransactionEditor); | ||
313 | } | 501 | return d->editSplits("interest-account", "interest-amount", d->m_interestSplits, true, SLOT(slotEditInterestSplits())); | ||
314 | | ||||
315 | int InvestTransactionEditor::editSplits(const QString& categoryWidgetName, const QString& amountWidgetName, QList<MyMoneySplit>& splits, bool isIncome, const char* slotEditSplits) | | |||
316 | { | | |||
317 | int rc = QDialog::Rejected; | | |||
318 | | ||||
319 | if (!m_openEditSplits) { | | |||
320 | // only get in here in a single instance | | |||
321 | m_openEditSplits = true; | | |||
322 | | ||||
323 | // force focus change to update all data | | |||
324 | KMyMoneyCategory* category = dynamic_cast<KMyMoneyCategory*>(m_editWidgets[categoryWidgetName]); | | |||
325 | QWidget* w = category->splitButton(); | | |||
326 | if (w) | | |||
327 | w->setFocus(); | | |||
328 | | ||||
329 | kMyMoneyEdit* amount = dynamic_cast<kMyMoneyEdit*>(haveWidget(amountWidgetName)); | | |||
330 | | ||||
331 | MyMoneyTransaction transaction; | | |||
332 | transaction.setCommodity(m_currency.id()); | | |||
333 | if (splits.count() == 0 && !category->selectedItem().isEmpty()) { | | |||
334 | MyMoneySplit s; | | |||
335 | s.setAccountId(category->selectedItem()); | | |||
336 | s.setShares(amount->value()); | | |||
337 | s.setValue(s.shares()); | | |||
338 | splits << s; | | |||
339 | } | | |||
340 | // use the transactions commodity as the currency indicator for the splits | | |||
341 | // this is used to allow some useful setting for the fractions in the amount fields | | |||
342 | try { | | |||
343 | d->m_phonyAccount.setCurrencyId(m_transaction.commodity()); | | |||
344 | d->m_phonyAccount.fraction(MyMoneyFile::instance()->security(m_transaction.commodity())); | | |||
345 | } catch (const MyMoneyException &) { | | |||
346 | qDebug("Unable to setup precision"); | | |||
347 | } | | |||
348 | | ||||
349 | if (createPseudoTransaction(transaction, splits)) { | | |||
350 | MyMoneyMoney value; | | |||
351 | | ||||
352 | QPointer<KSplitTransactionDlg> dlg = new KSplitTransactionDlg(transaction, | | |||
353 | d->m_phonySplit, | | |||
354 | d->m_phonyAccount, | | |||
355 | false, | | |||
356 | isIncome, | | |||
357 | MyMoneyMoney(), | | |||
358 | m_priceInfo, | | |||
359 | m_regForm); | | |||
360 | // connect(dlg, SIGNAL(newCategory(MyMoneyAccount&)), this, SIGNAL(newCategory(MyMoneyAccount&))); | | |||
361 | | ||||
362 | if ((rc = dlg->exec()) == QDialog::Accepted) { | | |||
363 | transaction = dlg->transaction(); | | |||
364 | // collect splits out of the transaction | | |||
365 | splits.clear(); | | |||
366 | QList<MyMoneySplit>::const_iterator it_s; | | |||
367 | MyMoneyMoney fees; | | |||
368 | for (it_s = transaction.splits().constBegin(); it_s != transaction.splits().constEnd(); ++it_s) { | | |||
369 | if ((*it_s).accountId() == d->m_phonyAccount.id()) | | |||
370 | continue; | | |||
371 | splits << *it_s; | | |||
372 | fees += (*it_s).shares(); | | |||
373 | } | | |||
374 | if (isIncome) | | |||
375 | fees = -fees; | | |||
376 | | ||||
377 | QString categoryId; | | |||
378 | setupCategoryWidget(category, splits, categoryId, slotEditSplits); | | |||
379 | amount->setValue(fees); | | |||
380 | slotUpdateTotalAmount(); | | |||
381 | } | | |||
382 | | ||||
383 | delete dlg; | | |||
384 | } | | |||
385 | | ||||
386 | // focus jumps into the memo field | | |||
387 | if ((w = haveWidget("memo")) != 0) { | | |||
388 | w->setFocus(); | | |||
389 | } | | |||
390 | | ||||
391 | m_openEditSplits = false; | | |||
392 | } | | |||
393 | return rc; | | |||
394 | } | | |||
395 | | ||||
396 | bool InvestTransactionEditor::createPseudoTransaction(MyMoneyTransaction& t, const QList<MyMoneySplit>& splits) | | |||
397 | { | | |||
398 | t.removeSplits(); | | |||
399 | | ||||
400 | MyMoneySplit split; | | |||
401 | split.setAccountId(d->m_phonyAccount.id()); | | |||
402 | split.setValue(-subtotal(splits)); | | |||
403 | split.setShares(split.value()); | | |||
404 | t.addSplit(split); | | |||
405 | d->m_phonySplit = split; | | |||
406 | | ||||
407 | QList<MyMoneySplit>::const_iterator it_s; | | |||
408 | for (it_s = splits.begin(); it_s != splits.end(); ++it_s) { | | |||
409 | split = *it_s; | | |||
410 | split.clearId(); | | |||
411 | t.addSplit(split); | | |||
412 | } | | |||
413 | return true; | | |||
414 | } | 502 | } | ||
415 | 503 | | |||
416 | void InvestTransactionEditor::slotCreateSecurity(const QString& name, QString& id) | 504 | void InvestTransactionEditor::slotCreateSecurity(const QString& name, QString& id) | ||
417 | { | 505 | { | ||
506 | Q_D(InvestTransactionEditor); | ||||
418 | MyMoneyAccount acc; | 507 | MyMoneyAccount acc; | ||
419 | QRegExp exp("([^:]+)"); | 508 | QRegExp exp("([^:]+)"); | ||
420 | if (exp.indexIn(name) != -1) { | 509 | if (exp.indexIn(name) != -1) { | ||
421 | acc.setName(exp.cap(1)); | 510 | acc.setName(exp.cap(1)); | ||
422 | 511 | | |||
423 | emit createSecurity(acc, m_account); | 512 | emit createSecurity(acc, d->m_account); | ||
424 | 513 | | |||
425 | // return id | 514 | // return id | ||
426 | id = acc.id(); | 515 | id = acc.id(); | ||
Context not available. | |||||
449 | 538 | | |||
450 | void InvestTransactionEditor::slotUpdateFeeVisibility(const QString& txt) | 539 | void InvestTransactionEditor::slotUpdateFeeVisibility(const QString& txt) | ||
451 | { | 540 | { | ||
541 | Q_D(InvestTransactionEditor); | ||||
452 | static const QSet<eMyMoney::Split::InvestmentTransactionType> transactionTypesWithoutFee = QSet<eMyMoney::Split::InvestmentTransactionType>() | 542 | static const QSet<eMyMoney::Split::InvestmentTransactionType> transactionTypesWithoutFee = QSet<eMyMoney::Split::InvestmentTransactionType>() | ||
453 | << eMyMoney::Split::InvestmentTransactionType::AddShares << eMyMoney::Split::InvestmentTransactionType::RemoveShares << eMyMoney::Split::InvestmentTransactionType::SplitShares; | 543 | << eMyMoney::Split::InvestmentTransactionType::AddShares << eMyMoney::Split::InvestmentTransactionType::RemoveShares << eMyMoney::Split::InvestmentTransactionType::SplitShares; | ||
454 | 544 | | |||
Context not available. | |||||
481 | 571 | | |||
482 | void InvestTransactionEditor::slotUpdateInterestVisibility(const QString& txt) | 572 | void InvestTransactionEditor::slotUpdateInterestVisibility(const QString& txt) | ||
483 | { | 573 | { | ||
574 | Q_D(InvestTransactionEditor); | ||||
484 | static const QSet<eMyMoney::Split::InvestmentTransactionType> transactionTypesWithInterest = QSet<eMyMoney::Split::InvestmentTransactionType>() | 575 | static const QSet<eMyMoney::Split::InvestmentTransactionType> transactionTypesWithInterest = QSet<eMyMoney::Split::InvestmentTransactionType>() | ||
485 | << eMyMoney::Split::InvestmentTransactionType::BuyShares << eMyMoney::Split::InvestmentTransactionType::SellShares << eMyMoney::Split::InvestmentTransactionType::Dividend << eMyMoney::Split::InvestmentTransactionType::InterestIncome << eMyMoney::Split::InvestmentTransactionType::Yield; | 576 | << eMyMoney::Split::InvestmentTransactionType::BuyShares << eMyMoney::Split::InvestmentTransactionType::SellShares << eMyMoney::Split::InvestmentTransactionType::Dividend << eMyMoney::Split::InvestmentTransactionType::InterestIncome << eMyMoney::Split::InvestmentTransactionType::Yield; | ||
486 | 577 | | |||
Context not available. | |||||
517 | 608 | | |||
518 | void InvestTransactionEditor::slotReloadEditWidgets() | 609 | void InvestTransactionEditor::slotReloadEditWidgets() | ||
519 | { | 610 | { | ||
520 | KMyMoneyCategory* interest = dynamic_cast<KMyMoneyCategory*>(haveWidget("interest-account")); | 611 | Q_D(InvestTransactionEditor); | ||
521 | KMyMoneyCategory* fees = dynamic_cast<KMyMoneyCategory*>(haveWidget("fee-account")); | 612 | auto interest = dynamic_cast<KMyMoneyCategory*>(haveWidget("interest-account")); | ||
522 | KMyMoneySecurity* security = dynamic_cast<KMyMoneySecurity*>(haveWidget("security")); | 613 | auto fees = dynamic_cast<KMyMoneyCategory*>(haveWidget("fee-account")); | ||
614 | auto security = dynamic_cast<KMyMoneySecurity*>(haveWidget("security")); | ||||
523 | 615 | | |||
524 | AccountSet aSet; | 616 | AccountSet aSet; | ||
525 | QString id; | 617 | QString id; | ||
526 | 618 | | |||
527 | // interest-account | 619 | // interest-account | ||
528 | aSet.clear(); | 620 | aSet.clear(); | ||
529 | aSet.addAccountGroup(eMyMoney::Account::Income); | 621 | aSet.addAccountGroup(Account::Income); | ||
530 | aSet.load(interest->selector()); | 622 | aSet.load(interest->selector()); | ||
531 | setupCategoryWidget(interest, m_interestSplits, id, SLOT(slotEditInterestSplits())); | 623 | setupCategoryWidget(interest, d->m_interestSplits, id, SLOT(slotEditInterestSplits())); | ||
532 | 624 | | |||
533 | // fee-account | 625 | // fee-account | ||
534 | aSet.clear(); | 626 | aSet.clear(); | ||
535 | aSet.addAccountGroup(eMyMoney::Account::Expense); | 627 | aSet.addAccountGroup(Account::Expense); | ||
536 | aSet.load(fees->selector()); | 628 | aSet.load(fees->selector()); | ||
537 | setupCategoryWidget(fees, m_feeSplits, id, SLOT(slotEditFeeSplits())); | 629 | setupCategoryWidget(fees, d->m_feeSplits, id, SLOT(slotEditFeeSplits())); | ||
538 | 630 | | |||
539 | // security | 631 | // security | ||
540 | aSet.clear(); | 632 | aSet.clear(); | ||
541 | aSet.load(security->selector(), i18n("Security"), m_account.accountList(), true); | 633 | aSet.load(security->selector(), i18n("Security"), d->m_account.accountList(), true); | ||
542 | } | 634 | } | ||
543 | 635 | | |||
544 | void InvestTransactionEditor::loadEditWidgets(KMyMoneyRegister::Action /* action */) | 636 | void InvestTransactionEditor::loadEditWidgets(KMyMoneyRegister::Action) | ||
545 | { | 637 | { | ||
638 | loadEditWidgets(); | ||||
639 | } | ||||
640 | | ||||
641 | void InvestTransactionEditor::loadEditWidgets() | ||||
642 | { | ||||
643 | Q_D(InvestTransactionEditor); | ||||
546 | QString id; | 644 | QString id; | ||
547 | 645 | | |||
548 | kMyMoneyDateInput* postDate = dynamic_cast<kMyMoneyDateInput*>(haveWidget("postdate")); | 646 | auto postDate = dynamic_cast<kMyMoneyDateInput*>(haveWidget("postdate")); | ||
549 | KMyMoneyReconcileCombo* reconcile = dynamic_cast<KMyMoneyReconcileCombo*>(haveWidget("status")); | 647 | auto reconcile = dynamic_cast<KMyMoneyReconcileCombo*>(haveWidget("status")); | ||
550 | KMyMoneySecurity* security = dynamic_cast<KMyMoneySecurity*>(haveWidget("security")); | 648 | auto security = dynamic_cast<KMyMoneySecurity*>(haveWidget("security")); | ||
551 | KMyMoneyActivityCombo* activity = dynamic_cast<KMyMoneyActivityCombo*>(haveWidget("activity")); | 649 | auto activity = dynamic_cast<KMyMoneyActivityCombo*>(haveWidget("activity")); | ||
552 | KMyMoneyCategory* asset = dynamic_cast<KMyMoneyCategory*>(haveWidget("asset-account")); | 650 | auto asset = dynamic_cast<KMyMoneyCategory*>(haveWidget("asset-account")); | ||
553 | KTextEdit* memo = dynamic_cast<KTextEdit*>(m_editWidgets["memo"]); | 651 | auto memo = dynamic_cast<KTextEdit*>(d->m_editWidgets["memo"]); | ||
554 | kMyMoneyEdit* value; | 652 | kMyMoneyEdit* value; | ||
555 | KMyMoneyCategory* interest = dynamic_cast<KMyMoneyCategory*>(haveWidget("interest-account")); | 653 | auto interest = dynamic_cast<KMyMoneyCategory*>(haveWidget("interest-account")); | ||
556 | KMyMoneyCategory* fees = dynamic_cast<KMyMoneyCategory*>(haveWidget("fee-account")); | 654 | auto fees = dynamic_cast<KMyMoneyCategory*>(haveWidget("fee-account")); | ||
557 | 655 | | |||
558 | // check if the current transaction has a reference to an equity account | 656 | // check if the current transaction has a reference to an equity account | ||
559 | bool haveEquityAccount = false; | 657 | bool haveEquityAccount = false; | ||
560 | QList<MyMoneySplit>::const_iterator it_s; | 658 | QList<MyMoneySplit>::const_iterator it_s; | ||
561 | for (it_s = m_transaction.splits().constBegin(); !haveEquityAccount && it_s != m_transaction.splits().constEnd(); ++it_s) { | 659 | for (it_s = d->m_transaction.splits().constBegin(); !haveEquityAccount && it_s != d->m_transaction.splits().constEnd(); ++it_s) { | ||
562 | MyMoneyAccount acc = MyMoneyFile::instance()->account((*it_s).accountId()); | 660 | MyMoneyAccount acc = MyMoneyFile::instance()->account((*it_s).accountId()); | ||
563 | if (acc.accountType() == eMyMoney::Account::Equity) | 661 | if (acc.accountType() == Account::Equity) | ||
564 | haveEquityAccount = true; | 662 | haveEquityAccount = true; | ||
565 | } | 663 | } | ||
566 | 664 | | |||
567 | // asset-account | 665 | // asset-account | ||
568 | AccountSet aSet; | 666 | AccountSet aSet; | ||
569 | aSet.clear(); | 667 | aSet.clear(); | ||
570 | aSet.addAccountType(eMyMoney::Account::Checkings); | 668 | aSet.addAccountType(Account::Checkings); | ||
571 | aSet.addAccountType(eMyMoney::Account::Savings); | 669 | aSet.addAccountType(Account::Savings); | ||
572 | aSet.addAccountType(eMyMoney::Account::Cash); | 670 | aSet.addAccountType(Account::Cash); | ||
573 | aSet.addAccountType(eMyMoney::Account::Asset); | 671 | aSet.addAccountType(Account::Asset); | ||
574 | aSet.addAccountType(eMyMoney::Account::Currency); | 672 | aSet.addAccountType(Account::Currency); | ||
575 | aSet.addAccountType(eMyMoney::Account::CreditCard); | 673 | aSet.addAccountType(Account::CreditCard); | ||
576 | if (KMyMoneyGlobalSettings::expertMode() || haveEquityAccount) | 674 | if (KMyMoneyGlobalSettings::expertMode() || haveEquityAccount) | ||
577 | aSet.addAccountGroup(eMyMoney::Account::Equity); | 675 | aSet.addAccountGroup(Account::Equity); | ||
578 | aSet.load(asset->selector()); | 676 | aSet.load(asset->selector()); | ||
579 | 677 | | |||
580 | // security | 678 | // security | ||
581 | security->setSuppressObjectCreation(false); // allow object creation on the fly | 679 | security->setSuppressObjectCreation(false); // allow object creation on the fly | ||
582 | aSet.clear(); | 680 | aSet.clear(); | ||
583 | aSet.load(security->selector(), i18n("Security"), m_account.accountList(), true); | 681 | aSet.load(security->selector(), i18n("Security"), d->m_account.accountList(), true); | ||
584 | 682 | | |||
585 | // memo | 683 | // memo | ||
586 | memo->setText(m_split.memo()); | 684 | memo->setText(d->m_split.memo()); | ||
587 | d->m_activity->m_memoText = m_split.memo(); | 685 | d->m_activity->memoText() = d->m_split.memo(); | ||
588 | d->m_activity->m_memoChanged = false; | 686 | d->m_activity->memoChanged() = false; | ||
589 | 687 | | |||
590 | if (!isMultiSelection()) { | 688 | if (!isMultiSelection()) { | ||
591 | // date | 689 | // date | ||
592 | if (m_transaction.postDate().isValid()) | 690 | if (d->m_transaction.postDate().isValid()) | ||
593 | postDate->setDate(m_transaction.postDate()); | 691 | postDate->setDate(d->m_transaction.postDate()); | ||
594 | else if (m_lastPostDate.isValid()) | 692 | else if (d->m_lastPostDate.isValid()) | ||
595 | postDate->setDate(m_lastPostDate); | 693 | postDate->setDate(d->m_lastPostDate); | ||
596 | else | 694 | else | ||
597 | postDate->setDate(QDate::currentDate()); | 695 | postDate->setDate(QDate::currentDate()); | ||
598 | 696 | | |||
599 | // security (but only if it's not the investment account) | 697 | // security (but only if it's not the investment account) | ||
600 | if (m_split.accountId() != m_account.id()) { | 698 | if (d->m_split.accountId() != d->m_account.id()) { | ||
601 | security->completion()->setSelected(m_split.accountId()); | 699 | security->completion()->setSelected(d->m_split.accountId()); | ||
602 | security->slotItemSelected(m_split.accountId()); | 700 | security->slotItemSelected(d->m_split.accountId()); | ||
603 | } | 701 | } | ||
604 | 702 | | |||
605 | // activity | 703 | // activity | ||
606 | activity->setActivity(d->m_activity->type()); | 704 | activity->setActivity(d->m_activity->type()); | ||
607 | slotUpdateActivity(activity->activity()); | 705 | slotUpdateActivity(activity->activity()); | ||
608 | 706 | | |||
609 | asset->completion()->setSelected(m_assetAccountSplit.accountId()); | 707 | asset->completion()->setSelected(d->m_assetAccountSplit.accountId()); | ||
610 | asset->slotItemSelected(m_assetAccountSplit.accountId()); | 708 | asset->slotItemSelected(d->m_assetAccountSplit.accountId()); | ||
611 | 709 | | |||
612 | // interest-account | 710 | // interest-account | ||
613 | aSet.clear(); | 711 | aSet.clear(); | ||
614 | aSet.addAccountGroup(eMyMoney::Account::Income); | 712 | aSet.addAccountGroup(Account::Income); | ||
615 | aSet.load(interest->selector()); | 713 | aSet.load(interest->selector()); | ||
616 | setupCategoryWidget(interest, m_interestSplits, id, SLOT(slotEditInterestSplits())); | 714 | setupCategoryWidget(interest, d->m_interestSplits, id, SLOT(slotEditInterestSplits())); | ||
617 | slotUpdateInterestVisibility(interest->currentText()); | 715 | slotUpdateInterestVisibility(interest->currentText()); | ||
618 | 716 | | |||
619 | // fee-account | 717 | // fee-account | ||
620 | aSet.clear(); | 718 | aSet.clear(); | ||
621 | aSet.addAccountGroup(eMyMoney::Account::Expense); | 719 | aSet.addAccountGroup(Account::Expense); | ||
622 | aSet.load(fees->selector()); | 720 | aSet.load(fees->selector()); | ||
623 | setupCategoryWidget(fees, m_feeSplits, id, SLOT(slotEditFeeSplits())); | 721 | setupCategoryWidget(fees, d->m_feeSplits, id, SLOT(slotEditFeeSplits())); | ||
624 | slotUpdateFeeVisibility(fees->currentText()); | 722 | slotUpdateFeeVisibility(fees->currentText()); | ||
625 | 723 | | |||
626 | // shares | 724 | // shares | ||
Context not available. | |||||
628 | // we can see the hint | 726 | // we can see the hint | ||
629 | value = dynamic_cast<kMyMoneyEdit*>(haveWidget("shares")); | 727 | value = dynamic_cast<kMyMoneyEdit*>(haveWidget("shares")); | ||
630 | if (typeid(*(d->m_activity)) != typeid(Invest::Split(this))) | 728 | if (typeid(*(d->m_activity)) != typeid(Invest::Split(this))) | ||
631 | value->setPrecision(MyMoneyMoney::denomToPrec(m_security.smallestAccountFraction())); | 729 | value->setPrecision(MyMoneyMoney::denomToPrec(d->m_security.smallestAccountFraction())); | ||
632 | else | 730 | else | ||
633 | value->setPrecision(-1); | 731 | value->setPrecision(-1); | ||
634 | 732 | | |||
635 | if (!m_split.shares().isZero()) | 733 | if (!d->m_split.shares().isZero()) | ||
636 | value->setValue(m_split.shares().abs()); | 734 | value->setValue(d->m_split.shares().abs()); | ||
637 | 735 | | |||
638 | // price | 736 | // price | ||
639 | updatePriceMode(m_split); | 737 | d->updatePriceMode(d->m_split); | ||
640 | 738 | | |||
641 | // fee amount | 739 | // fee amount | ||
642 | value = dynamic_cast<kMyMoneyEdit*>(haveWidget("fee-amount")); | 740 | value = dynamic_cast<kMyMoneyEdit*>(haveWidget("fee-amount")); | ||
643 | value->setValue(subtotal(m_feeSplits)); | 741 | value->setValue(d->subtotal(d->m_feeSplits)); | ||
644 | 742 | | |||
645 | // interest amount | 743 | // interest amount | ||
646 | value = dynamic_cast<kMyMoneyEdit*>(haveWidget("interest-amount")); | 744 | value = dynamic_cast<kMyMoneyEdit*>(haveWidget("interest-amount")); | ||
647 | value->setValue(-subtotal(m_interestSplits)); | 745 | value->setValue(-d->subtotal(d->m_interestSplits)); | ||
648 | 746 | | |||
649 | // total | 747 | // total | ||
650 | slotUpdateTotalAmount(); | 748 | slotUpdateTotalAmount(); | ||
651 | 749 | | |||
652 | // status | 750 | // status | ||
653 | if (m_split.reconcileFlag() == eMyMoney::Split::State::Unknown) | 751 | if (d->m_split.reconcileFlag() == eMyMoney::Split::State::Unknown) | ||
654 | m_split.setReconcileFlag(eMyMoney::Split::State::NotReconciled); | 752 | d->m_split.setReconcileFlag(eMyMoney::Split::State::NotReconciled); | ||
655 | reconcile->setState(m_split.reconcileFlag()); | 753 | reconcile->setState(d->m_split.reconcileFlag()); | ||
656 | 754 | | |||
657 | } else { | 755 | } else { | ||
658 | postDate->loadDate(QDate()); | 756 | postDate->loadDate(QDate()); | ||
Context not available. | |||||
665 | 763 | | |||
666 | // scan the list of selected transactions and check that they have | 764 | // scan the list of selected transactions and check that they have | ||
667 | // the same activity. | 765 | // the same activity. | ||
668 | KMyMoneyRegister::SelectedTransactions::iterator it_t = m_transactions.begin(); | 766 | KMyMoneyRegister::SelectedTransactions::iterator it_t = d->m_transactions.begin(); | ||
669 | const QString& action = m_item->split().action(); | 767 | const QString& action = d->m_item->split().action(); | ||
670 | bool isNegative = m_item->split().shares().isNegative(); | 768 | bool isNegative = d->m_item->split().shares().isNegative(); | ||
671 | bool allSameActivity = true; | 769 | bool allSameActivity = true; | ||
672 | for (it_t = m_transactions.begin(); allSameActivity && (it_t != m_transactions.end()); ++it_t) { | 770 | for (it_t = d->m_transactions.begin(); allSameActivity && (it_t != d->m_transactions.end()); ++it_t) { | ||
673 | allSameActivity = (action == (*it_t).split().action() && (*it_t).split().shares().isNegative() == isNegative); | 771 | allSameActivity = (action == (*it_t).split().action() && (*it_t).split().shares().isNegative() == isNegative); | ||
674 | } | 772 | } | ||
675 | 773 | | |||
Context not available. | |||||
695 | 793 | | |||
696 | QWidget* InvestTransactionEditor::firstWidget() const | 794 | QWidget* InvestTransactionEditor::firstWidget() const | ||
697 | { | 795 | { | ||
698 | return 0; // let the creator use the first widget in the tab order | 796 | return nullptr; // let the creator use the first widget in the tab order | ||
699 | } | 797 | } | ||
700 | 798 | | |||
701 | bool InvestTransactionEditor::isComplete(QString& reason) const | 799 | bool InvestTransactionEditor::isComplete(QString& reason) const | ||
702 | { | 800 | { | ||
801 | Q_D(const InvestTransactionEditor); | ||||
703 | reason.clear(); | 802 | reason.clear(); | ||
704 | return d->m_activity->isComplete(reason); | 803 | return d->m_activity->isComplete(reason); | ||
705 | } | 804 | } | ||
706 | 805 | | |||
707 | MyMoneyMoney InvestTransactionEditor::subtotal(const QList<MyMoneySplit>& splits) const | | |||
708 | { | | |||
709 | QList<MyMoneySplit>::const_iterator it_s; | | |||
710 | MyMoneyMoney sum; | | |||
711 | | ||||
712 | for (it_s = splits.begin(); it_s != splits.end(); ++it_s) { | | |||
713 | sum += (*it_s).value(); | | |||
714 | } | | |||
715 | | ||||
716 | return sum; | | |||
717 | } | | |||
718 | | ||||
719 | void InvestTransactionEditor::slotUpdateSecurity(const QString& stockId) | 806 | void InvestTransactionEditor::slotUpdateSecurity(const QString& stockId) | ||
720 | { | 807 | { | ||
721 | MyMoneyFile* file = MyMoneyFile::instance(); | 808 | Q_D(InvestTransactionEditor); | ||
809 | auto file = MyMoneyFile::instance(); | ||||
722 | MyMoneyAccount stock = file->account(stockId); | 810 | MyMoneyAccount stock = file->account(stockId); | ||
723 | m_security = file->security(stock.currencyId()); | 811 | d->m_security = file->security(stock.currencyId()); | ||
724 | m_currency = file->security(m_security.tradingCurrency()); | 812 | d->m_currency = file->security(d->m_security.tradingCurrency()); | ||
725 | bool currencyKnown = !m_currency.id().isEmpty(); | 813 | bool currencyKnown = !d->m_currency.id().isEmpty(); | ||
726 | if (!currencyKnown) { | 814 | if (!currencyKnown) { | ||
727 | m_currency.setTradingSymbol("???"); | 815 | d->m_currency.setTradingSymbol("???"); | ||
728 | } else { | 816 | } else { | ||
729 | if (typeid(*(d->m_activity)) != typeid(Invest::Split(this))) { | 817 | if (typeid(*(d->m_activity)) != typeid(Invest::Split(this))) { | ||
730 | dynamic_cast<kMyMoneyEdit*>(haveWidget("shares"))->setPrecision(MyMoneyMoney::denomToPrec(m_security.smallestAccountFraction())); | 818 | dynamic_cast<kMyMoneyEdit*>(haveWidget("shares"))->setPrecision(MyMoneyMoney::denomToPrec(d->m_security.smallestAccountFraction())); | ||
731 | } else { | 819 | } else { | ||
732 | dynamic_cast<kMyMoneyEdit*>(haveWidget("shares"))->setPrecision(-1); | 820 | dynamic_cast<kMyMoneyEdit*>(haveWidget("shares"))->setPrecision(-1); | ||
733 | } | 821 | } | ||
734 | } | 822 | } | ||
735 | 823 | | |||
736 | updatePriceMode(); | 824 | d->updatePriceMode(); | ||
737 | 825 | | |||
738 | d->m_activity->preloadAssetAccount(); | 826 | d->m_activity->preloadAssetAccount(); | ||
739 | 827 | | |||
Context not available. | |||||
747 | resizeForm(); | 835 | resizeForm(); | ||
748 | } | 836 | } | ||
749 | 837 | | |||
838 | bool InvestTransactionEditor::fixTransactionCommodity(const MyMoneyAccount& /* account */) | ||||
839 | { | ||||
840 | return true; | ||||
841 | } | ||||
842 | | ||||
843 | | ||||
750 | void InvestTransactionEditor::totalAmount(MyMoneyMoney& amount) const | 844 | void InvestTransactionEditor::totalAmount(MyMoneyMoney& amount) const | ||
751 | { | 845 | { | ||
752 | KMyMoneyActivityCombo* activityCombo = dynamic_cast<KMyMoneyActivityCombo*>(haveWidget("activity")); | 846 | auto activityCombo = dynamic_cast<KMyMoneyActivityCombo*>(haveWidget("activity")); | ||
753 | kMyMoneyEdit* sharesEdit = dynamic_cast<kMyMoneyEdit*>(haveWidget("shares")); | 847 | auto sharesEdit = dynamic_cast<kMyMoneyEdit*>(haveWidget("shares")); | ||
754 | kMyMoneyEdit* priceEdit = dynamic_cast<kMyMoneyEdit*>(haveWidget("price")); | 848 | auto priceEdit = dynamic_cast<kMyMoneyEdit*>(haveWidget("price")); | ||
755 | kMyMoneyEdit* feesEdit = dynamic_cast<kMyMoneyEdit*>(haveWidget("fee-amount")); | 849 | auto feesEdit = dynamic_cast<kMyMoneyEdit*>(haveWidget("fee-amount")); | ||
756 | kMyMoneyEdit* interestEdit = dynamic_cast<kMyMoneyEdit*>(haveWidget("interest-amount")); | 850 | auto interestEdit = dynamic_cast<kMyMoneyEdit*>(haveWidget("interest-amount")); | ||
757 | 851 | | |||
758 | if (priceMode() == InvestTransactionEditor::PricePerTransaction) | 852 | if (priceMode() == eDialogs::PriceMode::PricePerTransaction) | ||
759 | amount = priceEdit->value().abs(); | 853 | amount = priceEdit->value().abs(); | ||
760 | else | 854 | else | ||
761 | amount = sharesEdit->value().abs() * priceEdit->value().abs(); | 855 | amount = sharesEdit->value().abs() * priceEdit->value().abs(); | ||
Context not available. | |||||
790 | 884 | | |||
791 | void InvestTransactionEditor::slotUpdateTotalAmount() | 885 | void InvestTransactionEditor::slotUpdateTotalAmount() | ||
792 | { | 886 | { | ||
887 | Q_D(InvestTransactionEditor); | ||||
793 | QLabel* total = dynamic_cast<QLabel*>(haveWidget("total")); | 888 | QLabel* total = dynamic_cast<QLabel*>(haveWidget("total")); | ||
794 | 889 | | |||
795 | if (total && total->isVisible()) { | 890 | if (total && total->isVisible()) { | ||
796 | MyMoneyMoney amount; | 891 | MyMoneyMoney amount; | ||
797 | totalAmount(amount); | 892 | totalAmount(amount); | ||
798 | total->setText(amount.convert(m_currency.smallestAccountFraction(), static_cast<MyMoneyMoney::roundingMethod>(m_security.roundingMethod())) | 893 | total->setText(amount.convert(d->m_currency.smallestAccountFraction(), static_cast<MyMoneyMoney::roundingMethod>(d->m_security.roundingMethod())) | ||
799 | .formatMoney(m_currency.tradingSymbol(), MyMoneyMoney::denomToPrec(m_currency.smallestAccountFraction()))); | 894 | .formatMoney(d->m_currency.tradingSymbol(), MyMoneyMoney::denomToPrec(d->m_currency.smallestAccountFraction()))); | ||
800 | } | 895 | } | ||
801 | } | 896 | } | ||
802 | 897 | | |||
803 | void InvestTransactionEditor::slotTransactionContainerGeometriesUpdated() | 898 | void InvestTransactionEditor::slotTransactionContainerGeometriesUpdated() | ||
804 | { | 899 | { | ||
900 | Q_D(InvestTransactionEditor); | ||||
805 | // when the geometries of the transaction container are updated some edit widgets that were | 901 | // when the geometries of the transaction container are updated some edit widgets that were | ||
806 | // previously hidden are being shown (see QAbstractItemView::updateEditorGeometries) so we | 902 | // previously hidden are being shown (see QAbstractItemView::updateEditorGeometries) so we | ||
807 | // need to update the activity with the current activity in order to show only the widgets | 903 | // need to update the activity with the current activity in order to show only the widgets | ||
Context not available. | |||||
811 | 907 | | |||
812 | void InvestTransactionEditor::slotUpdateActivity(eMyMoney::Split::InvestmentTransactionType activity) | 908 | void InvestTransactionEditor::slotUpdateActivity(eMyMoney::Split::InvestmentTransactionType activity) | ||
813 | { | 909 | { | ||
910 | Q_D(InvestTransactionEditor); | ||||
814 | // create new activity object if required | 911 | // create new activity object if required | ||
815 | activityFactory(activity); | 912 | d->activityFactory(activity); | ||
816 | 913 | | |||
817 | // hide all dynamic widgets | 914 | // hide all dynamic widgets | ||
818 | d->hideCategory("interest-account"); | 915 | d->hideCategory("interest-account"); | ||
Context not available. | |||||
857 | } | 954 | } | ||
858 | } | 955 | } | ||
859 | 956 | | |||
860 | InvestTransactionEditor::priceModeE InvestTransactionEditor::priceMode() const | 957 | eDialogs::PriceMode InvestTransactionEditor::priceMode() const | ||
861 | { | 958 | { | ||
862 | priceModeE mode = static_cast<priceModeE>(Price); | 959 | Q_D(const InvestTransactionEditor); | ||
863 | KMyMoneySecurity* sec = dynamic_cast<KMyMoneySecurity*>(m_editWidgets["security"]); | 960 | eDialogs::PriceMode mode = static_cast<eDialogs::PriceMode>(eDialogs::PriceMode::Price); | ||
961 | KMyMoneySecurity* sec = dynamic_cast<KMyMoneySecurity*>(d->m_editWidgets["security"]); | ||||
864 | QString accId; | 962 | QString accId; | ||
865 | if (!sec->currentText().isEmpty()) { | 963 | if (!sec->currentText().isEmpty()) { | ||
866 | accId = sec->selectedItem(); | 964 | accId = sec->selectedItem(); | ||
867 | if (accId.isEmpty()) | 965 | if (accId.isEmpty()) | ||
868 | accId = m_account.id(); | 966 | accId = d->m_account.id(); | ||
869 | } | 967 | } | ||
870 | while (!accId.isEmpty() && mode == Price) { | 968 | while (!accId.isEmpty() && mode == eDialogs::PriceMode::Price) { | ||
871 | MyMoneyAccount acc = MyMoneyFile::instance()->account(accId); | 969 | MyMoneyAccount acc = MyMoneyFile::instance()->account(accId); | ||
872 | if (acc.value("priceMode").isEmpty()) | 970 | if (acc.value("priceMode").isEmpty()) | ||
873 | accId = acc.parentAccountId(); | 971 | accId = acc.parentAccountId(); | ||
874 | else | 972 | else | ||
875 | mode = static_cast<priceModeE>(acc.value("priceMode").toInt()); | 973 | mode = static_cast<eDialogs::PriceMode>(acc.value("priceMode").toInt()); | ||
876 | } | 974 | } | ||
877 | 975 | | |||
878 | // if mode is still <Price> then use that | 976 | // if mode is still <Price> then use that | ||
879 | if (mode == Price) | 977 | if (mode == eDialogs::PriceMode::Price) | ||
880 | mode = PricePerShare; | 978 | mode = eDialogs::PriceMode::PricePerShare; | ||
881 | return mode; | 979 | return mode; | ||
882 | } | 980 | } | ||
883 | 981 | | |||
982 | MyMoneySecurity InvestTransactionEditor::security() const | ||||
983 | { | ||||
984 | Q_D(const InvestTransactionEditor); | ||||
985 | return d->m_security; | ||||
986 | } | ||||
987 | | ||||
988 | QList<MyMoneySplit> InvestTransactionEditor::feeSplits() const | ||||
989 | { | ||||
990 | Q_D(const InvestTransactionEditor); | ||||
991 | return d->m_feeSplits; | ||||
992 | } | ||||
993 | | ||||
994 | QList<MyMoneySplit> InvestTransactionEditor::interestSplits() const | ||||
995 | { | ||||
996 | Q_D(const InvestTransactionEditor); | ||||
997 | return d->m_interestSplits; | ||||
998 | } | ||||
999 | | ||||
884 | bool InvestTransactionEditor::setupPrice(const MyMoneyTransaction& t, MyMoneySplit& split) | 1000 | bool InvestTransactionEditor::setupPrice(const MyMoneyTransaction& t, MyMoneySplit& split) | ||
885 | { | 1001 | { | ||
886 | MyMoneyFile* file = MyMoneyFile::instance(); | 1002 | Q_D(InvestTransactionEditor); | ||
1003 | auto file = MyMoneyFile::instance(); | ||||
887 | MyMoneyAccount acc = file->account(split.accountId()); | 1004 | MyMoneyAccount acc = file->account(split.accountId()); | ||
888 | MyMoneySecurity toCurrency(file->security(acc.currencyId())); | 1005 | MyMoneySecurity toCurrency(file->security(acc.currencyId())); | ||
889 | int fract = acc.fraction(); | 1006 | int fract = acc.fraction(); | ||
Context not available. | |||||
894 | 1011 | | |||
895 | QMap<QString, MyMoneyMoney>::Iterator it_p; | 1012 | QMap<QString, MyMoneyMoney>::Iterator it_p; | ||
896 | QString key = t.commodity() + '-' + acc.currencyId(); | 1013 | QString key = t.commodity() + '-' + acc.currencyId(); | ||
897 | it_p = m_priceInfo.find(key); | 1014 | it_p = d->m_priceInfo.find(key); | ||
898 | 1015 | | |||
899 | // if it's not found, then collect it from the user first | 1016 | // if it's not found, then collect it from the user first | ||
900 | MyMoneyMoney price; | 1017 | MyMoneyMoney price; | ||
901 | if (it_p == m_priceInfo.end()) { | 1018 | if (it_p == d->m_priceInfo.end()) { | ||
902 | MyMoneySecurity fromCurrency = file->security(t.commodity()); | 1019 | MyMoneySecurity fromCurrency = file->security(t.commodity()); | ||
903 | MyMoneyMoney fromValue, toValue; | 1020 | MyMoneyMoney fromValue, toValue; | ||
904 | 1021 | | |||
Context not available. | |||||
913 | toValue, | 1030 | toValue, | ||
914 | t.postDate(), | 1031 | t.postDate(), | ||
915 | fract, | 1032 | fract, | ||
916 | m_regForm); | 1033 | d->m_regForm); | ||
917 | 1034 | | |||
918 | if (calc->exec() == QDialog::Rejected) { | 1035 | if (calc->exec() == QDialog::Rejected) { | ||
919 | delete calc; | 1036 | delete calc; | ||
Context not available. | |||||
921 | } | 1038 | } | ||
922 | price = calc->price(); | 1039 | price = calc->price(); | ||
923 | delete calc; | 1040 | delete calc; | ||
924 | m_priceInfo[key] = price; | 1041 | d->m_priceInfo[key] = price; | ||
925 | } else { | 1042 | } else { | ||
926 | price = (*it_p); | 1043 | price = (*it_p); | ||
927 | } | 1044 | } | ||
Context not available. | |||||
938 | 1055 | | |||
939 | bool InvestTransactionEditor::createTransaction(MyMoneyTransaction& t, const MyMoneyTransaction& torig, const MyMoneySplit& sorig, bool /* skipPriceDialog */) | 1056 | bool InvestTransactionEditor::createTransaction(MyMoneyTransaction& t, const MyMoneyTransaction& torig, const MyMoneySplit& sorig, bool /* skipPriceDialog */) | ||
940 | { | 1057 | { | ||
941 | MyMoneyFile* file = MyMoneyFile::instance(); | 1058 | Q_D(InvestTransactionEditor); | ||
1059 | auto file = MyMoneyFile::instance(); | ||||
942 | // we start with the previous values, make sure we can add them later on | 1060 | // we start with the previous values, make sure we can add them later on | ||
943 | t = torig; | 1061 | t = torig; | ||
944 | MyMoneySplit s0 = sorig; | 1062 | MyMoneySplit s0 = sorig; | ||
945 | s0.clearId(); | 1063 | s0.clearId(); | ||
946 | 1064 | | |||
947 | KMyMoneySecurity* sec = dynamic_cast<KMyMoneySecurity*>(m_editWidgets["security"]); | 1065 | KMyMoneySecurity* sec = dynamic_cast<KMyMoneySecurity*>(d->m_editWidgets["security"]); | ||
948 | if (!isMultiSelection() || (isMultiSelection() && !sec->currentText().isEmpty())) { | 1066 | if (!isMultiSelection() || (isMultiSelection() && !sec->currentText().isEmpty())) { | ||
949 | QString securityId = sec->selectedItem(); | 1067 | QString securityId = sec->selectedItem(); | ||
950 | if (!securityId.isEmpty()) { | 1068 | if (!securityId.isEmpty()) { | ||
Context not available. | |||||
955 | 1073 | | |||
956 | t.setCommodity(security.tradingCurrency()); | 1074 | t.setCommodity(security.tradingCurrency()); | ||
957 | } else { | 1075 | } else { | ||
958 | s0.setAccountId(m_account.id()); | 1076 | s0.setAccountId(d->m_account.id()); | ||
959 | t.setCommodity(m_account.currencyId()); | 1077 | t.setCommodity(d->m_account.currencyId()); | ||
960 | } | 1078 | } | ||
961 | } | 1079 | } | ||
962 | 1080 | | |||
963 | // extract price info from original transaction | 1081 | // extract price info from original transaction | ||
964 | m_priceInfo.clear(); | 1082 | d->m_priceInfo.clear(); | ||
965 | QList<MyMoneySplit>::const_iterator it_s; | 1083 | QList<MyMoneySplit>::const_iterator it_s; | ||
966 | if (!torig.id().isEmpty()) { | 1084 | if (!torig.id().isEmpty()) { | ||
967 | for (it_s = torig.splits().begin(); it_s != torig.splits().end(); ++it_s) { | 1085 | for (it_s = torig.splits().begin(); it_s != torig.splits().end(); ++it_s) { | ||
968 | if ((*it_s).id() != sorig.id()) { | 1086 | if ((*it_s).id() != sorig.id()) { | ||
969 | MyMoneyAccount cat = file->account((*it_s).accountId()); | 1087 | MyMoneyAccount cat = file->account((*it_s).accountId()); | ||
970 | if (cat.currencyId() != m_account.currencyId()) { | 1088 | if (cat.currencyId() != d->m_account.currencyId()) { | ||
971 | if (cat.currencyId().isEmpty()) | 1089 | if (cat.currencyId().isEmpty()) | ||
972 | cat.setCurrencyId(m_account.currencyId()); | 1090 | cat.setCurrencyId(d->m_account.currencyId()); | ||
973 | if (!(*it_s).shares().isZero() && !(*it_s).value().isZero()) { | 1091 | if (!(*it_s).shares().isZero() && !(*it_s).value().isZero()) { | ||
974 | m_priceInfo[cat.currencyId()] = ((*it_s).shares() / (*it_s).value()).reduce(); | 1092 | d->m_priceInfo[cat.currencyId()] = ((*it_s).shares() / (*it_s).value()).reduce(); | ||
975 | } | 1093 | } | ||
976 | } | 1094 | } | ||
977 | } | 1095 | } | ||
Context not available. | |||||
980 | 1098 | | |||
981 | t.removeSplits(); | 1099 | t.removeSplits(); | ||
982 | 1100 | | |||
983 | kMyMoneyDateInput* postDate = dynamic_cast<kMyMoneyDateInput*>(m_editWidgets["postdate"]); | 1101 | kMyMoneyDateInput* postDate = dynamic_cast<kMyMoneyDateInput*>(d->m_editWidgets["postdate"]); | ||
984 | if (postDate->date().isValid()) { | 1102 | if (postDate->date().isValid()) { | ||
985 | t.setPostDate(postDate->date()); | 1103 | t.setPostDate(postDate->date()); | ||
986 | } | 1104 | } | ||
Context not available. | |||||
990 | // FIXME a better approach would be to have a 'dirty' flag with the widgets | 1108 | // FIXME a better approach would be to have a 'dirty' flag with the widgets | ||
991 | // which identifies if the originally loaded value has been modified | 1109 | // which identifies if the originally loaded value has been modified | ||
992 | // by the user | 1110 | // by the user | ||
993 | KTextEdit* memo = dynamic_cast<KTextEdit*>(m_editWidgets["memo"]); | 1111 | KTextEdit* memo = dynamic_cast<KTextEdit*>(d->m_editWidgets["memo"]); | ||
994 | if (memo) { | 1112 | if (memo) { | ||
995 | if (!isMultiSelection() || (isMultiSelection() && d->m_activity->m_memoChanged)) | 1113 | if (!isMultiSelection() || (isMultiSelection() && d->m_activity->memoChanged())) | ||
996 | s0.setMemo(memo->toPlainText()); | 1114 | s0.setMemo(memo->toPlainText()); | ||
997 | } | 1115 | } | ||
998 | 1116 | | |||
Context not available. | |||||
1021 | 1139 | | |||
1022 | // keep the current activity object and create a new one | 1140 | // keep the current activity object and create a new one | ||
1023 | // that can be destroyed later on | 1141 | // that can be destroyed later on | ||
1024 | Activity* activity = d->m_activity; | 1142 | auto activity = d->m_activity; | ||
1025 | d->m_activity = 0; // make sure we create a new one | 1143 | d->m_activity = 0; // make sure we create a new one | ||
1026 | activityFactory(activity->type()); | 1144 | d->activityFactory(activity->type()); | ||
1027 | 1145 | | |||
1028 | // if the activity is not set in the combo widget, we keep | 1146 | // if the activity is not set in the combo widget, we keep | ||
1029 | // the one which is used in the original transaction | 1147 | // the one which is used in the original transaction | ||
1030 | KMyMoneyActivityCombo* activityCombo = dynamic_cast<KMyMoneyActivityCombo*>(haveWidget("activity")); | 1148 | auto activityCombo = dynamic_cast<KMyMoneyActivityCombo*>(haveWidget("activity")); | ||
1031 | if (activityCombo->activity() == eMyMoney::Split::InvestmentTransactionType::UnknownTransactionType) { | 1149 | if (activityCombo->activity() == eMyMoney::Split::InvestmentTransactionType::UnknownTransactionType) { | ||
1032 | activityFactory(transactionType); | 1150 | d->activityFactory(transactionType); | ||
1033 | } | 1151 | } | ||
1034 | 1152 | | |||
1035 | // if we mark the split reconciled here, we'll use today's date if no reconciliation date is given | 1153 | // if we mark the split reconciled here, we'll use today's date if no reconciliation date is given | ||
1036 | KMyMoneyReconcileCombo* status = dynamic_cast<KMyMoneyReconcileCombo*>(m_editWidgets["status"]); | 1154 | auto status = dynamic_cast<KMyMoneyReconcileCombo*>(d->m_editWidgets["status"]); | ||
1037 | if (status->state() != eMyMoney::Split::State::Unknown) | 1155 | if (status->state() != eMyMoney::Split::State::Unknown) | ||
1038 | s0.setReconcileFlag(status->state()); | 1156 | s0.setReconcileFlag(status->state()); | ||
1039 | 1157 | | |||
Context not available. | |||||
1041 | s0.setReconcileDate(QDate::currentDate()); | 1159 | s0.setReconcileDate(QDate::currentDate()); | ||
1042 | 1160 | | |||
1043 | // call the creation logic for the current selected activity | 1161 | // call the creation logic for the current selected activity | ||
1044 | bool rc = d->m_activity->createTransaction(t, s0, assetAccountSplit, feeSplits, m_feeSplits, interestSplits, m_interestSplits, security, currency); | 1162 | bool rc = d->m_activity->createTransaction(t, s0, assetAccountSplit, feeSplits, d->m_feeSplits, interestSplits, d->m_interestSplits, security, currency); | ||
1045 | 1163 | | |||
1046 | // now switch back to the original activity | 1164 | // now switch back to the original activity | ||
1047 | delete d->m_activity; | 1165 | delete d->m_activity; | ||
Context not available. | |||||
1086 | return rc; | 1204 | return rc; | ||
1087 | } | 1205 | } | ||
1088 | 1206 | | |||
1089 | void InvestTransactionEditor::updatePriceMode(const MyMoneySplit& split) | | |||
1090 | { | | |||
1091 | QLabel* label = dynamic_cast<QLabel*>(haveWidget("price-label")); | | |||
1092 | if (label) { | | |||
1093 | kMyMoneyEdit* sharesEdit = dynamic_cast<kMyMoneyEdit*>(haveWidget("shares")); | | |||
1094 | kMyMoneyEdit* priceEdit = dynamic_cast<kMyMoneyEdit*>(haveWidget("price")); | | |||
1095 | MyMoneyMoney price; | | |||
1096 | if (!split.id().isEmpty()) | | |||
1097 | price = split.price().reduce(); | | |||
1098 | else | | |||
1099 | price = priceEdit->value().abs(); | | |||
1100 | | ||||
1101 | if (priceMode() == PricePerTransaction) { | | |||
1102 | priceEdit->setPrecision(m_currency.pricePrecision()); | | |||
1103 | label->setText(i18n("Transaction amount")); | | |||
1104 | if (!sharesEdit->value().isZero()) | | |||
1105 | priceEdit->setValue(sharesEdit->value().abs() * price); | | |||
1106 | | ||||
1107 | } else if (priceMode() == PricePerShare) { | | |||
1108 | priceEdit->setPrecision(m_security.pricePrecision()); | | |||
1109 | label->setText(i18n("Price/Share")); | | |||
1110 | priceEdit->setValue(price); | | |||
1111 | } else | | |||
1112 | priceEdit->setValue(price); | | |||
1113 | } | | |||
1114 | } | | |||
1115 | | ||||
1116 | void InvestTransactionEditor::setupFinalWidgets() | 1207 | void InvestTransactionEditor::setupFinalWidgets() | ||
1117 | { | 1208 | { | ||
1118 | addFinalWidget(haveWidget("memo")); | 1209 | addFinalWidget(haveWidget("memo")); | ||
Context not available. | |||||
1120 | 1211 | | |||
1121 | void InvestTransactionEditor::slotUpdateInvestMemoState() | 1212 | void InvestTransactionEditor::slotUpdateInvestMemoState() | ||
1122 | { | 1213 | { | ||
1123 | KTextEdit* memo = dynamic_cast<KTextEdit*>(m_editWidgets["memo"]); | 1214 | Q_D(InvestTransactionEditor); | ||
1215 | auto memo = dynamic_cast<KTextEdit*>(d->m_editWidgets["memo"]); | ||||
1124 | if (memo) { | 1216 | if (memo) { | ||
1125 | d->m_activity->m_memoChanged = (memo->toPlainText() != d->m_activity->m_memoText); | 1217 | d->m_activity->memoChanged() = (memo->toPlainText() != d->m_activity->memoText()); | ||
1126 | } | 1218 | } | ||
1127 | } | 1219 | } | ||
Context not available. |