diff --git a/CMakeLists.txt b/CMakeLists.txt index 275c66045..c769fd195 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,399 +1,403 @@ # The CMake version we require cmake_minimum_required(VERSION 3.1) # Setting the name of the main project project(KMyMoney VERSION "5.0.80" LANGUAGES CXX) # Determine the GIT reference (if we're based on GIT) if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/.git") execute_process(COMMAND git rev-parse --short HEAD WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" OUTPUT_VARIABLE VERSION_SUFFIX OUTPUT_STRIP_TRAILING_WHITESPACE) set(VERSION_SUFFIX "-${VERSION_SUFFIX}") # Add variables which are similar to the build in names of cmake set(PROJECT_VERSION_SUFFIX "${VERSION_SUFFIX}") set(${PROJECT_NAME}_VERSION_SUFFIX "${VERSION_SUFFIX}") endif() # Automoc all sources set(CMAKE_AUTOMOC TRUE) list(APPEND CMAKE_AUTOMOC_MACRO_NAMES "K_PLUGIN_FACTORY" "K_PLUGIN_FACTORY_WITH_JSON") if (POLICY CMP0063) cmake_policy(SET CMP0063 NEW) # Policy introduced in CMake version 3.3 endif() if (POLICY CMP0071) # We do not require the old behaviour. It is only set to old, to prevent accidential use of # the new behavour. If the new behaviour becomes important, cmake_minimum_required has to be # set to "3.10". cmake_policy(SET CMP0071 OLD) # Policy introduced in CMake version 3.10 endif() ######################### General Requirements ########################## if (CMAKE_COMPILER_IS_GNUCXX AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 6.0.0) message(FATAL_ERROR "This version of KMyMoney requires at least gcc 6.0.0 to be built successfully") endif() find_package(ECM 5.10 REQUIRED NO_MODULE) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${ECM_MODULE_PATH} ${ECM_KDE_MODULE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules) include(KDEInstallDirs) include(KDECMakeSettings) include(FeatureSummary) include(CMakeDependentOption) include(GenerateExportHeader) include(KMyMoneyMacros) find_package(PkgConfig) set (OPT_KF5_COMPONENTS DocTools Holidays Contacts Akonadi IdentityManagement Activities) find_package(Gpgmepp) if (Gpgmepp_FOUND) set(GPG_FOUND TRUE) else() set(GPG_FOUND FALSE) list(APPEND OPT_KF5_COMPONENTS Gpgmepp) endif() if (PkgConfig_FOUND) pkg_check_modules(SQLCIPHER sqlcipher) endif() find_package(Qt5 5.6 REQUIRED COMPONENTS Core DBus Widgets Svg Xml Test PrintSupport OPTIONAL_COMPONENTS Sql Concurrent QuickWidgets) find_package(KF5 5.2 REQUIRED COMPONENTS Archive CoreAddons Config ConfigWidgets I18n Completion KCMUtils ItemModels ItemViews Service Wallet IconThemes XmlGui TextWidgets Notifications KIO OPTIONAL_COMPONENTS ${OPT_KF5_COMPONENTS} ) if(LibAlkimia5_DIR) set(_LibAlkimia5_DIR ${LibAlkimia5_DIR}) endif() find_package(LibAlkimia5 8.0) if (NOT LibAlkimia5_FOUND) # restore LibAlkimia5_DIR set to NOTFOUND by first find_package call if(_LibAlkimia5_DIR) set(LibAlkimia5_DIR ${_LibAlkimia5_DIR}) endif() find_package(LibAlkimia5 7.0 REQUIRED) endif() # Recent changes to LibAlkimia should allow us to remove this construct #if(CMAKE_SYSTEM_NAME MATCHES "Windows") # include_directories(${GMP_INCLUDE_DIR}) #endif() find_package(KChart 2.6.0) if(KF5Gpgmepp_FOUND) set(GPG_FOUND TRUE) endif() cmake_dependent_option(ENABLE_GPG "Enable GPG support." ON "GPG_FOUND" OFF) add_feature_info("Encryption" ENABLE_GPG "Allows to store your financial data using strong GPG encryption.") add_definitions(-DQT_USE_QSTRINGBUILDER -DQT_NO_CAST_TO_ASCII -DQT_NO_URL_CAST_FROM_STRING) set(CMAKE_CXX_STANDARD 14) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) # use DBus only on Linux if(CMAKE_SYSTEM_NAME MATCHES "Linux") set(KMM_DBUS 1) endif() set(CMAKE_INCLUDE_CURRENT_DIR ON) include_directories(${CMAKE_SOURCE_DIR} ${CMAKE_BINARY_DIR}) # check for Doxygen find_package(Doxygen) if(DOXYGEN_FOUND) set(APIDOC_DIR ${CMAKE_CURRENT_BINARY_DIR}/apidocs) make_directory("${APIDOC_DIR}") configure_file(${CMAKE_CURRENT_SOURCE_DIR}/kmymoney.doxygen.in ${CMAKE_CURRENT_BINARY_DIR}/kmymoney.doxygen IMMEDIATE) add_custom_target(apidoc "${DOXYGEN}" "${CMAKE_CURRENT_BINARY_DIR}/kmymoney.doxygen") endif(DOXYGEN_FOUND) add_feature_info("Doxygen" DOXYGEN_FOUND "Generate API documentation with Doxygen (for devs only).") # check some include files exists set(CMAKE_REQUIRED_DEFINITIONS -D_XOPEN_SOURCE=500 -D_BSD_SOURCE) include (CheckIncludeFileCXX) check_include_file_cxx("unistd.h" HAVE_UNISTD_H) check_include_file_cxx("pwd.h" HAVE_PWD_H) check_include_file_cxx("windows.h" HAVE_WINDOWS_H) check_include_file_cxx("lmcons.h" HAVE_LMCONS_H) check_include_file_cxx("process.h" HAVE_PROCESS_H) # include check for members in structs include (CheckStructHasMember) ######################### Special Requirements ########################## # This is needed for QtSqlite and QtDesigner # (they'll install files to ${QT_INSTALL_DIR}/plugins/) get_filename_component(QT_BIN_DIR "${QT_MOC_EXECUTABLE}" PATH) get_filename_component(QT_DIR ${QT_BIN_DIR} PATH) set(QT_INSTALL_DIR ${QT_DIR} CACHE PATH "Qt install prefix defaults to the Qt prefix: ${QT_DIR}") cmake_dependent_option(ENABLE_ADDRESSBOOK "Enable addressbook support." ON "KF5IdentityManagement_FOUND;KF5Akonadi_FOUND;KF5Contacts_FOUND" OFF) add_feature_info("Address book" ENABLE_ADDRESSBOOK "Allows fetching payee information from KDE PIM system.") cmake_dependent_option(ENABLE_HOLIDAYS "Enable addressbook support." ON "KF5Holidays_FOUND" OFF) add_feature_info("Holidays" ENABLE_HOLIDAYS "Allows fetching holidays from KDE PIM system.") cmake_dependent_option(ENABLE_ACTIVITIES "Enable activities support." ON "KF5Activities_FOUND" OFF) option(ENABLE_FORECASTVIEW "Enable forecast view" ON) add_feature_info("Forecast view" ENABLE_FORECASTVIEW "Adds possibility to calculate forecasts.") cmake_dependent_option(ENABLE_REPORTSVIEW "Enable reports view." ON "KChart_FOUND" OFF) add_feature_info("Reports view" ENABLE_REPORTSVIEW "Adds possibility to display chart and table reports.") option(ENABLE_BUDGETVIEW "Enable budget view" ON) add_feature_info("Budget view" ENABLE_BUDGETVIEW "Adds possibility to plan a budget.") option(ENABLE_ONLINEJOBOUTBOXVIEW "Enable online job outbox view" ON) add_feature_info("Online job outbox view" ENABLE_ONLINEJOBOUTBOXVIEW "Adds outbox for sending online jobs.") cmake_dependent_option(ENABLE_SQLSTORAGE "Enable SQL storage support." ON "Qt5Sql_FOUND" OFF) add_feature_info("SQL Storage" ENABLE_SQLSTORAGE "Allows storing your financial data in SQL database.") cmake_dependent_option(ENABLE_SQLCIPHER "Enable SQLCipher support." ON "SQLCIPHER_FOUND" OFF) # Otherwise compilers halt on something like that: # ld: library not found for -lsqlcipher # on MS Windows, FreeBSD, macOS, and Ubuntu 14.04 (Ubuntu has CMake 3.5.1 but I'm not sure if it's the one to blame). if(ENABLE_SQLCIPHER AND (NOT CMAKE_SYSTEM_NAME MATCHES "Linux" OR CMAKE_VERSION VERSION_LESS 3.5.2)) link_directories(${SQLCIPHER_LIBRARY_DIRS}) endif() add_feature_info("SQLCipher" ENABLE_SQLCIPHER "Allows encrypting your SQLite3 database.") cmake_dependent_option(ENABLE_IBANBICDATA "Enable IBAN/BIC data support." OFF "Qt5Sql_FOUND" OFF) add_feature_info("IBAN/BIC data" ENABLE_IBANBICDATA "Adds predefined IBAN/BIC numbers to KMyMoney (note: doesn't work yet).") # check for optional QWebEngine option(ENABLE_WEBENGINE "Enable QWebEngine" OFF) if(ENABLE_WEBENGINE) find_package(Qt5WebEngineWidgets 5.8 REQUIRED) if(Qt5WebEngineWidgets_VERSION VERSION_GREATER 5.8.99 AND Qt5WebEngineWidgets_VERSION VERSION_LESS 5.9.3) message(WARNING "QWebEngine version ${Qt5WebEngineWidgets_VERSION} is known to be unstable with KMyMoney") endif() else(ENABLE_WEBENGINE) find_package(KF5WebKit REQUIRED) endif(ENABLE_WEBENGINE) # check for optional LibOFX support find_package(LibOfx) cmake_dependent_option(ENABLE_OFXIMPORTER "Enable OFX Importer" ON "LIBOFX_FOUND" OFF) if(ENABLE_OFXIMPORTER) if(NOT LIBOFX_HAVE_CLIENTUID) set(PATH_TO_LIBOFX_HEADER "${LIBOFX_INCLUDE_DIR}/libofx/libofx.h") unset(LIBOFX_HAVE_CLIENTUID) unset(LIBOFX_HAVE_CLIENTUID CACHE) #not doing this will prevent updating below check check_struct_has_member("struct OfxFiLogin" clientuid ${PATH_TO_LIBOFX_HEADER} LIBOFX_HAVE_CLIENTUID LANGUAGE CXX) endif() if (LIBOFX_HAVE_CLIENTUID) set (nice_LIBOFX_HAVE_CLIENTUID "yes") else() set (nice_LIBOFX_HAVE_CLIENTUID "no") endif() else() set (nice_LIBOFX_HAVE_CLIENTUID "unknown") unset(LIBOFX_HAVE_CLIENTUID) unset(LIBOFX_HAVE_CLIENTUID CACHE) endif(ENABLE_OFXIMPORTER) add_feature_info("OFX Importer" ENABLE_OFXIMPORTER "Allows importing OFX files (have client uid version: ${nice_LIBOFX_HAVE_CLIENTUID})" ) # check for optional KBanking support find_package(AQBANKING 5.6.5) find_package(gwenhywfar 4.15.3) find_package(gwengui-cpp) find_package(gwengui-qt5) cmake_dependent_option(ENABLE_KBANKING "Enable KBanking plugin" ON "AQBANKING_FOUND;gwengui-cpp_FOUND;gwengui-qt5_FOUND;Qt5QuickWidgets_FOUND" OFF) add_feature_info(KBanking ENABLE_KBANKING "Interface for the following online banking protocols: HBCI, EBICS, OFX Direct Connect, Paypal") # check for optional Weboob support set(Python_ADDITIONAL_VERSIONS 2.7 2.6) find_package(PythonInterp 2.6) find_package(PythonLibs ${PYTHON_VERSION_STRING}) if(PYTHONINTERP_FOUND AND PYTHONLIBS_FOUND) if(NOT PYTHON_VERSION_MAJOR VERSION_LESS 3) unset(PYTHONLIBS_FOUND) unset(PYTHONINTERP_FOUND) message(WARNING "Python 2 required, but Python 3 found.") else() include(FindPythonModule) find_python_module(weboob REQUIRED) endif() endif() cmake_dependent_option(ENABLE_WEBOOB "Enable Weboob plugin" ON "PYTHONLIBS_FOUND;PYTHONINTERP_FOUND;PY_WEBOOB;Qt5Concurrent_FOUND" OFF) add_feature_info(Weboob ENABLE_WEBOOB "Online banking interface using Weboob.") # check for optional ical support find_package(Libical) cmake_dependent_option(ENABLE_LIBICAL "Enable Calendar plugin" ON "LIBICAL_FOUND" OFF) add_feature_info(iCalendar ENABLE_LIBICAL "iCalendar integration.") option(ENABLE_QIFIMPORTER "Enable QIF Importer" ON) option(ENABLE_QIFEXPORTER "Enable QIF Exporter" ON) add_feature_info("QIF Importer" ENABLE_QIFIMPORTER "Allows importing QIF files.") add_feature_info("QIF Exporter" ENABLE_QIFEXPORTER "Allows exporting QIF files.") option(ENABLE_GNCIMPORTER "Enable GNC Importer" ON) add_feature_info("GNC Importer" ENABLE_GNCIMPORTER "Allows importing GNUCash files.") option(ENABLE_CSVIMPORTER "Enable CSV Importer" ON) option(ENABLE_CSVEXPORTER "Enable CSV Exporter" ON) add_feature_info("CSV Importer" ENABLE_CSVIMPORTER "Allows importing CSV files.") add_feature_info("CSV Exporter" ENABLE_CSVEXPORTER "Allows exporting CSV files.") option(ENABLE_UNFINISHEDFEATURES "For devs only" OFF) # TODO: this should be removed enable_testing() ######################### Settings ########################## # If no build type is set, use "Release with Debug Info" if(NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE RelWithDebInfo) endif(NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE "${CMAKE_BUILD_TYPE}" CACHE STRING "Choose the type of build. Possible values are: 'Release' 'RelWithDebInfo' 'Debug' 'DebugKMM' 'Debugfull' 'Profile' The default value is: 'RelWithDebInfo'" FORCE) # tells gcc to enable exception handling include(KDECompilerSettings) kde_enable_exceptions() # Set linker flags # There is no way to detect linker in cmake (see https://gitlab.kitware.com/cmake/cmake/issues/17596) # and linkers aren't compatible with each other, so we need to assume something if(CMAKE_CXX_COMPILER_ID MATCHES "AppleClang") set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -Wl,-dead_strip -Wl,-undefined,error") set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-dead_strip -Wl,-undefined,error -Wl,-mark_dead_strippable_dylib") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-dead_strip -Wl,-undefined,error") elseif(CMAKE_CXX_COMPILER_ID MATCHES "GNU" OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -Wl,--as-needed") set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--as-needed") # TODO: remove multiple definitions of payeeIdentifierLoader::createPayeeIdentifierFromSqlDatabase set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--as-needed -Wl,--allow-multiple-definition") # CI builds are crashing on FreeBSD with --no-undefined. Probably because -DECM_ENABLE_SANITIZERS='address' # more can be read on the following site https://bugs.freedesktop.org/show_bug.cgi?id=100120 if(NOT CMAKE_SYSTEM_NAME MATCHES "FreeBSD") set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -Wl,--no-undefined") set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--no-undefined") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--no-undefined") endif() # TODO: remove multiple definitions of payeeIdentifierLoader::hasItemEditDelegate if(CMAKE_SYSTEM_NAME MATCHES "Windows") set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -Wl,--allow-multiple-definition") set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--allow-multiple-definition") endif() elseif(CMAKE_CXX_COMPILER_ID MATCHES "MSVC") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /FORCE:Multiple") endif() # Set compiler flags if(CMAKE_CXX_COMPILER_ID MATCHES "GNU") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wlogical-op -Wno-null-dereference -Wshadow -Wunused -Wno-misleading-indentation -Wsuggest-override -Wcast-qual -Wformat=2 -fno-common") elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR CMAKE_CXX_COMPILER_ID MATCHES "AppleClang") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wcast-qual -Wformat=2 -Wunreachable-code -fno-common") elseif(CMAKE_CXX_COMPILER_ID MATCHES "MSVC") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /experimental:external /external:anglebrackets /external:W0 /W3") endif() # IDEA: Set on a per target base set(CMAKE_POSITION_INDEPENDENT_CODE ON) if(CMAKE_CXX_COMPILER_ID MATCHES "GNU" OR CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR CMAKE_CXX_COMPILER_ID MATCHES "AppleClang") # DebugKMM, Debugfull, Profile set(CMAKE_CXX_FLAGS_DEBUGKMM "-g -O2 -fno-reorder-blocks -fno-schedule-insns -fno-inline") set(CMAKE_CXX_FLAGS_DEBUGFULL "-g3 -fno-inline") set(CMAKE_CXX_FLAGS_PROFILE "-g3 -fno-inline -ftest-coverage -fprofile-arcs") # preprocessor definitions in case this is a debug build set(CMAKE_CXX_FLAGS_DEBUGFULL "${CMAKE_CXX_FLAGS_DEBUGFULL} -DQT_STRICT_ITERATORS -DKMM_DEBUG -DQT_FORCE_ASSERTS") set(CMAKE_CXX_FLAGS_DEBUGKMM "${CMAKE_CXX_FLAGS_DEBUGFULL} -DKMM_DEBUG -DQT_FORCE_ASSERTS") endif() option(USE_MODELTEST "Compile with ModelTest code (default=OFF)" OFF) add_feature_info("Model test" USE_MODELTEST "Generate modeltest code (for devs only).") option(USE_QT_DESIGNER "Install KMyMoney specific widget library for Qt-Designer (default=OFF)" OFF) add_feature_info("QtDesigner" USE_QT_DESIGNER "Qt-Designer library support (for devs only).") ######################### The Actual Targets ########################## +set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) +set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) + add_subdirectory( tools ) add_subdirectory( kmymoney ) if(KF5DocTools_FOUND) add_subdirectory( doc ) endif() ######################### Output Results ############################# # create the config.h file out of the config.h.cmake configure_file("config-kmymoney.h.cmake" "${CMAKE_CURRENT_BINARY_DIR}/config-kmymoney.h") configure_file("config-kmymoney-version.h.cmake" "${CMAKE_CURRENT_BINARY_DIR}/config-kmymoney-version.h") message(" Build type: ${CMAKE_BUILD_TYPE}") feature_summary(WHAT REQUIRED_PACKAGES_NOT_FOUND DESCRIPTION "The following REQUIRED packages have not been found:") feature_summary(WHAT OPTIONAL_PACKAGES_NOT_FOUND DESCRIPTION "The following OPTIONAL packages have not been found:") feature_summary(WHAT ENABLED_FEATURES DESCRIPTION "The following features have been enabled:") feature_summary(WHAT DISABLED_FEATURES DESCRIPTION "The following features have been disabled:") diff --git a/kmymoney/dialogs/kenterscheduledlg.cpp b/kmymoney/dialogs/kenterscheduledlg.cpp index ad3b83bac..d76059269 100644 --- a/kmymoney/dialogs/kenterscheduledlg.cpp +++ b/kmymoney/dialogs/kenterscheduledlg.cpp @@ -1,406 +1,407 @@ /* * Copyright 2007-2012 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 "kenterscheduledlg.h" // ---------------------------------------------------------------------------- // QT Includes #include #include #include #include #include #include // ---------------------------------------------------------------------------- // KDE Includes #include #include #include #include #include #include #include #include // ---------------------------------------------------------------------------- // Project Includes #include "ui_kenterscheduledlg.h" #include "tabbar.h" #include "mymoneysplit.h" #include "mymoneytransaction.h" #include "mymoneyfile.h" #include "mymoneyaccount.h" #include "mymoneymoney.h" #include "mymoneyschedule.h" #include "register.h" #include "transactionform.h" #include "transaction.h" #include "selectedtransactions.h" #include "transactioneditor.h" #include "kmymoneyutils.h" #include "kmymoneylineedit.h" #include "kmymoneydateinput.h" #include "knewaccountdlg.h" #include "knewinvestmentwizard.h" #include "mymoneyexception.h" #include "icons/icons.h" #include "mymoneyenums.h" #include "dialogenums.h" #include "widgetenums.h" using namespace Icons; class KEnterScheduleDlgPrivate { Q_DISABLE_COPY(KEnterScheduleDlgPrivate) public: KEnterScheduleDlgPrivate() : ui(new Ui::KEnterScheduleDlg), m_item(nullptr), m_showWarningOnce(true), m_extendedReturnCode(eDialogs::ScheduleResultCode::Cancel) { } ~KEnterScheduleDlgPrivate() { delete ui; } Ui::KEnterScheduleDlg *ui; MyMoneySchedule m_schedule; KMyMoneyRegister::Transaction* m_item; QWidgetList m_tabOrderWidgets; bool m_showWarningOnce; eDialogs::ScheduleResultCode m_extendedReturnCode; }; KEnterScheduleDlg::KEnterScheduleDlg(QWidget *parent, const MyMoneySchedule& schedule) : QDialog(parent), d_ptr(new KEnterScheduleDlgPrivate) { Q_D(KEnterScheduleDlg); // restore the last used dialog size KConfigGroup grp = KSharedConfig::openConfig()->group("KEnterScheduleDlg"); if (grp.isValid()) { KWindowConfig::restoreWindowSize(windowHandle(), grp); } // let the minimum size be 780x410 resize(QSize(780, 410).expandedTo(windowHandle() ? windowHandle()->size() : QSize())); // position the dialog centered on the application (for some reason without // a call to winId() the dialog is positioned in the upper left corner of // the screen, but winId() crashes on MS-Windows ... - move(parent->pos() + QPoint(parent->width()/2, parent->height()/2) - QPoint(width()/2, height()/2)); + if (parent) + move(parent->pos() + QPoint(parent->width()/2, parent->height()/2) - QPoint(width()/2, height()/2)); d->ui->setupUi(this); d->m_schedule = schedule; d->m_extendedReturnCode = eDialogs::ScheduleResultCode::Enter; d->ui->buttonOk->setIcon(Icons::get(Icon::KeyEnter)); d->ui->buttonSkip->setIcon(Icons::get(Icon::MediaSeekForward)); KGuiItem::assign(d->ui->buttonCancel, KStandardGuiItem::cancel()); KGuiItem::assign(d->ui->buttonHelp, KStandardGuiItem::help()); d->ui->buttonIgnore->setHidden(true); d->ui->buttonSkip->setHidden(true); // make sure, we have a tabbar with the form KMyMoneyTransactionForm::TabBar* tabbar = d->ui->m_form->getTabBar(d->ui->m_form->parentWidget()); // we never need to see the register d->ui->m_register->hide(); // ... setup the form ... d->ui->m_form->setupForm(d->m_schedule.account()); // ... and the register ... d->ui->m_register->clear(); // ... now add the transaction to register and form ... MyMoneyTransaction t = transaction(); d->m_item = KMyMoneyRegister::Register::transactionFactory(d->ui->m_register, t, d->m_schedule.transaction().splits().isEmpty() ? MyMoneySplit() : d->m_schedule.transaction().splits().front(), 0); d->ui->m_register->selectItem(d->m_item); // show the account row d->m_item->setShowRowInForm(0, true); d->ui->m_form->slotSetTransaction(d->m_item); // no need to see the tabbar tabbar->hide(); // setup name and type d->ui->m_scheduleName->setText(d->m_schedule.name()); d->ui->m_type->setText(KMyMoneyUtils::scheduleTypeToString(d->m_schedule.type())); connect(d->ui->buttonHelp, &QAbstractButton::clicked, this, &KEnterScheduleDlg::slotShowHelp); connect(d->ui->buttonIgnore, &QAbstractButton::clicked, this, &KEnterScheduleDlg::slotIgnore); connect(d->ui->buttonSkip, &QAbstractButton::clicked, this, &KEnterScheduleDlg::slotSkip); } KEnterScheduleDlg::~KEnterScheduleDlg() { Q_D(KEnterScheduleDlg); // store the last used dialog size KConfigGroup grp = KSharedConfig::openConfig()->group("KEnterScheduleDlg"); if (grp.isValid()) { KWindowConfig::saveWindowSize(windowHandle(), grp); } delete d; } eDialogs::ScheduleResultCode KEnterScheduleDlg::resultCode() const { Q_D(const KEnterScheduleDlg); if (result() == QDialog::Accepted) return d->m_extendedReturnCode; return eDialogs::ScheduleResultCode::Cancel; } void KEnterScheduleDlg::showExtendedKeys(bool visible) { Q_D(KEnterScheduleDlg); d->ui->buttonIgnore->setVisible(visible); d->ui->buttonSkip->setVisible(visible); } void KEnterScheduleDlg::slotIgnore() { Q_D(KEnterScheduleDlg); d->m_extendedReturnCode = eDialogs::ScheduleResultCode::Ignore; accept(); } void KEnterScheduleDlg::slotSkip() { Q_D(KEnterScheduleDlg); d->m_extendedReturnCode = eDialogs::ScheduleResultCode::Skip; accept(); } MyMoneyTransaction KEnterScheduleDlg::transaction() { Q_D(KEnterScheduleDlg); auto t = d->m_schedule.transaction(); try { if (d->m_schedule.type() == eMyMoney::Schedule::Type::LoanPayment) { KMyMoneyUtils::calculateAutoLoan(d->m_schedule, t, QMap()); } } catch (const MyMoneyException &e) { KMessageBox::detailedError(this, i18n("Unable to load schedule details"), QString::fromLatin1(e.what())); } t.clearId(); t.setEntryDate(QDate()); return t; } QDate KEnterScheduleDlg::date(const QDate& _date) const { Q_D(const KEnterScheduleDlg); auto date(_date); return d->m_schedule.adjustedDate(date, d->m_schedule.weekendOption()); } void KEnterScheduleDlg::resizeEvent(QResizeEvent* ev) { Q_UNUSED(ev) Q_D(KEnterScheduleDlg); d->ui->m_register->resize((int)eWidgets::eTransaction::Column::Detail); d->ui->m_form->resize((int)eWidgets::eTransactionForm::Column::Value1); QDialog::resizeEvent(ev); } void KEnterScheduleDlg::slotSetupSize() { resize(width(), minimumSizeHint().height()); } int KEnterScheduleDlg::exec() { Q_D(KEnterScheduleDlg); if (d->m_showWarningOnce) { d->m_showWarningOnce = false; KMessageBox::information(parentWidget(), QString("") + i18n("

