diff --git a/kmymoney/dialogs/kavailablecurrencydlg.ui b/kmymoney/dialogs/kavailablecurrencydlg.ui
index ddba3fc9f..63048544e 100644
--- a/kmymoney/dialogs/kavailablecurrencydlg.ui
+++ b/kmymoney/dialogs/kavailablecurrencydlg.ui
@@ -1,102 +1,102 @@
KAvailableCurrencyDlg
0
0
400
516
Select currencies to add
true
-
1
1
QAbstractItemView::NoEditTriggers
QAbstractItemView::ExtendedSelection
false
true
Name
ID
- Symbol
+ Symbol
-
QDialogButtonBox::Cancel|QDialogButtonBox::Ok
buttonBox
accepted()
KAvailableCurrencyDlg
accept()
199
492
199
257
buttonBox
rejected()
KAvailableCurrencyDlg
reject()
199
492
199
257
diff --git a/kmymoney/dialogs/kcurrencyeditdlg.ui b/kmymoney/dialogs/kcurrencyeditdlg.ui
index 919c6b286..0e2a9428d 100644
--- a/kmymoney/dialogs/kcurrencyeditdlg.ui
+++ b/kmymoney/dialogs/kcurrencyeditdlg.ui
@@ -1,146 +1,146 @@
KCurrencyEditDlg
0
0
400
516
Currencies
true
-
1
1
Qt::CustomContextMenu
QAbstractItemView::ExtendedSelection
false
true
Name
ID
- Symbol
+ Symbol
-
-
Remove
..
-
Add
..
-
Edit
-
Remove unused currencies
..
-
Close
-
Select as base currency
m_currencyList
m_addCurrencyButton
m_removeCurrencyButton
m_editCurrencyButton
m_removeUnusedCurrencyButton
m_selectBaseCurrencyButton
m_closeButton
m_closeButton
clicked()
KCurrencyEditDlg
reject()
296
488
199
257
diff --git a/kmymoney/dialogs/kequitypriceupdatedlg.ui b/kmymoney/dialogs/kequitypriceupdatedlg.ui
index c07429a2f..e1d2aae1a 100644
--- a/kmymoney/dialogs/kequitypriceupdatedlg.ui
+++ b/kmymoney/dialogs/kequitypriceupdatedlg.ui
@@ -1,197 +1,197 @@
Kevin Tambascio <ktambascio@users.sourceforge.net>
KEquityPriceUpdateDlg
0
0
537
482
Update Stock and Currency Prices
-
350
0
List of known Equities, and the date they were last updated on.
QFrame::StyledPanel
QFrame::Plain
true
false
true
true
1
-
-
- From
+ From
-
-
- To
+ To
-
-
-
Configure
-
Qt::Horizontal
QSizePolicy::Expanding
21
20
-
Update All
-
Update Selected
-
Status:
false
-
true
-
-
QDialogButtonBox::Cancel|QDialogButtonBox::Ok
KTextEdit
QTextEdit
KMyMoneyDateInput
QWidget
1
buttonBox
accepted()
KEquityPriceUpdateDlg
accept()
268
458
268
240
buttonBox
rejected()
KEquityPriceUpdateDlg
reject()
268
458
268
240
diff --git a/kmymoney/dialogs/settings/ksettingsonlinequotes.cpp b/kmymoney/dialogs/settings/ksettingsonlinequotes.cpp
index 040db4aba..15a8d557b 100644
--- a/kmymoney/dialogs/settings/ksettingsonlinequotes.cpp
+++ b/kmymoney/dialogs/settings/ksettingsonlinequotes.cpp
@@ -1,377 +1,377 @@
/*
* Copyright 2005-2010 Thomas Baumgart
* Copyright 2017-2018 Łukasz Wojniłowicz
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
#include "ksettingsonlinequotes.h"
// ----------------------------------------------------------------------------
// QT Includes
#include
#include
// ----------------------------------------------------------------------------
// KDE Includes
#include
#include
#include
// ----------------------------------------------------------------------------
// Project Includes
#include "ui_ksettingsonlinequotes.h"
#include "kmymoney/converter/webpricequote.h"
#include "mymoneyfile.h"
#include "mymoneysecurity.h"
#include "icons/icons.h"
using namespace Icons;
class KSettingsOnlineQuotesPrivate
{
Q_DISABLE_COPY(KSettingsOnlineQuotesPrivate)
public:
KSettingsOnlineQuotesPrivate() :
ui(new Ui::KSettingsOnlineQuotes),
m_quoteInEditing(false)
{
}
~KSettingsOnlineQuotesPrivate()
{
delete ui;
}
Ui::KSettingsOnlineQuotes *ui;
QList m_resetList;
WebPriceQuoteSource m_currentItem;
bool m_quoteInEditing;
};
KSettingsOnlineQuotes::KSettingsOnlineQuotes(QWidget *parent) :
QWidget(parent),
d_ptr(new KSettingsOnlineQuotesPrivate)
{
Q_D(KSettingsOnlineQuotes);
d->ui->setupUi(this);
QStringList groups = WebPriceQuote::quoteSources();
loadList(true /*updateResetList*/);
d->ui->m_updateButton->setEnabled(false);
d->ui->m_updateButton->setIcon(Icons::get(Icon::DialogOK));
d->ui->m_deleteButton->setIcon(Icons::get(Icon::EditDelete));
d->ui->m_newButton->setIcon(Icons::get(Icon::DocumentNew));
- d->ui->m_editIdentifyBy->addItem(i18n("Symbol"), WebPriceQuoteSource::identifyBy::Symbol);
- d->ui->m_editIdentifyBy->addItem(i18n("Identification number"), WebPriceQuoteSource::identifyBy::IdentificationNumber);
- d->ui->m_editIdentifyBy->addItem(i18n("Name"), WebPriceQuoteSource::identifyBy::Name);
+ d->ui->m_editIdentifyBy->addItem(i18nc("@item:inlistbox Stock", "Symbol"), WebPriceQuoteSource::identifyBy::Symbol);
+ d->ui->m_editIdentifyBy->addItem(i18nc("@item:inlistbox Stock", "Identification number"), WebPriceQuoteSource::identifyBy::IdentificationNumber);
+ d->ui->m_editIdentifyBy->addItem(i18nc("@item:inlistbox Stock", "Name"), WebPriceQuoteSource::identifyBy::Name);
connect(d->ui->m_dumpCSVProfile, &QAbstractButton::clicked, this, &KSettingsOnlineQuotes::slotDumpCSVProfile);
connect(d->ui->m_updateButton, &QAbstractButton::clicked, this, &KSettingsOnlineQuotes::slotUpdateEntry);
connect(d->ui->m_newButton, &QAbstractButton::clicked, this, &KSettingsOnlineQuotes::slotNewEntry);
connect(d->ui->m_deleteButton, &QAbstractButton::clicked, this, &KSettingsOnlineQuotes::slotDeleteEntry);
connect(d->ui->m_quoteSourceList, &QListWidget::itemSelectionChanged, this, &KSettingsOnlineQuotes::slotLoadWidgets);
connect(d->ui->m_quoteSourceList, &QListWidget::itemChanged, this, &KSettingsOnlineQuotes::slotEntryRenamed);
connect(d->ui->m_quoteSourceList, &QListWidget::itemDoubleClicked, this, &KSettingsOnlineQuotes::slotStartRename);
connect(d->ui->m_editURL, &QLineEdit::textChanged, this, static_cast(&KSettingsOnlineQuotes::slotEntryChanged));
connect(d->ui->m_editCSVURL, &QLineEdit::textChanged, this, static_cast(&KSettingsOnlineQuotes::slotEntryChanged));
connect(d->ui->m_editIdentifier, &QLineEdit::textChanged, this, static_cast(&KSettingsOnlineQuotes::slotEntryChanged));
connect(d->ui->m_editIdentifyBy, static_cast(&QComboBox::currentIndexChanged), this, static_cast(&KSettingsOnlineQuotes::slotEntryChanged));
connect(d->ui->m_editDate, &QLineEdit::textChanged, this, static_cast(&KSettingsOnlineQuotes::slotEntryChanged));
connect(d->ui->m_editDateFormat, &QLineEdit::textChanged, this, static_cast(&KSettingsOnlineQuotes::slotEntryChanged));
connect(d->ui->m_editPrice, &QLineEdit::textChanged, this, static_cast(&KSettingsOnlineQuotes::slotEntryChanged));
connect(d->ui->m_skipStripping, &QAbstractButton::toggled, this, static_cast(&KSettingsOnlineQuotes::slotEntryChanged));
}
KSettingsOnlineQuotes::~KSettingsOnlineQuotes()
{
Q_D(KSettingsOnlineQuotes);
delete d;
}
void KSettingsOnlineQuotes::loadList(const bool updateResetList)
{
Q_D(KSettingsOnlineQuotes);
//disconnect the slot while items are being loaded and reconnect at the end
disconnect(d->ui->m_quoteSourceList, &QListWidget::itemChanged, this, &KSettingsOnlineQuotes::slotEntryRenamed);
d->m_quoteInEditing = false;
QStringList groups = WebPriceQuote::quoteSources();
if (updateResetList)
d->m_resetList.clear();
d->ui->m_quoteSourceList->clear();
QStringList::Iterator it;
for (it = groups.begin(); it != groups.end(); ++it) {
QListWidgetItem* item = new QListWidgetItem(*it);
item->setFlags(Qt::ItemIsEditable | Qt::ItemIsSelectable | Qt::ItemIsEnabled);
d->ui->m_quoteSourceList->addItem(item);
if (updateResetList)
d->m_resetList += WebPriceQuoteSource(*it);
}
d->ui->m_quoteSourceList->sortItems();
QListWidgetItem* first = d->ui->m_quoteSourceList->item(0);
if (first)
d->ui->m_quoteSourceList->setCurrentItem(first);
slotLoadWidgets();
d->ui->m_newButton->setEnabled((d->ui->m_quoteSourceList->findItems(i18n("New Quote Source"), Qt::MatchExactly)).count() == 0);
connect(d->ui->m_quoteSourceList, &QListWidget::itemChanged, this, &KSettingsOnlineQuotes::slotEntryRenamed);
}
void KSettingsOnlineQuotes::resetConfig()
{
Q_D(KSettingsOnlineQuotes);
QStringList::ConstIterator it;
QStringList groups = WebPriceQuote::quoteSources();
// delete all currently defined entries
for (it = groups.constBegin(); it != groups.constEnd(); ++it) {
WebPriceQuoteSource(*it).remove();
}
// and write back the one's from the reset list
QList::ConstIterator itr;
for (itr = d->m_resetList.constBegin(); itr != d->m_resetList.constEnd(); ++itr) {
(*itr).write();
}
loadList();
}
void KSettingsOnlineQuotes::slotLoadWidgets()
{
Q_D(KSettingsOnlineQuotes);
d->m_quoteInEditing = false;
QListWidgetItem* item = d->ui->m_quoteSourceList->currentItem();
d->ui->m_editURL->setEnabled(true);
d->ui->m_editCSVURL->setEnabled(true);
d->ui->m_editIdentifier->setEnabled(true);
d->ui->m_editIdentifyBy->setEnabled(true);
d->ui->m_editPrice->setEnabled(true);
d->ui->m_editDate->setEnabled(true);
d->ui->m_editDateFormat->setEnabled(true);
d->ui->m_skipStripping->setEnabled(true);
d->ui->m_dumpCSVProfile->setEnabled(true);
d->ui->m_deleteButton->setEnabled(true);
d->ui->m_editURL->setText(QString());
d->ui->m_editCSVURL->setText(QString());
d->ui->m_editIdentifier->setText(QString());
d->ui->m_editIdentifyBy->setCurrentIndex(WebPriceQuoteSource::identifyBy::Symbol);
d->ui->m_editPrice->setText(QString());
d->ui->m_editDate->setText(QString());
d->ui->m_editDateFormat->setText(QString());
if (item) {
d->m_currentItem = WebPriceQuoteSource(item->text());
d->ui->m_editURL->setText(d->m_currentItem.m_url);
d->ui->m_editCSVURL->setText(d->m_currentItem.m_csvUrl);
d->ui->m_editIdentifier->setText(d->m_currentItem.m_webID);
d->ui->m_editIdentifyBy->setCurrentIndex(d->m_currentItem.m_webIDBy);
d->ui->m_editPrice->setText(d->m_currentItem.m_price);
d->ui->m_editDate->setText(d->m_currentItem.m_date);
d->ui->m_editDateFormat->setText(d->m_currentItem.m_dateformat);
d->ui->m_skipStripping->setChecked(d->m_currentItem.m_skipStripping);
} else {
d->ui->m_editURL->setEnabled(false);
d->ui->m_editCSVURL->setEnabled(false);
d->ui->m_editIdentifier->setEnabled(false);
d->ui->m_editIdentifyBy->setEnabled(false);
d->ui->m_editPrice->setEnabled(false);
d->ui->m_editDate->setEnabled(false);
d->ui->m_editDateFormat->setEnabled(false);
d->ui->m_skipStripping->setEnabled(false);
d->ui->m_dumpCSVProfile->setEnabled(false);
d->ui->m_deleteButton->setEnabled(false);
}
d->ui->m_updateButton->setEnabled(false);
}
void KSettingsOnlineQuotes::slotEntryChanged()
{
Q_D(KSettingsOnlineQuotes);
bool modified = d->ui->m_editURL->text() != d->m_currentItem.m_url
|| d->ui->m_editCSVURL->text() != d->m_currentItem.m_csvUrl
|| d->ui->m_editIdentifier->text() != d->m_currentItem.m_webID
|| d->ui->m_editIdentifyBy->currentData().toInt() != static_cast(d->m_currentItem.m_webIDBy)
|| d->ui->m_editDate->text() != d->m_currentItem.m_date
|| d->ui->m_editDateFormat->text() != d->m_currentItem.m_dateformat
|| d->ui->m_editPrice->text() != d->m_currentItem.m_price
|| d->ui->m_skipStripping->isChecked() != d->m_currentItem.m_skipStripping;
d->ui->m_updateButton->setEnabled(modified);
}
void KSettingsOnlineQuotes::slotEntryChanged(int)
{
slotEntryChanged();
}
void KSettingsOnlineQuotes::slotEntryChanged(const QString&)
{
slotEntryChanged();
}
void KSettingsOnlineQuotes::slotEntryChanged(bool)
{
slotEntryChanged();
}
void KSettingsOnlineQuotes::slotDumpCSVProfile()
{
Q_D(KSettingsOnlineQuotes);
KSharedConfigPtr config = CSVImporterCore::configFile();
PricesProfile profile;
profile.m_profileName = d->m_currentItem.m_name;
profile.m_profileType = Profile::StockPrices;
bool profileExists = false;
bool writeProfile = true;
if (profile.readSettings(config))
profileExists = true;
else {
profile.m_profileType = Profile::CurrencyPrices;
if (profile.readSettings(config))
profileExists = true;
}
if (profileExists)
writeProfile = (KMessageBox::questionYesNoCancel(this,
i18n("CSV profile %1 already exists.
"
"Do you want to overwrite it?",
d->m_currentItem.m_name),
i18n("CSV Profile Already Exists")) == KMessageBox::Yes ? true : false);
if (writeProfile) {
QMap quoteSources = WebPriceQuote::defaultCSVQuoteSources();
profile = quoteSources.value(d->m_currentItem.m_name);
if (profile.m_profileName.compare(d->m_currentItem.m_name, Qt::CaseInsensitive) == 0) {
profile.writeSettings(config);
CSVImporterCore::profilesAction(profile.type(), ProfileAction::Add, profile.m_profileName, profile.m_profileName);
}
}
CSVImporterCore::profilesAction(profile.type(), ProfileAction::UpdateLastUsed, profile.m_profileName, profile.m_profileName);
}
void KSettingsOnlineQuotes::slotUpdateEntry()
{
Q_D(KSettingsOnlineQuotes);
d->m_currentItem.m_url = d->ui->m_editURL->text();
d->m_currentItem.m_csvUrl = d->ui->m_editCSVURL->text();
d->m_currentItem.m_webID = d->ui->m_editIdentifier->text();
d->m_currentItem.m_webIDBy = static_cast(d->ui->m_editIdentifyBy->currentData().toInt());
d->m_currentItem.m_date = d->ui->m_editDate->text();
d->m_currentItem.m_dateformat = d->ui->m_editDateFormat->text();
d->m_currentItem.m_price = d->ui->m_editPrice->text();
d->m_currentItem.m_skipStripping = d->ui->m_skipStripping->isChecked();
d->m_currentItem.write();
slotEntryChanged();
}
void KSettingsOnlineQuotes::slotNewEntry()
{
Q_D(KSettingsOnlineQuotes);
WebPriceQuoteSource newSource(i18n("New Quote Source"));
newSource.write();
loadList();
QListWidgetItem* item = d->ui->m_quoteSourceList->findItems(i18n("New Quote Source"), Qt::MatchExactly).at(0);
if (item) {
d->ui->m_quoteSourceList->setCurrentItem(item);
slotLoadWidgets();
}
}
void KSettingsOnlineQuotes::slotDeleteEntry()
{
Q_D(KSettingsOnlineQuotes);
// first check if no security is using this online source
auto securities = MyMoneyFile::instance()->securityList();
foreach(const auto security, securities) {
if (security.value(QStringLiteral("kmm-online-source")).compare(d->m_currentItem.m_name) == 0) {
if (KMessageBox::questionYesNo(this,
i18n("Security %1 uses this quote source.
"
"Do you really want to remove it?", security.name()),
i18n("Delete quote source")) == KMessageBox::Yes)
break; // webpricequote can handle missing online quotes, so proceed without any extra action
else
return;
}
}
// remove online source from webpricequote...
d->m_currentItem.remove();
// ...and from setting's list
auto row = d->ui->m_quoteSourceList->currentRow();
QListWidgetItem *item = d->ui->m_quoteSourceList->takeItem(row);
if (item)
delete item;
item = nullptr;
int count = d->ui->m_quoteSourceList->count();
if (row < count) // select next available entry...
item = d->ui->m_quoteSourceList->item(row);
else if (row >= count && count > 0) // ...or last entry if this was the last entry...
item = d->ui->m_quoteSourceList->item(count - 1);
if (item) {
d->ui->m_quoteSourceList->setCurrentItem(item);
slotLoadWidgets();
}
}
void KSettingsOnlineQuotes::slotStartRename(QListWidgetItem* item)
{
Q_D(KSettingsOnlineQuotes);
d->m_quoteInEditing = true;
d->ui->m_quoteSourceList->editItem(item);
}
void KSettingsOnlineQuotes::slotEntryRenamed(QListWidgetItem* item)
{
Q_D(KSettingsOnlineQuotes);
//if there is no current item selected, exit
if (d->m_quoteInEditing == false || !d->ui->m_quoteSourceList->currentItem() || item != d->ui->m_quoteSourceList->currentItem())
return;
d->m_quoteInEditing = false;
QString text = item->text();
int nameCount = 0;
for (auto i = 0; i < d->ui->m_quoteSourceList->count(); ++i) {
if (d->ui->m_quoteSourceList->item(i)->text() == text)
++nameCount;
}
// Make sure we get a non-empty and unique name
if (text.length() > 0 && nameCount == 1) {
d->m_currentItem.rename(text);
} else {
item->setText(d->m_currentItem.m_name);
}
d->ui->m_quoteSourceList->sortItems();
d->ui->m_newButton->setEnabled(d->ui->m_quoteSourceList->findItems(i18n("New Quote Source"), Qt::MatchExactly).count() == 0);
}
diff --git a/kmymoney/models/equitiesmodel.cpp b/kmymoney/models/equitiesmodel.cpp
index 0bd0b0646..e82b96668 100644
--- a/kmymoney/models/equitiesmodel.cpp
+++ b/kmymoney/models/equitiesmodel.cpp
@@ -1,489 +1,489 @@
/*
* Copyright 2017-2018 Łukasz Wojniłowicz
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
#include "equitiesmodel.h"
// ----------------------------------------------------------------------------
// QT Includes
#include
#include
// ----------------------------------------------------------------------------
// KDE Includes
#include
// ----------------------------------------------------------------------------
// Project Includes
#include "mymoneymoney.h"
#include "mymoneyfile.h"
#include "mymoneyaccount.h"
#include "mymoneysecurity.h"
#include "mymoneyprice.h"
#include "mymoneyenums.h"
class EquitiesModel::Private
{
public:
Private() : m_file(MyMoneyFile::instance())
{
QVector columns {Column::Equity, Column::Symbol, Column::Value,
Column::Quantity, Column::Price};
foreach (auto const column, columns)
m_columns.append(column);
}
~Private() {}
void loadInvestmentAccount(QStandardItem *node, const MyMoneyAccount &invAcc)
{
auto itInvAcc = new QStandardItem(invAcc.name());
node->appendRow(itInvAcc); // investment account is meant to be added under root item
itInvAcc->setEditable(false);
itInvAcc->setColumnCount(m_columns.count());
setAccountData(node, itInvAcc->row(), invAcc, m_columns);
foreach (const auto strStkAcc, invAcc.accountList()) { // only stock or bond accounts are expected here
auto stkAcc = m_file->account(strStkAcc);
auto itStkAcc = new QStandardItem(strStkAcc);
itStkAcc->setEditable(false);
itInvAcc->appendRow(itStkAcc);
setAccountData(itInvAcc, itStkAcc->row(), stkAcc, m_columns);
}
}
void setAccountData(QStandardItem *node, const int row, const MyMoneyAccount &account, const QList &columns)
{
QStandardItem *cell;
auto getCell = [&, row](const auto column) {
cell = node->child(row, column); // try to get QStandardItem
if (!cell) { // it may be uninitialized
cell = new QStandardItem; // so create one
node->setChild(row, column, cell); // and add it under the node
cell->setEditable(false); // and don't forget that it's non-editable
}
};
auto colNum = m_columns.indexOf(Column::Equity);
if (colNum == -1)
return;
// Equity
getCell(colNum);
if (columns.contains(Column::Equity)) {
cell->setData(account.name(), Qt::DisplayRole);
cell->setData(account.id(), Role::EquityID);
cell->setData(account.currencyId(), Role::SecurityID);
}
if (account.accountType() == eMyMoney::Account::Type::Investment) // investments accounts are not meant to be displayed, so stop here
return;
// Display the name of the equity with strikeout font in case it is closed
auto font = cell->data(Qt::FontRole).value();
if (account.isClosed() != font.strikeOut()) {
font.setStrikeOut(account.isClosed());
cell->setData(font, Qt::FontRole);
}
// Symbol
if (columns.contains(Column::Symbol)) {
colNum = m_columns.indexOf(Column::Symbol);
if (colNum != -1) {
auto security = m_file->security(account.currencyId());
getCell(colNum);
cell->setData(security.tradingSymbol(), Qt::DisplayRole);
}
}
setAccountBalanceAndValue(node, row, account, columns);
}
void setAccountBalanceAndValue(QStandardItem *node, const int row, const MyMoneyAccount &account, const QList &columns)
{
QStandardItem *cell;
auto getCell = [&, row](const auto column) {
cell = node->child(row, column); // try to get QStandardItem
if (!cell) { // it may be uninitialized
cell = new QStandardItem; // so create one
node->setChild(row, column, cell); // and add it under the node
cell->setEditable(false); // and don't forget that it's non-editable
}
};
auto colNum = m_columns.indexOf(Column::Equity);
if (colNum == -1)
return;
auto balance = m_file->balance(account.id());
auto security = m_file->security(account.currencyId());
auto tradingCurrency = m_file->security(security.tradingCurrency());
auto price = m_file->price(account.currencyId(), tradingCurrency.id());
// Value
if (columns.contains(Column::Value)) {
colNum = m_columns.indexOf(Column::Value);
if (colNum != -1) {
getCell(colNum);
if (price.isValid()) {
auto prec = MyMoneyMoney::denomToPrec(tradingCurrency.smallestAccountFraction());
auto value = balance * price.rate(tradingCurrency.id());
auto strValue = QVariant(value.formatMoney(tradingCurrency.tradingSymbol(), prec));
cell->setData(strValue, Qt::DisplayRole);
} else {
cell->setData(QVariant("---"), Qt::DisplayRole);
}
cell->setData(QVariant(Qt::AlignRight | Qt::AlignVCenter), Qt::TextAlignmentRole);
}
}
// Quantity
if (columns.contains(Column::Quantity)) {
colNum = m_columns.indexOf(Column::Quantity);
if (colNum != -1) {
getCell(colNum);
auto prec = MyMoneyMoney::denomToPrec(security.smallestAccountFraction());
auto strQuantity = QVariant(balance.formatMoney(QString(), prec));
cell->setData(strQuantity, Qt::DisplayRole);
cell->setData(QVariant(Qt::AlignRight | Qt::AlignVCenter), Qt::TextAlignmentRole);
}
}
// Price
if (columns.contains(Column::Price)) {
colNum = m_columns.indexOf(Column::Price);
if (colNum != -1) {
getCell(colNum);
if (price.isValid()) {
auto prec = security.pricePrecision();
auto strPrice = QVariant(price.rate(tradingCurrency.id()).formatMoney(tradingCurrency.tradingSymbol(), prec));
cell->setData(strPrice, Qt::DisplayRole);
} else {
cell->setData(QVariant("---"), Qt::DisplayRole);
}
cell->setData(QVariant(Qt::AlignRight | Qt::AlignVCenter), Qt::TextAlignmentRole);
}
}
}
QStandardItem *itemFromId(QStandardItemModel *model, const QString &id, const Role role)
{
const auto itemList = model->match(model->index(0, 0), role, QVariant(id), 1, Qt::MatchFlags(Qt::MatchExactly | Qt::MatchCaseSensitive | Qt::MatchRecursive));
if (!itemList.isEmpty())
return model->itemFromIndex(itemList.first());
return nullptr;
}
MyMoneyFile *m_file;
QList m_columns;
};
EquitiesModel::EquitiesModel(QObject *parent)
: QStandardItemModel(parent), d(new Private)
{
init();
}
EquitiesModel::~EquitiesModel()
{
delete d;
}
void EquitiesModel::init()
{
QStringList headerLabels;
foreach (const auto column, d->m_columns)
headerLabels.append(getHeaderName(column));
setHorizontalHeaderLabels(headerLabels);
}
void EquitiesModel::load()
{
this->blockSignals(true);
auto rootItem = invisibleRootItem();
QList accList;
d->m_file->accountList(accList); // get all available accounts
foreach (const auto acc, accList)
if (acc.accountType() == eMyMoney::Account::Type::Investment) // but add only investment accounts (and its children) to the model
d->loadInvestmentAccount(rootItem, acc);
this->blockSignals(false);
}
/**
* Notify the model that an object has been added. An action is performed only if the object is an account.
*/
void EquitiesModel::slotObjectAdded(eMyMoney::File::Object objType, const QString& id)
{
// check whether change is about accounts
if (objType != eMyMoney::File::Object::Account)
return;
// check whether change is about either investment or stock account
const auto acc = MyMoneyFile::instance()->account(id);
if (acc.accountType() != eMyMoney::Account::Type::Investment &&
acc.accountType() != eMyMoney::Account::Type::Stock)
return;
auto itAcc = d->itemFromId(this, id, Role::EquityID);
QStandardItem *itParentAcc;
if (acc.accountType() == eMyMoney::Account::Type::Investment) // if it's investment account then its parent is root item
itParentAcc = invisibleRootItem();
else // otherwise it's stock account and its parent is investment account
itParentAcc = d->itemFromId(this, acc.parentAccountId(), Role::InvestmentID);
// if account doesn't exist in model then add it
if (!itAcc) {
itAcc = new QStandardItem(acc.name());
itParentAcc->appendRow(itAcc);
itAcc->setEditable(false);
}
d->setAccountData(itParentAcc, itAcc->row(), acc, d->m_columns);
}
/**
* Notify the model that an object has been modified. An action is performed only if the object is an account.
*/
void EquitiesModel::slotObjectModified(eMyMoney::File::Object objType, const QString& id)
{
MyMoneyAccount acc;
QStandardItem *itAcc;
switch (objType) {
case eMyMoney::File::Object::Account:
{
auto tmpAcc = MyMoneyFile::instance()->account(id);
if (tmpAcc.accountType() != eMyMoney::Account::Type::Stock)
return;
acc = MyMoneyAccount(tmpAcc);
itAcc = d->itemFromId(this, acc.id(), Role::EquityID);
break;
}
case eMyMoney::File::Object::Security:
{
auto sec = MyMoneyFile::instance()->security(id);
// in case we hit a currency, we simply bail out here
// as there is nothing to do for us
if(sec.isCurrency())
return;
itAcc = d->itemFromId(this, sec.id(), Role::SecurityID);
if (!itAcc)
return;
const auto idAcc = itAcc->data(Role::EquityID).toString();
acc = d->m_file->account(idAcc);
break;
}
default:
return;
}
auto itParentAcc = d->itemFromId(this, acc.parentAccountId(), Role::InvestmentID);
// in case something went wrong, we bail out
if(itParentAcc == nullptr) {
qWarning() << "EquitiesModel::slotObjectModified: itParentAcc == 0";
return;
}
auto modelID = itParentAcc->data(Role::InvestmentID).toString(); // get parent account from model
if (modelID == acc.parentAccountId()) { // and if it matches with those from file then modify only
d->setAccountData(itParentAcc, itAcc->row(), acc, d->m_columns);
} else { // and if not then reparent
slotObjectRemoved(eMyMoney::File::Object::Account, acc.id());
slotObjectAdded(eMyMoney::File::Object::Account, id);
}
}
/**
* Notify the model that an object has been removed. An action is performed only if the object is an account.
*
*/
void EquitiesModel::slotObjectRemoved(eMyMoney::File::Object objType, const QString& id)
{
if (objType != eMyMoney::File::Object::Account)
return;
const auto indexList = match(index(0, 0), Role::EquityID, id, -1, Qt::MatchFlags(Qt::MatchExactly | Qt::MatchRecursive));
foreach (const auto index, indexList)
removeRow(index.row(), index.parent());
}
/**
* Notify the model that the account balance has been changed.
*/
void EquitiesModel::slotBalanceOrValueChanged(const MyMoneyAccount &account)
{
if (account.accountType() != eMyMoney::Account::Type::Stock)
return;
const auto itAcc = d->itemFromId(this, account.id(), Role::EquityID);
if (!itAcc)
return;
d->setAccountBalanceAndValue(itAcc->parent(), itAcc->row(), account, d->m_columns);
}
auto EquitiesModel::getColumns()
{
return &d->m_columns;
}
QString EquitiesModel::getHeaderName(const Column column)
{
switch(column) {
case Equity:
return i18n("Equity");
case Symbol:
- return i18n("Symbol");
+ return i18nc("@title stock symbol column", "Symbol");
case Value:
return i18n("Value");
case Quantity:
return i18n("Quantity");
case Price:
return i18n("Price");
default:
return QString();
}
}
class EquitiesFilterProxyModel::Private
{
public:
Private() :
m_mdlColumns(nullptr),
m_file(MyMoneyFile::instance()),
m_hideClosedAccounts(false),
m_hideZeroBalanceAccounts(false)
{}
~Private() {}
QList *m_mdlColumns;
QList m_visColumns;
MyMoneyFile *m_file;
bool m_hideClosedAccounts;
bool m_hideZeroBalanceAccounts;
};
EquitiesFilterProxyModel::EquitiesFilterProxyModel(QObject *parent, EquitiesModel *model, const QList &columns)
: KRecursiveFilterProxyModel(parent), d(new Private)
{
setDynamicSortFilter(true);
setFilterKeyColumn(-1);
setSortLocaleAware(true);
setFilterCaseSensitivity(Qt::CaseInsensitive);
setSourceModel(model);
d->m_mdlColumns = model->getColumns();
d->m_visColumns.append(columns);
}
EquitiesFilterProxyModel::~EquitiesFilterProxyModel()
{
delete d;
}
/**
* Set if closed accounts should be hidden or not.
* @param hideClosedAccounts
*/
void EquitiesFilterProxyModel::setHideClosedAccounts(const bool hideClosedAccounts)
{
d->m_hideClosedAccounts = hideClosedAccounts;
}
/**
* Set if zero balance accounts should be hidden or not.
* @param hideZeroBalanceAccounts
*/
void EquitiesFilterProxyModel::setHideZeroBalanceAccounts(const bool hideZeroBalanceAccounts)
{
d->m_hideZeroBalanceAccounts = hideZeroBalanceAccounts;
}
bool EquitiesFilterProxyModel::filterAcceptsColumn(int source_column, const QModelIndex &source_parent) const
{
Q_UNUSED(source_parent)
if (d->m_visColumns.isEmpty() || d->m_visColumns.contains(d->m_mdlColumns->at(source_column)))
return true;
return false;
}
bool EquitiesFilterProxyModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const
{
if (d->m_hideClosedAccounts || d->m_hideZeroBalanceAccounts) {
const auto ixRow = sourceModel()->index(source_row, EquitiesModel::Equity, source_parent);
const auto idAcc = sourceModel()->data(ixRow, EquitiesModel::EquityID).toString();
const auto acc = d->m_file->account(idAcc);
if (d->m_hideClosedAccounts &&
acc.isClosed())
return false;
if (d->m_hideZeroBalanceAccounts &&
acc.accountType() != eMyMoney::Account::Type::Investment && acc.balance().isZero()) // we should never hide investment account because all underlaying stocks will be hidden as well
return false;
}
return true;
}
QList &EquitiesFilterProxyModel::getVisibleColumns()
{
return d->m_visColumns;
}
void EquitiesFilterProxyModel::slotColumnsMenu(const QPoint)
{
// construct all hideable columns list
const QList idColumns {
EquitiesModel::Symbol, EquitiesModel::Value,
EquitiesModel::Quantity, EquitiesModel::Price
};
// create menu
QMenu menu(i18n("Displayed columns"));
QList actions;
foreach (const auto idColumn, idColumns) {
auto a = new QAction(nullptr);
a->setObjectName(QString::number(idColumn));
a->setText(EquitiesModel::getHeaderName(idColumn));
a->setCheckable(true);
a->setChecked(d->m_visColumns.contains(idColumn));
actions.append(a);
}
menu.addActions(actions);
// execute menu and get result
const auto retAction = menu.exec(QCursor::pos());
if (retAction) {
const auto idColumn = static_cast(retAction->objectName().toInt());
const auto isChecked = retAction->isChecked();
const auto contains = d->m_visColumns.contains(idColumn);
if (isChecked && !contains) { // column has just been enabled
d->m_visColumns.append(idColumn); // change filtering variable
emit columnToggled(idColumn, true); // emit signal for method to add column to model
invalidate(); // refresh model to reflect recent changes
} else if (!isChecked && contains) { // column has just been disabled
d->m_visColumns.removeOne(idColumn);
emit columnToggled(idColumn, false);
invalidate();
}
}
}
diff --git a/kmymoney/models/securitiesmodel.cpp b/kmymoney/models/securitiesmodel.cpp
index 097cca6fd..ed9c3a318 100644
--- a/kmymoney/models/securitiesmodel.cpp
+++ b/kmymoney/models/securitiesmodel.cpp
@@ -1,373 +1,373 @@
/*
* Copyright 2017-2018 Łukasz Wojniłowicz
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
#include "securitiesmodel.h"
// ----------------------------------------------------------------------------
// QT Includes
#include
// ----------------------------------------------------------------------------
// KDE Includes
#include
// ----------------------------------------------------------------------------
// Project Includes
#include "mymoneyfile.h"
#include "mymoneysecurity.h"
#include "mymoneyenums.h"
class SecuritiesModel::Private
{
public:
Private() :
m_file(MyMoneyFile::instance()),
m_ndCurrencies(nullptr),
m_ndSecurities(nullptr)
{
QVector columns {
Column::Security, Column::Symbol, Column::Type,
Column::Market, Column::Currency, Column::Fraction
};
foreach (auto const column, columns)
m_columns.append(column);
}
~Private() {}
void loadSecurity(QStandardItem *node, const MyMoneySecurity &sec)
{
auto itSec = new QStandardItem(sec.name());
node->appendRow(itSec);
itSec->setEditable(false);
setSecurityData(node, itSec->row(), sec, m_columns);
}
void setSecurityData(QStandardItem *node, const int row, const MyMoneySecurity &security, const QList &columns)
{
QStandardItem *cell;
auto getCell = [&, row](const auto column) {
cell = node->child(row, column); // try to get QStandardItem
if (!cell) { // it may be uninitialized
cell = new QStandardItem; // so create one
node->setChild(row, column, cell); // and add it under the node
cell->setEditable(false); // and don't forget that it's non-editable
}
};
auto colNum = m_columns.indexOf(Column::Security);
if (colNum == -1)
return;
// Security
getCell(colNum);
if (columns.contains(Column::Security)) {
cell->setData(security.name(), Qt::DisplayRole);
cell->setData(security.id(), Qt::UserRole);
}
// Symbol
if (columns.contains(Column::Symbol)) {
colNum = m_columns.indexOf(Column::Symbol);
if (colNum != -1) {
getCell(colNum);
cell->setData(security.tradingSymbol(), Qt::DisplayRole);
}
}
// Type
if (columns.contains(Column::Type)) {
colNum = m_columns.indexOf(Column::Type);
if (colNum != -1) {
getCell(colNum);
cell->setData(security.securityTypeToString(security.securityType()), Qt::DisplayRole);
}
}
// Market
if (columns.contains(Column::Market)) {
colNum = m_columns.indexOf(Column::Market);
if (colNum != -1) {
getCell(colNum);
QString market;
if (security.isCurrency())
market = QLatin1String("ISO 4217");
else
market = security.tradingMarket();
cell->setData(market, Qt::DisplayRole);
}
}
// Currency
if (columns.contains(Column::Currency)) {
colNum = m_columns.indexOf(Column::Currency);
if (colNum != -1) {
getCell(colNum);
MyMoneySecurity tradingCurrency;
if (!security.isCurrency())
tradingCurrency = m_file->security(security.tradingCurrency());
cell->setData(tradingCurrency.tradingSymbol(), Qt::DisplayRole);
}
}
// Fraction
if (columns.contains(Column::Fraction)) {
colNum = m_columns.indexOf(Column::Fraction);
if (colNum != -1) {
getCell(colNum);
cell->setData(QString::number(security.smallestAccountFraction()), Qt::DisplayRole);
}
}
}
QStandardItem *itemFromSecurityId(QStandardItemModel *model, const QString &securityId)
{
const auto itemList = model->match(model->index(0, 0), Qt::UserRole, QVariant(securityId), 1, Qt::MatchFlags(Qt::MatchExactly | Qt::MatchCaseSensitive | Qt::MatchRecursive));
if (!itemList.isEmpty())
return model->itemFromIndex(itemList.first());
return nullptr;
}
MyMoneyFile *m_file;
QList m_columns;
QStandardItem *m_ndCurrencies;
QStandardItem *m_ndSecurities;
};
SecuritiesModel::SecuritiesModel(QObject *parent)
: QStandardItemModel(parent), d(new Private)
{
init();
}
SecuritiesModel::~SecuritiesModel()
{
delete d;
}
void SecuritiesModel::init()
{
QStringList headerLabels;
foreach (const auto column, d->m_columns)
headerLabels.append(getHeaderName(column));
setHorizontalHeaderLabels(headerLabels);
}
void SecuritiesModel::load()
{
this->blockSignals(true);
auto rootItem = invisibleRootItem();
auto secList = d->m_file->securityList(); // get all available securities
d->m_ndSecurities = new QStandardItem(QStringLiteral("Securities"));
d->m_ndSecurities->setEditable(false);
rootItem->appendRow(d->m_ndSecurities);
foreach (const auto sec, secList)
d->loadSecurity(d->m_ndSecurities, sec);
secList = d->m_file->currencyList(); // get all available currencies
d->m_ndCurrencies = new QStandardItem(QStringLiteral("Currencies"));
d->m_ndCurrencies->setEditable(false);
rootItem->appendRow(d->m_ndCurrencies);
foreach (const auto sec, secList)
d->loadSecurity(d->m_ndCurrencies, sec);
this->blockSignals(false);
}
/**
* Notify the model that an object has been added. An action is performed only if the object is a security.
*
*/
void SecuritiesModel::slotObjectAdded(eMyMoney::File::Object objType, const QString& id)
{
// check whether change is about security
if (objType != eMyMoney::File::Object::Security)
return;
// check that we're about to add security
auto sec = MyMoneyFile::instance()->security(id);
auto itSec = d->itemFromSecurityId(this, id);
QStandardItem *node;
if (sec.isCurrency())
node = d->m_ndCurrencies;
else
node = d->m_ndSecurities;
// if security doesn't exist in model then add it
if (!itSec) {
itSec = new QStandardItem(sec.name());
node->appendRow(itSec);
itSec->setEditable(false);
}
d->setSecurityData(node, itSec->row(), sec, d->m_columns);
}
/**
* Notify the model that an object has been modified. An action is performed only if the object is a security.
*
*/
void SecuritiesModel::slotObjectModified(eMyMoney::File::Object objType, const QString& id)
{
if (objType != eMyMoney::File::Object::Security)
return;
// check that we're about to modify security
auto sec = MyMoneyFile::instance()->security(id);
auto itSec = d->itemFromSecurityId(this, id);
QStandardItem *node;
if (sec.isCurrency())
node = d->m_ndCurrencies;
else
node = d->m_ndSecurities;
d->setSecurityData(node, itSec->row(), sec, d->m_columns);
}
/**
* Notify the model that an object has been removed. An action is performed only if the object is an account.
*
*/
void SecuritiesModel::slotObjectRemoved(eMyMoney::File::Object objType, const QString& id)
{
if (objType != eMyMoney::File::Object::Security)
return;
const auto indexList = match(index(0, 0), Qt::UserRole, id, -1, Qt::MatchFlags(Qt::MatchExactly | Qt::MatchRecursive));
foreach (const auto index, indexList)
removeRow(index.row(), index.parent());
}
auto SecuritiesModel::getColumns()
{
return &d->m_columns;
}
QString SecuritiesModel::getHeaderName(const Column column)
{
switch(column) {
case Security:
return i18n("Security");
case Symbol:
- return i18n("Symbol");
+ return i18nc("@title stock symbol column", "Symbol");
case Type:
return i18n("Type");
case Market:
return i18n("Market");
case Currency:
return i18n("Currency");
case Fraction:
return i18n("Fraction");
default:
return QString();
}
}
class SecuritiesFilterProxyModel::Private
{
public:
Private() :
m_mdlColumns(nullptr),
m_file(MyMoneyFile::instance())
{}
~Private() {}
QList *m_mdlColumns;
QList m_visColumns;
MyMoneyFile *m_file;
};
SecuritiesFilterProxyModel::SecuritiesFilterProxyModel(QObject *parent, SecuritiesModel *model, const QList &columns)
: KRecursiveFilterProxyModel(parent), d(new Private)
{
setDynamicSortFilter(true);
setFilterKeyColumn(-1);
setSortLocaleAware(true);
setFilterCaseSensitivity(Qt::CaseInsensitive);
setSourceModel(model);
d->m_mdlColumns = model->getColumns();
d->m_visColumns.append(columns);
}
SecuritiesFilterProxyModel::~SecuritiesFilterProxyModel()
{
delete d;
}
bool SecuritiesFilterProxyModel::filterAcceptsColumn(int source_column, const QModelIndex &source_parent) const
{
Q_UNUSED(source_parent)
if (d->m_visColumns.isEmpty() || d->m_visColumns.contains(d->m_mdlColumns->at(source_column)))
return true;
return false;
}
QList &SecuritiesFilterProxyModel::getVisibleColumns()
{
return d->m_visColumns;
}
void SecuritiesFilterProxyModel::slotColumnsMenu(const QPoint)
{
// construct all hideable columns list
const QList idColumns {
SecuritiesModel::Symbol, SecuritiesModel::Type,
SecuritiesModel::Market, SecuritiesModel::Currency,
SecuritiesModel::Fraction
};
// create menu
QMenu menu(i18n("Displayed columns"));
QList actions;
foreach (const auto idColumn, idColumns) {
auto a = new QAction(nullptr);
a->setObjectName(QString::number(idColumn));
a->setText(SecuritiesModel::getHeaderName(idColumn));
a->setCheckable(true);
a->setChecked(d->m_visColumns.contains(idColumn));
actions.append(a);
}
menu.addActions(actions);
// execute menu and get result
const auto retAction = menu.exec(QCursor::pos());
if (retAction) {
const auto idColumn = static_cast(retAction->objectName().toInt());
const auto isChecked = retAction->isChecked();
const auto contains = d->m_visColumns.contains(idColumn);
if (isChecked && !contains) { // column has just been enabled
d->m_visColumns.append(idColumn); // change filtering variable
emit columnToggled(idColumn, true); // emit signal for method to add column to model
invalidate(); // refresh model to reflect recent changes
} else if (!isChecked && contains) { // column has just been disabled
d->m_visColumns.removeOne(idColumn);
emit columnToggled(idColumn, false);
invalidate();
}
}
}
diff --git a/kmymoney/plugins/csv/import/investmentwizardpage.cpp b/kmymoney/plugins/csv/import/investmentwizardpage.cpp
index 537284f82..b0ef37cfe 100644
--- a/kmymoney/plugins/csv/import/investmentwizardpage.cpp
+++ b/kmymoney/plugins/csv/import/investmentwizardpage.cpp
@@ -1,665 +1,665 @@
/*
* Copyright 2010-2017 Allan Anderson
* Copyright 2016-2018 Łukasz Wojniłowicz
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
#include "investmentwizardpage.h"
// ----------------------------------------------------------------------------
// QT Includes
#include
#include
#include
#include
// ----------------------------------------------------------------------------
// KDE Includes
#include
// ----------------------------------------------------------------------------
// Project Includes
#include "mymoneyfile.h"
#include "mymoneysecurity.h"
#include "csvwizard.h"
#include "core/csvimportercore.h"
#include "transactiondlg.h"
#include "securitydlg.h"
#include "securitiesdlg.h"
#include "ui_investmentwizardpage.h"
#include "ui_securitiesdlg.h"
#include "ui_securitydlg.h"
// ----------------------------------------------------------------------------
InvestmentPage::InvestmentPage(CSVWizard *dlg, CSVImporterCore *imp) :
CSVWizardPage(dlg, imp),
ui(new Ui::InvestmentPage)
{
ui->setupUi(this);
connect(ui->m_clear, &QAbstractButton::clicked, this, &InvestmentPage::clearColumns);
connect(ui->m_clearFee, &QAbstractButton::clicked, this, &InvestmentPage::clearFee);
connect(ui->m_calculateFee, &QAbstractButton::clicked, this, &InvestmentPage::calculateFee);
// initialize column names
m_dlg->m_colTypeName.insert(Column::Type, i18n("Type"));
m_dlg->m_colTypeName.insert(Column::Price, i18n("Price"));
m_dlg->m_colTypeName.insert(Column::Quantity, i18n("Quantity"));
m_dlg->m_colTypeName.insert(Column::Fee, i18n("Fee"));
m_dlg->m_colTypeName.insert(Column::Date, i18n("Date"));
m_dlg->m_colTypeName.insert(Column::Amount, i18n("Amount"));
- m_dlg->m_colTypeName.insert(Column::Symbol, i18n("Symbol"));
+ m_dlg->m_colTypeName.insert(Column::Symbol, i18nc("@title stock symbol column", "Symbol"));
m_dlg->m_colTypeName.insert(Column::Name, i18n("Name"));
m_dlg->m_colTypeName.insert(Column::Memo, i18n("Memo"));
m_profile = dynamic_cast(m_imp->m_profile);
connect(ui->m_memoCol, SIGNAL(currentIndexChanged(int)), this, SLOT(memoColSelected(int)));
connect(ui->m_typeCol, SIGNAL(currentIndexChanged(int)), this, SLOT(typeColSelected(int)));
connect(ui->m_dateCol, SIGNAL(currentIndexChanged(int)), this, SLOT(dateColSelected(int)));
connect(ui->m_quantityCol, SIGNAL(currentIndexChanged(int)), this, SLOT(quantityColSelected(int)));
connect(ui->m_priceCol, SIGNAL(currentIndexChanged(int)), this, SLOT(priceColSelected(int)));
connect(ui->m_priceFraction, SIGNAL(currentIndexChanged(int)), this, SLOT(fractionChanged(int)));
connect(ui->m_amountCol, SIGNAL(currentIndexChanged(int)), this, SLOT(amountColSelected(int)));
connect(ui->m_feeCol, SIGNAL(currentIndexChanged(int)), this, SLOT(feeColSelected(int)));
connect(ui->m_symbolCol, SIGNAL(currentIndexChanged(int)), this, SLOT(symbolColSelected(int)));
connect(ui->m_nameCol, SIGNAL(currentIndexChanged(int)), this, SLOT(nameColSelected(int)));
connect(ui->m_feeIsPercentage, &QAbstractButton::clicked, this, &InvestmentPage::feeIsPercentageClicked);
connect(ui->m_feeRate, &QLineEdit::editingFinished, this, &InvestmentPage::feeInputsChanged);
connect(ui->m_feeRate, &QLineEdit::textChanged, this, &InvestmentPage::feeRateChanged);
connect(ui->m_minFee, &QLineEdit::textChanged, this, &InvestmentPage::minFeeChanged);
}
InvestmentPage::~InvestmentPage()
{
delete m_securitiesDlg;
delete ui;
}
void InvestmentPage::calculateFee()
{
m_imp->calculateFee();
m_dlg->updateWindowSize();
m_dlg->markUnwantedRows();
}
void InvestmentPage::initializePage()
{
QHash columns {{Column::Amount, ui->m_amountCol}, {Column::Type, ui->m_typeCol},
{Column::Quantity, ui->m_quantityCol}, {Column::Memo, ui->m_memoCol},
{Column::Price, ui->m_priceCol}, {Column::Date, ui->m_dateCol},
{Column::Fee, ui->m_feeCol}, {Column::Symbol, ui->m_symbolCol},
{Column::Name, ui->m_nameCol}};
if (ui->m_dateCol->count() != m_imp->m_file->m_columnCount)
m_dlg->initializeComboBoxes(columns);
ui->m_feeIsPercentage->setChecked(m_profile->m_feeIsPercentage);
columns.remove(Column::Memo);
for (auto it = columns.cbegin(); it != columns.cend(); ++it)
it.value()->setCurrentIndex(m_profile->m_colTypeNum.value(it.key()));
ui->m_priceFraction->blockSignals(true);
foreach (const auto priceFraction, m_imp->m_priceFractions)
ui->m_priceFraction->addItem(QString::number(priceFraction.toDouble(), 'g', 3));
ui->m_priceFraction->blockSignals(false);
ui->m_priceFraction->setCurrentIndex(m_profile->m_priceFraction);
ui->m_feeRate->setText(m_profile->m_feeRate);
ui->m_minFee->setText(m_profile->m_minFee);
ui->m_feeRate->setValidator(new QRegularExpressionValidator(QRegularExpression(QStringLiteral("[0-9]{1,2}[") + QLocale().decimalPoint() + QStringLiteral("]{1,1}[0-9]{0,2}")), this) );
ui->m_minFee->setValidator(new QRegularExpressionValidator(QRegularExpression(QStringLiteral("[0-9]{1,}[") + QLocale().decimalPoint() + QStringLiteral("]{0,1}[0-9]{0,}")), this) );
if (!m_profile->m_feeRate.isEmpty()) { // fee rate indicates that fee column needs to be calculated
if (m_imp->calculateFee()) {
ui->m_feeCol->blockSignals(true);
int feeCol = ui->m_feeCol->count();
ui->m_feeCol->addItem(QString::number(feeCol + 1));
ui->m_feeCol->setEnabled(false);
ui->m_feeCol->setCurrentIndex(feeCol);
ui->m_feeCol->blockSignals(false);
m_dlg->updateWindowSize();
m_dlg->markUnwantedRows();
}
} else if (m_profile->m_colTypeNum.value(Column::Fee, -1) >= ui->m_feeCol->count()) { // no fee rate, calculated fee column index exist, but the column doesn't exist and that's not ok
m_profile->m_colTypeNum[Column::Fee] = -1;
m_profile->m_colNumType.remove(m_profile->m_colNumType.key(Column::Fee));
}
for (int i = 0; i < m_profile->m_memoColList.count(); ++i) { // Set up all memo fields...
int tmp = m_profile->m_memoColList.at(i);
if (tmp < m_profile->m_colTypeNum.count())
ui->m_memoCol->setCurrentIndex(tmp);
}
feeInputsChanged();
}
bool InvestmentPage::isComplete() const
{
return ui->m_dateCol->currentIndex() > -1 &&
ui->m_typeCol->currentIndex() > -1 &&
ui->m_quantityCol->currentIndex() > -1 &&
ui->m_priceCol->currentIndex() > -1 &&
ui->m_amountCol->currentIndex() > -1 &&
ui->m_priceFraction->currentIndex() > -1;
}
bool InvestmentPage::validatePage()
{
if (ui->m_symbolCol->currentIndex() == -1 &&
ui->m_nameCol->currentIndex() == -1)
return validateSecurity();
else
return validateSecurities();
}
void InvestmentPage::cleanupPage()
{
clearFeeCol();
}
void InvestmentPage::memoColSelected(int col)
{
if (m_profile->m_colNumType.value(col) == Column::Type ||
m_profile->m_colNumType.value(col) == Column::Name) {
int rc = KMessageBox::Yes;
if (isVisible())
rc = KMessageBox::questionYesNo(m_dlg, i18n("The '%1' field already has this column selected."
"If you wish to copy that data to the memo field, click 'Yes'.",
m_dlg->m_colTypeName.value(m_profile->m_colNumType.value(col))));
if (rc == KMessageBox::Yes) {
ui->m_memoCol->setItemText(col, QString::number(col + 1) + QChar(QLatin1Char('*')));
if (!m_profile->m_memoColList.contains(col))
m_profile->m_memoColList.append(col);
} else {
ui->m_memoCol->setItemText(col, QString::number(col + 1));
m_profile->m_memoColList.removeOne(col);
}
//allow only separate memo field occupy combobox
ui->m_memoCol->blockSignals(true);
if (m_profile->m_colTypeNum.value(Column::Memo) != -1)
ui->m_memoCol->setCurrentIndex(m_profile->m_colTypeNum.value(Column::Memo));
else
ui->m_memoCol->setCurrentIndex(-1);
ui->m_memoCol->blockSignals(false);
return;
}
if (m_profile->m_colTypeNum.value(Column::Memo) != -1) // check if this memo has any column 'number' assigned...
m_profile->m_memoColList.removeOne(col); // ...if true remove it from memo list
if(validateSelectedColumn(col, Column::Memo))
if (col != - 1 && !m_profile->m_memoColList.contains(col))
m_profile->m_memoColList.append(col);
}
void InvestmentPage::dateColSelected(int col)
{
validateSelectedColumn(col, Column::Date);
}
void InvestmentPage::feeColSelected(int col)
{
validateSelectedColumn(col, Column::Fee);
feeInputsChanged();
}
void InvestmentPage::typeColSelected(int col)
{
if (validateSelectedColumn(col, Column::Type))
if (!validateMemoComboBox()) // user could have it already in memo so...
memoColSelected(col); // ...if true set memo field again
}
void InvestmentPage::quantityColSelected(int col)
{
validateSelectedColumn(col, Column::Quantity);
}
void InvestmentPage::priceColSelected(int col)
{
validateSelectedColumn(col, Column::Price);
}
void InvestmentPage::amountColSelected(int col)
{
validateSelectedColumn(col, Column::Amount);
clearFeeCol();
feeInputsChanged();
}
void InvestmentPage::symbolColSelected(int col)
{
validateSelectedColumn(col, Column::Symbol);
m_imp->m_mapSymbolName.clear(); // new symbol column so this map is no longer valid
}
void InvestmentPage::nameColSelected(int col)
{
if (validateSelectedColumn(col, Column::Name))
if (!validateMemoComboBox()) // user could have it already in memo so...
memoColSelected(col); // ...if true set memo field again
m_imp->m_mapSymbolName.clear(); // new name column so this map is no longer valid
}
void InvestmentPage::feeIsPercentageClicked(bool checked)
{
m_profile->m_feeIsPercentage = checked;
}
void InvestmentPage::fractionChanged(int col)
{
m_profile->m_priceFraction = col;
emit completeChanged();
}
void InvestmentPage::clearColumns()
{
ui->m_amountCol->setCurrentIndex(-1);
ui->m_dateCol->setCurrentIndex(-1);
ui->m_priceCol->setCurrentIndex(-1);
ui->m_quantityCol->setCurrentIndex(-1);
ui->m_memoCol->setCurrentIndex(-1);
ui->m_typeCol->setCurrentIndex(-1);
ui->m_nameCol->setCurrentIndex(-1);
ui->m_symbolCol->setCurrentIndex(-1);
ui->m_priceFraction->setCurrentIndex(-1);
clearFee();
}
void InvestmentPage::clearFee()
{
clearFeeCol();
ui->m_feeCol->setCurrentIndex(-1);
ui->m_feeIsPercentage->setChecked(false);
ui->m_calculateFee->setEnabled(false);
ui->m_feeRate->setEnabled(true);
ui->m_minFee->setEnabled(false);
ui->m_feeRate->clear();
ui->m_minFee->clear();
}
void InvestmentPage::feeInputsChanged()
{
// if (ui->comboBoxInv_feeCol->currentIndex() < m_importer->m_file->m_columnCount &&
// ui->comboBoxInv_feeCol->currentIndex() > -1) {
// ui->lineEdit_minFee->setEnabled(false);
// ui->lineEdit_feeRate->setEnabled(false);
// ui->lineEdit_minFee->clear();
// ui->lineEdit_feeRate->clear();
// }
if (m_profile->m_feeRate.isEmpty()) {
ui->m_feeCol->setEnabled(true);
ui->m_feeIsPercentage->setEnabled(true);
ui->m_minFee->setEnabled(false);
ui->m_calculateFee->setEnabled(false);
} else {
ui->m_feeCol->setEnabled(false);
ui->m_feeIsPercentage->setEnabled(false);
ui->m_feeIsPercentage->setChecked(true);
ui->m_minFee->setEnabled(true);
ui->m_feeRate->setEnabled(true);
if (m_profile->m_colTypeNum.value(Column::Amount) != -1)
ui->m_calculateFee->setEnabled(true);
}
}
void InvestmentPage::feeRateChanged(const QString &text)
{
m_profile->m_feeRate = text;
}
void InvestmentPage::minFeeChanged(const QString &text)
{
m_profile->m_minFee = text;
}
void InvestmentPage::clearFeeCol()
{
if (!m_profile->m_feeRate.isEmpty() && // if fee rate isn't empty...
m_profile->m_colTypeNum.value(Column::Fee) >= m_imp->m_file->m_columnCount - 1 &&
!ui->m_feeCol->isEnabled()) { // ...and fee column is last...
--m_imp->m_file->m_columnCount;
m_imp->m_file->m_model->removeColumn(m_imp->m_file->m_columnCount);
int feeCol = ui->m_feeCol->currentIndex();
ui->m_feeCol->setCurrentIndex(-1);
ui->m_feeCol->removeItem(feeCol);
m_dlg->updateWindowSize();
}
ui->m_feeCol->setEnabled(true);
ui->m_feeIsPercentage->setEnabled(true);
ui->m_feeIsPercentage->setChecked(false);
}
void InvestmentPage::resetComboBox(const Column comboBox)
{
switch (comboBox) {
case Column::Amount:
ui->m_amountCol->setCurrentIndex(-1);
break;
case Column::Date:
ui->m_dateCol->setCurrentIndex(-1);
break;
case Column::Fee:
ui->m_feeCol->setCurrentIndex(-1);
break;
case Column::Memo:
ui->m_memoCol->setCurrentIndex(-1);
break;
case Column::Price:
ui->m_priceCol->setCurrentIndex(-1);
break;
case Column::Quantity:
ui->m_quantityCol->setCurrentIndex(-1);
break;
case Column::Type:
ui->m_typeCol->setCurrentIndex(-1);
break;
case Column::Symbol:
ui->m_symbolCol->setCurrentIndex(-1);
break;
case Column::Name:
ui->m_nameCol->setCurrentIndex(-1);
break;
default:
KMessageBox::sorry(m_dlg, i18n("Field name not recognised.'%1'Please re-enter your column selections.", (int)comboBox), i18n("CSV import"));
}
}
bool InvestmentPage::validateActionType()
{
for (int row = m_profile->m_startLine; row <= m_profile->m_endLine; ++row) {
MyMoneyStatement::Transaction tr;
// process quantity field
int col = m_profile->m_colTypeNum.value(Column::Quantity);
tr.m_shares = m_imp->processQuantityField(m_profile, row, col);
// process price field
col = m_profile->m_colTypeNum.value(Column::Price);
tr.m_price = m_imp->processPriceField(m_profile, row, col);
// process amount field
col = m_profile->m_colTypeNum.value(Column::Amount);
tr.m_amount = m_imp->processAmountField(m_profile, row, col);
// process type field
col = m_profile->m_colTypeNum.value(Column::Type);
tr.m_eAction = m_imp->processActionTypeField(m_profile, row, col);
switch(m_imp->validateActionType(tr)) {
case InvalidActionValues:
KMessageBox::sorry(m_dlg,
i18n("The values in the columns you have selected\ndo not match any expected investment type.\n"
"Please check the fields in the current transaction,\nand also your selections."),
i18n("CSV import"));
return false;
break;
case NoActionType:
{
bool unknownType = false;
if (tr.m_eAction == eMyMoney::Transaction::Action::None)
unknownType = true;
QStringList colList;
QStringList colHeaders;
for (col = 0; col < m_imp->m_file->m_columnCount; ++col) {
colHeaders.append(m_dlg->m_colTypeName.value(m_profile->m_colNumType.value(col, Column::Invalid), QString(i18nc("Unused column", "Unused"))));
colList.append(m_imp->m_file->m_model->item(row, col)->text());
}
QList validActionTypes = m_imp->createValidActionTypes(tr);
QPointer transactionDlg = new TransactionDlg(colList, colHeaders, m_profile->m_colTypeNum.value(Column::Type), validActionTypes);
if (transactionDlg->exec() == QDialog::Rejected) {
KMessageBox::information(m_dlg,
i18n("No valid action type found for this transaction."
"Please check the parameters supplied."),
i18n("CSV import"));
return false;
} else
tr.m_eAction = transactionDlg->getActionType();
delete transactionDlg;
if (unknownType) { // type was unknown so store it
col = m_profile->m_colTypeNum.value(Column::Type);
m_profile->m_transactionNames[tr.m_eAction].append(m_imp->m_file->m_model->item(row, col)->text()); // store action type
}
}
default:
break;
}
}
m_imp->m_isActionTypeValidated = true;
return true;
}
bool InvestmentPage::validateSelectedColumn(const int col, const Column type)
{
if (m_profile->m_colTypeNum.value(type) != -1) // check if this 'type' has any column 'number' assigned...
m_profile->m_colNumType.remove(m_profile->m_colTypeNum.value(type)); // ...if true remove 'type' assigned to this column 'number'
bool ret = true;
if (col == -1) { // user only wanted to reset his column so allow him
m_profile->m_colTypeNum[type] = col; // assign new column 'number' to this 'type'
} else if (m_profile->m_colNumType.contains(col)) { // if this column 'number' has already 'type' assigned
KMessageBox::information(m_dlg, i18n("The '%1' field already has this column selected. Please reselect both entries as necessary.",
m_dlg->m_colTypeName.value(m_profile->m_colNumType.value(col))));
resetComboBox(m_profile->m_colNumType[col]);
resetComboBox(type);
ret = false;
} else {
m_profile->m_colTypeNum[type] = col; // assign new column 'number' to this 'type'
m_profile->m_colNumType[col] = type; // assign new 'type' to this column 'number'
}
emit completeChanged();
return ret;
}
bool InvestmentPage::validateMemoComboBox()
{
if (m_profile->m_memoColList.count() == 0)
return true;
for (int i = 0; i < ui->m_memoCol->count(); ++i)
{
QString txt = ui->m_memoCol->itemText(i);
if (txt.contains(QLatin1Char('*'))) // check if text containing '*' belongs to valid column types
if (m_profile->m_colNumType.value(i) != Column::Name &&
m_profile->m_colNumType.value(i) != Column::Type) {
ui->m_memoCol->setItemText(i, QString::number(i + 1));
m_profile->m_memoColList.removeOne(i);
return false;
}
}
return true;
}
bool InvestmentPage::validateSecurities()
{
if (m_securitiesDlg.isNull() &&
m_imp->m_mapSymbolName.isEmpty()) {
QSet onlySymbols;
QSet onlyNames;
m_imp->sortSecurities(onlySymbols, onlyNames, m_imp->m_mapSymbolName);
if (!onlySymbols.isEmpty() || !onlyNames.isEmpty()) {
m_securitiesDlg = new SecuritiesDlg;
for (QSet::const_iterator symbol = onlySymbols.cbegin(); symbol != onlySymbols.cend(); ++symbol)
m_securitiesDlg->displayLine(*symbol, QString());
for (QSet::const_iterator name = onlyNames.cbegin(); name != onlyNames.cend(); ++name)
m_securitiesDlg->displayLine(QString(), *name);
}
}
if (!m_securitiesDlg.isNull()) {
QTableWidget* symbolTable = m_securitiesDlg->ui->tableWidget;
if (m_securitiesDlg->exec() == QDialog::Rejected) {
return false;
} else {
for (int row = 0; row < symbolTable->rowCount(); ++row) {
QString symbol = symbolTable->item(row, 1)->text();
QString name = symbolTable->item(row, 2)->text();
m_imp->m_mapSymbolName.insert(symbol, name);
}
delete m_securitiesDlg;
}
}
return true;
}
bool InvestmentPage::validateSecurity()
{
if (!m_profile->m_securitySymbol.isEmpty() &&
!m_profile->m_securityName.isEmpty())
m_imp->m_mapSymbolName.insert(m_profile->m_securitySymbol, m_profile->m_securityName);
MyMoneyFile* file = MyMoneyFile::instance();
if (m_securityDlg.isNull() &&
(m_imp->m_mapSymbolName.isEmpty() ||
!(m_profile->m_dontAsk && m_dlg->m_skipSetup))) {
m_securityDlg = new SecurityDlg;
m_securityDlg->initializeSecurities(m_profile->m_securitySymbol, m_profile->m_securityName);
m_securityDlg->ui->cbDontAsk->setChecked(m_profile->m_dontAsk);
}
if (!m_securityDlg.isNull()) {
if (m_securityDlg->exec() == QDialog::Rejected) {
return false;
} else {
QString securityID = m_securityDlg->security();
if (!securityID.isEmpty()) {
m_profile->m_securityName = file->security(securityID).name();
m_profile->m_securitySymbol = file->security(securityID).tradingSymbol();
} else {
m_profile->m_securityName = m_securityDlg->name();
m_profile->m_securitySymbol = m_securityDlg->symbol();
}
m_profile->m_dontAsk = m_securityDlg->dontAsk();
m_imp->m_mapSymbolName.clear();
m_imp->m_mapSymbolName.insert(m_profile->m_securitySymbol, m_profile->m_securityName); // probably we should check if security with given symbol and name exists...
delete m_securityDlg; // ...but KMM allows creating duplicates, so don't bother
}
}
if (m_imp->m_mapSymbolName.isEmpty())
return false;
return true;
}
void InvestmentPage::makeQIF(const MyMoneyStatement& st, const QString& outFileName)
{
QFile oFile(outFileName);
oFile.open(QIODevice::WriteOnly);
QTextStream out(&oFile);
QString buffer;
QString strEType;
switch (st.m_eType) {
case eMyMoney::Statement::Type::Investment:
default:
strEType = QStringLiteral("Invst");
}
if (!st.m_strAccountName.isEmpty()) {
buffer.append(QStringLiteral("!Account\n"));
buffer.append(QChar(QLatin1Char('N')) + st.m_strAccountName + QChar(QLatin1Char('\n')));
buffer.append(QChar(QLatin1Char('T')) + strEType + QChar(QLatin1Char('\n')));
buffer.append(QStringLiteral("^\n"));
}
for (QList::const_iterator it = st.m_listSecurities.constBegin(); it != st.m_listSecurities.constEnd(); ++it) {
buffer.append(QStringLiteral("!Type:Security\n"));
buffer.append(QChar(QLatin1Char('N')) + (*it).m_strName + QChar(QLatin1Char('\n')));
buffer.append(QChar(QLatin1Char('S')) + (*it).m_strSymbol + QChar(QLatin1Char('\n')));
buffer.append(QStringLiteral("TStock\n^\n"));
}
if (!st.m_strAccountName.isEmpty()) {
buffer.append(QStringLiteral("!Account\n"));
buffer.append(QChar(QLatin1Char('N')) + st.m_strAccountName + QChar(QLatin1Char('\n')));
buffer.append(QChar(QLatin1Char('T')) + strEType + QChar(QLatin1Char('\n')));
buffer.append(QStringLiteral("^\n"));
}
buffer.append(QStringLiteral("!Type:") + strEType + QChar(QLatin1Char('\n')));
for (QList::const_iterator it = st.m_listTransactions.constBegin(); it != st.m_listTransactions.constEnd(); ++it) {
buffer.append(QChar(QLatin1Char('D')) + it->m_datePosted.toString(QStringLiteral("MM/dd/yyyy")) + QChar(QLatin1Char('\n')));
buffer.append(QChar(QLatin1Char('Y')) + it->m_strSecurity + QChar(QLatin1Char('\n')));
QString txt;
switch (it->m_eAction) {
case eMyMoney::Transaction::Action::Buy:
txt = QStringLiteral("Buy");
break;
case eMyMoney::Transaction::Action::Sell:
txt = QStringLiteral("Sell");
break;
case eMyMoney::Transaction::Action::ReinvestDividend:
txt = QStringLiteral("ReinvDiv");
break;
case eMyMoney::Transaction::Action::CashDividend:
txt = QStringLiteral("Div");
break;
case eMyMoney::Transaction::Action::Interest:
txt = QStringLiteral("IntInc");
break;
case eMyMoney::Transaction::Action::Shrsin:
txt = QStringLiteral("ShrsIn");
break;
case eMyMoney::Transaction::Action::Shrsout:
txt = QStringLiteral("ShrsOut");
break;
case eMyMoney::Transaction::Action::Stksplit:
txt = QStringLiteral("stksplit");
break;
default:
txt = QStringLiteral("unknown"); // shouldn't happen
}
buffer.append(QChar(QLatin1Char('N')) + txt + QChar(QLatin1Char('\n')));
if (it->m_eAction == eMyMoney::Transaction::Action::Buy) // we added 'N' field so buy transaction should have any sign
txt.setNum(it->m_amount.abs().toDouble(), 'f', 4);
else
txt.setNum(it->m_amount.toDouble(), 'f', 4);
buffer.append(QChar(QLatin1Char('T')) + txt + QChar(QLatin1Char('\n')));
txt.setNum(it->m_shares.toDouble(), 'f', 4);
buffer.append(QChar(QLatin1Char('Q')) + txt + QChar(QLatin1Char('\n')));
txt.setNum(it->m_price.toDouble(), 'f', 4);
buffer.append(QChar(QLatin1Char('I')) + txt + QChar(QLatin1Char('\n')));
if (!it->m_fees.isZero()) {
txt.setNum(it->m_fees.toDouble(), 'f', 4);
buffer.append(QChar(QLatin1Char('O')) + txt + QChar(QLatin1Char('\n')));
}
if (!it->m_strBrokerageAccount.isEmpty())
buffer.append(QChar(QLatin1Char('L')) + it->m_strBrokerageAccount + QChar(QLatin1Char('\n')));
if (!it->m_strMemo.isEmpty())
buffer.append(QChar(QLatin1Char('M')) + it->m_strMemo + QChar(QLatin1Char('\n')));
buffer.append(QStringLiteral("^\n"));
out << buffer;// output qif file
buffer.clear();
}
oFile.close();
}
diff --git a/kmymoney/plugins/csv/import/investmentwizardpage.ui b/kmymoney/plugins/csv/import/investmentwizardpage.ui
index 4f2edca46..b52b3b1dc 100644
--- a/kmymoney/plugins/csv/import/investmentwizardpage.ui
+++ b/kmymoney/plugins/csv/import/investmentwizardpage.ui
@@ -1,564 +1,564 @@
InvestmentPage
0
0
846
284
0
0
Investment Wizard Page
-
Qt::Horizontal
40
20
-
-
0
0
50
false
Please select the appropriate columns to use, corresponding to your data.
If there is just a single security in the file, enter its name below.
Otherwise, select the column for the symbol, and for the description or name.
Qt::AlignCenter
true
-
-
0
0
Qt::Horizontal
-
Memo
Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
-
true
Quantity
Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
-
0
0
Select column containing amount field.
12
-
0
0
If necessary, select a fraction/multiplier for compatibility
between imported and stored prices. For instance, if the
import price is in cents but the file is priced in dollars, select 0.01.
5
-
Select column containing date field
Date
Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
-
true
16777215
16777215
Price
Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
-
0
0
Select column containing date field.
12
-
true
Amount
Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
-
0
0
Select column containing quantity field.
12
-
0
0
Select column containing price field.
12
-
0
0
If more than one stock is present in the file,
and if the stock symbols are shown in one of the columns,
select it here.
-
0
0
Clear selected column entries.
Clear
-
0
0
Qt::Horizontal
-
16777215
16777215
Price Fraction
Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
-
- Symbol
+ Symbol
Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
-
0
0
If a descriptive column also contains an activity type, select it here.
See also Filter text field.
-
Name
Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
-
Fee is Percentage
Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
-
Qt::LeftToRight
Fee Column
Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
-
0
0
Check box if any fee is a percentage figure rather than a value.
Qt::RightToLeft
-
0
0
Select column containing investment type field.
12
-
0
0
If necessary, select column containing fee.
Caution. This might already have been
incorporated into the price.
12
-
0
0
-
Fee rate
Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
-
0
0
-
Type/Action
Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
-
0
0
Select column containing memo field.
More than one column may be entered successively.
May also be selected to contain a copy of the type or name column.
12
-
Minimal Fee
Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
-
0
0
Qt::Horizontal
-
0
0
Clear Fee
-
0
0
Calculate Fee
-
Qt::Horizontal
40
20
m_dateCol
m_typeCol
m_memoCol
m_priceCol
m_quantityCol
m_amountCol
m_priceFraction
m_symbolCol
m_nameCol
m_feeCol
m_feeIsPercentage
m_feeRate
m_minFee
m_calculateFee
m_clear
m_clearFee
diff --git a/kmymoney/plugins/csv/import/securitiesdlg.ui b/kmymoney/plugins/csv/import/securitiesdlg.ui
index 0800a75d9..ea7fbc785 100644
--- a/kmymoney/plugins/csv/import/securitiesdlg.ui
+++ b/kmymoney/plugins/csv/import/securitiesdlg.ui
@@ -1,158 +1,158 @@
SecuritiesDlg
0
0
606
306
Securities
-
75
true
Missing names and symbols
Qt::AlignCenter
-
The following securities' names and symbols are not known to KMyMoney.
Please complete every missing name or symbol.
Qt::AlignCenter
true
-
QAbstractItemView::NoSelection
false
3
true
true
false
Status
- Symbol
+ Symbol
Name
-
0
0
QDialogButtonBox::Cancel|QDialogButtonBox::Ok
true
buttonBox
accepted()
SecuritiesDlg
accept()
302
280
302
152
buttonBox
rejected()
SecuritiesDlg
reject()
302
280
302
152
2
2
true
true
true
diff --git a/kmymoney/widgets/kmymoneycashflowcombo.cpp b/kmymoney/widgets/kmymoneycashflowcombo.cpp
index cbb7ba5ee..bb4ce69d3 100644
--- a/kmymoney/widgets/kmymoneycashflowcombo.cpp
+++ b/kmymoney/widgets/kmymoneycashflowcombo.cpp
@@ -1,106 +1,106 @@
/*
* Copyright 2009-2010 Cristian Oneț
* Copyright 2009-2010 Alvaro Soliverez
* Copyright 2011-2017 Thomas Baumgart
* Copyright 2017 Łukasz Wojniłowicz
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
#include "kmymoneycashflowcombo.h"
#include "kmymoneymvccombo_p.h"
// ----------------------------------------------------------------------------
// QT Includes
// ----------------------------------------------------------------------------
// KDE Includes
#include
// ----------------------------------------------------------------------------
// Project Includes
#include "mymoneyenums.h"
#include "widgetenums.h"
using namespace eWidgets;
using namespace eMyMoney;
class KMyMoneyCashFlowComboPrivate : public KMyMoneyMVCComboPrivate
{
Q_DISABLE_COPY(KMyMoneyCashFlowComboPrivate)
public:
KMyMoneyCashFlowComboPrivate() :
m_dir(eRegister::CashFlowDirection::Unknown)
{
}
eRegister::CashFlowDirection m_dir;
};
KMyMoneyCashFlowCombo::KMyMoneyCashFlowCombo(Account::Type accountType, QWidget* parent) :
KMyMoneyMVCCombo(*new KMyMoneyCashFlowComboPrivate, false, parent)
{
addItem(" ", QVariant((int)eRegister::CashFlowDirection::Unknown));
if (accountType == Account::Type::Income || accountType == Account::Type::Expense) {
// this is used for income/expense accounts to just show the reverse sense
addItem(i18nc("Activity for income categories", "Received"), QVariant((int)eRegister::CashFlowDirection::Payment));
addItem(i18nc("Activity for expense categories", "Paid"), QVariant((int)eRegister::CashFlowDirection::Deposit));
} else {
- addItem(i18n("Pay to"), QVariant((int)eRegister::CashFlowDirection::Payment));
- addItem(i18n("From"), QVariant((int)eRegister::CashFlowDirection::Deposit));
+ addItem(i18nc("Payee", "Pay to"), QVariant((int)eRegister::CashFlowDirection::Payment));
+ addItem(i18nc("Payer", "From"), QVariant((int)eRegister::CashFlowDirection::Deposit));
}
connect(this, &KMyMoneyMVCCombo::itemSelected, this, &KMyMoneyCashFlowCombo::slotSetDirection);
}
KMyMoneyCashFlowCombo::~KMyMoneyCashFlowCombo()
{
}
void KMyMoneyCashFlowCombo::setDirection(eRegister::CashFlowDirection dir)
{
Q_D(KMyMoneyCashFlowCombo);
d->m_dir = dir;
QString num;
setSelectedItem(num.setNum((int)dir));
}
eRegister::CashFlowDirection KMyMoneyCashFlowCombo::direction() const
{
Q_D(const KMyMoneyCashFlowCombo);
return d->m_dir;
}
void KMyMoneyCashFlowCombo::slotSetDirection(const QString& id)
{
Q_D(KMyMoneyCashFlowCombo);
QString num;
for (int i = (int)eRegister::CashFlowDirection::Deposit; i <= (int)eRegister::CashFlowDirection::Unknown; ++i) {
num.setNum(i);
if (num == id) {
d->m_dir = static_cast(i);
break;
}
}
emit directionSelected(d->m_dir);
update();
}
void KMyMoneyCashFlowCombo::removeDontCare()
{
removeItem(findData(QVariant((int)eRegister::CashFlowDirection::Unknown), Qt::UserRole, Qt::MatchExactly));
}
diff --git a/kmymoney/widgets/transaction_p.h b/kmymoney/widgets/transaction_p.h
index af3f671de..759c8aa7c 100644
--- a/kmymoney/widgets/transaction_p.h
+++ b/kmymoney/widgets/transaction_p.h
@@ -1,135 +1,135 @@
/*
* Copyright 2006-2018 Thomas Baumgart
* Copyright 2017-2018 Łukasz Wojniłowicz
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
#ifndef TRANSACTION_P_H
#define TRANSACTION_P_H
#include "registeritem_p.h"
// ----------------------------------------------------------------------------
// QT Includes
#include
#include
// ----------------------------------------------------------------------------
// KDE Includes
#include
// ----------------------------------------------------------------------------
// Project Includes
#include "register.h"
#include "mymoneyaccount.h"
#include "mymoneyfile.h"
#include "mymoneymoney.h"
#include "mymoneypayee.h"
#include "mymoneysplit.h"
#include "mymoneytag.h"
#include "mymoneytransaction.h"
namespace KMyMoneyRegister
{
class TransactionPrivate : public RegisterItemPrivate
{
public:
TransactionPrivate() :
m_form(nullptr),
m_formRowHeight(-1),
m_selected(false),
m_focus(false),
m_erroneous(false),
m_inEdit(false),
m_inRegisterEdit(false),
m_showBalance(true),
m_reducedIntensity(false)
{
}
virtual ~ TransactionPrivate()
{
}
void init(int uniqueId)
{
auto file = MyMoneyFile::instance();
// load the account
if (!m_split.accountId().isEmpty())
m_account = file->account(m_split.accountId());
// load the payee
if (!m_split.payeeId().isEmpty()) {
m_payee = file->payee(m_split.payeeId()).name();
}
if (m_parent->account().isIncomeExpense()) {
- m_payeeHeader = m_split.shares().isNegative() ? i18n("From") : i18n("Pay to");
+ m_payeeHeader = m_split.shares().isNegative() ? i18nc("Payer", "From") : i18nc("Payee", "Pay to");
} else {
- m_payeeHeader = m_split.shares().isNegative() ? i18n("Pay to") : i18n("From");
+ m_payeeHeader = m_split.shares().isNegative() ? i18nc("Payee", "Pay to") : i18nc("Payer", "From");
}
// load the tag
if (!m_split.tagIdList().isEmpty()) {
const QList t = m_split.tagIdList();
for (auto i = 0; i < t.count(); i++) {
m_tagList << file->tag(t[i]).name();
m_tagColorList << file->tag(t[i]).tagColor();
}
}
// load the currency
if (!m_transaction.id().isEmpty())
m_splitCurrencyId = m_account.currencyId();
// check if transaction is erroneous or not
m_erroneous = !m_transaction.splitSum().isZero();
if (!m_uniqueId.isEmpty()) {
m_uniqueId += '-';
QString id;
id.setNum(uniqueId);
m_uniqueId += id.rightJustified(3, '0');
}
}
MyMoneyTransaction m_transaction;
MyMoneySplit m_split;
MyMoneyAccount m_account;
MyMoneyMoney m_balance;
QTableWidget* m_form;
QString m_category;
QString m_payee;
QString m_payeeHeader;
QList m_tagList;
QList m_tagColorList;
QString m_categoryHeader;
QString m_splitCurrencyId;
QString m_uniqueId;
int m_formRowHeight;
bool m_selected;
bool m_focus;
bool m_erroneous;
bool m_inEdit;
bool m_inRegisterEdit;
bool m_showBalance;
bool m_reducedIntensity;
};
}
#endif