Please check that all the details in the following dialog are correct and press OK.

Editable data can be changed and can either be applied to just this occurrence or for all subsequent occurrences for this schedule. (You will be asked what you intend after pressing OK in the following dialog)

") + QString("
"), i18n("Enter scheduled transaction"), "EnterScheduleDlgInfo"); } // force the initial height to be as small as possible QTimer::singleShot(0, this, SLOT(slotSetupSize())); return QDialog::exec(); } TransactionEditor* KEnterScheduleDlg::startEdit() { Q_D(KEnterScheduleDlg); KMyMoneyRegister::SelectedTransactions list(d->ui->m_register); auto editor = d->m_item->createEditor(d->ui->m_form, list, QDate()); if (editor) { editor->setScheduleInfo(d->m_schedule.name()); editor->setPaymentMethod(d->m_schedule.paymentType()); } // check that we use the same transaction commodity in all selected transactions // if not, we need to update this in the editor's list. The user can also bail out // of this operation which means that we have to stop editing here. if (editor) { if (!editor->fixTransactionCommodity(d->m_schedule.account())) { // if the user wants to quit, we need to destroy the editor // and bail out delete editor; editor = 0; } } if (editor) { connect(editor, &TransactionEditor::transactionDataSufficient, d->ui->buttonOk, &QWidget::setEnabled); connect(editor, &TransactionEditor::escapePressed, d->ui->buttonCancel, &QAbstractButton::animateClick); connect(editor, &TransactionEditor::returnPressed, d->ui->buttonOk, &QAbstractButton::animateClick); connect(MyMoneyFile::instance(), &MyMoneyFile::dataChanged, editor, &TransactionEditor::slotReloadEditWidgets); // connect(editor, SIGNAL(finishEdit(KMyMoneyRegister::SelectedTransactions)), this, SLOT(slotLeaveEditMode(KMyMoneyRegister::SelectedTransactions))); connect(MyMoneyFile::instance(), &MyMoneyFile::dataChanged, editor, &TransactionEditor::slotReloadEditWidgets); // create the widgets, place them in the parent and load them with data // setup tab order d->m_tabOrderWidgets.clear(); eWidgets::eRegister::Action action = eWidgets::eRegister::Action::Withdrawal; switch (d->m_schedule.type()) { case eMyMoney::Schedule::Type::Transfer: action = eWidgets::eRegister::Action::Transfer; break; case eMyMoney::Schedule::Type::Deposit: action = eWidgets::eRegister::Action::Deposit; break; case eMyMoney::Schedule::Type::LoanPayment: switch (d->m_schedule.paymentType()) { case eMyMoney::Schedule::PaymentType::DirectDeposit: case eMyMoney::Schedule::PaymentType::ManualDeposit: action = eWidgets::eRegister::Action::Deposit; break; default: break; } break; default: break; } editor->setup(d->m_tabOrderWidgets, d->m_schedule.account(), action); MyMoneyTransaction t = d->m_schedule.transaction(); QString num = t.splits().first().number(); QWidget* w = editor->haveWidget("number"); if (d->m_schedule.paymentType() == eMyMoney::Schedule::PaymentType::WriteChecque) { num = KMyMoneyUtils::nextFreeCheckNumber(d->m_schedule.account()); d->m_schedule.account().setValue("lastNumberUsed", num); if (w) if (auto numberWidget = dynamic_cast(w)) numberWidget->loadText(num); } else { // if it's not a check, then we need to clear // a possibly assigned check number if (w) if (auto numberWidget = dynamic_cast(w)) numberWidget->loadText(QString()); } Q_ASSERT(!d->m_tabOrderWidgets.isEmpty()); // editor->setup() leaves the tabbar as the last widget in the stack, but we // need it as first here. So we move it around. w = editor->haveWidget("tabbar"); if (w) { int idx = d->m_tabOrderWidgets.indexOf(w); if (idx != -1) { d->m_tabOrderWidgets.removeAt(idx); d->m_tabOrderWidgets.push_front(w); } } // don't forget our three buttons d->m_tabOrderWidgets.append(d->ui->buttonOk); d->m_tabOrderWidgets.append(d->ui->buttonCancel); d->m_tabOrderWidgets.append(d->ui->buttonHelp); for (auto i = 0; i < d->m_tabOrderWidgets.size(); ++i) { w = d->m_tabOrderWidgets.at(i); if (w) { w->installEventFilter(this); w->installEventFilter(editor); } } // Check if the editor has some preference on where to set the focus // If not, set the focus to the first widget in the tab order QWidget* focusWidget = editor->firstWidget(); if (!focusWidget) focusWidget = d->m_tabOrderWidgets.first(); focusWidget->setFocus(); // Make sure, we use the adjusted date if (auto dateEdit = dynamic_cast(editor->haveWidget("postdate"))) dateEdit->setDate(d->m_schedule.adjustedNextDueDate()); } return editor; } bool KEnterScheduleDlg::focusNextPrevChild(bool next) { Q_D(KEnterScheduleDlg); auto rc = false; auto w = qApp->focusWidget(); int currentWidgetIndex = d->m_tabOrderWidgets.indexOf(w); while (w && currentWidgetIndex == -1) { // qDebug("'%s' not in list, use parent", w->className()); w = w->parentWidget(); currentWidgetIndex = d->m_tabOrderWidgets.indexOf(w); } if (currentWidgetIndex != -1) { // if(w) qDebug("tab order is at '%s'", w->className()); currentWidgetIndex += next ? 1 : -1; if (currentWidgetIndex < 0) currentWidgetIndex = d->m_tabOrderWidgets.size() - 1; else if (currentWidgetIndex >= d->m_tabOrderWidgets.size()) currentWidgetIndex = 0; w = d->m_tabOrderWidgets[currentWidgetIndex]; // qDebug("currentWidgetIndex = %d, w = %p", currentWidgetIndex, w); if (((w->focusPolicy() & Qt::TabFocus) == Qt::TabFocus) && w->isVisible() && w->isEnabled()) { // qDebug("Selecting '%s' as focus", w->className()); w->setFocus(); rc = true; } } return rc; } void KEnterScheduleDlg::slotShowHelp() { KHelpClient::invokeHelp("details.schedules.entering"); } diff --git a/kmymoney/plugins/views/budget/kbudgetvalues.cpp b/kmymoney/plugins/views/budget/kbudgetvalues.cpp index 5aa172952..3b011fdbf 100644 --- a/kmymoney/plugins/views/budget/kbudgetvalues.cpp +++ b/kmymoney/plugins/views/budget/kbudgetvalues.cpp @@ -1,387 +1,387 @@ /*************************************************************************** kbudgetvalues - description ------------------- begin : Wed Nov 28 2007 copyright : (C) 2007 by Thomas Baumgart email : Thomas Baumgart (C) 2017 by Ł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. * * * ***************************************************************************/ #include "kbudgetvalues.h" // ---------------------------------------------------------------------------- // QT Includes #include #include #include #include #include #include #include #include #include // ---------------------------------------------------------------------------- // KDE Includes #include #include #include // ---------------------------------------------------------------------------- // Project Includes #include "ui_kbudgetvalues.h" #include "mymoneybudget.h" #include "kmymoneyedit.h" #include "kmymoneysettings.h" #include "mymoneyenums.h" class KBudgetValuesPrivate { Q_DISABLE_COPY(KBudgetValuesPrivate) public: KBudgetValuesPrivate() : ui(new Ui::KBudgetValues), m_currentTab(nullptr) { for (int i = 0; i < 12; ++i) { m_label[i] = nullptr; m_field[i] = nullptr; } } ~KBudgetValuesPrivate() { delete ui; } void enableMonths(bool enabled) { for (int i = 1; i < 12; ++i) { m_label[i]->setEnabled(enabled); m_field[i]->setEnabled(enabled); } } void fillMonthLabels() { QDate date(m_budgetDate); for (auto i = 0; i < 12; ++i) { m_label[i]->setText(QLocale().standaloneMonthName(date.month(), QLocale::ShortFormat)); date = date.addMonths(1); } } Ui::KBudgetValues *ui; - KMyMoneyEdit* m_field[12]; + AmountEdit* m_field[12]; QLabel* m_label[12]; QWidget* m_currentTab; QDate m_budgetDate; }; KBudgetValues::KBudgetValues(QWidget* parent) : QWidget(parent), d_ptr(new KBudgetValuesPrivate) { Q_D(KBudgetValues); d->ui->setupUi(this); d->m_currentTab = d->ui->m_monthlyButton; d->m_budgetDate = QDate(2007, KMyMoneySettings::firstFiscalMonth(), KMyMoneySettings::firstFiscalDay()); d->m_field[0] = d->ui->m_amount1; d->m_field[1] = d->ui->m_amount2; d->m_field[2] = d->ui->m_amount3; d->m_field[3] = d->ui->m_amount4; d->m_field[4] = d->ui->m_amount5; d->m_field[5] = d->ui->m_amount6; d->m_field[6] = d->ui->m_amount7; d->m_field[7] = d->ui->m_amount8; d->m_field[8] = d->ui->m_amount9; d->m_field[9] = d->ui->m_amount10; d->m_field[10] = d->ui->m_amount11; d->m_field[11] = d->ui->m_amount12; d->m_label[0] = d->ui->m_label1; d->m_label[1] = d->ui->m_label2; d->m_label[2] = d->ui->m_label3; d->m_label[3] = d->ui->m_label4; d->m_label[4] = d->ui->m_label5; d->m_label[5] = d->ui->m_label6; d->m_label[6] = d->ui->m_label7; d->m_label[7] = d->ui->m_label8; d->m_label[8] = d->ui->m_label9; d->m_label[9] = d->ui->m_label10; d->m_label[10] = d->ui->m_label11; d->m_label[11] = d->ui->m_label12; // fill with standard labels d->ui->m_monthlyButton->setChecked(true); d->ui->m_periodGroup->setId(d->ui->m_monthlyButton, 0); d->ui->m_periodGroup->setId(d->ui->m_yearlyButton, 1); d->ui->m_periodGroup->setId(d->ui->m_individualButton, 2); slotChangePeriod(d->ui->m_periodGroup->id(d->ui->m_monthlyButton)); - connect(d->ui->m_amountMonthly, &KMyMoneyEdit::valueChanged, this, &KBudgetValues::slotNeedUpdate); - connect(d->ui->m_amountYearly, &KMyMoneyEdit::valueChanged, this, &KBudgetValues::slotNeedUpdate); + connect(d->ui->m_amountMonthly, &AmountEdit::valueChanged, this, &KBudgetValues::slotNeedUpdate); + connect(d->ui->m_amountYearly, &AmountEdit::valueChanged, this, &KBudgetValues::slotNeedUpdate); d->ui->m_amountMonthly->installEventFilter(this); d->ui->m_amountYearly->installEventFilter(this); for (auto i = 0; i < 12; ++i) { - connect(d->m_field[i], &KMyMoneyEdit::valueChanged, this, &KBudgetValues::slotNeedUpdate); + connect(d->m_field[i], &AmountEdit::valueChanged, this, &KBudgetValues::slotNeedUpdate); d->m_field[i]->installEventFilter(this); } connect(d->ui->m_clearButton, &QAbstractButton::clicked, this, &KBudgetValues::slotClearAllValues); connect(d->ui->m_periodGroup, static_cast(&QButtonGroup::buttonClicked), this, &KBudgetValues::slotChangePeriod); connect(this, &KBudgetValues::valuesChanged, this, &KBudgetValues::slotUpdateClearButton); KGuiItem clearItem(KStandardGuiItem::clear()); KGuiItem::assign(d->ui->m_clearButton, clearItem); d->ui->m_clearButton->setText(QString()); d->ui->m_clearButton->setToolTip(clearItem.toolTip()); } KBudgetValues::~KBudgetValues() { Q_D(KBudgetValues); delete d; } bool KBudgetValues::eventFilter(QObject* o, QEvent* e) { auto rc = false; if (o->isWidgetType() && (e->type() == QEvent::KeyPress)) { if (auto k = dynamic_cast(e)) { if ((k->modifiers() & Qt::KeyboardModifierMask) == 0 || (k->modifiers() & Qt::KeypadModifier) != 0) { QKeyEvent evt(e->type(), Qt::Key_Tab, k->modifiers(), QString(), k->isAutoRepeat(), k->count()); switch (k->key()) { case Qt::Key_Return: case Qt::Key_Enter: // send out a TAB key event QApplication::sendEvent(o, &evt); // don't process this one any further rc = true; break; default: break; } } } } return rc; } void KBudgetValues::clear() { Q_D(KBudgetValues); blockSignals(true); for (auto i = 0; i < 12; ++i) d->m_field[i]->setValue(MyMoneyMoney()); d->ui->m_amountMonthly->setValue(MyMoneyMoney()); d->ui->m_amountYearly->setValue(MyMoneyMoney()); blockSignals(false); } void KBudgetValues::slotClearAllValues() { Q_D(KBudgetValues); int tab = d->ui->m_periodGroup->checkedId(); if (tab == d->ui->m_periodGroup->id(d->ui->m_monthlyButton)) { d->ui->m_amountMonthly->setValue(MyMoneyMoney()); } else if (tab == d->ui->m_periodGroup->id(d->ui->m_yearlyButton)) { d->ui->m_amountYearly->setValue(MyMoneyMoney()); } else if (tab == d->ui->m_periodGroup->id(d->ui->m_individualButton)) { for (auto i = 0; i < 12; ++i) d->m_field[i]->setValue(MyMoneyMoney()); } emit valuesChanged(); } void KBudgetValues::slotChangePeriod(int id) { Q_D(KBudgetValues); // Prevent a recursive entry of this method due to widget changes // performed during execution of this method static bool inside = false; if (inside) return; inside = true; QWidget *tab = d->ui->m_periodGroup->button(id); d->fillMonthLabels(); MyMoneyMoney newValue; if (tab == d->ui->m_monthlyButton) { d->ui->m_firstItemStack->setCurrentIndex(d->ui->m_firstItemStack->indexOf(d->ui->m_monthlyPage)); d->enableMonths(false); d->m_label[0]->setText(" "); if (d->ui->m_amountMonthly->value().isZero()) { if (d->m_currentTab == d->ui->m_yearlyButton) { newValue = (d->ui->m_amountYearly->value() / MyMoneyMoney(12, 1)).convert(); } else if (d->m_currentTab == d->ui->m_individualButton) { for (auto i = 0; i < 12; ++i) newValue += d->m_field[i]->value(); newValue = (newValue / MyMoneyMoney(12, 1)).convert(); } if (!newValue.isZero()) { if (KMessageBox::questionYesNo(this, QString("") + i18n("You have entered budget values using a different base which would result in a monthly budget of %1. Should this value be used to fill the monthly budget?", newValue.formatMoney(QString(), 2)) + QString(""), i18nc("Auto assignment (caption)", "Auto assignment"), KStandardGuiItem::yes(), KStandardGuiItem::no(), "use_previous_budget_values") == KMessageBox::Yes) { d->ui->m_amountMonthly->setValue(newValue); } } } } else if (tab == d->ui->m_yearlyButton) { d->ui->m_firstItemStack->setCurrentIndex(d->ui->m_firstItemStack->indexOf(d->ui->m_yearlyPage)); d->enableMonths(false); d->m_label[0]->setText(" "); if (d->ui->m_amountYearly->value().isZero()) { if (d->m_currentTab == d->ui->m_monthlyButton) { newValue = (d->ui->m_amountMonthly->value() * MyMoneyMoney(12, 1)).convert(); } else if (d->m_currentTab == d->ui->m_individualButton) { for (auto i = 0; i < 12; ++i) newValue += d->m_field[i]->value(); } if (!newValue.isZero()) { if (KMessageBox::questionYesNo(this, QString("") + i18n("You have entered budget values using a different base which would result in a yearly budget of %1. Should this value be used to fill the monthly budget?", newValue.formatMoney(QString(), 2)) + QString(""), i18nc("Auto assignment (caption)", "Auto assignment"), KStandardGuiItem::yes(), KStandardGuiItem::no(), "use_previous_budget_values") == KMessageBox::Yes) { d->ui->m_amountYearly->setValue(newValue); } } } } else if (tab == d->ui->m_individualButton) { d->ui->m_firstItemStack->setCurrentIndex(d->ui->m_firstItemStack->indexOf(d->ui->m_individualPage)); d->enableMonths(true); for (auto i = 0; i < 12; ++i) newValue += d->m_field[i]->value(); if (newValue.isZero()) { if (d->m_currentTab == d->ui->m_monthlyButton) { newValue = d->ui->m_amountMonthly->value(); } else if (d->m_currentTab == d->ui->m_yearlyButton) { newValue = (d->ui->m_amountYearly->value() / MyMoneyMoney(12, 1)).convert(); } if (!newValue.isZero()) { if (KMessageBox::questionYesNo(this, QString("") + i18n("You have entered budget values using a different base which would result in an individual monthly budget of %1. Should this value be used to fill the monthly budgets?", newValue.formatMoney(QString(), 2)) + QString(""), i18nc("Auto assignment (caption)", "Auto assignment"), KStandardGuiItem::yes(), KStandardGuiItem::no(), "use_previous_budget_values") == KMessageBox::Yes) { for (auto i = 0; i < 12; ++i) d->m_field[i]->setValue(newValue); } } } } slotNeedUpdate(); d->m_currentTab = tab; inside = false; } void KBudgetValues::slotNeedUpdate() { if (!signalsBlocked()) QTimer::singleShot(0, this, SIGNAL(valuesChanged())); } void KBudgetValues::setBudgetValues(const MyMoneyBudget& budget, const MyMoneyBudget::AccountGroup& budgetAccount) { Q_D(KBudgetValues); MyMoneyBudget::PeriodGroup period; d->m_budgetDate = budget.budgetStart(); QDate date; // make sure all values are zero so that slotChangePeriod() // doesn't check for anything. clear(); blockSignals(true); switch (budgetAccount.budgetLevel()) { case eMyMoney::Budget::Level::Monthly: default: d->ui->m_monthlyButton->setChecked(true); slotChangePeriod(d->ui->m_periodGroup->id(d->ui->m_monthlyButton)); d->ui->m_amountMonthly->setValue(budgetAccount.period(d->m_budgetDate).amount()); break; case eMyMoney::Budget::Level::Yearly: d->ui->m_yearlyButton->setChecked(true); slotChangePeriod(d->ui->m_periodGroup->id(d->ui->m_yearlyButton)); d->ui->m_amountYearly->setValue(budgetAccount.period(d->m_budgetDate).amount()); break; case eMyMoney::Budget::Level::MonthByMonth: d->ui->m_individualButton->setChecked(true); slotChangePeriod(d->ui->m_periodGroup->id(d->ui->m_individualButton)); date.setDate(d->m_budgetDate.year(), d->m_budgetDate.month(), d->m_budgetDate.day()); for (auto i = 0; i < 12; ++i) { d->m_field[i]->setValue(budgetAccount.period(date).amount()); date = date.addMonths(1); } break; } slotUpdateClearButton(); blockSignals(false); } void KBudgetValues::budgetValues(const MyMoneyBudget& budget, MyMoneyBudget::AccountGroup& budgetAccount) { Q_D(KBudgetValues); MyMoneyBudget::PeriodGroup period; d->m_budgetDate = budget.budgetStart(); period.setStartDate(d->m_budgetDate); QDate date; budgetAccount.clearPeriods(); int tab = d->ui->m_periodGroup->checkedId(); if (tab == d->ui->m_periodGroup->id(d->ui->m_monthlyButton)) { budgetAccount.setBudgetLevel(eMyMoney::Budget::Level::Monthly); period.setAmount(d->ui->m_amountMonthly->value()); budgetAccount.addPeriod(d->m_budgetDate, period); } else if (tab == d->ui->m_periodGroup->id(d->ui->m_yearlyButton)) { budgetAccount.setBudgetLevel(eMyMoney::Budget::Level::Yearly); period.setAmount(d->ui->m_amountYearly->value()); budgetAccount.addPeriod(d->m_budgetDate, period); } else if (tab == d->ui->m_periodGroup->id(d->ui->m_individualButton)) { budgetAccount.setBudgetLevel(eMyMoney::Budget::Level::MonthByMonth); date.setDate(d->m_budgetDate.year(), d->m_budgetDate.month(), d->m_budgetDate.day()); for (auto i = 0; i < 12; ++i) { period.setStartDate(date); period.setAmount(d->m_field[i]->value()); budgetAccount.addPeriod(date, period); date = date.addMonths(1); } } } void KBudgetValues::slotUpdateClearButton() { Q_D(KBudgetValues); auto rc = false; int tab = d->ui->m_periodGroup->checkedId(); if (tab == d->ui->m_periodGroup->id(d->ui->m_monthlyButton)) { rc = !d->ui->m_amountMonthly->value().isZero(); } else if (tab == d->ui->m_periodGroup->id(d->ui->m_yearlyButton)) { rc = !d->ui->m_amountYearly->value().isZero(); } else if (tab == d->ui->m_periodGroup->id(d->ui->m_individualButton)) { for (auto i = 0; (i < 12) && (rc == false); ++i) { rc |= !d->m_field[i]->value().isZero(); } } d->ui->m_clearButton->setEnabled(rc); } diff --git a/kmymoney/plugins/views/budget/kbudgetvalues.ui b/kmymoney/plugins/views/budget/kbudgetvalues.ui index 7a2db0e0e..fc1aea53f 100644 --- a/kmymoney/plugins/views/budget/kbudgetvalues.ui +++ b/kmymoney/plugins/views/budget/kbudgetvalues.ui @@ -1,383 +1,363 @@ KBudgetValues 0 0 228 111 - + + 0 + + + 0 + + + 0 + + 0 Period Monthly - m_periodGroup + m_periodGroup Yearly - m_periodGroup + m_periodGroup Individual - m_periodGroup + m_periodGroup Qt::Vertical QSizePolicy::Expanding 20 21 Qt::Vertical QSizePolicy::Expanding 20 21 xxx false 0 0 - + + 0 + + + 0 + + + 0 + + 0 - - - false - - + - + + 0 + + + 0 + + + 0 + + 0 - - - false - - + - + + 0 + + + 0 + + + 0 + + 0 - - - false - - + xxx false - - - false - - + xxx false - - - false - - + xxx false - - - false - - + xxx false - - - false - - + xxx false - - - false - - + xxx false - - - false - - + xxx false - - - false - - + xxx false - - - false - - + xxx false - - - false - - + xxx false - - - false - - + xxx false - - - false - - + - KMyMoneyEdit - QWidget -
kmymoneyedit.h
+ AmountEdit + QLineEdit +
amountedit.h
m_monthlyButton m_yearlyButton m_individualButton m_clearButton m_amount1 m_amountMonthly m_amountYearly m_amount2 m_amount3 m_amount4 m_amount5 m_amount6 m_amount7 m_amount8 m_amount9 m_amount10 m_amount11 m_amount12