No OneTemporary

File Metadata

Created
Fri, Apr 19, 4:58 AM
This file is larger than 256 KB, so syntax highlighting was skipped.
diff --git a/CMakeLists.txt b/CMakeLists.txt
index cb3bc2d77..09dd1529c 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,266 +1,266 @@
#***************************************************************************
#* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
#* *
#* 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 <http://www.gnu.org/licenses/> *
+#* along with this program. If not, see <https://www.gnu.org/licenses/> *
#***************************************************************************
MESSAGE( STATUS "..:: CMAKE ROOT ::..")
PROJECT(skrooge)
SET (QT_MIN_VERSION "5.7.0")
OPTION(SKG_BUILD_TEST "Build the test" ON)
OPTION(SKG_DESIGNER "Build designer library" ON)
OPTION(SKG_WEBENGINE "Build WebEngine instead of WebKit" OFF)
IF(WIN32)
SET(SKG_WEBENGINE OFF)
SET(SKG_DESIGNER OFF)
ENDIF(WIN32)
IF(SKG_WEBENGINE)
SET (QT_MIN_VERSION "5.9.0")
ENDIF(SKG_WEBENGINE)
CMAKE_MINIMUM_REQUIRED(VERSION 2.8.12)
IF(POLICY CMP0063)
CMAKE_POLICY(SET CMP0063 NEW)
ENDIF(POLICY CMP0063)
FIND_PACKAGE(ECM 1.7.0 REQUIRED NO_MODULE)
SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${ECM_MODULE_PATH} ${ECM_KDE_MODULE_DIR} ${skrooge_SOURCE_DIR}/cmake/modules)
INCLUDE(ECMInstallIcons)
INCLUDE(KDEInstallDirs)
INCLUDE(KDECompilerSettings)
INCLUDE(KDECMakeSettings)
INCLUDE(FeatureSummary)
INCLUDE(CheckCXXCompilerFlag)
INCLUDE(GenerateExportHeader)
INCLUDE(ECMSetupVersion)
INCLUDE(ECMGenerateHeaders)
INCLUDE(ECMPackageConfigHelpers)
INCLUDE(KDEFrameworkCompilerSettings)
FIND_PACKAGE(Qt5 ${QT_MIN_VERSION} NO_MODULE REQUIRED Core DBus Widgets Script Sql Test PrintSupport Svg Xml Concurrent Qml QuickWidgets)
IF(SKG_WEBENGINE)
FIND_PACKAGE(Qt5 ${QT_MIN_VERSION} NO_MODULE REQUIRED WebEngineWidgets)
ELSE(SKG_WEBENGINE)
FIND_PACKAGE(Qt5 ${QT_MIN_VERSION} NO_MODULE REQUIRED WebKitWidgets)
ENDIF(SKG_WEBENGINE)
IF(SKG_DESIGNER)
FIND_PACKAGE(Qt5 ${QT_MIN_VERSION} NO_MODULE REQUIRED Designer )
FIND_PACKAGE(KF5 5.0.0 REQUIRED COMPONENTS
DesignerPlugin # Tier 3
)
ELSE(SKG_DESIGNER)
SET(SKG_BUILD_TEST OFF)
ENDIF(SKG_DESIGNER)
FIND_PACKAGE(Grantlee5 0.5 REQUIRED)
FIND_PACKAGE(KF5 5.0.0 REQUIRED COMPONENTS
Archive # Tier 1
Config # Tier 1
CoreAddons # Tier 1
I18n # Tier 1
ItemViews # Tier 1
WidgetsAddons # Tier 1
WindowSystem # Tier 1
Completion # Tier 2
JobWidgets # Tier 2
ConfigWidgets # Tier 3
IconThemes # Tier 3
KIO # Tier 3
NewStuff # Tier 3
Parts # Tier 3
Wallet # Tier 3
XmlGui # Tier 3
)
FIND_PACKAGE(KF5DocTools)
FIND_PACKAGE(PkgConfig REQUIRED)
PKG_CHECK_MODULES(SQLCIPHER REQUIRED sqlcipher)
MESSAGE( STATUS " Mode SQLCIPHER enabled")
MESSAGE( STATUS " SQLCIPHER INCLUDE : " ${SQLCIPHER_INCLUDE_DIRS})
SET(SQLITE_LIBRARIES ${SQLCIPHER_LIBRARIES})
SET(SQLITE_INCLUDE_DIR ${SQLCIPHER_INCLUDE_DIRS})
link_directories(${SQLCIPHER_LIBRARY_DIRS})
SET_PACKAGE_PROPERTIES(Sqlcipher PROPERTIES DESCRIPTION "Support for encryption"
URL "https://www.zetetic.net/sqlcipher/"
TYPE REQUIRED)
SET(GRANTLEE_VERSION ${Grantlee5_VERSION_MAJOR}.${Grantlee5_VERSION_MINOR}.${Grantlee5_VERSION_PATCH})
MESSAGE( STATUS " GRANTLEE VERSION : " ${GRANTLEE_VERSION})
SET(SKG_VERSION "2.21.0")
SET(SKG_BETA "BETA")
SET(SOVERSION 2)
IF (CMAKE_BUILD_TYPE)
ELSE (CMAKE_BUILD_TYPE)
SET(CMAKE_BUILD_TYPE profile)
#"release": optimized for speed, no debug symbols or debug messages
#"relwithdebinfo": optimized for speed, debug symbols for backtraces
#"debug": optimized, but debuggable
#"debugfull": no optimizations, full debug support
#"profile": adds coverage flags to debugfull
#"none": the build flags are manually set using the CMAKE_CXX_FLAGS option.
ENDIF (CMAKE_BUILD_TYPE)
FIND_PROGRAM(SKG_BASH bash)
MARK_AS_ADVANCED(SKG_BASH)
SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib)
MESSAGE( STATUS " QT : " ${Qt5_VERSION} )
MESSAGE( STATUS " PROJECT_SOURCE_DIR : " ${PROJECT_SOURCE_DIR} )
MESSAGE( STATUS " PROJECT_BINARY_DIR : " ${PROJECT_BINARY_DIR} )
MESSAGE( STATUS " CMAKE_BUILD_TYPE : " ${CMAKE_BUILD_TYPE} )
MESSAGE( STATUS " CMAKE_MODULE_PATH : " ${CMAKE_MODULE_PATH} )
MESSAGE( STATUS " CMAKE_INSTALL_PREFIX: " ${CMAKE_INSTALL_PREFIX} )
MESSAGE( STATUS " SKG_BUILD_TEST : " ${SKG_BUILD_TEST} )
MESSAGE( STATUS " SKG_DESIGNER : " ${SKG_DESIGNER} )
MESSAGE( STATUS " SKG_WEBENGINE : " ${SKG_WEBENGINE} )
MESSAGE( STATUS " KDE_INSTALL_QTPLUGINDIR : " ${KDE_INSTALL_QTPLUGINDIR})
#IF(CMAKE_BUILD_TYPE MATCHES "profile")
# MESSAGE( STATUS " TRACES : All traces activated")
#add_definitions(-DSKGFULLTRACES)
#ELSE(CMAKE_BUILD_TYPE MATCHES "profile")
# IF(CMAKE_BUILD_TYPE MATCHES "debug" OR SKG_BETA MATCHES "BETA")
MESSAGE( STATUS " TRACES : Some traces activated")
# ELSE(CMAKE_BUILD_TYPE MATCHES "debug" OR SKG_BETA MATCHES "BETA")
# MESSAGE( STATUS " TRACES : All traces disabled")
# add_definitions(-DSKGNOTRACES)
# ENDIF(CMAKE_BUILD_TYPE MATCHES "debug" OR SKG_BETA MATCHES "BETA")
#ENDIF(CMAKE_BUILD_TYPE MATCHES "profile")
# FIX: Qt was built with -reduce-relocations
IF(Qt5_POSITION_INDEPENDENT_CODE)
SET(CMAKE_POSITION_INDEPENDENT_CODE ON)
ENDIF(Qt5_POSITION_INDEPENDENT_CODE)
ADD_DEFINITIONS(-DSKGVERSION=${SKG_VERSION}${SKG_BETA})
REMOVE_DEFINITIONS(-DQT_NO_CAST_FROM_ASCII)
#Correction bug 207249 vvvv
IF(CMAKE_COMPILER_IS_GNUCXX)
CHECK_CXX_COMPILER_FLAG("-Wlogical-op" WLOGICALOP)
IF(WLOGICALOP)
ADD_COMPILE_OPTIONS(-Wlogical-op)
ENDIF(WLOGICALOP)
CHECK_CXX_COMPILER_FLAG("-Wnoexcept" WNOEXCEPT)
IF(WNOEXCEPT)
ADD_COMPILE_OPTIONS(-Wnoexcept)
ENDIF(WNOEXCEPT)
ADD_COMPILE_OPTIONS(-std=c++0x -pedantic -Wall -Wextra -Wno-variadic-macros -Wparentheses -Wmissing-braces -Wcast-align -Wcast-qual -Wformat=2 -Winit-self -Wmissing-include-dirs -Woverloaded-virtual -Wsign-promo -Wstrict-null-sentinel -Wundef -Wno-unused)
# ADD_COMPILE_OPTIONS(-Wstrict-overflow=5 -Wshadow -Wctor-dtor-privacy -Wshadow -Wold-style-cast -Wswitch-default -Wredundant-decls)
ENDIF(CMAKE_COMPILER_IS_GNUCXX)
#Correction bug 207249 ^^^^
#Default installation path
SET(CMAKE_INSTALL_PREFIX ${BUILD_DIR})
# Win32 specific configuration
IF(WIN32)
ADD_DEFINITIONS(-DSKG_PLATFORM_WIN32)
IF(CMAKE_COMPILER_IS_GNUCXX)
SET(CMAKE_SHARED_LINKER_FLAGS "-Wl,--enable-runtime-pseudo-reloc -Wl,--export-all-symbols" CACHE STRING "" FORCE)
ENDIF(CMAKE_COMPILER_IS_GNUCXX)
IF (CMAKE_BUILD_TYPE MATCHES RelWithDebInfo)
ADD_DEFINITIONS( -DQT_DEBUG )
ENDIF (CMAKE_BUILD_TYPE MATCHES RelWithDebInfo)
ELSE(WIN32)
#To solve Bug 209912:"ldd -u <library>""
#does not work on MACOS, must be done manually SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--as-needed" CACHE STRING "" FORCE)
ENDIF(WIN32)
MESSAGE(STATUS " CMAKE_SHARED_LINKER_FLAGS : ${CMAKE_SHARED_LINKER_FLAGS}")
#ADD_SUBDIRECTORY
ADD_SUBDIRECTORY(skgsqlcipher)
ADD_SUBDIRECTORY(skgbasemodeler)
ADD_SUBDIRECTORY(skgbankmodeler)
ADD_SUBDIRECTORY(skgbasegui)
ADD_SUBDIRECTORY(skgbankgui)
IF(SKG_DESIGNER)
ADD_SUBDIRECTORY(skgbaseguidesigner)
ADD_SUBDIRECTORY(skgbankguidesigner)
ENDIF(SKG_DESIGNER)
ADD_SUBDIRECTORY(plugins)
ADD_SUBDIRECTORY(images)
IF(SKG_BUILD_TEST AND NOT WIN32)
ADD_SUBDIRECTORY(tests)
ENDIF(SKG_BUILD_TEST AND NOT WIN32)
IF(KF5DocTools_FOUND)
ADD_SUBDIRECTORY(doc)
ENDIF(KF5DocTools_FOUND)
#Main application
ADD_SUBDIRECTORY(skrooge)
ADD_SUBDIRECTORY(skroogeconvert)
#TODO(STEPHANE MANKOWSKI) KF5 ADD_SUBDIRECTORY(skroogeakonadi)
CONFIGURE_FILE(scripts/addNewPlugin.sh.in scripts/addNewPlugin.sh @ONLY)
CONFIGURE_FILE(scripts/addNewImportPlugin.sh.in scripts/addNewImportPlugin.sh @ONLY)
#DOXYGEN
ADD_CUSTOM_TARGET(apidox "doxygen" "${PROJECT_SOURCE_DIR}/Doxyfile")
#ASTYLE
CONFIGURE_FILE(scripts/astyle.sh.in scripts/astyle.sh @ONLY)
ADD_CUSTOM_TARGET(astyle "scripts/astyle.sh")
#GENERATE SPLASH SCREEN
CONFIGURE_FILE(scripts/generateSplash.sh.in scripts/generateSplash.sh @ONLY)
ADD_CUSTOM_TARGET(splash "scripts/generateSplash.sh")
#STATIC CODE CHECKS
CONFIGURE_FILE(scripts/codecheck.sh.in scripts/codecheck.sh @ONLY)
ADD_CUSTOM_TARGET(codecheck "scripts/codecheck.sh")
CONFIGURE_FILE(CTestCustom.cmake CTestCustom.cmake @ONLY)
#FULL
CONFIGURE_FILE(scripts/full.sh scripts/full.sh @ONLY)
#GETPO
ADD_CUSTOM_COMMAND(
OUTPUT getpocmd
COMMAND python3 scripts/download-po.py
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
)
ADD_CUSTOM_TARGET(getpo
DEPENDS getpocmd
COMMENT "Re-run cmake after this to be able to run BuildTranslations with the latest files"
)
#PO files
FIND_PACKAGE(KF5I18n CONFIG REQUIRED)
KI18N_INSTALL(po)
FIND_PACKAGE(KF5DocTools CONFIG)
IF(KF5DocTools_FOUND)
KDOCTOOLS_INSTALL(po)
ENDIF()
FEATURE_SUMMARY(WHAT ALL FATAL_ON_MISSING_REQUIRED_PACKAGES)
diff --git a/cmake/modules/FindSqlite.cmake b/cmake/modules/FindSqlite.cmake
index 68cbe37c1..ac69905d8 100644
--- a/cmake/modules/FindSqlite.cmake
+++ b/cmake/modules/FindSqlite.cmake
@@ -1,57 +1,57 @@
# - find Sqlite 3
# SQLITE_INCLUDE_DIR - Where to find Sqlite 3 header files (directory)
# SQLITE_LIBRARIES - Sqlite 3 libraries
# SQLITE_LIBRARY_RELEASE - Where the release library is
# SQLITE_LIBRARY_DEBUG - Where the debug library is
# SQLITE_FOUND - Set to TRUE if we found everything (library, includes and executable)
# Copyright (c) 2010 Pau Garcia i Quiles, <pgquiles@elpauer.org>
#
# Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
#
-# Generated by CModuler, a CMake Module Generator - http://gitorious.org/cmoduler
+# Generated by CModuler, a CMake Module Generator - https://gitorious.org/cmoduler
IF( SQLITE_INCLUDE_DIR AND SQLITE_LIBRARY_RELEASE AND SQLITE_LIBRARY_DEBUG )
SET(SQLITE_FIND_QUIETLY TRUE)
ENDIF( SQLITE_INCLUDE_DIR AND SQLITE_LIBRARY_RELEASE AND SQLITE_LIBRARY_DEBUG )
FIND_PATH( SQLITE_INCLUDE_DIR sqlite3.h )
FIND_LIBRARY(SQLITE_LIBRARY_RELEASE NAMES sqlite3 )
FIND_LIBRARY(SQLITE_LIBRARY_DEBUG NAMES sqlite3 sqlite3d HINTS /usr/lib/debug/usr/lib/ )
IF( SQLITE_LIBRARY_RELEASE OR SQLITE_LIBRARY_DEBUG AND SQLITE_INCLUDE_DIR )
SET( SQLITE_FOUND TRUE )
ENDIF( SQLITE_LIBRARY_RELEASE OR SQLITE_LIBRARY_DEBUG AND SQLITE_INCLUDE_DIR )
IF( SQLITE_LIBRARY_DEBUG AND SQLITE_LIBRARY_RELEASE )
# if the generator supports configuration types then set
# optimized and debug libraries, or if the CMAKE_BUILD_TYPE has a value
IF( CMAKE_CONFIGURATION_TYPES OR CMAKE_BUILD_TYPE )
SET( SQLITE_LIBRARIES optimized ${SQLITE_LIBRARY_RELEASE} debug ${SQLITE_LIBRARY_DEBUG} )
ELSE( CMAKE_CONFIGURATION_TYPES OR CMAKE_BUILD_TYPE )
# if there are no configuration types and CMAKE_BUILD_TYPE has no value
# then just use the release libraries
SET( SQLITE_LIBRARIES ${SQLITE_LIBRARY_RELEASE} )
ENDIF( CMAKE_CONFIGURATION_TYPES OR CMAKE_BUILD_TYPE )
ELSEIF( SQLITE_LIBRARY_RELEASE )
SET( SQLITE_LIBRARIES ${SQLITE_LIBRARY_RELEASE} )
ELSE( SQLITE_LIBRARY_DEBUG AND SQLITE_LIBRARY_RELEASE )
SET( SQLITE_LIBRARIES ${SQLITE_LIBRARY_DEBUG} )
ENDIF( SQLITE_LIBRARY_DEBUG AND SQLITE_LIBRARY_RELEASE )
IF( SQLITE_FOUND )
IF( NOT SQLITE_FIND_QUIETLY )
MESSAGE( STATUS "Found Sqlite3 header file in ${SQLITE_INCLUDE_DIR}")
MESSAGE( STATUS "Found Sqlite3 libraries: ${SQLITE_LIBRARIES}")
ENDIF( NOT SQLITE_FIND_QUIETLY )
ELSE(SQLITE_FOUND)
IF( SQLITE_FIND_REQUIRED)
MESSAGE( FATAL_ERROR "Could not find Sqlite3" )
ELSE( SQLITE_FIND_REQUIRED)
MESSAGE( STATUS "Optional package Sqlite3 was not found" )
ENDIF( SQLITE_FIND_REQUIRED)
ENDIF(SQLITE_FOUND)
diff --git a/doc/CMakeLists.txt b/doc/CMakeLists.txt
index 99180edeb..0af82d5e7 100644
--- a/doc/CMakeLists.txt
+++ b/doc/CMakeLists.txt
@@ -1,17 +1,17 @@
#***************************************************************************
#* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
#* *
#* 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 <http://www.gnu.org/licenses/> *
+#* along with this program. If not, see <https://www.gnu.org/licenses/> *
#***************************************************************************
kdoctools_create_handbook(index.docbook INSTALL_DESTINATION ${HTML_INSTALL_DIR}/en SUBDIR skrooge)
diff --git a/images/CMakeLists.txt b/images/CMakeLists.txt
index 791309a29..3ce151a7a 100644
--- a/images/CMakeLists.txt
+++ b/images/CMakeLists.txt
@@ -1,26 +1,26 @@
#***************************************************************************
#* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
#* *
#* 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 <http://www.gnu.org/licenses/> *
+#* along with this program. If not, see <https://www.gnu.org/licenses/> *
#***************************************************************************
MESSAGE( STATUS "..:: CMAKE IMAGES ::..")
PROJECT(images)
ADD_SUBDIRECTORY( logos )
#GENERATE SPLASH SCREEN
CONFIGURE_FILE(${PROJECT_SOURCE_DIR}/splash.svg.in ${PROJECT_BINARY_DIR}/splash.svg @ONLY)
INSTALL(FILES splash.png DESTINATION ${KDE_INSTALL_DATADIR}/skrooge/images)
diff --git a/images/logos/CMakeLists.txt b/images/logos/CMakeLists.txt
index d96afc1d9..91bcc9f5b 100644
--- a/images/logos/CMakeLists.txt
+++ b/images/logos/CMakeLists.txt
@@ -1,28 +1,28 @@
#***************************************************************************
#* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
#* *
#* 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 <http://www.gnu.org/licenses/> *
+#* along with this program. If not, see <https://www.gnu.org/licenses/> *
#***************************************************************************
MESSAGE( STATUS "..:: CMAKE IMAGES/LOGOS ::..")
PROJECT(logos)
INSTALL(DIRECTORY . DESTINATION ${KDE_INSTALL_DATADIR}/skrooge/images/logo/ FILES_MATCHING PATTERN "*.png"
PATTERN ".svn" EXCLUDE
PATTERN "CMakeFiles" EXCLUDE
PATTERN "Testing" EXCLUDE)
INSTALL(DIRECTORY . DESTINATION ${KDE_INSTALL_DATADIR}/skrooge/images/logo/ FILES_MATCHING PATTERN "list_bank.txt"
PATTERN ".svn" EXCLUDE
PATTERN "CMakeFiles" EXCLUDE
PATTERN "Testing" EXCLUDE)
diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt
index d4b45b374..4725b97d5 100644
--- a/plugins/CMakeLists.txt
+++ b/plugins/CMakeLists.txt
@@ -1,20 +1,20 @@
#***************************************************************************
#* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
#* *
#* 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 <http://www.gnu.org/licenses/> *
+#* along with this program. If not, see <https://www.gnu.org/licenses/> *
#***************************************************************************
ADD_SUBDIRECTORY(generic)
ADD_SUBDIRECTORY(skrooge)
ADD_SUBDIRECTORY(import)
ADD_SUBDIRECTORY(krunner)
diff --git a/plugins/generic/CMakeLists.txt b/plugins/generic/CMakeLists.txt
index 23da8d360..2f84d7451 100644
--- a/plugins/generic/CMakeLists.txt
+++ b/plugins/generic/CMakeLists.txt
@@ -1,29 +1,29 @@
#***************************************************************************
#* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
#* *
#* 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 <http://www.gnu.org/licenses/> *
+#* along with this program. If not, see <https://www.gnu.org/licenses/> *
#***************************************************************************
ADD_SUBDIRECTORY(skg_advice)
ADD_SUBDIRECTORY(skg_bookmark)
ADD_SUBDIRECTORY(skg_dashboard)
ADD_SUBDIRECTORY(skg_debug)
ADD_SUBDIRECTORY(skg_delete)
ADD_SUBDIRECTORY(skg_file)
ADD_SUBDIRECTORY(skg_highlight)
ADD_SUBDIRECTORY(skg_print)
ADD_SUBDIRECTORY(skg_properties)
ADD_SUBDIRECTORY(skg_selectall)
ADD_SUBDIRECTORY(skg_undoredo)
ADD_SUBDIRECTORY(skg_monthly)
ADD_SUBDIRECTORY(skg_statistic)
diff --git a/plugins/generic/skg_advice/CMakeLists.txt b/plugins/generic/skg_advice/CMakeLists.txt
index 3c4f12e26..63c34d0db 100644
--- a/plugins/generic/skg_advice/CMakeLists.txt
+++ b/plugins/generic/skg_advice/CMakeLists.txt
@@ -1,37 +1,37 @@
#***************************************************************************
#* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
#* *
#* 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 <http://www.gnu.org/licenses/> *
+#* along with this program. If not, see <https://www.gnu.org/licenses/> *
#***************************************************************************
MESSAGE( STATUS "..:: CMAKE PLUGIN_ADVICE ::..")
PROJECT(plugin_advice)
LINK_DIRECTORIES (${LIBRARY_OUTPUT_PATH})
SET(skg_advice_SRCS
skgadviceplugin.cpp
skgadviceboardwidget.cpp
skgtipofdayboardwidget.cpp
)
ki18n_wrap_ui(skg_advice_SRCS skgtipofdayboardwidget.ui)
ADD_LIBRARY(skg_advice MODULE ${skg_advice_SRCS})
TARGET_LINK_LIBRARIES(skg_advice KF5::Parts KF5::ConfigWidgets skgbasemodeler skgbasegui)
########### install files ###############
INSTALL(TARGETS skg_advice DESTINATION ${KDE_INSTALL_QTPLUGINDIR})
INSTALL(FILES ${PROJECT_SOURCE_DIR}/org.kde.skg-plugin-advice.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR})
INSTALL(FILES ${PROJECT_SOURCE_DIR}/skg_advice.rc DESTINATION ${KDE_INSTALL_KXMLGUI5DIR}/skg_advice )
diff --git a/plugins/generic/skg_advice/org.kde.skg-plugin-advice.desktop b/plugins/generic/skg_advice/org.kde.skg-plugin-advice.desktop
index cd7a070c8..fb2e04cac 100644
--- a/plugins/generic/skg_advice/org.kde.skg-plugin-advice.desktop
+++ b/plugins/generic/skg_advice/org.kde.skg-plugin-advice.desktop
@@ -1,77 +1,77 @@
[Desktop Entry]
Name=Advice plugin
Name[bs]=Priključak za savjet
Name[ca]=Connector de consells
Name[ca@valencia]=Connector de consells
Name[cs]=Rozšíření rádce
Name[da]=Råd-plugin
Name[de]=Empfehlungsmodul
Name[el]=Advice plugin
Name[en_GB]=Advice plugin
Name[es]=Complemento de consejos
Name[et]=Nõuandeplugin
Name[fi]=Neuvoliitännäinen
Name[fr]=Module externe de conseils
Name[gl]=Complemento de consellos
Name[hu]=Tanács bővítmény
Name[it]=Estensione per i suggerimenti
Name[lt]=Patarimų papildinys
Name[nb]=Adviseringsmodul
Name[nds]=Raatslääg-Moduul
Name[nl]=Plug-in voor advies
Name[pl]=Wtyczka porad
Name[pt]='Plugin' de avisos
Name[pt_BR]=Plugin de Conselhos
Name[ru]=Модуль рекомендаций
Name[sk]=Plugin rád
Name[sv]=Rådinsticksprogram
Name[tr]=Öneri eklentisi
Name[uk]=Додаток порад
Name[x-test]=xxAdvice pluginxx
Name[zh_CN]=建议插件
Name[zh_TW]=Advice 外掛程式
Comment=A plugin to advise
Comment[bs]=Dodatak za savjet
Comment[ca]=Un connector per consells
Comment[ca@valencia]=Un connector per consells
Comment[cs]=Rozšíření rádce
Comment[da]=Et plugin til rådgivning
Comment[de]=Ein Empfehlungsmodul
Comment[el]=Ένα πρόσθετο για συμβουλές
Comment[en_GB]=A plugin to advise
Comment[es]=Complemento para aconsejar
Comment[et]=Nõuandeplugin
Comment[fi]=Neuvova liitännäinen
Comment[fr]=Un module externe de conseils
Comment[gl]=Un complemento para aconsellar.
Comment[hu]=Egy tanácsadó bővítmény
Comment[it]=Un'estensione per i suggerimenti
Comment[lt]=Patarimų papildinys
Comment[nb]=Et programtillegg for advisering
Comment[nl]=Een plugin voor advies
Comment[pl]=Wtyczka do radzenia
Comment[pt]=Um 'plugin' de conselho
Comment[pt_BR]=Um plugin para aconselhar
Comment[ru]=Модуль рекомендаций
Comment[sk]=Plugin na radenie
Comment[sv]=Ett insticksprogram för borttagning
Comment[tr]=Önerilecek bir eklenti
Comment[uk]=Додаток для порад
Comment[x-test]=xxA plugin to advisexx
Comment[zh_CN]=给出建议的插件
Comment[zh_TW]=Advice 外掛程式
Encoding=UTF-8
Icon=quickopen
Type=Service
X-KDE-ServiceTypes=SKG GUI/Plugin
X-KDE-Library=skg_advice
X-Krunner-ID=Advice plugin
X-KDE-PluginInfo-Author=Stephane MANKOWSKI,miraks
X-KDE-PluginInfo-Email=stephane@mankowski.fr
X-KDE-PluginInfo-Name=skg_advice
X-KDE-PluginInfo-Version=1.0
-X-KDE-PluginInfo-Website=http://skrooge.org/
+X-KDE-PluginInfo-Website=https://skrooge.org/
X-KDE-PluginInfo-Category=Plugins
X-KDE-PluginInfo-Depends=
X-KDE-PluginInfo-License=GPL
X-KDE-PluginInfo-EnabledByDefault=true
diff --git a/plugins/generic/skg_advice/skgadviceboardwidget.cpp b/plugins/generic/skg_advice/skgadviceboardwidget.cpp
index 3186e6e5c..c702afed9 100644
--- a/plugins/generic/skg_advice/skgadviceboardwidget.cpp
+++ b/plugins/generic/skg_advice/skgadviceboardwidget.cpp
@@ -1,463 +1,463 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is plugin for advice.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgadviceboardwidget.h"
#include <qdom.h>
#include <qlayoutitem.h>
#include <qmenu.h>
#include <qpushbutton.h>
#include <qtoolbutton.h>
#include <klocalizedstring.h>
#include "skgdocument.h"
#include "skginterfaceplugin.h"
#include "skgmainpanel.h"
#include "skgservices.h"
#include "skgtraces.h"
#include "skgtransactionmng.h"
SKGAdviceBoardWidget::SKGAdviceBoardWidget(QWidget* iParent, SKGDocument* iDocument)
: SKGBoardWidget(iParent, iDocument, i18nc("Dashboard widget title", "Advices")), m_maxAdvice(7), m_refreshNeeded(true), m_refresh(nullptr), m_inapplyall(false)
{
SKGTRACEINFUNC(10)
// Create menu
setContextMenuPolicy(Qt::ActionsContextMenu);
auto g = new QWidget(this);
m_layout = new QFormLayout(g);
m_layout->setContentsMargins(0, 0, 0, 0);
m_layout->setObjectName(QStringLiteral("Slayout"));
m_layout->setFieldGrowthPolicy(QFormLayout::ExpandingFieldsGrow);
m_layout->setHorizontalSpacing(1);
m_layout->setVerticalSpacing(1);
setMainWidget(g);
// menu
auto menuResetAdvice = new QAction(SKGServices::fromTheme(QStringLiteral("edit-undo")), i18nc("Noun, a user action", "Activate all advice"), this);
connect(menuResetAdvice, &QAction::triggered, this, &SKGAdviceBoardWidget::activateAllAdvice);
addAction(menuResetAdvice);
auto sep = new QAction(this);
sep->setSeparator(true);
addAction(sep);
m_menuAuto = new QAction(i18nc("Noun, a type of refresh for advice", "Automatic refresh"), this);
m_menuAuto->setCheckable(true);
m_menuAuto->setChecked(true);
connect(m_menuAuto, &QAction::triggered, this, &SKGAdviceBoardWidget::dataModifiedNotForce);
addAction(m_menuAuto);
// Refresh
connect(getDocument(), &SKGDocument::transactionSuccessfullyEnded, this, &SKGAdviceBoardWidget::dataModifiedNotForce, Qt::QueuedConnection);
connect(SKGMainPanel::getMainPanel(), &SKGMainPanel::currentPageChanged, this, &SKGAdviceBoardWidget::pageChanged, Qt::QueuedConnection);
connect(this, &SKGAdviceBoardWidget::refreshNeeded, this, [ = ]() {
this->dataModifiedNotForce();
}, Qt::QueuedConnection);
}
SKGAdviceBoardWidget::~SKGAdviceBoardWidget()
{
SKGTRACEINFUNC(10)
m_menuAuto = nullptr;
m_refresh = nullptr;
}
QString SKGAdviceBoardWidget::getState()
{
QDomDocument doc(QStringLiteral("SKGML"));
doc.setContent(SKGBoardWidget::getState());
QDomElement root = doc.documentElement();
root.setAttribute(QStringLiteral("maxAdvice"), SKGServices::intToString(m_maxAdvice));
root.setAttribute(QStringLiteral("automatic"), (m_menuAuto->isChecked() ? QStringLiteral("Y") : QStringLiteral("N")));
return doc.toString();
}
void SKGAdviceBoardWidget::setState(const QString& iState)
{
SKGBoardWidget::setState(iState);
QDomDocument doc(QStringLiteral("SKGML"));
doc.setContent(iState);
QDomElement root = doc.documentElement();
QString maxAdviceS = root.attribute(QStringLiteral("maxAdvice"));
if (maxAdviceS.isEmpty()) {
maxAdviceS = '7';
}
m_maxAdvice = SKGServices::stringToInt(maxAdviceS);
QString automatic = root.attribute(QStringLiteral("automatic"));
if (automatic.isEmpty()) {
automatic = 'Y';
}
if (m_menuAuto != nullptr) {
bool previous = m_menuAuto->blockSignals(true);
m_menuAuto->setChecked(automatic == QStringLiteral("Y"));
m_menuAuto->blockSignals(previous);
}
dataModifiedForce();
}
void SKGAdviceBoardWidget::pageChanged()
{
if (m_refreshNeeded) {
dataModifiedNotForce();
}
}
void SKGAdviceBoardWidget::dataModifiedNotForce()
{
dataModified(false);
}
void SKGAdviceBoardWidget::dataModifiedForce()
{
dataModified(true);
}
void SKGAdviceBoardWidget::dataModified(bool iForce)
{
SKGTRACEINFUNC(10)
SKGTabPage* page = SKGTabPage::parentTabPage(this);
if (m_inapplyall || (!iForce && ((page != nullptr && page != SKGMainPanel::getMainPanel()->currentPage()) || !m_menuAuto->isChecked()))) {
m_refreshNeeded = true;
if (m_refresh != nullptr) {
m_refresh->show();
}
return;
}
QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
m_refreshNeeded = false;
// Remove all item of the layout
while (m_layout->count() != 0) {
QLayoutItem* child = m_layout->takeAt(0);
if (child != nullptr) {
QWidget* w = child->widget();
delete w;
delete child;
}
}
// Get list of advice
double elapse = SKGServices::getMicroTime();
SKGAdviceList globalAdviceList = SKGMainPanel::getMainPanel()->getAdvice();
elapse = SKGServices::getMicroTime() - elapse;
// Get list of ignored advice
QString currentMonth = QDate::currentDate().toString(QStringLiteral("yyyy-MM"));
QStringList ignoredAdvice = getDocument()->getParameters(QStringLiteral("advice"), "t_value='I' OR t_value='I_" % currentMonth % '\'');
if (elapse > 3000 && m_menuAuto->isChecked() && !ignoredAdvice.contains(QStringLiteral("skgadviceboardwidget_verylong"))) {
SKGAdvice ad;
ad.setUUID(QStringLiteral("skgadviceboardwidget_verylong"));
ad.setPriority(2);
ad.setShortMessage(i18nc("Advice on making the best (short)", "Advice are very long to compute"));
ad.setLongMessage(i18nc("Advice on making the best (long)", "To improve performances, you should switch the widget in 'Manual refresh' (see contextual menu)."));
globalAdviceList.push_back(ad);
}
// Fill layout
int nbDisplayedAdvice = 0;
int nb = globalAdviceList.count();
m_recommendedActions.clear();
for (int i = 0; i < m_maxAdvice && i < nb; ++i) {
// Get advice
const SKGAdvice& ad = globalAdviceList.at(i);
// Create icon
QString iconName = (ad.getPriority() == -1 ? QStringLiteral("dialog-information") : ad.getPriority() >= 8 ? QStringLiteral("security-low") : ad.getPriority() <= 4 ? QStringLiteral("security-high") : QStringLiteral("security-medium"));
QString toolTipString = i18n("<p><b>Priority %1:</b>%2</p>", SKGServices::intToString(ad.getPriority()), ad.getLongMessage());
// Add ignored action
SKGAdvice::SKGAdviceActionList autoCorrections = ad.getAutoCorrections();
{
SKGAdvice::SKGAdviceAction dismiss;
dismiss.Title = i18nc("Dismiss an advice provided", "Dismiss");
dismiss.IconName = QStringLiteral("edit-delete");
dismiss.IsRecommended = false;
autoCorrections.push_back(dismiss);
}
{
SKGAdvice::SKGAdviceAction dismiss;
dismiss.Title = i18nc("Dismiss an advice provided", "Dismiss during current month");
dismiss.IconName = QStringLiteral("edit-delete");
dismiss.IsRecommended = false;
autoCorrections.push_back(dismiss);
}
{
SKGAdvice::SKGAdviceAction dismiss;
dismiss.Title = i18nc("Dismiss an advice provided", "Dismiss this kind");
dismiss.IconName = QStringLiteral("edit-delete");
dismiss.IsRecommended = false;
autoCorrections.push_back(dismiss);
}
{
SKGAdvice::SKGAdviceAction dismiss;
dismiss.Title = i18nc("Dismiss an advice provided", "Dismiss this kind during current month");
dismiss.IconName = QStringLiteral("edit-delete");
dismiss.IsRecommended = false;
autoCorrections.push_back(dismiss);
}
int nbSolution = autoCorrections.count();
// Build button
QStringList overlays;
overlays.push_back(nbSolution > 2 ? QStringLiteral("system-run") : QStringLiteral("edit-delete"));
auto icon = new QToolButton(this);
icon->setObjectName(ad.getUUID());
icon->setIcon(SKGServices::fromTheme(iconName, overlays));
icon->setIconSize(QSize(24, 24));
icon->setMaximumSize(QSize(24, 24));
icon->setCursor(Qt::PointingHandCursor);
icon->setAutoRaise(true);
auto menu = new QMenu(this);
menu->setIcon(icon->icon());
for (int k = 0; k < nbSolution; ++k) {
SKGAdvice::SKGAdviceAction adviceAction = autoCorrections.at(k);
QString actionText = adviceAction.Title;
QAction* action = SKGMainPanel::getMainPanel()->getGlobalAction(QString(actionText).remove(QStringLiteral("skg://")), false);
QAction* act;
if (action != nullptr) {
// This is an action
act = menu->addAction(action->icon(), action->text(), SKGMainPanel::getMainPanel(), static_cast<bool (SKGMainPanel::*)()>(&SKGMainPanel::openPage));
act->setData(actionText);
} else {
// This is a text
act = menu->addAction(SKGServices::fromTheme(adviceAction.IconName.isEmpty() ? QStringLiteral("system-run") : adviceAction.IconName), autoCorrections.at(k).Title, this, &SKGAdviceBoardWidget::adviceClicked);
if (act != nullptr) {
act->setProperty("id", ad.getUUID());
act->setProperty("solution", k < nbSolution - 4 ? k : k - nbSolution);
}
}
if ((act != nullptr) && adviceAction.IsRecommended) {
act->setToolTip(act->text());
act->setText(act->text() % i18nc("To recommend this action", " (recommended)"));
m_recommendedActions.append(act);
}
}
icon->setMenu(menu);
icon->setPopupMode(QToolButton::InstantPopup);
icon->setToolTip(toolTipString);
// Create text
auto label = new QLabel(this);
label->setText(ad.getShortMessage());
label->setToolTip(toolTipString);
// Add them
m_layout->addRow(icon, label);
++nbDisplayedAdvice;
}
// Add apply all recommended actions
QPushButton* apply = nullptr;
int nb2 = m_recommendedActions.count();
if (nb2 != 0) {
apply = new QPushButton(this);
apply->setIcon(SKGServices::fromTheme(QStringLiteral("games-solve")));
apply->setIconSize(QSize(22, 22));
apply->setMaximumSize(QSize(22, 22));
apply->setCursor(Qt::PointingHandCursor);
QString ToolTip;
for (int i = 0; i < nb2; ++i) {
if (i > 0) {
ToolTip += '\n';
}
ToolTip += m_recommendedActions.at(i)->toolTip();
}
apply->setToolTip(ToolTip);
connect(apply, &QPushButton::clicked, this, &SKGAdviceBoardWidget::applyRecommended, Qt::QueuedConnection);
}
// Add more
if (nb > m_maxAdvice) {
auto more = new QPushButton(this);
more->setIcon(SKGServices::fromTheme(QStringLiteral("arrow-down-double")));
more->setIconSize(QSize(22, 22));
more->setMaximumSize(QSize(22, 22));
more->setCursor(Qt::PointingHandCursor);
more->setToolTip(i18nc("Information message", "Display all advices"));
connect(more, &QPushButton::clicked, this, &SKGAdviceBoardWidget::moreAdvice, Qt::QueuedConnection);
if (apply != nullptr) {
m_layout->addRow(more, apply);
apply = nullptr;
} else {
m_layout->addRow(more, new QLabel(this));
}
} else if (nbDisplayedAdvice > 7) {
// Add less
auto less = new QPushButton(this);
less->setIcon(SKGServices::fromTheme(QStringLiteral("arrow-up-double")));
less->setIconSize(QSize(22, 22));
less->setMaximumSize(QSize(22, 22));
less->setCursor(Qt::PointingHandCursor);
less->setToolTip(i18nc("Information message", "Display less advices"));
connect(less, &QPushButton::clicked, this, &SKGAdviceBoardWidget::lessAdvice, Qt::QueuedConnection);
if (apply != nullptr) {
m_layout->addRow(less, apply);
apply = nullptr;
} else {
m_layout->addRow(less, new QLabel(this));
}
}
if (apply != nullptr) {
m_layout->addRow(apply, new QLabel(this));
}
// Add manual refresh button
m_refresh = new QPushButton(this);
m_refresh->setIcon(SKGServices::fromTheme(QStringLiteral("view-refresh")));
m_refresh->setIconSize(QSize(22, 22));
m_refresh->setMaximumSize(QSize(22, 22));
m_refresh->setCursor(Qt::PointingHandCursor);
m_refresh->setToolTip(i18nc("Information message", "Refresh advices"));
m_refresh->hide();
connect(m_refresh, &QPushButton::clicked, this, &SKGAdviceBoardWidget::dataModifiedForce, Qt::QueuedConnection);
m_layout->addRow(m_refresh, new QLabel(this));
QApplication::restoreOverrideCursor();
}
void SKGAdviceBoardWidget::moreAdvice()
{
m_maxAdvice = 9999999;
dataModifiedForce();
}
void SKGAdviceBoardWidget::lessAdvice()
{
m_maxAdvice = 7;
dataModifiedForce();
}
void SKGAdviceBoardWidget::applyRecommended()
{
SKGError err;
SKGBEGINTRANSACTION(*getDocument(), i18nc("Noun, name of the user action", "Apply all recommended corrections"), err)
m_inapplyall = true;
int nb = m_recommendedActions.count();
for (int i = 0; i < nb; ++i) {
m_recommendedActions.at(i)->trigger();
}
m_inapplyall = false;
}
void SKGAdviceBoardWidget::activateAllAdvice()
{
SKGError err;
{
SKGBEGINTRANSACTION(*getDocument(), i18nc("Noun, name of the user action", "Activate all advice"), err)
err = getDocument()->executeSqliteOrder(QStringLiteral("DELETE FROM parameters WHERE t_uuid_parent='advice'"));
}
// status bar
IFOKDO(err, SKGError(0, i18nc("Successful message after an user action", "Advice activated.")))
else {
err.addError(ERR_FAIL, i18nc("Error message", "Advice activation failed"));
}
SKGMainPanel::displayErrorMessage(err);
}
void SKGAdviceBoardWidget::adviceClicked()
{
// Get advice identifier
auto* act = qobject_cast< QAction* >(sender());
if (act != nullptr) {
QString uuid = act->property("id").toString();
if (!uuid.isEmpty()) {
// Get solution clicker
int solution = sender()->property("solution").toInt();
if (solution < 0) {
// We have to ignore this advice
SKGError err;
{
SKGBEGINLIGHTTRANSACTION(*getDocument(), i18nc("Noun, name of the user action", "Dismiss advice"), err)
QString currentMonth = QDate::currentDate().toString(QStringLiteral("yyyy-MM"));
// Create dismiss
if (solution == -1 || solution == -2) {
uuid = SKGServices::splitCSVLine(uuid, '|').at(0);
}
IFOKDO(err, getDocument()->setParameter(uuid, solution == -2 || solution == -4 ? QStringLiteral("I") :
QString("I_" % currentMonth), QVariant(), QStringLiteral("advice")))
// Delete useless dismiss
IFOKDO(err, getDocument()->executeSqliteOrder("DELETE FROM parameters WHERE t_uuid_parent='advice' AND t_value like 'I_ % ' AND t_value!='I_" % currentMonth % '\''))
}
// status bar
IFOKDO(err, SKGError(0, i18nc("Successful message after an user action", "Advice dismissed.")))
else {
err.addError(ERR_FAIL, i18nc("Error message", "Advice dismiss failed"));
}
} else {
// Get last transaction id
int previous = getDocument()->getTransactionToProcess(SKGDocument::UNDO);
// Execute the advice correction on all plugin
QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
int index = 0;
while (index >= 0) {
SKGInterfacePlugin* plugin = SKGMainPanel::getMainPanel()->getPluginByIndex(index);
if (plugin != nullptr) {
SKGError err = plugin->executeAdviceCorrection(uuid, solution);
if (!err || err.getReturnCode() != ERR_NOTIMPL) {
// The correction has been done or failed. This is the end.
index = -2;
}
} else {
index = -2;
}
++index;
}
// Get last transaction id
int next = getDocument()->getTransactionToProcess(SKGDocument::UNDO);
// If this is the same transaction, it means that an action has been done outside the document ==> a refresh is needed
if (next == previous) {
emit refreshNeeded();
}
QApplication::restoreOverrideCursor();
}
}
}
}
diff --git a/plugins/generic/skg_advice/skgadviceboardwidget.h b/plugins/generic/skg_advice/skgadviceboardwidget.h
index 69c4823c1..182ea1311 100644
--- a/plugins/generic/skg_advice/skgadviceboardwidget.h
+++ b/plugins/generic/skg_advice/skgadviceboardwidget.h
@@ -1,92 +1,92 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGADVICEBOARDWIDGET_H
#define SKGADVICEBOARDWIDGET_H
/** @file
* This file is plugin for advice.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgboardwidget.h"
class QFormLayout;
class QAction;
class QPushButton;
/**
* This file is plugin for advice
*/
class SKGAdviceBoardWidget : public SKGBoardWidget
{
Q_OBJECT
public:
/**
* Default Constructor
* @param iParent the parent widget
* @param iDocument the document*
*/
explicit SKGAdviceBoardWidget(QWidget* iParent, SKGDocument* iDocument);
/**
* Default Destructor
*/
~SKGAdviceBoardWidget() override;
/**
* Get the current state
* MUST BE OVERWRITTEN
* @return a string containing all information needed to set the same state.
* Could be an XML stream
*/
QString getState() override;
/**
* Set the current state
* MUST BE OVERWRITTEN
* @param iState must be interpreted to set the state of the widget
*/
void setState(const QString& iState) override;
Q_SIGNALS:
void refreshNeeded();
private Q_SLOTS:
void pageChanged();
void dataModifiedNotForce();
void dataModifiedForce();
void dataModified(bool iForce = false);
void adviceClicked();
void activateAllAdvice();
void moreAdvice();
void lessAdvice();
void applyRecommended();
private:
Q_DISABLE_COPY(SKGAdviceBoardWidget)
int m_maxAdvice;
bool m_refreshNeeded;
QAction* m_menuAuto;
QPushButton* m_refresh;
QFormLayout* m_layout;
QList<QAction*> m_recommendedActions;
bool m_inapplyall;
};
#endif // SKGADVICEBOARDWIDGET_H
diff --git a/plugins/generic/skg_advice/skgadviceplugin.cpp b/plugins/generic/skg_advice/skgadviceplugin.cpp
index 18e2eab70..17b1c872b 100644
--- a/plugins/generic/skg_advice/skgadviceplugin.cpp
+++ b/plugins/generic/skg_advice/skgadviceplugin.cpp
@@ -1,115 +1,115 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* A plugin to advice
*
* @author Stephane MANKOWSKI
*/
#include "skgadviceplugin.h"
#include <kaboutdata.h>
#include <kactioncollection.h>
#include <kpluginfactory.h>
#include <kstandardaction.h>
#include "skgadviceboardwidget.h"
#include "skgmainpanel.h"
#include "skgtipofdayboardwidget.h"
#include "skgtraces.h"
/**
* This plugin factory.
*/
K_PLUGIN_FACTORY(SKGAdvicePluginFactory, registerPlugin<SKGAdvicePlugin>();)
SKGAdvicePlugin::SKGAdvicePlugin(QWidget* iWidget, QObject* iParent, const QVariantList& /*iArg*/) : SKGInterfacePlugin(iParent), currentDocument(nullptr)
{
SKGTRACEINFUNC(10)
Q_UNUSED(iWidget)
}
SKGAdvicePlugin::~SKGAdvicePlugin()
{
SKGTRACEINFUNC(10)
currentDocument = nullptr;
}
bool SKGAdvicePlugin::setupActions(SKGDocument* iDocument)
{
SKGTRACEINFUNC(10)
currentDocument = iDocument;
setComponentName(QStringLiteral("skg_advice"), title());
setXMLFile(QStringLiteral("skg_advice.rc"));
// Create yours actions here
return true;
}
int SKGAdvicePlugin::getNbDashboardWidgets()
{
SKGTRACEINFUNC(1)
return 2;
}
QString SKGAdvicePlugin::getDashboardWidgetTitle(int iIndex)
{
SKGTRACEINFUNC(1)
if (iIndex == 0) {
return i18nc("Noun, a list of items", "Advice");
}
return i18nc("Noun, a list of items", "Tip of the day");
}
SKGBoardWidget* SKGAdvicePlugin::getDashboardWidget(int iIndex)
{
if (iIndex == 0) {
return new SKGAdviceBoardWidget(SKGMainPanel::getMainPanel(), currentDocument);
}
return new SKGTipOfDayBoardWidget(SKGMainPanel::getMainPanel(), currentDocument);
}
QString SKGAdvicePlugin::title() const
{
return i18nc("The title", "Advice");
}
QString SKGAdvicePlugin::icon() const
{
return QStringLiteral("help-hint");
}
QString SKGAdvicePlugin::toolTip() const
{
return i18nc("The tool tip", "Advice");
}
int SKGAdvicePlugin::getOrder() const
{
return 1;
}
QStringList SKGAdvicePlugin::tips() const
{
QStringList output;
output.push_back(i18nc("Description of a tip", "<p>... Skrooge can give you advice on how to manage your accounts. See the <a href=\"skg://dashboard_plugin\">dashboard</a>.</p>"));
output.push_back(i18nc("Description of a tip", "<p>... Skrooge can automatically apply recommended corrections. See the <a href=\"skg://dashboard_plugin\">dashboard</a>.</p>"));
return output;
}
#include <skgadviceplugin.moc>
diff --git a/plugins/generic/skg_advice/skgadviceplugin.h b/plugins/generic/skg_advice/skgadviceplugin.h
index 48b10116c..461f8f71a 100644
--- a/plugins/generic/skg_advice/skgadviceplugin.h
+++ b/plugins/generic/skg_advice/skgadviceplugin.h
@@ -1,113 +1,113 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGADVICEPLUGIN_H
#define SKGADVICEPLUGIN_H
/** @file
* A plugin to advice.
*
* @author Stephane MANKOWSKI
*/
#include <qvariant.h>
#include "skginterfaceplugin.h"
/**
* A plugin to advice
*/
class SKGAdvicePlugin : public SKGInterfacePlugin
{
Q_OBJECT
Q_INTERFACES(SKGInterfacePlugin)
public:
/**
* Default Constructor
*/
explicit SKGAdvicePlugin(QWidget* iWidget, QObject* iParent, const QVariantList& iArg);
/**
* Default Destructor
*/
~SKGAdvicePlugin() override;
/**
* Called to initialise the plugin
* @param iDocument the main document
* @return true if the plugin is compatible with the document
*/
bool setupActions(SKGDocument* iDocument) override;
/**
* The number of dashboard widgets of the plugin.
* @return The number of dashboard widgets of the plugin
*/
int getNbDashboardWidgets() override;
/**
* Get a dashboard widget title of the plugin.
* @param iIndex the index of the widget
* @return The title
*/
QString getDashboardWidgetTitle(int iIndex) override;
/**
* Get a dashboard widget of the plugin.
* @param iIndex the index of the widget
* @return The dashboard widget of the plugin
*/
SKGBoardWidget* getDashboardWidget(int iIndex) override;
/**
* The title of the plugin.
* @return The title of the plugin
*/
QString title() const override;
/**
* The icon of the plugin.
* @return The icon of the plugin
*/
QString icon() const override;
/**
* The toolTip of the plugin.
* @return The toolTip of the plugin
*/
QString toolTip() const override;
/**
* The tips list of the plugin.
* @return The tips list of the plugin
*/
QStringList tips() const override;
/**
* Must be implemented to set the position of the plugin.
* @return integer value between 0 and 999 (default = 999)
*/
int getOrder() const override;
private Q_SLOTS:
private:
Q_DISABLE_COPY(SKGAdvicePlugin)
SKGDocument* currentDocument;
};
#endif // SKGADVICEPLUGIN_H
diff --git a/plugins/generic/skg_advice/skgtipofdayboardwidget.cpp b/plugins/generic/skg_advice/skgtipofdayboardwidget.cpp
index 9700bfc99..33d6e73ee 100644
--- a/plugins/generic/skg_advice/skgtipofdayboardwidget.cpp
+++ b/plugins/generic/skg_advice/skgtipofdayboardwidget.cpp
@@ -1,69 +1,69 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is plugin for tip of day.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgtipofdayboardwidget.h"
#include <qfileinfo.h>
#include <klocalizedstring.h>
#include <kcolorscheme.h>
#include "skgmainpanel.h"
#include "skgservices.h"
#include "skgtraces.h"
SKGTipOfDayBoardWidget::SKGTipOfDayBoardWidget(QWidget* iParent, SKGDocument* iDocument)
: SKGBoardWidget(iParent, iDocument, i18nc("Dashboard widget title", "Tip of the day"))
{
SKGTRACEINFUNC(10)
auto f = new QFrame();
ui.setupUi(f);
setMainWidget(f);
ui.kIcon->setIcon(SKGServices::fromTheme(QStringLiteral("ktip")));
onModified();
connect(ui.kIcon, &QPushButton::clicked, this, &SKGTipOfDayBoardWidget::onModified);
connect(ui.kText, &QLabel::linkActivated, this, [ = ](const QString & val) {
SKGMainPanel::getMainPanel()->openPage(val);
});
// Refresh
connect(getDocument(), &SKGDocument::transactionSuccessfullyEnded, this, &SKGTipOfDayBoardWidget::onModified, Qt::QueuedConnection);
}
SKGTipOfDayBoardWidget::~SKGTipOfDayBoardWidget()
{
SKGTRACEINFUNC(10)
}
void SKGTipOfDayBoardWidget::onModified()
{
auto text = SKGMainPanel::getMainPanel()->getTipOfDay();
// Remove color of hyperlinks
KColorScheme scheme(QPalette::Normal, KColorScheme::Window);
auto color = scheme.foreground(KColorScheme::NormalText).color().name().right(6);
text = text.replace(QStringLiteral("<a href"), QStringLiteral("<a style=\"color: #") + color + ";\" href");
ui.kText->setText(text);
}
diff --git a/plugins/generic/skg_advice/skgtipofdayboardwidget.h b/plugins/generic/skg_advice/skgtipofdayboardwidget.h
index c4f097f9c..f83364e3d 100644
--- a/plugins/generic/skg_advice/skgtipofdayboardwidget.h
+++ b/plugins/generic/skg_advice/skgtipofdayboardwidget.h
@@ -1,56 +1,56 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGTIPOFDAYBOARDWIDGET_H
#define SKGTIPOFDAYBOARDWIDGET_H
/** @file
* This file is a plugin for tip of day.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgboardwidget.h"
#include "ui_skgtipofdayboardwidget.h"
/**
* This file is a plugin for tip of day
*/
class SKGTipOfDayBoardWidget : public SKGBoardWidget
{
Q_OBJECT
public:
/**
* Default Constructor
* @param iParent the parent widget
* @param iDocument the document
*/
explicit SKGTipOfDayBoardWidget(QWidget* iParent, SKGDocument* iDocument);
/**
* Default Destructor
*/
~SKGTipOfDayBoardWidget() override;
private Q_SLOTS:
void onModified();
private:
Q_DISABLE_COPY(SKGTipOfDayBoardWidget)
Ui::skgtipofdayboardwidget ui{};
};
#endif // SKGTIPOFDAYBOARDWIDGET_H
diff --git a/plugins/generic/skg_bookmark/CMakeLists.txt b/plugins/generic/skg_bookmark/CMakeLists.txt
index 92717c431..4c42d7f13 100644
--- a/plugins/generic/skg_bookmark/CMakeLists.txt
+++ b/plugins/generic/skg_bookmark/CMakeLists.txt
@@ -1,36 +1,36 @@
#***************************************************************************
#* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
#* *
#* 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 <http://www.gnu.org/licenses/> *
+#* along with this program. If not, see <https://www.gnu.org/licenses/> *
#***************************************************************************
MESSAGE( STATUS "..:: CMAKE PLUGIN_BOOKMARK ::..")
PROJECT(plugin_bookmark)
LINK_DIRECTORIES (${LIBRARY_OUTPUT_PATH})
SET(skg_bookmark_SRCS skgbookmarkplugin.cpp skgbookmarkplugindockwidget.cpp)
ki18n_wrap_ui(skg_bookmark_SRCS skgbookmarkplugindockwidget_base.ui skgbookmarkpluginwidget_pref.ui)
kconfig_add_kcfg_files(skg_bookmark_SRCS skgbookmark_settings.kcfgc )
ADD_LIBRARY(skg_bookmark MODULE ${skg_bookmark_SRCS})
TARGET_LINK_LIBRARIES(skg_bookmark KF5::Parts KF5::ItemViews KF5::IconThemes skgbasemodeler skgbasegui )
########### install files ###############
INSTALL(TARGETS skg_bookmark DESTINATION ${KDE_INSTALL_QTPLUGINDIR})
INSTALL(FILES ${PROJECT_SOURCE_DIR}/skgbookmark_settings.kcfg DESTINATION ${KDE_INSTALL_KCFGDIR} )
INSTALL(FILES ${PROJECT_SOURCE_DIR}/org.kde.skg-plugin-bookmark.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR})
INSTALL(FILES ${PROJECT_SOURCE_DIR}/skg_bookmark.rc DESTINATION ${KDE_INSTALL_KXMLGUI5DIR}/skg_bookmark )
diff --git a/plugins/generic/skg_bookmark/org.kde.skg-plugin-bookmark.desktop b/plugins/generic/skg_bookmark/org.kde.skg-plugin-bookmark.desktop
index f8c73c418..0b8063e13 100644
--- a/plugins/generic/skg_bookmark/org.kde.skg-plugin-bookmark.desktop
+++ b/plugins/generic/skg_bookmark/org.kde.skg-plugin-bookmark.desktop
@@ -1,77 +1,77 @@
[Desktop Entry]
Name=Bookmark plugin
Name[bs]=Dodatak za markere
Name[ca]=Connector de punts
Name[ca@valencia]=Connector de punts
Name[cs]=Modul pro záložky
Name[da]=Bogmærke-plugin
Name[de]=Lesezeichen-Modul
Name[el]=Bookmark plugin
Name[en_GB]=Bookmark plugin
Name[es]=Complemento de marcadores
Name[et]=Järjehoidjaplugin
Name[fi]=Kirjanmerkkiliitännäinen
Name[fr]=Module externe de signets
Name[gl]=Complemento de marcadores
Name[hu]=Könyvjelző bővítmény
Name[it]=Estensione per segnalibri
Name[lt]=Žymelių papildinys
Name[nb]=Bokmerkemodul
Name[nds]=Leestekenmoduul
Name[nl]=Plugin voor bladwijzer
Name[pl]=Wtyczka zakładek
Name[pt]='Plugin' de favoritos
Name[pt_BR]=Plugin de favoritos
Name[ru]=Модуль закладок
Name[sk]=Plugin záložiek
Name[sv]=Bokmärkesinsticksprogram
Name[tr]=Yer imi eklentisi
Name[uk]=Додаток закладок
Name[x-test]=xxBookmark pluginxx
Name[zh_CN]=书签插件
Name[zh_TW]=書籤外掛程式
Comment=A plugin for bookmarks
Comment[bs]=Dodatak za markere
Comment[ca]=Un connector de punts
Comment[ca@valencia]=Un connector de punts
Comment[cs]=Modul pro záložky
Comment[da]=Et plugin til bogmærker
Comment[de]=Ein Modul für Lesezeichen
Comment[el]=Ένα πρόσθετο για σελιδοδείκτες
Comment[en_GB]=A plugin for bookmarks
Comment[es]=Un complemento para marcadores
Comment[et]=Järjehoidjate plugin
Comment[fi]=Kirjanmerkkiliitännäinen
Comment[fr]=Un module externe pour les signets
Comment[gl]=Un complemento para marcadores.
Comment[hu]=Egy bővítmény a könyvjelzőkhöz
Comment[it]=Un'estensione per i segnalibri
Comment[lt]=Papildinys žymelėms
Comment[nb]=Et programtillegg for bokmerker
Comment[nds]=En Leestekenmoduul
Comment[nl]=Een plugin voor bladwijzers
Comment[pl]=Wtyczka do zakładek
Comment[pt]=Um 'plugin' para favoritos
Comment[pt_BR]=Um plugin para favoritos
Comment[ru]=Модуль закладок
Comment[sk]=Plugin pre záložky
Comment[sv]=Ett insticksprogram för bokmärken
Comment[tr]=Yer imleri için bir eklenti
Comment[uk]=Додаток для роботи з закладками
Comment[x-test]=xxA plugin for bookmarksxx
Comment[zh_TW]=書籤外掛程式
Encoding=UTF-8
Icon=quickopen
Type=Service
X-KDE-ServiceTypes=SKG GUI/Plugin
X-KDE-Library=skg_bookmark
X-Krunner-ID=Bookmark plugin
X-KDE-PluginInfo-Author=Stephane MANKOWSKI,miraks
X-KDE-PluginInfo-Email=stephane@mankowski.fr
X-KDE-PluginInfo-Name=skg_bookmark
X-KDE-PluginInfo-Version=1.0
-X-KDE-PluginInfo-Website=http://skrooge.org/
+X-KDE-PluginInfo-Website=https://skrooge.org/
X-KDE-PluginInfo-Category=Plugins
X-KDE-PluginInfo-Depends=
X-KDE-PluginInfo-License=GPL
X-KDE-PluginInfo-EnabledByDefault=true
diff --git a/plugins/generic/skg_bookmark/skgbookmarkplugin.cpp b/plugins/generic/skg_bookmark/skgbookmarkplugin.cpp
index 310296f56..0fe9ab870 100644
--- a/plugins/generic/skg_bookmark/skgbookmarkplugin.cpp
+++ b/plugins/generic/skg_bookmark/skgbookmarkplugin.cpp
@@ -1,368 +1,368 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is a plugin for bookmarks management.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgbookmarkplugin.h"
#include <qwidget.h>
#include <kaboutdata.h>
#include <kactioncollection.h>
#include <kpluginfactory.h>
#include <ktoolbarpopupaction.h>
#include "skgbookmark_settings.h"
#include "skgbookmarkplugindockwidget.h"
#include "skgerror.h"
#include "skgmainpanel.h"
#include "skgnodeobject.h"
#include "skgservices.h"
#include "skgtraces.h"
#include "skgtransactionmng.h"
/**
* This plugin factory.
*/
K_PLUGIN_FACTORY(SKGBookmarkPluginFactory, registerPlugin<SKGBookmarkPlugin>();)
SKGBookmarkPlugin::SKGBookmarkPlugin(QWidget* iWidget, QObject* iParent, const QVariantList& iArg) :
SKGInterfacePlugin(iParent), m_currentDocument(nullptr), m_dockWidget(nullptr), m_bookmarkMenu(nullptr)
{
Q_UNUSED(iArg)
Q_UNUSED(iWidget)
SKGTRACEINFUNC(10)
}
SKGBookmarkPlugin::~SKGBookmarkPlugin()
{
SKGTRACEINFUNC(10)
m_currentDocument = nullptr;
m_dockWidget = nullptr;
m_bookmarkMenu = nullptr;
}
bool SKGBookmarkPlugin::setupActions(SKGDocument* iDocument)
{
SKGTRACEINFUNC(10)
m_currentDocument = iDocument;
setComponentName(QStringLiteral("skg_bookmark"), title());
setXMLFile(QStringLiteral("skg_bookmark.rc"));
m_dockWidget = new QDockWidget(SKGMainPanel::getMainPanel());
m_dockWidget->setObjectName(QStringLiteral("skg_bookmark_docwidget"));
m_dockWidget->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
m_dockWidget->setWindowTitle(title());
m_dockWidget->setWidget(new SKGBookmarkPluginDockWidget(m_dockWidget, m_currentDocument));
// add action to control hide / display of Bookmarks
QAction* toggle = m_dockWidget->toggleViewAction();
QAction* panelAction = actionCollection()->addAction(QStringLiteral("view_bookmarks"));
registerGlobalAction(QStringLiteral("view_bookmarks"), panelAction);
panelAction->setCheckable(true);
panelAction->setChecked(toggle->isChecked());
panelAction->setText(toggle->text());
actionCollection()->setDefaultShortcut(panelAction, Qt::SHIFT + Qt::Key_F10);
connect(panelAction, &QAction::triggered, toggle, &QAction::trigger);
connect(toggle, &QAction::toggled, panelAction, &QAction::setChecked);
// Import bookmarks
QStringList overlaybookmarks;
overlaybookmarks.push_back(icon());
auto actImportStdBookmark = new QAction(SKGServices::fromTheme(QStringLiteral("document-import"), overlaybookmarks), i18nc("Verb", "Import standard bookmarks"), this);
connect(actImportStdBookmark, &QAction::triggered, this, &SKGBookmarkPlugin::importStandardBookmarks);
registerGlobalAction(QStringLiteral("import_standard_bookmarks"), actImportStdBookmark);
//
QAction* goHomeAction = KStandardAction::home(this, SLOT(goHome()), actionCollection());
goHomeAction->setPriority(QAction::LowPriority);
registerGlobalAction(QStringLiteral("go_home"), goHomeAction);
// Bookmark
auto actBookmark = new KToolBarPopupAction(SKGServices::fromTheme(QStringLiteral("bookmark-new-list")), i18nc("Verb, action to display bookmarks", "Bookmarks"), this);
connect(actBookmark, &KToolBarPopupAction::triggered, this, &SKGBookmarkPlugin::onOpenBookmark);
m_bookmarkMenu = actBookmark->menu();
if (m_bookmarkMenu != nullptr) {
m_bookmarkMenu->setProperty("id", 0);
connect(m_bookmarkMenu, &QMenu::aboutToShow, this, &SKGBookmarkPlugin::onShowBookmarkMenu);
}
actBookmark->setStickyMenu(false);
actBookmark->setDelayed(false);
actBookmark->setData(0);
actBookmark->setPriority(QAction::LowPriority);
registerGlobalAction(QStringLiteral("edit_bookmark"), actBookmark);
return true;
}
QWidget* SKGBookmarkPlugin::getPreferenceWidget()
{
SKGTRACEINFUNC(10)
auto w = new QWidget();
ui.setupUi(w);
return w;
}
KConfigSkeleton* SKGBookmarkPlugin::getPreferenceSkeleton()
{
return skgbookmark_settings::self();
}
void SKGBookmarkPlugin::refresh()
{
SKGTRACEINFUNC(10)
if (m_dockWidget != nullptr) {
auto* p = qobject_cast<SKGBookmarkPluginDockWidget*>(m_dockWidget->widget());
if (p != nullptr) {
p->refresh();
}
}
if (m_currentDocument != nullptr) {
// Automatic bookmarks creation
if (m_currentDocument->getMainDatabase() != nullptr) {
QString doc_id = m_currentDocument->getUniqueIdentifier();
if (m_docUniqueIdentifier != doc_id) {
m_docUniqueIdentifier = doc_id;
bool exist = false;
SKGError err = m_currentDocument->existObjects(QStringLiteral("node"), QLatin1String(""), exist);
if (!err && !exist) {
importStandardBookmarks();
// The file is considered has not modified
m_currentDocument->setFileNotModified();
}
// Automatic open of autostart bookmark
if (!err && !(QApplication::keyboardModifiers() &Qt::ShiftModifier)) {
goHome();
}
}
}
}
}
QString SKGBookmarkPlugin::title() const
{
return i18nc("Noun, a bookmark as in a webbrowser bookmark", "Bookmarks");
}
QString SKGBookmarkPlugin::icon() const
{
return QStringLiteral("bookmarks");
}
QStringList SKGBookmarkPlugin::tips() const
{
QStringList output;
output.push_back(i18nc("Description of a tips", "<p>... some bookmarks can be opened automatically when the application is launched.</p>"));
output.push_back(i18nc("Description of a tips", "<p>... bookmarks can be reorganized by drag & drop.</p>"));
output.push_back(i18nc("Description of a tips", "<p>... a double click on a folder of bookmarks will open all the bookmarks it contains.</p>"));
output.push_back(i18nc("Description of a tips", "<p>... you can <a href=\"skg://import_standard_bookmarks\">import standard bookmarks</a>.</p>"));
return output;
}
int SKGBookmarkPlugin::getOrder() const
{
return 3;
}
QDockWidget* SKGBookmarkPlugin::getDockWidget()
{
return m_dockWidget;
}
void SKGBookmarkPlugin::importStandardBookmarks()
{
SKGTRACEINFUNC(10)
SKGError err;
SKGBEGINTRANSACTION(*m_currentDocument, i18nc("Noun, name of the user action", "Import standard bookmarks"), err)
QStringList bks;
bks << i18nc("Noun, bookmark name", "Dashboard") % "|N|dashboard-show|\"Dashboard plugin\";\"Dashboard\";\"<!DOCTYPE SKGML><parameters zoomPosition=\"\"0\"\"> <ITEM-1 zoom=\"\"0\"\" index=\"\"0\"\" name=\"\"Skrooge bank plugin\"\" state=\"\"&lt;!DOCTYPE SKGML>&#xa;&lt;parameters menuOther=&quot;Y&quot; menuCurrent=&quot;Y&quot; menuFavorite=&quot;N&quot; menuAssets=&quot;Y&quot; menuInvestment=&quot;Y&quot; menuCreditCard=&quot;Y&quot;/>&#xa;\"\"/> <ITEM-2 zoom=\"\"0\"\" index=\"\"0\"\" name=\"\"Skrooge operation plugin\"\" state=\"\"&lt;!DOCTYPE SKGML>"
"&#xa;&lt;parameters menuTransfert=&quot;Y&quot;/>&#xa;\"\"/> <ITEM-3 zoom=\"\"0\"\" index=\"\"1\"\" name=\"\"Skrooge operation plugin\"\" state=\"\"\"\"/> <ITEM-4 zoom=\"\"0\"\" index=\"\"0\"\" name=\"\"Skrooge scheduled plugin\"\" state=\"\"\"\"/> <ITEM-5 zoom=\"\"0\"\" index=\"\"0\"\" name=\"\"Skrooge search plugin\"\" state=\"\"&lt;!DOCTYPE SKGML>"
"&#xa;&lt;parameters menuFavorite=&quot;N&quot;/>&#xa;\"\"/> <ITEM-6 zoom=\"\"0\"\" index=\"\"0\"\" name=\"\"Skrooge unit plugin\"\" state=\"\"&lt;!DOCTYPE SKGML>&#xa;&lt;parameters menuShares=&quot;Y&quot; menuSharesOwnedOnly=&quot;N&quot; menuIndexes=&quot;Y&quot;/>&#xa;\"\"/> <ITEM-7 zoom=\"\"0\"\" index=\"\"0\"\" name=\"\"Skrooge calculator plugin\"\" state=\"\"\"\"/></parameters>\""
<< i18nc("Noun, bookmark name", "Report > Income vs Expenditure on 12 last months") % "|N|view-statistics|\"Skrooge report plugin\";\"Rapport\";\"<!DOCTYPE SKGML><parameters expenses=\"\"Y\"\" tableAndGraphState=\"\"&lt;!DOCTYPE SKGML>"
"&#xa;&lt;parameters graphMode=&quot;1&quot; graphicViewState=&quot;&amp;lt;!DOCTYPE SKGML>&amp;#xa;&amp;lt;parameters isToolBarVisible=&amp;quot;Y&amp;quot; antialiasing=&amp;quot;Y&amp;quot;/>&amp;#xa;&quot; splitterState=&quot;000000ff00000000000000020000025b0000032901000000060100000001&quot; bottomToolBarVisible=&quot;Y&quot; filter=&quot;&quot; legendVisible=&quot;N&quot; allPositive=&quot;Y&quot; linearRegressionVisible=&quot;Y&quot; sortColumn=&quot;0&quot; limitVisible=&quot;Y&quot; web=&quot;&amp;lt;!DOCTYPE SKGML>"
"&amp;#xa;&amp;lt;parameters zoomFactor=&amp;quot;0&amp;quot;/>&amp;#xa;&quot; sortOrder=&quot;0&quot;/>&#xa;\"\" mode=\"\"0\"\" period=\"\"3\"\" incomes=\"\"Y\"\" interval=\"\"2\"\" lines=\"\"t_TYPEEXPENSENLS\"\" lines2=\"\"#NOTHING#\"\" nbLevelLines=\"\"0\"\" nbLevelColumns=\"\"0\"\" forecast=\"\"0\"\" columns=\"\"d_DATEMONTH\"\" nb_intervals=\"\"12\"\" forecastValue=\"\"20\"\" transfers=\"\"N\"\" currentPage=\"\"0\"\"/>\""
<< i18nc("Noun, bookmark name", "Report > Pie categories in 12 last months") % "|N|view-statistics|\"Skrooge report plugin\";\"Rapport\";\"<!DOCTYPE SKGML><parameters expenses=\"\"Y\"\" tableAndGraphState=\"\"&lt;!DOCTYPE SKGML>&#xa;&lt;parameters graphMode=&quot;2&quot; graphicViewState=&quot;&amp;lt;!DOCTYPE SKGML>"
"&amp;#xa;&amp;lt;parameters isToolBarVisible=&amp;quot;Y&amp;quot; antialiasing=&amp;quot;Y&amp;quot;/>&amp;#xa;&quot; splitterState=&quot;000000ff00000000000000020000025b0000032901000000060100000001&quot; bottomToolBarVisible=&quot;Y&quot; filter=&quot;&quot; legendVisible=&quot;N&quot; allPositive=&quot;Y&quot; linearRegressionVisible=&quot;Y&quot; sortColumn=&quot;-1&quot; limitVisible=&quot;Y&quot; web=&quot;&amp;lt;!DOCTYPE SKGML>"
"&amp;#xa;&amp;lt;parameters zoomFactor=&amp;quot;0&amp;quot;/>&amp;#xa;&quot; sortOrder=&quot;0&quot;/>&#xa;\"\" mode=\"\"0\"\" period=\"\"3\"\" incomes=\"\"Y\"\" interval=\"\"2\"\" lines=\"\"t_REALCATEGORY\"\" lines2=\"\"#NOTHING#\"\" nbLevelLines=\"\"0\"\" nbLevelColumns=\"\"0\"\" forecast=\"\"0\"\" columns=\"\"d_DATEMONTH\"\" nb_intervals=\"\"12\"\" forecastValue=\"\"20\"\" transfers=\"\"N\"\" currentPage=\"\"0\"\"/>\""
<< i18nc("Noun, bookmark name", "Report > History") % "|N|view-statistics|\"Skrooge report plugin\";\"Rapport\";\"<!DOCTYPE SKGML><parameters expenses=\"\"Y\"\" tableAndGraphState=\"\"&lt;!DOCTYPE SKGML>"
"&#xa;&lt;parameters graphMode=&quot;1&quot; graphicViewState=&quot;&amp;lt;!DOCTYPE SKGML>&amp;#xa;&amp;lt;parameters isToolBarVisible=&amp;quot;Y&amp;quot; antialiasing=&amp;quot;Y&amp;quot;/>&amp;#xa;&quot; splitterState=&quot;000000ff0000000000000002000002b50000032601000000060100000001&quot; bottomToolBarVisible=&quot;Y&quot; filter=&quot;&quot; legendVisible=&quot;N&quot; allPositive=&quot;N&quot; linearRegressionVisible=&quot;Y&quot; sortColumn=&quot;-1&quot; limitVisible=&quot;Y&quot; web=&quot;&amp;lt;!DOCTYPE SKGML>"
"&amp;#xa;&amp;lt;parameters zoomFactor=&amp;quot;0&amp;quot;/>&amp;#xa;&quot; sortOrder=&quot;0&quot;/>&#xa;\"\" mode=\"\"1\"\" period=\"\"0\"\" incomes=\"\"Y\"\" interval=\"\"2\"\" lines=\"\"#NOTHING#\"\" lines2=\"\"#NOTHING#\"\" nbLevelLines=\"\"0\"\" nbLevelColumns=\"\"0\"\" forecast=\"\"0\"\" columns=\"\"d_DATEMONTH\"\" nb_intervals=\"\"1\"\" forecastValue=\"\"20\"\" transfers=\"\"Y\"\" currentPage=\"\"0\"\"/>\"";
for (const auto& bk : qAsConst(bks)) {
QStringList line = SKGServices::splitCSVLine(bk, '|', false);
if (line.count() == 4) {
SKGNodeObject node;
err = SKGNodeObject::createPathNode(m_currentDocument, line.at(0), node);
IFOKDO(err, node.setAutoStart(line.at(1) == QStringLiteral("Y")))
IFOKDO(err, node.setIcon(line.at(2)))
IFOKDO(err, node.setData(line.at(3)))
IFOKDO(err, node.save())
}
}
// status
IFOKDO(err, SKGError(0, i18nc("Successful message after an user action", "Standard bookmarks imported.")))
else {
err.addError(ERR_FAIL, i18nc("Error message", "Import standard bookmarks failed"));
}
// Display error
SKGMainPanel::displayErrorMessage(err);
}
void SKGBookmarkPlugin::goHome()
{
if (SKGMainPanel::getMainPanel() != nullptr) {
SKGMainPanel::getMainPanel()->closeAllPages(false); // Home do not close pinned pages
}
SKGObjectBase::SKGListSKGObjectBase oNodeList;
if (m_currentDocument != nullptr) {
m_currentDocument->getObjects(QStringLiteral("v_node"), QStringLiteral("t_autostart='Y' ORDER BY f_sortorder, t_name"), oNodeList);
}
int nbAutoStartedBookmarks = oNodeList.count();
for (int i = 0; i < nbAutoStartedBookmarks; ++i) {
SKGNodeObject autostarted_bookmark(oNodeList.at(i));
autostarted_bookmark.load();
SKGTRACEIN(10, "autostarting bookmark : " % autostarted_bookmark.getName())
SKGBookmarkPluginDockWidget::openBookmark(autostarted_bookmark, i > 0, true);
}
}
void SKGBookmarkPlugin::onOpenBookmark()
{
auto* callerAction = qobject_cast<QAction*>(this->sender());
if (callerAction != nullptr) {
SKGNodeObject node(m_currentDocument, callerAction->data().toInt());
SKGBookmarkPluginDockWidget::openBookmark(node, (QGuiApplication::mouseButtons() & Qt::MidButton) != 0u || (QApplication::keyboardModifiers() & Qt::ControlModifier) != 0u);
}
}
void SKGBookmarkPlugin::onAddBookmark()
{
SKGTRACEINFUNC(1)
SKGError err;
// Get current page
SKGNodeObject node;
{
// Get current selection
SKGNodeObject parentNode;
auto* callerAction = qobject_cast<QAction*>(this->sender());
if (callerAction != nullptr) {
parentNode = SKGNodeObject(m_currentDocument, callerAction->data().toInt());
}
// Create bookmark
err = SKGBookmarkPluginDockWidget::createNodeFromPage(SKGMainPanel::getMainPanel()->currentPage(), parentNode, node);
}
// status bar
IFOK(err) {
err = SKGError(0, i18nc("Successful message after an user action", "Bookmark created"));
}
SKGMainPanel::displayErrorMessage(err);
}
void SKGBookmarkPlugin::onShowBookmarkMenu()
{
auto* callerMenu = qobject_cast<QMenu*>(this->sender());
if ((callerMenu != nullptr) && (m_currentDocument != nullptr)) {
// Remove previous menu
callerMenu->clear();
// Build query
QString wc = QStringLiteral("rd_node_id=0 OR rd_node_id IS NULL OR rd_node_id=''");
int idParent = callerMenu->property("id").toInt();
if (idParent != 0) {
wc = "rd_node_id=" % SKGServices::intToString(idParent);
}
// Build new menu
SKGObjectBase::SKGListSKGObjectBase listNode;
m_currentDocument->getObjects(QStringLiteral("v_node"), wc % " ORDER BY f_sortorder, t_name", listNode);
int nb = listNode.count();
for (int i = 0; i < nb; ++i) {
SKGNodeObject node(listNode.at(i));
if (node.isFolder()) {
// This is a folder
auto menu = new QMenu(callerMenu);
if (menu != nullptr) {
callerMenu->addMenu(menu);
menu->setTitle(node.getName());
menu->setIcon(node.getIcon());
menu->setProperty("id", node.getID());
connect(menu, &QMenu::aboutToShow, this, &SKGBookmarkPlugin::onShowBookmarkMenu);
}
} else {
// This is a bookmark
auto act = new QAction(callerMenu);
if (act != nullptr) {
callerMenu->addAction(act);
act->setText(node.getName());
act->setIcon(node.getIcon());
act->setData(node.getID());
connect(act, &QAction::triggered, this, &SKGBookmarkPlugin::onOpenBookmark);
}
}
}
// Add separator
auto sep = new QAction(this);
sep->setSeparator(true);
callerMenu->addAction(sep);
// This common actions
{
// Open all
auto act = new QAction(callerMenu);
if (act != nullptr) {
callerMenu->addAction(act);
act->setText(i18nc("Action", "Open all"));
act->setIcon(SKGServices::fromTheme(QStringLiteral("quickopen")));
act->setData(idParent);
connect(act, &QAction::triggered, this, &SKGBookmarkPlugin::onOpenBookmark);
}
if (SKGMainPanel::getMainPanel()->currentPageIndex() >= 0) {
// Bookmark current here
auto act2 = new QAction(callerMenu);
if (act2 != nullptr) {
callerMenu->addAction(act2);
act2->setText(i18nc("Action", "Bookmark current page here"));
act2->setIcon(SKGServices::fromTheme(QStringLiteral("list-add")));
act2->setData(idParent);
connect(act2, &QAction::triggered, this, &SKGBookmarkPlugin::onAddBookmark);
}
}
}
}
}
#include <skgbookmarkplugin.moc>
diff --git a/plugins/generic/skg_bookmark/skgbookmarkplugin.h b/plugins/generic/skg_bookmark/skgbookmarkplugin.h
index ea0b7674d..feaeb6241 100644
--- a/plugins/generic/skg_bookmark/skgbookmarkplugin.h
+++ b/plugins/generic/skg_bookmark/skgbookmarkplugin.h
@@ -1,123 +1,123 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGBOOKMARKPLUGIN_H
#define SKGBOOKMARKPLUGIN_H
/** @file
* This file is a plugin for bookmarks management.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include <qvariant.h>
#include "skginterfaceplugin.h"
#include "ui_skgbookmarkpluginwidget_pref.h"
class QMenu;
/**
* This file is a plugin for bookmarks management
*/
class SKGBookmarkPlugin : public SKGInterfacePlugin
{
Q_OBJECT
Q_INTERFACES(SKGInterfacePlugin)
public:
/**
* Default Constructor
*/
explicit SKGBookmarkPlugin(QWidget* iWidget, QObject* iParent, const QVariantList& iArg);
/**
* Default Destructor
*/
~SKGBookmarkPlugin() override;
/**
* Called to setupActions the plugin
* @param iDocument the main document
* @return true if the plugin is compatible with the document
*/
bool setupActions(SKGDocument* iDocument) override;
/**
* The preference widget of the plugin.
* @return The preference widget of the plugin
*/
QWidget* getPreferenceWidget() override;
/**
* The preference skeleton of the plugin.
* @return The preference skeleton of the plugin
*/
KConfigSkeleton* getPreferenceSkeleton() override;
/**
* Must be modified to refresh widgets after a modification.
*/
void refresh() override;
/**
* The title of the plugin.
* @return The title of the plugin
*/
QString title() const override;
/**
* The icon of the plugin.
* @return The icon of the plugin
*/
QString icon() const override;
/**
* The tips list of the plugin.
* @return The tips list of the plugin
*/
QStringList tips() const override;
/**
* Must be implemented to set the position of the plugin.
* @return integer value between 0 and 999 (default = 999)
*/
int getOrder() const override;
/**
* The dock widget of the plugin.
* @return The dock widget of the plugin
*/
QDockWidget* getDockWidget() override;
private Q_SLOTS:
void importStandardBookmarks();
void goHome();
void onOpenBookmark();
void onAddBookmark();
void onShowBookmarkMenu();
private:
Q_DISABLE_COPY(SKGBookmarkPlugin)
SKGDocument* m_currentDocument;
QDockWidget* m_dockWidget;
QString m_docUniqueIdentifier;
QMenu* m_bookmarkMenu;
Ui::skgbookmarkplugin_pref ui{};
};
#endif // SKGBOOKMARKPLUGIN_H
diff --git a/plugins/generic/skg_bookmark/skgbookmarkplugindockwidget.cpp b/plugins/generic/skg_bookmark/skgbookmarkplugindockwidget.cpp
index 1036f0437..2c13c0466 100644
--- a/plugins/generic/skg_bookmark/skgbookmarkplugindockwidget.cpp
+++ b/plugins/generic/skg_bookmark/skgbookmarkplugindockwidget.cpp
@@ -1,608 +1,608 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is a plugin for bookmarks management.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgbookmarkplugindockwidget.h"
#include <kicondialog.h>
#include <qevent.h>
#include <qheaderview.h>
#include <qmenu.h>
#include "skgbookmark_settings.h"
#include "skgdocument.h"
#include "skginterfaceplugin.h"
#include "skgmainpanel.h"
#include "skgnodeobject.h"
#include "skgobjectmodelbase.h"
#include "skgsortfilterproxymodel.h"
#include "skgtraces.h"
#include "skgtransactionmng.h"
bool SKGBookmarkPluginDockWidget::m_middleClick = false;
SKGBookmarkPluginDockWidget::SKGBookmarkPluginDockWidget(QWidget* iParent, SKGDocument* iDocument)
: SKGWidget(iParent, iDocument), m_mainMenu(nullptr), m_actDelete(nullptr), m_actRename(nullptr), m_actChangeIcon(nullptr), m_actAddBookmark(nullptr), m_actAddBookmarks(nullptr),
m_actAddBookmarkGroup(nullptr), m_actSetAutostart(nullptr), m_actUnsetAutostart(nullptr), m_modelview(nullptr)
{
SKGTRACEINFUNC(1)
if (iDocument == nullptr) {
return;
}
ui.setupUi(this);
QPalette newPalette = QApplication::palette();
newPalette.setColor(QPalette::Base, Qt::transparent);
ui.kBookmarksList->setPalette(newPalette);
ui.kBookmarksList->setRootIsDecorated(false);
ui.kBookmarksList->setAnimated(false); // Not compatible with double click
ui.kBookmarksList->setEditTriggers(QAbstractItemView::NoEditTriggers);
ui.kTools->setIcon(SKGServices::fromTheme(QStringLiteral("configure")));
ui.kBookmarksList->setContextMenuPolicy(Qt::CustomContextMenu);
connect(ui.kBookmarksList, &SKGTreeView::customContextMenuRequested, this, &SKGBookmarkPluginDockWidget::showMenu);
// Add model
m_modelview = new SKGObjectModelBase(getDocument(), QStringLiteral("v_node"), QStringLiteral("1=1 ORDER BY f_sortorder, t_name"), this, QStringLiteral("rd_node_id"));
auto modelproxy = new SKGSortFilterProxyModel(this);
modelproxy->setSourceModel(m_modelview);
ui.kBookmarksList->setModel(modelproxy);
connect(ui.kFilterEdit, &QLineEdit::textChanged, this, [ = ](const QString & itext) {
modelproxy->setFilterKeyColumn(-1);
modelproxy->setFilterCaseSensitivity(Qt::CaseInsensitive);
modelproxy->setFilterFixedString(itext);
});
connect(ui.kBookmarksList, &SKGTreeView::selectionChangedDelayed, this, &SKGBookmarkPluginDockWidget::refresh);
connect(ui.kBookmarksList, &SKGTreeView::pressed, this, &SKGBookmarkPluginDockWidget::onBeforeOpenBookmark);
connect(ui.kBookmarksList, &SKGTreeView::pressed, this, &SKGBookmarkPluginDockWidget::onOpenBookmark);
connect(ui.kBookmarksList, &SKGTreeView::doubleClicked, this, &SKGBookmarkPluginDockWidget::onOpenBookmarkFolder);
connect(SKGMainPanel::getMainPanel(), &SKGMainPanel::currentPageChanged, this, &SKGBookmarkPluginDockWidget::onPageChanged);
connect(m_modelview, &SKGObjectModelBase::beforeReset, ui.kBookmarksList, &SKGTreeView::saveSelection);
connect(m_modelview, &SKGObjectModelBase::afterReset, ui.kBookmarksList, &SKGTreeView::resetSelection);
ui.kBookmarksList->setTextResizable(false);
// Refresh action states
refresh();
}
SKGBookmarkPluginDockWidget::~SKGBookmarkPluginDockWidget()
{
SKGTRACEINFUNC(1)
m_mainMenu = nullptr;
m_actDelete = nullptr;
m_actRename = nullptr;
m_actChangeIcon = nullptr;
m_actAddBookmark = nullptr;
m_actAddBookmarks = nullptr;
m_actAddBookmarkGroup = nullptr;
m_actSetAutostart = nullptr;
m_actUnsetAutostart = nullptr;
m_modelview = nullptr;
}
QWidget* SKGBookmarkPluginDockWidget::mainWidget()
{
return ui.kBookmarksList;
}
void SKGBookmarkPluginDockWidget::initMenu()
{
if (m_mainMenu == nullptr) {
// Build contextual menu
m_mainMenu = new QMenu(ui.kBookmarksList);
QAction* actExpandAll = m_mainMenu->addAction(SKGServices::fromTheme(QStringLiteral("format-indent-more")), i18nc("Noun, user action", "Expand all"));
connect(actExpandAll, &QAction::triggered, ui.kBookmarksList, &SKGTreeView::expandAll);
QAction* actCollapseAll = m_mainMenu->addAction(SKGServices::fromTheme(QStringLiteral("format-indent-less")), i18nc("Noun, user action", "Collapse all"));
connect(actCollapseAll, &QAction::triggered, ui.kBookmarksList, &SKGTreeView::collapseAll);
ui.kBookmarksList->insertAction(nullptr, actCollapseAll);
m_mainMenu->addSeparator();
m_actAddBookmark = m_mainMenu->addAction(SKGServices::fromTheme(QStringLiteral("list-add")), i18nc("Verb", "Bookmark current page"));
connect(m_actAddBookmark, &QAction::triggered, this, &SKGBookmarkPluginDockWidget::onAddBookmark);
m_actAddBookmarks = m_mainMenu->addAction(SKGServices::fromTheme(QStringLiteral("list-add")), i18nc("Verb", "Bookmark all pages"));
connect(m_actAddBookmarks, &QAction::triggered, this, &SKGBookmarkPluginDockWidget::onAddBookmarks);
m_actAddBookmarkGroup = m_mainMenu->addAction(SKGServices::fromTheme(QStringLiteral("folder-new")), i18nc("Verb", "Add bookmark group"));
connect(m_actAddBookmarkGroup, &QAction::triggered, this, &SKGBookmarkPluginDockWidget::onAddBookmarkGroup);
m_mainMenu->addSeparator();
m_actDelete = m_mainMenu->addAction(SKGServices::fromTheme(QStringLiteral("edit-delete")), i18nc("Verb, delete an item", "Delete"));
connect(m_actDelete, &QAction::triggered, this, &SKGBookmarkPluginDockWidget::onRemoveBookmark);
m_mainMenu->addSeparator();
m_actSetAutostart = m_mainMenu->addAction(SKGServices::fromTheme(QStringLiteral("media-playback-start")), i18nc("Verb, automatically load when the application is started", "Autostart"));
connect(m_actSetAutostart, &QAction::triggered, this, &SKGBookmarkPluginDockWidget::onSetAutostart);
m_actUnsetAutostart = m_mainMenu->addAction(SKGServices::fromTheme(QStringLiteral("media-playback-stop")), i18nc("Verb", "Remove Autostart"));
connect(m_actUnsetAutostart, &QAction::triggered, this, &SKGBookmarkPluginDockWidget::onUnsetAutostart);
m_actRename = m_mainMenu->addAction(SKGServices::fromTheme(QStringLiteral("edit-rename")), i18nc("Verb, change the name of an item", "Rename"));
m_actRename->setShortcut(Qt::Key_F2);
connect(m_actRename, &QAction::triggered, this, &SKGBookmarkPluginDockWidget::onRenameBookmark);
m_actChangeIcon = m_mainMenu->addAction(SKGServices::fromTheme(QStringLiteral("edit-image-face-add")), i18nc("Verb, change the icon of an item", "Change icon..."));
connect(m_actChangeIcon, &QAction::triggered, this, &SKGBookmarkPluginDockWidget::onChangeIconBookmark);
m_mainMenu->addSeparator();
m_mainMenu->addAction(SKGMainPanel::getMainPanel()->getGlobalAction(QStringLiteral("tab_overwritebookmark")));
ui.kTools->setMenu(m_mainMenu);
}
}
void SKGBookmarkPluginDockWidget::showMenu(const QPoint iPos)
{
initMenu();
m_mainMenu->popup(ui.kBookmarksList->mapToGlobal(iPos));
}
void SKGBookmarkPluginDockWidget::onSetAutostart()
{
SKGTRACEINFUNC(10)
setAutostart(QStringLiteral("Y"));
}
void SKGBookmarkPluginDockWidget::onUnsetAutostart()
{
SKGTRACEINFUNC(10)
setAutostart(QStringLiteral("N"));
}
void SKGBookmarkPluginDockWidget::setAutostart(const QString& value)
{
SKGTRACEINFUNC(10)
SKGObjectBase::SKGListSKGObjectBase selectedBookmarks = getSelectedObjects();
SKGError err;
// foreach selected bookmark, set the t_autostart attribute to 'y' or 'n'
{
int nb = selectedBookmarks.count();
SKGBEGINPROGRESSTRANSACTION(*getDocument(), value == QStringLiteral("Y") ? i18nc("Noun, name of the user action", "Autostart bookmarks") : i18nc("Noun, name of the user action", "Do not Autostart bookmarks"), err, nb)
for (int i = 0 ; !err && i < nb ; ++i) {
SKGNodeObject bookmark(selectedBookmarks.at(i));
err = bookmark.setAttribute(QStringLiteral("t_autostart"), value);
IFOKDO(err, bookmark.save())
// Send message
IFOKDO(err, bookmark.getDocument()->sendMessage(i18nc("An information message", "The Autostart status of bookmark '%1' has been changed", bookmark.getDisplayName()), SKGDocument::Hidden))
IFOKDO(err, getDocument()->stepForward(i + 1))
}
}
// status bar
IFOKDO(err, SKGError(0, value == QStringLiteral("Y") ? i18nc("Successful message after an user action", "Autostart bookmarks") : i18nc("Successful message after an user action", "Do not Autostart bookmarks")))
SKGMainPanel::displayErrorMessage(err);
}
void SKGBookmarkPluginDockWidget::openBookmark(const SKGNodeObject& iNode, bool iFirstInNewPage, bool iPin)
{
SKGTRACEINFUNC(1)
QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
QVector<SKGNodeObject> nodes;
nodes.reserve(20);
nodes.push_back(iNode);
int setForcusOn = 0;
int nbTab = SKGMainPanel::getMainPanel()->countPages();
if (nbTab != 0) {
setForcusOn = nbTab - 1;
SKGTabPage* cPage = SKGMainPanel::getMainPanel()->currentPage();
if (m_middleClick || ((cPage != nullptr) && cPage->isPin())) {
setForcusOn = nbTab;
} else {
setForcusOn = SKGMainPanel::getMainPanel()->currentPageIndex();
}
}
int tabNumberForNextOpen = (m_middleClick || iFirstInNewPage ? -1 : SKGMainPanel::getMainPanel()->currentPageIndex());
for (int i = 0; i < nodes.count(); ++i) { // WARNING: This list is modified dynamically
SKGNodeObject selectedNode = nodes.at(i);
QStringList data = SKGServices::splitCSVLine(selectedNode.getData());
if (data.count() > 2) {
// This bookmark has information ==> we open it
SKGTabPage* page = SKGMainPanel::getMainPanel()->openPage(SKGMainPanel::getMainPanel()->getPluginByName(data[0]), tabNumberForNextOpen, data[2], selectedNode.getName(), SKGServices::intToString(selectedNode.getID()), i == nodes.count() - 1);
if (page != nullptr) {
if (skgbookmark_settings::pinhomebookmarks()) {
page->setPin(iPin);
}
SKGTabWidget* tab = SKGMainPanel::getMainPanel()->getTabWidget();
if (tab != nullptr) {
tab->setTabIcon(tab->indexOf(page), selectedNode.getIcon());
}
selectedNode.opened = true;
tabNumberForNextOpen = -1;
}
} else {
// This bookmark is a folder ==> we open children by recursion
SKGObjectBase::SKGListSKGObjectBase children;
selectedNode.getNodes(children);
for (const auto& item : qAsConst(children)) {
nodes.push_back(SKGNodeObject(item));
}
}
}
QApplication::restoreOverrideCursor();
// Set focus on first page
SKGMainPanel::getMainPanel()->setCurrentPage(setForcusOn);
}
void SKGBookmarkPluginDockWidget::onBeforeOpenBookmark()
{
m_middleClick = (QApplication::keyboardModifiers() & Qt::ControlModifier) != 0u || (QApplication::mouseButtons() & Qt::MidButton) != 0u;
}
void SKGBookmarkPluginDockWidget::onOpenBookmark(const QModelIndex& index)
{
SKGTRACEINFUNC(1)
if (!(QApplication::mouseButtons() & Qt::RightButton)) {
auto* proxyModel = qobject_cast<QSortFilterProxyModel*>(ui.kBookmarksList->model());
auto* model = qobject_cast<SKGObjectModelBase*>(proxyModel->sourceModel());
if (model != nullptr) {
SKGNodeObject node(model->getObject(proxyModel->mapToSource(index)));
if (!node.isFolder()) {
openBookmark(node);
}
}
}
}
void SKGBookmarkPluginDockWidget::onOpenBookmarkFolder(const QModelIndex& index)
{
SKGTRACEINFUNC(1)
if (!(QApplication::mouseButtons() & Qt::RightButton)) {
auto* proxyModel = qobject_cast<QSortFilterProxyModel*>(ui.kBookmarksList->model());
auto* model = qobject_cast<SKGObjectModelBase*>(proxyModel->sourceModel());
if (model != nullptr) {
SKGNodeObject node(model->getObject(proxyModel->mapToSource(index)));
if (node.isFolder()) {
openBookmark(node);
}
}
}
}
void SKGBookmarkPluginDockWidget::onAddBookmarkGroup()
{
SKGTRACEINFUNC(1)
SKGError err;
SKGNodeObject node;
{
// Get current selection name
QString name;
SKGObjectBase::SKGListSKGObjectBase bookmarks = getSelectedObjects();
if (!bookmarks.isEmpty()) {
SKGNodeObject parentNode(bookmarks.at(0));
if (!parentNode.isFolder()) {
// This is not a folder, we have to take the parent
SKGNodeObject parentNodeTmp;
parentNode.getParentNode(parentNodeTmp);
parentNode = parentNodeTmp;
}
name = parentNode.getFullName();
}
// Add current name
if (!name.isEmpty()) {
name += OBJECTSEPARATOR;
}
name += i18nc("Default name for bookmark", "New bookmark");
// Create bookmark folder
SKGBEGINTRANSACTION(*getDocument(), i18nc("Noun, name of the user action", "Bookmark folder creation '%1'", name), err)
IFOKDO(err, SKGNodeObject::createPathNode(getDocument(), name, node, true))
// Send message
IFOKDO(err, node.getDocument()->sendMessage(i18nc("An information message", "The bookmark folder '%1' has been added", node.getDisplayName()), SKGDocument::Hidden))
}
// status bar
IFOK(err) {
ui.kBookmarksList->selectObject(node.getUniqueID());
err = SKGError(0, i18nc("Successful message after an user action", "Bookmark group created"));
}
SKGMainPanel::displayErrorMessage(err);
}
void SKGBookmarkPluginDockWidget::onAddBookmarks()
{
SKGTRACEINFUNC(1)
SKGError err;
SKGNodeObject rootNode;
{
// Get current selection name
QString name;
SKGObjectBase::SKGListSKGObjectBase bookmarks = getSelectedObjects();
if (!bookmarks.isEmpty()) {
SKGNodeObject parentNode(bookmarks.at(0));
if (!parentNode.isFolder()) {
// This is not a folder, we have to take the parent
SKGNodeObject parentNodeTmp;
parentNode.getParentNode(parentNodeTmp);
parentNode = parentNodeTmp;
}
name = parentNode.getFullName();
}
// Add current name
if (!name.isEmpty()) {
name += OBJECTSEPARATOR;
}
name += i18nc("Default name for bookmark", "New bookmark");
// Create bookmark folder
SKGBEGINTRANSACTION(*getDocument(), i18nc("Noun, name of the user action", "Bookmarks creation"), err)
err = SKGNodeObject::createPathNode(getDocument(), name, rootNode, true);
int nb = SKGMainPanel::getMainPanel()->countPages();
for (int i = 0; !err && i < nb; ++i) {
SKGNodeObject node;
err = createNodeFromPage(SKGMainPanel::getMainPanel()->page(i), rootNode, node);
// Send message
IFOKDO(err, node.getDocument()->sendMessage(i18nc("An information message", "The bookmark '%1' has been added", node.getDisplayName()), SKGDocument::Hidden))
}
}
// status bar
IFOK(err) {
ui.kBookmarksList->selectObject(rootNode.getUniqueID());
err = SKGError(0, i18nc("Successful message after an user action", "Bookmarks created"));
}
SKGMainPanel::displayErrorMessage(err);
}
void SKGBookmarkPluginDockWidget::onAddBookmark()
{
SKGTRACEINFUNC(1)
SKGError err;
// Get current page
SKGNodeObject node;
{
// Get current selection
SKGNodeObject parentNode(getDocument(), 0);
SKGObjectBase::SKGListSKGObjectBase bookmarks = getSelectedObjects();
if (!bookmarks.isEmpty()) {
parentNode = bookmarks.at(0);
}
// Create bookmark
err = createNodeFromPage(SKGMainPanel::getMainPanel()->currentPage(), parentNode, node);
}
// status bar
IFOK(err) {
ui.kBookmarksList->selectObject(node.getUniqueID());
err = SKGError(0, i18nc("Successful message after an user action", "Bookmark created"));
}
SKGMainPanel::displayErrorMessage(err);
}
SKGError SKGBookmarkPluginDockWidget::createNodeFromPage(SKGTabPage* iPage, const SKGNodeObject& iParentNode, SKGNodeObject& oCreatedNode)
{
SKGTRACEINFUNC(1)
SKGError err;
// Get current page
oCreatedNode = SKGNodeObject();
if (iPage != nullptr) {
// Get current selection name
QString name;
SKGNodeObject parentNode = iParentNode;
if (!parentNode.isFolder()) {
// This is not a folder, we have to take the parent
SKGNodeObject parentNodeTmp;
parentNode.getParentNode(parentNodeTmp);
parentNode = parentNodeTmp;
}
name = parentNode.getFullName();
// Add current name
if (!name.isEmpty()) {
name += OBJECTSEPARATOR;
}
QString defaultName = iPage->objectName();
QString defaultIcon;
SKGInterfacePlugin* plugin = SKGMainPanel::getMainPanel()->getPluginByName(defaultName);
if (plugin != nullptr) {
defaultName = plugin->title();
defaultIcon = plugin->icon();
}
name += defaultName;
// Create bookmark
SKGBEGINTRANSACTION(*iParentNode.getDocument(), i18nc("Noun, name of the user action", "Bookmark creation '%1'", name), err)
err = SKGNodeObject::createPathNode(iParentNode.getDocument(), name, oCreatedNode, true);
IFOK(err) {
QString value = SKGServices::stringToCsv(iPage->objectName()) % ';' %
SKGServices::stringToCsv(defaultName) % ';' %
SKGServices::stringToCsv(iPage->getState());
err = oCreatedNode.setData(value);
IFOKDO(err, oCreatedNode.setIcon(defaultIcon))
IFOKDO(err, oCreatedNode.save())
// Send message
IFOKDO(err, oCreatedNode.getDocument()->sendMessage(i18nc("An information message", "The bookmark '%1' has been added", oCreatedNode.getDisplayName()), SKGDocument::Hidden))
}
}
return err;
}
void SKGBookmarkPluginDockWidget::onRenameBookmark()
{
SKGTRACEINFUNC(1)
QItemSelectionModel* selModel = ui.kBookmarksList->selectionModel();
auto* proxyModel = qobject_cast< QSortFilterProxyModel* >(ui.kBookmarksList->model());
if ((proxyModel != nullptr) && (selModel != nullptr)) {
auto* model = qobject_cast<SKGObjectModelBase*>(proxyModel->sourceModel());
if (model != nullptr) {
QModelIndexList indexes = selModel->selectedRows();
if (indexes.count() == 1) {
ui.kBookmarksList->edit(indexes.at(0));
}
}
}
}
void SKGBookmarkPluginDockWidget::onChangeIconBookmark()
{
SKGTRACEINFUNC(1)
SKGObjectBase::SKGListSKGObjectBase bookmarks = getSelectedObjects();
if (bookmarks.count() == 1) {
SKGNodeObject node(bookmarks.at(0));
KIconDialog diag(this);
diag.setup(KIconLoader::NoGroup);
QString icon = diag.openDialog();
if (!icon.isEmpty()) {
SKGError err;
{
SKGBEGINTRANSACTION(*getDocument(), i18nc("Noun, name of the user action", "Bookmark icon change"), err)
err = node.setIcon(icon);
IFOKDO(err, node.save())
// Send message
IFOKDO(err, node.getDocument()->sendMessage(i18nc("An information message", "The icon of the bookmark '%1' has been changed", node.getDisplayName()), SKGDocument::Hidden))
}
// status bar
IFOKDO(err, SKGError(0, i18nc("Successful message after an user action", "Bookmark icon changed")))
SKGMainPanel::displayErrorMessage(err);
}
}
}
void SKGBookmarkPluginDockWidget::onRemoveBookmark()
{
SKGTRACEINFUNC(1)
SKGError err;
{
SKGBEGINTRANSACTION(*getDocument(), i18nc("Noun, name of the user action", "Bookmark delete"), err)
// Get current selection
SKGObjectBase::SKGListSKGObjectBase bookmarks = getSelectedObjects();
int nb = bookmarks.count();
for (int i = 0; i < nb && !err; ++i) {
SKGNodeObject node(bookmarks.at(i));
err = node.remove();
}
}
// status bar
IFOKDO(err, SKGError(0, i18nc("Successful message after an user action", "Bookmark deleted")))
SKGMainPanel::displayErrorMessage(err);
}
void SKGBookmarkPluginDockWidget::onBookmarkEditorChanged()
{
SKGTRACEINFUNC(10)
// Enable bookmark buttons
int nbSelectedObjects = getNbSelectedObjects();
bool testAdd = getDocument()->getMainDatabase() != nullptr && nbSelectedObjects <= 1;
if (m_actAddBookmarkGroup != nullptr) {
m_actAddBookmarkGroup->setEnabled(testAdd);
}
if (m_actAddBookmark != nullptr) {
m_actAddBookmark->setEnabled(testAdd && SKGMainPanel::getMainPanel()->currentPageIndex() >= 0);
}
if (m_actAddBookmarks != nullptr) {
m_actAddBookmarks->setEnabled(testAdd && SKGMainPanel::getMainPanel()->currentPageIndex() >= 0);
}
if (m_actDelete != nullptr) {
m_actDelete->setEnabled(nbSelectedObjects > 0);
}
if (m_actRename != nullptr) {
m_actRename->setEnabled(nbSelectedObjects == 1);
}
if (m_actChangeIcon != nullptr) {
m_actChangeIcon->setEnabled(nbSelectedObjects == 1);
}
}
void SKGBookmarkPluginDockWidget::refresh()
{
SKGTRACEINFUNC(10)
// Bookmarks
SKGObjectBase::SKGListSKGObjectBase bookmarks = getSelectedObjects();
int nbSelectedObjects = bookmarks.count();
if (nbSelectedObjects == 1) {
SKGNodeObject node(bookmarks.at(0));
if (m_actSetAutostart != nullptr) {
m_actSetAutostart->setEnabled(node.getAttribute(QStringLiteral("t_autostart")) != QStringLiteral("Y"));
}
if (m_actUnsetAutostart != nullptr) {
m_actUnsetAutostart->setEnabled(node.getAttribute(QStringLiteral("t_autostart")) == QStringLiteral("Y"));
}
} else {
if (m_actSetAutostart != nullptr) {
m_actSetAutostart->setEnabled(nbSelectedObjects > 1);
}
if (m_actUnsetAutostart != nullptr) {
m_actUnsetAutostart->setEnabled(nbSelectedObjects > 1);
}
}
onBookmarkEditorChanged();
}
void SKGBookmarkPluginDockWidget::onPageChanged()
{
// Set current selection of dock
QString id;
SKGTabPage* cPage = SKGMainPanel::getMainPanel()->currentPage();
if (cPage != nullptr) {
id = cPage->getBookmarkID();
}
ui.kBookmarksList->selectObject(id % "-node");
}
void SKGBookmarkPluginDockWidget::resizeEvent(QResizeEvent* iEvent)
{
if (iEvent != nullptr) {
QSize newSize = iEvent->size();
// Compute icon size
int s = qMax(qMin(newSize.width() / 5, 64), 16);
ui.kBookmarksList->setIconSize(QSize(s, s));
}
QWidget::resizeEvent(iEvent);
}
diff --git a/plugins/generic/skg_bookmark/skgbookmarkplugindockwidget.h b/plugins/generic/skg_bookmark/skgbookmarkplugindockwidget.h
index 082653f53..1ce2830b8 100644
--- a/plugins/generic/skg_bookmark/skgbookmarkplugindockwidget.h
+++ b/plugins/generic/skg_bookmark/skgbookmarkplugindockwidget.h
@@ -1,123 +1,123 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGBOOKMARKPLUGINDOCKWIDGET_H
#define SKGBOOKMARKPLUGINDOCKWIDGET_H
/** @file
* This file is a plugin for bookmarks management.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgnodeobject.h"
#include "skgwidget.h"
#include "ui_skgbookmarkplugindockwidget_base.h"
class QMenu;
class SKGObjectModelBase;
/**
* This file is a plugin for undoredo management
*/
class SKGBookmarkPluginDockWidget : public SKGWidget
{
Q_OBJECT
public:
/**
* Default Constructor
* @param iParent the parent widget
* @param iDocument the document
*/
explicit SKGBookmarkPluginDockWidget(QWidget* iParent, SKGDocument* iDocument);
/**
* Default Destructor
*/
~SKGBookmarkPluginDockWidget() override;
/**
* Get the main widget
* @return a widget
*/
QWidget* mainWidget() override;
/**
* Open a bookmark
* @param iNode bookmark object to open
* @param iFirstInNewPage to open first object in new page
* @param iPin to pin opened page
*/
static void openBookmark(const SKGNodeObject& iNode, bool iFirstInNewPage = false, bool iPin = false);
/**
* Bookmark a page
* @param iPage the page to bookmark
* @param iParentNode the parent node
* @param oCreatedNode the created node
*/
static SKGError createNodeFromPage(SKGTabPage* iPage, const SKGNodeObject& iParentNode, SKGNodeObject& oCreatedNode);
protected:
/**
* This event handler can be reimplemented in a subclass to receive widget resize events which are passed in the event parameter.
* When resizeEvent() is called, the widget already has its new geometry. The old size is accessible through QResizeEvent::oldSize().
* @param iEvent the event pointer
*/
void resizeEvent(QResizeEvent* iEvent) override;
public Q_SLOTS:
/**
* Refresh the content.
*/
virtual void refresh();
private Q_SLOTS:
void initMenu();
void showMenu(QPoint iPos);
void onAddBookmarkGroup();
void onAddBookmark();
void onAddBookmarks();
void onRemoveBookmark();
void onRenameBookmark();
void onChangeIconBookmark();
void onBeforeOpenBookmark();
void onOpenBookmark(const QModelIndex& index);
void onOpenBookmarkFolder(const QModelIndex& index);
void onBookmarkEditorChanged();
void onSetAutostart();
void onUnsetAutostart();
void onPageChanged();
private:
Q_DISABLE_COPY(SKGBookmarkPluginDockWidget)
void setAutostart(const QString& value);
Ui::skgbookmarkplugindockwidget_base ui{};
QMenu* m_mainMenu;
QAction* m_actDelete;
QAction* m_actRename;
QAction* m_actChangeIcon;
QAction* m_actAddBookmark;
QAction* m_actAddBookmarks;
QAction* m_actAddBookmarkGroup;
QAction* m_actSetAutostart;
QAction* m_actUnsetAutostart;
SKGObjectModelBase* m_modelview;
static bool m_middleClick;
};
#endif // SKGBOOKMARKPLUGINDOCKWIDGET_H
diff --git a/plugins/generic/skg_bookmark/skgbookmarkplugindockwidget_base.ui b/plugins/generic/skg_bookmark/skgbookmarkplugindockwidget_base.ui
index e342a2636..db677ca38 100644
--- a/plugins/generic/skg_bookmark/skgbookmarkplugindockwidget_base.ui
+++ b/plugins/generic/skg_bookmark/skgbookmarkplugindockwidget_base.ui
@@ -1,142 +1,142 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>skgbookmarkplugindockwidget_base</class>
<widget class="QWidget" name="skgbookmarkplugindockwidget_base">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>330</width>
<height>215</height>
</rect>
</property>
<layout class="QGridLayout" name="gridLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<property name="spacing">
<number>2</number>
</property>
<item row="0" column="0">
<widget class="QLineEdit" name="kFilterEdit">
<property name="focusPolicy">
<enum>Qt::WheelFocus</enum>
</property>
<property name="placeholderText">
<string>Search</string>
</property>
<property name="clearButtonEnabled">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="0" colspan="2">
<widget class="SKGTreeView" name="kBookmarksList">
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="toolTip">
- <string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
+ <string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;https://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'DejaVu Sans'; font-size:10pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;this list allows you to open bookmarked pages&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Ctrl&lt;/span&gt; to open in a new page&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="statusTip">
<string>this list allows you to open bookmarked pages</string>
</property>
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="lineWidth">
<number>0</number>
</property>
<property name="dragEnabled">
<bool>true</bool>
</property>
<property name="dragDropMode">
<enum>QAbstractItemView::DragDrop</enum>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::ExtendedSelection</enum>
</property>
<property name="iconSize">
<size>
<width>32</width>
<height>32</height>
</size>
</property>
<property name="uniformRowHeights">
<bool>true</bool>
</property>
<property name="animated">
<bool>true</bool>
</property>
<property name="allColumnsShowFocus">
<bool>true</bool>
</property>
<property name="headerHidden">
<bool>true</bool>
</property>
<property name="expandsOnDoubleClick">
<bool>false</bool>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QToolButton" name="kTools">
<property name="maximumSize">
<size>
<width>22</width>
<height>22</height>
</size>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="popupMode">
<enum>QToolButton::InstantPopup</enum>
</property>
<property name="autoRaise">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>SKGTreeView</class>
<extends>QTreeView</extends>
<header>skgtreeview.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<tabstops>
<tabstop>kFilterEdit</tabstop>
<tabstop>kTools</tabstop>
<tabstop>kBookmarksList</tabstop>
</tabstops>
<resources/>
<connections/>
<slots>
<slot>onAddBookmarkGroup()</slot>
<slot>onAddBookmark()</slot>
<slot>onRemoveBookmark()</slot>
<slot>onRenameBookmark()</slot>
<slot>onOpenBookmark()</slot>
<slot>onBookmarkEditorChanged()</slot>
<slot>onBookmarkFilterRegExpChanged()</slot>
<slot>onAddAutoStart()</slot>
</slots>
</ui>
diff --git a/plugins/generic/skg_dashboard/CMakeLists.txt b/plugins/generic/skg_dashboard/CMakeLists.txt
index e3e190ccd..1b5a20984 100644
--- a/plugins/generic/skg_dashboard/CMakeLists.txt
+++ b/plugins/generic/skg_dashboard/CMakeLists.txt
@@ -1,37 +1,37 @@
#***************************************************************************
#* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
#* *
#* 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 <http://www.gnu.org/licenses/> *
+#* along with this program. If not, see <https://www.gnu.org/licenses/> *
#***************************************************************************
MESSAGE( STATUS "..:: CMAKE PLUGIN_DASHBOARD ::..")
PROJECT(plugin_dashboard)
LINK_DIRECTORIES (${LIBRARY_OUTPUT_PATH})
SET(skg_dashboard_SRCS
skgdashboardplugin.cpp
skgdashboardpluginwidget.cpp)
ki18n_wrap_ui(skg_dashboard_SRCS skgdashboardpluginwidget_base.ui skgdashboardpluginwidget_pref.ui skgdashboardpluginwidget_pref.ui)
kconfig_add_kcfg_files(skg_dashboard_SRCS skgdashboard_settings.kcfgc )
ADD_LIBRARY(skg_dashboard MODULE ${skg_dashboard_SRCS})
TARGET_LINK_LIBRARIES(skg_dashboard Qt5::Gui KF5::Parts skgbasemodeler skgbasegui)
########### install files ###############
INSTALL(TARGETS skg_dashboard DESTINATION ${KDE_INSTALL_QTPLUGINDIR})
INSTALL(FILES ${PROJECT_SOURCE_DIR}/org.kde.skg-plugin-dashboard.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR})
INSTALL(FILES ${PROJECT_SOURCE_DIR}/skg_dashboard.rc DESTINATION ${KDE_INSTALL_KXMLGUI5DIR}/skg_dashboard )
INSTALL(FILES ${PROJECT_SOURCE_DIR}/skgdashboard_settings.kcfg DESTINATION ${KDE_INSTALL_KCFGDIR} )
diff --git a/plugins/generic/skg_dashboard/org.kde.skg-plugin-dashboard.desktop b/plugins/generic/skg_dashboard/org.kde.skg-plugin-dashboard.desktop
index 1975db579..0a8204913 100644
--- a/plugins/generic/skg_dashboard/org.kde.skg-plugin-dashboard.desktop
+++ b/plugins/generic/skg_dashboard/org.kde.skg-plugin-dashboard.desktop
@@ -1,76 +1,76 @@
[Desktop Entry]
Name=Dashboard plugin
Name[bs]=Dodatak za kontrolnu ploču
Name[ca]=Connector de tauler
Name[ca@valencia]=Connector de tauler
Name[cs]=Modul přístrojové desky
Name[da]=Instrumentbræt-plugin
Name[de]=Übersichtsseiten-Modul
Name[el]=Πρόσθετο πίνακα ελέγχου
Name[en_GB]=Dashboard plugin
Name[es]=Complemento de tablero
Name[et]=Vidinavaate plugin
Name[fi]=Kojelautaliitännäinen
Name[fr]=Module externe de tableau de bord
Name[gl]=Complemento de cadro de control
Name[hu]=Áttekintés bővítmény
Name[it]=Estensione per il quadro degli strumenti
Name[lt]=Prietaisų skydelio papildinys
Name[nb]=Kontrollpultmodul
Name[nds]=Klockpaneelmoduul
Name[nl]=Plugin voor Dashboard
Name[pl]=Wtyczka tablicy
Name[pt]='Plugin' de painel
Name[pt_BR]=Plugin de painel
Name[ru]=Модуль виджетов
Name[sk]=Plugin nástenky
Name[sv]=Insticksprogram med instrumentpanel
Name[tr]=Pano eklentisi
Name[uk]=Додаток панелі приладів
Name[x-test]=xxDashboard pluginxx
Name[zh_TW]=資訊看板外掛程式
Comment=Display a summary of your information
Comment[bs]=Prikazuje rezime vaših informacija
Comment[ca]=Mostra un resum de la vostra informació
Comment[ca@valencia]=Mostra un resum de la vostra informació
Comment[cs]=Zobrazí souhrn vašich informací
Comment[da]=Vis en oversigt over din information
Comment[de]=Zeigt eine Zusammenfassung Ihrer Information
Comment[el]=Εμφανίζει μια περίληψη των πληροφοριών σας
Comment[en_GB]=Display a summary of your information
Comment[es]=Mostrar un resumen con su información
Comment[et]=Kokkuvõtliku teabe näitamine
Comment[fi]=Näyttää yhteenvedon tiedoistasi
Comment[fr]=Afficher un résumé de vos informations
Comment[gl]=Mostrar un resumo da súa información.
Comment[hu]=Összegzés megjelenítése az információkról
Comment[it]=Visualizza un riassunto delle tue informazioni
Comment[lt]=Rodyti Jūsų informacijos suvestinę
Comment[nb]=Vis et sammendrag av din informasjon
Comment[nds]=En Tosamenfaten vun Dien Informatschonen wiesen
Comment[nl]=Een samenvatting van uw informatie tonen
Comment[pl]=Wyświetl podsumowanie swoich informacji
Comment[pt]=Mostrar um resumo da sua informação
Comment[pt_BR]=Exibe um resumo de sua informação
Comment[ru]=Показ общей информации
Comment[sk]=Zobraziť súhrn vašich informácií
Comment[sv]=Visar en sammanfattning av information
Comment[tr]=Bilgilerinizin bir özetini görüntüleyin
Comment[uk]=Показ резюме ваших відомостей
Comment[x-test]=xxDisplay a summary of your informationxx
Comment[zh_TW]=顯示您的資訊摘要
Encoding=UTF-8
Icon=quickopen
Type=Service
X-KDE-ServiceTypes=SKG GUI/Plugin
X-KDE-Library=skg_dashboard
X-Krunner-ID=Dashboard plugin
X-KDE-PluginInfo-Author=Stephane MANKOWSKI,miraks
X-KDE-PluginInfo-Email=stephane@mankowski.fr
X-KDE-PluginInfo-Name=skg_dashboard
X-KDE-PluginInfo-Version=1.0
-X-KDE-PluginInfo-Website=http://skrooge.org/
+X-KDE-PluginInfo-Website=https://skrooge.org/
X-KDE-PluginInfo-Category=Plugins
X-KDE-PluginInfo-Depends=
X-KDE-PluginInfo-License=GPL
X-KDE-PluginInfo-EnabledByDefault=true
diff --git a/plugins/generic/skg_dashboard/skgdashboardplugin.cpp b/plugins/generic/skg_dashboard/skgdashboardplugin.cpp
index b44144033..bf00a6670 100644
--- a/plugins/generic/skg_dashboard/skgdashboardplugin.cpp
+++ b/plugins/generic/skg_dashboard/skgdashboardplugin.cpp
@@ -1,118 +1,118 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* A dashboard
*
* @author Stephane MANKOWSKI
*/
#include "skgdashboardplugin.h"
#include <kaboutdata.h>
#include <kactioncollection.h>
#include <kpluginfactory.h>
#include <kstandardaction.h>
#include "skgdashboard_settings.h"
#include "skgdashboardpluginwidget.h"
#include "skgmainpanel.h"
#include "skgtraces.h"
/**
* This plugin factory.
*/
K_PLUGIN_FACTORY(SKGDashboardPluginFactory, registerPlugin<SKGDashboardPlugin>();)
SKGDashboardPlugin::SKGDashboardPlugin(QWidget* iWidget, QObject* iParent, const QVariantList& iArg) : SKGInterfacePlugin(iParent), m_currentDocument(nullptr)
{
Q_UNUSED(iArg)
Q_UNUSED(iWidget)
SKGTRACEINFUNC(10)
}
SKGDashboardPlugin::~SKGDashboardPlugin()
{
SKGTRACEINFUNC(10)
m_currentDocument = nullptr;
}
bool SKGDashboardPlugin::setupActions(SKGDocument* iDocument)
{
SKGTRACEINFUNC(10)
m_currentDocument = iDocument;
setComponentName(QStringLiteral("skg_dashboard"), title());
setXMLFile(QStringLiteral("skg_dashboard.rc"));
// Create yours actions here
return true;
}
SKGTabPage* SKGDashboardPlugin::getWidget()
{
SKGTRACEINFUNC(10)
return new SKGDashboardPluginWidget(SKGMainPanel::getMainPanel(), m_currentDocument);
}
QWidget* SKGDashboardPlugin::getPreferenceWidget()
{
SKGTRACEINFUNC(10)
auto w = new QWidget();
ui.setupUi(w);
return w;
}
KConfigSkeleton* SKGDashboardPlugin::getPreferenceSkeleton()
{
return skgdashboard_settings::self();
}
QString SKGDashboardPlugin::title() const
{
return i18nc("Noun, a summary of your financial situation", "Dashboard");
}
QString SKGDashboardPlugin::icon() const
{
return QStringLiteral("dashboard-show");
}
QString SKGDashboardPlugin::toolTip() const
{
return i18nc("Noun, a summary of your financial situation", "Dashboard");
}
int SKGDashboardPlugin::getOrder() const
{
return 8;
}
QStringList SKGDashboardPlugin::tips() const
{
QStringList output;
output.push_back(i18nc("Description of a tips", "<p>... the <a href=\"skg://dashboard_plugin\">dashboard</a> is there to give you a summary of your situation.</p>"));
output.push_back(i18nc("Description of a tips", "<p>... the <a href=\"skg://dashboard_plugin\">dashboard</a> can be reorganized by drag and drop.</p>"));
output.push_back(i18nc("Description of a tips", "<p>... some widgets of the <a href=\"skg://dashboard_plugin\">dashboard</a> have parameters.</p>"));
return output;
}
bool SKGDashboardPlugin::isInPagesChooser() const
{
return true;
}
#include <skgdashboardplugin.moc>
diff --git a/plugins/generic/skg_dashboard/skgdashboardplugin.h b/plugins/generic/skg_dashboard/skgdashboardplugin.h
index d8611816f..a07318ef4 100644
--- a/plugins/generic/skg_dashboard/skgdashboardplugin.h
+++ b/plugins/generic/skg_dashboard/skgdashboardplugin.h
@@ -1,118 +1,118 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGDASHBOARDPLUGIN_H
#define SKGDASHBOARDPLUGIN_H
/** @file
* A dashboard.
*
* @author Stephane MANKOWSKI
*/
#include "skginterfaceplugin.h"
#include "ui_skgdashboardpluginwidget_pref.h"
/**
* A dashboard
*/
class SKGDashboardPlugin : public SKGInterfacePlugin
{
Q_OBJECT
Q_INTERFACES(SKGInterfacePlugin)
public:
/**
* Default Constructor
*/
explicit SKGDashboardPlugin(QWidget* iWidget, QObject* iParent, const QVariantList& iArg);
/**
* Default Destructor
*/
~SKGDashboardPlugin() override;
/**
* Called to initialise the plugin
* @param iDocument the main document
* @return true if the plugin is compatible with the document
*/
bool setupActions(SKGDocument* iDocument) override;
/**
* The page widget of the plugin.
* @return The page widget of the plugin
*/
SKGTabPage* getWidget() override;
/**
* The preference widget of the plugin.
* @return The preference widget of the plugin
*/
QWidget* getPreferenceWidget() override;
/**
* The preference skeleton of the plugin.
* @return The preference skeleton of the plugin
*/
KConfigSkeleton* getPreferenceSkeleton() override;
/**
* The title of the plugin.
* @return The title of the plugin
*/
QString title() const override;
/**
* The icon of the plugin.
* @return The icon of the plugin
*/
QString icon() const override;
/**
* The toolTip of the plugin.
* @return The toolTip of the plugin
*/
QString toolTip() const override;
/**
* The tips list of the plugin.
* @return The tips list of the plugin
*/
QStringList tips() const override;
/**
* Must be implemented to set the position of the plugin.
* @return integer value between 0 and 999 (default = 999)
*/
int getOrder() const override;
/**
* Must be implemented to know if a plugin must be display in pages chooser.
* @return true of false (default = false)
*/
bool isInPagesChooser() const override;
private Q_SLOTS:
private:
Q_DISABLE_COPY(SKGDashboardPlugin)
SKGDocument* m_currentDocument;
Ui::skgdashboardplugin_pref ui{};
};
#endif // SKGDASHBOARDPLUGIN_H
diff --git a/plugins/generic/skg_dashboard/skgdashboardpluginwidget.cpp b/plugins/generic/skg_dashboard/skgdashboardpluginwidget.cpp
index 28bb1a353..3a6ca6d42 100644
--- a/plugins/generic/skg_dashboard/skgdashboardpluginwidget.cpp
+++ b/plugins/generic/skg_dashboard/skgdashboardpluginwidget.cpp
@@ -1,466 +1,466 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* A dashboard.
*
* @author Stephane MANKOWSKI
*/
#include "skgdashboardpluginwidget.h"
#include <kaboutdata.h>
#include <kservice.h>
#include <qdom.h>
#include <qdrag.h>
#include <qevent.h>
#include <qmenu.h>
#include <qmimedata.h>
#include "skgboardwidget.h"
#include "skgdocument.h"
#include "skgflowlayout.h"
#include "skginterfaceplugin.h"
#include "skgmainpanel.h"
#include "skgservices.h"
#include "skgtraces.h"
#include "skgzoomselector.h"
SKGDashboardPluginWidget::SKGDashboardPluginWidget(QWidget* iParent, SKGDocument* iDocument)
: SKGTabPage(iParent, iDocument), m_flowLayout(nullptr), m_menu(nullptr), m_addMenu(nullptr)
{
SKGTRACEINFUNC(1)
if (iDocument == nullptr) {
return;
}
ui.setupUi(this);
// Create a context menu for adding widgets
setContextMenuPolicy(Qt::CustomContextMenu);
m_menu = new QMenu(this);
connect(this, &SKGDashboardPluginWidget::customContextMenuRequested, this, &SKGDashboardPluginWidget::showHeaderMenu);
m_addMenu = m_menu->addMenu(SKGServices::fromTheme(QStringLiteral("list-add")), i18nc("Verb", "Add"));
// Drag and drop
m_clickedPoint = QPoint(-1, -1);
ui.kTitle->setPixmap(SKGServices::fromTheme(KAboutData::applicationData().programIconName()).pixmap(22, 22), KTitleWidget::ImageLeft);
ui.kTitle->setComment("<html><body><b>" % i18nc("Message", "Welcome to %1", KAboutData::applicationData().displayName()) % "</b></body></html>");
// Build menu
if (m_addMenu != nullptr) {
m_addMenu->clear();
int index = 0;
while (index >= 0) {
SKGInterfacePlugin* plugin = SKGMainPanel::getMainPanel()->getPluginByIndex(index);
if (plugin != nullptr) {
int nbdbw = plugin->getNbDashboardWidgets();
for (int j = 0; j < nbdbw; ++j) {
// Create menu
QAction* act = m_addMenu->addAction(plugin->getDashboardWidgetTitle(j));
if (act != nullptr) {
act->setIcon(SKGServices::fromTheme(plugin->icon()));
act->setData(QString(plugin->objectName() % '-' % SKGServices::intToString(j)));
connect(act, &QAction::triggered, this, &SKGDashboardPluginWidget::onAddWidget);
}
}
} else {
index = -2;
}
++index;
}
}
// Build layout
m_flowLayout = new SKGFlowLayout(ui.kContent, 0, 0, 0);
// Plug buttons with menus
if ((m_addMenu != nullptr) && (ui.kAddWidget != nullptr)) {
ui.kAddWidget->setIcon(m_addMenu->icon());
ui.kAddWidget->setMenu(m_addMenu);
ui.kAddWidget->setPopupMode(QToolButton::InstantPopup);
}
}
SKGDashboardPluginWidget::~SKGDashboardPluginWidget()
{
SKGTRACEINFUNC(1)
m_menu = nullptr;
m_addMenu = nullptr;
m_flowLayout = nullptr;
}
QString SKGDashboardPluginWidget::getState()
{
SKGTRACEINFUNC(10)
QDomDocument doc(QStringLiteral("SKGML"));
QDomElement root = doc.createElement(QStringLiteral("parameters"));
doc.appendChild(root);
root.setAttribute(QStringLiteral("zoomPosition"), SKGServices::intToString(zoomPosition()));
int nb = m_items.count();
for (int i = 0; i < nb; ++i) {
QDomElement element = doc.createElement("ITEM-" % SKGServices::intToString(i + 1));
root.appendChild(element);
QStringList param = SKGServices::splitCSVLine(m_items.at(i), '-');
SKGBoardWidget* item = m_itemsPointers.at(i);
if (item != nullptr) {
element.setAttribute(QStringLiteral("name"), param.at(0));
element.setAttribute(QStringLiteral("index"), param.at(1));
element.setAttribute(QStringLiteral("state"), item->getState());
element.setAttribute(QStringLiteral("zoom"), SKGServices::intToString(item->getZoomRatio() * 5 - 15));
}
}
return doc.toString();
}
void SKGDashboardPluginWidget::setState(const QString& iState)
{
SKGTRACEINFUNC(10)
QDomDocument doc(QStringLiteral("SKGML"));
doc.setContent(iState);
QDomElement root = doc.documentElement();
// Initialisation
int nb = (m_flowLayout != nullptr ? m_flowLayout->count() : 0);
for (int i = 0; i < nb; ++i) {
SKGBoardWidget* item = m_itemsPointers.at(0);
if (item != nullptr) {
m_flowLayout->removeWidget(item);
item->hide();
m_items.removeAt(0);
m_itemsPointers.removeAt(0);
item->deleteLater();
}
}
QString zoomPositionS = root.attribute(QStringLiteral("zoomPosition"));
if (zoomPositionS.isEmpty()) {
zoomPositionS = '0';
}
setZoomPosition(SKGServices::stringToInt(zoomPositionS));
int index = 1;
while (index > 0) {
QDomElement element = root.firstChildElement("ITEM-" % SKGServices::intToString(index));
if (!element.isNull()) {
SKGInterfacePlugin* plugin = SKGMainPanel::getMainPanel()->getPluginByName(element.attribute(QStringLiteral("name")));
QString indexString = element.attribute(QStringLiteral("index"));
if (indexString.isEmpty()) {
indexString = '0';
}
QString zoom = element.attribute(QStringLiteral("zoom"));
if (zoom.isEmpty()) {
zoom = '0';
}
if (plugin != nullptr) {
addItem(plugin, SKGServices::stringToInt(indexString), SKGServices::stringToInt(zoom), element.attribute(QStringLiteral("state")));
}
} else {
index = -1;
}
++index;
}
// In case of reset
if (m_items.isEmpty() && root.attribute(QStringLiteral("zoomPosition")).isEmpty()) {
int index2 = 0;
while (index2 >= 0) {
SKGInterfacePlugin* plugin = SKGMainPanel::getMainPanel()->getPluginByIndex(index2);
if (plugin != nullptr) {
int nb2 = plugin->getNbDashboardWidgets();
for (int j = 0; j < nb2; ++j) {
addItem(plugin, j);
}
} else {
index2 = -2;
}
++index2;
}
}
}
QString SKGDashboardPluginWidget::getDefaultStateAttribute()
{
return QStringLiteral("SKGDASHBOARD_DEFAULT_PARAMETERS");
}
void SKGDashboardPluginWidget::refresh()
{
SKGTRACEINFUNC(1)
}
QWidget* SKGDashboardPluginWidget::zoomableWidget()
{
return SKGTabPage::zoomableWidget();
}
QList< QWidget* > SKGDashboardPluginWidget::printableWidgets()
{
QList< QWidget* > output;
output.reserve(m_itemsPointers.count());
for (auto w : qAsConst(m_itemsPointers)) {
output.push_back(w);
}
return output;
}
bool SKGDashboardPluginWidget::eventFilter(QObject* iObject, QEvent* iEvent)
{
if ((iEvent != nullptr) && iEvent->type() == QEvent::HoverLeave) {
// Leave widget
m_timer.stop();
return true;
}
if ((iEvent != nullptr) && (iObject != nullptr) &&
(iEvent->type() == QEvent::MouseButtonPress ||
iEvent->type() == QEvent::MouseButtonRelease ||
iEvent->type() == QEvent::MouseMove ||
iEvent->type() == QEvent::DragEnter ||
iEvent->type() == QEvent::DragMove ||
iEvent->type() == QEvent::Drop ||
iEvent->type() == QEvent::HoverMove)) {
// Search SKGBoardWidget corresponding to this widget
SKGBoardWidget* toMove = nullptr;
int toMoveIndex = -1;
int nb = m_itemsPointers.count();
for (int i = 0; toMove == nullptr && i < nb; ++i) {
SKGBoardWidget* w = m_itemsPointers.at(i);
if ((w != nullptr) && w->getDragWidget() == iObject) {
toMove = w;
toMoveIndex = i;
}
}
if (iEvent->type() == QEvent::MouseButtonPress) {
// Drag
auto* mevent = dynamic_cast<QMouseEvent*>(iEvent);
if (mevent && mevent->button() == Qt::LeftButton) {
m_clickedPoint = mevent->pos();
m_timer.stop();
}
} else if (iEvent->type() == QEvent::MouseButtonRelease) {
// Drag
auto* mevent = dynamic_cast<QMouseEvent*>(iEvent);
if (mevent && mevent->button() == Qt::LeftButton) {
m_clickedPoint = QPoint(-1, -1);
}
} else if (iEvent->type() == QEvent::MouseMove) {
// Drag
if (m_clickedPoint != QPoint(-1, -1) && toMoveIndex != -1) {
auto* mevent = dynamic_cast<QMouseEvent*>(iEvent);
if (mevent) {
int distance = (mevent->pos() - m_clickedPoint).manhattanLength();
if (distance >= QApplication::startDragDistance()) {
auto mimeData = new QMimeData;
mimeData->setData(QStringLiteral("application/x-skgdashboardpluginwidget"), SKGServices::intToString(toMoveIndex).toLatin1());
auto drag = new QDrag(this);
drag->setMimeData(mimeData);
drag->exec(); // krazy:exclude=crashy
return true;
}
}
}
} else if (iEvent->type() == QEvent::DragEnter) {
// Drop move
auto* devent = dynamic_cast<QDragEnterEvent*>(iEvent);
if (devent && devent->mimeData()->hasFormat(QStringLiteral("application/x-skgdashboardpluginwidget"))) {
devent->accept();
return true;
}
} else if (iEvent->type() == QEvent::DragMove) {
// Drop move
auto* devent = dynamic_cast<QDragMoveEvent*>(iEvent);
if (devent && devent->mimeData()->hasFormat(QStringLiteral("application/x-skgdashboardpluginwidget"))) {
int oldPos = SKGServices::stringToInt(devent->mimeData()->data(QStringLiteral("application/x-skgdashboardpluginwidget")));
if (oldPos != toMoveIndex) {
devent->accept();
} else {
devent->ignore();
}
return true;
}
} else if (iEvent->type() == QEvent::Drop) {
// Drop
auto* devent = dynamic_cast<QDropEvent*>(iEvent);
if (devent && devent->mimeData()->hasFormat(QStringLiteral("application/x-skgdashboardpluginwidget"))) {
int oldPos = SKGServices::stringToInt(devent->mimeData()->data(QStringLiteral("application/x-skgdashboardpluginwidget")));
if (oldPos + 1 == toMoveIndex) {
++toMoveIndex;
}
// Move item
if (toMoveIndex > oldPos) {
--toMoveIndex;
}
moveItem(oldPos, toMoveIndex);
return true;
}
}
}
return SKGTabPage::eventFilter(iObject, iEvent);
}
void SKGDashboardPluginWidget::showHeaderMenu(const QPoint iPos)
{
// Display menu
if (m_menu != nullptr) {
m_menu->popup(mapToGlobal(iPos));
}
}
void SKGDashboardPluginWidget::onAddWidget()
{
auto* send = qobject_cast<QAction*>(this->sender());
if (send != nullptr) {
QString id = send->data().toString();
QStringList param = SKGServices::splitCSVLine(id, '-');
SKGInterfacePlugin* db = SKGMainPanel::getMainPanel()->getPluginByName(param.at(0));
if (db != nullptr) {
addItem(db, SKGServices::stringToInt(param.at(1)));
}
}
}
void SKGDashboardPluginWidget::onMoveWidget(int iMove)
{
// Get current position
QWidget* send = qobject_cast<QWidget*>(this->sender());
if (send != nullptr) {
int currentPos = m_itemsPointers.indexOf(parentBoardWidget(send));
int newPos = currentPos + iMove;
if (newPos < 0) {
newPos = 0;
} else if (newPos > m_items.count() - 1) {
newPos = m_items.count() - 1;
}
moveItem(currentPos, newPos);
}
}
void SKGDashboardPluginWidget::moveItem(int iFrom, int iTo)
{
// Compute new position
if (iTo != iFrom) {
// Move item
m_items.move(iFrom, iTo);
m_itemsPointers.move(iFrom, iTo);
// Build list of items in the right order
QList<SKGBoardWidget*> listWidgets;
int nb = m_itemsPointers.count();
listWidgets.reserve(nb);
for (int i = 0; i < nb; ++i) {
SKGBoardWidget* wgt2 = m_itemsPointers.at(i);
m_flowLayout->removeWidget(wgt2);
listWidgets.push_back(wgt2);
}
// Add items
nb = listWidgets.count();
for (int i = 0; i < nb; ++i) {
SKGBoardWidget* dbw = listWidgets.at(i);
dbw->setParent(ui.kContent);
m_flowLayout->addWidget(dbw);
}
}
}
SKGBoardWidget* SKGDashboardPluginWidget::parentBoardWidget(QWidget* iWidget)
{
auto* output = qobject_cast< SKGBoardWidget* >(iWidget);
if ((output == nullptr) && (iWidget != nullptr)) {
QWidget* iParent = iWidget->parentWidget();
if (iParent != nullptr) {
output = SKGDashboardPluginWidget::parentBoardWidget(iParent);
}
}
return output;
}
void SKGDashboardPluginWidget::onRemoveWidget()
{
int p = -1;
QWidget* send = qobject_cast<QWidget*>(this->sender());
if (send != nullptr) {
p = m_itemsPointers.indexOf(parentBoardWidget(send));
}
if (p >= 0) {
// Get item
SKGBoardWidget* wgt = m_itemsPointers.at(p);
// Delete widget
m_flowLayout->removeWidget(wgt);
wgt->hide();
wgt->deleteLater();
// Remove item
m_items.removeAt(p);
m_itemsPointers.removeAt(p);
}
}
void SKGDashboardPluginWidget::addItem(SKGInterfacePlugin* iDashboard, int iIndex, int iZoom, const QString& iState)
{
if ((iDashboard != nullptr) && (m_flowLayout != nullptr)) {
SKGBoardWidget* dbw = iDashboard->getDashboardWidget(iIndex);
if (dbw != nullptr) {
// Add widget
dbw->setParent(ui.kContent);
dbw->setState(iState);
m_flowLayout->addWidget(dbw);
// Install filter
QWidget* drag = dbw->getDragWidget();
if (drag != nullptr) {
drag->installEventFilter(this);
drag->setAcceptDrops(true);
drag->setAttribute(Qt::WA_Hover);
}
// Connect widget
connect(dbw, &SKGBoardWidget::requestRemove, this, &SKGDashboardPluginWidget::onRemoveWidget, Qt::QueuedConnection);
connect(dbw, &SKGBoardWidget::requestMove, this, &SKGDashboardPluginWidget::onMoveWidget, Qt::QueuedConnection);
// Set size
dbw->setZoomRatio((iZoom + 15.0) / 5.0);
QString id = iDashboard->objectName() % '-' % SKGServices::intToString(iIndex);
m_items.push_back(id);
m_itemsPointers.push_back(dbw);
}
}
}
diff --git a/plugins/generic/skg_dashboard/skgdashboardpluginwidget.h b/plugins/generic/skg_dashboard/skgdashboardpluginwidget.h
index aeeac65c0..1c0e0bbf1 100644
--- a/plugins/generic/skg_dashboard/skgdashboardpluginwidget.h
+++ b/plugins/generic/skg_dashboard/skgdashboardpluginwidget.h
@@ -1,139 +1,139 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGDASHBOARDPLUGINWIDGET_H
#define SKGDASHBOARDPLUGINWIDGET_H
/** @file
* A dashboard
*
* @author Stephane MANKOWSKI
*/
#include <qlist.h>
#include <qstringlist.h>
#include <qtimer.h>
#include "skgtabpage.h"
#include "ui_skgdashboardpluginwidget_base.h"
class QMenu;
class SKGInterfacePlugin;
class SKGFlowLayout;
class SKGBoardWidget;
/**
* A dashboard
*/
class SKGDashboardPluginWidget : public SKGTabPage
{
Q_OBJECT
public:
/**
* Default Constructor
* @param iParent the parent widget
* @param iDocument the document
*/
explicit SKGDashboardPluginWidget(QWidget* iParent, SKGDocument* iDocument);
/**
* Default Destructor
*/
~SKGDashboardPluginWidget() override;
/**
* Get the current state
* MUST BE OVERWRITTEN
* @return a string containing all information needed to set the same state.
* Could be an XML stream
*/
QString getState() override;
/**
* Set the current state
* MUST BE OVERWRITTEN
* @param iState must be interpreted to set the state of the widget
*/
void setState(const QString& iState) override;
/**
* Get attribute name to save the default state
* MUST BE OVERWRITTEN
* @return attribute name to save the default state.
*/
QString getDefaultStateAttribute() override;
/**
* Get the zoomable widget.
* The default implementation returns the main widget.
* @return the zoomable widget.
*/
QWidget* zoomableWidget() override;
/**
* Get the printable widgets.
* The default implementation returns the main widget.
* @return the printable widgets.
*/
QList<QWidget*> printableWidgets() override;
protected:
/**
* Event filtering
* @param iObject object
* @param iEvent event
* @return In your reimplementation of this function, if you want to filter the event out, i.e. stop it being handled further, return true; otherwise return false.
*/
bool eventFilter(QObject* iObject, QEvent* iEvent) override;
public Q_SLOTS:
/**
* Refresh the content.
*/
virtual void refresh();
Q_SIGNALS:
/**
* When an applet id added
*/
void appletAdded(const QString& /*_t1*/);
private Q_SLOTS:
void showHeaderMenu(QPoint iPos);
void onAddWidget();
void onRemoveWidget();
void onMoveWidget(int iMove);
private:
Q_DISABLE_COPY(SKGDashboardPluginWidget)
void addItem(SKGInterfacePlugin* iDashboard, int iIndex, int iZoom = -10, const QString& iState = QString());
void moveItem(int iFrom, int iTo);
static SKGBoardWidget* parentBoardWidget(QWidget* iWidget);
Ui::skgdashboardplugin_base ui{};
SKGFlowLayout* m_flowLayout;
QStringList m_items;
QList<SKGBoardWidget*> m_itemsPointers;
QMenu* m_menu;
QMenu* m_addMenu;
QTimer m_timer;
QPoint m_clickedPoint;
QPoint m_lastPoint;
};
#endif // SKGDASHBOARDPLUGINWIDGET_H
diff --git a/plugins/generic/skg_debug/CMakeLists.txt b/plugins/generic/skg_debug/CMakeLists.txt
index ca52c4345..1d1f44472 100644
--- a/plugins/generic/skg_debug/CMakeLists.txt
+++ b/plugins/generic/skg_debug/CMakeLists.txt
@@ -1,37 +1,37 @@
#***************************************************************************
#* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
#* *
#* 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 <http://www.gnu.org/licenses/> *
+#* along with this program. If not, see <https://www.gnu.org/licenses/> *
#***************************************************************************
MESSAGE( STATUS "..:: CMAKE PLUGIN_DEBUG ::..")
PROJECT(plugin_debug)
IF(SKG_BUILD_TEST AND NOT WIN32)
ADD_SUBDIRECTORY(tests)
ENDIF(SKG_BUILD_TEST AND NOT WIN32)
LINK_DIRECTORIES (${LIBRARY_OUTPUT_PATH})
SET(skg_debug_SRCS skgdebugplugin.cpp skgdebugpluginwidget.cpp)
ki18n_wrap_ui(skg_debug_SRCS skgdebugpluginwidget_base.ui)
ADD_LIBRARY(skg_debug MODULE ${skg_debug_SRCS})
TARGET_LINK_LIBRARIES(skg_debug KF5::Parts skgbasemodeler skgbasegui Qt5::Qml)
########### install files ###############
INSTALL(TARGETS skg_debug DESTINATION ${KDE_INSTALL_QTPLUGINDIR})
INSTALL(FILES ${PROJECT_SOURCE_DIR}/org.kde.skg-plugin-debug.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR})
INSTALL(FILES ${PROJECT_SOURCE_DIR}/skg_debug.rc DESTINATION ${KDE_INSTALL_KXMLGUI5DIR}/skg_debug )
diff --git a/plugins/generic/skg_debug/org.kde.skg-plugin-debug.desktop b/plugins/generic/skg_debug/org.kde.skg-plugin-debug.desktop
index d6ff940ec..5cfcbe137 100644
--- a/plugins/generic/skg_debug/org.kde.skg-plugin-debug.desktop
+++ b/plugins/generic/skg_debug/org.kde.skg-plugin-debug.desktop
@@ -1,78 +1,78 @@
[Desktop Entry]
Name=Debug plugin
Name[bs]=Dodatak za otklanjanje grešaka
Name[ca]=Connector de depuració
Name[ca@valencia]=Connector de depuració
Name[cs]=Ladicí modul
Name[da]=Fejlsøgnings-plugin
Name[de]=Debug-Modul
Name[el]=Debug plugin
Name[en_GB]=Debug plugin
Name[es]=Complemento de depuración
Name[et]=Silumisplugin
Name[fi]=Virheenpaikannusliitännäinen
Name[fr]=Module externe de débogage
Name[gl]=Complemento de depuración
Name[hu]=Hibakereső bővítmény
Name[it]=Estensione di debug
Name[lt]=Derinimo papildinys
Name[nb]=Debug-modul
Name[nds]=Fehlersöökmoduul
Name[nl]=Plugin voor debug
Name[pl]=Wtyczka debugowania
Name[pt]='Plugin' de depuração
Name[pt_BR]=Plugin de depuração
Name[ru]=Модуль отладки
Name[sk]=Ladiaci plugin
Name[sv]=Felsökningsinsticksprogram
Name[tr]=Hata Ayıklama Eklentisi
Name[uk]=Додаток налагоджування
Name[x-test]=xxDebug pluginxx
Name[zh_CN]=调试插件
Name[zh_TW]=除錯外掛程式
Comment=A plugin helping debug
Comment[bs]=Dodatak koji pomaže pri otklanjanju grešaka
Comment[ca]=Un connector d'ajuda a la depuració
Comment[ca@valencia]=Un connector d'ajuda a la depuració
Comment[cs]=Rozšíření usnadňující ladění
Comment[da]=Et plugin som hjælper med fejlsøgning
Comment[de]=Ein Modul zur Fehlersuche
Comment[el]=Ένα πρόσθετο που βοηθάει στη διόρθωση σφαλμάτων
Comment[en_GB]=A plugin helping debug
Comment[es]=Un complemento de ayuda a la depuración
Comment[et]=Silumist abistav plugin
Comment[fi]=Virheenpaikannusta helpottava liitännäinen
Comment[fr]=Module externe pour l'aide au débogage
Comment[gl]=Un complemento que axuda a depurar.
Comment[hu]=Egy bővítmény hibakeresés segítéséhez
Comment[it]=Un'estensione per assistere il debugging
Comment[lt]=Papildinys padedantis derinti programą
Comment[nb]=Et programtilleggl for feilsøking
Comment[nds]=En Fehlersöök-Hülpmoduul
Comment[nl]=Een plugin om te helpen bij debugging
Comment[pl]=Wtyczka pomagająca debugować
Comment[pt]=Um 'plugin' auxiliar na depuração
Comment[pt_BR]=Um plugin para ajudar na depuração
Comment[ru]=Вспомогательный модуль отладки
Comment[sk]=Plugin na pomoc pri ladení
Comment[sv]=Ett insticksprogram som hjälper till med felsökning
Comment[tr]=Hata ayıklamaya yardımcı bir eklenti
Comment[uk]=Додаток діагностики вад
Comment[x-test]=xxA plugin helping debugxx
Comment[zh_TW]=除錯用的外掛程式
Encoding=UTF-8
Icon=quickopen
Type=Service
X-KDE-ServiceTypes=SKG GUI/Plugin
X-KDE-Library=skg_debug
X-Krunner-ID=Debug plugin
X-KDE-PluginInfo-Author=Stephane MANKOWSKI,miraks
X-KDE-PluginInfo-Email=stephane@mankowski.fr
X-KDE-PluginInfo-Name=skg_debug
X-KDE-PluginInfo-Version=1.0
-X-KDE-PluginInfo-Website=http://skrooge.org/
+X-KDE-PluginInfo-Website=https://skrooge.org/
X-KDE-PluginInfo-Category=Plugins
X-KDE-PluginInfo-Depends=
X-KDE-PluginInfo-License=GPL
X-KDE-PluginInfo-EnabledByDefault=true
diff --git a/plugins/generic/skg_debug/skgdebugplugin.cpp b/plugins/generic/skg_debug/skgdebugplugin.cpp
index bc0b0f733..4043f0ceb 100644
--- a/plugins/generic/skg_debug/skgdebugplugin.cpp
+++ b/plugins/generic/skg_debug/skgdebugplugin.cpp
@@ -1,129 +1,129 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is a plugin for debug.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgdebugplugin.h"
#include <kaboutdata.h>
#include <kactioncollection.h>
#include <kpluginfactory.h>
#include "skgdebugpluginwidget.h"
#include "skgmainpanel.h"
#include "skgtraces.h"
/**
* This plugin factory.
*/
K_PLUGIN_FACTORY(SKGDebugPluginFactory, registerPlugin<SKGDebugPlugin>();)
SKGDebugPlugin::SKGDebugPlugin(QWidget* iWidget, QObject* iParent, const QVariantList& /*iArg*/) : SKGInterfacePlugin(iParent), m_currentDocument(nullptr)
{
Q_UNUSED(iWidget)
SKGTRACEINFUNC(10)
}
SKGDebugPlugin::~SKGDebugPlugin()
{
SKGTRACEINFUNC(10)
m_currentDocument = nullptr;
}
bool SKGDebugPlugin::setupActions(SKGDocument* iDocument)
{
SKGTRACEINFUNC(10)
m_currentDocument = iDocument;
if (m_currentDocument == nullptr) {
return false;
}
setComponentName(QStringLiteral("skg_debug"), title());
setXMLFile(QStringLiteral("skg_debug.rc"));
// Menu
auto restartProfiling = new QAction(SKGServices::fromTheme(QStringLiteral("fork")), i18nc("Restart the profiling, a method used for analysing performances", "Restart profiling"), this);
connect(restartProfiling, &QAction::triggered, this, &SKGDebugPlugin::onRestartProfiling);
actionCollection()->setDefaultShortcut(restartProfiling, Qt::CTRL + Qt::Key_Pause);
registerGlobalAction(QStringLiteral("debug_restart_profiling"), restartProfiling);
QStringList overlayopen;
overlayopen.push_back(QStringLiteral("quickopen"));
auto openProfiling = new QAction(SKGServices::fromTheme(QStringLiteral("fork"), overlayopen), i18nc("Open the profiling, a method used for analysing performances", "Open profiling"), this);
connect(openProfiling, &QAction::triggered, this, &SKGDebugPlugin::onOpenProfiling);
actionCollection()->setDefaultShortcut(openProfiling, Qt::ALT + Qt::Key_Pause);
registerGlobalAction(QStringLiteral("debug_open_profiling"), openProfiling);
return true;
}
SKGTabPage* SKGDebugPlugin::getWidget()
{
SKGTRACEINFUNC(10)
return new SKGDebugPluginWidget(SKGMainPanel::getMainPanel(), m_currentDocument);
}
QString SKGDebugPlugin::title() const
{
return i18nc("Noun, a plugin allowing to access the SQLite database, useful to debug", "Debug");
}
QString SKGDebugPlugin::icon() const
{
return QStringLiteral("tools-report-bug");
}
QString SKGDebugPlugin::toolTip() const
{
return i18nc("A tool tip, explaining that the plugin is useful for debugging purposes", "Useful for debug");
}
bool SKGDebugPlugin::isInPagesChooser() const
{
return true;
}
bool SKGDebugPlugin::isEnabled() const
{
return (SKGTraces::SKGLevelTrace > 0 || SKGTraces::SKGPerfo);
}
void SKGDebugPlugin::onRestartProfiling()
{
SKGTraces::cleanProfilingStatistics();
}
void SKGDebugPlugin::onOpenProfiling()
{
// Call debug plugin
QString dumpString;
QStringList dump = SKGTraces::getProfilingStatistics();
int nbl = dump.count();
for (int i = 0; i < nbl; ++i) {
dumpString += dump.at(i);
dumpString += '\n';
}
if (SKGMainPanel::getMainPanel() != nullptr) {
SKGMainPanel::getMainPanel()->openPage("skg://debug_plugin/?sqlResult=" % SKGServices::encodeForUrl(dumpString));
}
}
#include <skgdebugplugin.moc>
diff --git a/plugins/generic/skg_debug/skgdebugplugin.h b/plugins/generic/skg_debug/skgdebugplugin.h
index 19226fcbd..7eae6e628 100644
--- a/plugins/generic/skg_debug/skgdebugplugin.h
+++ b/plugins/generic/skg_debug/skgdebugplugin.h
@@ -1,99 +1,99 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGDEBUGPLUGIN_H
#define SKGDEBUGPLUGIN_H
/** @file
* This file is a plugin for debug.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skginterfaceplugin.h"
/**
* This file is a plugin for debug
*/
class SKGDebugPlugin : public SKGInterfacePlugin
{
Q_OBJECT
Q_INTERFACES(SKGInterfacePlugin)
public:
/**
* Default Constructor
*/
explicit SKGDebugPlugin(QWidget* iWidget, QObject* iParent, const QVariantList& iArg);
/**
* Default Destructor
*/
~SKGDebugPlugin() override;
/**
* Called to initialise the plugin
* @param iDocument the main document
* @return true if the plugin is compatible with the document
*/
bool setupActions(SKGDocument* iDocument) override;
/**
* The page widget of the plugin.
* @return The page widget of the plugin
*/
SKGTabPage* getWidget() override;
/**
* The title of the plugin.
* @return The title of the plugin
*/
QString title() const override;
/**
* The icon of the plugin.
* @return The icon of the plugin
*/
QString icon() const override;
/**
* The toolTip of the plugin.
* @return The toolTip of the plugin
*/
QString toolTip() const override;
/**
* Must be implemented to know if a plugin must be display in pages chooser.
* @return true of false (default = false)
*/
bool isInPagesChooser() const override;
/**
* Must be implemented to know if this plugin is enabled
* @return true of false (default = true)
*/
bool isEnabled() const override;
private Q_SLOTS:
void onRestartProfiling();
void onOpenProfiling();
private:
Q_DISABLE_COPY(SKGDebugPlugin)
SKGDocument* m_currentDocument;
};
#endif // SKGDEBUGPLUGIN_H
diff --git a/plugins/generic/skg_debug/skgdebugpluginwidget.cpp b/plugins/generic/skg_debug/skgdebugpluginwidget.cpp
index dc5ce0e69..0ea040ea6 100644
--- a/plugins/generic/skg_debug/skgdebugpluginwidget.cpp
+++ b/plugins/generic/skg_debug/skgdebugpluginwidget.cpp
@@ -1,224 +1,224 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is a plugin for debug.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgdebugpluginwidget.h"
#include <qdom.h>
#include <qjsengine.h>
#include <qscriptengine.h>
#include "skgdocument.h"
#include "skgmainpanel.h"
#include "skgservices.h"
#include "skgtraces.h"
#include "skgtransactionmng.h"
SKGDebugPluginWidget::SKGDebugPluginWidget(QWidget* iParent, SKGDocument* iDocument)
: SKGTabPage(iParent, iDocument)
{
SKGTRACEINFUNC(10)
if (iDocument == nullptr) {
return;
}
ui.setupUi(this);
// Set icons
ui.kSQLPushButton->setIcon(SKGServices::fromTheme(QStringLiteral("system-run")));
ui.kSQLTransactionPushButton->setIcon(SKGServices::fromTheme(QStringLiteral("system-run")));
ui.kRefreshViewsAndIndexes->setIcon(SKGServices::fromTheme(QStringLiteral("view-refresh")));
// Fill combo box
ui.kExplainCmb->addItem(SKGServices::fromTheme(QStringLiteral("system-run")), i18nc("Execute an SQL query", "Execute"));
ui.kExplainCmb->addItem(SKGServices::fromTheme(QStringLiteral("help-hint")), i18nc("Explain an SQL query", "Explain"));
ui.kExplainCmb->addItem(SKGServices::fromTheme(QStringLiteral("games-hint")), i18nc("Explain the SQL query plan", "Explain query plan"));
ui.kExplainCmb->addItem(SKGServices::fromTheme(QStringLiteral("media-playback-start")), i18nc("Execute script", "Execute script [%1]", "javascript"));
ui.kInput->setVisible(false);
// Set level trace
ui.kTraceLevel->setValue(SKGTraces::SKGLevelTrace);
// Set profiling mode
ui.kEnableProfilingChk->setCheckState(SKGTraces::SKGPerfo ? Qt::Checked : Qt::Unchecked);
// Init debug page
QStringList tables;
ui.kSQLInput->addItem(QStringLiteral("SELECT * FROM sqlite_master;"));
iDocument->getDistinctValues(QStringLiteral("sqlite_master"), QStringLiteral("name"), QStringLiteral("type in ('table', 'view')"), tables);
int nb = tables.count();
for (int i = 0; i < nb; ++i) {
ui.kSQLInput->addItem("SELECT * FROM " % tables.at(i) % ';');
}
ui.kSQLInput->addItem(QStringLiteral("ANALYZE;"));
ui.kSQLInput->addItem(QStringLiteral("PRAGMA integrity_check;"));
for (int i = 0; i < nb; ++i) {
ui.kSQLInput->addItem("PRAGMA table_info(" % tables.at(i) % ");");
ui.kSQLInput->addItem("PRAGMA index_list(" % tables.at(i) % ");");
}
iDocument->getDistinctValues(QStringLiteral("sqlite_master"), QStringLiteral("name"), QStringLiteral("type='index'"), tables);
nb = tables.count();
for (int i = 0; i < nb; ++i) {
ui.kSQLInput->addItem("PRAGMA index_info(" % tables.at(i) % ");");
}
connect(ui.kTraceLevel, &QSlider::valueChanged, this, &SKGDebugPluginWidget::onTraceLevelModified);
connect(ui.kEnableProfilingChk, &QCheckBox::stateChanged, this, &SKGDebugPluginWidget::onProfilingModeChanged);
connect(ui.kExplainCmb, static_cast<void (SKGComboBox::*)(int)>(&SKGComboBox::currentIndexChanged), this, &SKGDebugPluginWidget::onModeChanged);
connect(ui.kSQLPushButton, &QPushButton::clicked, this, &SKGDebugPluginWidget::onExecuteSqlOrder);
connect(ui.kSQLTransactionPushButton, &QPushButton::clicked, this, &SKGDebugPluginWidget::onExecuteSqlOrderInTransaction);
connect(ui.kRefreshViewsAndIndexes, &QPushButton::clicked, this, &SKGDebugPluginWidget::onRefreshViewsAndIndexes);
}
SKGDebugPluginWidget::~SKGDebugPluginWidget()
{
SKGTRACEINFUNC(10)
}
QString SKGDebugPluginWidget::getState()
{
SKGTRACEINFUNC(10)
QDomDocument doc(QStringLiteral("SKGML"));
QDomElement root = doc.createElement(QStringLiteral("parameters"));
doc.appendChild(root);
root.setAttribute(QStringLiteral("explain"), ui.kExplainCmb->currentIndex());
root.setAttribute(QStringLiteral("enableProfiling"), ui.kEnableProfilingChk->checkState() == Qt::Checked ? QStringLiteral("Y") : QStringLiteral("N"));
root.setAttribute(QStringLiteral("levelTraces"), ui.kTraceLevel->value());
root.setAttribute(QStringLiteral("sqlOrder"), ui.kSQLInput->currentText());
return doc.toString();
}
void SKGDebugPluginWidget::setState(const QString& iState)
{
SKGTRACEINFUNC(10)
QDomDocument doc(QStringLiteral("SKGML"));
doc.setContent(iState);
QDomElement root = doc.documentElement();
QString explain = root.attribute(QStringLiteral("explain"));
QString enableProfiling = root.attribute(QStringLiteral("enableProfiling"));
QString levelTraces = root.attribute(QStringLiteral("levelTraces"));
QString sqlOrder = root.attribute(QStringLiteral("sqlOrder"));
QString sqlResult = root.attribute(QStringLiteral("sqlResult"));
if (!explain.isEmpty()) {
ui.kExplainCmb->setCurrentIndex(SKGServices::stringToInt(explain == QStringLiteral("Y") ? QStringLiteral("1") : explain));
}
if (!enableProfiling.isEmpty()) {
ui.kEnableProfilingChk->setCheckState(enableProfiling == QStringLiteral("Y") ? Qt::Checked : Qt::Unchecked);
}
if (!levelTraces.isEmpty()) {
ui.kTraceLevel->setValue(SKGServices::stringToInt(levelTraces));
}
ui.kSQLInput->setText(sqlOrder);
ui.kSQLResult->setPlainText(sqlResult);
}
void SKGDebugPluginWidget::onExecuteSqlOrderInTransaction()
{
onExecuteSqlOrder(true);
}
void SKGDebugPluginWidget::onExecuteSqlOrder(bool iInTransaction)
{
SKGTRACEINFUNC(10)
SKGError err;
int exp = ui.kExplainCmb->currentIndex();
if (exp > 2) {
// Script execution
ui.kSQLResult->clear();
QJSEngine myEngine;
// skgresult.setText(skgdocument.getUniqueIdentifier())
// skgerror=skgdocument.sendMessage(QStringLiteral("Hello"))
// skgerror=skgdocument.sendMessage(QStringLiteral("Hello"))
// skgmainpanel.closeAllOtherPages(skgmainpanel.currentPage())
auto t = myEngine.globalObject();
t.setProperty(QStringLiteral("skgresult"), myEngine.newQObject(ui.kSQLResult));
t.setProperty(QStringLiteral("skgdocument"), myEngine.newQObject(getDocument()));
t.setProperty(QStringLiteral("skgerror"), myEngine.newQObject(&err));
t.setProperty(QStringLiteral("skgmainpanel"), myEngine.newQObject(SKGMainPanel::getMainPanel()));
// Finally execute the scripting code.
myEngine.evaluate(ui.kInput->toPlainText());
} else {
// SQL execution
QString text = ui.kSQLInput->currentText();
if (exp == 1) {
text = "EXPLAIN " % text;
} else if (exp == 2) {
text = "EXPLAIN QUERY PLAN " % text;
}
QString oResult;
double time = SKGServices::getMicroTime();
if (iInTransaction) {
SKGBEGINTRANSACTION(*getDocument(), i18nc("Display an SQL command from the debug plugin", "SQL command from debug plugin"), err)
IFOKDO(err, getDocument()->dumpSelectSqliteOrder(text, oResult))
} else {
QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
err = getDocument()->dumpSelectSqliteOrder(text, oResult);
QApplication::restoreOverrideCursor();
}
time = SKGServices::getMicroTime() - time;
oResult += i18nc("Display the execution time needed by an SQL query", "\nExecution time: %1 ms", SKGServices::doubleToString(time));
IFOK(err) {
ui.kSQLResult->setPlainText(oResult);
} else {
ui.kSQLResult->setPlainText(err.getFullMessageWithHistorical());
}
}
}
void SKGDebugPluginWidget::onTraceLevelModified()
{
SKGTRACEINFUNC(10)
SKGTraces::SKGLevelTrace = ui.kTraceLevel->value();
}
void SKGDebugPluginWidget::onModeChanged()
{
SKGTRACEINFUNC(10)
int exp = ui.kExplainCmb->currentIndex();
ui.kInput->setVisible(exp > 2);
ui.kSQLInput->setVisible(exp < 3);
}
void SKGDebugPluginWidget::onProfilingModeChanged()
{
SKGTRACEINFUNC(10)
SKGTraces::SKGPerfo = (ui.kEnableProfilingChk->checkState() == Qt::Checked);
}
void SKGDebugPluginWidget::onRefreshViewsAndIndexes()
{
SKGTRACEINFUNC(10)
QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
SKGError err;
err = getDocument()->refreshViewsIndexesAndTriggers();
IFKO(err) {
ui.kSQLResult->setPlainText(err.getFullMessageWithHistorical());
}
QApplication::restoreOverrideCursor();
}
diff --git a/plugins/generic/skg_debug/skgdebugpluginwidget.h b/plugins/generic/skg_debug/skgdebugpluginwidget.h
index d60430551..0a401118e 100644
--- a/plugins/generic/skg_debug/skgdebugpluginwidget.h
+++ b/plugins/generic/skg_debug/skgdebugpluginwidget.h
@@ -1,76 +1,76 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGDEBUGPLUGINWIDGET_H
#define SKGDEBUGPLUGINWIDGET_H
/** @file
* This file is a plugin for debug.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgtabpage.h"
#include "ui_skgdebugpluginwidget_base.h"
/**
* This file is a plugin for debug
*/
class SKGDebugPluginWidget : public SKGTabPage
{
Q_OBJECT
public:
/**
* Default Constructor
* @param iParent the parent widget
* @param iDocument the document
*/
explicit SKGDebugPluginWidget(QWidget* iParent, SKGDocument* iDocument);
/**
* Default Destructor
*/
~SKGDebugPluginWidget() override;
/**
* Get the current state
* MUST BE OVERWRITTEN
* @return a string containing all information needed to set the same state.
* Could be an XML stream
*/
QString getState() override;
/**
* Set the current state
* MUST BE OVERWRITTEN
* @param iState must be interpreted to set the state of the widget
*/
void setState(const QString& iState) override;
private Q_SLOTS:
void onExecuteSqlOrderInTransaction();
void onExecuteSqlOrder(bool iInTransaction = false);
void onTraceLevelModified();
void onProfilingModeChanged();
void onModeChanged();
void onRefreshViewsAndIndexes();
private:
Q_DISABLE_COPY(SKGDebugPluginWidget)
Ui::skgdebugplugin_base ui{};
};
#endif // SKGDEBUGPLUGINWIDGET_H
diff --git a/plugins/generic/skg_debug/tests/CMakeLists.txt b/plugins/generic/skg_debug/tests/CMakeLists.txt
index 2595450a9..e30ae15d1 100644
--- a/plugins/generic/skg_debug/tests/CMakeLists.txt
+++ b/plugins/generic/skg_debug/tests/CMakeLists.txt
@@ -1,39 +1,39 @@
#***************************************************************************
#* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
#* *
#* 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 <http://www.gnu.org/licenses/> *
+#* along with this program. If not, see <https://www.gnu.org/licenses/> *
#***************************************************************************
MESSAGE( STATUS "..:: CMAKE PLUGIN_DEBUG_TEST ::..")
PROJECT(plugin_debug_test)
ADD_DEFINITIONS(-DQT_GUI_LIB)
LINK_DIRECTORIES (${LIBRARY_OUTPUT_PATH})
INCLUDE_DIRECTORIES( ${CMAKE_SOURCE_DIR}/tests/skgbasemodelertest )
#Add test
ENABLE_TESTING()
FILE(GLOB cpp_files "skgtest*.cpp")
LIST(SORT cpp_files)
FOREACH(file ${cpp_files})
GET_FILENAME_COMPONENT(utname ${file} NAME_WE)
SET(SRC ../skgdebugplugin.cpp ../skgdebugpluginwidget.cpp)
ki18n_wrap_ui(SRC ../skgdebugpluginwidget_base.ui)
ADD_EXECUTABLE(${utname} ${file} ${SRC})
TARGET_LINK_LIBRARIES(${utname} Qt5::Gui Qt5::Core Qt5::Test skgbasegui skgbasemodeler)
ADD_TEST(NAME ${utname} COMMAND ${CMAKE_SOURCE_DIR}/tests/scripts/${utname}.sh)
ENDFOREACH()
INCLUDE(CTest)
diff --git a/plugins/generic/skg_debug/tests/skgtestdebugplugin.cpp b/plugins/generic/skg_debug/tests/skgtestdebugplugin.cpp
index 997418925..7cd13ee06 100644
--- a/plugins/generic/skg_debug/tests/skgtestdebugplugin.cpp
+++ b/plugins/generic/skg_debug/tests/skgtestdebugplugin.cpp
@@ -1,42 +1,42 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is a test for SKGDebugPlugin component.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgtestdebugplugin.h"
#include "skgdocument.h"
#include "../skgdebugplugin.h"
#include "../../../../tests/skgbasemodelertest/skgtestmacro.h"
#include <QAction>
void SKGTESTDebugPlugin::TestPlugin()
{
SKGDocument doc;
SKGDebugPlugin plugin(nullptr, nullptr, QVariantList());
SKGTESTPLUGIN(plugin, doc);
QCOMPARE(plugin.isInPagesChooser(), true);
QCOMPARE(plugin.isEnabled(), false);
SKGTESTTRIGGERACTION("debug_restart_profiling");
SKGTESTTRIGGERACTION("debug_open_profiling");
}
QTEST_MAIN(SKGTESTDebugPlugin)
diff --git a/plugins/generic/skg_debug/tests/skgtestdebugplugin.h b/plugins/generic/skg_debug/tests/skgtestdebugplugin.h
index 3e4edbcbf..b53788b20 100644
--- a/plugins/generic/skg_debug/tests/skgtestdebugplugin.h
+++ b/plugins/generic/skg_debug/tests/skgtestdebugplugin.h
@@ -1,35 +1,35 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGTESTDEBUGPLUGIN_H
#define SKGTESTDEBUGPLUGIN_H
/** @file
* This file is a test for SKGDebugPlugin component.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include <qtest.h>
/**
* A unit test
*/
class SKGTESTDebugPlugin: public QObject
{
Q_OBJECT
private Q_SLOTS:
void TestPlugin();
};
#endif
diff --git a/plugins/generic/skg_delete/CMakeLists.txt b/plugins/generic/skg_delete/CMakeLists.txt
index 0981ac64b..a6c3dbe5f 100644
--- a/plugins/generic/skg_delete/CMakeLists.txt
+++ b/plugins/generic/skg_delete/CMakeLists.txt
@@ -1,31 +1,31 @@
#***************************************************************************
#* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
#* *
#* 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 <http://www.gnu.org/licenses/> *
+#* along with this program. If not, see <https://www.gnu.org/licenses/> *
#***************************************************************************
MESSAGE( STATUS "..:: CMAKE PLUGIN_DELETE ::..")
PROJECT(plugin_delete)
LINK_DIRECTORIES (${LIBRARY_OUTPUT_PATH})
SET(skg_delete_SRCS skgdeleteplugin.cpp)
ADD_LIBRARY(skg_delete MODULE ${skg_delete_SRCS})
TARGET_LINK_LIBRARIES(skg_delete KF5::Parts skgbasemodeler skgbasegui)
########### install files ###############
INSTALL(TARGETS skg_delete DESTINATION ${KDE_INSTALL_QTPLUGINDIR})
INSTALL(FILES ${PROJECT_SOURCE_DIR}/org.kde.skg-plugin-delete.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR})
INSTALL(FILES ${PROJECT_SOURCE_DIR}/skg_delete.rc DESTINATION ${KDE_INSTALL_KXMLGUI5DIR}/skg_delete )
diff --git a/plugins/generic/skg_delete/org.kde.skg-plugin-delete.desktop b/plugins/generic/skg_delete/org.kde.skg-plugin-delete.desktop
index a7520c6a7..38c0bf2a0 100644
--- a/plugins/generic/skg_delete/org.kde.skg-plugin-delete.desktop
+++ b/plugins/generic/skg_delete/org.kde.skg-plugin-delete.desktop
@@ -1,77 +1,77 @@
[Desktop Entry]
Name=Delete plugin
Name[bs]=Dodatak za brisanje
Name[ca]=Connector de supressió
Name[ca@valencia]=Connector de supressió
Name[cs]=Rozšíření pro mazání
Name[da]=Slette-plugin
Name[de]=Lösch-Modul
Name[el]=Delete plugin
Name[en_GB]=Delete plugin
Name[es]=Complemento de borrado
Name[et]=Kustutamisplugin
Name[fi]=Poistamisliitännäinen
Name[fr]=Module externe de suppression
Name[gl]=Complemento de eliminar
Name[hu]=Törlés bővítmény
Name[it]=Estensione di eliminazione
Name[lt]=Ištrinti papildinį
Name[nb]=Slett-modul
Name[nds]=Wegmaakmoduul
Name[nl]=Plugin voor verwijderen
Name[pl]=Wtyczka usuwania
Name[pt]='Plugin' de remoção
Name[pt_BR]=Plugin de remoção
Name[ru]=Модуль удаления
Name[sk]=Mazací plugin
Name[sv]=Borttagningsinsticksprogram
Name[tr]=Silme eklentisi
Name[uk]=Додаток вилучення
Name[x-test]=xxDelete pluginxx
Name[zh_CN]=删除插件
Name[zh_TW]=刪除外掛程式
Comment=A plugin for delete
Comment[bs]=Dodatak za brisanje
Comment[ca]=Un connector per suprimir
Comment[ca@valencia]=Un connector per suprimir
Comment[cs]=Modul pro mazání
Comment[da]=Et plugin til sletning
Comment[de]=Ein Modul zum Löschen
Comment[el]=Ένα πρόσθετο για τη διαγραφή
Comment[en_GB]=A plugin for delete
Comment[es]=Un complemento para eliminar
Comment[et]=Kustutamisplugin
Comment[fi]=Poistamisliitännäinen
Comment[fr]=Un module externe de suppression
Comment[gl]=Un complemento para eliminar.
Comment[hu]=Egy bővítmény a törléshez
Comment[it]=Un'estensione per le eliminazioni
Comment[lt]=Papildinys šalinimui
Comment[nb]=Et programtillegg for sletting
Comment[nds]=En Wegmaakmoduul
Comment[nl]=Een plugin voor verwijderen
Comment[pl]=Wtyczka do usuwania
Comment[pt]=Um 'plugin' de remoção
Comment[pt_BR]=Um plugin para remover
Comment[ru]=Модуль удаления
Comment[sk]=Plugin na mazanie
Comment[sv]=Ett insticksprogram för borttagning
Comment[tr]=Silme için bir eklenti
Comment[uk]=Додаток для вилучення
Comment[x-test]=xxA plugin for deletexx
Comment[zh_TW]=刪除用的外掛程式
Encoding=UTF-8
Icon=quickopen
Type=Service
X-KDE-ServiceTypes=SKG GUI/Plugin
X-KDE-Library=skg_delete
X-Krunner-ID=Delete plugin
X-KDE-PluginInfo-Author=Stephane MANKOWSKI,miraks
X-KDE-PluginInfo-Email=stephane@mankowski.fr
X-KDE-PluginInfo-Name=skg_delete
X-KDE-PluginInfo-Version=1.0
-X-KDE-PluginInfo-Website=http://skrooge.org/
+X-KDE-PluginInfo-Website=https://skrooge.org/
X-KDE-PluginInfo-Category=Plugins
X-KDE-PluginInfo-Depends=
X-KDE-PluginInfo-License=GPL
X-KDE-PluginInfo-EnabledByDefault=true
diff --git a/plugins/generic/skg_delete/skgdeleteplugin.cpp b/plugins/generic/skg_delete/skgdeleteplugin.cpp
index 3e80e4f24..944ecfeb4 100644
--- a/plugins/generic/skg_delete/skgdeleteplugin.cpp
+++ b/plugins/generic/skg_delete/skgdeleteplugin.cpp
@@ -1,138 +1,138 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is a plugin for delete operation.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgdeleteplugin.h"
#include <qwidget.h>
#include <kaboutdata.h>
#include <kactioncollection.h>
#include <klocalizedstring.h>
#include <kmessagebox.h>
#include <kpluginfactory.h>
#include <kstandardaction.h>
#include "skgerror.h"
#include "skgmainpanel.h"
#include "skgobjectbase.h"
#include "skgtraces.h"
#include "skgtransactionmng.h"
/**
* This plugin factory.
*/
K_PLUGIN_FACTORY(SKGDeletePluginFactory, registerPlugin<SKGDeletePlugin>();)
SKGDeletePlugin::SKGDeletePlugin(QWidget* iWidget, QObject* iParent, const QVariantList& /*iArg*/) :
SKGInterfacePlugin(iParent), m_currentDocument(nullptr)
{
Q_UNUSED(iWidget)
SKGTRACEINFUNC(10)
}
SKGDeletePlugin::~SKGDeletePlugin()
{
SKGTRACEINFUNC(10)
m_currentDocument = nullptr;
}
bool SKGDeletePlugin::setupActions(SKGDocument* iDocument)
{
SKGTRACEINFUNC(10)
m_currentDocument = iDocument;
setComponentName(QStringLiteral("skg_delete"), title());
setXMLFile(QStringLiteral("skg_delete.rc"));
// Menu
QStringList tmp;
m_currentDocument->getDistinctValues(QStringLiteral("sqlite_master"), QStringLiteral("name"), QStringLiteral("type='table' AND name!='parameters'"), tmp);
auto actDelete = new QAction(SKGServices::fromTheme(QStringLiteral("edit-delete")), i18nc("Verb, delete an item", "Delete"), this);
connect(actDelete, &QAction::triggered, this, &SKGDeletePlugin::onDelete);
actionCollection()->setDefaultShortcut(actDelete, Qt::Key_Delete);
registerGlobalAction(QStringLiteral("edit_delete"), actDelete, tmp, 1, -1, 200, true);
return true;
}
QString SKGDeletePlugin::title() const
{
return i18nc("Verb, delete an item", "Delete");
}
int SKGDeletePlugin::getOrder() const
{
return 5;
}
void SKGDeletePlugin::onDelete()
{
SKGError err;
SKGTRACEINFUNCRC(10, err)
if ((SKGMainPanel::getMainPanel() != nullptr) && (m_currentDocument != nullptr)) {
SKGObjectBase::SKGListSKGObjectBase selection = SKGMainPanel::getMainPanel()->getSelectedObjects();
int nb = selection.count();
if (nb > 0) {
if (selection[0].getRealTable() == QStringLiteral("doctransaction")) {
err = m_currentDocument->beginTransaction(QStringLiteral("#INTERNAL#"));
IFOKDO(err, m_currentDocument->executeSqliteOrder(QStringLiteral("CREATE TRIGGER fkdc_doctransaction_doctransaction_i_parent_id "
"BEFORE DELETE ON doctransaction "
"FOR EACH ROW BEGIN "
" DELETE FROM doctransaction WHERE OLD.t_name!='#INTERNAL#' AND doctransaction.id = OLD.i_parent; "
"END")));
for (int i = 0; !err && i < nb; ++i) {
err = selection.at(i).remove();
}
m_currentDocument->executeSqliteOrder(QStringLiteral("DROP TRIGGER IF EXISTS fkdc_doctransaction_doctransaction_i_parent_id"));
SKGENDTRANSACTION(m_currentDocument, err)
} else {
SKGBEGINPROGRESSTRANSACTION(*m_currentDocument, i18nc("Verb, delete an item", "Delete"), err, nb)
for (int i = 0; !err && i < nb; ++i) {
err = selection.at(i).remove();
if (err && err.getReturnCode() == ERR_FORCEABLE) {
QApplication::setOverrideCursor(QCursor(Qt::ArrowCursor));
int rc = KMessageBox::questionYesNo(SKGMainPanel::getMainPanel(),
err.getFullMessage() % '\n' % i18nc("Question", "Do you want to force the deletion ?"),
i18nc("Question", "Do you want to force the deletion ?"),
KStandardGuiItem::yes(), KStandardGuiItem::no(),
QStringLiteral("forcedelete"));
QApplication::restoreOverrideCursor();
if (rc == KMessageBox::Yes) {
err = selection.at(i).remove(true, true);
}
}
IFOKDO(err, m_currentDocument->stepForward(i + 1))
}
}
}
//
KMessageBox::enableMessage(QStringLiteral("forcedelete"));
// status bar
IFOKDO(err, SKGError(0, i18nc("Successful message after an user action", "Objects deleted.")))
}
// Display error
SKGMainPanel::displayErrorMessage(err, true);
}
#include <skgdeleteplugin.moc>
diff --git a/plugins/generic/skg_delete/skgdeleteplugin.h b/plugins/generic/skg_delete/skgdeleteplugin.h
index 9a37b8fac..9c2712cd9 100644
--- a/plugins/generic/skg_delete/skgdeleteplugin.h
+++ b/plugins/generic/skg_delete/skgdeleteplugin.h
@@ -1,74 +1,74 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGDELETEPLUGIN_H
#define SKGDELETEPLUGIN_H
/** @file
* This file is a plugin for delete operation.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skginterfaceplugin.h"
class QAction;
/**
* This file is a plugin for delete operation
*/
class SKGDeletePlugin : public SKGInterfacePlugin
{
Q_OBJECT
Q_INTERFACES(SKGInterfacePlugin)
public:
/**
* Default Constructor
*/
explicit SKGDeletePlugin(QWidget* iWidget, QObject* iParent, const QVariantList& iArg);
/**
* Default Destructor
*/
~SKGDeletePlugin() override;
/**
* Called to initialise the plugin
* @param iDocument the main document
* @return true if the plugin is compatible with the document
*/
bool setupActions(SKGDocument* iDocument) override;
/**
* The title of the plugin.
* @return The title of the plugin
*/
QString title() const override;
/**
* Must be implemented to set the position of the plugin.
* @return integer value between 0 and 999 (default = 999)
*/
int getOrder() const override;
private Q_SLOTS:
void onDelete();
private:
Q_DISABLE_COPY(SKGDeletePlugin)
SKGDocument* m_currentDocument;
};
#endif // SKGDEBUGPLUGIN_H
diff --git a/plugins/generic/skg_file/CMakeLists.txt b/plugins/generic/skg_file/CMakeLists.txt
index b6e09173c..55218488f 100644
--- a/plugins/generic/skg_file/CMakeLists.txt
+++ b/plugins/generic/skg_file/CMakeLists.txt
@@ -1,41 +1,41 @@
#***************************************************************************
#* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
#* *
#* 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 <http://www.gnu.org/licenses/> *
+#* along with this program. If not, see <https://www.gnu.org/licenses/> *
#***************************************************************************
MESSAGE( STATUS "..:: CMAKE PLUGIN_FILE ::..")
PROJECT(plugin_file)
IF(SKG_BUILD_TEST AND NOT WIN32)
ADD_SUBDIRECTORY(tests)
ENDIF(SKG_BUILD_TEST AND NOT WIN32)
LINK_DIRECTORIES (${LIBRARY_OUTPUT_PATH})
SET(skg_file_SRCS skgfileplugin.cpp )
ki18n_wrap_ui(skg_file_SRCS skgfilepluginwidget_pref.ui )
kconfig_add_kcfg_files(skg_file_SRCS skgfile_settings.kcfgc )
ADD_LIBRARY(skg_file MODULE ${skg_file_SRCS})
TARGET_LINK_LIBRARIES(skg_file KF5::Parts KF5::ItemViews KF5::Wallet skgbasemodeler skgbasegui)
########### install files ###############
INSTALL(TARGETS skg_file DESTINATION ${KDE_INSTALL_QTPLUGINDIR})
INSTALL(FILES ${PROJECT_SOURCE_DIR}/skgfile_settings.kcfg DESTINATION ${KDE_INSTALL_KCFGDIR} )
INSTALL(FILES ${PROJECT_SOURCE_DIR}/org.kde.skg-plugin-file.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR})
INSTALL(FILES ${PROJECT_SOURCE_DIR}/skg_file.rc DESTINATION ${KDE_INSTALL_KXMLGUI5DIR}/skg_file )
diff --git a/plugins/generic/skg_file/org.kde.skg-plugin-file.desktop b/plugins/generic/skg_file/org.kde.skg-plugin-file.desktop
index 12b0da001..26aa174a5 100644
--- a/plugins/generic/skg_file/org.kde.skg-plugin-file.desktop
+++ b/plugins/generic/skg_file/org.kde.skg-plugin-file.desktop
@@ -1,78 +1,78 @@
[Desktop Entry]
Name=File plugin
Name[bs]=Dodatak za datoteke
Name[ca]=Connector de fitxer
Name[ca@valencia]=Connector de fitxer
Name[cs]=Souborový modul
Name[da]=Fil-plugin
Name[de]=Datei-Modul
Name[el]=File plugin
Name[en_GB]=File plugin
Name[es]=Complemento de archivo
Name[et]=Failiplugin
Name[fi]=Tiedostoliitännäinen
Name[fr]=Module externe de gestion de fichiers
Name[gl]=Complemento de ficheiros
Name[hu]=Fájl bővítmény
Name[it]=Estensione per i file
Name[lt]=Failo papildinys
Name[nb]=Filmodul
Name[nds]=Dateimoduul
Name[nl]=Plugin voor bestand
Name[pl]=Wtyczka pliku
Name[pt]='Plugin' de ficheiros
Name[pt_BR]=Plugin de arquivo
Name[ru]=Модуль файлов
Name[sk]=Súborový plugin
Name[sv]=Filinsticksprogram
Name[tr]=Dosya eklentisi
Name[uk]=Додаток файлів
Name[x-test]=xxFile pluginxx
Name[zh_CN]=文件插件
Name[zh_TW]=檔案外掛程式
Comment=A plugin for file operations
Comment[bs]=Dodatak za operacije nad datotekama
Comment[ca]=Un connector per operacions amb fitxers
Comment[ca@valencia]=Un connector per operacions amb fitxers
Comment[cs]=Modul pro správu operací se soubory
Comment[da]=Et plugin til filhandlinger
Comment[de]=Ein Modul für Datei-Vorgänge
Comment[el]=Ένα πρόσθετο για λειτουργίες αρχείων
Comment[en_GB]=A plugin for file operations
Comment[es]=Un complemento para operaciones con archivos
Comment[et]=Failitoimingute plugin
Comment[fi]=Tiedostotoimintojen liitännäinen
Comment[fr]=Un module externe de gestion de fichiers
Comment[gl]=Un complemento para as operacións con ficheiros.
Comment[hu]=Egy bővítmény a fájlműveletekhez
Comment[it]=Un'estensione per le operazioni sui file
Comment[lt]=Failų operacijų papildinys
Comment[nb]=Et programtillegg for filhandlinger
Comment[nds]=En Dateiakschoon-Moduul
Comment[nl]=Een plugin voor bestandsbewerkingen
Comment[pl]=Wtyczka do operacji na plikach
Comment[pt]=Um 'plugin' para operações com ficheiros
Comment[pt_BR]=Um plugin para operações com arquivos
Comment[ru]=Модуль для действий с файлами
Comment[sk]=Plugin na súborové operácie
Comment[sv]=Ett insticksprogram för filhantering
Comment[tr]=Dosya işlemleri için bir eklenti
Comment[uk]=Додаток для виконання дій з файлами
Comment[x-test]=xxA plugin for file operationsxx
Comment[zh_CN]=负责文件操作的插件
Comment[zh_TW]=檔案操作用的外掛程式
Encoding=UTF-8
Icon=quickopen
Type=Service
X-KDE-ServiceTypes=SKG GUI/Plugin
X-KDE-Library=skg_file
X-Krunner-ID=File plugin
X-KDE-PluginInfo-Author=Stephane MANKOWSKI,miraks
X-KDE-PluginInfo-Email=stephane@mankowski.fr
X-KDE-PluginInfo-Name=skrooge_file
X-KDE-PluginInfo-Version=1.0
-X-KDE-PluginInfo-Website=http://skrooge.org/
+X-KDE-PluginInfo-Website=https://skrooge.org/
X-KDE-PluginInfo-Category=Plugins
X-KDE-PluginInfo-Depends=
X-KDE-PluginInfo-License=GPL
X-KDE-PluginInfo-EnabledByDefault=true
diff --git a/plugins/generic/skg_file/skgfileplugin.cpp b/plugins/generic/skg_file/skgfileplugin.cpp
index 94ce0661a..2d32a4085 100644
--- a/plugins/generic/skg_file/skgfileplugin.cpp
+++ b/plugins/generic/skg_file/skgfileplugin.cpp
@@ -1,625 +1,625 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is a plugin for file operation.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgfileplugin.h"
#include <kaboutdata.h>
#include <kactioncollection.h>
#include <kmessagewidget.h>
#include <knewpassworddialog.h>
#include <kpassworddialog.h>
#include <kpluginfactory.h>
#include <krecentfilesaction.h>
#include <kstandardaction.h>
#include <kwallet.h>
#include <qfile.h>
#include <qfiledialog.h>
#include <qsplashscreen.h>
#include <qwidget.h>
#include "skgerror.h"
#include "skgfile_settings.h"
#include "skgmainpanel.h"
#include "skgtraces.h"
#include "skgtransactionmng.h"
/**
* This plugin factory.
*/
K_PLUGIN_FACTORY(SKGFilePluginFactory, registerPlugin<SKGFilePlugin>();)
SKGFilePlugin::SKGFilePlugin(QWidget* iWidget, QObject* iParent, const QVariantList& /*iArg*/) :
SKGInterfacePlugin(iParent),
m_saveAction(nullptr), m_recentFiles(nullptr), m_currentDocument(nullptr)
{
Q_UNUSED(iWidget)
SKGTRACEINFUNC(10)
// Set save on close mode
if (SKGMainPanel::getMainPanel() != nullptr) {
SKGMainPanel::getMainPanel()->setSaveOnClose(skgfile_settings::saveonclose());
}
}
SKGFilePlugin::~SKGFilePlugin()
{
SKGTRACEINFUNC(10)
if (m_recentFiles != nullptr) {
m_recentFiles->saveEntries(KConfigGroup(KSharedConfig::openConfig(), "RecentFiles"));
}
m_currentDocument = nullptr;
m_recentFiles = nullptr;
m_saveAction = nullptr;
}
bool SKGFilePlugin::setupActions(SKGDocument* iDocument)
{
SKGTRACEINFUNC(10)
m_currentDocument = iDocument;
if (m_currentDocument == nullptr) {
return false;
}
setComponentName(QStringLiteral("skg_file"), title());
setXMLFile(QStringLiteral("skg_file.rc"));
// Menu
registerGlobalAction(QStringLiteral("file_new"), KStandardAction::openNew(this, SLOT(onNew()), actionCollection()));
registerGlobalAction(QStringLiteral("file_open"), KStandardAction::open(this, SLOT(onOpen()), actionCollection()));
m_saveAction = KStandardAction::save(this, SLOT(onSave()), actionCollection());
registerGlobalAction(QStringLiteral("file_save"), m_saveAction);
registerGlobalAction(QStringLiteral("file_save_as"), KStandardAction::saveAs(this, SLOT(onSaveAs()), actionCollection()));
auto actChangePassword = new QAction(SKGServices::fromTheme(QStringLiteral("document-encrypt")), i18nc("Action allowing the user to change his document password", "Change password..."), this);
connect(actChangePassword, &QAction::triggered, this, &SKGFilePlugin::onChangePassword);
actionCollection()->setDefaultShortcut(actChangePassword, Qt::CTRL + Qt::Key_K);
registerGlobalAction(QStringLiteral("file_change_password"), actChangePassword);
// Recent file
m_recentFiles = KStandardAction::openRecent(this, SLOT(onOpen(QUrl)), actionCollection());
if (m_recentFiles != nullptr) {
m_recentFiles->loadEntries(KConfigGroup(KSharedConfig::openConfig(), "RecentFiles"));
}
// Get last argument
connect(this, &SKGFilePlugin::loadFile, this, &SKGFilePlugin::onOpen, Qt::QueuedConnection);
return true;
}
QStringList SKGFilePlugin::processArguments(const QStringList& iArgument)
{
SKGTRACEINFUNC(10)
QStringList output = iArgument;
if (m_currentDocument->getCurrentFileName().isEmpty()) {
int nbArg = iArgument.count();
int openMode = 1; // 0=no open, 1=open last opened if settings set, 2=new document
if (nbArg != 0) {
openMode = 2;
QString filename = iArgument.at(nbArg - 1);
QString extension = QFileInfo(filename).suffix().toUpper();
auto inputFile = QFileInfo(filename);
if (!inputFile.isAbsolute()) {
filename = QFileInfo(QDir::currentPath(), filename).absoluteFilePath();
}
QString extensionDocument = m_currentDocument->getFileExtension().toUpper();
if (extension == extensionDocument) {
if (QFile(filename).exists()) {
if (SKGMainPanel::getMainPanel() != nullptr) {
QSplashScreen* splashScreen = SKGMainPanel::getMainPanel()->splashScreen();
if (splashScreen != nullptr) {
splashScreen->showMessage(i18nc("Splash screen message", "Opening file %1...", filename), Qt::AlignLeft, QColor(221, 130, 8)); // krazy:exclude=qmethods
}
}
Q_EMIT loadFile(QUrl::fromLocalFile(filename));
output.pop_back();
openMode = 0;
} else {
m_currentDocument->sendMessage(i18nc("Error Message", "File %1 not found! Impossible to open it.", filename), SKGDocument::Error);
}
}
}
if (openMode != 0) {
// Read Setting
bool openlastfile = skgfile_settings::openlastfile();
if (openMode == 1 && openlastfile) {
QString lastOpenedFile = skgfile_settings::lastfilepath();
if (!lastOpenedFile.isEmpty() && QFile(lastOpenedFile).exists()) {
if (SKGMainPanel::getMainPanel() != nullptr) {
QSplashScreen* splashScreen = SKGMainPanel::getMainPanel()->splashScreen();
if (splashScreen != nullptr) {
splashScreen->showMessage(i18nc("Splash screen message", "Opening file %1...", lastOpenedFile), Qt::AlignLeft, QColor(221, 130, 8)); // krazy:exclude=qmethods
}
}
Q_EMIT loadFile(QUrl::fromLocalFile(lastOpenedFile));
} else {
openMode = 2;
}
} else {
openMode = 2;
}
if (openMode == 2 && m_currentDocument->getMainDatabase() == nullptr) {
onNew();
}
}
// To be sure that the document has the right parameters
savePreferences();
}
return output;
}
QWidget* SKGFilePlugin::getPreferenceWidget()
{
SKGTRACEINFUNC(10)
auto w = new QWidget();
ui.setupUi(w);
connect(ui.kcfg_backup_enabled, &QCheckBox::toggled, ui.kcfg_prefix, &SKGComboBox::setEnabled);
connect(ui.kcfg_backup_enabled, &QCheckBox::toggled, ui.kcfg_suffix, &SKGComboBox::setEnabled);
connect(ui.kcfg_storeInKdeWallet, &QCheckBox::toggled, ui.kcfg_selectedWallet, &SKGComboBox::setEnabled);
ui.kcfg_prefix->addItem(QLatin1String(""));
ui.kcfg_prefix->addItem(QStringLiteral("."));
ui.kcfg_suffix->addItem(QStringLiteral(".old"));
ui.kcfg_suffix->addItem(QStringLiteral(".back"));
ui.kcfg_suffix->addItem(QStringLiteral(".<DATE>.back"));
ui.kcfg_suffix->addItem(QStringLiteral(".<DATE>.old"));
ui.kcfg_suffix->addItem(QStringLiteral("~"));
ui.kcfg_selectedWallet->addItems(KWallet::Wallet::walletList());
return w;
}
KConfigSkeleton* SKGFilePlugin::getPreferenceSkeleton()
{
return skgfile_settings::self();
}
SKGError SKGFilePlugin::savePreferences() const
{
SKGError err;
if (m_currentDocument != nullptr) {
// Read Setting
QString prefix;
QString suffix;
if (skgfile_settings::backup_enabled()) {
prefix = skgfile_settings::prefix();
suffix = skgfile_settings::suffix();
}
// Save setting in document
m_currentDocument->setBackupParameters(prefix, suffix);
// Set save on close mode
if (SKGMainPanel::getMainPanel()) {
SKGMainPanel::getMainPanel()->setSaveOnClose(skgfile_settings::saveonclose());
}
}
return err;
}
void SKGFilePlugin::refresh()
{
SKGTRACEINFUNC(10)
// Refresh action status
if (m_currentDocument != nullptr) {
if (m_saveAction != nullptr) {
m_saveAction->setEnabled(m_currentDocument->isFileModified());
}
}
}
QString SKGFilePlugin::title() const
{
return i18nc("Noun, a file as in a text file", "File");
}
QString SKGFilePlugin::icon() const
{
return QStringLiteral("document-save");
}
QString SKGFilePlugin::toolTip() const
{
return i18nc("File Management, as in Save File, Save As...", "File management");
}
QStringList SKGFilePlugin::tips() const
{
QStringList output;
output.push_back(i18nc("Description of a tip", "<p>... the last opened file can be <a href=\"skg://tab_configure?page=File plugin\">open automatically</a> when the application is launched.</p>"));
output.push_back(i18nc("Description of a tip", "<p>... you can secure your document with a <a href=\"skg://file_change_password\">password</a>.</p>"));
return output;
}
int SKGFilePlugin::getOrder() const
{
// Must be one of the first
return 1;
}
void SKGFilePlugin::onNew()
{
SKGError err;
SKGTRACEINFUNCRC(10, err)
if ((SKGMainPanel::getMainPanel() != nullptr) && (m_currentDocument != nullptr) && SKGMainPanel::getMainPanel()->queryFileClose()) {
QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
SKGMainPanel::getMainPanel()->closeAllPages(true);
err = m_currentDocument->initialize();
IFOKDO(err, m_currentDocument->setLanguage(QLocale::languageToString(QLocale().language())))
QApplication::restoreOverrideCursor();
// status bar
IFOKDO(err, SKGError(0, i18nc("Successful message after creating a document", "Document successfully created.")))
else {
err.addError(ERR_FAIL, i18nc("Error message: Could not create a document", "Document creation failed."));
}
// Display error
SKGMainPanel::displayErrorMessage(err);
}
}
void SKGFilePlugin::onSave()
{
SKGError err;
SKGTRACEINFUNCRC(10, err)
if ((m_currentDocument != nullptr) && (SKGMainPanel::getMainPanel() != nullptr)) {
if (m_currentDocument->getCurrentFileName().isEmpty()) {
onSaveAs();
} else {
QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
err = m_currentDocument->save();
QApplication::restoreOverrideCursor();
// Refresh
SKGMainPanel::getMainPanel()->refresh();
// status bar
IFOKDO(err, SKGError(0, i18nc("Successfully saved a file", "File successfully saved.")))
else {
err.addError(ERR_FAIL, i18nc("Error message: Could not save a file", "Cannot save file"));
}
// Display error
SKGMainPanel::displayErrorMessage(err);
}
}
}
void SKGFilePlugin::onSaveAs()
{
SKGError err;
SKGTRACEINFUNCRC(10, err)
if ((m_currentDocument != nullptr) && (SKGMainPanel::getMainPanel() != nullptr)) {
QString fileName = SKGMainPanel::getSaveFileName("kfiledialog:///" % m_currentDocument->objectName(),
"*." % m_currentDocument->getFileExtension() % '|' % i18nc("Associated with the file extension : for example, .csv --> CSV document", "%1 document", KAboutData::applicationData().displayName()),
SKGMainPanel::getMainPanel());
if (fileName.isEmpty()) {
return;
}
QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
err = m_currentDocument->saveAs(fileName, true);
QApplication::restoreOverrideCursor();
// Refresh
SKGMainPanel::getMainPanel()->refresh();
// status bar
IFOK(err) {
err = SKGError(0, i18nc("Successfully saved a file", "File '%1' saved.", fileName));
// Add in recentFiles
if (m_recentFiles != nullptr) {
m_recentFiles->addUrl(QUrl::fromLocalFile(fileName));
m_recentFiles->saveEntries(KConfigGroup(KSharedConfig::openConfig(), "RecentFiles"));
}
// Set as last open file in kcfg
KSharedConfigPtr config = KSharedConfig::openConfig();
KConfigGroup pref = config->group("File");
pref.writePathEntry("lastfilepath", fileName);
} else {
err.addError(ERR_FAIL, i18nc("Error message: Could not save a file", "Failed to save '%1'.", fileName));
}
// Display error
SKGMainPanel::displayErrorMessage(err);
}
}
void SKGFilePlugin::onReOpen()
{
auto* act = qobject_cast< QAction* >(sender());
if (act != nullptr) {
QString filename = act->data().toString();
QFile(SKGDocument::getTemporaryFile(filename)).remove();
onOpen(QUrl::fromLocalFile(filename));
}
}
void SKGFilePlugin::onOpen(const QUrl& iUrl)
{
SKGError err;
SKGTRACEINFUNCRC(10, err)
if ((SKGMainPanel::getMainPanel() != nullptr) && (m_currentDocument != nullptr) && SKGMainPanel::getMainPanel()->queryFileClose()) {
bool useKWallet = skgfile_settings::storeInKdeWallet();
QString pwd;
QString programName = KAboutData::applicationData().displayName();
QString fileName = iUrl.toLocalFile();
if (fileName.isEmpty()) {
auto* act = qobject_cast< QAction* >(sender());
if (act != nullptr) {
fileName = act->property("filename").toString();
}
}
if (fileName.isEmpty()) {
fileName = QFileDialog::getOpenFileUrl(SKGMainPanel::getMainPanel(), i18nc("Panel title", "Open file"),
QUrl(),
i18nc("File format for open dialog panel", "%1 document", programName) % "(*." % m_currentDocument->getFileExtension() % ")").toLocalFile();
}
if (!fileName.isEmpty()) {
// Check if temporary file exists
bool restoreTmpFile = false;
QString tmpFile = SKGDocument::getTemporaryFile(fileName);
if (QFile(tmpFile).exists()) {
KMessageWidget* msg = SKGMainPanel::getMainPanel()->displayMessage(i18nc("Warning message", "Your document has been restored from its temporary file. You can decide to reopen the original document."), SKGDocument::Warning);
auto reopen = new QAction(i18nc("Noun", "Reopen"), msg);
reopen->setIcon(SKGServices::fromTheme(QStringLiteral("quickopen")));
reopen->setData(fileName);
msg->addAction(reopen);
connect(reopen, &QAction::triggered, this, &SKGFilePlugin::onReOpen);
connect(reopen, &QAction::triggered, msg, &KMessageWidget::deleteLater, Qt::QueuedConnection);
restoreTmpFile = true;
}
// Open
QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
SKGMainPanel::getMainPanel()->closeAllPages(true);
err = m_currentDocument->load(fileName, QLatin1String(""), restoreTmpFile);
QApplication::restoreOverrideCursor();
if (err && err.getReturnCode() == ERR_ENCRYPTION) {
m_currentDocument->close();
// Open failed
// Password must be asked
QString additionalMessage;
do {
// Reset error
err = SKGError(0, QLatin1String(""));
pwd = QLatin1String("");
// Get password
if (useKWallet) {
SKGTRACEL(10) << "Use KWallet" << endl;
// Use KWallet
QString walletName = skgfile_settings::selectedWallet();
if (!KWallet::Wallet::walletList().contains(walletName)) {
walletName = KWallet::Wallet::walletList().value(SKGServices::stringToInt(skgfile_settings::selectedWallet()));
if (walletName.isEmpty()) {
walletName = QStringLiteral("kdewallet");
}
}
KWallet::Wallet* w = KWallet::Wallet::openWallet(walletName, SKGMainPanel::getMainPanel()->winId());
if (w != nullptr) {
// Change folder
if (!w->hasFolder(programName)) {
w->createFolder(programName);
}
w->setFolder(programName);
// Read password
w->readPassword(fileName, pwd);
if (pwd.isEmpty()) {
SKGTRACEL(10) << "Password not found in KWallet for " << fileName << endl;
useKWallet = false;
}
delete w;
w = nullptr;
}
}
if (!useKWallet) {
SKGTRACEL(10) << "Ask password" << endl;
// Use password dialog
QPointer<KPasswordDialog> dlg = new KPasswordDialog(SKGMainPanel::getMainPanel());
dlg->setPrompt(additionalMessage % i18nc("Question", "This file seems to be protected.\nPlease enter the password."));
if (dlg->exec() == QDialog::Accepted) {
pwd = dlg->password();
}
delete dlg;
}
// Load file
if (!pwd.isEmpty()) {
QSplashScreen* splashScreen = SKGMainPanel::getMainPanel()->splashScreen();
if (splashScreen != nullptr) {
splashScreen->hide();
}
QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
err = m_currentDocument->load(fileName, pwd, restoreTmpFile);
IFKO(err) {
if (err.getReturnCode() == ERR_ENCRYPTION) {
additionalMessage = i18nc("The user did not provide the correct password", "<b>Wrong password.</b>\n");
useKWallet = false;
} else {
// Load error
QApplication::restoreOverrideCursor();
break;
}
}
QApplication::restoreOverrideCursor();
if (splashScreen != nullptr) {
splashScreen->show();
}
}
} while (err);
}
IFOKDO(err, m_currentDocument->setLanguage(QLocale::languageToString(QLocale().language())))
// status bar
IFOK(err) {
err = SKGError(0, i18nc("Successfully opened a file", "File '%1' opened.", fileName));
// Add in recentFiles
if (m_recentFiles != nullptr) {
m_recentFiles->addUrl(QUrl::fromLocalFile(fileName));
m_recentFiles->saveEntries(KConfigGroup(KSharedConfig::openConfig(), "RecentFiles"));
}
// Set as last open file in kcfg
KSharedConfigPtr config = KSharedConfig::openConfig();
KConfigGroup pref = config->group("File");
pref.writePathEntry("lastfilepath", fileName);
// Store password if KDE wallet if needed
if (skgfile_settings::storeInKdeWallet() && !useKWallet) {
// Use KWallet
QString walletName = skgfile_settings::selectedWallet();
if (!KWallet::Wallet::walletList().contains(walletName)) {
walletName = KWallet::Wallet::walletList().value(SKGServices::stringToInt(skgfile_settings::selectedWallet()));
if (walletName.isEmpty()) {
walletName = QStringLiteral("kdewallet");
}
}
KWallet::Wallet* w = KWallet::Wallet::openWallet(walletName, SKGMainPanel::getMainPanel()->winId());
if (w != nullptr) {
// Change folder
w->setFolder(programName);
// Write password
w->writePassword(fileName, pwd);
delete w;
w = nullptr;
}
}
} else {
this->onNew();
if (err.getReturnCode() != ERR_CORRUPTION) {
err.addError(ERR_FAIL, i18nc("Error message: Could not open a file", "Failed to open '%1'.", fileName));
}
}
// Display error
QAction* recovery = nullptr;
#ifdef Q_OS_UNIX
if (err.getReturnCode() == ERR_CORRUPTION) {
recovery = new QAction(i18nc("Noun", "Try a recovery"), this);
recovery->setIcon(SKGServices::fromTheme(QStringLiteral("games-solve")));
recovery->setData(SKGServices::stringsToCsv(QStringList() << fileName << pwd));
connect(recovery, &QAction::triggered, this, &SKGFilePlugin::onRecover);
}
#endif
SKGMainPanel::displayErrorMessage(err, recovery);
}
}
}
void SKGFilePlugin::onRecover()
{
SKGError err;
SKGTRACEINFUNCRC(10, err)
auto* act = qobject_cast< QAction* >(sender());
if ((act != nullptr) && (m_currentDocument != nullptr) && (SKGMainPanel::getMainPanel() != nullptr)) {
QStringList params = SKGServices::splitCSVLine(act->data().toString());
QString recoveredFileName;
err = m_currentDocument->recover(params.at(0), params.at(1), recoveredFileName);
IFOK(err) {
// Display recovery message
KMessageWidget* msg = SKGMainPanel::getMainPanel()->displayMessage(i18nc("Positive message", "Your document has been recovered here: %1\nTake care the recovery could be not perfect", recoveredFileName), SKGDocument::Positive);
auto reopen = new QAction(i18nc("Noun", "Open the recovered file"), msg);
reopen->setIcon(SKGServices::fromTheme(QStringLiteral("quickopen")));
reopen->setData(recoveredFileName);
msg->addAction(reopen);
connect(reopen, &QAction::triggered, this, &SKGFilePlugin::onReOpen);
connect(reopen, &QAction::triggered, msg, &KMessageWidget::deleteLater, Qt::QueuedConnection);
} else {
// Display error
SKGMainPanel::displayErrorMessage(err);
}
}
}
void SKGFilePlugin::onChangePassword()
{
SKGError err;
SKGTRACEINFUNCRC(10, err)
if ((m_currentDocument != nullptr) && (SKGMainPanel::getMainPanel() != nullptr)) {
QPointer<KNewPasswordDialog> dlg = new KNewPasswordDialog(SKGMainPanel::getMainPanel());
dlg->setPrompt(i18n("Take care, if you lose your <b>password</b> then it will be <u><b>impossible</b></u> to open your document. Warning, this action can not be undone excepted by changing the password again."));
if (dlg->exec() == 0) {
err = SKGError(0, i18nc("Successfully changed the document password", "Changing password was canceled."));
} else {
QString newPassword = dlg->password();
IFOKDO(err, m_currentDocument->changePassword(newPassword))
// status
IFOKDO(err, SKGError(0, i18nc("Successfully changed the document password", "Password changed.")))
else {
err.addError(ERR_FAIL, i18nc("Error message: Could not change the document password", "Failed to change password."));
}
}
delete dlg;
// Display error
SKGMainPanel::displayErrorMessage(err);
}
}
SKGAdviceList SKGFilePlugin::advice(const QStringList& iIgnoredAdvice)
{
SKGTRACEINFUNC(10)
SKGAdviceList output;
// Backup
if (!iIgnoredAdvice.contains(QStringLiteral("skgfileplugin_notvalidated"))) {
SKGAdvice ad;
ad.setUUID(QStringLiteral("skgfileplugin_notvalidated"));
ad.setPriority(2);
ad.setShortMessage(i18nc("Advice to the user that he should backup his document", "Backup your document"));
ad.setLongMessage(i18nc("Explain the user that he should backup his document", "Do not forget to backup your document on another device."));
output.push_back(ad);
}
return output;
}
#include <skgfileplugin.moc>
diff --git a/plugins/generic/skg_file/skgfileplugin.h b/plugins/generic/skg_file/skgfileplugin.h
index 08c89f82d..c221e3cac 100644
--- a/plugins/generic/skg_file/skgfileplugin.h
+++ b/plugins/generic/skg_file/skgfileplugin.h
@@ -1,160 +1,160 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGFILEPLUGIN_H
#define SKGFILEPLUGIN_H
/** @file
* This file is a plugin for file operation.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include <qurl.h>
#include "skginterfaceplugin.h"
#include "ui_skgfilepluginwidget_pref.h"
class QAction;
class KRecentFilesAction;
/**
* This file is a plugin for file operation
*/
class SKGFilePlugin : public SKGInterfacePlugin
{
Q_OBJECT
Q_INTERFACES(SKGInterfacePlugin)
public:
/**
* Default Constructor
*/
explicit SKGFilePlugin(QWidget* iWidget, QObject* iParent, const QVariantList& iArg);
/**
* Default Destructor
*/
~SKGFilePlugin() override;
/**
* Called to initialise the plugin
* @param iDocument the main document
* @return true if the plugin is compatible with the document
*/
bool setupActions(SKGDocument* iDocument) override;
/**
* This function is called when the application is launched again with new arguments
* @param iArgument the arguments
* @return the rest of arguments to treat
*/
QStringList processArguments(const QStringList& iArgument) override;
/**
* The preference widget of the plugin.
* @return The preference widget of the plugin
*/
QWidget* getPreferenceWidget() override;
/**
* The preference skeleton of the plugin.
* @return The preference skeleton of the plugin
*/
KConfigSkeleton* getPreferenceSkeleton() override;
/**
* This function is called when preferences have been modified. Must be used to save some parameters into the document.
* A transaction is already opened
* @return an object managing the error.
* @see SKGError
*/
SKGError savePreferences() const override;
/**
* Must be modified to refresh widgets after a modification.
*/
void refresh() override;
/**
* The title of the plugin.
* @return The title of the plugin
*/
QString title() const override;
/**
* The icon of the plugin.
* @return The icon of the plugin
*/
QString icon() const override;
/**
* The toolTip of the plugin.
* @return The toolTip of the plugin
*/
QString toolTip() const override;
/**
* Must be implemented to set the position of the plugin.
* @return integer value between 0 and 999 (default = 999)
*/
int getOrder() const override;
/**
* The tips list of the plugin.
* @return The tips list of the plugin
*/
QStringList tips() const override;
/**
* The advice list of the plugin.
* @return The advice list of the plugin
*/
SKGAdviceList advice(const QStringList& iIgnoredAdvice) override;
Q_SIGNALS:
/**
* request to load a file
* @param iFile file name
*/
void loadFile(const QUrl& iFile);
private Q_SLOTS:
/**
* @brief Open a Url
* @param iUrl The url to open.
* If empty, then the URL is searched on the property "filename" of the QAction sending
* If still empty, an open panel is displayed
* @return void
*/
void onOpen(const QUrl& iUrl = QUrl());
void onSave();
void onSaveAs();
void onReOpen();
void onRecover();
void onNew();
void onChangePassword();
private:
Q_DISABLE_COPY(SKGFilePlugin)
QAction* m_saveAction;
KRecentFilesAction* m_recentFiles;
SKGDocument* m_currentDocument;
Ui::skgfileplugin_pref ui{};
};
#endif // SKGFILEPLUGIN_H
diff --git a/plugins/generic/skg_file/tests/CMakeLists.txt b/plugins/generic/skg_file/tests/CMakeLists.txt
index fe7c1f894..6bea3aba2 100644
--- a/plugins/generic/skg_file/tests/CMakeLists.txt
+++ b/plugins/generic/skg_file/tests/CMakeLists.txt
@@ -1,45 +1,45 @@
#***************************************************************************
#* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
#* *
#* 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 <http://www.gnu.org/licenses/> *
+#* along with this program. If not, see <https://www.gnu.org/licenses/> *
#***************************************************************************
MESSAGE( STATUS "..:: CMAKE PLUGIN_FILE_TEST ::..")
PROJECT(plugin_file_test)
IF(SKG_WEBENGINE)
MESSAGE( STATUS " Mode WebEngine")
ADD_DEFINITIONS(-DSKG_WEBENGINE=${SKG_WEBENGINE})
ENDIF(SKG_WEBENGINE)
ADD_DEFINITIONS(-DQT_GUI_LIB)
LINK_DIRECTORIES (${LIBRARY_OUTPUT_PATH})
INCLUDE_DIRECTORIES( ${CMAKE_SOURCE_DIR}/tests/skgbasemodelertest )
#Add test
ENABLE_TESTING()
FILE(GLOB cpp_files "skgtest*.cpp")
LIST(SORT cpp_files)
FOREACH(file ${cpp_files})
GET_FILENAME_COMPONENT(utname ${file} NAME_WE)
SET(SRC ../skgfileplugin.cpp)
ki18n_wrap_ui(SRC ../skgfilepluginwidget_pref.ui)
kconfig_add_kcfg_files(SRC ../skgfile_settings.kcfgc )
ADD_EXECUTABLE(${utname} ${file} ${SRC})
TARGET_LINK_LIBRARIES(${utname} KF5::Parts KF5::ItemViews KF5::Wallet Qt5::Gui Qt5::Core Qt5::Test skgbasegui skgbasemodeler)
ADD_TEST(NAME ${utname} COMMAND ${CMAKE_SOURCE_DIR}/tests/scripts/${utname}.sh)
ENDFOREACH()
INCLUDE(CTest)
diff --git a/plugins/generic/skg_file/tests/skgtestfileplugin.cpp b/plugins/generic/skg_file/tests/skgtestfileplugin.cpp
index 83bde9cef..590885d0d 100644
--- a/plugins/generic/skg_file/tests/skgtestfileplugin.cpp
+++ b/plugins/generic/skg_file/tests/skgtestfileplugin.cpp
@@ -1,44 +1,44 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is a test for SKGFilePlugin component.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgtestfileplugin.h"
#include "skgdocument.h"
#include "../skgfileplugin.h"
#include "../../../../tests/skgbasemodelertest/skgtestmacro.h"
#include <QAction>
void SKGTESTFilePlugin::TestPlugin()
{
SKGDocument doc;
SKGFilePlugin plugin(nullptr, nullptr, QVariantList());
SKGTESTPLUGIN(plugin, doc);
QCOMPARE(plugin.isInPagesChooser(), false);
QCOMPARE(plugin.isEnabled(), true);
SKGTESTTRIGGERACTION("file_new");
SKGTESTTRIGGERACTION("file_open");
SKGTESTTRIGGERACTION("file_save");
SKGTESTTRIGGERACTION("file_save_as");
SKGTESTTRIGGERACTION("file_change_password");
}
QTEST_MAIN(SKGTESTFilePlugin)
diff --git a/plugins/generic/skg_file/tests/skgtestfileplugin.h b/plugins/generic/skg_file/tests/skgtestfileplugin.h
index 12ba94c03..ce19be76b 100644
--- a/plugins/generic/skg_file/tests/skgtestfileplugin.h
+++ b/plugins/generic/skg_file/tests/skgtestfileplugin.h
@@ -1,35 +1,35 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGTESTFILEPLUGIN_H
#define SKGTESTFILEPLUGIN_H
/** @file
* This file is a test for SKGFilePlugin component.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include <qtest.h>
/**
* A unit test
*/
class SKGTESTFilePlugin: public QObject
{
Q_OBJECT
private Q_SLOTS:
void TestPlugin();
};
#endif
diff --git a/plugins/generic/skg_highlight/CMakeLists.txt b/plugins/generic/skg_highlight/CMakeLists.txt
index 69b84b3cf..69d135d4b 100644
--- a/plugins/generic/skg_highlight/CMakeLists.txt
+++ b/plugins/generic/skg_highlight/CMakeLists.txt
@@ -1,32 +1,32 @@
#***************************************************************************
#* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
#* *
#* 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 <http://www.gnu.org/licenses/> *
+#* along with this program. If not, see <https://www.gnu.org/licenses/> *
#***************************************************************************
MESSAGE( STATUS "..:: CMAKE PLUGIN_HIGHLIGHT ::..")
PROJECT(plugin_highlight)
LINK_DIRECTORIES (${LIBRARY_OUTPUT_PATH})
SET(skg_highlight_SRCS
skghighlightplugin.cpp)
ADD_LIBRARY(skg_highlight MODULE ${skg_highlight_SRCS})
TARGET_LINK_LIBRARIES(skg_highlight KF5::Parts skgbasemodeler skgbasegui)
########### install files ###############
INSTALL(TARGETS skg_highlight DESTINATION ${KDE_INSTALL_QTPLUGINDIR})
INSTALL(FILES ${PROJECT_SOURCE_DIR}/org.kde.skg-plugin-highlight.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR})
INSTALL(FILES ${PROJECT_SOURCE_DIR}/skg_highlight.rc DESTINATION ${KDE_INSTALL_KXMLGUI5DIR}/skg_highlight )
diff --git a/plugins/generic/skg_highlight/org.kde.skg-plugin-highlight.desktop b/plugins/generic/skg_highlight/org.kde.skg-plugin-highlight.desktop
index 61b393a02..d009d3efe 100644
--- a/plugins/generic/skg_highlight/org.kde.skg-plugin-highlight.desktop
+++ b/plugins/generic/skg_highlight/org.kde.skg-plugin-highlight.desktop
@@ -1,77 +1,77 @@
[Desktop Entry]
Name=Highlight plugin
Name[bs]=Dodatak za obilježavanje
Name[ca]=Connector de ressaltat
Name[ca@valencia]=Connector de ressaltat
Name[cs]=Modul pro zvýraznění
Name[da]=Fremhævningsplugin
Name[de]=Hervorhebungs-Modul
Name[el]=Πρόσθετο τονισμού
Name[en_GB]=Highlight plugin
Name[es]=Complemento de resaltado
Name[et]=Esiletõstmise plugin
Name[fi]=Korostusliitännäinen
Name[fr]=Module externe de mise en valeur
Name[ga]=Breiseán aibhsithe
Name[gl]=Complemento de realzado
Name[hu]=Kiemelés bővítmény
Name[it]=Estensione di evidenziazione
Name[lt]=Paryškinimo papildinys
Name[nb]=Programtillegg for fremheving
Name[nds]=Syntaxmarkeren-Moduul
Name[nl]=Plugin voor accentueren
Name[pl]=Wtyczka podświetlenia
Name[pt]='Plugin' de realce
Name[pt_BR]=Plugin de realce
Name[ru]=Модуль пометки
Name[sk]=Plugin zvýraznenia
Name[sv]=Markeringsinsticksprogram
Name[tr]=Vurgulama eklentisi
Name[ug]=يورۇتۇش قىستۇرمىسى
Name[uk]=Додаток підсвічування
Name[x-test]=xxHighlight pluginxx
Name[zh_TW]=突顯外掛程式
Comment=A plugin to highlight objects
Comment[bs]=Dodatak za naglašavanje objekata
Comment[ca]=Un connector per ressaltar objectes
Comment[ca@valencia]=Un connector per ressaltar objectes
Comment[cs]=Rozšíření zvýrazňující objekty
Comment[da]=Et plugin til at fremhæve objekter
Comment[de]=Ein Modul zur Hervorhebung von Objekten
Comment[el]=Ένα πρόσθετο για τονισμό αντικειμένων
Comment[en_GB]=A plugin to highlight objects
Comment[es]=Un complemento para resaltar objetos
Comment[et]=Objekte esile tõstev plugin
Comment[fi]=Kohteita korostava liitännäinen
Comment[fr]=Un module externe de mise en valeur
Comment[gl]=Un complemento para realzar obxectos.
Comment[hu]=Egy bővítmény objektumok kiemeléséhez
Comment[it]=Un'estensione per evidenziare gli oggetti
Comment[lt]=Papildinys paryškinti objektus
Comment[nb]=Et programtillegg for å fremheve objekter
Comment[nl]=Een plugin voor het accentueren van objecten
Comment[pl]=Wtyczka do podświetlania obiektów
Comment[pt]=Um 'plugin' para o realce de objectos
Comment[pt_BR]=Um plugin para realçar objetos
Comment[ru]=Модуль пометки объектов
Comment[sk]=Plugin na zvýraznenie objektov
Comment[sv]=Ett insticksprogram för att markera objekt
Comment[tr]=Nesneleri vurgulamak için bir eklenti
Comment[uk]=Додаток для підсвічування об’єктів
Comment[x-test]=xxA plugin to highlight objectsxx
Comment[zh_TW]=突顯物件用的外掛程式
Encoding=UTF-8
Icon=quickopen
Type=Service
X-KDE-ServiceTypes=SKG GUI/Plugin
X-KDE-Library=skg_highlight
X-Krunner-ID=Highlight plugin
X-KDE-PluginInfo-Author=Stephane MANKOWSKI,miraks
X-KDE-PluginInfo-Email=stephane@mankowski.fr
X-KDE-PluginInfo-Name=skg_highlight
X-KDE-PluginInfo-Version=1.0
-X-KDE-PluginInfo-Website=http://skrooge.org/
+X-KDE-PluginInfo-Website=https://skrooge.org/
X-KDE-PluginInfo-Category=Plugins
X-KDE-PluginInfo-Depends=
X-KDE-PluginInfo-License=GPL
X-KDE-PluginInfo-EnabledByDefault=true
diff --git a/plugins/generic/skg_highlight/skghighlightplugin.cpp b/plugins/generic/skg_highlight/skghighlightplugin.cpp
index 34290c1dd..609e4ffff 100644
--- a/plugins/generic/skg_highlight/skghighlightplugin.cpp
+++ b/plugins/generic/skg_highlight/skghighlightplugin.cpp
@@ -1,162 +1,162 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* A plugin to highlight objects
*
* @author Stephane MANKOWSKI
*/
#include "skghighlightplugin.h"
#include <kaboutdata.h>
#include <kactioncollection.h>
#include <klocalizedstring.h>
#include <kpluginfactory.h>
#include <kstandardaction.h>
#include "skgmainpanel.h"
#include "skgtraces.h"
#include "skgtransactionmng.h"
/**
* This plugin factory.
*/
K_PLUGIN_FACTORY(SKGHighlightPluginFactory, registerPlugin<SKGHighlightPlugin>();)
SKGHighlightPlugin::SKGHighlightPlugin(QWidget* iWidget, QObject* iParent, const QVariantList& /*iArg*/) :
SKGInterfacePlugin(iParent), m_currentDocument(nullptr)
{
Q_UNUSED(iWidget)
SKGTRACEINFUNC(10)
}
SKGHighlightPlugin::~SKGHighlightPlugin()
{
SKGTRACEINFUNC(10)
m_currentDocument = nullptr;
}
bool SKGHighlightPlugin::setupActions(SKGDocument* iDocument)
{
SKGTRACEINFUNC(10)
m_currentDocument = iDocument;
setComponentName(QStringLiteral("skg_highlight"), title());
setXMLFile(QStringLiteral("skg_highlight.rc"));
// ------------
auto actSwitchHighLight = new QAction(SKGServices::fromTheme(QStringLiteral("bookmarks")), i18nc("Verb", "Switch highlight"), this);
connect(actSwitchHighLight, &QAction::triggered, this, &SKGHighlightPlugin::onSwitchHighLight);
actionCollection()->setDefaultShortcut(actSwitchHighLight, Qt::CTRL + Qt::Key_H);
registerGlobalAction(QStringLiteral("edit_switch_highlight"), actSwitchHighLight, QStringList() << QStringLiteral("query:type='table' AND sql LIKE '%t_bookmarked%'"), 1, -1, 301);
// ------------
auto actSwitchClose = new QAction(SKGServices::fromTheme(QStringLiteral("dialog-close")), i18nc("Verb", "Switch close"), this);
connect(actSwitchClose, &QAction::triggered, this, &SKGHighlightPlugin::onSwitchClose);
registerGlobalAction(QStringLiteral("edit_switch_close"), actSwitchClose, QStringList() << QStringLiteral("query:type='table' AND sql LIKE '%t_close%'"), 1, -1, 301);
// Create yours actions here
return true;
}
QString SKGHighlightPlugin::title() const
{
return toolTip();
}
QString SKGHighlightPlugin::icon() const
{
return QStringLiteral("bookmarks");
}
QString SKGHighlightPlugin::toolTip() const
{
return i18nc("The tool tip", "Highlight");
}
int SKGHighlightPlugin::getOrder() const
{
return 6;
}
void SKGHighlightPlugin::onSwitchClose()
{
SKGError err;
SKGTRACEINFUNCRC(10, err)
// Get Selection
if ((SKGMainPanel::getMainPanel() != nullptr) && (m_currentDocument != nullptr)) {
SKGObjectBase::SKGListSKGObjectBase selection = SKGMainPanel::getMainPanel()->getSelectedObjects();
int nb = selection.count();
{
SKGBEGINPROGRESSTRANSACTION(*m_currentDocument, i18nc("Noun, name of the user action", "Close"), err, nb)
for (int i = 0; !err && i < nb; ++i) {
SKGObjectBase obj(selection.at(i));
IFOKDO(err, obj.setAttribute(QStringLiteral("t_close"), obj.getAttribute(QStringLiteral("t_close")) == QStringLiteral("Y") ? QStringLiteral("N") : QStringLiteral("Y")))
IFOKDO(err, obj.save())
// Send message
IFOKDO(err, m_currentDocument->sendMessage(i18nc("An information to the user", "The close status of '%1' has been changed", obj.getDisplayName()), SKGDocument::Hidden))
IFOKDO(err, m_currentDocument->stepForward(i + 1))
}
}
// status bar
IFOKDO(err, SKGError(0, i18nc("Successful message after an user action", "Closed.")))
else {
err.addError(ERR_FAIL, i18nc("Error message", "Closure failed"));
}
// Display error
SKGMainPanel::displayErrorMessage(err);
}
}
void SKGHighlightPlugin::onSwitchHighLight()
{
SKGError err;
SKGTRACEINFUNCRC(10, err)
// Get Selection
if ((SKGMainPanel::getMainPanel() != nullptr) && (m_currentDocument != nullptr)) {
SKGObjectBase::SKGListSKGObjectBase selection = SKGMainPanel::getMainPanel()->getSelectedObjects();
int nb = selection.count();
{
SKGBEGINPROGRESSTRANSACTION(*m_currentDocument, i18nc("Noun, name of the user action", "Highlight"), err, nb)
for (int i = 0; !err && i < nb; ++i) {
SKGObjectBase obj(selection.at(i));
IFOKDO(err, obj.setAttribute(QStringLiteral("t_bookmarked"), obj.getAttribute(QStringLiteral("t_bookmarked")) == QStringLiteral("Y") ? QStringLiteral("N") : QStringLiteral("Y")))
IFOKDO(err, obj.save())
// Send message
IFOKDO(err, m_currentDocument->sendMessage(i18nc("An information to the user", "The highlight status of '%1' has been changed", obj.getDisplayName()), SKGDocument::Hidden))
IFOKDO(err, m_currentDocument->stepForward(i + 1))
}
}
// status bar
IFOKDO(err, SKGError(0, i18nc("Successful message after an user action", "Highlighted.")))
else {
err.addError(ERR_FAIL, i18nc("Error message", "Highlight failed"));
}
// Display error
SKGMainPanel::displayErrorMessage(err);
}
}
#include <skghighlightplugin.moc>
diff --git a/plugins/generic/skg_highlight/skghighlightplugin.h b/plugins/generic/skg_highlight/skghighlightplugin.h
index bf08dd46d..7ae948da3 100644
--- a/plugins/generic/skg_highlight/skghighlightplugin.h
+++ b/plugins/generic/skg_highlight/skghighlightplugin.h
@@ -1,87 +1,87 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGHIGHLIGHTPLUGIN_H
#define SKGHIGHLIGHTPLUGIN_H
/** @file
* A plugin to highlight objects.
*
* @author Stephane MANKOWSKI
*/
#include "skginterfaceplugin.h"
/**
* A plugin to highlight objects
*/
class SKGHighlightPlugin : public SKGInterfacePlugin
{
Q_OBJECT
Q_INTERFACES(SKGInterfacePlugin)
public:
/**
* Default Constructor
*/
explicit SKGHighlightPlugin(QWidget* iWidget, QObject* iParent, const QVariantList& iArg);
/**
* Default Destructor
*/
~SKGHighlightPlugin() override;
/**
* Called to initialise the plugin
* @param iDocument the main document
* @return true if the plugin is compatible with the document
*/
bool setupActions(SKGDocument* iDocument) override;
/**
* The title of the plugin.
* @return The title of the plugin
*/
QString title() const override;
/**
* The icon of the plugin.
* @return The icon of the plugin
*/
QString icon() const override;
/**
* The toolTip of the plugin.
* @return The toolTip of the plugin
*/
QString toolTip() const override;
/**
* Must be implemented to set the position of the plugin.
* @return integer value between 0 and 999 (default = 999)
*/
int getOrder() const override;
private Q_SLOTS:
void onSwitchHighLight();
void onSwitchClose();
private:
Q_DISABLE_COPY(SKGHighlightPlugin)
SKGDocument* m_currentDocument;
};
#endif // SKGHIGHLIGHTPLUGIN_H
diff --git a/plugins/generic/skg_monthly/CMakeLists.txt b/plugins/generic/skg_monthly/CMakeLists.txt
index df8ff67be..e11dd3c6d 100644
--- a/plugins/generic/skg_monthly/CMakeLists.txt
+++ b/plugins/generic/skg_monthly/CMakeLists.txt
@@ -1,42 +1,42 @@
#***************************************************************************
#* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
#* *
#* 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 <http://www.gnu.org/licenses/> *
+#* along with this program. If not, see <https://www.gnu.org/licenses/> *
#***************************************************************************
MESSAGE( STATUS "..:: CMAKE PLUGIN_MONTHLY ::..")
PROJECT(plugin_monthly)
IF(SKG_WEBENGINE)
MESSAGE( STATUS " Mode WebEngine")
ADD_DEFINITIONS(-DSKG_WEBENGINE=${SKG_WEBENGINE})
ENDIF(SKG_WEBENGINE)
ADD_SUBDIRECTORY(grantlee_filters)
LINK_DIRECTORIES (${LIBRARY_OUTPUT_PATH})
SET(skg_monthly_SRCS
skgmonthlyplugin.cpp
skgmonthlypluginwidget.cpp)
ki18n_wrap_ui(skg_monthly_SRCS skgmonthlypluginwidget_base.ui)
ADD_LIBRARY(skg_monthly MODULE ${skg_monthly_SRCS})
TARGET_LINK_LIBRARIES(skg_monthly KF5::Parts KF5::ItemViews KF5::NewStuff KF5::Archive Qt5::PrintSupport skgbasemodeler skgbasegui)
########### install files ###############
INSTALL(TARGETS skg_monthly DESTINATION ${KDE_INSTALL_QTPLUGINDIR})
INSTALL(FILES ${PROJECT_SOURCE_DIR}/org.kde.skg-plugin-monthly.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR})
INSTALL(FILES ${PROJECT_SOURCE_DIR}/skg_monthly.rc DESTINATION ${KDE_INSTALL_KXMLGUI5DIR}/skg_monthly )
diff --git a/plugins/generic/skg_monthly/grantlee_filters/CMakeLists.txt b/plugins/generic/skg_monthly/grantlee_filters/CMakeLists.txt
index da6169538..07689006c 100644
--- a/plugins/generic/skg_monthly/grantlee_filters/CMakeLists.txt
+++ b/plugins/generic/skg_monthly/grantlee_filters/CMakeLists.txt
@@ -1,32 +1,32 @@
#***************************************************************************
#* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
#* *
#* 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 <http://www.gnu.org/licenses/> *
+#* along with this program. If not, see <https://www.gnu.org/licenses/> *
#***************************************************************************
MESSAGE( STATUS "..:: CMAKE GRANTLEE_FILTERS ::..")
PROJECT(grantlee_filters)
FIND_PACKAGE(Grantlee5 0.5 REQUIRED)
ADD_LIBRARY(grantlee_skgfilters MODULE
skggrantleefilters.cpp
skgdocumentfilter.cpp
skgobjectfilter.cpp)
SET_PROPERTY(TARGET grantlee_skgfilters PROPERTY EXPORT_NAME skggrantleefilters)
TARGET_LINK_LIBRARIES(grantlee_skgfilters KF5::CoreAddons Qt5::Core skgbasemodeler skgbasegui)
GRANTLEE_ADJUST_PLUGIN_NAME(grantlee_skgfilters)
########### install files ###############
INSTALL(TARGETS grantlee_skgfilters LIBRARY DESTINATION ${KDE_INSTALL_QTPLUGINDIR}/grantlee/${Grantlee5_VERSION_MAJOR}.${Grantlee5_VERSION_MINOR} )
diff --git a/plugins/generic/skg_monthly/grantlee_filters/skgdocumentfilter.cpp b/plugins/generic/skg_monthly/grantlee_filters/skgdocumentfilter.cpp
index 8d68d54b0..dacc8b1cf 100644
--- a/plugins/generic/skg_monthly/grantlee_filters/skgdocumentfilter.cpp
+++ b/plugins/generic/skg_monthly/grantlee_filters/skgdocumentfilter.cpp
@@ -1,264 +1,264 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* The grantlee's filter to get items of a document table.
*
* @author Stephane MANKOWSKI
*/
#include "skgdocumentfilter.h"
#include <grantlee/util.h>
#include "skgdocument.h"
#include "skgmainpanel.h"
#include "skgtraces.h"
#include <QMetaProperty>
#include <KFormat>
QVariant SKGDocumentTableFilter::doFilter(const QVariant& input, const QVariant& argument, bool autoescape) const
{
Q_UNUSED(autoescape)
auto* doc = qobject_cast< SKGDocument* >(input.value<QObject*>());
if ((doc != nullptr) && argument.isValid()) {
SKGObjectBase::SKGListSKGObjectBase objects;
QString table = Grantlee::getSafeString(argument);
QString wc;
int pos = table.indexOf(QStringLiteral(","));
if (pos != -1) {
wc = table.right(table.count() - pos - 1);
table = table.left(pos);
}
doc->getObjects(table, wc, objects);
return QVariant::fromValue(objects);
}
return QVariant();
}
bool SKGDocumentTableFilter::isSafe() const
{
return true;
}
QVariant SKGDocumentQueryFilter::doFilter(const QVariant& input, const QVariant& argument, bool autoescape) const
{
Q_UNUSED(autoescape)
auto* doc = qobject_cast< SKGDocument* >(input.value<QObject*>());
if ((doc != nullptr) && argument.isValid()) {
QString sql = Grantlee::getSafeString(argument);
SKGStringListList result;
doc->executeSelectSqliteOrder(sql, result);
return QVariant::fromValue(result);
}
return QVariant();
}
bool SKGDocumentQueryFilter::isSafe() const
{
return true;
}
QVariant SKGDocumentDisplayFilter::doFilter(const QVariant& input, const QVariant& argument, bool autoescape) const
{
Q_UNUSED(autoescape)
auto* doc = qobject_cast< SKGDocument* >(input.value<QObject*>());
if (doc != nullptr) {
return doc->getDisplay(Grantlee::getSafeString(argument));
}
return QVariant();
}
bool SKGDocumentDisplayFilter::isSafe() const
{
return true;
}
QVariant SKGPercentFilter::doFilter(const QVariant& input, const QVariant& argument, bool autoescape) const
{
Q_UNUSED(autoescape)
Q_UNUSED(argument)
SKGMainPanel* mainPanel = SKGMainPanel::getMainPanel();
SKGDocument* doc = nullptr;
if (mainPanel != nullptr) {
doc = mainPanel->getDocument();
}
if (doc != nullptr) {
QString s = Grantlee::getSafeString(input);
return QVariant(doc->formatPercentage(SKGServices::stringToDouble(s)));
}
return QVariant();
}
bool SKGPercentFilter::isSafe() const
{
return true;
}
QVariant SKGFileSizeFilter::doFilter(const QVariant& input, const QVariant& argument, bool autoescape) const
{
Q_UNUSED(autoescape)
Q_UNUSED(argument)
auto size = SKGServices::stringToInt(Grantlee::getSafeString(input));
return QVariant(KFormat().formatByteSize(size));
}
bool SKGFileSizeFilter::isSafe() const
{
return true;
}
QVariant SKGDumpFilter::doFilter(const QVariant& input, const QVariant& argument, bool autoescape) const
{
Q_UNUSED(autoescape)
Q_UNUSED(argument)
if (input.isValid()) {
auto* obj = input.value<QObject*>();
if (obj != nullptr) {
const QMetaObject* metaObject = obj->metaObject();
QString table = QStringLiteral("<table class=\"table table-striped table-condensed \">");
int nb = metaObject->propertyCount();
for (int i = 0; i < nb; ++i) {
QVariant val = SKGDumpFilter::doFilter(obj->property(metaObject->property(i).name()), QVariant(), autoescape);
table += QStringLiteral("<tr><td>") % metaObject->property(i).name() % "</td><td>" % val.toString() % "</td></tr>";
}
table += QStringLiteral("</table>");
return QVariant(table);
}
if (input.canConvert<SKGObjectBase>()) {
SKGObjectBase objectBase = input.value<SKGObjectBase>();
SKGQStringQStringMap att = objectBase.getAttributes();
QStringList keys = att.keys();
QString table = QStringLiteral("<table class=\"table table-striped table-condensed \">");
int nb = keys.count();
for (int i = 0; i < nb; ++i) {
table += QStringLiteral("<tr><td>") % keys.at(i) % "</td><td>" % att[keys.at(i)] % "</td></tr>";
}
table += QStringLiteral("</table>");
return QVariant(table);
}
if (input.canConvert(QVariant::List)) {
QVariantList l = input.toList();
int nb = l.count();
QString table = QStringLiteral("<table class=\"table table-striped table-condensed \">");
for (int i = 0; i < nb; ++i) {
QVariant val = SKGDumpFilter::doFilter(l.at(i), QVariant(), autoescape);
table += QStringLiteral("<tr><td>") % SKGServices::intToString(i) % "</td><td>" % val.toString() % "</td></tr>";
}
table += QStringLiteral("</table>");
return QVariant(table);
}
if (input.canConvert<SKGObjectBase::SKGListSKGObjectBase>()) {
SKGObjectBase::SKGListSKGObjectBase l = input.value<SKGObjectBase::SKGListSKGObjectBase>();
int nb = l.count();
QString table;
if (nb != 0) {
table = QStringLiteral("<table class=\"table table-striped table-condensed \"><tr><th>#</th>");
for (int i = 0; i < nb; ++i) {
const SKGObjectBase& objectBase = l.at(i);
SKGQStringQStringMap att = objectBase.getAttributes();
QStringList keys = att.keys();
QString line = QStringLiteral("<tr><td>") % SKGServices::intToString(i) % "</td>";
int nbc = keys.count();
for (int j = 0; j < nbc; ++j) {
if (i == 0) {
table += QStringLiteral("<th>") % keys.at(j) % "</th>";
}
line += QStringLiteral("<td>") % att[keys.at(j)] % "</td>";
}
if (i == 0) {
table += QStringLiteral("</tr>");
}
line += QStringLiteral("</tr>");
table += line;
}
table += QStringLiteral("</table>");
}
return QVariant(table);
}
return QVariant(input.toString());
}
return QVariant();
}
bool SKGDumpFilter::isSafe() const
{
return true;
}
QVariant SKGMoneyFilter::doFilter(const QVariant& input, const QVariant& argument, bool autoescape) const
{
Q_UNUSED(autoescape)
QString arg = Grantlee::getSafeString(argument);
SKGMainPanel* mainPanel = SKGMainPanel::getMainPanel();
SKGDocument* doc = nullptr;
if (mainPanel != nullptr) {
doc = mainPanel->getDocument();
}
if (doc != nullptr) {
QStringList args = SKGServices::splitCSVLine(arg);
SKGServices::SKGUnitInfo unit = doc->getUnit(args.contains(QStringLiteral("2")) ? QStringLiteral("secondary") : QStringLiteral("primary"));
if (args.contains(QStringLiteral("nodecimal"))) {
unit.NbDecimal = 0;
}
return QVariant(doc->formatMoney(SKGServices::stringToDouble(Grantlee::getSafeString(input)), unit, !args.contains(QStringLiteral("nocolor"))));
}
return QVariant();
}
bool SKGMoneyFilter::isSafe() const
{
return true;
}
QVariant SKGUrlEncodeFilter::doFilter(const QVariant& input, const QVariant& argument, bool autoescape) const
{
Q_UNUSED(autoescape)
Q_UNUSED(argument)
return QVariant(SKGServices::encodeForUrl(Grantlee::getSafeString(input)));
}
bool SKGUrlEncodeFilter::isSafe() const
{
return true;
}
QVariant SKGReplaceFilter::doFilter(const QVariant& input, const QVariant& argument, bool autoescape) const
{
Q_UNUSED(autoescape)
QString arg = Grantlee::getSafeString(argument);
QStringList args = SKGServices::splitCSVLine(arg, QLatin1Char(';'), false);
QString output = Grantlee::getSafeString(input);
if (args.count() == 2) {
output = output.replace(args.at(0), args.at(1));
}
return QVariant(output);
}
bool SKGReplaceFilter::isSafe() const
{
return true;
}
diff --git a/plugins/generic/skg_monthly/grantlee_filters/skgdocumentfilter.h b/plugins/generic/skg_monthly/grantlee_filters/skgdocumentfilter.h
index dd0a45071..edd77e496 100644
--- a/plugins/generic/skg_monthly/grantlee_filters/skgdocumentfilter.h
+++ b/plugins/generic/skg_monthly/grantlee_filters/skgdocumentfilter.h
@@ -1,287 +1,287 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGDOCUMENTFILTER_H
#define SKGDOCUMENTFILTER_H
/** @file
* The grantlee's filter to get information from document.
*
* @author Stephane MANKOWSKI
*/
#include <grantlee/filter.h>
#include <qobject.h>
/**
* The grantlee's filter to get items of a document table
*/
class SKGDocumentTableFilter final : public Grantlee::Filter
{
public:
Q_DISABLE_COPY(SKGDocumentTableFilter)
/**
* Default constructor
*/
SKGDocumentTableFilter() = default;
/**
* Do the filtering
* @param input the input
* @param argument the argument
* @param autoescape the autoescape mode
* @return the filtered value
*/
QVariant doFilter(const QVariant& input, const QVariant& argument = QVariant(), bool autoescape = false) const override;
/**
* To know if the filter is safe
* @return true or false
*/
bool isSafe() const override;
};
/**
* The grantlee's filter to execute a sql query on the document
*/
class SKGDocumentQueryFilter final : public Grantlee::Filter
{
public:
Q_DISABLE_COPY(SKGDocumentQueryFilter)
/**
* Default constructor
*/
SKGDocumentQueryFilter() = default;
/**
* Do the filtering
* @param input the input
* @param argument the argument
* @param autoescape the autoescape mode
* @return the filtered value
*/
QVariant doFilter(const QVariant& input, const QVariant& argument = QVariant(), bool autoescape = false) const override;
/**
* To know if the filter is safe
* @return true or false
*/
bool isSafe() const override;
};
/**
* The grantlee's filter to get display of an attribute
*/
class SKGDocumentDisplayFilter final : public Grantlee::Filter
{
public:
Q_DISABLE_COPY(SKGDocumentDisplayFilter)
/**
* Default constructor
*/
SKGDocumentDisplayFilter() = default;
/**
* Do the filtering
* @param input the input
* @param argument the argument
* @param autoescape the autoescape mode
* @return the filtered value
*/
QVariant doFilter(const QVariant& input, const QVariant& argument = QVariant(), bool autoescape = false) const override;
/**
* To know if the filter is safe
* @return true or false
*/
bool isSafe() const override;
};
/**
* The grantlee's filter to format percent
*/
class SKGPercentFilter final : public Grantlee::Filter
{
public:
Q_DISABLE_COPY(SKGPercentFilter)
/**
* Default constructor
*/
SKGPercentFilter() = default;
/**
* Do the filtering
* @param input the input
* @param argument the argument
* @param autoescape the autoescape mode
* @return the filtered value
*/
QVariant doFilter(const QVariant& input, const QVariant& argument = QVariant(), bool autoescape = false) const override;
/**
* To know if the filter is safe
* @return true or false
*/
bool isSafe() const override;
};
/**
* The grantlee's filter to format file size
*/
class SKGFileSizeFilter final : public Grantlee::Filter
{
public:
Q_DISABLE_COPY(SKGFileSizeFilter)
/**
* Default constructor
*/
SKGFileSizeFilter() = default;
/**
* Do the filtering
* @param input the input
* @param argument the argument
* @param autoescape the autoescape mode
* @return the filtered value
*/
QVariant doFilter(const QVariant& input, const QVariant& argument = QVariant(), bool autoescape = false) const override;
/**
* To know if the filter is safe
* @return true or false
*/
bool isSafe() const override;
};
/**
* The grantlee's filter to dump objects
*/
class SKGDumpFilter final : public Grantlee::Filter
{
public:
Q_DISABLE_COPY(SKGDumpFilter)
/**
* Default constructor
*/
SKGDumpFilter() = default;
/**
* Do the filtering
* @param input the input
* @param argument the argument
* @param autoescape the autoescape mode
* @return the filtered value
*/
QVariant doFilter(const QVariant& input, const QVariant& argument = QVariant(), bool autoescape = false) const override;
/**
* To know if the filter is safe
* @return true or false
*/
bool isSafe() const override;
};
/**
* The grantlee's filter to format money
*/
class SKGMoneyFilter final : public Grantlee::Filter
{
public:
Q_DISABLE_COPY(SKGMoneyFilter)
/**
* Default constructor
*/
SKGMoneyFilter() = default;
/**
* Do the filtering
* @param input the input
* @param argument the argument
* @param autoescape the autoescape mode
* @return the filtered value
*/
QVariant doFilter(const QVariant& input, const QVariant& argument = QVariant(), bool autoescape = false) const override;
/**
* To know if the filter is safe
* @return true or false
*/
bool isSafe() const override;
};
/**
* The grantlee's filter to encode url
*/
class SKGUrlEncodeFilter final : public Grantlee::Filter
{
public:
Q_DISABLE_COPY(SKGUrlEncodeFilter)
/**
* Default constructor
*/
SKGUrlEncodeFilter() = default;
/**
* Do the filtering
* @param input the input
* @param argument the argument
* @param autoescape the autoescape mode
* @return the filtered value
*/
QVariant doFilter(const QVariant& input, const QVariant& argument = QVariant(), bool autoescape = false) const override;
/**
* To know if the filter is safe
* @return true or false
*/
bool isSafe() const override;
};
/**
* The grantlee's filter to replace in strings
*/
class SKGReplaceFilter final : public Grantlee::Filter
{
public:
Q_DISABLE_COPY(SKGReplaceFilter)
/**
* Default constructor
*/
SKGReplaceFilter() = default;
/**
* Do the filtering
* @param input the input
* @param argument the argument
* @param autoescape the autoescape mode
* @return the filtered value
*/
QVariant doFilter(const QVariant& input, const QVariant& argument = QVariant(), bool autoescape = false) const override;
/**
* To know if the filter is safe
* @return true or false
*/
bool isSafe() const override;
};
#endif // SKGDOCUMENTFILTER_H
diff --git a/plugins/generic/skg_monthly/grantlee_filters/skggrantleefilters.cpp b/plugins/generic/skg_monthly/grantlee_filters/skggrantleefilters.cpp
index b480f304d..a8e47bcf3 100644
--- a/plugins/generic/skg_monthly/grantlee_filters/skggrantleefilters.cpp
+++ b/plugins/generic/skg_monthly/grantlee_filters/skggrantleefilters.cpp
@@ -1,51 +1,51 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* The grantlee's plugin to define filters.
*
* @author Stephane MANKOWSKI
*/
#include "skggrantleefilters.h"
#include "skgdocumentfilter.h"
#include "skgobjectfilter.h"
SKGGrantleeFilters::SKGGrantleeFilters(QObject* iParent): QObject(iParent)
{}
SKGGrantleeFilters::~SKGGrantleeFilters()
= default;
QHash< QString, Grantlee::Filter* > SKGGrantleeFilters::filters(const QString& iName)
{
Q_UNUSED(iName)
QHash<QString, Grantlee::Filter*> filtersList;
filtersList.insert(QStringLiteral("query"), new SKGDocumentQueryFilter());
filtersList.insert(QStringLiteral("table"), new SKGDocumentTableFilter());
filtersList.insert(QStringLiteral("display"), new SKGDocumentDisplayFilter());
filtersList.insert(QStringLiteral("att"), new SKGObjectFilter());
filtersList.insert(QStringLiteral("money"), new SKGMoneyFilter());
filtersList.insert(QStringLiteral("percent"), new SKGPercentFilter());
filtersList.insert(QStringLiteral("filesizeformat"), new SKGFileSizeFilter());
filtersList.insert(QStringLiteral("dump"), new SKGDumpFilter());
filtersList.insert(QStringLiteral("encode"), new SKGUrlEncodeFilter());
filtersList.insert(QStringLiteral("replace"), new SKGReplaceFilter());
return filtersList;
}
diff --git a/plugins/generic/skg_monthly/grantlee_filters/skggrantleefilters.h b/plugins/generic/skg_monthly/grantlee_filters/skggrantleefilters.h
index 3351eb7bb..bafb4e22c 100644
--- a/plugins/generic/skg_monthly/grantlee_filters/skggrantleefilters.h
+++ b/plugins/generic/skg_monthly/grantlee_filters/skggrantleefilters.h
@@ -1,55 +1,55 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGGRANTLEEFILTERS_H
#define SKGGRANTLEEFILTERS_H
/** @file
* The grantlee's plugin to define filters.
*
* @author Stephane MANKOWSKI
*/
#include <grantlee/taglibraryinterface.h>
#include <qobject.h>
/**
* The grantlee's plugin to define filters
*/
class SKGGrantleeFilters : public QObject, public Grantlee::TagLibraryInterface
{
Q_OBJECT
Q_INTERFACES(Grantlee::TagLibraryInterface)
Q_PLUGIN_METADATA(IID "org.grantlee.TagLibraryInterface")
public:
/**
* Default Constructor
*/
explicit SKGGrantleeFilters(QObject* iParent = nullptr);
/**
* Default Destructor
*/
~SKGGrantleeFilters() override;
/**
* Returns the Filter implementations available in this library
* @param iName the name
* @return the implementations
*/
QHash<QString, Grantlee::Filter*> filters(const QString& iName = QString()) override;
};
#endif // SKGGRANTLEEFILTERS_H
diff --git a/plugins/generic/skg_monthly/grantlee_filters/skgobjectfilter.cpp b/plugins/generic/skg_monthly/grantlee_filters/skgobjectfilter.cpp
index ebd04278c..33edbb793 100644
--- a/plugins/generic/skg_monthly/grantlee_filters/skgobjectfilter.cpp
+++ b/plugins/generic/skg_monthly/grantlee_filters/skgobjectfilter.cpp
@@ -1,38 +1,38 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* The grantlee's filter to get attribute of an object.
*
* @author Stephane MANKOWSKI
*/
#include "skgobjectfilter.h"
#include "skgobjectbase.h"
#include "skgtraces.h"
#include "grantlee/util.h"
QVariant SKGObjectFilter::doFilter(const QVariant& input, const QVariant& argument, bool autoescape) const
{
Q_UNUSED(autoescape)
SKGObjectBase obj = input.value<SKGObjectBase>();
return obj.getAttribute(Grantlee::getSafeString(argument));
}
bool SKGObjectFilter::isSafe() const
{
return true;
}
diff --git a/plugins/generic/skg_monthly/grantlee_filters/skgobjectfilter.h b/plugins/generic/skg_monthly/grantlee_filters/skgobjectfilter.h
index 310f43153..bc274a653 100644
--- a/plugins/generic/skg_monthly/grantlee_filters/skgobjectfilter.h
+++ b/plugins/generic/skg_monthly/grantlee_filters/skgobjectfilter.h
@@ -1,49 +1,49 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGOBJECTFILTER_H
#define SKGOBJECTFILTER_H
/** @file
* The grantlee's filter to get attribute of an object.
*
* @author Stephane MANKOWSKI
*/
#include <grantlee/filter.h>
#include <qobject.h>
/**
* The grantlee's filter to get attribute of an object
*/
class SKGObjectFilter : public Grantlee::Filter
{
public:
/**
* Do the filtering
* @param input the input
* @param argument the argument
* @param autoescape the autoescape mode
* @return the filtered value
*/
QVariant doFilter(const QVariant& input, const QVariant& argument = QVariant(), bool autoescape = false) const override;
/**
* To know if the filter is safe
* @return true or false
*/
bool isSafe() const override;
};
#endif // SKGOBJECTFILTER_H
diff --git a/plugins/generic/skg_monthly/org.kde.skg-plugin-monthly.desktop b/plugins/generic/skg_monthly/org.kde.skg-plugin-monthly.desktop
index 003917569..0d4ea9520 100644
--- a/plugins/generic/skg_monthly/org.kde.skg-plugin-monthly.desktop
+++ b/plugins/generic/skg_monthly/org.kde.skg-plugin-monthly.desktop
@@ -1,72 +1,72 @@
[Desktop Entry]
Name=Monthly plugin
Name[bs]=Mjesečni dodatak
Name[ca]=Connector mensual
Name[ca@valencia]=Connector mensual
Name[cs]=Modul hlášení
Name[da]=Månedligt-plugin
Name[de]=Monatsberichtmodul
Name[el]=Monthly plugin
Name[en_GB]=Monthly plugin
Name[es]=Complemento mensual
Name[et]=Kuuaruande plugin
Name[fi]=Kuukausiliitännäinen
Name[fr]=Module externe de rapport mensuel
Name[gl]=Complemento mensual
Name[hu]=Havi bővítmény
Name[it]=Estensione mensile
Name[lt]=Mėnesio papildinys
Name[nl]=Plug-in voor maandelijks
Name[pl]=Wtyczka miesięczna
Name[pt]='Plugin' mensal
Name[pt_BR]=Plugin de mês
Name[ru]=Модуль месячных отчётов
Name[sk]=Mesačný plugin
Name[sv]=Månatligt insticksprogram
Name[tr]=Aylık eklenti
Name[uk]=Додаток місячних звітів
Name[x-test]=xxMonthly pluginxx
Name[zh_TW]=月報表外掛程式
Comment=A monthly report plugin.
Comment[bs]=Dodatak za mjesečne izvještaje.
Comment[ca]=Un connector d'informe mensual.
Comment[ca@valencia]=Un connector d'informe mensual.
Comment[cs]=Modul pro měsíční hlášení
Comment[da]=Et plugin til månedlig rapport.
Comment[de]=Ein Modul für Monatsberichte.
Comment[el]=Ένα πρόσθετο για μηνιαίες αναφορές.
Comment[en_GB]=A monthly report plugin.
Comment[es]=Un complemento para informes mensuales.
Comment[et]=Kuuaruande plugin.
Comment[fi]=Kuukausittainen raportti -liitännäinen
Comment[fr]=Un module externe de rapport mensuel.
Comment[gl]=Un complemento de informes mensuais.
Comment[hu]=Egy havi jelentés bővítmény.
Comment[it]=Un'estensione per i rapporti mensili.
Comment[lt]=Mėnesio ataskaitos papildinys.
Comment[nl]=Een plug-in voor maandelijks rapporteren.
Comment[pl]=Wtyczka sprawozdania miesięcznego.
Comment[pt]=Um 'plugin' de relatórios mensais.
Comment[pt_BR]=Um plugin para relatório mensal.
Comment[ru]=Модуль месячных отчётов
Comment[sk]=Plugin na mesačné správy.
Comment[sv]=Ett insticksprogram för månatliga rapporter.
Comment[tr]=Aylık rapor eklentisi.
Comment[uk]=Додаток місячних звітів.
Comment[x-test]=xxA monthly report plugin.xx
Comment[zh_TW]=月報表外掛程式。
Encoding=UTF-8
Icon=quickopen
Type=Service
X-KDE-ServiceTypes=SKG GUI/Plugin
X-KDE-Library=skg_monthly
X-Krunner-ID=Monthly plugin
X-KDE-PluginInfo-Author=Stephane MANKOWSKI,miraks
X-KDE-PluginInfo-Email=stephane@mankowski.fr
X-KDE-PluginInfo-Name=skg_monthly
X-KDE-PluginInfo-Version=1.0
-X-KDE-PluginInfo-Website=http://skrooge.org/
+X-KDE-PluginInfo-Website=https://skrooge.org/
X-KDE-PluginInfo-Category=Plugins
X-KDE-PluginInfo-Depends=
X-KDE-PluginInfo-License=GPL
X-KDE-PluginInfo-EnabledByDefault=true
diff --git a/plugins/generic/skg_monthly/skgmonthlyplugin.cpp b/plugins/generic/skg_monthly/skgmonthlyplugin.cpp
index d7495314c..bd15a7513 100644
--- a/plugins/generic/skg_monthly/skgmonthlyplugin.cpp
+++ b/plugins/generic/skg_monthly/skgmonthlyplugin.cpp
@@ -1,188 +1,188 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* A plugin for monthly report
*
* @author Stephane MANKOWSKI
*/
#include "skgmonthlyplugin.h"
#include <kaboutdata.h>
#include <kactioncollection.h>
#include <klocalizedstring.h>
#include <kpluginfactory.h>
#include <kstandardaction.h>
#include <qdesktopservices.h>
#include <qdir.h>
#include <qdiriterator.h>
#include <qfile.h>
#include <qfileinfo.h>
#include <qstandardpaths.h>
#include "skgmainpanel.h"
#include "skgmonthlypluginwidget.h"
#include "skgreport.h"
#include "skgtraces.h"
/**
* This plugin factory.
*/
K_PLUGIN_FACTORY(SKGMonthlyPluginFactory, registerPlugin<SKGMonthlyPlugin>();)
SKGMonthlyPlugin::SKGMonthlyPlugin(QWidget* iWidget, QObject* iParent, const QVariantList& /*iArg*/) :
SKGInterfacePlugin(iParent),
m_currentBankDocument(nullptr), m_mainPage(nullptr)
{
Q_UNUSED(iWidget)
SKGTRACEINFUNC(10)
}
SKGMonthlyPlugin::~SKGMonthlyPlugin()
{
SKGTRACEINFUNC(10)
m_currentBankDocument = nullptr;
}
bool SKGMonthlyPlugin::setupActions(SKGDocument* iDocument)
{
SKGTRACEINFUNC(10)
m_currentBankDocument = iDocument;
setComponentName(QStringLiteral("skg_monthly"), title());
setXMLFile(QStringLiteral("skg_monthly.rc"));
// Make needed paths
QString writablePath = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation);
QString path = writablePath % QLatin1Char('/') + KAboutData::applicationData().componentName() % QStringLiteral("/html/default");
if (!QDir(writablePath).mkpath(KAboutData::applicationData().componentName() % QStringLiteral("/html/default"))) {
SKGTRACE << "WARNING: Impossible to create html/default in " << writablePath << endl;
}
// Copy "default" directory in locale
const auto dirs = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, KAboutData::applicationData().componentName() % "/html/default", QStandardPaths::LocateDirectory);
for (const auto& dir : dirs) {
QDirIterator it(dir, QStringList() << QStringLiteral("*.html"));
while (it.hasNext()) {
QString file = it.next();
QString target = path % QLatin1Char('/') % QFileInfo(file).fileName();
QFile(target).remove();
if (file != target && !QFile(file).copy(target)) {
SKGTRACE << "WARNING: Impossible to copie " << file << " in " << target << endl;
}
}
}
// Create yours actions here
return true;
}
QStringList SKGMonthlyPlugin::processArguments(const QStringList& iArgument)
{
// Initialise the main page
if (m_mainPage == nullptr) {
#ifdef SKG_WEBENGINE
{
SKGTRACEIN(10, "SKGMonthlyPlugin::setupActions-Init SKGWebView")
m_mainPage = new SKGWebView(SKGMainPanel::getMainPanel(), 0, false);
SKGMainPanel::getMainPanel()->setMainWidget(m_mainPage);
refreshMainPage();
connect(m_currentBankDocument, &SKGDocument::transactionSuccessfullyEnded, this, &SKGMonthlyPlugin::refreshMainPage);
qApp->processEvents(QEventLoop::AllEvents, 500);
}
#else
m_mainPage = new QWebView();
m_mainPage->page()->setLinkDelegationPolicy(QWebPage::DelegateAllLinks);
connect(m_mainPage, &QWebView::linkClicked, this, [ = ](const QUrl & val) {
SKGMainPanel::getMainPanel()->openPage(val);
});
SKGMainPanel::getMainPanel()->setMainWidget(m_mainPage);
refreshMainPage();
connect(m_currentBankDocument, &SKGDocument::transactionSuccessfullyEnded, this, &SKGMonthlyPlugin::refreshMainPage);
#endif
}
return iArgument;
}
void SKGMonthlyPlugin::refreshMainPage()
{
QString html;
QString templateFile = QStandardPaths::locate(QStandardPaths::GenericDataLocation, KAboutData::applicationData().componentName() % "/html/main.txt");
if (templateFile.isEmpty()) {
html = i18nc("Error message", "File %1/html/main.txt not found", KAboutData::applicationData().componentName());
} else {
if ((m_currentBankDocument != nullptr) && (SKGMainPanel::getMainPanel() != nullptr)) {
SKGReport* rep = m_currentBankDocument->getReport();
// Enrich with tips of the day
rep->setTipsOfDay(SKGMainPanel::getMainPanel()->getTipsOfDay());
SKGError err = SKGReport::getReportFromTemplate(rep, templateFile, html);
IFKO(err) html += err.getFullMessageWithHistorical();
delete rep;
}
}
#ifdef SKG_WEBENGINE
m_mainPage->setHtml(html, QUrl("file://"));
#else
m_mainPage->setHtml(html);
#endif
}
SKGTabPage* SKGMonthlyPlugin::getWidget()
{
SKGTRACEINFUNC(10)
return new SKGMonthlyPluginWidget(SKGMainPanel::getMainPanel(), m_currentBankDocument);
}
QString SKGMonthlyPlugin::title() const
{
return toolTip();
}
QString SKGMonthlyPlugin::icon() const
{
return QStringLiteral("view-calendar-journal");
}
QString SKGMonthlyPlugin::toolTip() const
{
return i18nc("A tool tip", "Monthly report");
}
int SKGMonthlyPlugin::getOrder() const
{
return 50;
}
QStringList SKGMonthlyPlugin::tips() const
{
QStringList output;
output.push_back(i18nc("Description of a tips", "<p>... you can generate a <a href=\"skg://monthly_plugin\">monthly report</a>.</p>"));
output.push_back(i18nc("Description of a tips", "<p>... you can download more monthly report <a href=\"skg://monthly_plugin\">templates</a>.</p>"));
output.push_back(i18nc("Description of a tips", "<p>... you can create and share your own <a href=\"skg://monthly_plugin\">monthly report</a> template.</p>"));
return output;
}
bool SKGMonthlyPlugin::isInPagesChooser() const
{
return true;
}
#include <skgmonthlyplugin.moc>
diff --git a/plugins/generic/skg_monthly/skgmonthlyplugin.h b/plugins/generic/skg_monthly/skgmonthlyplugin.h
index 930fc28ad..b2d0bc88a 100644
--- a/plugins/generic/skg_monthly/skgmonthlyplugin.h
+++ b/plugins/generic/skg_monthly/skgmonthlyplugin.h
@@ -1,122 +1,122 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGMONTHLYPLUGIN_H
#define SKGMONTHLYPLUGIN_H
/** @file
* A plugin for monthly report.
*
* @author Stephane MANKOWSKI
*/
#include "skginterfaceplugin.h"
#ifdef SKG_WEBENGINE
class QWebEngineView;
#else
class QWebView;
#endif
/**
* A plugin for monthly report
*/
class SKGMonthlyPlugin : public SKGInterfacePlugin
{
Q_OBJECT
Q_INTERFACES(SKGInterfacePlugin)
public:
/**
* Default Constructor
*/
explicit SKGMonthlyPlugin(QWidget* iWidget, QObject* iParent, const QVariantList& iArg);
/**
* Default Destructor
*/
~SKGMonthlyPlugin() override;
/**
* Called to initialise the plugin
* @param iDocument the main document
* @return true if the plugin is compatible with the document
*/
bool setupActions(SKGDocument* iDocument) override;
/**
* This function is called when the application is launched again with new arguments
* @param iArgument the arguments
* @return the rest of arguments to treat
*/
QStringList processArguments(const QStringList& iArgument) override;
/**
* The page widget of the plugin.
* @return The page widget of the plugin
*/
SKGTabPage* getWidget() override;
/**
* The title of the plugin.
* @return The title of the plugin
*/
QString title() const override;
/**
* The icon of the plugin.
* @return The icon of the plugin
*/
QString icon() const override;
/**
* The toolTip of the plugin.
* @return The toolTip of the plugin
*/
QString toolTip() const override;
/**
* The tips list of the plugin.
* @return The tips list of the plugin
*/
QStringList tips() const override;
/**
* Must be implemented to set the position of the plugin.
* @return integer value between 0 and 999 (default = 999)
*/
int getOrder() const override;
/**
* Must be implemented to know if a plugin must be display in pages chooser.
* @return true of false (default = false)
*/
bool isInPagesChooser() const override;
private Q_SLOTS:
void refreshMainPage();
private:
Q_DISABLE_COPY(SKGMonthlyPlugin)
SKGDocument* m_currentBankDocument;
#ifdef SKG_WEBENGINE
QWebEngineView* m_mainPage;
#else
QWebView* m_mainPage;
#endif
};
#endif // SKGMonthlyPLUGIN_H
diff --git a/plugins/generic/skg_monthly/skgmonthlypluginwidget.cpp b/plugins/generic/skg_monthly/skgmonthlypluginwidget.cpp
index 6f95d238c..6844218de 100644
--- a/plugins/generic/skg_monthly/skgmonthlypluginwidget.cpp
+++ b/plugins/generic/skg_monthly/skgmonthlypluginwidget.cpp
@@ -1,393 +1,393 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* A plugin for monthly report.
*
* @author Stephane MANKOWSKI
*/
#include "skgmonthlypluginwidget.h"
#include <kaboutdata.h>
#include <kns3/downloaddialog.h>
#include <kns3/uploaddialog.h>
#include <kzip.h>
#include <qdesktopservices.h>
#include <qdir.h>
#include <qdom.h>
#include <qfile.h>
#include <qmenu.h>
#include <qtextstream.h>
#ifdef SKG_WEBENGINE
#include <qwebenginepage.h>
#else
#include <qwebframe.h>
#endif
#include <qdiriterator.h>
#include <qstandardpaths.h>
#include <qvalidator.h>
#include "skgmainpanel.h"
#include "skgreport.h"
#include "skgtraces.h"
#include "skgtransactionmng.h"
SKGMonthlyPluginWidget::SKGMonthlyPluginWidget(QWidget* iParent, SKGDocument* iDocument)
: SKGTabPage(iParent, iDocument), m_upload(nullptr)
{
SKGTRACEINFUNC(1)
if (iDocument == nullptr) {
return;
}
ui.setupUi(this);
ui.kMonth->setMode(SKGSimplePeriodEdit::PREVIOUS_PERIODS | SKGSimplePeriodEdit::PREVIOUS_MONTHS);
ui.kDeleteTemplate->hide();
ui.kRefresh->setIcon(SKGServices::fromTheme(QStringLiteral("view-refresh")));
ui.kGetNewHotStuff->setIcon(SKGServices::fromTheme(QStringLiteral("get-hot-new-stuff")));
ui.kDeleteTemplate->setIcon(SKGServices::fromTheme(QStringLiteral("edit-delete")));
auto newValidator = new QRegExpValidator(QRegExp(QStringLiteral("^[\\w\\s]+$")), this);
ui.kTemplate->setValidator(newValidator);
connect(getDocument(), &SKGDocument::tableModified, this, &SKGMonthlyPluginWidget::dataModified, Qt::QueuedConnection);
connect(ui.kMonth, static_cast<void (SKGComboBox::*)(const QString&)>(&SKGComboBox::currentTextChanged), this, &SKGMonthlyPluginWidget::onPeriodChanged, Qt::QueuedConnection);
QStringList overlays;
overlays.push_back(QStringLiteral("list-add"));
m_upload = new QAction(SKGServices::fromTheme(QStringLiteral("get-hot-new-stuff"), overlays), i18n("Upload"), this);
connect(m_upload, &QAction::triggered, this, &SKGMonthlyPluginWidget::onPutNewHotStuff);
auto menu = new QMenu(this);
menu->addAction(m_upload);
ui.kGetNewHotStuff->setMenu(menu);
connect(ui.kDeleteTemplate, &QToolButton::clicked, this, &SKGMonthlyPluginWidget::onDeleteTemplate);
connect(ui.kTemplate, static_cast<void (SKGComboBox::*)(const QString&)>(&SKGComboBox::returnPressed), this, &SKGMonthlyPluginWidget::onAddTemplate);
connect(ui.kTemplate, &SKGComboBox::editTextChanged, this, &SKGMonthlyPluginWidget::onTemplateChanged);
connect(ui.kGetNewHotStuff, &QToolButton::clicked, this, &SKGMonthlyPluginWidget::onGetNewHotStuff);
connect(ui.kRefresh, &QToolButton::clicked, this, &SKGMonthlyPluginWidget::onPeriodChanged);
// Refresh
fillTemplateList();
dataModified(QLatin1String(""), 0);
}
SKGMonthlyPluginWidget::~SKGMonthlyPluginWidget()
{
SKGTRACEINFUNC(1)
}
QString SKGMonthlyPluginWidget::getState()
{
SKGTRACEINFUNC(10)
QDomDocument doc(QStringLiteral("SKGML"));
QDomElement root = doc.createElement(QStringLiteral("parameters"));
doc.appendChild(root);
// Get state
root.setAttribute(QStringLiteral("month"), ui.kMonth->text());
root.setAttribute(QStringLiteral("template"), ui.kTemplate->text());
root.setAttribute(QStringLiteral("web"), ui.kWebView->getState());
return doc.toString();
}
void SKGMonthlyPluginWidget::setState(const QString& iState)
{
SKGTRACEINFUNC(10)
QDomDocument doc(QStringLiteral("SKGML"));
doc.setContent(iState);
QDomElement root = doc.documentElement();
// Set state
QString webS = root.attribute(QStringLiteral("web"));
if (!webS.isEmpty()) {
ui.kWebView->setState(webS);
}
QString templat = root.attribute(QStringLiteral("template"));
if (!templat.isEmpty()) {
bool p = ui.kTemplate->blockSignals(true);
ui.kTemplate->setText(templat);
ui.kTemplate->blockSignals(p);
onTemplateChanged();
}
QString month = root.attribute(QStringLiteral("month"));
if (!month.isEmpty()) {
ui.kMonth->setText(month);
}
onPeriodChanged();
}
QString SKGMonthlyPluginWidget::getDefaultStateAttribute()
{
return QStringLiteral("SKGMONTHLY_DEFAULT_PARAMETERS");
}
QWidget* SKGMonthlyPluginWidget::mainWidget()
{
return ui.kWebView;
}
void SKGMonthlyPluginWidget::fillTemplateList()
{
disconnect(ui.kTemplate, static_cast<void (SKGComboBox::*)(const QString&)>(&SKGComboBox::currentTextChanged), this, &SKGMonthlyPluginWidget::onPeriodChanged);
// Get previous selected item
QString current = ui.kTemplate->text();
// Fill
ui.kTemplate->clear();
const auto dirs = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, KAboutData::applicationData().componentName() % "/html", QStandardPaths::LocateDirectory);
for (const auto& dir : dirs) {
QDirIterator it(dir, QStringList() << QStringLiteral("*.txt"));
while (it.hasNext()) {
QString file = it.next();
QFileInfo f(file);
QString file2 = f.completeBaseName();
if (!ui.kTemplate->contains(file2) && file2 != QStringLiteral("main")) {
ui.kTemplate->addItem(file2, file);
}
}
}
// Set previous selected itemData
if (!current.isEmpty() && ui.kTemplate->contains(current)) {
ui.kTemplate->setCurrentItem(current);
}
connect(ui.kTemplate, static_cast<void (SKGComboBox::*)(const QString&)>(&SKGComboBox::currentTextChanged), this, &SKGMonthlyPluginWidget::onPeriodChanged, Qt::QueuedConnection);
}
void SKGMonthlyPluginWidget::onAddTemplate()
{
QString templat = ui.kTemplate->text().trimmed();
QString templateDir = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QLatin1Char('/') + KAboutData::applicationData().componentName();
QString templatFileName = templateDir % "/html/" % templat % ".txt";
QStringList templates;
const auto dirs = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, KAboutData::applicationData().componentName() % "/html", QStandardPaths::LocateDirectory);
for (const auto& dir : dirs) {
QDirIterator it(dir, QStringList() << QStringLiteral("*.txt"));
while (it.hasNext()) {
templates.append(it.next());
}
}
if (!templat.isEmpty() && (!templates.contains(templatFileName) || QFileInfo(templatFileName).isWritable())) {
SKGError err;
if (!templates.contains(templatFileName)) {
// Create the new template
QString source = QStandardPaths::locate(QStandardPaths::GenericDataLocation, KAboutData::applicationData().componentName() % "/html/tutorial.txt");
QDir(templateDir).mkpath(QStringLiteral("html"));
if (SKGServices::upload(QUrl::fromLocalFile(source), QUrl::fromLocalFile(templatFileName))) {
err.setReturnCode(ERR_FAIL).setMessage(i18nc("An error message", "Impossible to copy file from '%1' to '%2'", source, templatFileName));
} else {
fillTemplateList();
}
}
// Open the created or already existing file
QDesktopServices::openUrl(QUrl::fromLocalFile(templatFileName));
onTemplateChanged();
// Display error
SKGMainPanel::displayErrorMessage(err);
}
}
void SKGMonthlyPluginWidget::onDeleteTemplate()
{
QString templat = ui.kTemplate->text().trimmed();
QString templatFileName = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QLatin1Char('/') + KAboutData::applicationData().componentName() % "/html/" % templat % ".txt";
if (!templat.isEmpty()) {
// This is a new source
SKGError err;
// Delete the file
QFile file(templatFileName);
if (!file.remove()) {
err.setReturnCode(ERR_INVALIDARG).setMessage(i18nc("Error message", "Deletion of '%1' failed", templatFileName));
}
IFOK(err) ui.kTemplate->removeItem(ui.kTemplate->findText(templat));
// Display error
SKGMainPanel::displayErrorMessage(err);
}
}
void SKGMonthlyPluginWidget::onTemplateChanged()
{
QString templat = ui.kTemplate->text().trimmed();
QString templatFileName = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QLatin1Char('/') + KAboutData::applicationData().componentName() % "/html/" % templat % ".txt";
bool local = !templat.isEmpty() && QFileInfo(templatFileName).isWritable();
ui.kDeleteTemplate->setVisible(local);
m_upload->setEnabled(local);
}
void SKGMonthlyPluginWidget::dataModified(const QString& iTableName, int iIdTransaction)
{
SKGTRACEINFUNC(1)
Q_UNUSED(iIdTransaction)
QSqlDatabase* db = getDocument()->getMainDatabase();
setEnabled(db != nullptr);
// TODO(Stephane MANKOWSKI): v_operation_display must be generic
if (db != nullptr && (iTableName == QStringLiteral("v_operation_display") || iTableName.isEmpty())) {
// Fill combo
QDate date = QDate::currentDate();
QStringList list;
// TODO(Stephane MANKOWSKI): v_operation_display must be generic
getDocument()->getDistinctValues(QStringLiteral("v_operation_display"), QStringLiteral("MIN(d_DATEMONTH)"), QStringLiteral("d_date<=CURRENT_DATE"), list);
if (!list.isEmpty()) {
if (!list[0].isEmpty()) {
date = SKGServices::periodToDate(list[0]);
}
}
ui.kMonth->setFirstDate(date);
ui.kRefresh->setEnabled(!list.isEmpty());
}
}
QString SKGMonthlyPluginWidget::getPeriod()
{
return ui.kMonth->period();
}
void SKGMonthlyPluginWidget::onPeriodChanged()
{
SKGTRACEINFUNC(1)
QString month = getPeriod();
if (!month.isEmpty()) {
// Display report
QString htmlReport = getDocument()->getParameter("SKG_MONTHLY_REPORT_" % month);
if (htmlReport.isEmpty() || sender() == ui.kRefresh || sender() == ui.kTemplate) {
SKGError err;
SKGBEGINLIGHTTRANSACTION(*getDocument(), i18nc("Noun, name of the user action", "Compute monthly report for '%1'", month), err)
htmlReport = getReport();
err = getDocument()->setParameter("SKG_MONTHLY_REPORT_" % month, htmlReport);
}
// Display html report
#ifdef SKG_WEBENGINE
ui.kWebView->page()->setHtml(htmlReport, QUrl("file://"));
#else
ui.kWebView->setHtml(htmlReport);
ui.kWebView->page()->setLinkDelegationPolicy(QWebPage::DelegateAllLinks);
#endif
}
}
void SKGMonthlyPluginWidget::onGetNewHotStuff()
{
QPointer<KNS3::DownloadDialog> dialog = new KNS3::DownloadDialog(KAboutData::applicationData().componentName() % "_monthly.knsrc", this);
dialog->exec();
fillTemplateList();
}
void SKGMonthlyPluginWidget::onPutNewHotStuff()
{
QString templat = ui.kTemplate->text().trimmed();
// Create zip file
QString templatFileName = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QLatin1Char('/') + KAboutData::applicationData().componentName() % "/html/" % templat % ".txt";
QString templatHFileName = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QLatin1Char('/') + KAboutData::applicationData().componentName() % "/html/" % templat % ".html";
QString zipFileName = QDir::tempPath() % "/" % templat % ".zip";
KZip zip(zipFileName);
if (zip.open(QIODevice::WriteOnly)) {
zip.addLocalFile(templatFileName, templat % ".txt");
if (QFile(templatHFileName).exists()) {
zip.addLocalFile(templatHFileName, templat % ".html");
}
zip.close();
// Create screen shots
QString preview1 = QDir::tempPath() % "/" % templat % "_preview1.png";
QString preview2 = QDir::tempPath() % "/" % templat % "_preview2.png";
QString preview3 = QDir::tempPath() % "/" % templat % "_preview3.png";
#ifdef SKG_WEBENGINE
// TODO(SMI): QWebEngine
#else
bool previous = ui.kWebView->blockSignals(true);
QWebFrame* frame = ui.kWebView->page()->mainFrame();
frame->setScrollBarValue(Qt::Vertical, frame->scrollBarMaximum(Qt::Vertical));
ui.kWebView->exportInFile(preview2);
frame->setScrollBarValue(Qt::Vertical, frame->scrollBarMaximum(Qt::Vertical) / 2);
ui.kWebView->exportInFile(preview3);
frame->setScrollBarValue(Qt::Vertical, 0);
ui.kWebView->exportInFile(preview1);
ui.kWebView->blockSignals(previous);
#endif
// Open dialog
QPointer<KNS3::UploadDialog> dialog = new KNS3::UploadDialog(KAboutData::applicationData().componentName() % "_monthly.knsrc", this);
dialog->setUploadFile(QUrl::fromLocalFile(zipFileName));
dialog->setUploadName(templat);
dialog->setPreviewImageFile(0, QUrl::fromLocalFile(preview1));
dialog->setPreviewImageFile(1, QUrl::fromLocalFile(preview2));
dialog->setPreviewImageFile(2, QUrl::fromLocalFile(preview3));
dialog->setDescription(i18nc("Default description for a monthly report template", "My favorite template"));
dialog->setVersion(QStringLiteral("0.1"));
dialog->setChangelog(QStringLiteral("V0.1 - Initial version"));
dialog->exec();
// Delete temporary files
QFile(zipFileName).remove();
QFile(preview1).remove();
QFile(preview2).remove();
QFile(preview3).remove();
}
}
QString SKGMonthlyPluginWidget::getReport()
{
QString html;
SKGError err;
SKGTRACEINFUNCRC(10, err)
QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
// Get period
if (!getPeriod().isEmpty()) {
SKGReport* rep = getDocument()->getReport();
if (rep != nullptr) {
rep->setPeriod(getPeriod());
// Enrich with tips of the day
rep->setTipsOfDay(SKGMainPanel::getMainPanel()->getTipsOfDay());
err = SKGReport::getReportFromTemplate(rep, ui.kTemplate->itemData(ui.kTemplate->currentIndex()).toString(), html);
delete rep;
}
}
QApplication::restoreOverrideCursor();
// status bar
IFKO(err) html += err.getFullMessageWithHistorical();
return html;
}
diff --git a/plugins/generic/skg_monthly/skgmonthlypluginwidget.h b/plugins/generic/skg_monthly/skgmonthlypluginwidget.h
index 58bc0c372..21fd82d73 100644
--- a/plugins/generic/skg_monthly/skgmonthlypluginwidget.h
+++ b/plugins/generic/skg_monthly/skgmonthlypluginwidget.h
@@ -1,101 +1,101 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGMONTHLYPLUGINWIDGET_H
#define SKGMONTHLYPLUGINWIDGET_H
/** @file
* A plugin for monthly report
*
* @author Stephane MANKOWSKI
*/
#include "skginterfaceplugin.h"
#include "skgtabpage.h"
#include "ui_skgmonthlypluginwidget_base.h"
/**
* A plugin for monthly report
*/
class SKGMonthlyPluginWidget : public SKGTabPage
{
Q_OBJECT
public:
/**
* Default Constructor
* @param iParent the parent widget
* @param iDocument the document
*/
explicit SKGMonthlyPluginWidget(QWidget* iParent, SKGDocument* iDocument);
/**
* Default Destructor
*/
~SKGMonthlyPluginWidget() override;
/**
* Get the current state
* MUST BE OVERWRITTEN
* @return a string containing all information needed to set the same state.
* Could be an XML stream
*/
QString getState() override;
/**
* Set the current state
* MUST BE OVERWRITTEN
* @param iState must be interpreted to set the state of the widget
*/
void setState(const QString& iState) override;
/**
* Get attribute name to save the default state
* MUST BE OVERWRITTEN
* @return attribute name to save the default state.
*/
QString getDefaultStateAttribute() override;
/**
* Get the main widget
* @return a widget
*/
QWidget* mainWidget() override;
/**
* Get the current month
* @return the current month
*/
virtual QString getPeriod();
private Q_SLOTS:
void dataModified(const QString& iTableName, int iIdTransaction);
void onPeriodChanged();
void onGetNewHotStuff();
void onPutNewHotStuff();
void onTemplateChanged();
void onAddTemplate();
void onDeleteTemplate();
QString getReport();
private:
Q_DISABLE_COPY(SKGMonthlyPluginWidget)
void fillTemplateList();
Ui::skgmonthlyplugin_base ui{};
QAction* m_upload;
};
#endif // SKGMonthlyPLUGINWIDGET_H
diff --git a/plugins/generic/skg_print/CMakeLists.txt b/plugins/generic/skg_print/CMakeLists.txt
index 519d2ef25..de53b9036 100644
--- a/plugins/generic/skg_print/CMakeLists.txt
+++ b/plugins/generic/skg_print/CMakeLists.txt
@@ -1,42 +1,42 @@
#***************************************************************************
#* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
#* *
#* 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 <http://www.gnu.org/licenses/> *
+#* along with this program. If not, see <https://www.gnu.org/licenses/> *
#***************************************************************************
MESSAGE( STATUS "..:: CMAKE PLUGIN_PRINT ::..")
PROJECT(plugin_print)
IF(SKG_WEBENGINE)
MESSAGE( STATUS " Mode WebEngine")
ADD_DEFINITIONS(-DSKG_WEBENGINE=${SKG_WEBENGINE})
ENDIF(SKG_WEBENGINE)
LINK_DIRECTORIES (${LIBRARY_OUTPUT_PATH})
SET(skg_print_SRCS
skgprintplugin.cpp)
ki18n_wrap_ui(skg_print_SRCS skgprintpluginwidget_pref.ui)
kconfig_add_kcfg_files(skg_print_SRCS skgprint_settings.kcfgc )
ADD_LIBRARY(skg_print MODULE ${skg_print_SRCS})
TARGET_LINK_LIBRARIES(skg_print KF5::Parts Qt5::PrintSupport skgbasemodeler skgbasegui)
########### install files ###############
INSTALL(TARGETS skg_print DESTINATION ${KDE_INSTALL_QTPLUGINDIR})
INSTALL(FILES ${PROJECT_SOURCE_DIR}/org.kde.skg-plugin-print.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR})
INSTALL(FILES ${PROJECT_SOURCE_DIR}/skg_print.rc DESTINATION ${KDE_INSTALL_KXMLGUI5DIR}/skg_print )
INSTALL(FILES ${PROJECT_SOURCE_DIR}/skgprint_settings.kcfg DESTINATION ${KDE_INSTALL_KCFGDIR} )
diff --git a/plugins/generic/skg_print/org.kde.skg-plugin-print.desktop b/plugins/generic/skg_print/org.kde.skg-plugin-print.desktop
index f1f1d8c3b..6a969921c 100644
--- a/plugins/generic/skg_print/org.kde.skg-plugin-print.desktop
+++ b/plugins/generic/skg_print/org.kde.skg-plugin-print.desktop
@@ -1,76 +1,76 @@
[Desktop Entry]
Name=Print plugin
Name[bs]=Dodatak za štampanje
Name[ca]=Connector d'impressió
Name[ca@valencia]=Connector d'impressió
Name[cs]=Modul pro tisk
Name[da]=Udskrifts-plugin
Name[de]=Druck-Modul
Name[el]=Print plugin
Name[en_GB]=Print plugin
Name[es]=Complemento de impresión
Name[et]=Trükkimisplugin
Name[fi]=Tulostusliitännäinen
Name[fr]=Module externe pour l'impression
Name[gl]=Complemento de impresión
Name[hu]=Nyomtatás bővítmény
Name[it]=Estensione di stampa
Name[lt]=Spausdinimo papildinys
Name[nb]=Utskriftsmodul
Name[nds]=Druckmoduul
Name[nl]=Plugin voor afdrukken
Name[pl]=Wtyczka wydruku
Name[pt]='Plugin' de impressão
Name[pt_BR]=Plugin de impressão
Name[ru]=Модуль печати
Name[sk]=Tlačový plugin
Name[sv]=Utskriftsinsticksprogram
Name[tr]=Yazdırma eklentisi
Name[uk]=Додаток друку
Name[x-test]=xxPrint pluginxx
Name[zh_TW]=列印外掛程式
Comment=A plugin to print pages
Comment[bs]=Dodatak za štampanje stranica
Comment[ca]=Un connector per imprimir pàgines
Comment[ca@valencia]=Un connector per imprimir pàgines
Comment[cs]=Modul pro tisk stránek
Comment[da]=Et plugin til at udskrive sider
Comment[de]=Ein Modul zum Drucken von Seiten
Comment[el]=Ένα πρόσθετο για εκτύπωση σελίδων
Comment[en_GB]=A plugin to print pages
Comment[es]=Un complemento para imprimir páginas
Comment[et]=Plugin lehekülgede trükkimiseks
Comment[fi]=Sivuja tulostava liitännäinen
Comment[fr]=Un module externe pour l'impression de pages
Comment[gl]=Un complemento para imprimir imaxes.
Comment[hu]=Egy bővítmény oldalak nyomtatásához
Comment[it]=Un'estensione per stampare pagine
Comment[lt]=Papildinys spausdinti puslapius
Comment[nb]=Et programtillegg for å skrive ut sider
Comment[nds]=En Moduul, mit dat sik Sieden drucken laat
Comment[nl]=Een plugin voor het afdrukken van pagina's
Comment[pl]=Wtyczka do wydruku stron
Comment[pt]=Um 'plugin' para a impressão de páginas
Comment[pt_BR]=Um plugin para imprimir páginas
Comment[ru]=Модуль печати страниц
Comment[sk]=Plugin na tlač stránok
Comment[sv]=Ett insticksprogram för utskrift av sidor
Comment[tr]=Sayfaları yazdırmak için bir eklenti
Comment[uk]=Додаток для друку сторінок
Comment[x-test]=xxA plugin to print pagesxx
Comment[zh_TW]=列印頁面用的外掛程式
Encoding=UTF-8
Icon=quickopen
Type=Service
X-KDE-ServiceTypes=SKG GUI/Plugin
X-KDE-Library=skg_print
X-Krunner-ID=Skrooge print plugin
X-KDE-PluginInfo-Author=Stephane MANKOWSKI,miraks
X-KDE-PluginInfo-Email=stephane@mankowski.fr
X-KDE-PluginInfo-Name=skg_print
X-KDE-PluginInfo-Version=1.0
-X-KDE-PluginInfo-Website=http://skrooge.org/
+X-KDE-PluginInfo-Website=https://skrooge.org/
X-KDE-PluginInfo-Category=Plugins
X-KDE-PluginInfo-Depends=
X-KDE-PluginInfo-License=GPL
X-KDE-PluginInfo-EnabledByDefault=true
diff --git a/plugins/generic/skg_print/skgprintplugin.cpp b/plugins/generic/skg_print/skgprintplugin.cpp
index ee86680f7..e6cf1d0a6 100644
--- a/plugins/generic/skg_print/skgprintplugin.cpp
+++ b/plugins/generic/skg_print/skgprintplugin.cpp
@@ -1,300 +1,300 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* A plugin to print pages
*
* @author Stephane MANKOWSKI
*/
#include "skgprintplugin.h"
#include <kaboutdata.h>
#include <kactioncollection.h>
#include <kpluginfactory.h>
#include <kstandardaction.h>
#include <qbuffer.h>
#include <qdesktopservices.h>
#include <qdir.h>
#include <qpainter.h>
#include <qpicture.h>
#include <qprintdialog.h>
#include <qprintpreviewdialog.h>
#include <qsavefile.h>
#include <qtextbrowser.h>
#include "skgmainpanel.h"
#include "skgprint_settings.h"
#include "skgtraces.h"
#include "skgtreeview.h"
/**
* This plugin factory.
*/
K_PLUGIN_FACTORY(SKGPrintPluginFactory, registerPlugin<SKGPrintPlugin>();)
SKGPrintPlugin::SKGPrintPlugin(QWidget* iWidget, QObject* iParent, const QVariantList& /*iArg*/) :
SKGInterfacePlugin(iParent), m_currentDocument(nullptr)
{
SKGTRACEINFUNC(10)
Q_UNUSED(iWidget)
m_printer.setResolution(QPrinter::HighResolution);
}
SKGPrintPlugin::~SKGPrintPlugin()
{
SKGTRACEINFUNC(10)
m_currentDocument = nullptr;
}
bool SKGPrintPlugin::setupActions(SKGDocument* iDocument)
{
SKGTRACEINFUNC(10)
m_currentDocument = iDocument;
setComponentName(QStringLiteral("skg_print"), title());
setXMLFile(QStringLiteral("skg_print.rc"));
registerGlobalAction(QStringLiteral("file_print"), KStandardAction::print(this, SLOT(onPrint()), actionCollection()), QStringList(), -1);
registerGlobalAction(QStringLiteral("file_print_preview"), KStandardAction::printPreview(this, SLOT(onPrintPreview()), actionCollection()), QStringList(), -1);
auto actPrintHtmlAction = new QAction(SKGServices::fromTheme(QStringLiteral("preview")), i18nc("Verb, print in an html file", "Print into a html file"), this);
connect(actPrintHtmlAction, &QAction::triggered, this, &SKGPrintPlugin::onPrintHtml);
registerGlobalAction(QStringLiteral("file_print_html"), actPrintHtmlAction, QStringList(), -1);
return true;
}
KConfigSkeleton* SKGPrintPlugin::getPreferenceSkeleton()
{
return skgprint_settings::self();
}
QString SKGPrintPlugin::title() const
{
return i18nc("Verb, action to use a printer", "print");
}
int SKGPrintPlugin::getOrder() const
{
return 2;
}
QStringList SKGPrintPlugin::tips() const
{
QStringList output;
output.push_back(i18nc("Description of a tips", "<p>... you can <a href=\"skg://file_print\">print</a> all opened pages.</p>"));
return output;
}
void SKGPrintPlugin::onPrint()
{
SKGError err;
SKGTRACEINFUNCRC(10, err)
if (SKGMainPanel::getMainPanel() != nullptr) {
QPointer<QPrintDialog> dialog = new QPrintDialog(&m_printer, SKGMainPanel::getMainPanel());
dialog->setOption(QAbstractPrintDialog::PrintCurrentPage, true);
dialog->setMinMax(1, SKGMainPanel::getMainPanel()->getTabWidget()->count());
if (dialog->exec() == QDialog::Accepted) {
QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
print(&m_printer);
QApplication::restoreOverrideCursor();
}
}
}
void SKGPrintPlugin::onPrintPreview()
{
SKGError err;
SKGTRACEINFUNCRC(10, err)
// TODO(SMI): QWebEngine does not work
QPointer<QPrintPreviewDialog> dialog = new QPrintPreviewDialog(SKGMainPanel::getMainPanel());
connect(dialog.data(), &QPrintPreviewDialog::paintRequested, this, &SKGPrintPlugin::print);
dialog->exec();
}
void SKGPrintPlugin::onPrintHtml()
{
QString html;
getHtml(&m_printer, html);
QString fileName = QDir::tempPath() % "/skrooge.html";
QSaveFile file(fileName);
if (file.open(QIODevice::WriteOnly)) {
QTextStream out(&file);
out << html;
// Close file
file.commit();
}
QDesktopServices::openUrl(QUrl::fromLocalFile(fileName));
}
SKGError SKGPrintPlugin::getHtml(QPrinter* iPrinter, QString& oHtml) const
{
SKGError err;
_SKGTRACEINFUNCRC(10, err)
if ((SKGMainPanel::getMainPanel() != nullptr) && (iPrinter != nullptr)) {
QString html;
// Get printer options
int docCopies;
int pageCopies;
if (iPrinter->collateCopies()) {
docCopies = 1;
pageCopies = iPrinter->actualNumCopies();
} else {
docCopies = iPrinter->actualNumCopies();
pageCopies = 1;
}
int fromPage = qMin(iPrinter->fromPage(), iPrinter->toPage());
int toPage = qMax(iPrinter->fromPage(), iPrinter->toPage());
// Compute the number of pages
SKGTabWidget* tabs = SKGMainPanel::getMainPanel()->getTabWidget();
int nbpages = tabs->count();
if (fromPage == 0 && toPage == 0) {
fromPage = 1;
toPage = nbpages;
}
if (iPrinter->printRange() == QPrinter::CurrentPage) {
fromPage = SKGMainPanel::getMainPanel()->currentPageIndex() + 1;
toPage = fromPage;
}
SKGTRACEL(10) << "Nb copy document=" << docCopies << endl;
SKGTRACEL(10) << "Nb copy page=" << docCopies << endl;
SKGTRACEL(10) << "From=" << fromPage << endl;
SKGTRACEL(10) << "To=" << toPage << endl;
// Copy document
for (int c = 1; !err && c <= docCopies; ++c) {
for (int i = 1; !err && i <= nbpages; ++i) {
// Compute page
int pageToTreat = (iPrinter->pageOrder() == QPrinter::LastPageFirst ? nbpages + 1 - i : i);
// Do we have to print it
if (pageToTreat >= fromPage && pageToTreat <= toPage) {
// Yes, get the widget
// Copy pages
for (int p = 1; !err && p <= pageCopies; ++p) {
auto* page = qobject_cast<SKGTabPage*>(tabs->widget(pageToTreat - 1));
if (page != nullptr) {
// Add page break if needed
if (!html.isEmpty()) {
html = html % "<div style=\"page-break-after:always\"></div>";
}
// Add widgets
QList<QWidget*> widgets = page->printableWidgets();
int nbw = widgets.count();
for (int j = 0; !err && j < nbw; ++j) {
QWidget* w = widgets.at(j);
if (w != nullptr) {
// Add widget
/*SKGTreeView* tw = qobject_cast< SKGTreeView* >(w);
if (tw) {
QTextBrowser* tb = tw->getTextBrowser();
if (tb) {
html = html % tb->toHtml();
delete tb;
}
} else {*/
#ifdef SKG_WEBENGINE
auto q = qobject_cast< QWebEngineView* >(w);
#else
auto q = qobject_cast< QWebView* >(w);
#endif
if (q != nullptr) {
#ifdef SKG_WEBENGINE
q->page()->toHtml([&](const QString & result) {
html = html % result;
});
qApp->processEvents(QEventLoop::AllEvents, 5000);
#else
html = html % q->page()->currentFrame()->toHtml();
#endif
} else {
// Save palette
QPalette previousPalette = w->palette();
// Draw in a picture with white background
QPalette palette;
palette.setColor(QPalette::Background, Qt::white);
w->setPalette(palette);
QImage image = w->grab().toImage();
// Restore palette
w->setPalette(previousPalette);
QByteArray byteArray;
QBuffer buffer(&byteArray);
image.save(&buffer, "PNG");
QString imgBase64 = QString::fromLatin1(byteArray.toBase64().data());
html = html % "<img src=\"data:image/png;base64," % imgBase64 % "\" />";
}
// }
}
}
}
}
}
}
}
oHtml = "<body style=\"background-color:white;\">" + html + "</body>";
}
return err;
}
void SKGPrintPlugin::print(QPrinter* iPrinter)
{
SKGTRACEINFUNC(10)
if ((SKGMainPanel::getMainPanel() != nullptr) && (iPrinter != nullptr)) {
QString html;
SKGError err = getHtml(iPrinter, html);
// Print
m_toPrint.setFixedSize(QSize(iPrinter->width(), iPrinter->height()));
#ifdef SKG_WEBENGINE
// TODO(SMI): QWebEngine - doesn't work - bad quality printing
disconnect(&m_toPrint);
connect(&m_toPrint, &QWebEngineView::loadFinished, &m_toPrint, [ = ]() {
m_toPrint.page()->print(iPrinter, [](bool) {});
});
m_toPrint.setHtml(html, QUrl("file://"));
#else
m_toPrint.setHtml(html);
m_toPrint.print(iPrinter);
#endif
// status bar
IFOKDO(err, SKGError(0, i18nc("Successful message after an user action", "Print successfully done.")))
else {
err.addError(ERR_FAIL, i18nc("Error message", "Print failed"));
}
// Display error
SKGMainPanel::displayErrorMessage(err);
}
}
#include <skgprintplugin.moc>
diff --git a/plugins/generic/skg_print/skgprintplugin.h b/plugins/generic/skg_print/skgprintplugin.h
index 033f2e20f..7159f09be 100644
--- a/plugins/generic/skg_print/skgprintplugin.h
+++ b/plugins/generic/skg_print/skgprintplugin.h
@@ -1,107 +1,107 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGPRINTPLUGIN_H
#define SKGPRINTPLUGIN_H
/** @file
* A plugin to print pages.
*
* @author Stephane MANKOWSKI
*/
#include <qprinter.h>
#ifdef SKG_WEBENGINE
#include <qwebengineview.h>
#else
#include <qwebframe.h>
#include <qwebview.h>
#endif
#include "skginterfaceplugin.h"
#include "ui_skgprintpluginwidget_pref.h"
/**
* A plugin to print pages
*/
class SKGPrintPlugin : public SKGInterfacePlugin
{
Q_OBJECT
Q_INTERFACES(SKGInterfacePlugin)
public:
/**
* Default Constructor
*/
explicit SKGPrintPlugin(QWidget* iWidget, QObject* iParent, const QVariantList& iArg);
/**
* Default Destructor
*/
~SKGPrintPlugin() override;
/**
* Called to initialise the plugin
* @param iDocument the main document
* @return true if the plugin is compatible with the document
*/
bool setupActions(SKGDocument* iDocument) override;
/**
* The preference skeleton of the plugin.
* @return The preference skeleton of the plugin
*/
KConfigSkeleton* getPreferenceSkeleton() override;
/**
* The title of the plugin.
* @return The title of the plugin
*/
QString title() const override;
/**
* The tips list of the plugin.
* @return The tips list of the plugin
*/
QStringList tips() const override;
/**
* Must be implemented to set the position of the plugin.
* @return integer value between 0 and 999 (default = 999)
*/
int getOrder() const override;
private Q_SLOTS:
void onPrint();
void onPrintPreview();
void onPrintHtml();
void print(QPrinter* iPrinter);
private:
Q_DISABLE_COPY(SKGPrintPlugin)
SKGError getHtml(QPrinter* iPrinter, QString& oHtml) const;
SKGDocument* m_currentDocument;
QPrinter m_printer;
#ifdef SKG_WEBENGINE
QWebEngineView m_toPrint;
#else
QWebView m_toPrint;
#endif
Ui::skgprintplugin_pref ui{};
};
#endif // SKGPRINTPLUGIN_H
diff --git a/plugins/generic/skg_properties/CMakeLists.txt b/plugins/generic/skg_properties/CMakeLists.txt
index e23983f05..89f9c495d 100644
--- a/plugins/generic/skg_properties/CMakeLists.txt
+++ b/plugins/generic/skg_properties/CMakeLists.txt
@@ -1,35 +1,35 @@
#***************************************************************************
#* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
#* *
#* 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 <http://www.gnu.org/licenses/> *
+#* along with this program. If not, see <https://www.gnu.org/licenses/> *
#***************************************************************************
MESSAGE( STATUS "..:: CMAKE PLUGIN_PROPERTIES ::..")
PROJECT(plugin_properties)
LINK_DIRECTORIES (${LIBRARY_OUTPUT_PATH})
SET(skg_properties_SRCS
skgpropertiesplugin.cpp
skgpropertiesplugindockwidget.cpp)
ki18n_wrap_ui(skg_properties_SRCS skgpropertiesplugindockwidget_base.ui)
ADD_LIBRARY(skg_properties MODULE ${skg_properties_SRCS})
TARGET_LINK_LIBRARIES(skg_properties KF5::Parts KF5::ItemViews KF5::KIOCore KF5::KIOFileWidgets KF5::KIOWidgets KF5::KIONTLM skgbasemodeler skgbasegui)
########### install files ###############
INSTALL(TARGETS skg_properties DESTINATION ${KDE_INSTALL_QTPLUGINDIR})
INSTALL(FILES ${PROJECT_SOURCE_DIR}/org.kde.skg-plugin-properties.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR})
INSTALL(FILES ${PROJECT_SOURCE_DIR}/skg_properties.rc DESTINATION ${KDE_INSTALL_KXMLGUI5DIR}/skg_properties )
diff --git a/plugins/generic/skg_properties/org.kde.skg-plugin-properties.desktop b/plugins/generic/skg_properties/org.kde.skg-plugin-properties.desktop
index dca178020..cf169d649 100644
--- a/plugins/generic/skg_properties/org.kde.skg-plugin-properties.desktop
+++ b/plugins/generic/skg_properties/org.kde.skg-plugin-properties.desktop
@@ -1,76 +1,76 @@
[Desktop Entry]
Name=Properties plugin
Name[bs]=Dodatak za svojstva
Name[ca]=Connector de propietats
Name[ca@valencia]=Connector de propietats
Name[cs]=Modul vlastností
Name[da]=Egenskabs-plugin
Name[de]=Eigenschaften-Modul
Name[el]=Properties plugin
Name[en_GB]=Properties plugin
Name[es]=Complemento de propiedades
Name[et]=Omaduste plugin
Name[fi]=Ominaisuusliitännäinen
Name[fr]=Module externe pour la gestion des propriétés
Name[gl]=Complemento de propiedades
Name[hu]=Tulajdonságok bővítmény
Name[it]=Estensione per proprietà
Name[lt]=Savybių papildinys
Name[nb]=Egenskapsmodul
Name[nds]=Egenschappenmoduul
Name[nl]=Plugin voor eigenschappen
Name[pl]=Wtyczka właściwości
Name[pt]='Plugin' de propriedades
Name[pt_BR]=Plugin de propriedades
Name[ru]=Модуль свойств
Name[sk]=Plugin vlastnosti
Name[sv]=Egenskapsinsticksprogram
Name[tr]=Özellikler eklentisi
Name[uk]=Додаток властивостей
Name[x-test]=xxProperties pluginxx
Name[zh_TW]=屬性外掛程式
Comment=A plugin to manage properties on objects
Comment[bs]=Dodatak za upravljanje svojstava objekata
Comment[ca]=Un connector per gestionar les propietats dels objectes
Comment[ca@valencia]=Un connector per gestionar les propietats dels objectes
Comment[cs]=Modul pro správu vlastností objektů
Comment[da]=Et plugin til at håndtere egenskaber for objekter
Comment[de]=Ein Modul zur Verwaltung von Eigenschaften von Objekten
Comment[el]=Ένα πρόσθετο για τη διαχείριση ιδιοτήτων σε αντικείμενα
Comment[en_GB]=A plugin to manage properties on objects
Comment[es]=Un complemento para gestionar propiedades de objetos
Comment[et]=Objektide omadusi hallata aitav plugin
Comment[fi]=Kohteiden ominaisuuksien hallinnan liitännäinen
Comment[fr]=Un module externe pour la gestion de propriétés
Comment[gl]=Un complemento para xestionar as propiedades dos obxectos.
Comment[hu]=Egy bővítmény az objektumok tulajdonságainak kezeléséhez
Comment[it]=Un'estensione per gestire le proprietà degli oggetti
Comment[lt]=Papildinys tvarkyti objektų savybes
Comment[nb]=Et programtillegg for å håndtere egenskaper på objekter
Comment[nds]=En Moduul för de Pleeg vun Objektegenschappen
Comment[nl]=Een plugin voor het beheren van eigenschappen van objecten
Comment[pl]=Wtyczka do obsługi właściwości obiektów
Comment[pt]=Um 'plugin' para gerir as propriedades dos objectos
Comment[pt_BR]=Um plugin para gerenciar propriedades em objetos
Comment[ru]=Модуль управления свойствами объектов
Comment[sk]=Plugin na správu vlastností objektov
Comment[sv]=Ett insticksprogram för att hantera objektegenskaper
Comment[tr]=Nesnelerin özelliklerini yönetmek için bir eklenti
Comment[uk]=Додаток для керування властивостями об’єктів
Comment[x-test]=xxA plugin to manage properties on objectsxx
Comment[zh_TW]=管理物件屬性的外掛程式
Encoding=UTF-8
Icon=quickopen
Type=Service
X-KDE-ServiceTypes=SKG GUI/Plugin
X-KDE-Library=skg_properties
X-Krunner-ID=Properties plugin
X-KDE-PluginInfo-Author=Stephane MANKOWSKI,miraks
X-KDE-PluginInfo-Email=stephane@mankowski.fr
X-KDE-PluginInfo-Name=skg_properties
X-KDE-PluginInfo-Version=1.0
-X-KDE-PluginInfo-Website=http://skrooge.org/
+X-KDE-PluginInfo-Website=https://skrooge.org/
X-KDE-PluginInfo-Category=Plugins
X-KDE-PluginInfo-Depends=
X-KDE-PluginInfo-License=GPL
X-KDE-PluginInfo-EnabledByDefault=true
diff --git a/plugins/generic/skg_properties/skgpropertiesplugin.cpp b/plugins/generic/skg_properties/skgpropertiesplugin.cpp
index 702f95d1e..7970fdabc 100644
--- a/plugins/generic/skg_properties/skgpropertiesplugin.cpp
+++ b/plugins/generic/skg_properties/skgpropertiesplugin.cpp
@@ -1,355 +1,355 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* A plugin to manage properties on objects
*
* @author Stephane MANKOWSKI
*/
#include "skgpropertiesplugin.h"
#include <qdir.h>
#include <qdockwidget.h>
#include <kaboutdata.h>
#include <kactioncollection.h>
#include <kpluginfactory.h>
#include <kstandardaction.h>
#include <ktoolbarpopupaction.h>
#include "skgmainpanel.h"
#include "skgpropertiesplugindockwidget.h"
#include "skgtraces.h"
#include "skgtransactionmng.h"
/**
* This plugin factory.
*/
K_PLUGIN_FACTORY(SKGPropertiesPluginFactory, registerPlugin<SKGPropertiesPlugin>();)
SKGPropertiesPlugin::SKGPropertiesPlugin(QWidget* iWidget, QObject* iParent, const QVariantList& /*iArg*/) :
SKGInterfacePlugin(iParent),
m_currentDocument(nullptr), m_dockWidget(nullptr), m_dockContent(nullptr), m_addPropertyMenu(nullptr)
{
Q_UNUSED(iWidget)
SKGTRACEINFUNC(10)
// Get list of bills
m_billsProcess.setStandardOutputFile(QDir::tempPath() % "/skg_bills.csv");
m_billsProcess.start(QStringLiteral("boobill bills -q -f csv -v"));
connect(&m_billsProcess, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished), this, &SKGPropertiesPlugin::onBillsRetreived);
connect(&m_billsProcess, static_cast<void (QProcess::*)(QProcess::ProcessError)>(&QProcess::error), this, &SKGPropertiesPlugin::onBillsRetreived);
}
SKGPropertiesPlugin::~SKGPropertiesPlugin()
{
SKGTRACEINFUNC(10)
m_currentDocument = nullptr;
m_dockWidget = nullptr;
m_dockContent = nullptr;
m_addPropertyMenu = nullptr;
if (m_billsProcess.state() == QProcess::Running) {
m_billsProcess.kill();
}
}
void SKGPropertiesPlugin::onBillsRetreived()
{
QFile file(QDir::tempPath() % "/skg_bills.csv");
if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
QTextStream stream(&file);
stream.readLine(); // To avoid header id;date;format;label;idparent;price;currency;deadline;startdate;finishdate
while (!stream.atEnd()) {
// Read line
QString line = stream.readLine().trimmed();
m_bills.push_back(line);
}
// close file
file.close();
}
file.remove();
}
bool SKGPropertiesPlugin::setupActions(SKGDocument* iDocument)
{
SKGTRACEINFUNC(10)
m_currentDocument = iDocument;
setComponentName(QStringLiteral("skg_properties"), title());
setXMLFile(QStringLiteral("skg_properties.rc"));
m_dockContent = new SKGPropertiesPluginDockWidget(SKGMainPanel::getMainPanel(), m_currentDocument);
if (m_dockContent != nullptr) {
connect(m_dockContent, &SKGPropertiesPluginDockWidget::selectionChanged, SKGMainPanel::getMainPanel(), &SKGMainPanel::refresh);
m_dockWidget = new QDockWidget(SKGMainPanel::getMainPanel());
if (m_dockWidget != nullptr) {
m_dockWidget->setObjectName(QStringLiteral("skg_properties_docwidget"));
m_dockWidget->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
m_dockWidget->setWindowTitle(title());
m_dockWidget->setWidget(m_dockContent);
// add action to control hide / display of Bookmarks
QAction* toggle = m_dockWidget->toggleViewAction();
QAction* panelAction = actionCollection()->addAction(QStringLiteral("view_properties"));
registerGlobalAction(QStringLiteral("view_properties"), panelAction);
panelAction->setCheckable(true);
panelAction->setChecked(toggle->isChecked());
panelAction->setText(toggle->text());
actionCollection()->setDefaultShortcut(panelAction, Qt::SHIFT + Qt::Key_F12);
connect(panelAction, &QAction::triggered, toggle, &QAction::trigger);
connect(toggle, &QAction::toggled, panelAction, &QAction::setChecked);
}
}
// Menu
auto actAddProperty = new KToolBarPopupAction(SKGServices::fromTheme(icon()), i18nc("Allows user to add a user defined property on an object", "Add property"), this);
m_addPropertyMenu = actAddProperty->menu();
connect(m_addPropertyMenu, &QMenu::aboutToShow, this, &SKGPropertiesPlugin::onShowAddPropertyMenu);
actAddProperty->setStickyMenu(false);
actAddProperty->setDelayed(false);
registerGlobalAction(QStringLiteral("add_property"), actAddProperty, QStringList() << QStringLiteral("query:type='table' AND name NOT LIKE 'doctransaction%'"), 1, -1, 450);
return true;
}
void SKGPropertiesPlugin::onAddProperty()
{
SKGTRACEINFUNC(10)
SKGError err;
// Scope for the transaction
auto* act = qobject_cast<QAction*>(sender());
if ((act != nullptr) && (m_currentDocument != nullptr)) {
// Get parameters
QStringList list = act->data().toStringList();
const QString& name = list.at(0);
const QString& value = list.at(1);
// Create properties
IFOK(err) {
SKGObjectBase::SKGListSKGObjectBase selection = SKGMainPanel::getMainPanel()->getSelectedObjects();
int nb = selection.count();
SKGBEGINPROGRESSTRANSACTION(*m_currentDocument, i18nc("Create a user defined property", "Property creation"), err, nb)
for (int i = 0; !err && i < nb; ++i) {
err = selection.at(i).setProperty(name, value);
IFOKDO(err, m_currentDocument->stepForward(i + 1))
}
}
}
// status bar
IFOK(err) {
err = SKGError(0, i18nc("The user defined property was successfully created", "Property created"));
}
SKGMainPanel::displayErrorMessage(err);
}
void SKGPropertiesPlugin::onDownloadAndAddBills()
{
SKGTRACEINFUNC(10)
SKGError err;
// Scope for the transaction
auto* act = qobject_cast<QAction*>(sender());
if ((act != nullptr) && (m_currentDocument != nullptr)) {
// Get parameters
QStringList list = act->data().toStringList();
const QString& id = list.at(0);
QString fileName = QDir::tempPath() % '/' % list.at(3) % '.' % list.at(2);
// Create properties
IFOK(err) {
SKGObjectBase::SKGListSKGObjectBase selection = SKGMainPanel::getMainPanel()->getSelectedObjects();
int nb = selection.count();
SKGBEGINPROGRESSTRANSACTION(*m_currentDocument, i18nc("Create a user defined property", "Property creation"), err, 2 * nb)
for (int i = 0; !err && i < nb; ++i) {
// Download the files
QFile::remove(fileName);
QString cmd = "boobill download " % id % " \"" % fileName % '"';
QProcess p;
p.start(cmd);
if (!p.waitForFinished(60000) || p.exitCode() != 0) {
err.setReturnCode(ERR_FAIL).setMessage(i18nc("Error message", "The following command line failed with code %2:\n'%1'", cmd, p.exitCode()));
} else {
IFOKDO(err, m_currentDocument->stepForward(2 * i))
IFOKDO(err, selection.at(i).setProperty(i18nc("Noun", "Bill"), id, fileName))
QStringList importedBills = SKGServices::splitCSVLine(m_currentDocument->getParameter(QStringLiteral("SKG_IMPORTED_BILLS")));
importedBills.push_back(id);
IFOKDO(err, m_currentDocument->setParameter(QStringLiteral("SKG_IMPORTED_BILLS"), SKGServices::stringsToCsv(importedBills)))
IFOKDO(err, m_currentDocument->stepForward(2 * i + 1))
QFile::remove(fileName);
}
}
}
}
// status bar
IFOK(err) {
err = SKGError(0, i18nc("The user defined property was successfully created", "Property created"));
}
SKGMainPanel::displayErrorMessage(err);
}
void SKGPropertiesPlugin::onShowAddPropertyMenu()
{
if ((m_addPropertyMenu != nullptr) && (m_currentDocument != nullptr)) {
m_addPropertyMenu->clear();
// Get selection
SKGObjectBase::SKGListSKGObjectBase sels = SKGMainPanel::getMainPanel()->getSelectedObjects();
if (!sels.isEmpty()) {
// Get the table of the selection
QString table = sels.at(0).getRealTable();
// Get list of more used properties for this table
SKGStringListList listTmp;
m_currentDocument->executeSelectSqliteOrder(
"SELECT t_name, t_value FROM (SELECT t_name, t_value, COUNT(1) AS nb FROM parameters WHERE (t_uuid_parent like '%-" % table % "' OR t_uuid_parent like '%-sub" % table % "') AND t_name NOT LIKE 'SKG_%' AND b_blob IS NULL GROUP BY t_name, t_value) ORDER BY nb DESC LIMIT 7",
listTmp);
// Create actions
int nb = listTmp.count();
QIcon iconp = SKGServices::fromTheme(icon());
if (nb > 1) {
for (int i = 1; i < nb; ++i) {
// Should the string below be translated ??? It contains no word...
QAction* act = m_addPropertyMenu->addAction(iconp, i18nc("Add a property (attribute=value)", "Add %1=%2", listTmp.at(i).at(0), listTmp.at(i).at(1)));
if (act != nullptr) {
act->setData(listTmp.at(i));
connect(act, &QAction::triggered, this, &SKGPropertiesPlugin::onAddProperty);
}
}
} else {
QAction* act = m_addPropertyMenu->addAction(iconp, i18nc("Help", "No property found. You must create a property from the dock first."));
act->setEnabled(false);
}
// Check if the sub process is still running
if (m_billsProcess.state() == QProcess::Running) {
// Create separator
{
QAction* act = m_addPropertyMenu->addAction(QLatin1String(""));
act->setSeparator(true);
}
// Add download on going
QAction* act = m_addPropertyMenu->addAction(i18nc("Message", "Download list of available bills on going..."));
if (act != nullptr) {
act->setEnabled(false);
}
} else {
// Check if some bills can be downloaded
int nb2 = m_bills.count();
if (nb2 != 0) {
// Create separator
{
QAction* act = m_addPropertyMenu->addAction(QLatin1String(""));
act->setSeparator(true);
}
// Create action
QStringList importedBills = SKGServices::splitCSVLine(m_currentDocument->getParameter(QStringLiteral("SKG_IMPORTED_BILLS")));
QMenu* menuMore = nullptr;
QIcon icond = SKGServices::fromTheme(icon(), QStringList() << QStringLiteral("download"));
QSet<QString> backendDone;
for (int j = 1; j < nb2; ++j) {
// id;date;format;label;idparent;price;currency;deadline;startdate;finishdate
QStringList fields = SKGServices::splitCSVLine(m_bills.at(j));
if (fields.count() > 3 && !importedBills.contains(fields.at(0))) {
QStringList ids = SKGServices::splitCSVLine(fields.at(0), '@');
if (ids.count() == 2) {
const QString& backend = ids.at(1);
// Selection of the menu where the item must be added
QMenu* menu;
if (!backendDone.contains(backend)) {
// This item must be added in root menu
menu = m_addPropertyMenu;
backendDone.insert(backend);
} else {
// This item must be added in "More..." menu
if (menuMore == nullptr) {
menuMore = new QMenu(i18nc("Noun", "More..."), m_addPropertyMenu);
}
menu = menuMore;
}
// Should the string below be translated ??? It contains no word...
QAction* act = menu->addAction(icond, i18nc("Add a property (attribute=value)", "Download and add %1 (%2)", fields[3] % '.' % fields[2], fields[0]));
if (act != nullptr) {
act->setToolTip(fields[0]);
act->setData(fields);
connect(act, &QAction::triggered, this, &SKGPropertiesPlugin::onDownloadAndAddBills);
}
}
}
}
// Add "More..." menu
if (menuMore != nullptr) {
m_addPropertyMenu->addMenu(menuMore);
}
}
}
}
}
}
void SKGPropertiesPlugin::refresh()
{
SKGTRACEINFUNC(10)
if (m_dockContent != nullptr) {
m_dockContent->refresh();
}
}
QDockWidget* SKGPropertiesPlugin::getDockWidget()
{
return m_dockWidget;
}
QString SKGPropertiesPlugin::title() const
{
return i18nc("Noun, an item's properties", "Properties");
}
QString SKGPropertiesPlugin::icon() const
{
return QStringLiteral("tag");
}
int SKGPropertiesPlugin::getOrder() const
{
return 6;
}
QStringList SKGPropertiesPlugin::tips() const
{
QStringList output;
output.push_back(i18nc("Description of a tip", "<p>... you can manage properties on all objects.</p>"));
output.push_back(i18nc("Description of a tip", "<p>... you can add files or Internet links as property.</p>"));
output.push_back(i18nc("Description of a tip", "<p>... you can automatically download and add bills as properties by using %1.</p>", "weboob"));
return output;
}
#include <skgpropertiesplugin.moc>
diff --git a/plugins/generic/skg_properties/skgpropertiesplugin.h b/plugins/generic/skg_properties/skgpropertiesplugin.h
index 3c30ec7d7..d5b12b366 100644
--- a/plugins/generic/skg_properties/skgpropertiesplugin.h
+++ b/plugins/generic/skg_properties/skgpropertiesplugin.h
@@ -1,111 +1,111 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGPROPERTIESPLUGIN_H
#define SKGPROPERTIESPLUGIN_H
/** @file
* A plugin to manage properties on objects.
*
* @author Stephane MANKOWSKI
*/
#include <qprocess.h>
#include "skginterfaceplugin.h"
class SKGPropertiesPluginDockWidget;
class QMenu;
class QDockWidget;
/**
* A plugin to manage properties on objects
*/
class SKGPropertiesPlugin : public SKGInterfacePlugin
{
Q_OBJECT
Q_INTERFACES(SKGInterfacePlugin)
public:
/**
* Default Constructor
*/
explicit SKGPropertiesPlugin(QWidget* iWidget, QObject* iParent, const QVariantList& iArg);
/**
* Default Destructor
*/
~SKGPropertiesPlugin() override;
/**
* Called to initialise the plugin
* @param iDocument the main document
* @return true if the plugin is compatible with the document
*/
bool setupActions(SKGDocument* iDocument) override;
/**
* Must be modified to refresh widgets after a modification.
*/
void refresh() override;
/**
* The dock widget of the plugin.
* @return The dock widget of the plugin
*/
QDockWidget* getDockWidget() override;
/**
* The icon of the plugin.
* @return The icon of the plugin
*/
QString icon() const override;
/**
* The title of the plugin.
* @return The title of the plugin
*/
QString title() const override;
/**
* The tips list of the plugin.
* @return The tips list of the plugin
*/
QStringList tips() const override;
/**
* Must be implemented to set the position of the plugin.
* @return integer value between 0 and 999 (default = 999)
*/
int getOrder() const override;
private Q_SLOTS:
void onAddProperty();
void onDownloadAndAddBills();
void onShowAddPropertyMenu();
void onBillsRetreived();
private:
Q_DISABLE_COPY(SKGPropertiesPlugin)
QProcess m_billsProcess;
QStringList m_bills;
SKGDocument* m_currentDocument;
QDockWidget* m_dockWidget;
SKGPropertiesPluginDockWidget* m_dockContent;
QMenu* m_addPropertyMenu;
};
#endif // SKGPROPERTIESPLUGIN_H
diff --git a/plugins/generic/skg_properties/skgpropertiesplugindockwidget.cpp b/plugins/generic/skg_properties/skgpropertiesplugindockwidget.cpp
index 96ece4e2e..b32f3a8ca 100644
--- a/plugins/generic/skg_properties/skgpropertiesplugindockwidget.cpp
+++ b/plugins/generic/skg_properties/skgpropertiesplugindockwidget.cpp
@@ -1,385 +1,385 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* A plugin to manage properties on objects.
*
* @author Stephane MANKOWSKI
*/
#include "skgpropertiesplugindockwidget.h"
#include <kmessagebox.h>
#include <qdesktopservices.h>
#include <qfile.h>
#include <qfiledialog.h>
#include <qlineedit.h>
#include "skgdocument.h"
#include "skgmainpanel.h"
#include "skgnamedobject.h"
#include "skgobjectmodelbase.h"
#include "skgpropertyobject.h"
#include "skgservices.h"
#include "skgsortfilterproxymodel.h"
#include "skgtraces.h"
#include "skgtransactionmng.h"
SKGPropertiesPluginDockWidget::SKGPropertiesPluginDockWidget(QWidget* iParent, SKGDocument* iDocument)
: SKGWidget(iParent, iDocument)
{
SKGTRACEINFUNC(1)
if (iDocument == nullptr) {
return;
}
ui.setupUi(this);
ui.kPicture->hide();
ui.kAdd->setMaximumWidth(ui.kAdd->height());
ui.kRemove->setMaximumWidth(ui.kRemove->height());
ui.kSelectFile->setMaximumWidth(ui.kSelectFile->height());
ui.kAdd->setIcon(SKGServices::fromTheme(QStringLiteral("list-add")));
ui.kRename->setIcon(SKGServices::fromTheme(QStringLiteral("dialog-ok")));
ui.kRemove->setIcon(SKGServices::fromTheme(QStringLiteral("list-remove")));
ui.kSelectFile->setIcon(SKGServices::fromTheme(QStringLiteral("document-open")));
ui.kOpenBtn->setIcon(SKGServices::fromTheme(QStringLiteral("quickopen")));
ui.kAttribute->lineEdit()->setPlaceholderText(i18n("Name"));
ui.kValue->lineEdit()->setPlaceholderText(i18n("Value"));
ui.kForCmb->addItem(i18n("Selection"));
ui.kForCmb->addItem(i18n("All"));
// Add model
auto modelview = new SKGObjectModelBase(getDocument(), QStringLiteral("parameters"), QStringLiteral("1=1 ORDER BY t_uuid_parent, t_name"), this, QLatin1String(""), false);
auto modelproxy = new SKGSortFilterProxyModel(this);
modelproxy->setSourceModel(modelview);
ui.kView->setModel(modelproxy);
connect(ui.kFilterEdit, &QLineEdit::textChanged, this, [ = ](const QString & itext) {
modelproxy->setFilterKeyColumn(-1);
modelproxy->setFilterCaseSensitivity(Qt::CaseInsensitive);
modelproxy->setFilterFixedString(itext);
});
auto actOpenPropertyFileAction = new QAction(QStringLiteral("internal action to open property file"), this);
connect(actOpenPropertyFileAction, &QAction::triggered, this, &SKGPropertiesPluginDockWidget::onOpenPropertyFileByUrl);
SKGMainPanel::getMainPanel()->registerGlobalAction(QStringLiteral("open_property_file"), actOpenPropertyFileAction);
ui.kView->setDefaultSaveParameters(getDocument(), QStringLiteral("SKG_DEFAULT_PROPERTIES"));
connect(modelview, &SKGObjectModelBase::beforeReset, ui.kView, &SKGTreeView::saveSelection);
connect(modelview, &SKGObjectModelBase::afterReset, ui.kView, &SKGTreeView::resetSelection);
connect(ui.kView, &SKGTableView::selectionChangedDelayed, this, &SKGPropertiesPluginDockWidget::onSelectionChanged);
connect(ui.kForCmb, static_cast<void (SKGComboBox::*)(const QString&)>(&SKGComboBox::currentTextChanged), this, &SKGPropertiesPluginDockWidget::refresh);
connect(ui.kAdd, &QPushButton::clicked, this, &SKGPropertiesPluginDockWidget::onAddProperty);
connect(ui.kRemove, &QPushButton::clicked, this, &SKGPropertiesPluginDockWidget::onRemoveProperty);
connect(ui.kSelectFile, &QPushButton::clicked, this, &SKGPropertiesPluginDockWidget::onSelectFile);
connect(ui.kOpenBtn, &QPushButton::clicked, this, &SKGPropertiesPluginDockWidget::onOpenFile);
connect(ui.kView, &SKGTableView::clickEmptyArea, this, &SKGPropertiesPluginDockWidget::cleanEditor);
connect(ui.kRename, &QPushButton::clicked, this, &SKGPropertiesPluginDockWidget::onRenameProperty);
ui.kView->setTextResizable(false);
}
SKGPropertiesPluginDockWidget::~SKGPropertiesPluginDockWidget()
{
SKGTRACEINFUNC(1)
}
void SKGPropertiesPluginDockWidget::refresh()
{
SKGTRACEINFUNC(1)
// Change filter
auto* proxyModel = qobject_cast<QSortFilterProxyModel*>(ui.kView->model());
auto* model = qobject_cast<SKGObjectModelBase*>(proxyModel->sourceModel());
if (model != nullptr) {
QString filter;
if (ui.kForCmb->currentIndex() == 1) {
filter = QStringLiteral("t_uuid_parent!='document' AND t_name NOT LIKE 'SKG_%'");
ui.kAdd->setEnabled(false);
ui.kSelectFile->setEnabled(false);
ui.kRemove->setEnabled(false);
ui.kAttribute->setEnabled(false);
ui.kValue->setEnabled(false);
} else if (ui.kForCmb->currentIndex() == 0) {
filter = QStringLiteral("t_uuid_parent IN (");
SKGObjectBase::SKGListSKGObjectBase selection = SKGMainPanel::getMainPanel()->getSelectedObjects();
int nb = selection.count();
if (nb != 0) {
ui.kAdd->setEnabled(true);
ui.kSelectFile->setEnabled(true);
ui.kRemove->setEnabled(false);
ui.kAttribute->setEnabled(true);
ui.kValue->setEnabled(true);
QString tableName;
for (int i = 0; i < nb; ++i) {
if (i > 0) {
filter += ',';
} else {
tableName = selection.at(i).getRealTable();
}
filter += '\'' % selection.at(i).getUniqueID() % '\'';
}
// Fill combo box
QString t = tableName;
if (t.startsWith(QLatin1String("sub"))) {
t = t.right(t.length() - 3);
}
SKGMainPanel::fillWithDistinctValue(QList<QWidget*>() << ui.kAttribute, getDocument(), QStringLiteral("parameters"), QStringLiteral("t_name"), "(t_uuid_parent like '%-" % t % "' OR t_uuid_parent like '%-sub" % t % "') AND t_name NOT LIKE 'SKG_%'");
SKGMainPanel::fillWithDistinctValue(QList<QWidget*>() << ui.kValue, getDocument(), QStringLiteral("parameters"), QStringLiteral("t_value"), "(t_uuid_parent like '%-" % t % "' OR t_uuid_parent like '%-sub" % t % "') AND t_name NOT LIKE 'SKG_%'");
} else {
filter += QStringLiteral("'XXX'"); // Always false
ui.kAdd->setEnabled(false);
ui.kSelectFile->setEnabled(false);
ui.kRemove->setEnabled(false);
ui.kAttribute->setEnabled(false);
ui.kValue->setEnabled(false);
}
filter += QStringLiteral(") AND t_name NOT LIKE 'SKG_%'");
}
filter += QStringLiteral(" ORDER BY t_uuid_parent, t_name");
ui.kView->saveSelection();
model->setFilter(filter);
model->refresh();
ui.kView->resetSelection();
}
ui.kView->setState(QLatin1String(""));
if (ui.kView->isAutoResized()) {
ui.kView->resizeColumnsToContentsDelayed();
}
onSelectionChanged();
}
void SKGPropertiesPluginDockWidget::onSelectionChanged()
{
SKGTRACEINFUNC(10)
int nbSelected = getNbSelectedObjects();
ui.kPicture->hide();
ui.kOpenBtn->hide();
ui.kRemove->setEnabled(nbSelected > 0);
if (nbSelected > 0) {
SKGObjectBase::SKGListSKGObjectBase objs = getSelectedObjects();
SKGPropertyObject obj(objs.at(0));
ui.kAttribute->setText(obj.getAttribute(QStringLiteral("t_name")));
ui.kValue->setText(obj.getAttribute(QStringLiteral("t_value")));
if (nbSelected == 1) {
QUrl u = obj.getUrl(true);
ui.kOpenBtn->show();
if (u.scheme() == QStringLiteral("file")) {
ui.kPicture->show();
ui.kPicture->showPreview(u);
}
}
}
if (ui.kView->isAutoResized()) {
ui.kView->resizeColumnsToContentsDelayed();
}
}
void SKGPropertiesPluginDockWidget::openPropertyFile(const SKGPropertyObject& iProp)
{
SKGTRACEINFUNC(10)
QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
QUrl url = iProp.getUrl(true);
if (!url.scheme().isEmpty() && !QDesktopServices::openUrl(url)) {
QString fileNameToSave = SKGMainPanel::getSaveFileName(QStringLiteral("kfiledialog:///IMPEXP"), QLatin1String(""), SKGMainPanel::getMainPanel());
if (!fileNameToSave.isEmpty()) {
QFile(url.toLocalFile()).copy(fileNameToSave);
}
}
QApplication::restoreOverrideCursor();
}
void SKGPropertiesPluginDockWidget::onOpenPropertyFileByUrl()
{
SKGTRACEINFUNC(10)
auto* act = qobject_cast<QAction*>(sender());
if (act != nullptr) {
SKGPropertyObject obj(getDocument(), SKGServices::stringToInt(act->property("id").toString()));
openPropertyFile(obj);
}
}
void SKGPropertiesPluginDockWidget::onOpenFile()
{
SKGTRACEINFUNC(10)
int nbSelected = getNbSelectedObjects();
if (nbSelected == 1) {
SKGObjectBase::SKGListSKGObjectBase objs = getSelectedObjects();
SKGPropertyObject obj(objs.at(0));
openPropertyFile(obj);
}
if (ui.kView->isAutoResized()) {
ui.kView->resizeColumnsToContentsDelayed();
}
}
void SKGPropertiesPluginDockWidget::onAddProperty()
{
SKGTRACEINFUNC(10)
SKGError err;
QStringList listUUID;
// Scope for the transaction
{
// Get parameters
QString name = ui.kAttribute->text();
QString value = ui.kValue->text();
QVariant blob;
QFile file(value);
if (file.exists()) {
int mode = KMessageBox::questionYesNoCancel(this, i18nc("Question", "Do you want copy or link the file?"),
QString(),
KGuiItem(i18nc("Question", "Copy"), QStringLiteral("edit-copy")),
KGuiItem(i18nc("Question", "Link"), QStringLiteral("edit-link")));
if (mode == KMessageBox::Cancel) {
return;
}
if (mode == KMessageBox::Yes) {
// Value is a file name ==> blob
if (Q_UNLIKELY(!file.open(QIODevice::ReadOnly))) {
err = SKGError(ERR_INVALIDARG, i18nc("Error message: could not open the requested file", "Open file '%1' failed", value));
} else {
QByteArray blob_bytes = file.readAll();
if (blob_bytes.isEmpty()) {
err = SKGError(ERR_INVALIDARG, i18nc("Error message: could not open the requested file", "Open file '%1' failed", value));
} else {
blob = blob_bytes;
value = QFileInfo(value).fileName();
}
// close file
file.close();
}
}
}
// Create properties
IFOK(err) {
SKGObjectBase::SKGListSKGObjectBase selection = SKGMainPanel::getMainPanel()->getSelectedObjects();
int nb = selection.count();
SKGBEGINPROGRESSTRANSACTION(*getDocument(), i18nc("Create a user defined property", "Property creation"), err, nb)
for (int i = 0; !err && i < nb; ++i) {
SKGPropertyObject prop;
err = selection.at(i).setProperty(name, value, blob, &prop);
IFOK(err) {
listUUID.push_back(prop.getUniqueID());
err = getDocument()->stepForward(i + 1);
}
}
}
}
// status bar
IFOK(err) {
err = SKGError(0, i18nc("The user defined property was successfully created", "Property created"));
ui.kView->selectObjects(listUUID, true);
}
SKGMainPanel::displayErrorMessage(err);
}
void SKGPropertiesPluginDockWidget::onRenameProperty()
{
SKGTRACEINFUNC(10)
SKGError err;
QStringList listUUID;
// Scope for the transaction
{
// Rename properties
IFOK(err) {
SKGObjectBase::SKGListSKGObjectBase selection = ui.kView->getSelectedObjects();
int nb = selection.count();
SKGBEGINPROGRESSTRANSACTION(*getDocument(), i18nc("Create a user defined property", "Rename property"), err, nb)
for (int i = 0; !err && i < nb; ++i) {
const SKGObjectBase& prop(selection.at(i));
IFOKDO(err, getDocument()->executeSqliteOrder("UPDATE parameters SET t_name='" % SKGServices::stringToSqlString(ui.kAttribute->text()) % "' WHERE id=" % SKGServices::intToString(prop.getID())))
IFOK(err) {
listUUID.push_back(prop.getUniqueID());
err = getDocument()->stepForward(i + 1);
}
}
}
}
// status bar
IFOK(err) {
err = SKGError(0, i18nc("The user property was successfully renamed", "Property renamed"));
ui.kView->selectObjects(listUUID, true);
}
SKGMainPanel::displayErrorMessage(err);
}
void SKGPropertiesPluginDockWidget::onSelectFile()
{
QString fileName = QFileDialog::getOpenFileName(this, i18nc("Open panel caption", "Select a file"));
ui.kValue->setText(fileName);
}
void SKGPropertiesPluginDockWidget::onRemoveProperty()
{
SKGError err;
SKGTRACEINFUNCRC(10, err) {
SKGObjectBase::SKGListSKGObjectBase selection = getSelectedObjects();
int nb = selection.count();
SKGBEGINPROGRESSTRANSACTION(*getDocument(), i18nc("Verb, delete an item", "Delete"), err, nb)
for (int i = 0; !err && i < nb; ++i) {
err = selection.at(i).remove();
IFOKDO(err, getDocument()->stepForward(i + 1))
}
}
// status bar
IFOKDO(err, SKGError(0, i18nc("The user defined property was successfully deleted", "Properties deleted.")))
else {
err.addError(ERR_FAIL, i18nc("Error message: Could not delete an item", "Delete failed"));
}
// Display error
SKGMainPanel::displayErrorMessage(err);
}
void SKGPropertiesPluginDockWidget::cleanEditor()
{
if (getNbSelectedObjects() == 0) {
ui.kAttribute->setText(QLatin1String(""));
ui.kValue->setText(QLatin1String(""));
}
}
QWidget* SKGPropertiesPluginDockWidget::mainWidget()
{
return ui.kView;
}
diff --git a/plugins/generic/skg_properties/skgpropertiesplugindockwidget.h b/plugins/generic/skg_properties/skgpropertiesplugindockwidget.h
index 73a5f9bf8..3b05f6b11 100644
--- a/plugins/generic/skg_properties/skgpropertiesplugindockwidget.h
+++ b/plugins/generic/skg_properties/skgpropertiesplugindockwidget.h
@@ -1,77 +1,77 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGPROPERTIESPLUGINDOCKWIDGET_H
#define SKGPROPERTIESPLUGINDOCKWIDGET_H
/** @file
* A plugin to manage properties on objects
*
* @author Stephane MANKOWSKI
*/
#include "skgwidget.h"
#include "ui_skgpropertiesplugindockwidget_base.h"
/**
* A plugin to manage properties on objects
*/
class SKGPropertiesPluginDockWidget : public SKGWidget
{
Q_OBJECT
public:
/**
* Default Constructor
* @param iParent the parent widget
* @param iDocument the document
*/
explicit SKGPropertiesPluginDockWidget(QWidget* iParent, SKGDocument* iDocument);
/**
* Default Destructor
*/
~SKGPropertiesPluginDockWidget() override;
/**
* Get the main widget
* @return a widget
*/
QWidget* mainWidget() override;
public Q_SLOTS:
/**
* Refresh the content.
*/
virtual void refresh();
private Q_SLOTS:
void onSelectionChanged();
void onAddProperty();
void onRenameProperty();
void onRemoveProperty();
void onSelectFile();
void onOpenFile();
void onOpenPropertyFileByUrl();
void cleanEditor();
private:
Q_DISABLE_COPY(SKGPropertiesPluginDockWidget)
void openPropertyFile(const SKGPropertyObject& iProp);
Ui::skgpropertiesdockplugin_base ui{};
};
#endif // SKGPROPERTIESPLUGINDOCKWIDGET_H
diff --git a/plugins/generic/skg_selectall/CMakeLists.txt b/plugins/generic/skg_selectall/CMakeLists.txt
index c3765f28a..ad267512f 100644
--- a/plugins/generic/skg_selectall/CMakeLists.txt
+++ b/plugins/generic/skg_selectall/CMakeLists.txt
@@ -1,34 +1,34 @@
#***************************************************************************
#* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
#* *
#* 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 <http://www.gnu.org/licenses/> *
+#* along with this program. If not, see <https://www.gnu.org/licenses/> *
#***************************************************************************
MESSAGE( STATUS "..:: CMAKE PLUGIN_SELECTALL ::..")
PROJECT(plugin_selectall)
LINK_DIRECTORIES (${LIBRARY_OUTPUT_PATH})
SET(skg_selectall_SRCS
skgselectallplugin.cpp
)
ADD_LIBRARY(skg_selectall MODULE ${skg_selectall_SRCS})
TARGET_LINK_LIBRARIES(skg_selectall KF5::Parts skgbasemodeler skgbasegui)
########### install files ###############
INSTALL(TARGETS skg_selectall DESTINATION ${KDE_INSTALL_QTPLUGINDIR})
INSTALL(FILES ${PROJECT_SOURCE_DIR}/org.kde.skg-plugin-selectall.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR})
INSTALL(FILES ${PROJECT_SOURCE_DIR}/skg_selectall.rc DESTINATION ${KDE_INSTALL_KXMLGUI5DIR}/skg_selectall )
diff --git a/plugins/generic/skg_selectall/org.kde.skg-plugin-selectall.desktop b/plugins/generic/skg_selectall/org.kde.skg-plugin-selectall.desktop
index fc6d449ee..3ace69955 100644
--- a/plugins/generic/skg_selectall/org.kde.skg-plugin-selectall.desktop
+++ b/plugins/generic/skg_selectall/org.kde.skg-plugin-selectall.desktop
@@ -1,77 +1,77 @@
[Desktop Entry]
Name=Select all plugin
Name[bs]=Dodatak izaberi sve
Name[ca]=Connector per seleccionar-ho tot
Name[ca@valencia]=Connector per seleccionar-ho tot
Name[cs]=Vybrat všechny moduly
Name[da]=Markér alt-plugin
Name[de]=Gesamtauswahl-Modul
Name[el]=Select all plugin
Name[en_GB]=Select all plugin
Name[es]=Seleccionar todos los complementos
Name[et]=Kõige valimise plugin
Name[fi]=Valitse kaikki -liitännäinen
Name[fr]=Module externe pour tout sélectionner
Name[gl]=Complemento de escollelo todo
Name[hu]=Minden kijelölése bővítmény
Name[it]=Seleziona tutte le estensioni
Name[lt]=Pažymėti viską papildinys
Name[nb]=Velg alt-modul
Name[nds]="Allens utsöken"-Moduul
Name[nl]=Plugins voor alles selecteren
Name[pl]=Wtyczka "zaznacz wszystko"
Name[pt]='Plugin' de selecção total
Name[pt_BR]=Plugin de seleção total
Name[ru]=Модуль «Выбрать всё»
Name[sk]=Plugin Vybrať všetko
Name[sv]=Insticksprogram för markera alla
Name[tr]=Tümünü seç eklentisi
Name[uk]=Додаток позначення повністю
Name[x-test]=xxSelect all pluginxx
Name[zh_CN]=全选插件
Name[zh_TW]=全部選取外掛程式
Comment=A plugin to select all
Comment[bs]=Dodatak za biranje svega
Comment[ca]=Un connector per seleccionar-ho tot
Comment[ca@valencia]=Un connector per seleccionar-ho tot
Comment[cs]=Modul pro výběr všeho
Comment[da]=Et plugin til at markere alt
Comment[de]=Ein Modul um Alles auszuwählen
Comment[el]=Ένα πρόσθετο για την επιλογή όλων
Comment[en_GB]=A plugin to select all
Comment[es]=Un complemento para seleccionarlos a todos
Comment[et]=Plugin kõige valimiseks
Comment[fi]=Valitse kaikki -liitännäinen
Comment[fr]=Un module externe pour tout sélectionner
Comment[gl]=Un complemento para escollelo todo.
Comment[hu]=Egy bővítmény minden kijelöléséhez
Comment[it]=Un'estensione per la selezione di tutte le estensioni
Comment[lt]=Pažymėti viską papildinys
Comment[nb]=Et programtillegg for å velge alt
Comment[nds]=En Moduul, mit dat sik allens utsöken lett
Comment[nl]=Een plugin om alles te selecteren
Comment[pl]=Wtyczka do zaznaczania wszystkiego
Comment[pt]=Um 'plugin' para seleccionar tudo
Comment[pt_BR]=Um plugin para selecionar tudo
Comment[ru]=Модуль «Выбрать всё»
Comment[sk]=Plugin na vybratie všetkého
Comment[sv]=Ett insticksprogram för att markera allt
Comment[tr]=Tümünü seçmek için bir eklenti
Comment[uk]=Додаток для позначення всіх елементів
Comment[x-test]=xxA plugin to select allxx
Comment[zh_TW]=全部選取用的外掛程式
Encoding=UTF-8
Icon=quickopen
Type=Service
X-KDE-ServiceTypes=SKG GUI/Plugin
X-KDE-Library=skg_selectall
X-Krunner-ID=Selectall plugin
X-KDE-PluginInfo-Author=Stephane MANKOWSKI,miraks
X-KDE-PluginInfo-Email=stephane@mankowski.fr
X-KDE-PluginInfo-Name=skg_selectall
X-KDE-PluginInfo-Version=1.0
-X-KDE-PluginInfo-Website=http://skrooge.org/
+X-KDE-PluginInfo-Website=https://skrooge.org/
X-KDE-PluginInfo-Category=Plugins
X-KDE-PluginInfo-Depends=
X-KDE-PluginInfo-License=GPL
X-KDE-PluginInfo-EnabledByDefault=true
diff --git a/plugins/generic/skg_selectall/skgselectallplugin.cpp b/plugins/generic/skg_selectall/skgselectallplugin.cpp
index 2c4d76317..0de2649cf 100644
--- a/plugins/generic/skg_selectall/skgselectallplugin.cpp
+++ b/plugins/generic/skg_selectall/skgselectallplugin.cpp
@@ -1,158 +1,158 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* A plugin to select all
*
* @author Stephane MANKOWSKI
*/
#include "skgselectallplugin.h"
#include <kaboutdata.h>
#include <kactioncollection.h>
#include <klocalizedstring.h>
#include <kpluginfactory.h>
#include <kstandardaction.h>
#include <qabstractitemview.h>
#include "skgmainpanel.h"
#include "skgtraces.h"
#include "skgtreeview.h"
/**
* This plugin factory.
*/
K_PLUGIN_FACTORY(SKGSelectAllPluginFactory, registerPlugin<SKGSelectAllPlugin>();)
SKGSelectAllPlugin::SKGSelectAllPlugin(QWidget* iWidget, QObject* iParent, const QVariantList& /*iArg*/) :
SKGInterfacePlugin(iParent), m_currentDocument(nullptr), m_selectionMessage(nullptr)
{
Q_UNUSED(iWidget)
SKGTRACEINFUNC(10)
connect(SKGMainPanel::getMainPanel(), &SKGMainPanel::selectionChanged, this, &SKGSelectAllPlugin::onSelectionChanged);
}
SKGSelectAllPlugin::~SKGSelectAllPlugin()
{
SKGTRACEINFUNC(10)
m_currentDocument = nullptr;
m_selectionMessage = nullptr;
}
bool SKGSelectAllPlugin::setupActions(SKGDocument* iDocument)
{
SKGTRACEINFUNC(10)
m_currentDocument = iDocument;
setComponentName(QStringLiteral("skg_selectall"), title());
setXMLFile(QStringLiteral("skg_selectall.rc"));
// Menu
registerGlobalAction(QStringLiteral("edit_select_all"), actionCollection()->addAction(KStandardAction::SelectAll, QStringLiteral("edit_select_all"), this, SLOT(onSelectAll())), QStringList(), 0);
return true;
}
QString SKGSelectAllPlugin::title() const
{
return i18nc("Select all objects in a list", "Select all");
}
QString SKGSelectAllPlugin::icon() const
{
return QStringLiteral("edit-select-all");
}
QString SKGSelectAllPlugin::toolTip() const
{
return i18nc("Select all objects in a list", "Select all");
}
int SKGSelectAllPlugin::getOrder() const
{
return 6;
}
QStringList SKGSelectAllPlugin::tips() const
{
QStringList output;
return output;
}
void SKGSelectAllPlugin::onSelectionChanged()
{
SKGTRACEINFUNC(10)
if (SKGMainPanel::getMainPanel() != nullptr) {
if (m_selectionMessage == nullptr) {
// Add statusbar
m_selectionMessage = new QLabel(SKGMainPanel::getMainPanel());
SKGMainPanel::getMainPanel()->statusBar()->insertPermanentWidget(1, m_selectionMessage);
}
SKGObjectBase::SKGListSKGObjectBase selection = SKGMainPanel::getMainPanel()->getSelectedObjects();
int nb = selection.count();
if (nb != 0) {
double sum = 0.0;
double max = -std::numeric_limits<double>::max();
double min = std::numeric_limits<double>::max();
int count = 0;
for (int i = 0; i < nb; ++i) {
const SKGObjectBase& obj(selection.at(i));
QString val = obj.getAttribute(QStringLiteral("f_REALCURRENTAMOUNT"));
if (val.isEmpty()) {
val = obj.getAttribute(QStringLiteral("f_CURRENTAMOUNT"));
}
if (!val.isEmpty()) {
double vald = SKGServices::stringToDouble(val);
sum += vald;
max = qMax(max, vald);
min = qMin(min, vald);
count++;
}
}
if (count > 1) {
m_selectionMessage->setText(i18n("Selection: %1 lines for %2 (min: %3, average: %4, max: %5)",
nb,
m_currentDocument->formatPrimaryMoney(sum),
m_currentDocument->formatPrimaryMoney(min),
m_currentDocument->formatPrimaryMoney(sum / count),
m_currentDocument->formatPrimaryMoney(max)));
} else if (count > 0) {
m_selectionMessage->setText(i18n("Selection: %1 line for %2", nb, m_currentDocument->formatPrimaryMoney(sum)));
} else {
m_selectionMessage->setText(i18np("Selection: %1 line", "Selection: %1 lines", nb));
}
} else {
m_selectionMessage->clear();
}
}
}
void SKGSelectAllPlugin::onSelectAll()
{
SKGTRACEINFUNC(10)
if (SKGMainPanel::getMainPanel() != nullptr) {
SKGTabPage* page = SKGMainPanel::getMainPanel()->currentPage();
if (page != nullptr) {
auto* view = qobject_cast<QAbstractItemView*>(page->mainWidget());
if (view != nullptr) {
view->selectAll();
}
}
}
}
#include <skgselectallplugin.moc>
diff --git a/plugins/generic/skg_selectall/skgselectallplugin.h b/plugins/generic/skg_selectall/skgselectallplugin.h
index cf778daf9..dfd18ecfe 100644
--- a/plugins/generic/skg_selectall/skgselectallplugin.h
+++ b/plugins/generic/skg_selectall/skgselectallplugin.h
@@ -1,95 +1,95 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGSELECTALLPLUGIN_H
#define SKGSELECTALLPLUGIN_H
/** @file
* A plugin to select all.
*
* @author Stephane MANKOWSKI
*/
#include "skginterfaceplugin.h"
class QLabel;
/**
* A plugin to select all
*/
class SKGSelectAllPlugin : public SKGInterfacePlugin
{
Q_OBJECT
Q_INTERFACES(SKGInterfacePlugin)
public:
/**
* Default Constructor
*/
explicit SKGSelectAllPlugin(QWidget* iWidget, QObject* iParent, const QVariantList& iArg);
/**
* Default Destructor
*/
~SKGSelectAllPlugin() override;
/**
* Called to initialise the plugin
* @param iDocument the main document
* @return true if the plugin is compatible with the document
*/
bool setupActions(SKGDocument* iDocument) override;
/**
* The title of the plugin.
* @return The title of the plugin
*/
QString title() const override;
/**
* The icon of the plugin.
* @return The icon of the plugin
*/
QString icon() const override;
/**
* The toolTip of the plugin.
* @return The toolTip of the plugin
*/
QString toolTip() const override;
/**
* The tips list of the plugin.
* @return The tips list of the plugin
*/
QStringList tips() const override;
/**
* Must be implemented to set the position of the plugin.
* @return integer value between 0 and 999 (default = 999)
*/
int getOrder() const override;
private Q_SLOTS:
void onSelectAll();
void onSelectionChanged();
private:
Q_DISABLE_COPY(SKGSelectAllPlugin)
SKGDocument* m_currentDocument;
QLabel* m_selectionMessage;
};
#endif // SKGSELECTALLPLUGIN_H
diff --git a/plugins/generic/skg_statistic/CMakeLists.txt b/plugins/generic/skg_statistic/CMakeLists.txt
index aa1930ac7..60ccec2ed 100644
--- a/plugins/generic/skg_statistic/CMakeLists.txt
+++ b/plugins/generic/skg_statistic/CMakeLists.txt
@@ -1,41 +1,41 @@
#***************************************************************************
#* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
#* *
#* 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 <http://www.gnu.org/licenses/> *
+#* along with this program. If not, see <https://www.gnu.org/licenses/> *
#***************************************************************************
MESSAGE( STATUS "..:: CMAKE PLUGIN_STATISTIC ::..")
PROJECT(plugin_statistic)
INCLUDE(CheckIncludeFileCXX)
CHECK_INCLUDE_FILE_CXX("sys/utsname.h" HAVE_UNAME)
IF(HAVE_UNAME)
MESSAGE( STATUS "uname found")
add_definitions(-DHAVE_UNAME)
ELSE(HAVE_UNAME)
MESSAGE( STATUS "uname NOT FOUND")
ENDIF(HAVE_UNAME)
LINK_DIRECTORIES (${LIBRARY_OUTPUT_PATH})
SET(skg_statistic_SRCS
skgstatisticplugin.cpp)
ADD_LIBRARY(skg_statistic MODULE ${skg_statistic_SRCS})
TARGET_LINK_LIBRARIES(skg_statistic KF5::Parts Qt5::Core skgbasemodeler skgbasegui)
########### install files ###############
INSTALL(TARGETS skg_statistic DESTINATION ${KDE_INSTALL_QTPLUGINDIR})
INSTALL(FILES ${PROJECT_SOURCE_DIR}/org.kde.skg-plugin-statistic.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR})
INSTALL(FILES ${PROJECT_SOURCE_DIR}/skg_statistic.rc DESTINATION ${KDE_INSTALL_KXMLGUI5DIR}/skg_statistic )
diff --git a/plugins/generic/skg_statistic/org.kde.skg-plugin-statistic.desktop b/plugins/generic/skg_statistic/org.kde.skg-plugin-statistic.desktop
index f4fc0181c..b4c753ffe 100644
--- a/plugins/generic/skg_statistic/org.kde.skg-plugin-statistic.desktop
+++ b/plugins/generic/skg_statistic/org.kde.skg-plugin-statistic.desktop
@@ -1,62 +1,62 @@
[Desktop Entry]
Name=Statistic plugin
Name[bs]=Statistički dodatak
Name[ca]=Connector d'estadístiques
Name[ca@valencia]=Connector d'estadístiques
Name[cs]=Modul pro statistiku
Name[da]=Statistik-plugin
Name[de]=Statistik-Modul
Name[en_GB]=Statistic plugin
Name[es]=Complemento de estadísticas
Name[fi]=Tilastoliitännäinen
Name[fr]=Module externe pour les statistiques
Name[gl]=Complemento de estatísticas
Name[hu]=Statisztika bővítmény
Name[it]=Estensione statistiche
Name[nl]=Plug-in voor statistiek
Name[pl]=Wtyczka statystyki
Name[pt]='Plugin' de estatísticas
Name[pt_BR]=Plugin de estatísticas
Name[sk]=Štatistický plugin
Name[sv]=Statistikinsticksprogram
Name[tr]=İstatistik eklentisi
Name[uk]=Додаток статистики
Name[x-test]=xxStatistic pluginxx
Comment=A plugin to generate statistic
Comment[bs]=Dodatak za generisanje statistike
Comment[ca]=Un connector per generar estadístiques
Comment[ca@valencia]=Un connector per generar estadístiques
Comment[cs]=Modul pro generování statistiky
Comment[da]=Et plugin til at generere statistik
Comment[de]=Ein Modul zum Erstellen von Statistiken
Comment[en_GB]=A plugin to generate statistic
Comment[es]=Un complemento para generar estadísticas
Comment[fi]=Tilastoja luova liitännäinen
Comment[fr]=Un module externe pour générer des statistiques
Comment[gl]=Un complemento para xerar estatísticas.
Comment[hu]=Egy bővítmény statisztika előállításához
Comment[it]=Un'estensione per generare le statistiche
Comment[nl]=Een plug-in om statistieken te genereren
Comment[pl]=Wtyczka do tworzenia statystyk
Comment[pt]=Um 'plugin' para gerar estatísticas
Comment[pt_BR]=Um plugin para gerar estatísticas
Comment[sk]=Plugin na generovanie štatistík
Comment[sv]=Ett insticksprogram för att skapa statistik
Comment[tr]=İstatistik oluşturmak için bir eklenti
Comment[uk]=Додаток для отримання статистичних даних
Comment[x-test]=xxA plugin to generate statisticxx
Encoding=UTF-8
Icon=quickopen
Type=Service
X-KDE-ServiceTypes=SKG GUI/Plugin
X-KDE-Library=skg_statistic
X-Krunner-ID=Statistic plugin
X-KDE-PluginInfo-Author=Stephane MANKOWSKI
X-KDE-PluginInfo-Email=stephane@mankowski.fr
X-KDE-PluginInfo-Name=skg_statistic
X-KDE-PluginInfo-Version=1.0
-X-KDE-PluginInfo-Website=http://skrooge.org/
+X-KDE-PluginInfo-Website=https://skrooge.org/
X-KDE-PluginInfo-Category=Plugins
X-KDE-PluginInfo-Depends=
X-KDE-PluginInfo-License=GPL
X-KDE-PluginInfo-EnabledByDefault=true
diff --git a/plugins/generic/skg_statistic/skgstatisticplugin.cpp b/plugins/generic/skg_statistic/skgstatisticplugin.cpp
index c7f2884f3..fa78c5f8c 100644
--- a/plugins/generic/skg_statistic/skgstatisticplugin.cpp
+++ b/plugins/generic/skg_statistic/skgstatisticplugin.cpp
@@ -1,264 +1,264 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* A plugin to generate statistic
*
* @author Stephane MANKOWSKI
*/
#include "skgstatisticplugin.h"
#ifdef HAVE_UNAME
# include <sys/utsname.h>
#endif
#include <kaboutdata.h>
#include <kactioncollection.h>
#include <kpluginfactory.h>
#include <kstandardaction.h>
#include <qapplication.h>
#include <qcryptographichash.h>
#include <qdesktopwidget.h>
#include <qdir.h>
#include <qjsondocument.h>
#include <qscreen.h>
#include "skgmainpanel.h"
#include "skgtraces.h"
/**
* This plugin factory.
*/
K_PLUGIN_FACTORY(SKGStatisticPluginFactory, registerPlugin<SKGStatisticPlugin>();)
SKGStatisticPlugin::SKGStatisticPlugin(QWidget* iWidget, QObject* iParent, const QVariantList& /*iArg*/) :
SKGInterfacePlugin(iParent), m_currentDocument(nullptr)
{
Q_UNUSED(iWidget)
m_timeInit = QDateTime::currentDateTime();
SKGTRACEINFUNC(10)
connect(SKGMainPanel::getMainPanel(), &SKGMainPanel::currentPageChanged, this, &SKGStatisticPlugin::pageChanged);
connect(SKGMainPanel::getMainPanel(), &SKGMainPanel::pageOpened, this, &SKGStatisticPlugin::pageOpened);
}
SKGStatisticPlugin::~SKGStatisticPlugin()
{
SKGTRACEINFUNC(10)
// Set duration
m_stats[QStringLiteral("avg.exec_time_sec")] = (m_stats.value(QStringLiteral("avg.exec_time_sec")).toDouble() * (m_stats.value(QStringLiteral("nb_launch")).toInt() - 1) + m_timeInit.secsTo(QDateTime::currentDateTime())) / m_stats.value(QStringLiteral("nb_launch")).toInt();
// Write stat file
writeStats();
m_currentDocument = nullptr;
}
bool SKGStatisticPlugin::setupActions(SKGDocument* iDocument)
{
SKGTRACEINFUNC(10)
m_currentDocument = iDocument;
setComponentName(QStringLiteral("skg_statistic"), title());
setXMLFile(QStringLiteral("skg_statistic.rc"));
return true;
}
void SKGStatisticPlugin::refresh()
{
SKGTRACEINFUNC(10)
if (m_currentDocument != nullptr) {
if (m_currentDocument->getMainDatabase() != nullptr) {
static bool initialisationDone = false;
if (!initialisationDone) {
// Connect actions
QMap<QString, QPointer<QAction> > actions = SKGMainPanel::getMainPanel()->getGlobalActions();
QStringList keys = actions.keys();
for (const auto& k : keys) {
QPointer<QAction> act = actions[k];
connect(act.data(), &QAction::triggered, this, &SKGStatisticPlugin::triggerAction);
}
initialisationDone = true;
}
QString doc_id = m_currentDocument->getUniqueIdentifier();
if (m_docUniqueIdentifier != doc_id) {
m_docUniqueIdentifier = doc_id;
// Initialize
QString appname = KAboutData::applicationData().componentName();
QDir::home().mkdir("." % appname);
QString docUUID = QString(QCryptographicHash::hash(m_currentDocument->getCurrentFileName().toLatin1(), QCryptographicHash::Md5).toHex());
m_file = QDir::homePath() % "/." % appname % "/" % docUUID % ".stats.txt";
// Read previous stat file
readStats();
// Initial values
if (!m_stats.contains(QStringLiteral("init.date"))) {
m_stats[QStringLiteral("init.date")] = QDate::currentDate();
m_stats[QStringLiteral("init.qt_version")] = qVersion();
m_stats[QStringLiteral("init.app_name")] = appname;
m_stats[QStringLiteral("init.app_version")] = KAboutData::applicationData().version();
}
m_stats[QStringLiteral("nb_launch")] = m_stats.value(QStringLiteral("nb_launch")).toInt() + 1;
// Current values
m_stats[QStringLiteral("current.date")] = QDate::currentDate();
m_stats[QStringLiteral("current.qt_version")] = qVersion();
m_stats[QStringLiteral("current.app_version")] = KAboutData::applicationData().version();
m_stats[QStringLiteral("current.language")] = QLocale::languageToString(QLocale().language());
m_stats[QStringLiteral("current.country")] = QLocale::countryToString(QLocale().country());
// OS
#ifdef Q_OS_WIN32
QString os = QStringLiteral("Windows");
#elif defined(Q_OS_FREEBSD)
QString os = QStringLiteral("FreeBSD");
#elif defined(Q_OS_NETBSD)
QString os = QStringLiteral("NetBSD");
#elif defined(Q_OS_OPENBSD)
QString os = QStringLiteral("OpenBSD");
#elif defined(Q_OS_LINUX)
QString os = QStringLiteral("Linux");
#elif defined(Q_OS_MAC)
QString os = QStringLiteral("Mac OS");
#else
QString os = QStringLiteral("Unknown");
#endif
m_stats[QStringLiteral("current.os")] = os;
QRect scr = QGuiApplication::primaryScreen()->geometry();
m_stats[QStringLiteral("current.screen")] = QString(SKGServices::intToString(scr.width()) % 'x' % SKGServices::intToString(scr.height()));
#ifdef HAVE_UNAME
struct utsname buf {};
if (uname(&buf) != -1) {
m_stats[QStringLiteral("current.os.machine")] = QString::fromLocal8Bit(buf.machine);
m_stats[QStringLiteral("current.os.version")] = QString::fromLocal8Bit(buf.version);
}
#endif
// Nb calls
QMap<QString, QPointer<QAction> > actions = SKGMainPanel::getMainPanel()->getGlobalActions();
QStringList keys = actions.keys();
for (const auto& k : qAsConst(keys)) {
QPointer<QAction> act = actions[k];
if (act != nullptr) {
QString id = "nb_call." % act->objectName();
if (!m_stats.contains(id)) {
m_stats[id] = 0;
}
}
}
m_stats[QStringLiteral("document.uuid")] = docUUID;
// Set tables sizes
QStringList tables;
m_currentDocument->getTablesList(tables);
for (const auto& t : qAsConst(tables)) {
QString r;
m_currentDocument->executeSingleSelectSqliteOrder("SELECT COUNT(1) FROM " % t, r);
m_stats["count." % t] = SKGServices::stringToInt(r);
}
}
}
}
}
void SKGStatisticPlugin::readStats()
{
m_stats.clear();
// Read file
QFile data(m_file);
if (data.open(QFile::ReadOnly)) {
// Parse json
m_stats = QJsonDocument::fromJson(data.readAll()).toVariant().toMap();
data.close();
}
}
void SKGStatisticPlugin::writeStats()
{
// Write it in file
QFile data(m_file);
if (data.open(QFile::WriteOnly | QFile::Truncate)) {
// serialize json
QJsonDocument serializer = QJsonDocument::fromVariant(m_stats);
QByteArray doc = serializer.toJson(QJsonDocument::Indented);
data.write(doc);
data.close();
}
}
void SKGStatisticPlugin::triggerAction()
{
SKGTRACEINFUNC(10)
auto* act = qobject_cast< QAction* >(sender());
if (act != nullptr) {
QString id = "nb_call." % act->objectName();
SKGTRACEL(10) << "SKGStatisticPlugin::triggerAction " << id << "++" << endl;
m_stats[id] = m_stats[id].toInt() + 1;
}
}
void SKGStatisticPlugin::pageChanged()
{
SKGTabPage::SKGPageHistoryItem currentPage = SKGMainPanel::getMainPanel()->currentPageHistoryItem();
if (!currentPage.plugin.isEmpty()) {
QString id = "nb_activated_" % QString(currentPage.bookmarkID.isEmpty() ? QStringLiteral("page") : QStringLiteral("bookmark")) % "." % currentPage.plugin;
m_stats[id] = m_stats[id].toInt() + 1;
}
}
void SKGStatisticPlugin::pageOpened()
{
SKGTabPage::SKGPageHistoryItem currentPage = SKGMainPanel::getMainPanel()->currentPageHistoryItem();
if (!currentPage.plugin.isEmpty()) {
QString id = "nb_opened_" % QString(currentPage.bookmarkID.isEmpty() ? QStringLiteral("page") : QStringLiteral("bookmark")) % "." % currentPage.plugin;
m_stats[id] = m_stats[id].toInt() + 1;
}
}
QString SKGStatisticPlugin::title() const
{
return i18nc("The title", "Statistic");
}
QString SKGStatisticPlugin::icon() const
{
return QStringLiteral("dialog-information");
}
QString SKGStatisticPlugin::toolTip() const
{
return title();
}
int SKGStatisticPlugin::getOrder() const
{
return 9999;
}
bool SKGStatisticPlugin::isInPagesChooser() const
{
return false;
}
#include <skgstatisticplugin.moc>
diff --git a/plugins/generic/skg_statistic/skgstatisticplugin.h b/plugins/generic/skg_statistic/skgstatisticplugin.h
index 877b20f89..e15272198 100644
--- a/plugins/generic/skg_statistic/skgstatisticplugin.h
+++ b/plugins/generic/skg_statistic/skgstatisticplugin.h
@@ -1,108 +1,108 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGSTATISTICPLUGIN_H
#define SKGSTATISTICPLUGIN_H
/** @file
* A plugin to generate statistic.
*
* @author Stephane MANKOWSKI
*/
#include "skginterfaceplugin.h"
/**
* A plugin to generate statistic
*/
class SKGStatisticPlugin : public SKGInterfacePlugin
{
Q_OBJECT
Q_INTERFACES(SKGInterfacePlugin)
public:
/**
* Default Constructor
*/
explicit SKGStatisticPlugin(QWidget* iWidget, QObject* iParent, const QVariantList& iArg);
/**
* Default Destructor
*/
~SKGStatisticPlugin() override;
/**
* Called to initialise the plugin
* @param iDocument the main document
* @return true if the plugin is compatible with the document
*/
bool setupActions(SKGDocument* iDocument) override;
/**
* Must be modified to refresh widgets after a modification.
*/
void refresh() override;
/**
* The title of the plugin.
* @return The title of the plugin
*/
QString title() const override;
/**
* The icon of the plugin.
* @return The icon of the plugin
*/
QString icon() const override;
/**
* The toolTip of the plugin.
* @return The toolTip of the plugin
*/
QString toolTip() const override;
/**
* Must be implemented to set the position of the plugin.
* @return integer value between 0 and 999 (default = 999)
*/
int getOrder() const override;
/**
* Must be implemented to know if a plugin must be display in pages chooser.
* @return true of false (default = false)
*/
bool isInPagesChooser() const override;
private Q_SLOTS:
void triggerAction();
void pageChanged();
void pageOpened();
private:
Q_DISABLE_COPY(SKGStatisticPlugin)
void readStats();
void writeStats();
SKGDocument* m_currentDocument;
QVariantMap m_stats;
QString m_file;
QDateTime m_timeInit;
QString m_docUniqueIdentifier;
};
#endif // SKGSTATISTICPLUGIN_H
diff --git a/plugins/generic/skg_undoredo/CMakeLists.txt b/plugins/generic/skg_undoredo/CMakeLists.txt
index b625a3e49..0e973af67 100644
--- a/plugins/generic/skg_undoredo/CMakeLists.txt
+++ b/plugins/generic/skg_undoredo/CMakeLists.txt
@@ -1,36 +1,36 @@
#***************************************************************************
#* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
#* *
#* 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 <http://www.gnu.org/licenses/> *
+#* along with this program. If not, see <https://www.gnu.org/licenses/> *
#***************************************************************************
MESSAGE( STATUS "..:: CMAKE PLUGIN_UNDOREDO ::..")
PROJECT(plugin_undoredo)
LINK_DIRECTORIES (${LIBRARY_OUTPUT_PATH})
SET(skg_undoredo_SRCS skgundoredoplugin.cpp skgundoredoplugindockwidget.cpp)
ki18n_wrap_ui(skg_undoredo_SRCS skgundoredoplugindockwidget_base.ui skgundoredopluginwidget_pref.ui)
kconfig_add_kcfg_files(skg_undoredo_SRCS skgundoredo_settings.kcfgc )
ADD_LIBRARY(skg_undoredo MODULE ${skg_undoredo_SRCS})
TARGET_LINK_LIBRARIES(skg_undoredo KF5::Parts skgbasemodeler skgbasegui)
########### install files ###############
INSTALL(TARGETS skg_undoredo DESTINATION ${KDE_INSTALL_QTPLUGINDIR})
INSTALL(FILES ${PROJECT_SOURCE_DIR}/skgundoredo_settings.kcfg DESTINATION ${KDE_INSTALL_KCFGDIR} )
INSTALL(FILES ${PROJECT_SOURCE_DIR}/org.kde.skg-plugin-undoredo.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR})
INSTALL(FILES ${PROJECT_SOURCE_DIR}/skg_undoredo.rc DESTINATION ${KDE_INSTALL_KXMLGUI5DIR}/skg_undoredo )
diff --git a/plugins/generic/skg_undoredo/org.kde.skg-plugin-undoredo.desktop b/plugins/generic/skg_undoredo/org.kde.skg-plugin-undoredo.desktop
index 5c841d868..ad4f827b2 100644
--- a/plugins/generic/skg_undoredo/org.kde.skg-plugin-undoredo.desktop
+++ b/plugins/generic/skg_undoredo/org.kde.skg-plugin-undoredo.desktop
@@ -1,76 +1,76 @@
[Desktop Entry]
Name=Undo redo plugin
Name[bs]=Poništi ponovi dodatak
Name[ca]=Connector de desfer i refer
Name[ca@valencia]=Connector de desfer i refer
Name[cs]=Modul pro zpět/znovu
Name[da]=Fortryd-/gendan-plugin
Name[de]=Modul für Rückgängig/Wiederherstellen
Name[el]=Undo redo plugin
Name[en_GB]=Undo redo plugin
Name[es]=Complemento para hacer/deshacer
Name[et]=Tagasivõtmise ja uuestitegemise plugin
Name[fi]=Kumoamis- ja uudelleentekemisliitännäinen
Name[fr]=Module externe pour annuler et refaire
Name[gl]=Complemento de desfacer e refacer
Name[hu]=Visszavonás, újra végrehajtás bővítmény
Name[it]=Estensione annulla/rifai
Name[lt]=Atšaukti, pakartoti papildinys
Name[nb]=Angre/gjør om-modul
Name[nds]=Torüchnehmen- un Wedderhalenmoduul
Name[nl]=Plugin voor ongedaan maken/opnieuw doen
Name[pl]=Wtyczka ponów/cofnij
Name[pt]='Plugin' para Desfazer/Refazer
Name[pt_BR]=Plugin de desfazer e refazer
Name[ru]=Модуль отмены и повтора действий
Name[sk]=Plugin Vrátiť naspäť
Name[sv]=Ångrings- och omgörningsinsticksprogram
Name[tr]=Geri alma tekrarlama eklentisi
Name[uk]=Додаток скасування/поновлення дій
Name[x-test]=xxUndo redo pluginxx
Name[zh_TW]=復原與重做外掛程式
Comment=A plugin for undo and redo operations
Comment[bs]=Dodatak za operacije poništi i ponovi
Comment[ca]=Un connector per desfer i refer operacions
Comment[ca@valencia]=Un connector per desfer i refer operacions
Comment[cs]=Modul pro operace typu zpět a znovu
Comment[da]=Et plugin til at fortryde og gendanne operationer
Comment[de]=Ein Modul zum Zurücknehmen und Wiederherstellen von Vorgängen
Comment[el]=Ένα πρόσθετο για λειτουργίες αναίρεσης και επανάληψης
Comment[en_GB]=A plugin for undo and redo operations
Comment[es]=Un complemento para deshacer y rehacer operaciones
Comment[et]=Tagasivõtmise ja uuestitegemise plugin
Comment[fi]=Liitännäinen kumoamis- ja uudelleentekemistoimenpiteille
Comment[fr]=Un module externe pour annuler et refaire
Comment[gl]=Un complemento para desfacer e refacer operacións.
Comment[hu]=Egy bővítmény műveletek visszavonásához és újra végrehajtásához
Comment[it]=Un'estensione per le operazioni di annullamento e rifacimento
Comment[lt]=Papildinys atšaukti, pakartoti operacijas
Comment[nb]=Et programtillegg for angre og gjør om-handlinger
Comment[nds]=En Moduul för't Torüchnehmen un Wedderhalen vun Akschonen
Comment[nl]=Een plugin voor ongedaan maken en opnieuw doen van bewerkingen
Comment[pl]=Wtyczka do operacji cofania i ponawiania
Comment[pt]=Um 'plugin' para as operações de anulação/repetição
Comment[pt_BR]=Um plugin para desfazer e refazer operações
Comment[ru]=Модуль отмены и повтора действий
Comment[sk]=Plugin na operácie Vrátiť a Naspäť
Comment[sv]=Ett insticksprogram för ångra- och gör om-åtgärder
Comment[tr]=İşlemleri geri almak ve tekrarlamak için bir eklenti
Comment[uk]=Додаток для виконання дій зі скасування-поновлення
Comment[x-test]=xxA plugin for undo and redo operationsxx
Comment[zh_TW]=復原與重做用的外掛程式
Encoding=UTF-8
Icon=quickopen
Type=Service
X-KDE-ServiceTypes=SKG GUI/Plugin
X-KDE-Library=skg_undoredo
X-Krunner-ID=Undo redo plugin
X-KDE-PluginInfo-Author=Stephane MANKOWSKI,miraks
X-KDE-PluginInfo-Email=stephane@mankowski.fr
X-KDE-PluginInfo-Name=skg_undoredo
X-KDE-PluginInfo-Version=1.0
-X-KDE-PluginInfo-Website=http://skrooge.org/
+X-KDE-PluginInfo-Website=https://skrooge.org/
X-KDE-PluginInfo-Category=Plugins
X-KDE-PluginInfo-Depends=
X-KDE-PluginInfo-License=GPL
X-KDE-PluginInfo-EnabledByDefault=true
diff --git a/plugins/generic/skg_undoredo/skgundoredoplugin.cpp b/plugins/generic/skg_undoredo/skgundoredoplugin.cpp
index c16808178..930f692bd 100644
--- a/plugins/generic/skg_undoredo/skgundoredoplugin.cpp
+++ b/plugins/generic/skg_undoredo/skgundoredoplugin.cpp
@@ -1,402 +1,402 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is a plugin for undo and redo operation.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgundoredoplugin.h"
#include <qwidget.h>
#include <kaboutdata.h>
#include <kactioncollection.h>
#include <kpluginfactory.h>
#include <kstandardaction.h>
#include <ktoolbarpopupaction.h>
#include "skgerror.h"
#include "skgmainpanel.h"
#include "skgservices.h"
#include "skgtraces.h"
#include "skgundoredo_settings.h"
#include "skgundoredoplugindockwidget.h"
/**
* This plugin factory.
*/
K_PLUGIN_FACTORY(SKGUndoRedoPluginFactory, registerPlugin<SKGUndoRedoPlugin>();)
SKGUndoRedoPlugin::SKGUndoRedoPlugin(QWidget* iWidget, QObject* iParent, const QVariantList& /*iArg*/) :
SKGInterfacePlugin(iParent),
m_undoSaveAction(nullptr), m_undoAction(nullptr), m_redoAction(nullptr), m_undoMenu(nullptr), m_redoMenu(nullptr), m_currentDocument(nullptr), m_dockWidget(nullptr)
{
Q_UNUSED(iWidget)
SKGTRACEINFUNC(10)
}
SKGUndoRedoPlugin::~SKGUndoRedoPlugin()
{
SKGTRACEINFUNC(10)
m_currentDocument = nullptr;
m_dockWidget = nullptr;
m_undoSaveAction = nullptr;
m_undoAction = nullptr;
m_redoAction = nullptr;
m_undoMenu = nullptr;
m_redoMenu = nullptr;
}
bool SKGUndoRedoPlugin::setupActions(SKGDocument* iDocument)
{
SKGTRACEINFUNC(10)
m_currentDocument = iDocument;
setComponentName(QStringLiteral("skg_undoredo"), title());
setXMLFile(QStringLiteral("skg_undoredo.rc"));
// Menu
m_undoSaveAction = new QAction(SKGServices::fromTheme(QStringLiteral("document-revert")), i18nc("Verb, action to cancel previous action", "Revert document"), this);
connect(m_undoSaveAction, &QAction::triggered, this, &SKGUndoRedoPlugin::onUndoSave);
actionCollection()->setDefaultShortcut(m_undoSaveAction, Qt::CTRL + Qt::ALT + Qt::Key_Z);
registerGlobalAction(QStringLiteral("edit_undolastsave"), m_undoSaveAction);
m_undoAction = new KToolBarPopupAction(SKGServices::fromTheme(QStringLiteral("edit-undo")), i18nc("Verb, action to cancel previous action", "Undo"), this);
connect(m_undoAction, &KToolBarPopupAction::triggered, this, &SKGUndoRedoPlugin::onUndo);
actionCollection()->setDefaultShortcut(m_undoAction, Qt::CTRL + Qt::Key_Z);
m_undoAction->setPriority(QAction::LowPriority);
m_undoMenu = m_undoAction->menu();
connect(m_undoMenu, &QMenu::aboutToShow, this, &SKGUndoRedoPlugin::onShowUndoMenu);
m_undoAction->setStickyMenu(false);
m_undoAction->setData(1);
registerGlobalAction(QStringLiteral("edit_undo"), m_undoAction);
m_redoAction = new KToolBarPopupAction(SKGServices::fromTheme(QStringLiteral("edit-redo")), i18nc("Verb, action to redo previous cancelled action", "Redo"), this);
connect(m_redoAction, &KToolBarPopupAction::triggered, this, &SKGUndoRedoPlugin::onRedo);
actionCollection()->setDefaultShortcut(m_redoAction, Qt::CTRL + Qt::SHIFT + Qt::Key_Z);
m_redoAction->setPriority(QAction::LowPriority);
m_redoMenu = m_redoAction->menu();
connect(m_redoMenu, &QMenu::aboutToShow, this, &SKGUndoRedoPlugin::onShowRedoMenu);
m_redoAction->setStickyMenu(false);
m_redoAction->setData(1);
registerGlobalAction(QStringLiteral("edit_redo"), m_redoAction);
// Menu
auto act = new QAction(SKGServices::fromTheme(QStringLiteral("edit-clear-history")), i18nc("Verb, action to cancel previous action", "Clear history"), this);
connect(act, &QAction::triggered, this, &SKGUndoRedoPlugin::onClearHistory);
registerGlobalAction(QStringLiteral("edit_clear_history"), act);
// Dock creation
m_dockWidget = new QDockWidget(SKGMainPanel::getMainPanel());
m_dockWidget->setObjectName(QStringLiteral("skg_undoredo_docwidget"));
m_dockWidget->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
m_dockWidget->setWindowTitle(title());
// add action to control hide / display of history
QAction* toggle = m_dockWidget->toggleViewAction();
QAction* panelAction = actionCollection()->addAction(QStringLiteral("view_transactions"));
registerGlobalAction(QStringLiteral("view_transactions"), panelAction);
panelAction->setCheckable(true);
panelAction->setChecked(toggle->isChecked());
panelAction->setText(toggle->text());
actionCollection()->setDefaultShortcut(panelAction, Qt::SHIFT + Qt::Key_F11);
connect(panelAction, &QAction::triggered, toggle, &QAction::trigger);
connect(toggle, &QAction::toggled, panelAction, &QAction::setChecked);
return true;
}
void SKGUndoRedoPlugin::refresh()
{
SKGTRACEINFUNC(10)
if (m_dockWidget->widget() == nullptr) {
auto w = new SKGUndoRedoPluginDockWidget(SKGMainPanel::getMainPanel(), m_currentDocument);
connect(w, &SKGUndoRedoPluginDockWidget::selectionChanged, SKGMainPanel::getMainPanel(), &SKGMainPanel::refresh);
m_dockWidget->setWidget(w);
}
if (m_currentDocument != nullptr) {
bool undoPossible = (m_currentDocument->getNbTransaction(SKGDocument::UNDO) > 0);
if (m_undoSaveAction != nullptr) {
m_undoSaveAction->setEnabled(undoPossible);
}
if (m_undoAction != nullptr) {
m_undoAction->setEnabled(undoPossible);
}
if (m_redoAction != nullptr) {
m_redoAction->setEnabled(m_currentDocument->getNbTransaction(SKGDocument::REDO) > 0);
}
// Refresh undo redo
QString name;
m_currentDocument->getTransactionToProcess(SKGDocument::UNDO, &name);
QString message = i18nc("Verb", "Undo operation '%1'.", name);
if (name.isEmpty()) {
message = QLatin1String("");
}
if (m_undoAction != nullptr) {
m_undoAction->setStatusTip(message);
}
m_currentDocument->getTransactionToProcess(SKGDocument::REDO, &name);
message = i18nc("Verb", "Redo operation '%1'.", name);
if (name.isEmpty()) {
message = QLatin1String("");
}
if (m_redoAction != nullptr) {
m_redoAction->setStatusTip(message);
}
}
}
QWidget* SKGUndoRedoPlugin::getPreferenceWidget()
{
SKGTRACEINFUNC(10)
// Read Setting
if (m_currentDocument != nullptr) {
KSharedConfigPtr config = KSharedConfig::openConfig();
KConfigGroup pref = config->group("skg_undoredo");
pref.writeEntry("maxNumberOfUndo", SKGServices::stringToInt(m_currentDocument->getParameter(QStringLiteral("SKG_UNDO_MAX_DEPTH"))));
pref.writeEntry("cleanHistoryOnSave", (m_currentDocument->getParameter(QStringLiteral("SKG_UNDO_CLEAN_AFTER_SAVE")) == QStringLiteral("Y")));
}
// Create widget
auto w = new QWidget();
ui.setupUi(w);
return w;
}
KConfigSkeleton* SKGUndoRedoPlugin::getPreferenceSkeleton()
{
return skgundoredo_settings::self();
}
SKGError SKGUndoRedoPlugin::savePreferences() const
{
SKGError err;
if (m_currentDocument != nullptr) {
// Read Setting
QString max = SKGServices::intToString(skgundoredo_settings::maxNumberOfUndo());
QString clean = (skgundoredo_settings::cleanHistoryOnSave() ? QStringLiteral("Y") : QStringLiteral("N"));
// Save setting in document
if (max != m_currentDocument->getParameter(QStringLiteral("SKG_UNDO_MAX_DEPTH"))) {
err = m_currentDocument->setParameter(QStringLiteral("SKG_UNDO_MAX_DEPTH"), max);
}
if (clean != m_currentDocument->getParameter(QStringLiteral("SKG_UNDO_CLEAN_AFTER_SAVE"))) {
err = m_currentDocument->setParameter(QStringLiteral("SKG_UNDO_CLEAN_AFTER_SAVE"), clean);
}
}
return err;
}
QString SKGUndoRedoPlugin::title() const
{
return i18nc("Noun", "History");
}
QString SKGUndoRedoPlugin::icon() const
{
return QStringLiteral("edit-undo");
}
QString SKGUndoRedoPlugin::toolTip() const
{
return i18nc("Noun", "History");
}
QStringList SKGUndoRedoPlugin::tips() const
{
QStringList output;
output.push_back(i18nc("Description of a tips", "<p>... you can undo and redo your modifications.</p>"));
output.push_back(i18nc("Description of a tips", "<p>... you can modify the maximum size of the undo/redo stack in the <a href=\"skg://tab_configure?page=Undo redo plugin\">settings</a>.</p>"));
return output;
}
int SKGUndoRedoPlugin::getOrder() const
{
return 4;
}
SKGAdviceList SKGUndoRedoPlugin::advice(const QStringList& iIgnoredAdvice)
{
SKGTRACEINFUNC(10)
SKGAdviceList output;
if (!iIgnoredAdvice.contains(QStringLiteral("skgundoredoplugin_too_big"))) {
// Get nb transaction
int nbObject = m_currentDocument->getNbTransaction();
int priority = qMin(10, nbObject / 50);
if (priority > 0) {
SKGAdvice ad;
ad.setUUID(QStringLiteral("skgundoredoplugin_too_big"));
ad.setPriority(priority);
ad.setShortMessage(i18nc("Advice on making the best (short)", "History is too large"));
ad.setLongMessage(i18nc("Advice on making the best (long)", "You can improve performances by reducing your history size in settings."));
QStringList autoCorrections;
autoCorrections.push_back(QStringLiteral("skg://edit_clear_history"));
autoCorrections.push_back(i18nc("Advice on making the best (action)", "Open settings panel"));
ad.setAutoCorrections(autoCorrections);
output.push_back(ad);
}
}
return output;
}
SKGError SKGUndoRedoPlugin::executeAdviceCorrection(const QString& iAdviceIdentifier, int iSolution)
{
SKGError err;
if ((m_currentDocument != nullptr) && iAdviceIdentifier == QStringLiteral("skgundoredoplugin_too_big")) {
SKGMainPanel::getMainPanel()->optionsPreferences(this->objectName());
return err;
}
return SKGInterfacePlugin::executeAdviceCorrection(iAdviceIdentifier, iSolution);
}
void SKGUndoRedoPlugin::onClearHistory()
{
SKGError err;
SKGTRACEINFUNCRC(10, err)
if ((m_currentDocument != nullptr) && (SKGMainPanel::getMainPanel() != nullptr)) {
QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
err = m_currentDocument->removeAllTransactions();
QApplication::restoreOverrideCursor();
// status bar
IFOKDO(err, SKGError(0, i18nc("Message for successful user action", "Clear history successfully done.")))
else {
err.addError(ERR_FAIL, i18nc("Error message", "Clear history failed"));
}
// Display error
SKGMainPanel::displayErrorMessage(err);
}
}
void SKGUndoRedoPlugin::onUndoSave()
{
SKGError err;
SKGTRACEINFUNCRC(10, err)
if ((m_currentDocument != nullptr) && (SKGMainPanel::getMainPanel() != nullptr)) {
QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
err = m_currentDocument->undoRedoTransaction(SKGDocument::UNDOLASTSAVE);
QApplication::restoreOverrideCursor();
// status bar
IFOKDO(err, SKGError(0, i18nc("Successful message after an user action", "Undo successfully done.")))
else {
err.addError(ERR_FAIL, i18nc("Error message", "Undo failed"));
}
// Display error
SKGMainPanel::displayErrorMessage(err);
}
}
void SKGUndoRedoPlugin::onUndo()
{
SKGError err;
SKGTRACEINFUNCRC(10, err)
if ((m_currentDocument != nullptr) && (SKGMainPanel::getMainPanel() != nullptr)) {
QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
int pos = qobject_cast<QAction*>(sender())->data().toInt();
for (int i = 1 ; !err && i <= pos; ++i) {
err = m_currentDocument->undoRedoTransaction(SKGDocument::UNDO);
}
QApplication::restoreOverrideCursor();
// status bar
IFOKDO(err, SKGError(0, i18nc("Successful message after an user action", "Undo successfully done.")))
else {
err.addError(ERR_FAIL, i18nc("Error message", "Undo failed"));
}
// Display error
SKGMainPanel::displayErrorMessage(err);
}
}
void SKGUndoRedoPlugin::onShowUndoMenu()
{
if ((m_undoMenu != nullptr) && (m_currentDocument != nullptr)) {
m_undoMenu->clear();
SKGStringListList listTmp;
m_currentDocument->executeSelectSqliteOrder(
QStringLiteral("SELECT t_name, t_savestep FROM doctransaction WHERE t_mode='U' ORDER BY d_date DESC LIMIT 7"),
listTmp);
int nb = listTmp.count();
for (int i = 1; i < nb; ++i) {
QAction* act = m_undoMenu->addAction(listTmp.at(i).at(1) == QStringLiteral("Y") ? SKGServices::fromTheme(QStringLiteral("document-revert")) : SKGServices::fromTheme(QStringLiteral("edit-undo")), listTmp.at(i).at(0));
if (act != nullptr) {
act->setData(i);
connect(act, &QAction::triggered, this, &SKGUndoRedoPlugin::onUndo);
}
}
}
}
void SKGUndoRedoPlugin::onRedo()
{
SKGError err;
SKGTRACEINFUNCRC(10, err)
if ((m_currentDocument != nullptr) && (SKGMainPanel::getMainPanel() != nullptr)) {
QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
int pos = qobject_cast<QAction*>(sender())->data().toInt();
for (int i = 1 ; !err && i <= pos; ++i) {
err = m_currentDocument->undoRedoTransaction(SKGDocument::REDO);
}
QApplication::restoreOverrideCursor();
// status bar
IFOKDO(err, SKGError(0, i18nc("Successful message after an user action", "Redo successfully done.")))
else {
err.addError(ERR_FAIL, i18nc("Error message", "Redo failed"));
}
// Display error
SKGMainPanel::displayErrorMessage(err);
}
}
void SKGUndoRedoPlugin::onShowRedoMenu()
{
if ((m_redoMenu != nullptr) && (m_currentDocument != nullptr)) {
m_redoMenu->clear();
SKGStringListList listTmp;
m_currentDocument->executeSelectSqliteOrder(
QStringLiteral("SELECT t_name FROM doctransaction WHERE t_mode='R' ORDER BY d_date ASC LIMIT 7"),
listTmp);
int nb = listTmp.count();
for (int i = 1; i < nb; ++i) {
QAction* act = m_redoMenu->addAction(SKGServices::fromTheme(QStringLiteral("edit-redo")), listTmp.at(i).at(0));
if (act != nullptr) {
act->setData(i);
connect(act, &QAction::triggered, this, &SKGUndoRedoPlugin::onRedo);
}
}
}
}
QDockWidget* SKGUndoRedoPlugin::getDockWidget()
{
return m_dockWidget;
}
#include <skgundoredoplugin.moc>
diff --git a/plugins/generic/skg_undoredo/skgundoredoplugin.h b/plugins/generic/skg_undoredo/skgundoredoplugin.h
index 0be42284a..84d420561 100644
--- a/plugins/generic/skg_undoredo/skgundoredoplugin.h
+++ b/plugins/generic/skg_undoredo/skgundoredoplugin.h
@@ -1,158 +1,158 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGUNDOREDOPLUGIN_H
#define SKGUNDOREDOPLUGIN_H
/** @file
* This file is a plugin for undo and redo operation.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skginterfaceplugin.h"
#include "ui_skgundoredopluginwidget_pref.h"
class QAction;
class KToolBarPopupAction;
class QMenu;
/**
* This file is a plugin for undo and redo operation
*/
class SKGUndoRedoPlugin : public SKGInterfacePlugin
{
Q_OBJECT
Q_INTERFACES(SKGInterfacePlugin)
public:
/**
* Default Constructor
*/
explicit SKGUndoRedoPlugin(QWidget* iWidget, QObject* iParent, const QVariantList& iArg);
/**
* Default Destructor
*/
~SKGUndoRedoPlugin() override;
/**
* Called to initialise the plugin
* @param iDocument the main document
* @return true if the plugin is compatible with the document
*/
bool setupActions(SKGDocument* iDocument) override;
/**
* Must be modified to refresh widgets after a modification.
*/
void refresh() override;
/**
* The preference widget of the plugin.
* @return The preference widget of the plugin
*/
QWidget* getPreferenceWidget() override;
/**
* The preference skeleton of the plugin.
* @return The preference skeleton of the plugin
*/
KConfigSkeleton* getPreferenceSkeleton() override;
/**
* This function is called when preferences have been modified. Must be used to save some parameters into the document.
* A transaction is already opened
* @return an object managing the error.
* @see SKGError
*/
SKGError savePreferences() const override;
/**
* The title of the plugin.
* @return The title of the plugin
*/
QString title() const override;
/**
* The icon of the plugin.
* @return The icon of the plugin
*/
QString icon() const override;
/**
* The toolTip of the plugin.
* @return The toolTip of the plugin
*/
QString toolTip() const override;
/**
* The tips list of the plugin.
* @return The tips list of the plugin
*/
QStringList tips() const override;
/**
* Must be implemented to set the position of the plugin.
* @return integer value between 0 and 999 (default = 999)
*/
int getOrder() const override;
/**
* The dock widget of the plugin.
* @return The dock widget of the plugin
*/
QDockWidget* getDockWidget() override;
/**
* The advice list of the plugin.
* @return The advice list of the plugin
*/
SKGAdviceList advice(const QStringList& iIgnoredAdvice) override;
/**
* Must be implemented to execute the automatic correction for the advice.
* @param iAdviceIdentifier the identifier of the advice
* @param iSolution the identifier of the possible solution
* @return an object managing the error. MUST return ERR_NOTIMPL if iAdviceIdentifier is not known
* @see SKGError
*/
SKGError executeAdviceCorrection(const QString& iAdviceIdentifier, int iSolution) override;
private Q_SLOTS:
void onUndoSave();
void onUndo();
void onRedo();
void onClearHistory();
void onShowUndoMenu();
void onShowRedoMenu();
private:
Q_DISABLE_COPY(SKGUndoRedoPlugin)
QAction* m_undoSaveAction;
KToolBarPopupAction* m_undoAction;
KToolBarPopupAction* m_redoAction;
QMenu* m_undoMenu;
QMenu* m_redoMenu;
SKGDocument* m_currentDocument;
QDockWidget* m_dockWidget;
Ui::skgundoredoplugin_pref ui{};
};
#endif // SKGDEBUGPLUGIN_H
diff --git a/plugins/generic/skg_undoredo/skgundoredoplugindockwidget.cpp b/plugins/generic/skg_undoredo/skgundoredoplugindockwidget.cpp
index 5ed207d96..f860de7b2 100644
--- a/plugins/generic/skg_undoredo/skgundoredoplugindockwidget.cpp
+++ b/plugins/generic/skg_undoredo/skgundoredoplugindockwidget.cpp
@@ -1,120 +1,120 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is a plugin for undoredo management.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgundoredoplugindockwidget.h"
#include <qheaderview.h>
#include "skgdocument.h"
#include "skgmainpanel.h"
#include "skgobjectmodelbase.h"
#include "skgtraces.h"
SKGUndoRedoPluginDockWidget::SKGUndoRedoPluginDockWidget(QWidget* iParent, SKGDocument* iDocument)
: SKGWidget(iParent, iDocument)
{
SKGTRACEINFUNC(1)
if (iDocument == nullptr) {
return;
}
ui.setupUi(this);
QPalette newPalette = QApplication::palette();
newPalette.setColor(QPalette::Base, Qt::transparent);
ui.kTransactionList->setPalette(newPalette);
auto modelview = new SKGObjectModelBase(getDocument(), QStringLiteral("doctransaction"), QStringLiteral("1=1 ORDER BY d_date DESC, id DESC"), this);
ui.kTransactionList->setModel(modelview);
ui.kTransactionList->header()->hide();
QAction* act = SKGMainPanel::getMainPanel()->getGlobalAction(QStringLiteral("edit_clear_history"));
if (act != nullptr) {
ui.kClearHistoryBtn->setIcon(act->icon());
connect(ui.kClearHistoryBtn, &QPushButton::clicked, act, &QAction::trigger);
}
ui.kTransactionList->setDefaultSaveParameters(getDocument(), QStringLiteral("SKG_DEFAULT_UNDOREDO"));
connect(ui.kTransactionList, &SKGTableView::doubleClicked, this, &SKGUndoRedoPluginDockWidget::onUndoRedo);
connect(ui.kTransactionList, &SKGTableView::selectionChangedDelayed, this, &SKGUndoRedoPluginDockWidget::selectionChanged);
connect(getDocument(), &SKGDocument::transactionSuccessfullyEnded, ui.kTransactionList, &SKGTableView::resizeColumnsToContentsDelayed, Qt::QueuedConnection);
ui.kTransactionList->setTextResizable(false);
}
SKGUndoRedoPluginDockWidget::~SKGUndoRedoPluginDockWidget()
{
SKGTRACEINFUNC(1)
}
QWidget* SKGUndoRedoPluginDockWidget::mainWidget()
{
return ui.kTransactionList;
}
void SKGUndoRedoPluginDockWidget::onClearHistory()
{
SKGTRACEINFUNC(1)
QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
SKGError err = getDocument()->removeAllTransactions();
QApplication::restoreOverrideCursor();
// status bar
IFOKDO(err, SKGError(0, i18nc("Message for successful user action", "Clear history successfully done.")))
else {
err.addError(ERR_FAIL, i18nc("Error message", "Clear history failed"));
}
// Display error
SKGMainPanel::displayErrorMessage(err);
}
void SKGUndoRedoPluginDockWidget::onUndoRedo(const QModelIndex& index)
{
SKGTRACEINFUNC(1)
QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
// Get Selection
SKGError err;
SKGDocument::UndoRedoMode mode = SKGDocument::UNDO;
auto* model = qobject_cast<SKGObjectModelBase*>(ui.kTransactionList->model());
if (model != nullptr) {
SKGObjectBase obj = model->getObject(index);
int id = obj.getID();
int lastExecuted = -1;
mode = (obj.getAttribute(QStringLiteral("t_mode")) == QStringLiteral("U") ? SKGDocument::UNDO : SKGDocument::REDO);
do {
lastExecuted = getDocument()->getTransactionToProcess(mode);
err = getDocument()->undoRedoTransaction(mode);
} while (!err && lastExecuted != id);
}
QApplication::restoreOverrideCursor();
// status bar
IFOKDO(err, SKGError(0, mode == SKGDocument::UNDO ? i18nc("Message for successful user action", "Undo successfully done.") : i18nc("Message for successful user action", "Redo successfully done.")))
else {
err.addError(ERR_FAIL, mode == SKGDocument::UNDO ? i18nc("Error message", "Undo failed") : i18nc("Error message", "Redo failed"));
}
// Display error
SKGMainPanel::displayErrorMessage(err);
}
diff --git a/plugins/generic/skg_undoredo/skgundoredoplugindockwidget.h b/plugins/generic/skg_undoredo/skgundoredoplugindockwidget.h
index 87ae1023f..656815204 100644
--- a/plugins/generic/skg_undoredo/skgundoredoplugindockwidget.h
+++ b/plugins/generic/skg_undoredo/skgundoredoplugindockwidget.h
@@ -1,63 +1,63 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGUNDOREDOPLUGINDOCKWIDGET_H
#define SKGUNDOREDOPLUGINDOCKWIDGET_H
/** @file
* This file is a undoredo for bank management.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgwidget.h"
#include "ui_skgundoredoplugindockwidget_base.h"
/**
* This file is a plugin for undoredo management
*/
class SKGUndoRedoPluginDockWidget : public SKGWidget
{
Q_OBJECT
public:
/**
* Default Constructor
* @param iParent the parent widget
* @param iDocument the document
*/
explicit SKGUndoRedoPluginDockWidget(QWidget* iParent, SKGDocument* iDocument);
/**
* Default Destructor
*/
~SKGUndoRedoPluginDockWidget() override;
/**
* Get the main widget
* @return a widget
*/
QWidget* mainWidget() override;
private Q_SLOTS:
void onUndoRedo(const QModelIndex& index);
void onClearHistory();
private:
Q_DISABLE_COPY(SKGUndoRedoPluginDockWidget)
Ui::skgundoredoplugindockwidget_base ui{};
};
#endif // SKGUNDOREDOPLUGINDOCKWIDGET_H
diff --git a/plugins/generic/skg_undoredo/skgundoredopluginwidget_pref.ui b/plugins/generic/skg_undoredo/skgundoredopluginwidget_pref.ui
index a1f810970..401f9772c 100644
--- a/plugins/generic/skg_undoredo/skgundoredopluginwidget_pref.ui
+++ b/plugins/generic/skg_undoredo/skgundoredopluginwidget_pref.ui
@@ -1,97 +1,97 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>skgundoredoplugin_pref</class>
<widget class="QWidget" name="skgundoredoplugin_pref">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>421</width>
<height>184</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="spacing">
<number>2</number>
</property>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="spacing">
<number>2</number>
</property>
<item>
<widget class="QLabel" name="label">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Maximum undo depth:</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="kcfg_maxNumberOfUndo">
<property name="toolTip">
- <string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
+ <string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;https://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;The number of undoable actions to keep in the history. If you want to keep &lt;span style=&quot; font-weight:600;&quot;&gt;all&lt;/span&gt; actions in the history, set this to &lt;span style=&quot; font-weight:600;&quot;&gt;-1&lt;/span&gt;, but be warned that the file size will increase steeply.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="statusTip">
<string>-1 for no limit</string>
</property>
<property name="minimum">
<number>-1</number>
</property>
<property name="maximum">
<number>999</number>
</property>
<property name="value">
<number>0</number>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<widget class="QCheckBox" name="kcfg_cleanHistoryOnSave">
<property name="text">
<string>Clean history on save</string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>126</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>
diff --git a/plugins/import/CMakeLists.txt b/plugins/import/CMakeLists.txt
index 0ece9d6d6..efae5e9e2 100644
--- a/plugins/import/CMakeLists.txt
+++ b/plugins/import/CMakeLists.txt
@@ -1,45 +1,45 @@
#***************************************************************************
#* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
#* *
#* 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 <http://www.gnu.org/licenses/> *
+#* along with this program. If not, see <https://www.gnu.org/licenses/> *
#***************************************************************************
#Correction bug 223848 vvvv
#FIND_PACKAGE( LibOfx REQUIRED )
FIND_PACKAGE( LibOfx )
ADD_SUBDIRECTORY(skrooge_import_afb120)
IF(WIN32)
MESSAGE( STATUS " WARNING:Backend module not available on windows")
ELSE(WIN32)
ADD_SUBDIRECTORY(skrooge_import_backend)
ENDIF(WIN32)
ADD_SUBDIRECTORY(skrooge_import_iif)
ADD_SUBDIRECTORY(skrooge_import_qif)
ADD_SUBDIRECTORY(skrooge_import_csv)
ADD_SUBDIRECTORY(skrooge_import_gnc)
ADD_SUBDIRECTORY(skrooge_import_gsb)
ADD_SUBDIRECTORY(skrooge_import_json)
ADD_SUBDIRECTORY(skrooge_import_kmy)
ADD_SUBDIRECTORY(skrooge_import_ledger)
ADD_SUBDIRECTORY(skrooge_import_mmb)
ADD_SUBDIRECTORY(skrooge_import_mny)
ADD_SUBDIRECTORY(skrooge_import_mt940)
IF(LIBOFX_FOUND)
ADD_SUBDIRECTORY(skrooge_import_ofx)
ENDIF(LIBOFX_FOUND)
ADD_SUBDIRECTORY(skrooge_import_pdf)
ADD_SUBDIRECTORY(skrooge_import_skg)
ADD_SUBDIRECTORY(skrooge_import_xhb)
ADD_SUBDIRECTORY(skrooge_import_xml)
diff --git a/plugins/import/skrooge_import_afb120/CMakeLists.txt b/plugins/import/skrooge_import_afb120/CMakeLists.txt
index 007edd821..4bc3a0a81 100644
--- a/plugins/import/skrooge_import_afb120/CMakeLists.txt
+++ b/plugins/import/skrooge_import_afb120/CMakeLists.txt
@@ -1,33 +1,33 @@
#***************************************************************************
#* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
#* *
#* 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 <http://www.gnu.org/licenses/> *
+#* along with this program. If not, see <https://www.gnu.org/licenses/> *
#***************************************************************************
MESSAGE( STATUS "..:: CMAKE PLUGIN_IMPORT_AFB120 ::..")
PROJECT(plugin_import_AFB120)
LINK_DIRECTORIES (${LIBRARY_OUTPUT_PATH})
SET(skrooge_import_afb120_SRCS
skgimportpluginafb120.cpp
)
ADD_LIBRARY(skrooge_import_afb120 MODULE ${skrooge_import_afb120_SRCS})
TARGET_LINK_LIBRARIES(skrooge_import_afb120 KF5::Parts skgbasemodeler skgbasegui skgbankmodeler skgbankgui)
########### install files ###############
INSTALL(TARGETS skrooge_import_afb120 DESTINATION ${KDE_INSTALL_QTPLUGINDIR})
INSTALL(FILES ${PROJECT_SOURCE_DIR}/org.kde.skrooge-import-afb120.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR})
diff --git a/plugins/import/skrooge_import_afb120/org.kde.skrooge-import-afb120.desktop b/plugins/import/skrooge_import_afb120/org.kde.skrooge-import-afb120.desktop
index f3d2b785d..24b52f862 100644
--- a/plugins/import/skrooge_import_afb120/org.kde.skrooge-import-afb120.desktop
+++ b/plugins/import/skrooge_import_afb120/org.kde.skrooge-import-afb120.desktop
@@ -1,63 +1,63 @@
[Desktop Entry]
Name=Skrooge import AFB120 plugin
Name[bs]=Skrooge dodatak za AFB120 uvoz
Name[ca]=Connector d'importació d'AFB120 de l'Skrooge
Name[ca@valencia]=Connector d'importació d'AFB120 de l'Skrooge
Name[cs]=Modul Skrooge pro import AFB120
Name[da]=Plugin til import af AFB120 til Skrooge
Name[de]=Skrooge-AFB120-Importmodul
Name[el]=Skrooge import AFB120 plugin
Name[en_GB]=Skrooge import AFB120 plugin
Name[es]=Complemento de Skrooge de importación de AFB120
Name[fi]=Skroogen AFB120-tuontiliitännäinen
-Name[fr]=Module externe de Skrooge pour l'importation « AFB120 »
+Name[fr]=Module externe de Skrooge pour l'importation « AFB120 »
Name[gl]=Complemento de importación de AFB120 a Skrooge
Name[hu]=Skrooge AFB120 importáló bővítmény
Name[it]=Estensione di Skrooge per l'importazione AFB120
Name[lt]=Skrooge AFB120 importavimo papildinys
Name[nl]=Plugin van Skrooge voor AFB120-importeren
Name[pl]=Wtyczka importu AFB120 dla Skrooge
Name[pt]='Plugin' de importação de AFB120 para o Skrooge
Name[pt_BR]=Plugin de importação de AFB120 para o Skrooge
Name[ru]=Модуль импорта AFB120
Name[sk]=Skrooge plugin AFB120 import
Name[sv]=Skrooge AFB120-importinsticksprogram
Name[tr]=Skrooge AFB120 içe aktarma eklentisi
Name[uk]=Додаток імпортування AFB120 до Skrooge
Name[x-test]=xxSkrooge import AFB120 pluginxx
Name[zh_TW]=Skrooge 匯入 AFB120 外掛程式
Comment=A Skrooge plugin to import AFB120 files
Comment[ca]=Un connector de l'Skrooge per importar fitxers AFB120
Comment[ca@valencia]=Un connector de l'Skrooge per importar fitxers AFB120
Comment[cs]=Modul Skrooge pro import souborů AFB120
Comment[de]=Ein Skrooge-Modul zum Import von AFB120-Dateien
Comment[en_GB]=A Skrooge plugin to import AFB120 files
Comment[es]=Un complemento de Skrooge para importar archivos AFB120
Comment[fi]=Skroogen AFB120-tiedostojen tuontiliitännäinen
-Comment[fr]=Un module externe de Skrooge pour l'importation de fichiers « AFB120 »
+Comment[fr]=Un module externe de Skrooge pour l'importation de fichiers « AFB120 »
Comment[gl]=Un complemento de Skrooge para importar ficheiros AFB120.
Comment[it]=Un'estensione di Skrooge per importare i file AFB120
Comment[nl]=Een Skrooge-plugin voor het importeren van AFB120-bestanden
Comment[pl]=Wtyczka Skrooge do importu plików AFB120
Comment[pt]=Um 'plugin' do Skrooge para importar ficheiros AFB120
Comment[pt_BR]=Um plugin do Skrooge para importar arquivos AFB120
Comment[sk]=Skrooge plugin na import AFB120 súborov
Comment[sv]=Ett insticksprogram till Skrooge för att importera AFB120-filer
Comment[tr]=AFB120 dosyalarını içe aktarmak için bir Skrooge eklentisi
Comment[uk]=Додаток до Skrooge для імпортування даних з файлів AFB120
Comment[x-test]=xxA Skrooge plugin to import AFB120 filesxx
Encoding=UTF-8
Icon=skrooge
Type=Service
X-KDE-ServiceTypes=SKG IMPORT/Plugin
X-KDE-Library=skrooge_import_afb120
X-Krunner-ID=Skrooge import AFB120 plugin
X-KDE-PluginInfo-Author=Stephane MANKOWSKI
X-KDE-PluginInfo-Email=stephane@mankowski.fr
X-KDE-PluginInfo-Name=skrooge_import_afb120
X-KDE-PluginInfo-Version=1.0
-X-KDE-PluginInfo-Website=http://skrooge.org/
+X-KDE-PluginInfo-Website=https://skrooge.org/
X-KDE-PluginInfo-Category=Plugins
X-KDE-PluginInfo-Depends=
X-KDE-PluginInfo-License=GPL
X-KDE-PluginInfo-EnabledByDefault=true
diff --git a/plugins/import/skrooge_import_afb120/skgimportpluginafb120.cpp b/plugins/import/skrooge_import_afb120/skgimportpluginafb120.cpp
index e5f4663ab..efd1b740c 100644
--- a/plugins/import/skrooge_import_afb120/skgimportpluginafb120.cpp
+++ b/plugins/import/skrooge_import_afb120/skgimportpluginafb120.cpp
@@ -1,213 +1,213 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is Skrooge plugin for AFB120 import / export.
* http://jerome.girod.perso.sfr.fr/finance/afb120x.php
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgimportpluginafb120.h"
#include <kpluginfactory.h>
#include <qcryptographichash.h>
#include <qfile.h>
#include <qmath.h>
#include "skgbankincludes.h"
#include "skgimportexportmanager.h"
#include "skgservices.h"
#include "skgtraces.h"
/**
* This plugin factory.
*/
K_PLUGIN_FACTORY(SKGImportPluginAFB120Factory, registerPlugin<SKGImportPluginAFB120>();)
SKGImportPluginAFB120::SKGImportPluginAFB120(QObject* iImporter, const QVariantList& iArg)
: SKGImportPlugin(iImporter)
{
SKGTRACEINFUNC(10)
Q_UNUSED(iArg)
}
SKGImportPluginAFB120::~SKGImportPluginAFB120()
= default;
bool SKGImportPluginAFB120::isImportPossible()
{
SKGTRACEINFUNC(10)
return (m_importer == nullptr ? true : m_importer->getFileNameExtension() == QStringLiteral("AFB120") || m_importer->getFileNameExtension() == QStringLiteral("CFO"));
}
double SKGImportPluginAFB120::toAmount(const QString& iAmount, int iNbDecimal)
{
QString amount = iAmount;
QChar lastChar = amount.right(1).at(0);
int codeAscii = lastChar.toLatin1();
int sign = (codeAscii > 79 && codeAscii != 123 ? -1 : 1);
if (codeAscii == 123 || codeAscii == 125) {
amount[amount.count() - 1] = '0';
} else {
bool ok = false;
amount[amount.count() - 1] = QChar(codeAscii + QChar('1').toLatin1() - QString(sign == -1 ? QStringLiteral("0x4A") : QStringLiteral("0x41")).toUInt(&ok, 16));
}
return static_cast<double>(sign) * SKGServices::stringToDouble(amount) / qPow(10, iNbDecimal);
}
SKGError SKGImportPluginAFB120::importFile()
{
if (m_importer == nullptr) {
return SKGError(ERR_ABORT, i18nc("Error message", "Invalid parameters"));
}
SKGError err;
SKGTRACEINFUNCRC(2, err)
// Begin transaction
err = m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Import step", "Import %1 file", "AFB120"), 2);
IFOK(err) {
// Open file
IFOK(err) {
QFile file(m_importer->getLocalFileName());
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
err.setReturnCode(ERR_INVALIDARG).setMessage(i18nc("Error message", "Open file '%1' failed", m_importer->getFileName().toDisplayString()));
} else {
// Read lines
QStringList lines;
{
QTextStream stream(&file);
if (!m_importer->getCodec().isEmpty()) {
stream.setCodec(m_importer->getCodec().toLatin1().constData());
}
while (!stream.atEnd()) {
// Read line
QString line = stream.readLine().trimmed();
if (!line.isEmpty()) {
lines.push_back(line);
}
}
}
// close file
file.close();
// Step 1 done
IFOKDO(err, m_importer->getDocument()->stepForward(1))
// Read lines
SKGAccountObject account;
SKGUnitObject unit;
QString bankName = QStringLiteral("AFB120");
QString inititalAmount;
int nb = lines.count();
IFOKDO(err, m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Import step", "Import operations"), nb))
for (int i = 0; i < nb && !err; ++i) {
// Read line
const QString& line = lines.at(i);
if (!line.isEmpty()) {
if (line.startsWith(QLatin1String("01"))) {
// Previous balance
QString accountNumber = line.mid(22 - 1, 11);
inititalAmount = line.mid(91 - 1, 14);
SKGObjectBase::SKGListSKGObjectBase listAccount;
err = m_importer->getDocument()->getObjects(QStringLiteral("v_account"), "t_number='" % accountNumber % '\'', listAccount);
IFOK(err) {
if (listAccount.count() == 1) {
// Yes ! Only one account found
account = listAccount.at(0);
err = m_importer->getDocument()->sendMessage(i18nc("An information message", "Using account '%1' for import", account.getName()));
} else {
if (listAccount.count() > 1) {
err = m_importer->getDocument()->sendMessage(i18nc("An information message", "More than one possible account found."));
}
SKGBankObject bank(m_importer->getDocument());
IFOKDO(err, bank.setName(bankName))
IFOKDO(err, bank.setNumber(bankName))
if (!err && bank.load().isFailed()) {
err = bank.save();
}
IFOKDO(err, bank.addAccount(account))
IFOKDO(err, account.setName(accountNumber))
IFOKDO(err, account.setNumber(accountNumber))
IFOKDO(err, account.setType(SKGAccountObject::CURRENT))
if (!err && account.load().isFailed()) {
err = account.save();
}
IFOKDO(err, m_importer->getDocument()->sendMessage(i18nc("An information message", "Default account '%1' created for import", accountNumber)))
}
}
} else if (line.startsWith(QLatin1String("04"))) {
// Operation
QString unitCode = line.mid(17 - 1, 3);
QString nbDecimal = line.mid(20 - 1, 1);
// QString codeMode = line.mid(33 - 1, 2);
QString dateJJMMAA = line.mid(35 - 1, 6);
QString comment = line.mid(49 - 1, 31).trimmed();
QString amount = line.mid(91 - 1, 14);
// Initialize balance
if (unit.getID() == 0) {
err = SKGUnitObject::createCurrencyUnit(m_importer->getDocument(), unitCode, unit);
if (account.getNbOperation() > 1) {
IFOKDO(err, m_importer->getDocument()->sendMessage(i18nc("An information message", "The initial balance of '%1' has not been set because some operations are already existing", account.getName()), SKGDocument::Warning))
} else {
// Set initial balance
IFOKDO(err, account.setInitialBalance(toAmount(inititalAmount, SKGServices::stringToInt(nbDecimal)), unit))
IFOKDO(err, account.save())
IFOKDO(err, m_importer->getDocument()->sendMessage(i18nc("An information message", "The initial balance of '%1' has been set with AFB120 file content", account.getName())))
}
}
SKGOperationObject operation;
IFOKDO(err, account.addOperation(operation, true))
IFOKDO(err, operation.setDate(SKGServices::stringToTime(SKGServices::dateToSqlString(dateJJMMAA, QStringLiteral("DDMMYYYY"))).date()))
IFOKDO(err, operation.setUnit(unit))
IFOKDO(err, operation.setAttribute(QStringLiteral("t_imported"), QStringLiteral("T")))
IFOKDO(err, operation.setComment(comment))
QByteArray hash = QCryptographicHash::hash(line.toUtf8(), QCryptographicHash::Md5);
IFOKDO(err, operation.setImportID(QStringLiteral("AFB120-") % hash.toHex()))
IFOKDO(err, operation.save(false))
SKGSubOperationObject subop;
IFOKDO(err, operation.addSubOperation(subop))
IFOKDO(err, subop.setComment(comment))
IFOKDO(err, subop.setQuantity(toAmount(amount, SKGServices::stringToInt(nbDecimal))))
IFOKDO(err, subop.save(false, false))
}
}
IFOKDO(err, m_importer->getDocument()->stepForward(i + 1))
}
SKGENDTRANSACTION(m_importer->getDocument(), err)
// Step 2 done
IFOKDO(err, m_importer->getDocument()->stepForward(2))
}
}
}
SKGENDTRANSACTION(m_importer->getDocument(), err)
return err;
}
QString SKGImportPluginAFB120::getMimeTypeFilter() const
{
return "*.afb120 *.cfo|" % i18nc("A file format", "AFB120 file (cfomb)");
}
#include <skgimportpluginafb120.moc>
diff --git a/plugins/import/skrooge_import_afb120/skgimportpluginafb120.h b/plugins/import/skrooge_import_afb120/skgimportpluginafb120.h
index 172dde73c..ec9414780 100644
--- a/plugins/import/skrooge_import_afb120/skgimportpluginafb120.h
+++ b/plugins/import/skrooge_import_afb120/skgimportpluginafb120.h
@@ -1,72 +1,72 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGIMPORTPLUGINAFB120_H
#define SKGIMPORTPLUGINAFB120_H
/** @file
* This file is Skrooge plugin for AFB120 import / export.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgimportplugin.h"
/**
* This file is Skrooge plugin for AFB120 import / export.
*/
class SKGImportPluginAFB120 : public SKGImportPlugin
{
Q_OBJECT
Q_INTERFACES(SKGImportPlugin)
public:
/**
* Default constructor
* @param iImporter the parent importer
* @param iArg the arguments
*/
explicit SKGImportPluginAFB120(QObject* iImporter, const QVariantList& iArg);
/**
* Default Destructor
*/
~SKGImportPluginAFB120() override;
/**
* To know if import is possible with this plugin
*/
bool isImportPossible() override;
/**
* Import a file
* @return an object managing the error.
* @see SKGError
*/
SKGError importFile() override;
/**
* Return the mime type filter
* @return the mime type filter. Example: "*.csv|CSV file"
*/
QString getMimeTypeFilter() const override;
private:
Q_DISABLE_COPY(SKGImportPluginAFB120)
double toAmount(const QString& iAmount, int iNbDecimal);
};
#endif // SKGIMPORTPLUGINAFB120_H
diff --git a/plugins/import/skrooge_import_backend/CMakeLists.txt b/plugins/import/skrooge_import_backend/CMakeLists.txt
index 0382f474f..597812d0b 100644
--- a/plugins/import/skrooge_import_backend/CMakeLists.txt
+++ b/plugins/import/skrooge_import_backend/CMakeLists.txt
@@ -1,36 +1,36 @@
#***************************************************************************
#* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
#* *
#* 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 <http://www.gnu.org/licenses/> *
+#* along with this program. If not, see <https://www.gnu.org/licenses/> *
#***************************************************************************
MESSAGE( STATUS "..:: CMAKE PLUGIN_IMPORT_BACKEND ::..")
PROJECT(plugin_import_backend)
ADD_SUBDIRECTORY(backends)
LINK_DIRECTORIES (${LIBRARY_OUTPUT_PATH})
SET(skrooge_import_backend_SRCS
skgimportpluginbackend.cpp
)
ADD_LIBRARY(skrooge_import_backend MODULE ${skrooge_import_backend_SRCS})
TARGET_LINK_LIBRARIES(skrooge_import_backend KF5::Parts Qt5::Concurrent skgbasemodeler skgbasegui skgbankmodeler skgbankgui)
########### install files ###############
INSTALL(TARGETS skrooge_import_backend DESTINATION ${KDE_INSTALL_QTPLUGINDIR})
INSTALL(FILES ${PROJECT_SOURCE_DIR}/org.kde.skrooge-import-backend.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR})
INSTALL(FILES ${PROJECT_SOURCE_DIR}/org.kde.skrooge-import-backend-type.desktop DESTINATION ${KDE_INSTALL_KSERVICETYPES5DIR})
INSTALL(PROGRAMS skrooge-sabb.py DESTINATION ${KDE_INSTALL_DATADIR}/skrooge)
diff --git a/plugins/import/skrooge_import_backend/backends/CMakeLists.txt b/plugins/import/skrooge_import_backend/backends/CMakeLists.txt
index b210712b0..daf6c6e2f 100644
--- a/plugins/import/skrooge_import_backend/backends/CMakeLists.txt
+++ b/plugins/import/skrooge_import_backend/backends/CMakeLists.txt
@@ -1,18 +1,18 @@
#***************************************************************************
#* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
#* *
#* 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 <http://www.gnu.org/licenses/> *
+#* along with this program. If not, see <https://www.gnu.org/licenses/> *
#***************************************************************************
INSTALL(DIRECTORY . DESTINATION ${KDE_INSTALL_KSERVICES5DIR} FILES_MATCHING PATTERN "*.desktop")
diff --git a/plugins/import/skrooge_import_backend/backends/org.kde.skrooge-import-backend-aqbanking.desktop b/plugins/import/skrooge_import_backend/backends/org.kde.skrooge-import-backend-aqbanking.desktop
index 6a7ede959..24fa9a877 100644
--- a/plugins/import/skrooge_import_backend/backends/org.kde.skrooge-import-backend-aqbanking.desktop
+++ b/plugins/import/skrooge_import_backend/backends/org.kde.skrooge-import-backend-aqbanking.desktop
@@ -1,52 +1,52 @@
[Desktop Entry]
Name=AqBanking backend
Name[ca]=Dorsal d'AqBanking
Name[ca@valencia]=Dorsal d'AqBanking
Name[cs]=Podpůrná vrstva AqBanking
Name[de]=AqBanking-Modul
Name[en_GB]=AqBanking backend
Name[es]=Motor AqBanking
Name[fi]=AqBanking-taustaosa
Name[fr]=Moteur AqBanking
Name[gl]=Infraestrutura de AqBanking
Name[it]=Motore AqBanking
Name[nl]=AqBanking-backend
Name[pl]=Silnik AqBanking
Name[pt]=Infra-estrutura do AqBanking
Name[pt_BR]=Infraestrutura AqBanking
Name[sv]=AqBanking-gränssnitt
Name[tr]=AqBanking Arka Ucu
Name[uk]=Модуль AqBanking
Name[x-test]=xxAqBanking backendxx
Comment=An import backend for Skrooge using AqBanking.\n You must install AqBanking (aqbanking-cli) and setup all accounts manually before using this backend.\n\nAt least AqBanking version 5.6.10 or later is required.\n\nThis backend starts an AqBanking user-interactive session in the default terminal emulator.\nIf you experience issues please switch to the "xterm" terminal emulator by setting the parameters to:\naqbanking(--terminal-emulator '"xterm -e"') [Note: The single and double quotes are important!]\n\nFor a list of all parameters please run "skrooge-sabb.py bulkdownload --help".
Comment[ca]=Un dorsal d'importació per a l'Skrooge que usa AqBanking.\n Cal instal·lar AqBanking (aqbanking-cli) i configurar manualment tots els comptes abans d'usar aquest dorsal.\n\nEs requereix com a mínim la versió 5.6.10 o superior d'AqBanking.\n\nAquest dorsal inicia una sessió d'usuari interactiva de l'AqBanking a l'emulador de terminal predeterminat.\nSi experimenteu problemes commuteu a l'emulador de terminal «xterm» establint els paràmetres a:\naqbanking(--terminal-emulator '"xterm -e"') [Nota: Les cometes senzilles i les dobles són importants!]\n\nPer a una llista de tots els paràmetres, executeu «skrooge-sabb.py bulkdownload --help».
Comment[ca@valencia]=Un dorsal d'importació per a l'Skrooge que usa AqBanking.\n Cal instal·lar AqBanking (aqbanking-cli) i configurar manualment tots els comptes abans d'usar aquest dorsal.\n\nEs requereix com a mínim la versió 5.6.10 o superior d'AqBanking.\n\nAquest dorsal inicia una sessió d'usuari interactiva de l'AqBanking a l'emulador de terminal predeterminat.\nSi experimenteu problemes commuteu a l'emulador de terminal «xterm» establint els paràmetres a:\naqbanking(--terminal-emulator '"xterm -e"') [Nota: Les cometes senzilles i les dobles són importants!]\n\nPer a una llista de tots els paràmetres, executeu «skrooge-sabb.py bulkdownload --help».
Comment[en_GB]=An import backend for Skrooge using AqBanking.\n You must install AqBanking (aqbanking-cli) and setup all accounts manually before using this backend.\n\nAt least AqBanking version 5.6.10 or later is required.\n\nThis backend starts an AqBanking user-interactive session in the default terminal emulator.\nIf you experience issues please switch to the "xterm" terminal emulator by setting the parameters to:\naqbanking(--terminal-emulator '"xterm -e"') [Note: The single and double quotes are important!]\n\nFor a list of all parameters please run "skrooge-sabb.py bulkdownload --help".
Comment[es]=Un motor de importación para Skrooge que usa AqBanking.\n Debe instalar AqBanking (aqbanking-cli) y configurar todas las cuentas de forma manual antes de usar este motor.\n\nSe necesita al menos la versión 5.6.10 de AqBanking.\n\nEste motor inicia una sesión interactiva de AqBanking en el emulador de terminal por omisión.\nSi experimenta algún problema, use el emulador de terminal «xterm» definiendo los parámetros:\naqbanking(--terminal-emulator '"xterm -e"') [Nota: las comillas sencillas y las dobles son importantes]\n\Para obtener una lista de todos los parámetros, ejecute «skrooge-sabb.py bulkdownload --help».
-Comment[fr]=Un moteur d'importation pour Skrooge utilisant AqBanking\n Vous devez installer AqBanking (aqbanking-cli) et le configurer correctement avant d'utiliser ce moteur.\n\nVous devez installer AqBanking en version 5.6.10 ou ultérieure.\n\nCe moteur démarre une session utilisateur interactive d'AqBanking dans l'émulateur de terminal par défaut.\nSi vous rencontrez le moindre problème, veuillez basculer vers l'émulateur de terminal « xterm » en configurant le paramètre :\naqbanking(--terminal-emulator '"xterm -e"') [Remarque : les guillemets anglais simples et doubles sont importants !]\n\nPour une liste de tous les paramètres, lancez « skrooge-sabb.py bulkdownload --help ».
+Comment[fr]=Un moteur d'importation pour Skrooge utilisant AqBanking\n Vous devez installer AqBanking (aqbanking-cli) et le configurer correctement avant d'utiliser ce moteur.\n\nVous devez installer AqBanking en version 5.6.10 ou ultérieure.\n\nCe moteur démarre une session utilisateur interactive d'AqBanking dans l'émulateur de terminal par défaut.\nSi vous rencontrez le moindre problème, veuillez basculer vers l'émulateur de terminal « xterm » en configurant le paramètre :\naqbanking(--terminal-emulator '"xterm -e"') [Remarque : les guillemets anglais simples et doubles sont importants !]\n\nPour une liste de tous les paramètres, lancez « skrooge-sabb.py bulkdownload --help ».
Comment[gl]=Unha infraestrutura de importación para Skrooge que usa AqBanking.\nDebe instalar AqBanking (aqbanking-cli) e configurar todas as contas manualmente para poder usar esta infraestrutura.\n\nNecesita a versión 5.6.10 de AqBanking ou unha posterior.\n\nEsta infraestrutura inicia unha sesión de AqBanking interactiva co usuario no emulador de terminal predeterminado.\nSe experimenta problemas cambie ao emulador de terminal «xterm» estabelecendo os parámetros como:\naqbanking(--terminal-emulator '"xterm -e"') [Nota: As comiñas simples e dobres son importantes!]
Comment[it]=Un motore di importazione per Skrooge che utilizza AqBanking.\n Prima di usare questo motore devi installare AqBanking (aqbanking-cli) e impostare manualmente i conti.\n\nÈ richiesto AqBanking in versione 5.6.10 o successiva.\n\nQuesto motore avvia una sessione utente interattiva AqBanking nell'emulatore di terminale predefinito.\nSe si verificano problemi, passa all'emulatore di terminale «xterm» impostando i parametri a :\naqbanking(--terminal-emulator '"xterm -e"') [Nota: le virgolette singole e doppie sono importanti]
Comment[nl]=Een backend voor importeren voor Skrooge bij gebruik van AqBanking.\n U moet AqBanking installeren (aqbanking-cli) en alle accounts handmatig instellen alvorens deze backend te gebruiken.\n\nMinstens AqBanking versie 5.6.10 of later is vereist.\n\nDeze backend start een AqBanking gebruikersinteractieve sessie in de standaard terminalemulator.\nAls u problemen tegenkomt schakel dan over naar de "xterm" terminalemulator door de parameters in te stellen naar:\naqbanking(--terminal-emulator '"xterm -e"') [Opmerking: De quotes en aanhalingstekens zijn belangrijk!]\n\nVoor een lijst met alle parameters voer uit "skrooge-sabb.py bulkdownload --help".
Comment[pl]=Silnik importowania dla Skrooge używający AqBanking.\n Musisz wgrać AqBanking (aqbanking-cli), a także ustawić wszystkie konta ręcznie przed dodaniem tego sinika.\n\nWymagana jest wersja 5.6.10 lub późniejsza AqBanking.\n\nTen silnik rozpoczyna interaktywną sesję AqBanking w domyślnym emulatorze terminala.\nJeśli doświadczysz błędów, to przełącz na emulator terminala "xterm" poprzez ustawienie parametrów na:\naqbanking(--terminal-emulator '"xterm -e"') [Uwaga: Pojedyncze i podwójne cudzysłowy mają znaczenie!]\n\nAby wyświetlić listę wszystkich parametrów wykonaj "skrooge-sabb.py bulkdownload --help".
Comment[pt]=Uma infra-estrutura de importação para o Skrooge que usa o AqBanking.\n Deverá instalar o AqBanking ('aqbanking-cli' e 'aqhbci-tool4') e configurar todas as contas manualmente antes de usar esta infra-estrutura.\n\nÉ necessária pelo menos a versão 5.6.10 ou posterior do AqBanking.\n\nEsta infra-estrutura inicia uma sessão interactiva do AqBanking no emulador de terminal predefinido.\nSe tiver alguns problemas, mude por favor para o emulador de terminal "xterm", definindo para tal os parâmetros:\naqbanking(--terminal-emulator '"xterm -e"') [Nota: As plicas e as aspas são importantes!]\n\nPara uma lista de todos os parâmetros, por favor execute "skrooge-sabb.py bulkdownload --help".
Comment[sv]=Ett importgränssnitt för Skrooge som använder AqBanking.\nDu måste installera AqBanking (aqbanking-cli) och ställa in alla konton manuellt innan gränssnittet används.\n\nÅtminstone AqBanking version 5.6.10 eller senare krävs.\n\nGränssnittet startar en användarinteraktiv session av AqBanking i standardterminalemulatorn.\nOm du råkar ut för problem, byt till "xterm" terminalemulator genom att ställa in parametrarna till:\naqbanking(--terminal-emulator '"xterm -e"') [Observera: De enkla och dubbla citationstecknen är viktiga.]
Comment[uk]=Модуль імпортування даних до Skrooge з використанням AqBanking.\n Вам слід встановити AqBanking (aqbanking-cli) і налаштувати усі рахунки вручну до того, як ви зможете скористатися цим модулем.\n\nСлід встановити AqBanking версії 5.6.10 або новішої.\n\nЦей модуль запускає сеанс взаємодії із користувачем AqBanking у типовому емуляторі термінала.\nЯкщо у вас виникають проблеми, будь ласка, перемкніться на емулятор термінала «xterm» встановленням таких параметрів:\naqbanking(--terminal-emulator '"xterm -e"') [Зауваження: використовуйте саме таку комбінацію одинарних і подвійних лапок!]\n\nЩоб ознайомитися зі списком усіх параметрів, будь ласка, віддайте команду «skrooge-sabb.py bulkdownload --help».
Comment[x-test]=xxAn import backend for Skrooge using AqBanking.\n You must install AqBanking (aqbanking-cli) and setup all accounts manually before using this backend.\n\nAt least AqBanking version 5.6.10 or later is required.\n\nThis backend starts an AqBanking user-interactive session in the default terminal emulator.\nIf you experience issues please switch to the "xterm" terminal emulator by setting the parameters to:\naqbanking(--terminal-emulator '"xterm -e"') [Note: The single and double quotes are important!]\n\nFor a list of all parameters please run "skrooge-sabb.py bulkdownload --help".xx
Encoding=UTF-8
Icon=skrooge
Type=Service
X-KDE-ServiceTypes=Skrooge/Import/Backend
X-Krunner-ID=aqbanking
X-KDE-PluginInfo-Author=Bernhard Scheirle
X-KDE-PluginInfo-Email=bernhard@scheirle.de
X-KDE-PluginInfo-Name=aqbanking
X-KDE-PluginInfo-Version=2.0.0
-X-KDE-PluginInfo-Website=http://skrooge.org/
+X-KDE-PluginInfo-Website=https://skrooge.org/
X-KDE-PluginInfo-Category=Plugins
X-KDE-PluginInfo-License=GPL
X-KDE-PluginInfo-EnabledByDefault=true
X-SKROOGE-getaccounts=skrooge-sabb.py listaccounts
X-SKROOGE-getaccountid="(.*)"
X-SKROOGE-getbulk=skrooge-sabb.py bulkdownload --output_folder "%1" %parameter1
X-SKROOGE-csvcolumns=date|mode|comment|payee|amount|unit
diff --git a/plugins/import/skrooge_import_backend/backends/org.kde.skrooge-import-backend-weboob.desktop b/plugins/import/skrooge_import_backend/backends/org.kde.skrooge-import-backend-weboob.desktop
index 2ecdfd598..7ea76d85c 100644
--- a/plugins/import/skrooge_import_backend/backends/org.kde.skrooge-import-backend-weboob.desktop
+++ b/plugins/import/skrooge_import_backend/backends/org.kde.skrooge-import-backend-weboob.desktop
@@ -1,110 +1,110 @@
[Desktop Entry]
Name=Weboob backend
Name[ca]=Dorsal del Weboob
Name[ca@valencia]=Dorsal del Weboob
Name[cs]=Podpůrná vrstva Weboob
Name[de]=Weboob-Modul
Name[en_GB]=Weboob backend
Name[es]=Motor Weboob
Name[fi]=Weboob-taustaosa
Name[fr]=Moteur Weboob
Name[gl]=Infraestrutura de weboob
Name[it]=Motore Weboob
Name[nl]=Weboob-backend
Name[pl]=Silnik Weboob
Name[pt]=Infra-estrutura do Weboob
Name[sv]=Weboob-gränssnitt
Name[tr]=Weboob arka ucu
Name[uk]=Модуль Weboob
Name[x-test]=xxWeboob backendxx
Comment=An import backend for Skrooge using weboob.\n You must install weboob and configure correctly the boobank module before using this backend.\n\n Parameters:\n 1-The list of accounts to import separated by '|'. If you don't pass parameter then all accounts will be imported.\n Example: 123@ca|456@bp\n 2-The first date of imported operations in format YYYY-MM-DD.\n Example: 2017-09-25\nWarning:If you want to specify this parameter, you have to specify the first one too but it could be blank.\n Example: ,2017-09-25
Comment[ca]=Un dorsal d'importació per a l'Skrooge usant Weboob.\n Cal instal·lar el «weboob» i configurar correctament el mòdul «boobank» abans d'usar aquest dorsal.\n\n Paràmetres:\n 1-La llista de comptes a importar, separats «|». Si no es passa el paràmetre, s'importaran tots els comptes.\n Exemple: 123@ca|456@bp\n 2-La primera data de les operacions importades en format AAAA-MM-DD.\n Exemple: 2017-09-25\nAvís: Si voleu indicar aquest paràmetre, també cal indicar el primer, però pot estar en blanc.\n Exemple: ,2017-09-25
Comment[ca@valencia]=Un dorsal d'importació per a l'Skrooge usant Weboob.\n Cal instal·lar el «weboob» i configurar correctament el mòdul «boobank» abans d'usar aquest dorsal.\n\n Paràmetres:\n 1-La llista de comptes a importar, separats «|». Si no es passa el paràmetre, s'importaran tots els comptes.\n Exemple: 123@ca|456@bp\n 2-La primera data de les operacions importades en format AAAA-MM-DD.\n Exemple: 2017-09-25\nAvís: Si voleu indicar aquest paràmetre, també cal indicar el primer, però pot estar en blanc.\n Exemple: ,2017-09-25
Comment[en_GB]=An import backend for Skrooge using weboob.\n You must install weboob and configure correctly the boobank module before using this backend.\n\n Parameters:\n 1-The list of accounts to import separated by '|'. If you don't pass parameter then all accounts will be imported.\n Example: 123@ca|456@bp\n 2-The first date of imported operations in format YYYY-MM-DD.\n Example: 2017-09-25\nWarning:If you want to specify this parameter, you have to specify the first one too but it could be blank.\n Example: ,2017-09-25
Comment[es]=Un motor de importación para Skrooge que usa weboob.\n Debe instalar weboob y configurar correctamente el módulo «boobank» antes de usar este motor.\n\n Parámetros:\n 1 - La lista de cuentas a importar separada por «|». Si no pasa ningún parámetro se importarán todas las cuentas.\n Ejemplo: 123@ca|456@bp\n 2 - La primera fecha de las operaciones a importar en el formato AAAA-MM-DD.\n Ejemplo: 2017-09-25\nAdvertencia: Si usa este parámetro, debe usar también el primero, aunque puede dejarlo en blanco.\nEjemplo: ,2017-07-25
Comment[fi]=Weboopia käyttävä tuontitaustaosa Skroogeen.\nSinun on asennettava weboob ja asetettava boobank-moduuli oikein ennen tämän taustaosan käyttöä.\n\n Parametrit:\n1 – Tuotavien tilien luettelo ”|”-merkein erotettuna. Parametritta tuodaan kaikki tilit.\n Esimerkki: 123@ca|456@bp\n2 – Ensimmäisen tuotavan tapahtuma päivämäärä muodossa VVVV-KK-P.\n Esimerkki: 2017-09-25\nVaroitus: Jos annat tämän parametrin, myös ensimmäinen on annettava, mutta se voi olla tyhjä.\n Esimerkki: ,2017-09-25
-Comment[fr]=Un moteur d'importation pour Skrooge utilisant weboob\n Vous devez installer weboob et configurer correctement le module boobank avant d'utiliser ce moteur.\n\n Paramètres : 1-La liste des comptes à importer séparés par '|'. Si vous ne passez pas de paramètre alors tous les comptes seront importés.\n Exemple: 123@ca|456@bp\n 2-La première date d'importation des opérations au format YYYY-MM-DD.\n Exemple: 2017-09-25\nAttention : Si vous voulez préciser ce paramètre, vous devez d'abord préciser le premier mais il peut être vide.\n Exemple: ,2017-09-25
+Comment[fr]=Un moteur d'importation pour Skrooge utilisant weboob\n Vous devez installer weboob et configurer correctement le module boobank avant d'utiliser ce moteur.\n\n Paramètres : 1-La liste des comptes à importer séparés par '|'. Si vous ne passez pas de paramètre alors tous les comptes seront importés.\n Exemple: 123@ca|456@bp\n 2-La première date d'importation des opérations au format YYYY-MM-DD.\n Exemple: 2017-09-25\nAttention : Si vous voulez préciser ce paramètre, vous devez d'abord préciser le premier mais il peut être vide.\n Exemple: ,2017-09-25
Comment[gl]=Unha infraestrutura de importación para Skrooge que usa weboob.\nDebe instalar weboob e configurar correctamente o módulo boobank para poder usar esta infraestrutura.\n\n Parámetros:\n 1. A lista de contas para importar separadas por «|». Se non pasa o parámetro, importaranse todas as contas.\nPor exemplo: «123@ca|456@bp».\n 2. A primeira data das operacións importadas en formato AAAA-MM-DD.\n Por exemplo: 2017-09-25\nAviso: Se quere indicar este parámetro, ten que indicar tamén o primeiro, pero pode deixalo baleiro.\n Por exemplo: ,2017-09-25
Comment[it]=Un motore di importazione per Skrooge che utilizza weboob.\n Prima di usare questo motore devi installare weboob e configurare correttamente il modulo boobank.\n\n Parametri:\n l'elenco dei conti da importare separati da «|». Se non passi il parametro verranno importati tutti i conti.\n Esempio: 123@ca|456@bp\n 2-La prima data delle operazioni importate nel formato YYYY-MM-DD.\n Esempio: 2017-09-25\nAttenzione: se vuoi specificare questo parametro, devi specificare anche il primo, ma esso potrebbe risultare vuoto.\n Esempio: ,2017-09-25
Comment[nl]=Een backend voor importeren voor Skrooge met gebruik van weboob.\n U moet weboob installeren en de boobank-module juist configureren vóór deze backend te gebruiken.\n\n Parameters:\n 1-De lijst accounts om apart te importeren gescheiden door '|'. Als u geen parameter meegeeft dan worden alle accounts geïmporteerd.\n Voorbeeld: 123@ca|456@bp\n 2-De eerste datum van geïmporteerde bewerkingen in formaat YYYY-MM-DD.\n Voorbeeld: 2017-09-25\nWaarschuwing:Als u deze parameter wilt specificeren, dan moet u ook de eerste specificeren, maar die kan leeg zijn.\n Voorbeeld: ,2017-09-25
Comment[pl]=Silnik importu dla Skrooge używający weboob.\n Musisz wgrać weboob i ustawić poprawnie moduł boobank przed użyciem tego silnika.\n\n Parametr:\n Lista kont do zaimportowania oddzielonych '|'. Jeśli nie podasz tego parametru, to zostaną zaimportowane wszystkie konta.\n Na przykład: 123@ca|456@bp\n 2-Pierwsza data importowanych operacji zapisana jako RRRR-MM-DD.\n Przykład: 2017-09-25\nUwaga:Jeśli chcesz podać ten parametr, to musisz podać ten pierwszy także, lecz może on pozostać pustym.\n Przykład: ,2017-09-25
Comment[pt]=Uma infra-estrutura de importação para o Skrooge que usa o Weboob.\n Deverá instalar o Weboob e configurar correctamente o módulo 'boobank' antes de usar esta infra-estrutura.\n\n. Parâmetros:\n 1-A lista de contas a importar, separadas por '|'. Se não passar parâmetros, então serão importadas todas as contas.\n Exemplo: 123@ca|456@bp\n 2-A primeira data das operações importadas no formato AAAA-MM-DD. Exemplo: 2017-09-25\nAtenção: Se quiser indicar este parâmetro, também terá de indicar o primeiro, embora este possa estar em branco.\nExemplo: ,2017-09-25
Comment[sv]=Ett importgränssnitt för Skrooge som använder weboob.\nDu måste installera weboob och ställa in modulen boobank korrekt innan gränssnittet används.\n\nParameter:\n1: Listan med konton som ska importeras åtskilda av '|'. Om du inte skickar med parametern importeras alla konton.\nExempel: 123@ca|456@bp\n2: Det första datumet för importerade transaktioner på formatet ÅÅÅÅ-MM-DD.\nExempel: 2017-09-25\nVarning: Om du vill ange parametern måste den första också anges, men den kan vara tom.\nExempel: ,2017-09-25
Comment[uk]=Модуль імпортування даних до Skrooge з використанням weboob.\n Вам слід встановити weboob і налаштувати належним чином модуль boobank, перш ніж користуватися цим модулем обробки.\n\n Параметри:\n 1-список рахунків, дані яких слід імпортувати з відокремленням записів символом «|». Якщо ви не передасте параметр, буде імпортовано дані усіх рахунків.\n Приклад: 123@ca|456@bp\n 2-Перша дата імпортованих операцій у форматі РРРР-ММ-ДД.\n Приклад: 2017-09-25\nПопередження: якщо ви хочете задати цей параметр, вам слід також задати і перший параметр, але він може бути і порожнім.\n Приклад: ,2017-09-25
Comment[x-test]=xxAn import backend for Skrooge using weboob.\n You must install weboob and configure correctly the boobank module before using this backend.\n\n Parameters:\n 1-The list of accounts to import separated by '|'. If you don't pass parameter then all accounts will be imported.\n Example: 123@ca|456@bp\n 2-The first date of imported operations in format YYYY-MM-DD.\n Example: 2017-09-25\nWarning:If you want to specify this parameter, you have to specify the first one too but it could be blank.\n Example: ,2017-09-25xx
Encoding=UTF-8
Icon=skrooge
Type=Service
X-KDE-ServiceTypes=Skrooge/Import/Backend
X-Krunner-ID=weboob
X-KDE-PluginInfo-Author=Stephane MANKOWSKI,miraks
X-KDE-PluginInfo-Email=stephane@mankowski.fr
X-KDE-PluginInfo-Name=weboob
X-KDE-PluginInfo-Version=1.0
-X-KDE-PluginInfo-Website=http://skrooge.org/
+X-KDE-PluginInfo-Website=https://skrooge.org/
X-KDE-PluginInfo-Category=Plugins
X-KDE-PluginInfo-Depends=
X-KDE-PluginInfo-License=GPL
X-KDE-PluginInfo-EnabledByDefault=true
#The command line to get the list of accounts in the standard output, something like this:
#id;balance
#12345@bankname;123.45
#78900@bankname;789.00
#
#The command must provide one line per account. This could be a csv or a text plain file.
#Warning: The first line is ignored
#%3 will be replaced by the password requeted interactively to the en user
#This parameter is MANDATORY
X-SKROOGE-getaccounts=PYTHONIOENCODING=utf_8 boobank ls -q -f csv -s id,label,balance 2>/dev/null |grep -v "If --auto-update" | grep -E "id;label;balance|%parameter1"
#Regular expression to capture the account id of each accounts
#For the regexp syntax, you can consult this page: http://qt-project.org/doc/qt-4.8/qregexp.html
#If the account id is something like aa@bb then aa is the account identifier and bb the bank name.
#This parameter is MANDATORY
X-SKROOGE-getaccountid=([^;]*);
#Regular expression to capture the account balance of each accounts
#The account balance is used only during the first import to compute the initial balance of the account.
#For an existing account with already some operations, this is used to check the account.
#This parameter is not MANDATORY.
X-SKROOGE-getaccountbalance=[^;]*;[^;]*;([^;]*)
#Regular expression to capture the name of account
#This parameter is not MANDATORY.
X-SKROOGE-getaccountname=[^;]*;([^;]*)
#The command line to get the csv operations list.
#Example:
#id;date;rdate;type;raw;category;label;amount
#0@creditcooperatif;2013-04-12;2013-04-12;1;VIREMENT I.P.E.C.A. PREVOYANCE- VIRT IPECA - FRAIS DE SANTE;Not available;I.P.E.C.A. PREVOYANCE;16.80
#0@creditcooperatif;2013-04-12;2013-04-12;1;VIR C.P.A.M. TOULOUSE- 000000 131000017450;Not available;C.P.A.M. TOULOUSE;16.10
#0@creditcooperatif;2013-04-12;2013-04-12;3;CHEQUE NC 1962805;Not available;CHEQUE NC 1962805;-319.00
#
#The command must provide one line per account. This must be csv file.
#
#In the command line:
# %1 will be replaced by the account id [MANDATORY]
# %2 will be replaced by the nb max operations to download [NOT MANDATORY]
# %3 will be replaced by the password) [NOT MANDATORY]
# %4 will be replaced by the begin date (format: YYYY-MM-DD) of operations [NOT MANDATORY]
#
#This parameter is not MANDATORY but if not used then getbulk must be used
X-SKROOGE-getoperations=a="%parameter2" && b="%4" && m=$( [[ ${a} > ${b} ]] && echo "$a" || echo "$b" ) && PYTHONIOENCODING=utf_8 boobank -q -f csv history "%1" -s date,rdate,type,raw,label,amount --condition "rdate>$m OR date>$m OR rdate>$m 00:00:00 OR date>$m 00:00:00" -n 99999 %parameter3 2>/dev/null
#The command line to get all csv files in one call.
#Format of CSV files must be the same than for getoperations
#If getbulk is declare then getoperations is ignored
#
#In the command line:
# %1 will be replaced by the temporary directory [MANDATORY]
#
#This parameter is not MANDATORY but if not used then getoperations must be used
#getbulk=bulkdownload "%1"
#The csv columns. See CSV import settings for more detail.
X-SKROOGE-csvcolumns=date2|date1|mode|comment|payee|amount
#The operating systems supported (linux, windows, osx, ...) or blank for all (see QSysInfo::kernelType)
X-SKROOGE-ossuppored=linux,freebsd,darwin
diff --git a/plugins/import/skrooge_import_backend/backends/org.kde.skrooge-import-backend-weboob_coming.desktop b/plugins/import/skrooge_import_backend/backends/org.kde.skrooge-import-backend-weboob_coming.desktop
index ce7983f4e..cd6b76a8b 100644
--- a/plugins/import/skrooge_import_backend/backends/org.kde.skrooge-import-backend-weboob_coming.desktop
+++ b/plugins/import/skrooge_import_backend/backends/org.kde.skrooge-import-backend-weboob_coming.desktop
@@ -1,107 +1,107 @@
[Desktop Entry]
Name=Weboob coming backend
Name[ca]=Dorsal per a entrades del Weboob
Name[ca@valencia]=Dorsal per a entrades del Weboob
Name[cs]=Podpůrná vrstva Weboob
Name[en_GB]=Weboob coming backend
Name[es]=Motor Weboob para opciones venideras
Name[fr]=Moteur Weboob à venir
Name[gl]=Infraestrutura de futuro de weboob
Name[it]=Motore Weboob in arrivo
Name[nl]=Weboob inkomende backend
Name[pl]=Silnik Weboob nadchodzących
Name[pt]=Infra-estrutura de adiantamento do Weboob
Name[sv]=Weboob coming-gränssnitt
Name[tr]=Weboob arka ucu
Name[uk]=Модуль Weboob для майбутніх операцій
Name[x-test]=xxWeboob coming backendxx
Comment=An import backend for Skrooge using weboob for coming operation. This plugin can be used for card with deferred debit.\n You must install weboob and configure correctly the boobank module before using this backend.\n\n Parameter:\n The list of accounts to import separated by '|'. If you don't pass parameter then all accounts will be imported.\n Example: 123@ca|456@bp
Comment[ca]=Un dorsal d'importació per a l'Skrooge usant Weboob per operacions entrants. Aquest connector es pot usar per a targetes amb càrrec diferit.\n Cal instal·lar el «weboob» i configurar correctament el mòdul «boobank» abans d'usar aquest dorsal.\n\n Paràmetre:\n La llista de comptes a importar, separats amb «|». Si no es passa el paràmetre, s'importaran tots els comptes.\n Exemple: 123@ca|456@bp
Comment[ca@valencia]=Un dorsal d'importació per a l'Skrooge usant Weboob per operacions entrants. Aquest connector es pot usar per a targetes amb càrrec diferit.\n Cal instal·lar el «weboob» i configurar correctament el mòdul «boobank» abans d'usar aquest dorsal.\n\n Paràmetre:\n La llista de comptes a importar, separats amb «|». Si no es passa el paràmetre, s'importaran tots els comptes.\n Exemple: 123@ca|456@bp
Comment[en_GB]=An import backend for Skrooge using weboob for coming operation. This plugin can be used for card with deferred debit.\n You must install weboob and configure correctly the boobank module before using this backend.\n\n Parameter:\n The list of accounts to import separated by '|'. If you don't pass parameter then all accounts will be imported.\n Example: 123@ca|456@bp
Comment[es]=Un motor de importación para Skrooge que usa weboob para operaciones venideras. Este complemento se puede usar para tarjetas de débito diferido.\n Debe instalar weboob y configurar correctamente el módulo «boobank» antes de usar este motor.\n\n Parámetro:\n La lista de cuentas a importar separada por «|». Si no pasa ningún parámetro se importarán todas las cuentas.\n Ejemplo: 123@ca|456@bp
-Comment[fr]=Un moteur d'importation pour Skrooge utilisant weboob pour les opérations à venir\n Vous devez installer weboob et configurer correctement le module boobank avant d'utiliser ce moteur.\n\n Paramètres : La liste des comptes à importer séparés par '|'. Si vous ne passez pas de paramètre alors tous les comptes seront importés.\n Exemple: 123@ca|456@bp
+Comment[fr]=Un moteur d'importation pour Skrooge utilisant weboob pour les opérations à venir\n Vous devez installer weboob et configurer correctement le module boobank avant d'utiliser ce moteur.\n\n Paramètres : La liste des comptes à importer séparés par '|'. Si vous ne passez pas de paramètre alors tous les comptes seront importés.\n Exemple: 123@ca|456@bp
Comment[gl]=Unha infraestrutura de importación para Skrooge que usa weboob para operacións futuras. Este complemento pode usarse para tarxetas con débito en diferido.\nDebe instalar weboob e configurar correctamente o módulo boobank para poder usar esta infraestrutura.\n\n Parámetro:\n A lista de contas para importar separadas por «|». Se non pasa o parámetro, impórtanse todas as contas.\nPor exemplo: «123@ca|456@bp».
Comment[it]=Un motore di importazione per Skrooge che utilizza weboob per le operazioni in arrivo. Questa estensione può essere usata per le carte con addebito differito.\n Prima di utilizzare questo motore devi installare weboob e configurare il modulo boobank.\n\n Parametro:\n l'elenco dei conti da importare separati da «|». Se non passi il parametro verranno importati tutti i conti.\n Esempio: 123@ca|456@bp
Comment[nl]=Een backend voor importeren voor Skrooge met gebruik van weboob voor aankomende bewerkingen. Deze plug-in kan gebruikt worden voor verschoven debet. U moet weboob installeren en de boobank-module juist configureren alvorens deze backend te gebruiken.\n\n Parameter:\n De lijst accounts om apart te importeren gescheiden door '|'. Als u geen parameter meegeeft dan worden alle accounts geïmporteerd.\n Voorbeeld: 123@ca|456@bp
Comment[pl]=Silnik importu dla Skrooge używający weboob do operacji przychodzących. Tej wtyczki można używać dla kart z odroczonym debetem.\n Musisz wgrać weboob i ustawić poprawnie moduł boobank przed użyciem tego silnika.\n\n Parametr:\n Lista kont do zaimportowania oddzielonych '|'. Jeśli nie podasz tego parametru, to zostaną zaimportowane wszystkie konta.\n Na przykład: 123@ca|456@bp
Comment[pt]=Uma infra-estrutura de importação para o Skrooge que usa o Weboob para operações de adiantamento. Este 'plugin' poderá ser usado para cartões com débito pré-datado.\n Deverá instalar o Weboob e configurar correctamente o módulo 'boobank' antes de usar esta infra-estrutura.\n\n. Parâmetro:\n A lista de contas a importar, separadas por '|' Se não passar parâmetros, então serão importadas todas as contas.\n Exemplo: 123@ca|456@bp
Comment[sv]=Ett importgränssnitt för Skrooge som använder weboob för framtida transaktioner. Insticksprogrammet kan användas för kreditkort med fakturering.\n Du måste installera weboob och ställa in modulen boobank korrekt innan gränssnittet används.\n\nParameter:\n Listan med konton som ska importeras åtskilda av '|'. Om du inte skickar med parametern importeras alla konton.\nExempel: 123@ca|456@bp
Comment[uk]=Модуль імпортування даних до Skrooge з використанням weboob для майбутніх операцій. Цим додатком можна скористатися для карток із відкладеними видатками.\n Вам слід встановити weboob і налаштувати належним чином модуль boobank, перш ніж користуватися цим модулем обробки.\n\n Параметр:\n список рахунків, дані яких слід імпортувати з відокремленням записів символом «|». Якщо ви не передасте параметр, буде імпортовано дані усіх рахунків.\n Приклад: 123@ca|456@bp
Comment[x-test]=xxAn import backend for Skrooge using weboob for coming operation. This plugin can be used for card with deferred debit.\n You must install weboob and configure correctly the boobank module before using this backend.\n\n Parameter:\n The list of accounts to import separated by '|'. If you don't pass parameter then all accounts will be imported.\n Example: 123@ca|456@bpxx
Encoding=UTF-8
Icon=skrooge
Type=Service
X-KDE-ServiceTypes=Skrooge/Import/Backend
X-Krunner-ID=weboob_coming
X-KDE-PluginInfo-Author=Stephane MANKOWSKI,miraks
X-KDE-PluginInfo-Email=stephane@mankowski.fr
X-KDE-PluginInfo-Name=weboob
X-KDE-PluginInfo-Version=1.0
-X-KDE-PluginInfo-Website=http://skrooge.org/
+X-KDE-PluginInfo-Website=https://skrooge.org/
X-KDE-PluginInfo-Category=Plugins
X-KDE-PluginInfo-Depends=
X-KDE-PluginInfo-License=GPL
X-KDE-PluginInfo-EnabledByDefault=true
#The command line to get the list of accounts in the standard output, something like this:
#id;balance
#12345@bankname;123.45
#78900@bankname;789.00
#
#The command must provide one line per account. This could be a csv or a text plain file.
#Warning: The first line is ignored
#%3 will be replaced by the password requeted interactively to the en user
#This parameter is MANDATORY
X-SKROOGE-getaccounts=PYTHONIOENCODING=utf_8 boobank ls -q -f csv -s id,label,balance | grep -E "id;label;balance|%parameter1"
#Regular expression to capture the account id of each accounts
#For the regexp syntax, you can consult this page: http://qt-project.org/doc/qt-4.8/qregexp.html
#If the account id is something like aa@bb then aa is the account identifier and bb the bank name.
#This parameter is MANDATORY
X-SKROOGE-getaccountid=([^;]*);
#Regular expression to capture the account balance of each accounts
#The account balance is used only during the first import to compute the initial balance of the account.
#For an existing account with already some operations, this is used to check the account.
#This parameter is not MANDATORY.
X-SKROOGE-getaccountbalance=[^;]*;[^;]*;([^;]*)
#Regular expression to capture the name of account
#This parameter is not MANDATORY.
X-SKROOGE-getaccountname=[^;]*;([^;]*)
#The command line to get the csv operations list.
#Example:
#id;date;rdate;type;raw;category;label;amount
#0@creditcooperatif;2013-04-12;2013-04-12;1;VIREMENT I.P.E.C.A. PREVOYANCE- VIRT IPECA - FRAIS DE SANTE;Not available;I.P.E.C.A. PREVOYANCE;16.80
#0@creditcooperatif;2013-04-12;2013-04-12;1;VIR C.P.A.M. TOULOUSE- 000000 131000017450;Not available;C.P.A.M. TOULOUSE;16.10
#0@creditcooperatif;2013-04-12;2013-04-12;3;CHEQUE NC 1962805;Not available;CHEQUE NC 1962805;-319.00
#
#The command must provide one line per account. This must be csv file.
#
#In the command line:
# %1 will be replaced by the account id [MANDATORY]
# %2 will be replaced by the nb max operations to download [NOT MANDATORY]
# %3 will be replaced by the password) [NOT MANDATORY]
# %4 will be replaced by the begin date (format: YYYY-MM-DD) of operations [NOT MANDATORY]
#
#This parameter is not MANDATORY but if not used then getbulk must be used
X-SKROOGE-getoperations=PYTHONIOENCODING=utf_8 boobank -q -f csv coming "%1" -s date,rdate,type,raw,label,amount --condition "rdate>%4 OR date>%4 OR rdate>%4 00:00:00 OR date>%4 00:00:00" -n 99999 %parameter2 2>/dev/null
#The command line to get all csv files in one call.
#Format of CSV files must be the same than for getoperations
#If getbulk is declare then getoperations is ignored
#
#In the command line:
# %1 will be replaced by the temporary directory [MANDATORY]
#
#This parameter is not MANDATORY but if not used then getoperations must be used
#getbulk=bulkdownload "%1"
#The csv columns. See CSV import settings for more detail.
X-SKROOGE-csvcolumns=date2|date1|mode|comment|payee|amount
#The operating systems supported (linux, windows, osx, ...) or blank for all (see QSysInfo::kernelType)
X-SKROOGE-ossuppored=linux,freebsd,darwin
diff --git a/plugins/import/skrooge_import_backend/org.kde.skrooge-import-backend.desktop b/plugins/import/skrooge_import_backend/org.kde.skrooge-import-backend.desktop
index 94e05265e..fae5377b5 100644
--- a/plugins/import/skrooge_import_backend/org.kde.skrooge-import-backend.desktop
+++ b/plugins/import/skrooge_import_backend/org.kde.skrooge-import-backend.desktop
@@ -1,63 +1,63 @@
[Desktop Entry]
Name=Skrooge import backend plugin
Name[bs]=Skrooge dodatak za backend uvoz
Name[ca]=Connector de dorsal d'importació de l'Skrooge
Name[ca@valencia]=Connector de dorsal d'importació de l'Skrooge
Name[cs]=Modul podpůrné vrstvy Skrooge pro import
Name[da]=Backend-plugin til Skrooge-import
Name[de]=Skrooge-Import-Backendmodul
Name[el]=Skrooge import backend plugin
Name[en_GB]=Skrooge import backend plugin
Name[es]=Complemento del motor de importación de Skrooge
Name[fi]=Skroogen tuontitaustaosan liitännäinen
Name[fr]=Module externe de Skrooge pour l'importation par moteur externe
Name[gl]=Complemento de infraestrutura de importación de Skrooge
Name[hu]=Skrooge importáló háttérprogram bővítmény
Name[it]=Estensione di Skrooge del motore di importazione
Name[lt]=Skrooge importo galinės sąsajos papildinys
Name[nl]=Plug-in voor importbackend van Skrooge
Name[pl]=Wtyczka silnika importu dla Skrooge
Name[pt]='Plugin' de infra-estrutura de importação do Skrooge
Name[pt_BR]=Plugin da infraestrutura de importação do Skrooge
Name[ru]=Модуль движка импорта
Name[sk]=Plugin backendu importu Skrooge
Name[sv]=Skrooge gränssnittsinsticksprogram för import
Name[tr]=Skrooge içe aktarma uygulaması eklentisi
Name[uk]=Додаток модуля імпортування Skrooge
Name[x-test]=xxSkrooge import backend pluginxx
Name[zh_TW]=Skrooge 匯入後端介面外掛程式
Comment=A Skrooge plugin to import files from backends
Comment[ca]=Un connector de l'Skrooge per importar fitxers des de dorsals
Comment[ca@valencia]=Un connector de l'Skrooge per importar fitxers des de dorsals
Comment[cs]=Modul Skrooge pro import souborů z podpůrných vrstev
Comment[de]=Ein Skrooge-Modul zum Import von Dateien von Backends
Comment[en_GB]=A Skrooge plugin to import files from backends
Comment[es]=Un complemento de Skrooge para importar archivos para motores
Comment[fi]=Skroogen liitännäinen tiedostojen tuontiin taustajärjestelmistä
Comment[fr]=Un module externe de Skrooge pour l'importation de fichiers avec un moteur
Comment[gl]=Un complemento de Skrooge para importar ficheiros desde infraestruturas.
Comment[it]=Un'estensione di Skrooge per importare i file dai motori
Comment[nl]=Een Skrooge-plugin voor het importeren van bestanden van backends
Comment[pl]=Wtyczka Skrooge do importu plików z innych silników
Comment[pt]=Um 'plugin' do Skrooge para importar ficheiros de outras infra-estruturas
Comment[pt_BR]=Um plugin do Skrooge para importar arquivos das infraestruturas
Comment[sk]=Skrooge plugin na import súborov z backendov
Comment[sv]=Ett insticksprogram till Skrooge för att importera filer från gränssnitt
Comment[tr]=Arkauç dosyalarını içe aktarmak için bir Skrooge eklentisi
Comment[uk]=Додаток до Skrooge для імпортування даних з модулів
Comment[x-test]=xxA Skrooge plugin to import files from backendsxx
Encoding=UTF-8
Icon=skrooge
Type=Service
X-KDE-ServiceTypes=SKG IMPORT/Plugin
X-KDE-Library=skrooge_import_backend
X-Krunner-ID=Skrooge import backend plugin
X-KDE-PluginInfo-Author=Stephane MANKOWSKI
X-KDE-PluginInfo-Email=stephane@mankowski.fr
X-KDE-PluginInfo-Name=skrooge_import_backend
X-KDE-PluginInfo-Version=1.0
-X-KDE-PluginInfo-Website=http://skrooge.org/
+X-KDE-PluginInfo-Website=https://skrooge.org/
X-KDE-PluginInfo-Category=Plugins
X-KDE-PluginInfo-Depends=
X-KDE-PluginInfo-License=GPL
X-KDE-PluginInfo-EnabledByDefault=true
diff --git a/plugins/import/skrooge_import_backend/skgimportpluginbackend.cpp b/plugins/import/skrooge_import_backend/skgimportpluginbackend.cpp
index 7ff216163..4840a35a5 100644
--- a/plugins/import/skrooge_import_backend/skgimportpluginbackend.cpp
+++ b/plugins/import/skrooge_import_backend/skgimportpluginbackend.cpp
@@ -1,417 +1,417 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is Skrooge plugin for BACKEND import / export.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgimportpluginbackend.h"
#include <qapplication.h>
#include <qdir.h>
#include <qdiriterator.h>
#include <qfile.h>
#include <qfileinfo.h>
#include <qprocess.h>
#include <qstandardpaths.h>
#include <qtconcurrentmap.h>
#include <kaboutdata.h>
#include <klocalizedstring.h>
#include <kpluginfactory.h>
#include "skgbankincludes.h"
#include "skgimportexportmanager.h"
#include "skgservices.h"
#include "skgtraces.h"
/**
* This plugin factory.
*/
K_PLUGIN_FACTORY(SKGImportPluginBackendFactory, registerPlugin<SKGImportPluginBackend>();)
SKGImportPluginBackend::SKGImportPluginBackend(QObject* iImporter, const QVariantList& iArg)
: SKGImportPlugin(iImporter)
{
SKGTRACEINFUNC(10)
Q_UNUSED(iArg)
m_listBackends = KServiceTypeTrader::self()->query(QStringLiteral("Skrooge/Import/Backend"));
}
SKGImportPluginBackend::~SKGImportPluginBackend()
= default;
QExplicitlySharedDataPointer<KService> SKGImportPluginBackend::getService() const
{
for (const auto& service : m_listBackends) {
if (service->property(QStringLiteral("X-Krunner-ID"), QVariant::String).toString().toUpper() == m_importer->getFileNameExtension()) {
return service;
}
}
return QExplicitlySharedDataPointer<KService>(nullptr);
}
QString SKGImportPluginBackend::getParameter(const QString& iAttribute)
{
auto service = getService();
QString output = service->property(iAttribute, QVariant::String).toString();
QMap<QString, QString> parameters = this->getImportParameters();
for (int i = 1; i <= 10; ++i) {
QString param = "parameter" + SKGServices::intToString(i);
if (output.contains(QStringLiteral("%") % param)) {
output = output.replace(QStringLiteral("%") % param, parameters.value(param));
}
}
return output;
}
bool SKGImportPluginBackend::isImportPossible()
{
SKGTRACEINFUNC(10)
return (m_importer == nullptr ? true : getService().data() != nullptr);
}
struct download {
download(int iNbToDownload, QString iDate, QString iCmd, QString iPwd, QString iPath)
: m_nbToDownload(iNbToDownload), m_date(std::move(iDate)), m_cmd(std::move(iCmd)), m_pwd(std::move(iPwd)), m_path(std::move(iPath))
{
}
using result_type = QString;
QString operator()(const QString& iAccountId)
{
QString file = m_path % "/" % iAccountId % ".csv";
// Build cmd
QString cmd = m_cmd;
cmd = cmd.replace(QStringLiteral("%2"), SKGServices::intToString(m_nbToDownload)).replace(QStringLiteral("%1"), iAccountId).replace(QStringLiteral("%3"), m_pwd).replace(QStringLiteral("%4"), m_date);
// Execute
QProcess p;
cmd = SKGServices::getFullPathCommandLine(cmd);
SKGTRACEL(10) << "Execute: " << cmd << endl;
p.setStandardOutputFile(file);
int retry = 0;
do {
p.start(QStringLiteral("/bin/bash"), QStringList() << QStringLiteral("-c") << cmd);
if (p.waitForFinished(1000 * 60 * 2)) {
if (p.exitCode() == 0) {
return iAccountId;
}
SKGTRACE << i18nc("A warning message", "WARNING: The command %1 failed with code %2 (Retry %3)", cmd, p.exitCode(), retry + 1) << endl;
} else {
SKGTRACE << i18nc("A warning message", "WARNING: The command %1 failed due to a time out (Retry %2)", cmd, retry + 1) << endl;
p.terminate();
p.kill();
}
++retry;
} while (retry < 6);
QString errorMsg = i18nc("Error message", "The following command line failed with code %2:\n'%1'", cmd, p.exitCode());
SKGTRACE << errorMsg << endl;
return QStringLiteral("ERROR:") + errorMsg;
}
int m_nbToDownload;
QString m_date;
QString m_cmd;
QString m_pwd;
QString m_path;
};
SKGError SKGImportPluginBackend::importFile()
{
if (m_importer == nullptr) {
return SKGError(ERR_ABORT, i18nc("Error message", "Invalid parameters"));
}
SKGError err;
SKGTRACEINFUNCRC(2, err)
SKGBEGINPROGRESSTRANSACTION(*m_importer->getDocument(), i18nc("Noun, name of the user action", "Import with %1", "Backend"), err, 3)
QString bankendName = m_importer->getFileNameExtension().toLower();
// Get parameters
QMap<QString, QString> parameters = this->getImportParameters();
QString pwd = parameters[QStringLiteral("password")];
// Get list of accounts
QStringList backendAccounts;
QMap<QString, QString> backendAccountsBalance;
QMap<QString, QString> backendAccountsName;
QString csvfile = m_tempDir.path() % "/skrooge_backend.csv";
QString cmd = getParameter(QStringLiteral("X-SKROOGE-getaccounts")).replace(QStringLiteral("%3"), pwd);
QProcess p;
cmd = SKGServices::getFullPathCommandLine(cmd);
SKGTRACEL(10) << "Execute: " << cmd << endl;
p.setStandardOutputFile(csvfile);
p.start(QStringLiteral("/bin/bash"), QStringList() << QStringLiteral("-c") << cmd);
if (!p.waitForFinished(1000 * 60 * 2) || p.exitCode() != 0) {
err.setReturnCode(ERR_FAIL).setMessage(i18nc("Error message", "The following command line failed with code %2:\n'%1'", cmd, p.exitCode()));
} else {
QFile file(csvfile);
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
err.setReturnCode(ERR_INVALIDARG).setMessage(i18nc("Error message", "Open file '%1' failed", csvfile));
} else {
QRegExp reggetaccounts(getParameter(QStringLiteral("X-SKROOGE-getaccountid")));
QRegExp reggetaccountbalance(getParameter(QStringLiteral("X-SKROOGE-getaccountbalance")));
QRegExp reggetaccountname(getParameter(QStringLiteral("X-SKROOGE-getaccountname")));
QTextStream stream(&file);
stream.readLine(); // To avoid header
QStringList backendAccountsUniqueId;
while (!stream.atEnd()) {
// Read line
QString line = stream.readLine().trimmed();
SKGTRACEL(10) << "Read line: " << line << endl;
// Get account id
int pos = reggetaccounts.indexIn(line);
if (pos > -1) {
QString accountid = reggetaccounts.cap(1);
QString uniqueid = SKGServices::splitCSVLine(accountid, QLatin1Char('@')).at(0);
if (!backendAccounts.contains(accountid) && !backendAccountsUniqueId.contains(uniqueid)) {
backendAccounts.push_back(accountid);
backendAccountsUniqueId.push_back(uniqueid);
// Get account balance
pos = reggetaccountbalance.indexIn(line);
if (pos > -1) {
backendAccountsBalance[accountid] = reggetaccountbalance.cap(1);
} else {
backendAccountsBalance[accountid] = '0';
}
// Get account name
pos = reggetaccountname.indexIn(line);
if (pos > -1) {
backendAccountsName[accountid] = reggetaccountname.cap(1);
} else {
backendAccountsName[accountid] = QLatin1String("");
}
}
} else {
// This is an error
err.setReturnCode(ERR_FAIL).setMessage(line).addError(ERR_FAIL, i18nc("Error message", "Impossible to find the account id with the regular expression '%1' in line '%2'", getParameter(QStringLiteral("X-SKROOGE-getaccountid")), line));
break;
}
}
// close file
file.close();
file.remove();
}
}
// Download operations
IFOKDO(err, m_importer->getDocument()->stepForward(1, i18nc("Progress message", "Download operations")))
IFOK(err) {
if (backendAccounts.isEmpty()) {
err.setReturnCode(ERR_FAIL).setMessage(i18nc("Error message", "Your backend '%1' seems to be not well configure because no account has been found.", bankendName));
} else {
// Compute the begin date for download
QDate lastDownload = SKGServices::stringToTime(m_importer->getDocument()->getParameter("SKG_LAST_" % bankendName.toUpper() % "_IMPORT_DATE")).date();
QString lastList = m_importer->getDocument()->getParameter("SKG_LAST_" % bankendName.toUpper() % "_IMPORT_LIST");
QString currentList = backendAccounts.join(QStringLiteral(";"));
int nbToDownload = 0;
QString fromDate;
if (currentList != lastList || !lastDownload.isValid()) {
nbToDownload = 99999;
fromDate = QStringLiteral("2000-01-01");
} else {
nbToDownload = qMax(lastDownload.daysTo(QDate::currentDate()) * 10, qint64(20));
fromDate = SKGServices::dateToSqlString(lastDownload.addDays(-4));
}
// Download
QStringList listDownloadedId;
QString bulk = getParameter(QStringLiteral("X-SKROOGE-getbulk"));
QString cmddownload;
if (!bulk.isEmpty()) {
// mode bulk
SKGTRACEL(10) << "Mode getbulk" << endl;
QProcess pbulk;
QString cmd = bulk.replace(QStringLiteral("%1"), m_tempDir.path());
cmd = SKGServices::getFullPathCommandLine(cmd);
cmddownload = cmd;
SKGTRACEL(10) << "Execute: " << cmd << endl;
pbulk.start(QStringLiteral("/bin/bash"), QStringList() << QStringLiteral("-c") << cmd);
if (!pbulk.waitForFinished(1000 * 60 * 2) || pbulk.exitCode() != 0) {
err.setReturnCode(ERR_FAIL).setMessage(i18nc("Error message", "The following command line failed with code %2:\n'%1'", cmd, pbulk.exitCode()));
} else {
SKGTRACEL(10) << "Searching csv files " << endl;
QDirIterator it(m_tempDir.path(), QStringList() << QStringLiteral("*.csv"));
while (it.hasNext()) {
auto id = QFileInfo(it.next()).baseName();
listDownloadedId.push_back(id);
SKGTRACEL(10) << "Find id: " << id << endl;
}
}
} else {
// mode getoperations
SKGTRACEL(10) << "Mode getoperations" << endl;
cmddownload = getParameter(QStringLiteral("X-SKROOGE-getoperations"));
QFuture<QString> f = QtConcurrent::mapped(backendAccounts, download(nbToDownload, fromDate, cmddownload, pwd, m_tempDir.path()));
f.waitForFinished();
listDownloadedId = f.results();
}
listDownloadedId.removeAll(QLatin1String(""));
// Build list of errors
QStringList errors;
int nb = listDownloadedId.count();
errors.reserve(nb);
for (int i = nb - 1; i >= 0; --i) {
auto item = listDownloadedId.value(i);
if (item.startsWith(QLatin1String("ERROR:"))) {
listDownloadedId.removeAt(i);
errors.push_back(item.right(item.length() - 6));
}
}
// Check
IFOK(err) {
bool checkOK = true;
int nb = listDownloadedId.count();
if (errors.count() != 0) {
// Some accounts have not been downloaded
if (nb == 0) {
err = SKGError(ERR_FAIL, i18nc("Error message", "No accounts downloaded with the following command:\n%1\nCheck your backend installation.", cmddownload));
} else {
// Warning
m_importer->getDocument()->sendMessage(i18nc("Warning message", "Some accounts have not been downloaded. %1", errors.join(QStringLiteral(". "))), SKGDocument::Warning);
}
SKGTRACEL(10) << errors.count() << " accounts not imported => checkOK=false" << endl;
checkOK = false;
}
// import
IFOKDO(err, m_importer->getDocument()->stepForward(2, i18nc("Progress message", "Import")))
if (!err && (nb != 0)) {
// import
SKGBEGINPROGRESSTRANSACTION(*m_importer->getDocument(), "#INTERNAL#" % i18nc("Noun, name of the user action", "Import one account with %1", "Backend"), err, nb)
// Get all messages
SKGDocument::SKGMessageList messages;
IFOKDO(err, m_importer->getDocument()->getMessages(m_importer->getDocument()->getCurrentTransaction(), messages, true))
// Import all files
for (int i = 0; !err && i < nb; ++i) {
// Rename the imported name
QString file = m_tempDir.path() % "/" % listDownloadedId.at(i) % ".csv";
if (!listDownloadedId.at(i).contains(QStringLiteral("-")) && !backendAccountsName[listDownloadedId.at(i)].isEmpty()) {
QString newFileName = m_tempDir.path() % "/" % backendAccountsName[listDownloadedId.at(i)] % '-' % listDownloadedId.at(i) % ".csv";
if (QFile::rename(file, newFileName)) {
file = newFileName;
}
}
// Import
SKGImportExportManager imp1(m_importer->getDocument(), QUrl::fromLocalFile(file));
imp1.setAutomaticValidation(m_importer->automaticValidation());
imp1.setAutomaticApplyRules(m_importer->automaticApplyRules());
// This option is not used with backend import
imp1.setSinceLastImportDate(false);
imp1.setCodec(m_importer->getCodec());
QMap<QString, QString> newParameters = imp1.getImportParameters();
newParameters[QStringLiteral("automatic_search_header")] = 'N';
newParameters[QStringLiteral("header_position")] = '1';
newParameters[QStringLiteral("automatic_search_columns")] = 'N';
newParameters[QStringLiteral("columns_positions")] = getParameter(QStringLiteral("X-SKROOGE-csvcolumns"));
newParameters[QStringLiteral("mode_csv_unit")] = 'N';
newParameters[QStringLiteral("mode_csv_rule")] = 'N';
newParameters[QStringLiteral("balance")] = backendAccountsBalance[listDownloadedId.at(i)];
newParameters[QStringLiteral("donotfinalize")] = 'Y';
imp1.setImportParameters(newParameters);
IFOKDO(err, imp1.importFile())
if (!backendAccountsBalance[listDownloadedId.at(i)].isEmpty()) {
SKGAccountObject act;
IFOKDO(err, imp1.getDefaultAccount(act))
m_importer->addAccountToCheck(act, SKGServices::stringToDouble(backendAccountsBalance[listDownloadedId.at(i)]));
}
IFOKDO(err, m_importer->getDocument()->stepForward(i + 1))
}
// Remove all temporary files
for (int i = 0; i < nb; ++i) {
QString file = m_tempDir.path() % "/" % listDownloadedId.at(i) % ".csv";
QFile::remove(file);
}
// Reset message
IFOKDO(err, m_importer->getDocument()->removeMessages(m_importer->getDocument()->getCurrentTransaction()))
int nbm = messages.count();
for (int j = 0; j < nbm; ++j) {
SKGDocument::SKGMessage msg = messages.at(j);
m_importer->getDocument()->sendMessage(msg.Text, msg.Type, msg.Action);
}
// Finalize import
IFOKDO(err, m_importer->finalizeImportation())
// Disable std finalisation
QMap<QString, QString> parameters = m_importer->getImportParameters();
parameters[QStringLiteral("donotfinalize")] = 'Y';
m_importer->setImportParameters(parameters);
// Check balances of accounts
auto accountsToCheck = m_importer->getAccountsToCheck();
int nb = accountsToCheck.count();
for (int i = 0; !err && i < nb; ++i) {
// Get the account to check
auto act = accountsToCheck[i].first;
auto targetBalance = accountsToCheck[i].second;
auto soluces = act.getPossibleReconciliations(targetBalance, false);
if (soluces.isEmpty()) {
SKGTRACEL(10) << "Account " << listDownloadedId.at(i) << " not reconciliable => checkOK=false" << endl;
checkOK = false;
}
}
if (checkOK) {
// Last import is memorized only in case of 100% success
IFOKDO(err, m_importer->getDocument()->setParameter("SKG_LAST_" % bankendName.toUpper() % "_IMPORT_DATE", SKGServices::dateToSqlString(QDateTime::currentDateTime())))
IFOKDO(err, m_importer->getDocument()->setParameter("SKG_LAST_" % bankendName.toUpper() % "_IMPORT_LIST", currentList))
} else {
// Remove last import for next import
IFOKDO(err, m_importer->getDocument()->setParameter("SKG_LAST_" % bankendName.toUpper() % "_IMPORT_DATE", QLatin1String("")))
IFOKDO(err, m_importer->getDocument()->setParameter("SKG_LAST_" % bankendName.toUpper() % "_IMPORT_LIST", QLatin1String("")))
}
}
IFOKDO(err, m_importer->getDocument()->stepForward(3))
}
}
}
return err;
}
QString SKGImportPluginBackend::getMimeTypeFilter() const
{
return QLatin1String("");
}
#include <skgimportpluginbackend.moc>
diff --git a/plugins/import/skrooge_import_backend/skgimportpluginbackend.h b/plugins/import/skrooge_import_backend/skgimportpluginbackend.h
index f4125d530..1d19c5f9b 100644
--- a/plugins/import/skrooge_import_backend/skgimportpluginbackend.h
+++ b/plugins/import/skrooge_import_backend/skgimportpluginbackend.h
@@ -1,81 +1,81 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGIMPORTPLUGINBACKEND_H
#define SKGIMPORTPLUGINBACKEND_H
/** @file
* This file is Skrooge plugin for BACKEND import / export.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgimportplugin.h"
#include <kservice.h>
#include <kservicetypetrader.h>
#include <qtemporarydir.h>
/**
* This file is Skrooge plugin for BACKEND import / export.
*/
class SKGImportPluginBackend : public SKGImportPlugin
{
Q_OBJECT
Q_INTERFACES(SKGImportPlugin)
public:
/**
* Default constructor
* @param iImporter the parent importer
* @param iArg the arguments
*/
explicit SKGImportPluginBackend(QObject* iImporter, const QVariantList& iArg);
/**
* Default Destructor
*/
~SKGImportPluginBackend() override;
/**
* To know if import is possible with this plugin
*/
bool isImportPossible() override;
/**
* Import a file
* @return an object managing the error.
* @see SKGError
*/
SKGError importFile() override;
/**
* Return the mime type filter
* @return the mime type filter. Example: "*.csv|CSV file"
*/
QString getMimeTypeFilter() const override;
private:
Q_DISABLE_COPY(SKGImportPluginBackend)
QExplicitlySharedDataPointer<KService> getService() const;
QString getParameter(const QString& iAttribute);
KService::List m_listBackends;
QTemporaryDir m_tempDir;
};
#endif // SKGIMPORTPLUGINBACKEND_H
diff --git a/plugins/import/skrooge_import_csv/CMakeLists.txt b/plugins/import/skrooge_import_csv/CMakeLists.txt
index 97026f71b..7695773b7 100644
--- a/plugins/import/skrooge_import_csv/CMakeLists.txt
+++ b/plugins/import/skrooge_import_csv/CMakeLists.txt
@@ -1,33 +1,33 @@
#***************************************************************************
#* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
#* *
#* 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 <http://www.gnu.org/licenses/> *
+#* along with this program. If not, see <https://www.gnu.org/licenses/> *
#***************************************************************************
MESSAGE( STATUS "..:: CMAKE PLUGIN_IMPORT_CSV ::..")
PROJECT(plugin_import_csv)
LINK_DIRECTORIES (${LIBRARY_OUTPUT_PATH})
SET(skrooge_import_csv_SRCS
skgimportplugincsv.cpp
)
ADD_LIBRARY(skrooge_import_csv MODULE ${skrooge_import_csv_SRCS})
TARGET_LINK_LIBRARIES(skrooge_import_csv KF5::Parts skgbasemodeler skgbasegui skgbankmodeler skgbankgui)
########### install files ###############
INSTALL(TARGETS skrooge_import_csv DESTINATION ${KDE_INSTALL_QTPLUGINDIR})
INSTALL(FILES ${PROJECT_SOURCE_DIR}/org.kde.skrooge-import-csv.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR})
diff --git a/plugins/import/skrooge_import_csv/org.kde.skrooge-import-csv.desktop b/plugins/import/skrooge_import_csv/org.kde.skrooge-import-csv.desktop
index c92c1ffb2..b44ca769e 100644
--- a/plugins/import/skrooge_import_csv/org.kde.skrooge-import-csv.desktop
+++ b/plugins/import/skrooge_import_csv/org.kde.skrooge-import-csv.desktop
@@ -1,74 +1,74 @@
[Desktop Entry]
Name=Skrooge import CSV plugin
Name[bs]=Skrooge dodatak za CSV uvoz
Name[ca]=Connector d'importació de CSV de l'Skrooge
Name[ca@valencia]=Connector d'importació de CSV de l'Skrooge
Name[cs]=Modul Skrooge pro import CSV
Name[da]=Plugin til import af CSV til Skrooge
Name[de]=Skrooge-CSV-Importmodul
Name[el]=Skrooge import CSV plugin
Name[en_GB]=Skrooge import CSV plugin
Name[es]=Complemento de Skrooge para la importación de CSV
Name[et]=Skrooge CSV impordi plugin
Name[fi]=Skroogen CSV-tuontiliitännäinen
-Name[fr]=Module externe de Skrooge pour l'importation « CSV »
+Name[fr]=Module externe de Skrooge pour l'importation « CSV »
Name[gl]=Complemento de importación de CSV a Skrooge
Name[hu]=Skrooge CSV importálás bővítmény
Name[it]=Estensione di Skrooge per l'importazione CSV
Name[lt]=Skrooge CSV importavimo papildinys
Name[nb]=Skrooge-modul for CSV-import
Name[nl]=Plugin van Skrooge voor CSV-importeren
Name[pl]=Wtyczka importu CSV dla Skrooge
Name[pt]='Plugin' de importação de CSV para o Skrooge
Name[pt_BR]=Plugin de importação de CSV para o Skrooge
Name[ru]=Модуль импорта файлов CSV
Name[sk]=Skrooge plugin CSV import
Name[sv]=Skrooge CSV-importinsticksprogram
Name[tr]=Skrooge CSV içe aktarma eklentisi
Name[uk]=Додаток імпортування CSV до Skrooge
Name[x-test]=xxSkrooge import CSV pluginxx
Name[zh_TW]=Skrooge 匯入 CSV 外掛程式
Comment=A Skrooge plugin to import CSV files
Comment[bs]=Skrooge dodatak za uvoz CSV datoteka
Comment[ca]=Un connector de l'Skrooge per importar fitxers CSV
Comment[ca@valencia]=Un connector de l'Skrooge per importar fitxers CSV
Comment[cs]=Modul Skrooge pro import souborů CSV
Comment[da]=Et Skrooge-plugin til at importere CSV-filer
Comment[de]=Ein Skrooge-Modul zum Import von CSV-Dateien
Comment[el]=Ένα πρόσθετο του Skrooge για την εισαγωγή αρχείων CSV
Comment[en_GB]=A Skrooge plugin to import CSV files
Comment[es]=Complemento de Skrooge para importar archivos CSV
Comment[et]=Skrooge plugin CSV-failide importimiseks
Comment[fi]=Skroogen CSV-tiedostojen tuontiliitännäinen
-Comment[fr]=Un module externe de Skrooge pour l'importation de fichiers « CSV »
+Comment[fr]=Un module externe de Skrooge pour l'importation de fichiers « CSV »
Comment[gl]=Un complemento de Skrooge para importar ficheiros CSV.
Comment[hu]=Egy Skrooge bővítmény CVS fájlok importálásához
Comment[it]=Un'estensione di Skrooge per importare i file CSV
Comment[lt]=Skrooge CSV failų importavimo papildinys
Comment[nb]=En Skrooge-modul for å importere CSV-filer
Comment[nl]=Een Skrooge-plugin voor het importeren van CSV-bestanden
Comment[pl]=Wtyczka Skrooge do importu plików CSV
Comment[pt]=Um 'plugin' do Skrooge para importar ficheiros CSV
Comment[pt_BR]=Um plugin do Skrooge para importar arquivos CSV
Comment[ru]=Модуль импорта файлов CSV
Comment[sk]=Skrooge plugin na import CSV súborov
Comment[sv]=Ett insticksprogram till Skrooge för att importera CSV-filer
Comment[tr]=CSV dosyalarını içe aktarmak için Skrooge eklentisi
Comment[uk]=Додаток до Skrooge для імпортування даних з файлів CSV
Comment[x-test]=xxA Skrooge plugin to import CSV filesxx
Comment[zh_TW]=Skrooge 匯入 CSV 檔用的外掛程式
Encoding=UTF-8
Icon=skrooge
Type=Service
X-KDE-ServiceTypes=SKG IMPORT/Plugin
X-KDE-Library=skrooge_import_csv
X-Krunner-ID=Skrooge import CSV plugin
X-KDE-PluginInfo-Author=Stephane MANKOWSKI
X-KDE-PluginInfo-Email=stephane@mankowski.fr
X-KDE-PluginInfo-Name=skrooge_import_csv
X-KDE-PluginInfo-Version=1.0
-X-KDE-PluginInfo-Website=http://skrooge.org/
+X-KDE-PluginInfo-Website=https://skrooge.org/
X-KDE-PluginInfo-Category=Plugins
X-KDE-PluginInfo-Depends=
X-KDE-PluginInfo-License=GPL
X-KDE-PluginInfo-EnabledByDefault=true
diff --git a/plugins/import/skrooge_import_csv/skgimportplugincsv.cpp b/plugins/import/skrooge_import_csv/skgimportplugincsv.cpp
index 73048f4c9..9a528d1af 100644
--- a/plugins/import/skrooge_import_csv/skgimportplugincsv.cpp
+++ b/plugins/import/skrooge_import_csv/skgimportplugincsv.cpp
@@ -1,1049 +1,1049 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is Skrooge plugin for CSV import / export.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgimportplugincsv.h"
#include <klocalizedstring.h>
#include <kpluginfactory.h>
#include <qcryptographichash.h>
#include <qfileinfo.h>
#include <qsavefile.h>
#include "skgbankincludes.h"
#include "skgimportexportmanager.h"
#include "skgservices.h"
#include "skgtraces.h"
/**
* This plugin factory.
*/
K_PLUGIN_FACTORY(SKGImportPluginCsvFactory, registerPlugin<SKGImportPluginCsv>();)
SKGImportPluginCsv::SKGImportPluginCsv(QObject* iImporter, const QVariantList& iArg)
: SKGImportPlugin(iImporter),
m_csvSeparator(QChar()), m_csvHeaderIndex(-1)
{
SKGTRACEINFUNC(10)
Q_UNUSED(iArg)
m_importParameters[QStringLiteral("mapping_date")] = i18nc("This is a regular expression to find the column in a csv file. You should keep the ^ and translate the word", "^date");
m_importParameters[QStringLiteral("mapping_account")] = i18nc("This is a regular expression to find the column in a csv file. You should keep the ^ and translate the word", "^account");
m_importParameters[QStringLiteral("mapping_number")] = i18nc("This is a regular expression to find the column in a csv file. You should keep the ^ and | and translate the words", "^number|^num?ro");
m_importParameters[QStringLiteral("mapping_mode")] = i18nc("This is a regular expression to find the column in a csv file. You should keep the ^ and | and translate the words", "^mode|^type");
m_importParameters[QStringLiteral("mapping_payee")] = i18nc("This is a regular expression to find the column in a csv file. You should keep the ^ and | and translate the words", "^payee|^tiers");
m_importParameters[QStringLiteral("mapping_comment")] = i18nc("This is a regular expression to find the column in a csv file. You should keep the ^ and | and translate the words", "^comment|^libell?|^d?tail|^info");
m_importParameters[QStringLiteral("mapping_status")] = i18nc("This is a regular expression to find the column in a csv file. You should keep the ^ and | and translate the words", "^status|^pointage");
m_importParameters[QStringLiteral("mapping_bookmarked")] = i18nc("This is a regular expression to find the column in a csv file. You should keep the ^ and translate the word", "^bookmarked");
m_importParameters[QStringLiteral("mapping_category")] = i18nc("This is a regular expression to find the column in a csv file. You should keep the ^ and translate the word", "^cat\\w*gor\\w*");
m_importParameters[QStringLiteral("mapping_amount")] = i18nc("This is a regular expression to find the column in a csv file. You should keep the ^ and | and translate the words", "^value|^amount|^valeur|^montant|^credit|^debit");
m_importParameters[QStringLiteral("mapping_quantity")] = i18nc("This is a regular expression to find the column in a csv file. You should keep the ^ and translate the word", "^quantity");
m_importParameters[QStringLiteral("mapping_unit")] = i18nc("This is a regular expression to find the column in a csv file. You should keep the ^ and translate the word", "^unit");
m_importParameters[QStringLiteral("mapping_sign")] = i18nc("This is a regular expression to find the column in a csv file. You should keep the ^ and | and translate the words", "^sign|^sens");
m_importParameters[QStringLiteral("mapping_debit")] = i18nc("This is a regular expression to find the column in a csv file. You should keep the ^ and | and translate the words", "^-|^debit|^withdrawal");
m_importParameters[QStringLiteral("mapping_idgroup")] = i18nc("This is a regular expression to find the column in a csv file. You should keep the ^ and translate the word", "^idgroup");
m_importParameters[QStringLiteral("mapping_idtransaction")] = i18nc("This is a regular expression to find the column in a csv file. You should keep the ^ and translate the word", "^idtransaction");
m_importParameters[QStringLiteral("mapping_property")] = QString();
m_importParameters[QStringLiteral("automatic_search_header")] = 'Y';
m_importParameters[QStringLiteral("header_position")] = '1';
m_importParameters[QStringLiteral("automatic_search_columns")] = 'Y';
m_importParameters[QStringLiteral("columns_positions")] = QString();
m_importParameters[QStringLiteral("mode_csv_unit")] = 'N';
m_importParameters[QStringLiteral("mode_csv_rule")] = 'N';
m_importParameters[QStringLiteral("date_format")] = QString();
}
SKGImportPluginCsv::~SKGImportPluginCsv()
= default;
void SKGImportPluginCsv::setImportParameters(const QMap< QString, QString >& iParameters)
{
SKGImportPlugin::setImportParameters(iParameters);
if (m_importParameters.value(QStringLiteral("automatic_search_header")) == QStringLiteral("N")) {
int header_position = SKGServices::stringToInt(m_importParameters.value(QStringLiteral("header_position")));
setCSVHeaderIndex(header_position);
}
if (m_importParameters.value(QStringLiteral("automatic_search_columns")) == QStringLiteral("N")) {
QStringList columns_positions = m_importParameters.value(QStringLiteral("columns_positions")).split('|');
if (m_csvHeaderIndex == -1) {
m_csvHeaderIndex = 1;
}
setCSVMapping(&columns_positions);
}
}
bool SKGImportPluginCsv::isImportPossible()
{
SKGTRACEINFUNC(10)
return isExportPossible();
}
QStringList SKGImportPluginCsv::getCSVMappingFromLine(const QString& iLine)
{
QStringList output;
QString line = iLine.trimmed();
// Split first line
QStringList csvAttributes = SKGServices::splitCSVLine(line, getCSVSeparator(iLine), true);
int nb = csvAttributes.count();
for (int i = 0; i < nb; ++i) {
QString att = csvAttributes.at(i).toLower();
// Search if this csv column is mapping a std attribute
QMapIterator<QString, QString> csvMapperIterator(m_importParameters);
bool found = false;
while (!found && csvMapperIterator.hasNext()) {
csvMapperIterator.next();
QString key = csvMapperIterator.key();
if (key.startsWith(QLatin1String("mapping_"))) {
key = key.right(key.length() - 8);
if (key != QStringLiteral("debit") &&
key != QStringLiteral("property") &&
!csvMapperIterator.value().isEmpty() &&
QRegExp(csvMapperIterator.value(), Qt::CaseInsensitive).indexIn(att) != -1 &&
(!output.contains(key) || key == QStringLiteral("comment") || key == QStringLiteral("category") || key == QStringLiteral("amount"))) {
output.push_back(key);
found = true;
}
}
}
// Search if this csv column must be added as a property
if (!found &&
!m_importParameters.value(QStringLiteral("mapping_property")).isEmpty() &&
QRegExp(m_importParameters.value(QStringLiteral("mapping_property")), Qt::CaseInsensitive).indexIn(att) != -1 &&
!output.contains(att)) {
output.push_back(att);
found = true;
}
if (!found) {
output.push_back(QString()); // To ignore this column
}
}
return output;
}
SKGError SKGImportPluginCsv::setCSVMapping(const QStringList* iCSVMapping)
{
SKGError err;
SKGTRACEINFUNCRC(10, err)
m_csvMapping.clear();
if (iCSVMapping == nullptr) {
// Automatic build
// Open file
QFile file(m_importer->getLocalFileName());
if (Q_UNLIKELY(!file.open(QIODevice::ReadOnly))) {
err.setReturnCode(ERR_INVALIDARG).setMessage(i18nc("Error message", "Open file '%1' failed", m_importer->getFileName().toDisplayString()));
} else {
QTextStream stream(&file);
if (!m_importer->getCodec().isEmpty()) {
stream.setCodec(m_importer->getCodec().toLatin1().constData());
}
// Ignore useless lines
int headerIndex = getCSVHeaderIndex();
for (int i = 1; i < headerIndex; ++i) {
stream.readLine();
}
// Get mapping
if (!stream.atEnd()) {
m_csvMapping = getCSVMappingFromLine(stream.readLine());
} else {
err.setReturnCode(ERR_INVALIDARG);
}
// close file
file.close();
}
} else {
// Manual build
m_csvMapping = *iCSVMapping;
}
IFOK(err) {
// Check if mandatory attributes have been found
if (m_importParameters.value(QStringLiteral("mode_csv_rule")) == QStringLiteral("Y")) {
if (!m_csvMapping.contains(QStringLiteral("payee")) || !m_csvMapping.contains(QStringLiteral("category"))) {
err = SKGError(ERR_FAIL, i18nc("Error message", "Columns payee and category not found. Set import parameters in settings (Configure Skrooge... / Import/Export / CSV / Edit regular expressions...)."));
}
} else {
if (!m_csvMapping.contains(QStringLiteral("date")) || !m_csvMapping.contains(QStringLiteral("amount"))) {
err = SKGError(ERR_FAIL, i18nc("Error message", "Columns date and amount not found. Set import parameters in settings (Configure Skrooge... / Import/Export / CSV / Edit regular expressions...)."));
}
}
}
return err;
}
SKGError SKGImportPluginCsv::setCSVHeaderIndex(int iIndex)
{
SKGError err;
SKGTRACEINFUNCRC(10, err)
if (iIndex == -1) {
// Automatic build
// Open file
QFile file(m_importer->getLocalFileName());
if (Q_UNLIKELY(!file.open(QIODevice::ReadOnly))) {
err.setReturnCode(ERR_INVALIDARG).setMessage(i18nc("Error message", "Open file '%1' failed", m_importer->getFileName().toDisplayString()));
} else {
QTextStream stream(&file);
if (!m_importer->getCodec().isEmpty()) {
stream.setCodec(m_importer->getCodec().toLatin1().constData());
}
int i = 1;
m_csvHeaderIndex = -1;
while (!stream.atEnd() && m_csvHeaderIndex == -1) {
// Read line
QStringList map = getCSVMappingFromLine(stream.readLine());
if (m_importParameters.value(QStringLiteral("mode_csv_rule")) == QStringLiteral("Y")) {
if (map.contains(QStringLiteral("payee")) && map.contains(QStringLiteral("category"))) {
m_csvHeaderIndex = i;
}
} else {
if (map.contains(QStringLiteral("date")) && map.contains(QStringLiteral("amount"))) {
m_csvHeaderIndex = i;
}
}
++i;
}
// close file
file.close();
}
} else {
// Manual build
m_csvHeaderIndex = iIndex;
}
return err;
}
int SKGImportPluginCsv::getCSVHeaderIndex()
{
SKGTRACEINFUNC(10)
if (m_csvHeaderIndex == -1) {
setCSVHeaderIndex(-1);
}
return m_csvHeaderIndex;
}
QChar SKGImportPluginCsv::getCSVSeparator(const QString& iLine)
{
SKGTRACEINFUNC(10)
if (m_csvSeparator.isNull()) {
QStringList csvAttributes = SKGServices::splitCSVLine(iLine, ';', true, &m_csvSeparator);
int nb = csvAttributes.count();
// If the split fails, we try with another separator
if (nb == 1) {
csvAttributes = SKGServices::splitCSVLine(iLine, ',', true, &m_csvSeparator);
nb = csvAttributes.count();
// If the split fails, we try with another separator
if (nb == 1) {
csvAttributes = SKGServices::splitCSVLine(iLine, '\t', true, &m_csvSeparator);
}
}
}
return m_csvSeparator;
}
SKGError SKGImportPluginCsv::importFile()
{
if (m_importParameters.value(QStringLiteral("mode_csv_rule")) == QStringLiteral("Y")) {
return importCSVRule();
}
if (m_importParameters.value(QStringLiteral("mode_csv_unit")) == QStringLiteral("Y")) {
return importCSVUnit();
}
if (m_importer == nullptr) {
return SKGError(ERR_ABORT, i18nc("Error message", "Invalid parameters"));
}
SKGError err;
SKGTRACEINFUNCRC(2, err)
// Begin transaction
err = m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Import step", "Import %1 file", "CSV"), 3);
IFOK(err) {
// Initialize some variables
QDateTime now = QDateTime::currentDateTime();
QString postFix = SKGServices::dateToSqlString(now);
// Default mapping
if (m_csvMapping.isEmpty()) {
err = setCSVMapping(nullptr);
IFOKDO(err, m_importer->getDocument()->sendMessage(i18nc("An information message", "Use automatic search of the columns")))
}
IFOKDO(err, m_importer->getDocument()->sendMessage(i18nc("An information message", "Mapping used: %1", m_csvMapping.join(QStringLiteral("|")))))
// Step 1 done
IFOKDO(err, m_importer->getDocument()->stepForward(1))
// Open file
IFOK(err) {
QFile file(m_importer->getLocalFileName());
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
err.setReturnCode(ERR_INVALIDARG).setMessage(i18nc("Error message", "Open file '%1' failed", m_importer->getFileName().toDisplayString()));
} else {
QTextStream stream(&file);
if (!m_importer->getCodec().isEmpty()) {
stream.setCodec(m_importer->getCodec().toLatin1().constData());
}
// Ignore useless lines
int headerIndex = getCSVHeaderIndex();
if (headerIndex == -1) {
err.setReturnCode(ERR_FAIL).setMessage(i18nc("Error message", "Header not found in CSV file"));
}
for (int i = 1; i <= headerIndex; ++i) {
stream.readLine();
}
QList<int> amountIndexes;
int nb = m_csvMapping.count();
for (int i = 0; i < nb; ++i) {
if (m_csvMapping.at(i) == QStringLiteral("amount")) {
amountIndexes.push_back(i);
}
}
int nbAmount = amountIndexes.count();
// Get data column
QStringList dates;
QStringList lines;
int posdate = -1;
bool modeAutoCreditDebit = (!m_csvMapping.contains(QStringLiteral("sign")) && nbAmount == 2);
IFOK(err) {
posdate = m_csvMapping.indexOf(QStringLiteral("date"));
if (posdate == -1) {
posdate = m_csvMapping.indexOf(QStringLiteral("date1"));
}
if (posdate == -1) {
posdate = m_csvMapping.indexOf(QStringLiteral("date2"));
}
if (posdate != -1) {
QString currentLine;
while (!stream.atEnd()) {
// Read line
QString line = stream.readLine().trimmed();
if (!line.isEmpty()) {
if (line.startsWith(QLatin1String("\""))) {
currentLine.clear();
}
currentLine += line;
// Get date
QStringList field = SKGServices::splitCSVLine(currentLine, getCSVSeparator(currentLine));
if (field.isEmpty()) {
// This is a multi line csv filename
} else {
lines.push_back(currentLine);
currentLine.clear();
if (field.count() >= m_csvMapping.count()) {
if (posdate < field.count()) {
dates.push_back(field.value(posdate).remove(QStringLiteral(" 00:00:00")).trimmed());
}
// Check if all amounts are positive
if (modeAutoCreditDebit) {
for (int i = 0; modeAutoCreditDebit && i < nbAmount; ++i) {
QString s = field.at(amountIndexes.at(i)).trimmed();
if (!s.isEmpty() && SKGServices::stringToDouble(s) < 0) {
modeAutoCreditDebit = false;
}
}
}
}
}
}
}
}
}
// close file
file.close();
// Select dateformat
QString dateFormat = m_importParameters.value(QStringLiteral("date_format"));
if (dateFormat.isEmpty()) {
dateFormat = SKGServices::getDateFormat(dates); // Automatic detection
}
if (!err) {
int posdate2 = m_csvMapping.indexOf(QStringLiteral("date2"));
if (dateFormat.isEmpty()) {
// Check if another "date" attribute exists
if (posdate2 != -1) {
m_csvMapping[posdate] = QLatin1String("");
err = importFile();
SKGENDTRANSACTION(m_importer->getDocument(), err)
return err;
}
err.setReturnCode(ERR_FAIL).setMessage(i18nc("Error message", "Date format not supported"));
} else {
// Disable other date columns
if (posdate2 != -1 && posdate2 != posdate) {
m_csvMapping[posdate2] = QLatin1String("");
}
}
}
IFOKDO(err, m_importer->getDocument()->sendMessage(i18nc("An information message", "Import of '%1' with code '%2' and date format '%3'", m_importer->getFileName().toDisplayString(), m_importer->getCodec(), dateFormat)))
// Step 2 done
IFOKDO(err, m_importer->getDocument()->stepForward(2))
// Treat all lines
IFOK(err) {
int nb2 = lines.size();
err = m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Import step", "Import operations"), nb2);
// Save last mapping used in a settings
QString mappingDesc;
int nbMap = m_csvMapping.count();
for (int i = 0; i < nbMap; ++i) {
if (i != 0) {
mappingDesc += '|';
}
mappingDesc += m_csvMapping.at(i);
}
IFOKDO(err, m_importer->getDocument()->setParameter(QStringLiteral("SKG_LAST_CSV_MAPPING_USED"), mappingDesc))
SKGUnitObject defUnit;
SKGAccountObject defAccount;
QMap<int, SKGOperationObject> mapGroup;
QMap<int, SKGOperationObject> mapOperation;
bool noUnitColumn = (m_csvMapping.indexOf(QStringLiteral("unit")) == -1);
bool noAccountColumn = (m_csvMapping.indexOf(QStringLiteral("account")) == -1);
bool emptyAccount = false;
for (int i = 0; !err && i < nb2; ++i) {
QString currentCategory;
SKGOperationObject currentOperation(m_importer->getDocument());
SKGSubOperationObject currentSubOperation(m_importer->getDocument());
// Valuate mandatory attribute with default value
if (noUnitColumn && i == 0) {
err = m_importer->getDefaultUnit(defUnit);
}
IFOKDO(err, currentOperation.setUnit(defUnit))
if (!err && noAccountColumn) {
err = m_importer->getDefaultAccount(defAccount);
if (i == 0) {
emptyAccount = (defAccount.getNbOperation() == 0);
}
IFOKDO(err, currentOperation.setParentAccount(defAccount))
}
const QString& line = lines.at(i);
QString skg_op_original_amount;
QStringList atts = SKGServices::splitCSVLine(line, getCSVSeparator(line));
int nbcol = m_csvMapping.count();
if (atts.count() < nbcol) {
if (i == nb2 - 1) {
// This is a footer (see 408284)
break;
}
err = SKGError(ERR_INVALIDARG, i18nc("Error message", "Invalid number of columns in line %1. Expected %2. Found %3.",
headerIndex + i + 1, nbcol, atts.count()));
}
QString linecleaned;
for (int z = 0; !err && z < nbcol; ++z) {
if (!m_csvMapping[z].isEmpty()) {
if (!linecleaned.isEmpty()) {
linecleaned += getCSVSeparator();
}
linecleaned += atts[z];
}
}
QByteArray hash = QCryptographicHash::hash(linecleaned.toUtf8(), QCryptographicHash::Md5);
int initialBalance = 0;
int idgroup = 0;
int idtransaction = 0;
QStringList propertiesAtt;
QStringList propertiesVal;
double sign = (modeAutoCreditDebit ? -1.0 : 1.0);
bool amountSet = false;
for (int c = 0; !err && c < nbcol; ++c) {
QString col = m_csvMapping[c];
if (!col.isEmpty()) {
QString val;
if (c >= 0 && c < atts.count()) {
val = atts.at(c).trimmed();
}
if (col == QStringLiteral("date") || col == QStringLiteral("date1") || col == QStringLiteral("date2")) {
QDate d = SKGServices::stringToTime(SKGServices::dateToSqlString(val.remove(QStringLiteral(" 00:00:00")), dateFormat)).date();
err = currentOperation.setDate(d);
IFOKDO(err, currentSubOperation.setDate(d))
if (val == QStringLiteral("0000-00-00")) {
initialBalance = 1;
}
} else if (col == QStringLiteral("number")) {
if (!val.isEmpty()) {
err = currentOperation.setNumber(val);
}
} else if (col == QStringLiteral("mode")) {
if (val == QStringLiteral("1")) {
val = i18nc("An operation mode", "Transfer");
} else if (val == QStringLiteral("2")) {
val = i18nc("An operation mode", "Direct debit");
} else if (val == QStringLiteral("3")) {
val = i18nc("An operation mode", "Check");
} else if (val == QStringLiteral("4")) {
val = i18nc("An operation mode", "Deposit");
} else if (val == QStringLiteral("5")) {
val = i18nc("An operation mode", "Payback");
} else if (val == QStringLiteral("6")) {
val = i18nc("An operation mode", "Withdrawal");
} else if (val == QStringLiteral("7")) {
val = i18nc("An operation mode", "Card");
} else if (val == QStringLiteral("8")) {
val = i18nc("An operation mode", "Loan payment");
} else if (val == QStringLiteral("9")) {
val = i18nc("An operation mode", "Subscription");
} else if (val == QStringLiteral("0")) {
val = QString();
} else if (val == QStringLiteral("10")) {
val = i18nc("An operation mode", "Cash deposit");
} else if (val == QStringLiteral("11")) {
val = i18nc("An operation mode", "Card summary");
} else if (val == QStringLiteral("12")) {
val = i18nc("An operation mode", "Deferred card");
}
err = currentOperation.setMode(val);
} else if (col == QStringLiteral("payee")) {
SKGPayeeObject payeeObj;
err = SKGPayeeObject::createPayee(m_importer->getDocument(), val, payeeObj);
IFOKDO(err, currentOperation.setPayee(payeeObj))
} else if (col == QStringLiteral("comment")) {
QString comment = currentOperation.getComment();
if (!comment.isEmpty()) {
comment += ' ';
}
comment += val;
err = currentOperation.setComment(comment);
IFOKDO(err, currentSubOperation.setComment(comment))
} else if (col == QStringLiteral("status")) {
err = currentOperation.setStatus(val == QStringLiteral("C") || val == QStringLiteral("Y") ? SKGOperationObject::CHECKED : val == QStringLiteral("P") ? SKGOperationObject::POINTED : SKGOperationObject::NONE);
} else if (col == QStringLiteral("bookmarked")) {
err = currentOperation.bookmark(val == QStringLiteral("Y"));
} else if (col == QStringLiteral("idgroup")) {
idgroup = SKGServices::stringToInt(val);
} else if (col == QStringLiteral("idtransaction")) {
idtransaction = SKGServices::stringToInt(val);
} else if (col == QStringLiteral("amount")) {
if (!val.isEmpty() && SKGServices::stringToDouble(val) != 0.0 && !amountSet) {
amountSet = true;
if (m_csvMapping.contains(QStringLiteral("quantity"))) {
// 209705 vvvv
skg_op_original_amount = val;
// 209705 ^^^^
} else {
err = currentSubOperation.setQuantity(sign * SKGServices::stringToDouble(val));
}
} else if (modeAutoCreditDebit) {
sign = 1.0; // Next one will be considered as a credit
}
} else if (col == QStringLiteral("quantity")) {
err = currentSubOperation.setQuantity(SKGServices::stringToDouble(val));
} else if (col == QStringLiteral("sign")) {
if (QRegExp(m_importParameters.value(QStringLiteral("mapping_debit")), Qt::CaseInsensitive).indexIn(val) != -1) {
sign = -1;
double cval = currentSubOperation.getQuantity();
if (cval > 0) {
err = currentSubOperation.setQuantity(-cval);
}
}
} else if (col == QStringLiteral("unit")) {
// Looking for unit
SKGUnitObject unit(m_importer->getDocument());
if (val != defUnit.getName()) { // For performance
err = unit.setName(val);
IFOKDO(err, unit.setSymbol(val))
if (!err && unit.load().isFailed()) {
err = unit.save(false); // Save only
}
// This unit is now the default one, it is better for performance
defUnit = unit;
} else {
unit = defUnit;
}
SKGUnitValueObject unitval;
IFOKDO(err, unit.addUnitValue(unitval))
IFOK(err) {
int posAmount = m_csvMapping.indexOf(QStringLiteral("amount"));
int posQuantity = m_csvMapping.indexOf(QStringLiteral("quantity"));
if (posAmount != -1 && posQuantity != -1) {
err = unitval.setQuantity(SKGServices::stringToDouble(atts.at(posAmount)) / SKGServices::stringToDouble(atts.at(posQuantity)));
} else {
err = unitval.setQuantity(1);
}
}
IFOKDO(err, unitval.setDate(now.date()))
IFOKDO(err, unitval.save())
IFOKDO(err, currentOperation.setUnit(unit))
} else if (col == QStringLiteral("account")) {
// Looking for account
if (val.isEmpty()) {
err = m_importer->getDefaultAccount(defAccount);
if (i == 0) {
emptyAccount = (defAccount.getNbOperation() == 0);
}
} else if (val != defAccount.getName()) { // For performance
SKGAccountObject account(m_importer->getDocument());
account.setName(val);
err = account.load();
IFKO(err) {
// Not found, we have to create one
SKGBankObject bank(m_importer->getDocument());
QString name = i18nc("Noun", "Bank for import %1", postFix);
err = bank.setName(name);
if (!err && bank.load().isFailed()) {
err = bank.save(false); // Save only
IFOKDO(err, m_importer->getDocument()->sendMessage(i18nc("An information message", "Default bank '%1' created for import", name)))
}
IFOKDO(err, bank.addAccount(account))
IFOKDO(err, account.setName(val))
if (!err && account.load().isFailed()) {
err = account.save(false); // Save only
}
}
// This account is now the default one, it is better for performance
defAccount = account;
}
IFOKDO(err, currentOperation.setParentAccount(defAccount))
} else if (col == QStringLiteral("category")) {
// Set Category
if (!val.isEmpty()) {
// Prepare val
val.replace('/', OBJECTSEPARATOR);
val.replace(':', OBJECTSEPARATOR);
val.replace(',', OBJECTSEPARATOR);
val.replace(';', OBJECTSEPARATOR);
// Get previous category
if (!currentCategory.isEmpty()) {
val = currentCategory % OBJECTSEPARATOR % val;
}
currentCategory = val;
// Create and set category
SKGCategoryObject Category;
err = SKGCategoryObject::createPathCategory(m_importer->getDocument(), val, Category);
IFOKDO(err, currentSubOperation.setCategory(Category))
IFOK(err) {
if (m_csvMapping.indexOf(QStringLiteral("payee")) == -1) {
SKGPayeeObject payeeObj;
QString p = m_importer->getDocument()->getCategoryForPayee(val, false);
err = SKGPayeeObject::createPayee(m_importer->getDocument(), p, payeeObj);
IFOKDO(err, currentOperation.setPayee(payeeObj))
}
}
}
} else {
// A property
propertiesAtt.push_back(col);
propertiesVal.push_back(val);
}
}
}
if (!err && (initialBalance != 0)) {
// Specific values for initial balance
err = currentOperation.setStatus(SKGOperationObject::CHECKED);
IFOKDO(err, currentOperation.setAttribute(QStringLiteral("d_date"), QStringLiteral("0000-00-00")))
IFOKDO(err, currentSubOperation.setAttribute(QStringLiteral("d_date"), QStringLiteral("0000-00-00")))
}
IFOKDO(err, currentOperation.setImportID(hash.toHex()))
IFOK(err) {
if (idtransaction != 0) {
if (mapOperation.contains(idtransaction)) {
currentOperation = mapOperation[idtransaction];
skg_op_original_amount = QString();
} else {
err = currentOperation.save();
mapOperation[idtransaction] = currentOperation;
}
} else {
err = currentOperation.save(false); // Save only
}
}
if (!err && idgroup != 0) {
if (mapGroup.contains(idgroup)) {
err = currentOperation.setGroupOperation(mapGroup[idgroup]);
IFOKDO(err, currentOperation.save())
}
mapGroup[idgroup] = currentOperation;
}
IFOKDO(err, currentSubOperation.setParentOperation(currentOperation))
IFOKDO(err, currentSubOperation.save(false, false))
// 209705 vvvv
if (!err && !skg_op_original_amount.isEmpty()) {
err = currentOperation.setProperty(QStringLiteral("SKG_OP_ORIGINAL_AMOUNT"), skg_op_original_amount);
}
// 209705 ^^^^
// Add properties
int nbp = propertiesAtt.count();
for (int p = 0; !err && p < nbp; ++p) {
err = currentOperation.setProperty(propertiesAtt.at(p), propertiesVal.at(p));
}
if (!err && i % 500 == 0) {
err = m_importer->getDocument()->executeSqliteOrder(QStringLiteral("ANALYZE"));
}
IFOKDO(err, m_importer->getDocument()->stepForward(i + 1))
}
IFOK(err) {
QString balance = m_importParameters.value(QStringLiteral("balance"));
if (!balance.isEmpty()) {
if (emptyAccount) {
// Current amount
double currentAmount = defAccount.getAmount(QDate::currentDate());
// Update account
IFOKDO(err, defAccount.setInitialBalance(SKGServices::stringToDouble(balance) - currentAmount, defUnit))
IFOKDO(err, defAccount.save())
IFOKDO(err, m_importer->getDocument()->sendMessage(i18nc("An information message", "The initial balance of '%1' has been set", defAccount.getName()), SKGDocument::Warning))
} else {
m_importer->getDocument()->sendMessage(i18nc("An information message", "The initial balance of '%1' has not been set because some operations are already existing", defAccount.getName()));
}
}
}
SKGENDTRANSACTION(m_importer->getDocument(), err)
// Lines treated
IFOKDO(err, m_importer->getDocument()->stepForward(3))
}
}
}
}
SKGENDTRANSACTION(m_importer->getDocument(), err)
return err;
}
bool SKGImportPluginCsv::isExportPossible()
{
SKGTRACEINFUNC(10)
return (m_importer == nullptr ? true : m_importer->getFileNameExtension() == QStringLiteral("CSV"));
}
SKGError SKGImportPluginCsv::exportFile()
{
if (m_importer == nullptr) {
return SKGError(ERR_ABORT, i18nc("Error message", "Invalid parameters"));
}
SKGError err;
SKGTRACEINFUNCRC(2, err)
auto listUUIDs = SKGServices::splitCSVLine(m_exportParameters.value(QStringLiteral("uuid_of_selected_accounts_or_operations")));
QString wc;
for (const auto& uuid : listUUIDs) {
auto items = SKGServices::splitCSVLine(uuid, '-');
if (items.at(1) == QStringLiteral("operation")) {
if (!wc.isEmpty()) {
wc += QLatin1String(" OR ");
}
wc += " i_OPID=" + items.at(0);
} else if (items.at(1) == QStringLiteral("account")) {
if (!wc.isEmpty()) {
wc += QLatin1String(" OR ");
}
wc += " rd_account_id=" + items.at(0);
}
}
if (wc.isEmpty()) {
wc = QStringLiteral("1=1");
} else {
IFOKDO(err, m_importer->getDocument()->sendMessage(i18nc("An information message", "Only selected accounts and operations have been exported")))
}
// Open file
QSaveFile file(m_importer->getLocalFileName(false));
if (!file.open(QIODevice::WriteOnly)) {
err.setReturnCode(ERR_INVALIDARG).setMessage(i18nc("Error message", "Save file '%1' failed", m_importer->getFileName().toDisplayString()));
} else {
QTextStream out(&file);
if (!m_importer->getCodec().isEmpty()) {
out.setCodec(m_importer->getCodec().toLatin1().constData());
}
err = m_importer->getDocument()->dumpSelectSqliteOrder(
QStringLiteral("SELECT v.d_date as date, v.t_BANK as bank, v.t_ACCOUNT as account, v.t_number as number, v.t_mode as mode, "
"v.t_PAYEE as payee, v.t_REALCOMMENT as comment, PRINTF('%.'||u.i_nbdecimal||'f', v.f_REALQUANTITY) as quantity, "
"v.t_UNIT as unit, PRINTF('%.'||u.i_nbdecimal||'f', v.f_REALCURRENTAMOUNT) as amount, v.t_TYPEEXPENSE as sign, v.t_REALCATEGORY as category, v.t_status as status, "
"v.t_REALREFUND as tracker, v.t_bookmarked as bookmarked, v.i_SUBOPID id, v.i_OPID idtransaction, v.i_group_id idgroup "
"FROM v_suboperation_consolidated as v, unit as u WHERE v.rc_unit_id=u.id AND (") % wc % ") ORDER BY v.d_date, v.i_OPID, v.i_SUBOPID", &out, SKGServices::DUMP_CSV);
// Close file
file.commit();
}
return err;
}
QString SKGImportPluginCsv::getMimeTypeFilter() const
{
return "*.csv|" % i18nc("A file format", "CSV file");
}
SKGError SKGImportPluginCsv::importCSVUnit()
{
SKGError err;
SKGTRACEINFUNCRC(2, err)
if (m_importer->getDocument() != nullptr) {
// Begin transaction
err = m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Import step", "Import units"), 3);
IFOK(err) {
// File name is the name of the unit
QFileInfo fInfo(m_importer->getFileName().path());
QString unitName = fInfo.baseName();
// Default mapping
if (m_csvMapping.isEmpty()) {
err = setCSVMapping(nullptr);
IFOKDO(err, m_importer->getDocument()->sendMessage(i18nc("An information message", "Use automatic search of the columns")))
}
// Step 1 done
IFOKDO(err, m_importer->getDocument()->stepForward(1))
// Open file
IFOK(err) {
QFile file(m_importer->getLocalFileName());
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
err.setReturnCode(ERR_INVALIDARG).setMessage(i18nc("Error message", "Open file '%1' failed", m_importer->getFileName().toDisplayString()));
} else {
QTextStream stream(&file);
if (!m_importer->getCodec().isEmpty()) {
stream.setCodec(m_importer->getCodec().toLatin1().constData());
}
// Ignore useless lines
int headerIndex = getCSVHeaderIndex();
for (int i = 1; i <= headerIndex; ++i) {
stream.readLine();
}
// Get data column
QStringList dates;
QStringList lines;
int posdate = m_csvMapping.indexOf(QStringLiteral("date"));
if (posdate != -1) {
while (!stream.atEnd()) {
// Read line
QString line = stream.readLine().trimmed();
if (!line.isEmpty()) {
lines.push_back(line);
// Get date
QStringList field = SKGServices::splitCSVLine(line, getCSVSeparator(line));
if (posdate < field.count()) {
dates.push_back(field.at(posdate));
}
}
}
}
// close file
file.close();
// Select dateformat
QString dateFormat = SKGServices::getDateFormat(dates);
if (dateFormat.isEmpty()) {
err.setReturnCode(ERR_FAIL).setMessage(i18nc("Error message", "Date format not supported"));
}
IFOKDO(err, m_importer->getDocument()->sendMessage(i18nc("An information message", "Import of '%1' with codec '%2' and date format '%3'", m_importer->getFileName().toDisplayString(), m_importer->getCodec(), dateFormat)))
// Step 2 done
IFOKDO(err, m_importer->getDocument()->stepForward(2))
// Treat all lines
IFOK(err) {
int nb = lines.size();
err = m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Import step", "Import units"), nb);
// Save last mapping used in a settings
QString mappingDesc;
int nbMap = m_csvMapping.count();
for (int i = 0; i < nbMap; ++i) {
if (i != 0) {
mappingDesc += '|';
}
mappingDesc += m_csvMapping.at(i);
}
IFOKDO(err, m_importer->getDocument()->setParameter(QStringLiteral("SKG_LAST_CSV_UNIT_MAPPING_USED"), mappingDesc))
int posdate2 = m_csvMapping.indexOf(QStringLiteral("date"));
int posvalue = m_csvMapping.indexOf(QStringLiteral("amount"));
if (posdate2 != -1 && posvalue != -1) {
for (int i = 0; !err && i < nb; ++i) {
QStringList atts = SKGServices::splitCSVLine(lines.at(i), getCSVSeparator(lines.at(i)));
err = m_importer->getDocument()->addOrModifyUnitValue(unitName,
SKGServices::stringToTime(SKGServices::dateToSqlString(atts.at(posdate2), dateFormat)).date(),
SKGServices::stringToDouble(atts.at(posvalue)));
IFOKDO(err, m_importer->getDocument()->stepForward(i + 1))
}
}
SKGENDTRANSACTION(m_importer->getDocument(), err)
// Lines treated
IFOKDO(err, m_importer->getDocument()->stepForward(3))
}
}
}
}
SKGENDTRANSACTION(m_importer->getDocument(), err)
}
return err;
}
SKGError SKGImportPluginCsv::importCSVRule()
{
SKGError err;
SKGTRACEINFUNCRC(2, err)
if (m_importer->getDocument() != nullptr) {
// Begin transaction
err = m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Import step", "Import rules"), 3);
IFOK(err) {
// Default mapping
if (m_csvMapping.isEmpty()) {
err = setCSVMapping(nullptr);
IFOKDO(err, m_importer->getDocument()->sendMessage(i18nc("An information message", "Use automatic search of the columns")))
}
// Step 1 done
IFOKDO(err, m_importer->getDocument()->stepForward(1))
// Open file
IFOK(err) {
QFile file(m_importer->getLocalFileName());
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
err.setReturnCode(ERR_INVALIDARG).setMessage(i18nc("Error message", "Open file '%1' failed", m_importer->getFileName().toDisplayString()));
} else {
QTextStream stream(&file);
if (!m_importer->getCodec().isEmpty()) {
stream.setCodec(m_importer->getCodec().toLatin1().constData());
}
// Ignore useless lines
int headerIndex = getCSVHeaderIndex();
for (int i = 1; i <= headerIndex; ++i) {
stream.readLine();
}
// Get data column
QStringList lines;
while (!stream.atEnd()) {
// Read line
QString line = stream.readLine().trimmed();
if (!line.isEmpty()) {
lines.push_back(line);
}
}
// close file
file.close();
IFOKDO(err, m_importer->getDocument()->sendMessage(i18nc("An information message", "Import of '%1' with codec '%2'", m_importer->getFileName().toDisplayString(), m_importer->getCodec())))
// Step 2 done
IFOKDO(err, m_importer->getDocument()->stepForward(2))
// Treat all lines
IFOK(err) {
int nb = lines.size();
err = m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Import step", "Import rules"), nb);
// Save last mapping used in a settings
QString mappingDesc;
int nbMap = m_csvMapping.count();
for (int i = 0; i < nbMap; ++i) {
if (i != 0) {
mappingDesc += '|';
}
mappingDesc += m_csvMapping.at(i);
}
IFOKDO(err, m_importer->getDocument()->setParameter(QStringLiteral("SKG_LAST_CSV_RULE_MAPPING_USED"), mappingDesc))
int pospayee = m_csvMapping.indexOf(QStringLiteral("payee"));
int poscategory = m_csvMapping.indexOf(QStringLiteral("category"));
if (pospayee != -1 && poscategory != -1) {
for (int i = 0; !err && i < nb; ++i) {
QStringList atts = SKGServices::splitCSVLine(lines.at(i), getCSVSeparator(lines.at(i)));
SKGRuleObject oRule;
err = SKGRuleObject::createPayeeCategoryRule(m_importer->getDocument(), atts.at(pospayee), atts.at(poscategory), oRule);
IFOKDO(err, m_importer->getDocument()->stepForward(i + 1))
}
}
SKGENDTRANSACTION(m_importer->getDocument(), err)
// Lines treated
IFOKDO(err, m_importer->getDocument()->stepForward(3))
}
}
}
}
SKGENDTRANSACTION(m_importer->getDocument(), err)
}
return err;
}
#include <skgimportplugincsv.moc>
diff --git a/plugins/import/skrooge_import_csv/skgimportplugincsv.h b/plugins/import/skrooge_import_csv/skgimportplugincsv.h
index 6aaf42176..66f8ef0a7 100644
--- a/plugins/import/skrooge_import_csv/skgimportplugincsv.h
+++ b/plugins/import/skrooge_import_csv/skgimportplugincsv.h
@@ -1,154 +1,154 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGIMPORTPLUGINCSV_H
#define SKGIMPORTPLUGINCSV_H
/** @file
* This file is Skrooge plugin for CSV import / export.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgimportplugin.h"
/**
* This file is Skrooge plugin for CSV import / export.
*/
class SKGImportPluginCsv : public SKGImportPlugin
{
Q_OBJECT
Q_INTERFACES(SKGImportPlugin)
public:
/**
* Default constructor
* @param iImporter the parent importer
* @param iArg the arguments
*/
explicit SKGImportPluginCsv(QObject* iImporter, const QVariantList& iArg);
/**
* Default Destructor
*/
~SKGImportPluginCsv() override;
/**
* Set parameters for Import
* @param iParameters the parameters
*/
void setImportParameters(const QMap< QString, QString >& iParameters) override;
/**
* To know if import is possible with this plugin
*/
bool isImportPossible() override;
/**
* Import a file
* @return an object managing the error.
* @see SKGError
*/
SKGError importFile() override;
/**
* To know if export is possible with this plugin
* @return true or false
*/
bool isExportPossible() override;
/**
* Export a file
* @return an object managing the error.
* @see SKGError
*/
SKGError exportFile() override;
/**
* Return the mime type filter
* @return the mime type filter. Example: "*.csv|CSV file"
*/
QString getMimeTypeFilter() const override;
/**
* Import units
* @return an object managing the error.
* @see SKGError
*/
virtual SKGError importCSVUnit();
/**
* Import rules
* @return an object managing the error.
* @see SKGError
*/
virtual SKGError importCSVRule();
private:
Q_DISABLE_COPY(SKGImportPluginCsv)
/**
* Set the CSV mapping.
* A mapping is ordered list to described the mapping between the csv file and
* the operation object.
* List of supported key word:
* date
* number
* mode
* payee
* comment
* status
* bookmarked
* account
* category
* amount
* quantity
* sign
* unit
* This list is a list of operation attributes.
* @param iCSVMapping the mapping. nullptr to build automatically the CSV mapping.
* @return an object managing the error.
* @see SKGError
*/
virtual SKGError setCSVMapping(const QStringList* iCSVMapping);
/**
* Set the index of the header in the CSV file.
* @param iIndex the index. -1 to search automatically the index of the header.
* @return an object managing the error.
* @see SKGError
*/
virtual SKGError setCSVHeaderIndex(int iIndex = -1);
/**
* Get the index of the header in the CSV file.
* @return the index
*/
virtual int getCSVHeaderIndex();
/**
* Get the CSV separator
* @param iLine the line to split to find the separator is not determined yet.
* @return the separator
*/
virtual QChar getCSVSeparator(const QString& iLine = QString());
QStringList getCSVMappingFromLine(const QString& iLine);
QStringList m_csvMapping;
QChar m_csvSeparator;
int m_csvHeaderIndex;
};
#endif // SKGIMPORTPLUGINCSV_H
diff --git a/plugins/import/skrooge_import_gnc/CMakeLists.txt b/plugins/import/skrooge_import_gnc/CMakeLists.txt
index a8d200414..f5f5819bb 100644
--- a/plugins/import/skrooge_import_gnc/CMakeLists.txt
+++ b/plugins/import/skrooge_import_gnc/CMakeLists.txt
@@ -1,33 +1,33 @@
#***************************************************************************
#* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
#* *
#* 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 <http://www.gnu.org/licenses/> *
+#* along with this program. If not, see <https://www.gnu.org/licenses/> *
#***************************************************************************
MESSAGE( STATUS "..:: CMAKE PLUGIN_IMPORT_GNC ::..")
PROJECT(plugin_import_gnc)
LINK_DIRECTORIES (${LIBRARY_OUTPUT_PATH})
SET(skrooge_import_gnc_SRCS
skgimportplugingnc.cpp
)
ADD_LIBRARY(skrooge_import_gnc MODULE ${skrooge_import_gnc_SRCS})
TARGET_LINK_LIBRARIES(skrooge_import_gnc KF5::Parts KF5::Archive skgbasemodeler skgbasegui skgbankmodeler skgbankgui)
########### install files ###############
INSTALL(TARGETS skrooge_import_gnc DESTINATION ${KDE_INSTALL_QTPLUGINDIR})
INSTALL(FILES ${PROJECT_SOURCE_DIR}/org.kde.skrooge-import-gnc.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR})
diff --git a/plugins/import/skrooge_import_gnc/org.kde.skrooge-import-gnc.desktop b/plugins/import/skrooge_import_gnc/org.kde.skrooge-import-gnc.desktop
index d2756e989..07b2ef433 100644
--- a/plugins/import/skrooge_import_gnc/org.kde.skrooge-import-gnc.desktop
+++ b/plugins/import/skrooge_import_gnc/org.kde.skrooge-import-gnc.desktop
@@ -1,74 +1,74 @@
[Desktop Entry]
Name=Skrooge import GNC plugin
Name[bs]=Skrooge dodatak za GNC uvoz
Name[ca]=Connector d'importació de GNC de l'Skrooge
Name[ca@valencia]=Connector d'importació de GNC de l'Skrooge
Name[cs]=Modul Skrooge pro import GNC
Name[da]=Plugin til import af GNC til Skrooge
Name[de]=Skrooge-GNC-Importmodul
Name[el]=Skrooge import GNC plugin
Name[en_GB]=Skrooge import GNC plugin
Name[es]=Complemento de Skrooge de importación de GNC
Name[et]=Skrooge GNC impordi plugin
Name[fi]=Skroogen GNC-tuontiliitännäinen
-Name[fr]=Module externe de Skrooge pour l'importation « GNC »
+Name[fr]=Module externe de Skrooge pour l'importation « GNC »
Name[gl]=Complemento de importación de GNC a Skrooge
Name[hu]=Skrooge GNC importáló bővítmény
Name[it]=Estensione di Skrooge per l'importazione GNC
Name[lt]=Skrooge GNC importavimo papildinys
Name[nb]=Skrooge-modul for GNC-import
Name[nl]=Plugin van Skrooge voor importeren van GNC
Name[pl]=Wtyczka importu GNC dla Skrooge
Name[pt]='Plugin' de importação de GNC para o Skrooge
Name[pt_BR]=Plugin de importação de GNC para o Skrooge
Name[ru]=Модуль импорта файлов GNC
Name[sk]=Skrooge plugin GNC import
Name[sv]=Skrooge GNC-importinsticksprogram
Name[tr]=Skrooge GNC içe aktarma eklentisi
Name[uk]=Додаток імпортування GNC до Skrooge
Name[x-test]=xxSkrooge import GNC pluginxx
Name[zh_TW]=Skrooge 匯入 GNC 外掛程式
Comment=A Skrooge plugin to import GNC files
Comment[bs]=Skrooge dodatak za uvoz GNC datoteka
Comment[ca]=Un connector de l'Skrooge per importar fitxers GNC
Comment[ca@valencia]=Un connector de l'Skrooge per importar fitxers GNC
Comment[cs]=Modul Skrooge pro import souborů GNC
Comment[da]=Et Skrooge-plugin til at importere GNC-filer
Comment[de]=Ein Skrooge-Modul zum Import von GNC-Dateien
Comment[el]=Ένα πρόσθετο του Skrooge για την εισαγωγή αρχείων GNC
Comment[en_GB]=A Skrooge plugin to import GNC files
Comment[es]=Complemento de Skrooge para importar archivos GNC
Comment[et]=Skrooge plugin GNC-failide importimiseks
Comment[fi]=Skroogen GNC-tiedostojen tuontiliitännäinen
-Comment[fr]=Un module externe de Skrooge pour l'importation de fichiers « GNC »
+Comment[fr]=Un module externe de Skrooge pour l'importation de fichiers « GNC »
Comment[gl]=Un complemento de Skrooge para importar ficheiros GNC.
Comment[hu]=Egy Skrooge bővítmény GNC fájlok importálásához
Comment[it]=Un'estensione di Skrooge per importare i file GNC
Comment[lt]=Skrooge GNC failų importavimo papildinys
Comment[nb]=En Skrooge-modul for å importere GNC-filer
Comment[nl]=Een Skrooge-plugin voor het importeren van GNC-bestanden
Comment[pl]=Wtyczka Skrooge do importu plików GNC
Comment[pt]=Um 'plugin' do Skrooge para importar ficheiros GNC
Comment[pt_BR]=Um plugin do Skrooge para importar arquivos GNC
Comment[ru]=Модуль импорта файлов GNC
Comment[sk]=Skrooge plugin na import GNC súborov
Comment[sv]=Ett insticksprogram till Skrooge för att importera GNC-filer
Comment[tr]=GNC dosyalarını içe aktarmak için Skrooge eklentisi
Comment[uk]=Додаток до Skrooge для імпортування даних з файлів GNC
Comment[x-test]=xxA Skrooge plugin to import GNC filesxx
Comment[zh_TW]=Skrooge 匯入 GNC 檔用的外掛程式
Encoding=UTF-8
Icon=skrooge
Type=Service
X-KDE-ServiceTypes=SKG IMPORT/Plugin
X-KDE-Library=skrooge_import_gnc
X-Krunner-ID=Skrooge import GNC plugin
X-KDE-PluginInfo-Author=Stephane MANKOWSKI
X-KDE-PluginInfo-Email=stephane@mankowski.fr
X-KDE-PluginInfo-Name=skrooge_import_gnc
X-KDE-PluginInfo-Version=1.0
-X-KDE-PluginInfo-Website=http://skrooge.org/
+X-KDE-PluginInfo-Website=https://skrooge.org/
X-KDE-PluginInfo-Category=Plugins
X-KDE-PluginInfo-Depends=
X-KDE-PluginInfo-License=GPL
X-KDE-PluginInfo-EnabledByDefault=true
diff --git a/plugins/import/skrooge_import_gnc/skgimportplugingnc.cpp b/plugins/import/skrooge_import_gnc/skgimportplugingnc.cpp
index 7bc9c5877..b27e0f47d 100644
--- a/plugins/import/skrooge_import_gnc/skgimportplugingnc.cpp
+++ b/plugins/import/skrooge_import_gnc/skgimportplugingnc.cpp
@@ -1,678 +1,678 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is Skrooge plugin for GNC import / export.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgimportplugingnc.h"
#include <kcompressiondevice.h>
#include <klocalizedstring.h>
#include <kpluginfactory.h>
#include <qdom.h>
#include <cmath>
#include "skgbankincludes.h"
#include "skgimportexportmanager.h"
#include "skgobjectbase.h"
#include "skgpayeeobject.h"
#include "skgservices.h"
#include "skgtraces.h"
/**
* This plugin factory.
*/
K_PLUGIN_FACTORY(SKGImportPluginGncFactory, registerPlugin<SKGImportPluginGnc>();)
SKGImportPluginGnc::SKGImportPluginGnc(QObject* iImporter, const QVariantList& iArg)
: SKGImportPlugin(iImporter)
{
SKGTRACEINFUNC(10)
Q_UNUSED(iArg)
}
SKGImportPluginGnc::~SKGImportPluginGnc()
= default;
bool SKGImportPluginGnc::isImportPossible()
{
SKGTRACEINFUNC(10)
if (m_importer == nullptr) {
return true;
}
QString extension = m_importer->getFileNameExtension();
return (extension == QStringLiteral("UNCOMPRESSED") || extension == QStringLiteral("GNUCASH") || extension == QStringLiteral("GNC"));
}
SKGError SKGImportPluginGnc::importFile()
{
if (m_importer == nullptr) {
return SKGError(ERR_ABORT, i18nc("Error message", "Invalid parameters"));
}
SKGError err;
SKGTRACEINFUNCRC(2, err)
// Open file
KCompressionDevice file(m_importer->getLocalFileName(), KCompressionDevice::GZip);
if (!file.open(QIODevice::ReadOnly)) {
err.setReturnCode(ERR_INVALIDARG).setMessage(i18nc("Error message", "Open file '%1' failed", m_importer->getFileName().toDisplayString()));
} else {
QDomDocument doc;
// Set the file without uncompression
QString errorMsg;
int errorLine = 0;
int errorCol = 0;
bool contentOK = doc.setContent(file.readAll(), &errorMsg, &errorLine, &errorCol);
file.close();
if (!contentOK) {
err.setReturnCode(ERR_ABORT).setMessage(i18nc("Error message", "%1-%2: '%3'", errorLine, errorCol, errorMsg)).addError(ERR_INVALIDARG, i18nc("Error message", "Invalid XML content in file '%1'", m_importer->getFileName().toDisplayString()));
} else {
// Get root
QDomElement docElem = doc.documentElement();
// // Get book
QDomElement book = docElem.firstChildElement(QStringLiteral("gnc:book"));
if (book.isNull()) {
book = docElem;
}
if (book.isNull()) {
err = SKGError(ERR_INVALIDARG, i18nc("Error message", "Invalid XML content in file '%1'", m_importer->getFileName().toDisplayString()));
} else {
QMap<QString, SKGUnitObject> mapUnitIdUnit;
err = m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Import step", "Import %1 file", "GNC"), 6);
IFOK(err) {
// Step 1-Get units
SKGUnitObject defaultUnit;
{
QDomNodeList unitList = book.elementsByTagName(QStringLiteral("gnc:commodity"));
int nbUnit = unitList.count();
err = m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Import step", "Import units"), nbUnit);
for (int i = 0; !err && i < nbUnit; ++i) {
QDomElement unit = unitList.at(i).toElement();
QDomElement unitName = unit.firstChildElement(QStringLiteral("cmdty:id"));
QDomElement unitSpace = unit.firstChildElement(QStringLiteral("cmdty:space"));
if (!unitName.isNull() && !unitSpace.isNull()) {
SKGUnitObject unitObj(m_importer->getDocument());
if (unitSpace.text() == QStringLiteral("ISO4217")) {
// We try a creation
SKGUnitObject::createCurrencyUnit(m_importer->getDocument(), unitName.text(), unitObj);
}
if (!err && !unitObj.exist()) {
// Creation of unit
err = unitObj.setName(unitName.text());
IFOKDO(err, unitObj.setSymbol(unitName.text()))
IFOKDO(err, unitObj.setType(SKGUnitObject::SHARE))
IFOKDO(err, unitObj.save())
}
if (!err && !defaultUnit.exist()) {
defaultUnit = unitObj;
}
mapUnitIdUnit[unitName.text()] = unitObj;
}
IFOKDO(err, m_importer->getDocument()->stepForward(i + 1))
}
SKGENDTRANSACTION(m_importer->getDocument(), err)
}
IFOKDO(err, m_importer->getDocument()->stepForward(1))
// Step 2-Get accounts and categories
SKGAccountObject gnucashTemporaryAccount(m_importer->getDocument());
QMap<QString, QString> mapIdName;
QMap<QString, QChar> mapIdType;
QMap<QString, SKGUnitObject> mapIdUnit;
QMap<QString, SKGAccountObject> mapIdAccount;
QMap<QString, SKGCategoryObject> mapIdCategory;
// Create bank and temporary account for gnucash import
SKGBankObject bank(m_importer->getDocument());
IFOKDO(err, m_importer->getDocument()->addOrModifyAccount(QStringLiteral("GNUCASH-TEMPORARY-ACCOUNT"), QString(), QStringLiteral("GNUCASH")))
IFOKDO(err, bank.setName(QStringLiteral("GNUCASH")))
IFOKDO(err, bank.load())
IFOKDO(err, gnucashTemporaryAccount.setName(QStringLiteral("GNUCASH-TEMPORARY-ACCOUNT")))
IFOKDO(err, gnucashTemporaryAccount.load())
{
// Create accounts
QDomNodeList accountList = book.elementsByTagName(QStringLiteral("gnc:account"));
int nbAccount = accountList.count();
IFOKDO(err, m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Import step", "Import banks and accounts"), nbAccount))
for (int i = 0; !err && i < nbAccount; ++i) {
QDomElement account = accountList.at(i).toElement();
QDomElement parentNode = account.parentNode().toElement();
if (parentNode.tagName() != QStringLiteral("gnc:template-transactions")) {
QDomElement accountId = account.firstChildElement(QStringLiteral("act:id"));
QDomElement accountName = account.firstChildElement(QStringLiteral("act:name"));
QDomElement accountType = account.firstChildElement(QStringLiteral("act:type"));
QDomElement accountCode = account.firstChildElement(QStringLiteral("act:code"));
QDomElement accountDescription = account.firstChildElement(QStringLiteral("act:description"));
QString realAccountName = accountName.text();
if (!accountId.isNull() && !accountType.isNull() && !realAccountName.isEmpty()) {
QString type = accountType.text();
if (type == QStringLiteral("INCOME") || type == QStringLiteral("EXPENSE")) {
// It is a category
QString fullName = realAccountName;
QDomElement accountParent = account.firstChildElement(QStringLiteral("act:parent"));
if (!err && !accountParent.isNull() && mapIdType[accountParent.text()] == 'C') {
fullName = mapIdName[accountParent.text()] % OBJECTSEPARATOR % fullName;
}
SKGCategoryObject catObj;
err = SKGCategoryObject::createPathCategory(m_importer->getDocument(), fullName, catObj);
mapIdCategory[accountId.text()] = catObj;
mapIdType[accountId.text()] = 'C'; // Memorize an account
} else if (type == QStringLiteral("BANK") ||
type == QStringLiteral("CREDIT") ||
type == QStringLiteral("STOCK") ||
type == QStringLiteral("ASSET") ||
type == QStringLiteral("LIABILITY") ||
type == QStringLiteral("RECEIVABLE") ||
type == QStringLiteral("PAYABLE") ||
type == QStringLiteral("TRADING") ||
type == QStringLiteral("CREDITCARD") ||
type == QStringLiteral("CASH") ||
type == QStringLiteral("MUTUAL")) {
// It is a real account
SKGAccountObject act(m_importer->getDocument());
err = bank.addAccount(act);
IFOKDO(err, act.setName(realAccountName))
int index = 1;
while (!err && act.exist()) {
index++;
realAccountName = accountName.text() % " (" % SKGServices::intToString(index) % ')';
err = act.setName(realAccountName);
}
if (!err && !accountCode.isNull()) {
err = act.setNumber(accountCode.text());
}
if (!err && !accountDescription.isNull()) {
err = act.setComment(accountDescription.text());
}
IFOKDO(err, act.setType(type == QStringLiteral("ASSET") ? SKGAccountObject::ASSETS :
type == QStringLiteral("STOCK") || type == QStringLiteral("MUTUAL") || type == QStringLiteral("RECEIVABLE") || type == QStringLiteral("PAYABLE") || type == QStringLiteral("TRADING") ? SKGAccountObject::INVESTMENT :
type == QStringLiteral("CASH") ? SKGAccountObject::WALLET :
type == QStringLiteral("LIABILITY") ? SKGAccountObject::LOAN :
type == QStringLiteral("CREDIT") ? SKGAccountObject::CREDITCARD : SKGAccountObject::CURRENT))
IFOKDO(err, act.save())
// Change parent bank in case of ASSETS
if (act.getType() == SKGAccountObject::WALLET) {
// Get blank bank
SKGBankObject blankBank(m_importer->getDocument());
IFOKDO(err, blankBank.setName(QString()))
if (blankBank.exist()) {
err = blankBank.load();
} else {
err = blankBank.save();
}
IFOKDO(err, act.setBank(blankBank))
IFOKDO(err, act.save())
}
mapIdAccount[accountId.text()] = act;
mapIdType[accountId.text()] = 'A'; // Memorize an account
QDomNodeList accountUnits = account.elementsByTagName(QStringLiteral("cmdty:id"));
if (!err && (accountUnits.count() != 0)) {
mapIdUnit[accountId.text()] = mapUnitIdUnit[accountUnits.at(0).toElement().text()];
}
} else if (type == QStringLiteral("EQUITY")) {
mapIdType[accountId.text()] = 'E'; // Memorize an account
} else {
mapIdType[accountId.text()] = ' '; // Memorize an account
}
mapIdName[accountId.text()] = realAccountName;
}
}
IFOKDO(err, m_importer->getDocument()->stepForward(i + 1))
}
SKGENDTRANSACTION(m_importer->getDocument(), err)
}
IFOKDO(err, m_importer->getDocument()->stepForward(2))
// Step 3- Get operations
QMap<QString, SKGOperationObject> mapIdScheduledOperation;
{
QDomNodeList operationsList = book.elementsByTagName(QStringLiteral("gnc:transaction"));
int nbOperations = operationsList.count();
IFOKDO(err, m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Import step", "Import operations"), nbOperations))
QVector<SubOpInfo> suboperationsList;
for (int i = 0; !err && i < nbOperations; ++i) {
QDomElement operation = operationsList.at(i).toElement();
QDomElement operationId = operation.firstChildElement(QStringLiteral("trn:id"));
QDomElement operationDate = operation.firstChildElement(QStringLiteral("trn:date-posted"));
QDomElement operationNumber = operation.firstChildElement(QStringLiteral("trn:num"));
QDomElement operationPayee = operation.firstChildElement(QStringLiteral("trn:description"));
QDomElement operationSlots = operation.firstChildElement(QStringLiteral("trn:slots"));
SKGOperationObject operationObj;
err = gnucashTemporaryAccount.addOperation(operationObj, true);
if (!err && !operationDate.isNull()) {
// Format 2007-01-13 00:00:00 +0100
err = operationObj.setDate(QDate::fromString(operationDate.text().left(10), QStringLiteral("yyyy-MM-dd")));
}
if (!err && !operationNumber.isNull()) {
err = operationObj.setNumber(operationNumber.text());
}
if (!err && !operationPayee.isNull()) {
SKGPayeeObject payeeObject;
err = SKGPayeeObject::createPayee(m_importer->getDocument(), operationPayee.text(), payeeObject);
IFOKDO(err, operationObj.setPayee(payeeObject))
}
IFOKDO(err, operationObj.setImported(true))
IFOKDO(err, operationObj.setImportID("GNC-" % operationId.text()))
IFOKDO(err, operationObj.setUnit(defaultUnit))
IFOK(err) {
QDomElement parentNode = operation.parentNode().toElement();
err = operationObj.setTemplate(parentNode.tagName() == QStringLiteral("gnc:template-transactions"));
}
if (!operationSlots.isNull()) {
QDomNodeList slotList = operationSlots.elementsByTagName(QStringLiteral("slot"));
int nbSlots = slotList.count();
for (int k = 0; !err && k < nbSlots; ++k) {
QDomElement slot = slotList.at(k).toElement();
QDomElement key = slot.firstChildElement(QStringLiteral("slot:key"));
QDomElement value = slot.firstChildElement(QStringLiteral("slot:value"));
if (!key.isNull() && !value.isNull()) {
if (key.text() == QStringLiteral("notes")) {
err = operationObj.setComment(value.text());
}
}
}
}
IFOKDO(err, operationObj.save())
// Get splits
bool parentSet = false;
QDomElement splits = operation.firstChildElement(QStringLiteral("trn:splits"));
int nbSuboperations = 0;
suboperationsList.resize(0);
{
QDomNodeList suboperationsListTmp = splits.elementsByTagName(QStringLiteral("trn:split"));
nbSuboperations = suboperationsListTmp.count();
int nbRealSuboperations = 0;
for (int j = 0; !err && j < nbSuboperations; ++j) {
SubOpInfo info;
info.subOp = suboperationsListTmp.at(j).toElement();
info.account = info.subOp.firstChildElement(QStringLiteral("split:account"));
info.value = 0;
QStringList vals = SKGServices::splitCSVLine(info.subOp.firstChildElement(QStringLiteral("split:quantity")).text(), '/');
if (vals.count() == 1) {
info.value = SKGServices::stringToDouble(vals.at(0));
} else if (vals.count() == 2) {
info.value = SKGServices::stringToDouble(vals.at(0)) / SKGServices::stringToDouble(vals.at(1));
}
QDomElement suboperationSlots = info.subOp.firstChildElement(QStringLiteral("split:slots"));
if (!suboperationSlots.isNull()) {
QDomNodeList slotList = suboperationSlots.elementsByTagName(QStringLiteral("slot"));
int nbSlots = slotList.count();
for (int k = 0; !err && k < nbSlots; ++k) {
QDomElement slot = slotList.at(k).toElement();
QDomElement key = slot.firstChildElement(QStringLiteral("slot:key"));
QDomElement value = slot.firstChildElement(QStringLiteral("slot:value"));
if (!key.isNull() && !value.isNull()) {
if (key.text() == QStringLiteral("sched-xaction")) {
// This is a scheduled operation
QDomNodeList scheduledSlotList = value.elementsByTagName(QStringLiteral("slot"));
int nbscheduledSlotList = scheduledSlotList.count();
for (int k2 = 0; !err && k2 < nbscheduledSlotList; ++k2) {
QDomElement slot2 = scheduledSlotList.at(k2).toElement();
QDomElement key2 = slot2.firstChildElement(QStringLiteral("slot:key"));
QDomElement value2 = slot2.firstChildElement(QStringLiteral("slot:value"));
if (!key2.isNull() && !value2.isNull()) {
if (key2.text() == QStringLiteral("account")) {
mapIdScheduledOperation[info.account.text()] = operationObj;
info.account = value2;
} else if (key2.text() == QStringLiteral("debit-formula") && !value2.text().isEmpty()) {
QStringList vals2 = SKGServices::splitCSVLine(value2.text(), '/');
if (vals2.count() == 1) {
info.value = SKGServices::stringToDouble(vals2.at(0));
} else if (vals2.count() == 2) {
info.value = SKGServices::stringToDouble(vals2.at(0)) / SKGServices::stringToDouble(vals2.at(1));
}
} else if (key2.text() == QStringLiteral("credit-formula") && !value2.text().isEmpty()) {
QStringList vals2 = SKGServices::splitCSVLine(value2.text(), '/');
if (vals2.count() == 1) {
info.value = -SKGServices::stringToDouble(vals2.at(0));
} else if (vals2.count() == 2) {
info.value = -SKGServices::stringToDouble(vals2.at(0)) / SKGServices::stringToDouble(vals2.at(1));
}
}
}
}
}
}
}
}
if (!std::isnan(info.value)) {
QChar accountType = mapIdType[info.account.text()];
if (accountType == 'C') {
suboperationsList.push_front(info);
} else {
suboperationsList.push_back(info);
}
++nbRealSuboperations;
}
}
nbSuboperations = nbRealSuboperations;
}
SKGSubOperationObject suboperationObj;
for (int j = 0; !err && j < nbSuboperations; ++j) {
SubOpInfo suboperationInfo = suboperationsList.at(j);
QDomElement suboperation = suboperationInfo.subOp.toElement();
QDomElement suboperationReconciled = suboperation.firstChildElement(QStringLiteral("split:reconciled-state"));
QDomElement suboperationMemo = suboperation.firstChildElement(QStringLiteral("split:memo"));
QDomElement suboperationAction = suboperation.firstChildElement(QStringLiteral("split:action"));
// Set operation attribute
if (!suboperationReconciled.isNull() && operationObj.getStatus() == SKGOperationObject::NONE) {
QString val = suboperationReconciled.text();
IFOKDO(err, operationObj.setStatus(val == QStringLiteral("c") ? SKGOperationObject::POINTED : val == QStringLiteral("y") ? SKGOperationObject::CHECKED : SKGOperationObject::NONE))
}
if (!err && !suboperationMemo.isNull() && operationObj.getComment().isEmpty()) {
err = operationObj.setComment(suboperationMemo.text());
}
if (!err && !suboperationAction.isNull() && operationObj.getMode().isEmpty()) {
err = operationObj.setMode(suboperationAction.text());
}
IFOKDO(err, operationObj.save())
QChar accountType = mapIdType[suboperationInfo.account.text()];
if (accountType == 'C') {
// It is a split on category
SKGCategoryObject cat = mapIdCategory[suboperationInfo.account.text()];
double q = -suboperationInfo.value;
if (!err && (!suboperationObj.exist() || suboperationObj.getQuantity() != q)) {
err = operationObj.addSubOperation(suboperationObj);
}
IFOKDO(err, suboperationObj.setQuantity(q))
IFOKDO(err, suboperationObj.setCategory(cat))
if (!err && !suboperationMemo.isNull()) {
err = suboperationObj.setComment(suboperationMemo.text());
}
IFOKDO(err, suboperationObj.save())
} else if (accountType == 'E') {
// Set as initial balance
IFOKDO(err, operationObj.setAttribute(QStringLiteral("d_date"), QStringLiteral("0000-00-00")))
IFOKDO(err, operationObj.setStatus(SKGOperationObject::CHECKED))
IFOKDO(err, operationObj.save())
IFOKDO(err, suboperationObj.setAttribute(QStringLiteral("d_date"), QStringLiteral("0000-00-00")))
IFOKDO(err, suboperationObj.save())
} else if (accountType == 'A') {
// It is a transfer of account
SKGAccountObject act(m_importer->getDocument());
IFOKDO(err, act.setName(mapIdName[suboperationInfo.account.text()]))
IFOKDO(err, act.load())
// Set Unit
SKGUnitObject unitName = mapIdUnit[suboperationInfo.account.text()];
double quantity = 0;
if (parentSet) {
// If the parent is already set, it means that is a transfer
SKGOperationObject operationObj2;
IFOKDO(err, act.addOperation(operationObj2, true))
IFOKDO(err, operationObj2.setDate(operationObj.getDate()))
IFOKDO(err, operationObj2.setNumber(operationObj.getNumber()))
IFOKDO(err, operationObj2.setMode(operationObj.getMode()))
if (!err && !suboperationMemo.isNull()) {
err = operationObj2.setComment(suboperationMemo.text());
}
SKGPayeeObject payeeObject;
operationObj.getPayee(payeeObject);
IFOKDO(err, operationObj2.setPayee(payeeObject))
IFOK(err) {
QString val = suboperationReconciled.text();
err = operationObj2.setStatus(val == QStringLiteral("c") ? SKGOperationObject::POINTED : val == QStringLiteral("y") ? SKGOperationObject::CHECKED : SKGOperationObject::NONE);
}
IFOKDO(err, operationObj2.setImported(true))
IFOKDO(err, operationObj2.setImportID(operationObj.getImportID()))
IFOKDO(err, operationObj2.setTemplate(operationObj.isTemplate()))
if (!err && unitName.exist()) {
err = operationObj2.setUnit(unitName);
}
IFOKDO(err, operationObj2.save())
IFOKDO(err, operationObj2.setGroupOperation(operationObj))
IFOKDO(err, operationObj2.save())
// Create sub operation on operationObj2
SKGSubOperationObject suboperationObj2;
IFOKDO(err, operationObj2.addSubOperation(suboperationObj2))
IFOK(err) {
// We must take the quality of the split having an action
quantity = suboperationInfo.value;
err = suboperationObj2.setQuantity(suboperationInfo.value);
}
if (!err && !suboperationMemo.isNull()) {
err = suboperationObj2.setComment(suboperationMemo.text());
}
IFOKDO(err, suboperationObj2.save())
} else {
// We set the parent
IFOKDO(err, operationObj.setParentAccount(act))
if (!err && unitName.exist()) {
err = operationObj.setUnit(unitName);
}
IFOKDO(err, operationObj.save())
// Compute quantity
quantity = suboperationInfo.value;
// Create sub operation on operationObj
quantity -= SKGServices::stringToDouble(operationObj.getAttribute(QStringLiteral("f_QUANTITY")));
if (fabs(quantity) > 10e-9) {
IFOKDO(err, operationObj.addSubOperation(suboperationObj))
IFOKDO(err, suboperationObj.setQuantity(quantity))
if (!err && !suboperationMemo.isNull()) {
err = suboperationObj.setComment(suboperationMemo.text());
}
IFOKDO(err, suboperationObj.save())
}
parentSet = true;
}
}
}
if (!err && i % 500 == 0) {
err = m_importer->getDocument()->executeSqliteOrder(QStringLiteral("ANALYZE"));
}
IFOKDO(err, m_importer->getDocument()->stepForward(i + 1))
}
SKGENDTRANSACTION(m_importer->getDocument(), err)
}
IFOKDO(err, m_importer->getDocument()->stepForward(3))
// Step 4-Get scheduled
{
// Create scheduled
QDomNodeList scheduleList = book.elementsByTagName(QStringLiteral("gnc:schedxaction"));
int nbSchedule = scheduleList.count();
IFOKDO(err, m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Import step", "Import scheduled operations"), nbSchedule))
for (int i = 0; !err && i < nbSchedule; ++i) {
QDomElement schedule = scheduleList.at(i).toElement();
QDomElement scheduleAutoCreate = schedule.firstChildElement(QStringLiteral("sx:autoCreate"));
QDomElement scheduleAutoCreateNotify = schedule.firstChildElement(QStringLiteral("sx:autoCreateNotify"));
QDomElement scheduleAdvanceCreateDays = schedule.firstChildElement(QStringLiteral("sx:advanceCreateDays"));
QDomElement scheduleAdvanceRemindDays = schedule.firstChildElement(QStringLiteral("sx:advanceRemindDays"));
QDomElement scheduleOccur = schedule.firstChildElement(QStringLiteral("sx:num-occur"));
QDomElement scheduleEnable = schedule.firstChildElement(QStringLiteral("sx:enabled"));
QDomElement scheduleLast = schedule.firstChildElement(QStringLiteral("sx:last"));
if (scheduleLast.isNull()) {
scheduleLast = schedule.firstChildElement(QStringLiteral("sx:start"));
}
QDomElement scheduleMult;
QDomElement schedulePeriod;
QDomElement scheduleDate;
QDomNodeList scheduleScheduleList = schedule.elementsByTagName(QStringLiteral("gnc:recurrence"));
if (scheduleScheduleList.count() != 0) {
QDomElement scheduleSchedule = scheduleScheduleList.at(0).toElement();
scheduleMult = scheduleSchedule.firstChildElement(QStringLiteral("recurrence:mult"));
schedulePeriod = scheduleSchedule.firstChildElement(QStringLiteral("recurrence:period_type"));
scheduleDate = scheduleLast.firstChildElement(QStringLiteral("gdate"));
}
QDomElement scheduleTempl = schedule.firstChildElement(QStringLiteral("sx:templ-acct"));
if (!scheduleTempl.isNull()) {
SKGOperationObject operation = mapIdScheduledOperation[scheduleTempl.text()];
SKGRecurrentOperationObject recuOperation;
err = operation.addRecurrentOperation(recuOperation);
if (!err && !scheduleOccur.isNull()) {
err = recuOperation.timeLimit(true);
IFOKDO(err, recuOperation.setTimeLimit(SKGServices::stringToInt(scheduleOccur.text())))
}
if (!err && !scheduleAutoCreate.isNull()) {
err = recuOperation.autoWriteEnabled(scheduleAutoCreate.text() == QStringLiteral("y"));
}
if (!err && !scheduleAdvanceCreateDays.isNull()) {
err = recuOperation.setAutoWriteDays(SKGServices::stringToInt(scheduleAdvanceCreateDays.text()));
}
if (!err && !scheduleAutoCreateNotify.isNull()) {
err = recuOperation.warnEnabled(scheduleAutoCreateNotify.text() == QStringLiteral("y"));
}
if (!err && !scheduleAdvanceRemindDays.isNull()) {
err = recuOperation.setWarnDays(SKGServices::stringToInt(scheduleAdvanceRemindDays.text()));
}
if (!err && !scheduleMult.isNull() && !schedulePeriod.isNull()) {
int p = SKGServices::stringToInt(scheduleMult.text());
SKGRecurrentOperationObject::PeriodUnit punit = SKGRecurrentOperationObject::DAY;
if (schedulePeriod.text() == QStringLiteral("month")) {
punit = SKGRecurrentOperationObject::MONTH;
} else if (schedulePeriod.text() == QStringLiteral("week")) {
punit = SKGRecurrentOperationObject::WEEK;
}
err = recuOperation.setPeriodIncrement(p);
IFOKDO(err, recuOperation.setPeriodUnit(punit))
}
if (!err && !scheduleDate.isNull()) {
err = recuOperation.setDate(QDate::fromString(scheduleDate.text().left(10), QStringLiteral("yyyy-MM-dd")));
}
IFOKDO(err, recuOperation.setDate(recuOperation.getNextDate()))
if (!err && !scheduleEnable.isNull() && scheduleEnable.text() == QStringLiteral("n")) {
err = recuOperation.autoWriteEnabled(false);
IFOKDO(err, recuOperation.setWarnDays(false))
}
IFOKDO(err, recuOperation.save())
}
IFOKDO(err, m_importer->getDocument()->stepForward(i + 1))
}
SKGENDTRANSACTION(m_importer->getDocument(), err)
}
IFOKDO(err, m_importer->getDocument()->stepForward(4))
// Step 5-Get unit values
{
// Create unit values
QDomElement pricedb = book.firstChildElement(QStringLiteral("gnc:pricedb"));
if (!pricedb.isNull()) {
QDomNodeList priceList = pricedb.elementsByTagName(QStringLiteral("price"));
int nbPrice = priceList.count();
IFOKDO(err, m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Import step", "Import units"), nbPrice))
for (int i = 0; !err && i < nbPrice; ++i) {
QDomElement price = priceList.at(i).toElement();
QDomNodeList priceIdList = price.elementsByTagName(QStringLiteral("cmdty:id"));
QDomNodeList priceDateList = price.elementsByTagName(QStringLiteral("ts:date"));
QDomElement priceValue = price.firstChildElement(QStringLiteral("price:value"));
if (!priceIdList.isEmpty() && !priceDateList.isEmpty() && !priceValue.isNull()) {
QString unitName = priceIdList.at(0).toElement().text();
QDate unitDate = QDate::fromString(priceDateList.at(0).toElement().text().left(10), QStringLiteral("yyyy-MM-dd"));
double val = 0;
QStringList vals = SKGServices::splitCSVLine(priceValue.text(), '/');
if (vals.count() == 1) {
val = SKGServices::stringToDouble(vals.at(0));
} else if (vals.count() == 2) {
val = SKGServices::stringToDouble(vals.at(0)) / SKGServices::stringToDouble(vals.at(1));
}
err = m_importer->getDocument()->addOrModifyUnitValue(unitName, unitDate, val);
}
IFOKDO(err, m_importer->getDocument()->stepForward(i + 1))
}
SKGENDTRANSACTION(m_importer->getDocument(), err)
}
}
IFOKDO(err, m_importer->getDocument()->stepForward(5))
// Step 6-Remove temporary account
{
IFOKDO(err, gnucashTemporaryAccount.remove(false, true))
IFOKDO(err, m_importer->getDocument()->executeSqliteOrder("DELETE FROM account WHERE rd_bank_id=" % SKGServices::intToString(bank.getID()) % " AND t_name='GNUCASH-TEMPORARY-ACCOUNT' AND (SELECT COUNT(1) FROM operation WHERE operation.rd_account_id=account.id)=0"))
IFOKDO(err, m_importer->getDocument()->stepForward(6))
}
}
SKGENDTRANSACTION(m_importer->getDocument(), err)
}
IFOKDO(err, m_importer->getDocument()->executeSqliteOrder(QStringLiteral("ANALYZE")))
}
}
return err;
}
QString SKGImportPluginGnc::getMimeTypeFilter() const
{
return "*.uncompressed *.gnucash *.gnc|" % i18nc("A file format", "GnuCash document");
}
#include <skgimportplugingnc.moc>
diff --git a/plugins/import/skrooge_import_gnc/skgimportplugingnc.h b/plugins/import/skrooge_import_gnc/skgimportplugingnc.h
index 1fabedc27..c2ab00740 100644
--- a/plugins/import/skrooge_import_gnc/skgimportplugingnc.h
+++ b/plugins/import/skrooge_import_gnc/skgimportplugingnc.h
@@ -1,78 +1,78 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGIMPORTPLUGINGNC_H
#define SKGIMPORTPLUGINGNC_H
/** @file
* This file is Skrooge plugin for GNC import / export.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include <qdom.h>
#include "skgimportplugin.h"
/**
* This file is Skrooge plugin for GNC import / export.
*/
class SKGImportPluginGnc : public SKGImportPlugin
{
Q_OBJECT
Q_INTERFACES(SKGImportPlugin)
public:
/**
* Default constructor
* @param iImporter the parent importer
* @param iArg the arguments
*/
explicit SKGImportPluginGnc(QObject* iImporter, const QVariantList& iArg);
/**
* Default Destructor
*/
~SKGImportPluginGnc() override;
/**
* To know if import is possible with this plugin
*/
bool isImportPossible() override;
/**
* Import a file
* @return an object managing the error.
* @see SKGError
*/
SKGError importFile() override;
/**
* Return the mime type filter
* @return the mime type filter. Example: "*.csv|CSV file"
*/
QString getMimeTypeFilter() const override;
private:
Q_DISABLE_COPY(SKGImportPluginGnc)
struct SubOpInfo {
QDomElement subOp;
QDomElement account;
double value{};
};
};
#endif // SKGIMPORTPLUGINGNC_H
diff --git a/plugins/import/skrooge_import_gsb/CMakeLists.txt b/plugins/import/skrooge_import_gsb/CMakeLists.txt
index 53ea86f10..052b1f003 100644
--- a/plugins/import/skrooge_import_gsb/CMakeLists.txt
+++ b/plugins/import/skrooge_import_gsb/CMakeLists.txt
@@ -1,33 +1,33 @@
#***************************************************************************
#* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
#* *
#* 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 <http://www.gnu.org/licenses/> *
+#* along with this program. If not, see <https://www.gnu.org/licenses/> *
#***************************************************************************
MESSAGE( STATUS "..:: CMAKE PLUGIN_IMPORT_GSB ::..")
PROJECT(plugin_import_gsb)
LINK_DIRECTORIES (${LIBRARY_OUTPUT_PATH})
SET(skrooge_import_gsb_SRCS
skgimportplugingsb.cpp
)
ADD_LIBRARY(skrooge_import_gsb MODULE ${skrooge_import_gsb_SRCS})
TARGET_LINK_LIBRARIES(skrooge_import_gsb KF5::Parts KF5::Archive skgbasemodeler skgbasegui skgbankmodeler skgbankgui)
########### install files ###############
INSTALL(TARGETS skrooge_import_gsb DESTINATION ${KDE_INSTALL_QTPLUGINDIR})
INSTALL(FILES ${PROJECT_SOURCE_DIR}/org.kde.skrooge-import-gsb.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR})
diff --git a/plugins/import/skrooge_import_gsb/org.kde.skrooge-import-gsb.desktop b/plugins/import/skrooge_import_gsb/org.kde.skrooge-import-gsb.desktop
index 3dc7f3bbf..cba77cc08 100644
--- a/plugins/import/skrooge_import_gsb/org.kde.skrooge-import-gsb.desktop
+++ b/plugins/import/skrooge_import_gsb/org.kde.skrooge-import-gsb.desktop
@@ -1,74 +1,74 @@
[Desktop Entry]
Name=Skrooge import GSB plugin
Name[bs]=Skrooge dodatak za GSB uvoz
Name[ca]=Connector d'importació de GSB de l'Skrooge
Name[ca@valencia]=Connector d'importació de GSB de l'Skrooge
Name[cs]=Modul Skrooge pro import GSB
Name[da]=Plugin til import af GSB til Skrooge
Name[de]=Skrooge-GSB-Importmodul
Name[el]=Skrooge import GSB plugin
Name[en_GB]=Skrooge import GSB plugin
Name[es]=Complemento de Skrooge de importación de GSB
Name[et]=Skrooge GSB impordi plugin
Name[fi]=Skroogen GSB-tuontiliitännäinen
-Name[fr]=Module externe de Skrooge pour l'importation « GSB »
+Name[fr]=Module externe de Skrooge pour l'importation « GSB »
Name[gl]=Complemento de importación de GSB a Skrooge
Name[hu]=Skrooge GSB importáló bővítmény
Name[it]=Estensione di Skrooge per l'importazione GSB
Name[lt]=Skrooge GSB importavimo papildinys
Name[nb]=Skrooge-modul for GSB-import
Name[nl]=Plugin van Skrooge voor GSB-importeren
Name[pl]=Wtyczka importu GSB dla Skrooge
Name[pt]='Plugin' de importação de GSB para o Skrooge
Name[pt_BR]=Plugin de importação de GSB para o Skrooge
Name[ru]=Модуль импорта файлов GSB
Name[sk]=Skrooge plugin GSB import
Name[sv]=Skrooge GSB-importinsticksprogram
Name[tr]=Skrooge GSB içe aktarma eklentisi
Name[uk]=Додаток імпортування GSB до Skrooge
Name[x-test]=xxSkrooge import GSB pluginxx
Name[zh_TW]=Skrooge 匯入 GSB 外掛程式
Comment=A Skrooge plugin to import GSB files
Comment[bs]=Skrooge dodatak za uvoz GSB datoteka
Comment[ca]=Un connector de l'Skrooge per importar fitxers GSB
Comment[ca@valencia]=Un connector de l'Skrooge per importar fitxers GSB
Comment[cs]=Modul Skrooge pro import souborů GSB
Comment[da]=Et Skrooge-plugin til at importere GSB-filer
Comment[de]=Ein Skrooge-Modul zum Import von GSB-Dateien
Comment[el]=Ένα πρόσθετο του Skrooge για την εισαγωγή αρχείων GSB
Comment[en_GB]=A Skrooge plugin to import GSB files
Comment[es]=Complemento de Skrooge para importar archivos GSB
Comment[et]=Skrooge plugin GSB-failide importimiseks
Comment[fi]=Skroogen GSB-tiedostojen tuontiliitännäinen
-Comment[fr]=Un module externe de Skrooge pour l'importation de fichiers « GSB »
+Comment[fr]=Un module externe de Skrooge pour l'importation de fichiers « GSB »
Comment[gl]=Un complemento de Skrooge para importar ficheiros GSB.
Comment[hu]=Egy Skrooge bővítmény GSB fájlok importálásához
Comment[it]=Un'estensione di Skrooge per importare i file GSB
Comment[lt]=Skrooge GSB failų importavimo papildinys
Comment[nb]=En Skrooge-modul for å importere GSB-filer
Comment[nl]=Een Skrooge-plugin voor het importeren van GSB-bestanden
Comment[pl]=Wtyczka Skrooge do importu plików GSB
Comment[pt]=Um 'plugin' do Skrooge para importar ficheiros GSB
Comment[pt_BR]=Um plugin do Skrooge para importar arquivos GSB
Comment[ru]=Модуль импорта файлов GSB
Comment[sk]=Skrooge plugin na import GSB súborov
Comment[sv]=Ett insticksprogram till Skrooge för att importera GSB-filer
Comment[tr]=GSB dosyalarını içe aktarmak için Skrooge eklentisi
Comment[uk]=Додаток до Skrooge для імпортування даних з файлів GSB
Comment[x-test]=xxA Skrooge plugin to import GSB filesxx
Comment[zh_TW]=Skrooge 匯入 GSB 檔用的外掛程式
Encoding=UTF-8
Icon=skrooge
Type=Service
X-KDE-ServiceTypes=SKG IMPORT/Plugin
X-KDE-Library=skrooge_import_gsb
X-Krunner-ID=Skrooge import GSB plugin
X-KDE-PluginInfo-Author=Stephane MANKOWSKI
X-KDE-PluginInfo-Email=stephane@mankowski.fr
X-KDE-PluginInfo-Name=skrooge_import_gsb
X-KDE-PluginInfo-Version=1.0
-X-KDE-PluginInfo-Website=http://skrooge.org/
+X-KDE-PluginInfo-Website=https://skrooge.org/
X-KDE-PluginInfo-Category=Plugins
X-KDE-PluginInfo-Depends=
X-KDE-PluginInfo-License=GPL
X-KDE-PluginInfo-EnabledByDefault=true
diff --git a/plugins/import/skrooge_import_gsb/skgimportplugingsb.cpp b/plugins/import/skrooge_import_gsb/skgimportplugingsb.cpp
index b2989c1c8..7587ce673 100644
--- a/plugins/import/skrooge_import_gsb/skgimportplugingsb.cpp
+++ b/plugins/import/skrooge_import_gsb/skgimportplugingsb.cpp
@@ -1,523 +1,523 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is Skrooge plugin for GSB import / export.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgimportplugingsb.h"
#include <kcompressiondevice.h>
#include <klocalizedstring.h>
#include <kpluginfactory.h>
#include <qdom.h>
#include "skgbankincludes.h"
#include "skgimportexportmanager.h"
#include "skgobjectbase.h"
#include "skgpayeeobject.h"
#include "skgservices.h"
#include "skgtraces.h"
/**
* This plugin factory.
*/
K_PLUGIN_FACTORY(SKGImportPluginGsbFactory, registerPlugin<SKGImportPluginGsb>();)
SKGImportPluginGsb::SKGImportPluginGsb(QObject* iImporter, const QVariantList& iArg)
: SKGImportPlugin(iImporter)
{
SKGTRACEINFUNC(10)
Q_UNUSED(iArg)
}
SKGImportPluginGsb::~SKGImportPluginGsb()
= default;
bool SKGImportPluginGsb::isImportPossible()
{
SKGTRACEINFUNC(10)
return (m_importer == nullptr ? true : m_importer->getFileNameExtension() == QStringLiteral("GSB"));
}
SKGError SKGImportPluginGsb::importFile()
{
if (m_importer == nullptr) {
return SKGError(ERR_ABORT, i18nc("Error message", "Invalid parameters"));
}
SKGError err;
SKGTRACEINFUNCRC(2, err)
// Initialisation
// Open file
KCompressionDevice file(m_importer->getLocalFileName(), KCompressionDevice::GZip);
if (!file.open(QIODevice::ReadOnly)) {
err.setReturnCode(ERR_INVALIDARG).setMessage(i18nc("Error message", "Open file '%1' failed", m_importer->getFileName().toDisplayString()));
} else {
QDomDocument doc;
// Set the file without uncompression
QString errorMsg;
int errorLine = 0;
int errorCol = 0;
bool contentOK = doc.setContent(file.readAll(), &errorMsg, &errorLine, &errorCol);
file.close();
// Get root
QDomElement docElem = doc.documentElement();
if (!contentOK) {
err.setReturnCode(ERR_ABORT).setMessage(i18nc("Error message", "%1-%2: '%3'", errorLine, errorCol, errorMsg));
} else {
// Check version
QDomElement general = docElem.firstChildElement(QStringLiteral("General"));
if (general.isNull()) {
err.setReturnCode(ERR_ABORT).setMessage(i18nc("Error message", "Bad version of Grisbi document. Version must be >= 0.6.0"));
contentOK = false;
}
}
if (!contentOK) {
err.addError(ERR_INVALIDARG, i18nc("Error message", "Invalid XML content in file '%1'", m_importer->getFileName().toDisplayString()));
} else {
err = m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Import step", "Import %1 file", "GSB"), 10);
QMap<QString, SKGUnitObject> mapIdUnit;
QMap<QString, SKGBankObject> mapIdBank;
QMap<QString, SKGAccountObject> mapIdAccount;
QMap<QString, SKGCategoryObject> mapIdCategory;
QMap<QString, SKGOperationObject> mapIdOperation;
QMap<QString, SKGPayeeObject> mapIdPayee;
QMap<QString, QString> mapIdMode;
QMap<QString, QString> mapIdBudgetCat;
// Specifications: http://wiki.grisbi.org/doku.php?id=docs:dev:format_gsb
// Step 1-Create units
IFOK(err) {
QDomNodeList currencyList = docElem.elementsByTagName(QStringLiteral("Currency"));
int nb = currencyList.count();
err = m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Import step", "Import units"), nb);
for (int i = 0; !err && i < nb; ++i) {
// Get account object
QDomElement currency = currencyList.at(i).toElement();
// Creation of the units
SKGUnitObject unitObj(m_importer->getDocument());
IFOKDO(err, unitObj.setName(getAttribute(currency, QStringLiteral("Na"))))
IFOKDO(err, unitObj.setSymbol(getAttribute(currency, QStringLiteral("Co"))))
IFOKDO(err, unitObj.setNumberDecimal(SKGServices::stringToInt(getAttribute(currency, QStringLiteral("Fl")))))
IFOKDO(err, unitObj.save())
mapIdUnit[getAttribute(currency, QStringLiteral("Nb"))] = unitObj;
IFOKDO(err, m_importer->getDocument()->stepForward(i + 1))
}
SKGENDTRANSACTION(m_importer->getDocument(), err)
}
IFOKDO(err, m_importer->getDocument()->stepForward(1))
// Step 2-Create banks
IFOK(err) {
QDomNodeList bankList = docElem.elementsByTagName(QStringLiteral("Bank"));
int nb = bankList.count();
err = m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Import step", "Import banks"), nb);
for (int i = 0; !err && i < nb; ++i) {
// Get account object
QDomElement bank = bankList.at(i).toElement();
// Creation of the banks
SKGBankObject bankObj(m_importer->getDocument());
IFOKDO(err, bankObj.setName(getAttribute(bank, QStringLiteral("Na"))))
IFOKDO(err, bankObj.setNumber(getAttribute(bank, QStringLiteral("BIC"))))
IFOKDO(err, bankObj.save())
mapIdBank[getAttribute(bank, QStringLiteral("Nb"))] = bankObj;
IFOKDO(err, m_importer->getDocument()->stepForward(i + 1))
}
SKGENDTRANSACTION(m_importer->getDocument(), err)
}
IFOKDO(err, m_importer->getDocument()->stepForward(2))
// Step 3-Create accounts
SKGBankObject bankDefault(m_importer->getDocument());
IFOKDO(err, bankDefault.setName(QStringLiteral("GRISBI")))
IFOKDO(err, bankDefault.save())
IFOK(err) {
QDomNodeList accountList = docElem.elementsByTagName(QStringLiteral("Account"));
int nb = accountList.count();
err = m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Import step", "Import accounts"), nb);
for (int i = 0; !err && i < nb; ++i) {
// Get account object
QDomElement account = accountList.at(i).toElement();
// Creation of the account
SKGAccountObject accountObj;
SKGBankObject bank = mapIdBank[getAttribute(account, QStringLiteral("Bank"))];
if (!bank.exist()) {
bank = bankDefault;
}
IFOKDO(err, bank.addAccount(accountObj))
IFOKDO(err, accountObj.setName(getAttribute(account, QStringLiteral("Name"))))
IFOKDO(err, accountObj.setNumber(getAttribute(account, QStringLiteral("Bank_account_number"))))
IFOKDO(err, accountObj.setComment(getAttribute(account, QStringLiteral("Comment"))))
IFOKDO(err, accountObj.setAgencyAddress(getAttribute(account, QStringLiteral("Owner_address"))))
IFOKDO(err, accountObj.setMinLimitAmount(SKGServices::stringToDouble(getAttribute(account, QStringLiteral("Minimum_authorised_balance")))))
IFOKDO(err, accountObj.minLimitAmountEnabled(accountObj.getMinLimitAmount() != 0.0))
IFOKDO(err, accountObj.setClosed(getAttribute(account, QStringLiteral("Closed_account")) != QStringLiteral("0")))
IFOKDO(err, accountObj.save())
IFOKDO(err, accountObj.setInitialBalance(SKGServices::stringToDouble(getAttribute(account, QStringLiteral("Initial_balance"))), mapIdUnit[getAttribute(account, QStringLiteral("Currency"))]))
mapIdAccount[getAttribute(account, QStringLiteral("Number"))] = accountObj;
IFOKDO(err, m_importer->getDocument()->stepForward(i + 1))
}
SKGENDTRANSACTION(m_importer->getDocument(), err)
}
IFOKDO(err, m_importer->getDocument()->stepForward(3))
// Step 4-Get payees
IFOK(err) {
QDomNodeList partyList = docElem.elementsByTagName(QStringLiteral("Party"));
int nb = partyList.count();
err = m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Import step", "Import payees"), nb);
for (int i = 0; !err && i < nb; ++i) {
// Get payee object
QDomElement party = partyList.at(i).toElement();
SKGPayeeObject payeeObject;
err = SKGPayeeObject::createPayee(m_importer->getDocument(), getAttribute(party, QStringLiteral("Na")), payeeObject);
mapIdPayee[getAttribute(party, QStringLiteral("Nb"))] = payeeObject;
IFOKDO(err, m_importer->getDocument()->stepForward(i + 1))
}
SKGENDTRANSACTION(m_importer->getDocument(), err)
}
IFOKDO(err, m_importer->getDocument()->stepForward(4))
// Step 5-Get payement mode
IFOK(err) {
QDomNodeList paymentList = docElem.elementsByTagName(QStringLiteral("Payment"));
int nb = paymentList.count();
err = m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Import step", "Import payment mode"), nb);
for (int i = 0; !err && i < nb; ++i) {
// Get mode object
QDomElement payment = paymentList.at(i).toElement();
mapIdMode[getAttribute(payment, QStringLiteral("Number"))] = getAttribute(payment, QStringLiteral("Name"));
IFOKDO(err, m_importer->getDocument()->stepForward(i + 1))
}
SKGENDTRANSACTION(m_importer->getDocument(), err)
}
IFOKDO(err, m_importer->getDocument()->stepForward(5))
// Step 6-Create categories
IFOK(err) {
QDomNodeList categoryList = docElem.elementsByTagName(QStringLiteral("Category"));
int nb = categoryList.count();
err = m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Import step", "Import categories"), nb);
for (int i = 0; !err && i < nb; ++i) {
// Get account object
QDomElement category = categoryList.at(i).toElement();
// Creation of the categories
SKGCategoryObject catObj(m_importer->getDocument());
IFOKDO(err, catObj.setName(getAttribute(category, QStringLiteral("Na"))))
IFOKDO(err, catObj.save())
QString id = SKGServices::intToString(10000 * SKGServices::stringToInt(getAttribute(category, QStringLiteral("Nb"))));
mapIdCategory[id] = catObj;
IFOKDO(err, m_importer->getDocument()->stepForward(i + 1))
}
SKGENDTRANSACTION(m_importer->getDocument(), err)
}
IFOKDO(err, m_importer->getDocument()->stepForward(6))
// Step 7-Create subcategories
IFOK(err) {
QDomNodeList categoryList = docElem.elementsByTagName(QStringLiteral("Sub_category"));
int nb = categoryList.count();
err = m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Import step", "Import categories"), nb);
for (int i = 0; !err && i < nb; ++i) {
// Get account object
QDomElement category = categoryList.at(i).toElement();
// Creation of the subcategories
SKGCategoryObject catParentObj = mapIdCategory[SKGServices::intToString(10000 * SKGServices::stringToInt(getAttribute(category, QStringLiteral("Nbc"))))];
SKGCategoryObject catObj;
IFOKDO(err, catParentObj.addCategory(catObj))
IFOKDO(err, catObj.setName(getAttribute(category, QStringLiteral("Na"))))
IFOKDO(err, catObj.save())
QString id = SKGServices::intToString(10000 * SKGServices::stringToInt(getAttribute(category, QStringLiteral("Nbc"))) + SKGServices::stringToInt(getAttribute(category, QStringLiteral("Nb"))));
mapIdCategory[id] = catObj;
IFOKDO(err, m_importer->getDocument()->stepForward(i + 1))
}
SKGENDTRANSACTION(m_importer->getDocument(), err)
}
IFOKDO(err, m_importer->getDocument()->stepForward(7))
// Step 8-Index of budget categories
IFOK(err) {
QDomNodeList budgetaryList = docElem.elementsByTagName(QStringLiteral("Budgetary"));
int nb = budgetaryList.count();
for (int i = 0; !err && i < nb; ++i) {
// Get account object
QDomElement budgetary = budgetaryList.at(i).toElement();
QString id = SKGServices::intToString(10000 * SKGServices::stringToInt(getAttribute(budgetary, QStringLiteral("Nb"))));
mapIdBudgetCat[id] = getAttribute(budgetary, QStringLiteral("Na"));
}
}
IFOK(err) {
QDomNodeList budgetaryList = docElem.elementsByTagName(QStringLiteral("Sub_budgetary"));
int nb = budgetaryList.count();
for (int i = 0; !err && i < nb; ++i) {
// Get account object
QDomElement budgetary = budgetaryList.at(i).toElement();
QString id1 = SKGServices::intToString(10000 * SKGServices::stringToInt(getAttribute(budgetary, QStringLiteral("Nb"))));
QString id = SKGServices::intToString(10000 * SKGServices::stringToInt(getAttribute(budgetary, QStringLiteral("Nbb"))) + SKGServices::stringToInt(getAttribute(budgetary, QStringLiteral("Nb"))));
mapIdBudgetCat[id] = mapIdBudgetCat[id1] % OBJECTSEPARATOR % getAttribute(budgetary, QStringLiteral("Na"));
}
}
IFOKDO(err, m_importer->getDocument()->stepForward(8))
// Step 9-Create transaction
IFOK(err) {
QDomNodeList transactionList = docElem.elementsByTagName(QStringLiteral("Transaction"));
int nb = transactionList.count();
err = m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Import step", "Import operations"), nb);
for (int i = 0; !err && i < nb; ++i) {
// Get account object
QDomElement transaction = transactionList.at(i).toElement();
// Creation of the operation
SKGOperationObject opObj;
QString parentOpId = getAttribute(transaction, QStringLiteral("Mo"));
if (parentOpId == QStringLiteral("0")) {
SKGAccountObject account = mapIdAccount[getAttribute(transaction, QStringLiteral("Ac"))];
IFOKDO(err, account.addOperation(opObj, true))
IFOKDO(err, opObj.setDate(QDate::fromString(getAttribute(transaction, QStringLiteral("Dt")), QStringLiteral("MM/dd/yyyy"))))
IFOKDO(err, opObj.setUnit(mapIdUnit[ getAttribute(transaction, QStringLiteral("Cu"))]))
IFOKDO(err, opObj.setPayee(mapIdPayee[ getAttribute(transaction, QStringLiteral("Pa"))]))
IFOKDO(err, opObj.setMode(mapIdMode[getAttribute(transaction, QStringLiteral("Pn"))]))
IFOKDO(err, opObj.setNumber(getAttribute(transaction, QStringLiteral("Pc"))))
IFOKDO(err, opObj.setComment(getAttribute(transaction, QStringLiteral("No"))))
IFOKDO(err, opObj.setImported(true))
IFOKDO(err, opObj.setImportID("GSB-" % getAttribute(transaction, QStringLiteral("Nb"))))
IFOKDO(err, opObj.setStatus(getAttribute(transaction, QStringLiteral("Re")) == QStringLiteral("0") ? SKGOperationObject::NONE : SKGOperationObject::CHECKED))
IFOKDO(err, opObj.setGroupOperation(mapIdOperation[getAttribute(transaction, QStringLiteral("Trt"))]))
IFOKDO(err, opObj.save())
} else {
opObj = mapIdOperation[parentOpId];
}
// Budgetary allocation
IFOK(err) {
int sbu = SKGServices::stringToInt(getAttribute(transaction, QStringLiteral("Sbu")));
QString id = SKGServices::intToString(10000 * SKGServices::stringToInt(getAttribute(transaction, QStringLiteral("Bu"))) + qMax(sbu, 0));
QString buCat = mapIdBudgetCat[id];
if (!buCat.isEmpty()) {
err = opObj.setProperty(i18nc("Noun", "Budgetary allocation"), buCat);
IFOKDO(err, opObj.save())
}
}
if (getAttribute(transaction, QStringLiteral("Br")) == QStringLiteral("0")) {
SKGSubOperationObject subObj;
IFOKDO(err, opObj.addSubOperation(subObj))
QString id = SKGServices::intToString(10000 * SKGServices::stringToInt(getAttribute(transaction, QStringLiteral("Ca"))) + SKGServices::stringToInt(getAttribute(transaction, QStringLiteral("Sca"))));
IFOKDO(err, subObj.setCategory(mapIdCategory[id]))
IFOKDO(err, subObj.setComment(getAttribute(transaction, QStringLiteral("No"))))
IFOKDO(err, subObj.setQuantity(SKGServices::stringToDouble(getAttribute(transaction, QStringLiteral("Am")))))
IFOKDO(err, subObj.save())
}
// Fiscal year
IFOK(err) {
QString fiscalYear = getAttribute(transaction, QStringLiteral("Vo"));
if (!fiscalYear.isEmpty()) {
err = opObj.setProperty(i18nc("Noun", "Fiscal year"), fiscalYear);
IFOKDO(err, opObj.save())
}
}
if (parentOpId == QStringLiteral("0")) {
mapIdOperation[getAttribute(transaction, QStringLiteral("Nb"))] = opObj;
}
if (!err && i % 500 == 0) {
err = m_importer->getDocument()->executeSqliteOrder(QStringLiteral("ANALYZE"));
}
IFOKDO(err, m_importer->getDocument()->stepForward(i + 1))
}
SKGENDTRANSACTION(m_importer->getDocument(), err)
}
IFOKDO(err, m_importer->getDocument()->stepForward(9))
// Step 10-Create scheduled transaction
IFOK(err) {
QDomNodeList scheduledList = docElem.elementsByTagName(QStringLiteral("Scheduled"));
int nb = scheduledList.count();
err = m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Import step", "Import scheduled operations"), nb);
for (int i = 0; !err && i < nb; ++i) {
// Get account object
QDomElement transaction = scheduledList.at(i).toElement();
// Creation of the operation
SKGAccountObject account = mapIdAccount[getAttribute(transaction, QStringLiteral("Ac"))];
SKGOperationObject opObj;
IFOKDO(err, account.addOperation(opObj, true))
QDate firstDate = QDate::fromString(getAttribute(transaction, QStringLiteral("Dt")), QStringLiteral("MM/dd/yyyy"));
IFOKDO(err, opObj.setDate(firstDate))
IFOKDO(err, opObj.setUnit(mapIdUnit[ getAttribute(transaction, QStringLiteral("Cu"))]))
IFOKDO(err, opObj.setPayee(mapIdPayee[ getAttribute(transaction, QStringLiteral("Pa"))]))
IFOKDO(err, opObj.setMode(mapIdMode[getAttribute(transaction, QStringLiteral("Pn"))]))
IFOKDO(err, opObj.setNumber(getAttribute(transaction, QStringLiteral("Pc"))))
IFOKDO(err, opObj.setComment(getAttribute(transaction, QStringLiteral("No"))))
IFOKDO(err, opObj.setImported(true))
IFOKDO(err, opObj.setImportID("GSB-" % getAttribute(transaction, QStringLiteral("Nb"))))
IFOKDO(err, opObj.setTemplate(true))
IFOKDO(err, opObj.save())
SKGSubOperationObject subObj;
IFOKDO(err, opObj.addSubOperation(subObj))
QString id = SKGServices::intToString(10000 * SKGServices::stringToInt(getAttribute(transaction, QStringLiteral("Ca"))) + SKGServices::stringToInt(getAttribute(transaction, QStringLiteral("Sca"))));
IFOKDO(err, subObj.setCategory(mapIdCategory[id]))
IFOKDO(err, subObj.setComment(getAttribute(transaction, QStringLiteral("No"))))
IFOKDO(err, subObj.setQuantity(SKGServices::stringToDouble(getAttribute(transaction, QStringLiteral("Am")))))
IFOKDO(err, subObj.save())
QString Tra = getAttribute(transaction, QStringLiteral("Tra"));
if (Tra != QStringLiteral("0")) {
// This is a transfer
SKGOperationObject opObj2;
IFOKDO(err, opObj.duplicate(opObj2, opObj.getDate(), true))
IFOKDO(err, opObj2.setImported(true))
IFOKDO(err, opObj2.setImportID("GSB-" % getAttribute(transaction, QStringLiteral("Nb")) % "_TR"))
IFOKDO(err, opObj2.save())
SKGObjectBase::SKGListSKGObjectBase subObjs2;
IFOKDO(err, opObj2.getSubOperations(subObjs2))
if (!err && !subObjs2.isEmpty()) {
SKGSubOperationObject subObj2(subObjs2.at(0));
err = subObj2.setQuantity(-subObj.getQuantity());
IFOKDO(err, subObj2.save())
}
// Group operations
IFOKDO(err, opObj.setGroupOperation(opObj2))
IFOKDO(err, opObj.save())
}
// Create the schedule
SKGRecurrentOperationObject recuObj;
IFOKDO(err, opObj.addRecurrentOperation(recuObj))
IFOKDO(err, recuObj.setAutoWriteDays(0))
IFOKDO(err, recuObj.autoWriteEnabled(getAttribute(transaction, QStringLiteral("Au")) != QStringLiteral("0")))
IFOK(err) {
// text_frequency [] = { _("Once"), _("Weekly"), _("Monthly"), _("two months"), ("trimester"), _("Yearly"), _("Custom"), nullptr };
int occu = 1;
SKGRecurrentOperationObject::PeriodUnit period = SKGRecurrentOperationObject::DAY;
QString Pe = getAttribute(transaction, QStringLiteral("Pe"));
if (Pe == QStringLiteral("0")) {
period = SKGRecurrentOperationObject::MONTH;
IFOKDO(err, recuObj.timeLimit(true))
IFOKDO(err, recuObj.setTimeLimit(1))
} else if (Pe == QStringLiteral("1")) {
period = SKGRecurrentOperationObject::WEEK;
} else if (Pe == QStringLiteral("2")) {
period = SKGRecurrentOperationObject::MONTH;
} else if (Pe == QStringLiteral("3")) {
occu = 2;
period = SKGRecurrentOperationObject::MONTH;
} else if (Pe == QStringLiteral("4")) {
occu = 3;
period = SKGRecurrentOperationObject::MONTH;
} else if (Pe == QStringLiteral("5")) {
period = SKGRecurrentOperationObject::YEAR;
} else if (Pe == QStringLiteral("6")) {
// text_frequency_user [] = { _("Days"), _("Weeks"), _("Months"), _("Years"), nullptr };
occu = SKGServices::stringToInt(getAttribute(transaction, QStringLiteral("Pep")));
QString Pei = getAttribute(transaction, QStringLiteral("Pei"));
if (Pei == QStringLiteral("0")) {
period = SKGRecurrentOperationObject::DAY;
} else if (Pei == QStringLiteral("1")) {
period = SKGRecurrentOperationObject::WEEK;
} else if (Pei == QStringLiteral("2")) {
period = SKGRecurrentOperationObject::MONTH;
} else {
period = SKGRecurrentOperationObject::YEAR;
}
}
IFOKDO(err, recuObj.setPeriodUnit(period))
IFOKDO(err, recuObj.setPeriodIncrement(occu))
QString Dtl = getAttribute(transaction, QStringLiteral("Dtl"));
if (!err && !Dtl.isEmpty()) {
IFOKDO(err, recuObj.timeLimit(true))
IFOKDO(err, recuObj.setTimeLimit(QDate::fromString(Dtl, QStringLiteral("MM/dd/yyyy"))))
}
}
IFOKDO(err, recuObj.save())
if (!err && i % 500 == 0) {
err = m_importer->getDocument()->executeSqliteOrder(QStringLiteral("ANALYZE"));
}
IFOKDO(err, m_importer->getDocument()->stepForward(i + 1))
}
SKGENDTRANSACTION(m_importer->getDocument(), err)
}
IFOKDO(err, m_importer->getDocument()->stepForward(10))
SKGENDTRANSACTION(m_importer->getDocument(), err)
IFOKDO(err, m_importer->getDocument()->executeSqliteOrder(QStringLiteral("ANALYZE")))
}
}
return err;
}
QString SKGImportPluginGsb::getAttribute(const QDomElement& iElement, const QString& iAttribute)
{
QString val = iElement.attribute(iAttribute);
if (val == QStringLiteral("(null)")) {
val = QString();
}
return val;
}
QString SKGImportPluginGsb::getMimeTypeFilter() const
{
return "*.gsb|" % i18nc("A file format", "Grisbi file");
}
#include <skgimportplugingsb.moc>
diff --git a/plugins/import/skrooge_import_gsb/skgimportplugingsb.h b/plugins/import/skrooge_import_gsb/skgimportplugingsb.h
index 8a240f638..42976e6f0 100644
--- a/plugins/import/skrooge_import_gsb/skgimportplugingsb.h
+++ b/plugins/import/skrooge_import_gsb/skgimportplugingsb.h
@@ -1,72 +1,72 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGIMPORTPLUGINGSB_H
#define SKGIMPORTPLUGINGSB_H
/** @file
* This file is Skrooge plugin for GSB import / export.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgimportplugin.h"
/**
* This file is Skrooge plugin for GSB import / export.
*/
class SKGImportPluginGsb : public SKGImportPlugin
{
Q_OBJECT
Q_INTERFACES(SKGImportPlugin)
public:
/**
* Default constructor
* @param iImporter the parent importer
* @param iArg the arguments
*/
explicit SKGImportPluginGsb(QObject* iImporter, const QVariantList& iArg);
/**
* Default Destructor
*/
~SKGImportPluginGsb() override;
/**
* To know if import is possible with this plugin
*/
bool isImportPossible() override;
/**
* Import a file
* @return an object managing the error.
* @see SKGError
*/
SKGError importFile() override;
/**
* Return the mime type filter
* @return the mime type filter. Example: "*.csv|CSV file"
*/
QString getMimeTypeFilter() const override;
private:
Q_DISABLE_COPY(SKGImportPluginGsb)
static QString getAttribute(const QDomElement& iElement, const QString& iAttribute);
};
#endif // SKGIMPORTPLUGINGSB_H
diff --git a/plugins/import/skrooge_import_iif/CMakeLists.txt b/plugins/import/skrooge_import_iif/CMakeLists.txt
index d851062b9..3ff531dfc 100644
--- a/plugins/import/skrooge_import_iif/CMakeLists.txt
+++ b/plugins/import/skrooge_import_iif/CMakeLists.txt
@@ -1,38 +1,38 @@
#***************************************************************************
#* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
#* *
#* 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 <http://www.gnu.org/licenses/> *
+#* along with this program. If not, see <https://www.gnu.org/licenses/> *
#***************************************************************************
MESSAGE( STATUS "..:: CMAKE PLUGIN_IMPORT_IIF ::..")
PROJECT(plugin_import_iif)
INCLUDE_DIRECTORIES( ${PROJECT_BINARY_DIR} ${KDE4_INCLUDES} ${QT_INCLUDES}
${CMAKE_SOURCE_DIR}/skgbankmodeler ${CMAKE_SOURCE_DIR}/skgbasemodeler ${CMAKE_SOURCE_DIR}/skgbankgui ${CMAKE_SOURCE_DIR}/skgbasegui
${CMAKE_BINARY_DIR}/skgbasegui
)
LINK_DIRECTORIES (${LIBRARY_OUTPUT_PATH})
SET(skrooge_import_iif_SRCS
skgimportpluginiif.cpp
)
add_library(skrooge_import_iif MODULE ${skrooge_import_iif_SRCS})
TARGET_LINK_LIBRARIES(skrooge_import_iif KF5::Parts skgbasemodeler skgbasegui skgbankmodeler skgbankgui)
########### install files ###############
INSTALL(TARGETS skrooge_import_iif DESTINATION ${KDE_INSTALL_QTPLUGINDIR})
INSTALL(FILES ${PROJECT_SOURCE_DIR}/org.kde.skrooge-import-iif.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR})
diff --git a/plugins/import/skrooge_import_iif/org.kde.skrooge-import-iif.desktop b/plugins/import/skrooge_import_iif/org.kde.skrooge-import-iif.desktop
index bb3015a6b..f260d3301 100644
--- a/plugins/import/skrooge_import_iif/org.kde.skrooge-import-iif.desktop
+++ b/plugins/import/skrooge_import_iif/org.kde.skrooge-import-iif.desktop
@@ -1,60 +1,60 @@
[Desktop Entry]
Name=Skrooge import IIF plugin
Name[bs]=Skrooge dodatak za IIF uvoz
Name[ca]=Connector d'importació d'IIF de l'Skrooge
Name[ca@valencia]=Connector d'importació d'IIF de l'Skrooge
Name[cs]=Modul Skrooge pro import IIF
Name[da]=Plugin til import af IIF til Skrooge
Name[de]=Skrooge-IIF-Importmodul
Name[en_GB]=Skrooge import IIF plugin
Name[es]=Complemento de Skrooge para la importación de IIF
Name[fi]=Skroogen IIF-tuontiliitännäinen
-Name[fr]=Module externe de Skrooge pour l'importation « IIF »
+Name[fr]=Module externe de Skrooge pour l'importation « IIF »
Name[gl]=Complemento de importación de IIF a Skrooge
Name[it]=Estensione di Skrooge per l'importazione IIF
Name[nl]=Plugin van Skrooge voor importeren van IIF
Name[pl]=Wtyczka importu IIF dla Skrooge
Name[pt]='Plugin' de importação de IIF para o Skrooge
Name[pt_BR]=Plugin de importação de IIF para o Skrooge
Name[sk]=Skrooge plugin IIF import
Name[sv]=Skrooge IIF-importinsticksprogram
Name[tr]=Skrooge IIF içe aktarma eklentisi
Name[uk]=Додаток імпортування IIF до Skrooge
Name[x-test]=xxSkrooge import IIF pluginxx
Comment=A Skrooge plugin to import IIF files
Comment[bs]=Skrooge dodatak za uvoz IIF datoteka
Comment[ca]=Un connector de l'Skrooge per importar fitxers IIF
Comment[ca@valencia]=Un connector de l'Skrooge per importar fitxers IIF
Comment[cs]=Modul Skrooge pro import souborů IIF
Comment[da]=Et Skrooge-plugin til at importere IIF-filer
Comment[de]=Ein Skrooge-Modul zum Import von IIF-Dateien
Comment[en_GB]=A Skrooge plugin to import IIF files
Comment[es]=Complemento de Skrooge para importar archivos IIF
Comment[fi]=Skroogen IIF-tiedostojen tuontiliitännäinen
-Comment[fr]=Un module externe de Skrooge pour l'importation de fichiers « IIF »
+Comment[fr]=Un module externe de Skrooge pour l'importation de fichiers « IIF »
Comment[gl]=Un complemento de Skrooge para importar ficheiros IIF.
Comment[it]=Un'estensione di Skrooge per importare i file IIF
Comment[nl]=Een Skrooge-plugin voor het importeren van IIF-bestanden
Comment[pl]=Wtyczka Skrooge do importu plików IIF
Comment[pt]=Um 'plugin' do Skrooge para importar ficheiros IIF
Comment[pt_BR]=Um plugin do Skrooge para importar arquivos IIF
Comment[sk]=Skrooge plugin na import IIF súborov
Comment[sv]=Ett insticksprogram till Skrooge för att importera IIF-filer
Comment[tr]=IIF dosyalarını içe aktarmak için Skrooge eklentisi
Comment[uk]=Додаток до Skrooge для імпортування даних з файлів IIF
Comment[x-test]=xxA Skrooge plugin to import IIF filesxx
Encoding=UTF-8
Icon=skrooge
Type=Service
X-KDE-ServiceTypes=SKG IMPORT/Plugin
X-KDE-Library=skrooge_import_iif
X-Krunner-ID=Skrooge import IIF plugin
X-KDE-PluginInfo-Author=Stephane MANKOWSKI,miraks
X-KDE-PluginInfo-Email=stephane@mankowski.fr
X-KDE-PluginInfo-Name=skrooge_import_iif
X-KDE-PluginInfo-Version=1.0
-X-KDE-PluginInfo-Website=http://skrooge.org/
+X-KDE-PluginInfo-Website=https://skrooge.org/
X-KDE-PluginInfo-Category=Plugins
X-KDE-PluginInfo-Depends=
X-KDE-PluginInfo-License=GPL
X-KDE-PluginInfo-EnabledByDefault=true
diff --git a/plugins/import/skrooge_import_iif/skgimportpluginiif.cpp b/plugins/import/skrooge_import_iif/skgimportpluginiif.cpp
index dd5c1224d..a1858d4d5 100644
--- a/plugins/import/skrooge_import_iif/skgimportpluginiif.cpp
+++ b/plugins/import/skrooge_import_iif/skgimportpluginiif.cpp
@@ -1,511 +1,511 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is Skrooge plugin for IIF import / export.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgimportpluginiif.h"
#include <kpluginfactory.h>
#include <qcryptographichash.h>
#include <qfile.h>
#include <qsavefile.h>
#include "skgbankincludes.h"
#include "skgimportexportmanager.h"
#include "skgservices.h"
#include "skgtraces.h"
/**
* Opening balance string
*/
#define OPENINGBALANCE "Opening Balance"
/**
* This plugin factory.
*/
K_PLUGIN_FACTORY(SKGImportPluginIifFactory, registerPlugin<SKGImportPluginIif>();)
SKGImportPluginIif::SKGImportPluginIif(QObject* iImporter, const QVariantList& iArg)
: SKGImportPlugin(iImporter)
{
SKGTRACEINFUNC(10)
Q_UNUSED(iArg)
}
SKGImportPluginIif::~SKGImportPluginIif()
= default;
bool SKGImportPluginIif::isImportPossible()
{
SKGTRACEINFUNC(10)
return isExportPossible();
}
QString SKGImportPluginIif::getVal(const QStringList& iVals, const QString& iAttribute) const
{
QString output;
// Get the corresponding header
QStringList header = m_headers["!" % iVals[0]];
if (!header.isEmpty()) {
// Get index of getAttribute
int pos = header.indexOf(iAttribute);
if (pos != -1 && pos < iVals.count()) {
output = iVals[pos].trimmed();
}
}
return output;
}
SKGError SKGImportPluginIif::importFile()
{
if (m_importer == nullptr) {
return SKGError(ERR_ABORT, i18nc("Error message", "Invalid parameters"));
}
SKGError err;
SKGTRACEINFUNCRC(2, err)
// Create account if needed
QDateTime now = QDateTime::currentDateTime();
QString postFix = SKGServices::dateToSqlString(now);
// Begin transaction
err = m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Import step", "Import %1 file", "IIF"), 3);
IFOK(err) {
// Open file
QFile file(m_importer->getLocalFileName());
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
err.setReturnCode(ERR_INVALIDARG).setMessage(i18nc("Error message", "Open file '%1' failed", m_importer->getFileName().toDisplayString()));
} else {
QTextStream stream(&file);
if (!m_importer->getCodec().isEmpty()) {
stream.setCodec(m_importer->getCodec().toLatin1().constData());
}
// Import
SKGOperationObject operation;
SKGSubOperationObject suboperation;
int index = 0;
while (!stream.atEnd() && !err) {
// Read line
QString line = stream.readLine().trimmed();
if (!line.isEmpty()) {
QStringList vals = SKGServices::splitCSVLine(line, '\t');
if (vals[0].startsWith(QLatin1Char('!'))) {
// This is a header
m_headers[vals[0]] = vals;
} else {
// This is an item
QString t = vals[0].trimmed();
if (t == QStringLiteral("ACCNT")) {
// This is an account
QString accountType = getVal(vals, QStringLiteral("ACCNTTYPE"));
QString name = getVal(vals, QStringLiteral("NAME"));
/*
AP: Accounts payable DONE: ACCOUNT
AR: Accounts receivable DONE: ACCOUNT
BANK: Checking or savings DONE: ACCOUNT
CCARD: Credit card account DONE: ACCOUNT
COGS: Cost of goods sold DONE: CATEGORY
EQUITY: Capital/Equity DONE: CATEGORY
EXEXP: Other expense DONE: CATEGORY
EXINC: Other income DONE: CATEGORY
EXP: Expense DONE: CATEGORY
FIXASSET: Fixed asset DONE: ACCOUNT
INC: Income DONE: CATEGORY
LTLIAB: Long term liability DONE: ACCOUNT
NONPOSTING: Non-posting account DONE: ACCOUNT
OASSET: Other asset DONE: ACCOUNT
OCASSET: Other current asset DONE: ACCOUNT
OCLIAB: Other current liability DONE: ACCOUNT*/
if (accountType == QStringLiteral("BANK") || accountType == QStringLiteral("AP") || accountType == QStringLiteral("AR") ||
accountType == QStringLiteral("OCASSET") || accountType == QStringLiteral("FIXASSET") || accountType == QStringLiteral("OASSET") ||
accountType == QStringLiteral("OCLIAB") || accountType == QStringLiteral("LTLIAB") ||
accountType == QStringLiteral("CCARD") || accountType == QStringLiteral("NONPOSTING")) {
// Check if the account already exist
SKGAccountObject account;
err = SKGNamedObject::getObjectByName(m_importer->getDocument(), QStringLiteral("account"), name, account);
IFKO(err) {
// Create account
SKGBankObject bank(m_importer->getDocument());
err = bank.setName(i18nc("Noun", "Bank for import %1", postFix));
if (!err && bank.load().isFailed()) {
err = bank.save(false);
}
IFOKDO(err, bank.addAccount(account))
IFOKDO(err, account.setName(name))
if (!err && account.load().isFailed()) {
IFOKDO(err, account.setType(accountType == QStringLiteral("BANK") || accountType == QStringLiteral("AP") || accountType == QStringLiteral("AR") ? SKGAccountObject::CURRENT :
accountType == QStringLiteral("OCASSET") || accountType == QStringLiteral("FIXASSET") || accountType == QStringLiteral("OASSET") || accountType == QStringLiteral("EQUITY") ? SKGAccountObject::ASSETS :
accountType == QStringLiteral("OCLIAB") || accountType == QStringLiteral("LTLIAB") ? SKGAccountObject::LOAN :
accountType == QStringLiteral("CCARD") ? SKGAccountObject::CREDITCARD :
SKGAccountObject::OTHER))
IFOKDO(err, account.setAgencyNumber(getVal(vals, QStringLiteral("ACCNUM"))))
IFOKDO(err, account.setComment(getVal(vals, QStringLiteral("DESC"))))
IFOKDO(err, account.save())
m_accounts[name] = account;
}
}
} else {
// This is a category
SKGCategoryObject category;
QString originalName = name;
IFOKDO(err, SKGCategoryObject::createPathCategory(m_importer->getDocument(), name.replace(':', OBJECTSEPARATOR), category))
m_categories[originalName] = category;
}
} else if (t == QStringLiteral("CUST")) {
// This is a payee
QString name = getVal(vals, QStringLiteral("NAME"));
SKGPayeeObject payee;
IFOKDO(err, SKGPayeeObject::createPayee(m_importer->getDocument(), name, payee))
QString address = getVal(vals, QStringLiteral("BADDR1")) % " " %
getVal(vals, QStringLiteral("BADDR2")) % " " %
getVal(vals, QStringLiteral("BADDR3")) % " " %
getVal(vals, QStringLiteral("BADDR4")) % " " %
getVal(vals, QStringLiteral("BADDR5")) % " " %
getVal(vals, QStringLiteral("SADDR1")) % " " %
getVal(vals, QStringLiteral("SADDR2")) % " " %
getVal(vals, QStringLiteral("SADDR3")) % " " %
getVal(vals, QStringLiteral("SADDR4")) % " " %
getVal(vals, QStringLiteral("SADDR5"));
address = address.trimmed();
IFOKDO(err, payee.setAddress(address))
IFOKDO(err, payee.save())
m_payees[name] = payee;
} else if (t == QStringLiteral("VEND")) {
// This is a payee
QString name = getVal(vals, QStringLiteral("NAME"));
SKGPayeeObject payee;
IFOKDO(err, SKGPayeeObject::createPayee(m_importer->getDocument(), getVal(vals, QStringLiteral("NAME")), payee))
QString address = getVal(vals, QStringLiteral("ADDR1")) % " " %
getVal(vals, QStringLiteral("ADDR2")) % " " %
getVal(vals, QStringLiteral("ADDR3")) % " " %
getVal(vals, QStringLiteral("ADDR4")) % " " %
getVal(vals, QStringLiteral("ADDR5"));
address = address.trimmed();
IFOKDO(err, payee.setAddress(address))
IFOKDO(err, payee.save())
m_payees[name] = payee;
} else if (t == QStringLiteral("ENDTRNS")) {
operation = SKGOperationObject();
suboperation = SKGSubOperationObject();
} else if (t == QStringLiteral("TRNS")) {
// This is an operation
SKGAccountObject account = m_accounts.value(getVal(vals, QStringLiteral("ACCNT")));
IFOKDO(err, account.addOperation(operation))
QDate date = SKGServices::stringToTime(SKGServices::dateToSqlString(getVal(vals, QStringLiteral("DATE")), QStringLiteral("MM/DD/YYYY"))).date();
IFOKDO(err, operation.setDate(date))
IFOKDO(err, operation.setStatus(getVal(vals, QStringLiteral("CLEAR")) == QStringLiteral("Y") ? SKGOperationObject::CHECKED : SKGOperationObject::NONE))
QString number = getVal(vals, QStringLiteral("DOCNUM"));
if (!number.isEmpty()) {
IFOKDO(err, operation.setNumber(number))
}
// If an initial balance is existing for the account then we use the unit else we look for the most appropriate unit
SKGUnitObject unit;
double initBalance;
account.getInitialBalance(initBalance, unit);
if (!unit.exist()) {
err = m_importer->getDefaultUnit(unit, &date);
}
IFOKDO(err, operation.setUnit(unit))
IFOKDO(err, operation.setMode(getVal(vals, QStringLiteral("TRNSTYPE"))))
QString p = getVal(vals, QStringLiteral("NAME"));
if (!p.isEmpty()) {
IFOKDO(err, operation.setPayee(m_payees[p]))
}
IFOKDO(err, operation.setComment(getVal(vals, QStringLiteral("MEMO"))))
IFOKDO(err, operation.save())
} else if (t == QStringLiteral("SPL")) {
// This is a sub operation
QString a = getVal(vals, QStringLiteral("ACCNT"));
if (m_categories.contains(a)) {
// This is a split
SKGCategoryObject cat = m_categories.value(a);
IFOKDO(err, operation.addSubOperation(suboperation))
IFOKDO(err, suboperation.setQuantity(-SKGServices::stringToDouble(getVal(vals, QStringLiteral("AMOUNT")))))
IFOKDO(err, suboperation.setCategory(cat))
IFOKDO(err, suboperation.setComment(getVal(vals, QStringLiteral("MEMO"))))
IFOKDO(err, suboperation.save())
} else if (m_accounts.contains(a)) {
// This is a transfer
SKGAccountObject act = m_accounts.value(a);
SKGOperationObject operation2;
IFOKDO(err, act.addOperation(operation2))
QDate date = SKGServices::stringToTime(SKGServices::dateToSqlString(getVal(vals, QStringLiteral("DATE")), QStringLiteral("MM/DD/YYYY"))).date();
IFOKDO(err, operation2.setDate(date))
IFOKDO(err, operation2.setStatus(getVal(vals, QStringLiteral("CLEAR")) == QStringLiteral("Y") ? SKGOperationObject::CHECKED : SKGOperationObject::NONE))
QString number = getVal(vals, QStringLiteral("DOCNUM"));
if (!number.isEmpty()) {
IFOKDO(err, operation2.setNumber(number))
}
SKGUnitObject unit;
IFOKDO(err, operation.getUnit(unit))
IFOKDO(err, operation2.setUnit(unit))
IFOKDO(err, operation2.setMode(getVal(vals, QStringLiteral("TRNSTYPE"))))
QString p = getVal(vals, QStringLiteral("NAME"));
if (!p.isEmpty()) {
IFOKDO(err, operation2.setPayee(m_payees[p]))
}
IFOKDO(err, operation2.setComment(getVal(vals, QStringLiteral("MEMO"))))
IFOKDO(err, operation2.save())
SKGSubOperationObject suboperation2;
SKGCategoryObject cat = m_categories.value(a);
IFOKDO(err, operation2.addSubOperation(suboperation2))
IFOKDO(err, suboperation2.setQuantity(SKGServices::stringToDouble(getVal(vals, QStringLiteral("AMOUNT")))))
IFOKDO(err, suboperation2.setCategory(cat))
IFOKDO(err, suboperation2.setComment(getVal(vals, QStringLiteral("MEMO"))))
IFOKDO(err, suboperation2.save())
IFOKDO(err, operation2.setGroupOperation(operation))
IFOKDO(err, operation2.save())
IFOKDO(err, operation.addSubOperation(suboperation))
IFOKDO(err, suboperation.setQuantity(-SKGServices::stringToDouble(getVal(vals, QStringLiteral("AMOUNT")))))
IFOKDO(err, suboperation.setCategory(cat))
IFOKDO(err, suboperation.setComment(getVal(vals, QStringLiteral("MEMO"))))
IFOKDO(err, suboperation.save())
}
}
}
++index;
if (!err && index % 500 == 0) {
err = m_importer->getDocument()->executeSqliteOrder(QStringLiteral("ANALYZE"));
}
}
// Lines treated
IFOKDO(err, m_importer->getDocument()->stepForward(3))
}
// close file
file.close();
}
}
SKGENDTRANSACTION(m_importer->getDocument(), err)
return err;
}
bool SKGImportPluginIif::isExportPossible()
{
SKGTRACEINFUNC(10)
return (m_importer == nullptr ? true : m_importer->getFileNameExtension() == QStringLiteral("IIF"));
}
SKGError SKGImportPluginIif::exportFile()
{
if (m_importer == nullptr) {
return SKGError(ERR_ABORT, i18nc("Error message", "Invalid parameters"));
}
SKGError err;
SKGTRACEINFUNCRC(2, err)
// Read parameters
auto listUUIDs = SKGServices::splitCSVLine(m_exportParameters.value(QStringLiteral("uuid_of_selected_accounts_or_operations")));
QStringList listOperationsToExport;
listOperationsToExport.reserve(listUUIDs.count());
QStringList listAccountsToExport;
listAccountsToExport.reserve(listUUIDs.count());
for (const auto& uuid : listUUIDs) {
if (uuid.endsWith(QLatin1String("-operation"))) {
listOperationsToExport.push_back(uuid);
} else if (uuid.endsWith(QLatin1String("-account"))) {
listAccountsToExport.push_back(uuid);
}
}
if ((listAccountsToExport.count() != 0) || (listOperationsToExport.count() != 0)) {
IFOKDO(err, m_importer->getDocument()->sendMessage(i18nc("An information message", "Only selected accounts and operations have been exported")))
}
// Open file
QSaveFile file(m_importer->getLocalFileName(false));
if (!file.open(QIODevice::WriteOnly)) {
err.setReturnCode(ERR_INVALIDARG).setMessage(i18nc("Error message", "Save file '%1' failed", m_importer->getFileName().toDisplayString()));
} else {
QTextStream stream(&file);
if (!m_importer->getCodec().isEmpty()) {
stream.setCodec(m_importer->getCodec().toLatin1().constData());
}
err = m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Export step", "Export %1 file", "IIF"), 4);
IFOK(err) {
// Export accounts
stream << "!ACCNT\tNAME\tACCNTTYPE\tDESC\tACCNUM\tEXTRA\n";
SKGObjectBase::SKGListSKGObjectBase accounts;
IFOKDO(err, m_importer->getDocument()->getObjects(QStringLiteral("v_account_display"), QStringLiteral("1=1 ORDER BY t_name, id"), accounts))
int nbaccount = accounts.count();
if (!err && (nbaccount != 0)) {
err = m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Export step", "Export accounts"), nbaccount);
for (int i = 0; !err && i < nbaccount; ++i) {
SKGAccountObject act(accounts.at(i));
if (listAccountsToExport.isEmpty() || listAccountsToExport.contains(act.getUniqueID())) {
SKGAccountObject::AccountType type = act.getType();
stream << "ACCNT"
<< '\t' << act.getName()
<< '\t' << (type == SKGAccountObject::ASSETS ? "FIXASSET" : (type == SKGAccountObject::LOAN ? "OCLIAB" : type == SKGAccountObject::CREDITCARD ? "CCARD" : "BANK"))
<< '\t' << act.getComment()
<< '\t' << act.getAgencyNumber()
<< '\t'
<< endl;
}
IFOKDO(err, m_importer->getDocument()->stepForward(i + 1))
}
SKGENDTRANSACTION(m_importer->getDocument(), err)
}
IFOKDO(err, m_importer->getDocument()->stepForward(1))
// Export categories
SKGObjectBase::SKGListSKGObjectBase categories;
IFOKDO(err, m_importer->getDocument()->getObjects(QStringLiteral("v_category_display_tmp"), QStringLiteral("1=1 ORDER BY t_fullname, id"), categories))
int nbcat = categories.count();
if (!err && (nbcat != 0)) {
err = m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Export step", "Export categories"), nbcat);
for (int i = 0; !err && i < nbcat; ++i) {
SKGCategoryObject cat(categories.at(i));
QString catName = cat.getFullName();
if (!catName.isEmpty()) {
stream << "ACCNT"
<< '\t' << catName.replace(OBJECTSEPARATOR, QStringLiteral(":"))
<< '\t' << (SKGServices::stringToDouble(cat.getAttribute(QStringLiteral("f_REALCURRENTAMOUNT"))) < 0 ? "EXP" : "INC")
<< '\t'
<< '\t'
<< '\t'
<< endl;
}
IFOKDO(err, m_importer->getDocument()->stepForward(i + 1))
}
SKGENDTRANSACTION(m_importer->getDocument(), err)
}
IFOKDO(err, m_importer->getDocument()->stepForward(2))
// Export payees
stream << "!CUST\tNAME\tBADDR1\n";
SKGObjectBase::SKGListSKGObjectBase payees;
IFOKDO(err, m_importer->getDocument()->getObjects(QStringLiteral("v_payee_display"), QStringLiteral("1=1 ORDER BY t_name, id"), payees))
int nbpayee = payees.count();
if (!err && (nbpayee != 0)) {
err = m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Export step", "Export payees"), nbpayee);
for (int i = 0; !err && i < nbpayee; ++i) {
SKGPayeeObject payee(payees.at(i));
stream << "CUST"
<< '\t' << payee.getName()
<< '\t' << payee.getAddress()
<< endl;
IFOKDO(err, m_importer->getDocument()->stepForward(i + 1))
}
SKGENDTRANSACTION(m_importer->getDocument(), err)
}
IFOKDO(err, m_importer->getDocument()->stepForward(3))
// Export operations
stream << "!TRNS\tTRNSID\tTRNSTYPE\tDATE\tACCNT\tNAME\tCLASS\tAMOUNT\tDOCNUM\tCLEAR\tMEMO\n";
stream << "!SPL\tSPLID\tTRNSTYPE\tDATE\tACCNT\tNAME\tCLASS\tAMOUNT\tDOCNUM\tCLEAR\tMEMO\n";
stream << "!ENDTRNS\n";
SKGObjectBase::SKGListSKGObjectBase operations;
IFOKDO(err, m_importer->getDocument()->getObjects(QStringLiteral("v_operation_display"), QStringLiteral("1=1 ORDER BY d_date, id"), operations))
int nbop = operations.count();
if (!err && (nbop != 0)) {
err = m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Export step", "Export operations"), nbop);
for (int i = 0; !err && i < nbop; ++i) {
SKGOperationObject op(operations.at(i));
SKGAccountObject a;
op.getParentAccount(a);
if ((listOperationsToExport.isEmpty() || listOperationsToExport.contains(op.getUniqueID())) &&
(listAccountsToExport.isEmpty() || listAccountsToExport.contains(a.getUniqueID()))) {
stream << "TRNS"
<< '\t' << SKGServices::intToString(op.getID())
<< '\t' << "PAYMENT"
<< '\t' << op.getDate().toString(QStringLiteral("M/d/yyyy"))
<< '\t' << op.getAttribute(QStringLiteral("t_ACCOUNT"))
<< '\t' << op.getAttribute(QStringLiteral("t_PAYEE"))
<< '\t' << op.getAttribute(QStringLiteral("t_CATEGORY")).replace(OBJECTSEPARATOR, QStringLiteral(":"))
<< '\t' << SKGServices::doubleToString(op.getAmount(QDate::currentDate()))
<< '\t' << op.getNumber()
<< '\t' << (op.getStatus() == SKGOperationObject::CHECKED ? QStringLiteral("Y") : QStringLiteral("N"))
<< '\t' << op.getComment()
<< endl;
// Export sub operations
SKGObjectBase::SKGListSKGObjectBase sops;
err = op.getSubOperations(sops);
int nbsops = sops.count();
for (int j = 0; !err && j < nbsops; ++j) {
SKGSubOperationObject sop(sops.at(j));
SKGCategoryObject cat;
sop.getCategory(cat);
stream << "SPL"
<< '\t' << SKGServices::intToString(sop.getID())
<< '\t' << "PAYMENT"
<< '\t' << op.getDate().toString(QStringLiteral("M/d/yyyy"))
<< '\t' << cat.getFullName().replace(OBJECTSEPARATOR, QStringLiteral(":"))
<< '\t' << op.getAttribute(QStringLiteral("t_PAYEE"))
<< '\t'
<< '\t' << SKGServices::doubleToString(-sop.getQuantity())
<< '\t' << op.getNumber()
<< '\t' << (op.getStatus() == SKGOperationObject::CHECKED ? QStringLiteral("Y") : QStringLiteral("N"))
<< '\t' << sop.getComment()
<< endl;
}
}
stream << "ENDTRNS" << endl;
IFOKDO(err, m_importer->getDocument()->stepForward(i + 1))
}
SKGENDTRANSACTION(m_importer->getDocument(), err)
}
IFOKDO(err, m_importer->getDocument()->stepForward(4))
SKGENDTRANSACTION(m_importer->getDocument(), err)
}
}
// Close file
file.commit();
return err;
}
QString SKGImportPluginIif::getMimeTypeFilter() const
{
return "*.iif|" % i18nc("A file format", "Intuit Interchange Format file");
}
#include "skgimportpluginiif.moc"
diff --git a/plugins/import/skrooge_import_iif/skgimportpluginiif.h b/plugins/import/skrooge_import_iif/skgimportpluginiif.h
index 39ad9e7c4..3a9152071 100644
--- a/plugins/import/skrooge_import_iif/skgimportpluginiif.h
+++ b/plugins/import/skrooge_import_iif/skgimportpluginiif.h
@@ -1,93 +1,93 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGIMPORTPLUGINIIF_H
#define SKGIMPORTPLUGINIIF_H
/** @file
* This file is Skrooge plugin for IIF import / export.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgaccountobject.h"
#include "skgcategoryobject.h"
#include "skgimportplugin.h"
#include "skgpayeeobject.h"
/**
* This file is Skrooge plugin for IIF import / export.
*/
class SKGImportPluginIif : public SKGImportPlugin
{
Q_OBJECT
Q_INTERFACES(SKGImportPlugin)
public:
/**
* Default constructor
* @param iImporter the parent importer
* @param iArg arguments
*/
explicit SKGImportPluginIif(QObject* iImporter, const QVariantList& iArg);
/**
* Default Destructor
*/
~SKGImportPluginIif() override;
/**
* To know if import is possible with this plugin
*/
bool isImportPossible() override;
/**
* Import a file
* @return an object managing the error.
* @see SKGError
*/
SKGError importFile() override;
/**
* To know if export is possible with this plugin
* @return true or false
*/
bool isExportPossible() override;
/**
* Export a file
* @return an object managing the error.
* @see SKGError
*/
SKGError exportFile() override;
/**
* Return the mime type filter
* @return the mime type filter. Example: "*.csv|CSV file"
*/
QString getMimeTypeFilter() const override;
private:
Q_DISABLE_COPY(SKGImportPluginIif)
QString getVal(const QStringList& iVals, const QString& iAttribute) const;
QMap<QString, QStringList> m_headers;
QMap<QString, SKGAccountObject> m_accounts;
QMap<QString, SKGCategoryObject> m_categories;
QMap<QString, SKGPayeeObject> m_payees;
};
#endif // SKGIMPORTPLUGINIIF_H
diff --git a/plugins/import/skrooge_import_json/CMakeLists.txt b/plugins/import/skrooge_import_json/CMakeLists.txt
index 3dd1fe855..df7f31ccf 100644
--- a/plugins/import/skrooge_import_json/CMakeLists.txt
+++ b/plugins/import/skrooge_import_json/CMakeLists.txt
@@ -1,33 +1,33 @@
#***************************************************************************
#* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
#* *
#* 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 <http://www.gnu.org/licenses/> *
+#* along with this program. If not, see <https://www.gnu.org/licenses/> *
#***************************************************************************
MESSAGE( STATUS "..:: CMAKE PLUGIN_IMPORT_JSON ::..")
PROJECT(plugin_import_json)
LINK_DIRECTORIES (${LIBRARY_OUTPUT_PATH})
SET(skrooge_import_json_SRCS
skgimportpluginjson.cpp
)
ADD_LIBRARY(skrooge_import_json MODULE ${skrooge_import_json_SRCS})
TARGET_LINK_LIBRARIES(skrooge_import_json KF5::Parts skgbasemodeler skgbasegui skgbankmodeler skgbankgui)
########### install files ###############
INSTALL(TARGETS skrooge_import_json DESTINATION ${KDE_INSTALL_QTPLUGINDIR})
INSTALL(FILES ${PROJECT_SOURCE_DIR}/org.kde.skrooge-import-json.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR})
diff --git a/plugins/import/skrooge_import_json/org.kde.skrooge-import-json.desktop b/plugins/import/skrooge_import_json/org.kde.skrooge-import-json.desktop
index 138791d3a..ed33da271 100644
--- a/plugins/import/skrooge_import_json/org.kde.skrooge-import-json.desktop
+++ b/plugins/import/skrooge_import_json/org.kde.skrooge-import-json.desktop
@@ -1,72 +1,72 @@
[Desktop Entry]
Name=Skrooge import JSON plugin
Name[bs]=Skrooge dodatak za JSON uvoz
Name[ca]=Connector d'importació de JSON de l'Skrooge
Name[ca@valencia]=Connector d'importació de JSON de l'Skrooge
Name[cs]=Modul Skrooge pro import JSON
Name[da]=Plugin til import af JSON til Skrooge
Name[de]=Skrooge-JSON-Importmodul
Name[el]=Skrooge import JSON plugin
Name[en_GB]=Skrooge import JSON plugin
Name[es]=Complemento de Skrooge para la importación de JSON
Name[et]=Skrooge JSON impordi plugin
Name[fi]=Skroogen JSON-tuontiliitännäinen
-Name[fr]=Module externe de Skrooge pour l'importation « JSON »
+Name[fr]=Module externe de Skrooge pour l'importation « JSON »
Name[gl]=Complemento de importación de JSON a Skrooge
Name[hu]=Skrooge JSON importáló bővítmény
Name[it]=Estensione di Skrooge per l'importazione JSON
Name[lt]=Skrooge JSON importavimo papildinys
Name[nl]=Plug-in van Skrooge voor JSON importeren
Name[pl]=Wtyczka importu JSON dla Skrooge
Name[pt]='Plugin' de importação de JSON para o Skrooge
Name[pt_BR]=Plugin de importação de JSON para o Skrooge
Name[ru]=Модуль импорта файлов JSON
Name[sk]=Skrooge plugin JSON import
Name[sv]=Skrooge JSON-importinsticksprogram
Name[tr]=Skrooge JSON içe aktarma eklentisi
Name[uk]=Додаток імпортування JSON до Skrooge
Name[x-test]=xxSkrooge import JSON pluginxx
Name[zh_TW]=Skrooge 匯入 JSON 外掛程式
Comment=A Skrooge plugin to import JSON files
Comment[bs]=Skrooge dodatak za uvoz JSON datoteka
Comment[ca]=Un connector de l'Skrooge per importar fitxers JSON
Comment[ca@valencia]=Un connector de l'Skrooge per importar fitxers JSON
Comment[cs]=Modul Skrooge pro import souborů JSON
Comment[da]=Et Skrooge-plugin til at importere JSON-filer
Comment[de]=Ein Skrooge-Modul zum Import von JSON-Dateien
Comment[el]=Ένα πρόσθετο του Skrooge για την εισαγωγή αρχείων JSON
Comment[en_GB]=A Skrooge plugin to import JSON files
Comment[es]=Un complemento de Skrooge para importar archivos JSON
Comment[et]=Skrooge plugin JSON-failide importimiseks
Comment[fi]=Skroogen JSON-tiedostojen tuontiliitännäinen
-Comment[fr]=Un module externe de Skrooge pour l'importation de fichiers « JSON »
+Comment[fr]=Un module externe de Skrooge pour l'importation de fichiers « JSON »
Comment[gl]=Un complemento de Skrooge para importar ficheiros JSON.
Comment[hu]=Egy Skrooge bővítmény JSON fájlok importálásához
Comment[it]=Un'estensione di Skrooge per importare i file JSON
Comment[lt]=Skrooge JSON failų importavimo papildinys
Comment[nl]=Plug-in van Skrooge voor het importeren van JSON-bestanden
Comment[pl]=Wtyczka Skrooge do importu plików JSON
Comment[pt]=Um 'plugin' do Skrooge para importar ficheiros JSON
Comment[pt_BR]=Um plugin do Skrooge para importar arquivos JSON
Comment[ru]=Модуль импорта файлов JSON
Comment[sk]=Plugin Skrooge na import JSON súborov
Comment[sv]=Ett insticksprogram till Skrooge för att importera JSON-filer
Comment[tr]=JSON dosyalarını içe aktarmak için Skrooge eklentisi
Comment[uk]=Додаток до Skrooge для імпортування даних з файлів JSON
Comment[x-test]=xxA Skrooge plugin to import JSON filesxx
Comment[zh_TW]=Skrooge 匯入 JSON 檔用的外掛程式
Encoding=UTF-8
Icon=skrooge
Type=Service
X-KDE-ServiceTypes=SKG IMPORT/Plugin
X-KDE-Library=skrooge_import_json
X-Krunner-ID=Skrooge import JSON plugin
X-KDE-PluginInfo-Author=Stephane MANKOWSKI
X-KDE-PluginInfo-Email=stephane@mankowski.fr
X-KDE-PluginInfo-Name=skrooge_import_json
X-KDE-PluginInfo-Version=1.0
-X-KDE-PluginInfo-Website=http://skrooge.org/
+X-KDE-PluginInfo-Website=https://skrooge.org/
X-KDE-PluginInfo-Category=Plugins
X-KDE-PluginInfo-Depends=
X-KDE-PluginInfo-License=GPL
X-KDE-PluginInfo-EnabledByDefault=true
diff --git a/plugins/import/skrooge_import_json/skgimportpluginjson.cpp b/plugins/import/skrooge_import_json/skgimportpluginjson.cpp
index 13fc3c25f..127774c9a 100644
--- a/plugins/import/skrooge_import_json/skgimportpluginjson.cpp
+++ b/plugins/import/skrooge_import_json/skgimportpluginjson.cpp
@@ -1,82 +1,82 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 impgnced 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is Skrooge plugin for JSON import / export.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgimportpluginjson.h"
#include <klocalizedstring.h>
#include <kpluginfactory.h>
#include <qsavefile.h>
#include "skgdocumentbank.h"
#include "skgservices.h"
#include "skgtraces.h"
/**
* This plugin factory.
*/
K_PLUGIN_FACTORY(SKGImportPluginJsonFactory, registerPlugin<SKGImportPluginJson>();)
SKGImportPluginJson::SKGImportPluginJson(QObject* iImporter, const QVariantList& iArg)
: SKGImportPlugin(iImporter)
{
SKGTRACEINFUNC(10)
Q_UNUSED(iArg)
}
SKGImportPluginJson::~SKGImportPluginJson()
= default;
bool SKGImportPluginJson::isExportPossible()
{
SKGTRACEINFUNC(10)
return (m_importer == nullptr ? true : m_importer->getFileNameExtension() == QStringLiteral("JSON"));
}
SKGError SKGImportPluginJson::exportFile()
{
SKGError err;
QString doc;
err = m_importer->getDocument()->copyToJson(doc);
IFOK(err) {
QSaveFile file(m_importer->getLocalFileName(false));
if (!file.open(QIODevice::WriteOnly)) {
err.setReturnCode(ERR_INVALIDARG).setMessage(i18nc("Error message", "Save file '%1' failed", m_importer->getFileName().toDisplayString()));
} else {
QTextStream stream(&file);
if (!m_importer->getCodec().isEmpty()) {
stream.setCodec(m_importer->getCodec().toLatin1().constData());
}
stream << doc << endl;
// Close file
file.commit();
}
}
return err;
}
QString SKGImportPluginJson::getMimeTypeFilter() const
{
return "*.json|" % i18nc("A file format", "JSON file");
}
#include <skgimportpluginjson.moc>
diff --git a/plugins/import/skrooge_import_json/skgimportpluginjson.h b/plugins/import/skrooge_import_json/skgimportpluginjson.h
index afe8d9e1c..8d0c21c4b 100644
--- a/plugins/import/skrooge_import_json/skgimportpluginjson.h
+++ b/plugins/import/skrooge_import_json/skgimportpluginjson.h
@@ -1,71 +1,71 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGIMPORTPLUGINJSON_H
#define SKGIMPORTPLUGINJSON_H
/** @file
* This file is Skrooge plugin for JSON import / export.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgimportplugin.h"
/**
* This file is Skrooge plugin for JSON import / export.
*/
class SKGImportPluginJson : public SKGImportPlugin
{
Q_OBJECT
Q_INTERFACES(SKGImportPlugin)
public:
/**
* Default constructor
* @param iImporter the parent importer
* @param iArg the arguments
*/
explicit SKGImportPluginJson(QObject* iImporter, const QVariantList& iArg);
/**
* Default Destructor
*/
~SKGImportPluginJson() override;
/**
* To know if export is possible with this plugin
* @return true or false
*/
bool isExportPossible() override;
/**
* Export a file
* @return an object managing the error.
* @see SKGError
*/
SKGError exportFile() override;
/**
* Return the mime type filter
* @return the mime type filter. Example: "*.csv|CSV file"
*/
QString getMimeTypeFilter() const override;
private:
Q_DISABLE_COPY(SKGImportPluginJson)
};
#endif // SKGIMPORTPLUGINJSON_H
diff --git a/plugins/import/skrooge_import_kmy/CMakeLists.txt b/plugins/import/skrooge_import_kmy/CMakeLists.txt
index 5cb11fec2..3dcc03d34 100644
--- a/plugins/import/skrooge_import_kmy/CMakeLists.txt
+++ b/plugins/import/skrooge_import_kmy/CMakeLists.txt
@@ -1,33 +1,33 @@
#***************************************************************************
#* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
#* *
#* 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 <http://www.gnu.org/licenses/> *
+#* along with this program. If not, see <https://www.gnu.org/licenses/> *
#***************************************************************************
MESSAGE( STATUS "..:: CMAKE PLUGIN_IMPORT_KMY ::..")
PROJECT(plugin_import_kmy)
LINK_DIRECTORIES (${LIBRARY_OUTPUT_PATH})
SET(skrooge_import_kmy_SRCS
skgimportpluginkmy.cpp
)
ADD_LIBRARY(skrooge_import_kmy MODULE ${skrooge_import_kmy_SRCS})
TARGET_LINK_LIBRARIES(skrooge_import_kmy KF5::Parts KF5::Archive skgbasemodeler skgbasegui skgbankmodeler skgbankgui)
########### install files ###############
INSTALL(TARGETS skrooge_import_kmy DESTINATION ${KDE_INSTALL_QTPLUGINDIR})
INSTALL(FILES ${PROJECT_SOURCE_DIR}/org.kde.skrooge-import-kmy.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR})
diff --git a/plugins/import/skrooge_import_kmy/org.kde.skrooge-import-kmy.desktop b/plugins/import/skrooge_import_kmy/org.kde.skrooge-import-kmy.desktop
index 964dec89d..c1cf2078f 100644
--- a/plugins/import/skrooge_import_kmy/org.kde.skrooge-import-kmy.desktop
+++ b/plugins/import/skrooge_import_kmy/org.kde.skrooge-import-kmy.desktop
@@ -1,74 +1,74 @@
[Desktop Entry]
Name=Skrooge import KMY plugin
Name[bs]=Skrooge dodatak za KMY uvoz
Name[ca]=Connector d'importació de KMY de l'Skrooge
Name[ca@valencia]=Connector d'importació de KMY de l'Skrooge
Name[cs]=Modul Skrooge pro import KMY
Name[da]=Plugin til import af KMY til Skrooge
Name[de]=Skrooge-KMY-Importmodul
Name[el]=Skrooge import KMY plugin
Name[en_GB]=Skrooge import KMY plugin
Name[es]=Complemento de Skrooge para la importación de KMY
Name[et]=Skrooge KMY impordi plugin
Name[fi]=Skroogen KMY-tuontiliitännäinen
-Name[fr]=Module externe de Skrooge pour l'importation « KMY »
+Name[fr]=Module externe de Skrooge pour l'importation « KMY »
Name[gl]=Complemento de importación de KMY a Skrooge
Name[hu]=Skrooge KMY importáló bővítmény
Name[it]=Estensione di Skrooge per l'importazione KMY
Name[lt]=Skrooge KMY importavimo papildinys
Name[nb]=Skrooge-modul for KMY-import
Name[nl]=Plugin van Skrooge voor KMY-importeren
Name[pl]=Wtyczka importu KMY dla Skrooge
Name[pt]='Plugin' de importação de KMY para o Skrooge
Name[pt_BR]=Plugin de importação de KMY para o Skrooge
Name[ru]=Модуль импорта файлов KMY
Name[sk]=Skrooge plugin KMY import
Name[sv]=Skrooge KMY-importinsticksprogram
Name[tr]=Skrooge KMY içe aktarma eklentisi
Name[uk]=Додаток імпортування KMY до Skrooge
Name[x-test]=xxSkrooge import KMY pluginxx
Name[zh_TW]=Skrooge 匯入 KMY 外掛程式
Comment=A Skrooge plugin to import KMY files
Comment[bs]=Skrooge dodatak za uvoz KMY datoteka
Comment[ca]=Un connector de l'Skrooge per importar fitxers KMY
Comment[ca@valencia]=Un connector de l'Skrooge per importar fitxers KMY
Comment[cs]=Modul Skrooge pro import souborů KMY
Comment[da]=Et Skrooge-plugin til at importere KMY-filer
Comment[de]=Ein Skrooge-Modul zum Import von KMY-Dateien
Comment[el]=Ένα πρόσθετο του Skrooge για την εισαγωγή αρχείων KMY
Comment[en_GB]=A Skrooge plugin to import KMY files
Comment[es]=Complemento de Skrooge para importar archivos KMY
Comment[et]=Skrooge plugin KMY-failide importimiseks
Comment[fi]=Skroogen KMY-tiedostojen tuontiliitännäinen
-Comment[fr]=Un module externe de Skrooge pour l'importation de fichiers « KMY »
+Comment[fr]=Un module externe de Skrooge pour l'importation de fichiers « KMY »
Comment[gl]=Un complemento de Skrooge para importar ficheiros KMY.
Comment[hu]=Egy Skrooge bővítmény KMY fájlok importálásához
Comment[it]=Un'estensione di Skrooge per importare i file KMY
Comment[lt]=Skrooge KMY failų importavimo papildinys
Comment[nb]=En Skrooge-modul for å importere KMY-filer
Comment[nl]=Een Skrooge-plugin voor het importeren van KMY-bestanden
Comment[pl]=Wtyczka Skrooge do importu plików KMY
Comment[pt]=Um 'plugin' do Skrooge para importar ficheiros KMY
Comment[pt_BR]=Um plugin do Skrooge para importar arquivos KMY
Comment[ru]=Модуль импорта файлов KMY
Comment[sk]=Skrooge plugin na import KMY súborov
Comment[sv]=Ett insticksprogram till Skrooge för att importera KMY-filer
Comment[tr]=KMY dosyalarını içe aktarmak için Skrooge eklentisi
Comment[uk]=Додаток до Skrooge для імпортування даних з файлів KMY
Comment[x-test]=xxA Skrooge plugin to import KMY filesxx
Comment[zh_TW]=Skrooge 匯入 KMY 檔用的外掛程式
Encoding=UTF-8
Icon=skrooge
Type=Service
X-KDE-ServiceTypes=SKG IMPORT/Plugin
X-KDE-Library=skrooge_import_kmy
X-Krunner-ID=Skrooge import KMY plugin
X-KDE-PluginInfo-Author=Stephane MANKOWSKI
X-KDE-PluginInfo-Email=stephane@mankowski.fr
X-KDE-PluginInfo-Name=skrooge_import_kmy
X-KDE-PluginInfo-Version=1.0
-X-KDE-PluginInfo-Website=http://skrooge.org/
+X-KDE-PluginInfo-Website=https://skrooge.org/
X-KDE-PluginInfo-Category=Plugins
X-KDE-PluginInfo-Depends=
X-KDE-PluginInfo-License=GPL
X-KDE-PluginInfo-EnabledByDefault=true
diff --git a/plugins/import/skrooge_import_kmy/skgimportpluginkmy.cpp b/plugins/import/skrooge_import_kmy/skgimportpluginkmy.cpp
index cf243a369..b788899a3 100644
--- a/plugins/import/skrooge_import_kmy/skgimportpluginkmy.cpp
+++ b/plugins/import/skrooge_import_kmy/skgimportpluginkmy.cpp
@@ -1,1749 +1,1749 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is Skrooge plugin for KMY import / export.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgimportpluginkmy.h"
#include <kcompressiondevice.h>
#include <kpluginfactory.h>
#include <qdom.h>
#include <qmath.h>
#include "skgbankincludes.h"
#include "skgimportexportmanager.h"
#include "skgobjectbase.h"
#include "skgpayeeobject.h"
#include "skgservices.h"
#include "skgtraces.h"
/**
* Operations treated.
*/
QSet<QString> SKGImportPluginKmy::m_opTreated;
/**
* Map id / unit.
*/
QMap<QString, SKGUnitObject> SKGImportPluginKmy::m_mapIdUnit;
/**
* Map id / account.
*/
QMap<QString, SKGAccountObject> SKGImportPluginKmy::m_mapIdAccount;
/**
* Map id / category.
*/
QMap<QString, SKGCategoryObject> SKGImportPluginKmy::m_mapIdCategory;
/**
* Map id / payee.
*/
QMap<QString, SKGPayeeObject> SKGImportPluginKmy::m_mapIdPayee;
/**
* This plugin factory.
*/
K_PLUGIN_FACTORY(SKGImportPluginKmyFactory, registerPlugin<SKGImportPluginKmy>();)
SKGImportPluginKmy::SKGImportPluginKmy(QObject* iImporter, const QVariantList& iArg)
: SKGImportPlugin(iImporter)
{
SKGTRACEINFUNC(10)
Q_UNUSED(iArg)
}
SKGImportPluginKmy::~SKGImportPluginKmy()
= default;
bool SKGImportPluginKmy::isImportPossible()
{
SKGTRACEINFUNC(10)
return isExportPossible();
}
SKGError SKGImportPluginKmy::importSecurities(QDomElement& docElem)
{
SKGError err;
QDomElement securities = docElem.firstChildElement(QStringLiteral("SECURITIES"));
if (!err && !securities.isNull()) {
SKGTRACEINRC(10, "SKGImportPluginKmy::importFile-SECURITIES", err)
QDomNodeList securityList = securities.elementsByTagName(QStringLiteral("SECURITY"));
int nb = securityList.count();
err = m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Import step", "Import units"), nb);
for (int i = 0; !err && i < nb; ++i) {
QDomElement security = securityList.at(i).toElement();
QString unitName = security.attribute(QStringLiteral("name"));
// We try a creation
SKGUnitObject unitObj(m_importer->getDocument());
SKGUnitObject::createCurrencyUnit(m_importer->getDocument(), unitName, unitObj);
if (!err && (unitObj.getID() == 0)) {
// Creation of unit
err = unitObj.setName(unitName);
QString symbol = security.attribute(QStringLiteral("symbol"));
if (symbol.isEmpty()) {
symbol = unitName;
}
IFOKDO(err, unitObj.setSymbol(symbol))
IFOKDO(err, unitObj.setCountry(security.attribute(QStringLiteral("trading-market"))))
IFOKDO(err, unitObj.setType(SKGUnitObject::SHARE))
IFOK(err) {
// Set pairs
QDomNodeList pairList = security.elementsByTagName(QStringLiteral("PAIR"));
int nb2 = pairList.count();
for (int j = 0; !err && j < nb2; ++j) {
QDomElement pair = pairList.at(j).toElement();
if (pair.attribute(QStringLiteral("key")).toLower() == QStringLiteral("kmm-security-id")) {
err = unitObj.setInternetCode(pair.attribute(QStringLiteral("value")));
}
}
}
IFOKDO(err, unitObj.save())
}
m_mapIdUnit[security.attribute(QStringLiteral("id"))] = unitObj;
IFOKDO(err, m_importer->getDocument()->stepForward(i + 1))
}
SKGENDTRANSACTION(m_importer->getDocument(), err)
}
return err;
}
SKGError SKGImportPluginKmy::importPrices(QDomElement& docElem)
{
SKGError err;
QDomElement prices = docElem.firstChildElement(QStringLiteral("PRICES"));
if (!err && !prices.isNull()) {
SKGTRACEINRC(10, "SKGImportPluginKmy::importFile-PRICES", err)
QDomNodeList pricepairList = prices.elementsByTagName(QStringLiteral("PRICEPAIR"));
int nb = pricepairList.count();
err = m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Import step", "Import units"), nb);
for (int i = 0; !err && i < nb; ++i) {
QDomElement pricepair = pricepairList.at(i).toElement();
SKGUnitObject unitObj = m_mapIdUnit.value(pricepair.attribute(QStringLiteral("from")));
if (unitObj.getID() != 0) {
// Unit is existing
QDomNodeList pricesList = pricepair.elementsByTagName(QStringLiteral("PRICE"));
int nb2 = pricesList.count();
for (int j = 0; !err && j < nb2; ++j) {
QDomElement price = pricesList.at(j).toElement();
SKGUnitValueObject unitValObj;
err = unitObj.addUnitValue(unitValObj);
IFOKDO(err, unitValObj.setDate(QDate::fromString(price.attribute(QStringLiteral("date")), QStringLiteral("yyyy-MM-dd"))))
IFOKDO(err, unitValObj.setQuantity(toKmyValue(price.attribute(QStringLiteral("price")))))
IFOKDO(err, unitValObj.save(true, false))
}
}
IFOKDO(err, m_importer->getDocument()->stepForward(i + 1))
}
SKGENDTRANSACTION(m_importer->getDocument(), err)
}
return err;
}
SKGError SKGImportPluginKmy::importInstitutions(QMap<QString, SKGBankObject>& mapIdBank, QDomElement& docElem)
{
SKGError err;
QDomElement institutions = docElem.firstChildElement(QStringLiteral("INSTITUTIONS"));
if (!err && !institutions.isNull()) {
SKGTRACEINRC(10, "SKGImportPluginKmy::importFile-INSTITUTIONS", err)
QDomNodeList institutionList = institutions.elementsByTagName(QStringLiteral("INSTITUTION"));
int nb = institutionList.count();
for (int i = 0; !err && i < nb; ++i) {
// Get bank object
QDomElement bank = institutionList.at(i).toElement();
SKGBankObject bankObject(m_importer->getDocument());
err = bankObject.setName(bank.attribute(QStringLiteral("name")));
IFOKDO(err, bankObject.setNumber(bank.attribute(QStringLiteral("sortcode"))))
IFOKDO(err, bankObject.save())
mapIdBank[bank.attribute(QStringLiteral("id"))] = bankObject;
}
}
return err;
}
SKGError SKGImportPluginKmy::importPayees(QMap<QString, SKGPayeeObject>& mapIdPayee, QDomElement& docElem)
{
SKGError err;
QDomElement payees = docElem.firstChildElement(QStringLiteral("PAYEES"));
if (!err && !payees.isNull()) {
SKGTRACEINRC(10, "SKGImportPluginKmy::importFile-PAYEES", err)
QDomNodeList payeeList = payees.elementsByTagName(QStringLiteral("PAYEE"));
int nb = payeeList.count();
for (int i = 0; !err && i < nb; ++i) {
// Get account object
QDomElement payee = payeeList.at(i).toElement();
QDomElement address = payee.firstChildElement(QStringLiteral("ADDRESS"));
SKGPayeeObject payeeObject;
err = SKGPayeeObject::createPayee(m_importer->getDocument(), payee.attribute(QStringLiteral("name")), payeeObject);
IFOK(err) {
QString add = address.attribute(QStringLiteral("street")) % ' ' % address.attribute(QStringLiteral("postcode")) % ' ' % address.attribute(QStringLiteral("city")) % ' ' % address.attribute(QStringLiteral("state")) % ' ' % address.attribute(QStringLiteral("telephone"));
add.replace(QStringLiteral(" "), QStringLiteral(" "));
err = payeeObject.setAddress(add.trimmed());
IFOKDO(err, payeeObject.save())
}
IFOK(err) {
mapIdPayee[payee.attribute(QStringLiteral("id"))] = payeeObject;
}
}
}
return err;
}
SKGError SKGImportPluginKmy::importTransactions(QDomElement& docElem, SKGAccountObject& kmymoneyTemporaryAccount, QMap<QString, SKGPayeeObject>& mapIdPayee)
{
SKGError err;
SKGTRACEINRC(10, "SKGImportPluginKmy::importFile-TRANSACTION", err)
QDomNodeList transactionList = docElem.elementsByTagName(QStringLiteral("TRANSACTION"));
int nb = transactionList.count();
err = m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Import step", "Import operations"), nb);
QVector<QDomNode> suboperationsList;
for (int i = 0; !err && i < nb; ++i) {
// Get operation object
QDomElement operation = transactionList.at(i).toElement();
SKGOperationObject operationObj;
err = kmymoneyTemporaryAccount.addOperation(operationObj, true);
IFOKDO(err, operationObj.setDate(QDate::fromString(operation.attribute(QStringLiteral("postdate")), QStringLiteral("yyyy-MM-dd"))))
IFOKDO(err, operationObj.setComment(operation.attribute(QStringLiteral("memo"))))
IFOKDO(err, operationObj.setImported(true))
IFOKDO(err, operationObj.setImportID("KMY-" % operation.attribute(QStringLiteral("id"))))
IFOK(err) {
QString unitName = operation.attribute(QStringLiteral("commodity"));
if (unitName.isEmpty()) {
unitName = QStringLiteral("??");
}
SKGUnitObject unit(m_importer->getDocument());
err = unit.setName(unitName);
IFOKDO(err, unit.setSymbol(unitName))
IFOK(err) {
if (unit.exist()) {
err = unit.load();
} else {
err = unit.save();
}
IFOKDO(err, operationObj.setUnit(unit))
}
}
IFOKDO(err, operationObj.save(false, false))
// Is it a schedule ?
IFOK(err) {
QDomElement recu = operation.parentNode().toElement();
if (recu.tagName() == QStringLiteral("SCHEDULED_TX")) {
// Yes ==> creation of the schedule
IFOKDO(err, operationObj.load())
IFOKDO(err, operationObj.setTemplate(true))
IFOKDO(err, operationObj.save(true, false))
// Yes ==> creation of the schedule
SKGRecurrentOperationObject recuObj;
IFOKDO(err, operationObj.addRecurrentOperation(recuObj))
IFOKDO(err, recuObj.setDate(operationObj.getDate()))
IFOKDO(err, recuObj.autoWriteEnabled(recu.attribute(QStringLiteral("autoEnter")) == QStringLiteral("1")))
IFOKDO(err, recuObj.setAutoWriteDays(0))
int occu = SKGServices::stringToInt(recu.attribute(QStringLiteral("occurenceMultiplier")));
QString occuType = recu.attribute(QStringLiteral("occurence")); // krazy:exclude=spelling
SKGRecurrentOperationObject::PeriodUnit period;
if (occuType == QStringLiteral("32") ||
occuType == QStringLiteral("1024") ||
occuType == QStringLiteral("256") ||
occuType == QStringLiteral("8192")) {
period = SKGRecurrentOperationObject::MONTH;
} else if (occuType == QStringLiteral("1")) {
period = SKGRecurrentOperationObject::DAY;
IFOKDO(err, recuObj.timeLimit(true))
IFOKDO(err, recuObj.setTimeLimit(1))
} else if (occuType == QStringLiteral("2")) {
period = SKGRecurrentOperationObject::DAY;
} else if (occuType == QStringLiteral("4")) {
period = SKGRecurrentOperationObject::WEEK;
} else if (occuType == QStringLiteral("18")) {
period = SKGRecurrentOperationObject::WEEK;
occu *= 2;
} else {
period = SKGRecurrentOperationObject::YEAR;
}
IFOKDO(err, recuObj.setPeriodIncrement(occu))
IFOKDO(err, recuObj.setPeriodUnit(period))
IFOK(err) {
QString endDate = recu.attribute(QStringLiteral("endDate"));
if (!endDate.isEmpty()) {
IFOKDO(err, recuObj.timeLimit(true))
IFOKDO(err, recuObj.setTimeLimit(QDate::fromString(recu.attribute(QStringLiteral("endDate")), QStringLiteral("yyyy-MM-dd"))))
}
}
if (occuType == QStringLiteral("1") && !recu.attribute(QStringLiteral("lastPayment")).isEmpty()) {
// Single schedule already done
IFOKDO(err, recuObj.timeLimit(true))
IFOKDO(err, recuObj.setTimeLimit(0))
}
IFOKDO(err, recuObj.save(true, false))
}
}
// Get splits
bool parentSet = false;
double quantity = 0;
QDomElement splits = operation.firstChildElement(QStringLiteral("SPLITS"));
int nbSuboperations = 0;
suboperationsList.resize(0);
{
QDomNodeList suboperationsListTmp = splits.elementsByTagName(QStringLiteral("SPLIT"));
nbSuboperations = suboperationsListTmp.count();
for (int j = 0; !err && j < nbSuboperations; ++j) {
QDomElement suboperation = suboperationsListTmp.at(j).toElement();
if (m_mapIdCategory.contains(suboperation.attribute(QStringLiteral("account")))) {
suboperationsList.push_front(suboperation);
} else {
suboperationsList.push_back(suboperation);
}
}
}
SKGSubOperationObject suboperationObj;
for (int j = 0; !err && j < nbSuboperations; ++j) {
QDomElement suboperation = suboperationsList.at(j).toElement();
// Set operation attributes
IFOKDO(err, operationObj.setPayee(mapIdPayee[suboperation.attribute(QStringLiteral("payee"))]))
if (!err && operationObj.getComment().isEmpty()) {
err = operationObj.setComment(suboperation.attribute(QStringLiteral("memo")));
}
IFOKDO(err, operationObj.setNumber(suboperation.attribute(QStringLiteral("number"))))
// Set state
if (operationObj.getStatus() == SKGOperationObject::NONE) {
QString val = suboperation.attribute(QStringLiteral("reconcileflag"));
IFOKDO(err, operationObj.setStatus(val == QStringLiteral("1") ? SKGOperationObject::POINTED : val == QStringLiteral("2") ? SKGOperationObject::CHECKED : SKGOperationObject::NONE))
}
IFOKDO(err, operationObj.save())
if (m_mapIdCategory.contains(suboperation.attribute(QStringLiteral("account")))) {
// It is a split on category
SKGCategoryObject cat = m_mapIdCategory.value(suboperation.attribute(QStringLiteral("account")));
double q = -toKmyValue(suboperation.attribute(QStringLiteral("shares")));
if (!err && ((suboperationObj.getID() == 0) || suboperationObj.getQuantity() != q)) {
err = operationObj.addSubOperation(suboperationObj);
}
IFOKDO(err, suboperationObj.setQuantity(q))
IFOKDO(err, suboperationObj.setCategory(cat))
IFOKDO(err, suboperationObj.setComment(suboperation.attribute(QStringLiteral("memo"))))
IFOKDO(err, suboperationObj.save(true, false))
} else {
QString accountSubOp = suboperation.attribute(QStringLiteral("account"));
if (!accountSubOp.isEmpty()) {
if (nbSuboperations == 1) {
SKGUnitObject unit = m_mapIdUnit.value(accountSubOp);
if (unit.getID() != 0) {
IFOKDO(err, operationObj.setUnit(unit))
}
}
if (!m_mapIdAccount.contains(accountSubOp) || (nbSuboperations == 2 &&
m_mapIdAccount.value(accountSubOp) == kmymoneyTemporaryAccount &&
suboperationsList.at(0).toElement().attribute(QStringLiteral("action")).isEmpty() &&
suboperationsList.at(1).toElement().attribute(QStringLiteral("action")).isEmpty())) {
// Set as initial balance
IFOKDO(err, operationObj.setAttribute(QStringLiteral("d_date"), QStringLiteral("0000-00-00")))
IFOKDO(err, operationObj.setStatus(SKGOperationObject::CHECKED))
IFOKDO(err, operationObj.save(true, false))
if (!err && (suboperationObj.getID() == 0)) {
err = operationObj.addSubOperation(suboperationObj);
}
IFOKDO(err, suboperationObj.setAttribute(QStringLiteral("d_date"), QStringLiteral("0000-00-00")))
IFOKDO(err, suboperationObj.save(true, false))
} else {
// It is a transfer of account
SKGAccountObject act = m_mapIdAccount.value(accountSubOp);
if (parentSet) {
// If the parent is already set, it means that is a transfer
SKGOperationObject operationObj2;
IFOKDO(err, act.addOperation(operationObj2, true))
IFOKDO(err, operationObj2.setTemplate(operationObj.isTemplate()))
IFOKDO(err, operationObj2.setDate(operationObj.getDate()))
IFOKDO(err, operationObj2.setNumber(operationObj.getNumber()))
IFOKDO(err, operationObj2.setComment(operationObj.getComment()))
SKGPayeeObject payeeObject;
operationObj.getPayee(payeeObject);
IFOKDO(err, operationObj2.setPayee(payeeObject))
IFOK(err) {
QString val = suboperation.attribute(QStringLiteral("reconcileflag"));
err = operationObj2.setStatus(val == QStringLiteral("1") ? SKGOperationObject::POINTED : val == QStringLiteral("2") ? SKGOperationObject::CHECKED : SKGOperationObject::NONE);
}
IFOKDO(err, operationObj2.setImported(true))
IFOKDO(err, operationObj2.setImportID(operationObj.getImportID()))
SKGUnitObject unit = m_mapIdUnit.value(accountSubOp);
if (unit.getID() != 0) {
IFOKDO(err, operationObj2.setUnit(unit))
} else {
IFOKDO(err, operationObj.getUnit(unit))
IFOKDO(err, operationObj2.setUnit(unit))
}
IFOKDO(err, operationObj2.save())
IFOKDO(err, operationObj2.setGroupOperation(operationObj))
IFOKDO(err, operationObj2.save())
// Create sub operation on operationObj2
SKGSubOperationObject suboperationObj2;
IFOKDO(err, operationObj2.addSubOperation(suboperationObj2))
IFOK(err) {
// We must take the quality of the split having an action
quantity = toKmyValue(suboperation.attribute(QStringLiteral("shares")));
err = suboperationObj2.setQuantity(quantity);
}
IFOKDO(err, suboperationObj2.setComment(suboperation.attribute(QStringLiteral("memo"))))
IFOKDO(err, suboperationObj2.save(true, false))
} else {
// We set the parent
if (Q_LIKELY(!err) && (act.getID() == 0)) {
err = SKGError(ERR_FAIL, i18nc("Error message", "Account with identifier %1 not found", suboperation.attribute(QStringLiteral("account"))));
}
IFOKDO(err, operationObj.setParentAccount(act, true))
IFOKDO(err, operationObj.save())
// Compute quantity
quantity = toKmyValue(suboperation.attribute(QStringLiteral("shares")));
// Create sub operation on operationObj
quantity -= SKGServices::stringToDouble(operationObj.getAttribute(QStringLiteral("f_QUANTITY")));
if (quantity != 0 || nbSuboperations == 1) {
IFOKDO(err, operationObj.addSubOperation(suboperationObj))
IFOKDO(err, suboperationObj.setQuantity(quantity))
IFOKDO(err, suboperationObj.setComment(suboperation.attribute(QStringLiteral("memo"))))
IFOKDO(err, suboperationObj.save(true, false))
}
parentSet = true;
}
}
}
}
}
if (!err && i % 500 == 0) {
err = m_importer->getDocument()->executeSqliteOrder(QStringLiteral("ANALYZE"));
}
IFOKDO(err, m_importer->getDocument()->stepForward(i + 1))
}
SKGENDTRANSACTION(m_importer->getDocument(), err)
return err;
}
SKGError SKGImportPluginKmy::importBudget(QDomElement& docElem)
{
SKGError err;
QDomElement budgets = docElem.firstChildElement(QStringLiteral("BUDGETS"));
if (!err && !budgets.isNull()) {
SKGTRACEINRC(10, "SKGImportPluginKmy::importFile-BUDGETS", err)
// Build cache of categories
QMap<int, bool> catExpense;
{
SKGStringListList list;
err = m_importer->getDocument()->executeSelectSqliteOrder(QStringLiteral("SELECT id, t_TYPEEXPENSE FROM v_category_display"), list);
int nb = list.count();
for (int i = 1; i < nb; ++i) {
catExpense[SKGServices::stringToInt(list.at(i).at(0))] = (list.at(i).at(0) == QStringLiteral("-"));
}
}
QDomNodeList budgetList = budgets.elementsByTagName(QStringLiteral("BUDGET"));
int nb = budgetList.count();
IFOKDO(err, m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Import step", "Import budgets"), nb))
for (int i = 0; !err && i < nb; ++i) {
QDomElement budget = budgetList.at(i).toElement();
QDomNodeList accountList = budget.elementsByTagName(QStringLiteral("ACCOUNT"));
int nb2 = accountList.count();
for (int j = 0; !err && j < nb2; ++j) {
QDomElement account = accountList.at(j).toElement();
SKGCategoryObject cat = m_mapIdCategory.value(account.attribute(QStringLiteral("id")));
QString budgetlevel = account.attribute(QStringLiteral("budgetlevel"));
QDomNodeList periodList = account.elementsByTagName(QStringLiteral("PERIOD"));
int nb3 = periodList.count();
for (int k = 0; !err && k < nb3; ++k) {
QDomElement period = periodList.at(k).toElement();
double q = toKmyValue(period.attribute(QStringLiteral("amount")));
// Are we able to find to sign with the category ?
if (catExpense[cat.getID()]) {
q = -q;
}
QStringList dates = SKGServices::splitCSVLine(period.attribute(QStringLiteral("start")), '-');
if (dates.count() == 3) {
// We try a creation
for (int m = 1; !err && m <= (budgetlevel == QStringLiteral("monthly") ? 12 : 1); ++m) {
SKGBudgetObject budget2(m_importer->getDocument());
err = budget2.setCategory(cat);
IFOKDO(err, budget2.setBudgetedAmount(q))
IFOKDO(err, budget2.setYear(SKGServices::stringToDouble(dates.at(0))))
IFOKDO(err, budget2.setMonth(budgetlevel == QStringLiteral("monthbymonth") ? SKGServices::stringToDouble(dates.at(1)) :
budgetlevel == QStringLiteral("yearly") ? 0 : m));
IFOKDO(err, budget2.save(true, false))
}
}
}
}
IFOKDO(err, m_importer->getDocument()->stepForward(i + 1))
}
SKGENDTRANSACTION(m_importer->getDocument(), err)
}
return err;
}
SKGError SKGImportPluginKmy::importAccounts(SKGBankObject& bank, SKGAccountObject& kmymoneyTemporaryAccount, QMap<QString, SKGBankObject>& mapIdBank, QDomElement& docElem)
{
SKGError err;
IFOKDO(err, m_importer->getDocument()->addOrModifyAccount(QStringLiteral("KMYMONEY-TEMPORARY-ACCOUNT"), QString(), QStringLiteral("KMYMONEY")))
IFOKDO(err, bank.setName(QStringLiteral("KMYMONEY")))
IFOKDO(err, bank.load())
IFOKDO(err, kmymoneyTemporaryAccount.setName(QStringLiteral("KMYMONEY-TEMPORARY-ACCOUNT")))
IFOKDO(err, kmymoneyTemporaryAccount.load())
QDomElement accounts = docElem.firstChildElement(QStringLiteral("ACCOUNTS"));
if (!err && !accounts.isNull()) {
SKGTRACEINRC(10, "SKGImportPluginKmy::importFile-ACCOUNTS", err)
QDomNodeList accountList = accounts.elementsByTagName(QStringLiteral("ACCOUNT"));
int nb = accountList.count();
err = m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Import step", "Import accounts"), nb);
QMap<QString, QString> type15Account;
QMap<QString, QString> type15Unit;
for (int i = 0; !err && i < nb; ++i) {
// Get account object
QDomElement account = accountList.at(i).toElement();
QString type = account.attribute(QStringLiteral("type"));
if (type == QStringLiteral("15")) {
// Actions: the real account is the parent
type15Account[account.attribute(QStringLiteral("id"))] = account.attribute(QStringLiteral("parentaccount"));
type15Unit[account.attribute(QStringLiteral("id"))] = account.attribute(QStringLiteral("currency"));
} else if (type != QStringLiteral("12") && type != QStringLiteral("13") && type != QStringLiteral("16")) {
// Get the bank
QString bankId = account.attribute(QStringLiteral("institution"));
SKGBankObject bankObj = (bankId.isEmpty() ? bank : mapIdBank[account.attribute(QStringLiteral("institution"))]);
// Creation of the account
SKGAccountObject accountObj;
IFOKDO(err, bankObj.addAccount(accountObj))
IFOKDO(err, accountObj.setName(account.attribute(QStringLiteral("name"))))
IFOKDO(err, accountObj.setNumber(account.attribute(QStringLiteral("number"))))
IFOKDO(err, accountObj.setComment(account.attribute(QStringLiteral("description"))))
IFOK(err) {
SKGAccountObject::AccountType typeA = (type == QStringLiteral("4") ? SKGAccountObject::CREDITCARD : (type == QStringLiteral("7") ? SKGAccountObject::INVESTMENT : (type == QStringLiteral("9") ? SKGAccountObject::ASSETS : (type == QStringLiteral("3") ? SKGAccountObject::WALLET : (type == QStringLiteral("10") ? SKGAccountObject::LOAN : SKGAccountObject::CURRENT)))));
err = accountObj.setType(typeA);
}
IFOK(err) {
// Set pairs
QDomNodeList pairList = account.elementsByTagName(QStringLiteral("PAIR"));
int nb2 = pairList.count();
for (int j = 0; !err && j < nb2; ++j) {
QDomElement pair = pairList.at(j).toElement();
if (pair.attribute(QStringLiteral("key")).toLower() == QStringLiteral("mm-closed") && pair.attribute(QStringLiteral("value")).toLower() == QStringLiteral("yes")) {
err = accountObj.setClosed(true);
} else if (pair.attribute(QStringLiteral("key")).toLower() == QStringLiteral("preferredaccount") && pair.attribute(QStringLiteral("value")).toLower() == QStringLiteral("yes")) {
err = accountObj.bookmark(true);
} else if (pair.attribute(QStringLiteral("key")).toLower() == QStringLiteral("minbalanceabsolute")) {
err = accountObj.setMinLimitAmount(toKmyValue(pair.attribute(QStringLiteral("value"))));
IFOKDO(err, accountObj.minLimitAmountEnabled(true))
} else if (pair.attribute(QStringLiteral("key")).toLower() == QStringLiteral("maxcreditabsolute")) {
err = accountObj.setMaxLimitAmount(-toKmyValue(pair.attribute(QStringLiteral("value"))));
IFOKDO(err, accountObj.maxLimitAmountEnabled(true))
}
}
}
IFOKDO(err, accountObj.save())
// Change parent bank in case of ASSETS
if (accountObj.getType() == SKGAccountObject::WALLET) {
// Get blank bank
SKGBankObject blankBank(m_importer->getDocument());
IFOKDO(err, blankBank.setName(QString()))
if (blankBank.exist()) {
err = blankBank.load();
} else {
err = blankBank.save();
}
IFOKDO(err, accountObj.setBank(blankBank))
IFOKDO(err, accountObj.save())
}
m_mapIdAccount[account.attribute(QStringLiteral("id"))] = accountObj;
} else if (type == QStringLiteral("16")) {
m_mapIdAccount[account.attribute(QStringLiteral("id"))] = kmymoneyTemporaryAccount;
} else {
// Create category
SKGCategoryObject cat = m_mapIdCategory.value(account.attribute(QStringLiteral("id")));
if (cat.getID() != 0) {
// Already existing ==> we must set the right name
err = cat.setName(account.attribute(QStringLiteral("name")));
IFOKDO(err, cat.save())
} else {
// We must create it
cat = SKGCategoryObject(m_importer->getDocument());
err = cat.setName(account.attribute(QStringLiteral("name")));
IFOKDO(err, cat.save())
}
if (err) {
// The category already exists
SKGCategoryObject catp;
err = cat.getParentCategory(catp);
QString fullName = catp.getFullName() % OBJECTSEPARATOR % cat.getName();
IFOKDO(err, cat.remove(false))
IFOKDO(err, SKGCategoryObject::createPathCategory(m_importer->getDocument(), fullName, cat))
}
m_mapIdCategory[account.attribute(QStringLiteral("id"))] = cat;
// Create sub categories
QDomNodeList subaccountList = account.elementsByTagName(QStringLiteral("SUBACCOUNT"));
int nb2 = subaccountList.count();
for (int j = 0; !err && j < nb2; ++j) {
QDomElement subaccount = subaccountList.at(j).toElement();
// Is child already existing ?
SKGCategoryObject cat2 = m_mapIdCategory.value(subaccount.attribute(QStringLiteral("id")));
if (cat2.getID() != 0) {
// Yes ==> reparent
err = cat2.setParentCategory(cat);
IFOKDO(err, cat2.save(true, false))
} else {
// No ==> create
IFOKDO(err, cat.addCategory(cat2))
IFOKDO(err, cat2.setName(subaccount.attribute(QStringLiteral("id"))))
IFOKDO(err, cat2.save())
m_mapIdCategory[subaccount.attribute(QStringLiteral("id"))] = cat2;
}
}
}
QStringList list = type15Account.keys();
for (const auto& k : qAsConst(list)) {
m_mapIdAccount[k] = m_mapIdAccount.value(type15Account[k]);
m_mapIdUnit[account.attribute(QStringLiteral("id"))] = m_mapIdUnit.value(account.attribute(QStringLiteral("currency")));
}
list = type15Unit.keys();
for (const auto& k : qAsConst(list)) {
m_mapIdUnit[k] = m_mapIdUnit[type15Unit[k]];
}
IFOKDO(err, m_importer->getDocument()->stepForward(i + 1))
}
SKGENDTRANSACTION(m_importer->getDocument(), err)
}
return err;
}
SKGError SKGImportPluginKmy::importFile()
{
if (m_importer == nullptr) {
return SKGError(ERR_ABORT, i18nc("Error message", "Invalid parameters"));
}
SKGError err;
SKGTRACEINFUNCRC(2, err)
// Initialisation
m_mapIdUnit.clear();
m_mapIdAccount.clear();
m_mapIdCategory.clear();
m_mapIdPayee.clear();
// Open file
KCompressionDevice file(m_importer->getLocalFileName(), KCompressionDevice::GZip);
if (!file.open(QIODevice::ReadOnly)) {
err.setReturnCode(ERR_INVALIDARG).setMessage(i18nc("Error message", "Open file '%1' failed", m_importer->getFileName().toDisplayString()));
} else {
QDomDocument doc;
// Set the file without uncompression
QString errorMsg;
int errorLine = 0;
int errorCol = 0;
bool contentOK = doc.setContent(file.readAll(), &errorMsg, &errorLine, &errorCol);
file.close();
if (!contentOK) {
err.setReturnCode(ERR_ABORT).setMessage(i18nc("Error message", "%1-%2: '%3'", errorLine, errorCol, errorMsg)).addError(ERR_INVALIDARG, i18nc("Error message", "Invalid XML content in file '%1'", m_importer->getFileName().toDisplayString()));
} else {
// Get root
QDomElement docElem = doc.documentElement();
err = m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Import step", "Import %1 file", "KMY"), 8);
// Step 1-Get units
IFOKDO(err, importSecurities(docElem))
IFOKDO(err, m_importer->getDocument()->stepForward(1))
// Step 2-Get units prices
IFOKDO(err, importPrices(docElem))
IFOKDO(err, m_importer->getDocument()->stepForward(2))
// Step 3-Create banks
QMap<QString, SKGBankObject> mapIdBank;
IFOKDO(err, importInstitutions(mapIdBank, docElem))
IFOKDO(err, m_importer->getDocument()->stepForward(3))
// Step 4-Create account and categories
// Create bank and temporary account for kmymoney import
SKGAccountObject kmymoneyTemporaryAccount(m_importer->getDocument());
SKGBankObject bank(m_importer->getDocument());
IFOKDO(err, importAccounts(bank, kmymoneyTemporaryAccount, mapIdBank, docElem))
IFOKDO(err, m_importer->getDocument()->stepForward(4))
// Step 5-Read payees
QMap<QString, SKGPayeeObject> mapIdPayee;
IFOKDO(err, importPayees(mapIdPayee, docElem))
IFOKDO(err, m_importer->getDocument()->stepForward(5))
// Step 6-Create operations
IFOKDO(err, importTransactions(docElem, kmymoneyTemporaryAccount, mapIdPayee))
IFOKDO(err, m_importer->getDocument()->stepForward(6))
// Step 7-Get budgets
IFOKDO(err, importBudget(docElem))
IFOKDO(err, m_importer->getDocument()->stepForward(7))
// Step 8-Remove useless account and temporary account
{
IFOKDO(err, kmymoneyTemporaryAccount.remove(false, true))
IFOKDO(err, m_importer->getDocument()->executeSqliteOrder("DELETE FROM account WHERE rd_bank_id=" % SKGServices::intToString(bank.getID()) % " AND (SELECT COUNT(1) FROM operation WHERE operation.rd_account_id=account.id)=0"))
}
IFOKDO(err, m_importer->getDocument()->stepForward(8))
SKGENDTRANSACTION(m_importer->getDocument(), err)
IFOKDO(err, m_importer->getDocument()->executeSqliteOrder(QStringLiteral("ANALYZE")))
}
}
// Clean
m_mapIdUnit.clear();
m_mapIdAccount.clear();
m_mapIdCategory.clear();
m_mapIdPayee.clear();
return err;
}
bool SKGImportPluginKmy::isExportPossible()
{
SKGTRACEINFUNC(10)
return (m_importer == nullptr ? true : m_importer->getFileNameExtension() == QStringLiteral("KMY"));
}
SKGError SKGImportPluginKmy::exportHeader(QDomDocument& doc, QDomElement& root)
{
SKGError err;
QDomElement fileindo = doc.createElement(QStringLiteral("FILEINFO"));
root.appendChild(fileindo);
{
// <CREATION_DATE>
QDomElement creation_date = doc.createElement(QStringLiteral("CREATION_DATE"));
fileindo.appendChild(creation_date);
creation_date.setAttribute(QStringLiteral("date"), SKGServices::dateToSqlString(QDateTime::currentDateTime()));
// <LAST_MODIFIED_DATE>
QDomElement last_modified_date = doc.createElement(QStringLiteral("LAST_MODIFIED_DATE"));
fileindo.appendChild(last_modified_date);
last_modified_date.setAttribute(QStringLiteral("date"), SKGServices::dateToSqlString(QDateTime::currentDateTime()));
// <VERSION>
QDomElement version = doc.createElement(QStringLiteral("VERSION"));
fileindo.appendChild(version);
version.setAttribute(QStringLiteral("id"), QStringLiteral("1"));
// <FIXVERSION>
QDomElement fixversion = doc.createElement(QStringLiteral("FIXVERSION"));
fileindo.appendChild(fixversion);
fixversion.setAttribute(QStringLiteral("id"), QStringLiteral("2"));
}
// <USER>
QDomElement user = doc.createElement(QStringLiteral("USER"));
root.appendChild(user);
user.setAttribute(QStringLiteral("email"), QString());
user.setAttribute(QStringLiteral("name"), QString());
{
// ADDRESS
QDomElement address = doc.createElement(QStringLiteral("ADDRESS"));
user.appendChild(address);
address.setAttribute(QStringLiteral("street"), QString());
address.setAttribute(QStringLiteral("zipcode"), QString());
address.setAttribute(QStringLiteral("county"), QString());
address.setAttribute(QStringLiteral("city"), QString());
address.setAttribute(QStringLiteral("telephone"), QString());
}
return err;
}
SKGError SKGImportPluginKmy::exportSecurities(QDomDocument& doc, QDomElement& root, const QString& stdUnit)
{
SKGError err;
QDomElement securities = doc.createElement(QStringLiteral("SECURITIES"));
root.appendChild(securities);
QDomElement currencies = doc.createElement(QStringLiteral("CURRENCIES"));
root.appendChild(currencies);
SKGObjectBase::SKGListSKGObjectBase objects;
IFOKDO(err, m_importer->getDocument()->getObjects(QStringLiteral("v_unit"), QStringLiteral("t_type!='I'"), objects))
int nb = objects.count();
securities.setAttribute(QStringLiteral("count"), SKGServices::intToString(nb));
QStringList importedCurrency;
IFOK(err) {
err = m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Export step", "Export units"), nb);
for (int i = 0; !err && i < nb; ++i) {
SKGUnitObject obj(objects.at(i));
if (obj.getType() == SKGUnitObject::SHARE || obj.getType() == SKGUnitObject::OBJECT) {
QDomElement security = doc.createElement(QStringLiteral("SECURITY"));
securities.appendChild(security);
SKGUnitObject parentUnit;
obj.getUnit(parentUnit);
QString unitP = SKGUnitObject::getInternationalCode(parentUnit.getName());
if (unitP.isEmpty()) {
unitP = stdUnit;
}
security.setAttribute(QStringLiteral("id"), obj.getName());
security.setAttribute(QStringLiteral("trading-currency"), unitP);
security.setAttribute(QStringLiteral("saf"), QStringLiteral("100000"));
security.setAttribute(QStringLiteral("symbol"), obj.getSymbol());
security.setAttribute(QStringLiteral("trading-market"), obj.getCountry());
security.setAttribute(QStringLiteral("type"), QStringLiteral("4"));
security.setAttribute(QStringLiteral("name"), obj.getName());
QString internetCode = obj.getInternetCode();
if (!internetCode.isEmpty()) {
QDomElement keyvaluepairs2 = doc.createElement(QStringLiteral("KEYVALUEPAIRS"));
security.appendChild(keyvaluepairs2);
QDomElement pair1 = doc.createElement(QStringLiteral("PAIR"));
keyvaluepairs2.appendChild(pair1);
pair1.setAttribute(QStringLiteral("key"), QStringLiteral("kmm-online-source"));
pair1.setAttribute(QStringLiteral("value"), QStringLiteral("Yahoo"));
QDomElement pair2 = doc.createElement(QStringLiteral("PAIR"));
keyvaluepairs2.appendChild(pair2);
pair2.setAttribute(QStringLiteral("key"), QStringLiteral("kmm-security-id"));
pair2.setAttribute(QStringLiteral("value"), internetCode);
}
} else {
QDomElement currency = doc.createElement(QStringLiteral("CURRENCY"));
currencies.appendChild(currency);
QString unit = SKGUnitObject::getInternationalCode(obj.getName());
if (unit.isEmpty()) {
unit = obj.getName();
}
currency.setAttribute(QStringLiteral("saf"), QStringLiteral("100"));
currency.setAttribute(QStringLiteral("symbol"), obj.getSymbol());
currency.setAttribute(QStringLiteral("type"), QStringLiteral("3"));
currency.setAttribute(QStringLiteral("id"), unit);
currency.setAttribute(QStringLiteral("name"), obj.getName());
currency.setAttribute(QStringLiteral("ppu"), QStringLiteral("100"));
currency.setAttribute(QStringLiteral("scf"), QStringLiteral("100"));
importedCurrency.push_back(obj.getSymbol());
}
IFOKDO(err, m_importer->getDocument()->stepForward(i + 1))
}
SKGENDTRANSACTION(m_importer->getDocument(), err)
}
// <CURRENCIES>
QStringList units = SKGUnitObject::getListofKnownCurrencies(false);
nb = units.count();
int nbreal = 0;
for (int i = 0; i < nb; ++i) {
SKGServices::SKGUnitInfo info = SKGUnitObject::getUnitInfo(units.at(i));
if (info.Name != info.Symbol && !importedCurrency.contains(info.Symbol)) {
QDomElement currency = doc.createElement(QStringLiteral("CURRENCY"));
currencies.appendChild(currency);
currency.setAttribute(QStringLiteral("saf"), QStringLiteral("100"));
currency.setAttribute(QStringLiteral("symbol"), info.Symbol);
currency.setAttribute(QStringLiteral("type"), QStringLiteral("3"));
currency.setAttribute(QStringLiteral("id"), SKGUnitObject::getInternationalCode(info.Name));
currency.setAttribute(QStringLiteral("name"), info.Name);
currency.setAttribute(QStringLiteral("ppu"), QStringLiteral("100"));
currency.setAttribute(QStringLiteral("scf"), QStringLiteral("100"));
++nbreal;
}
}
currencies.setAttribute(QStringLiteral("count"), SKGServices::intToString(nbreal));
// <PRICES>
QDomElement prices = doc.createElement(QStringLiteral("PRICES"));
root.appendChild(prices);
IFOKDO(err, m_importer->getDocument()->getObjects(QStringLiteral("v_unit"), QStringLiteral("t_type='S'"), objects))
nb = objects.count();
prices.setAttribute(QStringLiteral("count"), SKGServices::intToString(nb));
IFOK(err) {
err = m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Export step", "Export units"), nb);
for (int i = 0; !err && i < nb; ++i) {
SKGUnitObject obj(objects.at(i));
QDomElement pricepair = doc.createElement(QStringLiteral("PRICEPAIR"));
prices.appendChild(pricepair);
QString unitP = SKGUnitObject::getInternationalCode(obj.getName());
if (unitP.isEmpty()) {
unitP = stdUnit;
}
pricepair.setAttribute(QStringLiteral("from"), obj.getName());
pricepair.setAttribute(QStringLiteral("to"), unitP);
SKGObjectBase::SKGListSKGObjectBase unitValues;
err = obj.getUnitValues(unitValues);
int nb2 = unitValues.count();
for (int j = 0; !err && j < nb2; ++j) {
QDomElement price = doc.createElement(QStringLiteral("PRICE"));
pricepair.appendChild(price);
SKGUnitValueObject unitval(unitValues.at(j));
price.setAttribute(QStringLiteral("price"), SKGImportPluginKmy::kmyValue(unitval.getQuantity()));
price.setAttribute(QStringLiteral("source"), QStringLiteral("Utilisateur"));
price.setAttribute(QStringLiteral("date"), SKGServices::dateToSqlString(QDateTime(unitval.getDate())));
}
IFOKDO(err, m_importer->getDocument()->stepForward(i + 1))
}
SKGENDTRANSACTION(m_importer->getDocument(), err)
}
// <REPORTS>
QDomElement reports = doc.createElement(QStringLiteral("REPORTS"));
root.appendChild(reports);
reports.setAttribute(QStringLiteral("count"), QStringLiteral("0"));
return err;
}
SKGError SKGImportPluginKmy::exportBudgets(QDomDocument& doc, QDomElement& root)
{
SKGError err;
QDomElement budgets = doc.createElement(QStringLiteral("BUDGETS"));
root.appendChild(budgets);
SKGObjectBase::SKGListSKGObjectBase objects;
IFOKDO(err, m_importer->getDocument()->getObjects(QStringLiteral("v_budget"), QStringLiteral("1=1 ORDER BY i_year, i_month"), objects))
int nb = objects.count();
int nbBudgets = 0;
int currentYear = 0;
QDomElement budget;
QMap<QString, QDomElement> mapCatAccount;
IFOK(err) {
err = m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Export step", "Export budgets"), nb);
for (int i = 0; !err && i < nb; ++i) {
SKGBudgetObject obj(objects.at(i));
SKGCategoryObject cat;
obj.getCategory(cat);
QString catId = getKmyUniqueIdentifier(cat);
int year = obj.getYear();
QString yearString = SKGServices::intToString(year);
int month = obj.getMonth();
QString monthString = SKGServices::intToString(month);
if (monthString.isEmpty()) {
monthString = '0' % monthString;
}
if (currentYear != year) {
budget = doc.createElement(QStringLiteral("BUDGET"));
budgets.appendChild(budget);
budget.setAttribute(QStringLiteral("version"), QStringLiteral("2"));
budget.setAttribute(QStringLiteral("id"), yearString);
budget.setAttribute(QStringLiteral("start"), yearString % "-01-01");
budget.setAttribute(QStringLiteral("name"), yearString);
currentYear = year;
mapCatAccount.clear();
++nbBudgets;
}
QDomElement account = mapCatAccount[catId];
if (account.isNull() && !catId.isEmpty()) {
account = doc.createElement(QStringLiteral("ACCOUNT"));
budget.appendChild(account);
account.setAttribute(QStringLiteral("budgetsubaccounts"), QStringLiteral("0"));
account.setAttribute(QStringLiteral("id"), catId);
mapCatAccount[catId] = account;
}
if (!account.isNull()) {
account.setAttribute(QStringLiteral("budgetlevel"), obj.getMonth() == 0 ? QStringLiteral("yearly") : QStringLiteral("monthbymonth"));
QDomElement period = doc.createElement(QStringLiteral("PERIOD"));
account.appendChild(period);
period.setAttribute(QStringLiteral("amount"), SKGImportPluginKmy::kmyValue(qAbs(obj.getBudgetedAmount())));
period.setAttribute(QStringLiteral("start"), yearString % '-' % (obj.getMonth() == 0 ? QStringLiteral("01") : monthString) % "-01");
}
IFOKDO(err, m_importer->getDocument()->stepForward(i + 1))
}
SKGENDTRANSACTION(m_importer->getDocument(), err)
}
budgets.setAttribute(QStringLiteral("count"), SKGServices::intToString(nbBudgets));
return err;
}
SKGError SKGImportPluginKmy::exportSchedules(QDomDocument& doc, QDomElement& root)
{
SKGError err;
QDomElement schedules = doc.createElement(QStringLiteral("SCHEDULES"));
root.appendChild(schedules);
SKGObjectBase::SKGListSKGObjectBase objects;
IFOKDO(err, m_importer->getDocument()->getObjects(QStringLiteral("v_recurrentoperation"), QString(), objects))
int nb = objects.count();
schedules.setAttribute(QStringLiteral("count"), SKGServices::intToString(nb));
IFOK(err) {
err = m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Export step", "Export scheduled operations"), nb);
for (int i = 0; !err && i < nb; ++i) {
SKGRecurrentOperationObject obj(objects.at(i));
SKGOperationObject op;
err = obj.getParentOperation(op);
IFOK(err) {
QDomElement scheduled_tx = doc.createElement(QStringLiteral("SCHEDULED_TX"));
schedules.appendChild(scheduled_tx);
scheduled_tx.setAttribute(QStringLiteral("id"), getKmyUniqueIdentifier(obj));
scheduled_tx.setAttribute(QStringLiteral("name"), getKmyUniqueIdentifier(obj));
scheduled_tx.setAttribute(QStringLiteral("startDate"), obj.getAttribute(QStringLiteral("d_date")));
scheduled_tx.setAttribute(QStringLiteral("lastPayment"), obj.getAttribute(QStringLiteral("d_date")));
bool autoEnter = obj.isAutoWriteEnabled();
scheduled_tx.setAttribute(QStringLiteral("autoEnter"), autoEnter ? QStringLiteral("1") : QStringLiteral("0"));
QString occuType;
int occu = obj.getPeriodIncrement();
SKGRecurrentOperationObject::PeriodUnit punit = obj.getPeriodUnit();
if (punit == SKGRecurrentOperationObject::MONTH) {
occuType = QStringLiteral("32");
} else if (punit == SKGRecurrentOperationObject::WEEK) {
occuType = '4';
} else if (punit == SKGRecurrentOperationObject::DAY) {
occuType = '2';
} else {
occuType = QStringLiteral("16384");
}
scheduled_tx.setAttribute(QStringLiteral("occurenceMultiplier"), SKGServices::intToString(occu));
scheduled_tx.setAttribute(QStringLiteral("occurence"), occuType); // krazy:exclude=spelling
scheduled_tx.setAttribute(QStringLiteral("weekendOption"), QStringLiteral("0"));
scheduled_tx.setAttribute(QStringLiteral("paymentType"), QStringLiteral("1"));
QChar type = '1';
SKGOperationObject op2;
if (op.isTransfer(op2)) {
type = '4';
} else if (op.getCurrentAmount() > 0) {
type = '2';
}
scheduled_tx.setAttribute(QStringLiteral("type"), type);
scheduled_tx.setAttribute(QStringLiteral("fixed"), QStringLiteral("1"));
QString endDate;
if (obj.hasTimeLimit()) {
QDate firstDate = obj.getDate();
// We must compute the date
int p = occu * (obj.getTimeLimit() - 1);
if (punit == SKGRecurrentOperationObject::DAY) {
firstDate = firstDate.addDays(p);
} else if (punit == SKGRecurrentOperationObject::MONTH) {
firstDate = firstDate.addMonths(p);
} else if (punit == SKGRecurrentOperationObject::YEAR) {
firstDate = firstDate.addYears(p);
}
endDate = firstDate.toString(QStringLiteral("yyyy-MM-dd"));
}
scheduled_tx.setAttribute(QStringLiteral("endDate"), endDate);
err = exportOperation(op, doc, scheduled_tx);
}
IFOKDO(err, m_importer->getDocument()->stepForward(i + 1))
}
SKGENDTRANSACTION(m_importer->getDocument(), err)
}
return err;
}
SKGError SKGImportPluginKmy::exportTransactions(QDomDocument& doc, QDomElement& root, const QString& stdUnit)
{
SKGError err;
QDomElement transactions = doc.createElement(QStringLiteral("TRANSACTIONS"));
root.appendChild(transactions);
SKGObjectBase::SKGListSKGObjectBase objects;
IFOKDO(err, m_importer->getDocument()->getObjects(QStringLiteral("v_operation"), QStringLiteral("t_template='N' ORDER BY d_date DESC"), objects))
int nb = objects.count();
transactions.setAttribute(QStringLiteral("count"), SKGServices::intToString(nb));
IFOK(err) {
err = m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Export step", "Export operations"), nb);
for (int i = 0; !err && i < nb; ++i) {
SKGOperationObject op(objects.at(i));
err = exportOperation(op, doc, transactions);
IFOKDO(err, m_importer->getDocument()->stepForward(i + 1))
}
SKGENDTRANSACTION(m_importer->getDocument(), err)
}
// <KEYVALUEPAIRS>
QDomElement keyvaluepairs = doc.createElement(QStringLiteral("KEYVALUEPAIRS"));
root.appendChild(keyvaluepairs);
{
QDomElement pair = doc.createElement(QStringLiteral("PAIR"));
keyvaluepairs.appendChild(pair);
pair.setAttribute(QStringLiteral("key"), QStringLiteral("kmm-baseCurrency"));
pair.setAttribute(QStringLiteral("value"), stdUnit);
}
return err;
}
SKGError SKGImportPluginKmy::exportPayees(QDomDocument& doc, QDomElement& root)
{
SKGError err;
QDomElement payees = doc.createElement(QStringLiteral("PAYEES"));
root.appendChild(payees);
SKGObjectBase::SKGListSKGObjectBase listPayees;
IFOKDO(err, m_importer->getDocument()->getObjects(QStringLiteral("v_payee"), QString(), listPayees))
int nb = listPayees.count();
payees.setAttribute(QStringLiteral("count"), SKGServices::intToString(nb));
IFOK(err) {
err = m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Export step", "Export payees"), nb);
for (int i = 0; !err && i < nb; ++i) {
SKGPayeeObject payeeObject(listPayees.at(i));
QDomElement payee = doc.createElement(QStringLiteral("PAYEE"));
payees.appendChild(payee);
payee.setAttribute(QStringLiteral("matchingenabled"), QStringLiteral("0"));
payee.setAttribute(QStringLiteral("id"), getKmyUniqueIdentifier(payeeObject));
payee.setAttribute(QStringLiteral("name"), payeeObject.getName());
payee.setAttribute(QStringLiteral("email"), QString());
payee.setAttribute(QStringLiteral("reference"), QString());
QDomElement address = doc.createElement(QStringLiteral("ADDRESS"));
payee.appendChild(address);
address.setAttribute(QStringLiteral("street"), payeeObject.getAddress());
address.setAttribute(QStringLiteral("postcode"), QString());
address.setAttribute(QStringLiteral("zip"), QString());
address.setAttribute(QStringLiteral("city"), QString());
address.setAttribute(QStringLiteral("telephone"), QString());
address.setAttribute(QStringLiteral("state"), QString());
m_mapIdPayee[SKGServices::intToString(i + 1)] = payeeObject;
IFOKDO(err, m_importer->getDocument()->stepForward(i + 1))
}
SKGENDTRANSACTION(m_importer->getDocument(), err)
}
return err;
}
SKGError SKGImportPluginKmy::exportInstitutions(QDomDocument& doc, QDomElement& root)
{
SKGError err;
QDomElement institutions = doc.createElement(QStringLiteral("INSTITUTIONS"));
root.appendChild(institutions);
SKGObjectBase::SKGListSKGObjectBase objects;
IFOKDO(err, m_importer->getDocument()->getObjects(QStringLiteral("v_bank"), QStringLiteral("EXISTS(SELECT 1 FROM account WHERE account.rd_bank_id=v_bank.id)"), objects))
int nb = objects.count();
institutions.setAttribute(QStringLiteral("count"), SKGServices::intToString(nb));
IFOK(err) {
err = m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Export step", "Export banks"), nb);
for (int i = 0; !err && i < nb; ++i) {
SKGBankObject obj(objects.at(i));
QDomElement institution = doc.createElement(QStringLiteral("INSTITUTION"));
institutions.appendChild(institution);
institution.setAttribute(QStringLiteral("id"), getKmyUniqueIdentifier(obj));
institution.setAttribute(QStringLiteral("name"), obj.getName());
institution.setAttribute(QStringLiteral("sortcode"), obj.getNumber());
institution.setAttribute(QStringLiteral("manager"), QString());
QDomElement address = doc.createElement(QStringLiteral("ADDRESS"));
institution.appendChild(address);
address.setAttribute(QStringLiteral("street"), QString());
address.setAttribute(QStringLiteral("zip"), QString());
address.setAttribute(QStringLiteral("city"), QString());
address.setAttribute(QStringLiteral("telephone"), QString());
QDomElement accountids = doc.createElement(QStringLiteral("ACCOUNTIDS"));
institution.appendChild(accountids);
SKGObjectBase::SKGListSKGObjectBase accounts;
err = obj.getAccounts(accounts);
int nb2 = accounts.count();
for (int j = 0; !err && j < nb2; ++j) {
QDomElement accountid = doc.createElement(QStringLiteral("ACCOUNTID"));
accountids.appendChild(accountid);
accountid.setAttribute(QStringLiteral("id"), getKmyUniqueIdentifier(accounts.at(j)));
}
IFOKDO(err, m_importer->getDocument()->stepForward(i + 1))
}
SKGENDTRANSACTION(m_importer->getDocument(), err)
}
return err;
}
SKGError SKGImportPluginKmy::exportCategories(QDomDocument& doc, QDomElement& accounts, const QString& stdUnit, QDomElement& accountIncome, QDomElement& accountExpense, int nbAccount)
{
// The v_category_display are retrieved to improve performances of getCurrentAmount
SKGError err;
SKGObjectBase::SKGListSKGObjectBase objects;
IFOKDO(err, m_importer->getDocument()->getObjects(QStringLiteral("v_category_display"), QString(), objects))
accounts.setAttribute(QStringLiteral("count"), SKGServices::intToString(5 + nbAccount + objects.count()));
int nb = objects.count();
IFOK(err) {
err = m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Export step", "Export categories"), nb);
for (int i = 0; !err && i < nb; ++i) {
SKGCategoryObject obj(objects.at(i));
QDomElement account = doc.createElement(QStringLiteral("ACCOUNT"));
accounts.appendChild(account);
account.setAttribute(QStringLiteral("id"), getKmyUniqueIdentifier(obj));
account.setAttribute(QStringLiteral("name"), obj.getName());
account.setAttribute(QStringLiteral("number"), QString());
account.setAttribute(QStringLiteral("type"), obj.getCurrentAmount() < 0 ? QStringLiteral("13") : QStringLiteral("12"));
account.setAttribute(QStringLiteral("institution"), QString());
SKGCategoryObject parentCat;
obj.getParentCategory(parentCat);
QString parentId = (parentCat.getID() != 0 ? getKmyUniqueIdentifier(parentCat) : (obj.getCurrentAmount() < 0 ? QStringLiteral("AStd::Expense") : QStringLiteral("AStd::Income")));
if (parentId == QStringLiteral("AStd::Expense")) {
QDomElement subaccount = doc.createElement(QStringLiteral("SUBACCOUNT"));
accountExpense.appendChild(subaccount);
subaccount.setAttribute(QStringLiteral("id"), getKmyUniqueIdentifier(obj));
} else if (parentId == QStringLiteral("AStd::Income")) {
QDomElement subaccount = doc.createElement(QStringLiteral("SUBACCOUNT"));
accountIncome.appendChild(subaccount);
subaccount.setAttribute(QStringLiteral("id"), getKmyUniqueIdentifier(obj));
}
account.setAttribute(QStringLiteral("parentaccount"), parentId);
account.setAttribute(QStringLiteral("lastmodified"), QString());
account.setAttribute(QStringLiteral("lastreconciled"), QString());
account.setAttribute(QStringLiteral("opened"), QString());
account.setAttribute(QStringLiteral("currency"), stdUnit);
account.setAttribute(QStringLiteral("description"), QString());
QDomElement subaccounts = doc.createElement(QStringLiteral("SUBACCOUNTS"));
account.appendChild(subaccounts);
SKGObjectBase::SKGListSKGObjectBase categories;
IFOKDO(err, obj.getCategories(categories))
int nb2 = categories.count();
for (int j = 0; !err && j < nb2; ++j) {
QDomElement subaccount = doc.createElement(QStringLiteral("SUBACCOUNT"));
subaccounts.appendChild(subaccount);
subaccount.setAttribute(QStringLiteral("id"), getKmyUniqueIdentifier(categories.at(j)));
}
IFOKDO(err, m_importer->getDocument()->stepForward(i + 1))
}
SKGENDTRANSACTION(m_importer->getDocument(), err)
}
return err;
}
SKGError SKGImportPluginKmy::exportAccounts(QDomDocument& doc, QDomElement& root, const QString& stdUnit, QDomElement& accounts, QDomElement& accountIncome, QDomElement& accountExpense, int& nbAccounts)
{
SKGError err;
accounts = doc.createElement(QStringLiteral("ACCOUNTS"));
root.appendChild(accounts);
QDomElement accountAsset;
{
QDomElement account = doc.createElement(QStringLiteral("ACCOUNT"));
accounts.appendChild(account);
account.setAttribute(QStringLiteral("id"), QStringLiteral("AStd::Equity"));
account.setAttribute(QStringLiteral("name"), QStringLiteral("Equity"));
account.setAttribute(QStringLiteral("number"), QString());
account.setAttribute(QStringLiteral("type"), QStringLiteral("16"));
account.setAttribute(QStringLiteral("institution"), QString());
account.setAttribute(QStringLiteral("parentaccount"), QString());
account.setAttribute(QStringLiteral("lastmodified"), QString());
account.setAttribute(QStringLiteral("lastreconciled"), QString());
account.setAttribute(QStringLiteral("opened"), QString());
account.setAttribute(QStringLiteral("currency"), stdUnit);
account.setAttribute(QStringLiteral("description"), QString());
QDomElement subaccounts = doc.createElement(QStringLiteral("SUBACCOUNTS"));
account.appendChild(subaccounts);
}
{
QDomElement account = doc.createElement(QStringLiteral("ACCOUNT"));
accounts.appendChild(account);
account.setAttribute(QStringLiteral("id"), QStringLiteral("AStd::Asset"));
account.setAttribute(QStringLiteral("name"), QStringLiteral("Asset"));
account.setAttribute(QStringLiteral("number"), QString());
account.setAttribute(QStringLiteral("type"), QStringLiteral("9"));
account.setAttribute(QStringLiteral("institution"), QString());
account.setAttribute(QStringLiteral("parentaccount"), QString());
account.setAttribute(QStringLiteral("lastmodified"), QString());
account.setAttribute(QStringLiteral("lastreconciled"), QString());
account.setAttribute(QStringLiteral("opened"), QString());
account.setAttribute(QStringLiteral("currency"), stdUnit);
account.setAttribute(QStringLiteral("description"), QString());
QDomElement subaccounts = doc.createElement(QStringLiteral("SUBACCOUNTS"));
account.appendChild(subaccounts);
accountAsset = subaccounts;
}
{
QDomElement account = doc.createElement(QStringLiteral("ACCOUNT"));
accounts.appendChild(account);
account.setAttribute(QStringLiteral("id"), QStringLiteral("AStd::Liability"));
account.setAttribute(QStringLiteral("name"), QStringLiteral("Liability"));
account.setAttribute(QStringLiteral("number"), QString());
account.setAttribute(QStringLiteral("type"), QStringLiteral("10"));
account.setAttribute(QStringLiteral("institution"), QString());
account.setAttribute(QStringLiteral("parentaccount"), QString());
account.setAttribute(QStringLiteral("lastmodified"), QString());
account.setAttribute(QStringLiteral("lastreconciled"), QString());
account.setAttribute(QStringLiteral("opened"), QString());
account.setAttribute(QStringLiteral("currency"), stdUnit);
account.setAttribute(QStringLiteral("description"), QString());
QDomElement subaccounts = doc.createElement(QStringLiteral("SUBACCOUNTS"));
account.appendChild(subaccounts);
}
{
QDomElement account = doc.createElement(QStringLiteral("ACCOUNT"));
accounts.appendChild(account);
account.setAttribute(QStringLiteral("id"), QStringLiteral("AStd::Income"));
account.setAttribute(QStringLiteral("name"), QStringLiteral("Income"));
account.setAttribute(QStringLiteral("number"), QString());
account.setAttribute(QStringLiteral("type"), QStringLiteral("12"));
account.setAttribute(QStringLiteral("institution"), QString());
account.setAttribute(QStringLiteral("parentaccount"), QString());
account.setAttribute(QStringLiteral("lastmodified"), QString());
account.setAttribute(QStringLiteral("lastreconciled"), QString());
account.setAttribute(QStringLiteral("opened"), QString());
account.setAttribute(QStringLiteral("currency"), stdUnit);
account.setAttribute(QStringLiteral("description"), QString());
QDomElement subaccounts = doc.createElement(QStringLiteral("SUBACCOUNTS"));
account.appendChild(subaccounts);
accountIncome = subaccounts;
}
{
QDomElement account = doc.createElement(QStringLiteral("ACCOUNT"));
accounts.appendChild(account);
account.setAttribute(QStringLiteral("id"), QStringLiteral("AStd::Expense"));
account.setAttribute(QStringLiteral("name"), QStringLiteral("Expense"));
account.setAttribute(QStringLiteral("number"), QString());
account.setAttribute(QStringLiteral("type"), QStringLiteral("13"));
account.setAttribute(QStringLiteral("institution"), QString());
account.setAttribute(QStringLiteral("parentaccount"), QString());
account.setAttribute(QStringLiteral("lastmodified"), QString());
account.setAttribute(QStringLiteral("lastreconciled"), QString());
account.setAttribute(QStringLiteral("opened"), QString());
account.setAttribute(QStringLiteral("currency"), stdUnit);
account.setAttribute(QStringLiteral("description"), QString());
QDomElement subaccounts = doc.createElement(QStringLiteral("SUBACCOUNTS"));
account.appendChild(subaccounts);
accountExpense = subaccounts;
}
SKGObjectBase::SKGListSKGObjectBase objects;
IFOKDO(err, m_importer->getDocument()->getObjects(QStringLiteral("v_account"), QString(), objects))
int nb = objects.count();
IFOK(err) {
err = m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Export step", "Export accounts"), nb);
for (int i = 0; !err && i < nb; ++i) {
SKGAccountObject obj(objects.at(i));
QDomElement account = doc.createElement(QStringLiteral("ACCOUNT"));
accounts.appendChild(account);
account.setAttribute(QStringLiteral("id"), getKmyUniqueIdentifier(obj));
account.setAttribute(QStringLiteral("name"), obj.getName());
account.setAttribute(QStringLiteral("number"), obj.getNumber());
account.setAttribute(QStringLiteral("type"), obj.getType() == SKGAccountObject::CREDITCARD ? QStringLiteral("4") :
(obj.getType() == SKGAccountObject::INVESTMENT ? QStringLiteral("7") :
(obj.getType() == SKGAccountObject::ASSETS ? QStringLiteral("9") :
(obj.getType() == SKGAccountObject::WALLET ? QStringLiteral("3") :
(obj.getType() == SKGAccountObject::LOAN ? QStringLiteral("10") :
QStringLiteral("1"))))));
SKGBankObject bank;
err = obj.getBank(bank);
account.setAttribute(QStringLiteral("institution"), getKmyUniqueIdentifier(bank));
account.setAttribute(QStringLiteral("parentaccount"), QStringLiteral("AStd::Asset"));
account.setAttribute(QStringLiteral("lastmodified"), QString());
account.setAttribute(QStringLiteral("lastreconciled"), QString());
account.setAttribute(QStringLiteral("opened"), QString());
SKGUnitObject unit;
obj.getUnit(unit);
QString unitS = SKGUnitObject::getInternationalCode(unit.getName());
if (unitS.isEmpty()) {
unitS = QStringLiteral("EUR");
}
account.setAttribute(QStringLiteral("currency"), unitS);
account.setAttribute(QStringLiteral("description"), QString());
// Bookmarked account
QDomElement keyvaluepairs = doc.createElement(QStringLiteral("KEYVALUEPAIRS"));
account.appendChild(keyvaluepairs);
if (obj.isBookmarked()) {
QDomElement pair = doc.createElement(QStringLiteral("PAIR"));
keyvaluepairs.appendChild(pair);
pair.setAttribute(QStringLiteral("key"), QStringLiteral("PreferredAccount"));
pair.setAttribute(QStringLiteral("value"), QStringLiteral("Yes"));
}
// Closed account
if (obj.isClosed()) {
QDomElement pair = doc.createElement(QStringLiteral("PAIR"));
keyvaluepairs.appendChild(pair);
pair.setAttribute(QStringLiteral("key"), QStringLiteral("mm-closed"));
pair.setAttribute(QStringLiteral("value"), QStringLiteral("yes"));
}
// Maximum and minimum limits
if (obj.isMaxLimitAmountEnabled()) {
QDomElement pair = doc.createElement(QStringLiteral("PAIR"));
keyvaluepairs.appendChild(pair);
pair.setAttribute(QStringLiteral("key"), QStringLiteral("maxCreditAbsolute"));
pair.setAttribute(QStringLiteral("value"), kmyValue(-obj.getMaxLimitAmount()));
}
if (obj.isMinLimitAmountEnabled()) {
QDomElement pair = doc.createElement(QStringLiteral("PAIR"));
keyvaluepairs.appendChild(pair);
pair.setAttribute(QStringLiteral("key"), QStringLiteral("minBalanceAbsolute"));
pair.setAttribute(QStringLiteral("value"), kmyValue(obj.getMinLimitAmount()));
}
// Add it in asset
QDomElement subaccount = doc.createElement(QStringLiteral("SUBACCOUNT"));
accountAsset.appendChild(subaccount);
subaccount.setAttribute(QStringLiteral("id"), getKmyUniqueIdentifier(obj));
IFOKDO(err, m_importer->getDocument()->stepForward(i + 1))
}
SKGENDTRANSACTION(m_importer->getDocument(), err)
}
nbAccounts = nb;
return err;
}
SKGError SKGImportPluginKmy::exportFile()
{
// Initialisation
m_opTreated.clear();
if (m_importer == nullptr) {
return SKGError(ERR_ABORT, i18nc("Error message", "Invalid parameters"));
}
SKGError err;
SKGTRACEINFUNCRC(2, err)
// Open file
KCompressionDevice file(m_importer->getLocalFileName(false), KCompressionDevice::GZip);
if (!file.open(QIODevice::WriteOnly)) {
err.setReturnCode(ERR_INVALIDARG).setMessage(i18nc("Error message", "Save file '%1' failed", m_importer->getFileName().toDisplayString()));
} else {
QDomDocument doc(QStringLiteral("KMYMONEY-FILE"));
QDomComment comment = doc.createComment(QStringLiteral("Generated by libskgbankmodeler"));
doc.appendChild(comment);
QDomElement root = doc.createElement(QStringLiteral("KMYMONEY-FILE"));
doc.appendChild(root);
{
err = m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Export step", "Export %1 file", "KMY"), 8);
IFOK(err) {
// Step 1-<FILEINFO>
IFOKDO(err, exportHeader(doc, root))
IFOKDO(err, m_importer->getDocument()->stepForward(1))
// // Step 2-<INSTITUTIONS>
IFOKDO(err, exportInstitutions(doc, root))
IFOKDO(err, m_importer->getDocument()->stepForward(2))
// Step 3-<PAYEES>
IFOKDO(err, exportPayees(doc, root))
IFOKDO(err, m_importer->getDocument()->stepForward(3))
// Step 4-<ACCOUNTS>
// Std accounts
QString stdUnit = SKGUnitObject::getInternationalCode(m_importer->getDocument()->getPrimaryUnit().Name);
if (stdUnit.isEmpty()) {
stdUnit = QStringLiteral("EUR");
}
QDomElement accountIncome;
QDomElement accountExpense;
QDomElement accounts;
int nbAccounts = 0;
IFOKDO(err, exportAccounts(doc, root, stdUnit, accounts, accountIncome, accountExpense, nbAccounts))
IFOKDO(err, m_importer->getDocument()->stepForward(4))
// Step 5
IFOKDO(err, exportCategories(doc, accounts, stdUnit, accountIncome, accountExpense, nbAccounts))
IFOKDO(err, m_importer->getDocument()->stepForward(5))
// Step 6-<TRANSACTIONS>
IFOKDO(err, exportTransactions(doc, root, stdUnit))
// Step 6-<SCHEDULES>
IFOKDO(err, exportSchedules(doc, root))
IFOKDO(err, m_importer->getDocument()->stepForward(6))
// Step 7-<BUDGETS>
IFOKDO(err, exportBudgets(doc, root))
IFOKDO(err, m_importer->getDocument()->stepForward(7))
// Step 8-<SECURITIES> and <CURRENCIES>
IFOKDO(err, exportSecurities(doc, root, stdUnit))
// Save file
IFOK(err) {
file.write(doc.toString().toUtf8());
}
IFOKDO(err, m_importer->getDocument()->stepForward(8))
}
SKGENDTRANSACTION(m_importer->getDocument(), err)
}
file.close();
}
// Clean
m_opTreated.clear();
return err;
}
SKGError SKGImportPluginKmy::exportOperation(const SKGOperationObject& iOperation, QDomDocument& iDoc, QDomElement& iTransaction)
{
SKGError err;
SKGTRACEINFUNCRC(2, err)
if (!m_opTreated.contains(getKmyUniqueIdentifier(iOperation))) {
QDomElement transaction = iDoc.createElement(QStringLiteral("TRANSACTION"));
iTransaction.appendChild(transaction);
SKGUnitObject unit;
iOperation.getUnit(unit);
QString date = iOperation.getAttribute(QStringLiteral("d_date"));
transaction.setAttribute(QStringLiteral("id"), getKmyUniqueIdentifier(iOperation));
transaction.setAttribute(QStringLiteral("entrydate"), date);
transaction.setAttribute(QStringLiteral("postdate"), date);
transaction.setAttribute(QStringLiteral("memo"), iOperation.getComment());
transaction.setAttribute(QStringLiteral("commodity"), SKGUnitObject::getInternationalCode(unit.getName()));
QString reconcileflag = (iOperation.getStatus() == SKGOperationObject::POINTED ? QStringLiteral("1") : (iOperation.getStatus() == SKGOperationObject::CHECKED ? QStringLiteral("2") : QStringLiteral("0")));
SKGAccountObject act;
IFOKDO(err, iOperation.getParentAccount(act))
QDomElement splits = iDoc.createElement(QStringLiteral("SPLITS"));
transaction.appendChild(splits);
QDomElement split = iDoc.createElement(QStringLiteral("SPLIT"));
splits.appendChild(split);
SKGPayeeObject payeeObject;
iOperation.getPayee(payeeObject);
QString payeeId = (payeeObject.getID() != 0 ? getKmyUniqueIdentifier(payeeObject) : QString());
int indexSubOp = 1;
// Split for account
split.setAttribute(QStringLiteral("payee"), payeeId);
split.setAttribute(QStringLiteral("reconciledate"), QString());
split.setAttribute(QStringLiteral("id"), "S" % SKGServices::intToString(indexSubOp++).rightJustified(4, '0'));
double val2 = SKGServices::stringToDouble(iOperation.getAttribute(QStringLiteral("f_QUANTITY")));
split.setAttribute(QStringLiteral("shares"), SKGImportPluginKmy::kmyValue(val2));
split.setAttribute(QStringLiteral("action"), QString());
split.setAttribute(QStringLiteral("bankid"), QString());
split.setAttribute(QStringLiteral("number"), iOperation.getNumber());
split.setAttribute(QStringLiteral("reconcileflag"), reconcileflag);
split.setAttribute(QStringLiteral("memo"), iOperation.getComment());
QString originalAmount = iOperation.getProperty(QStringLiteral("SKG_OP_ORIGINAL_AMOUNT"));
if (!originalAmount.isEmpty()) {
val2 = qAbs(SKGServices::stringToDouble(originalAmount)) * (val2 / qAbs(val2));
}
split.setAttribute(QStringLiteral("value"), SKGImportPluginKmy::kmyValue(val2));
split.setAttribute(QStringLiteral("account"), getKmyUniqueIdentifier(act));
SKGOperationObject obj2;
if (!err && iOperation.isTransfer(obj2)) {
// It is a Transfer
QString reconcileflag2 = (obj2.getStatus() == SKGOperationObject::POINTED ? QStringLiteral("1") : (obj2.getStatus() == SKGOperationObject::CHECKED ? QStringLiteral("2") : QStringLiteral("0")));
SKGAccountObject act2;
IFOKDO(err, obj2.getParentAccount(act2))
QDomElement split2 = iDoc.createElement(QStringLiteral("SPLIT"));
splits.appendChild(split2);
// Split for account
val2 = -val2;
split2.setAttribute(QStringLiteral("payee"), payeeId);
split2.setAttribute(QStringLiteral("reconciledate"), QString());
split2.setAttribute(QStringLiteral("id"), "S" % SKGServices::intToString(indexSubOp++).rightJustified(4, '0'));
split2.setAttribute(QStringLiteral("shares"), SKGImportPluginKmy::kmyValue(SKGServices::stringToDouble(obj2.getAttribute(QStringLiteral("f_QUANTITY")))));
split2.setAttribute(QStringLiteral("action"), QString());
split2.setAttribute(QStringLiteral("bankid"), QString());
split2.setAttribute(QStringLiteral("number"), obj2.getNumber());
split2.setAttribute(QStringLiteral("reconcileflag"), reconcileflag2);
split2.setAttribute(QStringLiteral("memo"), obj2.getComment());
split2.setAttribute(QStringLiteral("value"), SKGImportPluginKmy::kmyValue(val2));
split2.setAttribute(QStringLiteral("account"), getKmyUniqueIdentifier(act2));
m_opTreated.insert(getKmyUniqueIdentifier(obj2));
} else {
SKGObjectBase::SKGListSKGObjectBase subops;
IFOKDO(err, iOperation.getSubOperations(subops))
int nb2 = subops.count();
for (int j = 0; !err && j < nb2; ++j) {
QDomElement split2 = iDoc.createElement(QStringLiteral("SPLIT"));
splits.appendChild(split2);
SKGSubOperationObject subop(subops.at(j));
SKGCategoryObject cat;
subop.getCategory(cat);
split2.setAttribute(QStringLiteral("payee"), payeeId);
split2.setAttribute(QStringLiteral("reconciledate"), QString());
split2.setAttribute(QStringLiteral("id"), "S" % SKGServices::intToString(indexSubOp++).rightJustified(4, '0'));
QString shape3 = SKGImportPluginKmy::kmyValue(-subop.getQuantity());
split2.setAttribute(QStringLiteral("shares"), shape3);
split2.setAttribute(QStringLiteral("action"), QString());
split2.setAttribute(QStringLiteral("bankid"), QString());
split2.setAttribute(QStringLiteral("number"), iOperation.getNumber());
split2.setAttribute(QStringLiteral("reconcileflag"), reconcileflag);
split2.setAttribute(QStringLiteral("memo"), subop.getComment());
split2.setAttribute(QStringLiteral("value"), shape3);
split2.setAttribute(QStringLiteral("account"), date == QStringLiteral("0000-00-00") ? QStringLiteral("AStd::Equity") : (cat.getID() != 0 ? getKmyUniqueIdentifier(cat) : QString()));
}
}
m_opTreated.insert(getKmyUniqueIdentifier(iOperation));
}
return err;
}
QString SKGImportPluginKmy::kmyValue(double iValue)
{
QString output;
for (int i = 0; output.isEmpty() && i < 11; ++i) {
QString d = SKGServices::doubleToString(pow(10, i) * iValue);
if (d.indexOf('.') == -1) {
output = d % '/' % SKGServices::intToString(qPow(10, i));
}
}
return output;
}
double SKGImportPluginKmy::toKmyValue(const QString& iString)
{
double output = 0;
QStringList vals = SKGServices::splitCSVLine(iString, '/');
if (vals.count() == 1) {
output = SKGServices::stringToDouble(vals.at(0));
} else if (vals.count() == 2) {
output = SKGServices::stringToDouble(vals.at(0)) / SKGServices::stringToDouble(vals.at(1));
}
return output;
}
QString SKGImportPluginKmy::getKmyUniqueIdentifier(const SKGObjectBase& iObject)
{
QString id;
if (iObject.getID() != 0) {
QString table = iObject.getRealTable();
if (table == QStringLiteral("operation") || table == QStringLiteral("suboperation")) {
// T000000000000003623
id = 'T' % SKGServices::intToString(iObject.getID()).rightJustified(18, '0');
} else if (table == QStringLiteral("payee")) {
// P000030
id = 'P' % SKGServices::intToString(iObject.getID()).rightJustified(6, '0');
} else {
id = iObject.getUniqueID();
}
}
return id;
}
QString SKGImportPluginKmy::getMimeTypeFilter() const
{
return "*.kmy|" % i18nc("A file format", "KMyMoney document");
}
#include <skgimportpluginkmy.moc>
diff --git a/plugins/import/skrooge_import_kmy/skgimportpluginkmy.h b/plugins/import/skrooge_import_kmy/skgimportpluginkmy.h
index 79115a5f8..9befc7a7b 100644
--- a/plugins/import/skrooge_import_kmy/skgimportpluginkmy.h
+++ b/plugins/import/skrooge_import_kmy/skgimportpluginkmy.h
@@ -1,125 +1,125 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGIMPORTPLUGINKMY_H
#define SKGIMPORTPLUGINKMY_H
/** @file
* This file is Skrooge plugin for KMY import / export.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include <qset.h>
#include "skgbankobject.h"
#include "skgimportplugin.h"
class SKGUnitObject;
class SKGAccountObject;
class SKGCategoryObject;
class SKGOperationObject;
class SKGPayeeObject;
class SKGObjectBase;
class QDomDocument;
class QDomElement;
/**
* This file is Skrooge plugin for KMY import / export.
*/
class SKGImportPluginKmy : public SKGImportPlugin
{
Q_OBJECT
Q_INTERFACES(SKGImportPlugin)
public:
/**
* Default constructor
* @param iImporter the parent importer
* @param iArg the arguments
*/
explicit SKGImportPluginKmy(QObject* iImporter, const QVariantList& iArg);
/**
* Default Destructor
*/
~SKGImportPluginKmy() override;
/**
* To know if import is possible with this plugin
*/
bool isImportPossible() override;
/**
* Import a file
* @return an object managing the error.
* @see SKGError
*/
SKGError importFile() override;
/**
* To know if export is possible with this plugin
* @return true or false
*/
bool isExportPossible() override;
/**
* Export a file
* @return an object managing the error.
* @see SKGError
*/
SKGError exportFile() override;
/**
* Return the mime type filter
* @return the mime type filter. Example: "*.csv|CSV file"
*/
QString getMimeTypeFilter() const override;
private:
Q_DISABLE_COPY(SKGImportPluginKmy)
SKGError importSecurities(QDomElement& docElem);
SKGError importPrices(QDomElement& docElem);
SKGError importInstitutions(QMap<QString, SKGBankObject>& mapIdBank, QDomElement& docElem);
SKGError importPayees(QMap<QString, SKGPayeeObject>& mapIdPayee, QDomElement& docElem);
SKGError importTransactions(QDomElement& docElem, SKGAccountObject& kmymoneyTemporaryAccount, QMap<QString, SKGPayeeObject>& mapIdPayee);
SKGError importBudget(QDomElement& docElem);
SKGError importAccounts(SKGBankObject& bank, SKGAccountObject& kmymoneyTemporaryAccount, QMap<QString, SKGBankObject>& mapIdBank, QDomElement& docElem);
SKGError exportHeader(QDomDocument& doc, QDomElement& root);
SKGError exportSecurities(QDomDocument& doc, QDomElement& root, const QString& stdUnit);
SKGError exportBudgets(QDomDocument& doc, QDomElement& root);
SKGError exportTransactions(QDomDocument& doc, QDomElement& root, const QString& stdUnit);
SKGError exportPayees(QDomDocument& doc, QDomElement& root);
SKGError exportSchedules(QDomDocument& doc, QDomElement& root);
SKGError exportInstitutions(QDomDocument& doc, QDomElement& root);
SKGError exportCategories(QDomDocument& doc, QDomElement& accounts, const QString& stdUnit, QDomElement& accountIncome, QDomElement& accountExpense, int nbAccount);
SKGError exportAccounts(QDomDocument& doc, QDomElement& root, const QString& stdUnit, QDomElement& accounts, QDomElement& accountIncome, QDomElement& accountExpense, int& nbAccounts);
static SKGError exportOperation(const SKGOperationObject& iOperation, QDomDocument& iDoc, QDomElement& iTransaction);
static QString kmyValue(double iValue);
static double toKmyValue(const QString& iString);
static QString getKmyUniqueIdentifier(const SKGObjectBase& iObject);
static QSet<QString> m_opTreated;
static QMap<QString, SKGUnitObject> m_mapIdUnit;
static QMap<QString, SKGAccountObject> m_mapIdAccount;
static QMap<QString, SKGCategoryObject> m_mapIdCategory;
static QMap<QString, SKGPayeeObject> m_mapIdPayee;
};
#endif // SKGIMPORTPLUGINKMY_H
diff --git a/plugins/import/skrooge_import_ledger/CMakeLists.txt b/plugins/import/skrooge_import_ledger/CMakeLists.txt
index 744e76840..130aaadd0 100644
--- a/plugins/import/skrooge_import_ledger/CMakeLists.txt
+++ b/plugins/import/skrooge_import_ledger/CMakeLists.txt
@@ -1,35 +1,35 @@
#***************************************************************************
#* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
#* *
#* 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 <http://www.gnu.org/licenses/> *
+#* along with this program. If not, see <https://www.gnu.org/licenses/> *
#***************************************************************************
MESSAGE( STATUS "..:: CMAKE PLUGIN_IMPORT_LEDGER ::..")
PROJECT(plugin_import_ledger)
LINK_DIRECTORIES (${LIBRARY_OUTPUT_PATH})
SET(skrooge_import_ledger_SRCS
skgimportpluginledger.cpp
)
ADD_LIBRARY(skrooge_import_ledger MODULE ${skrooge_import_ledger_SRCS})
TARGET_LINK_LIBRARIES(skrooge_import_ledger KF5::Parts skgbasemodeler skgbasegui skgbankmodeler skgbankgui)
IF(Qt5_VERSION VERSION_LESS 5.7.0)
TARGET_LINK_LIBRARIES(skrooge_import_ledger KF5::KDELibs4Support)
ENDIF()
########### install files ###############
INSTALL(TARGETS skrooge_import_ledger DESTINATION ${KDE_INSTALL_QTPLUGINDIR})
INSTALL(FILES ${PROJECT_SOURCE_DIR}/org.kde.skrooge-import-ledger.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR})
diff --git a/plugins/import/skrooge_import_ledger/org.kde.skrooge-import-ledger.desktop b/plugins/import/skrooge_import_ledger/org.kde.skrooge-import-ledger.desktop
index 46cc28016..3f5d57c5f 100644
--- a/plugins/import/skrooge_import_ledger/org.kde.skrooge-import-ledger.desktop
+++ b/plugins/import/skrooge_import_ledger/org.kde.skrooge-import-ledger.desktop
@@ -1,46 +1,46 @@
[Desktop Entry]
Name=Skrooge import ledger plugin
Name[ca]=Connector d'importació de llibre major de l'Skrooge
Name[ca@valencia]=Connector d'importació de llibre major de l'Skrooge
Name[de]=Skrooge-Import-Kontenbuchmodul
Name[en_GB]=Skrooge import ledger plugin
Name[es]=Complemento de importación de libros de contabilidad de Skrooge
-Name[fr]=Module externe de Skrooge pour l'importation depuis « Ledger »
+Name[fr]=Module externe de Skrooge pour l'importation depuis « Ledger »
Name[gl]=Complemento de importación de libros de compatibilidade a Skrooge
Name[it]=Estensione di Skrooge per l'importazione dei mastri
Name[nl]=Plug-in voor importeren van kasboek van Skrooge
Name[pl]=Wtyczka silnika importu księgi rachunkowej
Name[pt]='Plugin' de importação de livros de registos do Skrooge
Name[sv]=Skrooge insticksprogram för huvudboksimport
Name[uk]=Додаток імпортування облікових книг Skrooge
Name[x-test]=xxSkrooge import ledger pluginxx
Comment=A Skrooge plugin to import ledger files
Comment[ca]=Un connector de l'Skrooge per importar fitxers de llibre major
Comment[ca@valencia]=Un connector de l'Skrooge per importar fitxers de llibre major
Comment[de]=Ein Skrooge-Modul zum Import von Kontenbuch-Dateien
Comment[en_GB]=A Skrooge plugin to import ledger files
Comment[es]=Complemento de Skrooge para importar archivos de libros de contabilidad
-Comment[fr]=Un module externe de Skrooge pour l'importation de fichiers de « Ledger »
+Comment[fr]=Un module externe de Skrooge pour l'importation de fichiers de « Ledger »
Comment[gl]=Un complemento de Skrooge para importar ficheiros de libro de contabilidade.
Comment[it]=Un'estensione di Skrooge per importare i file dei mastri
Comment[nl]=Een Skrooge-plugin voor het importeren van kasboekbestanden
Comment[pl]=Wtyczka Skrooge do importu plików ksiąg rachunkowych
Comment[pt]=Um 'plugin' do Skrooge para importar livros de registos
Comment[sv]=Ett insticksprogram till Skrooge för att importera huvudboksfiler
Comment[uk]=Додаток до Skrooge для імпортування даних з файлів облікових книг
Comment[x-test]=xxA Skrooge plugin to import ledger filesxx
Encoding=UTF-8
Icon=skrooge
Type=Service
X-KDE-ServiceTypes=SKG IMPORT/Plugin
X-KDE-Library=skrooge_import_ledger
X-Krunner-ID=Skrooge import ledger plugin
X-KDE-PluginInfo-Author=Stephane MANKOWSKI
X-KDE-PluginInfo-Email=stephane@mankowski.fr
X-KDE-PluginInfo-Name=skrooge_import_ledger
X-KDE-PluginInfo-Version=1.0
-X-KDE-PluginInfo-Website=http://skrooge.org/
+X-KDE-PluginInfo-Website=https://skrooge.org/
X-KDE-PluginInfo-Category=Plugins
X-KDE-PluginInfo-Depends=
X-KDE-PluginInfo-License=GPL
X-KDE-PluginInfo-EnabledByDefault=true
diff --git a/plugins/import/skrooge_import_ledger/skgimportpluginledger.cpp b/plugins/import/skrooge_import_ledger/skgimportpluginledger.cpp
index 77e75b200..44be59bdb 100644
--- a/plugins/import/skrooge_import_ledger/skgimportpluginledger.cpp
+++ b/plugins/import/skrooge_import_ledger/skgimportpluginledger.cpp
@@ -1,225 +1,225 @@
/***************************************************************************
* Copyright (C) 2017 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 impgnced 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is Skrooge plugin for ledger import / export.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgimportpluginledger.h"
#include <klocalizedstring.h>
#include <kpluginfactory.h>
#include <qsavefile.h>
#include "skgbankincludes.h"
#include "skgdocumentbank.h"
#include "skgservices.h"
#include "skgtraces.h"
/**
* This plugin factory.
*/
K_PLUGIN_FACTORY(SKGImportPluginLedgerFactory, registerPlugin<SKGImportPluginLedger>();)
SKGImportPluginLedger::SKGImportPluginLedger(QObject* iImporter, const QVariantList& iArg)
: SKGImportPlugin(iImporter)
{
SKGTRACEINFUNC(10)
Q_UNUSED(iArg)
}
SKGImportPluginLedger::~SKGImportPluginLedger()
= default;
bool SKGImportPluginLedger::isExportPossible()
{
SKGTRACEINFUNC(10)
return (m_importer == nullptr ? true : m_importer->getFileNameExtension() == QStringLiteral("LEDGER"));
}
SKGError SKGImportPluginLedger::exportFile()
{
SKGError err;
QSaveFile file(m_importer->getLocalFileName(false));
if (!file.open(QIODevice::WriteOnly)) {
err.setReturnCode(ERR_INVALIDARG).setMessage(i18nc("Error message", "Save file '%1' failed", m_importer->getFileName().toDisplayString()));
} else {
auto listUUIDs = SKGServices::splitCSVLine(m_exportParameters.value(QStringLiteral("uuid_of_selected_accounts_or_operations")));
QString wc;
for (const auto& uuid : listUUIDs) {
auto items = SKGServices::splitCSVLine(uuid, '-');
if (items.at(1) == QStringLiteral("operation")) {
if (!wc.isEmpty()) {
wc += QLatin1String(" AND ");
}
wc += " i_OPID=" + items.at(0);
} else if (items.at(1) == QStringLiteral("account")) {
if (!wc.isEmpty()) {
wc += QLatin1String(" AND ");
}
wc += " rd_account_id=" + items.at(0);
}
}
if (wc.isEmpty()) {
wc = QStringLiteral("1=1");
} else {
IFOKDO(err, m_importer->getDocument()->sendMessage(i18nc("An information message", "Only selected accounts and operations have been exported")))
}
QLocale en(QStringLiteral("en_EN"));
QTextStream stream(&file);
if (!m_importer->getCodec().isEmpty()) {
stream.setCodec(m_importer->getCodec().toLatin1().constData());
}
stream << "; -*- ledger file generated by Skrooge -*-" << endl;
err = m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Export step", "Export %1 file", "ledger"), 2);
IFOK(err) {
auto punit = m_importer->getDocument()->getPrimaryUnit();
SKGObjectBase::SKGListSKGObjectBase units;
err = m_importer->getDocument()->getObjects(QStringLiteral("v_unit"), QStringLiteral("t_type NOT IN ('C', '1', '2')"), units);
int nb = units.count();
IFOK(err) {
err = m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Export step", "Export units"), nb);
for (int i = 0; !err && i < nb; ++i) {
SKGUnitObject unit(units.at(i));
QString qs = en.toCurrencyString(SKGServices::stringToDouble(unit.getAttribute(QStringLiteral("f_CURRENTAMOUNT"))), punit.Symbol, punit.NbDecimal);
stream << "P " << SKGServices::dateToSqlString(QDate::currentDate()).replace('-', '/')
<< " \"" << unit.getSymbol() << '"'
<< " " << qs
<< endl;
stream << endl;
IFOKDO(err, m_importer->getDocument()->stepForward(i + 1))
}
SKGENDTRANSACTION(m_importer->getDocument(), err)
}
}
IFOKDO(err, m_importer->getDocument()->stepForward(1))
IFOK(err) {
SKGObjectBase::SKGListSKGObjectBase operations;
err = m_importer->getDocument()->getObjects(QStringLiteral("v_operation"), wc % QStringLiteral(" AND t_template='N' ORDER BY d_date"), operations);
int nb = operations.count();
IFOK(err) {
err = m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Export step", "Export operations"), nb);
for (int i = 0; !err && i < nb; ++i) {
SKGOperationObject op(operations.at(i));
auto status = op.getStatus();
auto number = op.getNumber();
SKGPayeeObject payee;
op.getPayee(payee);
SKGUnitObject unit;
op.getUnit(unit);
bool isCurrency = unit.getType() == SKGUnitObject::CURRENCY || unit.getType() == SKGUnitObject::PRIMARY || unit.getType() == SKGUnitObject::SECONDARY;
auto payeeString = payee.getName();
if (payeeString.isEmpty()) {
payeeString = op.getComment();
}
auto nbDec = SKGServices::stringToInt(op.getAttribute(QStringLiteral("i_NBDEC")));
if (nbDec == 0) {
nbDec = 2;
}
QString symbol = unit.getSymbol();
if (symbol.contains(QStringLiteral(" "))) {
symbol = '"' + symbol + '"';
}
QString qs = en.toCurrencyString(SKGServices::stringToDouble(op.getAttribute(QStringLiteral("f_QUANTITY"))), QStringLiteral(" "), nbDec);
if (isCurrency) {
qs = symbol + qs;
} else {
qs = qs + ' ' + symbol;
}
stream << SKGServices::dateToSqlString(op.getDate()).replace('-', '/')
<< (status == SKGOperationObject::CHECKED ? " *" : status == SKGOperationObject::POINTED ? " !" : "")
<< (!number.isEmpty() ? QStringLiteral(" (") % number % ")" : QString())
<< QStringLiteral(" ") << payeeString
<< endl;
stream << " ; Skrooge ID: " << op.getID() << endl;
stream << " ; Import ID: " << op.getImportID() << endl;
auto properties = op.getProperties();
for (const auto& p : qAsConst(properties)) {
stream << " ; " << p << ": " << op.getProperty(p) << endl;
}
stream << " " << i18nc("The default category for the accounts for ledger export", "Account") << ':' << op.getAttribute(QStringLiteral("t_ACCOUNT"))
<< " " << qs
<< endl;
SKGObjectBase::SKGListSKGObjectBase suboperations;
IFOKDO(err, op.getSubOperations(suboperations))
int nbsuboperations = suboperations.count();
for (int j = 0; !err && j < nbsuboperations; ++j) {
SKGSubOperationObject sop(suboperations.at(j));
SKGCategoryObject cat;
sop.getCategory(cat);
auto catString = cat.getFullName().replace(OBJECTSEPARATOR, QLatin1String(":"));
if (catString.isEmpty()) {
catString = i18nc("Category not defined", "Not defined");
}
QString qs = en.toCurrencyString(-sop.getQuantity(), QStringLiteral(" "), nbDec);
if (isCurrency) {
qs = unit.getSymbol() + qs;
} else {
qs = qs + ' ' + unit.getSymbol();
}
stream << " " << i18nc("The default category for the categories for ledger export", "Category") << ':' << catString
<< " " << qs;
if (sop.getDate() != op.getDate()) {
stream << " ; [=" << SKGServices::dateToSqlString(sop.getDate()).replace('-', '/') << "]";
}
auto comment = sop.getComment();
if (!comment.isEmpty()) {
stream << " ;comment=" << comment;
}
stream << " ; Skrooge ID: " << sop.getID();
stream << endl;
}
stream << endl;
IFOKDO(err, m_importer->getDocument()->stepForward(i + 1))
}
SKGENDTRANSACTION(m_importer->getDocument(), err)
}
}
IFOKDO(err, m_importer->getDocument()->stepForward(2))
SKGENDTRANSACTION(m_importer->getDocument(), err)
// Close file
file.commit();
}
return err;
}
QString SKGImportPluginLedger::getMimeTypeFilter() const
{
return "*.ledger|" % i18nc("A file format", "Ledger file");
}
#include <skgimportpluginledger.moc>
diff --git a/plugins/import/skrooge_import_ledger/skgimportpluginledger.h b/plugins/import/skrooge_import_ledger/skgimportpluginledger.h
index 82002f6ec..9f56f4486 100644
--- a/plugins/import/skrooge_import_ledger/skgimportpluginledger.h
+++ b/plugins/import/skrooge_import_ledger/skgimportpluginledger.h
@@ -1,71 +1,71 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGIMPORTPLUGINLEDGER_H
#define SKGIMPORTPLUGINLEDGER_H
/** @file
* This file is Skrooge plugin for ledger import / export.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgimportplugin.h"
/**
* This file is Skrooge plugin for ledger import / export.
*/
class SKGImportPluginLedger : public SKGImportPlugin
{
Q_OBJECT
Q_INTERFACES(SKGImportPlugin)
public:
/**
* Default constructor
* @param iImporter the parent importer
* @param iArg the arguments
*/
explicit SKGImportPluginLedger(QObject* iImporter, const QVariantList& iArg);
/**
* Default Destructor
*/
~SKGImportPluginLedger() override;
/**
* To know if export is possible with this plugin
* @return true or false
*/
bool isExportPossible() override;
/**
* Export a file
* @return an object managing the error.
* @see SKGError
*/
SKGError exportFile() override;
/**
* Return the mime type filter
* @return the mime type filter. Example: "*.csv|CSV file"
*/
QString getMimeTypeFilter() const override;
private:
Q_DISABLE_COPY(SKGImportPluginLedger)
};
#endif // SKGIMPORTPLUGINLEDGER_H
diff --git a/plugins/import/skrooge_import_mmb/CMakeLists.txt b/plugins/import/skrooge_import_mmb/CMakeLists.txt
index 6e13df4ff..a84ab22a4 100644
--- a/plugins/import/skrooge_import_mmb/CMakeLists.txt
+++ b/plugins/import/skrooge_import_mmb/CMakeLists.txt
@@ -1,33 +1,33 @@
#***************************************************************************
#* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
#* *
#* 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 <http://www.gnu.org/licenses/> *
+#* along with this program. If not, see <https://www.gnu.org/licenses/> *
#***************************************************************************
MESSAGE( STATUS "..:: CMAKE PLUGIN_IMPORT_MMB ::..")
PROJECT(plugin_import_mmb)
LINK_DIRECTORIES (${LIBRARY_OUTPUT_PATH})
SET(skrooge_import_mmb_SRCS
skgimportpluginmmb.cpp
)
ADD_LIBRARY(skrooge_import_mmb MODULE ${skrooge_import_mmb_SRCS})
TARGET_LINK_LIBRARIES(skrooge_import_mmb KF5::Parts Qt5::Sql skgbasemodeler skgbasegui skgbankmodeler skgbankgui)
########### install files ###############
INSTALL(TARGETS skrooge_import_mmb DESTINATION ${KDE_INSTALL_QTPLUGINDIR})
INSTALL(FILES ${PROJECT_SOURCE_DIR}/org.kde.skrooge-import-mmb.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR})
diff --git a/plugins/import/skrooge_import_mmb/org.kde.skrooge-import-mmb.desktop b/plugins/import/skrooge_import_mmb/org.kde.skrooge-import-mmb.desktop
index d5f7e0134..184fd3320 100644
--- a/plugins/import/skrooge_import_mmb/org.kde.skrooge-import-mmb.desktop
+++ b/plugins/import/skrooge_import_mmb/org.kde.skrooge-import-mmb.desktop
@@ -1,74 +1,74 @@
[Desktop Entry]
Name=Skrooge import MMB plugin
Name[bs]=Skrooge dodatak za MMB uvoz
Name[ca]=Connector d'importació de MMB de l'Skrooge
Name[ca@valencia]=Connector d'importació de MMB de l'Skrooge
Name[cs]=Modul Skrooge pro import MMB
Name[da]=Plugin til import af MMB til Skrooge
Name[de]=Skrooge-MMB-Importmodul
Name[el]=Skrooge import MMB plugin
Name[en_GB]=Skrooge import MMB plugin
Name[es]=Complemento de Skrooge de importación de MMB
Name[et]=Skrooge MMB impordi plugin
Name[fi]=Skroogen MMB-tuontiliitännäinen
-Name[fr]=Module externe de Skrooge pour l'importation « MMB »
+Name[fr]=Module externe de Skrooge pour l'importation « MMB »
Name[gl]=Complemento de importación de MMB a Skrooge
Name[hu]=Skrooge MMB importáló bővítmény
Name[it]=Estensione di Skrooge per l'importazione MMB
Name[lt]=Skrooge MMB importavimo papildinys
Name[nb]=Skrooge-modul for MMB-import
Name[nl]=Plugin van Skrooge voor importeren van MMB
Name[pl]=Wtyczka importu MMB dla Skrooge
Name[pt]='Plugin' de importação de MMB para o Skrooge
Name[pt_BR]=Plugin de importação de MMB para o Skrooge
Name[ru]=Модуль импорта файлов MMB
Name[sk]=Skrooge plugin MMB import
Name[sv]=Skrooge MMB-importinsticksprogram
Name[tr]=Skrooge MMB içe aktarma eklentisi
Name[uk]=Додаток імпортування MMB до Skrooge
Name[x-test]=xxSkrooge import MMB pluginxx
Name[zh_TW]=Skrooge 匯入 MMB 外掛程式
Comment=A Skrooge plugin to import MMB files
Comment[bs]=Skrooge dodatak za uvoz MMB datoteka
Comment[ca]=Un connector de l'Skrooge per importar fitxers MMB
Comment[ca@valencia]=Un connector de l'Skrooge per importar fitxers MMB
Comment[cs]=Modul Skrooge pro import souborů MMB
Comment[da]=Et Skrooge-plugin til at importere MMB-filer
Comment[de]=Ein Skrooge-Modul zum Import von MMB-Dateien
Comment[el]=Ένα πρόσθετο του Skrooge για την εισαγωγή αρχείων MMB
Comment[en_GB]=A Skrooge plugin to import MMB files
Comment[es]=Complemento de Skrooge para importar archivos MMB
Comment[et]=Skrooge plugin MMB-failide importimiseks
Comment[fi]=Skroogen MMB-tiedostojen tuontiliitännäinen
-Comment[fr]=Un module externe de Skrooge pour l'importation de fichiers « MMB »
+Comment[fr]=Un module externe de Skrooge pour l'importation de fichiers « MMB »
Comment[gl]=Un complemento de Skrooge para importar ficheiros MMB.
Comment[hu]=Egy Skrooge bővítmény MMB fájlok importálásához
Comment[it]=Un'estensione di Skrooge per importare i file MMB
Comment[lt]=Skrooge MMB failų importavimo papildinys
Comment[nb]=En Skrooge-modul for å importere MMB-filer
Comment[nl]=Een Skrooge-plugin voor het importeren van MMB-bestanden
Comment[pl]=Wtyczka Skrooge do importu plików MMB
Comment[pt]=Um 'plugin' do Skrooge para importar ficheiros MMB
Comment[pt_BR]=Um plugin do Skrooge para importar arquivos MMB
Comment[ru]=Модуль импорта файлов MMB
Comment[sk]=Skrooge plugin na import MMB súborov
Comment[sv]=Ett insticksprogram till Skrooge för att importera MMB-filer
Comment[tr]=MMB dosyalarını içe aktarmak için Skrooge eklentisi
Comment[uk]=Додаток до Skrooge для імпортування даних з файлів MMB
Comment[x-test]=xxA Skrooge plugin to import MMB filesxx
Comment[zh_TW]=Skrooge 匯入 MMB 檔用的外掛程式
Encoding=UTF-8
Icon=skrooge
Type=Service
X-KDE-ServiceTypes=SKG IMPORT/Plugin
X-KDE-Library=skrooge_import_mmb
X-Krunner-ID=Skrooge import MMB plugin
X-KDE-PluginInfo-Author=Stephane MANKOWSKI
X-KDE-PluginInfo-Email=stephane@mankowski.fr
X-KDE-PluginInfo-Name=skrooge_import_mmb
X-KDE-PluginInfo-Version=1.0
-X-KDE-PluginInfo-Website=http://skrooge.org/
+X-KDE-PluginInfo-Website=https://skrooge.org/
X-KDE-PluginInfo-Category=Plugins
X-KDE-PluginInfo-Depends=
X-KDE-PluginInfo-License=GPL
X-KDE-PluginInfo-EnabledByDefault=true
diff --git a/plugins/import/skrooge_import_mmb/skgimportpluginmmb.cpp b/plugins/import/skrooge_import_mmb/skgimportpluginmmb.cpp
index a16d88b53..074104029 100644
--- a/plugins/import/skrooge_import_mmb/skgimportpluginmmb.cpp
+++ b/plugins/import/skrooge_import_mmb/skgimportpluginmmb.cpp
@@ -1,652 +1,652 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is Skrooge plugin for MMB import / export.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgimportpluginmmb.h"
#include <qfile.h>
#include <qsqldatabase.h>
#include <qsqlerror.h>
#include <klocalizedstring.h>
#include <kpluginfactory.h>
#include "skgbankincludes.h"
#include "skgimportexportmanager.h"
#include "skgobjectbase.h"
#include "skgservices.h"
#include "skgtraces.h"
/**
* This plugin factory.
*/
K_PLUGIN_FACTORY(SKGImportPluginMmbFactory, registerPlugin<SKGImportPluginMmb>();)
SKGImportPluginMmb::SKGImportPluginMmb(QObject* iImporter, const QVariantList& iArg)
: SKGImportPlugin(iImporter)
{
SKGTRACEINFUNC(10)
Q_UNUSED(iArg)
}
SKGImportPluginMmb::~SKGImportPluginMmb()
= default;
bool SKGImportPluginMmb::isImportPossible()
{
SKGTRACEINFUNC(10)
return (m_importer == nullptr ? true : m_importer->getFileNameExtension() == QStringLiteral("MMB"));
}
SKGError SKGImportPluginMmb::importFile()
{
if (m_importer == nullptr) {
return SKGError(ERR_ABORT, i18nc("Error message", "Invalid parameters"));
}
SKGError err;
SKGTRACEINFUNCRC(2, err)
{
QSqlDatabase originalDocument(QSqlDatabase::addDatabase(QStringLiteral("SKGSQLCIPHER"), QStringLiteral("originalDocument")));
originalDocument.setDatabaseName(m_importer->getLocalFileName());
if (!originalDocument.open()) {
// Set error message
QSqlError sqlErr = originalDocument.lastError();
err = SKGError(SQLLITEERROR + sqlErr.nativeErrorCode().toInt(), sqlErr.text());
}
IFOK(err) {
QMap<QString, SKGUnitObject> mapUnit;
err = m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Import step", "Import %1 file", "MMB"), 9);
// Step 1 - units
IFOK(err) {
SKGStringListList listUnits;
err = SKGServices::executeSelectSqliteOrder(originalDocument, QStringLiteral("SELECT CURRENCYID, CURRENCYNAME, PFX_SYMBOL, SFX_SYMBOL, DECIMAL_POINT, GROUP_SEPARATOR, UNIT_NAME, CENT_NAME, SCALE, BASECONVRATE, CURRENCY_SYMBOL, "
"(CASE WHEN EXISTS (SELECT 1 FROM INFOTABLE_V1 WHERE INFONAME='BASECURRENCYID' AND INFOVALUE=CURRENCYID) THEN 'Y' ELSE 'N' END) AS PRIMARYUNIT FROM CURRENCYFORMATS_V1"), listUnits);
IFOK(err) {
int nb = listUnits.count() - 1;
err = m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Import step", "Import units"), nb);
for (int i = 0; !err && i < nb; ++i) {
const QStringList& attributes = listUnits.at(i + 1);
SKGUnitObject unit(m_importer->getDocument());
err = unit.setName(attributes.at(1));
IFOK(err) {
QString symbol = attributes.at(2);
if (symbol.isEmpty()) {
symbol = attributes.at(3);
}
err = unit.setSymbol(symbol);
}
if (!err && attributes.at(11) == QStringLiteral("Y")) {
err = unit.setType(SKGUnitObject::PRIMARY);
}
IFOKDO(err, unit.save())
mapUnit[attributes.at(0)] = unit;
IFOKDO(err, m_importer->getDocument()->stepForward(i + 1))
}
SKGENDTRANSACTION(m_importer->getDocument(), err)
}
}
IFOKDO(err, m_importer->getDocument()->stepForward(1))
// Step 2 - bank and accounts
QMap<QString, SKGAccountObject> mapAccount;
IFOK(err) {
SKGStringListList listAccounts;
err = SKGServices::executeSelectSqliteOrder(originalDocument, QStringLiteral("SELECT ACCOUNTID, ACCOUNTNAME, ACCOUNTTYPE, ACCOUNTNUM, STATUS, NOTES, HELDAT, WEBSITE, CONTACTINFO, ACCESSINFO, INITIALBAL, FAVORITEACCT, CURRENCYID FROM ACCOUNTLIST_V1"), listAccounts);
IFOK(err) {
int nb = listAccounts.count() - 1;
IFOKDO(err, m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Import step", "Import banks and accounts"), nb))
for (int i = 0; !err && i < nb; ++i) {
const QStringList& attributes = listAccounts.at(i + 1);
// Create bank
SKGBankObject bank(m_importer->getDocument());
IFOK(err) {
QString bankName = attributes.at(6);
if (bankName.isEmpty()) {
bankName = QStringLiteral("MMEX");
}
err = bank.setName(bankName);
}
IFOKDO(err, bank.save())
// Create account
SKGAccountObject account;
err = bank.addAccount(account);
IFOKDO(err, account.setName(attributes.at(1)))
IFOKDO(err, account.setType(attributes.at(2) == QStringLiteral("Checking") ? SKGAccountObject::CURRENT : SKGAccountObject::INVESTMENT))
IFOKDO(err, account.setNumber(attributes.at(3)))
IFOKDO(err, account.setComment(attributes.at(5)))
IFOKDO(err, account.setAgencyAddress(attributes.at(8)))
IFOKDO(err, account.bookmark(attributes.at(11) == QStringLiteral("TRUE")))
IFOKDO(err, account.setClosed(attributes.at(4) != QStringLiteral("Open")))
IFOKDO(err, account.save())
IFOKDO(err, account.setInitialBalance(SKGServices::stringToDouble(attributes.at(10)), mapUnit[attributes.at(12)]))
IFOKDO(err, account.save())
mapAccount[attributes.at(0)] = account;
IFOKDO(err, m_importer->getDocument()->stepForward(i + 1))
}
SKGENDTRANSACTION(m_importer->getDocument(), err)
}
}
IFOKDO(err, m_importer->getDocument()->stepForward(2))
// Step 3 - categories
QMap<QString, SKGCategoryObject> mapCategory;
IFOK(err) {
SKGStringListList listCategories;
err = SKGServices::executeSelectSqliteOrder(originalDocument, QStringLiteral("SELECT CATEGID, CATEGNAME FROM CATEGORY_V1"), listCategories);
IFOK(err) {
int nb = listCategories.count() - 1;
err = m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Import step", "Import categories"), nb);
for (int i = 0; !err && i < nb; ++i) {
const QStringList& attributes = listCategories.at(i + 1);
SKGCategoryObject cat(m_importer->getDocument());
err = cat.setName(attributes.at(1));
IFOKDO(err, cat.save())
mapCategory[attributes.at(0)] = cat;
IFOKDO(err, m_importer->getDocument()->stepForward(i + 1))
}
SKGENDTRANSACTION(m_importer->getDocument(), err)
}
}
IFOKDO(err, m_importer->getDocument()->stepForward(3))
// Step 4 - sub categories
QMap<QString, SKGCategoryObject> mapSubCategory;
IFOK(err) {
SKGStringListList listCategories;
err = SKGServices::executeSelectSqliteOrder(originalDocument, QStringLiteral("SELECT SUBCATEGID, SUBCATEGNAME, CATEGID FROM SUBCATEGORY_V1"), listCategories);
IFOK(err) {
int nb = listCategories.count() - 1;
err = m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Import step", "Import categories"), nb);
for (int i = 0; !err && i < nb; ++i) {
const QStringList& attributes = listCategories.at(i + 1);
SKGCategoryObject cat(m_importer->getDocument());
err = cat.setName(attributes.at(1));
IFOKDO(err, cat.setParentCategory(mapCategory[attributes.at(2)]))
IFOKDO(err, cat.save())
mapSubCategory[attributes.at(0)] = cat;
IFOKDO(err, m_importer->getDocument()->stepForward(i + 1))
}
SKGENDTRANSACTION(m_importer->getDocument(), err)
}
}
IFOKDO(err, m_importer->getDocument()->stepForward(4))
// Step 5 - payee
QMap<QString, SKGPayeeObject> mapPayee;
IFOK(err) {
SKGStringListList listPayee;
err = SKGServices::executeSelectSqliteOrder(originalDocument, QStringLiteral("SELECT PAYEEID, PAYEENAME FROM PAYEE_V1"), listPayee);
IFOK(err) {
int nb = listPayee.count() - 1;
err = m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Import step", "Import payees"), nb);
for (int i = 0; !err && i < nb; ++i) {
const QStringList& attributes = listPayee.at(i + 1);
SKGPayeeObject payee(m_importer->getDocument());
err = payee.setName(attributes.at(1));
IFOKDO(err, payee.save())
mapPayee[attributes.at(0)] = payee;
IFOKDO(err, m_importer->getDocument()->stepForward(i + 1))
}
SKGENDTRANSACTION(m_importer->getDocument(), err)
}
}
IFOKDO(err, m_importer->getDocument()->stepForward(5))
// Step 6 - operations
QMap<QString, SKGOperationObject> mapOperation;
IFOK(err) {
SKGStringListList listOperations;
err = SKGServices::executeSelectSqliteOrder(originalDocument, QStringLiteral("SELECT * FROM ("
"SELECT TRANSID, ACCOUNTID, TOACCOUNTID, PAYEEID, TRANSCODE, TRANSAMOUNT, STATUS, TRANSACTIONNUMBER, NOTES, CATEGID, SUBCATEGID, TRANSDATE, FOLLOWUPID, TOTRANSAMOUNT, 'N/A' , 'N/A', 'N/A' FROM CHECKINGACCOUNT_V1 UNION "
"SELECT BDID, ACCOUNTID, TOACCOUNTID, PAYEEID, TRANSCODE, TRANSAMOUNT, STATUS, TRANSACTIONNUMBER, NOTES, CATEGID, SUBCATEGID, TRANSDATE, FOLLOWUPID, TOTRANSAMOUNT, REPEATS, NEXTOCCURRENCEDATE, NUMOCCURRENCES FROM BILLSDEPOSITS_V1)"), listOperations);
IFOK(err) {
int nb = listOperations.count() - 1;
err = m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Import step", "Import operations"), nb);
for (int i = 0; !err && i < nb; ++i) {
const QStringList& attributes = listOperations.at(i + 1);
if (attributes.at(6) != QStringLiteral("V")) { // Void
bool recurrent = (attributes.at(14) != QStringLiteral("N/A"));
const QString& idTarget = attributes.at(2);
SKGAccountObject acc = mapAccount[attributes.at(1)];
SKGUnitObject unit;
IFOKDO(err, acc.getUnit(unit))
SKGOperationObject op;
IFOKDO(err, acc.addOperation(op, true))
IFOK(err) {
const QString& id = attributes.at(3);
if (id != QStringLiteral("-1")) {
err = op.setPayee(mapPayee[id]);
}
}
IFOKDO(err, op.setNumber(attributes.at(7)))
IFOKDO(err, op.setComment(attributes.at(8)))
IFOKDO(err, op.setDate(SKGServices::stringToTime(attributes.at(11)).date()))
IFOKDO(err, op.setAttribute(QStringLiteral("t_imported"), QStringLiteral("T")))
IFOKDO(err, op.setImportID("MMEX-" % attributes.at(0)))
IFOKDO(err, op.setUnit(unit))
IFOKDO(err, op.bookmark(attributes.at(6) == QStringLiteral("F")))
IFOKDO(err, op.setTemplate(recurrent))
IFOKDO(err, op.setStatus(attributes.at(6) == QStringLiteral("R") ? SKGOperationObject::CHECKED : SKGOperationObject::NONE))
IFOKDO(err, op.save())
// Get splits
IFOK(err) {
SKGStringListList listSubOperations;
err = SKGServices::executeSelectSqliteOrder(originalDocument, QStringLiteral("SELECT SPLITTRANSID, CATEGID, SUBCATEGID, SPLITTRANSAMOUNT FROM ") % (recurrent ? "BUDGET" : "") % "SPLITTRANSACTIONS_V1 WHERE TRANSID=" % attributes.at(0), listSubOperations);
IFOK(err) {
int nb2 = listSubOperations.count() - 1;
if (nb2 <= 0) {
// No split
SKGSubOperationObject subop;
IFOKDO(err, op.addSubOperation(subop))
IFOK(err) {
QString id = attributes.at(10);
if (id == QStringLiteral("-1")) {
id = attributes.at(9);
if (id != QStringLiteral("-1")) {
err = subop.setCategory(mapSubCategory[id]);
}
} else {
err = subop.setCategory(mapCategory[id]);
}
}
IFOK(err) {
double q = SKGServices::stringToDouble(attributes.at(5));
if (attributes.at(4) == QStringLiteral("Withdrawal") || idTarget != QStringLiteral("-1")) {
q = -q;
}
err = subop.setQuantity(q);
}
IFOKDO(err, subop.save())
} else {
// Has splits
for (int j = 0; !err && j < nb2; ++j) {
const QStringList& attributesSubOp = listSubOperations.at(j + 1);
SKGSubOperationObject subop;
IFOKDO(err, op.addSubOperation(subop))
IFOK(err) {
QString id = attributesSubOp.at(2);
if (id == QStringLiteral("-1")) {
id = attributesSubOp.at(1);
if (id != QStringLiteral("-1")) {
err = subop.setCategory(mapCategory[id]);
}
} else {
err = subop.setCategory(mapSubCategory[id]);
}
}
IFOK(err) {
double q = SKGServices::stringToDouble(attributesSubOp.at(3));
if (attributes.at(4) == QStringLiteral("Withdrawal") || idTarget != QStringLiteral("-1")) {
q = -q;
}
err = subop.setQuantity(q);
}
IFOKDO(err, subop.save())
}
}
}
}
// Case Transfer
if (!err && idTarget != QStringLiteral("-1")) {
SKGOperationObject op2;
err = op.duplicate(op2, op.getDate());
IFOKDO(err, op2.setStatus(op.getStatus()))
IFOKDO(err, op2.bookmark(op.isBookmarked()))
IFOKDO(err, op2.setAttribute(QStringLiteral("t_imported"), QStringLiteral("T")))
IFOKDO(err, op2.setImportID("MMEX-" % attributes.at(0) % "_TR"))
IFOKDO(err, op2.save())
SKGObjectBase::SKGListSKGObjectBase subops;
IFOKDO(err, op.getSubOperations(subops))
if (!err && !subops.isEmpty()) {
SKGSubOperationObject subop2(subops.at(0));
err = subop2.setQuantity(-subop2.getQuantity());
IFOKDO(err, subop2.save())
}
IFOKDO(err, op.setParentAccount(mapAccount[idTarget]))
IFOKDO(err, op.setGroupOperation(op2))
IFOKDO(err, op.save())
}
// Create recurrent transaction
if (recurrent) {
SKGRecurrentOperationObject recu;
IFOKDO(err, op.addRecurrentOperation(recu))
IFOKDO(err, recu.setDate(SKGServices::stringToTime(attributes.at(15)).date()))
int nbTimes = SKGServices::stringToInt(attributes.at(16));
if (!err && nbTimes != -1) {
err = recu.setTimeLimit(nbTimes);
IFOKDO(err, recu.timeLimit(true))
}
int repeats = SKGServices::stringToInt(attributes.at(14));
IFOK(err) {
switch (repeats) {
case 1:
// Weekly
err = recu.setPeriodUnit(SKGRecurrentOperationObject::WEEK);
IFOKDO(err, recu.setPeriodIncrement(1))
break;
case 2:
// Bi-Weekly
err = recu.setPeriodUnit(SKGRecurrentOperationObject::WEEK);
IFOKDO(err, recu.setPeriodIncrement(2))
break;
case 3:
// Monthly
err = recu.setPeriodUnit(SKGRecurrentOperationObject::MONTH);
IFOKDO(err, recu.setPeriodIncrement(1))
break;
case 4:
// Bi-Monthly
err = recu.setPeriodUnit(SKGRecurrentOperationObject::MONTH);
IFOKDO(err, recu.setPeriodIncrement(2))
break;
case 5:
// Quarterly
err = recu.setPeriodUnit(SKGRecurrentOperationObject::MONTH);
IFOKDO(err, recu.setPeriodIncrement(3))
break;
case 6:
// Half yearly
err = recu.setPeriodUnit(SKGRecurrentOperationObject::MONTH);
IFOKDO(err, recu.setPeriodIncrement(6))
break;
case 7:
// Yearly
err = recu.setPeriodUnit(SKGRecurrentOperationObject::YEAR);
IFOKDO(err, recu.setPeriodIncrement(1))
break;
case 8:
// Four months
err = recu.setPeriodUnit(SKGRecurrentOperationObject::MONTH);
IFOKDO(err, recu.setPeriodIncrement(4))
break;
case 9:
// Four weeks
err = recu.setPeriodUnit(SKGRecurrentOperationObject::WEEK);
IFOKDO(err, recu.setPeriodIncrement(4))
break;
case 10:
// Daily
err = recu.setPeriodUnit(SKGRecurrentOperationObject::DAY);
IFOKDO(err, recu.setPeriodIncrement(1))
break;
default:
break;
}
}
IFOKDO(err, recu.save(true, false))
}
mapOperation[attributes.at(0)] = op;
}
IFOKDO(err, m_importer->getDocument()->stepForward(i + 1))
}
SKGENDTRANSACTION(m_importer->getDocument(), err)
}
}
IFOKDO(err, m_importer->getDocument()->stepForward(6))
// Step 7 - stock
IFOK(err) {
SKGStringListList listStock;
err = SKGServices::executeSelectSqliteOrder(originalDocument, QStringLiteral("SELECT STOCKID, HELDAT, PURCHASEDATE, STOCKNAME, SYMBOL, NUMSHARES, PURCHASEPRICE, NOTES, CURRENTPRICE, VALUE, COMMISSION FROM STOCK_V1"), listStock);
IFOK(err) {
int nb = listStock.count() - 1;
err = m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Import step", "Import stocks"), nb);
for (int i = 0; !err && i < nb; ++i) {
const QStringList& attributes = listStock.at(i + 1);
// Create unit
SKGUnitObject unit(m_importer->getDocument());
err = unit.setName(attributes.at(3));
IFOKDO(err, unit.setSymbol(attributes.at(4)))
IFOKDO(err, unit.setType(SKGUnitObject::SHARE))
IFOKDO(err, unit.save())
SKGUnitValueObject unitValue;
IFOKDO(err, unit.addUnitValue(unitValue))
IFOKDO(err, unitValue.setDate(SKGServices::stringToTime(attributes.at(2)).date()))
IFOKDO(err, unitValue.setQuantity(SKGServices::stringToDouble(attributes.at(6))))
IFOKDO(err, unitValue.save(true, false))
SKGUnitValueObject unitValue2;
IFOKDO(err, unit.addUnitValue(unitValue2))
IFOKDO(err, unitValue2.setDate(QDate::currentDate()))
IFOKDO(err, unitValue2.setQuantity(SKGServices::stringToDouble(attributes.at(8))))
IFOKDO(err, unitValue2.save(true, false))
// Create operation
SKGAccountObject acc = mapAccount[attributes.at(1)];
SKGUnitObject unitCurrency;
IFOKDO(err, acc.getUnit(unitCurrency))
SKGOperationObject op;
IFOKDO(err, acc.addOperation(op, true))
IFOKDO(err, op.setComment(attributes.at(7)))
IFOKDO(err, op.setDate(SKGServices::stringToTime(attributes.at(2)).date()))
IFOKDO(err, op.setAttribute(QStringLiteral("t_imported"), QStringLiteral("T")))
IFOKDO(err, op.setImportID("MMEX-STOCK-" % attributes.at(0)))
IFOKDO(err, op.setUnit(unit))
IFOKDO(err, op.save())
SKGSubOperationObject subop;
IFOKDO(err, op.addSubOperation(subop))
IFOKDO(err, subop.setQuantity(SKGServices::stringToDouble(attributes.at(5))))
IFOKDO(err, subop.save(true, false))
/*SKGOperationObject op2;
if(!err) err = acc.addOperation(op2, true);
if(!err) err = op2.setComment(attributes.at(7));
if(!err) err = op2.setDate(SKGServices::stringToTime(attributes.at(2)).date());
if(!err) err = op2.setAttribute(QStringLiteral("t_imported"), QStringLiteral("T"));
if(!err) err = op2.setImportID("MMEX-STOCK-" % attributes.at(0)% "_TR");
if(!err) err = op2.setUnit(unitCurrency);
if(!err) err = op2.save();
SKGSubOperationObject subop2;
if(!err) err = op2.addSubOperation(subop2);
if(!err) err = subop2.setQuantity(-SKGServices::stringToDouble(attributes.at(5))*SKGServices::stringToDouble(attributes.at(6)));
if(!err) err = subop2.save();
if(!err) err = op.setGroupOperation(op2);
if(!err) err = op.save();*/
IFOKDO(err, m_importer->getDocument()->stepForward(i + 1))
}
SKGENDTRANSACTION(m_importer->getDocument(), err)
}
}
IFOKDO(err, m_importer->getDocument()->stepForward(7))
// Step 8 - asset
IFOK(err) {
SKGStringListList listAssets;
err = SKGServices::executeSelectSqliteOrder(originalDocument, QStringLiteral("SELECT ASSETID, STARTDATE, ASSETNAME, VALUE, VALUECHANGE, NOTES, VALUECHANGERATE, ASSETTYPE FROM ASSETS_V1"), listAssets);
IFOK(err) {
int nb = listAssets.count() - 1;
if (nb != 0) {
// Create account
// Create bank
SKGBankObject bank(m_importer->getDocument());
IFOKDO(err, bank.setName(QStringLiteral("MMEX")))
IFOKDO(err, bank.save())
// Create account
SKGAccountObject account;
err = bank.addAccount(account);
IFOKDO(err, account.setName(i18nc("Noun, a type of account", "Assets")))
IFOKDO(err, account.setType(SKGAccountObject::ASSETS))
IFOKDO(err, account.save())
err = m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Import step", "Import assets"), nb);
for (int i = 0; !err && i < nb; ++i) {
const QStringList& attributes = listAssets.at(i + 1);
// Create unit
SKGUnitObject unit(m_importer->getDocument());
err = unit.setName(attributes.at(2));
IFOKDO(err, unit.setSymbol(attributes.at(2)))
IFOKDO(err, unit.setType(SKGUnitObject::OBJECT))
IFOKDO(err, unit.setInternetCode(QStringLiteral("=") % (attributes.at(4) == QStringLiteral("Depreciates") ? QStringLiteral("-") : QStringLiteral("+")) % attributes.at(6)))
IFOKDO(err, unit.save())
SKGUnitValueObject unitValue;
IFOKDO(err, unit.addUnitValue(unitValue))
IFOKDO(err, unitValue.setDate(SKGServices::stringToTime(attributes.at(1)).date()))
IFOKDO(err, unitValue.setQuantity(SKGServices::stringToDouble(attributes.at(3))))
IFOKDO(err, unitValue.save(true, false))
// Create operation
SKGOperationObject op;
IFOKDO(err, account.addOperation(op, true))
IFOKDO(err, op.setComment(attributes.at(5)))
IFOKDO(err, op.setDate(SKGServices::stringToTime(attributes.at(1)).date()))
IFOKDO(err, op.setAttribute(QStringLiteral("t_imported"), QStringLiteral("T")))
IFOKDO(err, op.setImportID("MMEX-ASSET-" % attributes.at(0)))
IFOKDO(err, op.setUnit(unit))
IFOKDO(err, op.save())
SKGSubOperationObject subop;
IFOKDO(err, op.addSubOperation(subop))
IFOKDO(err, subop.setQuantity(1.0))
IFOKDO(err, subop.save(true, false))
IFOKDO(err, m_importer->getDocument()->stepForward(i + 1))
}
SKGENDTRANSACTION(m_importer->getDocument(), err)
}
}
}
IFOKDO(err, m_importer->getDocument()->stepForward(8))
// Step 9 - budgets
IFOK(err) {
SKGStringListList listBudgets;
err = SKGServices::executeSelectSqliteOrder(originalDocument, QStringLiteral("SELECT BUDGETENTRYID, (SELECT Y.BUDGETYEARNAME FROM BUDGETYEAR_V1 Y WHERE Y.BUDGETYEARID=BUDGETTABLE_V1.BUDGETYEARID), CATEGID, SUBCATEGID, PERIOD, AMOUNT FROM BUDGETTABLE_V1"), listBudgets);
IFOK(err) {
int nb = listBudgets.count() - 1;
err = m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Import step", "Import budgets"), nb);
for (int i = 0; !err && i < nb; ++i) {
const QStringList& attributes = listBudgets.at(i + 1);
const QString& period = attributes.at(4);
int step = 0;
double coef = 0;
if (period == QStringLiteral("Weekly")) {
coef = 52.0 / 12.0;
step = 1;
} else if (period == QStringLiteral("Monthly")) {
coef = 1;
step = 1;
} else if (period == QStringLiteral("Bi-Weekly")) {
coef = 52.0 / 12.0 / 2.0;
step = 1;
} else if (period == QStringLiteral("Bi-Monthly")) {
coef = 1;
step = 2;
} else if (period == QStringLiteral("Quarterly")) {
coef = 1;
step = 4;
} else if (period == QStringLiteral("Half-Yearly")) {
coef = 1;
step = 6;
} else if (period == QStringLiteral("Yearly")) {
coef = 1;
step = 12;
}
if (step != 0) {
for (int j = 0; !err && j < 12; j = j + step) {
SKGBudgetObject bug(m_importer->getDocument());
err = bug.setYear(SKGServices::stringToInt(attributes.at(1)));
IFOKDO(err, bug.setMonth(step == 12 ? 0 : j + 1))
IFOK(err) {
QString id = attributes.at(3);
if (id == QStringLiteral("-1")) {
id = attributes.at(2);
if (id != QStringLiteral("-1")) {
err = bug.setCategory(mapCategory[id]);
}
} else {
err = bug.setCategory(mapSubCategory[id]);
}
}
IFOKDO(err, bug.setBudgetedAmount(coef * SKGServices::stringToDouble(attributes.at(5))))
IFOKDO(err, bug.save())
}
}
IFOKDO(err, m_importer->getDocument()->stepForward(i + 1))
}
SKGENDTRANSACTION(m_importer->getDocument(), err)
}
}
IFOKDO(err, m_importer->getDocument()->stepForward(9))
SKGENDTRANSACTION(m_importer->getDocument(), err)
IFOKDO(err, m_importer->getDocument()->executeSqliteOrder(QStringLiteral("ANALYZE")))
}
originalDocument.close();
}
QSqlDatabase::removeDatabase(QStringLiteral("originalDocument"));
return err;
}
QString SKGImportPluginMmb::getMimeTypeFilter() const
{
return "*.mmb|" % i18nc("A file format", "Money Manager Ex document");
}
#include <skgimportpluginmmb.moc>
diff --git a/plugins/import/skrooge_import_mmb/skgimportpluginmmb.h b/plugins/import/skrooge_import_mmb/skgimportpluginmmb.h
index 71881e312..df9f6ce74 100644
--- a/plugins/import/skrooge_import_mmb/skgimportpluginmmb.h
+++ b/plugins/import/skrooge_import_mmb/skgimportpluginmmb.h
@@ -1,70 +1,70 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGIMPORTPLUGINMMB_H
#define SKGIMPORTPLUGINMMB_H
/** @file
* This file is Skrooge plugin for MMB import / export.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgimportplugin.h"
/**
* This file is Skrooge plugin for MMB import / export.
*/
class SKGImportPluginMmb : public SKGImportPlugin
{
Q_OBJECT
Q_INTERFACES(SKGImportPlugin)
public:
/**
* Default constructor
* @param iImporter the parent importer
* @param iArg the arguments
*/
explicit SKGImportPluginMmb(QObject* iImporter, const QVariantList& iArg);
/**
* Default Destructor
*/
~SKGImportPluginMmb() override;
/**
* To know if import is possible with this plugin
*/
bool isImportPossible() override;
/**
* Import a file
* @return an object managing the error.
* @see SKGError
*/
SKGError importFile() override;
/**
* Return the mime type filter
* @return the mime type filter. Example: "*.csv|CSV file"
*/
QString getMimeTypeFilter() const override;
private:
Q_DISABLE_COPY(SKGImportPluginMmb)
};
#endif // SKGIMPORTPLUGINMMB_H
diff --git a/plugins/import/skrooge_import_mny/CMakeLists.txt b/plugins/import/skrooge_import_mny/CMakeLists.txt
index ff4bd47e8..d700203e0 100644
--- a/plugins/import/skrooge_import_mny/CMakeLists.txt
+++ b/plugins/import/skrooge_import_mny/CMakeLists.txt
@@ -1,33 +1,33 @@
#***************************************************************************
#* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
#* *
#* 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 <http://www.gnu.org/licenses/> *
+#* along with this program. If not, see <https://www.gnu.org/licenses/> *
#***************************************************************************
MESSAGE( STATUS "..:: CMAKE PLUGIN_IMPORT_MNY ::..")
PROJECT(plugin_import_mny)
LINK_DIRECTORIES (${LIBRARY_OUTPUT_PATH})
SET(skrooge_import_mny_SRCS
skgimportpluginmny.cpp
)
ADD_LIBRARY(skrooge_import_mny MODULE ${skrooge_import_mny_SRCS})
TARGET_LINK_LIBRARIES(skrooge_import_mny KF5::Parts Qt5::Core skgbasemodeler skgbasegui skgbankmodeler skgbankgui)
########### install files ###############
INSTALL(TARGETS skrooge_import_mny DESTINATION ${KDE_INSTALL_QTPLUGINDIR})
INSTALL(FILES ${PROJECT_SOURCE_DIR}/org.kde.skrooge-import-mny.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR})
diff --git a/plugins/import/skrooge_import_mny/org.kde.skrooge-import-mny.desktop b/plugins/import/skrooge_import_mny/org.kde.skrooge-import-mny.desktop
index 6fd0cea38..87445b059 100644
--- a/plugins/import/skrooge_import_mny/org.kde.skrooge-import-mny.desktop
+++ b/plugins/import/skrooge_import_mny/org.kde.skrooge-import-mny.desktop
@@ -1,62 +1,62 @@
[Desktop Entry]
Name=Skrooge import MNY plugin
Name[bs]=Skrooge dodatak za MNY uvoz
Name[ca]=Connector d'importació de MNY de l'Skrooge
Name[ca@valencia]=Connector d'importació de MNY de l'Skrooge
Name[cs]=Modul Skrooge pro import MNY
Name[da]=Plugin til import af MNY til Skrooge
Name[de]=Skrooge-MNY-Importmodul
Name[el]=Skrooge import MNY plugin
Name[en_GB]=Skrooge import MNY plugin
Name[es]=Complemento de Skrooge para la importación de MNY
Name[fi]=Skroogen MNY-tuontiliitännäinen
-Name[fr]=Module externe de Skrooge pour l'importation « MNY »
+Name[fr]=Module externe de Skrooge pour l'importation « MNY »
Name[gl]=Complemento de importación de MNY a Skrooge
Name[hu]=Skrooge MNY importáló bővítmény
Name[it]=Estensione di Skrooge per l'importazione MNY
Name[nl]=Plug-in van Skrooge voor MNY-importeren
Name[pl]=Wtyczka importu MNY dla Skrooge
Name[pt]='Plugin' de importação de MNY para o Skrooge
Name[pt_BR]=Plugin de importação de MNY para o Skrooge
Name[ru]=Модуль импорта файлов MNY
Name[sk]=Skrooge import MNY plugin
Name[sv]=Skrooge MNY-importinsticksprogram
Name[tr]=Skrooge MNY içe aktarma eklentisi
Name[uk]=Додаток імпортування MNY до Skrooge
Name[x-test]=xxSkrooge import MNY pluginxx
Name[zh_TW]=Skrooge 匯入 MNY 外掛程式
Comment=A Skrooge plugin to import Microsoft Money files
Comment[ca]=Un connector de l'Skrooge per importar fitxers de Microsoft Money
Comment[ca@valencia]=Un connector de l'Skrooge per importar fitxers de Microsoft Money
Comment[cs]=Modul Skrooge pro import souborů Microsoft Money
Comment[de]=Ein Skrooge-Modul zum Import von „Microsoft Money"-Dateien
Comment[en_GB]=A Skrooge plugin to import Microsoft Money files
Comment[es]=Un complemento de Skrooge para importar archivos de Microsoft Money
Comment[fi]=Skroogen Microsoft Money -tiedostojen tuontiliitännäinen
Comment[fr]=Un module externe de Skrooge pour l'importation de fichiers Microsoft Money
Comment[gl]=Un complemento de Skrooge para importar ficheiros Microsoft Money.
Comment[it]=Un'estensione di Skrooge per importare i file Microsoft Money
Comment[nl]=Een Skrooge-plugin voor het importeren van Microsoft Money bestanden
Comment[pl]=Wtyczka Skrooge do importu plików Microsoft Money
Comment[pt]=Um 'plugin' do Skrooge para importar ficheiros do Microsoft Money
Comment[pt_BR]=Um plugin do Skrooge para importar arquivos do Microsoft Money
Comment[sk]=Skrooge plugin na import súborov Microsoft Money
Comment[sv]=Ett insticksprogram till Skrooge för att importera Microsoft Money-filer
Comment[tr]=Microsoft Money dosyalarını içe aktarmak için bir Skrooge eklentisi
Comment[uk]=Додаток до Skrooge для імпортування даних з файлів Microsoft Money
Comment[x-test]=xxA Skrooge plugin to import Microsoft Money filesxx
Encoding=UTF-8
Icon=skrooge
Type=Service
X-KDE-ServiceTypes=SKG IMPORT/Plugin
X-KDE-Library=skrooge_import_mny
X-Krunner-ID=Skrooge import MNY plugin
X-KDE-PluginInfo-Author=Stephane MANKOWSKI
X-KDE-PluginInfo-Email=stephane@mankowski.fr
X-KDE-PluginInfo-Name=skrooge_import_mny
X-KDE-PluginInfo-Version=1.0
-X-KDE-PluginInfo-Website=http://skrooge.org/
+X-KDE-PluginInfo-Website=https://skrooge.org/
X-KDE-PluginInfo-Category=Plugins
X-KDE-PluginInfo-Depends=
X-KDE-PluginInfo-License=GPL
X-KDE-PluginInfo-EnabledByDefault=true
diff --git a/plugins/import/skrooge_import_mny/skgimportpluginmny.cpp b/plugins/import/skrooge_import_mny/skgimportpluginmny.cpp
index c680fe708..3300a6c12 100644
--- a/plugins/import/skrooge_import_mny/skgimportpluginmny.cpp
+++ b/plugins/import/skrooge_import_mny/skgimportpluginmny.cpp
@@ -1,525 +1,525 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is Skrooge plugin for KMY import / export.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgimportpluginmny.h"
#include <klocalizedstring.h>
#include <kpluginfactory.h>
#include <qdir.h>
#include <qjsondocument.h>
#include <qprocess.h>
#include <qstandardpaths.h>
#include <quuid.h>
#include "skgbankincludes.h"
#include "skgimportexportmanager.h"
#include "skgobjectbase.h"
#include "skgpayeeobject.h"
#include "skgservices.h"
#include "skgtraces.h"
QMap<QString, SKGUnitObject> SKGImportPluginMny::m_mapIdSecurity;
QMap<QString, SKGAccountObject> SKGImportPluginMny::m_mapIdAccount;
QMap<QString, SKGCategoryObject> SKGImportPluginMny::m_mapIdCategory;
QMap<QString, SKGPayeeObject> SKGImportPluginMny::m_mapIdPayee;
/**
* This plugin factory.
*/
K_PLUGIN_FACTORY(SKGImportPluginMnyFactory, registerPlugin<SKGImportPluginMny>();)
SKGImportPluginMny::SKGImportPluginMny(QObject* iImporter, const QVariantList& iArg)
: SKGImportPlugin(iImporter)
{
SKGTRACEINFUNC(10)
Q_UNUSED(iArg)
m_importParameters[QStringLiteral("password")] = QString();
m_importParameters[QStringLiteral("install_sunriise")] = 'N';
}
SKGImportPluginMny::~SKGImportPluginMny()
= default;
bool SKGImportPluginMny::removeDir(const QString& dirName)
{
bool result = false;
QDir dir(dirName);
if (dir.exists(dirName)) {
const auto list = dir.entryInfoList(QDir::NoDotAndDotDot | QDir::System | QDir::Hidden | QDir::AllDirs | QDir::Files, QDir::DirsFirst);
for (const auto& info : list) {
if (info.isDir()) {
result = SKGImportPluginMny::removeDir(info.absoluteFilePath());
} else {
result = QFile::remove(info.absoluteFilePath());
}
if (!result) {
return result;
}
}
result = dir.rmdir(dirName);
}
return result;
}
bool SKGImportPluginMny::isImportPossible()
{
SKGTRACEINFUNC(10)
if (m_importer == nullptr) {
return true;
}
QString extension = m_importer->getFileNameExtension();
return (extension == QStringLiteral("MNY"));
}
SKGError SKGImportPluginMny::readJsonFile(const QString& iFileName, QVariant& oVariant)
{
SKGError err;
SKGTRACEINFUNCRC(2, err)
QFile file(iFileName);
if (Q_UNLIKELY(!file.open(QIODevice::ReadOnly))) {
err.setReturnCode(ERR_INVALIDARG).setMessage(i18nc("Error message", "Open file '%1' failed", iFileName));
} else {
QByteArray json = file.readAll();
file.close();
QJsonParseError ok{};
oVariant = QJsonDocument::fromJson(json, &ok).toVariant();
if (ok.error != QJsonParseError::NoError || json.isEmpty()) {
err.setReturnCode(ERR_FAIL).setMessage(ok.errorString()).addError(ERR_FAIL, i18nc("Error message", "Error during parsing of '%1'", file.fileName()));
}
}
return err;
}
SKGError SKGImportPluginMny::importFile()
{
if (m_importer == nullptr) {
return SKGError(ERR_ABORT, i18nc("Error message", "Invalid parameters"));
}
SKGError err;
SKGTRACEINFUNCRC(2, err)
// Check read access file
if (!QFileInfo(m_importer->getLocalFileName()).isReadable()) {
err.setReturnCode(ERR_READACCESS).setMessage(i18nc("Error message", "The file %1 does not have read access rights", m_importer->getLocalFileName()));
return err;
}
// Check install
if (QStandardPaths::findExecutable(QStringLiteral("java")).isEmpty()) {
err.setReturnCode(ERR_ABORT).setMessage(i18nc("Error message", "The java application is not installed. You must manually install it."));
return err;
}
QString sunriise_jar = QDir::homePath() % "/.skrooge/sunriise.jar";
if (!QFile(sunriise_jar).exists()) {
if (m_importParameters.value(QStringLiteral("install_sunriise")) == QStringLiteral("Y")) {
QDir::home().mkdir(QStringLiteral(".skrooge"));
- err = SKGServices::upload(QUrl(QStringLiteral("http://skrooge.org/files/sunriise.jar")), QUrl::fromLocalFile(sunriise_jar));
+ err = SKGServices::upload(QUrl(QStringLiteral("https://skrooge.org/files/sunriise.jar")), QUrl::fromLocalFile(sunriise_jar));
IFKO(err) return err;
} else {
err.setReturnCode(ERR_INSTALL).setMessage(i18nc("Error message", "The sunriise application is needed for Microsoft Money import but is not installed in '%1'", sunriise_jar));
err.setProperty("application", "sunriise");
return err;
}
}
// Initialisation
m_mapIdSecurity.clear();
m_mapIdAccount.clear();
m_mapIdCategory.clear();
m_mapIdPayee.clear();
// Execute sunriise
QString uniqueId = QUuid::createUuid().toString();
QString temporaryPath = QDir::tempPath() % "/" % uniqueId;
removeDir(temporaryPath);
QDir::temp().mkdir(uniqueId);
QDir temporaryDir(temporaryPath);
QString cmd = "java -cp \"" % sunriise_jar % "\" com/le/sunriise/export/ExportToJSON \"" % m_importer->getLocalFileName() % "\" \"" % m_importParameters.value(QStringLiteral("password")) % "\" " % temporaryPath;
SKGTRACEL(10) << "Execution of :" << cmd << endl;
QProcess p;
p.start(cmd);
if (p.waitForFinished(1000 * 60 * 5) && p.exitCode() == 0) {
// Import
err = m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Import step", "Import %1 file", "MNY"), 6);
// Step 1-Import categories
IFOK(err) {
/*[ {
"id" : 137,
"parentId" : 130,
"name" : "Other Income",
"classificationId" : 0,
"level" : 1
},*/
QVariant var;
err = readJsonFile(temporaryPath % "/categories.json", var);
QVariantList list = var.toList();
IFOK(err) {
SKGTRACEINRC(10, "SKGImportPluginMny::importFile-categories", err)
int nb = list.count();
err = m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Import step", "Import categories"), nb);
// Create categories
int index = 0;
for (int t = 0; !err && t < 20 && index < nb; ++t) {
for (int i = 0; !err && i < nb && index < nb; ++i) {
QVariantMap category = list.at(i).toMap();
QString parentId = category[QStringLiteral("parentId")].toString();
QString id = category[QStringLiteral("id")].toString();
QString name = category[QStringLiteral("name")].toString();
int level = category[QStringLiteral("level")].toInt();
if (level == t) {
SKGCategoryObject catObject(m_importer->getDocument());
err = catObject.setName(name);
if (!err && !parentId.isEmpty()) {
err = catObject.setParentCategory(m_mapIdCategory[parentId]);
}
IFOKDO(err, catObject.save())
m_mapIdCategory[id] = catObject;
++index;
IFOKDO(err, m_importer->getDocument()->stepForward(index))
}
}
}
SKGENDTRANSACTION(m_importer->getDocument(), err)
}
IFOKDO(err, m_importer->getDocument()->stepForward(1))
}
// Step 2-Import payees
IFOK(err) {
QVariant var;
err = readJsonFile(temporaryPath % "/payees.json", var);
QVariantList list = var.toList();
IFOK(err) {
SKGTRACEINRC(10, "SKGImportPluginMny::importFile-payees", err)
int nb = list.count();
err = m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Import step", "Import payees"), nb);
// Create categories
for (int i = 0; !err && i < nb; ++i) {
QVariantMap payee = list.at(i).toMap();
QString id = payee[QStringLiteral("id")].toString();
QString name = payee[QStringLiteral("name")].toString();
// Is already created?
SKGPayeeObject payeeObject(m_importer->getDocument());
err = payeeObject.setName(name);
IFOKDO(err, payeeObject.save())
m_mapIdPayee[id] = payeeObject;
IFOKDO(err, m_importer->getDocument()->stepForward(i + 1))
}
SKGENDTRANSACTION(m_importer->getDocument(), err)
}
IFOKDO(err, m_importer->getDocument()->stepForward(2))
}
// Step 3-Import securities
IFOK(err) {
QVariant var;
err = readJsonFile(temporaryPath % "/securities.json", var);
QVariantList list = var.toList();
IFOK(err) {
SKGTRACEINRC(10, "SKGImportPluginMny::importFile-securities", err)
int nb = list.count();
err = m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Import step", "Import units"), nb);
// Create categories
for (int i = 0; !err && i < nb; ++i) {
QVariantMap unit = list.at(i).toMap();
QString id = unit[QStringLiteral("id")].toString();
QString name = unit[QStringLiteral("name")].toString();
QString symbol = unit[QStringLiteral("symbol")].toString();
if (symbol.isEmpty()) {
symbol = name;
}
// Is already created?
SKGUnitObject unitobject(m_importer->getDocument());
err = unitobject.setName(name);
IFOKDO(err, unitobject.setSymbol(symbol))
IFOKDO(err, unitobject.setType(SKGUnitObject::SHARE))
// The unit is not saved because it will be saved when used
m_mapIdSecurity[id] = unitobject;
IFOKDO(err, m_importer->getDocument()->stepForward(i + 1))
}
SKGENDTRANSACTION(m_importer->getDocument(), err)
}
IFOKDO(err, m_importer->getDocument()->stepForward(3))
}
// Step 4-Import accounts
IFOK(err) {
/*
{
"id" : 1,
"name" : "Investments to Watch",
"relatedToAccountId" : null,
"relatedToAccount" : null,
"type" : 5,
"accountType" : "INVESTMENT",
"closed" : false,
"startingBalance" : 0.0000,
"currentBalance" : 0,
"currencyId" : 18,
"currencyCode" : "GBP",
"retirement" : false,
"investmentSubType" : -1,
"securityHoldings" : [ ],
"amountLimit" : null,
"creditCard" : false,
"401k403b" : false
}*/
// List directories
QStringList list = temporaryDir.entryList(QStringList() << QStringLiteral("*.d"), QDir::Dirs);
SKGTRACEINFUNCRC(10, err)
int nb = list.count();
err = m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Import step", "Import accounts"), nb);
SKGBankObject bank(m_importer->getDocument());
IFOKDO(err, bank.setName(QStringLiteral("Microsof Money")))
IFOKDO(err, bank.save())
// Create accounts
for (int i = 0; !err && i < nb; ++i) {
const QString& accountDir = list.at(i);
QVariant var;
err = readJsonFile(temporaryPath % "/" % accountDir % "/account.json", var);
QVariantMap account = var.toMap();
IFOK(err) {
// Create currency
SKGUnitObject unitObj;
err = SKGUnitObject::createCurrencyUnit(m_importer->getDocument(), account[QStringLiteral("currencyCode")].toString(), unitObj);
// Create account
SKGAccountObject accountObj;
IFOKDO(err, bank.addAccount(accountObj))
IFOKDO(err, accountObj.setName(account[QStringLiteral("name")].toString()))
int type = account[QStringLiteral("type")].toInt();
IFOKDO(err, accountObj.setType(type == 0 ? SKGAccountObject::CURRENT :
type == 1 ? SKGAccountObject::CREDITCARD :
type == 3 ? SKGAccountObject::ASSETS :
type == 5 ? SKGAccountObject::INVESTMENT :
type == 6 ? SKGAccountObject::LOAN :
SKGAccountObject::OTHER)); // TODO(Stephane MANKOWSKI)
IFOKDO(err, accountObj.save())
// Update initial balance
IFOKDO(err, accountObj.setInitialBalance(account[QStringLiteral("startingBalance")].toDouble(), unitObj))
IFOKDO(err, accountObj.setClosed(account[QStringLiteral("closed")].toBool()))
IFOKDO(err, accountObj.save())
m_mapIdAccount[account[QStringLiteral("id")].toString()] = accountObj;
}
IFOKDO(err, m_importer->getDocument()->stepForward(i + 1))
}
SKGENDTRANSACTION(m_importer->getDocument(), err)
}
IFOKDO(err, m_importer->getDocument()->stepForward(4))
// Step 5-Import operation
IFOK(err) {
// List directories
QStringList list = temporaryDir.entryList(QStringList() << QStringLiteral("*.d"), QDir::Dirs);
SKGTRACEINFUNCRC(10, err)
int nb = list.count();
err = m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Import step", "Import operations"), nb);
// Create accounts
int index = 0;
for (int i = 0; !err && i < nb; ++i) {
const QString& accountDir = list.at(i);
QVariant var;
err = readJsonFile(temporaryPath % "/" % accountDir % "/transactions.json", var);
QVariantList operations = var.toList();
IFOK(err) {
int nbo = operations.count();
err = m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Import step", "Import operations"), nbo);
for (int j = 0; !err && j < nbo; ++j) {
QVariantMap operation = operations.at(j).toMap();
if (!operation[QStringLiteral("void")].toBool()) {
SKGAccountObject accountObj = m_mapIdAccount.value(operation[QStringLiteral("accountId")].toString());
QString securityId = operation[QStringLiteral("securityId")].toString();
SKGUnitObject unitObj;
if (securityId.isEmpty()) {
IFOKDO(err, accountObj.getUnit(unitObj))
} else {
unitObj = m_mapIdSecurity[securityId];
if (unitObj.getID() == 0) {
err = unitObj.save();
m_mapIdSecurity[securityId] = unitObj;
}
}
SKGOperationObject operationObj;
IFOKDO(err, accountObj.addOperation(operationObj, true))
IFOKDO(err, operationObj.setUnit(unitObj))
IFOKDO(err, operationObj.setDate(QDateTime::fromMSecsSinceEpoch(operation[QStringLiteral("date")].toULongLong()).date()))
IFOKDO(err, operationObj.setComment(operation[QStringLiteral("memo")].toString()))
IFOK(err) {
// The number is something like "0 4220725" or "1string"
QString number = operation[QStringLiteral("number")].toString();
if (!number.isEmpty()) {
if (number.startsWith(QLatin1Char('1'))) {
err = operationObj.setMode(number.right(number.count() - 1));
} else {
QStringList ln = SKGServices::splitCSVLine(number, ' ');
err = operationObj.setNumber(ln.at(ln.count() - 1));
}
}
}
IFOKDO(err, operationObj.setAttribute(QStringLiteral("t_imported"), QStringLiteral("T")))
IFOKDO(err, operationObj.setImportID("MNY-" % operation[QStringLiteral("id")].toString()))
QString payId = operation[QStringLiteral("payeeId")].toString();
if (!payId.isEmpty() && !err) {
err = operationObj.setPayee(m_mapIdPayee[payId]);
}
IFOKDO(err, operationObj.setStatus(operation[QStringLiteral("reconciled")].toBool() ? SKGOperationObject::CHECKED :
operation[QStringLiteral("cleared")].toBool() ? SKGOperationObject::POINTED :
SKGOperationObject::NONE));
if (operation[QStringLiteral("transfer")].toBool()) {
IFOKDO(err, operationObj.setComment("#MNYTRANSFER#" % operationObj.getComment()))
}
IFOKDO(err, operationObj.save(false))
double amount = operation[QStringLiteral("amount")].toDouble();
// Is it a split?
QVariantList splits = operation[QStringLiteral("splits")].toList();
int nbs = splits.count();
if (nbs != 0) {
// Yes
for (int k = 0; !err && k < nbs; ++k) {
QVariantMap split = splits[k].toMap();
QVariantMap transaction = split[QStringLiteral("transaction")].toMap();
SKGSubOperationObject subOperationObj;
IFOKDO(err, operationObj.addSubOperation(subOperationObj))
QString catId = transaction[QStringLiteral("categoryId")].toString();
if (!catId.isEmpty() && !err) {
err = subOperationObj.setCategory(m_mapIdCategory[catId]);
}
double splitAmount = transaction[QStringLiteral("amount")].toDouble();
IFOKDO(err, subOperationObj.setQuantity(splitAmount))
IFOKDO(err, subOperationObj.setComment(operation[QStringLiteral("memo")].toString()))
IFOKDO(err, subOperationObj.save(false, false))
amount -= splitAmount;
}
// Is the amount equal to the sum of split?
if (qAbs(amount) > 0.00001) {
// Create one more sub operation to align amounts
SKGSubOperationObject subOperationObj;
IFOKDO(err, operationObj.addSubOperation(subOperationObj))
IFOKDO(err, subOperationObj.setQuantity(amount))
IFOKDO(err, subOperationObj.setComment(operation[QStringLiteral("memo")].toString()))
IFOKDO(err, subOperationObj.save(false, false))
IFOKDO(err, m_importer->getDocument()->sendMessage(i18nc("Warning message", "The operation '%1' has been repaired because its amount was not equal to the sum of the amounts of its splits", operationObj.getDisplayName()), SKGDocument::Warning))
}
} else {
// No
SKGSubOperationObject subOperationObj;
IFOKDO(err, operationObj.addSubOperation(subOperationObj))
QString catId = operation[QStringLiteral("categoryId")].toString();
if (!catId.isEmpty() && !err) {
err = subOperationObj.setCategory(m_mapIdCategory[catId]);
}
IFOKDO(err, subOperationObj.setQuantity(amount))
IFOKDO(err, subOperationObj.setComment(operation[QStringLiteral("memo")].toString()))
IFOKDO(err, subOperationObj.save(false, false))
}
}
if (!err && index % 500 == 0) {
err = m_importer->getDocument()->executeSqliteOrder(QStringLiteral("ANALYZE"));
}
++index;
IFOKDO(err, m_importer->getDocument()->stepForward(j + 1))
}
SKGENDTRANSACTION(m_importer->getDocument(), err)
}
IFOKDO(err, m_importer->getDocument()->stepForward(i + 1))
}
SKGENDTRANSACTION(m_importer->getDocument(), err)
}
IFOKDO(err, m_importer->getDocument()->stepForward(5))
// Step 6-Group operation
int nbg = 0;
IFOKDO(err, m_importer->findAndGroupTransfers(nbg, QStringLiteral("A.t_comment LIKE '#MNYTRANSFER#%' AND B.t_comment LIKE '#MNYTRANSFER#%'")))
IFOKDO(err, m_importer->getDocument()->executeSqliteOrder(QStringLiteral("UPDATE operation SET t_comment=SUBSTR(t_comment, 14) WHERE t_comment LIKE '#MNYTRANSFER#%'")))
IFOKDO(err, m_importer->getDocument()->stepForward(6))
SKGENDTRANSACTION(m_importer->getDocument(), err)
} else {
if (p.exitCode() == 1) {
err.setReturnCode(ERR_ENCRYPTION).setMessage(i18nc("Error message", "Invalid password"));
} else {
err.setReturnCode(ERR_FAIL).setMessage(i18nc("Error message", "The execution of '%1' failed", cmd)).addError(ERR_FAIL, i18nc("Error message", "The extraction from the Microsoft Money document '%1' failed", m_importer->getFileName().toDisplayString()));
}
}
removeDir(temporaryPath);
// Clean
m_mapIdSecurity.clear();
m_mapIdAccount.clear();
m_mapIdCategory.clear();
m_mapIdPayee.clear();
return err;
}
QString SKGImportPluginMny::getMimeTypeFilter() const
{
return "*.mny|" % i18nc("A file format", "Microsoft Money document");
}
#include <skgimportpluginmny.moc>
diff --git a/plugins/import/skrooge_import_mny/skgimportpluginmny.h b/plugins/import/skrooge_import_mny/skgimportpluginmny.h
index 6ae7d228c..24bf22b58 100644
--- a/plugins/import/skrooge_import_mny/skgimportpluginmny.h
+++ b/plugins/import/skrooge_import_mny/skgimportpluginmny.h
@@ -1,86 +1,86 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGIMPORTPLUGINMNY_H
#define SKGIMPORTPLUGINMNY_H
/** @file
* This file is Skrooge plugin for Microsoft Money import.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include <qset.h>
#include "skgimportplugin.h"
class SKGUnitObject;
class SKGAccountObject;
class SKGCategoryObject;
class SKGPayeeObject;
/**
* This file is Skrooge plugin for KMY import / export.
*/
class SKGImportPluginMny : public SKGImportPlugin
{
Q_OBJECT
Q_INTERFACES(SKGImportPlugin)
public:
/**
* Default constructor
* @param iImporter the parent importer
* @param iArg the arguments
*/
explicit SKGImportPluginMny(QObject* iImporter, const QVariantList& iArg);
/**
* Default Destructor
*/
~SKGImportPluginMny() override;
/**
* To know if import is possible with this plugin
*/
bool isImportPossible() override;
/**
* Import a file
* @return an object managing the error.
* @see SKGError
*/
SKGError importFile() override;
/**
* Return the mime type filter
* @return the mime type filter. Example: "*.csv|CSV file"
*/
QString getMimeTypeFilter() const override;
private:
Q_DISABLE_COPY(SKGImportPluginMny)
bool removeDir(const QString& dirName);
SKGError readJsonFile(const QString& iFileName, QVariant& oVariant);
static QMap<QString, SKGUnitObject> m_mapIdSecurity;
static QMap<QString, SKGAccountObject> m_mapIdAccount;
static QMap<QString, SKGCategoryObject> m_mapIdCategory;
static QMap<QString, SKGPayeeObject> m_mapIdPayee;
};
#endif // SKGIMPORTPLUGINMNY_H
diff --git a/plugins/import/skrooge_import_mt940/CMakeLists.txt b/plugins/import/skrooge_import_mt940/CMakeLists.txt
index 3ed4bbbe1..95477689f 100644
--- a/plugins/import/skrooge_import_mt940/CMakeLists.txt
+++ b/plugins/import/skrooge_import_mt940/CMakeLists.txt
@@ -1,33 +1,33 @@
#***************************************************************************
#* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
#* *
#* 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 <http://www.gnu.org/licenses/> *
+#* along with this program. If not, see <https://www.gnu.org/licenses/> *
#***************************************************************************
MESSAGE( STATUS "..:: CMAKE PLUGIN_IMPORT_MT940 ::..")
PROJECT(plugin_import_mt940)
LINK_DIRECTORIES (${LIBRARY_OUTPUT_PATH})
SET(skrooge_import_mt940_SRCS
skgimportpluginmt940.cpp
)
ADD_LIBRARY(skrooge_import_mt940 MODULE ${skrooge_import_mt940_SRCS})
TARGET_LINK_LIBRARIES(skrooge_import_mt940 KF5::Parts skgbasemodeler skgbasegui skgbankmodeler skgbankgui)
########### install files ###############
INSTALL(TARGETS skrooge_import_mt940 DESTINATION ${KDE_INSTALL_QTPLUGINDIR})
INSTALL(FILES ${PROJECT_SOURCE_DIR}/org.kde.skrooge-import-mt940.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR})
diff --git a/plugins/import/skrooge_import_mt940/org.kde.skrooge-import-mt940.desktop b/plugins/import/skrooge_import_mt940/org.kde.skrooge-import-mt940.desktop
index 6c57006c8..11e598390 100644
--- a/plugins/import/skrooge_import_mt940/org.kde.skrooge-import-mt940.desktop
+++ b/plugins/import/skrooge_import_mt940/org.kde.skrooge-import-mt940.desktop
@@ -1,74 +1,74 @@
[Desktop Entry]
Name=Skrooge import MT940 plugin
Name[bs]=Skrooge dodatak za MT940 uvoz
Name[ca]=Connector d'importació de MT940 de l'Skrooge
Name[ca@valencia]=Connector d'importació de MT940 de l'Skrooge
Name[cs]=Modul Skrooge pro import MT940
Name[da]=Plugin til import af MT940 til Skrooge
Name[de]=Skrooge-MT940-Importmodul
Name[el]=Skrooge import MT940 plugin
Name[en_GB]=Skrooge import MT940 plugin
Name[es]=Complemento de Skrooge para la importación de MT940
Name[et]=Skrooge MT940 impordi plugin
Name[fi]=Skroogen MT940-tuontiliitännäinen
-Name[fr]=Module externe de Skrooge pour l'importation « MT940 »
+Name[fr]=Module externe de Skrooge pour l'importation « MT940 »
Name[gl]=Complemento de importación de MT940 a Skrooge
Name[hu]=Skrooge MT940 importáló bővítmény
Name[it]=Estensione di Skrooge per l'importazione MT940
Name[lt]=Skrooge MT940 importavimo papildinys
Name[nb]=Skrooge-modul for MT940-import
Name[nl]=Plugin van Skrooge voor importeren van MT940
Name[pl]=Wtyczka importu MT940 dla Skrooge
Name[pt]='Plugin' de importação de MT940 para o Skrooge
Name[pt_BR]=Plugin de importação de MT940 para o Skrooge
Name[ru]=Модуль импорта файлов MT940
Name[sk]=Skrooge plugin MT940 import
Name[sv]=Skrooge MT940-importinsticksprogram
Name[tr]=Skrooge MT940 içe aktarma eklentisi
Name[uk]=Додаток імпортування MT940 до Skrooge
Name[x-test]=xxSkrooge import MT940 pluginxx
Name[zh_TW]=Skrooge 匯入 MT940 外掛程式
Comment=A Skrooge plugin to import MT940 files
Comment[bs]=Skrooge dodatak za uvoz MT940 datoteka
Comment[ca]=Un connector de l'Skrooge per importar fitxers MT940
Comment[ca@valencia]=Un connector de l'Skrooge per importar fitxers MT940
Comment[cs]=Modul Skrooge pro import souborů MT940
Comment[da]=Et Skrooge-plugin til at importere MT940-filer
Comment[de]=Ein Skrooge-Modul zum Import von MT940-Dateien
Comment[el]=Ένα πρόσθετο του Skrooge για την εισαγωγή αρχείων MT940
Comment[en_GB]=A Skrooge plugin to import MT940 files
Comment[es]=Complemento de Skrooge para importar archivos MT940
Comment[et]=Skrooge plugin MT940-failide importimiseks
Comment[fi]=Skroogen MT940-tiedostojen tuontiliitännäinen
-Comment[fr]=Un module externe de Skrooge pour l'importation de fichiers « MT940 »
+Comment[fr]=Un module externe de Skrooge pour l'importation de fichiers « MT940 »
Comment[gl]=Un complemento de Skrooge para importar ficheiros MT940.
Comment[hu]=Egy Skrooge bővítmény MT940 fájlok importálásához
Comment[it]=Un'estensione di Skrooge per importare i file MT940
Comment[lt]=Skrooge MT940 failų importavimo papildinys
Comment[nb]=En Skrooge-modul for å importere MT940-filer
Comment[nl]=Een Skrooge-plugin voor het importeren van MT940-bestanden
Comment[pl]=Wtyczka Skrooge do importu plików MT940
Comment[pt]=Um 'plugin' do Skrooge para importar ficheiros MT940
Comment[pt_BR]=Um plugin do Skrooge para importar arquivos MT940
Comment[ru]=Модуль импорта файлов MT940
Comment[sk]=Plugin Skrooge na import súborov MT940
Comment[sv]=Ett insticksprogram till Skrooge för att importera MT940-filer
Comment[tr]=MT940 dosyalarını içe aktarmak için Skrooge eklentisi
Comment[uk]=Додаток до Skrooge для імпортування даних з файлів MT940
Comment[x-test]=xxA Skrooge plugin to import MT940 filesxx
Comment[zh_TW]=Skrooge 匯入 MT940 檔用的外掛程式
Encoding=UTF-8
Icon=skrooge
Type=Service
X-KDE-ServiceTypes=SKG IMPORT/Plugin
X-KDE-Library=skrooge_import_mt940
X-Krunner-ID=Skrooge import MT940 plugin
X-KDE-PluginInfo-Author=Stephane MANKOWSKI
X-KDE-PluginInfo-Email=stephane@mankowski.fr
X-KDE-PluginInfo-Name=skrooge_import_mt940
X-KDE-PluginInfo-Version=1.0
-X-KDE-PluginInfo-Website=http://skrooge.org/
+X-KDE-PluginInfo-Website=https://skrooge.org/
X-KDE-PluginInfo-Category=Plugins
X-KDE-PluginInfo-Depends=
X-KDE-PluginInfo-License=GPL
X-KDE-PluginInfo-EnabledByDefault=true
diff --git a/plugins/import/skrooge_import_mt940/skgimportpluginmt940.cpp b/plugins/import/skrooge_import_mt940/skgimportpluginmt940.cpp
index 8e094bf81..9237140fb 100644
--- a/plugins/import/skrooge_import_mt940/skgimportpluginmt940.cpp
+++ b/plugins/import/skrooge_import_mt940/skgimportpluginmt940.cpp
@@ -1,257 +1,257 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is Skrooge plugin for MT940 import / export.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgimportpluginmt940.h"
#include <qfile.h>
#include <klocalizedstring.h>
#include <kpluginfactory.h>
#include "skgbankincludes.h"
#include "skgimportexportmanager.h"
#include "skgobjectbase.h"
#include "skgservices.h"
#include "skgtraces.h"
/**
* This plugin factory.
*/
K_PLUGIN_FACTORY(SKGImportPluginMT940Factory, registerPlugin<SKGImportPluginMT940>();)
SKGImportPluginMT940::SKGImportPluginMT940(QObject* iImporter, const QVariantList& iArg)
: SKGImportPlugin(iImporter)
{
SKGTRACEINFUNC(10)
Q_UNUSED(iArg)
}
SKGImportPluginMT940::~SKGImportPluginMT940()
= default;
bool SKGImportPluginMT940::isImportPossible()
{
SKGTRACEINFUNC(10)
return (m_importer == nullptr ? true : m_importer->getFileNameExtension() == QStringLiteral("MT940"));
}
SKGError SKGImportPluginMT940::importFile()
{
if (m_importer == nullptr) {
return SKGError(ERR_ABORT, i18nc("Error message", "Invalid parameters"));
}
SKGError err;
SKGTRACEINFUNCRC(2, err)
// Begin transaction
err = m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Import step", "Import %1 file", "MT940"), 2);
IFOK(err) {
// Open file
IFOK(err) {
QFile file(m_importer->getLocalFileName());
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
err.setReturnCode(ERR_INVALIDARG).setMessage(i18nc("Error message", "Open file '%1' failed", m_importer->getFileName().toDisplayString()));
} else {
// Read lines
QStringList lines;
{
QTextStream stream(&file);
if (!m_importer->getCodec().isEmpty()) {
stream.setCodec(m_importer->getCodec().toLatin1().constData());
}
while (!stream.atEnd()) {
// Read line
QString line = stream.readLine().trimmed();
if (!line.isEmpty()) {
lines.push_back(line);
}
}
}
// close file
file.close();
// Step 1 done
IFOKDO(err, m_importer->getDocument()->stepForward(1))
// Read lines
bool importActivated = false;
bool in86 = false;
SKGAccountObject account;
SKGOperationObject operation;
SKGUnitObject unit;
QString bankName = QStringLiteral("MT940");
int nb = lines.count();
IFOKDO(err, m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Import step", "Import operations"), nb))
for (int i = 0; i < nb && !err; ++i) {
// Read line
const QString& line = lines.at(i);
if (!line.isEmpty()) {
if (line.startsWith(QLatin1String(":20:"))) {
importActivated = true;
in86 = false;
bankName = line.right(line.count() - 4);
} else if (importActivated) {
if (line.startsWith(QLatin1String(":25:"))) {
// Account
QStringList vals = SKGServices::splitCSVLine(line.right(line.count() - 4), '/');
QString name = QStringLiteral("MT940");
QString number = name;
if (vals.count() == 2) {
bankName = vals.at(0);
number = vals.at(1);
name = number;
} else if (vals.count() == 1) {
number = vals.at(0);
name = number;
}
// Search if account is already existing
SKGObjectBase::SKGListSKGObjectBase listAccount;
err = m_importer->getDocument()->getObjects(QStringLiteral("v_account"), "t_number='" % number % '\'', listAccount);
IFOK(err) {
if (listAccount.count() == 1) {
// Yes ! Only one account found
account = listAccount.at(0);
err = m_importer->getDocument()->sendMessage(i18nc("An information message", "Using account '%1' for import", account.getName()));
} else {
if (listAccount.count() > 1) {
err = m_importer->getDocument()->sendMessage(i18nc("An information message", "More than one possible account found."));
}
SKGBankObject bank(m_importer->getDocument());
IFOKDO(err, bank.setName(bankName))
IFOKDO(err, bank.setNumber(bankName))
if (!err && bank.load().isFailed()) {
err = bank.save();
}
IFOKDO(err, bank.addAccount(account))
IFOKDO(err, account.setName(name))
IFOKDO(err, account.setNumber(number))
IFOKDO(err, account.setType(SKGAccountObject::CURRENT))
if (!err && account.load().isFailed()) {
err = account.save();
}
IFOKDO(err, m_importer->getDocument()->sendMessage(i18nc("An information message", "Default account '%1' created for import", name)))
}
}
in86 = false;
} else if (line.startsWith(QLatin1String(":28C:"))) {
in86 = false;
} else if (line.startsWith(QLatin1String(":60F:")) || line.startsWith(QLatin1String(":60M:"))) {
QString val = line.right(line.count() - 5);
err = SKGUnitObject::createCurrencyUnit(m_importer->getDocument(), val.mid(7, 3), unit);
// Example C040802EUR16,40
if (account.getNbOperation() > 1) {
IFOKDO(err, m_importer->getDocument()->sendMessage(i18nc("An information message", "The initial balance of '%1' has not been set because some operations are already existing", account.getName()), SKGDocument::Warning))
} else {
// Set initial balance
IFOKDO(err, account.setInitialBalance((val[0] == 'C' ? 1.0 : -1.0) * SKGServices::stringToDouble(val.right(val.count() - 10)), unit))
IFOKDO(err, account.save())
IFOKDO(err, m_importer->getDocument()->sendMessage(i18nc("An information message", "The initial balance of '%1' has been set with MT940 file content", account.getName())))
}
in86 = false;
} else if (line.startsWith(QLatin1String(":62F:")) || line.startsWith(QLatin1String(":62M:"))) {
in86 = false;
} else if (line.startsWith(QLatin1String(":61:"))) {
// Example :61:0712280103D000000000200,00FMSCNONREF
QString val = line.right(line.count() - 4);
QDate date = QDate::fromString(val.left(6), QStringLiteral("yyMMdd"));
if (date.year() < 1970) {
date = date.addYears(100);
}
int index = (val[10] == 'R' ? 11 : 10);
double sign = (val[index] == 'C' ? 1.0 : -1.0);
++index;
if (val[index] == 'R') {
++index;
}
QString amountString;
while (true) {
if ((val[index] >= '0' && val[index] <= '9') || val[index] == '-' || val[index] == ',') {
amountString += val[index];
++index;
} else {
break;
}
}
err = account.addOperation(operation, true);
IFOKDO(err, operation.setDate(date))
IFOKDO(err, operation.setUnit(unit))
IFOKDO(err, operation.setAttribute(QStringLiteral("t_imported"), QStringLiteral("T")))
// if(!err) err = operation.setImportID("MT940");
IFOKDO(err, operation.save())
SKGSubOperationObject subop;
err = operation.addSubOperation(subop);
IFOKDO(err, subop.setQuantity(sign * SKGServices::stringToDouble(amountString)))
IFOKDO(err, subop.save())
in86 = false;
} else if (line.startsWith(QLatin1String(":NS:")) && !operation.exist()) {
QString val = line.right(line.count() - 4);
QString comment = account.getComment();
comment += (comment.isEmpty() || val.isEmpty() ? "" : " ") % val;
IFOKDO(err, account.setComment(comment))
IFOKDO(err, account.save())
} else if (line.startsWith(QLatin1String(":86:")) || line.startsWith(QLatin1String(":NS:"))) {
QString val = line.right(line.count() - 4);
QString comment = operation.getComment();
comment += (comment.isEmpty() || val.isEmpty() ? "" : " ") % val;
IFOKDO(err, operation.setComment(comment))
IFOKDO(err, operation.save())
in86 = true;
} else if (in86) {
const QString& val = line;
QString comment = operation.getComment();
comment += (comment.isEmpty() || val.isEmpty() ? "" : " ") % val;
IFOKDO(err, operation.setComment(comment))
IFOKDO(err, operation.save())
}
}
}
IFOKDO(err, m_importer->getDocument()->stepForward(i + 1))
}
SKGENDTRANSACTION(m_importer->getDocument(), err)
// Step 2 done
IFOKDO(err, m_importer->getDocument()->stepForward(2))
}
}
}
SKGENDTRANSACTION(m_importer->getDocument(), err)
return err;
}
QString SKGImportPluginMT940::getMimeTypeFilter() const
{
return "*.mt940|" % i18nc("A file format", "MT940 file");
}
#include <skgimportpluginmt940.moc>
diff --git a/plugins/import/skrooge_import_mt940/skgimportpluginmt940.h b/plugins/import/skrooge_import_mt940/skgimportpluginmt940.h
index cc39f034a..a66af4b23 100644
--- a/plugins/import/skrooge_import_mt940/skgimportpluginmt940.h
+++ b/plugins/import/skrooge_import_mt940/skgimportpluginmt940.h
@@ -1,70 +1,70 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGIMPORTPLUGINMT940_H
#define SKGIMPORTPLUGINMT940_H
/** @file
* This file is Skrooge plugin for MT940 import / export.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgimportplugin.h"
/**
* This file is Skrooge plugin for MT940 import / export.
*/
class SKGImportPluginMT940 : public SKGImportPlugin
{
Q_OBJECT
Q_INTERFACES(SKGImportPlugin)
public:
/**
* Default constructor
* @param iImporter the parent importer
* @param iArg the arguments
*/
explicit SKGImportPluginMT940(QObject* iImporter, const QVariantList& iArg);
/**
* Default Destructor
*/
~SKGImportPluginMT940() override;
/**
* To know if import is possible with this plugin
*/
bool isImportPossible() override;
/**
* Import a file
* @return an object managing the error.
* @see SKGError
*/
SKGError importFile() override;
/**
* Return the mime type filter
* @return the mime type filter. Example: "*.csv|CSV file"
*/
QString getMimeTypeFilter() const override;
private:
Q_DISABLE_COPY(SKGImportPluginMT940)
};
#endif // SKGIMPORTPLUGINMT940_H
diff --git a/plugins/import/skrooge_import_ofx/CMakeLists.txt b/plugins/import/skrooge_import_ofx/CMakeLists.txt
index 9996acb0b..538bb63b8 100644
--- a/plugins/import/skrooge_import_ofx/CMakeLists.txt
+++ b/plugins/import/skrooge_import_ofx/CMakeLists.txt
@@ -1,38 +1,38 @@
#***************************************************************************
#* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
#* *
#* 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 <http://www.gnu.org/licenses/> *
+#* along with this program. If not, see <https://www.gnu.org/licenses/> *
#***************************************************************************
MESSAGE( STATUS "..:: CMAKE PLUGIN_IMPORT_OFX ::..")
PROJECT(plugin_import_ofx)
MESSAGE( STATUS "OFX found. OFX support enabled")
INCLUDE(KDECompilerSettings NO_POLICY_SCOPE)
KDE_ENABLE_EXCEPTIONS()
LINK_DIRECTORIES (${LIBRARY_OUTPUT_PATH})
SET(skrooge_import_ofx_SRCS
skgimportpluginofx.cpp
)
ADD_LIBRARY(skrooge_import_ofx MODULE ${skrooge_import_ofx_SRCS})
TARGET_LINK_LIBRARIES(skrooge_import_ofx KF5::Parts ${LIBOFX_LIBRARIES} skgbasemodeler skgbasegui skgbankmodeler skgbankgui)
########### install files ###############
INSTALL(TARGETS skrooge_import_ofx DESTINATION ${KDE_INSTALL_QTPLUGINDIR})
INSTALL(FILES ${PROJECT_SOURCE_DIR}/org.kde.skrooge-import-ofx.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR})
diff --git a/plugins/import/skrooge_import_ofx/org.kde.skrooge-import-ofx.desktop b/plugins/import/skrooge_import_ofx/org.kde.skrooge-import-ofx.desktop
index ad2cbca07..506621b9f 100644
--- a/plugins/import/skrooge_import_ofx/org.kde.skrooge-import-ofx.desktop
+++ b/plugins/import/skrooge_import_ofx/org.kde.skrooge-import-ofx.desktop
@@ -1,74 +1,74 @@
[Desktop Entry]
Name=Skrooge import OFX plugin
Name[bs]=Skrooge dodatak za OFX uvoz
Name[ca]=Connector d'importació d'OFX de l'Skrooge
Name[ca@valencia]=Connector d'importació d'OFX de l'Skrooge
Name[cs]=Modul Skrooge pro import OFX
Name[da]=Plugin til import af OFX til Skrooge
Name[de]=Skrooge-OFX-Importmodul
Name[el]=Skrooge import OFX plugin
Name[en_GB]=Skrooge import OFX plugin
Name[es]=Complemento de Skrooge para la importación de OFX
Name[et]=Skrooge OFX impordi plugin
Name[fi]=Skroogen OFX-tuontiliitännäinen
-Name[fr]=Module externe de Skrooge pour l'importation « OFX »
+Name[fr]=Module externe de Skrooge pour l'importation « OFX »
Name[gl]=Complemento de importación de OFX a Skrooge
Name[hu]=Skrooge OFX importáló bővítmény
Name[it]=Estensione di Skrooge per l'importazione OFX
Name[lt]=Skrooge OFX importavimo papildinys
Name[nb]=Skrooge-modul for OFX-import
Name[nl]=Plugin van Skrooge voor importeren van OFX
Name[pl]=Wtyczka importu OFX dla Skrooge
Name[pt]='Plugin' de importação de OFX para o Skrooge
Name[pt_BR]=Plugin de importação de OFX para o Skrooge
Name[ru]=Модуль импорта файлов OFX
Name[sk]=Skrooge plugin OFX import
Name[sv]=Skrooge OFX-importinsticksprogram
Name[tr]=Skrooge OFX içe aktarma eklentisi
Name[uk]=Додаток імпортування OFX до Skrooge
Name[x-test]=xxSkrooge import OFX pluginxx
Name[zh_TW]=Skrooge 匯入 OFX 外掛程式
Comment=A Skrooge plugin to import OFX files
Comment[bs]=Skrooge dodatak za uvoz OFX datoteka
Comment[ca]=Un connector de l'Skrooge per importar fitxers OFX
Comment[ca@valencia]=Un connector de l'Skrooge per importar fitxers OFX
Comment[cs]=Modul Skrooge pro import souborů OFX
Comment[da]=Et Skrooge-plugin til at importere OFX-filer
Comment[de]=Ein Skrooge-Modul zum Import von OFX-Dateien
Comment[el]=Ένα πρόσθετο του Skrooge για την εισαγωγή αρχείων OFX
Comment[en_GB]=A Skrooge plugin to import OFX files
Comment[es]=Complemento de Skrooge para importar archivos OFX
Comment[et]=Skrooge plugin OFX-failide importimiseks
Comment[fi]=Skroogen OFX-tiedostojen tuontiliitännäinen
-Comment[fr]=Un module externe de Skrooge pour l'importation de fichiers « OFX »
+Comment[fr]=Un module externe de Skrooge pour l'importation de fichiers « OFX »
Comment[gl]=Un complemento de Skrooge para importar ficheiros OFX.
Comment[hu]=Egy Skrooge bővítmény OFX fájlok importálásához
Comment[it]=Un'estensione di Skrooge per importare i file OFX
Comment[lt]=Skrooge OFX failų importavimo papildinys
Comment[nb]=En Skrooge-modul for å importere OFX-filer
Comment[nl]=Een Skrooge-plugin voor het importeren van OFX-bestanden
Comment[pl]=Wtyczka Skrooge do importu plików OFX
Comment[pt]=Um 'plugin' do Skrooge para importar ficheiros OFX
Comment[pt_BR]=Um plugin do Skrooge para importar arquivos OFX
Comment[ru]=Модуль импорта файлов OFX
Comment[sk]=Skrooge plugin na import OFX súborov
Comment[sv]=Ett insticksprogram till Skrooge för att importera OFX-filer
Comment[tr]=OFX dosyalarını içe aktarmak için Skrooge eklentisi
Comment[uk]=Додаток до Skrooge для імпортування даних з файлів OFX
Comment[x-test]=xxA Skrooge plugin to import OFX filesxx
Comment[zh_TW]=Skrooge 匯入 OFX 檔用的外掛程式
Encoding=UTF-8
Icon=skrooge
Type=Service
X-KDE-ServiceTypes=SKG IMPORT/Plugin
X-KDE-Library=skrooge_import_ofx
X-Krunner-ID=Skrooge import OFX plugin
X-KDE-PluginInfo-Author=Stephane MANKOWSKI
X-KDE-PluginInfo-Email=stephane@mankowski.fr
X-KDE-PluginInfo-Name=skrooge_import_ofx
X-KDE-PluginInfo-Version=1.0
-X-KDE-PluginInfo-Website=http://skrooge.org/
+X-KDE-PluginInfo-Website=https://skrooge.org/
X-KDE-PluginInfo-Category=Plugins
X-KDE-PluginInfo-Depends=
X-KDE-PluginInfo-License=GPL
X-KDE-PluginInfo-EnabledByDefault=true
diff --git a/plugins/import/skrooge_import_ofx/skgimportpluginofx.cpp b/plugins/import/skrooge_import_ofx/skgimportpluginofx.cpp
index ff9eadb73..39e9b00b0 100644
--- a/plugins/import/skrooge_import_ofx/skgimportpluginofx.cpp
+++ b/plugins/import/skrooge_import_ofx/skgimportpluginofx.cpp
@@ -1,549 +1,549 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is Skrooge plugin for OFX import / export.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgimportpluginofx.h"
#include <qcryptographichash.h>
#include <qfile.h>
#include <klocalizedstring.h>
#include <kpluginfactory.h>
#include "skgbankincludes.h"
#include "skgimportexportmanager.h"
#include "skgservices.h"
#include "skgtraces.h"
SKGError SKGImportPluginOfx::m_ofxError;
QStringList SKGImportPluginOfx::m_ofxInitialBalanceName;
QList<double> SKGImportPluginOfx::m_ofxInitialBalanceAmount;
QList<QDate> SKGImportPluginOfx::m_ofxInitialBalanceDate;
QMap<QString, SKGAccountObject> SKGImportPluginOfx::m_accounts;
/**
* This plugin factory.
*/
K_PLUGIN_FACTORY(SKGImportPluginOfxFactory, registerPlugin<SKGImportPluginOfx>();)
SKGImportPluginOfx::SKGImportPluginOfx(QObject* iImporter, const QVariantList& iArg)
: SKGImportPlugin(iImporter)
{
SKGTRACEINFUNC(10)
Q_UNUSED(iArg)
SKGImportPluginOfx::m_accounts.clear();
}
SKGImportPluginOfx::~SKGImportPluginOfx()
= default;
bool SKGImportPluginOfx::isImportPossible()
{
SKGTRACEINFUNC(10)
return (m_importer == nullptr ? true : m_importer->getFileNameExtension() == QStringLiteral("OFX") || m_importer->getFileNameExtension() == QStringLiteral("QFX"));
}
SKGError SKGImportPluginOfx::importFile()
{
if (m_importer == nullptr) {
return SKGError(ERR_ABORT, i18nc("Error message", "Invalid parameters"));
}
SKGError err;
SKGTRACEINFUNCRC(2, err)
if (!QFile(m_importer->getLocalFileName()).exists()) {
err.setReturnCode(ERR_INVALIDARG).setMessage(i18nc("Error message", "Open file '%1' failed", m_importer->getFileName().toDisplayString()));
}
IFOKDO(err, m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Import step", "Import %1 file", "OFX")))
IFOK(err) {
SKGImportPluginOfx::m_ofxError = SKGError();
SKGImportPluginOfx::m_ofxInitialBalanceName.clear();
SKGImportPluginOfx::m_ofxInitialBalanceAmount.clear();
SKGImportPluginOfx::m_ofxInitialBalanceDate.clear();
try {
// Check file type
// auto type = libofx_detect_file_type( m_importer->getLocalFileName().toUtf8().data());
LibofxContextPtr ctx = libofx_get_new_context();
ofx_set_account_cb(ctx, SKGImportPluginOfx::ofxAccountCallback, m_importer);
ofx_set_statement_cb(ctx, SKGImportPluginOfx::ofxStatementCallback, m_importer);
ofx_set_transaction_cb(ctx, SKGImportPluginOfx::ofxTransactionCallback, m_importer);
// ofx_set_security_cb(ctx, ofxSecurityCallback, this);
int rc = libofx_proc_file(ctx, m_importer->getLocalFileName().toUtf8().data(), AUTODETECT);
if (rc != 0) {
err = SKGError(ERR_FAIL, i18nc("Error message", "Import OFX file '%1' failed", m_importer->getFileName().toDisplayString()));
}
IFOKDO(err, SKGImportPluginOfx::m_ofxError) {
// This is an option ==> no error management
SKGError err2;
int nb = SKGImportPluginOfx::m_ofxInitialBalanceName.count();
for (int i = 0; !err2 && i < nb; ++i) {
SKGAccountObject act;
err2 = m_importer->getDocument()->getObject(QStringLiteral("v_account"), "t_number='" % SKGServices::stringToSqlString(m_ofxInitialBalanceName.at(i)) % '\'', act);
// Date of balance
auto date = m_ofxInitialBalanceDate.at(i);
// Get unit
SKGUnitObject unit;
if (!err2) {
err2 = m_importer->getDefaultUnit(unit);
}
// Current amount
double currentAmount = act.getAmount(date);
// Update account
if (!err2) {
err2 = act.setInitialBalance(m_ofxInitialBalanceAmount.at(i) - currentAmount, unit);
}
if (!err2) {
err2 = act.save();
}
if (!err2) {
err2 = m_importer->getDocument()->sendMessage(i18nc("An information message", "The initial balance of '%1' has been set", act.getName()));
}
}
}
libofx_free_context(ctx);
} catch (...) { // NOLINT(whitespace/parens)
err = SKGError(ERR_HANDLE, i18nc("Error message", "OFX import failed"));
}
SKGImportPluginOfx::m_ofxInitialBalanceName.clear();
SKGImportPluginOfx::m_ofxInitialBalanceAmount.clear();
SKGImportPluginOfx::m_ofxInitialBalanceDate.clear();
SKGENDTRANSACTION(m_importer->getDocument(), err)
}
return err;
}
QString SKGImportPluginOfx::getAccountName(OfxAccountData* iAccountData)
{
SKGTRACEINFUNC(3)
QString accountNumber;
if (iAccountData != nullptr) {
accountNumber = QString::fromUtf8(iAccountData->account_id);
QString bankNumber = QString::fromUtf8(iAccountData->bank_id);
// Correction BUG 234771 vvvvv
accountNumber = accountNumber.trimmed();
bankNumber = bankNumber.trimmed();
if (accountNumber.isEmpty()) {
accountNumber = QString::fromUtf8(iAccountData->account_number);
}
// Correction BUG 234771 ^^^^^
if (accountNumber.startsWith(bankNumber % ' ')) {
accountNumber = accountNumber.right(accountNumber.length() - bankNumber.length() - 1);
QStringList splitNumbers = accountNumber.split(' ');
if (splitNumbers.count() == 2) {
accountNumber = splitNumbers.at(1);
}
}
}
SKGTRACEL(3) << "accountNumber=" << accountNumber << endl;
return accountNumber;
}
SKGError SKGImportPluginOfx::getAccount(OfxAccountData* iAccountData, SKGDocumentBank* iDoc, SKGAccountObject& oAccount)
{
SKGError err;
SKGTRACEINFUNCRC(3, err)
if ((iAccountData != nullptr) && (iDoc != nullptr)) {
// Check if account is already existing
QString name = getAccountName(iAccountData);
if (m_accounts.contains(name)) {
SKGTRACEL(3) << "Found in index" << endl;
oAccount = m_accounts[name];
} else {
SKGTRACEL(3) << "NOT found in index" << endl;
err = iDoc->getObject(QStringLiteral("v_account"), "t_number='" % SKGServices::stringToSqlString(name) % '\'', oAccount);
}
}
return err;
}
int SKGImportPluginOfx::ofxStatementCallback(struct OfxStatementData data, void* pv) // clazy:exclude=function-args-by-ref
{
if (SKGImportPluginOfx::m_ofxError) {
return 0;
}
SKGTRACEINFUNCRC(5, SKGImportPluginOfx::m_ofxError)
auto* impotExporter = static_cast<SKGImportExportManager*>(pv);
if (impotExporter == nullptr) {
return 0;
}
SKGDocumentBank* doc = impotExporter->getDocument();
if (doc == nullptr) {
return 0;
}
// // Get data
OfxAccountData* accountData = data.account_ptr;
if ((accountData != nullptr) && static_cast<bool>(data.ledger_balance_valid)) {
// Get account
SKGAccountObject act;
SKGImportPluginOfx::m_ofxError = getAccount(accountData, doc, act);
if (!SKGImportPluginOfx::m_ofxError) {
if (act.getNbOperation() > 1) {
SKGImportPluginOfx::m_ofxError = doc->sendMessage(i18nc("An information message", "The initial balance of '%1' has not been set because some operations are already existing", act.getName()));
} else {
m_ofxInitialBalanceName.push_back(getAccountName(accountData));
m_ofxInitialBalanceDate.push_back(static_cast<bool>(data.ledger_balance_date_valid) ? QDateTime::fromTime_t(data.ledger_balance_date).date() : QDate::currentDate());
m_ofxInitialBalanceAmount.push_back(data.ledger_balance);
}
}
}
return SKGImportPluginOfx::m_ofxError.getReturnCode();
}
int SKGImportPluginOfx::ofxAccountCallback(struct OfxAccountData data, void* pv)
{
if (SKGImportPluginOfx::m_ofxError) {
return 0;
}
SKGTRACEINFUNCRC(5, SKGImportPluginOfx::m_ofxError)
auto* impotExporter = static_cast<SKGImportExportManager*>(pv);
if (impotExporter == nullptr) {
return 0;
}
SKGDocumentBank* doc = impotExporter->getDocument();
if (doc == nullptr) {
return 0;
}
SKGObjectBase tmp;
QString agencyNumber = QString::fromUtf8(data.branch_id);
QString accountNumber = QString::fromUtf8(data.account_id);
QString bankNumber = QString::fromUtf8(data.bank_id);
// Correction BUG 234771 vvvvv
accountNumber = accountNumber.trimmed();
bankNumber = bankNumber.trimmed();
// Correction BUG 234771 ^^^^^
if (accountNumber.isEmpty()) {
accountNumber = QString::fromUtf8(data.account_number);
}
if (accountNumber.startsWith(bankNumber % ' ')) {
accountNumber = accountNumber.right(accountNumber.length() - bankNumber.length() - 1);
QStringList splitNumbers = accountNumber.split(' ');
if (splitNumbers.count() == 2) {
agencyNumber = splitNumbers.at(0);
accountNumber = splitNumbers.at(1);
}
}
// Check if account is already existing
SKGAccountObject account;
SKGImportPluginOfx::m_ofxError = getAccount(&data, doc, account);
if (!SKGImportPluginOfx::m_ofxError) {
// Already existing
account = tmp;
SKGImportPluginOfx::m_ofxError = impotExporter->setDefaultAccount(&account);
} else {
// Not existing
QString bankId = (static_cast<bool>(data.bank_id_valid) ? QString::fromUtf8(data.bank_id) : QString::fromUtf8(data.broker_id));
if (!bankId.isEmpty()) {
bankId = i18nc("Adjective, an unknown item", "Unknown");
}
// Check if bank is already existing
SKGBankObject bank;
SKGImportPluginOfx::m_ofxError = doc->getObject(QStringLiteral("v_bank"), "t_bank_number='" % SKGServices::stringToSqlString(bankId) % '\'', tmp);
if (!SKGImportPluginOfx::m_ofxError) {
// Already existing
bank = tmp;
} else {
// Create new bank
bank = SKGBankObject(doc);
SKGImportPluginOfx::m_ofxError = bank.setName(bankId);
if (!SKGImportPluginOfx::m_ofxError) {
SKGImportPluginOfx::m_ofxError = bank.setNumber(QString::fromUtf8(data.bank_id));
}
if (!SKGImportPluginOfx::m_ofxError) {
SKGImportPluginOfx::m_ofxError = bank.save();
}
}
// Create new account
QString name = QString::fromUtf8(data.account_name);
if (name.isEmpty()) {
name = QString::fromUtf8(data.account_id);
} else {
name = name.remove(QStringLiteral("Bank account "));
}
if (!SKGImportPluginOfx::m_ofxError) {
SKGImportPluginOfx::m_ofxError = bank.addAccount(account);
}
if (!SKGImportPluginOfx::m_ofxError) {
SKGImportPluginOfx::m_ofxError = account.setName(name);
}
if (!SKGImportPluginOfx::m_ofxError) {
SKGImportPluginOfx::m_ofxError = account.setNumber(accountNumber);
}
if (!SKGImportPluginOfx::m_ofxError) {
SKGImportPluginOfx::m_ofxError = account.setAgencyNumber(agencyNumber);
}
if (!SKGImportPluginOfx::m_ofxError) {
SKGImportPluginOfx::m_ofxError = account.setComment(QString::fromUtf8(data.account_name));
}
SKGAccountObject::AccountType type = SKGAccountObject::CURRENT;
if (static_cast<bool>(data.account_type_valid)) {
switch (data.account_type) {
case OfxAccountData::OFX_CHECKING:
case OfxAccountData::OFX_SAVINGS:
case OfxAccountData::OFX_CREDITLINE:
case OfxAccountData::OFX_CMA:
type = SKGAccountObject::CURRENT;
break;
case OfxAccountData::OFX_MONEYMRKT:
case OfxAccountData::OFX_INVESTMENT:
type = SKGAccountObject::INVESTMENT;
break;
case OfxAccountData::OFX_CREDITCARD:
type = SKGAccountObject::CREDITCARD;
break;
default:
break;
}
}
if (!SKGImportPluginOfx::m_ofxError) {
SKGImportPluginOfx::m_ofxError = account.setType(type);
}
if (!SKGImportPluginOfx::m_ofxError) {
SKGImportPluginOfx::m_ofxError = account.save();
m_accounts[accountNumber] = account;
SKGTRACEL(3) << "Add account '" << accountNumber << "' in index" << endl;
}
if (!SKGImportPluginOfx::m_ofxError) {
SKGImportPluginOfx::m_ofxError = impotExporter->setDefaultAccount(&account);
}
SKGTRACEL(10) << "Account [" << name << "] created" << endl;
}
if (static_cast<bool>(data.currency_valid)) {
// Check if unit is already existing
SKGUnitObject unit(doc);
SKGImportPluginOfx::m_ofxError = doc->getObject(QStringLiteral("v_unit"), "t_name='" % SKGServices::stringToSqlString(QString::fromUtf8(data.currency)) % "' OR t_name like '%(" % SKGServices::stringToSqlString(QString::fromUtf8(data.currency)) % ")%'", tmp);
if (!SKGImportPluginOfx::m_ofxError) {
// Already existing
unit = tmp;
SKGImportPluginOfx::m_ofxError = impotExporter->setDefaultUnit(&unit);
} else {
// Create new account
SKGImportPluginOfx::m_ofxError = unit.setName(QString::fromUtf8(data.currency));
if (!SKGImportPluginOfx::m_ofxError) {
SKGImportPluginOfx::m_ofxError = unit.setSymbol(QString::fromUtf8(data.currency));
}
if (!SKGImportPluginOfx::m_ofxError) {
SKGImportPluginOfx::m_ofxError = unit.save();
}
if (!SKGImportPluginOfx::m_ofxError) {
SKGImportPluginOfx::m_ofxError = impotExporter->setDefaultUnit(&unit);
}
}
}
return SKGImportPluginOfx::m_ofxError.getReturnCode();
}
int SKGImportPluginOfx::ofxTransactionCallback(struct OfxTransactionData data, void* pv) // clazy:exclude=function-args-by-ref
{
if (SKGImportPluginOfx::m_ofxError) {
return 0;
}
SKGTRACEINFUNCRC(5, SKGImportPluginOfx::m_ofxError)
auto* impotExporter = static_cast<SKGImportExportManager*>(pv);
if (impotExporter == nullptr) {
return 0;
}
SKGDocumentBank* doc = impotExporter->getDocument();
if (doc == nullptr) {
return 0;
}
// Get account
SKGAccountObject account;
SKGImportPluginOfx::m_ofxError = getAccount(data.account_ptr, doc, account);
if (!SKGImportPluginOfx::m_ofxError) {
// Get operation date
QDate date = QDateTime::fromTime_t(static_cast<bool>(data.date_initiated_valid) ? data.date_initiated : data.date_posted).date();
// Get unit
SKGUnitObject unit;
SKGImportPluginOfx::m_ofxError = impotExporter->getDefaultUnit(unit);
// Create id
QString ID;
if (static_cast<bool>(data.fi_id_valid)) {
if (QString::fromUtf8(data.fi_id).count('0') != QString::fromUtf8(data.fi_id).count()) {
ID = QStringLiteral("ID-") % QString::fromUtf8(data.fi_id);
}
} else if (static_cast<bool>(data.reference_number_valid)) {
if (QString::fromUtf8(data.reference_number).count('0') != QString::fromUtf8(data.reference_number).count()) {
ID = QStringLiteral("REF-") % data.reference_number;
}
}
if (ID.isEmpty()) {
QByteArray hash = QCryptographicHash::hash(QString(SKGServices::dateToSqlString(date) % SKGServices::doubleToString(data.amount)).toUtf8(), QCryptographicHash::Md5);
ID = QStringLiteral("ID-") % hash.toHex();
}
// Create operation
SKGOperationObject ope;
if (!SKGImportPluginOfx::m_ofxError) {
SKGImportPluginOfx::m_ofxError = account.addOperation(ope, true);
}
if (!SKGImportPluginOfx::m_ofxError) {
SKGImportPluginOfx::m_ofxError = ope.setDate(date);
}
if (!SKGImportPluginOfx::m_ofxError) {
SKGImportPluginOfx::m_ofxError = ope.setUnit(unit);
}
if (!SKGImportPluginOfx::m_ofxError) {
SKGImportPluginOfx::m_ofxError = ope.setAttribute(QStringLiteral("t_imported"), QStringLiteral("T"));
}
if (!SKGImportPluginOfx::m_ofxError) {
SKGImportPluginOfx::m_ofxError = ope.setImportID(ID);
}
if (!SKGImportPluginOfx::m_ofxError) {
QString payeeName;
if (static_cast<bool>(data.payee_id_valid)) {
payeeName = QString::fromUtf8(data.payee_id);
} else if (static_cast<bool>(data.name_valid)) {
payeeName = QString::fromUtf8(data.name);
}
if (!payeeName.isEmpty()) {
SKGPayeeObject payeeObj;
SKGImportPluginOfx::m_ofxError = SKGPayeeObject::createPayee(doc, payeeName, payeeObj);
if (!SKGImportPluginOfx::m_ofxError) {
SKGImportPluginOfx::m_ofxError = ope.setPayee(payeeObj);
}
}
}
if (!SKGImportPluginOfx::m_ofxError && static_cast<bool>(data.memo_valid)) {
SKGImportPluginOfx::m_ofxError = ope.setComment(QString::fromUtf8(data.memo));
}
if (!SKGImportPluginOfx::m_ofxError && static_cast<bool>(data.check_number_valid)) {
SKGImportPluginOfx::m_ofxError = ope.setNumber(data.check_number);
}
if (!SKGImportPluginOfx::m_ofxError && static_cast<bool>(data.invtransactiontype_valid)) {
SKGImportPluginOfx::m_ofxError = ope.setMode(i18nc("Noun, the title of an item", "Title"));
}
if (!SKGImportPluginOfx::m_ofxError && static_cast<bool>(data.transactiontype_valid)) {
QString mode;
if (data.transactiontype == OFX_CREDIT) {
mode = i18nc("Noun, type of OFX transaction", "Credit");
} else if (data.transactiontype == OFX_DEBIT) {
mode = i18nc("Noun, type of OFX transaction", "Debit");
} else if (data.transactiontype == OFX_INT) {
mode = i18nc("Noun, type of OFX transaction", "Interest");
} else if (data.transactiontype == OFX_DIV) {
mode = i18nc("Noun, type of OFX transaction", "Dividend");
} else if (data.transactiontype == OFX_FEE) {
mode = i18nc("Noun, type of OFX transaction", "FI fee");
} else if (data.transactiontype == OFX_SRVCHG) {
mode = i18nc("Noun, type of OFX transaction", "Service charge");
} else if (data.transactiontype == OFX_DEP) {
mode = i18nc("Noun, type of OFX transaction", "Deposit");
} else if (data.transactiontype == OFX_ATM) {
mode = i18nc("Noun, type of OFX transaction", "ATM");
} else if (data.transactiontype == OFX_POS) {
mode = i18nc("Noun, type of OFX transaction", "Point of sale");
} else if (data.transactiontype == OFX_XFER) {
mode = i18nc("An operation mode", "Transfer");
} else if (data.transactiontype == OFX_CHECK) {
mode = i18nc("An operation mode", "Check");
} else if (data.transactiontype == OFX_PAYMENT) {
mode = i18nc("Noun, type of OFX transaction", "Electronic payment");
} else if (data.transactiontype == OFX_CASH) {
mode = i18nc("An operation mode", "Withdrawal");
} else if (data.transactiontype == OFX_DIRECTDEP) {
mode = i18nc("Noun, type of OFX transaction", "Deposit");
} else if (data.transactiontype == OFX_REPEATPMT) {
mode = i18nc("Noun, type of OFX transaction", "Repeating payment");
} else if (data.transactiontype == OFX_DIRECTDEBIT) {
mode = i18nc("An operation mode", "Direct debit");
}
SKGImportPluginOfx::m_ofxError = ope.setMode(mode);
}
if (!SKGImportPluginOfx::m_ofxError) {
SKGImportPluginOfx::m_ofxError = ope.save();
}
// Create sub operation
SKGSubOperationObject subop;
if (!SKGImportPluginOfx::m_ofxError) {
SKGImportPluginOfx::m_ofxError = ope.addSubOperation(subop);
}
if (!SKGImportPluginOfx::m_ofxError && static_cast<bool>(data.amount_valid)) {
bool mustFlipSign = (data.transactiontype == OFX_DEBIT || data.transactiontype == OFX_FEE || data.transactiontype == OFX_SRVCHG ||
data.transactiontype == OFX_PAYMENT || data.transactiontype == OFX_CASH || data.transactiontype == OFX_DIRECTDEBIT ||
data.transactiontype == OFX_REPEATPMT) && data.amount > 0; // OFX spec version 2.1.1, section 3.2.9.2
double sign = mustFlipSign ? -1.0 : 1.0;
double commission = static_cast<bool>(data.commission_valid) ? data.commission : 0;
SKGImportPluginOfx::m_ofxError = subop.setQuantity(sign * (data.amount + commission));
}
if (!SKGImportPluginOfx::m_ofxError && static_cast<bool>(data.memo_valid)) {
SKGImportPluginOfx::m_ofxError = subop.setComment(QString::fromUtf8(data.memo));
}
if (!SKGImportPluginOfx::m_ofxError) {
SKGImportPluginOfx::m_ofxError = subop.save();
}
// Commission
if (!SKGImportPluginOfx::m_ofxError && static_cast<bool>(data.commission_valid) && static_cast<bool>(data.amount_valid) && data.commission > 0) {
// Create splitter operation
SKGSubOperationObject subop2;
if (!SKGImportPluginOfx::m_ofxError) {
SKGImportPluginOfx::m_ofxError = ope.addSubOperation(subop2);
}
if (!SKGImportPluginOfx::m_ofxError) {
SKGImportPluginOfx::m_ofxError = subop2.setComment(i18nc("Noun, a quantity of money taken by a financial institution to perform an operation", "Commission"));
}
if (!SKGImportPluginOfx::m_ofxError) {
SKGImportPluginOfx::m_ofxError = subop2.setQuantity(-data.commission);
}
if (!SKGImportPluginOfx::m_ofxError) {
SKGImportPluginOfx::m_ofxError = subop2.save();
}
}
}
return SKGImportPluginOfx::m_ofxError.getReturnCode();
}
QString SKGImportPluginOfx::getMimeTypeFilter() const
{
return "*.ofx *.qfx|" % i18nc("A file format", "OFX file");
}
#include <skgimportpluginofx.moc>
diff --git a/plugins/import/skrooge_import_ofx/skgimportpluginofx.h b/plugins/import/skrooge_import_ofx/skgimportpluginofx.h
index 72ddc24ee..064a84e55 100644
--- a/plugins/import/skrooge_import_ofx/skgimportpluginofx.h
+++ b/plugins/import/skrooge_import_ofx/skgimportpluginofx.h
@@ -1,85 +1,85 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGIMPORTPLUGINOFX_H
#define SKGIMPORTPLUGINOFX_H
/** @file
* This file is Skrooge plugin for OFX import / export.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgimportplugin.h"
#include <libofx/libofx.h>
#include <qdatetime.h>
/**
* This file is Skrooge plugin for OFX import / export.
*/
class SKGImportPluginOfx : public SKGImportPlugin
{
Q_OBJECT
Q_INTERFACES(SKGImportPlugin)
public:
/**
* Default constructor
* @param iImporter the parent importer
* @param iArg the arguments
*/
explicit SKGImportPluginOfx(QObject* iImporter, const QVariantList& iArg);
/**
* Default Destructor
*/
~SKGImportPluginOfx() override;
/**
* To know if import is possible with this plugin
*/
bool isImportPossible() override;
/**
* Import a file
* @return an object managing the error.
* @see SKGError
*/
SKGError importFile() override;
/**
* Return the mime type filter
* @return the mime type filter. Example: "*.csv|CSV file"
*/
QString getMimeTypeFilter() const override;
private:
Q_DISABLE_COPY(SKGImportPluginOfx)
static int ofxAccountCallback(struct OfxAccountData data, void* pv);
static int ofxTransactionCallback(struct OfxTransactionData data, void* pv);
static int ofxStatementCallback(struct OfxStatementData data, void* pv);
static QStringList m_ofxInitialBalanceName;
static QList<double> m_ofxInitialBalanceAmount;
static QList<QDate> m_ofxInitialBalanceDate;
static SKGError getAccount(OfxAccountData* iAccountData, SKGDocumentBank* iDoc, SKGAccountObject& oAccount);
static QString getAccountName(OfxAccountData* iAccountData);
static SKGError m_ofxError;
static QMap<QString, SKGAccountObject> m_accounts;
};
#endif // SKGIMPORTPLUGINOFX_H
diff --git a/plugins/import/skrooge_import_pdf/CMakeLists.txt b/plugins/import/skrooge_import_pdf/CMakeLists.txt
index 6700bf1f6..f09586d52 100644
--- a/plugins/import/skrooge_import_pdf/CMakeLists.txt
+++ b/plugins/import/skrooge_import_pdf/CMakeLists.txt
@@ -1,38 +1,38 @@
#***************************************************************************
#* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
#* *
#* 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 <http://www.gnu.org/licenses/> *
+#* along with this program. If not, see <https://www.gnu.org/licenses/> *
#***************************************************************************
MESSAGE( STATUS "..:: CMAKE PLUGIN_IMPORT_PDF ::..")
PROJECT(plugin_import_PDF)
LINK_DIRECTORIES (${LIBRARY_OUTPUT_PATH})
SET(skrooge_import_pdf_SRCS
skgimportpluginpdf.cpp
)
ADD_LIBRARY(skrooge_import_pdf MODULE ${skrooge_import_pdf_SRCS})
TARGET_LINK_LIBRARIES(skrooge_import_pdf KF5::Parts skgbasemodeler skgbasegui skgbankmodeler skgbankgui)
########### install files ###############
INSTALL(TARGETS skrooge_import_pdf DESTINATION ${KDE_INSTALL_QTPLUGINDIR})
INSTALL(FILES ${PROJECT_SOURCE_DIR}/org.kde.skrooge-import-pdf.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR})
INSTALL(DIRECTORY . DESTINATION ${KDE_INSTALL_DATADIR}/skrooge/extractors FILES_MATCHING PATTERN "*.extractor"
PATTERN ".svn" EXCLUDE
PATTERN "CMakeLists.txt" EXCLUDE
PATTERN "CMakeFiles" EXCLUDE
PATTERN "grantlee_filters" EXCLUDE
PATTERN "Testing" EXCLUDE)
diff --git a/plugins/import/skrooge_import_pdf/org.kde.skrooge-import-pdf.desktop b/plugins/import/skrooge_import_pdf/org.kde.skrooge-import-pdf.desktop
index bae00ccd5..f1ee5e31d 100644
--- a/plugins/import/skrooge_import_pdf/org.kde.skrooge-import-pdf.desktop
+++ b/plugins/import/skrooge_import_pdf/org.kde.skrooge-import-pdf.desktop
@@ -1,54 +1,54 @@
[Desktop Entry]
Name=Skrooge import PDF plugin
Name[ca]=Connector d'importació de PDF de l'Skrooge
Name[ca@valencia]=Connector d'importació de PDF de l'Skrooge
Name[cs]=Modul Skrooge pro import PDF
Name[de]=Skrooge-PDF-Importmodul
Name[en_GB]=Skrooge import PDF plugin
Name[es]=Complemento de Skrooge para la importación de PDF
Name[fi]=Skroogen PDF-tuontiliitännäinen
-Name[fr]=Module externe de Skrooge pour l'importation « PDF »
+Name[fr]=Module externe de Skrooge pour l'importation « PDF »
Name[gl]=Complemento para Skrooge de importación de PDF
Name[it]=Estensione di Skrooge per l'importazione PDF
Name[nl]=Plug-in van Skrooge voor importeren van PDF
Name[pl]=Wtyczka importu PDF dla Skrooge
Name[pt]='Plugin' de importação de PDF para o Skrooge
Name[sk]=Skrooge plugin na import PDF
Name[sv]=Skrooge PDF-importinsticksprogram
Name[tr]=Skrooge PDF içe aktarma eklentisi
Name[uk]=Додаток імпортування PDF до Skrooge
Name[x-test]=xxSkrooge import PDF pluginxx
Comment=A Skrooge plugin to import PDF files
Comment[ca]=Un connector de l'Skrooge per importar fitxers PDF
Comment[ca@valencia]=Un connector de l'Skrooge per importar fitxers PDF
Comment[cs]=Modul Skrooge pro import souborů PDF
Comment[de]=Ein Skrooge-Modul zum Import von PDF-Dateien
Comment[en_GB]=A Skrooge plugin to import PDF files
Comment[es]=Complemento de Skrooge para importar archivos PDF
Comment[fi]=Skrooge-liitännäinen PDF-tiedostojen tuomiseen
-Comment[fr]=Un module externe de Skrooge pour l'importation de factures « PDF »
+Comment[fr]=Un module externe de Skrooge pour l'importation de factures « PDF »
Comment[gl]=Un complemento para Skrooge para importar ficheiros PDF.
Comment[it]=Un'estensione di Skrooge per importare i file PDF
Comment[nl]=Een plug-in van Skrooge voor het importeren van PDF-bestanden
Comment[pl]=Wtyczka Skrooge do importu plików PDF
Comment[pt]=Um 'plugin' do Skrooge para importar ficheiros PDF
Comment[sk]=Skrooge plugin na import PDF súborov
Comment[sv]=Ett insticksprogram till Skrooge för att importera PDF-filer
Comment[tr]=PDF dosyalarını içe aktarmak için Skrooge eklentisi
Comment[uk]=Додаток до Skrooge для імпортування даних з файлів PDF
Comment[x-test]=xxA Skrooge plugin to import PDF filesxx
Encoding=UTF-8
Icon=skrooge
Type=Service
X-KDE-ServiceTypes=SKG IMPORT/Plugin
X-KDE-Library=skrooge_import_pdf
X-Krunner-ID=Skrooge import PDF plugin
X-KDE-PluginInfo-Author=Stephane MANKOWSKI
X-KDE-PluginInfo-Email=stephane@mankowski.fr
X-KDE-PluginInfo-Name=skrooge_import_pdf
X-KDE-PluginInfo-Version=1.0
-X-KDE-PluginInfo-Website=http://skrooge.org/
+X-KDE-PluginInfo-Website=https://skrooge.org/
X-KDE-PluginInfo-Category=Plugins
X-KDE-PluginInfo-Depends=
X-KDE-PluginInfo-License=GPL
X-KDE-PluginInfo-EnabledByDefault=true
diff --git a/plugins/import/skrooge_import_pdf/skgimportpluginpdf.cpp b/plugins/import/skrooge_import_pdf/skgimportpluginpdf.cpp
index 38be15a6a..424761782 100644
--- a/plugins/import/skrooge_import_pdf/skgimportpluginpdf.cpp
+++ b/plugins/import/skrooge_import_pdf/skgimportpluginpdf.cpp
@@ -1,260 +1,260 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is Skrooge plugin for PDF import / export.
* http://jerome.girod.perso.sfr.fr/finance/pdfx.php
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgimportpluginpdf.h"
#include <kpluginfactory.h>
#include <qdiriterator.h>
#include <qfileinfo.h>
#include <qprocess.h>
#include <qstandardpaths.h>
#include <qtemporaryfile.h>
#include "skgbankincludes.h"
#include "skgimportexportmanager.h"
#include "skgservices.h"
#include "skgtraces.h"
/**
* This plugin factory.
*/
K_PLUGIN_FACTORY(SKGImportPluginPDFFactory, registerPlugin<SKGImportPluginPDF>();)
SKGImportPluginPDF::SKGImportPluginPDF(QObject* iImporter, const QVariantList& iArg)
: SKGImportPlugin(iImporter)
{
SKGTRACEINFUNC(10)
Q_UNUSED(iArg)
}
SKGImportPluginPDF::~SKGImportPluginPDF()
= default;
bool SKGImportPluginPDF::isImportPossible()
{
SKGTRACEINFUNC(10)
return (m_importer == nullptr ? true : m_importer->getFileNameExtension() == QStringLiteral("PDF"));
}
QString SKGImportPluginPDF::extract(const QStringList& iLine, const QString& iSyntax)
{
QString output;
int currentIndex = -1;
bool setpossible = true;
// Interpret the syntax
auto items = SKGServices::splitCSVLine(iSyntax, '|', false);
for (const auto& item : items) {
if (item.startsWith(QLatin1String("REGEXPCAP:"))) {
QRegExp regexp(item.right(item.length() - 10));
if (output.isEmpty()) {
for (const auto& line : iLine) {
if (regexp.indexIn(line) > -1) {
output = regexp.cap(1);
break;
}
}
} else {
if (regexp.indexIn(output) > -1) {
output = regexp.cap(1);
}
}
} else if (item.startsWith(QLatin1String("REGEXP:"))) {
setpossible = false;
QRegExp regexp(item.right(item.length() - 7));
int nb = iLine.count();
for (int i = 0; i < nb; ++i) {
if (regexp.indexIn(iLine.at(i)) > -1) {
currentIndex = i;
setpossible = true;
break;
}
}
} else if (item.startsWith(QLatin1String("LINEOFFSET:"))) {
currentIndex += SKGServices::stringToInt(item.right(item.length() - 11));
if (currentIndex >= 0 && currentIndex < iLine.count()) {
output = iLine.at(currentIndex);
}
} else if (item.startsWith(QLatin1String("SET:")) && setpossible) {
QString s = item.right(item.length() - 4);
if (s.contains(QLatin1String("%1"))) {
output = s.arg(output);
} else {
output = s;
}
}
}
return output;
}
SKGError SKGImportPluginPDF::importFile()
{
if (m_importer == nullptr) {
return SKGError(ERR_ABORT, i18nc("Error message", "Invalid parameters"));
}
SKGError err;
SKGTRACEINFUNCRC(2, err)
// Begin transaction
err = m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Import step", "Import %1 file", "PDF"), 2);
IFOK(err) {
// Open file
IFOK(err) {
// Extract text from PDF
QString file = m_importer->getLocalFileName();
QTemporaryFile txtFile;
txtFile.open();
QStringList args = QStringList() << file << txtFile.fileName();
QProcess p;
p.start(QStringLiteral("pdftotext"), args);
if (!p.waitForFinished(1000 * 60 * 2) || p.exitCode() != 0) {
QString cmd = "pdftotext " % args.join(QStringLiteral(" "));
err.setReturnCode(ERR_FAIL).setMessage(i18nc("Error message", "The following command line failed with code %2:\n'%1'", cmd, p.exitCode()));
} else {
// Step 1 done
IFOKDO(err, m_importer->getDocument()->stepForward(1))
// Read the text file
QStringList lines;
QTextStream stream(&txtFile);
while (!stream.atEnd()) {
// Read line
lines.push_back(stream.readLine());
}
// Search extractors
QStringList listOfExtractors;
bool found = false;
QString a = QStringLiteral("skrooge/extractors");
const auto dirs = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, a, QStandardPaths::LocateDirectory);
for (const auto& dir : dirs) {
QDirIterator it(dir, QStringList() << QStringLiteral("*.extractor"));
while (it.hasNext() && !found) {
// Read extractor
QString fileName = it.next();
QString extractor = QFileInfo(fileName).baseName().toUpper();
listOfExtractors.push_back(extractor);
QHash< QString, QString > properties;
err = SKGServices::readPropertyFile(fileName, properties);
IFOK(err) {
// Check if this extractor is done for this file
QString payee = extract(lines, properties[QStringLiteral("payee")]);
if (!payee.isEmpty()) {
// Search the date
QString date = extract(lines, properties[QStringLiteral("date")]);
QString dateFormat = properties[QStringLiteral("dateformat")];
auto d = QDate::fromString(date, dateFormat);
if (!d.isValid()) {
d = QDate::fromString(date);
if (!d.isValid()) {
SKGTRACE << "WARNING: Impossible to parse the date [" << date << "] with [" << dateFormat << "]" << endl;
}
}
if (!dateFormat.contains(QStringLiteral("yyyy")) && d.year() < 2000) {
d = d.addYears(100);
}
// Search the amount
double amount = SKGServices::stringToDouble(extract(lines, properties[QStringLiteral("amount")]));
// Search the comment
QString comment = extract(lines, properties[QStringLiteral("comment")]);
// Search the number
QString number = extract(lines, properties[QStringLiteral("number")]);
// Search the mode
QString mode = extract(lines, properties[QStringLiteral("mode")]);
// Get account
SKGAccountObject account;
SKGOperationObject act;
m_importer->getDocument()->getObject(QStringLiteral("v_account_display"), QStringLiteral("t_close='N' AND t_type='C' ORDER BY i_NBOPERATIONS DESC LIMIT 1"), act);
if (act.exist()) {
account = act;
IFOKDO(err, m_importer->getDocument()->sendMessage(i18nc("An information message", "Using account '%1' for import", account.getName())))
} else {
IFOKDO(err, m_importer->getDefaultAccount(account))
}
if (d.isValid() && !qFuzzyCompare(1 + amount, 1.0)) {
// Get unit
SKGUnitObject unit;
IFOKDO(err, m_importer->getDefaultUnit(unit))
// Create operation
SKGOperationObject operation;
IFOKDO(err, account.addOperation(operation, true))
IFOKDO(err, operation.setDate(d))
IFOKDO(err, operation.setUnit(unit))
SKGPayeeObject payeeObj;
IFOKDO(err, SKGPayeeObject::createPayee(m_importer->getDocument(), payee, payeeObj))
IFOKDO(err, operation.setPayee(payeeObj))
IFOKDO(err, operation.setComment(comment))
IFOKDO(err, operation.setMode(mode))
IFOKDO(err, operation.setImportID(QStringLiteral("PDF-") % extractor % QStringLiteral("-") % number))
// This is normal. PDF inport is for only one operation, so no check if already imported
IFOKDO(err, operation.setAttribute(QStringLiteral("t_imported"), QStringLiteral("Y")))
IFOKDO(err, operation.save(false))
SKGSubOperationObject subop;
IFOKDO(err, operation.addSubOperation(subop))
IFOKDO(err, subop.setComment(comment))
IFOKDO(err, subop.setQuantity(-amount))
IFOKDO(err, subop.save(false, false))
// Add file
IFOKDO(err, err = operation.setProperty(i18n("Invoice"), file, file))
found = true;
}
}
}
}
}
if (!found) {
IFOKDO(err, m_importer->getDocument()->sendMessage(i18nc("An information message", "Invoice %1 has not been imported because it is not recognized (List of recognized extractors: %2).", file, listOfExtractors.join(',')), SKGDocument::Error))
}
// Step 2 done
IFOKDO(err, m_importer->getDocument()->stepForward(2))
}
}
}
SKGENDTRANSACTION(m_importer->getDocument(), err)
return err;
}
QString SKGImportPluginPDF::getMimeTypeFilter() const
{
return "*.pdf|" % i18nc("A file format", "PDF file (invoice)");
}
#include <skgimportpluginpdf.moc>
diff --git a/plugins/import/skrooge_import_pdf/skgimportpluginpdf.h b/plugins/import/skrooge_import_pdf/skgimportpluginpdf.h
index e67c77673..b8ae47482 100644
--- a/plugins/import/skrooge_import_pdf/skgimportpluginpdf.h
+++ b/plugins/import/skrooge_import_pdf/skgimportpluginpdf.h
@@ -1,71 +1,71 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGIMPORTPLUGINPDF_H
#define SKGIMPORTPLUGINPDF_H
/** @file
* This file is Skrooge plugin for PDF import / export.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgimportplugin.h"
/**
* This file is Skrooge plugin for PDF import / export.
*/
class SKGImportPluginPDF : public SKGImportPlugin
{
Q_OBJECT
Q_INTERFACES(SKGImportPlugin)
public:
/**
* Default constructor
* @param iImporter the parent importer
* @param iArg the arguments
*/
explicit SKGImportPluginPDF(QObject* iImporter, const QVariantList& iArg);
/**
* Default Destructor
*/
~SKGImportPluginPDF() override;
/**
* To know if import is possible with this plugin
*/
bool isImportPossible() override;
/**
* Import a file
* @return an object managing the error.
* @see SKGError
*/
SKGError importFile() override;
/**
* Return the mime type filter
* @return the mime type filter. Example: "*.csv|CSV file"
*/
QString getMimeTypeFilter() const override;
private:
Q_DISABLE_COPY(SKGImportPluginPDF)
QString extract(const QStringList& iLine, const QString& iSyntax);
};
#endif // SKGIMPORTPLUGINPDF_H
diff --git a/plugins/import/skrooge_import_qif/CMakeLists.txt b/plugins/import/skrooge_import_qif/CMakeLists.txt
index b6643e325..d22b97b97 100644
--- a/plugins/import/skrooge_import_qif/CMakeLists.txt
+++ b/plugins/import/skrooge_import_qif/CMakeLists.txt
@@ -1,33 +1,33 @@
#***************************************************************************
#* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
#* *
#* 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 <http://www.gnu.org/licenses/> *
+#* along with this program. If not, see <https://www.gnu.org/licenses/> *
#***************************************************************************
MESSAGE( STATUS "..:: CMAKE PLUGIN_IMPORT_QIF ::..")
PROJECT(plugin_import_qif)
LINK_DIRECTORIES (${LIBRARY_OUTPUT_PATH})
SET(skrooge_import_qif_SRCS
skgimportpluginqif.cpp
)
ADD_LIBRARY(skrooge_import_qif MODULE ${skrooge_import_qif_SRCS})
TARGET_LINK_LIBRARIES(skrooge_import_qif KF5::Parts skgbasemodeler skgbasegui skgbankmodeler skgbankgui)
########### install files ###############
INSTALL(TARGETS skrooge_import_qif DESTINATION ${KDE_INSTALL_QTPLUGINDIR})
INSTALL(FILES ${PROJECT_SOURCE_DIR}/org.kde.skrooge-import-qif.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR})
diff --git a/plugins/import/skrooge_import_qif/org.kde.skrooge-import-qif.desktop b/plugins/import/skrooge_import_qif/org.kde.skrooge-import-qif.desktop
index f938a6bdb..b11b3ea37 100644
--- a/plugins/import/skrooge_import_qif/org.kde.skrooge-import-qif.desktop
+++ b/plugins/import/skrooge_import_qif/org.kde.skrooge-import-qif.desktop
@@ -1,74 +1,74 @@
[Desktop Entry]
Name=Skrooge import QIF plugin
Name[bs]=Skrooge dodatak za QIF uvoz
Name[ca]=Connector d'importació de QIF de l'Skrooge
Name[ca@valencia]=Connector d'importació de QIF de l'Skrooge
Name[cs]=Modul Skrooge pro import QIF
Name[da]=Plugin til import af QIF til Skrooge
Name[de]=Skrooge-QIF-Importmodul
Name[el]=Skrooge import QIF plugin
Name[en_GB]=Skrooge import QIF plugin
Name[es]=Complemento de Skrooge para la importación de QIF
Name[et]=Skrooge QIF impordi plugin
Name[fi]=Skroogen QIF-tuontiliitännäinen
-Name[fr]=Module externe de Skrooge pour l'importation « QIF »
+Name[fr]=Module externe de Skrooge pour l'importation « QIF »
Name[gl]=Complemento de importación de QIF a Skrooge
Name[hu]=Skrooge QIF importáló bővítmény
Name[it]=Estensione di Skrooge per l'importazione QIF
Name[lt]=Skrooge QIF importavimo papildinys
Name[nb]=Skrooge-modul for QIF-import
Name[nl]=Plugin van Skrooge voor importeren van QIF
Name[pl]=Wtyczka importu QIF dla Skrooge
Name[pt]='Plugin' de importação de QIF para o Skrooge
Name[pt_BR]=Plugin de importação de QIF para o Skrooge
Name[ru]=Модуль импорта файлов QIF
Name[sk]=Skrooge plugin QIF import
Name[sv]=Skrooge QIF-importinsticksprogram
Name[tr]=Skrooge QIF içe aktarma eklentisi
Name[uk]=Додаток імпортування QIF до Skrooge
Name[x-test]=xxSkrooge import QIF pluginxx
Name[zh_TW]=Skrooge 匯入 QIF 外掛程式
Comment=A Skrooge plugin to import QIF files
Comment[bs]=Skrooge dodatak za uvoz QIF datoteka
Comment[ca]=Un connector de l'Skrooge per importar fitxers QIF
Comment[ca@valencia]=Un connector de l'Skrooge per importar fitxers QIF
Comment[cs]=Modul Skrooge pro import souborů QIF
Comment[da]=Et Skrooge-plugin til at importere QIF-filer
Comment[de]=Ein Skrooge-Modul zum Import von QIF-Dateien
Comment[el]=Ένα πρόσθετο του Skrooge για την εισαγωγή αρχείων QIF
Comment[en_GB]=A Skrooge plugin to import QIF files
Comment[es]=Complemento de Skrooge para importar archivos QIF
Comment[et]=Skrooge plugin QIF-failide importimiseks
Comment[fi]=Skroogen QIF-tiedostojen tuontiliitännäinen
-Comment[fr]=Un module externe de Skrooge pour l'importation de fichiers « QIF »
+Comment[fr]=Un module externe de Skrooge pour l'importation de fichiers « QIF »
Comment[gl]=Un complemento de Skrooge para importar ficheiros QIF.
Comment[hu]=Egy Skrooge bővítmény QIF fájlok importálásához
Comment[it]=Un'estensione di Skrooge per importare i file QIF
Comment[lt]=Skrooge QIF failų importavimo papildinys
Comment[nb]=En Skrooge-modul for å importere QIF-filer
Comment[nl]=Een Skrooge-plugin voor het importeren van QIF-bestanden
Comment[pl]=Wtyczka Skrooge do importu plików QIF
Comment[pt]=Um 'plugin' do Skrooge para importar ficheiros QIF
Comment[pt_BR]=Um plugin do Skrooge para importar arquivos QIF
Comment[ru]=Модуль импорта файлов QIF
Comment[sk]=Skrooge plugin na import QIF súborov
Comment[sv]=Ett insticksprogram till Skrooge för att importera QIF-filer
Comment[tr]=QIF dosyalarını içe aktarmak için Skrooge eklentisi
Comment[uk]=Додаток до Skrooge для імпортування даних з файлів QIF
Comment[x-test]=xxA Skrooge plugin to import QIF filesxx
Comment[zh_TW]=Skrooge 匯入 QIF 檔用的外掛程式
Encoding=UTF-8
Icon=skrooge
Type=Service
X-KDE-ServiceTypes=SKG IMPORT/Plugin
X-KDE-Library=skrooge_import_qif
X-Krunner-ID=Skrooge import QIF plugin
X-KDE-PluginInfo-Author=Stephane MANKOWSKI,miraks
X-KDE-PluginInfo-Email=stephane@mankowski.fr
X-KDE-PluginInfo-Name=skrooge_import_qif
X-KDE-PluginInfo-Version=1.0
-X-KDE-PluginInfo-Website=http://skrooge.org/
+X-KDE-PluginInfo-Website=https://skrooge.org/
X-KDE-PluginInfo-Category=Plugins
X-KDE-PluginInfo-Depends=
X-KDE-PluginInfo-License=GPL
X-KDE-PluginInfo-EnabledByDefault=true
diff --git a/plugins/import/skrooge_import_qif/skgimportpluginqif.cpp b/plugins/import/skrooge_import_qif/skgimportpluginqif.cpp
index 76c11e490..36e48ab21 100644
--- a/plugins/import/skrooge_import_qif/skgimportpluginqif.cpp
+++ b/plugins/import/skrooge_import_qif/skgimportpluginqif.cpp
@@ -1,1258 +1,1258 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is Skrooge plugin for QIF import / export.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgimportpluginqif.h"
#include <klocalizedstring.h>
#include <kpluginfactory.h>
#include <qcryptographichash.h>
#include <qfile.h>
#include <qsavefile.h>
#include "skgbankincludes.h"
#include "skgimportexportmanager.h"
#include "skgservices.h"
#include "skgtraces.h"
/**
* Opening balance string
*/
#define OPENINGBALANCE QStringLiteral("Opening Balance")
/**
* This plugin factory.
*/
K_PLUGIN_FACTORY(SKGImportPluginQifFactory, registerPlugin<SKGImportPluginQif>();)
SKGImportPluginQif::SKGImportPluginQif(QObject* iImporter, const QVariantList& iArg)
: SKGImportPlugin(iImporter)
{
SKGTRACEINFUNC(10)
Q_UNUSED(iArg)
m_importParameters[QStringLiteral("date_format")] = QString();
m_exportParameters[QStringLiteral("uuid_of_selected_accounts_or_operations")] = QString();
}
SKGImportPluginQif::~SKGImportPluginQif()
= default;
bool SKGImportPluginQif::isImportPossible()
{
SKGTRACEINFUNC(10)
return isExportPossible();
}
SKGError SKGImportPluginQif::importFile()
{
if (m_importer == nullptr) {
return SKGError(ERR_ABORT, i18nc("Error message", "Invalid parameters"));
}
SKGError err;
SKGTRACEINFUNCRC(2, err)
// Info for QIF format:
// http://mb-net.net/Debian/src/gnucash/gnucash-2.2.6/src/import-export/qif-import/file-format.txt
// http://web.intuit.com/support/quicken/docs/d_qif.html
// Begin transaction
err = m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Import step", "Import %1 file", "QIF"), 3);
IFOK(err) {
// Create account if needed
QDateTime now = QDateTime::currentDateTime();
QString postFix = SKGServices::dateToSqlString(now);
// Step 1 done
IFOKDO(err, m_importer->getDocument()->stepForward(1))
// Open file
QFile file(m_importer->getLocalFileName());
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
err.setReturnCode(ERR_INVALIDARG).setMessage(i18nc("Error message", "Open file '%1' failed", m_importer->getFileName().toDisplayString()));
} else {
QTextStream stream(&file);
if (!m_importer->getCodec().isEmpty()) {
stream.setCodec(m_importer->getCodec().toLatin1().constData());
}
// load file in memory
QStringList lines;
QStringList dates;
bool inWrongSection = false;
bool inPriceSection = false;
while (!stream.atEnd()) {
// Read line
// Check line if line is empty or is a commented
QString line = stream.readLine().trimmed().toUtf8();
if (!line.isEmpty() && line[0] != '#') {
lines.push_back(line);
// Manage !Account section
if (line.startsWith(QLatin1String("!"))) {
inWrongSection = false;
inPriceSection = false;
}
if (QString::compare(line, QStringLiteral("!account"), Qt::CaseInsensitive) == 0 ||
QString::compare(line, QStringLiteral("!type:cat"), Qt::CaseInsensitive) == 0 ||
QString::compare(line, QStringLiteral("!type:tag"), Qt::CaseInsensitive) == 0 ||
QString::compare(line, QStringLiteral("!type:class"), Qt::CaseInsensitive) == 0) {
inWrongSection = true;
} else if (QString::compare(line, QStringLiteral("!type:prices"), Qt::CaseInsensitive) == 0) {
inPriceSection = true;
}
// We try to find automatically the date format
if (!inWrongSection && line[0] == 'D') {
dates.push_back(line.right(line.length() - 1));
} else if (inPriceSection) {
QStringList vals = SKGServices::splitCSVLine(line, ',');
if (vals.count() == 3) {
dates.push_back(vals.at(2));
}
}
}
}
// close file
file.close();
// Select dateformat
QString dateFormat = m_importParameters.value(QStringLiteral("date_format"));
if (dateFormat.isEmpty()) {
dateFormat = SKGServices::getDateFormat(dates); // Automatic detection
}
if (dateFormat.isEmpty()) {
err.setReturnCode(ERR_FAIL).setMessage(i18nc("Error message", "Date format not supported"));
}
IFOKDO(err, m_importer->getDocument()->sendMessage(i18nc("An information message", "Import of '%1' with code '%2' and date format '%3'", m_importer->getFileName().toDisplayString(), m_importer->getCodec(), dateFormat)))
// Step 2 done
IFOKDO(err, m_importer->getDocument()->stepForward(2))
// Treat all lines
IFOK(err) {
SKGAccountObject* account = nullptr;
SKGOperationObject currentOperation;
SKGOperationObject payement;
SKGPayeeObject currentPayee;
SKGTrackerObject currentTracker;
SKGUnitObject currentUnit;
SKGSubOperationObject currentSubOperation;
QDate currentOperationDate;
QString lastTransferAccount;
QList<QString> transferAccount;
QList<double> transferQuantity;
bool addNextAmountToTransferQuantity = false;
QString stringForHash;
QString currentUnitForInvestment;
QChar inSection = 'B';
bool currentOperationInitialized = false;
bool latestSubCatMustBeRemoved = false;
bool investmentAccount = false;
bool div = false;
bool automaticAccount = true;
int quantityFactor = 1;
double currentUnitPrice = 1;
double checkOperationAmount = 0;
double checkSuboperationsAmount = 0;
bool openingbalancecreated = false;
int nb = lines.size();
err = m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Import step", "Import operations"), nb);
for (int i = 0; !err && i < nb; ++i) {
QString line = lines.at(i);
QString val;
QChar op = line[0];
if (line.length() > 1) {
val = line.right(line.length() - 1).trimmed();
}
// Manage !Account section
if (QString::compare(line, QStringLiteral("!type:bank"), Qt::CaseInsensitive) == 0 ||
QString::compare(line, QStringLiteral("!type:cash"), Qt::CaseInsensitive) == 0 ||
QString::compare(line, QStringLiteral("!type:ccard"), Qt::CaseInsensitive) == 0 ||
QString::compare(line, QStringLiteral("!type:oth a"), Qt::CaseInsensitive) == 0 ||
QString::compare(line, QStringLiteral("!type:oth l"), Qt::CaseInsensitive) == 0 ||
QString::compare(line, QStringLiteral("!type:invst"), Qt::CaseInsensitive) == 0) {
inSection = 'B';
openingbalancecreated = false;
investmentAccount = (QString::compare(val, QStringLiteral("type:invst"), Qt::CaseInsensitive) == 0);
// Set type of account
if (account == nullptr) {
SKGAccountObject defAccount;
err = m_importer->getDefaultAccount(defAccount);
IFOKDO(err, defAccount.addOperation(currentOperation, true))
IFOK(err) account = new SKGAccountObject(defAccount);
}
if (!err && (account != nullptr)) {
err = account->setType(QString::compare(line, QStringLiteral("!type:bank"), Qt::CaseInsensitive) == 0 ? SKGAccountObject::CURRENT :
(QString::compare(line, QStringLiteral("!type:ccard"), Qt::CaseInsensitive) == 0 ? SKGAccountObject::CREDITCARD :
(QString::compare(line, QStringLiteral("!type:invst"), Qt::CaseInsensitive) == 0 ? SKGAccountObject::INVESTMENT :
(QString::compare(line, QStringLiteral("!type:oth a"), Qt::CaseInsensitive) == 0 ? SKGAccountObject::ASSETS : SKGAccountObject::OTHER))));
IFOKDO(err, account->save())
}
} else if (QString::compare(line, QStringLiteral("!account"), Qt::CaseInsensitive) == 0) {
inSection = 'A';
openingbalancecreated = false;
automaticAccount = false;
} else if (QString::compare(line, QStringLiteral("!type:cat"), Qt::CaseInsensitive) == 0) {
inSection = 'C';
openingbalancecreated = false;
IFOKDO(err, m_importer->getDocument()->sendMessage(i18nc("An information message", "Categories found and imported")))
} else if (QString::compare(line, QStringLiteral("!type:prices"), Qt::CaseInsensitive) == 0) {
inSection = 'U';
openingbalancecreated = false;
IFOKDO(err, m_importer->getDocument()->sendMessage(i18nc("An information message", "Units prices found and imported")))
} else if (QString::compare(line, QStringLiteral("!type:security"), Qt::CaseInsensitive) == 0) {
inSection = 'S';
IFOKDO(err, m_importer->getDocument()->sendMessage(i18nc("An information message", "Units found and imported")))
} else if (QString::compare(line, QStringLiteral("!type:tag"), Qt::CaseInsensitive) == 0) {
inSection = 'T';
IFOKDO(err, m_importer->getDocument()->sendMessage(i18nc("An information message", "Trackers found and imported")))
} else if (line.at(0) == '!') {
inSection = '?';
openingbalancecreated = false;
} else if (inSection == 'U') {
// Unit value creation
openingbalancecreated = false;
QStringList vals = SKGServices::splitCSVLine(line, ',');
if (vals.count() == 3 && !vals.at(0).isEmpty()) {
err = m_importer->getDocument()->addOrModifyUnitValue(vals.at(0), SKGServices::stringToTime(SKGServices::dateToSqlString(vals.at(2), dateFormat)).date(), SKGServices::stringToDouble(vals.at(1)));
}
} else if (inSection == 'T') {
// Tracker creation
if (op == 'N') {
IFOKDO(err, SKGTrackerObject::createTracker(m_importer->getDocument(), val, currentTracker))
} else if (op == 'D') {
IFOKDO(err, currentTracker.setComment(val))
IFOKDO(err, currentTracker.save())
}
} else if (inSection == 'S') {
// Unit creation
if (op == 'N') {
currentUnit = SKGUnitObject(m_importer->getDocument());
IFOKDO(err, currentUnit.setName(val))
IFOKDO(err, currentUnit.setSymbol(val))
IFOKDO(err, currentUnit.setType(SKGUnitObject::CURRENCY))
IFOKDO(err, currentUnit.setNumberDecimal(2))
IFOKDO(err, currentUnit.save())
} else if (op == 'S') {
IFOKDO(err, currentUnit.setSymbol(val))
IFOKDO(err, currentUnit.save())
} else if (op == 'T') {
if (QString::compare(val, QStringLiteral("stock"), Qt::CaseInsensitive) == 0) {
IFOKDO(err, currentUnit.setType(SKGUnitObject::SHARE))
IFOKDO(err, currentUnit.setNumberDecimal(4))
IFOKDO(err, currentUnit.save())
}
}
} else if (inSection == 'C') {
// Category creation
openingbalancecreated = false;
if (op == 'N') {
SKGCategoryObject Category;
val.replace('/', OBJECTSEPARATOR);
val.replace(':', OBJECTSEPARATOR);
err = SKGCategoryObject::createPathCategory(m_importer->getDocument(), val, Category);
}
} else if (inSection == 'A') {
// Account creation
openingbalancecreated = false;
if (op == 'N') {
// Check if the account already exist
SKGAccountObject account2;
err = SKGNamedObject::getObjectByName(m_importer->getDocument(), QStringLiteral("account"), val, account2);
IFKO(err) {
// Create account
SKGBankObject bank(m_importer->getDocument());
err = bank.setName(i18nc("Noun", "Bank for import %1", postFix));
if (!err && bank.load().isFailed()) {
err = bank.save(false);
}
IFOKDO(err, bank.addAccount(account2))
IFOKDO(err, account2.setName(val))
if (!err && account2.load().isFailed()) {
err = account2.save(false); // Save only
}
}
IFOK(err) {
delete account;
account = new SKGAccountObject(account2);
}
} else if (op == 'D') {
if (account != nullptr) {
err = account->setNumber(val);
}
} else if (op == 'T') {
if (account != nullptr) {
err = account->setType(val == QStringLiteral("Bank") ? SKGAccountObject::CURRENT : (val == QStringLiteral("CCard") ? SKGAccountObject::CREDITCARD : (val == QStringLiteral("Invst") ? SKGAccountObject::INVESTMENT : (val == QStringLiteral("Oth A") ? SKGAccountObject::ASSETS : SKGAccountObject::OTHER))));
}
} else if (op == '^') {
// ^ End of entry
// save
if (account != nullptr) {
err = account->save();
}
}
} else if (inSection == 'B') {
// Operation creation
/*
>>>> Items for Non-Investment Accounts <<<<
DONE D Date
DONE T Amount
U Transaction amount (higher possible value than T)
DONE C Cleared status
DONE N Number (check or reference number)
DONE P Payee/description
DONE M Memo
DONE A Address (up to 5 lines; 6th line is an optional message)
DONE L Category (category/class or transfer/class)
DONE S Category in split (category/class or transfer/class)
DONE E Memo in split
DONE $ Dollar amount of split
% Percentage of split if percentages are used
F Reimbursable business expense flag
X Small Business extensions
DONE ^ End of entry
>>>> Items for Investment Accounts <<<<
DONE D Date
N Action
DONE Y Security
DONE I Price
DONE Q Quantity (number of shares or split ratio)
DONE T Transaction amount
DONE C Cleared status
P Text in the first line for transfers and reminders
DONE M Memo
O Commission
L Account for the transfer
$ Amount transferred
^ End of entry
*/
stringForHash += line;
if (op == 'D') {
// D Date
/*
Dates in US QIF files are usually in the format MM/DD/YY, although
four-digit years are not uncommon. Dates sometimes occur without the
slash separator, or using other separators in place of the slash,
commonly '-' and '.'. US Quicken seems to be using the ' to indicate
post-2000 two-digit years (such as 01/01'00 for Jan 1 2000). Some
banks appear to be using a completely undifferentiated numeric QString
formateed YYYYMMDD in downloaded QIF files.
*/
// Operation creation
SKGUnitObject unit;
IFOK(err) {
if (account != nullptr) {
err = account->addOperation(currentOperation, true);
if (!openingbalancecreated) {
double initBalance;
account->getInitialBalance(initBalance, unit);
}
} else {
SKGAccountObject defAccount;
err = m_importer->getDefaultAccount(defAccount);
IFOKDO(err, defAccount.addOperation(currentOperation, true))
if (!openingbalancecreated) {
double initBalance;
defAccount.getInitialBalance(initBalance, unit);
}
}
currentOperationInitialized = true;
}
// Set date
currentOperationDate = SKGServices::stringToTime(SKGServices::dateToSqlString(val, dateFormat)).date();
IFOKDO(err, currentOperation.setDate(currentOperationDate))
// Set unit
IFOK(err) {
// Create unit if needed
// If an initial balance is existing for the account then we use the unit else we look for the most appropriate unit
if (!unit.exist()) {
err = m_importer->getDefaultUnit(unit, &currentOperationDate);
}
IFOKDO(err, currentOperation.setUnit(unit))
}
IFOK(err) currentOperation.save();
// Create suboperation
IFOKDO(err, currentOperation.addSubOperation(currentSubOperation))
} else if (op == 'Y') {
// Y Security
if (!div) {
currentUnitForInvestment = val;
SKGUnitObject unit(m_importer->getDocument());
if (currentUnitForInvestment.isEmpty()) {
IFOKDO(err, err = m_importer->getDefaultUnit(unit))
} else {
IFOKDO(err, unit.setName(currentUnitForInvestment))
IFOKDO(err, unit.setSymbol(currentUnitForInvestment))
if (unit.load().isFailed()) {
IFOKDO(err, unit.setType(investmentAccount ? SKGUnitObject::SHARE : SKGUnitObject::CURRENCY))
IFOKDO(err, unit.save(false))
}
}
IFOKDO(err, currentOperation.setUnit(unit))
} else {
// For dividend, if comment is empty, we set the security in comment
if (currentOperation.getComment().isEmpty()) {
err = currentOperation.setComment(val);
}
}
} else if (op == 'O') {
// O Commission
// Get previous quantity
double quantity = SKGServices::stringToDouble(val);
SKGObjectBase::SKGListSKGObjectBase subops;
payement.getSubOperations(subops);
if (!subops.isEmpty()) {
SKGSubOperationObject subpayement(subops.at(0));
err = subpayement.setQuantity(subpayement.getQuantity() + quantity);
IFOKDO(err, subpayement.save())
}
SKGSubOperationObject subcommission;
if (!payement.exist()) {
// We have to create a new operation
if (account != nullptr) {
err = account->addOperation(payement, true);
} else {
SKGAccountObject defAccount;
err = m_importer->getDefaultAccount(defAccount);
IFOKDO(err, defAccount.addOperation(payement, true))
}
IFOKDO(err, payement.setDate(currentOperationDate))
IFOK(err) {
// If an initial balance is existing for the account then we use the unit else we look for the most appropriate unit
SKGUnitObject unit;
if ((account != nullptr) && !openingbalancecreated) {
double initBalance;
account->getInitialBalance(initBalance, unit);
}
if (!unit.exist()) {
err = m_importer->getDefaultUnit(unit, &currentOperationDate);
}
IFOKDO(err, payement.setUnit(unit))
}
IFOKDO(err, payement.save())
}
IFOKDO(err, payement.addSubOperation(subcommission))
IFOKDO(err, subcommission.setQuantity(-quantity))
IFOKDO(err, subcommission.save(false, false))
} else if (op == 'I') {
// I Price
currentUnitPrice = SKGServices::stringToDouble(val);
if ((currentUnitPrice != 0.0) && !currentUnitForInvestment.isEmpty()) {
err = m_importer->getDocument()->addOrModifyUnitValue(currentUnitForInvestment, currentOperationDate, currentUnitPrice);
}
} else if (op == 'N') {
if (investmentAccount) {
// N Action
/*
QIF N Line Notes
============ =====
Aktab Same as ShrsOut.
AktSplit Same as StkSplit.
Aktzu Same as ShrsIn.
Buy Buy shares.
BuyX Buy shares. Used with an L line.
Cash Miscellaneous cash transaction. Used with an L line.
CGMid Mid-term capital gains.
CGMidX Mid-term capital gains. For use with an L line.
CGLong Long-term capital gains.
CGLongX Long-term capital gains. For use with an L line.
CGShort Short-term capital gains.
CGShortX Short-term capital gains. For use with an L line.
ContribX Same as XIn. Used for tax-advantaged accounts.
CvrShrt Buy shares to cover a short sale.
CvrShrtX Buy shares to cover a short sale. Used with an L line.
Div Dividend received.
DivX Dividend received. For use with an L line.
Errinerg Same as Reminder.
Exercise Exercise an option.
ExercisX Exercise an option. For use with an L line.
Expire Mark an option as expired. (Uses D, N, Y & M lines)
Grant Receive a grant of stock options.
Int Same as IntInc.
IntX Same as IntIncX.
IntInc Interest received.
IntIncX Interest received. For use with an L line.
K.gewsp Same as CGShort. (German)
K.gewspX Same as CGShortX. (German)2307068
Kapgew Same as CGLong. Kapitalgewinnsteuer.(German)
KapgewX Same as CGLongX. Kapitalgewinnsteuer. (German)
Kauf Same as Buy. (German)
KaufX Same as BuyX. (German)
MargInt Margin interest paid.
MargIntX Margin interest paid. For use with an L line.
MiscExp Miscellaneous expense.
MiscExpX Miscellaneous expense. For use with an L line.
MiscInc Miscellaneous income.
MiscIncX Miscellaneous income. For use with an L line.
ReinvDiv Reinvested dividend.
ReinvInt Reinvested interest.
ReinvLG Reinvested long-term capital gains.
Reinvkur Same as ReinvLG.
Reinvksp Same as ReinvSh.
ReinvMd Reinvested mid-term capital gains.
ReinvSG Same as ReinvSh.
ReinvSh Reinvested short-term capital gains.
Reinvzin Same as ReinvDiv.
Reminder Reminder. (Uses D, N, C & M lines)
RtrnCap Return of capital.
RtrnCapX Return of capital. For use with an L line.
Sell Sell shares.
SellX Sell shares. For use with an L line.
ShtSell Short sale.
ShrsIn Deposit shares.
ShrsOut Withdraw shares.
StkSplit Share split.
Verkauf Same as Sell. (German)
VerkaufX Same as SellX. (German)
Vest Mark options as vested. (Uses N, Y, Q, C & M lines)
WithDrwX Same as XOut. Used for tax-advantaged accounts.
XIn Transfer cash from another account.
XOut Transfer cash to another account.
*/
val = val.toLower();
if (val.contains(QStringLiteral("div")) && val != QStringLiteral("reinvdiv")) {
// TODO(Stephane MANKOWSKI) err=currentOperation.setProperty ( "SKG_OP_ORIGINAL_AMOUNT", "" );
div = true;
} else if (val.contains(QStringLiteral("sell")) ||
val.contains(QStringLiteral("verkauf")) ||
val.contains(QStringLiteral("miscexp")) ||
val.contains(QStringLiteral("shrsout"))
) {
quantityFactor = -1;
}
// Correction 214851 vvvv
// err=currentOperation.setComment ( val );
// if ( !err ) err=currentOperation.setMode ( i18nc ( "Noun, the title of an item","Title" ) );
// Correction 214851 ^^^^
} else {
// N Num (check or reference number)
// Set number
bool ok;
int number = val.toInt(&ok);
if (ok && number != 0) {
err = currentOperation.setNumber(val);
} else {
err = currentOperation.setMode(val);
}
}
} else if (op == 'Q') {
// Q Quantity (number of shares or split ratio)
// Set value
if (!val.isEmpty()) {
double previousQuantity = currentSubOperation.getQuantity();
if (previousQuantity != 0.0) {
// We have to create a new operation
if (account != nullptr) {
err = account->addOperation(payement, true);
} else {
SKGAccountObject defAccount;
err = m_importer->getDefaultAccount(defAccount);
IFOKDO(err, defAccount.addOperation(payement, true))
}
IFOKDO(err, payement.setDate(currentOperationDate))
IFOK(err) {
// Create unit if needed
// If an initial balance is existing for the account then we use the unit else we look for the most appropriate unit
SKGUnitObject unit;
if ((account != nullptr) && !openingbalancecreated) {
double initBalance;
account->getInitialBalance(initBalance, unit);
}
if (!unit.exist()) {
err = m_importer->getDefaultUnit(unit, &currentOperationDate);
}
IFOKDO(err, payement.setUnit(unit))
}
IFOKDO(err, payement.save())
IFOKDO(err, currentOperation.setGroupOperation(payement))
SKGSubOperationObject subpayement;
IFOKDO(err, payement.addSubOperation(subpayement))
IFOKDO(err, subpayement.setQuantity(-previousQuantity))
IFOKDO(err, subpayement.save())
}
IFOKDO(err, currentSubOperation.setQuantity(quantityFactor * SKGServices::stringToDouble(val)))
}
} else if (op == 'T') {
// T Amount
// Set value
checkOperationAmount = SKGServices::stringToDouble(val);
err = currentSubOperation.setQuantity(checkOperationAmount / currentUnitPrice);
if (!err && investmentAccount) {
err = currentOperation.setProperty(QStringLiteral("SKG_OP_ORIGINAL_AMOUNT"), val);
}
} else if (op == '$') {
// Dollar amount of split
// Set value
if (!investmentAccount) {
double vald = SKGServices::stringToDouble(val);
checkSuboperationsAmount += vald;
if (addNextAmountToTransferQuantity && !lastTransferAccount.isEmpty()) {
transferQuantity[transferAccount.count() - 1] += vald;
}
addNextAmountToTransferQuantity = false;
lastTransferAccount = QString();
err = currentSubOperation.setQuantity(vald);
// save
IFOKDO(err, currentSubOperation.save())
// Create suboperation
IFOKDO(err, currentOperation.addSubOperation(currentSubOperation))
latestSubCatMustBeRemoved = true;
}
} else if (op == 'P') {
// P Payee
// Set Payee
// Clean QIF coming from bankperfect
val.remove(QStringLiteral("[auto]"));
err = SKGPayeeObject::createPayee(m_importer->getDocument(), val, currentPayee);
IFOKDO(err, currentOperation.setPayee(currentPayee))
} else if (op == 'A') {
// A Address (up to 5 lines; 6th line is an optional message)
QString add = currentPayee.getAddress();
if (!add.isEmpty()) {
add += ' ';
}
add += val;
err = currentPayee.setAddress(add);
IFOKDO(err, currentPayee.save())
} else if (op == 'M') {
// M Memo
// Set Memo
err = currentOperation.setComment(val);
} else if (op == 'E') {
// E Memo in split
// Set Memo
err = currentSubOperation.setComment(val);
} else if (op == 'S' || op == 'L') {
// S Category in split (Category/Transfer/Class)
// L Category (Category/Subcategory/Transfer/Class)
// LCategory of transaction
// L[Transfer account]
// LCategory of transaction/Class of transaction
// L[Transfer account]/Class of transaction// Set Category
if (!val.isEmpty()) {
if (val[0] == '[') {
addNextAmountToTransferQuantity = true;
int pos = val.indexOf(']');
if (pos != -1) {
SKGPayeeObject payeeObj;
currentOperation.getPayee(payeeObj);
bool opening = (payeeObj.getName().compare(OPENINGBALANCE, Qt::CaseInsensitive) == 0);
// If the very first Bank transaction in the file has a payee of "Opening Balance", the L line contains the name of the account that the file describes. This is not a transfer
if (op == 'L' && automaticAccount && (account != nullptr) && opening) {
QString accountName = val.mid(1, pos - 1);
SKGAccountObject newAccount(m_importer->getDocument());
err = newAccount.setName(accountName);
IFOK(err) {
if (newAccount.exist()) {
// Oups, the real account is existing and it is another one
err = newAccount.load();
// We move the operation in the right account
IFOKDO(err, currentOperation.setParentAccount(newAccount))
IFOKDO(err, currentOperation.save())
// We delete the previous account if empty
IFOK(err) {
if (account->getNbOperation() == 0) {
err = account->remove();
}
delete account;
account = new SKGAccountObject(newAccount);
}
} else {
err = account->setName(accountName);
IFOKDO(err, account->save())
}
}
}
// if ( op=='L' && currentOperation.getPayee().compare ( "Opening Balance", Qt::CaseInsensitive ) !=0 && !investmentAccount)
if (!opening) {
lastTransferAccount = val.mid(1, pos - 1);
if ((account != nullptr) && lastTransferAccount == account->getName()) {
lastTransferAccount = QString();
}
if (!lastTransferAccount.isEmpty() &&
(transferAccount.count() == 0 ||
transferAccount.at(transferAccount.count() - 1) != lastTransferAccount ||
transferQuantity.at(transferQuantity.count() - 1) != 0.0
)
) {
transferAccount.append(lastTransferAccount);
transferQuantity.append(0.0);
}
}
val = val.mid(pos + 2);
}
}
if (!err && !val.isEmpty()) {
auto cat_tag = SKGServices::splitCSVLine(val, '/', false);
val = cat_tag.at(0);
SKGCategoryObject Category;
val.replace('/', OBJECTSEPARATOR);
val.replace(':', OBJECTSEPARATOR);
val.replace(',', OBJECTSEPARATOR);
val.replace(';', OBJECTSEPARATOR);
err = SKGCategoryObject::createPathCategory(m_importer->getDocument(), val, Category);
IFOKDO(err, currentSubOperation.setCategory(Category))
if (!err && cat_tag.count() > 1) {
SKGTrackerObject tracker;
err = SKGTrackerObject::createTracker(m_importer->getDocument(), cat_tag.at(1), tracker);
IFOKDO(err, currentSubOperation.setTracker(tracker))
}
}
}
} else if (op == 'C') {
// C Cleared status
// Set status
err = currentOperation.setStatus((val == QStringLiteral("C") || val == QStringLiteral("*") ? SKGOperationObject::POINTED : (val == QStringLiteral("R") || val == QStringLiteral("X") ? SKGOperationObject::CHECKED : SKGOperationObject::NONE)));
} else if (op == '^') {
// ^ End of entry
// save
if (currentOperationInitialized) {
QByteArray hash = QCryptographicHash::hash(stringForHash.toUtf8(), QCryptographicHash::Md5);
SKGPayeeObject payeeObj;
currentOperation.getPayee(payeeObj);
bool opening = (payeeObj.getName().compare(OPENINGBALANCE, Qt::CaseInsensitive) == 0);
if (!err && opening) {
// Specific values for initial balance
err = currentOperation.setStatus(SKGOperationObject::CHECKED);
IFOKDO(err, currentOperation.setAttribute(QStringLiteral("d_date"), QStringLiteral("0000-00-00")))
IFOKDO(err, currentSubOperation.setAttribute(QStringLiteral("d_date"), QStringLiteral("0000-00-00")))
openingbalancecreated = true;
}
IFOKDO(err, currentOperation.setImportID(hash.toHex()))
IFOKDO(err, currentOperation.save())
if (!latestSubCatMustBeRemoved && !err) {
err = currentSubOperation.save();
}
// Create transfers if needed
// Get origin op
SKGOperationObject opOrigin(m_importer->getDocument(), currentOperation.getID());
SKGAccountObject accountOrigin;
IFOKDO(err, opOrigin.getParentAccount(accountOrigin))
int nbTransfers = transferAccount.count();
for (int j = 0; !err && j < nbTransfers; ++j) {
bool merged = false;
double tq = transferQuantity.at(j);
const QString& ta = transferAccount.at(j);
// Is the transfert operation already existing?
double qua = tq == 0.0 && addNextAmountToTransferQuantity ? SKGServices::stringToDouble(opOrigin.getAttribute(QStringLiteral("f_QUANTITY"))) : tq;
QString wc = "t_ACCOUNT='" % SKGServices::stringToSqlString(ta) %
"' AND t_TOACCOUNT='" % SKGServices::stringToSqlString(accountOrigin.getName()) %
"' AND ABS(f_QUANTITY-(" % SKGServices::doubleToString(-qua) % "))<0.0001"
" AND ABS(julianday(d_date) - julianday('" % SKGServices::dateToSqlString(QDateTime(opOrigin.getDate())) % "'))<1"
" ORDER BY ABS(julianday(d_date) - julianday('" % SKGServices::dateToSqlString(QDateTime(opOrigin.getDate())) % "')) ASC";
SKGObjectBase::SKGListSKGObjectBase obs;
m_importer->getDocument()->getObjects(QStringLiteral("v_operation_display"), wc, obs);
if (!obs.isEmpty()) {
// We have to merge them and we do not need to create the transfer
SKGOperationObject firstOne(obs.at(0));
// Remove all operation attached to this transfer
SKGObjectBase::SKGListSKGObjectBase list;
IFOKDO(err, firstOne.getGroupedOperations(list))
for (const auto& o : qAsConst(list)) {
SKGOperationObject op2(o);
if (op2 != firstOne) {
IFOKDO(err, op2.setStatus(SKGOperationObject::NONE))
IFOKDO(err, op2.remove(false, true))
}
}
// Attach myself
IFOKDO(err, currentOperation.setGroupOperation(firstOne))
IFOKDO(err, currentOperation.save())
merged = true;
} else {
// Is the operation already created as a transfer of an other one?
QString wc = "t_import_id='QIF TRANSFER-" % SKGServices::stringToSqlString(ta) % "' AND t_ACCOUNT='" % SKGServices::stringToSqlString(accountOrigin.getName()) %
"' AND (ABS(f_CURRENTAMOUNT-(" % SKGServices::doubleToString(opOrigin.getCurrentAmount()) % "))<0.0001 OR f_QUANTITY=" % SKGServices::doubleToString(qua) % ")"
" AND ABS(julianday(d_date) - julianday('" % SKGServices::dateToSqlString(QDateTime(opOrigin.getDate())) % "'))<1"
" ORDER BY ABS(julianday(d_date) - julianday('" % SKGServices::dateToSqlString(QDateTime(opOrigin.getDate())) % "')) ASC";
m_importer->getDocument()->getObjects(QStringLiteral("v_operation_display"), wc, obs);
if (!obs.isEmpty()) {
// We have to merge them and we do not need to create the transfer
SKGOperationObject firstOne(obs.at(0));
err = opOrigin.setStatus(SKGOperationObject::NONE); // To be sure we can delete it
IFOKDO(err, opOrigin.save())
IFOKDO(err, firstOne.mergeAttribute(opOrigin))
SKGObjectBase::SKGListSKGObjectBase list;
IFOKDO(err, currentOperation.getGroupedOperations(list))
for (const auto& o : qAsConst(list)) {
SKGOperationObject op2(o);
IFOKDO(err, op2.setStatus(SKGOperationObject::NONE))
IFOKDO(err, op2.remove(false, true))
}
merged = true;
}
}
if (!merged) {
// Create target account if needed
SKGAccountObject accountTransfer(m_importer->getDocument());
if (m_accountCache.contains(ta)) {
accountTransfer = m_accountCache[ta];
} else {
accountTransfer.setName(ta);
if (!accountTransfer.exist()) {
// The account is created in the same bank by default
SKGBankObject bankOrigin;
IFOKDO(err, accountOrigin.getBank(bankOrigin))
IFOKDO(err, accountTransfer.setBank(bankOrigin))
IFOKDO(err, accountTransfer.save(false, true))
} else {
err = accountTransfer.load();
}
m_accountCache[ta] = accountTransfer;
}
// Create operation
SKGUnitObject unit;
opOrigin.getUnit(unit);
SKGOperationObject opTransfer;
IFOKDO(err, accountTransfer.addOperation(opTransfer, true))
IFOKDO(err, opTransfer.setDate(opOrigin.getDate()))
IFOKDO(err, opTransfer.setComment(opOrigin.getComment()))
SKGPayeeObject payeeObj2;
opTransfer.getPayee(payeeObj2);
IFOKDO(err, opTransfer.setPayee(payeeObj2))
IFOKDO(err, opTransfer.setStatus(opOrigin.getStatus()))
IFOKDO(err, opTransfer.setUnit(unit))
IFOKDO(err, opTransfer.setImportID("QIF TRANSFER-" % accountOrigin.getName()))
IFOKDO(err, opTransfer.save()) // save needed before setGroupOperation
IFOKDO(err, opTransfer.setGroupOperation(opOrigin))
IFOKDO(err, opOrigin.load()) // Must be reload because of setGroupOperation modified it
IFOKDO(err, opTransfer.save())
SKGSubOperationObject subopTransfer;
IFOKDO(err, opTransfer.addSubOperation(subopTransfer))
IFOKDO(err, subopTransfer.setQuantity(-qua))
IFOKDO(err, subopTransfer.save())
}
}
}
// Check Sum($)=T for incident 214462
QString checkOperationAmountString = SKGServices::doubleToString(checkOperationAmount);
QString checkSuboperationsAmountString = SKGServices::doubleToString(checkSuboperationsAmount);
if (!err && checkOperationAmount != 0 && checkSuboperationsAmount != 0 && checkOperationAmountString != checkSuboperationsAmountString) {
SKGSubOperationObject suboprepair;
IFOKDO(err, currentOperation.addSubOperation(suboprepair))
IFOKDO(err, suboprepair.setQuantity(checkOperationAmount - checkSuboperationsAmount))
IFOKDO(err, suboprepair.setComment(i18nc("An information message", "Auto repaired operation")))
IFOKDO(err, suboprepair.save())
IFOKDO(err, m_importer->getDocument()->sendMessage(i18nc("An information message", "The total amount of the operation (%1) was different to the sum of the sub-operations (%2). The operation has been repaired.", checkOperationAmountString, checkSuboperationsAmountString), SKGDocument::Warning))
}
// Initialize variables
currentOperationInitialized = false;
latestSubCatMustBeRemoved = false;
currentUnitForInvestment = QString();
quantityFactor = 1;
currentUnitPrice = 1;
stringForHash = QString();
checkOperationAmount = 0;
checkSuboperationsAmount = 0;
lastTransferAccount = QString();
transferAccount.clear();
transferQuantity.clear();
payement = SKGOperationObject();
} else {
// A Address (up to five lines; the sixth line is an optional message)
}
}
if (!err && i % 500 == 0) {
err = m_importer->getDocument()->executeSqliteOrder(QStringLiteral("ANALYZE"));
}
IFOKDO(err, m_importer->getDocument()->stepForward(i + 1))
}
delete account;
account = nullptr;
SKGENDTRANSACTION(m_importer->getDocument(), err)
// Lines treated
IFOKDO(err, m_importer->getDocument()->stepForward(3))
}
}
}
SKGENDTRANSACTION(m_importer->getDocument(), err)
return err;
}
bool SKGImportPluginQif::isExportPossible()
{
SKGTRACEINFUNC(10)
return (m_importer == nullptr ? true : m_importer->getFileNameExtension() == QStringLiteral("QIF"));
}
SKGError SKGImportPluginQif::exportFile()
{
if (m_importer == nullptr) {
return SKGError(ERR_ABORT, i18nc("Error message", "Invalid parameters"));
}
SKGError err;
SKGTRACEINFUNCRC(2, err)
// Read parameters
auto listUUIDs = SKGServices::splitCSVLine(m_exportParameters.value(QStringLiteral("uuid_of_selected_accounts_or_operations")));
QStringList listOperationsToExport;
listOperationsToExport.reserve(listUUIDs.count());
QStringList listAccountsToExport;
listAccountsToExport.reserve(listUUIDs.count());
for (const auto& uuid : listUUIDs) {
if (uuid.endsWith(QLatin1String("-operation"))) {
listOperationsToExport.push_back(uuid);
} else if (uuid.endsWith(QLatin1String("-account"))) {
listAccountsToExport.push_back(uuid);
}
}
if ((listAccountsToExport.count() != 0) || (listOperationsToExport.count() != 0)) {
IFOKDO(err, m_importer->getDocument()->sendMessage(i18nc("An information message", "Only selected accounts and operations have been exported")))
}
// Open file
QSaveFile file(m_importer->getLocalFileName(false));
if (!file.open(QIODevice::WriteOnly)) {
err.setReturnCode(ERR_INVALIDARG).setMessage(i18nc("Error message", "Save file '%1' failed", m_importer->getFileName().toDisplayString()));
} else {
QTextStream stream(&file);
if (!m_importer->getCodec().isEmpty()) {
stream.setCodec(m_importer->getCodec().toLatin1().constData());
}
err = m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Export step", "Export %1 file", "QIF"), 3);
IFOK(err) {
// Export categories
SKGObjectBase::SKGListSKGObjectBase categories;
IFOKDO(err, m_importer->getDocument()->getObjects(QStringLiteral("v_category_display_tmp"), QStringLiteral("1=1 ORDER BY t_fullname, id"), categories))
int nbcat = categories.count();
if (!err && (nbcat != 0)) {
stream << "!Type:Cat\n";
err = m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Export step", "Export categories"), nbcat);
for (int i = 0; !err && i < nbcat; ++i) {
SKGCategoryObject cat(categories.at(i));
QString catName = cat.getFullName();
if (!catName.isEmpty()) {
stream << QStringLiteral("N") << catName.replace(OBJECTSEPARATOR, QStringLiteral(":")) << endl;
if (SKGServices::stringToDouble(cat.getAttribute(QStringLiteral("f_REALCURRENTAMOUNT"))) < 0) {
stream << "E" << endl;
} else {
stream << "I" << endl;
}
stream << "^" << endl;
}
IFOKDO(err, m_importer->getDocument()->stepForward(i + 1))
}
SKGENDTRANSACTION(m_importer->getDocument(), err)
}
IFOKDO(err, m_importer->getDocument()->stepForward(1))
SKGServices::SKGUnitInfo primaryUnit = m_importer->getDocument()->getPrimaryUnit();
// Get operations
QString currentAccountName;
SKGObjectBase::SKGListSKGObjectBase operations;
IFOKDO(err, m_importer->getDocument()->getObjects(QStringLiteral("v_operation_display_all"), QStringLiteral("t_template='N' ORDER BY t_ACCOUNT, d_date, id"), operations))
int nb = operations.count();
IFOK(err) {
err = m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Export step", "Export operations"), nb);
for (int i = 0; !err && i < nb; ++i) {
SKGOperationObject operation(operations.at(i));
SKGAccountObject a;
operation.getParentAccount(a);
if ((listOperationsToExport.isEmpty() || listOperationsToExport.contains(operation.getUniqueID())) &&
(listAccountsToExport.isEmpty() || listAccountsToExport.contains(a.getUniqueID()))) {
// Get account name
QString accountName = operation.getAttribute(QStringLiteral("t_ACCOUNT"));
// In the same account ?
if (accountName != currentAccountName) {
SKGAccountObject account(m_importer->getDocument());
account.setName(accountName);
account.load();
SKGBankObject bank;
account.getBank(bank);
// Write header
stream << "!Account\n";
stream << 'N' << accountName << endl;
QString type = (account.getType() == SKGAccountObject::CURRENT ? QStringLiteral("Bank") : (account.getType() == SKGAccountObject::CREDITCARD ? QStringLiteral("CCard") : (account.getType() == SKGAccountObject::INVESTMENT ? QStringLiteral("Invst") : (account.getType() == SKGAccountObject::ASSETS ? QStringLiteral("Oth A") : QStringLiteral("Cash")))));
stream << 'T' << type << endl;
QString number = bank.getNumber();
QString bnumber = account.getAgencyNumber();
QString cnumber = account.getNumber();
if (!bnumber.isEmpty()) {
if (!number.isEmpty()) {
number += '-';
}
number += bnumber;
}
if (!cnumber.isEmpty()) {
if (!number.isEmpty()) {
number += '-';
}
number += cnumber;
}
stream << 'D' << number << endl;
// stream << "/" Statement balance date
// stream << "$" Statement balance amount
stream << '^' << endl;
currentAccountName = accountName;
stream << "!Type:" << type << "\n";
}
// Write operation
/*
DONE D Date
DONE T Amount
N/A U Transaction amount (higher possible value than T)
DONE C Cleared status
DONE N Number (check or reference number)
DONE P Payee/description
DONE M Memo
N/A A Address (up to 5 lines; 6th line is an optional message)
DONE L Category (category/class or transfer/class)
DONE S Category in split (category/class or transfer/class)
DONE E Memo in split
DONE $ Dollar amount of split
N/A % Percentage of split if percentages are used
N/A F Reimbursable business expense flag
N/A X Small Business extensions
DONE Y Security
DONE I Price
DONE Q Quantity (number of shares or split ratio)
N/A O Commission
DONE ^ End of entry
*/
SKGUnitObject unit;
operation.getUnit(unit);
bool investment = false;
bool unitExported = false;
if (unit.getSymbol() != primaryUnit.Symbol && !primaryUnit.Symbol.isEmpty()) {
unitExported = true;
}
if (unit.getType() == SKGUnitObject::SHARE) {
unitExported = true;
investment = true;
}
QString date = SKGServices::dateToSqlString(QDateTime(operation.getDate()));
if (date.isEmpty()) {
// This is an opening balance
date = QStringLiteral("0000-00-00");
}
stream << 'D' << date << endl;
if (!unitExported) {
stream << 'T' << SKGServices::doubleToString(operation.getCurrentAmount()) << endl;
}
if (!investment) {
auto number = operation.getNumber();
if (!number.isEmpty()) {
stream << 'N' << operation.getNumber() << endl;
}
} else {
stream << 'N' << (operation.getCurrentAmount() > 0 ? "Buy" : "Sell") << endl;
}
if (unitExported) {
stream << 'Y' << unit.getSymbol() << endl;
}
SKGPayeeObject payeeObj;
operation.getPayee(payeeObj);
QString payee = payeeObj.getName();
QString address = payeeObj.getAddress();
if (date == QStringLiteral("0000-00-00")) {
payee = OPENINGBALANCE;
}
if (!payee.isEmpty()) {
stream << 'P' << payee << endl;
}
if (!address.isEmpty()) {
stream << 'A' << address << endl;
}
QString memo = operation.getMode() % " " % operation.getComment();
memo = memo.trimmed();
if (!memo.isEmpty()) {
stream << 'M' << memo << endl;
}
SKGOperationObject::OperationStatus status = operation.getStatus();
stream << 'C' << (status == SKGOperationObject::POINTED ? "C" : (status == SKGOperationObject::CHECKED ? "R" : "")) << endl;
// Get sub operations
SKGObjectBase::SKGListSKGObjectBase suboperations;
err = operation.getSubOperations(suboperations);
IFOK(err) {
int nbSubOps = suboperations.size();
QString category;
if (nbSubOps == 1) {
SKGSubOperationObject suboperation(suboperations.at(0));
// Dump quantity
if (unitExported) {
stream << 'Q' << SKGServices::doubleToString(qAbs(suboperation.getQuantity())) << endl;
stream << 'I' << SKGServices::doubleToString(qAbs(operation.getCurrentAmount() / suboperation.getQuantity())) << endl;
}
// Get category of this simple operation
SKGCategoryObject cat;
suboperation.getCategory(cat);
category = cat.getFullName().replace(OBJECTSEPARATOR, QStringLiteral(":"));
}
// Is it a transfer
SKGOperationObject transfer;
if (operation.isTransfer(transfer)) {
if (!category.isEmpty()) {
category.prepend('/');
}
SKGAccountObject transferAccount;
err = transfer.getParentAccount(transferAccount);
IFOK(err) category.prepend('[' % transferAccount.getName() % ']');
}
if (!category.isEmpty()) {
stream << 'L' << category << endl;
}
if (nbSubOps > 1) {
// Split operation
for (int k = 0; k < nbSubOps; ++k) {
SKGSubOperationObject suboperation(suboperations.at(k));
SKGCategoryObject cat;
suboperation.getCategory(cat);
QString category2 = cat.getFullName().replace(OBJECTSEPARATOR, QStringLiteral(":"));
if (!category2.isEmpty()) {
stream << 'S' << category2 << endl;
}
QString memo2 = suboperation.getComment();
memo2 = memo2.trimmed();
if (!memo2.isEmpty()) {
stream << 'E' << memo2 << endl;
}
stream << '$' << SKGServices::doubleToString(suboperation.getQuantity()) << endl;
}
}
}
stream << '^' << endl;
}
IFOKDO(err, m_importer->getDocument()->stepForward(i + 1))
}
SKGENDTRANSACTION(m_importer->getDocument(), err)
}
IFOKDO(err, m_importer->getDocument()->stepForward(2))
// Export prices
SKGObjectBase::SKGListSKGObjectBase unitvalues;
IFOKDO(err, m_importer->getDocument()->getObjects(QStringLiteral("v_unitvalue"), QStringLiteral("1=1 ORDER BY (select t_name from unit where v_unitvalue.rd_unit_id=unit.id), d_date"), unitvalues))
nb = unitvalues.count();
if (!err && (nb != 0)) {
stream << "!Type:Prices\n";
err = m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Export step", "Export units"), nb);
for (int i = 0; !err && i < nb; ++i) {
SKGUnitValueObject unitVal(unitvalues.at(i));
SKGUnitObject unit;
err = unitVal.getUnit(unit);
IFOK(err) {
QStringList vals;
QString v = unit.getSymbol();
if (v.isEmpty()) {
v = unit.getName();
}
vals.push_back(v);
vals.push_back(SKGServices::doubleToString(unitVal.getQuantity()));
vals.push_back(SKGServices::dateToSqlString(QDateTime(unitVal.getDate())));
stream << SKGServices::stringsToCsv(vals) << endl;
}
IFOKDO(err, m_importer->getDocument()->stepForward(i + 1))
}
stream << "^" << endl;
SKGENDTRANSACTION(m_importer->getDocument(), err)
}
IFOKDO(err, m_importer->getDocument()->stepForward(3))
SKGENDTRANSACTION(m_importer->getDocument(), err)
}
// Close file
file.commit();
}
return err;
}
QString SKGImportPluginQif::getMimeTypeFilter() const
{
return "*.qif|" % i18nc("A file format", "QIF file");
}
#include <skgimportpluginqif.moc>
diff --git a/plugins/import/skrooge_import_qif/skgimportpluginqif.h b/plugins/import/skrooge_import_qif/skgimportpluginqif.h
index 1bf262f95..7b549b722 100644
--- a/plugins/import/skrooge_import_qif/skgimportpluginqif.h
+++ b/plugins/import/skrooge_import_qif/skgimportpluginqif.h
@@ -1,86 +1,86 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGIMPORTPLUGINQIF_H
#define SKGIMPORTPLUGINQIF_H
/** @file
* This file is Skrooge plugin for QIF import / export.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgimportplugin.h"
/**
* This file is Skrooge plugin for QIF import / export.
*/
class SKGImportPluginQif : public SKGImportPlugin
{
Q_OBJECT
Q_INTERFACES(SKGImportPlugin)
public:
/**
* Default constructor
* @param iImporter the parent importer
* @param iArg arguments
*/
explicit SKGImportPluginQif(QObject* iImporter, const QVariantList& iArg);
/**
* Default Destructor
*/
~SKGImportPluginQif() override;
/**
* To know if import is possible with this plugin
*/
bool isImportPossible() override;
/**
* Import a file
* @return an object managing the error.
* @see SKGError
*/
SKGError importFile() override;
/**
* To know if export is possible with this plugin
* @return true or false
*/
bool isExportPossible() override;
/**
* Export a file
* @return an object managing the error.
* @see SKGError
*/
SKGError exportFile() override;
/**
* Return the mime type filter
* @return the mime type filter. Example: "*.csv|CSV file"
*/
QString getMimeTypeFilter() const override;
private:
Q_DISABLE_COPY(SKGImportPluginQif)
QMap<QString, SKGAccountObject> m_accountCache;
};
#endif // SKGIMPORTPLUGINQIF_H
diff --git a/plugins/import/skrooge_import_skg/CMakeLists.txt b/plugins/import/skrooge_import_skg/CMakeLists.txt
index 9457743cd..4ec63ca12 100644
--- a/plugins/import/skrooge_import_skg/CMakeLists.txt
+++ b/plugins/import/skrooge_import_skg/CMakeLists.txt
@@ -1,33 +1,33 @@
#***************************************************************************
#* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
#* *
#* 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 <http://www.gnu.org/licenses/> *
+#* along with this program. If not, see <https://www.gnu.org/licenses/> *
#***************************************************************************
MESSAGE( STATUS "..:: CMAKE PLUGIN_IMPORT_SKG ::..")
PROJECT(plugin_import_skg)
LINK_DIRECTORIES (${LIBRARY_OUTPUT_PATH})
SET(skrooge_import_skg_SRCS
skgimportpluginskg.cpp
)
ADD_LIBRARY(skrooge_import_skg MODULE ${skrooge_import_skg_SRCS})
TARGET_LINK_LIBRARIES(skrooge_import_skg KF5::Parts Qt5::Sql skgbasemodeler skgbasegui skgbankmodeler skgbankgui)
########### install files ###############
INSTALL(TARGETS skrooge_import_skg DESTINATION ${KDE_INSTALL_QTPLUGINDIR})
INSTALL(FILES ${PROJECT_SOURCE_DIR}/org.kde.skrooge-import-skg.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR})
diff --git a/plugins/import/skrooge_import_skg/org.kde.skrooge-import-skg.desktop b/plugins/import/skrooge_import_skg/org.kde.skrooge-import-skg.desktop
index 400e28775..bce0b0c57 100644
--- a/plugins/import/skrooge_import_skg/org.kde.skrooge-import-skg.desktop
+++ b/plugins/import/skrooge_import_skg/org.kde.skrooge-import-skg.desktop
@@ -1,74 +1,74 @@
[Desktop Entry]
Name=Skrooge import SKG plugin
Name[bs]=Skrooge dodatak za SKG uvoz
Name[ca]=Connector d'importació de SKG de l'Skrooge
Name[ca@valencia]=Connector d'importació de SKG de l'Skrooge
Name[cs]=Modul Skrooge pro import SKG
Name[da]=Plugin til import af SKG til Skrooge
Name[de]=Skrooge-SKG-Importmodul
Name[el]=Skrooge import SKG plugin
Name[en_GB]=Skrooge import SKG plugin
Name[es]=Complemento de Skrooge para la importación de SKG
Name[et]=Skrooge SKG impordi plugin
Name[fi]=Skroogen SKG-tuontiliitännäinen
-Name[fr]=Module externe de Skrooge pour l'importation « SKG »
+Name[fr]=Module externe de Skrooge pour l'importation « SKG »
Name[gl]=Complemento de importación de SKG a Skrooge
Name[hu]=Skrooge SKG importáló bővítmény
Name[it]=Estensione di Skrooge per l'importazione SKG
Name[lt]=Skrooge SKG importavimo papildinys
Name[nb]=Skrooge-modul for SKG-import
Name[nl]=Plugin van Skrooge voor importeren van SKG
Name[pl]=Wtyczka importu SKG dla Skrooge
Name[pt]='Plugin' de importação de SKG para o Skrooge
Name[pt_BR]=Plugin de importação de SKG para o Skrooge
Name[ru]=Модуль импорта файлов SKG
Name[sk]=Skrooge plugin SKG import
Name[sv]=Skrooge SKG-importinsticksprogram
Name[tr]=Skrooge SKG içe aktarma eklentisi
Name[uk]=Додаток імпортування SKG до Skrooge
Name[x-test]=xxSkrooge import SKG pluginxx
Name[zh_TW]=Skrooge 匯入 SKG 外掛程式
Comment=A Skrooge plugin to import SKG files
Comment[bs]=Skrooge dodatak za uvoz SKG datoteka
Comment[ca]=Un connector de l'Skrooge per importar fitxers SKG
Comment[ca@valencia]=Un connector de l'Skrooge per importar fitxers SKG
Comment[cs]=Modul Skrooge pro import souborů SKG
Comment[da]=Et Skrooge-plugin til at importere SKG-filer
Comment[de]=Ein Skrooge-Modul zum Import von SKG-Dateien
Comment[el]=Ένα πρόσθετο του Skrooge για την εισαγωγή αρχείων SKG
Comment[en_GB]=A Skrooge plugin to import SKG files
Comment[es]=Complemento de Skrooge para importar archivos SKG
Comment[et]=Skrooge plugin SKG-failide importimiseks
Comment[fi]=Skroogen SKG-tiedostojen tuontiliitännäinen
-Comment[fr]=Un module externe de Skrooge pour l'importation de fichiers « SKG »
+Comment[fr]=Un module externe de Skrooge pour l'importation de fichiers « SKG »
Comment[gl]=Un complemento de Skrooge para importar ficheiros SKG.
Comment[hu]=Egy Skrooge bővítmény SKG fájlok importálásához
Comment[it]=Un'estensione di Skrooge per importare i file SKG
Comment[lt]=Skrooge SKG failų importavimo papildinys
Comment[nb]=En Skrooge-modul for å importere SKG-filer
Comment[nl]=Een Skrooge-plugin voor het importeren van SKG-bestanden
Comment[pl]=Wtyczka Skrooge do importu plików SKG
Comment[pt]=Um 'plugin' do Skrooge para importar ficheiros SKG
Comment[pt_BR]=Um plugin do Skrooge para importar arquivos SKG
Comment[ru]=Модуль импорта файлов SKG
Comment[sk]=Skrooge plugin na import SKG súborov
Comment[sv]=Ett insticksprogram till Skrooge för att importera SKG-filer
Comment[tr]=SKG dosyalarını içe aktarmak için Skrooge eklentisi
Comment[uk]=Додаток до Skrooge для імпортування даних з файлів SKG
Comment[x-test]=xxA Skrooge plugin to import SKG filesxx
Comment[zh_TW]=Skrooge 匯入 SKG 檔用的外掛程式
Encoding=UTF-8
Icon=skrooge
Type=Service
X-KDE-ServiceTypes=SKG IMPORT/Plugin
X-KDE-Library=skrooge_import_skg
X-Krunner-ID=Skrooge import SKG plugin
X-KDE-PluginInfo-Author=Stephane MANKOWSKI
X-KDE-PluginInfo-Email=stephane@mankowski.fr
X-KDE-PluginInfo-Name=skrooge_import_skg
X-KDE-PluginInfo-Version=1.0
-X-KDE-PluginInfo-Website=http://skrooge.org/
+X-KDE-PluginInfo-Website=https://skrooge.org/
X-KDE-PluginInfo-Category=Plugins
X-KDE-PluginInfo-Depends=
X-KDE-PluginInfo-License=GPL
X-KDE-PluginInfo-EnabledByDefault=true
diff --git a/plugins/import/skrooge_import_skg/skgimportpluginskg.cpp b/plugins/import/skrooge_import_skg/skgimportpluginskg.cpp
index f8eee75f5..96dd4655f 100644
--- a/plugins/import/skrooge_import_skg/skgimportpluginskg.cpp
+++ b/plugins/import/skrooge_import_skg/skgimportpluginskg.cpp
@@ -1,580 +1,580 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is Skrooge plugin for SKG import / export.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgimportpluginskg.h"
#include <qdir.h>
#include <qfile.h>
#include <qfileinfo.h>
#include <qsqldatabase.h>
#include <qsqlerror.h>
#include <quuid.h>
#include <klocalizedstring.h>
#include <kpluginfactory.h>
#include "skgbankincludes.h"
#include "skgimportexportmanager.h"
#include "skgobjectbase.h"
#include "skgservices.h"
#include "skgtraces.h"
#define SQLDRIVERNAME QStringLiteral("SKGSQLCIPHER")
/**
* This plugin factory.
*/
K_PLUGIN_FACTORY(SKGImportPluginSkgFactory, registerPlugin<SKGImportPluginSkg>();)
SKGImportPluginSkg::SKGImportPluginSkg(QObject* iImporter, const QVariantList& iArg)
: SKGImportPlugin(iImporter)
{
SKGTRACEINFUNC(10)
Q_UNUSED(iArg)
m_importParameters[QStringLiteral("password")] = QString();
}
SKGImportPluginSkg::~SKGImportPluginSkg()
= default;
bool SKGImportPluginSkg::isImportPossible()
{
SKGTRACEINFUNC(10)
return (m_importer == nullptr ? true : m_importer->getFileNameExtension() == QStringLiteral("SKG") || m_importer->getFileNameExtension() == QStringLiteral("SQLITE") || m_importer->getFileNameExtension() == QStringLiteral("SQLCIPHER"));
}
SKGError SKGImportPluginSkg::importFile()
{
if (m_importer == nullptr) {
return SKGError(ERR_ABORT, i18nc("Error message", "Invalid parameters"));
}
SKGError err;
SKGTRACEINFUNCRC(2, err)
QString lfile = m_importer->getLocalFileName();
if (lfile.isEmpty()) {
err.setReturnCode(ERR_INVALIDARG).setMessage(i18nc("Error message", "Open file '%1' failed", m_importer->getFileName().toDisplayString()));
} else {
SKGDocumentBank docOrigin;
err = docOrigin.load(lfile, m_importParameters.value(QStringLiteral("password")));
IFOK(err) {
QMap<QString, SKGObjectBase> mapOriginNew;
err = m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Import step", "Import %1 file", "SKG"), 10);
// Step 1 - units
IFOK(err) {
SKGObjectBase::SKGListSKGObjectBase listUnits;
err = docOrigin.getObjects(QStringLiteral("v_unit"), QStringLiteral("1=1 order by rd_unit_id, t_type"), listUnits);
IFOK(err) {
int nb = listUnits.count();
err = m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Import step", "Import units"), nb);
for (int i = 0; !err && i < nb; ++i) {
SKGUnitObject unitOrigin(listUnits.at(i));
SKGUnitObject unit(unitOrigin.cloneInto(m_importer->getDocument()));
if (unit.load().isFailed()) {
// This unit does not exist yet
IFOK(err) {
SKGUnitObject::UnitType unitType = unitOrigin.getType();
if (unitType == SKGUnitObject::PRIMARY || unitType == SKGUnitObject::SECONDARY) {
unitType = SKGUnitObject::CURRENCY;
}
err = unit.setType(unitType);
}
IFOK(err) {
SKGUnitObject parentUnitOrigin;
unitOrigin.getUnit(parentUnitOrigin);
SKGUnitObject parentUnit(mapOriginNew[parentUnitOrigin.getUniqueID()]);
if (parentUnit != unit) {
err = unit.setUnit(parentUnit);
}
}
IFOKDO(err, unit.save(false))
}
mapOriginNew[unitOrigin.getUniqueID()] = unit;
// Duplicate properties
IFOKDO(err, copyParameters(unitOrigin, unit))
// Unit values
SKGObjectBase::SKGListSKGObjectBase listUnitsValues;
IFOKDO(err, unitOrigin.getUnitValues(listUnitsValues))
int nb2 = listUnitsValues.count();
for (int j = 0; !err && j < nb2; ++j) {
SKGUnitValueObject unitValueOrigin(listUnitsValues.at(j));
SKGUnitValueObject unitval;
err = unit.addUnitValue(unitval);
IFOKDO(err, unitval.setDate(unitValueOrigin.getDate()))
IFOKDO(err, unitval.setQuantity(unitValueOrigin.getQuantity()))
IFOKDO(err, unitval.save(true))
// Duplicate properties
IFOKDO(err, copyParameters(unitValueOrigin, unitval))
}
IFOKDO(err, m_importer->getDocument()->stepForward(i + 1))
}
SKGENDTRANSACTION(m_importer->getDocument(), err)
}
}
IFOKDO(err, m_importer->getDocument()->stepForward(1))
// Step 2 - bank and accounts
IFOK(err) {
SKGObjectBase::SKGListSKGObjectBase listBanks;
err = docOrigin.getObjects(QStringLiteral("v_bank"), QString(), listBanks);
IFOK(err) {
int nb = listBanks.count();
err = m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Import step", "Import banks and accounts"), nb);
for (int i = 0; !err && i < nb; ++i) {
SKGBankObject bankOrigin(listBanks.at(i));
SKGBankObject bank(bankOrigin.cloneInto(m_importer->getDocument()));
if (bank.load().isFailed()) {
// This bank does not exist yet
IFOKDO(err, bank.save(false))
}
// Duplicate properties
IFOKDO(err, copyParameters(bankOrigin, bank))
// Accounts
SKGObjectBase::SKGListSKGObjectBase listAccounts;
IFOKDO(err, bankOrigin.getAccounts(listAccounts))
int nb2 = listAccounts.count();
for (int j = 0; !err && j < nb2; ++j) {
SKGAccountObject accountOrigin(listAccounts.at(j));
SKGAccountObject account(accountOrigin.cloneInto(m_importer->getDocument()));
if (account.load().isFailed()) {
// This account does not exist yet
IFOKDO(err, account.setBank(bank))
// Initial balance will be set on operation creation
IFOKDO(err, account.save(false))
}
// Duplicate properties
IFOKDO(err, copyParameters(accountOrigin, account))
mapOriginNew[accountOrigin.getUniqueID()] = account;
}
IFOKDO(err, m_importer->getDocument()->stepForward(i + 1))
}
SKGENDTRANSACTION(m_importer->getDocument(), err)
}
}
IFOKDO(err, m_importer->getDocument()->stepForward(2))
// Step 3 - categories
IFOK(err) {
SKGObjectBase::SKGListSKGObjectBase listCategories;
err = docOrigin.getObjects(QStringLiteral("v_category"), QString(), listCategories);
IFOK(err) {
int nb = listCategories.count();
err = m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Import step", "Import categories"), nb);
for (int i = 0; !err && i < nb; ++i) {
SKGCategoryObject catOrigin(listCategories.at(i));
SKGCategoryObject cat;
err = SKGCategoryObject::createPathCategory(m_importer->getDocument(), catOrigin.getFullName(), cat);
// Duplicate properties
IFOKDO(err, copyParameters(catOrigin, cat))
mapOriginNew[catOrigin.getUniqueID()] = cat;
IFOKDO(err, m_importer->getDocument()->stepForward(i + 1))
}
SKGENDTRANSACTION(m_importer->getDocument(), err)
}
}
IFOKDO(err, m_importer->getDocument()->stepForward(3))
// Step 4 - trackers
IFOK(err) {
SKGObjectBase::SKGListSKGObjectBase listRefund;
err = docOrigin.getObjects(QStringLiteral("v_refund"), QString(), listRefund);
IFOK(err) {
int nb = listRefund.count();
err = m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Import step", "Import trackers"), nb);
for (int i = 0; !err && i < nb; ++i) {
SKGTrackerObject tracOrigin(listRefund.at(i));
SKGTrackerObject trac(tracOrigin.cloneInto(m_importer->getDocument()));
err = trac.save();
// Duplicate properties
IFOKDO(err, copyParameters(tracOrigin, trac))
mapOriginNew[tracOrigin.getUniqueID()] = trac;
IFOKDO(err, m_importer->getDocument()->stepForward(i + 1))
}
SKGENDTRANSACTION(m_importer->getDocument(), err)
}
}
IFOKDO(err, m_importer->getDocument()->stepForward(4))
// Step 5 - rules
IFOK(err) {
SKGObjectBase::SKGListSKGObjectBase listRules;
err = docOrigin.getObjects(QStringLiteral("v_rule"), QString(), listRules);
IFOK(err) {
int nb = listRules.count();
err = m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Import step", "Import rules"), nb);
for (int i = 0; !err && i < nb; ++i) {
SKGRuleObject rulOrigin(listRules.at(i));
SKGRuleObject rul(rulOrigin.cloneInto(m_importer->getDocument()));
err = rul.save(false); // Save only
// Duplicate properties
IFOKDO(err, copyParameters(rulOrigin, rul))
IFOKDO(err, m_importer->getDocument()->stepForward(i + 1))
}
SKGENDTRANSACTION(m_importer->getDocument(), err)
}
}
IFOKDO(err, m_importer->getDocument()->stepForward(5))
// Step 6 - payee
IFOK(err) {
SKGObjectBase::SKGListSKGObjectBase listPayee;
err = docOrigin.getObjects(QStringLiteral("v_payee"), QString(), listPayee);
IFOK(err) {
int nb = listPayee.count();
err = m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Import step", "Import payees"), nb);
for (int i = 0; !err && i < nb; ++i) {
SKGPayeeObject paylOrigin(listPayee.at(i));
SKGPayeeObject pay;
err = SKGPayeeObject::createPayee(m_importer->getDocument(), paylOrigin.getName(), pay);
IFOKDO(err, pay.setAddress(paylOrigin.getAddress()))
IFOKDO(err, pay.save())
// Duplicate properties
IFOKDO(err, copyParameters(paylOrigin, pay))
mapOriginNew[paylOrigin.getUniqueID()] = pay;
IFOKDO(err, m_importer->getDocument()->stepForward(i + 1))
}
SKGENDTRANSACTION(m_importer->getDocument(), err)
}
}
IFOKDO(err, m_importer->getDocument()->stepForward(6))
// Step 7 - operations and suboperation
IFOK(err) {
SKGObjectBase::SKGListSKGObjectBase listOperations;
err = docOrigin.getObjects(QStringLiteral("v_operation"), QString(), listOperations);
IFOK(err) {
int nb = listOperations.count();
err = m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Import step", "Import operations"), nb);
for (int i = 0; !err && i < nb; ++i) {
SKGOperationObject operationOrigin(listOperations.at(i));
SKGOperationObject operation(operationOrigin.cloneInto(m_importer->getDocument()));
IFOKDO(err, operation.setAttribute(QStringLiteral("r_recurrentoperation_id"), QString()))
IFOKDO(err, operation.setImported(true))
IFOK(err) {
QString importID = operationOrigin.getImportID();
if (importID.isEmpty()) {
importID = "SKG-" % SKGServices::intToString(operationOrigin.getID());
}
err = operation.setImportID(importID);
}
IFOK(err) {
SKGAccountObject actOrig;
err = operationOrigin.getParentAccount(actOrig);
IFOK(err) {
SKGAccountObject act(mapOriginNew[actOrig.getUniqueID()]);
act.setClosed(false); // To be sure that the modification is possible. NOT SAVED
IFOKDO(err, operation.setParentAccount(act))
}
}
IFOK(err) {
SKGPayeeObject payeeOrig;
operationOrigin.getPayee(payeeOrig); // Error not managed
IFOKDO(err, operation.setPayee(SKGPayeeObject(mapOriginNew[payeeOrig.getUniqueID()])))
}
IFOK(err) {
SKGUnitObject unitOrig;
err = operationOrigin.getUnit(unitOrig);
IFOKDO(err, operation.setUnit(SKGUnitObject(mapOriginNew[unitOrig.getUniqueID()])))
}
IFOK(err) {
SKGOperationObject groupOrig;
operationOrigin.getGroupOperation(groupOrig);
err = operation.setGroupOperation(SKGOperationObject(mapOriginNew[groupOrig.getUniqueID()]));
}
IFOKDO(err, operation.save(false))
mapOriginNew[operationOrigin.getUniqueID()] = operation;
// Duplicate properties
IFOKDO(err, copyParameters(operationOrigin, operation))
// Sub operation
SKGObjectBase::SKGListSKGObjectBase listSuboperations;
IFOKDO(err, operationOrigin.getSubOperations(listSuboperations))
int nb2 = listSuboperations.count();
for (int j = 0; !err && j < nb2; ++j) {
SKGSubOperationObject subopOrigin(listSuboperations.at(j));
SKGSubOperationObject subop(subopOrigin.cloneInto(m_importer->getDocument()));
err = subop.setParentOperation(operation);
IFOK(err) {
SKGCategoryObject catOrig;
subopOrigin.getCategory(catOrig); // Error not managed
err = subop.setCategory(SKGCategoryObject(mapOriginNew[catOrig.getUniqueID()]));
}
IFOK(err) {
SKGTrackerObject tracOrig;
subopOrigin.getTracker(tracOrig); // Error not managed
IFOKDO(err, subop.setTracker(SKGTrackerObject(mapOriginNew[tracOrig.getUniqueID()]), true))
}
IFOKDO(err, subop.save(false))
// Duplicate properties
IFOKDO(err, copyParameters(subopOrigin, subop))
}
IFOKDO(err, m_importer->getDocument()->stepForward(i + 1))
if (!err && i % 500 == 0) {
err = m_importer->getDocument()->executeSqliteOrder(QStringLiteral("ANALYZE"));
}
}
SKGENDTRANSACTION(m_importer->getDocument(), err)
}
}
IFOKDO(err, m_importer->getDocument()->stepForward(7))
/* SKGObjectBase opWithThisHash;
if ( SKGObjectBase::getObject ( m_importer->getDocument(), "operation", "t_imported IN ('Y','P') AND t_import_id='"+QString ( hash.toHex() ) +'\'', opWithThisHash ).isSucceeded() )*/
// Step 8 - recurrent
IFOK(err) {
SKGObjectBase::SKGListSKGObjectBase ListRecurrentOperations;
err = docOrigin.getObjects(QStringLiteral("v_recurrentoperation"), QString(), ListRecurrentOperations);
IFOK(err) {
int nb = ListRecurrentOperations.count();
err = m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Import step", "Import scheduled operations"), nb);
for (int i = 0; !err && i < nb; ++i) {
SKGRecurrentOperationObject recuOrigin(ListRecurrentOperations.at(i));
SKGRecurrentOperationObject recu(recuOrigin.cloneInto(m_importer->getDocument()));
SKGOperationObject opOrig;
err = recuOrigin.getParentOperation(opOrig);
IFOKDO(err, recu.setParentOperation(SKGOperationObject(mapOriginNew[opOrig.getUniqueID()])))
IFOKDO(err, recu.save(false))
// Duplicate properties
IFOKDO(err, copyParameters(recuOrigin, recu))
IFOKDO(err, m_importer->getDocument()->stepForward(i + 1))
}
SKGENDTRANSACTION(m_importer->getDocument(), err)
}
}
IFOKDO(err, m_importer->getDocument()->stepForward(8))
// Step 9 - nodes
IFOK(err) {
SKGObjectBase::SKGListSKGObjectBase listNodes;
err = docOrigin.getObjects(QStringLiteral("v_node"), QString(), listNodes);
IFOK(err) {
int nb = listNodes.count();
err = m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Import step", "Import bookmarks"), nb);
for (int i = 0; !err && i < nb; ++i) {
SKGNodeObject nodeOrigin(listNodes.at(i));
SKGNodeObject node;
err = SKGNodeObject::createPathNode(m_importer->getDocument(), i18n("Imported bookmarks") % OBJECTSEPARATOR % nodeOrigin.getFullName(), node);
IFOKDO(err, node.setData(nodeOrigin.getData()))
IFOKDO(err, node.setOrder(nodeOrigin.getOrder()))
IFOKDO(err, node.setAutoStart(nodeOrigin.isAutoStart()))
IFOKDO(err, node.save(true, false))
IFOKDO(err, m_importer->getDocument()->stepForward(i + 1))
}
SKGENDTRANSACTION(m_importer->getDocument(), err)
}
}
IFOKDO(err, m_importer->getDocument()->stepForward(9))
// Step 10 - interest
IFOK(err) {
SKGObjectBase::SKGListSKGObjectBase listInterests;
err = docOrigin.getObjects(QStringLiteral("v_interest"), QString(), listInterests);
IFOK(err) {
int nb = listInterests.count();
err = m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Import step", "Import interests"), nb);
for (int i = 0; !err && i < nb; ++i) {
SKGInterestObject interestOrigin(listInterests.at(i));
SKGInterestObject interest(interestOrigin.cloneInto(m_importer->getDocument()));
IFOK(err) {
SKGAccountObject actOrig;
err = interestOrigin.getAccount(actOrig);
IFOKDO(err, interest.setAccount(SKGAccountObject(mapOriginNew[actOrig.getUniqueID()])))
}
IFOKDO(err, interest.save())
// Duplicate properties
IFOKDO(err, copyParameters(interestOrigin, interest))
IFOKDO(err, m_importer->getDocument()->stepForward(i + 1))
}
SKGENDTRANSACTION(m_importer->getDocument(), err)
}
}
IFOKDO(err, m_importer->getDocument()->stepForward(10))
SKGENDTRANSACTION(m_importer->getDocument(), err)
IFOKDO(err, m_importer->getDocument()->executeSqliteOrder(QStringLiteral("ANALYZE")))
}
}
return err;
}
bool SKGImportPluginSkg::isExportPossible()
{
SKGTRACEINFUNC(10)
return isImportPossible();
}
SKGError SKGImportPluginSkg::exportFile()
{
if (m_importer == nullptr) {
return SKGError(ERR_ABORT, i18nc("Error message", "Invalid parameters"));
}
SKGError err;
SKGTRACEINFUNCRC(2, err)
// Different modes:
// In memory sqlite DB => skg : copySqliteDatabase + cryptFile
// In memory sqlcipher DB => skg : sqlcipher_export + cryptFile
// File sqlite DB => skg : cryptFile
// File sqcipher DB => skg : cryptFile
// In memory sqlite DB => sqlite : copySqliteDatabase + upload
// In memory sqlcipher DB => sqlite : sqlcipher_export + upload
// File sqlite DB => sqlite : upload
// File sqcipher DB => sqlite : sqlcipher_export + upload
// In memory sqlite DB => sqlcipher : sqlcipher_export + upload
// In memory sqlcipher DB => sqlcipher : sqlcipher_export + upload
// File sqlite DB => sqlcipher : sqlcipher_export + upload
// File sqcipher DB => sqlcipher : sqlcipher_export + upload
QString file = m_importer->getLocalFileName(false);
QFile::remove(file);
QString ext = QFileInfo(file).suffix().toUpper();
QString pwd = m_importer->getDocument()->getPassword();
QString tempFile = m_importer->getDocument()->getCurrentTemporaryFile();
bool removeTempFile = false;
QString DBMode = m_importer->getDocument()->getParameter(QStringLiteral("SKG_DATABASE_TYPE"));
if (m_importer->getDocument()->getCurrentFileName().isEmpty() || DBMode != QStringLiteral("QSQLITE") || (ext == QStringLiteral("SQLCIPHER") && !pwd.isEmpty())) {
// The database is only in memory
tempFile = QDir::tempPath() % "/skg_" % QUuid::createUuid().toString() % ".skg";
removeTempFile = true;
auto fileDb = QSqlDatabase::addDatabase(ext == QStringLiteral("SQLITE") ? QStringLiteral("QSQLITE") : SQLDRIVERNAME, tempFile);
fileDb.setDatabaseName(tempFile);
if (!fileDb.open()) {
// Set error message
QSqlError sqlErr = fileDb.lastError();
err = SKGError(SQLLITEERROR + sqlErr.nativeErrorCode().toInt(), sqlErr.text());
} else {
if (ext == QStringLiteral("SQLCIPHER") && !pwd.isEmpty()) {
IFOKDO(err, SKGServices::executeSqliteOrder(fileDb, "PRAGMA KEY = '" % SKGServices::stringToSqlString(pwd) % "'"))
IFOKDO(err, m_importer->getDocument()->sendMessage(i18nc("An information message", "The sqlcipher database has been protected with the same password than your document"), SKGDocument::Information))
}
m_importer->getDocument()->getMainDatabase()->commit();
if (DBMode == QStringLiteral("QSQLITE") && ext == QStringLiteral("QSQLITE")) {
// The source database is a sqlite DB
IFOKDO(err, SKGServices::copySqliteDatabase(fileDb, *(m_importer->getDocument()->getMainDatabase()), false))
} else {
// The source database is a sqcipher DB
if (ext == QStringLiteral("SQLITE")) {
pwd = QString();
}
IFOKDO(err, m_importer->getDocument()->executeSqliteOrders(QStringList() << "ATTACH DATABASE '" % tempFile % "' AS sqlcipher KEY '" % SKGServices::stringToSqlString(pwd) % "'"
<< QStringLiteral("SELECT SQLCIPHER_EXPORT('sqlcipher')")
<< QStringLiteral("DETACH DATABASE sqlcipher")));
}
m_importer->getDocument()->getMainDatabase()->transaction();
fileDb.close();
QSqlDatabase::removeDatabase(tempFile);
}
}
// Copy file to file
IFOK(err) {
if (ext != QStringLiteral("SKG")) {
if (SKGServices::upload(QUrl::fromLocalFile(tempFile), QUrl::fromLocalFile(file))) {
err.setReturnCode(ERR_FAIL).setMessage(i18nc("An error message", "Creation file '%1' failed", file));
}
} else {
bool mode;
err = SKGServices::cryptFile(tempFile, file, QString(), true, m_importer->getDocument()->getDocumentHeader(), mode);
IFOK(err) {
SKGDocumentBank doc;
err = doc.load(file);
IFOKDO(err, doc.removeAllTransactions())
IFOKDO(err, doc.saveAs(file, true))
}
}
}
if (removeTempFile) {
QFile(tempFile).remove();
}
return err;
}
SKGError SKGImportPluginSkg::copyParameters(const SKGObjectBase& iFrom, const SKGObjectBase& iTo)
{
SKGError err;
SKGObjectBase::SKGListSKGObjectBase params;
err = iFrom.getDocument()->getObjects(QStringLiteral("parameters"), "t_uuid_parent='" % SKGServices::stringToSqlString(iFrom.getUniqueID()) % '\'', params);
IFOK(err) {
int nb = params.count();
SKGDocument* documentTarget = iTo.getDocument();
for (int i = 0; !err && i < nb; ++i) {
SKGObjectBase orig = params.at(i);
SKGObjectBase param = orig.cloneInto(documentTarget);
err = param.setAttribute(QStringLiteral("t_uuid_parent"), iTo.getUniqueID());
IFOKDO(err, param.save(true, false))
}
}
return err;
}
QString SKGImportPluginSkg::getMimeTypeFilter() const
{
return "*.skg|" % i18nc("A file format", "Skrooge document") % '\n' %
"*.sqlcipher|" % i18nc("A file format", "SQLCipher document") % '\n' %
"*.sqlite|" % i18nc("A file format", "SQLite document");
}
#include <skgimportpluginskg.moc>
diff --git a/plugins/import/skrooge_import_skg/skgimportpluginskg.h b/plugins/import/skrooge_import_skg/skgimportpluginskg.h
index dc1aea5fa..e7f049b16 100644
--- a/plugins/import/skrooge_import_skg/skgimportpluginskg.h
+++ b/plugins/import/skrooge_import_skg/skgimportpluginskg.h
@@ -1,88 +1,88 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGIMPORTPLUGINSKG_H
#define SKGIMPORTPLUGINSKG_H
/** @file
* This file is Skrooge plugin for SKG import / export.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgimportplugin.h"
class SKGObjectBase;
/**
* This file is Skrooge plugin for SKG import / export.
*/
class SKGImportPluginSkg : public SKGImportPlugin
{
Q_OBJECT
Q_INTERFACES(SKGImportPlugin)
public:
/**
* Default constructor
* @param iImporter the parent importer
* @param iArg the arguments
*/
explicit SKGImportPluginSkg(QObject* iImporter, const QVariantList& iArg);
/**
* Default Destructor
*/
~SKGImportPluginSkg() override;
/**
* To know if import is possible with this plugin
*/
bool isImportPossible() override;
/**
* Import a file
* @return an object managing the error.
* @see SKGError
*/
SKGError importFile() override;
/**
* To know if export is possible with this plugin
* @return true or false
*/
bool isExportPossible() override;
/**
* Export a file
* @return an object managing the error.
* @see SKGError
*/
SKGError exportFile() override;
/**
* Return the mime type filter
* @return the mime type filter. Example: "*.csv|CSV file"
*/
QString getMimeTypeFilter() const override;
private:
Q_DISABLE_COPY(SKGImportPluginSkg)
static SKGError copyParameters(const SKGObjectBase& iFrom, const SKGObjectBase& iTo);
};
#endif // SKGIMPORTPLUGINSKG_H
diff --git a/plugins/import/skrooge_import_xhb/CMakeLists.txt b/plugins/import/skrooge_import_xhb/CMakeLists.txt
index 9ccb02caa..e12f55085 100644
--- a/plugins/import/skrooge_import_xhb/CMakeLists.txt
+++ b/plugins/import/skrooge_import_xhb/CMakeLists.txt
@@ -1,33 +1,33 @@
#***************************************************************************
#* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
#* *
#* 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 <http://www.gnu.org/licenses/> *
+#* along with this program. If not, see <https://www.gnu.org/licenses/> *
#***************************************************************************
MESSAGE( STATUS "..:: CMAKE PLUGIN_IMPORT_XHB ::..")
PROJECT(plugin_import_xhb)
LINK_DIRECTORIES (${LIBRARY_OUTPUT_PATH})
SET(skrooge_import_xhb_SRCS
skgimportpluginxhb.cpp
)
ADD_LIBRARY(skrooge_import_xhb MODULE ${skrooge_import_xhb_SRCS})
TARGET_LINK_LIBRARIES(skrooge_import_xhb KF5::Parts KF5::Archive skgbasemodeler skgbasegui skgbankmodeler skgbankgui)
########### install files ###############
INSTALL(TARGETS skrooge_import_xhb DESTINATION ${KDE_INSTALL_QTPLUGINDIR})
INSTALL(FILES ${PROJECT_SOURCE_DIR}/org.kde.skrooge-import-xhb.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR})
diff --git a/plugins/import/skrooge_import_xhb/org.kde.skrooge-import-xhb.desktop b/plugins/import/skrooge_import_xhb/org.kde.skrooge-import-xhb.desktop
index 350996e3b..c01965da9 100644
--- a/plugins/import/skrooge_import_xhb/org.kde.skrooge-import-xhb.desktop
+++ b/plugins/import/skrooge_import_xhb/org.kde.skrooge-import-xhb.desktop
@@ -1,74 +1,74 @@
[Desktop Entry]
Name=Skrooge import XHB plugin
Name[bs]=Skrooge dodatak za XHB uvoz
Name[ca]=Connector d'importació de XHB de l'Skrooge
Name[ca@valencia]=Connector d'importació de XHB de l'Skrooge
Name[cs]=Modul Skrooge pro import XHB
Name[da]=Plugin til import af XHB til Skrooge
Name[de]=Skrooge-XHB-Importmodul
Name[el]=Skrooge import XHB plugin
Name[en_GB]=Skrooge import XHB plugin
Name[es]=Complemento de Skrooge para la importación de XHB
Name[et]=Skrooge XHB impordi plugin
Name[fi]=Skroogen XHB-tuontiliitännäinen
-Name[fr]=Module externe de Skrooge pour l'importation « XHB »
+Name[fr]=Module externe de Skrooge pour l'importation « XHB »
Name[gl]=Complemento de importación de XHB a Skrooge
Name[hu]=Skrooge XHB importáló bővítmény
Name[it]=Estensione di Skrooge per l'importazione XHB
Name[lt]=Skrooge XHB importavimo papildinys
Name[nb]=Skrooge-modul for XHB-import
Name[nl]=Plugin van Skrooge voor importeren van XHB
Name[pl]=Wtyczka importu XHB dla Skrooge
Name[pt]='Plugin' de importação de XHB para o Skrooge
Name[pt_BR]=Plugin de importação de XHB para o Skrooge
Name[ru]=Модуль импорта файлов XHB
Name[sk]=Skrooge plugin XHB import
Name[sv]=Skrooge XHB-importinsticksprogram
Name[tr]=Skrooge XHB içe aktarma eklentisi
Name[uk]=Додаток імпортування XHB до Skrooge
Name[x-test]=xxSkrooge import XHB pluginxx
Name[zh_TW]=Skrooge 匯入 XHB 外掛程式
Comment=A Skrooge plugin to import XHB files
Comment[bs]=Skrooge dodatak za uvoz XHB datoteka
Comment[ca]=Un connector de l'Skrooge per importar fitxers XHB
Comment[ca@valencia]=Un connector de l'Skrooge per importar fitxers XHB
Comment[cs]=Modul Skrooge pro import souborů XHB
Comment[da]=Et Skrooge-plugin til at importere XHB-filer
Comment[de]=Ein Skrooge-Modul zum Import von XHB-Dateien
Comment[el]=Ένα πρόσθετο του Skrooge για την εισαγωγή αρχείων XHB
Comment[en_GB]=A Skrooge plugin to import XHB files
Comment[es]=Complemento de Skrooge para importar archivos XHB
Comment[et]=Skrooge plugin XHB-failide importimiseks
Comment[fi]=Skroogen XHB-tiedostojen tuontiliitännäinen
-Comment[fr]=Un module externe de Skrooge pour l'importation de fichiers « XHB »
+Comment[fr]=Un module externe de Skrooge pour l'importation de fichiers « XHB »
Comment[gl]=Un complemento de Skrooge para importar ficheiros XHB.
Comment[hu]=Egy Skrooge bővítmény XHB fájlok importálásához
Comment[it]=Un'estensione di Skrooge per importare i file XHB
Comment[lt]=Skrooge XHB failų importavimo papildinys
Comment[nb]=En Skrooge-modul for å importere XHB-filer
Comment[nl]=Een Skrooge-plugin voor het importeren van XHB-bestanden
Comment[pl]=Wtyczka Skrooge do importu plików XHB
Comment[pt]=Um 'plugin' do Skrooge para importar ficheiros XHB
Comment[pt_BR]=Um plugin do Skrooge para importar arquivos XHB
Comment[ru]=Модуль импорта файлов XHB
Comment[sk]=Skrooge plugin na import XHB súborov
Comment[sv]=Ett insticksprogram till Skrooge för att importera XHB-filer
Comment[tr]=XHB dosyalarını içe aktarmak için Skrooge eklentisi
Comment[uk]=Додаток до Skrooge для імпортування даних з файлів XHB
Comment[x-test]=xxA Skrooge plugin to import XHB filesxx
Comment[zh_TW]=Skrooge 匯入 XHB 檔用的外掛程式
Encoding=UTF-8
Icon=skrooge
Type=Service
X-KDE-ServiceTypes=SKG IMPORT/Plugin
X-KDE-Library=skrooge_import_xhb
X-Krunner-ID=Skrooge import XHB plugin
X-KDE-PluginInfo-Author=Stephane MANKOWSKI
X-KDE-PluginInfo-Email=stephane@mankowski.fr
X-KDE-PluginInfo-Name=skrooge_import_xhb
X-KDE-PluginInfo-Version=1.0
-X-KDE-PluginInfo-Website=http://skrooge.org/
+X-KDE-PluginInfo-Website=https://skrooge.org/
X-KDE-PluginInfo-Category=Plugins
X-KDE-PluginInfo-Depends=
X-KDE-PluginInfo-License=GPL
X-KDE-PluginInfo-EnabledByDefault=true
diff --git a/plugins/import/skrooge_import_xhb/skgimportpluginxhb.cpp b/plugins/import/skrooge_import_xhb/skgimportpluginxhb.cpp
index 17f835de4..b752c99d1 100644
--- a/plugins/import/skrooge_import_xhb/skgimportpluginxhb.cpp
+++ b/plugins/import/skrooge_import_xhb/skgimportpluginxhb.cpp
@@ -1,394 +1,394 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is Skrooge plugin for XHB import / export.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgimportpluginxhb.h"
#include <kcompressiondevice.h>
#include <klocalizedstring.h>
#include <kpluginfactory.h>
#include <qdom.h>
#include "skgbankincludes.h"
#include "skgimportexportmanager.h"
#include "skgobjectbase.h"
#include "skgpayeeobject.h"
#include "skgservices.h"
#include "skgtraces.h"
/**
* This plugin factory.
*/
K_PLUGIN_FACTORY(SKGImportPluginXhbFactory, registerPlugin<SKGImportPluginXhb>();)
SKGImportPluginXhb::SKGImportPluginXhb(QObject* iImporter, const QVariantList& iArg)
: SKGImportPlugin(iImporter)
{
SKGTRACEINFUNC(10)
Q_UNUSED(iArg)
}
SKGImportPluginXhb::~SKGImportPluginXhb()
= default;
bool SKGImportPluginXhb::isImportPossible()
{
SKGTRACEINFUNC(10)
return (m_importer == nullptr ? true : m_importer->getFileNameExtension() == QStringLiteral("XHB"));
}
SKGError SKGImportPluginXhb::importFile()
{
if (m_importer == nullptr) {
return SKGError(ERR_ABORT, i18nc("Error message", "Invalid parameters"));
}
SKGError err;
SKGTRACEINFUNCRC(2, err)
// Initialisation
// Open file
KCompressionDevice file(m_importer->getLocalFileName(), KCompressionDevice::GZip);
if (!file.open(QIODevice::ReadOnly)) {
err.setReturnCode(ERR_INVALIDARG).setMessage(i18nc("Error message", "Open file '%1' failed", m_importer->getFileName().toDisplayString()));
} else {
QDomDocument doc;
// Set the file without uncompression
QString errorMsg;
int errorLine = 0;
int errorCol = 0;
bool contentOK = doc.setContent(file.readAll(), &errorMsg, &errorLine, &errorCol);
file.close();
// Get root
QDomElement docElem = doc.documentElement();
if (!contentOK) {
err.setReturnCode(ERR_ABORT).setMessage(i18nc("Error message", "%1-%2: '%3'", errorLine, errorCol, errorMsg));
}
if (!contentOK) {
err.addError(ERR_INVALIDARG, i18nc("Error message", "Invalid XML content in file '%1'", m_importer->getFileName().toDisplayString()));
} else {
err = m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Import step", "Import %1 file", "XHB"), 4);
QMap<QString, SKGAccountObject> mapIdAccount;
QMap<QString, SKGCategoryObject> mapIdCategory;
QMap<QString, SKGPayeeObject> mapIdPayee;
SKGUnitObject unit;
IFOKDO(err, m_importer->getDefaultUnit(unit))
// Step 1-Create accounts
IFOK(err) {
QDomNodeList accountList = docElem.elementsByTagName(QStringLiteral("account"));
int nb = accountList.count();
err = m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Import step", "Import accounts"), nb);
for (int i = 0; !err && i < nb; ++i) {
// Get account object
QDomElement account = accountList.at(i).toElement();
// Create the bank
SKGBankObject bank(m_importer->getDocument());
QString bname = getAttribute(account, QStringLiteral("bankname"));
if (bname.isEmpty()) {
bname = QStringLiteral("HOMEBANK");
}
IFOKDO(err, bank.setName(bname))
IFOKDO(err, bank.save())
// Creation of the account
SKGAccountObject accountObj;
IFOKDO(err, bank.addAccount(accountObj))
IFOKDO(err, accountObj.setName(getAttribute(account, QStringLiteral("name"))))
IFOKDO(err, accountObj.setNumber(getAttribute(account, QStringLiteral("number"))))
IFOKDO(err, accountObj.setMinLimitAmount(SKGServices::stringToDouble(getAttribute(account, QStringLiteral("minimum")))))
IFOKDO(err, accountObj.minLimitAmountEnabled(accountObj.getMinLimitAmount() != 0.0))
QString type = getAttribute(account, QStringLiteral("type"));
IFOKDO(err, accountObj.setType(type == QStringLiteral("2") ? SKGAccountObject::WALLET : (type == QStringLiteral("3") ? SKGAccountObject::ASSETS : (type == QStringLiteral("4") ? SKGAccountObject::CREDITCARD : (type == QStringLiteral("5") ? SKGAccountObject::LOAN : SKGAccountObject::CURRENT)))))
IFOK(err) {
QString flags = getAttribute(account, QStringLiteral("flags"));
err = accountObj.setClosed(flags == QStringLiteral("2") || flags == QStringLiteral("3"));
}
IFOKDO(err, accountObj.save())
// Change parent bank in case of ASSETS
if (accountObj.getType() == SKGAccountObject::WALLET) {
// Get blank bank
SKGBankObject blankBank(m_importer->getDocument());
IFOKDO(err, blankBank.setName(QString()))
if (blankBank.exist()) {
err = blankBank.load();
} else {
err = blankBank.save();
}
IFOKDO(err, accountObj.setBank(blankBank))
IFOKDO(err, accountObj.save())
}
// Set initial balance
IFOKDO(err, accountObj.setInitialBalance(SKGServices::stringToDouble(getAttribute(account, QStringLiteral("initial"))), unit))
mapIdAccount[getAttribute(account, QStringLiteral("key"))] = accountObj;
IFOKDO(err, m_importer->getDocument()->stepForward(i + 1))
}
SKGENDTRANSACTION(m_importer->getDocument(), err)
}
IFOKDO(err, m_importer->getDocument()->stepForward(1))
// Step 2-Get payees
IFOK(err) {
QDomNodeList partyList = docElem.elementsByTagName(QStringLiteral("pay"));
int nb = partyList.count();
err = m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Import step", "Import payees"), nb);
for (int i = 0; !err && i < nb; ++i) {
// Get payee object
QDomElement party = partyList.at(i).toElement();
SKGPayeeObject payeeObject;
err = SKGPayeeObject::createPayee(m_importer->getDocument(), getAttribute(party, QStringLiteral("name")), payeeObject);
mapIdPayee[getAttribute(party, QStringLiteral("key"))] = payeeObject;
IFOKDO(err, m_importer->getDocument()->stepForward(i + 1))
}
SKGENDTRANSACTION(m_importer->getDocument(), err)
}
IFOKDO(err, m_importer->getDocument()->stepForward(2))
// Step 3-Create categories
IFOK(err) {
QDomNodeList categoryList = docElem.elementsByTagName(QStringLiteral("cat"));
int nb = categoryList.count();
err = m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Import step", "Import categories"), 2 * nb);
for (int j = 0; !err && j < 2; ++j) {
for (int i = 0; !err && i < nb; ++i) {
// Get account object
QDomElement category = categoryList.at(i).toElement();
// Creation of the category
bool catCreated = false;
SKGCategoryObject catObj(m_importer->getDocument());
QString parent2 = getAttribute(category, QStringLiteral("parent"));
if (parent2.isEmpty()) {
parent2 = '0';
}
if (parent2 == QStringLiteral("0") && j == 0) {
IFOKDO(err, catObj.setName(getAttribute(category, QStringLiteral("name"))))
IFOKDO(err, catObj.save())
mapIdCategory[getAttribute(category, QStringLiteral("key"))] = catObj;
catCreated = true;
} else if (parent2 != QStringLiteral("0") && j == 1) {
SKGCategoryObject catParentObj = mapIdCategory[parent2];
IFOKDO(err, catObj.setName(getAttribute(category, QStringLiteral("name"))))
IFOKDO(err, catObj.setParentCategory(catParentObj))
IFOKDO(err, catObj.save())
mapIdCategory[getAttribute(category, QStringLiteral("key"))] = catObj;
catCreated = true;
}
// Creation of the attached budget
if (!err && catCreated) {
QString b0 = getAttribute(category, QStringLiteral("b0"));
QString b1 = getAttribute(category, QStringLiteral("b1"));
if (!b0.isEmpty() || !b1.isEmpty()) {
for (int m = 1; !err && m <= 12; ++m) {
SKGBudgetObject budget(m_importer->getDocument());
int year = QDate::currentDate().year();
IFOKDO(err, budget.setCategory(catObj))
IFOKDO(err, budget.setYear(year))
IFOKDO(err, budget.setMonth(m))
IFOKDO(err, budget.setBudgetedAmount(SKGServices::stringToDouble(getAttribute(category, 'b' % SKGServices::intToString(b0.isEmpty() ? m : 0)))))
IFOKDO(err, budget.save())
}
}
}
IFOKDO(err, m_importer->getDocument()->stepForward(nb * j + i + 1))
}
}
SKGENDTRANSACTION(m_importer->getDocument(), err)
}
IFOKDO(err, m_importer->getDocument()->stepForward(3))
// Step 4-Create transaction
IFOK(err) {
err = m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Import step", "Import operations"), 2);
for (int j = 1; !err && j <= 2; ++j) {
QDomNodeList transactionList = docElem.elementsByTagName(j == 1 ? QStringLiteral("ope") : QStringLiteral("fav"));
int nb = transactionList.count();
err = m_importer->getDocument()->beginTransaction("#INTERNAL#" % i18nc("Import step", "Import operations"), nb);
for (int i = 0; !err && i < nb; ++i) {
// Get account object
QDomElement transaction = transactionList.at(i).toElement();
// Get attributes
QString idAccount = getAttribute(transaction, QStringLiteral("account"));
// QString dst_account = getAttribute(transaction, QStringLiteral("dst_account"));
if (idAccount != QStringLiteral("0")) {
SKGAccountObject account = mapIdAccount[idAccount];
QDate date = QDate(1, 1, 1).addDays(1 + SKGServices::stringToInt(getAttribute(transaction, j == 1 ? QStringLiteral("date") : QStringLiteral("nextdate"))));
QString mode = getAttribute(transaction, QStringLiteral("paymode"));
if (mode == QStringLiteral("1")) {
mode = i18nc("Noun: type of payement", "Credit card");
} else if (mode == QStringLiteral("2")) {
mode = i18nc("Noun: type of payement", "Check");
} else if (mode == QStringLiteral("3")) {
mode = i18nc("Noun: type of payement", "Cash");
} else if (mode == QStringLiteral("4") || mode == QStringLiteral("5")) {
mode = i18nc("Noun: type of payement", "Transfer");
} else {
mode = i18nc("Noun: type of payement", "Other");
}
QString comment = QString(getAttribute(transaction, QStringLiteral("wording")) % ' ' % getAttribute(transaction, QStringLiteral("info"))).trimmed();
int flags = SKGServices::stringToInt(getAttribute(transaction, QStringLiteral("flags")));
double amount = SKGServices::stringToDouble(getAttribute(transaction, QStringLiteral("amount")));
SKGOperationObject::OperationStatus status = (flags == 1 || flags == 3 ? SKGOperationObject::CHECKED : SKGOperationObject::NONE);
SKGPayeeObject payee = mapIdPayee[ getAttribute(transaction, QStringLiteral("payee"))];
SKGCategoryObject category = mapIdCategory[getAttribute(transaction, QStringLiteral("category"))];
// Creation of the operation
SKGOperationObject opObj;
IFOKDO(err, account.addOperation(opObj, true))
IFOKDO(err, opObj.setDate(date))
IFOKDO(err, opObj.setUnit(unit))
IFOKDO(err, opObj.setPayee(payee))
IFOKDO(err, opObj.setMode(mode))
IFOKDO(err, opObj.setComment(comment))
IFOKDO(err, opObj.setTemplate(j == 2))
IFOKDO(err, opObj.setImported(true))
IFOKDO(err, opObj.setImportID("HXB-" % SKGServices::intToString(i)))
IFOKDO(err, opObj.setStatus(status))
IFOKDO(err, opObj.save())
SKGSubOperationObject subObj;
IFOKDO(err, opObj.addSubOperation(subObj))
IFOKDO(err, subObj.setCategory(category))
IFOKDO(err, subObj.setComment(comment))
IFOKDO(err, subObj.setQuantity(amount))
IFOKDO(err, subObj.save())
// Transfer
/*if(dst_account != idAccount && dst_account != "0") {
SKGAccountObject account = mapIdAccount[dst_account];
SKGOperationObject op2Obj;
if(!err) err = account.addOperation(op2Obj, true);
if(!err) err = op2Obj.setDate(date);
if(!err) err = op2Obj.setUnit(unit);
if(!err) err = op2Obj.setPayee(payee);
if(!err) err = op2Obj.setMode(mode);
if(!err) err = op2Obj.setComment(comment);
if(!err) err = op2Obj.setTemplate(j == 2);
if(!err) err = op2Obj.setImported(true);
if(!err) err = op2Obj.setImportID("HXB-" % SKGServices::intToString(i) % "_TR");
if(!err) err = op2Obj.setStatus(status);
if(!err) err = op2Obj.save();
SKGSubOperationObject subObj;
if(!err) err = op2Obj.addSubOperation(subObj);
if(!err) err = subObj.setCategory(category);
if(!err) err = subObj.setComment(comment);
if(!err) err = subObj.setQuantity(-amount);
if(!err) err = subObj.save();
if(!err) err = op2Obj.setGroupOperation(opObj);
if(!err) err = op2Obj.save();
}*/
// Scheduled operations
if (j == 2) {
// Creation of scheduled operation
SKGRecurrentOperationObject recu;
IFOKDO(err, opObj.addRecurrentOperation(recu))
int limit = SKGServices::stringToInt(getAttribute(transaction, QStringLiteral("limit")));
IFOKDO(err, recu.timeLimit(flags & (1 << 7)))
IFOKDO(err, recu.setTimeLimit(limit))
int punit = SKGServices::stringToInt(getAttribute(transaction, QStringLiteral("unit")));
int pstep = SKGServices::stringToInt(getAttribute(transaction, QStringLiteral("every")));
SKGRecurrentOperationObject::PeriodUnit p = SKGRecurrentOperationObject::MONTH;
if (punit == 0) {
p = SKGRecurrentOperationObject::DAY;
} else if (punit == 1) {
p = SKGRecurrentOperationObject::WEEK;
} else if (punit == 3) {
p = SKGRecurrentOperationObject::YEAR;
}
IFOKDO(err, recu.setPeriodIncrement(pstep))
IFOKDO(err, recu.setPeriodUnit(p))
IFOKDO(err, recu.warnEnabled(flags & (1 << 5)))
IFOKDO(err, recu.autoWriteEnabled(flags & (1 << 2)))
IFOKDO(err, recu.save())
// #define OF_VALID (1<<0)
// #define OF_INCOME (1<<1)
// #define OF_AUTO (1<<2)
// #define OF_ADDED (1<<3)
// #define OF_CHANGED (1<<4)
// #define OF_REMIND (1<<5)
// #define OF_CHEQ2 (1<<6)
// #define OF_LIMIT (1<<7)
}
}
if (!err && i % 500 == 0) {
err = m_importer->getDocument()->executeSqliteOrder(QStringLiteral("ANALYZE"));
}
IFOKDO(err, m_importer->getDocument()->stepForward(i + 1))
}
SKGENDTRANSACTION(m_importer->getDocument(), err)
IFOKDO(err, m_importer->getDocument()->stepForward(j))
}
SKGENDTRANSACTION(m_importer->getDocument(), err)
}
IFOKDO(err, m_importer->getDocument()->stepForward(4))
SKGENDTRANSACTION(m_importer->getDocument(), err)
IFOKDO(err, m_importer->getDocument()->executeSqliteOrder(QStringLiteral("ANALYZE")))
}
}
return err;
}
QString SKGImportPluginXhb::getAttribute(const QDomElement& iElement, const QString& iAttribute)
{
QString val = iElement.attribute(iAttribute);
if (val == QStringLiteral("(null)")) {
val = QString();
}
return val;
}
QString SKGImportPluginXhb::getMimeTypeFilter() const
{
return "*.xhb|" % i18nc("A file format", "Homebank document");
}
#include <skgimportpluginxhb.moc>
diff --git a/plugins/import/skrooge_import_xhb/skgimportpluginxhb.h b/plugins/import/skrooge_import_xhb/skgimportpluginxhb.h
index d5055ea1b..253b7efdb 100644
--- a/plugins/import/skrooge_import_xhb/skgimportpluginxhb.h
+++ b/plugins/import/skrooge_import_xhb/skgimportpluginxhb.h
@@ -1,72 +1,72 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGIMPORTPLUGINXHB_H
#define SKGIMPORTPLUGINXHB_H
/** @file
* This file is Skrooge plugin for XHB import / export.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgimportplugin.h"
/**
* This file is Skrooge plugin for XHB import / export.
*/
class SKGImportPluginXhb : public SKGImportPlugin
{
Q_OBJECT
Q_INTERFACES(SKGImportPlugin)
public:
/**
* Default constructor
* @param iImporter the parent importer
* @param iArg the arguments
*/
explicit SKGImportPluginXhb(QObject* iImporter, const QVariantList& iArg);
/**
* Default Destructor
*/
~SKGImportPluginXhb() override;
/**
* To know if import is possible with this plugin
*/
bool isImportPossible() override;
/**
* Import a file
* @return an object managing the error.
* @see SKGError
*/
SKGError importFile() override;
/**
* Return the mime type filter
* @return the mime type filter. Example: "*.csv|CSV file"
*/
QString getMimeTypeFilter() const override;
private:
Q_DISABLE_COPY(SKGImportPluginXhb)
static QString getAttribute(const QDomElement& iElement, const QString& iAttribute);
};
#endif // SKGIMPORTPLUGINXHB_H
diff --git a/plugins/import/skrooge_import_xml/CMakeLists.txt b/plugins/import/skrooge_import_xml/CMakeLists.txt
index e4e1fd2c2..2404d1596 100644
--- a/plugins/import/skrooge_import_xml/CMakeLists.txt
+++ b/plugins/import/skrooge_import_xml/CMakeLists.txt
@@ -1,33 +1,33 @@
#***************************************************************************
#* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
#* *
#* 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 <http://www.gnu.org/licenses/> *
+#* along with this program. If not, see <https://www.gnu.org/licenses/> *
#***************************************************************************
MESSAGE( STATUS "..:: CMAKE PLUGIN_IMPORT_XML ::..")
PROJECT(plugin_import_xml)
LINK_DIRECTORIES (${LIBRARY_OUTPUT_PATH})
SET(skrooge_import_xml_SRCS
skgimportpluginxml.cpp
)
ADD_LIBRARY(skrooge_import_xml MODULE ${skrooge_import_xml_SRCS})
TARGET_LINK_LIBRARIES(skrooge_import_xml KF5::Parts skgbasemodeler skgbasegui skgbankmodeler skgbankgui)
########### install files ###############
INSTALL(TARGETS skrooge_import_xml DESTINATION ${KDE_INSTALL_QTPLUGINDIR})
INSTALL(FILES ${PROJECT_SOURCE_DIR}/org.kde.skrooge-import-xml.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR})
diff --git a/plugins/import/skrooge_import_xml/org.kde.skrooge-import-xml.desktop b/plugins/import/skrooge_import_xml/org.kde.skrooge-import-xml.desktop
index 74543b467..55c34cc60 100644
--- a/plugins/import/skrooge_import_xml/org.kde.skrooge-import-xml.desktop
+++ b/plugins/import/skrooge_import_xml/org.kde.skrooge-import-xml.desktop
@@ -1,74 +1,74 @@
[Desktop Entry]
Name=Skrooge import XML plugin
Name[bs]=Skrooge dodatak za XML uvoz
Name[ca]=Connector d'importació d'XML de l'Skrooge
Name[ca@valencia]=Connector d'importació d'XML de l'Skrooge
Name[cs]=Modul Skrooge pro import XML
Name[da]=Plugin til import af XML til Skrooge
Name[de]=Skrooge-XML-Importmodul
Name[el]=Skrooge import XML plugin
Name[en_GB]=Skrooge import XML plugin
Name[es]=Complemento de Skrooge para la importación de XML
Name[et]=Skrooge XML impordi plugin
Name[fi]=Skroogen XML-tuontiliitännäinen
-Name[fr]=Module externe de Skrooge pour l'importation « XML »
+Name[fr]=Module externe de Skrooge pour l'importation « XML »
Name[gl]=Complemento de importación de XML a Skrooge
Name[hu]=Skrooge XML importáló bővítmény
Name[it]=Estensione di Skrooge per l'importazione XML
Name[lt]=Skrooge XML importavimo papildinys
Name[nb]=Skrooge-modul for XML-import
Name[nl]=Plugin van Skrooge voor importeren van XML
Name[pl]=Wtyczka importu XML dla Skrooge
Name[pt]='Plugin' de importação de XML para o Skrooge
Name[pt_BR]=Plugin de importação de XML para o Skrooge
Name[ru]=Модуль импорта файлов XML
Name[sk]=Skrooge plugin XML import
Name[sv]=Skrooge XML-importinsticksprogram
Name[tr]=Skrooge XML içe aktarma eklentisi
Name[uk]=Додаток імпортування XML до Skrooge
Name[x-test]=xxSkrooge import XML pluginxx
Name[zh_TW]=Skrooge 匯入 XML 外掛程式
Comment=A Skrooge plugin to import XML files
Comment[bs]=Skrooge dodatak za uvoz XML datoteka
Comment[ca]=Un connector de l'Skrooge per importar fitxers XML
Comment[ca@valencia]=Un connector de l'Skrooge per importar fitxers XML
Comment[cs]=Modul Skrooge pro import souborů XML
Comment[da]=Et Skrooge-plugin til at importere XML-filer
Comment[de]=Ein Skrooge-Modul zum Import von XML-Dateien
Comment[el]=Ένα πρόσθετο του Skrooge για την εισαγωγή αρχείων XML
Comment[en_GB]=A Skrooge plugin to import XML files
Comment[es]=Complemento de Skrooge para importar archivos XML
Comment[et]=Skrooge plugin XML-failide importimiseks
Comment[fi]=Skroogen XML-tiedostojen tuontiliitännäinen
-Comment[fr]=Un module externe de Skrooge pour l'importation de fichiers « XML »
+Comment[fr]=Un module externe de Skrooge pour l'importation de fichiers « XML »
Comment[gl]=Un complemento do Skrooge para importar ficheiros XML.
Comment[hu]=Egy Skrooge bővítmény XML fájlok importálásához
Comment[it]=Un'estensione di Skrooge per importare i file XML
Comment[lt]=Skrooge XML failų importavimo papildinys
Comment[nb]=En Skrooge-modul for å importere XML-filer
Comment[nl]=Een Skrooge-plugin voor het importeren van XML-bestanden
Comment[pl]=Wtyczka Skrooge do importu plików XML
Comment[pt]=Um 'plugin' do Skrooge para importar ficheiros XML
Comment[pt_BR]=Um plugin do Skrooge para importar arquivos XML
Comment[ru]=Модуль импорта файлов XML
Comment[sk]=Skrooge plugin na import XML súborov
Comment[sv]=Ett insticksprogram till Skrooge för att importera XML-filer
Comment[tr]=XML dosyalarını içe aktarmak için Skrooge eklentisi
Comment[uk]=Додаток до Skrooge для імпортування даних з файлів XML
Comment[x-test]=xxA Skrooge plugin to import XML filesxx
Comment[zh_TW]=Skrooge 匯入 XML 檔用的外掛程式
Encoding=UTF-8
Icon=skrooge
Type=Service
X-KDE-ServiceTypes=SKG IMPORT/Plugin
X-KDE-Library=skrooge_import_xml
X-Krunner-ID=Skrooge import XML plugin
X-KDE-PluginInfo-Author=Stephane MANKOWSKI
X-KDE-PluginInfo-Email=stephane@mankowski.fr
X-KDE-PluginInfo-Name=skrooge_import_xml
X-KDE-PluginInfo-Version=1.0
-X-KDE-PluginInfo-Website=http://skrooge.org/
+X-KDE-PluginInfo-Website=https://skrooge.org/
X-KDE-PluginInfo-Category=Plugins
X-KDE-PluginInfo-Depends=
X-KDE-PluginInfo-License=GPL
X-KDE-PluginInfo-EnabledByDefault=true
diff --git a/plugins/import/skrooge_import_xml/skgimportpluginxml.cpp b/plugins/import/skrooge_import_xml/skgimportpluginxml.cpp
index fcf55a450..3362c88aa 100644
--- a/plugins/import/skrooge_import_xml/skgimportpluginxml.cpp
+++ b/plugins/import/skrooge_import_xml/skgimportpluginxml.cpp
@@ -1,82 +1,82 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 impgnced 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is Skrooge plugin for XML import / export.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgimportpluginxml.h"
#include <klocalizedstring.h>
#include <kpluginfactory.h>
#include <qsavefile.h>
#include "skgdocumentbank.h"
#include "skgservices.h"
#include "skgtraces.h"
/**
* This plugin factory.
*/
K_PLUGIN_FACTORY(SKGImportPluginXmlFactory, registerPlugin<SKGImportPluginXml>();)
SKGImportPluginXml::SKGImportPluginXml(QObject* iImporter, const QVariantList& iArg)
: SKGImportPlugin(iImporter)
{
SKGTRACEINFUNC(10)
Q_UNUSED(iArg)
}
SKGImportPluginXml::~SKGImportPluginXml()
= default;
bool SKGImportPluginXml::isExportPossible()
{
SKGTRACEINFUNC(10)
return (m_importer == nullptr ? true : m_importer->getFileNameExtension() == QStringLiteral("XML"));
}
SKGError SKGImportPluginXml::exportFile()
{
SKGError err;
QDomDocument doc;
err = SKGServices::copySqliteDatabaseToXml(*(m_importer->getDocument()->getMainDatabase()), doc);
IFOK(err) {
QSaveFile file(m_importer->getLocalFileName(false));
if (!file.open(QIODevice::WriteOnly)) {
err.setReturnCode(ERR_INVALIDARG).setMessage(i18nc("Error message", "Save file '%1' failed", m_importer->getFileName().toDisplayString()));
} else {
QTextStream stream(&file);
if (!m_importer->getCodec().isEmpty()) {
stream.setCodec(m_importer->getCodec().toLatin1().constData());
}
stream << doc.toString() << endl;
// Close file
file.commit();
}
}
return err;
}
QString SKGImportPluginXml::getMimeTypeFilter() const
{
return "*.xml|" % i18nc("A file format", "XML file");
}
#include <skgimportpluginxml.moc>
diff --git a/plugins/import/skrooge_import_xml/skgimportpluginxml.h b/plugins/import/skrooge_import_xml/skgimportpluginxml.h
index a7b6f013b..9436516fa 100644
--- a/plugins/import/skrooge_import_xml/skgimportpluginxml.h
+++ b/plugins/import/skrooge_import_xml/skgimportpluginxml.h
@@ -1,71 +1,71 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGIMPORTPLUGINXML_H
#define SKGIMPORTPLUGINXML_H
/** @file
* This file is Skrooge plugin for XML import / export.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgimportplugin.h"
/**
* This file is Skrooge plugin for XML import / export.
*/
class SKGImportPluginXml : public SKGImportPlugin
{
Q_OBJECT
Q_INTERFACES(SKGImportPlugin)
public:
/**
* Default constructor
* @param iImporter the parent importer
* @param iArg the arguments
*/
explicit SKGImportPluginXml(QObject* iImporter, const QVariantList& iArg);
/**
* Default Destructor
*/
~SKGImportPluginXml() override;
/**
* To know if export is possible with this plugin
* @return true or false
*/
bool isExportPossible() override;
/**
* Export a file
* @return an object managing the error.
* @see SKGError
*/
SKGError exportFile() override;
/**
* Return the mime type filter
* @return the mime type filter. Example: "*.csv|CSV file"
*/
QString getMimeTypeFilter() const override;
private:
Q_DISABLE_COPY(SKGImportPluginXml)
};
#endif // SKGIMPORTPLUGINXML_H
diff --git a/plugins/krunner/CMakeLists.txt b/plugins/krunner/CMakeLists.txt
index 30a24a575..c3b498bf6 100644
--- a/plugins/krunner/CMakeLists.txt
+++ b/plugins/krunner/CMakeLists.txt
@@ -1,18 +1,18 @@
#***************************************************************************
#* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
#* *
#* 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 <http://www.gnu.org/licenses/> *
+#* along with this program. If not, see <https://www.gnu.org/licenses/> *
#***************************************************************************
add_subdirectory(skrooge_add_operation)
diff --git a/plugins/krunner/skrooge_add_operation/CMakeLists.txt b/plugins/krunner/skrooge_add_operation/CMakeLists.txt
index f9c41bf6c..755547532 100644
--- a/plugins/krunner/skrooge_add_operation/CMakeLists.txt
+++ b/plugins/krunner/skrooge_add_operation/CMakeLists.txt
@@ -1,32 +1,32 @@
#***************************************************************************
#* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
#* *
#* 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 <http://www.gnu.org/licenses/> *
+#* along with this program. If not, see <https://www.gnu.org/licenses/> *
#***************************************************************************
MESSAGE( STATUS "..:: CMAKE PLUGIN_ADD_OPERATION ::..")
PROJECT(plugin_add_operation)
FIND_PACKAGE(KF5Runner)
IF(KF5Runner_FOUND)
LINK_DIRECTORIES (${LIBRARY_OUTPUT_PATH})
ADD_LIBRARY(skrooge_add_operation MODULE skgaddoperation.cpp)
TARGET_LINK_LIBRARIES(skrooge_add_operation KF5::Runner KF5::WidgetsAddons KF5::I18n)
########### install files ###############
INSTALL(TARGETS skrooge_add_operation DESTINATION ${KDE_INSTALL_QTPLUGINDIR})
INSTALL(FILES ${PROJECT_SOURCE_DIR}/org.kde.plasma-runner-skrooge-add-operation.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR})
ENDIF()
diff --git a/plugins/krunner/skrooge_add_operation/org.kde.plasma-runner-skrooge-add-operation.desktop b/plugins/krunner/skrooge_add_operation/org.kde.plasma-runner-skrooge-add-operation.desktop
index 3b2667f17..2074eda3b 100644
--- a/plugins/krunner/skrooge_add_operation/org.kde.plasma-runner-skrooge-add-operation.desktop
+++ b/plugins/krunner/skrooge_add_operation/org.kde.plasma-runner-skrooge-add-operation.desktop
@@ -1,73 +1,73 @@
[Desktop Entry]
Name=Skrooge
Name[bs]=Skrooge
Name[ca]=Skrooge
Name[ca@valencia]=Skrooge
Name[cs]=Skrooge
Name[da]=Skrooge
Name[de]=Skrooge
Name[el]=Skrooge
Name[en_GB]=Skrooge
Name[eo]=Skrooge
Name[es]=Skrooge
Name[et]=Skrooge
Name[fi]=Skrooge
Name[fr]=Skrooge
Name[gl]=Skrooge
Name[hu]=Skrooge
Name[it]=Skrooge
Name[lt]=Skrooge
Name[nb]=Skrooge
Name[nl]=Skrooge
Name[pl]=Skrooge
Name[pt]=Skrooge
Name[pt_BR]=Skrooge
Name[ru]=Skrooge
Name[sk]=Skrooge
Name[sv]=Skrooge
Name[tr]=Skrooge
Name[uk]=Skrooge
Name[x-test]=xxSkroogexx
Name[zh_CN]=Skrooge
Name[zh_TW]=Skrooge
Comment=Add a new operation in skrooge
Comment[bs]=Dodaj novu operaciju u skrooge
Comment[ca]=Afegeix una operació nova en l'Skrooge
Comment[ca@valencia]=Afig una operació nova en l'Skrooge
Comment[cs]=Přidat novou operaci ve skrooge
Comment[da]=Tilføj en ny operation i skrooge
Comment[de]=Fügt einen neue Vorgang in Skrooge hinzu
Comment[el]=Προσθήκη νέας πράξης στο skrooge
Comment[en_GB]=Add a new operation in skrooge
Comment[es]=Añadir una nueva operación a Skrooge
Comment[et]=Uue tehingu lisamine Skrooges
Comment[fi]=Lisää Skroogeen uusi toiminto
Comment[fr]=Ajouter une nouvelle opération à Skrooge
Comment[gl]=Engadir unha nova operación en Skrooge.
Comment[hu]=Új művelet hozzáadása a skrooge-ba
Comment[it]=Aggiungi una nuova operazione in skrooge
Comment[lt]=Pridėti naują skrooge operaciją
Comment[nb]=Legg til ny operasjon i skrooge
Comment[nl]=Een nieuwe operatie toevoegen aan skrooge
Comment[pl]=Dodaj nową operację w skrooge
Comment[pt]=Adicionar uma nova operação no Skrooge
Comment[pt_BR]=Adicione uma nova operação no Skrooge
Comment[ru]=Добавление новой операции в Skrooge
Comment[sk]=Pridať novú operáciu do Skrooge
Comment[sv]=Lägg till en ny operation i Skrooge
Comment[tr]=Skrooge için yeni bir işlem ekle
Comment[uk]=Додавання нової операції у Skrooge
Comment[x-test]=xxAdd a new operation in skroogexx
Comment[zh_TW]=在 skrooge 裡新增操作
X-KDE-ServiceTypes=Plasma/Runner
Type=Service
Icon=skrooge
X-KDE-Library=skrooge_add_operation
X-KDE-PluginInfo-Author=Stephane MANKOWSKI
X-KDE-PluginInfo-Email=stephane@mankowski.fr
X-KDE-PluginInfo-Name=skroogeaddoperation
-X-KDE-PluginInfo-Website=http://skrooge.org/
+X-KDE-PluginInfo-Website=https://skrooge.org/
X-KDE-PluginInfo-Category=Qt;KDE;Office;Finance;
X-KDE-PluginInfo-Version=1.0
X-KDE-PluginInfo-License=LGPL
X-KDE-PluginInfo-EnabledByDefault=true
diff --git a/plugins/krunner/skrooge_add_operation/skgaddoperation.cpp b/plugins/krunner/skrooge_add_operation/skgaddoperation.cpp
index f1d9c6adb..7faddf774 100644
--- a/plugins/krunner/skrooge_add_operation/skgaddoperation.cpp
+++ b/plugins/krunner/skrooge_add_operation/skgaddoperation.cpp
@@ -1,108 +1,108 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#include "skgaddoperation.h"
#include <qdir.h>
#include <qicon.h>
#include <qsavefile.h>
#include <qstringbuilder.h>
#include <qtextstream.h>
#include <quuid.h>
#include <klocalizedstring.h>
#include <kmessagebox.h>
SKGAddOperation::SKGAddOperation(QObject* iParent, const QVariantList& args)
: AbstractRunner(iParent, args)
{
setIgnoredTypes(Plasma::RunnerContext::NetworkLocation |
Plasma::RunnerContext::FileSystem);
setPriority(HighPriority);
setHasRunOptions(false);
}
void SKGAddOperation::init()
{
reloadConfiguration();
}
void SKGAddOperation::reloadConfiguration()
{
KConfigGroup c = config();
m_triggerWord = c.readEntry("buy", i18nc("default keyword for krunner plugin", "buy"));
if (!m_triggerWord.isEmpty()) {
m_triggerWord.append(' ');
}
QList<Plasma::RunnerSyntax> listofSyntaxes;
Plasma::RunnerSyntax syntax(QStringLiteral("%1:q:").arg(m_triggerWord), i18n("Add a new operation in skrooge"));
syntax.setSearchTermDescription(i18n("amount payee"));
syntax.addExampleQuery(i18nc("Example of krunner command", "%1 10 computer", m_triggerWord));
listofSyntaxes.append(syntax);
setSyntaxes(listofSyntaxes);
}
void SKGAddOperation::match(Plasma::RunnerContext& iContext)
{
QString query = iContext.query();
if (!query.startsWith(m_triggerWord)) {
return;
}
query = query.remove(0, m_triggerWord.length());
Plasma::QueryMatch m(this);
m.setText(i18n("Add operation %1", query));
m.setData(query);
m.setIcon(QIcon::fromTheme(QStringLiteral("skrooge")));
m.setId(query);
iContext.addMatch(m);
}
void SKGAddOperation::run(const Plasma::RunnerContext& iContext, const Plasma::QueryMatch& iMatch)
{
Q_UNUSED(iContext)
QString dirName = QDir::homePath() % "/.skrooge/";
QDir().mkpath(dirName);
QString fileName = dirName % "add_operation_" % QUuid::createUuid().toString() % ".txt";
QSaveFile file(fileName);
if (file.open(QIODevice::WriteOnly)) {
QTextStream stream(&file);
stream << "buy" << endl;
stream << QDate::currentDate().toString(QStringLiteral("yyyy-MM-dd")) << endl;
QString s = iMatch.id().remove(0, QStringLiteral("skroogeaddoperation_").length());
int pos = s.indexOf(QStringLiteral(" "));
if (pos == -1) {
stream << s << endl;
stream << "" << endl;
} else {
stream << s.left(pos).trimmed() << endl;
stream << s.right(s.length() - pos - 1).trimmed() << endl;
}
// Close file
file.commit();
KMessageBox::information(nullptr, i18nc("Information message", "Operation created"));
} else {
KMessageBox::error(nullptr, i18nc("Error message: Could not create a file", "Creation of file %1 failed", fileName));
}
}
K_EXPORT_PLASMA_RUNNER(skroogeaddoperation, SKGAddOperation)
#include "skgaddoperation.moc"
diff --git a/plugins/krunner/skrooge_add_operation/skgaddoperation.h b/plugins/krunner/skrooge_add_operation/skgaddoperation.h
index 7ae691ea3..1dd468660 100644
--- a/plugins/krunner/skrooge_add_operation/skgaddoperation.h
+++ b/plugins/krunner/skrooge_add_operation/skgaddoperation.h
@@ -1,70 +1,70 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGADDOPERATION_H
#define SKGADDOPERATION_H
#include <krunner/abstractrunner.h>
/**
* @brief An KRunner addon to create a new operation
*
*/
class SKGAddOperation : public Plasma::AbstractRunner
{
Q_OBJECT
public:
/**
* @brief The constructor
*
* @param iParent The parent object
* @param args The list of arguments
*/
SKGAddOperation(QObject* iParent, const QVariantList& args);
/**
* @brief Check if the user input match
*
* @param iContext The KRunner context
* @return void
*/
void match(Plasma::RunnerContext& iContext) override;
/**
* @brief Execute the creation of operation
*
* @param iContext The KRunner context
* @param iMatch The query match
* @return void
*/
void run(const Plasma::RunnerContext& iContext, const Plasma::QueryMatch& iMatch) override;
/**
* @brief Reload the configuration
*
* @return void
*/
void reloadConfiguration() override;
protected Q_SLOTS:
void init() override;
private:
QString m_triggerWord;
};
#endif
diff --git a/plugins/skrooge/CMakeLists.txt b/plugins/skrooge/CMakeLists.txt
index 7aa32001d..e32052582 100644
--- a/plugins/skrooge/CMakeLists.txt
+++ b/plugins/skrooge/CMakeLists.txt
@@ -1,49 +1,49 @@
#***************************************************************************
#* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
#* *
#* 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 <http://www.gnu.org/licenses/> *
+#* along with this program. If not, see <https://www.gnu.org/licenses/> *
#***************************************************************************
ADD_SUBDIRECTORY(skrooge_bank)
ADD_SUBDIRECTORY(skrooge_budget)
ADD_SUBDIRECTORY(skrooge_calculator)
ADD_SUBDIRECTORY(skrooge_categories)
ADD_SUBDIRECTORY(skrooge_importexport)
ADD_SUBDIRECTORY(skrooge_operation)
ADD_SUBDIRECTORY(skrooge_report)
ADD_SUBDIRECTORY(skrooge_scheduled)
ADD_SUBDIRECTORY(skrooge_search)
ADD_SUBDIRECTORY(skrooge_payee)
ADD_SUBDIRECTORY(skrooge_tracker)
ADD_SUBDIRECTORY(skrooge_unit)
INSTALL(DIRECTORY . DESTINATION ${KDE_INSTALL_DATADIR}/skrooge/html FILES_MATCHING PATTERN "*.txt"
PATTERN ".svn" EXCLUDE
PATTERN "CMakeLists.txt" EXCLUDE
PATTERN "CMakeFiles" EXCLUDE
PATTERN "grantlee_filters" EXCLUDE
PATTERN "Testing" EXCLUDE)
INSTALL(DIRECTORY . DESTINATION ${KDE_INSTALL_DATADIR}/skrooge/html FILES_MATCHING PATTERN "*.html"
PATTERN ".svn" EXCLUDE
PATTERN "CMakeLists.txt" EXCLUDE
PATTERN "CMakeFiles" EXCLUDE
PATTERN "grantlee_filters" EXCLUDE
PATTERN "Testing" EXCLUDE)
INSTALL(DIRECTORY . DESTINATION ${KDE_INSTALL_DATADIR}/skrooge/html FILES_MATCHING PATTERN "*.qml"
PATTERN ".svn" EXCLUDE
PATTERN "CMakeLists.txt" EXCLUDE
PATTERN "CMakeFiles" EXCLUDE
PATTERN "grantlee_filters" EXCLUDE
PATTERN "Testing" EXCLUDE)
INSTALL(FILES skrooge_monthly.knsrc DESTINATION ${CONFIG_INSTALL_DIR})
diff --git a/plugins/skrooge/dark.txt b/plugins/skrooge/dark.txt
index 43c88702d..c4e73dd50 100644
--- a/plugins/skrooge/dark.txt
+++ b/plugins/skrooge/dark.txt
@@ -1,161 +1,161 @@
<!--***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************-->
<?xml version="1.0" encoding="utf-8"?>
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml">
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="https://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8" />
<meta http-equiv="Content-Style-Type" content="text/css" />
<style type="text/css">
body
{
background-color: #FFFFFF;
font-size : small;
font-family : {{ font_family }};
}
h1
{
text-decoration: underline;
color: #000000;
}
h2
{
text-decoration: underline;
color: #999999;
}
.table
{
border: thin solid #000000;
border-collapse: collapse;
background-color: #000000;
}
.tabletitle
{
background-color: #000000;
color : #FFFFFF;
font-weight : bold;
font-size : normal;
}
.tabletotal
{
background-color: #999999;
color : #FFFFFF;
font-weight : bold;
}
tr
{
background-color: #FFFFFF;
padding: 2px;
}
td
{
padding: 2px;
white-space: nowrap;
}
</style>
</head>
<body>
<table>
<tr>
<td>
<img src="{{ logo_black }}" height="128" width="128"/>
</td>
<td align="left">
<h1>{{ title_main }}</h1>
<small>Date: {{ current_date }}</small><br/>
<small>File name: {{ document.fileName }}</small><br/>
</td>
</tr>
</table>
<h2>{{ title_personal_finance_score }}</h2>
{% include "default/personal_finance_score.html" %}
<h2>{{ document|display:"f_CURRENTAMOUNT_INCOME" }} &amp; {{ document|display:"f_CURRENTAMOUNT_EXPENSE" }} *</h2>
<table>
<tr>
<td valign="top">
{% include "default/income_vs_expenditure_table.html" %}
</td>
<td align="top">
<img src="http://chart.apis.google.com/chart?cht=bvs&chbh=100&chxt=x,y&chxr=1,0,{{ report.income_vs_expenditure.4.3 }}&chco=000000|999999&chd=t:{{ report.income_vs_expenditure.2.3 }},{{ report.income_vs_expenditure.1.3 }}&chds=0,{{ report.income_vs_expenditure.4.3 }}&chs=300x100&chl={{ document|display:"f_CURRENTAMOUNT_EXPENSE" }} {{ report.period }}|{{ document|display:"f_CURRENTAMOUNT_INCOME" }} {{ report.period }}"/>
</td>
</tr>
</table>
<table>
<tr>
<td valign="top">
<h2>{{ title_main_categories }}</h2>
<table>
<tr>
<td align="center">
{% include "default/categories_previous_period_table.html" %}
<img src="http://chart.apis.google.com/chart?cht=p3&chco=000000&chd=t:{{ report.categories_previous_period.1.2 }},{{ report.categories_previous_period.2.2 }},{{ report.categories_previous_period.3.2 }},{{ report.categories_previous_period.4.2 }},{{ report.categories_previous_period.5.2 }}&chs=300x100&chl=1|2|3|4|5&chds=0,400000000" />
</td>
<td align="center">
{% include "default/categories_period_table.html" %}
<img src="http://chart.apis.google.com/chart?cht=p3&chco=000000&chd=t:{{ report.categories_period.1.2 }},{{ report.categories_period.2.2 }},{{ report.categories_period.3.2 }},{{ report.categories_period.4.2 }},{{ report.categories_period.5.2 }}&chs=300x100&chl=1|2|3|4|5&chds=0,400000000" />
</tr>
</table>
</td>
<td valign="top">
<h2>{{ title_variations }}</h2>
{% for item in report.categories_variations %}
<li> {{ item|safe }}</li>
{% endfor %}
</td>
</tr>
</table>
<table>
<tr>
<td valign="top">
<h2>{{ title_account }} *</h2>
{% include "default/account_table.html" %}
</td>
<td valign="top">
<h2>{{ title_budget }}</h2>
{% include "default/budget_table.html" %}
</td>
</tr>
</table>
<table>
<tr>
<td valign="top">
<h2>{{ title_unit }} *</h2>
{% include "default/unit_table.html" %}
</td>
<td valign="top">
<h2>{{ title_portfolio }} *</h2>
{% include "default/portfolio.html" %}
<img src="http://chart.apis.google.com/chart?cht=p3&chco=000000&chd=t:{% for item in report.portfolio %}{% if forloop.first %}{% else %}{% if forloop.last %}{{ item.5 }}{% else %}{{ item.5 }},{% endif %}{% endif %}{% endfor %}&chs=300x100&chl={% for item in report.portfolio %}{% if forloop.first %}{% else %}{% if forloop.last %}{{ item.0 }}{% else %}{{ item.0 }}|{% endif %}{% endif %}{% endfor %}&chds=0,400000000" />
</td>
</tr>
</table>
</br>
<small>{{ current_date }} - {{ document.fileName }}</small>
<p><small>* {{ msg_amount_unit_date }}</small></p>
</body>
</html>
diff --git a/plugins/skrooge/default.txt b/plugins/skrooge/default.txt
index 07024ce9c..010ec4993 100644
--- a/plugins/skrooge/default.txt
+++ b/plugins/skrooge/default.txt
@@ -1,134 +1,134 @@
<!--***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************-->
<?xml version="1.0" encoding="utf-8"?>
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml">
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="https://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8" />
<meta http-equiv="Content-Style-Type" content="text/css" />
<style type="text/css">
body
{
background-color: #{{ color_normalbackground }};
color: #{{ color_normaltext }};
font-size : small;
font-family : {{ font_family }};
}
h1
{
text-decoration: underline;
color: #{{ color_activetext }};
}
h2
{
text-decoration: underline;
color: #{{ color_inactivetext }};
}
.table
{
border: thin solid #000000;
border-collapse: collapse;
}
.tabletitle
{
background-color: #6495ed;
color : #FFFF33;
font-weight : bold;
font-size : normal;
}
.tabletotal
{
background-color: #{{ color_activebackground }};
font-weight : bold;
}
tr
{
padding: 2px;
}
td
{
padding: 2px;
white-space: nowrap;
}
</style>
</head>
<body>
<table>
<tr>
<td>
<img src="{{ logo }}" height="128" width="128"/>
</td>
<td align="left">
<h1>{{ title_main }}</h1>
<small>Date: {{ current_date }}</small><br/>
<small>File name: {{ document.fileName }}</small><br/>
</td>
</tr>
</table>
<h2>{{ title_personal_finance_score }}</h2>
{% include "default/personal_finance_score.html" %}
<h2>{{ document|display:"f_CURRENTAMOUNT_INCOME" }} &amp; {{ document|display:"f_CURRENTAMOUNT_EXPENSE" }} *</h2>
{% include "default/income_vs_expenditure_table.html" %}
<img src="http://chart.apis.google.com/chart?cht=bvs&chxs=0,{{ color_normaltext }}|1,{{ color_normaltext }}&chbh=100&chxt=x,y&chxr=1,0,{{ report.income_vs_expenditure.4.3 }}&chf=bg,s,{{ color_normalbackground }}&chco={{ color_negativetext }}|{{ color_positivetext }}&chd=t:{{ report.income_vs_expenditure.2.3 }},{{ report.income_vs_expenditure.1.3 }}&chds=0,{{ report.income_vs_expenditure.4.3 }}&chs=300x200&chl={{ document|display:"f_CURRENTAMOUNT_EXPENSE" }}|{{ document|display:"f_CURRENTAMOUNT_INCOME" }}&chts={{ color_normaltext }}&chtt={{ document|display:"f_CURRENTAMOUNT_EXPENSE" }} vs {{ document|display:"f_CURRENTAMOUNT_INCOME" }}|{{ report.period }}"/>
<h2>{{ title_budget }}</h2>
{% include "default/budget_table.html" %}
<h2>{{ title_main_categories }}</h2>
<table>
<tr>
<td align="center">
{% include "default/categories_previous_period_table.html" %}
<img src="http://chart.apis.google.com/chart?cht=p3&chf=bg,s,{{ color_normalbackground }}&chco={{ color_negativetext }}&chd=t:{{ report.categories_previous_period.1.2 }},{{ report.categories_previous_period.2.2 }},{{ report.categories_previous_period.3.2 }},{{ report.categories_previous_period.4.2 }},{{ report.categories_previous_period.5.2 }}&chs=300x100&chl=1|2|3|4|5&chds=0,400000000" />
</td>
<td align="center">
{% include "default/categories_period_table.html" %}
<img src="http://chart.apis.google.com/chart?cht=p3&chf=bg,s,{{ color_normalbackground }}&chco={{ color_negativetext }}&chd=t:{{ report.categories_period.1.2 }},{{ report.categories_period.2.2 }},{{ report.categories_period.3.2 }},{{ report.categories_period.4.2 }},{{ report.categories_period.5.2 }}&chs=300x100&chl=1|2|3|4|5&chds=0,400000000" />
</tr>
</table>
<h2>{{ title_variations }}</h2>
{% include "default/categories_variations.html" %}
<h2>{{ title_account }} *</h2>
{% include "default/bank_table.html" %}
<br/>
{% include "default/account_table.html" %}
<h2>{{ title_unit }} *</h2>
{% include "default/unit_table.html" %}
<h2>{{ title_portfolio }} *</h2>
{% include "default/portfolio.html" %}
{% if report.portfolio|length %}
<img src="http://chart.apis.google.com/chart?cht=p3&chf=bg,s,{{ color_normalbackground }}&chco={{ color_negativetext }}&chd=t:{% for item in report.portfolio %}{% if forloop.first %}{% else %}{% if forloop.last %}{{ item.5 }}{% else %}{{ item.5 }},{% endif %}{% endif %}{% endfor %}&chs=300x100&chl={% for item in report.portfolio %}{% if forloop.first %}{% else %}{% if forloop.last %}{{ item.0 }}{% else %}{{ item.0 }}|{% endif %}{% endif %}{% endfor %}&chds=0,400000000" />
{% endif %}
<h2>{{ title_highlighted }}</h2>
{% include "default/highlighted_operations.html" %}
<p><small>* {{ msg_amount_unit_date }}</small></p>
</body>
</html>
diff --git a/plugins/skrooge/default/SKGValue.qml b/plugins/skrooge/default/SKGValue.qml
index c47c6e664..0f34a163b 100644
--- a/plugins/skrooge/default/SKGValue.qml
+++ b/plugins/skrooge/default/SKGValue.qml
@@ -1,59 +1,59 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
import QtQuick 2.0
import QtQuick.Controls 1.0
import QtQuick.Layouts 1.0
Label {
property var value: null
property var max: null
property var bold: false
property var url: ""
property var backgroundColor: "#FF0000"
color: '#' + (value == null || max != null ? color_normaltext : (value < 0 ? color_negativetext : color_positivetext))
Layout.fillWidth: true
Layout.alignment: Qt.AlignVCenter | Qt.AlignRight
font.pixelSize: report.point_size
font.bold: bold
MouseArea {
anchors.fill: parent
cursorShape: url.length ? Qt.PointingHandCursor : Qt.ArrowCursor
onClicked: {
if (url.length) panel.openPage(url)
}
}
Rectangle {
anchors.top: parent.top
anchors.bottom: parent.bottom
anchors.left: parent.left
color: parent.backgroundColor
width: parent.max == null || parent.max == 0 ? 0 : Math.abs(parent.width * parent.value / parent.max)
z: -1
visible: parent.value != null && parent.max != null
Behavior on width {
NumberAnimation {
duration: 300
easing.type: Easing.InOutQuad
}
}
}
}
diff --git a/plugins/skrooge/default/account_table.qml b/plugins/skrooge/default/account_table.qml
index 92e8b9e7d..063a51b00 100644
--- a/plugins/skrooge/default/account_table.qml
+++ b/plugins/skrooge/default/account_table.qml
@@ -1,74 +1,74 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
import QtQuick 2.0
import QtQuick.Controls 1.0
import QtQuick.Layouts 1.0
RowLayout {
id: grid
property var m: report.account_table
spacing: 2
function maxValues(m, id) {
var output = 0
for (var i = 1; i < m.length; i++) {
if (!m[i][0] && Math.abs(m[i][id]) > output)
output = Math.abs(m[i][id])
}
return output
}
ColumnLayout {
spacing: 0
// Set titles
Repeater {
model: m
Label {
Layout.fillWidth: true
font.bold: index == 0 || modelData[0]
font.pixelSize: report.point_size
text: modelData[1]
horizontalAlignment: index == 0 ? Text.AlignHCenter : Text.AlignLeft
}
}
}
Repeater {
model: 6
ColumnLayout {
spacing: 0
property var modelId: modelData + 2
// Set values
Repeater {
model: m
SKGValue {
Layout.fillWidth: true
horizontalAlignment: index == 0 ? Text.AlignHCenter : Text.AlignRight
font.bold: index == 0 || modelData[0]
value: index == 0 || parent.modelId == 4 || parent.modelId == 7 ? null : modelData[parent.modelId]
max: parent.modelId == 4 || parent.modelId == 7 || modelData[0] ? null : maxValues(m, parent.modelId)
backgroundColor: '#' + (value == null || value < 0 ? color_negativetext : color_positivetext)
text: index == 0 ? modelData[parent.modelId] : parent.modelId == 4 || parent.modelId == 7 ? document.formatPercentage(modelData[parent.modelId]) : document.formatPrimaryMoney(modelData[parent.modelId])
url: font.bold || parent.modelId != 6 ? "" : "skg://Skrooge_operation_plugin/?operationWhereClause=t_ACCOUNT='"+ modelData[1] + "'&title="+ modelData[1] + "&title_icon=view-bank-account"
}
}
}
}
}
diff --git a/plugins/skrooge/default/alarm.qml b/plugins/skrooge/default/alarm.qml
index 2b05f0c16..56e56908d 100644
--- a/plugins/skrooge/default/alarm.qml
+++ b/plugins/skrooge/default/alarm.qml
@@ -1,41 +1,41 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
import QtQuick 2.0
import QtQuick.Controls 1.0
import QtQuick.Layouts 1.0
RowLayout {
id: grid
property var m: report.alarms
spacing: 2
ColumnLayout {
spacing: 0
// Set values
Repeater {
model: m
SKGValue {
horizontalAlignment: Text.AlignHCenter
value: modelData[1]
max: modelData[2]
backgroundColor: '#' + (value == null || value < 0.7 * max ? color_positivetext : value < 0.9 * max ? color_neutraltext : color_negativetext)
text: modelData[0]
}
}
}
}
diff --git a/plugins/skrooge/default/bank_table.qml b/plugins/skrooge/default/bank_table.qml
index f372392d7..395ddd5ea 100644
--- a/plugins/skrooge/default/bank_table.qml
+++ b/plugins/skrooge/default/bank_table.qml
@@ -1,74 +1,74 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
import QtQuick 2.0
import QtQuick.Controls 1.0
import QtQuick.Layouts 1.0
RowLayout {
id: grid
property var m: report.bank_table
spacing: 2
function maxValues(m, id) {
var output = 0
for (var i = 1; i < m.length; i++) {
if (!m[i][0] && Math.abs(m[i][id]) > output)
output = Math.abs(m[i][id])
}
return output
}
ColumnLayout {
spacing: 0
// Set titles
Repeater {
model: m
Label {
Layout.fillWidth: true
font.bold: index == 0 || modelData[0]
font.pixelSize: report.point_size
text: modelData[1]
horizontalAlignment: index == 0 ? Text.AlignHCenter : Text.AlignLeft
}
}
}
Repeater {
model: 6
ColumnLayout {
spacing: 0
property var modelId: index + 2
// Set values
Repeater {
model: m
SKGValue {
Layout.fillWidth: true
horizontalAlignment: index == 0 ? Text.AlignHCenter : Text.AlignRight
font.bold: index == 0 || modelData[0]
value: index == 0 || parent.modelId == 4 || parent.modelId == 7 ? null : modelData[parent.modelId]
max: parent.modelId == 4 || parent.modelId == 7 || modelData[0] ? null : maxValues(m, parent.modelId)
backgroundColor: '#' + (value == null || value < 0 ? color_negativetext : color_positivetext)
text: index == 0 ? modelData[parent.modelId] : parent.modelId == 4 || parent.modelId == 7 ? document.formatPercentage(modelData[parent.modelId]) : document.formatPrimaryMoney(modelData[parent.modelId])
url: font.bold || parent.modelId != 6 ? "" : "skg://Skrooge_operation_plugin/?operationWhereClause=t_BANK='"+ modelData[1] + "'&title="+ modelData[1] + "&title_icon=view-bank-account"
}
}
}
}
}
diff --git a/plugins/skrooge/default/bank_table_light.qml b/plugins/skrooge/default/bank_table_light.qml
index 48e0a3ce9..4e885d7d5 100644
--- a/plugins/skrooge/default/bank_table_light.qml
+++ b/plugins/skrooge/default/bank_table_light.qml
@@ -1,70 +1,70 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
import QtQuick 2.0
import QtQuick.Controls 1.0
import QtQuick.Layouts 1.0
RowLayout {
id: grid
property var m: report.bank_table
spacing: 2
function maxValues(m, id) {
var output = 0
for (var i = 1; i < m.length; i++) {
if (!m[i][0] && Math.abs(m[i][id]) > output)
output = Math.abs(m[i][id])
}
return output
}
ColumnLayout {
spacing: 0
// Set titles
Repeater {
model: m
Label {
Layout.fillWidth: true
font.bold: index == 0 || modelData[0]
font.pixelSize: report.point_size
text: modelData[1]
horizontalAlignment: index == 0 ? Text.AlignHCenter : Text.AlignLeft
}
}
}
ColumnLayout {
spacing: 0
// Set values
Repeater {
model: m
SKGValue {
Layout.fillWidth: true
horizontalAlignment: index == 0 ? Text.AlignHCenter : Text.AlignRight
font.bold: index == 0 || modelData[0]
value: index == 0 ? null : modelData[6]
max: modelData[0] ? null : maxValues(m, 6)
backgroundColor: '#' + (value == null || value < 0 ? color_negativetext : color_positivetext)
text: index == 0 ? modelData[6] : document.formatPrimaryMoney(modelData[6])
url: font.bold ? "" : "skg://Skrooge_operation_plugin/?operationWhereClause=t_BANK='"+ modelData[1] + "'&title="+ modelData[1] + "&title_icon=view-bank-account"
}
}
}
}
diff --git a/plugins/skrooge/default/budget_table.qml b/plugins/skrooge/default/budget_table.qml
index 6501a953f..6aa546317 100644
--- a/plugins/skrooge/default/budget_table.qml
+++ b/plugins/skrooge/default/budget_table.qml
@@ -1,77 +1,77 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
import QtQuick 2.0
import QtQuick.Controls 1.0
import QtQuick.Layouts 1.0
RowLayout {
id: grid
property var m: report.budget_table
spacing: 2
ColumnLayout {
spacing: 0
// Set titles
Repeater {
model: m
Label {
Layout.fillWidth: true
font.bold: index == 0 || modelData[0]
font.pixelSize: report.point_size
text: modelData[1]
horizontalAlignment: index == 0 ? Text.AlignHCenter : Text.AlignLeft
}
}
}
Repeater {
model: [2, 3, 4]
ColumnLayout {
spacing: 0
property var modelId: modelData
// Set values
Repeater {
model: m
SKGValue {
Layout.fillWidth: true
horizontalAlignment: index == 0 ? Text.AlignHCenter : Text.AlignRight
font.bold: index == 0 || modelData[0]
value: index == 0 ? null : modelData[parent.modelId]
backgroundColor: '#' + (value == null || value < 0 ? color_negativetext : color_positivetext)
text: index == 0 ? modelData[parent.modelId] : parent.modelId!=2 ? document.formatPrimaryMoney(modelData[parent.modelId]) : document.formatPrimaryMoney(modelData[5])
Timer {
interval: 2000; running: index != 0 && parent.modelId==2 && document.formatPrimaryMoney(modelData[5])!=document.formatPrimaryMoney(modelData[2]); repeat: true
onTriggered: {
if(parent.text == document.formatPrimaryMoney(modelData[5])) {
parent.text = document.formatPrimaryMoney(modelData[2])
parent.font.strikeout = true
}else {
parent.text = document.formatPrimaryMoney(modelData[5])
parent.font.strikeout = false
}
}
}
}
}
}
}
}
diff --git a/plugins/skrooge/default/categories_period_table.qml b/plugins/skrooge/default/categories_period_table.qml
index 288a622bc..4c0a5814c 100644
--- a/plugins/skrooge/default/categories_period_table.qml
+++ b/plugins/skrooge/default/categories_period_table.qml
@@ -1,73 +1,73 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
import QtQuick 2.0
import QtQuick.Controls 1.0
import QtQuick.Layouts 1.0
RowLayout {
id: grid
property var m: report.categories_period
property var max: maxValues(m)
spacing: 2
function maxValues(m) {
var output = -1
for (var i = 1; i < m.length; i++) {
if (m[i][2] > output)
output = m[i][2]
}
return output
}
ColumnLayout {
spacing: 0
// Set titles
Repeater {
model: m
Label {
Layout.fillWidth: true
font.bold: index == 0
font.pixelSize: report.point_size
text: index == 0 ? modelData[1] : index + ": " + modelData[1]
horizontalAlignment: index == 0 ? Text.AlignHCenter : Text.AlignLeft
}
}
}
ColumnLayout {
spacing: 0
// Set values
Repeater {
model: m
SKGValue {
Layout.fillWidth: true
horizontalAlignment: index == 0 ? Text.AlignHCenter : Text.AlignRight
font.bold: index == 0
value: index == 0 ? null : modelData[2]
max: grid.max
text: index == 0 ? modelData[2] : document.formatPrimaryMoney(modelData[2])
backgroundColor: '#' + color_negativetext
url: index == 0 ? "" : "skg://Skrooge_operation_plugin/SKGOPERATION_CONSOLIDATED_DEFAULT_PARAMETERS/?operationTable=v_suboperation_consolidated&operationWhereClause="
+ modelData[3] + "&title=" + modelData[1] + "/"
+ m[0][2] + "&title_icon=view-categories"
}
}
}
}
diff --git a/plugins/skrooge/default/categories_variations.qml b/plugins/skrooge/default/categories_variations.qml
index 01d3688d9..bb61a2920 100644
--- a/plugins/skrooge/default/categories_variations.qml
+++ b/plugins/skrooge/default/categories_variations.qml
@@ -1,31 +1,31 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
import QtQuick 2.0
import QtQuick.Controls 1.0
Column {
Repeater {
model: report.categories_variations
Label {
text: modelData
font.pixelSize: report.point_size
horizontalAlignment: Text.AlignLeft
verticalAlignment: Text.AlignVCenter
wrapMode: Text.Wrap
}
}
}
diff --git a/plugins/skrooge/default/categories_variations_issues.qml b/plugins/skrooge/default/categories_variations_issues.qml
index 8538c4d3a..4733a9c3d 100644
--- a/plugins/skrooge/default/categories_variations_issues.qml
+++ b/plugins/skrooge/default/categories_variations_issues.qml
@@ -1,31 +1,31 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
import QtQuick 2.0
import QtQuick.Controls 1.0
Column {
Repeater {
model: report.categories_variations_issues
Label {
text: modelData
font.pixelSize: report.point_size
horizontalAlignment: Text.AlignLeft
verticalAlignment: Text.AlignVCenter
wrapMode: Text.Wrap
}
}
}
diff --git a/plugins/skrooge/default/income_vs_expenditure.qml b/plugins/skrooge/default/income_vs_expenditure.qml
index 864e61a0e..2e3682e9f 100644
--- a/plugins/skrooge/default/income_vs_expenditure.qml
+++ b/plugins/skrooge/default/income_vs_expenditure.qml
@@ -1,167 +1,167 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
import QtQuick 2.0
import QtQuick.Layouts 1.0
import QtQuick.Controls 1.0
GridLayout {
id: widget
columns: 2
property double maxValue: Math.max(incomes1Bar.value, expenditures1Bar.value, incomes2Bar.value, expenditures2Bar.value)
property double totrigger: 1.0
Connections {
target: report
onChanged: {
totrigger = 2.0;
totrigger = 1.0;
}
}
Label{
id: label1
text: period1Widget.text
font.bold: true
font.pixelSize: report.point_size
Layout.columnSpan: 2
}
Label{
text: qsTr("Incomes:")
font.pixelSize: report.point_size
}
SKGValue {
id: incomes1Bar
max: parent.maxValue
value: totrigger*report.getIncomeVsExpenditure(suboperationsWidget.checked, groupedWidget.checked, transferWidget.checked, trackerWidget.checked, period1Widget.whereClause, period2Widget.whereClause)[1][3]
text: document.formatPrimaryMoney(value)
horizontalAlignment: Text.AlignHCenter
backgroundColor: '#' + color_positivetext
url: "skg://skrooge_operation_plugin/" + (suboperationsWidget.checked ? "SKGOPERATION_CONSOLIDATED_DEFAULT_PARAMETERS/" :"") + "?operationTable=" +
(suboperationsWidget.checked ? "v_suboperation_consolidated": "v_operation_display") + "&title_icon=view-bank-account-savings&currentPage=-1&title=" +
qsTr("Incomes of %1").arg(label1.text) +
"&operationWhereClause=" + period1Widget.whereClause + " AND t_TYPEACCOUNT<>'L' AND t_TYPEEXPENSE='+'" +
(groupedWidget.checked ? "" : " AND i_group_id=0") + (transferWidget.checked ? "" : " AND t_TRANSFER='N'") + (trackerWidget.checked ? "" : (suboperationsWidget.checked ? " AND t_REALREFUND=''" : " AND t_REFUND=''"));
}
Label{
text: qsTr("Expenditures:")
font.pixelSize: report.point_size
}
SKGValue {
id: expenditures1Bar
max: parent.maxValue
value: totrigger*report.getIncomeVsExpenditure(suboperationsWidget.checked, groupedWidget.checked, transferWidget.checked, trackerWidget.checked, period1Widget.whereClause, period2Widget.whereClause)[2][3]
text: document.formatPrimaryMoney(value)
horizontalAlignment: Text.AlignHCenter
backgroundColor: '#' + color_negativetext
url: "skg://skrooge_operation_plugin/" + (suboperationsWidget.checked ? "SKGOPERATION_CONSOLIDATED_DEFAULT_PARAMETERS/" :"") + "?operationTable=" +
(suboperationsWidget.checked ? "v_suboperation_consolidated": "v_operation_display") + "&title_icon=view-bank-account-savings&currentPage=-1&title=" +
qsTr("Expenses of %1").arg(label1.text) +
"&operationWhereClause=" + period1Widget.whereClause + " AND t_TYPEACCOUNT<>'L' AND t_TYPEEXPENSE='-'" +
(groupedWidget.checked ? "" : " AND i_group_id=0") + (transferWidget.checked ? "" : " AND t_TRANSFER='N'") + (trackerWidget.checked ? "" : (suboperationsWidget.checked ? " AND t_REALREFUND=''" : " AND t_REFUND=''"));
}
Label{
text: qsTr("Savings:")
font.pixelSize: report.point_size
}
SKGValue {
id: savings1Bar
max: parent.maxValue
value: Math.abs(incomes1Bar.value - expenditures1Bar.value)
text: document.formatPrimaryMoney(incomes1Bar.value - expenditures1Bar.value)
horizontalAlignment: Text.AlignHCenter
backgroundColor: '#' + (incomes1Bar.value - expenditures1Bar.value <0 ? color_negativetext : color_positivetext)
url: "skg://skrooge_operation_plugin/" + (suboperationsWidget.checked ? "SKGOPERATION_CONSOLIDATED_DEFAULT_PARAMETERS/" :"") + "?operationTable=" +
(suboperationsWidget.checked ? "v_suboperation_consolidated": "v_operation_display") + "&title_icon=view-bank-account-savings&currentPage=-1&title=" +
qsTr("Savings of %1").arg(label1.text) +
"&operationWhereClause=" + period1Widget.whereClause + " AND t_TYPEACCOUNT<>'L'" +
(groupedWidget.checked ? "" : " AND i_group_id=0") + (transferWidget.checked ? "" : " AND t_TRANSFER='N'") + (trackerWidget.checked ? "" : (suboperationsWidget.checked ? " AND t_REALREFUND=''" : " AND t_REFUND=''"));
}
Label{
id: label2
text: period2Widget.text
font.bold: true
font.pixelSize: report.point_size
Layout.columnSpan: 2
}
Label{
text: qsTr("Incomes:")
font.pixelSize: report.point_size
}
SKGValue {
id: incomes2Bar
max: parent.maxValue
value: totrigger*report.getIncomeVsExpenditure(suboperationsWidget.checked, groupedWidget.checked, transferWidget.checked, trackerWidget.checked, period1Widget.whereClause, period2Widget.whereClause)[1][2]
text: document.formatPrimaryMoney(value)
horizontalAlignment: Text.AlignHCenter
backgroundColor: '#' + color_positivetext
url: "skg://skrooge_operation_plugin/" + (suboperationsWidget.checked ? "SKGOPERATION_CONSOLIDATED_DEFAULT_PARAMETERS/" :"") + "?operationTable=" +
(suboperationsWidget.checked ? "v_suboperation_consolidated": "v_operation_display") + "&title_icon=view-bank-account-savings&currentPage=-1&title=" +
qsTr("Incomes of %1").arg(label2.text) +
"&operationWhereClause=" + period2Widget.whereClause + " AND t_TYPEACCOUNT<>'L' AND t_TYPEEXPENSE='+'" +
(groupedWidget.checked ? "" : " AND i_group_id=0") + (transferWidget.checked ? "" : " AND t_TRANSFER='N'") + (trackerWidget.checked ? "" : (suboperationsWidget.checked ? " AND t_REALREFUND=''" : " AND t_REFUND=''"));
}
Label{
text: qsTr("Expenditures:")
font.pixelSize: report.point_size
}
SKGValue {
id: expenditures2Bar
max: parent.maxValue
value: totrigger*report.getIncomeVsExpenditure(suboperationsWidget.checked, groupedWidget.checked, transferWidget.checked, trackerWidget.checked, period1Widget.whereClause, period2Widget.whereClause)[2][2]
text: document.formatPrimaryMoney(value)
horizontalAlignment: Text.AlignHCenter
backgroundColor: '#' + color_negativetext
url: "skg://skrooge_operation_plugin/" + (suboperationsWidget.checked ? "SKGOPERATION_CONSOLIDATED_DEFAULT_PARAMETERS/" :"") + "?operationTable=" +
(suboperationsWidget.checked ? "v_suboperation_consolidated": "v_operation_display") + "&title_icon=view-bank-account-savings&currentPage=-1&title=" +
qsTr("Expenses of %1").arg(label2.text) +
"&operationWhereClause=" + period2Widget.whereClause + " AND t_TYPEACCOUNT<>'L' AND t_TYPEEXPENSE='-'" +
(groupedWidget.checked ? "" : " AND i_group_id=0") + (transferWidget.checked ? "" : " AND t_TRANSFER='N'") + (trackerWidget.checked ? "" : (suboperationsWidget.checked ? " AND t_REALREFUND=''" : " AND t_REFUND=''"));
}
Label{
text: qsTr("Savings:")
font.pixelSize: report.point_size
}
SKGValue {
id: savings2Bar
max: parent.maxValue
value: Math.abs(incomes2Bar.value - expenditures2Bar.value)
text: document.formatPrimaryMoney(incomes2Bar.value - expenditures2Bar.value)
horizontalAlignment: Text.AlignHCenter
backgroundColor: '#' + (incomes2Bar.value - expenditures2Bar.value <0 ? color_negativetext : color_positivetext)
url: "skg://skrooge_operation_plugin/" + (suboperationsWidget.checked ? "SKGOPERATION_CONSOLIDATED_DEFAULT_PARAMETERS/" :"") + "?operationTable=" +
(suboperationsWidget.checked ? "v_suboperation_consolidated": "v_operation_display") + "&title_icon=view-bank-account-savings&currentPage=-1&title=" +
qsTr("Savings of %1").arg(label2.text) +
"&operationWhereClause=" + period2Widget.whereClause + " AND t_TYPEACCOUNT<>'L'" +
(groupedWidget.checked ? "" : " AND i_group_id=0") + (transferWidget.checked ? "" : " AND t_TRANSFER='N'") + (trackerWidget.checked ? "" : (suboperationsWidget.checked ? " AND t_REALREFUND=''" : " AND t_REFUND=''"));
}
}
diff --git a/plugins/skrooge/default/interests.qml b/plugins/skrooge/default/interests.qml
index 5aeb836eb..16a51da60 100644
--- a/plugins/skrooge/default/interests.qml
+++ b/plugins/skrooge/default/interests.qml
@@ -1,70 +1,70 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
import QtQuick 2.0
import QtQuick.Controls 1.0
import QtQuick.Layouts 1.0
RowLayout {
id: grid
property var m: report.interests
spacing: 2
function maxValues(m, id) {
var output = 0
for (var i = 1; i < m.length; i++) {
if (!m[i][0] && Math.abs(m[i][id]) > output)
output = Math.abs(m[i][id])
}
return output
}
ColumnLayout {
spacing: 0
// Set titles
Repeater {
model: m
Label {
Layout.fillWidth: true
font.bold: index == 0 || modelData[0]
font.pixelSize: report.point_size
text: modelData[1]
horizontalAlignment: index == 0 ? Text.AlignHCenter : Text.AlignLeft
}
}
}
ColumnLayout {
spacing: 0
// Set values
Repeater {
model: m
SKGValue {
Layout.fillWidth: true
horizontalAlignment: index == 0 ? Text.AlignHCenter : Text.AlignRight
font.bold: index == 0 || modelData[0]
value: index == 0 ? null : modelData[2]
max: modelData[0] ? null : maxValues(m, 2)
backgroundColor: '#' + (value == null || value < 0 ? color_negativetext : color_positivetext)
text: index == 0 ? modelData[2] : document.formatPrimaryMoney(modelData[2])
url: font.bold ? "" : "skg://Skrooge_calculator_plugin/?currentPage=0&account="+ modelData[1] + "&year=" + m[0][2]
}
}
}
}
diff --git a/plugins/skrooge/default/personal_finance_score.qml b/plugins/skrooge/default/personal_finance_score.qml
index f8e83ac41..da03b7693 100644
--- a/plugins/skrooge/default/personal_finance_score.qml
+++ b/plugins/skrooge/default/personal_finance_score.qml
@@ -1,75 +1,75 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
import QtQuick 2.0
import QtQuick.Controls 1.0
Row {
spacing: 5
Rectangle {
id: rect1
width: 50
height: width
color: "#" + report.personal_finance_score_details.color
radius: width / 10
Label {
id: pfstext
text: report.personal_finance_score_details.value.toFixed(2)
fontSizeMode: Text.Fit
minimumPixelSize: 10
font.pixelSize: 72
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
anchors.fill: rect1
}
}
Column {
spacing: 2
Label {
id: t1
width: rect1.width * 4
height: rect1.height / 2
text: '=' + title_networth + ' / ' + title_annual_spending
horizontalAlignment: Text.AlignLeft
verticalAlignment: Text.AlignVCenter
wrapMode: Text.Wrap
}
Label {
id: t2
width: t1.width
height: t1.height
text: '=' + document.formatPrimaryMoney(report.networth) + ' / ' + document.formatPrimaryMoney(report.annual_spending)
horizontalAlignment: Text.AlignLeft
verticalAlignment: Text.AlignVCenter
wrapMode: Text.Wrap
}
Label {
id: msg
width: t1.width
height: t1.height
text: report.personal_finance_score_details.message
fontSizeMode: Text.Fit
minimumPixelSize: 10
font.pixelSize: 72
horizontalAlignment: Text.AlignLeft
verticalAlignment: Text.AlignVCenter
wrapMode: Text.Wrap
}
}
}
diff --git a/plugins/skrooge/default/portfolio.qml b/plugins/skrooge/default/portfolio.qml
index c83027200..c462f7f46 100644
--- a/plugins/skrooge/default/portfolio.qml
+++ b/plugins/skrooge/default/portfolio.qml
@@ -1,58 +1,58 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
import QtQuick 2.0
import QtQuick.Controls 1.0
import QtQuick.Layouts 1.0
RowLayout {
id: grid
property var m: report.portfolio
spacing: 2
function maxValues(m, id) {
var output = 0
for (var i = 1; i < m.length; i++) {
if (Math.abs(m[i][id]) > output)
output = Math.abs(m[i][id])
}
return output
}
Repeater {
model: 7
ColumnLayout {
spacing: 0
property var modelId: modelData + 1
// Set values
Repeater {
model: m
SKGValue {
Layout.fillWidth: true
horizontalAlignment: index == 0 ? Text.AlignHCenter :(parent.modelId <=2 ? Text.AlignLeft : Text.AlignRight)
font.bold: index == 0
value: index == 0 || parent.modelId <=2 ? null : modelData[parent.modelId]
max: index == 0 || parent.modelId <=3 || parent.modelId >=6 ? null : maxValues(m, parent.modelId)
backgroundColor: '#' + (value == null || value < 0 ? color_negativetext : color_positivetext)
text: index == 0 || parent.modelId <=2 ? parent.modelId==7 ? "%" : modelData[parent.modelId] : parent.modelId==7 ? document.formatPercentage(modelData[parent.modelId]) : document.formatPrimaryMoney(modelData[parent.modelId])
url: font.bold || parent.modelId != 5 ? "" : "skg://Skrooge_operation_plugin/?operationWhereClause=t_UNIT='"+ modelData[0] + "'&title=Operations with unit equal to '"+ modelData[1] + "'&title_icon=view-currency-list&currentPage=-1"
}
}
}
}
}
diff --git a/plugins/skrooge/default/scheduled_operations.qml b/plugins/skrooge/default/scheduled_operations.qml
index 6f801a6c5..3069d1ac6 100644
--- a/plugins/skrooge/default/scheduled_operations.qml
+++ b/plugins/skrooge/default/scheduled_operations.qml
@@ -1,46 +1,46 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
import QtQuick 2.0
import QtQuick.Controls 1.0
import QtQuick.Layouts 1.0
ColumnLayout {
id: grid
property var m: report.scheduled_operations
spacing: 0
Repeater {
model: m
Row {
SKGValue {
id: l
text: modelData[1]
url: modelData[2]!="" ? "skg://skrooge_scheduled_plugin/?selection="+modelData[2] : ""
bold: modelData[0]
}
Button {
text: qsTr("Skip")
anchors.top: l.top
anchors.bottom: l.bottom
onClicked: {
panel.openPage("skg://skip_scheduled_operations/?selection="+modelData[2])
}
visible: modelData[2]!=""
}
}
}
}
diff --git a/plugins/skrooge/detailed.txt b/plugins/skrooge/detailed.txt
index fe3a5f2ed..43328c6a8 100644
--- a/plugins/skrooge/detailed.txt
+++ b/plugins/skrooge/detailed.txt
@@ -1,156 +1,156 @@
<!--***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************-->
<?xml version="1.0" encoding="utf-8"?>
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml">
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="https://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8" />
<meta http-equiv="Content-Style-Type" content="text/css" />
<style type="text/css">
body
{
background-color: #{{ color_normalbackground }};
color: #{{ color_normaltext }};
font-size : small;
font-family : {{ font_family }};
}
h1
{
text-decoration: underline;
color: #{{ color_activetext }};
}
h2
{
text-decoration: underline;
color: #{{ color_inactivetext }};
}
.table
{
border: thin solid #000000;
border-collapse: collapse;
}
.tabletitle
{
background-color: #6495ed;
color : #FFFF33;
font-weight : bold;
font-size : normal;
}
.tabletotal
{
background-color: #{{ color_activebackground }};
font-weight : bold;
}
tr
{
padding: 2px;
}
td
{
padding: 2px;
white-space: nowrap;
}
</style>
</head>
<body>
<table>
<tr>
<td>
<img src="{{ logo }}" height="128" width="128"/>
</td>
<td align="left">
<h1>{{ title_main }}</h1>
<small>Date: {{ current_date }}</small><br/>
<small>File name: {{ document.fileName }}</small><br/>
</td>
</tr>
</table>
<h2>{{ title_personal_finance_score }}</h2>
{% include "default/personal_finance_score.html" %}
<h2>{{ document|display:"f_CURRENTAMOUNT_INCOME" }} &amp; {{ document|display:"f_CURRENTAMOUNT_EXPENSE" }} *</h2>
{% include "default/income_vs_expenditure_table.html" %}
<img src="http://chart.apis.google.com/chart?cht=bvs&chxs=0,{{ color_normaltext }}|1,{{ color_normaltext }}&chbh=100&chxt=x,y&chxr=1,0,{{ report.income_vs_expenditure.4.3 }}&chf=bg,s,{{ color_normalbackground }}&chco={{ color_negativetext }}|{{ color_positivetext }}&chd=t:{{ report.income_vs_expenditure.2.3 }},{{ report.income_vs_expenditure.1.3 }}&chds=0,{{ report.income_vs_expenditure.4.3 }}&chs=300x200&chl={{ document|display:"f_CURRENTAMOUNT_EXPENSE" }}|{{ document|display:"f_CURRENTAMOUNT_INCOME" }}&chts={{ color_normaltext }}&chtt={{ document|display:"f_CURRENTAMOUNT_EXPENSE" }} vs {{ document|display:"f_CURRENTAMOUNT_INCOME" }}|{{ report.period }}"/>
<h2>{{ title_budget }}</h2>
{% include "default/budget_table.html" %}
<h2>{{ title_main_categories }}</h2>
<table>
<tr>
<td align="center">
{% include "default/categories_previous_period_table.html" %}
<img src="http://chart.apis.google.com/chart?cht=p3&chf=bg,s,{{ color_normalbackground }}&chco={{ color_negativetext }}&chd=t:{{ report.categories_previous_period.1.2 }},{{ report.categories_previous_period.2.2 }},{{ report.categories_previous_period.3.2 }},{{ report.categories_previous_period.4.2 }},{{ report.categories_previous_period.5.2 }}&chs=300x100&chl=1|2|3|4|5&chds=0,400000000" />
</td>
<td align="center">
{% include "default/categories_period_table.html" %}
<img src="http://chart.apis.google.com/chart?cht=p3&chf=bg,s,{{ color_normalbackground }}&chco={{ color_negativetext }}&chd=t:{{ report.categories_period.1.2 }},{{ report.categories_period.2.2 }},{{ report.categories_period.3.2 }},{{ report.categories_period.4.2 }},{{ report.categories_period.5.2 }}&chs=300x100&chl=1|2|3|4|5&chds=0,400000000" />
</tr>
</table>
<h2>Operations</h2>
<table>
{% for item in document|table:"v_operation_display,1=1 ORDER By d_date, t_ACCOUNT, t_CATEGORY" %}
{% ifequal item|att:"d_DATEMONTH" report.period %}
<tr><td>{{ item|att:"d_date" }}</td><td>{{ item|att:"t_ACCOUNT" }}</td><td>{{ item|att:"f_CURRENTAMOUNT"|money|safe }}</td><td>{{ item|att:"t_CATEGORY" }}</td></tr>
{% endifequal %}
{% ifequal item|att:"d_DATEQUARTER" report.period %}
<tr><td>{{ item|att:"d_date" }}</td><td>{{ item|att:"t_ACCOUNT" }}</td><td>{{ item|att:"f_CURRENTAMOUNT"|money|safe }}</td><td>{{ item|att:"t_CATEGORY" }}</td></tr>
{% endifequal %}
{% ifequal item|att:"d_DATESEMESTER" report.period %}
<tr><td>{{ item|att:"d_date" }}</td><td>{{ item|att:"t_ACCOUNT" }}</td><td>{{ item|att:"f_CURRENTAMOUNT"|money|safe }}</td><td>{{ item|att:"t_CATEGORY" }}</td></tr>
{% endifequal %}
{% ifequal item|att:"d_DATEYEAR" report.period %}
<tr><td>{{ item|att:"d_date" }}</td><td>{{ item|att:"t_ACCOUNT" }}</td><td>{{ item|att:"f_CURRENTAMOUNT"|money|safe }}</td><td>{{ item|att:"t_CATEGORY" }}</td></tr>
{% endifequal %}
{% endfor %}
</table>
<h2>{{ title_variations }}</h2>
{% for item in report.categories_variations %}
<li> {{ item|safe }}</li>
{% endfor %}
<h2>{{ title_account }} *</h2>
{% include "default/bank_table.html" %}
<br/>
{% include "default/account_table.html" %}
<h2>{{ title_unit }} *</h2>
{% include "default/unit_table.html" %}
<h2>{{ title_portfolio }} *</h2>
{% include "default/portfolio.html" %}
<img src="http://chart.apis.google.com/chart?cht=p3&chf=bg,s,{{ color_normalbackground }}&chco={{ color_negativetext }}&chd=t:{% for item in report.portfolio %}{% if forloop.first %}{% else %}{% if forloop.last %}{{ item.5 }}{% else %}{{ item.5 }},{% endif %}{% endif %}{% endfor %}&chs=300x100&chl={% for item in report.portfolio %}{% if forloop.first %}{% else %}{% if forloop.last %}{{ item.0 }}{% else %}{{ item.0 }}|{% endif %}{% endif %}{% endfor %}&chds=0,400000000" />
<h2>{{ title_interests }} *</h2>
{% include "default/interests.html" %}
<h2>{{ title_alarms }} *</h2>
{% include "default/alarm.html" %}
<p><small>* {{ msg_amount_unit_date }}</small></p>
</body>
</html>
diff --git a/plugins/skrooge/main.txt b/plugins/skrooge/main.txt
index fd0118498..f7927f30e 100644
--- a/plugins/skrooge/main.txt
+++ b/plugins/skrooge/main.txt
@@ -1,114 +1,114 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml">
+ "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="https://www.w3.org/1999/xhtml">
<head>
<style type="text/css">
{{ kde_infopage_css|safe }}
{{ kde_infopage_rtl_css|safe }}
body {
font-size: %3px;
font-family : {{ font_family }};
}
</style>
<title>Skrooge</title>
</head>
<body>
<div id="header">
<div id="headerL"><img src="{{ logo }}" height="128" width="128"/></div>
<div id="headerR"></div>
<div id="title">Skrooge</div>
<div id="tagline"></div>
</div>
<!-- the bar -->
<div id="bar">
<div id="barT">
<div id="barTL"></div>
<div id="barTR"></div>
<div id="barTC"></div>
</div>
<div id="barL">
<div id="barR">
<div id="barCenter" class="bar_text">{{ about_shortdescription|safe }}</div>
</div>
</div>
<div id="barB">
<div id="barBL"></div>
<div id="barBR"></div>
<div id="barBC"></div>
</div>
</div>
<!-- the main text box -->
<div id="box">
<div id="boxT">
<div id="boxTL"></div>
<div id="boxTR"></div>
<div id="boxTC"></div>
</div>
<div id="boxL">
<div id="boxR">
<div id="boxCenter">
<h2 style="margin-top: 0px;">{{ about_welcome }} {{about_version}}</h2>
{{ about_maintext|safe }}
</div>
</div>
</div>
<div id="boxB">
<div id="boxBL"></div>
<div id="boxBR"></div>
<div id="boxBC"></div>
</div>
</div>
<div id="footer">
<div id="footerL"></div>
<div id="footerR"></div>
</div>
<!-- the main text box -->
<div id="box">
<div id="boxT">
<div id="boxTL"></div>
<div id="boxTR"></div>
<div id="boxTC"></div>
</div>
<div id="boxL">
<div id="boxR">
<div id="boxCenter">
<h2 style="margin-top: 0px;"><a onclick="genQuote()">{{ about_did_you_know }}</a></h2>
<div id="quote"></div><br/>
</div>
</div>
</div>
<div id="boxB">
<div id="boxBL"></div>
<div id="boxBR"></div>
<div id="boxBC"></div>
</div>
</div>
<div id="footer">
<div id="footerL"></div>
<div id="footerR"></div>
</div>
<script >
function genQuote() {
document.getElementById('quote').innerHTML = quotes[Math.floor(Math.random() * quotes.length)];
}
//quote array
var quotes = [
{% for item in report.tips_of_day %}
"{{ item|replace:"\";\\\""|safe }}",
{% endfor %}
];
genQuote();
</script>
</body>
</html>
diff --git a/plugins/skrooge/responsive.txt b/plugins/skrooge/responsive.txt
index b8e2cb993..0b0b3e0b6 100644
--- a/plugins/skrooge/responsive.txt
+++ b/plugins/skrooge/responsive.txt
@@ -1,388 +1,388 @@
<!--***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************-->
<?xml version="1.0" encoding="utf-8"?>
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml">
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="https://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8" />
<meta http-equiv="Content-Style-Type" content="text/css" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css">
<style>
body {padding-top: 70px; padding-bottom: 70px; }
td {white-space: nowrap;}
@media print {a[href]:after {content: "" !important;}}
meter {
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
width: 200px;
height: 30px;
}
meter::-webkit-meter-bar {
background: #EEE;
box-shadow: 0 2px 3px rgba(0,0,0,0.2) inset;
border-radius: 3px;
}
meter::-webkit-meter-optimum-value {
background: #86CC00; /* Green */
border-radius: 3px;
}
meter::-webkit-meter-suboptimum-value {
background: #FFDB1A; /* Yellow */
border-radius: 3px;
}
meter::-webkit-meter-even-less-good-value {
background: #CC4600; /* Red */
border-radius: 3px;
}
</style>
</head>
<body>
<script src="https://code.jquery.com/jquery.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/js/bootstrap.min.js"></script>
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/highcharts-3d.js"></script>
<div class="navbar navbar-default navbar-fixed-top" role="navigation">
<div class="container">
<div class="navbar-header">
<h1>{{ title_main }}</h1>
</div>
</div>
</div>
<div class="navbar navbar-default navbar-fixed-bottom" role="navigation">
<div class="container">
<small>Date: {{ current_date }}</small><br/>
<small>File name: {{ document.fileName }}</small><br/>
<small>* {{ msg_amount_unit_date }}</small>
</div>
</div>
</div>
<div class="container">
<h2>{{ title_personal_finance_score }}</h2>
<span class="btn btn-{{ report.personal_finance_score_details.level }} btn-lg">{{ report.personal_finance_score_details.value|floatformat }}
<span class="badge">
{{ title_networth }} / {{ title_annual_spending }}</br>
{{ report.networth|money|safe }} / {{ report.annual_spending|money|safe }}
</span>
</span>
<p>{{ report.personal_finance_score_details.message }}</p>
<h2>{{ document|display:"f_CURRENTAMOUNT_INCOME" }} &amp; {{ document|display:"f_CURRENTAMOUNT_EXPENSE" }} *</h2>
{% include "default/income_vs_expenditure_table.html" %}
<div id="chart4" style="height: 300px; width: 600px"></div>
<h2>{{ title_budget }}</h2>
{% include "default/budget_table.html" %}
<h2>{{ title_main_categories }}</h2>
<table>
<tr>
<td align="center">
{% include "default/categories_previous_period_table.html" %}
<div id="chart1" style="height: 300px; width: 300px"></div>
</td>
<td align="center">
{% include "default/categories_period_table.html" %}
<div id="chart2" style="height: 300px; width: 300px"></div>
</tr>
</table>
<h2>{{ title_variations }}</h2>
{% include "default/categories_variations.html" %}
<h2>{{ title_account }} *</h2>
{% include "default/bank_table.html" %}
<div id="chart5" style="height: 300px; width: 400px"></div>
<br/>
{% include "default/account_table.html" %}
<h2>{{ title_unit }} *</h2>
{% include "default/unit_table.html" %}
<h2>{{ title_portfolio }} *</h2>
{% include "default/portfolio.html" %}
{% if report.portfolio|length %}
<div id="chart3" style="height: 300px; width: 400px"></div>
{% endif %}
<h2>{{ title_highlighted }}</h2>
{% include "default/highlighted_operations.html" %}
</div>
<script language="javascript">
var item = document.getElementById("table_unit");
if(item != null) item.className= "table table-bordered table-striped table-condensed";
var item = document.getElementById("table_portfolio");
if(item != null) item.className= "table table-bordered table-striped table-condensed";
var item = document.getElementById("table_income_vs_expenditure");
if(item != null) item.className= "table table-bordered table-striped table-condensed";
var item = document.getElementById("table_categories_previous_period");
if(item != null) item.className= "table table-bordered table-striped table-condensed";
var item = document.getElementById("table_categories_period");
if(item != null) item.className= "table table-bordered table-striped table-condensed";
var item = document.getElementById("table_budget");
if(item != null) item.className= "table table-bordered table-striped table-condensed";
var item = document.getElementById("table_bank");
if(item != null) item.className= "table table-bordered table-striped table-condensed";
var item = document.getElementById("table_account");
if(item != null) item.className= "table table-bordered table-striped table-condensed";
$(function () {
$('#chart1').highcharts({
chart: {
type: 'pie',
options3d: {
enabled: true,
alpha: 45,
beta: 0
}
},
title: {
text: ''
},
tooltip: {
pointFormat: '{point.percentage:.1f}%</b>'
},
plotOptions: {
pie: {
allowPointSelect: false,
depth: 35,
dataLabels: {
enabled: true,
format: '{point.name}'
},
cursor: 'pointer',
point: {
events: {
click: function () {
window.open(this.options.url);
}
}
}
}
},
series: [{
type: 'pie',
name: '{{ title_main_categories }}',
data: [
{% for item in report.categories_previous_period %}
{% if forloop.first %}
{% else %}
{name: '{{ forloop.counter0 }}',
y: {{ item.2 }},
url: 'skg://Skrooge_operation_plugin/SKGOPERATION_CONSOLIDATED_DEFAULT_PARAMETERS/?operationTable=v_suboperation_consolidated&operationWhereClause={{ item.3|encode }}&title={{ item.1|encode }}/{{ report.categories_period.0.2 }}&title_icon=view-categories'}
{% if forloop.last %}{% else %},{% endif %}
{% endif %}
{% endfor %}
]
}]
});
});
$(function () {
$('#chart2').highcharts({
chart: {
type: 'pie',
options3d: {
enabled: true,
alpha: 45,
beta: 0
}
},
title: {
text: ''
},
tooltip: {
pointFormat: '{point.percentage:.1f}%</b>'
},
plotOptions: {
pie: {
allowPointSelect: false,
depth: 35,
dataLabels: {
enabled: true,
format: '{point.name}'
}
}
},
series: [{
type: 'pie',
name: '{{ title_main_categories }}',
data: [
{% for item in report.categories_period %}
{% if forloop.first %}
{% else %}
{name: '{{ forloop.counter0 }}',
y: {{ item.2 }},
url: 'skg://Skrooge_operation_plugin/SKGOPERATION_CONSOLIDATED_DEFAULT_PARAMETERS/?operationTable=v_suboperation_consolidated&operationWhereClause={{ item.3|encode }}&title={{ item.1|encode }}/{{ report.categories_period.0.2 }}&title_icon=view-categories'}
{% if forloop.last %}{% else %},{% endif %}
{% endif %}
{% endfor %}
]
}]
});
});
$(function () {
$('#chart3').highcharts({
chart: {
type: 'pie',
options3d: {
enabled: true,
alpha: 45,
beta: 0
}
},
title: {
text: ''
},
tooltip: {
pointFormat: '{point.percentage:.1f}%</b>'
},
plotOptions: {
pie: {
allowPointSelect: false,
depth: 35,
dataLabels: {
enabled: true,
format: '{point.name}'
}
}
},
series: [{
type: 'pie',
name: '',
data: [
{% for item in report.portfolio %}
{% if forloop.first %}
{% else %}
['{{ item.0 }}', {{ item.5 }}]
{% if forloop.last %}{% else %},{% endif %}
{% endif %}
{% endfor %}
]
}]
});
});
$(function () {
$('#chart4').highcharts({
chart: {
type: 'column',
options3d: {
enabled: true,
alpha: 15,
beta: 15,
viewDistance: 25,
depth: 40
}
},
title: {
text: ''
},
xAxis: {
categories: ['{{ report.previous_period }}', '{{ report.period }}']
},
yAxis: {
allowDecimals: true,
min: 0,
title: {
text: ''
}
},
colors: ['#{{ color_negativetext }}', '#{{ color_positivetext }}'],
tooltip: {
pointFormat: '<span style="color:{series.color}">\u25CF</span>{point.y}'
},
series: [{
name: '{{ document|display:"f_CURRENTAMOUNT_EXPENSE" }}',
data: [{{ report.income_vs_expenditure.2.2 }}, {{ report.income_vs_expenditure.2.3 }}0]
}, {
name: '{{ document|display:"f_CURRENTAMOUNT_INCOME" }}',
data: [{{ report.income_vs_expenditure.1.2 }}, {{ report.income_vs_expenditure.1.3 }}]
}
]
});
});
$(function () {
$('#chart5').highcharts({
chart: {
type: 'pie',
options3d: {
enabled: true,
alpha: 45,
beta: 0
}
},
title: {
text: ''
},
tooltip: {
pointFormat: '{point.percentage:.1f}%</b>'
},
plotOptions: {
pie: {
allowPointSelect: false,
depth: 35,
dataLabels: {
enabled: true,
format: '{point.name}'
}
}
},
series: [{
type: 'pie',
name: '',
data: [
{% for item in report.bank_table %}
{% if forloop.first %}
{% else %}
{% if forloop.last %}
[null, null]
{% else %}
['{{ item.1 }}', {{ item.6 }}],
{% endif %}
{% endif %}
{% endfor %}
]
}]
});
});
</script>
</body>
</html>
diff --git a/plugins/skrooge/skrooge_bank/CMakeLists.txt b/plugins/skrooge/skrooge_bank/CMakeLists.txt
index 7d7377e5a..e4fdc7981 100644
--- a/plugins/skrooge/skrooge_bank/CMakeLists.txt
+++ b/plugins/skrooge/skrooge_bank/CMakeLists.txt
@@ -1,42 +1,42 @@
#***************************************************************************
#* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
#* *
#* 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 <http://www.gnu.org/licenses/> *
+#* along with this program. If not, see <https://www.gnu.org/licenses/> *
#***************************************************************************
MESSAGE( STATUS "..:: CMAKE PLUGIN_BANK ::..")
PROJECT(plugin_bank)
IF(SKG_WEBENGINE)
MESSAGE( STATUS " Mode WebEngine")
ADD_DEFINITIONS(-DSKG_WEBENGINE=${SKG_WEBENGINE})
ENDIF(SKG_WEBENGINE)
LINK_DIRECTORIES (${LIBRARY_OUTPUT_PATH})
SET(skrooge_bank_SRCS
skgbankplugin.cpp
skgbankpluginwidget.cpp
skgaccountboardwidget.cpp
)
ki18n_wrap_ui(skrooge_bank_SRCS skgbankpluginwidget_base.ui skgbankpluginwidget_board.ui)
ADD_LIBRARY(skrooge_bank MODULE ${skrooge_bank_SRCS})
TARGET_LINK_LIBRARIES(skrooge_bank KF5::Parts KF5::ItemViews skgbasemodeler skgbasegui skgbankmodeler skgbankgui)
########### install files ###############
INSTALL(TARGETS skrooge_bank DESTINATION ${KDE_INSTALL_QTPLUGINDIR})
INSTALL(FILES ${PROJECT_SOURCE_DIR}/org.kde.skrooge-plugin-bank.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR})
INSTALL(FILES ${PROJECT_SOURCE_DIR}/skrooge_bank.rc DESTINATION ${KDE_INSTALL_KXMLGUI5DIR}/skrooge_bank )
diff --git a/plugins/skrooge/skrooge_bank/org.kde.skrooge-plugin-bank.desktop b/plugins/skrooge/skrooge_bank/org.kde.skrooge-plugin-bank.desktop
index b98b76711..09e766394 100644
--- a/plugins/skrooge/skrooge_bank/org.kde.skrooge-plugin-bank.desktop
+++ b/plugins/skrooge/skrooge_bank/org.kde.skrooge-plugin-bank.desktop
@@ -1,80 +1,80 @@
[Desktop Entry]
Name=Skrooge bank plugin
Name[bs]=Skrooge dodatak za banku
Name[ca]=Connector de banca de l'Skrooge
Name[ca@valencia]=Connector de banca de l'Skrooge
Name[cs]=Modul Skrooge pro banky
Name[da]=Skrooge bank-plugin
Name[de]=Skrooge-Bankmodul
Name[el]=Skrooge bank plugin
Name[en_GB]=Skrooge bank plugin
Name[eo]=Skrooge banka kromaĵo
Name[es]=Complemento bancario de Skrooge
Name[et]=Skrooge pangaplugin
Name[fi]=Skroogen pankkiliitännäinen
Name[fr]=Module externe pour les traitements bancaires
Name[gl]=Complemento de bancos de Skrooge
Name[hu]=Skrooge bank bővítmény
Name[it]=Estensione bancaria di Skrooge
Name[lt]=Skrooge banko papildinys
Name[ms]=Plugin bank Skrooge
Name[nb]=Skrooge bankmodul
Name[nds]=Bankmoduul för Skrooge
Name[nl]=Plugin voor Skrooge-bank
Name[pl]=Wtyczka banku dla Skrooge
Name[pt]='Plugin' de banco do Skrooge
Name[pt_BR]=Plugin de banco do Skrooge
Name[ru]=Модуль банков
Name[sk]=Plugin bánk Skrooge
Name[sv]=Skrooge bankinsticksprogram
Name[tr]=Skrooge banka eklentisi
Name[uk]=Додаток банків Skrooge
Name[x-test]=xxSkrooge bank pluginxx
Name[zh_TW]=Skrooge 銀行外掛程式
Comment=A Skrooge banking assistant plugin.
Comment[bs]=Skrooge dodatak za pomoć u bankarstvu.
Comment[ca]=Un connector d'assistent de banca per a Skrooge.
Comment[ca@valencia]=Un connector d'assistent de banca per a Skrooge.
Comment[cs]=Modul bankovního asistenta pro Skrooge
Comment[da]=Et bankassistent-plugin til Skrooge
Comment[de]=Ein Skrooge-Modul für einen Bank-Assistenten.
Comment[el]=Ένα πρόσθετο τραπεζικού βοηθού του Skrooge.
Comment[en_GB]=A Skrooge banking assistant plugin.
Comment[eo]=Skrooge kromaĵo por banka asistilo
Comment[es]=Un complemento de asistencia bancaria de Skrooge
Comment[et]=Skrooge pangaasjade nõustamisplugin
Comment[fi]=Skroogen pankkiavustajaliitännäinen.
Comment[fr]=Un module externe Skrooge d'assistant de traitements bancaires
Comment[gl]=Un complemento asistente de banca para Skrooge.
Comment[hu]=Egy Skrooge banki asszisztens bővítmény.
Comment[it]=Un'estensione di assistenza bancaria per Skrooge.
Comment[lt]=Skrooge banko pagalbininko papildinys.
Comment[ms]=Plugin pembantu perbankan Skrooge.
Comment[nb]=En modul som er bankassistent for Skrooge.
Comment[nds]=En Bankmoduul för Skrooge
Comment[nl]=Een bankierenassistent-plugin voor Skrooge.
Comment[pl]=Wtyczka asystenta bankowości dla Skrooge.
Comment[pt]=Um 'plugin' de assistência à banca do Skrooge.
Comment[pt_BR]=Um plugin do Skrooge para assistente de banco.
Comment[ru]=Модуль банковского помощника Skrooge
Comment[sk]=Plugin bankového asistenta Skrooge.
Comment[sv]=Ett insticksprogram till Skrooge med guide för bankärenden.
Comment[tr]=Bir Skrooge banka işlemleri eklentisi.
Comment[uk]=Додаток банківського помічника Skrooge.
Comment[x-test]=xxA Skrooge banking assistant plugin.xx
Comment[zh_TW]=Skrooge 銀行小助手外掛程式。
Encoding=UTF-8
Icon=skrooge
Type=Service
X-KDE-ServiceTypes=SKG GUI/Plugin
X-KDE-Library=skrooge_bank
X-Krunner-ID=Skrooge bank plugin
X-KDE-PluginInfo-Author=Stephane MANKOWSKI,miraks
X-KDE-PluginInfo-Email=stephane@mankowski.fr
X-KDE-PluginInfo-Name=skrooge_bank
X-KDE-PluginInfo-Version=1.0
-X-KDE-PluginInfo-Website=http://skrooge.org/
+X-KDE-PluginInfo-Website=https://skrooge.org/
X-KDE-PluginInfo-Category=Plugins
X-KDE-PluginInfo-Depends=
X-KDE-PluginInfo-License=GPL
X-KDE-PluginInfo-EnabledByDefault=true
diff --git a/plugins/skrooge/skrooge_bank/skgaccountboardwidget.cpp b/plugins/skrooge/skrooge_bank/skgaccountboardwidget.cpp
index 168123324..209db0988 100644
--- a/plugins/skrooge/skrooge_bank/skgaccountboardwidget.cpp
+++ b/plugins/skrooge/skrooge_bank/skgaccountboardwidget.cpp
@@ -1,390 +1,390 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is Skrooge plugin for bank management.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgaccountboardwidget.h"
#include <qaction.h>
#include <qdom.h>
#include <kcolorscheme.h>
#include "skgaccountobject.h"
#include "skgdocumentbank.h"
#include "skgmainpanel.h"
#include "skgservices.h"
#include "skgtraces.h"
#include "skgunitobject.h"
SKGAccountBoardWidget::SKGAccountBoardWidget(QWidget* iParent, SKGDocument* iDocument)
: SKGBoardWidget(iParent, iDocument, i18nc("Title of a dashboard widget", "Accounts")), m_refreshNeeded(true)
{
SKGTRACEINFUNC(10)
// Create menu
setContextMenuPolicy(Qt::ActionsContextMenu);
// menu
m_menuFavorite = new QAction(SKGServices::fromTheme(QStringLiteral("bookmarks")), i18nc("Display only favorite accounts", "Highlighted only"), this);
m_menuFavorite->setCheckable(true);
m_menuFavorite->setChecked(false);
connect(m_menuFavorite, &QAction::triggered, this, [ = ]() {
this->dataModified();
});
addAction(m_menuFavorite);
m_menuPastOperations = new QAction(i18nc("Noun, a type of account", "Only past operations"), this);
m_menuPastOperations->setCheckable(true);
m_menuPastOperations->setChecked(false);
connect(m_menuPastOperations, &QAction::triggered, this, [ = ]() {
this->dataModified();
});
addAction(m_menuPastOperations);
{
auto sep = new QAction(this);
sep->setSeparator(true);
addAction(sep);
}
m_menuCurrent = new QAction(i18nc("Noun, a type of account", "Current"), this);
m_menuCurrent->setCheckable(true);
m_menuCurrent->setChecked(true);
connect(m_menuCurrent, &QAction::triggered, this, [ = ]() {
this->dataModified();
});
addAction(m_menuCurrent);
m_menuCreditCard = new QAction(i18nc("Noun, a type of account", "Credit card"), this);
m_menuCreditCard->setCheckable(true);
m_menuCreditCard->setChecked(true);
connect(m_menuCreditCard, &QAction::triggered, this, [ = ]() {
this->dataModified();
});
addAction(m_menuCreditCard);
m_menuSaving = new QAction(i18nc("Noun, a type of account", "Saving"), this);
m_menuSaving->setCheckable(true);
m_menuSaving->setChecked(true);
connect(m_menuSaving, &QAction::triggered, this, [ = ]() {
this->dataModified();
});
addAction(m_menuSaving);
m_menuInvestment = new QAction(i18nc("Noun, a type of account", "Investment"), this);
m_menuInvestment->setCheckable(true);
m_menuInvestment->setChecked(true);
connect(m_menuInvestment, &QAction::triggered, this, [ = ]() {
this->dataModified();
});
addAction(m_menuInvestment);
m_menuAssets = new QAction(i18nc("Noun, a type of account", "Assets"), this);
m_menuAssets->setCheckable(true);
m_menuAssets->setChecked(true);
connect(m_menuAssets, &QAction::triggered, this, [ = ]() {
this->dataModified();
});
addAction(m_menuAssets);
m_menuLoan = new QAction(i18nc("Noun, a type of account", "Loan"), this);
m_menuLoan->setCheckable(true);
m_menuLoan->setChecked(true);
connect(m_menuLoan, &QAction::triggered, this, [ = ]() {
this->dataModified();
});
addAction(m_menuLoan);
m_menuPension = new QAction(i18nc("Noun, a type of account", "Pension"), this);
m_menuPension->setCheckable(true);
m_menuPension->setChecked(true);
connect(m_menuPension, &QAction::triggered, this, [ = ]() {
this->dataModified();
});
addAction(m_menuPension);
m_menuWallet = new QAction(i18nc("Noun, a type of account", "Wallet"), this);
m_menuWallet->setCheckable(true);
m_menuWallet->setChecked(true);
connect(m_menuWallet, &QAction::triggered, this, [ = ]() {
this->dataModified();
});
addAction(m_menuWallet);
m_menuOther = new QAction(i18nc("Noun, a type of account", "Other"), this);
m_menuOther->setCheckable(true);
m_menuOther->setChecked(true);
connect(m_menuOther, &QAction::triggered, this, [ = ]() {
this->dataModified();
});
addAction(m_menuOther);
m_label = new QLabel();
setMainWidget(m_label);
// Refresh
connect(getDocument(), &SKGDocument::tableModified, this, &SKGAccountBoardWidget::dataModified, Qt::QueuedConnection);
connect(SKGMainPanel::getMainPanel(), &SKGMainPanel::currentPageChanged, this, &SKGAccountBoardWidget::pageChanged, Qt::QueuedConnection);
connect(m_label, &QLabel::linkActivated, this, [ = ](const QString & val) {
SKGMainPanel::getMainPanel()->openPage(val);
});
}
SKGAccountBoardWidget::~SKGAccountBoardWidget()
{
SKGTRACEINFUNC(10)
m_menuAssets = nullptr;
m_menuCurrent = nullptr;
m_menuCreditCard = nullptr;
m_menuSaving = nullptr;
m_menuInvestment = nullptr;
m_menuWallet = nullptr;
m_menuLoan = nullptr;
m_menuPension = nullptr;
m_menuOther = nullptr;
m_menuFavorite = nullptr;
m_menuPastOperations = nullptr;
}
QString SKGAccountBoardWidget::getState()
{
QDomDocument doc(QStringLiteral("SKGML"));
doc.setContent(SKGBoardWidget::getState());
QDomElement root = doc.documentElement();
root.setAttribute(QStringLiteral("menuFavorite"), (m_menuFavorite != nullptr) && m_menuFavorite->isChecked() ? QStringLiteral("Y") : QStringLiteral("N"));
root.setAttribute(QStringLiteral("menuAssets"), (m_menuAssets != nullptr) && m_menuAssets->isChecked() ? QStringLiteral("Y") : QStringLiteral("N"));
root.setAttribute(QStringLiteral("menuCurrent"), (m_menuCurrent != nullptr) && m_menuCurrent->isChecked() ? QStringLiteral("Y") : QStringLiteral("N"));
root.setAttribute(QStringLiteral("menuCreditCard"), (m_menuCreditCard != nullptr) && m_menuCreditCard->isChecked() ? QStringLiteral("Y") : QStringLiteral("N"));
root.setAttribute(QStringLiteral("menuSaving"), (m_menuSaving != nullptr) && m_menuSaving->isChecked() ? QStringLiteral("Y") : QStringLiteral("N"));
root.setAttribute(QStringLiteral("menuInvestment"), (m_menuInvestment != nullptr) && m_menuInvestment->isChecked() ? QStringLiteral("Y") : QStringLiteral("N"));
root.setAttribute(QStringLiteral("menuWallet"), (m_menuWallet != nullptr) && m_menuWallet->isChecked() ? QStringLiteral("Y") : QStringLiteral("N"));
root.setAttribute(QStringLiteral("menuLoan"), (m_menuLoan != nullptr) && m_menuLoan->isChecked() ? QStringLiteral("Y") : QStringLiteral("N"));
root.setAttribute(QStringLiteral("menuPension"), (m_menuPension != nullptr) && m_menuPension->isChecked() ? QStringLiteral("Y") : QStringLiteral("N"));
root.setAttribute(QStringLiteral("menuOther"), (m_menuOther != nullptr) && m_menuOther->isChecked() ? QStringLiteral("Y") : QStringLiteral("N"));
root.setAttribute(QStringLiteral("menuPastOperations"), (m_menuPastOperations != nullptr) && m_menuPastOperations->isChecked() ? QStringLiteral("Y") : QStringLiteral("N"));
return doc.toString();
}
void SKGAccountBoardWidget::setState(const QString& iState)
{
SKGBoardWidget::setState(iState);
QDomDocument doc(QStringLiteral("SKGML"));
doc.setContent(iState);
QDomElement root = doc.documentElement();
if (m_menuFavorite != nullptr) {
m_menuFavorite->setChecked(root.attribute(QStringLiteral("menuFavorite")) == QStringLiteral("Y"));
}
if (m_menuAssets != nullptr) {
m_menuAssets->setChecked(root.attribute(QStringLiteral("menuAssets")) != QStringLiteral("N"));
}
if (m_menuCurrent != nullptr) {
m_menuCurrent->setChecked(root.attribute(QStringLiteral("menuCurrent")) != QStringLiteral("N"));
}
if (m_menuCreditCard != nullptr) {
m_menuCreditCard->setChecked(root.attribute(QStringLiteral("menuCreditCard")) != QStringLiteral("N"));
}
if (m_menuSaving != nullptr) {
m_menuSaving->setChecked(root.attribute(QStringLiteral("menuSaving")) != QStringLiteral("N"));
}
if (m_menuInvestment != nullptr) {
m_menuInvestment->setChecked(root.attribute(QStringLiteral("menuInvestment")) != QStringLiteral("N"));
}
if (m_menuWallet != nullptr) {
m_menuWallet->setChecked(root.attribute(QStringLiteral("menuWallet")) != QStringLiteral("N"));
}
if (m_menuLoan != nullptr) {
m_menuLoan->setChecked(root.attribute(QStringLiteral("menuLoan")) != QStringLiteral("N"));
}
if (m_menuPension != nullptr) {
m_menuPension->setChecked(root.attribute(QStringLiteral("menuPension")) != QStringLiteral("N"));
}
if (m_menuOther != nullptr) {
m_menuOther->setChecked(root.attribute(QStringLiteral("menuOther")) != QStringLiteral("N"));
}
if (m_menuPastOperations != nullptr) {
m_menuPastOperations->setChecked(root.attribute(QStringLiteral("menuPastOperations")) == QStringLiteral("Y"));
}
dataModified(QLatin1String(""), 0);
}
void SKGAccountBoardWidget::pageChanged()
{
if (m_refreshNeeded) {
dataModified(QLatin1String(""), 0);
}
}
void SKGAccountBoardWidget::dataModified(const QString& iTableName, int iIdTransaction)
{
Q_UNUSED(iIdTransaction)
if (iTableName == QStringLiteral("v_account_display") || iTableName.isEmpty()) {
SKGTRACEINFUNC(10)
SKGTabPage* page = SKGTabPage::parentTabPage(this);
if (page != nullptr && page != SKGMainPanel::getMainPanel()->currentPage()) {
m_refreshNeeded = true;
return;
}
m_refreshNeeded = false;
auto* doc = qobject_cast<SKGDocumentBank*>(getDocument());
if (doc != nullptr) {
SKGServices::SKGUnitInfo primary = doc->getPrimaryUnit();
bool exist = false;
SKGError err = doc->existObjects(QStringLiteral("account"), QLatin1String(""), exist);
IFOK(err) {
QString html;
if (!exist) {
html = "<html><body>" % i18nc("Message, do not translate URL", "First, you have to create at least one account<br>from <a href=\"%1\">\"Bank and Account\"</a> page or <a href=\"%2\">import</a> operations.", "skg://Skrooge_bank_plugin", "skg://import_operation") % "</body></html>";
} else {
// Build where clause
QString wc;
if ((m_menuAssets != nullptr) && m_menuAssets->isChecked()) {
wc = QStringLiteral("t_type='A'");
}
if ((m_menuCurrent != nullptr) && m_menuCurrent->isChecked()) {
if (!wc.isEmpty()) {
wc += QStringLiteral(" OR ");
}
wc += QStringLiteral("t_type='C'");
}
if ((m_menuCreditCard != nullptr) && m_menuCreditCard->isChecked()) {
if (!wc.isEmpty()) {
wc += QStringLiteral(" OR ");
}
wc += QStringLiteral("t_type='D'");
}
if ((m_menuSaving != nullptr) && m_menuSaving->isChecked()) {
if (!wc.isEmpty()) {
wc += QStringLiteral(" OR ");
}
wc += QStringLiteral("t_type='S'");
}
if ((m_menuInvestment != nullptr) && m_menuInvestment->isChecked()) {
if (!wc.isEmpty()) {
wc += QStringLiteral(" OR ");
}
wc += QStringLiteral("t_type='I'");
}
if ((m_menuWallet != nullptr) && m_menuWallet->isChecked()) {
if (!wc.isEmpty()) {
wc += QStringLiteral(" OR ");
}
wc += QStringLiteral("t_type='W'");
}
if ((m_menuOther != nullptr) && m_menuOther->isChecked()) {
if (!wc.isEmpty()) {
wc += QStringLiteral(" OR ");
}
wc += QStringLiteral("t_type='O'");
}
if ((m_menuLoan != nullptr) && m_menuLoan->isChecked()) {
if (!wc.isEmpty()) {
wc += QStringLiteral(" OR ");
}
wc += QStringLiteral("t_type='L'");
}
if ((m_menuPension != nullptr) && m_menuPension->isChecked()) {
if (!wc.isEmpty()) {
wc += QStringLiteral(" OR ");
}
wc += QStringLiteral("t_type='P'");
}
if (wc.isEmpty()) {
wc = QStringLiteral("1=0");
} else if ((m_menuFavorite != nullptr) && m_menuFavorite->isChecked()) {
wc = "t_bookmarked='Y' AND (" % wc % ')';
}
// Build display
SKGStringListList listTmp;
err = doc->executeSelectSqliteOrder(
QStringLiteral("SELECT t_name, t_TYPENLS, t_UNIT, ") % ((m_menuPastOperations != nullptr) && m_menuPastOperations->isChecked() ? "f_TODAYAMOUNT" : "f_CURRENTAMOUNT") % ", t_close from v_account_display WHERE (" % wc % ") ORDER BY t_TYPENLS, t_name",
listTmp);
IFOK(err) {
KColorScheme scheme(QPalette::Normal, KColorScheme::Window);
auto color = scheme.foreground(KColorScheme::NormalText).color().name().right(6);
html += QStringLiteral("<html><head><style>a {color: #") + color + ";}</style></head><body><table>";
double sumTypeV1 = 0;
double sumV1 = 0;
QString currentType;
int nb = listTmp.count();
for (int i = 1; i < nb; ++i) { // Ignore header
const QStringList& r = listTmp.at(i);
const QString& name = r.at(0);
const QString& type = r.at(1);
const QString& unitAccountSymbol = r.at(2);
double v1 = SKGServices::stringToDouble(r.at(3));
bool closed = (r.at(4) == QStringLiteral("Y"));
if (type != currentType) {
if (!currentType.isEmpty()) {
html += "<tr><td><b>" % SKGServices::stringToHtml(i18nc("the numerical total of a sum of values", "Total of %1", currentType)) % "</b></td>"
"<td align=\"right\"><b>" % doc->formatMoney(sumTypeV1, primary) % "</b></td></tr>";
sumTypeV1 = 0;
}
currentType = type;
}
if (!closed || qAbs(v1) > 0.1) {
html += QString("<tr><td><a href=\"skg://Skrooge_operation_plugin/?account=" % SKGServices::encodeForUrl(name) % "\">") % SKGServices::stringToHtml(name) % "</a></td>"
"<td align=\"right\">";
if (!unitAccountSymbol.isEmpty() && primary.Symbol != unitAccountSymbol) {
SKGUnitObject unitAccount(getDocument());
unitAccount.setSymbol(unitAccountSymbol);
unitAccount.load();
double unitAccountValue = SKGServices::stringToDouble(unitAccount.getAttribute(QStringLiteral("f_CURRENTAMOUNT")));
SKGServices::SKGUnitInfo u2 = primary;
u2.Symbol = unitAccountSymbol;
u2.NbDecimal = unitAccount.getNumberDecimal();
html += doc->formatMoney(v1 / unitAccountValue, u2);
html += '=';
}
html += doc->formatMoney(v1, primary);
html += QStringLiteral("</td></tr>");
}
sumTypeV1 += v1;
sumV1 += v1;
}
if (!currentType.isEmpty()) {
html += "<tr><td><b>" % SKGServices::stringToHtml(i18nc("the numerical total of a sum of values", "Total of %1", currentType)) % "</b></td>"
"<td align=\"right\"><b>" % doc->formatMoney(sumTypeV1, primary) % "</b></td>"
"</tr>";
}
html += "<tr><td><b>" % SKGServices::stringToHtml(i18nc("Noun, the numerical total of a sum of values", "Total")) % "</b></td>"
"<td align=\"right\"><b>" % doc->formatMoney(sumV1, primary) % "</b></td>"
"</tr>";
html += QStringLiteral("</table></body></html>");
}
}
m_label->setText(html);
}
}
}
}
diff --git a/plugins/skrooge/skrooge_bank/skgaccountboardwidget.h b/plugins/skrooge/skrooge_bank/skgaccountboardwidget.h
index fb1695942..400325281 100644
--- a/plugins/skrooge/skrooge_bank/skgaccountboardwidget.h
+++ b/plugins/skrooge/skrooge_bank/skgaccountboardwidget.h
@@ -1,85 +1,85 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGACCOUNTBOARDWIDGET_H
#define SKGACCOUNTBOARDWIDGET_H
/** @file
* This file is Skrooge plugin for bank management.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgboardwidget.h"
class QAction;
/**
* This file is Skrooge plugin for bank management
*/
class SKGAccountBoardWidget : public SKGBoardWidget
{
Q_OBJECT
public:
/**
* Default Constructor
* @param iParent the parent widget
* @param iDocument the document
*/
explicit SKGAccountBoardWidget(QWidget* iParent, SKGDocument* iDocument);
/**
* Default Destructor
*/
~SKGAccountBoardWidget() override;
/**
* Get the current state
* MUST BE OVERWRITTEN
* @return a string containing all information needed to set the same state.
* Could be an XML stream
*/
QString getState() override;
/**
* Set the current state
* MUST BE OVERWRITTEN
* @param iState must be interpreted to set the state of the widget
*/
void setState(const QString& iState) override;
private Q_SLOTS:
void pageChanged();
void dataModified(const QString& iTableName = QString(), int iIdTransaction = 0);
private:
Q_DISABLE_COPY(SKGAccountBoardWidget)
QAction* m_menuAssets;
QAction* m_menuCurrent;
QAction* m_menuCreditCard;
QAction* m_menuSaving;
QAction* m_menuInvestment;
QAction* m_menuWallet;
QAction* m_menuLoan;
QAction* m_menuPension;
QAction* m_menuOther;
QAction* m_menuFavorite;
QAction* m_menuPastOperations;
bool m_refreshNeeded;
QLabel* m_label;
};
#endif // SKGACCOUNTBOARDWIDGET_H
diff --git a/plugins/skrooge/skrooge_bank/skgbankplugin.cpp b/plugins/skrooge/skrooge_bank/skgbankplugin.cpp
index 7030921a3..706bddf98 100644
--- a/plugins/skrooge/skrooge_bank/skgbankplugin.cpp
+++ b/plugins/skrooge/skrooge_bank/skgbankplugin.cpp
@@ -1,347 +1,347 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is Skrooge plugin for bank management.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgbankplugin.h"
#include <kaboutdata.h>
#include <kactioncollection.h>
#include <klocalizedstring.h>
#include <kpluginfactory.h>
#include <qstandardpaths.h>
#include "skgaccountboardwidget.h"
#include "skgaccountobject.h"
#include "skgbankobject.h"
#include "skgbankpluginwidget.h"
#include "skgdocumentbank.h"
#include "skghtmlboardwidget.h"
#include "skgmainpanel.h"
#include "skgoperationobject.h"
#include "skgsuboperationobject.h"
#include "skgtraces.h"
#include "skgtransactionmng.h"
/**
* This plugin factory.
*/
K_PLUGIN_FACTORY(SKGBankPluginFactory, registerPlugin<SKGBankPlugin>();)
SKGBankPlugin::SKGBankPlugin(QWidget* iWidget, QObject* iParent, const QVariantList& /*iArg*/)
: SKGInterfacePlugin(iParent), m_currentBankDocument(nullptr), m_reconciliateAction(nullptr)
{
Q_UNUSED(iWidget)
SKGTRACEINFUNC(10)
}
SKGBankPlugin::~SKGBankPlugin()
{
SKGTRACEINFUNC(10)
m_currentBankDocument = nullptr;
}
bool SKGBankPlugin::setupActions(SKGDocument* iDocument)
{
SKGTRACEINFUNC(10)
m_currentBankDocument = qobject_cast<SKGDocumentBank*>(iDocument);
if (m_currentBankDocument == nullptr) {
return false;
}
setComponentName(QStringLiteral("skrooge_bank"), title());
setXMLFile(QStringLiteral("skrooge_bank.rc"));
// Menu
auto actReconciliate = new QAction(SKGServices::fromTheme(QStringLiteral("window-duplicate")), i18nc("Verb: Reconciliation is process through which you ensure compliance with your bank's statement", "Reconcile..."), this);
connect(actReconciliate, &QAction::triggered, this, &SKGBankPlugin::onReconciliate);
actionCollection()->setDefaultShortcut(actReconciliate, Qt::ALT + Qt::Key_R);
registerGlobalAction(QStringLiteral("edit_reconciliate"), actReconciliate, QStringList() << QStringLiteral("account"), 1, -1, 320);
return true;
}
int SKGBankPlugin::getNbDashboardWidgets()
{
return 4;
}
QString SKGBankPlugin::getDashboardWidgetTitle(int iIndex)
{
if (iIndex == 0) {
return i18nc("Noun, a list of bank accounts", "Accounts (Light)");
}
if (iIndex == 1) {
return i18nc("Noun, a list of bank accounts", "Accounts (Full)");
}
if (iIndex == 2) {
return i18nc("Noun, a list of banks", "Banks (Light)");
}
return i18nc("Noun, a list of banks", "Banks (Full)");
}
SKGBoardWidget* SKGBankPlugin::getDashboardWidget(int iIndex)
{
// Get QML mode for dashboard
KConfigSkeleton* skl = SKGMainPanel::getMainPanel()->getPluginByName(QStringLiteral("Dashboard plugin"))->getPreferenceSkeleton();
KConfigSkeletonItem* sklItem = skl->findItem(QStringLiteral("qmlmode"));
bool qml = sklItem->property().toBool();
if (iIndex == 0) {
return new SKGAccountBoardWidget(SKGMainPanel::getMainPanel(), m_currentBankDocument);
}
if (iIndex == 1) {
return new SKGHtmlBoardWidget(SKGMainPanel::getMainPanel(), m_currentBankDocument,
getDashboardWidgetTitle(iIndex),
QStandardPaths::locate(QStandardPaths::GenericDataLocation, QStringLiteral("skrooge/html/default/account_table.") % (qml ? QStringLiteral("qml") : QStringLiteral("html"))),
QStringList() << QStringLiteral("v_account_display"), SKGSimplePeriodEdit::PREVIOUS_AND_CURRENT_PERIODS);
}
if (iIndex == 2) {
auto w = new SKGHtmlBoardWidget(SKGMainPanel::getMainPanel(), m_currentBankDocument,
getDashboardWidgetTitle(iIndex),
QStandardPaths::locate(QStandardPaths::GenericDataLocation, QStringLiteral("skrooge/html/default/bank_table_light.") % (qml ? QStringLiteral("qml") : QStringLiteral("html"))),
QStringList() << QStringLiteral("v_account_display"));
QStringList overlayopen;
overlayopen.push_back(QStringLiteral("quickopen"));
auto open = new QAction(SKGServices::fromTheme(QStringLiteral("view-statistics"), overlayopen), i18nc("Verb", "Open report..."), w);
connect(open, &QAction::triggered, SKGMainPanel::getMainPanel(), [ = ]() {
SKGMainPanel::getMainPanel()->SKGMainPanel::openPage();
});
QString u = QStringLiteral("skg://skrooge_report_plugin/?grouped=Y&transfers=Y&tracked=Y&expenses=Y&incomes=Y&lines2=t_BANK&currentPage=-1&mode=0&interval=3&period=0") %
"&tableAndGraphState.graphMode=2&tableAndGraphState.allPositive=N&tableAndGraphState.show=graph&columns=" % SKGServices::encodeForUrl(QStringLiteral("#NOTHING#"));
open->setData(u);
w->addAction(open);
return w;
}
return new SKGHtmlBoardWidget(SKGMainPanel::getMainPanel(), m_currentBankDocument,
getDashboardWidgetTitle(iIndex),
QStandardPaths::locate(QStandardPaths::GenericDataLocation, QStringLiteral("skrooge/html/default/bank_table.") % (qml ? QStringLiteral("qml") : QStringLiteral("html"))),
QStringList() << QStringLiteral("v_account_display"), SKGSimplePeriodEdit::PREVIOUS_AND_CURRENT_PERIODS);
}
SKGTabPage* SKGBankPlugin::getWidget()
{
SKGTRACEINFUNC(10)
return new SKGBankPluginWidget(SKGMainPanel::getMainPanel(), m_currentBankDocument);
}
QString SKGBankPlugin::title() const
{
return i18nc("Display a list of Accounts", "Accounts");
}
QString SKGBankPlugin::icon() const
{
return QStringLiteral("view-bank");
}
QString SKGBankPlugin::toolTip() const
{
return i18nc("This allows the user to manage his list of accounts", "Manage your accounts");
}
QStringList SKGBankPlugin::tips() const
{
QStringList output;
output.push_back(i18nc("Description of a tip", "<p>... you can associate a logo with your <a href=\"skg://skrooge_bank_plugin\">banks</a>.</p>"));
output.push_back(i18nc("Description of a tip", "<p>... <a href=\"skg://skrooge_bank_plugin\">accounts</a> can be merged by drag & drop.</p>"));
output.push_back(i18nc("Description of a tip", "<p>... you can set a minimum and a maximum limit on your <a href=\"skg://skrooge_bank_plugin\">accounts</a>. This will trigger an alarm.</p>"));
return output;
}
int SKGBankPlugin::getOrder() const
{
// Must be one of the first
return 10;
}
bool SKGBankPlugin::isInPagesChooser() const
{
return true;
}
void SKGBankPlugin::onReconciliate()
{
if ((m_currentBankDocument != nullptr) && (SKGMainPanel::getMainPanel() != nullptr)) {
// Open in operation plugin
SKGObjectBase::SKGListSKGObjectBase selection = SKGMainPanel::getMainPanel()->getSelectedObjects();
int nb = selection.count();
for (int i = 0; i < nb; ++i) {
SKGAccountObject accountObj(selection.at(i));
SKGMainPanel::getMainPanel()->openPage("skg://skrooge_operation_plugin/?modeInfoZone=1&currentPage=-1&account=" % SKGServices::encodeForUrl(accountObj.getName()));
}
}
}
SKGAdviceList SKGBankPlugin::advice(const QStringList& iIgnoredAdvice)
{
SKGTRACEINFUNC(10)
SKGAdviceList output;
output.reserve(40);
// Get bank without accounts
if (!iIgnoredAdvice.contains(QStringLiteral("skgbankplugin_withoutaccount"))) {
SKGStringListList result;
m_currentBankDocument->executeSelectSqliteOrder(QStringLiteral("SELECT bank.t_name FROM bank WHERE NOT EXISTS (SELECT 1 FROM account WHERE account.rd_bank_id=bank.id)"), result);
int nb = result.count();
for (int i = 1; i < nb; ++i) { // Ignore header
// Get parameters
const QStringList& line = result.at(i);
const QString& bank = line.at(0);
SKGAdvice ad;
ad.setUUID("skgbankplugin_withoutaccount|" % bank);
ad.setPriority(3);
ad.setShortMessage(i18nc("A bank is in the list of used banks, but it doesn't have any account attached", "Bank '%1' has no account", bank));
ad.setLongMessage(i18nc("User can delete banks with no accounts", "Do not forget to remove useless banks"));
QStringList autoCorrections;
autoCorrections.push_back(i18nc("Action to delete a bank", "Delete '%1'", bank));
ad.setAutoCorrections(autoCorrections);
output.push_back(ad);
}
}
// Get accounts closed with money
if (!iIgnoredAdvice.contains(QStringLiteral("skgbankplugin_closedaccount"))) {
SKGStringListList result;
m_currentBankDocument->executeSelectSqliteOrder(QStringLiteral("SELECT t_name FROM v_account_amount WHERE f_CURRENTAMOUNT>0.1 AND t_close='Y'"), result);
int nb = result.count();
SKGAdvice::SKGAdviceActionList autoCorrections;
for (int i = 1; i < nb; ++i) { // Ignore header
// Get parameters
const QStringList& line = result.at(i);
const QString& account = line.at(0);
SKGAdvice ad;
ad.setUUID("skgbankplugin_closedaccount|" % account);
ad.setPriority(3);
ad.setShortMessage(i18nc("A account is closed but the amount is not equal to 0", "Closed account '%1' still has money", account));
ad.setLongMessage(i18nc("Advice on making the best (long)", "This is may be not normal"));
autoCorrections.resize(0);
{
SKGAdvice::SKGAdviceAction a;
a.Title = i18nc("Action to reopen the account", "Reopen '%1'", account);
a.IconName = QStringLiteral("edit_undo");
a.IsRecommended = false;
autoCorrections.push_back(a);
}
{
SKGAdvice::SKGAdviceAction a;
a.Title = i18nc("Action to create a fake operation to set the amount of the account to 0", "Create fake operation");
a.IconName = QStringLiteral("edit-delete");
a.IsRecommended = true;
autoCorrections.push_back(a);
}
ad.setAutoCorrections(autoCorrections);
output.push_back(ad);
}
}
return output;
}
SKGError SKGBankPlugin::executeAdviceCorrection(const QString& iAdviceIdentifier, int iSolution)
{
if ((m_currentBankDocument != nullptr) && iAdviceIdentifier.startsWith(QLatin1String("skgbankplugin_withoutaccount|"))) {
// Get parameters
QString bank = iAdviceIdentifier.right(iAdviceIdentifier.length() - 29);
SKGError err;
{
SKGBEGINTRANSACTION(*m_currentBankDocument, i18nc("Delete banks with no account", "Delete unused banks"), err)
SKGBankObject bankObj(m_currentBankDocument);
err = bankObj.setName(bank);
IFOKDO(err, bankObj.load())
IFOKDO(err, bankObj.remove())
}
// status bar
IFOKDO(err, SKGError(0, i18nc("Successfully deleted a bank with no account", "Unused bank deleted")))
else {
err.addError(ERR_FAIL, i18nc("Could not delete a bank with no account", "Unused bank deletion failed"));
}
// Display error
SKGMainPanel::displayErrorMessage(err);
return SKGError();
}
if ((m_currentBankDocument != nullptr) && iAdviceIdentifier.startsWith(QLatin1String("skgbankplugin_closedaccount|"))) {
// Get parameters
QString account = iAdviceIdentifier.right(iAdviceIdentifier.length() - 28);
SKGAccountObject accountObj(m_currentBankDocument);
SKGError err = accountObj.setName(account);
IFOKDO(err, accountObj.load())
if (iSolution == 0) {
{
SKGBEGINTRANSACTION(*m_currentBankDocument, i18nc("Reopen a closed account", "Reopen account '%1'", account), err)
IFOKDO(err, accountObj.setClosed(false))
IFOKDO(err, accountObj.save())
}
// status bar
IFOKDO(err, SKGError(0, i18nc("Successfully reopen account", "Account reopened")))
else {
err.addError(ERR_FAIL, i18nc("Failure", "reopening of the account failed"));
}
} else if (iSolution == 1) {
{
SKGBEGINTRANSACTION(*m_currentBankDocument, i18nc("Noun, name of the user action", "Create fake operation"), err)
SKGOperationObject op;
IFOKDO(err, accountObj.setClosed(false))
IFOKDO(err, accountObj.addOperation(op))
IFOKDO(err, op.setDate(QDate::currentDate()))
IFOKDO(err, op.setComment(i18nc("Noun, default comment for a fake operation", "Fake operation")))
SKGUnitObject unit;
IFOKDO(err, accountObj.getUnit(unit))
IFOKDO(err, op.setUnit(unit))
IFOKDO(err, op.save())
SKGSubOperationObject sop;
IFOKDO(err, op.addSubOperation(sop))
IFOKDO(err, sop.setQuantity(-accountObj.getAmount(QDate::currentDate())))
IFOKDO(err, sop.save())
// Send message
IFOKDO(err, op.getDocument()->sendMessage(i18nc("An information to the user that something was added", "The operation '%1' has been added", op.getDisplayName()), SKGDocument::Hidden))
}
// status bar
IFOKDO(err, SKGError(0, i18nc("Successful message after an user action", "Fake operation created.")))
else {
err.addError(ERR_FAIL, i18nc("Error message", "Creation failed"));
}
}
// Display error
SKGMainPanel::displayErrorMessage(err);
return SKGError();
}
return SKGInterfacePlugin::executeAdviceCorrection(iAdviceIdentifier, iSolution);
}
#include <skgbankplugin.moc>
diff --git a/plugins/skrooge/skrooge_bank/skgbankplugin.h b/plugins/skrooge/skrooge_bank/skgbankplugin.h
index 86f8a1f15..875d0a516 100644
--- a/plugins/skrooge/skrooge_bank/skgbankplugin.h
+++ b/plugins/skrooge/skrooge_bank/skgbankplugin.h
@@ -1,141 +1,141 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGBANKPLUGIN_H
#define SKGBANKPLUGIN_H
/** @file
* This file is Skrooge plugin for bank management.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skginterfaceplugin.h"
class SKGDocumentBank;
/**
* This file is Skrooge plugin for bank management
*/
class SKGBankPlugin : public SKGInterfacePlugin
{
Q_OBJECT
Q_INTERFACES(SKGInterfacePlugin)
public:
/**
* Default Constructor
*/
explicit SKGBankPlugin(QWidget* iWidget, QObject* iParent, const QVariantList& iArg);
/**
* Default Destructor
*/
~SKGBankPlugin() override;
/**
* Called to initialise the plugin
* @param iDocument the main document
* @return true if the plugin is compatible with the document
*/
bool setupActions(SKGDocument* iDocument) override;
/**
* The number of dashboard widgets of the plugin.
* @return The number of dashboard widgets of the plugin
*/
int getNbDashboardWidgets() override;
/**
* Get a dashboard widget title of the plugin.
* @param iIndex the index of the widget
* @return The title
*/
QString getDashboardWidgetTitle(int iIndex) override;
/**
* Get a dashboard widget of the plugin.
* @param iIndex the index of the widget
* @return The dashboard widget of the plugin
*/
SKGBoardWidget* getDashboardWidget(int iIndex) override;
/**
* The page widget of the plugin.
* @return The page widget of the plugin
*/
SKGTabPage* getWidget() override;
/**
* The title of the plugin.
* @return The title of the plugin
*/
QString title() const override;
/**
* The icon of the plugin.
* @return The icon of the plugin
*/
QString icon() const override;
/**
* The toolTip of the plugin.
* @return The toolTip of the plugin
*/
QString toolTip() const override;
/**
* The tips list of the plugin.
* @return The tips list of the plugin
*/
QStringList tips() const override;
/**
* Must be implemented to set the position of the plugin.
* @return integer value between 0 and 999 (default = 999)
*/
int getOrder() const override;
/**
* Must be implemented to know if a plugin must be display in pages chooser.
* @return true of false (default = false)
*/
bool isInPagesChooser() const override;
/**
* The advice list of the plugin.
* @return The advice list of the plugin
*/
SKGAdviceList advice(const QStringList& iIgnoredAdvice) override;
/**
* Must be implemented to execute the automatic correction for the advice.
* @param iAdviceIdentifier the identifier of the advice
* @param iSolution the identifier of the possible solution
* @return an object managing the error. MUST return ERR_NOTIMPL if iAdviceIdentifier is not known
* @see SKGError
*/
SKGError executeAdviceCorrection(const QString& iAdviceIdentifier, int iSolution) override;
private Q_SLOTS:
void onReconciliate();
private:
Q_DISABLE_COPY(SKGBankPlugin)
SKGDocumentBank* m_currentBankDocument;
QAction* m_reconciliateAction;
};
#endif // SKGDEBUGPLUGIN_H
diff --git a/plugins/skrooge/skrooge_bank/skgbankpluginwidget.cpp b/plugins/skrooge/skrooge_bank/skgbankpluginwidget.cpp
index ad064220f..d68df734a 100644
--- a/plugins/skrooge/skrooge_bank/skgbankpluginwidget.cpp
+++ b/plugins/skrooge/skrooge_bank/skgbankpluginwidget.cpp
@@ -1,869 +1,869 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is Skrooge plugin for bank management.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgbankpluginwidget.h"
#include <kmessagebox.h>
#include <qdir.h>
#include <qdom.h>
#include <qevent.h>
#include <qfile.h>
#include <qfiledialog.h>
#include <qstandardpaths.h>
#include "skgbankobject.h"
#include "skgboardwidget.h"
#include "skgdocumentbank.h"
#include "skginterfaceplugin.h"
#include "skgmainpanel.h"
#include "skgobjectmodel.h"
#include "skgtablewithgraph.h"
#include "skgtraces.h"
#include "skgtransactionmng.h"
#include "skgunitobject.h"
#include "skgunitvalueobject.h"
SKGBankPluginWidget::SKGBankPluginWidget(QWidget* iParent, SKGDocumentBank* iDocument)
: SKGTabPage(iParent, iDocument), m_graph(nullptr)
{
SKGTRACEINFUNC(10)
if (iDocument == nullptr) {
return;
}
ui.setupUi(this);
// Add report
SKGInterfacePlugin* reportPlugin = SKGMainPanel::getMainPanel()->getPluginByName(QStringLiteral("Skrooge report plugin"));
if (reportPlugin != nullptr) {
m_graph = reportPlugin->getDashboardWidget(0);
if (m_graph != nullptr) {
// To avoid hidden page when no account exist
auto w = new QWidget(this);
auto verticalLayout = new QVBoxLayout(w);
verticalLayout->addWidget(m_graph);
m_graph->hideTitle();
ui.verticalLayout->insertWidget(2, w);
// Set initial state
m_graph->hide();
QDomDocument doc(QStringLiteral("SKGML"));
QDomElement root = doc.createElement(QStringLiteral("parameters"));
doc.appendChild(root);
{
QDomDocument doc1(QStringLiteral("SKGML"));
QDomElement root1 = doc1.createElement(QStringLiteral("parameters"));
doc1.appendChild(root1);
root1.setAttribute(QStringLiteral("period"), QStringLiteral("0"));
root1.setAttribute(QStringLiteral("columns"), QStringLiteral("d_DATEMONTH"));
root1.setAttribute(QStringLiteral("mode"), QStringLiteral("1"));
root1.setAttribute(QStringLiteral("currentPage"), QStringLiteral("-2"));
root1.setAttribute(QStringLiteral("operationWhereClause"), QStringLiteral("1=0"));
root1.setAttribute(QStringLiteral("title"), QStringLiteral("none"));
{
QDomDocument doc2(QStringLiteral("SKGML"));
QDomElement root2 = doc2.createElement(QStringLiteral("parameters"));
doc2.appendChild(root2);
root2.setAttribute(QStringLiteral("graphMode"), SKGServices::intToString(static_cast<int>(SKGTableWithGraph::LINE)));
{
QDomDocument doc3(QStringLiteral("SKGML"));
QDomElement root3 = doc3.createElement(QStringLiteral("parameters"));
doc3.appendChild(root3);
root3.setAttribute(QStringLiteral("isToolBarVisible"), QStringLiteral("N"));
root2.setAttribute(QStringLiteral("graphicViewState"), doc3.toString());
}
root1.setAttribute(QStringLiteral("tableAndGraphState"), doc2.toString());
}
root.setAttribute(QStringLiteral("graph"), doc1.toString());
}
m_graph->setState(doc.toString());
m_timer2.setSingleShot(true);
connect(&m_timer2, &QTimer::timeout, this, &SKGBankPluginWidget::onRefreshGraph, Qt::QueuedConnection);
onRefreshGraphDelayed();
connect(ui.kView->getShowWidget(), &SKGShow::stateChanged, this, &SKGBankPluginWidget::onRefreshGraphDelayed, Qt::QueuedConnection);
}
}
// Set label titles
ui.kBankLbl->setText(i18n("%1:", iDocument->getDisplay(QStringLiteral("t_bank"))));
ui.kAccountLbl->setText(i18n("%1:", iDocument->getDisplay(QStringLiteral("t_ACCOUNT"))));
ui.kTypeLbl->setText(i18n("%1:", iDocument->getDisplay(QStringLiteral("t_type"))));
ui.kBankNumberLbl->setText(i18n("%1:", iDocument->getDisplay(QStringLiteral("t_bank_number"))));
ui.kAgencyNumberLbl->setText(i18n("%1:", iDocument->getDisplay(QStringLiteral("t_agency_number"))));
ui.kNumberLbl->setText(i18n("%1:", iDocument->getDisplay(QStringLiteral("t_number"))));
ui.kAgencyAddressLbl->setText(i18n("%1:", iDocument->getDisplay(QStringLiteral("t_agency_address"))));
ui.kMaxLimit->setText(i18n("%1:", iDocument->getDisplay(QStringLiteral("f_maxamount"))));
ui.kMinLimit->setText(i18n("%1:", iDocument->getDisplay(QStringLiteral("f_minamount"))));
ui.kCommentLabel->setText(i18n("%1:", iDocument->getDisplay(QStringLiteral("t_comment"))));
// Set show widget
ui.kView->getShowWidget()->addGroupedItem(QStringLiteral("all"), i18n("All"), QLatin1String(""), QLatin1String(""), QLatin1String(""), Qt::META + Qt::Key_A);
ui.kView->getShowWidget()->addGroupedItem(QStringLiteral("opened"), i18n("Opened"), QStringLiteral("vcs-normal"), QStringLiteral("t_close='N'"), QLatin1String(""), Qt::META + Qt::Key_O);
ui.kView->getShowWidget()->addGroupedItem(QStringLiteral("closed"), i18n("Closed"), QStringLiteral("vcs-conflicting"), QStringLiteral("t_close='Y'"), QLatin1String(""), Qt::META + Qt::Key_C);
ui.kView->getShowWidget()->addGroupedItem(QStringLiteral("highlighted"), i18n("Highlighted only"), QStringLiteral("bookmarks"), QStringLiteral("t_bookmarked='Y'"), QLatin1String(""), Qt::META + Qt::Key_H);
if (m_graph != nullptr) {
ui.kView->getShowWidget()->addSeparator();
ui.kView->getShowWidget()->addItem(QStringLiteral("graph"), i18n("Graph"), QStringLiteral("view-statistics"), QStringLiteral("1=0"), QLatin1String(""), QLatin1String(""), QLatin1String(""), QLatin1String(""), Qt::META + Qt::Key_G);
}
ui.kView->getShowWidget()->setDefaultState(QStringLiteral("opened"));
m_timer.setSingleShot(true);
connect(&m_timer, &QTimer::timeout, this, &SKGBankPluginWidget::refreshInfoZone, Qt::QueuedConnection);
// Add Standard KDE Icons to buttons to Accounts
ui.kAccountCreatorUpdate->setIcon(SKGServices::fromTheme(QStringLiteral("dialog-ok")));
ui.kAccountCreatorAdd->setIcon(SKGServices::fromTheme(QStringLiteral("list-add")));
SKGWidgetSelector::SKGListQWidget list;
list.push_back(ui.SKGEditionWidget);
list.push_back(ui.SKGEditionButtonswidget);
ui.kWidgetSelector->addButton(SKGServices::fromTheme(QStringLiteral("configure")), i18n("Edit"), i18n("Display the account edit panel"), list);
// Add NLS values for type of account
// C=current D=credit card P=passif (for objects) I=Investment O=other
ui.kAccountCreatorType->addItem(SKGServices::fromTheme(QStringLiteral("view-bank-account-checking")), i18nc("Noun, a type of account", "Current"), static_cast<int>(SKGAccountObject::CURRENT));
ui.kAccountCreatorType->addItem(SKGServices::fromTheme(QStringLiteral("skrooge_credit_card")), i18nc("Noun, a type of account", "Credit card"), static_cast<int>(SKGAccountObject::CREDITCARD));
ui.kAccountCreatorType->addItem(SKGServices::fromTheme(QStringLiteral("view-bank-account-savings")), i18nc("Noun, a type of account", "Saving"), static_cast<int>(SKGAccountObject::SAVING));
ui.kAccountCreatorType->addItem(SKGServices::fromTheme(QStringLiteral("view-bank-account-savings")), i18nc("Noun, a type of account", "Investment"), static_cast<int>(SKGAccountObject::INVESTMENT));
ui.kAccountCreatorType->addItem(SKGServices::fromTheme(QStringLiteral("view-bank-account-savings")), i18nc("Noun, a type of account", "Assets"), static_cast<int>(SKGAccountObject::ASSETS));
ui.kAccountCreatorType->addItem(SKGServices::fromTheme(QStringLiteral("view-bank-account-savings")), i18nc("Noun, a type of account", "Loan"), static_cast<int>(SKGAccountObject::LOAN));
ui.kAccountCreatorType->addItem(SKGServices::fromTheme(QStringLiteral("view-bank-account-savings")), i18nc("Noun, a type of account", "Pension"), static_cast<int>(SKGAccountObject::PENSION));
ui.kAccountCreatorType->addItem(SKGServices::fromTheme(QStringLiteral("wallet-closed")), i18nc("Noun, a type of account", "Wallet"), static_cast<int>(SKGAccountObject::WALLET));
ui.kAccountCreatorType->addItem(i18nc("Noun, a type of account", "Other"), static_cast<int>(SKGAccountObject::OTHER));
// Bind account creation view
ui.kView->setModel(new SKGObjectModel(qobject_cast<SKGDocumentBank*>(getDocument()), QStringLiteral("v_account_display"), QStringLiteral("1=0"), this, QLatin1String(""), false));
connect(ui.kView->getView(), &SKGTreeView::clickEmptyArea, this, &SKGBankPluginWidget::cleanEditor);
connect(ui.kView->getView(), &SKGTreeView::doubleClicked, SKGMainPanel::getMainPanel()->getGlobalAction(QStringLiteral("open")).data(), &QAction::trigger);
connect(ui.kView->getView(), &SKGTreeView::selectionChangedDelayed, this, [ = ] {this->onSelectionChanged();});
// Search file list
QString listIconFile = QStandardPaths::locate(QStandardPaths::GenericDataLocation, "skrooge/images/logo/l10n/" % QLocale::countryToString(QLocale().country()) % "/list_bank.txt");
if (listIconFile.isEmpty()) {
listIconFile = QStandardPaths::locate(QStandardPaths::GenericDataLocation, QStringLiteral("skrooge/images/logo/list_bank.txt"));
}
// Logo for banks
ui.kAccountCreatorIcon->addItem(QLatin1String(""));
QFile file(listIconFile);
if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
QTextStream in(&file);
while (!in.atEnd()) {
QString line = in.readLine().trimmed();
if (!line.isEmpty()) {
QString fileName = QStandardPaths::locate(QStandardPaths::GenericDataLocation, "skrooge/images/logo/" % line);
QString bankName = line;
bankName.remove(QStringLiteral(".png"));
bankName.replace('_', ' ');
QRegExp rx(QStringLiteral("(.+) {2,}(.+)"));
if (rx.indexIn(bankName) != -1) {
// Icon is something like <bank name>__<banknumber>.png
ui.kAccountCreatorIcon->addItem(QIcon(fileName), rx.cap(1), rx.cap(2));
} else {
ui.kAccountCreatorIcon->addItem(QIcon(fileName), bankName, "");
}
}
}
ui.kAccountCreatorIcon->addItem(SKGServices::fromTheme(QStringLiteral("document-open-folder")), i18nc("Other type of bank account", "Other..."));
file.close();
}
// Set Event filters to catch CTRL+ENTER or SHIFT+ENTER
this->installEventFilter(this);
// Activate the edit panel per default
ui.kWidgetSelector->setSelectedMode(0);
// Connects
connect(ui.kAccountCreatorAdd, &QPushButton::clicked, this, &SKGBankPluginWidget::onAddAccountClicked);
connect(ui.kAccountCreatorUpdate, &QPushButton::clicked, this, &SKGBankPluginWidget::onModifyAccountClicked);
connect(ui.kAccountCreatorAccount, &QLineEdit::textChanged, this, &SKGBankPluginWidget::onAccountCreatorModified);
connect(ui.kUnitEdit, &SKGUnitComboBox::editTextChanged, this, &SKGBankPluginWidget::onAccountCreatorModified);
connect(ui.kAccountCreatorType, static_cast<void (SKGComboBox::*)(int)>(&SKGComboBox::currentIndexChanged), this, &SKGBankPluginWidget::onAccountCreatorModified);
connect(ui.kWidgetSelector, &SKGWidgetSelector::selectedModeChanged, this, &SKGBankPluginWidget::onAccountCreatorModified);
connect(ui.kAmountEdit, &SKGCalculatorEdit::textChanged, this, &SKGBankPluginWidget::onAccountCreatorModified);
connect(ui.kAccountCreatorIcon, static_cast<void (SKGComboBox::*)(int)>(&SKGComboBox::currentIndexChanged), this, &SKGBankPluginWidget::onIconChanged);
connect(ui.kAccountCreatorBank, &SKGComboBox::editTextChanged, this, &SKGBankPluginWidget::onAccountCreatorModified);
connect(ui.kMinLimit, &QCheckBox::toggled, ui.kMinLimitAmout, &SKGCalculatorEdit::setEnabled);
connect(ui.kMaxLimit, &QCheckBox::toggled, ui.kMaxLimitAmout, &SKGCalculatorEdit::setEnabled);
connect(ui.kUnitEdit, &SKGUnitComboBox::editTextChanged, ui.kMinLimitunit, &QLabel::setText);
connect(ui.kUnitEdit, &SKGUnitComboBox::editTextChanged, ui.kMaxLimitunit, &QLabel::setText);
// Must be done after the connects
ui.kUnitEdit->setDocument(iDocument);
// Refresh
connect(getDocument(), &SKGDocument::tableModified, this, &SKGBankPluginWidget::dataModified, Qt::QueuedConnection);
dataModified(QLatin1String(""), 0);
}
SKGBankPluginWidget::~SKGBankPluginWidget()
{
SKGTRACEINFUNC(10)
}
bool SKGBankPluginWidget::eventFilter(QObject* iObject, QEvent* iEvent)
{
if ((iEvent != nullptr) && iEvent->type() == QEvent::KeyPress) {
auto* keyEvent = dynamic_cast<QKeyEvent*>(iEvent);
if (keyEvent && (keyEvent->key() == Qt::Key_Return || keyEvent->key() == Qt::Key_Enter) && iObject == this) {
if ((QApplication::keyboardModifiers() & Qt::ControlModifier) != 0u && ui.kAccountCreatorAdd->isEnabled()) {
ui.kAccountCreatorAdd->click();
} else if ((QApplication::keyboardModifiers() &Qt::ShiftModifier) != 0u && ui.kAccountCreatorUpdate->isEnabled()) {
ui.kAccountCreatorUpdate->click();
}
}
}
return SKGTabPage::eventFilter(iObject, iEvent);
}
void SKGBankPluginWidget::onSelectionChanged()
{
SKGTRACEINFUNC(10)
// Mapping
int nbSelect = ui.kView->getView()->getNbSelectedObjects();
if (nbSelect == 1) {
// set the icon
SKGAccountObject account(ui.kView->getView()->getFirstSelectedObject());
SKGBankObject bank;
account.getBank(bank);
QString fileName = bank.getIcon();
QString iconName = fileName;
if (!iconName.isEmpty()) {
iconName.remove(QStringLiteral(".png"));
iconName.replace('_', ' ');
QRegExp rx(QStringLiteral("(.+) {2,}(.+)"));
if (rx.indexIn(iconName) != -1) {
iconName = rx.cap(1);
}
if (ui.kAccountCreatorIcon->contains(iconName)) {
ui.kAccountCreatorIcon->setText(iconName);
} else if (ui.kAccountCreatorIcon->contains(fileName)) {
ui.kAccountCreatorIcon->setText(fileName);
} else {
int c = ui.kAccountCreatorIcon->count() - 1;
bool b = ui.kAccountCreatorIcon->blockSignals(true);
ui.kAccountCreatorIcon->insertItem(c, QIcon(fileName), fileName);
ui.kAccountCreatorIcon->setCurrentIndex(c);
ui.kAccountCreatorIcon->blockSignals(b);
}
} else {
ui.kAccountCreatorIcon->setText(QLatin1String(""));
}
ui.kAccountCreatorBank->setText(account.getAttribute(QStringLiteral("t_BANK")));
ui.kAccountCreatorAccount->setText(account.getAttribute(QStringLiteral("t_name")));
ui.kAccountCreatorBankNumber->setText(account.getAttribute(QStringLiteral("t_BANK_NUMBER")));
ui.kAccountCreatorAgencyNumber->setText(account.getAttribute(QStringLiteral("t_agency_number")));
ui.kAccountCreatorNumber->setText(account.getAttribute(QStringLiteral("t_number")));
ui.kAccountCreatorType->setText(account.getAttribute(QStringLiteral("t_TYPENLS")));
ui.kAccountCreatorAddress->setText(account.getAttribute(QStringLiteral("t_agency_address")));
ui.kAccountCreatorComment->setText(account.getAttribute(QStringLiteral("t_comment")));
ui.kMinLimitAmout->setText(account.getAttribute(QStringLiteral("f_minamount")));
ui.kMaxLimitAmout->setText(account.getAttribute(QStringLiteral("f_maxamount")));
ui.kMaxLimit->setTristate(false);
ui.kMaxLimit->setCheckState(account.isMaxLimitAmountEnabled() ? Qt::Checked : Qt::Unchecked);
ui.kMinLimit->setTristate(false);
ui.kMinLimit->setCheckState(account.isMinLimitAmountEnabled() ? Qt::Checked : Qt::Unchecked);
double oBalance = 0;
SKGUnitObject oUnit;
account.getInitialBalance(oBalance, oUnit);
int nbDec = oUnit.getNumberDecimal();
if (nbDec == 0) {
nbDec = 2;
}
ui.kAmountEdit->setText(SKGServices::toCurrencyString(oBalance, QLatin1String(""), nbDec));
if (oUnit.exist()) {
ui.kUnitEdit->setUnit(oUnit);
} else {
auto* doc = qobject_cast<SKGDocumentBank*>(getDocument());
if (doc != nullptr) {
SKGServices::SKGUnitInfo primary = doc->getPrimaryUnit();
ui.kUnitEdit->setText(primary.Symbol);
}
}
} else if (nbSelect > 1) {
ui.kAccountCreatorIcon->setText(NOUPDATE);
ui.kAccountCreatorBank->setText(NOUPDATE);
ui.kAccountCreatorAccount->setText(NOUPDATE);
ui.kAccountCreatorBankNumber->setText(NOUPDATE);
ui.kAccountCreatorAgencyNumber->setText(NOUPDATE);
ui.kAccountCreatorNumber->setText(NOUPDATE);
ui.kAccountCreatorType->setText(NOUPDATE);
ui.kAccountCreatorAddress->setText(NOUPDATE);
ui.kAccountCreatorComment->setText(NOUPDATE);
ui.kAmountEdit->setText(NOUPDATE);
ui.kUnitEdit->setText(NOUPDATE);
ui.kMinLimitAmout->setText(NOUPDATE);
ui.kMaxLimitAmout->setText(NOUPDATE);
ui.kMaxLimit->setTristate(true);
ui.kMaxLimit->setCheckState(Qt::PartiallyChecked);
ui.kMinLimit->setTristate(true);
ui.kMinLimit->setCheckState(Qt::PartiallyChecked);
}
// Refresh graph
m_timer2.start(300);
onAccountCreatorModified();
Q_EMIT selectionChanged();
}
void SKGBankPluginWidget::onRefreshGraphDelayed()
{
m_timer2.start(300);
}
void SKGBankPluginWidget::onRefreshGraph()
{
SKGTRACEINFUNC(10)
if (m_graph != nullptr) {
bool visible = ui.kView->getShowWidget()->getState().contains(QStringLiteral("graph"));
QDomDocument doc(QStringLiteral("SKGML"));
if (doc.setContent(m_graph->getState())) {
QDomElement root = doc.documentElement();
QString graphS = root.attribute(QStringLiteral("graph"));
QDomDocument doc2(QStringLiteral("SKGML"));
if (doc2.setContent(graphS)) {
QDomElement root2 = doc2.documentElement();
QString wc;
QString title;
int nbSelect = 0;
if (visible) {
SKGObjectBase::SKGListSKGObjectBase objs = ui.kView->getView()->getSelectedObjects();
nbSelect = objs.count();
if (nbSelect != 0) {
wc = QStringLiteral("t_ACCOUNT IN (");
title = i18nc("Noun, a list of items", "Operations of account ");
for (int i = 0; i < nbSelect; ++i) {
if (i != 0) {
wc += ',';
title += ',';
}
SKGAccountObject act(objs.at(i));
wc += '\'' % SKGServices::stringToSqlString(act.getName()) % '\'';
title += i18n("'%1'", act.getName());
}
wc += ')';
}
} else {
wc = QStringLiteral("1=0");
title = QStringLiteral("none");
}
root2.setAttribute(QStringLiteral("operationWhereClause"), wc);
root2.setAttribute(QStringLiteral("title"), title);
root2.setAttribute(QStringLiteral("lines"), nbSelect != 0 ? QStringLiteral("t_ACCOUNT") : QStringLiteral("#NOTHING#"));
}
root.setAttribute(QStringLiteral("graph"), doc2.toString());
}
QString newGraphState = doc.toString();
if (newGraphState != m_graphState) {
m_graphState = newGraphState;
m_graph->setState(m_graphState);
}
m_graph->setVisible(visible);
}
}
void SKGBankPluginWidget::onIconChanged()
{
SKGTRACEINFUNC(10)
int c = ui.kAccountCreatorIcon->currentIndex();
if ((c != 0) && c == ui.kAccountCreatorIcon->count() - 1) {
QString fileName = QFileDialog::getOpenFileName(this,
i18nc("Title of panel", "Select a bank icon"),
QStandardPaths::locate(QStandardPaths::GenericDataLocation, QStringLiteral("skrooge/images/logo/"), QStandardPaths::LocateDirectory),
i18nc("File format for open dialog panel", "Image files") % " (*.png *.jpeg *.jpg *.gif *.tiff)");
if (!fileName.isEmpty()) {
if (ui.kAccountCreatorIcon->contains(fileName)) {
ui.kAccountCreatorIcon->setText(fileName);
} else {
bool b = ui.kAccountCreatorIcon->blockSignals(true);
ui.kAccountCreatorIcon->insertItem(c, QIcon(fileName), fileName);
ui.kAccountCreatorIcon->setCurrentIndex(c);
ui.kAccountCreatorIcon->blockSignals(b);
}
} else {
ui.kAccountCreatorIcon->setCurrentIndex(c - 1);
}
}
if (ui.kAccountCreatorIcon->currentIndex() != 0) {
// Set the bank name
QString name = ui.kAccountCreatorIcon->currentText();
QFileInfo f(name);
if (f.exists()) {
name = f.baseName();
name = name.replace('_', ' ');
}
ui.kAccountCreatorBank->setText(name);
} else {
ui.kAccountCreatorBank->setText(QLatin1String(""));
}
// Facilitate bank number
QString code = ui.kAccountCreatorIcon->itemData(ui.kAccountCreatorIcon->currentIndex()).toString();
ui.kAccountCreatorBankNumber->setText(code);
}
void SKGBankPluginWidget::onAccountCreatorModified()
{
SKGTRACEINFUNC(10)
bool activatedForWallet = ui.kWidgetSelector->getSelectedMode() != -1 &&
!ui.kAccountCreatorAccount->text().isEmpty() &&
!ui.kAccountCreatorAccount->text().startsWith(QLatin1Char('=')) &&
!ui.kUnitEdit->currentText().isEmpty() &&
(ui.kAmountEdit->valid() || ui.kAmountEdit->text().isEmpty() || ui.kAmountEdit->text() == NOUPDATE);
bool activated = activatedForWallet &&
!ui.kAccountCreatorBank->text().isEmpty() &&
!ui.kAccountCreatorBank->text().startsWith(QLatin1Char('='));
bool wallet = (static_cast<SKGAccountObject::AccountType>(ui.kAccountCreatorType->itemData(ui.kAccountCreatorType->currentIndex()).toInt()) == SKGAccountObject::WALLET);
int nbSelect = getNbSelectedObjects();
ui.kAccountCreatorAdd->setEnabled(activated || (wallet && activatedForWallet));
ui.kAccountCreatorUpdate->setEnabled((activated || (wallet && activatedForWallet)) && nbSelect > 0);
// Wallet specific mode
ui.kBankNumberLbl->setVisible(!wallet);
ui.kAccountCreatorBankNumber->setVisible(!wallet);
ui.kAgencyNumberLbl->setVisible(!wallet);
ui.kAccountCreatorAgencyNumber->setVisible(!wallet);
ui.kNumberLbl->setVisible(!wallet);
ui.kAccountCreatorNumber->setVisible(!wallet);
ui.kBankLbl->setVisible(!wallet);
ui.kAccountCreatorIcon->setVisible(!wallet);
ui.kAccountCreatorBank->setVisible(!wallet);
ui.kAccountCreatorAddress->setVisible(!wallet);
ui.kAgencyAddressLbl->setVisible(!wallet);
}
SKGError SKGBankPluginWidget::setInitialBalanceFromEditor(SKGAccountObject& iAccount)
{
return (ui.kAmountEdit->text() != NOUPDATE && ui.kUnitEdit->text() != NOUPDATE ? iAccount.setInitialBalance(ui.kAmountEdit->value(), ui.kUnitEdit->getUnit()) : SKGError());
}
void SKGBankPluginWidget::onAddAccountClicked()
{
SKGError err;
SKGTRACEINFUNCRC(10, err) {
SKGAccountObject accountObj;
QString bankName = ui.kAccountCreatorBank->text();
QString accountName = ui.kAccountCreatorAccount->text();
QString name = bankName % '-' % accountName;
SKGAccountObject::AccountType accountType = static_cast<SKGAccountObject::AccountType>(ui.kAccountCreatorType->itemData(ui.kAccountCreatorType->currentIndex()).toInt());
if (accountType == SKGAccountObject::WALLET) {
bankName = QLatin1String("");
}
{
SKGBEGINTRANSACTION(*getDocument(), i18nc("Creating an account", "Account creation '%1'", name), err)
// Create bank object in case of missing
SKGBankObject bankObj(getDocument());
IFOKDO(err, bankObj.setName(ui.kAccountCreatorBank->text()))
IFOK(err) {
// Build icon name
QString icon = ui.kAccountCreatorIcon->currentText();
if (!QFile(icon).exists() && !icon.isEmpty()) {
QString code = ui.kAccountCreatorIcon->itemData(ui.kAccountCreatorIcon->currentIndex()).toString();
if (!code.isEmpty()) {
icon += " " % code;
}
icon.replace(' ', '_');
icon += QStringLiteral(".png");
}
err = bankObj.setIcon(icon);
}
IFOKDO(err, bankObj.setNumber(ui.kAccountCreatorBankNumber->text()))
IFOKDO(err, bankObj.save())
IFOKDO(err, bankObj.load())
// Create account object in case of missing
IFOKDO(err, bankObj.addAccount(accountObj))
IFOKDO(err, accountObj.setName(accountName))
IFOKDO(err, accountObj.setAgencyNumber(ui.kAccountCreatorAgencyNumber->text()))
IFOKDO(err, accountObj.setAgencyAddress(ui.kAccountCreatorAddress->text()))
IFOKDO(err, accountObj.setComment(ui.kAccountCreatorComment->text()))
IFOKDO(err, accountObj.setNumber(ui.kAccountCreatorNumber->text()))
IFOKDO(err, accountObj.setType(accountType))
IFOKDO(err, accountObj.maxLimitAmountEnabled(ui.kMaxLimit->isChecked()))
IFOKDO(err, accountObj.setMaxLimitAmount(ui.kMaxLimitAmout->value()))
IFOKDO(err, accountObj.minLimitAmountEnabled(ui.kMinLimit->isChecked()))
IFOKDO(err, accountObj.setMinLimitAmount(ui.kMinLimitAmout->value()))
IFOKDO(err, accountObj.save(false))
IFOKDO(err, setInitialBalanceFromEditor(accountObj))
IFOKDO(err, accountObj.save())
// Send message
IFOKDO(err, accountObj.getDocument()->sendMessage(i18nc("An information to the user that something was added", "The account '%1' has been added", accountObj.getDisplayName()), SKGDocument::Hidden))
}
// status bar
IFOK(err) {
err = SKGError(0, i18nc("Successfully created an account", "Account '%1' created", name));
ui.kView->getView()->selectObject(accountObj.getUniqueID());
} else {
err.addError(ERR_FAIL, i18nc("Error message : Could not create an account", "Account creation failed"));
}
}
// Display error
SKGMainPanel::displayErrorMessage(err, true);
}
void SKGBankPluginWidget::onModifyAccountClicked()
{
SKGError err;
SKGTRACEINFUNCRC(10, err) {
// Get Selection
SKGObjectBase::SKGListSKGObjectBase selection = getSelectedObjects();
int nb = selection.count();
// Is it a massive modification of accounts to merge them ?
SKGBEGINPROGRESSTRANSACTION(*getDocument(), i18nc("Updating an account", "Account update"), err, nb)
auto name = ui.kAccountCreatorAccount->text();
if (name != NOUPDATE && !name.startsWith(QLatin1String("="))) {
// Is this name already existing?
bool messageSent = false;
SKGAccountObject p(getDocument());
p.setName(name);
IFOK(p.load()) {
if (selection.indexOf(p) == -1) {
// We will have to merge with the existing account
selection.insert(0, p);
nb++;
getDocument()->sendMessage(i18nc("Information message", "You tried to modify names of selected accounts to an existing account. Accounts have been merged."));
messageSent = true;
}
}
// Is it a massive modification of account to merge them ?
if (nb > 1) {
if (!messageSent) {
getDocument()->sendMessage(i18nc("Information message", "You tried to modify all names of selected accounts. Accounts have been merged."));
}
// Do the merge
SKGAccountObject accountObj1(selection[0]);
for (int i = 1; !err && i < nb; ++i) {
SKGAccountObject accountObj(selection.at(i));
err = accountObj1.merge(accountObj, true);
}
// Change selection for the rest of the operation
selection.clear();
selection.push_back(accountObj1);
nb = 1;
}
}
QString bankName = ui.kAccountCreatorBank->text();
SKGAccountObject::AccountType accountType = static_cast<SKGAccountObject::AccountType>(ui.kAccountCreatorType->itemData(ui.kAccountCreatorType->currentIndex()).toInt());
if (accountType == SKGAccountObject::WALLET) {
bankName = QLatin1String("");
}
for (int i = 0; !err && i < nb; ++i) {
SKGAccountObject accountObj(selection.at(i));
err = accountObj.setName(name);
IFOKDO(err, accountObj.setNumber(ui.kAccountCreatorNumber->text()))
IFOKDO(err, setInitialBalanceFromEditor(accountObj))
if (!err && ui.kAccountCreatorType->text() != NOUPDATE) {
err = accountObj.setType(static_cast<SKGAccountObject::AccountType>(ui.kAccountCreatorType->itemData(ui.kAccountCreatorType->currentIndex()).toInt()));
}
IFOKDO(err, accountObj.setAgencyNumber(ui.kAccountCreatorAgencyNumber->text()))
IFOKDO(err, accountObj.setAgencyAddress(ui.kAccountCreatorAddress->text()))
IFOKDO(err, accountObj.setComment(ui.kAccountCreatorComment->text()))
if (!err && ui.kMaxLimit->checkState() != Qt::PartiallyChecked) {
err = accountObj.maxLimitAmountEnabled(ui.kMaxLimit->isChecked());
}
if (!err && ui.kMaxLimitAmout->text() != NOUPDATE) {
err = accountObj.setMaxLimitAmount(ui.kMaxLimitAmout->value());
}
if (!err && ui.kMinLimit->checkState() != Qt::PartiallyChecked) {
err = accountObj.minLimitAmountEnabled(ui.kMinLimit->isChecked());
}
if (!err && ui.kMaxLimitAmout->text() != NOUPDATE) {
err = accountObj.setMinLimitAmount(ui.kMinLimitAmout->value());
}
IFOKDO(err, accountObj.save())
// Send message
IFOKDO(err, accountObj.getDocument()->sendMessage(i18nc("An information message", "The account '%1' has been updated", accountObj.getDisplayName()), SKGDocument::Hidden))
// Update bank
SKGBankObject bankObj;
if (bankName == NOUPDATE) {
accountObj.getBank(bankObj);
} else {
if (SKGNamedObject::getObjectByName(getDocument(), QStringLiteral("bank"), bankName, bankObj).isSucceeded()) {
// The created bank already exist ==> update parent bank
IFOKDO(err, accountObj.setBank(bankObj))
IFOKDO(err, accountObj.save())
} else {
// The bank does not exist
int code = KMessageBox::Yes;
SKGBankObject currentBank;
err = accountObj.getBank(currentBank);
IFOK(err) {
SKGObjectBase::SKGListSKGObjectBase accounts;
err = currentBank.getAccounts(accounts);
if (!err && accounts.count() > 1) {
QApplication::setOverrideCursor(QCursor(Qt::ArrowCursor));
code = KMessageBox::questionYesNo(this, i18nc("Question", "You are trying to modify bank name of account named '%1'.\nDo you want to do this modification for all accounts of this bank ? ", accountObj.getName()));
QApplication::restoreOverrideCursor();
}
}
IFOKDO(err, accountObj.getBank(bankObj))
if (code == KMessageBox::Yes) {
// The bank does not exist ==> update this one
IFOKDO(err, bankObj.setName(bankName))
} else {
// The bank does not exist ==> create a new one
IFOKDO(err, bankObj.resetID())
IFOKDO(err, bankObj.setName(bankName))
IFOKDO(err, bankObj.save())
IFOKDO(err, accountObj.setBank(bankObj))
IFOKDO(err, accountObj.save())
}
}
}
if (ui.kAccountCreatorIcon->text() != NOUPDATE) {
IFOK(err) {
// Build icon name
QString icon = ui.kAccountCreatorIcon->currentText();
if (!QFile(icon).exists() && !icon.isEmpty()) {
QString code = ui.kAccountCreatorIcon->itemData(ui.kAccountCreatorIcon->currentIndex()).toString();
if (!code.isEmpty()) {
icon += " " % code;
}
icon.replace(' ', '_');
icon += QStringLiteral(".png");
}
err = bankObj.setIcon(icon);
}
}
IFOKDO(err, bankObj.setNumber(ui.kAccountCreatorBankNumber->text()))
IFOKDO(err, bankObj.save())
IFOKDO(err, getDocument()->stepForward(i + 1))
}
// Remove bank without account
IFOK(err) {
err = getDocument()->executeSqliteOrder(QStringLiteral("DELETE FROM bank WHERE NOT EXISTS(SELECT 1 FROM account WHERE account.rd_bank_id = bank.id)"));
}
}
// status bar
IFOKDO(err, SKGError(0, i18nc("Successfully updated an account", "Account updated.")))
else {
err.addError(ERR_FAIL, i18nc("Error message : Could not update an account", "Update failed"));
}
// Display error
SKGMainPanel::displayErrorMessage(err, true);
// Set focus on table
ui.kView->getView()->setFocus();
}
void SKGBankPluginWidget::cleanEditor()
{
if (getNbSelectedObjects() == 0) {
ui.kAccountCreatorIcon->setText(QLatin1String(""));
ui.kAccountCreatorBank->setText(QLatin1String(""));
ui.kAccountCreatorAccount->setText(QLatin1String(""));
ui.kAccountCreatorBankNumber->setText(QLatin1String(""));
ui.kAccountCreatorAgencyNumber->setText(QLatin1String(""));
ui.kAccountCreatorNumber->setText(QLatin1String(""));
ui.kAccountCreatorType->setText(i18nc("Noun, a type of account", "Current"));
ui.kAccountCreatorAddress->setText(QLatin1String(""));
ui.kAccountCreatorComment->setText(QLatin1String(""));
ui.kAmountEdit->setText(QStringLiteral("0"));
ui.kUnitEdit->refershList();
}
}
QString SKGBankPluginWidget::getState()
{
SKGTRACEINFUNC(10)
QDomDocument doc(QStringLiteral("SKGML"));
QDomElement root = doc.createElement(QStringLiteral("parameters"));
doc.appendChild(root);
root.setAttribute(QStringLiteral("currentPage"), SKGServices::intToString(ui.kWidgetSelector->getSelectedMode()));
root.setAttribute(QStringLiteral("view"), ui.kView->getState());
root.setAttribute(QStringLiteral("graph"), m_graph->getState());
return doc.toString();
}
void SKGBankPluginWidget::setState(const QString& iState)
{
SKGTRACEINFUNC(10)
QDomDocument doc(QStringLiteral("SKGML"));
doc.setContent(iState);
QDomElement root = doc.documentElement();
QString currentPage = root.attribute(QStringLiteral("currentPage"));
if (currentPage.isEmpty()) {
currentPage = '0';
}
ui.kWidgetSelector->setSelectedMode(SKGServices::stringToInt(currentPage));
ui.kView->setState(root.attribute(QStringLiteral("view")));
m_graph->setState(root.attribute(QStringLiteral("graph")));
onRefreshGraph();
}
QString SKGBankPluginWidget::getDefaultStateAttribute()
{
return QStringLiteral("SKGBANK_DEFAULT_PARAMETERS");
}
void SKGBankPluginWidget::dataModified(const QString& iTableName, int iIdTransaction, bool iLightTransaction)
{
SKGTRACEINFUNC(10)
Q_UNUSED(iIdTransaction)
// Refresh widgets
if (iTableName == QStringLiteral("v_account_display") || iTableName.isEmpty()) {
// Refresh info area
m_timer.start(300);
}
if (!iLightTransaction) {
if (iTableName == QStringLiteral("bank") || iTableName.isEmpty()) {
// Set completions
SKGMainPanel::fillWithDistinctValue(QList<QWidget*>() << ui.kAccountCreatorBank, getDocument(), QStringLiteral("bank"), QStringLiteral("t_name"), QLatin1String(""), true);
}
if (iTableName == QStringLiteral("account") || iTableName.isEmpty()) {
// Set completions
SKGMainPanel::fillWithDistinctValue(QList<QWidget*>() << ui.kAccountCreatorAccount, getDocument(), QStringLiteral("account"), QStringLiteral("t_name"), QLatin1String(""), true);
SKGMainPanel::fillWithDistinctValue(QList<QWidget*>() << ui.kAccountCreatorBankNumber, getDocument(), QStringLiteral("bank"), QStringLiteral("t_bank_number"), QLatin1String(""), true);
SKGMainPanel::fillWithDistinctValue(QList<QWidget*>() << ui.kAccountCreatorAgencyNumber, getDocument(), QStringLiteral("account"), QStringLiteral("t_agency_number"), QLatin1String(""), true);
SKGMainPanel::fillWithDistinctValue(QList<QWidget*>() << ui.kAccountCreatorNumber, getDocument(), QStringLiteral("account"), QStringLiteral("t_number"), QLatin1String(""), true);
SKGMainPanel::fillWithDistinctValue(QList<QWidget*>() << ui.kAccountCreatorAddress, getDocument(), QStringLiteral("account"), QStringLiteral("t_agency_address"), QLatin1String(""), true);
SKGMainPanel::fillWithDistinctValue(QList<QWidget*>() << ui.kAccountCreatorComment, getDocument(), QStringLiteral("account"), QStringLiteral("t_comment"), QLatin1String(""), true);
}
}
}
void SKGBankPluginWidget::refreshInfoZone()
{
SKGTRACEINFUNC(10)
auto* doc = qobject_cast<SKGDocumentBank*>(getDocument());
if (doc != nullptr) {
ui.kInfo->setText(i18nc("Message", "Computing..."));
doc->concurrentExecuteSelectSqliteOrder(QStringLiteral("SELECT TOTAL(f_TODAYAMOUNT), TOTAL(f_CURRENTAMOUNT), TOTAL(f_CHECKED), TOTAL(f_COMING_SOON) from v_account_display"), [ = ](const SKGStringListList & iResult) {
if (iResult.count() == 2 && SKGMainPanel::getMainPanel()->pageIndex(this) != -1) {
SKGServices::SKGUnitInfo primary = doc->getPrimaryUnit();
double v1 = SKGServices::stringToDouble(iResult.at(1).at(0));
double v2 = SKGServices::stringToDouble(iResult.at(1).at(1));
double v3 = SKGServices::stringToDouble(iResult.at(1).at(2));
double v4 = SKGServices::stringToDouble(iResult.at(1).at(3));
QString s1 = doc->formatMoney(v1, primary);
QString s2 = doc->formatMoney(v2, primary);
QString s3 = doc->formatMoney(v3, primary);
QString s4 = doc->formatMoney(v4, primary);
ui.kInfo->setText(i18nc("Information on an account's status : Balance is the current amount of money on the account, Checked is the amount of money on your last bank's statement, To be Checked is the differences between these two values", "Today balance : %1 Balance : %2 Checked : %3 To be Checked : %4", s1, s2, s3, s4));
SKGServices::SKGUnitInfo secondaryUnit = doc->getSecondaryUnit();
if (!secondaryUnit.Symbol.isEmpty() && (secondaryUnit.Value != 0.0)) {
s1 = doc->formatMoney(v1, secondaryUnit);
s2 = doc->formatMoney(v2, secondaryUnit);
s3 = doc->formatMoney(v3, secondaryUnit);
s4 = doc->formatMoney(v4, secondaryUnit);
}
ui.kInfo->setToolTip(i18nc("Information on an account's status : Balance is the current amount of money on the account, Checked is the amount of money on your last bank's statement, To be Checked is the differences between these two values", "<p>Today balance : %1 < / p > <p>Balance : %2 < / p > <p>Checked : %3 < / p > <p>To be Checked : %4 < / p > ", s1, s2, s3, s4));
}
});
}
}
QWidget* SKGBankPluginWidget::mainWidget()
{
return ui.kView->getView();
}
QList< QWidget* > SKGBankPluginWidget::printableWidgets()
{
QList< QWidget* > output;
output.push_back(mainWidget());
if ((m_graph != nullptr) && m_graph->isVisible()) {
output.push_back(m_graph);
}
return output;
}
void SKGBankPluginWidget::activateEditor()
{
if (ui.kWidgetSelector->getSelectedMode() == -1) {
ui.kWidgetSelector->setSelectedMode(0);
}
ui.kAccountCreatorBank->setFocus();
}
bool SKGBankPluginWidget::isEditor()
{
return true;
}
diff --git a/plugins/skrooge/skrooge_bank/skgbankpluginwidget.h b/plugins/skrooge/skrooge_bank/skgbankpluginwidget.h
index 5d6b0fe6b..ba4447751 100644
--- a/plugins/skrooge/skrooge_bank/skgbankpluginwidget.h
+++ b/plugins/skrooge/skrooge_bank/skgbankpluginwidget.h
@@ -1,132 +1,132 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGBANKPLUGINWIDGET_H
#define SKGBANKPLUGINWIDGET_H
/** @file
* This file is Skrooge plugin for bank management.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include <qstringlist.h>
#include <qtimer.h>
#include "skgaccountobject.h"
#include "skgtabpage.h"
#include "ui_skgbankpluginwidget_base.h"
class SKGBoardWidget;
class SKGDocumentBank;
/**
* This file is Skrooge plugin for bank management
*/
class SKGBankPluginWidget : public SKGTabPage
{
Q_OBJECT
public:
/**
* Default Constructor
* @param iParent the parent widget
* @param iDocument the document
*/
explicit SKGBankPluginWidget(QWidget* iParent, SKGDocumentBank* iDocument);
/**
* Default Destructor
*/
~SKGBankPluginWidget() override;
/**
* Get the current state
* MUST BE OVERWRITTEN
* @return a string containing all information needed to set the same state.
* Could be an XML stream
*/
QString getState() override;
/**
* Set the current state
* MUST BE OVERWRITTEN
* @param iState must be interpreted to set the state of the widget
*/
void setState(const QString& iState) override;
/**
* Get attribute name to save the default state
* MUST BE OVERWRITTEN
* @return attribute name to save the default state.
*/
QString getDefaultStateAttribute() override;
/**
* Get the main widget
* @return a widget
*/
QWidget* mainWidget() override;
/**
* Get the printable widgets.
* The default implementation returns the main widget.
* @return the printable widgets.
*/
QList<QWidget*> printableWidgets() override;
/**
* To know if this page contains an editor. MUST BE OVERWRITTEN
* @return the editor state
*/
bool isEditor() override;
/**
* To activate the editor by setting focus on right widget. MUST BE OVERWRITTEN
*/
void activateEditor() override;
protected:
/**
* Event filtering
* @param iObject object
* @param iEvent event
* @return In your reimplementation of this function, if you want to filter the event out, i.e. stop it being handled further, return true; otherwise return false.
*/
bool eventFilter(QObject* iObject, QEvent* iEvent) override;
private Q_SLOTS:
void dataModified(const QString& iTableName, int iIdTransaction, bool iLightTransaction = false);
void onIconChanged();
void onAccountCreatorModified();
void onAddAccountClicked();
void onModifyAccountClicked();
void onSelectionChanged();
void onRefreshGraphDelayed();
void onRefreshGraph();
void cleanEditor();
void refreshInfoZone();
SKGError setInitialBalanceFromEditor(SKGAccountObject& iAccount);
private:
Q_DISABLE_COPY(SKGBankPluginWidget)
Ui::skgbankplugin_base ui{};
QTimer m_timer;
QTimer m_timer2;
SKGBoardWidget* m_graph;
QString m_graphState;
};
#endif // SKGDEBUGPLUGIN_H
diff --git a/plugins/skrooge/skrooge_bank/skgbankpluginwidget_base.ui b/plugins/skrooge/skrooge_bank/skgbankpluginwidget_base.ui
index c072ea086..e9efd159e 100644
--- a/plugins/skrooge/skrooge_bank/skgbankpluginwidget_base.ui
+++ b/plugins/skrooge/skrooge_bank/skgbankpluginwidget_base.ui
@@ -1,714 +1,714 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>skgbankplugin_base</class>
<widget class="QWidget" name="skgbankplugin_base">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>604</width>
<height>360</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="spacing">
<number>2</number>
</property>
<item>
<widget class="SKGFilteredTableView" name="kView"/>
</item>
<item>
<widget class="QLabel" name="kInfo">
<property name="text">
<string>Computing...</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item>
<widget class="Line" name="line">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<widget class="QWidget" name="SKGEditionWidget" native="true">
<layout class="QGridLayout" name="gridLayout_4">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<property name="spacing">
<number>2</number>
</property>
<item row="0" column="1">
<widget class="SKGComboBox" name="kAccountCreatorIcon">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>45</width>
<height>16777215</height>
</size>
</property>
<property name="toolTip">
<string>Icon of the bank</string>
</property>
<property name="statusTip">
<string>Icon of the bank</string>
</property>
</widget>
</item>
<item row="3" column="5">
<widget class="QLabel" name="kMinLimitunit">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string notr="true">F</string>
</property>
</widget>
</item>
<item row="3" column="1" colspan="2">
<layout class="QHBoxLayout" name="horizontalLayout_11">
<property name="spacing">
<number>2</number>
</property>
<item>
<widget class="SKGCalculatorEdit" name="kAmountEdit">
<property name="toolTip">
- <string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
+ <string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;https://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Bitstream Vera Sans'; font-size:9pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Amount of the operation.&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;You can enter expressions here, such as &lt;span style=&quot; font-style:italic;&quot;&gt;3+4*2&lt;/span&gt;, skrooge will compute the result (&lt;span style=&quot; font-style:italic;&quot;&gt;11&lt;/span&gt;)&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="statusTip">
<string>Initial balance of the account</string>
</property>
</widget>
</item>
<item>
<widget class="SKGUnitComboBox" name="kUnitEdit">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>60</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>80</width>
<height>16777215</height>
</size>
</property>
<property name="toolTip">
<string>Unit of the initial balance of the account</string>
</property>
<property name="statusTip">
<string>Unit of the initial balance of the account</string>
</property>
<property name="editable">
<bool>true</bool>
</property>
<property name="sizeAdjustPolicy">
<enum>QComboBox::AdjustToContents</enum>
</property>
<property name="autoCompletion">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>0</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="1" column="1" colspan="2">
<widget class="QLineEdit" name="kAccountCreatorAccount">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>Name of the account</string>
</property>
<property name="statusTip">
<string>Name of the account</string>
</property>
</widget>
</item>
<item row="3" column="15">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>0</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="3">
<widget class="QLabel" name="kBankNumberLbl">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string notr="true">Title:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>kAccountCreatorBankNumber</cstring>
</property>
</widget>
</item>
<item row="0" column="6">
<widget class="QLabel" name="kAgencyAddressLbl">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string notr="true">Title:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>kAccountCreatorAddress</cstring>
</property>
</widget>
</item>
<item row="3" column="14">
<widget class="QLabel" name="kMaxLimitunit">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string notr="true">F</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="kBankLbl">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string notr="true">Title:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="3" column="3">
<widget class="QCheckBox" name="kMinLimit">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string notr="true">Title:</string>
</property>
</widget>
</item>
<item row="2" column="4" colspan="12">
<widget class="QLineEdit" name="kAccountCreatorNumber">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>Number of the account</string>
</property>
<property name="statusTip">
<string>Number of the account</string>
</property>
</widget>
</item>
<item row="3" column="13">
<widget class="SKGCalculatorEdit" name="kMaxLimitAmout">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>Maximum amount of the account</string>
</property>
<property name="statusTip">
<string>Maximum amount of the account</string>
</property>
</widget>
</item>
<item row="3" column="6">
<widget class="QCheckBox" name="kMaxLimit">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string notr="true">Title:</string>
</property>
</widget>
</item>
<item row="0" column="9" colspan="7">
<widget class="QLineEdit" name="kAccountCreatorAddress">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>Address of the agency</string>
</property>
<property name="statusTip">
<string>Address of the agency</string>
</property>
<property name="showClearButton" stdset="0">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="9" colspan="7">
<widget class="QLineEdit" name="kAccountCreatorComment">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>Comment of the account</string>
</property>
<property name="statusTip">
<string>Comment of the account</string>
</property>
<property name="showClearButton" stdset="0">
<bool>true</bool>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="SKGComboBox" name="kAccountCreatorBank">
<property name="minimumSize">
<size>
<width>112</width>
<height>0</height>
</size>
</property>
<property name="toolTip">
<string>Name of the bank</string>
</property>
<property name="statusTip">
<string>Name of the bank</string>
</property>
<property name="editable">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="6">
<widget class="QLabel" name="kCommentLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string notr="true">Title:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>kAccountCreatorComment</cstring>
</property>
</widget>
</item>
<item row="3" column="4">
<widget class="SKGCalculatorEdit" name="kMinLimitAmout">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>Minimum amount of the account</string>
</property>
<property name="statusTip">
<string>Minimum amount of the account</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="kAmountLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string comment="Noun, a numerical quantity">Initial &amp;balance:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>kAmountEdit</cstring>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="kAccountLbl">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
<strikeout>false</strikeout>
<stylestrategy>PreferDefault</stylestrategy>
<kerning>true</kerning>
</font>
</property>
<property name="text">
<string notr="true">&amp;Title:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>kAccountCreatorAccount</cstring>
</property>
</widget>
</item>
<item row="1" column="3">
<widget class="QLabel" name="kAgencyNumberLbl">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string notr="true">Title:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>kAccountCreatorAgencyNumber</cstring>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="kTypeLbl">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
<strikeout>false</strikeout>
<stylestrategy>PreferDefault</stylestrategy>
<kerning>true</kerning>
</font>
</property>
<property name="text">
<string notr="true">&amp;Title:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>kAccountCreatorType</cstring>
</property>
</widget>
</item>
<item row="2" column="3">
<widget class="QLabel" name="kNumberLbl">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string notr="true">Title:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>kAccountCreatorNumber</cstring>
</property>
</widget>
</item>
<item row="2" column="1" colspan="2">
<widget class="SKGComboBox" name="kAccountCreatorType">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>Type of the account</string>
</property>
<property name="statusTip">
<string>Type of the account</string>
</property>
<property name="sizeAdjustPolicy">
<enum>QComboBox::AdjustToContents</enum>
</property>
</widget>
</item>
<item row="1" column="4" colspan="2">
<widget class="QLineEdit" name="kAccountCreatorAgencyNumber">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>Number of the agency</string>
</property>
<property name="statusTip">
<string>Number of the agency</string>
</property>
</widget>
</item>
<item row="0" column="4" colspan="2">
<widget class="QLineEdit" name="kAccountCreatorBankNumber">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>Number of the bank</string>
</property>
<property name="statusTip">
<string>Number of the bank</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_12">
<property name="spacing">
<number>2</number>
</property>
<item>
<widget class="SKGWidgetSelector" name="kWidgetSelector"/>
</item>
<item>
<widget class="QWidget" name="SKGEditionButtonswidget" native="true">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="spacing">
<number>2</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QPushButton" name="kAccountCreatorAdd">
<property name="enabled">
<bool>false</bool>
</property>
<property name="toolTip">
<string>Add a bank and an account (Ctrl+Enter)</string>
</property>
<property name="statusTip">
<string>Add a bank and an account (Ctrl+Enter)</string>
</property>
<property name="text">
<string comment="Verb, add an item to a list">Add</string>
</property>
<property name="autoDefault">
<bool>true</bool>
</property>
<property name="default">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="kAccountCreatorUpdate">
<property name="enabled">
<bool>false</bool>
</property>
<property name="toolTip">
<string>Update selected banks and accounts (Shift+Enter)</string>
</property>
<property name="statusTip">
<string>Update selected banks and accounts (Shift+Enter)</string>
</property>
<property name="text">
<string comment="Verb, modify an item">Modify</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>SKGUnitComboBox</class>
<extends>SKGComboBox</extends>
<header>skgunitcombobox.h</header>
</customwidget>
<customwidget>
<class>SKGCalculatorEdit</class>
<extends>QLineEdit</extends>
<header>skgcalculatoredit.h</header>
</customwidget>
<customwidget>
<class>SKGComboBox</class>
<extends>QComboBox</extends>
<header>skgcombobox.h</header>
</customwidget>
<customwidget>
<class>SKGFilteredTableView</class>
<extends>QWidget</extends>
<header>skgfilteredtableview.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>SKGWidgetSelector</class>
<extends>QWidget</extends>
<header>skgwidgetselector.h</header>
</customwidget>
</customwidgets>
<tabstops>
<tabstop>kAmountEdit</tabstop>
<tabstop>kUnitEdit</tabstop>
<tabstop>kAccountCreatorAddress</tabstop>
<tabstop>kAccountCreatorComment</tabstop>
<tabstop>kAccountCreatorAdd</tabstop>
<tabstop>kAccountCreatorUpdate</tabstop>
</tabstops>
<resources/>
<connections/>
<slots>
<slot>onFilterChanged()</slot>
<slot>onAccountCreatorModified()</slot>
<slot>onAddAccountClicked()</slot>
<slot>onModifyAccountClicked()</slot>
<slot>onDoubleClickedAccount()</slot>
<slot>onFilterRegExpChanged()</slot>
<slot>onComputeRIB()</slot>
<slot>onBtnModeClicked()</slot>
<slot>cleanEditor()</slot>
<slot>onIconChanged()</slot>
</slots>
</ui>
diff --git a/plugins/skrooge/skrooge_budget/CMakeLists.txt b/plugins/skrooge/skrooge_budget/CMakeLists.txt
index 210892157..e6ea90181 100644
--- a/plugins/skrooge/skrooge_budget/CMakeLists.txt
+++ b/plugins/skrooge/skrooge_budget/CMakeLists.txt
@@ -1,36 +1,36 @@
#***************************************************************************
#* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
#* *
#* 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 <http://www.gnu.org/licenses/> *
+#* along with this program. If not, see <https://www.gnu.org/licenses/> *
#***************************************************************************
MESSAGE( STATUS "..:: CMAKE PLUGIN_BUDGET ::..")
PROJECT(plugin_budget)
LINK_DIRECTORIES (${LIBRARY_OUTPUT_PATH})
SET(skrooge_budget_SRCS
skgbudgetdelegate.cpp
skgbudgetplugin.cpp
skgbudgetpluginwidget.cpp)
ki18n_wrap_ui(skrooge_budget_SRCS skgbudgetpluginwidget_base.ui)
ADD_LIBRARY(skrooge_budget MODULE ${skrooge_budget_SRCS})
TARGET_LINK_LIBRARIES(skrooge_budget KF5::Parts KF5::ItemViews skgbasemodeler skgbasegui skgbankmodeler skgbankgui)
########### install files ###############
INSTALL(TARGETS skrooge_budget DESTINATION ${KDE_INSTALL_QTPLUGINDIR})
INSTALL(FILES ${PROJECT_SOURCE_DIR}/org.kde.skrooge-plugin-budget.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR})
INSTALL(FILES ${PROJECT_SOURCE_DIR}/skrooge_budget.rc DESTINATION ${KDE_INSTALL_KXMLGUI5DIR}/skrooge_budget )
diff --git a/plugins/skrooge/skrooge_budget/org.kde.skrooge-plugin-budget.desktop b/plugins/skrooge/skrooge_budget/org.kde.skrooge-plugin-budget.desktop
index e8c70fc68..43de98728 100644
--- a/plugins/skrooge/skrooge_budget/org.kde.skrooge-plugin-budget.desktop
+++ b/plugins/skrooge/skrooge_budget/org.kde.skrooge-plugin-budget.desktop
@@ -1,76 +1,76 @@
[Desktop Entry]
Name=Skrooge budget plugin
Name[bs]=Skrooge dodatak za budžet
Name[ca]=Connector de pressupostos de l'Skrooge
Name[ca@valencia]=Connector de pressupostos de l'Skrooge
Name[cs]=Modul rozpočtu pro Skrooge
Name[da]=Budget-plugin til Skrooge
Name[de]=Skrooge-Budgetmodul
Name[el]=Skrooge budget plugin
Name[en_GB]=Skrooge budget plugin
Name[es]=Complemento de presupuestos de Skrooge
Name[et]=Skrooge eelarveplugin
Name[fi]=Skroogen budjettiliitännäinen
Name[fr]=Module externe pour les budgets
Name[gl]=Complemento de orzamentos de Skrooge
Name[hu]=Skrooge költségvetés bővítmény
Name[it]=Estensione budget di Skrooge
Name[lt]=Skrooge biudžeto papildinys
Name[nb]=Skrooge budsjettmodul
Name[nds]=Finanzplaanmoduul för Skrooge
Name[nl]=Plugin voor Skrooge-budget
Name[pl]=Wtyczka budżetu dla Skrooge
Name[pt]='Plugin' de orçamentos do Skrooge
Name[pt_BR]=Plugin de orçamento do Skrooge
Name[ru]=Модуль бюджета
Name[sk]=Plugin rozpočtu Skrooge
Name[sv]=Skrooge budgetinsticksprogram
Name[tr]=Skrooge bütçe eklentisi
Name[uk]=Додаток бюджетування Skrooge
Name[x-test]=xxSkrooge budget pluginxx
Name[zh_TW]=Skrooge 預算外掛程式
Comment=A skrooge plugin to manage budgets
Comment[bs]=Skrooge dodatak za upravljanje budžetom
Comment[ca]=Un connector de l'Skrooge per gestionar pressupostos
Comment[ca@valencia]=Un connector de l'Skrooge per gestionar pressupostos
Comment[cs]=Modul správy rozpočtů pro Skrooge
Comment[da]=Et Skrooge-plugin til at håndtere budgetter
Comment[de]=Ein Skrooge-Modul zum Verwalten von Budgets
Comment[el]=Ένα πρόσθετο του skrooge για τη διαχείριση προϋπολογισμών
Comment[en_GB]=A skrooge plugin to manage budgets
Comment[es]=Un complemento de Skrooge para gestionar presupuestos
Comment[et]=Skrooge eelarve haldamise plugin
Comment[fi]=Skroogen budjetinhallintaliitännäinen
Comment[fr]=Un module externe Skrooge pour la gestion de budgets
Comment[gl]=Un complemento de Skrooge para xestionar orzamentos.
Comment[hu]=Egy Skrooge bővítmény költségvetések kezeléséhez
Comment[it]=Un'estensione di Skrooge per gestire i budget
Comment[lt]=Skrooge biudžetų tvarkymo papildinys
Comment[nb]=En Skrooge-modul for å håndtere budsjetter
Comment[nds]=En Moduul för de Pleeg vun Finanzplaans för Skrooge
Comment[nl]=Een skrooge-plugin voor het beheren van budgetten
Comment[pl]=Wtyczka Skrooge do zarządzania budżetami
Comment[pt]=Um 'plugin' do Skrooge para gerir os orçamentos
Comment[pt_BR]=Um plugin do Skrooge para gerenciar orçamentos
Comment[ru]=Модуль управления бюджетом
Comment[sk]=Plugin Skrooge na správu rozpočtu
Comment[sv]=Ett insticksprogram till Skrooge för att hantera budgetar
Comment[tr]=Bütçe yönetimi için bir skrooge eklentisi
Comment[uk]=Додаток до skrooge для керування бюджетами
Comment[x-test]=xxA skrooge plugin to manage budgetsxx
Comment[zh_TW]=管理預算用的 Skrooge 外掛程式
Encoding=UTF-8
Icon=skrooge
Type=Service
X-KDE-ServiceTypes=SKG GUI/Plugin
X-KDE-Library=skrooge_budget
X-Krunner-ID=Skrooge budget plugin
X-KDE-PluginInfo-Author=Stephane MANKOWSKI,miraks
X-KDE-PluginInfo-Email=stephane@mankowski.fr
X-KDE-PluginInfo-Name=skrooge_budget
X-KDE-PluginInfo-Version=1.0
-X-KDE-PluginInfo-Website=http://skrooge.org/
+X-KDE-PluginInfo-Website=https://skrooge.org/
X-KDE-PluginInfo-Category=Plugins
X-KDE-PluginInfo-Depends=
X-KDE-PluginInfo-License=GPL
X-KDE-PluginInfo-EnabledByDefault=true
diff --git a/plugins/skrooge/skrooge_budget/skgbudgetdelegate.cpp b/plugins/skrooge/skrooge_budget/skgbudgetdelegate.cpp
index 257574170..cf2da67b9 100644
--- a/plugins/skrooge/skrooge_budget/skgbudgetdelegate.cpp
+++ b/plugins/skrooge/skrooge_budget/skgbudgetdelegate.cpp
@@ -1,191 +1,191 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is a delegate for budget.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgbudgetdelegate.h"
#include <kcolorscheme.h>
#include <qpainter.h>
#include <qsortfilterproxymodel.h>
#include "skgobjectmodelbase.h"
#include "skgprogressbar.h"
#include "skgtraces.h"
SKGBudgetDelegate::SKGBudgetDelegate(QObject* iParent, SKGDocument* iDoc) : QStyledItemDelegate(iParent), m_document(iDoc)
{}
SKGBudgetDelegate::~SKGBudgetDelegate()
{
m_document = nullptr;
}
void SKGBudgetDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const
{
bool done = false;
if (index.isValid()) {
const auto* m = qobject_cast<const SKGObjectModelBase*> (index.model());
const auto* p = qobject_cast<const QSortFilterProxyModel*> (index.model());
if (p != nullptr) {
m = qobject_cast<SKGObjectModelBase*>(p->sourceModel());
}
if (m != nullptr) {
QString att = m->getAttribute(index.column());
// Compute percent of time
QModelIndex idxs = index;
if (p != nullptr) {
idxs = p->mapToSource(index);
}
SKGObjectBase obj = m->getObject(idxs);
int year = SKGServices::stringToDouble(obj.getAttribute(QStringLiteral("i_year")));
int month = SKGServices::stringToDouble(obj.getAttribute(QStringLiteral("i_month")));
QDate today = QDate::currentDate();
double pourcent = 1;
bool actif = true;
if (year == today.year()) {
if (month == 0) {
QDate d1(year, 1, 1);
pourcent = static_cast<double>(d1.daysTo(today)) / static_cast<double>(today.daysInYear());
} else if (month == today.month()) {
QDate d1(year, month, 1);
pourcent = static_cast<double>(d1.daysTo(today)) / static_cast<double>(today.daysInMonth());
} else if (month > today.month()) {
pourcent = 0;
actif = false;
}
} else if (year > today.year()) {
pourcent = 0;
actif = false;
}
if ((att == QStringLiteral("f_budgeted") || att == QStringLiteral("f_budgeted_modified")) && actif) {
double budgeted = SKGServices::stringToDouble(obj.getAttribute(att));
double amount = SKGServices::stringToDouble(obj.getAttribute(QStringLiteral("f_CURRENTAMOUNT")));
KColorScheme scheme(QPalette::Normal);
QColor negativeC = scheme.foreground(KColorScheme::NegativeText).color().toHsv();
QColor positiveC = scheme.foreground(KColorScheme::PositiveText).color().toHsv();
QColor backC = scheme.foreground(KColorScheme::LinkText).color().toHsv();
double coef = 0.3;
negativeC.setHsv(negativeC.hue(), negativeC.saturation()*coef, negativeC.value());
positiveC.setHsv(positiveC.hue(), positiveC.saturation()*coef, positiveC.value());
backC.setHsv(backC.hue(), backC.saturation()*coef, backC.value());
QBrush negative(negativeC);
QBrush positive(positiveC);
QBrush back(backC);
painter->save();
painter->setRenderHint(QPainter::Antialiasing);
QStyleOptionViewItem opt = option;
QStyledItemDelegate::initStyleOption(&opt, index);
QRect rect = opt.rect.adjusted(1, 1, -1, -1);
// handle selection
if ((option.state & QStyle::State_Selected) != 0u) {
KStatefulBrush sb(KColorScheme::View, KColorScheme::NormalBackground);
QBrush selectionBrush(sb.brush(QPalette::Active));
painter->setBrush(selectionBrush);
painter->drawRect(rect);
}
rect = opt.rect.adjusted(1, 1, -1, -1);
painter->setPen(Qt::NoPen);
if (budgeted > 0) {
if (amount < 0) {
amount = 0;
}
// Income
if (amount < budgeted) {
// Draw red zone
painter->setBrush(negative);
painter->drawRect(rect);
// Draw blue zone
painter->setBrush(back);
QRect r2(rect.left(), rect.top(), rect.width() * (budgeted == 0 ? 1 : amount / budgeted), rect.height());
painter->drawRect(r2);
} else {
// Draw green zone
painter->setBrush(positive);
painter->drawRect(rect);
// Draw blue zone
painter->setBrush(back);
QRect r2(rect.left(), rect.top(), rect.width() * (amount == 0 ? 0 : budgeted / amount), rect.height());
painter->drawRect(r2);
}
} else {
if (amount > 0) {
amount = 0;
}
// Expenditure
if (amount < budgeted) {
// Draw red zone
painter->setBrush(negative);
painter->drawRect(rect);
// Draw blue zone
painter->setBrush(back);
QRect r2(rect.left(), rect.top(), rect.width() * (amount == 0 ? 0 : budgeted / amount), rect.height());
painter->drawRect(r2);
} else {
// Draw green zone
painter->setBrush(positive);
painter->drawRect(rect);
// Draw blue zone
painter->setBrush(back);
QRect r2(rect.left(), rect.top(), rect.width() * (budgeted == 0 ? 1 : amount / budgeted), rect.height());
painter->drawRect(r2);
}
}
// Draw time progress
painter->setPen(Qt::black);
QLine r2(rect.left() + rect.width()*pourcent, rect.top() + 1, rect.left() + rect.width()*pourcent, rect.top() + rect.height() - 1);
painter->drawLine(r2);
// Draw text
painter->setPen(m->data(idxs, Qt::TextColorRole).value<QColor>());
QTextOption to;
to.setAlignment(static_cast<Qt::AlignmentFlag>(m->data(idxs, Qt::TextAlignmentRole).toInt()));
painter->drawText(rect, m->data(idxs).toString(), to);
painter->restore();
done = true;
}
}
}
if (!done) {
QStyledItemDelegate::paint(painter, option, index);
}
}
diff --git a/plugins/skrooge/skrooge_budget/skgbudgetdelegate.h b/plugins/skrooge/skrooge_budget/skgbudgetdelegate.h
index 3816319eb..fcc8920ac 100644
--- a/plugins/skrooge/skrooge_budget/skgbudgetdelegate.h
+++ b/plugins/skrooge/skrooge_budget/skgbudgetdelegate.h
@@ -1,58 +1,58 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGBUDGETDELEGATE_H
#define SKGBUDGETDELEGATE_H
/** @file
* This file is a delegate for budget.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include <qstyleditemdelegate.h>
class SKGDocument;
/**
* This file is a delegate for budget
*/
class SKGBudgetDelegate : public QStyledItemDelegate
{
Q_OBJECT
public:
/**
* Default Constructor
*/
explicit SKGBudgetDelegate(QObject* iParent, SKGDocument* iDoc);
/**
* Default Destructor
*/
~SKGBudgetDelegate() override;
void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const override;
private:
Q_DISABLE_COPY(SKGBudgetDelegate)
SKGDocument* m_document;
QString m_negativeStyleSheet;
QString m_neutralStyleSheet;
QString m_positiveStyleSheet;
};
#endif // SKGBUDGETDELEGATE_H
diff --git a/plugins/skrooge/skrooge_budget/skgbudgetplugin.cpp b/plugins/skrooge/skrooge_budget/skgbudgetplugin.cpp
index 8e42af2c9..301fe4d0a 100644
--- a/plugins/skrooge/skrooge_budget/skgbudgetplugin.cpp
+++ b/plugins/skrooge/skrooge_budget/skgbudgetplugin.cpp
@@ -1,222 +1,222 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* A skrooge plugin to manage budgets
*
* @author Stephane MANKOWSKI
*/
#include "skgbudgetplugin.h"
#include <kaboutdata.h>
#include <kactioncollection.h>
#include <klocalizedstring.h>
#include <kpluginfactory.h>
#include <kstandardaction.h>
#include "skgbudgetobject.h"
#include "skgbudgetpluginwidget.h"
#include "skgbudgetruleobject.h"
#include "skgdocumentbank.h"
#include "skgmainpanel.h"
#include "skgtraces.h"
#include "skgtransactionmng.h"
/**
* This plugin factory.
*/
K_PLUGIN_FACTORY(SKGBudgetPluginFactory, registerPlugin<SKGBudgetPlugin>();)
SKGBudgetPlugin::SKGBudgetPlugin(QWidget* iWidget, QObject* iParent, const QVariantList& /*iArg*/) : SKGInterfacePlugin(iParent), m_currentBankDocument(nullptr)
{
Q_UNUSED(iWidget)
SKGTRACEINFUNC(10)
}
SKGBudgetPlugin::~SKGBudgetPlugin()
{
SKGTRACEINFUNC(10)
m_currentBankDocument = nullptr;
}
bool SKGBudgetPlugin::setupActions(SKGDocument* iDocument)
{
SKGTRACEINFUNC(10)
m_currentBankDocument = qobject_cast<SKGDocumentBank*>(iDocument);
if (m_currentBankDocument == nullptr) {
return false;
}
setComponentName(QStringLiteral("skrooge_budget"), title());
setXMLFile(QStringLiteral("skrooge_budget.rc"));
// Create yours actions here
// -----------
QStringList overlayrun;
overlayrun.push_back(QStringLiteral("system-run"));
auto act = new QAction(SKGServices::fromTheme(icon(), overlayrun), i18nc("Verb", "Process budget rules"), this);
connect(act, &QAction::triggered, this, &SKGBudgetPlugin::onProcessRules);
registerGlobalAction(QStringLiteral("tool_process_budget_rules"), act);
return true;
}
SKGTabPage* SKGBudgetPlugin::getWidget()
{
SKGTRACEINFUNC(10)
return new SKGBudgetPluginWidget(SKGMainPanel::getMainPanel(), m_currentBankDocument);
}
QString SKGBudgetPlugin::title() const
{
return i18nc("The title", "Budget");
}
QString SKGBudgetPlugin::icon() const
{
return QStringLiteral("view-calendar-whatsnext");
}
QString SKGBudgetPlugin::toolTip() const
{
return i18nc("The tool tip", "Budget");
}
int SKGBudgetPlugin::getOrder() const
{
return 32;
}
QStringList SKGBudgetPlugin::tips() const
{
QStringList output;
return output;
}
bool SKGBudgetPlugin::isInPagesChooser() const
{
return true;
}
SKGAdviceList SKGBudgetPlugin::advice(const QStringList& iIgnoredAdvice)
{
SKGTRACEINFUNC(10)
SKGAdviceList output;
QString month = QDate::currentDate().toString(QStringLiteral("yyyy-MM"));
QString year = QDate::currentDate().toString(QStringLiteral("yyyy"));
// Alarms
if (!iIgnoredAdvice.contains(QStringLiteral("skgbudgetplugin_alarm"))) {
SKGObjectBase::SKGListSKGObjectBase budgets;
// Query is done on v_budget_display because v_budget_display is faster than v_budget
SKGError err = m_currentBankDocument->getObjects(QStringLiteral("v_budget_display"), "(f_CURRENTAMOUNT/f_budgeted_modified>0.8 OR (f_CURRENTAMOUNT<0 AND f_budgeted_modified>0)) AND ABS(f_CURRENTAMOUNT-f_budgeted_modified)>" % SKGServices::doubleToString(EPSILON) % " AND f_budgeted<0 AND (t_PERIOD='" % month % "' OR t_PERIOD='" % year % "');", budgets);
int nb = budgets.count();
if (nb != 0) {
SKGServices::SKGUnitInfo primary = m_currentBankDocument->getPrimaryUnit();
SKGAdvice::SKGAdviceActionList autoCorrections;
for (int i = 0; !err && i < nb; ++i) {
SKGBudgetObject budget(budgets.at(i));
double f_CURRENTAMOUNT = SKGServices::stringToDouble(budget.getAttribute(QStringLiteral("f_CURRENTAMOUNT")));
double f_budgeted_modified = SKGServices::stringToDouble(budget.getAttribute(QStringLiteral("f_budgeted_modified")));
SKGAdvice ad;
ad.setUUID("skgbudgetplugin_alarm|" % SKGServices::intToString(budget.getID()));
ad.setPriority((f_CURRENTAMOUNT < f_budgeted_modified ? 9 : 6));
ad.setShortMessage(i18nc("Advice on making the best (short)", "Budget alarm for '%1'", budget.getAttribute(QStringLiteral("t_CATEGORY"))));
ad.setLongMessage(i18nc("Advice on making the best (long)", "Take care to your budget.<br> %1.<br>%2 / %3",
budget.getAttribute(QStringLiteral("t_CATEGORY")),
m_currentBankDocument->formatMoney(f_CURRENTAMOUNT, primary),
m_currentBankDocument->formatMoney(f_budgeted_modified, primary)));
autoCorrections.resize(0);
{
SKGAdvice::SKGAdviceAction a;
a.Title = i18nc("Advice on making the best (action)", "Open operations corresponding to this budget");
a.IconName = QStringLiteral("quickopen");
a.IsRecommended = false;
autoCorrections.push_back(a);
}
ad.setAutoCorrections(autoCorrections);
output.push_back(ad);
}
}
}
if (!iIgnoredAdvice.contains(QStringLiteral("skgbudgetplugin_oldprocessing"))) {
QString lastBudgetProcessingDate = m_currentBankDocument->getParameter(QStringLiteral("SKG_LAST_BUDGET_PROCESSING"));
if (lastBudgetProcessingDate.isEmpty() || SKGServices::stringToTime(lastBudgetProcessingDate).date() < QDate::currentDate().addMonths(-1)) { // Ignore header
bool exist = false;
m_currentBankDocument->existObjects(QStringLiteral("budgetrule"), QLatin1String(""), exist);
if (exist) {
SKGAdvice ad;
ad.setUUID(QStringLiteral("skgbudgetplugin_oldprocessing"));
ad.setPriority(3);
ad.setShortMessage(i18nc("Advice on making the best (short)", "Old budget treatment"));
ad.setLongMessage(i18nc("Advice on making the best (long)", "The budget has not been treated for at least one month."));
SKGAdvice::SKGAdviceActionList autoCorrections;
{
SKGAdvice::SKGAdviceAction a;
a.Title = QStringLiteral("skg://tool_process_budget_rules");
a.IsRecommended = true;
autoCorrections.push_back(a);
}
ad.setAutoCorrections(autoCorrections);
output.push_back(ad);
}
}
}
return output;
}
SKGError SKGBudgetPlugin::executeAdviceCorrection(const QString& iAdviceIdentifier, int iSolution)
{
if ((m_currentBankDocument != nullptr) && iAdviceIdentifier.startsWith(QLatin1String("skgbudgetplugin_alarm|"))) {
// Get parameters
QString id = iAdviceIdentifier.right(iAdviceIdentifier.length() - 22);
SKGBudgetObject budget(m_currentBankDocument, SKGServices::stringToInt(id));
budget.load();
QAction* act = SKGMainPanel::getMainPanel()->getGlobalAction(QStringLiteral("open"));
if (act != nullptr) {
act->setData(budget.getUniqueID());
act->trigger();
}
return SKGError();
}
return SKGInterfacePlugin::executeAdviceCorrection(iAdviceIdentifier, iSolution);
}
void SKGBudgetPlugin::onProcessRules()
{
SKGError err;
_SKGTRACEINFUNCRC(10, err)
{
SKGBEGINTRANSACTION(*m_currentBankDocument, i18nc("Noun, name of the user action", "Process budget rules"), err)
err = SKGBudgetRuleObject::processAllRules(m_currentBankDocument);
}
// status bar
IFOK(err) {
err = SKGError(0, i18nc("Successful message after an user action", "Budget rules processed"));
} else {
err.addError(ERR_FAIL, i18nc("Error message", "Budget rules failed"));
}
// Display error
SKGMainPanel::displayErrorMessage(err);
}
#include <skgbudgetplugin.moc>
diff --git a/plugins/skrooge/skrooge_budget/skgbudgetplugin.h b/plugins/skrooge/skrooge_budget/skgbudgetplugin.h
index cddf0a011..dba50bba4 100644
--- a/plugins/skrooge/skrooge_budget/skgbudgetplugin.h
+++ b/plugins/skrooge/skrooge_budget/skgbudgetplugin.h
@@ -1,120 +1,120 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGBUDGETPLUGIN_H
#define SKGBUDGETPLUGIN_H
/** @file
* A skrooge plugin to manage budgets.
*
* @author Stephane MANKOWSKI
*/
#include "skginterfaceplugin.h"
class SKGDocumentBank;
/**
* A skrooge plugin to manage budgets
*/
class SKGBudgetPlugin : public SKGInterfacePlugin
{
Q_OBJECT
Q_INTERFACES(SKGInterfacePlugin)
public:
/**
* Default Constructor
*/
explicit SKGBudgetPlugin(QWidget* iWidget, QObject* iParent, const QVariantList& iArg);
/**
* Default Destructor
*/
~SKGBudgetPlugin() override;
/**
* Called to initialise the plugin
* @param iDocument the main document
* @return true if the plugin is compatible with the document
*/
bool setupActions(SKGDocument* iDocument) override;
/**
* The page widget of the plugin.
* @return The page widget of the plugin
*/
SKGTabPage* getWidget() override;
/**
* The title of the plugin.
* @return The title of the plugin
*/
QString title() const override;
/**
* The icon of the plugin.
* @return The icon of the plugin
*/
QString icon() const override;
/**
* The toolTip of the plugin.
* @return The toolTip of the plugin
*/
QString toolTip() const override;
/**
* The tips list of the plugin.
* @return The tips list of the plugin
*/
QStringList tips() const override;
/**
* Must be implemented to set the position of the plugin.
* @return integer value between 0 and 999 (default = 999)
*/
int getOrder() const override;
/**
* Must be implemented to know if a plugin must be display in pages chooser.
* @return true of false (default = false)
*/
bool isInPagesChooser() const override;
/**
* The advice list of the plugin.
* @return The advice list of the plugin
*/
SKGAdviceList advice(const QStringList& iIgnoredAdvice) override;
/**
* Must be implemented to execute the automatic correction for the advice.
* @param iAdviceIdentifier the identifier of the advice
* @param iSolution the identifier of the possible solution
* @return an object managing the error. MUST return ERR_NOTIMPL if iAdviceIdentifier is not known
* @see SKGError
*/
SKGError executeAdviceCorrection(const QString& iAdviceIdentifier, int iSolution) override;
private Q_SLOTS:
void onProcessRules();
private:
Q_DISABLE_COPY(SKGBudgetPlugin)
SKGDocumentBank* m_currentBankDocument;
};
#endif // SKGBUDGETPLUGIN_H
diff --git a/plugins/skrooge/skrooge_budget/skgbudgetpluginwidget.cpp b/plugins/skrooge/skrooge_budget/skgbudgetpluginwidget.cpp
index 3e5c10de2..7586d5824 100644
--- a/plugins/skrooge/skrooge_budget/skgbudgetpluginwidget.cpp
+++ b/plugins/skrooge/skrooge_budget/skgbudgetpluginwidget.cpp
@@ -1,834 +1,834 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* A skrooge plugin to manage budgets.
*
* @author Stephane MANKOWSKI
*/
#include "skgbudgetpluginwidget.h"
#include <qdom.h>
#include <qevent.h>
#include "skgbudgetdelegate.h"
#include "skgbudgetobject.h"
#include "skgbudgetruleobject.h"
#include "skgcategoryobject.h"
#include "skgdocument.h"
#include "skgmainpanel.h"
#include "skgobjectmodel.h"
#include "skgtraces.h"
#include "skgtransactionmng.h"
SKGBudgetPluginWidget::SKGBudgetPluginWidget(QWidget* iParent, SKGDocument* iDocument)
: SKGTabPage(iParent, iDocument), m_objectModel(nullptr)
{
SKGTRACEINFUNC(1)
if (iDocument == nullptr) {
return;
}
ui.setupUi(this);
ui.kUseScheduledOperation->hide();
ui.kTopBtn->setIcon(SKGServices::fromTheme(QStringLiteral("arrow-up-double")));
ui.kUpBtn->setIcon(SKGServices::fromTheme(QStringLiteral("arrow-up")));
ui.kDownBtn->setIcon(SKGServices::fromTheme(QStringLiteral("arrow-down")));
ui.kBottomBtn->setIcon(SKGServices::fromTheme(QStringLiteral("arrow-down-double")));
ui.kPeriodLbl->setText(i18n("%1:", iDocument->getDisplay(QStringLiteral("t_period"))));
ui.kYearLbl->setText(i18n("%1:", iDocument->getDisplay(QStringLiteral("i_year"))));
ui.kMonthLbl->setText(i18n("%1:", iDocument->getDisplay(QStringLiteral("i_month"))));
ui.kAmountLabel->setText(i18n("%1:", iDocument->getDisplay(QStringLiteral("f_value"))));
ui.kCategoryLabel->setText(i18n("%1:", iDocument->getDisplay(QStringLiteral("t_category"))));
ui.kYearCheck->setText(i18n("%1:", iDocument->getDisplay(QStringLiteral("i_year"))));
ui.kMonthCheck->setText(i18n("%1:", iDocument->getDisplay(QStringLiteral("i_month"))));
ui.kCategoryCheck->setText(i18n("%1:", iDocument->getDisplay(QStringLiteral("t_category"))));
ui.kPeriodLbl2->setText(i18n("%1:", iDocument->getDisplay(QStringLiteral("t_period"))));
ui.kAmountLabel2->setText(i18n("%1:", iDocument->getDisplay(QStringLiteral("f_value"))));
ui.kCategoryTransferCheck->setText(i18n("%1:", iDocument->getDisplay(QStringLiteral("t_category"))));
ui.kYear->setValue(QDate::currentDate().year());
ui.kYearAutoBase->setValue(QDate::currentDate().year());
ui.kMonth->setValue(QDate::currentDate().month());
ui.kPeriod->addItem(i18nc("Noun, how to define a budget period", "Monthly"));
ui.kPeriod->addItem(i18nc("Noun, how to define a budget period", "Yearly"));
ui.kPeriod->addItem(i18nc("Noun, how to define a budget period", "Individual"));
ui.kView->getShowWidget()->addItem(QStringLiteral("all"), i18nc("Noun, budget items to display", "All"), QLatin1String(""),
QLatin1String(""),
QStringLiteral("current;currentYear;currentMonth;previousYear;previousMonth"),
QStringLiteral("none"), QLatin1String(""), QLatin1String(""),
Qt::META + Qt::Key_A);
ui.kView->getShowWidget()->addItem(QStringLiteral("none"), i18nc("Noun, budget items to display", "None"), QLatin1String(""),
QStringLiteral("1=0"),
QLatin1String(""), // Check when checked
QStringLiteral("all;current;currentYear;currentMonth;previousYear;previousMonth"), // Uncheck when checked
QLatin1String(""), // Check when unchecked
QStringLiteral("all"), // Uncheck when unchecked
Qt::META + Qt::Key_0);
ui.kView->getShowWidget()->addSeparator();
ui.kView->getShowWidget()->addItem(QStringLiteral("current"), i18nc("Noun, budget items to display", "Current"), QStringLiteral("view-calendar-whatsnext"),
QStringLiteral("t_PERIOD>=STRFTIME('%Y-%m', date('now')) OR t_PERIOD=STRFTIME('%Y', date('now'))"),
QStringLiteral("currentMonth"), // Check when checked
QStringLiteral("none"), // Uncheck when checked
QLatin1String(""), // Check when unchecked
QStringLiteral("all"), // Uncheck when unchecked
Qt::META + Qt::Key_1);
ui.kView->getShowWidget()->addSeparator();
ui.kView->getShowWidget()->addItem(QStringLiteral("currentYear"), i18nc("Noun, budget items to display", "Current year"), QStringLiteral("view-calendar-month"),
QStringLiteral("t_PERIOD LIKE STRFTIME('%Y', date('now'))||'%'"),
QLatin1String(""),
QStringLiteral("none"),
QLatin1String(""),
QStringLiteral("all"),
Qt::META + Qt::Key_3);
ui.kView->getShowWidget()->addItem(QStringLiteral("currentMonth"), i18nc("Noun, budget items to display", "Current month"), QStringLiteral("view-calendar-week"),
QStringLiteral("t_PERIOD=STRFTIME('%Y-%m', date('now'))"),
QLatin1String(""),
QStringLiteral("none"),
QLatin1String(""),
QStringLiteral("all;current"),
Qt::META + Qt::Key_2);
ui.kView->getShowWidget()->addSeparator();
ui.kView->getShowWidget()->addItem(QStringLiteral("previousYear"), i18nc("Noun, budget items to display", "Previous year"), QStringLiteral("view-calendar-month"),
QStringLiteral("t_PERIOD LIKE STRFTIME('%Y', date('now','start of year','-1 day'))||'%'"),
QLatin1String(""),
QStringLiteral("none"),
QLatin1String(""),
QStringLiteral("all"),
Qt::META + Qt::Key_5);
ui.kView->getShowWidget()->addItem(QStringLiteral("previousMonth"), i18nc("Noun, budget items to display", "Previous month"), QStringLiteral("view-calendar-week"),
QStringLiteral("t_PERIOD=STRFTIME('%Y-%m', date('now','start of month','-1 day'))"),
QLatin1String(""),
QStringLiteral("none"),
QLatin1String(""),
QStringLiteral("all"),
Qt::META + Qt::Key_4);
ui.kView->getShowWidget()->setDefaultState(QStringLiteral("current;currentMonth"));
m_timer.setSingleShot(true);
connect(&m_timer, &QTimer::timeout, this, &SKGBudgetPluginWidget::refreshInfoZone, Qt::QueuedConnection);
ui.kConditionCmb->addItem(i18nc("Noun, condition item to a apply a transfer of budget", "All"), static_cast<int>(SKGBudgetRuleObject::ALL));
ui.kConditionCmb->addItem(i18nc("Noun, condition item to a apply a transfer of budget", "Negative"), static_cast<int>(SKGBudgetRuleObject::NEGATIVE));
ui.kConditionCmb->addItem(i18nc("Noun, condition item to a apply a transfer of budget", "Positive"), static_cast<int>(SKGBudgetRuleObject::POSITIVE));
ui.kModeCmb->addItem(i18nc("Noun, mode item to a apply a transfer of budget", "Next"), static_cast<int>(SKGBudgetRuleObject::NEXT));
ui.kModeCmb->addItem(i18nc("Noun, mode item to a apply a transfer of budget", "Current"), static_cast<int>(SKGBudgetRuleObject::CURRENT));
ui.kModeCmb->addItem(i18nc("Noun, mode item to a apply a transfer of budget", "Current year"), static_cast<int>(SKGBudgetRuleObject::YEAR));
ui.kView->getView()->setItemDelegate(new SKGBudgetDelegate(ui.kView->getView(), getDocument()));
auto* doc = qobject_cast<SKGDocumentBank*>(getDocument());
if (doc != nullptr) {
ui.kUnitCmb->addItem(QStringLiteral("%"));
ui.kUnitCmb->addItem(doc->getPrimaryUnit().Symbol);
ui.kUnit->setText(doc->getPrimaryUnit().Symbol);
// Bind operation view
m_objectModel = new SKGObjectModel(doc, QStringLiteral("v_budget_display"), QStringLiteral("1=0"), this, QLatin1String(""), false);
ui.kView->setModel(m_objectModel);
ui.kSortButton->setVisible(false);
}
connect(ui.kView->getView(), &SKGTreeView::doubleClicked, SKGMainPanel::getMainPanel()->getGlobalAction(QStringLiteral("open")).data(), &QAction::trigger);
connect(ui.kView->getView(), &SKGTreeView::selectionChangedDelayed, this, [ = ] {this->onSelectionChanged();});
// Add Standard KDE Icons to buttons to Operations
ui.kModifyBtn->setIcon(SKGServices::fromTheme(QStringLiteral("dialog-ok")));
ui.kAddBtn->setIcon(SKGServices::fromTheme(QStringLiteral("list-add")));
QAction* processAction = SKGMainPanel::getMainPanel()->getGlobalAction(QStringLiteral("tool_process_budget_rules"));
if (processAction != nullptr) {
ui.kProcessBtn->setIcon(processAction->icon());
connect(ui.kProcessBtn, &QPushButton::clicked, processAction, &QAction::trigger);
}
{
SKGWidgetSelector::SKGListQWidget list;
list.push_back(ui.SKGManualSection);
list.push_back(ui.SKGEditionButtonsSection);
ui.kWidgetSelector->addButton(SKGServices::fromTheme(QStringLiteral("user-properties")), i18n("Manual"), i18n("Display the edit panel for standard budget"), list);
}
{
SKGWidgetSelector::SKGListQWidget list;
list.push_back(ui.SKGAutoSection);
list.push_back(ui.SKGEditionButtonsSection);
ui.kWidgetSelector->addButton(SKGServices::fromTheme(QStringLiteral("games-solve")), i18n("Auto"), i18n("Display the edit panel for automatic budgets"), list);
}
{
SKGWidgetSelector::SKGListQWidget list;
list.push_back(ui.SKGRuleSection);
list.push_back(ui.SKGEditionButtonsSection);
ui.kWidgetSelector->addButton(SKGServices::fromTheme(QStringLiteral("run-build")), i18n("Rules"), i18n("Display the edit panel for rules"), list);
}
connect(ui.kWidgetSelector, &SKGWidgetSelector::selectedModeChanged, this, &SKGBudgetPluginWidget::onBtnModeClicked, Qt::QueuedConnection);
connect(ui.kAddBtn, &QPushButton::clicked, this, &SKGBudgetPluginWidget::onAddClicked);
connect(ui.kModifyBtn, &QPushButton::clicked, this, &SKGBudgetPluginWidget::onUpdateClicked);
connect(ui.kAmountEdit, &SKGCalculatorEdit::textChanged, this, &SKGBudgetPluginWidget::onCreatorModified);
connect(ui.kPeriod, static_cast<void (SKGComboBox::*)(const QString&)>(&SKGComboBox::currentTextChanged), this, &SKGBudgetPluginWidget::onCreatorModified);
connect(ui.kYearCheck, &QCheckBox::toggled, ui.kYearRule, &QSpinBox::setEnabled);
connect(ui.kMonthCheck, &QCheckBox::toggled, ui.kMonthRule, &QSpinBox::setEnabled);
connect(ui.kCategoryCheck, &QCheckBox::toggled, ui.kCategoryRule, &SKGComboBox::setEnabled);
connect(ui.kCategoryTransferCheck, &QCheckBox::toggled, ui.kCategoryTransfer, &SKGComboBox::setEnabled);
connect(ui.kModeCmb, static_cast<void (SKGComboBox::*)(int)>(&SKGComboBox::currentIndexChanged), this, &SKGBudgetPluginWidget::onCreatorModified);
connect(ui.kAutoBudgetCheck, &QCheckBox::toggled, ui.kYearAutoBase, &QSpinBox::setEnabled);
connect(ui.kAutoBudgetCheck, &QCheckBox::toggled, ui.kRemovePrevious, &QCheckBox::setEnabled);
connect(ui.kAutoBudgetCheck, &QCheckBox::toggled, ui.kUseScheduledOperation, &QCheckBox::setEnabled);
connect(ui.kTopBtn, &QToolButton::clicked, this, &SKGBudgetPluginWidget::onTop);
connect(ui.kUpBtn, &QToolButton::clicked, this, &SKGBudgetPluginWidget::onUp);
connect(ui.kDownBtn, &QToolButton::clicked, this, &SKGBudgetPluginWidget::onDown);
connect(ui.kBottomBtn, &QToolButton::clicked, this, &SKGBudgetPluginWidget::onBottom);
connect(ui.kYearAuto, static_cast<void (QSpinBox::*)(const QString&)>(&QSpinBox::valueChanged), this, [ = ](const QString & text) {
ui.kRemovePrevious->setText(i18nc("Option", "Remove existing budgets for %1", text));
});
ui.kYearAuto->setValue(QDate::currentDate().year());
ui.kWidgetSelector->setSelectedMode(0);
// Set Event filters to catch CTRL+ENTER or SHIFT+ENTER
this->installEventFilter(this);
// Refresh
connect(getDocument(), &SKGDocument::tableModified, this, &SKGBudgetPluginWidget::dataModified, Qt::QueuedConnection);
dataModified(QLatin1String(""), 0);
}
SKGBudgetPluginWidget::~SKGBudgetPluginWidget()
{
SKGTRACEINFUNC(1)
m_objectModel = nullptr;
}
bool SKGBudgetPluginWidget::eventFilter(QObject* iObject, QEvent* iEvent)
{
if ((iEvent != nullptr) && iEvent->type() == QEvent::KeyPress) {
auto* keyEvent = dynamic_cast<QKeyEvent*>(iEvent);
if (keyEvent && (keyEvent->key() == Qt::Key_Return || keyEvent->key() == Qt::Key_Enter) && iObject == this) {
if ((QApplication::keyboardModifiers() & Qt::ControlModifier) != 0u && ui.kAddBtn->isEnabled()) {
ui.kAddBtn->click();
} else if ((QApplication::keyboardModifiers() &Qt::ShiftModifier) != 0u && ui.kModifyBtn->isEnabled()) {
ui.kModifyBtn->click();
}
}
}
return SKGTabPage::eventFilter(iObject, iEvent);
}
QString SKGBudgetPluginWidget::getState()
{
SKGTRACEINFUNC(10)
QDomDocument doc(QStringLiteral("SKGML"));
QDomElement root = doc.createElement(QStringLiteral("parameters"));
doc.appendChild(root);
root.setAttribute(QStringLiteral("currentPage"), SKGServices::intToString(ui.kWidgetSelector->getSelectedMode()));
if ((m_objectModel != nullptr) && m_objectModel->getRealTable() == QStringLiteral("budget")) {
root.setAttribute(QStringLiteral("view"), ui.kView->getState());
root.setAttribute(QStringLiteral("viewRule"), m_viewRule);
} else {
root.setAttribute(QStringLiteral("view"), m_viewBudget);
root.setAttribute(QStringLiteral("viewRule"), ui.kView->getState());
}
return doc.toString();
}
void SKGBudgetPluginWidget::setState(const QString& iState)
{
SKGTRACEINFUNC(10)
QDomDocument doc(QStringLiteral("SKGML"));
doc.setContent(iState);
QDomElement root = doc.documentElement();
QString currentPage = root.attribute(QStringLiteral("currentPage"));
if (currentPage.isEmpty()) {
currentPage = '0';
}
ui.kWidgetSelector->setSelectedMode(SKGServices::stringToInt(currentPage));
m_viewBudget = root.attribute(QStringLiteral("view"));
m_viewRule = root.attribute(QStringLiteral("viewRule"));
if ((m_objectModel != nullptr) && m_objectModel->getRealTable() == QStringLiteral("budget")) {
ui.kView->setState(m_viewBudget);
} else {
ui.kView->setState(m_viewRule);
}
}
QString SKGBudgetPluginWidget::getDefaultStateAttribute()
{
return QStringLiteral("SKGBUDGET_DEFAULT_PARAMETERS");
}
QWidget* SKGBudgetPluginWidget::mainWidget()
{
return ui.kView->getView();
}
void SKGBudgetPluginWidget::refresh()
{
SKGTRACEINFUNC(1)
QSqlDatabase* db = getDocument()->getMainDatabase();
setEnabled(db != nullptr);
if (db != nullptr) {
// Refresh yours widgets here
}
}
void SKGBudgetPluginWidget::dataModified(const QString& iTableName, int iIdTransaction, bool iLightTransaction)
{
SKGTRACEINFUNC(10)
Q_UNUSED(iIdTransaction)
// Refresh widgets
if (iTableName == QStringLiteral("budget") || iTableName.isEmpty()) {
// Refresh info area
m_timer.start(300);
}
if (!iLightTransaction) {
if (iTableName == QStringLiteral("category") || iTableName.isEmpty()) {
// Set type category
SKGMainPanel::fillWithDistinctValue(QList<QWidget*>() << ui.kCategoryEdit << ui.kCategoryRule << ui.kCategoryTransfer, getDocument(), QStringLiteral("category"), QStringLiteral("t_fullname"), QLatin1String(""));
}
}
}
void SKGBudgetPluginWidget::onBtnModeClicked(int mode)
{
SKGTRACEINFUNC(10)
if (m_objectModel == nullptr) {
return;
}
if (mode == 2 && m_objectModel->getTable() != QStringLiteral("v_budgetrule_display")) {
ui.kView->getShowWidget()->setEnabled(false);
m_viewBudget = ui.kView->getState();
m_objectModel->setFilter(QLatin1String(""));
m_objectModel->setTable(QStringLiteral("v_budgetrule_display"));
ui.kSortButton->setVisible(true);
ui.kView->setState(m_viewRule);
} else if (mode != 2 && m_objectModel->getTable() != QStringLiteral("v_budget_display")) {
ui.kView->getShowWidget()->setEnabled(true);
m_viewRule = ui.kView->getState();
m_objectModel->setTable(QStringLiteral("v_budget_display"));
ui.kSortButton->setVisible(false);
ui.kView->setState(m_viewBudget);
}
onCreatorModified();
}
void SKGBudgetPluginWidget::onAddClicked()
{
SKGError err;
_SKGTRACEINFUNCRC(10, err)
if (ui.kWidgetSelector->getSelectedMode() == 2) {
// Creation of a rule
QStringList uniqueIDs;
{
SKGBEGINTRANSACTION(*getDocument(), i18nc("Noun, name of the user action", "Budget rule creation"), err)
SKGBudgetRuleObject budgetRule(getDocument());
IFOKDO(err, updateBudgetRule(budgetRule))
IFOKDO(err, budgetRule.setOrder(-1))
IFOKDO(err, budgetRule.save())
uniqueIDs.push_back(budgetRule.getUniqueID());
// Send message
IFOKDO(err, budgetRule.getDocument()->sendMessage(i18nc("An information to the user", "The budget rule '%1' has been added", budgetRule.getDisplayName()), SKGDocument::Hidden))
}
// status bar
IFOK(err) {
err = SKGError(0, i18nc("Successful message after an user action", "Budget rule created"));
ui.kView->getView()->selectObjects(uniqueIDs);
} else {
err.addError(ERR_FAIL, i18nc("Error message", "Budget rule creation failed"));
}
} else {
// Creation of a budget
QStringList uniqueIDs;
{
SKGBEGINPROGRESSTRANSACTION(*getDocument(), i18nc("Noun, name of the user action", "Budget creation"), err, 2)
if (ui.kWidgetSelector->getSelectedMode() == 0) {
// Manual creation
int mode = ui.kPeriod->currentIndex();
if (mode == 0) { // Monthly
for (int m = 1; !err && m <= 12; ++m) {
SKGBudgetObject budget(getDocument());
IFOKDO(err, updateBudget(budget, m))
// Send message
IFOKDO(err, getDocument()->sendMessage(i18nc("An information to the user", "The budget '%1' has been added", budget.getDisplayName()), SKGDocument::Hidden))
uniqueIDs.push_back(budget.getUniqueID());
}
} else if (mode == 1) { // Yearly
SKGBudgetObject budget(getDocument());
IFOKDO(err, updateBudget(budget, 0))
// Send message
IFOKDO(err, getDocument()->sendMessage(i18nc("An information to the user", "The budget '%1' has been added", budget.getDisplayName()), SKGDocument::Hidden))
uniqueIDs.push_back(budget.getUniqueID());
} else { // Individual
SKGBudgetObject budget(getDocument());
IFOKDO(err, updateBudget(budget))
// Send message
IFOKDO(err, getDocument()->sendMessage(i18nc("An information to the user", "The budget '%1' has been added", budget.getDisplayName()), SKGDocument::Hidden))
uniqueIDs.push_back(budget.getUniqueID());
}
} else {
// Automatic creation
if (ui.kAutoBudgetCheck->isChecked()) {
err = SKGBudgetObject::createAutomaticBudget(qobject_cast<SKGDocumentBank*>(getDocument()),
ui.kYearAuto->value(),
ui.kYearAutoBase->value(),
ui.kUseScheduledOperation->isChecked(),
ui.kRemovePrevious->isChecked());
}
IFOKDO(err, getDocument()->stepForward(1))
IFOKDO(err, SKGBudgetObject::balanceBudget(qobject_cast<SKGDocumentBank*>(getDocument()),
ui.kYearAuto->value(), (ui.kBalancingMonthly->isChecked() ? 0 : -1),
ui.kBalancingAnnual->isChecked()));
IFOKDO(err, getDocument()->stepForward(2))
}
}
// status bar
IFOK(err) {
err = SKGError(0, i18nc("Successful message after an user action", "Budget created"));
ui.kView->getView()->selectObjects(uniqueIDs);
} else {
err.addError(ERR_FAIL, i18nc("Error message", "Budget creation failed"));
}
}
// Display error
SKGMainPanel::displayErrorMessage(err, true);
}
void SKGBudgetPluginWidget::onUpdateClicked()
{
SKGError err;
SKGTRACEINFUNCRC(10, err)
// Get Selection
SKGObjectBase::SKGListSKGObjectBase selection = getSelectedObjects();
if (ui.kWidgetSelector->getSelectedMode() == 2) {
{
SKGBEGINTRANSACTION(*getDocument(), i18nc("Noun, name of the user action", "Budget rule update"), err)
SKGBudgetRuleObject rule(selection.at(0));
IFOKDO(err, updateBudgetRule(rule))
// Send message
IFOKDO(err, rule.getDocument()->sendMessage(i18nc("An information to the user", "The budget rule '%1' has been updated", rule.getDisplayName()), SKGDocument::Hidden))
}
// status bar
IFOK(err) {
err = SKGError(0, i18nc("Successful message after an user action", "Budget rule updated"));
} else {
err.addError(ERR_FAIL, i18nc("Error message", "Budget rule update failed"));
}
} else {
{
int nb = selection.count();
SKGBEGINPROGRESSTRANSACTION(*getDocument(), i18nc("Noun, name of the user action", "Budget update"), err, nb)
for (int i = 0; !err && i < nb; ++i) {
SKGBudgetObject budget(selection.at(i));
int mode = ui.kPeriod->currentIndex();
if (mode == 1) { // Yearly
err = updateBudget(budget, 0);
} else { // Individual
err = updateBudget(budget);
}
IFOKDO(err, getDocument()->stepForward(i + 1))
}
}
// status bar
IFOK(err) {
err = SKGError(0, i18nc("Successful message after an user action", "Budget updated"));
} else {
err.addError(ERR_FAIL, i18nc("Error message", "Budget update failed"));
}
}
// Display error
SKGMainPanel::displayErrorMessage(err, true);
// Set focus on table
ui.kView->getView()->setFocus();
}
SKGError SKGBudgetPluginWidget::updateBudget(SKGBudgetObject& iBudget, int iMonth)
{
SKGError err;
if (!err && ui.kYear->isEnabled()) {
err = iBudget.setYear(ui.kYear->value());
}
if (!err && ui.kMonth->isEnabled()) {
err = iBudget.setMonth(iMonth != -1 ? iMonth : ui.kMonth->value());
}
SKGCategoryObject cat;
QString catName = ui.kCategoryEdit->text().trimmed();
IFOKDO(err, SKGCategoryObject::createPathCategory(qobject_cast<SKGDocumentBank*>(getDocument()), catName, cat, true))
IFOKDO(err, iBudget.setCategory(cat))
IFOKDO(err, iBudget.enableSubCategoriesInclusion(ui.kIncludingSubCategories->isChecked()))
double val = ui.kAmountEdit->value();
// Is the sign forced ?
if (ui.kAmountEdit->sign() == 0) {
// No
SKGObjectBase cat2(cat.getDocument(), QStringLiteral("v_category_display"), cat.getID());
// Are we able to find to sign with the category ?
if (cat2.getAttribute(QStringLiteral("t_TYPEEXPENSE")) == QStringLiteral("-")) {
val = -val;
}
}
IFOKDO(err, iBudget.setBudgetedAmount(val))
IFOKDO(err, iBudget.save())
return err;
}
SKGError SKGBudgetPluginWidget::updateBudgetRule(SKGBudgetRuleObject& iRule)
{
SKGError err;
SKGCategoryObject cat;
QString catName = ui.kCategoryRule->text().trimmed();
IFOKDO(err, SKGCategoryObject::createPathCategory(qobject_cast<SKGDocumentBank*>(getDocument()), catName, cat, true))
SKGCategoryObject catchange;
QString catchangeName = ui.kCategoryTransfer->text().trimmed();
IFOKDO(err, SKGCategoryObject::createPathCategory(qobject_cast<SKGDocumentBank*>(getDocument()), catchangeName, catchange, true))
IFOKDO(err, iRule.enableCategoryCondition(ui.kCategoryCheck->isChecked()))
IFOKDO(err, iRule.setBudgetCategory(cat))
IFOKDO(err, iRule.enableYearCondition(ui.kYearCheck->isChecked()))
IFOKDO(err, iRule.setBudgetYear(ui.kYearRule->value()))
IFOKDO(err, iRule.enableMonthCondition(ui.kMonthCheck->isChecked()))
IFOKDO(err, iRule.setBudgetMonth(ui.kMonthRule->value()))
IFOK(err) {
bool absolute = (ui.kUnitCmb->currentIndex() == 1);
double val = ui.kAmountEdit2->value();
if (!absolute) {
val = qMin(qMax(static_cast<double>(0), val), static_cast<double>(100));
}
err = iRule.setQuantity(val, absolute);
}
IFOKDO(err, iRule.setCondition(static_cast<SKGBudgetRuleObject::Condition>(ui.kConditionCmb->itemData(ui.kConditionCmb->currentIndex()).toInt())))
IFOKDO(err, iRule.enableCategoryChange(ui.kCategoryTransferCheck->isChecked()))
IFOKDO(err, iRule.setTransfer(static_cast<SKGBudgetRuleObject::Mode>(ui.kModeCmb->itemData(ui.kModeCmb->currentIndex()).toInt()), catchange))
IFOKDO(err, iRule.save())
return err;
}
void SKGBudgetPluginWidget::onCreatorModified()
{
bool test = !ui.kAmountEdit->text().isEmpty() && !ui.kYear->text().isEmpty();
ui.kAddBtn->setEnabled(test || ui.kWidgetSelector->getSelectedMode() != 0);
ui.kModifyBtn->setEnabled((test && ui.kPeriod->currentIndex() != 0 && ui.kWidgetSelector->getSelectedMode() == 0 && (getNbSelectedObjects() != 0))
|| (ui.kWidgetSelector->getSelectedMode() == 2 && getNbSelectedObjects() == 1));
bool monthCondition = (ui.kPeriod->currentIndex() == 2 || ui.kWidgetSelector->getSelectedMode() == 2);
ui.kMonthLbl->setVisible(monthCondition);
ui.kMonth->setVisible(monthCondition);
}
void SKGBudgetPluginWidget::onSelectionChanged()
{
SKGTRACEINFUNC(10)
if (m_objectModel == nullptr) {
return;
}
SKGObjectBase::SKGListSKGObjectBase objs = getSelectedObjects();
int nb = objs.count();
int mode = ui.kWidgetSelector->getSelectedMode();
if (nb != 0) {
if (m_objectModel->getRealTable() == QStringLiteral("budget")) {
SKGBudgetObject budget(objs.at(0));
ui.kYear->setValue(budget.getYear());
ui.kMonth->setValue(budget.getMonth());
ui.kAmountEdit->setValue(budget.getBudgetedAmount());
ui.kCategoryEdit->setText(budget.getAttribute(QStringLiteral("t_CATEGORY")));
ui.kPeriod->setCurrentIndex(budget.getMonth() == 0 ? 1 : 2); // Set yearly or individual
ui.kIncludingSubCategories->setChecked(budget.isSubCategoriesInclusionEnabled());
if (mode > 0) {
ui.kWidgetSelector->setSelectedMode(0);
}
} else {
SKGBudgetRuleObject rule(objs.at(0));
ui.kYearCheck->setChecked(rule.isYearConditionEnabled());
ui.kYearRule->setValue(rule.getBudgetYear());
ui.kMonthCheck->setChecked(rule.isMonthConditionEnabled());
ui.kMonthRule->setValue(rule.getBudgetMonth());
ui.kCategoryCheck->setChecked(rule.isCategoryConditionEnabled());
ui.kCategoryRule->setText(rule.getAttribute(QStringLiteral("t_CATEGORYCONDITION")));
ui.kCategoryTransferCheck->setChecked(rule.isCategoryChangeEnabled());
ui.kCategoryTransfer->setText(rule.getAttribute(QStringLiteral("t_CATEGORY")));
ui.kUnitCmb->setCurrentIndex(rule.isAbolute() ? 1 : 0);
ui.kAmountEdit2->setValue(rule.getQuantity());
ui.kModeCmb->setCurrentIndex(ui.kModeCmb->findData(static_cast<int>(rule.getTransferMode())));
ui.kConditionCmb->setCurrentIndex(ui.kConditionCmb->findData(static_cast<int>(rule.getCondition())));
}
}
ui.kPeriod->setEnabled(nb <= 1);
ui.kYear->setEnabled(nb <= 1);
ui.kMonth->setEnabled(nb <= 1);
onCreatorModified();
refreshInfoZone();
Q_EMIT selectionChanged();
}
void SKGBudgetPluginWidget::activateEditor()
{
if (ui.kWidgetSelector->getSelectedMode() == -1) {
ui.kWidgetSelector->setSelectedMode(0);
}
ui.kAmountEdit->setFocus();
}
bool SKGBudgetPluginWidget::isEditor()
{
return true;
}
void SKGBudgetPluginWidget::refreshInfoZone()
{
SKGTRACEINFUNC(10)
auto* doc = qobject_cast<SKGDocumentBank*>(getDocument());
if ((doc != nullptr) && ui.kWidgetSelector->getSelectedMode() != 2) {
SKGServices::SKGUnitInfo primary = doc->getPrimaryUnit();
SKGServices::SKGUnitInfo secondary = doc->getSecondaryUnit();
// Refresh info area with selection
SKGObjectBase::SKGListSKGObjectBase selection = getSelectedObjects();
double budgeted = 0;
double modified = 0;
int nb = selection.count();
for (int i = 0; i < nb; ++i) {
SKGBudgetObject budget(selection.at(i));
budgeted += budget.getBudgetedAmount();
modified += budget.getBudgetedModifiedAmount();
}
QString budgetedS = doc->formatMoney(budgeted, primary);
QString modifiedS = doc->formatMoney(modified, primary);
QString v = (budgetedS == modifiedS ? budgetedS : modifiedS % " <s><small>" % budgetedS % "</small></s>");
if (nb != 0) {
ui.kInfo->setText(i18np("Selection: %1 budget for %2", "Selection: %1 budgets for %2", nb, v));
if (!secondary.Symbol.isEmpty() && (secondary.Value != 0.0)) {
budgetedS = doc->formatMoney(budgeted, secondary);
modifiedS = doc->formatMoney(modified, secondary);
v = (budgetedS == modifiedS ? budgetedS : modifiedS % " <s><small>" % budgetedS % "</small></s>");
}
ui.kInfo->setToolTip(i18np("Selection: %1 budget for %2", "Selection: %1 budgets for %2", nb, v));
} else {
ui.kInfo->setText(i18nc("Noun", "Selection: none"));
ui.kInfo->setToolTip(i18nc("Noun", "Selection: none"));
}
}
}
void SKGBudgetPluginWidget::onTop()
{
SKGError err;
SKGTRACEINFUNCRC(1, err)
// Get rules
SKGObjectBase::SKGListSKGObjectBase rules = getSelectedObjects();
int nb = rules.count();
{
SKGBEGINPROGRESSTRANSACTION(*getDocument(), i18nc("Noun, name of the user action", "Budget rule update"), err, nb)
for (int i = nb - 1; !err && i >= 0; --i) {
SKGBudgetRuleObject rule(rules.at(i));
double order = 1;
SKGStringListList result;
err = getDocument()->executeSelectSqliteOrder(QStringLiteral("SELECT min(f_sortorder) from budgetrule"), result);
if (!err && result.count() == 2) {
order = SKGServices::stringToDouble(result.at(1).at(0)) - 1;
}
IFOKDO(err, rule.setOrder(order))
IFOKDO(err, rule.save())
// Send message
IFOKDO(err, getDocument()->sendMessage(i18nc("An information to the user", "The budget rule '%1' has been updated", rule.getDisplayName()), SKGDocument::Hidden))
IFOKDO(err, getDocument()->stepForward(i + 1))
}
}
// status bar
IFOKDO(err, SKGError(0, i18nc("Successful message after an user action", "Budget rule updated")))
else {
err.addError(ERR_FAIL, i18nc("Error message", "Budget rule update failed"));
}
// Display error
SKGMainPanel::displayErrorMessage(err);
}
void SKGBudgetPluginWidget::onUp()
{
SKGError err;
SKGTRACEINFUNCRC(1, err)
// Get rules
SKGObjectBase::SKGListSKGObjectBase rules = getSelectedObjects();
int nb = rules.count();
{
SKGBEGINPROGRESSTRANSACTION(*getDocument(), i18nc("Noun, name of the user action", "Budget rule update"), err, nb)
for (int i = 0; !err && i < nb; ++i) {
SKGBudgetRuleObject rule(rules.at(i));
double order = rule.getOrder();
SKGStringListList result;
err = getDocument()->executeSelectSqliteOrder("SELECT f_sortorder from budgetrule where f_sortorder<" % SKGServices::doubleToString(order) % " ORDER BY f_sortorder DESC", result);
IFOK(err) {
if (result.count() == 2) {
order = SKGServices::stringToDouble(result.at(1).at(0)) - 1;
} else if (result.count() >= 2) {
order = (SKGServices::stringToDouble(result.at(1).at(0)) + SKGServices::stringToDouble(result.at(2).at(0))) / 2;
}
}
IFOKDO(err, rule.setOrder(order))
IFOKDO(err, rule.save())
// Send message
IFOKDO(err, getDocument()->sendMessage(i18nc("An information to the user", "The budget rule '%1' has been updated", rule.getDisplayName()), SKGDocument::Hidden))
IFOKDO(err, getDocument()->stepForward(i + 1))
}
}
// status bar
IFOKDO(err, SKGError(0, i18nc("Successful message after an user action", "Budget rule updated")))
else {
err.addError(ERR_FAIL, i18nc("Error message", "Budget rule update failed"));
}
// Display error
SKGMainPanel::displayErrorMessage(err);
}
void SKGBudgetPluginWidget::onDown()
{
SKGError err;
SKGTRACEINFUNCRC(1, err)
// Get rules
SKGObjectBase::SKGListSKGObjectBase rules = getSelectedObjects();
int nb = rules.count();
{
SKGBEGINPROGRESSTRANSACTION(*getDocument(), i18nc("Noun, name of the user action", "Budget rule update"), err, nb)
for (int i = nb - 1; !err && i >= 0; --i) {
SKGBudgetRuleObject rule(rules.at(i));
double order = rule.getOrder();
SKGStringListList result;
err = getDocument()->executeSelectSqliteOrder("SELECT f_sortorder from budgetrule where f_sortorder>" % SKGServices::doubleToString(order) % " ORDER BY f_sortorder ASC", result);
IFOK(err) {
if (result.count() == 2) {
order = SKGServices::stringToDouble(result.at(1).at(0)) + 1;
} else if (result.count() >= 2) {
order = (SKGServices::stringToDouble(result.at(1).at(0)) + SKGServices::stringToDouble(result.at(2).at(0))) / 2;
}
}
IFOKDO(err, rule.setOrder(order))
IFOKDO(err, rule.save())
// Send message
IFOKDO(err, getDocument()->sendMessage(i18nc("An information to the user", "The budget rule '%1' has been updated", rule.getDisplayName()), SKGDocument::Hidden))
IFOKDO(err, getDocument()->stepForward(i + 1))
}
}
// status bar
IFOKDO(err, SKGError(0, i18nc("Successful message after an user action", "Budget rule updated")))
else {
err.addError(ERR_FAIL, i18nc("Error message", "Budget rule update failed"));
}
// Display error
SKGMainPanel::displayErrorMessage(err);
}
void SKGBudgetPluginWidget::onBottom()
{
SKGError err;
SKGTRACEINFUNCRC(1, err)
// Get rules
SKGObjectBase::SKGListSKGObjectBase rules = getSelectedObjects();
int nb = rules.count();
{
SKGBEGINPROGRESSTRANSACTION(*getDocument(), i18nc("Noun, name of the user action", "Budget rule update"), err, nb)
for (int i = 0; !err && i < nb; ++i) {
SKGBudgetRuleObject rule(rules.at(i));
double order = 1;
SKGStringListList result;
err = getDocument()->executeSelectSqliteOrder(QStringLiteral("SELECT max(f_sortorder) from budgetrule"), result);
if (!err && result.count() == 2) {
order = SKGServices::stringToDouble(result.at(1).at(0)) + 1;
}
IFOKDO(err, rule.setOrder(order))
IFOKDO(err, rule.save())
// Send message
IFOKDO(err, getDocument()->sendMessage(i18nc("An information to the user", "The budget rule '%1' has been updated", rule.getDisplayName()), SKGDocument::Hidden))
IFOKDO(err, getDocument()->stepForward(i + 1))
}
}
// status bar
IFOKDO(err, SKGError(0, i18nc("Successful message after an user action", "Budget rule updated")))
else {
err.addError(ERR_FAIL, i18nc("Error message", "Budget rule update failed"));
}
// Display error
SKGMainPanel::displayErrorMessage(err);
}
diff --git a/plugins/skrooge/skrooge_budget/skgbudgetpluginwidget.h b/plugins/skrooge/skrooge_budget/skgbudgetpluginwidget.h
index 9a9a1395e..c00cb966b 100644
--- a/plugins/skrooge/skrooge_budget/skgbudgetpluginwidget.h
+++ b/plugins/skrooge/skrooge_budget/skgbudgetpluginwidget.h
@@ -1,134 +1,134 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGBUDGETPLUGINWIDGET_H
#define SKGBUDGETPLUGINWIDGET_H
/** @file
* A skrooge plugin to manage budgets
*
* @author Stephane MANKOWSKI
*/
#include "skgtabpage.h"
#include "ui_skgbudgetpluginwidget_base.h"
#include <qtimer.h>
class SKGObjectModel;
class SKGBudgetObject;
class SKGBudgetRuleObject;
/**
* A skrooge plugin to manage budgets
*/
class SKGBudgetPluginWidget : public SKGTabPage
{
Q_OBJECT
public:
/**
* Default Constructor
* @param iParent the parent widget
* @param iDocument the document
*/
explicit SKGBudgetPluginWidget(QWidget* iParent, SKGDocument* iDocument);
/**
* Default Destructor
*/
~SKGBudgetPluginWidget() override;
/**
* Get the current state
* MUST BE OVERWRITTEN
* @return a string containing all information needed to set the same state.
* Could be an XML stream
*/
QString getState() override;
/**
* Set the current state
* MUST BE OVERWRITTEN
* @param iState must be interpreted to set the state of the widget
*/
void setState(const QString& iState) override;
/**
* Get attribute name to save the default state
* MUST BE OVERWRITTEN
* @return attribute name to save the default state.
*/
QString getDefaultStateAttribute() override;
/**
* Get the main widget
* @return a widget
*/
QWidget* mainWidget() override;
/**
* To know if this page contains an editor. MUST BE OVERWRITTEN
* @return the editor state
*/
bool isEditor() override;
/**
* To activate the editor by setting focus on right widget. MUST BE OVERWRITTEN
*/
void activateEditor() override;
public Q_SLOTS:
/**
* Refresh the content.
*/
virtual void refresh();
protected:
/**
* Event filtering
* @param iObject object
* @param iEvent event
* @return In your reimplementation of this function, if you want to filter the event out, i.e. stop it being handled further, return true; otherwise return false.
*/
bool eventFilter(QObject* iObject, QEvent* iEvent) override;
private Q_SLOTS:
void dataModified(const QString& iTableName, int iIdTransaction, bool iLightTransaction = false);
void onCreatorModified();
void onAddClicked();
void onUpdateClicked();
void onSelectionChanged();
void onBtnModeClicked(int mode);
void onTop();
void onUp();
void onDown();
void onBottom();
void refreshInfoZone();
private:
Q_DISABLE_COPY(SKGBudgetPluginWidget)
Ui::skgbudgetplugin_base ui{};
SKGError updateBudget(SKGBudgetObject& iBudget, int iMonth = -1);
SKGError updateBudgetRule(SKGBudgetRuleObject& iRule);
SKGObjectModel* m_objectModel;
QString m_viewBudget;
QString m_viewRule;
QTimer m_timer;
};
#endif // SKGBUDGETPLUGINWIDGET_H
diff --git a/plugins/skrooge/skrooge_calculator/CMakeLists.txt b/plugins/skrooge/skrooge_calculator/CMakeLists.txt
index 8491bd97b..cf4842999 100644
--- a/plugins/skrooge/skrooge_calculator/CMakeLists.txt
+++ b/plugins/skrooge/skrooge_calculator/CMakeLists.txt
@@ -1,35 +1,35 @@
#***************************************************************************
#* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
#* *
#* 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 <http://www.gnu.org/licenses/> *
+#* along with this program. If not, see <https://www.gnu.org/licenses/> *
#***************************************************************************
MESSAGE( STATUS "..:: CMAKE PLUGIN_CALCULATOR ::..")
PROJECT(plugin_calculator)
LINK_DIRECTORIES (${LIBRARY_OUTPUT_PATH})
SET(skrooge_calculator_SRCS
skgcalculatorplugin.cpp
skgcalculatorpluginwidget.cpp)
ki18n_wrap_ui(skrooge_calculator_SRCS skgcalculatorpluginwidget_base.ui)
ADD_LIBRARY(skrooge_calculator MODULE ${skrooge_calculator_SRCS})
TARGET_LINK_LIBRARIES(skrooge_calculator KF5::Parts skgbasemodeler skgbasegui skgbankmodeler skgbankgui)
########### install files ###############
INSTALL(TARGETS skrooge_calculator DESTINATION ${KDE_INSTALL_QTPLUGINDIR})
INSTALL(FILES ${PROJECT_SOURCE_DIR}/org.kde.skrooge-plugin-calculator.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR})
INSTALL(FILES ${PROJECT_SOURCE_DIR}/skrooge_calculator.rc DESTINATION ${KDE_INSTALL_KXMLGUI5DIR}/skrooge_calculator )
diff --git a/plugins/skrooge/skrooge_calculator/org.kde.skrooge-plugin-calculator.desktop b/plugins/skrooge/skrooge_calculator/org.kde.skrooge-plugin-calculator.desktop
index 232338ddb..1230edc25 100644
--- a/plugins/skrooge/skrooge_calculator/org.kde.skrooge-plugin-calculator.desktop
+++ b/plugins/skrooge/skrooge_calculator/org.kde.skrooge-plugin-calculator.desktop
@@ -1,77 +1,77 @@
[Desktop Entry]
Name=Skrooge calculator plugin
Name[bs]=Skrooge dodatak za kalkulator
Name[ca]=Connector de càlcul de l'Skrooge
Name[ca@valencia]=Connector de càlcul de l'Skrooge
Name[cs]=Výpočtový modul Skrooge
Name[da]=Regnemaskine-plugin til Skrooge
Name[de]=Skrooge-Rechnermodul
Name[el]=krooge calculator plugin
Name[en_GB]=Skrooge calculator plugin
Name[eo]=Skrooge kalkulila kromaĵo
Name[es]=Complemento de calculadora de Skrooge
Name[et]=Skrooge arvutusplugin
Name[fi]=Skroogen laskinliitännäinen
Name[fr]=Module externe Skrooge de calcul
Name[gl]=Complemento de calculadora de Skrooge
Name[hu]=Skrooge számológép bővítmény
Name[it]=Estensione calcolatrice di Skrooge
Name[lt]=Skrooge skaičiuotuvo papildinys
Name[nb]=Skrooge kalkulatormodul
Name[nds]=Taschenreeknermoduul för Skrooge
Name[nl]=Rekenmachine-plugin voor Skrooge
Name[pl]=Wtyczka kalkulatora dla Skrooge
Name[pt]='Plugin' de calculadora do Skrooge
Name[pt_BR]=Plugin de calculadora do Skrooge
Name[ru]=Модуль вычислений
Name[sk]=Plugin kalkulačky Skrooge
Name[sv]=Skrooge insticksprogram med miniräknare
Name[tr]=Skrooge hesap makinesi eklentisi
Name[uk]=Додаток калькулятора Skrooge
Name[x-test]=xxSkrooge calculator pluginxx
Name[zh_TW]=Skrooge 計算機外掛程式
Comment=A skrooge plugin to calculate
Comment[bs]=Skrooge dodatak za kalkulisanje
Comment[ca]=Un connector de l'Skrooge per calcular
Comment[ca@valencia]=Un connector de l'Skrooge per calcular
Comment[cs]=Modul Skrooge pro provádění výpočtů
Comment[da]=Et Skrooge-plugin til at regne
Comment[de]=Ein Skrooge-Modul für einen Taschenrechner
Comment[el]=Ένα πρόσθετο του skrooge για αριθμητικές πράξεις
Comment[en_GB]=A skrooge plugin to calculate
Comment[es]=Un complemento de Skrooge para realizar cálculos
Comment[et]=Skrooge plugin arvutuste sooritamiseks
Comment[fi]=Skroogen laskinliitännäinen
Comment[fr]=Un module externe Skrooge de calcul
Comment[gl]=Un complemento de Skrooge para calcular.
Comment[hu]=Egy Skrooge bővítmény számításokhoz
Comment[it]=Un'estensione per calcolare di Skrooge
Comment[lt]=Skrooge skaičiavimo papildinys
Comment[nb]=En Skrooge-modul for beregning
Comment[nds]=En Taschenreeknermoduul för Skrooge
Comment[nl]=Een skrooge-plugin om mee te rekenen
Comment[pl]=Wtyczka Skrooge do obliczania
Comment[pt]=Um 'plugin' do Skrooge para efectuar cálculos
Comment[pt_BR]=Um plugin do Skrooge para calcular
Comment[ru]=Модуль вычислений
Comment[sk]=Plugin Skrooge na výpočty
Comment[sv]=Ett insticksprogram till Skrooge för beräkningar
Comment[tr]=Hesaplama işlemleri için bir Skrooge eklentisi
Comment[uk]=Додаток до skrooge для обчислень
Comment[x-test]=xxA skrooge plugin to calculatexx
Comment[zh_TW]=Skrooge 計算機外掛程式
Encoding=UTF-8
Icon=skrooge
Type=Service
X-KDE-ServiceTypes=SKG GUI/Plugin
X-KDE-Library=skrooge_calculator
X-Krunner-ID=Skrooge calculator plugin
X-KDE-PluginInfo-Author=Stephane MANKOWSKI,miraks
X-KDE-PluginInfo-Email=stephane@mankowski.fr
X-KDE-PluginInfo-Name=skrooge_calculator
X-KDE-PluginInfo-Version=1.0
-X-KDE-PluginInfo-Website=http://skrooge.org/
+X-KDE-PluginInfo-Website=https://skrooge.org/
X-KDE-PluginInfo-Category=Plugins
X-KDE-PluginInfo-Depends=
X-KDE-PluginInfo-License=GPL
X-KDE-PluginInfo-EnabledByDefault=true
diff --git a/plugins/skrooge/skrooge_calculator/skgcalculatorplugin.cpp b/plugins/skrooge/skrooge_calculator/skgcalculatorplugin.cpp
index 5272459db..35fa797c1 100644
--- a/plugins/skrooge/skrooge_calculator/skgcalculatorplugin.cpp
+++ b/plugins/skrooge/skrooge_calculator/skgcalculatorplugin.cpp
@@ -1,175 +1,175 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* A skrooge plugin to calculate
*
* @author Stephane MANKOWSKI
*/
#include "skgcalculatorplugin.h"
#include <kaboutdata.h>
#include <kactioncollection.h>
#include <kpluginfactory.h>
#include <kstandardaction.h>
#include "skgaccountobject.h"
#include "skgcalculatorpluginwidget.h"
#include "skgdocumentbank.h"
#include "skghtmlboardwidget.h"
#include "skgtraces.h"
/**
* This plugin factory.
*/
K_PLUGIN_FACTORY(SKGCalculatorPluginFactory, registerPlugin<SKGCalculatorPlugin>();)
SKGCalculatorPlugin::SKGCalculatorPlugin(QWidget* iWidget, QObject* iParent, const QVariantList& /*iArg*/) : SKGInterfacePlugin(iParent), m_currentBankDocument(nullptr)
{
Q_UNUSED(iWidget)
SKGTRACEINFUNC(10)
}
SKGCalculatorPlugin::~SKGCalculatorPlugin()
{
SKGTRACEINFUNC(10)
m_currentBankDocument = nullptr;
}
bool SKGCalculatorPlugin::setupActions(SKGDocument* iDocument)
{
SKGTRACEINFUNC(10)
m_currentBankDocument = qobject_cast<SKGDocumentBank*>(iDocument);
if (m_currentBankDocument == nullptr) {
return false;
}
setComponentName(QStringLiteral("skrooge_calculator"), title());
setXMLFile(QStringLiteral("skrooge_calculator.rc"));
// Create yours actions here
return true;
}
int SKGCalculatorPlugin::getNbDashboardWidgets()
{
return 1;
}
QString SKGCalculatorPlugin::getDashboardWidgetTitle(int iIndex)
{
Q_UNUSED(iIndex)
return i18nc("The estimated amount of money earned through interests on a remunerated account", "Estimated interest");
}
SKGBoardWidget* SKGCalculatorPlugin::getDashboardWidget(int iIndex)
{
Q_UNUSED(iIndex)
// Get QML mode for dashboard
KConfigSkeleton* skl = SKGMainPanel::getMainPanel()->getPluginByName(QStringLiteral("Dashboard plugin"))->getPreferenceSkeleton();
KConfigSkeletonItem* sklItem = skl->findItem(QStringLiteral("qmlmode"));
bool qml = sklItem->property().toBool();
return new SKGHtmlBoardWidget(SKGMainPanel::getMainPanel(), m_currentBankDocument,
getDashboardWidgetTitle(iIndex),
QStandardPaths::locate(QStandardPaths::GenericDataLocation, QStringLiteral("skrooge/html/default/interests.") % (qml ? QStringLiteral("qml") : QStringLiteral("html"))),
QStringList() << QStringLiteral("v_account_display") << QStringLiteral("interest"), SKGSimplePeriodEdit::PREVIOUS_AND_CURRENT_YEARS);
}
SKGTabPage* SKGCalculatorPlugin::getWidget()
{
SKGTRACEINFUNC(10)
return new SKGCalculatorPluginWidget(SKGMainPanel::getMainPanel(), m_currentBankDocument);
}
QString SKGCalculatorPlugin::title() const
{
return toolTip();
}
QString SKGCalculatorPlugin::icon() const
{
return QStringLiteral("accessories-calculator");
}
QString SKGCalculatorPlugin::toolTip() const
{
return i18nc("Compute financial simulations for various situations (interests...)", "Simulations");
}
int SKGCalculatorPlugin::getOrder() const
{
return 100;
}
QStringList SKGCalculatorPlugin::tips() const
{
QStringList output;
output.push_back(i18nc("Description of a tips", "<p>... you can use the <a href=\"skg://skrooge_calculator_plugin\">calculator</a> for many things</p>"));
return output;
}
bool SKGCalculatorPlugin::isInPagesChooser() const
{
return true;
}
SKGAdviceList SKGCalculatorPlugin::advice(const QStringList& iIgnoredAdvice)
{
SKGTRACEINFUNC(10)
SKGAdviceList output;
// Search investment accounts without interest rate
if (!iIgnoredAdvice.contains(QStringLiteral("skgcalculatorplugin_nointerest"))) {
SKGObjectBase::SKGListSKGObjectBase accounts;
m_currentBankDocument->getObjects(QStringLiteral("account"), QStringLiteral("t_type='I' AND t_close='N' AND NOT EXISTS (SELECT 1 FROM interest WHERE interest.rd_account_id=account.id)"), accounts);
int nb = accounts.count();
SKGAdvice::SKGAdviceActionList autoCorrections;
for (int i = 0; i < nb; ++i) {
SKGAccountObject account(accounts.at(i));
SKGAdvice ad;
ad.setUUID("skgcalculatorplugin_nointerest|" % account.getName());
ad.setPriority(3);
ad.setShortMessage(i18nc("User did not define an interest rate on an investment account", "No interest rate defined for account '%1'", account.getName()));
ad.setLongMessage(i18nc("User did not define an interest rate on an investment account", "Your investment account '%1' doesn't have interest rate defined", account.getName()));
autoCorrections.resize(0);
{
SKGAdvice::SKGAdviceAction a;
a.Title = i18nc("Link allowing user to open a new tab for defining interests parameters", "Open interest page");
a.IconName = QStringLiteral("quickopen");
a.IsRecommended = false;
autoCorrections.push_back(a);
}
ad.setAutoCorrections(autoCorrections);
output.push_back(ad);
}
}
return output;
}
SKGError SKGCalculatorPlugin::executeAdviceCorrection(const QString& iAdviceIdentifier, int iSolution)
{
if ((m_currentBankDocument != nullptr) && iAdviceIdentifier.startsWith(QLatin1String("skgcalculatorplugin_nointerest|"))) {
// Get parameters
QString account = iAdviceIdentifier.right(iAdviceIdentifier.length() - 31);
SKGMainPanel::getMainPanel()->openPage("skg://skrooge_calculator_plugin/?currentPage=0&account=" % SKGServices::encodeForUrl(account));
return SKGError();
}
return SKGInterfacePlugin::executeAdviceCorrection(iAdviceIdentifier, iSolution);
}
#include <skgcalculatorplugin.moc>
diff --git a/plugins/skrooge/skrooge_calculator/skgcalculatorplugin.h b/plugins/skrooge/skrooge_calculator/skgcalculatorplugin.h
index 8061e5677..382cc818e 100644
--- a/plugins/skrooge/skrooge_calculator/skgcalculatorplugin.h
+++ b/plugins/skrooge/skrooge_calculator/skgcalculatorplugin.h
@@ -1,140 +1,140 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGCALCULATORPLUGIN_H
#define SKGCALCULATORPLUGIN_H
/** @file
* A skrooge plugin to calculate.
*
* @author Stephane MANKOWSKI
*/
#include "skginterfaceplugin.h"
class SKGDocumentBank;
/**
* A skrooge plugin to calculate
*/
class SKGCalculatorPlugin : public SKGInterfacePlugin
{
Q_OBJECT
Q_INTERFACES(SKGInterfacePlugin)
public:
/**
* Default Constructor
*/
explicit SKGCalculatorPlugin(QWidget* iWidget, QObject* iParent, const QVariantList& iArg);
/**
* Default Destructor
*/
~SKGCalculatorPlugin() override;
/**
* Called to initialise the plugin
* @param iDocument the main document
* @return true if the plugin is compatible with the document
*/
bool setupActions(SKGDocument* iDocument) override;
/**
* The number of dashboard widgets of the plugin.
* @return The number of dashboard widgets of the plugin
*/
int getNbDashboardWidgets() override;
/**
* Get a dashboard widget title of the plugin.
* @param iIndex the index of the widget
* @return The title
*/
QString getDashboardWidgetTitle(int iIndex) override;
/**
* Get a dashboard widget of the plugin.
* @param iIndex the index of the widget
* @return The dashboard widget of the plugin
*/
SKGBoardWidget* getDashboardWidget(int iIndex) override;
/**
* The page widget of the plugin.
* @return The page widget of the plugin
*/
SKGTabPage* getWidget() override;
/**
* The title of the plugin.
* @return The title of the plugin
*/
QString title() const override;
/**
* The icon of the plugin.
* @return The icon of the plugin
*/
QString icon() const override;
/**
* The toolTip of the plugin.
* @return The toolTip of the plugin
*/
QString toolTip() const override;
/**
* The tips list of the plugin.
* @return The tips list of the plugin
*/
QStringList tips() const override;
/**
* Must be implemented to set the position of the plugin.
* @return integer value between 0 and 999 (default = 999)
*/
int getOrder() const override;
/**
* Must be implemented to know if a plugin must be display in pages chooser.
* @return true of false (default = false)
*/
bool isInPagesChooser() const override;
/**
* The advice list of the plugin.
* @return The advice list of the plugin
*/
SKGAdviceList advice(const QStringList& iIgnoredAdvice) override;
/**
* Must be implemented to execute the automatic correction for the advice.
* @param iAdviceIdentifier the identifier of the advice
* @param iSolution the identifier of the possible solution
* @return an object managing the error. MUST return ERR_NOTIMPL if iAdviceIdentifier is not known
* @see SKGError
*/
SKGError executeAdviceCorrection(const QString& iAdviceIdentifier, int iSolution) override;
private Q_SLOTS:
private:
Q_DISABLE_COPY(SKGCalculatorPlugin)
SKGDocumentBank* m_currentBankDocument;
};
#endif // SKGCALCULATORPLUGIN_H
diff --git a/plugins/skrooge/skrooge_calculator/skgcalculatorpluginwidget.cpp b/plugins/skrooge/skrooge_calculator/skgcalculatorpluginwidget.cpp
index 94a4559fa..bbddb409d 100644
--- a/plugins/skrooge/skrooge_calculator/skgcalculatorpluginwidget.cpp
+++ b/plugins/skrooge/skrooge_calculator/skgcalculatorpluginwidget.cpp
@@ -1,605 +1,605 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* A skrooge plugin to calculate.
*
* @author Stephane MANKOWSKI
*/
#include "skgcalculatorpluginwidget.h"
#include <qdir.h>
#include <qdom.h>
#include <qevent.h>
#include <qmath.h>
#include <qstandardpaths.h>
#include "skgaccountobject.h"
#include "skgdocumentbank.h"
#include "skginterestobject.h"
#include "skgmainpanel.h"
#include "skgobjectmodel.h"
#include "skgtraces.h"
#include "skgtransactionmng.h"
#include "skgunitobject.h"
SKGCalculatorPluginWidget::SKGCalculatorPluginWidget(QWidget* iParent, SKGDocumentBank* iDocument)
: SKGTabPage(iParent, iDocument), m_objectModel(nullptr)
{
SKGTRACEINFUNC(1)
if (iDocument == nullptr) {
return;
}
m_timer.setSingleShot(true);
connect(&m_timer, &QTimer::timeout, this, &SKGCalculatorPluginWidget::onAmortizationComputation, Qt::QueuedConnection);
ui.setupUi(this);
ui.kUnitEdit->setDocument(iDocument);
ui.kUnitEdit->setWhereClauseCondition(QStringLiteral("t_type IN ('1','2','C')"));
ui.kUpdate->setIcon(SKGServices::fromTheme(QStringLiteral("dialog-ok")));
ui.kAdd->setIcon(SKGServices::fromTheme(QStringLiteral("list-add")));
ui.kLoadSummaryTitle->setPixmap(SKGServices::fromTheme(QStringLiteral("configure")).pixmap(22, 22), KTitleWidget::ImageLeft);
ui.kPaymentSummaryTitle->setPixmap(SKGServices::fromTheme(QStringLiteral("bookmarks")).pixmap(22, 22), KTitleWidget::ImageLeft);
ui.kAmortizationTableTitle->setPixmap(SKGServices::fromTheme(QStringLiteral("view-pim-calendar")).pixmap(22, 22), KTitleWidget::ImageLeft);
ui.kInterestResultsTitle->setPixmap(SKGServices::fromTheme(QStringLiteral("bookmarks")).pixmap(22, 22), KTitleWidget::ImageLeft);
ui.kInterestValuesTitle->setPixmap(SKGServices::fromTheme(QStringLiteral("configure")).pixmap(22, 22), KTitleWidget::ImageLeft);
ui.kDefineValueTitle->setPixmap(SKGServices::fromTheme(QStringLiteral("configure")).pixmap(22, 22), KTitleWidget::ImageLeft);
ui.kCreditValueDate->addItem(i18nc("A period of 15 days", "Fifteen"));
ui.kDebitValueDate->addItem(i18nc("A period of 15 days", "Fifteen"));
for (int i = 0 ; i <= 5 ; ++i) {
ui.kCreditValueDate->addItem(i18nc("Used for configurating when interests are paid on an account : %s days after being calculated", "Day +%1", i));
ui.kDebitValueDate->addItem(i18nc("Used for configurating when interests are paid on an account : %s days after being calculated", "Day -%1", i));
}
ui.kMode->addItem(i18nc("24 fifteen is the name of a financial method to compute interests on an account", "24 fifteen"));
ui.kMode->addItem(i18nc("A period of 360 days", "360 days"));
ui.kMode->addItem(i18nc("A period of 365 days", "365 days"));
ui.kAmortizationTable->verticalHeader()->setDefaultSectionSize(ui.kAmortizationTable->verticalHeader()->minimumSectionSize());
SKGWidgetSelector::SKGListQWidget list;
list.push_back(ui.kInterestFrm);
list.push_back(ui.kBtnFrm);
ui.kWidgetSelector->addButton(SKGServices::fromTheme(QStringLiteral("taxes-finances")), i18n("Interest"), i18n("Interests calculator"), list);
ui.kWidgetSelector->addButton(SKGServices::fromTheme(QStringLiteral("accessories-calculator")), i18n("Amortization Table"), i18n("Loan amortization table calculator"), ui.kAmortizationFrm);
connect(ui.kWidgetSelector, &SKGWidgetSelector::selectedModeChanged, this, &SKGCalculatorPluginWidget::onBtnModeClicked);
// Bind account creation view
m_objectModel = new SKGObjectModel(qobject_cast<SKGDocumentBank*>(getDocument()), QStringLiteral("v_interest"), QLatin1String(""), this, QLatin1String(""), false);
ui.kInterestView->setModel(m_objectModel);
auto resultModel = new SKGObjectModel(qobject_cast<SKGDocumentBank*>(getDocument()), QStringLiteral("interest_result"), QLatin1String(""), this, QLatin1String(""), false);
ui.kInterestResultTable->setModel(resultModel);
connect(ui.kInterestView, &SKGTableView::selectionChangedDelayed, this, &SKGCalculatorPluginWidget::onSelectionChanged);
connect(m_objectModel, &SKGObjectModelBase::beforeReset, ui.kInterestView, &SKGTreeView::saveSelection);
connect(m_objectModel, &SKGObjectModelBase::afterReset, ui.kInterestView, &SKGTreeView::resetSelection);
ui.kWidgetSelector->setSelectedMode(0);
// Refresh
connect(ui.kDisplayAccountCombo, static_cast<void (SKGComboBox::*)(const QString&)>(&SKGComboBox::currentTextChanged), this, &SKGCalculatorPluginWidget::onFilterChanged, Qt::QueuedConnection);
connect(ui.KYearEdit, static_cast<void (SKGComboBox::*)(const QString&)>(&SKGComboBox::currentTextChanged), this, &SKGCalculatorPluginWidget::onFilterChanged, Qt::QueuedConnection);
connect(getDocument(), &SKGDocument::tableModified, this, &SKGCalculatorPluginWidget::dataModified, Qt::QueuedConnection);
dataModified(QLatin1String(""), 0);
// Set Event filters to catch CTRL+ENTER or SHIFT+ENTER
this->installEventFilter(this);
// Synchronize zooms of both tables
connect(ui.kInterestResultTable, &SKGTableView::zoomChanged, ui.kInterestView, &SKGTableView::setZoomPosition);
connect(ui.kInterestView, &SKGTableView::zoomChanged, ui.kInterestResultTable, &SKGTableView::setZoomPosition);
// Other connects
connect(ui.kAdd, &QPushButton::clicked, this, &SKGCalculatorPluginWidget::onAdd);
connect(ui.kUpdate, &QPushButton::clicked, this, &SKGCalculatorPluginWidget::onUpdate);
connect(ui.kLoanEdit, &SKGCalculatorEdit::textChanged, this, &SKGCalculatorPluginWidget::onAmortizationComputationDelayed);
connect(ui.kUnitEdit, static_cast<void (SKGUnitComboBox::*)(const QString&)>(&SKGUnitComboBox::currentTextChanged), this, &SKGCalculatorPluginWidget::onAmortizationComputationDelayed);
connect(ui.kLenghtEdit, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), this, &SKGCalculatorPluginWidget::onAmortizationComputationDelayed);
connect(ui.kAnnualRateEdit, static_cast<void (QDoubleSpinBox::*)(double)>(&QDoubleSpinBox::valueChanged), this, &SKGCalculatorPluginWidget::onAmortizationComputationDelayed);
connect(ui.kInsuranceRateEdit, static_cast<void (QDoubleSpinBox::*)(double)>(&QDoubleSpinBox::valueChanged), this, &SKGCalculatorPluginWidget::onAmortizationComputationDelayed);
}
SKGCalculatorPluginWidget::~SKGCalculatorPluginWidget()
{
SKGTRACEINFUNC(1)
m_objectModel = nullptr;
}
bool SKGCalculatorPluginWidget::eventFilter(QObject* iObject, QEvent* iEvent)
{
if ((iEvent != nullptr) && iEvent->type() == QEvent::KeyPress) {
auto* keyEvent = dynamic_cast<QKeyEvent*>(iEvent);
if (keyEvent && (keyEvent->key() == Qt::Key_Return || keyEvent->key() == Qt::Key_Enter) && iObject == this) {
if ((QApplication::keyboardModifiers() & Qt::ControlModifier) != 0u && ui.kAdd->isEnabled()) {
ui.kAdd->click();
} else if ((QApplication::keyboardModifiers() &Qt::ShiftModifier) != 0u && ui.kUpdate->isEnabled()) {
ui.kUpdate->click();
}
}
}
return SKGTabPage::eventFilter(iObject, iEvent);
}
QString SKGCalculatorPluginWidget::getState()
{
SKGTRACEINFUNC(10)
QDomDocument doc(QStringLiteral("SKGML"));
QDomElement root = doc.createElement(QStringLiteral("parameters"));
doc.appendChild(root);
root.setAttribute(QStringLiteral("currentPage"), SKGServices::intToString(ui.kWidgetSelector->getSelectedMode()));
root.setAttribute(QStringLiteral("account"), ui.kDisplayAccountCombo->currentText());
root.setAttribute(QStringLiteral("year"), ui.KYearEdit->text());
root.setAttribute(QStringLiteral("amortizationLoan"), ui.kLoanEdit->text());
root.setAttribute(QStringLiteral("amortizationUnit"), ui.kUnitEdit->text());
root.setAttribute(QStringLiteral("amortizationRate"), SKGServices::doubleToString(ui.kAnnualRateEdit->value()));
root.setAttribute(QStringLiteral("amortizationLenght"), SKGServices::intToString(ui.kLenghtEdit->value()));
root.setAttribute(QStringLiteral("amortizationInsuranceRate"), SKGServices::doubleToString(ui.kInsuranceRateEdit->value()));
// Memorize table settings
root.setAttribute(QStringLiteral("view"), ui.kInterestView->getState());
root.setAttribute(QStringLiteral("viewResult"), ui.kInterestResultTable->getState());
return doc.toString();
}
void SKGCalculatorPluginWidget::setState(const QString& iState)
{
SKGTRACEINFUNC(10)
QDomDocument doc(QStringLiteral("SKGML"));
doc.setContent(iState);
QDomElement root = doc.documentElement();
QString account = root.attribute(QStringLiteral("account"));
QString currentPage = root.attribute(QStringLiteral("currentPage"));
QString year = root.attribute(QStringLiteral("year"));
QString amortizationLoan = root.attribute(QStringLiteral("amortizationLoan"));
QString amortizationUnit = root.attribute(QStringLiteral("amortizationUnit"));
QString amortizationRate = root.attribute(QStringLiteral("amortizationRate"));
QString amortizationInsuranceRate = root.attribute(QStringLiteral("amortizationInsuranceRate"));
QString amortizationLenght = root.attribute(QStringLiteral("amortizationLenght"));
if (!currentPage.isEmpty()) {
ui.kWidgetSelector->setSelectedMode(SKGServices::stringToInt(currentPage));
}
if (!account.isEmpty()) {
bool previous = ui.kDisplayAccountCombo->blockSignals(true);
ui.kDisplayAccountCombo->setText(account);
ui.kDisplayAccountCombo->blockSignals(previous);
}
if (!amortizationLoan.isEmpty()) {
ui.kLoanEdit->setText(amortizationLoan);
}
if (!amortizationUnit.isEmpty()) {
ui.kUnitEdit->setText(amortizationUnit);
}
if (!amortizationRate.isEmpty()) {
ui.kAnnualRateEdit->setValue(SKGServices::stringToDouble(amortizationRate));
}
if (!amortizationInsuranceRate.isEmpty()) {
ui.kInsuranceRateEdit->setValue(SKGServices::stringToDouble(amortizationInsuranceRate));
}
if (!amortizationLenght.isEmpty()) {
ui.kLenghtEdit->setValue(SKGServices::stringToInt(amortizationLenght));
}
if (!year.isEmpty()) {
ui.KYearEdit->setText(year);
}
// Update model
if (m_objectModel != nullptr) {
bool previous = m_objectModel->blockRefresh(true);
onFilterChanged();
m_objectModel->blockRefresh(previous);
}
// !!! Must be done here after onFilterChanged
ui.kInterestView->setState(root.attribute(QStringLiteral("view")));
ui.kInterestResultTable->setState(root.attribute(QStringLiteral("viewResult")));
}
QString SKGCalculatorPluginWidget::getDefaultStateAttribute()
{
return QStringLiteral("SKGCALCULATOR_DEFAULT_PARAMETERS");
}
void SKGCalculatorPluginWidget::onBtnModeClicked(int mode)
{
Q_UNUSED(mode)
// Save zoom position of previous page
int zoom = zoomPosition();
// Save zoom position on new page
setZoomPosition(zoom);
Q_EMIT selectionChanged();
}
void SKGCalculatorPluginWidget::onSelectionChanged()
{
SKGTRACEINFUNC(10)
// Mapping
QItemSelectionModel* selModel = ui.kInterestView->selectionModel();
if (selModel != nullptr) {
QModelIndexList indexes = selModel->selectedRows();
if (!indexes.isEmpty() && (m_objectModel != nullptr)) {
QModelIndex idx = indexes[indexes.count() - 1];
SKGInterestObject interest(m_objectModel->getObject(idx));
ui.kDateEdit->setDate(interest.getDate());
ui.kRateEdit->setValue(interest.getRate());
ui.kCreditValueDate->setCurrentIndex(static_cast<int>(interest.getIncomeValueDateMode()));
ui.kDebitValueDate->setCurrentIndex(static_cast<int>(interest.getExpenditueValueDateMode()));
ui.kMode->setCurrentIndex(static_cast<int>(interest.getInterestComputationMode()));
}
Q_EMIT selectionChanged();
}
}
void SKGCalculatorPluginWidget::dataModified(const QString& iTableName, int iIdTransaction)
{
SKGTRACEINFUNC(10)
Q_UNUSED(iIdTransaction)
QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
// Refresh widgets
QSqlDatabase* db = getDocument()->getMainDatabase();
setEnabled(db != nullptr);
if (db != nullptr && (iTableName == QStringLiteral("interest") || iTableName.isEmpty())) {
// Correction bug 2299394 vvv
if (ui.kInterestView->isAutoResized()) {
ui.kInterestView->resizeColumnsToContentsDelayed();
}
// Correction bug 2299394 ^^^
// Correction 215658: vvv because the table is modified, the selection is modified
onSelectionChanged();
// Correction 215658: ^^^
}
// Refresh interest parameter view
QString current = ui.kDisplayAccountCombo->currentText();
if (db != nullptr && (iTableName == QStringLiteral("v_account_display") || iTableName.isEmpty())) {
// Clear
ui.kDisplayAccountCombo->clear();
SKGStringListList listAccount;
getDocument()->executeSelectSqliteOrder(QStringLiteral("SELECT t_ICON, t_name from v_account_display where t_close='N' order by t_name"), listAccount);
int nbAccounts = listAccount.count();
if (nbAccounts >= 0) {
for (int i = 1; i < nbAccounts; ++i) { // Ignore header
QString fileName = QStandardPaths::locate(QStandardPaths::GenericDataLocation, "skrooge/images/logo/" % listAccount.at(i).at(0));
if (fileName.isEmpty()) {
fileName = listAccount.at(i).at(0);
}
QIcon icon(fileName);
QString text = listAccount.at(i).at(1);
ui.kDisplayAccountCombo->addItem(icon, text);
}
}
int posText = ui.kDisplayAccountCombo->findText(current);
if (posText == -1) {
posText = 0;
}
ui.kDisplayAccountCombo->setCurrentIndex(posText);
ui.kAdd->setEnabled(ui.kDisplayAccountCombo->count() > 0);
}
// Fill years
if (db != nullptr && (iTableName == QStringLiteral("v_operation_display") || iTableName.isEmpty())) {
disconnect(ui.KYearEdit, static_cast<void (SKGComboBox::*)(const QString&)>(&SKGComboBox::currentTextChanged), this, &SKGCalculatorPluginWidget::onFilterChanged);
int lastYear = QDate::currentDate().year();
int firstYear = lastYear;
QStringList list;
getDocument()->getDistinctValues(QStringLiteral("v_operation_display"), QStringLiteral("d_DATEYEAR"), QLatin1String(""), list);
if (!list.isEmpty()) {
firstYear = SKGServices::stringToInt(list.at(0));
}
QString year = ui.KYearEdit->text();
ui.KYearEdit->clear();
for (int i = lastYear; i >= firstYear; --i) {
QString v = SKGServices::intToString(i);
if (year.isEmpty()) {
year = v;
}
ui.KYearEdit->addItem(v);
}
ui.KYearEdit->setText(year);
connect(ui.KYearEdit, static_cast<void (SKGComboBox::*)(const QString&)>(&SKGComboBox::currentTextChanged), this, &SKGCalculatorPluginWidget::onFilterChanged);
}
// Refresh computation
if (db != nullptr && (iTableName == QStringLiteral("interest") || iTableName == QStringLiteral("account") || iTableName.isEmpty())) {
computeInterest();
}
QApplication::restoreOverrideCursor();
}
void SKGCalculatorPluginWidget::computeInterest()
{
// Compute
SKGAccountObject account(getDocument());
SKGError err = account.setName(ui.kDisplayAccountCombo->currentText());
IFOKDO(err, account.load())
SKGAccountObject::SKGInterestItemList oInterestList;
double oInterests = 0;
IFOKDO(err, account.getInterestItems(oInterestList, oInterests, SKGServices::stringToInt(ui.KYearEdit->text())))
IFOK(err) {
// Refresh table
ui.kInterestResultTable->setState(ui.kInterestResultTable->getState());
// Set text
auto* doc = qobject_cast<SKGDocumentBank*>(getDocument());
if (doc != nullptr) {
SKGServices::SKGUnitInfo unit1 = doc->getPrimaryUnit();
SKGServices::SKGUnitInfo unit2 = doc->getSecondaryUnit();
QString s1 = doc->formatMoney(oInterests, unit1);
ui.kInterestLbl->setText(i18nc("The Annual interest is the amount of money gained in one year on a remunerated account", "Annual interest=%1", s1));
if (!unit2.Symbol.isEmpty() && (unit2.Value != 0.0)) {
s1 = doc->formatMoney(oInterests, unit2);
ui.kInterestLbl->setToolTip(i18nc("The Annual interest is the amount of money gained in one year on a remunerated account", "Annual interest=%1", s1));
}
}
}
}
void SKGCalculatorPluginWidget::onFilterChanged()
{
SKGTRACEINFUNC(1)
if (!isEnabled()) {
return;
}
QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
// Compute where clause
QString account = ui.kDisplayAccountCombo->currentText();
QString filter2 = "t_ACCOUNT='" % SKGServices::stringToSqlString(account) % "' ORDER BY d_date";
// Update model
if (m_objectModel != nullptr) {
if (m_objectModel->setFilter(filter2)) {
ui.kInterestView->setState(ui.kInterestView->getState());
}
// Compute result
computeInterest();
}
QApplication::restoreOverrideCursor();
}
SKGObjectBase::SKGListSKGObjectBase SKGCalculatorPluginWidget::getSelectedObjects()
{
SKGObjectBase::SKGListSKGObjectBase output;
if (ui.kWidgetSelector->getSelectedMode() == 0) {
output = ui.kInterestView->getSelectedObjects();
}
return output;
}
int SKGCalculatorPluginWidget::getNbSelectedObjects()
{
int output = 0;
if (ui.kWidgetSelector->getSelectedMode() == 0) {
output = ui.kInterestView->getNbSelectedObjects();
}
return output;
}
// void SKGCalculatorPluginWidget::onCalculatorReturnPressed(const QString& iText)
// {
// // ui.kCalculatorList->addItem(iText);
// }
// /*void SKGCalculatorPluginWidget::onCalculatorListClicked(const QString& iText)
// {
// // ui.kCalculatorEdit->setText(iText);
// // ui.kCalculatorEdit->setFocus();
// }*/
void SKGCalculatorPluginWidget::onSelectedInterestChanged()
{
int nbSel = getNbSelectedObjects();
ui.kDateEdit->setEnabled(nbSel <= 1);
ui.kRateEdit->setEnabled(nbSel <= 1);
ui.kAdd->setEnabled(nbSel <= 1);
}
void SKGCalculatorPluginWidget::onAdd()
{
SKGError err;
SKGTRACEINFUNCRC(10, err) {
SKGInterestObject interestObj;
{
QString accountname = ui.kDisplayAccountCombo->currentText();
SKGBEGINTRANSACTION(*getDocument(), i18nc("Lets the user create parameters for computing interests on an account", "Interest parameter creation for account '%1'", accountname), err)
// Get Parent account
SKGAccountObject accountObj(getDocument());
IFOKDO(err, accountObj.setName(accountname))
IFOKDO(err, accountObj.load())
// Create interest object
IFOKDO(err, accountObj.addInterest(interestObj))
IFOKDO(err, interestObj.setDate(ui.kDateEdit->date()))
IFOKDO(err, interestObj.setRate(ui.kRateEdit->value()))
IFOKDO(err, interestObj.setIncomeValueDateMode(static_cast<SKGInterestObject::ValueDateMode>(ui.kCreditValueDate->currentIndex())))
IFOKDO(err, interestObj.setExpenditueValueDateMode(static_cast<SKGInterestObject::ValueDateMode>(ui.kDebitValueDate->currentIndex())))
IFOKDO(err, interestObj.setInterestComputationMode(static_cast<SKGInterestObject::InterestMode>(ui.kMode->currentIndex())))
IFOKDO(err, interestObj.save())
// Send message
IFOKDO(err, interestObj.getDocument()->sendMessage(i18nc("An information to the user", "The interest parameter '%1' has been added", interestObj.getDisplayName()), SKGDocument::Hidden))
}
// status bar
IFOK(err) {
err = SKGError(0, i18nc("User defined parameters for computing interests were successfully created", "Interest parameter created"));
ui.kInterestView->selectObject(interestObj.getUniqueID());
} else {
err.addError(ERR_FAIL, i18nc("Error message: User defined parameters for computing interests could not be created", "Interest parameter creation failed"));
}
}
// Display error
SKGMainPanel::displayErrorMessage(err, true);
}
void SKGCalculatorPluginWidget::onUpdate()
{
SKGError err;
SKGTRACEINFUNCRC(10, err)
// Get Parent account
QString accountname = ui.kDisplayAccountCombo->currentText();
SKGAccountObject accountObj(getDocument());
IFOKDO(err, accountObj.setName(accountname))
IFOKDO(err, accountObj.load())
SKGObjectBase::SKGListSKGObjectBase updatedInterest = getSelectedObjects();
int nb = updatedInterest.count();
{
SKGInterestObject interestObj;
SKGBEGINTRANSACTION(*getDocument(), i18nc("Lets the user update parameters for computing interests on an account", "Interest parameter update for account '%1'", accountname), err)
for (int i = 0; !err && i < nb; ++i) {
interestObj = updatedInterest.at(i);
if (nb == 1) {
IFOKDO(err, interestObj.setDate(ui.kDateEdit->date()))
IFOKDO(err, interestObj.setRate(ui.kRateEdit->value()))
}
IFOKDO(err, interestObj.setIncomeValueDateMode(static_cast<SKGInterestObject::ValueDateMode>(ui.kCreditValueDate->currentIndex())))
IFOKDO(err, interestObj.setExpenditueValueDateMode(static_cast<SKGInterestObject::ValueDateMode>(ui.kDebitValueDate->currentIndex())))
IFOKDO(err, interestObj.setInterestComputationMode(static_cast<SKGInterestObject::InterestMode>(ui.kMode->currentIndex())))
IFOKDO(err, interestObj.save())
// Send message
IFOKDO(err, interestObj.getDocument()->sendMessage(i18nc("An information to the user", "The interest parameter '%1' has been updated", interestObj.getDisplayName()), SKGDocument::Hidden))
}
}
// status bar
IFOKDO(err, SKGError(0, i18nc("User defined parameters for computing interests were successfully updated", "Interest parameter updated")))
else {
err.addError(ERR_FAIL, i18nc("Error message: User defined parameters for computing interests could not be updated", "Interest parameter update failed"));
}
// Display error
SKGMainPanel::displayErrorMessage(err, true);
}
void SKGCalculatorPluginWidget::onAmortizationComputationDelayed()
{
m_timer.start(300);
}
void SKGCalculatorPluginWidget::onAmortizationComputation()
{
SKGTRACEINFUNC(10)
QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
// Get unit
SKGServices::SKGUnitInfo unitInfo;
unitInfo.Symbol = ui.kUnitEdit->text();
SKGUnitObject unit(getDocument());
unit.setSymbol(unitInfo.Symbol);
unit.load();
unitInfo.NbDecimal = unit.getNumberDecimal();
int p = qPow(10, unitInfo.NbDecimal);
// Computation
int periodInMonths = 12;
int numberPayments = ui.kLenghtEdit->value() * periodInMonths;
double periodicRate = ui.kAnnualRateEdit->value() / 100 / periodInMonths;
double insurance = qRound(ui.kLoanEdit->value() * ui.kInsuranceRateEdit->value() / 100.0 / static_cast<double>(periodInMonths) * static_cast<double>(p)) / static_cast<double>(p);
double periodicAmount = qRound(ui.kLoanEdit->value() * periodicRate / (1 - pow(1 + periodicRate, -numberPayments)) * static_cast<double>(p)) / static_cast<double>(p);
// Fill table
double dueAmount = ui.kLoanEdit->value();
double sumInterest = 0;
ui.kAmortizationTable->setRowCount(numberPayments);
for (int i = 0; i < numberPayments; ++i) {
// Compute
double roundedInterest = qRound(dueAmount * periodicRate * static_cast<double>(p)) / static_cast<double>(p);
double principal = qRound((i == numberPayments - 1 ? dueAmount : periodicAmount - roundedInterest) * p) / static_cast<double>(p);
double amount = roundedInterest + principal;
dueAmount -= principal;
sumInterest += roundedInterest;
// Add items
ui.kAmortizationTable->setItem(i, 0, new QTableWidgetItem(SKGServices::toCurrencyString(amount, unitInfo.Symbol, unitInfo.NbDecimal)));
ui.kAmortizationTable->setItem(i, 1, new QTableWidgetItem(SKGServices::toCurrencyString(principal, unitInfo.Symbol, unitInfo.NbDecimal)));
ui.kAmortizationTable->setItem(i, 2, new QTableWidgetItem(SKGServices::toCurrencyString(roundedInterest, unitInfo.Symbol, unitInfo.NbDecimal)));
ui.kAmortizationTable->setItem(i, 3, new QTableWidgetItem(SKGServices::toCurrencyString(insurance, unitInfo.Symbol, unitInfo.NbDecimal)));
ui.kAmortizationTable->setItem(i, 4, new QTableWidgetItem(SKGServices::toCurrencyString(dueAmount, unitInfo.Symbol, unitInfo.NbDecimal)));
}
ui.kAmortizationResult->setText(i18n("Number of payments: %1\n" // NOLINT(whitespace/tab)
"Monthly payment: %2\n" // NOLINT(whitespace/tab)
"Monthly insurance: %3\n" // NOLINT(whitespace/tab)
"Total principal paid: %4\n" // NOLINT(whitespace/tab)
"Total interest paid: %5\n" // NOLINT(whitespace/tab)
"Total insurance paid: %6\n" // NOLINT(whitespace/tab)
"Total paid: %7", // NOLINT(whitespace/tab)
SKGServices::intToString(numberPayments),
SKGServices::toCurrencyString(periodicAmount, unitInfo.Symbol, unitInfo.NbDecimal),
SKGServices::toCurrencyString(insurance, unitInfo.Symbol, unitInfo.NbDecimal),
SKGServices::toCurrencyString(ui.kLoanEdit->value(), unitInfo.Symbol, unitInfo.NbDecimal),
SKGServices::toCurrencyString(sumInterest, unitInfo.Symbol, unitInfo.NbDecimal),
SKGServices::toCurrencyString(numberPayments * insurance, unitInfo.Symbol, unitInfo.NbDecimal),
SKGServices::toCurrencyString(ui.kLoanEdit->value() + sumInterest + numberPayments * insurance, unitInfo.Symbol, unitInfo.NbDecimal)));
QApplication::restoreOverrideCursor();
}
QWidget* SKGCalculatorPluginWidget::zoomableWidget()
{
if (ui.kWidgetSelector->getSelectedMode() == 0) {
return ui.kInterestView;
}
return ui.kAmortizationTable;
}
QWidget* SKGCalculatorPluginWidget::mainWidget()
{
if (ui.kWidgetSelector->getSelectedMode() == 0) {
return ui.kInterestView;
}
return ui.kAmortizationTable;
}
diff --git a/plugins/skrooge/skrooge_calculator/skgcalculatorpluginwidget.h b/plugins/skrooge/skrooge_calculator/skgcalculatorpluginwidget.h
index 499475eb8..0789c5c9c 100644
--- a/plugins/skrooge/skrooge_calculator/skgcalculatorpluginwidget.h
+++ b/plugins/skrooge/skrooge_calculator/skgcalculatorpluginwidget.h
@@ -1,128 +1,128 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGCALCULATORPLUGINWIDGET_H
#define SKGCALCULATORPLUGINWIDGET_H
/** @file
* A skrooge plugin to calculate
*
* @author Stephane MANKOWSKI
*/
#include "skgtabpage.h"
#include "ui_skgcalculatorpluginwidget_base.h"
#include <qtimer.h>
class SKGObjectModel;
/**
* A skrooge plugin to calculate
*/
class SKGCalculatorPluginWidget : public SKGTabPage
{
Q_OBJECT
public:
/**
* Default Constructor
* @param iParent the parent widget
* @param iDocument the document
*/
explicit SKGCalculatorPluginWidget(QWidget* iParent, SKGDocumentBank* iDocument);
/**
* Default Destructor
*/
~SKGCalculatorPluginWidget() override;
/**
* Get the current state
* MUST BE OVERWRITTEN
* @return a string containing all information needed to set the same state.
* Could be an XML stream
*/
QString getState() override;
/**
* Set the current state
* MUST BE OVERWRITTEN
* @param iState must be interpreted to set the state of the widget
*/
void setState(const QString& iState) override;
/**
* Get attribute name to save the default state
* MUST BE OVERWRITTEN
* @return attribute name to save the default state.
*/
QString getDefaultStateAttribute() override;
/**
* Get the current selection
* @return selected objects
*/
SKGObjectBase::SKGListSKGObjectBase getSelectedObjects() override;
/**
* Get the number of selected object
* @return number of selected objects
*/
int getNbSelectedObjects() override;
/**
* Get the zoomable widget.
* The default implementation returns the main widget.
* @return the zoomable widget.
*/
QWidget* zoomableWidget() override;
/**
* Get the main widget
* @return a widget
*/
QWidget* mainWidget() override;
protected:
/**
* Event filtering
* @param iObject object
* @param iEvent event
* @return In your reimplementation of this function, if you want to filter the event out, i.e. stop it being handled further, return true; otherwise return false.
*/
bool eventFilter(QObject* iObject, QEvent* iEvent) override;
private Q_SLOTS:
void dataModified(const QString& iTableName, int iIdTransaction);
void onBtnModeClicked(int mode);
void onAmortizationComputationDelayed();
void onAmortizationComputation();
// void onCalculatorReturnPressed(const QString& iText);
// void onCalculatorListClicked(const QString& iText);
void onSelectionChanged();
void onAdd();
void onUpdate();
void onFilterChanged();
void onSelectedInterestChanged();
private:
Q_DISABLE_COPY(SKGCalculatorPluginWidget)
void computeInterest();
Ui::skgcalculatorplugin_base ui{};
SKGObjectModel* m_objectModel;
QTimer m_timer;
};
#endif // SKGCALCULATORPLUGINWIDGET_H
diff --git a/plugins/skrooge/skrooge_categories/CMakeLists.txt b/plugins/skrooge/skrooge_categories/CMakeLists.txt
index fe25fc9f2..2ce39c810 100644
--- a/plugins/skrooge/skrooge_categories/CMakeLists.txt
+++ b/plugins/skrooge/skrooge_categories/CMakeLists.txt
@@ -1,40 +1,40 @@
#***************************************************************************
#* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
#* *
#* 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 <http://www.gnu.org/licenses/> *
+#* along with this program. If not, see <https://www.gnu.org/licenses/> *
#***************************************************************************
MESSAGE( STATUS "..:: CMAKE PLUGIN_CATEGORIES ::..")
PROJECT(plugin_categories)
LINK_DIRECTORIES (${LIBRARY_OUTPUT_PATH})
SET(skrooge_categories_SRCS
skgcategoriesplugin.cpp
skgcategoriespluginwidget.cpp)
ki18n_wrap_ui(skrooge_categories_SRCS skgcategoriespluginwidget_base.ui)
ADD_LIBRARY(skrooge_categories MODULE ${skrooge_categories_SRCS})
TARGET_LINK_LIBRARIES(skrooge_categories KF5::Parts skgbasemodeler KF5::ItemViews skgbasegui skgbankmodeler skgbankgui)
########### install files ###############
INSTALL(TARGETS skrooge_categories DESTINATION ${KDE_INSTALL_QTPLUGINDIR})
INSTALL(FILES ${PROJECT_SOURCE_DIR}/org.kde.skrooge-plugin-categories.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR})
INSTALL(FILES ${PROJECT_SOURCE_DIR}/skrooge_categories.rc DESTINATION ${KDE_INSTALL_KXMLGUI5DIR}/skrooge_categories )
INSTALL(DIRECTORY . DESTINATION ${KDE_INSTALL_DATADIR}/skrooge/categories/ FILES_MATCHING PATTERN "*.qif"
PATTERN ".svn" EXCLUDE
PATTERN "CMakeFiles" EXCLUDE
PATTERN "Testing" EXCLUDE)
diff --git a/plugins/skrooge/skrooge_categories/org.kde.skrooge-plugin-categories.desktop b/plugins/skrooge/skrooge_categories/org.kde.skrooge-plugin-categories.desktop
index 05008db3d..8528771e0 100644
--- a/plugins/skrooge/skrooge_categories/org.kde.skrooge-plugin-categories.desktop
+++ b/plugins/skrooge/skrooge_categories/org.kde.skrooge-plugin-categories.desktop
@@ -1,77 +1,77 @@
[Desktop Entry]
Name=Skrooge categories plugin
Name[bs]=Skrooge dodatak za kategorije
Name[ca]=Connector de categories de l'Skrooge
Name[ca@valencia]=Connector de categories de l'Skrooge
Name[cs]=Modul kategorií Skrooge
Name[da]=Kategori-plugin til Skrooge
Name[de]=Skrooge-Kategoriemodul
Name[el]=Skrooge categories plugin
Name[en_GB]=Skrooge categories plugin
Name[eo]=Skrooge kategoriaj kromaĵo
Name[es]=Complemento de categorías de Skrooge
Name[et]=Skrooge kategooriaplugin
Name[fi]=Skroogen luokkaliitännäinen
Name[fr]=Module externe Skrooge de catégorie
Name[gl]=Complemento de categorías de Skrooge
Name[hu]=Skrooge kategóriák bővítmény
Name[it]=Estensione per categorie di Skrooge
Name[lt]=Skrooge kategorijų papildinys
Name[ms]=Plugin kategori Skrooge
Name[nb]=Skrooge kategorimodul
Name[nds]=Kategorienmoduul för Skrooge
Name[nl]=Plugin voor Skrooge-categorieën
Name[pl]=Wtyczka kategorii dla Skrooge
Name[pt]='Plugin' de categorias do Skrooge
Name[pt_BR]=Plugin de categorias do Skrooge
Name[ru]=Модуль категорий
Name[sk]=Plugin kategórií Skrooge
Name[sv]=Skrooge kategori-insticksprogram
Name[tr]=Skrooge kategoriler eklentisi
Name[uk]=Додаток категорій Skrooge
Name[x-test]=xxSkrooge categories pluginxx
Name[zh_TW]=Skrooge 類別外掛程式
Comment=A skrooge plugin to manage categories
Comment[bs]=Skrooge dodatak za upravljanje kategorijama
Comment[ca]=Un connector de l'Skrooge per gestionar categories
Comment[ca@valencia]=Un connector de l'Skrooge per gestionar categories
Comment[cs]=Modul správy kategorií pro Skrooge
Comment[da]=Et Skrooge-plugin til at håndtere kategorier
Comment[de]=Ein Skrooge-Modul zum Verwalten von Kategorien
Comment[el]=Ένα πρόσθετο του skrooge για τη διαχείριση κατηγοριοποίησης
Comment[en_GB]=A skrooge plugin to manage categories
Comment[es]=Complemento de Skrooge para gestionar categorías
Comment[et]=Skrooge kategooriate haldamise plugin
Comment[fi]=Skroogen luokkienhallintaliitännäinen
Comment[fr]=Un module externe Skrooge pour la gestion des catégories
Comment[gl]=Un complemento de Skrooge para xestionar categorías.
Comment[hu]=Egy Skrooge bővítmény kategóriák kezeléséhez
Comment[it]=Un'estensione di Skrooge per gestire le categorie
Comment[lt]=Skrooge kategorijų tvarkymo papildinys
Comment[nb]=En Skrooge-modul for å håndtere kategorier
Comment[nl]=Een skrooge-plugin voor het beheren van categorieën
Comment[pl]=Wtyczka Skrooge do zarządzania kategoriami
Comment[pt]=Um 'plugin' do Skrooge para gerir as categorias
Comment[pt_BR]=Um plugin do Skrooge para gerenciar categorias
Comment[ru]=Модуль управления категориями
Comment[sk]=Plugin Skrooge na správu kategórií
Comment[sv]=Ett insticksprogram till Skrooge för att hantera budgetar
Comment[tr]=Kategori yönetimi için bir skrooge eklentisi
Comment[uk]=Додаток до skrooge для керування категоріями
Comment[x-test]=xxA skrooge plugin to manage categoriesxx
Comment[zh_TW]=管理類別用的 Skrooge 外掛程式
Encoding=UTF-8
Icon=skrooge
Type=Service
X-KDE-ServiceTypes=SKG GUI/Plugin
X-KDE-Library=skrooge_categories
X-Krunner-ID=Skrooge categories plugin
X-KDE-PluginInfo-Author=Stephane MANKOWSKI,miraks
X-KDE-PluginInfo-Email=stephane@mankowski.fr
X-KDE-PluginInfo-Name=skrooge_categories
X-KDE-PluginInfo-Version=1.0
-X-KDE-PluginInfo-Website=http://skrooge.org/
+X-KDE-PluginInfo-Website=https://skrooge.org/
X-KDE-PluginInfo-Category=Plugins
X-KDE-PluginInfo-Depends=
X-KDE-PluginInfo-License=GPL
X-KDE-PluginInfo-EnabledByDefault=true
diff --git a/plugins/skrooge/skrooge_categories/skgcategoriesplugin.cpp b/plugins/skrooge/skrooge_categories/skgcategoriesplugin.cpp
index 42c390aa3..c40bc0980 100644
--- a/plugins/skrooge/skrooge_categories/skgcategoriesplugin.cpp
+++ b/plugins/skrooge/skrooge_categories/skgcategoriesplugin.cpp
@@ -1,460 +1,460 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is Skrooge plugin to generate categories.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgcategoriesplugin.h"
#include <kaboutdata.h>
#include <kactioncollection.h>
#include <kpluginfactory.h>
#include <kselectaction.h>
#include <qaction.h>
#include <qdiriterator.h>
#include <qfileinfo.h>
#include <qstandardpaths.h>
#include "skgcategoriespluginwidget.h"
#include "skgcategoryobject.h"
#include "skgdocumentbank.h"
#include "skghtmlboardwidget.h"
#include "skgimportexportmanager.h"
#include "skgmainpanel.h"
#include "skgtraces.h"
#include "skgtransactionmng.h"
/**
* This plugin factory.
*/
K_PLUGIN_FACTORY(SKGCategoriesPluginFactory, registerPlugin<SKGCategoriesPlugin>();)
SKGCategoriesPlugin::SKGCategoriesPlugin(QWidget* iWidget, QObject* iParent, const QVariantList& /*iArg*/)
: SKGInterfacePlugin(iParent), m_currentBankDocument(nullptr)
{
Q_UNUSED(iWidget)
SKGTRACEINFUNC(10)
}
SKGCategoriesPlugin::~SKGCategoriesPlugin()
{
SKGTRACEINFUNC(10)
m_currentBankDocument = nullptr;
}
bool SKGCategoriesPlugin::setupActions(SKGDocument* iDocument)
{
SKGTRACEINFUNC(10)
m_currentBankDocument = qobject_cast<SKGDocumentBank*>(iDocument);
if (m_currentBankDocument == nullptr) {
return false;
}
setComponentName(QStringLiteral("skrooge_categories"), title());
setXMLFile(QStringLiteral("skrooge_categories.rc"));
// Import categories
QStringList overlaycategories;
overlaycategories.push_back(icon());
QStringList overlaydelete;
overlaydelete.push_back(QStringLiteral("edit-delete"));
auto contextMenu = new KSelectAction(SKGServices::fromTheme(QStringLiteral("document-import"), overlaycategories), i18nc("Verb", "Import categories"), this);
registerGlobalAction(QStringLiteral("import_categories"), contextMenu);
QAction* actImportStdCat = contextMenu->addAction(SKGServices::fromTheme(QStringLiteral("document-import"), overlaycategories), i18nc("Verb", "Import standard categories"));
actImportStdCat->setCheckable(false);
connect(actImportStdCat, &QAction::triggered, this, &SKGCategoriesPlugin::importStandardCategories);
registerGlobalAction(QStringLiteral("import_standard_categories"), actImportStdCat);
const auto dirs = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, "skrooge/categories/" % QLocale::countryToString(QLocale().country()), QStandardPaths::LocateDirectory);
for (const auto& dir : dirs) {
QDirIterator it(dir, QStringList() << QStringLiteral("*.qif"));
while (it.hasNext()) {
QString cat = it.next();
QString name = QFileInfo(cat).baseName().replace('_', ' ');
QAction* act = contextMenu->addAction(SKGServices::fromTheme(QStringLiteral("document-import"), overlaycategories), i18nc("Verb", "Import categories [%1]", name));
act->setCheckable(false);
act->setData(cat);
connect(act, &QAction::triggered, this, &SKGCategoriesPlugin::importCategories);
registerGlobalAction("import_categories_" % name, act);
}
}
auto deleteUnusedCategoriesAction = new QAction(SKGServices::fromTheme(icon(), overlaydelete), i18nc("Verb", "Delete unused categories"), this);
connect(deleteUnusedCategoriesAction, &QAction::triggered, this, &SKGCategoriesPlugin::deleteUnusedCategories);
registerGlobalAction(QStringLiteral("clean_delete_unused_categories"), deleteUnusedCategoriesAction);
// ------------
auto actTmp = new QAction(SKGServices::fromTheme(icon()), i18nc("Verb", "Open similar categories..."), this);
actTmp->setData(QString("skg://skrooge_categories_plugin/?title_icon=" % icon() % "&title=" % SKGServices::encodeForUrl(i18nc("Noun, a list of items", "Similar categories")) %
"&whereClause=" % SKGServices::encodeForUrl(QStringLiteral("id IN (SELECT category.id FROM category, ("
"SELECT * FROM category C WHERE EXISTS (SELECT 1 FROM category p2 WHERE p2.id<>C.id AND upper(p2.t_fullname)=upper(C.t_fullname) AND p2.t_fullname<>C.t_fullname)) "
"AS C WHERE category.t_fullname=C.t_fullname OR C.t_fullname LIKE category.t_fullname||' > %')"))));
connect(actTmp, &QAction::triggered, SKGMainPanel::getMainPanel(), [ = ]() {
SKGMainPanel::getMainPanel()->SKGMainPanel::openPage();
});
registerGlobalAction(QStringLiteral("view_open_similar_categories"), actTmp);
/*TODO
WITH RECURSIVE
cat(t_fullname,id, level) AS (
SELECT t_fullname, id, 0 FROM v_category_display WHERE EXISTS (SELECT 1 FROM category p2 WHERE p2.id<>v_category_display.id AND upper(p2.t_fullname)=upper(v_category_display.t_fullname) AND p2.t_fullname<>v_category_display.t_fullname)
UNION ALL
SELECT v_category_display.t_name, v_category_display.id, cat.level+1
FROM v_category_display JOIN cat ON v_category_display.rd_category_id=cat.id
ORDER BY 2
) SELECT substr('..........',1,level*3) || t_fullname FROM cat;
*/
return true;
}
int SKGCategoriesPlugin::getNbDashboardWidgets()
{
SKGTRACEINFUNC(1)
return 4;
}
QString SKGCategoriesPlugin::getDashboardWidgetTitle(int iIndex)
{
SKGTRACEINFUNC(1)
if (iIndex == 0) {
return i18nc("Report header", "5 main categories of expenditure");
}
if (iIndex == 1) {
return i18nc("Report header", "5 main variations");
}
if (iIndex == 2) {
return i18nc("Report header", "Budget");
}
return i18nc("Report header", "5 main variations (issues)");
}
SKGBoardWidget* SKGCategoriesPlugin::getDashboardWidget(int iIndex)
{
SKGTRACEINFUNC(1)
// Get QML mode for dashboard
KConfigSkeleton* skl = SKGMainPanel::getMainPanel()->getPluginByName(QStringLiteral("Dashboard plugin"))->getPreferenceSkeleton();
KConfigSkeletonItem* sklItem = skl->findItem(QStringLiteral("qmlmode"));
bool qml = sklItem->property().toBool();
if (iIndex == 0) {
return new SKGHtmlBoardWidget(SKGMainPanel::getMainPanel(), m_currentBankDocument,
getDashboardWidgetTitle(iIndex),
QStandardPaths::locate(QStandardPaths::GenericDataLocation, QStringLiteral("skrooge/html/default/categories_period_table.") % (qml ? QStringLiteral("qml") : QStringLiteral("html"))),
QStringList() << QStringLiteral("v_suboperation_consolidated"), SKGSimplePeriodEdit::ALL_PERIODS);
}
if (iIndex == 1) {
return new SKGHtmlBoardWidget(SKGMainPanel::getMainPanel(), m_currentBankDocument,
getDashboardWidgetTitle(iIndex) % " - %1",
QStandardPaths::locate(QStandardPaths::GenericDataLocation, QStringLiteral("skrooge/html/default/categories_variations.") % (qml ? QStringLiteral("qml") : QStringLiteral("html"))),
QStringList() << QStringLiteral("v_suboperation_consolidated"), SKGSimplePeriodEdit::PREVIOUS_AND_CURRENT_PERIODS);
}
if (iIndex == 2) {
return new SKGHtmlBoardWidget(SKGMainPanel::getMainPanel(), m_currentBankDocument,
getDashboardWidgetTitle(iIndex) % " - %1",
QStandardPaths::locate(QStandardPaths::GenericDataLocation, QStringLiteral("skrooge/html/default/budget_table.") % (qml ? QStringLiteral("qml") : QStringLiteral("html"))),
QStringList() << QStringLiteral("v_budget"), SKGSimplePeriodEdit::PREVIOUS_AND_CURRENT_MONTHS);
}
return new SKGHtmlBoardWidget(SKGMainPanel::getMainPanel(), m_currentBankDocument,
getDashboardWidgetTitle(iIndex) % " - %1",
QStandardPaths::locate(QStandardPaths::GenericDataLocation, QStringLiteral("skrooge/html/default/categories_variations_issues.") % (qml ? QStringLiteral("qml") : QStringLiteral("html"))),
QStringList() << QStringLiteral("v_suboperation_consolidated"), SKGSimplePeriodEdit::PREVIOUS_AND_CURRENT_PERIODS);
}
void SKGCategoriesPlugin::refresh()
{
SKGTRACEINFUNC(10)
if (m_currentBankDocument != nullptr) {
// Automatic categories creation
if (m_currentBankDocument->getMainDatabase() != nullptr) {
QString doc_id = m_currentBankDocument->getUniqueIdentifier();
if (m_docUniqueIdentifier != doc_id) {
m_docUniqueIdentifier = doc_id;
bool exist = false;
SKGError err = m_currentBankDocument->existObjects(QStringLiteral("category"), QString(), exist);
if (!err && !exist) {
importStandardCategories();
// The file is considered has not modified
m_currentBankDocument->setFileNotModified();
}
}
}
}
}
void SKGCategoriesPlugin::importCategories()
{
SKGTRACEINFUNC(10)
SKGError err;
auto* act = qobject_cast< QAction* >(sender());
if (act != nullptr) {
QString fileName = act->data().toString();
QString name = QFileInfo(fileName).baseName().replace('_', ' ');
{
SKGBEGINTRANSACTION(*m_currentBankDocument, i18nc("Verb", "Import categories [%1]", name), err)
SKGImportExportManager imp(m_currentBankDocument, QUrl(fileName));
err = imp.importFile();
IFOKDO(err, m_currentBankDocument->removeMessages(m_currentBankDocument->getCurrentTransaction()))
}
// status
IFOKDO(err, SKGError(0, i18nc("Successful message after an user action", "Categories imported.")))
else {
err.addError(ERR_FAIL, i18nc("Error message", "Importing categories failed."));
}
// Display error
SKGMainPanel::displayErrorMessage(err);
}
}
void SKGCategoriesPlugin::importStandardCategories()
{
SKGTRACEINFUNC(10)
SKGError err;
{
QString cats = i18nc("List of categories. It is not needed to translate each item. You can set the list you want. ';' must be used to separate categories. ' > ' must be used to separate category and sub category (no limit of level).",
"Alimony;Auto;Auto > Fuel;Auto > Insurance;Auto > Lease;Auto > Loan;Auto > Registration;Auto > Service;Bank Charges;Bank Charges > Interest Paid;Bank Charges > Service Charge;Bills;Bills > Electricity;"
"Bills > Fuel Oil;Bills > Local Taxes;Bills > Mortgage;Bills > Natural Gas;Bills > Rent;Bills > TV;Bills > Telephone;Bills > Water & Sewage;Bonus;Business;Business > Auto;Business > Capital Goods;Business > Legal Expenses;Business > Office Rent;"
"Business > Office Supplies;Business > Other;Business > Revenue;Business > Taxes;Business > Travel;Business > Utilities;Business > Wages & Salary;Car;Car > Fuel;Car > Insurance;Car > Lease;Car > Loan;Car > Registration;Car > Service;"
"Cash Withdrawal;Charity;Charity > Donations;Child Care;Child Support;Clothing;Disability;Div Income;Div Income > Ord dividend;Div Income > Stock dividend;Education;Education > Board;Education > Books;Education > Fees;Education > Loans;"
"Education > Tuition;Employment;Employment > Benefits;Employment > Foreign;Employment > Lump sums;Employment > Other employ;Employment > Salary & wages;Food;Food > Dining Out;Food > Groceries;Gardening;"
"Gift Received;Gifts;Healthcare;Healthcare > Dental;Healthcare > Doctor;Healthcare > Hospital;Healthcare > Optician;Healthcare > Prescriptions;Holidays;Holidays > Accomodation;Holidays > Travel;Household;"
"Household > Furnishings;Household > Repairs;Insurance;Insurance > Auto;Insurance > Disability;Insurance > Home and Contents;Insurance > Life;Insurance > Medical;Int Inc;Int Inc > Bank Interest;Int Inc > Gross;Int Inc > Net;"
"Int Inc > Other savings;Invest. income;Invest. income > 1st option;Invest. income > Dividend;Invest. income > Foreign;Invest. income > Other savings;Invest. income > Other trusts;Invest. income > Other trusts#Capital;"
"Invest. income > Other trusts#Dist. rec'd;Invest. income > Other trusts#Estate;Investment Income;Investment Income > Dividends;Investment Income > Interest;Investment Income > Long-Term Capital Gains;"
"Investment Income > Short-Term Capital Gains;Investment Income > Tax-Exempt Interest;Job Expense;Job Expense > Non-Reimbursed;Job Expense > Reimbursed;Legal Fees;Leisure;Leisure > Books & Magazines;Leisure > Entertaining;"
"Leisure > Films & Video Rentals;Leisure > Hobbies;Leisure > Sporting Events;Leisure > Sports Goods;Leisure > Tapes & CDs;Leisure > Theatre & Concerts etc;Leisure > Toys & Games;Loan;Loan > Loan Interest;Long-Term Capital gains;Mortgage;Mortgage > Interest;Mortgage > PMI;Mortgage > Principle;Motor;Motor > Fuel;Motor > Loan;Motor > Service;Other Expense;Other Expense > Unknown;Other Income;Other Income > Child Support;"
"Other Income > Employee Share Option;Other Income > Gifts Received;Other Income > Loan Principal Received;Other Income > Lottery or Premium Bond Prizes;Other Income > Student loan;Other Income > Tax Refund;"
"Other Income > Unemployment Benefit;Pension;Pension > Employer;Personal Care;Pet Care;Pet Care > Food;Pet Care > Supplies;Pet Care > Vet's Bills;Recreation;Retirement Accounts;Retirement Accounts > 401(k)403(b) Plan Contributions;"
"Retirement Accounts > 529 Plan Contributions;Retirement Accounts > IRA Contributions;Retirement Income;Retirement Income > 401(k);Retirement Income > 401(k) > 403(b) Distributions;Retirement Income > IRA Distributions;"
"Retirement Income > Pensions & Annuities;Retirement Income > State Pension Benefits;Short-Term Capital gains;Social Security Benefits;Taxes;Taxes > AMT;Taxes > Federal Tax;Taxes > Federal Taxes;Taxes > Local Tax;Taxes > Local Taxes;"
"Taxes > Other Invest;Taxes > Other Tax;Taxes > Property Taxes;Taxes > Social Security;Taxes > State Tax;Taxes > State Taxes;Travel;Travel > Accomodations;Travel > Car Rental;Travel > Fares;Utilities;Utilities > Electricity;"
"Utilities > Garbage & Recycling;Utilities > Gas;Utilities > Sewer;Utilities > Telephone;Utilities > Water;Wages & Salary;Wages & Salary > Benefits;Wages & Salary > Bonus;Wages & Salary > Commission;"
"Wages & Salary > Employer Pension Contributions;Wages & Salary > Gross Pay;Wages & Salary > Net Pay;Wages & Salary > Overtime;Wages & Salary > Workman's Comp");
SKGBEGINTRANSACTION(*m_currentBankDocument, i18nc("Noun, name of the user action", "Import standard categories"), err)
const auto items = SKGServices::splitCSVLine(cats, ';');
for (const auto& item : items) {
QString line = item.trimmed();
if (!line.isEmpty()) {
SKGCategoryObject cat;
err = SKGCategoryObject::createPathCategory(m_currentBankDocument, line, cat);
}
}
}
// status
IFOKDO(err, SKGError(0, i18nc("Successful message after an user action", "Categories imported.")))
else {
err.addError(ERR_FAIL, i18nc("Error message", "Importing categories failed."));
}
// Display error
SKGMainPanel::displayErrorMessage(err);
}
SKGTabPage* SKGCategoriesPlugin::getWidget()
{
SKGTRACEINFUNC(10)
return new SKGCategoriesPluginWidget(SKGMainPanel::getMainPanel(), m_currentBankDocument);
}
QString SKGCategoriesPlugin::title() const
{
return i18nc("Noun, categories of items", "Categories");
}
QString SKGCategoriesPlugin::icon() const
{
return QStringLiteral("view-categories");
}
QString SKGCategoriesPlugin::toolTip() const
{
return i18nc("A tool tip", "Categories management");
}
QStringList SKGCategoriesPlugin::tips() const
{
QStringList output;
output.push_back(i18nc("Description of a tips", "<p>... <a href=\"skg://skrooge_categories_plugin\">categories</a> can be reorganized by drag & drop.</p>"));
output.push_back(i18nc("Description of a tips", "<p>... if you delete a <a href=\"skg://skrooge_categories_plugin\">category</a>, all operations affected by this category will be associated to its parent category.</p>"));
return output;
}
int SKGCategoriesPlugin::getOrder() const
{
return 30;
}
bool SKGCategoriesPlugin::isInPagesChooser() const
{
return true;
}
SKGAdviceList SKGCategoriesPlugin::advice(const QStringList& iIgnoredAdvice)
{
SKGTRACEINFUNC(10)
SKGAdviceList output;
// Check unused categories
if (!iIgnoredAdvice.contains(QStringLiteral("skgcategoriesplugin_unused"))) {
bool exist = false;
m_currentBankDocument->existObjects(QStringLiteral("v_category_used2"), QStringLiteral("t_ISUSEDCASCADE='N'"), exist);
if (exist) {
SKGAdvice ad;
ad.setUUID(QStringLiteral("skgcategoriesplugin_unused"));
ad.setPriority(5);
ad.setShortMessage(i18nc("Advice on making the best (short)", "Many unused categories"));
ad.setLongMessage(i18nc("Advice on making the best (long)", "You can improve performances by removing categories that have no operations."));
SKGAdvice::SKGAdviceActionList autoCorrections;
{
SKGAdvice::SKGAdviceAction a;
a.Title = QStringLiteral("skg://clean_delete_unused_categories");
a.IsRecommended = true;
autoCorrections.push_back(a);
}
ad.setAutoCorrections(autoCorrections);
output.push_back(ad);
}
}
// Check operations not validated
if (!iIgnoredAdvice.contains(QStringLiteral("skgmonthlyplugin_maincategoriesvariation"))) {
QString month = QDate::currentDate().toString(QStringLiteral("yyyy-MM"));
QDate datepreviousmonth = QDate::currentDate().addDays(-QDate::currentDate().day());
QString previousmonth = datepreviousmonth.toString(QStringLiteral("yyyy-MM"));
QStringList listCategories;
QStringList listVariations = m_currentBankDocument->get5MainCategoriesVariationList(month, previousmonth, true, &listCategories);
int nb = listVariations.count();
SKGAdvice::SKGAdviceActionList autoCorrections;
for (int i = 0; i < nb; ++i) {
SKGAdvice ad;
ad.setUUID("skgmonthlyplugin_maincategoriesvariation|" % listCategories.at(i));
ad.setPriority(7);
ad.setShortMessage(i18nc("Advice on making the best (short)", "Important variation for '%1'", listCategories.at(i)));
ad.setLongMessage(listVariations.at(i));
autoCorrections.resize(0);
{
SKGAdvice::SKGAdviceAction a;
a.Title = i18nc("Advice on making the best (action)", "Open sub operations with category containing '%1'", listCategories.at(i));
a.IconName = QStringLiteral("quickopen");
a.IsRecommended = false;
autoCorrections.push_back(a);
}
ad.setAutoCorrections(autoCorrections);
output.push_back(ad);
}
}
// Check categories with different case
if (!iIgnoredAdvice.contains(QStringLiteral("skgcategoriesplugin_case"))) {
bool exist = false;
m_currentBankDocument->existObjects(QStringLiteral("category"), QStringLiteral("EXISTS (SELECT 1 FROM category p2 WHERE p2.id<>category.id AND upper(p2.t_fullname)=upper(category.t_fullname) AND p2.t_fullname<>category.t_fullname)"), exist);
if (exist) {
SKGAdvice ad;
ad.setUUID(QStringLiteral("skgcategoriesplugin_case"));
ad.setPriority(3);
ad.setShortMessage(i18nc("Advice on making the best (short)", "Some categories seem to be identical"));
ad.setLongMessage(i18nc("Advice on making the best (long)", "Some categories seem to be identical but with different syntax. They could be merged."));
SKGAdvice::SKGAdviceActionList autoCorrections;
{
SKGAdvice::SKGAdviceAction a;
a.Title = QStringLiteral("skg://view_open_similar_categories");
a.IsRecommended = false;
autoCorrections.push_back(a);
}
ad.setAutoCorrections(autoCorrections);
output.push_back(ad);
}
}
return output;
}
SKGError SKGCategoriesPlugin::executeAdviceCorrection(const QString& iAdviceIdentifier, int iSolution)
{
if ((m_currentBankDocument != nullptr) && iAdviceIdentifier.startsWith(QLatin1String("skgmonthlyplugin_maincategoriesvariation|"))) {
// Get parameters
QString category = iAdviceIdentifier.right(iAdviceIdentifier.length() - 41);
QString month = QDate::currentDate().toString(QStringLiteral("yyyy-MM"));
// Call operation plugin
SKGMainPanel::getMainPanel()->openPage("skg://skrooge_operation_plugin/SKGOPERATION_CONSOLIDATED_DEFAULT_PARAMETERS/?currentPage=-1&title_icon=" % icon() % "&operationTable=v_suboperation_consolidated&title=" %
SKGServices::encodeForUrl(i18nc("Noun, a list of items", "Sub operations with category containing '%1'", category)) % "&operationWhereClause=" % SKGServices::encodeForUrl("d_DATEMONTH='" % month % "' AND t_REALCATEGORY='" % SKGServices::stringToSqlString(category) % '\''));
return SKGError();
}
return SKGInterfacePlugin::executeAdviceCorrection(iAdviceIdentifier, iSolution);
}
void SKGCategoriesPlugin::deleteUnusedCategories() const
{
SKGError err;
_SKGTRACEINFUNCRC(10, err)
if (m_currentBankDocument != nullptr) {
SKGBEGINTRANSACTION(*m_currentBankDocument, i18nc("Noun, name of the user action", "Delete unused categories"), err)
QStringList categoriesUsed;
err = m_currentBankDocument->getDistinctValues(QStringLiteral("category"), QStringLiteral("t_fullname"), QStringLiteral("t_fullname in ("
"SELECT DISTINCT(category.t_fullname) FROM category, suboperation WHERE suboperation.r_category_id=category.id UNION ALL "
"SELECT DISTINCT(category.t_fullname) FROM category, budget WHERE budget.rc_category_id=category.id UNION ALL "
"SELECT DISTINCT(category.t_fullname) FROM category, budgetrule WHERE budgetrule.rc_category_id=category.id UNION ALL "
"SELECT DISTINCT(category.t_fullname) FROM category, budgetrule WHERE budgetrule.rc_category_id_target=category.id)"), categoriesUsed);
for (int i = 0; i < categoriesUsed.count(); ++i) { // Warning categoriesUsed is modified in the loop
QString cat = categoriesUsed.at(i);
categoriesUsed[i] = SKGServices::stringToSqlString(cat);
int pos = cat.lastIndexOf(OBJECTSEPARATOR);
if (pos != -1) {
categoriesUsed.push_back(cat.left(pos));
}
}
IFOK(err) {
QString sql;
if (!categoriesUsed.isEmpty()) {
sql = "DELETE FROM category WHERE t_fullname NOT IN ('" % categoriesUsed.join(QStringLiteral("','")) % "')";
} else {
sql = QStringLiteral("DELETE FROM category");
}
err = m_currentBankDocument->executeSqliteOrder(sql);
}
}
// status bar
IFOKDO(err, SKGError(0, i18nc("Successful message after an user action", "Unused categories deleted")))
else {
err.addError(ERR_FAIL, i18nc("Error message", "Unused categories deletion failed"));
}
// Display error
SKGMainPanel::displayErrorMessage(err);
}
#include <skgcategoriesplugin.moc>
diff --git a/plugins/skrooge/skrooge_categories/skgcategoriesplugin.h b/plugins/skrooge/skrooge_categories/skgcategoriesplugin.h
index c1f398d77..e2e669a38 100644
--- a/plugins/skrooge/skrooge_categories/skgcategoriesplugin.h
+++ b/plugins/skrooge/skrooge_categories/skgcategoriesplugin.h
@@ -1,149 +1,149 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGCATEGORIESPLUGIN_H
#define SKGCATEGORIESPLUGIN_H
/** @file
* This file is Skrooge plugin to generate categories.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skginterfaceplugin.h"
class QAction;
class SKGDocumentBank;
/**
* This file is Skrooge plugin to generate categories
*/
class SKGCategoriesPlugin : public SKGInterfacePlugin
{
Q_OBJECT
Q_INTERFACES(SKGInterfacePlugin)
public:
/**
* Default Constructor
*/
explicit SKGCategoriesPlugin(QWidget* iWidget, QObject* iParent, const QVariantList& iArg);
/**
* Default Destructor
*/
~SKGCategoriesPlugin() override;
/**
* Called to initialise the plugin
* @param iDocument the main document
* @return true if the plugin is compatible with the document
*/
bool setupActions(SKGDocument* iDocument) override;
/**
* The number of dashboard widgets of the plugin.
* @return The number of dashboard widgets of the plugin
*/
int getNbDashboardWidgets() override;
/**
* Get a dashboard widget title of the plugin.
* @param iIndex the index of the widget
* @return The title
*/
QString getDashboardWidgetTitle(int iIndex) override;
/**
* Get a dashboard widget of the plugin.
* @param iIndex the index of the widget
* @return The dashboard widget of the plugin
*/
SKGBoardWidget* getDashboardWidget(int iIndex) override;
/**
* Must be modified to refresh widgets after a modification.
*/
void refresh() override;
/**
* The page widget of the plugin.
* @return The page widget of the plugin
*/
SKGTabPage* getWidget() override;
/**
* The title of the plugin.
* @return The title of the plugin
*/
QString title() const override;
/**
* The icon of the plugin.
* @return The icon of the plugin
*/
QString icon() const override;
/**
* The toolTip of the plugin.
* @return The toolTip of the plugin
*/
QString toolTip() const override;
/**
* The tips list of the plugin.
* @return The tips list of the plugin
*/
QStringList tips() const override;
/**
* Must be implemented to set the position of the plugin.
* @return integer value between 0 and 999 (default = 999)
*/
int getOrder() const override;
/**
* Must be implemented to know if a plugin must be display in pages chooser.
* @return true of false (default = false)
*/
bool isInPagesChooser() const override;
/**
* The advice list of the plugin.
* @return The advice list of the plugin
*/
SKGAdviceList advice(const QStringList& iIgnoredAdvice) override;
/**
* Must be implemented to execute the automatic correction for the advice.
* @param iAdviceIdentifier the identifier of the advice
* @param iSolution the identifier of the possible solution
* @return an object managing the error. MUST return ERR_NOTIMPL if iAdviceIdentifier is not known
* @see SKGError
*/
SKGError executeAdviceCorrection(const QString& iAdviceIdentifier, int iSolution) override;
private Q_SLOTS:
void importCategories();
void importStandardCategories();
void deleteUnusedCategories() const;
private:
Q_DISABLE_COPY(SKGCategoriesPlugin)
SKGDocumentBank* m_currentBankDocument;
QString m_docUniqueIdentifier;
};
#endif // SKGCATEGORIESPLUGIN_H
diff --git a/plugins/skrooge/skrooge_categories/skgcategoriespluginwidget.cpp b/plugins/skrooge/skrooge_categories/skgcategoriespluginwidget.cpp
index bccebab82..4671a9cdc 100644
--- a/plugins/skrooge/skrooge_categories/skgcategoriespluginwidget.cpp
+++ b/plugins/skrooge/skrooge_categories/skgcategoriespluginwidget.cpp
@@ -1,356 +1,356 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is Skrooge plugin to generate categories.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgcategoriespluginwidget.h"
#include <klocalizedstring.h>
#include <qaction.h>
#include <qdom.h>
#include <qevent.h>
#include <qgraphicsscene.h>
#include <qheaderview.h>
#include <qwidget.h>
#include "skgcategoryobject.h"
#include "skgdocumentbank.h"
#include "skgmainpanel.h"
#include "skgobjectmodel.h"
#include "skgsortfilterproxymodel.h"
#include "skgtraces.h"
#include "skgtransactionmng.h"
SKGCategoriesPluginWidget::SKGCategoriesPluginWidget(QWidget* iParent, SKGDocumentBank* iDocument)
: SKGTabPage(iParent, iDocument)
{
SKGTRACEINFUNC(10)
if (iDocument == nullptr) {
return;
}
ui.setupUi(this);
// Define action
QStringList overlaycategories;
overlaycategories.push_back(QStringLiteral("view-categories"));
if (SKGMainPanel::getMainPanel() != nullptr) {
auto addCategoryAction = new QAction(SKGServices::fromTheme(QStringLiteral("list-add"), overlaycategories), i18nc("Verb", "Add category"), this);
connect(addCategoryAction, &QAction::triggered, this, &SKGCategoriesPluginWidget::onAddCategory);
SKGMainPanel::getMainPanel()->registerGlobalAction(QStringLiteral("edit_add_category"), addCategoryAction, true, QStringList() << QStringLiteral("category"), 1, -1, 450);
}
// Set show widget
ui.kCategoriesView->getShowWidget()->addGroupedItem(QStringLiteral("all"), i18n("All"), QLatin1String(""), QLatin1String(""), QLatin1String(""), Qt::META + Qt::Key_A);
ui.kCategoriesView->getShowWidget()->addGroupedItem(QStringLiteral("opened"), i18n("Opened"), QStringLiteral("vcs-normal"), QStringLiteral("t_close='N'"), QLatin1String(""), Qt::META + Qt::Key_O);
ui.kCategoriesView->getShowWidget()->addGroupedItem(QStringLiteral("closed"), i18n("Closed"), QStringLiteral("vcs-conflicting"), QStringLiteral("t_close='Y'"), QLatin1String(""), Qt::META + Qt::Key_C);
ui.kCategoriesView->getShowWidget()->addGroupedItem(QStringLiteral("income"), i18n("Income"), QStringLiteral("list-add"), QStringLiteral("f_REALCURRENTAMOUNT>=0"), QLatin1String(""), Qt::META + Qt::Key_Plus);
ui.kCategoriesView->getShowWidget()->addGroupedItem(QStringLiteral("expenditure"), i18n("Expenditure"), QStringLiteral("list-remove"), QStringLiteral("f_REALCURRENTAMOUNT<=0"), QLatin1String(""), Qt::META + Qt::Key_Minus);
ui.kCategoriesView->getShowWidget()->addGroupedItem(QStringLiteral("highlighted"), i18n("Highlighted"), QStringLiteral("bookmarks"), QStringLiteral("t_HASBOOKMARKEDCHILD<>'N'"), QLatin1String(""), Qt::META + Qt::Key_H);
ui.kCategoriesView->getShowWidget()->setDefaultState(QStringLiteral("all"));
ui.kAdd->setIcon(SKGServices::fromTheme(QStringLiteral("list-add"), overlaycategories));
ui.kAdd->setToolTip(i18nc("An help", "Add a sub category to the selected one"));
ui.kAdd->setMaximumWidth(ui.kAdd->height());
ui.kNameLbl->setText(i18n("%1:", iDocument->getDisplay(QStringLiteral("t_name"))));
ui.kModifyCategoryButton->setIcon(SKGServices::fromTheme(QStringLiteral("dialog-ok")));
ui.kDeleteUnusedButton->setIcon(SKGServices::fromTheme(QStringLiteral("edit-delete")));
ui.kCategoriesView->setModel(new SKGObjectModel(qobject_cast<SKGDocumentBank*>(getDocument()), QStringLiteral("v_category_display"), QStringLiteral("1=0"), this, QStringLiteral("rd_category_id"), false));
ui.kCategoriesView->getView()->setRootIsDecorated(true);
ui.kCategoriesView->getView()->setAnimated(false); // Not compatible with double click
ui.kCategoriesView->getView()->resizeColumnToContents(0);
ui.kCategoriesView->getView()->header()->setStretchLastSection(false);
connect(getDocument(), &SKGDocument::tableModified, this, &SKGCategoriesPluginWidget::dataModified, Qt::QueuedConnection);
connect(ui.kCategoriesView->getView(), &SKGTreeView::clickEmptyArea, this, &SKGCategoriesPluginWidget::cleanEditor);
connect(ui.kCategoriesView->getView(), &SKGTreeView::doubleClicked, SKGMainPanel::getMainPanel()->getGlobalAction(QStringLiteral("open")).data(), &QAction::trigger);
connect(ui.kCategoriesView->getView(), &SKGTreeView::selectionChangedDelayed, this, [ = ] {this->onSelectionChanged();});
connect(ui.kModifyCategoryButton, &QPushButton::clicked, this, &SKGCategoriesPluginWidget::onUpdateCategory);
connect(ui.kNameInput1, &QLineEdit::textChanged, this, &SKGCategoriesPluginWidget::onEditorModified);
connect(ui.kDeleteUnusedButton, &QPushButton::clicked, this, &SKGCategoriesPluginWidget::onDeleteUnused);
connect(ui.kAdd, &QPushButton::clicked, this, &SKGCategoriesPluginWidget::onAddCategory);
// Set Event filters to catch CTRL+ENTER or SHIFT+ENTER
this->installEventFilter(this);
dataModified(QLatin1String(""), 0);
}
SKGCategoriesPluginWidget::~SKGCategoriesPluginWidget()
{
SKGTRACEINFUNC(10)
}
bool SKGCategoriesPluginWidget::eventFilter(QObject* iObject, QEvent* iEvent)
{
if ((iEvent != nullptr) && iEvent->type() == QEvent::KeyPress) {
auto* keyEvent = dynamic_cast<QKeyEvent*>(iEvent);
if (keyEvent && (keyEvent->key() == Qt::Key_Return || keyEvent->key() == Qt::Key_Enter) && iObject == this) {
if ((QApplication::keyboardModifiers() & Qt::ControlModifier) != 0u && ui.kAdd->isEnabled()) {
ui.kAdd->click();
} else if ((QApplication::keyboardModifiers() &Qt::ShiftModifier) != 0u && ui.kModifyCategoryButton->isEnabled()) {
ui.kModifyCategoryButton->click();
}
}
}
return SKGTabPage::eventFilter(iObject, iEvent);
}
void SKGCategoriesPluginWidget::dataModified(const QString& iTableName, int iIdTransaction, bool iLightTransaction)
{
SKGTRACEINFUNC(10)
Q_UNUSED(iIdTransaction)
if (!iLightTransaction) {
if (iTableName == QStringLiteral("category") || iTableName.isEmpty()) {
// Set completions
SKGMainPanel::fillWithDistinctValue(QList<QWidget*>() << ui.kNameInput1, getDocument(), QStringLiteral("category"), QStringLiteral("t_name"), QLatin1String(""), true);
onSelectionChanged();
}
}
}
void SKGCategoriesPluginWidget::onSelectionChanged()
{
SKGTRACEINFUNC(10)
// Clean widgets
int nb = ui.kLayout->count();
for (int i = 0; i < nb; ++i) {
QLayoutItem* item = ui.kLayout->itemAt(0);
if (item != nullptr) {
ui.kLayout->removeItem(item);
delete item->widget();
delete item;
}
}
int nbSelect = getNbSelectedObjects();
if (nbSelect == 1) {
SKGCategoryObject obj(getFirstSelectedObject());
ui.kNameInput1->setText(obj.getName());
SKGCategoryObject parentCat;
obj.getParentCategory(parentCat);
QString parentName = parentCat.getFullName();
QStringList items = SKGServices::splitCSVLine(parentName, QString(OBJECTSEPARATOR).trimmed().at(0));
int nbItems = items.count();
QString fullname;
for (int i = 0; i < nbItems; ++i) {
auto btn = new QPushButton(ui.kFrame);
btn->setFlat(true);
btn->setText(items.at(i).trimmed());
if (!fullname.isEmpty()) {
fullname += OBJECTSEPARATOR;
}
fullname += items.at(i).trimmed();
btn->setProperty("FULLNAME", fullname);
connect(btn, &QPushButton::clicked, this, &SKGCategoriesPluginWidget::changeSelection);
ui.kLayout->addWidget(btn);
auto lbl = new QLabel(ui.kFrame);
lbl->setText(OBJECTSEPARATOR);
ui.kLayout->addWidget(lbl);
}
} else if (nbSelect > 1) {
ui.kNameInput1->setText(NOUPDATE);
}
onEditorModified();
Q_EMIT selectionChanged();
}
void SKGCategoriesPluginWidget::changeSelection()
{
QString fullname = sender()->property("FULLNAME").toString();
SKGObjectBase::SKGListSKGObjectBase list;
getDocument()->getObjects(QStringLiteral("v_category"), "t_fullname='" % SKGServices::stringToSqlString(fullname) % '\'', list);
if (!list.isEmpty()) {
ui.kCategoriesView->getView()->selectObject(list.at(0).getUniqueID());
onSelectionChanged();
}
}
QString SKGCategoriesPluginWidget::getState()
{
SKGTRACEINFUNC(10)
QDomDocument doc(QStringLiteral("SKGML"));
QDomElement root = doc.createElement(QStringLiteral("parameters"));
doc.appendChild(root);
// Memorize table settings
root.setAttribute(QStringLiteral("view"), ui.kCategoriesView->getState());
return doc.toString();
}
void SKGCategoriesPluginWidget::setState(const QString& iState)
{
SKGTRACEINFUNC(10)
QDomDocument doc(QStringLiteral("SKGML"));
doc.setContent(iState);
QDomElement root = doc.documentElement();
ui.kCategoriesView->setFilter(SKGServices::fromTheme(root.attribute(QStringLiteral("title_icon"))), root.attribute(QStringLiteral("title")), root.attribute(QStringLiteral("whereClause")));
ui.kCategoriesView->setState(root.attribute(QStringLiteral("view")));
}
QString SKGCategoriesPluginWidget::getDefaultStateAttribute()
{
return QStringLiteral("SKGCATEGORIES_DEFAULT_PARAMETERS");
}
QWidget* SKGCategoriesPluginWidget::mainWidget()
{
return ui.kCategoriesView->getView();
}
void SKGCategoriesPluginWidget::onEditorModified()
{
_SKGTRACEINFUNC(10)
int nb = getNbSelectedObjects();
ui.kModifyCategoryButton->setEnabled(!ui.kNameInput1->text().isEmpty() && nb >= 1);
}
void SKGCategoriesPluginWidget::onAddCategory()
{
SKGError err;
_SKGTRACEINFUNCRC(10, err)
SKGCategoryObject cat;
QString name = ui.kNameInput1->text();
if (name.isEmpty()) {
name = i18nc("Noun, default name for a new category", "New category");
}
{
// Get Selection
SKGObjectBase::SKGListSKGObjectBase selection = getSelectedObjects();
int nb = selection.count();
SKGBEGINTRANSACTION(*getDocument(), i18nc("Noun, name of the user action", "Category creation '%1'", name), err)
if (nb == 1) {
SKGCategoryObject parentCat(selection[0]);
name = parentCat.getFullName() % OBJECTSEPARATOR % name;
}
IFOKDO(err, SKGCategoryObject::createPathCategory(qobject_cast<SKGDocumentBank*>(getDocument()), name, cat, false, true))
// Send message
IFOKDO(err, cat.getDocument()->sendMessage(i18nc("An information message", "The category '%1' has been created", cat.getDisplayName()), SKGDocument::Hidden))
}
// status bar
IFOK(err) {
ui.kCategoriesView->getView()->selectObject(cat.getUniqueID());
err = SKGError(0, i18nc("Successful message after an user action", "Category '%1' created", name));
} else {
err.addError(ERR_FAIL, i18nc("Error message", "Category creation failed"));
}
// Display error
SKGMainPanel::displayErrorMessage(err, true);
}
void SKGCategoriesPluginWidget::onUpdateCategory()
{
SKGError err;
_SKGTRACEINFUNCRC(10, err)
// Get Selection
SKGObjectBase::SKGListSKGObjectBase selection = getSelectedObjects();
int nb = selection.count();
{
QString name = ui.kNameInput1->text();
SKGBEGINPROGRESSTRANSACTION(*getDocument(), i18nc("Noun, name of the user action", "Category update"), err, nb)
if (nb > 1 && name != NOUPDATE && !name.startsWith(QLatin1String("="))) {
getDocument()->sendMessage(i18nc("Information message", "You tried to modify all names of selected categories. Categories have been merged."));
// Do the merge
SKGCategoryObject catObj1(selection[0]);
for (int i = 1; !err && i < nb; ++i) {
SKGCategoryObject catObj(selection.at(i));
// Send message
IFOKDO(err, catObj.getDocument()->sendMessage(i18nc("An information message", "The category '%1' has been merged with category '%2'", catObj1.getDisplayName(), catObj.getDisplayName()), SKGDocument::Hidden))
IFOKDO(err, catObj1.merge(catObj))
IFOKDO(err, getDocument()->stepForward(i))
}
// Change selection for the rest of the operation
selection.clear();
selection.push_back(catObj1);
nb = 1;
}
for (int i = 0; !err && i < nb; ++i) {
// Modification of object
SKGCategoryObject cat(selection.at(i));
err = cat.setName(name);
IFOKDO(err, cat.save())
// Send message
IFOKDO(err, cat.getDocument()->sendMessage(i18nc("An information message", "The category '%1' has been updated", cat.getDisplayName()), SKGDocument::Hidden))
}
}
// status bar
IFOKDO(err, SKGError(0, i18nc("Successful message after an user action", "Category updated")))
else {
err.addError(ERR_FAIL, i18nc("Error message", "Category update failed"));
}
// Display error
SKGMainPanel::displayErrorMessage(err, true);
// Set focus on table
ui.kCategoriesView->getView()->setFocus();
}
void SKGCategoriesPluginWidget::onDeleteUnused()
{
QAction* act = SKGMainPanel::getMainPanel()->getGlobalAction(QStringLiteral("clean_delete_unused_categories"));
if (act != nullptr) {
act->trigger();
}
}
void SKGCategoriesPluginWidget::cleanEditor()
{
if (getNbSelectedObjects() == 0) {
ui.kNameInput1->setText(QLatin1String(""));
}
}
void SKGCategoriesPluginWidget::activateEditor()
{
ui.kNameInput1->setFocus();
}
bool SKGCategoriesPluginWidget::isEditor()
{
return true;
}
diff --git a/plugins/skrooge/skrooge_categories/skgcategoriespluginwidget.h b/plugins/skrooge/skrooge_categories/skgcategoriespluginwidget.h
index b1063d709..6ca10a465 100644
--- a/plugins/skrooge/skrooge_categories/skgcategoriespluginwidget.h
+++ b/plugins/skrooge/skrooge_categories/skgcategoriespluginwidget.h
@@ -1,114 +1,114 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGCATEGORIESPLUGINWIDGET_H
#define SKGCATEGORIESPLUGINWIDGET_H
/** @file
* This file is Skrooge plugin for bank management.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgtabpage.h"
#include "ui_skgcategoriespluginwidget_base.h"
#include <qstringlist.h>
class SKGDocumentBank;
/**
* This file is Skrooge plugin to generate categories
*/
class SKGCategoriesPluginWidget : public SKGTabPage
{
Q_OBJECT
public:
/**
* Default Constructor
* @param iParent the parent widget
* @param iDocument the document
*/
explicit SKGCategoriesPluginWidget(QWidget* iParent, SKGDocumentBank* iDocument);
/**
* Default Destructor
*/
~SKGCategoriesPluginWidget() override;
/**
* Get the current state
* MUST BE OVERWRITTEN
* @return a string containing all information needed to set the same state.
* Could be an XML stream
*/
QString getState() override;
/**
* Set the current state
* MUST BE OVERWRITTEN
* @param iState must be interpreted to set the state of the widget
*/
void setState(const QString& iState) override;
/**
* Get attribute name to save the default state
* MUST BE OVERWRITTEN
* @return attribute name to save the default state.
*/
QString getDefaultStateAttribute() override;
/**
* Get the main widget
* @return a widget
*/
QWidget* mainWidget() override;
/**
* To know if this page contains an editor. MUST BE OVERWRITTEN
* @return the editor state
*/
bool isEditor() override;
/**
* To activate the editor by setting focus on right widget. MUST BE OVERWRITTEN
*/
void activateEditor() override;
protected:
/**
* Event filtering
* @param iObject object
* @param iEvent event
* @return In your reimplementation of this function, if you want to filter the event out, i.e. stop it being handled further, return true; otherwise return false.
*/
bool eventFilter(QObject* iObject, QEvent* iEvent) override;
private Q_SLOTS:
void dataModified(const QString& iTableName, int iIdTransaction, bool iLightTransaction = false);
void onSelectionChanged();
void onEditorModified();
void onAddCategory();
void onUpdateCategory();
void onDeleteUnused();
void cleanEditor();
void changeSelection();
private:
Q_DISABLE_COPY(SKGCategoriesPluginWidget)
Ui::skgcategoriesplugin_base ui{};
};
#endif // SKGCATEGORIESPLUGINWIDGET_H
diff --git a/plugins/skrooge/skrooge_importexport/CMakeLists.txt b/plugins/skrooge/skrooge_importexport/CMakeLists.txt
index b0dd82f93..0ae16cac1 100644
--- a/plugins/skrooge/skrooge_importexport/CMakeLists.txt
+++ b/plugins/skrooge/skrooge_importexport/CMakeLists.txt
@@ -1,40 +1,40 @@
#***************************************************************************
#* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
#* *
#* 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 <http://www.gnu.org/licenses/> *
+#* along with this program. If not, see <https://www.gnu.org/licenses/> *
#***************************************************************************
MESSAGE( STATUS "..:: CMAKE PLUGIN_IMPORTEXPORT ::..")
PROJECT(plugin_importexport)
FIND_PACKAGE(KF5 5.0.0 REQUIRED COMPONENTS
GuiAddons # Tier 1
)
LINK_DIRECTORIES (${LIBRARY_OUTPUT_PATH})
SET(skrooge_importexport_SRCS
skgimportexportplugin.cpp)
ki18n_wrap_ui(skrooge_importexport_SRCS skgimportexportpluginwidget_pref.ui)
kconfig_add_kcfg_files(skrooge_importexport_SRCS skgimportexport_settings.kcfgc )
ADD_LIBRARY(skrooge_importexport MODULE ${skrooge_importexport_SRCS})
TARGET_LINK_LIBRARIES(skrooge_importexport KF5::Parts KF5::KIOCore KF5::KIOFileWidgets KF5::KIOWidgets KF5::KIONTLM skgbasemodeler skgbasegui skgbankmodeler)
########### install files ###############
INSTALL(TARGETS skrooge_importexport DESTINATION ${KDE_INSTALL_QTPLUGINDIR})
INSTALL(FILES ${PROJECT_SOURCE_DIR}/org.kde.skrooge-plugin-importexport.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR})
INSTALL(FILES ${PROJECT_SOURCE_DIR}/skrooge_importexport.rc DESTINATION ${KDE_INSTALL_KXMLGUI5DIR}/skrooge_importexport )
INSTALL(FILES ${PROJECT_SOURCE_DIR}/skgimportexport_settings.kcfg DESTINATION ${KDE_INSTALL_KCFGDIR} )
diff --git a/plugins/skrooge/skrooge_importexport/org.kde.skrooge-plugin-importexport.desktop b/plugins/skrooge/skrooge_importexport/org.kde.skrooge-plugin-importexport.desktop
index 62461552e..8375255f9 100644
--- a/plugins/skrooge/skrooge_importexport/org.kde.skrooge-plugin-importexport.desktop
+++ b/plugins/skrooge/skrooge_importexport/org.kde.skrooge-plugin-importexport.desktop
@@ -1,76 +1,76 @@
[Desktop Entry]
Name=Skrooge import and export plugin
Name[bs]=Skrooge dodatak za uvoz i izvoz
Name[ca]=Connector d'importació i exportació de l'Skrooge
Name[ca@valencia]=Connector d'importació i exportació de l'Skrooge
Name[cs]=Modul importu a exportu pro Skrooge
Name[da]=Eksport- og import-plugin til Skrooge
Name[de]=Skrooge-Import/Exportmodul
Name[el]=Skrooge import and export plugin
Name[en_GB]=Skrooge import and export plugin
Name[es]=Complemento de importación y exportación de Skrooge
Name[et]=Skrooge impordi- ja ekspordiplugin
Name[fi]=Skroogen tuonti- ja vientiliitännäinen
Name[fr]=Module externe Skrooge d'importation et d'exportation
Name[gl]=Complemento de importación e exportación de Skrooge
Name[hu]=Skrooge importálás és exportálás bővítmény
Name[it]=Estensione di importazione ed esportazione per Skrooge
Name[lt]=Skrooge importo ir eksporto papildinys
Name[nb]=Skrooge eksport/import-modul
Name[nds]=Im- un Exporterenmoduul för Skrooge
Name[nl]=Im-/exportplugin voor Skrooge
Name[pl]=Wtyczka importu i eksportu dla Skrooge
Name[pt]='Plugin' de importação e exportação do Skrooge
Name[pt_BR]=Plugin de importação e exportação do Skrooge
Name[ru]=Модуль импорта и экспорта
Name[sk]=Plugin importu a exportu Skrooge
Name[sv]=Skrooge import- och exportinsticksprogram
Name[tr]=Bir Skrooge içeriye ve dışarıya aktarma eklentisi
Name[uk]=Додаток імпорту та експорту Skrooge
Name[x-test]=xxSkrooge import and export pluginxx
Name[zh_TW]=Skrooge 匯入與匯出外掛程式
Comment=A skrooge plugin for import and export operations
Comment[bs]=Skrooge dodatak za operacije uvoza i izvoza
Comment[ca]=Un connector de l'Skrooge per operacions d'importació i exportació
Comment[ca@valencia]=Un connector de l'Skrooge per operacions d'importació i exportació
Comment[cs]=Modul importu a exportu operací pro Skrooge
Comment[da]=Et Skrooge-plugin til import- og eksporthandlinger
Comment[de]=Ein Skrooge-Modul für Import- und Exportvorgängen
Comment[el]=Ένα πρόσθετο του skrooge για τις λειτουργίες εισαγωγής και εξαγωγής
Comment[en_GB]=A skrooge plugin for import and export operations
Comment[es]=Un complemento de Skrooge para importar y exportar operaciones
Comment[et]=Skrooge importimise ja eksportimise plugin
Comment[fi]=Skroogen tuonti- ja vientitoimintojen liitännäinen
Comment[fr]=Un module externe Skrooge pour les opérations d'importation et d'exportation
Comment[gl]=Un complemento de Skrooge para operacións de importación e exportación.
Comment[hu]=Egy Skrooge bővítmény import és export műveletekhez
Comment[it]=Un'estensione di Skrooge per le operazioni di importazione ed esportazione
Comment[lt]=Skrooge papildinys importuoti ir eksportuoti operacijas
Comment[nb]=En Skrooge-modul for import og eksporthandlinger
Comment[nds]=En Moduul för't Im- un Exporteren för Skrooge
Comment[nl]=Een skrooge-plugin voor im- en export bewerkingen
Comment[pl]=Wtyczka Skrooge dla operacji importu i eksportu
Comment[pt]=Um 'plugin' do Skrooge para operações de importação e exportação
Comment[pt_BR]=Um plugin do Skrooge para operações de importação e exportação
Comment[ru]=Модуль импорта и экспорта операций
Comment[sk]=Plugin Skrooge na operácie importu a exportu
Comment[sv]=Ett insticksprogram till Skrooge för import- och exportåtgärder
Comment[tr]=İçeriye ve dışarıya aktarma işlemleri için bir Skrooge eklentisi
Comment[uk]=Додаток до skrooge для виконання дій з імпортування та експортування
Comment[x-test]=xxA skrooge plugin for import and export operationsxx
Comment[zh_TW]=Skrooge 匯入與匯出用的外掛程式
Encoding=UTF-8
Icon=skrooge
Type=Service
X-KDE-ServiceTypes=SKG GUI/Plugin
X-KDE-Library=skrooge_importexport
X-Krunner-ID=Skrooge import and export plugin
X-KDE-PluginInfo-Author=Stephane MANKOWSKI,miraks
X-KDE-PluginInfo-Email=stephane@mankowski.fr
X-KDE-PluginInfo-Name=skrooge_importexport
X-KDE-PluginInfo-Version=1.0
-X-KDE-PluginInfo-Website=http://skrooge.org/
+X-KDE-PluginInfo-Website=https://skrooge.org/
X-KDE-PluginInfo-Category=Plugins
X-KDE-PluginInfo-Depends=
X-KDE-PluginInfo-License=GPL
X-KDE-PluginInfo-EnabledByDefault=true
diff --git a/plugins/skrooge/skrooge_importexport/skgimportexportplugin.cpp b/plugins/skrooge/skrooge_importexport/skgimportexportplugin.cpp
index 22f4dbe27..ce09ddec3 100644
--- a/plugins/skrooge/skrooge_importexport/skgimportexportplugin.cpp
+++ b/plugins/skrooge/skrooge_importexport/skgimportexportplugin.cpp
@@ -1,1074 +1,1074 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is Skrooge plugin for import and export operation.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgimportexportplugin.h"
#include <kaboutdata.h>
#include <kactioncollection.h>
#include <kactionmenu.h>
#include <kencodingfiledialog.h>
#include <kmessagewidget.h>
#include <kpassworddialog.h>
#include <kpluginfactory.h>
#include <kservice.h>
#include <kservicetypetrader.h>
#include <qaction.h>
#include <qdiriterator.h>
#include <qdom.h>
#include <qstandardpaths.h>
#include <qsysinfo.h>
#include <qtextcodec.h>
#include "skgbankincludes.h"
#include "skgerror.h"
#include "skgimportexport_settings.h"
#include "skgmainpanel.h"
#include "skgoperationobject.h"
#include "skgtraces.h"
/**
* This plugin factory.
*/
K_PLUGIN_FACTORY(SKGImportExportPluginFactory, registerPlugin<SKGImportExportPlugin>();)
SKGImportExportPlugin::SKGImportExportPlugin(QWidget* iWidget, QObject* iParent, const QVariantList& /*iArg*/) :
SKGInterfacePlugin(iParent),
m_currentBankDocument(nullptr), m_install(false)
{
Q_UNUSED(iWidget)
SKGTRACEINFUNC(10)
}
SKGImportExportPlugin::~SKGImportExportPlugin()
{
SKGTRACEINFUNC(10)
m_currentBankDocument = nullptr;
}
bool SKGImportExportPlugin::setupActions(SKGDocument* iDocument)
{
SKGTRACEINFUNC(10)
m_currentBankDocument = qobject_cast<SKGDocumentBank*>(iDocument);
if (m_currentBankDocument == nullptr) {
return false;
}
// Tell the host application to load my GUI component
setComponentName(QStringLiteral("skrooge_importexport"), title());
setXMLFile(QStringLiteral("skrooge_importexport.rc"));
// Imports
auto imports = new KActionMenu(SKGServices::fromTheme(QStringLiteral("document-import")), i18nc("Verb, action to import items from another format", "Import"), this);
registerGlobalAction(QStringLiteral("import"), imports);
// Import
QStringList overlay;
overlay.push_back(QStringLiteral("skrooge"));
auto actImport = new QAction(SKGServices::fromTheme(QStringLiteral("document-import"), overlay), i18nc("Verb, action to import items from another format", "Import..."), this);
actionCollection()->setDefaultShortcut(actImport, Qt::CTRL + Qt::META + Qt::Key_I);
connect(actImport, &QAction::triggered, this, [ = ]() {
this->importFiles();
});
imports->addAction(actImport);
registerGlobalAction(QStringLiteral("import_operation"), actImport);
// Import backends
QStringList overlay2;
overlay.push_back(QStringLiteral("download"));
auto actImportBackend = new QAction(SKGServices::fromTheme(QStringLiteral("document-import"), overlay2), i18nc("Verb, action to import items from another format", "Import with backends"), this);
actionCollection()->setDefaultShortcut(actImportBackend, Qt::CTRL + Qt::META + Qt::Key_W);
connect(actImportBackend, &QAction::triggered, this, &SKGImportExportPlugin::importbackends);
imports->addAction(actImportBackend);
registerGlobalAction(QStringLiteral("import_backends"), actImportBackend);
// Import CSV Unit
QStringList overlaycsv;
overlaycsv.push_back(QStringLiteral("text-csv"));
auto actImportCsvUnit = new QAction(SKGServices::fromTheme(QStringLiteral("document-import"), overlaycsv), i18nc("Verb, action to import", "Import currency values..."), this);
connect(actImportCsvUnit, &QAction::triggered, this, [ = ]() {
this->importFiles(QList<QUrl>(), 2);
});
imports->addAction(actImportCsvUnit);
registerGlobalAction(QStringLiteral("import_csv_unit"), actImportCsvUnit);
// Import CSV Rule
auto actImportCsvRule = new QAction(SKGServices::fromTheme(QStringLiteral("document-import"), overlaycsv), i18nc("Verb, action to import", "Import rules..."), this);
connect(actImportCsvRule, &QAction::triggered, this, [ = ]() {
this->importFiles(QList<QUrl>(), 3);
});
imports->addAction(actImportCsvRule);
registerGlobalAction(QStringLiteral("import_csv_rule"), actImportCsvRule);
// Exports
auto exports = new KActionMenu(SKGServices::fromTheme(QStringLiteral("document-export")), i18nc("Verb, action to export items in another format", "Export"), this);
registerGlobalAction(QStringLiteral("export"), exports);
// Export
auto actExportFile = new QAction(SKGServices::fromTheme(QStringLiteral("document-export")), i18nc("Verb, action to export items to another format", "Export..."), this);
connect(actExportFile, &QAction::triggered, this, &SKGImportExportPlugin::exportFile);
exports->addAction(actExportFile);
actionCollection()->setDefaultShortcut(actExportFile, Qt::CTRL + Qt::META + Qt::Key_E);
registerGlobalAction(QStringLiteral("export_operation"), actExportFile);
// Processing
auto processing = new KActionMenu(SKGServices::fromTheme(QStringLiteral("tools-wizard")), i18nc("Noun, apply some kind of transformation on an item", "Processing"), this);
registerGlobalAction(QStringLiteral("processing"), processing);
// Processing found and group
QStringList overlaytransfers;
overlaytransfers.push_back(QStringLiteral("exchange-positions"));
auto actProcessingFoundTransfer = new QAction(SKGServices::fromTheme(QStringLiteral("tools-wizard"), overlaytransfers), i18nc("Verb, action to find and group transfers", "Find and group transfers"), this);
connect(actProcessingFoundTransfer, &QAction::triggered, this, &SKGImportExportPlugin::findTransfers);
processing->addAction(actProcessingFoundTransfer);
actionCollection()->setDefaultShortcut(actProcessingFoundTransfer, Qt::CTRL + Qt::META + Qt::Key_G);
registerGlobalAction(QStringLiteral("process_foundtransfer"), actProcessingFoundTransfer);
auto actProcessingAnonymize = new QAction(SKGServices::fromTheme(QStringLiteral("tools-wizard"), overlaytransfers), i18nc("Verb, action to anonymize a document", "Anonymize"), this);
connect(actProcessingAnonymize, &QAction::triggered, this, &SKGImportExportPlugin::anonymize);
processing->addAction(actProcessingAnonymize);
registerGlobalAction(QStringLiteral("process_anonymize"), actProcessingAnonymize);
// Processing banks
auto actProcessingBank = new QAction(SKGServices::fromTheme(QStringLiteral("tools-wizard")), i18nc("Verb, action to clean an import", "Clean bank's imports"), this);
connect(actProcessingBank, &QAction::triggered, this, &SKGImportExportPlugin::cleanBanks);
processing->addAction(actProcessingBank);
registerGlobalAction(QStringLiteral("process_banks"), actProcessingBank);
// Processing banks
QStringList overlayValidate;
overlayValidate.push_back(QStringLiteral("dialog-ok"));
auto actSwithValidationImportedOperations = new QAction(SKGServices::fromTheme(QStringLiteral("document-import"), overlayValidate), i18nc("Verb, action to validate imported operations", "Switch validation of imported operations"), this);
connect(actSwithValidationImportedOperations, &QAction::triggered, this, &SKGImportExportPlugin::swithvalidationImportedOperations);
actionCollection()->setDefaultShortcut(actSwithValidationImportedOperations, Qt::CTRL + Qt::SHIFT + Qt::Key_V);
registerGlobalAction(QStringLiteral("switch_validation_imported_operation"), actSwithValidationImportedOperations, QStringList() << QStringLiteral("operation"), 1, -1, 318);
auto act = new QAction(SKGServices::fromTheme(QStringLiteral("document-import"), overlayValidate), i18nc("Verb, action to merge", "Validate operations that do not require further action"), this);
connect(act, &QAction::triggered, this, &SKGImportExportPlugin::validateAllOperations);
registerGlobalAction(QStringLiteral("process_validate"), act, QStringList(), -2, -1);
QStringList overlayopen;
overlayopen.push_back(QStringLiteral("quickopen"));
auto actOpenNotValidated = new QAction(SKGServices::fromTheme(QStringLiteral("document-import"), overlayopen), i18nc("Verb, action to open", "Open imported operations not yet validated..."), this);
actOpenNotValidated->setData(QString("skg://skrooge_operation_plugin/?title=" % SKGServices::encodeForUrl(i18nc("Noun, a list of items", "Operations imported and not yet validated")) %
"&title_icon=" % SKGServices::encodeForUrl(icon()) %
"&operationWhereClause=" % SKGServices::encodeForUrl(QStringLiteral("t_imported='P'"))));
connect(actOpenNotValidated, &QAction::triggered, SKGMainPanel::getMainPanel(), [ = ]() {
SKGMainPanel::getMainPanel()->SKGMainPanel::openPage();
});
actionCollection()->setDefaultShortcut(actOpenNotValidated, Qt::META + Qt::Key_V);
registerGlobalAction(QStringLiteral("view_open_not_validated"), actOpenNotValidated);
auto actMergeImportedOperation = new QAction(SKGServices::fromTheme(QStringLiteral("merge")), i18nc("Verb, action to merge", "Merge imported operations"), this);
connect(actMergeImportedOperation, &QAction::triggered, this, &SKGImportExportPlugin::mergeImportedOperation);
actionCollection()->setDefaultShortcut(actMergeImportedOperation, Qt::CTRL + Qt::ALT + Qt::Key_M);
registerGlobalAction(QStringLiteral("merge_imported_operation"), actMergeImportedOperation, QStringList() << QStringLiteral("operation"), 1, -1, 319);
auto force = new QAction(i18nc("Noun", "Force the merge"), this);
force->setIcon(SKGServices::fromTheme(QStringLiteral("merge")));
force->setData(1);
connect(force, &QAction::triggered, this, &SKGImportExportPlugin::mergeImportedOperation);
registerGlobalAction(QStringLiteral("merge_imported_operation_force"), force);
// Get last argument
connect(this, &SKGImportExportPlugin::importFileName, this, [ = ](const QString & iFileName) {
this->importFile(iFileName, true);
}, Qt::QueuedConnection);
// Krunner operations
QString dirName = QDir::homePath() % "/.skrooge/";
QStringList fileList = QDir(dirName).entryList(QStringList() << QStringLiteral("add_operation_*.txt"), QDir::Files);
if (!fileList.isEmpty()) {
m_currentBankDocument->sendMessage(i18nc("Information message", "You have some krunner's operations to import"));
}
return true;
}
QStringList SKGImportExportPlugin::processArguments(const QStringList& iArgument)
{
SKGTRACEINFUNC(10)
QStringList output = iArgument;
int nbArg = output.count();
if (nbArg != 0) {
QString filename = output.at(nbArg - 1);
QString extension = QFileInfo(filename).suffix().toUpper();
QString extensionDocument = m_currentBankDocument->getFileExtension().toUpper();
if (QFile(filename).exists() && extension != extensionDocument) {
Q_EMIT importFileName(filename);
output.pop_back();
}
}
return output;
}
QWidget* SKGImportExportPlugin::getPreferenceWidget()
{
SKGTRACEINFUNC(10)
auto w = new QWidget();
ui.setupUi(w);
connect(ui.kcfg_automatic_search_header, &QCheckBox::toggled, ui.kHeaderPositionFrm, &QFrame::setHidden);
connect(ui.kcfg_automatic_search_columns, &QCheckBox::toggled, ui.kColumnsPositionsFrm, &QFrame::setHidden);
connect(ui.kcfg_automatic_search_columns, &QCheckBox::clicked, ui.kCsvMappingFrm, &QFrame::hide);
connect(ui.kcfg_automatic_search_columns, &QCheckBox::toggled, ui.More, &QPushButton::setEnabled);
connect(ui.More, &QPushButton::toggled, ui.kCsvMappingFrm, &QFrame::setVisible);
connect(ui.kcfg_automatic_search_columns, &QCheckBox::clicked, ui.More, &QPushButton::setChecked);
connect(ui.kcfg_download_on_open, &QCheckBox::toggled, ui.kcfg_download_frequency, &KComboBox::setEnabled);
ui.kHeaderPositionFrm->hide();
ui.kColumnsPositionsFrm->hide();
ui.kCsvMappingFrm->hide();
// Build list of known backends
QString doc;
const auto services = KServiceTypeTrader::self()->query(QStringLiteral("Skrooge/Import/Backend"));
for (const auto& service : services) {
auto os_supported = SKGServices::splitCSVLine(service->property(QStringLiteral("X-SKROOGE-ossuppored"), QVariant::String).toString().toLower(), QLatin1Char(','));
if (os_supported.isEmpty() || os_supported.contains(QSysInfo::kernelType().toLower())) {
doc += "<br/><b>" + service->property(QStringLiteral("X-Krunner-ID"), QVariant::String).toString().toLower() + "</b><br/>";
doc += service->property(QStringLiteral("Name"), QVariant::String).toString() + "<br/>";
doc += service->property(QStringLiteral("Comment"), QVariant::String).toString() + "<br/>";
}
}
auto text = i18nc("Information", "You must enter the list of backends to use separated by a ';'.\nA backend can have parameters. You can pass the parameters in parenthesis separated by comma.\n\nExample: backendA;backendB(parameter1,parameter2).\n\nHere is the list of known backends: %1.", doc);
text = text.replace(QStringLiteral("\n"), QStringLiteral("<br/>"));
ui.kbackendText->setText(text);
// Add date formats
QStringList dateFormats;
dateFormats << i18nc("Format date", "Automatic detection")
<< QStringLiteral("YYYYMMDD")
<< QStringLiteral("MMDDYYYY")
<< QStringLiteral("DDMMYYYY")
<< QStringLiteral("MM-DD-YY")
<< QStringLiteral("DD-MM-YY")
<< QStringLiteral("MM-DD-YYYY")
<< QStringLiteral("DD-MM-YYYY")
<< QStringLiteral("YYYY-MM-DD")
<< QStringLiteral("DDMMMYYYY")
<< QStringLiteral("DD-MMM-YY")
<< QStringLiteral("DD-MMM-YYYY");
ui.kcfg_qif_date_format->addItems(dateFormats);
ui.kcfg_csv_date_format->addItems(dateFormats);
return w;
}
KConfigSkeleton* SKGImportExportPlugin::getPreferenceSkeleton()
{
return skgimportexport_settings::self();
}
QString SKGImportExportPlugin::title() const
{
return i18nc("Noun", "Import / Export");
}
QString SKGImportExportPlugin::icon() const
{
return QStringLiteral("utilities-file-archiver");
}
QString SKGImportExportPlugin::toolTip() const
{
return i18nc("Noun", "Import / Export management");
}
QStringList SKGImportExportPlugin::tips() const
{
QStringList output;
output.push_back(i18nc("Description of a tips", "<p>... skrooge is able to detect <a href=\"skg://tab_configure?page=Skrooge import and export plugin\">automatically</a> transfers after an import.</p>"));
output.push_back(i18nc("Description of a tips", "<p>... you can automatically import operation with <a href=\"skg://tab_configure?page=Skrooge import and export plugin\">backend</a>.</p>"));
output.push_back(i18nc("Description of a tips", "<p>... you can <a href=\"skg://import_operation\">import</a> many files in one shot.</p>"));
output.push_back(i18nc("Description of a tips", "<p>... unit amounts can be imported through a CSV file.</p>"));
output.push_back(i18nc("Description of a tips", "<p>... you can customize your CSV import with regular expressions defined in <a href=\"skg://tab_configure?page=Skrooge import and export plugin\">setting</a> panel.</p>"));
output.push_back(i18nc("Description of a tips", "<p>... you can export the full content of your document into a XML file.</p>"));
output.push_back(i18nc("Description of a tips", "<p>... you can export some accounts or operations just be selecting them before to launch the <a href=\"skg://export\">export_operation</a>.</p>"));
output.push_back(i18nc("Description of a tips", "<p>... you can apply <a href=\"skg://skrooge_search_plugin\">automatic rules</a> after an import to set the right categories.</p>"));
output.push_back(i18nc("Description of a tips", "<p>... you can convert file by using the batch tool '%1'.</p>", "skroogeconvert"));
output.push_back(i18nc("Description of a tips", "<p>... skrooge uses the name of the imported file to find the target account.</p>"));
return output;
}
QStringList SKGImportExportPlugin::subPlugins() const
{
return QStringList() << QStringLiteral("SKG IMPORT/Plugin") << QStringLiteral("Skrooge/Import/Backend");
}
int SKGImportExportPlugin::getOrder() const
{
return 70;
}
void SKGImportExportPlugin::refresh()
{
SKGTRACEINFUNC(10)
if ((m_currentBankDocument != nullptr) && (SKGMainPanel::getMainPanel() != nullptr)) {
bool test = (m_currentBankDocument->getMainDatabase() != nullptr);
// Automatic download
if (test) {
QString doc_id = m_currentBankDocument->getUniqueIdentifier();
if (m_docUniqueIdentifier != doc_id) {
m_docUniqueIdentifier = doc_id;
SKGError err;
if (skgimportexport_settings::download_on_open()) {
// Check frequency
QString lastAutomaticDownload = m_currentBankDocument->getParameter(QStringLiteral("SKG_LAST_BACKEND_AUTOMATIC_DOWNLOAD"));
if (!lastAutomaticDownload.isEmpty()) {
// The automatic import is not done if at least one manual import has not been done
QDate lastAutomaticDownloadDate = QDate::fromString(lastAutomaticDownload, QStringLiteral("yyyy-MM-dd"));
if ((lastAutomaticDownloadDate.daysTo(QDate::currentDate()) >= 1 && skgimportexport_settings::download_frequency() == 0) ||
(lastAutomaticDownloadDate.daysTo(QDate::currentDate()) >= 7 && skgimportexport_settings::download_frequency() == 1) ||
(lastAutomaticDownloadDate.daysTo(QDate::currentDate()) >= 30 && skgimportexport_settings::download_frequency() == 2))
{
// Import
importbackends();
}
}
}
}
}
}
}
SKGError SKGImportExportPlugin::importbackends()
{
SKGError err;
SKGTRACEINFUNCRC(10, err)
if (m_currentBankDocument != nullptr) {
// Check if already in a transaction
if (!m_currentBankDocument->checkExistingTransaction()) {
// Repeat later
QTimer::singleShot(300, Qt::CoarseTimer, this, &SKGImportExportPlugin::importbackends);
return err;
}
// Get backends list to used
QStringList backends = SKGServices::splitCSVLine(skgimportexport_settings::backends());
int nbBackends = backends.count();
// Import
SKGBEGINPROGRESSTRANSACTION(*m_currentBankDocument, i18nc("Noun, name of the user action", "Import with backends"), err, nbBackends)
for (int i = 0; !err && i < nbBackends; ++i) {
QString backend = backends.at(i).trimmed();
QString parameter;
if (backend.contains(QStringLiteral("("))) {
QRegExp reg(QStringLiteral("^(.+)\\((.+)\\)$"));
int pos = reg.indexIn(backend);
if (pos != -1) {
backend = reg.cap(1);
parameter = reg.cap(2);
} else {
err = SKGError(ERR_FAIL, i18nc("Error message", "Syntax error in backend \"%1\"", backend));
break;
}
}
// Is password needed?
QString pwd;
/*TODO QHash< QString, QString > properties;
err = SKGServices::readPropertyFile(QStandardPaths::locate(QStandardPaths::GenericDataLocation, "skrooge/backends/" % backends.at(i) % ".backend"), properties);
if (!err && (properties[QStringLiteral("getaccounts")].contains(QStringLiteral("%3")) || properties[QStringLiteral("getoperations")].contains(QStringLiteral("%3")))) {
QApplication::setOverrideCursor(QCursor(Qt::ArrowCursor));
QPointer<KPasswordDialog> dlg = new KPasswordDialog(SKGMainPanel::getMainPanel());
dlg->setPrompt(i18nc("Question", "The backend '%1' needs a password.\nPlease enter the password.", backend));
int rc = dlg->exec();
pwd = dlg->password();
delete dlg;
QApplication::restoreOverrideCursor();
if (rc != QDialog::Accepted) {
continue;
}
}*/
QString codec = m_currentBankDocument->getParameter(QStringLiteral("SKG_LAST_CODEC_USED_FOR_IMPORT"));
if (codec.isEmpty()) {
codec = QTextCodec::codecForLocale()->name();
}
IFOKDO(err, m_currentBankDocument->setParameter(QStringLiteral("SKG_LAST_CODEC_USED_FOR_IMPORT"), codec))
SKGImportExportManager imp1(m_currentBankDocument, QUrl("." % backend));
QMap<QString, QString> parameters = imp1.getImportParameters();
parameters[QStringLiteral("password")] = pwd;
auto params = SKGServices::splitCSVLine(parameter, QLatin1Char(','));
int nbp = params.count();
for (int j = 0; j < nbp; ++j) {
parameters[QStringLiteral("parameter") % SKGServices::intToString(j + 1)] = params.at(j).trimmed();
}
imp1.setImportParameters(parameters);
imp1.setAutomaticValidation(skgimportexport_settings::automatic_validation());
imp1.setAutomaticApplyRules(skgimportexport_settings::apply_rules());
// This option is not used with backend import
imp1.setSinceLastImportDate(false);
imp1.setCodec(codec);
IFOKDO(err, imp1.importFile())
IFOKDO(err, m_currentBankDocument->stepForward(i + 1))
}
// Memorize the last download date
IFOKDO(err, m_currentBankDocument->setParameter(QStringLiteral("SKG_LAST_BACKEND_AUTOMATIC_DOWNLOAD"), QDate::currentDate().toString(QStringLiteral("yyyy-MM-dd"))))
}
// Display error
SKGMainPanel::displayErrorMessage(err);
// Open last modified operations if setting activated
IFOK(err) openLastModifiedIfSetting();
return err;
}
void SKGImportExportPlugin::importFile(const QString& iFile, bool iBlockOpenLastModified)
{
importFiles(QList<QUrl>() << QUrl::fromLocalFile(iFile), static_cast<int>(iBlockOpenLastModified));
}
void SKGImportExportPlugin::importFiles(const QList<QUrl>& iFiles, int mode, bool iBlockOpenLastModified)
{
SKGError err;
SKGTRACEINFUNCRC(10, err)
if (m_currentBankDocument != nullptr) {
QList<QUrl> fileNames;
QString lastCodecUsed = m_currentBankDocument->getParameter(QStringLiteral("SKG_LAST_CODEC_USED_FOR_IMPORT"));
if (lastCodecUsed.isEmpty()) {
lastCodecUsed = QTextCodec::codecForLocale()->name();
}
QString codec;
if (iFiles.isEmpty()) {
// Panel to ask files
KEncodingFileDialog::Result result = KEncodingFileDialog::getOpenUrlsAndEncoding(lastCodecUsed, QUrl(QStringLiteral("kfiledialog:///IMPEXP")),
mode == 2 || mode == 3 ? QString("*.csv|" % i18nc("A file format", "CSV Files")) :
SKGImportExportManager::getImportMimeTypeFilter(),
SKGMainPanel::getMainPanel());
const auto urls = result.URLs;
fileNames.reserve(urls.count());
for (const auto& u : qAsConst(urls)) {
fileNames.append(QUrl(u.url()));
}
codec = result.encoding;
} else {
fileNames = iFiles;
codec = lastCodecUsed;
}
int nbFiles = fileNames.count();
if (nbFiles != 0) {
{
SKGBEGINPROGRESSTRANSACTION(*m_currentBankDocument, i18nc("Noun, name of the user action", "Import with codec %1", codec), err, nbFiles)
// Read Setting
bool automatic_validation = skgimportexport_settings::automatic_validation();
bool automatic_rule = skgimportexport_settings::apply_rules();
bool since_last = skgimportexport_settings::since_last_import();
IFOKDO(err, m_currentBankDocument->setParameter(QStringLiteral("SKG_LAST_CODEC_USED_FOR_IMPORT"), codec))
for (int i = 0; !err && i < nbFiles; ++i) {
// Get Filename
const QUrl& fileName = fileNames.at(i);
// Import
SKGImportExportManager imp1(m_currentBankDocument, fileName);
imp1.setAutomaticValidation(automatic_validation);
imp1.setAutomaticApplyRules(automatic_rule);
imp1.setSinceLastImportDate(since_last);
imp1.setCodec(codec);
if (QFileInfo(fileName.path()).suffix().toUpper() == QStringLiteral("CSV")) {
QMap<QString, QString> parameters = imp1.getImportParameters();
parameters[QStringLiteral("automatic_search_header")] = (skgimportexport_settings::automatic_search_header() ? QStringLiteral("Y") : QStringLiteral("N"));
parameters[QStringLiteral("header_position")] = SKGServices::intToString(skgimportexport_settings::header_position());
parameters[QStringLiteral("mapping_date")] = skgimportexport_settings::mapping_date();
parameters[QStringLiteral("mapping_account")] = skgimportexport_settings::mapping_account();
parameters[QStringLiteral("mapping_number")] = skgimportexport_settings::mapping_number();
parameters[QStringLiteral("mapping_mode")] = skgimportexport_settings::mapping_mode();
parameters[QStringLiteral("mapping_payee")] = skgimportexport_settings::mapping_payee();
parameters[QStringLiteral("mapping_comment")] = skgimportexport_settings::mapping_comment();
parameters[QStringLiteral("mapping_status")] = skgimportexport_settings::mapping_status();
parameters[QStringLiteral("mapping_bookmarked")] = skgimportexport_settings::mapping_bookmarked();
parameters[QStringLiteral("mapping_category")] = skgimportexport_settings::mapping_category();
parameters[QStringLiteral("mapping_amount")] = skgimportexport_settings::mapping_amount();
parameters[QStringLiteral("mapping_quantity")] = skgimportexport_settings::mapping_quantity();
parameters[QStringLiteral("mapping_unit")] = skgimportexport_settings::mapping_unit();
parameters[QStringLiteral("mapping_idtransaction")] = skgimportexport_settings::mapping_idtransaction();
parameters[QStringLiteral("mapping_idgroup")] = skgimportexport_settings::mapping_idgroup();
parameters[QStringLiteral("mapping_sign")] = skgimportexport_settings::mapping_sign();
parameters[QStringLiteral("mapping_debit")] = skgimportexport_settings::mapping_debit();
parameters[QStringLiteral("mapping_property")] = skgimportexport_settings::mapping_property();
parameters[QStringLiteral("automatic_search_columns")] = (skgimportexport_settings::automatic_search_columns() ? QStringLiteral("Y") : QStringLiteral("N"));
parameters[QStringLiteral("columns_positions")] = skgimportexport_settings::columns_positions();
parameters[QStringLiteral("mode_csv_unit")] = (mode == 2 ? QStringLiteral("Y") : QStringLiteral("N"));
parameters[QStringLiteral("mode_csv_rule")] = (mode == 3 ? QStringLiteral("Y") : QStringLiteral("N"));
parameters[QStringLiteral("date_format")] = skgimportexport_settings::csv_date_format();
if (!parameters[QStringLiteral("date_format")].contains(QStringLiteral("YY"))) {
parameters[QStringLiteral("date_format")] = QString();
}
imp1.setImportParameters(parameters);
} else if (QFileInfo(fileName.path()).suffix().toUpper() == QStringLiteral("QIF")) {
QMap<QString, QString> parameters = imp1.getImportParameters();
parameters[QStringLiteral("date_format")] = skgimportexport_settings::qif_date_format();
if (!parameters[QStringLiteral("date_format")].contains(QStringLiteral("YY"))) {
parameters[QStringLiteral("date_format")] = QString();
}
imp1.setImportParameters(parameters);
}
// Optimization
if (i != nbFiles - 1) {
QMap< QString, QString > parameters = imp1.getImportParameters();
parameters[QStringLiteral("donotfinalize")] = 'Y';
imp1.setImportParameters(parameters);
}
if (m_install) {
QMap< QString, QString > parameters = imp1.getImportParameters();
parameters[QStringLiteral("install_sunriise")] = 'Y';
imp1.setImportParameters(parameters);
}
IFOKDO(err, imp1.importFile())
if (err && err.getReturnCode() == ERR_ENCRYPTION) {
QString pwd;
QString additionalMessage;
do {
// Reset error
err = SKGError(ERR_FAIL, i18nc("Error message", "Import of file named '%1' failed", fileName.toDisplayString()));
pwd = QString();
// Use password dialog
QApplication::restoreOverrideCursor();
QPointer<KPasswordDialog> dlg = new KPasswordDialog(SKGMainPanel::getMainPanel());
dlg->setPrompt(additionalMessage % i18nc("Question", "This file seems to be protected.\nPlease enter the password."));
if (dlg->exec() == QDialog::Accepted) {
pwd = dlg->password();
}
delete dlg;
QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
// Load file
if (!pwd.isEmpty()) {
QMap<QString, QString> parameters = imp1.getImportParameters();
parameters[QStringLiteral("password")] = pwd;
imp1.setImportParameters(parameters);
err = imp1.importFile();
IFKO(err) {
if (err.getReturnCode() == ERR_ENCRYPTION) {
additionalMessage = i18nc("The user did not provide the correct password", "<b>Wrong password.</b>\n");
} else {
// Import error
break;
}
}
} else {
err = SKGError(ERR_FAIL, i18nc("Error message", "Import canceled by user"));
break;
}
} while (err);
}
if (err && err.getReturnCode() != ERR_INSTALL) {
err.addError(ERR_FAIL, i18nc("Error message", "Import of file named '%1' failed", fileName.toDisplayString()));
}
IFOKDO(err, m_currentBankDocument->stepForward(i + 1))
}
}
// status bar
IFOK(err) {
err = SKGError(0, i18np("%1 file successfully imported.", "%1 files successfully imported.", nbFiles));
}
// Display error
m_install = false;
KMessageWidget* msg = SKGMainPanel::displayErrorMessage(err);
if (err.getReturnCode() == ERR_INSTALL && (msg != nullptr)) {
QString application = err.property("application").toString();
auto install = new QAction(i18nc("Noun", "Install %1", application), msg);
install->setIcon(SKGServices::fromTheme(QStringLiteral("download")));
msg->addAction(install);
connect(install, &QAction::triggered, this, &SKGImportExportPlugin::onInstall);
connect(install, &QAction::triggered, msg, &KMessageWidget::deleteLater, Qt::QueuedConnection);
}
// Open last modified operations if setting activated
if (!iBlockOpenLastModified) {
IFOK(err) openLastModifiedIfSetting();
}
}
}
}
void SKGImportExportPlugin::onInstall()
{
m_install = true;
SKGMainPanel::getMainPanel()->displayMessage(i18nc("Information message", "The installation will be done during the next import"));
}
void SKGImportExportPlugin::exportFile()
{
SKGError err;
SKGTRACEINFUNCRC(10, err)
if (m_currentBankDocument != nullptr) {
QString lastCodecUsed = m_currentBankDocument->getParameter(QStringLiteral("SKG_LAST_CODEC_USED_FOR_IMPORT"));
if (lastCodecUsed.isEmpty()) {
lastCodecUsed = QTextCodec::codecForLocale()->name();
}
QString fileName = SKGMainPanel::getSaveFileName(QStringLiteral("kfiledialog:///IMPEXP"), SKGImportExportManager::getExportMimeTypeFilter(),
SKGMainPanel::getMainPanel(), &lastCodecUsed);
if (fileName.isEmpty() || (m_currentBankDocument == nullptr)) {
return;
}
QString uuids;
const auto objects = SKGMainPanel::getMainPanel()->getSelectedObjects();
for (const auto& obj : objects) {
if (!uuids.isEmpty()) {
uuids.append(";");
}
uuids.append(obj.getUniqueID());
}
{
SKGBEGINTRANSACTION(*m_currentBankDocument, i18nc("Noun, name of the user action", "Export"), err)
IFOK(err) {
SKGImportExportManager imp1(m_currentBankDocument, QUrl::fromLocalFile(fileName));
imp1.setCodec(lastCodecUsed);
QMap<QString, QString> params;
params[QStringLiteral("uuid_of_selected_accounts_or_operations")] = uuids;
imp1.setExportParameters(params);
err = imp1.exportFile();
}
}
// status bar
IFOKDO(err, SKGError(0, i18nc("Successful message after an user action", "File '%1' successfully exported.", fileName)))
else {
err.addError(ERR_FAIL, i18nc("Error message", "Export of '%1' failed", fileName));
}
// Display error
SKGMainPanel::displayErrorMessage(err);
}
}
void SKGImportExportPlugin::anonymize()
{
SKGError err;
SKGTRACEINFUNCRC(10, err)
if (m_currentBankDocument != nullptr) {
QString pwd;
QPointer<KPasswordDialog> dlg = new KPasswordDialog(SKGMainPanel::getMainPanel());
dlg->setPrompt(i18nc("Question", "The file can be made anonymous in two ways.<br/><b>Reversibly:</b> enter a key and memorize it, it will be used to go back.<br/><b>Irreversibly (recommended):</b> do not enter a key.<br/><br/>To reverse an anonymous file, simply try to anonymize it with the same key."));
if (dlg->exec() == QDialog::Accepted) {
pwd = dlg->password();
}
QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
SKGImportExportManager imp1(m_currentBankDocument);
err = imp1.anonymize(pwd);
QApplication::restoreOverrideCursor();
// status bar
IFOKDO(err, SKGError(0, i18nc("An anonymized document is a document where all private data has been removed", "Document anonymized.")))
// Display error
SKGMainPanel::displayErrorMessage(err);
}
}
void SKGImportExportPlugin::findTransfers()
{
SKGError err;
SKGTRACEINFUNCRC(10, err)
if (m_currentBankDocument != nullptr) {
int NbOperationsMerged = 0;
{
SKGBEGINTRANSACTION(*m_currentBankDocument, i18nc("Noun, name of the user action", "Find and group transfers"), err)
IFOK(err) {
SKGImportExportManager imp1(m_currentBankDocument);
err = imp1.findAndGroupTransfers(NbOperationsMerged);
}
}
// status bar
IFOK(err) {
if (NbOperationsMerged != 0) {
err = SKGError(0, i18np("Document successfully processed. %1 transfer created.",
"Document successfully processed. %1 transfers created.", NbOperationsMerged));
} else {
err = m_currentBankDocument->sendMessage(i18nc("Information message", "No transfers found"));
}
} else {
err.addError(ERR_FAIL, i18nc("Error message", "Processing failed."));
}
// Display error
SKGMainPanel::displayErrorMessage(err);
// Open last modified operations if setting activated
if (!err && (NbOperationsMerged != 0)) {
openLastModifiedIfSetting();
}
}
}
void SKGImportExportPlugin::cleanBanks()
{
SKGError err;
SKGTRACEINFUNCRC(10, err) {
SKGBEGINTRANSACTION(*m_currentBankDocument, i18nc("Noun, name of the user action", "Clean bank's imports"), err)
IFOK(err) {
SKGImportExportManager imp1(m_currentBankDocument);
err = imp1.cleanBankImport();
}
}
// status bar
IFOKDO(err, SKGError(0, i18nc("Successful message after an user action", "Document successfully cleaned.")))
else {
err.addError(ERR_FAIL, i18nc("Error message", "Clean failed."));
}
// Display error
SKGMainPanel::displayErrorMessage(err);
// Open last modified operations if setting activated
IFOK(err) openLastModifiedIfSetting();
}
void SKGImportExportPlugin::swithvalidationImportedOperations()
{
SKGError err;
SKGTRACEINFUNCRC(10, err)
if ((SKGMainPanel::getMainPanel() != nullptr) && (m_currentBankDocument != nullptr)) {
SKGObjectBase::SKGListSKGObjectBase selection = SKGMainPanel::getMainPanel()->getSelectedObjects();
int nb = selection.count();
{
SKGBEGINPROGRESSTRANSACTION(*m_currentBankDocument, i18nc("Noun, name of the user action", "Switch validation of imported operations"), err, nb)
for (int i = 0; !err && i < nb; ++i) {
SKGOperationObject op(selection.at(i));
if (op.getAttribute(QStringLiteral("t_imported")) == QStringLiteral("P")) {
err = op.setImported(true);
IFOKDO(err, op.save())
} else if (op.getAttribute(QStringLiteral("t_imported")) == QStringLiteral("Y")) {
err = op.setAttribute(QStringLiteral("t_imported"), QStringLiteral("P"));
IFOKDO(err, op.save())
}
IFOKDO(err, m_currentBankDocument->stepForward(i + 1))
}
}
}
// status bar
IFOKDO(err, SKGError(0, i18nc("Successful message after an user action", "Imported operations validated.")))
else {
err.addError(ERR_FAIL, i18nc("Error message", "Validation failed"));
}
// Display error
SKGMainPanel::displayErrorMessage(err);
}
void SKGImportExportPlugin::mergeImportedOperation()
{
SKGError err;
SKGTRACEINFUNCRC(10, err)
if ((SKGMainPanel::getMainPanel() != nullptr) && (m_currentBankDocument != nullptr)) {
SKGObjectBase::SKGListSKGObjectBase selection = SKGMainPanel::getMainPanel()->getSelectedObjects();
int nb = selection.count();
err = SKGError(ERR_INVALIDARG, i18nc("Error message", "Invalid selection, you must select one imported operation and one manual operation with same amounts"));
if (nb == 2) {
SKGOperationObject opImported(selection.at(0));
SKGOperationObject opManual(selection.at(1));
if (opImported.isImported() || opManual.isImported()) {
if (opImported.isImported() && opManual.isImported()) {
// Both are imports, so the "imported" on is the last one
if (opImported.getID() < opManual.getID()) {
qSwap(opImported, opManual);
}
} else if (!opImported.isImported()) {
qSwap(opImported, opManual);
}
// Mode force?
bool modeForce = false;
auto* act = qobject_cast< QAction* >(sender());
if (act != nullptr) {
modeForce = (act->data().toInt() == 1);
}
if (!modeForce && m_currentBankDocument->formatMoney(opImported.getCurrentAmount(), m_currentBankDocument->getPrimaryUnit()) != m_currentBankDocument->formatMoney(opManual.getCurrentAmount(), m_currentBankDocument->getPrimaryUnit())) {
SKGMainPanel::getMainPanel()->displayMessage(i18nc("Question", "Amounts are not equals. Do you want to force the merge ?"), SKGDocument::Error, QStringLiteral("skg://merge_imported_operation_force"));
err = SKGError();
} else {
SKGBEGINTRANSACTION(*m_currentBankDocument, i18nc("Noun, name of the user action", "Merge imported operations"), err)
err = opManual.mergeAttribute(opImported);
IFKO(err) err.addError(ERR_FAIL, i18nc("Error message", "Merge failed"));
}
}
}
}
// status bar
IFOKDO(err, SKGError(0, i18nc("Successful message after an user action", "Imported operations merged.")))
// Display error
SKGMainPanel::displayErrorMessage(err);
}
void SKGImportExportPlugin::openLastModifiedIfSetting()
{
// Read Setting
bool open_after_import_or_processing = skgimportexport_settings::open_after_import_or_processing();
if (open_after_import_or_processing) {
// Open last operations
QAction* act = SKGMainPanel::getMainPanel()->getGlobalAction(QStringLiteral("view_open_last_modified"));
if (act != nullptr) {
act->trigger();
}
}
}
void SKGImportExportPlugin::validateAllOperations()
{
SKGError err;
SKGTRACEINFUNCRC(10, err) {
SKGBEGINTRANSACTION(*m_currentBankDocument, i18nc("Noun, name of the user action", "Validate all operations"), err)
err = m_currentBankDocument->executeSqliteOrder(QStringLiteral("UPDATE operation SET t_imported='Y' WHERE t_imported='P'"));
}
// status bar
IFOKDO(err, SKGError(0, i18nc("Message for successful user action", "Operations validated.")))
else {
err.addError(ERR_FAIL, i18nc("Error message", "Validation failed"));
}
// Display error
SKGMainPanel::displayErrorMessage(err);
}
SKGAdviceList SKGImportExportPlugin::advice(const QStringList& iIgnoredAdvice)
{
SKGTRACEINFUNC(10)
SKGAdviceList output;
// Check operations not validated
if (!iIgnoredAdvice.contains(QStringLiteral("skgimportexportplugin_notvalidated"))) {
bool exist = false;
m_currentBankDocument->existObjects(QStringLiteral("operation"), QStringLiteral("t_imported='P'"), exist);
if (exist) {
SKGAdvice ad;
ad.setUUID(QStringLiteral("skgimportexportplugin_notvalidated"));
ad.setPriority(4);
ad.setShortMessage(i18nc("Advice on making the best (short)", "Many operations imported and not yet validated"));
ad.setLongMessage(i18nc("Advice on making the best (long)", "After importing operations, you should review them, make corrections on, for instance, category, payee. Once done, you should mark the imported operation as validated, so that you know the operation has been fully processed."));
SKGAdvice::SKGAdviceActionList autoCorrections;
{
SKGAdvice::SKGAdviceAction a;
a.Title = QStringLiteral("skg://view_open_not_validated");
a.IsRecommended = false;
autoCorrections.push_back(a);
}
{
SKGAdvice::SKGAdviceAction a;
a.Title = QStringLiteral("skg://process_validate");
a.IsRecommended = false;
autoCorrections.push_back(a);
}
ad.setAutoCorrections(autoCorrections);
output.push_back(ad);
}
}
// Krunner operations
QString dirName = QDir::homePath() % "/.skrooge/";
QStringList fileList = QDir(dirName).entryList(QStringList() << QStringLiteral("add_operation_*.txt"), QDir::Files);
int nb = fileList.count();
if (nb != 0) {
QStringList listAccounts;
m_currentBankDocument->getDistinctValues(QStringLiteral("account"), QStringLiteral("t_name"), QStringLiteral("t_type IN ('C', 'D', 'W') and t_close='N'"), listAccounts);
int nbAccounts = listAccounts.count();
SKGAdvice::SKGAdviceActionList autoCorrections;
autoCorrections.reserve(nbAccounts + 1);
for (int i = 0; i < nb; ++i) {
QString fileName = dirName % fileList.at(i);
QFile file(fileName);
if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
QTextStream stream(&file);
stream.readLine(); // action not used yet
QString date = QLocale().toString(SKGServices::stringToTime(stream.readLine().trimmed()).date(), QLocale::ShortFormat);
QString amount = m_currentBankDocument->formatMoney(SKGServices::stringToDouble(stream.readLine().trimmed()), m_currentBankDocument->getPrimaryUnit());
QString payee = stream.readLine().trimmed();
SKGAdvice ad;
ad.setUUID("skgimportexportplugin_krunner_" % fileName);
ad.setPriority(8);
ad.setShortMessage(i18nc("Advice on making the best (short)", "Krunner's operation ongoing [%1 %2 %3]", date, amount, payee));
ad.setLongMessage(i18nc("Advice on making the best (long)", "Operations created through krunner have to be fully created in skrooge."));
autoCorrections.resize(0);
for (int j = 0; j < nbAccounts; ++j) {
SKGAdvice::SKGAdviceAction a;
a.Title = i18nc("Advice on making the best (action)", "Import operation in %1", listAccounts.at(j));
a.IconName = icon();
a.IsRecommended = false;
autoCorrections.push_back(a);
}
{
SKGAdvice::SKGAdviceAction a;
a.Title = i18nc("Advice on making the best (action)", "Remove operation");
a.IconName = QStringLiteral("edit-delete");
a.IsRecommended = false;
autoCorrections.push_back(a);
}
ad.setAutoCorrections(autoCorrections);
output.push_back(ad);
// Close file
file.close();
}
}
}
return output;
}
SKGError SKGImportExportPlugin::executeAdviceCorrection(const QString& iAdviceIdentifier, int iSolution)
{
if (iAdviceIdentifier.startsWith(QLatin1String("skgimportexportplugin_krunner_")) && (m_currentBankDocument != nullptr)) {
SKGError err;
// Get file name
QString fileName = iAdviceIdentifier.right(iAdviceIdentifier.length() - 30);
QFile file(fileName);
// Get accounts
QStringList listAccounts;
m_currentBankDocument->getDistinctValues(QStringLiteral("account"), QStringLiteral("t_name"), QStringLiteral("t_type IN ('C', 'D', 'W') and t_close='N'"), listAccounts);
if (iSolution < listAccounts.count()) {
// Addition in an account
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
err = SKGError(ERR_FAIL, i18nc("An erro message", "Open file '%1' failed", fileName));
} else {
QTextStream stream(&file);
stream.readLine(); // action is not used yet
QDate date = SKGServices::stringToTime(stream.readLine().trimmed()).date();
double amount = SKGServices::stringToDouble(stream.readLine().trimmed());
QString payee = stream.readLine().trimmed();
SKGBEGINTRANSACTION(*m_currentBankDocument, i18nc("Noun, name of the user action", "Import krunner's operation"), err)
// Get account
SKGAccountObject act(m_currentBankDocument);
err = act.setName(listAccounts.at(iSolution));
IFOKDO(err, act.load())
// Get unit
SKGUnitObject unit(m_currentBankDocument);
IFOKDO(err, unit.setName(m_currentBankDocument->getPrimaryUnit().Name))
IFOKDO(err, unit.load())
// Add operation
SKGOperationObject op;
IFOKDO(err, act.addOperation(op))
IFOKDO(err, op.setDate(date))
IFOKDO(err, op.setUnit(unit))
if (!payee.isEmpty()) {
// Get payee
SKGPayeeObject pa;
IFOKDO(err, SKGPayeeObject::createPayee(m_currentBankDocument, payee, pa, true))
IFOKDO(err, op.setPayee(pa))
}
IFOK(err) {
int pos1 = fileName.indexOf(QStringLiteral("{"));
int pos2 = fileName.indexOf(QStringLiteral("}"));
if (pos1 != -1 && pos2 > pos1) {
err = op.setImportID("KR-" % fileName.mid(pos1 + 1, pos2 - pos1 - 1));
}
}
IFOKDO(err, op.save())
// Add suboperation
SKGSubOperationObject sop;
IFOKDO(err, op.addSubOperation(sop))
IFOKDO(err, sop.setQuantity(-amount))
IFOKDO(err, sop.save())
// Finalize the importation
IFOK(err) {
bool automatic_validation = skgimportexport_settings::automatic_validation();
bool automatic_rule = skgimportexport_settings::apply_rules();
bool since_last = skgimportexport_settings::since_last_import();
SKGImportExportManager imp1(m_currentBankDocument);
imp1.setAutomaticValidation(automatic_validation);
imp1.setAutomaticApplyRules(automatic_rule);
imp1.setSinceLastImportDate(since_last);
err = imp1.finalizeImportation();
}
// Send message
IFOKDO(err, op.getDocument()->sendMessage(i18nc("An information to the user", "The operation '%1' has been added", op.getDisplayName()), SKGDocument::Hidden))
// Close file
file.close();
}
// status bar
IFOK(err) {
err = SKGError(0, i18nc("Message for successful user action", "Operations imported."));
QFile::remove(fileName);
} else {
err.addError(ERR_FAIL, i18nc("Error message", "Import failed"));
}
} else {
err = SKGError(0, i18nc("Message for successful user action", "Operations removed."));
QFile::remove(fileName);
}
// Display error
SKGMainPanel::displayErrorMessage(err);
return SKGError();
}
return SKGInterfacePlugin::executeAdviceCorrection(iAdviceIdentifier, iSolution);
}
#include <skgimportexportplugin.moc>
diff --git a/plugins/skrooge/skrooge_importexport/skgimportexportplugin.h b/plugins/skrooge/skrooge_importexport/skgimportexportplugin.h
index 56b914e0e..4c4ce4950 100644
--- a/plugins/skrooge/skrooge_importexport/skgimportexportplugin.h
+++ b/plugins/skrooge/skrooge_importexport/skgimportexportplugin.h
@@ -1,164 +1,164 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGIMPORTEXPORTPLUGIN_H
#define SKGIMPORTEXPORTPLUGIN_H
/** @file
* This file is Skrooge plugin for import and export operation.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgimportexportmanager.h"
#include "skginterfaceplugin.h"
#include "ui_skgimportexportpluginwidget_pref.h"
class QAction;
class SKGDocumentBank;
/**
* This file is Skrooge plugin for import and export operation
*/
class SKGImportExportPlugin : public SKGInterfacePlugin
{
Q_OBJECT
Q_INTERFACES(SKGInterfacePlugin)
public:
/**
* Default Constructor
*/
explicit SKGImportExportPlugin(QWidget* iWidget, QObject* iParent, const QVariantList& iArg);
/**
* Default Destructor
*/
~SKGImportExportPlugin() override;
/**
* Called to initialise the plugin
* @param iDocument the main document
* @return true if the plugin is compatible with the document
*/
bool setupActions(SKGDocument* iDocument) override;
/**
* This function is called when the application is launched again with new arguments
* @param iArgument the arguments
* @return the rest of arguments to treat
*/
QStringList processArguments(const QStringList& iArgument) override;
/**
* Must be modified to refresh widgets after a modification.
*/
void refresh() override;
/**
* The preference widget of the plugin.
* @return The preference widget of the plugin
*/
QWidget* getPreferenceWidget() override;
/**
* The preference skeleton of the plugin.
* @return The preference skeleton of the plugin
*/
KConfigSkeleton* getPreferenceSkeleton() override;
/**
* The title of the plugin.
* @return The title of the plugin
*/
QString title() const override;
/**
* The icon of the plugin.
* @return The icon of the plugin
*/
QString icon() const override;
/**
* The toolTip of the plugin.
* @return The toolTip of the plugin
*/
QString toolTip() const override;
/**
* Must be implemented to set the position of the plugin.
* @return integer value between 0 and 999 (default = 999)
*/
int getOrder() const override;
/**
* The tips list of the plugin.
* @return The tips list of the plugin
*/
QStringList tips() const override;
/**
* The sub plugins services types list of the plugin.
* This will be used to display authors in the "About" of the application
* @return The sub plugins list of the plugin
*/
QStringList subPlugins() const override;
/**
* The advice list of the plugin.
* @return The advice list of the plugin
*/
SKGAdviceList advice(const QStringList& iIgnoredAdvice) override;
/**
* Must be implemented to execute the automatic correction for the advice.
* @param iAdviceIdentifier the identifier of the advice
* @param iSolution the identifier of the possible solution
* @return an object managing the error. MUST return ERR_NOTIMPL if iAdviceIdentifier is not known
* @see SKGError
*/
SKGError executeAdviceCorrection(const QString& iAdviceIdentifier, int iSolution) override;
Q_SIGNALS:
/**
* Request to import a file
* @param iFile the file
*/
void importFileName(const QString& iFile);
private Q_SLOTS:
void importFile(const QString& iFile = QString(), bool iBlockOpenLastModified = false);
void importFiles(const QList<QUrl>& iFiles = QList<QUrl>(), int mode = 1, bool iBlockOpenLastModified = false); // 1=operations, 2=unit, 3=rules
SKGError importbackends();
void exportFile();
void findTransfers();
void anonymize();
void cleanBanks();
void swithvalidationImportedOperations();
void validateAllOperations();
void mergeImportedOperation();
void onInstall();
private:
Q_DISABLE_COPY(SKGImportExportPlugin)
void openLastModifiedIfSetting();
SKGDocumentBank* m_currentBankDocument;
QString m_docUniqueIdentifier;
Ui::skgimportexportplugin_pref ui{};
bool m_install;
};
#endif // SKGDEBUGPLUGIN_H
diff --git a/plugins/skrooge/skrooge_importexport/skgimportexportpluginwidget_pref.ui b/plugins/skrooge/skrooge_importexport/skgimportexportpluginwidget_pref.ui
index b2265b93d..520f02c0e 100644
--- a/plugins/skrooge/skrooge_importexport/skgimportexportpluginwidget_pref.ui
+++ b/plugins/skrooge/skrooge_importexport/skgimportexportpluginwidget_pref.ui
@@ -1,1100 +1,1100 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>skgimportexportplugin_pref</class>
<widget class="QWidget" name="skgimportexportplugin_pref">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>581</width>
<height>506</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<property name="spacing">
<number>2</number>
</property>
<item>
<widget class="QTabWidget" name="tabWidget">
<property name="currentIndex">
<number>3</number>
</property>
<widget class="QWidget" name="kGeneral">
<attribute name="title">
<string>General</string>
</attribute>
<attribute name="toolTip">
<string>General import settings</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_3">
<property name="spacing">
<number>2</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>After import</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="spacing">
<number>2</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QCheckBox" name="kcfg_apply_rules">
<property name="toolTip">
<string>This option allows to apply all rules defined in &quot;Search and process&quot; on all imported operations</string>
</property>
<property name="text">
<string>Apply rules on imported operations</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="kcfg_automatic_validation">
<property name="toolTip">
<string>This option allows to validate all imported operations</string>
</property>
<property name="text">
<string>Automatic validation</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="kcfg_open_after_import_or_processing">
<property name="toolTip">
<string>This option allows to open all imported operations at the end of the import</string>
</property>
<property name="text">
<string>Open operations</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="kcfg_since_last_import">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600; color:#ff0000;&quot;&gt;WARNING: &lt;/span&gt;In some conditions, this option can cause missing operations. &lt;/p&gt;&lt;p&gt;This option is mainly interesting with OFX import when your bank is not able to generate real unique identifier for operations.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Import only operations since the last imported one (not recommended)</string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer_4">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="kCsv">
<attribute name="title">
<string notr="true">CSV</string>
</attribute>
<attribute name="toolTip">
<string>Settings for CSV import</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_5">
<property name="spacing">
<number>2</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QScrollArea" name="scrollArea">
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="widgetResizable">
<bool>true</bool>
</property>
<widget class="QWidget" name="scrollAreaWidgetContents">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>541</width>
<height>883</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_4">
<property name="spacing">
<number>2</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<layout class="QGridLayout" name="gridLayout_3">
<property name="spacing">
<number>2</number>
</property>
<item row="2" column="0" colspan="3">
<widget class="QFrame" name="kHeaderPositionFrm">
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QGridLayout" name="gridLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="enabled">
<bool>true</bool>
</property>
<property name="text">
<string>Header position:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QSpinBox" name="kcfg_header_position">
<property name="enabled">
<bool>true</bool>
</property>
<property name="focusPolicy">
<enum>Qt::WheelFocus</enum>
</property>
<property name="minimum">
<number>0</number>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QLabel" name="label_7">
<property name="text">
<string>0 if CSV file does not have header</string>
</property>
</widget>
</item>
<item row="0" column="3">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>0</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="kcfg_automatic_search_header">
<property name="text">
<string>Automatic search of the header</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QCheckBox" name="kcfg_automatic_search_columns">
<property name="text">
<string>Automatic search of the columns</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="5" column="0" colspan="3">
<widget class="QFrame" name="kCsvMappingFrm">
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QGridLayout" name="gridLayout_4">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<property name="spacing">
<number>2</number>
</property>
<item row="1" column="0">
<widget class="QLabel" name="kDateLbl">
<property name="font">
<font>
<underline>true</underline>
</font>
</property>
<property name="toolTip">
<string>Date of the operation</string>
</property>
<property name="statusTip">
<string>Date of the operation</string>
</property>
<property name="text">
<string>Date:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>kcfg_mapping_date</cstring>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="kNumberLbl">
<property name="toolTip">
<string>Number of the operation, for example the Check number, or a Transfer reference.</string>
</property>
<property name="statusTip">
<string>Number of the operation</string>
</property>
<property name="text">
<string>Number:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>kcfg_mapping_number</cstring>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="kTypeLabel">
<property name="toolTip">
<string>Operation mode (how you made the operation).
Examples: Credit Card, Check, Transfer...
</string>
</property>
<property name="statusTip">
<string>Operation mode</string>
</property>
<property name="text">
<string comment="Noun, the mode used for payment of the operation (Credit Card, Cheque, Transfer...)">Mode:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>kcfg_mapping_mode</cstring>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="kPayeeLabel">
<property name="toolTip">
<string>Payee of the operation</string>
</property>
<property name="statusTip">
<string>Payee of the operation</string>
</property>
<property name="text">
<string comment="Noun, a person or institution receiving a payment, or paying the operation">Pa&amp;yee:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>kcfg_mapping_payee</cstring>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="kCommentLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>Comment of the operation</string>
</property>
<property name="statusTip">
<string>Comment of the operation</string>
</property>
<property name="text">
<string comment="Noun, a user comment on an item">Comment:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>kcfg_mapping_comment</cstring>
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QLabel" name="kStatusLbl">
<property name="toolTip">
<string>Status of the operation (reconciled or not)</string>
</property>
<property name="statusTip">
<string>Status of the operation</string>
</property>
<property name="text">
<string>Status:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>kcfg_mapping_status</cstring>
</property>
</widget>
</item>
<item row="7" column="0">
<widget class="QLabel" name="kBookmarkedLbl">
<property name="toolTip">
<string>Bookmark of the operation</string>
</property>
<property name="statusTip">
<string>Bookmark of the operation</string>
</property>
<property name="text">
<string>Boo&amp;kmarked:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>kcfg_mapping_bookmarked</cstring>
</property>
</widget>
</item>
<item row="8" column="0">
<widget class="QLabel" name="kAccountLabel">
<property name="toolTip">
<string>Account of the operation</string>
</property>
<property name="statusTip">
<string>Account of the operation</string>
</property>
<property name="text">
<string comment="Noun, an account as in a bank account">Account:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>kcfg_mapping_account</cstring>
</property>
</widget>
</item>
<item row="9" column="0">
<widget class="QLabel" name="kCategoryLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>Category of the operation</string>
</property>
<property name="statusTip">
<string>Category of the operation</string>
</property>
<property name="text">
<string comment="Noun, the category of an item">Category:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>kcfg_mapping_category</cstring>
</property>
</widget>
</item>
<item row="10" column="0">
<widget class="QLabel" name="kAmountLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<underline>true</underline>
</font>
</property>
<property name="toolTip">
<string>Amount of the operation</string>
</property>
<property name="statusTip">
<string>Amount of the operation</string>
</property>
<property name="text">
<string comment="Noun, a numerical quantity">Amount:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>kcfg_mapping_amount</cstring>
</property>
</widget>
</item>
<item row="11" column="0">
<widget class="QLabel" name="kQuantityLbl">
<property name="toolTip">
<string>Amount of the operation</string>
</property>
<property name="statusTip">
<string>Amount of the operation</string>
</property>
<property name="text">
<string>Quantity:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>kcfg_mapping_quantity</cstring>
</property>
</widget>
</item>
<item row="12" column="0">
<widget class="QLabel" name="kSignLbl">
<property name="toolTip">
<string>Sign of the operation</string>
</property>
<property name="statusTip">
<string>Sign of the operation</string>
</property>
<property name="text">
<string>Sign:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>kcfg_mapping_sign</cstring>
</property>
</widget>
</item>
<item row="13" column="0">
<widget class="QLabel" name="kUnitLbl">
<property name="toolTip">
<string>Unit of the operation</string>
</property>
<property name="statusTip">
<string>Unit of the operation</string>
</property>
<property name="text">
<string>Unit:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>kcfg_mapping_unit</cstring>
</property>
</widget>
</item>
<item row="14" column="0">
<widget class="QLabel" name="kidtransaction">
<property name="statusTip">
<string>Id to join all operations as a split operation</string>
</property>
<property name="whatsThis">
<string>Id to join all operations as a split operation</string>
</property>
<property name="text">
<string>Idtransaction:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>kcfg_mapping_idtransaction</cstring>
</property>
</widget>
</item>
<item row="15" column="0">
<widget class="QLabel" name="label_8">
<property name="statusTip">
<string>Id to join all operations as a transfer</string>
</property>
<property name="whatsThis">
<string>Id to join all operations as a transfer</string>
</property>
<property name="text">
<string>Idgroup:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>kcfg_mapping_idgroup</cstring>
</property>
</widget>
</item>
<item row="16" column="0">
<widget class="QLabel" name="label_9">
<property name="statusTip">
<string>To identify column to import as properties</string>
</property>
<property name="whatsThis">
<string>To identify column to import as properties</string>
</property>
<property name="text">
<string>Property:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>kcfg_mapping_property</cstring>
</property>
</widget>
</item>
<item row="0" column="0" colspan="2">
<widget class="QLabel" name="label_6">
<property name="text">
- <string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
+ <string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;https://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'DejaVu Sans'; font-size:8pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;You have to define &lt;a href=&quot;http://en.wikipedia.org/wiki/Regular_expression&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0057ae;&quot;&gt;regular expression&lt;/span&gt;&lt;/a&gt; allowing to automatically map each attribute.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="openExternalLinks">
<bool>true</bool>
</property>
</widget>
</item>
<item row="12" column="1">
<widget class="QLineEdit" name="kcfg_mapping_sign"/>
</item>
<item row="11" column="1">
<widget class="QLineEdit" name="kcfg_mapping_quantity"/>
</item>
<item row="10" column="1">
<widget class="QLineEdit" name="kcfg_mapping_amount"/>
</item>
<item row="9" column="1">
<widget class="QLineEdit" name="kcfg_mapping_category"/>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="kcfg_mapping_date"/>
</item>
<item row="2" column="1">
<widget class="QLineEdit" name="kcfg_mapping_number"/>
</item>
<item row="13" column="1">
<widget class="QLineEdit" name="kcfg_mapping_unit"/>
</item>
<item row="14" column="1">
<widget class="QLineEdit" name="kcfg_mapping_idtransaction"/>
</item>
<item row="15" column="1">
<widget class="QLineEdit" name="kcfg_mapping_idgroup"/>
</item>
<item row="16" column="1">
<widget class="QLineEdit" name="kcfg_mapping_property"/>
</item>
<item row="8" column="1">
<widget class="QLineEdit" name="kcfg_mapping_account"/>
</item>
<item row="7" column="1">
<widget class="QLineEdit" name="kcfg_mapping_bookmarked"/>
</item>
<item row="6" column="1">
<widget class="QLineEdit" name="kcfg_mapping_status"/>
</item>
<item row="5" column="1">
<widget class="QLineEdit" name="kcfg_mapping_comment"/>
</item>
<item row="4" column="1">
<widget class="QLineEdit" name="kcfg_mapping_payee"/>
</item>
<item row="3" column="1">
<widget class="QLineEdit" name="kcfg_mapping_mode"/>
</item>
</layout>
</widget>
</item>
<item row="7" column="0" colspan="3">
<widget class="QFrame" name="kColumnsPositionsFrm">
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<property name="spacing">
<number>2</number>
</property>
<item row="0" column="0">
<widget class="QLabel" name="label_2">
<property name="enabled">
<bool>true</bool>
</property>
<property name="text">
<string>Column positions:</string>
</property>
<property name="buddy">
<cstring>kcfg_columns_positions</cstring>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="kcfg_columns_positions"/>
</item>
<item row="1" column="0" colspan="3">
<widget class="QLabel" name="kLabelColumns">
<property name="font">
<font>
<italic>true</italic>
</font>
</property>
<property name="text">
- <string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
+ <string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;https://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'DejaVu Sans'; font-size:9pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; Must be a string containing following key words separated by &lt;span style=&quot; font-weight:600;&quot;&gt;|&lt;/span&gt;:&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
</item>
<item row="2" column="0" colspan="2">
<widget class="QLabel" name="label_3">
<property name="text">
- <string notr="true">&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
+ <string notr="true">&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;https://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'DejaVu Sans'; font-size:8pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:9pt;&quot;&gt; &lt;/span&gt;&lt;span style=&quot; font-size:9pt; text-decoration: underline;&quot;&gt;date,&lt;/span&gt;&lt;span style=&quot; font-size:9pt;&quot;&gt; number, mode, payee, comment, status, &lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:9pt;&quot;&gt; bookmarked, account, category, &lt;/span&gt;&lt;span style=&quot; font-size:9pt; text-decoration: underline;&quot;&gt;amount,&lt;/span&gt;&lt;span style=&quot; font-size:9pt;&quot;&gt; quantity, sign, unit, idtransaction, idgroup&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
</item>
<item row="3" column="0" colspan="2">
<widget class="QLabel" name="label_4">
<property name="text">
- <string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
+ <string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;https://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'DejaVu Sans'; font-size:8pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:9pt;&quot;&gt; &lt;/span&gt;&lt;span style=&quot; font-size:9pt;&quot;&gt;or nothing to ignore the column&lt;/span&gt;&lt;span style=&quot; font-size:9pt;&quot;&gt; &lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:9pt;&quot;&gt; or anything else to import the column as a property.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:9pt;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:9pt;&quot;&gt; &lt;/span&gt;&lt;span style=&quot; font-size:9pt; text-decoration: underline;&quot;&gt;Example:&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
</item>
<item row="4" column="0" colspan="2">
<widget class="QLabel" name="label_5">
<property name="text">
<string notr="true">date|mode|payee|comment||amount|status|my_property</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="3" column="1">
<widget class="QPushButton" name="More">
<property name="enabled">
<bool>true</bool>
</property>
<property name="text">
<string>Edit regular expressions...</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
</widget>
</item>
<item row="8" column="0" colspan="3">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="kSignLbl_2">
<property name="toolTip">
<string>How to identify a debit</string>
</property>
<property name="statusTip">
<string>How to identify a debit</string>
</property>
<property name="text">
<string>Debit values of &quot;sign&quot; column:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>kcfg_mapping_debit</cstring>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="kcfg_mapping_debit"/>
</item>
</layout>
</item>
<item row="9" column="0">
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item row="3" column="2">
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>0</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_12">
<property name="text">
<string>Date format:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>kcfg_csv_date_format</cstring>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="SKGComboBox" name="kcfg_csv_date_format"/>
</item>
</layout>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="kQif">
<attribute name="title">
<string notr="true">QIF</string>
</attribute>
<attribute name="toolTip">
<string>Settings for QIF import</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_6">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<property name="spacing">
<number>2</number>
</property>
<item row="0" column="0">
<widget class="QLabel" name="label_11">
<property name="text">
<string>Date format:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>kcfg_qif_date_format</cstring>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="SKGComboBox" name="kcfg_qif_date_format"/>
</item>
<item row="0" column="2">
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>388</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="0">
<spacer name="verticalSpacer_3">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<widget class="QWidget" name="kBackends">
<attribute name="title">
<string>Backends</string>
</attribute>
<attribute name="toolTip">
<string>Settings for import by backends</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_5">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<property name="spacing">
<number>2</number>
</property>
<item row="1" column="1">
<widget class="QLineEdit" name="kcfg_backends"/>
</item>
<item row="3" column="0">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="0" colspan="2">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="spacing">
<number>2</number>
</property>
<item>
<widget class="QCheckBox" name="kcfg_download_on_open">
<property name="text">
<string>Download on open</string>
</property>
</widget>
</item>
<item>
<widget class="KComboBox" name="kcfg_download_frequency">
<property name="enabled">
<bool>false</bool>
</property>
<item>
<property name="text">
<string>Once a day</string>
</property>
</item>
<item>
<property name="text">
<string>Once a week</string>
</property>
</item>
<item>
<property name="text">
<string>Once a month</string>
</property>
</item>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_4">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_10">
<property name="text">
<string>List of bac&amp;kends used:</string>
</property>
<property name="buddy">
<cstring>kcfg_backends</cstring>
</property>
</widget>
</item>
<item row="2" column="0" colspan="2">
<widget class="QLabel" name="kbackendText">
<property name="text">
<string/>
</property>
<property name="textFormat">
<enum>Qt::RichText</enum>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>SKGComboBox</class>
<extends>QComboBox</extends>
<header>skgcombobox.h</header>
</customwidget>
<customwidget>
<class>KComboBox</class>
<extends>QComboBox</extends>
<header>kcombobox.h</header>
</customwidget>
</customwidgets>
<tabstops>
<tabstop>tabWidget</tabstop>
<tabstop>scrollArea</tabstop>
<tabstop>kcfg_csv_date_format</tabstop>
<tabstop>kcfg_automatic_search_header</tabstop>
<tabstop>kcfg_header_position</tabstop>
<tabstop>kcfg_automatic_search_columns</tabstop>
<tabstop>More</tabstop>
<tabstop>kcfg_mapping_date</tabstop>
<tabstop>kcfg_mapping_number</tabstop>
<tabstop>kcfg_mapping_mode</tabstop>
<tabstop>kcfg_mapping_payee</tabstop>
<tabstop>kcfg_mapping_comment</tabstop>
<tabstop>kcfg_mapping_status</tabstop>
<tabstop>kcfg_mapping_bookmarked</tabstop>
<tabstop>kcfg_mapping_account</tabstop>
<tabstop>kcfg_mapping_category</tabstop>
<tabstop>kcfg_mapping_amount</tabstop>
<tabstop>kcfg_mapping_quantity</tabstop>
<tabstop>kcfg_mapping_sign</tabstop>
<tabstop>kcfg_mapping_unit</tabstop>
<tabstop>kcfg_mapping_idtransaction</tabstop>
<tabstop>kcfg_mapping_idgroup</tabstop>
<tabstop>kcfg_mapping_property</tabstop>
<tabstop>kcfg_columns_positions</tabstop>
<tabstop>kcfg_mapping_debit</tabstop>
<tabstop>kcfg_since_last_import</tabstop>
<tabstop>kcfg_qif_date_format</tabstop>
<tabstop>kcfg_open_after_import_or_processing</tabstop>
<tabstop>kcfg_apply_rules</tabstop>
<tabstop>kcfg_automatic_validation</tabstop>
</tabstops>
<resources/>
<connections/>
</ui>
diff --git a/plugins/skrooge/skrooge_operation/CMakeLists.txt b/plugins/skrooge/skrooge_operation/CMakeLists.txt
index 82bd46c15..570e30c9f 100644
--- a/plugins/skrooge/skrooge_operation/CMakeLists.txt
+++ b/plugins/skrooge/skrooge_operation/CMakeLists.txt
@@ -1,41 +1,41 @@
#***************************************************************************
#* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
#* *
#* 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 <http://www.gnu.org/licenses/> *
+#* along with this program. If not, see <https://www.gnu.org/licenses/> *
#***************************************************************************
MESSAGE( STATUS "..:: CMAKE PLUGIN_OPERATION ::..")
PROJECT(plugin_operation)
LINK_DIRECTORIES (${LIBRARY_OUTPUT_PATH})
SET(skrooge_operation_SRCS
skgsplittabledelegate.cpp
skgoperationplugin.cpp
skgoperationpluginwidget.cpp
skgoperationboardwidget.cpp
skgoperationboardwidgetqml.cpp
)
ki18n_wrap_ui(skrooge_operation_SRCS skgoperationpluginwidget_base.ui skgoperationpluginwidget_pref.ui skgoperationpluginwidget_board.ui )
kconfig_add_kcfg_files(skrooge_operation_SRCS skgoperation_settings.kcfgc )
ADD_LIBRARY(skrooge_operation MODULE ${skrooge_operation_SRCS})
TARGET_LINK_LIBRARIES(skrooge_operation KF5::Parts KF5::ItemViews skgbasemodeler skgbasegui skgbankmodeler skgbankgui)
########### install files ###############
INSTALL(TARGETS skrooge_operation DESTINATION ${KDE_INSTALL_QTPLUGINDIR})
INSTALL(FILES ${PROJECT_SOURCE_DIR}/org.kde.skrooge-plugin-operation.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR})
INSTALL(FILES ${PROJECT_SOURCE_DIR}/skrooge_operation.rc DESTINATION ${KDE_INSTALL_KXMLGUI5DIR}/skrooge_operation )
INSTALL(FILES ${PROJECT_SOURCE_DIR}/skgoperation_settings.kcfg DESTINATION ${KDE_INSTALL_KCFGDIR} )
diff --git a/plugins/skrooge/skrooge_operation/org.kde.skrooge-plugin-operation.desktop b/plugins/skrooge/skrooge_operation/org.kde.skrooge-plugin-operation.desktop
index c4b7725bd..a178ddbde 100644
--- a/plugins/skrooge/skrooge_operation/org.kde.skrooge-plugin-operation.desktop
+++ b/plugins/skrooge/skrooge_operation/org.kde.skrooge-plugin-operation.desktop
@@ -1,75 +1,75 @@
[Desktop Entry]
Name=Skrooge operation plugin
Name[bs]=Skrooge dodatak za operacije
Name[ca]=Connector d'operacions de l'Skrooge
Name[ca@valencia]=Connector d'operacions de l'Skrooge
Name[cs]=Modul operací pro Skrooge
Name[da]=Operation-plugin til Skrooge
Name[de]=Skrooge-Vorgangsmodul
Name[el]=Skrooge operation plugin
Name[en_GB]=Skrooge operation plugin
Name[es]=Complemento de operaciones de Skrooge
Name[et]=Skrooge tehinguplugin
Name[fi]=Skroogen tapahtumaliitännäinen
Name[fr]=Module externe de gestion des opérations
Name[gl]=Complemento de operacións de Skrooge
Name[hu]=Skrooge művelet bővítmény
Name[it]=Estensione per le operazioni di Skrooge
Name[lt]=Skrooge operacijų papildinys
Name[nb]=Skrooge operasjonsmodul
Name[nds]=Akschoonmoduul för Skrooge
Name[nl]=Plugin voor Skrooge-bewerking
Name[pl]=Wtyczka operacji dla Skrooge
Name[pt]='Plugin' de operações do Skrooge
Name[pt_BR]=Plugin de operação do Skrooge
Name[ru]=Модуль операций
Name[sk]=Plugin operácií Skrooge
Name[sv]=Skrooge åtgärdsinsticksprogram
Name[tr]=Skrooge işlem eklentisi
Name[uk]=Додаток операцій Skrooge
Name[x-test]=xxSkrooge operation pluginxx
Name[zh_TW]=Skrooge 操作外掛程式
Comment=A skrooge plugin to manage operations
Comment[bs]=Skrooge dodatak za upravljanje operacijama
Comment[ca]=Un connector de l'Skrooge per gestionar operacions
Comment[ca@valencia]=Un connector de l'Skrooge per gestionar operacions
Comment[cs]=Modul správy operací pro Skrooge
Comment[da]=Et Skrooge-plugin til at håndtere operationer
Comment[de]=Ein Skrooge-Modul zum Verwalten von Vorgängen
Comment[el]=Ένα πρόσθετο του skrooge για τη διαχείριση λειτουργιών
Comment[en_GB]=A skrooge plugin to manage operations
Comment[es]=Complemento de Skrooge para gestionar operaciones
Comment[et]=Skrooge tehingute haldamise plugin
Comment[fi]=Skroogen tapahtumahallinnan liitännäinen
Comment[fr]=Un module externe Skrooge pour la gestion des opérations
Comment[gl]=Un complemento de Skrooge para xestionar operacións.
Comment[hu]=Egy Skrooge bővítmény műveletek kezeléséhez
Comment[it]=Un'estensione di Skrooge per gestire le operazioni
Comment[lt]=Skrooge operacijų tvarkymo papildinys
Comment[nb]=En Skrooge-modul for å håndtere operasjoner
Comment[nl]=Een skrooge-plugin voor het beheren van bewerkingen
Comment[pl]=Wtyczka Skrooge do obsługi operacji
Comment[pt]=Um 'plugin' do Skrooge para gerir as operações
Comment[pt_BR]=Um plugin do Skrooge para gerenciar operações
Comment[ru]=Модуль управления операциями
Comment[sk]=Plugin Skrooge na správu operácií
Comment[sv]=Ett insticksprogram till Skrooge för att hantera schemalagda ärenden
Comment[tr]=İşlemleri yönetmek için bir skrooge eklentisi
Comment[uk]=Додаток до skrooge для керування операціями
Comment[x-test]=xxA skrooge plugin to manage operationsxx
Comment[zh_TW]=管理操作用的 Skrooge 外掛程式
Encoding=UTF-8
Icon=skrooge
Type=Service
X-KDE-ServiceTypes=SKG GUI/Plugin
X-KDE-Library=skrooge_operation
X-Krunner-ID=Skrooge operation plugin
X-KDE-PluginInfo-Author=Stephane MANKOWSKI,miraks
X-KDE-PluginInfo-Email=stephane@mankowski.fr
X-KDE-PluginInfo-Name=skrooge_operation
X-KDE-PluginInfo-Version=1.0
-X-KDE-PluginInfo-Website=http://skrooge.org/
+X-KDE-PluginInfo-Website=https://skrooge.org/
X-KDE-PluginInfo-Category=Plugins
X-KDE-PluginInfo-Depends=
X-KDE-PluginInfo-License=GPL
X-KDE-PluginInfo-EnabledByDefault=true
diff --git a/plugins/skrooge/skrooge_operation/skgoperationboardwidget.cpp b/plugins/skrooge/skrooge_operation/skgoperationboardwidget.cpp
index 93bfb7eb6..d66ce14f6 100644
--- a/plugins/skrooge/skrooge_operation/skgoperationboardwidget.cpp
+++ b/plugins/skrooge/skrooge_operation/skgoperationboardwidget.cpp
@@ -1,388 +1,388 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is Skrooge plugin for operation management.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgoperationboardwidget.h"
#include <qdom.h>
#include <qparallelanimationgroup.h>
#include <qpropertyanimation.h>
#include <qaction.h>
#include <qwidgetaction.h>
#include <kcolorscheme.h>
#include "skgdocumentbank.h"
#include "skgmainpanel.h"
#include "skgobjectbase.h"
#include "skgperiodedit.h"
#include "skgreportbank.h"
#include "skgservices.h"
#include "skgtraces.h"
SKGOperationBoardWidget::SKGOperationBoardWidget(QWidget* iParent, SKGDocument* iDocument)
: SKGBoardWidget(iParent, iDocument, i18nc("Dashboard widget title", "Income & Expenditure")),
m_periodEdit1(nullptr), m_periodEdit2(nullptr), m_anim(nullptr)
{
SKGTRACEINFUNC(10)
m_timer.setSingleShot(true);
connect(&m_timer, &QTimer::timeout, this, [ = ]() {
this->dataModified();
}, Qt::QueuedConnection);
// Initialize animation group
m_anim = new QParallelAnimationGroup(this);
auto f = new QFrame();
ui.setupUi(f);
setMainWidget(f);
KColorScheme scheme(QPalette::Normal, KColorScheme::Window);
auto color = scheme.foreground(KColorScheme::NormalText).color().name().right(6);
ui.kIncomeLabel->setText("<a href=\"IC\" style=\"color: #" % color % "\">" % ui.kIncomeLabel->text() % "</a>");
ui.kExpenseLabel->setText("<a href=\"EC\" style=\"color: #" % color % "\">" % ui.kExpenseLabel->text() % "</a>");
ui.kSavingLabel->setText("<a href=\"SC\" style=\"color: #" % color % "\">" % ui.kSavingLabel->text() % "</a>");
ui.kIncome_previousLabel->setText("<a href=\"IP\" style=\"color: #" % color % "\">" % ui.kIncome_previousLabel->text() % "</a>");
ui.kExpense_previousLabel->setText("<a href=\"EP\" style=\"color: #" % color % "\">" % ui.kExpense_previousLabel->text() % "</a>");
ui.kSaving_previousLabel->setText("<a href=\"SP\" style=\"color: #" % color % "\">" % ui.kSaving_previousLabel->text() % "</a>");
connect(ui.kIncomeLabel, &QLabel::linkActivated, this, &SKGOperationBoardWidget::onOpen);
connect(ui.kExpenseLabel, &QLabel::linkActivated, this, &SKGOperationBoardWidget::onOpen);
connect(ui.kSavingLabel, &QLabel::linkActivated, this, &SKGOperationBoardWidget::onOpen);
connect(ui.kIncome_previousLabel, &QLabel::linkActivated, this, &SKGOperationBoardWidget::onOpen);
connect(ui.kExpense_previousLabel, &QLabel::linkActivated, this, &SKGOperationBoardWidget::onOpen);
connect(ui.kSaving_previousLabel, &QLabel::linkActivated, this, &SKGOperationBoardWidget::onOpen);
// Create menu
setContextMenuPolicy(Qt::ActionsContextMenu);
QStringList overlayopen;
overlayopen.push_back(QStringLiteral("quickopen"));
m_menuOpen = new QAction(SKGServices::fromTheme(QStringLiteral("view-statistics"), overlayopen), i18nc("Verb", "Open report..."), this);
connect(m_menuOpen, &QAction::triggered, SKGMainPanel::getMainPanel(), [ = ]() {
SKGMainPanel::getMainPanel()->SKGMainPanel::openPage();
});
addAction(m_menuOpen);
{
auto sep = new QAction(this);
sep->setSeparator(true);
addAction(sep);
}
m_menuGroup = new QAction(i18nc("Noun, a type of operations", "Grouped"), this);
m_menuGroup->setCheckable(true);
m_menuGroup->setChecked(false);
connect(m_menuGroup, &QAction::triggered, this, &SKGOperationBoardWidget::refreshDelayed);
addAction(m_menuGroup);
m_menuTransfer = new QAction(i18nc("Noun, a type of operations", "Transfers"), this);
m_menuTransfer->setCheckable(true);
m_menuTransfer->setChecked(false);
connect(m_menuTransfer, &QAction::triggered, this, &SKGOperationBoardWidget::refreshDelayed);
addAction(m_menuTransfer);
connect(m_menuGroup, &QAction::toggled, m_menuTransfer, &QAction::setEnabled);
m_menuTracked = new QAction(i18nc("Noun, a type of operations", "Tracked"), this);
m_menuTracked->setCheckable(true);
m_menuTracked->setChecked(true);
connect(m_menuTracked, &QAction::triggered, this, &SKGOperationBoardWidget::refreshDelayed);
addAction(m_menuTracked);
m_menuSuboperation = new QAction(i18nc("Noun, a type of operations", "On suboperations"), this);
m_menuSuboperation->setCheckable(true);
m_menuSuboperation->setChecked(false);
connect(m_menuSuboperation, &QAction::triggered, this, &SKGOperationBoardWidget::refreshDelayed);
addAction(m_menuSuboperation);
{
auto sep = new QAction(this);
sep->setSeparator(true);
addAction(sep);
}
m_periodEdit1 = new SKGPeriodEdit(this, true);
m_periodEdit1->setObjectName(QStringLiteral("m_periodEdit1"));
{
// Set default
QDomDocument doc(QStringLiteral("SKGML"));
QDomElement root = doc.createElement(QStringLiteral("parameters"));
doc.appendChild(root);
root.setAttribute(QStringLiteral("period"), SKGServices::intToString(static_cast<int>(SKGPeriodEdit::CURRENT)));
m_periodEdit1->setState(doc.toString());
// Add widget in menu
auto periodEditWidget = new QWidgetAction(this);
periodEditWidget->setObjectName(QStringLiteral("m_periodEdit1Action"));
periodEditWidget->setDefaultWidget(m_periodEdit1);
addAction(periodEditWidget);
}
{
auto sep = new QAction(this);
sep->setSeparator(true);
addAction(sep);
}
m_periodEdit2 = new SKGPeriodEdit(this, true);
m_periodEdit2->setObjectName(QStringLiteral("m_periodEdit2"));
{
// Set default
QDomDocument doc(QStringLiteral("SKGML"));
QDomElement root = doc.createElement(QStringLiteral("parameters"));
doc.appendChild(root);
root.setAttribute(QStringLiteral("period"), SKGServices::intToString(static_cast<int>(SKGPeriodEdit::PREVIOUS)));
m_periodEdit2->setState(doc.toString());
// Add widget in menu
auto periodEditWidget = new QWidgetAction(this);
periodEditWidget->setObjectName(QStringLiteral("m_periodEdit2Action"));
periodEditWidget->setDefaultWidget(m_periodEdit2);
addAction(periodEditWidget);
}
// Refresh
connect(m_periodEdit1, &SKGPeriodEdit::changed, this, &SKGOperationBoardWidget::refreshDelayed, Qt::QueuedConnection);
connect(m_periodEdit2, &SKGPeriodEdit::changed, this, &SKGOperationBoardWidget::refreshDelayed, Qt::QueuedConnection);
connect(getDocument(), &SKGDocument::tableModified, this, &SKGOperationBoardWidget::dataModified, Qt::QueuedConnection);
}
SKGOperationBoardWidget::~SKGOperationBoardWidget()
{
SKGTRACEINFUNC(10)
m_menuGroup = nullptr;
m_menuTransfer = nullptr;
m_menuTracked = nullptr;
m_anim = nullptr;
}
QString SKGOperationBoardWidget::getState()
{
QDomDocument doc(QStringLiteral("SKGML"));
doc.setContent(SKGBoardWidget::getState());
QDomElement root = doc.documentElement();
root.setAttribute(QStringLiteral("menuGroup"), (m_menuGroup != nullptr) && m_menuGroup->isChecked() ? QStringLiteral("Y") : QStringLiteral("N"));
root.setAttribute(QStringLiteral("menuTransfert"), (m_menuTransfer != nullptr) && m_menuTransfer->isChecked() ? QStringLiteral("Y") : QStringLiteral("N"));
root.setAttribute(QStringLiteral("menuTracked"), (m_menuTracked != nullptr) && m_menuTracked->isChecked() ? QStringLiteral("Y") : QStringLiteral("N"));
root.setAttribute(QStringLiteral("menuSuboperation"), (m_menuSuboperation != nullptr) && m_menuSuboperation->isChecked() ? QStringLiteral("Y") : QStringLiteral("N"));
root.setAttribute(QStringLiteral("period1"), m_periodEdit1 != nullptr ? m_periodEdit1->getState() : QLatin1String(""));
root.setAttribute(QStringLiteral("period2"), m_periodEdit2 != nullptr ? m_periodEdit2->getState() : QLatin1String(""));
return doc.toString();
}
void SKGOperationBoardWidget::setState(const QString& iState)
{
SKGBoardWidget::setState(iState);
QDomDocument doc(QStringLiteral("SKGML"));
doc.setContent(iState);
QDomElement root = doc.documentElement();
if (m_menuGroup != nullptr) {
QString val = root.attribute(QStringLiteral("menuGroup"));
if (val.isEmpty()) {
val = root.attribute(QStringLiteral("menuTransfert"));
}
m_menuGroup->setChecked(val == QStringLiteral("Y"));
}
if (m_menuTransfer != nullptr) {
m_menuTransfer->setChecked(root.attribute(QStringLiteral("menuTransfert")) == QStringLiteral("Y"));
}
if (m_menuTracked != nullptr) {
m_menuTracked->setChecked(root.attribute(QStringLiteral("menuTracked")) != QStringLiteral("N"));
}
if (m_menuSuboperation != nullptr) {
m_menuSuboperation->setChecked(root.attribute(QStringLiteral("menuSuboperation")) == QStringLiteral("Y"));
}
QString period1 = root.attribute(QStringLiteral("period1"));
if ((m_periodEdit1 != nullptr) && !period1.isEmpty()) {
m_periodEdit1->setState(period1);
}
QString period2 = root.attribute(QStringLiteral("period2"));
if ((m_periodEdit2 != nullptr) && !period2.isEmpty()) {
m_periodEdit2->setState(period2);
}
refreshDelayed();
}
void SKGOperationBoardWidget::onOpen(const QString& iLink)
{
bool onSubOperation = ((m_menuSuboperation != nullptr) && m_menuSuboperation->isChecked());
// Call operation plugin
QString wc;
if (iLink.endsWith(QLatin1String("C"))) {
wc = m_periodEdit1->getWhereClause() % " AND t_TYPEACCOUNT<>'L'";
} else {
wc = m_periodEdit2->getWhereClause() % " AND t_TYPEACCOUNT<>'L'";
}
if (iLink.startsWith(QLatin1String("I"))) {
wc = wc % " AND t_TYPEEXPENSE='+'";
} else if (iLink.startsWith(QLatin1String("E"))) {
wc = wc % " AND t_TYPEEXPENSE='-'";
}
wc = wc % ((m_menuGroup != nullptr) && m_menuGroup->isChecked() ? "" : " AND i_group_id=0") % ((m_menuTransfer != nullptr) && m_menuTransfer->isChecked() ? "" : " AND t_TRANSFER='N'") % ((m_menuTracked != nullptr) && m_menuTracked->isChecked() ? "" : (onSubOperation ? " AND t_REALREFUND=''" : " AND t_REFUND=''"));
QString title;
if (iLink == QStringLiteral("IC")) {
title = i18nc("Title of a list of operations", "Incomes of %1", ui.kLabel->text());
} else if (iLink == QStringLiteral("EC")) {
title = i18nc("Title of a list of operations", "Expenses of %1", ui.kLabel->text());
} else if (iLink == QStringLiteral("SC")) {
title = i18nc("Title of a list of operations", "Savings of %1", ui.kLabel->text());
} else if (iLink == QStringLiteral("IP")) {
title = i18nc("Title of a list of operations", "Incomes of %1", ui.kLabel_previous->text());
} else if (iLink == QStringLiteral("EP")) {
title = i18nc("Title of a list of operations", "Expenses of %1", ui.kLabel_previous->text());
} else if (iLink == QStringLiteral("SP")) {
title = i18nc("Title of a list of operations", "Savings of %1", ui.kLabel_previous->text());
}
SKGMainPanel::getMainPanel()->openPage("skg://skrooge_operation_plugin/" % QString(onSubOperation ? QStringLiteral("SKGOPERATION_CONSOLIDATED_DEFAULT_PARAMETERS/") : QString()) % "?operationTable=" % SKGServices::encodeForUrl(onSubOperation ? QStringLiteral("v_suboperation_consolidated") : QStringLiteral("v_operation_display")) % "&title_icon=view-bank-account&currentPage=-1&title=" % SKGServices::encodeForUrl(title) %
"&operationWhereClause=" % SKGServices::encodeForUrl(wc));
}
void SKGOperationBoardWidget::refreshDelayed()
{
m_timer.start(300);
}
void SKGOperationBoardWidget::dataModified(const QString& iTableName, int iIdTransaction)
{
SKGTRACEINFUNC(10)
Q_UNUSED(iIdTransaction)
QString table = ((m_menuSuboperation != nullptr) && m_menuSuboperation->isChecked() ? QStringLiteral("v_suboperation_consolidated") : QStringLiteral("v_operation_display"));
if ((m_periodEdit1 != nullptr) && (m_periodEdit2 != nullptr) && (iTableName == table || iTableName.isEmpty())) {
// Set titles
ui.kLabel->setText(m_periodEdit1->text());
ui.kLabel_previous->setText(m_periodEdit2->text());
auto* doc = qobject_cast<SKGDocumentBank*>(getDocument());
if (doc != nullptr) {
if (m_menuOpen != nullptr) {
QString url = QStringLiteral("skg://skrooge_report_plugin/?grouped=") % ((m_menuGroup != nullptr) && m_menuGroup->isChecked() ? QStringLiteral("Y") : QStringLiteral("N")) % "&transfers="
% ((m_menuTransfer != nullptr) && m_menuTransfer->isChecked() ? QStringLiteral("Y") : QStringLiteral("N")) % "&tracked="
% ((m_menuTracked != nullptr) && m_menuTracked->isChecked() ? QStringLiteral("Y") : QStringLiteral("N")) % "&expenses=Y&incomes=Y&lines2=t_TYPEEXPENSENLS&columns=d_DATEMONTH&currentPage=-1" %
"&mode=0&interval=3&period=3" %
"&tableAndGraphState.graphMode=1&tableAndGraphState.allPositive=Y&tableAndGraphState.show=graph&title=" %
SKGServices::encodeForUrl(i18nc("Noun, the title of a section", "Income & Expenditure"));
m_menuOpen->setData(url);
}
SKGServices::SKGUnitInfo primary = doc->getPrimaryUnit();
SKGServices::SKGUnitInfo secondary = doc->getSecondaryUnit();
auto* bk = qobject_cast< SKGReportBank* >(doc->getReport());
if (bk != nullptr) {
QVariantList table2 = bk->getIncomeVsExpenditure((m_menuSuboperation != nullptr) && m_menuSuboperation->isChecked(),
(m_menuGroup != nullptr) && m_menuGroup->isChecked(),
(m_menuTransfer != nullptr) && m_menuTransfer->isChecked(),
(m_menuTracked != nullptr) && m_menuTracked->isChecked(),
m_periodEdit1->getWhereClause(),
m_periodEdit2->getWhereClause());
delete bk;
QVariantList l1 = table2.value(1).toList();
QVariantList l2 = table2.value(2).toList();
double income_previous_month = l1.value(2).toDouble();
double expense_previous_month = l2.value(2).toDouble();
double income_month = l1.value(3).toDouble();
double expense_month = l2.value(3).toDouble();
// Set Maximum
int max = qMax(income_previous_month, qMax(expense_previous_month, qMax(income_month, expense_month)));
if (max == 0) {
max = 100.0;
}
ui.kIncome->setMaximum(max);
ui.kIncome_previous->setMaximum(max);
ui.kExpense->setMaximum(max);
ui.kExpense_previous->setMaximum(max);
ui.kSaving->setMaximum(max);
ui.kSaving_previous->setMaximum(max);
// Set texts and tool tips
ui.kIncome->setFormat(doc->formatMoney(income_month, primary, false));
ui.kIncome_previous->setFormat(doc->formatMoney(income_previous_month, primary, false));
ui.kExpense->setFormat(doc->formatMoney(expense_month, primary, false));
ui.kExpense_previous->setFormat(doc->formatMoney(expense_previous_month, primary, false));
ui.kSaving->setFormat(doc->formatMoney(income_month - expense_month, primary, false));
ui.kSaving_previous->setFormat(doc->formatMoney(income_previous_month - expense_previous_month, primary, false));
if (!secondary.Symbol.isEmpty() && (secondary.Value != 0.0)) {
ui.kIncome->setToolTip(doc->formatMoney(income_month, secondary, false));
ui.kIncome_previous->setToolTip(doc->formatMoney(income_previous_month, secondary, false));
ui.kExpense->setToolTip(doc->formatMoney(expense_month, secondary, false));
ui.kExpense_previous->setToolTip(doc->formatMoney(expense_previous_month, secondary, false));
ui.kSaving->setToolTip(doc->formatMoney(income_month - expense_month, secondary, false));
ui.kSaving_previous->setToolTip(doc->formatMoney(income_previous_month - expense_previous_month, secondary, false));
}
// Change colors
ui.kIncome->setLimits(0, 0, max);
ui.kIncome_previous->setLimits(0, 0, max);
ui.kExpense->setLimits(max, -1, -1);
ui.kExpense_previous->setLimits(max, -1, -1);
ui.kSaving->setLimits(income_month - expense_month < 0 ? max : 0, 0.1 * income_month, max);
ui.kSaving_previous->setLimits(income_previous_month - expense_previous_month < 0 ? max : 0, 0.1 * income_previous_month, max);
// Set values
if (m_anim != nullptr) {
m_anim->clear();
}
SKGOperationBoardWidget::setValue(ui.kIncome, income_month);
SKGOperationBoardWidget::setValue(ui.kIncome_previous, income_previous_month);
SKGOperationBoardWidget::setValue(ui.kExpense, expense_month);
SKGOperationBoardWidget::setValue(ui.kExpense_previous, expense_previous_month);
SKGOperationBoardWidget::setValue(ui.kSaving, qAbs(income_month - expense_month));
SKGOperationBoardWidget::setValue(ui.kSaving_previous, qAbs(income_previous_month - expense_previous_month));
if (m_anim != nullptr) {
QTimer::singleShot(1000, Qt::CoarseTimer, m_anim, [ = ]() {
m_anim->start();
});
}
}
// No widget if no account
bool exist = false;
doc->existObjects(QStringLiteral("account"), QLatin1String(""), exist);
if (parentWidget() != nullptr) {
setVisible(exist);
}
}
}
}
void SKGOperationBoardWidget::setValue(SKGProgressBar* iWidget, double iValue)
{
if (m_anim != nullptr) {
auto panim = new QPropertyAnimation(iWidget, "value");
panim->setDuration(1000);
panim->setStartValue(0);
panim->setEndValue(static_cast<int>(iValue));
m_anim->addAnimation(panim);
} else {
iWidget->setValue(iValue);
}
}
diff --git a/plugins/skrooge/skrooge_operation/skgoperationboardwidget.h b/plugins/skrooge/skrooge_operation/skgoperationboardwidget.h
index cf7a14437..dc7be9123 100644
--- a/plugins/skrooge/skrooge_operation/skgoperationboardwidget.h
+++ b/plugins/skrooge/skrooge_operation/skgoperationboardwidget.h
@@ -1,94 +1,94 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGOPERATIONBOARDWIDGET_H
#define SKGOPERATIONBOARDWIDGET_H
/** @file
* This file is Skrooge plugin for operation management.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include <qtimer.h>
#include "skgboardwidget.h"
#include "ui_skgoperationpluginwidget_board.h"
class QAction;
class SKGPeriodEdit;
class QParallelAnimationGroup;
/**
* This file is Skrooge plugin for operation management
*/
class SKGOperationBoardWidget : public SKGBoardWidget
{
Q_OBJECT
public:
/**
* Default Constructor
* @param iParent the parent widget
* @param iDocument the document
*/
explicit SKGOperationBoardWidget(QWidget* iParent, SKGDocument* iDocument);
/**
* Default Destructor
*/
~SKGOperationBoardWidget() override;
/**
* Get the current state
* MUST BE OVERWRITTEN
* @return a string containing all information needed to set the same state.
* Could be an XML stream
*/
QString getState() override;
/**
* Set the current state
* MUST BE OVERWRITTEN
* @param iState must be interpreted to set the state of the widget
*/
void setState(const QString& iState) override;
private Q_SLOTS:
void refreshDelayed();
void dataModified(const QString& iTableName = QString(), int iIdTransaction = 0);
void onOpen(const QString& iLink);
private:
Q_DISABLE_COPY(SKGOperationBoardWidget)
void setValue(SKGProgressBar* iWidget, double iValue);
Ui::skgoperationplugin_board ui{};
QAction* m_menuOpen;
QAction* m_menuGroup;
QAction* m_menuTransfer;
QAction* m_menuTracked;
QAction* m_menuSuboperation;
SKGPeriodEdit* m_periodEdit1;
SKGPeriodEdit* m_periodEdit2;
QParallelAnimationGroup* m_anim;
QTimer m_timer;
};
#endif // SKGOPERATIONBOARDWIDGET_H
diff --git a/plugins/skrooge/skrooge_operation/skgoperationboardwidgetqml.cpp b/plugins/skrooge/skrooge_operation/skgoperationboardwidgetqml.cpp
index 9c08508ad..995ebe9f6 100644
--- a/plugins/skrooge/skrooge_operation/skgoperationboardwidgetqml.cpp
+++ b/plugins/skrooge/skrooge_operation/skgoperationboardwidgetqml.cpp
@@ -1,217 +1,217 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is Skrooge plugin for operation management.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgoperationboardwidgetqml.h"
#include <qdom.h>
#include <qaction.h>
#include <qqmlcontext.h>
#include <qquickwidget.h>
#include <qwidgetaction.h>
#include "skgdocumentbank.h"
#include "skgmainpanel.h"
#include "skgobjectbase.h"
#include "skgperiodedit.h"
#include "skgreportbank.h"
#include "skgservices.h"
#include "skgtraces.h"
SKGOperationBoardWidgetQml::SKGOperationBoardWidgetQml(QWidget* iParent, SKGDocument* iDocument)
: SKGHtmlBoardWidget(iParent, iDocument, i18nc("Dashboard widget title", "Income & Expenditure"),
QStandardPaths::locate(QStandardPaths::GenericDataLocation, QStringLiteral("skrooge/html/default/income_vs_expenditure.qml")), QStringList() << QStringLiteral("v_operation")),
m_periodEdit1(nullptr), m_periodEdit2(nullptr)
{
SKGTRACEINFUNC(10)
QStringList overlayopen;
overlayopen.push_back(QStringLiteral("quickopen"));
m_menuOpen = new QAction(SKGServices::fromTheme(QStringLiteral("view-statistics"), overlayopen), i18nc("Verb", "Open report..."), this);
connect(m_menuOpen, &QAction::triggered, SKGMainPanel::getMainPanel(), [ = ]() {
SKGMainPanel::getMainPanel()->SKGMainPanel::openPage();
});
addAction(m_menuOpen);
{
auto sep = new QAction(this);
sep->setSeparator(true);
addAction(sep);
}
m_menuGroup = new QAction(i18nc("Noun, a type of operations", "Grouped"), this);
m_menuGroup->setCheckable(true);
m_menuGroup->setChecked(false);
connect(m_menuGroup, &QAction::triggered, this, &SKGOperationBoardWidgetQml::settingsModified);
addAction(m_menuGroup);
m_Quick->rootContext()->setContextProperty(QStringLiteral("groupedWidget"), m_menuGroup);
m_menuTransfer = new QAction(i18nc("Noun, a type of operations", "Transfers"), this);
m_menuTransfer->setCheckable(true);
m_menuTransfer->setChecked(false);
connect(m_menuTransfer, &QAction::triggered, this, &SKGOperationBoardWidgetQml::settingsModified);
addAction(m_menuTransfer);
m_Quick->rootContext()->setContextProperty(QStringLiteral("transferWidget"), m_menuTransfer);
connect(m_menuGroup, &QAction::toggled, m_menuTransfer, &QAction::setEnabled);
m_menuTracked = new QAction(i18nc("Noun, a type of operations", "Tracked"), this);
m_menuTracked->setCheckable(true);
m_menuTracked->setChecked(true);
connect(m_menuTracked, &QAction::triggered, this, &SKGOperationBoardWidgetQml::settingsModified);
addAction(m_menuTracked);
m_Quick->rootContext()->setContextProperty(QStringLiteral("trackerWidget"), m_menuTracked);
m_menuSuboperation = new QAction(i18nc("Noun, a type of operations", "On suboperations"), this);
m_menuSuboperation->setCheckable(true);
m_menuSuboperation->setChecked(false);
connect(m_menuSuboperation, &QAction::triggered, this, &SKGOperationBoardWidgetQml::settingsModified);
addAction(m_menuSuboperation);
m_Quick->rootContext()->setContextProperty(QStringLiteral("suboperationsWidget"), m_menuSuboperation);
{
auto sep = new QAction(this);
sep->setSeparator(true);
addAction(sep);
}
m_periodEdit1 = new SKGPeriodEdit(this, true);
m_periodEdit1->setObjectName(QStringLiteral("m_periodEdit1"));
{
// Set default
QDomDocument doc(QStringLiteral("SKGML"));
QDomElement root = doc.createElement(QStringLiteral("parameters"));
doc.appendChild(root);
root.setAttribute(QStringLiteral("period"), SKGServices::intToString(static_cast<int>(SKGPeriodEdit::CURRENT)));
m_periodEdit1->setState(doc.toString());
// Add widget in menu
auto periodEditWidget = new QWidgetAction(this);
periodEditWidget->setObjectName(QStringLiteral("m_periodEdit1Action"));
periodEditWidget->setDefaultWidget(m_periodEdit1);
addAction(periodEditWidget);
}
m_Quick->rootContext()->setContextProperty(QStringLiteral("period1Widget"), m_periodEdit1);
{
auto sep = new QAction(this);
sep->setSeparator(true);
addAction(sep);
}
m_periodEdit2 = new SKGPeriodEdit(this, true);
m_periodEdit2->setObjectName(QStringLiteral("m_periodEdit2"));
{
// Set default
QDomDocument doc(QStringLiteral("SKGML"));
QDomElement root = doc.createElement(QStringLiteral("parameters"));
doc.appendChild(root);
root.setAttribute(QStringLiteral("period"), SKGServices::intToString(static_cast<int>(SKGPeriodEdit::PREVIOUS)));
m_periodEdit2->setState(doc.toString());
// Add widget in menu
auto periodEditWidget = new QWidgetAction(this);
periodEditWidget->setObjectName(QStringLiteral("m_periodEdit2Action"));
periodEditWidget->setDefaultWidget(m_periodEdit2);
addAction(periodEditWidget);
}
m_Quick->rootContext()->setContextProperty(QStringLiteral("period2Widget"), m_periodEdit2);
// Refresh
connect(m_periodEdit1, &SKGPeriodEdit::changed, this, &SKGOperationBoardWidgetQml::settingsModified);
connect(m_periodEdit2, &SKGPeriodEdit::changed, this, &SKGOperationBoardWidgetQml::settingsModified);
settingsModified();
}
SKGOperationBoardWidgetQml::~SKGOperationBoardWidgetQml()
{
SKGTRACEINFUNC(10)
m_menuTransfer = nullptr;
m_menuTracked = nullptr;
}
QString SKGOperationBoardWidgetQml::getState()
{
QDomDocument doc(QStringLiteral("SKGML"));
QDomElement root = doc.createElement(QStringLiteral("parameters"));
doc.appendChild(root);
root.setAttribute(QStringLiteral("menuGroup"), (m_menuGroup != nullptr) && m_menuGroup->isChecked() ? QStringLiteral("Y") : QStringLiteral("N"));
root.setAttribute(QStringLiteral("menuTransfert"), (m_menuTransfer != nullptr) && m_menuTransfer->isChecked() ? QStringLiteral("Y") : QStringLiteral("N"));
root.setAttribute(QStringLiteral("menuTracked"), (m_menuTracked != nullptr) && m_menuTracked->isChecked() ? QStringLiteral("Y") : QStringLiteral("N"));
root.setAttribute(QStringLiteral("menuSuboperation"), (m_menuSuboperation != nullptr) && m_menuSuboperation->isChecked() ? QStringLiteral("Y") : QStringLiteral("N"));
root.setAttribute(QStringLiteral("period1"), m_periodEdit1 != nullptr ? m_periodEdit1->getState() : QLatin1String(""));
root.setAttribute(QStringLiteral("period2"), m_periodEdit2 != nullptr ? m_periodEdit2->getState() : QLatin1String(""));
return doc.toString();
}
void SKGOperationBoardWidgetQml::setState(const QString& iState)
{
QDomDocument doc(QStringLiteral("SKGML"));
doc.setContent(iState);
QDomElement root = doc.documentElement();
if (m_menuGroup != nullptr) {
QString val = root.attribute(QStringLiteral("menuGroup"));
if (val.isEmpty()) {
val = root.attribute(QStringLiteral("menuTransfert"));
}
m_menuGroup->setChecked(val == QStringLiteral("Y"));
}
if (m_menuTransfer != nullptr) {
m_menuTransfer->setChecked(root.attribute(QStringLiteral("menuTransfert")) == QStringLiteral("Y"));
}
if (m_menuTracked != nullptr) {
m_menuTracked->setChecked(root.attribute(QStringLiteral("menuTracked")) != QStringLiteral("N"));
}
if (m_menuSuboperation != nullptr) {
m_menuSuboperation->setChecked(root.attribute(QStringLiteral("menuSuboperation")) == QStringLiteral("Y"));
}
QString period1 = root.attribute(QStringLiteral("period1"));
if ((m_periodEdit1 != nullptr) && !period1.isEmpty()) {
m_periodEdit1->setState(period1);
}
QString period2 = root.attribute(QStringLiteral("period2"));
if ((m_periodEdit2 != nullptr) && !period2.isEmpty()) {
m_periodEdit2->setState(period2);
}
SKGHtmlBoardWidget::dataModified(QLatin1String(""), 0);
settingsModified();
}
void SKGOperationBoardWidgetQml::settingsModified()
{
SKGTRACEINFUNC(10)
if (m_menuOpen != nullptr) {
auto* doc = qobject_cast<SKGDocumentBank*>(getDocument());
if (doc != nullptr) {
QString url = QStringLiteral("skg://skrooge_report_plugin/?grouped=") % ((m_menuGroup != nullptr) && m_menuGroup->isChecked() ? QStringLiteral("Y") : QStringLiteral("N")) % "&transfers="
% ((m_menuTransfer != nullptr) && m_menuTransfer->isChecked() ? QStringLiteral("Y") : QStringLiteral("N")) % "&tracked="
% ((m_menuTracked != nullptr) && m_menuTracked->isChecked() ? QStringLiteral("Y") : QStringLiteral("N")) % "&expenses=Y&incomes=Y&lines2=t_TYPEEXPENSENLS&columns=d_DATEMONTH&currentPage=-1" %
"&mode=0&interval=3&period=3" %
"&tableAndGraphState.graphMode=1&tableAndGraphState.allPositive=Y&tableAndGraphState.show=graph&title=" %
SKGServices::encodeForUrl(i18nc("Noun, the title of a section", "Income & Expenditure"));
m_menuOpen->setData(url);
}
}
}
diff --git a/plugins/skrooge/skrooge_operation/skgoperationboardwidgetqml.h b/plugins/skrooge/skrooge_operation/skgoperationboardwidgetqml.h
index ffd228691..d9d2e4ce1 100644
--- a/plugins/skrooge/skrooge_operation/skgoperationboardwidgetqml.h
+++ b/plugins/skrooge/skrooge_operation/skgoperationboardwidgetqml.h
@@ -1,80 +1,80 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGOPERATIONBOARDWIDGETQML_H
#define SKGOPERATIONBOARDWIDGETQML_H
/** @file
* This file is Skrooge plugin for operation management.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skghtmlboardwidget.h"
class QAction;
class SKGPeriodEdit;
/**
* This file is Skrooge plugin for operation management
*/
class SKGOperationBoardWidgetQml : public SKGHtmlBoardWidget
{
Q_OBJECT
public:
/**
* Default Constructor
* @param iParent the parent widget
* @param iDocument the document
*/
explicit SKGOperationBoardWidgetQml(QWidget* iParent, SKGDocument* iDocument);
/**
* Default Destructor
*/
~SKGOperationBoardWidgetQml() override;
/**
* Get the current state
* MUST BE OVERWRITTEN
* @return a string containing all information needed to set the same state.
* Could be an XML stream
*/
QString getState() override;
/**
* Set the current state
* MUST BE OVERWRITTEN
* @param iState must be interpreted to set the state of the widget
*/
void setState(const QString& iState) override;
private Q_SLOTS:
void settingsModified();
private:
Q_DISABLE_COPY(SKGOperationBoardWidgetQml)
QAction* m_menuOpen;
QAction* m_menuGroup;
QAction* m_menuTransfer;
QAction* m_menuTracked;
QAction* m_menuSuboperation;
SKGPeriodEdit* m_periodEdit1;
SKGPeriodEdit* m_periodEdit2;
};
#endif // SKGOPERATIONBOARDWIDGETQML_H
diff --git a/plugins/skrooge/skrooge_operation/skgoperationplugin.cpp b/plugins/skrooge/skrooge_operation/skgoperationplugin.cpp
index 16beab819..e52438811 100644
--- a/plugins/skrooge/skrooge_operation/skgoperationplugin.cpp
+++ b/plugins/skrooge/skrooge_operation/skgoperationplugin.cpp
@@ -1,1730 +1,1730 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is Skrooge plugin for operation management.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgoperationplugin.h"
#include <kaboutdata.h>
#include <kactioncollection.h>
#include <kpluginfactory.h>
#include <kstandardaction.h>
#include <ktoolbarpopupaction.h>
#include <qdom.h>
#include <qstandardpaths.h>
#include <qthread.h>
#include "skgaccountobject.h"
#include "skgbudgetobject.h"
#include "skgcategoryobject.h"
#include "skgdocumentbank.h"
#include "skghtmlboardwidget.h"
#include "skgmainpanel.h"
#include "skgoperation_settings.h"
#include "skgoperationboardwidget.h"
#include "skgoperationboardwidgetqml.h"
#include "skgoperationobject.h"
#include "skgoperationpluginwidget.h"
#include "skgpayeeobject.h"
#include "skgrecurrentoperationobject.h"
#include "skgruleobject.h"
#include "skgsuboperationobject.h"
#include "skgtableview.h"
#include "skgtraces.h"
#include "skgtrackerobject.h"
#include "skgtransactionmng.h"
/**
* This plugin factory.
*/
K_PLUGIN_FACTORY(SKGOperationPluginFactory, registerPlugin<SKGOperationPlugin>();)
SKGOperationPlugin::SKGOperationPlugin(QWidget* iWidget, QObject* iParent, const QVariantList& /*iArg*/) :
SKGInterfacePlugin(iParent),
m_applyTemplateMenu(nullptr), m_openOperationsWithMenu(nullptr), m_openSubOperationsWithMenu(nullptr), m_currentBankDocument(nullptr)
{
Q_UNUSED(iWidget)
SKGTRACEINFUNC(10)
}
SKGOperationPlugin::~SKGOperationPlugin()
{
SKGTRACEINFUNC(10)
m_currentBankDocument = nullptr;
m_applyTemplateMenu = nullptr;
m_openOperationsWithMenu = nullptr;
m_openSubOperationsWithMenu = nullptr;
}
bool SKGOperationPlugin::setupActions(SKGDocument* iDocument)
{
SKGTRACEINFUNC(10)
m_currentBankDocument = qobject_cast<SKGDocumentBank*>(iDocument);
if (m_currentBankDocument == nullptr) {
return false;
}
m_currentBankDocument->setComputeBalances(skgoperation_settings::computeBalances());
m_currentBankDocument->addEndOfTransactionCheck(SKGOperationPlugin::checkReconciliation);
m_currentBankDocument->addEndOfTransactionCheck(SKGOperationPlugin::checkImport);
setComponentName(QStringLiteral("skrooge_operation"), title());
setXMLFile(QStringLiteral("skrooge_operation.rc"));
QStringList listOperation;
listOperation << QStringLiteral("operation");
// Menu
// ------------
auto actDuplicateAction = new QAction(SKGServices::fromTheme(QStringLiteral("window-duplicate")), i18nc("Verb, duplicate an object", "Duplicate"), this);
connect(actDuplicateAction, &QAction::triggered, this, &SKGOperationPlugin::onDuplicate);
actionCollection()->setDefaultShortcut(actDuplicateAction, Qt::CTRL + Qt::Key_D);
registerGlobalAction(QStringLiteral("edit_duplicate_operation"), actDuplicateAction, listOperation, 1, -1, 400);
// ------------
auto actCreateTemplateAction = new QAction(SKGServices::fromTheme(QStringLiteral("edit-guides")), i18nc("Verb", "Create template"), this);
connect(actCreateTemplateAction, &QAction::triggered, this, &SKGOperationPlugin::onCreateTemplate);
actionCollection()->setDefaultShortcut(actCreateTemplateAction, Qt::CTRL + Qt::SHIFT + Qt::Key_T);
registerGlobalAction(QStringLiteral("edit_template_operation"), actCreateTemplateAction, listOperation, 1, -1, 401);
// ------------
auto actSwitchToPointedAction = new QAction(SKGServices::fromTheme(QStringLiteral("dialog-ok")), i18nc("Verb, mark an object", "Point"), this);
connect(actSwitchToPointedAction, &QAction::triggered, this, &SKGOperationPlugin::onSwitchToPointed);
actionCollection()->setDefaultShortcut(actSwitchToPointedAction, Qt::CTRL + Qt::Key_R);
registerGlobalAction(QStringLiteral("edit_point_selected_operation"), actSwitchToPointedAction, listOperation, 1, -1, 310);
// ------------
auto actFastEdition = new QAction(SKGServices::fromTheme(QStringLiteral("games-solve")), i18nc("Verb", "Fast edit"), this);
actFastEdition->setEnabled(false);
actionCollection()->setDefaultShortcut(actFastEdition, Qt::Key_F10);
registerGlobalAction(QStringLiteral("fast_edition"), actFastEdition, listOperation);
// ------------
QStringList overlayopen;
overlayopen.push_back(QStringLiteral("quickopen"));
QStringList overlayrun;
overlayrun.push_back(QStringLiteral("system-run"));
auto actOpen = new QAction(SKGServices::fromTheme(icon(), overlayopen), i18nc("Verb", "Open operations..."), this);
connect(actOpen, &QAction::triggered, this, &SKGOperationPlugin::onOpenOperations);
registerGlobalAction(QStringLiteral("open"), actOpen, QStringList() << QStringLiteral("account") << QStringLiteral("unit") << QStringLiteral("category") << QStringLiteral("refund") << QStringLiteral("payee") << QStringLiteral("budget") << QStringLiteral("recurrentoperation") << QStringLiteral("operation") << QStringLiteral("suboperation") << QStringLiteral("rule"),
1, -1, 110);
auto actOpen2 = new KToolBarPopupAction(SKGServices::fromTheme(icon(), overlayopen), i18nc("Verb", "Open operations with ..."), this);
m_openOperationsWithMenu = actOpen2->menu();
connect(m_openOperationsWithMenu, &QMenu::aboutToShow, this, &SKGOperationPlugin::onShowOpenWithMenu);
actOpen2->setStickyMenu(false);
actOpen2->setDelayed(false);
registerGlobalAction(QStringLiteral("open_operations_with"), actOpen2, QStringList() << QStringLiteral("operation") << QStringLiteral("suboperation"), 1, 1, 111);
auto actOpen3 = new KToolBarPopupAction(SKGServices::fromTheme(icon(), overlayopen), i18nc("Verb", "Open sub operations with ..."), this);
m_openSubOperationsWithMenu = actOpen3->menu();
connect(m_openSubOperationsWithMenu, &QMenu::aboutToShow, this, &SKGOperationPlugin::onShowOpenWithMenu);
actOpen3->setStickyMenu(false);
actOpen3->setDelayed(false);
registerGlobalAction(QStringLiteral("open_suboperations_with"), actOpen3, QStringList() << QStringLiteral("operation") << QStringLiteral("suboperation"), 1, 1, 112);
auto actOpenHighLights = new QAction(SKGServices::fromTheme(QStringLiteral("bookmarks"), overlayopen), i18nc("Verb", "Open highlights..."), this);
actOpenHighLights->setData(QString("skg://skrooge_operation_plugin/?title_icon=bookmarks&title=" % SKGServices::encodeForUrl(i18nc("Noun, a list of items", "Highlighted operations")) %
"&operationWhereClause=t_bookmarked='Y'"));
connect(actOpenHighLights, &QAction::triggered, SKGMainPanel::getMainPanel(), [ = ]() {
SKGMainPanel::getMainPanel()->SKGMainPanel::openPage();
});
actionCollection()->setDefaultShortcut(actOpenHighLights, Qt::CTRL + Qt::META + Qt::Key_H);
registerGlobalAction(QStringLiteral("view_open_highlight"), actOpenHighLights);
// ------------
auto actOpenLastModified = new QAction(SKGServices::fromTheme(QStringLiteral("view-refresh"), overlayopen), i18nc("Verb", "Open last modified..."), this);
actOpenLastModified->setData(QString("skg://skrooge_operation_plugin/?title_icon=view-refresh&title=" % SKGServices::encodeForUrl(i18nc("Noun, a list of items", "Operations modified or created during last action")) %
"&operationWhereClause=" % SKGServices::encodeForUrl(QStringLiteral("id in (SELECT i_object_id FROM doctransactionitem di, doctransaction dt WHERE dt.t_mode='U' AND +di.rd_doctransaction_id=dt.id AND di.t_object_table='operation'AND NOT EXISTS(select 1 from doctransaction B where B.i_parent=dt.id))"))));
connect(actOpenLastModified, &QAction::triggered, SKGMainPanel::getMainPanel(), [ = ]() {
SKGMainPanel::getMainPanel()->SKGMainPanel::openPage();
});
actionCollection()->setDefaultShortcut(actOpenLastModified, Qt::META + Qt::Key_L);
registerGlobalAction(QStringLiteral("view_open_last_modified"), actOpenLastModified);
// ------------
auto actOpenModifiedByTransaction = new QAction(SKGServices::fromTheme(QStringLiteral("view-refresh"), overlayopen), i18nc("Verb", "Open operations modified by this transaction..."), this);
connect(actOpenModifiedByTransaction, &QAction::triggered, SKGMainPanel::getMainPanel(), [ = ]() {
SKGObjectBase::SKGListSKGObjectBase selection = SKGMainPanel::getMainPanel()->getSelectedObjects();
if (!selection.isEmpty()) {
SKGObjectBase obj = selection[0];
QString name = obj.getAttribute(QStringLiteral("t_name"));
QString url = QString("skg://skrooge_operation_plugin/?title_icon=view-refresh&title=" % SKGServices::encodeForUrl(i18nc("Noun, a list of items", "Operations modified or created during the action '%1'", name)) % "&operationWhereClause=" % SKGServices::encodeForUrl("id in (SELECT i_object_id FROM doctransactionitem WHERE rd_doctransaction_id=" % SKGServices::intToString(obj.getID()) % " AND t_object_table='operation')"));
SKGMainPanel::getMainPanel()->SKGMainPanel::openPage(url);
}
});
registerGlobalAction(QStringLiteral("view_open_modified_by_transaction"), actOpenModifiedByTransaction, QStringList() << QStringLiteral("doctransaction"), 1, 1, 100);
// ------------
auto actOpenSuboperations = new QAction(SKGServices::fromTheme(QStringLiteral("split"), overlayopen), i18nc("Verb", "Open sub operations..."), this);
actOpenSuboperations->setData(QString("skg://skrooge_operation_plugin/SKGOPERATION_CONSOLIDATED_DEFAULT_PARAMETERS/?title_icon=split&operationTable=v_suboperation_consolidated&operationWhereClause=&title=" % SKGServices::encodeForUrl(i18nc("Noun, a list of items", "Sub operations"))));
connect(actOpenSuboperations, &QAction::triggered, SKGMainPanel::getMainPanel(), [ = ]() {
SKGMainPanel::getMainPanel()->SKGMainPanel::openPage();
});
actionCollection()->setDefaultShortcut(actOpenSuboperations, Qt::META + Qt::Key_S);
registerGlobalAction(QStringLiteral("view_open_suboperations"), actOpenSuboperations);
// ------------
auto actOpenDuplicate = new QAction(SKGServices::fromTheme(QStringLiteral("window-duplicate"), overlayopen), i18nc("Verb", "Open potential duplicates..."), this);
actOpenDuplicate->setData(QString("skg://skrooge_operation_plugin/?title_icon=window-duplicate&title=" % SKGServices::encodeForUrl(i18nc("Noun, a list of items", "Operations potentially duplicated")) %
"&operationWhereClause=" % SKGServices::encodeForUrl("id in (SELECT o1.id FROM v_operation o1 WHERE EXISTS (SELECT 1 FROM v_operation o2 WHERE o1.id<>o2.id AND o1.t_template='N' AND o2.t_template='N' AND o1.d_date=o2.d_date AND ABS(o1.f_CURRENTAMOUNT-o2.f_CURRENTAMOUNT)<" % SKGServices::doubleToString(EPSILON) % " AND o1.rd_account_id=o2.rd_account_id AND o1.rc_unit_id=o2.rc_unit_id AND (o1.t_status<>'Y' OR o2.t_status<>'Y')))")));
connect(actOpenDuplicate, &QAction::triggered, SKGMainPanel::getMainPanel(), [ = ]() {
SKGMainPanel::getMainPanel()->SKGMainPanel::openPage();
});
actionCollection()->setDefaultShortcut(actOpenDuplicate, Qt::META + Qt::Key_D);
registerGlobalAction(QStringLiteral("view_open_duplicates"), actOpenDuplicate);
// ------------
auto actTmp = new QAction(SKGServices::fromTheme(QStringLiteral("exchange-positions"), overlayopen), i18nc("Verb", "Open transfers without payee..."), this);
actTmp->setData(QString("skg://skrooge_operation_plugin/?title_icon=user-group-properties&title=" % SKGServices::encodeForUrl(i18nc("Noun, a list of items", "Transfers without payee")) %
"&operationWhereClause=" % SKGServices::encodeForUrl(QStringLiteral("t_TRANSFER='Y' AND r_payee_id=0"))));
connect(actTmp, &QAction::triggered, SKGMainPanel::getMainPanel(), [ = ]() {
SKGMainPanel::getMainPanel()->SKGMainPanel::openPage();
});
registerGlobalAction(QStringLiteral("view_open_transfers_without_payee"), actTmp);
// ------------
actTmp = new QAction(SKGServices::fromTheme(QStringLiteral("user-group-properties"), overlayopen), i18nc("Verb", "Open operations without payee..."), this);
actTmp->setData(QString("skg://skrooge_operation_plugin/?title_icon=user-group-properties&title=" % SKGServices::encodeForUrl(i18nc("Noun, a list of items", "Operations without payee")) %
"&operationWhereClause=" % SKGServices::encodeForUrl(QStringLiteral("t_TRANSFER='N' AND r_payee_id=0"))));
connect(actTmp, &QAction::triggered, SKGMainPanel::getMainPanel(), [ = ]() {
SKGMainPanel::getMainPanel()->SKGMainPanel::openPage();
});
registerGlobalAction(QStringLiteral("view_open_operation_without_payee"), actTmp);
// ------------
actTmp = new QAction(SKGServices::fromTheme(QStringLiteral("exchange-positions"), overlayopen), i18nc("Verb", "Open transfers without category..."), this);
actTmp->setData(QString("skg://skrooge_operation_plugin/?title_icon=view-categories&title=" % SKGServices::encodeForUrl(i18nc("Noun, a list of items", "Transfers without category")) %
"&operationWhereClause=" % SKGServices::encodeForUrl(QStringLiteral("t_TRANSFER='Y' AND EXISTS (SELECT 1 FROM suboperation WHERE rd_operation_id=v_operation_display.id AND r_category_id=0)"))));
connect(actTmp, &QAction::triggered, SKGMainPanel::getMainPanel(), [ = ]() {
SKGMainPanel::getMainPanel()->SKGMainPanel::openPage();
});
registerGlobalAction(QStringLiteral("view_open_transfers_without_category"), actTmp);
// ------------
actTmp = new QAction(SKGServices::fromTheme(QStringLiteral("view-categories"), overlayopen), i18nc("Verb", "Open operations without category..."), this);
actTmp->setData(QString("skg://skrooge_operation_plugin/?title_icon=view-categories&title=" % SKGServices::encodeForUrl(i18nc("Noun, a list of items", "Operations without category")) %
"&operationWhereClause=" % SKGServices::encodeForUrl(QStringLiteral("t_TRANSFER='N' AND EXISTS (SELECT 1 FROM suboperation WHERE rd_operation_id=v_operation_display.id AND r_category_id=0)"))));
connect(actTmp, &QAction::triggered, SKGMainPanel::getMainPanel(), [ = ]() {
SKGMainPanel::getMainPanel()->SKGMainPanel::openPage();
});
registerGlobalAction(QStringLiteral("view_open_operation_without_category"), actTmp);
// ------------
actTmp = new QAction(SKGServices::fromTheme(QStringLiteral("skrooge_credit_card"), overlayopen), i18nc("Verb", "Open operations without mode..."), this);
actTmp->setData(QString("skg://skrooge_operation_plugin/?title_icon=skrooge_credit_card&title=" % SKGServices::encodeForUrl(i18nc("Noun, a list of items", "Operations without mode")) %
"&operationWhereClause=" % SKGServices::encodeForUrl(QStringLiteral("t_template='N' AND t_mode='' AND d_date<>'0000-00-00'"))));
connect(actTmp, &QAction::triggered, SKGMainPanel::getMainPanel(), [ = ]() {
SKGMainPanel::getMainPanel()->SKGMainPanel::openPage();
});
registerGlobalAction(QStringLiteral("view_open_operation_without_mode"), actTmp);
// ------------
actTmp = new QAction(SKGServices::fromTheme(QStringLiteral("draw-freehand"), overlayopen), i18nc("Verb", "Open operations with comments not aligned..."), this);
actTmp->setData(QString("skg://skrooge_operation_plugin/?title_icon=draw-freehand&title=" % SKGServices::encodeForUrl(i18nc("Noun, a list of items", "Operations with comments not aligned")) %
"&operationWhereClause=" % SKGServices::encodeForUrl(QStringLiteral("id IN (SELECT op.id FROM operation op, suboperation so WHERE so.rd_operation_id=op.id AND so.t_comment<>op.t_comment AND (SELECT COUNT(1) FROM suboperation so2 WHERE so2.rd_operation_id=op.id)=1)"))));
connect(actTmp, &QAction::triggered, SKGMainPanel::getMainPanel(), [ = ]() {
SKGMainPanel::getMainPanel()->SKGMainPanel::openPage();
});
registerGlobalAction(QStringLiteral("view_open_operation_with_comment_not_aligned"), actTmp);
// ------------
actTmp = new QAction(SKGServices::fromTheme(QStringLiteral("view-pim-calendar"), overlayopen), i18nc("Verb", "Open operations with dates not aligned..."), this);
actTmp->setData(QString("skg://skrooge_operation_plugin/?title_icon=draw-freehand&title=" % SKGServices::encodeForUrl(i18nc("Noun, a list of items", "Operations with dates not aligned")) %
"&operationWhereClause=" % SKGServices::encodeForUrl(QStringLiteral("id IN (SELECT op.id FROM operation op, suboperation so WHERE so.rd_operation_id=op.id AND (so.d_date<op.d_date OR (so.d_date<>op.d_date AND (SELECT COUNT(1) FROM suboperation so2 WHERE so2.rd_operation_id=op.id)=1)))"))));
connect(actTmp, &QAction::triggered, SKGMainPanel::getMainPanel(), [ = ]() {
SKGMainPanel::getMainPanel()->SKGMainPanel::openPage();
});
registerGlobalAction(QStringLiteral("view_open_operation_with_date_not_aligned"), actTmp);
// ------------
auto actCleanAlignComment = new QAction(SKGServices::fromTheme(QStringLiteral("draw-freehand"), overlayrun), i18nc("Verb", "Align comment of suboperations of all operations"), this);
connect(actCleanAlignComment, &QAction::triggered, this, &SKGOperationPlugin::onAlignComment);
registerGlobalAction(QStringLiteral("clean_align_comment"), actCleanAlignComment);
// ------------
auto actCleanAlignDate = new QAction(SKGServices::fromTheme(QStringLiteral("view-pim-calendar"), overlayrun), i18nc("Verb", "Align date of suboperations of all operations"), this);
connect(actCleanAlignDate, &QAction::triggered, this, &SKGOperationPlugin::onAlignDate);
registerGlobalAction(QStringLiteral("clean_align_date"), actCleanAlignDate);
// ------------
actTmp = new QAction(SKGServices::fromTheme(QStringLiteral("exchange-positions"), overlayopen), i18nc("Verb", "Open operations in groups with only one operation..."), this);
actTmp->setData(QString("skg://skrooge_operation_plugin/?title_icon=exchange-positions&title=" % SKGServices::encodeForUrl(i18nc("Noun, a list of items", "Operations in groups with only one operation")) %
"&operationWhereClause=" % SKGServices::encodeForUrl(QStringLiteral("v_operation_display.i_group_id<>0 AND (SELECT COUNT(1) FROM operation o WHERE o.i_group_id=v_operation_display.i_group_id)<2"))));
connect(actTmp, &QAction::triggered, SKGMainPanel::getMainPanel(), [ = ]() {
SKGMainPanel::getMainPanel()->SKGMainPanel::openPage();
});
registerGlobalAction(QStringLiteral("view_open_operation_in_group_of_one"), actTmp);
// ------------
auto actCleanRemoveGroupWithOneOperation = new QAction(SKGServices::fromTheme(QStringLiteral("exchange-positions"), overlayrun), i18nc("Verb", "Remove groups with only one operation of all operations"), this);
connect(actCleanRemoveGroupWithOneOperation, &QAction::triggered, this, &SKGOperationPlugin::onRemoveGroupWithOneOperation);
registerGlobalAction(QStringLiteral("clean_remove_group_with_one_operation"), actCleanRemoveGroupWithOneOperation);
// ------------
auto actGroupOperation = new QAction(SKGServices::fromTheme(QStringLiteral("exchange-positions")), i18nc("Verb", "Group operations"), this);
connect(actGroupOperation, &QAction::triggered, this, &SKGOperationPlugin::onGroupOperation);
actionCollection()->setDefaultShortcut(actGroupOperation, Qt::CTRL + Qt::Key_G);
registerGlobalAction(QStringLiteral("edit_group_operation"), actGroupOperation, listOperation, 2, -1, 311);
// ------------
QStringList overlay;
overlay.push_back(QStringLiteral("edit-delete"));
auto actUngroupOperation = new QAction(SKGServices::fromTheme(QStringLiteral("exchange-positions"), overlay), i18nc("Verb", "Ungroup operations"), this);
connect(actUngroupOperation, &QAction::triggered, this, &SKGOperationPlugin::onUngroupOperation);
actionCollection()->setDefaultShortcut(actUngroupOperation, Qt::CTRL + Qt::SHIFT + Qt::Key_G);
registerGlobalAction(QStringLiteral("edit_ungroup_operation"), actUngroupOperation, listOperation, 1, -1, 312);
// ------------
auto actMergeOperationAction = new QAction(SKGServices::fromTheme(QStringLiteral("split")), i18nc("Verb, action to merge", "Merge sub operations"), this);
connect(actMergeOperationAction, &QAction::triggered, this, &SKGOperationPlugin::onMergeSubOperations);
actionCollection()->setDefaultShortcut(actMergeOperationAction, Qt::CTRL + Qt::SHIFT + Qt::Key_M);
registerGlobalAction(QStringLiteral("merge_sub_operations"), actMergeOperationAction, listOperation, 1, -1, 320);
auto actApplyTemplateAction = new KToolBarPopupAction(SKGServices::fromTheme(QStringLiteral("edit-guides")), i18nc("Verb, action to apply a template", "Apply template"), this);
m_applyTemplateMenu = actApplyTemplateAction->menu();
connect(m_applyTemplateMenu, &QMenu::aboutToShow, this, &SKGOperationPlugin::onShowApplyTemplateMenu);
actApplyTemplateAction->setStickyMenu(false);
actApplyTemplateAction->setData(1);
registerGlobalAction(QStringLiteral("edit_apply_template"), actApplyTemplateAction, listOperation, 1, -1, 402);
return true;
}
void SKGOperationPlugin::onShowApplyTemplateMenu()
{
if ((m_applyTemplateMenu != nullptr) && (m_currentBankDocument != nullptr)) {
// Clean Menu
QMenu* m = m_applyTemplateMenu;
m->clear();
// Search templates
SKGStringListList listTmp;
m_currentBankDocument->executeSelectSqliteOrder(
QStringLiteral("SELECT t_displayname, id, t_bookmarked FROM v_operation_displayname WHERE t_template='Y' ORDER BY t_bookmarked DESC, t_PAYEE ASC"),
listTmp);
// Build menus
int count = 0;
bool fav = true;
int nb = listTmp.count();
for (int i = 1; i < nb; ++i) {
// Add more sub menu
if (count == 8) {
m = m->addMenu(i18nc("More items in a menu", "More"));
count = 0;
}
count++;
// Add separator for bookmarked templates
if (fav && listTmp.at(i).at(2) == QStringLiteral("N") && i > 1) {
m->addSeparator();
}
fav = (listTmp.at(i).at(2) == QStringLiteral("Y"));
// Add actions
QAction* act = m->addAction(SKGServices::fromTheme(QStringLiteral("edit-guides")), listTmp.at(i).at(0));
if (act != nullptr) {
act->setData(listTmp.at(i).at(1));
connect(act, &QAction::triggered, this, &SKGOperationPlugin::onApplyTemplate);
}
}
}
}
void SKGOperationPlugin::refresh()
{
SKGTRACEINFUNC(10)
if ((m_currentBankDocument != nullptr) && (SKGMainPanel::getMainPanel() != nullptr)) {
SKGObjectBase::SKGListSKGObjectBase selection = SKGMainPanel::getMainPanel()->getSelectedObjects();
int nb = selection.count();
bool onOperation = (nb > 0 && selection.at(0).getRealTable() == QStringLiteral("operation"));
QAction* act = SKGMainPanel::getMainPanel()->getGlobalAction(QStringLiteral("clean_align_date"));
act->setText(onOperation ? i18nc("Verb", "Align date of suboperations of selected operations") : i18nc("Verb", "Align date of suboperations of all operations"));
act->setData(onOperation);
act = SKGMainPanel::getMainPanel()->getGlobalAction(QStringLiteral("clean_align_comment"));
act->setText(onOperation ? i18nc("Verb", "Align comment of suboperations of selected operations") : i18nc("Verb", "Align comment of suboperations of all operations"));
act->setData(onOperation);
act = SKGMainPanel::getMainPanel()->getGlobalAction(QStringLiteral("clean_remove_group_with_one_operation"));
act->setText(onOperation ? i18nc("Verb", "Remove groups with only one operation of selected operations") : i18nc("Verb", "Remove groups with only one operation of all operations"));
act->setData(onOperation);
}
}
SKGError SKGOperationPlugin::checkReconciliation(SKGDocument* iDocument)
{
SKGError err;
SKGTRACEINFUNCRC(5, err)
if ((iDocument != nullptr) && (SKGMainPanel::getMainPanel() != nullptr) && skgoperation_settings::broken_reconciliation() > QStringLiteral("0")) {
// Check the reconciliation for all opened account
SKGObjectBase::SKGListSKGObjectBase accounts;
iDocument->getObjects(QStringLiteral("v_account"), QStringLiteral("t_close='N' AND f_reconciliationbalance!=''"), accounts);
for (const auto& account : qAsConst(accounts)) {
SKGAccountObject a(account);
auto soluces = a.getPossibleReconciliations(SKGServices::stringToDouble(account.getAttribute(QStringLiteral("f_reconciliationbalance"))), false);
if (soluces.isEmpty()) {
if (skgoperation_settings::broken_reconciliation() == QStringLiteral("1")) {
iDocument->sendMessage(i18nc("Warning message", "The previous reconciliation of '%1' has been broken by this action or a previous one.", a.getDisplayName()), SKGDocument::Warning, QStringLiteral("skg://edit_undo"));
} else {
auto msg = i18nc("Warning message", "This action would break the previous reconciliation of '%1', so it is cancelled.", a.getDisplayName());
iDocument->sendMessage(msg, SKGDocument::Error);
return err = SKGError(ERR_ABORT, msg);
}
}
}
}
return err;
}
SKGError SKGOperationPlugin::checkImport(SKGDocument* iDocument)
{
SKGError err;
SKGTRACEINFUNCRC(5, err)
if ((iDocument != nullptr) && (SKGMainPanel::getMainPanel() != nullptr) && skgoperation_settings::broken_import() > QStringLiteral("0")) {
// Check the reconciliation for all opened account
SKGObjectBase::SKGListSKGObjectBase accounts;
iDocument->getObjects(QStringLiteral("v_account"), QStringLiteral("t_close='N' AND f_importbalance!=''"), accounts);
for (const auto& account : qAsConst(accounts)) {
SKGAccountObject a(account);
auto soluces = a.getPossibleReconciliations(SKGServices::stringToDouble(account.getAttribute(QStringLiteral("f_importbalance"))), false);
if (soluces.isEmpty()) {
if (skgoperation_settings::broken_import() == QStringLiteral("1")) {
iDocument->sendMessage(i18nc("Warning message", "The previous import in '%1' has been broken by this action or a previous one.", a.getDisplayName()), SKGDocument::Warning, QStringLiteral("skg://edit_undo"));
} else {
auto msg = i18nc("Warning message", "This action would break the previous import in '%1', so it is cancelled.", a.getDisplayName());
iDocument->sendMessage(msg, SKGDocument::Error);
return err = SKGError(ERR_ABORT, msg);
}
}
}
}
return err;
}
int SKGOperationPlugin::getNbDashboardWidgets()
{
return 2;
}
QString SKGOperationPlugin::getDashboardWidgetTitle(int iIndex)
{
if (iIndex == 0) {
return i18nc("Noun, the title of a section", "Income && Expenditure");
}
return i18nc("Noun, the title of a section", "Highlighted operations");
}
SKGBoardWidget* SKGOperationPlugin::getDashboardWidget(int iIndex)
{
// Get QML mode for dashboard
KConfigSkeleton* skl = SKGMainPanel::getMainPanel()->getPluginByName(QStringLiteral("Dashboard plugin"))->getPreferenceSkeleton();
KConfigSkeletonItem* sklItem = skl->findItem(QStringLiteral("qmlmode"));
bool qml = sklItem->property().toBool();
if (iIndex == 0) {
if (qml) {
return new SKGOperationBoardWidgetQml(SKGMainPanel::getMainPanel(), m_currentBankDocument);
}
return new SKGOperationBoardWidget(SKGMainPanel::getMainPanel(), m_currentBankDocument);
}
return new SKGHtmlBoardWidget(SKGMainPanel::getMainPanel(), m_currentBankDocument,
getDashboardWidgetTitle(iIndex),
QStandardPaths::locate(QStandardPaths::GenericDataLocation, QStringLiteral("skrooge/html/default/highlighted_operations.html")),
QStringList() << QStringLiteral("operation"));
}
SKGTabPage* SKGOperationPlugin::getWidget()
{
SKGTRACEINFUNC(10)
return new SKGOperationPluginWidget(SKGMainPanel::getMainPanel(), m_currentBankDocument);
}
QWidget* SKGOperationPlugin::getPreferenceWidget()
{
SKGTRACEINFUNC(10)
auto w = new QWidget();
ui.setupUi(w);
// Set labels
ui.kPayeeFakeLbl->setText(i18n("%1:", m_currentBankDocument->getDisplay(QStringLiteral("t_payee"))));
ui.kCategoryFakeLbl->setText(i18n("%1:", m_currentBankDocument->getDisplay(QStringLiteral("t_CATEGORY"))));
ui.kCommentFakeLbl->setText(i18n("%1:", m_currentBankDocument->getDisplay(QStringLiteral("t_comment"))));
ui.kCategoryCommissionLbl->setText(ui.kCategoryFakeLbl->text());
ui.kCommentCommissionLbl->setText(ui.kCommentFakeLbl->text());
ui.kCategoryTaxLbl->setText(ui.kCategoryFakeLbl->text());
ui.kCommentTaxLbl->setText(ui.kCommentFakeLbl->text());
// Fill combo boxes and auto complession
SKGMainPanel::fillWithDistinctValue(QList<QWidget*>() << ui.kcfg_categoryFakeOperation << ui.kcfg_categoryCommissionOperation << ui.kcfg_categoryTaxOperation, m_currentBankDocument, QStringLiteral("category"), QStringLiteral("t_fullname"), QLatin1String(""));
SKGMainPanel::fillWithDistinctValue(QList<QWidget*>() << ui.kcfg_payeeFakeOperation, m_currentBankDocument, QStringLiteral("payee"), QStringLiteral("t_name"), QLatin1String(""));
SKGMainPanel::fillWithDistinctValue(QList<QWidget*>() << ui.kcfg_commentFakeOperation << ui.kcfg_commentCommissionOperation << ui.kcfg_commentTaxOperation, m_currentBankDocument, QStringLiteral("v_operation_all_comment"), QStringLiteral("t_comment"), QLatin1String(""), true);
return w;
}
KConfigSkeleton* SKGOperationPlugin::getPreferenceSkeleton()
{
return skgoperation_settings::self();
}
SKGError SKGOperationPlugin::savePreferences() const
{
m_currentBankDocument->setComputeBalances(skgoperation_settings::computeBalances());
return SKGInterfacePlugin::savePreferences();
}
QString SKGOperationPlugin::title() const
{
return i18nc("Noun", "Operations");
}
QString SKGOperationPlugin::icon() const
{
return QStringLiteral("view-bank-account");
}
QString SKGOperationPlugin::toolTip() const
{
return i18nc("Noun", "Operation management");
}
int SKGOperationPlugin::getOrder() const
{
return 15;
}
QStringList SKGOperationPlugin::tips() const
{
QStringList output;
output.push_back(i18nc("Description of a tips", "<p>... you can press +, -, CTRL + or CTRL - to quickly change dates.</p>"));
output.push_back(i18nc("Description of a tips", "<p>... you can update many <a href=\"skg://skrooge_operation_plugin\">operations</a> in one shot.</p>"));
output.push_back(i18nc("Description of a tips", "<p>... you can double click on an <a href=\"skg://skrooge_operation_plugin\">operation</a> to show or edit sub operations.</p>"));
output.push_back(i18nc("Description of a tips", "<p>... you can duplicate an <a href=\"skg://skrooge_operation_plugin\">operation</a> including complex operations (split, grouped, ...).</p>"));
output.push_back(i18nc("Description of a tips", "<p>... you can create template of <a href=\"skg://skrooge_operation_plugin\">operations</a>.</p>"));
output.push_back(i18nc("Description of a tips", "<p>... you can group and ungroup <a href=\"skg://skrooge_operation_plugin\">operations</a>.</p>"));
output.push_back(i18nc("Description of a tips", "<p>... you have to indicate the sign of an <a href=\"skg://skrooge_operation_plugin\">operation</a> only if you want to force it, else it will be determined automatically with the <a href=\"skg://skrooge_category_plugin\">category</a>.</p>"));
return output;
}
bool SKGOperationPlugin::isInPagesChooser() const
{
return true;
}
void SKGOperationPlugin::onApplyTemplate()
{
SKGError err;
SKGTRACEINFUNCRC(10, err)
auto* act = qobject_cast<QAction*>(sender());
if (act != nullptr) {
// Get template
SKGOperationObject temp(m_currentBankDocument, SKGServices::stringToInt(act->data().toString()));
// Get Selection
if ((SKGMainPanel::getMainPanel() != nullptr) && (m_currentBankDocument != nullptr)) {
QStringList listUUID;
SKGObjectBase::SKGListSKGObjectBase selection = SKGMainPanel::getMainPanel()->getSelectedObjects();
int nb = selection.count();
{
SKGBEGINPROGRESSTRANSACTION(*m_currentBankDocument, i18nc("Noun, name of the user action", "Apply template"), err, nb)
for (int i = 0; !err && i < nb; ++i) {
SKGOperationObject operationObj(selection.at(i));
SKGOperationObject op;
IFOKDO(err, temp.duplicate(op))
IFOKDO(err, op.mergeAttribute(operationObj, SKGOperationObject::PROPORTIONAL, false))
listUUID.push_back(op.getUniqueID());
IFOKDO(err, m_currentBankDocument->stepForward(i + 1))
}
}
// status bar
IFOK(err) {
err = SKGError(0, i18nc("Successful message after an user action", "Template applied."));
auto* w = qobject_cast<SKGOperationPluginWidget*>(SKGMainPanel::getMainPanel()->currentPage());
if (w != nullptr) {
w->getTableView()->selectObjects(listUUID, true);
}
} else {
err.addError(ERR_FAIL, i18nc("Error message", "Apply of template failed"));
}
}
// Display error
SKGMainPanel::displayErrorMessage(err);
}
}
void SKGOperationPlugin::onGroupOperation()
{
SKGError err;
SKGTRACEINFUNCRC(10, err)
// Get Selection
if ((SKGMainPanel::getMainPanel() != nullptr) && (m_currentBankDocument != nullptr)) {
SKGObjectBase::SKGListSKGObjectBase selection = SKGMainPanel::getMainPanel()->getSelectedObjects();
int nb = selection.count();
if (nb >= 2) {
SKGBEGINPROGRESSTRANSACTION(*m_currentBankDocument, i18nc("Noun, name of the user action", "Group operations"), err, nb)
SKGOperationObject main(selection.at(0));
IFOKDO(err, m_currentBankDocument->stepForward(1))
for (int i = 1; !err && i < nb; ++i) {
SKGOperationObject operationObj(selection.at(i));
IFOKDO(err, operationObj.setGroupOperation(main))
IFOKDO(err, operationObj.save())
IFOKDO(err, main.load())
// Send message
IFOKDO(err, m_currentBankDocument->sendMessage(i18nc("An information to the user", "The operation '%1' has been grouped with '%2'", operationObj.getDisplayName(), main.getDisplayName()), SKGDocument::Hidden))
IFOKDO(err, m_currentBankDocument->stepForward(i + 1))
}
}
// status bar
IFOKDO(err, SKGError(0, i18nc("Successful message after an user action", "Operations grouped.")))
else {
err.addError(ERR_FAIL, i18nc("Error message", "Group creation failed"));
}
// Display error
SKGMainPanel::displayErrorMessage(err);
}
}
void SKGOperationPlugin::onUngroupOperation()
{
SKGError err;
SKGTRACEINFUNCRC(10, err)
// Get Selection
if ((SKGMainPanel::getMainPanel() != nullptr) && (m_currentBankDocument != nullptr)) {
SKGObjectBase::SKGListSKGObjectBase selection = SKGMainPanel::getMainPanel()->getSelectedObjects();
int nb = selection.count();
{
SKGBEGINPROGRESSTRANSACTION(*m_currentBankDocument, i18nc("Noun, name of the user action", "Ungroup operation"), err, nb)
for (int i = 0; !err && i < nb; ++i) {
SKGOperationObject operationObj(selection.at(i));
IFOKDO(err, operationObj.setGroupOperation(operationObj))
IFOKDO(err, operationObj.save())
// Send message
IFOKDO(err, m_currentBankDocument->sendMessage(i18nc("An information to the user", "The operation '%1' has been ungrouped", operationObj.getDisplayName()), SKGDocument::Hidden))
IFOKDO(err, m_currentBankDocument->stepForward(i + 1))
}
}
// status bar
IFOKDO(err, SKGError(0, i18nc("Successful message after an user action", "Operation ungrouped.")))
else {
err.addError(ERR_FAIL, i18nc("Error message", "Group deletion failed"));
}
// Display error
SKGMainPanel::displayErrorMessage(err);
}
}
void SKGOperationPlugin::onSwitchToPointed()
{
SKGError err;
SKGTRACEINFUNCRC(10, err)
// Get Selection
if ((SKGMainPanel::getMainPanel() != nullptr) && (m_currentBankDocument != nullptr)) {
SKGObjectBase::SKGListSKGObjectBase selection = SKGMainPanel::getMainPanel()->getSelectedObjects();
int nb = selection.count();
{
SKGBEGINPROGRESSTRANSACTION(*m_currentBankDocument, i18nc("Noun, name of the user action", "Switch to pointed"), err, nb)
for (int i = 0; !err && i < nb; ++i) {
SKGOperationObject operationObj(selection.at(i));
IFOKDO(err, operationObj.setStatus(operationObj.getStatus() != SKGOperationObject::POINTED ? SKGOperationObject::POINTED : SKGOperationObject::NONE))
IFOKDO(err, operationObj.save())
// Send message
IFOKDO(err, m_currentBankDocument->sendMessage(i18nc("An information to the user", "The status of the operation '%1' has been changed", operationObj.getDisplayName()), SKGDocument::Hidden))
IFOKDO(err, m_currentBankDocument->stepForward(i + 1))
}
}
// status bar
IFOKDO(err, SKGError(0, i18nc("Successful message after an user action", "Operation pointed.")))
else {
err.addError(ERR_FAIL, i18nc("Error message", "Switch failed"));
}
// Display error
SKGMainPanel::displayErrorMessage(err);
}
}
void SKGOperationPlugin::onDuplicate()
{
SKGError err;
SKGTRACEINFUNCRC(10, err)
// Get Selection
if ((SKGMainPanel::getMainPanel() != nullptr) && (m_currentBankDocument != nullptr)) {
QStringList listUUID;
SKGObjectBase::SKGListSKGObjectBase selection = SKGMainPanel::getMainPanel()->getSelectedObjects();
int nb = selection.count();
{
SKGBEGINPROGRESSTRANSACTION(*m_currentBankDocument, i18nc("Noun, name of the user action", "Duplicate operation"), err, nb)
for (int i = 0; !err && i < nb; ++i) {
SKGOperationObject operationObj(selection.at(i));
SKGOperationObject dup;
IFOKDO(err, operationObj.duplicate(dup))
IFOKDO(err, m_currentBankDocument->stepForward(i + 1))
// Send message
IFOKDO(err, m_currentBankDocument->sendMessage(i18nc("An information to the user", "The duplicate operation '%1' has been added", dup.getDisplayName()), SKGDocument::Hidden))
listUUID.push_back(dup.getUniqueID());
}
}
// status bar
IFOK(err) {
err = SKGError(0, i18nc("Successful message after an user action", "Operation duplicated."));
auto* w = qobject_cast<SKGOperationPluginWidget*>(SKGMainPanel::getMainPanel()->currentPage());
if (w != nullptr) {
w->getTableView()->selectObjects(listUUID, true);
}
} else {
err.addError(ERR_FAIL, i18nc("Error message", "Duplicate operation failed"));
}
// Display error
SKGMainPanel::displayErrorMessage(err);
}
}
void SKGOperationPlugin::onCreateTemplate()
{
SKGError err;
SKGTRACEINFUNCRC(10, err)
// Get Selection
if ((SKGMainPanel::getMainPanel() != nullptr) && (m_currentBankDocument != nullptr)) {
QStringList listUUID;
SKGObjectBase::SKGListSKGObjectBase selection = SKGMainPanel::getMainPanel()->getSelectedObjects();
int nb = selection.count();
{
SKGBEGINPROGRESSTRANSACTION(*m_currentBankDocument, i18nc("Noun, name of the user action", "Create template"), err, nb)
for (int i = 0; !err && i < nb; ++i) {
SKGOperationObject operationObj(selection.at(i));
SKGOperationObject dup;
IFOKDO(err, operationObj.duplicate(dup, QDate::currentDate(), true))
IFOKDO(err, m_currentBankDocument->stepForward(i + 1))
// Send message
IFOKDO(err, m_currentBankDocument->sendMessage(i18nc("An information to the user", "The template '%1' has been added", dup.getDisplayName()), SKGDocument::Hidden))
listUUID.push_back(dup.getUniqueID());
}
}
// status bar
IFOK(err) {
err = SKGError(0, i18nc("Successful message after an user action", "Template created."));
auto* w = qobject_cast<SKGOperationPluginWidget*>(SKGMainPanel::getMainPanel()->currentPage());
if (w != nullptr) {
w->setTemplateMode(true);
w->getTableView()->selectObjects(listUUID, true);
}
} else {
err.addError(ERR_FAIL, i18nc("Error message", "Creation template failed"));
}
// Display error
SKGMainPanel::displayErrorMessage(err);
}
}
void SKGOperationPlugin::onOpenOperations()
{
SKGTRACEINFUNC(10)
if (SKGMainPanel::getMainPanel() != nullptr) {
SKGObjectBase::SKGListSKGObjectBase selection;
auto* act = qobject_cast< QAction* >(sender());
if (act != nullptr) {
QStringList data = SKGServices::splitCSVLine(act->data().toString(), '-');
if (data.count() == 2) {
selection.push_back(SKGObjectBase(m_currentBankDocument, data[1], SKGServices::stringToInt(data[0])));
}
}
if (selection.isEmpty()) {
selection = SKGMainPanel::getMainPanel()->getSelectedObjects();
}
int nb = selection.count();
if (nb > 0) {
QString wc;
QString titleOpen;
QString iconOpen;
QString table = selection.at(0).getRealTable();
QString view;
QString account;
if (table == QStringLiteral("account")) {
if (nb == 1) {
SKGAccountObject tmp(selection.at(0));
account = tmp.getName();
} else {
// Build whereclause and title
wc = QStringLiteral("rd_account_id in (");
titleOpen = i18nc("Noun, a list of items", "Operations of account:");
for (int i = 0; i < nb; ++i) {
SKGAccountObject tmp(selection.at(i));
if (i != 0) {
wc += ',';
titleOpen += ',';
}
wc += SKGServices::intToString(tmp.getID());
titleOpen += i18n("'%1'", tmp.getDisplayName());
}
wc += ')';
// Set icon
iconOpen = QStringLiteral("view-bank-account");
}
} else if (table == QStringLiteral("unit")) {
// Build whereclause and title
wc = QStringLiteral("rc_unit_id in (");
titleOpen = i18nc("Noun, a list of items", "Operations with unit:");
for (int i = 0; i < nb; ++i) {
SKGUnitObject tmp(selection.at(i));
if (i != 0) {
wc += ',';
titleOpen += ',';
}
wc += SKGServices::intToString(tmp.getID());
titleOpen += i18n("'%1'", tmp.getDisplayName());
}
wc += ')';
// Set icon
iconOpen = QStringLiteral("taxes-finances");
} else if (table == QStringLiteral("category")) {
titleOpen = i18nc("Noun, a list of items", "Sub operations with category:");
for (int i = 0; i < nb; ++i) {
SKGCategoryObject tmp(selection.at(i));
if (i != 0) {
wc += QStringLiteral(" OR ");
titleOpen += ',';
}
QString name = tmp.getFullName();
wc += QStringLiteral("(t_REALCATEGORY");
if (name.isEmpty()) {
wc += QStringLiteral(" IS NULL OR t_REALCATEGORY='')");
} else {
wc += " = '" % SKGServices::stringToSqlString(name) % "' OR t_REALCATEGORY like '" % SKGServices::stringToSqlString(name) % OBJECTSEPARATOR % "%')";
}
titleOpen += i18n("'%1'", tmp.getDisplayName());
}
// Set icon
iconOpen = QStringLiteral("view-categories");
view = QStringLiteral("v_suboperation_consolidated");
} else if (table == QStringLiteral("refund")) {
// Build whereclause and title
wc = QStringLiteral("t_REALREFUND in (");
titleOpen = i18nc("Noun, a list of items", "Sub operations followed by tracker:");
for (int i = 0; i < nb; ++i) {
SKGTrackerObject tmp(selection.at(i));
if (i != 0) {
wc += ',';
titleOpen += ',';
}
wc += '\'' % SKGServices::stringToSqlString(tmp.getName()) % '\'';
titleOpen += i18n("'%1'", tmp.getDisplayName());
}
wc += ')';
// Set icon
iconOpen = QStringLiteral("checkbox");
view = QStringLiteral("v_suboperation_consolidated");
} else if (table == QStringLiteral("payee")) {
// Build whereclause and title
wc = QStringLiteral("r_payee_id in (");
titleOpen = i18nc("Noun, a list of items", "Operations assigned to payee:");
for (int i = 0; i < nb; ++i) {
SKGPayeeObject tmp(selection.at(i));
if (i != 0) {
wc += ',';
titleOpen += ',';
}
wc += SKGServices::intToString(tmp.getID());
titleOpen += i18n("'%1'", tmp.getDisplayName());
}
wc += ')';
// Set icon
iconOpen = QStringLiteral("user-group-properties");
} else if (table == QStringLiteral("budget")) {
titleOpen = i18nc("Noun, a list of items", "Operations assigned to budget:");
for (int i = 0; i < nb; ++i) {
SKGBudgetObject tmp(selection.at(i));
if (i != 0) {
wc += QStringLiteral(" OR ");
titleOpen += ',';
}
wc += "(t_TYPEACCOUNT<>'L' AND i_SUBOPID IN (SELECT b2.id_suboperation FROM budgetsuboperation b2 WHERE b2.id=" % SKGServices::intToString(tmp.getID()) % "))";
titleOpen += i18n("'%1'", tmp.getDisplayName());
}
// Set icon
iconOpen = QStringLiteral("view-calendar-whatsnext");
view = QStringLiteral("v_suboperation_consolidated");
} else if (table == QStringLiteral("recurrentoperation")) {
titleOpen = i18nc("Noun, a list of items", "Scheduled operations:");
for (int i = 0; i < nb; ++i) {
SKGRecurrentOperationObject tmp(selection.at(i));
if (i != 0) {
wc += QStringLiteral(" OR ");
titleOpen += ',';
}
wc += "(EXISTS(SELECT 1 FROM recurrentoperation s WHERE s.rd_operation_id=v_operation_display.id and s.id=" % SKGServices::intToString(tmp.getID()) % ") OR r_recurrentoperation_id=" % SKGServices::intToString(tmp.getID()) + ')';
titleOpen += i18n("'%1'", tmp.getDisplayName());
}
// Set icon
iconOpen = QStringLiteral("chronometer");
view = QStringLiteral("v_operation_display");
} else if (table == QStringLiteral("rule")) {
titleOpen = i18nc("Noun, a list of items", "Sub operations corresponding to rule:");
for (int i = 0; i < nb; ++i) {
SKGRuleObject tmp(selection.at(i));
if (i != 0) {
wc += QStringLiteral(" OR ");
titleOpen += ',';
}
wc += "i_SUBOPID in (SELECT i_SUBOPID FROM v_operation_prop WHERE " % tmp.getSelectSqlOrder() % ')';
titleOpen += i18n("'%1'", tmp.getDisplayName());
}
// Set icon
iconOpen = QStringLiteral("edit-find");
view = QStringLiteral("v_suboperation_consolidated");
} else if (table == QStringLiteral("operation")) {
// Build whereclause and title
titleOpen = i18nc("Noun, a list of items", "Sub operations grouped or split of:");
view = QStringLiteral("v_suboperation_consolidated");
for (int i = 0; i < nb; ++i) {
SKGOperationObject tmp(selection.at(i));
if (i != 0) {
wc += QStringLiteral(" OR ");
titleOpen += ',';
}
int opid = tmp.getID();
wc += QStringLiteral("(i_OPID=") % SKGServices::intToString(opid);
opid = SKGServices::stringToInt(tmp.getAttribute(QStringLiteral("i_group_id")));
if (opid != 0) {
wc += " or i_group_id=" % SKGServices::intToString(opid);
}
wc += ')';
titleOpen += i18n("'%1'", tmp.getDisplayName());
}
// Set icon
iconOpen = icon();
} else if (table == QStringLiteral("suboperation")) {
// Build whereclause and title
titleOpen = i18nc("Noun, a list of items", "Operations grouped with:");
view = QStringLiteral("v_operation_display_all");
for (int i = 0; i < nb; ++i) {
SKGSubOperationObject tmp(selection.at(i).getDocument(), selection.at(i).getID());
SKGOperationObject op;
tmp.getParentOperation(op);
if (i != 0) {
wc += QStringLiteral(" OR ");
titleOpen += ',';
}
int opid = op.getID();
wc += QStringLiteral("(id=") % SKGServices::intToString(opid);
opid = SKGServices::stringToInt(op.getAttribute(QStringLiteral("i_group_id")));
if (opid != 0) {
wc += " or i_group_id=" % SKGServices::intToString(opid);
}
wc += ')';
titleOpen += i18n("'%1'", op.getDisplayName());
}
// Set icon
iconOpen = icon();
}
// Open
QDomDocument doc(QStringLiteral("SKGML"));
doc.setContent(SKGMainPanel::getMainPanel()->getDocument()->getParameter(view != QStringLiteral("v_suboperation_consolidated") ? QStringLiteral("SKGOPERATION_DEFAULT_PARAMETERS") : QStringLiteral("SKGOPERATION_CONSOLIDATED_DEFAULT_PARAMETERS")));
QDomElement root = doc.documentElement();
if (root.isNull()) {
root = doc.createElement(QStringLiteral("parameters"));
doc.appendChild(root);
}
if (!view.isEmpty()) {
root.setAttribute(QStringLiteral("operationTable"), view);
}
if (!wc.isEmpty()) {
root.setAttribute(QStringLiteral("operationWhereClause"), wc);
}
if (!titleOpen.isEmpty()) {
root.setAttribute(QStringLiteral("title"), titleOpen);
}
if (!iconOpen.isEmpty()) {
root.setAttribute(QStringLiteral("title_icon"), iconOpen);
}
if (!account.isEmpty()) {
root.setAttribute(QStringLiteral("account"), account);
} else {
root.setAttribute(QStringLiteral("currentPage"), QStringLiteral("-1"));
}
SKGMainPanel::getMainPanel()->openPage(SKGMainPanel::getMainPanel()->getPluginByName(QStringLiteral("Skrooge operation plugin")), -1, doc.toString());
}
}
}
SKGAdviceList SKGOperationPlugin::advice(const QStringList& iIgnoredAdvice)
{
SKGTRACEINFUNC(10)
SKGAdviceList output;
output.reserve(20);
int nbConcurrentCheckExecuted = 0;
int nbConcurrentCheckTargeted = 0;
QMutex mutex;
// Search duplicate number on operation
if (!iIgnoredAdvice.contains(QStringLiteral("skgoperationplugin_duplicate"))) {
nbConcurrentCheckTargeted++;
m_currentBankDocument->concurrentExecuteSelectSqliteOrder(QStringLiteral("SELECT count(1), t_ACCOUNT, t_number FROM v_operation WHERE t_number!='' GROUP BY t_ACCOUNT, t_number HAVING count(1)>1 ORDER BY count(1) DESC"), [ & ](const SKGStringListList & iResult) {
int nb = iResult.count();
SKGAdvice::SKGAdviceActionList autoCorrections;
for (int i = 1; i < nb; ++i) { // Ignore header
// Get parameters
const QStringList& line = iResult.at(i);
const QString& account = line.at(1);
const QString& number = line.at(2);
SKGAdvice ad;
ad.setUUID("skgoperationplugin_duplicate|" % number % ';' % account);
ad.setPriority(7);
ad.setShortMessage(i18nc("Advice on making the best (short)", "Duplicate number %1 in account '%2'", number, account));
ad.setLongMessage(i18nc("Advice on making the best (long)", "Your account '%1' contains more than one operation with number %2.The operation number should be unique (check number, transaction reference...)", account, number));
autoCorrections.resize(0);
{
SKGAdvice::SKGAdviceAction a;
a.Title = i18nc("Advice on making the best (action)", "Edit operations with duplicate number");
a.IconName = QStringLiteral("quickopen");
a.IsRecommended = false;
autoCorrections.push_back(a);
}
ad.setAutoCorrections(autoCorrections);
mutex.lock();
output.push_back(ad);
mutex.unlock();
}
mutex.lock();
nbConcurrentCheckExecuted++;
mutex.unlock();
}, false);
}
// Check operations not reconciliated
if (!iIgnoredAdvice.contains(QStringLiteral("skgoperationplugin_notreconciliated"))) {
nbConcurrentCheckTargeted++;
m_currentBankDocument->concurrentExecuteSelectSqliteOrder(QStringLiteral("SELECT count(1), t_ACCOUNT FROM v_operation WHERE t_status='N' GROUP BY t_ACCOUNT HAVING count(1)>100 ORDER BY count(1) DESC"), [ & ](const SKGStringListList & iResult) {
int nb = iResult.count();
SKGAdvice::SKGAdviceActionList autoCorrections;
for (int i = 1; i < nb; ++i) { // Ignore header
// Get parameters
const QStringList& line = iResult.at(i);
const QString& account = line.at(1);
SKGAdvice ad;
ad.setUUID("skgoperationplugin_notreconciliated|" % account);
ad.setPriority(9);
ad.setShortMessage(i18nc("Advice on making the best (short)", "Many operations of '%1' not reconciliated", account));
ad.setLongMessage(i18nc("Advice on making the best (long)", "Do not forget to reconciliate your accounts. By doing so, you acknowledge that your bank has indeed processed these operations on your account. This is how you enforce compliance with your bank's statements. See online help for more details"));
autoCorrections.resize(0);
{
SKGAdvice::SKGAdviceAction a;
a.Title = i18nc("Advice on making the best (action)", "Open account '%1' for reconciliation", account);
a.IconName = QStringLiteral("quickopen");
a.IsRecommended = false;
autoCorrections.push_back(a);
}
ad.setAutoCorrections(autoCorrections);
mutex.lock();
output.push_back(ad);
mutex.unlock();
}
mutex.lock();
nbConcurrentCheckExecuted++;
mutex.unlock();
}, false);
}
// Not enough money in your account
if (!iIgnoredAdvice.contains(QStringLiteral("skgoperationplugin_minimum_limit"))) {
nbConcurrentCheckTargeted++;
// Get accounts with amount close or below the minimum limit
m_currentBankDocument->concurrentExecuteSelectSqliteOrder(QStringLiteral("SELECT t_name FROM v_account_amount WHERE t_close='N' AND t_minamount_enabled='Y' AND f_CURRENTAMOUNT<f_CURRENTAMOUNTUNIT*f_minamount"), [ & ](const SKGStringListList & iResult) {
int nb = iResult.count();
mutex.lock();
output.reserve(output.count() + nb);
mutex.unlock();
for (int i = 1; i < nb; ++i) { // Ignore header
// Get parameters
QString account = iResult.at(i).at(0);
SKGAdvice ad;
ad.setUUID("skgoperationplugin_minimum_limit|" % account);
ad.setPriority(9);
ad.setShortMessage(i18nc("Advice on making the best (short)", "Not enough money in your account '%1'", account));
ad.setLongMessage(i18nc("Advice on making the best (long)", "The amount of this account is below the minimum limit. You should replenish it."));
mutex.lock();
output.push_back(ad);
mutex.unlock();
}
mutex.lock();
nbConcurrentCheckExecuted++;
mutex.unlock();
}, false);
}
// Maximum limit reached
if (!iIgnoredAdvice.contains(QStringLiteral("skgoperationplugin_maximum_limit"))) {
nbConcurrentCheckTargeted++;
// Get accounts with amount over the maximum limit
m_currentBankDocument->concurrentExecuteSelectSqliteOrder(QStringLiteral("SELECT t_name FROM v_account_amount WHERE t_close='N' AND t_maxamount_enabled='Y' AND f_CURRENTAMOUNT>f_CURRENTAMOUNTUNIT*f_maxamount"), [ & ](const SKGStringListList & iResult) {
int nb = iResult.count();
mutex.lock();
output.reserve(output.count() + nb);
mutex.unlock();
for (int i = 1; i < nb; ++i) { // Ignore header
// Get parameters
QString account = iResult.at(i).at(0);
SKGAdvice ad;
ad.setUUID("skgoperationplugin_maximum_limit|" % account);
ad.setPriority(6);
ad.setShortMessage(i18nc("Advice on making the best (short)", "Balance in account '%1' exceeds the maximum limit", account));
ad.setLongMessage(i18nc("Advice on making the best (long)", "The balance of this account exceeds the maximum limit."));
mutex.lock();
output.push_back(ad);
mutex.unlock();
}
mutex.lock();
nbConcurrentCheckExecuted++;
mutex.unlock();
}, false);
}
// Minimum limit reached
if (!iIgnoredAdvice.contains(QStringLiteral("skgoperationplugin_close_minimum_limit"))) {
nbConcurrentCheckTargeted++;
// Get accounts with amount close or below the minimum limit
m_currentBankDocument->concurrentExecuteSelectSqliteOrder(QStringLiteral("SELECT t_name FROM v_account_amount WHERE t_close='N' AND t_minamount_enabled='Y' AND t_maxamount_enabled='Y'"
" AND f_CURRENTAMOUNT>=f_CURRENTAMOUNTUNIT*f_minamount AND f_CURRENTAMOUNT<=f_CURRENTAMOUNTUNIT*f_minamount+0.1*(f_CURRENTAMOUNTUNIT*f_maxamount-f_CURRENTAMOUNTUNIT*f_minamount)"), [ & ](const SKGStringListList & iResult) {
int nb = iResult.count();
mutex.lock();
output.reserve(output.count() + nb);
mutex.unlock();
for (int i = 1; i < nb; ++i) { // Ignore header
// Get parameters
QString account = iResult.at(i).at(0);
SKGAdvice ad;
ad.setUUID("skgoperationplugin_close_minimum_limit|" % account);
ad.setPriority(5);
ad.setShortMessage(i18nc("Advice on making the best (short)", "Your account '%1' is close to the minimum limit", account));
ad.setLongMessage(i18nc("Advice on making the best (long)", "The amount of this account is close to the minimum limit. You should take care of it."));
mutex.lock();
output.push_back(ad);
mutex.unlock();
}
mutex.lock();
nbConcurrentCheckExecuted++;
mutex.unlock();
}, false);
}
// Too much money in your account
if (!iIgnoredAdvice.contains(QStringLiteral("skgoperationplugin_too_much_money"))) {
nbConcurrentCheckTargeted++;
m_currentBankDocument->concurrentExecuteSelectSqliteOrder(QStringLiteral("SELECT t_name, f_RATE FROM v_account_display WHERE t_close='N' AND f_RATE>0 AND (t_maxamount_enabled='N' OR f_CURRENTAMOUNT<f_CURRENTAMOUNTUNIT*f_maxamount*0.9) ORDER BY f_RATE DESC"), [ & ](const SKGStringListList & iResult) {
int nb = iResult.count();
if (nb > 1) {
// Get better interest account
QString target = iResult.at(1).at(0);
QString rate = iResult.at(1).at(1);
// Get accounts with too much money
m_currentBankDocument->concurrentExecuteSelectSqliteOrder("SELECT t_name FROM v_account_display WHERE t_close='N' AND ("
// Interest are computed on amount over the limit too, not need to transfer them "(t_maxamount_enabled='Y' AND f_CURRENTAMOUNT>f_CURRENTAMOUNTUNIT*f_maxamount) OR "
"(f_RATE<" % rate % " AND t_type='C' AND f_CURRENTAMOUNT>-2*(SELECT TOTAL(s.f_CURRENTAMOUNT) FROM v_operation_display s WHERE s.rd_account_id=v_account_display.id AND s.t_TYPEEXPENSE='-' AND s.d_DATEMONTH = (SELECT strftime('%Y-%m',date('now','start of month', '-1 MONTH')))))"
")", [ &output, target, rate ](const SKGStringListList & iResult2) {
int nb = iResult2.count();
QMutex mutex;
mutex.lock();
output.reserve(output.count() + nb);
mutex.unlock();
for (int i = 1; i < nb; ++i) { // Ignore header
// Get parameters
QString account = iResult2.at(i).at(0);
SKGAdvice ad;
ad.setUUID("skgoperationplugin_too_much_money|" % account);
ad.setPriority(6);
ad.setShortMessage(i18nc("Advice on making the best (short)", "Too much money in your account '%1'", account));
ad.setLongMessage(i18nc("Advice on making the best (long)", "You could save money on an account with a better rate. Example: '%1' (%2%)", target, rate));
mutex.lock();
output.push_back(ad);
mutex.unlock();
}
}, false);
}
mutex.lock();
nbConcurrentCheckExecuted++;
mutex.unlock();
}, false);
}
// Check operations without mode
if (!iIgnoredAdvice.contains(QStringLiteral("skgimportexportplugin_notvalidated"))) {
nbConcurrentCheckTargeted++;
m_currentBankDocument->concurrentExistObjects(QStringLiteral("operation"),
QStringLiteral("t_template='N' AND t_mode='' AND d_date<>'0000-00-00'"),
[ & ](bool iFound) {
if (iFound) {
SKGAdvice ad;
ad.setUUID(QStringLiteral("skgimportexportplugin_notvalidated"));
ad.setPriority(5);
ad.setShortMessage(i18nc("Advice on making the best (short)", "Many operations do not have mode"));
ad.setLongMessage(i18nc("Advice on making the best (long)", "Do not forget to set a mode for each operation. This will allow you to generate better reports."));
QStringList autoCorrections;
autoCorrections.push_back(QStringLiteral("skg://view_open_operation_without_mode"));
ad.setAutoCorrections(autoCorrections);
mutex.lock();
output.push_back(ad);
mutex.unlock();
}
mutex.lock();
nbConcurrentCheckExecuted++;
mutex.unlock();
}, false);
}
// Check operations without category
if (!iIgnoredAdvice.contains(QStringLiteral("skgoperationplugin_nocategory"))) {
nbConcurrentCheckTargeted++;
m_currentBankDocument->concurrentExistObjects(QStringLiteral("v_operation_display"),
QStringLiteral("t_TRANSFER='N' AND EXISTS (SELECT 1 FROM suboperation WHERE rd_operation_id=v_operation_display.id AND r_category_id=0)"),
[ & ](bool iFound) {
if (iFound) {
SKGAdvice ad;
ad.setUUID(QStringLiteral("skgoperationplugin_nocategory"));
ad.setPriority(5);
ad.setShortMessage(i18nc("Advice on making the best (short)", "Many operations do not have category"));
ad.setLongMessage(i18nc("Advice on making the best (long)", "Do not forget to associate a category for each operation. This will allow you to generate better reports."));
QStringList autoCorrections;
autoCorrections.push_back(QStringLiteral("skg://view_open_operation_without_category"));
ad.setAutoCorrections(autoCorrections);
mutex.lock();
output.push_back(ad);
mutex.unlock();
}
mutex.lock();
nbConcurrentCheckExecuted++;
mutex.unlock();
}, false);
}
if (!iIgnoredAdvice.contains(QStringLiteral("skgoperationplugin_transfer_nocategory"))) {
nbConcurrentCheckTargeted++;
m_currentBankDocument->concurrentExistObjects(QStringLiteral("v_operation_display"),
QStringLiteral("t_TRANSFER='Y' AND EXISTS (SELECT 1 FROM suboperation WHERE rd_operation_id=v_operation_display.id AND r_category_id=0)"),
[ & ](bool iFound) {
if (iFound) {
SKGAdvice ad;
ad.setUUID(QStringLiteral("skgoperationplugin_transfer_nocategory"));
ad.setPriority(3);
ad.setShortMessage(i18nc("Advice on making the best (short)", "Many transfers do not have category"));
ad.setLongMessage(i18nc("Advice on making the best (long)", "Do not forget to associate a category for each transfer."));
QStringList autoCorrections;
autoCorrections.push_back(QStringLiteral("skg://view_open_transfers_without_category"));
ad.setAutoCorrections(autoCorrections);
mutex.lock();
output.push_back(ad);
mutex.unlock();
}
mutex.lock();
nbConcurrentCheckExecuted++;
mutex.unlock();
}, false);
}
// Check operations without payee
if (!iIgnoredAdvice.contains(QStringLiteral("skgoperationplugin_nopayee"))) {
nbConcurrentCheckTargeted++;
m_currentBankDocument->concurrentExistObjects(QStringLiteral("v_operation_display"),
QStringLiteral("t_TRANSFER='N' AND r_payee_id=0"),
[ & ](bool iFound) {
if (iFound) {
SKGAdvice ad;
ad.setUUID(QStringLiteral("skgoperationplugin_nopayee"));
ad.setPriority(5);
ad.setShortMessage(i18nc("Advice on making the best (short)", "Many operations do not have payee"));
ad.setLongMessage(i18nc("Advice on making the best (long)", "Do not forget to associate a payee for each operation. This will allow you to generate better reports."));
QStringList autoCorrections;
autoCorrections.push_back(QStringLiteral("skg://view_open_operation_without_payee"));
ad.setAutoCorrections(autoCorrections);
mutex.lock();
output.push_back(ad);
mutex.unlock();
}
mutex.lock();
nbConcurrentCheckExecuted++;
mutex.unlock();
}, false);
}
if (!iIgnoredAdvice.contains(QStringLiteral("skgoperationplugin_transfer_nopayee"))) {
nbConcurrentCheckTargeted++;
m_currentBankDocument->concurrentExistObjects(QStringLiteral("v_operation_display"),
QStringLiteral("t_TRANSFER='Y' AND r_payee_id=0"),
[ & ](bool iFound) {
if (iFound) {
SKGAdvice ad;
ad.setUUID(QStringLiteral("skgoperationplugin_transfer_nopayee"));
ad.setPriority(3);
ad.setShortMessage(i18nc("Advice on making the best (short)", "Many transfers do not have payee"));
ad.setLongMessage(i18nc("Advice on making the best (long)", "Do not forget to associate a payee for each transfer."));
QStringList autoCorrections;
autoCorrections.push_back(QStringLiteral("skg://view_open_transfers_without_payee"));
ad.setAutoCorrections(autoCorrections);
mutex.lock();
output.push_back(ad);
mutex.unlock();
}
mutex.lock();
nbConcurrentCheckExecuted++;
mutex.unlock();
}, false);
}
// Check operations in group of only one transaction
if (!iIgnoredAdvice.contains(QStringLiteral("skgoperationplugin_groupofone"))) {
nbConcurrentCheckTargeted++;
m_currentBankDocument->concurrentExistObjects(QStringLiteral("v_operation_display"),
QStringLiteral("i_group_id<>0 AND (SELECT COUNT(1) FROM operation o WHERE o.i_group_id=v_operation_display.i_group_id)<2"),
[ & ](bool iFound) {
if (iFound) {
SKGAdvice ad;
ad.setUUID(QStringLiteral("skgoperationplugin_groupofone"));
ad.setPriority(4);
ad.setShortMessage(i18nc("Advice on making the best (short)", "Some operations are in groups with only one operation"));
ad.setLongMessage(i18nc("Advice on making the best (long)", "When a transfer is created and when only one part of this transfer is removed, the second part is in a group of only one operation. This makes no sense."));
SKGAdvice::SKGAdviceActionList autoCorrections;
{
SKGAdvice::SKGAdviceAction a;
a.Title = QStringLiteral("skg://view_open_operation_in_group_of_one");
a.IsRecommended = false;
autoCorrections.push_back(a);
}
{
SKGAdvice::SKGAdviceAction a;
a.Title = QStringLiteral("skg://clean_remove_group_with_one_operation");
a.IsRecommended = true;
autoCorrections.push_back(a);
}
ad.setAutoCorrections(autoCorrections);
mutex.lock();
output.push_back(ad);
mutex.unlock();
}
mutex.lock();
nbConcurrentCheckExecuted++;
mutex.unlock();
}, false);
}
// Check simple operations with comment not aligned with the comment of the suboperation
if (!iIgnoredAdvice.contains(QStringLiteral("skgoperationplugin_commentsnotaligned"))) {
nbConcurrentCheckTargeted++;
m_currentBankDocument->concurrentExistObjects(QStringLiteral("operation op, suboperation so"),
QStringLiteral("so.rd_operation_id=op.id AND so.t_comment<>op.t_comment AND (SELECT COUNT(1) FROM suboperation so2 WHERE so2.rd_operation_id=op.id)=1"),
[ & ](bool iFound) {
if (iFound) {
SKGAdvice ad;
ad.setUUID(QStringLiteral("skgoperationplugin_commentsnotaligned"));
ad.setPriority(5);
ad.setShortMessage(i18nc("Advice on making the best (short)", "Some simple operations do not have their comments aligned"));
ad.setLongMessage(i18nc("Advice on making the best (long)", "The comment of the operation is not aligned with the comment of the suboperation."));
SKGAdvice::SKGAdviceActionList autoCorrections;
{
SKGAdvice::SKGAdviceAction a;
a.Title = QStringLiteral("skg://view_open_operation_with_comment_not_aligned");
a.IsRecommended = false;
autoCorrections.push_back(a);
}
{
SKGAdvice::SKGAdviceAction a;
a.Title = QStringLiteral("skg://clean_align_comment");
a.IsRecommended = true;
autoCorrections.push_back(a);
}
ad.setAutoCorrections(autoCorrections);
mutex.lock();
output.push_back(ad);
mutex.unlock();
}
mutex.lock();
nbConcurrentCheckExecuted++;
mutex.unlock();
}, false);
}
// Check simple operations with date not aligned with the date of the suboperation
if (!iIgnoredAdvice.contains(QStringLiteral("skgoperationplugin_datesnotaligned"))) {
nbConcurrentCheckTargeted++;
m_currentBankDocument->concurrentExistObjects(QStringLiteral("operation op, suboperation so"),
QStringLiteral("so.rd_operation_id=op.id AND (so.d_date<op.d_date OR (so.d_date<>op.d_date AND (SELECT COUNT(1) FROM suboperation so2 WHERE so2.rd_operation_id=op.id)=1))"),
[ & ](bool iFound) {
if (iFound) {
SKGAdvice ad;
ad.setUUID(QStringLiteral("skgoperationplugin_datesnotaligned"));
ad.setPriority(5);
ad.setShortMessage(i18nc("Advice on making the best (short)", "Some operations do not have their dates aligned"));
ad.setLongMessage(i18nc("Advice on making the best (long)", "The date of the operation is not aligned with the date of the suboperation. This case seems to be abnormal."));
SKGAdvice::SKGAdviceActionList autoCorrections;
{
SKGAdvice::SKGAdviceAction a;
a.Title = QStringLiteral("skg://view_open_operation_with_date_not_aligned");
a.IsRecommended = false;
autoCorrections.push_back(a);
}
{
SKGAdvice::SKGAdviceAction a;
a.Title = QStringLiteral("skg://clean_align_date");
a.IsRecommended = true;
autoCorrections.push_back(a);
}
ad.setAutoCorrections(autoCorrections);
mutex.lock();
output.push_back(ad);
mutex.unlock();
}
mutex.lock();
nbConcurrentCheckExecuted++;
mutex.unlock();
}, false);
}
do {
QThread::yieldCurrentThread();
if (nbConcurrentCheckExecuted == nbConcurrentCheckTargeted) {
break;
}
} while (true);
return output;
}
SKGError SKGOperationPlugin::executeAdviceCorrection(const QString& iAdviceIdentifier, int iSolution)
{
if ((m_currentBankDocument != nullptr) && iAdviceIdentifier.startsWith(QLatin1String("skgoperationplugin_duplicate|"))) {
// Get parameters
QString parameters = iAdviceIdentifier.right(iAdviceIdentifier.length() - 29);
int pos = parameters.indexOf(';');
QString num = parameters.left(pos);
QString account = parameters.right(parameters.length() - 1 - pos);
// Call operation plugin
SKGMainPanel::getMainPanel()->openPage("skg://skrooge_operation_plugin/?title_icon=security-low&title=" % SKGServices::encodeForUrl(i18nc("Noun, a list of items", "Operations of '%1' with duplicate number %2", account, num)) %
"&operationWhereClause=" % SKGServices::encodeForUrl("t_number='" % SKGServices::stringToSqlString(num) % "' AND t_ACCOUNT='" % SKGServices::stringToSqlString(account) % '\''));
return SKGError();
}
if ((m_currentBankDocument != nullptr) && iAdviceIdentifier.startsWith(QLatin1String("skgoperationplugin_notreconciliated|"))) {
// Get parameters
QString account = iAdviceIdentifier.right(iAdviceIdentifier.length() - 36);
SKGMainPanel::getMainPanel()->openPage("skg://skrooge_operation_plugin/?currentPage=-1&modeInfoZone=1&account=" % SKGServices::encodeForUrl(account));
return SKGError();
}
return SKGInterfacePlugin::executeAdviceCorrection(iAdviceIdentifier, iSolution);
}
void SKGOperationPlugin::onRemoveGroupWithOneOperation()
{
SKGError err;
SKGTRACEINFUNCRC(10, err) {
SKGObjectBase::SKGListSKGObjectBase selection = SKGMainPanel::getMainPanel()->getSelectedObjects();
auto* act = qobject_cast< QAction* >(sender());
if ((act == nullptr) || !act->data().toBool()) {
// Clear selection to enable the model "All"
selection.clear();
}
SKGBEGINTRANSACTION(*m_currentBankDocument, i18nc("Noun, name of the user action", "Remove groups with only one operation"), err)
QString q = QStringLiteral("UPDATE operation SET i_group_id=0 WHERE i_group_id<>0 AND (SELECT COUNT(1) FROM operation o WHERE o.i_group_id=operation.i_group_id)<2");
int nb = selection.count();
if (nb == 0) {
err = m_currentBankDocument->executeSqliteOrder(q);
} else {
for (int i = 0; !err && i < nb; ++i) {
SKGOperationObject op(selection.at(i));
err = m_currentBankDocument->executeSqliteOrder(q % " AND id=" % SKGServices::intToString(op.getID()));
}
}
}
// status bar
IFOKDO(err, SKGError(0, i18nc("Message for successful user action", "Remove groups done.")))
else {
err.addError(ERR_FAIL, i18nc("Error message", "Remove groups failed"));
}
// Display error
SKGMainPanel::displayErrorMessage(err);
}
void SKGOperationPlugin::onAlignComment()
{
SKGError err;
SKGTRACEINFUNCRC(10, err)
{
SKGObjectBase::SKGListSKGObjectBase selection = SKGMainPanel::getMainPanel()->getSelectedObjects();
auto* act = qobject_cast< QAction* >(sender());
if ((act == nullptr) || !act->data().toBool()) {
// Clear selection to enable the model "All"
selection.clear();
}
SKGBEGINTRANSACTION(*m_currentBankDocument, i18nc("Noun, name of the user action", "Align comment of suboperations"), err)
QString q = QStringLiteral("UPDATE suboperation SET t_comment=(SELECT op.t_comment FROM operation op WHERE suboperation.rd_operation_id=op.id) WHERE suboperation.id IN (SELECT so.id FROM operation op, suboperation so WHERE so.rd_operation_id=op.id AND so.t_comment<>op.t_comment AND (SELECT COUNT(1) FROM suboperation so2 WHERE so2.rd_operation_id=op.id)=1)");
int nb = selection.count();
if (nb == 0) {
err = m_currentBankDocument->executeSqliteOrder(q);
} else {
for (int i = 0; !err && i < nb; ++i) {
SKGOperationObject op(selection.at(i));
err = m_currentBankDocument->executeSqliteOrder(q % " AND rd_operation_id=" % SKGServices::intToString(op.getID()));
}
}
}
// status bar
IFOKDO(err, SKGError(0, i18nc("Message for successful user action", "Comments aligned.")))
else {
err.addError(ERR_FAIL, i18nc("Error message", "Comments alignment failed"));
}
// Display error
SKGMainPanel::displayErrorMessage(err);
}
void SKGOperationPlugin::onAlignDate()
{
SKGError err;
SKGTRACEINFUNCRC(10, err)
{
SKGObjectBase::SKGListSKGObjectBase selection = SKGMainPanel::getMainPanel()->getSelectedObjects();
auto* act = qobject_cast< QAction* >(sender());
if ((act == nullptr) || !act->data().toBool()) {
// Clear selection to enable the model "All"
selection.clear();
}
SKGBEGINTRANSACTION(*m_currentBankDocument, i18nc("Noun, name of the user action", "Align date of suboperations"), err)
QString q = QStringLiteral("UPDATE suboperation SET d_date=(SELECT op.d_date FROM operation op WHERE suboperation.rd_operation_id=op.id) WHERE suboperation.id IN (SELECT so.id FROM operation op, suboperation so WHERE so.rd_operation_id=op.id AND (so.d_date<op.d_date OR (so.d_date<>op.d_date AND (SELECT COUNT(1) FROM suboperation so2 WHERE so2.rd_operation_id=op.id)=1)))");
int nb = selection.count();
if (nb == 0) {
err = m_currentBankDocument->executeSqliteOrder(q);
} else {
for (int i = 0; !err && i < nb; ++i) {
SKGOperationObject op(selection.at(i));
err = m_currentBankDocument->executeSqliteOrder(q % " AND rd_operation_id=" % SKGServices::intToString(op.getID()));
}
}
}
// status bar
IFOKDO(err, SKGError(0, i18nc("Message for successful user action", "Dates aligned.")))
else {
err.addError(ERR_FAIL, i18nc("Error message", "Dates alignment failed"));
}
// Display error
SKGMainPanel::displayErrorMessage(err);
}
void SKGOperationPlugin::onMergeSubOperations()
{
SKGError err;
SKGTRACEINFUNCRC(10, err)
if ((SKGMainPanel::getMainPanel() != nullptr) && (m_currentBankDocument != nullptr)) {
SKGObjectBase::SKGListSKGObjectBase selection = SKGMainPanel::getMainPanel()->getSelectedObjects();
int nb = selection.count();
if (nb >= 2) {
SKGBEGINTRANSACTION(*m_currentBankDocument, i18nc("Noun, name of the user action", "Merge sub operations"), err)
SKGOperationObject op(selection.at(0));
for (int i = 1; !err && i < nb; ++i) {
SKGOperationObject op2(selection.at(i));
err = op.mergeSuboperations(op2);
// Send message
IFOKDO(err, op.getDocument()->sendMessage(i18nc("An information to the user", "The sub operations of '%1' have been merged in the operation '%2'", op2.getDisplayName(), op.getDisplayName()), SKGDocument::Hidden))
}
}
}
// status bar
IFOKDO(err, SKGError(0, i18nc("Successful message after an user action", "Operations merged.")))
else {
err.addError(ERR_FAIL, i18nc("Error message", "Merge failed"));
}
// Display error
SKGMainPanel::displayErrorMessage(err);
}
void SKGOperationPlugin::onShowOpenWithMenu()
{
if ((m_openOperationsWithMenu != nullptr) && (m_currentBankDocument != nullptr)) {
// Clean Menu
auto* m = qobject_cast<QMenu*>(sender());
bool modeOperation = (m == m_openOperationsWithMenu);
m->clear();
// Get Selection
auto selection = SKGMainPanel::getMainPanel()->getSelectedObjects();
// Build list od attribute to take into account
QStringList existingAttributes;
m_currentBankDocument->getAttributesList(modeOperation ? QStringLiteral("v_operation_display") : QStringLiteral("v_suboperation_consolidated"), existingAttributes);
QStringList attributes;
auto schema = SKGServices::splitCSVLine(m_currentBankDocument->getDisplaySchemas(modeOperation ? QStringLiteral("operation") : QStringLiteral("suboperation")).at(0).schema);
attributes.reserve(attributes.count());
for (const auto& att : schema) {
auto a = SKGServices::splitCSVLine(att, QLatin1Char('|')).value(0);
if (existingAttributes.contains(a) && !a.endsWith(QLatin1String("_INCOME")) && !a.endsWith(QLatin1String("_EXPENSE"))) {
attributes.push_back(a);
}
}
// Build menus
auto unitp = m_currentBankDocument->getPrimaryUnit();
int nb = attributes.count();
for (int i = 0; i < nb; ++i) {
// Add actions
QString att = attributes[i];
QString attDisplay = m_currentBankDocument->getDisplay(att);
QString value = selection[0].getAttribute(att);
QString iconName = m_currentBankDocument->getIconName(att);
QString wc = att;
if (att.startsWith(QLatin1String("f_"))) {
wc += '=' % SKGServices::stringToSqlString(value);
} else {
wc += "='" % SKGServices::stringToSqlString(value) % '\'';
}
if (att.startsWith(QStringLiteral("f_"))) {
auto unit = unitp;
if (!att.contains(QStringLiteral("QUANTITY")) && !att.contains(QStringLiteral("f_BALANCE_ENTERED"))) {
value = SKGServices::toCurrencyString(SKGServices::stringToDouble(value), unit.Symbol, unit.NbDecimal);
} else {
unit.NbDecimal = SKGServices::stringToInt(selection[0].getAttribute(QStringLiteral("i_NBDEC")));
if (unit.NbDecimal == 0) {
unit.NbDecimal = 2;
}
if (att != QStringLiteral("f_QUANTITYOWNED")) {
unit.Symbol = selection[0].getAttribute(QStringLiteral("t_UNIT"));
}
value = SKGServices::toCurrencyString(SKGServices::stringToDouble(value), unit.Symbol, unit.NbDecimal);
}
}
QString title = i18nc("A condition", "%1 = %2", attDisplay, value);
if (!value.isEmpty() && att != attDisplay) {
QAction* act = m->addAction(m_currentBankDocument->getIcon(att), title);
if (act != nullptr) {
connect(act, &QAction::triggered, this, [ title, wc, iconName, modeOperation ]() {
QString view = modeOperation ? QStringLiteral("v_operation_display") : QStringLiteral("v_suboperation_consolidated");
// Open
QDomDocument doc(QStringLiteral("SKGML"));
doc.setContent(SKGMainPanel::getMainPanel()->getDocument()->getParameter(view != QStringLiteral("v_suboperation_consolidated") ? QStringLiteral("SKGOPERATION_DEFAULT_PARAMETERS") : QStringLiteral("SKGOPERATION_CONSOLIDATED_DEFAULT_PARAMETERS")));
QDomElement root = doc.documentElement();
if (root.isNull()) {
root = doc.createElement(QStringLiteral("parameters"));
doc.appendChild(root);
}
root.setAttribute(QStringLiteral("operationTable"), view);
root.setAttribute(QStringLiteral("operationWhereClause"), wc);
root.setAttribute(QStringLiteral("title"), title);
root.setAttribute(QStringLiteral("title_icon"), iconName);
SKGMainPanel::getMainPanel()->openPage(SKGMainPanel::getMainPanel()->getPluginByName(QStringLiteral("Skrooge operation plugin")), -1, doc.toString());
});
}
}
}
}
}
#include <skgoperationplugin.moc>
diff --git a/plugins/skrooge/skrooge_operation/skgoperationplugin.h b/plugins/skrooge/skrooge_operation/skgoperationplugin.h
index 5baf81d03..cb22bb5b0 100644
--- a/plugins/skrooge/skrooge_operation/skgoperationplugin.h
+++ b/plugins/skrooge/skrooge_operation/skgoperationplugin.h
@@ -1,187 +1,187 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGOPERATIONPLUGIN_H
#define SKGOPERATIONPLUGIN_H
/** @file
* This file is Skrooge plugin for operation management.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skginterfaceplugin.h"
#include "ui_skgoperationpluginwidget_pref.h"
class QMenu;
class SKGDocumentBank;
/**
* This file is Skrooge plugin for operation management
*/
class SKGOperationPlugin : public SKGInterfacePlugin
{
Q_OBJECT
Q_INTERFACES(SKGInterfacePlugin)
public:
/**
* Default Constructor
*/
explicit SKGOperationPlugin(QWidget* iWidget, QObject* iParent, const QVariantList& iArg);
/**
* Default Destructor
*/
~SKGOperationPlugin() override;
/**
* Called to initialise the plugin
* @param iDocument the main document
* @return true if the plugin is compatible with the document
*/
bool setupActions(SKGDocument* iDocument) override;
/**
* Must be modified to refresh widgets after a modification.
*/
void refresh() override;
/**
* The number of dashboard widgets of the plugin.
* @return The number of dashboard widgets of the plugin
*/
int getNbDashboardWidgets() override;
/**
* Get a dashboard widget title of the plugin.
* @param iIndex the index of the widget
* @return The title
*/
QString getDashboardWidgetTitle(int iIndex) override;
/**
* Get a dashboard widget of the plugin.
* @param iIndex the index of the widget
* @return The dashboard widget of the plugin
*/
SKGBoardWidget* getDashboardWidget(int iIndex) override;
/**
* The preference widget of the plugin.
* @return The preference widget of the plugin
*/
QWidget* getPreferenceWidget() override;
/**
* The preference skeleton of the plugin.
* @return The preference skeleton of the plugin
*/
KConfigSkeleton* getPreferenceSkeleton() override;
/**
* This function is called when preferences have been modified. Must be used to save some parameters into the document.
* A transaction is already opened
* @return an object managing the error.
* @see SKGError
*/
SKGError savePreferences() const override;
/**
* The page widget of the plugin.
* @return The page widget of the plugin
*/
SKGTabPage* getWidget() override;
/**
* The title of the plugin.
* @return The title of the plugin
*/
QString title() const override;
/**
* The icon of the plugin.
* @return The icon of the plugin
*/
QString icon() const override;
/**
* The toolTip of the plugin.
* @return The toolTip of the plugin
*/
QString toolTip() const override;
/**
* The tips list of the plugin.
* @return The tips list of the plugin
*/
QStringList tips() const override;
/**
* Must be implemented to set the position of the plugin.
* @return integer value between 0 and 999 (default = 999)
*/
int getOrder() const override;
/**
* Must be implemented to know if a plugin must be display in pages chooser.
* @return true of false (default = false)
*/
bool isInPagesChooser() const override;
/**
* The advice list of the plugin.
* @return The advice list of the plugin
*/
SKGAdviceList advice(const QStringList& iIgnoredAdvice) override;
/**
* Must be implemented to execute the automatic correction for the advice.
* @param iAdviceIdentifier the identifier of the advice
* @param iSolution the identifier of the possible solution
* @return an object managing the error. MUST return ERR_NOTIMPL if iAdviceIdentifier is not known
* @see SKGError
*/
SKGError executeAdviceCorrection(const QString& iAdviceIdentifier, int iSolution) override;
private Q_SLOTS:
void onDuplicate();
void onCreateTemplate();
void onSwitchToPointed();
void onOpenOperations();
void onGroupOperation();
void onUngroupOperation();
void onMergeSubOperations();
void onAlignComment();
void onAlignDate();
void onRemoveGroupWithOneOperation();
void onShowApplyTemplateMenu();
void onApplyTemplate();
void onShowOpenWithMenu();
private:
Q_DISABLE_COPY(SKGOperationPlugin)
static SKGError checkReconciliation(SKGDocument* /*iDocument*/);
static SKGError checkImport(SKGDocument* /*iDocument*/);
QMenu* m_applyTemplateMenu;
QMenu* m_openOperationsWithMenu;
QMenu* m_openSubOperationsWithMenu;
SKGDocumentBank* m_currentBankDocument;
Ui::skgoperationplugin_pref ui{};
};
#endif // SKGOPERATIONPLUGIN_H
diff --git a/plugins/skrooge/skrooge_operation/skgoperationpluginwidget.cpp b/plugins/skrooge/skrooge_operation/skgoperationpluginwidget.cpp
index 5ec47c739..20163fb96 100644
--- a/plugins/skrooge/skrooge_operation/skgoperationpluginwidget.cpp
+++ b/plugins/skrooge/skrooge_operation/skgoperationpluginwidget.cpp
@@ -1,2681 +1,2681 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is Skrooge plugin for operation management.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgoperationpluginwidget.h"
#include <kcolorscheme.h>
#include <kstandardaction.h>
#include <qcompleter.h>
#include <qdir.h>
#include <qdom.h>
#include <qfile.h>
#include <qheaderview.h>
#include <qinputdialog.h>
#include <qmap.h>
#include <qscriptengine.h>
#include <qstandardpaths.h>
#include <qstringlistmodel.h>
#include <qtablewidget.h>
#include "skgbankincludes.h"
#include "skgcalculatoredit.h"
#include "skgmainpanel.h"
#include "skgobjectbase.h"
#include "skgobjectmodel.h"
#include "skgoperation_settings.h"
#include "skgpayeeobject.h"
#include "skgservices.h"
#include "skgshow.h"
#include "skgsplittabledelegate.h"
#include "skgtraces.h"
#include "skgtreeview.h"
SKGOperationPluginWidget::SKGOperationPluginWidget(QWidget* iParent, SKGDocumentBank* iDocument)
: SKGTabPage(iParent, iDocument), m_objectModel(nullptr), m_fastEditionAction(nullptr), m_lastFastEditionOperationFound(0), m_showClosedAccounts(false),
m_numberFieldIsNotUptodate(true), m_modeInfoZone(0), m_tableDelegate(nullptr)
{
SKGTRACEINFUNC(1)
if (iDocument == nullptr) {
return;
}
m_timer.setSingleShot(true);
connect(&m_timer, &QTimer::timeout, this, &SKGOperationPluginWidget::onRefreshInformationZone, Qt::QueuedConnection);
ui.setupUi(this);
ui.kAccountLabel2->setText(i18n("%1:", iDocument->getDisplay(QStringLiteral("t_ACCOUNT"))));
ui.kDateLabel->setText(i18n("%1:", iDocument->getDisplay(QStringLiteral("d_date"))));
ui.kAmountLabel->setText(i18n("%1:", iDocument->getDisplay(QStringLiteral("f_CURRENTAMOUNT"))));
ui.kPayeeLabel->setText(i18n("%1:", iDocument->getDisplay(QStringLiteral("t_payee"))));
ui.kTypeLabel->setText(i18n("%1:", iDocument->getDisplay(QStringLiteral("t_mode"))));
ui.kNumberEdit->setPlaceholderText(iDocument->getDisplay(QStringLiteral("t_number")));
ui.kCategoryLabel->setText(i18n("%1:", iDocument->getDisplay(QStringLiteral("t_CATEGORY"))));
ui.kCommentLabel->setText(i18n("%1:", iDocument->getDisplay(QStringLiteral("t_comment"))));
ui.kTrackerLabel->setText(i18n("%1:", iDocument->getDisplay(QStringLiteral("t_REFUND"))));
ui.kUnitEdit->setDocument(iDocument);
ui.kUnitShare->setDocument(iDocument);
ui.kTitle->hide();
ui.kReconciliatorFrame2->hide();
ui.kReconciliateAccount->hide();
m_attributesForSplit << QStringLiteral("d_date") << QStringLiteral("t_category") << QStringLiteral("f_value") << QStringLiteral("t_comment") << QStringLiteral("t_refund");
int nb = m_attributesForSplit.count();
ui.kSubOperationsTable->setColumnCount(nb);
for (int i = 0; i < nb; ++i) {
QString att = m_attributesForSplit.at(i);
auto item = new QTableWidgetItem(iDocument->getIcon(att), iDocument->getDisplay(att));
ui.kSubOperationsTable->setHorizontalHeaderItem(i, item);
}
{
// Bind operation view
m_objectModel = new SKGObjectModel(qobject_cast<SKGDocumentBank*>(getDocument()), QStringLiteral("v_operation_display_all"), QStringLiteral("1=0"), this, QLatin1String(""), false);
ui.kOperationView->setModel(m_objectModel);
// Add registered global action in contextual menu
if (SKGMainPanel::getMainPanel() != nullptr) {
m_fastEditionAction = SKGMainPanel::getMainPanel()->getGlobalAction(QStringLiteral("fast_edition"));
}
connect(ui.kOperationView->getView(), &SKGTreeView::clickEmptyArea, this, &SKGOperationPluginWidget::cleanEditor);
connect(ui.kOperationView->getView(), &SKGTreeView::doubleClicked, this, &SKGOperationPluginWidget::onDoubleClick);
connect(ui.kOperationView->getView(), &SKGTreeView::selectionChangedDelayed, this, [ = ] {this->onSelectionChanged();});
}
// Add Standard KDE Icons to buttons to Operations
ui.kModifyOperationBtn->setIcon(SKGServices::fromTheme(QStringLiteral("dialog-ok")));
ui.kAddOperationBtn->setIcon(SKGServices::fromTheme(QStringLiteral("list-add")));
ui.kCleanBtn->setIcon(SKGServices::fromTheme(QStringLiteral("edit-clear")));
ui.kReconciliatorButton->setIcon(SKGServices::fromTheme(QStringLiteral("view-refresh")));
ui.kValidate->setIcon(SKGServices::fromTheme(QStringLiteral("dialog-ok")));
ui.kValidate->setIconSize(QSize(48, 48));
ui.kAutoPoint->setIcon(SKGServices::fromTheme(QStringLiteral("games-solve")));
ui.kCreateFakeOperation->setIcon(SKGServices::fromTheme(QStringLiteral("list-add")));
ui.kFastEditBtn->setIcon(SKGServices::fromTheme(QStringLiteral("games-solve")));
{
SKGWidgetSelector::SKGListQWidget list;
list.push_back(ui.SKGBasicSection);
list.push_back(ui.SKGPayeeModeSection);
list.push_back(ui.SKGSmallButtons);
list.push_back(ui.SKGEditionButtonsWidget);
list.push_back(ui.SKGSingleOpSection);
ui.kWidgetSelector->addButton(SKGServices::fromTheme(QStringLiteral("dialog-ok")), i18n("Standard"), i18n("Display the edit panel for standard operations"), list);
}
{
SKGWidgetSelector::SKGListQWidget list;
list.push_back(ui.SKGBasicSection);
list.push_back(ui.SKGPayeeModeSection);
list.push_back(ui.SKGSmallButtons);
list.push_back(ui.SKGEditionButtonsWidget);
list.push_back(ui.SKGSplitOpSection);
ui.kWidgetSelector->addButton(SKGServices::fromTheme(QStringLiteral("split")), i18n("Split"), i18n("Display the edit panel for split operations"), list);
}
{
SKGWidgetSelector::SKGListQWidget list;
list.push_back(ui.SKGBasicSection);
list.push_back(ui.SKGPayeeModeSection);
list.push_back(ui.SKGSmallButtons);
list.push_back(ui.SKGEditionButtonsWidget);
list.push_back(ui.SKGSingleOpSection);
list.push_back(ui.kTargetAccountEdit);
list.push_back(ui.kTargetAccountLabel);
ui.kWidgetSelector->addButton(SKGServices::fromTheme(QStringLiteral("exchange-positions")), i18n("Transfer"), i18n("Display the edit panel for transfers between accounts"), list);
}
{
SKGWidgetSelector::SKGListQWidget list;
list.push_back(ui.SKGBasicSection);
list.push_back(ui.SKGPayeeModeSection);
list.push_back(ui.SKGSmallButtons);
list.push_back(ui.SKGEditionButtonsWidget);
list.push_back(ui.SKGSharesSection);
ui.kWidgetSelector->addButton(SKGServices::fromTheme(QStringLiteral("view-bank-account-savings")), i18n("Shares"), i18n("Display the edit panel for purchasing or selling shares"), list);
}
connect(ui.kWidgetSelector, &SKGWidgetSelector::selectedModeChanged, this, &SKGOperationPluginWidget::onBtnModeClicked);
ui.kFreezeBtn->setIcon(SKGServices::fromTheme(QStringLiteral("emblem-locked")));
// Fast edition
connect(qApp, &QApplication::focusChanged, this, &SKGOperationPluginWidget::onFocusChanged);
connect(m_fastEditionAction, &QAction::triggered, this, &SKGOperationPluginWidget::onFastEdition);
// SubOperations
connect(ui.kAmountEdit, &SKGCalculatorEdit::textChanged, this, &SKGOperationPluginWidget::onQuantityChanged);
connect(ui.kDateEdit, &SKGDateEdit::dateChanged, this, &SKGOperationPluginWidget::onDateChanged);
connect(ui.kSubOperationsTable, &SKGTableWidget::cellChanged, this, &SKGOperationPluginWidget::onSubopCellChanged);
connect(ui.kSubOperationsTable->verticalHeader(), &QHeaderView::sectionClicked, this, &SKGOperationPluginWidget::onRemoveSubOperation);
ui.kSubOperationsTable->horizontalHeader()->setSectionResizeMode(QHeaderView::Interactive);
ui.kSubOperationsTable->verticalHeader()->setSectionResizeMode(QHeaderView::Fixed);
ui.kSubOperationsTable->setWordWrap(false);
m_tableDelegate = new SKGSplitTableDelegate(ui.kSubOperationsTable, getDocument(), m_attributesForSplit);
m_tableDelegate->addParameterValue(QStringLiteral("total"), '0');
ui.kSubOperationsTable->setItemDelegate(m_tableDelegate);
ui.kSubOperationsTable->setTextElideMode(Qt::ElideMiddle);
connect(ui.kSubOperationsTable, &SKGTableWidget::removeLine, this, &SKGOperationPluginWidget::onRemoveSubOperation);
ui.kTargetAccountEdit->hide();
ui.kTargetAccountLabel->hide();
ui.SKGSplitOpSection->hide();
ui.SKGSharesSection->hide();
ui.kWidgetSelector->setSelectedMode(0);
// Set Event filters to catch CTRL+ENTER or SHIFT+ENTER
mainWidget()->installEventFilter(this);
this->installEventFilter(this);
// Set Event filters for locking widgets
ui.kTypeEdit->lineEdit()->installEventFilter(this);
ui.kTypeEdit->installEventFilter(this);
ui.kUnitEdit->lineEdit()->installEventFilter(this);
ui.kUnitEdit->installEventFilter(this);
ui.kCategoryEdit->lineEdit()->installEventFilter(this);
ui.kCategoryEdit->installEventFilter(this);
ui.kCommentEdit->lineEdit()->installEventFilter(this);
ui.kCommentEdit->installEventFilter(this);
ui.kPayeeEdit->lineEdit()->installEventFilter(this);
ui.kPayeeEdit->installEventFilter(this);
ui.kTrackerEdit->lineEdit()->installEventFilter(this);
ui.kTrackerEdit->installEventFilter(this);
ui.kAccountEdit->installEventFilter(this);
ui.kTargetAccountLabel->installEventFilter(this);
ui.kAmountEdit->installEventFilter(this);
ui.kNumberEdit->installEventFilter(this);
connect(getDocument(), &SKGDocument::tableModified, this, &SKGOperationPluginWidget::dataModified, Qt::QueuedConnection);
connect(ui.kUnitEdit, &SKGUnitComboBox::editTextChanged, this, &SKGOperationPluginWidget::refreshSubOperationAmount, Qt::QueuedConnection);
connect(ui.kUnitEdit, &SKGUnitComboBox::editTextChanged, this, &SKGOperationPluginWidget::onOperationCreatorModified, Qt::QueuedConnection);
connect(ui.kUnitShare, static_cast<void (SKGUnitComboBox::*)(int)>(&SKGUnitComboBox::currentIndexChanged), this, &SKGOperationPluginWidget::onOperationCreatorModified, Qt::QueuedConnection);
connect(ui.kAmountEdit, &SKGCalculatorEdit::textChanged, this, &SKGOperationPluginWidget::onOperationCreatorModified, Qt::QueuedConnection);
connect(ui.kAmountSharesEdit, &SKGCalculatorEdit::textChanged, this, &SKGOperationPluginWidget::onOperationCreatorModified, Qt::QueuedConnection);
connect(ui.kCommissionEdit, &SKGCalculatorEdit::textChanged, this, &SKGOperationPluginWidget::onOperationCreatorModified, Qt::QueuedConnection);
connect(ui.kTaxEdit, &SKGCalculatorEdit::textChanged, this, &SKGOperationPluginWidget::onOperationCreatorModified, Qt::QueuedConnection);
connect(ui.kAccountEdit, static_cast<void (SKGComboBox::*)(const QString&)>(&SKGComboBox::currentTextChanged), this, &SKGOperationPluginWidget::onOperationCreatorModified, Qt::QueuedConnection);
connect(ui.kOperationView->getShowWidget(), &SKGShow::stateChanged, this, &SKGOperationPluginWidget::onFilterChanged, Qt::QueuedConnection);
connect(ui.kPayeeEdit->lineEdit(), &QLineEdit::returnPressed, this, &SKGOperationPluginWidget::onPayeeChanged, Qt::QueuedConnection);
connect(ui.kReconcilitorAmountEdit, &SKGCalculatorEdit::textChanged, this, &SKGOperationPluginWidget::onRefreshInformationZone);
connect(ui.kAddOperationBtn, &QPushButton::clicked, this, &SKGOperationPluginWidget::onAddOperationClicked);
connect(ui.kModifyOperationBtn, &QPushButton::clicked, this, &SKGOperationPluginWidget::onUpdateOperationClicked);
connect(ui.kReconciliatorButton, &QToolButton::clicked, this, &SKGOperationPluginWidget::onRotateAccountTools);
connect(ui.kValidate, &QToolButton::clicked, this, &SKGOperationPluginWidget::onValidatePointedOperations);
connect(ui.kCleanBtn, &QPushButton::clicked, this, &SKGOperationPluginWidget::cleanEditor);
connect(ui.kSubOperationsTable, &SKGTableWidget::itemSelectionChanged, this, &SKGOperationPluginWidget::onOperationCreatorModified);
connect(ui.kAutoPoint, &QToolButton::clicked, this, &SKGOperationPluginWidget::onAutoPoint);
connect(ui.kFreezeBtn, &QToolButton::clicked, this, &SKGOperationPluginWidget::onFreeze);
connect(ui.kCreateFakeOperation, &QToolButton::clicked, this, &SKGOperationPluginWidget::onAddFakeOperation);
connect(ui.kFastEditBtn, &QPushButton::clicked, this, &SKGOperationPluginWidget::onFastEdition);
dataModified(QLatin1String(""), 0);
onOperationCreatorModified();
setAllWidgetsEnabled();
}
SKGOperationPluginWidget::~SKGOperationPluginWidget()
{
SKGTRACEINFUNC(1)
m_objectModel = nullptr;
m_fastEditionAction = nullptr;
}
QString SKGOperationPluginWidget::currentAccount()
{
QStringList accounts = SKGServices::splitCSVLine(ui.kOperationView->getShowWidget()->getState());
for (const auto& item : qAsConst(accounts)) {
if (item.startsWith(QLatin1String("##_"))) {
return item.right(item.length() - 3);
}
}
return QLatin1String("");
}
bool SKGOperationPluginWidget::isWidgetEditionEnabled(QWidget* iWidget)
{
return ((iWidget != nullptr) && (!iWidget->property("frozen").isValid() || !iWidget->property("frozen").toBool()));
}
void SKGOperationPluginWidget::setWidgetEditionEnabled(QWidget* iWidget, bool iEnabled)
{
if ((iWidget != nullptr) && isWidgetEditionEnabled(iWidget) != iEnabled) {
if (iEnabled) {
iWidget->setStyleSheet(QStringLiteral("background-image:none;"));
iWidget->setProperty("frozen", false);
} else {
auto color = KColorScheme(QPalette::Normal).background(KColorScheme::ActiveBackground).color().name().right(6);
iWidget->setStyleSheet("background-color:#" % color);
iWidget->setProperty("frozen", true);
}
QString addOn = i18nc("A tool tip", "This field is frozen (it will not be affected by Fast Edition). Double click to unfreeze it");
QString t = iWidget->toolTip().remove('\n' % addOn).remove(addOn);
if (!iEnabled) {
t = iWidget->toolTip();
if (!t.isEmpty()) {
t += '\n';
}
t += addOn;
}
iWidget->setToolTip(t);
// 348619: Freeze the unit when amount is frozen
if (iWidget == ui.kAmountEdit) {
setWidgetEditionEnabled(ui.kUnitEdit->lineEdit(), iEnabled);
}
}
}
bool SKGOperationPluginWidget::eventFilter(QObject* iObject, QEvent* iEvent)
{
if ((iEvent != nullptr) && iEvent->type() == QEvent::MouseButtonDblClick) {
auto* line = qobject_cast<QLineEdit*>(iObject);
if (line != nullptr) {
setWidgetEditionEnabled(line, !isWidgetEditionEnabled(line));
}
} else if ((iEvent != nullptr) && iEvent->type() == QEvent::FocusIn) {
auto* line = qobject_cast<QLineEdit*>(iObject);
if (line != nullptr) {
m_previousValue = line->text();
} else {
auto* cmb = qobject_cast<SKGComboBox*>(iObject);
if (cmb != nullptr) {
m_previousValue = cmb->text();
}
}
} else if ((iEvent != nullptr) && iEvent->type() == QEvent::FocusOut) {
auto* line = qobject_cast<QLineEdit*>(iObject);
if (line != nullptr) {
if (m_previousValue != line->text() && !line->text().isEmpty()) {
setWidgetEditionEnabled(line, false);
}
} else {
auto* cmb = qobject_cast<SKGComboBox*>(iObject);
if (cmb != nullptr) {
if (m_previousValue != cmb->text() && !cmb->text().isEmpty()) {
setWidgetEditionEnabled(cmb->lineEdit(), false);
}
}
}
} else if ((iEvent != nullptr) && iEvent->type() == QEvent::KeyPress) {
auto* keyEvent = dynamic_cast<QKeyEvent*>(iEvent);
if (keyEvent && (keyEvent->key() == Qt::Key_Return || keyEvent->key() == Qt::Key_Enter) && iObject == this) {
if ((QApplication::keyboardModifiers() & Qt::ControlModifier) != 0u && ui.kAddOperationBtn->isEnabled()) {
ui.kAddOperationBtn->click();
} else if ((QApplication::keyboardModifiers() &Qt::ShiftModifier) != 0u && ui.kModifyOperationBtn->isEnabled()) {
ui.kModifyOperationBtn->click();
}
} else if (keyEvent && (keyEvent->key() == Qt::Key_Up || keyEvent->key() == Qt::Key_Down) && iObject == ui.kNumberEdit) {
int c = SKGServices::stringToInt(ui.kNumberEdit->text());
if (c != 0) {
ui.kNumberEdit->setText(SKGServices::intToString(keyEvent->key() == Qt::Key_Up ? c + 1 : c - 1));
}
}
}
return SKGTabPage::eventFilter(iObject, iEvent);
}
void SKGOperationPluginWidget::onFreeze()
{
if (!ui.kFreezeBtn->isChecked()) {
ui.kFreezeBtn->setIcon(SKGServices::fromTheme(QStringLiteral("emblem-locked")));
// At least one fiels is already frozen ==> unfreeze
setAllWidgetsEnabled();
} else {
QStringList overlay;
overlay.push_back(QStringLiteral("edit-delete"));
ui.kFreezeBtn->setIcon(SKGServices::fromTheme(QStringLiteral("emblem-locked"), overlay));
// No wildget frozen ==> freeze widget containing test
if (!ui.kTypeEdit->text().isEmpty()) {
setWidgetEditionEnabled(ui.kTypeEdit->lineEdit(), false);
}
if (!ui.kUnitEdit->text().isEmpty()) {
setWidgetEditionEnabled(ui.kUnitEdit->lineEdit(), false);
}
if (!ui.kCategoryEdit->text().isEmpty()) {
setWidgetEditionEnabled(ui.kCategoryEdit->lineEdit(), false);
}
if (!ui.kCommentEdit->text().isEmpty()) {
setWidgetEditionEnabled(ui.kCommentEdit->lineEdit(), false);
}
if (!ui.kPayeeEdit->text().isEmpty()) {
setWidgetEditionEnabled(ui.kPayeeEdit->lineEdit(), false);
}
if (!ui.kTrackerEdit->text().isEmpty()) {
setWidgetEditionEnabled(ui.kTrackerEdit->lineEdit(), false);
}
// if(!ui.kAccountEdit->text().isEmpty()) setWidgetEditionEnabled(ui.kAccountEdit, false);
if (!ui.kAmountEdit->text().isEmpty()) {
setWidgetEditionEnabled(ui.kAmountEdit, false);
}
if (!ui.kNumberEdit->text().isEmpty()) {
setWidgetEditionEnabled(ui.kNumberEdit, false);
}
if (!ui.kTargetAccountEdit->text().isEmpty()) {
setWidgetEditionEnabled(ui.kTargetAccountEdit, false);
}
}
}
void SKGOperationPluginWidget::setAllWidgetsEnabled()
{
SKGTRACEINFUNC(10)
// Enable widgets
setWidgetEditionEnabled(ui.kTypeEdit->lineEdit(), true);
setWidgetEditionEnabled(ui.kUnitEdit->lineEdit(), true);
setWidgetEditionEnabled(ui.kCategoryEdit->lineEdit(), true);
setWidgetEditionEnabled(ui.kCommentEdit->lineEdit(), true);
setWidgetEditionEnabled(ui.kPayeeEdit->lineEdit(), true);
setWidgetEditionEnabled(ui.kTrackerEdit->lineEdit(), true);
setWidgetEditionEnabled(ui.kAccountEdit, true);
setWidgetEditionEnabled(ui.kTargetAccountEdit, true);
setWidgetEditionEnabled(ui.kAmountEdit, true);
setWidgetEditionEnabled(ui.kNumberEdit, true);
}
QString SKGOperationPluginWidget::getAttributeOfSelection(const QString& iAttribute)
{
QString output;
SKGObjectBase::SKGListSKGObjectBase selectedObjects = ui.kOperationView->getView()->getSelectedObjects();
int nb = selectedObjects.count();
for (int i = 0; i < nb ; ++i) {
const SKGObjectBase& obj = selectedObjects.at(i);
QString val = obj.getAttribute(iAttribute);
if (i > 0 && val != output) {
output = NOUPDATE;
break;
}
output = val;
}
return output;
}
void SKGOperationPluginWidget::onSelectionChanged()
{
SKGTRACEINFUNC(10)
int mode = ui.kWidgetSelector->getSelectedMode();
// Enable widgets
setAllWidgetsEnabled();
ui.kFreezeBtn->setChecked(false);
ui.kFreezeBtn->setIcon(SKGServices::fromTheme(QStringLiteral("emblem-locked")));
// Mapping
int nbSelect = ui.kOperationView->getView()->getNbSelectedObjects();
bool onConsolidatedTable = false;
if ((nbSelect != 0) && (m_objectModel != nullptr)) {
SKGObjectBase objbase = ui.kOperationView->getView()->getFirstSelectedObject();
SKGOperationObject obj;
onConsolidatedTable = (objbase.getTable() == QStringLiteral("v_suboperation_consolidated"));
if (onConsolidatedTable) {
obj = SKGOperationObject(obj.getDocument(), SKGServices::stringToInt(obj.getAttribute(QStringLiteral("i_OPID"))));
} else {
obj = objbase;
}
ui.kDateEdit->setDate(SKGServices::stringToTime(objbase.getAttribute(QStringLiteral("d_date"))).date());
m_previousDate = ui.kDateEdit->date();
ui.kCommentEdit->setText(objbase.getAttribute(onConsolidatedTable ? QStringLiteral("t_REALCOMMENT") : QStringLiteral("t_comment")));
QString number = objbase.getAttribute(QStringLiteral("t_number"));
ui.kNumberEdit->setText(number);
QString accountName = objbase.getAttribute(QStringLiteral("t_ACCOUNT"));
if (!m_showClosedAccounts && !accountName.isEmpty() && !ui.kAccountEdit->contains(accountName)) {
// Refresh list of accounts if a closed account is selected
m_showClosedAccounts = true;
dataModified(QLatin1String(""), 0);
}
ui.kAccountEdit->setText(accountName);
ui.kPayeeEdit->setText(objbase.getAttribute(QStringLiteral("t_PAYEE")));
ui.kTypeEdit->setText(objbase.getAttribute(QStringLiteral("t_mode")));
QString unit = objbase.getAttribute(QStringLiteral("t_UNIT"));
ui.kUnitEdit->setText(unit);
QString cat = objbase.getAttribute(QStringLiteral("t_REALCATEGORY"));
if (cat.isEmpty()) {
cat = objbase.getAttribute(QStringLiteral("t_CATEGORY"));
}
ui.kCategoryEdit->setText(cat);
ui.kTrackerEdit->setText(objbase.getAttribute(onConsolidatedTable ? QStringLiteral("t_REALREFUND") : QStringLiteral("t_REFUND")));
QString quantity = objbase.getAttribute(QStringLiteral("f_REALQUANTITY"));
if (quantity.isEmpty()) {
quantity = objbase.getAttribute(QStringLiteral("f_QUANTITY"));
}
double quantityVal = SKGServices::stringToDouble(quantity);
SKGUnitObject unitObject = ui.kUnitEdit->getUnit();
int nbDec = unitObject.getNumberDecimal();
if (nbDec == 0) {
nbDec = 2;
}
quantity = SKGServices::toCurrencyString(qAbs(quantityVal), QLatin1String(""), nbDec);
if (quantity.startsWith(QLocale().positiveSign())) {
quantity = quantity.right(quantity.length() - 1);
}
if (quantityVal > 0) {
quantity = '+' % quantity;
} else {
quantity = '-' % quantity;
}
ui.kAmountEdit->setText(quantity);
if (nbSelect > 1) {
// In case of multi selection
if (mode >= 0) {
ui.kWidgetSelector->setSelectedMode(0);
}
ui.kAccountEdit->setText(getAttributeOfSelection(QStringLiteral("t_ACCOUNT")));
ui.kTypeEdit->setText(getAttributeOfSelection(QStringLiteral("t_mode")));
ui.kUnitEdit->setText(getAttributeOfSelection(QStringLiteral("t_UNIT")));
ui.kCategoryEdit->setText(getAttributeOfSelection(onConsolidatedTable ? QStringLiteral("t_REALCATEGORY") : QStringLiteral("t_CATEGORY")));
ui.kTrackerEdit->setText(getAttributeOfSelection(onConsolidatedTable ? QStringLiteral("t_REALREFUND") : QStringLiteral("t_REFUND")));
ui.kCommentEdit->setText(getAttributeOfSelection(onConsolidatedTable ? QStringLiteral("t_REALCOMMENT") : QStringLiteral("t_comment")));
ui.kPayeeEdit->setText(getAttributeOfSelection(QStringLiteral("t_PAYEE")));
QString d = getAttributeOfSelection(QStringLiteral("d_date"));
if (d == NOUPDATE) {
ui.kDateEdit->setCurrentText(NOUPDATE);
}
QString q = getAttributeOfSelection(onConsolidatedTable ? QStringLiteral("f_REALQUANTITY") : QStringLiteral("f_QUANTITY"));
ui.kAmountEdit->setText(q != NOUPDATE ? quantity : NOUPDATE);
ui.kNumberEdit->setText(QLatin1String(""));
} else {
if (obj.getStatus() == SKGOperationObject::POINTED) {
displayReconciliationInfo();
} else if (m_modeInfoZone != 1) {
displayBalance();
}
// It is a single selection
// Is it a split ?
int nbSubOperations = obj.getNbSubOperations();
if (nbSubOperations > 1 && !onConsolidatedTable) {
// yes, it is a split
if (mode >= 0) {
ui.kWidgetSelector->setSelectedMode(1);
}
displaySubOperations();
} else {
// Is it a transfer ?
SKGOperationObject op2;
if (obj.isTransfer(op2) && op2.exist()) {
// yes it is a transfer
SKGAccountObject account2;
op2.getParentAccount(account2);
QString accountName2 = account2.getName();
if (!m_showClosedAccounts && !ui.kTargetAccountEdit->contains(accountName2)) {
// Refresh list of accounts if a closed account is selected
m_showClosedAccounts = true;
dataModified(QLatin1String(""), 0);
}
ui.kTargetAccountEdit->setText(accountName2);
if (mode >= 0) {
ui.kWidgetSelector->setSelectedMode(2);
}
} else {
if (mode >= 0) {
ui.kWidgetSelector->setSelectedMode(0);
}
}
}
}
}
ui.kNumberEdit->setEnabled(nbSelect <= 1);
bool splitTest = nbSelect <= 1 && !onConsolidatedTable;
ui.kWidgetSelector->setEnabledMode(1, splitTest);
if (!splitTest && mode == 1) {
ui.kWidgetSelector->setSelectedMode(0);
}
onOperationCreatorModified();
Q_EMIT selectionChanged();
}
void SKGOperationPluginWidget::onOperationCreatorModified()
{
SKGTRACEINFUNC(10)
int mode = ui.kWidgetSelector->getSelectedMode();
// Set icons
if (!isTemplateMode()) {
ui.kModifyOperationBtn->setIcon(SKGServices::fromTheme(QStringLiteral("dialog-ok")));
ui.kAddOperationBtn->setIcon(SKGServices::fromTheme(QStringLiteral("list-add")));
} else {
QStringList overlay;
overlay.push_back(QStringLiteral("edit-guides"));
ui.kModifyOperationBtn->setIcon(SKGServices::fromTheme(QStringLiteral("dialog-ok"), overlay));
ui.kAddOperationBtn->setIcon(SKGServices::fromTheme(QStringLiteral("list-add"), overlay));
}
// Is it an existing unit ?
QString unitName = ui.kUnitEdit->currentText();
SKGUnitObject unit(getDocument());
unit.setName(unitName);
unit.setSymbol(unitName);
if (unit.load().isSucceeded()) {
ui.kWidgetSelector->setEnabledMode(3, true);
if (mode == 3 && unit.getType() == SKGUnitObject::SHARE) {
// Update units
auto unit = ui.kUnitShare->getUnit();
ui.kUnitCommission->setText(unit.getSymbol());
ui.kUnitTax->setText(unit.getSymbol());
// Update total in "purchase / sale share" page
double total = ui.kAmountSharesEdit->value() + (ui.kCommissionEdit->value() + ui.kTaxEdit->value()) * (ui.kAmountEdit->value() > 0 ? 1 : -1);
ui.KTotal->setText(SKGServices::toCurrencyString(total, unit.getSymbol(), unit.getNumberDecimal()));
} else {
// BUG 2692665
auto unitShareName = ui.kUnitShare->currentText();
if (unitShareName.isEmpty()) {
ui.kUnitShare->setText(unitName);
ui.kUnitCommission->setText(unitName);
ui.kUnitTax->setText(unitName);
ui.KTotal->setText(unitName);
} else {
ui.kUnitCommission->setText(unitShareName);
ui.kUnitTax->setText(unitShareName);
ui.KTotal->setText(unitShareName);
}
}
} else {
ui.kWidgetSelector->setEnabledMode(3, false);
if (mode == 3) {
ui.kWidgetSelector->setSelectedMode(0);
}
}
bool activated = mode != -1 &&
!ui.kAccountEdit->currentText().isEmpty() &&
((!ui.kAmountEdit->text().isEmpty() && (ui.kAmountEdit->valid() || ui.kAmountEdit->text() == NOUPDATE)) || !ui.kAmountEdit->isEnabled()) &&
!unitName.isEmpty() &&
(mode != 3 || !ui.kAmountSharesEdit->text().isEmpty());
int nbSelect = getNbSelectedObjects();
ui.kAddOperationBtn->setEnabled(activated);
ui.kModifyOperationBtn->setEnabled(activated && nbSelect > 0 && (ui.kWidgetSelector->getSelectedMode() == 0 || ui.kWidgetSelector->getSelectedMode() == 1 || ui.kWidgetSelector->getSelectedMode() == 2));
m_numberFieldIsNotUptodate = true;
if (ui.kNumberEdit->hasFocus()) {
fillNumber();
}
}
void SKGOperationPluginWidget::onPayeeChanged()
{
if (skgoperation_settings::setCategoryForPayee() && ui.kCategoryEdit->text().isEmpty()) {
ui.kCategoryEdit->setText(qobject_cast<SKGDocumentBank*>(getDocument())->getCategoryForPayee(ui.kPayeeEdit->text(), false));
}
}
void SKGOperationPluginWidget::onUpdateOperationClicked()
{
SKGError err;
SKGTRACEINFUNCRC(10, err)
// Get Selection
SKGObjectBase::SKGListSKGObjectBase selection = getSelectedObjects();
int nb = selection.count();
{
SKGBEGINPROGRESSTRANSACTION(*getDocument(), i18nc("Noun, name of the user action", "Operation update"), err, nb)
err = updateSelection(selection);
}
// status bar
IFOKDO(err, SKGError(0, i18nc("Successful message after an user action", "Operation updated")))
else {
err.addError(ERR_FAIL, i18nc("Error message", "Operation update failed"));
}
// Display error
SKGMainPanel::displayErrorMessage(err, true);
// Set focus on table
ui.kOperationView->getView()->setFocus();
}
SKGError SKGOperationPluginWidget::updateSelection(const SKGObjectBase::SKGListSKGObjectBase& iSelection, bool iForceCreation)
{
SKGError err;
SKGTRACEINFUNCRC(10, err)
// Initialisation
double ratio = -1;
bool refreshSubOperation = true;
// Get Selection
int nb = iSelection.count();
double rate = -1;
for (int i = 0; !err && i < nb; ++i) {
const SKGObjectBase& obj = iSelection.at(i);
SKGOperationObject operationObj;
if (obj.getTable() == QStringLiteral("v_suboperation_consolidated")) {
operationObj = SKGOperationObject(obj.getDocument(), SKGServices::stringToInt(obj.getAttribute(QStringLiteral("i_OPID"))));
} else {
operationObj = SKGOperationObject(obj.getDocument(), obj.getID());
}
SKGObjectBase::SKGListSKGObjectBase gops;
IFOKDO(err, operationObj.getGroupedOperations(gops))
if (gops.count() == 2 && ui.kWidgetSelector->getSelectedMode() < 2) {
getDocument()->sendMessage(i18nc("An information message", "You modified one part of a transfer"), SKGDocument::Warning);
}
// Update operation if single selection
if (ui.kWidgetSelector->getSelectedMode() == 0) {
// Get subop
SKGSubOperationObject subOp;
int nbSubop = 0;
if (obj.getTable() == QStringLiteral("v_suboperation_consolidated")) {
// It is a sub operation
subOp = SKGSubOperationObject(obj.getDocument(), SKGServices::stringToInt(obj.getAttribute(QStringLiteral("i_SUBOPID"))));
nbSubop = 1;
} else {
// It is a real operation, we take the first one
SKGObjectBase::SKGListSKGObjectBase subOps;
IFOKDO(err, operationObj.getSubOperations(subOps))
nbSubop = subOps.count();
if (nbSubop != 0) {
subOp = subOps[0];
}
}
QString trackerName = ui.kTrackerEdit->text().trimmed();
if (!err && trackerName != NOUPDATE) {
SKGTrackerObject tracker;
err = SKGTrackerObject::createTracker(qobject_cast<SKGDocumentBank*>(getDocument()), trackerName, tracker, true);
IFOKDO(err, subOp.setTracker(tracker))
}
SKGCategoryObject cat;
QString catName = ui.kCategoryEdit->text().trimmed();
if (!err && catName != NOUPDATE) {
err = SKGCategoryObject::createPathCategory(qobject_cast<SKGDocumentBank*>(getDocument()), catName, cat, true);
IFOKDO(err, subOp.setCategory(cat))
} else {
// Get current category to be able to find the appropriate sign
subOp.getCategory(cat);
}
if (!err && ui.kAmountEdit->text() != NOUPDATE) {
if (nbSubop > 1) {
err = SKGError(25, i18nc("Error message", "Cannot update a split operation"));
} else {
double val = ui.kAmountEdit->value();
// Is the sign forced ?
if (ui.kAmountEdit->sign() == 0) {
// No
SKGObjectBase cat2(cat.getDocument(), QStringLiteral("v_category_display"), cat.getID());
// Are we able to find to sign with the category ?
if (cat2.getAttribute(QStringLiteral("t_TYPEEXPENSE")) == QStringLiteral("-")) {
val = -val;
}
}
err = subOp.setQuantity(val);
}
}
if (!err && ui.kCommentEdit->text() != NOUPDATE) {
err = subOp.setComment(ui.kCommentEdit->text());
}
IFOKDO(err, subOp.save())
} else if (ui.kWidgetSelector->getSelectedMode() == 1) {
// Case split
refreshSubOperation = false;
int nbsubop = ui.kSubOperationsTable->rowCount();
QList<int> listIdSubOp; // clazy:exclude=container-inside-loop
listIdSubOp.reserve(nbsubop);
for (int j = 0; !err && j < nbsubop; ++j) {
// Get values
QTableWidgetItem* item = ui.kSubOperationsTable->item(j, m_attributesForSplit.indexOf(QStringLiteral("t_category")));
int id = (iForceCreation ? 0 : item->data(Qt::UserRole).toInt());
QString catName = item->text();
item = ui.kSubOperationsTable->item(j, m_attributesForSplit.indexOf(QStringLiteral("t_comment")));
QString comment = item->text();
item = ui.kSubOperationsTable->item(j, m_attributesForSplit.indexOf(QStringLiteral("f_value")));
double val = item->data(101).toDouble();
QString formula = item->toolTip();
item = ui.kSubOperationsTable->item(j, m_attributesForSplit.indexOf(QStringLiteral("t_refund")));
QString trackerName = item->text();
item = ui.kSubOperationsTable->item(j, m_attributesForSplit.indexOf(QStringLiteral("d_date")));
QDate date = SKGServices::stringToTime(item->toolTip()).date();
if (!date.isValid()) {
date = ui.kDateEdit->date();
}
SKGSubOperationObject subOperation;
if (id != 0) {
// Update existing sub op
subOperation = SKGSubOperationObject(qobject_cast<SKGDocumentBank*>(getDocument()), id);
} else {
// Create new sub op
err = operationObj.addSubOperation(subOperation);
}
// Create sub operation object
IFOK(err) {
SKGCategoryObject cat;
err = SKGCategoryObject::createPathCategory(qobject_cast<SKGDocumentBank*>(getDocument()), catName, cat, true);
IFOKDO(err, subOperation.setCategory(cat))
}
IFOK(err) {
SKGTrackerObject tracker;
err = SKGTrackerObject::createTracker(qobject_cast<SKGDocumentBank*>(getDocument()), trackerName, tracker, true);
IFOKDO(err, subOperation.setTracker(tracker))
}
IFOKDO(err, subOperation.setOrder(ui.kSubOperationsTable->visualRow(j)))
IFOKDO(err, subOperation.setDate(date))
IFOKDO(err, subOperation.setComment(comment))
IFOKDO(err, subOperation.setQuantity(val))
if (formula.startsWith(QLatin1String("=")) && !err) {
err = subOperation.setFormula(formula);
}
IFOKDO(err, subOperation.save())
// The sub operation created or updated mustn't be removed
listIdSubOp.push_back(subOperation.getID());
}
// Remove useless subop
IFOK(err) {
SKGObjectBase::SKGListSKGObjectBase subOps;
err = operationObj.getSubOperations(subOps);
int nbsubop2 = subOps.count();
for (int j = 0; !err && j < nbsubop2; ++j) {
const SKGObjectBase& sop = subOps.at(j);
if (!listIdSubOp.contains(sop.getID())) {
err = sop.remove(false);
}
}
}
} else if (ui.kWidgetSelector->getSelectedMode() == 2) {
// Case transfer
// Create sub operation object
double operationQuantity = ui.kAmountEdit->value();
SKGSubOperationObject subOperation;
SKGObjectBase::SKGListSKGObjectBase subOps;
IFOKDO(err, operationObj.getSubOperations(subOps))
IFOK(err) {
subOperation = subOps.at(0);
double oldQuantity = subOperation.getQuantity();
if (ui.kAmountEdit->sign() == 0) {
operationQuantity = qAbs(operationQuantity);
} else if (ui.kAmountEdit->sign() > 0) {
operationQuantity = -qAbs(operationQuantity);
} else {
operationQuantity = qAbs(operationQuantity);
if (oldQuantity == 0) {
err = getDocument()->sendMessage(i18nc("An information message", "Absolute value has been used for transfer creation."));
}
}
if (ui.kAmountEdit->text().trimmed() != NOUPDATE) {
err = subOperation.setQuantity(-operationQuantity);
} else {
operationQuantity = -subOperation.getQuantity();
}
}
SKGTrackerObject tracker;
QString trackerName = ui.kTrackerEdit->text().trimmed();
if (!err) {
if (trackerName != NOUPDATE) {
err = SKGTrackerObject::createTracker(qobject_cast<SKGDocumentBank*>(getDocument()), trackerName, tracker, true);
IFOKDO(err, subOperation.setTracker(tracker))
} else {
err = subOperation.getTracker(tracker);
}
}
SKGCategoryObject cat;
QString catName = ui.kCategoryEdit->text().trimmed();
if (!err) {
if (catName != NOUPDATE) {
err = SKGCategoryObject::createPathCategory(qobject_cast<SKGDocumentBank*>(getDocument()), ui.kCategoryEdit->text(), cat, true);
IFOKDO(err, subOperation.setCategory(cat))
} else {
err = subOperation.getCategory(cat);
}
}
IFOKDO(err, subOperation.setComment(operationObj.getComment()))
IFOKDO(err, subOperation.save())
// Get account
SKGAccountObject accountObj2(getDocument());
IFOKDO(err, accountObj2.setName(ui.kTargetAccountEdit->currentText()))
IFOKDO(err, accountObj2.load())
// Check unit of target account
SKGUnitObject unit;
IFOKDO(err, operationObj.getUnit(unit))
// Get date
QDate operationDate;
if (ui.kDateEdit->currentText().trimmed() != NOUPDATE) {
operationDate = ui.kDateEdit->date();
} else {
operationDate = operationObj.getDate();
}
// Correction bug 2299303 vvv
SKGUnitObject unitTargetAccount;
IFOKDO(err, accountObj2.getUnit(unitTargetAccount))
if (!err && unitTargetAccount.exist() && unit != unitTargetAccount) {
// The unit of the operation is not compliant with the unit of the target account
// We ask to the user if he wants to continue or convert into the target account
bool ok = false;
QApplication::setOverrideCursor(QCursor(Qt::ArrowCursor));
int decimal = qMax(unit.getNumberDecimal(), unitTargetAccount.getNumberDecimal());
double newval;
double defaultnewval = SKGUnitObject::convert(operationQuantity, unit, unitTargetAccount, operationDate);
if (nb == 1) {
newval = QInputDialog::getDouble(SKGMainPanel::getMainPanel(),
i18nc("Question", "Confirmation"),
i18nc("Question", "The operation's unit is not compatible with the target account.\n"
"Click Cancel if you want to continue anyway; "
"otherwise, enter the value in the target account's unit (%1):", unitTargetAccount.getSymbol()),
defaultnewval,
-std::numeric_limits<double>::max(), std::numeric_limits<double>::max(), decimal, &ok);
} else {
if (rate == -1) {
newval = QInputDialog::getDouble(SKGMainPanel::getMainPanel(),
i18nc("Question", "Confirmation"),
i18nc("Question", "Some operation's units are not compatible with the target account.\n"
"The first selected operation is:%1\n"
"Click Cancel if you want to continue anyway; "
"otherwise, enter the value in the target account's unit (%2):\nThe same rate will be applied to all operations.", operationObj.getDisplayName(), unitTargetAccount.getSymbol()),
defaultnewval,
-std::numeric_limits<double>::max(), std::numeric_limits<double>::max(), decimal, &ok);
if (ok) {
rate = defaultnewval / newval;
} else {
// Mode cancel for all
rate = -2;
}
} else {
if (rate != -2) {
ok = true;
newval = defaultnewval / rate;
}
}
}
QApplication::restoreOverrideCursor();
if (ok) {
operationQuantity = newval;
unit = unitTargetAccount;
} else {
// Mode cancel for all
rate = -2;
}
}
// Correction bug 2299303 ^^^
// create transferred operation
SKGOperationObject operation2;
IFOK(err) {
if (gops.count() == 2) {
operation2 = (obj == SKGOperationObject(gops.at(0)) ? gops.at(1) : gops.at(0));
if (ui.kTargetAccountEdit->text() != NOUPDATE) {
err = operation2.setParentAccount(accountObj2);
}
} else {
err = accountObj2.addOperation(operation2);
}
}
if (nb == 1) {
IFOKDO(err, operation2.setMode(ui.kTypeEdit->currentText()))
QString payeeName = ui.kPayeeEdit->currentText();
if (!err && payeeName != NOUPDATE) {
SKGPayeeObject payeeObject;
err = SKGPayeeObject::createPayee(qobject_cast<SKGDocumentBank*>(getDocument()), payeeName, payeeObject, true);
IFOKDO(err, operation2.setPayee(payeeObject))
}
IFOKDO(err, operation2.setNumber(ui.kNumberEdit->text()))
IFOKDO(err, operation2.setComment(ui.kCommentEdit->text()))
IFOKDO(err, operation2.setDate(operationDate, refreshSubOperation))
IFOKDO(err, operation2.setUnit(unit))
} else {
IFOKDO(err, operation2.setMode(operationObj.getMode()))
IFOKDO(err, operation2.setAttribute(QStringLiteral("r_payee_id"), operationObj.getAttribute(QStringLiteral("r_payee_id"))))
IFOKDO(err, operation2.setNumber(operationObj.getNumber()))
IFOKDO(err, operation2.setComment(operationObj.getComment()))
IFOKDO(err, operation2.setDate(operationDate, refreshSubOperation))
IFOKDO(err, operation2.setUnit(unit))
}
IFOKDO(err, operation2.setGroupOperation(operationObj))
IFOKDO(err, operationObj.load())
IFOKDO(err, operation2.setTemplate(isTemplateMode()))
IFOKDO(err, operation2.save())
// Create sub operation object
SKGSubOperationObject subOperation2;
SKGObjectBase::SKGListSKGObjectBase subops;
IFOKDO(err, operation2.getSubOperations(subops))
IFOK(err) {
if (!subops.isEmpty()) {
subOperation2 = subops.at(0);
} else {
err = operation2.addSubOperation(subOperation2);
}
}
IFOKDO(err, subOperation2.setQuantity(operationQuantity))
IFOKDO(err, subOperation2.setTracker(tracker))
IFOKDO(err, subOperation2.setCategory(cat))
IFOKDO(err, subOperation2.setComment(operationObj.getComment()))
IFOKDO(err, subOperation2.save())
}
IFOKDO(err, operationObj.setTemplate(isTemplateMode()))
if (ui.kDateEdit->currentText() != NOUPDATE) {
IFOKDO(err, operationObj.setDate(ui.kDateEdit->date(), refreshSubOperation))
}
if (nb == 1) {
IFOKDO(err, operationObj.setNumber(ui.kNumberEdit->text()))
}
if (!err && ui.kCommentEdit->text() != NOUPDATE) {
if (obj.getTable() != QStringLiteral("v_suboperation_consolidated")) {
err = operationObj.setComment(ui.kCommentEdit->text());
}
}
if (!err && ui.kAccountEdit->text() != NOUPDATE) {
SKGAccountObject account(getDocument());
err = account.setName(ui.kAccountEdit->text());
IFOKDO(err, account.load())
IFOKDO(err, operationObj.setParentAccount(account))
}
if (!err && ui.kTypeEdit->text() != NOUPDATE) {
err = operationObj.setMode(ui.kTypeEdit->text());
}
QString payeeName = ui.kPayeeEdit->currentText();
if (!err && payeeName != NOUPDATE) {
SKGPayeeObject payeeObject;
err = SKGPayeeObject::createPayee(qobject_cast<SKGDocumentBank*>(getDocument()), payeeName, payeeObject, true);
IFOKDO(err, operationObj.setPayee(payeeObject))
}
if (!err && ui.kUnitEdit->text() != NOUPDATE) {
// Correction bug 282983 vvv
// Check unit of target account
SKGAccountObject account;
IFOKDO(err, operationObj.getParentAccount(account))
SKGUnitObject unitTargetAccount;
IFOKDO(err, account.getUnit(unitTargetAccount))
SKGUnitObject unit = ui.kUnitEdit->getUnit();
if (!err && unitTargetAccount.exist() && unit != unitTargetAccount) {
// Correction bug 283842 vvvv
bool ok = false;
if (ratio == -1) {
// The unit of the operation is not compliant with the unit of the target account
// We ask to the user if he wants to continue or convert into the target account
QApplication::setOverrideCursor(QCursor(Qt::ArrowCursor));
double currentAmount = ui.kAmountEdit->value();
int decimal = qMax(unit.getNumberDecimal(), unitTargetAccount.getNumberDecimal());
double newval = QInputDialog::getDouble(SKGMainPanel::getMainPanel(),
i18nc("Question", "Confirmation"),
i18nc("Question", "The operation's unit is not compatible with the target account.\n"
"Click Cancel if you want to continue anyway; "
"otherwise, enter the value in the target account's unit (%1):", unitTargetAccount.getSymbol()),
SKGUnitObject::convert(currentAmount, unit, unitTargetAccount, ui.kDateEdit->date()),
-std::numeric_limits<double>::max(), std::numeric_limits<double>::max(), decimal, &ok);
ratio = newval / currentAmount;
QApplication::restoreOverrideCursor();
}
if (ok) {
// Apply ratio to all operation
SKGObjectBase::SKGListSKGObjectBase subops;
err = operationObj.getSubOperations(subops);
int nbsubops = subops.count();
for (int j = 0; !err && j < nbsubops; ++j) {
SKGSubOperationObject subop(subops.at(j));
err = subop.setQuantity(subop.getQuantity() * ratio);
IFOKDO(err, subop.save(true, false))
}
// Change unit
unit = unitTargetAccount;
} else {
err = getDocument()->sendMessage(i18nc("Warning message", "You created an operation in %1 in an account in %2.", unit.getSymbol(), unitTargetAccount.getSymbol()), SKGDocument::Warning);
}
// Correction bug 283842 ^^^^
}
// Correction bug 282983 ^^^
IFOKDO(err, operationObj.setUnit(unit))
}
// Save
IFOKDO(err, operationObj.save())
// Send message
if (!iForceCreation) {
IFOKDO(err, operationObj.getDocument()->sendMessage(i18nc("An information message", "The operation '%1' has been updated", operationObj.getDisplayName()), SKGDocument::Hidden))
}
IFOKDO(err, getDocument()->stepForward(i + 1))
}
return err;
}
void SKGOperationPluginWidget::onAddOperationClicked()
{
SKGError err;
SKGTRACEINFUNC(10)
// Get parameters
QString accountName = ui.kAccountEdit->currentText();
SKGOperationObject operation;
{
SKGBEGINTRANSACTION(*getDocument(), i18nc("Noun, name of the user action", "Operation creation"), err)
// Check entries
if (ui.kAccountEdit->text() == NOUPDATE ||
ui.kTypeEdit->text() == NOUPDATE ||
ui.kUnitEdit->text() == NOUPDATE ||
ui.kCategoryEdit->text() == NOUPDATE ||
ui.kTrackerEdit->text() == NOUPDATE ||
ui.kCommentEdit->text() == NOUPDATE ||
ui.kAmountEdit->text() == NOUPDATE ||
ui.kDateEdit->currentText() == NOUPDATE ||
ui.kPayeeEdit->text() == NOUPDATE) {
err = SKGError(ERR_FAIL, i18nc("Error message", "Impossible to create an operation with one attribute valuated with %1", NOUPDATE));
}
// Get account
SKGAccountObject accountObj(getDocument());
IFOKDO(err, accountObj.setName(accountName))
IFOKDO(err, accountObj.load())
// Create operation object
IFOKDO(err, accountObj.addOperation(operation))
IFOKDO(err, operation.setMode(ui.kTypeEdit->currentText()))
SKGPayeeObject payeeObject;
IFOK(err) {
QString payeeName = ui.kPayeeEdit->currentText();
err = SKGPayeeObject::createPayee(qobject_cast<SKGDocumentBank*>(getDocument()), payeeName, payeeObject, true);
IFOKDO(err, operation.setPayee(payeeObject))
}
IFOKDO(err, operation.setNumber(ui.kNumberEdit->text()))
IFOKDO(err, operation.setComment(ui.kCommentEdit->text()))
IFOKDO(err, operation.setDate(ui.kDateEdit->date()))
IFOKDO(err, operation.setTemplate(isTemplateMode()))
SKGUnitObject unit = ui.kUnitEdit->getUnit();
IFOKDO(err, operation.setUnit(unit))
if (skgoperation_settings::automaticPointInReconciliation() && m_modeInfoZone == 1) {
IFOKDO(err, operation.setStatus(SKGOperationObject::POINTED))
}
IFOKDO(err, operation.save())
if (ui.kWidgetSelector->getSelectedMode() <= 2) {
// STD OPERATION (SPLIT , TRANSFER OR NOT)
// We must create a suboperation, just be sure to be able to update it
SKGSubOperationObject subOperation;
IFOKDO(err, operation.addSubOperation(subOperation))
IFOKDO(err, subOperation.setQuantity(0))
IFOKDO(err, subOperation.save())
SKGObjectBase::SKGListSKGObjectBase list;
list << operation;
IFOKDO(err, updateSelection(list, true))
} else if (ui.kWidgetSelector->getSelectedMode() == 3) {
// PURCHASE OR SALE SHARE
// Create sub operation object
SKGSubOperationObject subOperation;
double val = ui.kAmountEdit->value();
IFOKDO(err, operation.addSubOperation(subOperation))
IFOKDO(err, subOperation.setQuantity(val))
IFOKDO(err, subOperation.save())
if (!err && val > 0) {
err = operation.setProperty(QStringLiteral("SKG_OP_ORIGINAL_AMOUNT"), SKGServices::doubleToString(ui.kAmountSharesEdit->value()));
}
IFOKDO(err, operation.save())
// Get account
SKGAccountObject accountObj2(getDocument());
IFOKDO(err, accountObj2.setName(ui.kPaymentAccountEdit->currentText()))
IFOKDO(err, accountObj2.load())
SKGUnitObject unit = ui.kUnitShare->getUnit();
SKGUnitObject unitTargetAccount;
IFOKDO(err, accountObj2.getUnit(unitTargetAccount))
double ratio = 1.0;
if (!err && unitTargetAccount.exist() && unit != unitTargetAccount) {
// The unit of the operation is not compliant with the unit of the target account
// We ask to the user if he wants to continue or convert into the target account
bool ok = false;
QApplication::setOverrideCursor(QCursor(Qt::ArrowCursor));
int decimal = qMax(unit.getNumberDecimal(), unitTargetAccount.getNumberDecimal());
double defaultnewval = SKGUnitObject::convert(ui.kAmountSharesEdit->value(), unit, unitTargetAccount, ui.kDateEdit->date());
double newval = QInputDialog::getDouble(SKGMainPanel::getMainPanel(),
i18nc("Question", "Confirmation"),
i18nc("Question", "The payment's unit (%1) is not compatible with the target account (%2).\n"
"Click Cancel if you want to continue anyway; "
"otherwise, enter the value in the target account's unit (%3):", unit.getSymbol(), accountObj2.getName(), unitTargetAccount.getSymbol()),
defaultnewval,
-std::numeric_limits<double>::max(), std::numeric_limits<double>::max(), decimal, &ok);
if (ok) {
ratio = newval / ui.kAmountSharesEdit->value();
unit = unitTargetAccount;
}
QApplication::restoreOverrideCursor();
}
// create payment operation for shares
SKGOperationObject operation2;
IFOKDO(err, accountObj2.addOperation(operation2))
IFOKDO(err, operation2.setMode(ui.kTypeEdit->currentText()))
IFOKDO(err, operation2.setPayee(payeeObject))
IFOKDO(err, operation2.setNumber(ui.kNumberEdit->text()))
IFOKDO(err, operation2.setComment(ui.kCommentEdit->text()))
IFOKDO(err, operation2.setDate(ui.kDateEdit->date()))
IFOKDO(err, operation2.setUnit(unit))
IFOKDO(err, operation2.setGroupOperation(operation))
IFOKDO(err, operation2.setTemplate(isTemplateMode()))
IFOKDO(err, operation2.save())
// Create main sub operation
SKGSubOperationObject subOperation2;
IFOKDO(err, operation2.addSubOperation(subOperation2))
IFOKDO(err, subOperation2.setComment(i18nc("Noun", "Shares")))
IFOKDO(err, subOperation2.setQuantity(ui.kAmountSharesEdit->value() * (val > 0 ? -1 : 1) * ratio))
IFOKDO(err, subOperation2.save())
// Create commission sub operation
if (ui.kCommissionEdit->value() != 0.0) {
SKGSubOperationObject subOperation3;
IFOKDO(err, operation2.addSubOperation(subOperation3))
IFOKDO(err, subOperation3.setComment(skgoperation_settings::commentCommissionOperation()))
QString category = skgoperation_settings::categoryCommissionOperation();
if (!category.isEmpty()) {
SKGCategoryObject c;
IFOKDO(err, SKGCategoryObject::createPathCategory(qobject_cast<SKGDocumentBank*>(getDocument()), category, c, true))
IFOKDO(err, subOperation3.setCategory(c))
}
IFOKDO(err, subOperation3.setQuantity(-ui.kCommissionEdit->value() * ratio))
IFOKDO(err, subOperation3.save())
}
// Create tax sub operation
if (ui.kTaxEdit->value() != 0.0) {
SKGSubOperationObject subOperation4;
IFOKDO(err, operation2.addSubOperation(subOperation4))
IFOKDO(err, subOperation4.setComment(skgoperation_settings::commentTaxOperation()))
QString category = skgoperation_settings::categoryTaxOperation();
if (!category.isEmpty()) {
SKGCategoryObject c;
IFOKDO(err, SKGCategoryObject::createPathCategory(qobject_cast<SKGDocumentBank*>(getDocument()), category, c, true))
IFOKDO(err, subOperation4.setCategory(c))
}
IFOKDO(err, subOperation4.setQuantity(-ui.kTaxEdit->value() * ratio))
IFOKDO(err, subOperation4.save())
}
}
// Send message
IFOKDO(err, operation.getDocument()->sendMessage(i18nc("An information to the user that something was added", "The operation '%1' has been added", operation.getDisplayName()), SKGDocument::Hidden))
}
// status bar
IFOK(err) {
err = SKGError(0, i18nc("Successful message after an user action", "Operation created"));
ui.kOperationView->getView()->selectObject(operation.getUniqueID());
} else {
err.addError(ERR_FAIL, i18nc("Error message", "Operation creation failed"));
}
// Display error
SKGMainPanel::displayErrorMessage(err, true);
// Set focus on date
ui.kDateEdit->setFocus();
}
SKGTreeView* SKGOperationPluginWidget::getTableView()
{
return ui.kOperationView->getView();
}
QString SKGOperationPluginWidget::getState()
{
SKGTRACEINFUNC(10)
QDomDocument doc(QStringLiteral("SKGML"));
QDomElement root;
if (m_lastState.hasChildNodes()) {
doc = m_lastState;
root = doc.documentElement();
} else {
root = doc.createElement(QStringLiteral("parameters"));
doc.appendChild(root);
}
root.setAttribute(QStringLiteral("currentPage"), SKGServices::intToString(ui.kWidgetSelector->getSelectedMode()));
root.setAttribute(QStringLiteral("modeInfoZone"), SKGServices::intToString(m_modeInfoZone));
root.setAttribute(QStringLiteral("reconcilitorAmount"), ui.kReconcilitorAmountEdit->text());
root.removeAttribute(QStringLiteral("account"));
// Memorize table settings
root.setAttribute(QStringLiteral("view"), ui.kOperationView->getState());
return doc.toString();
}
void SKGOperationPluginWidget::setState(const QString& iState)
{
SKGTRACEINFUNC(10)
QDomDocument doc(QStringLiteral("SKGML"));
doc.setContent(iState);
QDomElement root = doc.documentElement();
QString account = root.attribute(QStringLiteral("account"));
QString currentPage = root.attribute(QStringLiteral("currentPage"));
QString title = root.attribute(QStringLiteral("title"));
QString title_icon = root.attribute(QStringLiteral("title_icon"));
QString modeInfoZoneS = root.attribute(QStringLiteral("modeInfoZone"));
QString reconcilitorAmountS = root.attribute(QStringLiteral("reconcilitorAmount"));
QString operationTable = root.attribute(QStringLiteral("operationTable"));
QString selection = root.attribute(QStringLiteral("selection"));
QString templates = root.attribute(QStringLiteral("template"));
m_operationWhereClause = root.attribute(QStringLiteral("operationWhereClause"));
// Default values in case of reset
if (currentPage.isEmpty()) {
currentPage = '0';
}
if (operationTable.isEmpty()) {
if (m_operationWhereClause.isEmpty()) {
operationTable = QStringLiteral("v_operation_display_all");
} else {
operationTable = QStringLiteral("v_operation_display");
}
}
// Set
SKGAccountObject acc;
SKGNamedObject::getObjectByName(getDocument(), QStringLiteral("v_account"), account, acc);
if (acc.isClosed() && !m_showClosedAccounts) {
m_showClosedAccounts = true;
dataModified(QLatin1String(""), 0);
}
bool previous = ui.kReconcilitorAmountEdit->blockSignals(true);
ui.kReconcilitorAmountEdit->setText(reconcilitorAmountS);
ui.kReconcilitorAmountEdit->blockSignals(previous);
ui.kWidgetSelector->setSelectedMode(SKGServices::stringToInt(currentPage));
if (!title.isEmpty()) {
QFontMetrics fm(fontMetrics());
ui.kTitle->setComment("<html><body><b>" % SKGServices::stringToHtml(fm.elidedText(title, Qt::ElideMiddle, 2000)) % "</b></body></html>");
ui.kTitle->setToolTip(title);
ui.kTitle->show();
}
if (!title_icon.isEmpty()) {
ui.kTitle->setPixmap(SKGServices::fromTheme(title_icon).pixmap(22, 22), KTitleWidget::ImageLeft);
}
if (m_objectModel != nullptr) {
m_objectModel->setTable(operationTable);
}
if ((m_objectModel != nullptr) && !m_operationWhereClause.isEmpty()) {
ui.kOperationView->getShowWidget()->setEnabled(false);
m_objectModel->setFilter(m_operationWhereClause);
}
if (!operationTable.isEmpty() || !m_operationWhereClause.isEmpty()) {
// We keep a copy of given state in case of bookmark
m_lastState = doc;
} else {
m_lastState = QDomDocument();
}
// Update model
if (m_objectModel != nullptr) {
previous = m_objectModel->blockRefresh(true);
onAccountChanged();
m_objectModel->blockRefresh(previous);
}
// !!! Must be done here after onFilterChanged
QString v = root.attribute(QStringLiteral("view"));
if (!v.isEmpty()) {
ui.kOperationView->setState(v);
}
if (!account.isEmpty()) {
QStringList parameters = SKGServices::splitCSVLine(ui.kOperationView->getShowWidget()->getState());
if (parameters.isEmpty()) {
parameters.push_back(QLatin1String(""));
parameters.push_back(QStringLiteral("operations"));
parameters.push_back(QStringLiteral("hide"));
}
parameters[0] = "##_" % account;
ui.kOperationView->getShowWidget()->setState(SKGServices::stringsToCsv(parameters));
}
if (templates == QStringLiteral("Y")) {
QStringList parameters = SKGServices::splitCSVLine(ui.kOperationView->getShowWidget()->getState());
parameters.removeAll(QStringLiteral("operations"));
parameters.push_back(QStringLiteral("templates"));
ui.kOperationView->getShowWidget()->setState(SKGServices::stringsToCsv(parameters));
}
QStringList parameters = SKGServices::splitCSVLine(ui.kOperationView->getShowWidget()->getState());
if (!parameters.contains(QStringLiteral("operations")) && !parameters.contains(QStringLiteral("templates"))) {
parameters.push_back(QStringLiteral("operations"));
ui.kOperationView->getShowWidget()->setState(SKGServices::stringsToCsv(parameters));
}
if (!selection.isEmpty()) {
QStringList uuids = SKGServices::splitCSVLine(selection);
ui.kOperationView->getView()->selectObjects(uuids, true); // FIXME // TODO(Stephane MANKOWSKI)
onSelectionChanged();
}
// Refresh of the information zone
if (!modeInfoZoneS.isEmpty()) {
m_modeInfoZone = SKGServices::stringToInt(modeInfoZoneS) - 1;
} else {
m_modeInfoZone = -1;
}
onRotateAccountTools();
}
QString SKGOperationPluginWidget::getDefaultStateAttribute()
{
if ((m_objectModel != nullptr) && m_objectModel->getTable() == QStringLiteral("v_suboperation_consolidated")) {
return QStringLiteral("SKGOPERATION_CONSOLIDATED_DEFAULT_PARAMETERS");
}
if (!m_operationWhereClause.isEmpty()) {
return QLatin1String("");
}
return QStringLiteral("SKGOPERATION_DEFAULT_PARAMETERS");
}
void SKGOperationPluginWidget::fillTargetAccount()
{
int nbAccounts = ui.kAccountEdit->count();
QString current = ui.kAccountEdit->text();
QString currentTarget = ui.kTargetAccountEdit->text();
QString currentRecon = ui.kReconciliateAccount->text();
ui.kTargetAccountEdit->clear();
ui.kReconciliateAccount->clear();
ui.kReconciliateAccount->addItem(QLatin1String(""));
for (int i = 0; i < nbAccounts; ++i) {
if (ui.kAccountEdit->itemText(i) != current) {
ui.kTargetAccountEdit->addItem(ui.kAccountEdit->itemIcon(i), ui.kAccountEdit->itemText(i));
ui.kReconciliateAccount->addItem(ui.kAccountEdit->itemIcon(i), ui.kAccountEdit->itemText(i));
}
}
if (ui.kTargetAccountEdit->contains(currentTarget)) {
ui.kTargetAccountEdit->setText(currentTarget);
}
SKGError err;
SKGAccountObject currentActObj(getDocument());
IFOKDO(err, currentActObj.setName(current))
IFOKDO(err, currentActObj.load())
SKGAccountObject linkedActObj;
IFOKDO(err, currentActObj.getLinkedAccount(linkedActObj))
if (linkedActObj.getID() != 0) {
currentRecon = linkedActObj.getName();
}
if (ui.kReconciliateAccount->contains(currentRecon)) {
ui.kReconciliateAccount->setText(currentRecon);
}
}
void SKGOperationPluginWidget::dataModified(const QString& iTableName, int iIdTransaction, bool iLightTransaction)
{
SKGTRACEINFUNC(10)
Q_UNUSED(iIdTransaction)
// Refresh widgets
QSqlDatabase* db = getDocument()->getMainDatabase();
setEnabled(db != nullptr);
if (db != nullptr) {
if (iTableName == QStringLiteral("account") || iTableName.isEmpty()) {
SKGShow* showWidget = ui.kOperationView->getShowWidget();
QString current = currentAccount();
QString currentState = showWidget->getState();
// Disconnect combo filter account
disconnect(showWidget, &SKGShow::stateChanged, this, &SKGOperationPluginWidget::onAccountChanged);
disconnect(showWidget, &SKGShow::stateChanged, this, &SKGOperationPluginWidget::onRefreshInformationZoneDelayed);
disconnect(showWidget, &SKGShow::stateChanged, this, &SKGOperationPluginWidget::onOperationCreatorModified);
disconnect(ui.kAccountEdit, static_cast<void (SKGComboBox::*)(const QString&)>(&SKGComboBox::currentTextChanged), this, &SKGOperationPluginWidget::fillTargetAccount);
// Clear
ui.kAccountEdit->clear();
ui.kPaymentAccountEdit->clear();
SKGStringListList listAccount;
getDocument()->executeSelectSqliteOrder(QStringLiteral("SELECT t_ICON, t_name, t_bookmarked, id from v_account_display ") % (m_showClosedAccounts ? "" : "where t_close='N' ")
% "order by t_bookmarked DESC, t_name ASC", listAccount);
int nbAccounts = listAccount.count() - 1;
if (!m_lastState.hasChildNodes()) {
ui.kTitle->hide();
}
// Set show widget
showWidget->clear();
if (nbAccounts > 1) {
showWidget->addGroupedItem(QStringLiteral("all"), i18nc("Option to for display of operations", "All"), QLatin1String(""), QStringLiteral("1=1"), QStringLiteral("account"), Qt::META + Qt::Key_A);
showWidget->addSeparator();
}
QString uncheck;
bool accountSeparatorAdded = false;
for (int i = 1; i <= nbAccounts; ++i) { // Ignore header
QString iconName = QStandardPaths::locate(QStandardPaths::GenericDataLocation, "skrooge/images/logo/" % listAccount.at(i).at(0));
if (iconName.isEmpty()) {
iconName = listAccount.at(i).at(0);
}
QIcon icon(iconName);
QString text = listAccount.at(i).at(1);
QString id = "##_" % text;
if (nbAccounts == 1) {
QStringList items = SKGServices::splitCSVLine(currentState);
if (items.isEmpty()) {
items.push_back(QStringLiteral("all"));
}
if (items[0] == QStringLiteral("all") || !items[0].startsWith(QLatin1String("##_"))) {
items[0] = id;
}
if (items.count() == 1) {
items.push_back(QStringLiteral("operations"));
items.push_back(QStringLiteral("hide"));
}
currentState = SKGServices::stringsToCsv(items);
}
ui.kAccountEdit->addItem(icon, text);
ui.kPaymentAccountEdit->addItem(icon, text);
if (!accountSeparatorAdded && listAccount.at(i).at(2) == QStringLiteral("N")) {
if (i > 1) {
showWidget->addSeparator();
}
accountSeparatorAdded = true;
}
QString account_id = listAccount.at(i).at(3);
showWidget->addGroupedItem(id, text, iconName, "rd_account_id=" + account_id, QStringLiteral("account"),
(i < 10 ? QKeySequence::fromString("Meta+" % SKGServices::intToString(i)) : QKeySequence()));
SKGStringListList listLinkedAccounts;
getDocument()->executeSelectSqliteOrder(QStringLiteral("SELECT id FROM v_account_display where t_close='N' AND r_account_id=") + account_id, listLinkedAccounts);
int nbLinkedAccount = listLinkedAccounts.count();
if (nbLinkedAccount > 1) {
QString f = account_id;
for (int j = 1; j < nbLinkedAccount; ++j) { // Ignore header
f += ",'" + listLinkedAccounts.at(j).at(0) + '\'';
}
showWidget->addGroupedItem(id + "_cc", i18nc("Information", "%1 + its credit cards", text), iconName, "rd_account_id IN(" + f + ')', QStringLiteral("account"),
QKeySequence());
}
if (!uncheck.isEmpty()) {
uncheck = uncheck % ";";
}
uncheck = uncheck % id;
}
int nb = showWidget->count();
for (int i = 1; i < nb; ++i) {
showWidget->setListIdToUncheckWhenChecked(i, uncheck % ";all");
}
if (nbAccounts > 1) {
showWidget->setListIdToUncheckWhenChecked(0, uncheck);
}
showWidget->addSeparator();
showWidget->addGroupedItem(QStringLiteral("operations"), i18nc("Option to for display of operations", "Operations"), QStringLiteral("view-bank-account"), QStringLiteral("d_date!='0000-00-00' AND t_template='N'"),
QStringLiteral("type"), Qt::META + Qt::Key_O);
showWidget->addGroupedItem(QStringLiteral("templates"), i18nc("Option to for display of operations", "Templates"), QStringLiteral("edit-guides"), QStringLiteral("d_date!='0000-00-00' AND t_template='Y'"),
QStringLiteral("type"), Qt::META + Qt::Key_T);
showWidget->addSeparator();
showWidget->addItem(QStringLiteral("hidepointed"), i18nc("Option to for display of operations", "Hide pointed operations"), QStringLiteral("dialog-ok"), QStringLiteral("t_status<>'P'"), QLatin1String(""), QLatin1String(""), QLatin1String(""), QLatin1String(""), Qt::META + Qt::Key_P);
showWidget->addItem(QStringLiteral("hide"), i18nc("Option to for display of operations", "Hide checked operations"), QStringLiteral("dialog-ok"), QStringLiteral("t_status<>'Y'"), QLatin1String(""), QLatin1String(""), QLatin1String(""), QLatin1String(""), Qt::META + Qt::Key_C);
showWidget->addSeparator();
showWidget->addPeriodItem(QStringLiteral("period"));
showWidget->setMode(SKGShow::AND);
if (currentState.isEmpty()) {
showWidget->setDefaultState(QStringLiteral("all;operations;hide"));
} else {
showWidget->setState(currentState);
}
if (!current.isEmpty()) {
ui.kAccountEdit->setText(current);
}
// Connect combo filter account
connect(ui.kAccountEdit, static_cast<void (SKGComboBox::*)(const QString&)>(&SKGComboBox::currentTextChanged), this, &SKGOperationPluginWidget::fillTargetAccount, Qt::QueuedConnection);
connect(showWidget, &SKGShow::stateChanged, this, &SKGOperationPluginWidget::onAccountChanged, Qt::QueuedConnection);
connect(showWidget, &SKGShow::stateChanged, this, &SKGOperationPluginWidget::onRefreshInformationZoneDelayed, Qt::QueuedConnection);
connect(showWidget, &SKGShow::stateChanged, this, &SKGOperationPluginWidget::onOperationCreatorModified, Qt::QueuedConnection);
fillTargetAccount();
if (nbAccounts == 0) {
ui.kTitle->setText(i18nc("Message", "First you have to create an account."));
ui.kTitle->setPixmap(SKGServices::fromTheme(QStringLiteral("dialog-information")).pixmap(22, 22), KTitleWidget::ImageLeft);
ui.kTitle->show();
showWidget->hide();
} else {
showWidget->show();
}
}
if (iTableName == QStringLiteral("refund") || iTableName.isEmpty()) {
SKGMainPanel::fillWithDistinctValue(QList<QWidget*>() << ui.kTrackerEdit, getDocument(), QStringLiteral("refund"), QStringLiteral("t_name"), QStringLiteral("t_close='N'"));
}
if (!iLightTransaction) {
if (iTableName == QStringLiteral("category") || iTableName.isEmpty()) {
SKGMainPanel::fillWithDistinctValue(QList<QWidget*>() << ui.kCategoryEdit, getDocument(), QStringLiteral("category"), QStringLiteral("t_fullname"), QStringLiteral("t_close='N'"));
}
if (iTableName == QStringLiteral("payee") || iTableName.isEmpty()) {
SKGMainPanel::fillWithDistinctValue(QList<QWidget*>() << ui.kPayeeEdit, getDocument(), QStringLiteral("payee"), QStringLiteral("t_name"), QStringLiteral("t_close='N'"));
}
if (iTableName == QStringLiteral("operation") || iTableName.isEmpty()) {
SKGMainPanel::fillWithDistinctValue(QList<QWidget*>() << ui.kTypeEdit, getDocument(), QStringLiteral("operation"), QStringLiteral("t_mode"), QLatin1String(""), true);
SKGMainPanel::fillWithDistinctValue(QList<QWidget*>() << ui.kCommentEdit, getDocument(), QStringLiteral("v_operation_all_comment"), QStringLiteral("t_comment"), QLatin1String(""), true);
// Set type number
m_numberFieldIsNotUptodate = true;
// Correction 215658: vvv because the table is modified, the selection is modified
onSelectionChanged();
// Correction 215658: ^^^
onRefreshInformationZoneDelayed();
}
} else if (iTableName == QStringLiteral("operation") || iTableName.isEmpty()) {
onRefreshInformationZoneDelayed();
}
}
}
void SKGOperationPluginWidget::onDoubleClick()
{
_SKGTRACEINFUNC(10)
// Get selection
SKGObjectBase::SKGListSKGObjectBase selection = getSelectedObjects();
if (selection.count() == 1) {
SKGOperationObject op(selection.at(0));
if (op.isTemplate() && selection.at(0).getRealTable() == QStringLiteral("operation")) {
// this is a template, we have to create an operation
SKGError err;
SKGBEGINTRANSACTION(*getDocument(), i18nc("Noun, name of the user action", "Operation creation"), err)
SKGOperationObject operation;
err = op.duplicate(operation);
if (skgoperation_settings::automaticPointInReconciliation() && m_modeInfoZone == 1) {
IFOKDO(err, operation.setStatus(SKGOperationObject::POINTED))
IFOKDO(err, operation.save())
}
// Send message
IFOKDO(err, operation.getDocument()->sendMessage(i18nc("An information to the user that something was added", "The operation '%1' has been added", operation.getDisplayName()), SKGDocument::Hidden))
// status bar
IFOK(err) {
setTemplateMode(false);
err = SKGError(0, i18nc("Successful message after an user action", "Operation created"));
ui.kOperationView->getView()->selectObject(operation.getUniqueID());
} else {
err.addError(ERR_FAIL, i18nc("Error message", "Operation creation failed"));
}
// Display error
SKGMainPanel::displayErrorMessage(err);
} else {
// This is not a template, we have to open it
SKGMainPanel::getMainPanel()->getGlobalAction(QStringLiteral("open"))->trigger();
}
}
}
void SKGOperationPluginWidget::onRefreshInformationZoneDelayed()
{
m_timer.start(300);
}
void SKGOperationPluginWidget::onRefreshInformationZone()
{
SKGTRACEINFUNC(1)
ui.kReconciliateAccount->hide();
auto* doc = qobject_cast<SKGDocumentBank*>(getDocument());
QString current = currentAccount();
if (doc != nullptr && SKGMainPanel::getMainPanel()) {
if (m_modeInfoZone == 0) {
// Refresh info area
// Compute where clause
QString filter = QStringLiteral("1=1");
if (!current.isEmpty()) {
filter = "t_name='" % SKGServices::stringToSqlString(current) % '\'';
}
ui.kInfo->setText(i18nc("Message", "Computing..."));
doc->concurrentExecuteSelectSqliteOrder("SELECT TOTAL(f_CURRENTAMOUNT), TOTAL(f_CHECKED), TOTAL(f_COMING_SOON), TOTAL(f_COMING_SOON_FROM_LINKED_ACCOUNT) from v_account_display WHERE " % filter, [ = ](const SKGStringListList & iResult) {
if (iResult.count() == 2 && SKGMainPanel::getMainPanel()->pageIndex(this) != -1) {
SKGServices::SKGUnitInfo unit1 = doc->getPrimaryUnit();
SKGServices::SKGUnitInfo unit2 = doc->getSecondaryUnit();
if (!current.isEmpty()) {
SKGAccountObject account(getDocument());
if (account.setName(current).isSucceeded()) {
if (account.load().isSucceeded()) {
SKGUnitObject unitAccount;
if (account.getUnit(unitAccount).isSucceeded()) {
if (!unitAccount.getSymbol().isEmpty()) {
unit1.Symbol = unitAccount.getSymbol();
unit1.Value = SKGServices::stringToDouble(unitAccount.getAttribute(QStringLiteral("f_CURRENTAMOUNT")));
if (unit1.Symbol != qobject_cast<SKGDocumentBank*>(getDocument())->getPrimaryUnit().Symbol) {
unit2 = qobject_cast<SKGDocumentBank*>(getDocument())->getPrimaryUnit();
}
}
}
}
}
}
double v1 = SKGServices::stringToDouble(iResult.at(1).at(0));
double v2 = SKGServices::stringToDouble(iResult.at(1).at(1));
double v3 = SKGServices::stringToDouble(iResult.at(1).at(2));
double v4 = SKGServices::stringToDouble(iResult.at(1).at(3));
QString s1 = doc->formatMoney(v1, unit1);
QString s2 = doc->formatMoney(v2, unit1);
QString s3 = doc->formatMoney(v3, unit1);
QString s4 = doc->formatMoney(v4, unit1);
QString zero = doc->formatMoney(0, unit1);
ui.kInfo->setText(i18nc("Message", "Balance: %1 Checked: %2 To be Checked: %3", s1, s2, !current.isEmpty() && s4 != zero ? s3 % " + " % s4 : s3));
if (!unit2.Symbol.isEmpty() && (unit2.Value != 0.0)) {
s1 = doc->formatMoney(v1, unit2);
s2 = doc->formatMoney(v2, unit2);
s3 = doc->formatMoney(v3, unit2);
s4 = doc->formatMoney(v4, unit2);
}
ui.kInfo->setToolTip(i18nc("Message", "<p>Balance: %1</p><p>Checked: %2</p><p>To be Checked: %3</p>", s1, s2, !current.isEmpty() && s4 != zero ? s3 % " + " % s4 : s3));
}
});
} else if (m_modeInfoZone == 1) {
// Refresh reconciliation area
SKGServices::SKGUnitInfo unit1 = doc->getPrimaryUnit();
SKGServices::SKGUnitInfo unit2 = doc->getSecondaryUnit();
// Compute where clause
QString filter = '\'' % SKGServices::stringToSqlString(currentAccount()) % '\'';
SKGStringListList listTmp;
getDocument()->executeSelectSqliteOrder(
"SELECT ABS(TOTAL(f_CURRENTAMOUNT_EXPENSE)),TOTAL(f_CURRENTAMOUNT_INCOME) FROM v_operation_display WHERE t_status='P' AND t_ACCOUNT=" % filter,
listTmp);
if (listTmp.count() == 2) {
SKGAccountObject::AccountType accountType = SKGAccountObject::OTHER;
if (!current.isEmpty()) {
SKGAccountObject account(getDocument());
if (account.setName(current).isSucceeded()) {
if (account.load().isSucceeded()) {
accountType = account.getType();
SKGUnitObject unitAccount;
if (account.getUnit(unitAccount).isSucceeded()) {
if (!unitAccount.getSymbol().isEmpty()) {
unit1.Symbol = unitAccount.getSymbol();
unit1.Value = SKGServices::stringToDouble(unitAccount.getAttribute(QStringLiteral("f_CURRENTAMOUNT")));
if (unit1.Symbol != qobject_cast<SKGDocumentBank*>(getDocument())->getPrimaryUnit().Symbol) {
unit2 = qobject_cast<SKGDocumentBank*>(getDocument())->getPrimaryUnit();
}
}
}
}
}
}
if (accountType == SKGAccountObject::SKGAccountObject::CREDITCARD) {
ui.kReconciliationTitle->setText(i18nc("A title", "Total amount:"));
ui.kReconciliateAccount->show();
} else {
ui.kReconciliationTitle->setText(i18nc("A title", "Final balance:"));
}
ui.kAutoPoint->setVisible(accountType != SKGAccountObject::WALLET);
SKGStringListList listTmp2;
double diff = 0;
getDocument()->executeSelectSqliteOrder(
"SELECT TOTAL(f_CHECKEDANDPOINTED) from v_account_display WHERE t_name=" % filter,
listTmp2);
if (listTmp2.count() == 2) {
diff = SKGServices::stringToDouble(listTmp2.at(1).at(0)) - ui.kReconcilitorAmountEdit->value() * unit1.Value;
}
// Set tooltip
if (current.isEmpty()) {
ui.kReconciliatorInfo->setText(i18nc("Description", "You must select only one account to use reconciliation."));
ui.kReconciliatorInfo->setToolTip(ui.kReconciliatorInfo->text());
} else {
double v1 = SKGServices::stringToDouble(listTmp.at(1).at(0));
double v2 = SKGServices::stringToDouble(listTmp.at(1).at(1));
QString sdiff = doc->formatMoney(diff, unit1);
QString s1 = doc->formatMoney(v1, unit1);
QString s2 = doc->formatMoney(v2, unit1);
ui.kReconciliatorInfo->setText(i18nc("Message", "%1 - Delta: %2 Expenditure: %3 Income: %4", unit1.Symbol, sdiff, s1, s2));
// Comparison
QString zero = doc->formatMoney(0, unit1);
QString negativezero = doc->formatMoney(-EPSILON, unit1);
ui.kValidate->setVisible(sdiff == zero || sdiff == negativezero);
ui.kCreateFakeOperation->setVisible(!ui.kValidate->isVisible());
ui.kAutoPoint->setVisible(!ui.kValidate->isVisible());
if (!unit2.Symbol.isEmpty() && (unit2.Value != 0.0)) {
sdiff = doc->formatMoney(diff, unit2);
s1 = doc->formatMoney(v1, unit2);
s2 = doc->formatMoney(v2, unit2);
}
ui.kReconciliatorInfo->setToolTip(i18nc("Message", "<p>Delta: %1</p><p>Expenditure: %2</p><p>Income: %3</p>", sdiff, s1, s2));
}
}
}
}
}
void SKGOperationPluginWidget::onAccountChanged()
{
SKGTRACEINFUNC(1)
if (!currentAccount().isEmpty() && ui.kOperationView->getView()->getNbSelectedObjects() == 0) {
// Get account object
SKGAccountObject act(getDocument());
SKGError err = act.setName(currentAccount());
IFOKDO(err, act.load())
// Get unit
SKGUnitObject unit;
IFOKDO(err, act.getUnit(unit))
if (!err && !unit.getSymbol().isEmpty()) {
ui.kUnitEdit->setText(unit.getSymbol());
}
}
onFilterChanged();
}
void SKGOperationPluginWidget::onFilterChanged()
{
SKGTRACEINFUNC(1)
if (!isEnabled()) {
return;
}
QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
// Enable/ disable widgets
bool onOneAccount = (!currentAccount().isEmpty());
ui.kReconciliatorFrame2->setEnabled(onOneAccount);
if (!onOneAccount && m_modeInfoZone == 1) {
ui.kReconciliatorFrame2->hide();
ui.kInfo->show();
m_modeInfoZone = 0;
}
QString current = currentAccount();
if (!current.isEmpty() && ui.kOperationView->getView()->getNbSelectedObjects() == 0) {
ui.kAccountEdit->setText(current);
}
QApplication::restoreOverrideCursor();
}
void SKGOperationPluginWidget::fillNumber()
{
SKGTRACEINFUNC(10)
QStringList list;
QString account = ui.kAccountEdit->text();
QString wc;
if (!account.isEmpty()) {
wc = "rd_account_id IN (SELECT id FROM account WHERE t_name='" + SKGServices::stringToSqlString(account) + "')";
}
getDocument()->getDistinctValues(QStringLiteral("v_operation_next_numbers"), QStringLiteral("t_number"), wc, list);
// Fill completion
auto comp = new QCompleter(list);
comp->setFilterMode(Qt::MatchContains);
ui.kNumberEdit->setCompleter(comp);
m_numberFieldIsNotUptodate = false;
}
void SKGOperationPluginWidget::onFocusChanged()
{
_SKGTRACEINFUNC(10)
if (!qApp->closingDown()) {
if ((SKGMainPanel::getMainPanel() != nullptr) && SKGMainPanel::getMainPanel()->currentPage() == this) {
if (m_numberFieldIsNotUptodate && ui.kNumberEdit->hasFocus()) {
fillNumber();
}
bool test = ui.kTypeEdit->hasFocus() ||
// ui.kAmountEdit->hasFocus() ||
// ui.kNumberEdit->hasFocus() ||
ui.kUnitEdit->hasFocus() ||
ui.kCategoryEdit->hasFocus() ||
ui.kTrackerEdit->hasFocus() ||
ui.kCommentEdit->hasFocus() ||
ui.kPayeeEdit->hasFocus();
if (m_fastEditionAction != nullptr) {
m_fastEditionAction->setEnabled(test);
}
}
}
}
void SKGOperationPluginWidget::onFastEdition()
{
if (SKGMainPanel::getMainPanel()->currentPage() != this) {
return;
}
SKGTRACEINFUNC(10)
QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
SKGError err;
// Get widget item
QWidget* w = QApplication::focusWidget();
auto* cmb = qobject_cast<SKGComboBox*>(w);
if (cmb != nullptr) {
setWidgetEditionEnabled(cmb->lineEdit(), false);
} else {
setWidgetEditionEnabled(w, false);
}
// Build the where clause
QString wc;
if (ui.kTypeEdit->hasFocus()) {
wc = "t_mode LIKE '" % SKGServices::stringToSqlString(ui.kTypeEdit->text()) % "%'";
} else if (ui.kUnitEdit->hasFocus()) {
wc = "t_UNIT LIKE '" % SKGServices::stringToSqlString(ui.kUnitEdit->text()) % "%'";
} else if (ui.kCategoryEdit->hasFocus()) {
wc = "t_CATEGORY LIKE '" % SKGServices::stringToSqlString(ui.kCategoryEdit->text()) % "%'";
} else if (ui.kTrackerEdit->hasFocus()) {
wc = "t_REFUND LIKE '" % SKGServices::stringToSqlString(ui.kTrackerEdit->text()) % "%'";
} else if (ui.kCommentEdit->hasFocus()) {
wc = "t_comment LIKE '" % SKGServices::stringToSqlString(ui.kCommentEdit->text()) % "%'";
} else if (ui.kPayeeEdit->hasFocus()) {
wc = "t_PAYEE LIKE '" % SKGServices::stringToSqlString(ui.kPayeeEdit->text()) % "%'";
}
if (!wc.isEmpty()) {
QString accountName = ui.kAccountEdit->currentText();
if (!accountName.isEmpty() && skgoperation_settings::oncurrentaccountonly()) {
wc += " AND t_ACCOUNT LIKE '" % SKGServices::stringToSqlString(accountName) % "%'";
}
// Read Setting
QString fasteditmode = skgoperation_settings::fasteditmode();
/*
0-Search in templates only
1-Search first in templates and after in operations
2-Search in operations only
3-Search first in operations and after in templates
*/
if (fasteditmode == QStringLiteral("0")) {
wc += QStringLiteral(" AND t_template='Y'");
} else if (fasteditmode == QStringLiteral("2")) {
wc += QStringLiteral(" AND t_template='N'");
}
if (wc != m_lastFastEditionWhereClause) {
m_lastFastEditionWhereClause = wc;
m_lastFastEditionOperationFound = 0;
}
// Look for last operation
if (m_lastFastEditionOperationFound != 0) {
wc += " AND id<" % SKGServices::intToString(m_lastFastEditionOperationFound);
}
// Add order by
wc += QStringLiteral(" ORDER BY ");
if (fasteditmode == QStringLiteral("1")) {
wc += QStringLiteral(" t_template DESC, ");
} else if (fasteditmode == QStringLiteral("3")) {
wc += QStringLiteral(" t_template ASC, ");
}
wc += QStringLiteral("d_date DESC, id DESC LIMIT 1");
SKGObjectBase::SKGListSKGObjectBase operations;
err = getDocument()->getObjects(QStringLiteral("v_operation_display_all"), wc, operations);
if (!err && !operations.isEmpty()) {
SKGOperationObject op(operations.at(0));
m_lastFastEditionOperationFound = op.getID();
if (isWidgetEditionEnabled(ui.kTypeEdit->lineEdit())) {
ui.kTypeEdit->setText(op.getMode());
}
if (isWidgetEditionEnabled(ui.kUnitEdit->lineEdit())) {
ui.kUnitEdit->setText(op.getAttribute(QStringLiteral("t_UNIT")));
}
if (isWidgetEditionEnabled(ui.kCategoryEdit->lineEdit())) {
ui.kCategoryEdit->setText(op.getAttribute(QStringLiteral("t_CATEGORY")));
}
if (isWidgetEditionEnabled(ui.kCommentEdit->lineEdit())) {
ui.kCommentEdit->setText(op.getComment());
}
if (isWidgetEditionEnabled(ui.kPayeeEdit->lineEdit())) {
ui.kPayeeEdit->setText(op.getAttribute(QStringLiteral("t_PAYEE")));
}
if (isWidgetEditionEnabled(ui.kTrackerEdit->lineEdit())) {
ui.kTrackerEdit->setText(op.getAttribute(QStringLiteral("t_REFUND")));
}
if (currentAccount().isEmpty()) {
ui.kAccountEdit->setText(op.getAttribute(QStringLiteral("t_ACCOUNT")));
}
if (isWidgetEditionEnabled(ui.kAmountEdit)) {
QString quantity = op.getAttribute(QStringLiteral("f_QUANTITY"));
double quantityVal = SKGServices::stringToDouble(quantity);
SKGUnitObject unitObject = ui.kUnitEdit->getUnit();
int nbDec = unitObject.getNumberDecimal();
if (nbDec == 0) {
nbDec = 2;
}
quantity = SKGServices::toCurrencyString(qAbs(quantityVal), QLatin1String(""), nbDec);
if (quantity.startsWith(QLocale().positiveSign())) {
quantity = quantity.right(quantity.length() - 1);
}
if (quantityVal > 0) {
quantity = '+' % quantity;
} else {
quantity = '-' % quantity;
}
ui.kAmountEdit->setText(quantity);
}
// set next number
if (isWidgetEditionEnabled(ui.kNumberEdit)) {
int number = SKGServices::stringToInt(op.getNumber());
if (number == 0) {
ui.kNumberEdit->setText(QLatin1String(""));
} else {
if (m_numberFieldIsNotUptodate) {
fillNumber();
}
QCompleter* comp = ui.kNumberEdit->completer();
if (comp != nullptr) {
QStringList list = qobject_cast<QStringListModel*>(comp->model())->stringList();
int nb = list.count();
int cpt = 0;
while (nb >= 0 && cpt >= 0 && cpt < 1000) {
++number;
if (list.contains(SKGServices::intToString(number))) {
cpt = -2;
}
++cpt;
}
if (cpt < 0) {
ui.kNumberEdit->setText(SKGServices::intToString(number));
}
}
}
}
// Get nb operation linked
SKGObjectBase::SKGListSKGObjectBase groupedOperations;
op.getGroupedOperations(groupedOperations);
int nbGroupedOp = groupedOperations.count();
// Get nb sub op
SKGObjectBase::SKGListSKGObjectBase subOperations;
op.getSubOperations(subOperations);
int nbSupOp = subOperations.count();
if (nbSupOp > 1) {
// It is a SPLIT operation
ui.kWidgetSelector->setSelectedMode(1);
QDate d = ui.kDateEdit->date();
if (!d.isValid()) {
d = QDate::currentDate();
}
displaySubOperations(op, false, d);
} else {
if (nbGroupedOp > 1) {
// It is a TRANSFER
SKGOperationObject op2(groupedOperations.at(0));
if (op2 == op) {
op2 = groupedOperations.at(1);
}
SKGAccountObject targetAccount;
op2.getParentAccount(targetAccount);
if (isWidgetEditionEnabled(ui.kTargetAccountEdit)) {
ui.kTargetAccountEdit->setText(targetAccount.getName());
}
} else {
ui.kWidgetSelector->setSelectedMode(0);
}
}
} else {
m_lastFastEditionWhereClause = QLatin1String("");
m_lastFastEditionOperationFound = 0;
}
}
if (w != nullptr) {
w->setFocus(Qt::OtherFocusReason);
}
QApplication::restoreOverrideCursor();
// Display error
SKGMainPanel::displayErrorMessage(err);
}
bool SKGOperationPluginWidget::isTemplateMode()
{
QAction* act = ui.kOperationView->getShowWidget()->getAction(QStringLiteral("templates"));
return ((act != nullptr) && act->isChecked());
}
void SKGOperationPluginWidget::setTemplateMode(bool iTemplate)
{
SKGTRACEINFUNC(10)
if (iTemplate != isTemplateMode()) {
QAction* act = ui.kOperationView->getShowWidget()->getAction(QStringLiteral("templates"));
if (act != nullptr) {
act->setChecked(iTemplate);
}
act = ui.kOperationView->getShowWidget()->getAction(QStringLiteral("operations"));
if (act != nullptr) {
act->setChecked(!iTemplate);
}
}
}
void SKGOperationPluginWidget::onBtnModeClicked(int mode)
{
SKGTRACEINFUNC(10)
if (mode != 1 && mode != -1) {
ui.kSubOperationsTable->setRowCount(0);
ui.kSubOperationsTable->clearContents();
}
if (mode == 1) {
if (ui.kSubOperationsTable->rowCount() == 0) {
addSubOperationLine(0, ui.kDateEdit->date(), ui.kCategoryEdit->text(), ui.kTrackerEdit->text(), ui.kCommentEdit->text(), ui.kAmountEdit->value(), nullptr);
}
}
onOperationCreatorModified();
}
void SKGOperationPluginWidget::displaySubOperations(const SKGOperationObject& iOperation, bool iKeepId, QDate iSubOperationsDate)
{
SKGTRACEINFUNC(10)
ui.kSubOperationsTable->setRowCount(0);
ui.kSubOperationsTable->clearContents();
int nbSubOperations = 0;
SKGObjectBase::SKGListSKGObjectBase subOperations;
SKGError err = iOperation.getSubOperations(subOperations);
nbSubOperations = subOperations.count();
for (int i = 0; i < nbSubOperations; ++i) {
SKGSubOperationObject subOperation(subOperations.at(i));
SKGCategoryObject category;
subOperation.getCategory(category);
SKGTrackerObject tracker;
subOperation.getTracker(tracker);
addSubOperationLine(i, iSubOperationsDate.isValid() ? iSubOperationsDate : subOperation.getDate(), category.getFullName(), tracker.getName(),
subOperation.getComment(), subOperation.getQuantity(), subOperation.getFormula(),
(iKeepId ? subOperation.getID() : 0));
}
onQuantityChanged();
}
void SKGOperationPluginWidget::displaySubOperations()
{
SKGTRACEINFUNC(10)
SKGOperationObject operation;
if (getSelectedOperation(operation).isSucceeded()) {
displaySubOperations(operation);
}
}
double SKGOperationPluginWidget::getRemainingQuantity()
{
SKGTRACEINFUNC(10)
double sumQuantities = 0;
int nbSubOperations = ui.kSubOperationsTable->rowCount();
for (int i = 0; i < nbSubOperations ; ++i) {
QTableWidgetItem* quantityItem = ui.kSubOperationsTable->item(i, m_attributesForSplit.indexOf(QStringLiteral("f_value")));
if (quantityItem != nullptr) {
sumQuantities = sumQuantities + quantityItem->data(101).toDouble();
}
}
return ui.kAmountEdit->value() - sumQuantities;
}
void SKGOperationPluginWidget::onDateChanged(QDate iDate)
{
SKGTRACEINFUNC(10)
bool previous = ui.kSubOperationsTable->blockSignals(true); // Disable signals so that filling cell doesn't create new lines
if (sender() == ui.kDateEdit && iDate.isValid() && m_previousDate.isValid()) {
// Refresh dates
int nbSubOperations = ui.kSubOperationsTable->rowCount();
for (int i = 0; i < nbSubOperations ; ++i) {
QTableWidgetItem* dateItem = ui.kSubOperationsTable->item(i, m_attributesForSplit.indexOf(QStringLiteral("d_date")));
if (dateItem != nullptr) {
auto datestring = dateItem->toolTip();
QDate previousSubDate = SKGServices::stringToTime(datestring).date();
if (previousSubDate.isValid()) {
int delta = m_previousDate.daysTo(iDate);
auto newDate = previousSubDate.addDays(delta);
dateItem->setText(SKGMainPanel::dateToString(newDate));
dateItem->setToolTip(SKGServices::dateToSqlString(newDate));
}
}
}
}
m_previousDate = iDate;
ui.kSubOperationsTable->blockSignals(previous); // Reenable signals
}
void SKGOperationPluginWidget::refreshSubOperationAmount()
{
SKGTRACEINFUNC(10)
bool previous = ui.kSubOperationsTable->blockSignals(true); // Disable signals so that filling cell doesn't create new lines
int nbSubOperations = ui.kSubOperationsTable->rowCount();
// Refresh computed amounts
auto unit = ui.kUnitEdit->getUnit().getUnitInfo();
unit.Value = 1.0;
for (int i = 0; i < nbSubOperations ; ++i) {
QTableWidgetItem* quantityItem = ui.kSubOperationsTable->item(i, m_attributesForSplit.indexOf(QStringLiteral("f_value")));
if (quantityItem != nullptr) {
QString formula = quantityItem->toolTip();
if (formula.startsWith(QLatin1String("="))) {
formula = formula.right(formula.length() - 1);
formula.replace(',', '.'); // Replace comma by a point in case of typo
formula.remove(' ');
formula.replace(QStringLiteral("total"), SKGServices::doubleToString(ui.kAmountEdit->value()));
QScriptEngine myEngine;
QScriptValue result = myEngine.evaluate(formula);
if (result.isNumber()) {
auto value = result.toNumber();
quantityItem->setText(getDocument()->formatMoney(value, unit, false));
quantityItem->setData(101, value);
}
} else {
auto value = quantityItem->data(101).toDouble();
quantityItem->setText(getDocument()->formatMoney(value, unit, false));
}
}
}
ui.kSubOperationsTable->blockSignals(previous); // Reenable signals
}
void SKGOperationPluginWidget::onQuantityChanged()
{
SKGTRACEINFUNC(10)
int nbSubOperations = ui.kSubOperationsTable->rowCount();
bool previous = ui.kSubOperationsTable->blockSignals(true); // Disable signals so that filling cell doesn't create new lines
if (sender() == ui.kAmountEdit) {
// Update the total amount
m_tableDelegate->addParameterValue(QStringLiteral("total"), ui.kAmountEdit->value());
// Refresh computed amounts
refreshSubOperationAmount();
}
// This code put the remaining quantity on the all sub operations with the same ratios ^^^
// Specific code for the last one to avoid "round" error
QTableWidgetItem* remainingQuantityItem = ui.kSubOperationsTable->item(nbSubOperations - 1, m_attributesForSplit.indexOf(QStringLiteral("f_value")));
if (remainingQuantityItem != nullptr) {
// 348490 vvv
double remain = remainingQuantityItem->data(101).toDouble() + getRemainingQuantity();
if (qAbs(remain) < 1e-10) {
onRemoveSubOperation(nbSubOperations - 1);
} else {
auto unit = ui.kUnitEdit->getUnit().getUnitInfo();
unit.Value = 1.0;
remainingQuantityItem->setText(getDocument()->formatMoney(remain, unit, false));
remainingQuantityItem->setData(101, remain);
remainingQuantityItem->setToolTip(SKGServices::doubleToString(remain));
}
// 348490 ^^^
}
ui.kSubOperationsTable->blockSignals(previous); // Reenable signals
}
void SKGOperationPluginWidget::onSubopCellChanged(int row, int column)
{
SKGTRACEINFUNC(10)
QTableWidgetItem* subop_cell = ui.kSubOperationsTable->item(row, column);
QBrush base_brush = ui.kSubOperationsTable->item(row, 0)->foreground();
if (column == m_attributesForSplit.indexOf(QStringLiteral("f_value"))) {
// If the quantity in the last line is edited, we add a new
// line with the new remaining quantity
addSubOperationLine(ui.kSubOperationsTable->rowCount(), ui.kDateEdit->date(), QLatin1String(""),
QLatin1String(""), QLatin1String(""), 0, QLatin1String(""));
if (subop_cell->data(101).toDouble() != 0) {
onQuantityChanged();
} else {
base_brush = KColorScheme(QPalette::Normal).foreground(KColorScheme::NegativeText);
}
subop_cell->setForeground(base_brush);
refreshSubOperationAmount();
}
}
void SKGOperationPluginWidget::onRemoveSubOperation(int iRow)
{
SKGTRACEINFUNC(10)
bool previous = ui.kSubOperationsTable->blockSignals(true);
ui.kSubOperationsTable->removeRow(iRow);
// If all rows removed, add an empty line
if (ui.kSubOperationsTable->rowCount() == 0) {
addSubOperationLine(0, ui.kDateEdit->date(), QLatin1String(""), QLatin1String(""), QLatin1String(""), 0, QLatin1String(""));
}
if (!previous) {
onQuantityChanged();
}
ui.kSubOperationsTable->blockSignals(previous);
}
void SKGOperationPluginWidget::onRotateAccountTools()
{
SKGTRACEINFUNC(10)
if (m_modeInfoZone == 0) {
displayReconciliationInfo();
} else {
displayBalance();
}
}
void SKGOperationPluginWidget::displayBalance()
{
if (m_modeInfoZone != 0) {
ui.kReconciliatorFrame2->hide();
ui.kInfo->show();
m_modeInfoZone = 0;
onRefreshInformationZoneDelayed();
}
}
void SKGOperationPluginWidget::displayReconciliationInfo()
{
if (!currentAccount().isEmpty()) {
// Only show reconciliation info if only one account is displayed
ui.kReconciliatorFrame2->show();
ui.kInfo->hide();
m_modeInfoZone = 1;
onRefreshInformationZoneDelayed();
} else {
// If more than one account is displayed, skip reconciliation mode
// (it doesn't make sense to reconciliate several accounts at once)
// and move to the next modeInfoZone
m_modeInfoZone = 1;
onRotateAccountTools();
}
}
void SKGOperationPluginWidget::onAutoPoint()
{
SKGError err;
SKGTRACEINFUNCRC(10, err)
{
SKGBEGINTRANSACTION(*getDocument(), i18nc("Noun, name of the user action", "Auto point account"), err)
SKGAccountObject act(getDocument());
err = act.setName(currentAccount());
IFOKDO(err, act.load())
IFOKDO(err, act.autoReconcile(ui.kReconcilitorAmountEdit->value()))
// Send message
IFOKDO(err, act.getDocument()->sendMessage(i18nc("An information message", "The account '%1' has been auto pointed", act.getDisplayName()), SKGDocument::Hidden))
}
// status bar
IFOKDO(err, SKGError(0, i18nc("Successful message after an user action", "Account auto pointed.")))
// Display error
SKGMainPanel::displayErrorMessage(err);
}
void SKGOperationPluginWidget::onAddFakeOperation()
{
SKGError err;
SKGTRACEINFUNCRC(10, err) {
SKGBEGINTRANSACTION(*getDocument(), i18nc("Noun, name of the user action", "Create fake operation"), err)
SKGAccountObject accountObj(getDocument());
IFOKDO(err, accountObj.setName(currentAccount()))
IFOKDO(err, accountObj.load())
SKGOperationObject op;
IFOKDO(err, accountObj.addOperation(op))
IFOKDO(err, op.setDate(QDate::currentDate()))
IFOKDO(err, op.setComment(skgoperation_settings::commentFakeOperation()))
QString payee = skgoperation_settings::payeeFakeOperation();
if (!payee.isEmpty()) {
SKGPayeeObject p;
IFOKDO(err, SKGPayeeObject::createPayee(qobject_cast<SKGDocumentBank*>(getDocument()), payee, p, true))
IFOKDO(err, op.setPayee(p))
}
SKGUnitObject unit;
IFOKDO(err, accountObj.getUnit(unit))
IFOKDO(err, op.setUnit(unit))
if (skgoperation_settings::automaticPointInReconciliation() && m_modeInfoZone == 1) {
IFOKDO(err, op.setStatus(SKGOperationObject::POINTED))
}
IFOKDO(err, op.save())
SKGSubOperationObject sop;
IFOKDO(err, op.addSubOperation(sop))
SKGStringListList listTmp2;
double diff = 0;
getDocument()->executeSelectSqliteOrder(
"SELECT f_CHECKEDANDPOINTED from v_account_display WHERE t_name='" % SKGServices::stringToSqlString(currentAccount()) % '\'',
listTmp2);
if (listTmp2.count() == 2) {
diff = SKGServices::stringToDouble(listTmp2.at(1).at(0)) / unit.getAmount() - ui.kReconcilitorAmountEdit->value();
}
IFOKDO(err, sop.setQuantity(-diff))
IFOKDO(err, sop.setComment(skgoperation_settings::commentFakeOperation()))
QString category = skgoperation_settings::categoryFakeOperation();
if (!category.isEmpty()) {
SKGCategoryObject c;
IFOKDO(err, SKGCategoryObject::createPathCategory(qobject_cast<SKGDocumentBank*>(getDocument()), category, c, true))
IFOKDO(err, sop.setCategory(c))
}
IFOKDO(err, sop.save())
// Send message
IFOKDO(err, op.getDocument()->sendMessage(i18nc("An information to the user that something was added", "The operation '%1' has been added", op.getDisplayName()), SKGDocument::Hidden))
}
// status bar
IFOKDO(err, SKGError(0, i18nc("Successful message after an user action", "Fake operation created.")))
else {
err.addError(ERR_FAIL, i18nc("Error message", "Creation failed"));
}
// Display error
SKGMainPanel::displayErrorMessage(err);
}
void SKGOperationPluginWidget::onValidatePointedOperations()
{
SKGError err;
SKGTRACEINFUNCRC(10, err)
QString account = currentAccount();
if (!account.isEmpty()) {
// Get reconciliated account
SKGAccountObject act(getDocument());
IFOKDO(err, act.setName(account))
IFOKDO(err, act.load())
QString bindAccount = ui.kReconciliateAccount->currentText();
if (act.getType() == SKGAccountObject::CREDITCARD && !bindAccount.isEmpty()) {
//
IFOK(err) {
SKGBEGINPROGRESSTRANSACTION(*getDocument(), i18nc("Noun, name of the user action", "Switch to checked"), err, 3)
SKGAccountObject accountObj2(getDocument());
IFOKDO(err, accountObj2.setName(bindAccount))
IFOKDO(err, accountObj2.load())
IFOKDO(err, getDocument()->stepForward(1))
IFOKDO(err, act.transferDeferredOperations(accountObj2))
IFOKDO(err, getDocument()->stepForward(2))
// Change reconciliation date of the account
IFOKDO(err, act.setReconciliationDate(QDate::currentDate()))
IFOKDO(err, act.setReconciliationBalance(ui.kReconcilitorAmountEdit->value()))
IFOKDO(err, act.setLinkedAccount(accountObj2))
IFOKDO(err, act.save())
// Send message
IFOKDO(err, act.getDocument()->sendMessage(i18nc("An information message", "The account '%1' has been reconciliated", act.getDisplayName()), SKGDocument::Hidden))
IFOKDO(err, getDocument()->stepForward(3))
}
} else {
// Change state of all operations
SKGObjectBase::SKGListSKGObjectBase list;
IFOKDO(err, getDocument()->getObjects(QStringLiteral("v_operation_display"), "t_status='P' AND t_ACCOUNT='" % SKGServices::stringToSqlString(account) % '\'', list))
int nb = list.count();
IFOK(err) {
SKGBEGINPROGRESSTRANSACTION(*getDocument(), i18nc("Noun, name of the user action", "Switch to checked"), err, nb + 1)
for (int i = 0; !err && i < nb; ++i) {
// Set operation checked
SKGOperationObject op(list.at(i));
err = op.setStatus(SKGOperationObject::CHECKED);
IFOKDO(err, op.save())
// Send message
IFOKDO(err, op.getDocument()->sendMessage(i18nc("An information message", "The operation '%1' has been checked", op.getDisplayName()), SKGDocument::Hidden))
IFOKDO(err, getDocument()->stepForward(i + 1))
}
// Change reconciliation date of the account
IFOKDO(err, act.setReconciliationDate(QDate::currentDate()))
IFOKDO(err, act.setReconciliationBalance(ui.kReconcilitorAmountEdit->value()))
IFOKDO(err, act.save())
// Send message
IFOKDO(err, act.getDocument()->sendMessage(i18nc("An information message", "The account '%1' has been reconciliated", act.getDisplayName()), SKGDocument::Hidden))
IFOKDO(err, getDocument()->stepForward(nb + 1))
}
}
}
// status bar
IFOKDO(err, SKGError(0, i18nc("Successful message after an user action", "Operation checked.")))
else {
err.addError(ERR_FAIL, i18nc("Error message", "Switch failed"));
}
// Display error
SKGMainPanel::displayErrorMessage(err);
}
void SKGOperationPluginWidget::addSubOperationLine(int row, QDate date, const QString& category, const QString& tracker, const QString& comment, double quantity, const QString& formula, int id)
{
SKGTRACEINFUNC(10)
bool previous = ui.kSubOperationsTable->blockSignals(true);
ui.kSubOperationsTable->insertRow(row);
// Add a delete icon on the line:
auto hitem = new QTableWidgetItem(SKGServices::fromTheme(QStringLiteral("edit-delete")), QLatin1String(""));
ui.kSubOperationsTable->setVerticalHeaderItem(row, hitem);
QHeaderView* headerView = ui.kSubOperationsTable->verticalHeader();
headerView->setSectionsMovable(true);
// Category
auto categoryItem = new QTableWidgetItem(category);
categoryItem->setToolTip(category);
categoryItem->setData(Qt::UserRole, id);
ui.kSubOperationsTable->setItem(row, m_attributesForSplit.indexOf(QStringLiteral("t_category")), categoryItem);
// Comment
auto commentItem = new QTableWidgetItem(comment);
commentItem->setToolTip(comment);
ui.kSubOperationsTable->setItem(row, m_attributesForSplit.indexOf(QStringLiteral("t_comment")), commentItem);
// Quantity
auto unit = ui.kUnitEdit->getUnit().getUnitInfo();
unit.Value = 1.0;
auto quantityItem = new QTableWidgetItem(getDocument()->formatMoney(quantity, unit, false));
quantityItem->setTextAlignment(Qt::AlignVCenter | Qt::AlignRight);
quantityItem->setData(101, quantity);
quantityItem->setToolTip(formula.isEmpty() ? SKGServices::doubleToString(quantity) : formula);
ui.kSubOperationsTable->setItem(row, m_attributesForSplit.indexOf(QStringLiteral("f_value")), quantityItem);
// Refund
auto trackerItem = new QTableWidgetItem(tracker);
trackerItem->setToolTip(tracker);
categoryItem->setData(Qt::UserRole, id);
ui.kSubOperationsTable->setItem(row, m_attributesForSplit.indexOf(QStringLiteral("t_refund")), trackerItem);
// Date
auto dateItem = new QTableWidgetItem(SKGMainPanel::dateToString(date));
dateItem->setToolTip(SKGServices::dateToSqlString(date));
ui.kSubOperationsTable->setItem(row, m_attributesForSplit.indexOf(QStringLiteral("d_date")), dateItem);
ui.kSubOperationsTable->blockSignals(previous);
ui.kSubOperationsTable->resizeColumnsToContents();
ui.kSubOperationsTable->horizontalHeader()->setStretchLastSection(true);
if (row == 0 && category.isEmpty()) {
ui.kSubOperationsTable->horizontalHeader()->resizeSection(0, 300);
}
}
QWidget* SKGOperationPluginWidget::mainWidget()
{
return ui.kOperationView->getView();
}
SKGError SKGOperationPluginWidget::getSelectedOperation(SKGOperationObject& operation)
{
SKGError err;
SKGObjectBase::SKGListSKGObjectBase selectedOperations = getSelectedObjects();
if (!selectedOperations.isEmpty()) {
operation = selectedOperations.at(0);
err.setReturnCode(0);
} else {
err.setReturnCode(1).setMessage(i18nc("Error message", "No Operation Selected"));
}
return err;
}
void SKGOperationPluginWidget::cleanEditor()
{
if (getNbSelectedObjects() == 0 || sender() == ui.kCleanBtn) {
ui.kOperationView->getView()->clearSelection();
ui.kDateEdit->setDate(QDate::currentDate());
ui.kPayeeEdit->setText(QLatin1String(""));
ui.kCategoryEdit->setText(QLatin1String(""));
ui.kTrackerEdit->setText(QLatin1String(""));
ui.kAmountEdit->setText(QLatin1String(""));
ui.kTypeEdit->setText(QLatin1String(""));
ui.kCommentEdit->setText(QLatin1String(""));
ui.kNumberEdit->setText(QLatin1String(""));
if (!currentAccount().isEmpty()) {
ui.kAccountEdit->setText(currentAccount());
}
// BUG 376025 vvvv
ui.kUnitEdit->setDocument(qobject_cast<SKGDocumentBank*>(getDocument()));
// BUG 376025 ^^^^
ui.kUnitShare->setDocument(qobject_cast<SKGDocumentBank*>(getDocument()));
setAllWidgetsEnabled();
m_previousDate = QDate::currentDate();
}
if (sender() == ui.kCleanBtn) {
ui.kWidgetSelector->setSelectedMode(0);
}
}
bool SKGOperationPluginWidget::isEditor()
{
return true;
}
void SKGOperationPluginWidget::activateEditor()
{
if (ui.kWidgetSelector->getSelectedMode() == -1) {
ui.kWidgetSelector->setSelectedMode(0);
}
ui.kPayeeEdit->setFocus();
}
diff --git a/plugins/skrooge/skrooge_operation/skgoperationpluginwidget.h b/plugins/skrooge/skrooge_operation/skgoperationpluginwidget.h
index 5914d539a..16e5a75a6 100644
--- a/plugins/skrooge/skrooge_operation/skgoperationpluginwidget.h
+++ b/plugins/skrooge/skrooge_operation/skgoperationpluginwidget.h
@@ -1,192 +1,192 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGOPERATIONPLUGINWIDGET_H
#define SKGOPERATIONPLUGINWIDGET_H
/** @file
* This file is Skrooge plugin for bank management.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgoperationobject.h"
#include "skgsuboperationobject.h"
#include "skgtabpage.h"
#include "ui_skgoperationpluginwidget_base.h"
#include <qdom.h>
class SKGDocumentBank;
class SKGObjectModel;
class SKGSplitTableDelegate;
class SKGTreeView;
class QAction;
/**
* This file is Skrooge plugin for operation management
*/
class SKGOperationPluginWidget : public SKGTabPage
{
Q_OBJECT
public:
/**
* Default Constructor
* @param iParent the parent widget
* @param iDocument the document
*/
explicit SKGOperationPluginWidget(QWidget* iParent, SKGDocumentBank* iDocument);
/**
* Default Destructor
*/
~SKGOperationPluginWidget() override;
/**
* Get the table view
* @return the table view
*/
virtual SKGTreeView* getTableView();
/**
* Get the current state
* MUST BE OVERWRITTEN
* @return a string containing all information needed to set the same state.
* Could be an XML stream
*/
QString getState() override;
/**
* Set the current state
* MUST BE OVERWRITTEN
* @param iState must be interpreted to set the state of the widget
*/
void setState(const QString& iState) override;
/**
* Get attribute name to save the default state
* MUST BE OVERWRITTEN
* @return attribute name to save the default state.
*/
QString getDefaultStateAttribute() override;
/**
* Get the main widget
* @return a widget
*/
QWidget* mainWidget() override;
/**
* Set or not the template mode
* @param iTemplate the template mode
*/
virtual void setTemplateMode(bool iTemplate);
/**
* To know if this page contains an editor. MUST BE OVERWRITTEN
* @return the editor state
*/
bool isEditor() override;
/**
* To activate the editor by setting focus on right widget. MUST BE OVERWRITTEN
*/
void activateEditor() override;
protected:
/**
* Event filtering
* @param iObject object
* @param iEvent event
* @return In your reimplementation of this function, if you want to filter the event out, i.e. stop it being handled further, return true; otherwise return false.
*/
bool eventFilter(QObject* iObject, QEvent* iEvent) override;
private Q_SLOTS:
void dataModified(const QString& iTableName, int iIdTransaction, bool iLightTransaction = false);
void onOperationCreatorModified();
void onPayeeChanged();
void onAddOperationClicked();
void onUpdateOperationClicked();
void onFilterChanged();
void onAccountChanged();
void onSelectionChanged();
void onFocusChanged();
void onFastEdition();
void onDoubleClick();
void onQuantityChanged();
// cppcheck-suppress passedByValue
void onDateChanged(QDate iDate);
void onSubopCellChanged(int row, int column);
void onRemoveSubOperation(int iRow);
void onRefreshInformationZone();
void onRefreshInformationZoneDelayed();
void onRotateAccountTools();
void onValidatePointedOperations();
void onBtnModeClicked(int mode);
void onAutoPoint();
void onAddFakeOperation();
void onFreeze();
void refreshSubOperationAmount();
void cleanEditor();
void displayReconciliationInfo();
void displayBalance();
void fillTargetAccount();
private:
Q_DISABLE_COPY(SKGOperationPluginWidget)
SKGError getSelectedOperation(SKGOperationObject& operation);
bool isWidgetEditionEnabled(QWidget* iWidget);
void setWidgetEditionEnabled(QWidget* iWidget, bool iEnabled);
void setAllWidgetsEnabled();
bool isTemplateMode();
void displaySubOperations();
// cppcheck-suppress passedByValue
void displaySubOperations(const SKGOperationObject& iOperation, bool iKeepId = true, QDate iSubOperationsDate = QDate());
double getRemainingQuantity();
// cppcheck-suppress passedByValue
void addSubOperationLine(int row, QDate date, const QString& category, const QString& tracker, const QString& comment, double quantity, const QString& formula, int id = 0);
SKGError updateSelection(const SKGObjectBase::SKGListSKGObjectBase& iSelection, bool iForceCreation = false);
void fillNumber();
QString getAttributeOfSelection(const QString& iAttribute);
QString currentAccount();
Ui::skgoperationplugin_base ui{};
SKGObjectModel* m_objectModel;
QString m_operationWhereClause;
QString m_previousValue;
QDomDocument m_lastState;
QAction* m_fastEditionAction;
QString m_lastFastEditionWhereClause;
int m_lastFastEditionOperationFound;
bool m_showClosedAccounts;
bool m_numberFieldIsNotUptodate;
int m_modeInfoZone;
QKeySequence m_deleteShortcut;
SKGSplitTableDelegate* m_tableDelegate;
QTimer m_timer;
QStringList m_attributesForSplit;
QDate m_previousDate;
};
#endif // SKGOPERATIONPLUGINWIDGET_H
diff --git a/plugins/skrooge/skrooge_operation/skgoperationpluginwidget_base.ui b/plugins/skrooge/skrooge_operation/skgoperationpluginwidget_base.ui
index bb80e2352..088c1a7b7 100644
--- a/plugins/skrooge/skrooge_operation/skgoperationpluginwidget_base.ui
+++ b/plugins/skrooge/skrooge_operation/skgoperationpluginwidget_base.ui
@@ -1,1464 +1,1464 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>skgoperationplugin_base</class>
<widget class="QWidget" name="skgoperationplugin_base">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>1369</width>
<height>660</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="spacing">
<number>2</number>
</property>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_5">
<property name="spacing">
<number>2</number>
</property>
<item>
<widget class="KTitleWidget" name="kTitle" native="true">
<property name="maximumSize">
<size>
<width>16777215</width>
<height>80</height>
</size>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="SKGFilteredTableView" name="kOperationView">
<property name="focusPolicy">
<enum>Qt::StrongFocus</enum>
</property>
<property name="acceptDrops">
<bool>true</bool>
</property>
<property name="toolTip">
<string>list of operations</string>
</property>
<property name="statusTip">
<string>list of operations</string>
</property>
<property name="dragEnabled" stdset="0">
<bool>true</bool>
</property>
<property name="alternatingRowColors" stdset="0">
<bool>true</bool>
</property>
<property name="sortingEnabled" stdset="0">
<bool>true</bool>
</property>
<property name="wordWrap" stdset="0">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QFrame" name="kReconciliatorFrame">
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_6">
<property name="spacing">
<number>2</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<layout class="QVBoxLayout" name="verticalLayout_4">
<property name="spacing">
<number>2</number>
</property>
<item>
<widget class="QFrame" name="kReconciliatorFrame2">
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_9">
<property name="spacing">
<number>2</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>0</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="kReconciliationTitle">
<property name="text">
<string notr="true">Final &amp;balance:</string>
</property>
<property name="buddy">
<cstring>kReconcilitorAmountEdit</cstring>
</property>
</widget>
</item>
<item>
<widget class="SKGCalculatorEdit" name="kReconcilitorAmountEdit">
<property name="enabled">
<bool>true</bool>
</property>
<property name="maximumSize">
<size>
<width>100</width>
<height>16777215</height>
</size>
</property>
<property name="focusPolicy">
<enum>Qt::ClickFocus</enum>
</property>
<property name="toolTip">
<string>Last balance on your account record</string>
</property>
<property name="statusTip">
<string>Last balance on your account record</string>
</property>
<property name="mode">
<enum>SKGCalculatorEdit::EXPRESSION</enum>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="kReconciliatorInfo">
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="kCreateFakeOperation">
<property name="maximumSize">
<size>
<width>22</width>
<height>22</height>
</size>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="toolTip">
<string>Create fake operation</string>
</property>
<property name="statusTip">
<string>Create fake operation</string>
</property>
<property name="text">
<string/>
</property>
<property name="autoRaise">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="SKGComboBox" name="kReconciliateAccount">
<property name="focusPolicy">
<enum>Qt::ClickFocus</enum>
</property>
<property name="toolTip">
<string>Account linked to the card, where to transfer the pointed operations</string>
</property>
<property name="statusTip">
<string>Account linked to the card, where to transfer the pointed operations</string>
</property>
<property name="sizeAdjustPolicy">
<enum>QComboBox::AdjustToContents</enum>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="kValidate">
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="toolTip">
<string>Validate pointed operations</string>
</property>
<property name="statusTip">
<string>Validate pointed operations</string>
</property>
<property name="text">
<string/>
</property>
<property name="autoRaise">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="kAutoPoint">
<property name="maximumSize">
<size>
<width>22</width>
<height>22</height>
</size>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="toolTip">
<string>Auto point all imported operations</string>
</property>
<property name="statusTip">
<string>Auto point all imported operations</string>
</property>
<property name="text">
<string/>
</property>
<property name="autoRaise">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QLabel" name="kInfo">
<property name="text">
<string comment="KDE::DoNotExtract">Computing...</string>
</property>
<property name="scaledContents">
<bool>true</bool>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QToolButton" name="kReconciliatorButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>22</width>
<height>22</height>
</size>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="toolTip">
<string>Switch information</string>
</property>
<property name="statusTip">
<string>Switch information</string>
</property>
<property name="autoRaise">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="Line" name="line">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<widget class="QWidget" name="horizontalWidget_3" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<layout class="QGridLayout" name="gridLayout_6">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item row="0" column="0">
<widget class="QWidget" name="SKGBasicSection" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<layout class="QGridLayout" name="gridLayout_5">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<property name="spacing">
<number>2</number>
</property>
<item row="0" column="0">
<widget class="QLabel" name="kAccountLabel2">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string notr="true">&amp;Title:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>kAccountEdit</cstring>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="SKGComboBox" name="kAccountEdit">
<property name="toolTip">
<string>Account of the operation</string>
</property>
<property name="statusTip">
<string>Account of the operation</string>
</property>
<property name="sizeAdjustPolicy">
<enum>QComboBox::AdjustToContents</enum>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="kDateLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string notr="true">Title:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>kDateEdit</cstring>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="SKGDateEdit" name="kDateEdit">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>120</width>
<height>0</height>
</size>
</property>
<property name="statusTip">
<string>Date of the operation</string>
</property>
<property name="mode">
<enum>SKGDateEdit::PREVIOUS</enum>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="kAmountLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string notr="true">Title:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>kAmountEdit</cstring>
</property>
</widget>
</item>
<item row="3" column="0">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
<item row="2" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_11">
<property name="spacing">
<number>2</number>
</property>
<item>
<widget class="SKGCalculatorEdit" name="kAmountEdit">
<property name="toolTip">
- <string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
+ <string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;https://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Bitstream Vera Sans'; font-size:9pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Amount of the operation.&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;You can enter expressions here, such as &lt;span style=&quot; font-style:italic;&quot;&gt;3+4*2&lt;/span&gt;, skrooge will compute the result (&lt;span style=&quot; font-style:italic;&quot;&gt;11&lt;/span&gt;)&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="statusTip">
<string>Amount of the operation</string>
</property>
<property name="mode">
<enum>SKGCalculatorEdit::EXPRESSION</enum>
</property>
</widget>
</item>
<item>
<widget class="SKGUnitComboBox" name="kUnitEdit">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>60</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>80</width>
<height>16777215</height>
</size>
</property>
<property name="toolTip">
<string>Unit of the operation</string>
</property>
<property name="statusTip">
<string>Unit of the operation</string>
</property>
<property name="editable">
<bool>true</bool>
</property>
<property name="sizeAdjustPolicy">
<enum>QComboBox::AdjustToContents</enum>
</property>
<property name="autoCompletion">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item row="0" column="1">
<widget class="QWidget" name="SKGPayeeModeSection" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<property name="spacing">
<number>2</number>
</property>
<item row="2" column="0">
<widget class="QLabel" name="kPayeeLabel">
<property name="text">
<string notr="true">Title:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>kPayeeEdit</cstring>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="SKGComboBox" name="kPayeeEdit">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>Payee of the operation</string>
</property>
<property name="statusTip">
<string>Payee of the operation</string>
</property>
<property name="editable">
<bool>true</bool>
</property>
<property name="sizeAdjustPolicy">
<enum>QComboBox::AdjustToMinimumContentsLength</enum>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="kTypeLabel">
<property name="text">
<string notr="true">Title:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>kTypeEdit</cstring>
</property>
</widget>
</item>
<item row="4" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_13">
<property name="spacing">
<number>2</number>
</property>
<item>
<widget class="SKGComboBox" name="kTypeEdit">
<property name="minimumSize">
<size>
<width>100</width>
<height>0</height>
</size>
</property>
<property name="toolTip">
<string>Operation mode (how you made the operation).
Examples: Credit Card, Check, Transfer...
</string>
</property>
<property name="statusTip">
<string>Operation mode</string>
</property>
<property name="editable">
<bool>true</bool>
</property>
<property name="sizeAdjustPolicy">
<enum>QComboBox::AdjustToMinimumContentsLength</enum>
</property>
<property name="autoCompletion">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="kNumberEdit">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="acceptDrops">
<bool>false</bool>
</property>
<property name="toolTip">
<string>Number of the operation, for example the Check number, or a Transfer reference.</string>
</property>
<property name="statusTip">
<string>Number of the operation</string>
</property>
<property name="showClearButton" stdset="0">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item row="7" column="0">
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="1">
<widget class="SKGComboBox" name="kTargetAccountEdit">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>Target account for this transfer</string>
</property>
<property name="statusTip">
<string>Target account for this transfer</string>
</property>
<property name="sizeAdjustPolicy">
<enum>QComboBox::AdjustToContents</enum>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="kTargetAccountLabel">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string comment="as in &quot;make a money transfer from account A *to account* B&quot;">To Account:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>kTargetAccountEdit</cstring>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="kCommentLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string notr="true">Title:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>kCommentEdit</cstring>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="SKGComboBox" name="kCommentEdit">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>Comment of the operation</string>
</property>
<property name="statusTip">
<string>Comment of the operation</string>
</property>
<property name="editable">
<bool>true</bool>
</property>
<property name="sizeAdjustPolicy">
<enum>QComboBox::AdjustToMinimumContentsLength</enum>
</property>
<property name="showClearButton" stdset="0">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="0" column="2">
<widget class="QWidget" name="SKGSingleOpSection" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<layout class="QGridLayout" name="gridLayout_3">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<property name="spacing">
<number>2</number>
</property>
<item row="0" column="0">
<widget class="QLabel" name="kCategoryLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string notr="true">Title:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>kCategoryEdit</cstring>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="SKGComboBox" name="kCategoryEdit">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>200</width>
<height>0</height>
</size>
</property>
<property name="toolTip">
<string>Category of the operation.
Use &quot; &gt; &quot; as a separator between a category and a subcategory.</string>
</property>
<property name="statusTip">
<string>Category of the operation</string>
</property>
<property name="editable">
<bool>true</bool>
</property>
<property name="sizeAdjustPolicy">
<enum>QComboBox::AdjustToMinimumContentsLength</enum>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="kTrackerLabel">
<property name="text">
<string notr="true">Title:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>kTrackerEdit</cstring>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="SKGComboBox" name="kTrackerEdit">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>Tracker associated to this operation</string>
</property>
<property name="statusTip">
<string>Tracker associated to this operation</string>
</property>
<property name="whatsThis">
- <string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
+ <string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;https://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Bitstream Vera Sans'; font-size:9pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;A &lt;span style=&quot; font-style:italic;&quot;&gt;Tracker&lt;/span&gt; is a way to group some operations together. For example, you may use it to follow refunds.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;You will find more information on this in the documentation in the chapter &quot;Trackers&quot;.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="editable">
<bool>true</bool>
</property>
<property name="sizeAdjustPolicy">
<enum>QComboBox::AdjustToMinimumContentsLength</enum>
</property>
</widget>
</item>
<item row="5" column="0">
<spacer name="verticalSpacer_3">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
<item row="0" column="3">
<widget class="QWidget" name="SKGSharesSection" native="true">
<layout class="QGridLayout" name="gridLayout_4">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<property name="spacing">
<number>2</number>
</property>
<item row="0" column="0">
<widget class="QLabel" name="kAccountLabel3_2">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Account for pa&amp;yment:</string>
</property>
<property name="buddy">
<cstring>kPaymentAccountEdit</cstring>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="kAmountSharesLabel">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>A&amp;mount of shares:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>kAmountSharesEdit</cstring>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="SKGCalculatorEdit" name="kAmountSharesEdit">
<property name="toolTip">
<string>Amount of shares</string>
</property>
<property name="statusTip">
<string>Amount of shares</string>
</property>
<property name="mode">
<enum>SKGCalculatorEdit::EXPRESSION</enum>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="kCommissionLabel">
<property name="text">
<string comment="Noun, a quantity of money taken by a financial institution to perform an operation">+ Commission:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>kCommissionEdit</cstring>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="SKGCalculatorEdit" name="kCommissionEdit">
<property name="toolTip">
<string>Amount of the commission</string>
</property>
<property name="statusTip">
<string>Amount of the commission</string>
</property>
<property name="mode">
<enum>SKGCalculatorEdit::EXPRESSION</enum>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="kTaxLabel">
<property name="text">
<string comment="Noun, Taxes applied on a financial operation">+ Tax:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>kTaxEdit</cstring>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="SKGCalculatorEdit" name="kTaxEdit">
<property name="toolTip">
<string>Amount of the Tax</string>
</property>
<property name="statusTip">
<string>Amount of the Tax</string>
</property>
<property name="mode">
<enum>SKGCalculatorEdit::EXPRESSION</enum>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="kTotalLabel">
<property name="text">
<string comment="Noun, the numerical total of a sum of values"> = Total:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="5" column="0">
<spacer name="verticalSpacer_4">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
<item row="2" column="2" colspan="2">
<widget class="QLabel" name="kUnitCommission">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>$</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="3" column="2" colspan="2">
<widget class="QLabel" name="kUnitTax">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>$</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="SKGUnitComboBox" name="kUnitShare"/>
</item>
<item row="0" column="1" colspan="2">
<widget class="SKGComboBox" name="kPaymentAccountEdit">
<property name="toolTip">
<string>Payment account for bought share</string>
</property>
<property name="statusTip">
<string>Payment account for bought share</string>
</property>
<property name="sizeAdjustPolicy">
<enum>QComboBox::AdjustToContents</enum>
</property>
<property name="frame">
<bool>true</bool>
</property>
<property name="autoCompletion">
<bool>false</bool>
</property>
</widget>
</item>
<item row="4" column="1" colspan="2">
<widget class="QLabel" name="KTotal">
<property name="text">
<string>$</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="0" column="4">
<widget class="QWidget" name="SKGSmallButtons" native="true">
<layout class="QGridLayout" name="gridLayout">
<property name="leftMargin">
<number>10</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<property name="spacing">
<number>2</number>
</property>
<item row="0" column="0">
<widget class="QToolButton" name="kFreezeBtn">
<property name="maximumSize">
<size>
<width>48</width>
<height>48</height>
</size>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="toolTip">
<string>Freeze / unfreeze fields</string>
</property>
<property name="statusTip">
<string>Freeze / unfreeze fields</string>
</property>
<property name="text">
<string notr="true"/>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>false</bool>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QPushButton" name="kCleanBtn">
<property name="maximumSize">
<size>
<width>48</width>
<height>48</height>
</size>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="toolTip">
<string>Clean editor</string>
</property>
<property name="statusTip">
<string>Clean editor</string>
</property>
<property name="text">
<string notr="true"/>
</property>
</widget>
</item>
<item row="4" column="0">
<spacer name="verticalSpacer_5">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="0">
<widget class="QPushButton" name="kFastEditBtn">
<property name="maximumSize">
<size>
<width>48</width>
<height>48</height>
</size>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="toolTip">
<string>Fast edition</string>
</property>
<property name="statusTip">
<string>Fast edition</string>
</property>
<property name="text">
<string notr="true"/>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QFrame" name="SKGSplitOpSection">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>100</height>
</size>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="SKGTableWidget" name="kSubOperationsTable">
<property name="maximumSize">
<size>
<width>16777215</width>
<height>150</height>
</size>
</property>
<property name="toolTip">
<string>List of splits</string>
</property>
<property name="statusTip">
<string>List of splits</string>
</property>
<property name="editTriggers">
<set>QAbstractItemView::AnyKeyPressed|QAbstractItemView::DoubleClicked|QAbstractItemView::EditKeyPressed|QAbstractItemView::SelectedClicked</set>
</property>
<property name="alternatingRowColors">
<bool>true</bool>
</property>
<property name="selectionBehavior">
<enum>QAbstractItemView::SelectRows</enum>
</property>
<property name="showGrid">
<bool>false</bool>
</property>
<attribute name="horizontalHeaderStretchLastSection">
<bool>true</bool>
</attribute>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_12">
<property name="spacing">
<number>2</number>
</property>
<item>
<widget class="SKGWidgetSelector" name="kWidgetSelector"/>
</item>
<item>
<widget class="QWidget" name="SKGEditionButtonsWidget" native="true">
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="spacing">
<number>2</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QPushButton" name="kAddOperationBtn">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>Create a new operation (Ctrl+Enter)</string>
</property>
<property name="statusTip">
<string>Create a new operation (Ctrl+Enter)</string>
</property>
<property name="text">
<string comment="Verb, add an item to a list">Add</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="kModifyOperationBtn">
<property name="enabled">
<bool>false</bool>
</property>
<property name="toolTip">
<string>Update selected operations (Shift+Enter)</string>
</property>
<property name="statusTip">
<string>Update selected operations (Shift+Enter)</string>
</property>
<property name="text">
<string comment="Verb, modify an item">Modify</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>SKGUnitComboBox</class>
<extends>SKGComboBox</extends>
<header>skgunitcombobox.h</header>
</customwidget>
<customwidget>
<class>SKGCalculatorEdit</class>
<extends>QLineEdit</extends>
<header>skgcalculatoredit.h</header>
</customwidget>
<customwidget>
<class>SKGComboBox</class>
<extends>QComboBox</extends>
<header>skgcombobox.h</header>
</customwidget>
<customwidget>
<class>SKGDateEdit</class>
<extends>QComboBox</extends>
<header>skgdateedit.h</header>
</customwidget>
<customwidget>
<class>SKGFilteredTableView</class>
<extends>QWidget</extends>
<header>skgfilteredtableview.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>SKGTableWidget</class>
<extends>QTableWidget</extends>
<header>skgtablewidget.h</header>
</customwidget>
<customwidget>
<class>SKGWidgetSelector</class>
<extends>QWidget</extends>
<header>skgwidgetselector.h</header>
</customwidget>
<customwidget>
<class>KTitleWidget</class>
<extends>QWidget</extends>
<header>ktitlewidget.h</header>
</customwidget>
</customwidgets>
<tabstops>
<tabstop>kOperationView</tabstop>
<tabstop>kAccountEdit</tabstop>
<tabstop>kDateEdit</tabstop>
<tabstop>kAmountEdit</tabstop>
<tabstop>kUnitEdit</tabstop>
<tabstop>kTargetAccountEdit</tabstop>
<tabstop>kPayeeEdit</tabstop>
<tabstop>kTypeEdit</tabstop>
<tabstop>kNumberEdit</tabstop>
<tabstop>kCommentEdit</tabstop>
<tabstop>kCategoryEdit</tabstop>
<tabstop>kTrackerEdit</tabstop>
<tabstop>kPaymentAccountEdit</tabstop>
<tabstop>kAmountSharesEdit</tabstop>
<tabstop>kCommissionEdit</tabstop>
<tabstop>kTaxEdit</tabstop>
<tabstop>kReconcilitorAmountEdit</tabstop>
<tabstop>kReconciliateAccount</tabstop>
<tabstop>kAddOperationBtn</tabstop>
<tabstop>kModifyOperationBtn</tabstop>
<tabstop>kSubOperationsTable</tabstop>
</tabstops>
<resources/>
<connections/>
<slots>
<slot>onOperationCreatorModified()</slot>
<slot>onAddOperationClicked()</slot>
<slot>onUpdateOperationClicked()</slot>
<slot>onFilterChanged()</slot>
<slot>onFilterRegExpChanged()</slot>
<slot>onResetInternalFilter()</slot>
<slot>onDoubleClick()</slot>
<slot>onSplitOperation()</slot>
<slot>onSwitchBookmark()</slot>
<slot>onRotateAccountTools()</slot>
<slot>onRefreshInformationZone()</slot>
<slot>onValidatePointedOperations()</slot>
<slot>onBtnModeClicked()</slot>
<slot>onTemplateModeClicked()</slot>
<slot>cleanEditor()</slot>
<slot>onAutoPoint()</slot>
<slot>onFreeze()</slot>
<slot>onAddFakeOperation()</slot>
<slot>onFastEdition()</slot>
</slots>
</ui>
diff --git a/plugins/skrooge/skrooge_operation/skgsplittabledelegate.cpp b/plugins/skrooge/skrooge_operation/skgsplittabledelegate.cpp
index 1773acd94..aa1c88130 100644
--- a/plugins/skrooge/skrooge_operation/skgsplittabledelegate.cpp
+++ b/plugins/skrooge/skrooge_operation/skgsplittabledelegate.cpp
@@ -1,170 +1,170 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is Skrooge plugin for operation management.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgsplittabledelegate.h"
#include <kformat.h>
#include <ksqueezedtextlabel.h>
#include <qheaderview.h>
#include <qpainter.h>
#include <utility>
#include "skgbasegui_settings.h"
#include "skgcalculatoredit.h"
#include "skgcombobox.h"
#include "skgdateedit.h"
#include "skgmainpanel.h"
#include "skgtablewidget.h"
SKGSplitTableDelegate::SKGSplitTableDelegate(QObject* iParent, SKGDocument* iDoc, QStringList iListAttribut) : QItemDelegate(iParent),
m_document(iDoc), m_listAttributes(std::move(iListAttribut)), m_table(qobject_cast<SKGTableWidget * >(iParent))
{
}
SKGSplitTableDelegate::~SKGSplitTableDelegate()
{
m_document = nullptr;
}
QWidget* SKGSplitTableDelegate::createEditor(QWidget* iParent,
const QStyleOptionViewItem& option,
const QModelIndex& index) const
{
QSizePolicy newSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
newSizePolicy.setHorizontalStretch(0);
newSizePolicy.setVerticalStretch(0);
if (index.column() == m_listAttributes.indexOf(QStringLiteral("t_category"))) {
auto editor = new SKGComboBox(iParent);
editor->setEditable(true);
if (m_document != nullptr) {
SKGMainPanel::fillWithDistinctValue(QList<QWidget*>() << editor, m_document, QStringLiteral("category"), QStringLiteral("t_fullname"), QStringLiteral("t_close='N'"));
}
editor->setSizePolicy(newSizePolicy);
editor->setSizeAdjustPolicy(QComboBox::AdjustToContents);
m_table->setColumnWidth(index.column(), editor->sizeHint().width());
return editor;
}
if (index.column() == m_listAttributes.indexOf(QStringLiteral("t_comment"))) {
auto editor = new SKGComboBox(iParent);
editor->setEditable(true);
if (m_document != nullptr) {
SKGMainPanel::fillWithDistinctValue(QList<QWidget*>() << editor, m_document, QStringLiteral("v_operation_all_comment"), QStringLiteral("t_comment"), QLatin1String(""));
}
editor->setSizePolicy(newSizePolicy);
editor->setSizeAdjustPolicy(QComboBox::AdjustToContents);
m_table->setColumnWidth(index.column(), editor->sizeHint().width());
return editor;
}
if (index.column() == m_listAttributes.indexOf(QStringLiteral("f_value"))) {
auto editor = new SKGCalculatorEdit(iParent);
editor->setMode(SKGCalculatorEdit::EXPRESSION);
QMapIterator<QString, double> i(m_parameters);
while (i.hasNext()) {
i.next();
editor->addParameterValue(i.key(), i.value());
}
editor->setSizePolicy(newSizePolicy);
m_table->setColumnWidth(index.column(), editor->sizeHint().width());
return editor;
}
if (index.column() == m_listAttributes.indexOf(QStringLiteral("t_refund"))) {
auto editor = new SKGComboBox(iParent);
editor->setEditable(true);
if (m_document != nullptr) {
SKGMainPanel::fillWithDistinctValue(QList<QWidget*>() << editor, m_document, QStringLiteral("refund"), QStringLiteral("t_name"), QStringLiteral("t_close='N'"));
}
editor->setSizePolicy(newSizePolicy);
editor->setSizeAdjustPolicy(QComboBox::AdjustToContents);
m_table->setColumnWidth(index.column(), editor->sizeHint().width());
return editor;
} if (index.column() == m_listAttributes.indexOf(QStringLiteral("d_date"))) {
auto editor = new SKGDateEdit(iParent);
editor->setSizePolicy(newSizePolicy);
editor->setSizeAdjustPolicy(QComboBox::AdjustToContents);
m_table->setColumnWidth(index.column(), editor->sizeHint().width());
return editor;
}
return QItemDelegate::createEditor(iParent, option, index);
}
void SKGSplitTableDelegate::setEditorData(QWidget* editor, const QModelIndex& index) const
{
if (index.column() == m_listAttributes.indexOf(QStringLiteral("f_value"))) {
auto* calculator = qobject_cast<SKGCalculatorEdit*>(editor);
if (calculator != nullptr) {
calculator->setText(index.model()->data(index, Qt::ToolTipRole).toString());
}
} else if (index.column() == m_listAttributes.indexOf(QStringLiteral("d_date"))) {
auto* date = qobject_cast<SKGDateEdit*>(editor);
if (date != nullptr) {
date->setDate(SKGServices::stringToTime(index.model()->data(index, Qt::ToolTipRole).toString()).date());
}
} else {
QItemDelegate::setEditorData(editor, index);
}
}
void SKGSplitTableDelegate::setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const
{
if (index.column() == m_listAttributes.indexOf(QStringLiteral("f_value"))) {
auto* calculator = qobject_cast<SKGCalculatorEdit*>(editor);
if ((calculator != nullptr) && (model != nullptr)) {
QString f = calculator->formula();
QString t = SKGServices::doubleToString(calculator->value());
if (f.isEmpty()) {
f = t;
}
bool previous = model->blockSignals(true);
model->setData(index, f, Qt::ToolTipRole);
model->setData(index, calculator->value(), 101);
model->blockSignals(previous);
model->setData(index, t, Qt::DisplayRole);
}
} else if (index.column() == m_listAttributes.indexOf(QStringLiteral("d_date"))) {
auto* date = qobject_cast<SKGDateEdit*>(editor);
if ((date != nullptr) && (model != nullptr)) {
QString dateDisplay = SKGMainPanel::dateToString(date->date());
QString dateInternal = SKGServices::dateToSqlString(date->date());
model->setData(index, dateInternal, Qt::ToolTipRole);
model->setData(index, dateDisplay, Qt::DisplayRole);
}
} else {
QItemDelegate::setModelData(editor, model, index);
}
m_table->resizeColumnsToContents();
m_table->horizontalHeader()->setStretchLastSection(true);
}
void SKGSplitTableDelegate::addParameterValue(const QString& iParameter, double iValue)
{
m_parameters.insert(iParameter, iValue);
}
diff --git a/plugins/skrooge/skrooge_operation/skgsplittabledelegate.h b/plugins/skrooge/skrooge_operation/skgsplittabledelegate.h
index 9609ac765..64f8f2172 100644
--- a/plugins/skrooge/skrooge_operation/skgsplittabledelegate.h
+++ b/plugins/skrooge/skrooge_operation/skgsplittabledelegate.h
@@ -1,98 +1,98 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGSPLITTABLEDELEGATE_H
#define SKGSPLITTABLEDELEGATE_H
/** @file
* This file is Skrooge plugin for bank management.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include <qitemdelegate.h>
class SKGDocument;
class SKGTableWidget;
/**
* This file is Skrooge plugin for operation management
*/
class SKGSplitTableDelegate : public QItemDelegate
{
Q_OBJECT
public:
/**
* Default Constructor
* @param iParent parent widget
* @param iDoc the document
* @param iListAttribut the list of corresponding attribute
*/
explicit SKGSplitTableDelegate(QObject* iParent, SKGDocument* iDoc, QStringList iListAttribut = QStringList());
/**
* Default Destructor
*/
~SKGSplitTableDelegate() override;
/**
* Returns the widget used to edit the item specified by index for editing.
* The parent widget and style option are used to control how the editor widget appears.
* @param iParent parent widget
* @param option options
* @param index index
* @return the widget
*/
QWidget* createEditor(QWidget* iParent,
const QStyleOptionViewItem& option,
const QModelIndex& index) const override;
/**
* Set the data to be shown in the delegate. For the quantity column,
* We pass the text value. This allows the user to correct an invalid
* expression without having to retype everything.
* @param editor
* @param index
*/
void setEditorData(QWidget* editor, const QModelIndex& index) const override;
/**
* Get the data to be shown in the model. For the quantity column,
* We pass the text value. If the entered expression was incorrect,
* we display it in red so that the user can see it is wrong and
* correct it
* @param editor
* @param model
* @param index
*/
void setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const override;
/**
* Add a parameter
* @param iParameter the parameter name
* @param iValue the value
*/
virtual void addParameterValue(const QString& iParameter, double iValue);
private:
Q_DISABLE_COPY(SKGSplitTableDelegate)
SKGDocument* m_document;
QMap<QString, double> m_parameters;
QStringList m_listAttributes;
SKGTableWidget* m_table;
};
#endif // SKGSPLITTABLEDELEGATE_H
diff --git a/plugins/skrooge/skrooge_payee/CMakeLists.txt b/plugins/skrooge/skrooge_payee/CMakeLists.txt
index d511eae72..b6eefa196 100644
--- a/plugins/skrooge/skrooge_payee/CMakeLists.txt
+++ b/plugins/skrooge/skrooge_payee/CMakeLists.txt
@@ -1,38 +1,38 @@
#***************************************************************************
#* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
#* *
#* 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 <http://www.gnu.org/licenses/> *
+#* along with this program. If not, see <https://www.gnu.org/licenses/> *
#***************************************************************************
MESSAGE( STATUS "..:: CMAKE PLUGIN_PAYEE ::..")
PROJECT(plugin_payee)
LINK_DIRECTORIES (${LIBRARY_OUTPUT_PATH})
SET(skrooge_payee_SRCS
skgpayeeplugin.cpp
skgpayeepluginwidget.cpp)
ki18n_wrap_ui(skrooge_payee_SRCS skgpayeepluginwidget_base.ui skgpayeepluginwidget_pref.ui)
kconfig_add_kcfg_files(skrooge_payee_SRCS skgpayee_settings.kcfgc )
ADD_LIBRARY(skrooge_payee MODULE ${skrooge_payee_SRCS})
TARGET_LINK_LIBRARIES(skrooge_payee KF5::Parts KF5::ItemViews skgbasemodeler skgbasegui skgbankmodeler skgbankgui)
########### install files ###############
INSTALL(TARGETS skrooge_payee DESTINATION ${KDE_INSTALL_QTPLUGINDIR})
INSTALL(FILES ${PROJECT_SOURCE_DIR}/org.kde.skrooge-plugin-payee.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR})
INSTALL(FILES ${PROJECT_SOURCE_DIR}/skrooge_payee.rc DESTINATION ${KDE_INSTALL_KXMLGUI5DIR}/skrooge_payee )
INSTALL(FILES ${PROJECT_SOURCE_DIR}/skgpayee_settings.kcfg DESTINATION ${KDE_INSTALL_KCFGDIR} )
diff --git a/plugins/skrooge/skrooge_payee/org.kde.skrooge-plugin-payee.desktop b/plugins/skrooge/skrooge_payee/org.kde.skrooge-plugin-payee.desktop
index 2930a7030..d2312fe3d 100644
--- a/plugins/skrooge/skrooge_payee/org.kde.skrooge-plugin-payee.desktop
+++ b/plugins/skrooge/skrooge_payee/org.kde.skrooge-plugin-payee.desktop
@@ -1,74 +1,74 @@
[Desktop Entry]
Name=Skrooge payee plugin
Name[bs]=Skrooge primaočev dodatak
Name[ca]=Connector de beneficiaris de l'Skrooge
Name[ca@valencia]=Connector de beneficiaris de l'Skrooge
Name[cs]=Modul plátců pro Skrooge
Name[da]=Skrooge betalingsmodtager-plugin
Name[de]=Skrooge-Modul für Zahlungsempfänger
Name[el]=Skrooge payee plugin
Name[en_GB]=Skrooge payee plugin
Name[es]=Complemento de beneficiarios de Skrooge
Name[et]=Skrooge maksesaajaplugin
Name[fi]=Skroogen maksunsaajaliitännäinen
Name[fr]=Module externe Skrooge pour la gestion des bénéficiaires
Name[gl]=Complemento de beneficiarios de Skrooge
Name[hu]=Skrooge fizető bővítmény
Name[it]=Estensione beneficiari di Skrooge
Name[lt]=Skrooge gavėjo papildinys
Name[nb]=Skrooge modul for betalingsmottaker
Name[nl]=Plugin voor Skrooge-begunstigde
Name[pl]=Wtyczka odbiorców dla Skrooge
Name[pt]='Plugin' de beneficiários do Skrooge
Name[pt_BR]=Plugin de beneficiário do Skrooge
Name[ru]=Модуль получателей
Name[sk]=Plugin veriteľov Skrooge
Name[sv]=Skrooge insticksprogram för betalare
Name[tr]=Skrooge alacaklı eklentisi
Name[uk]=Додаток отримувачів Skrooge
Name[x-test]=xxSkrooge payee pluginxx
Name[zh_TW]=Skrooge 收款人外掛程式
Comment=A skrooge plugin to follow payee
Comment[bs]=Skrooge dodatak za praćenje primaoca novca
Comment[ca]=Un connector de l'Skrooge per fer el seguiment dels beneficiaris
Comment[ca@valencia]=Un connector de l'Skrooge per fer el seguiment dels beneficiaris
Comment[cs]=Modul sledování plátců pro Skrooge
Comment[da]=Et Skrooge-plugin til at følge betalingsmodtager
Comment[de]=Ein Skrooge-Modul zur Überwachung von Zahlungsempfängern
Comment[el]=Ένα πρόσθετο του skrooge για την παρακολούθηση των δικαιούχων
Comment[en_GB]=A skrooge plugin to follow payee
Comment[es]=Un complemento de Skrooge para seguir los beneficiarios
Comment[et]=Skrooge maksesaaja jälgimise plugin
Comment[fi]=Skroogen maksunsaajien seurantaliitännäinen
Comment[fr]=Un module externe Skrooge pour le suivi des bénéficiaires
Comment[gl]=Un complemento de Skrooge para seguir os beneficiarios.
Comment[hu]=Egy Skrooge bővítmény fizetések követéséhez
Comment[it]=Un'estensione di Skrooge per seguire il beneficiario
Comment[lt]=Skrooge gavėjo sekimo papildinys
Comment[nb]=En Skrooge-modul for å følge betalingsmottaker
Comment[nl]=Een plugin van skrooge voor het volgen van begunstigden
Comment[pl]=Wtyczka Skrooge do obsługi odbiorców
Comment[pt]=Um 'plugin' do Skrooge para fazer o seguimento dos beneficiários
Comment[pt_BR]=Um plugin do Skrooge para fazer o acompanhamento dos beneficiários
Comment[ru]=Модуль получателей
Comment[sk]=Plugin Skrooge na sledovanie veriteľa
Comment[sv]=Ett insticksprogram till Skrooge som följer betalare
Comment[tr]=Alacıklıları takip etmek için bir Skrooge eklentisi
Comment[uk]=Додаток до skrooge для стеження за отримувачами
Comment[x-test]=xxA skrooge plugin to follow payeexx
Comment[zh_TW]=管理收款人的 Skrooge 外掛程式
Encoding=UTF-8
Icon=skrooge
Type=Service
X-KDE-ServiceTypes=SKG GUI/Plugin
X-KDE-Library=skrooge_payee
X-Krunner-ID=Skrooge payee plugin
X-KDE-PluginInfo-Author=Stephane MANKOWSKI,miraks
X-KDE-PluginInfo-Email=stephane@mankowski.fr
X-KDE-PluginInfo-Name=skrooge_payee
X-KDE-PluginInfo-Version=1.0
-X-KDE-PluginInfo-Website=http://skrooge.org/
+X-KDE-PluginInfo-Website=https://skrooge.org/
X-KDE-PluginInfo-Category=Plugins
X-KDE-PluginInfo-Depends=
X-KDE-PluginInfo-License=GPL
X-KDE-PluginInfo-EnabledByDefault=true
diff --git a/plugins/skrooge/skrooge_payee/skgpayeeplugin.cpp b/plugins/skrooge/skrooge_payee/skgpayeeplugin.cpp
index 055ccfb03..d59581c9a 100644
--- a/plugins/skrooge/skrooge_payee/skgpayeeplugin.cpp
+++ b/plugins/skrooge/skrooge_payee/skgpayeeplugin.cpp
@@ -1,195 +1,195 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* A skrooge plugin to payee operations
*
* @author Stephane MANKOWSKI
*/
#include "skgpayeeplugin.h"
#include <kaboutdata.h>
#include <kactioncollection.h>
#include <kpluginfactory.h>
#include <kstandardaction.h>
#include "skgdocumentbank.h"
#include "skgpayee_settings.h"
#include "skgpayeepluginwidget.h"
#include "skgtraces.h"
#include "skgtransactionmng.h"
/**
* This plugin factory.
*/
K_PLUGIN_FACTORY(SKGPayeePluginFactory, registerPlugin<SKGPayeePlugin>();)
SKGPayeePlugin::SKGPayeePlugin(QWidget* iWidget, QObject* iParent, const QVariantList& /*iArg*/) : SKGInterfacePlugin(iParent), m_currentBankDocument(nullptr)
{
Q_UNUSED(iWidget)
SKGTRACEINFUNC(10)
}
SKGPayeePlugin::~SKGPayeePlugin()
{
SKGTRACEINFUNC(10)
m_currentBankDocument = nullptr;
}
bool SKGPayeePlugin::setupActions(SKGDocument* iDocument)
{
SKGTRACEINFUNC(10)
if (qobject_cast<SKGDocumentBank*>(iDocument) == nullptr) {
return false;
}
m_currentBankDocument = iDocument;
setComponentName(QStringLiteral("skrooge_payee"), title());
setXMLFile(QStringLiteral("skrooge_payee.rc"));
// Actions
QStringList overlaydelete;
overlaydelete.push_back(QStringLiteral("edit-delete"));
auto deleteUnusedPayeesAction = new QAction(SKGServices::fromTheme(icon(), overlaydelete), i18nc("Verb", "Delete unused payees"), this);
connect(deleteUnusedPayeesAction, &QAction::triggered, this, &SKGPayeePlugin::deleteUnusedPayees);
registerGlobalAction(QStringLiteral("clean_delete_unused_payees"), deleteUnusedPayeesAction);
// ------------
auto actTmp = new QAction(SKGServices::fromTheme(icon()), i18nc("Verb", "Open similar payees..."), this);
actTmp->setData(QString("skg://skrooge_payee_plugin/?title_icon=" % icon() % "&title=" % SKGServices::encodeForUrl(i18nc("Noun, a list of items", "Similar payees")) %
"&whereClause=" % SKGServices::encodeForUrl(QStringLiteral("EXISTS (SELECT 1 FROM payee p2 WHERE p2.id<>v_payee_display.id AND upper(p2.t_name)=upper(v_payee_display.t_name) AND p2.t_name<>v_payee_display.t_name)"))));
connect(actTmp, &QAction::triggered, SKGMainPanel::getMainPanel(), [ = ]() {
SKGMainPanel::getMainPanel()->SKGMainPanel::openPage();
});
registerGlobalAction(QStringLiteral("view_open_similar_payees"), actTmp);
return true;
}
SKGTabPage* SKGPayeePlugin::getWidget()
{
SKGTRACEINFUNC(10)
return new SKGPayeePluginWidget(SKGMainPanel::getMainPanel(), m_currentBankDocument);
}
KConfigSkeleton* SKGPayeePlugin::getPreferenceSkeleton()
{
return skgpayee_settings::self();
}
QString SKGPayeePlugin::title() const
{
return i18nc("Noun, something that is used to track items", "Payees");
}
QString SKGPayeePlugin::icon() const
{
return QStringLiteral("user-group-properties");
}
QString SKGPayeePlugin::toolTip() const
{
return i18nc("A tool tip", "Payees management");
}
int SKGPayeePlugin::getOrder() const
{
return 28;
}
QStringList SKGPayeePlugin::tips() const
{
QStringList output;
output.push_back(i18nc("Description of a tips", "<p>... <a href=\"skg://skrooge_payee_plugin\">payees</a> can be merged by drag & drop.</p>"));
return output;
}
bool SKGPayeePlugin::isInPagesChooser() const
{
return true;
}
SKGAdviceList SKGPayeePlugin::advice(const QStringList& iIgnoredAdvice)
{
SKGTRACEINFUNC(10)
SKGAdviceList output;
// Check unused payee
if (!iIgnoredAdvice.contains(QStringLiteral("skgpayeeplugin_unused"))) {
bool exist = false;
m_currentBankDocument->existObjects(QStringLiteral("payee LEFT JOIN operation ON operation.r_payee_id=payee.id"), QStringLiteral("operation.id IS NULL"), exist);
if (exist) {
SKGAdvice ad;
ad.setUUID(QStringLiteral("skgpayeeplugin_unused"));
ad.setPriority(5);
ad.setShortMessage(i18nc("Advice on making the best (short)", "Many unused payees"));
ad.setLongMessage(i18nc("Advice on making the best (long)", "You can improve performances by removing payees for which no operation is registered."));
SKGAdvice::SKGAdviceActionList autoCorrections;
{
SKGAdvice::SKGAdviceAction a;
a.Title = QStringLiteral("skg://clean_delete_unused_payees");
a.IsRecommended = true;
autoCorrections.push_back(a);
}
ad.setAutoCorrections(autoCorrections);
output.push_back(ad);
}
}
// Check payee with different case
if (!iIgnoredAdvice.contains(QStringLiteral("skgpayeeplugin_case"))) {
bool exist = false;
m_currentBankDocument->existObjects(QStringLiteral("payee"), QStringLiteral("EXISTS (SELECT 1 FROM payee p2 WHERE p2.id>payee.id AND p2.t_name=payee.t_name COLLATE NOCASE AND p2.t_name<>payee.t_name)"), exist);
if (exist) {
SKGAdvice ad;
ad.setUUID(QStringLiteral("skgpayeeplugin_case"));
ad.setPriority(3);
ad.setShortMessage(i18nc("Advice on making the best (short)", "Some payees seem to be identical"));
ad.setLongMessage(i18nc("Advice on making the best (long)", "Some payee seem to be identical but with different syntax. They could be merged."));
QStringList autoCorrections;
autoCorrections.push_back(QStringLiteral("skg://view_open_similar_payees"));
ad.setAutoCorrections(autoCorrections);
output.push_back(ad);
}
}
return output;
}
void SKGPayeePlugin::deleteUnusedPayees() const
{
SKGError err;
_SKGTRACEINFUNCRC(10, err)
if (m_currentBankDocument != nullptr) {
SKGBEGINTRANSACTION(*m_currentBankDocument, i18nc("Noun, name of the user action", "Delete unused payees"), err)
// Modification of payee object
QString sql = QStringLiteral("DELETE FROM payee WHERE id IN (SELECT payee.id FROM payee LEFT JOIN operation ON operation.r_payee_id=payee.id WHERE operation.id IS NULL)");
err = m_currentBankDocument->executeSqliteOrder(sql);
}
// status bar
IFOKDO(err, SKGError(0, i18nc("Successful message after an user action", "Unused payees deleted")))
else {
err.addError(ERR_FAIL, i18nc("Error message", "Unused payees deletion failed"));
}
// Display error
SKGMainPanel::displayErrorMessage(err);
}
#include <skgpayeeplugin.moc>
diff --git a/plugins/skrooge/skrooge_payee/skgpayeeplugin.h b/plugins/skrooge/skrooge_payee/skgpayeeplugin.h
index d23f733c8..d11d30620 100644
--- a/plugins/skrooge/skrooge_payee/skgpayeeplugin.h
+++ b/plugins/skrooge/skrooge_payee/skgpayeeplugin.h
@@ -1,119 +1,119 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGPAYEEPLUGIN_H
#define SKGPAYEEPLUGIN_H
/** @file
* A skrooge plugin to payee operations.
*
* @author Stephane MANKOWSKI
*/
#include "skginterfaceplugin.h"
#include "ui_skgpayeepluginwidget_pref.h"
/**
* A skrooge plugin to tracker operations
*/
class SKGPayeePlugin : public SKGInterfacePlugin
{
Q_OBJECT
Q_INTERFACES(SKGInterfacePlugin)
public:
/**
* Default Constructor
*/
explicit SKGPayeePlugin(QWidget* iWidget, QObject* iParent, const QVariantList& iArg);
/**
* Default Destructor
*/
~SKGPayeePlugin() override;
/**
* Called to initialise the plugin
* @return true if the plugin is compatible with the document
*/
bool setupActions(SKGDocument* iDocument) override;
/**
* The preference skeleton of the plugin.
* @return The preference skeleton of the plugin
*/
KConfigSkeleton* getPreferenceSkeleton() override;
/**
* The page widget of the plugin.
* @return The page widget of the plugin
*/
SKGTabPage* getWidget() override;
/**
* The title of the plugin.
* @return The title of the plugin
*/
QString title() const override;
/**
* The icon of the plugin.
* @return The icon of the plugin
*/
QString icon() const override;
/**
* The toolTip of the plugin.
* @return The toolTip of the plugin
*/
QString toolTip() const override;
/**
* The tips list of the plugin.
* @return The tips list of the plugin
*/
QStringList tips() const override;
/**
* Must be implemented to set the position of the plugin.
* @return integer value between 0 and 999 (default = 999)
*/
int getOrder() const override;
/**
* Must be implemented to know if a plugin must be display in pages chooser.
* @return true of false (default = false)
*/
bool isInPagesChooser() const override;
/**
* The advice list of the plugin.
* @return The advice list of the plugin
*/
SKGAdviceList advice(const QStringList& iIgnoredAdvice) override;
private Q_SLOTS:
void deleteUnusedPayees() const;
private:
Q_DISABLE_COPY(SKGPayeePlugin)
SKGDocument* m_currentBankDocument;
Ui::skgpayeeplugin_pref ui{};
};
#endif // SKGPAYEEPLUGIN_H
diff --git a/plugins/skrooge/skrooge_payee/skgpayeepluginwidget.cpp b/plugins/skrooge/skrooge_payee/skgpayeepluginwidget.cpp
index ca6f7889d..b1cd3e40f 100644
--- a/plugins/skrooge/skrooge_payee/skgpayeepluginwidget.cpp
+++ b/plugins/skrooge/skrooge_payee/skgpayeepluginwidget.cpp
@@ -1,330 +1,330 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* A skrooge plugin to track operations.
*
* @author Stephane MANKOWSKI
*/
#include "skgpayeepluginwidget.h"
#include <qaction.h>
#include <qdom.h>
#include <qevent.h>
#include "skgcategoryobject.h"
#include "skgdocumentbank.h"
#include "skgmainpanel.h"
#include "skgobjectmodel.h"
#include "skgpayeeobject.h"
#include "skgtraces.h"
#include "skgtransactionmng.h"
SKGPayeePluginWidget::SKGPayeePluginWidget(QWidget* iParent, SKGDocument* iDocument)
: SKGTabPage(iParent, iDocument)
{
SKGTRACEINFUNC(1)
if (iDocument == nullptr) {
return;
}
ui.setupUi(this);
// Set show widget
ui.kView->getShowWidget()->addGroupedItem(QStringLiteral("all"), i18n("All"), QLatin1String(""), QLatin1String(""), QLatin1String(""), Qt::META + Qt::Key_A);
ui.kView->getShowWidget()->addGroupedItem(QStringLiteral("opened"), i18n("Opened"), QStringLiteral("vcs-normal"), QStringLiteral("t_close='N'"), QLatin1String(""), Qt::META + Qt::Key_O);
ui.kView->getShowWidget()->addGroupedItem(QStringLiteral("closed"), i18n("Closed"), QStringLiteral("vcs-conflicting"), QStringLiteral("t_close='Y'"), QLatin1String(""), Qt::META + Qt::Key_C);
ui.kView->getShowWidget()->addGroupedItem(QStringLiteral("highlighted"), i18n("Highlighted only"), QStringLiteral("bookmarks"), QStringLiteral("t_bookmarked='Y'"), QLatin1String(""), Qt::META + Qt::Key_H);
ui.kView->getShowWidget()->addGroupedItem(QStringLiteral("income"), i18n("Income"), QStringLiteral("list-add"), QStringLiteral("f_CURRENTAMOUNT>=0"), QLatin1String(""), Qt::META + Qt::Key_Plus);
ui.kView->getShowWidget()->addGroupedItem(QStringLiteral("expenditure"), i18n("Expenditure"), QStringLiteral("list-remove"), QStringLiteral("f_CURRENTAMOUNT<=0"), QLatin1String(""), Qt::META + Qt::Key_Minus);
ui.kView->getShowWidget()->setDefaultState(QStringLiteral("all"));
ui.kView->getShowWidget()->setDefaultState(QStringLiteral("all"));
ui.kNameLbl->setText(i18n("%1:", iDocument->getDisplay(QStringLiteral("t_name"))));
ui.kAddressLabel->setText(i18n("%1:", iDocument->getDisplay(QStringLiteral("t_address"))));
ui.kCategoryLabel->setText(i18n("%1:", iDocument->getDisplay(QStringLiteral("t_CATEGORY"))));
ui.kAddButton->setIcon(SKGServices::fromTheme(QStringLiteral("list-add")));
ui.kModifyButton->setIcon(SKGServices::fromTheme(QStringLiteral("dialog-ok")));
ui.kDeleteUnusedButton->setIcon(SKGServices::fromTheme(QStringLiteral("edit-delete")));
ui.kView->setModel(new SKGObjectModel(qobject_cast<SKGDocumentBank*>(getDocument()), QStringLiteral("v_payee_display"), QStringLiteral("1=0"), this, QLatin1String(""), false));
ui.kView->getView()->resizeColumnToContents(0);
connect(getDocument(), &SKGDocument::tableModified, this, &SKGPayeePluginWidget::dataModified, Qt::QueuedConnection);
connect(ui.kView->getView(), &SKGTreeView::clickEmptyArea, this, &SKGPayeePluginWidget::cleanEditor);
connect(ui.kView->getView(), &SKGTreeView::doubleClicked, SKGMainPanel::getMainPanel()->getGlobalAction(QStringLiteral("open")).data(), &QAction::trigger);
connect(ui.kView->getView(), &SKGTreeView::selectionChangedDelayed, this, [ = ] {this->onSelectionChanged();});
connect(ui.kAddButton, &QPushButton::clicked, this, &SKGPayeePluginWidget::onAddPayee);
connect(ui.kModifyButton, &QPushButton::clicked, this, &SKGPayeePluginWidget::onModifyPayee);
connect(ui.kNameInput, &QLineEdit::textChanged, this, &SKGPayeePluginWidget::onEditorModified);
connect(ui.kDeleteUnusedButton, &QPushButton::clicked, this, &SKGPayeePluginWidget::onDeleteUnused);
// Set Event filters to catch CTRL+ENTER or SHIFT+ENTER
this->installEventFilter(this);
dataModified(QLatin1String(""), 0);
}
SKGPayeePluginWidget::~SKGPayeePluginWidget()
{
SKGTRACEINFUNC(1)
}
bool SKGPayeePluginWidget::eventFilter(QObject* iObject, QEvent* iEvent)
{
if ((iEvent != nullptr) && iEvent->type() == QEvent::KeyPress) {
auto* keyEvent = dynamic_cast<QKeyEvent*>(iEvent);
if (keyEvent && (keyEvent->key() == Qt::Key_Return || keyEvent->key() == Qt::Key_Enter) && iObject == this) {
if ((QApplication::keyboardModifiers() & Qt::ControlModifier) != 0u && ui.kAddButton->isEnabled()) {
ui.kAddButton->click();
} else if ((QApplication::keyboardModifiers() &Qt::ShiftModifier) != 0u && ui.kModifyButton->isEnabled()) {
ui.kModifyButton->click();
}
}
}
return SKGTabPage::eventFilter(iObject, iEvent);
}
void SKGPayeePluginWidget::onSelectionChanged()
{
SKGTRACEINFUNC(10)
int nbSelect = ui.kView->getView()->getNbSelectedObjects();
if (nbSelect == 1) {
SKGPayeeObject obj(ui.kView->getView()->getFirstSelectedObject());
ui.kNameInput->setText(obj.getName());
ui.kAddressEdit->setText(obj.getAddress());
ui.kCategoryEdit->setText(obj.getAttribute(QStringLiteral("t_CATEGORY")));
} else if (nbSelect > 1) {
ui.kNameInput->setText(NOUPDATE);
ui.kAddressEdit->setText(NOUPDATE);
ui.kCategoryEdit->setText(NOUPDATE);
}
onEditorModified();
Q_EMIT selectionChanged();
}
QString SKGPayeePluginWidget::getState()
{
SKGTRACEINFUNC(10)
QDomDocument doc(QStringLiteral("SKGML"));
QDomElement root = doc.createElement(QStringLiteral("parameters"));
doc.appendChild(root);
root.setAttribute(QStringLiteral("view"), ui.kView->getState());
return doc.toString();
}
void SKGPayeePluginWidget::setState(const QString& iState)
{
SKGTRACEINFUNC(10)
QDomDocument doc(QStringLiteral("SKGML"));
doc.setContent(iState);
QDomElement root = doc.documentElement();
ui.kView->setFilter(SKGServices::fromTheme(root.attribute(QStringLiteral("title_icon"))), root.attribute(QStringLiteral("title")), root.attribute(QStringLiteral("whereClause")));
ui.kView->setState(root.attribute(QStringLiteral("view")));
}
QString SKGPayeePluginWidget::getDefaultStateAttribute()
{
return QStringLiteral("SKGPAYEE_DEFAULT_PARAMETERS");
}
QWidget* SKGPayeePluginWidget::mainWidget()
{
return ui.kView->getView();
}
void SKGPayeePluginWidget::onEditorModified()
{
_SKGTRACEINFUNC(10)
int nb = getNbSelectedObjects();
ui.kModifyButton->setEnabled(!ui.kNameInput->text().isEmpty() && nb >= 1);
ui.kAddButton->setEnabled(!ui.kNameInput->text().isEmpty() &&
!ui.kNameInput->text().startsWith(QLatin1Char('=')));
}
void SKGPayeePluginWidget::dataModified(const QString& iTableName, int iIdTransaction, bool iLightTransaction)
{
SKGTRACEINFUNC(10)
Q_UNUSED(iIdTransaction)
if (!iLightTransaction) {
if (iTableName == QStringLiteral("payee") || iTableName.isEmpty()) {
// Set completions
SKGMainPanel::fillWithDistinctValue(QList<QWidget*>() << ui.kNameInput, getDocument(), QStringLiteral("payee"), QStringLiteral("t_name"), QLatin1String(""), true);
SKGMainPanel::fillWithDistinctValue(QList<QWidget*>() << ui.kAddressEdit, getDocument(), QStringLiteral("payee"), QStringLiteral("t_address"), QLatin1String(""), true);
SKGMainPanel::fillWithDistinctValue(QList<QWidget*>() << ui.kCategoryEdit, getDocument(), QStringLiteral("category"), QStringLiteral("t_fullname"), QLatin1String(""));
}
}
}
void SKGPayeePluginWidget::onAddPayee()
{
SKGError err;
_SKGTRACEINFUNCRC(10, err)
QString name = ui.kNameInput->text();
SKGPayeeObject payee;
{
SKGBEGINTRANSACTION(*getDocument(), i18nc("Noun, name of the user action", "Payee creation '%1'", name), err)
IFOKDO(err, SKGPayeeObject::createPayee(qobject_cast<SKGDocumentBank*>(getDocument()), name, payee))
IFOKDO(err, payee.setAddress(ui.kAddressEdit->text()))
SKGCategoryObject cat;
QString catName = ui.kCategoryEdit->text().trimmed();
if (!err && catName != NOUPDATE) {
err = SKGCategoryObject::createPathCategory(qobject_cast<SKGDocumentBank*>(getDocument()), catName, cat, true);
}
IFOKDO(err, payee.setCategory(cat))
IFOKDO(err, payee.save())
// Send message
IFOKDO(err, payee.getDocument()->sendMessage(i18nc("An information message", "The payee '%1' has been added", payee.getDisplayName()), SKGDocument::Hidden))
}
// status bar
IFOK(err) {
err = SKGError(0, i18nc("Successful message after an user action", "Payee '%1' created", name));
ui.kView->getView()->selectObject(payee.getUniqueID());
} else {
err.addError(ERR_FAIL, i18nc("Error message", "Payee creation failed"));
}
// Display error
SKGMainPanel::displayErrorMessage(err, true);
}
void SKGPayeePluginWidget::onModifyPayee()
{
SKGError err;
_SKGTRACEINFUNCRC(10, err)
// Get Selection
SKGObjectBase::SKGListSKGObjectBase selection = getSelectedObjects();
int nb = selection.count();
{
SKGBEGINPROGRESSTRANSACTION(*getDocument(), i18nc("Noun, name of the user action", "Payee update"), err, nb)
auto name = ui.kNameInput->text();
if (name != NOUPDATE && !name.startsWith(QLatin1String("="))) {
// Is this name already existing?
bool messageSent = false;
SKGPayeeObject p(getDocument());
p.setName(name);
IFOK(p.load()) {
if (selection.indexOf(p) == -1) {
// We will have to merge with the existing payee
selection.insert(0, p);
nb++;
getDocument()->sendMessage(i18nc("Information message", "You tried to modify names of selected payees to an existing payee. Payees have been merged."));
messageSent = true;
}
}
// Is it a massive modification of payees to merge them ?
if (nb > 1) {
if (!messageSent) {
getDocument()->sendMessage(i18nc("Information message", "You tried to modify all names of selected payees. Payees have been merged."));
}
// Do the merge
SKGPayeeObject payeeObj1(selection[0]);
for (int i = 1; !err && i < nb; ++i) {
SKGPayeeObject payeeObj(selection.at(i));
// Send message
IFOKDO(err, payeeObj.getDocument()->sendMessage(i18nc("An information message", "The payee '%1' has been merged with payee '%2'", payeeObj1.getDisplayName(), payeeObj.getDisplayName()), SKGDocument::Hidden))
err = payeeObj1.merge(payeeObj);
}
// Change selection for the rest of the operation
selection.clear();
selection.push_back(payeeObj1);
nb = 1;
}
}
for (int i = 0; !err && i < nb; ++i) {
// Modification of object
SKGPayeeObject payee(selection.at(i));
err = payee.setName(name);
QString address = ui.kAddressEdit->text();
if (address != NOUPDATE) {
IFOKDO(err, payee.setAddress(address))
}
SKGCategoryObject cat;
QString catName = ui.kCategoryEdit->text().trimmed();
if (!err && catName != NOUPDATE) {
err = SKGCategoryObject::createPathCategory(qobject_cast<SKGDocumentBank*>(getDocument()), catName, cat, true);
IFOKDO(err, payee.setCategory(cat))
}
IFOKDO(err, payee.save())
// Send message
IFOKDO(err, payee.getDocument()->sendMessage(i18nc("An information message", "The payee '%1' has been updated", payee.getDisplayName()), SKGDocument::Hidden))
}
}
// status bar
IFOKDO(err, SKGError(0, i18nc("Successful message after an user action", "Payee updated")))
else {
err.addError(ERR_FAIL, i18nc("Error message", "Payee update failed"));
}
// Display error
SKGMainPanel::displayErrorMessage(err, true);
// Set focus on table
ui.kView->getView()->setFocus();
}
void SKGPayeePluginWidget::cleanEditor()
{
if (getNbSelectedObjects() == 0) {
ui.kNameInput->setText(QLatin1String(""));
ui.kAddressEdit->setText(QLatin1String(""));
}
}
void SKGPayeePluginWidget::activateEditor()
{
ui.kNameInput->setFocus();
}
bool SKGPayeePluginWidget::isEditor()
{
return true;
}
void SKGPayeePluginWidget::onDeleteUnused()
{
QAction* act = SKGMainPanel::getMainPanel()->getGlobalAction(QStringLiteral("clean_delete_unused_payees"));
if (act != nullptr) {
act->trigger();
}
}
diff --git a/plugins/skrooge/skrooge_payee/skgpayeepluginwidget.h b/plugins/skrooge/skrooge_payee/skgpayeepluginwidget.h
index da8a3ed8e..6e5f15831 100644
--- a/plugins/skrooge/skrooge_payee/skgpayeepluginwidget.h
+++ b/plugins/skrooge/skrooge_payee/skgpayeepluginwidget.h
@@ -1,110 +1,110 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGPAYEEPLUGINWIDGET_H
#define SKGPAYEEPLUGINWIDGET_H
/** @file
* A skrooge plugin to payee operations
*
* @author Stephane MANKOWSKI
*/
#include "skgtabpage.h"
#include "ui_skgpayeepluginwidget_base.h"
/**
* A skrooge plugin to track operations
*/
class SKGPayeePluginWidget : public SKGTabPage
{
Q_OBJECT
public:
/**
* Default Constructor
* @param iParent the parent widget
* @param iDocument the document
*/
explicit SKGPayeePluginWidget(QWidget* iParent, SKGDocument* iDocument);
/**
* Default Destructor
*/
~SKGPayeePluginWidget() override;
/**
* Get the current state
* MUST BE OVERWRITTEN
* @return a string containing all information needed to set the same state.
* Could be an XML stream
*/
QString getState() override;
/**
* Set the current state
* MUST BE OVERWRITTEN
* @param iState must be interpreted to set the state of the widget
*/
void setState(const QString& iState) override;
/**
* Get attribute name to save the default state
* MUST BE OVERWRITTEN
* @return attribute name to save the default state.
*/
QString getDefaultStateAttribute() override;
/**
* Get the main widget
* @return a widget
*/
QWidget* mainWidget() override;
/**
* To know if this page contains an editor. MUST BE OVERWRITTEN
* @return the editor state
*/
bool isEditor() override;
/**
* To activate the editor by setting focus on right widget. MUST BE OVERWRITTEN
*/
void activateEditor() override;
protected:
/**
* Event filtering
* @param iObject object
* @param iEvent event
* @return In your reimplementation of this function, if you want to filter the event out, i.e. stop it being handled further, return true; otherwise return false.
*/
bool eventFilter(QObject* iObject, QEvent* iEvent) override;
private Q_SLOTS:
void dataModified(const QString& iTableName, int iIdTransaction, bool iLightTransaction = false);
void onSelectionChanged();
void onEditorModified();
void onAddPayee();
void onModifyPayee();
void cleanEditor();
void onDeleteUnused();
private:
Q_DISABLE_COPY(SKGPayeePluginWidget)
Ui::skgpayeeplugin_base ui{};
};
#endif // SKGPAYEEPLUGINWIDGET_H
diff --git a/plugins/skrooge/skrooge_report/CMakeLists.txt b/plugins/skrooge/skrooge_report/CMakeLists.txt
index 905f164c9..f0967bcf8 100644
--- a/plugins/skrooge/skrooge_report/CMakeLists.txt
+++ b/plugins/skrooge/skrooge_report/CMakeLists.txt
@@ -1,47 +1,47 @@
#***************************************************************************
#* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
#* *
#* 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 <http://www.gnu.org/licenses/> *
+#* along with this program. If not, see <https://www.gnu.org/licenses/> *
#***************************************************************************
MESSAGE( STATUS "..:: CMAKE PLUGIN_REPORT ::..")
PROJECT(plugin_report)
IF(SKG_BUILD_TEST AND NOT WIN32)
ADD_SUBDIRECTORY(tests)
ENDIF(SKG_BUILD_TEST AND NOT WIN32)
IF(SKG_WEBENGINE)
MESSAGE( STATUS " Mode WebEngine")
ADD_DEFINITIONS(-DSKG_WEBENGINE=${SKG_WEBENGINE})
ENDIF(SKG_WEBENGINE)
LINK_DIRECTORIES (${LIBRARY_OUTPUT_PATH})
SET(skrooge_report_SRCS
skgreportplugin.cpp
skgreportpluginwidget.cpp
skgreportboardwidget.cpp)
ki18n_wrap_ui(skrooge_report_SRCS skgreportpluginwidget_base.ui skgreportpluginwidget_pref.ui)
kconfig_add_kcfg_files(skrooge_report_SRCS skgreport_settings.kcfgc )
ADD_LIBRARY(skrooge_report MODULE ${skrooge_report_SRCS})
TARGET_LINK_LIBRARIES(skrooge_report KF5::Parts skgbasemodeler skgbasegui skgbankmodeler skgbankgui)
########### install files ###############
INSTALL(TARGETS skrooge_report DESTINATION ${KDE_INSTALL_QTPLUGINDIR})
INSTALL(FILES ${PROJECT_SOURCE_DIR}/org.kde.skrooge-plugin-report.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR})
INSTALL(FILES ${PROJECT_SOURCE_DIR}/skrooge_report.rc DESTINATION ${KDE_INSTALL_KXMLGUI5DIR}/skrooge_report )
INSTALL(FILES ${PROJECT_SOURCE_DIR}/skgreport_settings.kcfg DESTINATION ${KDE_INSTALL_KCFGDIR} )
diff --git a/plugins/skrooge/skrooge_report/org.kde.skrooge-plugin-report.desktop b/plugins/skrooge/skrooge_report/org.kde.skrooge-plugin-report.desktop
index 6fa09750d..fa501a5f1 100644
--- a/plugins/skrooge/skrooge_report/org.kde.skrooge-plugin-report.desktop
+++ b/plugins/skrooge/skrooge_report/org.kde.skrooge-plugin-report.desktop
@@ -1,76 +1,76 @@
[Desktop Entry]
Name=Skrooge report plugin
Name[bs]=Skrooge dodatak za izvještaje
Name[ca]=Connector d'informe de l'Skrooge
Name[ca@valencia]=Connector d'informe de l'Skrooge
Name[cs]=Modul hlášení pro Skrooge
Name[da]=Rapport-plugin til Skrooge
Name[de]=Skrooge-Berichtmodul
Name[el]=Skrooge report plugin
Name[en_GB]=Skrooge report plugin
Name[es]=Complemento de informes de Skrooge
Name[et]=Skrooge aruandeplugin
Name[fi]=Skroogen raporttiliitännäinen
Name[fr]=Module externe Skrooge de rapport
Name[gl]=Complemento de informes de Skrooge
Name[hu]=Skrooge jelentés bővítmény
Name[it]=Estensione per rapporti di Skrooge
Name[lt]=Skrooge ataskaitos papildinys
Name[nb]=Skrooge rapportmoduls
Name[nds]=Berichtmoduul för Skrooge
Name[nl]=Plugin voor Skrooge-rapporteren
Name[pl]=Wtyczka sprawozdania dla Skrooge
Name[pt]='Plugin' de relatórios do Skrooge
Name[pt_BR]=Plugin de relatório do Skrooge
Name[ru]=Модуль отчётов
Name[sk]=Plugin výkazov Skrooge
Name[sv]=Skrooge rapportinsticksprogram
Name[tr]=Skrooge rapor eklentisi
Name[uk]=Додаток звітів Skrooge
Name[x-test]=xxSkrooge report pluginxx
Name[zh_TW]=Skrooge 報表外掛程式。
Comment=A skrooge plugin to manage reports
Comment[bs]=Skrooge dodatak za upravljanje izvještajima
Comment[ca]=Un connector de l'Skrooge per gestionar informes
Comment[ca@valencia]=Un connector de l'Skrooge per gestionar informes
Comment[cs]=Modul Skrooge pro správu hlášení
Comment[da]=Et Skrooge-plugin til at håndtere rapporter
Comment[de]=Ein Skrooge-Modul zum Verwalten von Berichten
Comment[el]=Ένα πρόσθετο του skrooge για τη διαχείριση αναφορών
Comment[en_GB]=A skrooge plugin to manage reports
Comment[es]=Complemento de Skrooge para gestionar informes
Comment[et]=Skrooge aruannete haldamise plugin
Comment[fi]=Skroogen raportinhallintaliitännäinen
Comment[fr]=Un module externe de Skrooge pour la gestion des rapports
Comment[gl]=Un complemento de Skrooge para xestionar informes.
Comment[hu]=Egy Skrooge bővítmény jelentések kezeléséhez
Comment[it]=Un'estensione di Skrooge per gestire i rapporti
Comment[lt]=Skrooge ataskaitų tvarkymo papildinys
Comment[nb]=En Skrooge-modul for å håndtere rapporter
Comment[nds]=En Moduul för de Pleeg vun Berichten för Skrooge
Comment[nl]=Een skrooge-plugin voor het beheren van rapporten
Comment[pl]=Wtyczka Skrooge do obsługi sprawozdań
Comment[pt]=Um 'plugin' do Skrooge para gerir os relatórios
Comment[pt_BR]=Um plugin do Skrooge para gerenciar relatórios
Comment[ru]=Модуль для управления отчётами
Comment[sk]=Plugin Skrooge na správu výkazov
Comment[sv]=Ett insticksprogram till Skrooge för att hantera budgetar
Comment[tr]=Raporları yönetmek için bir Skrooge eklentisi
Comment[uk]=Додаток до skrooge для керування звітами
Comment[x-test]=xxA skrooge plugin to manage reportsxx
Comment[zh_TW]=管理報表用的 Skrooge 外掛程式
Encoding=UTF-8
Icon=skrooge
Type=Service
X-KDE-ServiceTypes=SKG GUI/Plugin
X-KDE-Library=skrooge_report
X-Krunner-ID=Skrooge report plugin
X-KDE-PluginInfo-Author=Stephane MANKOWSKI,miraks
X-KDE-PluginInfo-Email=stephane@mankowski.fr
X-KDE-PluginInfo-Name=skrooge_report
X-KDE-PluginInfo-Version=1.0
-X-KDE-PluginInfo-Website=http://skrooge.org/
+X-KDE-PluginInfo-Website=https://skrooge.org/
X-KDE-PluginInfo-Category=Plugins
X-KDE-PluginInfo-Depends=
X-KDE-PluginInfo-License=GPL
X-KDE-PluginInfo-EnabledByDefault=true
diff --git a/plugins/skrooge/skrooge_report/skgreportboardwidget.cpp b/plugins/skrooge/skrooge_report/skgreportboardwidget.cpp
index ed5c372d5..bda7ad323 100644
--- a/plugins/skrooge/skrooge_report/skgreportboardwidget.cpp
+++ b/plugins/skrooge/skrooge_report/skgreportboardwidget.cpp
@@ -1,133 +1,133 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is Skrooge plugin for bank management.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgreportboardwidget.h"
#include "skgdocumentbank.h"
#include "skgmainpanel.h"
#include "skgreportpluginwidget.h"
#include "skgtraces.h"
SKGReportBoardWidget::SKGReportBoardWidget(QWidget* iParent, SKGDocumentBank* iDocument)
: SKGBoardWidget(iParent, iDocument, i18nc("Dashboard widget title", "Report"), true)
{
SKGTRACEINFUNC(10)
// This must be done at the beginning
this->setMinimumSize(200, 200);
// Create menu
setContextMenuPolicy(Qt::ActionsContextMenu);
QStringList overlayopen;
overlayopen.push_back(QStringLiteral("quickopen"));
auto open = new QAction(SKGServices::fromTheme(QStringLiteral("view-statistics"), overlayopen), i18nc("Verb", "Open report..."), this);
connect(open, &QAction::triggered, this, &SKGReportBoardWidget::onOpen);
addAction(open);
m_graph = new SKGReportPluginWidget(iParent, iDocument, true);
setMainWidget(m_graph);
// Refresh
connect(getDocument(), &SKGDocument::tableModified, this, &SKGReportBoardWidget::dataModified, Qt::QueuedConnection);
}
SKGReportBoardWidget::~SKGReportBoardWidget()
{
SKGTRACEINFUNC(10)
m_graph = nullptr;
}
QString SKGReportBoardWidget::getState()
{
QDomDocument doc(QStringLiteral("SKGML"));
doc.setContent(SKGBoardWidget::getState());
QDomElement root = doc.documentElement();
if (m_graph != nullptr) {
root.setAttribute(QStringLiteral("graph"), m_graph->getState());
}
return doc.toString();
}
void SKGReportBoardWidget::setState(const QString& iState)
{
SKGBoardWidget::setState(iState);
QDomDocument doc(QStringLiteral("SKGML"));
if (doc.setContent(iState)) {
QDomElement root = doc.documentElement();
QString title = root.attribute(QStringLiteral("title"));
if (!title.isEmpty()) {
setMainTitle(title);
}
QString graphS = root.attribute(QStringLiteral("graph"));
if (m_graph != nullptr) {
if (graphS.isEmpty()) {
m_graph->setState(iState);
} else {
m_graph->setState(graphS);
}
}
}
dataModified(QLatin1String(""), 0);
}
void SKGReportBoardWidget::dataModified(const QString& iTableName, int iIdTransaction)
{
SKGTRACEINFUNC(10)
Q_UNUSED(iIdTransaction)
if (iTableName == QStringLiteral("operation") || iTableName.isEmpty()) {
bool exist = false;
getDocument()->existObjects(QStringLiteral("account"), QLatin1String(""), exist);
if (parentWidget() != nullptr) {
setVisible(exist);
}
}
}
void SKGReportBoardWidget::onOpen()
{
QDomDocument doc(QStringLiteral("SKGML"));
QString graphS;
if (doc.setContent(getState())) {
QDomElement root = doc.documentElement();
graphS = root.attribute(QStringLiteral("graph"));
QDomDocument doc2(QStringLiteral("SKGML"));
if (doc2.setContent(graphS)) {
QDomElement root2 = doc2.documentElement();
QString currentPage = root2.attribute(QStringLiteral("currentPage"));
if (SKGServices::stringToInt(currentPage) < -1) {
root2.setAttribute(QStringLiteral("currentPage"), QStringLiteral("-1"));
graphS = doc2.toString();
}
}
}
SKGMainPanel::getMainPanel()->openPage(SKGMainPanel::getMainPanel()->getPluginByName(QStringLiteral("Skrooge report plugin")), -1, graphS);
}
diff --git a/plugins/skrooge/skrooge_report/skgreportboardwidget.h b/plugins/skrooge/skrooge_report/skgreportboardwidget.h
index ce117d884..eb63a9efd 100644
--- a/plugins/skrooge/skrooge_report/skgreportboardwidget.h
+++ b/plugins/skrooge/skrooge_report/skgreportboardwidget.h
@@ -1,75 +1,75 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGREPORTBOARDWIDGET_H
#define SKGREPORTBOARDWIDGET_H
/** @file
* This file is Skrooge plugin for bank management.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgboardwidget.h"
class SKGReportPluginWidget;
class SKGDocumentBank;
class QAction;
/**
* This file is Skrooge plugin for bank management
*/
class SKGReportBoardWidget : public SKGBoardWidget
{
Q_OBJECT
public:
/**
* Default Constructor
* @param iParent the parent widget
* @param iDocument the document
*/
explicit SKGReportBoardWidget(QWidget* iParent, SKGDocumentBank* iDocument);
/**
* Default Destructor
*/
~SKGReportBoardWidget() override;
/**
* Get the current state
* MUST BE OVERWRITTEN
* @return a string containing all information needed to set the same state.
* Could be an XML stream
*/
QString getState() override;
/**
* Set the current state
* MUST BE OVERWRITTEN
* @param iState must be interpreted to set the state of the widget
*/
void setState(const QString& iState) override;
private Q_SLOTS:
void dataModified(const QString& iTableName, int iIdTransaction);
void onOpen();
private:
Q_DISABLE_COPY(SKGReportBoardWidget)
SKGReportPluginWidget* m_graph;
};
#endif // SKGREPORTBOARDWIDGET_H
diff --git a/plugins/skrooge/skrooge_report/skgreportplugin.cpp b/plugins/skrooge/skrooge_report/skgreportplugin.cpp
index 694a69d61..6b74da354 100644
--- a/plugins/skrooge/skrooge_report/skgreportplugin.cpp
+++ b/plugins/skrooge/skrooge_report/skgreportplugin.cpp
@@ -1,404 +1,404 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is Skrooge plugin to generate report.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgreportplugin.h"
#include <kaboutdata.h>
#include <kactioncollection.h>
#include <kpluginfactory.h>
#include <qaction.h>
#include <qdom.h>
#include "skgaccountobject.h"
#include "skgcategoryobject.h"
#include "skgdocumentbank.h"
#include "skghtmlboardwidget.h"
#include "skgmainpanel.h"
#include "skgnodeobject.h"
#include "skgpayeeobject.h"
#include "skgreport_settings.h"
#include "skgreportboardwidget.h"
#include "skgreportpluginwidget.h"
#include "skgruleobject.h"
#include "skgservices.h"
#include "skgtraces.h"
#include "skgtrackerobject.h"
#include "skgunitobject.h"
/**
* This plugin factory.
*/
K_PLUGIN_FACTORY(SKGReportPluginFactory, registerPlugin<SKGReportPlugin>();)
SKGReportPlugin::SKGReportPlugin(QWidget* iWidget, QObject* iParent, const QVariantList& /*iArg*/) :
SKGInterfacePlugin(iParent), m_currentBankDocument(nullptr)
{
Q_UNUSED(iWidget)
SKGTRACEINFUNC(10)
}
SKGReportPlugin::~SKGReportPlugin()
{
SKGTRACEINFUNC(10)
m_currentBankDocument = nullptr;
}
bool SKGReportPlugin::setupActions(SKGDocument* iDocument)
{
SKGTRACEINFUNC(10)
m_currentBankDocument = qobject_cast<SKGDocumentBank*>(iDocument);
if (m_currentBankDocument == nullptr) {
return false;
}
setComponentName(QStringLiteral("skrooge_report"), title());
setXMLFile(QStringLiteral("skrooge_report.rc"));
// Menu
QStringList overlayopen;
overlayopen.push_back(QStringLiteral("quickopen"));
auto actOpenReport = new QAction(SKGServices::fromTheme(QStringLiteral("view-statistics"), overlayopen), i18nc("Verb", "Open report..."), this);
connect(actOpenReport, &QAction::triggered, this, &SKGReportPlugin::onOpenReport);
actionCollection()->setDefaultShortcut(actOpenReport, Qt::META + Qt::Key_R);
registerGlobalAction(QStringLiteral("open_report"), actOpenReport,
QStringList() << QStringLiteral("operation") << QStringLiteral("suboperation") << QStringLiteral("account") << QStringLiteral("unit") << QStringLiteral("category") << QStringLiteral("refund") << QStringLiteral("payee") << QStringLiteral("rule"), 1, -1, 120);
// ---------------
{
auto act = new QAction(SKGServices::fromTheme(QStringLiteral("security-low"), overlayopen), i18nc("Verb", "Open very old operations..."), this);
act->setData(QString("skg://skrooge_operation_plugin/?title_icon=security-low&title=" %
SKGServices::encodeForUrl(i18nc("Noun, a list of items", "Very old operations")) %
"&operationWhereClause=" % SKGServices::encodeForUrl(QStringLiteral("d_date<=(SELECT date('now', '-50 year')) AND d_date<>'0000-00-00'"))));
connect(act, &QAction::triggered, SKGMainPanel::getMainPanel(), [ = ]() {
SKGMainPanel::getMainPanel()->openPage();
});
registerGlobalAction(QStringLiteral("view_open_very_old_operations"), act);
}
// ---------------
{
auto act = new QAction(SKGServices::fromTheme(QStringLiteral("security-low"), overlayopen), i18nc("Verb", "Open very far operations in the future..."), this);
act->setData(QString("skg://skrooge_operation_plugin/?title_icon=security-low&title=" %
SKGServices::encodeForUrl(i18nc("Noun, a list of items", "Very far operations in the future")) %
"&operationWhereClause=" % SKGServices::encodeForUrl(QStringLiteral("d_date>=(SELECT date('now', '+50 year'))"))));
connect(act, &QAction::triggered, SKGMainPanel::getMainPanel(), [ = ]() {
SKGMainPanel::getMainPanel()->openPage();
});
registerGlobalAction(QStringLiteral("view_open_very_far_operations"), act);
}
return true;
}
int SKGReportPlugin::getNbDashboardWidgets()
{
// Count the number of bookmark on reports
int nb = 0;
m_currentBankDocument->getNbObjects(QStringLiteral("node"), QStringLiteral("t_data like '\"Skrooge report plugin\";%' "), nb);
return 2 + nb;
}
QString SKGReportPlugin::getDashboardWidgetTitle(int iIndex)
{
Q_UNUSED(iIndex)
if (iIndex == 0) {
return i18nc("Noun, the title of a section", "Report");
}
if (iIndex == 1) {
return i18nc("Noun, the title of a section", "Personal Financial Score");
}
SKGObjectBase::SKGListSKGObjectBase objs;
m_currentBankDocument->getObjects(QStringLiteral("node"), QStringLiteral("t_data like '\"Skrooge report plugin\";%' ORDER BY t_fullname"), objs);
if (iIndex - 2 < objs.count()) {
return i18nc("Noun, the title of a section", "Report bookmarked named \"%1\"", objs[iIndex - 2].getAttribute(QStringLiteral("t_fullname")));
}
return QLatin1String("");
}
SKGBoardWidget* SKGReportPlugin::getDashboardWidget(int iIndex)
{
Q_UNUSED(iIndex)
if (iIndex == 0) {
return new SKGReportBoardWidget(SKGMainPanel::getMainPanel(), m_currentBankDocument);
}
if (iIndex == 1) {
// Get QML mode for dashboard
KConfigSkeleton* skl = SKGMainPanel::getMainPanel()->getPluginByName(QStringLiteral("Dashboard plugin"))->getPreferenceSkeleton();
KConfigSkeletonItem* sklItem = skl->findItem(QStringLiteral("qmlmode"));
bool qml = sklItem->property().toBool();
return new SKGHtmlBoardWidget(SKGMainPanel::getMainPanel(), m_currentBankDocument,
getDashboardWidgetTitle(iIndex) % " - %1",
QStandardPaths::locate(QStandardPaths::GenericDataLocation, QStringLiteral("skrooge/html/default/personal_finance_score.") % (qml ? QStringLiteral("qml") : QStringLiteral("html"))),
QStringList() << QStringLiteral("v_suboperation_consolidated"), SKGSimplePeriodEdit::PREVIOUS_MONTHS);
}
SKGObjectBase::SKGListSKGObjectBase objs;
m_currentBankDocument->getObjects(QStringLiteral("node"), QStringLiteral("t_data like '\"Skrooge report plugin\";%' ORDER BY t_fullname"), objs);
if (iIndex - 2 < objs.count()) {
auto* report = new SKGReportBoardWidget(SKGMainPanel::getMainPanel(), m_currentBankDocument);
QString state = SKGServices::splitCSVLine(objs.at(iIndex - 2).getAttribute(QStringLiteral("t_data"))).at(2);
state = state.replace(QStringLiteral("isToolBarVisible=&amp;quot;Y&amp;quot;"), QStringLiteral("isToolBarVisible=&amp;quot;N&amp;quot;"));
state = state.replace(QStringLiteral("show=&quot;&amp;quot;table&amp;quot;;&amp;quot;graph&amp;quot;&quot;"), QStringLiteral("show=&quot;&amp;quot;graph&amp;quot;&quot;"));
state = state.replace(QStringLiteral("currentPage=\"0\""), QStringLiteral("currentPage=\"-1\""));
report->setState(state);
return report;
}
return nullptr;
}
SKGTabPage* SKGReportPlugin::getWidget()
{
SKGTRACEINFUNC(10)
return new SKGReportPluginWidget(SKGMainPanel::getMainPanel(), m_currentBankDocument);
}
QWidget* SKGReportPlugin::getPreferenceWidget()
{
SKGTRACEINFUNC(10)
auto w = new QWidget();
ui.setupUi(w);
return w;
}
KConfigSkeleton* SKGReportPlugin::getPreferenceSkeleton()
{
return skgreport_settings::self();
}
QString SKGReportPlugin::title() const
{
return i18nc("Noun", "Report");
}
QString SKGReportPlugin::icon() const
{
return QStringLiteral("view-statistics");
}
QString SKGReportPlugin::toolTip() const
{
return i18nc("Noun", "Generate report");
}
int SKGReportPlugin::getOrder() const
{
return 40;
}
QStringList SKGReportPlugin::tips() const
{
QStringList output;
output.push_back(i18nc("Description of a tips", "<p>... you can double click on a value in <a href=\"skg://skrooge_report_plugin\">reports</a> to show corresponding operations.</p>"));
output.push_back(i18nc("Description of a tips", "<p>... you can open <a href=\"skg://skrooge_report_plugin\">reports</a> for selections made in other pages.</p>"));
output.push_back(i18nc("Description of a tips", "<p>... you can export <a href=\"skg://skrooge_report_plugin\">reports</a> in many formats.</p>"));
return output;
}
bool SKGReportPlugin::isInPagesChooser() const
{
return true;
}
void SKGReportPlugin::getTitleAndWhereClause(const SKGObjectBase::SKGListSKGObjectBase& iSelection, QString& oTitle, QString& oWhereClause) const
{
int nb = iSelection.count();
if (nb > 0) {
QString table = iSelection.at(0).getRealTable();
if (table == QStringLiteral("account")) {
oWhereClause = QStringLiteral("rd_account_id in (");
oTitle = i18nc("Noun, a list of items", "Operations of account ");
for (int i = 0; i < nb; ++i) {
SKGAccountObject tmp(iSelection.at(i));
if (i != 0) {
oWhereClause += ',';
oTitle += ',';
}
oWhereClause += SKGServices::intToString(tmp.getID());
oTitle += i18n("'%1'", tmp.getName());
}
oWhereClause += ')';
} else if (table == QStringLiteral("unit")) {
oWhereClause = QStringLiteral("rc_unit_id in (");
oTitle = i18nc("Noun, a list of items", "Operations with Unit equal to ");
for (int i = 0; i < nb; ++i) {
SKGUnitObject tmp(iSelection.at(i));
if (i != 0) {
oWhereClause += ',';
oTitle += ',';
}
oWhereClause += SKGServices::intToString(tmp.getID());
oTitle += i18n("'%1'", tmp.getName());
}
oWhereClause += ')';
} else if (table == QStringLiteral("category")) {
oWhereClause = QStringLiteral("t_REALCATEGORY in (");
QString wc2;
oTitle = i18nc("Noun, a list of items", "Operations with Category equal to ");
for (int i = 0; i < nb; ++i) {
SKGCategoryObject tmp(iSelection.at(i));
if (i != 0) {
oWhereClause += ',';
wc2 += QStringLiteral(" OR ");
oTitle += ',';
}
oWhereClause += '\'' % SKGServices::stringToSqlString(tmp.getFullName()) % '\'';
wc2 += "t_REALCATEGORY like '" % SKGServices::stringToSqlString(tmp.getFullName()) % "%'";
oTitle += i18n("'%1'", tmp.getFullName());
}
oWhereClause += ") OR " % wc2;
} else if (table == QStringLiteral("refund")) {
oWhereClause = QStringLiteral("r_refund_id in (");
oTitle = i18nc("Noun, a list of items", "Operations followed by ");
for (int i = 0; i < nb; ++i) {
SKGTrackerObject tmp(iSelection.at(i));
if (i != 0) {
oWhereClause += ',';
oTitle += ',';
}
oWhereClause += SKGServices::intToString(tmp.getID());
oTitle += i18n("'%1'", tmp.getName());
}
oWhereClause += ')';
} else if (table == QStringLiteral("payee")) {
oWhereClause = QStringLiteral("r_payee_id in (");
oTitle = i18nc("Noun, a list of items", "Operations assigned to ");
for (int i = 0; i < nb; ++i) {
SKGPayeeObject tmp(iSelection.at(i));
if (i != 0) {
oWhereClause += ',';
oTitle += ',';
}
oWhereClause += SKGServices::intToString(tmp.getID());
oTitle += i18n("'%1'", tmp.getName());
}
oWhereClause += ')';
} else if (table == QStringLiteral("operation")) {
oWhereClause = QStringLiteral("i_OPID in (");
oTitle = i18nc("Noun, a list of items", "Selected operations");
for (int i = 0; i < nb; ++i) {
if (i != 0) {
oWhereClause += ',';
}
oWhereClause += SKGServices::intToString(iSelection.at(i).getID());
}
oWhereClause += ')';
} else if (table == QStringLiteral("suboperation")) {
oWhereClause = QStringLiteral("i_SUBOPID in (");
oTitle = i18nc("Noun, a list of items", "Selected sub operations");
for (int i = 0; i < nb; ++i) {
if (i != 0) {
oWhereClause += ',';
}
oWhereClause += SKGServices::intToString(iSelection.at(i).getID());
}
oWhereClause += ')';
} else if (table == QStringLiteral("rule")) {
oTitle = i18nc("Noun, a list of items", "Operations corresponding to rule ");
for (int i = 0; i < nb; ++i) {
SKGRuleObject tmp(iSelection.at(i));
QString ruleWc = tmp.getSelectSqlOrder();
if (!ruleWc.isEmpty()) {
if (!oWhereClause.isEmpty()) {
oWhereClause += QStringLiteral(" OR ");
oTitle += ',';
}
oWhereClause += '(' % ruleWc % ')';
oTitle += i18n("'%1'", tmp.getSearchDescription());
}
}
}
}
}
void SKGReportPlugin::onOpenReport()
{
SKGError err;
SKGTRACEINFUNCRC(10, err)
if (SKGMainPanel::getMainPanel() != nullptr) {
SKGObjectBase::SKGListSKGObjectBase selection = SKGMainPanel::getMainPanel()->getSelectedObjects();
int nb = selection.count();
if (nb > 0) {
QString titleTable;
QString wc;
getTitleAndWhereClause(selection, titleTable, wc);
// Call report plugin
SKGMainPanel::getMainPanel()->openPage("skg://skrooge_report_plugin/?period=0&title_icon=" % icon() % "&title=" % SKGServices::encodeForUrl(titleTable) % "&operationWhereClause=" % SKGServices::encodeForUrl(wc));
}
}
}
SKGAdviceList SKGReportPlugin::advice(const QStringList& iIgnoredAdvice)
{
SKGTRACEINFUNC(10)
SKGAdviceList output;
// Very old operation
if (!iIgnoredAdvice.contains(QStringLiteral("skgreportplugin_veryold"))) {
bool exist = false;
m_currentBankDocument->existObjects(QStringLiteral("operation"), QStringLiteral("d_date<=(SELECT date('now', '-50 year')) AND d_date<>'0000-00-00'"), exist);
if (exist) {
SKGAdvice ad;
ad.setUUID(QStringLiteral("skgreportplugin_veryold"));
ad.setPriority(3);
ad.setShortMessage(i18nc("Advice on making the best (short)", "Some operations are very old"));
ad.setLongMessage(i18nc("Advice on making the best (long)", "For performances reasons, very old operations are not taken into account in graph report. Check if these operations are normal."));
QStringList autoCorrections;
autoCorrections.push_back(QStringLiteral("skg://view_open_very_old_operations"));
ad.setAutoCorrections(autoCorrections);
output.push_back(ad);
}
}
// Very far operation
if (!iIgnoredAdvice.contains(QStringLiteral("skgreportplugin_veryfar"))) {
bool exist = false;
m_currentBankDocument->existObjects(QStringLiteral("operation"), QStringLiteral("d_date>=(SELECT date('now', '+50 year'))"), exist);
if (exist) {
SKGAdvice ad;
ad.setUUID(QStringLiteral("skgreportplugin_veryfar"));
ad.setPriority(3);
ad.setShortMessage(i18nc("Advice on making the best (short)", "Some operations are very far in the future"));
ad.setLongMessage(i18nc("Advice on making the best (long)", "For performances reasons, operations very far in the future are not taken into account in graph report. Check if these operations are normal."));
QStringList autoCorrections;
autoCorrections.push_back(QStringLiteral("skg://view_open_very_far_operations"));
ad.setAutoCorrections(autoCorrections);
output.push_back(ad);
}
}
return output;
}
#include <skgreportplugin.moc>
diff --git a/plugins/skrooge/skrooge_report/skgreportplugin.h b/plugins/skrooge/skrooge_report/skgreportplugin.h
index 8944e8590..232bec0a8 100644
--- a/plugins/skrooge/skrooge_report/skgreportplugin.h
+++ b/plugins/skrooge/skrooge_report/skgreportplugin.h
@@ -1,155 +1,155 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGREPORTPLUGIN_H
#define SKGREPORTPLUGIN_H
/** @file
* This file is Skrooge plugin to generate report.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skginterfaceplugin.h"
#include "ui_skgreportpluginwidget_pref.h"
class SKGDocumentBank;
/**
* This file is Skrooge plugin to generate report
*/
class SKGReportPlugin : public SKGInterfacePlugin
{
Q_OBJECT
Q_INTERFACES(SKGInterfacePlugin)
public:
/**
* Default Constructor
*/
explicit SKGReportPlugin(QWidget* iWidget, QObject* iParent, const QVariantList& iArg);
/**
* Default Destructor
*/
~SKGReportPlugin() override;
/**
* Called to initialise the plugin
* @param iDocument the main document
* @return true if the plugin is compatible with the document
*/
bool setupActions(SKGDocument* iDocument) override;
/**
* The number of dashboard widgets of the plugin.
* @return The number of dashboard widgets of the plugin
*/
int getNbDashboardWidgets() override;
/**
* Get a dashboard widget title of the plugin.
* @param iIndex the index of the widget
* @return The title
*/
QString getDashboardWidgetTitle(int iIndex) override;
/**
* Get a dashboard widget of the plugin.
* @param iIndex the index of the widget
* @return The dashboard widget of the plugin
*/
SKGBoardWidget* getDashboardWidget(int iIndex) override;
/**
* The preference widget of the plugin.
* @return The preference widget of the plugin
*/
QWidget* getPreferenceWidget() override;
/**
* The preference skeleton of the plugin.
* @return The preference skeleton of the plugin
*/
KConfigSkeleton* getPreferenceSkeleton() override;
/**
* The page widget of the plugin.
* @return The page widget of the plugin
*/
SKGTabPage* getWidget() override;
/**
* The title of the plugin.
* @return The title of the plugin
*/
QString title() const override;
/**
* The icon of the plugin.
* @return The icon of the plugin
*/
QString icon() const override;
/**
* The toolTip of the plugin.
* @return The toolTip of the plugin
*/
QString toolTip() const override;
/**
* The tips list of the plugin.
* @return The tips list of the plugin
*/
QStringList tips() const override;
/**
* Must be implemented to set the position of the plugin.
* @return integer value between 0 and 999 (default = 999)
*/
int getOrder() const override;
/**
* Must be implemented to know if a plugin must be display in pages chooser.
* @return true of false (default = false)
*/
bool isInPagesChooser() const override;
/**
* The advice list of the plugin.
* @return The advice list of the plugin
*/
SKGAdviceList advice(const QStringList& iIgnoredAdvice) override;
/**
* Get the title and where clause from a selection
* @param iSelection the selection
* @param oTitle the title
* @param oWhereClause the where clause
*/
virtual void getTitleAndWhereClause(const SKGObjectBase::SKGListSKGObjectBase& iSelection, QString& oTitle, QString& oWhereClause) const;
private Q_SLOTS:
void onOpenReport();
private:
Q_DISABLE_COPY(SKGReportPlugin)
SKGDocumentBank* m_currentBankDocument;
Ui::skgreportplugin_pref ui{};
};
#endif // SKGREPORTPLUGIN_H
diff --git a/plugins/skrooge/skrooge_report/skgreportpluginwidget.cpp b/plugins/skrooge/skrooge_report/skgreportpluginwidget.cpp
index 7f1f8452d..df4141050 100644
--- a/plugins/skrooge/skrooge_report/skgreportpluginwidget.cpp
+++ b/plugins/skrooge/skrooge_report/skgreportpluginwidget.cpp
@@ -1,1468 +1,1468 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is Skrooge plugin to generate report.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgreportpluginwidget.h"
#include <klocalizedstring.h>
#include <qgraphicsscene.h>
#include <qlistwidget.h>
#include <qmenu.h>
#include <qwidgetaction.h>
#include "skgbankincludes.h"
#include "skgcolorbutton.h"
#include "skgmainpanel.h"
#include "skgreport_settings.h"
#include "skgreportplugin.h"
#include "skgtraces.h"
/**
* The size of the forecast
*/
static const int FORECASTMAX = 100;
SKGReportPluginWidget::SKGReportPluginWidget(QWidget* iParent, SKGDocumentBank* iDocument, bool iMinimmumMode)
: SKGTabPage(iParent, iDocument), m_openReportAction(nullptr), m_openAction(nullptr), m_mode(0), m_nbLevelLines(0), m_nbLevelColumns(0), m_refreshNeeded(true)
{
SKGTRACEINFUNC(10)
if (iDocument == nullptr) {
return;
}
m_timer.setSingleShot(true);
connect(&m_timer, &QTimer::timeout, this, [ = ]() {
this->dataModified();
}, Qt::QueuedConnection);
ui.setupUi(this);
ui.kCorrectedBy->setDocument(iDocument);
ui.kCorrectedBy->setCurrentIndex(0);
ui.kCorrectedBy->setWhereClauseCondition(QStringLiteral("t_type='I'"));
ui.kCorrectedByMode->addItem(QStringLiteral("x"));
ui.kCorrectedByMode->addItem(QStringLiteral("/"));
ui.kLineLabel->setText(QLatin1String(""));
ui.kLineUp->setIcon(SKGServices::fromTheme(QStringLiteral("format-indent-more")));
ui.kLineDown->setIcon(SKGServices::fromTheme(QStringLiteral("format-indent-less")));
ui.kColUp->setIcon(SKGServices::fromTheme(QStringLiteral("format-indent-more")));
ui.kColDown->setIcon(SKGServices::fromTheme(QStringLiteral("format-indent-less")));
ui.kLineAdd->setIcon(SKGServices::fromTheme(QStringLiteral("arrow-right")));
ui.kLineRemove->setIcon(SKGServices::fromTheme(QStringLiteral("edit-delete")));
ui.kMode->addItem(SKGServices::fromTheme(QStringLiteral("office-chart-line")), i18nc("Display graph values as the sum of operations amount", "Sum of operations"), 0);
ui.kMode->addItem(SKGServices::fromTheme(QStringLiteral("office-chart-line-stacked")), i18nc("Display graph values as the cumulated sum of operations amount", "Cumulated sum of operations"), 1);
ui.kMode->addItem(SKGServices::fromTheme(QStringLiteral("office-chart-bar-percentage")), i18nc("Display graph values in base 100", "Base 100"), 7);
ui.kMode->addItem(SKGServices::fromTheme(QStringLiteral("office-chart-bar-percentage")), i18nc("Display graph values in base 100", "Cumulated sum in base 100"), 8);
ui.kMode->addItem(SKGServices::fromTheme(QStringLiteral("office-chart-area")), i18nc("Display graph values in percentage", "Percent of columns"), 2);
ui.kMode->addItem(SKGServices::fromTheme(QStringLiteral("office-chart-area")), i18nc("Display graph values in percentage", "Absolute percent of columns"), 5);
ui.kMode->addItem(SKGServices::fromTheme(QStringLiteral("office-chart-line")), i18nc("Display graph values in percentage", "Percent of lines"), 4);
ui.kMode->addItem(SKGServices::fromTheme(QStringLiteral("office-chart-line")), i18nc("Display graph values in percentage", "Absolute percent of lines"), 6);
ui.kMode->addItem(SKGServices::fromTheme(QStringLiteral("irc-operator")), i18nc("Display graph values as a number of operations (or transaction)", "Count number of operations"), 3);
ui.kForecastCmb->addItem(i18nc("Noun", "None"), 0);
ui.kForecastCmb->addItem(SKGServices::fromTheme(QStringLiteral("download-later")), i18nc("Noun", "Moving average"), 2);
ui.kForecastCmb->addItem(SKGServices::fromTheme(QStringLiteral("download-later")), i18nc("Noun", "Weighted moving average"), 3);
// TODO(Stephane MANKOWSKI): ui.kForecastCmb->addItem(SKGServices::fromTheme("applications-education-mathematics"), i18nc("Noun", "Interest rate") , 5);
ui.kForecastCmb->addItem(SKGServices::fromTheme(QStringLiteral("chronometer")), i18nc("Noun", "Schedule"), 1);
ui.kForecastCmb->addItem(SKGServices::fromTheme(QStringLiteral("view-calendar-whatsnext")), i18nc("Noun", "Budget"), 4);
ui.kWidgetSelector->addButton(SKGServices::fromTheme(QStringLiteral("configure")), i18n("Setup Report"), i18n("Display the edit panel for report"), ui.setupWidget);
connect(ui.kWidgetSelector, &SKGWidgetSelector::selectedModeChanged, this, &SKGReportPluginWidget::onBtnModeClicked);
// Set colors
setSettings();
if (SKGMainPanel::getMainPanel() != nullptr) {
connect(SKGMainPanel::getMainPanel(), &SKGMainPanel::settingsChanged, this, &SKGReportPluginWidget::setSettings);
}
// Build contextual menu
QMenu* tableMenu = ui.kTableWithGraph->getTableContextualMenu();
if (tableMenu != nullptr) {
tableMenu->addSeparator();
m_openAction = tableMenu->addAction(SKGServices::fromTheme(QStringLiteral("quickopen")), i18nc("Verb", "Open..."));
if (m_openAction != nullptr) {
m_openAction->setEnabled(false);
}
QStringList overlayopen;
overlayopen.push_back(QStringLiteral("quickopen"));
m_openReportAction = tableMenu->addAction(SKGServices::fromTheme(QStringLiteral("view-statistics"), overlayopen), i18nc("Verb", "Open report..."));
if (m_openReportAction != nullptr) {
m_openReportAction->setEnabled(false);
}
}
QMenu* graphMenu = ui.kTableWithGraph->getGraphContextualMenu();
if (iMinimmumMode && graphMenu != nullptr) {
graphMenu->addSeparator();
QList<QCheckBox*> list;
list << ui.kIncomes << ui.kExpenses << ui.kGrouped << ui.kTransfers << ui.kTracked;
for (auto actref : qAsConst(list)) {
auto act = graphMenu->addAction(actref->text());
if (act != nullptr) {
act->setCheckable(true);
act->setChecked(actref->isChecked());
connect(act, &QAction::triggered, actref, &QCheckBox::setChecked);
connect(actref, &QCheckBox::toggled, act, &QAction::setChecked);
}
}
graphMenu->addSeparator();
auto act = new QWidgetAction(this);
act->setDefaultWidget(ui.kColumns);
graphMenu->addAction(act);
graphMenu->addSeparator();
graphMenu->addAction(m_openAction);
graphMenu->addAction(m_openReportAction);
}
connect(m_openAction, &QAction::triggered, this, &SKGReportPluginWidget::onOpen);
connect(m_openReportAction, &QAction::triggered, this, &SKGReportPluginWidget::onOpenReport);
// Init comboboxes
m_attsForColumns << QStringLiteral("d_date") << QStringLiteral("d_DATEWEEK") << QStringLiteral("d_DATEMONTH") << QStringLiteral("d_DATEQUARTER") << QStringLiteral("d_DATESEMESTER") << QStringLiteral("d_DATEYEAR");
m_attsForLines << QStringLiteral("#NOTHING#") <<
QStringLiteral("t_BANK") << QStringLiteral("t_ACCOUNTTYPE") << QStringLiteral("t_ACCOUNT") << QStringLiteral("t_TOACCOUNT") <<
QStringLiteral("t_REALCATEGORY") <<
QStringLiteral("t_PAYEE") <<
QStringLiteral("t_TYPEEXPENSENLS") <<
QStringLiteral("t_mode") <<
QStringLiteral("t_status") <<
QStringLiteral("t_UNITTYPE") << QStringLiteral("t_UNIT") <<
QStringLiteral("t_REALREFUND") <<
QStringLiteral("t_TRANSFER");
// Adding properties of operations and sub operations
QStringList properties;
iDocument->getDistinctValues(QStringLiteral("parameters"), QStringLiteral("'p_'||t_name"), QStringLiteral("(t_uuid_parent like '%-operation' OR t_uuid_parent like '%-suboperation') AND t_name NOT LIKE 'SKG_%'"), properties);
int nb = properties.count();
m_attsForLines.reserve(m_attsForLines.count() + nb);
for (int i = 0; i < nb; ++i) {
m_attsForLines.push_back(properties.at(i));
}
// Adding properties of categories
iDocument->getDistinctValues(QStringLiteral("parameters"), '\'' + iDocument->getDisplay(QStringLiteral("t_category")) + ".p_'||t_name", QStringLiteral("t_uuid_parent like '%-category' AND t_name NOT LIKE 'SKG_%'"), properties);
nb = properties.count();
m_attsForLines.reserve(m_attsForLines.count() + nb);
for (int i = 0; i < nb; ++i) {
m_attsForLines.push_back(properties.at(i));
}
// Adding properties of accounts
iDocument->getDistinctValues(QStringLiteral("parameters"), '\'' + iDocument->getDisplay(QStringLiteral("t_account")) + ".p_'||t_name", QStringLiteral("t_uuid_parent like '%-account' AND t_name NOT LIKE 'SKG_%'"), properties);
nb = properties.count();
m_attsForLines.reserve(m_attsForLines.count() + nb);
for (int i = 0; i < nb; ++i) {
m_attsForLines.push_back(properties.at(i));
}
// Adding properties of payee
iDocument->getDistinctValues(QStringLiteral("parameters"), '\'' + iDocument->getDisplay(QStringLiteral("t_payee")) + ".p_'||t_name", QStringLiteral("t_uuid_parent like '%-payee' AND t_name NOT LIKE 'SKG_%'"), properties);
nb = properties.count();
m_attsForLines.reserve(m_attsForLines.count() + nb);
for (int i = 0; i < nb; ++i) {
m_attsForLines.push_back(properties.at(i));
}
// Adding properties of unit
iDocument->getDistinctValues(QStringLiteral("parameters"), '\'' + iDocument->getDisplay(QStringLiteral("t_unit")) + ".p_'||t_name", QStringLiteral("t_uuid_parent like '%-unit' AND t_name NOT LIKE 'SKG_%'"), properties);
nb = properties.count();
m_attsForLines.reserve(m_attsForLines.count() + nb);
for (int i = 0; i < nb; ++i) {
m_attsForLines.push_back(properties.at(i));
}
if (!iMinimmumMode) {
m_attsForColumns += m_attsForLines;
}
for (const auto& att : qAsConst(m_attsForColumns)) {
ui.kColumns->addItem(iDocument->getIcon(att), iDocument->getDisplay(att));
}
for (const auto& att : qAsConst(m_attsForLines)) {
ui.kLines->addItem(iDocument->getIcon(att), iDocument->getDisplay(att));
}
ui.kColumns->setCurrentIndex(2);
connect(ui.kTableWithGraph, &SKGTableWithGraph::selectionChanged, this, &SKGReportPluginWidget::onSelectionChanged);
// Refresh
connect(ui.kPeriod, &SKGPeriodEdit::changed, this, &SKGReportPluginWidget::refresh, Qt::QueuedConnection);
connect(ui.kColumns, static_cast<void (SKGComboBox::*)(const QString&)>(&SKGComboBox::currentTextChanged), this, &SKGReportPluginWidget::refresh, Qt::QueuedConnection);
connect(ui.kLines, static_cast<void (SKGComboBox::*)(const QString&)>(&SKGComboBox::currentTextChanged), this, &SKGReportPluginWidget::refresh, Qt::QueuedConnection);
connect(ui.kMode, static_cast<void (SKGComboBox::*)(const QString&)>(&SKGComboBox::currentTextChanged), this, &SKGReportPluginWidget::refresh, Qt::QueuedConnection);
connect(ui.kIncomes, &QCheckBox::stateChanged, this, &SKGReportPluginWidget::refresh, Qt::QueuedConnection);
connect(ui.kExpenses, &QCheckBox::stateChanged, this, &SKGReportPluginWidget::refresh, Qt::QueuedConnection);
connect(ui.kTransfers, &QCheckBox::stateChanged, this, &SKGReportPluginWidget::refresh, Qt::QueuedConnection);
connect(ui.kGrouped, &QCheckBox::stateChanged, this, &SKGReportPluginWidget::refresh, Qt::QueuedConnection);
connect(ui.kTracked, &QCheckBox::stateChanged, this, &SKGReportPluginWidget::refresh, Qt::QueuedConnection);
connect(ui.kForecastCmb, static_cast<void (SKGComboBox::*)(const QString&)>(&SKGComboBox::currentTextChanged), this, &SKGReportPluginWidget::refresh, Qt::QueuedConnection);
connect(ui.kForecastValue, static_cast<void (QSlider::*)(int)>(&QSlider::valueChanged), this, &SKGReportPluginWidget::refresh, Qt::QueuedConnection);
connect(ui.kCorrectedBy, static_cast<void (SKGUnitComboBox::*)(int)>(&SKGUnitComboBox::currentIndexChanged), this, &SKGReportPluginWidget::refresh, Qt::QueuedConnection);
connect(ui.kCorrectedByMode, static_cast<void (SKGComboBox::*)(const QString&)>(&SKGComboBox::currentTextChanged), this, &SKGReportPluginWidget::refresh, Qt::QueuedConnection);
connect(getDocument(), &SKGDocument::tableModified, this, &SKGReportPluginWidget::dataModified);
connect(SKGMainPanel::getMainPanel(), &SKGMainPanel::currentPageChanged, this, &SKGReportPluginWidget::pageChanged, Qt::QueuedConnection);
connect(SKGMainPanel::getMainPanel(), &SKGMainPanel::pageClosed, this, &SKGReportPluginWidget::pageChanged, Qt::QueuedConnection);
connect(ui.kOtherFilters, &QListWidget::itemChanged, this, &SKGReportPluginWidget::pageChanged, Qt::QueuedConnection);
connect(ui.kOtherFilters, &QListWidget::itemChanged, this, &SKGReportPluginWidget::refresh, Qt::QueuedConnection);
connect(ui.kTableWithGraph, &SKGTableWithGraph::cellDoubleClicked, this, &SKGReportPluginWidget::onDoubleClick);
connect(ui.kLineRemove, &QToolButton::clicked, this, &SKGReportPluginWidget::onRemoveLine);
connect(ui.kLineAdd, &QToolButton::clicked, this, &SKGReportPluginWidget::onAddLine);
connect(ui.kLineDown, &QToolButton::clicked, this, &SKGReportPluginWidget::onOneLevelLess);
connect(ui.kLineUp, &QToolButton::clicked, this, &SKGReportPluginWidget::onOneLevelMore);
connect(ui.kColDown, &QToolButton::clicked, this, &SKGReportPluginWidget::onOneLevelLess);
connect(ui.kColUp, &QToolButton::clicked, this, &SKGReportPluginWidget::onOneLevelMore);
connect(ui.kGrouped, &QCheckBox::toggled, ui.kTransfers, &QCheckBox::setEnabled);
if (iMinimmumMode) {
ui.kTableWithGraph->getShowWidget()->setState(QStringLiteral("\"graph\""));
ui.kWidgetSelector->setSelectedMode(-1);
} else {
ui.kWidgetSelector->setSelectedMode(0);
}
onBtnModeClicked(ui.kWidgetSelector->getSelectedMode());
}
SKGReportPluginWidget::~SKGReportPluginWidget()
{
SKGTRACEINFUNC(10)
m_openAction = nullptr;
m_openReportAction = nullptr;
}
QString SKGReportPluginWidget::getState()
{
SKGTRACEINFUNC(10)
QDomDocument doc(QStringLiteral("SKGML"));
QDomElement root = doc.createElement(QStringLiteral("parameters"));
doc.appendChild(root);
root.setAttribute(QStringLiteral("columns"), m_attsForColumns.value(ui.kColumns->currentIndex()));
QString lineString;
int nb = m_attsForLinesAdded.count();
for (int i = 0; i < nb; ++i) {
lineString += m_attsForLinesAdded.at(i);
if (i < nb - 1) {
lineString += OBJECTSEPARATOR;
}
}
root.setAttribute(QStringLiteral("lines"), lineString);
root.setAttribute(QStringLiteral("lines2"), m_attsForLines.value(ui.kLines->currentIndex()));
root.setAttribute(QStringLiteral("mode"), SKGServices::intToString(ui.kMode->itemData(ui.kMode->currentIndex()).toInt()));
root.setAttribute(QStringLiteral("periodDef"), ui.kPeriod->getState());
root.setAttribute(QStringLiteral("incomes"), ui.kIncomes->isChecked() ? QStringLiteral("Y") : QStringLiteral("N"));
root.setAttribute(QStringLiteral("expenses"), ui.kExpenses->isChecked() ? QStringLiteral("Y") : QStringLiteral("N"));
root.setAttribute(QStringLiteral("transfers"), ui.kTransfers->isChecked() ? QStringLiteral("Y") : QStringLiteral("N"));
root.setAttribute(QStringLiteral("grouped"), ui.kGrouped->isChecked() ? QStringLiteral("Y") : QStringLiteral("N"));
root.setAttribute(QStringLiteral("tracked"), ui.kTracked->isChecked() ? QStringLiteral("Y") : QStringLiteral("N"));
root.setAttribute(QStringLiteral("currentPage"), SKGServices::intToString(ui.kWidgetSelector->getSelectedMode()));
root.setAttribute(QStringLiteral("tableAndGraphState"), ui.kTableWithGraph->getState());
root.setAttribute(QStringLiteral("nbLevelLines"), SKGServices::intToString(m_nbLevelLines));
root.setAttribute(QStringLiteral("nbLevelColumns"), SKGServices::intToString(m_nbLevelColumns));
root.setAttribute(QStringLiteral("forecast"), SKGServices::intToString(ui.kForecastCmb->itemData(ui.kForecastCmb->currentIndex()).toInt()));
root.setAttribute(QStringLiteral("forecastValue"), SKGServices::intToString(ui.kForecastValue->value()));
root.setAttribute(QStringLiteral("zoomPosition"), SKGServices::intToString(zoomPosition()));
root.setAttribute(QStringLiteral("correctedby"), ui.kCorrectedBy->currentText());
root.setAttribute(QStringLiteral("correctedbymode"), ui.kCorrectedByMode->currentText());
// Addition of other filter
QString wc;
QString title = root.attribute(QStringLiteral("title"));
QString title_icon;
nb = ui.kOtherFilters->count();
for (int i = 0; i < nb; ++i) {
QListWidgetItem* item = ui.kOtherFilters->item(i);
if (item->checkState() == Qt::Checked) {
if (!wc.isEmpty()) {
wc = '(' % wc % ") AND (" % item->data(1000).toString() % ')';
} else {
wc = item->data(1000).toString();
}
title_icon = item->data(1001).toString();
title += item->text();
}
}
if (!wc.isEmpty()) {
root.setAttribute(QStringLiteral("title"), title);
root.setAttribute(QStringLiteral("operationWhereClause"), wc);
root.setAttribute(QStringLiteral("title_icon"), title_icon);
}
return doc.toString();
}
void SKGReportPluginWidget::setState(const QString& iState)
{
SKGTRACEINFUNC(10)
m_timer.stop();
QDomDocument doc(QStringLiteral("SKGML"));
doc.setContent(iState);
QDomElement root = doc.documentElement();
QString columns = root.attribute(QStringLiteral("columns"));
QString lines = root.attribute(QStringLiteral("lines"));
QString lines2 = root.attribute(QStringLiteral("lines2"));
QString mode = root.attribute(QStringLiteral("mode"));
QString incomes = root.attribute(QStringLiteral("incomes"));
QString expenses = root.attribute(QStringLiteral("expenses"));
QString transfers = root.attribute(QStringLiteral("transfers"));
QString grouped = root.attribute(QStringLiteral("grouped"));
QString tracked = root.attribute(QStringLiteral("tracked"));
QString currentPage = root.attribute(QStringLiteral("currentPage"));
QString forecast = root.attribute(QStringLiteral("forecast"));
QString forecastValue = root.attribute(QStringLiteral("forecastValue"));
QString tableAndGraphState = root.attribute(QStringLiteral("tableAndGraphState"));
QString title = root.attribute(QStringLiteral("title"));
QString title_icon = root.attribute(QStringLiteral("title_icon"));
QString wc = root.attribute(QStringLiteral("operationWhereClause"));
QString nbLevelLinesString = root.attribute(QStringLiteral("nbLevelLines"));
QString nbLevelColumnsString = root.attribute(QStringLiteral("nbLevelColumns"));
QString zoomPositionString = root.attribute(QStringLiteral("zoomPosition"));
QString correctedby = root.attribute(QStringLiteral("correctedby"));
QString correctedbymode = root.attribute(QStringLiteral("correctedbymode"));
QString periodDef = root.attribute(QStringLiteral("periodDef"));
// Default values
if (nbLevelLinesString.isEmpty()) {
nbLevelLinesString = '0';
}
if (nbLevelColumnsString.isEmpty()) {
nbLevelColumnsString = '0';
}
if (columns.isEmpty()) {
columns = m_attsForColumns.at(2);
}
if (lines2.isEmpty()) {
lines2 = m_attsForLines.at(0);
}
if (mode.isEmpty()) {
mode = '0';
}
if (incomes.isEmpty()) {
incomes = 'Y';
}
if (expenses.isEmpty()) {
expenses = 'Y';
}
if (transfers.isEmpty()) {
transfers = 'N';
}
if (grouped.isEmpty()) {
grouped = 'Y';
}
if (tracked.isEmpty()) {
tracked = 'Y';
}
if (currentPage.isEmpty()) {
currentPage = '0';
}
if (forecast.isEmpty()) {
forecast = '0';
}
if (forecastValue.isEmpty()) {
forecastValue = '0';
}
m_nbLevelLines = SKGServices::stringToInt(nbLevelLinesString);
m_nbLevelColumns = SKGServices::stringToInt(nbLevelColumnsString);
ui.kColumns->setCurrentIndex(m_attsForColumns.indexOf(columns));
ui.kLines->setCurrentIndex(m_attsForLines.indexOf(lines2));
m_attsForLinesAdded.clear();
if (!lines.isEmpty()) {
m_attsForLinesAdded = lines.split(OBJECTSEPARATOR);
}
ui.kMode->setCurrentIndex(ui.kMode->findData(SKGServices::stringToInt(mode)));
if (periodDef.isEmpty()) {
QString period = root.attribute(QStringLiteral("period"));
QString interval = root.attribute(QStringLiteral("interval"));
QString nb_interval = root.attribute(QStringLiteral("nb_intervals"));
QString timeline = root.attribute(QStringLiteral("timeline"));
QString date_begin = root.attribute(QStringLiteral("date_begin"));
QString date_end = root.attribute(QStringLiteral("date_end"));
if (period.isEmpty()) {
period = '1';
}
if (interval.isEmpty()) {
interval = '2';
}
if (nb_interval.isEmpty()) {
nb_interval = '1';
}
if (timeline.isEmpty()) {
timeline = '1';
}
QDomDocument doc2(QStringLiteral("SKGML"));
QDomElement root2 = doc2.createElement(QStringLiteral("parameters"));
doc2.appendChild(root2);
root2.setAttribute(QStringLiteral("period"), period);
if (period == QStringLiteral("4")) {
root2.setAttribute(QStringLiteral("date_begin"), date_begin);
root2.setAttribute(QStringLiteral("date_end"), date_end);
}
root2.setAttribute(QStringLiteral("interval"), interval);
root2.setAttribute(QStringLiteral("nb_intervals"), nb_interval);
root2.setAttribute(QStringLiteral("timeline"), timeline);
periodDef = doc2.toString();
}
ui.kPeriod->setState(periodDef);
ui.kIncomes->setChecked(incomes != QStringLiteral("N"));
ui.kExpenses->setChecked(expenses != QStringLiteral("N"));
ui.kTransfers->setChecked(transfers != QStringLiteral("N"));
ui.kGrouped->setChecked(grouped != QStringLiteral("N"));
ui.kTracked->setChecked(tracked != QStringLiteral("N"));
int currentPageInt = SKGServices::stringToInt(currentPage);
ui.kWidgetSelector->setSelectedMode(currentPageInt);
ui.kLine->setVisible(currentPageInt >= -1);
ui.kForecastCmb->setCurrentIndex(ui.kForecastCmb->findData(SKGServices::stringToInt(forecast)));
ui.kForecastValue->setValue(SKGServices::stringToInt(forecastValue));
if (!zoomPositionString.isEmpty()) {
setZoomPosition(SKGServices::stringToInt(zoomPositionString));
}
if (!correctedby.isEmpty()) {
ui.kCorrectedBy->setCurrentIndex(ui.kCorrectedBy->findText(correctedby));
}
if (!correctedbymode.isEmpty()) {
ui.kCorrectedByMode->setCurrentIndex(ui.kCorrectedByMode->findText(correctedbymode));
}
refresh();
ui.kTableWithGraph->setState(tableAndGraphState);
// Remove previous other filters
ui.kOtherFilters->clear();
if (!title.isEmpty() && !wc.isEmpty()) {
// Add new filter
auto item = new QListWidgetItem(SKGServices::fromTheme(title_icon), title);
item->setCheckState(Qt::Checked);
item->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled);
item->setData(1000, wc);
item->setData(1001, title_icon);
ui.kOtherFilters->addItem(item);
}
m_previousParametersUsed = QLatin1String("");
}
QString SKGReportPluginWidget::getDefaultStateAttribute()
{
return QStringLiteral("SKGREPORT_DEFAULT_PARAMETERS");
}
QWidget* SKGReportPluginWidget::zoomableWidget()
{
return ui.kTableWithGraph->table();
}
QList< QWidget* > SKGReportPluginWidget::printableWidgets()
{
QList<QWidget*> output;
if (ui.kTableWithGraph->isTableVisible()) {
output.push_back(ui.kTableWithGraph->table());
}
if (ui.kTableWithGraph->isGraphVisible()) {
output.push_back(ui.kTableWithGraph->graph()->graphicsView());
}
if (ui.kTableWithGraph->isTextReportVisible()) {
output.push_back(ui.kTableWithGraph->textReport());
}
return output;
}
void SKGReportPluginWidget::getWhereClauseAndTitleForItem(int row, int column, QString& oWc, QString& oTitle)
{
// Build where clause and title
oTitle.clear();
// Addition of other filter
int nb = ui.kOtherFilters->count();
for (int i = 0; i < nb; ++i) {
QListWidgetItem* item = ui.kOtherFilters->item(i);
if (item->checkState() == Qt::Checked) {
oTitle += item->text() % '.';
}
}
// Condition on line attribute
oTitle += i18nc("Noun, a list of items", "Sub operations");
auto* btn = qobject_cast<SKGColorButton*>(ui.kTableWithGraph->table()->cellWidget(row, 0));
QString attLine;
QStringList listAtt = m_attsForLinesAdded;
if (listAtt.isEmpty() || ui.kLines->currentIndex() > 0) {
listAtt.push_back(m_attsForLines.at(ui.kLines->currentIndex()));
}
nb = listAtt.count();
for (int i = 0; i < nb; ++i) {
QString att = listAtt.at(i);
if (att == QStringLiteral("#NOTHING#")) {
att = QLatin1String("");
}
if (att.startsWith(QLatin1String("p_")) || att.contains(QStringLiteral(".p_"))) {
att = getWhereClauseForProperty(att);
}
if (att.isEmpty()) {
att = '\'' % i18nc("Noun", "All") % '\'';
}
if (!attLine.isEmpty()) {
attLine += "||'" % OBJECTSEPARATOR % "'||";
}
attLine += att;
}
oWc = attLine;
QString lineVal = (btn != nullptr ? btn->text() : ui.kTableWithGraph->table()->item(row, 0)->data(1).toString());
QString title = ui.kTableWithGraph->table()->horizontalHeaderItem(0)->text();
bool avoidAnd = false;
if (lineVal.isEmpty() && row == ui.kTableWithGraph->table()->rowCount() - 1) {
// This is the last sum
oWc = QLatin1String("");
if (!attLine.isEmpty()) {
oWc = attLine % " NOT LIKE '%#NULL#%'";
avoidAnd = true;
}
} else {
// This is not the last sum
if (lineVal.isEmpty()) {
oWc += " IS NULL OR " % attLine;
}
oWc += " = '" % SKGServices::stringToSqlString(lineVal) % "' OR " %
attLine % " like '" % SKGServices::stringToSqlString(lineVal) % OBJECTSEPARATOR % "%'";
oWc = '(' % oWc % ')';
oTitle += i18nc("Noun", " with ");
oTitle += i18nc("Noun", "'%1' with '%2'", title, lineVal);
}
// Condition on column attribute
int nbCol = ui.kTableWithGraph->getNbColumns();
QString att = m_attsForColumns[ui.kColumns->currentIndex()];
if (att == QStringLiteral("#NOTHING#")) {
att = QLatin1String("");
}
if (att.startsWith(QLatin1String("p_")) || att.contains(QStringLiteral(".p_"))) {
att = getWhereClauseForProperty(att);
}
if (!att.isEmpty()) {
if (column != 0 && column < nbCol) {
if (!oWc.isEmpty()) {
oWc += QStringLiteral(" AND ");
if (!avoidAnd) {
oTitle += i18nc("Noun", " and ");
} else {
oTitle += i18nc("Noun", " with ");
}
} else {
oTitle += i18nc("Noun", " with ");
}
oWc += '(' % att;
QString val = ui.kTableWithGraph->table()->horizontalHeaderItem(column)->text();
if (val.isEmpty()) {
oWc += " IS NULL OR " % att % "=''";
oTitle += i18nc("Noun", "'%1' are empty", ui.kColumns->currentText());
} else {
oWc += " = '" % SKGServices::stringToSqlString(val) % "' OR " %
att % " like '" % SKGServices::stringToSqlString(val) % OBJECTSEPARATOR % "%'";
oTitle += i18nc("Noun", "'%1' with '%2'", ui.kColumns->currentText(), val);
}
oWc += ')';
} else {
oWc = '(' % oWc % ") AND " % att % " NOT LIKE '%#NULL#%'";
}
}
// Condition on other attribute
if (!oWc.isEmpty()) {
oWc += QStringLiteral(" AND ");
oTitle += i18nc("Noun", " and ");
}
oWc += getConsolidatedWhereClause();
QString during = ui.kPeriod->text();
QStringList types;
if (ui.kIncomes->isChecked()) {
types.push_back(i18nc("Noun", "incomes"));
}
if (ui.kExpenses->isChecked()) {
types.push_back(i18nc("Noun", "expenses"));
}
if (ui.kTransfers->isChecked()) {
types.push_back(i18nc("Noun", "transfers"));
} else if (ui.kGrouped->isChecked()) {
types.push_back(i18nc("Noun", "grouped"));
}
if (ui.kTracked->isChecked()) {
types.push_back(i18nc("Noun", "tracked"));
}
oTitle += i18nc("Noun", "during '%1' for '%2'", during, types.join(QStringLiteral(" ")));
}
void SKGReportPluginWidget::getWhereClauseAndTitleForSelection(QString& oWc, QString& oTitle)
{
oWc.clear();
oTitle.clear();
QList<QTableWidgetItem*> selection = ui.kTableWithGraph->table()->selectedItems();
int nb = selection.count();
if (nb != 0) {
for (int i = 0; i < nb; ++i) {
QString wc2;
QString title2;
getWhereClauseAndTitleForItem(selection.at(i)->row(), selection.at(i)->column(), wc2, title2);
if (!wc2.isEmpty()) {
if (!oWc.isEmpty()) {
oWc = '(' % oWc % ") OR (" % wc2 % ')';
} else {
oWc = wc2;
}
}
if (!title2.isEmpty()) {
if (!oTitle.isEmpty()) {
oTitle = i18n("(%1) or (%2)", oTitle, title2);
} else {
oTitle = title2;
}
}
}
}
}
void SKGReportPluginWidget::onDoubleClick(int row, int column)
{
_SKGTRACEINFUNC(10)
QString wc;
QString title;
getWhereClauseAndTitleForItem(row, column, wc, title);
SKGMainPanel::getMainPanel()->openPage("skg://skrooge_operation_plugin/SKGOPERATION_CONSOLIDATED_DEFAULT_PARAMETERS/?currentPage=-1&title_icon=view-statistics&operationTable=v_suboperation_consolidated&operationWhereClause=" % SKGServices::encodeForUrl(wc) % "&title=" % SKGServices::encodeForUrl(title));
}
void SKGReportPluginWidget::onBtnModeClicked(int mode)
{
ui.kTableWithGraph->setFilterVisibility(mode == 0);
}
void SKGReportPluginWidget::onOpen()
{
QString wc;
QString title;
getWhereClauseAndTitleForSelection(wc, title);
SKGMainPanel::getMainPanel()->openPage("skg://skrooge_operation_plugin/SKGOPERATION_CONSOLIDATED_DEFAULT_PARAMETERS/?currentPage=-1&title_icon=view-statistics&operationTable=v_suboperation_consolidated&operationWhereClause=" % SKGServices::encodeForUrl(wc) % "&title=" % SKGServices::encodeForUrl(title));
}
void SKGReportPluginWidget::onOpenReport()
{
SKGError err;
SKGTRACEINFUNCRC(10, err)
QString wc;
QString title;
getWhereClauseAndTitleForSelection(wc, title);
if (!wc.isEmpty()) {
// Call report plugin
QDomDocument doc(QStringLiteral("SKGML"));
doc.setContent(getState());
QDomElement root = doc.documentElement();
root.setAttribute(QStringLiteral("operationWhereClause"), wc);
root.setAttribute(QStringLiteral("title"), title);
root.setAttribute(QStringLiteral("title_icon"), QStringLiteral("view-statistics"));
QString currentPage = root.attribute(QStringLiteral("currentPage"));
if (SKGServices::stringToInt(currentPage) < -1) {
root.setAttribute(QStringLiteral("currentPage"), QStringLiteral("-1"));
}
SKGMainPanel::getMainPanel()->openPage(SKGMainPanel::getMainPanel()->getPluginByName(QStringLiteral("Skrooge report plugin")), -1, doc.toString());
}
}
void SKGReportPluginWidget::onOneLevelMore()
{
_SKGTRACEINFUNC(10)
if (sender() == ui.kLineUp) {
++m_nbLevelLines;
} else {
++m_nbLevelColumns;
}
refresh();
}
void SKGReportPluginWidget::onOneLevelLess()
{
_SKGTRACEINFUNC(10)
if (sender() == ui.kLineDown) {
--m_nbLevelLines;
} else {
--m_nbLevelColumns;
}
refresh();
}
void SKGReportPluginWidget::onAddLine()
{
_SKGTRACEINFUNC(10)
m_attsForLinesAdded.push_back(m_attsForLines.value(ui.kLines->currentIndex()));
ui.kLines->setCurrentIndex(0);
refresh();
}
void SKGReportPluginWidget::onRemoveLine()
{
_SKGTRACEINFUNC(10)
if (!m_attsForLinesAdded.isEmpty()) {
m_attsForLinesAdded.pop_back();
}
refresh();
}
QString SKGReportPluginWidget::getConsolidatedWhereClause(QString* oWhereClausForPreviousData, QString* oWhereClausForForecastData)
{
// Build where clause
int forecastmode = ui.kForecastCmb->itemData(ui.kForecastCmb->currentIndex()).toInt();
QString wc = ui.kPeriod->getWhereClause(forecastmode != 1, oWhereClausForPreviousData, oWhereClausForForecastData);
wc = "((" % wc % ") OR d_date='0000') AND d_date!='0000-00-00'";
if (oWhereClausForPreviousData != nullptr) {
*oWhereClausForPreviousData = "((" % *oWhereClausForPreviousData % ") OR d_date='0000-00-00')";
}
QString operationTypes;
if (ui.kIncomes->isChecked() && !ui.kExpenses->isChecked()) {
operationTypes = QStringLiteral("t_TYPEEXPENSE='+'");
} else if (ui.kExpenses->isChecked() && !ui.kIncomes->isChecked()) {
operationTypes = QStringLiteral("t_TYPEEXPENSE='-'");
}
if (!operationTypes.isEmpty()) {
QString condition = " AND " % operationTypes;
wc += condition;
if (oWhereClausForPreviousData != nullptr) {
*oWhereClausForPreviousData += condition;
}
}
if (!ui.kGrouped->isChecked()) {
QString condition = QStringLiteral(" AND i_group_id=0");
wc += condition;
if (oWhereClausForPreviousData != nullptr) {
*oWhereClausForPreviousData += condition;
}
} else {
if (!ui.kTransfers->isChecked()) {
QString condition = QStringLiteral(" AND t_TRANSFER='N'");
wc += condition;
if (oWhereClausForPreviousData != nullptr) {
*oWhereClausForPreviousData += condition;
}
}
}
if (!ui.kTracked->isChecked()) {
QString condition = QStringLiteral(" AND r_refund_id=0");
wc += condition;
if (oWhereClausForPreviousData != nullptr) {
*oWhereClausForPreviousData += condition;
}
}
// Addition of other filters
int nb = ui.kOtherFilters->count();
for (int i = 0; i < nb; ++i) {
QListWidgetItem* item = ui.kOtherFilters->item(i);
if (item->checkState() == Qt::Checked) {
QString condition = " AND (" % item->data(1000).toString() % ")";
wc += condition;
if (oWhereClausForPreviousData != nullptr) {
*oWhereClausForPreviousData += condition;
}
}
}
return wc;
}
void SKGReportPluginWidget::onSelectionChanged()
{
if (m_openReportAction != nullptr) {
m_openReportAction->setEnabled(!ui.kTableWithGraph->table()->selectedItems().isEmpty());
}
if (m_openAction != nullptr) {
m_openAction->setEnabled(!ui.kTableWithGraph->table()->selectedItems().isEmpty());
}
}
void SKGReportPluginWidget::refresh()
{
int p = ui.kPeriod->mode();
bool dateCol = (m_attsForColumns.value(ui.kColumns->currentIndex()).startsWith(QLatin1String("d_")));
if (!dateCol) {
ui.kForecastCmb->setCurrentIndex(0);
}
ui.kForecastCmb->setEnabled(dateCol);
ui.kForecastValue->setEnabled(ui.kForecastCmb->currentIndex() > 0);
ui.kLineRemove->setEnabled(!m_attsForLinesAdded.isEmpty());
int mode = ui.kMode->itemData(ui.kMode->currentIndex()).toInt();
ui.kCorrectedBy->setEnabled(mode != 3);
ui.kCorrectedByMode->setEnabled(mode != 3);
// Check income & expense
if (!ui.kIncomes->isChecked() && !ui.kExpenses->isChecked()) {
if (sender() == ui.kIncomes) {
ui.kExpenses->setChecked(true);
} else {
ui.kIncomes->setChecked(true);
}
}
bool timeline = (p == 5);
ui.kForecastFrm->setEnabled(!timeline);
if (timeline) {
ui.kForecastCmb->setCurrentIndex(0);
}
m_timer.start(300);
}
void SKGReportPluginWidget::pageChanged()
{
if (m_refreshNeeded) {
m_timer.start(300);
}
// Refresh other filter
auto* rep = qobject_cast<SKGReportPlugin*>(SKGMainPanel::getMainPanel()->getPluginByName(QStringLiteral("Skrooge report plugin")));
if (rep != nullptr) {
// Remove unused filters
int nbf = ui.kOtherFilters->count();
for (int i = nbf - 1; i >= 0; --i) {
QListWidgetItem* item = ui.kOtherFilters->item(i);
if (item->checkState() == Qt::Unchecked) {
QListWidgetItem* item = ui.kOtherFilters->takeItem(i);
delete item;
}
}
// Add pages filters
int nb = SKGMainPanel::getMainPanel()->countPages();
for (int i = 0; i < nb; ++i) {
SKGTabPage* page = SKGMainPanel::getMainPanel()->page(i);
SKGObjectBase::SKGListSKGObjectBase selection = page->getSelectedObjects();
QString title;
QString wc;
rep->getTitleAndWhereClause(selection, title, wc);
if (!title.isEmpty()) {
// Check if already existing
bool existing = false;
int nbf = ui.kOtherFilters->count();
for (int j = 0; !existing && j < nbf; ++j) {
QListWidgetItem* item2 = ui.kOtherFilters->item(j);
if (item2->data(1000).toString() == wc) {
existing = true;
}
}
// Add it if not existing
if (!existing) {
QString icon = SKGMainPanel::getMainPanel()->getPluginByName(page->objectName())->icon();
auto item = new QListWidgetItem(SKGServices::fromTheme(icon), title);
item->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled);
item->setCheckState(Qt::Unchecked);
item->setData(1000, wc);
item->setData(1001, icon);
ui.kOtherFilters->addItem(item);
}
}
}
}
}
void SKGReportPluginWidget::dataModified(const QString& iTableName, int iIdTransaction)
{
SKGTRACEINFUNC(10)
Q_UNUSED(iIdTransaction)
// Refresh panel
QSqlDatabase* db = getDocument()->getMainDatabase();
setEnabled(db != nullptr);
// Check if needed
if (db != nullptr && (iTableName == QStringLiteral("v_suboperation_consolidated") || iTableName.isEmpty())) {
SKGError err;
auto* doc = qobject_cast<SKGDocumentBank*>(getDocument());
if (doc != nullptr) {
// Check if update is needed
SKGTabPage* page = SKGTabPage::parentTabPage(this->parentWidget());
SKGTabPage* cpage = SKGMainPanel::getMainPanel()->currentPage();
if (page != nullptr && page != cpage) {
m_refreshNeeded = true;
return;
}
QString ParametersUsed = getState() % ';' % SKGServices::intToString(doc->getTransactionToProcess(SKGDocument::UNDO));
if (ParametersUsed == m_previousParametersUsed) {
SKGTRACEL(10) << "Same parameters. Refresh ignored" << endl;
return;
}
QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
m_refreshNeeded = false;
m_previousParametersUsed = ParametersUsed;
// Fill line and create title
QString lineString;
QString title;
int nb = m_attsForLinesAdded.count();
for (int i = 0; i < nb; ++i) {
lineString += doc->getDisplay(m_attsForLinesAdded.at(i));
if (i < nb - 1) {
lineString += OBJECTSEPARATOR;
}
}
if (ui.kLines->currentIndex() > 0 && (nb != 0)) {
lineString += OBJECTSEPARATOR;
}
title = lineString;
if (ui.kLines->currentIndex() > 0 || nb == 0) {
title += ui.kLines->text();
}
ui.kLineLabel->setVisible(nb > 0);
ui.kLineLabel->setText(lineString);
ui.kLineLabel->setToolTip(lineString);
// Get parameters
int col = ui.kColumns->currentIndex();
int line = ui.kLines->currentIndex();
if (col >= 0 && line >= 0) {
int mode = ui.kMode->itemData(ui.kMode->currentIndex()).toInt();
// Mode history ?
bool modeHistory = (mode == 1 || mode == 8);
// Get condition (must be done before forecast on scheduled operations)
int nbVirtualColumn = 0;
QString conditionPrevious;
QString conditionForecast;
QString condition = getConsolidatedWhereClause(&conditionPrevious, &conditionForecast);
int forecastMode = ui.kForecastCmb->itemData(ui.kForecastCmb->currentIndex()).toInt();
// Compute forecast on scheduled operations
bool transactionToRollback = false;
if (forecastMode == 1 || forecastMode == 4) {
// Create operations
QDate lastDate = QDate::currentDate().addDays(ui.kForecastValue->value() * skgreport_settings::maxForecasts() * 365.0 / ui.kForecastValue->maximum());
if (forecastMode == 1) {
// Create scheduled operations
doc->beginTransaction("#INTERNAL#" % i18nc("Progression step", "Create scheduled operations"));
transactionToRollback = true;
int nbInserted = 0;
SKGRecurrentOperationObject::process(doc, nbInserted, true, lastDate);
} else {
// Create budgeted operations
SKGObjectBase::SKGListSKGObjectBase budgets;
IFOKDO(err, doc->getObjects(QStringLiteral("v_budget"),
"t_PERIOD>STRFTIME('%Y-%m', date('now')) AND "
"t_PERIOD<=STRFTIME('%Y-%m', '" % SKGServices::dateToSqlString(QDateTime(lastDate)) % "')", budgets));
int nbBudgets = budgets.count();
if (nbBudgets != 0) {
// Get most active account
SKGStringListList list;
err = doc->executeSelectSqliteOrder(QStringLiteral("SELECT rd_account_id, r_category_id FROM v_suboperation_consolidated WHERE d_date>date('now', '-3 month') group by r_category_id, rd_account_id order by count(rd_account_id) DESC"), list);
int nbmap = list.count();
if (!err && nbmap >= 2) {
// Build map
int default_account = 0;
QMap<int, int> category_account;
for (int i = 1; i < nbmap; ++i) {
if (i == 1) {
default_account = SKGServices::stringToInt(list.at(i).at(0));
}
category_account[SKGServices::stringToInt(list.at(i).at(1))] = SKGServices::stringToInt(list.at(i).at(0));
}
// Get unit
SKGUnitObject unit(doc);
IFOKDO(err, unit.setName(doc->getPrimaryUnit().Name))
IFOKDO(err, unit.setSymbol(doc->getPrimaryUnit().Symbol))
IFOKDO(err, unit.load())
doc->beginTransaction("#INTERNAL#" % i18nc("Progression step", "Create budgeted operations"));
transactionToRollback = true;
for (int i = 0; !err && i < nbBudgets; ++i) {
SKGBudgetObject budget(budgets.at(i));
SKGCategoryObject cat;
budget.getCategory(cat);
// Get better account for the category
SKGAccountObject account(doc, category_account.contains(cat.getID()) ? category_account[cat.getID()] : default_account);
account.load();
SKGOperationObject op;
IFOKDO(err, account.addOperation(op))
IFOKDO(err, op.setDate(QDate(budget.getYear(), qMax(budget.getMonth(), 1), 1)))
IFOKDO(err, op.setUnit(unit))
IFOKDO(err, op.save())
SKGSubOperationObject sop;
IFOKDO(err, op.addSubOperation(sop))
IFOKDO(err, sop.setCategory(cat))
IFOKDO(err, sop.setQuantity(budget.getBudgetedAmount()))
IFOKDO(err, sop.save())
}
}
}
}
ui.kForecastValue->setToolTip(SKGServices::dateToSqlString(QDateTime(lastDate)));
} else {
ui.kForecastValue->setToolTip(QLatin1String(""));
conditionForecast = QStringLiteral("1=0");
}
// Execute sql order
SKGStringListList table;
QString tableName = QStringLiteral("v_suboperation_consolidated");
QString attCol = m_attsForColumns[col ];
if (attCol == QStringLiteral("#NOTHING#")) {
attCol = QLatin1String("");
}
if (attCol.startsWith(QLatin1String("p_")) || attCol.contains(QStringLiteral(".p_"))) {
attCol = getWhereClauseForProperty(attCol);
}
QStringList listAtt = m_attsForLinesAdded;
if (listAtt.isEmpty() || line > 0) {
listAtt.push_back(m_attsForLines.at(line));
}
QString attLine;
int nb2 = listAtt.count();
for (int i = 0; i < nb2; ++i) {
QString att = listAtt.at(i);
if (att == QStringLiteral("#NOTHING#")) {
att = QLatin1String("");
}
if (att.startsWith(QLatin1String("p_")) || att.contains(QStringLiteral(".p_"))) {
att = getWhereClauseForProperty(att);
}
if (att.isEmpty()) {
att = '\'' % i18nc("Noun", "All") % '\'';
}
if (!attLine.isEmpty()) {
attLine += "||'" % OBJECTSEPARATOR % "'||";
}
attLine += att;
}
if ((modeHistory || (forecastMode != 0)) && !attCol.isEmpty()) {
tableName = QStringLiteral("(SELECT ");
if (!modeHistory) {
tableName += QStringLiteral("d_date, ");
tableName += attCol % "||(CASE WHEN " % conditionForecast % " THEN '999' ELSE '' END) AS " % m_attsForColumns[col ] % ",* FROM v_suboperation_consolidated) as v_suboperation_consolidated";
} else {
if (attCol != QStringLiteral("d_date")) {
tableName += "(CASE WHEN (" % conditionPrevious % ") AND f_REALQUANTITY<>0 THEN '0000' ELSE d_date END) AS d_date, ";
}
tableName += "(CASE WHEN (" % conditionPrevious % ") AND f_REALQUANTITY<>0 THEN '0000' ELSE " % attCol % "||(CASE WHEN " % conditionForecast % " THEN '999' ELSE '' END) END) AS " % m_attsForColumns[col ] % ",* FROM v_suboperation_consolidated) as v_suboperation_consolidated";
}
}
// Remove #NULL# columns and lines
if (!attLine.isEmpty()) {
condition = '(' % condition % ") AND " % attLine % " NOT LIKE '%#NULL#%'";
}
if (!attCol.isEmpty()) {
condition = '(' % condition % ") AND " % attCol % " NOT LIKE '%#NULL#%'";
}
// Limit size of the result
condition = '(' % condition % ") AND (d_date>(SELECT date('now', '-50 year')) OR d_date='0000') AND d_date<(SELECT date('now', '+50 year'))";
QString coef;
if (ui.kCorrectedBy->currentIndex() > 0 && mode != 3) {
SKGUnitObject unit = ui.kCorrectedBy->getUnit();
QString id = SKGServices::intToString(unit.getID());
if (ui.kCorrectedByMode->currentIndex() == 0) {
coef = '*';
} else {
coef = '/';
}
coef = coef % "COALESCE((SELECT u1.f_quantity FROM unitvalue u1 where u1.rd_unit_id=" % id % " and u1.d_date=(SELECT MAX(u2.d_date) FROM unitvalue u2 where u2.rd_unit_id=" % id % " and u2.d_date<=v_suboperation_consolidated.d_date)), (SELECT u1.f_quantity FROM unitvalue u1 where u1.rd_unit_id=" % id % " and u1.d_date=(SELECT MIN(u2.d_date) FROM unitvalue u2 where u2.rd_unit_id=" % id % ")),0)";
}
IFOKDO(err, doc->getConsolidatedView(tableName, attCol, attLine, "f_REALCURRENTAMOUNT" % coef,
(mode == 3 ? QStringLiteral("COUNT") : QStringLiteral("TOTAL")), condition, table));
int nbLines = table.count();
IFSKGTRACEL(10) {
QStringList dump = SKGServices::tableToDump(table, SKGServices::DUMP_TEXT);
int nbl = dump.count();
for (int i = 0; i < nbl; ++i) {
SKGTRACE << dump.at(i) << endl;
}
}
// Rollback create operations
if (transactionToRollback) {
doc->endTransaction(false);
}
if (forecastMode == 1 || forecastMode == 4) {
// Compute nb date in futur
if (nbLines != 0) {
QStringList line1 = table.at(0);
int nbCol = line1.count();
for (int i = 0; i < nbCol; ++i) {
QString newTitle = line1.at(i);
if (newTitle.endsWith(QLatin1String("999"))) {
newTitle = newTitle.left(newTitle.count() - 3);
line1.replace(i, newTitle);
++nbVirtualColumn;
}
}
table.replace(0, line1);
}
}
IFOK(err) {
// Update title
if (nbLines != 0) {
// Change title
QStringList line1 = table.at(0);
if (!line1.isEmpty()) {
line1.replace(0, title);
table.replace(0, line1);
}
}
// Compute forecast on average
if ((nbLines != 0) && (forecastMode == 2 || forecastMode == 3)) {
QStringList newLine = table.at(0);
int nbVals = newLine.count() - 1;
int percent = ui.kForecastValue->value();
if (nbVals >= 3 && percent > 0) {
// Compute nb value to add
nbVirtualColumn = percent * nbVals / FORECASTMAX;
// Build header
newLine.reserve(newLine.count() + nbVirtualColumn);
for (int i = 0; i < nbVirtualColumn; ++i) {
newLine.push_back(i18nc("Noun", "N %1", (i + 1)));
}
table.replace(0, newLine);
// Build values
for (int j = 1; j < nbLines; ++j) {
QStringList newLineTmp = table.at(j);
newLineTmp.reserve(newLineTmp.count() + nbVirtualColumn);
for (int i = 0; i < nbVirtualColumn; ++i) {
// Moving average
double nv = 0;
double weight = 0;
for (int k = 0; k < nbVirtualColumn; ++k) {
if (forecastMode == 2) {
// Simple mode
nv += SKGServices::stringToDouble(newLineTmp.at(nbVals + i - k));
++weight;
} else {
// Weighted mode
nv += (nbVirtualColumn - k) * SKGServices::stringToDouble(newLineTmp.at(nbVals + i - k));
weight += nbVirtualColumn - k;
}
}
newLineTmp.push_back(SKGServices::doubleToString(nv / weight));
}
table.replace(j, newLineTmp);
}
}
}
// Create grouped by lines table
int nbLevelLineMax = 0;
{
SKGStringListList groupedByLineTable = table;
{
int nbCols = -1;
QString previousLineName = QStringLiteral("###");
if (!groupedByLineTable.isEmpty()) {
nbCols = groupedByLineTable.at(0).count();
}
for (int i = 1; (nbCols != 0) && i < groupedByLineTable.count(); ++i) { // Dynamically modified
QStringList line2 = groupedByLineTable.at(i);
QString val = line2.at(0);
// Rebuild val for the number of level
QStringList vals = val.split(OBJECTSEPARATOR);
int nbvals = vals.count();
if (nbvals > m_nbLevelLines + 1) {
// Rebuild val
val = QLatin1String("");
for (int k = 0; k <= m_nbLevelLines; ++k) {
val += vals[k];
if (k != m_nbLevelLines) {
val += OBJECTSEPARATOR;
}
}
}
nbLevelLineMax = qMax(nbLevelLineMax, nbvals - 1);
if (val == previousLineName) {
// Current line is merged with previous one
QStringList newLine;
newLine.reserve(nbCols);
newLine.push_back(val);
for (int k = 1; k < nbCols; ++k) {
const QString& valstring1 = line2.at(k);
QString valstring2 = groupedByLineTable.at(i - 1).at(k);
if (!valstring1.isEmpty() || !valstring2.isEmpty()) {
double sum2 = 0;
if (!valstring1.isEmpty()) {
sum2 += SKGServices::stringToDouble(valstring1);
}
if (!valstring2.isEmpty()) {
sum2 += SKGServices::stringToDouble(valstring2);
}
newLine.push_back(SKGServices::doubleToString(sum2));
} else {
newLine.push_back(QLatin1String(""));
}
}
groupedByLineTable.replace(i - 1, newLine);
// Remove current line
groupedByLineTable.removeAt(i);
--i;
} else {
// Current line is just modified
QStringList newLine;
newLine.reserve(nbCols);
newLine.push_back(val);
for (int k = 1; k < nbCols; ++k) {
newLine.push_back(line2.at(k));
}
groupedByLineTable.replace(i, newLine);
previousLineName = val;
}
}
}
table = groupedByLineTable;
}
// Create grouped by columns table
int nbLevelColMax = 0;
{
SKGStringListList groupedByColTable = table;
int nbLines2 = groupedByColTable.count();
if (nbLines2 != 0) {
QString previousColumnName = QStringLiteral("###");
for (int i = 1; (nbLines2 != 0) && i < groupedByColTable.at(0).count(); ++i) { // Dynamically modified
QString val = groupedByColTable.at(0).at(i);
// Rebuild val for the number of level
QStringList vals = val.split(OBJECTSEPARATOR);
int nbvals = vals.count();
if (nbvals > m_nbLevelColumns + 1) {
// Rebuild val
val = QLatin1String("");
for (int k = 0; k <= m_nbLevelColumns; ++k) {
val += vals[k];
if (k != m_nbLevelColumns) {
val += OBJECTSEPARATOR;
}
}
}
nbLevelColMax = qMax(nbLevelColMax, nbvals - 1);
if (val == previousColumnName) {
// Current column is merged with previous one
QStringList newLine = groupedByColTable.at(0);
newLine.removeAt(i);
groupedByColTable.replace(0, newLine);
for (int k = 1; k < nbLines2; ++k) {
newLine = groupedByColTable.at(k);
QString valstring1 = newLine.at(i);
QString valstring2 = newLine.at(i - 1);
if (!valstring1.isEmpty() || !valstring2.isEmpty()) {
double sum2 = 0;
if (!valstring1.isEmpty()) {
sum2 += SKGServices::stringToDouble(valstring1);
}
if (!valstring2.isEmpty()) {
sum2 += SKGServices::stringToDouble(valstring2);
}
newLine.replace(i - 1, SKGServices::doubleToString(sum2));
} else {
newLine.removeAt(i - 1);
}
newLine.removeAt(i);
groupedByColTable.replace(k, newLine);
}
// Remove current line
--i;
} else {
// Current column is just modified
QStringList newLine = groupedByColTable.at(0);
newLine.replace(i, val);
groupedByColTable.replace(0, newLine);
previousColumnName = val;
}
}
}
table = groupedByColTable;
}
// Initialize parameters
SKGServices::SKGUnitInfo primaryUnit = doc->getPrimaryUnit();
SKGServices::SKGUnitInfo secondaryUnit = doc->getSecondaryUnit();
SKGTableWithGraph::DisplayAdditionalFlag dmode = SKGTableWithGraph::NONE;
if (m_attsForColumns.at(col).startsWith(QLatin1String("d_"))) {
dmode |= SKGTableWithGraph::AVERAGE | SKGTableWithGraph::LIMITS;
}
// Create history (must be done after groups)
if (modeHistory) {
table = SKGServices::getHistorizedTable(table);
} else {
// Add SUM if not in HISTORY mode
dmode |= SKGTableWithGraph::SUM;
}
// Mode percent
bool modePercent = (mode == 2 || mode == 4 || mode == 5 || mode == 6);
if (modePercent) {
primaryUnit.Symbol = '%';
SKGServices::SKGUnitInfo empty;
empty.Value = 0.0;
empty.NbDecimal = 2;
secondaryUnit = empty;
table = SKGServices::getPercentTable(table, (mode == 2 || mode == 5), (mode == 5 || mode == 6));
}
// Mode base 100
if (mode == 7 || mode == 8) {
table = SKGServices::getBase100Table(table);
}
// Mode Count
if (mode == 3) {
primaryUnit.Symbol = ' ';
SKGServices::SKGUnitInfo empty;
empty.Value = 0.0;
empty.NbDecimal = 2;
secondaryUnit = empty;
}
// Set data
ui.kTableWithGraph->setData(table, primaryUnit, secondaryUnit, dmode, nbVirtualColumn);
// Enable/Disable buttons
m_nbLevelLines = qMin(nbLevelLineMax, m_nbLevelLines);
ui.kLineDown->setEnabled(m_nbLevelLines > 0);
ui.kLineUp->setEnabled(m_nbLevelLines < nbLevelLineMax);
m_nbLevelColumns = qMin(nbLevelColMax, m_nbLevelColumns);
ui.kColDown->setEnabled(m_nbLevelColumns > 0);
ui.kColUp->setEnabled(m_nbLevelColumns < nbLevelColMax);
}
}
QApplication::restoreOverrideCursor();
}
// Display error
SKGMainPanel::displayErrorMessage(err);
}
}
void SKGReportPluginWidget::setSettings()
{
ui.kTableWithGraph->setAxisColor(skgreport_settings::axisColor());
ui.kTableWithGraph->setGridColor(skgreport_settings::gridColor());
ui.kTableWithGraph->setMinColor(skgreport_settings::minColor());
ui.kTableWithGraph->setMaxColor(skgreport_settings::maxColor());
ui.kTableWithGraph->setParetoColor(skgreport_settings::paretoColor());
ui.kTableWithGraph->setAverageColor(skgreport_settings::averageColor());
ui.kTableWithGraph->setTendencyColor(skgreport_settings::tendencyColor());
ui.kTableWithGraph->setBackgroundColor(skgreport_settings::backgroundColor());
ui.kTableWithGraph->setTextColor(skgreport_settings::textColor());
ui.kTableWithGraph->setOutlineColor(skgreport_settings::outlineColor());
ui.kTableWithGraph->setAntialiasing(skgreport_settings::antialiasing());
ui.kTableWithGraph->redrawGraphDelayed();
}
QString SKGReportPluginWidget::getWhereClauseForProperty(const QString& iProperty) const
{
QString propertyName = iProperty.right(iProperty.length() - 2);
QString check = getDocument()->getDisplay(QStringLiteral("t_category"));
if (iProperty.startsWith(check)) {
propertyName = iProperty.right(iProperty.length() - check.length() - 1 - 2);
return "(SELECT t_value FROM parameters WHERE t_uuid_parent=v_suboperation_consolidated.i_IDCATEGORY||'-category' AND t_name='" % propertyName % "')";
}
check = getDocument()->getDisplay(QStringLiteral("t_account"));
if (iProperty.startsWith(check)) {
propertyName = iProperty.right(iProperty.length() - check.length() - 1 - 2);
return "(SELECT t_value FROM parameters WHERE t_uuid_parent=v_suboperation_consolidated.rd_account_id||'-account' AND t_name='" % propertyName % "')";
}
check = getDocument()->getDisplay(QStringLiteral("t_payee"));
if (iProperty.startsWith(check)) {
propertyName = iProperty.right(iProperty.length() - check.length() - 1 - 2);
return "(SELECT t_value FROM parameters WHERE t_uuid_parent=v_suboperation_consolidated.r_payee_id||'-payee' AND t_name='" % propertyName % "')";
}
check = getDocument()->getDisplay(QStringLiteral("t_unit"));
if (iProperty.startsWith(check)) {
propertyName = iProperty.right(iProperty.length() - check.length() - 1 - 2);
return "(SELECT t_value FROM parameters WHERE t_uuid_parent=v_suboperation_consolidated.rc_unit_id||'-unit' AND t_name='" % propertyName % "')";
}
return "IFNULL((SELECT t_value FROM parameters WHERE t_uuid_parent=v_suboperation_consolidated.id||'-suboperation' AND t_name='" % propertyName % "'), IFNULL((SELECT t_value FROM parameters WHERE t_uuid_parent=v_suboperation_consolidated.i_OPID||'-operation' AND t_name='" % propertyName % "'), '#NULL#'))";
}
diff --git a/plugins/skrooge/skrooge_report/skgreportpluginwidget.h b/plugins/skrooge/skrooge_report/skgreportpluginwidget.h
index 16073c8cd..a4571137a 100644
--- a/plugins/skrooge/skrooge_report/skgreportpluginwidget.h
+++ b/plugins/skrooge/skrooge_report/skgreportpluginwidget.h
@@ -1,140 +1,140 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGREPORTPLUGINWIDGET_H
#define SKGREPORTPLUGINWIDGET_H
/** @file
* This file is Skrooge plugin for bank management.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include <qdom.h>
#include <qstringlist.h>
#include <qtimer.h>
#include "skgtabpage.h"
#include "ui_skgreportpluginwidget_base.h"
class SKGDocumentBank;
/**
* This file is Skrooge plugin to generate report
*/
class SKGReportPluginWidget : public SKGTabPage
{
Q_OBJECT
public:
/**
* Default Constructor
* @param iParent the parent widget
* @param iDocument the document
* @param iMinimmumMode the panel will be displayed with minimum widgets
*/
explicit SKGReportPluginWidget(QWidget* iParent, SKGDocumentBank* iDocument, bool iMinimmumMode = false);
/**
* Default Destructor
*/
~SKGReportPluginWidget() override;
/**
* Get the current state
* MUST BE OVERWRITTEN
* @return a string containing all information needed to set the same state.
* Could be an XML stream
*/
QString getState() override;
/**
* Set the current state
* MUST BE OVERWRITTEN
* @param iState must be interpreted to set the state of the widget
*/
void setState(const QString& iState) override;
/**
* Get attribute name to save the default state
* MUST BE OVERWRITTEN
* @return attribute name to save the default state.
*/
QString getDefaultStateAttribute() override;
/**
* Get the zoomable widget.
* The default implementation returns the main widget.
* @return the zoomable widget.
*/
QWidget* zoomableWidget() override;
/**
* Get the printable widgets.
* The default implementation returns the main widget.
* @return the printable widgets.
*/
QList<QWidget*> printableWidgets() override;
public Q_SLOTS:
/**
* Refresh the panel
*/
void refresh();
/**
* data are modified
* @param iTableName table name
* @param iIdTransaction the id of the transaction for direct modifications of the table (update of modify objects is enough)
*or 0 in case of modifications by impact (full table must be refreshed)
*/
virtual void dataModified(const QString& iTableName = QString(), int iIdTransaction = 0);
private Q_SLOTS:
void pageChanged();
void onDoubleClick(int row, int column);
void onOpen();
void onOpenReport();
void onSelectionChanged();
void onOneLevelMore();
void onOneLevelLess();
void onAddLine();
void onRemoveLine();
void onBtnModeClicked(int mode);
void setSettings();
private:
Q_DISABLE_COPY(SKGReportPluginWidget)
QString getConsolidatedWhereClause(QString* oWhereClausForPreviousData = nullptr, QString* oWhereClausForForecastData = nullptr);
void getWhereClauseAndTitleForItem(int row, int column, QString& oWc, QString& oTitle);
void getWhereClauseAndTitleForSelection(QString& oWc, QString& oTitle);
QString getWhereClauseForProperty(const QString& iProperty) const;
Ui::skgreportplugin_base ui{};
QString m_previousParametersUsed;
QStringList m_attsForColumns;
QStringList m_attsForLines;
QStringList m_attsForLinesAdded;
QAction* m_openReportAction;
QAction* m_openAction;
QTimer m_timer;
int m_mode;
int m_nbLevelLines;
int m_nbLevelColumns;
bool m_refreshNeeded;
};
#endif // SKGREPORTPLUGINWIDGET_H
diff --git a/plugins/skrooge/skrooge_report/tests/CMakeLists.txt b/plugins/skrooge/skrooge_report/tests/CMakeLists.txt
index f5a5c36b6..3cb0abee2 100644
--- a/plugins/skrooge/skrooge_report/tests/CMakeLists.txt
+++ b/plugins/skrooge/skrooge_report/tests/CMakeLists.txt
@@ -1,45 +1,45 @@
#***************************************************************************
#* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
#* *
#* 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 <http://www.gnu.org/licenses/> *
+#* along with this program. If not, see <https://www.gnu.org/licenses/> *
#***************************************************************************
MESSAGE( STATUS "..:: CMAKE PLUGIN_REPORT_TEST ::..")
PROJECT(plugin_report_test)
IF(SKG_WEBENGINE)
MESSAGE( STATUS " Mode WebEngine")
ADD_DEFINITIONS(-DSKG_WEBENGINE=${SKG_WEBENGINE})
ENDIF(SKG_WEBENGINE)
ADD_DEFINITIONS(-DQT_GUI_LIB)
LINK_DIRECTORIES (${LIBRARY_OUTPUT_PATH})
INCLUDE_DIRECTORIES( ${CMAKE_SOURCE_DIR}/tests/skgbasemodelertest )
#Add test
ENABLE_TESTING()
FILE(GLOB cpp_files "skgtest*.cpp")
LIST(SORT cpp_files)
FOREACH(file ${cpp_files})
GET_FILENAME_COMPONENT(utname ${file} NAME_WE)
SET(SRC ../skgreportplugin.cpp ../skgreportpluginwidget.cpp ../skgreportboardwidget.cpp)
ki18n_wrap_ui(SRC ../skgreportpluginwidget_base.ui ../skgreportpluginwidget_pref.ui)
kconfig_add_kcfg_files(SRC ../skgreport_settings.kcfgc )
ADD_EXECUTABLE(${utname} ${file} ${SRC})
TARGET_LINK_LIBRARIES(${utname} Qt5::Gui Qt5::Core Qt5::Test skgbasegui skgbankgui skgbasemodeler skgbankmodeler)
ADD_TEST(NAME ${utname} COMMAND ${CMAKE_SOURCE_DIR}/tests/scripts/${utname}.sh)
ENDFOREACH()
INCLUDE(CTest)
diff --git a/plugins/skrooge/skrooge_report/tests/skgtestreportplugin.cpp b/plugins/skrooge/skrooge_report/tests/skgtestreportplugin.cpp
index fd8b8aded..c26ecde46 100644
--- a/plugins/skrooge/skrooge_report/tests/skgtestreportplugin.cpp
+++ b/plugins/skrooge/skrooge_report/tests/skgtestreportplugin.cpp
@@ -1,43 +1,43 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is a test for SKGReportPlugin component.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgtestreportplugin.h"
#include "skgdocumentbank.h"
#include "../skgreportplugin.h"
#include "../../../../tests/skgbasemodelertest/skgtestmacro.h"
#include <QAction>
void SKGTESTReportPlugin::TestPlugin()
{
SKGDocumentBank doc;
SKGReportPlugin plugin(nullptr, nullptr, QVariantList());
SKGTESTPLUGIN(plugin, doc);
QCOMPARE(plugin.isInPagesChooser(), true);
QCOMPARE(plugin.isEnabled(), true);
SKGTESTTRIGGERACTION("open_report");
SKGTESTTRIGGERACTION("view_open_very_old_operations");
SKGTESTTRIGGERACTION("view_open_very_far_operations");
}
QTEST_MAIN(SKGTESTReportPlugin)
diff --git a/plugins/skrooge/skrooge_report/tests/skgtestreportplugin.h b/plugins/skrooge/skrooge_report/tests/skgtestreportplugin.h
index 2f7824e83..6f03a0e13 100644
--- a/plugins/skrooge/skrooge_report/tests/skgtestreportplugin.h
+++ b/plugins/skrooge/skrooge_report/tests/skgtestreportplugin.h
@@ -1,35 +1,35 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGTESTREPORTPLUGIN_H
#define SKGTESTREPORTPLUGIN_H
/** @file
* This file is a test for SKGReportPlugin component.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include <qtest.h>
/**
* A unit test
*/
class SKGTESTReportPlugin: public QObject
{
Q_OBJECT
private Q_SLOTS:
void TestPlugin();
};
#endif
diff --git a/plugins/skrooge/skrooge_scheduled/CMakeLists.txt b/plugins/skrooge/skrooge_scheduled/CMakeLists.txt
index 247f7d060..db2d1b5e3 100644
--- a/plugins/skrooge/skrooge_scheduled/CMakeLists.txt
+++ b/plugins/skrooge/skrooge_scheduled/CMakeLists.txt
@@ -1,40 +1,40 @@
#***************************************************************************
#* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
#* *
#* 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 <http://www.gnu.org/licenses/> *
+#* along with this program. If not, see <https://www.gnu.org/licenses/> *
#***************************************************************************
MESSAGE( STATUS "..:: CMAKE PLUGIN_SCHEDULED ::..")
PROJECT(plugin_scheduled)
LINK_DIRECTORIES (${LIBRARY_OUTPUT_PATH})
SET(skrooge_scheduled_SRCS
skgscheduledplugin.cpp
skgscheduledpluginwidget.cpp
skgscheduledboardwidget.cpp
)
ki18n_wrap_ui(skrooge_scheduled_SRCS skgscheduledpluginwidget_base.ui skgscheduledpluginwidget_pref.ui)
kconfig_add_kcfg_files(skrooge_scheduled_SRCS skgscheduled_settings.kcfgc )
ADD_LIBRARY(skrooge_scheduled MODULE ${skrooge_scheduled_SRCS})
TARGET_LINK_LIBRARIES(skrooge_scheduled KF5::Parts KF5::ItemViews skgbasemodeler skgbasegui skgbankmodeler skgbankgui)
########### install files ###############
INSTALL(TARGETS skrooge_scheduled DESTINATION ${KDE_INSTALL_QTPLUGINDIR})
INSTALL(FILES ${PROJECT_SOURCE_DIR}/org.kde.skrooge-plugin-scheduled.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR})
INSTALL(FILES ${PROJECT_SOURCE_DIR}/skrooge_scheduled.rc DESTINATION ${KDE_INSTALL_KXMLGUI5DIR}/skrooge_scheduled )
INSTALL(FILES ${PROJECT_SOURCE_DIR}/skgscheduled_settings.kcfg DESTINATION ${KDE_INSTALL_KCFGDIR} )
diff --git a/plugins/skrooge/skrooge_scheduled/org.kde.skrooge-plugin-scheduled.desktop b/plugins/skrooge/skrooge_scheduled/org.kde.skrooge-plugin-scheduled.desktop
index 20c566fbd..d65cd592b 100644
--- a/plugins/skrooge/skrooge_scheduled/org.kde.skrooge-plugin-scheduled.desktop
+++ b/plugins/skrooge/skrooge_scheduled/org.kde.skrooge-plugin-scheduled.desktop
@@ -1,76 +1,76 @@
[Desktop Entry]
Name=Skrooge scheduled plugin
Name[bs]=Skrooge dodatak za planiranje
Name[ca]=Connector de planificació de l'Skrooge
Name[ca@valencia]=Connector de planificació de l'Skrooge
Name[cs]=Modul plánování pro Skrooge
Name[da]=Skemalægnings-plugin til Skrooge
Name[de]=Skrooge-Modul für geplante Aktionen
Name[el]=Skrooge scheduled plugin
Name[en_GB]=Skrooge scheduled plugin
Name[es]=Complemento de planificación de Skrooge
Name[et]=Skrooge ajaplaaniplugin
Name[fi]=Skroogen ajastusliitännäinen
Name[fr]=Module externe Skrooge pour la gestion des opérations programmées
Name[gl]=Complemento de planificación de Skrooge
Name[hu]=Skrooge ütemezett bővítmény
Name[it]=Estensione di pianificazione di Skrooge
Name[lt]=Skrooge suplanuotos operacijų papildinys
Name[nb]=Skrooge tidsplanmodul
Name[nds]=Plaanmoduul för Skrooge
Name[nl]=Plugin voor Skrooge-bewerkingen plannen
Name[pl]=Wtyczka harmonogramu dla Skrooge
Name[pt]='Plugin' calendarizado do Skrooge
Name[pt_BR]=Plugin de agendamento do Skrooge
Name[ru]=Модуль плановых операций
Name[sk]=Plugin plánovacia Skrooge
Name[sv]=Skrooge schemaläggningsinsticksprogram
Name[tr]=Skrooge zamanlama eklentisi
Name[uk]=Додаток розкладу Skrooge
Name[x-test]=xxSkrooge scheduled pluginxx
Name[zh_TW]=Skrooge 排程外掛程式
Comment=A skrooge plugin to manage scheduled operations
Comment[bs]=Skrooge dodatak za upravljanje planiranim operacijama
Comment[ca]=Un connector de l'Skrooge per gestionar operacions planificades
Comment[ca@valencia]=Un connector de l'Skrooge per gestionar operacions planificades
Comment[cs]=Modul Skrooge pro správu naplánovaných operací
Comment[da]=Et Skrooge-plugin til at håndtere skemalagte operationer
Comment[de]=Ein Skrooge-Modul zum Verwalten von geplanten Vorgängen
Comment[el]=Ένα πρόσθετο του skrooge για τη διαχείριση προγραμματισμένων λειτουργιών
Comment[en_GB]=A skrooge plugin to manage scheduled operations
Comment[es]=Un complemento de Skrooge para planificar operaciones
Comment[et]=Skrooge planeeritud tehingute haldamise plugin
Comment[fi]=Skroogen ajastuksenhallintaliitännäinen
Comment[fr]=Un module externe Skrooge pour la gestion des opérations programmées
Comment[gl]=Un complemento de Skrooge para xestionar operacións planificadas.
Comment[hu]=Egy Skrooge bővítmény ütemezett műveletek kezeléséhez
Comment[it]=Un'estensione di Skrooge per gestire le operazioni pianificate
Comment[lt]=Skrooge suplanuotų operacijų tvarkymo papildinys
Comment[nb]=En Skrooge-modul for å håndtere planlagte operasjoner
Comment[nds]=En Moduul för de Pleeg vun plaant Akschonen för Skrooge
Comment[nl]=Een skrooge-plugin voor het beheren van geplande bewerkingen
Comment[pl]=Wtyczka Skrooge do obsługi zaplanowanych operacji
Comment[pt]=Um 'plugin' do Skrooge para gerir as operações agendadas
Comment[pt_BR]=Um plugin do Skrooge para gerenciar operações agendadas
Comment[ru]=Модуль плановых операций
Comment[sk]=Plugin Skrooge na správu plánovaných operácií
Comment[sv]=Ett insticksprogram till Skrooge för att hantera schemalagda ärenden
Comment[tr]=Zamanlanmış işlemleri yönetmek için bir Skrooge eklentisi
Comment[uk]=Додаток до skrooge для керування розкладом дій
Comment[x-test]=xxA skrooge plugin to manage scheduled operationsxx
Comment[zh_TW]=管理排程操作用的 Skrooge 外掛程式
Encoding=UTF-8
Icon=skrooge
Type=Service
X-KDE-ServiceTypes=SKG GUI/Plugin
X-KDE-Library=skrooge_scheduled
X-Krunner-ID=Skrooge scheduled plugin
X-KDE-PluginInfo-Author=Stephane MANKOWSKI,miraks
X-KDE-PluginInfo-Email=stephane@mankowski.fr
X-KDE-PluginInfo-Name=skrooge_scheduled
X-KDE-PluginInfo-Version=1.0
-X-KDE-PluginInfo-Website=http://skrooge.org/
+X-KDE-PluginInfo-Website=https://skrooge.org/
X-KDE-PluginInfo-Category=Plugins
X-KDE-PluginInfo-Depends=
X-KDE-PluginInfo-License=GPL
X-KDE-PluginInfo-EnabledByDefault=true
diff --git a/plugins/skrooge/skrooge_scheduled/skgscheduledboardwidget.cpp b/plugins/skrooge/skrooge_scheduled/skgscheduledboardwidget.cpp
index 0a34f505f..db2dcdd93 100644
--- a/plugins/skrooge/skrooge_scheduled/skgscheduledboardwidget.cpp
+++ b/plugins/skrooge/skrooge_scheduled/skgscheduledboardwidget.cpp
@@ -1,100 +1,100 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is Skrooge plugin for scheduled operation management.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgscheduledboardwidget.h"
#include <qdom.h>
#include <qaction.h>
#include <qqmlcontext.h>
#include <qquickwidget.h>
#include <qwidgetaction.h>
#include "skgdocumentbank.h"
#include "skgmainpanel.h"
#include "skgobjectbase.h"
#include "skgperiodedit.h"
#include "skgreportbank.h"
#include "skgservices.h"
#include "skgtraces.h"
SKGScheduledBoardWidget::SKGScheduledBoardWidget(QWidget* iParent, SKGDocument* iDocument)
: SKGHtmlBoardWidget(iParent, iDocument, i18nc("Noun, the title of a section", "Scheduled operations"),
QStandardPaths::locate(QStandardPaths::GenericDataLocation, QStringLiteral("skrooge/html/default/scheduled_operations.") %
(SKGMainPanel::getMainPanel()->getPluginByName(QStringLiteral("Dashboard plugin"))->getPreferenceSkeleton()->findItem(QStringLiteral("qmlmode"))->property().toBool() ? QStringLiteral("qml") : QStringLiteral("html"))),
QStringList() << QStringLiteral("v_recurrentoperation_display"))
{
SKGTRACEINFUNC(10)
m_daysmax = new SKGComboBox(this);
m_daysmax->addItem(i18nc("Item in a combo box", "For 5 next days"), "5");
m_daysmax->addItem(i18nc("Item in a combo box", "For 10 next days"), "10");
m_daysmax->addItem(i18nc("Item in a combo box", "For 15 next days"), "15");
m_daysmax->addItem(i18nc("Item in a combo box", "For 30 next days"), "30");
m_daysmax->addItem(i18nc("Item in a combo box", "For 60 next days"), "60");
m_daysmax->addItem(i18nc("Item in a combo box", "For 90 next days"), "90");
// Add widget in menu
auto daysmaxWidget = new QWidgetAction(this);
daysmaxWidget->setObjectName(QStringLiteral("daysmaxWidget"));
daysmaxWidget->setDefaultWidget(m_daysmax);
addAction(daysmaxWidget);
connect(m_daysmax, static_cast<void (SKGComboBox::*)(const QString&)>(&SKGComboBox::currentTextChanged), this, [ = ]() {
this->dataModified();
});
}
SKGScheduledBoardWidget::~SKGScheduledBoardWidget()
{
SKGTRACEINFUNC(10)
}
QString SKGScheduledBoardWidget::getState()
{
QDomDocument doc(QStringLiteral("SKGML"));
QDomElement root = doc.createElement(QStringLiteral("parameters"));
doc.appendChild(root);
root.setAttribute(QStringLiteral("daysmax"), (m_daysmax != nullptr ? m_daysmax->currentData().toString() : QStringLiteral("30")));
return doc.toString();
}
void SKGScheduledBoardWidget::setState(const QString& iState)
{
QDomDocument doc(QStringLiteral("SKGML"));
doc.setContent(iState);
QDomElement root = doc.documentElement();
QString daysmax = root.attribute(QStringLiteral("daysmax"));
if (daysmax.isEmpty()) {
daysmax = QStringLiteral("30");
}
if (m_daysmax != nullptr && !daysmax.isEmpty()) {
m_daysmax->setCurrentIndex(m_daysmax->findData(daysmax));
}
}
void SKGScheduledBoardWidget::dataModified(const QString& iTableName, int iIdTransaction)
{
m_Report->addParameter(QStringLiteral("scheduled_operation_days_max"), m_daysmax->currentData());
SKGHtmlBoardWidget::dataModified(iTableName, iIdTransaction);
}
diff --git a/plugins/skrooge/skrooge_scheduled/skgscheduledboardwidget.h b/plugins/skrooge/skrooge_scheduled/skgscheduledboardwidget.h
index de79987cc..399a913fa 100644
--- a/plugins/skrooge/skrooge_scheduled/skgscheduledboardwidget.h
+++ b/plugins/skrooge/skrooge_scheduled/skgscheduledboardwidget.h
@@ -1,69 +1,69 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGSCHEDULEDBOARDWIDGET_H
#define SKGSCHEDULEDBOARDWIDGET_H
/** @file
* This file is Skrooge plugin for scheduled operation management.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skghtmlboardwidget.h"
/**
* This file is Skrooge plugin for scheduled operation management
*/
class SKGScheduledBoardWidget : public SKGHtmlBoardWidget
{
Q_OBJECT
public:
/**
* Default Constructor
* @param iParent the parent widget
* @param iDocument the document
*/
explicit SKGScheduledBoardWidget(QWidget* iParent, SKGDocument* iDocument);
/**
* Default Destructor
*/
~SKGScheduledBoardWidget() override;
/**
* Get the current state
* MUST BE OVERWRITTEN
* @return a string containing all information needed to set the same state.
* Could be an XML stream
*/
QString getState() override;
/**
* Set the current state
* MUST BE OVERWRITTEN
* @param iState must be interpreted to set the state of the widget
*/
void setState(const QString& iState) override;
protected Q_SLOTS:
void dataModified(const QString& iTableName = QString(), int iIdTransaction = 0) override;
private:
Q_DISABLE_COPY(SKGScheduledBoardWidget)
SKGComboBox* m_daysmax;
};
#endif // SKGSCHEDULEDBOARDWIDGET_H
diff --git a/plugins/skrooge/skrooge_scheduled/skgscheduledplugin.cpp b/plugins/skrooge/skrooge_scheduled/skgscheduledplugin.cpp
index 0b38a2d08..e2f41c6ac 100644
--- a/plugins/skrooge/skrooge_scheduled/skgscheduledplugin.cpp
+++ b/plugins/skrooge/skrooge_scheduled/skgscheduledplugin.cpp
@@ -1,571 +1,571 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* A skrooge plugin to manage scheduled operations
*
* @author Stephane MANKOWSKI
*/
#include "skgscheduledplugin.h"
#include <kaboutdata.h>
#include <kactioncollection.h>
#include <kpluginfactory.h>
#include <qstandardpaths.h>
#include "skgdocumentbank.h"
#include "skgmainpanel.h"
#include "skgrecurrentoperationobject.h"
#include "skgscheduled_settings.h"
#include "skgscheduledboardwidget.h"
#include "skgscheduledpluginwidget.h"
#include "skgsuboperationobject.h"
#include "skgtraces.h"
#include "skgtransactionmng.h"
/**
* This plugin factory.
*/
K_PLUGIN_FACTORY(SKGScheduledPluginFactory, registerPlugin<SKGScheduledPlugin>();)
SKGScheduledPlugin::SKGScheduledPlugin(QWidget* iWidget, QObject* iParent, const QVariantList& /*iArg*/) :
SKGInterfacePlugin(iParent), m_currentBankDocument(nullptr), m_counterAdvice(0)
{
Q_UNUSED(iWidget)
SKGTRACEINFUNC(10)
}
SKGScheduledPlugin::~SKGScheduledPlugin()
{
SKGTRACEINFUNC(10)
m_currentBankDocument = nullptr;
}
bool SKGScheduledPlugin::setupActions(SKGDocument* iDocument)
{
SKGTRACEINFUNC(10)
m_currentBankDocument = qobject_cast<SKGDocumentBank*>(iDocument);
if (m_currentBankDocument == nullptr) {
return false;
}
setComponentName(QStringLiteral("skrooge_scheduled"), title());
setXMLFile(QStringLiteral("skrooge_scheduled.rc"));
// Create yours actions here
auto actScheduleOperation = new QAction(SKGServices::fromTheme(icon()), i18nc("Verb, create a scheduled operation", "Schedule"), this);
connect(actScheduleOperation, &QAction::triggered, this, &SKGScheduledPlugin::onScheduleOperation);
actionCollection()->setDefaultShortcut(actScheduleOperation, Qt::CTRL + Qt::Key_I);
registerGlobalAction(QStringLiteral("schedule_operation"), actScheduleOperation, QStringList() << QStringLiteral("operation"), 1, -1, 410);
auto actSkipScheduledOperation = new QAction(SKGServices::fromTheme(QStringLiteral("nextuntranslated")), i18nc("Verb, skip scheduled operations", "Skip"), this);
connect(actSkipScheduledOperation, &QAction::triggered, this, &SKGScheduledPlugin::onSkipScheduledOperations);
registerGlobalAction(QStringLiteral("skip_scheduled_operations"), actSkipScheduledOperation, QStringList() << QStringLiteral("recurrentoperation"), 1, -1, 410);
return true;
}
void SKGScheduledPlugin::refresh()
{
SKGTRACEINFUNC(10)
// Automatic insert
if ((m_currentBankDocument != nullptr) && m_currentBankDocument->getMainDatabase() != nullptr) {
QString doc_id = m_currentBankDocument->getUniqueIdentifier();
if (m_docUniqueIdentifier != doc_id && m_currentBankDocument->getParameter(QStringLiteral("SKG_DB_BANK_VERSION")) >= QStringLiteral("0.5")) {
m_docUniqueIdentifier = doc_id;
SKGError err;
// Read Setting
bool check_on_open = skgscheduled_settings::check_on_open();
if (check_on_open) {
SKGBEGINTRANSACTION(*m_currentBankDocument, i18nc("Noun, name of the user action", "Insert recurrent operations"), err)
int nbi = 0;
err = SKGRecurrentOperationObject::process(m_currentBankDocument, nbi);
}
// Display error
SKGMainPanel::displayErrorMessage(err);
}
}
}
int SKGScheduledPlugin::getNbDashboardWidgets()
{
return 1;
}
QString SKGScheduledPlugin::getDashboardWidgetTitle(int iIndex)
{
Q_UNUSED(iIndex)
return i18nc("Noun, the title of a section", "Scheduled operations");
}
SKGBoardWidget* SKGScheduledPlugin::getDashboardWidget(int iIndex)
{
Q_UNUSED(iIndex)
return new SKGScheduledBoardWidget(SKGMainPanel::getMainPanel(), m_currentBankDocument);
}
SKGTabPage* SKGScheduledPlugin::getWidget()
{
SKGTRACEINFUNC(10)
return new SKGScheduledPluginWidget(SKGMainPanel::getMainPanel(), m_currentBankDocument);
}
QWidget* SKGScheduledPlugin::getPreferenceWidget()
{
SKGTRACEINFUNC(10)
auto w = new QWidget();
ui.setupUi(w);
connect(ui.kcfg_remind_me, &QCheckBox::toggled, ui.kcfg_remind_me_days, &QSpinBox::setEnabled);
connect(ui.kcfg_remind_me, &QCheckBox::toggled, ui.label_3, &QSpinBox::setEnabled);
connect(ui.kcfg_nb_times, &QCheckBox::toggled, ui.kcfg_nb_times_val, &QSpinBox::setEnabled);
connect(ui.kcfg_auto_write, &QCheckBox::toggled, ui.kcfg_auto_write_days, &QSpinBox::setEnabled);
connect(ui.kcfg_auto_write, &QCheckBox::toggled, ui.label_4, &QSpinBox::setEnabled);
return w;
}
KConfigSkeleton* SKGScheduledPlugin::getPreferenceSkeleton()
{
return skgscheduled_settings::self();
}
QString SKGScheduledPlugin::title() const
{
return i18nc("Noun", "Scheduled operations");
}
QString SKGScheduledPlugin::icon() const
{
return QStringLiteral("chronometer");
}
QString SKGScheduledPlugin::toolTip() const
{
return i18nc("Noun", "Operations scheduled management");
}
int SKGScheduledPlugin::getOrder() const
{
return 20;
}
QStringList SKGScheduledPlugin::tips() const
{
QStringList output;
output.push_back(i18nc("Description of a tips", "<p>... you can <a href=\"skg://skrooge_scheduled_plugin\">schedule</a> operations or templates.</p>"));
return output;
}
bool SKGScheduledPlugin::isInPagesChooser() const
{
return true;
}
SKGError SKGScheduledPlugin::savePreferences() const
{
SKGError err;
if (m_currentBankDocument != nullptr) {
// Read Setting
if (skgscheduled_settings::create_template()) {
SKGObjectBase::SKGListSKGObjectBase recurrents;
err = m_currentBankDocument->getObjects(QStringLiteral("v_recurrentoperation"), QStringLiteral("(select count(1) from operation where operation.id=rd_operation_id and t_template='N')=1"), recurrents);
int nb = recurrents.count();
if (nb != 0) {
SKGBEGINPROGRESSTRANSACTION(*m_currentBankDocument, i18nc("Noun, name of the user action", "Conversion schedule"), err, nb)
for (int i = 0; !err && i < nb; ++i) {
// Migration of existing schedule in template mode
SKGRecurrentOperationObject recOp(recurrents.at(i));
SKGOperationObject operationObj;
IFOK(err) recOp.getParentOperation(operationObj);
SKGOperationObject operationObjOrig = operationObj;
IFOKDO(err, operationObjOrig.duplicate(operationObj, operationObjOrig.getDate(), true))
IFOKDO(err, recOp.setParentOperation(operationObj))
IFOKDO(err, recOp.save())
IFOKDO(err, recOp.load())
IFOKDO(err, operationObjOrig.setAttribute(QStringLiteral("r_recurrentoperation_id"), SKGServices::intToString(recOp.getID())))
IFOKDO(err, operationObjOrig.save())
IFOKDO(err, m_currentBankDocument->stepForward(i + 1))
}
IFOK(err) m_currentBankDocument->sendMessage(i18nc("An information message", "All scheduled operations have been converted in template"));
}
}
}
return err;
}
SKGError SKGScheduledPlugin::scheduleOperation(const SKGOperationObject& iOperation, SKGRecurrentOperationObject& oRecurrent) const
{
SKGError err;
SKGOperationObject operationObjDuplicate = iOperation;
bool isTemplate = operationObjDuplicate.isTemplate();
SKGOperationObject operationObjOrig;
if (!isTemplate && skgscheduled_settings::create_template()) {
// The selected operation is not a template and settings is set to create one
operationObjOrig = operationObjDuplicate;
IFOKDO(err, operationObjOrig.duplicate(operationObjDuplicate, operationObjOrig.getDate(), true))
IFOK(err) m_currentBankDocument->sendMessage(i18nc("An information message", "A template has been created"), SKGDocument::Positive);
}
SKGRecurrentOperationObject recOp;
err = operationObjDuplicate.addRecurrentOperation(recOp);
IFOKDO(err, recOp.warnEnabled(skgscheduled_settings::remind_me()))
IFOKDO(err, recOp.setWarnDays(skgscheduled_settings::remind_me_days()))
IFOKDO(err, recOp.autoWriteEnabled(skgscheduled_settings::auto_write()))
IFOKDO(err, recOp.setAutoWriteDays(skgscheduled_settings::auto_write_days()))
IFOKDO(err, recOp.timeLimit(skgscheduled_settings::nb_times()))
IFOKDO(err, recOp.setTimeLimit(skgscheduled_settings::nb_times_val()))
IFOKDO(err, recOp.setPeriodIncrement(skgscheduled_settings::once_every()))
IFOKDO(err, recOp.setPeriodUnit(static_cast<SKGRecurrentOperationObject::PeriodUnit>(SKGServices::stringToInt(skgscheduled_settings::once_every_unit()))))
if (!err && !isTemplate) {
err = recOp.setDate(recOp.getNextDate());
}
IFOKDO(err, recOp.save())
if (!isTemplate && skgscheduled_settings::create_template()) {
IFOKDO(err, recOp.load())
IFOKDO(err, operationObjOrig.setAttribute(QStringLiteral("r_recurrentoperation_id"), SKGServices::intToString(recOp.getID())))
IFOKDO(err, operationObjOrig.save())
}
oRecurrent = recOp;
return err;
}
void SKGScheduledPlugin::onScheduleOperation()
{
SKGError err;
SKGTRACEINFUNCRC(10, err)
// Get Selection
if (SKGMainPanel::getMainPanel() != nullptr) {
SKGObjectBase::SKGListSKGObjectBase selection = SKGMainPanel::getMainPanel()->getSelectedObjects();
int nb = selection.count();
if ((nb != 0) && (m_currentBankDocument != nullptr)) {
QStringList list;
SKGBEGINPROGRESSTRANSACTION(*m_currentBankDocument, i18nc("Noun, name of the user action", "Operation schedule"), err, nb)
for (int i = 0; !err && i < nb; ++i) {
SKGOperationObject operationObj(selection.at(i));
SKGRecurrentOperationObject rop;
err = scheduleOperation(operationObj, rop);
// Send message
IFOKDO(err, m_currentBankDocument->sendMessage(i18nc("An information to the user", "The operation '%1' has been scheduled", operationObj.getDisplayName()), SKGDocument::Hidden))
IFOKDO(err, m_currentBankDocument->stepForward(i + 1))
list.push_back(operationObj.getUniqueID());
}
IFOK(err) {
// Open the scheduled operation
SKGMainPanel::getMainPanel()->openPage("skg://skrooge_scheduled_plugin/?selection=" % SKGServices::encodeForUrl(SKGServices::stringsToCsv(list)));
}
}
// status bar
IFOKDO(err, SKGError(0, i18nc("Successful message after an user action", "Operation scheduled.")))
else {
err.addError(ERR_FAIL, i18nc("Error message", "Operation schedule failed"));
}
// Display error
SKGMainPanel::displayErrorMessage(err);
}
}
void SKGScheduledPlugin::onSkipScheduledOperations()
{
SKGError err;
SKGTRACEINFUNCRC(10, err)
// Get Selection
if (SKGMainPanel::getMainPanel() != nullptr) {
SKGObjectBase::SKGListSKGObjectBase selection;
auto selectionString = sender()->property("selection").toString();
if (!selectionString.isEmpty()) {
selection.append(SKGRecurrentOperationObject(m_currentBankDocument, SKGServices::stringToInt(SKGServices::splitCSVLine(selectionString, QLatin1Char('-'), false).at(0))));
} else {
selection = SKGMainPanel::getMainPanel()->getSelectedObjects();
}
int nb = selection.count();
if ((nb != 0) && (m_currentBankDocument != nullptr)) {
QStringList list;
SKGBEGINPROGRESSTRANSACTION(*m_currentBankDocument, i18nc("Noun, name of the user action", "Skip scheduled operations"), err, nb)
for (int i = 0; !err && i < nb; ++i) {
SKGRecurrentOperationObject rop(m_currentBankDocument, selection.at(i).getID());
err = rop.setDate(rop.getNextDate());
if (!err && rop.hasTimeLimit()) {
err = rop.setTimeLimit(rop.getTimeLimit() - 1);
}
IFOKDO(err, rop.save())
IFOKDO(err, m_currentBankDocument->stepForward(i + 1))
list.push_back(rop.getUniqueID());
}
}
// status bar
IFOKDO(err, SKGError(0, i18nc("Successful message after an user action", "Scheduled operations skipped.")))
else {
err.addError(ERR_FAIL, i18nc("Error message", "Skip of scheduled operation failed"));
}
// Display error
SKGMainPanel::displayErrorMessage(err);
}
}
SKGAdviceList SKGScheduledPlugin::advice(const QStringList& iIgnoredAdvice)
{
SKGTRACEINFUNC(10)
SKGAdviceList output;
output.reserve(20);
// Recurrent operation with the last inserted operation having a different amount
if (!iIgnoredAdvice.contains(QStringLiteral("skgscheduledplugin_notuptodate"))) {
SKGStringListList result;
m_currentBankDocument->executeSelectSqliteOrder("SELECT r.id, r.rd_operation_id, r.f_CURRENTAMOUNT, r2.f_CURRENTAMOUNT FROM v_recurrentoperation_display r INNER JOIN (SELECT MAX(d_date), f_CURRENTAMOUNT, r_recurrentoperation_id FROM v_operation_display GROUP BY r_recurrentoperation_id) r2 WHERE r2.r_recurrentoperation_id=r.id AND ABS(r.f_CURRENTAMOUNT-r2.f_CURRENTAMOUNT)>" % SKGServices::doubleToString(EPSILON), result);
int nb = result.count();
SKGAdvice::SKGAdviceActionList autoCorrections;
for (int i = 1; i < nb; ++i) { // Ignore header
// Get parameters
const QStringList& line = result.at(i);
int idRecu = SKGServices::stringToInt(line.at(0));
const QString& idOper = line.at(1);
const QString& amountLastOperation = line.at(3);
SKGRecurrentOperationObject recu(m_currentBankDocument, idRecu);
QString name = recu.getDisplayName();
SKGAdvice ad;
ad.setUUID("skgscheduledplugin_notuptodate|" % idOper % ';' % amountLastOperation);
ad.setPriority(4);
ad.setShortMessage(i18nc("Advice on making the best (short)", "Scheduled operation '%1' not uptodate", name));
ad.setLongMessage(i18nc("Advice on making the best (long)", "The scheduled operation '%1' does not have the amount of the last inserted operation (%2)", name, amountLastOperation));
autoCorrections.resize(0);
{
SKGAdvice::SKGAdviceAction a;
a.Title = i18nc("Advice on making the best (action)", "Update the next scheduled operation amount (%1)", amountLastOperation);
a.IconName = QStringLiteral("system-run");
a.IsRecommended = true;
autoCorrections.push_back(a);
}
ad.setAutoCorrections(autoCorrections);
output.push_back(ad);
}
}
// Recurrent operation with the last inserted operation having a different date
if (!iIgnoredAdvice.contains(QStringLiteral("skgscheduledplugin_newdate"))) {
SKGStringListList result;
m_currentBankDocument->executeSelectSqliteOrder(QStringLiteral("SELECT r.id, r.d_date, "
"date(r2.d_date, '+'||((CASE r.t_period_unit WHEN 'W' THEN 7 ELSE 1 END)*r.i_period_increment)||' '||(CASE r.t_period_unit WHEN 'M' THEN 'month' WHEN 'Y' THEN 'year' ELSE 'day' END)) "
"FROM v_recurrentoperation_display r "
"INNER JOIN (SELECT MAX(d_date) as d_date, r_recurrentoperation_id FROM v_operation_display GROUP BY r_recurrentoperation_id) r2 "
"WHERE r2.r_recurrentoperation_id=r.id AND r.d_PREVIOUS!=r2.d_date"), result);
int nb = result.count();
SKGAdvice::SKGAdviceActionList autoCorrections;
for (int i = 1; i < nb; ++i) { // Ignore header
// Get parameters
const QStringList& line = result.at(i);
int idRecu = SKGServices::stringToInt(line.at(0));
const QString& currentDate = line.at(1);
const QString& newDate = line.at(2);
if (SKGServices::stringToTime(newDate).date() > QDate::currentDate() && SKGServices::stringToTime(newDate).date() != SKGServices::stringToTime(currentDate).date()) {
SKGRecurrentOperationObject recu(m_currentBankDocument, idRecu);
QString name = recu.getDisplayName();
SKGAdvice ad;
ad.setUUID("skgscheduledplugin_newdate|" % line.at(0) % ';' % newDate);
ad.setPriority(4);
ad.setShortMessage(i18nc("Advice on making the best (short)", "Scheduled operation '%1' not uptodate", name));
ad.setLongMessage(i18nc("Advice on making the best (long)", "The scheduled operation '%1' does not have the date aligned with the last inserted operation (%2)", name, currentDate));
autoCorrections.resize(0);
{
SKGAdvice::SKGAdviceAction a;
a.Title = i18nc("Advice on making the best (action)", "Update the next scheduled operation date (%1)", newDate);
a.IconName = QStringLiteral("system-run");
a.IsRecommended = true;
autoCorrections.push_back(a);
}
ad.setAutoCorrections(autoCorrections);
output.push_back(ad);
}
}
}
// Possible recurrent operations
if (!iIgnoredAdvice.contains(QStringLiteral("skgscheduledplugin_possibleschedule"))) {
SKGStringListList result;
m_currentBankDocument->executeSelectSqliteOrder(QStringLiteral("SELECT op1.id, op1.t_displayname FROM v_operation_displayname op1 WHERE op1.id||'#'||op1.f_QUANTITY IN (SELECT op1.id||'#'||op2.f_QUANTITY FROM operation op1, v_operation_tmp1 op2 "
"WHERE op1.rd_account_id=op2.rd_account_id AND op1.r_payee_id=op2.r_payee_id AND op1.rc_unit_id=op2.rc_unit_id "
"AND op1.r_recurrentoperation_id=0 AND op1.d_date<>'0000-00-00' AND op1.d_date=date(op2.d_date, '+1 month') "
"AND op1.d_date>(SELECT date('now','-2 month')) AND op2.d_date>(SELECT date('now','-3 month'))) "
"AND op1.t_TRANSFER='N' "
"AND NOT EXISTS (SELECT 1 FROM recurrentoperation ro, v_operation_tmp1 rop WHERE ro.rd_operation_id=rop.id AND ro.i_period_increment=1 AND ro.t_period_unit='M' AND op1.rd_account_id=rop.rd_account_id AND op1.r_payee_id=rop.r_payee_id AND op1.f_QUANTITY=rop.f_QUANTITY AND op1.rc_unit_id=rop.rc_unit_id)"), result);
int nb = result.count();
SKGAdvice::SKGAdviceActionList autoCorrections;
autoCorrections.reserve(nb);
for (int i = 1; i < nb; ++i) { // Ignore header
// Get parameters
const QStringList& line = result.at(i);
const QString& id = line.at(0);
const QString& name = line.at(1);
SKGAdvice ad;
ad.setUUID("skgscheduledplugin_possibleschedule|" % id);
ad.setPriority(4);
ad.setShortMessage(i18nc("Advice on making the best (short)", "Possible schedule '%1'", name));
ad.setLongMessage(i18nc("Advice on making the best (long)", "The operation '%1' seems to be regularly created and could be scheduled", name));
autoCorrections.resize(0);
{
SKGAdvice::SKGAdviceAction a;
a.Title = i18nc("Advice on making the best (action)", "Monthly schedule the operation '%1'", name);
a.IconName = icon();
a.IsRecommended = false;
autoCorrections.push_back(a);
}
ad.setAutoCorrections(autoCorrections);
output.push_back(ad);
}
}
m_counterAdvice++;
return output;
}
SKGError SKGScheduledPlugin::executeAdviceCorrection(const QString& iAdviceIdentifier, int iSolution)
{
SKGError err;
if ((m_currentBankDocument != nullptr) && iAdviceIdentifier.startsWith(QLatin1String("skgscheduledplugin_notuptodate|"))) {
// Get parameters
QString parameters = iAdviceIdentifier.right(iAdviceIdentifier.length() - 31);
int pos = parameters.indexOf(';');
int idOper = SKGServices::stringToInt(parameters.left(pos));
double amount = SKGServices::stringToDouble(parameters.right(parameters.length() - 1 - pos));
// Update the operation
{
SKGBEGINTRANSACTION(*m_currentBankDocument, i18nc("Noun, name of the user action", "Update scheduled operation"), err)
SKGOperationObject op(m_currentBankDocument, idOper);
SKGObjectBase::SKGListSKGObjectBase subOps;
IFOKDO(err, op.getSubOperations(subOps))
if (subOps.count() == 1) {
// Change the quantity of the sub operation
SKGSubOperationObject so1(subOps.at(0));
IFOKDO(err, so1.setQuantity(amount))
IFOKDO(err, so1.save())
} else if (subOps.count() >= 1) {
// Add a split
SKGSubOperationObject so1;
IFOKDO(err, op.addSubOperation(so1))
IFOKDO(err, so1.setQuantity(amount - op.getCurrentAmount()))
IFOKDO(err, so1.save())
}
// Send message
IFOKDO(err, op.getDocument()->sendMessage(i18nc("An information to the user", "The amount of the scheduled operation of '%1' have been updated", op.getDisplayName()), SKGDocument::Hidden))
}
// status bar
IFOKDO(err, SKGError(0, i18nc("Successful message after an user action", "Scheduled operation updated.")))
else {
err.addError(ERR_FAIL, i18nc("Error message", "Update failed"));
}
// Display error
SKGMainPanel::displayErrorMessage(err);
return err;
}
if ((m_currentBankDocument != nullptr) && iAdviceIdentifier.startsWith(QLatin1String("skgscheduledplugin_newdate|"))) {
// Get parameters
QString parameters = iAdviceIdentifier.right(iAdviceIdentifier.length() - 27);
int pos = parameters.indexOf(';');
int id = SKGServices::stringToInt(parameters.left(pos));
QString newDate = parameters.right(parameters.length() - 1 - pos);
// Update the operation
{
SKGBEGINTRANSACTION(*m_currentBankDocument, i18nc("Noun, name of the user action", "Update scheduled operation"), err)
SKGRecurrentOperationObject rop(m_currentBankDocument, id);
IFOKDO(err, rop.setDate(SKGServices::stringToTime(newDate).date()))
IFOKDO(err, rop.save())
// Send message
IFOKDO(err, rop.getDocument()->sendMessage(i18nc("An information to the user", "The date of the scheduled operation of '%1' have been updated", rop.getDisplayName()), SKGDocument::Hidden))
}
// status bar
IFOKDO(err, SKGError(0, i18nc("Successful message after an user action", "Scheduled operation updated.")))
else {
err.addError(ERR_FAIL, i18nc("Error message", "Update failed"));
}
// Display error
SKGMainPanel::displayErrorMessage(err);
return err;
}
if ((m_currentBankDocument != nullptr) && iAdviceIdentifier.startsWith(QLatin1String("skgscheduledplugin_possibleschedule|"))) {
// Get parameters
int idOper = SKGServices::stringToInt(iAdviceIdentifier.right(iAdviceIdentifier.length() - 36));
// Update the operation
{
SKGBEGINTRANSACTION(*m_currentBankDocument, i18nc("Noun, name of the user action", "Scheduled operation"), err)
SKGOperationObject op(m_currentBankDocument, idOper);
SKGRecurrentOperationObject rop;
err = scheduleOperation(op, rop);
IFOKDO(err, rop.setPeriodUnit(SKGRecurrentOperationObject::MONTH))
IFOKDO(err, rop.setPeriodIncrement(1))
IFOKDO(err, rop.setDate(op.getDate()))
IFOKDO(err, rop.setDate(rop.getNextDate()))
IFOKDO(err, rop.save())
// Send message
IFOKDO(err, rop.getDocument()->sendMessage(i18nc("An information to the user", "The scheduled operation of '%1' have been added", rop.getDisplayName()), SKGDocument::Hidden))
m_counterAdvice = 0; // To force the update
}
// status bar
IFOKDO(err, SKGError(0, i18nc("Successful message after an user action", "Operation scheduled.")))
else {
err.addError(ERR_FAIL, i18nc("Error message", "Schedule failed"));
}
// Display error
SKGMainPanel::displayErrorMessage(err);
return err;
}
return SKGInterfacePlugin::executeAdviceCorrection(iAdviceIdentifier, iSolution);
}
#include <skgscheduledplugin.moc>
diff --git a/plugins/skrooge/skrooge_scheduled/skgscheduledplugin.h b/plugins/skrooge/skrooge_scheduled/skgscheduledplugin.h
index 335d1b3c9..cbfbdf707 100644
--- a/plugins/skrooge/skrooge_scheduled/skgscheduledplugin.h
+++ b/plugins/skrooge/skrooge_scheduled/skgscheduledplugin.h
@@ -1,175 +1,175 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGSCHEDULEDPLUGIN_H
#define SKGSCHEDULEDPLUGIN_H
/** @file
* A skrooge plugin to manage scheduled operations.
*
* @author Stephane MANKOWSKI
*/
#include "skginterfaceplugin.h"
#include "skgoperationobject.h"
#include "ui_skgscheduledpluginwidget_pref.h"
class SKGDocumentBank;
/**
* A skrooge plugin to manage scheduled operations
*/
class SKGScheduledPlugin : public SKGInterfacePlugin
{
Q_OBJECT
Q_INTERFACES(SKGInterfacePlugin)
public:
/**
* Default Constructor
*/
explicit SKGScheduledPlugin(QWidget* iWidget, QObject* iParent, const QVariantList& iArg);
/**
* Default Destructor
*/
~SKGScheduledPlugin() override;
/**
* Called to initialise the plugin
* @param iDocument the main document
* @return true if the plugin is compatible with the document
*/
bool setupActions(SKGDocument* iDocument) override;
/**
* The number of dashboard widgets of the plugin.
* @return The number of dashboard widgets of the plugin
*/
int getNbDashboardWidgets() override;
/**
* Get a dashboard widget title of the plugin.
* @param iIndex the index of the widget
* @return The title
*/
QString getDashboardWidgetTitle(int iIndex) override;
/**
* Get a dashboard widget of the plugin.
* @param iIndex the index of the widget
* @return The dashboard widget of the plugin
*/
SKGBoardWidget* getDashboardWidget(int iIndex) override;
/**
* Must be modified to refresh widgets after a modification.
*/
void refresh() override;
/**
* The preference widget of the plugin.
* @return The preference widget of the plugin
*/
QWidget* getPreferenceWidget() override;
/**
* The preference skeleton of the plugin.
* @return The preference skeleton of the plugin
*/
KConfigSkeleton* getPreferenceSkeleton() override;
/**
* This function is called when preferences have been modified. Must be used to save some parameters into the document.
* A transaction is already opened
* @return an object managing the error.
* @see SKGError
*/
SKGError savePreferences() const override;
/**
* The page widget of the plugin.
* @return The page widget of the plugin
*/
SKGTabPage* getWidget() override;
/**
* The title of the plugin.
* @return The title of the plugin
*/
QString title() const override;
/**
* The icon of the plugin.
* @return The icon of the plugin
*/
QString icon() const override;
/**
* The toolTip of the plugin.
* @return The toolTip of the plugin
*/
QString toolTip() const override;
/**
* The tips list of the plugin.
* @return The tips list of the plugin
*/
QStringList tips() const override;
/**
* Must be implemented to set the position of the plugin.
* @return integer value between 0 and 999 (default = 999)
*/
int getOrder() const override;
/**
* Must be implemented to know if a plugin must be display in pages chooser.
* @return true of false (default = false)
*/
bool isInPagesChooser() const override;
/**
* The advice list of the plugin.
* @return The advice list of the plugin
*/
SKGAdviceList advice(const QStringList& iIgnoredAdvice) override;
/**
* Must be implemented to execute the automatic correction for the advice.
* @param iAdviceIdentifier the identifier of the advice
* @param iSolution the identifier of the possible solution
* @return an object managing the error. MUST return ERR_NOTIMPL if iAdviceIdentifier is not known
* @see SKGError
*/
SKGError executeAdviceCorrection(const QString& iAdviceIdentifier, int iSolution) override;
private Q_SLOTS:
void onScheduleOperation();
void onSkipScheduledOperations();
private:
Q_DISABLE_COPY(SKGScheduledPlugin)
SKGError scheduleOperation(const SKGOperationObject& iOperation, SKGRecurrentOperationObject& oRecurrent) const;
SKGDocumentBank* m_currentBankDocument;
QString m_docUniqueIdentifier;
Ui::skgscheduledplugin_pref ui{};
int m_counterAdvice;
};
#endif // SKGSCHEDULEDPLUGIN_H
diff --git a/plugins/skrooge/skrooge_scheduled/skgscheduledpluginwidget.cpp b/plugins/skrooge/skrooge_scheduled/skgscheduledpluginwidget.cpp
index b670577ba..0a03579e1 100644
--- a/plugins/skrooge/skrooge_scheduled/skgscheduledpluginwidget.cpp
+++ b/plugins/skrooge/skrooge_scheduled/skgscheduledpluginwidget.cpp
@@ -1,351 +1,351 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* A skrooge plugin to manage scheduled operations.
*
* @author Stephane MANKOWSKI
*/
#include "skgscheduledpluginwidget.h"
#include <qlineedit.h>
#include <qdom.h>
#include <qevent.h>
#include <qheaderview.h>
#include "skgdocumentbank.h"
#include "skgmainpanel.h"
#include "skgobjectmodel.h"
#include "skgoperationobject.h"
#include "skgrecurrentoperationobject.h"
#include "skgtraces.h"
#include "skgtransactionmng.h"
SKGScheduledPluginWidget::SKGScheduledPluginWidget(QWidget* iParent, SKGDocumentBank* iDocument)
: SKGTabPage(iParent, iDocument)
{
SKGTRACEINFUNC(1)
if (iDocument == nullptr) {
return;
}
ui.setupUi(this);
// Define action
if (SKGMainPanel::getMainPanel() != nullptr) {
auto actJumpToOperation = new QAction(SKGServices::fromTheme(QStringLiteral("quickopen")), ui.kJumpBtn->text(), this);
connect(actJumpToOperation, &QAction::triggered, this, &SKGScheduledPluginWidget::onJumpToTheOperation);
SKGMainPanel::getMainPanel()->registerGlobalAction(QStringLiteral("edit_reconciliate"), actJumpToOperation, true, QStringList() << QStringLiteral("recurrentoperation"), 1, -1, 160);
}
// Set show widget
ui.kView->getShowWidget()->addGroupedItem(QStringLiteral("all"), i18n("All"), QLatin1String(""), QLatin1String(""), QLatin1String(""), Qt::META + Qt::Key_A);
ui.kView->getShowWidget()->addGroupedItem(QStringLiteral("ongoing"), i18n("Ongoing"), QStringLiteral("vcs-normal"), QStringLiteral("t_times='N' OR i_nb_times>0"), QLatin1String(""), Qt::META + Qt::Key_O);
ui.kView->getShowWidget()->addGroupedItem(QStringLiteral("finished"), i18n("Complete"), QStringLiteral("vcs-conflicting"), QStringLiteral("t_times='Y' AND i_nb_times=0"), QLatin1String(""), Qt::META + Qt::Key_C);
ui.kView->getShowWidget()->setDefaultState(QStringLiteral("all"));
ui.kView->setModel(new SKGObjectModel(qobject_cast<SKGDocumentBank*>(getDocument()), QStringLiteral("v_recurrentoperation_display"), QLatin1String(""), this, QLatin1String(""), false));
connect(ui.kView->getView(), &SKGTreeView::doubleClicked, SKGMainPanel::getMainPanel()->getGlobalAction(QStringLiteral("open")).data(), &QAction::trigger);
connect(ui.kView->getView(), &SKGTreeView::selectionChangedDelayed, this, [ = ] {this->onSelectionChanged();});
// Add Standard KDE Icons to buttons to Operations
ui.kModifyBtn->setIcon(SKGServices::fromTheme(QStringLiteral("dialog-ok")));
ui.kProcessBtn->setIcon(SKGServices::fromTheme(QStringLiteral("system-run")));
connect(ui.kProcessBtn, &QToolButton::clicked, this, &SKGScheduledPluginWidget::onProcess);
auto processImmediatelyAction = new QAction(SKGServices::fromTheme(QStringLiteral("system-run")), i18nc("User action", "Process immediately"), this);
connect(processImmediatelyAction, &QAction::triggered, this, &SKGScheduledPluginWidget::onProcessImmediately);
auto processMenu = new QMenu(this);
processMenu->addAction(processImmediatelyAction);
ui.kProcessBtn->setMenu(processMenu);
ui.kJumpBtn->setIcon(SKGServices::fromTheme(QStringLiteral("quickopen")));
ui.kTitle->setPixmap(SKGServices::fromTheme(QStringLiteral("dialog-information")).pixmap(22, 22), KTitleWidget::ImageLeft);
bool exist = false;
getDocument()->existObjects(QStringLiteral("recurrentoperation"), QLatin1String(""), exist);
ui.kTitle->setVisible(!exist);
// Set Event filters to catch CTRL+ENTER or SHIFT+ENTER
this->installEventFilter(this);
connect(ui.kRemindMe, &QCheckBox::toggled, ui.kRemindMeVal, &QSpinBox::setEnabled);
connect(ui.kRemindMe, &QCheckBox::toggled, ui.label_3, &QSpinBox::setEnabled);
connect(ui.kNbTimes, &QCheckBox::toggled, ui.kNbTimesVal, &QSpinBox::setEnabled);
connect(ui.kNbTimes, &QCheckBox::toggled, ui.kLastOccurenceDate, &QSpinBox::setEnabled);
connect(ui.kAutoWrite, &QCheckBox::toggled, ui.kAutoWriteVal, &QSpinBox::setEnabled);
connect(ui.kAutoWrite, &QCheckBox::toggled, ui.label_4, &QSpinBox::setEnabled);
connect(ui.kModifyBtn, &QPushButton::clicked, this, &SKGScheduledPluginWidget::onUpdate);
connect(ui.kJumpBtn, &QPushButton::clicked, this, &SKGScheduledPluginWidget::onJumpToTheOperation);
connect(ui.kOnceEveryUnit, static_cast<void (KComboBox::*)(const QString&)>(&KComboBox::currentTextChanged), this, &SKGScheduledPluginWidget::onNbOccurrenceChanged);
connect(ui.kLastOccurenceDate, &SKGDateEdit::dateChanged, this, &SKGScheduledPluginWidget::onNbOccurrenceChanged);
connect(ui.kNbTimesVal, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), this, &SKGScheduledPluginWidget::onNbOccurrenceChanged);
connect(ui.kOnceEveryVal, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), this, &SKGScheduledPluginWidget::onNbOccurrenceChanged);
}
SKGScheduledPluginWidget::~SKGScheduledPluginWidget()
{
SKGTRACEINFUNC(1)
}
bool SKGScheduledPluginWidget::eventFilter(QObject* iObject, QEvent* iEvent)
{
if ((iEvent != nullptr) && iEvent->type() == QEvent::KeyPress) {
auto* keyEvent = dynamic_cast<QKeyEvent*>(iEvent);
if (keyEvent && (keyEvent->key() == Qt::Key_Return || keyEvent->key() == Qt::Key_Enter) && iObject == this) {
if ((QApplication::keyboardModifiers() & Qt::ShiftModifier) != 0u && ui.kModifyBtn->isEnabled()) {
ui.kModifyBtn->click();
}
}
}
return SKGTabPage::eventFilter(iObject, iEvent);
}
QString SKGScheduledPluginWidget::getState()
{
SKGTRACEINFUNC(10)
QDomDocument doc(QStringLiteral("SKGML"));
QDomElement root = doc.createElement(QStringLiteral("parameters"));
doc.appendChild(root);
root.setAttribute(QStringLiteral("view"), ui.kView->getState());
return doc.toString();
}
void SKGScheduledPluginWidget::setState(const QString& iState)
{
SKGTRACEINFUNC(10)
QDomDocument doc(QStringLiteral("SKGML"));
doc.setContent(iState);
QDomElement root = doc.documentElement();
ui.kView->setState(root.attribute(QStringLiteral("view")));
QString selection = root.attribute(QStringLiteral("selection"));
if (!selection.isEmpty()) {
QStringList uuids = SKGServices::splitCSVLine(selection);
ui.kView->getView()->selectObjects(uuids, true); // FIXME // TODO(Stephane MANKOWSKI)
onSelectionChanged();
}
}
QString SKGScheduledPluginWidget::getDefaultStateAttribute()
{
return QStringLiteral("SKGSCHEDULED_DEFAULT_PARAMETERS");
}
QWidget* SKGScheduledPluginWidget::mainWidget()
{
return ui.kView->getView();
}
void SKGScheduledPluginWidget::onJumpToTheOperation()
{
// Get selection
SKGObjectBase::SKGListSKGObjectBase selection = getSelectedObjects();
if (!selection.isEmpty()) {
// Build where clause and title
QString wc = QStringLiteral("id IN (");
QString title = i18nc("Noun, a list of items", "Operations of the schedule");
int nb = selection.count();
for (int i = 0; i < nb; ++i) {
SKGRecurrentOperationObject recOp(selection.at(i));
SKGOperationObject op;
recOp.getParentOperation(op);
wc += SKGServices::intToString(op.getID());
if (i < nb - 1) {
wc += ',';
}
}
wc += ')';
// Call operation plugin
SKGMainPanel::getMainPanel()->openPage("skg://skrooge_operation_plugin/?template=Y&title_icon=chronometer&operationTable=v_operation_display_all&title=" %
SKGServices::encodeForUrl(title) % "&operationWhereClause=" % SKGServices::encodeForUrl(wc));
}
}
void SKGScheduledPluginWidget::onSelectionChanged()
{
SKGTRACEINFUNC(10)
int nb = getNbSelectedObjects();
ui.kModifyBtn->setEnabled(nb != 0);
ui.kProcessBtn->setEnabled(nb != 0);
ui.kJumpBtn->setEnabled(nb > 0);
if (nb == 1) {
SKGRecurrentOperationObject recOp(ui.kView->getView()->getFirstSelectedObject());
ui.kFirstOccurenceDate->setDate(recOp.getDate());
ui.kOnceEveryVal->setValue(recOp.getPeriodIncrement());
ui.kOnceEveryUnit->setCurrentIndex(static_cast<int>(recOp.getPeriodUnit()));
ui.kRemindMeVal->setValue(recOp.getWarnDays());
ui.kRemindMe->setCheckState(recOp.isWarnEnabled() ? Qt::Checked : Qt::Unchecked);
ui.kAutoWriteVal->setValue(recOp.getAutoWriteDays());
ui.kAutoWrite->setCheckState(recOp.isAutoWriteEnabled() ? Qt::Checked : Qt::Unchecked);
ui.kNbTimesVal->setValue(recOp.getTimeLimit());
ui.kNbTimes->setCheckState(recOp.hasTimeLimit() ? Qt::Checked : Qt::Unchecked);
} else if (nb > 1) {
ui.kFirstOccurenceDate->setEditText(NOUPDATE);
}
Q_EMIT selectionChanged();
}
void SKGScheduledPluginWidget::onNbOccurrenceChanged()
{
QDate firstDate = ui.kFirstOccurenceDate->date();
auto punit = static_cast<SKGRecurrentOperationObject::PeriodUnit>(ui.kOnceEveryUnit->currentIndex());
int p = ui.kOnceEveryVal->value();
if (ui.kLastOccurenceDate == this->sender()) {
// End date has been modified.
// We must set the number of occurrence
QDate lastDate = ui.kLastOccurenceDate->date();
if (lastDate <= firstDate) {
ui.kLastOccurenceDate->setDate(firstDate);
ui.kNbTimesVal->setValue(1);
} else {
int nbd = firstDate.daysTo(lastDate);
if (punit == SKGRecurrentOperationObject::DAY) {
nbd = nbd / p;
} else if (punit == SKGRecurrentOperationObject::WEEK) {
nbd = nbd / p / 7;
} else if (punit == SKGRecurrentOperationObject::MONTH) {
nbd = (lastDate.day() >= firstDate.day() ? 0 : -1) + (lastDate.year() - firstDate.year()) * 12 + (lastDate.month() - firstDate.month());
} else if (punit == SKGRecurrentOperationObject::YEAR) {
nbd = nbd / (365 * p);
}
bool previous = ui.kNbTimesVal->blockSignals(true);
ui.kNbTimesVal->setValue(nbd + 1);
ui.kNbTimesVal->blockSignals(previous);
}
} else {
// We must compute the date
p *= (ui.kNbTimesVal->value() - 1);
if (punit == SKGRecurrentOperationObject::DAY) {
firstDate = firstDate.addDays(p);
} else if (punit == SKGRecurrentOperationObject::WEEK) {
firstDate = firstDate.addDays(7 * p);
} else if (punit == SKGRecurrentOperationObject::MONTH) {
firstDate = firstDate.addMonths(p);
} else if (punit == SKGRecurrentOperationObject::YEAR) {
firstDate = firstDate.addYears(p);
}
bool previous = ui.kLastOccurenceDate->blockSignals(true);
ui.kLastOccurenceDate->setDate(firstDate);
ui.kLastOccurenceDate->blockSignals(previous);
}
}
void SKGScheduledPluginWidget::onUpdate()
{
SKGError err;
SKGTRACEINFUNCRC(10, err) {
// Get Selection
SKGObjectBase::SKGListSKGObjectBase selection = getSelectedObjects();
int nb = selection.count();
SKGBEGINPROGRESSTRANSACTION(*getDocument(), i18nc("Noun, name of the user action", "Recurrent operation update"), err, nb)
for (int i = 0; !err && i < nb; ++i) {
// Get the real object, not the object from the view
SKGRecurrentOperationObject recOp = SKGRecurrentOperationObject(selection.at(i).getDocument(), selection.at(i).getID());
// Update it
if (ui.kFirstOccurenceDate->currentText() != NOUPDATE) {
err = recOp.setDate(ui.kFirstOccurenceDate->date());
}
IFOKDO(err, recOp.setPeriodIncrement(ui.kOnceEveryVal->value()))
IFOKDO(err, recOp.setPeriodUnit(static_cast<SKGRecurrentOperationObject::PeriodUnit>(ui.kOnceEveryUnit->currentIndex())))
IFOKDO(err, recOp.setWarnDays(ui.kRemindMeVal->value()))
IFOKDO(err, recOp.warnEnabled(ui.kRemindMe->checkState() == Qt::Checked))
IFOKDO(err, recOp.setAutoWriteDays(ui.kAutoWriteVal->value()))
IFOKDO(err, recOp.autoWriteEnabled(ui.kAutoWrite->checkState() == Qt::Checked))
IFOKDO(err, recOp.setTimeLimit(ui.kNbTimesVal->value()))
IFOKDO(err, recOp.timeLimit(ui.kNbTimes->checkState() == Qt::Checked))
IFOKDO(err, recOp.save())
// Send message
IFOKDO(err, getDocument()->sendMessage(i18nc("An information to the user", "The recurrent operation '%1' has been updated", recOp.getDisplayName()), SKGDocument::Hidden))
IFOKDO(err, getDocument()->stepForward(i + 1))
}
}
// status bar
IFOKDO(err, SKGError(0, i18nc("Successful message after an user action", "Recurrent operation updated.")))
else {
err.addError(ERR_FAIL, i18nc("Error message", "Update failed"));
}
// Display error
SKGMainPanel::displayErrorMessage(err, true);
// Set focus on table
ui.kView->getView()->setFocus();
}
void SKGScheduledPluginWidget::onProcessImmediately()
{
onProcess(true);
}
void SKGScheduledPluginWidget::onProcess(bool iImmediately)
{
SKGError err;
SKGTRACEINFUNCRC(10, err) {
// Get Selection
SKGObjectBase::SKGListSKGObjectBase selection = getSelectedObjects();
int nb = selection.count();
SKGBEGINPROGRESSTRANSACTION(*getDocument(), i18nc("Noun, name of the user action", "Insert recurrent operations"), err, nb)
for (int i = 0; !err && i < nb; ++i) {
// Get the real object, not the object from the view
SKGRecurrentOperationObject recOp = SKGRecurrentOperationObject(selection.at(i).getDocument(), selection.at(i).getID());
// Process it
int nbi = 0;
err = recOp.process(nbi, true, (iImmediately ? recOp.getDate() : QDate::currentDate()));
IFOKDO(err, getDocument()->stepForward(i + 1))
}
}
// status bar
IFOKDO(err, SKGError(0, i18nc("Successful message after an user action", "Recurrent operation inserted.")))
else {
err.addError(ERR_FAIL, i18nc("Error message", "Insertion failed"));
}
// Display error
SKGMainPanel::displayErrorMessage(err);
}
diff --git a/plugins/skrooge/skrooge_scheduled/skgscheduledpluginwidget.h b/plugins/skrooge/skrooge_scheduled/skgscheduledpluginwidget.h
index 2ddacd5b0..6dc7fb892 100644
--- a/plugins/skrooge/skrooge_scheduled/skgscheduledpluginwidget.h
+++ b/plugins/skrooge/skrooge_scheduled/skgscheduledpluginwidget.h
@@ -1,100 +1,100 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGSCHEDULEDPLUGINWIDGET_H
#define SKGSCHEDULEDPLUGINWIDGET_H
/** @file
* A skrooge plugin to manage scheduled operations
*
* @author Stephane MANKOWSKI
*/
#include "skgtabpage.h"
#include "ui_skgscheduledpluginwidget_base.h"
class SKGDocumentBank;
/**
* A skrooge plugin to manage scheduled operations
*/
class SKGScheduledPluginWidget : public SKGTabPage
{
Q_OBJECT
public:
/**
* Default Constructor
* @param iParent the parent widget
* @param iDocument the document
*/
explicit SKGScheduledPluginWidget(QWidget* iParent, SKGDocumentBank* iDocument);
/**
* Default Destructor
*/
~SKGScheduledPluginWidget() override;
/**
* Get the current state
* MUST BE OVERWRITTEN
* @return a string containing all information needed to set the same state.
* Could be an XML stream
*/
QString getState() override;
/**
* Set the current state
* MUST BE OVERWRITTEN
* @param iState must be interpreted to set the state of the widget
*/
void setState(const QString& iState) override;
/**
* Get attribute name to save the default state
* MUST BE OVERWRITTEN
* @return attribute name to save the default state.
*/
QString getDefaultStateAttribute() override;
/**
* Get the main widget
* @return a widget
*/
QWidget* mainWidget() override;
protected:
/**
* Event filtering
* @param iObject object
* @param iEvent event
* @return In your reimplementation of this function, if you want to filter the event out, i.e. stop it being handled further, return true; otherwise return false.
*/
bool eventFilter(QObject* iObject, QEvent* iEvent) override;
private Q_SLOTS:
void onSelectionChanged();
void onUpdate();
void onProcessImmediately();
void onProcess(bool iImmediately = false);
void onNbOccurrenceChanged();
void onJumpToTheOperation();
private:
Q_DISABLE_COPY(SKGScheduledPluginWidget)
Ui::skgscheduledplugin_base ui{};
};
#endif // SKGSCHEDULEDPLUGINWIDGET_H
diff --git a/plugins/skrooge/skrooge_search/CMakeLists.txt b/plugins/skrooge/skrooge_search/CMakeLists.txt
index 53b818574..226bf43e8 100644
--- a/plugins/skrooge/skrooge_search/CMakeLists.txt
+++ b/plugins/skrooge/skrooge_search/CMakeLists.txt
@@ -1,38 +1,38 @@
#***************************************************************************
#* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
#* *
#* 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 <http://www.gnu.org/licenses/> *
+#* along with this program. If not, see <https://www.gnu.org/licenses/> *
#***************************************************************************
MESSAGE( STATUS "..:: CMAKE PLUGIN_SEARCH ::..")
PROJECT(plugin_search)
LINK_DIRECTORIES (${LIBRARY_OUTPUT_PATH})
SET(skrooge_search_SRCS
skgsearchplugin.cpp
skgsearchpluginwidget.cpp
skgalarmboardwidget.cpp)
ki18n_wrap_ui(skrooge_search_SRCS skgsearchpluginwidget_base.ui skgsearchpluginwidget_pref.ui)
kconfig_add_kcfg_files(skrooge_search_SRCS skgsearch_settings.kcfgc )
ADD_LIBRARY(skrooge_search MODULE ${skrooge_search_SRCS})
TARGET_LINK_LIBRARIES(skrooge_search KF5::Parts KF5::ItemViews skgbasemodeler skgbasegui skgbankmodeler skgbankgui)
########### install files ###############
INSTALL(TARGETS skrooge_search DESTINATION ${KDE_INSTALL_QTPLUGINDIR})
INSTALL(FILES ${PROJECT_SOURCE_DIR}/org.kde.skrooge-plugin-search.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR})
INSTALL(FILES ${PROJECT_SOURCE_DIR}/skrooge_search.rc DESTINATION ${KDE_INSTALL_KXMLGUI5DIR}/skrooge_search )
INSTALL(FILES ${PROJECT_SOURCE_DIR}/skgsearch_settings.kcfg DESTINATION ${KDE_INSTALL_KCFGDIR} )
diff --git a/plugins/skrooge/skrooge_search/org.kde.skrooge-plugin-search.desktop b/plugins/skrooge/skrooge_search/org.kde.skrooge-plugin-search.desktop
index 63a6ab10b..91ccf89d7 100644
--- a/plugins/skrooge/skrooge_search/org.kde.skrooge-plugin-search.desktop
+++ b/plugins/skrooge/skrooge_search/org.kde.skrooge-plugin-search.desktop
@@ -1,76 +1,76 @@
[Desktop Entry]
Name=Skrooge search plugin
Name[bs]=Skrooge dodatak za pretragu
Name[ca]=Connector de cerca de l'Skrooge
Name[ca@valencia]=Connector de cerca de l'Skrooge
Name[cs]=Vyhledávací modul Skrooge
Name[da]=Søge-plugin til Skrooge
Name[de]=Skrooge-Suchmodul
Name[el]=Skrooge search plugin
Name[en_GB]=Skrooge search plugin
Name[es]=Complemento de búsqueda de Skrooge
Name[et]=Skrooge otsinguplugin
Name[fi]=Skroogen hakuliitännäinen
Name[fr]=Module externe Skrooge de recherche
Name[gl]=Complemento de busca de Skrooge
Name[hu]=Skrooge keresés bővítmény
Name[it]=Estensione di ricerca di Skrooge
Name[lt]=Skrooge paieškos papildinys
Name[nb]=Skrooge søkemodul
Name[nds]=Söökmoduul för Skrooge
Name[nl]=Een zoek-plugin voor Skrooge
Name[pl]=Wtyczka wyszukiwania dla Skrooge
Name[pt]='Plugin' de pesquisa do Skrooge
Name[pt_BR]=Plugin de pesquisa do Skrooge
Name[ru]=Модуль поиска и обработки
Name[sk]=Plugin hľadania Skrooge
Name[sv]=Skrooge sökinsticksprogram
Name[tr]=Skrooge arama eklentisi
Name[uk]=Додаток пошуку Skrooge
Name[x-test]=xxSkrooge search pluginxx
Name[zh_TW]=Skrooge 搜尋外掛程式
Comment=A skrooge plugin to search and treat operations
Comment[bs]=Skrooge dodatak za pretragu i tretiranje operacija
Comment[ca]=Un connector de l'Skrooge per cercar i tractar operacions
Comment[ca@valencia]=Un connector de l'Skrooge per cercar i tractar operacions
Comment[cs]=Modul Skrooge pro hledaní a zpracování operací
Comment[da]=Et Skrooge-plugin til at søge i og behandle operationer
Comment[de]=Ein Skrooge-Modul zum Suchen und Behandeln von Vorgängen
Comment[el]=Ένα πρόσθετο του skrooge για αναζήτηση και χειρισμό λειτουργιών
Comment[en_GB]=A skrooge plugin to search and treat operations
Comment[es]=Un complemento de Skrooge para buscar y tratar operaciones
Comment[et]=Skrooge tehingute otsimise ja käitlemise plugin
Comment[fi]=Skroogen haku- ja käsittelyliitännäinen
Comment[fr]=Un module externe Skrooge pour les opérations de recherche et de traitement
Comment[gl]=Un complemento de Skrooge para buscar e tratar operacións
Comment[hu]=Egy Skrooge bővítmény kereséshez és műveletek kezeléséhez
Comment[it]=Un'estensione di Skrooge per cercare e trattare le operazioni
Comment[lt]=Skrooge operacijų paieškos ir apdorojimo papildinys
Comment[nb]=En Skrooge-modul for å søke og behandle operasjoner
Comment[nds]=En Moduul för't Söken un Hanteren vun Akschonen för Skrooge
Comment[nl]=Een plugin voor het zoeken en behandelen van bewerkingen voor Skrooge
Comment[pl]=Wtyczka Skrooge do wyszukiwania i traktowania operacji
Comment[pt]=Um 'plugin' do Skrooge para as operações de pesquisa e tratamento
Comment[pt_BR]=Um plugin do Skrooge para pesquisar e tratar operações
Comment[ru]=Модуль поиска и обработки
Comment[sk]=Plugin Skrooge na hľadanie a úpravu operácií
Comment[sv]=Ett insticksprogram till Skrooge för söka och behandla åtgärder
Comment[tr]=İşlemleri aramak ve uygulamak için bir Skrooge eklentisi
Comment[uk]=Додаток до skrooge для виконання дій зі пошуку і обробки
Comment[x-test]=xxA skrooge plugin to search and treat operationsxx
Comment[zh_TW]=搜尋與處理用的 Skrooge 外掛程式
Encoding=UTF-8
Icon=skrooge
Type=Service
X-KDE-ServiceTypes=SKG GUI/Plugin
X-KDE-Library=skrooge_search
X-Krunner-ID=Skrooge search plugin
X-KDE-PluginInfo-Author=Stephane MANKOWSKI,miraks
X-KDE-PluginInfo-Email=stephane@mankowski.fr
X-KDE-PluginInfo-Name=skrooge_search
X-KDE-PluginInfo-Version=1.0
-X-KDE-PluginInfo-Website=http://skrooge.org/
+X-KDE-PluginInfo-Website=https://skrooge.org/
X-KDE-PluginInfo-Category=Plugins
X-KDE-PluginInfo-Depends=
X-KDE-PluginInfo-License=GPL
X-KDE-PluginInfo-EnabledByDefault=true
diff --git a/plugins/skrooge/skrooge_search/skgalarmboardwidget.cpp b/plugins/skrooge/skrooge_search/skgalarmboardwidget.cpp
index 8ff4873bb..be11d2458 100644
--- a/plugins/skrooge/skrooge_search/skgalarmboardwidget.cpp
+++ b/plugins/skrooge/skrooge_search/skgalarmboardwidget.cpp
@@ -1,197 +1,197 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is Skrooge plugin for bank management.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgalarmboardwidget.h"
#include <qaction.h>
#include <qdom.h>
#include "skgaccountobject.h"
#include "skgdocumentbank.h"
#include "skgmainpanel.h"
#include "skgprogressbar.h"
#include "skgruleobject.h"
#include "skgservices.h"
#include "skgtraces.h"
#include "skgunitobject.h"
SKGAlarmBoardWidget::SKGAlarmBoardWidget(QWidget* iParent, SKGDocument* iDocument)
: SKGBoardWidget(iParent, iDocument, i18nc("Dashboard widget title", "Alarms"))
{
SKGTRACEINFUNC(10)
// Create widget
m_frame = new QFrame();
m_layout = new QVBoxLayout(m_frame);
m_layout->setSpacing(2);
m_layout->setContentsMargins(0, 0, 0, 0);
setMainWidget(m_frame);
// Create menu
setContextMenuPolicy(Qt::ActionsContextMenu);
auto open = new QAction(SKGServices::fromTheme(QStringLiteral("quickopen")), i18nc("Verb, open a page", "Open..."), this);
open->setData(QStringLiteral("skg://skrooge_search_plugin"));
connect(open, &QAction::triggered, SKGMainPanel::getMainPanel(), [ = ]() {
SKGMainPanel::getMainPanel()->SKGMainPanel::openPage();
});
addAction(open);
m_menuFavorite = new QAction(SKGServices::fromTheme(QStringLiteral("bookmarks")), i18nc("Noun, an option in contextual menu", "Highlighted only"), this);
m_menuFavorite->setCheckable(true);
m_menuFavorite->setChecked(false);
connect(m_menuFavorite, &QAction::triggered, this, [ = ]() {
this->dataModified();
});
addAction(m_menuFavorite);
// Refresh
connect(getDocument(), &SKGDocument::tableModified, this, &SKGAlarmBoardWidget::dataModified, Qt::QueuedConnection);
}
SKGAlarmBoardWidget::~SKGAlarmBoardWidget()
{
SKGTRACEINFUNC(10)
m_menuFavorite = nullptr;
}
QString SKGAlarmBoardWidget::getState()
{
QDomDocument doc(QStringLiteral("SKGML"));
doc.setContent(SKGBoardWidget::getState());
QDomElement root = doc.documentElement();
root.setAttribute(QStringLiteral("menuFavorite"), (m_menuFavorite != nullptr) && m_menuFavorite->isChecked() ? QStringLiteral("Y") : QStringLiteral("N"));
return doc.toString();
}
void SKGAlarmBoardWidget::setState(const QString& iState)
{
SKGBoardWidget::setState(iState);
QDomDocument doc(QStringLiteral("SKGML"));
doc.setContent(iState);
QDomElement root = doc.documentElement();
if (m_menuFavorite != nullptr) {
m_menuFavorite->setChecked(root.attribute(QStringLiteral("menuFavorite")) == QStringLiteral("Y"));
}
dataModified(QLatin1String(""), 0);
}
void SKGAlarmBoardWidget::dataModified(const QString& iTableName, int iIdTransaction)
{
SKGTRACEINFUNC(10)
Q_UNUSED(iIdTransaction)
if (iTableName == QStringLiteral("operation") || iTableName == QStringLiteral("rule") || iTableName.isEmpty()) {
// Remove all item of the layout
while (m_layout->count() != 0) {
QLayoutItem* child = m_layout->takeAt(0);
if (child != nullptr) {
QWidget* w = child->widget();
delete w;
delete child;
}
}
// Fill layout
auto* doc = qobject_cast<SKGDocumentBank*>(getDocument());
if (doc != nullptr) {
SKGServices::SKGUnitInfo primary = doc->getPrimaryUnit();
SKGServices::SKGUnitInfo secondary = doc->getSecondaryUnit();
// Build where clause
QString wc = QStringLiteral("t_action_type='A'");
if ((m_menuFavorite != nullptr) && m_menuFavorite->isChecked()) {
wc = "t_bookmarked='Y' AND (" % wc % ')';
}
SKGObjectBase::SKGListSKGObjectBase rules;
SKGError err = doc->getObjects(QStringLiteral("v_rule"), wc % " ORDER BY i_ORDER", rules);
int nb = rules.count();
if (nb != 0) {
for (int i = 0; !err && i < nb; ++i) {
SKGRuleObject rule(rules.at(i));
SKGRuleObject::SKGAlarmInfo alarm = rule.getAlarmInfo();
// Create progress bar
auto progressBar = new SKGProgressBar(m_frame);
progressBar->setObjectName(QStringLiteral("progressBar"));
progressBar->setMaximum(qMax(alarm.Amount, alarm.Limit));
progressBar->setValue(alarm.Amount);
QSizePolicy newSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
newSizePolicy.setHorizontalStretch(0);
newSizePolicy.setVerticalStretch(0);
newSizePolicy.setHeightForWidth(progressBar->sizePolicy().hasHeightForWidth());
progressBar->setSizePolicy(newSizePolicy);
// Set tooltip
QString msg = alarm.Message;
// Build the message
if (alarm.Message.contains(QLatin1String("%3"))) {
msg = alarm.Message.arg(doc->formatMoney(alarm.Amount, primary, false), doc->formatMoney(alarm.Limit, primary, false), doc->formatMoney(alarm.Amount - alarm.Limit, primary, false));
} else if (alarm.Message.contains(QLatin1String("%2"))) {
msg = alarm.Message.arg(doc->formatMoney(alarm.Amount, primary, false), doc->formatMoney(alarm.Limit, primary, false));
} else if (alarm.Message.contains(QLatin1String("%1"))) {
msg = alarm.Message.arg(doc->formatMoney(alarm.Amount, primary, false));
}
QString txt = msg % "<br>";
txt += doc->formatMoney(alarm.Amount, primary, false) % " / " % doc->formatMoney(alarm.Limit, primary, false);
if (!secondary.Symbol.isEmpty() && (secondary.Value != 0.0)) {
txt += "<br>" % doc->formatMoney(alarm.Amount, secondary, false) % " / " % doc->formatMoney(alarm.Limit, secondary, false);
}
progressBar->setToolTip(txt);
// Change color
progressBar->setLimits(qMax(alarm.Amount, alarm.Limit), 0.9 * alarm.Limit, 0.7 * alarm.Limit);
// Add progress bar
m_layout->addWidget(progressBar);
}
} else {
auto lab = new QLabel(m_frame);
lab->setTextInteractionFlags(Qt::LinksAccessibleByMouse | Qt::TextSelectableByMouse);
lab->setText(i18nc("Message", R"(No alarm defined<br>on the <a href="%1">"Search and process"</a> page.)", "skg://Skrooge_search_plugin"));
connect(lab, &QLabel::linkActivated, this, [ = ](const QString & val) {
SKGMainPanel::getMainPanel()->openPage(val);
});
// Add progress bar
m_layout->addWidget(lab);
}
// No widget if no account
bool exist = false;
getDocument()->existObjects(QStringLiteral("account"), QLatin1String(""), exist);
if (parentWidget() != nullptr) {
setVisible(exist);
}
}
}
}
diff --git a/plugins/skrooge/skrooge_search/skgalarmboardwidget.h b/plugins/skrooge/skrooge_search/skgalarmboardwidget.h
index 32b06d670..039fe6b36 100644
--- a/plugins/skrooge/skrooge_search/skgalarmboardwidget.h
+++ b/plugins/skrooge/skrooge_search/skgalarmboardwidget.h
@@ -1,75 +1,75 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGALARMBOARDWIDGET_H
#define SKGALARMBOARDWIDGET_H
/** @file
* This file is Skrooge dashbord plugin for alarms.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgboardwidget.h"
class QVBoxLayout;
class QFrame;
class QAction;
/**
* This file is Skrooge dashbord plugin for alarms
*/
class SKGAlarmBoardWidget : public SKGBoardWidget
{
Q_OBJECT
public:
/**
* Default Constructor
* @param iParent the parent widget
* @param iDocument the document
*/
explicit SKGAlarmBoardWidget(QWidget* iParent, SKGDocument* iDocument);
/**
* Default Destructor
*/
~SKGAlarmBoardWidget() override;
/**
* Get the current state
* MUST BE OVERWRITTEN
* @return a string containing all information needed to set the same state.
* Could be an XML stream
*/
QString getState() override;
/**
* Set the current state
* MUST BE OVERWRITTEN
* @param iState must be interpreted to set the state of the widget
*/
void setState(const QString& iState) override;
private Q_SLOTS:
void dataModified(const QString& iTableName = QString(), int iIdTransaction = 0);
private:
Q_DISABLE_COPY(SKGAlarmBoardWidget)
QAction* m_menuFavorite;
QFrame* m_frame;
QVBoxLayout* m_layout;
};
#endif // SKGALARMBOARDWIDGET_H
diff --git a/plugins/skrooge/skrooge_search/skgsearchplugin.cpp b/plugins/skrooge/skrooge_search/skgsearchplugin.cpp
index f9a5bd145..a70beda8d 100644
--- a/plugins/skrooge/skrooge_search/skgsearchplugin.cpp
+++ b/plugins/skrooge/skrooge_search/skgsearchplugin.cpp
@@ -1,439 +1,439 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* A skrooge plugin to search and process operations
*
* @author Stephane MANKOWSKI
*/
#include "skgsearchplugin.h"
#include <kaboutdata.h>
#include <kactioncollection.h>
#include <kpluginfactory.h>
#include <kstandardaction.h>
#include <qdom.h>
#include "skgalarmboardwidget.h"
#include "skgcategoryobject.h"
#include "skgdocumentbank.h"
#include "skgerror.h"
#include "skghtmlboardwidget.h"
#include "skgmainpanel.h"
#include "skgruleobject.h"
#include "skgsearch_settings.h"
#include "skgsearchpluginwidget.h"
#include "skgtraces.h"
#include "skgtransactionmng.h"
/**
* This plugin factory.
*/
K_PLUGIN_FACTORY(SKGSearchPluginFactory, registerPlugin<SKGSearchPlugin>();)
SKGSearchPlugin::SKGSearchPlugin(QWidget* iWidget, QObject* iParent, const QVariantList& /*iArg*/) :
SKGInterfacePlugin(iParent), m_currentBankDocument(nullptr)
{
Q_UNUSED(iWidget)
SKGTRACEINFUNC(10)
m_timer.setSingleShot(true);
connect(&m_timer, &QTimer::timeout, this, &SKGSearchPlugin::raiseAlarms, Qt::QueuedConnection);
}
SKGSearchPlugin::~SKGSearchPlugin()
{
SKGTRACEINFUNC(10)
m_currentBankDocument = nullptr;
}
int SKGSearchPlugin::getNbDashboardWidgets()
{
return 1;
}
QString SKGSearchPlugin::getDashboardWidgetTitle(int iIndex)
{
Q_UNUSED(iIndex)
return i18nc("Noun, alarms", "Alarms");
}
SKGBoardWidget* SKGSearchPlugin::getDashboardWidget(int iIndex)
{
Q_UNUSED(iIndex)
// Get QML mode for dashboard
KConfigSkeleton* skl = SKGMainPanel::getMainPanel()->getPluginByName(QStringLiteral("Dashboard plugin"))->getPreferenceSkeleton();
KConfigSkeletonItem* sklItem = skl->findItem(QStringLiteral("qmlmode"));
bool qml = sklItem->property().toBool();
if (qml) {
return new SKGHtmlBoardWidget(SKGMainPanel::getMainPanel(), m_currentBankDocument,
getDashboardWidgetTitle(iIndex),
QStandardPaths::locate(QStandardPaths::GenericDataLocation, QStringLiteral("skrooge/html/default/alarm.qml")),
QStringList() << QStringLiteral("operation") << QStringLiteral("rule"));
}
return new SKGAlarmBoardWidget(SKGMainPanel::getMainPanel(), m_currentBankDocument);
}
bool SKGSearchPlugin::setupActions(SKGDocument* iDocument)
{
SKGTRACEINFUNC(10)
m_currentBankDocument = qobject_cast<SKGDocumentBank*>(iDocument);
if (m_currentBankDocument == nullptr) {
return false;
}
setComponentName(QStringLiteral("skrooge_search"), title());
setXMLFile(QStringLiteral("skrooge_search.rc"));
// Create yours actions here
// Execute on all operation
auto actExecuteAll = new QAction(SKGServices::fromTheme(QStringLiteral("system-run")), i18nc("Verb, action to execute", "Execute on all operations"), this);
connect(actExecuteAll, &QAction::triggered, this, [ = ] { execute(SKGRuleObject::ALL); });
registerGlobalAction(QStringLiteral("execute_all"), actExecuteAll, QStringList() << QStringLiteral("rule"), 1, -1, 501);
// Execute on not checked
{
QStringList overlaycsv;
overlaycsv.push_back(QStringLiteral("document-import"));
auto actExecuteImported = new QAction(SKGServices::fromTheme(QStringLiteral("system-run"), overlaycsv), i18nc("Verb, action to execute", "Execute on not checked operations"), this);
connect(actExecuteImported, &QAction::triggered, this, [ = ] { execute(SKGRuleObject::NOTCHECKED); });
registerGlobalAction(QStringLiteral("execute_notchecked"), actExecuteImported, QStringList() << QStringLiteral("rule"), 1, -1, 502);
}
// Execute on imported operation
{
QStringList overlaycsv;
overlaycsv.push_back(QStringLiteral("document-import"));
auto actExecuteImported = new QAction(SKGServices::fromTheme(QStringLiteral("system-run"), overlaycsv), i18nc("Verb, action to execute", "Execute on imported operations"), this);
connect(actExecuteImported, &QAction::triggered, this, [ = ] { execute(SKGRuleObject::IMPORTED); });
registerGlobalAction(QStringLiteral("execute_imported"), actExecuteImported, QStringList() << QStringLiteral("rule"), 1, -1, 502);
}
// Execute on not validated
{
QStringList overlaycsv;
overlaycsv.push_back(QStringLiteral("dialog-ok"));
auto actExecuteNotValidated = new QAction(SKGServices::fromTheme(QStringLiteral("system-run"), overlaycsv), i18nc("Verb, action to execute", "Execute on not validated operations"), this);
connect(actExecuteNotValidated, &QAction::triggered, this, [ = ] { execute(SKGRuleObject::IMPORTEDNOTVALIDATE); });
registerGlobalAction(QStringLiteral("execute_not_validated"), actExecuteNotValidated, QStringList() << QStringLiteral("rule"), 1, -1, 503);
}
// Search
QAction* actSearch = actionCollection()->addAction(KStandardAction::Find, QStringLiteral("edit_find"), this, SLOT(find()));
registerGlobalAction(QStringLiteral("edit_find"), actSearch); // Global
auto actSearch2 = new QAction(actSearch->icon(), actSearch->text(), this);
connect(actSearch2, &QAction::triggered, this, &SKGSearchPlugin::find);
registerGlobalAction(QStringLiteral("edit_find_ctx"), actSearch2, QStringList() << QStringLiteral("account") << QStringLiteral("category") << QStringLiteral("refund") << QStringLiteral("payee") << QStringLiteral("operation") << QStringLiteral("suboperation"), 1, -1, 130); // For contextual menus
return true;
}
void SKGSearchPlugin::refresh()
{
SKGTRACEINFUNC(10)
// Start alarm
if ((m_currentBankDocument != nullptr) && m_currentBankDocument->getMainDatabase() != nullptr) {
QString doc_id = m_currentBankDocument->getUniqueIdentifier();
if (m_docUniqueIdentifier != doc_id) {
m_docUniqueIdentifier = doc_id;
raiseAlarms();
}
}
}
void SKGSearchPlugin::raiseAlarms()
{
if (m_currentBankDocument != nullptr) {
SKGObjectBase::SKGListSKGObjectBase rules;
SKGError err = m_currentBankDocument->getObjects(QStringLiteral("v_rule"), QStringLiteral("t_action_type='A' ORDER BY i_ORDER"), rules);
int nb = rules.count();
if (!err && (nb != 0)) {
for (int i = 0; !err && i < nb; ++i) {
SKGRuleObject rule(rules.at(i));
err = rule.execute();
}
}
// Display error
SKGMainPanel::displayErrorMessage(err);
m_timer.start(skgsearch_settings::alarm_frequency() * 60 * 1000);
}
}
void SKGSearchPlugin::execute(SKGRuleObject::ProcessMode iMode)
{
SKGError err;
SKGTRACEINFUNCRC(1, err)
// Get rules
SKGObjectBase::SKGListSKGObjectBase rules = SKGMainPanel::getMainPanel()->getSelectedObjects();
int nb = rules.count();
if (m_currentBankDocument != nullptr) {
SKGBEGINPROGRESSTRANSACTION(*m_currentBankDocument, i18nc("Noun, name of the user action", "Process execution"), err, nb)
for (int i = 0; !err && i < nb; ++i) {
SKGRuleObject rule(rules.at(i));
err = rule.execute(iMode);
IFOKDO(err, m_currentBankDocument->stepForward(i + 1))
}
}
// status bar
IFOKDO(err, SKGError(0, i18nc("Successful message after an user action", "Process executed")))
else {
err.addError(ERR_FAIL, i18nc("Error message", "Process execution failed"));
}
// Display error
SKGMainPanel::displayErrorMessage(err);
}
void SKGSearchPlugin::find()
{
SKGError err;
SKGTRACEINFUNCRC(10, err)
if (SKGMainPanel::getMainPanel() != nullptr) {
SKGObjectBase::SKGListSKGObjectBase selection = SKGMainPanel::getMainPanel()->getSelectedObjects();
QString xmlsearchcondition;
int nb = selection.count();
if (nb > 0) {
QString table = selection.at(0).getRealTable();
if (table == QStringLiteral("account")) {
QDomDocument doc(QStringLiteral("SKGML"));
QDomElement element = doc.createElement(QStringLiteral("element"));
doc.appendChild(element);
for (int i = 0; i < nb; ++i) {
QDomElement elementLine = doc.createElement(QStringLiteral("element"));
element.appendChild(elementLine);
QDomElement elementElement = doc.createElement(QStringLiteral("element"));
elementLine.appendChild(elementElement);
elementElement.setAttribute(QStringLiteral("attribute"), QStringLiteral("t_ACCOUNT"));
elementElement.setAttribute(QStringLiteral("operator"), QStringLiteral("#ATT#='#V1S#'"));
elementElement.setAttribute(QStringLiteral("value"), selection.at(i).getAttribute(QStringLiteral("t_name")));
}
xmlsearchcondition = doc.toString();
} else if (table == QStringLiteral("category")) {
QDomDocument doc(QStringLiteral("SKGML"));
QDomElement element = doc.createElement(QStringLiteral("element"));
doc.appendChild(element);
for (int i = 0; i < nb; ++i) {
QDomElement elementLine = doc.createElement(QStringLiteral("element"));
element.appendChild(elementLine);
QDomElement elementElement = doc.createElement(QStringLiteral("element"));
elementLine.appendChild(elementElement);
elementElement.setAttribute(QStringLiteral("attribute"), QStringLiteral("t_REALCATEGORY"));
elementElement.setAttribute(QStringLiteral("operator"), QStringLiteral("#ATT#='#V1S#'"));
SKGCategoryObject cat(selection.at(i));
elementElement.setAttribute(QStringLiteral("value"), cat.getFullName());
}
xmlsearchcondition = doc.toString();
} else if (table == QStringLiteral("refund")) {
QDomDocument doc(QStringLiteral("SKGML"));
QDomElement element = doc.createElement(QStringLiteral("element"));
doc.appendChild(element);
for (int i = 0; i < nb; ++i) {
QDomElement elementLine = doc.createElement(QStringLiteral("element"));
element.appendChild(elementLine);
QDomElement elementElement = doc.createElement(QStringLiteral("element"));
elementLine.appendChild(elementElement);
elementElement.setAttribute(QStringLiteral("attribute"), QStringLiteral("t_REALREFUND"));
elementElement.setAttribute(QStringLiteral("operator"), QStringLiteral("#ATT#='#V1S#'"));
elementElement.setAttribute(QStringLiteral("value"), selection.at(i).getAttribute(QStringLiteral("t_name")));
}
xmlsearchcondition = doc.toString();
} else if (table == QStringLiteral("payee")) {
QDomDocument doc(QStringLiteral("SKGML"));
QDomElement element = doc.createElement(QStringLiteral("element"));
doc.appendChild(element);
for (int i = 0; i < nb; ++i) {
QDomElement elementLine = doc.createElement(QStringLiteral("element"));
element.appendChild(elementLine);
QDomElement elementElement = doc.createElement(QStringLiteral("element"));
elementLine.appendChild(elementElement);
elementElement.setAttribute(QStringLiteral("attribute"), QStringLiteral("t_PAYEE"));
elementElement.setAttribute(QStringLiteral("operator"), QStringLiteral("#ATT#='#V1S#'"));
elementElement.setAttribute(QStringLiteral("value"), selection.at(i).getAttribute(QStringLiteral("t_name")));
}
xmlsearchcondition = doc.toString();
} else if (table == QStringLiteral("operation") || table == QStringLiteral("suboperation")) {
QStringList attributeForQuery;
attributeForQuery << QStringLiteral("d_date") << QStringLiteral("t_number") << QStringLiteral("t_mode") << QStringLiteral("t_PAYEE") << QStringLiteral("t_comment") << QStringLiteral("t_REALCATEGORY") << QStringLiteral("t_status") << QStringLiteral("t_bookmarked") << QStringLiteral("t_imported") << QStringLiteral("t_ACCOUNT") << QStringLiteral("f_REALCURRENTAMOUNT") << QStringLiteral("t_REALREFUND");
QDomDocument doc(QStringLiteral("SKGML"));
QDomElement element = doc.createElement(QStringLiteral("element"));
doc.appendChild(element);
for (int i = 0; i < nb; ++i) {
QDomElement elementLine = doc.createElement(QStringLiteral("element"));
element.appendChild(elementLine);
for (int j = 0; j < attributeForQuery.count(); ++j) {
const QString& att = attributeForQuery.at(j);
QString attRead = (att == QStringLiteral("t_REALCATEGORY") ? QStringLiteral("t_CATEGORY") : (att == QStringLiteral("f_REALCURRENTAMOUNT") ? QStringLiteral("f_CURRENTAMOUNT") : (att == QStringLiteral("t_REALREFUND") ? QStringLiteral("t_REFUND") : att)));
SKGObjectBase op(selection.at(i).getDocument(), QStringLiteral("v_operation_display_all"), selection.at(i).getID());
op.load();
QString val = op.getAttribute(attRead);
if (!val.isEmpty()) {
QDomElement elementElement = doc.createElement(QStringLiteral("element"));
elementLine.appendChild(elementElement);
elementElement.setAttribute(QStringLiteral("attribute"), att);
elementElement.setAttribute(QStringLiteral("operator"), att.startsWith(QLatin1String("f_")) || att.startsWith(QLatin1String("i_")) ? QStringLiteral("#ATT#=#V1#") : QStringLiteral("#ATT#='#V1S#'"));
elementElement.setAttribute(QStringLiteral("value"), val);
}
}
}
xmlsearchcondition = doc.toString();
}
}
// Call search plugin
SKGMainPanel::getMainPanel()->openPage("skg://skrooge_search_plugin/?currentPage=0&xmlsearchcondition=" % SKGServices::encodeForUrl(xmlsearchcondition));
}
}
SKGTabPage* SKGSearchPlugin::getWidget()
{
SKGTRACEINFUNC(10)
return new SKGSearchPluginWidget(SKGMainPanel::getMainPanel(), m_currentBankDocument);
}
QWidget* SKGSearchPlugin::getPreferenceWidget()
{
SKGTRACEINFUNC(10)
auto w = new QWidget();
ui.setupUi(w);
return w;
}
KConfigSkeleton* SKGSearchPlugin::getPreferenceSkeleton()
{
return skgsearch_settings::self();
}
QString SKGSearchPlugin::title() const
{
return i18nc("Noun", "Search and process");
}
QString SKGSearchPlugin::icon() const
{
return QStringLiteral("edit-find");
}
QString SKGSearchPlugin::toolTip() const
{
return i18nc("Noun", "Search and process management");
}
int SKGSearchPlugin::getOrder() const
{
return 35;
}
QStringList SKGSearchPlugin::tips() const
{
QStringList output;
output.push_back(i18nc("Description of a tips", "<p>... skrooge can <a href=\"skg://skrooge_search_plugin\">search</a> and automatically process some operations.</p>"));
output.push_back(i18nc("Description of a tips", "<p>... you can create alarms based on <a href=\"skg://skrooge_search_plugin\">searches</a>.</p>"));
return output;
}
bool SKGSearchPlugin::isInPagesChooser() const
{
return true;
}
SKGAdviceList SKGSearchPlugin::advice(const QStringList& iIgnoredAdvice)
{
SKGTRACEINFUNC(10)
SKGAdviceList output;
// Alarms
if (!iIgnoredAdvice.contains(QStringLiteral("skgsearchplugin_alarm"))) {
SKGObjectBase::SKGListSKGObjectBase rules;
SKGError err = m_currentBankDocument->getObjects(QStringLiteral("v_rule"), QStringLiteral("t_action_type='A' ORDER BY i_ORDER"), rules);
int nb = rules.count();
if (nb != 0) {
SKGServices::SKGUnitInfo primary = m_currentBankDocument->getPrimaryUnit();
SKGAdvice::SKGAdviceActionList autoCorrections;
for (int i = 0; !err && i < nb; ++i) {
SKGRuleObject rule(rules.at(i));
SKGRuleObject::SKGAlarmInfo alarm = rule.getAlarmInfo();
if (alarm.Raised) {
double percent = 100 * alarm.Amount / alarm.Limit;
if (percent >= 70) {
SKGAdvice ad;
ad.setUUID("skgsearchplugin_alarm|" % SKGServices::intToString(rule.getID()));
ad.setPriority(percent >= 90 ? 9 : 6);
QString msg = alarm.Message;
// Build the message
if (alarm.Message.contains(QLatin1String("%3"))) {
msg = alarm.Message.arg(m_currentBankDocument->formatMoney(alarm.Amount, primary, false), m_currentBankDocument->formatMoney(alarm.Limit, primary, false), m_currentBankDocument->formatMoney(alarm.Amount - alarm.Limit, primary, false));
} else if (alarm.Message.contains(QLatin1String("%2"))) {
msg = alarm.Message.arg(m_currentBankDocument->formatMoney(alarm.Amount, primary, false), m_currentBankDocument->formatMoney(alarm.Limit, primary, false));
} else if (alarm.Message.contains(QLatin1String("%1"))) {
msg = alarm.Message.arg(m_currentBankDocument->formatMoney(alarm.Amount, primary, false));
}
ad.setShortMessage(msg);
ad.setLongMessage(i18nc("Advice on making the best (long)", "Take care to your alarms.<br> %1.", msg));
autoCorrections.resize(0);
{
SKGAdvice::SKGAdviceAction a;
a.Title = i18nc("Advice on making the best (action)", "Open operations corresponding to this alarm");
a.IconName = QStringLiteral("quickopen");
a.IsRecommended = false;
autoCorrections.push_back(a);
}
ad.setAutoCorrections(autoCorrections);
output.push_back(ad);
}
}
}
}
}
return output;
}
SKGError SKGSearchPlugin::executeAdviceCorrection(const QString& iAdviceIdentifier, int iSolution)
{
if ((m_currentBankDocument != nullptr) && iAdviceIdentifier.startsWith(QLatin1String("skgsearchplugin_alarm|"))) {
// Get parameters
QString id = iAdviceIdentifier.right(iAdviceIdentifier.length() - 22);
SKGSearchPluginWidget::open(SKGRuleObject(m_currentBankDocument, SKGServices::stringToInt(id)));
return SKGError();
}
return SKGInterfacePlugin::executeAdviceCorrection(iAdviceIdentifier, iSolution);
}
#include <skgsearchplugin.moc>
diff --git a/plugins/skrooge/skrooge_search/skgsearchplugin.h b/plugins/skrooge/skrooge_search/skgsearchplugin.h
index b29e3d581..5f7693b84 100644
--- a/plugins/skrooge/skrooge_search/skgsearchplugin.h
+++ b/plugins/skrooge/skrooge_search/skgsearchplugin.h
@@ -1,168 +1,168 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGSEARCHPLUGIN_H
#define SKGSEARCHPLUGIN_H
/** @file
* A skrooge plugin to search and process operations.
*
* @author Stephane MANKOWSKI
*/
#include <qtimer.h>
#include "skginterfaceplugin.h"
#include "skgruleobject.h"
#include "ui_skgsearchpluginwidget_pref.h"
class SKGDocumentBank;
class QAction;
/**
* A skrooge plugin to search and process operations
*/
class SKGSearchPlugin : public SKGInterfacePlugin
{
Q_OBJECT
Q_INTERFACES(SKGInterfacePlugin)
public:
/**
* Default Constructor
*/
explicit SKGSearchPlugin(QWidget* iWidget, QObject* iParent, const QVariantList& iArg);
/**
* Default Destructor
*/
~SKGSearchPlugin() override;
/**
* Called to initialise the plugin
* @param iDocument the main document
* @return true if the plugin is compatible with the document
*/
bool setupActions(SKGDocument* iDocument) override;
/**
* The number of dashboard widgets of the plugin.
* @return The number of dashboard widgets of the plugin
*/
int getNbDashboardWidgets() override;
/**
* Get a dashboard widget title of the plugin.
* @param iIndex the index of the widget
* @return The title
*/
QString getDashboardWidgetTitle(int iIndex) override;
/**
* Get a dashboard widget of the plugin.
* @param iIndex the index of the widget
* @return The dashboard widget of the plugin
*/
SKGBoardWidget* getDashboardWidget(int iIndex) override;
/**
* Must be modified to refresh widgets after a modification.
*/
void refresh() override;
/**
* The preference widget of the plugin.
* @return The preference widget of the plugin
*/
QWidget* getPreferenceWidget() override;
/**
* The preference skeleton of the plugin.
* @return The preference skeleton of the plugin
*/
KConfigSkeleton* getPreferenceSkeleton() override;
/**
* The page widget of the plugin.
* @return The page widget of the plugin
*/
SKGTabPage* getWidget() override;
/**
* The title of the plugin.
* @return The title of the plugin
*/
QString title() const override;
/**
* The icon of the plugin.
* @return The icon of the plugin
*/
QString icon() const override;
/**
* The toolTip of the plugin.
* @return The toolTip of the plugin
*/
QString toolTip() const override;
/**
* The tips list of the plugin.
* @return The tips list of the plugin
*/
QStringList tips() const override;
/**
* Must be implemented to set the position of the plugin.
* @return integer value between 0 and 999 (default = 999)
*/
int getOrder() const override;
/**
* Must be implemented to know if a plugin must be display in pages chooser.
* @return true of false (default = false)
*/
bool isInPagesChooser() const override;
/**
* The advice list of the plugin.
* @return The advice list of the plugin
*/
SKGAdviceList advice(const QStringList& iIgnoredAdvice) override;
/**
* Must be implemented to execute the automatic correction for the advice.
* @param iAdviceIdentifier the identifier of the advice
* @param iSolution the identifier of the possible solution
* @return an object managing the error. MUST return ERR_NOTIMPL if iAdviceIdentifier is not known
* @see SKGError
*/
SKGError executeAdviceCorrection(const QString& iAdviceIdentifier, int iSolution) override;
private Q_SLOTS:
void raiseAlarms();
void execute(SKGRuleObject::ProcessMode iMode);
void find();
private:
Q_DISABLE_COPY(SKGSearchPlugin)
SKGDocumentBank* m_currentBankDocument;
Ui::skgsearchplugin_pref ui{};
QString m_docUniqueIdentifier;
QTimer m_timer;
};
#endif // SKGSEARCHPLUGIN_H
diff --git a/plugins/skrooge/skrooge_search/skgsearchpluginwidget.cpp b/plugins/skrooge/skrooge_search/skgsearchpluginwidget.cpp
index 09bfb5d4a..88c23c5b0 100644
--- a/plugins/skrooge/skrooge_search/skgsearchpluginwidget.cpp
+++ b/plugins/skrooge/skrooge_search/skgsearchpluginwidget.cpp
@@ -1,706 +1,706 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* A skrooge plugin to search and process operations.
*
* @author Stephane MANKOWSKI
*/
#include "skgsearchpluginwidget.h"
#include <qdir.h>
#include <qdom.h>
#include <qevent.h>
#include "skgbankincludes.h"
#include "skgcategoryobject.h"
#include "skgdocument.h"
#include "skgmainpanel.h"
#include "skgobjectmodel.h"
#include "skgruleobject.h"
#include "skgservices.h"
#include "skgtraces.h"
SKGSearchPluginWidget::SKGSearchPluginWidget(QWidget* iParent, SKGDocument* iDocument)
: SKGTabPage(iParent, iDocument)
{
SKGTRACEINFUNC(1)
if (iDocument == nullptr) {
return;
}
ui.setupUi(this);
auto msg = i18nc("Message template", "Message to display when alarm is triggered (%1 is the total amount, %2 is the alarm amount, %3 the difference)", "%1", "%2", "%3");
ui.kAlarmMessage->setToolTip(msg);
ui.kAlarmMessage->setStatusTip(msg);
ui.kView->getShowWidget()->addItem(QStringLiteral("search"), i18nc("Noun, a search", "Search"), QStringLiteral("edit-find"), QStringLiteral("t_action_type='S'"), QLatin1String(""), QLatin1String(""), QLatin1String(""), QLatin1String(""), Qt::META + Qt::Key_S);
ui.kView->getShowWidget()->addItem(QStringLiteral("update"), i18nc("Noun, a modification", "Update"), QStringLiteral("view-refresh"), QStringLiteral("t_action_type='U'"), QLatin1String(""), QLatin1String(""), QLatin1String(""), QLatin1String(""), Qt::META + Qt::Key_U);
ui.kView->getShowWidget()->addItem(QStringLiteral("alarm"), i18nc("Noun, an alarm", "Alarm"), QStringLiteral("dialog-warning"), QStringLiteral("t_action_type='A'"), QLatin1String(""), QLatin1String(""), QLatin1String(""), QLatin1String(""), Qt::META + Qt::Key_A);
ui.kView->getShowWidget()->addItem(QStringLiteral("template"), i18nc("Noun, a modification by applying a template", "Template"), QStringLiteral("edit-guides"), QStringLiteral("t_action_type='T'"), QLatin1String(""), QLatin1String(""), QLatin1String(""), QLatin1String(""), Qt::META + Qt::Key_T);
ui.kView->getShowWidget()->addSeparator();
ui.kView->getShowWidget()->addItem(QStringLiteral("highlighted"), i18nc("Adjective, an highlighted item", "Highlighted"), QStringLiteral("bookmarks"), QStringLiteral("t_bookmarked='Y'"), QLatin1String(""), QLatin1String(""), QLatin1String(""), QLatin1String(""), Qt::META + Qt::Key_H);
ui.kView->getShowWidget()->setDefaultState(QStringLiteral("search;update;alarm;template;highlighted"));
// Add Standard KDE Icons to buttons
ui.kUpdate->setIcon(SKGServices::fromTheme(QStringLiteral("dialog-ok")));
ui.kAdd->setIcon(SKGServices::fromTheme(QStringLiteral("list-add")));
ui.kSearch->setIcon(SKGServices::fromTheme(QStringLiteral("edit-find")));
QStringList overlayopen;
overlayopen.push_back(QStringLiteral("quickopen"));
ui.kOpenReport->setIcon(SKGServices::fromTheme(QStringLiteral("view-statistics"), overlayopen));
ui.kTopBtn->setIcon(SKGServices::fromTheme(QStringLiteral("arrow-up-double")));
ui.kUpBtn->setIcon(SKGServices::fromTheme(QStringLiteral("arrow-up")));
ui.kDownBtn->setIcon(SKGServices::fromTheme(QStringLiteral("arrow-down")));
ui.kBottomBtn->setIcon(SKGServices::fromTheme(QStringLiteral("arrow-down-double")));
{
SKGWidgetSelector::SKGListQWidget list;
list.push_back(ui.kQueryGrp);
list.push_back(ui.kBtnFrm);
ui.kWidgetSelector->addButton(SKGServices::fromTheme(QStringLiteral("edit-find")), i18n("Search"), i18n("Display the edit panel for searches"), list);
}
{
SKGWidgetSelector::SKGListQWidget list;
list.push_back(ui.kQueryGrp);
list.push_back(ui.kBtnFrm);
list.push_back(ui.kActionGrp);
ui.kWidgetSelector->addButton(SKGServices::fromTheme(QStringLiteral("view-refresh")), i18n("Update"), i18n("Display the edit panel for updates"), list);
}
{
SKGWidgetSelector::SKGListQWidget list;
list.push_back(ui.kQueryGrp);
list.push_back(ui.kBtnFrm);
list.push_back(ui.kAlarmFrm);
ui.kWidgetSelector->addButton(SKGServices::fromTheme(QStringLiteral("dialog-warning")), i18n("Alarm"), i18n("Display the edit panel for alarm"), list);
}
{
SKGWidgetSelector::SKGListQWidget list;
list.push_back(ui.kQueryGrp);
list.push_back(ui.kBtnFrm);
list.push_back(ui.kTemplateFrm);
ui.kWidgetSelector->addButton(SKGServices::fromTheme(QStringLiteral("edit-guides")), i18n("Template"), i18n("Display the edit panel for updates by templates"), list);
}
QStringList attributeForQuery;
attributeForQuery.reserve(40);
attributeForQuery << QStringLiteral("d_DATEOP") << QStringLiteral("t_number") << QStringLiteral("t_mode") << QStringLiteral("t_PAYEE") << QStringLiteral("t_comment") << QStringLiteral("t_REALCOMMENT") << QStringLiteral("t_REALCATEGORY") << QStringLiteral("t_status") << QStringLiteral("t_bookmarked") << QStringLiteral("t_imported") << QStringLiteral("t_TRANSFER") << QStringLiteral("t_UNIT") << QStringLiteral("t_ACCOUNT") << QStringLiteral("t_BANK") << QStringLiteral("t_TOACCOUNT") << QStringLiteral("f_REALCURRENTAMOUNT") << QStringLiteral("t_REALREFUND") << QStringLiteral("f_BALANCE");
QStringList attributeForUpdate;
attributeForUpdate.reserve(40);
attributeForUpdate << QStringLiteral("d_DATEOP") << QStringLiteral("t_number") << QStringLiteral("t_mode") << QStringLiteral("t_PAYEE") << QStringLiteral("t_comment") << QStringLiteral("t_status") << QStringLiteral("t_bookmarked") << QStringLiteral("t_imported") << QStringLiteral("t_REALCOMMENT") << QStringLiteral("t_REALCATEGORY") << QStringLiteral("t_ACCOUNT") << QStringLiteral("t_REALREFUND") << QStringLiteral("t_UNIT");
// WARNING: trigger must be modified if this list is modifier
// Adding properties
QStringList properties;
iDocument->getDistinctValues(QStringLiteral("parameters"), QStringLiteral("t_name"), QStringLiteral("(t_uuid_parent like '%-operation' OR t_uuid_parent like '%-suboperation') AND t_name NOT LIKE 'SKG_%'"), properties);
int nb = properties.count();
for (int i = 0; i < nb; ++i) {
attributeForQuery.push_back("p_" % properties.at(i));
attributeForUpdate.push_back("p_" % properties.at(i));
}
ui.kQueryCreator->setParameters(iDocument, QStringLiteral("v_suboperation_consolidated"), attributeForQuery);
ui.kActionCreator->setParameters(iDocument, QStringLiteral("v_suboperation_consolidated"), attributeForUpdate, true);
// Bind operation view
ui.kView->setModel(new SKGObjectModel(qobject_cast<SKGDocumentBank*>(getDocument()), QStringLiteral("v_rule_display"), QStringLiteral("1=1 ORDER BY f_sortorder"), this, QLatin1String(""), false));
ui.kView->getView()->sortByColumn(0, Qt::AscendingOrder);
// Add registered global action in contextual menu
if (SKGMainPanel::getMainPanel() != nullptr) {
auto menu = new QMenu(this);
menu->setIcon(SKGServices::fromTheme(QStringLiteral("system-run")));
menu->addAction(SKGMainPanel::getMainPanel()->getGlobalAction(QStringLiteral("execute_all")));
menu->addAction(SKGMainPanel::getMainPanel()->getGlobalAction(QStringLiteral("execute_imported")));
menu->addAction(SKGMainPanel::getMainPanel()->getGlobalAction(QStringLiteral("execute_not_validated")));
menu->addAction(SKGMainPanel::getMainPanel()->getGlobalAction(QStringLiteral("execute_notchecked")));
ui.kApply->setIcon(menu->icon());
ui.kApply->setMenu(menu);
ui.kApply->setPopupMode(QToolButton::InstantPopup);
}
ui.kWidgetSelector->setSelectedMode(0);
connect(ui.kView->getView(), &SKGTreeView::clickEmptyArea, this, &SKGSearchPluginWidget::cleanEditor);
connect(ui.kView->getView(), &SKGTreeView::doubleClicked, SKGMainPanel::getMainPanel()->getGlobalAction(QStringLiteral("open")).data(), &QAction::trigger);
connect(ui.kView->getView(), &SKGTreeView::selectionChangedDelayed, this, [ = ] {this->onSelectionChanged();});
connect(ui.kQueryCreator, &SKGQueryCreator::search, this, &SKGSearchPluginWidget::onOpen);
connect(ui.kAdd, &QPushButton::clicked, this, &SKGSearchPluginWidget::onAddRule);
connect(ui.kUpdate, &QPushButton::clicked, this, &SKGSearchPluginWidget::onModifyRule);
connect(ui.kTopBtn, &QToolButton::clicked, this, &SKGSearchPluginWidget::onTop);
connect(ui.kUpBtn, &QToolButton::clicked, this, &SKGSearchPluginWidget::onUp);
connect(ui.kDownBtn, &QToolButton::clicked, this, &SKGSearchPluginWidget::onDown);
connect(ui.kBottomBtn, &QToolButton::clicked, this, &SKGSearchPluginWidget::onBottom);
connect(ui.kOpenReport, &QPushButton::clicked, this, &SKGSearchPluginWidget::onOpen);
connect(ui.kSearch, &QPushButton::clicked, this, &SKGSearchPluginWidget::onOpen);
// Refresh
connect(getDocument(), &SKGDocument::tableModified, this, &SKGSearchPluginWidget::dataModified, Qt::QueuedConnection);
dataModified(QLatin1String(""), 0);
onSelectionChanged();
// Set Event filters to catch CTRL+ENTER or SHIFT+ENTER
this->installEventFilter(this);
}
SKGSearchPluginWidget::~SKGSearchPluginWidget()
{
SKGTRACEINFUNC(1)
}
bool SKGSearchPluginWidget::eventFilter(QObject* iObject, QEvent* iEvent)
{
if ((iEvent != nullptr) && iEvent->type() == QEvent::KeyPress) {
auto* keyEvent = dynamic_cast<QKeyEvent*>(iEvent);
if (keyEvent && (keyEvent->key() == Qt::Key_Return || keyEvent->key() == Qt::Key_Enter) && iObject == this) {
if ((QApplication::keyboardModifiers() & Qt::ControlModifier) != 0u && ui.kAdd->isEnabled()) {
ui.kAdd->click();
} else if ((QApplication::keyboardModifiers() &Qt::ShiftModifier) != 0u && ui.kUpdate->isEnabled()) {
ui.kUpdate->click();
}
}
}
return SKGTabPage::eventFilter(iObject, iEvent);
}
QString SKGSearchPluginWidget::getState()
{
SKGTRACEINFUNC(10)
QDomDocument doc(QStringLiteral("SKGML"));
QDomElement root = doc.createElement(QStringLiteral("parameters"));
doc.appendChild(root);
root.setAttribute(QStringLiteral("currentPage"), SKGServices::intToString(ui.kWidgetSelector->getSelectedMode()));
root.setAttribute(QStringLiteral("view"), ui.kView->getState());
return doc.toString();
}
void SKGSearchPluginWidget::setState(const QString& iState)
{
SKGTRACEINFUNC(10)
QDomDocument doc(QStringLiteral("SKGML"));
doc.setContent(iState);
QDomElement root = doc.documentElement();
QString currentPage = root.attribute(QStringLiteral("currentPage"));
QString xmlsearchcondition = root.attribute(QStringLiteral("xmlsearchcondition"));
if (currentPage.isEmpty()) {
currentPage = '0';
}
ui.kWidgetSelector->setSelectedMode(SKGServices::stringToInt(currentPage));
ui.kQueryCreator->setXMLCondition(xmlsearchcondition);
ui.kView->setState(root.attribute(QStringLiteral("view")));
}
QString SKGSearchPluginWidget::getDefaultStateAttribute()
{
return QStringLiteral("SKGSEARCH_DEFAULT_PARAMETERS");
}
QWidget* SKGSearchPluginWidget::mainWidget()
{
return ui.kView->getView();
}
SKGObjectBase::SKGListSKGObjectBase SKGSearchPluginWidget::getSelectedObjects()
{
SKGObjectBase::SKGListSKGObjectBase list = ui.kView->getView()->getSelectedObjects();
// Sort selection by f_sortorder. It is mandatory for reorder functions
std::stable_sort(list.begin(), list.end());
return list;
}
int SKGSearchPluginWidget::getNbSelectedObjects()
{
return ui.kView->getView()->getNbSelectedObjects();
}
void SKGSearchPluginWidget::dataModified(const QString& iTableName, int iIdTransaction)
{
SKGTRACEINFUNC(1)
Q_UNUSED(iIdTransaction)
// Refresh account list
if (iTableName == QStringLiteral("unit") || iTableName.isEmpty()) {
ui.kAlarmUnit->setText(qobject_cast<SKGDocumentBank*>(getDocument())->getPrimaryUnit().Symbol);
}
if (iTableName == QStringLiteral("operation") || iTableName.isEmpty()) {
// Fill combo boxes
SKGStringListList result;
getDocument()->executeSelectSqliteOrder(QStringLiteral("SELECT id, t_displayname FROM v_operation_displayname WHERE t_template='Y' ORDER BY t_displayname"), result);
int nb2 = result.count();
for (int i = 1; i < nb2; ++i) { // Ignore header
const QStringList& r = result.at(i);
ui.kTemplate->addItem(r.at(1), r.at(0));
}
}
}
void SKGSearchPluginWidget::onAddRule()
{
SKGError err;
SKGTRACEINFUNCRC(1, err) {
SKGRuleObject rule;
{
SKGBEGINTRANSACTION(*getDocument(), i18nc("Noun, name of the user action", "Search and process creation"), err)
rule = SKGRuleObject(getDocument());
IFOKDO(err, rule.setXMLSearchDefinition(ui.kQueryCreator->getXMLCondition()))
IFOKDO(err, rule.setOrder(-1))
QString xml = getXMLActionDefinition();
IFOKDO(err, rule.setActionType(xml.isEmpty() ? SKGRuleObject::SEARCH : SKGRuleObject::ActionType(ui.kWidgetSelector->getSelectedMode())))
IFOKDO(err, rule.setXMLActionDefinition(xml))
IFOKDO(err, rule.save())
// Send message
IFOKDO(err, rule.getDocument()->sendMessage(i18nc("An information to the user", "The search rule '%1' have been added", rule.getDisplayName()), SKGDocument::Hidden))
}
// status bar
IFOK(err) {
err = SKGError(0, i18nc("Successful message after an user action", "Search and process created"));
ui.kView->getView()->selectObject(rule.getUniqueID());
} else {
err.addError(ERR_FAIL, i18nc("Error message", "Search and process creation failed"));
}
}
// Display error
SKGMainPanel::displayErrorMessage(err, true);
}
void SKGSearchPluginWidget::onOpen()
{
SKGError err;
SKGTRACEINFUNCRC(1, err)
SKGRuleObject rule;
QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
rule = SKGRuleObject(getDocument());
IFOKDO(err, rule.setXMLSearchDefinition(ui.kQueryCreator->getXMLCondition()))
IFOKDO(err, rule.setOrder(-1))
QString xml = getXMLActionDefinition();
IFOKDO(err, rule.setActionType(xml.isEmpty() ? SKGRuleObject::SEARCH : SKGRuleObject::ActionType(ui.kWidgetSelector->getSelectedMode())))
IFOKDO(err, rule.setXMLActionDefinition(xml))
IFOK(err) open(rule, (sender() == ui.kOpenReport ? SKGSearchPluginWidget::REPORT : SKGSearchPluginWidget::TABLE));
QApplication::restoreOverrideCursor();
// Display error
SKGMainPanel::displayErrorMessage(err);
}
void SKGSearchPluginWidget::onModifyRule()
{
SKGError err;
SKGTRACEINFUNCRC(1, err) {
SKGBEGINTRANSACTION(*getDocument(), i18nc("Noun, name of the user action", "Search and process update"), err)
SKGObjectBase::SKGListSKGObjectBase rules = getSelectedObjects();
if (rules.count() == 1) {
SKGRuleObject rule(rules.at(0));
IFOKDO(err, rule.setXMLSearchDefinition(ui.kQueryCreator->getXMLCondition()))
QString xml = getXMLActionDefinition();
IFOKDO(err, rule.setActionType(xml.isEmpty() ? SKGRuleObject::SEARCH : SKGRuleObject::ActionType(ui.kWidgetSelector->getSelectedMode())))
IFOKDO(err, rule.setXMLActionDefinition(xml))
IFOKDO(err, rule.save())
// Send message
IFOKDO(err, rule.getDocument()->sendMessage(i18nc("An information to the user", "The search rule '%1' have been updated", rule.getDisplayName()), SKGDocument::Hidden))
}
}
// status bar
IFOKDO(err, SKGError(0, i18nc("Successful message after an user action", "Search and process updated")))
else {
err.addError(ERR_FAIL, i18nc("Error message", "Search and process update failed"));
}
// Display error
SKGMainPanel::displayErrorMessage(err, true);
// Set focus on table
ui.kView->getView()->setFocus();
}
void SKGSearchPluginWidget::onSelectionChanged()
{
SKGObjectBase::SKGListSKGObjectBase selection = getSelectedObjects();
int nbSel = selection.count();
ui.kTopBtn->setEnabled(nbSel > 0);
ui.kUpBtn->setEnabled(nbSel > 0);
ui.kDownBtn->setEnabled(nbSel > 0);
ui.kBottomBtn->setEnabled(nbSel > 0);
ui.kUpdate->setEnabled(nbSel == 1);
ui.kApply->setEnabled(nbSel > 0);
if (nbSel > 0) {
SKGRuleObject rule(selection.at(0));
ui.kQueryCreator->setXMLCondition(rule.getXMLSearchDefinition());
int index = qMax(0, static_cast<int>(rule.getActionType()));
if (ui.kWidgetSelector->getSelectedMode() != -1) {
ui.kWidgetSelector->setSelectedMode(index);
}
if (index == 1) {
// Set update mode
ui.kActionCreator->setXMLCondition(rule.getXMLActionDefinition());
} else if (index == 2) {
// Set alarm mode
QDomDocument doc(QStringLiteral("SKGML"));
doc.setContent(rule.getXMLActionDefinition());
QDomElement element = doc.documentElement();
QDomElement elementLine = element.firstChild().toElement();
QDomElement elementElement = elementLine.firstChild().toElement();
ui.kAlarmAmount->setValue(SKGServices::stringToDouble(elementElement.attribute(QStringLiteral("value"))));
ui.kAlarmMessage->setText(elementElement.attribute(QStringLiteral("value2")));
} else if (index == 3) {
// Set template mode
QDomDocument doc(QStringLiteral("SKGML"));
doc.setContent(rule.getXMLActionDefinition());
QDomElement element = doc.documentElement();
QDomElement elementLine = element.firstChild().toElement();
QDomElement elementElement = elementLine.firstChild().toElement();
ui.kTemplate->setCurrentIndex(ui.kTemplate->findData(elementElement.attribute(QStringLiteral("value"))));
}
}
onEditorModified();
Q_EMIT selectionChanged();
}
void SKGSearchPluginWidget::onTop()
{
SKGError err;
SKGTRACEINFUNCRC(1, err)
// Get rules
SKGObjectBase::SKGListSKGObjectBase rules = getSelectedObjects();
int nb = rules.count();
{
SKGBEGINPROGRESSTRANSACTION(*getDocument(), i18nc("Noun, name of the user action", "Search update"), err, nb)
for (int i = nb - 1; !err && i >= 0; --i) {
SKGRuleObject rule(rules.at(i));
double order = 1;
SKGStringListList result;
err = getDocument()->executeSelectSqliteOrder(QStringLiteral("SELECT min(f_sortorder) from rule"), result);
if (!err && result.count() == 2) {
order = SKGServices::stringToDouble(result.at(1).at(0)) - 1;
}
IFOKDO(err, rule.setOrder(order))
IFOKDO(err, rule.save())
// Send message
IFOKDO(err, getDocument()->sendMessage(i18nc("An information to the user", "The search '%1' has been updated", rule.getDisplayName()), SKGDocument::Hidden))
IFOKDO(err, getDocument()->stepForward(i + 1))
}
}
// status bar
IFOKDO(err, SKGError(0, i18nc("Successful message after an user action", "Search updated")))
else {
err.addError(ERR_FAIL, i18nc("Error message", "Search update failed"));
}
// Display error
SKGMainPanel::displayErrorMessage(err);
}
void SKGSearchPluginWidget::onUp()
{
SKGError err;
SKGTRACEINFUNCRC(1, err)
// Get rules
SKGObjectBase::SKGListSKGObjectBase rules = getSelectedObjects();
int nb = rules.count();
{
SKGBEGINPROGRESSTRANSACTION(*getDocument(), i18nc("Noun, name of the user action", "Search update"), err, nb)
for (int i = 0; !err && i < nb; ++i) {
SKGRuleObject rule(rules.at(i));
double order = rule.getOrder();
SKGStringListList result;
err = getDocument()->executeSelectSqliteOrder("SELECT f_sortorder from rule where f_sortorder<" % SKGServices::doubleToString(order) % " ORDER BY f_sortorder DESC", result);
IFOK(err) {
if (result.count() == 2) {
order = SKGServices::stringToDouble(result.at(1).at(0)) - 1;
} else if (result.count() >= 2) {
order = (SKGServices::stringToDouble(result.at(1).at(0)) + SKGServices::stringToDouble(result.at(2).at(0))) / 2;
}
}
IFOKDO(err, rule.setOrder(order))
IFOKDO(err, rule.save())
// Send message
IFOKDO(err, getDocument()->sendMessage(i18nc("An information to the user", "The search '%1' has been updated", rule.getDisplayName()), SKGDocument::Hidden))
IFOKDO(err, getDocument()->stepForward(i + 1))
}
}
// status bar
IFOKDO(err, SKGError(0, i18nc("Successful message after an user action", "Search updated")))
else {
err.addError(ERR_FAIL, i18nc("Error message", "Search update failed"));
}
// Display error
SKGMainPanel::displayErrorMessage(err);
}
void SKGSearchPluginWidget::onDown()
{
SKGError err;
SKGTRACEINFUNCRC(1, err)
// Get rules
SKGObjectBase::SKGListSKGObjectBase rules = getSelectedObjects();
int nb = rules.count();
{
SKGBEGINPROGRESSTRANSACTION(*getDocument(), i18nc("Noun, name of the user action", "Search update"), err, nb)
for (int i = nb - 1; !err && i >= 0; --i) {
SKGRuleObject rule(rules.at(i));
double order = rule.getOrder();
SKGStringListList result;
err = getDocument()->executeSelectSqliteOrder("SELECT f_sortorder from rule where f_sortorder>" % SKGServices::doubleToString(order) % " ORDER BY f_sortorder ASC", result);
IFOK(err) {
if (result.count() == 2) {
order = SKGServices::stringToDouble(result.at(1).at(0)) + 1;
} else if (result.count() >= 2) {
order = (SKGServices::stringToDouble(result.at(1).at(0)) + SKGServices::stringToDouble(result.at(2).at(0))) / 2;
}
}
IFOKDO(err, rule.setOrder(order))
IFOKDO(err, rule.save())
// Send message
IFOKDO(err, getDocument()->sendMessage(i18nc("An information to the user", "The search '%1' has been updated", rule.getDisplayName()), SKGDocument::Hidden))
IFOKDO(err, getDocument()->stepForward(i + 1))
}
}
// status bar
IFOKDO(err, SKGError(0, i18nc("Successful message after an user action", "Search updated")))
else {
err.addError(ERR_FAIL, i18nc("Error message", "Search update failed"));
}
// Display error
SKGMainPanel::displayErrorMessage(err);
}
void SKGSearchPluginWidget::onBottom()
{
SKGError err;
SKGTRACEINFUNCRC(1, err)
// Get rules
SKGObjectBase::SKGListSKGObjectBase rules = getSelectedObjects();
int nb = rules.count();
{
SKGBEGINPROGRESSTRANSACTION(*getDocument(), i18nc("Noun, name of the user action", "Search update"), err, nb)
for (int i = 0; !err && i < nb; ++i) {
SKGRuleObject rule(rules.at(i));
double order = 1;
SKGStringListList result;
err = getDocument()->executeSelectSqliteOrder(QStringLiteral("SELECT max(f_sortorder) from rule"), result);
if (!err && result.count() == 2) {
order = SKGServices::stringToDouble(result.at(1).at(0)) + 1;
}
IFOKDO(err, rule.setOrder(order))
IFOKDO(err, rule.save())
// Send message
IFOKDO(err, getDocument()->sendMessage(i18nc("An information to the user", "The search '%1' has been updated", rule.getDisplayName()), SKGDocument::Hidden))
IFOKDO(err, getDocument()->stepForward(i + 1))
}
}
// status bar
IFOKDO(err, SKGError(0, i18nc("Successful message after an user action", "Search updated")))
else {
err.addError(ERR_FAIL, i18nc("Error message", "Search update failed"));
}
// Display error
SKGMainPanel::displayErrorMessage(err);
}
void SKGSearchPluginWidget::open(const SKGRuleObject& iRule, OpenMode iMode)
{
_SKGTRACEINFUNC(10)
// Build where clause and title
QString wc = "i_SUBOPID in (SELECT i_SUBOPID FROM v_operation_prop WHERE " % iRule.getSelectSqlOrder() % ')';
QString title = i18nc("Noun, a list of items", "Sub operations corresponding to rule '%1'", iRule.getSearchDescription());
// Call operation plugin
QDomDocument doc(QStringLiteral("SKGML"));
doc.setContent(SKGMainPanel::getMainPanel()->getDocument()->getParameter(iMode == TABLE ? QStringLiteral("SKGOPERATION_CONSOLIDATED_DEFAULT_PARAMETERS") : QStringLiteral("SKGREPORT_DEFAULT_PARAMETERS")));
QDomElement root = doc.documentElement();
if (root.isNull()) {
root = doc.createElement(QStringLiteral("parameters"));
doc.appendChild(root);
}
root.setAttribute(QStringLiteral("operationWhereClause"), wc);
root.setAttribute(QStringLiteral("title"), title);
root.setAttribute(QStringLiteral("title_icon"), QStringLiteral("edit-find"));
if (iMode == TABLE) {
root.setAttribute(QStringLiteral("operationTable"), QStringLiteral("v_suboperation_consolidated"));
root.setAttribute(QStringLiteral("currentPage"), QStringLiteral("-1"));
SKGMainPanel::getMainPanel()->openPage(SKGMainPanel::getMainPanel()->getPluginByName(QStringLiteral("Skrooge operation plugin")), -1, doc.toString());
} else {
root.setAttribute(QStringLiteral("period"), QStringLiteral("0"));
SKGMainPanel::getMainPanel()->openPage(SKGMainPanel::getMainPanel()->getPluginByName(QStringLiteral("Skrooge report plugin")), -1, doc.toString());
}
}
void SKGSearchPluginWidget::onEditorModified()
{
SKGObjectBase::SKGListSKGObjectBase selection = getSelectedObjects();
int nbSelect = selection.count();
ui.kUpdate->setEnabled(nbSelect == 1);
ui.kQueryInfo->setText(QLatin1String(""));
if (nbSelect == 1) {
SKGRuleObject rule(selection.at(0));
// Build where clause and title
QString wc = rule.getSelectSqlOrder();
SKGStringListList result;
int vAll = 0;
getDocument()->executeSelectSqliteOrder("SELECT count(distinct(id)) from v_operation_prop WHERE " % wc, result);
if (result.count() == 2) {
vAll = SKGServices::stringToInt(result.at(1).at(0));
}
int vNotChecked = 0;
getDocument()->executeSelectSqliteOrder("SELECT count(distinct(id)) from v_operation_prop WHERE t_status!='Y' AND " % wc, result);
if (result.count() == 2) {
vNotChecked = SKGServices::stringToInt(result.at(1).at(0));
}
int vImported = 0;
getDocument()->executeSelectSqliteOrder("SELECT count(distinct(id)) from v_operation_prop WHERE t_imported!='N' AND " % wc, result);
if (result.count() == 2) {
vImported = SKGServices::stringToInt(result.at(1).at(0));
}
int vNotValidatedl = 0;
getDocument()->executeSelectSqliteOrder("SELECT count(distinct(id)) from v_operation_prop WHERE t_imported='P' AND " % wc, result);
if (result.count() == 2) {
vNotValidatedl = SKGServices::stringToInt(result.at(1).at(0));
}
ui.kQueryInfo->setText(i18np("%1 operation found (%2 imported, %3 not yet validated, %4 not checked).", "%1 operations found (%2 imported, %3 not yet validated, %4 not checked).", vAll, vImported, vNotValidatedl, vNotChecked));
}
}
void SKGSearchPluginWidget::cleanEditor()
{
if (getNbSelectedObjects() == 0) {
ui.kQueryCreator->clearContents();
ui.kActionCreator->clearContents();
}
}
QString SKGSearchPluginWidget::getXMLActionDefinition()
{
QString output;
if (ui.kWidgetSelector->getSelectedMode() == 1) {
// Mode update
output = ui.kActionCreator->getXMLCondition();
} else if (ui.kWidgetSelector->getSelectedMode() == 2) {
// Mode alarm
QDomDocument doc(QStringLiteral("SKGML"));
QDomElement element = doc.createElement(QStringLiteral("element"));
doc.appendChild(element);
QDomElement elementLine = doc.createElement(QStringLiteral("element"));
element.appendChild(elementLine);
QDomElement elementElement = doc.createElement(QStringLiteral("element"));
elementLine.appendChild(elementElement);
elementElement.setAttribute(QStringLiteral("attribute"), QStringLiteral("f_REALCURRENTAMOUNT"));
elementElement.setAttribute(QStringLiteral("operator"), QStringLiteral("ABS(TOTAL(#ATT#))#OP##V1#,ABS(TOTAL(#ATT#)), #V1#, '#V2S#'"));
elementElement.setAttribute(QStringLiteral("operator2"), QStringLiteral(">="));
elementElement.setAttribute(QStringLiteral("value"), SKGServices::doubleToString(ui.kAlarmAmount->value()));
elementElement.setAttribute(QStringLiteral("value2"), ui.kAlarmMessage->text());
output = doc.toString();
} else if (ui.kWidgetSelector->getSelectedMode() == 3) {
// Mode template
QDomDocument doc(QStringLiteral("SKGML"));
QDomElement element = doc.createElement(QStringLiteral("element"));
doc.appendChild(element);
QDomElement elementLine = doc.createElement(QStringLiteral("element"));
element.appendChild(elementLine);
QDomElement elementElement = doc.createElement(QStringLiteral("element"));
elementLine.appendChild(elementElement);
elementElement.setAttribute(QStringLiteral("attribute"), QStringLiteral("id"));
elementElement.setAttribute(QStringLiteral("operator"), QStringLiteral("APPLYTEMPLATE(#V1#)"));
elementElement.setAttribute(QStringLiteral("value"), ui.kTemplate->itemData(ui.kTemplate->currentIndex()).toString());
elementElement.setAttribute(QStringLiteral("value2"), ui.kTemplate->currentText());
output = doc.toString();
}
return output;
}
bool SKGSearchPluginWidget::isEditor()
{
return true;
}
void SKGSearchPluginWidget::activateEditor()
{
if (ui.kWidgetSelector->getSelectedMode() == -1) {
ui.kWidgetSelector->setSelectedMode(0);
}
}
diff --git a/plugins/skrooge/skrooge_search/skgsearchpluginwidget.h b/plugins/skrooge/skrooge_search/skgsearchpluginwidget.h
index e53d7281c..5351721c8 100644
--- a/plugins/skrooge/skrooge_search/skgsearchpluginwidget.h
+++ b/plugins/skrooge/skrooge_search/skgsearchpluginwidget.h
@@ -1,145 +1,145 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGSEARCHPLUGINWIDGET_H
#define SKGSEARCHPLUGINWIDGET_H
/** @file
* A skrooge plugin to search and process operations
*
* @author Stephane MANKOWSKI
*/
#include "skgruleobject.h"
#include "skgtabpage.h"
#include "ui_skgsearchpluginwidget_base.h"
/**
* A skrooge plugin to search and process operations
*/
class SKGSearchPluginWidget : public SKGTabPage
{
Q_OBJECT
public:
/**
* This enumerate defines the open mode
*/
enum OpenMode {TABLE, /**< open in a table*/
REPORT /**< open in report page*/
};
/**
* This enumerate defines the open mode
*/
Q_ENUM(OpenMode)
public:
/**
* Default Constructor
* @param iParent the parent widget
* @param iDocument the document
*/
explicit SKGSearchPluginWidget(QWidget* iParent, SKGDocument* iDocument);
/**
* Default Destructor
*/
~SKGSearchPluginWidget() override;
/**
* Get the current selection
* @return selected objects
*/
SKGObjectBase::SKGListSKGObjectBase getSelectedObjects() override;
/**
* Get the number of selected object
* @return number of selected objects
*/
int getNbSelectedObjects() override;
/**
* Get the current state
* MUST BE OVERWRITTEN
* @return a string containing all information needed to set the same state.
* Could be an XML stream
*/
QString getState() override;
/**
* Set the current state
* MUST BE OVERWRITTEN
* @param iState must be interpreted to set the state of the widget
*/
void setState(const QString& iState) override;
/**
* Get attribute name to save the default state
* MUST BE OVERWRITTEN
* @return attribute name to save the default state.
*/
QString getDefaultStateAttribute() override;
/**
* To know if this page contains an editor. MUST BE OVERWRITTEN
* @return the editor state
*/
bool isEditor() override;
/**
* To activate the editor by setting focus on right widget. MUST BE OVERWRITTEN
*/
void activateEditor() override;
/**
* Get the main widget
* @return a widget
*/
QWidget* mainWidget() override;
/**
* Open operations corresponding to a rule
* @param iRule a rule
* @param iMode the mode for the open
*/
static void open(const SKGRuleObject& iRule, OpenMode iMode = TABLE);
protected:
/**
* Event filtering
* @param iObject object
* @param iEvent event
* @return In your reimplementation of this function, if you want to filter the event out, i.e. stop it being handled further, return true; otherwise return false.
*/
bool eventFilter(QObject* iObject, QEvent* iEvent) override;
private Q_SLOTS:
void dataModified(const QString& iTableName, int iIdTransaction);
void onAddRule();
void onModifyRule();
void onOpen();
void onSelectionChanged();
void onTop();
void onUp();
void onDown();
void onBottom();
void onEditorModified();
void cleanEditor();
private:
Q_DISABLE_COPY(SKGSearchPluginWidget)
QString getXMLActionDefinition();
Ui::skgsearchplugin_base ui{};
};
#endif // SKGSEARCHPLUGINWIDGET_H
diff --git a/plugins/skrooge/skrooge_tracker/CMakeLists.txt b/plugins/skrooge/skrooge_tracker/CMakeLists.txt
index de8b5dced..89c2483db 100644
--- a/plugins/skrooge/skrooge_tracker/CMakeLists.txt
+++ b/plugins/skrooge/skrooge_tracker/CMakeLists.txt
@@ -1,37 +1,37 @@
#***************************************************************************
#* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
#* *
#* 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 <http://www.gnu.org/licenses/> *
+#* along with this program. If not, see <https://www.gnu.org/licenses/> *
#***************************************************************************
MESSAGE( STATUS "..:: CMAKE PLUGIN_TRACKER ::..")
PROJECT(plugin_tracker)
LINK_DIRECTORIES (${LIBRARY_OUTPUT_PATH})
SET(skrooge_tracker_SRCS
skgtrackerplugin.cpp
skgtrackerpluginwidget.cpp)
ki18n_wrap_ui(skrooge_tracker_SRCS skgtrackerpluginwidget_base.ui skgtrackerpluginwidget_pref.ui)
kconfig_add_kcfg_files(skrooge_tracker_SRCS skgtracker_settings.kcfgc )
ADD_LIBRARY(skrooge_tracker MODULE ${skrooge_tracker_SRCS})
TARGET_LINK_LIBRARIES(skrooge_tracker KF5::Parts KF5::ItemViews skgbasemodeler skgbasegui skgbankmodeler skgbankgui)
########### install files ###############
INSTALL(TARGETS skrooge_tracker DESTINATION ${KDE_INSTALL_QTPLUGINDIR})
INSTALL(FILES ${PROJECT_SOURCE_DIR}/org.kde.skrooge-plugin-tracker.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR})
INSTALL(FILES ${PROJECT_SOURCE_DIR}/skrooge_tracker.rc DESTINATION ${KDE_INSTALL_KXMLGUI5DIR}/skrooge_tracker )
INSTALL(FILES ${PROJECT_SOURCE_DIR}/skgtracker_settings.kcfg DESTINATION ${KDE_INSTALL_KCFGDIR} )
diff --git a/plugins/skrooge/skrooge_tracker/org.kde.skrooge-plugin-tracker.desktop b/plugins/skrooge/skrooge_tracker/org.kde.skrooge-plugin-tracker.desktop
index bb61d8369..8e806a80f 100644
--- a/plugins/skrooge/skrooge_tracker/org.kde.skrooge-plugin-tracker.desktop
+++ b/plugins/skrooge/skrooge_tracker/org.kde.skrooge-plugin-tracker.desktop
@@ -1,76 +1,76 @@
[Desktop Entry]
Name=Skrooge tracker plugin
Name[bs]=Skrooge dodatak za praćenje
Name[ca]=Connector de seguiment de l'Skrooge
Name[ca@valencia]=Connector de seguiment de l'Skrooge
Name[cs]=Modul sledování pro Skrooge
Name[da]=Overvågnings-plugin til Skrooge
Name[de]=Skrooge-Modul für Vorgangsgruppen
Name[el]=Skrooge tracker plugin
Name[en_GB]=Skrooge tracker plugin
Name[es]=Complemento de seguimiento de Skrooge
Name[et]=Skrooge jälgimisplugin
Name[fi]=Skroogen jäljitysliitännäinen
Name[fr]=Module externe de gestion des suiveurs
Name[gl]=Complemento de rastrexador de Skrooge
Name[hu]=Skrooge követő bővítmény
Name[it]=Estensione di tracciamento di Skrooge
Name[lt]=Skrooge sekimo papildinys
Name[nb]=Skrooge sporermodul
Name[nds]=Beluermoduul för Skrooge
Name[nl]=Een tracker-plugin voor Skrooge
Name[pl]=Wtyczka śledzenia dla Skrooge
Name[pt]='Plugin' de seguimento do Skrooge
Name[pt_BR]=Plugin de rastreador do Skrooge
Name[ru]=Модуль трекеров
Name[sk]=Plugin stopovača Skrooge
Name[sv]=Skrooge uppföljningsinsticksprogram
Name[tr]=Skrooge izleyici eklentisi
Name[uk]=Додаток стеження Skrooge
Name[x-test]=xxSkrooge tracker pluginxx
Name[zh_TW]=Skrooge 追蹤器外掛程式
Comment=A skrooge plugin to follow refund
Comment[bs]=Skrooge dodatak za praćenje nadoknada
Comment[ca]=Un connector de l'Skrooge per fer el seguiment de les restitucions
Comment[ca@valencia]=Un connector de l'Skrooge per fer el seguiment de les restitucions
Comment[cs]=Modul Skrooge pro hlídání vrácení peněz
Comment[da]=Et Skrooge-plugin til at følge refunderinger
Comment[de]=Ein Skrooge-Modul zur Überwachung von Rückzahlungen
Comment[el]=Ένα πρόσθετο του skrooge για την παρακολούθηση επιστροφών
Comment[en_GB]=A skrooge plugin to follow refund
Comment[es]=Un complemento de Skrooge para seguir los reembolsos
Comment[et]=Skrooge rahaliikumiste jälgimise plugin
Comment[fi]=Skroogen korvauksenseurantaliitännäinen
Comment[fr]=Un module externe Skrooge pour le suivi des remboursements
Comment[gl]=Un complemento de Skrooge para o seguimento de devolucións.
Comment[hu]=Egy Skrooge bővítmény visszatérítések követéséhez
Comment[it]=Un'estensione di Skrooge per seguire i rimborsi
Comment[lt]=Skrooge gražinimų sekimo papildinys
Comment[nb]=En Skrooge-modul for å følge tilbakebetaling
Comment[nds]=En Moduul för't Beluern vun Torüchtahlen för Skrooge
Comment[nl]=Een plugin voor het volgen van betalingen voor Skrooge
Comment[pl]=Wtyczka Skrooge do obsługi zwrotów
Comment[pt]=Um 'plugin' do Skrooge para fazer o seguimento dos retornos
Comment[pt_BR]=Um plugin do Skrooge para fazer o seguimento dos retornos
Comment[ru]=Модуль трекеров
Comment[sk]=Plugin Skrooge na sledovanie náhrad
Comment[sv]=Ett insticksprogram till Skrooge som följer återbäringar
Comment[tr]=Ödemeleri takip etmek için bir Skrooge eklentisi
Comment[uk]=Додаток до skrooge для стеження за поверненням грошей
Comment[x-test]=xxA skrooge plugin to follow refundxx
Comment[zh_TW]=追蹤償還用的 Skrooge 外掛程式
Encoding=UTF-8
Icon=skrooge
Type=Service
X-KDE-ServiceTypes=SKG GUI/Plugin
X-KDE-Library=skrooge_tracker
X-Krunner-ID=Skrooge tracker plugin
X-KDE-PluginInfo-Author=Stephane MANKOWSKI,miraks
X-KDE-PluginInfo-Email=stephane@mankowski.fr
X-KDE-PluginInfo-Name=skrooge_tracker
X-KDE-PluginInfo-Version=1.0
-X-KDE-PluginInfo-Website=http://skrooge.org/
+X-KDE-PluginInfo-Website=https://skrooge.org/
X-KDE-PluginInfo-Category=Plugins
X-KDE-PluginInfo-Depends=
X-KDE-PluginInfo-License=GPL
X-KDE-PluginInfo-EnabledByDefault=true
diff --git a/plugins/skrooge/skrooge_tracker/skgtrackerplugin.cpp b/plugins/skrooge/skrooge_tracker/skgtrackerplugin.cpp
index 6139e3908..2f9fd18d5 100644
--- a/plugins/skrooge/skrooge_tracker/skgtrackerplugin.cpp
+++ b/plugins/skrooge/skrooge_tracker/skgtrackerplugin.cpp
@@ -1,134 +1,134 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* A skrooge plugin to track operations
*
* @author Stephane MANKOWSKI
*/
#include "skgtrackerplugin.h"
#include <kaboutdata.h>
#include <kactioncollection.h>
#include <kpluginfactory.h>
#include <kstandardaction.h>
#include "skgdocumentbank.h"
#include "skgtraces.h"
#include "skgtracker_settings.h"
#include "skgtrackerpluginwidget.h"
/**
* This plugin factory.
*/
K_PLUGIN_FACTORY(SKGTrackerPluginFactory, registerPlugin<SKGTrackerPlugin>();)
SKGTrackerPlugin::SKGTrackerPlugin(QWidget* iWidget, QObject* iParent, const QVariantList& /*iArg*/) : SKGInterfacePlugin(iParent), m_currentBankDocument(nullptr)
{
Q_UNUSED(iWidget)
SKGTRACEINFUNC(10)
}
SKGTrackerPlugin::~SKGTrackerPlugin()
{
SKGTRACEINFUNC(10)
m_currentBankDocument = nullptr;
}
bool SKGTrackerPlugin::setupActions(SKGDocument* iDocument)
{
SKGTRACEINFUNC(10)
if (qobject_cast<SKGDocumentBank*>(iDocument) == nullptr) {
return false;
}
m_currentBankDocument = iDocument;
setComponentName(QStringLiteral("skrooge_tracker"), title());
setXMLFile(QStringLiteral("skrooge_tracker.rc"));
// Create yours actions here
return true;
}
SKGTabPage* SKGTrackerPlugin::getWidget()
{
SKGTRACEINFUNC(10)
return new SKGTrackerPluginWidget(SKGMainPanel::getMainPanel(), m_currentBankDocument);
}
KConfigSkeleton* SKGTrackerPlugin::getPreferenceSkeleton()
{
return skgtracker_settings::self();
}
QString SKGTrackerPlugin::title() const
{
return i18nc("Noun, something that is used to track items", "Trackers");
}
QString SKGTrackerPlugin::icon() const
{
return QStringLiteral("checkbox");
}
QString SKGTrackerPlugin::toolTip() const
{
return i18nc("A tool tip", "Trackers management");
}
int SKGTrackerPlugin::getOrder() const
{
return 25;
}
QStringList SKGTrackerPlugin::tips() const
{
QStringList output;
output.push_back(i18nc("Description of a tips", "<p>...you can follow your refunds by using a <a href=\"skg://skrooge_tracker_plugin\">tracker</a>.</p>"));
return output;
}
bool SKGTrackerPlugin::isInPagesChooser() const
{
return true;
}
SKGAdviceList SKGTrackerPlugin::advice(const QStringList& iIgnoredAdvice)
{
SKGTRACEINFUNC(10)
SKGAdviceList output;
// Search old trackers
if (!iIgnoredAdvice.contains(QStringLiteral("skgtrackerplugin_old"))) {
SKGStringListList result;
m_currentBankDocument->executeSelectSqliteOrder(QStringLiteral("SELECT t_name FROM v_refund_display WHERE t_close='N' AND julianday('now')-julianday(d_LASTDATE)>300 ORDER BY julianday('now')-julianday(d_LASTDATE) DESC;"), result);
int nb = result.count();
output.reserve(nb);
for (int i = 1; i < nb; ++i) { // Ignore header
SKGAdvice ad;
ad.setUUID("skgtrackerplugin_old|" % result.at(i).at(0));
ad.setPriority(2);
ad.setShortMessage(i18nc("Advice on making the best (short)", "'%1' is an old tracker", result.at(i).at(0)));
ad.setLongMessage(i18nc("Advice on making the best (long)", "This tracker does not contain recent operation. You may want to close it if you do not intend to add other operations"));
output.push_back(ad);
}
}
return output;
}
#include <skgtrackerplugin.moc>
diff --git a/plugins/skrooge/skrooge_tracker/skgtrackerplugin.h b/plugins/skrooge/skrooge_tracker/skgtrackerplugin.h
index ecd8ffd56..9fbf28207 100644
--- a/plugins/skrooge/skrooge_tracker/skgtrackerplugin.h
+++ b/plugins/skrooge/skrooge_tracker/skgtrackerplugin.h
@@ -1,119 +1,119 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGTRACKERPLUGIN_H
#define SKGTRACKERPLUGIN_H
/** @file
* A skrooge plugin to track operations.
*
* @author Stephane MANKOWSKI
*/
#include "skginterfaceplugin.h"
#include "ui_skgtrackerpluginwidget_pref.h"
/**
* A skrooge plugin to track operations
*/
class SKGTrackerPlugin : public SKGInterfacePlugin
{
Q_OBJECT
Q_INTERFACES(SKGInterfacePlugin)
public:
/**
* Default Constructor
*/
explicit SKGTrackerPlugin(QWidget* iWidget, QObject* iParent, const QVariantList& iArg);
/**
* Default Destructor
*/
~SKGTrackerPlugin() override;
/**
* Called to initialise the plugin
* @param iDocument the main document
* @return true if the plugin is compatible with the document
*/
bool setupActions(SKGDocument* iDocument) override;
/**
* The preference skeleton of the plugin.
* @return The preference skeleton of the plugin
*/
KConfigSkeleton* getPreferenceSkeleton() override;
/**
* The page widget of the plugin.
* @return The page widget of the plugin
*/
SKGTabPage* getWidget() override;
/**
* The title of the plugin.
* @return The title of the plugin
*/
QString title() const override;
/**
* The icon of the plugin.
* @return The icon of the plugin
*/
QString icon() const override;
/**
* The toolTip of the plugin.
* @return The toolTip of the plugin
*/
QString toolTip() const override;
/**
* The tips list of the plugin.
* @return The tips list of the plugin
*/
QStringList tips() const override;
/**
* Must be implemented to set the position of the plugin.
* @return integer value between 0 and 999 (default = 999)
*/
int getOrder() const override;
/**
* Must be implemented to know if a plugin must be display in pages chooser.
* @return true of false (default = false)
*/
bool isInPagesChooser() const override;
/**
* The advice list of the plugin.
* @return The advice list of the plugin
*/
SKGAdviceList advice(const QStringList& iIgnoredAdvice) override;
private Q_SLOTS:
private:
Q_DISABLE_COPY(SKGTrackerPlugin)
SKGDocument* m_currentBankDocument;
Ui::skgtrackerplugin_pref ui{};
};
#endif // SKGTRACKERPLUGIN_H
diff --git a/plugins/skrooge/skrooge_tracker/skgtrackerpluginwidget.cpp b/plugins/skrooge/skrooge_tracker/skgtrackerpluginwidget.cpp
index 3a35daefc..528e0ae73 100644
--- a/plugins/skrooge/skrooge_tracker/skgtrackerpluginwidget.cpp
+++ b/plugins/skrooge/skrooge_tracker/skgtrackerpluginwidget.cpp
@@ -1,248 +1,248 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* A skrooge plugin to track operations.
*
* @author Stephane MANKOWSKI
*/
#include "skgtrackerpluginwidget.h"
#include <qdom.h>
#include <qevent.h>
#include "skgdocumentbank.h"
#include "skgmainpanel.h"
#include "skgobjectmodel.h"
#include "skgtraces.h"
#include "skgtrackerobject.h"
#include "skgtransactionmng.h"
SKGTrackerPluginWidget::SKGTrackerPluginWidget(QWidget* iParent, SKGDocument* iDocument)
: SKGTabPage(iParent, iDocument)
{
SKGTRACEINFUNC(1)
if (iDocument == nullptr) {
return;
}
ui.setupUi(this);
// Set show widget
ui.kView->getShowWidget()->addGroupedItem(QStringLiteral("all"), i18n("All"), QLatin1String(""), QLatin1String(""), QLatin1String(""), Qt::META + Qt::Key_A);
ui.kView->getShowWidget()->addGroupedItem(QStringLiteral("opened"), i18n("Opened"), QStringLiteral("vcs-normal"), QStringLiteral("t_close='N'"), QLatin1String(""), Qt::META + Qt::Key_O);
ui.kView->getShowWidget()->addGroupedItem(QStringLiteral("closed"), i18n("Closed"), QStringLiteral("vcs-conflicting"), QStringLiteral("t_close='Y'"), QLatin1String(""), Qt::META + Qt::Key_C);
ui.kView->getShowWidget()->setDefaultState(QStringLiteral("opened"));
ui.kNameLbl->setText(i18n("%1:", iDocument->getDisplay(QStringLiteral("t_name"))));
ui.kCommentLabel->setText(i18n("%1:", iDocument->getDisplay(QStringLiteral("t_comment"))));
ui.kAddButton->setIcon(SKGServices::fromTheme(QStringLiteral("list-add")));
ui.kModifyButton->setIcon(SKGServices::fromTheme(QStringLiteral("dialog-ok")));
ui.kView->setModel(new SKGObjectModel(qobject_cast<SKGDocumentBank*>(getDocument()), QStringLiteral("v_refund_display"), QStringLiteral("1=0"), this, QLatin1String(""), false));
ui.kView->getView()->resizeColumnToContents(0);
connect(getDocument(), &SKGDocument::tableModified, this, &SKGTrackerPluginWidget::dataModified, Qt::QueuedConnection);
connect(ui.kView->getView(), &SKGTreeView::clickEmptyArea, this, &SKGTrackerPluginWidget::cleanEditor);
connect(ui.kView->getView(), &SKGTreeView::doubleClicked, SKGMainPanel::getMainPanel()->getGlobalAction(QStringLiteral("open")).data(), &QAction::trigger);
connect(ui.kView->getView(), &SKGTreeView::selectionChangedDelayed, this, [ = ] {this->onSelectionChanged();});
connect(ui.kAddButton, &QPushButton::clicked, this, &SKGTrackerPluginWidget::onAddTracker);
connect(ui.kModifyButton, &QPushButton::clicked, this, &SKGTrackerPluginWidget::onModifyTracker);
connect(ui.kNameInput, &QLineEdit::textChanged, this, &SKGTrackerPluginWidget::onEditorModified);
// Set Event filters to catch CTRL+ENTER or SHIFT+ENTER
this->installEventFilter(this);
dataModified(QLatin1String(""), 0);
}
SKGTrackerPluginWidget::~SKGTrackerPluginWidget() = default;
bool SKGTrackerPluginWidget::eventFilter(QObject* iObject, QEvent* iEvent)
{
if ((iEvent != nullptr) && iEvent->type() == QEvent::KeyPress) {
auto* keyEvent = dynamic_cast<QKeyEvent*>(iEvent);
if (keyEvent && (keyEvent->key() == Qt::Key_Return || keyEvent->key() == Qt::Key_Enter) && iObject == this) {
if ((QApplication::keyboardModifiers() & Qt::ControlModifier) != 0u && ui.kAddButton->isEnabled()) {
ui.kAddButton->click();
} else if ((QApplication::keyboardModifiers() &Qt::ShiftModifier) != 0u && ui.kModifyButton->isEnabled()) {
ui.kModifyButton->click();
}
}
}
return SKGTabPage::eventFilter(iObject, iEvent);
}
void SKGTrackerPluginWidget::onSelectionChanged()
{
SKGTRACEINFUNC(10)
int nbSelect = ui.kView->getView()->getNbSelectedObjects();
if (nbSelect == 1) {
SKGTrackerObject obj(ui.kView->getView()->getFirstSelectedObject());
ui.kNameInput->setText(obj.getName());
ui.kCommentEdit->setText(obj.getComment());
} else if (nbSelect > 1) {
ui.kNameInput->setText(NOUPDATE);
ui.kCommentEdit->setText(NOUPDATE);
}
onEditorModified();
Q_EMIT selectionChanged();
}
QString SKGTrackerPluginWidget::getState()
{
SKGTRACEINFUNC(10)
QDomDocument doc(QStringLiteral("SKGML"));
QDomElement root = doc.createElement(QStringLiteral("parameters"));
doc.appendChild(root);
root.setAttribute(QStringLiteral("view"), ui.kView->getState());
return doc.toString();
}
void SKGTrackerPluginWidget::setState(const QString& iState)
{
SKGTRACEINFUNC(10)
QDomDocument doc(QStringLiteral("SKGML"));
doc.setContent(iState);
QDomElement root = doc.documentElement();
ui.kView->setState(root.attribute(QStringLiteral("view")));
}
QString SKGTrackerPluginWidget::getDefaultStateAttribute()
{
return QStringLiteral("SKGREFUND_DEFAULT_PARAMETERS");
}
QWidget* SKGTrackerPluginWidget::mainWidget()
{
return ui.kView->getView();
}
void SKGTrackerPluginWidget::onEditorModified()
{
_SKGTRACEINFUNC(10)
int nb = ui.kView->getView()->getNbSelectedObjects();
ui.kModifyButton->setEnabled(!ui.kNameInput->text().isEmpty() && nb >= 1);
ui.kAddButton->setEnabled(!ui.kNameInput->text().isEmpty() &&
!ui.kNameInput->text().startsWith(QLatin1Char('=')));
}
void SKGTrackerPluginWidget::dataModified(const QString& iTableName, int iIdTransaction, bool iLightTransaction)
{
SKGTRACEINFUNC(10)
Q_UNUSED(iIdTransaction)
if (!iLightTransaction) {
if (iTableName == QStringLiteral("refund") || iTableName.isEmpty()) {
// Set completions
SKGMainPanel::fillWithDistinctValue(QList<QWidget*>() << ui.kNameInput, getDocument(), QStringLiteral("refund"), QStringLiteral("t_name"), QLatin1String(""), true);
SKGMainPanel::fillWithDistinctValue(QList<QWidget*>() << ui.kCommentEdit, getDocument(), QStringLiteral("refund"), QStringLiteral("t_comment"), QLatin1String(""), true);
}
}
}
void SKGTrackerPluginWidget::onAddTracker()
{
SKGError err;
_SKGTRACEINFUNCRC(10, err)
QString name = ui.kNameInput->text();
SKGTrackerObject tracker;
{
SKGBEGINTRANSACTION(*getDocument(), i18nc("Noun, name of the user action", "Tracker creation '%1'", name), err)
err = SKGTrackerObject::createTracker(qobject_cast<SKGDocumentBank*>(getDocument()), name, tracker);
IFOKDO(err, tracker.setComment(ui.kCommentEdit->text()))
IFOKDO(err, tracker.save())
// Send message
IFOKDO(err, tracker.getDocument()->sendMessage(i18nc("An information to the user", "The tracker '%1' have been added", tracker.getDisplayName()), SKGDocument::Hidden))
}
// status bar
IFOK(err) {
err = SKGError(0, i18nc("Successful message after an user action", "Tracker '%1' created", name));
ui.kView->getView()->selectObject(tracker.getUniqueID());
} else {
err.addError(ERR_FAIL, i18nc("Error message", "Tracker creation failed"));
}
// Display error
SKGMainPanel::displayErrorMessage(err, true);
}
void SKGTrackerPluginWidget::onModifyTracker()
{
SKGError err;
_SKGTRACEINFUNCRC(10, err)
// Get Selection
SKGObjectBase::SKGListSKGObjectBase selection = getSelectedObjects();
int nb = selection.count();
{
SKGBEGINPROGRESSTRANSACTION(*getDocument(), i18nc("Noun, name of the user action", "Tracker update"), err, nb)
for (int i = 0; !err && i < nb; ++i) {
// Modification of object
SKGTrackerObject tracker(selection.at(i));
err = tracker.setName(ui.kNameInput->text());
IFOKDO(err, tracker.setComment(ui.kCommentEdit->text()))
IFOKDO(err, tracker.save())
// Send message
IFOKDO(err, getDocument()->sendMessage(i18nc("An information to the user", "The tracker '%1' has been updated", tracker.getDisplayName()), SKGDocument::Hidden))
IFOKDO(err, getDocument()->stepForward(i + 1))
}
}
// status bar
IFOKDO(err, SKGError(0, i18nc("Successful message after an user action", "Tracker updated")))
else {
err.addError(ERR_FAIL, i18nc("Error message", "Tracker update failed"));
}
// Display error
SKGMainPanel::displayErrorMessage(err, true);
// Set focus on table
ui.kView->getView()->setFocus();
}
void SKGTrackerPluginWidget::cleanEditor()
{
if (getNbSelectedObjects() == 0) {
ui.kNameInput->setText(QLatin1String(""));
ui.kCommentEdit->setText(QLatin1String(""));
}
}
void SKGTrackerPluginWidget::activateEditor()
{
ui.kNameInput->setFocus();
}
bool SKGTrackerPluginWidget::isEditor()
{
return true;
}
diff --git a/plugins/skrooge/skrooge_tracker/skgtrackerpluginwidget.h b/plugins/skrooge/skrooge_tracker/skgtrackerpluginwidget.h
index 378a31f13..fc87fad11 100644
--- a/plugins/skrooge/skrooge_tracker/skgtrackerpluginwidget.h
+++ b/plugins/skrooge/skrooge_tracker/skgtrackerpluginwidget.h
@@ -1,109 +1,109 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGTRACKERPLUGINWIDGET_H
#define SKGTRACKERPLUGINWIDGET_H
/** @file
* A skrooge plugin to track operations
*
* @author Stephane MANKOWSKI
*/
#include "skgtabpage.h"
#include "ui_skgtrackerpluginwidget_base.h"
/**
* A skrooge plugin to track operations
*/
class SKGTrackerPluginWidget : public SKGTabPage
{
Q_OBJECT
public:
/**
* Default Constructor
* @param iParent the parent widget
* @param iDocument the document
*/
explicit SKGTrackerPluginWidget(QWidget* iParent, SKGDocument* iDocument);
/**
* Default Destructor
*/
~SKGTrackerPluginWidget() override;
/**
* Get the current state
* MUST BE OVERWRITTEN
* @return a string containing all information needed to set the same state.
* Could be an XML stream
*/
QString getState() override;
/**
* Set the current state
* MUST BE OVERWRITTEN
* @param iState must be interpreted to set the state of the widget
*/
void setState(const QString& iState) override;
/**
* Get attribute name to save the default state
* MUST BE OVERWRITTEN
* @return attribute name to save the default state.
*/
QString getDefaultStateAttribute() override;
/**
* Get the main widget
* @return a widget
*/
QWidget* mainWidget() override;
/**
* To know if this page contains an editor. MUST BE OVERWRITTEN
* @return the editor state
*/
bool isEditor() override;
/**
* To activate the editor by setting focus on right widget. MUST BE OVERWRITTEN
*/
void activateEditor() override;
protected:
/**
* Event filtering
* @param iObject object
* @param iEvent event
* @return In your reimplementation of this function, if you want to filter the event out, i.e. stop it being handled further, return true; otherwise return false.
*/
bool eventFilter(QObject* iObject, QEvent* iEvent) override;
private Q_SLOTS:
void dataModified(const QString& iTableName, int iIdTransaction, bool iLightTransaction = false);
void onSelectionChanged();
void onEditorModified();
void onAddTracker();
void onModifyTracker();
void cleanEditor();
private:
Q_DISABLE_COPY(SKGTrackerPluginWidget)
Ui::skgtrackerplugin_base ui{};
};
#endif // SKGTRACKERPLUGINWIDGET_H
diff --git a/plugins/skrooge/skrooge_unit/CMakeLists.txt b/plugins/skrooge/skrooge_unit/CMakeLists.txt
index 3e744863e..3991d894d 100644
--- a/plugins/skrooge/skrooge_unit/CMakeLists.txt
+++ b/plugins/skrooge/skrooge_unit/CMakeLists.txt
@@ -1,41 +1,41 @@
#***************************************************************************
#* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
#* *
#* 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 <http://www.gnu.org/licenses/> *
+#* along with this program. If not, see <https://www.gnu.org/licenses/> *
#***************************************************************************
MESSAGE( STATUS "..:: CMAKE PLUGIN_UNIT ::..")
PROJECT(plugin_unit)
IF(SKG_WEBENGINE)
MESSAGE( STATUS " Mode WebEngine")
ADD_DEFINITIONS(-DSKG_WEBENGINE=${SKG_WEBENGINE})
ENDIF(SKG_WEBENGINE)
LINK_DIRECTORIES (${LIBRARY_OUTPUT_PATH})
SET(skrooge_unit_SRCS skgunitplugin.cpp skgunitpluginwidget.cpp skgunitboardwidget.cpp)
ki18n_wrap_ui(skrooge_unit_SRCS skgunitpluginwidget_base.ui skgunitpluginwidget_pref.ui)
kconfig_add_kcfg_files(skrooge_unit_SRCS skgunit_settings.kcfgc )
ADD_LIBRARY(skrooge_unit MODULE ${skrooge_unit_SRCS})
TARGET_LINK_LIBRARIES(skrooge_unit KF5::Parts KF5::NewStuff KF5::Archive KF5::ItemViews skgbasemodeler skgbasegui skgbankmodeler skgbankgui)
########### install files ###############
INSTALL(TARGETS skrooge_unit DESTINATION ${KDE_INSTALL_QTPLUGINDIR})
INSTALL(FILES ${PROJECT_SOURCE_DIR}/skgunit_settings.kcfg DESTINATION ${KDE_INSTALL_KCFGDIR} )
INSTALL(FILES ${PROJECT_SOURCE_DIR}/org.kde.skrooge-plugin-unit.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR})
INSTALL(FILES ${PROJECT_SOURCE_DIR}/skrooge_unit.rc DESTINATION ${KDE_INSTALL_KXMLGUI5DIR}/skrooge_unit )
INSTALL(FILES skrooge_unit.knsrc DESTINATION ${CONFIG_INSTALL_DIR})
diff --git a/plugins/skrooge/skrooge_unit/org.kde.skrooge-plugin-unit.desktop b/plugins/skrooge/skrooge_unit/org.kde.skrooge-plugin-unit.desktop
index e82da487c..4e444a2eb 100644
--- a/plugins/skrooge/skrooge_unit/org.kde.skrooge-plugin-unit.desktop
+++ b/plugins/skrooge/skrooge_unit/org.kde.skrooge-plugin-unit.desktop
@@ -1,76 +1,76 @@
[Desktop Entry]
Name=Skrooge unit plugin
Name[bs]=Skrooge dodatak za jedinice
Name[ca]=Connector d'unitats de l'Skrooge
Name[ca@valencia]=Connector d'unitats de l'Skrooge
Name[cs]=Modul jednotek pro Skrooge
Name[da]=Enheds-plugin til Skrooge
Name[de]=Skrooge-Einheitenmodul
Name[el]=Skrooge unit plugin
Name[en_GB]=Skrooge unit plugin
Name[es]=Complemento de unidades de Skrooge
Name[et]=Skrooge ühikuplugin
Name[fi]=Skroogen yksikköliitännäinen
Name[fr]=Module externe Skrooge pour la gestion des unités
Name[gl]=Complemento de unidades de Skrooge
Name[hu]=Skrooge egység bővítmény
Name[it]=Estensione per unità di Skrooge
Name[lt]=Skrooge vienetų papildinys
Name[nb]=Skrooge enhetsmodul
Name[nds]=Geldeenheitenmoduul för Skrooge
Name[nl]=Plugin voor Skrooge-eenheid
Name[pl]=Wtyczka jednostki dla Skrooge
Name[pt]='Plugin' unitário do Skrooge
Name[pt_BR]=Plugin de unidade do Skrooge
Name[ru]=Модуль платёжных единиц
Name[sk]=Plugin jednotiek Skrooge
Name[sv]=Skrooge enhetsinsticksprogram
Name[tr]=Skrooge birim eklentisi
Name[uk]=Додаток одиниць Skrooge
Name[x-test]=xxSkrooge unit pluginxx
Name[zh_TW]=Skrooge 單位外掛程式
Comment=A skrooge plugin for unit management
Comment[bs]=Skrooge dodatak za upravljanje jedinicama
Comment[ca]=Un connector de l'Skrooge per gestionar unitats
Comment[ca@valencia]=Un connector de l'Skrooge per gestionar unitats
Comment[cs]=Modul Skrooge pro správu jednotek
Comment[da]=Et Skrooge-plugin til håndtering af enheder
Comment[de]=Ein Skrooge-Modul zum Verwalten von Einheiten
Comment[el]=Ένα πρόσθετο του skrooge για τη διαχείριση μονάδων
Comment[en_GB]=A skrooge plugin for unit management
Comment[es]=Un complemento de Skrooge para gestionar unidades
Comment[et]=Skrooge ühikute haldamise plugin
Comment[fi]=Skroogen yksikönhallintaliitännäinen
Comment[fr]=Un module externe Skrooge pour la gestion des unités
-Comment[gl]=Un complemento de Skrooge para a xestión de unidades.
+Comment[gl]=Un complemento de Skrooge para a xestión de unidades.
Comment[hu]=Egy Skrooge bővítmény egységkezeléshez
Comment[it]=Un'estensione di Skrooge per la gestione delle unità
Comment[lt]=Skrooge vienetų tvarkymo papildinys
Comment[nb]=En Skrooge-modul for håndtering av enheter
Comment[nds]=En Moduul för de Pleeg vun Geldeenheiten för Skrooge
Comment[nl]=Een skrooge-plugin voor eenheidbeheer
Comment[pl]=Wtyczka Skrooge do zarządzania jednostkami
Comment[pt]=Um 'plugin' do Skrooge para a gestão de unidades
Comment[pt_BR]=Um plugin do Skrooge para gerenciamento de unidades
Comment[ru]=Модуль управления платёжными единицами
Comment[sk]=Plugin Skrooge na správu jednotiek
Comment[sv]=Ett insticksprogram till Skrooge för enhetshantering
Comment[tr]=Birim yönetimi için bir Skrooge eklentisi
Comment[uk]=Додаток до skrooge для керування даними одиниць
Comment[x-test]=xxA skrooge plugin for unit managementxx
Comment[zh_TW]=管理單位用的 Skrooge 外掛程式
Encoding=UTF-8
Icon=skrooge
Type=Service
X-KDE-ServiceTypes=SKG GUI/Plugin
X-KDE-Library=skrooge_unit
X-Krunner-ID=Skrooge unit plugin
X-KDE-PluginInfo-Author=Stephane MANKOWSKI,miraks
X-KDE-PluginInfo-Email=stephane@mankowski.fr
X-KDE-PluginInfo-Name=skrooge_unit
X-KDE-PluginInfo-Version=1.0
-X-KDE-PluginInfo-Website=http://skrooge.org/
+X-KDE-PluginInfo-Website=https://skrooge.org/
X-KDE-PluginInfo-Category=Plugins
X-KDE-PluginInfo-Depends=
X-KDE-PluginInfo-License=GPL
X-KDE-PluginInfo-EnabledByDefault=true
diff --git a/plugins/skrooge/skrooge_unit/skgunitboardwidget.cpp b/plugins/skrooge/skrooge_unit/skgunitboardwidget.cpp
index b88e9ef36..d0b36e51a 100644
--- a/plugins/skrooge/skrooge_unit/skgunitboardwidget.cpp
+++ b/plugins/skrooge/skrooge_unit/skgunitboardwidget.cpp
@@ -1,261 +1,261 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is Skrooge plugin for unit management.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgunitboardwidget.h"
#include <qdom.h>
#include <kcolorscheme.h>
#include "skgdocumentbank.h"
#include "skgmainpanel.h"
#include "skgtraces.h"
#include "skgunitobject.h"
SKGUnitBoardWidget::SKGUnitBoardWidget(QWidget* iParent, SKGDocument* iDocument)
: SKGBoardWidget(iParent, iDocument, i18nc("Title of a dashboard widget", "Quotes"))
{
SKGTRACEINFUNC(10)
// Create menu
setContextMenuPolicy(Qt::ActionsContextMenu);
m_menuFavorite = new QAction(SKGServices::fromTheme(QStringLiteral("bookmarks")), i18nc("Display only favorite accounts", "Highlighted only"), this);
m_menuFavorite->setCheckable(true);
m_menuFavorite->setChecked(false);
connect(m_menuFavorite, &QAction::triggered, this, [ = ]() {
this->dataModified();
});
addAction(m_menuFavorite);
{
auto sep = new QAction(this);
sep->setSeparator(true);
addAction(sep);
}
m_menuCurrencies = new QAction(i18nc("Noun, a country's currency", "Currencies"), this);
m_menuCurrencies->setCheckable(true);
m_menuCurrencies->setChecked(true);
connect(m_menuCurrencies, &QAction::triggered, this, [ = ]() {
this->dataModified();
});
addAction(m_menuCurrencies);
m_menuIndexes = new QAction(i18nc("Financial indexes, used as an indicator of financial places' health. Examples : Dow Jones, CAC40, Nikkei...", "Indexes"), this);
m_menuIndexes->setCheckable(true);
m_menuIndexes->setChecked(true);
connect(m_menuIndexes, &QAction::triggered, this, [ = ]() {
this->dataModified();
});
addAction(m_menuIndexes);
m_menuShares = new QAction(i18nc("Shares, as in financial shares: parts of a company that you can buy or sell on financial markets", "Shares"), this);
m_menuShares->setCheckable(true);
m_menuShares->setChecked(true);
connect(m_menuShares, &QAction::triggered, this, [ = ]() {
this->dataModified();
});
addAction(m_menuShares);
m_menuObjects = new QAction(i18nc("Noun, a physical object like a house or a car", "Objects"), this);
m_menuObjects->setCheckable(true);
m_menuObjects->setChecked(true);
connect(m_menuObjects, &QAction::triggered, this, [ = ]() {
this->dataModified();
});
addAction(m_menuObjects);
m_menuSharesOwnedOnly = new QAction(i18nc("Only show the list of Shares (financial shares) that you own", "Shares owned only"), this);
m_menuSharesOwnedOnly->setCheckable(true);
m_menuSharesOwnedOnly->setChecked(false);
connect(m_menuSharesOwnedOnly, &QAction::triggered, this, [ = ]() {
this->dataModified();
});
addAction(m_menuSharesOwnedOnly);
m_label = new QLabel();
setMainWidget(m_label);
// Refresh
connect(getDocument(), &SKGDocument::tableModified, this, &SKGUnitBoardWidget::dataModified, Qt::QueuedConnection);
connect(m_label, &QLabel::linkActivated, this, [ = ](const QString & val) {
SKGMainPanel::getMainPanel()->openPage(val);
});
}
SKGUnitBoardWidget::~SKGUnitBoardWidget()
{
SKGTRACEINFUNC(10)
m_menuIndexes = nullptr;
m_menuShares = nullptr;
m_menuSharesOwnedOnly = nullptr;
m_menuObjects = nullptr;
m_menuCurrencies = nullptr;
m_menuFavorite = nullptr;
}
QString SKGUnitBoardWidget::getState()
{
QDomDocument doc(QStringLiteral("SKGML"));
doc.setContent(SKGBoardWidget::getState());
QDomElement root = doc.documentElement();
root.setAttribute(QStringLiteral("m_menuCurrencies"), (m_menuCurrencies != nullptr) && m_menuCurrencies->isChecked() ? QStringLiteral("Y") : QStringLiteral("N"));
root.setAttribute(QStringLiteral("m_menuObjects"), (m_menuObjects != nullptr) && m_menuObjects->isChecked() ? QStringLiteral("Y") : QStringLiteral("N"));
root.setAttribute(QStringLiteral("menuIndexes"), (m_menuIndexes != nullptr) && m_menuIndexes->isChecked() ? QStringLiteral("Y") : QStringLiteral("N"));
root.setAttribute(QStringLiteral("menuShares"), (m_menuShares != nullptr) && m_menuShares->isChecked() ? QStringLiteral("Y") : QStringLiteral("N"));
root.setAttribute(QStringLiteral("menuSharesOwnedOnly"), (m_menuSharesOwnedOnly != nullptr) && m_menuSharesOwnedOnly->isChecked() ? QStringLiteral("Y") : QStringLiteral("N"));
root.setAttribute(QStringLiteral("menuFavorite"), (m_menuFavorite != nullptr) && m_menuFavorite->isChecked() ? QStringLiteral("Y") : QStringLiteral("N"));
return doc.toString();
}
void SKGUnitBoardWidget::setState(const QString& iState)
{
SKGBoardWidget::setState(iState);
QDomDocument doc(QStringLiteral("SKGML"));
doc.setContent(iState);
QDomElement root = doc.documentElement();
if (m_menuCurrencies != nullptr) {
m_menuCurrencies->setChecked(root.attribute(QStringLiteral("m_menuCurrencies")) == QStringLiteral("Y"));
}
if (m_menuObjects != nullptr) {
m_menuObjects->setChecked(root.attribute(QStringLiteral("m_menuObjects")) == QStringLiteral("Y"));
}
if (m_menuIndexes != nullptr) {
m_menuIndexes->setChecked(root.attribute(QStringLiteral("menuIndexes")) != QStringLiteral("N"));
}
if (m_menuShares != nullptr) {
m_menuShares->setChecked(root.attribute(QStringLiteral("menuShares")) != QStringLiteral("N"));
}
if (m_menuSharesOwnedOnly != nullptr) {
m_menuSharesOwnedOnly->setChecked(root.attribute(QStringLiteral("menuSharesOwnedOnly")) != QStringLiteral("N"));
}
if (m_menuFavorite != nullptr) {
m_menuFavorite->setChecked(root.attribute(QStringLiteral("menuFavorite")) == QStringLiteral("Y"));
}
dataModified(QLatin1String(""), 0);
}
void SKGUnitBoardWidget::dataModified(const QString& iTableName, int iIdTransaction)
{
SKGTRACEINFUNC(10)
Q_UNUSED(iIdTransaction)
if (iTableName == QStringLiteral("v_unit_display") || iTableName.isEmpty()) {
auto* doc = qobject_cast<SKGDocumentBank*>(getDocument());
if (doc != nullptr) {
SKGServices::SKGUnitInfo primary = doc->getPrimaryUnit();
// Build where clause
QString wc;
if ((m_menuSharesOwnedOnly != nullptr) && (m_menuShares != nullptr) && (m_menuIndexes != nullptr)) {
m_menuSharesOwnedOnly->setEnabled(m_menuShares->isChecked());
m_menuShares->setEnabled(!m_menuSharesOwnedOnly->isChecked());
if (!m_menuShares->isChecked()) {
m_menuSharesOwnedOnly->setChecked(false);
}
if (m_menuIndexes->isChecked()) {
wc = QStringLiteral("t_type='I'");
}
if (m_menuShares->isChecked()) {
if (!wc.isEmpty()) {
wc += QStringLiteral(" OR ");
}
if (m_menuSharesOwnedOnly->isChecked()) {
wc += QStringLiteral("(t_type='S' AND f_QUANTITYOWNED>0)");
} else {
wc += QStringLiteral("t_type='S'");
}
}
if (m_menuCurrencies->isChecked()) {
if (!wc.isEmpty()) {
wc += QStringLiteral(" OR ");
}
wc += QStringLiteral("t_type IN ('1','2','C')");
}
if (m_menuObjects->isChecked()) {
if (!wc.isEmpty()) {
wc += QStringLiteral(" OR ");
}
wc += QStringLiteral("t_type='O'");
}
}
if (wc.isEmpty()) {
wc = QStringLiteral("1=0");
} else if ((m_menuFavorite != nullptr) && m_menuFavorite->isChecked()) {
wc = "t_bookmarked='Y' AND (" % wc % ')';
}
SKGObjectBase::SKGListSKGObjectBase objs;
SKGError err = getDocument()->getObjects(QStringLiteral("v_unit_display"), wc % " ORDER BY t_type DESC, t_name ASC", objs);
IFOK(err) {
KColorScheme scheme(QPalette::Normal, KColorScheme::Window);
auto color = scheme.foreground(KColorScheme::NormalText).color().name().right(6);
QString html = QStringLiteral("<html><head><style>a {color: #") + color + ";}</style></head><body>";
int nb = objs.count();
if (nb != 0) {
html += QStringLiteral("<table>");
QString lastTitle;
for (int i = 0; i < nb; ++i) {
SKGUnitObject obj(objs.at(i));
QString type = obj.getAttribute(QStringLiteral("t_TYPENLS"));
if (lastTitle != type) {
lastTitle = type;
html += "<tr><td><b>" % SKGServices::stringToHtml(lastTitle) % "</b></td></tr>";
}
html += QString("<tr><td><a href=\"skg://Skrooge_operation_plugin/?operationWhereClause=rc_unit_id=" % SKGServices::intToString(obj.getID()) %
"&title=" % SKGServices::encodeForUrl(i18nc("A list of operations made on the specified unit", "Operations with unit equal to '%1'", obj.getName())) %
"&title_icon=taxes-finances&currentPage=-1" % "\">") % SKGServices::stringToHtml(obj.getDisplayName()) % "</a></td><td align=\"right\">";
if (obj.getType() == SKGUnitObject::INDEX) {
primary.Symbol = ' ';
}
html += doc->formatMoney(SKGServices::stringToDouble(obj.getAttribute(QStringLiteral("f_CURRENTAMOUNT"))), primary);
html += QStringLiteral("</td><td>(");
double amountOneYearBefore = obj.getAmount(QDate::currentDate().addYears(-1));
double val = 100.0 * (obj.getAmount() - amountOneYearBefore) / amountOneYearBefore;
html += doc->formatPercentage(val);
html += QStringLiteral(")</td></tr>");
}
html += QStringLiteral("</table>");
} else {
html += i18nc("Message about not having any financial Share or financial index in the document", R"(No share or index defined<br>on the <a href="%1">"Units"</a> page.)", "skg://Skrooge_unit_plugin");
}
html += QStringLiteral("</body></html>");
m_label->setText(html);
}
// No widget if no account
bool exist = false;
getDocument()->existObjects(QStringLiteral("account"), QLatin1String(""), exist);
if (parentWidget() != nullptr) {
setVisible(exist);
}
}
}
}
diff --git a/plugins/skrooge/skrooge_unit/skgunitboardwidget.h b/plugins/skrooge/skrooge_unit/skgunitboardwidget.h
index 3e44a18bc..b4cc9ee72 100644
--- a/plugins/skrooge/skrooge_unit/skgunitboardwidget.h
+++ b/plugins/skrooge/skrooge_unit/skgunitboardwidget.h
@@ -1,79 +1,79 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGUNITBOARDWIDGET_H
#define SKGUNITBOARDWIDGET_H
/** @file
* This file is Skrooge plugin for unit management.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgboardwidget.h"
class QAction;
/**
* This file is Skrooge plugin for unit management
*/
class SKGUnitBoardWidget : public SKGBoardWidget
{
Q_OBJECT
public:
/**
* Default Constructor
* @param iParent the parent widget
* @param iDocument the document
*/
explicit SKGUnitBoardWidget(QWidget* iParent, SKGDocument* iDocument);
/**
* Default Destructor
*/
~SKGUnitBoardWidget() override;
/**
* Get the current state
* MUST BE OVERWRITTEN
* @return a string containing all information needed to set the same state.
* Could be an XML stream
*/
QString getState() override;
/**
* Set the current state
* MUST BE OVERWRITTEN
* @param iState must be interpreted to set the state of the widget
*/
void setState(const QString& iState) override;
private Q_SLOTS:
void dataModified(const QString& iTableName = QString(), int iIdTransaction = 0);
private:
Q_DISABLE_COPY(SKGUnitBoardWidget)
QAction* m_menuFavorite;
QAction* m_menuCurrencies;
QAction* m_menuIndexes;
QAction* m_menuShares;
QAction* m_menuObjects;
QAction* m_menuSharesOwnedOnly;
QLabel* m_label;
};
#endif // SKGUNITBOARDWIDGET_H
diff --git a/plugins/skrooge/skrooge_unit/skgunitplugin.cpp b/plugins/skrooge/skrooge_unit/skgunitplugin.cpp
index 6560920fa..9adeb362b 100644
--- a/plugins/skrooge/skrooge_unit/skgunitplugin.cpp
+++ b/plugins/skrooge/skrooge_unit/skgunitplugin.cpp
@@ -1,628 +1,628 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is Skrooge plugin for unit management.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgunitplugin.h"
#include <kaboutdata.h>
#include <kactioncollection.h>
#include <kpluginfactory.h>
#include <qaction.h>
#include <qinputdialog.h>
#include <qprocess.h>
#include "skgdocumentbank.h"
#include "skghtmlboardwidget.h"
#include "skgmainpanel.h"
#include "skgtraces.h"
#include "skgtransactionmng.h"
#include "skgunit_settings.h"
#include "skgunitboardwidget.h"
#include "skgunitpluginwidget.h"
#include "skgunitvalueobject.h"
/**
* This plugin factory.
*/
K_PLUGIN_FACTORY(SKGUnitPluginFactory, registerPlugin<SKGUnitPlugin>();)
SKGUnitPlugin::SKGUnitPlugin(QWidget* iWidget, QObject* iParent, const QVariantList& /*iArg*/)
: SKGInterfacePlugin(iParent), m_currentBankDocument(nullptr)
{
Q_UNUSED(iWidget)
SKGTRACEINFUNC(10)
}
SKGUnitPlugin::~SKGUnitPlugin()
{
SKGTRACEINFUNC(10)
m_currentBankDocument = nullptr;
}
bool SKGUnitPlugin::setupActions(SKGDocument* iDocument)
{
SKGTRACEINFUNC(10)
m_currentBankDocument = qobject_cast<SKGDocumentBank*>(iDocument);
if (m_currentBankDocument == nullptr) {
return false;
}
setComponentName(QStringLiteral("skrooge_unit"), title());
setXMLFile(QStringLiteral("skrooge_unit.rc"));
// Menu
auto actSplitShare = new QAction(SKGServices::fromTheme(QStringLiteral("format-text-strikethrough")), i18nc("Verb", "Split share..."), this);
connect(actSplitShare, &QAction::triggered, this, &SKGUnitPlugin::onSplitShare);
actionCollection()->setDefaultShortcut(actSplitShare, Qt::ALT + Qt::Key_Slash);
registerGlobalAction(QStringLiteral("edit_split_stock"), actSplitShare, QStringList() << QStringLiteral("unit"), 1, 1, 310); // TODO(Stephane MANKOWSKI): must be a share
// -----------
auto act = new QAction(SKGServices::fromTheme(icon()), i18nc("Verb", "Delete unused units"), this);
connect(act, &QAction::triggered, this, &SKGUnitPlugin::deleteUnusedUnits);
registerGlobalAction(QStringLiteral("clean_delete_unused_units"), act);
return true;
}
int SKGUnitPlugin::getNbDashboardWidgets()
{
return 2;
}
QString SKGUnitPlugin::getDashboardWidgetTitle(int iIndex)
{
if (iIndex == 0) {
return i18nc("Noun, the title of a section", "Quotes");
}
return i18nc("Noun, the title of a section", "Stock portfolio");
}
SKGBoardWidget* SKGUnitPlugin::getDashboardWidget(int iIndex)
{
if (iIndex == 0) {
return new SKGUnitBoardWidget(SKGMainPanel::getMainPanel(), m_currentBankDocument);
}
// Get QML mode for dashboard
KConfigSkeleton* skl = SKGMainPanel::getMainPanel()->getPluginByName(QStringLiteral("Dashboard plugin"))->getPreferenceSkeleton();
KConfigSkeletonItem* sklItem = skl->findItem(QStringLiteral("qmlmode"));
bool qml = sklItem->property().toBool();
return new SKGHtmlBoardWidget(SKGMainPanel::getMainPanel(), m_currentBankDocument,
getDashboardWidgetTitle(iIndex),
QStandardPaths::locate(QStandardPaths::GenericDataLocation, QStringLiteral("skrooge/html/default/portfolio.") % (qml ? QStringLiteral("qml") : QStringLiteral("html"))),
QStringList() << QStringLiteral("v_operation_display"));
}
void SKGUnitPlugin::refresh()
{
SKGTRACEINFUNC(10)
if ((SKGMainPanel::getMainPanel() != nullptr) && (m_currentBankDocument != nullptr)) {
// Automatic download
QString doc_id = m_currentBankDocument->getUniqueIdentifier();
if (m_docUniqueIdentifier != doc_id) {
m_docUniqueIdentifier = doc_id;
// Check if current unit is existing
bool exist = false;
SKGError err = m_currentBankDocument->existObjects(QStringLiteral("unit"), QLatin1String(""), exist);
IFOK(err) {
if (!exist) {
SKGBEGINTRANSACTION(*m_currentBankDocument, i18nc("Noun, name of the user action", "Create default unit"), err)
IFOK(err) {
// Create default unit
SKGUnitObject unit;
QString unitS = QLocale().currencySymbol(QLocale::CurrencyIsoCode);
if (!unitS.isEmpty()) {
err = SKGUnitObject::createCurrencyUnit(m_currentBankDocument, unitS, unit);
}
// The file is considered has not modified
m_currentBankDocument->setFileNotModified();
}
} else if (skgunit_settings::download_on_open()) {
// Check frequency
QString lastAutomaticDownload = m_currentBankDocument->getParameter(QStringLiteral("SKG_LAST_UNIT_AUTOMATIC_DOWNLOAD"));
if (lastAutomaticDownload.isEmpty()) {
lastAutomaticDownload = QStringLiteral("1970-01-01");
}
QDate lastAutomaticDownloadDate = QDate::fromString(lastAutomaticDownload, QStringLiteral("yyyy-MM-dd"));
if ((lastAutomaticDownloadDate.daysTo(QDate::currentDate()) >= 1 && skgunit_settings::download_frequency() == 0) ||
(lastAutomaticDownloadDate.daysTo(QDate::currentDate()) >= 7 && skgunit_settings::download_frequency() == 1) ||
(lastAutomaticDownloadDate.daysTo(QDate::currentDate()) >= 30 && skgunit_settings::download_frequency() == 2))
{
// Download all units
SKGObjectBase::SKGListSKGObjectBase selection;
err = m_currentBankDocument->getObjects(QStringLiteral("unit"), QLatin1String(""), selection);
int nb = selection.count();
SKGBEGINPROGRESSTRANSACTION(*m_currentBankDocument, i18nc("Noun, name of the user action", "Automatic download of units"), err, nb)
for (int i = 0; !err && i < nb; ++i) {
SKGUnitObject unit(selection.at(i));
err = SKGUnitPluginWidget::downloadUnitValue(unit, SKGUnitPluginWidget::getDownloadModeFromSettings());
// Send message
IFOKDO(err, m_currentBankDocument->sendMessage(i18nc("An information to the user", "The unit '%1' has been downloaded", unit.getDisplayName()), SKGDocument::Hidden))
IFOKDO(err, m_currentBankDocument->stepForward(i + 1))
}
// Memorize the last download date
IFOKDO(err, m_currentBankDocument->setParameter(QStringLiteral("SKG_LAST_UNIT_AUTOMATIC_DOWNLOAD"), QDate::currentDate().toString(QStringLiteral("yyyy-MM-dd"))))
}
}
}
// Display error
SKGMainPanel::displayErrorMessage(err);
}
}
}
SKGTabPage* SKGUnitPlugin::getWidget()
{
SKGTRACEINFUNC(10)
return new SKGUnitPluginWidget(SKGMainPanel::getMainPanel(), m_currentBankDocument);
}
QWidget* SKGUnitPlugin::getPreferenceWidget()
{
SKGTRACEINFUNC(10)
auto w = new QWidget();
ui.setupUi(w);
connect(ui.kcfg_download_on_open, &QCheckBox::toggled, ui.kcfg_download_frequency, &KComboBox::setEnabled);
return w;
}
KConfigSkeleton* SKGUnitPlugin::getPreferenceSkeleton()
{
return skgunit_settings::self();
}
QString SKGUnitPlugin::title() const
{
return i18nc("Noun, units for operations, usually currencies or a shares", "Units");
}
QString SKGUnitPlugin::icon() const
{
return QStringLiteral("taxes-finances");
}
QString SKGUnitPlugin::toolTip() const
{
return i18nc("A tool tip", "Unit management");
}
QStringList SKGUnitPlugin::tips() const
{
QStringList output;
output.push_back(i18nc("Description of a tips", "<p>... you can download <a href=\"skg://skrooge_unit_plugin\">units</a>.</p>"));
output.push_back(i18nc("Description of a tips", "<p>... <a href=\"skg://skrooge_unit_plugin\">units</a> can be downloaded <a href=\"skg://tab_configure?page=Skrooge Unit Plugin\">automatically</a> when a document is opened.</p>"));
output.push_back(i18nc("Description of a tips", "<p>... you can split a <a href=\"skg://skrooge_unit_plugin\">share</a>.</p>"));
output.push_back(i18nc("Description of a tips", "<p>... <a href=\"skg://skrooge_unit_plugin\">units</a> can be merged by drag & drop.</p>"));
output.push_back(i18nc("Description of a tips", "<p>... you can download more <a href=\"skg://skrooge_unit_plugin\">sources</a> of quote.</p>"));
output.push_back(i18nc("Description of a tips", "<p>... you can create and share your own source of quote.</p>"));
return output;
}
int SKGUnitPlugin::getOrder() const
{
return 60;
}
bool SKGUnitPlugin::isInPagesChooser() const
{
return true;
}
void SKGUnitPlugin::onSplitShare()
{
SKGError err;
SKGTRACEINFUNCRC(10, err)
// Get Selection
if (SKGMainPanel::getMainPanel() != nullptr) {
SKGObjectBase::SKGListSKGObjectBase selection = SKGMainPanel::getMainPanel()->getSelectedObjects();
int nb = selection.count();
if (nb == 1) {
bool ok = false;
double ratio = QInputDialog::getDouble(SKGMainPanel::getMainPanel(), i18nc("Question", "Split share"),
i18nc("Question", "Ratio (2 means 2-for-1, 0.5 means 1-for-2):"), 2.0,
0, std::numeric_limits<double>::max(), 8, &ok);
if (ok) {
SKGUnitObject unit(selection.at(0));
SKGBEGINTRANSACTION(*m_currentBankDocument, i18nc("Noun, name of the user action", "Split stock '%1' by '%2'", unit.getName(), ratio), err)
IFOKDO(err, unit.split(ratio))
}
}
// status
IFOKDO(err, SKGError(0, i18nc("Successful message after an user action", "Stock split.")))
else {
err.addError(ERR_FAIL, i18nc("Error message", "Splitting stock failed."));
}
// Display error
SKGMainPanel::displayErrorMessage(err);
}
}
SKGAdviceList SKGUnitPlugin::advice(const QStringList& iIgnoredAdvice)
{
SKGTRACEINFUNC(10)
SKGAdviceList output;
output.reserve(20);
// Get all currencies
SKGStringListList result;
m_currentBankDocument->executeSelectSqliteOrder(QStringLiteral("SELECT (SELECT count(1) FROM operation WHERE operation.rc_unit_id=unit.id), unit.t_name FROM unit WHERE t_type='C' GROUP BY t_name ORDER BY count(1) DESC"), result);
int nb = result.count();
// Check primary unit
if (!iIgnoredAdvice.contains(QStringLiteral("skgunitplugin_primaryunit"))) {
if (m_currentBankDocument->getPrimaryUnit().Name.isEmpty() && nb > 1) {
// Get unit
QString unit = result.at(1).at(1);
SKGAdvice ad;
ad.setUUID("skgunitplugin_primaryunit|" % unit);
ad.setPriority(8);
ad.setShortMessage(i18nc("Advice on making the best (short)", "Define a primary currency"));
ad.setLongMessage(i18nc("Advice on making the best (long)", "To avoid misunderstanding and conflicts between units at conversion time, you should define a primary currency. It is the currency against which all other will be converted"));
SKGAdvice::SKGAdviceActionList autoCorrections;
{
SKGAdvice::SKGAdviceAction a;
a.Title = i18nc("Advice on making the best (action)", "Set '%1' as primary currency", unit);
a.IconName = icon();
a.IsRecommended = true;
autoCorrections.push_back(a);
}
{
SKGAdvice::SKGAdviceAction a;
a.Title = i18nc("Advice on making the best (action)", "Edit units");
a.IconName = icon();
a.IsRecommended = false;
autoCorrections.push_back(a);
}
ad.setAutoCorrections(autoCorrections);
output.push_back(ad);
--nb;
}
}
// Check secondary unit
if (!iIgnoredAdvice.contains(QStringLiteral("skgunitplugin_secondaryunit"))) {
if (m_currentBankDocument->getSecondaryUnit().Name.isEmpty() && nb > 1) {
// Get unit
QString unit = result.at(1).at(1);
SKGAdvice ad;
ad.setUUID("skgunitplugin_secondaryunit|" % unit);
ad.setPriority(2);
ad.setShortMessage(i18nc("Advice on making the best (short)", "Define a secondary currency"));
ad.setLongMessage(i18nc("Advice on making the best (long)", "When a secondary unit is defined, Skrooge will display it as an additional amount information."));
SKGAdvice::SKGAdviceActionList autoCorrections;
{
SKGAdvice::SKGAdviceAction a;
a.Title = i18nc("Advice on making the best (action)", "Set '%1' as secondary currency", unit);
a.IconName = icon();
a.IsRecommended = true;
autoCorrections.push_back(a);
}
{
SKGAdvice::SKGAdviceAction a;
a.Title = i18nc("Advice on making the best (action)", "Edit units");
a.IconName = icon();
a.IsRecommended = false;
autoCorrections.push_back(a);
}
ad.setAutoCorrections(autoCorrections);
output.push_back(ad);
}
}
// Shares not downloaded
if (!iIgnoredAdvice.contains(QStringLiteral("skgunitplugin_notdownloaded"))) {
m_currentBankDocument->executeSelectSqliteOrder(QStringLiteral("SELECT t_name, t_internet_code from unit WHERE t_internet_code<>'' AND (julianday('now')-(SELECT MAX(julianday(d_date)) FROM unitvalue WHERE rd_unit_id=unit.id ))>30 OR NOT EXISTS (SELECT 1 FROM unitvalue WHERE unitvalue.rd_unit_id=unit.id)"), result);
nb = result.count();
SKGAdvice::SKGAdviceActionList autoCorrections;
autoCorrections.reserve(nb);
for (int i = 1; i < nb; ++i) { // Ignore header
// Get parameters
const QStringList& line = result.at(i);
const QString& unit = line.at(0);
const QString& internet_code = line.at(1);
SKGAdvice ad;
ad.setUUID("skgunitplugin_notdownloaded|" % unit);
ad.setPriority(5);
ad.setShortMessage(i18nc("Advice on making the best (short)", "Unit '%1' has not been downloaded for more than a month", unit));
ad.setLongMessage(i18nc("Advice on making the best (long)", "Do not forget download units to have a better view of your accounts"));
autoCorrections.resize(0);
{
SKGAdvice::SKGAdviceAction a;
a.Title = i18nc("Advice on making the best (action)", "Edit units");
a.IconName = icon();
a.IsRecommended = false;
autoCorrections.push_back(a);
}
if (!internet_code.isEmpty()) {
SKGAdvice::SKGAdviceAction a;
a.Title = i18nc("Advice on making the best (action)", "Download '%1'", unit);
a.IconName = QStringLiteral("download");
a.IsRecommended = true;
autoCorrections.push_back(a);
}
ad.setAutoCorrections(autoCorrections);
output.push_back(ad);
}
}
// Check unused units
if (!iIgnoredAdvice.contains(QStringLiteral("skgunitplugin_unused"))) {
bool exist = false;
m_currentBankDocument->existObjects(QStringLiteral("unit"), QStringLiteral("t_type NOT IN ('I', '1', '2') AND NOT EXISTS (SELECT 1 FROM operation WHERE operation.rc_unit_id=unit.id) AND NOT EXISTS (SELECT 1 FROM unit as unit2 WHERE unit2.rd_unit_id=unit.id)"), exist);
if (exist) {
SKGAdvice ad;
ad.setUUID(QStringLiteral("skgunitplugin_unused"));
ad.setPriority(5);
ad.setShortMessage(i18nc("Advice on making the best (short)", "Many unused units"));
ad.setLongMessage(i18nc("Advice on making the best (long)", "You can improve performances by removing units for which no operation is registered."));
QStringList autoCorrections;
autoCorrections.push_back(QStringLiteral("skg://clean_delete_unused_units"));
ad.setAutoCorrections(autoCorrections);
output.push_back(ad);
}
}
// Check unit too complex
if (!iIgnoredAdvice.contains(QStringLiteral("skgunitplugin_amountnotdefined"))) {
m_currentBankDocument->executeSelectSqliteOrder(QStringLiteral("SELECT t_name FROM v_unit WHERE t_type IN ('2','C') AND f_CURRENTAMOUNT=1"), result);
nb = result.count();
SKGAdvice::SKGAdviceActionList autoCorrections;
autoCorrections.reserve(nb);
for (int i = 1; i < nb; ++i) { // Ignore header
// Get parameters
const QStringList& line = result.at(i);
const QString& unit = line.at(0);
SKGAdvice ad;
ad.setUUID("skgunitplugin_amountnotdefined|" % unit);
ad.setPriority(9);
ad.setShortMessage(i18nc("Advice on making the best (short)", "The amount of the unit '%1' is not defined", unit));
ad.setLongMessage(i18nc("Advice on making the best (long)", "'%1' has an amount defined at 1. Most of the time this is not normal and causes wrong computation. Check if this is normal.", unit));
autoCorrections.resize(0);
{
SKGAdvice::SKGAdviceAction a;
a.Title = i18nc("Advice on making the best (action)", "Edit units");
a.IconName = icon();
a.IsRecommended = false;
autoCorrections.push_back(a);
}
ad.setAutoCorrections(autoCorrections);
output.push_back(ad);
}
}
// Check unit too complex
if (!iIgnoredAdvice.contains(QStringLiteral("skgunitplugin_toocomplex"))) {
m_currentBankDocument->executeSelectSqliteOrder(QStringLiteral("SELECT A.t_name FROM unit A, unit B, unit C, unit D WHERE A.rd_unit_id=B.id AND B.rd_unit_id=C.id AND C.rd_unit_id=D.id"), result);
nb = result.count();
SKGAdvice::SKGAdviceActionList autoCorrections;
autoCorrections.reserve(nb);
for (int i = 1; i < nb; ++i) { // Ignore header
// Get parameters
const QStringList& line = result.at(i);
const QString& unit = line.at(0);
SKGAdvice ad;
ad.setUUID(QStringLiteral("skgunitplugin_toocomplex"));
ad.setPriority(9);
ad.setShortMessage(i18nc("Advice on making the best (short)", "The definition of the unit '%1' is too complex", unit));
ad.setLongMessage(i18nc("Advice on making the best (long)", "'%1' is defined relatively to another unit defined relatively to a third one. This is too complex and not supported by Skrooge.", unit));
autoCorrections.resize(0);
{
SKGAdvice::SKGAdviceAction a;
a.Title = i18nc("Advice on making the best (action)", "Edit units");
a.IconName = icon();
a.IsRecommended = false;
autoCorrections.push_back(a);
}
ad.setAutoCorrections(autoCorrections);
output.push_back(ad);
}
}
// Unit with very old values
if (!iIgnoredAdvice.contains(QStringLiteral("skgunitplugin_veryold"))) {
m_currentBankDocument->executeSelectSqliteOrder(QStringLiteral("SELECT t_name from unit WHERE (SELECT COUNT(*) FROM unitvalue WHERE unitvalue.rd_unit_id=unit.id)>1 AND EXISTS (SELECT 1 FROM unitvalue WHERE unitvalue.rd_unit_id=unit.id AND unitvalue.d_date<=(SELECT date('now', '-50 year')))"), result);
nb = result.count();
SKGAdvice::SKGAdviceActionList autoCorrections;
autoCorrections.reserve(nb);
for (int i = 1; i < nb; ++i) { // Ignore header
// Get parameters
const QStringList& line = result.at(i);
const QString& unit = line.at(0);
SKGAdvice ad;
ad.setUUID("skgunitplugin_veryold|" % unit);
ad.setPriority(3);
ad.setShortMessage(i18nc("Advice on making the best (short)", "Unit '%1' has very old values", unit));
ad.setLongMessage(i18nc("Advice on making the best (long)", "Unit '%1' has very old values. Check if this is normal.", unit));
autoCorrections.resize(0);
{
SKGAdvice::SKGAdviceAction a;
a.Title = i18nc("Advice on making the best (action)", "Edit units");
a.IconName = icon();
a.IsRecommended = false;
autoCorrections.push_back(a);
}
ad.setAutoCorrections(autoCorrections);
output.push_back(ad);
}
}
// No decimal settings
if (!iIgnoredAdvice.contains(QStringLiteral("skgunitplugin_decimalsymbol")) && QLocale().decimalPoint().isNull()) {
SKGAdvice ad;
ad.setUUID(QStringLiteral("skgunitplugin_decimalsymbol"));
ad.setPriority(9);
ad.setShortMessage(i18nc("Advice on making the best (short)", "No decimal symbol defined"));
ad.setLongMessage(i18nc("Advice on making the best (long)", "In KDE localization settings, there is no decimal symbol defined for currencies. This could be confusing."));
SKGAdvice::SKGAdviceActionList autoCorrections;
{
SKGAdvice::SKGAdviceAction a;
a.Title = i18nc("Advice on making the best (action)", "Edit KDE settings");
a.IconName = QStringLiteral("configure");
a.IsRecommended = false;
autoCorrections.push_back(a);
}
ad.setAutoCorrections(autoCorrections);
output.push_back(ad);
}
return output;
}
SKGError SKGUnitPlugin::executeAdviceCorrection(const QString& iAdviceIdentifier, int iSolution)
{
if ((m_currentBankDocument != nullptr) && iAdviceIdentifier.startsWith(QLatin1String("skgunitplugin_primaryunit|"))) {
if (iSolution == 1) {
SKGMainPanel::getMainPanel()->openPage(QStringLiteral("skg://skrooge_unit_plugin"));
} else {
// Get parameters
QString unit = iAdviceIdentifier.right(iAdviceIdentifier.length() - 26);
SKGError err;
{
SKGBEGINTRANSACTION(*m_currentBankDocument, i18nc("Noun, name of the user action", "Define primary currency"), err)
SKGUnitObject unitObj(m_currentBankDocument);
err = unitObj.setName(unit);
IFOKDO(err, unitObj.load())
IFOKDO(err, unitObj.setType(SKGUnitObject::PRIMARY))
IFOKDO(err, unitObj.save())
// Send message
IFOKDO(err, unitObj.getDocument()->sendMessage(i18nc("An information to the user", "The unit '%1' is now the primary unit", unitObj.getDisplayName()), SKGDocument::Hidden))
}
// status bar
IFOKDO(err, SKGError(0, i18nc("Message for successful user action", "Primary currency defined.")))
else {
err.addError(ERR_FAIL, i18nc("Error message", "Primary currency definition failed"));
}
// Display error
SKGMainPanel::displayErrorMessage(err);
}
return SKGError();
}
if ((m_currentBankDocument != nullptr) && iAdviceIdentifier.startsWith(QLatin1String("skgunitplugin_secondaryunit|"))) {
if (iSolution == 1) {
SKGMainPanel::getMainPanel()->openPage(QStringLiteral("skg://skrooge_unit_plugin"));
} else {
// Get parameters
QString unit = iAdviceIdentifier.right(iAdviceIdentifier.length() - 28);
SKGError err;
{
SKGBEGINTRANSACTION(*m_currentBankDocument, i18nc("Noun, name of the user action", "Define secondary currency"), err)
SKGUnitObject unitObj(m_currentBankDocument);
err = unitObj.setName(unit);
IFOKDO(err, unitObj.load())
IFOKDO(err, unitObj.setType(SKGUnitObject::SECONDARY))
IFOKDO(err, unitObj.save())
// Send message
IFOKDO(err, unitObj.getDocument()->sendMessage(i18nc("An information to the user", "The unit '%1' is now the secondary unit", unitObj.getDisplayName()), SKGDocument::Hidden))
}
// status bar
IFOKDO(err, SKGError(0, i18nc("Message for successful user action", "Secondary currency defined.")))
else {
err.addError(ERR_FAIL, i18nc("Error message", "Secondary currency definition failed"));
}
// Display error
SKGMainPanel::displayErrorMessage(err);
}
return SKGError();
}
if ((m_currentBankDocument != nullptr) && iAdviceIdentifier.startsWith(QLatin1String("skgunitplugin_notdownloaded|"))) {
if (iSolution == 0) {
SKGMainPanel::getMainPanel()->openPage(QStringLiteral("skg://skrooge_unit_plugin"));
} else {
// Get parameters
QString unit = iAdviceIdentifier.right(iAdviceIdentifier.length() - 28);
SKGError err;
SKGUnitObject unitObj(m_currentBankDocument);
err = unitObj.setName(unit);
IFOKDO(err, unitObj.load())
IFOKDO(err, SKGUnitPluginWidget::downloadUnitValue(unitObj, SKGUnitPluginWidget::getDownloadModeFromSettings()))
// Display error
SKGMainPanel::displayErrorMessage(err);
}
return SKGError();
}
if ((m_currentBankDocument != nullptr) && (iAdviceIdentifier.startsWith(QLatin1String("skgunitplugin_veryold|")) ||
iAdviceIdentifier.startsWith(QLatin1String("skgunitplugin_toocomplex")) ||
iAdviceIdentifier.startsWith(QLatin1String("skgunitplugin_amountnotdefined|")))
) {
SKGMainPanel::getMainPanel()->openPage(QStringLiteral("skg://skrooge_unit_plugin"));
return SKGError();
}
if ((m_currentBankDocument != nullptr) && iAdviceIdentifier.startsWith(QLatin1String("skgunitplugin_decimalsymbol"))) {
QProcess::execute(QStringLiteral("kcmshell5"), QStringList() << QStringLiteral("formats"));
return SKGError();
}
return SKGInterfacePlugin::executeAdviceCorrection(iAdviceIdentifier, iSolution);
}
void SKGUnitPlugin::deleteUnusedUnits() const
{
SKGError err;
_SKGTRACEINFUNCRC(10, err)
if (m_currentBankDocument != nullptr) {
SKGBEGINTRANSACTION(*m_currentBankDocument, i18nc("Noun, name of the user action", "Delete unused units"), err)
// Modification of payee object
QString sql = QStringLiteral("DELETE FROM unit WHERE t_type NOT IN ('I', '1', '2') AND NOT EXISTS (SELECT 1 FROM operation WHERE operation.rc_unit_id=unit.id) AND NOT EXISTS (SELECT 1 FROM unit as unit2 WHERE unit2.rd_unit_id=unit.id)");
err = m_currentBankDocument->executeSqliteOrder(sql);
}
// status bar
IFOKDO(err, SKGError(0, i18nc("Successful message after an user action", "Unused units deleted")))
else {
err.addError(ERR_FAIL, i18nc("Error message", "Unused units deletion failed"));
}
// Display error
SKGMainPanel::displayErrorMessage(err);
}
#include <skgunitplugin.moc>
diff --git a/plugins/skrooge/skrooge_unit/skgunitplugin.h b/plugins/skrooge/skrooge_unit/skgunitplugin.h
index 6f1e365c6..a1a134ef3 100644
--- a/plugins/skrooge/skrooge_unit/skgunitplugin.h
+++ b/plugins/skrooge/skrooge_unit/skgunitplugin.h
@@ -1,162 +1,162 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGUNITPLUGIN_H
#define SKGUNITPLUGIN_H
/** @file
* This file is Skrooge plugin for unit management.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skginterfaceplugin.h"
#include "ui_skgunitpluginwidget_pref.h"
class SKGDocumentBank;
/**
* This file is Skrooge plugin for unit management
*/
class SKGUnitPlugin : public SKGInterfacePlugin
{
Q_OBJECT
Q_INTERFACES(SKGInterfacePlugin)
public:
/**
* Default Constructor
*/
explicit SKGUnitPlugin(QWidget* iWidget, QObject* iParent, const QVariantList& iArg);
/**
* Default Destructor
*/
~SKGUnitPlugin() override;
/**
* Called to initialise the plugin
* @param iDocument the main document
* @return true if the plugin is compatible with the document
*/
bool setupActions(SKGDocument* iDocument) override;
/**
* The page widget of the plugin.
* @return The page widget of the plugin
*/
SKGTabPage* getWidget() override;
/**
* The number of dashboard widgets of the plugin.
* @return The number of dashboard widgets of the plugin
*/
int getNbDashboardWidgets() override;
/**
* Get a dashboard widget title of the plugin.
* @param iIndex the index of the widget
* @return The title
*/
QString getDashboardWidgetTitle(int iIndex) override;
/**
* Get a dashboard widget of the plugin.
* @param iIndex the index of the widget
* @return The dashboard widget of the plugin
*/
SKGBoardWidget* getDashboardWidget(int iIndex) override;
/**
* Must be modified to refresh widgets after a modification.
*/
void refresh() override;
/**
* The preference widget of the plugin.
* @return The preference widget of the plugin
*/
QWidget* getPreferenceWidget() override;
/**
* The preference skeleton of the plugin.
* @return The preference skeleton of the plugin
*/
KConfigSkeleton* getPreferenceSkeleton() override;
/**
* The title of the plugin.
* @return The title of the plugin
*/
QString title() const override;
/**
* The icon of the plugin.
* @return The icon of the plugin
*/
QString icon() const override;
/**
* The toolTip of the plugin.
* @return The toolTip of the plugin
*/
QString toolTip() const override;
/**
* The tips list of the plugin.
* @return The tips list of the plugin
*/
QStringList tips() const override;
/**
* Must be implemented to set the position of the plugin.
* @return integer value between 0 and 999 (default = 999)
*/
int getOrder() const override;
/**
* Must be implemented to know if a plugin must be display in pages chooser.
* @return true of false (default = false)
*/
bool isInPagesChooser() const override;
/**
* The advice list of the plugin.
* @return The advice list of the plugin
*/
SKGAdviceList advice(const QStringList& iIgnoredAdvice) override;
/**
* Must be implemented to execute the automatic correction for the advice.
* @param iAdviceIdentifier the identifier of the advice
* @param iSolution the identifier of the possible solution
* @return an object managing the error. MUST return ERR_NOTIMPL if iAdviceIdentifier is not known
* @see SKGError
*/
SKGError executeAdviceCorrection(const QString& iAdviceIdentifier, int iSolution) override;
private Q_SLOTS:
void onSplitShare();
void deleteUnusedUnits() const;
private:
Q_DISABLE_COPY(SKGUnitPlugin)
SKGDocumentBank* m_currentBankDocument;
QString m_docUniqueIdentifier;
Ui::skgunitplugin_pref ui{};
};
#endif // SKGUNITPLUGIN_H
diff --git a/plugins/skrooge/skrooge_unit/skgunitpluginwidget.cpp b/plugins/skrooge/skrooge_unit/skgunitpluginwidget.cpp
index eb82124e4..270eb4237 100644
--- a/plugins/skrooge/skrooge_unit/skgunitpluginwidget.cpp
+++ b/plugins/skrooge/skrooge_unit/skgunitpluginwidget.cpp
@@ -1,939 +1,939 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is Skrooge plugin for unit management.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgunitpluginwidget.h"
#include <klocalizedstring.h>
#include <kns3/downloaddialog.h>
#include <kns3/uploaddialog.h>
#include <krun.h>
#include <kzip.h>
#include <qdir.h>
#include <qdom.h>
#include <qevent.h>
#include <qfile.h>
#include <qsortfilterproxymodel.h>
#include <qstandardpaths.h>
#include <qurl.h>
#include <qvalidator.h>
#include "skgbankincludes.h"
#include "skgmainpanel.h"
#include "skgobjectmodel.h"
#include "skgservices.h"
#include "skgtraces.h"
#include "skgunit_settings.h"
SKGUnitPluginWidget::SKGUnitPluginWidget(QWidget* iParent, SKGDocumentBank* iDocument)
: SKGTabPage(iParent, iDocument), m_upload(nullptr), m_unitValueGraphCmb(nullptr)
{
SKGTRACEINFUNC(10)
if (iDocument == nullptr) {
return;
}
ui.setupUi(this);
ui.kGraph->setShadowVisible(false);
m_unitValueGraphCmb = new SKGComboBox(this);
m_unitValueGraphCmb->addItem(i18nc("A mode of graph of unit values", "Unit values"));
m_unitValueGraphCmb->addItem(i18nc("A mode of graph of unit values", "Amount owned"));
connect(m_unitValueGraphCmb, static_cast<void (SKGComboBox::*)(int)>(&SKGComboBox::currentIndexChanged), this, &SKGUnitPluginWidget::onSelectionChanged);
ui.kGraph->graph()->addToolbarWidget(m_unitValueGraphCmb);
ui.kNameLbl->setText(i18n("%1:", iDocument->getDisplay(QStringLiteral("t_name"))));
ui.kDecimalLbl->setText(i18n("%1:", iDocument->getDisplay(QStringLiteral("i_nbdecimal"))));
ui.kCountyLbl->setText(i18n("%1:", iDocument->getDisplay(QStringLiteral("t_country"))));
ui.kSymbolLbl->setText(i18n("%1:", iDocument->getDisplay(QStringLiteral("t_symbol"))));
ui.kTypeLbl->setText(i18n("%1:", iDocument->getDisplay(QStringLiteral("t_type"))));
ui.kInternetLbl->setText(i18n("%1:", iDocument->getDisplay(QStringLiteral("t_internet_code"))));
ui.kDateLabel->setText(i18n("%1:", iDocument->getDisplay(QStringLiteral("d_date"))));
ui.kAmountLabel->setText(i18n("%1:", iDocument->getDisplay(QStringLiteral("f_value"))));
ui.kUnitLbl->setText(i18n("%1:", iDocument->getDisplay(QStringLiteral("t_UNIT"))));
ui.kUnitLbl->setText(i18n("%1:", iDocument->getDisplay(QStringLiteral("t_UNIT"))));
ui.kDownloadSourceLbl->setText(i18n("%1:", iDocument->getDisplay(QStringLiteral("t_source"))));
ui.kUnitTableViewEdition->getShowWidget()->addItem(QStringLiteral("all"), i18nc("Noun, items to display", "All"), QLatin1String(""),
QLatin1String(""),
QStringLiteral("currency;share;index;object"), // Check when checked
QStringLiteral("highlighted"), // Uncheck when checked
QLatin1String(""), QLatin1String(""),
Qt::META + Qt::Key_A);
ui.kUnitTableViewEdition->getShowWidget()->addItem(QStringLiteral("highlighted"), i18n("Highlighted only"), QStringLiteral("bookmarks"), QStringLiteral("t_bookmarked='Y'"), QLatin1String(""), QStringLiteral("all;currency;share;index;object"), QStringLiteral("all"), QLatin1String(""), Qt::META + Qt::Key_H);
ui.kUnitTableViewEdition->getShowWidget()->addSeparator();
ui.kUnitTableViewEdition->getShowWidget()->addItem(QStringLiteral("currency"), i18nc("Noun, a country's currency", "Currency"), QLatin1String(""),
QStringLiteral("t_type IN ('1','2','C')"),
QLatin1String(""), // Check when checked
QStringLiteral("highlighted"), // Uncheck when checked
QLatin1String(""), // Check when unchecked
QStringLiteral("all"), Qt::META + Qt::Key_C); // Uncheck when unchecked
ui.kUnitTableViewEdition->getShowWidget()->addItem(QStringLiteral("share"), i18nc("Noun, a financial share, as in a stock market", "Share"), QLatin1String(""),
QStringLiteral("t_type='S'"),
QLatin1String(""),
QStringLiteral("highlighted"),
QLatin1String(""),
QStringLiteral("all"), Qt::META + Qt::Key_S);
ui.kUnitTableViewEdition->getShowWidget()->addItem(QStringLiteral("index"), i18nc("Noun, a financial index like the Dow Jones, NASDAQ, CAC40...", "Index"), QLatin1String(""),
QStringLiteral("t_type='I'"),
QLatin1String(""),
QStringLiteral("highlighted"),
QLatin1String(""),
QStringLiteral("all;current"), Qt::META + Qt::Key_I);
ui.kUnitTableViewEdition->getShowWidget()->addItem(QStringLiteral("object"), i18nc("Noun, a physical object like a house or a car", "Object"), QLatin1String(""),
QStringLiteral("t_type='O'"),
QLatin1String(""),
QStringLiteral("highlighted"),
QLatin1String(""),
QStringLiteral("all"), Qt::META + Qt::Key_O);
ui.kUnitTableViewEdition->getShowWidget()->setDefaultState(QStringLiteral("all;currency;share;index;object"));
ui.kGraph->getShowWidget()->setState(QStringLiteral("\"graph\""));
ui.kGraph->setFilterVisibility(false);
ui.kUnitCreatorUnit->setDocument(iDocument);
ui.kUnitCreatorUnit->setWhereClauseCondition(QStringLiteral("t_type IN ('1','2','C')"));
// Add Standard KDE Icons to buttons to Accounts
ui.kUnitAdd->setIcon(SKGServices::fromTheme(QStringLiteral("list-add")));
ui.kUnitUpdate->setIcon(SKGServices::fromTheme(QStringLiteral("dialog-ok")));
ui.kUnitValueDownload->setIcon(SKGServices::fromTheme(QStringLiteral("download")));
ui.kDeleteSource->setIcon(SKGServices::fromTheme(QStringLiteral("edit-delete")));
ui.kGetNewHotStuff->setIcon(SKGServices::fromTheme(QStringLiteral("get-hot-new-stuff")));
auto newValidator = new QRegExpValidator(QRegExp(QStringLiteral("^[\\w\\s]+$")), this);
ui.kDownloadSource->setValidator(newValidator);
QStringList overlays;
overlays.push_back(QStringLiteral("list-add"));
m_upload = new QAction(SKGServices::fromTheme(QStringLiteral("get-hot-new-stuff"), overlays), i18n("Upload"), this);
connect(m_upload, &QAction::triggered, this, &SKGUnitPluginWidget::onPutNewHotStuff);
auto menu = new QMenu(this);
menu->addAction(m_upload);
ui.kGetNewHotStuff->setMenu(menu);
ui.kUnitOpen->setIcon(SKGServices::fromTheme(QStringLiteral("quickopen")));
connect(ui.kUnitOpen, &QPushButton::clicked, this, &SKGUnitPluginWidget::onOpenURL);
auto downloadLastAction = new QAction(SKGServices::fromTheme(QStringLiteral("download")), i18n("download last value only"), this);
downloadLastAction->setData(static_cast<int>(SKGUnitObject::LAST));
connect(downloadLastAction, &QAction::triggered, this, &SKGUnitPluginWidget::onDownloadUnitValue);
auto downloadLastMonthlyAction = new QAction(SKGServices::fromTheme(QStringLiteral("download")), i18n("download monthly values since last known value"), this);
downloadLastMonthlyAction->setData(static_cast<int>(SKGUnitObject::LAST_MONTHLY));
connect(downloadLastMonthlyAction, &QAction::triggered, this, &SKGUnitPluginWidget::onDownloadUnitValue);
auto downloadLastWeeklyAction = new QAction(SKGServices::fromTheme(QStringLiteral("download")), i18n("download weekly values since last known value"), this);
downloadLastWeeklyAction->setData(static_cast<int>(SKGUnitObject::LAST_WEEKLY));
connect(downloadLastWeeklyAction, &QAction::triggered, this, &SKGUnitPluginWidget::onDownloadUnitValue);
auto downloadLastDailyAction = new QAction(SKGServices::fromTheme(QStringLiteral("download")), i18n("download daily values since last known value"), this);
downloadLastDailyAction->setData(static_cast<int>(SKGUnitObject::LAST_DAILY));
connect(downloadLastDailyAction, &QAction::triggered, this, &SKGUnitPluginWidget::onDownloadUnitValue);
auto downloadMonthlyAction = new QAction(SKGServices::fromTheme(QStringLiteral("download")), i18n("download all monthly values"), this);
downloadMonthlyAction->setData(static_cast<int>(SKGUnitObject::ALL_MONTHLY));
connect(downloadMonthlyAction, &QAction::triggered, this, &SKGUnitPluginWidget::onDownloadUnitValue);
auto downloadWeeklyAction = new QAction(SKGServices::fromTheme(QStringLiteral("download")), i18n("download all weekly values"), this);
downloadWeeklyAction->setData(static_cast<int>(SKGUnitObject::ALL_WEEKLY));
connect(downloadWeeklyAction, &QAction::triggered, this, &SKGUnitPluginWidget::onDownloadUnitValue);
auto downloadDailyAction = new QAction(SKGServices::fromTheme(QStringLiteral("download")), i18n("download all daily values"), this);
downloadDailyAction->setData(static_cast<int>(SKGUnitObject::ALL_DAILY));
connect(downloadDailyAction, &QAction::triggered, this, &SKGUnitPluginWidget::onDownloadUnitValue);
auto simplifyAction = new QAction(SKGServices::fromTheme(QStringLiteral("edit-delete")), i18n("simplify values"), this);
connect(simplifyAction, &QAction::triggered, this, &SKGUnitPluginWidget::onSimplify);
auto downloadMenu = new QMenu(this);
downloadMenu->addAction(downloadLastAction);
downloadMenu->addAction(downloadLastMonthlyAction);
downloadMenu->addAction(downloadLastWeeklyAction);
downloadMenu->addAction(downloadLastDailyAction);
downloadMenu->addAction(downloadMonthlyAction);
downloadMenu->addAction(downloadWeeklyAction);
downloadMenu->addAction(downloadDailyAction);
downloadMenu->addAction(simplifyAction);
ui.kUnitValueDownload->setMenu(downloadMenu);
connect(ui.kUnitValueDownload, &QToolButton::clicked, this, &SKGUnitPluginWidget::onDownloadUnitValue);
{
SKGWidgetSelector::SKGListQWidget list;
list.push_back(ui.kStandardFrm);
list.push_back(ui.kBtnFrm);
ui.kWidgetSelector->addButton(SKGServices::fromTheme(QStringLiteral("dialog-ok")), i18n("Standard"), i18n("Display the edit panel for standard units"), list);
}
{
SKGWidgetSelector::SKGListQWidget list;
list.push_back(ui.kManualFrm);
list.push_back(ui.kBtnFrm);
ui.kWidgetSelector->addButton(SKGServices::fromTheme(QStringLiteral("user-properties")), i18n("Manual / Share"), i18n("Display the edit panel for manual units"), list);
}
{
SKGWidgetSelector::SKGListQWidget list;
list.push_back(ui.kValuesFrm);
list.push_back(ui.kBtnFrm);
ui.kWidgetSelector->addButton(SKGServices::fromTheme(QStringLiteral("taxes-finances")), i18n("Values"), i18n("Display the edit panel for values of units"), list);
}
connect(ui.kWidgetSelector, &SKGWidgetSelector::selectedModeChanged, this, &SKGUnitPluginWidget::onUnitCreatorModified);
// Fill combo box for type
ui.kTypeCreatorUnit->addItem(i18nc("Noun", "Primary currency"), static_cast<int>(SKGUnitObject::PRIMARY));
ui.kTypeCreatorUnit->addItem(i18nc("Noun", "Secondary currency"), static_cast<int>(SKGUnitObject::SECONDARY));
ui.kTypeCreatorUnit->addItem(i18nc("Noun, a country's currency", "Currency"), static_cast<int>(SKGUnitObject::CURRENCY));
ui.kTypeCreatorUnit->addItem(i18nc("Noun, a financial share, as in a stock market", "Share"), static_cast<int>(SKGUnitObject::SHARE));
ui.kTypeCreatorUnit->addItem(i18nc("Noun, a financial index like the Dow Jones, NASDAQ, CAC40...", "Index"), static_cast<int>(SKGUnitObject::INDEX));
ui.kTypeCreatorUnit->addItem(i18nc("Noun, a physical object like a house or a car", "Object"), static_cast<int>(SKGUnitObject::OBJECT));
bool primaryUnit, secondaryUnit;
iDocument->existObjects(QStringLiteral("unit"), QStringLiteral("t_type='1'"), primaryUnit);
iDocument->existObjects(QStringLiteral("unit"), QStringLiteral("t_type='2'"), secondaryUnit);
if (primaryUnit) {
if (secondaryUnit) {
ui.kTypeCreatorUnit->setCurrentIndex(2);
} else {
ui.kTypeCreatorUnit->setCurrentIndex(1);
}
} else {
ui.kTypeCreatorUnit->setCurrentIndex(0);
}
// Bind unit creation view
{
ui.kUnitTableViewEdition->setModel(new SKGObjectModel(qobject_cast<SKGDocumentBank*>(getDocument()), QStringLiteral("v_unit_display"), QLatin1String(""), this, QLatin1String(""), false));
connect(ui.kUnitTableViewEdition->getView(), &SKGTreeView::clickEmptyArea, this, &SKGUnitPluginWidget::cleanEditor);
connect(ui.kUnitTableViewEdition->getView(), &SKGTreeView::doubleClicked, SKGMainPanel::getMainPanel()->getGlobalAction(QStringLiteral("open")).data(), &QAction::trigger);
connect(ui.kUnitTableViewEdition->getView(), &SKGTreeView::selectionChangedDelayed, this, [ = ] {this->onSelectionChanged();});
}
// Bind unit creation view
{
auto objectModel2 = new SKGObjectModel(qobject_cast<SKGDocumentBank*>(getDocument()), QStringLiteral("v_unitvalue_display"), QStringLiteral("1=0"), this, QLatin1String(""), false);
ui.kUnitValueTableViewEdition->setModel(objectModel2);
connect(ui.kUnitValueTableViewEdition, &SKGTableView::selectionChangedDelayed, this, &SKGUnitPluginWidget::onSelectionValueChanged);
}
// Refresh
connect(getDocument(), &SKGDocument::tableModified, this, &SKGUnitPluginWidget::dataModified, Qt::QueuedConnection);
ui.kWidgetSelector->setSelectedMode(0);
// Fill combo box for reference currency
fillSourceList();
dataModified(QLatin1String(""), 0);
// Set Event filters to catch CTRL+ENTER or SHIFT+ENTER
this->installEventFilter(this);
// Synchronize zooms of both tables
connect(ui.kUnitTableViewEdition->getView(), &SKGTreeView::zoomChanged, ui.kUnitValueTableViewEdition, &SKGTreeView::setZoomPosition);
connect(ui.kUnitValueTableViewEdition, &SKGTreeView::zoomChanged, ui.kUnitTableViewEdition->getView(), &SKGTreeView::setZoomPosition);
// Other connects
connect(ui.kNameCreatorUnit, &QLineEdit::textChanged, this, &SKGUnitPluginWidget::onUnitCreatorModified);
connect(ui.kUnitAdd, &QPushButton::clicked, this, &SKGUnitPluginWidget::onAddUnit);
connect(ui.kUnitUpdate, &QPushButton::clicked, this, &SKGUnitPluginWidget::onModifyUnit);
connect(ui.kInternetCreatorUnit, &QLineEdit::textChanged, this, &SKGUnitPluginWidget::onUnitCreatorModified);
connect(ui.kSymbolCreatorUnit, &QLineEdit::textChanged, this, &SKGUnitPluginWidget::onUnitCreatorModified);
connect(ui.kObsolete, &QCheckBox::toggled, this, &SKGUnitPluginWidget::refreshUnitList);
connect(ui.kAmountEdit, &SKGCalculatorEdit::textChanged, this, &SKGUnitPluginWidget::onUnitCreatorModified);
connect(ui.kDeleteSource, &QToolButton::clicked, this, &SKGUnitPluginWidget::onDeleteSource);
connect(ui.kDownloadSource, static_cast<void (SKGComboBox::*)()>(&SKGComboBox::returnPressed), this, &SKGUnitPluginWidget::onAddSource);
connect(ui.kDownloadSource, &SKGComboBox::editTextChanged, this, &SKGUnitPluginWidget::onSourceChanged);
connect(ui.kGetNewHotStuff, &QToolButton::clicked, this, &SKGUnitPluginWidget::onGetNewHotStuff);
// Fill combo box for currency
m_timer.setSingleShot(true);
connect(&m_timer, &QTimer::timeout, this, &SKGUnitPluginWidget::refreshUnitList);
m_timer.start(500);
onSourceChanged();
}
SKGUnitPluginWidget::~SKGUnitPluginWidget()
{
SKGTRACEINFUNC(10)
}
bool SKGUnitPluginWidget::eventFilter(QObject* iObject, QEvent* iEvent)
{
if ((iEvent != nullptr) && iEvent->type() == QEvent::KeyPress) {
auto* keyEvent = dynamic_cast<QKeyEvent*>(iEvent);
if (keyEvent && (keyEvent->key() == Qt::Key_Return || keyEvent->key() == Qt::Key_Enter) && iObject == this) {
if ((QApplication::keyboardModifiers() & Qt::ControlModifier) != 0u && ui.kUnitAdd->isEnabled()) {
ui.kUnitAdd->click();
} else if ((QApplication::keyboardModifiers() & Qt::ShiftModifier) != 0u && ui.kUnitUpdate->isEnabled()) {
ui.kUnitUpdate->click();
}
}
}
return SKGTabPage::eventFilter(iObject, iEvent);
}
void SKGUnitPluginWidget::fillSourceList()
{
// Get previous selected item
QString current = ui.kDownloadSource->text();
// Fill
ui.kDownloadSource->clear();
ui.kDownloadSource->addItems(SKGUnitObject::downloadSources());
ui.kDeleteSource->hide();
// Set previous selected itemData
if (!current.isEmpty() && ui.kDownloadSource->contains(current)) {
ui.kDownloadSource->setCurrentItem(current);
}
}
void SKGUnitPluginWidget::onSelectionChanged()
{
SKGTRACEINFUNC(10)
// Mapping
SKGUnitObject unit;
int nbSelect = ui.kUnitTableViewEdition->getView()->getNbSelectedObjects();
if (nbSelect == 1) {
unit = ui.kUnitTableViewEdition->getView()->getFirstSelectedObject();
ui.kNameCreatorUnit->setText(unit.getName());
ui.kSymbolCreatorUnit->setText(unit.getSymbol());
ui.kCountryCreatorUnit->setText(unit.getCountry());
ui.kTypeCreatorUnit->setCurrentIndex(ui.kTypeCreatorUnit->findData(static_cast<int>(unit.getType())));
ui.kInternetCreatorUnit->setText(unit.getInternetCode());
ui.kUnitCreatorUnit->setText(unit.getAttribute(QStringLiteral("t_UNIT")));
ui.kNbDecimal->setValue(unit.getNumberDecimal());
ui.kDownloadSource->setText(unit.getDownloadSource());
} else if (nbSelect > 1) {
ui.kNameCreatorUnit->setText(NOUPDATE);
ui.kSymbolCreatorUnit->setText(NOUPDATE);
ui.kCountryCreatorUnit->setText(NOUPDATE);
ui.kTypeCreatorUnit->setText(NOUPDATE);
ui.kInternetCreatorUnit->setText(NOUPDATE);
ui.kUnitCreatorUnit->setText(NOUPDATE);
ui.kDownloadSource->setText(NOUPDATE);
}
ui.kUnitValueFrame->setEnabled(nbSelect == 1);
ui.kUnitValueDownload->setEnabled(nbSelect > 0);
ui.kUnitOpen->setEnabled(nbSelect > 0);
// Fill values
QString wc = "rd_unit_id=(select id from unit where t_name='" % SKGServices::stringToSqlString(ui.kNameCreatorUnit->text()) % "')";
auto* objectModel = qobject_cast<SKGObjectModel*>(ui.kUnitValueTableViewEdition->model());
if (objectModel != nullptr) {
objectModel->setFilter(QLatin1String("")); // Correction 2299600: to be sure that refresh will be done
objectModel->setFilter(wc % " order by d_date desc");
objectModel->refresh();
}
ui.kUnitOfUnitLbl->setText(ui.kUnitCreatorUnit->text());
// Draw plot
SKGStringListList table;
getDocument()->getConsolidatedView(QStringLiteral("v_unitvalue_display"), QStringLiteral("d_date"), QStringLiteral("t_UNIT"),
m_unitValueGraphCmb->currentIndex() == 0 ? QStringLiteral("f_quantity") : QStringLiteral("f_AMOUNTOWNED"),
QStringLiteral("TOTAL"), wc % " AND d_date>(SELECT date('now', '-50 year')) AND d_date<(SELECT date('now', '+50 year'))", table, QLatin1String(""));
SKGServices::SKGUnitInfo primaryUnit = qobject_cast<SKGDocumentBank*>(getDocument())->getPrimaryUnit();
SKGServices::SKGUnitInfo secondaryUnit = qobject_cast<SKGDocumentBank*>(getDocument())->getSecondaryUnit();
if (unit.getType() == SKGUnitObject::INDEX) {
primaryUnit.Symbol = QLatin1String("");
secondaryUnit.Symbol = QLatin1String("");
} else {
SKGUnitObject parentUnitObject;
unit.getUnit(parentUnitObject);
SKGServices::SKGUnitInfo parentUnit = parentUnitObject.getUnitInfo();
if (primaryUnit.Symbol != parentUnit.Symbol) {
secondaryUnit = primaryUnit;
primaryUnit = parentUnit;
secondaryUnit.Value = 1.0 / primaryUnit.Value;
primaryUnit.Value = 1;
}
}
ui.kGraph->setData(table, primaryUnit, secondaryUnit, SKGTableWithGraph::LIMITS);
// Correction bug 2299394 vvv
if (ui.kUnitValueTableViewEdition->isAutoResized()) {
ui.kUnitValueTableViewEdition->resizeColumnsToContentsDelayed();
}
// Correction bug 2299394 ^^^
onUnitCreatorModified();
Q_EMIT selectionChanged();
}
void SKGUnitPluginWidget::onSelectionValueChanged()
{
SKGTRACEINFUNC(10)
// Mapping
QItemSelectionModel* selModel = ui.kUnitValueTableViewEdition->selectionModel();
if (selModel != nullptr) {
QModelIndexList indexes = selModel->selectedRows();
int nbSelect = indexes.count();
if (nbSelect != 0) {
QModelIndex idx = indexes[indexes.count() - 1];
auto* model = qobject_cast<SKGObjectModel*>(ui.kUnitValueTableViewEdition->model());
if (model != nullptr) {
SKGUnitValueObject unitValue(model->getObject(idx));
SKGUnitObject unit;
unitValue.getUnit(unit);
ui.kDateEdit->setDate(unitValue.getDate());
ui.kAmountEdit->setText(SKGServices::toCurrencyString(SKGServices::stringToDouble(unitValue.getAttribute(QStringLiteral("f_quantity"))),
QLatin1String(""),
SKGServices::stringToInt(unit.getAttribute(QStringLiteral("i_nbdecimal")))));
}
} else {
ui.kDateEdit->setDate(QDate::currentDate());
ui.kAmountEdit->setText(QLatin1String(""));
}
Q_EMIT selectionChanged();
}
}
void SKGUnitPluginWidget::onUnitCreatorModified()
{
SKGTRACEINFUNC(10)
bool activated = ui.kWidgetSelector->getSelectedMode() != -1 &&
!ui.kNameCreatorUnit->text().isEmpty() &&
!ui.kSymbolCreatorUnit->text().isEmpty();
int nbSelect = getNbSelectedObjects();
ui.kUnitAdd->setEnabled((activated && (ui.kAmountEdit->valid() || ui.kWidgetSelector->getSelectedMode() != 2)) || ui.kWidgetSelector->getSelectedMode() == 0);
ui.kUnitUpdate->setEnabled(activated && nbSelect > 0 && ui.kWidgetSelector->getSelectedMode() == 1);
ui.kWidgetSelector->setEnabledMode(2, nbSelect == 1);
if (!(activated && nbSelect > 0) && ui.kWidgetSelector->getSelectedMode() == 2) {
ui.kWidgetSelector->setSelectedMode(0);
}
}
void SKGUnitPluginWidget::onAddUnit()
{
SKGError err;
SKGTRACEINFUNCRC(10, err)
int mode = ui.kWidgetSelector->getSelectedMode();
if (mode == 0) {
QString untiname = ui.kCurrencyList->text();
SKGBEGINTRANSACTION(*getDocument(), i18nc("Noun, name of the user action", "Unit creation '%1'", untiname), err)
SKGUnitObject oUnit;
err = SKGUnitObject::createCurrencyUnit(qobject_cast<SKGDocumentBank*>(getDocument()), ui.kCurrencyList->text(), oUnit);
} else if (mode == 1) {
QString untiname = ui.kNameCreatorUnit->text();
SKGUnitObject unitObj(getDocument());
{
SKGBEGINTRANSACTION(*getDocument(), i18nc("Noun, name of the user action", "Unit creation '%1'", untiname), err)
// Create unit object
IFOKDO(err, unitObj.setName(untiname))
IFOKDO(err, unitObj.setSymbol(ui.kSymbolCreatorUnit->text()))
IFOKDO(err, unitObj.setCountry(ui.kCountryCreatorUnit->text()))
IFOKDO(err, unitObj.setInternetCode(ui.kInternetCreatorUnit->text()))
IFOKDO(err, unitObj.setType(static_cast<SKGUnitObject::UnitType>(ui.kTypeCreatorUnit->itemData(ui.kTypeCreatorUnit->currentIndex()).toInt())))
IFOKDO(err, unitObj.setNumberDecimal(ui.kNbDecimal->value()))
IFOKDO(err, unitObj.setUnit(ui.kUnitCreatorUnit->getUnit()))
IFOKDO(err, unitObj.setDownloadSource(ui.kDownloadSource->text()))
IFOKDO(err, unitObj.save())
}
// status bar
IFOK(err) {
err = SKGError(0, i18nc("Successful message after an user action", "Unit '%1' created", untiname));
ui.kUnitTableViewEdition->getView()->selectObject(unitObj.getUniqueID());
} else {
err.addError(ERR_FAIL, i18nc("Error message", "Unit creation failed"));
}
} else if (mode == 2) {
QString untiname = ui.kNameCreatorUnit->text();
SKGUnitValueObject unitValueObject;
{
SKGBEGINTRANSACTION(*getDocument(), i18nc("Noun, name of the user action", "Unit value creation for '%1'", untiname), err)
IFOKDO(err, qobject_cast<SKGDocumentBank*>(getDocument())->addOrModifyUnitValue(untiname, ui.kDateEdit->date(), ui.kAmountEdit->value(), &unitValueObject))
}
// status bar
IFOK(err) {
err = SKGError(0, i18nc("Successful message after an user action", "Unit value created for '%1'", untiname));
// BUG: doesn't work because of unit table is modified an refreshed
ui.kUnitValueTableViewEdition->selectObject(unitValueObject.getUniqueID());
} else {
err.addError(ERR_FAIL, i18nc("Error message", "Unit value creation failed"));
}
}
// Display error
SKGMainPanel::displayErrorMessage(err, true);
}
void SKGUnitPluginWidget::onModifyUnit()
{
SKGError err;
SKGTRACEINFUNCRC(10, err)
// Get Selection
SKGObjectBase::SKGListSKGObjectBase selection = ui.kUnitTableViewEdition->getView()->getSelectedObjects();
int nb = selection.count();
{
SKGBEGINPROGRESSTRANSACTION(*getDocument(), i18nc("Noun, name of the user action", "Unit update"), err, nb)
auto name = ui.kNameCreatorUnit->text();
if (name != NOUPDATE && !name.startsWith(QLatin1String("="))) {
// Is this name already existing?
bool messageSent = false;
SKGUnitObject p(getDocument());
p.setName(name);
IFOK(p.load()) {
if (selection.indexOf(p) == -1) {
// We will have to merge with the existing unit
selection.insert(0, p);
nb++;
getDocument()->sendMessage(i18nc("Information message", "You tried to modify names of selected units to an existing unit. Units have been merged."));
messageSent = true;
}
}
// Is it a massive modification of payees to merge them ?
if (nb > 1) {
if (!messageSent) {
getDocument()->sendMessage(i18nc("Information message", "You tried to modify all names of selected units. Units have been merged."));
}
// Do the merge
SKGUnitObject unitObj1(selection[0]);
for (int i = 1; !err && i < nb; ++i) {
SKGUnitObject unitObj(selection.at(i));
err = unitObj1.merge(unitObj);
}
// Change selection for the rest of the operation
selection.clear();
selection.push_back(unitObj1);
nb = 1;
}
}
for (int i = 0; !err && i < nb; ++i) {
// Modification of unit object
SKGUnitObject unitObj(selection.at(i));
IFOKDO(err, unitObj.setName(name))
IFOKDO(err, unitObj.setSymbol(ui.kSymbolCreatorUnit->text()))
IFOKDO(err, unitObj.setCountry(ui.kCountryCreatorUnit->text()))
IFOKDO(err, unitObj.setInternetCode(ui.kInternetCreatorUnit->text()))
if (!err && ui.kTypeCreatorUnit->text() != NOUPDATE) {
err = unitObj.setType(static_cast<SKGUnitObject::UnitType>(ui.kTypeCreatorUnit->itemData(ui.kTypeCreatorUnit->currentIndex()).toInt()));
}
IFOKDO(err, unitObj.setNumberDecimal(ui.kNbDecimal->value()))
if (!err && ui.kUnitCreatorUnit->text() != NOUPDATE) {
err = unitObj.setUnit(ui.kUnitCreatorUnit->getUnit());
}
if (!err && ui.kDownloadSource->text() != NOUPDATE) {
err = unitObj.setDownloadSource(ui.kDownloadSource->text());
}
IFOKDO(err, unitObj.save())
// Send message
IFOKDO(err, getDocument()->sendMessage(i18nc("An information to the user", "The unit '%1' has been updated", unitObj.getDisplayName()), SKGDocument::Hidden))
IFOKDO(err, getDocument()->stepForward(i + 1))
}
}
// status bar
IFOKDO(err, SKGError(0, i18nc("Message for successful user action", "Unit updated")))
else {
err.addError(ERR_FAIL, i18nc("Error message", "Unit update failed"));
}
// Display error
SKGMainPanel::displayErrorMessage(err, true);
// Set focus on table
ui.kUnitTableViewEdition->getView()->setFocus();
}
SKGUnitObject::UnitDownloadMode SKGUnitPluginWidget::getDownloadModeFromSettings()
{
SKGUnitObject::UnitDownloadMode mode = SKGUnitObject::LAST;
if (skgunit_settings::last()) {
mode = SKGUnitObject::LAST;
} else if (skgunit_settings::last_monthly()) {
mode = SKGUnitObject::LAST_MONTHLY;
} else if (skgunit_settings::last_weekly()) {
mode = SKGUnitObject::LAST_WEEKLY;
} else if (skgunit_settings::last_daily()) {
mode = SKGUnitObject::LAST_DAILY;
} else if (skgunit_settings::all_monthly()) {
mode = SKGUnitObject::ALL_MONTHLY;
} else if (skgunit_settings::all_weekly()) {
mode = SKGUnitObject::ALL_WEEKLY;
} else if (skgunit_settings::all_daily()) {
mode = SKGUnitObject::ALL_DAILY;
}
return mode;
}
SKGError SKGUnitPluginWidget::downloadUnitValue(const SKGUnitObject& iUnit, SKGUnitObject::UnitDownloadMode iMode)
{
SKGError err;
SKGTRACEINFUNCRC(10, err)
QString unitname = iUnit.getName();
QString code = iUnit.getInternetCode();
auto* doc = qobject_cast<SKGDocumentBank*>(iUnit.getDocument());
if (!code.isEmpty() && (doc != nullptr)) {
SKGBEGINTRANSACTION(*doc, i18nc("Noun, name of the user action", "Download values for [%1 (%2)]", unitname, code), err)
err = const_cast<SKGUnitObject*>(&iUnit)->downloadUnitValue(iMode, skgunit_settings::nb_loaded_values());
}
return err;
}
void SKGUnitPluginWidget::onDownloadUnitValue()
{
SKGError err;
SKGTRACEINFUNCRC(10, err)
SKGUnitObject::UnitDownloadMode mode = SKGUnitObject::LAST;
auto* act = qobject_cast<QAction*>(sender());
if (act != nullptr) {
mode = static_cast<SKGUnitObject::UnitDownloadMode>(act->data().toInt());
} else {
mode = SKGUnitPluginWidget::getDownloadModeFromSettings();
}
SKGObjectBase::SKGListSKGObjectBase selection = ui.kUnitTableViewEdition->getView()->getSelectedObjects();
int nb = selection.count();
if (nb != 0) {
SKGBEGINPROGRESSTRANSACTION(*getDocument(), i18nc("Noun, name of the user action", "Download values"), err, nb)
for (int i = 0; !err && i < nb; ++i) {
SKGUnitObject unit(selection.at(i));
err = downloadUnitValue(unit, mode);
// Send message
IFOKDO(err, getDocument()->sendMessage(i18nc("An information to the user", "The unit '%1' has been downloaded", unit.getDisplayName()), SKGDocument::Hidden))
IFOKDO(err, getDocument()->stepForward(i + 1))
}
}
IFOKDO(err, SKGError(0, i18nc("Successful message after an user action", "Download done")))
else {
err.addError(ERR_FAIL, i18nc("Error message", "Download failed"));
}
// Display error
SKGMainPanel::displayErrorMessage(err);
}
void SKGUnitPluginWidget::onSimplify()
{
SKGError err;
SKGTRACEINFUNCRC(10, err)
SKGObjectBase::SKGListSKGObjectBase selection = ui.kUnitTableViewEdition->getView()->getSelectedObjects();
int nb = selection.count();
if (nb != 0) {
SKGBEGINPROGRESSTRANSACTION(*getDocument(), i18nc("Noun, name of the user action", "Simplify unit values"), err, nb)
for (int i = 0; !err && i < nb; ++i) {
SKGUnitObject unit(selection.at(i));
err = unit.simplify();
// Send message
IFOKDO(err, getDocument()->sendMessage(i18nc("An information to the user", "The unit '%1' has been simplified", unit.getDisplayName()), SKGDocument::Hidden))
IFOKDO(err, getDocument()->stepForward(i + 1))
}
}
IFOKDO(err, SKGError(0, i18nc("Successful message after an user action", "Simplification done")))
else {
err.addError(ERR_FAIL, i18nc("Error message", "Simplification failed"));
}
// Display error
SKGMainPanel::displayErrorMessage(err);
}
SKGObjectBase::SKGListSKGObjectBase SKGUnitPluginWidget::getSelectedObjects()
{
SKGObjectBase::SKGListSKGObjectBase output;
if (ui.kUnitValueTableViewEdition->hasFocus()) {
output = ui.kUnitValueTableViewEdition->getSelectedObjects();
}
if (output.isEmpty()) {
output = ui.kUnitTableViewEdition->getView()->getSelectedObjects();
}
return output;
}
int SKGUnitPluginWidget::getNbSelectedObjects()
{
int output = 0;
if (ui.kUnitValueTableViewEdition->hasFocus()) {
output = ui.kUnitValueTableViewEdition->getNbSelectedObjects();
}
if (output == 0) {
output = ui.kUnitTableViewEdition->getView()->getNbSelectedObjects();
}
return output;
}
QString SKGUnitPluginWidget::getState()
{
SKGTRACEINFUNC(10)
QDomDocument doc(QStringLiteral("SKGML"));
QDomElement root = doc.createElement(QStringLiteral("parameters"));
doc.appendChild(root);
root.setAttribute(QStringLiteral("splitter1State"), QString(ui.kMainSplitter->saveState().toHex()));
root.setAttribute(QStringLiteral("splitter2State"), QString(ui.kValuesSplitter->saveState().toHex()));
// Memorize table settings
root.setAttribute(QStringLiteral("unitview"), ui.kUnitTableViewEdition->getState());
root.setAttribute(QStringLiteral("unitvalueview"), ui.kUnitValueTableViewEdition->getState());
root.setAttribute(QStringLiteral("currentPage"), SKGServices::intToString(ui.kWidgetSelector->getSelectedMode()));
root.setAttribute(QStringLiteral("obsolete"), ui.kObsolete->isChecked() ? QStringLiteral("Y") : QStringLiteral("N"));
root.setAttribute(QStringLiteral("graphSettings"), ui.kGraph->getState());
root.setAttribute(QStringLiteral("unitvaluegraphmode"), m_unitValueGraphCmb->currentIndex());
return doc.toString();
}
void SKGUnitPluginWidget::setState(const QString& iState)
{
SKGTRACEINFUNC(10)
QDomDocument doc(QStringLiteral("SKGML"));
doc.setContent(iState);
QDomElement root = doc.documentElement();
QString splitter1State = root.attribute(QStringLiteral("splitter1State"));
QString splitter2State = root.attribute(QStringLiteral("splitter2State"));
QString currentPage = root.attribute(QStringLiteral("currentPage"));
QString obsolete = root.attribute(QStringLiteral("obsolete"));
QString unitvaluegraphmode = root.attribute(QStringLiteral("unitvaluegraphmode"));
if (currentPage.isEmpty()) {
currentPage = '0';
}
if (!splitter1State.isEmpty()) {
ui.kMainSplitter->restoreState(QByteArray::fromHex(splitter1State.toLatin1()));
}
if (!splitter2State.isEmpty()) {
ui.kValuesSplitter->restoreState(QByteArray::fromHex(splitter2State.toLatin1()));
}
ui.kWidgetSelector->setSelectedMode(SKGServices::stringToInt(currentPage));
ui.kObsolete->setChecked(obsolete == QStringLiteral("Y"));
ui.kUnitTableViewEdition->setState(root.attribute(QStringLiteral("unitview")));
ui.kUnitValueTableViewEdition->setState(root.attribute(QStringLiteral("unitvalueview")));
ui.kGraph->setState(root.attribute(QStringLiteral("graphSettings")));
ui.kGraph->setGraphType(SKGTableWithGraph::LINE);
if (!unitvaluegraphmode.isEmpty()) {
m_unitValueGraphCmb->setCurrentIndex(SKGServices::stringToInt(unitvaluegraphmode));
}
}
QString SKGUnitPluginWidget::getDefaultStateAttribute()
{
return QStringLiteral("SKGUNIT_DEFAULT_PARAMETERS");
}
void SKGUnitPluginWidget::dataModified(const QString& iTableName, int iIdTransaction)
{
SKGTRACEINFUNC(10)
Q_UNUSED(iIdTransaction)
if (iTableName == QStringLiteral("unitvalue") || iTableName.isEmpty()) {
// Correction bug 2299394 vvv
if (ui.kUnitValueTableViewEdition->isAutoResized()) {
ui.kUnitValueTableViewEdition->resizeColumnsToContentsDelayed();
}
// Correction bug 2299394 ^^^
}
}
void SKGUnitPluginWidget::cleanEditor()
{
if (getNbSelectedObjects() == 0) {
ui.kNameCreatorUnit->setText(QLatin1String(""));
ui.kSymbolCreatorUnit->setText(QLatin1String(""));
ui.kCountryCreatorUnit->setText(QLatin1String(""));
ui.kInternetCreatorUnit->setText(QLatin1String(""));
ui.kUnitCreatorUnit->setText(QLatin1String(""));
}
}
bool SKGUnitPluginWidget::isEditor()
{
return true;
}
void SKGUnitPluginWidget::activateEditor()
{
if (ui.kWidgetSelector->getSelectedMode() == -1) {
ui.kWidgetSelector->setSelectedMode(0);
}
ui.kCurrencyList->setFocus();
}
void SKGUnitPluginWidget::refreshUnitList()
{
QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
// Clean list
ui.kCurrencyList->clear();
// Add items
QStringList list = SKGUnitObject::getListofKnownCurrencies(ui.kObsolete->isChecked());
ui.kCurrencyList->addItems(list);
// Completion
KCompletion* comp = ui.kCurrencyList->completionObject();
if (comp != nullptr) {
comp->setIgnoreCase(true);
comp->setSoundsEnabled(true);
comp->clear();
comp->insertItems(list);
}
QApplication::restoreOverrideCursor();
}
QWidget* SKGUnitPluginWidget::mainWidget()
{
if (ui.kUnitValueTableViewEdition->hasFocus()) {
return ui.kUnitValueTableViewEdition;
}
return ui.kUnitTableViewEdition->getView();
}
void SKGUnitPluginWidget::onAddSource()
{
QString source = ui.kDownloadSource->text().trimmed();
if (!source.isEmpty() &&
(!SKGUnitObject::downloadSources().contains(source) || SKGUnitObject::isWritable(source))) {
// This is a new source
SKGError err = SKGUnitObject::addSource(source);
onSourceChanged();
// Display error
SKGMainPanel::displayErrorMessage(err);
}
}
void SKGUnitPluginWidget::onDeleteSource()
{
QString source = ui.kDownloadSource->text();
if (!source.isEmpty() && SKGUnitObject::downloadSources().contains(source)) {
// This is a new source
SKGError err = SKGUnitObject::deleteSource(source);
IFOK(err) ui.kDownloadSource->removeItem(ui.kDownloadSource->findText(source));
// Display error
SKGMainPanel::displayErrorMessage(err);
}
}
void SKGUnitPluginWidget::onSourceChanged()
{
QString source = ui.kDownloadSource->text().trimmed();
bool local = !source.isEmpty() && SKGUnitObject::isWritable(source);
ui.kDeleteSource->setVisible(local);
m_upload->setEnabled(local);
static QString tooltipOrigin;
if (tooltipOrigin.isEmpty()) {
tooltipOrigin = ui.kInternetCreatorUnit->toolTip();
}
QString tooltip = tooltipOrigin;
auto help = SKGUnitObject::getCommentFromSource(source);
if (!help.isEmpty()) {
tooltip += "<br/>" + i18nc("Help meeage in tooltip", "Here is the help for the selected source '%1':<br/>%2", source, help);
}
ui.kSourceHelp->setText(help);
// Set tooltip on internet code
ui.kInternetCreatorUnit->setToolTip(tooltip);
}
void SKGUnitPluginWidget::onGetNewHotStuff()
{
QPointer<KNS3::DownloadDialog> dialog = new KNS3::DownloadDialog(QStringLiteral("skrooge_unit.knsrc"), this);
dialog->exec();
fillSourceList();
}
void SKGUnitPluginWidget::onPutNewHotStuff()
{
QString source = ui.kDownloadSource->text().trimmed();
// Create zip file
QString sourceFileName = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QLatin1Char('/') + QStringLiteral("skrooge/quotes/") % source % ".txt";
QString zipFileName = QDir::tempPath() % "/" % source % ".zip";
KZip zip(zipFileName);
if (zip.open(QIODevice::WriteOnly)) {
zip.addLocalFile(sourceFileName, source % ".txt");
zip.close();
// Open dialog
QPointer<KNS3::UploadDialog> dialog = new KNS3::UploadDialog(QStringLiteral("skrooge_unit.knsrc"), this);
dialog->setUploadFile(QUrl::fromLocalFile(zipFileName));
dialog->setUploadName(source);
dialog->setDescription(i18nc("Default description for the source", "My favorite source of download for units"));
dialog->setVersion(QStringLiteral("0.1"));
dialog->setChangelog(QStringLiteral("V0.1 - Initial version"));
dialog->exec();
// Delete temporary files
QFile(zipFileName).remove();
}
}
void SKGUnitPluginWidget::onOpenURL()
{
SKGError err;
SKGTRACEINFUNCRC(10, err)
SKGObjectBase::SKGListSKGObjectBase selection = ui.kUnitTableViewEdition->getView()->getSelectedObjects();
int nb = selection.count();
if (nb != 0) {
for (int i = 0; !err && i < nb; ++i) {
SKGUnitObject unit(selection.at(i));
err = unit.openURL();
}
}
// Display error
SKGMainPanel::displayErrorMessage(err);
}
diff --git a/plugins/skrooge/skrooge_unit/skgunitpluginwidget.h b/plugins/skrooge/skrooge_unit/skgunitpluginwidget.h
index 00386fd59..a3837ba06 100644
--- a/plugins/skrooge/skrooge_unit/skgunitpluginwidget.h
+++ b/plugins/skrooge/skrooge_unit/skgunitpluginwidget.h
@@ -1,154 +1,154 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGUNITPLUGINWIDGET_H
#define SKGUNITPLUGINWIDGET_H
/** @file
* This file is Skrooge plugin for unit management.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgtabpage.h"
#include "skgunitobject.h"
#include "ui_skgunitpluginwidget_base.h"
class SKGDocumentBank;
/**
* This file is Skrooge plugin for unit management
*/
class SKGUnitPluginWidget : public SKGTabPage
{
Q_OBJECT
public:
/**
* Default Constructor
* @param iParent the parent widget
* @param iDocument the document
*/
explicit SKGUnitPluginWidget(QWidget* iParent, SKGDocumentBank* iDocument);
/**
* Default Destructor
*/
~SKGUnitPluginWidget() override;
/**
* Get the current selection
* @return selected objects
*/
SKGObjectBase::SKGListSKGObjectBase getSelectedObjects() override;
/**
* Get the number of selected object
* @return number of selected objects
*/
int getNbSelectedObjects() override;
/**
* Get the current state
* MUST BE OVERWRITTEN
* @return a string containing all information needed to set the same state.
* Could be an XML stream
*/
QString getState() override;
/**
* Set the current state
* MUST BE OVERWRITTEN
* @param iState must be interpreted to set the state of the widget
*/
void setState(const QString& iState) override;
/**
* Get attribute name to save the default state
* MUST BE OVERWRITTEN
* @return attribute name to save the default state.
*/
QString getDefaultStateAttribute() override;
/**
* Download values for a unit
* @param iUnit unit
* @param iMode the download mode
* @return an object managing the error
* @see SKGError
*/
static SKGError downloadUnitValue(const SKGUnitObject& iUnit, SKGUnitObject::UnitDownloadMode iMode);
/**
* Get the download mode defined in settings
* @return the download mode
*/
static SKGUnitObject::UnitDownloadMode getDownloadModeFromSettings();
/**
* To know if this page contains an editor. MUST BE OVERWRITTEN
* @return the editor state
*/
bool isEditor() override;
/**
* To activate the editor by setting focus on right widget. MUST BE OVERWRITTEN
*/
void activateEditor() override;
/**
* Get the main widget
* @return a widget
*/
QWidget* mainWidget() override;
protected:
/**
* Event filtering
* @param iObject object
* @param iEvent event
* @return In your reimplementation of this function, if you want to filter the event out, i.e. stop it being handled further, return true; otherwise return false.
*/
bool eventFilter(QObject* iObject, QEvent* iEvent) override;
private Q_SLOTS:
void dataModified(const QString& iTableName, int iIdTransaction);
void onSelectionChanged();
void onSelectionValueChanged();
void onUnitCreatorModified();
void onAddUnit();
void onModifyUnit();
void onDownloadUnitValue();
void onSimplify();
void onDeleteSource();
void onAddSource();
void onSourceChanged();
void onGetNewHotStuff();
void onPutNewHotStuff();
void onOpenURL();
void cleanEditor();
void refreshUnitList();
void fillSourceList();
private:
Q_DISABLE_COPY(SKGUnitPluginWidget)
Ui::skgunitplugin_base ui{};
QTimer m_timer;
QAction* m_upload;
SKGComboBox* m_unitValueGraphCmb;
};
#endif // SKGDEBUGPLUGIN_H
diff --git a/plugins/skrooge/skrooge_unit/skgunitpluginwidget_base.ui b/plugins/skrooge/skrooge_unit/skgunitpluginwidget_base.ui
index a955d9873..5f1397ed7 100644
--- a/plugins/skrooge/skrooge_unit/skgunitpluginwidget_base.ui
+++ b/plugins/skrooge/skrooge_unit/skgunitpluginwidget_base.ui
@@ -1,945 +1,945 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>skgunitplugin_base</class>
<widget class="QWidget" name="skgunitplugin_base">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>662</width>
<height>512</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QSplitter" name="kMainSplitter">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<widget class="SKGFilteredTableView" name="kUnitTableViewEdition">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>1</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="acceptDrops">
<bool>true</bool>
</property>
<property name="dragEnabled" stdset="0">
<bool>true</bool>
</property>
<property name="alternatingRowColors" stdset="0">
<bool>true</bool>
</property>
<property name="sortingEnabled" stdset="0">
<bool>true</bool>
</property>
</widget>
<widget class="QFrame" name="kUnitValueFrame">
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_6">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QSplitter" name="kValuesSplitter">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<widget class="SKGTableView" name="kUnitValueTableViewEdition">
<property name="toolTip">
<string>List of quotes for selected unit</string>
</property>
<property name="statusTip">
<string>List of quotes for selected unit</string>
</property>
<property name="dragDropMode">
<enum>QAbstractItemView::DropOnly</enum>
</property>
<property name="alternatingRowColors">
<bool>true</bool>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::ExtendedSelection</enum>
</property>
<property name="sortingEnabled">
<bool>false</bool>
</property>
</widget>
<widget class="QFrame" name="frame">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QGridLayout" name="gridLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<property name="spacing">
<number>0</number>
</property>
<item row="0" column="0">
<widget class="SKGTableWithGraph" name="kGraph">
<property name="graphTypeSelectorVisible">
<bool>false</bool>
</property>
<property name="selectable">
<bool>false</bool>
</property>
<property name="graphType">
<enum>SKGTableWithGraph::LINE</enum>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
<item>
<widget class="Line" name="line">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="spacing">
<number>2</number>
</property>
<item>
<layout class="QVBoxLayout" name="verticalLayout_2">
<property name="spacing">
<number>2</number>
</property>
<item>
<widget class="QWidget" name="kManualFrm" native="true">
<layout class="QHBoxLayout" name="horizontalLayout_4">
<property name="spacing">
<number>2</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<layout class="QGridLayout" name="gridLayout_2">
<property name="spacing">
<number>2</number>
</property>
<item row="0" column="3">
<widget class="QSpinBox" name="kNbDecimal">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>The number of decimal to display of the unit.</string>
</property>
<property name="statusTip">
<string>The number of decimal to display of the unit.</string>
</property>
<property name="maximum">
<number>8</number>
</property>
<property name="value">
<number>2</number>
</property>
</widget>
</item>
<item row="1" column="3">
<widget class="QLineEdit" name="kCountryCreatorUnit">
<property name="toolTip">
<string>The country of the unit.</string>
</property>
<property name="statusTip">
<string>The country of the unit.</string>
</property>
</widget>
</item>
<item row="2" column="3">
<widget class="SKGUnitComboBox" name="kUnitCreatorUnit">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>The unit of the unit.</string>
</property>
<property name="statusTip">
<string>The unit of the unit.</string>
</property>
</widget>
</item>
<item row="2" column="2">
<widget class="QLabel" name="kUnitLbl">
<property name="text">
<string notr="true">Unit:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>kUnitCreatorUnit</cstring>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QLabel" name="kCountyLbl">
<property name="font">
<font>
<weight>50</weight>
<bold>false</bold>
<strikeout>false</strikeout>
<stylestrategy>PreferDefault</stylestrategy>
<kerning>true</kerning>
</font>
</property>
<property name="text">
<string notr="true">Country:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>kCountryCreatorUnit</cstring>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QLabel" name="kDecimalLbl">
<property name="text">
<string notr="true">N&amp;b Decimals:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>kNbDecimal</cstring>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="kNameCreatorUnit">
<property name="toolTip">
<string>The name of the unit.</string>
</property>
<property name="statusTip">
<string>The name of the unit.</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="kSymbolCreatorUnit">
<property name="toolTip">
<string>The symbol of the unit.</string>
</property>
<property name="statusTip">
<string>The symbol of the unit.</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="SKGComboBox" name="kTypeCreatorUnit">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>The type of the unit.</string>
</property>
<property name="statusTip">
<string>The type of the unit.</string>
</property>
<property name="autoCompletion">
<bool>false</bool>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="kTypeLbl">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
<strikeout>false</strikeout>
<stylestrategy>PreferDefault</stylestrategy>
<kerning>true</kerning>
</font>
</property>
<property name="text">
<string notr="true">&amp;Type:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>kTypeCreatorUnit</cstring>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="kSymbolLbl">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
<strikeout>false</strikeout>
<stylestrategy>PreferDefault</stylestrategy>
<kerning>true</kerning>
</font>
</property>
<property name="text">
<string notr="true">S&amp;ymbol</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>kSymbolCreatorUnit</cstring>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="kNameLbl">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string notr="true">Name:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>kNameCreatorUnit</cstring>
</property>
</widget>
</item>
<item row="0" column="4">
<widget class="QLabel" name="kDownloadSourceLbl">
<property name="text">
<string notr="true">Download source:</string>
</property>
<property name="buddy">
<cstring>kDownloadSource</cstring>
</property>
</widget>
</item>
<item row="0" column="5">
<widget class="SKGComboBox" name="kDownloadSource">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>The download source for the unit</string>
</property>
<property name="statusTip">
<string>The download source for the unit</string>
</property>
<property name="editable">
<bool>true</bool>
</property>
</widget>
</item>
<item row="0" column="6">
<widget class="QToolButton" name="kDeleteSource">
<property name="maximumSize">
<size>
<width>22</width>
<height>22</height>
</size>
</property>
<property name="toolTip">
<string>Delete the selected source</string>
</property>
<property name="statusTip">
<string>Delete the selected source</string>
</property>
<property name="text">
<string/>
</property>
<property name="autoRaise">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="4">
<widget class="QLabel" name="kInternetLbl">
<property name="font">
<font>
<weight>50</weight>
<bold>false</bold>
<strikeout>false</strikeout>
<stylestrategy>PreferDefault</stylestrategy>
<kerning>true</kerning>
</font>
</property>
<property name="text">
<string notr="true">Internet Code:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>kInternetCreatorUnit</cstring>
</property>
</widget>
</item>
<item row="1" column="5" colspan="3">
<widget class="QLineEdit" name="kInternetCreatorUnit">
<property name="toolTip">
- <string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
+ <string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;https://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Ubuntu'; font-size:9pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'DejaVu Sans'; font-size:10pt;&quot;&gt;The Internet code of the unit.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'DejaVu Sans'; font-size:10pt;&quot;&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'DejaVu Sans'; font-size:10pt;&quot;&gt;You can add &amp;quot; /&amp;quot; if you are not able to download the expected quote but you are able to download the inverse.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'DejaVu Sans'; font-size:10pt; text-decoration: underline;&quot;&gt;Example:&lt;/span&gt;&lt;span style=&quot; font-family:'DejaVu Sans'; font-size:10pt;&quot;&gt; EURUSD=X is the symbol to download EURO in USD.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'DejaVu Sans'; font-size:10pt;&quot;&gt;If you want USD in EURO, you have to create a unit USD with &amp;quot;EURUSD=X /&amp;quot; as the Internet code.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'DejaVu Sans'; font-size:10pt;&quot;&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'DejaVu Sans'; font-size:10pt;&quot;&gt;This field can also be set with a yearly rate. The values are computed by clicking on download.&lt;br /&gt;Example:&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'DejaVu Sans'; font-size:10pt;&quot;&gt;=-25 means -25% per year.&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="statusTip">
<string>The Internet code of the unit.</string>
</property>
</widget>
</item>
<item row="0" column="7">
<widget class="QToolButton" name="kGetNewHotStuff">
<property name="maximumSize">
<size>
<width>22</width>
<height>22</height>
</size>
</property>
<property name="toolTip">
<string>Get more templates</string>
</property>
<property name="statusTip">
<string>Get more templates</string>
</property>
<property name="text">
<string/>
</property>
<property name="autoRaise">
<bool>true</bool>
</property>
</widget>
</item>
<item row="2" column="4" colspan="4">
<widget class="QLabel" name="kSourceHelp">
<property name="text">
<string/>
</property>
<property name="textFormat">
<enum>Qt::RichText</enum>
</property>
<property name="openExternalLinks">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QWidget" name="kStandardFrm" native="true">
<layout class="QHBoxLayout" name="horizontalLayout_7">
<property name="spacing">
<number>2</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="SKGComboBox" name="kCurrencyList">
<property name="toolTip">
<string>List of known units</string>
</property>
<property name="statusTip">
<string>List of known units</string>
</property>
<property name="editable">
<bool>true</bool>
</property>
<property name="sizeAdjustPolicy">
<enum>QComboBox::AdjustToContents</enum>
</property>
<property name="autoCompletion">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="kObsolete">
<property name="toolTip">
<string>To include suspended and obsolete currencies</string>
</property>
<property name="statusTip">
<string>To include suspended and obsolete currencies</string>
</property>
<property name="text">
<string>Obsolete currencies</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QFrame" name="kValuesFrm">
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="spacing">
<number>2</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="kDateLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string notr="true">Title:</string>
</property>
<property name="buddy">
<cstring>kDateEdit</cstring>
</property>
</widget>
</item>
<item>
<widget class="SKGDateEdit" name="kDateEdit">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>120</width>
<height>0</height>
</size>
</property>
<property name="toolTip">
<string>Date of the unit's quote</string>
</property>
<property name="statusTip">
<string>Date of the unit's quote</string>
</property>
<property name="mode">
<enum>SKGDateEdit::PREVIOUS</enum>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="kAmountLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string notr="true">Title:</string>
</property>
<property name="buddy">
<cstring>kAmountEdit</cstring>
</property>
</widget>
</item>
<item>
<widget class="SKGCalculatorEdit" name="kAmountEdit">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>Amount of the unit's quote</string>
</property>
<property name="statusTip">
<string>Amount of the unit's quote</string>
</property>
<property name="mode">
<enum>SKGCalculatorEdit::EXPRESSION</enum>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="kUnitOfUnitLbl">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>$</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>0</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Maximum</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_12">
<property name="spacing">
<number>2</number>
</property>
<item>
<widget class="SKGWidgetSelector" name="kWidgetSelector"/>
</item>
<item>
<widget class="QFrame" name="kBtnFrm">
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<property name="spacing">
<number>2</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Maximum</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="kUnitAdd">
<property name="enabled">
<bool>false</bool>
</property>
<property name="toolTip">
<string>Create a new unit (Ctrl+Enter)</string>
</property>
<property name="statusTip">
<string>Create a new unit (Ctrl+Enter)</string>
</property>
<property name="text">
<string>Add</string>
</property>
<property name="autoDefault">
<bool>true</bool>
</property>
<property name="default">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="kUnitUpdate">
<property name="enabled">
<bool>false</bool>
</property>
<property name="toolTip">
<string>Update the selected unit (Shift+Enter)</string>
</property>
<property name="statusTip">
<string>Update the selected unit (Shift+Enter)</string>
</property>
<property name="text">
<string>Modify</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QToolButton" name="kUnitValueDownload">
<property name="enabled">
<bool>false</bool>
</property>
<property name="toolTip">
<string>Download quotes for the selected unit.
See options to modify download frequency.</string>
</property>
<property name="statusTip">
<string>Download quotes for the selected unit.</string>
</property>
<property name="text">
<string>Download</string>
</property>
<property name="popupMode">
<enum>QToolButton::DelayedPopup</enum>
</property>
<property name="toolButtonStyle">
<enum>Qt::ToolButtonTextBesideIcon</enum>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="kUnitOpen">
<property name="enabled">
<bool>false</bool>
</property>
<property name="toolTip">
<string>Open the url of the source</string>
</property>
<property name="statusTip">
<string>Open the url of the source</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
</layout>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>SKGUnitComboBox</class>
<extends>SKGComboBox</extends>
<header>skgunitcombobox.h</header>
</customwidget>
<customwidget>
<class>SKGCalculatorEdit</class>
<extends>QLineEdit</extends>
<header>skgcalculatoredit.h</header>
</customwidget>
<customwidget>
<class>SKGComboBox</class>
<extends>QComboBox</extends>
<header>skgcombobox.h</header>
</customwidget>
<customwidget>
<class>SKGDateEdit</class>
<extends>QComboBox</extends>
<header>skgdateedit.h</header>
</customwidget>
<customwidget>
<class>SKGFilteredTableView</class>
<extends>QWidget</extends>
<header>skgfilteredtableview.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>SKGTableView</class>
<extends>SKGTreeView</extends>
<header>skgtableview.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>SKGTreeView</class>
<extends>QTreeView</extends>
<header>skgtreeview.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>SKGTableWithGraph</class>
<extends>QWidget</extends>
<header>skgtablewithgraph.h</header>
</customwidget>
<customwidget>
<class>SKGWidgetSelector</class>
<extends>QWidget</extends>
<header>skgwidgetselector.h</header>
</customwidget>
</customwidgets>
<tabstops>
<tabstop>kUnitValueTableViewEdition</tabstop>
<tabstop>kNameCreatorUnit</tabstop>
<tabstop>kSymbolCreatorUnit</tabstop>
<tabstop>kTypeCreatorUnit</tabstop>
<tabstop>kNbDecimal</tabstop>
<tabstop>kCountryCreatorUnit</tabstop>
<tabstop>kUnitCreatorUnit</tabstop>
<tabstop>kDownloadSource</tabstop>
<tabstop>kDeleteSource</tabstop>
<tabstop>kGetNewHotStuff</tabstop>
<tabstop>kInternetCreatorUnit</tabstop>
<tabstop>kCurrencyList</tabstop>
<tabstop>kObsolete</tabstop>
<tabstop>kDateEdit</tabstop>
<tabstop>kAmountEdit</tabstop>
<tabstop>kUnitAdd</tabstop>
<tabstop>kUnitUpdate</tabstop>
<tabstop>kUnitValueDownload</tabstop>
<tabstop>kUnitOpen</tabstop>
</tabstops>
<resources/>
<connections/>
<slots>
<slot>onUnitCreatorModified()</slot>
<slot>onAddUnit()</slot>
<slot>onModifyUnit()</slot>
<slot>onAddUnitValue()</slot>
<slot>onDownloadUnitValue()</slot>
<slot>onDoubleClickUnit()</slot>
<slot>onAddCurrency()</slot>
<slot>onBtnModeClicked()</slot>
<slot>cleanEditor()</slot>
<slot>refreshUnitList()</slot>
<slot>onDeleteSource()</slot>
<slot>onAddSource()</slot>
<slot>onSourceChanged()</slot>
<slot>onGetNewHotStuff()</slot>
</slots>
</ui>
diff --git a/plugins/skrooge/tutorial.txt b/plugins/skrooge/tutorial.txt
index 60f140022..591a36ddb 100644
--- a/plugins/skrooge/tutorial.txt
+++ b/plugins/skrooge/tutorial.txt
@@ -1,372 +1,372 @@
<!--***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************-->
<?xml version="1.0" encoding="utf-8"?>
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml">
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="https://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8" />
<meta http-equiv="Content-Style-Type" content="text/css" />
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css">
</head>
<body>
<h1>Introduction</h1>
Welcome to this tutorial. You will learn how to develop a template to personalize your how report.<br>
The template engine is based on <a href="http://www.grantlee.org/apidox/">Grantlee</a>.<br>
<br>
You can find information here:<br>
<a href="http://www.grantlee.org/apidox/for_themers.html">http://www.grantlee.org/apidox/for_themers.html</a><br>
<a href="https://docs.djangoproject.com/en/dev/ref/templates/builtins/">https://docs.djangoproject.com/en/dev/ref/templates/builtins/</a><br>
<h1>The main variables</h1>
<h2>The simple values:</h2>
You can have access to simple values:
<div class="panel panel-primary">
<div class="panel-heading">Code</div>
<div class="panel-body">
color_negativetext: &#123;{ color_negativetext }}<br/>
color_positivetext: &#123;{ color_positivetext }}<br/>
color_neutraltext: &#123;{ color_neutraltext }}<br/>
color_normaltext: &#123;{ color_normaltext }}<br/>
color_inactivetext: &#123;{ color_inactivetext }}<br/>
color_activetext: &#123;{ color_activetext }}<br/>
color_linktext: &#123;{ color_linktext }}<br/>
color_visitedtext: &#123;{ color_visitedtext }}<br/>
color_activebackground: &#123;{ color_activebackground }}<br/>
font_family: &#123;{ font_family }}<br/>
logo: &#123;{ logo }} &lt;img src="&#123;{ logo }}" /><br/>
logo_black: &#123;{ logo_black }} &lt;img src="&#123;{ logo_black }}" /><br/>
title_main: &#123;{ title_main }}<br/>
title_budget: &#123;{ title_budget }}<br/>
title_main_categories: &#123;{ title_main_categories }}<br/>
title_variations: &#123;{ title_variations }}<br/>
title_account: &#123;{ title_account }}<br/>
title_unit: &#123;{ title_unit }}<br/>
title_advice: &#123;{ title_advice }}<br/>
title_portfolio: &#123;{ title_portfolio }}<br/>
title_highlighted: &#123;{ title_highlighted }}<br/>
title_networth: &#123;{ title_networth }}<br/>
title_annual_spending: &#123;{ title_annual_spending }}<br/>
title_personal_finance_score: &#123;{ title_personal_finance_score }}<br/>
msg_no_variation: &#123;{ msg_no_variation|safe }}<br/>
msg_no_scheduled: &#123;{ msg_no_scheduled|safe }}<br/>
msg_no_highlighted: &#123;{ msg_no_highlighted|safe }}<br/>
msg_no_budget: &#123;{ msg_no_budget|safe }}<br/>
msg_no_share: &#123;{ msg_no_share|safe }}<br/>
msg_amount_unit_date: &#123;{ msg_amount_unit_date|safe }}<br/>
about_welcome: &#123;{ about_welcome|safe }}<br/>
about_programname: &#123;{ about_programname|safe }}<br/>
about_version: &#123;{ about_version|safe }}<br/>
about_bugaddress: &#123;{ about_bugaddress|safe }}<br/>
about_copyrightstatement: &#123;{ about_copyrightstatement|safe }}<br/>
about_homepage: &#123;{ about_homepage|safe }}<br/>
about_forumpage: &#123;{ about_forumpage|safe }}<br/>
about_newspage: &#123;{ about_newspage|safe }}<br/>
about_operationpage: &#123;{ about_operationpage|safe }}<br/>
about_accountpage: &#123;{ about_accountpage|safe }}<br/>
about_shortdescription: &#123;{ about_shortdescription|safe }}<br/>
about_othertext: &#123;{ about_othertext|safe }}<br/>
about_maintext: &#123;{ about_maintext|safe }}<br/>
about_did_you_know: &#123;{ about_did_you_know|safe }}<br/>
</div>
</div>
<div class="panel panel-primary">
<div class="panel-heading">Result</div>
<div class="panel-body">
color_negativetext: {{ color_negativetext }}<br/>
color_positivetext: {{ color_positivetext }}<br/>
color_neutraltext: {{ color_neutraltext }}<br/>
color_normaltext: {{ color_normaltext }}<br/>
color_inactivetext: {{ color_inactivetext }}<br/>
color_activetext: {{ color_activetext }}<br/>
color_linktext: {{ color_linktext }}<br/>
color_visitedtext: {{ color_visitedtext }}<br/>
color_activebackground: {{ color_activebackground }}<br/>
font_family: {{ font_family }}<br/>
logo: {{ logo }} <img src="{{ logo }}" /><br/>
logo_black: {{ logo_black }} <img src="{{ logo_black }}" /><br/>
title_main: {{ title_main }}<br/>
title_budget: {{ title_budget }}<br/>
title_main_categories: {{ title_main_categories }}<br/>
title_variations: {{ title_variations }}<br/>
title_account: {{ title_account }}<br/>
title_unit: {{ title_unit }}<br/>
title_advice: {{ title_advice }}<br/>
title_portfolio: {{ title_portfolio }}<br/>
title_highlighted: {{ title_highlighted }}<br/>
title_networth: {{ title_networth }}<br/>
title_annual_spending: {{ title_annual_spending }}<br/>
title_personal_finance_score: {{ title_personal_finance_score }}<br/>
msg_no_variation: {{ msg_no_variation|safe }}<br/>
msg_no_scheduled: {{ msg_no_scheduled|safe }}<br/>
msg_no_highlighted: {{ msg_no_highlighted|safe }}<br/>
msg_no_budget: {{ msg_no_budget|safe }}<br/>
msg_no_share: {{ msg_no_share|safe }}<br/>
msg_amount_unit_date: {{ msg_amount_unit_date|safe }}<br/>
about_welcome: {{ about_welcome|safe }}<br/>
about_programname: {{ about_programname|safe }}<br/>
about_version: {{ about_version|safe }}<br/>
about_bugaddress: {{ about_bugaddress|safe }}<br/>
about_copyrightstatement: {{ about_copyrightstatement|safe }}<br/>
about_homepage: {{ about_homepage|safe }}<br/>
about_forumpage: {{ about_forumpage|safe }}<br/>
about_newspage: {{ about_newspage|safe }}<br/>
about_operationpage: {{ about_operationpage|safe }}<br/>
about_accountpage: {{ about_accountpage|safe }}<br/>
about_shortdescription: {{ about_shortdescription|safe }}<br/>
about_othertext: {{ about_othertext|safe }}<br/>
about_maintext: {{ about_maintext|safe }}<br/>
about_did_you_know: {{ about_did_you_know|safe }}<br/>
</div>
</div>
<h2>The report:</h2>
From this object you can have access to more complex values:
<div class="panel panel-primary">
<div class="panel-heading">Code</div>
<div class="panel-body">
report.period=&#123;{ report.period }}<br/>
report.previous_period=&#123;{ report.previous_period }}<br/>
report.previous.period=&#123;{ report.previous.period }}<br/>
report.previous.previous_period=&#123;{ report.previous.previous_period }}<br/>
report.tip_of_day;{ report.tip_of_day }}<br/>
report.budget_table=&#123;{ report.budget_table|dump|safe }}<br/>
report.unit_table=&#123;{ report.unit_table|dump|safe }}<br/>
report.portfolio=&#123;{ report.portfolio|dump|safe }}<br/>
report.account_table=&#123;{ report.account_table|dump|safe }}<br/>
report.bank_table=&#123;{ report.bank_table|dump|safe }}<br/>
report.scheduled_operations=&#123;{ report.scheduled_operations|dump|safe }}<br/>
report.categories_period=&#123;{ report.categories_period|dump|safe }}<br/>
report.categories_previous_period=&#123;{ report.categories_previous_period|dump|safe }}<br/>
report.income_vs_expenditure=&#123;{ report.income_vs_expenditure|dump|safe }}<br/>
report.networth=&#123;{ report.networth|money|safe }}<br/>
report.annual_spending=&#123;{ report.annual_spending|money|safe }}<br/>
report.personal_finance_score=&#123;{ report.personal_finance_score }}<br/>
report.categories_variations=&#123;{ report.categories_variations|dump|safe }}<br/>
report.categories_variations_issues=&#123;{ report.categories_variations_issues|dump|safe }}<br/>
</div>
</div>
<div class="panel panel-primary">
<div class="panel-heading">Result</div>
<div class="panel-body">
report.period={{ report.period }}<br/>
report.previous_period={{ report.previous_period }}<br/>
report.previous.period={{ report.previous.period }}<br/>
report.previous.previous_period={{ report.previous.previous_period }}<br/>
report.tip_of_day={{ report.tip_of_day }}<br/>
report.budget_table={{ report.budget_table|dump|safe }}<br/>
report.unit_table={{ report.unit_table|dump|safe }}<br/>
report.portfolio={{ report.portfolio|dump|safe }}<br/>
report.account_table={{ report.account_table|dump|safe }}<br/>
report.bank_table={{ report.bank_table|dump|safe }}<br/>
report.scheduled_operations={{ report.scheduled_operations|dump|safe }}<br/>
report.categories_period={{ report.categories_period|dump|safe }}<br/>
report.categories_previous_period={{ report.categories_previous_period|dump|safe }}<br/>
report.income_vs_expenditure={{ report.income_vs_expenditure|dump|safe }}<br/>
report.networth={{ report.networth|money|safe }}<br/>
report.annual_spending={{ report.annual_spending|money|safe }}<br/>
report.personal_finance_score={{ report.personal_finance_score }}<br/>
report.categories_variations={{ report.categories_variations|dump|safe }}<br/>
report.categories_variations_issues={{ report.categories_variations_issues|dump|safe }}<br/>
</div>
</div>
<h2>The document:</h2>
From this object you can have access to more complex values:
<div class="panel panel-primary">
<div class="panel-heading">Code</div>
<div class="panel-body">
&#123;{ document|dump|safe }}
</div>
</div>
<div class="alert alert-success" role="alert">The "dump" filter allows to dump the object</div>
<div class="panel panel-primary">
<div class="panel-heading">Result</div>
<div class="panel-body">
{{ document|dump|safe }}
</div>
</div>
<h1>The filters</h1>
In addition of standard filters, you can the following filters developed for Skrooge.
<div class="panel panel-primary">
<div class="panel-heading">Code</div>
<div class="panel-body">
&#123;{ 10.1|money|safe }}<br/>
&#123;{ -10.2|money|safe }}<br/>
&#123;{ -10.3|money:"nocolor" }}<br/>
&#123;{ -10.4|money:"nodecimal" }}<br/>
&#123;{ -10.5|money:"nocolor;nodecimal" }}<br/>
&#123;{ 10.1|money:"1"|safe }}<br/>
&#123;{ -10.2|money:"1"|safe }}<br/>
&#123;{ -10.3|money:"1;nocolor" }}<br/>
&#123;{ -10.4|money:"1;nocolor;nodecimal" }}<br/>
&#123;{ 10.1|money:"2"|safe }}<br/>
&#123;{ -10.2|money:"2"|safe }}<br/>
&#123;{ -10.3|money:"2;nocolor" }}<br/>
&#123;{ -10.4|money:"2;nocolor;nodecimal" }}<br/>
&#123;{ 10.1|percent|safe }}<br/>
&#123;{ -10.2|percent|safe }}<br/>
&#123;{ 70000|filesizeformat }}<br/>
&#123;{ about_did_you_know|replace:"Did;Do" }}<br/>
</div>
</div>
<div class="alert alert-success" role="alert">The "money" filter displays a numerical value as a money. With "1", in primary money. With "2", in secondary money</div>
<div class="alert alert-success" role="alert">The "percent" filter displays a numerical value as a percent</div>
<div class="alert alert-success" role="alert">The "filesizeformat" filter displays a numerical value as a file size format</div>
<div class="alert alert-success" role="alert">The "replace" filter replaces a string by another one</div>
<div class="panel panel-primary">
<div class="panel-heading">Result</div>
<div class="panel-body">
{{ 10.1|money|safe }}<br/>
{{ -10.2|money|safe }}<br/>
{{ -10.3|money:"nocolor" }}<br/>
{{ -10.4|money:"nodecimal" }}<br/>
{{ -10.5|money:"nocolor;nodecimal" }}<br/>
{{ 10.1|money:"1"|safe }}<br/>
{{ -10.2|money:"1"|safe }}<br/>
{{ -10.3|money:"1;nocolor" }}<br/>
{{ -10.4|money:"1;nocolor;nodecimal" }}<br/>
{{ 10.1|money:"2"|safe }}<br/>
{{ -10.2|money:"2"|safe }}<br/>
{{ -10.3|money:"2;nocolor" }}<br/>
{{ -10.4|money:"2;nocolor;nodecimal" }}<br/>
{{ 10.1|percent|safe }}<br/>
{{ -10.2|percent|safe }}<br/>
{{ 70000|filesizeformat }}<br/>
{{ about_did_you_know|replace:"Did;Do" }}<br/>
</div>
</div>
The following code will display the list of opened accounts with current amount:<br/>
<div class="panel panel-primary">
<div class="panel-heading">Code</div>
<div class="panel-body">
&#123;% for item in document|table:"v_account_display,t_close='N' ORDER BY t_name" %}<br/>
&#123;{ item|att:"rd_bank_id.t_name" }}.&#123;{ item|att:"t_name" }}:&#123;{ item|att:"f_CURRENTAMOUNT"|money|safe }}&lt;br/&gt;<br/>
&#123;% endfor %}
</div>
</div>
<div class="alert alert-success" role="alert">The "table" filter allows to search objects</div>
<div class="alert alert-success" role="alert">The "att" filter allows to get an attribute of an object</div>
<div class="panel panel-primary">
<div class="panel-heading">Result</div>
<div class="panel-body">
{% for item in document|table:"v_account_display,t_close='N' ORDER BY t_name" %}
{{ item|att:"rd_bank_id.t_name" }}.{{ item|att:"t_name" }}:{{ item|att:"f_CURRENTAMOUNT"|money|safe }}<br/>
{% endfor %}
</div>
</div>
The following code will execute a sql order and display the result:<br/>
<div class="panel panel-primary">
<div class="panel-heading">Code</div>
<div class="panel-body">
&#123;% for item in document|query:"select t_name as name, (select count(1) from operation where rd_account_id=account.id) as id from account" %}<br/>
&#123;{ item.0 }}:&#123;{ item.1 }}&lt;br/&gt;<br/>
&#123;% endfor %}
</div>
</div>
<div class="alert alert-success" role="alert">The "query" filter allows to execute the sql order you want</div>
<div class="panel panel-primary">
<div class="panel-heading">Result</div>
<div class="panel-body">
{% for item in document|query:"select t_name as name, (select count(1) from operation where rd_account_id=account.id) as id from account" %}
{{ item.0 }}:{{ item.1 }}<br/>
{% endfor %}
</div>
</div>
<h1>Some examples</h1>
To go faster, you can include already existing part of template like this:
<div class="panel panel-primary">
<div class="panel-heading">Code</div>
<div class="panel-body">
&#123;% include "default/personal_finance_score.html" %}<br/>
&#123;% include "default/income_vs_expenditure_table.html" %}<br/>
&#123;% include "default/budget_table.html" %}<br/>
&#123;% include "default/categories_previous_period_table.html" %}<br/>
&#123;% include "default/categories_period_table.html" %}<br/>
&#123;% include "default/categories_variations.html" %}<br/>
&#123;% include "default/bank_table.html" %}<br/>
&#123;% include "default/account_table.html" %}<br/>
&#123;% include "default/unit_table.html" %}<br/>
&#123;% include "default/portfolio.html" %}<br/>
&#123;% include "default/highlighted_operations.html" %}<br/>
</div>
</div>
<div class="panel panel-primary">
<div class="panel-heading">Result</div>
<div class="panel-body">
{% include "default/personal_finance_score.html" %}
{% include "default/income_vs_expenditure_table.html" %}
{% include "default/budget_table.html" %}
{% include "default/categories_previous_period_table.html" %}
{% include "default/categories_period_table.html" %}
{% include "default/categories_variations.html" %}
{% include "default/bank_table.html" %}
{% include "default/account_table.html" %}
{% include "default/unit_table.html" %}
{% include "default/portfolio.html" %}
{% include "default/highlighted_operations.html" %}
</div>
</div>
You can also use external libraries to display values as you want:
<div class="panel panel-primary">
<div class="panel-heading">Code</div>
<div class="panel-body">
&lt;img src="http://chart.apis.google.com/chart?cht=bvs&chxs=0,&#123;{ color_normaltext }}|1,&#123;{ color_normaltext }}&chbh=100&chxt=x,y&chxr=1,0,&#123;{ report.income_vs_expenditure.4.3 }}&chf=bg,s,&#123;{ color_normalbackground }}&chco=&#123;{ color_negativetext }}|&#123;{ color_positivetext }}&chd=t:&#123;{ report.income_vs_expenditure.2.3 }},&#123;{ report.income_vs_expenditure.1.3 }}&chds=0,&#123;{ report.income_vs_expenditure.4.3 }}&chs=300x200&chl=&#123;{ document|display:"f_CURRENTAMOUNT_EXPENSE" }}|&#123;{ document|display:"f_CURRENTAMOUNT_INCOME" }}&chts=&#123;{ color_normaltext }}&chtt=&#123;{ document|display:"f_CURRENTAMOUNT_EXPENSE" }} vs &#123;{ document|display:"f_CURRENTAMOUNT_INCOME" }}|&#123;{ report.period }}"/>
</div>
</div>
<div class="panel panel-primary">
<div class="panel-heading">Result</div>
<div class="panel-body">
<img src="http://chart.apis.google.com/chart?cht=bvs&chxs=0,{{ color_normaltext }}|1,{{ color_normaltext }}&chbh=100&chxt=x,y&chxr=1,0,{{ report.income_vs_expenditure.4.3 }}&chf=bg,s,{{ color_normalbackground }}&chco={{ color_negativetext }}|{{ color_positivetext }}&chd=t:{{ report.income_vs_expenditure.2.3 }},{{ report.income_vs_expenditure.1.3 }}&chds=0,{{ report.income_vs_expenditure.4.3 }}&chs=300x200&chl={{ document|display:"f_CURRENTAMOUNT_EXPENSE" }}|{{ document|display:"f_CURRENTAMOUNT_INCOME" }}&chts={{ color_normaltext }}&chtt={{ document|display:"f_CURRENTAMOUNT_EXPENSE" }} vs {{ document|display:"f_CURRENTAMOUNT_INCOME" }}|{{ report.period }}"/>
</div>
</div>
</body>
</html>
diff --git a/skgbankgui/CMakeLists.txt b/skgbankgui/CMakeLists.txt
index 453af92f3..e5cd3aa21 100644
--- a/skgbankgui/CMakeLists.txt
+++ b/skgbankgui/CMakeLists.txt
@@ -1,116 +1,116 @@
#***************************************************************************
#* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
#* *
#* 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 <http://www.gnu.org/licenses/> *
+#* along with this program. If not, see <https://www.gnu.org/licenses/> *
#***************************************************************************
MESSAGE( STATUS "..:: CMAKE SKGBANKGUI ::..")
PROJECT(SKGBANKGUI)
LINK_DIRECTORIES (${LIBRARY_OUTPUT_PATH})
IF(SKG_WEBENGINE)
MESSAGE( STATUS " Mode WebEngine")
ADD_DEFINITIONS(-DSKG_WEBENGINE=${SKG_WEBENGINE})
ENDIF(SKG_WEBENGINE)
SET(skgbankgui_SRCS
skgobjectmodel.cpp
skgquerycreator.cpp
skgpredicatcreator.cpp
skgquerydelegate.cpp
skgunitcombobox.cpp
)
SET(LIBS Qt5::Xml skgbankmodeler skgbasemodeler skgbasegui)
IF(SKG_WEBENGINE)
SET(LIBS ${LIBS} Qt5::WebEngineWidgets)
ELSE(SKG_WEBENGINE)
SET(LIBS ${LIBS} Qt5::WebKitWidgets)
ENDIF(SKG_WEBENGINE)
IF(KActivities_FOUND)
MESSAGE( STATUS " KActivity FOUND" )
SET(LIBS ${LIBS} KF5::Activities)
endif (KActivities_FOUND)
ki18n_wrap_ui(skgbankgui_SRCS skgquerycreator.ui)
ADD_LIBRARY(skgbankgui SHARED ${skgbankgui_SRCS})
TARGET_LINK_LIBRARIES(skgbankgui LINK_PUBLIC ${LIBS})
SET_TARGET_PROPERTIES(skgbankgui PROPERTIES VERSION ${SKG_VERSION} SOVERSION ${SOVERSION} )
GENERATE_EXPORT_HEADER(skgbankgui BASE_NAME skgbankgui)
########### install files ###############
INSTALL(TARGETS skgbankgui ${INSTALL_TARGETS_DEFAULT_ARGS} LIBRARY NAMELINK_SKIP )
INSTALL(DIRECTORY icons_breeze/ DESTINATION ${ICON_INSTALL_DIR}/breeze/actions/22 FILES_MATCHING PATTERN "*.svgz")
INSTALL(DIRECTORY icons_breeze-dark/ DESTINATION ${ICON_INSTALL_DIR}/breeze-dark/actions/22 FILES_MATCHING PATTERN "*.svgz")
ECM_INSTALL_ICONS(ICONS
icons_hicolor/16-actions-skrooge_credit_card.png
icons_hicolor/16-actions-skrooge_less.png
icons_hicolor/16-actions-skrooge_more.png
icons_hicolor/16-actions-skrooge_much_less.png
icons_hicolor/16-actions-skrooge_much_more.png
icons_hicolor/16-actions-skrooge_type.png
icons_hicolor/22-actions-skrooge_credit_card.png
icons_hicolor/22-actions-skrooge_less.png
icons_hicolor/22-actions-skrooge_more.png
icons_hicolor/22-actions-skrooge_much_less.png
icons_hicolor/22-actions-skrooge_much_more.png
icons_hicolor/22-actions-skrooge_type.png
icons_hicolor/32-actions-skrooge_credit_card.png
icons_hicolor/32-actions-skrooge_less.png
icons_hicolor/32-actions-skrooge_more.png
icons_hicolor/32-actions-skrooge_much_less.png
icons_hicolor/32-actions-skrooge_much_more.png
icons_hicolor/32-actions-skrooge_type.png
icons_hicolor/48-actions-skrooge_credit_card.png
icons_hicolor/48-actions-skrooge_less.png
icons_hicolor/48-actions-skrooge_more.png
icons_hicolor/48-actions-skrooge_much_less.png
icons_hicolor/48-actions-skrooge_much_more.png
icons_hicolor/48-actions-skrooge_type.png
icons_hicolor/64-actions-skrooge_credit_card.png
icons_hicolor/64-actions-skrooge_less.png
icons_hicolor/64-actions-skrooge_more.png
icons_hicolor/64-actions-skrooge_much_less.png
icons_hicolor/64-actions-skrooge_much_more.png
icons_hicolor/64-actions-skrooge_type.png
icons_hicolor/128-actions-skrooge_credit_card.png
icons_hicolor/128-actions-skrooge_less.png
icons_hicolor/128-actions-skrooge_more.png
icons_hicolor/128-actions-skrooge_much_less.png
icons_hicolor/128-actions-skrooge_much_more.png
icons_hicolor/128-actions-skrooge_type.png
icons_hicolor/256-actions-skrooge_credit_card.png
icons_hicolor/256-actions-skrooge_less.png
icons_hicolor/256-actions-skrooge_more.png
icons_hicolor/256-actions-skrooge_much_less.png
icons_hicolor/256-actions-skrooge_much_more.png
icons_hicolor/256-actions-skrooge_type.png
icons_hicolor/512-actions-skrooge_credit_card.png
icons_hicolor/512-actions-skrooge_less.png
icons_hicolor/512-actions-skrooge_more.png
icons_hicolor/512-actions-skrooge_much_less.png
icons_hicolor/512-actions-skrooge_much_more.png
icons_hicolor/512-actions-skrooge_type.png
icons_hicolor/sc-actions-skrooge_credit_card.svgz
icons_hicolor/sc-actions-skrooge_less.svgz
icons_hicolor/sc-actions-skrooge_more.svgz
icons_hicolor/sc-actions-skrooge_much_less.svgz
icons_hicolor/sc-actions-skrooge_much_more.svgz
icons_hicolor/sc-actions-skrooge_type.svgz
DESTINATION ${ICON_INSTALL_DIR}
THEME hicolor
)
diff --git a/skgbankgui/skgobjectmodel.cpp b/skgbankgui/skgobjectmodel.cpp
index c64662f5f..1e9715640 100644
--- a/skgbankgui/skgobjectmodel.cpp
+++ b/skgbankgui/skgobjectmodel.cpp
@@ -1,1315 +1,1315 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file defines classes SKGObjectModel.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgobjectmodel.h"
#include <math.h>
#include <kconfiggroup.h>
#include <klocalizedstring.h>
#include <qapplication.h>
#include <qcolor.h>
#include <qdir.h>
#include <qfont.h>
#include <qicon.h>
#include <qmimedata.h>
#include <qstandardpaths.h>
#include "skgaccountobject.h"
#include "skgbudgetobject.h"
#include "skgbudgetruleobject.h"
#include "skgcategoryobject.h"
#include "skgdocumentbank.h"
#include "skgmainpanel.h"
#include "skgoperationobject.h"
#include "skgpayeeobject.h"
#include "skgrecurrentoperationobject.h"
#include "skgsuboperationobject.h"
#include "skgtraces.h"
#include "skgtrackerobject.h"
#include "skgtransactionmng.h"
#include "skgunitobject.h"
#include "skgunitvalueobject.h"
SKGObjectModel::
SKGObjectModel(SKGDocumentBank* iDocument,
const QString& iTable,
const QString& iWhereClause,
QWidget* iParent,
const QString& iParentAttribute,
bool iResetOnCreation)
: SKGObjectModelBase(iDocument, iTable, iWhereClause, iParent, iParentAttribute, false)
{
SKGTRACEINFUNC(1)
m_operationTable = false;
m_recurrentoperationTable = false;
m_trackerTable = false;
m_accountTable = false;
m_unitTable = false;
m_unitvalueTable = false;
m_suboperationTable = false;
m_categoryTable = false;
m_ruleTable = false;
m_interestTable = false;
m_interestResultTable = false;
m_payeeTable = false;
m_budgetTable = false;
m_budgetRuleTable = false;
m_isResetRealyNeeded = iResetOnCreation;
refresh();
}
void SKGObjectModel::buidCache()
{
SKGObjectModelBase::buidCache();
m_operationTable = (getRealTable() == QStringLiteral("operation") || getRealTable() == QStringLiteral("suboperation"));
m_payeeTable = (getRealTable() == QStringLiteral("payee"));
m_trackerTable = (getRealTable() == QStringLiteral("refund"));
m_recurrentoperationTable = (getRealTable() == QStringLiteral("recurrentoperation"));
m_accountTable = (getRealTable() == QStringLiteral("account"));
m_unitTable = (getRealTable() == QStringLiteral("unit"));
m_unitvalueTable = (getRealTable() == QStringLiteral("unitvalue"));
m_suboperationTable = (getTable() == QStringLiteral("v_suboperation_consolidated"));
m_ruleTable = (getRealTable() == QStringLiteral("rule"));
m_categoryTable = (getRealTable() == QStringLiteral("category"));
m_interestTable = (getRealTable() == QStringLiteral("interest"));
m_interestResultTable = (getRealTable() == QStringLiteral("interest_result"));
m_budgetTable = (getRealTable() == QStringLiteral("budget"));
m_budgetRuleTable = (getRealTable() == QStringLiteral("budgetrule"));
if (m_unitvalueTable) {
SKGUnitValueObject unitValObject(getObject(this->index(0, 0)));
SKGUnitObject unitObject;
unitValObject.getUnit(unitObject);
SKGUnitObject parentUnit;
unitObject.getUnit(parentUnit);
if (parentUnit.exist()) {
m_cacheUnit.Name = parentUnit.getName();
m_cacheUnit.Symbol = parentUnit.getSymbol();
m_cacheUnit.Value = 1;
m_cacheUnit.NbDecimal = unitObject.getNumberDecimal();
} else {
m_cacheUnit.Name = QLatin1String("");
m_cacheUnit.Symbol = QLatin1String("");
m_cacheUnit.Value = 1;
m_cacheUnit.NbDecimal = unitObject.getNumberDecimal();
}
if (m_cacheUnit.Symbol.isEmpty()) {
m_cacheUnit.Symbol = ' ';
}
// Bug 209672 vvvv
if (unitObject.getType() == SKGUnitObject::INDEX) {
m_cacheUnit.Symbol = ' ';
m_cacheUnit.Name = ' ';
}
// Bug 209672 ^^^^
}
if (m_operationTable) {
// Read Setting
KSharedConfigPtr config = KSharedConfig::openConfig();
KConfigGroup pref = config->group("skrooge_operation");
m_fontFutureOperationsColor = QVariant::fromValue(pref.readEntry("fontFutureColor", QColor(Qt::gray)));
m_fontNotValidatedOperationsColor = QVariant::fromValue(pref.readEntry("fontNotValidatedColor", QColor(Qt::blue)));
m_fontSubOperationsColor = QVariant::fromValue(pref.readEntry("fontSubOperationColor", QColor(Qt::darkGreen)));
}
if (m_recurrentoperationTable) {
// Read Setting
KSharedConfigPtr config = KSharedConfig::openConfig();
KConfigGroup pref = config->group("skrooge_scheduled");
m_fontDisabledScheduleColor = QVariant::fromValue(pref.readEntry("fontFutureColor", QColor(Qt::gray)));
}
m_iconFavorite = SKGServices::fromTheme(QStringLiteral("bookmarks"));
if (m_operationTable || m_recurrentoperationTable) {
m_iconTransfer = SKGServices::fromTheme(QStringLiteral("exchange-positions"));
QStringList overlays;
overlays.push_back(QStringLiteral("list-remove"));
m_iconGroup = SKGServices::fromTheme(QStringLiteral("exchange-positions"), overlays);
m_iconSplit = SKGServices::fromTheme(QStringLiteral("split"));
m_iconImported = SKGServices::fromTheme(QStringLiteral("utilities-file-archiver"));
{
QStringList overlay;
overlay.push_back(QStringLiteral("dialog-ok"));
m_iconImportedChecked = SKGServices::fromTheme(QStringLiteral("utilities-file-archiver"), overlay);
}
m_iconRecurrent = SKGServices::fromTheme(QStringLiteral("chronometer"));
{
QStringList overlay;
overlay.push_back(QStringLiteral("bookmarks"));
m_iconRecurrentMaster = SKGServices::fromTheme(QStringLiteral("chronometer"), overlay);
}
}
if (m_budgetTable) {
m_iconGreen = SKGServices::fromTheme(QStringLiteral("security-high"));
m_iconRed = SKGServices::fromTheme(QStringLiteral("security-low"));
m_iconAnber = SKGServices::fromTheme(QStringLiteral("security-medium"));
}
if (m_unitTable) {
m_iconMuchMore = SKGServices::fromTheme(QStringLiteral("skrooge_much_more"));
m_iconMuchLess = SKGServices::fromTheme(QStringLiteral("skrooge_much_less"));
m_iconMore = SKGServices::fromTheme(QStringLiteral("skrooge_more"));
m_iconLess = SKGServices::fromTheme(QStringLiteral("skrooge_less"));
}
if (m_ruleTable) {
m_iconSearch = SKGServices::fromTheme(QStringLiteral("edit-find"));
m_iconUpdate = SKGServices::fromTheme(QStringLiteral("view-refresh"));
m_iconAlarm = SKGServices::fromTheme(QStringLiteral("dialog-warning"));
m_iconTemplate = SKGServices::fromTheme(QStringLiteral("edit-guides"));
}
m_iconClosed = SKGServices::fromTheme(QStringLiteral("dialog-close"));
if (m_categoryTable) {
m_iconCategory = SKGServices::fromTheme(QStringLiteral("view-categories"));
m_iconCategoryMoins = SKGServices::fromTheme(QStringLiteral("view-categories-expenditures"));
m_iconCategoryPlus = SKGServices::fromTheme(QStringLiteral("view-categories-incomes"));
}
}
SKGObjectModel::~SKGObjectModel()
{
SKGTRACEINFUNC(1)
}
QVariant SKGObjectModel::headerData(int section, Qt::Orientation orientation, int role) const
{
_SKGTRACEINFUNC(10)
if (orientation == Qt::Horizontal) {
if (role == Qt::DisplayRole) {
QString att;
if (section >= 0 && section < m_listAttibutes.count()) {
att = m_listAttibutes[section];
} else {
att = SKGServices::intToString(section);
}
if (att == QStringLiteral("t_bookmarked") || att == QStringLiteral("i_NBRECURRENT") || att == QStringLiteral("t_status") || att == QStringLiteral("t_close") || att == QStringLiteral("t_imported")) {
return "";
}
}
}
return SKGObjectModelBase::headerData(section, orientation, role);
}
QString SKGObjectModel::getAttributeForGrouping(const SKGObjectBase& iObject, const QString& iAttribute) const
{
if (m_recurrentoperationTable && iAttribute == QStringLiteral("i_nb_times")) {
if (iObject.getAttribute(QStringLiteral("t_times")) != QStringLiteral("Y")) {
return QChar(8734);
}
} else if (m_ruleTable && iAttribute == QStringLiteral("t_action_type")) {
QString val = iObject.getAttribute(iAttribute);
if (val == QStringLiteral("S")) {
val = i18nc("Noun, a search", "Search");
} else if (val == QStringLiteral("U")) {
val = i18nc("Noun, a modification", "Update");
} else {
val = i18nc("Noun, an alarm", "Alarm");
}
return val;
} else if (iAttribute == QStringLiteral("t_bookmarked") || iAttribute == QStringLiteral("t_close")) {
QString val = iObject.getAttribute(iAttribute);
return val == QStringLiteral("Y") ? i18n("Yes") : i18n("No");
} else if (iAttribute == QStringLiteral("t_status")) {
QString val = iObject.getAttribute(iAttribute);
return val == QStringLiteral("N") ? i18n("None") : val == QStringLiteral("P") ? i18n("Pointed") : i18n("Checked");
}
return SKGObjectModelBase::getAttributeForGrouping(iObject, iAttribute);
}
QVariant SKGObjectModel::computeData(const QModelIndex& iIndex, int iRole) const
{
if (!iIndex.isValid()) {
return QVariant();
}
_SKGTRACEINFUNC(10)
SKGObjectBase* obj = getObjectPointer(iIndex);
if (obj == nullptr || obj->getTable().isEmpty()) {
return SKGObjectModelBase::computeData(iIndex, iRole);
}
switch (iRole) {
case Qt::DisplayRole:
case Qt::EditRole:
case Qt::UserRole: {
QString att = m_listAttibutes[iIndex.column()];
QString val = obj->getAttribute(att);
if (att == QStringLiteral("i_NBRECURRENT")) {
if (iRole == Qt::UserRole) {
if (val != QStringLiteral("0")) {
return QLatin1String("Y");
}
if (obj->getAttribute(QStringLiteral("r_recurrentoperation_id")) != QStringLiteral("0")) {
return QLatin1String("Y");
}
return QLatin1String("N");
}
return "";
}
if (att == QStringLiteral("t_bookmarked") ||
att == QStringLiteral("t_status") ||
att == QStringLiteral("t_imported") ||
att == QStringLiteral("t_close") ||
att == QStringLiteral("t_action_type")
) {
if (iRole == Qt::UserRole) {
if (m_ruleTable && att == QStringLiteral("t_action_type")) {
if (val == QStringLiteral("S")) {
return i18nc("Noun, a search", "Search");
}
if (val == QStringLiteral("U")) {
return i18nc("Noun, a modification", "Update");
}
return i18nc("Noun, an alarm", "Alarm");
}
return val;
}
return "";
}
if (m_interestTable && att == QStringLiteral("t_expenditure_value_date_mode")) {
if (val == QStringLiteral("0")) {
return i18nc("Noun", "Day -0");
}
if (val == QStringLiteral("1")) {
return i18nc("Noun", "Day -1");
}
if (val == QStringLiteral("2")) {
return i18nc("Noun", "Day -2");
}
if (val == QStringLiteral("3")) {
return i18nc("Noun", "Day -3");
}
if (val == QStringLiteral("4")) {
return i18nc("Noun", "Day -4");
}
if (val == QStringLiteral("5")) {
return i18nc("Noun", "Day -5");
}
return i18nc("Noun", "Fifteen");
}
if (m_accountTable && att == QStringLiteral("d_reconciliationdate")) {
if (val.isEmpty() && iRole == Qt::DisplayRole) {
return i18nc("Noun", "Never");
}
} else if (m_interestTable && att == QStringLiteral("t_income_value_date_mode")) {
if (val == QStringLiteral("0")) {
return i18nc("Noun", "Day +0");
}
if (val == QStringLiteral("1")) {
return i18nc("Noun", "Day +1");
}
if (val == QStringLiteral("2")) {
return i18nc("Noun", "Day +2");
}
if (val == QStringLiteral("3")) {
return i18nc("Noun", "Day +3");
}
if (val == QStringLiteral("4")) {
return i18nc("Noun", "Day +4");
}
if (val == QStringLiteral("5")) {
return i18nc("Noun", "Day +5");
}
return i18nc("Noun", "Fifteen");
}
if (getAttributeType(iIndex.column()) == SKGServices::FLOAT) {
double dval = SKGServices::stringToDouble(val);
if (iRole == Qt::DisplayRole) {
if (val.isEmpty()) {
return "";
}
if (att.endsWith(QLatin1String("_INCOME")) ||
att.endsWith(QLatin1String("_EXPENSE")) ||
(m_operationTable && obj->getAttribute(QStringLiteral("t_template")) == QStringLiteral("Y")) ||
(m_categoryTable && (att == QStringLiteral("f_REALCURRENTAMOUNT") ||
att == QStringLiteral("f_SUMCURRENTAMOUNT")))) {
if (dval == 0) {
return "";
}
}
SKGServices::SKGUnitInfo unit;
unit.Symbol = QLatin1String("");
unit.NbDecimal = 2;
if (!att.contains(QStringLiteral("QUANTITY")) && !att.contains(QStringLiteral("f_BALANCE_ENTERED"))) {
unit = qobject_cast<SKGDocumentBank*>(getDocument())->getPrimaryUnit();
if (m_unitvalueTable && !m_cacheUnit.Symbol.isEmpty()) {
unit = m_cacheUnit;
}
} else {
unit.NbDecimal = SKGServices::stringToInt(obj->getAttribute(QStringLiteral("i_NBDEC")));
if (unit.NbDecimal == 0) {
unit.NbDecimal = 2;
}
if (att != QStringLiteral("f_QUANTITYOWNED")) {
unit.Symbol = obj->getAttribute(QStringLiteral("t_UNIT"));
}
}
// Bug 209672 vvvv
if (m_unitTable) {
if (obj->getAttribute(QStringLiteral("t_type")) == QStringLiteral("I")) {
unit.Symbol = ' ';
}
}
// Bug 209672 ^^^
if (QString::compare(att, QStringLiteral("f_rate"), Qt::CaseInsensitive) == 0) {
unit.Symbol = '%';
unit.NbDecimal = 2;
} else if (att == QStringLiteral("f_coef")) {
unit.Symbol = QLatin1String("");
unit.NbDecimal = 2;
}
if (unit.Symbol.isEmpty()) {
unit.Symbol = ' ';
}
return SKGServices::toCurrencyString(dval, unit.Symbol, unit.NbDecimal);
}
return dval;
}
if (getAttributeType(iIndex.column()) == SKGServices::INTEGER) {
if (m_recurrentoperationTable && att == QStringLiteral("i_nb_times")) {
QString t_times = obj->getAttribute(QStringLiteral("t_times"));
if (t_times != QStringLiteral("Y")) {
return QChar(8734);
}
} else if ((att == QStringLiteral("i_NBOPERATIONS") || att == QStringLiteral("i_SUMNBOPERATIONS")) && val == QStringLiteral("0")) {
return "";
}
return SKGServices::stringToInt(val);
}
if (m_suboperationTable && att.startsWith(QLatin1String("p_"))) {
val = obj->getProperty(att.right(att.count() - 2));
if (val.isEmpty()) {
val = obj->getDocument()->getParameter(att.right(att.count() - 2), obj->getAttribute(QStringLiteral("i_OPID")) % "-operation");
}
return val;
}
if (m_payeeTable && att == QStringLiteral("t_CATEGORY") && val.isEmpty()) {
auto c = qobject_cast<SKGDocumentBank*>(getDocument())->getCategoryForPayee(obj->getAttribute(QStringLiteral("t_name")));
if (!c.isEmpty()) {
return i18n("Auto: %1", c);
}
}
break;
}
case Qt::DecorationRole: {
// decoration
QString att = m_listAttibutes[iIndex.column()];
if (att == QStringLiteral("t_bookmarked")) {
if (obj->getAttribute(QStringLiteral("t_bookmarked")) == QStringLiteral("Y")) {
return m_iconFavorite;
}
} else if (m_operationTable || m_recurrentoperationTable) {
if (att == QStringLiteral("t_mode")) {
if (obj->getAttribute(QStringLiteral("t_TRANSFER")) == QStringLiteral("Y")) {
return m_iconTransfer;
}
if (obj->getAttribute(QStringLiteral("i_group_id")) != QStringLiteral("0")) {
return m_iconGroup;
}
} else if (att == QStringLiteral("t_CATEGORY")) {
if (SKGServices::stringToInt(obj->getAttribute(QStringLiteral("i_NBSUBOPERATIONS"))) > 1) {
return m_iconSplit;
}
} else if (att == QStringLiteral("i_NBRECURRENT") && m_operationTable) {
if (obj->getAttribute(QStringLiteral("i_NBRECURRENT")) != QStringLiteral("0")) {
return m_iconRecurrentMaster;
}
if (obj->getAttribute(QStringLiteral("r_recurrentoperation_id")) != QStringLiteral("0")) {
return m_iconRecurrent;
}
} else if (att == QStringLiteral("t_imported")) {
QString impStatus = obj->getAttribute(QStringLiteral("t_imported"));
if (impStatus == QStringLiteral("Y")) {
return m_iconImported;
}
if (impStatus == QStringLiteral("P")) {
return m_iconImportedChecked;
}
} else if (att == QStringLiteral("t_REFUND") || att == QStringLiteral("t_REALREFUND") || att == QStringLiteral("t_REFUNDDISPLAY")) {
if (att == QStringLiteral("t_REFUNDDISPLAY")) {
if (obj->getAttribute(att).count(QStringLiteral("(")) > 1) {
att.clear();
} else {
att = QStringLiteral("t_REFUND");
}
}
if (!att.isEmpty()) {
QString trackerName;
trackerName = obj->getAttribute(att);
if (!trackerName.isEmpty()) {
SKGTrackerObject tracker(SKGObjectBase(getDocument(), QStringLiteral("refund"))); // Better performance if v_refund is not used
tracker.setName(trackerName);
tracker.load();
if (tracker.isClosed()) {
return m_iconClosed;
}
}
}
}
} else if (m_ruleTable) {
if (att == QStringLiteral("t_action_type")) {
QString val = obj->getAttribute(att);
if (val == QStringLiteral("S")) {
return m_iconSearch;
}
if (val == QStringLiteral("U")) {
return m_iconUpdate;
}
if (val == QStringLiteral("T")) {
return m_iconTemplate;
}
return m_iconAlarm;
}
} else if (m_unitTable) {
if (att == QStringLiteral("f_CURRENTAMOUNT")) {
SKGUnitObject unit(*obj);
double amountOneYearBefore = unit.getAmount(QDate::currentDate().addYears(-1));
double annualchange = 100.0 * (unit.getAmount() - amountOneYearBefore) / amountOneYearBefore;
if (annualchange >= 15) {
return m_iconMuchMore;
}
if (annualchange <= -15) {
return m_iconMuchLess;
}
if (annualchange >= 5) {
return m_iconMore;
}
if (annualchange <= -5) {
return m_iconLess;
}
}
} else if (m_accountTable) {
if (att == QStringLiteral("t_BANK")) {
QString t_icon = obj->getAttribute(QStringLiteral("t_icon"));
if (t_icon.isEmpty()) {
t_icon = obj->getAttribute(QStringLiteral("t_ICON"));
}
if (!t_icon.isEmpty()) {
QString fileName = QStandardPaths::locate(QStandardPaths::GenericDataLocation, "skrooge/images/logo/" % t_icon);
if (fileName.isEmpty()) {
fileName = t_icon;
}
return QVariant::fromValue(QIcon(fileName));
}
} else if (att == QStringLiteral("f_importbalance")) {
QString val = obj->getAttribute(att);
if (val.isEmpty()) {
return "";
}
// Compute value
SKGAccountObject act(*obj);
auto soluces = act.getPossibleReconciliations(SKGServices::stringToDouble(val), false);
return SKGServices::fromTheme(soluces.isEmpty() ? QStringLiteral("security-low") : QStringLiteral("security-high"));
} else if (att == QStringLiteral("f_reconciliationbalance")) {
QString val = obj->getAttribute(att);
if (val.isEmpty()) {
return "";
}
// Compute value
SKGAccountObject act(*obj);
auto soluces = act.getPossibleReconciliations(SKGServices::stringToDouble(val), false);
return SKGServices::fromTheme(soluces.isEmpty() ? QStringLiteral("security-low") : QStringLiteral("security-high"));
}
} else if (m_categoryTable) {
if (iIndex.column() == 0) {
QString t_TYPEEXPENSE = obj->getAttribute(QStringLiteral("t_TYPEEXPENSE"));
if (t_TYPEEXPENSE == QStringLiteral("-")) {
return m_iconCategoryMoins;
}
if (t_TYPEEXPENSE == QStringLiteral("+")) {
return m_iconCategoryPlus;
}
return m_iconCategory;
}
} else if (m_budgetTable) {
if (att == QStringLiteral("f_DELTA") || att == QStringLiteral("f_DELTABEFORETRANSFER")) {
double val = SKGServices::stringToDouble(obj->getAttribute(att));
if (val < -EPSILON) {
return m_iconRed;
}
if (val > EPSILON) {
return m_iconGreen;
}
double transferred = SKGServices::stringToDouble(obj->getAttribute(QStringLiteral("f_transferred")));
if (transferred < -EPSILON) {
return m_iconAnber;
}
return m_iconGreen;
}
}
break;
}
case Qt::TextColorRole: {
// Text color
QString att = m_listAttibutes[iIndex.column()];
if (m_recurrentoperationTable) {
if (obj->getAttribute(QStringLiteral("i_nb_times")) == QStringLiteral("0")) {
return m_fontDisabledScheduleColor;
}
if (att == QStringLiteral("d_date") && SKGServices::stringToTime(obj->getAttribute(QStringLiteral("d_date"))).date() <= QDate::currentDate()) {
return m_fontNegativeColor;
}
} else if (m_operationTable) {
if (SKGServices::stringToTime(obj->getAttribute(QStringLiteral("d_date"))).date() > QDate::currentDate()) {
return m_fontFutureOperationsColor;
}
if (getAttributeType(iIndex.column()) != SKGServices::FLOAT) {
if (obj->getAttribute(QStringLiteral("t_imported")) == QStringLiteral("P")) {
return m_fontNotValidatedOperationsColor;
}
if (m_suboperationTable) {
return m_fontSubOperationsColor;
}
}
}
break;
}
case Qt::TextAlignmentRole: {
// Text alignment
if (m_recurrentoperationTable) {
QString att = m_listAttibutes[iIndex.column()];
if (att == QStringLiteral("i_auto_write_days") || att == QStringLiteral("i_warn_days") || att == QStringLiteral("i_nb_times")) {
return static_cast<int>(Qt::AlignVCenter | Qt::AlignLeft);
}
}
break;
}
case Qt::CheckStateRole: {
// CheckState
QString att = m_listAttibutes[iIndex.column()];
if (m_operationTable && att == QStringLiteral("t_status")) {
QString cond = obj->getAttribute(QStringLiteral("t_status"));
if (cond == QStringLiteral("P")) {
return static_cast<int>(Qt::PartiallyChecked);
}
if (cond == QStringLiteral("Y")) {
return static_cast<int>(Qt::Checked);
}
if (cond == QStringLiteral("N")) {
return static_cast<int>(Qt::Unchecked);
}
} else if (att == QStringLiteral("t_close")) {
QString cond = obj->getAttribute(QStringLiteral("t_close"));
if (cond == QStringLiteral("Y")) {
return static_cast<int>(Qt::Checked);
}
return static_cast<int>(Qt::Unchecked);
} else if (m_recurrentoperationTable && att == QStringLiteral("i_auto_write_days")) {
QString cond = obj->getAttribute(QStringLiteral("t_auto_write"));
if (cond == QStringLiteral("Y")) {
return static_cast<int>(Qt::Checked);
}
return static_cast<int>(Qt::Unchecked);
} else if (m_recurrentoperationTable && att == QStringLiteral("i_warn_days")) {
QString cond = obj->getAttribute(QStringLiteral("t_warn"));
if (cond == QStringLiteral("Y")) {
return static_cast<int>(Qt::Checked);
}
return static_cast<int>(Qt::Unchecked);
} else if (m_recurrentoperationTable && att == QStringLiteral("i_nb_times")) {
QString cond = obj->getAttribute(QStringLiteral("t_times"));
if (cond == QStringLiteral("Y")) {
return static_cast<int>(Qt::Checked);
}
return static_cast<int>(Qt::Unchecked);
} else if (m_budgetRuleTable && att == QStringLiteral("t_CATEGORYCONDITION")) {
QString cond = obj->getAttribute(QStringLiteral("t_category_condition"));
if (cond == QStringLiteral("Y")) {
return static_cast<int>(Qt::Checked);
}
return static_cast<int>(Qt::Unchecked);
} else if (m_budgetRuleTable && att == QStringLiteral("i_year")) {
QString cond = obj->getAttribute(QStringLiteral("t_year_condition"));
if (cond == QStringLiteral("Y")) {
return static_cast<int>(Qt::Checked);
}
return static_cast<int>(Qt::Unchecked);
} else if (m_budgetRuleTable && att == QStringLiteral("i_month")) {
QString cond = obj->getAttribute(QStringLiteral("t_month_condition"));
if (cond == QStringLiteral("Y")) {
return static_cast<int>(Qt::Checked);
}
return static_cast<int>(Qt::Unchecked);
} else if (m_budgetRuleTable && att == QStringLiteral("t_CATEGORY")) {
QString cond = obj->getAttribute(QStringLiteral("t_category_target"));
if (cond == QStringLiteral("Y")) {
return static_cast<int>(Qt::Checked);
}
return static_cast<int>(Qt::Unchecked);
} else if (m_budgetTable && att == QStringLiteral("t_CATEGORY")) {
QString cond = obj->getAttribute(QStringLiteral("t_including_subcategories"));
if (cond == QStringLiteral("Y")) {
return static_cast<int>(Qt::Checked);
}
return static_cast<int>(Qt::Unchecked);
}
break;
}
case Qt::ToolTipRole: {
// Tooltip
QString toolTipString;
QString att = m_listAttibutes[iIndex.column()];
if (getAttributeType(iIndex.column()) == SKGServices::FLOAT) {
// Add secondary unit
if (!att.contains(QStringLiteral("QUANTITY")) && att != QStringLiteral("f_coef") && att != QStringLiteral("f_rate")) {
SKGServices::SKGUnitInfo secondaryUnit = qobject_cast<SKGDocumentBank*>(getDocument())->getSecondaryUnit();
if (!secondaryUnit.Symbol.isEmpty()) {
double val = SKGServices::stringToDouble(obj->getAttribute(att));
if ((!att.endsWith(QLatin1String("_INCOME")) && !att.endsWith(QLatin1String("_EXPENSE"))) || val != 0) {
if (secondaryUnit.Value != 0.0) {
toolTipString = SKGServices::toCurrencyString(val / secondaryUnit.Value, secondaryUnit.Symbol, secondaryUnit.NbDecimal);
}
}
}
}
// Add balance
if (m_operationTable && !m_suboperationTable) {
SKGOperationObject op(*obj);
if (!op.isTemplate()) {
SKGServices::SKGUnitInfo primaryUnit = qobject_cast<SKGDocumentBank*>(getDocument())->getPrimaryUnit();
// Add original amount
QString originalAmount = obj->getProperty(QStringLiteral("SKG_OP_ORIGINAL_AMOUNT"));
if (!originalAmount.isEmpty()) {
if (!toolTipString.isEmpty()) {
toolTipString += QStringLiteral("\n\n");
}
double val1 = SKGServices::stringToDouble(obj->getAttribute(QStringLiteral("f_CURRENTAMOUNT")));
double val2 = SKGServices::stringToDouble(originalAmount);
double gain = (val2 != 0 ? 100.0 * (val1 - val2) / val2 : 0);
double gainperyear = gain;
int nbDays = op.getDate().daysTo(QDate::currentDate());
if (nbDays != 0 && val2 != 0) {
double gainperday = 100.0 * expm1(log(val1 / val2) / static_cast<double>(nbDays));
gainperyear = 100.0 * (pow(1.0 + gainperday / 100.0, 365.0) - 1);
}
toolTipString += i18nc("Noun", "Original amount=%1 (%2 = %3 / year)",
SKGServices::toCurrencyString(val2, primaryUnit.Symbol, primaryUnit.NbDecimal),
(gain >= 0 ? "+" : "-") % SKGServices::toPercentageString(gain, 2),
(gainperyear >= 0 ? "+" : "-") % SKGServices::toPercentageString(gainperyear, 2));
} else {
if (!toolTipString.isEmpty()) {
toolTipString += QStringLiteral("\n\n");
}
double val1 = SKGServices::stringToDouble(obj->getAttribute(QStringLiteral("f_CURRENTAMOUNT")));
double val2 = op.getAmount(op.getDate());
double gain = (val2 != 0 ? 100.0 * (val1 - val2) / val2 : 0);
double gainperyear = gain;
int nbDays = op.getDate().daysTo(QDate::currentDate());
if (nbDays != 0 && val2 != 0) {
double gainperday = 100.0 * expm1(log(val1 / val2) / static_cast<double>(nbDays));
gainperyear = 100.0 * (pow(1.0 + gainperday / 100.0, 365.0) - 1);
}
QString sval1 = SKGServices::toCurrencyString(val1, primaryUnit.Symbol, primaryUnit.NbDecimal);
QString sval2 = SKGServices::toCurrencyString(val2, primaryUnit.Symbol, primaryUnit.NbDecimal);
if (sval1 != sval2) {
toolTipString += i18nc("Noun", "Amount at creation date=%1 (%2 = %3 / year)",
sval2,
(gain >= 0 ? "+" : "-") % SKGServices::toPercentageString(gain, 2),
(gainperyear >= 0 ? "+" : "-") % SKGServices::toPercentageString(gainperyear, 2));
toolTipString += '\n';
}
}
toolTipString += i18nc("Noun", "Account balance=%1",
SKGServices::toCurrencyString(op.getBalance(), primaryUnit.Symbol, primaryUnit.NbDecimal));
}
}
if (m_budgetTable) {
if (att == QStringLiteral("f_DELTA")) {
double val = SKGServices::stringToDouble(obj->getAttribute(QStringLiteral("f_DELTABEFORETRANSFER")));
if (!toolTipString.isEmpty()) {
toolTipString += QStringLiteral("\n\n");
}
SKGServices::SKGUnitInfo primaryUnit = qobject_cast<SKGDocumentBank*>(getDocument())->getPrimaryUnit();
toolTipString += i18nc("Noun", "Original delta=%1",
SKGServices::toCurrencyString(val, primaryUnit.Symbol, primaryUnit.NbDecimal));
} else if (att == QStringLiteral("f_budgeted_modified")) {
QString reasons = obj->getAttribute(QStringLiteral("t_modification_reasons"));
if (!reasons.isEmpty()) {
if (!toolTipString.isEmpty()) {
toolTipString += QStringLiteral("\n\n");
}
toolTipString += reasons;
}
}
}
if (m_unitTable) {
if (att == QStringLiteral("f_CURRENTAMOUNT")) {
SKGUnitObject unit(*obj);
double amountOneYearBefore = unit.getAmount(QDate::currentDate().addYears(-1));
double annualchange = 100.0 * (unit.getAmount() - amountOneYearBefore) / amountOneYearBefore;
if (!toolTipString.isEmpty()) {
toolTipString += QStringLiteral("\n\n");
}
toolTipString += SKGServices::toPercentageString(annualchange);
}
}
} else if (m_operationTable || m_recurrentoperationTable) {
if (att == QStringLiteral("t_imported")) {
if (!m_suboperationTable) {
SKGOperationObject op;
if (m_recurrentoperationTable) {
SKGRecurrentOperationObject rop(*obj);
rop.getParentOperation(op);
} else {
op = *obj;
}
toolTipString = op.getImportID();
}
} else if (att == QStringLiteral("t_REFUND") || att == QStringLiteral("t_REALREFUND") || att == QStringLiteral("t_REFUNDDISPLAY")) {
if (att == QStringLiteral("t_REFUNDDISPLAY")) {
if (obj->getAttribute(att).count(QStringLiteral("(")) > 1) {
att.clear();
} else {
att = QStringLiteral("t_REFUND");
}
}
if (!att.isEmpty()) {
QString trackerName = obj->getAttribute(att);
if (!trackerName.isEmpty()) {
SKGTrackerObject tracker(getDocument());
tracker.setName(trackerName);
tracker.load();
SKGServices::SKGUnitInfo unit = qobject_cast<SKGDocumentBank*>(getDocument())->getPrimaryUnit();
toolTipString = SKGServices::toCurrencyString(tracker.getCurrentAmount(), unit.Symbol, unit.NbDecimal);
}
}
} else if (att == QStringLiteral("t_PAYEE")) {
QString payeeName = obj->getAttribute(att);
if (!payeeName.isEmpty()) {
SKGPayeeObject payee(getDocument());
payee.setName(payeeName);
payee.load();
auto address = payee.getAddress();
if (!address.isEmpty()) {
toolTipString += i18nc("Information", "Address= %1\n", address);
}
auto c = payee.getAttribute(QStringLiteral("t_CATEGORY"));
if (c.isEmpty()) {
c = qobject_cast<SKGDocumentBank*>(getDocument())->getCategoryForPayee(payeeName, false);
}
if (!c.isEmpty()) {
toolTipString += i18nc("Information", "Category= %1\n", c);
}
}
} else if (att == QStringLiteral("t_ACCOUNT") || att == QStringLiteral("t_TOACCOUNT")) {
QString accountName = obj->getAttribute(att);
if (!accountName.isEmpty()) {
SKGAccountObject account(getDocument());
account.setName(accountName);
account.load();
auto tmp = account.getAgencyNumber();
if (!tmp.isEmpty()) {
toolTipString += i18nc("Information", "Agency number= %1\n", tmp);
}
tmp = account.getNumber();
if (!tmp.isEmpty()) {
toolTipString += i18nc("Information", "Number= %1\n", tmp);
}
tmp = account.getAgencyAddress();
if (!tmp.isEmpty()) {
toolTipString += i18nc("Information", "Address= %1\n", tmp);
}
tmp = account.getComment();
if (!tmp.isEmpty()) {
toolTipString += i18nc("Information", "Comment= %1\n", tmp);
}
}
} else if (att == QStringLiteral("t_CATEGORY")) {
SKGOperationObject op(*obj);
if (m_recurrentoperationTable) {
SKGRecurrentOperationObject rop(*obj);
rop.getParentOperation(op);
}
if (SKGServices::stringToInt(op.getAttribute(QStringLiteral("i_NBSUBOPERATIONS"))) > 1) {
SKGObjectBase::SKGListSKGObjectBase subOps;
op.getSubOperations(subOps);
for (const auto& subOp : qAsConst(subOps)) {
toolTipString += subOp.getDisplayName() % '\n';
}
}
} else if (att == QStringLiteral("t_mode")) {
SKGOperationObject op(*obj);
if (m_recurrentoperationTable) {
SKGRecurrentOperationObject rop(*obj);
rop.getParentOperation(op);
}
if (op.getAttribute(QStringLiteral("i_group_id")) != QStringLiteral("0")) {
SKGOperationObject gop;
op.getGroupOperation(gop);
SKGObjectBase::SKGListSKGObjectBase gOps;
op.getGroupedOperations(gOps);
for (const auto& item : qAsConst(gOps)) {
SKGOperationObject gOp(item);
SKGAccountObject account;
gOp.getParentAccount(account);
toolTipString += account.getDisplayName() % '\n';
}
}
}
if (m_operationTable && !m_suboperationTable && toolTipString.isEmpty()) {
SKGOperationObject op(*obj);
if (op.getStatus() == SKGOperationObject::POINTED) {
toolTipString = i18nc("A tool tip", "This operation is pointed but not checked yet.");
toolTipString += '\n';
toolTipString += i18nc("A tool tip", "You can use the reconciliation mode to validate pointed operations.");
toolTipString += '\n';
toolTipString += i18nc("A tool tip", "Click to switch back status.");
toolTipString += '\n';
toolTipString += i18nc("A tool tip", "Ctrl+click to force checked status.");
} else if (op.getStatus() == SKGOperationObject::CHECKED) {
toolTipString = i18nc("A tool tip", "This operation is already checked.");
} else if (op.getStatus() == SKGOperationObject::NONE) {
toolTipString = i18nc("A tool tip", "This operation is not pointed yet.");
toolTipString += '\n';
toolTipString += i18nc("A tool tip", "Click to set pointed status.");
toolTipString += '\n';
toolTipString += i18nc("A tool tip", "Ctrl+click to force checked status.");
}
}
} else if (m_ruleTable && att == QStringLiteral("t_action_type")) {
QString val = obj->getAttribute(att);
if (val == QStringLiteral("S")) {
toolTipString = i18nc("Noun, a search", "Search");
} else if (val == QStringLiteral("U")) {
toolTipString = i18nc("Noun, a modification", "Update");
} else {
toolTipString = i18nc("Noun, an alarm", "Alarm");
}
}
QString toolTipStringBase = SKGObjectModelBase::computeData(iIndex, iRole).toString();
if (!toolTipStringBase.isEmpty()) {
if (!toolTipString.isEmpty()) {
toolTipString += QStringLiteral("\n\n");
}
toolTipString += toolTipStringBase;
}
return toolTipString;
}
default: {
}
}
return SKGObjectModelBase::computeData(iIndex, iRole);
}
bool SKGObjectModel::setData(const QModelIndex& iIndex, const QVariant& iValue, int iRole)
{
if (!iIndex.isValid()) {
return false;
}
if (iRole == Qt::CheckStateRole) {
SKGError err;
{
auto newState = static_cast<Qt::CheckState>(iValue.toInt());
if (m_accountTable) {
SKGAccountObject obj(getObject(iIndex));
SKGBEGINLIGHTTRANSACTION(*getDocument(),
(newState == Qt::Checked ? i18nc("Noun, name of the user action", "Close account '%1'", obj.getName()) : i18nc("Noun, name of the user action", "Open account '%1'", obj.getName())), err);
if (qAbs(obj.getCurrentAmount()) > 0.01 && newState == Qt::Checked) {
err = getDocument()->sendMessage(i18nc("An information message", "Warning, you closed an account with money"), SKGDocument::Warning);
}
IFOKDO(err, obj.setClosed(newState == Qt::Checked))
IFOKDO(err, obj.save())
} else if (m_trackerTable) {
SKGTrackerObject obj(getObject(iIndex));
SKGBEGINLIGHTTRANSACTION(*getDocument(),
(newState == Qt::Checked ? i18nc("Noun, name of the user action", "Close tracker '%1'", obj.getName()) : i18nc("Noun, name of the user action", "Open tracker '%1'", obj.getName())), err);
err = obj.setClosed(newState == Qt::Checked);
IFOKDO(err, obj.save())
} else if (m_categoryTable) {
SKGCategoryObject obj(getObject(iIndex));
SKGBEGINLIGHTTRANSACTION(*getDocument(),
(newState == Qt::Checked ? i18nc("Noun, name of the user action", "Close category '%1'", obj.getName()) : i18nc("Noun, name of the user action", "Open category '%1'", obj.getName())), err);
err = obj.setClosed(newState == Qt::Checked);
IFOKDO(err, obj.save())
} else if (m_payeeTable) {
SKGPayeeObject obj(getObject(iIndex));
SKGBEGINLIGHTTRANSACTION(*getDocument(),
(newState == Qt::Checked ? i18nc("Noun, name of the user action", "Close payee '%1'", obj.getName()) : i18nc("Noun, name of the user action", "Open payee '%1'", obj.getName())), err);
err = obj.setClosed(newState == Qt::Checked);
IFOKDO(err, obj.save())
} else if (m_operationTable && !m_suboperationTable) {
// Get the real object, not the object from the view
SKGObjectBase* objtmp = getObjectPointer(iIndex);
if (objtmp != nullptr) {
SKGOperationObject obj = SKGOperationObject(objtmp->getDocument(), objtmp->getID());
SKGBEGINLIGHTTRANSACTION(*getDocument(), i18nc("Noun, name of the user action", "Change operation status"), err)
SKGOperationObject::OperationStatus statusinitial = obj.getStatus();
SKGOperationObject::OperationStatus t_status = statusinitial;
if ((QApplication::keyboardModifiers() & Qt::ControlModifier) != 0u) {
// 2747379: NONE ==> CHECKED, POINTED ==> CHECKED, CHECKED ==> CHECKED
t_status = SKGOperationObject::CHECKED;
// t_status= ( t_status==SKGOperationObject::POINTED ? SKGOperationObject::NONE : ( t_status==SKGOperationObject::CHECKED ? SKGOperationObject::POINTED : SKGOperationObject::NONE ) );
} else {
// 2747379: NONE ==> POINTED, POINTED ==> NONE, CHECKED ==> POINTED
t_status = (t_status == SKGOperationObject::NONE ? SKGOperationObject::POINTED : (t_status == SKGOperationObject::POINTED ? SKGOperationObject::NONE : SKGOperationObject::POINTED));
// t_status=(t_status==SKGOperationObject::POINTED ? SKGOperationObject::CHECKED : (t_status==SKGOperationObject::CHECKED ? SKGOperationObject::CHECKED : SKGOperationObject::POINTED ));
}
if (t_status != statusinitial) {
err = obj.setStatus(t_status);
IFOKDO(err, obj.save())
// Send message
IFOKDO(err, getDocument()->sendMessage(i18nc("An information to the user", "The status of the operation '%1' has been changed", obj.getDisplayName()), SKGDocument::Hidden))
}
}
} else if (m_recurrentoperationTable) {
QString att = m_listAttibutes[iIndex.column()];
// Get the real object, not the object from the view
SKGObjectBase* objtmp = getObjectPointer(iIndex);
if (objtmp != nullptr) {
SKGRecurrentOperationObject obj = SKGRecurrentOperationObject(objtmp->getDocument(), objtmp->getID());
SKGBEGINLIGHTTRANSACTION(*getDocument(), i18nc("Noun, name of the user action", "Recurrent operation update"), err)
if (att == QStringLiteral("i_warn_days")) {
err = obj.warnEnabled(!obj.isWarnEnabled());
} else if (att == QStringLiteral("i_auto_write_days")) {
err = obj.autoWriteEnabled(!obj.isAutoWriteEnabled());
} else if (att == QStringLiteral("i_nb_times")) {
err = obj.timeLimit(!obj.hasTimeLimit());
}
IFOKDO(err, obj.save())
// Send message
IFOKDO(err, getDocument()->sendMessage(i18nc("An information to the user", "The recurrent operation '%1' has been updated", obj.getDisplayName()), SKGDocument::Hidden))
}
} else if (m_budgetRuleTable) {
QString att = m_listAttibutes[iIndex.column()];
// Get the real object, not the object from the view
SKGObjectBase* objtmp = getObjectPointer(iIndex);
if (objtmp != nullptr) {
SKGBudgetRuleObject obj = SKGBudgetRuleObject(objtmp->getDocument(), objtmp->getID());
SKGBEGINLIGHTTRANSACTION(*getDocument(), i18nc("Noun, name of the user action", "Budget rule update"), err)
if (att == QStringLiteral("i_year")) {
err = obj.enableYearCondition(!obj.isYearConditionEnabled());
} else if (att == QStringLiteral("i_month")) {
err = obj.enableMonthCondition(!obj.isMonthConditionEnabled());
} else if (att == QStringLiteral("t_CATEGORYCONDITION")) {
err = obj.enableCategoryCondition(!obj.isCategoryConditionEnabled());
} else if (att == QStringLiteral("t_CATEGORY")) {
err = obj.enableCategoryChange(!obj.isCategoryChangeEnabled());
}
IFOKDO(err, obj.save())
// Send message
IFOKDO(err, getDocument()->sendMessage(i18nc("An information to the user", "The budget rule '%1' has been updated", obj.getDisplayName()), SKGDocument::Hidden))
}
} else if (m_budgetTable) {
QString att = m_listAttibutes[iIndex.column()];
// Get the real object, not the object from the view
SKGObjectBase* objtmp = getObjectPointer(iIndex);
if (objtmp != nullptr) {
SKGBudgetObject obj = SKGBudgetObject(objtmp->getDocument(), objtmp->getID());
SKGBEGINTRANSACTION(*getDocument(), i18nc("Noun, name of the user action", "Budget update"), err)
if (att == QStringLiteral("t_CATEGORY")) {
IFOKDO(err, obj.enableSubCategoriesInclusion(!obj.isSubCategoriesInclusionEnabled()))
IFOKDO(err, obj.save())
// Send message
IFOKDO(err, getDocument()->sendMessage(i18nc("An information to the user", "The budget '%1' have been updated", obj.getDisplayName()), SKGDocument::Hidden))
}
}
}
}
SKGMainPanel::displayErrorMessage(err);
return !err;
}
return SKGObjectModelBase::setData(iIndex, iValue, iRole);
}
Qt::ItemFlags SKGObjectModel::flags(const QModelIndex& iIndex) const
{
_SKGTRACEINFUNC(10)
Qt::ItemFlags f = SKGObjectModelBase::flags(iIndex);
if (iIndex.isValid()) {
QString att = m_listAttibutes[iIndex.column()];
if (att == QStringLiteral("t_bookmarked") || m_ruleTable || m_recurrentoperationTable || m_interestTable || m_interestResultTable) {
f = f & ~Qt::ItemIsEditable;
}
}
if (m_categoryTable || m_payeeTable || m_accountTable || m_unitTable || m_trackerTable) {
if (iIndex.isValid()) {
f |= Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled;
} else {
f |= Qt::ItemIsDropEnabled;
}
}
return f;
}
Qt::DropActions SKGObjectModel::supportedDragActions() const
{
if (m_categoryTable || m_payeeTable || m_accountTable || m_unitTable || m_trackerTable) {
return Qt::MoveAction;
}
return SKGObjectModelBase::supportedDragActions();
}
Qt::DropActions SKGObjectModel::supportedDropActions() const
{
if (m_categoryTable || m_payeeTable || m_accountTable || m_unitTable || m_trackerTable) {
return Qt::MoveAction;
}
return SKGObjectModelBase::supportedDropActions();
}
bool SKGObjectModel::dropMimeData(const QMimeData* iData,
Qt::DropAction iAction,
int iRow, int iColumn,
const QModelIndex& iParent)
{
if (SKGObjectModelBase::dropMimeData(iData, iAction, iRow, iColumn, iParent)) {
return true;
}
if (iAction == Qt::IgnoreAction) {
return true;
}
if ((iData == nullptr) || !(iData->hasFormat(QStringLiteral("application/skg.category.ids")) ||
iData->hasFormat(QStringLiteral("application/skg.payee.ids")) ||
iData->hasFormat(QStringLiteral("application/skg.account.ids")) ||
iData->hasFormat(QStringLiteral("application/skg.refund.ids")) ||
iData->hasFormat(QStringLiteral("application/skg.unit.ids")))) {
return false;
}
if (iColumn > 0) {
return false;
}
SKGError err;
if (iData->hasFormat(QStringLiteral("application/skg.category.ids"))) {
QByteArray encodedData = iData->data(QStringLiteral("application/skg.category.ids"));
QDataStream stream(&encodedData, QIODevice::ReadOnly);
QStringList newItems;
SKGCategoryObject parentCategory;
if (iParent.isValid()) {
parentCategory = getObject(iParent);
}
{
SKGBEGINTRANSACTION(*getDocument(), i18nc("Noun, name of the user action", "Move category"), err)
while (!stream.atEnd() && !err) {
int o_id;
QString o_table;
stream >> o_table;
stream >> o_id;
SKGCategoryObject child(getDocument(), o_id);
err = child.load();
QString oldName = child.getDisplayName();
IFOK(err) {
if (iParent.isValid()) {
err = child.setParentCategory(parentCategory);
} else {
err = child.removeParentCategory();
}
}
IFOKDO(err, child.save())
// Send message
IFOKDO(err, getDocument()->sendMessage(i18nc("An information to the user", "The category '%1' has been moved to '%2'", oldName, child.getDisplayName()), SKGDocument::Hidden))
}
}
} else if (iData->hasFormat(QStringLiteral("application/skg.payee.ids"))) {
QByteArray encodedData = iData->data(QStringLiteral("application/skg.payee.ids"));
QDataStream stream(&encodedData, QIODevice::ReadOnly);
QStringList newItems;
if (iParent.isValid()) {
SKGBEGINTRANSACTION(*getDocument(), i18nc("Noun, name of the user action", "Merge payees"), err)
SKGPayeeObject parentPayee(getObject(iParent));
while (!stream.atEnd() && !err) {
int o_id;
QString o_table;
stream >> o_table;
stream >> o_id;
SKGPayeeObject child(getDocument(), o_id);
err = child.load();
// Send message
IFOKDO(err, getDocument()->sendMessage(i18nc("An information to the user", "The payee '%1' has been merged with payee '%2'", child.getDisplayName(), parentPayee.getDisplayName()), SKGDocument::Hidden))
IFOKDO(err, parentPayee.merge(child))
}
}
} else if (iData->hasFormat(QStringLiteral("application/skg.account.ids"))) {
QByteArray encodedData = iData->data(QStringLiteral("application/skg.account.ids"));
QDataStream stream(&encodedData, QIODevice::ReadOnly);
QStringList newItems;
if (iParent.isValid()) {
SKGBEGINTRANSACTION(*getDocument(), i18nc("Noun, name of the user action", "Merge accounts"), err)
SKGAccountObject parentAccount(getObject(iParent));
while (!stream.atEnd() && !err) {
int o_id;
QString o_table;
stream >> o_table;
stream >> o_id;
SKGAccountObject child(getDocument(), o_id);
err = child.load();
// Send message
IFOKDO(err, getDocument()->sendMessage(i18nc("An information to the user", "The account '%1' has been merged with account '%2'", child.getDisplayName(), parentAccount.getDisplayName()), SKGDocument::Hidden))
double balancebefore = 0.0;
double balanceafter = 0.0;
SKGUnitObject unit2;
IFOKDO(err, parentAccount.getInitialBalance(balancebefore, unit2))
IFOKDO(err, parentAccount.merge(child, !(QApplication::keyboardModifiers() &Qt::ControlModifier)))
IFOKDO(err, parentAccount.getInitialBalance(balanceafter, unit2))
if (balanceafter != balancebefore) {
getDocument()->sendMessage(i18nc("Warning message", "The initial balance of the target account '%1' has been change to %2.\nIf you want to do the merge without changing the initial balance, you must keep the Ctrl key pressed.", parentAccount.getDisplayName(), balanceafter), SKGDocument::Warning);
}
}
}
} else if (iData->hasFormat(QStringLiteral("application/skg.unit.ids"))) {
QByteArray encodedData = iData->data(QStringLiteral("application/skg.unit.ids"));
QDataStream stream(&encodedData, QIODevice::ReadOnly);
QStringList newItems;
if (iParent.isValid()) {
SKGBEGINTRANSACTION(*getDocument(), i18nc("Noun, name of the user action", "Merge units"), err)
SKGUnitObject parentUnit(getObject(iParent));
while (!stream.atEnd() && !err) {
int o_id;
QString o_table;
stream >> o_table;
stream >> o_id;
SKGUnitObject child(getDocument(), o_id);
err = child.load();
// Send message
IFOKDO(err, getDocument()->sendMessage(i18nc("An information to the user", "The unit '%1' has been merged with unit '%2'", child.getDisplayName(), parentUnit.getDisplayName()), SKGDocument::Hidden))
IFOKDO(err, parentUnit.merge(child))
}
}
} else if (iData->hasFormat(QStringLiteral("application/skg.refund.ids"))) {
QByteArray encodedData = iData->data(QStringLiteral("application/skg.refund.ids"));
QDataStream stream(&encodedData, QIODevice::ReadOnly);
QStringList newItems;
if (iParent.isValid()) {
SKGBEGINTRANSACTION(*getDocument(), i18nc("Noun, name of the user action", "Merge trackers"), err)
SKGTrackerObject parentTracker(getObject(iParent));
while (!stream.atEnd() && !err) {
int o_id;
QString o_table;
stream >> o_table;
stream >> o_id;
SKGTrackerObject child(getDocument(), o_id);
err = child.load();
// Send message
IFOKDO(err, parentTracker.getDocument()->sendMessage(i18nc("An information to the user", "The tracker '%1' has been merged with tracker '%2'", child.getDisplayName(), parentTracker.getDisplayName()), SKGDocument::Hidden))
IFOKDO(err, parentTracker.merge(child))
}
}
}
SKGMainPanel::displayErrorMessage(err);
return !err;
}
void SKGObjectModel::dataModified(const QString& iTableName, int iIdTransaction)
{
if (getRealTable() == iTableName || iTableName.isEmpty() || getRealTable() == QStringLiteral("doctransaction")) {
SKGTRACEINFUNC(1)
if (iTableName == QStringLiteral("category")) {
// Full refresh
m_isResetRealyNeeded = true;
refresh();
} else {
SKGObjectModelBase::dataModified(iTableName, iIdTransaction);
}
} else {
SKGObjectModelBase::dataModified(iTableName, iIdTransaction);
}
}
QString SKGObjectModel::formatMoney(double iValue) const
{
return getDocument()->formatMoney(iValue, qobject_cast<SKGDocumentBank*>(getDocument())->getPrimaryUnit(), false);
}
diff --git a/skgbankgui/skgobjectmodel.h b/skgbankgui/skgobjectmodel.h
index 2c1ce5182..cf3720237 100644
--- a/skgbankgui/skgobjectmodel.h
+++ b/skgbankgui/skgobjectmodel.h
@@ -1,202 +1,202 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGOBJECTMODEL_H
#define SKGOBJECTMODEL_H
/** @file
* This file defines classes SKGObjectModel.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include <qcolor.h>
#include <qfont.h>
#include "skgbankgui_export.h"
#include "skgdocumentbank.h"
#include "skgobjectbase.h"
#include "skgobjectmodelbase.h"
/**
* The Table model managing SKGObjectBase
*/
class SKGBANKGUI_EXPORT SKGObjectModel : public SKGObjectModelBase
{
Q_OBJECT
public:
/**
* Default constructor
* @param iDocument the document where to search
* @param iTable the table where to search
* @param iWhereClause the where clause
* @param iParent parent QT object
* @param iParentAttribute the attribute to find the parent of an object clause to find children
* @param iResetOnCreation to reset data during creation
*/
explicit SKGObjectModel(SKGDocumentBank* iDocument,
const QString& iTable,
const QString& iWhereClause,
QWidget* iParent,
const QString& iParentAttribute = QString(),
bool iResetOnCreation = true);
/**
* Destructor
*/
~SKGObjectModel() override;
/**
* Returns the data stored under the given role for the item referred to by the index.
* @param iIndex the index
* @param iRole the role
* @return the returned value
*/
QVariant computeData(const QModelIndex& iIndex, int iRole = Qt::DisplayRole) const override;
/**
* Sets the role data for the item at index to value. Returns true if successful; otherwise returns false.
* @param iIndex index of the object
* @param iValue value
* @param iRole role
* @return
*/
bool setData(const QModelIndex& iIndex, const QVariant& iValue, int iRole = Qt::EditRole) override;
/**
* Returns the data for the given role and section in the header with the specified orientation.
* @param section the section
* @param orientation the orientation
* @param role the role
* @return the header data
*/
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
/**
* Returns the item flags for the given index.
* @param iIndex index of the object
* @return flags of the given index
*/
Qt::ItemFlags flags(const QModelIndex& iIndex) const override;
/**
* Returns the actions supported by the data in this model.
* @return Qt::DropActions
*/
Qt::DropActions supportedDragActions() const override;
/**
* Returns the actions supported by the data in this model.
* @return Qt::DropActions
*/
Qt::DropActions supportedDropActions() const override;
/**
* Handles the data supplied by a drag and drop operation that ended with the given action.
* Returns true if the data and action can be handled by the model; otherwise returns false.
* Although the specified row, column and parent indicate the location of an item in the model where the operation ended,
*it is the responsibility of the view to provide a suitable location for where the data should be inserted.
* @param iData mime data
* @param iAction action
* @param iRow row
* @param iColumn column
* @param iParent parent
* @return true if the dropping was successful otherwise false.
*/
bool dropMimeData(const QMimeData* iData,
Qt::DropAction iAction,
int iRow, int iColumn,
const QModelIndex& iParent) override;
protected:
/**
* Get the attribute value for grouping
* @param iObject the object
* @param iAttribute the attribute name
* @return the value of the attribute
*/
QString getAttributeForGrouping(const SKGObjectBase& iObject, const QString& iAttribute) const override;
/**
* Get the string of an amount
* @param iValue the value
* @return the string
*/
QString formatMoney(double iValue) const override;
protected Q_SLOTS:
/**
* This method is called by refresh to build the cache (to improve performance)
*/
void buidCache() override;
/**
* data are modified
* @param iTableName table name
* @param iIdTransaction the id of the transaction for direct modifications of the table (update of modify objects is enough)
*or 0 in case of modifications by impact (full table must be refreshed)
*/
void dataModified(const QString& iTableName, int iIdTransaction) override;
private:
Q_DISABLE_COPY(SKGObjectModel)
SKGServices::SKGUnitInfo m_cacheUnit;
bool m_operationTable;
bool m_recurrentoperationTable;
bool m_trackerTable;
bool m_accountTable;
bool m_unitTable;
bool m_unitvalueTable;
bool m_suboperationTable;
bool m_categoryTable;
bool m_ruleTable;
bool m_interestTable;
bool m_interestResultTable;
bool m_payeeTable;
bool m_budgetTable;
bool m_budgetRuleTable;
QVariant m_fontDisabledScheduleColor;
QVariant m_fontFutureOperationsColor;
QVariant m_fontNotValidatedOperationsColor;
QVariant m_fontSubOperationsColor;
QVariant m_iconTransfer;
QVariant m_iconGroup;
QVariant m_iconSplit;
QVariant m_iconMuchMore;
QVariant m_iconMuchLess;
QVariant m_iconMore;
QVariant m_iconLess;
QVariant m_iconClosed;
QVariant m_iconImported;
QVariant m_iconImportedChecked;
QVariant m_iconRecurrent;
QVariant m_iconRecurrentMaster;
QVariant m_iconFavorite;
QVariant m_iconCategory;
QVariant m_iconCategoryPlus;
QVariant m_iconCategoryMoins;
QVariant m_iconSearch;
QVariant m_iconUpdate;
QVariant m_iconAlarm;
QVariant m_iconTemplate;
QVariant m_iconGreen;
QVariant m_iconRed;
QVariant m_iconAnber;
};
#endif
diff --git a/skgbankgui/skgpredicatcreator.cpp b/skgbankgui/skgpredicatcreator.cpp
index 641247663..2210bbb30 100644
--- a/skgbankgui/skgpredicatcreator.cpp
+++ b/skgbankgui/skgpredicatcreator.cpp
@@ -1,446 +1,446 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is a query creator for skrooge
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgpredicatcreator.h"
#include <qapplication.h>
#include <qcheckbox.h>
#include <qdom.h>
#include <qlineedit.h>
#include <qtablewidget.h>
#include "skgcalculatoredit.h"
#include "skgcombobox.h"
#include "skgdateedit.h"
#include "skgdocument.h"
#include "skgmainpanel.h"
#include "skgruleobject.h"
#include "skgservices.h"
SKGPredicatCreator::SKGPredicatCreator(QWidget* iParent, SKGDocument* document, const QString& attribute, bool iModeUpdate, const QStringList& iListAtt)
: QWidget(iParent), m_updateMode(iModeUpdate), m_kValue1(nullptr), m_kValue2(nullptr), m_kAttributes(nullptr)
{
SKGServices::AttributeType attType = SKGServices::TEXT;
if (document != nullptr) {
attType = document->getAttributeType(attribute);
}
// Build
this->setAutoFillBackground(true);
this->resize(491, 25);
auto horizontalLayout = new QHBoxLayout(this);
horizontalLayout->setSpacing(2);
horizontalLayout->setMargin(0);
horizontalLayout->setObjectName(QStringLiteral("horizontalLayout"));
m_kOperator = new SKGComboBox(this);
m_kOperator->setObjectName(QStringLiteral("kOperator"));
m_kOperator->setSizeAdjustPolicy(KComboBox::AdjustToContentsOnFirstShow);
QSizePolicy newSizePolicy2(QSizePolicy::Fixed, QSizePolicy::Fixed);
newSizePolicy2.setHorizontalStretch(0);
newSizePolicy2.setVerticalStretch(0);
newSizePolicy2.setHeightForWidth(m_kOperator->sizePolicy().hasHeightForWidth());
m_kOperator->setSizePolicy(newSizePolicy2);
horizontalLayout->addWidget(m_kOperator);
int nbAtt = iListAtt.count();
if (nbAtt != 0) {
m_kAttributes = new SKGComboBox(this);
if (m_kAttributes != nullptr) {
m_kAttributes->setObjectName(QStringLiteral("kAttributes"));
m_kAttributes->setMinimumSize(QSize(100, 0));
m_kAttributes->setEditable(false);
QSizePolicy newSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
newSizePolicy.setHorizontalStretch(0);
newSizePolicy.setVerticalStretch(0);
newSizePolicy.setHeightForWidth(m_kAttributes->sizePolicy().hasHeightForWidth());
m_kAttributes->setSizePolicy(newSizePolicy);
horizontalLayout->addWidget(m_kAttributes);
for (const auto& att : qAsConst(iListAtt)) {
if (document != nullptr) {
m_kAttributes->addItem(document->getIcon(att), document->getDisplay(att), att);
}
}
}
}
if (attType == SKGServices::TEXT) {
auto cmbVal1 = new SKGComboBox(this);
if (cmbVal1 != nullptr) {
cmbVal1->setObjectName(QStringLiteral("cmbVal1"));
cmbVal1->setMinimumSize(QSize(100, 0));
cmbVal1->setEditable(true);
QSizePolicy newSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
newSizePolicy.setHorizontalStretch(0);
newSizePolicy.setVerticalStretch(0);
newSizePolicy.setHeightForWidth(cmbVal1->sizePolicy().hasHeightForWidth());
cmbVal1->setSizePolicy(newSizePolicy);
cmbVal1->lineEdit()->setPlaceholderText(i18n("Value"));
horizontalLayout->addWidget(cmbVal1);
m_kValue1 = cmbVal1;
}
auto cmbVal2 = new SKGComboBox(this);
if (cmbVal2 != nullptr) {
cmbVal2->setObjectName(QStringLiteral("cmbVal2"));
cmbVal2->setMinimumSize(QSize(100, 0));
cmbVal2->setEditable(true);
QSizePolicy newSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
newSizePolicy.setHorizontalStretch(0);
newSizePolicy.setVerticalStretch(0);
newSizePolicy.setHeightForWidth(cmbVal2->sizePolicy().hasHeightForWidth());
cmbVal2->setSizePolicy(newSizePolicy);
cmbVal2->lineEdit()->setPlaceholderText(i18n("Value"));
horizontalLayout->addWidget(cmbVal2);
m_kValue2 = cmbVal2;
}
if (document != nullptr) {
QString realTable = QStringLiteral("operation");
QString realAtt = attribute;
QString realCond = QLatin1String("");
if (attribute == QStringLiteral("t_REALCATEGORY")) {
realTable = QStringLiteral("category");
realAtt = QStringLiteral("t_fullname");
} else if (attribute == QStringLiteral("t_BANK")) {
realTable = QStringLiteral("bank");
realAtt = QStringLiteral("t_name");
} else if (attribute == QStringLiteral("t_ACCOUNT") || attribute == QStringLiteral("t_TOACCOUNT")) {
realTable = QStringLiteral("account");
realAtt = QStringLiteral("t_name");
} else if (attribute == QStringLiteral("t_UNIT")) {
realTable = QStringLiteral("unit");
realAtt = QStringLiteral("t_name");
} else if (attribute == QStringLiteral("t_REALCOMMENT")) {
realTable = QStringLiteral("suboperation");
realAtt = QStringLiteral("t_comment");
} else if (attribute == QStringLiteral("t_REALREFUND")) {
realTable = QStringLiteral("refund");
realAtt = QStringLiteral("t_name");
} else if (attribute == QStringLiteral("t_PAYEE")) {
realTable = QStringLiteral("payee");
realAtt = QStringLiteral("t_name");
} else if (attribute.startsWith(QLatin1String("p_"))) {
realTable = QStringLiteral("parameters");
realAtt = QStringLiteral("t_value");
realCond = "t_name='" % attribute.right(attribute.length() - 2) % '\'';
}
SKGMainPanel::fillWithDistinctValue(QList<QWidget*>() << cmbVal1 << cmbVal2, document, realTable, realAtt, realCond);
}
} else if (attType == SKGServices::INTEGER || attType == SKGServices::FLOAT) {
auto cmbVal1 = new SKGCalculatorEdit(this);
if (cmbVal1 != nullptr) {
cmbVal1->setObjectName(QStringLiteral("cmbVal1"));
cmbVal1->setMode(SKGCalculatorEdit::EXPRESSION);
cmbVal1->setMinimumSize(QSize(100, 0));
horizontalLayout->addWidget(cmbVal1);
m_kValue1 = cmbVal1;
}
auto cmbVal2 = new SKGCalculatorEdit(this);
if (cmbVal2 != nullptr) {
cmbVal2->setObjectName(QStringLiteral("cmbVal2"));
cmbVal2->setMode(SKGCalculatorEdit::EXPRESSION);
cmbVal2->setMinimumSize(QSize(100, 0));
horizontalLayout->addWidget(cmbVal2);
m_kValue2 = cmbVal2;
}
} else if (attType == SKGServices::DATE) {
if (iModeUpdate) {
auto cmbVal1 = new SKGComboBox(this);
if (cmbVal1 != nullptr) {
cmbVal1->setObjectName(QStringLiteral("cmbVal1"));
cmbVal1->setMinimumSize(QSize(100, 0));
cmbVal1->setEditable(true);
QSizePolicy newSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
newSizePolicy.setHorizontalStretch(0);
newSizePolicy.setVerticalStretch(0);
newSizePolicy.setHeightForWidth(cmbVal1->sizePolicy().hasHeightForWidth());
cmbVal1->setSizePolicy(newSizePolicy);
cmbVal1->lineEdit()->setPlaceholderText(i18n("Value"));
horizontalLayout->addWidget(cmbVal1);
m_kValue1 = cmbVal1;
}
auto cmbVal2 = new SKGComboBox(this);
if (cmbVal2 != nullptr) {
cmbVal2->setObjectName(QStringLiteral("cmbVal2"));
cmbVal2->setMinimumSize(QSize(100, 0));
cmbVal2->setEditable(false);
QSizePolicy newSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
newSizePolicy.setHorizontalStretch(0);
newSizePolicy.setVerticalStretch(0);
newSizePolicy.setHeightForWidth(cmbVal2->sizePolicy().hasHeightForWidth());
cmbVal2->setSizePolicy(newSizePolicy);
cmbVal2->addItems(QStringList() << QStringLiteral("YYYYMMDD") << QStringLiteral("MMDDYYYY") << QStringLiteral("DDMMYYYY")
<< QStringLiteral("MM-DD-YY") << QStringLiteral("DD-MM-YY") << QStringLiteral("MM-DD-YYYY") << QStringLiteral("DD-MM-YYYY") << QStringLiteral("YYYY-MM-DD"));
horizontalLayout->addWidget(cmbVal2);
m_kValue2 = cmbVal2;
}
} else {
auto cmbVal1 = new SKGDateEdit(this);
if (cmbVal1 != nullptr) {
cmbVal1->setObjectName(QStringLiteral("cmbVal1"));
cmbVal1->setMinimumSize(QSize(100, 0));
horizontalLayout->addWidget(cmbVal1);
m_kValue1 = cmbVal1;
}
auto cmbVal2 = new SKGDateEdit(this);
if (cmbVal2 != nullptr) {
cmbVal2->setObjectName(QStringLiteral("cmbVal2"));
cmbVal2->setMinimumSize(QSize(100, 0));
horizontalLayout->addWidget(cmbVal2);
m_kValue2 = cmbVal2;
}
}
} else if (attType == SKGServices::BOOL || attType == SKGServices::TRISTATE) {
auto cmbVal1 = new QCheckBox(this);
if (cmbVal1 != nullptr) {
cmbVal1->setObjectName(QStringLiteral("cmbVal1"));
cmbVal1->setMinimumSize(QSize(100, 0));
cmbVal1->setTristate(attType == SKGServices::TRISTATE);
horizontalLayout->addWidget(cmbVal1);
m_kValue1 = cmbVal1;
}
}
// Fill combo boxes
m_kOperator->clear();
m_kOperator->addItem(QLatin1String(""), "");
if (m_kValue1 != nullptr) {
m_kValue1->installEventFilter(this);
}
if (m_kValue2 != nullptr) {
m_kValue2->installEventFilter(this);
}
if (m_kOperator != nullptr) {
m_kOperator->installEventFilter(this);
}
if (m_kAttributes != nullptr) {
m_kAttributes->installEventFilter(this);
}
QStringList listOps = SKGRuleObject::getListOfOperators(attType, m_updateMode ? SKGRuleObject::UPDATE : SKGRuleObject::SEARCH);
int nb = listOps.count();
if (iModeUpdate && attribute == QStringLiteral("t_REALCATEGORY") && nb > 1) {
nb = 1; // TODO(Stephane MANKOWSKI): unblock t_REALCATEGORY
}
for (int i = 0; i < nb; ++i) {
const QString& op = listOps.at(i);
QString nlsOp = SKGRuleObject::getDisplayForOperator(op,
i18nc("Default value", "..."),
i18nc("Default value", "..."),
i18nc("Noun, an item's attribute", "attribute"));
if (m_kOperator != nullptr) {
m_kOperator->addItem(nlsOp, op);
}
}
connect(m_kOperator, static_cast<void (SKGComboBox::*)(const QString&)>(&SKGComboBox::currentTextChanged), this, &SKGPredicatCreator::onOperatorChanged);
onOperatorChanged();
}
SKGPredicatCreator::~SKGPredicatCreator()
{
m_kOperator = nullptr;
m_kValue1 = nullptr;
m_kValue2 = nullptr;
m_kAttributes = nullptr;
}
bool SKGPredicatCreator::eventFilter(QObject* iObject, QEvent* iEvent)
{
Q_UNUSED(iObject)
if ((iEvent != nullptr) && (iEvent->type() == QEvent::FocusIn || iEvent->type() == QEvent::FocusOut)) {
QObject* appliFocus = QApplication::focusWidget();
while (appliFocus != nullptr) {
if (appliFocus == this) {
break;
}
appliFocus = appliFocus->parent();
}
if (appliFocus == nullptr) {
Q_EMIT editingFinished();
}
}
return false;
}
void SKGPredicatCreator::onOperatorChanged()
{
QString req;
if (m_kOperator != nullptr) {
req = m_kOperator->itemData(m_kOperator->currentIndex()).toString();
m_kOperator->setToolTip(SKGRuleObject::getToolTipForOperator(req));
}
if (m_kValue1 != nullptr) {
m_kValue1->setVisible(req.contains(QStringLiteral("#V1S#")) || req.contains(QStringLiteral("#V1#")));
}
if (m_kValue2 != nullptr) {
m_kValue2->setVisible(req.contains(QStringLiteral("#V2S#")) || req.contains(QStringLiteral("#V2#")) || req.contains(QStringLiteral("#DF#")));
}
if (m_kAttributes != nullptr) {
m_kAttributes->setVisible(req.contains(QStringLiteral("#ATT2#")));
}
}
QString SKGPredicatCreator::text()
{
return SKGPredicatCreator::getTextFromXml(xmlDescription());
}
QString SKGPredicatCreator::getTextFromXml(const QString& iXML)
{
QDomDocument doc(QStringLiteral("SKGML"));
doc.setContent(iXML);
QDomElement root = doc.documentElement();
QString output = SKGRuleObject::getDisplayForOperator(root.attribute(QStringLiteral("operator")),
root.attribute(QStringLiteral("value")),
root.attribute(QStringLiteral("value2")),
root.attribute(QStringLiteral("att2s")));
return output;
}
QString SKGPredicatCreator::xmlDescription()
{
QString output;
if (m_kOperator != nullptr) {
QString op = m_kOperator->itemData(m_kOperator->currentIndex()).toString();
if (!op.isEmpty()) {
QDomDocument doc(QStringLiteral("SKGML"));
QDomElement root = doc.createElement(QStringLiteral("element"));
doc.appendChild(root);
// Condition
root.setAttribute(QStringLiteral("operator"), op);
if ((m_kValue1 != nullptr) && m_kValue1->isVisible()) {
auto* cmbVal1 = qobject_cast<SKGDateEdit*> (m_kValue1);
if (cmbVal1 != nullptr) {
root.setAttribute(QStringLiteral("value"), SKGServices::dateToSqlString(QDateTime(cmbVal1->date())));
} else {
auto* cmbVal12 = qobject_cast<SKGCalculatorEdit*> (m_kValue1);
if (cmbVal12 != nullptr) {
root.setAttribute(QStringLiteral("value"), cmbVal12->text());
} else {
auto* cmbVal13 = qobject_cast<QCheckBox*> (m_kValue1);
if (cmbVal13 != nullptr) {
root.setAttribute(QStringLiteral("value"), cmbVal13->checkState() == Qt::Checked ? QStringLiteral("Y") : cmbVal13->checkState() == Qt::Unchecked ? QStringLiteral("N") : QStringLiteral("P"));
} else {
auto* cmbVal14 = qobject_cast<SKGComboBox*> (m_kValue1);
if (cmbVal14 != nullptr) {
root.setAttribute(QStringLiteral("value"), cmbVal14->text());
}
}
}
}
}
if ((m_kValue2 != nullptr) && m_kValue2->isVisible()) {
auto* cmbVal2 = qobject_cast<SKGDateEdit*> (m_kValue2);
if (cmbVal2 != nullptr) {
root.setAttribute(QStringLiteral("value2"), SKGServices::dateToSqlString(QDateTime(cmbVal2->date())));
} else {
auto* cmbVal21 = qobject_cast<SKGCalculatorEdit*> (m_kValue2);
if (cmbVal21 != nullptr) {
root.setAttribute(QStringLiteral("value2"), cmbVal21->text());
} else {
auto* cmbVal22 = qobject_cast<SKGComboBox*> (m_kValue2);
if (cmbVal22 != nullptr) {
root.setAttribute(QStringLiteral("value2"), cmbVal22->text());
}
}
}
}
if ((m_kAttributes != nullptr) && m_kAttributes->isVisible()) {
root.setAttribute(QStringLiteral("att2"), m_kAttributes->itemData(m_kAttributes->currentIndex()).toString());
root.setAttribute(QStringLiteral("att2s"), m_kAttributes->text());
}
output = doc.toString();
}
}
return output;
}
void SKGPredicatCreator::setXmlDescription(const QString& iXML)
{
QDomDocument doc(QStringLiteral("SKGML"));
doc.setContent(iXML);
QDomElement root = doc.documentElement();
// Condition
if (m_kOperator != nullptr) {
m_kOperator->setCurrentIndex(m_kOperator->findData(root.attribute(QStringLiteral("operator"))));
auto* cmbVal1 = qobject_cast<SKGDateEdit*> (m_kValue1);
if (cmbVal1 != nullptr) {
cmbVal1->setDate(SKGServices::stringToTime(root.attribute(QStringLiteral("value"))).date());
} else {
auto* cmbVal12 = qobject_cast<SKGCalculatorEdit*> (m_kValue1);
if (cmbVal12 != nullptr) {
cmbVal12->setText(root.attribute(QStringLiteral("value")));
} else {
auto* cmbVal13 = qobject_cast<QCheckBox*> (m_kValue1);
if (cmbVal13 != nullptr) {
cmbVal13->setCheckState(root.attribute(QStringLiteral("value")) == QStringLiteral("Y") ? Qt::Checked : root.attribute(QStringLiteral("value")) == QStringLiteral("P") ? Qt::PartiallyChecked : Qt::Unchecked);
} else {
auto* cmbVal14 = qobject_cast<SKGComboBox*> (m_kValue1);
if (cmbVal14 != nullptr) {
cmbVal14->setText(root.attribute(QStringLiteral("value")));
}
}
}
}
auto* cmbVal2 = qobject_cast<SKGDateEdit*> (m_kValue2);
if (cmbVal2 != nullptr) {
cmbVal2->setDate(SKGServices::stringToTime(root.attribute(QStringLiteral("value2"))).date());
} else {
auto* cmbVal22 = qobject_cast<SKGCalculatorEdit*> (m_kValue2);
if (cmbVal22 != nullptr) {
cmbVal22->setText(root.attribute(QStringLiteral("value2")));
} else {
auto* cmbVal23 = qobject_cast<SKGComboBox*> (m_kValue2);
if (cmbVal23 != nullptr) {
cmbVal23->setText(root.attribute(QStringLiteral("value2")));
}
}
}
if (m_kAttributes != nullptr) {
m_kAttributes->setCurrentIndex(m_kAttributes->findData(root.attribute(QStringLiteral("att2"))));
}
}
emit xmlDescriptionChanged();
}
diff --git a/skgbankgui/skgpredicatcreator.h b/skgbankgui/skgpredicatcreator.h
index e50a57ff4..094899c3f 100644
--- a/skgbankgui/skgpredicatcreator.h
+++ b/skgbankgui/skgpredicatcreator.h
@@ -1,121 +1,121 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGPREDICATCREATOR_H
#define SKGPREDICATCREATOR_H
/** @file
* A query creator for skrooge.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include <qwidget.h>
#include "skgbankgui_export.h"
class SKGDocument;
class SKGComboBox;
/**
* This file is a query creator for skrooge
*/
class SKGBANKGUI_EXPORT SKGPredicatCreator : public QWidget
{
Q_OBJECT
/**
* Text of the predicat
*/
Q_PROPERTY(QString text READ text USER true NOTIFY xmlDescriptionChanged)
/**
* XML description of the predicat
*/
Q_PROPERTY(QString xmlDescription READ xmlDescription WRITE setXmlDescription NOTIFY xmlDescriptionChanged)
public:
/**
* Default Constructor
* @param iParent the parent
* @param document the document
* @param attribute name of the attribute
* @param iModeUpdate to enable mode update
* @param iListAtt list of attribute
*/
explicit SKGPredicatCreator(QWidget* iParent, SKGDocument* document, const QString& attribute = QString(),
bool iModeUpdate = false, const QStringList& iListAtt = QStringList());
/**
* Default Destructor
*/
~SKGPredicatCreator() override;
/**
* Get text
* @return text
*/
virtual QString text();
/**
* Get Text from XML description
* @param iXML the description
*/
static QString getTextFromXml(const QString& iXML);
/**
* Get XML description
* @return description
*/
virtual QString xmlDescription();
/**
* Set XML description
* @param iXML the description
*/
virtual void setXmlDescription(const QString& iXML);
Q_SIGNALS:
/**
* Sent when edition is finished
*/
void editingFinished();
/**
* Sent when edition changed
*/
void xmlDescriptionChanged();
protected :
/**
* Event filtering
* @param iObject object
* @param iEvent event
* @return In your reimplementation of this function, if you want to filter the event out, i.e. stop it being handled further, return true; otherwise return false.
*/
bool eventFilter(QObject* iObject, QEvent* iEvent) override;
private Q_SLOTS:
void onOperatorChanged();
private:
Q_DISABLE_COPY(SKGPredicatCreator)
bool m_updateMode;
SKGComboBox* m_kOperator;
QWidget* m_kValue1;
QWidget* m_kValue2;
SKGComboBox* m_kAttributes;
};
#endif // SKGPREDICATCREATOR_H
diff --git a/skgbankgui/skgquerycreator.cpp b/skgbankgui/skgquerycreator.cpp
index d15e045f5..66109e60e 100644
--- a/skgbankgui/skgquerycreator.cpp
+++ b/skgbankgui/skgquerycreator.cpp
@@ -1,538 +1,538 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is a query creator for skrooge
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgquerycreator.h"
#include <qdom.h>
#include <qheaderview.h>
#include <qmenu.h>
#include "skgdocument.h"
#include "skgpredicatcreator.h"
#include "skgquerydelegate.h"
#include "skgruleobject.h"
#include "skgservices.h"
#define ADDOPERATOR(title, op) \
{ \
QAction* act = helpMenu->addAction(title); \
act->setData(op); \
connect(act, &QAction::triggered, this, &SKGQueryCreator::onAddText); \
}
SKGQueryCreator::SKGQueryCreator(QWidget* iParent)
: QWidget(iParent), m_document(nullptr), m_updateMode(false)
{
ui.setupUi(this);
ui.kList->horizontalHeader()->setSectionResizeMode(QHeaderView::Interactive);
ui.kList->verticalHeader()->setSectionResizeMode(QHeaderView::Fixed);
ui.kList->setWordWrap(false);
ui.kList->horizontalHeader()->setSectionsMovable(true);
ui.kToolHelp->setIcon(SKGServices::fromTheme(QStringLiteral("dialog-information")));
ui.kCheckMode->setIcon(SKGServices::fromTheme(QStringLiteral("arrow-down")));
ui.kCheckMode->setToolTip(i18nc("A tool tip", "Switch in advanced mode"));
connect(ui.kFilterEdit, &QLineEdit::textChanged, this, &SKGQueryCreator::onTextFilterChanged);
connect(ui.kCheckMode, &QToolButton::clicked, this, &SKGQueryCreator::switchAdvancedSearchMode);
connect(ui.kList, &SKGTableWidget::removeLine, this, &SKGQueryCreator::removeLine);
connect(ui.kFilterEdit, &QLineEdit::returnPressed, this, &SKGQueryCreator::search);
connect(ui.kListAtt, &QListWidget::doubleClicked, this, &SKGQueryCreator::onAddColumn);
addNewLine();
onTextFilterChanged(QLatin1String(""));
}
SKGQueryCreator::~SKGQueryCreator()
{
m_document = nullptr;
}
void SKGQueryCreator::onTextFilterChanged(const QString& iFilter)
{
auto tooltip = i18nc("Tooltip", "<html><head/><body><p>Searching is case-insensitive. So table, Table, and TABLE are all the same.<br/>"
"If you just put a word or series of words in the search box, the application will filter the table to keep all lines having these words (logical operator AND). <br/>"
"If you want to add (logical operator OR) some lines, you must prefix your word by '+'.<br/>"
"If you want to remove (logical operator NOT) some lines, you must prefix your word by '-'.<br/>"
"If you want to search only on some columns, you must prefix your word by the beginning of column name like: col1:word.<br/>"
"If you want to search only on one column, you must prefix your word by the column name and a dot like: col1.:word.<br/>"
"If you want to use the character ':' in value, you must specify the column name like this: col1:value:rest.<br/>"
"If you want to search for a phrase or something that contains spaces, you must put it in quotes, like: 'yes, this is a phrase'.</p>"
"<p>You can also use operators '&lt;', '&gt;', '&lt;=', '&gt;=', '=' and '#' (for regular expression).</p>"
"<p><span style=\"font-weight:600; text-decoration: underline;\">Examples:</span><br/>"
"+val1 +val2 =&gt; Keep lines containing val1 OR val2<br/>"
"+val1 -val2 =&gt; Keep lines containing val1 but NOT val2<br/>"
"'abc def' =&gt; Keep lines containing the sentence 'abc def' <br/>"
"'-att:abc def' =&gt; Remove lines having a column name starting by abc and containing 'abc def' <br/>"
"abc:def =&gt; Keep lines having a column name starting by abc and containing def<br/>"
":abc:def =&gt; Keep lines containing 'abc:def'<br/>"
"Date&gt;2015-03-01 =&gt; Keep lines where at least one attribute starting by Date is greater than 2015-03-01<br/>"
"Date.&gt;2015-03-01 =&gt; Keep lines where at the Date attribute is greater than 2015-03-01<br/>"
"Amount&lt;10 =&gt;Keep lines where at least one attribute starting by Amount is less than 10<br/>"
"Amount=10 =&gt;Keep lines where at least one attribute starting by Amount is equal to 10<br/>"
"Amount&lt;=10 =&gt;Keep lines where at least one attribute starting by Amount is less or equal to 10<br/>"
"abc#^d.*f$ =&gt; Keep lines having a column name starting by abc and matching the regular expression ^d.*f$</p>"
"<span style=\"font-weight:600; text-decoration: underline;\">Your filter is understood like this:</span><br/>"
"%1</body></html>", SKGServices::searchCriteriasToWhereClause(SKGServices::stringToSearchCriterias(iFilter), m_attributes, m_document, true));
ui.kFilterEdit->setToolTip(tooltip);
}
bool SKGQueryCreator::advancedSearchMode() const
{
return (!ui.kFilterEdit->isVisible());
}
void SKGQueryCreator::setAdvancedSearchMode(bool iAdvancedMode) const
{
if (iAdvancedMode) {
ui.kToolHelp->hide();
ui.kFrmAdvanced->show();
ui.kFilterEdit->hide();
ui.kCheckMode->setIcon(SKGServices::fromTheme(QStringLiteral("arrow-up")));
ui.kCheckMode->setToolTip(i18nc("A tool tip", "Switch in simple mode"));
} else {
ui.kToolHelp->show();
ui.kFrmAdvanced->hide();
ui.kFilterEdit->show();
ui.kCheckMode->setIcon(SKGServices::fromTheme(QStringLiteral("arrow-down")));
ui.kCheckMode->setToolTip(i18nc("A tool tip", "Switch in advanced mode"));
}
}
void SKGQueryCreator::switchAdvancedSearchMode() const
{
setAdvancedSearchMode(!advancedSearchMode());
}
void SKGQueryCreator::setParameters(SKGDocument* iDocument, const QString& iTable, const QStringList& iListAttribute, bool iModeUpdate)
{
m_document = iDocument;
m_table = iTable;
m_updateMode = iModeUpdate;
m_attributes = iListAttribute;
setAdvancedSearchMode(m_updateMode);
ui.kCheckMode->setVisible(!m_updateMode);
// QString txt=(updateMode ? i18nc("Description", "Double click on a field name to add it to your modification definition.") : i18nc("Description", "Double click on a field name to add it to your search definition."))+'\n'+i18nc("Description", "Double click on a cell to modify it.");
// ui.kLabel->setComment ( "<html><body><b>"+SKGServices::stringToHtml ( txt ) +"</b></body></html>" );
// ui.kLabel->setPixmap ( SKGServices::fromTheme( updateMode ? "view-refresh" :"edit-find" ).pixmap ( 22, 22 ), KTitleWidget::ImageLeft );
// Build list of attributes
if (m_document != nullptr) {
auto delegate = new SKGQueryDelegate(ui.kList, m_document, m_updateMode, iListAttribute);
connect(delegate, &SKGQueryDelegate::commitData, this, &SKGQueryCreator::onCloseEditor, Qt::QueuedConnection);
ui.kList->setItemDelegate(delegate);
// Keep only existing attribute
SKGServices::SKGAttributesList listAtts;
int nb = iListAttribute.count();
SKGServices::SKGAttributesList attributes;
m_document->getAttributesDescription(m_table, attributes);
listAtts.reserve(nb + attributes.count());
for (const auto& att : qAsConst(attributes)) {
if (iListAttribute.isEmpty() || iListAttribute.contains(att.name)) {
listAtts.push_back(att);
}
}
// Adding properties
for (int i = 0; i < nb; ++i) {
const QString& att = iListAttribute.at(i);
if (att.startsWith(QLatin1String("p_"))) {
SKGServices::SKGAttributeInfo info;
info.name = att;
info.display = att.right(att.length() - 2);
info.type = SKGServices::TEXT;
info.icon = iDocument->getIcon(att);
listAtts.push_back(info);
}
}
ui.kList->setRowCount(0);
// Build list of attributes
QMenu* helpMenu = nullptr;
if (!iModeUpdate) {
helpMenu = new QMenu(this);
{
QAction* act = helpMenu->addAction(i18nc("Operator contains", "or"));
act->setData(QStringLiteral(" +"));
connect(act, &QAction::triggered, this, &SKGQueryCreator::onAddText);
}
{
QAction* act = helpMenu->addAction(i18nc("Operator contains", "but not"));
act->setData(QStringLiteral(" -"));
connect(act, &QAction::triggered, this, &SKGQueryCreator::onAddText);
}
helpMenu->addSeparator();
}
int nbCol = listAtts.count();
for (int i = 0; i < nbCol; ++i) {
auto listItem = new QListWidgetItem(listAtts.at(i).icon, listAtts.at(i).display);
ui.kListAtt->addItem(listItem);
listItem->setData(Qt::UserRole, listAtts.at(i).name);
if (helpMenu != nullptr) {
QAction* act = helpMenu->addAction(listAtts.at(i).icon, listAtts.at(i).display);
act->setData(listAtts.at(i).display);
connect(act, &QAction::triggered, this, &SKGQueryCreator::onAddText);
}
}
ui.kListAtt->sortItems();
ui.kListAtt->setModelColumn(nbCol);
if (helpMenu != nullptr) {
helpMenu->addSeparator();
{
QAction* act = helpMenu->addAction(i18nc("Operator contains", "Contains"));
act->setData(QStringLiteral(":"));
connect(act, &QAction::triggered, this, &SKGQueryCreator::onAddText);
}
ADDOPERATOR(QStringLiteral("="), QStringLiteral("="))
ADDOPERATOR(i18nc("Noun", "Regular expression"), QStringLiteral("#"))
ADDOPERATOR(QStringLiteral(">"), QStringLiteral(">"))
ADDOPERATOR(QStringLiteral("<"), QStringLiteral("<"))
ADDOPERATOR(QStringLiteral(">="), QStringLiteral(">="))
ADDOPERATOR(QStringLiteral("<="), QStringLiteral("<="))
ui.kToolHelp->setMenu(helpMenu);
}
connect(ui.kList->verticalHeader(), &QHeaderView::sectionClicked, this, &SKGQueryCreator::removeLine);
connect(ui.kList->horizontalHeader(), &QHeaderView::sectionClicked, this, &SKGQueryCreator::removeColumn);
addNewLine();
}
}
int SKGQueryCreator::getIndexQueryColumn(const QString& iAttribute, int row)
{
// Search column for this attribute
int output = -1;
int nbCol = ui.kList->columnCount();
for (int i = 0; i < nbCol && output == -1; ++i) {
QTableWidgetItem* it_h = ui.kList->horizontalHeaderItem(i);
if ((it_h != nullptr) && iAttribute == it_h->data(Qt::UserRole).toString()) {
if (row >= 0) {
// Check if the cell is empty
QTableWidgetItem* it = ui.kList->item(row, i);
if (it != nullptr) {
if (it->text().isEmpty()) {
output = i;
}
}
} else {
output = i;
}
}
}
// If not existing, we have to create it
if (output == -1) {
int nb = ui.kListAtt->count();
for (int i = 0; i < nb; ++i) {
QListWidgetItem* it = ui.kListAtt->item(i);
if ((it != nullptr) && iAttribute == it->data(Qt::UserRole).toString()) {
addColumnFromAttribut(it);
output = nbCol;
break;
}
}
}
return output;
}
void SKGQueryCreator::clearContents()
{
ui.kList->clearContents();
ui.kList->setRowCount(0);
addNewLine();
}
void SKGQueryCreator::setXMLCondition(const QString& iXML)
{
QDomDocument doc(QStringLiteral("SKGML"));
doc.setContent(iXML);
QDomElement root = doc.documentElement();
ui.kList->clearContents();
ui.kList->setRowCount(0);
ui.kList->setColumnCount(0);
if (root.tagName() == QStringLiteral("element")) {
// Mode advanced
setAdvancedSearchMode(true);
int row = -1;
QDomNode l = root.firstChild();
while (!l.isNull()) {
QDomElement elementl = l.toElement();
if (!elementl.isNull()) {
// Add new line
addNewLine();
++row;
QDomNode n = elementl.firstChild();
while (!n.isNull()) {
QDomElement element = n.toElement();
if (!element.isNull()) {
QString attribute = element.attribute(QStringLiteral("attribute"));
int idx = getIndexQueryColumn(attribute, row);
if (idx >= 0) {
QDomDocument doc2(QStringLiteral("SKGML"));
QDomElement root2 = doc2.createElement(QStringLiteral("element"));
doc2.appendChild(root2);
root2.setAttribute(QStringLiteral("operator"), element.attribute(QStringLiteral("operator")));
root2.setAttribute(QStringLiteral("value"), element.attribute(QStringLiteral("value")));
root2.setAttribute(QStringLiteral("value2"), element.attribute(QStringLiteral("value2")));
root2.setAttribute(QStringLiteral("att2"), element.attribute(QStringLiteral("att2")));
root2.setAttribute(QStringLiteral("att2s"), element.attribute(QStringLiteral("att2s")));
QTableWidgetItem* it = ui.kList->item(row, idx);
if (it != nullptr) {
QString xml = doc2.toString();
it->setText(SKGPredicatCreator::getTextFromXml(xml));
it->setData(Qt::UserRole, xml);
}
}
}
n = n.nextSibling();
}
}
l = l.nextSibling();
}
addNewLine();
} else {
// Mode simple
setAdvancedSearchMode(false);
ui.kFilterEdit->setText(root.attribute(QStringLiteral("query")));
}
}
QString SKGQueryCreator::getXMLCondition()
{
QString output;
if (advancedSearchMode()) {
// Mode advanced
QHeaderView* hHeader = ui.kList->horizontalHeader();
if (hHeader != nullptr) {
QDomDocument doc(QStringLiteral("SKGML"));
QDomElement element = doc.createElement(QStringLiteral("element"));
doc.appendChild(element);
element.appendChild(doc.createComment(QStringLiteral("OR")));
bool empty = true;
int nbRow = ui.kList->rowCount();
int nbCol = hHeader->count();
for (int j = 0; j < nbRow; ++j) {
QDomElement elementLine = doc.createElement(QStringLiteral("element"));
element.appendChild(elementLine);
elementLine.appendChild(doc.createComment(QStringLiteral("AND")));
bool atLeastOne = false;
for (int i = 0; i < nbCol; ++i) {
int iRealPos = hHeader->logicalIndex(i);
QTableWidgetItem* it = ui.kList->item(j, iRealPos);
if (it != nullptr) {
QString co = it->data(Qt::UserRole).toString();
if (!co.isEmpty()) {
QDomElement elementElement = doc.createElement(QStringLiteral("element"));
elementLine.appendChild(elementElement);
QTableWidgetItem* it_h = ui.kList->horizontalHeaderItem(iRealPos);
QString attname = it_h->data(Qt::UserRole).toString();
QDomDocument doc2(QStringLiteral("SKGML"));
doc2.setContent(co);
QDomElement root2 = doc2.documentElement();
elementElement.setAttribute(QStringLiteral("attribute"), attname);
elementElement.setAttribute(QStringLiteral("operator"), root2.attribute(QStringLiteral("operator")));
if (root2.hasAttribute(QStringLiteral("value"))) {
elementElement.setAttribute(QStringLiteral("value"), root2.attribute(QStringLiteral("value")));
}
if (root2.hasAttribute(QStringLiteral("value2"))) {
elementElement.setAttribute(QStringLiteral("value2"), root2.attribute(QStringLiteral("value2")));
}
if (root2.hasAttribute(QStringLiteral("att2"))) {
elementElement.setAttribute(QStringLiteral("att2"), root2.attribute(QStringLiteral("att2")));
}
if (root2.hasAttribute(QStringLiteral("att2s"))) {
elementElement.setAttribute(QStringLiteral("att2s"), root2.attribute(QStringLiteral("att2s")));
}
atLeastOne = true;
empty = false;
}
}
}
if (!atLeastOne) {
element.removeChild(elementLine);
}
}
if (!empty) {
output = doc.toString();
}
}
} else {
// Mode simple
QDomDocument doc(QStringLiteral("SKGML"));
QDomElement element = doc.createElement(QStringLiteral("simple"));
element.setAttribute(QStringLiteral("query"), ui.kFilterEdit->text());
element.setAttribute(QStringLiteral("sql"), SKGServices::searchCriteriasToWhereClause(SKGServices::stringToSearchCriterias(ui.kFilterEdit->text()), m_attributes, m_document));
doc.appendChild(element);
output = doc.toString();
}
return output;
}
void SKGQueryCreator::onCloseEditor()
{
// If all lignes have at least one value then add a new line
bool lineEmpty = false;
int nbCol = ui.kList->columnCount();
int nbRow = ui.kList->rowCount();
for (int j = 0; !lineEmpty && j < nbRow; ++j) {
lineEmpty = true;
for (int i = 0; lineEmpty && i < nbCol; ++i) {
QTableWidgetItem* it = ui.kList->item(j, i);
if ((it != nullptr) && !it->text().isEmpty()) {
lineEmpty = false;
}
}
}
if (!lineEmpty) {
addNewLine();
}
resizeColumns();
}
void SKGQueryCreator::onAddText()
{
auto* act = qobject_cast< QAction* >(sender());
if (act != nullptr) {
ui.kFilterEdit->insert(act->data().toString());
}
}
void SKGQueryCreator::onAddColumn()
{
QList<QListWidgetItem*> selection = ui.kListAtt->selectedItems();
if (selection.count() == 1) {
QListWidgetItem* listItem = selection.at(0);
addColumnFromAttribut(listItem);
}
}
void SKGQueryCreator::addColumnFromAttribut(const QListWidgetItem* iListItem)
{
if (iListItem != nullptr) {
bool previous = ui.kList->blockSignals(true);
int nb = ui.kList->columnCount();
ui.kList->setColumnCount(nb + 1);
// Create header
auto item = new QTableWidgetItem(iListItem->icon(), iListItem->text());
item->setData(Qt::UserRole, iListItem->data(Qt::UserRole));
ui.kList->setHorizontalHeaderItem(nb, item);
// Create items
int nbRows = ui.kList->rowCount();
for (int i = 0; i < nbRows; ++i) {
ui.kList->setItem(i, nb, new QTableWidgetItem());
}
ui.kList->blockSignals(previous);
resizeColumns();
}
}
void SKGQueryCreator::addNewLine()
{
// add line is only for
if (!m_updateMode || ui.kList->rowCount() < 1) {
bool previous = ui.kList->blockSignals(true);
int nbCol = ui.kList->columnCount();
int row = ui.kList->rowCount();
ui.kList->insertRow(row);
// Add a delete icon
if (!m_updateMode) {
ui.kList->setVerticalHeaderItem(row, new QTableWidgetItem(SKGServices::fromTheme(QStringLiteral("edit-delete")), QLatin1String("")));
}
for (int i = 0; i < nbCol; ++i) {
auto item = new QTableWidgetItem();
ui.kList->setItem(row, i, item);
}
ui.kList->blockSignals(previous);
resizeColumns();
}
}
int SKGQueryCreator::getColumnsCount()
{
return ui.kList->horizontalHeader()->count();
}
int SKGQueryCreator::getLinesCount()
{
return ui.kList->rowCount();
}
void SKGQueryCreator::removeColumn(int iColumn)
{
ui.kList->removeColumn(iColumn);
// To be sure that we have at least an empty line
onCloseEditor();
}
void SKGQueryCreator::removeLine(int iRow)
{
ui.kList->removeRow(iRow);
// To be sure that we have at least an empty line
onCloseEditor();
}
void SKGQueryCreator::resizeColumns()
{
ui.kList->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
qApp->processEvents(QEventLoop::AllEvents, 300);
ui.kList->horizontalHeader()->setSectionResizeMode(QHeaderView::Interactive);
}
diff --git a/skgbankgui/skgquerycreator.h b/skgbankgui/skgquerycreator.h
index c0b78e855..b869b6d4f 100644
--- a/skgbankgui/skgquerycreator.h
+++ b/skgbankgui/skgquerycreator.h
@@ -1,149 +1,149 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGQUERYCREATOR_H
#define SKGQUERYCREATOR_H
/** @file
* A query creator for skrooge.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include <qwidget.h>
#include "skgbankgui_export.h"
#include "ui_skgquerycreator.h"
class SKGDocument;
/**
* This file is a query creator for skrooge
*/
class SKGBANKGUI_EXPORT SKGQueryCreator : public QWidget
{
Q_OBJECT
public:
/**
* Default Constructor
* @param iParent the parent
*/
explicit SKGQueryCreator(QWidget* iParent);
/**
* Default Destructor
*/
~SKGQueryCreator() override;
/**
* Set parameters
* @param iDocument the document
* @param iTable the table
* @param iListAttribute the list of attribute (empty means all attributes supported of the table)
* @param iModeUpdate to enable update mode
*/
void setParameters(SKGDocument* iDocument, const QString& iTable, const QStringList& iListAttribute = QStringList(), bool iModeUpdate = false);
/**
* Set XML representing the query
* @param iXML the XML representing the query
*/
void setXMLCondition(const QString& iXML);
/**
* Get XML representing the query
* @return the XML representing the query
*/
QString getXMLCondition();
/**
* Get the number of line
* @return the number of line
*/
int getLinesCount();
/**
* Get the number of line
* @return the number of line
*/
int getColumnsCount();
/**
* Get the advanced search mode
*/
bool advancedSearchMode() const;
public Q_SLOTS:
/**
* Clear table content
*/
void clearContents();
/**
* Remove a line
* @param iRow the index of the line (-1 for all)
*/
void removeLine(int iRow = -1);
/**
* Remove a column
* @param iColumn the index of the column
*/
void removeColumn(int iColumn);
/**
* Add a new line
*/
void addNewLine();
/**
* Set/unset the advanced search mode
* @param iAdvancedMode the mode
*/
void setAdvancedSearchMode(bool iAdvancedMode) const;
/**
* Switch the advanced search mode
*/
void switchAdvancedSearchMode() const;
Q_SIGNALS:
/**
* Emitted when the search is triggered
*/
void search();
private Q_SLOTS:
void onCloseEditor();
void onAddColumn();
void onAddText();
void onTextFilterChanged(const QString& iFilter);
private:
Q_DISABLE_COPY(SKGQueryCreator)
int getIndexQueryColumn(const QString& iAttribute, int row = -1);
void addColumnFromAttribut(const QListWidgetItem* iListItem);
void resizeColumns();
Ui::skgquerycreator_base ui{};
SKGDocument* m_document;
QString m_table;
bool m_updateMode;
QStringList m_attributes;
};
#endif // SKGQUERYCREATOR_H
diff --git a/skgbankgui/skgquerydelegate.cpp b/skgbankgui/skgquerydelegate.cpp
index d4a1012e3..b04c8f86c 100644
--- a/skgbankgui/skgquerydelegate.cpp
+++ b/skgbankgui/skgquerydelegate.cpp
@@ -1,89 +1,89 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This is a delegate for query creator
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgquerydelegate.h"
#include <qpainter.h>
#include <qtablewidget.h>
#include "skgmainpanel.h"
#include "skgpredicatcreator.h"
#include "skgtraces.h"
SKGQueryDelegate::SKGQueryDelegate(QObject* iParent, SKGDocument* iDoc, bool iModeUpdate, QStringList iListAtt):
QItemDelegate(iParent), m_document(iDoc), m_updateMode(iModeUpdate), m_listAtt(std::move(iListAtt))
{
}
SKGQueryDelegate::~SKGQueryDelegate()
{
m_document = nullptr;
}
QWidget* SKGQueryDelegate::createEditor(QWidget* iParent,
const QStyleOptionViewItem& option,
const QModelIndex& index) const
{
SKGTRACEINFUNC(1)
Q_UNUSED(option)
QTableWidgetItem* it_h = (qobject_cast<QTableWidget*>(this->parent()))->horizontalHeaderItem(index.column());
QString attname = it_h->data(Qt::UserRole).toString();
auto editor = new SKGPredicatCreator(iParent, m_document, attname, m_updateMode, m_listAtt);
connect(editor, &SKGPredicatCreator::editingFinished, this, &SKGQueryDelegate::commitAndCloseEditor);
return editor;
}
void SKGQueryDelegate::setEditorData(QWidget* editor, const QModelIndex& index) const
{
SKGTRACEINFUNC(1)
auto* pred = qobject_cast<SKGPredicatCreator*>(editor);
if (pred != nullptr) {
pred->setXmlDescription(index.model()->data(index, Qt::UserRole).toString());
} else {
QItemDelegate::setEditorData(editor, index);
}
}
void SKGQueryDelegate::setModelData(QWidget* editor, QAbstractItemModel* model,
const QModelIndex& index) const
{
SKGTRACEINFUNC(1)
auto* pred = qobject_cast<SKGPredicatCreator*>(editor);
if ((pred != nullptr) && (model != nullptr)) {
QString xml = pred->xmlDescription();
model->setData(index, pred->text(), Qt::DisplayRole);
model->setData(index, xml, Qt::UserRole);
} else {
QItemDelegate::setModelData(editor, model, index);
}
}
void SKGQueryDelegate::commitAndCloseEditor()
{
auto* editor = qobject_cast<SKGPredicatCreator*>(sender());
Q_EMIT commitData(editor);
Q_EMIT closeEditor(editor);
}
diff --git a/skgbankgui/skgquerydelegate.h b/skgbankgui/skgquerydelegate.h
index ed360551f..c9008c4d5 100644
--- a/skgbankgui/skgquerydelegate.h
+++ b/skgbankgui/skgquerydelegate.h
@@ -1,85 +1,85 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGQUERYDELEGATE_H
#define SKGQUERYDELEGATE_H
/** @file
* This is a delegate for query creator.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include <qitemdelegate.h>
#include "skgbankgui_export.h"
class SKGDocument;
/**
* This is a delegate for query creator
*/
class SKGBANKGUI_EXPORT SKGQueryDelegate : public QItemDelegate
{
Q_OBJECT
public:
/**
* Default Constructor
*/
explicit SKGQueryDelegate(QObject* iParent, SKGDocument* iDoc, bool iModeUpdate = false, QStringList iListAtt = QStringList());
/**
* Default Destructor
*/
~SKGQueryDelegate() override;
/**
* Returns the widget used to edit the item specified by index for editing.
* The parent widget and style option are used to control how the editor widget appears.
* @param iParent perant widget
* @param option options
* @param index index
* @return the widget
*/
QWidget* createEditor(QWidget* iParent,
const QStyleOptionViewItem& option,
const QModelIndex& index) const override;
/**
* Sets the data to be displayed and edited by the editor from the data model item specified by the model index.
* @param editor the editor
* @param index the index
*/
void setEditorData(QWidget* editor, const QModelIndex& index) const override;
/**
* Gets data from the editor widget and stores it in the specified model at the item inde
* @param editor the editor
* @param model the model
* @param index the index
*/
void setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const override;
private Q_SLOTS:
void commitAndCloseEditor();
private:
Q_DISABLE_COPY(SKGQueryDelegate)
SKGDocument* m_document;
bool m_updateMode;
QStringList m_listAtt;
};
#endif // SKGQUERYDELEGATE_H
diff --git a/skgbankgui/skgunitcombobox.cpp b/skgbankgui/skgunitcombobox.cpp
index 3532f43d0..46d06b3f3 100644
--- a/skgbankgui/skgunitcombobox.cpp
+++ b/skgbankgui/skgunitcombobox.cpp
@@ -1,112 +1,112 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file defines classes SKGUnitComboBox.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgunitcombobox.h"
#include <klocalizedstring.h>
#include "skgdocumentbank.h"
#include "skgmainpanel.h"
#include "skgunitvalueobject.h"
SKGUnitComboBox::SKGUnitComboBox(QWidget* iParent): SKGComboBox(iParent), m_document(nullptr), m_fillWhereClause(QStringLiteral("t_type!='I'"))
{
}
SKGUnitComboBox::~SKGUnitComboBox()
{
m_document = nullptr;
}
void SKGUnitComboBox::setDocument(SKGDocumentBank* iDocument)
{
m_document = iDocument;
connect(m_document, &SKGDocument::tableModified, this, &SKGUnitComboBox::dataModified);
dataModified(QLatin1String(""), 0);
}
void SKGUnitComboBox::setWhereClauseCondition(const QString& iCondition)
{
m_fillWhereClause = iCondition;
dataModified(QLatin1String(""), 0);
}
SKGUnitObject SKGUnitComboBox::getUnit()
{
SKGUnitObject unit(m_document);
QString unitName = text();
if ((m_document != nullptr) && !unitName.isEmpty()) {
SKGError err;
err = unit.setSymbol(unitName);
if (!unit.exist()) {
IFOKDO(err, unit.setName(unitName))
IFOKDO(err, unit.save())
SKGUnitValueObject unitVal;
IFOKDO(err, unit.addUnitValue(unitVal))
IFOKDO(err, unitVal.setDate(QDate::currentDate()))
IFOKDO(err, unitVal.setQuantity(1))
IFOKDO(err, unitVal.save())
IFOK(err) m_document->sendMessage(i18nc("An information message", "Unit '%1' has been created", text()), SKGDocument::Positive);
} else {
err = unit.load();
}
}
return unit;
}
void SKGUnitComboBox::setUnit(const SKGUnitObject& iUnit)
{
if (text() != iUnit.getSymbol()) {
setText(iUnit.getSymbol());
emit unitChanged();
}
}
void SKGUnitComboBox::refershList()
{
// Fill comboboxes
if (m_document != nullptr) {
SKGMainPanel::fillWithDistinctValue(QList<QWidget*>() << this, m_document, QStringLiteral("unit"), QStringLiteral("ifnull(t_symbol,t_name)"), m_fillWhereClause);
SKGServices::SKGUnitInfo primary = m_document->getPrimaryUnit();
if (!primary.Symbol.isEmpty()) {
this->setCurrentIndex(this->findText(primary.Symbol));
}
}
}
void SKGUnitComboBox::dataModified(const QString& iTableName, int iIdTransaction)
{
Q_UNUSED(iIdTransaction)
// Refresh widgets
if (m_document != nullptr) {
QSqlDatabase* db = m_document->getMainDatabase();
setEnabled(db != nullptr);
if (db != nullptr && (iTableName == QStringLiteral("unit") || iTableName.isEmpty())) {
refershList();
}
}
}
diff --git a/skgbankgui/skgunitcombobox.h b/skgbankgui/skgunitcombobox.h
index b0a6d8b62..24b9f685a 100644
--- a/skgbankgui/skgunitcombobox.h
+++ b/skgbankgui/skgunitcombobox.h
@@ -1,98 +1,98 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGUNITCOMBOBOX_H
#define SKGUNITCOMBOBOX_H
/** @file
* This file defines classes SKGUnitComboBox.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgbankgui_export.h"
#include "skgcombobox.h"
#include "skgunitobject.h"
class SKGDocumentBank;
/**
* This class is a unit
*/
class SKGBANKGUI_EXPORT SKGUnitComboBox : public SKGComboBox
{
Q_OBJECT
/**
* the current unit
*/
Q_PROPERTY(SKGUnitObject unit READ getUnit WRITE setUnit NOTIFY unitChanged)
public:
/**
* Default Constructor
* @param iParent the parent
*/
explicit SKGUnitComboBox(QWidget* iParent);
/**
* Default Destructor
*/
~SKGUnitComboBox() override;
/**
* Set the current document
* @param iDocument the current document
*/
virtual void setDocument(SKGDocumentBank* iDocument);
/**
* Set the condition to selection the list of units to display
* @param iCondition the condition (Default= "t_type!='I'")
*/
virtual void setWhereClauseCondition(const QString& iCondition);
/**
* Get the current unit
* The unit will be created if not existing
* @return the current unit
*/
virtual SKGUnitObject getUnit();
/**
* Set the current unit
* @param iUnit the current unit
*/
virtual void setUnit(const SKGUnitObject& iUnit);
public Q_SLOTS:
/**
* To refresh the list of the combo
*/
virtual void refershList();
Q_SIGNALS:
/**
* Emitted when the unit is changed
*/
void unitChanged();
private Q_SLOTS:
void dataModified(const QString& iTableName, int iIdTransaction);
private:
SKGDocumentBank* m_document;
QString m_fillWhereClause;
};
#endif // SKGUNITCOMBOBOX_H
diff --git a/skgbankguidesigner/CMakeLists.txt b/skgbankguidesigner/CMakeLists.txt
index bbffaaf6a..066b26e49 100644
--- a/skgbankguidesigner/CMakeLists.txt
+++ b/skgbankguidesigner/CMakeLists.txt
@@ -1,52 +1,52 @@
#***************************************************************************
#* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
#* *
#* 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 <http://www.gnu.org/licenses/> *
+#* along with this program. If not, see <https://www.gnu.org/licenses/> *
#***************************************************************************
MESSAGE( STATUS "..:: CMAKE SKGBANKGUIDESIGNER ::..")
PROJECT(SKGBANKGUI)
LINK_DIRECTORIES (${LIBRARY_OUTPUT_PATH})
IF(SKG_WEBENGINE)
MESSAGE( STATUS " Mode WebEngine")
ADD_DEFINITIONS(-DSKG_WEBENGINE=${SKG_WEBENGINE})
ENDIF(SKG_WEBENGINE)
SET(skgbankguidesigner_SRCS ${skgbankgui_SRCS}
skgquerycreatordesignerplugin.cpp
skgbkwidgetcollectiondesignerplugin.cpp
skgpredicatcreatordesignerplugin.cpp
skgunitcomboboxdesignerplugin.cpp
)
SET(LIBS Qt5::Designer skgbankgui)
IF(SKG_WEBENGINE)
SET(LIBS ${LIBS} Qt5::WebEngineWidgets)
ELSE(SKG_WEBENGINE)
SET(LIBS ${LIBS} Qt5::WebKitWidgets)
ENDIF(SKG_WEBENGINE)
ADD_LIBRARY(skgbankguidesigner SHARED ${skgbankguidesigner_SRCS})
TARGET_LINK_LIBRARIES(skgbankguidesigner LINK_PUBLIC ${LIBS})
GENERATE_EXPORT_HEADER(skgbankguidesigner BASE_NAME skgbankguidesigner)
########### install files ###############
IF(WIN32)
INSTALL(TARGETS skgbankguidesigner LIBRARY ARCHIVE DESTINATION ${PLUGIN_INSTALL_DIR}/designer )
ELSE(WIN32)
INSTALL(TARGETS skgbankguidesigner LIBRARY DESTINATION ${PLUGIN_INSTALL_DIR}/designer )
ENDIF(WIN32)
diff --git a/skgbankguidesigner/skgbkwidgetcollectiondesignerplugin.cpp b/skgbankguidesigner/skgbkwidgetcollectiondesignerplugin.cpp
index 592486381..48b31cda5 100644
--- a/skgbankguidesigner/skgbkwidgetcollectiondesignerplugin.cpp
+++ b/skgbankguidesigner/skgbkwidgetcollectiondesignerplugin.cpp
@@ -1,41 +1,41 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* A collection of widgets for skrooge (qt designer plugin).
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgbkwidgetcollectiondesignerplugin.h"
#include "skgpredicatcreatordesignerplugin.h"
#include "skgquerycreatordesignerplugin.h"
#include "skgunitcomboboxdesignerplugin.h"
SKGBKWidgetCollectionDesignerPlugin::SKGBKWidgetCollectionDesignerPlugin(QObject* iParent)
: QObject(iParent)
{
m_widgets.append(new SKGQueryCreatorDesignerPlugin(this));
m_widgets.append(new SKGPredicatCreatorDesignerPlugin(this));
m_widgets.append(new SKGUnitComboBoxDesignerPlugin(this));
}
QList<QDesignerCustomWidgetInterface*> SKGBKWidgetCollectionDesignerPlugin::customWidgets() const
{
return m_widgets;
}
diff --git a/skgbankguidesigner/skgbkwidgetcollectiondesignerplugin.h b/skgbankguidesigner/skgbkwidgetcollectiondesignerplugin.h
index 509f390ce..6a432130f 100644
--- a/skgbankguidesigner/skgbkwidgetcollectiondesignerplugin.h
+++ b/skgbankguidesigner/skgbkwidgetcollectiondesignerplugin.h
@@ -1,53 +1,53 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGBKWIDGETCOLLECTIONDESIGNERPLUGIN_H
#define SKGBKWIDGETCOLLECTIONDESIGNERPLUGIN_H
/** @file
* A collection of widgets for skrooge (qt designer plugin).
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include <customwidget.h>
#include "skgbankguidesigner_export.h"
/**
* QDesigner plugin collection
*/
class SKGBANKGUIDESIGNER_EXPORT SKGBKWidgetCollectionDesignerPlugin: public QObject, public QDesignerCustomWidgetCollectionInterface
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QDesignerCustomWidgetCollectionInterface")
Q_INTERFACES(QDesignerCustomWidgetCollectionInterface)
public:
/**
* Constructor
* @param iParent the parent
*/
explicit SKGBKWidgetCollectionDesignerPlugin(QObject* iParent = nullptr);
/**
* To get the list of widgets
* @return the list of widgets
*/
QList<QDesignerCustomWidgetInterface*> customWidgets() const override;
private:
QList<QDesignerCustomWidgetInterface*> m_widgets;
};
#endif // SKGBKWIDGETCOLLECTIONDESIGNERPLUGIN_H
diff --git a/skgbankguidesigner/skgpredicatcreatordesignerplugin.cpp b/skgbankguidesigner/skgpredicatcreatordesignerplugin.cpp
index f0c5a37fb..e538d0805 100644
--- a/skgbankguidesigner/skgpredicatcreatordesignerplugin.cpp
+++ b/skgbankguidesigner/skgpredicatcreatordesignerplugin.cpp
@@ -1,103 +1,103 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is a predicat creator for skrooge (qt designer plugin).
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgpredicatcreatordesignerplugin.h"
#include "skgpredicatcreator.h"
#include "skgservices.h"
SKGPredicatCreatorDesignerPlugin::SKGPredicatCreatorDesignerPlugin(QObject* iParent)
: QObject(iParent)
{
m_initialized = false;
}
void SKGPredicatCreatorDesignerPlugin::initialize(QDesignerFormEditorInterface* iCore)
{
Q_UNUSED(iCore)
if (m_initialized) {
return;
}
m_initialized = true;
}
bool SKGPredicatCreatorDesignerPlugin::isInitialized() const
{
return m_initialized;
}
QWidget* SKGPredicatCreatorDesignerPlugin::createWidget(QWidget* iParent)
{
return new SKGPredicatCreator(iParent, nullptr);
}
QString SKGPredicatCreatorDesignerPlugin::name() const
{
return QStringLiteral("SKGPredicatCreator");
}
QString SKGPredicatCreatorDesignerPlugin::group() const
{
return QStringLiteral("SKG Widgets");
}
QIcon SKGPredicatCreatorDesignerPlugin::icon() const
{
return SKGServices::fromTheme(QStringLiteral("skrooge.png"));
}
QString SKGPredicatCreatorDesignerPlugin::toolTip() const
{
return QStringLiteral("A predicat creator");
}
QString SKGPredicatCreatorDesignerPlugin::whatsThis() const
{
return QStringLiteral("A predicat creator");
}
bool SKGPredicatCreatorDesignerPlugin::isContainer() const
{
return false;
}
QString SKGPredicatCreatorDesignerPlugin::domXml() const
{
return QStringLiteral("<widget class=\"SKGPredicatCreator\" name=\"SKGPredicatCreator\">\n"
" <property name=\"geometry\">\n"
" <rect>\n"
" <x>0</x>\n"
" <y>0</y>\n"
" <width>100</width>\n"
" <height>100</height>\n"
" </rect>\n"
" </property>\n"
"</widget>\n");
}
QString SKGPredicatCreatorDesignerPlugin::includeFile() const
{
return QStringLiteral("skgpredicatcreator.h");
}
diff --git a/skgbankguidesigner/skgpredicatcreatordesignerplugin.h b/skgbankguidesigner/skgpredicatcreatordesignerplugin.h
index 33d009121..5ea2f54a6 100644
--- a/skgbankguidesigner/skgpredicatcreatordesignerplugin.h
+++ b/skgbankguidesigner/skgpredicatcreatordesignerplugin.h
@@ -1,112 +1,112 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGPREDICATCREATORDESIGNERPLUGIN_H
#define SKGPREDICATCREATORDESIGNERPLUGIN_H
/** @file
* This file is a predicat creator for skrooge (qt designer plugin).
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include <customwidget.h>
/**
* QDesigner plugin for SKGTableWithGraph
*/
class SKGPredicatCreatorDesignerPlugin : public QObject, public QDesignerCustomWidgetInterface
{
Q_OBJECT
Q_INTERFACES(QDesignerCustomWidgetInterface)
public:
/**
* Constructor
* @param iParent parent
*/
explicit SKGPredicatCreatorDesignerPlugin(QObject* iParent = nullptr);
/**
* To know if the component is a container
* @return true or false
*/
bool isContainer() const override;
/**
* To know if the component is initialized
* @return true or false
*/
bool isInitialized() const override;
/**
* To get the icon for this component
* @return the icon
*/
QIcon icon() const override;
/**
* To get the icon for this component
* @return
*/
QString domXml() const override;
/**
* To get the group for this component
* @return group
*/
QString group() const override;
/**
* To get the include file for this component
* @return the include file
*/
QString includeFile() const override;
/**
* To get the name for this component
* @return name
*/
QString name() const override;
/**
* To get the "tool tip" for this component
* @return the "tool tip"
*/
QString toolTip() const override;
/**
* To get the "whats this" for this component
* @return the "whats this"
*/
QString whatsThis() const override;
/**
* To get the widget representing the component
* @param iParent the parent of the widget
* @return the widget
*/
QWidget* createWidget(QWidget* iParent) override;
/**
* Initilialize the component
* @param iCore interface
*/
void initialize(QDesignerFormEditorInterface* iCore) override;
private:
bool m_initialized;
};
#endif
diff --git a/skgbankguidesigner/skgquerycreatordesignerplugin.cpp b/skgbankguidesigner/skgquerycreatordesignerplugin.cpp
index ab20ab04e..6ee5f6d9a 100644
--- a/skgbankguidesigner/skgquerycreatordesignerplugin.cpp
+++ b/skgbankguidesigner/skgquerycreatordesignerplugin.cpp
@@ -1,103 +1,103 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is a query creator for skrooge (qt designer plugin).
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgquerycreatordesignerplugin.h"
#include "skgquerycreator.h"
#include "skgservices.h"
SKGQueryCreatorDesignerPlugin::SKGQueryCreatorDesignerPlugin(QObject* iParent)
: QObject(iParent)
{
m_initialized = false;
}
void SKGQueryCreatorDesignerPlugin::initialize(QDesignerFormEditorInterface* iCore)
{
Q_UNUSED(iCore)
if (m_initialized) {
return;
}
m_initialized = true;
}
bool SKGQueryCreatorDesignerPlugin::isInitialized() const
{
return m_initialized;
}
QWidget* SKGQueryCreatorDesignerPlugin::createWidget(QWidget* iParent)
{
return new SKGQueryCreator(iParent);
}
QString SKGQueryCreatorDesignerPlugin::name() const
{
return QStringLiteral("SKGQueryCreator");
}
QString SKGQueryCreatorDesignerPlugin::group() const
{
return QStringLiteral("SKG Widgets");
}
QIcon SKGQueryCreatorDesignerPlugin::icon() const
{
return SKGServices::fromTheme(QStringLiteral("skrooge.png"));
}
QString SKGQueryCreatorDesignerPlugin::toolTip() const
{
return QStringLiteral("A query creator");
}
QString SKGQueryCreatorDesignerPlugin::whatsThis() const
{
return QStringLiteral("A query creator");
}
bool SKGQueryCreatorDesignerPlugin::isContainer() const
{
return false;
}
QString SKGQueryCreatorDesignerPlugin::domXml() const
{
return QStringLiteral("<widget class=\"SKGQueryCreator\" name=\"SKGQueryCreator\">\n"
" <property name=\"geometry\">\n"
" <rect>\n"
" <x>0</x>\n"
" <y>0</y>\n"
" <width>100</width>\n"
" <height>100</height>\n"
" </rect>\n"
" </property>\n"
"</widget>\n");
}
QString SKGQueryCreatorDesignerPlugin::includeFile() const
{
return QStringLiteral("skgquerycreator.h");
}
diff --git a/skgbankguidesigner/skgquerycreatordesignerplugin.h b/skgbankguidesigner/skgquerycreatordesignerplugin.h
index 13b6bfcb6..8d2b38c87 100644
--- a/skgbankguidesigner/skgquerycreatordesignerplugin.h
+++ b/skgbankguidesigner/skgquerycreatordesignerplugin.h
@@ -1,112 +1,112 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGQUERYCREATORDESIGNERPLUGIN_H
#define SKGQUERYCREATORDESIGNERPLUGIN_H
/** @file
* This file is a query creator for skrooge (qt designer plugin).
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include <customwidget.h>
/**
* QDesigner plugin for SKGTableWithGraph
*/
class SKGQueryCreatorDesignerPlugin : public QObject, public QDesignerCustomWidgetInterface
{
Q_OBJECT
Q_INTERFACES(QDesignerCustomWidgetInterface)
public:
/**
* Constructor
* @param iParent parent
*/
explicit SKGQueryCreatorDesignerPlugin(QObject* iParent = nullptr);
/**
* To know if the component is a container
* @return true or false
*/
bool isContainer() const override;
/**
* To know if the component is initialized
* @return true or false
*/
bool isInitialized() const override;
/**
* To get the icon for this component
* @return the icon
*/
QIcon icon() const override;
/**
* To get the icon for this component
* @return
*/
QString domXml() const override;
/**
* To get the group for this component
* @return group
*/
QString group() const override;
/**
* To get the include file for this component
* @return the include file
*/
QString includeFile() const override;
/**
* To get the name for this component
* @return name
*/
QString name() const override;
/**
* To get the "tool tip" for this component
* @return the "tool tip"
*/
QString toolTip() const override;
/**
* To get the "whats this" for this component
* @return the "whats this"
*/
QString whatsThis() const override;
/**
* To get the widget representing the component
* @param iParent the parent of the widget
* @return the widget
*/
QWidget* createWidget(QWidget* iParent) override;
/**
* Initilialize the component
* @param iCore interface
*/
void initialize(QDesignerFormEditorInterface* iCore) override;
private:
bool m_initialized;
};
#endif
diff --git a/skgbankguidesigner/skgunitcomboboxdesignerplugin.cpp b/skgbankguidesigner/skgunitcomboboxdesignerplugin.cpp
index ccf192917..f4f952073 100644
--- a/skgbankguidesigner/skgunitcomboboxdesignerplugin.cpp
+++ b/skgbankguidesigner/skgunitcomboboxdesignerplugin.cpp
@@ -1,104 +1,104 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is a predicat creator for skrooge (qt designer plugin).
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgunitcomboboxdesignerplugin.h"
#include <qicon.h>
#include "skgunitcombobox.h"
SKGUnitComboBoxDesignerPlugin::SKGUnitComboBoxDesignerPlugin(QObject* iParent)
: QObject(iParent)
{
m_initialized = false;
}
void SKGUnitComboBoxDesignerPlugin::initialize(QDesignerFormEditorInterface* iCore)
{
Q_UNUSED(iCore)
if (m_initialized) {
return;
}
m_initialized = true;
}
bool SKGUnitComboBoxDesignerPlugin::isInitialized() const
{
return m_initialized;
}
QWidget* SKGUnitComboBoxDesignerPlugin::createWidget(QWidget* iParent)
{
return new SKGUnitComboBox(iParent);
}
QString SKGUnitComboBoxDesignerPlugin::name() const
{
return QStringLiteral("SKGUnitComboBox");
}
QString SKGUnitComboBoxDesignerPlugin::group() const
{
return QStringLiteral("SKG Widgets");
}
QIcon SKGUnitComboBoxDesignerPlugin::icon() const
{
return SKGServices::fromTheme(QStringLiteral("skrooge.png"));
}
QString SKGUnitComboBoxDesignerPlugin::toolTip() const
{
return QStringLiteral("A unit combo box");
}
QString SKGUnitComboBoxDesignerPlugin::whatsThis() const
{
return QStringLiteral("A unit combo box");
}
bool SKGUnitComboBoxDesignerPlugin::isContainer() const
{
return false;
}
QString SKGUnitComboBoxDesignerPlugin::domXml() const
{
return QStringLiteral("<widget class=\"SKGUnitComboBox\" name=\"SKGUnitComboBox\">\n"
" <property name=\"geometry\">\n"
" <rect>\n"
" <x>0</x>\n"
" <y>0</y>\n"
" <width>100</width>\n"
" <height>100</height>\n"
" </rect>\n"
" </property>\n"
"</widget>\n");
}
QString SKGUnitComboBoxDesignerPlugin::includeFile() const
{
return QStringLiteral("skgunitcombobox.h");
}
diff --git a/skgbankguidesigner/skgunitcomboboxdesignerplugin.h b/skgbankguidesigner/skgunitcomboboxdesignerplugin.h
index f23ac92e2..88b329281 100644
--- a/skgbankguidesigner/skgunitcomboboxdesignerplugin.h
+++ b/skgbankguidesigner/skgunitcomboboxdesignerplugin.h
@@ -1,112 +1,112 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGUNITCOMBOBOXDESIGNERPLUGIN_H
#define SKGUNITCOMBOBOXDESIGNERPLUGIN_H
/** @file
* This file is a predicat creator for skrooge (qt designer plugin).
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include <customwidget.h>
/**
* QDesigner plugin for SKGTableWithGraph
*/
class SKGUnitComboBoxDesignerPlugin : public QObject, public QDesignerCustomWidgetInterface
{
Q_OBJECT
Q_INTERFACES(QDesignerCustomWidgetInterface)
public:
/**
* Constructor
* @param iParent parent
*/
explicit SKGUnitComboBoxDesignerPlugin(QObject* iParent = nullptr);
/**
* To know if the component is a container
* @return true or false
*/
bool isContainer() const override;
/**
* To know if the component is initialized
* @return true or false
*/
bool isInitialized() const override;
/**
* To get the icon for this component
* @return the icon
*/
QIcon icon() const override;
/**
* To get the icon for this component
* @return
*/
QString domXml() const override;
/**
* To get the group for this component
* @return group
*/
QString group() const override;
/**
* To get the include file for this component
* @return the include file
*/
QString includeFile() const override;
/**
* To get the name for this component
* @return name
*/
QString name() const override;
/**
* To get the "tool tip" for this component
* @return the "tool tip"
*/
QString toolTip() const override;
/**
* To get the "whats this" for this component
* @return the "whats this"
*/
QString whatsThis() const override;
/**
* To get the widget representing the component
* @param iParent the parent of the widget
* @return the widget
*/
QWidget* createWidget(QWidget* iParent) override;
/**
* Initilialize the component
* @param iCore interface
*/
void initialize(QDesignerFormEditorInterface* iCore) override;
private:
bool m_initialized;
};
#endif
diff --git a/skgbankmodeler/CMakeLists.txt b/skgbankmodeler/CMakeLists.txt
index 11277f583..6b030306f 100644
--- a/skgbankmodeler/CMakeLists.txt
+++ b/skgbankmodeler/CMakeLists.txt
@@ -1,62 +1,62 @@
#***************************************************************************
#* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
#* *
#* 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 <http://www.gnu.org/licenses/> *
+#* along with this program. If not, see <https://www.gnu.org/licenses/> *
#***************************************************************************
MESSAGE( STATUS "..:: CMAKE SKGBANKMODELER ::..")
PROJECT(SKGBANKMODELER)
LINK_DIRECTORIES (${LIBRARY_OUTPUT_PATH})
SET(skgbankmodeler_SRCS
skgbankobject.cpp
skgbudgetobject.cpp
skgbudgetruleobject.cpp
skgaccountobject.cpp
skgoperationobject.cpp
skgrecurrentoperationobject.cpp
skgtrackerobject.cpp
skgpayeeobject.cpp
skgsuboperationobject.cpp
skgcategoryobject.cpp
skgunitobject.cpp
skgunitvalueobject.cpp
skgruleobject.cpp
skginterestobject.cpp
skgdocumentbank.cpp
skgimportexportmanager.cpp
skgimportplugin.cpp
skgreportbank.cpp
)
#build a shared library
ADD_LIBRARY(skgbankmodeler SHARED ${skgbankmodeler_SRCS})
#need to link to some other libraries ? just add them here
TARGET_LINK_LIBRARIES(skgbankmodeler LINK_PUBLIC KF5::Parts Qt5::Xml skgbasemodeler)
SET_TARGET_PROPERTIES( skgbankmodeler PROPERTIES VERSION ${SKG_VERSION} SOVERSION ${SOVERSION} )
GENERATE_EXPORT_HEADER(skgbankmodeler BASE_NAME skgbankmodeler)
ADD_SUBDIRECTORY(currency)
########### install files ###############
INSTALL(TARGETS skgbankmodeler ${INSTALL_TARGETS_DEFAULT_ARGS} LIBRARY NAMELINK_SKIP)
INSTALL(FILES ${PROJECT_SOURCE_DIR}/org.kde.skrooge-import-plugin.desktop DESTINATION ${KDE_INSTALL_KSERVICETYPES5DIR})
INSTALL(FILES ${PROJECT_SOURCE_DIR}/org.kde.skrooge-source-plugin.desktop DESTINATION ${KDE_INSTALL_KSERVICETYPES5DIR})
INSTALL(DIRECTORY sources DESTINATION ${KDE_INSTALL_KSERVICES5DIR} FILES_MATCHING PATTERN "*.desktop")
INSTALL(PROGRAMS skrooge-yahoodl.py DESTINATION ${KDE_INSTALL_DATADIR}/skrooge)
INSTALL(PROGRAMS skrooge-coinmarketcap.py DESTINATION ${KDE_INSTALL_DATADIR}/skrooge)
INSTALL(PROGRAMS skrooge-ratesapi.py DESTINATION ${KDE_INSTALL_DATADIR}/skrooge)
diff --git a/skgbankmodeler/skgaccountobject.cpp b/skgbankmodeler/skgaccountobject.cpp
index 121c19bbe..0e45d9ba5 100644
--- a/skgbankmodeler/skgaccountobject.cpp
+++ b/skgbankmodeler/skgaccountobject.cpp
@@ -1,1076 +1,1076 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file implements classes SKGAccountObject.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgaccountobject.h"
#include <klocalizedstring.h>
#include "skgbankobject.h"
#include "skgdocumentbank.h"
#include "skginterestobject.h"
#include "skgoperationobject.h"
#include "skgpayeeobject.h"
#include "skgsuboperationobject.h"
#include "skgtraces.h"
#include "skgunitobject.h"
int factorial(int n)
{
return (n == 1 || n == 0) ? 1 : factorial(n - 1) * n;
}
SKGAccountObject::SKGAccountObject() : SKGAccountObject(nullptr, 0) {}
SKGAccountObject::SKGAccountObject(SKGDocument* iDocument, int iID) : SKGNamedObject(iDocument, QStringLiteral("v_account"), iID) {}
SKGAccountObject::~SKGAccountObject() = default;
SKGAccountObject::SKGAccountObject(const SKGAccountObject& iObject)
= default;
SKGAccountObject::SKGAccountObject(const SKGNamedObject& iObject)
: SKGNamedObject(iObject.getDocument(), QStringLiteral("v_account"), iObject.getID())
{
if (iObject.getRealTable() == QStringLiteral("account")) {
copyFrom(iObject);
} else {
*this = SKGNamedObject(iObject.getDocument(), QStringLiteral("v_account"), iObject.getID());
}
}
SKGAccountObject::SKGAccountObject(const SKGObjectBase& iObject)
{
if (iObject.getRealTable() == QStringLiteral("account")) {
copyFrom(iObject);
} else {
*this = SKGNamedObject(iObject.getDocument(), QStringLiteral("v_account"), iObject.getID());
}
}
SKGAccountObject& SKGAccountObject::operator= (const SKGObjectBase& iObject)
{
copyFrom(iObject);
return *this;
}
SKGError SKGAccountObject::setInitialBalance(double iBalance, const SKGUnitObject& iUnit)
{
SKGError err;
SKGTRACEINFUNCRC(10, err)
if (getDocument() != nullptr) {
// Delete previous initial balance for this account
err = getDocument()->executeSqliteOrder("DELETE FROM operation WHERE d_date='0000-00-00' AND rd_account_id=" % SKGServices::intToString(getID()));
// Creation of new initial balance
IFOK(err) {
SKGOperationObject initialBalanceOp;
err = addOperation(initialBalanceOp, true);
IFOKDO(err, initialBalanceOp.setAttribute(QStringLiteral("d_date"), QStringLiteral("0000-00-00")))
IFOKDO(err, initialBalanceOp.setUnit(iUnit))
IFOKDO(err, initialBalanceOp.setStatus(SKGOperationObject::CHECKED))
IFOKDO(err, initialBalanceOp.save())
SKGSubOperationObject initialBalanceSubOp;
IFOKDO(err, initialBalanceOp.addSubOperation(initialBalanceSubOp))
IFOKDO(err, initialBalanceSubOp.setAttribute(QStringLiteral("d_date"), QStringLiteral("0000-00-00")))
IFOKDO(err, initialBalanceSubOp.setQuantity(iBalance))
IFOKDO(err, initialBalanceSubOp.save())
}
}
return err;
}
SKGError SKGAccountObject::getInitialBalance(double& oBalance, SKGUnitObject& oUnit)
{
SKGError err;
SKGTRACEINFUNCRC(10, err)
// Initialisation
oBalance = 0;
oUnit = SKGUnitObject();
QString unitName = qobject_cast<SKGDocumentBank*>(getDocument())->getPrimaryUnit().Symbol;
// Get initial balance
SKGStringListList listTmp;
err = getDocument()->executeSelectSqliteOrder("SELECT f_QUANTITY, t_UNIT FROM v_operation_tmp1 WHERE d_date='0000-00-00' AND rd_account_id=" % SKGServices::intToString(getID()), listTmp);
if (!err && listTmp.count() > 1) {
oBalance = SKGServices::stringToDouble(listTmp.at(1).at(0));
unitName = listTmp.at(1).at(1);
oUnit = SKGUnitObject(getDocument());
err = oUnit.setSymbol(unitName);
IFOKDO(err, oUnit.load())
}
return err;
}
SKGError SKGAccountObject::setBank(const SKGBankObject& iBank)
{
return setAttribute(QStringLiteral("rd_bank_id"), SKGServices::intToString(iBank.getID()));
}
SKGError SKGAccountObject::getBank(SKGBankObject& oBank) const
{
SKGError err = getDocument()->getObject(QStringLiteral("v_bank"), "id=" % getAttribute(QStringLiteral("rd_bank_id")), oBank);
return err;
}
SKGError SKGAccountObject::setLinkedAccount(const SKGAccountObject& iAccount)
{
return setAttribute(QStringLiteral("r_account_id"), SKGServices::intToString(iAccount.getID()));
}
SKGError SKGAccountObject::getLinkedAccount(SKGAccountObject& oAccount) const
{
SKGError err = getDocument()->getObject(QStringLiteral("v_account"), "id=" % getAttribute(QStringLiteral("r_account_id")), oAccount);
return err;
}
SKGError SKGAccountObject::getLinkedByAccounts(SKGListSKGObjectBase& oAccounts) const
{
SKGError err;
if (getDocument() != nullptr) {
err = getDocument()->getObjects(QStringLiteral("v_account"),
"r_account_id=" % SKGServices::intToString(getID()),
oAccounts);
}
return err;
}
SKGError SKGAccountObject::setNumber(const QString& iNumber)
{
return setAttribute(QStringLiteral("t_number"), iNumber);
}
QString SKGAccountObject::getNumber() const
{
return getAttribute(QStringLiteral("t_number"));
}
SKGError SKGAccountObject::setComment(const QString& iComment)
{
return setAttribute(QStringLiteral("t_comment"), iComment);
}
QString SKGAccountObject::getComment() const
{
return getAttribute(QStringLiteral("t_comment"));
}
SKGError SKGAccountObject::setAgencyNumber(const QString& iNumber)
{
return setAttribute(QStringLiteral("t_agency_number"), iNumber);
}
QString SKGAccountObject::getAgencyNumber() const
{
return getAttribute(QStringLiteral("t_agency_number"));
}
SKGError SKGAccountObject::setAgencyAddress(const QString& iAddress)
{
return setAttribute(QStringLiteral("t_agency_address"), iAddress);
}
QString SKGAccountObject::getAgencyAddress() const
{
return getAttribute(QStringLiteral("t_agency_address"));
}
SKGError SKGAccountObject::addOperation(SKGOperationObject& oOperation, bool iForce)
{
SKGError err;
if (getID() == 0) {
err = SKGError(ERR_FAIL, i18nc("Error message", "%1 failed because linked object is not yet saved in the database.", QStringLiteral("SKGAccountObject::addOperation")));
} else {
oOperation = SKGOperationObject(getDocument());
err = oOperation.setParentAccount(*this, iForce);
}
return err;
}
int SKGAccountObject::getNbOperation() const
{
int nb = 0;
if (getDocument() != nullptr) {
getDocument()->getNbObjects(QStringLiteral("operation"), "rd_account_id=" % SKGServices::intToString(getID()), nb);
}
return nb;
}
SKGError SKGAccountObject::getOperations(SKGListSKGObjectBase& oOperations) const
{
SKGError err;
if (getDocument() != nullptr) {
err = getDocument()->getObjects(QStringLiteral("v_operation"),
"rd_account_id=" % SKGServices::intToString(getID()),
oOperations);
}
return err;
}
double SKGAccountObject::getCurrentAmount() const
{
return SKGServices::stringToDouble(getAttributeFromView(QStringLiteral("v_account_amount"), QStringLiteral("f_CURRENTAMOUNT")));
}
double SKGAccountObject::getAmount(QDate iDate, bool iOnlyCurrencies) const
{
SKGTRACEINFUNC(10)
double output = 0;
if (getDocument() != nullptr) {
// Search result in cache
QString ids = SKGServices::intToString(getID());
QString dates = SKGServices::dateToSqlString(QDateTime(iDate));
QString key = "getamount-" % ids % '-' % dates;
QString val = getDocument()->getCachedValue(key);
if (val.isEmpty()) {
SKGStringListList listTmp;
SKGError err = getDocument()->executeSelectSqliteOrder("SELECT TOTAL(f_QUANTITY), rc_unit_id FROM v_operation_tmp1 WHERE "
"d_date<='" % dates % "' AND t_template='N' AND rd_account_id=" % ids %
(iOnlyCurrencies ? " AND t_TYPEUNIT IN ('1', '2', 'C')" : "") %
" GROUP BY rc_unit_id",
listTmp);
int nb = listTmp.count();
for (int i = 1; !err && i < nb ; ++i) {
QString quantity = listTmp.at(i).at(0);
QString unitid = listTmp.at(i).at(1);
double coef = 1;
QString val2 = getDocument()->getCachedValue("unitvalue-" % unitid);
if (!val2.isEmpty()) {
// Yes
coef = SKGServices::stringToDouble(val2);
} else {
// No
SKGUnitObject unit(getDocument(), SKGServices::stringToInt(unitid));
if (unit.getType() != SKGUnitObject::PRIMARY) {
coef = unit.getAmount(iDate);
}
}
output += coef * SKGServices::stringToDouble(quantity);
}
getDocument()->addValueInCache(key, SKGServices::doubleToString(output));
} else {
output = SKGServices::stringToDouble(val);
}
}
return output;
}
SKGError SKGAccountObject::setType(SKGAccountObject::AccountType iType)
{
return setAttribute(QStringLiteral("t_type"), (iType == CURRENT ? QStringLiteral("C") :
(iType == CREDITCARD ? QStringLiteral("D") :
(iType == ASSETS ? QStringLiteral("A") :
(iType == INVESTMENT ? QStringLiteral("I") :
(iType == WALLET ? QStringLiteral("W") :
(iType == PENSION ? QStringLiteral("P") :
(iType == LOAN ? QStringLiteral("L") :
(iType == SAVING ? QStringLiteral("S") :
QStringLiteral("O"))))))))));
}
SKGAccountObject::AccountType SKGAccountObject::getType() const
{
QString typeString = getAttribute(QStringLiteral("t_type"));
return (typeString == QStringLiteral("C") ? CURRENT :
(typeString == QStringLiteral("D") ? CREDITCARD :
(typeString == QStringLiteral("A") ? ASSETS :
(typeString == QStringLiteral("I") ? INVESTMENT :
(typeString == QStringLiteral("W") ? WALLET :
(typeString == QStringLiteral("P") ? PENSION :
(typeString == QStringLiteral("L") ? LOAN :
(typeString == QStringLiteral("S") ? SAVING : OTHER))))))));
}
SKGError SKGAccountObject::setClosed(bool iClosed)
{
return setAttribute(QStringLiteral("t_close"), iClosed ? QStringLiteral("Y") : QStringLiteral("N"));
}
bool SKGAccountObject::isClosed() const
{
return (getAttribute(QStringLiteral("t_close")) == QStringLiteral("Y"));
}
SKGError SKGAccountObject::bookmark(bool iBookmark)
{
return setAttribute(QStringLiteral("t_bookmarked"), iBookmark ? QStringLiteral("Y") : QStringLiteral("N"));
}
bool SKGAccountObject::isBookmarked() const
{
return (getAttribute(QStringLiteral("t_bookmarked")) == QStringLiteral("Y"));
}
SKGError SKGAccountObject::maxLimitAmountEnabled(bool iEnabled)
{
return setAttribute(QStringLiteral("t_maxamount_enabled"), iEnabled ? QStringLiteral("Y") : QStringLiteral("N"));
}
bool SKGAccountObject::isMaxLimitAmountEnabled() const
{
return (getAttribute(QStringLiteral("t_maxamount_enabled")) == QStringLiteral("Y"));
}
SKGError SKGAccountObject::setMaxLimitAmount(double iAmount)
{
SKGError err = setAttribute(QStringLiteral("f_maxamount"), SKGServices::doubleToString(iAmount));
if (!err && getMinLimitAmount() > iAmount) {
err = setMinLimitAmount(iAmount);
}
return err;
}
double SKGAccountObject::getMaxLimitAmount() const
{
return SKGServices::stringToDouble(getAttribute(QStringLiteral("f_maxamount")));
}
SKGError SKGAccountObject::minLimitAmountEnabled(bool iEnabled)
{
return setAttribute(QStringLiteral("t_minamount_enabled"), iEnabled ? QStringLiteral("Y") : QStringLiteral("N"));
}
bool SKGAccountObject::isMinLimitAmountEnabled() const
{
return (getAttribute(QStringLiteral("t_minamount_enabled")) == QStringLiteral("Y"));
}
SKGError SKGAccountObject::setMinLimitAmount(double iAmount)
{
SKGError err = setAttribute(QStringLiteral("f_minamount"), SKGServices::doubleToString(iAmount));
if (!err && getMaxLimitAmount() < iAmount) {
err = setMaxLimitAmount(iAmount);
}
return err;
}
double SKGAccountObject::getMinLimitAmount() const
{
return SKGServices::stringToDouble(getAttribute(QStringLiteral("f_minamount")));
}
SKGError SKGAccountObject::setReconciliationDate(QDate iDate)
{
return setAttribute(QStringLiteral("d_reconciliationdate"), SKGServices::dateToSqlString(QDateTime(iDate)));
}
QDate SKGAccountObject::getReconciliationDate() const
{
return SKGServices::stringToTime(getAttribute(QStringLiteral("d_reconciliationdate"))).date();
}
SKGError SKGAccountObject::setReconciliationBalance(double iAmount)
{
return setAttribute(QStringLiteral("f_reconciliationbalance"), SKGServices::doubleToString(iAmount));
}
double SKGAccountObject::getReconciliationBalance() const
{
return SKGServices::stringToDouble(getAttribute(QStringLiteral("f_reconciliationbalance")));
}
SKGError SKGAccountObject::getUnit(SKGUnitObject& oUnit) const
{
// Get initial amount
SKGStringListList listTmp;
SKGError err = getDocument()->executeSelectSqliteOrder("SELECT t_UNIT FROM v_suboperation_consolidated WHERE d_date='0000-00-00' AND rd_account_id=" % SKGServices::intToString(getID()), listTmp);
IFOK(err) {
// Is initial amount existing ?
if (listTmp.count() > 1) {
// Yes ==> then the amount is the amount of the initial value
oUnit = SKGUnitObject(getDocument());
err = oUnit.setSymbol(listTmp.at(1).at(0));
IFOKDO(err, oUnit.load())
} else {
// No ==> we get the preferred unit
SKGObjectBase::SKGListSKGObjectBase units;
err = getDocument()->getObjects(QStringLiteral("v_unit"),
"t_type IN ('1', '2', 'C') AND EXISTS(SELECT 1 FROM operation WHERE rc_unit_id=v_unit.id AND rd_account_id=" % SKGServices::intToString(getID()) % ") ORDER BY t_type", units);
int nb = units.count();
if (nb != 0) {
oUnit = units.at(0);
}
}
}
return err;
}
SKGError SKGAccountObject::addInterest(SKGInterestObject& oInterest)
{
SKGError err;
if (getID() == 0) {
err = SKGError(ERR_FAIL, i18nc("Error message", "%1 failed because linked object is not yet saved in the database.", QStringLiteral("SKGAccountObject::addInterest")));
} else {
oInterest = SKGInterestObject(qobject_cast<SKGDocumentBank*>(getDocument()));
err = oInterest.setAccount(*this);
}
return err;
}
SKGError SKGAccountObject::getInterests(SKGListSKGObjectBase& oInterestList) const
{
SKGError err = getDocument()->getObjects(QStringLiteral("v_interest"),
"rd_account_id=" % SKGServices::intToString(getID()),
oInterestList);
return err;
}
SKGError SKGAccountObject::getInterest(QDate iDate, SKGInterestObject& oInterest) const
{
QString ids = SKGServices::intToString(getID());
QString dates = SKGServices::dateToSqlString(QDateTime(iDate));
SKGError err = SKGObjectBase::getDocument()->getObject(QStringLiteral("v_interest"),
"rd_account_id=" % ids % " AND d_date<='" % dates %
"' AND ABS(strftime('%s','" % dates %
"')-strftime('%s',d_date))=(SELECT MIN(ABS(strftime('%s','" % dates %
"')-strftime('%s',u2.d_date))) FROM interest u2 WHERE u2.rd_account_id=" % ids %
" AND u2.d_date<='" % dates % "')",
oInterest);
// If not found then get first
IFKO(err) err = SKGObjectBase::getDocument()->getObject(QStringLiteral("v_interest"),
"rd_account_id=" % SKGServices::intToString(getID()) % " AND d_date=(SELECT MIN(d_date) FROM interest WHERE rd_account_id=" %
SKGServices::intToString(getID()) % ')',
oInterest);
return err;
}
SKGError SKGAccountObject::getInterestItems(SKGAccountObject::SKGInterestItemList& oInterestList, double& oInterests, int iYear) const
{
oInterestList.clear();
SKGError err;
// Initial date
int y = iYear;
if (y == 0) {
y = QDate::currentDate().year();
}
QDate initialDate = QDate(y, 1, 1);
QDate lastDate = QDate(y, 12, 31);
oInterests = 0;
bool computationNeeded = false;
// Add operations
SKGObjectBase::SKGListSKGObjectBase items;
err = getDocument()->getObjects(QStringLiteral("v_operation"), "rd_account_id=" % SKGServices::intToString(getID()) %
" AND t_template='N' AND t_TYPEUNIT IN ('1', '2', 'C')"
" AND d_date>='" % SKGServices::dateToSqlString(QDateTime(initialDate)) % "' "
" AND d_date<='" % SKGServices::dateToSqlString(QDateTime(lastDate)) % "' ORDER BY d_date", items);
int nb = items.count();
for (int i = 0; !err && i < nb; ++i) {
SKGOperationObject ob(items.at(i));
SKGInterestItem itemI;
itemI.object = ob;
itemI.date = ob.getDate();
itemI.valueDate = itemI.date;
itemI.rate = 0;
itemI.base = 0;
itemI.coef = 0;
itemI.annualInterest = 0;
itemI.accruedInterest = 0;
itemI.amount = ob.getCurrentAmount();
oInterestList.push_back(itemI);
}
// Add interest
IFOK(err) {
err = getDocument()->getObjects(QStringLiteral("v_interest"), "rd_account_id=" % SKGServices::intToString(getID()) %
" AND d_date>='" % SKGServices::dateToSqlString(QDateTime(initialDate)) % "' "
" AND d_date<='" % SKGServices::dateToSqlString(QDateTime(lastDate)) % "' ORDER BY d_date", items);
int pos = 0;
int nb2 = items.count();
for (int i = 0; !err && i < nb2; ++i) {
SKGInterestObject ob(items.at(i));
SKGInterestItem itemI;
itemI.object = ob;
itemI.date = ob.getDate();
itemI.valueDate = itemI.date;
itemI.rate = ob.getRate();
itemI.base = SKGServices::stringToInt(ob.getAttribute(QStringLiteral("t_base")));
itemI.coef = 0;
itemI.annualInterest = 0;
itemI.accruedInterest = 0;
itemI.amount = 0;
int nb3 = oInterestList.count();
for (int j = pos; !err && j < nb3; ++j) {
if (itemI.date <= oInterestList.at(j).date) {
break;
}
++pos;
}
oInterestList.insert(pos, itemI);
computationNeeded = true;
}
}
// Get first interest
IFOK(err) {
SKGInterestObject firstInterest;
if (getInterest(initialDate, firstInterest).isSucceeded()) {
if (firstInterest.getDate() < initialDate) {
SKGInterestItem itemI;
itemI.object = firstInterest;
itemI.date = initialDate;
itemI.valueDate = initialDate;
itemI.rate = firstInterest.getRate();
itemI.base = 0;
itemI.coef = 0;
itemI.annualInterest = 0;
itemI.accruedInterest = 0;
itemI.amount = 0;
oInterestList.insert(0, itemI);
computationNeeded = true;
}
}
}
// Launch computation
IFOK(err) {
if (computationNeeded) {
err = computeInterestItems(oInterestList, oInterests, y);
} else {
// Drop temporary table
IFOKDO(err, getDocument()->executeSqliteOrder(QStringLiteral("DROP TABLE IF EXISTS interest_result")))
// Create fake table
IFOKDO(err, getDocument()->executeSqliteOrder(QStringLiteral("CREATE TEMP TABLE interest_result(a)")))
}
}
return err;
}
SKGError SKGAccountObject::computeInterestItems(SKGAccountObject::SKGInterestItemList& ioInterestList, double& oInterests, int iYear) const
{
SKGError err;
// Sum annual interest
oInterests = 0;
// Initial date
int y = iYear;
if (y == 0) {
y = QDate::currentDate().year();
}
QDate initialDate = QDate(y, 1, 1);
// Default interest item
SKGInterestItem currentInterest;
currentInterest.date = initialDate;
currentInterest.valueDate = currentInterest.date;
currentInterest.rate = 0;
currentInterest.coef = 0;
currentInterest.annualInterest = 0;
currentInterest.accruedInterest = 0;
int nb = ioInterestList.count();
for (int i = 0; !err && i < nb; ++i) {
SKGInterestItem tmp = ioInterestList.at(i);
SKGObjectBase object = tmp.object;
if (object.getRealTable() == QStringLiteral("operation")) {
// Get operations
SKGOperationObject op(object);
// Get current amount
tmp.amount = op.getCurrentAmount();
// Get value date computation mode
SKGInterestObject::ValueDateMode valueMode = SKGInterestObject::FIFTEEN;
SKGInterestObject::InterestMode baseMode = SKGInterestObject::FIFTEEN24;
if (currentInterest.object.getRealTable() == QStringLiteral("interest")) {
SKGInterestObject interestObj(currentInterest.object);
valueMode = (tmp.amount >= 0 ? interestObj.getIncomeValueDateMode() : interestObj.getExpenditueValueDateMode());
baseMode = interestObj.getInterestComputationMode();
tmp.rate = interestObj.getRate();
}
// Compute value date
if (object.getRealTable() == QStringLiteral("operation")) {
if (valueMode == SKGInterestObject::FIFTEEN) {
if (tmp.amount >= 0) {
if (tmp.date.day() <= 15) {
tmp.valueDate = tmp.date.addDays(16 - tmp.date.day());
} else {
tmp.valueDate = tmp.date.addMonths(1).addDays(1 - tmp.date.day());
}
} else {
if (tmp.date.day() <= 15) {
tmp.valueDate = tmp.date.addDays(1 - tmp.date.day());
} else {
tmp.valueDate = tmp.date.addDays(16 - tmp.date.day());
}
}
} else {
tmp.valueDate = tmp.date.addDays(tmp.amount >= 0 ? (static_cast<int>(valueMode)) - 1 : - (static_cast<int>(valueMode)) + 1);
}
}
// Compute coef
if (baseMode == SKGInterestObject::DAYS365) {
QDate last(tmp.date.year(), 12, 31);
tmp.coef = tmp.valueDate.daysTo(last) + 1;
tmp.coef /= 365;
} else if (baseMode == SKGInterestObject::DAYS360) {
QDate last(tmp.date.year(), 12, 31);
tmp.coef = 360 * (last.year() - tmp.valueDate.year()) + 30 * (last.month() - tmp.valueDate.month()) + (last.day() - tmp.valueDate.day());
tmp.coef /= 360;
} else {
tmp.coef = 2 * (12 - tmp.valueDate.month()) + (tmp.valueDate.day() <= 15 ? 2 : 1);
tmp.coef /= 24;
}
if (tmp.valueDate.year() != iYear) {
tmp.coef = 0;
}
// Compute annual interest
tmp.annualInterest = tmp.amount * tmp.coef * tmp.rate / 100;
} else if (object.getRealTable() == QStringLiteral("interest")) {
// Compute coef
if (tmp.base == 365) {
QDate last(tmp.date.year(), 12, 31);
tmp.coef = tmp.valueDate.daysTo(last) + 1;
tmp.coef /= 365;
} else if (tmp.base == 360) {
QDate last(tmp.date.year(), 12, 31);
tmp.coef = 360 * (last.year() - tmp.valueDate.year()) + 30 * (last.month() - tmp.valueDate.month()) + (last.day() - tmp.valueDate.day());
tmp.coef /= 360;
} else {
tmp.coef = 2 * (12 - tmp.valueDate.month()) + (tmp.valueDate.day() <= 15 ? 2 : 1);
tmp.coef /= 24;
}
if (tmp.valueDate.year() != iYear) {
tmp.coef = 0;
}
// Compute annual interest
// BUG 329568: We must ignore operations of the day
tmp.amount = getAmount(tmp.valueDate.addDays(-1), true);
tmp.annualInterest = tmp.amount * tmp.coef * (tmp.rate - currentInterest.rate) / 100;
currentInterest = tmp;
}
// Compute sum
oInterests += tmp.annualInterest;
// Compute accrued interest
tmp.accruedInterest = oInterests - getAmount(tmp.date, true) * tmp.coef * tmp.rate / 100;
ioInterestList[i] = tmp;
}
// Create temporary table
IFOK(err) {
QStringList sqlOrders;
sqlOrders << QStringLiteral("DROP TABLE IF EXISTS interest_result")
<< QStringLiteral("CREATE TEMP TABLE interest_result("
"id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,"
"d_date DATE NOT NULL,"
"d_valuedate DATE NOT NULL,"
"t_comment TEXT NOT NULL DEFAULT '',"
"f_currentamount FLOAT NOT NULL DEFAULT 0,"
"f_coef FLOAT NOT NULL DEFAULT 0,"
"f_rate FLOAT NOT NULL DEFAULT 0,"
"f_annual_interest FLOAT NOT NULL DEFAULT 0,"
"f_accrued_interest FLOAT NOT NULL DEFAULT 0"
")");
err = getDocument()->executeSqliteOrders(sqlOrders);
// Fill table
int nb2 = ioInterestList.count();
for (int i = 0; !err && i < nb2; ++i) {
SKGInterestItem interest = ioInterestList.at(i);
SKGObjectBase object = interest.object;
QString sqlinsert =
"INSERT INTO interest_result (d_date,d_valuedate,t_comment,f_currentamount,f_coef,f_rate,f_annual_interest,f_accrued_interest) "
" VALUES ('" % SKGServices::dateToSqlString(QDateTime(interest.date)) %
"','" % SKGServices::dateToSqlString(QDateTime(interest.valueDate)) %
"','" % SKGServices::stringToSqlString(object.getRealTable() == QStringLiteral("operation") ? i18nc("Noun", "Relative to operation '%1'", SKGOperationObject(object).getDisplayName()) : i18nc("Noun", "Rate change")) %
"'," % SKGServices::doubleToString(interest.amount) %
',' % SKGServices::doubleToString(interest.coef) %
',' % SKGServices::doubleToString(interest.rate) %
',' % SKGServices::doubleToString(interest.annualInterest) %
',' % SKGServices::doubleToString(interest.accruedInterest) %
")";
err = getDocument()->executeSqliteOrder(sqlinsert);
}
}
return err;
}
SKGError SKGAccountObject::transferDeferredOperations(const SKGAccountObject& iTargetAccount, QDate iDate)
{
SKGError err;
SKGTRACEINFUNCRC(10, err)
//
auto* doc = qobject_cast<SKGDocumentBank*>(getDocument());
if (doc != nullptr) {
// Get pointed operations
SKGObjectBase::SKGListSKGObjectBase operations;
IFOKDO(err, getDocument()->getObjects(QStringLiteral("v_operation"), "rd_account_id=" % SKGServices::intToString(getID()) % " AND t_status='P'", operations))
int nb = operations.count();
if (nb != 0) {
SKGOperationObject mergedOperations;
SKGOperationObject balancedOperations;
for (int i = 0; !err && i < nb; ++i) {
SKGOperationObject op(operations.at(i));
// Create the balance operation
SKGOperationObject opdup;
IFOKDO(err, op.duplicate(opdup, iDate))
SKGListSKGObjectBase subops;
IFOKDO(err, opdup.getSubOperations(subops))
int nbsupops = subops.count();
for (int j = 0; !err && j < nbsupops; ++j) {
SKGSubOperationObject subop(subops.at(j));
IFOKDO(err, subop.setDate(op.getDate()))
IFOKDO(err, subop.setQuantity(-subop.getQuantity()))
IFOKDO(err, subop.save())
}
if (i == 0) {
mergedOperations = opdup;
} else {
IFOKDO(err, mergedOperations.mergeSuboperations(opdup))
}
// Create the duplicate in target account
SKGOperationObject opduptarget;
IFOKDO(err, op.duplicate(opduptarget))
IFOKDO(err, opduptarget.setDate(op.getDate()))
IFOKDO(err, opduptarget.setParentAccount(iTargetAccount))
IFOKDO(err, opduptarget.setImported(op.isImported()))
IFOKDO(err, opduptarget.setImportID(op.getImportID()))
IFOKDO(err, opduptarget.setGroupOperation(mergedOperations))
IFOKDO(err, opduptarget.setStatus(SKGOperationObject::POINTED))
IFOKDO(err, opduptarget.save())
IFOKDO(err, mergedOperations.load()) // To reload the modif done by the setGroupOperation
// Check the operation
IFOKDO(err, op.setStatus(SKGOperationObject::CHECKED))
IFOKDO(err, op.save())
}
// Check the balance operation
IFOKDO(err, mergedOperations.setPayee(SKGPayeeObject()))
IFOKDO(err, mergedOperations.setStatus(SKGOperationObject::CHECKED))
IFOKDO(err, mergedOperations.save())
}
}
return err;
}
QVector< QVector<SKGOperationObject> > SKGAccountObject::getPossibleReconciliations(double iTargetBalance, bool iSearchAllPossibleReconciliation) const
{
SKGTRACEINFUNC(5)
QVector< QVector<SKGOperationObject> > output;
auto* doc = qobject_cast<SKGDocumentBank*>(getDocument());
if (doc != nullptr) {
// Get unit
SKGServices::SKGUnitInfo unit1 = doc->getPrimaryUnit();
SKGUnitObject unitAccount;
if (getUnit(unitAccount).isSucceeded()) {
if (!unitAccount.getSymbol().isEmpty()) {
unit1.Symbol = unitAccount.getSymbol();
unit1.Value = SKGServices::stringToDouble(unitAccount.getAttribute(QStringLiteral("f_CURRENTAMOUNT")));
}
}
SKGTRACEL(5) << "iTargetBalance=" << doc->formatMoney(iTargetBalance, unit1, false) << endl;
// Get balance of checked operations
QString balanceString;
getDocument()->executeSingleSelectSqliteOrder("SELECT f_CHECKED from v_account_display WHERE id=" % SKGServices::intToString(getID()), balanceString);
double balance = SKGServices::stringToDouble(balanceString);
SKGTRACEL(5) << "balance=" << doc->formatMoney(balance, unit1, false) << endl;
QString zero = doc->formatMoney(0, unit1, false);
QString negativezero = doc->formatMoney(-EPSILON, unit1, false);
QString sdiff = doc->formatMoney(balance - iTargetBalance * unit1.Value, unit1, false);
if (sdiff == zero || sdiff == negativezero) {
// This is an empty soluce
output.push_back(QVector<SKGOperationObject>());
SKGTRACEL(5) << "empty solution found !!!" << endl;
} else {
// Get all imported operation
SKGObjectBase::SKGListSKGObjectBase operations;
getDocument()->getObjects(QStringLiteral("v_operation"), "rd_account_id=" % SKGServices::intToString(getID()) % " AND t_status!='Y' AND t_template='N' AND t_imported IN ('Y','P') ORDER BY d_date, id", operations);
int nb = operations.count();
if (!iSearchAllPossibleReconciliation) {
// Check if all operations are a solution
double amount = 0.0;
QVector<SKGOperationObject> list;
list.reserve(nb);
for (int i = 0; i < nb; ++i) {
SKGOperationObject op(operations.at(i));
amount += op.getCurrentAmount();
list.push_back(op);
}
QString sdiff = doc->formatMoney(amount + balance - iTargetBalance * unit1.Value, unit1, false);
if (sdiff == zero || sdiff == negativezero) {
SKGTRACEL(5) << "all operations are a solution !!!" << endl;
output.push_back(list);
return output;
}
}
// Search
int nbmax = 500;
SKGTRACEL(5) << "Nb operations:" << nb << endl;
if (nb > nbmax) {
SKGTRACEL(5) << "Too many operations (" << nb << ") ==> Reducing the size of the computation" << endl;
for (int i = 0; i < nb - nbmax; ++i) {
SKGOperationObject op(operations.at(0));
auto amount = op.getCurrentAmount();
balance += amount;
operations.removeFirst();
}
}
output = getPossibleReconciliations(operations, balance, iTargetBalance, unit1, iSearchAllPossibleReconciliation);
}
}
return output;
}
QVector< QVector<SKGOperationObject> > SKGAccountObject::getPossibleReconciliations(const SKGObjectBase::SKGListSKGObjectBase& iOperations, double iBalance, double iTargetBalance, const SKGServices::SKGUnitInfo& iUnit, bool iSearchAllPossibleReconciliation) const
{
SKGTRACEINFUNC(5)
QVector< QVector<SKGOperationObject> > output;
output.reserve(5);
auto* doc = qobject_cast<SKGDocumentBank*>(getDocument());
if (doc != nullptr) {
SKGTRACEL(5) << "iTargetBalance=" << doc->formatMoney(iTargetBalance, iUnit, false) << endl;
// Comparison
QString zero = doc->formatMoney(0, iUnit, false);
QString negativezero = doc->formatMoney(-EPSILON, iUnit, false);
// Check operations list
int nb = iOperations.count();
if (nb > 0) {
// Get all operations of the next date
QVector<SKGOperationObject> nextOperations;
nextOperations.reserve(iOperations.count());
QString date = iOperations.at(0).getAttribute(QStringLiteral("d_date"));
for (int i = 0; i < nb; ++i) {
SKGOperationObject op(iOperations.at(i));
if (op.getAttribute(QStringLiteral("d_date")) == date) {
nextOperations.push_back(op);
} else {
break;
}
}
// Get all combination of operations
int nbNext = nextOperations.count();
SKGTRACEL(5) << date << ":" << nbNext << " operations found" << endl;
std::vector<int> v(nbNext);
for (int i = 0; i < nbNext; ++i) {
v[i] = i;
}
double nextBalance = iBalance;
int index = 0;
if (nbNext > 7) {
SKGTRACEL(5) << "Too many combination: " << factorial(nbNext) << " ==> limited to 5040" << endl;
nbNext = 7;
}
nb = factorial(nbNext);
bool stopTests = false;
QVector<SKGOperationObject> combi;
QVector<double> combiAmount;
combi.reserve(nbNext);
combiAmount.reserve(nbNext);
do {
// Build the next combination
combi.resize(0);
combiAmount.resize(0);
double sumOperationPositives = 0.0;
double sumOperationsNegatives = 0.0;
for (int i = 0; i < nbNext; ++i) {
const SKGOperationObject& op = nextOperations.at(v[i]);
combi.push_back(op);
auto amount = op.getCurrentAmount();
combiAmount.push_back(amount);
if (Q_LIKELY(amount < 0)) {
sumOperationsNegatives += amount;
} else if (amount > 0) {
sumOperationPositives += amount;
}
}
// Test the combination
double diff = iBalance - iTargetBalance * iUnit.Value;
double previousDiff = diff;
SKGTRACEL(5) << "Check combination " << (index + 1) << "/" << nb << ": Diff=" << doc->formatMoney(diff, iUnit, false) << endl;
// Try to find an immediate soluce
int nbop = combi.count();
for (int j = 0; j < nbop; ++j) {
auto amount = combiAmount.at(j);
diff += amount;
if (Q_UNLIKELY(index == 0)) {
nextBalance += amount;
}
QString sdiff = doc->formatMoney(diff, iUnit, false);
SKGTRACEL(5) << (j + 1) << "/" << nbop << ": Amount=" << amount << " / New diff=" << sdiff << endl;
if (sdiff == zero || sdiff == negativezero) {
// This is a soluce
auto s = combi.mid(0, j + 1);
if (output.contains(s)) {
SKGTRACEL(5) << "found but already existing !!!" << endl;
} else {
output.push_back(s);
SKGTRACEL(5) << "found !!!" << endl;
if (j == nbop - 1 || iSearchAllPossibleReconciliation) {
// No need to test all combinations
SKGTRACEL(5) << "No need to test all combinations" << endl;
stopTests = true;
}
}
}
}
// Check if tests of all combinations can be cancelled
if ((previousDiff > 0 && previousDiff + sumOperationsNegatives > 0) || (previousDiff < 0 && previousDiff + sumOperationPositives < 0)) {
SKGTRACEL(5) << "No need to test all combinations due to signs of operations and diffs" << endl;
stopTests = true;
}
++index;
} while (index < nb && std::next_permutation(v.begin(), v.end()) && !stopTests);
// Try to find next solutions
auto reconciliations = getPossibleReconciliations(iOperations.mid(nbNext), nextBalance, iTargetBalance, iUnit, iSearchAllPossibleReconciliation);
int nbReconciliations = reconciliations.count();
output.reserve(nbReconciliations + 5);
for (int i = 0; i < nbReconciliations; ++i) {
QVector<SKGOperationObject> output2 = nextOperations;
output2 = output2 << reconciliations.at(i);
output.push_back(output2);
}
}
}
SKGTRACEL(5) << output.count() << " soluces found" << endl;
if (!output.isEmpty()) {
SKGTRACEL(5) << "Size of the first soluce: " << output.at(0).count() << endl;
}
return output;
}
SKGError SKGAccountObject::autoReconcile(double iBalance)
{
SKGError err;
SKGTRACEINFUNCRC(5, err)
// Soluces
auto soluces = getPossibleReconciliations(iBalance);
int nbSoluces = soluces.count();
if (nbSoluces > 0) {
if (nbSoluces > 1) {
err = getDocument()->sendMessage(i18nc("An information message", "More than one solution is possible for this auto reconciliation."));
}
// Choose the longest solution
QVector<SKGOperationObject> soluce;
int length = 0;
for (int i = 0; i < nbSoluces; ++i) {
const auto& s = soluces.at(i);
int l = s.count();
if (l > length) {
soluce = s;
length = l;
}
}
// Check all
SKGTRACEL(5) << length << " operations pointed" << endl;
for (int i = 0; i < length; ++i) {
SKGOperationObject op(soluce.at(i));
err = op.setStatus(SKGOperationObject::POINTED);
IFOKDO(err, op.save(true, false))
}
} else {
err = SKGError(ERR_FAIL, i18nc("Error message", "Can not find the imported operations for obtaining the expected final balance"),
QString("skg://skrooge_operation_plugin/?title_icon=quickopen&title=" % SKGServices::encodeForUrl(i18nc("Noun, a list of items", "Operations of account \"%1\" used for auto reconciliation", getDisplayName())) %
"&operationWhereClause=" % SKGServices::encodeForUrl("rd_account_id=" + SKGServices::intToString(getID()) + " AND t_template='N' AND ((t_status='N' AND t_imported IN ('Y','P')) OR t_status='Y')")));
}
return err;
}
SKGError SKGAccountObject::merge(const SKGAccountObject& iAccount, bool iMergeInitalBalance)
{
SKGError err;
SKGTRACEINFUNCRC(10, err)
// Get initial balances
double balance1 = 0.0;
SKGUnitObject unit1;
err = getInitialBalance(balance1, unit1);
double balance2 = 0.0;
SKGUnitObject unit2;
if (iMergeInitalBalance) {
IFOKDO(err, const_cast<SKGAccountObject*>(&iAccount)->getInitialBalance(balance2, unit2))
}
// Transfer operations
SKGObjectBase::SKGListSKGObjectBase ops;
IFOKDO(err, iAccount.getOperations(ops))
int nb = ops.count();
for (int i = 0; !err && i < nb; ++i) {
SKGOperationObject op(ops.at(i));
err = op.setParentAccount(*this);
IFOKDO(err, op.save(true, false))
}
// Set initial balance
SKGUnitObject unit = unit1;
if (!unit1.exist()) {
unit = unit2;
}
if (unit.exist() && balance2 != 0.0) {
double balance = balance1 + SKGUnitObject::convert(balance2, unit2, unit);
IFOKDO(err, setInitialBalance(balance, unit))
}
// Remove account
IFOKDO(err, iAccount.remove(false))
return err;
}
diff --git a/skgbankmodeler/skgaccountobject.h b/skgbankmodeler/skgaccountobject.h
index 56e8a1f60..ea6cfb0d2 100644
--- a/skgbankmodeler/skgaccountobject.h
+++ b/skgbankmodeler/skgaccountobject.h
@@ -1,505 +1,505 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGACCOUNTOBJECT_H
#define SKGACCOUNTOBJECT_H
/** @file
* This file defines classes SKGAccountObject.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgbankmodeler_export.h"
#include "skgnamedobject.h"
class SKGBankObject;
class SKGOperationObject;
class SKGUnitObject;
class SKGInterestObject;
/**
* This class manages account object
*/
class SKGBANKMODELER_EXPORT SKGAccountObject : public SKGNamedObject
{
Q_OBJECT
public:
/**
* Describe a interest item
*/
struct SKGInterestItem {
SKGObjectBase object; /**< The object (an operation, an interest or nothing for initial balance) */
QDate date; /**< The date */
QDate valueDate; /**< The valueDate */
int base{}; /**< Base */
double amount{}; /**< Amount */
double coef{}; /**< Coef */
double rate{}; /**< Rate */
double annualInterest{}; /**< Annual Interest */
double accruedInterest{}; /**< Accrued Interest */
};
using SKGInterestItemList = QVector<SKGAccountObject::SKGInterestItem>;
/**
* This enumerate defines type of account
*/
enum AccountType {CURRENT, /**< to define a bank account*/
CREDITCARD, /**< to define a credit card account*/
INVESTMENT, /**< to define an account for investment */
ASSETS, /**< to define a assets account */
OTHER, /**< other kind of account */
WALLET, /**< to define a wallet account */
LOAN, /**< to define a loan account */
SAVING, /**< to define a saving account */
PENSION /**< to define a pension account */
};
/**
* This enumerate defines type of account
*/
Q_ENUM(AccountType)
/**
* Default constructor
*/
explicit SKGAccountObject();
/**
* Constructor
* @param iDocument the document containing the object
* @param iID the identifier in @p iTable of the object
*/
explicit SKGAccountObject(SKGDocument* iDocument, int iID = 0);
/**
* Copy constructor
* @param iObject the object to copy
*/
SKGAccountObject(const SKGAccountObject& iObject);
/**
* Copy constructor
* @param iObject the object to copy
*/
explicit SKGAccountObject(const SKGNamedObject& iObject);
/**
* Copy constructor
* @param iObject the object to copy
*/
explicit SKGAccountObject(const SKGObjectBase& iObject);
/**
* Operator affectation
* @param iObject the object to copy
*/
SKGAccountObject& operator= (const SKGObjectBase& iObject);
/**
* Destructor
*/
~SKGAccountObject() override;
/**
* Get the parent bank
* @param oBank the parent bank
* @return an object managing the error
* @see SKGError
*/
virtual SKGError getBank(SKGBankObject& oBank) const;
/**
* Set the parent bank
* @param iBank the parent bank
* @return an object managing the error
* @see SKGError
*/
virtual SKGError setBank(const SKGBankObject& iBank);
/**
* Get the linked account
* @param oAccount the linked account
* @return an object managing the error
* @see SKGError
*/
virtual SKGError getLinkedAccount(SKGAccountObject& oAccount) const;
/**
* Get the list of accounts linked to this one
* @param oAccounts the list of accounts linked
* @return an object managing the error
* @see SKGError
*/
virtual SKGError getLinkedByAccounts(SKGListSKGObjectBase& oAccounts) const;
/**
* Set the linked account
* @param iAccount the linked account
* @return an object managing the error
* @see SKGError
*/
virtual SKGError setLinkedAccount(const SKGAccountObject& iAccount);
/**
* Set the initial balance of this account
* @param iBalance the balance
* @param iUnit the unit
* @return an object managing the error
* @see SKGError
*/
virtual SKGError setInitialBalance(double iBalance, const SKGUnitObject& iUnit);
/**
* Get the initial balance of this account
* @param oBalance the balance
* @param oUnit the unit
* @return an object managing the error
* @see SKGError
*/
virtual SKGError getInitialBalance(double& oBalance, SKGUnitObject& oUnit);
/**
* Set the number of the account
* @param iNumber the number
* @return an object managing the error
* @see SKGError
*/
virtual SKGError setNumber(const QString& iNumber);
/**
* Get the number of the account
* @return the number
*/
virtual QString getNumber() const;
/**
* Set the agency number of the account
* @param iNumber the agency number
* @return an object managing the error
* @see SKGError
*/
virtual SKGError setAgencyNumber(const QString& iNumber);
/**
* Get the agency number of the account
* @return the number
*/
virtual QString getAgencyNumber() const;
/**
* Set the agency address of the account
* @param iAddress the agency address
* @return an object managing the error
* @see SKGError
*/
virtual SKGError setAgencyAddress(const QString& iAddress);
/**
* Get the agency address of the account
* @return the number
*/
virtual QString getAgencyAddress() const;
/**
* Set the comment of account
* @param iComment the comment
* @return an object managing the error
* @see SKGError
*/
virtual SKGError setComment(const QString& iComment);
/**
* Get the comment of this account
* @return the comment
*/
virtual QString getComment() const;
/**
* Add a new operation to this account
* @param oOperation the created operation
* @param iForce force the creation even if the account is closed
* @return an object managing the error
* @see SKGError
*/
virtual SKGError addOperation(SKGOperationObject& oOperation, bool iForce = false);
/**
* Get number of operations
* @return the number of operations
*/
virtual int getNbOperation() const;
/**
* Get all operations of this account
* @param oOperations all operations of this account
* @return an object managing the error
* @see SKGError
*/
virtual SKGError getOperations(SKGListSKGObjectBase& oOperations) const;
/**
* Get the current amount
* @return the current amount
*/
virtual double getCurrentAmount() const;
/**
* Get amount of the account at a date
* @param iDate date
* @param iOnlyCurrencies only the operations based on currencies are taken into account, not shares
* @return amount of the account
*/
// cppcheck-suppress passedByValue
virtual double getAmount(QDate iDate, bool iOnlyCurrencies = false) const;
/**
* Set the type of this account
* @param iType the type
* @return an object managing the error
* @see SKGError
*/
virtual SKGError setType(SKGAccountObject::AccountType iType);
/**
* Get the type of this account
* @return the type
*/
virtual SKGAccountObject::AccountType getType() const;
/**
* To set the closed attribute of an account
* @param iClosed the closed attribute: true or false
* @return an object managing the error
* @see SKGError
*/
virtual SKGError setClosed(bool iClosed);
/**
* To know if the account has been closed or not
* @return an object managing the error
* @see SKGError
*/
virtual bool isClosed() const;
/**
* To bookmark or not on an account
* @param iBookmark the bookmark: true or false
* @return an object managing the error
* @see SKGError
*/
virtual SKGError bookmark(bool iBookmark);
/**
* To know if the account is bookmarked
* @return an object managing the error
* @see SKGError
*/
virtual bool isBookmarked() const;
/**
* To enable the max amount limit or not on an account
* @param iEnabled the state: true or false
* @return an object managing the error
* @see SKGError
*/
virtual SKGError maxLimitAmountEnabled(bool iEnabled);
/**
* To know if the account has a max amount limit
* @return an object managing the error
* @see SKGError
*/
virtual bool isMaxLimitAmountEnabled() const;
/**
* To set the max amount limit
* @param iAmount the amount (in account's unit)
* @return an object managing the error
* @see SKGError
*/
virtual SKGError setMaxLimitAmount(double iAmount);
/**
* To get the max amount limit (in account's unit)
* @return an object managing the error
* @see SKGError
*/
virtual double getMaxLimitAmount() const;
/**
* To enable the min amount limit or not on an account
* @param iEnabled the state: true or false
* @return an object managing the error
* @see SKGError
*/
virtual SKGError minLimitAmountEnabled(bool iEnabled);
/**
* To know if the account has a min amount limit
* @return an object managing the error
* @see SKGError
*/
virtual bool isMinLimitAmountEnabled() const;
/**
* To set the min amount limit
* @param iAmount the amount (in account's unit)
* @return an object managing the error
* @see SKGError
*/
virtual SKGError setMinLimitAmount(double iAmount);
/**
* To get the min amount limit (in account's unit)
* @return an object managing the error
* @see SKGError
*/
virtual double getMinLimitAmount() const;
/**
* Set reconciliation date of this account
* @param iDate the date
* @return an object managing the error
* @see SKGError
*/
// cppcheck-suppress passedByValue
virtual SKGError setReconciliationDate(QDate iDate);
/**
* Get reconciliation date of this account
* @return the date
*/
virtual QDate getReconciliationDate() const;
/**
* Set reconciliation balance of this account
* @param iAmount the balance
* @return an object managing the error
* @see SKGError
*/
virtual SKGError setReconciliationBalance(double iAmount);
/**
* Get reconciliation balance of this account
* @return the balance
*/
virtual double getReconciliationBalance() const;
/**
* Get the unit
* @param oUnit the unit
* @return an object managing the error
* @see SKGError
*/
virtual SKGError getUnit(SKGUnitObject& oUnit) const;
/**
* Add an interest
* @param oInterest the created interest
* @return an object managing the error.
* @see SKGError
*/
virtual SKGError addInterest(SKGInterestObject& oInterest);
/**
* Get interests
* @param oInterestList the list of interest in this account
* @return an object managing the error
* @see SKGError
*/
virtual SKGError getInterests(SKGListSKGObjectBase& oInterestList) const;
/**
* Get interest object at a given date
* @param iDate the date
* @param oInterest the interest object
* @return an object managing the error
* @see SKGError
*/
// cppcheck-suppress passedByValue
virtual SKGError getInterest(QDate iDate, SKGInterestObject& oInterest) const;
/**
* Get and compute interest items
* @param oInterestList interest items
* @param oInterests sum of annual interests
* @param iYear the year of computation (default=current year)
* @return an object managing the error
* @see SKGError
*/
virtual SKGError getInterestItems(SKGAccountObject::SKGInterestItemList& oInterestList, double& oInterests, int iYear = 0) const;
/**
* Compute all items
* @param ioInterestList interest items
* @param oInterests sum of annual interests
* @param iYear the year of computation (default=current year)
* @return an object managing the error
* @see SKGError
*/
virtual SKGError computeInterestItems(SKGAccountObject::SKGInterestItemList& ioInterestList, double& oInterests, int iYear = 0) const;
/**
* Try to point all imported operations to obtain the expected balance
* @param iBalance the expected balance in the account unit
* @return an object managing the error
* @see SKGError
*/
virtual SKGError autoReconcile(double iBalance);
/**
* Merge iAccount in current account
* @param iAccount the account. All operations will be transferred into this account. The account will be removed
* @param iMergeInitalBalance to merge the initial balances too
* @return an object managing the error
* @see SKGError
*/
virtual SKGError merge(const SKGAccountObject& iAccount, bool iMergeInitalBalance);
/**
* Create a Transfer operation to balance a credit card account (based on pointed operations)
* @param iTargetAccount the target account (should be the bank account)
* @param iDate the date of the balance operation
* @return an object managing the error
* @see SKGError
*/
// cppcheck-suppress passedByValue
virtual SKGError transferDeferredOperations(const SKGAccountObject& iTargetAccount, QDate iDate = QDate::currentDate());
/**
* Get all list of operations that can be checked to reconcile with target balance
* @param iTargetBalance the target balance (in the unit of the account)
* @param iSearchAllPossibleReconciliation to search all possible reconciliation
* @return the list of possible solutions
*/
virtual QVector< QVector<SKGOperationObject> > getPossibleReconciliations(double iTargetBalance, bool iSearchAllPossibleReconciliation = true) const;
private:
/**
* Get all list of operations that can be checked to reconcile with target balance
* @param iOperations the operations to take into account
* @param iBalance the current balance (in the unit of the account)
* @param iTargetBalance the target balance (in the unit of the account)
* @param iUnit the unit of the account (for better performances)
* @param iSearchAllPossibleReconciliation to search all possible reconciliation
* @return the list of possible solutions
*/
QVector< QVector<SKGOperationObject> > getPossibleReconciliations(const SKGObjectBase::SKGListSKGObjectBase& iOperations, double iBalance, double iTargetBalance, const SKGServices::SKGUnitInfo& iUnit, bool iSearchAllPossibleReconciliation) const;
};
/**
* Declare the class
*/
Q_DECLARE_TYPEINFO(SKGAccountObject, Q_MOVABLE_TYPE);
#endif
diff --git a/skgbankmodeler/skgbankincludes.h b/skgbankmodeler/skgbankincludes.h
index 81edacccc..397b1c8eb 100644
--- a/skgbankmodeler/skgbankincludes.h
+++ b/skgbankmodeler/skgbankincludes.h
@@ -1,44 +1,44 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGBANKINCLUDES_H
#define SKGBANKINCLUDES_H
/** @file
* This file defines all includes needed to develop on this modeler.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgaccountobject.h"
#include "skgbankobject.h"
#include "skgbudgetobject.h"
#include "skgbudgetruleobject.h"
#include "skgcategoryobject.h"
#include "skgdocumentbank.h"
#include "skginterestobject.h"
#include "skgnodeobject.h"
#include "skgoperationobject.h"
#include "skgpayeeobject.h"
#include "skgrecurrentoperationobject.h"
#include "skgruleobject.h"
#include "skgsuboperationobject.h"
#include "skgtrackerobject.h"
#include "skgtransactionmng.h"
#include "skgunitobject.h"
#include "skgunitvalueobject.h"
#include "skgdefinebank.h"
#endif // SKGBANKINCLUDES_H
diff --git a/skgbankmodeler/skgbankobject.cpp b/skgbankmodeler/skgbankobject.cpp
index 66e348c30..6a828704f 100644
--- a/skgbankmodeler/skgbankobject.cpp
+++ b/skgbankmodeler/skgbankobject.cpp
@@ -1,109 +1,109 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file implements classes SKGBankObject.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgbankobject.h"
#include <klocalizedstring.h>
#include "skgaccountobject.h"
#include "skgdocumentbank.h"
SKGBankObject::SKGBankObject(): SKGBankObject(nullptr)
{}
SKGBankObject::SKGBankObject(SKGDocument* iDocument, int iID): SKGNamedObject(iDocument, QStringLiteral("v_bank"), iID)
{}
SKGBankObject::~SKGBankObject()
= default;
SKGBankObject::SKGBankObject(const SKGBankObject& iObject)
= default;
SKGBankObject::SKGBankObject(const SKGNamedObject& iObject)
{
if (iObject.getRealTable() == QStringLiteral("bank")) {
copyFrom(iObject);
} else {
*this = SKGNamedObject(iObject.getDocument(), QStringLiteral("v_bank"), iObject.getID());
}
}
SKGBankObject::SKGBankObject(const SKGObjectBase& iObject)
{
if (iObject.getRealTable() == QStringLiteral("bank")) {
copyFrom(iObject);
} else {
*this = SKGNamedObject(iObject.getDocument(), QStringLiteral("v_bank"), iObject.getID());
}
}
SKGBankObject& SKGBankObject::operator= (const SKGObjectBase& iObject)
{
copyFrom(iObject);
return *this;
}
SKGError SKGBankObject::addAccount(SKGAccountObject& oAccount)
{
SKGError err;
if (getID() == 0) {
err = SKGError(ERR_FAIL, i18nc("Error message", "%1 failed because linked object is not yet saved in the database.", QStringLiteral("SKGBankObject::addAccount")));
} else {
oAccount = SKGAccountObject(qobject_cast<SKGDocumentBank*>(getDocument()));
err = oAccount.setAttribute(QStringLiteral("rd_bank_id"), SKGServices::intToString(getID()));
}
return err;
}
SKGError SKGBankObject::getAccounts(SKGListSKGObjectBase& oAccountList) const
{
SKGError err = getDocument()->getObjects(QStringLiteral("v_account"),
"rd_bank_id=" % SKGServices::intToString(getID()),
oAccountList);
return err;
}
SKGError SKGBankObject::setNumber(const QString& iNumber)
{
return setAttribute(QStringLiteral("t_bank_number"), iNumber);
}
QString SKGBankObject::getNumber() const
{
return getAttribute(QStringLiteral("t_bank_number"));
}
SKGError SKGBankObject::setIcon(const QString& iIcon)
{
return setAttribute(QStringLiteral("t_icon"), iIcon);
}
QString SKGBankObject::getIcon() const
{
return getAttribute(QStringLiteral("t_icon"));
}
double SKGBankObject::getCurrentAmount() const
{
return SKGServices::stringToDouble(getAttributeFromView(QStringLiteral("v_bank_amount"), QStringLiteral("f_CURRENTAMOUNT")));
}
diff --git a/skgbankmodeler/skgbankobject.h b/skgbankmodeler/skgbankobject.h
index 66c180b91..50d161e13 100644
--- a/skgbankmodeler/skgbankobject.h
+++ b/skgbankmodeler/skgbankobject.h
@@ -1,133 +1,133 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGBANKOBJECT_H
#define SKGBANKOBJECT_H
/** @file
* This file defines classes SKGBankObject.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgbankmodeler_export.h"
#include "skgnamedobject.h"
class SKGAccountObject;
/**
* This class manages bank object
*/
class SKGBANKMODELER_EXPORT SKGBankObject final : public SKGNamedObject
{
Q_OBJECT
public:
/**
* Default constructor
*/
explicit SKGBankObject();
/**
* Constructor
* @param iDocument the document containing the object
* @param iID the identifier in @p iTable of the object
*/
explicit SKGBankObject(SKGDocument* iDocument, int iID = 0);
/**
* Copy constructor
* @param iObject the object to copy
*/
SKGBankObject(const SKGBankObject& iObject);
/**
* Copy constructor
* @param iObject the object to copy
*/
explicit SKGBankObject(const SKGNamedObject& iObject);
/**
* Copy constructor
* @param iObject the object to copy
*/
explicit SKGBankObject(const SKGObjectBase& iObject);
/**
* Operator affectation
* @param iObject the object to copy
*/
SKGBankObject& operator= (const SKGObjectBase& iObject);
/**
* Destructor
*/
~SKGBankObject() override;
/**
* Add an account
* @param oAccount the created account
* @return an object managing the error.
* @see SKGError
*/
SKGError addAccount(SKGAccountObject& oAccount);
/**
* Get accounts
* @param oAccountList the list of accounts in this bank
* @return an object managing the error
* @see SKGError
*/
SKGError getAccounts(SKGListSKGObjectBase& oAccountList) const;
/**
* Set the number of the bank
* @param iNumber the number
* @return an object managing the error
* @see SKGError
*/
SKGError setNumber(const QString& iNumber);
/**
* Get the number of the bank
* @return the number
*/
QString getNumber() const;
/**
* Set the icon of the bank
* @param iIcon the icon
* @return an object managing the error
* @see SKGError
*/
SKGError setIcon(const QString& iIcon);
/**
* Get the icon of the bank
* @return the number
*/
QString getIcon() const;
/**
* Get the current amount
* @return the current amount
*/
double getCurrentAmount() const;
};
/**
* Declare the class
*/
Q_DECLARE_TYPEINFO(SKGBankObject, Q_MOVABLE_TYPE);
#endif
diff --git a/skgbankmodeler/skgbudgetobject.cpp b/skgbankmodeler/skgbudgetobject.cpp
index ef366ac78..b31161d13 100644
--- a/skgbankmodeler/skgbudgetobject.cpp
+++ b/skgbankmodeler/skgbudgetobject.cpp
@@ -1,389 +1,389 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+* along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file defines classes SKGBudgetObject.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgbudgetobject.h"
#include <klocalizedstring.h>
#include "skgbudgetruleobject.h"
#include "skgcategoryobject.h"
#include "skgdefine.h"
#include "skgdocumentbank.h"
#include "skgtraces.h"
#include "skgtransactionmng.h"
SKGBudgetObject::SKGBudgetObject() : SKGBudgetObject(nullptr)
{}
SKGBudgetObject::SKGBudgetObject(SKGDocument* iDocument, int iID)
: SKGObjectBase(iDocument, QStringLiteral("v_budget"), iID)
{}
SKGBudgetObject::~SKGBudgetObject()
= default;
SKGBudgetObject::SKGBudgetObject(const SKGBudgetObject& iObject)
= default;
SKGBudgetObject::SKGBudgetObject(const SKGObjectBase& iObject)
{
if (iObject.getRealTable() == QStringLiteral("budget")) {
copyFrom(iObject);
} else {
*this = SKGObjectBase(iObject.getDocument(), QStringLiteral("v_budget"), iObject.getID());
}
}
SKGBudgetObject& SKGBudgetObject::operator= (const SKGObjectBase& iObject)
{
copyFrom(iObject);
return *this;
}
QString SKGBudgetObject::getWhereclauseId() const
{
// Could we use the id
QString output = SKGObjectBase::getWhereclauseId();
if (output.isEmpty()) {
QString y = getAttribute(QStringLiteral("i_year"));
if (!y.isEmpty()) {
output = "i_year=" % y;
}
QString m = getAttribute(QStringLiteral("i_month"));
if (!m.isEmpty()) {
if (!output.isEmpty()) {
output = output % " AND ";
}
output = output % "i_month=" % m;
}
QString r = getAttribute(QStringLiteral("rc_category_id"));
if (!output.isEmpty()) {
output = output % " AND ";
}
output = output % "rc_category_id=" % (r.isEmpty() ? QStringLiteral("0") : r);
}
return output;
}
SKGError SKGBudgetObject::setBudgetedAmount(double iAmount)
{
SKGError err = setAttribute(QStringLiteral("f_budgeted"), SKGServices::doubleToString(iAmount));
IFOKDO(err, setAttribute(QStringLiteral("f_budgeted_modified"), SKGServices::doubleToString(iAmount)))
IFOKDO(err, setAttribute(QStringLiteral("t_modification_reasons"), QLatin1String("")))
return err;
}
double SKGBudgetObject::getBudgetedAmount() const
{
return SKGServices::stringToDouble(getAttribute(QStringLiteral("f_budgeted")));
}
double SKGBudgetObject::getBudgetedModifiedAmount() const
{
return SKGServices::stringToDouble(getAttribute(QStringLiteral("f_budgeted_modified")));
}
QString SKGBudgetObject::getModificationReasons() const
{
return getAttribute(QStringLiteral("t_modification_reasons"));
}
double SKGBudgetObject::getDelta() const
{
return SKGServices::stringToDouble(getAttribute(QStringLiteral("f_DELTABEFORETRANSFER")));
}
SKGError SKGBudgetObject::setYear(int iYear)
{
return setAttribute(QStringLiteral("i_year"), SKGServices::intToString(iYear));
}
int SKGBudgetObject::getYear() const
{
return SKGServices::stringToInt(getAttribute(QStringLiteral("i_year")));
}
SKGError SKGBudgetObject::setMonth(int iMonth)
{
return setAttribute(QStringLiteral("i_month"), SKGServices::intToString(iMonth));
}
int SKGBudgetObject::getMonth() const
{
return SKGServices::stringToInt(getAttribute(QStringLiteral("i_month")));
}
SKGError SKGBudgetObject::setCategory(const SKGCategoryObject& iCategory)
{
return setAttribute(QStringLiteral("rc_category_id"), SKGServices::intToString(iCategory.getID()));
}
SKGError SKGBudgetObject::getCategory(SKGCategoryObject& oCategory) const
{
return getDocument()->getObject(QStringLiteral("v_category"), "id=" % getAttribute(QStringLiteral("rc_category_id")), oCategory);
}
SKGError SKGBudgetObject::enableSubCategoriesInclusion(bool iEnable)
{
return setAttribute(QStringLiteral("t_including_subcategories"), iEnable ? QStringLiteral("Y") : QStringLiteral("N"));
}
bool SKGBudgetObject::isSubCategoriesInclusionEnabled() const
{
return (getAttribute(QStringLiteral("t_including_subcategories")) == QStringLiteral("Y"));
}
SKGError SKGBudgetObject::removeCategory()
{
return setAttribute(QStringLiteral("rc_category_id"), QStringLiteral("0"));
}
SKGError SKGBudgetObject::process()
{
SKGError err;
SKGTRACEINFUNCRC(10, err)
// Main values
int m = getMonth();
int y = getYear();
double transferred = SKGServices::stringToDouble(getAttribute(QStringLiteral("f_transferred")));
// Get budgets rules ordered
SKGObjectBase::SKGListSKGObjectBase budgetsRules;
QString sql = "(t_year_condition='N' OR i_year=" % SKGServices::intToString(y) % ") AND "
"(t_month_condition='N' OR i_month=" % SKGServices::intToString(m) % ") AND "
"(t_category_condition='N' OR rc_category_id=" % getAttribute(QStringLiteral("rc_category_id")) % ") "
"ORDER BY i_ORDER ASC";
err = getDocument()->getObjects(QStringLiteral("v_budgetrule"), sql, budgetsRules);
int nb = budgetsRules.count();
if (!err && (nb != 0)) {
err = getDocument()->beginTransaction("#INTERNAL#" % i18nc("Progression step", "Apply budget rules"), nb);
for (int i = 0; !err && i < nb; ++i) {
SKGBudgetRuleObject rule(budgetsRules.at(i));
// Do we have something to do
SKGBudgetRuleObject::Condition cond = rule.getCondition();
double delta = getDelta();
double quantity = rule.getQuantity();
if (delta != 0.0) {
if (cond == SKGBudgetRuleObject::ALL || (delta < 0 && cond == SKGBudgetRuleObject::NEGATIVE) || (delta > 0 && cond == SKGBudgetRuleObject::POSITIVE)) {
// Compute value to transfer
double value = (rule.isAbolute() ? (cond == SKGBudgetRuleObject::NEGATIVE ? qMax(delta, quantity) : qMin(delta, quantity)) : quantity * (delta - transferred) / 100.0);
// Get impacted budget
SKGBudgetObject impactedBudget = *this;
impactedBudget.resetID();
SKGBudgetRuleObject::Mode mode = rule.getTransferMode();
if (mode == SKGBudgetRuleObject::NEXT) {
// Next
int mi = m;
int yi = y;
if (mi == 0) {
// Yearly budget
++yi;
} else {
// Monthly budget
++mi;
if (mi == 13) {
mi = 1;
++yi;
}
}
IFOKDO(err, impactedBudget.setYear(yi))
IFOKDO(err, impactedBudget.setMonth(mi))
} else if (mode == SKGBudgetRuleObject::YEAR) {
// Year
IFOKDO(err, impactedBudget.setYear(y))
IFOKDO(err, impactedBudget.setMonth(0))
}
// Change category
if (!err && rule.isCategoryChangeEnabled()) {
SKGCategoryObject transferCategory;
rule.getTransferCategory(transferCategory);
err = impactedBudget.setCategory(transferCategory);
}
IFOK(err) {
if (impactedBudget.exist()) {
err = impactedBudget.load();
QString newBudget = SKGServices::doubleToString(impactedBudget.getBudgetedModifiedAmount() - value);
IFOKDO(err, impactedBudget.setAttribute(QStringLiteral("f_budgeted_modified"), newBudget))
QString reasons = impactedBudget.getAttribute(QStringLiteral("t_modification_reasons"));
if (!reasons.isEmpty()) {
reasons += '\n';
}
reasons += i18nc("Message", "Transfer of %1 from '%2' to '%3' due to the rule '%4'", value, getDisplayName(), impactedBudget.getDisplayName(), rule.getDisplayName());
IFOKDO(err, impactedBudget.setAttribute(QStringLiteral("t_modification_reasons"), reasons))
IFOKDO(err, impactedBudget.save())
transferred += value;
IFOKDO(err, setAttribute(QStringLiteral("f_transferred"), SKGServices::doubleToString(transferred)))
IFOKDO(err, save())
} else {
getDocument()->sendMessage(i18nc("", "Impossible to apply the rule '%1' for budget '%2' because the impacted budget does not exist", rule.getDisplayName(), this->getDisplayName()), SKGDocument::Warning);
}
}
}
}
IFOKDO(err, getDocument()->stepForward(i + 1))
}
SKGENDTRANSACTION(getDocument(), err)
}
return err;
}
SKGError SKGBudgetObject::createAutomaticBudget(SKGDocumentBank* iDocument, int iYear, int iBaseYear, bool iUseScheduledOperation, bool iRemovePreviousBudget)
{
Q_UNUSED(iUseScheduledOperation)
SKGError err;
SKGTRACEINFUNCRC(10, err)
QString baseYear = SKGServices::intToString(iBaseYear);
int fistMonth = 0;
if (iDocument != nullptr) {
SKGStringListList listTmp;
err = iDocument->executeSelectSqliteOrder(
"SELECT MIN(STRFTIME('%m', d_date)) FROM operation WHERE i_group_id = 0 AND STRFTIME('%Y', d_date) = '" % baseYear %
"' AND t_template='N'",
listTmp);
if (listTmp.count() == 2) {
fistMonth = SKGServices::stringToInt(listTmp.at(1).at(0));
}
}
if (!err && (iDocument != nullptr)) {
SKGStringListList listTmp;
QString sql = "SELECT t_REALCATEGORY, COUNT(TOT),"
"100*COUNT(TOT)/((CASE WHEN STRFTIME('%Y', date('now'))<>'" % baseYear % "' THEN 12 ELSE STRFTIME('%m', date('now'))-1 END)-" %
SKGServices::intToString(fistMonth) % "+1) AS CPOUR,"
"ROUND(TOTAL(TOT)/COUNT(TOT)), MAX(MONTH), TOTAL(TOT) FROM ("
"SELECT t_REALCATEGORY, STRFTIME('%m', d_date) AS MONTH, TOTAL(f_REALCURRENTAMOUNT) AS TOT "
"FROM v_suboperation_consolidated WHERE i_group_id = 0 AND d_DATEYEAR = '" % baseYear % "' AND d_DATEMONTH<STRFTIME('%Y-%m', date('now')) "
"GROUP BY t_REALCATEGORY, d_DATEMONTH"
") GROUP BY t_REALCATEGORY ORDER BY COUNT(TOT) DESC, (MAX(TOT)-MIN(TOT))/ABS(ROUND(TOTAL(TOT)/COUNT(TOT))) ASC, ROUND(TOTAL(TOT)/COUNT(TOT)) ASC";
err = iDocument->executeSelectSqliteOrder(sql, listTmp);
// SELECT r.d_date,r.i_period_increment,r.t_period_unit, r.i_nb_times, r. t_times, r.t_CATEGORY, r.f_CURRENTAMOUNT FROM v_recurrentoperation_display r WHERE r.t_TRANSFER='N'
/*double sumBudgeted = 0;
double sumOps = 0;*/
int nbval = listTmp.count();
if (!err) {
int step = 0;
err = iDocument->beginTransaction("#INTERNAL#" % i18nc("Progression step", "Create automatic budget"), nbval - 1 + 1 + (iRemovePreviousBudget ? 1 : 0));
// Remove previous budgets
if (iRemovePreviousBudget) {
IFOKDO(err, iDocument->executeSqliteOrder("DELETE FROM budget WHERE i_year=" % SKGServices::intToString(iYear)))
++step;
IFOKDO(err, iDocument->stepForward(step))
}
// Create budgets
for (int i = 1; !err && i < nbval; ++i) { // Ignore header
// Get values
QString catName = listTmp.at(i).at(0);
int count = SKGServices::stringToInt(listTmp.at(i).at(1));
int countPercent = SKGServices::stringToInt(listTmp.at(i).at(2));
double amount = SKGServices::stringToDouble(listTmp.at(i).at(3));
int month = SKGServices::stringToInt(listTmp.at(i).at(4));
// sumOps += SKGServices::stringToDouble(listTmp.at(i).at(5));
if (!catName.isEmpty() && (countPercent > 85 || count == 1)) {
SKGCategoryObject cat;
err = iDocument->getObject(QStringLiteral("v_category"), "t_fullname = '" % SKGServices::stringToSqlString(catName) % '\'', cat);
for (int m = fistMonth; !err && m <= (count == 1 ? fistMonth : 12); ++m) {
SKGBudgetObject budget(iDocument);
err = budget.setBudgetedAmount(amount);
IFOKDO(err, budget.setYear(iYear))
IFOKDO(err, budget.setMonth(count == 1 ? month : m))
IFOKDO(err, budget.setCategory(cat))
IFOKDO(err, budget.save())
// sumBudgeted += amount;
}
}
++step;
IFOKDO(err, iDocument->stepForward(step))
}
// Analyze
IFOKDO(err, iDocument->executeSqliteOrder(QStringLiteral("ANALYZE")))
++step;
IFOKDO(err, iDocument->stepForward(step))
SKGENDTRANSACTION(iDocument, err)
}
}
return err;
}
SKGError SKGBudgetObject::balanceBudget(SKGDocumentBank* iDocument, int iYear, int iMonth, bool iBalanceYear)
{
SKGError err;
SKGTRACEINFUNCRC(10, err)
if (iDocument != nullptr) {
err = iDocument->beginTransaction("#INTERNAL#" % i18nc("Progression step", "Balance budgets"), 2);
// Monthly balancing
if (!err && iMonth != -1) {
for (int m = (iMonth == 0 ? 1 : qAsConst(iMonth)); !err && m <= (iMonth == 0 ? 12 : iMonth); ++m) {
SKGStringListList listTmp;
err = iDocument->executeSelectSqliteOrder("SELECT TOTAL(f_budgeted) FROM budget WHERE i_year=" % SKGServices::intToString(iYear) % " AND i_month=" % SKGServices::intToString(m) % " AND rc_category_id<>0", listTmp);
if (!err && listTmp.count() == 2) {
SKGBudgetObject budget(iDocument);
double amount = -SKGServices::stringToDouble(listTmp.at(1).at(0));
err = budget.setBudgetedAmount(amount);
IFOKDO(err, budget.setYear(iYear))
IFOKDO(err, budget.setMonth(m))
IFOKDO(err, budget.save())
}
}
}
IFOKDO(err, iDocument->stepForward(1))
// Annual balancing
if (!err && iBalanceYear) {
SKGStringListList listTmp;
err = iDocument->executeSelectSqliteOrder("SELECT TOTAL(f_budgeted) FROM budget WHERE i_year=" % SKGServices::intToString(iYear) % " AND (i_month<>0 OR rc_category_id<>0)", listTmp);
if (!err && listTmp.count() == 2) {
SKGBudgetObject budget(iDocument);
double amount = -SKGServices::stringToDouble(listTmp.at(1).at(0));
err = budget.setBudgetedAmount(amount);
IFOKDO(err, budget.setYear(iYear))
IFOKDO(err, budget.setMonth(0))
IFOKDO(err, budget.save())
}
}
IFOKDO(err, iDocument->stepForward(2))
SKGENDTRANSACTION(iDocument, err)
}
return err;
}
diff --git a/skgbankmodeler/skgbudgetobject.h b/skgbankmodeler/skgbudgetobject.h
index c7f598b3b..9ba8ba44c 100644
--- a/skgbankmodeler/skgbudgetobject.h
+++ b/skgbankmodeler/skgbudgetobject.h
@@ -1,208 +1,208 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGBUDGETOBJECTT_H
#define SKGBUDGETOBJECTT_H
/** @file
* This file defines classes SKGBudgetObject.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgbankmodeler_export.h"
#include "skgerror.h"
#include "skgobjectbase.h"
class SKGCategoryObject;
class SKGDocumentBank;
/**
* This class is a budget
*/
class SKGBANKMODELER_EXPORT SKGBudgetObject final : public SKGObjectBase
{
Q_OBJECT
public:
/**
* Default constructor
*/
explicit SKGBudgetObject();
/**
* Constructor
* @param iDocument the document containing the object
* @param iID the identifier in @p iTable of the object
*/
explicit SKGBudgetObject(SKGDocument* iDocument, int iID = 0);
/**
* Destructor
*/
~SKGBudgetObject() override;
/**
* Copy constructor
* @param iObject the object to copy
*/
SKGBudgetObject(const SKGBudgetObject& iObject);
/**
* Copy constructor
* @param iObject the object to copy
*/
explicit SKGBudgetObject(const SKGObjectBase& iObject);
/**
* Operator affectation
* @param iObject the object to copy
*/
SKGBudgetObject& operator= (const SKGObjectBase& iObject);
/**
* Set year of the budget
* @param iYear the year
* @return an object managing the error
* @see SKGError
*/
SKGError setYear(int iYear);
/**
* Get year of the budget
* @return year of the budget
*/
int getYear() const;
/**
* Set month of the budget
* @param iMonth the month
* @return an object managing the error
* @see SKGError
*/
SKGError setMonth(int iMonth);
/**
* Get month of the budget
* @return month of the budget
*/
int getMonth() const;
/**
* Set the category
* @param iCategory the category
* @return an object managing the error
* @see SKGError
*/
SKGError setCategory(const SKGCategoryObject& iCategory);
/**
* Remove the category
* @return an object managing the error
* @see SKGError
*/
SKGError removeCategory();
/**
* Get the category
* @param oCategory the category
* @return an object managing the error
* @see SKGError
*/
SKGError getCategory(SKGCategoryObject& oCategory) const;
/**
* Enable / disable the inclusion of sub categories
* @param iEnable condition
* @return an object managing the error
* @see SKGError
*/
SKGError enableSubCategoriesInclusion(bool iEnable);
/**
* To know if sub categories inclusion is enabled or disabled
* @return condition
*/
bool isSubCategoriesInclusionEnabled() const;
/**
* Set budgeted amount of the budget
* @param iAmount the budgeted amount
* @return an object managing the error
* @see SKGError
*/
SKGError setBudgetedAmount(double iAmount);
/**
* Get budgeted amount of the budget
* @return budgeted amount of the budget
*/
double getBudgetedAmount() const;
/**
* Get budgeted modified amount of the budget
* @return budgeted modified amount of the budget
*/
double getBudgetedModifiedAmount() const;
/**
* Get the text explaining the reasons of the modification
* @return the text explaining the reasons of the modification
*/
QString getModificationReasons() const;
/**
* Get delta
* @return delta
*/
double getDelta() const;
/**
* Process all rules
* @return an object managing the error
* @see SKGError
*/
SKGError process();
/**
* Create automatically budget items based on existing operations
* @param iDocument the document where to create*
* @param iYear year of budget
* @param iBaseYear year of the base for computation
* @param iUseScheduledOperation use the scheduled operations for a more accurate creation
* @param iRemovePreviousBudget remove existing budget for @param iYear
* @return an object managing the error
* @see SKGError
*/
static SKGError createAutomaticBudget(SKGDocumentBank* iDocument, int iYear, int iBaseYear, bool iUseScheduledOperation, bool iRemovePreviousBudget);
/**
* Create automatically budget items based on existing operations
* @param iDocument the document where to create*
* @param iYear year of budget
* @param iMonth month of the budget. 0 to balance all months. -1 to balance any month
* @param iBalanceYear to balance the year
* @return an object managing the error
* @see SKGError
*/
static SKGError balanceBudget(SKGDocumentBank* iDocument, int iYear, int iMonth = 0, bool iBalanceYear = true);
private:
QString getWhereclauseId() const override;
};
/**
* Declare the class
*/
Q_DECLARE_TYPEINFO(SKGBudgetObject, Q_MOVABLE_TYPE);
#endif
diff --git a/skgbankmodeler/skgbudgetruleobject.cpp b/skgbankmodeler/skgbudgetruleobject.cpp
index 4bdc2782c..d09f4e73d 100644
--- a/skgbankmodeler/skgbudgetruleobject.cpp
+++ b/skgbankmodeler/skgbudgetruleobject.cpp
@@ -1,234 +1,234 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+* along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file defines classes SKGBudgetRuleObject.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgbudgetruleobject.h"
#include <klocalizedstring.h>
#include "skgbudgetobject.h"
#include "skgcategoryobject.h"
#include "skgdocumentbank.h"
#include "skgtraces.h"
#include "skgtransactionmng.h"
SKGBudgetRuleObject::SKGBudgetRuleObject()
: SKGBudgetRuleObject(nullptr)
{}
SKGBudgetRuleObject::SKGBudgetRuleObject(SKGDocument* iDocument, int iID)
: SKGObjectBase(iDocument, QStringLiteral("v_budgetrule"), iID)
{}
SKGBudgetRuleObject::~SKGBudgetRuleObject()
= default;
SKGBudgetRuleObject::SKGBudgetRuleObject(const SKGBudgetRuleObject& iObject)
= default;
SKGBudgetRuleObject::SKGBudgetRuleObject(const SKGObjectBase& iObject)
{
if (iObject.getRealTable() == QStringLiteral("budgetrule")) {
copyFrom(iObject);
} else {
*this = SKGObjectBase(iObject.getDocument(), QStringLiteral("v_budgetrule"), iObject.getID());
}
}
SKGBudgetRuleObject& SKGBudgetRuleObject::operator= (const SKGObjectBase& iObject)
{
copyFrom(iObject);
return *this;
}
SKGError SKGBudgetRuleObject::enableYearCondition(bool iEnable)
{
return setAttribute(QStringLiteral("t_year_condition"), iEnable ? QStringLiteral("Y") : QStringLiteral("N"));
}
bool SKGBudgetRuleObject::isYearConditionEnabled() const
{
return (getAttribute(QStringLiteral("t_year_condition")) == QStringLiteral("Y"));
}
SKGError SKGBudgetRuleObject::enableMonthCondition(bool iEnable)
{
return setAttribute(QStringLiteral("t_month_condition"), iEnable ? QStringLiteral("Y") : QStringLiteral("N"));
}
bool SKGBudgetRuleObject::isMonthConditionEnabled() const
{
return (getAttribute(QStringLiteral("t_month_condition")) == QStringLiteral("Y"));
}
SKGError SKGBudgetRuleObject::enableCategoryCondition(bool iEnable)
{
return setAttribute(QStringLiteral("t_category_condition"), iEnable ? QStringLiteral("Y") : QStringLiteral("N"));
}
bool SKGBudgetRuleObject::isCategoryConditionEnabled() const
{
return (getAttribute(QStringLiteral("t_category_condition")) == QStringLiteral("Y"));
}
SKGError SKGBudgetRuleObject::setBudgetYear(int iYear)
{
return setAttribute(QStringLiteral("i_year"), SKGServices::intToString(iYear));
}
int SKGBudgetRuleObject::getBudgetYear() const
{
return SKGServices::stringToInt(getAttribute(QStringLiteral("i_year")));
}
SKGError SKGBudgetRuleObject::setBudgetMonth(int iMonth)
{
return setAttribute(QStringLiteral("i_month"), SKGServices::intToString(iMonth));
}
int SKGBudgetRuleObject::getBudgetMonth() const
{
return SKGServices::stringToInt(getAttribute(QStringLiteral("i_month")));
}
SKGError SKGBudgetRuleObject::setBudgetCategory(const SKGCategoryObject& iCategory)
{
return setAttribute(QStringLiteral("rc_category_id"), SKGServices::intToString(iCategory.getID()));
}
SKGError SKGBudgetRuleObject::getBudgetCategory(SKGCategoryObject& oCategory) const
{
return getDocument()->getObject(QStringLiteral("v_category"), "id=" % getAttribute(QStringLiteral("rc_category_id")), oCategory);
}
SKGError SKGBudgetRuleObject::removeBudgetCategory()
{
return setAttribute(QStringLiteral("rc_category_id"), QStringLiteral("0"));
}
SKGError SKGBudgetRuleObject::setCondition(SKGBudgetRuleObject::Condition iCondition)
{
return setAttribute(QStringLiteral("i_condition"), SKGServices::intToString(static_cast<int>(iCondition)));
}
SKGBudgetRuleObject::Condition SKGBudgetRuleObject::getCondition() const
{
return static_cast<SKGBudgetRuleObject::Condition>(SKGServices::stringToInt(getAttribute(QStringLiteral("i_condition"))));
}
SKGError SKGBudgetRuleObject::setQuantity(double iQuantity, bool iAbsolute)
{
SKGError err = setAttribute(QStringLiteral("f_quantity"), SKGServices::doubleToString(iQuantity));
IFOKDO(err, setAttribute(QStringLiteral("t_absolute"), iAbsolute ? QStringLiteral("Y") : QStringLiteral("N")))
return err;
}
double SKGBudgetRuleObject::getQuantity() const
{
return SKGServices::stringToDouble(getAttribute(QStringLiteral("f_quantity")));
}
bool SKGBudgetRuleObject::isAbolute() const
{
return getAttribute(QStringLiteral("t_absolute")) != QStringLiteral("N");
}
SKGError SKGBudgetRuleObject::enableCategoryChange(bool iEnable)
{
return setAttribute(QStringLiteral("t_category_target"), iEnable ? QStringLiteral("Y") : QStringLiteral("N"));
}
bool SKGBudgetRuleObject::isCategoryChangeEnabled() const
{
return getAttribute(QStringLiteral("t_category_target")) == QStringLiteral("Y");
}
SKGError SKGBudgetRuleObject::setTransfer(SKGBudgetRuleObject::Mode iMode, const SKGCategoryObject& iCategory)
{
SKGError err = setAttribute(QStringLiteral("t_rule"), iMode == NEXT ? QStringLiteral("N") : iMode == CURRENT ? QStringLiteral("C") : QStringLiteral("Y"));
IFOKDO(err, setAttribute(QStringLiteral("rc_category_id_target"), SKGServices::intToString(iCategory.getID())))
return err;
}
SKGBudgetRuleObject::Mode SKGBudgetRuleObject::getTransferMode() const
{
return (getAttribute(QStringLiteral("t_rule")) == QStringLiteral("N") ? NEXT : (getAttribute(QStringLiteral("t_rule")) == QStringLiteral("C") ? CURRENT : YEAR));
}
SKGError SKGBudgetRuleObject::getTransferCategory(SKGCategoryObject& oCategory) const
{
return getDocument()->getObject(QStringLiteral("v_category"), "id=" % getAttribute(QStringLiteral("rc_category_id_target")), oCategory);
}
SKGError SKGBudgetRuleObject::processAllRules(SKGDocumentBank* iDocument)
{
SKGError err;
SKGTRACEINFUNCRC(10, err)
if (iDocument != nullptr) {
// Initialize
err = iDocument->executeSqliteOrder(QStringLiteral("UPDATE budget SET f_budgeted_modified=f_budgeted WHERE f_budgeted_modified!=f_budgeted"));
IFOKDO(err, iDocument->executeSqliteOrder(QStringLiteral("UPDATE budget SET f_transferred=0 WHERE f_transferred!=0")))
// Get budgets ordered by date
SKGObjectBase::SKGListSKGObjectBase budgets;
IFOKDO(err, iDocument->getObjects(QStringLiteral("vm_budget_tmp"), QStringLiteral("length(t_RULES)>0 "
"AND (t_PERIOD<=STRFTIME('%Y-%m', date('now')) OR t_PERIOD=STRFTIME('%Y', date('now'))) "
"ORDER BY t_PERIOD, id"), budgets));
int nb = budgets.count();
if (!err && nb > 0) {
err = iDocument->beginTransaction("#INTERNAL#" % i18nc("Progression step", "Apply rules"), nb);
for (int i = 0; !err && i < nb; ++i) {
SKGBudgetObject bud(budgets.at(i));
err = bud.load(); // Reload to be sure that delta has been updated
IFOKDO(err, bud.process())
IFOKDO(err, iDocument->stepForward(i + 1))
}
IFOKDO(err, iDocument->setParameter(QStringLiteral("SKG_LAST_BUDGET_PROCESSING"), QDate::currentDate().toString(QStringLiteral("yyyy-MM-dd"))))
SKGENDTRANSACTION(iDocument, err)
}
}
return err;
}
SKGError SKGBudgetRuleObject::setOrder(double iOrder)
{
SKGError err;
double order = iOrder;
if (order == -1) {
order = 1;
SKGStringListList result;
err = getDocument()->executeSelectSqliteOrder(QStringLiteral("SELECT max(f_sortorder) from budgetrule"), result);
if (!err && result.count() == 2) {
order = SKGServices::stringToDouble(result.at(1).at(0)) + 1;
}
}
IFOKDO(err, setAttribute(QStringLiteral("f_sortorder"), SKGServices::doubleToString(order)))
return err;
}
double SKGBudgetRuleObject::getOrder() const
{
return SKGServices::stringToDouble(getAttribute(QStringLiteral("f_sortorder")));
}
diff --git a/skgbankmodeler/skgbudgetruleobject.h b/skgbankmodeler/skgbudgetruleobject.h
index 112a9eb84..504cfc9a2 100644
--- a/skgbankmodeler/skgbudgetruleobject.h
+++ b/skgbankmodeler/skgbudgetruleobject.h
@@ -1,289 +1,289 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGBUDGETRULEOBJECTT_H
#define SKGBUDGETRULEOBJECTT_H
/** @file
* This file defines classes SKGBudgetRuleObject.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgbankmodeler_export.h"
#include "skgcategoryobject.h"
#include "skgerror.h"
#include "skgobjectbase.h"
class SKGDocumentBank;
/**
* This class is a budget rule
*/
class SKGBANKMODELER_EXPORT SKGBudgetRuleObject final : public SKGObjectBase
{
Q_OBJECT
public:
/**
* Condition
*/
enum Condition {NEGATIVE = -1,
ALL = 0,
POSITIVE = 1
};
/**
* Condition
*/
Q_ENUM(Condition)
/**
* Mode
*/
enum Mode {NEXT,
CURRENT,
YEAR
};
/**
* Mode
*/
Q_ENUM(Mode)
/**
* Default constructor
*/
explicit SKGBudgetRuleObject();
/**
* Constructor
* @param iDocument the document containing the object
* @param iID the identifier in @p iTable of the object
*/
explicit SKGBudgetRuleObject(SKGDocument* iDocument, int iID = 0);
/**
* Destructor
*/
~SKGBudgetRuleObject() override;
/**
* Copy constructor
* @param iObject the object to copy
*/
SKGBudgetRuleObject(const SKGBudgetRuleObject& iObject);
/**
* Copy constructor
* @param iObject the object to copy
*/
explicit SKGBudgetRuleObject(const SKGObjectBase& iObject);
/**
* Operator affectation
* @param iObject the object to copy
*/
SKGBudgetRuleObject& operator= (const SKGObjectBase& iObject);
/**
* Enable / disable condition on year of the budget
* @param iEnable condition
* @return an object managing the error
* @see SKGError
*/
SKGError enableYearCondition(bool iEnable);
/**
* To know if condition on year is enabled or disabled
* @return condition
*/
bool isYearConditionEnabled() const;
/**
* Set year of the condition of the rule
* @param iYear the year (0=all year)
* @return an object managing the error
* @see SKGError
*/
SKGError setBudgetYear(int iYear);
/**
* Get year of the condition of the rule
* @return year of the condition of the rule
*/
int getBudgetYear() const;
/**
* Enable / disable condition on month of the budget
* @param iEnable condition
* @return an object managing the error
* @see SKGError
*/
SKGError enableMonthCondition(bool iEnable);
/**
* To know if condition on month is enabled or disabled
* @return condition
*/
bool isMonthConditionEnabled() const;
/**
* Set month of the condition of the rule
* @param iMonth the month
* @return an object managing the error
* @see SKGError
*/
SKGError setBudgetMonth(int iMonth);
/**
* Get month of the condition of the rule
* @return month of the budget
*/
int getBudgetMonth() const;
/**
* Enable / disable condition on category of the budget
* @param iEnable condition
* @return an object managing the error
* @see SKGError
*/
SKGError enableCategoryCondition(bool iEnable);
/**
* To know if condition on category is enabled or disabled
* @return condition
*/
bool isCategoryConditionEnabled() const;
/**
* Set the category of the condition of the rule
* @param iCategory the category
* @return an object managing the error
* @see SKGError
*/
SKGError setBudgetCategory(const SKGCategoryObject& iCategory);
/**
* Remove the category of the condition of the rule
* @return an object managing the error
* @see SKGError
*/
SKGError removeBudgetCategory();
/**
* Get the category of the condition of the rule
* @param oCategory the category
* @return an object managing the error
* @see SKGError
*/
SKGError getBudgetCategory(SKGCategoryObject& oCategory) const;
/**
* Set the condition when the rule must be applied
* @param iCondition the condition
* @return an object managing the error
* @see SKGError
*/
SKGError setCondition(SKGBudgetRuleObject::Condition iCondition);
/**
* Get the condition when the rule must be applied
* @return the condition
*/
SKGBudgetRuleObject::Condition getCondition() const;
/**
* Set the quantity to transfer
* @param iQuantity quantity
* @param iAbsolute true means "an amount in primary unit", false means "a percentage"
* @return an object managing the error
* @see SKGError
*/
SKGError setQuantity(double iQuantity, bool iAbsolute);
/**
* Get quantity to transfer
* @return quantity to transfer
*/
double getQuantity() const;
/**
* To know if the quantity is an amount or a percentage
* @return true means "an amount in primary unit", false means "a percentage"
*/
bool isAbolute() const;
/**
* Enable / disable transfer change the category of the budget
* @param iEnable condition
* @return an object managing the error
* @see SKGError
*/
SKGError enableCategoryChange(bool iEnable);
/**
* To know if transfer change the category
* @return transfer change the category
*/
bool isCategoryChangeEnabled() const;
/**
* Set the transfer to apply
* @param iMode the mode (NEXT=same category but for following budget, CURRENT=same period but for another category, YEAR=period of same year)
* @param iCategory the category
* @return an object managing the error
* @see SKGError
*/
SKGError setTransfer(SKGBudgetRuleObject::Mode iMode, const SKGCategoryObject& iCategory = SKGCategoryObject());
/**
* Get the mode of the transfer
* @return the mode
*/
SKGBudgetRuleObject::Mode getTransferMode() const;
/**
* Get the category of the transfer of the rule
* @param oCategory the category
* @return an object managing the error
* @see SKGError
*/
SKGError getTransferCategory(SKGCategoryObject& oCategory) const;
/**
* Set the order for the rule
* @param iOrder the order. (-1 means "at the end")
* @return an object managing the error
* @see SKGError
*/
SKGError setOrder(double iOrder);
/**
* Get the order for the rule
* @return the order
*/
double getOrder() const;
/**
* Process all rules
* @param iDocument the document containing the object
* @return an object managing the error
* @see SKGError
*/
static SKGError processAllRules(SKGDocumentBank* iDocument);
};
/**
* Declare the class
*/
Q_DECLARE_TYPEINFO(SKGBudgetRuleObject, Q_MOVABLE_TYPE);
#endif
diff --git a/skgbankmodeler/skgcategoryobject.cpp b/skgbankmodeler/skgcategoryobject.cpp
index 474b6618f..c119194e1 100644
--- a/skgbankmodeler/skgcategoryobject.cpp
+++ b/skgbankmodeler/skgcategoryobject.cpp
@@ -1,310 +1,310 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file implements classes SKGCategoryObject.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgcategoryobject.h"
#include <klocalizedstring.h>
#include "skgdocumentbank.h"
#include "skgsuboperationobject.h"
#include "skgtraces.h"
SKGCategoryObject::SKGCategoryObject() : SKGCategoryObject(nullptr)
{}
SKGCategoryObject::SKGCategoryObject(SKGDocument* iDocument, int iID) : SKGNamedObject(iDocument, QStringLiteral("v_category"), iID)
{}
SKGCategoryObject::~SKGCategoryObject()
= default;
SKGCategoryObject::SKGCategoryObject(const SKGCategoryObject& iObject) = default;
SKGCategoryObject::SKGCategoryObject(const SKGObjectBase& iObject)
{
if (iObject.getRealTable() == QStringLiteral("category")) {
copyFrom(iObject);
} else {
*this = SKGNamedObject(iObject.getDocument(), QStringLiteral("v_category"), iObject.getID());
}
}
SKGCategoryObject& SKGCategoryObject::operator= (const SKGObjectBase& iObject)
{
copyFrom(iObject);
return *this;
}
SKGError SKGCategoryObject::setName(const QString& iName)
{
SKGError err;
if (iName.contains(OBJECTSEPARATOR)) {
err = SKGError(ERR_FAIL, i18nc("Error message", "Invalid name '%1' because of the name cannot contain '%2'", iName, QString(OBJECTSEPARATOR)));
} else {
err = SKGNamedObject::setName(iName);
}
return err;
}
QString SKGCategoryObject::getWhereclauseId() const
{
// Could we use the id
QString output = SKGObjectBase::getWhereclauseId(); // clazy:exclude=skipped-base-method
if (output.isEmpty()) {
if (!(getAttribute(QStringLiteral("t_name")).isEmpty())) {
output = "t_name='" % SKGServices::stringToSqlString(getAttribute(QStringLiteral("t_name"))) % '\'';
}
QString rd_category_id = getAttribute(QStringLiteral("rd_category_id"));
if (!output.isEmpty()) {
output += QStringLiteral(" AND ");
}
if (rd_category_id.isEmpty()) {
output += QStringLiteral("(rd_category_id=0 OR rd_category_id IS NULL OR rd_category_id='')");
} else {
output += "rd_category_id=" % rd_category_id;
}
}
return output;
}
QString SKGCategoryObject::getFullName() const
{
return getAttribute(QStringLiteral("t_fullname"));
}
SKGError SKGCategoryObject::createPathCategory(SKGDocumentBank* iDocument,
const QString& iFullPath,
SKGCategoryObject& oCategory,
bool iSendPopupMessageOnCreation,
bool iRenameIfAlreadyExist)
{
SKGError err;
SKGTRACEINFUNCRC(10, err)
// Check if category is already existing
if (iFullPath.isEmpty()) {
oCategory = SKGCategoryObject(nullptr, 0);
} else if (iDocument != nullptr) {
if (!iRenameIfAlreadyExist) {
iDocument->getObject(QStringLiteral("v_category"), "t_fullname='" % SKGServices::stringToSqlString(iFullPath) % '\'', oCategory);
} else {
oCategory.resetID();
}
if (oCategory.getID() == 0) {
// No, we have to create it
// Search category separator
int posSeparator = iFullPath.lastIndexOf(OBJECTSEPARATOR);
if (posSeparator == -1) {
oCategory = SKGCategoryObject(iDocument);
err = oCategory.setName(iFullPath);
// Check if already existing
if (!err && iRenameIfAlreadyExist) {
int index = 1;
while (!err && oCategory.exist()) {
index++;
err = oCategory.setName(iFullPath % " (" % SKGServices::intToString(index) % ')');
}
}
IFOKDO(err, oCategory.save())
} else {
// Get first and second parts of the branch
QString first = iFullPath.mid(0, posSeparator);
QString second = iFullPath.mid(posSeparator + QString(OBJECTSEPARATOR).length(), iFullPath.length() - posSeparator - QString(OBJECTSEPARATOR).length());
// Get first category
SKGCategoryObject FirstCategory;
err = SKGCategoryObject::createPathCategory(iDocument, first, FirstCategory);
IFOK(err) {
// Get second category
err = FirstCategory.addCategory(oCategory);
// Add second under first
IFOKDO(err, oCategory.setName(second))
// Check if already existing
if (!err && iRenameIfAlreadyExist) {
int index = 2;
while (!err && oCategory.exist()) {
err = oCategory.setName(second % " (" % SKGServices::intToString(index) % ')');
++index;
}
}
// save
IFOKDO(err, oCategory.save())
}
}
if (!err && iSendPopupMessageOnCreation) {
iDocument->sendMessage(i18nc("Information message", "The category '%1' has been created", iFullPath), SKGDocument::Positive);
}
}
}
return err;
}
SKGError SKGCategoryObject::addCategory(SKGCategoryObject& oCategory)
{
SKGError err;
SKGTRACEINFUNCRC(10, err)
if (getID() == 0) {
err = SKGError(ERR_FAIL, i18nc("Error message", "%1 failed because linked object is not yet saved in the database.", QStringLiteral("SKGCategoryObject::addCategory")));
} else {
oCategory = SKGCategoryObject(qobject_cast<SKGDocumentBank*>(getDocument()));
err = oCategory.setAttribute(QStringLiteral("rd_category_id"), SKGServices::intToString(getID()));
}
return err;
}
SKGError SKGCategoryObject::setParentCategory(const SKGCategoryObject& iCategory)
{
SKGError err;
SKGTRACEINFUNCRC(10, err)
if (iCategory.getID() == 0) {
err = SKGError(ERR_FAIL, i18nc("Error message", "%1 failed because linked object is not yet saved in the database.", QStringLiteral("SKGCategoryObject::setParentCategory")));
} else {
// Check if it is a loop
SKGCategoryObject current = iCategory;
do {
if (current == *this) {
err = SKGError(ERR_FAIL, i18nc("Error message", "You cannot create a loop."));
} else {
SKGCategoryObject parent2;
current.getParentCategory(parent2);
current = parent2;
}
} while (!err && current.getID() != 0);
IFOKDO(err, setAttribute(QStringLiteral("rd_category_id"), SKGServices::intToString(iCategory.getID())))
}
return err;
}
SKGError SKGCategoryObject::removeParentCategory()
{
return setAttribute(QStringLiteral("rd_category_id"), QStringLiteral("0"));
}
SKGError SKGCategoryObject::getParentCategory(SKGCategoryObject& oCategory) const
{
SKGError err;
QString parent_id = getAttribute(QStringLiteral("rd_category_id"));
if (!parent_id.isEmpty() && parent_id != QStringLiteral("0")) {
err = getDocument()->getObject(QStringLiteral("v_category"), "id=" % parent_id, oCategory);
}
return err;
}
SKGError SKGCategoryObject::getRootCategory(SKGCategoryObject& oCategory) const
{
SKGError err;
SKGCategoryObject parent2;
err = getParentCategory(parent2);
IFOK(err) {
if (!parent2.exist()) {
// No parent
oCategory = *this;
} else {
// Parent exist
err = parent2.getRootCategory(oCategory);
}
}
return err;
}
SKGError SKGCategoryObject::getCategories(SKGListSKGObjectBase& oCategoryList) const
{
return getDocument()->getObjects(QStringLiteral("v_category"),
"rd_category_id=" % SKGServices::intToString(getID()),
oCategoryList);
}
double SKGCategoryObject::getCurrentAmount() const
{
QString v = getAttribute(QStringLiteral("f_SUMCURRENTAMOUNT"));
if (v.isEmpty()) {
SKGNamedObject cat(getDocument(), QStringLiteral("v_category_display"), getID());
v = cat.getAttribute(QStringLiteral("f_SUMCURRENTAMOUNT"));
}
return SKGServices::stringToDouble(v);
}
SKGError SKGCategoryObject::getSubOperations(SKGListSKGObjectBase& oSubOperations) const
{
SKGError err = getDocument()->getObjects(QStringLiteral("v_suboperation"),
"r_category_id=" % SKGServices::intToString(getID()),
oSubOperations);
return err;
}
SKGError SKGCategoryObject::bookmark(bool iBookmark)
{
return setAttribute(QStringLiteral("t_bookmarked"), iBookmark ? QStringLiteral("Y") : QStringLiteral("N"));
}
bool SKGCategoryObject::isBookmarked() const
{
return (getAttribute(QStringLiteral("t_bookmarked")) == QStringLiteral("Y"));
}
SKGError SKGCategoryObject::setClosed(bool iClosed)
{
return setAttribute(QStringLiteral("t_close"), iClosed ? QStringLiteral("Y") : QStringLiteral("N"));
}
bool SKGCategoryObject::isClosed() const
{
return (getAttribute(QStringLiteral("t_close")) == QStringLiteral("Y"));
}
SKGError SKGCategoryObject::merge(const SKGCategoryObject& iCategory)
{
SKGError err;
SKGObjectBase::SKGListSKGObjectBase ops;
IFOKDO(err, iCategory.getSubOperations(ops))
int nb = ops.count();
for (int i = 0; !err && i < nb; ++i) {
SKGSubOperationObject op(ops.at(i));
err = op.setCategory(*this);
IFOKDO(err, op.save(true, false))
}
SKGObjectBase::SKGListSKGObjectBase cats;
IFOKDO(err, iCategory.getCategories(cats))
nb = cats.count();
for (int i = 0; !err && i < nb; ++i) {
SKGCategoryObject cat(cats.at(i));
err = cat.setParentCategory(*this);
IFOKDO(err, cat.save(true, false))
}
IFOKDO(err, iCategory.remove(false))
return err;
}
diff --git a/skgbankmodeler/skgcategoryobject.h b/skgbankmodeler/skgcategoryobject.h
index 695ee88f0..001b528ad 100644
--- a/skgbankmodeler/skgcategoryobject.h
+++ b/skgbankmodeler/skgcategoryobject.h
@@ -1,214 +1,214 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGCATEGORYOBJECT_H
#define SKGCATEGORYOBJECT_H
/** @file
* This file defines classes SKGCategoryObject.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgbankmodeler_export.h"
#include "skgnamedobject.h"
class SKGDocumentBank;
/**
* This class manages category object
*/
class SKGBANKMODELER_EXPORT SKGCategoryObject final : public SKGNamedObject
{
Q_OBJECT
public:
/**
* Default constructor
*/
explicit SKGCategoryObject();
/**
* Constructor
* @param iDocument the document containing the object
* @param iID the identifier in @p iTable of the object
*/
explicit SKGCategoryObject(SKGDocument* iDocument, int iID = 0);
/**
* Copy constructor
* @param iObject the object to copy
*/
SKGCategoryObject(const SKGCategoryObject& iObject);
/**
* Copy constructor
* @param iObject the object to copy
*/
explicit SKGCategoryObject(const SKGObjectBase& iObject);
/**
* Operator affectation
* @param iObject the object to copy
*/
SKGCategoryObject& operator= (const SKGObjectBase& iObject);
/**
* Destructor
*/
~SKGCategoryObject() override;
/**
* Create a category branch if needed and return the leaf of the branch
* @param iDocument the document where to create
* @param iFullPath the full path. Example: cat1 > cat2 > cat3
* @param oCategory the leaf of the branch
* @param iSendPopupMessageOnCreation to send a creation message if the category is created
* @param iRenameIfAlreadyExist if a leaf with the expected name already exist than the leaf will be renamed and created
* @return an object managing the error.
* @see SKGError
*/
static SKGError createPathCategory(SKGDocumentBank* iDocument,
const QString& iFullPath,
SKGCategoryObject& oCategory,
bool iSendPopupMessageOnCreation = false,
bool iRenameIfAlreadyExist = false);
/**
* Set the name of this object
* @param iName the name
* @return an object managing the error
* @see SKGError
*/
SKGError setName(const QString& iName) override;
/**
* To bookmark or not a category
* @param iBookmark the bookmark: true or false
* @return an object managing the error
* @see SKGError
*/
SKGError bookmark(bool iBookmark);
/**
* To know if the category is bookmarked
* @return an object managing the error
* @see SKGError
*/
bool isBookmarked() const;
/**
* To set the closed attribute of a payee
* @param iClosed the closed attribute: true or false
* @return an object managing the error
* @see SKGError
*/
virtual SKGError setClosed(bool iClosed);
/**
* To know if the payee has been closed or not
* @return an object managing the error
* @see SKGError
*/
virtual bool isClosed() const;
/**
* Get the full name of this category.
* The full name is the unique name of the category.
* It is computed by the concatenation of names for all
* the fathers of this category.
* @return the full name
*/
QString getFullName() const;
/**
* Add a category
* @param oCategory the created category
* @return an object managing the error.
* @see SKGError
*/
SKGError addCategory(SKGCategoryObject& oCategory);
/**
* Move the category by changing the parent
* @param iCategory the parent category
* @return an object managing the error.
* @see SKGError
*/
SKGError setParentCategory(const SKGCategoryObject& iCategory);
/**
* Remove the parent category. The category will be a root.
* @return an object managing the error.
* @see SKGError
*/
SKGError removeParentCategory();
/**
* Get the parent category
* @param oCategory the parent category
* @return an object managing the error.
* @see SKGError
*/
SKGError getParentCategory(SKGCategoryObject& oCategory) const;
/**
* Get the root category
* @param oCategory the root category
* @return an object managing the error.
* @see SKGError
*/
SKGError getRootCategory(SKGCategoryObject& oCategory) const;
/**
* Get categories
* @param oCategoryList the list of categories under the current one
* @return an object managing the error
* @see SKGError
*/
SKGError getCategories(SKGListSKGObjectBase& oCategoryList) const;
/**
* Get the current amount
* @return the current amount
*/
double getCurrentAmount() const;
/**
* Get all sub operations of this category
* @param oSubOperations all sub operations of this category
* @return an object managing the error
* @see SKGError
*/
SKGError getSubOperations(SKGListSKGObjectBase& oSubOperations) const;
/**
* Merge iCategory in current category
* @param iCategory the category. All sub operations will be transferred into this category. The category will be removed
* @return an object managing the error
* @see SKGError
*/
SKGError merge(const SKGCategoryObject& iCategory);
protected:
/**
* Get where clause needed to identify objects.
* For this class, the whereclause is based on name + rd_category_id
* @return the where clause
*/
QString getWhereclauseId() const override;
};
/**
* Declare the class
*/
Q_DECLARE_TYPEINFO(SKGCategoryObject, Q_MOVABLE_TYPE);
#endif
diff --git a/skgbankmodeler/skgdefinebank.h b/skgbankmodeler/skgdefinebank.h
index f2acb66d4..1762879d2 100644
--- a/skgbankmodeler/skgdefinebank.h
+++ b/skgbankmodeler/skgdefinebank.h
@@ -1,74 +1,74 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGDEFINEBANK_H
#define SKGDEFINEBANK_H
/** @file
* This file defines some macros and constants.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgdefine.h"
/**
* @var DUMPUNIT
* To display units and values
* @see dump
*/
static const int DUMPUNIT = (2u << 10);
/**
* @var DUMPACCOUNT
* To display accounts
* @see dump
*/
static const int DUMPACCOUNT = (2u << 11);
/**
* @var DUMPOPERATION
* To display accounts
* @see dump
*/
static const int DUMPOPERATION = (2u << 12);
/**
* @var DUMPCATEGORY
* To display categories
* @see dump
*/
static const int DUMPCATEGORY = (2u << 13);
/**
* @var DUMPPAYEE
* To display payees
* @see dump
*/
static const int DUMPPAYEE = (2u << 14);
/**
* @var DUMPBUDGET
* To display payees
* @see dump
*/
static const int DUMPBUDGET = (2u << 15);
/**
* @var DUMPBANKOBJECT
* To display categories
* @see dump
*/
static const int DUMPBANKOBJECT = DUMPUNIT | DUMPACCOUNT | DUMPOPERATION | DUMPCATEGORY | DUMPPAYEE | DUMPBUDGET;
#endif
diff --git a/skgbankmodeler/skgdocumentbank.cpp b/skgbankmodeler/skgdocumentbank.cpp
index c699f274b..72cd738c5 100644
--- a/skgbankmodeler/skgdocumentbank.cpp
+++ b/skgbankmodeler/skgdocumentbank.cpp
@@ -1,3461 +1,3461 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file implements classes SKGDocumentBank.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgdocumentbank.h"
#include <qdbusconnection.h>
#include <qicon.h>
#include <qlocale.h>
#include <qsqldatabase.h>
#include <cmath>
#include "skgaccountobject.h"
#include "skgbankobject.h"
#include "skgerror.h"
#include "skgreportbank.h"
#include "skgservices.h"
#include "skgtraces.h"
#include "skgtransactionmng.h"
#include "skgunitobject.h"
#include "skgunitvalueobject.h"
SKGDocumentBank::SKGDocumentBank() : SKGDocument()
{
SKGTRACEINFUNC(10)
connect(this, &SKGDocumentBank::tableModified, this, &SKGDocumentBank::refreshCache);
QDBusConnection dbus = QDBusConnection::sessionBus();
dbus.registerObject(QStringLiteral("/skrooge/skgdocumentbank"), this, QDBusConnection::ExportAllContents);
// Initialisation of not undoable tables
SKGListNotUndoable.push_back(QStringLiteral("T.operationbalance"));
SKGListNotUndoable.push_back(QStringLiteral("T.budgetsuboperation"));
}
SKGDocumentBank::~SKGDocumentBank()
{
SKGTRACEINFUNC(10)
}
SKGError SKGDocumentBank::computeBudgetSuboperationLinks() const
{
SKGError err;
SKGTRACEINFUNCRC(5, err)
// Remove computed values
err = this->executeSqliteOrder(QStringLiteral("DELETE FROM budgetsuboperation"));
// Compute values
IFOKDO(err, executeSqliteOrder(
"INSERT INTO budgetsuboperation (id, id_suboperation, i_priority) "
// Garbage collector annualy
"SELECT b.id, s.id, 6.0 FROM budget b, operation o, suboperation s WHERE +s.rd_operation_id=o.id AND b.rc_category_id=0 AND b.i_month=0 AND b.i_year=STRFTIME('%Y', IFNULL(s.d_date, o.d_date))"
// Garbage collectory monthly
" UNION SELECT b.id, s.id, 5.0 FROM budget b, operation o, suboperation s WHERE +s.rd_operation_id=o.id AND b.rc_category_id=0 AND b.i_month<>0 AND b.i_year=STRFTIME('%Y', IFNULL(s.d_date, o.d_date)) AND b.i_month=STRFTIME('%m', IFNULL(s.d_date, o.d_date))"
// Garbage categories annualy
" UNION SELECT b.id, s.id, 4.0 - (LENGTH(c2.t_fullname)-LENGTH(REPLACE(c2.t_fullname, '" % OBJECTSEPARATOR % "', '')))/(100.0*LENGTH('" % OBJECTSEPARATOR % "')) FROM budget b, operation o, v_suboperation_display s, category c2 WHERE +s.rd_operation_id=o.id AND b.rc_category_id<>0 AND b.i_month=0 AND b.i_year=STRFTIME('%Y', IFNULL(s.d_date, o.d_date)) AND b.t_including_subcategories='Y' AND s.t_CATEGORY LIKE c2.t_fullname||'" % OBJECTSEPARATOR % "%' AND c2.id=b.rc_category_id"
// Garbage categories monthly
" UNION SELECT b.id, s.id, 3.0 - (LENGTH(c2.t_fullname)-LENGTH(REPLACE(c2.t_fullname, '" % OBJECTSEPARATOR % "', '')))/(100.0*LENGTH('" % OBJECTSEPARATOR % "')) FROM budget b, operation o, v_suboperation_display s, category c2 WHERE +s.rd_operation_id=o.id AND b.rc_category_id<>0 AND b.i_month<>0 AND b.i_year=STRFTIME('%Y', IFNULL(s.d_date, o.d_date)) AND b.i_month=STRFTIME('%m', IFNULL(s.d_date, o.d_date)) AND b.t_including_subcategories='Y' AND s.t_CATEGORY LIKE c2.t_fullname||'" % OBJECTSEPARATOR % "%' AND c2.id=b.rc_category_id"
// Strict category annualy
" UNION SELECT b.id, s.id, 2.0 FROM budget b, operation o, v_suboperation_display s WHERE +s.rd_operation_id=o.id AND b.rc_category_id<>0 AND b.i_month=0 AND b.i_year=STRFTIME('%Y', IFNULL(s.d_date, o.d_date)) AND b.rc_category_id=s.r_category_id"
// Strict category monthly
" UNION SELECT b.id, s.id, 1.0 FROM budget b, operation o, v_suboperation_display s WHERE +s.rd_operation_id=o.id AND b.rc_category_id<>0 AND b.i_month<>0 AND b.i_year=STRFTIME('%Y', IFNULL(s.d_date, o.d_date)) AND b.i_month=STRFTIME('%m', IFNULL(s.d_date, o.d_date)) AND +b.rc_category_id=s.r_category_id"));
// Remove useless values
IFOKDO(err, executeSqliteOrder(QStringLiteral("DELETE FROM budgetsuboperation WHERE EXISTS (SELECT 1 FROM budgetsuboperation b2 WHERE b2.id_suboperation=budgetsuboperation.id_suboperation AND b2.i_priority<budgetsuboperation.i_priority)")))
return err;
}
void SKGDocumentBank::setComputeBalances(bool iEnabled)
{
if (iEnabled != m_computeBalances) {
m_computeBalances = iEnabled;
computeBalances();
}
}
SKGError SKGDocumentBank::computeBalances() const
{
SKGError err;
SKGTRACEINFUNCRC(5, err)
// Remove computed values
err = this->executeSqliteOrder(QStringLiteral("DELETE FROM operationbalance"));
if (m_computeBalances) {
SKGStringListList result;
IFOKDO(err, executeSelectSqliteOrder(QStringLiteral("SELECT id, rd_account_id, f_CURRENTAMOUNT, f_QUANTITY FROM v_operation WHERE t_template='N' ORDER BY rd_account_id, d_date, id"), result))
int nb = result.count();
double sum = 0;
double sum2 = 0;
int currentAccount = 0;
QStringList items;
for (int i = 1; !err && i < nb; ++i) { // Ignore header
const QStringList& line = result.at(i);
const QString& idOp = line.at(0);
int account = SKGServices::stringToInt(line.at(1));
double val = SKGServices::stringToDouble(line.at(2));
double val2 = SKGServices::stringToDouble(line.at(3));
if (account != currentAccount) {
sum = 0;
sum2 = 0;
currentAccount = account;
}
sum += val;
sum2 += val2;
items.push_back(idOp % "," % SKGServices::doubleToString(sum) % "," % SKGServices::doubleToString(sum2));
if (items.count() == 490) {
err = this->executeSqliteOrder("INSERT INTO operationbalance (r_operation_id,f_balance,f_balance_entered) "
"SELECT " % items.join(QStringLiteral(" UNION SELECT ")));
items.clear();
}
}
if (!err && !items.isEmpty()) {
err = this->executeSqliteOrder("INSERT INTO operationbalance (r_operation_id,f_balance,f_balance_entered) "
"SELECT " % items.join(QStringLiteral(" UNION SELECT ")));
}
}
return err;
}
SKGError SKGDocumentBank::endTransaction(bool succeedded)
{
SKGError err;
if (succeedded && getDepthTransaction() == 1) {
if (getCachedValue(QStringLiteral("SKG_REFRESH_VIEW")) == QStringLiteral("Y")) {
QStringList listModifiedTables;
err = this->getDistinctValues(QStringLiteral("doctransactionitem"),
QStringLiteral("t_object_table"),
QStringLiteral("rd_doctransaction_id=0"),
listModifiedTables);
if (!err &&
(listModifiedTables.contains(QStringLiteral("operation")) || listModifiedTables.contains(QStringLiteral("suboperation")) || listModifiedTables.contains(QStringLiteral("unit")) || listModifiedTables.contains(QStringLiteral("unitvalue")))
) {
// Computation of cache
err = computeBalances();
}
if (!err &&
(listModifiedTables.contains(QStringLiteral("operation")) || listModifiedTables.contains(QStringLiteral("suboperation")) || listModifiedTables.contains(QStringLiteral("unit")) || listModifiedTables.contains(QStringLiteral("unitvalue")) || listModifiedTables.contains(QStringLiteral("category")) || listModifiedTables.contains(QStringLiteral("budget")))
) {
// Computation of cache
err = computeBudgetSuboperationLinks();
}
}
// Clean main variations cache
m_5mainVariations_cache.clear();
m_5mainVariationsCat_cache.clear();
m_5mainVariations_inputs = QLatin1String("");
}
SKGError err2 = SKGDocument::endTransaction(succeedded);
if (!err && err2) {
err = err2;
}
return err;
}
QString SKGDocumentBank::getViewsIndexesAndTriggersVersion() const
{
return "2019.04.07_" % getParameter(QStringLiteral("SKG_LANGUAGE"));
}
SKGError SKGDocumentBank::refreshViewsIndexesAndTriggers(bool iForce) const
{
SKGError err;
SKGTRACEINFUNCRC(5, err)
QString version = getParameter(QStringLiteral("SKG_DB_BANK_VIEWS_VERSION"));
if (!iForce && version == getViewsIndexesAndTriggersVersion()) {
return err;
}
err = setParameter(QStringLiteral("SKG_DB_BANK_VIEWS_VERSION"), getViewsIndexesAndTriggersVersion());
QString dateFormatShort = QLocale::system().dateFormat(QLocale::ShortFormat);
int firstDayOfWeek = QLocale::system().firstDayOfWeek();
// WARNING: Do not forget to update getViewVersion when this method is modified
/**
* This constant is used to initialized the data model (trigger creation)
* IF YOU MODIFY THIS METHOD, DO NOT FORGET TO MODIFY getViewsIndexesAndTriggersVersion TOO
*/
QStringList BankInitialDataModelTrigger;
BankInitialDataModelTrigger << DELETECASCADEPARAMETER("bank")
<< DELETECASCADEPARAMETER("account")
<< DELETECASCADEPARAMETER("unit")
<< DELETECASCADEPARAMETER("unitvalue")
<< DELETECASCADEPARAMETER("category")
<< DELETECASCADEPARAMETER("operation")
<< DELETECASCADEPARAMETER("interest")
<< DELETECASCADEPARAMETER("suboperation")
<< DELETECASCADEPARAMETER("refund")
<< DELETECASCADEPARAMETER("payee")
<< DELETECASCADEPARAMETER("recurrentoperation")
<< DELETECASCADEPARAMETER("rule")
<< DELETECASCADEPARAMETER("budget")
<< DELETECASCADEPARAMETER("budgetrule")
// Compute fullname
<< QStringLiteral("DROP TRIGGER IF EXISTS cpt_category_fullname3")
/* << "CREATE TRIGGER cpt_category_fullname1 " // This trigger must be the first
"AFTER UPDATE OF t_fullname ON category BEGIN "
"UPDATE category SET t_name=t_name WHERE rd_category_id=new.id;"
"END"*/
<< QStringLiteral("DROP TRIGGER IF EXISTS cpt_category_fullname1")
<< "CREATE TRIGGER cpt_category_fullname1 "
"AFTER INSERT ON category BEGIN "
"UPDATE category SET t_fullname="
"CASE WHEN rd_category_id IS NULL OR rd_category_id='' OR rd_category_id=0 THEN new.t_name ELSE (SELECT c.t_fullname FROM category c WHERE c.id=new.rd_category_id)||'" % OBJECTSEPARATOR % "'||new.t_name END "
"WHERE id=new.id;"
"END"
<< QStringLiteral("DROP TRIGGER IF EXISTS cpt_category_fullname2")
<< "CREATE TRIGGER cpt_category_fullname2 "
"AFTER UPDATE OF t_name, rd_category_id ON category BEGIN "
"UPDATE category SET t_fullname="
"CASE WHEN rd_category_id IS NULL OR rd_category_id='' OR rd_category_id=0 THEN new.t_name ELSE (SELECT c.t_fullname FROM category c WHERE c.id=new.rd_category_id)||'" % OBJECTSEPARATOR % "'||new.t_name END "
"WHERE id=new.id;"
"UPDATE category SET t_name=t_name WHERE rd_category_id=new.id;"
"END"
// -- Reparent suboperation on parent category when a category is removed
<< QStringLiteral("DROP TRIGGER IF EXISTS fkdc_category_delete")
<< "CREATE TRIGGER fkdc_category_delete "
"BEFORE DELETE ON category "
"FOR EACH ROW BEGIN "
" UPDATE suboperation SET r_category_id=OLD.rd_category_id WHERE r_category_id IN (SELECT c.id FROM category c WHERE c.id=OLD.id OR c.t_fullname LIKE OLD.t_fullname||'" % OBJECTSEPARATOR % "%'); "
" UPDATE payee SET r_category_id=0 WHERE r_category_id IN (SELECT c.id FROM category c WHERE c.id=OLD.id OR c.t_fullname LIKE OLD.t_fullname||'" % OBJECTSEPARATOR % "%'); "
"END "
<< QStringLiteral("DROP TRIGGER IF EXISTS fkdc_category_parent_id_category_id")
// Trigger for update on view
<< QStringLiteral("DROP TRIGGER IF EXISTS trgu_v_operation_prop_i_tmp")
<< QStringLiteral("CREATE TRIGGER trgu_v_operation_prop_i_tmp "
"INSTEAD OF UPDATE OF i_tmp ON v_operation_prop "
"FOR EACH ROW BEGIN "
" UPDATE suboperation SET i_tmp=NEW.i_tmp WHERE id=OLD.i_SUBOPID; "
" UPDATE operation SET i_tmp=NEW.i_tmp WHERE id=OLD.i_OPID; "
" UPDATE parameters SET i_tmp=NEW.i_tmp WHERE id=OLD.i_PROPPID; "
"END ")
<< QStringLiteral("DROP TRIGGER IF EXISTS trgu_v_operation_prop_t_realcomment")
<< QStringLiteral("CREATE TRIGGER trgu_v_operation_prop_t_realcomment "
"INSTEAD OF UPDATE OF t_REALCOMMENT ON v_operation_prop "
"FOR EACH ROW BEGIN "
" UPDATE suboperation SET t_comment=NEW.t_REALCOMMENT WHERE id=OLD.i_SUBOPID; "
"END ")
<< QStringLiteral("DROP TRIGGER IF EXISTS trgu_v_operation_prop_t_unit")
<< QStringLiteral("CREATE TRIGGER trgu_v_operation_prop_t_unit "
"INSTEAD OF UPDATE OF t_UNIT ON v_operation_prop "
"FOR EACH ROW BEGIN "
" INSERT OR IGNORE INTO unit (t_name, t_symbol) VALUES (NEW.t_UNIT, NEW.t_UNIT); "
" UPDATE operation set rc_unit_id=(SELECT id FROM unit WHERE t_name=NEW.t_UNIT) WHERE id=OLD.i_OPID; "
"END ")
<< QStringLiteral("DROP TRIGGER IF EXISTS trgu_v_operation_prop_t_account")
<< QStringLiteral("CREATE TRIGGER trgu_v_operation_prop_t_account "
"INSTEAD OF UPDATE OF t_ACCOUNT ON v_operation_prop "
"FOR EACH ROW BEGIN "
" INSERT OR IGNORE INTO account (t_name, rd_bank_id) VALUES (NEW.t_ACCOUNT, (SELECT MIN(id) FROM bank)); "
" UPDATE operation set rd_account_id=(SELECT id FROM account WHERE t_name=NEW.t_ACCOUNT) WHERE id=OLD.i_OPID; "
"END ")
<< QStringLiteral("DROP TRIGGER IF EXISTS trgu_v_operation_prop_t_payee")
<< QStringLiteral("CREATE TRIGGER trgu_v_operation_prop_t_payee "
"INSTEAD OF UPDATE OF t_PAYEE ON v_operation_prop "
"FOR EACH ROW BEGIN "
" INSERT OR IGNORE INTO payee (t_name) VALUES (NEW.t_PAYEE); "
" UPDATE operation set r_payee_id=(SELECT id FROM payee WHERE t_name=NEW.t_PAYEE) WHERE id=OLD.i_OPID; "
"END ")
<< QStringLiteral("DROP TRIGGER IF EXISTS trgu_v_operation_prop_t_realrefund")
<< QStringLiteral("CREATE TRIGGER trgu_v_operation_prop_t_realrefund "
"INSTEAD OF UPDATE OF t_REALREFUND ON v_operation_prop "
"FOR EACH ROW BEGIN "
" INSERT OR IGNORE INTO refund (t_name) VALUES (NEW.t_REALREFUND); "
" UPDATE suboperation set r_refund_id=(SELECT id FROM refund WHERE t_name=NEW.t_REALREFUND) WHERE id=OLD.i_SUBOPID; "
"END ")
<< QStringLiteral("DROP TRIGGER IF EXISTS trgu_v_operation_prop_d_dateop")
<< QStringLiteral("CREATE TRIGGER trgu_v_operation_prop_d_dateop "
"INSTEAD OF UPDATE OF d_DATEOP ON v_operation_prop "
"FOR EACH ROW BEGIN "
" UPDATE suboperation set d_date=date(d_date, '+'||(julianday(NEW.d_DATEOP)-julianday(old.d_DATEOP))||' days') WHERE id=OLD.i_SUBOPID; "
" UPDATE operation set d_date=NEW.d_DATEOP WHERE id=OLD.i_OPID; "
"END ");
// Build triggers for normal attribute
SKGServices::SKGAttributesList attributes;
getAttributesDescription(QStringLiteral("operation"), attributes);
int nb = attributes.count();
for (int i = 0; i < nb; ++i) {
QString att = attributes.at(i).name;
if (att == att.toLower() && att != QStringLiteral("i_tmp")) {
BankInitialDataModelTrigger << QStringLiteral("DROP TRIGGER IF EXISTS trgu_v_operation_prop_") % att
<< "CREATE TRIGGER trgu_v_operation_prop_" % att % " "
"INSTEAD OF UPDATE OF " % att % " ON v_operation_prop "
"FOR EACH ROW BEGIN "
" UPDATE operation SET " % att % "=NEW." % att % " WHERE id=OLD.i_OPID; "
"END ";
}
}
/**
* This constant is used to initialized the data model (index creation)
*/
QStringList BankInitialDataModelIndex;
BankInitialDataModelIndex << QStringLiteral("CREATE UNIQUE INDEX uidx_unit_name ON unit(t_name)")
<< QStringLiteral("CREATE UNIQUE INDEX uidx_unit_symbol ON unit(t_symbol)")
<< QStringLiteral("CREATE INDEX idx_unit_unit_id ON unitvalue(rd_unit_id)")
<< QStringLiteral("CREATE UNIQUE INDEX uidx_unitvalue ON unitvalue(d_date,rd_unit_id)")
<< QStringLiteral("CREATE UNIQUE INDEX uidx_unitvalue2 ON unitvalue(rd_unit_id, d_date)")
<< QStringLiteral("CREATE UNIQUE INDEX uidx_bank_name ON bank(t_name)")
<< QStringLiteral("CREATE UNIQUE INDEX uidx_account_name ON account(t_name)")
<< QStringLiteral("CREATE INDEX idx_account_bank_id ON account(rd_bank_id)")
<< QStringLiteral("CREATE INDEX idx_account_type ON account(t_type)")
<< QStringLiteral("CREATE INDEX idx_category_category_id ON category(rd_category_id)")
<< QStringLiteral("CREATE INDEX idx_category_t_fullname ON category(t_fullname)")
<< QStringLiteral("CREATE INDEX idx_category_close ON category(t_close)")
<< QStringLiteral("CREATE UNIQUE INDEX uidx_category_parent_id_name ON category(t_name,rd_category_id)")
<< QStringLiteral("CREATE INDEX idx_operation_tmp1_found_transfert ON operation (rc_unit_id, d_date)")
<< QStringLiteral("CREATE INDEX idx_operation_grouped_operation_id ON operation (i_group_id)")
// << "CREATE INDEX idx_operation_t_mode ON operation (t_mode)"
// << "CREATE INDEX idx_operation_t_payee ON operation (t_payee)"
<< QStringLiteral("CREATE INDEX idx_operation_t_number ON operation (t_number)")
<< QStringLiteral("CREATE INDEX idx_operation_i_tmp ON operation (i_tmp)")
<< QStringLiteral("CREATE INDEX idx_operation_rd_account_id ON operation (rd_account_id)")
<< QStringLiteral("CREATE INDEX idx_operation_rd_account_id_t_imported ON operation (rd_account_id, t_imported)")
<< QStringLiteral("CREATE INDEX idx_operation_rd_account_id_t_number ON operation (rd_account_id, t_number)")
<< QStringLiteral("CREATE INDEX idx_operation_rc_unit_id ON operation (rc_unit_id)")
<< QStringLiteral("CREATE INDEX idx_operation_t_status ON operation (t_status)")
<< QStringLiteral("CREATE INDEX idx_operation_t_import_id ON operation (t_import_id)")
<< QStringLiteral("CREATE INDEX idx_operation_d_date ON operation (d_date)")
<< QStringLiteral("CREATE INDEX idx_operation_t_template ON operation (t_template)")
<< QStringLiteral("CREATE INDEX idx_operationbalance_operation_id ON operationbalance (r_operation_id)")
<< QStringLiteral("CREATE INDEX idx_suboperation_operation_id ON suboperation (rd_operation_id)")
<< QStringLiteral("CREATE INDEX idx_suboperation_i_tmp ON suboperation (i_tmp)")
<< QStringLiteral("CREATE INDEX idx_suboperation_category_id ON suboperation (r_category_id)")
<< QStringLiteral("CREATE INDEX idx_suboperation_refund_id_id ON suboperation (r_refund_id)")
<< QStringLiteral("CREATE INDEX idx_recurrentoperation_rd_operation_id ON recurrentoperation (rd_operation_id)")
<< QStringLiteral("CREATE UNIQUE INDEX uidx_refund_name ON refund(t_name)")
<< QStringLiteral("CREATE INDEX idx_refund_close ON refund(t_close)")
<< QStringLiteral("CREATE UNIQUE INDEX uidx_payee_name ON payee(t_name)")
<< QStringLiteral("CREATE INDEX idx_payee_close ON payee(t_close)")
<< QStringLiteral("CREATE INDEX idx_interest_account_id ON interest (rd_account_id)")
<< QStringLiteral("CREATE UNIQUE INDEX uidx_interest ON interest(d_date,rd_account_id)")
<< QStringLiteral("CREATE INDEX idx_rule_action_type ON rule(t_action_type)")
<< QStringLiteral("CREATE UNIQUE INDEX uidx_budget ON budget(i_year,i_month, rc_category_id)")
<< QStringLiteral("CREATE INDEX idx_budget_category_id ON budget(rc_category_id)")
<< QStringLiteral("CREATE INDEX idx_budgetsuboperation_id ON budgetsuboperation (id)")
<< QStringLiteral("CREATE INDEX idx_budgetsuboperation_id_suboperation ON budgetsuboperation (id_suboperation)");
/**
* This constant is used to initialized the data model (view creation)
*/
QStringList BankInitialDataModelView;
BankInitialDataModelView
// ==================================================================
// These following views contains only attributes used by corresponding class (better for performances)
// unit
<< QStringLiteral("CREATE VIEW v_unit_displayname AS "
"SELECT *, t_name||' ('||t_symbol||')' AS t_displayname FROM unit")
<< "CREATE VIEW v_unit_tmp1 AS "
"SELECT *,"
"(SELECT COUNT(1) FROM unitvalue s WHERE s.rd_unit_id=unit.id) AS i_NBVALUES, "
"(CASE WHEN unit.rd_unit_id=0 THEN '' ELSE (SELECT (CASE WHEN s.t_symbol!='' THEN s.t_symbol ELSE s.t_name END) FROM unit s WHERE s.id=unit.rd_unit_id) END) AS t_UNIT,"
"(CASE unit.t_type "
"WHEN '1' THEN '" % SKGServices::stringToSqlString(i18nc("Noun", "Primary currency")) % "' "
"WHEN '2' THEN '" % SKGServices::stringToSqlString(i18nc("Noun", "Secondary currency")) % "' "
"WHEN 'C' THEN '" % SKGServices::stringToSqlString(i18nc("Noun, a country's currency", "Currency")) % "' "
"WHEN 'S' THEN '" % SKGServices::stringToSqlString(i18nc("Noun, a financial share, as in a stock market", "Share")) % "' "
"WHEN 'I' THEN '" % SKGServices::stringToSqlString(i18nc("Noun, a financial index like the Dow Jones, NASDAQ, CAC40...", "Index")) % "' "
"ELSE '" % SKGServices::stringToSqlString(i18nc("Noun, a physical object like a house or a car", "Object")) % "' END) AS t_TYPENLS, "
"(SELECT MIN(s.d_date) FROM unitvalue s WHERE s.rd_unit_id=unit.id) AS d_MINDATE, "
"(SELECT MAX(s.d_date) FROM unitvalue s WHERE s.rd_unit_id=unit.id) AS d_MAXDATE "
"FROM unit"
<< QStringLiteral("CREATE VIEW v_unit_tmp2 AS "
"SELECT *,"
"CASE WHEN v_unit_tmp1.t_type='1' THEN 1 ELSE IFNULL((SELECT s.f_quantity FROM unitvalue s INDEXED BY uidx_unitvalue2 WHERE s.rd_unit_id=v_unit_tmp1.id AND s.d_date=v_unit_tmp1.d_MAXDATE),1) END AS f_LASTVALUE "
"FROM v_unit_tmp1")
<< QStringLiteral("CREATE VIEW v_unit AS "
"SELECT *,"
"CASE WHEN v_unit_tmp2.t_type='1' THEN 1 ELSE v_unit_tmp2.f_LASTVALUE*IFNULL((SELECT s2.f_LASTVALUE FROM v_unit_tmp2 s2 WHERE s2.id=v_unit_tmp2.rd_unit_id) , 1) END AS f_CURRENTAMOUNT "
"FROM v_unit_tmp2")
// unitvalue
<< "CREATE VIEW v_unitvalue_displayname AS "
"SELECT *, (SELECT t_displayname FROM v_unit_displayname WHERE unitvalue.rd_unit_id=v_unit_displayname.id)||' '||IFNULL(TOFORMATTEDDATE(d_date,'" % SKGServices::stringToSqlString(dateFormatShort) % "'),STRFTIME('%Y-%m-%d',d_date)) AS t_displayname FROM unitvalue"
<< QStringLiteral("CREATE VIEW v_unitvalue AS "
"SELECT * "
"FROM unitvalue")
// suboperation
<< QStringLiteral("CREATE VIEW v_suboperation AS "
"SELECT * "
"FROM suboperation")
// operation
<< QStringLiteral("CREATE VIEW v_operation_numbers AS "
"SELECT DISTINCT t_number, rd_account_id FROM operation")
<< QStringLiteral("CREATE VIEW v_operation_next_numbers AS "
"SELECT NEXT(T1.t_number) AS t_number, T1.rd_account_id FROM v_operation_numbers AS T1 LEFT OUTER JOIN v_operation_numbers T2 "
"ON T2.rd_account_id=T1.rd_account_id AND T2.t_number=NEXT(T1.t_number) "
"WHERE T1.t_number!='' AND (T2.t_number IS NULL) ORDER BY T1.t_number")
<< QStringLiteral("CREATE VIEW v_operation_tmp1 AS "
"SELECT operation.*,"
"(CASE WHEN v_unit.t_symbol!='' THEN v_unit.t_symbol ELSE v_unit.t_name END) AS t_UNIT,"
"IFNULL((SELECT s.t_name FROM payee s WHERE s.id=operation.r_payee_id), '') AS t_PAYEE,"
"v_unit.i_nbdecimal AS i_NBDEC,"
"v_unit.t_type AS t_TYPEUNIT,"
"v_unit.f_CURRENTAMOUNT AS f_CURRENTAMOUNTUNIT,"
"(SELECT TOTAL(s.f_value) FROM suboperation s WHERE s.rd_operation_id=operation.ID) AS f_QUANTITY,"
"(SELECT COUNT(1) FROM suboperation s WHERE s.rd_operation_id=operation.ID) AS i_NBSUBOPERATIONS, "
"account.t_name AS t_ACCOUNT, "
"account.t_type AS t_TYPEACCOUNT, "
"(CASE WHEN bank.t_name='' THEN '") % i18nc("Noun", "Wallets") % QStringLiteral("' ELSE bank.t_name END) AS t_BANK "
"FROM operation, account, bank, v_unit WHERE +operation.rd_account_id=account.id AND +account.rd_bank_id=bank.id AND +operation.rc_unit_id=v_unit.id")
<< QStringLiteral("CREATE VIEW v_operation AS "
"SELECT *,"
"(SELECT s.id FROM suboperation s WHERE s.rd_operation_id=v_operation_tmp1.id AND ABS(s.f_value)=(SELECT MAX(ABS(s2.f_value)) FROM suboperation s2 WHERE s2.rd_operation_id=v_operation_tmp1.id)) AS i_MOSTIMPSUBOP,"
"v_operation_tmp1.f_CURRENTAMOUNTUNIT*v_operation_tmp1.f_QUANTITY AS f_CURRENTAMOUNT, "
"(CASE WHEN v_operation_tmp1.i_group_id<>0 AND v_operation_tmp1.t_TYPEACCOUNT<>'L' AND v_operation_tmp1.t_TYPEUNIT IN ('1', '2', 'C') AND "
"(SELECT COUNT(1) FROM operation WHERE i_group_id=v_operation_tmp1.i_group_id)=2 AND "
"EXISTS (SELECT 1 FROM v_operation_tmp1 op2 WHERE op2.i_group_id=v_operation_tmp1.i_group_id "
"AND op2.t_TYPEACCOUNT<>'L' AND op2.t_TYPEUNIT IN ('1', '2', 'C') AND op2.f_QUANTITY*v_operation_tmp1.f_QUANTITY<=0) THEN 'Y' ELSE 'N' END) AS t_TRANSFER "
// "ROUND((SELECT s.f_CURRENTAMOUNT FROM v_unit s WHERE s.id=v_operation_tmp1.rc_unit_id)*v_operation_tmp1.f_QUANTITY, 2) AS f_CURRENTAMOUNT "
"FROM v_operation_tmp1")
<< "CREATE VIEW v_operation_displayname AS "
"SELECT *, IFNULL(TOFORMATTEDDATE(d_date,'" % SKGServices::stringToSqlString(dateFormatShort) % "'),STRFTIME('%Y-%m-%d',d_date))||' '||IFNULL(t_PAYEE,'')||' '||TOCURRENCY(v_operation.f_quantity, (SELECT (CASE WHEN s.t_symbol!='' THEN s.t_symbol ELSE s.t_name END) FROM unit s WHERE s.id=v_operation.rc_unit_id)) AS t_displayname FROM v_operation"
<< "CREATE VIEW v_operation_delete AS "
"SELECT *, (CASE WHEN t_status='Y' THEN '" %
SKGServices::stringToSqlString(i18nc("Error message", "You are not authorized to delete this operation because in \"checked\" status")) %
"' END) t_delete_message FROM operation"
// account
<< QStringLiteral("CREATE VIEW v_account AS "
"SELECT "
"account.*,"
"(CASE t_type "
"WHEN 'C' THEN '") % SKGServices::stringToSqlString(i18nc("Adjective, a current account", "Current")) % "' "
"WHEN 'D' THEN '" % SKGServices::stringToSqlString(i18nc("Noun", "Credit card")) % "' "
"WHEN 'A' THEN '" % SKGServices::stringToSqlString(i18nc("Noun, the type of an account", "Assets")) % "' "
"WHEN 'I' THEN '" % SKGServices::stringToSqlString(i18nc("Noun, a type of account WHERE you invest money", "Investment")) % "' "
"WHEN 'W' THEN '" % SKGServices::stringToSqlString(i18nc("Noun, a type of account", "Wallet")) % "' "
"WHEN 'L' THEN '" % SKGServices::stringToSqlString(i18nc("Noun, a type of account", "Loan")) % "' "
"WHEN 'S' THEN '" % SKGServices::stringToSqlString(i18nc("Noun, a type of account", "Saving")) % "' "
"WHEN 'P' THEN '" % SKGServices::stringToSqlString(i18nc("Noun, a type of account", "Pension")) % "' "
"WHEN 'O' THEN '" % SKGServices::stringToSqlString(i18nc("Noun, as in other type of item", "Other")) % "' END) AS t_TYPENLS,"
"(CASE WHEN bank.t_name='' THEN '" % i18nc("Noun", "Wallets") % QStringLiteral("' ELSE bank.t_name END) AS t_BANK,"
"bank.t_bank_number AS t_BANK_NUMBER,"
"bank.t_icon AS t_ICON,"
"IFNULL((SELECT f_CURRENTAMOUNTUNIT FROM v_operation_tmp1 WHERE d_date='0000-00-00' AND rd_account_id=account.id), 1) AS f_CURRENTAMOUNTUNIT,"
"(SELECT MAX(s.d_date) FROM interest s WHERE s.rd_account_id=account.id) AS d_MAXDATE "
"FROM account, bank WHERE +account.rd_bank_id=bank.id")
<< QStringLiteral("CREATE VIEW v_account_amount AS "
"SELECT "
"v_account.*,"
"(SELECT TOTAL(s.f_CURRENTAMOUNT) FROM v_operation s WHERE s.rd_account_id=v_account.id AND s.t_template='N') AS f_CURRENTAMOUNT "
"FROM v_account")
<< "CREATE VIEW v_account_delete AS "
"SELECT *, (CASE WHEN EXISTS(SELECT 1 FROM operation WHERE rd_account_id=account.id AND d_date<>'0000-00-00' AND t_template='N' AND t_status='Y') THEN '" %
SKGServices::stringToSqlString(i18nc("Error message", "You are not authorized to delete this account because it contains some checked operations")) %
"' END) t_delete_message FROM account"
// bank
<< QStringLiteral("CREATE VIEW v_bank_displayname AS "
"SELECT *, t_name AS t_displayname FROM bank")
<< QStringLiteral("CREATE VIEW v_account_displayname AS "
"SELECT *, (SELECT t_displayname FROM v_bank_displayname WHERE account.rd_bank_id=v_bank_displayname.id)||'-'||t_name AS t_displayname FROM account")
<< QStringLiteral("CREATE VIEW v_bank AS "
"SELECT * FROM bank")
<< QStringLiteral("CREATE VIEW v_bank_amount AS "
"SELECT *,"
"(SELECT TOTAL(s.f_CURRENTAMOUNT) FROM v_account_amount s WHERE s.rd_bank_id=v_bank.id) AS f_CURRENTAMOUNT "
"FROM v_bank")
// category
<< QStringLiteral("CREATE VIEW v_category_displayname AS "
"SELECT *, t_fullname AS t_displayname FROM category")
<< QStringLiteral("CREATE VIEW v_category AS SELECT * "
"FROM category")
// recurrentoperation
<< "CREATE VIEW v_recurrentoperation AS "
"SELECT *,"
"date(d_date, '-'||((CASE t_period_unit WHEN 'W' THEN 7 ELSE 1 END)*i_period_increment)||' '||(CASE t_period_unit WHEN 'M' THEN 'month' WHEN 'Y' THEN 'year' ELSE 'day' END)) as d_PREVIOUS,"
"i_period_increment||' '||(CASE t_period_unit "
"WHEN 'Y' THEN '" % SKGServices::stringToSqlString(i18nc("Noun", "year(s)")) % "' "
"WHEN 'M' THEN '" % SKGServices::stringToSqlString(i18nc("Noun", "month(s)")) % "' "
"WHEN 'W' THEN '" % SKGServices::stringToSqlString(i18nc("Noun", "week(s)")) % "' "
"ELSE '" % SKGServices::stringToSqlString(i18nc("Noun", "day(s)")) % "' END) AS t_PERIODNLS "
"FROM recurrentoperation"
<< "CREATE VIEW v_recurrentoperation_displayname AS "
"SELECT *, IFNULL(TOFORMATTEDDATE(d_date,'" % SKGServices::stringToSqlString(dateFormatShort) % "'),STRFTIME('%Y-%m-%d',d_date))||' '||(SELECT SUBSTR(t_displayname, INSTR(t_displayname, ' ')+1) FROM v_operation_displayname WHERE v_operation_displayname.id=v_recurrentoperation.rd_operation_id) AS t_displayname FROM v_recurrentoperation"
// ==================================================================
// These following views contains all attributes needed for display
// unitvalue
<< QStringLiteral("CREATE VIEW v_unitvalue_display AS "
"SELECT *,"
"unitvalue.f_QUANTITY*(SELECT TOTAL(v_operation.f_QUANTITY) FROM v_operation WHERE v_operation.rc_unit_id=unitvalue.rd_unit_id AND v_operation.d_date<=unitvalue.d_date AND v_operation.t_template='N') AS f_AMOUNTOWNED,"
"IFNULL((SELECT (CASE WHEN s.t_symbol!='' THEN s.t_symbol ELSE s.t_name END) FROM unit s WHERE s.id=(SELECT s2.rd_unit_id FROM unit s2 WHERE s2.id=unitvalue.rd_unit_id)),'') AS t_UNIT,"
"STRFTIME('%Y-%m',unitvalue.d_date) AS d_DATEMONTH,"
"STRFTIME('%Y',unitvalue.d_date) AS d_DATEYEAR "
"FROM unitvalue")
// suboperation
<< QStringLiteral("CREATE VIEW v_suboperation_display AS "
"SELECT *,"
"IFNULL((SELECT s.t_fullname FROM category s WHERE s.id=v_suboperation.r_category_id),'') AS t_CATEGORY, "
"IFNULL((SELECT s.t_name FROM refund s WHERE s.id=v_suboperation.r_refund_id),'') AS t_REFUND, "
"IFNULL((SELECT s.t_name||\" (\"||TOCURRENCY((SELECT TOTAL(s2.f_value) FROM v_suboperation s2 WHERE s2.d_date<=v_suboperation.d_date AND s2.r_refund_id=v_suboperation.r_refund_id), (SELECT t_UNIT FROM v_operation WHERE v_suboperation.rd_operation_id = v_operation.id))||\")\" FROM refund s WHERE s.id=v_suboperation.r_refund_id),'') AS t_REFUNDDISPLAY, "
"(CASE WHEN v_suboperation.f_value>=0 THEN v_suboperation.f_value ELSE 0 END) AS f_VALUE_INCOME, "
"(CASE WHEN v_suboperation.f_value<=0 THEN v_suboperation.f_value ELSE 0 END) AS f_VALUE_EXPENSE "
"FROM v_suboperation")
<< QStringLiteral("CREATE VIEW v_suboperation_displayname AS "
"SELECT *, t_CATEGORY||' : '||f_value AS t_displayname FROM v_suboperation_display")
// operation
<< "CREATE VIEW v_operation_display_all AS "
"SELECT *,"
// "(SELECT s.t_comment FROM v_suboperation_display s WHERE s.id=v_operation.i_MOSTIMPSUBOP) AS t_COMMENT,"
"IFNULL((CASE WHEN v_operation.i_group_id=0 THEN '' ELSE (SELECT GROUP_CONCAT(DISTINCT(op2.t_ACCOUNT)) FROM v_operation_tmp1 op2 WHERE op2.i_group_id=v_operation.i_group_id AND op2.id<>v_operation.id) END), '') AS t_TOACCOUNT, "
"(SELECT s.t_CATEGORY FROM v_suboperation_display s WHERE s.id=v_operation.i_MOSTIMPSUBOP) AS t_CATEGORY,"
"(SELECT s.t_REFUND FROM v_suboperation_display s WHERE s.id=v_operation.i_MOSTIMPSUBOP) AS t_REFUND,"
"(SELECT GROUP_CONCAT(s.t_REFUNDDISPLAY) FROM v_suboperation_display s WHERE s.rd_operation_id=v_operation.id AND s.t_REFUNDDISPLAY!='') AS t_REFUNDDISPLAY,"
"(CASE WHEN v_operation.f_QUANTITY<0 THEN '-' WHEN v_operation.f_QUANTITY=0 THEN '' ELSE '+' END) AS t_TYPEEXPENSE, "
"(CASE WHEN v_operation.f_QUANTITY<=0 THEN '" % SKGServices::stringToSqlString(i18nc("Noun, financial operations with a negative amount", "Expenditure")) % "' ELSE '" % SKGServices::stringToSqlString(i18nc("Noun, financial operations with a positive amount", "Income")) % "' END) AS t_TYPEEXPENSENLS, "
"STRFTIME('%Y-W%W',v_operation.d_date" + (firstDayOfWeek == Qt::Sunday ? ", '+1 days'" : "") + ") AS d_DATEWEEK,"
"STRFTIME('%Y-%m',v_operation.d_date) AS d_DATEMONTH,"
"STRFTIME('%Y',v_operation.d_date)||'-Q'||(CASE WHEN STRFTIME('%m',v_operation.d_date)<='03' THEN '1' WHEN STRFTIME('%m',v_operation.d_date)<='06' THEN '2' WHEN STRFTIME('%m',v_operation.d_date)<='09' THEN '3' ELSE '4' END) AS d_DATEQUARTER, "
"STRFTIME('%Y',v_operation.d_date)||'-S'||(CASE WHEN STRFTIME('%m',v_operation.d_date)<='06' THEN '1' ELSE '2' END) AS d_DATESEMESTER, "
"STRFTIME('%Y',v_operation.d_date) AS d_DATEYEAR, "
"(SELECT COUNT(1) FROM v_recurrentoperation s WHERE s.rd_operation_id=v_operation.id) AS i_NBRECURRENT, "
"(CASE WHEN v_operation.f_QUANTITY>=0 THEN v_operation.f_QUANTITY ELSE 0 END) AS f_QUANTITY_INCOME, "
"(CASE WHEN v_operation.f_QUANTITY<=0 THEN v_operation.f_QUANTITY ELSE 0 END) AS f_QUANTITY_EXPENSE, "
"(SELECT o2.f_balance FROM operationbalance o2 WHERE o2.r_operation_id=v_operation.id ) AS f_BALANCE, "
"(SELECT o2.f_balance_entered FROM operationbalance o2 WHERE o2.r_operation_id=v_operation.id ) AS f_BALANCE_ENTERED, "
"(CASE WHEN v_operation.f_QUANTITY>=0 THEN v_operation.f_CURRENTAMOUNT ELSE 0 END) AS f_CURRENTAMOUNT_INCOME, "
"(CASE WHEN v_operation.f_QUANTITY<=0 THEN v_operation.f_CURRENTAMOUNT ELSE 0 END) AS f_CURRENTAMOUNT_EXPENSE "
"FROM v_operation"
<< QStringLiteral("CREATE VIEW v_operation_display AS "
"SELECT * FROM v_operation_display_all WHERE d_date!='0000-00-00' AND t_template='N'")
// unit
<< QStringLiteral("CREATE VIEW v_unit_display AS "
"SELECT *,"
"i_nbdecimal AS i_NBDEC,"
"(SELECT TOTAL(o.f_QUANTITY) FROM v_operation_display_all o WHERE o.rc_unit_id=v_unit.id AND o.t_template='N') AS f_QUANTITYOWNED, "
"(SELECT TOTAL(o.f_QUANTITY) FROM v_operation_display_all o WHERE o.rc_unit_id=v_unit.id AND o.t_template='N')*v_unit.f_CURRENTAMOUNT AS f_AMOUNTOWNED "
"FROM v_unit")
// account
<< "CREATE VIEW v_account_display AS "
"SELECT "
"v_account_amount.*,"
"(v_account_amount.f_CURRENTAMOUNT/(SELECT u.f_CURRENTAMOUNT FROM v_unit u, operation s WHERE u.id=s.rc_unit_id AND s.rd_account_id=v_account_amount.id AND s.d_date='0000-00-00')) AS f_QUANTITY, "
"(SELECT (CASE WHEN u.t_symbol!='' THEN u.t_symbol ELSE u.t_name END) FROM unit u, operation s WHERE u.id=s.rc_unit_id AND s.rd_account_id=v_account_amount.id AND s.d_date='0000-00-00') AS t_UNIT, "
"(SELECT TOTAL(s.f_CURRENTAMOUNT) FROM v_operation s WHERE s.rd_account_id=v_account_amount.id AND s.t_status='Y' AND s.t_template='N') AS f_CHECKED, "
"(SELECT TOTAL(s.f_CURRENTAMOUNT) FROM v_operation s WHERE s.rd_account_id=v_account_amount.id AND s.t_status!='N' AND s.t_template='N') AS f_CHECKEDANDPOINTED, "
"(SELECT TOTAL(s.f_CURRENTAMOUNT) FROM v_operation s WHERE s.rd_account_id=v_account_amount.id AND s.t_status!='Y' AND s.t_template='N') AS f_COMING_SOON, "
"(SELECT TOTAL(s.f_CURRENTAMOUNT) FROM v_operation s WHERE s.rd_account_id IN (SELECT id FROM account WHERE account.r_account_id=v_account_amount.id) AND s.t_status='N' AND s.t_template='N') AS f_COMING_SOON_FROM_LINKED_ACCOUNT, "
"(SELECT TOTAL(s.f_CURRENTAMOUNT) FROM v_operation s WHERE s.rd_account_id=v_account_amount.id AND s.d_date<=(SELECT date('now')) AND s.t_template='N') AS f_TODAYAMOUNT, "
"(SELECT COUNT(1) FROM v_operation_display s WHERE s.rd_account_id=v_account_amount.id) AS i_NBOPERATIONS, "
"IFNULL((SELECT s.f_rate FROM interest s WHERE s.rd_account_id=v_account_amount.id AND s.d_date=v_account_amount.d_MAXDATE),0) AS f_RATE "
"FROM v_account_amount"
// operations
<< "CREATE VIEW v_suboperation_consolidated AS "
"SELECT "
"(SELECT s.t_TYPENLS FROM v_account_display s WHERE s.id=op.rd_account_id) AS t_ACCOUNTTYPE,"
"(SELECT s.t_BANK FROM v_account_display s WHERE s.id=op.rd_account_id) AS t_BANK,"
"(SELECT u.t_TYPENLS FROM v_unit u WHERE u.id=op.rc_unit_id) AS t_UNITTYPE,"
"sop.id AS id, "
"sop.id AS i_SUBOPID, "
"sop.r_refund_id AS r_refund_id, "
"(CASE WHEN sop.t_comment='' THEN op.t_comment ELSE sop.t_comment END) AS t_REALCOMMENT, "
"sop.t_CATEGORY AS t_REALCATEGORY, "
"sop.t_REFUND AS t_REALREFUND, "
"sop.r_category_id AS i_IDCATEGORY, "
"(CASE WHEN sop.f_value<0 THEN '-' WHEN sop.f_value=0 THEN '' ELSE '+' END) AS t_TYPEEXPENSE, "
"(CASE WHEN sop.f_value<=0 THEN '" % SKGServices::stringToSqlString(i18nc("Noun, financial operations with a negative amount", "Expenditure")) % "' ELSE '" % SKGServices::stringToSqlString(i18nc("Noun, financial operations with a positive amount", "Income")) % "' END) AS t_TYPEEXPENSENLS, "
"sop.f_value AS f_REALQUANTITY, "
"sop.f_VALUE_INCOME AS f_REALQUANTITY_INCOME, "
"sop.f_VALUE_EXPENSE AS f_REALQUANTITY_EXPENSE, "
"((SELECT u.f_CURRENTAMOUNT FROM v_unit u WHERE u.id=op.rc_unit_id)*sop.f_value) AS f_REALCURRENTAMOUNT, "
"((SELECT u.f_CURRENTAMOUNT FROM v_unit u WHERE u.id=op.rc_unit_id)*sop.f_VALUE_INCOME) AS f_REALCURRENTAMOUNT_INCOME, "
"((SELECT u.f_CURRENTAMOUNT FROM v_unit u WHERE u.id=op.rc_unit_id)*sop.f_VALUE_EXPENSE) AS f_REALCURRENTAMOUNT_EXPENSE, "
"STRFTIME('%Y-W%W',sop.d_date" + (firstDayOfWeek == Qt::Sunday ? ", '+1 days'" : "") + ") AS d_DATEWEEK,"
"STRFTIME('%Y-%m',sop.d_date) AS d_DATEMONTH,"
"STRFTIME('%Y',sop.d_date)||'-Q'||(CASE WHEN STRFTIME('%m',sop.d_date)<='03' THEN '1' WHEN STRFTIME('%m',sop.d_date)<='06' THEN '2' WHEN STRFTIME('%m',sop.d_date)<='09' THEN '3' ELSE '4' END) AS d_DATEQUARTER, "
"STRFTIME('%Y',sop.d_date)||'-S'||(CASE WHEN STRFTIME('%m',sop.d_date)<='06' THEN '1' ELSE '2' END) AS d_DATESEMESTER, "
"STRFTIME('%Y',sop.d_date) AS d_DATEYEAR, "
"sop.d_date AS d_date, "
"op.id AS i_OPID, "
"op.d_date AS d_DATEOP, "
"op.*, "
"sop.* "
"FROM v_operation_display_all AS op, v_suboperation_display AS sop WHERE +sop.rd_operation_id=op.ID AND op.t_template='N'"
<< QStringLiteral("CREATE VIEW v_operation_prop AS "
"SELECT "
"p.id AS i_PROPPID, "
"p.t_name AS i_PROPPNAME, "
"p.t_value AS i_PROPVALUE, "
"op.* "
"FROM v_suboperation_consolidated AS op LEFT OUTER JOIN parameters AS p ON (p.t_uuid_parent=op.id||'-suboperation' OR p.t_uuid_parent=op.i_OPID||'-operation')")
// refund
<< "CREATE VIEW v_refund_delete AS "
"SELECT *, (CASE WHEN EXISTS(SELECT 1 FROM v_suboperation_consolidated WHERE r_refund_id=refund.id AND t_status='Y') THEN '" %
SKGServices::stringToSqlString(i18nc("Error message", "You are not authorized to delete this tracker because used by some checked operations")) %
"' END) t_delete_message FROM refund"
<< QStringLiteral("CREATE VIEW v_refund AS SELECT * FROM refund")
<< QStringLiteral("CREATE VIEW v_refund_amount AS "
"SELECT *, "
"(SELECT TOTAL(o.f_REALCURRENTAMOUNT) FROM v_suboperation_consolidated o WHERE o.r_refund_id=v_refund.id) AS f_CURRENTAMOUNT "
"FROM v_refund")
<< QStringLiteral("CREATE VIEW v_refund_display AS "
"SELECT *,"
"(SELECT MIN(o.d_date) FROM v_suboperation_consolidated o WHERE o.r_refund_id=v_refund_amount.id) AS d_FIRSTDATE, "
"(SELECT MAX(o.d_date) FROM v_suboperation_consolidated o WHERE o.r_refund_id=v_refund_amount.id) AS d_LASTDATE "
" FROM v_refund_amount")
<< QStringLiteral("CREATE VIEW v_refund_displayname AS "
"SELECT *, t_name AS t_displayname FROM refund")
// Payee
<< "CREATE VIEW v_payee_delete AS "
"SELECT *, (CASE WHEN EXISTS(SELECT 1 FROM operation WHERE r_payee_id=payee.id AND t_status='Y') THEN '" %
SKGServices::stringToSqlString(i18nc("Error message", "You are not authorized to delete this payee because used by some checked operations")) %
"' END) t_delete_message FROM payee"
<< QStringLiteral("CREATE VIEW v_payee_amount AS SELECT o.r_payee_id AS r_payee_id, TOTAL(o.f_CURRENTAMOUNT) AS f_CURRENTAMOUNT, COUNT(1) AS i_NBOPERATIONS FROM v_operation o GROUP BY o.r_payee_id")
<< QStringLiteral("CREATE VIEW v_payee AS SELECT *,"
"IFNULL((SELECT s.t_fullname FROM category s WHERE s.id=payee.r_category_id),'') AS t_CATEGORY "
"FROM payee")
<< QStringLiteral("CREATE VIEW v_payee_display AS "
"SELECT v_payee.*, "
"(CASE WHEN p.f_CURRENTAMOUNT IS NULL THEN 0 ELSE p.f_CURRENTAMOUNT END) AS f_CURRENTAMOUNT, "
"(CASE WHEN p.i_NBOPERATIONS IS NULL THEN 0 ELSE p.i_NBOPERATIONS END) AS i_NBOPERATIONS "
"FROM v_payee LEFT OUTER JOIN v_payee_amount p ON p.r_payee_id=v_payee.id")
<< QStringLiteral("CREATE VIEW v_payee_displayname AS "
"SELECT *, t_name AS t_displayname FROM payee")
// category
<< "CREATE VIEW v_category_delete AS "
"SELECT *, (CASE WHEN EXISTS(SELECT 1 FROM v_suboperation_consolidated WHERE (t_REALCATEGORY=category.t_fullname OR t_REALCATEGORY like category.t_fullname||'%') AND t_status='Y') THEN '" %
SKGServices::stringToSqlString(i18nc("Error message", "You are not authorized to delete this category because used by some checked operations")) %
"' END) t_delete_message FROM category"
<< QStringLiteral("CREATE VIEW v_category_amount AS SELECT o.i_IDCATEGORY AS i_IDCATEGORY, TOTAL(o.f_REALCURRENTAMOUNT) AS f_REALCURRENTAMOUNT FROM v_suboperation_consolidated o GROUP BY o.i_IDCATEGORY")
<< QStringLiteral("CREATE VIEW v_category_display_tmp AS SELECT v_category.*, "
"IFNULL(t.f_REALCURRENTAMOUNT, 0) AS f_REALCURRENTAMOUNT, "
"(SELECT COUNT(DISTINCT(so.rd_operation_id)) FROM operation o, suboperation so WHERE +so.rd_operation_id=o.id AND so.r_category_id=v_category.ID AND o.t_template='N') AS i_NBOPERATIONS "
"FROM v_category LEFT OUTER JOIN v_category_amount t ON t.i_IDCATEGORY=v_category.ID")
<< QStringLiteral("CREATE VIEW v_category_used1 AS SELECT v_category.*, "
"(CASE WHEN EXISTS(SELECT 1 FROM operation o, suboperation so WHERE +so.rd_operation_id=o.id AND so.r_category_id=v_category.ID AND o.t_template='N') THEN 'Y' ELSE 'N' END) AS t_ISUSED "
"FROM v_category")
<< "CREATE VIEW v_category_used2 AS SELECT v_category_used1.*, "
"(CASE WHEN v_category_used1.t_ISUSED='Y' THEN 'Y' WHEN EXISTS(SELECT 1 FROM v_category_used1 c WHERE c.t_ISUSED='Y' AND c.t_fullname like v_category_used1.t_fullname||'" % OBJECTSEPARATOR % "%') THEN 'C' ELSE 'N' END) AS t_ISUSEDCASCADE "
"FROM v_category_used1"
<< "CREATE VIEW v_category_display AS SELECT *,"
"v_category_display_tmp.f_REALCURRENTAMOUNT+(SELECT TOTAL(c.f_REALCURRENTAMOUNT) FROM v_category_display_tmp c WHERE c.t_fullname LIKE v_category_display_tmp.t_fullname||'" % OBJECTSEPARATOR % "%') AS f_SUMCURRENTAMOUNT, "
"v_category_display_tmp.i_NBOPERATIONS+(SELECT CAST(TOTAL(c.i_NBOPERATIONS) AS INTEGER) FROM v_category_display_tmp c WHERE c.t_fullname like v_category_display_tmp.t_fullname||'" % OBJECTSEPARATOR % "%') AS i_SUMNBOPERATIONS, "
"(CASE WHEN v_category_display_tmp.t_bookmarked='Y' THEN 'Y' WHEN EXISTS(SELECT 1 FROM category c WHERE c.t_bookmarked='Y' AND c.t_fullname like v_category_display_tmp.t_fullname||'" % OBJECTSEPARATOR % "%') THEN 'C' ELSE 'N' END) AS t_HASBOOKMARKEDCHILD, "
"(CASE WHEN v_category_display_tmp.f_REALCURRENTAMOUNT<0 THEN '-' WHEN v_category_display_tmp.f_REALCURRENTAMOUNT=0 THEN '' ELSE '+' END) AS t_TYPEEXPENSE,"
"(CASE WHEN v_category_display_tmp.f_REALCURRENTAMOUNT<0 THEN '" % SKGServices::stringToSqlString(i18nc("Noun, financial operations with a negative amount", "Expenditure")) % "' WHEN v_category_display_tmp.f_REALCURRENTAMOUNT=0 THEN '' ELSE '" % SKGServices::stringToSqlString(i18nc("Noun, financial operations with a positive amount", "Income")) % "' END) AS t_TYPEEXPENSENLS "
"FROM v_category_display_tmp"
// recurrentoperation
<< QStringLiteral("CREATE VIEW v_recurrentoperation_display AS "
"SELECT rop.*, op.t_ACCOUNT, op.t_number, op.t_mode, op.i_group_id, op.t_TRANSFER, op.t_PAYEE, op.t_comment, op.t_CATEGORY, op.t_status, op.f_CURRENTAMOUNT "
"FROM v_recurrentoperation rop, v_operation_display_all AS op WHERE +rop.rd_operation_id=op.ID")
// rule
<< QStringLiteral("CREATE VIEW v_rule AS SELECT *,"
"(SELECT COUNT(1) FROM rule r WHERE r.f_sortorder<=rule.f_sortorder) AS i_ORDER "
"FROM rule")
<< QStringLiteral("CREATE VIEW v_rule_displayname AS SELECT *, t_description AS t_displayname FROM rule")
<< QStringLiteral("CREATE VIEW v_rule_display AS SELECT * FROM v_rule")
// interest
<< QStringLiteral("CREATE VIEW v_interest AS SELECT *,"
"(SELECT s.t_name FROM account s WHERE s.id=interest.rd_account_id) AS t_ACCOUNT "
" FROM interest")
<< "CREATE VIEW v_interest_displayname AS SELECT *, IFNULL(TOFORMATTEDDATE(d_date,'" % SKGServices::stringToSqlString(dateFormatShort) % "'),STRFTIME('%Y-%m-%d',d_date))||' '||f_rate||'%' AS t_displayname FROM interest"
// budgetrule
<< "CREATE VIEW v_budgetrule AS "
"SELECT *, "
"(SELECT COUNT(1) FROM budgetrule r WHERE r.f_sortorder<=budgetrule.f_sortorder) AS i_ORDER, "
"IFNULL((SELECT s.t_fullname FROM category s WHERE s.id=budgetrule.rc_category_id),'') AS t_CATEGORYCONDITION, "
"IFNULL((SELECT s.t_fullname FROM category s WHERE s.id=budgetrule.rc_category_id_target),'') AS t_CATEGORY, "
"(CASE "
"WHEN budgetrule.i_condition=-1 THEN '" % SKGServices::stringToSqlString(i18nc("Noun", "Negative")) % "' "
"WHEN budgetrule.i_condition=1 THEN '" % SKGServices::stringToSqlString(i18nc("Noun", "Positive")) % "' "
"WHEN budgetrule.i_condition=0 THEN '" % SKGServices::stringToSqlString(i18nc("Noun", "All")) % "' "
"END) AS t_WHENNLS, "
"f_quantity||(CASE WHEN budgetrule.t_absolute='N' THEN '%' ELSE (SELECT t_symbol FROM unit WHERE t_type='1') END) AS t_WHATNLS,"
"(CASE "
"WHEN budgetrule.t_rule='N' THEN '" % SKGServices::stringToSqlString(i18nc("Noun", "Next")) % "' "
"WHEN budgetrule.t_rule='C' THEN '" % SKGServices::stringToSqlString(i18nc("Noun", "Current")) % "' "
"WHEN budgetrule.t_rule='Y' THEN '" % SKGServices::stringToSqlString(i18nc("Noun", "Year")) % "' "
"END) AS t_RULENLS "
"FROM budgetrule"
<< QStringLiteral("CREATE VIEW v_budgetrule_display AS "
"SELECT * "
" FROM v_budgetrule")
<< QStringLiteral("CREATE VIEW v_budgetrule_displayname AS "
"SELECT *, t_WHENNLS||' '||t_WHATNLS||' '||t_RULENLS||' '||t_CATEGORY AS t_displayname FROM v_budgetrule")
// budget
<< QStringLiteral("CREATE VIEW v_budget_tmp AS "
"SELECT *, "
"IFNULL((SELECT s.t_fullname FROM category s WHERE s.id=budget.rc_category_id),'') AS t_CATEGORY, "
"(budget.i_year||(CASE WHEN budget.i_month=0 THEN '' WHEN budget.i_month<10 THEN '-0'||budget.i_month ELSE '-'||budget.i_month END)) AS t_PERIOD, "
"(SELECT TOTAL(o.f_REALCURRENTAMOUNT) FROM v_suboperation_consolidated o WHERE o.t_TYPEACCOUNT<>'L' AND o.i_SUBOPID IN "
"(SELECT b2.id_suboperation FROM budgetsuboperation b2 WHERE b2.id=budget.id)"
") AS f_CURRENTAMOUNT, "
"(SELECT GROUP_CONCAT(v_budgetrule_displayname.t_displayname,',') FROM v_budgetrule_displayname WHERE "
"(v_budgetrule_displayname.t_year_condition='N' OR budget.i_year=v_budgetrule_displayname.i_year) AND "
"(v_budgetrule_displayname.t_month_condition='N' OR budget.i_month=v_budgetrule_displayname.i_month) AND "
"(v_budgetrule_displayname.t_category_condition='N' OR budget.rc_category_id=v_budgetrule_displayname.rc_category_id) "
"ORDER BY v_budgetrule_displayname.t_absolute DESC, v_budgetrule_displayname.id) AS t_RULES "
"FROM budget")
<< QStringLiteral("CREATE VIEW v_budget AS "
"SELECT *, "
"(f_CURRENTAMOUNT-f_budgeted_modified) AS f_DELTABEFORETRANSFER, "
"(f_CURRENTAMOUNT-f_budgeted_modified-f_transferred) AS f_DELTA "
"FROM v_budget_tmp")
<< QStringLiteral("CREATE VIEW v_budget_display AS "
"SELECT *, "
"(f_CURRENTAMOUNT-f_budgeted_modified) AS f_DELTABEFORETRANSFER, "
"(f_CURRENTAMOUNT-f_budgeted_modified-f_transferred) AS f_DELTA "
"FROM vm_budget_tmp")
<< QStringLiteral("CREATE VIEW v_budget_displayname AS "
"SELECT *, t_CATEGORY||' '||t_PERIOD||' '||f_budgeted_modified AS t_displayname FROM v_budget")
<< QStringLiteral("CREATE VIEW v_operation_all_comment AS "
"SELECT t_comment FROM operation UNION SELECT t_comment FROM suboperation");
IFOKDO(err, SKGDocument::refreshViewsIndexesAndTriggers(iForce))
QStringList tables;
tables << QStringLiteral("account") << QStringLiteral("unit") << QStringLiteral("unitvalue") << QStringLiteral("bank") << QStringLiteral("recurrentoperation") << QStringLiteral("refund") << QStringLiteral("payee") << QStringLiteral("operation")
<< QStringLiteral("operationbalance") << QStringLiteral("interest") << QStringLiteral("rule") << QStringLiteral("suboperation") << QStringLiteral("budget") << QStringLiteral("budgetrule") << QStringLiteral("budgetcategory") << QStringLiteral("budgetsuboperation") << QStringLiteral("category");
IFOKDO(err, dropViewsAndIndexes(tables))
IFOKDO(err, executeSqliteOrders(BankInitialDataModelIndex))
IFOKDO(err, executeSqliteOrders(BankInitialDataModelView))
IFOKDO(err, executeSqliteOrders(BankInitialDataModelTrigger))
IFOKDO(err, executeSqliteOrder(QStringLiteral("ANALYZE")))
return err;
}
QStringList SKGDocumentBank::getMigationSteps()
{
SKGTRACEINFUNC(5)
QStringList migrationSteps;
migrationSteps.reserve(1000);
migrationSteps
// ============
<< QLatin1String("")
<< QStringLiteral("0.1")
<< QStringLiteral("0.2")
<< QStringLiteral("ALTER TABLE unit ADD COLUMN rc_unit_id INTEGER NOT NULL DEFAULT 0")
// ============
<< QLatin1String("")
<< QStringLiteral("0.2")
<< QStringLiteral("0.3")
<< QStringLiteral("DROP TABLE IF EXISTS unitvalue2")
<< QStringLiteral("CREATE TABLE unitvalue2("
"id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,"
"rd_unit_id INTEGER NOT NULL,"
"d_date DATE NOT NULL,"
"f_quantity FLOAT NOT NULL CHECK (f_quantity>=0))")
<< QStringLiteral("INSERT INTO unitvalue2 (id,rd_unit_id,d_date,f_quantity) SELECT id,rd_unit_id,d_date,f_value FROM unitvalue")
<< QStringLiteral("DROP TABLE IF EXISTS unitvalue")
<< QStringLiteral("ALTER TABLE unitvalue2 RENAME TO unitvalue")
// ============
<< QLatin1String("")
<< QStringLiteral("0.3")
<< QStringLiteral("0.4")
<< QStringLiteral("ALTER TABLE operation ADD COLUMN t_import_id TEXT DEFAULT ''")
// ============
<< QLatin1String("")
<< QStringLiteral("0.4")
<< QStringLiteral("0.5")
<< QStringLiteral("DROP TABLE IF EXISTS recurrentoperation")
<< QStringLiteral("CREATE TABLE recurrentoperation ("
"id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,"
"d_date DATE NOT NULL DEFAULT '0000-00-00',"
"rd_operation_id INTEGER NOT NULL,"
"i_period_increment INTEGER NOT NULL DEFAULT 1 CHECK (i_period_increment>=0),"
"t_period_unit TEXT NOT NULL DEFAULT 'M' CHECK (t_period_unit IN ('D', 'M', 'Y')),"
"t_auto_write VARCHAR(1) DEFAULT 'Y' CHECK (t_auto_write IN ('Y', 'N')),"
"i_auto_write_days INTEGER NOT NULL DEFAULT 5 CHECK (i_auto_write_days>=0),"
"t_warn VARCHAR(1) DEFAULT 'Y' CHECK (t_auto_write IN ('Y', 'N')),"
"i_warn_days INTEGER NOT NULL DEFAULT 5 CHECK (i_warn_days>=0)"
")")
<< QStringLiteral("ALTER TABLE operation ADD COLUMN r_recurrentoperation_id INTEGER NOT NULL DEFAULT 0")
// ============
<< QLatin1String("")
<< QStringLiteral("0.5")
<< QStringLiteral("0.6")
<< QStringLiteral("ALTER TABLE account ADD COLUMN t_comment TEXT NOT NULL DEFAULT ''")
// ============
<< QLatin1String("")
<< QStringLiteral("0.6")
<< QStringLiteral("0.7")
<< QStringLiteral("DROP TABLE IF EXISTS unit2")
<< QStringLiteral("CREATE TABLE unit2("
"id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,"
"t_name TEXT NOT NULL,"
"t_symbol TEXT NOT NULL DEFAULT '',"
"t_country TEXT NOT NULL DEFAULT '',"
"t_type VARCHAR(1) NOT NULL DEFAULT 'C' CHECK (t_type IN ('1', '2', 'C', 'S', 'O')),"
// 1=main currency, 2=secondary currency, C=currencies S=share O=object
"t_internet_code TEXT NOT NULL DEFAULT '',"
"rd_unit_id INTEGER NOT NULL DEFAULT 0)")
<< QStringLiteral("INSERT INTO unit2 (id,t_name,t_symbol,t_country,t_type,t_internet_code,rd_unit_id) SELECT id,t_name,t_symbol,t_country,t_type,t_internet_code,rc_unit_id FROM unit")
<< QStringLiteral("DROP TABLE IF EXISTS unit")
<< QStringLiteral("ALTER TABLE unit2 RENAME TO unit")
// ============
<< QLatin1String("")
<< QStringLiteral("0.7")
<< QStringLiteral("0.8")
<< QStringLiteral("DELETE FROM operation WHERE id IN (SELECT id FROM operation op WHERE NOT EXISTS(SELECT 1 FROM suboperation sop WHERE sop.rd_operation_id=op.id))")
// ============
<< QLatin1String("")
<< QStringLiteral("0.8")
<< QStringLiteral("0.9")
<< QStringLiteral("UPDATE operation SET i_group_id=0 WHERE i_group_id=''")
// ============
<< QLatin1String("")
<< QStringLiteral("0.9")
<< QStringLiteral("1.0")
<< QStringLiteral("DROP TABLE IF EXISTS unit2")
<< QStringLiteral("CREATE TABLE unit2("
"id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,"
"t_name TEXT NOT NULL,"
"t_symbol TEXT NOT NULL DEFAULT '',"
"t_country TEXT NOT NULL DEFAULT '',"
"t_type VARCHAR(1) NOT NULL DEFAULT 'C' CHECK (t_type IN ('1', '2', 'C', 'S', 'I', 'O')),"
// 1=main currency, 2=secondary currency, C=currencies S=share, I=index, O=object
"t_internet_code TEXT NOT NULL DEFAULT '',"
"rd_unit_id INTEGER NOT NULL DEFAULT 0)")
<< QStringLiteral("INSERT INTO unit2 (id,t_name,t_symbol,t_country,t_type,t_internet_code,rd_unit_id) SELECT id,t_name,t_symbol,t_country,t_type,t_internet_code,rd_unit_id FROM unit")
<< QStringLiteral("DROP TABLE IF EXISTS unit")
<< QStringLiteral("ALTER TABLE unit2 RENAME TO unit")
// ============
<< QLatin1String("")
<< QStringLiteral("1.0")
<< QStringLiteral("1.1")
<< QStringLiteral("DELETE FROM parameters WHERE t_name LIKE 'SKG_MONTHLY_REPORT_%'")
// ============
<< QLatin1String("")
<< QStringLiteral("1.1")
<< QStringLiteral("1.2")
<< QStringLiteral("ALTER TABLE suboperation ADD COLUMN t_comment TEXT NOT NULL DEFAULT ''")
// ============
<< QLatin1String("")
<< QStringLiteral("1.2")
<< QStringLiteral("1.3")
<< QStringLiteral("UPDATE node SET f_sortorder=id WHERE f_sortorder IS NULL OR f_sortorder=''")
// ============
<< QLatin1String("")
<< QStringLiteral("1.3")
<< QStringLiteral("1.4")
<< QStringLiteral("DROP TABLE IF EXISTS refund")
<< QStringLiteral("CREATE TABLE refund ("
"id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,"
"t_name TEXT NOT NULL DEFAULT '',"
"t_comment TEXT NOT NULL DEFAULT '',"
"t_close VARCHAR(1) DEFAULT 'N' CHECK (t_close IN ('Y', 'N')))")
<< QStringLiteral("ALTER TABLE suboperation ADD COLUMN r_refund_id INTEGER NOT NULL DEFAULT 0")
// ============
<< QLatin1String("")
<< QStringLiteral("1.4")
<< QStringLiteral("1.5")
<< QStringLiteral("DELETE FROM parameters WHERE (t_name LIKE 'SKG_DEFAULT_%' AND t_name!='SKG_DEFAULT_PROPERTIES') OR t_name='DBVERSION'")
// ============
<< QLatin1String("")
<< QStringLiteral("1.5")
<< QStringLiteral("1.6")
<< QStringLiteral("CREATE TABLE rule ("
"id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,"
"t_description TEXT NOT NULL DEFAULT '',"
"t_definition TEXT NOT NULL DEFAULT '',"
"f_sortorder FLOAT"
")")
// ============
<< QLatin1String("")
<< QStringLiteral("1.6")
<< QStringLiteral("1.7")
<< QStringLiteral("CREATE TABLE action ("
"id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,"
"rd_rule_id INTEGER NOT NULL,"
"t_description TEXT NOT NULL DEFAULT '',"
"t_definition TEXT NOT NULL DEFAULT ''"
")")
<< QStringLiteral("DELETE FROM rule")
<< QStringLiteral("DROP TABLE IF EXISTS budget")
// ============
<< QLatin1String("")
<< QStringLiteral("1.7")
<< QStringLiteral("1.8")
<< QStringLiteral("DROP TABLE IF EXISTS action")
<< QStringLiteral("ALTER TABLE rule ADD COLUMN t_action_description TEXT NOT NULL DEFAULT ''")
<< QStringLiteral("ALTER TABLE rule ADD COLUMN t_action_definition TEXT NOT NULL DEFAULT ''")
<< QStringLiteral("DROP TRIGGER IF EXISTS fkdc_rule_action_id_rd_rule_id")
// ============
<< QLatin1String("")
<< QStringLiteral("1.8")
<< QStringLiteral("1.9")
<< QStringLiteral("DROP TABLE IF EXISTS operation2")
<< QStringLiteral("CREATE TABLE operation2("
"id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,"
"i_group_id INTEGER NOT NULL DEFAULT 0,"
"i_number INTEGER DEFAULT 0 CHECK (i_number>=0),"
"d_date DATE NOT NULL DEFAULT '0000-00-00',"
"rd_account_id INTEGER NOT NULL,"
"t_mode TEXT NOT NULL DEFAULT '',"
"t_payee TEXT NOT NULL DEFAULT '',"
"t_comment TEXT NOT NULL DEFAULT '',"
"rc_unit_id INTEGER NOT NULL,"
"t_status VARCHAR(1) DEFAULT 'N' CHECK (t_status IN ('N', 'P', 'Y')),"
"t_bookmarked VARCHAR(1) DEFAULT 'N' CHECK (t_bookmarked IN ('Y', 'N')),"
"t_imported VARCHAR(1) DEFAULT 'N' CHECK (t_imported IN ('Y', 'N', 'P')),"
"t_import_id TEXT DEFAULT '',"
"r_recurrentoperation_id INTEGER NOT NULL DEFAULT 0)")
<< QStringLiteral("INSERT INTO operation2 (id,i_group_id,i_number,d_date,rd_account_id,t_mode,t_payee,t_comment,rc_unit_id,"
"t_status,t_bookmarked,t_imported,t_import_id,r_recurrentoperation_id) "
"SELECT id,i_group_id,i_number,d_date,rd_account_id,t_mode,t_payee,t_comment,rc_unit_id,"
"(CASE WHEN t_status='C' THEN 'Y' ELSE t_status END),t_bookmarked,t_imported,t_import_id,r_recurrentoperation_id FROM operation")
<< QStringLiteral("DROP TABLE IF EXISTS operation")
<< QStringLiteral("ALTER TABLE operation2 RENAME TO operation")
// ============
<< QLatin1String("")
<< QStringLiteral("1.9")
<< QStringLiteral("2.0")
<< QStringLiteral("ALTER TABLE operation ADD COLUMN i_tmp INTEGER NOT NULL DEFAULT 0")
<< QStringLiteral("ALTER TABLE suboperation ADD COLUMN i_tmp INTEGER NOT NULL DEFAULT 0")
// ============
<< QLatin1String("")
<< QStringLiteral("2.0")
<< QStringLiteral("2.1")
<< QStringLiteral("ALTER TABLE operation ADD COLUMN t_template VARCHAR(1) NOT NULL DEFAULT 'N' CHECK (t_template IN ('Y', 'N'))")
// ============
<< QLatin1String("")
<< QStringLiteral("2.1")
<< QStringLiteral("2.2")
<< QStringLiteral("UPDATE recurrentoperation SET d_date=date(d_date,i_period_increment||(CASE WHEN t_period_unit='Y' THEN ' year' ELSE (CASE WHEN t_period_unit='M' THEN ' month' ELSE ' day' END) END))")
<< QStringLiteral("DROP TABLE IF EXISTS recurrentoperation2")
<< QStringLiteral("CREATE TABLE recurrentoperation2 ("
"id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,"
"d_date DATE NOT NULL DEFAULT '0000-00-00',"
"rd_operation_id INTEGER NOT NULL,"
"i_period_increment INTEGER NOT NULL DEFAULT 1 CHECK (i_period_increment>=0),"
"t_period_unit TEXT NOT NULL DEFAULT 'M' CHECK (t_period_unit IN ('D', 'M', 'Y')),"
"t_auto_write VARCHAR(1) DEFAULT 'Y' CHECK (t_auto_write IN ('Y', 'N')),"
"i_auto_write_days INTEGER NOT NULL DEFAULT 5 CHECK (i_auto_write_days>=0),"
"t_warn VARCHAR(1) DEFAULT 'Y' CHECK (t_warn IN ('Y', 'N')),"
"i_warn_days INTEGER NOT NULL DEFAULT 5 CHECK (i_warn_days>=0),"
"t_times VARCHAR(1) DEFAULT 'N' CHECK (t_times IN ('Y', 'N')),"
"i_nb_times INTEGER NOT NULL DEFAULT 1 CHECK (i_nb_times>=0)"
")")
<< QStringLiteral("INSERT INTO recurrentoperation2 (id,d_date,rd_operation_id,i_period_increment,t_period_unit,t_auto_write,i_auto_write_days,t_warn,i_warn_days) "
"SELECT id,d_date,rd_operation_id,i_period_increment,t_period_unit,t_auto_write,i_auto_write_days,t_warn,i_warn_days FROM recurrentoperation")
<< QStringLiteral("DROP TABLE IF EXISTS recurrentoperation")
<< QStringLiteral("ALTER TABLE recurrentoperation2 RENAME TO recurrentoperation")
// ============
<< QLatin1String("")
<< QStringLiteral("2.2")
<< QStringLiteral("2.3")
<< QStringLiteral("UPDATE rule SET t_definition=replace(t_definition,'%9','#ATT#')")
<< QStringLiteral("UPDATE rule SET t_definition=replace(t_definition,'''%1''','''#V1S#''')")
<< QStringLiteral("UPDATE rule SET t_definition=replace(t_definition,'''%2''','''#V2S#''')")
<< QStringLiteral("UPDATE rule SET t_definition=replace(t_definition,'''%%1%''','''%#V1S#%''')")
<< QStringLiteral("UPDATE rule SET t_definition=replace(t_definition,'''%1%''','''#V1S#%''')")
<< QStringLiteral("UPDATE rule SET t_definition=replace(t_definition,'''%%1''','''%#V1S#''')")
<< QStringLiteral("UPDATE rule SET t_definition=replace(t_definition,'%1','#V1#')")
<< QStringLiteral("UPDATE rule SET t_definition=replace(t_definition,'%2','#V2#')")
<< QStringLiteral("UPDATE rule SET t_action_definition=replace(t_action_definition,'%9','#ATT#')")
<< QStringLiteral("UPDATE rule SET t_action_definition=replace(t_action_definition,'''%1''','''#V1S#''')")
<< QStringLiteral("UPDATE rule SET t_action_definition=replace(t_action_definition,'''%2''','''#V2S#''')")
<< QStringLiteral("UPDATE rule SET t_action_definition=replace(t_action_definition,'''%%1%''','''%#V1S#%''')")
<< QStringLiteral("UPDATE rule SET t_action_definition=replace(t_action_definition,'''%1%''','''#V1S#%''')")
<< QStringLiteral("UPDATE rule SET t_action_definition=replace(t_action_definition,'''%%1''','''%#V1S#''')")
<< QStringLiteral("UPDATE rule SET t_action_definition=replace(t_action_definition,'%1','#V1#')")
<< QStringLiteral("UPDATE rule SET t_action_definition=replace(t_action_definition,'%2','#V2#')")
// ============
<< QLatin1String("")
<< QStringLiteral("2.3")
<< QStringLiteral("2.4")
<< QStringLiteral("UPDATE operation SET t_template='N' WHERE t_template NOT IN ('Y', 'N')")
// ============
<< QLatin1String("")
<< QStringLiteral("2.4")
<< QStringLiteral("2.5")
<< QStringLiteral("ALTER TABLE rule ADD COLUMN t_action_type VARCHAR(1) DEFAULT 'S' CHECK (t_action_type IN ('S', 'U', 'A'))")
<< QStringLiteral("UPDATE rule SET t_action_type='S' WHERE t_action_type NOT IN ('S', 'U', 'A') AND t_action_definition=''")
<< QStringLiteral("UPDATE rule SET t_action_type='U' WHERE t_action_type NOT IN ('S', 'U', 'A') AND t_action_definition!=''")
// ============
<< QLatin1String("")
<< QStringLiteral("2.5")
<< QStringLiteral("2.6")
<< QStringLiteral("ALTER TABLE unit ADD COLUMN i_nbdecimal INT NOT NULL DEFAULT 2")
<< QStringLiteral("UPDATE unit SET i_nbdecimal=2")
// ============
<< QLatin1String("")
<< QStringLiteral("2.6")
<< QStringLiteral("2.7")
<< QStringLiteral("CREATE TABLE operation2("
"id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,"
"i_group_id INTEGER NOT NULL DEFAULT 0,"
"i_number INTEGER DEFAULT 0 CHECK (i_number>=0),"
"d_date DATE NOT NULL DEFAULT '0000-00-00',"
"rd_account_id INTEGER NOT NULL,"
"t_mode TEXT NOT NULL DEFAULT '',"
"t_payee TEXT NOT NULL DEFAULT '',"
"t_comment TEXT NOT NULL DEFAULT '',"
"rc_unit_id INTEGER NOT NULL,"
"t_status VARCHAR(1) NOT NULL DEFAULT 'N' CHECK (t_status IN ('N', 'P', 'Y')),"
"t_bookmarked VARCHAR(1) NOT NULL DEFAULT 'N' CHECK (t_bookmarked IN ('Y', 'N')),"
"t_imported VARCHAR(1) NOT NULL DEFAULT 'N' CHECK (t_imported IN ('Y', 'N', 'P', 'T')),"
"t_template VARCHAR(1) NOT NULL DEFAULT 'N' CHECK (t_template IN ('Y', 'N')),"
"t_import_id TEXT NOT NULL DEFAULT '',"
"i_tmp INTEGER NOT NULL DEFAULT 0,"
"r_recurrentoperation_id INTEGER NOT NULL DEFAULT 0)")
<< QStringLiteral("INSERT INTO operation2 ("
"id,i_group_id,i_number,d_date,rd_account_id,t_mode,t_payee,t_comment,rc_unit_id,t_status,t_bookmarked,t_imported,t_template,t_import_id,i_tmp,r_recurrentoperation_id) "
"SELECT id,i_group_id,i_number,d_date,rd_account_id,t_mode,t_payee,t_comment,rc_unit_id,t_status,t_bookmarked,t_imported,t_template,t_import_id,i_tmp,r_recurrentoperation_id FROM operation")
<< QStringLiteral("DROP TABLE IF EXISTS operation")
<< QStringLiteral("ALTER TABLE operation2 RENAME TO operation")
// ============
<< QLatin1String("")
<< QStringLiteral("2.7")
<< QStringLiteral("2.8")
<< QStringLiteral("UPDATE rule SET t_action_type='U' WHERE t_action_type='S' AND t_action_definition!=''")
// ============
<< QLatin1String("")
<< QStringLiteral("2.8")
<< QStringLiteral("2.9")
<< QStringLiteral("DROP TABLE IF EXISTS interest")
<< QStringLiteral("CREATE TABLE interest("
"id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,"
"rd_account_id INTEGER NOT NULL,"
"d_date DATE NOT NULL,"
"f_rate FLOAT NOT NULL CHECK (f_rate>=0),"
"t_income_value_date_mode VARCHAR(1) NOT NULL DEFAULT 'F' CHECK (t_income_value_date_mode IN ('F', '0', '1', '2', '3', '4', '5')),"
"t_expenditure_value_date_mode VARCHAR(1) NOT NULL DEFAULT 'F' CHECK (t_expenditure_value_date_mode IN ('F', '0', '1', '2', '3', '4', '5')),"
"t_base VARCHAR(3) NOT NULL DEFAULT '24' CHECK (t_base IN ('24', '360', '365'))"
")")
// ============
<< QLatin1String("")
<< QStringLiteral("2.9")
<< QStringLiteral("3.0")
// Current month
<< QStringLiteral("UPDATE node SET t_data=replace(t_data, 'period=\"\"1\"\"', 'period=\"\"1\"\" interval=\"\"2\"\" nb_intervals=\"\"1\"\"') WHERE t_data like '%Skrooge report plugin%'")
// Previous month
<< QStringLiteral("UPDATE node SET t_data=replace(t_data, 'period=\"\"2\"\"', 'period=\"\"2\"\" interval=\"\"2\"\" nb_intervals=\"\"1\"\"') WHERE t_data like '%Skrooge report plugin%'")
// Current year
<< QStringLiteral("UPDATE node SET t_data=replace(t_data, 'period=\"\"3\"\"', 'period=\"\"1\"\" interval=\"\"3\"\" nb_intervals=\"\"1\"\"') WHERE t_data like '%Skrooge report plugin%'")
// Previous year
<< QStringLiteral("UPDATE node SET t_data=replace(t_data, 'period=\"\"4\"\"', 'period=\"\"2\"\" interval=\"\"3\"\" nb_intervals=\"\"1\"\"') WHERE t_data like '%Skrooge report plugin%'")
// Last 30 days
<< QStringLiteral("UPDATE node SET t_data=replace(t_data, 'period=\"\"5\"\"', 'period=\"\"3\"\" interval=\"\"0\"\" nb_intervals=\"\"30\"\"') WHERE t_data like '%Skrooge report plugin%'")
// Last 3 months
<< QStringLiteral("UPDATE node SET t_data=replace(t_data, 'period=\"\"6\"\"', 'period=\"\"3\"\" interval=\"\"2\"\" nb_intervals=\"\"3\"\"') WHERE t_data like '%Skrooge report plugin%'")
// Last 6 months
<< QStringLiteral("UPDATE node SET t_data=replace(t_data, 'period=\"\"7\"\"', 'period=\"\"3\"\" interval=\"\"2\"\" nb_intervals=\"\"6\"\"') WHERE t_data like '%Skrooge report plugin%'")
// Last 12 months
<< QStringLiteral("UPDATE node SET t_data=replace(t_data, 'period=\"\"8\"\"', 'period=\"\"3\"\" interval=\"\"2\"\" nb_intervals=\"\"12\"\"') WHERE t_data like '%Skrooge report plugin%'")
// Last 2 years
<< QStringLiteral("UPDATE node SET t_data=replace(t_data, 'period=\"\"9\"\"', 'period=\"\"3\"\" interval=\"\"3\"\" nb_intervals=\"\"2\"\"') WHERE t_data like '%Skrooge report plugin%'")
// Last 3 years
<< QStringLiteral("UPDATE node SET t_data=replace(t_data, 'period=\"\"10\"\"', 'period=\"\"3\"\" interval=\"\"3\"\" nb_intervals=\"\"3\"\"') WHERE t_data like '%Skrooge report plugin%'")
// Last 5 years
<< QStringLiteral("UPDATE node SET t_data=replace(t_data, 'period=\"\"11\"\"', 'period=\"\"3\"\" interval=\"\"3\"\" nb_intervals=\"\"5\"\"') WHERE t_data like '%Skrooge report plugin%'")
// Custom...
<< QStringLiteral("UPDATE node SET t_data=replace(t_data, 'period=\"\"12\"\"', 'period=\"\"4\"\"') WHERE t_data like '%Skrooge report plugin%'")
// All without transfers
<< QStringLiteral("UPDATE node SET t_data=replace(t_data, 'type=\"\"0\"\"', 'incomes=\"\"Y\"\" expenses=\"\"Y\"\" transfers=\"\"N\"\"') WHERE t_data like '%Skrooge report plugin%'")
// Income without transfers
<< QStringLiteral("UPDATE node SET t_data=replace(t_data, 'type=\"\"1\"\"', 'incomes=\"\"Y\"\" expenses=\"\"N\"\" transfers=\"\"N\"\"') WHERE t_data like '%Skrooge report plugin%'")
// Expenditure without transfers
<< QStringLiteral("UPDATE node SET t_data=replace(t_data, 'type=\"\"2\"\"', 'incomes=\"\"N\"\" expenses=\"\"Y\"\" transfers=\"\"N\"\"') WHERE t_data like '%Skrooge report plugin%'")
// All with transfers
<< QStringLiteral("UPDATE node SET t_data=replace(t_data, 'type=\"\"3\"\"', 'incomes=\"\"Y\"\" expenses=\"\"Y\"\" transfers=\"\"Y\"\"') WHERE t_data like '%Skrooge report plugin%'")
// Income with transfers
<< QStringLiteral("UPDATE node SET t_data=replace(t_data, 'type=\"\"4\"\"', 'incomes=\"\"Y\"\" expenses=\"\"N\"\" transfers=\"\"Y\"\"') WHERE t_data like '%Skrooge report plugin%'")
// Expenditure with transfers
<< QStringLiteral("UPDATE node SET t_data=replace(t_data, 'type=\"\"5\"\"', 'incomes=\"\"N\"\" expenses=\"\"Y\"\" transfers=\"\"Y\"\"') WHERE t_data like '%Skrooge report plugin%'")
// ============
<< QLatin1String("")
<< QStringLiteral("3.0")
<< QStringLiteral("3.1")
<< QStringLiteral("UPDATE node SET t_data=replace(t_data, 'columns=\"\"2\"\"', 'columns=\"\"4\"\"') WHERE t_data like '%Skrooge report plugin%'")
<< QStringLiteral("UPDATE node SET t_data=replace(t_data, 'columns=\"\"1\"\"', 'columns=\"\"3\"\"') WHERE t_data like '%Skrooge report plugin%'")
// ============
<< QLatin1String("")
<< QStringLiteral("3.1")
<< QStringLiteral("3.2")
<< QStringLiteral("UPDATE parameters SET t_name='SKGSEARCH_DEFAULT_PARAMETERS' WHERE t_name='SKGIMPORT_DEFAULT_PARAMETERS'")
// ============
<< QLatin1String("")
<< QStringLiteral("3.2")
<< QStringLiteral("3.3")
<< QStringLiteral("UPDATE node SET t_data=replace(t_data, ' columns=&quot;4&quot;', ' columns=&quot;&quot;') WHERE t_data like '%graphicViewState=%'")
<< QStringLiteral("UPDATE node SET t_data=replace(t_data, ' columns=&quot;3&quot;', ' columns=&quot;d_DATEYEAR&quot;') WHERE t_data like '%graphicViewState=%'")
<< QStringLiteral("UPDATE node SET t_data=replace(t_data, ' columns=&quot;2&quot;', ' columns=&quot;d_DATESEMESTER&quot;') WHERE t_data like '%graphicViewState=%'")
<< QStringLiteral("UPDATE node SET t_data=replace(t_data, ' columns=&quot;1&quot;', ' columns=&quot;d_DATEQUARTER&quot;') WHERE t_data like '%graphicViewState=%'")
<< QStringLiteral("UPDATE node SET t_data=replace(t_data, ' columns=&quot;0&quot;', ' columns=&quot;d_DATEMONTH&quot;') WHERE t_data like '%graphicViewState=%'")
<< QStringLiteral("UPDATE node SET t_data=replace(t_data, ' columns=\"\"4\"\"', ' columns=\"\"\"\"') WHERE t_data like '%graphicViewState=%'")
<< QStringLiteral("UPDATE node SET t_data=replace(t_data, ' columns=\"\"3\"\"', ' columns=\"\"d_DATEYEAR\"\"') WHERE t_data like '%graphicViewState=%'")
<< QStringLiteral("UPDATE node SET t_data=replace(t_data, ' columns=\"\"2\"\"', ' columns=\"\"d_DATESEMESTER\"\"') WHERE t_data like '%graphicViewState=%'")
<< QStringLiteral("UPDATE node SET t_data=replace(t_data, ' columns=\"\"1\"\"', ' columns=\"\"d_DATEQUARTER\"\"') WHERE t_data like '%graphicViewState=%'")
<< QStringLiteral("UPDATE node SET t_data=replace(t_data, ' columns=\"\"0\"\"', ' columns=\"\"d_DATEMONTH\"\"') WHERE t_data like '%graphicViewState=%'")
<< QStringLiteral("UPDATE parameters SET t_value=replace(t_value, ' columns=&quot;4&quot;', ' columns=&quot;&quot;') WHERE t_name='SKGDASHBOARD_DEFAULT_PARAMETERS'")
<< QStringLiteral("UPDATE parameters SET t_value=replace(t_value, ' columns=&quot;3&quot;', ' columns=&quot;d_DATEYEAR&quot;') WHERE t_name='SKGDASHBOARD_DEFAULT_PARAMETERS'")
<< QStringLiteral("UPDATE parameters SET t_value=replace(t_value, ' columns=&quot;2&quot;', ' columns=&quot;d_DATESEMESTER&quot;') WHERE t_name='SKGDASHBOARD_DEFAULT_PARAMETERS'")
<< QStringLiteral("UPDATE parameters SET t_value=replace(t_value, ' columns=&quot;1&quot;', ' columns=&quot;d_DATEQUARTER&quot;') WHERE t_name='SKGDASHBOARD_DEFAULT_PARAMETERS'")
<< QStringLiteral("UPDATE parameters SET t_value=replace(t_value, ' columns=&quot;0&quot;', ' columns=&quot;d_DATEMONTH&quot;') WHERE t_name='SKGDASHBOARD_DEFAULT_PARAMETERS'")
<< QStringLiteral("UPDATE node SET t_data=replace(t_data, ' lines=&quot;0&quot;', ' lines=&quot;t_REALCATEGORY&quot;') WHERE t_data like '%graphicViewState=%'")
<< QStringLiteral("UPDATE node SET t_data=replace(t_data, ' lines=&quot;1&quot;', ' lines=&quot;t_payee&quot;') WHERE t_data like '%graphicViewState=%'")
<< QStringLiteral("UPDATE node SET t_data=replace(t_data, ' lines=&quot;2&quot;', ' lines=&quot;t_mode&quot;') WHERE t_data like '%graphicViewState=%'")
<< QStringLiteral("UPDATE node SET t_data=replace(t_data, ' lines=&quot;3&quot;', ' lines=&quot;t_TYPEEXPENSENLS&quot;') WHERE t_data like '%graphicViewState=%'")
<< QStringLiteral("UPDATE node SET t_data=replace(t_data, ' lines=&quot;4&quot;', ' lines=&quot;t_status&quot;') WHERE t_data like '%graphicViewState=%'")
<< QStringLiteral("UPDATE node SET t_data=replace(t_data, ' lines=&quot;5&quot;', ' lines=&quot;t_ACCOUNTTYPE&quot;') WHERE t_data like '%graphicViewState=%'")
<< QStringLiteral("UPDATE node SET t_data=replace(t_data, ' lines=&quot;6&quot;', ' lines=&quot;t_UNITTYPE&quot;') WHERE t_data like '%graphicViewState=%'")
<< QStringLiteral("UPDATE node SET t_data=replace(t_data, ' lines=&quot;7&quot;', ' lines=&quot;t_REALREFUND&quot;') WHERE t_data like '%graphicViewState=%'")
<< QStringLiteral("UPDATE node SET t_data=replace(t_data, ' lines=\"\"0\"\"', ' lines=\"\"t_REALCATEGORY\"\"') WHERE t_data like '%graphicViewState=%'")
<< QStringLiteral("UPDATE node SET t_data=replace(t_data, ' lines=\"\"1\"\"', ' lines=\"\"t_payee\"\"') WHERE t_data like '%graphicViewState=%'")
<< QStringLiteral("UPDATE node SET t_data=replace(t_data, ' lines=\"\"2\"\"', ' lines=\"\"t_mode\"\"') WHERE t_data like '%graphicViewState=%'")
<< QStringLiteral("UPDATE node SET t_data=replace(t_data, ' lines=\"\"3\"\"', ' lines=\"\"t_TYPEEXPENSENLS\"\"') WHERE t_data like '%graphicViewState=%'")
<< QStringLiteral("UPDATE node SET t_data=replace(t_data, ' lines=\"\"4\"\"', ' lines=\"\"t_status\"\"') WHERE t_data like '%graphicViewState=%'")
<< QStringLiteral("UPDATE node SET t_data=replace(t_data, ' lines=\"\"5\"\"', ' lines=\"\"t_ACCOUNTTYPE\"\"') WHERE t_data like '%graphicViewState=%'")
<< QStringLiteral("UPDATE node SET t_data=replace(t_data, ' lines=\"\"6\"\"', ' lines=\"\"t_UNITTYPE\"\"') WHERE t_data like '%graphicViewState=%'")
<< QStringLiteral("UPDATE node SET t_data=replace(t_data, ' lines=\"\"7\"\"', ' lines=\"\"t_REALREFUND\"\"') WHERE t_data like '%graphicViewState=%'")
<< QStringLiteral("UPDATE parameters SET t_value=replace(t_value, ' lines=&quot;0&quot;', ' lines=&quot;t_REALCATEGORY&quot;') WHERE t_name='SKGDASHBOARD_DEFAULT_PARAMETERS'")
<< QStringLiteral("UPDATE parameters SET t_value=replace(t_value, ' lines=&quot;1&quot;', ' lines=&quot;t_payee&quot;') WHERE t_name='SKGDASHBOARD_DEFAULT_PARAMETERS'")
<< QStringLiteral("UPDATE parameters SET t_value=replace(t_value, ' lines=&quot;2&quot;', ' lines=&quot;t_mode&quot;') WHERE t_name='SKGDASHBOARD_DEFAULT_PARAMETERS'")
<< QStringLiteral("UPDATE parameters SET t_value=replace(t_value, ' lines=&quot;3&quot;', ' lines=&quot;t_TYPEEXPENSENLS&quot;') WHERE t_name='SKGDASHBOARD_DEFAULT_PARAMETERS'")
<< QStringLiteral("UPDATE parameters SET t_value=replace(t_value, ' lines=&quot;4&quot;', ' lines=&quot;t_status&quot;') WHERE t_name='SKGDASHBOARD_DEFAULT_PARAMETERS'")
<< QStringLiteral("UPDATE parameters SET t_value=replace(t_value, ' lines=&quot;5&quot;', ' lines=&quot;t_ACCOUNTTYPE&quot;') WHERE t_name='SKGDASHBOARD_DEFAULT_PARAMETERS'")
<< QStringLiteral("UPDATE parameters SET t_value=replace(t_value, ' lines=&quot;6&quot;', ' lines=&quot;t_UNITTYPE&quot;') WHERE t_name='SKGDASHBOARD_DEFAULT_PARAMETERS'")
<< QStringLiteral("UPDATE parameters SET t_value=replace(t_value, ' lines=&quot;7&quot;', ' lines=&quot;t_REALREFUND&quot;') WHERE t_name='SKGDASHBOARD_DEFAULT_PARAMETERS'")
// ============
<< QLatin1String("")
<< QStringLiteral("3.3")
<< QStringLiteral("3.4")
<< QStringLiteral("UPDATE parameters SET t_value=replace(t_value, ' columns=\"4\"', ' columns=\"\"') WHERE t_name='SKGREPORT_DEFAULT_PARAMETERS'")
<< QStringLiteral("UPDATE parameters SET t_value=replace(t_value, ' columns=\"3\"', ' columns=\"d_DATEYEAR\"') WHERE t_name='SKGREPORT_DEFAULT_PARAMETERS'")
<< QStringLiteral("UPDATE parameters SET t_value=replace(t_value, ' columns=\"2\"', ' columns=\"d_DATESEMESTER\"') WHERE t_name='SKGREPORT_DEFAULT_PARAMETERS'")
<< QStringLiteral("UPDATE parameters SET t_value=replace(t_value, ' columns=\"1\"', ' columns=\"d_DATEQUARTER\"') WHERE t_name='SKGREPORT_DEFAULT_PARAMETERS'")
<< QStringLiteral("UPDATE parameters SET t_value=replace(t_value, ' columns=\"0\"', ' columns=\"d_DATEMONTH\"') WHERE t_name='SKGREPORT_DEFAULT_PARAMETERS'")
<< QStringLiteral("UPDATE parameters SET t_value=replace(t_value, ' lines=\"0\"', ' lines=\"t_REALCATEGORY\"') WHERE t_name='SKGREPORT_DEFAULT_PARAMETERS'")
<< QStringLiteral("UPDATE parameters SET t_value=replace(t_value, ' lines=\"1\"', ' lines=\"t_payee\"') WHERE t_name='SKGREPORT_DEFAULT_PARAMETERS'")
<< QStringLiteral("UPDATE parameters SET t_value=replace(t_value, ' lines=\"2\"', ' lines=\"t_mode\"') WHERE t_name='SKGREPORT_DEFAULT_PARAMETERS'")
<< QStringLiteral("UPDATE parameters SET t_value=replace(t_value, ' lines=\"3\"', ' lines=\"t_TYPEEXPENSENLS\"') WHERE t_name='SKGREPORT_DEFAULT_PARAMETERS'")
<< QStringLiteral("UPDATE parameters SET t_value=replace(t_value, ' lines=\"4\"', ' lines=\"t_status\"') WHERE t_name='SKGREPORT_DEFAULT_PARAMETERS'")
<< QStringLiteral("UPDATE parameters SET t_value=replace(t_value, ' lines=\"5\"', ' lines=\"t_ACCOUNTTYPE\"') WHERE t_name='SKGREPORT_DEFAULT_PARAMETERS'")
<< QStringLiteral("UPDATE parameters SET t_value=replace(t_value, ' lines=\"6\"', ' lines=\"t_UNITTYPE\"') WHERE t_name='SKGREPORT_DEFAULT_PARAMETERS'")
<< QStringLiteral("UPDATE parameters SET t_value=replace(t_value, ' lines=\"7\"', ' lines=\"t_REALREFUND\"') WHERE t_name='SKGREPORT_DEFAULT_PARAMETERS'")
// ============
<< QLatin1String("")
<< QStringLiteral("3.4")
<< QStringLiteral("3.5")
<< QStringLiteral("ALTER TABLE account ADD COLUMN t_bookmarked VARCHAR(1) NOT NULL DEFAULT 'N' CHECK (t_bookmarked IN ('Y', 'N'))")
<< QStringLiteral("UPDATE account SET t_bookmarked='N'")
// ============
<< QLatin1String("")
<< QStringLiteral("3.5")
<< QStringLiteral("3.6")
<< QStringLiteral("ALTER TABLE rule ADD COLUMN t_bookmarked VARCHAR(1) NOT NULL DEFAULT 'N' CHECK (t_bookmarked IN ('Y', 'N'))")
<< QStringLiteral("UPDATE rule SET t_bookmarked='N'")
// ============
<< QLatin1String("")
<< QStringLiteral("3.6")
<< QStringLiteral("3.7")
<< QStringLiteral("UPDATE suboperation SET r_category_id=0 WHERE r_category_id=(SELECT id FROM category WHERE t_name='')")
<< QStringLiteral("DELETE FROM category WHERE t_name=''")
// ============
<< QLatin1String("")
<< QStringLiteral("3.7")
<< QStringLiteral("3.8")
<< QStringLiteral("UPDATE recurrentoperation SET t_times='N' WHERE t_times IS NULL")
// ============
<< QLatin1String("")
<< QStringLiteral("3.8")
<< QStringLiteral("3.9")
<< QStringLiteral("UPDATE node SET t_data=replace(t_data, 'Skrooge dashboard plugin', 'Dashboard plugin') WHERE t_data like '%Skrooge dashboard plugin%'")
// ============
<< QLatin1String("")
<< QStringLiteral("3.9")
<< QStringLiteral("4.0")
<< "UPDATE rule SET t_definition=replace(t_definition, '" % SKGServices::stringToSqlString(QStringLiteral("date('now','-1")) % "', '" % SKGServices::stringToSqlString(QStringLiteral("date('now','start of month','-1")) % "')"
// ============
<< QLatin1String("")
<< QStringLiteral("4.0")
<< QStringLiteral("4.1")
<< QStringLiteral("UPDATE rule SET t_definition=replace(t_definition,'t_REFUND','t_REALREFUND')")
<< QStringLiteral("UPDATE rule SET t_action_definition=replace(t_action_definition,'t_REFUND','t_REALREFUND')")
// ============
<< QLatin1String("")
<< QStringLiteral("4.1")
<< QStringLiteral("4.2")
<< QStringLiteral("UPDATE operation SET t_imported='Y' WHERE t_imported='T'")
<< QStringLiteral("UPDATE operation SET t_imported='N' WHERE t_imported!='N' AND t_import_id='';")
// ============
<< QLatin1String("")
<< QStringLiteral("4.2")
<< QStringLiteral("4.3")
<< QStringLiteral("CREATE TABLE payee ("
"id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,"
"t_name TEXT NOT NULL DEFAULT '',"
"t_address TEXT NOT NULL DEFAULT '')")
<< QStringLiteral("INSERT INTO payee (t_name) "
"SELECT distinct(operation.t_payee) FROM operation WHERE operation.t_payee<>''")
<< QStringLiteral("CREATE TABLE operation2("
"id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,"
"i_group_id INTEGER NOT NULL DEFAULT 0,"
"i_number INTEGER DEFAULT 0 CHECK (i_number>=0),"
"d_date DATE NOT NULL DEFAULT '0000-00-00',"
"rd_account_id INTEGER NOT NULL,"
"t_mode TEXT NOT NULL DEFAULT '',"
"r_payee_id INTEGER NOT NULL DEFAULT 0,"
"t_comment TEXT NOT NULL DEFAULT '',"
"rc_unit_id INTEGER NOT NULL,"
"t_status VARCHAR(1) NOT NULL DEFAULT 'N' CHECK (t_status IN ('N', 'P', 'Y')),"
"t_bookmarked VARCHAR(1) NOT NULL DEFAULT 'N' CHECK (t_bookmarked IN ('Y', 'N')),"
"t_imported VARCHAR(1) NOT NULL DEFAULT 'N' CHECK (t_imported IN ('Y', 'N', 'P', 'T')),"
"t_template VARCHAR(1) NOT NULL DEFAULT 'N' CHECK (t_template IN ('Y', 'N')),"
"t_import_id TEXT NOT NULL DEFAULT '',"
"i_tmp INTEGER NOT NULL DEFAULT 0,"
"r_recurrentoperation_id INTEGER NOT NULL DEFAULT 0)")
<< QStringLiteral("INSERT INTO operation2 ("
"id,i_group_id,i_number,d_date,rd_account_id,t_mode,r_payee_id,t_comment,rc_unit_id,t_status,t_bookmarked,t_imported,t_template,t_import_id,i_tmp,r_recurrentoperation_id) "
"SELECT id,i_group_id,i_number,d_date,rd_account_id,t_mode,(CASE WHEN (SELECT payee.id FROM payee WHERE payee.t_name=operation.t_payee) IS NULL THEN 0 ELSE (SELECT payee.id FROM payee WHERE payee.t_name=operation.t_payee) END),t_comment,rc_unit_id,t_status,t_bookmarked,t_imported,t_template,t_import_id,i_tmp,r_recurrentoperation_id FROM operation")
<< QStringLiteral("DROP TABLE IF EXISTS operation")
<< QStringLiteral("ALTER TABLE operation2 RENAME TO operation")
<< QStringLiteral("UPDATE parameters SET t_value=replace(t_value, 't_payee', 't_PAYEE') WHERE t_name like '%_DEFAULT_PARAMETERS'")
// ============
<< QLatin1String("")
<< QStringLiteral("4.3")
<< QStringLiteral("4.4")
<< QStringLiteral("UPDATE rule SET t_definition=replace(t_definition, 't_payee', 't_PAYEE') WHERE t_definition like '%t_payee'")
<< QStringLiteral("UPDATE node SET t_data=replace(t_data, 't_payee', 't_PAYEE') WHERE t_data like '%t_payee'")
// ============
<< QLatin1String("")
<< QStringLiteral("4.4")
<< QStringLiteral("4.5")
<< QStringLiteral("UPDATE rule SET t_definition=replace(t_definition, 't_payee', 't_PAYEE') WHERE t_definition like '%t_payee%'")
<< QStringLiteral("UPDATE rule SET t_action_definition=replace(t_action_definition, 't_payee', 't_PAYEE') WHERE t_action_definition like '%t_payee%'")
// ============
<< QLatin1String("")
<< QStringLiteral("4.5")
<< QStringLiteral("4.6")
<< QStringLiteral("DELETE FROM suboperation WHERE NOT EXISTS (SELECT 1 FROM operation WHERE operation.id=suboperation.rd_operation_id)")
// ============
<< QLatin1String("")
<< QStringLiteral("4.6")
<< QStringLiteral("4.7")
<< QStringLiteral("UPDATE node SET t_data=replace(t_data, ' smoothScrolling=&quot;N&quot;', ' zoomPosition=&quot;0&quot;') WHERE t_data like '% smoothScrolling=&quot;N&quot;%'")
<< QStringLiteral("UPDATE node SET t_data=replace(t_data, ' smoothScrolling=&quot;Y&quot;', ' zoomPosition=&quot;0&quot;') WHERE t_data like '% smoothScrolling=&quot;Y&quot;%'")
<< QStringLiteral("UPDATE parameters SET t_value=replace(t_value, ' smoothScrolling=&quot;N&quot;', ' zoomPosition=&quot;0&quot;') WHERE t_value like '% smoothScrolling=&quot;N&quot;%'")
<< QStringLiteral("UPDATE parameters SET t_value=replace(t_value, ' smoothScrolling=&quot;Y&quot;', ' zoomPosition=&quot;0&quot;') WHERE t_value like '% smoothScrolling=&quot;Y&quot;%'")
// ============
<< QLatin1String("")
<< QStringLiteral("4.7")
<< QStringLiteral("4.8")
<< QStringLiteral("CREATE TABLE operationbalance("
"id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,"
"f_balance FLOAT NOT NULL DEFAULT 0,"
"r_operation_id INTEGER NOT NULL)")
// ============
<< QLatin1String("")
<< QStringLiteral("4.8")
<< QStringLiteral("4.9")
<<
QStringLiteral("UPDATE node SET t_data=replace(t_data, ' lines=&quot;t_ACCOUNTTYPE&quot; nbLevelLines=&quot;0&quot;', ' lines=&quot;&quot; nbLevelLines=&quot;0&quot;')")
<< QStringLiteral("UPDATE node SET t_data=replace(t_data, ' lines=\"\"t_ACCOUNTTYPE\"\" nbLevelLines=\"\"0\"\"', ' lines=\"\"\"\" nbLevelLines=\"\"0\"\"')")
<< QStringLiteral("UPDATE node SET t_data=replace(t_data, ' lines=&amp;quot;t_ACCOUNTTYPE&amp;quot; nbLevelLines=&amp;quot;0&amp;quot;', ' lines=&amp;quot;&amp;quot; nbLevelLines=&amp;quot;0&amp;quot;')")
<< QStringLiteral("UPDATE parameters SET t_value=replace(t_value, ' lines=&amp;quot;t_ACCOUNTTYPE&amp;quot; nbLevelLines=&amp;quot;0&amp;quot;', ' lines=&amp;quot;&amp;quot; nbLevelLines=&amp;quot;0&amp;quot;')")
<< QStringLiteral("UPDATE node SET t_data=replace(t_data, ' lines=&quot;t_UNITTYPE&quot;', ' lines=&quot;t_UNITTYPE&quot; lines2=&quot;t_UNIT&quot;')")
<< QStringLiteral("UPDATE node SET t_data=replace(t_data, ' lines=\"\"t_UNITTYPE\"\"', ' lines=\"\"t_UNITTYPE\"\" lines2=\"\"t_UNIT\"\"')")
<< QStringLiteral("UPDATE node SET t_data=replace(t_data, ' lines=&amp;quot;t_UNITTYPE&amp;quot;', ' lines=&amp;quot;t_UNITTYPE&amp;quot; lines2=&amp;quot;t_UNIT&amp;quot;')")
<< QStringLiteral("UPDATE parameters SET t_value=replace(t_value, ' lines=&amp;quot;t_UNITTYPE&amp;quot;', ' lines=&amp;quot;t_UNITTYPE&amp;quot; lines2=&amp;quot;t_UNIT&amp;quot;')")
<< QStringLiteral("UPDATE node SET t_data=replace(t_data, ' lines=&quot;t_ACCOUNTTYPE&quot;', ' lines=&quot;t_ACCOUNTTYPE&quot; lines2=&quot;t_ACCOUNT&quot;')")
<< QStringLiteral("UPDATE node SET t_data=replace(t_data, ' lines=\"\"t_ACCOUNTTYPE\"\"', ' lines=\"\"t_ACCOUNTTYPE\"\" lines2=\"\"t_ACCOUNT\"\"')")
<< QStringLiteral("UPDATE node SET t_data=replace(t_data, ' lines=&amp;quot;t_ACCOUNTTYPE&amp;quot;', ' lines=&amp;quot;t_ACCOUNTTYPE&amp;quot; lines2=&amp;quot;t_ACCOUNT&amp;quot;')")
<< QStringLiteral("UPDATE parameters SET t_value=replace(t_value, ' lines=&amp;quot;t_ACCOUNTTYPE&amp;quot;', ' lines=&amp;quot;t_ACCOUNTTYPE&amp;quot; lines2=&amp;quot;t_ACCOUNT&amp;quot;')")
// ============
<< QLatin1String("")
<< QStringLiteral("4.9")
<< QStringLiteral("5.0")
<< QStringLiteral("CREATE TABLE budget ("
"id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,"
"rc_category_id INTEGER NOT NULL DEFAULT 0,"
"f_budgeted FLOAT NOT NULL DEFAULT 0.0,"
"i_year INTEGER NOT NULL DEFAULT 2010,"
"i_month INTEGER NOT NULL DEFAULT 0 CHECK (i_month>=0 AND i_month<=12)"
")")
// ============
<< QLatin1String("")
<< QStringLiteral("5.0")
<< QStringLiteral("5.1")
<< QStringLiteral("CREATE TABLE budgetrule ("
"id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,"
"rc_category_id INTEGER NOT NULL DEFAULT 0,"
"i_year INTEGER NOT NULL DEFAULT 2010,"
"i_month INTEGER NOT NULL DEFAULT 0 CHECK (i_month>=0 AND i_month<=12),"
"i_condition INTEGER NOT NULL DEFAULT 0 CHECK (i_condition IN (-1,0,1)),"
"f_quantity FLOAT NOT NULL DEFAULT 0.0,"
"t_absolute TEXT NOT NULL DEFAULT 'Y' CHECK (t_absolute IN ('Y', 'N')),"
"rc_category_id_target INTEGER NOT NULL DEFAULT 0,"
"t_rule TEXT NOT NULL DEFAULT 'N' CHECK (t_rule IN ('N', 'C', 'Y'))"
")")
// ============
<< QLatin1String("")
<< QStringLiteral("5.1")
<< QStringLiteral("5.2")
<< QStringLiteral("CREATE TABLE budgetcategory("
"id INTEGER NOT NULL DEFAULT 0,"
"id_category INTEGER NOT NULL DEFAULT 0)")
// ============
<< QLatin1String("")
<< QStringLiteral("5.2")
<< QStringLiteral("5.3")
<< QStringLiteral("ALTER TABLE budget ADD COLUMN f_budgeted_modified FLOAT NOT NULL DEFAULT 0.0")
<< QStringLiteral("UPDATE budget SET f_budgeted_modified=f_budgeted")
// ============
<< QLatin1String("")
<< QStringLiteral("5.3")
<< QStringLiteral("5.4")
<< QStringLiteral("UPDATE node SET t_data=replace(t_data, ' lines=&quot;&quot;', ' lines=&quot;#NOTHING#&quot;')")
<< QStringLiteral("UPDATE node SET t_data=replace(t_data, ' lines=\"\"\"\"', ' lines=\"\"#NOTHING#\"\"')")
<< QStringLiteral("UPDATE node SET t_data=replace(t_data, ' lines=&amp;quot;&amp;quot;', ' lines=&amp;quot;#NOTHING#&amp;quot;')")
<< QStringLiteral("UPDATE parameters SET t_value=replace(t_value, ' lines=&amp;quot;&amp;quot;', ' lines=&amp;quot;#NOTHING#&amp;quot;')")
<< QStringLiteral("UPDATE node SET t_data=replace(t_data, ' lines2=&quot;&quot;', ' lines2=&quot;#NOTHING#&quot;')")
<< QStringLiteral("UPDATE node SET t_data=replace(t_data, ' lines2=\"\"\"\"', ' lines2=\"\"#NOTHING#\"\"')")
<< QStringLiteral("UPDATE node SET t_data=replace(t_data, ' lines2=&amp;quot;&amp;quot;', ' lines2=&amp;quot;#NOTHING#&amp;quot;')")
<< QStringLiteral("UPDATE parameters SET t_value=replace(t_value, ' lines2=&amp;quot;&amp;quot;', ' lines2=&amp;quot;#NOTHING#&amp;quot;')")
<< QStringLiteral("UPDATE node SET t_data=replace(t_data, ' columns=&quot;&quot;', ' columns=&quot;#NOTHING#&quot;')")
<< QStringLiteral("UPDATE node SET t_data=replace(t_data, ' columns=\"\"\"\"', ' columns=\"\"#NOTHING#\"\"')")
<< QStringLiteral("UPDATE node SET t_data=replace(t_data, ' columns=&amp;quot;&amp;quot;', ' columns=&amp;quot;#NOTHING#&amp;quot;')")
<< QStringLiteral("UPDATE parameters SET t_value=replace(t_value, ' columns=&amp;quot;&amp;quot;', ' columns=&amp;quot;#NOTHING#&amp;quot;')")
// ============
<< QLatin1String("")
<< QStringLiteral("5.4")
<< QStringLiteral("5.5")
<< QStringLiteral("ALTER TABLE budgetrule ADD COLUMN t_category_condition TEXT NOT NULL DEFAULT 'Y' CHECK (t_category_condition IN ('Y', 'N'))")
<< QStringLiteral("ALTER TABLE budgetrule ADD COLUMN t_year_condition TEXT NOT NULL DEFAULT 'Y' CHECK (t_year_condition IN ('Y', 'N'))")
<< QStringLiteral("ALTER TABLE budgetrule ADD COLUMN t_month_condition TEXT NOT NULL DEFAULT 'Y' CHECK (t_month_condition IN ('Y', 'N'))")
<< QStringLiteral("UPDATE budgetrule SET t_year_condition='Y'")
<< QStringLiteral("UPDATE budgetrule SET t_year_condition='N', i_year=2010 WHERE i_year=0")
<< QStringLiteral("UPDATE budgetrule SET t_month_condition='Y'")
<< QStringLiteral("UPDATE budgetrule SET t_month_condition='N', i_month=1 WHERE i_month=0")
<< QStringLiteral("UPDATE budgetrule SET t_category_condition='Y'")
<< QStringLiteral("UPDATE budgetrule SET t_category_condition='N' WHERE rc_category_id=0")
// ============
<< QLatin1String("")
<< QStringLiteral("5.5")
<< QStringLiteral("5.6")
<< QStringLiteral("ALTER TABLE budgetrule ADD COLUMN t_category_target TEXT NOT NULL DEFAULT 'Y' CHECK (t_category_target IN ('Y', 'N'))")
<< QStringLiteral("UPDATE budgetrule SET t_category_target='N'")
// ============
<< QLatin1String("")
<< QStringLiteral("5.6")
<< QStringLiteral("5.7")
<< QStringLiteral("ALTER TABLE budget ADD COLUMN f_transferred FLOAT NOT NULL DEFAULT 0.0")
<< QStringLiteral("UPDATE budget SET f_transferred=0")
// ============
<< QLatin1String("")
<< QStringLiteral("5.7")
<< QStringLiteral("5.8")
<< QStringLiteral("ALTER TABLE budget ADD COLUMN t_including_subcategories TEXT NOT NULL DEFAULT 'N' CHECK (t_including_subcategories IN ('Y', 'N'));")
<< QStringLiteral("UPDATE budget SET t_including_subcategories='N'")
// ============
<< QLatin1String("")
<< QStringLiteral("5.8")
<< QStringLiteral("5.9")
<< QStringLiteral("DELETE FROM parameters WHERE t_uuid_parent='advices';")
// ============
<< QLatin1String("")
<< QStringLiteral("5.9")
<< QStringLiteral("6.0")
<< QStringLiteral("UPDATE category SET t_name=t_name;")
// ============
<< QLatin1String("")
<< QStringLiteral("6.0")
<< QStringLiteral("6.1")
<< QStringLiteral("UPDATE node SET t_data=replace(t_data,'t_type', 't_TYPENLS')")
<< QStringLiteral("UPDATE parameters SET t_value=replace(t_value, 't_type', 't_TYPENLS') where t_name like '%_DEFAULT_PARAMETERS'")
// ============
<< QLatin1String("")
<< QStringLiteral("6.1")
<< QStringLiteral("6.2")
<< QStringLiteral("CREATE TABLE account2("
"id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,"
"t_name TEXT NOT NULL,"
"t_number TEXT NOT NULL DEFAULT '',"
"t_agency_number TEXT NOT NULL DEFAULT '',"
"t_agency_address TEXT NOT NULL DEFAULT '',"
"t_comment TEXT NOT NULL DEFAULT '',"
"t_close VARCHAR(1) DEFAULT 'N' CHECK (t_close IN ('Y', 'N')),"
"t_type VARCHAR(1) NOT NULL DEFAULT 'C' CHECK (t_type IN ('C', 'D', 'A', 'I', 'O', 'W')),"
// C=current D=credit card A=assets (for objects) I=Investment W=Wallet O=other
"t_bookmarked VARCHAR(1) NOT NULL DEFAULT 'N' CHECK (t_bookmarked IN ('Y', 'N')),"
"rd_bank_id INTEGER NOT NULL)")
<< QStringLiteral("INSERT INTO account2 (id, t_name, t_number, t_agency_number, t_agency_address, t_comment, t_close, t_type, t_bookmarked, rd_bank_id) "
"SELECT id, t_name, t_number, t_agency_number, t_agency_address, t_comment, t_close, t_type, t_bookmarked, rd_bank_id FROM account")
<< QStringLiteral("DROP TABLE IF EXISTS account")
<< QStringLiteral("ALTER TABLE account2 RENAME TO account")
// ============
<< QLatin1String("")
<< QStringLiteral("6.2")
<< QStringLiteral("6.3")
<< QStringLiteral("ALTER TABLE suboperation ADD COLUMN t_formula TEXT NOT NULL DEFAULT '';")
<< QStringLiteral("UPDATE suboperation SET t_formula=''")
// ============
<< QLatin1String("")
<< QStringLiteral("6.3")
<< QStringLiteral("6.4")
<< QStringLiteral("CREATE TABLE vm_category_display_tmp( id INT, t_name TEXT, t_fullname TEXT, rd_category_id INT, i_NBOPERATIONS, f_REALCURRENTAMOUNT)")
// ============
<< QLatin1String("")
<< QStringLiteral("6.4")
<< QStringLiteral("6.5")
<< QStringLiteral("ALTER TABLE category ADD COLUMN t_bookmarked VARCHAR(1) NOT NULL DEFAULT 'N' CHECK (t_bookmarked IN ('Y', 'N'));")
<< QStringLiteral("ALTER TABLE payee ADD COLUMN t_bookmarked VARCHAR(1) NOT NULL DEFAULT 'N' CHECK (t_bookmarked IN ('Y', 'N'));")
<< QStringLiteral("UPDATE category SET t_bookmarked='N'")
<< QStringLiteral("UPDATE payee SET t_bookmarked='N'")
// ============
<< QLatin1String("")
<< QStringLiteral("6.5")
<< QStringLiteral("6.6")
<< QStringLiteral("CREATE TABLE vm_budget_tmp( id INT, rc_category_id INT, f_budgeted REAL, i_year INT, i_month INT, f_budgeted_modified REAL, f_transferred REAL, t_including_subcategories TEXT, t_CATEGORY, t_PERIOD, f_CURRENTAMOUNT, t_RULES)")
// ============
<< QLatin1String("")
<< QStringLiteral("6.6")
<< QStringLiteral("6.7")
<< QStringLiteral("DROP TABLE IF EXISTS vm_category_display_tmp")
<< QStringLiteral("CREATE TABLE vm_category_display_tmp( id INT, t_name TEXT, t_fullname TEXT, rd_category_id INT, i_NBOPERATIONS, f_REALCURRENTAMOUNT, t_bookmarked)")
// ============
<< QLatin1String("")
<< QStringLiteral("6.7")
<< QStringLiteral("6.8")
<< QStringLiteral("CREATE TABLE recurrentoperation2 ("
"id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,"
"d_date DATE NOT NULL DEFAULT '0000-00-00',"
"rd_operation_id INTEGER NOT NULL,"
"i_period_increment INTEGER NOT NULL DEFAULT 1 CHECK (i_period_increment>=0),"
"t_period_unit TEXT NOT NULL DEFAULT 'M' CHECK (t_period_unit IN ('D', 'W', 'M', 'Y')),"
"t_auto_write VARCHAR(1) DEFAULT 'Y' CHECK (t_auto_write IN ('Y', 'N')),"
"i_auto_write_days INTEGER NOT NULL DEFAULT 5 CHECK (i_auto_write_days>=0),"
"t_warn VARCHAR(1) DEFAULT 'Y' CHECK (t_warn IN ('Y', 'N')),"
"i_warn_days INTEGER NOT NULL DEFAULT 5 CHECK (i_warn_days>=0),"
"t_times VARCHAR(1) DEFAULT 'N' CHECK (t_times IN ('Y', 'N')),"
"i_nb_times INTEGER NOT NULL DEFAULT 1 CHECK (i_nb_times>=0)"
")")
<< QStringLiteral("INSERT INTO recurrentoperation2 (id,d_date,rd_operation_id,i_period_increment,t_period_unit,t_auto_write,i_auto_write_days,t_warn,i_warn_days,t_times,i_nb_times) "
"SELECT id,d_date,rd_operation_id,i_period_increment,t_period_unit,t_auto_write,i_auto_write_days,t_warn,i_warn_days,t_times,i_nb_times FROM recurrentoperation")
<< QStringLiteral("DROP TABLE IF EXISTS recurrentoperation")
<< QStringLiteral("ALTER TABLE recurrentoperation2 RENAME TO recurrentoperation")
// ============
<< QLatin1String("")
<< QStringLiteral("6.8")
<< QStringLiteral("6.9")
<< "CREATE TABLE category2 ("
"id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,"
"t_name TEXT NOT NULL DEFAULT '' CHECK (t_name NOT LIKE '%" % OBJECTSEPARATOR % "%'),"
"t_fullname TEXT,"
"rd_category_id INT,"
"t_bookmarked VARCHAR(1) NOT NULL DEFAULT 'N' CHECK (t_bookmarked IN ('Y', 'N'))"
")"
<< QStringLiteral("INSERT INTO category2 (id, t_name, t_fullname, rd_category_id, t_bookmarked) "
"SELECT id, t_name, t_fullname, r_category_id, t_bookmarked FROM category")
<< QStringLiteral("DROP TABLE IF EXISTS category")
<< QStringLiteral("ALTER TABLE category2 RENAME TO category")
<< QStringLiteral("DROP TABLE IF EXISTS vm_category_display_tmp")
<< QStringLiteral("CREATE TABLE vm_category_display_tmp( id INT, t_name TEXT, t_fullname TEXT, rd_category_id INT, i_NBOPERATIONS, f_REALCURRENTAMOUNT, t_bookmarked)")
// ============
<< QLatin1String("")
<< QStringLiteral("6.9")
<< QStringLiteral("7.0")
<< QStringLiteral("DELETE FROM parameters WHERE t_name LIKE 'SKG_MONTHLY_REPORT_%'")
// ============ SKROOGE 1.0.0 ^^^
<< QLatin1String("")
<< QStringLiteral("7.0")
<< QStringLiteral("7.1")
<< QStringLiteral("ALTER TABLE unit ADD COLUMN t_source TEXT NOT NULL DEFAULT ''")
<< QStringLiteral("UPDATE unit SET t_source=''")
// ============
<< QLatin1String("")
<< QStringLiteral("7.1")
<< QStringLiteral("7.2")
<< QStringLiteral("UPDATE unit SET t_source='Yahoo' WHERE t_source='' AND t_internet_code<>''")
// ============
<< QLatin1String("")
<< QStringLiteral("7.2")
<< QStringLiteral("7.3")
<< QStringLiteral("CREATE TABLE account2("
"id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,"
"t_name TEXT NOT NULL,"
"t_number TEXT NOT NULL DEFAULT '',"
"t_agency_number TEXT NOT NULL DEFAULT '',"
"t_agency_address TEXT NOT NULL DEFAULT '',"
"t_comment TEXT NOT NULL DEFAULT '',"
"t_close VARCHAR(1) DEFAULT 'N' CHECK (t_close IN ('Y', 'N')),"
"t_type VARCHAR(1) NOT NULL DEFAULT 'C' CHECK (t_type IN ('C', 'D', 'A', 'I', 'L', 'W', 'O')),"
// C=current D=credit card A=assets (for objects) I=Investment W=Wallet L=Loan O=other
"t_bookmarked VARCHAR(1) NOT NULL DEFAULT 'N' CHECK (t_bookmarked IN ('Y', 'N')),"
"rd_bank_id INTEGER NOT NULL)")
<< QStringLiteral("INSERT INTO account2 (id, t_name, t_number, t_agency_number, t_agency_address, t_comment, t_close, t_type, t_bookmarked, rd_bank_id) "
"SELECT id, t_name, t_number, t_agency_number, t_agency_address, t_comment, t_close, t_type, t_bookmarked, rd_bank_id FROM account")
<< QStringLiteral("DROP TABLE IF EXISTS account")
<< QStringLiteral("ALTER TABLE account2 RENAME TO account")
// ============ SKROOGE 1.1.0 ^^^
<< QLatin1String("")
<< QStringLiteral("7.3")
<< QStringLiteral("7.4")
<< QStringLiteral("ALTER TABLE unit ADD COLUMN t_bookmarked VARCHAR(1) NOT NULL DEFAULT 'N' CHECK (t_bookmarked IN ('Y', 'N'))")
<< QStringLiteral("UPDATE unit SET t_bookmarked='N'")
// ============
<< QLatin1String("")
<< QStringLiteral("7.4")
<< QStringLiteral("7.5")
<< QStringLiteral("DELETE FROM parameters WHERE t_name LIKE 'SKGOPERATION_%'")
// ============
<< QLatin1String("")
<< QStringLiteral("7.5")
<< QStringLiteral("7.6")
<< "CREATE TABLE category2 ("
"id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,"
"t_name TEXT NOT NULL DEFAULT '' CHECK (t_name NOT LIKE '%" % OBJECTSEPARATOR % "%'),"
"t_fullname TEXT,"
"rd_category_id INTEGER NOT NULL DEFAULT 0,"
"t_bookmarked VARCHAR(1) NOT NULL DEFAULT 'N' CHECK (t_bookmarked IN ('Y', 'N'))"
")"
<< QStringLiteral("INSERT INTO category2 (id, t_name, t_fullname, rd_category_id, t_bookmarked) "
"SELECT id, t_name, t_fullname, (CASE WHEN rd_category_id IS NULL OR rd_category_id='' THEN 0 ELSE rd_category_id END), t_bookmarked FROM category")
<< QStringLiteral("DROP TABLE IF EXISTS category")
<< QStringLiteral("ALTER TABLE category2 RENAME TO category")
// ============
<< QLatin1String("")
<< QStringLiteral("7.6")
<< QStringLiteral("7.7")
<< QStringLiteral("ALTER TABLE operationbalance ADD COLUMN f_balance_entered FLOAT NOT NULL DEFAULT 0")
// ============ SKROOGE 1.3.2 ^^^
<< QLatin1String("")
<< QStringLiteral("7.7")
<< QStringLiteral("7.8")
<< QStringLiteral("CREATE TABLE account2("
"id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,"
"t_name TEXT NOT NULL,"
"t_number TEXT NOT NULL DEFAULT '',"
"t_agency_number TEXT NOT NULL DEFAULT '',"
"t_agency_address TEXT NOT NULL DEFAULT '',"
"t_comment TEXT NOT NULL DEFAULT '',"
"t_close VARCHAR(1) DEFAULT 'N' CHECK (t_close IN ('Y', 'N')),"
"t_type VARCHAR(1) NOT NULL DEFAULT 'C' CHECK (t_type IN ('C', 'D', 'A', 'I', 'L', 'W', 'S', 'O')),"
// C=current D=credit card A=assets (for objects) I=Investment W=Wallet L=Loan S=Saving O=other
"t_bookmarked VARCHAR(1) NOT NULL DEFAULT 'N' CHECK (t_bookmarked IN ('Y', 'N')),"
"rd_bank_id INTEGER NOT NULL)")
<< QStringLiteral("INSERT INTO account2 (id, t_name, t_number, t_agency_number, t_agency_address, t_comment, t_close, t_type, t_bookmarked, rd_bank_id) "
"SELECT id, t_name, t_number, t_agency_number, t_agency_address, t_comment, t_close, t_type, t_bookmarked, rd_bank_id FROM account")
<< QStringLiteral("DROP TABLE IF EXISTS account")
<< QStringLiteral("ALTER TABLE account2 RENAME TO account")
// ============
<< QLatin1String("")
<< QStringLiteral("7.8")
<< QStringLiteral("7.9")
<< QStringLiteral("DROP TABLE IF EXISTS vm_budget_tmp")
<< QStringLiteral("CREATE TABLE vm_budget_tmp( id INT, rc_category_id INT, f_budgeted REAL, i_year INT, i_month INT, f_budgeted_modified REAL, f_transferred REAL, t_including_subcategories TEXT, t_CATEGORY, t_PERIOD, f_CURRENTAMOUNT, t_RULES)")
<< QStringLiteral("DROP TABLE IF EXISTS vm_category_display_tmp")
<< QStringLiteral("CREATE TABLE vm_category_display_tmp( id INT, t_name TEXT, t_fullname TEXT, rd_category_id INT, i_NBOPERATIONS, f_REALCURRENTAMOUNT, t_bookmarked)")
// ============ SKROOGE 1.3.3 ^^^
<< QLatin1String("")
<< QStringLiteral("7.9")
<< QStringLiteral("8.0")
<< QStringLiteral("DROP TABLE IF EXISTS operationbalance")
<< QStringLiteral("CREATE TABLE operationbalance("
"r_operation_id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,"
"f_balance FLOAT NOT NULL DEFAULT 0,"
"f_balance_entered FLOAT NOT NULL DEFAULT 0)")
<< QLatin1String("")
<< QStringLiteral("8.0")
<< QStringLiteral("8.1")
<< QStringLiteral("DROP TABLE IF EXISTS operationbalance")
<< QStringLiteral("CREATE TABLE operationbalance("
"r_operation_id INTEGER NOT NULL,"
"f_balance FLOAT NOT NULL DEFAULT 0,"
"f_balance_entered FLOAT NOT NULL DEFAULT 0)")
// ============ SKROOGE 1.4.0 ^^^
<< QLatin1String("")
<< QStringLiteral("8.1")
<< QStringLiteral("8.2")
<< QStringLiteral("DROP TABLE IF EXISTS budgetcategory")
<< QStringLiteral("CREATE TABLE budgetsuboperation("
"id INTEGER NOT NULL DEFAULT 0,"
"id_suboperation INTEGER NOT NULL DEFAULT 0,"
"i_priority INTEGER NOT NULL DEFAULT 0)")
<< QLatin1String("")
<< QStringLiteral("8.2")
<< QStringLiteral("8.3")
<< QStringLiteral("DROP TABLE IF EXISTS vm_category_display_tmp")
<< QStringLiteral("DROP TRIGGER IF EXISTS fkdc_category_vm_category_display_tmp_id_rd_category_id")
// ============ SKROOGE 1.7.4 ^^^
<< QLatin1String("")
<< QStringLiteral("8.3")
<< QStringLiteral("8.4")
<< QStringLiteral("ALTER TABLE account ADD COLUMN f_maxamount FLOAT NOT NULL DEFAULT 10000.0")
<< QStringLiteral("ALTER TABLE account ADD COLUMN t_maxamount_enabled VARCHAR(1) DEFAULT 'N' CHECK (t_close IN ('Y', 'N'))")
<< QStringLiteral("ALTER TABLE account ADD COLUMN f_minamount FLOAT NOT NULL DEFAULT 0.0")
<< QStringLiteral("ALTER TABLE account ADD COLUMN t_minamount_enabled VARCHAR(1) DEFAULT 'N' CHECK (t_close IN ('Y', 'N'))")
<< QStringLiteral("UPDATE account SET f_maxamount=10000.0, t_maxamount_enabled='N', f_minamount=0.0, t_minamount_enabled='N'")
// ============ SKROOGE 1.7.7 ^^^
<< QLatin1String("")
<< QStringLiteral("8.4")
<< QStringLiteral("8.5")
<< QStringLiteral("ALTER TABLE account ADD COLUMN d_reconciliationdate DATE")
// ============
<< QLatin1String("")
<< QStringLiteral("8.5")
<< QStringLiteral("8.6")
<< QStringLiteral("CREATE TABLE account2("
"id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,"
"t_name TEXT NOT NULL,"
"t_number TEXT NOT NULL DEFAULT '',"
"t_agency_number TEXT NOT NULL DEFAULT '',"
"t_agency_address TEXT NOT NULL DEFAULT '',"
"t_comment TEXT NOT NULL DEFAULT '',"
"t_close VARCHAR(1) DEFAULT 'N' CHECK (t_close IN ('Y', 'N')),"
"t_type VARCHAR(1) NOT NULL DEFAULT 'C' CHECK (t_type IN ('C', 'D', 'A', 'I', 'L', 'W', 'S', 'P', 'O')),"
// C=current D=credit card A=assets (for objects) I=Investment W=Wallet L=Loan S=Saving P=Pension O=other
"t_bookmarked VARCHAR(1) NOT NULL DEFAULT 'N' CHECK (t_bookmarked IN ('Y', 'N')),"
"f_maxamount FLOAT NOT NULL DEFAULT 10000.0,"
"t_maxamount_enabled VARCHAR(1) DEFAULT 'N' CHECK (t_close IN ('Y', 'N')),"
"f_minamount FLOAT NOT NULL DEFAULT 0.0,"
"t_minamount_enabled VARCHAR(1) DEFAULT 'N' CHECK (t_close IN ('Y', 'N')),"
"d_reconciliationdate DATE,"
"rd_bank_id INTEGER NOT NULL)")
<< QStringLiteral("INSERT INTO account2 (id, t_name, t_number, t_agency_number, t_agency_address, t_comment, t_close, t_type, t_bookmarked, f_maxamount, t_maxamount_enabled, f_minamount, t_minamount_enabled, d_reconciliationdate, rd_bank_id) "
"SELECT id, t_name, t_number, t_agency_number, t_agency_address, t_comment, t_close, t_type, t_bookmarked, f_maxamount, t_maxamount_enabled, f_minamount, t_minamount_enabled, d_reconciliationdate, rd_bank_id FROM account")
<< QStringLiteral("DROP TABLE IF EXISTS account")
<< QStringLiteral("ALTER TABLE account2 RENAME TO account")
// ============ SKROOGE 1.8.0 ^^^
<< QLatin1String("")
<< QStringLiteral("8.6")
<< QStringLiteral("8.7")
<< QStringLiteral("ALTER TABLE suboperation ADD COLUMN d_date DATE NOT NULL DEFAULT '0000-00-00'")
<< QStringLiteral("UPDATE suboperation SET d_date=(SELECT d_date FROM operation WHERE suboperation.rd_operation_id=operation.id)")
<< QLatin1String("")
<< QStringLiteral("8.7")
<< QStringLiteral("8.8")
<< QStringLiteral("UPDATE rule SET t_action_definition=replace(t_action_definition, '\"d_date\"', '\"d_DATEOP\"') WHERE t_action_definition like '%\"d_date\"%'")
<< QStringLiteral("UPDATE rule SET t_definition=replace(t_definition, '\"d_date\"', '\"d_DATEOP\"') WHERE t_definition like '%\"d_date\"%'")
// ============ SKROOGE 1.9.0 ^^^
<< QLatin1String("")
<< QStringLiteral("8.8")
<< QStringLiteral("8.9")
<< QStringLiteral("ALTER TABLE suboperation ADD COLUMN i_order INTEGER NOT NULL DEFAULT 0")
<< QStringLiteral("UPDATE suboperation SET i_order=id")
<< QLatin1String("")
<< QStringLiteral("8.9")
<< QStringLiteral("9.0")
<< QStringLiteral("ALTER TABLE account ADD COLUMN r_account_id INTEGER NOT NULL DEFAULT 0")
<< QStringLiteral("UPDATE account SET r_account_id=0")
<< QLatin1String("")
<< QStringLiteral("9.0")
<< QStringLiteral("9.1")
<< QStringLiteral("CREATE TABLE rule2 ("
"id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,"
"t_description TEXT NOT NULL DEFAULT '',"
"t_definition TEXT NOT NULL DEFAULT '',"
"t_action_description TEXT NOT NULL DEFAULT '',"
"t_action_definition TEXT NOT NULL DEFAULT '',"
"t_action_type VARCHAR(1) DEFAULT 'S' CHECK (t_action_type IN ('S', 'U', 'A', 'T')),"
"t_bookmarked VARCHAR(1) NOT NULL DEFAULT 'N' CHECK (t_bookmarked IN ('Y', 'N')),"
"f_sortorder FLOAT"
")")
<< QStringLiteral("INSERT INTO rule2 (id, t_description, t_definition, t_action_description, t_action_definition, t_action_type, t_bookmarked,f_sortorder) SELECT id, t_description, t_definition, t_action_description, t_action_definition, t_action_type, t_bookmarked,f_sortorder FROM rule")
<< QStringLiteral("DROP TABLE IF EXISTS rule")
<< QStringLiteral("ALTER TABLE rule2 RENAME TO rule")
<< QLatin1String("")
<< QStringLiteral("9.1")
<< QStringLiteral("9.2")
<< QStringLiteral("UPDATE parameters SET t_value=replace(t_value, ' limitVisible=&amp;amp;quot;Y&amp;amp;quot; ', ' limitVisible=&amp;amp;quot;Y&amp;amp;quot; averageVisible=&amp;amp;quot;Y&amp;amp;quot; ')")
<< QStringLiteral("UPDATE parameters SET t_value=replace(t_value, ' limitVisible=&amp;amp;quot;N&amp;amp;quot; ', ' limitVisible=&amp;amp;quot;N&amp;amp;quot; averageVisible=&amp;amp;quot;N&amp;amp;quot; ')")
<< QLatin1String("")
<< QStringLiteral("9.2")
<< QStringLiteral("9.3")
<< QStringLiteral("CREATE TABLE operation2 ("
"id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,"
"i_group_id INTEGER NOT NULL DEFAULT 0,"
"i_number INTEGER DEFAULT 0 CHECK (i_number>=0),"
"d_date DATE NOT NULL DEFAULT '0000-00-00',"
"d_createdate DATE NOT NULL DEFAULT CURRENT_TIMESTAMP,"
"rd_account_id INTEGER NOT NULL,"
"t_mode TEXT NOT NULL DEFAULT '',"
"r_payee_id INTEGER NOT NULL DEFAULT 0,"
"t_comment TEXT NOT NULL DEFAULT '',"
"rc_unit_id INTEGER NOT NULL,"
"t_status VARCHAR(1) NOT NULL DEFAULT 'N' CHECK (t_status IN ('N', 'P', 'Y')),"
"t_bookmarked VARCHAR(1) NOT NULL DEFAULT 'N' CHECK (t_bookmarked IN ('Y', 'N')),"
"t_imported VARCHAR(1) NOT NULL DEFAULT 'N' CHECK (t_imported IN ('Y', 'N', 'P', 'T')),"
"t_template VARCHAR(1) NOT NULL DEFAULT 'N' CHECK (t_template IN ('Y', 'N')),"
"t_import_id TEXT NOT NULL DEFAULT '',"
"i_tmp INTEGER NOT NULL DEFAULT 0,"
"r_recurrentoperation_id INTEGER NOT NULL DEFAULT 0)")
<< QStringLiteral("INSERT INTO operation2 (id, i_group_id, i_number, d_date, d_createdate, rd_account_id, t_mode, r_payee_id, t_comment,"
"rc_unit_id, t_status, t_bookmarked, t_imported, t_template, t_import_id, i_tmp, r_recurrentoperation_id) "
"SELECT id, i_group_id, i_number, d_date, CURRENT_TIMESTAMP, rd_account_id, t_mode, r_payee_id, t_comment,"
"rc_unit_id, t_status, t_bookmarked, t_imported, t_template, t_import_id, i_tmp, r_recurrentoperation_id FROM operation")
<< QStringLiteral("DROP TABLE IF EXISTS operation")
<< QStringLiteral("ALTER TABLE operation2 RENAME TO operation")
<< QLatin1String("")
<< QStringLiteral("9.3")
<< QStringLiteral("9.4")
<< QStringLiteral("UPDATE rule SET t_definition=replace(t_definition,'#ATT#>=#V1# AND #ATT#&lt;=#V2#','((#ATT#>=#V1# AND #ATT#&lt;=#V2#) OR (#ATT#>=#V2# AND #ATT#&lt;=#V1#))')")
<< QLatin1String("")
<< QStringLiteral("9.4")
<< QStringLiteral("9.5")
<< QStringLiteral("ALTER TABLE account ADD COLUMN f_importbalance FLOAT")
<< QStringLiteral("UPDATE account SET f_importbalance=NULL")
// ============ SKROOGE 2.4.0 ^^^
<< QLatin1String("")
<< QStringLiteral("9.5")
<< QStringLiteral("9.6")
<< QStringLiteral("CREATE TABLE IF NOT EXISTS vm_budget_tmp( id INT, rc_category_id INT, f_budgeted REAL, i_year INT, i_month INT, f_budgeted_modified REAL, f_transferred REAL, t_including_subcategories TEXT, t_CATEGORY, t_PERIOD, f_CURRENTAMOUNT, t_RULES)")
<< QStringLiteral("ALTER TABLE budgetrule ADD COLUMN f_sortorder FLOAT")
<< QStringLiteral("UPDATE budgetrule SET f_sortorder=id WHERE f_sortorder IS NULL OR f_sortorder=''")
<< QLatin1String("")
<< QStringLiteral("9.6")
<< QStringLiteral("9.7")
<< QStringLiteral("ALTER TABLE budget ADD COLUMN t_modification_reasons TEXT NOT NULL DEFAULT ''")
<< QStringLiteral("UPDATE budget SET t_modification_reasons=''")
// ============ SKROOGE 2.8.1 ^^^
<< QLatin1String("")
<< QStringLiteral("9.7")
<< QStringLiteral("9.8")
<< QStringLiteral("UPDATE operation SET d_createdate=d_date WHERE d_createdate=''")
// ============ SKROOGE 2.9.0 ^^^
<< QLatin1String("")
<< QStringLiteral("9.8")
<< QStringLiteral("9.9")
<< QStringLiteral("ALTER TABLE payee ADD r_category_id INTEGER NOT NULL DEFAULT 0")
<< QStringLiteral("UPDATE payee SET r_category_id=0")
<< QLatin1String("")
<< QStringLiteral("9.9")
<< QStringLiteral("10.0")
<< QStringLiteral("ALTER TABLE payee ADD t_close VARCHAR(1) DEFAULT 'N' CHECK (t_close IN ('Y', 'N'))")
<< QStringLiteral("UPDATE payee SET t_close='N'")
<< QLatin1String("")
<< QStringLiteral("10.0")
<< QStringLiteral("10.1")
<< QStringLiteral("ALTER TABLE category ADD t_close VARCHAR(1) DEFAULT 'N' CHECK (t_close IN ('Y', 'N'))")
<< QStringLiteral("UPDATE category SET t_close='N'")
// ============ SKROOGE 2.11.0 ^^^
<< QLatin1String("")
<< QStringLiteral("10.1")
<< QStringLiteral("10.2")
<< QStringLiteral("CREATE TABLE operation2("
"id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,"
"i_group_id INTEGER NOT NULL DEFAULT 0,"
"t_number TEXT NOT NULL DEFAULT '',"
"d_date DATE NOT NULL DEFAULT '0000-00-00',"
"d_createdate DATE NOT NULL DEFAULT CURRENT_TIMESTAMP,"
"rd_account_id INTEGER NOT NULL,"
"t_mode TEXT NOT NULL DEFAULT '',"
"r_payee_id INTEGER NOT NULL DEFAULT 0,"
"t_comment TEXT NOT NULL DEFAULT '',"
"rc_unit_id INTEGER NOT NULL,"
"t_status VARCHAR(1) NOT NULL DEFAULT 'N' CHECK (t_status IN ('N', 'P', 'Y')),"
"t_bookmarked VARCHAR(1) NOT NULL DEFAULT 'N' CHECK (t_bookmarked IN ('Y', 'N')),"
"t_imported VARCHAR(1) NOT NULL DEFAULT 'N' CHECK (t_imported IN ('Y', 'N', 'P', 'T')),"
"t_template VARCHAR(1) NOT NULL DEFAULT 'N' CHECK (t_template IN ('Y', 'N')),"
"t_import_id TEXT NOT NULL DEFAULT '',"
"i_tmp INTEGER NOT NULL DEFAULT 0,"
"r_recurrentoperation_id INTEGER NOT NULL DEFAULT 0)")
<< QStringLiteral("INSERT INTO operation2 (id, i_group_id, t_number, d_date, d_createdate, rd_account_id, t_mode, r_payee_id, t_comment,"
"rc_unit_id, t_status, t_bookmarked, t_imported, t_template, t_import_id, i_tmp, r_recurrentoperation_id) "
"SELECT id, i_group_id, (CASE WHEN i_number=0 OR i_number IS NULL THEN '' ELSE i_number END), d_date, CURRENT_TIMESTAMP, rd_account_id, t_mode, r_payee_id, t_comment,"
"rc_unit_id, t_status, t_bookmarked, t_imported, t_template, t_import_id, i_tmp, r_recurrentoperation_id FROM operation")
<< QStringLiteral("DROP TABLE IF EXISTS operation")
<< QStringLiteral("ALTER TABLE operation2 RENAME TO operation")
<< QLatin1String("")
<< QStringLiteral("10.2")
<< QStringLiteral("10.3")
<< QStringLiteral("UPDATE rule SET t_definition=replace(t_definition, 'i_number', 't_number')")
<< QStringLiteral("UPDATE rule SET t_action_definition=replace(t_action_definition, 'i_number', 't_number')")
// ============ SKROOGE 2.11.0 ^^^
<< QLatin1String("")
<< QStringLiteral("10.3")
<< QStringLiteral("10.4")
<< QStringLiteral("ALTER TABLE account ADD COLUMN f_reconciliationbalance FLOAT")
<< QStringLiteral("UPDATE account SET f_reconciliationbalance=NULL")
// ============ SKROOGE 2.13.0 ^^^
<< QLatin1String("")
<< QStringLiteral("10.4")
<< QStringLiteral("10.5")
<< QStringLiteral("ALTER TABLE account ADD COLUMN d_importdate DATE");
return migrationSteps;
}
SKGError SKGDocumentBank::migrate(bool& oMigrationDone)
{
SKGError err;
SKGTRACEINFUNCRC(5, err)
oMigrationDone = false;
QStringList migrationSteps = getMigationSteps();
{
int nbSteps = migrationSteps.count();
SKGBEGINPROGRESSTRANSACTION(*this, "#INTERNAL#" % i18nc("Progression step", "Migrate document"), err, 5)
IFOK(err) {
QString version = getParameter(QStringLiteral("SKG_DB_BANK_VERSION"));
QString initialversion = version;
QString lastversion = QStringLiteral("10.6");
if (version.isEmpty()) {
SKGTRACEL(10) << "Initial creation" << endl;
/**
* This constant is used to initialized the data model.
* Rules for attribute name:
* t_xxx for TEXT and VARCHAR
* d_xxx for DATE
* f_xxx for FLOAT
* i_xxx for INTEGER
* r_xxx for a link without constraint
* rc_pointed_table_pointed_attribute_xxx for link on other an object in named "pointed_table" with "pointed_attribute"=id of pointing object
* a constraint will be created without DELETE CASCADE
* rd_pointed_table_pointed_attribute_xxx for link on other an object in named "pointed_table" with "pointed_attribute"=id of pointing object
* a constraint will be created with DELETE CASCADE
* xxx must be in lower case for R/W attributes and in upper case for R/O attributes
* Rules for table name:
* v_yyy for views
*/
QStringList BankInitialDataModel;
BankInitialDataModel
// ==================================================================
// Table unit
<< QStringLiteral("CREATE TABLE unit("
"id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,"
"t_name TEXT NOT NULL,"
"t_symbol TEXT NOT NULL DEFAULT '',"
"t_country TEXT NOT NULL DEFAULT '',"
"t_type VARCHAR(1) NOT NULL DEFAULT 'C' CHECK (t_type IN ('1', '2', 'C', 'S', 'I', 'O')),"
// 1=main currency, 2=secondary currency, C=currencies S=share, I=index, O=object
"t_internet_code TEXT NOT NULL DEFAULT '',"
"i_nbdecimal INT NOT NULL DEFAULT 2,"
"rd_unit_id INTEGER NOT NULL DEFAULT 0,"
"t_source TEXT NOT NULL DEFAULT '',"
"t_bookmarked VARCHAR(1) NOT NULL DEFAULT 'N' CHECK (t_bookmarked IN ('Y', 'N'))"
")")
// ==================================================================
// Table unitvalue
<< QStringLiteral("CREATE TABLE unitvalue("
"id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,"
"rd_unit_id INTEGER NOT NULL,"
"d_date DATE NOT NULL,"
"f_quantity FLOAT NOT NULL CHECK (f_quantity>=0))")
// ==================================================================
// Table bank
<< QStringLiteral("CREATE TABLE bank ("
"id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,"
"t_name TEXT NOT NULL DEFAULT '',"
"t_bank_number TEXT NOT NULL DEFAULT '',"
"t_icon TEXT NOT NULL DEFAULT '')")
// ==================================================================
// Table account
<< QStringLiteral("CREATE TABLE account("
"id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,"
"t_name TEXT NOT NULL,"
"t_number TEXT NOT NULL DEFAULT '',"
"t_agency_number TEXT NOT NULL DEFAULT '',"
"t_agency_address TEXT NOT NULL DEFAULT '',"
"t_comment TEXT NOT NULL DEFAULT '',"
"t_close VARCHAR(1) DEFAULT 'N' CHECK (t_close IN ('Y', 'N')),"
"t_type VARCHAR(1) NOT NULL DEFAULT 'C' CHECK (t_type IN ('C', 'D', 'A', 'I', 'L', 'W', 'S', 'P', 'O')),"
// C=current D=credit card A=assets (for objects) I=Investment W=Wallet L=Loan S=Saving P=Pension O=other
"t_bookmarked VARCHAR(1) NOT NULL DEFAULT 'N' CHECK (t_bookmarked IN ('Y', 'N')),"
"f_maxamount FLOAT NOT NULL DEFAULT 10000.0,"
"t_maxamount_enabled VARCHAR(1) DEFAULT 'N' CHECK (t_close IN ('Y', 'N')),"
"f_minamount FLOAT NOT NULL DEFAULT 0.0,"
"t_minamount_enabled VARCHAR(1) DEFAULT 'N' CHECK (t_close IN ('Y', 'N')),"
"d_importdate DATE,"
"f_importbalance FLOAT,"
"d_reconciliationdate DATE,"
"f_reconciliationbalance FLOAT,"
"r_account_id INTEGER NOT NULL DEFAULT 0,"
"rd_bank_id INTEGER NOT NULL)")
// ==================================================================
// Table interest
<< QStringLiteral("CREATE TABLE interest("
"id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,"
"rd_account_id INTEGER NOT NULL,"
"d_date DATE NOT NULL,"
"f_rate FLOAT NOT NULL CHECK (f_rate>=0),"
"t_income_value_date_mode VARCHAR(1) NOT NULL DEFAULT 'F' CHECK (t_income_value_date_mode IN ('F', '0', '1', '2', '3', '4', '5')),"
"t_expenditure_value_date_mode VARCHAR(1) NOT NULL DEFAULT 'F' CHECK (t_expenditure_value_date_mode IN ('F', '0', '1', '2', '3', '4', '5')),"
"t_base VARCHAR(3) NOT NULL DEFAULT '24' CHECK (t_base IN ('24', '360', '365'))"
")")
// ==================================================================
// Table category
<< "CREATE TABLE category ("
"id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,"
"t_name TEXT NOT NULL DEFAULT '' CHECK (t_name NOT LIKE '%" % OBJECTSEPARATOR % "%'),"
"t_fullname TEXT,"
"t_close VARCHAR(1) DEFAULT 'N' CHECK (t_close IN ('Y', 'N')),"
"rd_category_id INTEGER NOT NULL DEFAULT 0,"
"t_bookmarked VARCHAR(1) NOT NULL DEFAULT 'N' CHECK (t_bookmarked IN ('Y', 'N'))"
")"
// ==================================================================
// Table operation
<< QStringLiteral("CREATE TABLE operation("
"id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,"
"i_group_id INTEGER NOT NULL DEFAULT 0,"
"t_number TEXT NOT NULL DEFAULT '',"
"d_date DATE NOT NULL DEFAULT '0000-00-00',"
"d_createdate DATE NOT NULL DEFAULT CURRENT_TIMESTAMP,"
"rd_account_id INTEGER NOT NULL,"
"t_mode TEXT NOT NULL DEFAULT '',"
"r_payee_id INTEGER NOT NULL DEFAULT 0,"
"t_comment TEXT NOT NULL DEFAULT '',"
"rc_unit_id INTEGER NOT NULL,"
"t_status VARCHAR(1) NOT NULL DEFAULT 'N' CHECK (t_status IN ('N', 'P', 'Y')),"
"t_bookmarked VARCHAR(1) NOT NULL DEFAULT 'N' CHECK (t_bookmarked IN ('Y', 'N')),"
"t_imported VARCHAR(1) NOT NULL DEFAULT 'N' CHECK (t_imported IN ('Y', 'N', 'P', 'T')),"
"t_template VARCHAR(1) NOT NULL DEFAULT 'N' CHECK (t_template IN ('Y', 'N')),"
"t_import_id TEXT NOT NULL DEFAULT '',"
"i_tmp INTEGER NOT NULL DEFAULT 0,"
"r_recurrentoperation_id INTEGER NOT NULL DEFAULT 0)")
<< QStringLiteral("CREATE TABLE operationbalance("
"r_operation_id INTEGER NOT NULL,"
"f_balance FLOAT NOT NULL DEFAULT 0,"
"f_balance_entered FLOAT NOT NULL DEFAULT 0)")
// ==================================================================
// Table refund
<< QStringLiteral("CREATE TABLE refund ("
"id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,"
"t_name TEXT NOT NULL DEFAULT '',"
"t_comment TEXT NOT NULL DEFAULT '',"
"t_close VARCHAR(1) DEFAULT 'N' CHECK (t_close IN ('Y', 'N')))")
// ==================================================================
// Table payee
<< QStringLiteral("CREATE TABLE payee ("
"id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,"
"t_name TEXT NOT NULL DEFAULT '',"
"t_address TEXT NOT NULL DEFAULT '',"
"t_bookmarked VARCHAR(1) NOT NULL DEFAULT 'N' CHECK (t_bookmarked IN ('Y', 'N')),"
"t_close VARCHAR(1) DEFAULT 'N' CHECK (t_close IN ('Y', 'N')),"
"r_category_id INTEGER NOT NULL DEFAULT 0"
")")
// ==================================================================
// Table suboperation
<< QStringLiteral("CREATE TABLE suboperation("
"id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,"
"d_date DATE NOT NULL DEFAULT '0000-00-00',"
"t_comment TEXT NOT NULL DEFAULT '',"
"rd_operation_id INTEGER NOT NULL,"
"r_category_id INTEGER NOT NULL DEFAULT 0,"
"f_value FLOAT NOT NULL DEFAULT 0.0,"
"t_formula TEXT NOT NULL DEFAULT '',"
"i_tmp INTEGER NOT NULL DEFAULT 0,"
"r_refund_id INTEGER NOT NULL DEFAULT 0,"
"i_order INTEGER NOT NULL DEFAULT 0"
")")
// ==================================================================
// Table recurrentoperation
<< QStringLiteral("CREATE TABLE recurrentoperation ("
"id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,"
"d_date DATE NOT NULL DEFAULT '0000-00-00',"
"rd_operation_id INTEGER NOT NULL,"
"i_period_increment INTEGER NOT NULL DEFAULT 1 CHECK (i_period_increment>=0),"
"t_period_unit TEXT NOT NULL DEFAULT 'M' CHECK (t_period_unit IN ('D', 'W', 'M', 'Y')),"
"t_auto_write VARCHAR(1) DEFAULT 'Y' CHECK (t_auto_write IN ('Y', 'N')),"
"i_auto_write_days INTEGER NOT NULL DEFAULT 5 CHECK (i_auto_write_days>=0),"
"t_warn VARCHAR(1) DEFAULT 'Y' CHECK (t_warn IN ('Y', 'N')),"
"i_warn_days INTEGER NOT NULL DEFAULT 5 CHECK (i_warn_days>=0),"
"t_times VARCHAR(1) DEFAULT 'N' CHECK (t_times IN ('Y', 'N')),"
"i_nb_times INTEGER NOT NULL DEFAULT 1 CHECK (i_nb_times>=0)"
")")
// ==================================================================
// Table rule
<< QStringLiteral("CREATE TABLE rule ("
"id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,"
"t_description TEXT NOT NULL DEFAULT '',"
"t_definition TEXT NOT NULL DEFAULT '',"
"t_action_description TEXT NOT NULL DEFAULT '',"
"t_action_definition TEXT NOT NULL DEFAULT '',"
"t_action_type VARCHAR(1) DEFAULT 'S' CHECK (t_action_type IN ('S', 'U', 'A', 'T')),"
"t_bookmarked VARCHAR(1) NOT NULL DEFAULT 'N' CHECK (t_bookmarked IN ('Y', 'N')),"
"f_sortorder FLOAT"
")")
// ==================================================================
// Table budget
<< QStringLiteral("CREATE TABLE budget ("
"id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,"
"rc_category_id INTEGER NOT NULL DEFAULT 0,"
"t_including_subcategories TEXT NOT NULL DEFAULT 'N' CHECK (t_including_subcategories IN ('Y', 'N')),"
"f_budgeted FLOAT NOT NULL DEFAULT 0.0,"
"f_budgeted_modified FLOAT NOT NULL DEFAULT 0.0,"
"t_modification_reasons TEXT NOT NULL DEFAULT '',"
"f_transferred FLOAT NOT NULL DEFAULT 0.0,"
"i_year INTEGER NOT NULL DEFAULT 2010,"
"i_month INTEGER NOT NULL DEFAULT 0 CHECK (i_month>=0 AND i_month<=12)"
")")
<< QStringLiteral("CREATE TABLE budgetsuboperation("
"id INTEGER NOT NULL DEFAULT 0,"
"id_suboperation INTEGER NOT NULL DEFAULT 0,"
"i_priority INTEGER NOT NULL DEFAULT 0)")
<< QStringLiteral("CREATE TABLE budgetrule ("
"id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,"
"rc_category_id INTEGER NOT NULL DEFAULT 0,"
"t_category_condition TEXT NOT NULL DEFAULT 'Y' CHECK (t_category_condition IN ('Y', 'N')),"
"t_year_condition TEXT NOT NULL DEFAULT 'Y' CHECK (t_year_condition IN ('Y', 'N')),"
"i_year INTEGER NOT NULL DEFAULT 2010,"
"i_month INTEGER NOT NULL DEFAULT 0 CHECK (i_month>=0 AND i_month<=12),"
"t_month_condition TEXT NOT NULL DEFAULT 'Y' CHECK (t_month_condition IN ('Y', 'N')),"
"i_condition INTEGER NOT NULL DEFAULT 0 CHECK (i_condition IN (-1,0,1)),"
"f_quantity FLOAT NOT NULL DEFAULT 0.0,"
"t_absolute TEXT NOT NULL DEFAULT 'Y' CHECK (t_absolute IN ('Y', 'N')),"
"rc_category_id_target INTEGER NOT NULL DEFAULT 0,"
"t_category_target TEXT NOT NULL DEFAULT 'Y' CHECK (t_category_target IN ('Y', 'N')),"
"t_rule TEXT NOT NULL DEFAULT 'N' CHECK (t_rule IN ('N', 'C', 'Y')),"
"f_sortorder FLOAT"
")")
<< QStringLiteral("CREATE TABLE vm_budget_tmp("
"id INT,"
"rc_category_id INT,"
"f_budgeted REAL,"
"i_year INT,"
"i_month INT,"
"f_budgeted_modified REAL,"
"t_modification_reasons TEXT,"
"f_transferred REAL,"
"t_including_subcategories TEXT,"
"t_CATEGORY TEXT,"
"t_PERIOD TEXT,"
"f_CURRENTAMOUNT REAL,"
"t_RULES TEXT)");
IFOKDO(err, this->executeSqliteOrders(BankInitialDataModel))
// Set new version
version = lastversion;
IFOKDO(err, SKGDocument::setParameter(QStringLiteral("SKG_DB_BANK_VERSION"), version))
}
if (!err && SKGServices::stringToDouble(version) > SKGServices::stringToDouble(lastversion)) {
err = SKGError(ERR_ABORT, i18nc("Error message", "Impossible to load a document generated by a more recent version"));
}
IFOK(err) {
QString v1;
QString v2;
bool computeCaches = false;
for (int i = 0; !err && i < nbSteps; ++i) {
if (migrationSteps.at(i).isEmpty()) {
++i;
v1 = migrationSteps.at(i);
++i;
v2 = migrationSteps.at(i);
if (version == v1) {
SKGTRACEL(10) << "Migration from " << v1 << " to " << v2 << endl;
for (int j = i + 1; !err && j < nbSteps; ++j) {
const QString& sql = migrationSteps.at(j);
if (!sql.isEmpty()) {
++i;
IFOKDO(err, this->executeSqliteOrder(sql))
} else {
break;
}
}
if (v1 == QStringLiteral("4.7") ||
v1 == QStringLiteral("5.1") ||
v1 == QStringLiteral("5.7") ||
v1 == QStringLiteral("5.9") ||
v1 == QStringLiteral("8.0") ||
v1 == QStringLiteral("8.1") ||
v1 == QStringLiteral("10.0")) {
computeCaches = true;
}
// Set new version
version = v2;
IFOKDO(err, SKGDocument::setParameter(QStringLiteral("SKG_DB_BANK_VERSION"), version))
oMigrationDone = true;
}
}
}
IFOKDO(err, stepForward(1, i18nc("Progression step", "Refresh views")))
if (!err && computeCaches) {
err = refreshViewsIndexesAndTriggers();
IFOKDO(err, stepForward(2, i18nc("Progression step", "Computation of balances")))
IFOKDO(err, computeBalances())
IFOKDO(err, stepForward(3, i18nc("Progression step", "Computation of budgets")))
IFOKDO(err, computeBudgetSuboperationLinks())
IFOKDO(err, stepForward(4))
}
IFOK(err) {
bool mig = false;
err = SKGDocument::migrate(mig);
oMigrationDone = oMigrationDone || mig;
} else {
err.addError(ERR_FAIL, i18nc("Error message: Could not perform database migration", "Database migration from version %1 to version %2 failed", initialversion, version));
}
IFOKDO(err, stepForward(5))
}
}
}
return err;
}
SKGError SKGDocumentBank::dump(int iMode) const
{
SKGError err;
if (Q_LIKELY(getMainDatabase())) {
// dump parameters
SKGTRACE << "=== START DUMP BANK DOCUMENT ===" << endl;
err = SKGDocument::dump(iMode);
if ((iMode & DUMPUNIT) != 0) {
SKGTRACE << "=== DUMPUNIT (UNITS))===" << endl;
err.addError(dumpSelectSqliteOrder(QStringLiteral("SELECT * FROM v_unit_display ORDER BY id")));
SKGTRACE << "=== DUMPUNIT (VALUES) ===" << endl;
err.addError(dumpSelectSqliteOrder(QStringLiteral("SELECT * FROM v_unitvalue_display ORDER BY rd_unit_id, d_date")));
}
if ((iMode & DUMPACCOUNT) != 0) {
SKGTRACE << "=== DUMPACCOUNT (BANKS) ===" << endl;
err.addError(dumpSelectSqliteOrder(QStringLiteral("SELECT * FROM v_bank ORDER BY id")));
SKGTRACE << "=== DUMPACCOUNT (ACCOUNTS) ===" << endl;
err.addError(dumpSelectSqliteOrder(QStringLiteral("SELECT * FROM v_account_display ORDER BY rd_bank_id, id")));
}
if ((iMode & DUMPOPERATION) != 0) {
SKGTRACE << "=== DUMPOPERATION (OPERATIONS) ===" << endl;
err.addError(dumpSelectSqliteOrder(QStringLiteral("SELECT * FROM v_operation_display_all ORDER BY id")));
SKGTRACE << "=== DUMPOPERATION (SUBOPERATIONS) ===" << endl;
err.addError(dumpSelectSqliteOrder(QStringLiteral("SELECT * FROM v_suboperation_display ORDER BY rd_operation_id, id")));
SKGTRACE << "=== DUMPOPERATION (RECURRENT) ===" << endl;
err.addError(dumpSelectSqliteOrder(QStringLiteral("SELECT * FROM v_recurrentoperation ORDER BY rd_operation_id, id")));
SKGTRACE << "=== DUMPOPERATION (TRACKER) ===" << endl;
err.addError(dumpSelectSqliteOrder(QStringLiteral("SELECT * FROM v_refund ORDER BY id")));
}
if ((iMode & DUMPPAYEE) != 0) {
SKGTRACE << "=== DUMPOPERATION (PAYEE) ===" << endl;
err.addError(dumpSelectSqliteOrder(QStringLiteral("SELECT * FROM v_payee ORDER BY id")));
}
if ((iMode & DUMPCATEGORY) != 0) {
SKGTRACE << "=== DUMPCATEGORY ===" << endl;
err.addError(dumpSelectSqliteOrder(QStringLiteral("SELECT * FROM v_category_display ORDER BY rd_category_id, id")));
}
if ((iMode & DUMPBUDGET) != 0) {
SKGTRACE << "=== DUMPBUDGET (BUDGET) ===" << endl;
err.addError(dumpSelectSqliteOrder(QStringLiteral("SELECT * FROM v_budget_display ORDER BY t_PERIOD")));
SKGTRACE << "=== DUMPBUDGET (RULES) ===" << endl;
err.addError(dumpSelectSqliteOrder(QStringLiteral("SELECT * FROM v_budgetrule_display ORDER BY t_absolute DESC, id")));
}
SKGTRACE << "=== END DUMP BANK DOCUMENT ===" << endl;
}
return err;
}
SKGError SKGDocumentBank::addOrModifyUnitValue(const QString& iUnitName, QDate iDate, double iValue, SKGUnitValueObject* oValue) const
{
SKGError err;
SKGTRACEINFUNCRC(10, err)
// Creation or update of the unit
bool insertOrUpdate = true;
SKGUnitObject unit(const_cast<SKGDocumentBank*>(this));
err = unit.setName(iUnitName);
IFOKDO(err, unit.setSymbol(iUnitName))
if (!unit.exist()) {
insertOrUpdate = false;
IFOKDO(err, unit.save(insertOrUpdate))
} else {
err = unit.load();
}
// Creation or update of the value
SKGUnitValueObject value;
IFOKDO(err, unit.addUnitValue(value))
IFOKDO(err, value.setDate(iDate))
IFOKDO(err, value.setQuantity(iValue))
IFOKDO(err, value.save(insertOrUpdate))
if (oValue != nullptr) {
*oValue = value;
}
// Add error if needed
IFKO(err) err.addError(ERR_FAIL, i18nc("Error message", "Operation '%1' on '%2' failed", QStringLiteral("SKGDocumentBank::addOrModifyUnitValue"),
iUnitName % " / " % SKGServices::dateToSqlString(QDateTime(iDate)) % " / " % SKGServices::doubleToString(iValue)));
return err;
}
SKGServices::SKGUnitInfo SKGDocumentBank::getPrimaryUnit() const
{
SKGServices::SKGUnitInfo output;
output.Name = getCachedValue(QStringLiteral("primaryUnitCache"));
if (output.Name.isEmpty()) {
this->refreshCache(QStringLiteral("unit"));
output.Name = getCachedValue(QStringLiteral("primaryUnitCache"));
}
output.Value = 1;
output.Symbol = getCachedValue(QStringLiteral("primaryUnitSymbolCache"));
output.NbDecimal = SKGServices::stringToInt(getCachedValue(QStringLiteral("primaryUnitDecimalCache")));
return output;
}
SKGServices::SKGUnitInfo SKGDocumentBank::getSecondaryUnit() const
{
SKGServices::SKGUnitInfo output;
output.Name = getCachedValue(QStringLiteral("secondaryUnitCache"));
if (output.Name.isEmpty()) {
this->refreshCache(QStringLiteral("unit"));
output.Name = getCachedValue(QStringLiteral("secondaryUnitCache"));
}
output.Symbol = getCachedValue(QStringLiteral("secondaryUnitSymbolCache"));
output.Value = SKGServices::stringToDouble(getCachedValue(QStringLiteral("secondaryUnitValueCache")));
output.NbDecimal = SKGServices::stringToInt(getCachedValue(QStringLiteral("secondaryUnitDecimalCache")));
return output;
}
QString SKGDocumentBank::formatPrimaryMoney(double iValue) const
{
return formatMoney(iValue, getPrimaryUnit(), false);
}
QString SKGDocumentBank::formatSecondaryMoney(double iValue) const
{
return formatMoney(iValue, getSecondaryUnit(), false);
}
QString SKGDocumentBank::getCategoryForPayee(const QString& iPayee, bool iComputeAllPayees) const
{
SKGTRACEINFUNC(10)
QString output;
QString key = "categoryForPayee-" + iPayee;
output = getCachedValue(key);
if (output.isEmpty()) {
QString sql = "SELECT * FROM (SELECT 9999, t_name, t_CATEGORY FROM v_payee WHERE t_CATEGORY!='' UNION "
"SELECT COUNT(1), t_name, t_CATEGORY from (SELECT payee.t_name, t_CATEGORY FROM payee, v_suboperation_display sop, v_operation op WHERE r_payee_id=payee.id AND sop.rd_operation_id=op.ID) GROUP BY t_name, t_CATEGORY) ORDER BY 2, 1 DESC";
if (!iComputeAllPayees) {
sql = "SELECT 9999, t_name, t_CATEGORY FROM v_payee WHERE t_name='" % SKGServices::stringToSqlString(iPayee) % "' AND t_CATEGORY!='' "
"UNION ALL SELECT COUNT(1),t_PAYEE, t_REALCATEGORY FROM (SELECT t_PAYEE, t_REALCATEGORY, d_date FROM v_suboperation_consolidated "
"WHERE t_PAYEE='" % SKGServices::stringToSqlString(iPayee) % "' ORDER BY d_date DESC LIMIT 50) GROUP BY t_REALCATEGORY ORDER BY COUNT(1) DESC";
}
SKGStringListList result;
executeSelectSqliteOrder(sql, result);
int nb = result.count();
if (nb >= 1) {
QString currentComputeKey;
QString currentCat;
int currentCount = 0;
int sum = 0;
for (int i = 1 ; i < nb; ++i) {
int count = SKGServices::stringToInt(result.at(i).at(0));
QString newComputeKey = "categoryForPayee-" + result.at(i).at(1);
if (newComputeKey != currentComputeKey) {
// The computed key change
if (!currentComputeKey.isEmpty()) {
// Store the automatic category of the key
if (sum > 0 && 100 * currentCount / sum > 70) {
addValueInCache(currentComputeKey, currentCat);
if (currentComputeKey == key) {
output = currentCat;
}
}
}
// Start to compute the new sum and keep this category
currentCount = count;
currentCat = result.at(i).at(2);
currentComputeKey = newComputeKey;
sum = count;
} else {
// Continue to compute the sum
sum += count;
}
}
// Compute the last
if (!currentComputeKey.isEmpty()) {
// Store the automatic category of the key
if (sum > 0 && 100 * currentCount / sum > 70) {
addValueInCache(currentComputeKey, currentCat);
if (currentComputeKey == key) {
output = currentCat;
}
}
}
}
}
return output;
}
void SKGDocumentBank::refreshCache(const QString& iTable) const
{
if (iTable == QStringLiteral("unit") || iTable.isEmpty()) {
SKGTRACEINFUNC(10)
SKGStringListList result;
executeSelectSqliteOrder(QStringLiteral("SELECT t_name, t_symbol, i_nbdecimal FROM unit WHERE t_type='1'"), result);
if (result.size() == 2) {
addValueInCache(QStringLiteral("primaryUnitCache"), result.at(1).at(0));
addValueInCache(QStringLiteral("primaryUnitSymbolCache"), result.at(1).at(1));
addValueInCache(QStringLiteral("primaryUnitDecimalCache"), result.at(1).at(2));
} else {
addValueInCache(QStringLiteral("primaryUnitCache"), QLatin1String(""));
addValueInCache(QStringLiteral("primaryUnitSymbolCache"), QLatin1String(""));
addValueInCache(QStringLiteral("primaryUnitDecimalCache"), QStringLiteral("2"));
}
executeSelectSqliteOrder(QStringLiteral("SELECT t_name, t_symbol, f_CURRENTAMOUNT, i_nbdecimal FROM v_unit WHERE t_type='2'"), result);
if (result.size() == 2) {
addValueInCache(QStringLiteral("secondaryUnitCache"), result.at(1).at(0));
addValueInCache(QStringLiteral("secondaryUnitSymbolCache"), result.at(1).at(1));
addValueInCache(QStringLiteral("secondaryUnitValueCache"), result.at(1).at(2));
addValueInCache(QStringLiteral("secondaryUnitDecimalCache"), result.at(1).at(3));
} else {
addValueInCache(QStringLiteral("secondaryUnitCache"), QLatin1String(""));
addValueInCache(QStringLiteral("secondaryUnitSymbolCache"), QLatin1String(""));
addValueInCache(QStringLiteral("secondaryUnitValueCache"), QStringLiteral("1"));
addValueInCache(QStringLiteral("secondaryUnitDecimalCache"), QStringLiteral("2"));
}
}
SKGDocument::refreshCache(iTable);
}
SKGError SKGDocumentBank::addOrModifyAccount(const QString& iName, const QString& iNumber, const QString& iBankName) const
{
SKGError err;
SKGTRACEINFUNCRC(10, err)
// Creation or update of the bank
SKGBankObject bank(const_cast<SKGDocumentBank*>(this));
err = bank.setName(iBankName);
IFOKDO(err, bank.save())
// Creation or update of the account
SKGAccountObject account;
IFOKDO(err, bank.addAccount(account))
IFOKDO(err, account.setAttribute(QStringLiteral("rd_bank_id"), SKGServices::intToString(bank.getID())))
IFOKDO(err, account.setName(iName))
IFOKDO(err, account.setAttribute(QStringLiteral("t_number"), iNumber))
IFOKDO(err, account.save())
IFKO(err) err.addError(ERR_FAIL, i18nc("Error message", "Operation '%1' on '%2' failed", QStringLiteral("SKGDocumentBank::addOrModifyAccount"), iName));
return err;
}
QString SKGDocumentBank::getFileExtension() const
{
return QStringLiteral("skg");
}
QString SKGDocumentBank::getDocumentHeader() const
{
return QStringLiteral("SKROOGE");
}
SKGDocument::SKGModelTemplateList SKGDocumentBank::getDisplaySchemas(const QString& iRealTable) const
{
SKGModelTemplateList listSchema;
listSchema.reserve(10);
// Get properties
QStringList properties;
QString tableForProperties = iRealTable;
if (tableForProperties == QStringLiteral("suboperation")) {
tableForProperties = QStringLiteral("operation");
}
this->getDistinctValues(QStringLiteral("parameters"), QStringLiteral("t_name"), "(t_uuid_parent like '%-" % tableForProperties % "' OR t_uuid_parent like '%-sub" % tableForProperties % "') AND t_name NOT LIKE 'SKG_%'", properties);
// Build property schema
QString propSchema;
int nb = properties.count();
for (int i = 0; i < nb; ++i) {
propSchema += ";p_" % properties.at(i) % "|N";
}
// Build schemas
if (iRealTable == QStringLiteral("operation") || iRealTable == QStringLiteral("suboperation")) {
SKGModelTemplate def;
def.id = QStringLiteral("default");
def.name = i18nc("Noun, the default value of an item", "Default");
def.icon = QStringLiteral("edit-undo");
def.schema = "d_date;d_DATEWEEK|N;d_DATEMONTH|N;d_DATEQUARTER|N;d_DATESEMESTER|N;d_DATEYEAR|N;i_NBRECURRENT;t_bookmarked;t_ACCOUNT;t_TOACCOUNT|N;t_number;t_mode;t_PAYEE;t_comment;t_REALCOMMENT;t_CATEGORY;t_REALCATEGORY;t_status;"
"f_REALCURRENTAMOUNT;f_REALCURRENTAMOUNT_EXPENSE|N;f_REALCURRENTAMOUNT_INCOME|N;"
"f_CURRENTAMOUNT;f_CURRENTAMOUNT_EXPENSE|N;f_CURRENTAMOUNT_INCOME|N;"
"f_QUANTITY|N;f_QUANTITY_EXPENSE|N;f_QUANTITY_INCOME|N;f_REALQUANTITY|N;f_REALQUANTITY_EXPENSE|N;f_REALQUANTITY_INCOME|N;t_UNIT|N;"
"t_imported|N;t_REALREFUND|N;t_REFUND|N;t_REFUNDDISPLAY|N"
";f_BALANCE|N;f_BALANCE_ENTERED|N;d_createdate|N;i_OPID|N" % propSchema;
listSchema.push_back(def);
SKGModelTemplate minimum;
minimum.id = QStringLiteral("minimum");
minimum.name = i18nc("Noun, the minimum value of an item", "Minimum");
minimum.icon = QLatin1String("");
minimum.schema = "d_date;d_DATEWEEK|N;d_DATEMONTH|N;d_DATEQUARTER|N;d_DATESEMESTER|N;d_DATEYEAR|N;i_NBRECURRENT|N;t_bookmarked|N;t_ACCOUNT;t_TOACCOUNT|N;t_number|N;t_mode|N;t_PAYEE|N;t_comment|N;t_REALCOMMENT|N;t_CATEGORY|N;t_REALCATEGORY|N;t_status;"
"f_REALCURRENTAMOUNT;f_REALCURRENTAMOUNT_EXPENSE|N;f_REALCURRENTAMOUNT_INCOME|N;"
"f_CURRENTAMOUNT;f_CURRENTAMOUNT_EXPENSE|N;f_CURRENTAMOUNT_INCOME|N;"
"f_QUANTITY|N;f_QUANTITY_EXPENSE|N;f_QUANTITY_INCOME|N;f_REALQUANTITY|N;f_REALQUANTITY_EXPENSE|N;f_REALQUANTITY_INCOME|N;t_UNIT|N;"
"t_imported|N;t_REALREFUND|N;t_REFUND|N;t_REFUNDDISPLAY|N"
";f_BALANCE|N;f_BALANCE_ENTERED|N;d_createdate|N;i_OPID|N" % propSchema;
listSchema.push_back(minimum);
SKGModelTemplate doubleColumn;
doubleColumn.id = QStringLiteral("doublecolumn");
doubleColumn.name = i18nc("Noun", "Amount in 2 columns");
doubleColumn.icon = QLatin1String("");
doubleColumn.schema = "d_date;d_DATEWEEK|N;d_DATEMONTH|N;d_DATEQUARTER|N;d_DATESEMESTER|N;d_DATEYEAR|N;i_NBRECURRENT;t_bookmarked;t_ACCOUNT;t_TOACCOUNT|N;t_number;t_mode;t_PAYEE;t_comment;t_REALCOMMENT;t_CATEGORY;t_REALCATEGORY;t_status;"
"f_REALCURRENTAMOUNT|N;f_REALCURRENTAMOUNT_EXPENSE|Y;f_REALCURRENTAMOUNT_INCOME|Y;"
"f_CURRENTAMOUNT|N;f_CURRENTAMOUNT_EXPENSE|Y;f_CURRENTAMOUNT_INCOME|Y;"
"f_QUANTITY|N;f_QUANTITY_EXPENSE|N;f_QUANTITY_INCOME|N;f_REALQUANTITY|N;f_REALQUANTITY_EXPENSE|N;f_REALQUANTITY_INCOME|N;t_UNIT|N;"
"t_imported|N;t_REALREFUND|N;t_REFUND|N;t_REFUNDDISPLAY|N"
";f_BALANCE|N;f_BALANCE_ENTERED|N;d_createdate|N;i_OPID|N" % propSchema;
listSchema.push_back(doubleColumn);
SKGModelTemplate amountEntered;
amountEntered.id = QStringLiteral("amountentered");
amountEntered.name = i18nc("Noun", "Amount entered");
amountEntered.icon = QLatin1String("");
amountEntered.schema = "d_date;d_DATEWEEK|N;d_DATEMONTH|N;d_DATEQUARTER|N;d_DATESEMESTER|N;d_DATEYEAR|N;i_NBRECURRENT;t_bookmarked;t_ACCOUNT;t_TOACCOUNT|N;t_number;t_mode;t_PAYEE;t_comment;t_REALCOMMENT;t_CATEGORY;t_REALCATEGORY;t_status;"
"f_REALCURRENTAMOUNT|N;f_REALCURRENTAMOUNT_EXPENSE|N;f_REALCURRENTAMOUNT_INCOME|N;"
"f_CURRENTAMOUNT|N;f_CURRENTAMOUNT_EXPENSE|N;f_CURRENTAMOUNT_INCOME|N;"
"f_QUANTITY|Y;f_QUANTITY_EXPENSE|N;f_QUANTITY_INCOME|N;f_REALQUANTITY|Y;f_REALQUANTITY_EXPENSE|N;f_REALQUANTITY_INCOME|N;t_UNIT|N;"
"t_imported|N;t_REALREFUND|N;t_REFUND|N;t_REFUNDDISPLAY|N"
";f_BALANCE|N;f_BALANCE_ENTERED|N;d_createdate|N;i_OPID|N" % propSchema;
listSchema.push_back(amountEntered);
SKGModelTemplate doubleColumnEntered;
doubleColumnEntered.id = QStringLiteral("doublecolumnentered");
doubleColumnEntered.name = i18nc("Noun", "Amount entered in 2 columns");
doubleColumnEntered.icon = QLatin1String("");
doubleColumnEntered.schema = "d_date;d_DATEWEEK|N;d_DATEMONTH|N;d_DATEQUARTER|N;d_DATESEMESTER|N;d_DATEYEAR|N;i_NBRECURRENT;t_bookmarked;t_ACCOUNT;t_TOACCOUNT|N;t_number;t_mode;t_PAYEE;t_comment;t_REALCOMMENT;t_CATEGORY;t_REALCATEGORY;t_status;"
"f_REALCURRENTAMOUNT|N;f_REALCURRENTAMOUNT_EXPENSE|N;f_REALCURRENTAMOUNT_INCOME|N;"
"f_CURRENTAMOUNT|N;f_CURRENTAMOUNT_EXPENSE|N;f_CURRENTAMOUNT_INCOME|N;"
"f_QUANTITY|N;f_QUANTITY_EXPENSE|Y;f_QUANTITY_INCOME|Y;f_REALQUANTITY|N;f_REALQUANTITY_EXPENSE|Y;f_REALQUANTITY_INCOME|Y;t_UNIT|N;"
"t_imported|N;t_REALREFUND|N;t_REFUND|N;t_REFUNDDISPLAY|N"
";f_BALANCE|N;f_BALANCE_ENTERED|N;d_createdate|N;i_OPID|N" % propSchema;
listSchema.push_back(doubleColumnEntered);
} else if (iRealTable == QStringLiteral("recurrentoperation")) {
SKGModelTemplate def;
def.id = QStringLiteral("default");
def.name = i18nc("Noun, the default value of an item", "Default");
def.icon = QStringLiteral("edit-undo");
def.schema = "d_date;t_PERIODNLS;i_nb_times;i_auto_write_days;i_warn_days;t_ACCOUNT;t_number;t_mode;t_PAYEE;t_comment;t_CATEGORY;"
"t_status;f_CURRENTAMOUNT" % propSchema;
listSchema.push_back(def);
SKGModelTemplate minimum;
minimum.id = QStringLiteral("minimum");
minimum.name = i18nc("Noun, the minimum value of an item", "Minimum");
minimum.icon = QLatin1String("");
minimum.schema = "d_date;t_PERIODNLS;i_nb_times;i_auto_write_days;i_warn_days;t_ACCOUNT;t_number|N;t_mode|N;t_PAYEE;t_comment|N;t_CATEGORY|N;"
"t_status;f_CURRENTAMOUNT" % propSchema;
listSchema.push_back(minimum);
} else if (iRealTable == QStringLiteral("account")) {
SKGModelTemplate def;
def.id = QStringLiteral("default");
def.name = i18nc("Noun, the default value of an item", "Default");
def.icon = QStringLiteral("edit-undo");
def.schema = "t_BANK;t_close;t_bookmarked;t_name;t_TYPENLS;t_BANK_NUMBER;t_agency_number;t_number;t_agency_address;t_comment;f_CURRENTAMOUNT;f_QUANTITY|N;f_TODAYAMOUNT|N;f_CHECKED;f_COMING_SOON;f_importbalance|N;d_importdate|N;f_reconciliationbalance|N;d_reconciliationdate|N;i_NBOPERATIONS;f_RATE|N" % propSchema;
listSchema.push_back(def);
SKGModelTemplate minimum;
minimum.id = QStringLiteral("minimum");
minimum.name = i18nc("Noun, the minimum value of an item", "Minimum");
minimum.icon = QLatin1String("");
minimum.schema = "t_BANK;t_close;t_bookmarked|N;t_name;t_TYPENLS|N;t_BANK_NUMBER|N;t_agency_number|N;t_number|N;t_agency_address|N;t_comment|N;f_CURRENTAMOUNT|N;f_QUANTITY|N;f_TODAYAMOUNT|N;f_CHECKED|N;f_COMING_SOON|N;f_importbalance|N;d_importdate|N;f_reconciliationbalance|N;d_reconciliationdate|N;i_NBOPERATIONS|N;f_RATE|N" % propSchema;
listSchema.push_back(minimum);
SKGModelTemplate intermediate;
intermediate.id = QStringLiteral("intermediate");
intermediate.name = i18nc("Noun, an intermediate value between two extremums", "Intermediate");
intermediate.icon = QLatin1String("");
intermediate.schema = "t_BANK;t_close;t_bookmarked;t_name;t_TYPENLS|N;t_BANK_NUMBER|N;t_agency_number|N;t_number|N;t_agency_address|N;t_comment|N;f_CURRENTAMOUNT;f_QUANTITY|N;f_TODAYAMOUNT|N,f_CHECKED;f_COMING_SOON;f_importbalance|N;d_importdate|N;f_reconciliationbalance|N;d_reconciliationdate|N;i_NBOPERATIONS|N;f_RATE|N" % propSchema;
listSchema.push_back(intermediate);
} else if (iRealTable == QStringLiteral("category")) {
SKGModelTemplate def;
def.id = QStringLiteral("default");
def.name = i18nc("Noun, the default value of an item", "Default");
def.icon = QStringLiteral("edit-undo");
def.schema = "t_name;t_close;t_bookmarked;i_NBOPERATIONS;f_REALCURRENTAMOUNT;i_SUMNBOPERATIONS;f_SUMCURRENTAMOUNT" % propSchema;
listSchema.push_back(def);
SKGModelTemplate minimum;
minimum.id = QStringLiteral("minimum");
minimum.name = i18nc("Noun, the minimum value of an item", "Minimum");
minimum.icon = QLatin1String("");
minimum.schema = "t_name;t_close|N;t_bookmarked;i_NBOPERATIONS|N;f_REALCURRENTAMOUNT|N;i_SUMNBOPERATIONS|N;f_SUMCURRENTAMOUNT|N" % propSchema;
listSchema.push_back(minimum);
SKGModelTemplate op;
op.id = QStringLiteral("with_operations");
op.name = i18nc("Noun", "With operations");
op.icon = QLatin1String("");
op.schema = "t_name;t_close;t_bookmarked;i_NBOPERATIONS;f_REALCURRENTAMOUNT;i_SUMNBOPERATIONS|N;f_SUMCURRENTAMOUNT|N" % propSchema;
listSchema.push_back(op);
SKGModelTemplate op2;
op2.id = QStringLiteral("with_cumulative_operations");
op2.name = i18nc("Noun", "With cumulative operations");
op2.icon = QLatin1String("");
op2.schema = "t_name;t_close;t_bookmarked;i_NBOPERATIONS|N;f_REALCURRENTAMOUNT|N;i_SUMNBOPERATIONS;f_SUMCURRENTAMOUNT" % propSchema;
listSchema.push_back(op2);
} else if (iRealTable == QStringLiteral("unit")) {
SKGModelTemplate def;
def.id = QStringLiteral("default");
def.name = i18nc("Noun, the default value of an item", "Default");
def.icon = QStringLiteral("edit-undo");
def.schema = "t_name;t_symbol;t_bookmarked;t_country;t_TYPENLS;t_source;t_internet_code;f_CURRENTAMOUNT;f_QUANTITYOWNED;f_AMOUNTOWNED;i_nbdecimal;t_UNIT;d_MAXDATE|N" % propSchema;
listSchema.push_back(def);
SKGModelTemplate minimum;
minimum.id = QStringLiteral("minimum");
minimum.name = i18nc("Noun, the minimum value of an item", "Minimum");
minimum.icon = QLatin1String("");
minimum.schema = "t_name;t_symbol;t_bookmarked|N;t_country|N;t_TYPENLS;t_source|N;t_internet_code|N;f_CURRENTAMOUNT|N;f_QUANTITYOWNED|N;f_AMOUNTOWNED|N;i_nbdecimal|N;t_UNIT|N;d_MAXDATE|N" % propSchema;
listSchema.push_back(minimum);
} else if (iRealTable == QStringLiteral("unitvalue")) {
SKGModelTemplate def;
def.id = QStringLiteral("default");
def.name = i18nc("Noun, the default value of an item", "Default");
def.icon = QStringLiteral("edit-undo");
def.schema = "d_date;f_quantity;t_UNIT|N;f_AMOUNTOWNED|N" % propSchema;
listSchema.push_back(def);
} else if (iRealTable == QStringLiteral("refund")) {
SKGModelTemplate def;
def.id = QStringLiteral("default");
def.name = i18nc("Noun, the default value of an item", "Default");
def.icon = QStringLiteral("edit-undo");
def.schema = "t_name;t_comment;t_close;d_FIRSTDATE;d_LASTDATE;f_CURRENTAMOUNT" % propSchema;
listSchema.push_back(def);
SKGModelTemplate minimum;
minimum.id = QStringLiteral("minimum");
minimum.name = i18nc("Noun, the minimum value of an item", "Minimum");
minimum.icon = QLatin1String("");
minimum.schema = "t_name;t_comment|N;t_close;d_FIRSTDATE|N;d_LASTDATE|N;f_CURRENTAMOUNT" % propSchema;
listSchema.push_back(minimum);
} else if (iRealTable == QStringLiteral("payee")) {
SKGModelTemplate def;
def.id = QStringLiteral("default");
def.name = i18nc("Noun, the default value of an item", "Default");
def.icon = QStringLiteral("edit-undo");
def.schema = "t_name;t_close;t_bookmarked;t_address;i_NBOPERATIONS|N;f_CURRENTAMOUNT;t_CATEGORY|N" % propSchema;
listSchema.push_back(def);
SKGModelTemplate minimum;
minimum.id = QStringLiteral("minimum");
minimum.name = i18nc("Noun, the minimum value of an item", "Minimum");
minimum.icon = QLatin1String("");
minimum.schema = "t_name;t_close|N;t_bookmarked;t_address|N;i_NBOPERATIONS|N;f_CURRENTAMOUNT;t_CATEGORY|N" % propSchema;
listSchema.push_back(minimum);
} else if (iRealTable == QStringLiteral("rule")) {
SKGModelTemplate def;
def.id = QStringLiteral("default");
def.name = i18nc("Noun, the default value of an item", "Default");
def.icon = QStringLiteral("edit-undo");
def.schema = "i_ORDER;t_bookmarked;t_action_type;t_description;t_action_description" % propSchema;
listSchema.push_back(def);
} else if (iRealTable == QStringLiteral("interest")) {
SKGModelTemplate def;
def.id = QStringLiteral("default");
def.name = i18nc("Noun, the default value of an item", "Default");
def.icon = QStringLiteral("edit-undo");
def.schema = "d_date;f_rate;t_income_value_date_mode;t_expenditure_value_date_mode;t_base" % propSchema;
listSchema.push_back(def);
SKGModelTemplate minimum;
minimum.id = QStringLiteral("minimum");
minimum.name = i18nc("Noun, the minimum value of an item", "Minimum");
minimum.icon = QLatin1String("");
minimum.schema = "d_date;f_rate;t_income_value_date_mode|N;t_expenditure_value_date_mode|N;t_base|N" % propSchema;
listSchema.push_back(minimum);
} else if (iRealTable == QStringLiteral("interest_result")) {
SKGModelTemplate def;
def.id = QStringLiteral("default");
def.name = i18nc("Noun, the default value of an item", "Default");
def.icon = QStringLiteral("edit-undo");
def.schema = "d_date;d_valuedate;t_comment;f_currentamount;f_coef;f_rate;f_annual_interest;f_accrued_interest" % propSchema;
listSchema.push_back(def);
SKGModelTemplate minimum;
minimum.id = QStringLiteral("minimum");
minimum.name = i18nc("Noun, the minimum value of an item", "Minimum");
minimum.icon = QLatin1String("");
minimum.schema = "d_date;d_valuedate|N;t_comment|N;f_currentamount|N;f_coef|N;f_rate;f_annual_interest;f_accrued_interest|N" % propSchema;
listSchema.push_back(minimum);
} else if (iRealTable == QStringLiteral("budget")) {
SKGModelTemplate def;
def.id = QStringLiteral("default");
def.name = i18nc("Noun, the default value of an item", "Default");
def.icon = QStringLiteral("edit-undo");
def.schema = "t_CATEGORY;t_PERIOD;i_year|N;i_month|N;f_budgeted;f_budgeted_modified;f_CURRENTAMOUNT;f_DELTABEFORETRANSFER|N;t_RULES;f_DELTA" % propSchema;
listSchema.push_back(def);
SKGModelTemplate minimum;
minimum.id = QStringLiteral("minimum");
minimum.name = i18nc("Noun, the minimum value of an item", "Minimum");
minimum.icon = QLatin1String("");
minimum.schema = "t_CATEGORY;t_PERIOD;i_year|N;i_month|N;f_budgeted|N;f_budgeted_modified;f_CURRENTAMOUNT;f_DELTABEFORETRANSFER;t_RULES|N;f_DELTA|N" % propSchema;
listSchema.push_back(minimum);
} else if (iRealTable == QStringLiteral("budgetrule")) {
SKGModelTemplate def;
def.id = QStringLiteral("default");
def.name = i18nc("Noun, the default value of an item", "Default");
def.icon = QStringLiteral("edit-undo");
def.schema = "i_ORDER;t_CATEGORYCONDITION;i_year;i_month;t_WHENNLS;t_WHATNLS;t_RULENLS;t_CATEGORY" % propSchema;
listSchema.push_back(def);
} else {
listSchema = SKGDocument::getDisplaySchemas(iRealTable);
}
return listSchema;
}
QString SKGDocumentBank::getIconName(const QString& iString) const
{
QString att = iString.toLower();
if (att.endsWith(QLatin1String("t_bookmarked"))) {
return QStringLiteral("bookmarks");
}
if (att.endsWith(QLatin1String("f_balance")) ||
att.endsWith(QLatin1String("f_balance_entered")) ||
att.endsWith(QLatin1String("f_reconciliationbalance"))) {
return QStringLiteral("office-chart-line");
}
if (att.endsWith(QLatin1String("i_nbrecurrent"))) {
return QStringLiteral("chronometer");
}
if (att.endsWith(QLatin1String("t_status")) ||
att.endsWith(QLatin1String("f_checked")) ||
att.endsWith(QLatin1String("f_coming_soon")) ||
att.endsWith(QLatin1String("d_reconciliationdate"))) {
return QStringLiteral("dialog-ok");
}
if (att.endsWith(QLatin1String("t_close"))) {
return QStringLiteral("window-close");
}
if (att.endsWith(QLatin1String("t_categorycondition")) ||
att.endsWith(QLatin1String("t_category")) ||
att.endsWith(QLatin1String("t_realcategory"))) {
return QStringLiteral("view-categories");
}
if (att.endsWith(QLatin1String("t_symbol"))) {
return QStringLiteral("taxes-finances");
}
if (att.endsWith(QLatin1String("t_typeexpensenls"))) {
return QStringLiteral("skrooge_type");
}
if (att.endsWith(QLatin1String("t_typenls"))) {
if (att.contains(QStringLiteral("v_unit"))) {
return QStringLiteral("view-bank-account-savings");
}
if (att.contains(QStringLiteral("v_account"))) {
return QStringLiteral("skrooge_credit_card");
}
}
if (att.endsWith(QLatin1String("t_unit")) ||
att.endsWith(QLatin1String("t_unittype"))) {
return QStringLiteral("taxes-finances");
}
if (att.endsWith(QLatin1String("f_value")) ||
att.endsWith(QLatin1String("f_currentamount")) ||
att.endsWith(QLatin1String("f_todayamount")) ||
att.endsWith(QLatin1String("f_sumcurrentamount")) ||
att.endsWith(QLatin1String("quantity")) ||
att.endsWith(QLatin1String("f_realcurrentamount"))) {
return QStringLiteral("skrooge_type");
}
if (att.endsWith(QLatin1String("_expense"))) {
return QStringLiteral("list-remove");
}
if (att.endsWith(QLatin1String("_income")) ||
att.endsWith(QLatin1String("f_annual_interest")) ||
att.endsWith(QLatin1String("f_accrued_interest"))) {
return QStringLiteral("list-add");
}
if (att.endsWith(QLatin1String("t_description"))) {
return QStringLiteral("edit-find");
}
if (att.endsWith(QLatin1String("t_action_description"))) {
return QStringLiteral("system-run");
}
if (att.endsWith(QLatin1String("t_imported")) ||
att.endsWith(QLatin1String("f_importbalance")) ||
att.endsWith(QLatin1String("d_importdate"))) {
return QStringLiteral("utilities-file-archiver");
}
if (att.endsWith(QLatin1String("t_refund")) ||
att.endsWith(QLatin1String("t_refunddisplay")) ||
att.endsWith(QLatin1String("t_realrefund"))) {
return QStringLiteral("checkbox");
}
if (att.endsWith(QLatin1String("t_mode"))) {
return QStringLiteral("skrooge_credit_card");
}
if (att.endsWith(QLatin1String("t_account")) ||
att.endsWith(QLatin1String("t_toaccount")) ||
att.endsWith(QLatin1String("t_accounttype"))) {
return QStringLiteral("view-bank");
}
if (att.endsWith(QLatin1String("t_payee"))) {
return QStringLiteral("user-group-properties");
}
if (att.endsWith(QLatin1String("t_comment")) ||
att.endsWith(QLatin1String("t_realcomment"))) {
return QStringLiteral("draw-freehand");
}
if (att.endsWith(QLatin1String("t_warn")) ||
att.endsWith(QLatin1String("i_warn_days"))) {
return QStringLiteral("dialog-information");
}
if (att.endsWith(QLatin1String("t_name"))) {
if (att.contains(QStringLiteral("v_account"))) {
return QStringLiteral("view-bank");
}
if (att.contains(QStringLiteral("v_category"))) {
return QStringLiteral("view-categories");
}
if (att.contains(QStringLiteral("v_refund"))) {
return QStringLiteral("checkbox");
}
if (att.contains(QStringLiteral("v_unit"))) {
return QStringLiteral("taxes-finances");
}
if (att.contains(QStringLiteral("v_payee"))) {
return QStringLiteral("user-group-properties");
}
}
if (att.endsWith(QLatin1String("f_rate"))) {
return QStringLiteral("skrooge_more");
}
if (att.endsWith(QLatin1String("t_internet_code")) || att.endsWith(QLatin1String("t_source")) || att.endsWith(QLatin1String("d_maxdate"))) {
return QStringLiteral("download");
}
if (att.contains(QStringLiteral(".d_")) || att.startsWith(QLatin1String("d_"))) {
return QStringLiteral("view-calendar");
}
if (att.endsWith(QLatin1String("i_year")) || att.endsWith(QLatin1String("i_month")) || att.endsWith(QLatin1String("t_period"))) {
return QStringLiteral("view-calendar");
}
if (att.endsWith(QLatin1String("f_delta"))) {
return QStringLiteral("security-high");
}
if (att.endsWith(QLatin1String("f_deltabeforetransfer"))) {
return QStringLiteral("security-medium");
}
if (att.endsWith(QLatin1String("f_budgeted")) || att.endsWith(QLatin1String("f_budgeted_modified"))) {
return QStringLiteral("view-calendar-whatsnext");
}
if (att.endsWith(QLatin1String("t_rules"))) {
return QStringLiteral("system-run");
}
if (att.endsWith(QLatin1String("t_whennls"))) {
return QStringLiteral("view-calendar");
}
if (att.endsWith(QLatin1String("t_whatnls"))) {
return QStringLiteral("skrooge_type");
}
if (att.endsWith(QLatin1String("t_rulenls"))) {
return QStringLiteral("view-calendar-whatsnext");
}
if (att.endsWith(QLatin1String("t_bank"))) {
return QStringLiteral("view-bank");
}
if (att.endsWith(QLatin1String("t_transfer"))) {
return QStringLiteral("exchange-positions");
}
if (att.endsWith(QLatin1String("_number"))) {
return QStringLiteral("dialog-information");
}
if (att.endsWith(QLatin1String("i_auto_write_days"))) {
return QStringLiteral("insert-text");
}
if (att.endsWith(QLatin1String("_address"))) {
return QStringLiteral("address-book-new");
}
if (att.endsWith(QLatin1String("i_order"))) {
return QStringLiteral("view-sort-ascending");
}
if (att.endsWith(QLatin1String("t_periodnls"))) {
return QStringLiteral("smallclock");
}
return SKGDocument::getIconName(iString);
}
QString SKGDocumentBank::getDisplay(const QString& iString) const
{
QString output = iString.toLower();
// Internationallization
if (output.endsWith(QLatin1String("account.t_name")) ||
output.endsWith(QLatin1String("t_account"))) {
return i18nc("Noun, an account as in a bank account", "Account");
}
if (output.endsWith(QLatin1String("t_accounttype"))) {
return i18nc("Noun, an account as in a bank account", "Account's type");
}
if (output.endsWith(QLatin1String("t_operationname"))) {
return i18nc("Noun, a financial operation", "Operation");
}
if (output.endsWith(QLatin1String("t_name"))) {
return i18nc("Noun, the name of an item", "Name");
}
if (output.endsWith(QLatin1String("account.f_value")) ||
output.endsWith(QLatin1String("f_balance"))) {
return i18nc("Noun, as in commercial balance", "Balance");
}
if (output.endsWith(QLatin1String("f_balance_entered"))) {
return i18nc("Noun, as in commercial balance", "Balance entered");
}
if (output.endsWith(QLatin1String("f_value"))) {
return i18nc("Name, the numerical amount of a financial operation", "Amount");
}
if (output.endsWith(QLatin1String("f_currentamount")) ||
output.endsWith(QLatin1String("f_realcurrentamount"))) {
return i18nc("Name, the numerical amount of a financial operation", "Amount");
}
if (output.endsWith(QLatin1String("f_todayamount"))) {
return i18nc("Name, the numerical amount of a financial operation", "Today amount");
}
if (output.endsWith(QLatin1String("f_currentamount_income")) ||
output.endsWith(QLatin1String("f_realcurrentamount_income"))) {
return i18nc("Noun, financial operations with a positive amount", "Income");
}
if (output.endsWith(QLatin1String("f_currentamount_expense")) ||
output.endsWith(QLatin1String("f_realcurrentamount_expense"))) {
return i18nc("Noun, financial operations with a negative amount", "Expenditure");
}
if (output.endsWith(QLatin1String("f_quantity_income")) ||
output.endsWith(QLatin1String("f_realquantity_income"))) {
return i18nc("Noun", "Income entered");
}
if (output.endsWith(QLatin1String("f_quantity_expense")) ||
output.endsWith(QLatin1String("f_realquantity_expense"))) {
return i18nc("Noun", "Expenditure entered");
}
if (output.endsWith(QLatin1String("f_quantityowned"))) {
return i18nc("Noun", "Quantity owned");
}
if (output.endsWith(QLatin1String("f_amountowned"))) {
return i18nc("Noun", "Amount owned");
}
if (output.endsWith(QLatin1String("quantity"))) {
return i18nc("Noun", "Amount entered");
}
if (output.endsWith(QLatin1String("account.t_number"))) {
return i18nc("Noun", "Account number");
}
if (output.endsWith(QLatin1String("t_number"))) {
return i18nc("Noun, a number identifying an item", "Number");
}
if (output.endsWith(QLatin1String("t_bank_number"))) {
return i18nc("Noun", "Bank number");
}
if (output.endsWith(QLatin1String("t_agency_number"))) {
return i18nc("Noun", "Agency number");
}
if (output.endsWith(QLatin1String("t_agency_address"))) {
return i18nc("Noun", "Agency address");
}
if (output.endsWith(QLatin1String("t_address"))) {
return i18nc("Noun", "Address");
}
if (output.endsWith(QLatin1String("t_payee"))) {
return i18nc("A person or institution receiving a payment, or paying the operation", "Payee");
}
if (output.endsWith(QLatin1String("t_comment"))) {
return i18nc("Noun, a user comment on an item", "Comment");
}
if (output.endsWith(QLatin1String("t_realcomment"))) {
return i18nc("Noun, a user comment on an item", "Sub comment");
}
if (output.endsWith(QLatin1String("t_mode"))) {
return i18nc("Noun, the mode used for payment of the operation (Credit Card, Cheque, Transfer...)", "Mode");
}
if (output.contains(QStringLiteral("recurrentoperation")) && output.endsWith(QLatin1String("d_date"))) {
return i18nc("Noun", "Next occurrence");
}
if (output.endsWith(QLatin1String("d_date")) ||
output.endsWith(QLatin1String("d_dateop"))) {
return i18nc("Noun, the date of an item", "Date");
}
if (output.endsWith(QLatin1String("d_createdate"))) {
return i18nc("Noun, the date of creation of an item", "Creation date");
}
if (output.endsWith(QLatin1String("d_dateweek"))) {
return i18nc("Noun, 7 days", "Week");
}
if (output.endsWith(QLatin1String("d_datemonth"))) {
return i18nc("Noun, the months in a year", "Month");
}
if (output.endsWith(QLatin1String("d_datequarter"))) {
return i18nc("Noun, 3 months", "Quarter");
}
if (output.endsWith(QLatin1String("d_datesemester"))) {
return i18nc("Noun, 6 months", "Semester");
}
if (output.endsWith(QLatin1String("d_dateyear"))) {
return i18nc("Noun, the years in a century", "Year");
}
if (output.endsWith(QLatin1String("d_firstdate"))) {
return i18nc("Noun, the date of an item", "First date");
}
if (output.endsWith(QLatin1String("d_lastdate"))) {
return i18nc("Noun, the date of an item", "Last date");
}
if (output.endsWith(QLatin1String("d_maxdate"))) {
return i18nc("Noun, the date of the last download", "Download date");
}
if (output.endsWith(QLatin1String("d_reconciliationdate"))) {
return i18nc("Noun, the date of the last reconciliation", "Reconciliation date");
}
if (output.endsWith(QLatin1String("t_categorycondition")) ||
output.endsWith(QLatin1String("t_category")) ||
output.endsWith(QLatin1String("t_realcategory"))) {
return i18nc("Noun, the category of an item", "Category");
}
if (output.endsWith(QLatin1String("t_bank"))) {
return i18nc("Noun, a financial institution", "Bank");
}
if (output.endsWith(QLatin1String("t_unit"))) {
return i18nc("Noun, the unit of an operation, usually a currency or a share", "Unit");
}
if (output.endsWith(QLatin1String("t_unittype"))) {
return i18nc("Noun, the unit of an operation, usually a currency or a share", "Unit's type");
}
if (output.endsWith(QLatin1String("f_checked"))) {
return i18nc("Adjective, has an item been checked or not", "Checked");
}
if (output.endsWith(QLatin1String("f_coming_soon"))) {
return i18nc("Adjective, a foreseen value", "To be Checked");
}
if (output.endsWith(QLatin1String("t_symbol"))) {
return i18nc("Noun, ahe unit symbol, something in the line of $, €, £...", "Symbol");
}
if (output.endsWith(QLatin1String("t_country"))) {
return i18nc("Noun, a country in the world (France, China...)", "Country");
}
if (output.endsWith(QLatin1String("t_type")) ||
output.endsWith(QLatin1String("t_typenls"))) {
return i18nc("Noun, the type of an item", "Type");
}
if (output.endsWith(QLatin1String("t_typeexpensenls"))) {
return i18nc("Noun, the type of an item", "Type");
}
if (output.endsWith(QLatin1String("t_internet_code"))) {
return i18nc("Noun", "Internet code");
}
if (output.endsWith(QLatin1String("i_nboperations"))) {
return i18nc("Noun", "Number of operations");
}
if (output.endsWith(QLatin1String("t_periodnls"))) {
return i18nc("Noun, how frequently something occurs", "Periodicity");
}
if (output.endsWith(QLatin1String("i_auto_write_days"))) {
return i18nc("Automatically write something", "Auto write");
}
if (output.endsWith(QLatin1String("i_nb_times"))) {
return i18nc("Noun", "Nb of occurrences");
}
if (output.endsWith(QLatin1String("i_warn_days"))) {
return i18nc("Verb, warn the user about an event", "Warn");
}
if (output.endsWith(QLatin1String("t_close"))) {
return i18nc("Adjective, a closed item", "Closed");
}
if (output.endsWith(QLatin1String("t_bookmarked"))) {
return i18nc("Adjective, an highlighted item", "Highlighted");
}
if (output.endsWith(QLatin1String("t_status"))) {
return i18nc("Noun, the status of an item", "Status");
}
if (output.endsWith(QLatin1String("i_nbrecurrent"))) {
return i18nc("Adjective, an item scheduled to happen on a regular basis", "Scheduled");
}
if (output.endsWith(QLatin1String("i_sumnboperations"))) {
return i18nc("Noun", "Number of operations (cumulative)");
}
if (output.endsWith(QLatin1String("f_sumcurrentamount"))) {
return i18nc("Noun", "Amount (cumulative)");
}
if (output.endsWith(QLatin1String("t_description"))) {
return i18nc("Noun", "Search description");
}
if (output.endsWith(QLatin1String("t_action_description"))) {
return i18nc("Noun", "Process description");
}
if (output.endsWith(QLatin1String("t_action_type"))) {
return i18nc("Noun, the type of action", "Action type");
}
if (output.endsWith(QLatin1String("t_refund")) ||
output.endsWith(QLatin1String("t_realrefund"))) {
return i18nc("Noun, something that is used to track items", "Tracker");
}
if (output.endsWith(QLatin1String("t_refunddisplay"))) {
return i18nc("Noun, something that is used to track items", "Trackers");
}
if (output.endsWith(QLatin1String("t_imported"))) {
return i18nc("Noun", "Import status");
}
if (output.endsWith(QLatin1String("i_nbdecimal"))) {
return i18nc("Noun, after the dot", "Nb decimal");
}
if (output.endsWith(QLatin1String("f_rate"))) {
return i18nc("Noun, for a share", "Rate");
}
if (output.endsWith(QLatin1String("d_valuedate"))) {
return i18nc("Noun", "Value date");
}
if (output.endsWith(QLatin1String("f_coef"))) {
return i18nc("Noun", "Coef");
}
if (output.endsWith(QLatin1String("f_annual_interest"))) {
return i18nc("Noun", "Annual Interest");
}
if (output.endsWith(QLatin1String("f_accrued_interest"))) {
return i18nc("Noun", "Accrued Interest");
}
if (output.endsWith(QLatin1String("t_income_value_date_mode"))) {
return i18nc("Noun", "Value date for credit");
}
if (output.endsWith(QLatin1String("t_expenditure_value_date_mode"))) {
return i18nc("Noun", "Value date for debit");
}
if (output.endsWith(QLatin1String("t_base"))) {
return i18nc("Noun", "Base computation");
}
if (output.endsWith(QLatin1String("i_year"))) {
return i18nc("Noun", "Year");
}
if (output.endsWith(QLatin1String("i_month"))) {
return i18nc("Noun", "Month");
}
if (output.endsWith(QLatin1String("t_period"))) {
return i18nc("Noun", "Period");
}
if (output.endsWith(QLatin1String("i_order"))) {
return i18nc("Noun, sort order", "Order");
}
if (output.endsWith(QLatin1String("t_whennls"))) {
return i18nc("Noun", "When");
}
if (output.endsWith(QLatin1String("t_whatnls"))) {
return i18nc("Noun", "What");
}
if (output.endsWith(QLatin1String("t_rulenls"))) {
return i18nc("Noun", "Impacted budget");
}
if (output.endsWith(QLatin1String("t_rules"))) {
return i18nc("Noun", "Rules");
}
if (output.endsWith(QLatin1String("f_budgeted"))) {
return i18nc("Noun", "Entered Budget");
}
if (output.endsWith(QLatin1String("f_budgeted_modified"))) {
return i18nc("Noun", "Corrected budget");
}
if (output.endsWith(QLatin1String("f_delta"))) {
return i18nc("Noun", "Delta after rules");
}
if (output.endsWith(QLatin1String("f_deltabeforetransfer"))) {
return i18nc("Noun", "Delta");
}
if (output.endsWith(QLatin1String("t_source"))) {
return i18nc("Noun", "Download source");
}
if (output.endsWith(QLatin1String("t_transfer"))) {
return i18nc("Noun", "Transfer");
}
if (output.endsWith(QLatin1String("t_toaccount"))) {
return i18nc("Noun, a target account of a transfer", "To account");
}
if (output.endsWith(QLatin1String("f_maxamount"))) {
return i18nc("Noun, a maximum limit", "Maximum limit");
}
if (output.endsWith(QLatin1String("f_minamount"))) {
return i18nc("Noun, a minimum limit", "Minimum limit");
}
if (output.endsWith(QLatin1String("i_opid"))) {
return i18nc("Noun, the id of an operation", "Operation id");
}
if (output.endsWith(QLatin1String("#nothing#"))) {
return i18nc("Noun, the absence of anything", "-- Nothing --");
}
if (output.endsWith(QLatin1String("f_importbalance"))) {
return i18nc("Noun", "Balance import");
}
if (output.endsWith(QLatin1String("f_reconciliationbalance"))) {
return i18nc("Noun", "Balance reconciliation");
}
if (output.endsWith(QLatin1String("d_importdate"))) {
return i18nc("Noun, the date of the last import", "Import date");
}
return SKGDocument::getDisplay(iString);
}
QString SKGDocumentBank::getRealAttribute(const QString& iString) const
{
if (iString.endsWith(QLatin1String("t_BANK"))) {
return QStringLiteral("bank.rd_bank_id.t_name");
}
if (iString.endsWith(QLatin1String("t_BANK_NUMBER"))) {
return QStringLiteral("bank.rd_bank_id.t_bank_number");
}
return SKGDocument::getRealAttribute(iString);
}
SKGServices::AttributeType SKGDocumentBank::getAttributeType(const QString& iAttributeName) const
{
SKGServices::AttributeType output = SKGServices::TEXT;
if (iAttributeName == QStringLiteral("t_status") || iAttributeName == QStringLiteral("t_imported")) {
return SKGServices::TRISTATE;
}
if (iAttributeName == QStringLiteral("t_close") || iAttributeName == QStringLiteral("t_bookmarked") || iAttributeName == QStringLiteral("t_auto_write") ||
iAttributeName == QStringLiteral("t_warn") || iAttributeName == QStringLiteral("t_TRANSFER") || iAttributeName == QStringLiteral("t_template") ||
iAttributeName == QStringLiteral("t_times") ||
iAttributeName == QStringLiteral("t_absolute") || iAttributeName == QStringLiteral("t_category_condition") || iAttributeName == QStringLiteral("t_month_condition") || iAttributeName == QStringLiteral("t_year_condition") || iAttributeName == QStringLiteral("t_including_subcategories")) {
return SKGServices::BOOL;
}
output = SKGDocument::getAttributeType(iAttributeName);
return output;
}
QVariantList SKGDocumentBank::getBudget(const QString& iMonth) const
{
SKGTRACEINFUNC(10)
QVariantList table;
SKGStringListList listTmp;
SKGError err = executeSelectSqliteOrder("SELECT t_CATEGORY, f_budgeted, f_CURRENTAMOUNT, f_DELTABEFORETRANSFER, f_budgeted_modified FROM v_budget "
"where t_PERIOD='" % iMonth % "' ORDER BY t_CATEGORY;",
listTmp);
int nbval = listTmp.count();
if (!err && nbval > 1) {
table.reserve(nbval + 1);
table.push_back(QVariantList() << "sum" << getDisplay(QStringLiteral("t_CATEGORY")) << getDisplay(QStringLiteral("f_budgeted_modified")) << getDisplay(QStringLiteral("f_CURRENTAMOUNT")) << getDisplay(QStringLiteral("f_DELTA")));
double sum1 = 0;
double sum2 = 0;
double sum3 = 0;
double sum4 = 0;
for (int i = 1; i < nbval; ++i) { // Ignore header
double v1 = SKGServices::stringToDouble(listTmp.at(i).at(1));
double v2 = SKGServices::stringToDouble(listTmp.at(i).at(2));
double v3 = SKGServices::stringToDouble(listTmp.at(i).at(3));
double v4 = SKGServices::stringToDouble(listTmp.at(i).at(4));
table.push_back(QVariantList() << false << listTmp.at(i).at(0) << v1 << v2 << v3 << v4);
sum1 += v1;
sum2 += v2;
sum3 += v3;
sum4 += v4;
}
table.push_back(QVariantList() << true << i18nc("Noun, the numerical total of a sum of values", "Total") << sum1 << sum2 << sum3 << sum4);
}
return table;
}
QVariantList SKGDocumentBank::getMainCategories(const QString& iPeriod, int iNb)
{
SKGTRACEINFUNC(10)
QVariantList table;
SKGServices::SKGUnitInfo primary = getPrimaryUnit();
QString wc = "t_TRANSFER='N' AND t_TYPEEXPENSE='-' AND " + SKGServices::getPeriodWhereClause(iPeriod);
SKGStringListList listTmp;
SKGError err = executeSelectSqliteOrder("SELECT t_REALCATEGORY, TOTAL(f_REALCURRENTAMOUNT), "
"100*TOTAL(f_REALCURRENTAMOUNT)/(SELECT TOTAL(f_REALCURRENTAMOUNT) FROM v_suboperation_consolidated WHERE " % wc % ") "
"FROM v_suboperation_consolidated "
"WHERE " % wc % " GROUP BY t_REALCATEGORY ORDER BY TOTAL(f_REALCURRENTAMOUNT)",
listTmp);
int nbval = listTmp.count();
if (!err && (nbval != 0)) {
table.reserve(nbval);
table.push_back(QVariantList() << "sum" << getDisplay(QStringLiteral("t_REALCATEGORY")) << iPeriod << "url" << "percent");
// Add X main categories
for (int i = 1; i < nbval && i <= iNb; ++i) { // Ignore header
QString cat = listTmp.at(i).at(0);
double v = qAbs(SKGServices::stringToDouble(listTmp.at(i).at(1)));
double p = qAbs(SKGServices::stringToDouble(listTmp.at(i).at(2)));
table.push_back(QVariantList() << false << cat << v << QString(wc % " AND t_REALCATEGORY='" % SKGServices::stringToSqlString(cat) % "'") << p);
}
// Build "Other" category
QStringList listCat;
listCat.reserve(nbval);
double sum = 0.0;
double sumPercent = 0.0;
for (int i = iNb + 1; i < nbval; ++i) {
listCat.push_back(SKGServices::stringToSqlString(listTmp.at(i).at(0)));
sum += qAbs(SKGServices::stringToDouble(listTmp.at(i).at(1)));
sumPercent += qAbs(SKGServices::stringToDouble(listTmp.at(i).at(2)));
}
if (listCat.count() != 0) {
table.push_back(QVariantList() << false << i18nc("an other category", "Others") << sum << QString(wc % " AND t_REALCATEGORY IN ('" % listCat.join(QStringLiteral("','")) % "')") << sumPercent);
}
}
return table;
}
QStringList SKGDocumentBank::get5MainCategoriesVariationList(const QString& iPeriod, const QString& iPreviousPeriod, bool iOnlyIssues, QStringList* oCategoryList)
{
SKGTRACEINFUNC(10)
// Compute input string
QString inputString = iPeriod % iPreviousPeriod % (iOnlyIssues ? 'Y' : 'N') % (oCategoryList != nullptr ? 'Y' : 'N');
// Use cache or not
QStringList output;
if (inputString == m_5mainVariations_inputs) {
// Yes
output = m_5mainVariations_cache;
if (oCategoryList != nullptr) {
*oCategoryList = m_5mainVariationsCat_cache;
}
}
m_5mainVariations_inputs = inputString;
if (output.isEmpty()) {
SKGServices::SKGUnitInfo primary = getPrimaryUnit();
SKGStringListList listTmp;
SKGError err = executeSelectSqliteOrder("select *, 100*(A2-A1)/ABS(A1) as 'V' from "
"(SELECT t_REALCATEGORY as 'C1', TOTAL(f_REALCURRENTAMOUNT) as 'A1' FROM v_suboperation_consolidated where "
"t_TRANSFER='N' AND " + SKGServices::getPeriodWhereClause(iPreviousPeriod) + " AND t_TYPEEXPENSE='-' group by t_REALCATEGORY) A,"
"(SELECT t_REALCATEGORY as 'C2', TOTAL(f_REALCURRENTAMOUNT) as 'A2' FROM v_suboperation_consolidated where "
"t_TRANSFER='N' AND " + SKGServices::getPeriodWhereClause(iPeriod) + " AND t_TYPEEXPENSE='-' group by t_REALCATEGORY) B "
"WHERE A.C1=B.C2 AND ABS(A2-A1)/ABS(A1)>0.1 " +
(iOnlyIssues ? "AND ((A1<0 AND A2<0 AND A2<A1) OR (A1>0 AND A2>0 AND A2<A1))" : "") +
" ORDER BY ABS(A2-A1) DESC LIMIT 5;",
listTmp);
IFOK(err) {
// Clear the list
m_5mainVariations_cache.clear();
m_5mainVariationsCat_cache.clear();
// Fill list
int nbval = listTmp.count();
for (int i = 1; i < nbval; ++i) { // Ignore header
/*Example of sentences:
Expenses in category "Food > Grocery" in November decreased by 14% for a total of 220,48€.
Expenses in category "Food" (no subcategory) in November increased by 24% for a total of 70,20€.
Expenses in category "Automotive > Fuel" in November increased by 24% for a total of 122,48€.
Expenses in category "Misc" in November decreased by 30% for a total of 36,52€.
This month, you spent 75,00€ in Category "Bills > Subscriptions". No expense in that category was found in previous month
Expenses with mode "withdrawal" reprensented 60,00€ of your expenses in current month*/
QString c1 = listTmp.at(i).at(0);
double a1 = SKGServices::stringToDouble(listTmp.at(i).at(1));
double a2 = SKGServices::stringToDouble(listTmp.at(i).at(3));
double v = SKGServices::stringToDouble(listTmp.at(i).at(4));
QString a2f = formatMoney(qAbs(a2), primary);
if (a1 < 0 && a2 < 0) {
QString vf = formatPercentage(qAbs(v), v < 0);
if (v < 0) {
m_5mainVariations_cache.push_back(i18n("Expenses in category <b>'%1'</b> increased by <b>%2</b> for a total of <b>%3</b>.", c1, vf, a2f));
m_5mainVariationsCat_cache.push_back(c1);
} else {
if (!iOnlyIssues) {
m_5mainVariations_cache.push_back(i18n("Expenses in category <b>'%1'</b> decreased by <b>%2</b> for a total of <b>%3</b>.", c1, vf, a2f));
m_5mainVariationsCat_cache.push_back(c1);
}
}
} else if (a1 > 0 && a2 > 0) {
QString vf = formatPercentage(qAbs(v));
if (v > 0) {
if (!iOnlyIssues) {
m_5mainVariations_cache.push_back(i18n("Incomes in category <b>'%1'</b> increased by <b>%2</b> for a total of <b>%3</b>.", c1, vf, a2f));
m_5mainVariationsCat_cache.push_back(c1);
}
} else {
m_5mainVariations_cache.push_back(i18n("Incomes in category <b>'%1'</b> decreased by <b>%2</b> for a total of <b>%3</b>.", c1, vf, a2f));
m_5mainVariationsCat_cache.push_back(c1);
}
}
}
}
output = m_5mainVariations_cache;
if (oCategoryList != nullptr) {
*oCategoryList = m_5mainVariationsCat_cache;
}
}
return output;
}
SKGReport* SKGDocumentBank::getReport() const
{
return new SKGReportBank(const_cast<SKGDocumentBank*>(this));
}
diff --git a/skgbankmodeler/skgdocumentbank.h b/skgbankmodeler/skgdocumentbank.h
index 9abb60c7b..245db428d 100644
--- a/skgbankmodeler/skgdocumentbank.h
+++ b/skgbankmodeler/skgdocumentbank.h
@@ -1,272 +1,272 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGDOCUMENTBANK_H
#define SKGDOCUMENTBANK_H
/** @file
* This file defines classes SKGDocumentBank.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgbankmodeler_export.h"
#include "skgdefinebank.h"
#include "skgdocument.h"
class SKGUnitValueObject;
/**
* This class manages skg bank documents
*/
class SKGBANKMODELER_EXPORT SKGDocumentBank : public SKGDocument
{
Q_OBJECT
Q_CLASSINFO("D-Bus Interface", "org.kde.skrooge.SKGDocumentBank")
public:
/**
* Constructor
*/
explicit SKGDocumentBank();
/**
* Destructor
*/
~SKGDocumentBank() override;
/**
* dump the document in the std output.
* It is useful for debug.
* @param iMode to select what you want to dump.
* @code
* document->dump (DUMPUNIT|DUMPPARAMETERS);
* @endcode
* @return an object managing the error.
* @see SKGError
*/
SKGError dump(int iMode = DUMPBANKOBJECT) const override;
/**
* Create or modify an account
* @param iName account name
* @param iNumber account number
* @param iBankName name of the bank
* @return an object managing the error.
* @see SKGError
*/
virtual SKGError addOrModifyAccount(const QString& iName, const QString& iNumber, const QString& iBankName) const;
/**
* Create or modify the value of an unit
* @param iUnitName unit name
* @param iDate date
* @param iValue unit value for the date @p iDate
* @param oValue this output unit value
* @return an object managing the error.
* @see SKGError
*/
// cppcheck-suppress passedByValue
virtual SKGError addOrModifyUnitValue(const QString& iUnitName, QDate iDate, double iValue, SKGUnitValueObject* oValue = nullptr) const;
/**
* Get Primary unit. WARNING: This value can be not uptodated in a transaction.
* @return Primary unit.
*/
virtual SKGServices::SKGUnitInfo getPrimaryUnit() const;
/**
* Get Secondary unit. WARNING: This value can be not uptodated in a transaction.
* @return Secondary unit.
*/
virtual SKGServices::SKGUnitInfo getSecondaryUnit() const;
/**
* Get the preferred category for a payee. WARNING: This value can be not uptodated in a transaction.
* @param iPayee the payee
* @param iComputeAllPayees compute all categories for all payees and put them in cache. This is better when you know that you will need all.
* @return The preferred category.
*/
virtual QString getCategoryForPayee(const QString& iPayee, bool iComputeAllPayees = true) const;
/**
* Return the number version of views, indexes and triggers
* @return
*/
virtual QString getViewsIndexesAndTriggersVersion() const;
/**
* Get display schemas
* @param iRealTable the real table name
* @return list of schemas
*/
SKGDocument::SKGModelTemplateList getDisplaySchemas(const QString& iRealTable) const override;
/**
* Get the display string for any modeler object (table, attribute)
* @param iString the name of the object (example: v_operation, v_unit.t_name)
* @return the display string
*/
QString getDisplay(const QString& iString) const override;
/**
* Get the real attribute
* @param iString the name of the attribute (something like t_BANK)
* @return the real attribute (something like bank.rd_bank_id.t_name)
*/
QString getRealAttribute(const QString& iString) const override;
/**
* Get the icon for attribute
* @param iString the name of the attribute
* @return the icon name
*/
QString getIconName(const QString& iString) const override;
/**
* Get the attribute type
* @param iAttributeName the name of an attribute
* @return the type
*/
SKGServices::AttributeType getAttributeType(const QString& iAttributeName) const override;
/**
* Get the file extension for this kind of document (must be overwritten)
* @return file extension (like skg)
*/
QString getFileExtension() const override;
/**
* Get the header of the file (useful for magic mime type).
* @return document header
*/
QString getDocumentHeader() const override;
/**
* Get budget report
* @param iMonth the month
* @return the report
*/
virtual QVariantList getBudget(const QString& iMonth) const;
/**
* Get main categories report
* @param iPeriod the period
* @param iNb number of categories
* @return the report
*/
virtual QVariantList getMainCategories(const QString& iPeriod, int iNb = 5);
/**
* Get 5 main variation of categories report
* @param iPeriod the period
* @param iPreviousPeriod the previous period
* @param iOnlyIssues only "Expenses increased" and "Incomes decreased"
* @param oCategoryList to get the category for each variation
* @return the list of variation string
*/
virtual QStringList get5MainCategoriesVariationList(const QString& iPeriod, const QString& iPreviousPeriod, bool iOnlyIssues, QStringList* oCategoryList = nullptr);
/**
* Get the report
* Do not forget to delete the pointer
* @return the report
*/
SKGReport* getReport() const override;
/**
* Refresh all views and indexes in the database
* @param iForce force the refresh
* @return an object managing the error.
* @see SKGError
*/
SKGError refreshViewsIndexesAndTriggers(bool iForce = false) const override;
/**
* Get formated money in primary unit
* @param iValue value
* @return formated value in red or black
*/
Q_INVOKABLE QString formatPrimaryMoney(double iValue) const override;
/**
* Get formated money in primary unit
* @param iValue value
* @return formated value in red or black
*/
Q_INVOKABLE QString formatSecondaryMoney(double iValue) const override;
public Q_SLOTS:
/**
* Close the current transaction.
* A transaction is needed to modify the SKGDocument.
* This transaction is also used to manage the undo/redo.
* @see beginTransaction
* @param succeedded : true to indicate that current transaction has been successfully executed
* : false to indicate that current transaction has failed
* @return an object managing the error
* @see SKGError
*/
SKGError endTransaction(bool succeedded) override;
/**
* Enable/disable balances computation
*/
virtual void setComputeBalances(bool iEnabled);
/**
* Refresh the case.
* @param iTable the modified table triggering the cache refresh.
*/
void refreshCache(const QString& iTable) const override;
protected:
/**
* Migrate the current SKGDocument to the latest version of the data model.
* WARNING: This method must be used in a transaction.
* @see beginTransaction
* @param oMigrationDone to know if a migration has been done or not.
* @return an object managing the error.
* @see SKGError
*/
SKGError migrate(bool& oMigrationDone) override;
/**
* Compute balance of each operation.
* @return an object managing the error.
* @see SKGError
*/
virtual SKGError computeBalances() const;
/**
* Compute the budget suboperation links.
* @return an object managing the error.
* @see SKGError
*/
virtual SKGError computeBudgetSuboperationLinks() const;
private:
Q_DISABLE_COPY(SKGDocumentBank)
QString m_5mainVariations_inputs;
QStringList m_5mainVariations_cache;
QStringList m_5mainVariationsCat_cache;
bool m_computeBalances{true};
QStringList getMigationSteps();
};
/**
* Declare the class
*/
Q_DECLARE_TYPEINFO(SKGDocumentBank, Q_MOVABLE_TYPE);
#endif
diff --git a/skgbankmodeler/skgimportexportmanager.cpp b/skgbankmodeler/skgimportexportmanager.cpp
index 9a55e0b61..aaab0241b 100644
--- a/skgbankmodeler/skgimportexportmanager.cpp
+++ b/skgbankmodeler/skgimportexportmanager.cpp
@@ -1,951 +1,951 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file defines classes SKGImportExportManager.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgimportexportmanager.h"
#include <klocalizedstring.h>
#include <kservicetypetrader.h>
#include <qcryptographichash.h>
#include <qfileinfo.h>
#include <qregexp.h>
#include <qtemporaryfile.h>
#include <qtextcodec.h>
#include <algorithm>
#include "skgbankincludes.h"
#include "skgimportplugin.h"
#include "skgobjectbase.h"
#include "skgpayeeobject.h"
#include "skgrecurrentoperationobject.h"
#include "skgruleobject.h"
#include "skgservices.h"
#include "skgtraces.h"
SKGImportExportManager::SKGImportExportManager(SKGDocumentBank* iDocument,
QUrl iFileName)
: m_document(iDocument), m_fileName(std::move(iFileName)),
m_defaultAccount(nullptr), m_defaultUnit(nullptr),
m_importPlugin(nullptr), m_exportPlugin(nullptr)
{
SKGTRACEINFUNC(10)
setAutomaticValidation(true);
setAutomaticApplyRules(false);
m_since_last_import = true;
m_codec = QStringLiteral("UTF-8");
}
SKGImportExportManager::~SKGImportExportManager()
{
SKGTRACEINFUNC(10)
setDefaultAccount(nullptr);
setDefaultUnit(nullptr);
m_document = nullptr;
m_importPlugin = nullptr;
m_exportPlugin = nullptr;
if (!m_localFileName.isEmpty() && m_localFileName != getFileName().toLocalFile()) {
QFile(m_localFileName).remove();
}
}
QString SKGImportExportManager::getFileNameExtension() const
{
return QFileInfo(getFileName().path()).suffix().toUpper();
}
QUrl SKGImportExportManager::getFileName() const
{
return m_fileName;
}
QString SKGImportExportManager::getLocalFileName(bool iDownload)
{
if (m_localFileName.isEmpty()) {
if (getFileName().isLocalFile()) {
m_localFileName = getFileName().toLocalFile();
} else {
if (iDownload) {
SKGServices::download(QUrl(getFileName()), m_localFileName);
} else {
QTemporaryFile tmpFile;
tmpFile.setAutoRemove(false);
tmpFile.open();
m_localFileName = tmpFile.fileName();
}
}
}
return m_localFileName;
}
SKGError SKGImportExportManager::setDefaultAccount(SKGAccountObject* iAccount)
{
SKGError err;
SKGTRACEINFUNCRC(10, err)
delete m_defaultAccount;
m_defaultAccount = nullptr;
if (iAccount != nullptr) {
m_defaultAccount = new SKGAccountObject(*iAccount);
}
return err;
}
SKGError SKGImportExportManager::getDefaultAccount(SKGAccountObject& oAccount)
{
SKGError err;
SKGTRACEINFUNCRC(10, err)
if (m_defaultAccount == nullptr && (m_document != nullptr)) {
QFileInfo fInfo(getLocalFileName());
QStringList items = fInfo.completeBaseName().split('@');
QString bankname;
QString number;
QString nameComplete;
QString name = items.at(0);
if (items.count() == 2) {
bankname = items.at(1);
QStringList items2 = name.split('-');
if (items2.count() == 2) {
name = items2.at(0);
number = items2.at(1);
} else {
number = name;
}
name.replace('_', ' ');
name.replace('-', ' ');
nameComplete = name;
} else {
bankname = name;
name.replace('_', ' ');
name.replace('-', ' ');
nameComplete = name;
QRegExp rx(QStringLiteral("(\\d{6,})"));
if (rx.indexIn(name) != -1) {
number = rx.cap(1);
if (name != number) {
name = name.remove(number).trimmed();
}
}
}
// Searching if an account exist
QString whereClause = "t_name='" % SKGServices::stringToSqlString(name) % '\'';
whereClause += " OR t_number='" % SKGServices::stringToSqlString(name) % "'";
whereClause += " OR t_agency_number||t_number='" % SKGServices::stringToSqlString(name) % "'";
whereClause += " OR t_BANK_NUMBER||t_agency_number||t_number='" % SKGServices::stringToSqlString(name) % "'";
whereClause += " OR (t_number!='' AND '" % SKGServices::stringToSqlString(name) % "' LIKE t_BANK_NUMBER||t_agency_number||t_number||'__')";
if (!number.isEmpty()) {
whereClause += " OR t_number='" % SKGServices::stringToSqlString(number) % "'";
whereClause += " OR t_agency_number||t_number='" % SKGServices::stringToSqlString(number) % "'";
whereClause += " OR t_BANK_NUMBER||t_agency_number||t_number='" % SKGServices::stringToSqlString(number) % "'";
whereClause += " OR (t_number!='' AND '" % SKGServices::stringToSqlString(number) % "' LIKE t_BANK_NUMBER||t_agency_number||t_number||'__')";
}
const auto words = nameComplete.split(' ');
for (const auto& val : words) {
whereClause += " OR t_number='" % SKGServices::stringToSqlString(val) % '\'';
}
// Avoid to take account with another import ongoing
whereClause = '(' % whereClause % ") AND NOT EXISTS(SELECT 1 FROM operation WHERE operation.rd_account_id=v_account.id AND operation.t_imported='T')";
SKGObjectBase::SKGListSKGObjectBase listAccount;
err = m_document->getObjects(QStringLiteral("v_account"), whereClause % " ORDER BY t_type ASC", listAccount);
IFOK(err) {
if (!listAccount.isEmpty()) {
// Yes ! Only one account found
SKGAccountObject account(listAccount.at(0));
m_defaultAccount = new SKGAccountObject(account);
err = m_document->sendMessage(i18nc("An information message", "Using account '%1' for import", account.getName()));
}
}
// If better account not found, then we must create one
if (m_defaultAccount == nullptr) {
SKGAccountObject account;
SKGBankObject bank(m_document);
IFOKDO(err, bank.setName(bankname))
if (!err && bank.load().isFailed()) {
err = bank.save(false); // Save only
}
IFOKDO(err, bank.addAccount(account))
IFOKDO(err, account.setNumber(number))
int index = 1;
do {
IFOKDO(err, account.setName(name % (index > 1 ? SKGServices::intToString(index) : QString())))
IFOK(err) {
if (account.exist()) {
++index;
} else {
err = account.save(false); // Save only
index = -1;
}
}
} while (!err && index > 0);
IFOK(err) {
m_defaultAccount = new SKGAccountObject(account);
}
IFOKDO(err, m_document->sendMessage(i18nc("An information message", "Default account '%1' created for import", name)))
}
}
if (m_defaultAccount != nullptr) {
oAccount = *m_defaultAccount;
}
return err;
}
SKGError SKGImportExportManager::setDefaultUnit(SKGUnitObject* iUnit)
{
SKGError err;
SKGTRACEINFUNCRC(10, err)
delete m_defaultUnit;
m_defaultUnit = nullptr;
if (iUnit != nullptr) {
m_defaultUnit = new SKGUnitObject(*iUnit);
}
return err;
}
SKGError SKGImportExportManager::getDefaultUnit(SKGUnitObject& oUnit, const QDate* iDate)
{
SKGError err;
SKGTRACEINFUNCRC(10, err)
if ((m_document != nullptr) && (m_defaultUnit == nullptr || (iDate != nullptr))) {
if (m_defaultUnit != nullptr) {
delete m_defaultUnit;
m_defaultUnit = nullptr;
}
// Do we have to found the best unit for a date ?
QString wc = QStringLiteral("t_type IN ('1', '2', 'C')");
if (iDate != nullptr) {
// Yes
wc += " AND (d_MINDATE<'" % SKGServices::dateToSqlString(QDateTime(*iDate)) % "' OR d_MINDATE IS NULL)";
}
// Check if a unit exist
SKGObjectBase::SKGListSKGObjectBase listUnits;
err = m_document->getObjects(QStringLiteral("v_unit"), wc % " ORDER BY ABS(f_CURRENTAMOUNT-1) ASC", listUnits);
IFOK(err) {
if (listUnits.isEmpty()) {
SKGUnitObject unit(m_document);
QString name = i18nc("Noun", "Unit for import");
err = unit.setName(name);
if (unit.load().isFailed()) {
IFOKDO(err, unit.setSymbol(name))
IFOKDO(err, unit.save(false))
SKGUnitValueObject unitval;
IFOKDO(err, unit.addUnitValue(unitval))
IFOKDO(err, unitval.setQuantity(1))
IFOKDO(err, unitval.setDate(QDate(1970, 1, 1)))
IFOKDO(err, unitval.save(false, false))
IFOKDO(err, m_document->sendMessage(i18nc("An information message", "Default unit '%1' created for import", name)))
}
IFOK(err) m_defaultUnit = new SKGUnitObject(unit);
} else {
// Found, we can use it
m_defaultUnit = new SKGUnitObject(listUnits.at(0));
}
}
}
if (m_defaultUnit != nullptr) {
oUnit = *m_defaultUnit;
}
return err;
}
void SKGImportExportManager::setAutomaticValidation(bool iValidation)
{
m_automaticValidationOfImportedOperation = iValidation;
}
bool SKGImportExportManager::automaticValidation() const
{
return m_automaticValidationOfImportedOperation;
}
void SKGImportExportManager::setAutomaticApplyRules(bool iApply)
{
m_automaticApplyRulesOfImportedOperation = iApply;
}
bool SKGImportExportManager::automaticApplyRules() const
{
return m_automaticApplyRulesOfImportedOperation;
}
void SKGImportExportManager::setSinceLastImportDate(bool iSinceLast)
{
m_since_last_import = iSinceLast;
}
bool SKGImportExportManager::sinceLastImportDate() const
{
return m_since_last_import;
}
void SKGImportExportManager::addAccountToCheck(const SKGAccountObject& iAccount, double iBalance)
{
m_AccountToCheck.append(QPair<SKGAccountObject, double>(iAccount, iBalance));
}
QList<QPair<SKGAccountObject, double> > SKGImportExportManager::getAccountsToCheck()
{
return m_AccountToCheck;
}
SKGError SKGImportExportManager::finalizeImportation()
{
SKGError err;
if (!getImportParameters().contains(QStringLiteral("donotfinalize"))) {
SKGTRACEINFUNCRC(2, err)
if (m_document != nullptr) {
// Count the number of operations imported but already existing
QString wc = "v_operation.t_imported='T' AND exists (SELECT 1 from v_operation op2 WHERE op2.t_imported!='T' AND op2.rd_account_id=v_operation.rd_account_id AND op2.t_import_id=v_operation.t_import_id AND ABS(op2.f_CURRENTAMOUNT-v_operation.f_CURRENTAMOUNT)<" % SKGServices::doubleToString(EPSILON) % ')';
SKGObjectBase::SKGListSKGObjectBase objects;
err = m_document->getObjects(QStringLiteral("v_operation"), wc, objects);
int nbOperations = objects.count();
if (!err && (nbOperations != 0)) {
err = m_document->sendMessage(i18np("One operation not imported because it already exists", "%1 operations not imported because they already exist", nbOperations), SKGDocument::Warning);
SKGTRACEL(1) << "### LIST OF OPERATIONS DELETED BY IMPORT_ID ###" << endl;
for (int i = 0; i < nbOperations; ++i) {
SKGTRACEL(1) << objects.at(i).getDisplayName() << " " << objects.at(i).getAttribute(QStringLiteral("t_import_id")) << endl;
}
// Remove operations imported for nothing
IFOKDO(err, m_document->executeSqliteOrder("DELETE from operation WHERE id IN (SELECT id from v_operation WHERE " % wc % ')'))
}
// Delete operations before the last import
if (sinceLastImportDate() && !err) {
SKGTRACEINRC(2, "SKGImportExportManager::finalizeImportation-since last date", err)
// Count the number of operations before the last import
QString wc2 = QStringLiteral("operation.t_imported='T' AND "
"EXISTS(SELECT 1 FROM operation o INDEXED BY idx_operation_rd_account_id_t_imported WHERE o.rd_account_id=operation.rd_account_id AND o.t_imported IN ('Y', 'P') AND date(o.d_date,'-4 day')>operation.d_date)");
err = m_document->getObjects(QStringLiteral("operation"), wc2, objects);
int nbOperations2 = objects.count();
if (!err && (nbOperations2 != 0)) {
err = m_document->sendMessage(i18np("One operation was not imported because it was dated before the last imported one, you can uncheck the option to avoid this.", "%1 operations were not imported because they were dated before the last imported one, you can uncheck the option to avoid this.", nbOperations2), SKGDocument::Warning);
SKGTRACEL(1) << "### LIST OF OPERATIONS DELETED BECAUSE AFTER THE LAST ONE ###" << endl;
for (int i = 0; i < nbOperations2; ++i) {
SKGTRACEL(1) << objects.at(i).getDisplayName() << endl;
}
// Remove operations imported for nothing
IFOKDO(err, m_document->executeSqliteOrder("DELETE from operation WHERE " % wc2))
}
}
// For performances
IFOKDO(err, m_document->executeSqliteOrder(QStringLiteral("ANALYZE")))
// Apply rules
if (!err && m_automaticApplyRulesOfImportedOperation) {
SKGTRACEINRC(2, "SKGImportExportManager::finalizeImportation-apply rules", err)
// Get rules
SKGObjectBase::SKGListSKGObjectBase rules;
IFOKDO(err, m_document->getObjects(QStringLiteral("v_rule"), QStringLiteral("1=1 ORDER BY f_sortorder"), rules))
int nbRules = rules.count();
IFOKDO(err, m_document->beginTransaction("#INTERNAL#" % i18nc("Progression step", "Finalize import"), nbRules))
for (int i = 0; !err && i < nbRules; ++i) {
SKGRuleObject rule(rules.at(i));
err = rule.execute(SKGRuleObject::IMPORTING);
IFOKDO(err, m_document->stepForward(i + 1))
}
SKGENDTRANSACTION(m_document, err)
// A failure in rule will not block the transaction.
// A warning message is sent
IFKO(err) err = m_document->sendMessage(i18nc("Warning message", "Error during execution of rules:\n%1", err.getFullMessageWithHistorical()), SKGDocument::Error);
}
// Change imported status
IFOK(err) {
SKGTRACEINRC(2, "SKGImportExportManager::finalizeImportation-change imported status", err)
int nbopimported = 0;
err = m_document->getNbObjects(QStringLiteral("operation"), QStringLiteral("t_imported='T'"), nbopimported);
IFOKDO(err, m_document->sendMessage(i18np("%1 operation imported", "%1 operations imported", nbopimported), SKGDocument::Positive))
IFOKDO(err, m_document->executeSqliteOrder(QStringLiteral("UPDATE operation SET t_imported='") %
(m_automaticValidationOfImportedOperation ? QStringLiteral("Y") : QStringLiteral("P")) %
"' WHERE t_imported='T'"));
}
// Check balances of accounts
int nb = m_AccountToCheck.count();
for (int i = 0; !err && i < nb; ++i) {
// Get the account to check
auto act = m_AccountToCheck.at(i).first;
auto targetBalance = m_AccountToCheck.at(i).second;
err = act.setAttribute(QStringLiteral("f_importbalance"), SKGServices::doubleToString(targetBalance));
IFOKDO(err, act.setAttribute(QStringLiteral("d_importdate"), SKGServices::dateToSqlString(QDate::currentDate())))
IFOKDO(err, act.save())
auto soluces = act.getPossibleReconciliations(targetBalance, false);
if (soluces.isEmpty()) {
IFOKDO(err, m_document->sendMessage(i18nc("Information message", "The balance of account '%1' is not aligned with import balance %2", act.getDisplayName(), m_document->formatMoney(targetBalance, m_document->getPrimaryUnit())),
SKGDocument::Warning,
QString("skg://skrooge_operation_plugin/?title_icon=quickopen&title=" % SKGServices::encodeForUrl(i18nc("Noun, a list of items", "Operations of account \"%1\" used for auto reconciliation", act.getDisplayName())) %
"&operationWhereClause=" % SKGServices::encodeForUrl("rd_account_id=" + SKGServices::intToString(act.getID()) + " AND t_template='N' AND ((t_status='N' AND t_imported IN ('Y','P')) OR t_status='Y')"))));
} else {
IFOKDO(err, m_document->sendMessage(i18nc("Information message", "The balance of account '%1' is aligned with import balance %2", act.getDisplayName(), m_document->formatMoney(targetBalance, m_document->getPrimaryUnit())), SKGDocument::Positive))
}
}
}
}
return err;
}
void SKGImportExportManager::setExportParameters(const QMap< QString, QString >& iParameters)
{
SKGImportPlugin* plugin = getExportPlugin();
if (plugin != nullptr) {
plugin->setExportParameters(iParameters);
}
}
QMap< QString, QString > SKGImportExportManager::getExportParameters()
{
QMap< QString, QString > output;
SKGImportPlugin* plugin = getExportPlugin();
if (plugin != nullptr) {
output = plugin->getExportParameters();
}
return output;
}
void SKGImportExportManager::setImportParameters(const QMap< QString, QString >& iParameters)
{
SKGImportPlugin* plugin = getImportPlugin();
if (plugin != nullptr) {
plugin->setImportParameters(iParameters);
}
}
QString SKGImportExportManager::getParameterDefaultValue(const QString& iParameter)
{
QString output;
// Search the first plugin having a value for this parameter
KService::List offers = KServiceTypeTrader::self()->query(QStringLiteral("SKG IMPORT/Plugin"));
int nb = offers.count();
for (int i = 0; i < nb && output.isEmpty(); ++i) {
KService::Ptr service = offers.at(i);
KPluginLoader loader(service->library());
KPluginFactory* factory = loader.factory();
if (factory != nullptr) {
auto* pluginInterface = factory->create<SKGImportPlugin> (nullptr);
if (pluginInterface != nullptr) {
auto val = pluginInterface->getImportParameters().value(iParameter);
if (!val.isEmpty()) {
output = val;
} else {
output = pluginInterface->getExportParameters().value(iParameter);
}
delete pluginInterface;
}
}
}
return output;
}
QMap< QString, QString > SKGImportExportManager::getImportParameters()
{
QMap< QString, QString > output;
SKGImportPlugin* plugin = getImportPlugin();
if (plugin != nullptr) {
output = plugin->getImportParameters();
}
return output;
}
QString SKGImportExportManager::getImportMimeTypeFilter(bool iIncludingAll)
{
QMap<QString, QString> tmp;
KService::List offers = KServiceTypeTrader::self()->query(QStringLiteral("SKG IMPORT/Plugin"));
int nb = offers.count();
for (int i = 0; i < nb; ++i) {
KService::Ptr service = offers.at(i);
QString name = service->name();
QString msg = i18nc("Message", "Loading plugin %1/%2: %3...", i + 1, nb, name);
SKGTRACEL(1) << msg << endl;
KPluginLoader loader(service->library());
KPluginFactory* factory = loader.factory();
if (factory != nullptr) {
auto* pluginInterface = factory->create<SKGImportPlugin> (nullptr);
if (pluginInterface != nullptr) {
if (pluginInterface->isImportPossible()) {
QString mime = pluginInterface->getMimeTypeFilter();
if (!mime.isEmpty()) {
QStringList lines = SKGServices::splitCSVLine(mime, '\n');
int nblines = lines.count();
for (int l = 0; l < nblines; ++l) {
QStringList items = SKGServices::splitCSVLine(lines.at(l), '|');
tmp[items.at(1)] = items.at(0);
}
}
}
delete pluginInterface;
}
}
}
QStringList descriptions = tmp.keys();
std::sort(descriptions.begin(), descriptions.end());
QStringList regexps = tmp.values();
QString output;
if (iIncludingAll) {
output = regexps.join(QStringLiteral(" ")) % '|' % i18nc("A file format", "All supported formats");
}
nb = descriptions.count();
for (int i = 0; i < nb; ++i) {
if (!output.isEmpty()) {
output += '\n';
}
output += tmp[descriptions.at(i)] % '|' % descriptions.at(i);
}
return output;
}
QString SKGImportExportManager::getExportMimeTypeFilter(bool iIncludingAll)
{
QMap<QString, QString> tmp;
KService::List offers = KServiceTypeTrader::self()->query(QStringLiteral("SKG IMPORT/Plugin"));
int nb = offers.count();
for (int i = 0; i < nb; ++i) {
KService::Ptr service = offers.at(i);
QString name = service->name();
QString msg = i18nc("Message", "Loading plugin %1/%2: %3...", i + 1, nb, name);
SKGTRACEL(1) << msg << endl;
KPluginLoader loader(service->library());
KPluginFactory* factory = loader.factory();
if (factory != nullptr) {
auto* pluginInterface = factory->create<SKGImportPlugin> (nullptr);
if (pluginInterface != nullptr) {
if (pluginInterface->isExportPossible()) {
QString mime = pluginInterface->getMimeTypeFilter();
if (!mime.isEmpty()) {
QStringList lines = SKGServices::splitCSVLine(mime, '\n');
int nblines = lines.count();
for (int l = 0; l < nblines; ++l) {
QStringList items = SKGServices::splitCSVLine(lines.at(l), '|');
tmp[items.at(1)] = items.at(0);
}
}
}
delete pluginInterface;
}
}
}
QStringList descriptions = tmp.keys();
std::sort(descriptions.begin(), descriptions.end());
QStringList regexps = tmp.values();
QString output;
if (iIncludingAll) {
output = regexps.join(QStringLiteral(" ")) % '|' % i18nc("A file format", "All supported formats");
}
nb = descriptions.count();
for (int i = 0; i < nb; ++i) {
if (!output.isEmpty()) {
output += '\n';
}
output += tmp[descriptions.at(i)] % '|' % descriptions.at(i);
}
return output;
}
SKGImportPlugin* SKGImportExportManager::getImportPlugin()
{
if (m_importPlugin == nullptr) {
KService::List offers = KServiceTypeTrader::self()->query(QStringLiteral("SKG IMPORT/Plugin"));
int nb = offers.count();
for (int i = 0; (m_importPlugin == nullptr) && i < nb; ++i) {
KService::Ptr service = offers.at(i);
QString id = service->property(QStringLiteral("X-Krunner-ID"), QVariant::String).toString();
KPluginLoader loader(service->library());
KPluginFactory* factory = loader.factory();
if (factory != nullptr) {
auto* pluginInterface = factory->create<SKGImportPlugin> (this);
if (pluginInterface != nullptr) {
if (pluginInterface->isImportPossible()) {
// Import
m_importPlugin = pluginInterface;
}
}
} else if (m_document != nullptr) {
m_document->sendMessage(i18nc("An information message", "Loading plugin %1 failed because the factory could not be found in %2", id, service->library()), SKGDocument::Error);
}
}
}
return m_importPlugin;
}
SKGImportPlugin* SKGImportExportManager::getExportPlugin()
{
if (m_exportPlugin == nullptr) {
KService::List offers = KServiceTypeTrader::self()->query(QStringLiteral("SKG IMPORT/Plugin"));
int nb = offers.count();
for (int i = 0; (m_exportPlugin == nullptr) && i < nb; ++i) {
KService::Ptr service = offers.at(i);
QString id = service->property(QStringLiteral("X-Krunner-ID"), QVariant::String).toString();
KPluginLoader loader(service->library());
KPluginFactory* factory = loader.factory();
if (factory != nullptr) {
auto* pluginInterface = factory->create<SKGImportPlugin> (this);
if (pluginInterface != nullptr) {
if (pluginInterface->isExportPossible()) {
// Import
m_exportPlugin = pluginInterface;
}
}
} else if (m_document != nullptr) {
m_document->sendMessage(i18nc("An information message", "Loading plugin %1 failed because the factory could not be found in %2", id, service->library()), SKGDocument::Error);
}
}
}
return m_exportPlugin;
}
SKGError SKGImportExportManager::importFile()
{
SKGError err;
SKGTRACEINFUNCRC(2, err)
if (m_document != nullptr) {
SKGBEGINPROGRESSTRANSACTION(*m_document, i18nc("Noun, name of the user action", "Import with codec %1", m_codec), err, 3)
err = m_document->executeSqliteOrder(QStringLiteral("ANALYZE"));
IFOKDO(err, m_document->stepForward(1))
IFOK(err) {
// Search plugins
bool fileTreated = false;
SKGImportPlugin* pluginInterface = getImportPlugin();
if (pluginInterface != nullptr) {
// Import
fileTreated = true;
m_AccountToCheck.clear();
SKGTRACEL(2) << "Input filename=" << m_fileName.toDisplayString() << endl;
SKGTRACEL(2) << "Input local filename=" << getLocalFileName() << endl;
err = pluginInterface->importFile();
}
if (!err && !fileTreated) {
err.setReturnCode(ERR_NOTIMPL).setMessage(i18nc("Error message", "The import mode %1 is not yet implemented", getFileNameExtension()));
}
}
IFOKDO(err, m_document->stepForward(2))
IFOKDO(err, finalizeImportation())
IFOKDO(err, m_document->stepForward(3))
}
return err;
}
SKGError SKGImportExportManager::exportFile()
{
SKGError err;
SKGTRACEINFUNCRC(2, err)
if (m_document != nullptr) {
err = m_document->executeSqliteOrder(QStringLiteral("ANALYZE"));
IFOK(err) {
// Search plugins
bool fileTreated = false;
SKGImportPlugin* pluginInterface = getExportPlugin();
if (pluginInterface != nullptr) {
// Import
fileTreated = true;
SKGTRACEL(2) << "Input filename=" << m_fileName.toDisplayString() << endl;
SKGTRACEL(2) << "Input local filename=" << getLocalFileName(false) << endl;
err = pluginInterface->exportFile();
IFOKDO(err, SKGServices::upload(QUrl::fromLocalFile(getLocalFileName(false)), m_fileName))
}
if (!err && !fileTreated) {
err.setReturnCode(ERR_NOTIMPL).setMessage(i18nc("Error message", "This export mode is not yet implemented"));
}
}
}
return err;
}
SKGError SKGImportExportManager::cleanBankImport()
{
SKGError err;
SKGTRACEINFUNCRC(2, err)
// Begin transaction
if (m_document != nullptr) {
err = m_document->beginTransaction("#INTERNAL#" % i18nc("Progression step", "Clean import"), 3);
IFOK(err) {
// Step 1 Clean operations without mode and with comment with double space
SKGObjectBase::SKGListSKGObjectBase operations;
IFOKDO(err, m_document->getObjects(QStringLiteral("operation"), QStringLiteral("t_imported!='N' and t_mode='' and t_comment like '% %'"), operations))
int nb = operations.count();
for (int i = 0; !err && i < nb ; ++i) {
SKGOperationObject op(operations.at(i));
// Comment is like this: <TYPE> <INFO>
// Example: RETRAIT DAB 20/01/08 11H44 013330 LCL GAILLAC 000497
QRegExp rx(QStringLiteral("(.+) {2,}(.+)"));
QString comment = op.getComment();
if (rx.indexIn(comment) != -1) {
// Get parameters
QString mode = rx.cap(1);
QString info = rx.cap(2);
// Modify
err = op.setComment(info.trimmed());
IFOKDO(err, op.setMode(mode.trimmed()))
IFOKDO(err, op.save(true, false)) // No reload
}
}
// Step 1 done
IFOKDO(err, m_document->stepForward(1))
// Step 2 Clean operations without mode and with comment
IFOKDO(err, m_document->getObjects(QStringLiteral("operation"), QStringLiteral("t_imported!='N' and t_mode='' and t_comment!=''"), operations))
nb = operations.count();
for (int i = 0; !err && i < nb ; ++i) {
SKGOperationObject op(operations.at(i));
// Comment is like this: <TYPE> <INFO>
// Example: RETRAIT DAB 14-05-16607-482390
QRegExp rx(QStringLiteral("(\\S+) +(.+)"));
QString comment = op.getComment();
if (rx.indexIn(comment) != -1) {
// Get parameters
QString mode = rx.cap(1);
QString info = rx.cap(2);
// Modify
err = op.setComment(info.trimmed());
IFOKDO(err, op.setMode(mode.trimmed()))
IFOKDO(err, op.save(true, false)) // No reload
}
}
// Step 2 done
IFOKDO(err, m_document->stepForward(2))
// Step 3 Clean cheque without number
IFOKDO(err, m_document->getObjects(QStringLiteral("operation"), QStringLiteral("t_imported!='N' and t_number='' and lower(t_mode)='cheque'"), operations))
nb = operations.count();
for (int i = 0; !err && i < nb ; ++i) {
SKGOperationObject op(operations.at(i));
// Comment is like this: <TYPE> <INFO>
// Example: RETRAIT DAB 20/01/08 11H44 013330 LCL GAILLAC 000497
QRegExp rx(QStringLiteral("(\\d+)"));
QString comment = op.getComment();
if (rx.indexIn(comment) != -1) {
// Get parameters
auto number = rx.cap(1);
// Modify
err = op.setNumber(number);
IFOKDO(err, op.save(true, false)) // No reload
}
}
// Step 3 done
IFOKDO(err, m_document->stepForward(3))
}
SKGENDTRANSACTION(m_document, err)
}
return err;
}
SKGError SKGImportExportManager::anonymize(const QString& iKey)
{
SKGError err;
SKGTRACEINFUNCRC(2, err)
if (m_document != nullptr) {
if (m_document->isFileModified()) {
err = SKGError(ERR_ABORT, i18nc("An information message", "The document must be saved to be anonymized."), QStringLiteral("skg://file_save"));
} else {
{
// Remove password
m_document->changePassword(QLatin1String(""));
// Anonymize data
QStringList sqlOrders;
if (iKey.isEmpty()) {
// Not reversible
sqlOrders << QStringLiteral("UPDATE bank SET t_bank_number='', t_name='bank_'||id")
<< QStringLiteral("UPDATE account SET t_number='', t_agency_number='', t_agency_address='', t_comment='', t_name='account_'||id")
<< QStringLiteral("UPDATE category SET t_name='category_'||id")
<< QStringLiteral("UPDATE payee SET t_address='', t_name='payee_'||id")
<< QStringLiteral("UPDATE refund SET t_comment='', t_name='tracker_'||id")
<< QStringLiteral("UPDATE operation SET t_comment=''")
<< QStringLiteral("UPDATE suboperation SET t_comment='', f_value=f_value%1234.56")
<< QStringLiteral("DELETE FROM parameters WHERE t_name NOT LIKE 'SKG_%' OR t_name='SKG_PASSWORD'");
} else {
// Reversible
sqlOrders << QStringLiteral("UPDATE bank SET t_bank_number=XOR(t_bank_number,'") + SKGServices::stringToSqlString(iKey) + "'), t_name=XOR(t_name,'" + SKGServices::stringToSqlString(iKey) + "')"
<< QStringLiteral("UPDATE account SET t_number=XOR(t_number,'") + SKGServices::stringToSqlString(iKey) + "'), t_agency_number=XOR(t_agency_number,'" + SKGServices::stringToSqlString(iKey) + "'), t_agency_address=XOR(t_agency_address,'" + SKGServices::stringToSqlString(iKey) + "'), t_comment=XOR(t_comment,'" + SKGServices::stringToSqlString(iKey) + "'), t_name=XOR(t_name,'" + SKGServices::stringToSqlString(iKey) + "')"
<< QStringLiteral("UPDATE category SET t_name=XOR(t_name,'") + SKGServices::stringToSqlString(iKey) + "')"
<< QStringLiteral("UPDATE payee SET t_address=XOR(t_address,'") + SKGServices::stringToSqlString(iKey) + "'), t_name=XOR(t_name,'" + SKGServices::stringToSqlString(iKey) + "')"
<< QStringLiteral("UPDATE refund SET t_comment=XOR(t_comment,'") + SKGServices::stringToSqlString(iKey) + "'), t_name=XOR(t_name,'" + SKGServices::stringToSqlString(iKey) + "')"
<< QStringLiteral("UPDATE operation SET t_comment=XOR(t_comment,'") + SKGServices::stringToSqlString(iKey) + "')"
<< QStringLiteral("UPDATE suboperation SET t_comment=XOR(t_comment,'") + SKGServices::stringToSqlString(iKey) + "'), f_value=XORD(f_value,'" + SKGServices::stringToSqlString(iKey) + "')"
<< QStringLiteral("UPDATE parameters SET t_name=XOR(t_name,'") + SKGServices::stringToSqlString(iKey) + "'), t_value=XOR(t_value,'" + SKGServices::stringToSqlString(iKey) + "'), b_blob=XOR(b_blob,'" + SKGServices::stringToSqlString(iKey) + "') WHERE t_name NOT LIKE 'SKG_%'"
<< QStringLiteral("DELETE FROM parameters WHERE t_name='SKG_PASSWORD'");
}
int nb = sqlOrders.count();
SKGBEGINPROGRESSTRANSACTION(*m_document, "##INTERNAL##" % i18nc("Progression step", "Anonymize"), err, nb)
for (int i = 0; !err && i < nb; ++i) {
err = m_document->executeSqliteOrder(sqlOrders.at(i));
IFOKDO(err, m_document->stepForward(i + 1))
}
if (iKey.isEmpty()) {
m_document->sendMessage(i18nc("An information message", "The document has been made anonymous with an irreversible mode."), SKGDocument::Positive);
} else {
m_document->sendMessage(i18nc("An information message", "The document has been made anonymous with a reversible mode. Don't forget the key if you want to reverse it."), SKGDocument::Information);
}
}
// Remove transactions
IFOKDO(err, m_document->removeAllTransactions())
// Save new file
QString newName = m_document->getCurrentFileName().replace(QStringLiteral(".skg"), QStringLiteral("-anonymized.skg"));
if (newName == m_document->getCurrentFileName()) {
newName = m_document->getCurrentFileName() % "-anonymized.skg";
}
IFOKDO(err, m_document->saveAs(newName, true))
}
}
return err;
}
SKGError SKGImportExportManager::findAndGroupTransfers(int& oNbOperationsMerged, const QString& iAdditionnalCondition)
{
SKGError err;
SKGTRACEINFUNCRC(2, err)
oNbOperationsMerged = 0;
// Begin transaction
if (m_document != nullptr) {
err = m_document->beginTransaction("#INTERNAL#" % i18nc("Progression step", "Find and group transfers"), 3);
IFOK(err) {
IFOKDO(err, m_document->executeSqliteOrder(QStringLiteral("ANALYZE")))
// Look for operations with
// Same units
// Same dates
// Null i_group_id
// Different accounts
// Opposite amounts
SKGStringListList listTmp;
{
SKGTRACEIN(2, "SKGImportExportManager::findAndGroupTransfers-step 1")
IFOKDO(err, m_document->executeSelectSqliteOrder(
"SELECT ID1, ID2 FROM (SELECT A.id as ID1, B.id as ID2, (SELECT TOTAL(s.f_value) FROM suboperation s "
"WHERE s.rd_operation_id=A.ID) AS quantity1, (SELECT TOTAL(s.f_value) FROM suboperation s "
"WHERE s.rd_operation_id=B.ID) AS quantity2 FROM operation A, operation B "
"WHERE +A.d_date=B.d_date AND A.rc_unit_id=B.rc_unit_id AND A.id<=B.id AND A.rd_account_id!=B.rd_account_id AND A.i_group_id=0 AND B.i_group_id=0" %
(iAdditionnalCondition.isEmpty() ? QString() : QStringLiteral(" AND ") % iAdditionnalCondition) % ") "
"WHERE ABS(quantity1+quantity2)<1e-5 AND quantity1!=0",
listTmp));
// Step 1 done
IFOKDO(err, m_document->stepForward(1))
}
SKGStringListList listTmp2;
{
SKGTRACEIN(2, "SKGImportExportManager::findAndGroupTransfers-step 2")
// +A.i_group_id=0 AND +B.i_group_id=0 is for avoiding to use bad index
IFOKDO(err, m_document->executeSelectSqliteOrder(
"SELECT A.id, B.id FROM v_operation A, operation B, parameters P "
"WHERE +P.t_name='SKG_OP_ORIGINAL_AMOUNT' AND +P.t_uuid_parent=B.id||'-operation' AND A.rc_unit_id!=B.rc_unit_id AND A.d_date=B.d_date AND A.rd_account_id!=B.rd_account_id AND ABS(A.f_CURRENTAMOUNT+CAST(P.t_value AS REAL))<" % SKGServices::doubleToString(EPSILON) % " AND +A.i_group_id=0 AND +B.i_group_id=0 AND A.f_CURRENTAMOUNT!=0" %
(iAdditionnalCondition.isEmpty() ? QString() : QStringLiteral(" AND ") % iAdditionnalCondition),
listTmp2));
// Step 2 done
IFOKDO(err, m_document->stepForward(2))
listTmp2.removeAt(0); // Remove header
listTmp += listTmp2;
}
// Group
{
SKGTRACEIN(2, "SKGImportExportManager::findAndGroupTransfers-group")
oNbOperationsMerged = listTmp.count();
IFOKDO(err, m_document->beginTransaction("#INTERNAL#" % i18nc("Progression step", "Find and group transfers"), oNbOperationsMerged - 1))
for (int i = 1; !err && i < oNbOperationsMerged ; ++i) { // First line ignored because of its header
SKGOperationObject op1(m_document, SKGServices::stringToInt(listTmp.at(i).at(0)));
SKGOperationObject op2(m_document, SKGServices::stringToInt(listTmp.at(i).at(1)));
if (!op1.isInGroup() && !op2.isInGroup()) {
err = op2.setGroupOperation(op1);
IFOKDO(err, op2.save(true, false))
}
IFOKDO(err, m_document->stepForward(i))
}
SKGENDTRANSACTION(m_document, err)
}
oNbOperationsMerged = (oNbOperationsMerged - 1) * 2;
// Step 3 done
IFOKDO(err, m_document->stepForward(3))
}
SKGENDTRANSACTION(m_document, err)
}
return err;
}
SKGError SKGImportExportManager::findAndGroupTransfers(int& oNbOperationsMerged, bool iOnCurrentlyImport)
{
return findAndGroupTransfers(oNbOperationsMerged, iOnCurrentlyImport ? QStringLiteral("A.t_imported='T' AND B.t_imported='T'") : QLatin1String(""));
}
diff --git a/skgbankmodeler/skgimportexportmanager.h b/skgbankmodeler/skgimportexportmanager.h
index 0f5742446..fccac74a1 100644
--- a/skgbankmodeler/skgimportexportmanager.h
+++ b/skgbankmodeler/skgimportexportmanager.h
@@ -1,311 +1,311 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGIMPORTEXPORTMANAGER_H
#define SKGIMPORTEXPORTMANAGER_H
/** @file
* This file defines classes SKGImportExportManager.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include <qmap.h>
#include <qobject.h>
#include <qstringlist.h>
#include <qurl.h>
#include "skgaccountobject.h"
#include "skgbankmodeler_export.h"
#include "skgerror.h"
class SKGDocumentBank;
class SKGAccountObject;
class SKGUnitObject;
class QDate;
class SKGImportPlugin;
/**
*Manage import and export
*/
class SKGBANKMODELER_EXPORT SKGImportExportManager : public QObject
{
Q_OBJECT
public:
/**
* Constructor.
* @param iDocument the document
* @param iFileName the file name
*/
explicit SKGImportExportManager(SKGDocumentBank* iDocument,
QUrl iFileName = QUrl(QLatin1String("")));
/**
* Destructor
*/
~SKGImportExportManager() override;
/**
* Set the codec used for imports.
* @param iCodec the codec name.
*/
inline void setCodec(const QString& iCodec)
{
m_codec = iCodec;
}
/**
* Get the codec used for imports.
* @return code.
*/
inline QString getCodec() const
{
return m_codec;
}
/**
* Set the default account for import in case of account is not detected in imported file.
* @param iAccount the account where to import. nullptr if you want to create a specific account for that.
* @return an object managing the error.
* @see SKGError
*/
SKGError setDefaultAccount(SKGAccountObject* iAccount);
/**
* Set the default unit for import in case of unit is not detected in imported file.
* @param iUnit the unit where to import. nullptr if you want to create a specific unit for that.
* @return an object managing the error.
* @see SKGError
*/
SKGError setDefaultUnit(SKGUnitObject* iUnit);
/**
* Enable/disable the automatically validation of imported operations.
* @param iValidation the mode.
*/
void setAutomaticValidation(bool iValidation);
/**
* get the automatic validation state
* @return The automatic validation state.
*/
bool automaticValidation() const;
/**
* Enable/disable the automatically rules application on imported operations.
* @param iApply the mode.
*/
void setAutomaticApplyRules(bool iApply);
/**
* get the automatic apply rules state
* @return The automatic apply rules state.
*/
bool automaticApplyRules() const;
/**
* To authorize the import of operations after the last imported operation
* @param iSinceLast the mode.
*/
void setSinceLastImportDate(bool iSinceLast);
/**
* get the since last import state
* @return The since last import state.
*/
bool sinceLastImportDate() const;
/**
* Get parameters for Export
* @return the parameters
*/
QMap<QString, QString> getExportParameters();
/**
* Set parameters for Export
* @param iParameters the parameters
*/
void setExportParameters(const QMap<QString, QString>& iParameters);
/**
* Get parameters for Import
* @return the parameters
*/
QMap<QString, QString> getImportParameters();
/**
* Set parameters for Import
* @param iParameters the parameters
*/
void setImportParameters(const QMap<QString, QString>& iParameters);
/**
* Get the default value of a parameter
* @param iParameter the parameter
*/
static QString getParameterDefaultValue(const QString& iParameter);
/**
* Get the mime type filter for import
* @param iIncludingAll to include the "All supported format"
* @return the mime type filter
*/
static QString getImportMimeTypeFilter(bool iIncludingAll = true);
/**
* Import the file in the document
* @return an object managing the error.
* @see SKGError
*/
SKGError importFile();
/**
* Get the mime type filter for export
* @param iIncludingAll to include the "All supported format"
* @return the mime type filter
*/
static QString getExportMimeTypeFilter(bool iIncludingAll = true);
/**
* Export the file in the document
* @return an object managing the error.
* @see SKGError
*/
SKGError exportFile();
/**
* Anonymize the document.
* This function must not be launched into a transaction
* @param iKey the key for anonymisation. If "" then the anonymisation is not reversible, else the anonymisation can be undone with the same key.
* @return an object managing the error.
* @see SKGError
*/
SKGError anonymize(const QString& iKey);
/**
* Find and group operations
* @param oNbOperationsMerged returns the number of operations merged.
* @param iAdditionnalCondition a condition on operations to check (eg. A.t_imported='T' AND B.t_imported='T'")
* @return an object managing the error.
* @see SKGError
*/
SKGError findAndGroupTransfers(int& oNbOperationsMerged, const QString& iAdditionnalCondition);
/**
* Find and group operations
* @param oNbOperationsMerged returns the number of operations merged.
* @param iOnCurrentlyImport to apply the grouping only on currently imported operations.
* @return an object managing the error.
* @see SKGError
*/
SKGError findAndGroupTransfers(int& oNbOperationsMerged, bool iOnCurrentlyImport = false);
/**
* Clean operations after an import coming from bank's web sites
* @return an object managing the error.
* @see SKGError
*/
SKGError cleanBankImport();
/**
* Get the document
* @return the document.
*/
inline SKGDocumentBank* getDocument()
{
return m_document;
}
/**
* Get the file name extension
* @return the file name.
*/
QString getFileNameExtension() const;
/**
* Get the file name
* @return the file name.
*/
QUrl getFileName() const;
/**
* Get the local file name
* @param iDownload create the local file by downloading the file.
* @return the local file name.
*/
QString getLocalFileName(bool iDownload = true);
/**
* Return the default account for import
* @param oAccount the default account for import.
* @return an object managing the error.
* @see SKGError
*/
SKGError getDefaultAccount(SKGAccountObject& oAccount);
/**
* Return the preferred unit for a date for import
* @param oUnit the default unit for import.
* @param iDate the date.
* @brief
* If @see setDefaultUnit is used then getDefaultUnit will return this unit.
* else return the unit compatible with entry date and with a value nearest than 1
* else a new unit is created and returned
* @return an object managing the error.
* @see SKGError
*/
SKGError getDefaultUnit(SKGUnitObject& oUnit, const QDate* iDate = nullptr);
/**
* Finalize an import by changing state and applying rules
* @see SKGError
*/
SKGError finalizeImportation();
/**
* Add an account to check during finalization
* @param iAccount the account.
* @param iBalance the balance.
*/
void addAccountToCheck(const SKGAccountObject& iAccount, double iBalance);
/**
* get accounts to check
* @return the accounts and balances to check.
*/
QList<QPair<SKGAccountObject, double>> getAccountsToCheck();
private:
Q_DISABLE_COPY(SKGImportExportManager)
SKGImportPlugin* getImportPlugin();
SKGImportPlugin* getExportPlugin();
SKGDocumentBank* m_document;
QUrl m_fileName;
QString m_localFileName;
SKGAccountObject* m_defaultAccount;
SKGUnitObject* m_defaultUnit;
QString m_codec;
bool m_automaticValidationOfImportedOperation{};
bool m_automaticApplyRulesOfImportedOperation{};
bool m_since_last_import;
SKGImportPlugin* m_importPlugin;
SKGImportPlugin* m_exportPlugin;
QList<QPair<SKGAccountObject, double>> m_AccountToCheck;
};
#endif
diff --git a/skgbankmodeler/skgimportplugin.cpp b/skgbankmodeler/skgimportplugin.cpp
index b50f341b5..a205b67b9 100644
--- a/skgbankmodeler/skgimportplugin.cpp
+++ b/skgbankmodeler/skgimportplugin.cpp
@@ -1,30 +1,30 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is a plugin interface default implementation.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgimportplugin.h"
SKGImportPlugin::SKGImportPlugin(QObject* iImporter)
: KParts::Plugin(iImporter), m_importer(qobject_cast< SKGImportExportManager * >(iImporter))
{}
SKGImportPlugin::~SKGImportPlugin()
= default;
diff --git a/skgbankmodeler/skgimportplugin.h b/skgbankmodeler/skgimportplugin.h
index a035232b3..160e499d2 100644
--- a/skgbankmodeler/skgimportplugin.h
+++ b/skgbankmodeler/skgimportplugin.h
@@ -1,146 +1,146 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGIMPORTPLUGIN_H
#define SKGIMPORTPLUGIN_H
/** @file
* This file is a plugin interface definition.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include <kparts/plugin.h>
#include "skgbankmodeler_export.h"
#include "skgerror.h"
#include "skgimportexportmanager.h"
/**
* This file is a plugin interface definition.
*/
class SKGBANKMODELER_EXPORT SKGImportPlugin : public KParts::Plugin
{
Q_OBJECT
public:
/**
* Default constructor
* @param iImporter the parent importer
*/
explicit SKGImportPlugin(QObject* iImporter = nullptr);
/**
* Default destructor
*/
~SKGImportPlugin() override;
/**
* Get parameters for Import
* @return the parameters
*/
virtual inline QMap<QString, QString> getImportParameters()
{
return m_importParameters;
}
/**
* Set parameters for Import
* @param iParameters the parameters
*/
virtual inline void setImportParameters(const QMap<QString, QString>& iParameters)
{
m_importParameters = iParameters;
}
/**
* Get parameters for Export
* @return the parameters
*/
virtual inline QMap<QString, QString> getExportParameters()
{
return m_exportParameters;
}
/**
* Set parameters for Export
* @param iParameters the parameters
*/
virtual inline void setExportParameters(const QMap<QString, QString>& iParameters)
{
m_exportParameters = iParameters;
}
/**
* To know if import is possible with this plugin
* @return true or false
*/
virtual inline bool isImportPossible()
{
return false;
}
/**
* Import a file
* @return an object managing the error.
* @see SKGError
*/
virtual inline SKGError importFile()
{
return SKGError(ERR_NOTIMPL, QLatin1String(""));
}
/**
* To know if export is possible with this plugin
* @return true or false
*/
virtual inline bool isExportPossible()
{
return false;
}
/**
* Export a file
* @return an object managing the error.
* @see SKGError
*/
virtual inline SKGError exportFile()
{
return SKGError(ERR_NOTIMPL, QLatin1String(""));
}
/**
* Return the mime type filter
* @return the mime type filter. Example: "*.csv|CSV file"
*/
virtual QString getMimeTypeFilter() const
{
return QLatin1String("");
}
private:
Q_DISABLE_COPY(SKGImportPlugin)
protected:
SKGImportExportManager* m_importer;
QMap<QString, QString> m_importParameters;
QMap<QString, QString> m_exportParameters;
};
/**
* This plugin interface definition.
*/
Q_DECLARE_INTERFACE(SKGImportPlugin, "skrooge.com.SKGImportPlugin/1.0")
#endif // SKGIMPORTPLUGIN_H
diff --git a/skgbankmodeler/skginterestobject.cpp b/skgbankmodeler/skginterestobject.cpp
index b98389b7f..7d68a1ca0 100644
--- a/skgbankmodeler/skginterestobject.cpp
+++ b/skgbankmodeler/skginterestobject.cpp
@@ -1,132 +1,132 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file defines classes SKGInterestObject.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skginterestobject.h"
#include "skgdocument.h"
SKGInterestObject::SKGInterestObject(): SKGInterestObject(nullptr)
{}
SKGInterestObject::SKGInterestObject(SKGDocument* iDocument, int iID): SKGObjectBase(iDocument, QStringLiteral("v_interest"), iID)
{}
SKGInterestObject::SKGInterestObject(const SKGInterestObject& iObject)
= default;
SKGInterestObject::SKGInterestObject(const SKGObjectBase& iObject)
{
if (iObject.getRealTable() == QStringLiteral("interest")) {
copyFrom(iObject);
} else {
*this = SKGObjectBase(iObject.getDocument(), QStringLiteral("v_interest"), iObject.getID());
}
}
SKGInterestObject& SKGInterestObject::operator= (const SKGObjectBase& iObject)
{
copyFrom(iObject);
return *this;
}
SKGInterestObject::~SKGInterestObject()
= default;
SKGError SKGInterestObject::setRate(double iValue)
{
return setAttribute(QStringLiteral("f_rate"), SKGServices::doubleToString(iValue));
}
double SKGInterestObject::getRate() const
{
return SKGServices::stringToDouble(getAttribute(QStringLiteral("f_rate")));
}
SKGError SKGInterestObject::setDate(QDate iDate)
{
return setAttribute(QStringLiteral("d_date"), SKGServices::dateToSqlString(QDateTime(iDate)));
}
QDate SKGInterestObject::getDate() const
{
return SKGServices::stringToTime(getAttribute(QStringLiteral("d_date"))).date();
}
SKGError SKGInterestObject::setIncomeValueDateMode(SKGInterestObject::ValueDateMode iMode)
{
return setAttribute(QStringLiteral("t_income_value_date_mode"), (iMode == FIFTEEN ? QStringLiteral("F") : SKGServices::intToString(static_cast<int>(iMode) - 1)));
}
SKGInterestObject::ValueDateMode SKGInterestObject::getIncomeValueDateMode() const
{
QString mode = getAttribute(QStringLiteral("t_income_value_date_mode"));
return (mode == QStringLiteral("F") ? FIFTEEN : static_cast<SKGInterestObject::ValueDateMode>(SKGServices::stringToInt(mode) + 1));
}
SKGError SKGInterestObject::setExpenditueValueDateMode(SKGInterestObject::ValueDateMode iMode)
{
return setAttribute(QStringLiteral("t_expenditure_value_date_mode"), (iMode == FIFTEEN ? QStringLiteral("F") : SKGServices::intToString(static_cast<int>(iMode) - 1)));
}
SKGInterestObject::ValueDateMode SKGInterestObject::getExpenditueValueDateMode() const
{
QString mode = getAttribute(QStringLiteral("t_expenditure_value_date_mode"));
return (mode == QStringLiteral("F") ? FIFTEEN : static_cast<SKGInterestObject::ValueDateMode>(SKGServices::stringToInt(mode) + 1));
}
SKGError SKGInterestObject::setInterestComputationMode(SKGInterestObject::InterestMode iMode)
{
return setAttribute(QStringLiteral("t_base"),
(iMode == FIFTEEN24 ? QStringLiteral("24") :
(iMode == DAYS360 ? QStringLiteral("360") :
QStringLiteral("365"))));
}
SKGInterestObject::InterestMode SKGInterestObject::getInterestComputationMode() const
{
QString mode = getAttribute(QStringLiteral("t_base"));
return (mode == QStringLiteral("24") ? FIFTEEN24 : (mode == QStringLiteral("360") ? DAYS360 : DAYS365));
}
QString SKGInterestObject::getWhereclauseId() const
{
// Could we use the id
QString output = SKGObjectBase::getWhereclauseId();
if (output.isEmpty()) {
// No, so we use the date and parent
if (!(getAttribute(QStringLiteral("d_date")).isEmpty()) && !(getAttribute(QStringLiteral("rd_account_id")).isEmpty())) {
output = "d_date='" % getAttribute(QStringLiteral("d_date")) % "' AND rd_account_id=" % getAttribute(QStringLiteral("rd_account_id"));
}
}
return output;
}
SKGError SKGInterestObject::setAccount(const SKGAccountObject& iAccount)
{
return setAttribute(QStringLiteral("rd_account_id"), SKGServices::intToString(iAccount.getID()));
}
SKGError SKGInterestObject::getAccount(SKGAccountObject& oAccount) const
{
SKGError err = getDocument()->getObject(QStringLiteral("v_account"), "id=" % getAttribute(QStringLiteral("rd_account_id")), oAccount);
return err;
}
diff --git a/skgbankmodeler/skginterestobject.h b/skgbankmodeler/skginterestobject.h
index 17aa0c382..fe9d2468c 100644
--- a/skgbankmodeler/skginterestobject.h
+++ b/skgbankmodeler/skginterestobject.h
@@ -1,201 +1,201 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGINTERESTOBJECT_H
#define SKGINTERESTOBJECT_H
/** @file
* This file defines classes SKGInterestObject.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgaccountobject.h"
#include "skgbankmodeler_export.h"
#include "skgerror.h"
#include "skgobjectbase.h"
class SKGInterestObject;
/**
* This class is interest option for an account
*/
class SKGBANKMODELER_EXPORT SKGInterestObject final : public SKGObjectBase
{
Q_OBJECT
public:
/**
* This enumerate defines how to compute value date
*/
enum ValueDateMode {FIFTEEN = 0,
J0,
J1,
J2,
J3,
J4,
J5
};
/**
* This enumerate defines how to compute value date
*/
Q_ENUM(ValueDateMode)
/**
* This enumerate defines how to compute interest
*/
enum InterestMode {FIFTEEN24 = 0,
DAYS360,
DAYS365
};
/**
* This enumerate defines how to compute interest
*/
Q_ENUM(InterestMode)
/**
* Default constructor
*/
explicit SKGInterestObject();
/**
* Constructor
* @param iDocument the document containing the object
* @param iID the identifier in @p iTable of the object
*/
explicit SKGInterestObject(SKGDocument* iDocument, int iID = 0);
/**
* Copy constructor
* @param iObject the object to copy
*/
SKGInterestObject(const SKGInterestObject& iObject);
/**
* Copy constructor
* @param iObject the object to copy
*/
explicit SKGInterestObject(const SKGObjectBase& iObject);
/**
* Operator affectation
* @param iObject the object to copy
*/
SKGInterestObject& operator= (const SKGObjectBase& iObject);
/**
* Destructor
*/
~SKGInterestObject() override;
/**
* Get the parent account
* @param oAccount the parent account
* @return an object managing the error
* @see SKGError
*/
SKGError getAccount(SKGAccountObject& oAccount) const;
/**
* Set the parent account
* @param iAccount the parent account
* @return an object managing the error
* @see SKGError
*/
SKGError setAccount(const SKGAccountObject& iAccount);
/**
* Set the quantity for the date of this unit
* @param iValue the quantity
* @return an object managing the error
* @see SKGError
*/
SKGError setRate(double iValue);
/**
* Get the quantity for the date of this unit
* @return the quantity
*/
double getRate() const;
/**
* Set date of this value
* @param iDate the date
* @return an object managing the error
* @see SKGError
*/
// cppcheck-suppress passedByValue
SKGError setDate(QDate iDate);
/**
* Get date of this value
* @return the date
*/
QDate getDate() const;
/**
* Set income value date mode
* @param iMode the mode
* @return an object managing the error
* @see SKGError
*/
SKGError setIncomeValueDateMode(SKGInterestObject::ValueDateMode iMode);
/**
* Get income value date mode
* @return the income value date mode
*/
SKGInterestObject::ValueDateMode getIncomeValueDateMode() const;
/**
* Set expenditue value date mode
* @param iMode the mode
* @return an object managing the error
* @see SKGError
*/
SKGError setExpenditueValueDateMode(SKGInterestObject::ValueDateMode iMode);
/**
* Get expenditue value date mode
* @return the expenditue value date mode
*/
SKGInterestObject::ValueDateMode getExpenditueValueDateMode() const;
/**
* Set interest computation mode
* @param iMode the mode
* @return an object managing the error
* @see SKGError
*/
SKGError setInterestComputationMode(SKGInterestObject::InterestMode iMode);
/**
* Get interest computation mode
* @return the interest computation mode
*/
SKGInterestObject::InterestMode getInterestComputationMode() const;
protected:
/**
* Get where clause needed to identify objects.
* For this class, the whereclause is based on date + unit
* @return the where clause
*/
QString getWhereclauseId() const override;
};
/**
* Declare the class
*/
Q_DECLARE_TYPEINFO(SKGInterestObject, Q_MOVABLE_TYPE);
#endif
diff --git a/skgbankmodeler/skgoperationobject.cpp b/skgbankmodeler/skgoperationobject.cpp
index 3e9a24dc3..1e8a91106 100644
--- a/skgbankmodeler/skgoperationobject.cpp
+++ b/skgbankmodeler/skgoperationobject.cpp
@@ -1,577 +1,577 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file implements classes SKGOperationObject.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgoperationobject.h"
#include <klocalizedstring.h>
#include "skgaccountobject.h"
#include "skgdocument.h"
#include "skgpayeeobject.h"
#include "skgrecurrentoperationobject.h"
#include "skgservices.h"
#include "skgsuboperationobject.h"
#include "skgtraces.h"
#include "skgunitobject.h"
SKGOperationObject::SKGOperationObject() : SKGOperationObject(nullptr)
{}
SKGOperationObject::SKGOperationObject(SKGDocument* iDocument, int iID) : SKGObjectBase(iDocument, QStringLiteral("v_operation"), iID)
{}
SKGOperationObject::~SKGOperationObject()
= default;
SKGOperationObject::SKGOperationObject(const SKGOperationObject& iObject)
= default;
SKGOperationObject::SKGOperationObject(const SKGObjectBase& iObject)
{
if (iObject.getRealTable() == QStringLiteral("operation")) {
copyFrom(iObject);
} else {
*this = SKGObjectBase(iObject.getDocument(), QStringLiteral("v_operation"), iObject.getID());
}
}
SKGOperationObject& SKGOperationObject::operator= (const SKGObjectBase& iObject)
{
copyFrom(iObject);
return *this;
}
SKGError SKGOperationObject::duplicate(SKGOperationObject& oOperation, QDate iDate, bool iTemplateMode) const
{
SKGError err;
SKGTRACEINFUNCRC(20, err)
QDate previousDate = getDate();
// Create the duplicated operation
oOperation = SKGOperationObject(getDocument(), this->getID()); // To be sure the object is on v_operation
IFOKDO(err, oOperation.load())
IFOKDO(err, oOperation.resetID())
IFOKDO(err, oOperation.setDate(iDate))
IFOKDO(err, oOperation.setStatus(SKGOperationObject::NONE))
IFOKDO(err, oOperation.setImported(false))
IFOKDO(err, oOperation.setTemplate(iTemplateMode))
IFOKDO(err, oOperation.setImportID(QLatin1String("")))
IFOKDO(err, oOperation.bookmark(false))
IFOKDO(err, oOperation.setNumber(QLatin1String("")))
IFOKDO(err, oOperation.setGroupOperation(oOperation))
IFOKDO(err, oOperation.setAttribute(QStringLiteral("d_createdate"), SKGServices::dateToSqlString(QDateTime::currentDateTime())))
IFOKDO(err, oOperation.save(false, false))
// Duplicate subop
IFOK(err) {
SKGListSKGObjectBase subops;
err = getSubOperations(subops);
int nbsupops = subops.count();
for (int i = 0; !err && i < nbsupops; ++i) {
SKGSubOperationObject subop(subops.at(i));
err = subop.resetID();
IFOKDO(err, subop.setParentOperation(oOperation))
IFOKDO(err, subop.setDate(subop.getDate().addDays(previousDate.daysTo(iDate))))
IFOKDO(err, subop.save(false))
}
}
// Duplicate grouped operation to support recurrent transfers
IFOK(err) {
SKGListSKGObjectBase goupops;
err = getGroupedOperations(goupops);
int nbgoupops = goupops.count();
for (int i = 0; !err && i < nbgoupops; ++i) {
SKGOperationObject groupop(goupops.at(i));
if (groupop != *this) {
// Create the duplicated operation
SKGOperationObject newgroupop = groupop;
err = newgroupop.resetID();
IFOKDO(err, newgroupop.setDate(iDate))
IFOKDO(err, newgroupop.setStatus(SKGOperationObject::NONE))
IFOKDO(err, newgroupop.setImported(false))
IFOKDO(err, newgroupop.setTemplate(iTemplateMode))
IFOKDO(err, newgroupop.setImportID(QLatin1String("")))
IFOKDO(err, newgroupop.bookmark(false))
IFOKDO(err, newgroupop.setNumber(QLatin1String("")))
IFOKDO(err, newgroupop.setGroupOperation(newgroupop))
IFOKDO(err, newgroupop.setGroupOperation(oOperation))
IFOKDO(err, newgroupop.save(false))
// Duplicate subop
IFOK(err) {
SKGListSKGObjectBase subops;
err = groupop.getSubOperations(subops);
int nbsupops = subops.count();
for (int j = 0; !err && j < nbsupops; ++j) {
SKGSubOperationObject subop(subops.at(j));
err = subop.resetID();
IFOKDO(err, subop.setParentOperation(newgroupop))
IFOKDO(err, subop.setDate(subop.getDate().addDays(previousDate.daysTo(iDate))))
IFOKDO(err, subop.save(false))
}
}
}
}
}
IFOKDO(err, oOperation.load())
return err;
}
SKGError SKGOperationObject::getParentAccount(SKGAccountObject& oAccount) const
{
SKGObjectBase objTmp;
SKGError err = getDocument()->getObject(QStringLiteral("v_account"), "id=" % getAttribute(QStringLiteral("rd_account_id")), objTmp);
oAccount = objTmp;
return err;
}
SKGError SKGOperationObject::setParentAccount(const SKGAccountObject& iAccount, bool iForce)
{
SKGError err;
QString currentAccount = getAttribute(QStringLiteral("rd_account_id"));
QString newAccount = SKGServices::intToString(iAccount.getID());
if (newAccount == QStringLiteral("0")) {
err = SKGError(ERR_FAIL, i18nc("Error message", "%1 failed because linked object is not yet saved in the database.", QStringLiteral("SKGOperationObject::setParentAccount")));
} else {
if (newAccount != currentAccount) {
if (iAccount.isClosed() && !iForce) {
err = SKGError(ERR_FAIL, i18nc("Error message", "Impossible to add an operation in a closed account"));
} else {
err = setAttribute(QStringLiteral("rd_account_id"), newAccount);
}
}
}
return err;
}
SKGError SKGOperationObject::setMode(const QString& iMode)
{
return setAttribute(QStringLiteral("t_mode"), iMode);
}
QString SKGOperationObject::getMode() const
{
return getAttribute(QStringLiteral("t_mode"));
}
SKGError SKGOperationObject::setPayee(const SKGPayeeObject& iPayee)
{
return setAttribute(QStringLiteral("r_payee_id"), SKGServices::intToString(iPayee.getID()));
}
SKGError SKGOperationObject::getPayee(SKGPayeeObject& oPayee) const
{
SKGError err = getDocument()->getObject(QStringLiteral("v_payee"), "id=" % SKGServices::intToString(SKGServices::stringToInt(getAttribute(QStringLiteral("r_payee_id")))), oPayee);
return err;
}
SKGError SKGOperationObject::setComment(const QString& iComment)
{
return setAttribute(QStringLiteral("t_comment"), iComment);
}
QString SKGOperationObject::getComment() const
{
return getAttribute(QStringLiteral("t_comment"));
}
SKGError SKGOperationObject::setNumber(const QString& iNumber)
{
return setAttribute(QStringLiteral("t_number"), iNumber);
}
QString SKGOperationObject::getNumber() const
{
return getAttribute(QStringLiteral("t_number"));
}
SKGOperationObject::OperationStatus SKGOperationObject::getStatus() const
{
QString t_status = getAttribute(QStringLiteral("t_status"));
if (t_status == QStringLiteral("Y")) {
return SKGOperationObject::CHECKED;
}
if (t_status == QStringLiteral("P")) {
return SKGOperationObject::POINTED;
}
return SKGOperationObject::NONE;
}
SKGError SKGOperationObject::setStatus(SKGOperationObject::OperationStatus iStatus)
{
return setAttribute(QStringLiteral("t_status"), (iStatus == SKGOperationObject::CHECKED ? QStringLiteral("Y") : (iStatus == SKGOperationObject::POINTED ? QStringLiteral("P") : QStringLiteral("N"))));
}
SKGError SKGOperationObject::setDate(QDate iDate, bool iRefreshSubOperations)
{
SKGError err;
// Compute delta of the change of date
QDate previousDate = getDate();
if (iRefreshSubOperations) {
// Apply the delta on sub operations
SKGObjectBase::SKGListSKGObjectBase listSubOperations;
getSubOperations(listSubOperations); // Error is not manage to avoid error in case of first creation
int nbSubOperations = listSubOperations.count();
for (int i = 0; !err && i < nbSubOperations; ++i) {
SKGSubOperationObject sop(listSubOperations.at(i));
QDate previousSubDate = sop.getDate();
if (previousSubDate.isValid()) {
if (previousDate.isValid()) {
int delta = previousDate.daysTo(iDate);
err = sop.setDate(previousSubDate.addDays(delta));
IFOKDO(err, sop.save(true, false))
}
} else {
err = sop.setDate(iDate);
IFOKDO(err, sop.save(true, false))
}
}
}
IFOKDO(err, setAttribute(QStringLiteral("d_date"), SKGServices::dateToSqlString(QDateTime(iDate))))
return err;
}
QDate SKGOperationObject::getDate() const
{
return SKGServices::stringToTime(getAttribute(QStringLiteral("d_date"))).date();
}
SKGError SKGOperationObject::getUnit(SKGUnitObject& oUnit) const
{
SKGError err = (getDocument() == nullptr ? SKGError(ERR_POINTER, i18nc("Error message", "Operation impossible because the document is missing")) : getDocument()->getObject(QStringLiteral("v_unit"), "id=" % getAttribute(QStringLiteral("rc_unit_id")), oUnit));
// SKGError err = getDocument()->getObject(QStringLiteral("v_unit"), "id=" % getAttribute(QStringLiteral("rc_unit_id")), oUnit);
return err;
}
SKGError SKGOperationObject::setUnit(const SKGUnitObject& iUnit)
{
return setAttribute(QStringLiteral("rc_unit_id"), SKGServices::intToString(iUnit.getID()));
}
bool SKGOperationObject::isInGroup() const
{
return (getAttribute(QStringLiteral("i_group_id")) != QStringLiteral("0"));
}
bool SKGOperationObject::isTransfer(SKGOperationObject& oOperation) const
{
SKGTRACEINFUNC(10)
SKGObjectBase::SKGListSKGObjectBase ops;
getGroupedOperations(ops);
if (ops.count() == 2) {
oOperation = (*this == SKGOperationObject(ops.at(0)) ? ops.at(1) : ops.at(0));
}
return (getAttribute(QStringLiteral("t_TRANSFER")) == QStringLiteral("Y"));
}
SKGError SKGOperationObject::getGroupedOperations(SKGListSKGObjectBase& oGroupedOperations) const
{
SKGError err;
QString gpId1 = getAttribute(QStringLiteral("i_group_id"));
if (gpId1 == QStringLiteral("0") || gpId1.isEmpty()) {
oGroupedOperations.clear();
} else {
err = getDocument()->getObjects(QStringLiteral("v_operation"), "i_group_id=" % gpId1, oGroupedOperations);
}
return err;
}
SKGError SKGOperationObject::getGroupOperation(SKGOperationObject& oOperation) const
{
SKGError err = getDocument()->getObject(QStringLiteral("v_operation"), "id=" % getAttribute(QStringLiteral("i_group_id")), oOperation);
return err;
}
SKGError SKGOperationObject::setGroupOperation(const SKGOperationObject& iOperation)
{
SKGError err;
SKGTRACEINFUNCRC(20, err)
// Is it a remove group ?
if (iOperation == *this) {
// Yes
err = setAttribute(QStringLiteral("i_group_id"), QStringLiteral("0"));
} else {
// Get previous groups
QString group1 = getAttribute(QStringLiteral("i_group_id"));
QString group2 = iOperation.getAttribute(QStringLiteral("i_group_id"));
// Create a new group
SKGStringListList result;
err = getDocument()->executeSelectSqliteOrder(QStringLiteral("SELECT max(i_group_id) from operation"), result);
IFOK(err) {
// Compute new group id
QString newIdGroup('1');
if (result.count() == 2) {
newIdGroup = SKGServices::intToString(SKGServices::stringToInt(result.at(1).at(0)) + 1);
}
// Set group id
SKGOperationObject op1 = SKGOperationObject(iOperation.getDocument(), iOperation.getID());
err = op1.setAttribute(QStringLiteral("i_group_id"), newIdGroup);
IFOKDO(err, op1.save(true, false))
IFOKDO(err, setAttribute(QStringLiteral("i_group_id"), newIdGroup))
// Update all objects of group2
if (!err && !group1.isEmpty() && group1 != QStringLiteral("0")) {
err = getDocument()->executeSqliteOrder("UPDATE operation SET i_group_id=" % newIdGroup % " WHERE i_group_id=" % group1);
}
// Update all objects of group2
if (!err && !group2.isEmpty() && group2 != QStringLiteral("0")) {
err = getDocument()->executeSqliteOrder("UPDATE operation SET i_group_id=" % newIdGroup % " WHERE i_group_id=" % group2);
}
}
}
return err;
}
SKGError SKGOperationObject::bookmark(bool iBookmark)
{
return setAttribute(QStringLiteral("t_bookmarked"), iBookmark ? QStringLiteral("Y") : QStringLiteral("N"));
}
bool SKGOperationObject::isBookmarked() const
{
return (getAttribute(QStringLiteral("t_bookmarked")) == QStringLiteral("Y"));
}
SKGError SKGOperationObject::setImported(bool iImported)
{
return setAttribute(QStringLiteral("t_imported"), iImported ? QStringLiteral("Y") : QStringLiteral("N"));
}
bool SKGOperationObject::isImported() const
{
return (getAttribute(QStringLiteral("t_imported")) != QStringLiteral("N"));
}
SKGError SKGOperationObject::setImportID(const QString& iImportID)
{
SKGError err = setAttribute(QStringLiteral("t_import_id"), iImportID);
if (!err && !iImportID.isEmpty()) {
err = setAttribute(QStringLiteral("t_imported"), QStringLiteral("T"));
}
return err;
}
QString SKGOperationObject::getImportID() const
{
return getAttribute(QStringLiteral("t_import_id"));
}
SKGError SKGOperationObject::setTemplate(bool iTemplate)
{
return setAttribute(QStringLiteral("t_template"), iTemplate ? QStringLiteral("Y") : QStringLiteral("N"));
}
bool SKGOperationObject::isTemplate() const
{
return (getAttribute(QStringLiteral("t_template")) != QStringLiteral("N"));
}
int SKGOperationObject::getNbSubOperations() const
{
return SKGServices::stringToInt(getAttribute(QStringLiteral("i_NBSUBOPERATIONS")));
}
SKGError SKGOperationObject::addSubOperation(SKGSubOperationObject& oSubOperation)
{
SKGError err;
if (getID() == 0) {
err = SKGError(ERR_FAIL, i18nc("Error message", "%1 failed because linked object is not yet saved in the database.", QStringLiteral("SKGOperationObject::addSubOperation")));
} else {
oSubOperation = SKGSubOperationObject(getDocument());
err = oSubOperation.setParentOperation(*this);
IFOKDO(err, oSubOperation.setDate(getDate()))
}
return err;
}
SKGError SKGOperationObject::getSubOperations(SKGListSKGObjectBase& oSubOperations) const
{
SKGError err;
if (getID() == 0) {
err = SKGError(ERR_FAIL, i18nc("Error message", "%1 failed because linked object is not yet saved in the database.", QStringLiteral("SKGOperationObject::getSubOperations")));
} else {
err = getDocument()->getObjects(QStringLiteral("v_suboperation"),
"rd_operation_id=" % SKGServices::intToString(getID()) % " ORDER BY i_order", oSubOperations);
}
return err;
}
double SKGOperationObject::getCurrentAmount() const
{
return SKGServices::stringToDouble(getAttribute(QStringLiteral("f_CURRENTAMOUNT")));
}
double SKGOperationObject::getBalance() const
{
double output = 0.0;
SKGStringListList result;
SKGError err = getDocument()->executeSelectSqliteOrder("SELECT TOTAL(f_CURRENTAMOUNT) FROM v_operation WHERE t_template='N' AND "
"rd_account_id=" % getAttribute(QStringLiteral("rd_account_id")) % " AND (d_date<'" % getAttribute(QStringLiteral("d_date")) % "' OR "
"(d_date='" % getAttribute(QStringLiteral("d_date")) % "' AND id<=" % SKGServices::intToString(getID()) % "))", result);
IFOK(err) {
output = SKGServices::stringToDouble(result.at(1).at(0));
}
return output;
}
double SKGOperationObject::getAmount(QDate iDate) const
{
// Get quantity
double quantity = SKGServices::stringToDouble(getAttribute(QStringLiteral("f_QUANTITY")));
// Is the unit value already in cache ?
double coef = 1;
QString val = getDocument()->getCachedValue("unitvalue-" % getAttribute(QStringLiteral("rc_unit_id")));
if (!val.isEmpty()) {
// Yes
coef = SKGServices::stringToDouble(val);
} else {
// No
SKGUnitObject unit;
if (getUnit(unit).isSucceeded()) {
coef = unit.getAmount(iDate);
}
}
return coef * quantity;
}
SKGError SKGOperationObject::addRecurrentOperation(SKGRecurrentOperationObject& oRecurrentOperation) const
{
SKGError err;
if (getID() == 0) {
err = SKGError(ERR_FAIL, i18nc("Error message", "%1 failed because linked object is not yet saved in the database.", QStringLiteral("SKGOperationObject::addRecurrentOperation")));
} else {
oRecurrentOperation = SKGRecurrentOperationObject(getDocument());
err = oRecurrentOperation.setParentOperation(*this);
IFOK(err) oRecurrentOperation.setDate(getDate());
}
return err;
}
SKGError SKGOperationObject::getRecurrentOperations(SKGListSKGObjectBase& oRecurrentOperation) const
{
SKGError err;
if (getID() == 0) {
err = SKGError(ERR_FAIL, i18nc("Error message", "%1 failed because linked object is not yet saved in the database.", QStringLiteral("SKGOperationObject::getRecurrentOperation")));
} else {
err = getDocument()->getObjects(QStringLiteral("v_recurrentoperation"),
"rd_operation_id=" % SKGServices::intToString(getID()), oRecurrentOperation);
}
return err;
}
SKGError SKGOperationObject::mergeAttribute(const SKGOperationObject& iDeletedOne, SKGOperationObject::AmountAlignmentMode iMode, bool iSendMessage)
{
// Merge operation
SKGError err = setDate(iDeletedOne.getDate());
IFOKDO(err, setImportID(iDeletedOne.getImportID()))
IFOKDO(err, setAttribute(QStringLiteral("t_imported"), iDeletedOne.getAttribute(QStringLiteral("t_imported"))))
if (!err && getComment().isEmpty()) {
err = setComment(iDeletedOne.getComment());
}
SKGPayeeObject payee;
getPayee(payee);
IFOKDO(err, setPayee(payee))
if (!err && getMode().isEmpty()) {
err = setMode(iDeletedOne.getMode());
}
if (!err && !isBookmarked()) {
err = bookmark(iDeletedOne.isBookmarked());
}
IFOKDO(err, setNumber(iDeletedOne.getNumber()))
IFOKDO(err, save())
// Merge suboperations
double currentAmount = getCurrentAmount();
double targettAmount = iDeletedOne.getCurrentAmount();
if (qAbs(currentAmount - targettAmount) > 0.0001) {
SKGObjectBase::SKGListSKGObjectBase subOps1;
IFOKDO(err, getSubOperations(subOps1))
SKGObjectBase::SKGListSKGObjectBase subOps2;
IFOKDO(err, iDeletedOne.getSubOperations(subOps2))
// Align amounts
SKGOperationObject::AmountAlignmentMode mode = iMode;
if (mode == DEFAULT) {
if (subOps2.count() == 1 && subOps1.count() == 1) {
mode = PROPORTIONAL;
} else if (subOps2.count() >= 1 && subOps1.count() >= 1) {
mode = ADDSUBOPERATION;
}
}
if (mode == SKGOperationObject::ADDSUBOPERATION) {
// Add sub operation to align amount
SKGSubOperationObject so1;
IFOKDO(err, addSubOperation(so1))
IFOKDO(err, so1.setQuantity(targettAmount - currentAmount))
IFOKDO(err, so1.save())
} else {
// Keep ratio
for (const auto& sopbase : qAsConst(subOps1)) {
SKGSubOperationObject sop(sopbase);
IFOKDO(err, sop.setQuantity(targettAmount * sop.getQuantity() / currentAmount))
IFOKDO(err, sop.save())
}
}
IFOKDO(err, load())
if (iSendMessage) {
IFOK(err) getDocument()->sendMessage(i18nc("An information message", "Amount has been changed to be aligned with the imported operation"), SKGDocument::Positive);
}
}
// transfers properties
IFOKDO(err, getDocument()->executeSqliteOrder(QStringLiteral("UPDATE parameters SET t_uuid_parent='") % getUniqueID() % QStringLiteral("' WHERE t_uuid_parent='") % iDeletedOne.getUniqueID() % QStringLiteral("'")))
// Delete useless operation
IFOKDO(err, iDeletedOne.remove(false, true))
return err;
}
SKGError SKGOperationObject::mergeSuboperations(const SKGOperationObject& iDeletedOne)
{
SKGError err;
SKGObjectBase::SKGListSKGObjectBase subops;
err = iDeletedOne.getSubOperations(subops);
int nb = subops.count();
for (int i = 0; !err && i < nb; ++i) {
SKGSubOperationObject subop(subops.at(i));
err = subop.setParentOperation(*this);
IFOKDO(err, subop.save())
}
IFOKDO(err, iDeletedOne.remove(false))
return err;
}
diff --git a/skgbankmodeler/skgoperationobject.h b/skgbankmodeler/skgoperationobject.h
index 48430c7f2..7bad36756 100644
--- a/skgbankmodeler/skgoperationobject.h
+++ b/skgbankmodeler/skgoperationobject.h
@@ -1,409 +1,409 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGOPERATIONOBJECT_H
#define SKGOPERATIONOBJECT_H
/** @file
* This file defines classes SKGOperationObject.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgbankmodeler_export.h"
#include "skgobjectbase.h"
class SKGAccountObject;
class SKGUnitObject;
class SKGSubOperationObject;
class SKGRecurrentOperationObject;
class SKGPayeeObject;
/**
* This class manages operation object
*/
class SKGBANKMODELER_EXPORT SKGOperationObject final : public SKGObjectBase
{
Q_OBJECT
public:
/**
* This enumerate defines status for operations
*/
enum OperationStatus {NONE, /**< no status */
POINTED, /**< pointed */
CHECKED /**< checked */
};
/**
* This enumerate defines status for operations
*/
Q_ENUM(OperationStatus)
/**
* This enumerate defines the alignment amount mode
*/
enum AmountAlignmentMode {
DEFAULT, /**< Default */
PROPORTIONAL, /**< Proportional */
ADDSUBOPERATION /**< Add sub operation */
};
/**
* This enumerate defines the alignment amount mode
*/
Q_ENUM(AmountAlignmentMode)
/**
* Default constructor
*/
explicit SKGOperationObject();
/**
* Constructor
* @param iDocument the document containing the object
* @param iID the identifier in @p iTable of the object
*/
explicit SKGOperationObject(SKGDocument* iDocument, int iID = 0);
/**
* Copy constructor
* @param iObject the object to copy
*/
explicit SKGOperationObject(const SKGObjectBase& iObject);
/**
* Copy constructor
* @param iObject the object to copy
*/
SKGOperationObject(const SKGOperationObject& iObject);
/**
* Operator affectation
* @param iObject the object to copy
*/
SKGOperationObject& operator= (const SKGObjectBase& iObject);
/**
* Destructor
*/
~SKGOperationObject() override;
/**
* Duplicate current operation including suboperations and grouped operations
* @param oOperation the created operation
* @param iDate date(s) for new operation(s)
* @param iTemplateMode the template mode for new operation(s)
* @return an object managing the error.
* @see SKGError
*/
// cppcheck-suppress passedByValue
SKGError duplicate(SKGOperationObject& oOperation, QDate iDate = QDate::currentDate(), bool iTemplateMode = false) const;
/**
* Get the parent account
* @param oAccount the parent account
* @return an object managing the error.
* @see SKGError
*/
SKGError getParentAccount(SKGAccountObject& oAccount) const;
/**
* Set the parent account
* @param iAccount the parent account
* @param iForce force the creation even if the account is closed
* @return an object managing the error.
* @see SKGError
*/
SKGError setParentAccount(const SKGAccountObject& iAccount, bool iForce = false);
/**
* Set the mode of operation
* @param iNumber the number
* @return an object managing the error
* @see SKGError
*/
SKGError setNumber(const QString& iNumber);
/**
* Get the number of this operation
* @return the number
*/
QString getNumber() const;
/**
* Set the mode of operation
* @param iMode the mode
* @return an object managing the error
* @see SKGError
*/
SKGError setMode(const QString& iMode);
/**
* Get the mode of this operation
* @return the mode
*/
QString getMode() const;
/**
* Set the payee of operation
* @param iPayee the payee
* @return an object managing the error
* @see SKGError
*/
SKGError setPayee(const SKGPayeeObject& iPayee);
/**
* Get the payee of this operation
* @param oPayee the payee
* @return an object managing the error
* @see SKGError
*/
SKGError getPayee(SKGPayeeObject& oPayee) const;
/**
* Set the comment of operation
* @param iComment the comment
* @return an object managing the error
* @see SKGError
*/
SKGError setComment(const QString& iComment);
/**
* Get the comment of this operation
* @return the comment
*/
QString getComment() const;
/**
* Get the status of this operation
* @return the status
*/
SKGOperationObject::OperationStatus getStatus() const;
/**
* Set the status of operation
* @param iStatus the status
* @return an object managing the error
* @see SKGError
*/
SKGError setStatus(SKGOperationObject::OperationStatus iStatus);
/**
* Set date of this operation
* @param iDate the date
* @param iRefreshSubOperations to refresh the sub operations
* @return an object managing the error
* @see SKGError
*/
// cppcheck-suppress passedByValue
SKGError setDate(QDate iDate, bool iRefreshSubOperations = true);
/**
* Get date of this operation
* @return the date
*/
QDate getDate() const;
/**
* Set the unit
* @param iUnit the unit
* @return an object managing the error
* @see SKGError
*/
SKGError setUnit(const SKGUnitObject& iUnit);
/**
* Get the unit
* @param oUnit the unit
* @return an object managing the error
* @see SKGError
*/
SKGError getUnit(SKGUnitObject& oUnit) const;
/**
* To know if an operation is grouped
* @return true or false
*/
bool isInGroup() const;
/**
* To know if the current operation is a transfer of the other one
* @param oOperation the other operation
* @return true or false
*/
bool isTransfer(SKGOperationObject& oOperation) const;
/**
* Set the group operation
* @param iOperation the operation (itself to remove from group)
* @return an object managing the error
* @see SKGError
*/
SKGError setGroupOperation(const SKGOperationObject& iOperation);
/**
* Get the group operation
* @param oOperation the operation
* @return an object managing the error
* @see SKGError
*/
SKGError getGroupOperation(SKGOperationObject& oOperation) const;
/**
* Get all operations in the same group
* @param oGroupedOperations all operation in the same group
* @return an object managing the error
* @see SKGError
*/
SKGError getGroupedOperations(SKGListSKGObjectBase& oGroupedOperations) const;
/**
* To bookmark or not an operation
* @param iBookmark the bookmark: true or false
* @return an object managing the error
* @see SKGError
*/
SKGError bookmark(bool iBookmark);
/**
* To know if the operation is bookmarked
* @return an object managing the error
* @see SKGError
*/
bool isBookmarked() const;
/**
* To set the imported attribute of an operation
* @param iImported the imported status: true or false
* @return an object managing the error
* @see SKGError
*/
SKGError setImported(bool iImported);
/**
* To know if the operation has been imported or not
* @return an object managing the error
* @see SKGError
*/
bool isImported() const;
/**
* Set the import identifier of operation, t_imported is set to 'T'
* @param iImportID the import identifier (it is used to check if the operation is already imported)
* @return an object managing the error
* @see SKGError
*/
SKGError setImportID(const QString& iImportID);
/**
* Get the import identifier of operation
* @return the comment
*/
QString getImportID() const;
/**
* To set the template attribute of an operation
* @param iTemplate the template status: true or false
* @return an object managing the error
* @see SKGError
*/
SKGError setTemplate(bool iTemplate);
/**
* To know if the operation is a template or not
* @return an object managing the error
* @see SKGError
*/
bool isTemplate() const;
/**
* Add a new suboperation to this operation
* @param oSubOperation the created suboperation
* @return an object managing the error
* @see SKGError
*/
SKGError addSubOperation(SKGSubOperationObject& oSubOperation);
/**
* Get the number of sub operations
* @return number of sub operations
*/
int getNbSubOperations() const;
/**
* Get all suboperations of this operation
* @param oSubOperations all suboperations of this operation
* @return an object managing the error
* @see SKGError
*/
SKGError getSubOperations(SKGListSKGObjectBase& oSubOperations) const;
/**
* Get the current amount
* @return the current amount
*/
double getCurrentAmount() const;
/**
* Get the account balance for this operation
* @return the account balance
*/
double getBalance() const;
/**
* Get amount of the operation at a date
* @param iDate date
* @return amount of the operation
*/
// cppcheck-suppress passedByValue
double getAmount(QDate iDate) const;
/**
* Create a recurrent operation based on this one
* @param oRecurrentOperation the created recurrent operation
* @return an object managing the error
* @see SKGError
*/
SKGError addRecurrentOperation(SKGRecurrentOperationObject& oRecurrentOperation) const;
/**
* Get the recurrent operations based on this one
* @param oRecurrentOperation the recurrent operations
* @return an object managing the error
* @see SKGError
*/
SKGError getRecurrentOperations(SKGListSKGObjectBase& oRecurrentOperation) const;
/**
* Merge current operation with another one
* @param iDeletedOne after merge this operation will be deleted
* @param iMode the alignment mode
* @param iSendMessage send warning message
* @return an object managing the error
* @see SKGError
*/
SKGError mergeAttribute(const SKGOperationObject& iDeletedOne, SKGOperationObject::AmountAlignmentMode iMode = SKGOperationObject::DEFAULT, bool iSendMessage = true);
/**
* Merge current operation with another one
* @param iDeletedOne after merge this operation will be deleted
* @return an object managing the error
* @see SKGError
*/
SKGError mergeSuboperations(const SKGOperationObject& iDeletedOne);
};
/**
* Declare the class
*/
Q_DECLARE_TYPEINFO(SKGOperationObject, Q_MOVABLE_TYPE);
#endif
diff --git a/skgbankmodeler/skgpayeeobject.cpp b/skgbankmodeler/skgpayeeobject.cpp
index 11b54c5b4..6dbec05dd 100644
--- a/skgbankmodeler/skgpayeeobject.cpp
+++ b/skgbankmodeler/skgpayeeobject.cpp
@@ -1,152 +1,152 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file implements classes SKGPayeeObject.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgpayeeobject.h"
#include <klocalizedstring.h>
#include "skgcategoryobject.h"
#include "skgdocumentbank.h"
#include "skgoperationobject.h"
#include "skgtraces.h"
SKGPayeeObject::SKGPayeeObject(): SKGPayeeObject(nullptr)
{}
SKGPayeeObject::SKGPayeeObject(SKGDocument* iDocument, int iID): SKGNamedObject(iDocument, QStringLiteral("v_payee"), iID)
{}
SKGPayeeObject::~SKGPayeeObject()
= default;
SKGPayeeObject::SKGPayeeObject(const SKGPayeeObject& iObject) = default;
SKGPayeeObject::SKGPayeeObject(const SKGObjectBase& iObject)
{
if (iObject.getRealTable() == QStringLiteral("payee")) {
copyFrom(iObject);
} else {
*this = SKGNamedObject(iObject.getDocument(), QStringLiteral("v_payee"), iObject.getID());
}
}
SKGPayeeObject& SKGPayeeObject::operator= (const SKGObjectBase& iObject)
{
copyFrom(iObject);
return *this;
}
SKGError SKGPayeeObject::createPayee(SKGDocumentBank* iDocument,
const QString& iName,
SKGPayeeObject& oPayee,
bool iSendPopupMessageOnCreation)
{
SKGError err;
SKGTRACEINFUNCRC(10, err)
// Check if refund is already existing
if (iName.isEmpty()) {
oPayee = SKGPayeeObject(nullptr, 0);
} else if (iDocument != nullptr) {
iDocument->getObject(QStringLiteral("v_payee"), "t_name='" % SKGServices::stringToSqlString(iName) % '\'', oPayee);
if (oPayee.getID() == 0) {
// No, we have to create it
oPayee = SKGPayeeObject(iDocument);
err = oPayee.setName(iName);
IFOKDO(err, oPayee.save())
if (!err && iSendPopupMessageOnCreation) {
err = iDocument->sendMessage(i18nc("Information message", "Payee '%1' has been created", iName), SKGDocument::Positive);
}
}
}
return err;
}
SKGError SKGPayeeObject::getOperations(SKGListSKGObjectBase& oOperations) const
{
SKGError err = getDocument()->getObjects(QStringLiteral("v_operation"),
"r_payee_id=" % SKGServices::intToString(getID()),
oOperations);
return err;
}
SKGError SKGPayeeObject::setAddress(const QString& iAddress)
{
return setAttribute(QStringLiteral("t_address"), iAddress);
}
QString SKGPayeeObject::getAddress() const
{
return getAttribute(QStringLiteral("t_address"));
}
SKGError SKGPayeeObject::setClosed(bool iClosed)
{
return setAttribute(QStringLiteral("t_close"), iClosed ? QStringLiteral("Y") : QStringLiteral("N"));
}
bool SKGPayeeObject::isClosed() const
{
return (getAttribute(QStringLiteral("t_close")) == QStringLiteral("Y"));
}
SKGError SKGPayeeObject::bookmark(bool iBookmark)
{
return setAttribute(QStringLiteral("t_bookmarked"), iBookmark ? QStringLiteral("Y") : QStringLiteral("N"));
}
bool SKGPayeeObject::isBookmarked() const
{
return (getAttribute(QStringLiteral("t_bookmarked")) == QStringLiteral("Y"));
}
SKGError SKGPayeeObject::getCategory(SKGCategoryObject& oCategory) const
{
SKGError err = getDocument()->getObject(QStringLiteral("v_category"), "id=" % getAttribute(QStringLiteral("r_category_id")), oCategory);
return err;
}
SKGError SKGPayeeObject::setCategory(const SKGCategoryObject& iCategory)
{
return setAttribute(QStringLiteral("r_category_id"), SKGServices::intToString(iCategory.getID()));
}
SKGError SKGPayeeObject::merge(const SKGPayeeObject& iPayee)
{
SKGError err;
SKGObjectBase::SKGListSKGObjectBase ops;
IFOKDO(err, iPayee.getOperations(ops))
int nb = ops.count();
for (int i = 0; !err && i < nb; ++i) {
SKGOperationObject op(ops.at(i));
err = op.setPayee(*this);
IFOKDO(err, op.save(true, false))
}
IFOKDO(err, iPayee.remove(false))
return err;
}
diff --git a/skgbankmodeler/skgpayeeobject.h b/skgbankmodeler/skgpayeeobject.h
index 21ce4cb9e..14c5b09e9 100644
--- a/skgbankmodeler/skgpayeeobject.h
+++ b/skgbankmodeler/skgpayeeobject.h
@@ -1,167 +1,167 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGPAYEEOBJECT_H
#define SKGPAYEEOBJECT_H
/** @file
* This file defines classes SKGPayeeObject.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgbankmodeler_export.h"
#include "skgnamedobject.h"
class SKGDocumentBank;
class SKGCategoryObject;
/**
* This class manages payee object
*/
class SKGBANKMODELER_EXPORT SKGPayeeObject final : public SKGNamedObject
{
Q_OBJECT
public:
/**
* Default constructor
*/
explicit SKGPayeeObject();
/**
* Constructor
* @param iDocument the document containing the object
* @param iID the identifier in @p iTable of the object
*/
explicit SKGPayeeObject(SKGDocument* iDocument, int iID = 0);
/**
* Copy constructor
* @param iObject the object to copy
*/
SKGPayeeObject(const SKGPayeeObject& iObject);
/**
* Copy constructor
* @param iObject the object to copy
*/
explicit SKGPayeeObject(const SKGObjectBase& iObject);
/**
* Operator affectation
* @param iObject the object to copy
*/
SKGPayeeObject& operator= (const SKGObjectBase& iObject);
/**
* Destructor
*/
~SKGPayeeObject() override;
/**
* Create a payee if needed and return it
* @param iDocument the document where to create
* @param iName the name
* @param oPayee the payee
* @param iSendPopupMessageOnCreation to send a creation message if the payee is created
* @return an object managing the error.
* @see SKGError
*/
static SKGError createPayee(SKGDocumentBank* iDocument,
const QString& iName,
SKGPayeeObject& oPayee,
bool iSendPopupMessageOnCreation = false);
/**
* Get all operations of this payee
* @param oOperations all operations of this payee
* @return an object managing the error
* @see SKGError
*/
SKGError getOperations(SKGListSKGObjectBase& oOperations) const;
/**
* Set the address of payee
* @param iAddress the address
* @return an object managing the error
* @see SKGError
*/
SKGError setAddress(const QString& iAddress);
/**
* Get the address of this payee
* @return the address
*/
QString getAddress() const;
/**
* To set the closed attribute of a payee
* @param iClosed the closed attribute: true or false
* @return an object managing the error
* @see SKGError
*/
virtual SKGError setClosed(bool iClosed);
/**
* To know if the payee has been closed or not
* @return an object managing the error
* @see SKGError
*/
virtual bool isClosed() const;
/**
* To bookmark or not a payee
* @param iBookmark the bookmark: true or false
* @return an object managing the error
* @see SKGError
*/
SKGError bookmark(bool iBookmark);
/**
* To know if the payee is bookmarked
* @return an object managing the error
* @see SKGError
*/
bool isBookmarked() const;
/**
* Set the category
* @param iCategory the category
* @return an object managing the error
* @see SKGError
*/
SKGError setCategory(const SKGCategoryObject& iCategory);
/**
* Get the category
* @param oCategory the category
* @return an object managing the error
* @see SKGError
*/
SKGError getCategory(SKGCategoryObject& oCategory) const;
/**
* Merge iPayee in current payee
* @param iPayee the payee. All operations will be transferred into this payee. The payee will be removed
* @return an object managing the error
* @see SKGError
*/
SKGError merge(const SKGPayeeObject& iPayee);
};
/**
* Declare the class
*/
Q_DECLARE_TYPEINFO(SKGPayeeObject, Q_MOVABLE_TYPE);
#endif
diff --git a/skgbankmodeler/skgrecurrentoperationobject.cpp b/skgbankmodeler/skgrecurrentoperationobject.cpp
index 04af73227..4a493a8d5 100644
--- a/skgbankmodeler/skgrecurrentoperationobject.cpp
+++ b/skgbankmodeler/skgrecurrentoperationobject.cpp
@@ -1,312 +1,312 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file implements classes SKGRecurrentOperationObject.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgrecurrentoperationobject.h"
#include <klocalizedstring.h>
#include "skgdocumentbank.h"
#include "skgoperationobject.h"
#include "skgservices.h"
#include "skgsuboperationobject.h"
#include "skgtraces.h"
SKGRecurrentOperationObject::SKGRecurrentOperationObject(): SKGRecurrentOperationObject(nullptr)
{}
SKGRecurrentOperationObject::SKGRecurrentOperationObject(SKGDocument* iDocument, int iID): SKGObjectBase(iDocument, QStringLiteral("v_recurrentoperation"), iID)
{}
SKGRecurrentOperationObject::~SKGRecurrentOperationObject()
= default;
SKGRecurrentOperationObject::SKGRecurrentOperationObject(const SKGRecurrentOperationObject& iObject) = default;
SKGRecurrentOperationObject::SKGRecurrentOperationObject(const SKGObjectBase& iObject)
{
if (iObject.getRealTable() == QStringLiteral("recurrentoperation")) {
copyFrom(iObject);
} else {
*this = SKGObjectBase(iObject.getDocument(), QStringLiteral("v_recurrentoperation"), iObject.getID());
}
}
SKGRecurrentOperationObject& SKGRecurrentOperationObject::operator= (const SKGObjectBase& iObject)
{
copyFrom(iObject);
return *this;
}
SKGError SKGRecurrentOperationObject::getParentOperation(SKGOperationObject& oOperation) const
{
SKGObjectBase objTmp;
SKGError err = getDocument()->getObject(QStringLiteral("v_operation"), "id=" % getAttribute(QStringLiteral("rd_operation_id")), objTmp);
oOperation = objTmp;
return err;
}
SKGError SKGRecurrentOperationObject::setParentOperation(const SKGOperationObject& iOperation)
{
return setAttribute(QStringLiteral("rd_operation_id"), SKGServices::intToString(iOperation.getID()));
}
SKGError SKGRecurrentOperationObject::setPeriodIncrement(int iIncrement)
{
return setAttribute(QStringLiteral("i_period_increment"), SKGServices::intToString(iIncrement));
}
int SKGRecurrentOperationObject::getPeriodIncrement() const
{
return SKGServices::stringToInt(getAttribute(QStringLiteral("i_period_increment")));
}
SKGRecurrentOperationObject::PeriodUnit SKGRecurrentOperationObject::getPeriodUnit() const
{
QString t_period_unit = getAttribute(QStringLiteral("t_period_unit"));
if (t_period_unit == QStringLiteral("D")) {
return SKGRecurrentOperationObject::DAY;
}
if (t_period_unit == QStringLiteral("W")) {
return SKGRecurrentOperationObject::WEEK;
}
if (t_period_unit == QStringLiteral("M")) {
return SKGRecurrentOperationObject::MONTH;
}
return SKGRecurrentOperationObject::YEAR;
}
SKGError SKGRecurrentOperationObject::setPeriodUnit(SKGRecurrentOperationObject::PeriodUnit iPeriod)
{
return setAttribute(QStringLiteral("t_period_unit"), (iPeriod == SKGRecurrentOperationObject::DAY ? QStringLiteral("D") : (iPeriod == SKGRecurrentOperationObject::WEEK ? QStringLiteral("W") : (iPeriod == SKGRecurrentOperationObject::MONTH ? QStringLiteral("M") : QStringLiteral("Y")))));
}
SKGError SKGRecurrentOperationObject::setAutoWriteDays(int iDays)
{
return setAttribute(QStringLiteral("i_auto_write_days"), SKGServices::intToString(iDays));
}
int SKGRecurrentOperationObject::getAutoWriteDays() const
{
return SKGServices::stringToInt(getAttribute(QStringLiteral("i_auto_write_days")));
}
SKGError SKGRecurrentOperationObject::setWarnDays(int iDays)
{
return setAttribute(QStringLiteral("i_warn_days"), SKGServices::intToString(iDays));
}
int SKGRecurrentOperationObject::getWarnDays() const
{
return SKGServices::stringToInt(getAttribute(QStringLiteral("i_warn_days")));
}
bool SKGRecurrentOperationObject::hasTimeLimit() const
{
return (getAttribute(QStringLiteral("t_times")) == QStringLiteral("Y"));
}
SKGError SKGRecurrentOperationObject::timeLimit(bool iTimeLimit)
{
return setAttribute(QStringLiteral("t_times"), iTimeLimit ? QStringLiteral("Y") : QStringLiteral("N"));
}
SKGError SKGRecurrentOperationObject::setTimeLimit(QDate iLastDate)
{
// Get parameters
QDate firstDate = this->getDate();
if (iLastDate < firstDate) {
return setTimeLimit(0);
}
SKGRecurrentOperationObject::PeriodUnit period = this->getPeriodUnit();
int occu = qMax(this->getPeriodIncrement(), 1);
// Compute nb time
int nbd = firstDate.daysTo(iLastDate);
if (period == SKGRecurrentOperationObject::DAY) {
nbd = nbd / occu;
} else if (period == SKGRecurrentOperationObject::WEEK) {
nbd = nbd / (7 * occu);
} else if (period == SKGRecurrentOperationObject::MONTH) {
nbd = (iLastDate.day() >= firstDate.day() ? 0 : -1) + (iLastDate.year() - firstDate.year()) * 12 + (iLastDate.month() - firstDate.month());
} else if (period == SKGRecurrentOperationObject::YEAR) {
nbd = nbd / (365 * occu);
}
if (nbd < -1) {
nbd = -1;
}
return setTimeLimit(nbd + 1);
}
SKGError SKGRecurrentOperationObject::setTimeLimit(int iTimeLimit)
{
return setAttribute(QStringLiteral("i_nb_times"), SKGServices::intToString(iTimeLimit));
}
int SKGRecurrentOperationObject::getTimeLimit() const
{
return SKGServices::stringToInt(getAttribute(QStringLiteral("i_nb_times")));
}
SKGError SKGRecurrentOperationObject::setDate(QDate iDate)
{
return setAttribute(QStringLiteral("d_date"), SKGServices::dateToSqlString(QDateTime(iDate)));
}
QDate SKGRecurrentOperationObject::getNextDate() const
{
QDate nextDate = getDate();
SKGRecurrentOperationObject::PeriodUnit punit = getPeriodUnit();
int p = getPeriodIncrement();
if (punit == SKGRecurrentOperationObject::DAY) {
nextDate = nextDate.addDays(p);
} else if (punit == SKGRecurrentOperationObject::WEEK) {
nextDate = nextDate.addDays(7 * p);
} else if (punit == SKGRecurrentOperationObject::MONTH) {
nextDate = nextDate.addMonths(p);
} else if (punit == SKGRecurrentOperationObject::YEAR) {
nextDate = nextDate.addYears(p);
}
return nextDate;
}
QDate SKGRecurrentOperationObject::getDate() const
{
return SKGServices::stringToTime(getAttribute(QStringLiteral("d_date"))).date();
}
SKGError SKGRecurrentOperationObject::warnEnabled(bool iWarn)
{
return setAttribute(QStringLiteral("t_warn"), iWarn ? QStringLiteral("Y") : QStringLiteral("N"));
}
bool SKGRecurrentOperationObject::isWarnEnabled() const
{
return (getAttribute(QStringLiteral("t_warn")) == QStringLiteral("Y"));
}
SKGError SKGRecurrentOperationObject::autoWriteEnabled(bool iAutoWrite)
{
return setAttribute(QStringLiteral("t_auto_write"), iAutoWrite ? QStringLiteral("Y") : QStringLiteral("N"));
}
bool SKGRecurrentOperationObject::isAutoWriteEnabled() const
{
return (getAttribute(QStringLiteral("t_auto_write")) == QStringLiteral("Y"));
}
SKGError SKGRecurrentOperationObject::getRecurredOperations(SKGListSKGObjectBase& oOperations) const
{
return getDocument()->getObjects(QStringLiteral("v_operation"), "r_recurrentoperation_id=" % SKGServices::intToString(getID()), oOperations);
}
SKGError SKGRecurrentOperationObject::process(int& oNbInserted, bool iForce, QDate iDate)
{
SKGError err;
SKGTRACEINFUNCRC(10, err)
oNbInserted = 0;
if (!hasTimeLimit() || getTimeLimit() > 0) {
if (isAutoWriteEnabled() || iForce) {
QDate nextDate = getDate();
if (nextDate.isValid() && iDate >= nextDate.addDays(-getAutoWriteDays())) {
SKGOperationObject op;
err = getParentOperation(op);
IFOK(err) {
// Create the duplicated operation
SKGOperationObject newOp;
err = op.duplicate(newOp, nextDate);
if (!op.isTemplate()) {
// Set old op as recurrent
IFOKDO(err, op.setAttribute(QStringLiteral("r_recurrentoperation_id"), SKGServices::intToString(getID())))
IFOKDO(err, op.save())
// Set new operation as reference
IFOKDO(err, setParentOperation(newOp))
} else {
// Set new op as recurrent
IFOKDO(err, newOp.setAttribute(QStringLiteral("r_recurrentoperation_id"), SKGServices::intToString(getID())))
IFOKDO(err, newOp.save())
}
IFOKDO(err, setDate(getNextDate()))
if (!err && hasTimeLimit()) {
err = setTimeLimit(getTimeLimit() - 1);
}
IFOKDO(err, save())
IFOKDO(err, load())
// Process again in case of multi insert needed
int nbi = 0;
IFOKDO(err, process(nbi, iForce, iDate))
oNbInserted = oNbInserted + 1 + nbi;
// Send message
IFOKDO(err, newOp.load())
IFOK(err) {
err = getDocument()->sendMessage(i18nc("An information message", "Operation '%1' has been inserted", newOp.getDisplayName()), SKGDocument::Positive);
}
}
}
}
if (isWarnEnabled() && !err) {
QDate nextDate = getDate();
if (QDate::currentDate() >= nextDate.addDays(-getWarnDays())) {
SKGOperationObject op;
err = getParentOperation(op);
IFOK(err) {
int nbdays = QDate::currentDate().daysTo(nextDate);
if (nbdays > 0) {
err = getDocument()->sendMessage(i18np("Operation '%2' will be inserted in one day", "Operation '%2' will be inserted in %1 days", nbdays, getDisplayName()));
}
}
}
}
}
return err;
}
SKGError SKGRecurrentOperationObject::process(SKGDocumentBank* iDocument, int& oNbInserted, bool iForce, QDate iDate)
{
SKGError err;
oNbInserted = 0;
// Get all operation with auto_write
SKGListSKGObjectBase recuOps;
if (iDocument != nullptr) {
err = iDocument->getObjects(QStringLiteral("v_recurrentoperation"), QLatin1String(""), recuOps);
}
int nb = recuOps.count();
for (int i = 0; !err && i < nb; ++i) {
SKGRecurrentOperationObject recu(recuOps.at(i));
int nbi = 0;
err = recu.process(nbi, iForce, iDate);
oNbInserted += nbi;
}
return err;
}
diff --git a/skgbankmodeler/skgrecurrentoperationobject.h b/skgbankmodeler/skgrecurrentoperationobject.h
index 54f0e3c85..bdad8c464 100644
--- a/skgbankmodeler/skgrecurrentoperationobject.h
+++ b/skgbankmodeler/skgrecurrentoperationobject.h
@@ -1,281 +1,281 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGRECURRENTOPERATIONOBJECT_H
#define SKGRECURRENTOPERATIONOBJECT_H
/** @file
* This file defines classes SKGRecurrentOperationObject.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgbankmodeler_export.h"
#include "skgobjectbase.h"
class SKGOperationObject;
class SKGDocumentBank;
/**
* This class manages recurrent operation object
*/
class SKGBANKMODELER_EXPORT SKGRecurrentOperationObject final : public SKGObjectBase
{
Q_OBJECT
public:
/**
* This enumerate defines the period unit
*/
enum PeriodUnit {DAY = 0, /**< day */
WEEK = 1, /**< week */
MONTH = 2, /**< month */
YEAR = 3 /**< year */
};
/**
* This enumerate defines the period unit
*/
Q_ENUM(PeriodUnit)
/**
* Default constructor
*/
explicit SKGRecurrentOperationObject();
/**
* Constructor
* @param iDocument the document containing the object
* @param iID the identifier in @p iTable of the object
*/
explicit SKGRecurrentOperationObject(SKGDocument* iDocument, int iID = 0);
/**
* Copy constructor
* @param iObject the object to copy
*/
explicit SKGRecurrentOperationObject(const SKGObjectBase& iObject);
/**
* Copy constructor
* @param iObject the object to copy
*/
SKGRecurrentOperationObject(const SKGRecurrentOperationObject& iObject);
/**
* Operator affectation
* @param iObject the object to copy
*/
SKGRecurrentOperationObject& operator= (const SKGObjectBase& iObject);
/**
* Destructor
*/
~SKGRecurrentOperationObject() override;
/**
* Get the parent operation
* @param oOperation the parent operation
* @return an object managing the error.
* @see SKGError
*/
SKGError getParentOperation(SKGOperationObject& oOperation) const;
/**
* Set the parent operation
* @param iOperation the parent operation
* @return an object managing the error.
* @see SKGError
*/
SKGError setParentOperation(const SKGOperationObject& iOperation);
/**
* Set the increment
* @param iIncrement the number of @see setPeriodUnit
* @return an object managing the error
* @see SKGError
*/
SKGError setPeriodIncrement(int iIncrement);
/**
* Get the increment
* @return the number
*/
int getPeriodIncrement() const;
/**
* Get the period unit of this recurrent operation
* @return the status
*/
SKGRecurrentOperationObject::PeriodUnit getPeriodUnit() const;
/**
* Set the period unit of this recurrent operation
* @param iPeriod the period unit
* @return an object managing the error
* @see SKGError
*/
SKGError setPeriodUnit(SKGRecurrentOperationObject::PeriodUnit iPeriod);
/**
* Set the number of days before term to create operation
* @param iDays the number of days
* @return an object managing the error
* @see SKGError
*/
SKGError setAutoWriteDays(int iDays);
/**
* Get the number of days before term to create operation
* @return the number of days
*/
int getAutoWriteDays() const;
/**
* Set the number of days before term to warn user
* @param iDays the number of days
* @return an object managing the error
* @see SKGError
*/
SKGError setWarnDays(int iDays);
/**
* Get the number of days before term to warn user
* @return the number of days
*/
int getWarnDays() const;
/**
* Set date of this recurrent operation
* @param iDate the date
* @return an object managing the error
* @see SKGError
*/
// cppcheck-suppress passedByValue
SKGError setDate(QDate iDate);
/**
* Get date of this recurrent operation
* @return the date
*/
QDate getDate() const;
/**
* Get next date of this recurrent operation
* @return the date
*/
QDate getNextDate() const;
/**
* Get all operations created by this recurrent operation
* @param oOperations all operations
* @return an object managing the error
* @see SKGError
*/
SKGError getRecurredOperations(SKGListSKGObjectBase& oOperations) const;
/**
* To warn or not the end user
* @param iWarn the warn: true or false
* @return an object managing the error
* @see SKGError
*/
SKGError warnEnabled(bool iWarn);
/**
* To know if the end user is warned or not
* @return an object managing the error
* @see SKGError
*/
bool isWarnEnabled() const;
/**
* To activate or not the auto write mode
* @param iAutoWrite auto write mode: true or false
* @return an object managing the error
* @see SKGError
*/
SKGError autoWriteEnabled(bool iAutoWrite);
/**
* To know if auto write mode is enabled or not
* @return an object managing the error
* @see SKGError
*/
bool isAutoWriteEnabled() const;
/**
* To know if a time limit is enabled or not
* @return an object managing the error
* @see SKGError
*/
bool hasTimeLimit() const;
/**
* To enable / disable a time limit
* @param iTimeLimit the time limit: true or false
* @return an object managing the error
* @see SKGError
*/
SKGError timeLimit(bool iTimeLimit);
/**
* Set the time limit
* @param iTimeLimit the number of times operation will be inserted
* @return an object managing the error
* @see SKGError
*/
SKGError setTimeLimit(int iTimeLimit);
/**
* Set the time limit
* @param iLastDate the last date of the operation will be inserted. setDate, setPeriodIncrement and setPeriodUnit must be used before.
* @return an object managing the error
* @see SKGError
*/
// cppcheck-suppress passedByValue
SKGError setTimeLimit(QDate iLastDate);
/**
* Get the number of times operation will be inserted
* @return the number of times
*/
int getTimeLimit() const;
/**
* Warn and/or create operations for this recurrent operation
* @param oNbInserted number of operations inserted
* @param iForce to force the insertion even if autowrite is not enable
* @param iDate date limit for insertion
* @return an object managing the error
* @see SKGError
*/
// cppcheck-suppress passedByValue
SKGError process(int& oNbInserted, bool iForce = false, QDate iDate = QDate::currentDate());
/**
* Warn and/or create operations for all recurrent operations of the document
* @param iDocument the document containing the object
* @param oNbInserted number of operations inserted
* @param iForce to force the insertion even if autowrite is not enable*
* @param iDate date limit for insertion
* @return an object managing the error
* @see SKGError
*/
// cppcheck-suppress passedByValue
static SKGError process(SKGDocumentBank* iDocument, int& oNbInserted, bool iForce = false, QDate iDate = QDate::currentDate());
};
/**
* Declare the class
*/
Q_DECLARE_TYPEINFO(SKGRecurrentOperationObject, Q_MOVABLE_TYPE);
#endif
diff --git a/skgbankmodeler/skgreportbank.cpp b/skgbankmodeler/skgreportbank.cpp
index 94ea3b8a2..60587f108 100644
--- a/skgbankmodeler/skgreportbank.cpp
+++ b/skgbankmodeler/skgreportbank.cpp
@@ -1,776 +1,776 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* A skrooge plugin for monthly report.
*
* @author Stephane MANKOWSKI
*/
#include "skgreportbank.h"
#include <qdir.h>
#include <qstandardpaths.h>
#include <qurl.h>
#include <kcolorscheme.h>
#include "skgaccountobject.h"
#include "skgdocumentbank.h"
#include "skgoperationobject.h"
#include "skgrecurrentoperationobject.h"
#include "skgruleobject.h"
#include "skgtraces.h"
#include "skgunitobject.h"
SKGReportBank::SKGReportBank(SKGDocument* iDocument) : SKGReport(iDocument)
{
SKGTRACEINFUNC(1)
connect(this, &SKGReportBank::changed, this, &SKGReportBank::changed2);
}
SKGReportBank::~SKGReportBank()
{
SKGTRACEINFUNC(1)
}
QVariantList SKGReportBank::getAlarms()
{
QString cacheId = QStringLiteral("getAlarms");
QVariantList table = m_cache.value(cacheId).toList();
if (table.isEmpty()) {
SKGTRACEINFUNC(10)
auto* doc = qobject_cast<SKGDocumentBank*>(m_document);
if (doc != nullptr) {
SKGServices::SKGUnitInfo primary = doc->getPrimaryUnit();
SKGObjectBase::SKGListSKGObjectBase rules;
SKGError err = doc->getObjects(QStringLiteral("v_rule"), QStringLiteral("t_action_type='A' ORDER BY i_ORDER"), rules);
int nb = rules.count();
if (nb != 0) {
for (int i = 0; !err && i < nb; ++i) {
SKGRuleObject rule(rules.at(i));
SKGRuleObject::SKGAlarmInfo alarm = rule.getAlarmInfo();
QVariantList item; // clazy:exclude=container-inside-loop
// Build the message
if (alarm.Message.contains(QLatin1String("%3"))) {
alarm.Message = alarm.Message.arg(doc->formatMoney(alarm.Amount, primary, false), doc->formatMoney(alarm.Limit, primary, false), doc->formatMoney(alarm.Amount - alarm.Limit, primary, false));
} else if (alarm.Message.contains(QLatin1String("%2"))) {
alarm.Message = alarm.Message.arg(doc->formatMoney(alarm.Amount, primary, false), doc->formatMoney(alarm.Limit, primary, false));
} else if (alarm.Message.contains(QLatin1String("%1"))) {
alarm.Message = alarm.Message.arg(doc->formatMoney(alarm.Amount, primary, false));
}
item.push_back(alarm.Message);
item.push_back(alarm.Amount);
item.push_back(alarm.Limit);
item.push_back(alarm.Amount - alarm.Limit);
item.push_back(alarm.Raised);
table.push_back(item);
}
}
m_cache[cacheId] = table;
}
}
return table;
}
QVariantList SKGReportBank::getInterests()
{
QString cacheId = QStringLiteral("getInterests");
QVariantList table = m_cache.value(cacheId).toList();
if (table.isEmpty()) {
SKGTRACEINFUNC(10)
auto* doc = qobject_cast<SKGDocumentBank*>(m_document);
if (doc != nullptr) {
// Build display
int year = SKGServices::periodToDate(getPeriod()).year();
SKGObjectBase::SKGListSKGObjectBase objs;
SKGError err = doc->getObjects(QStringLiteral("v_account"), QStringLiteral("t_close='N' AND EXISTS(select 1 from interest where interest.rd_account_id=v_account.id) ORDER BY t_name"), objs);
IFOK(err) {
int nb = objs.count();
table.reserve(nb + 2);
if (nb != 0) {
{
// Add header
QVariantList item;
item.push_back(false);
item.push_back(i18nc("Title", "Account"));
item.push_back(year);
table.push_back(item);
}
// Add items
double sum = 0;
for (int i = 0; i < nb; ++i) {
SKGAccountObject obj(objs.at(i));
SKGAccountObject::SKGInterestItemList oInterestList;
double oInterests = 0;
obj.getInterestItems(oInterestList, oInterests, year);
sum += oInterests;
QVariantList item; // clazy:exclude=container-inside-loop
item.push_back(false);
item.push_back(obj.getName());
item.push_back(oInterests);
table.push_back(item);
}
{
// Add sum
QVariantList item;
item.push_back(true);
item.push_back(i18nc("Noun, the numerical total of a sum of values", "Total"));
item.push_back(sum);
table.push_back(item);
}
}
}
m_cache[cacheId] = table;
}
}
return table;
}
QVariantList SKGReportBank::getBudgetTable()
{
QString cacheId = QStringLiteral("getBudgetTable");
QVariantList table = m_cache.value(cacheId).toList();
if (table.isEmpty()) {
SKGTRACEINFUNC(10)
auto* doc = qobject_cast<SKGDocumentBank*>(m_document);
table = doc != nullptr ? doc->getBudget(getPeriod()) : QVariantList();
m_cache[cacheId] = table;
}
return table;
}
QVariantList SKGReportBank::getPortfolio()
{
QString cacheId = QStringLiteral("getPortfolio");
QVariantList table = m_cache.value(cacheId).toList();
if (table.isEmpty()) {
SKGTRACEINFUNC(10)
QString period = getPeriod();
if (!period.isEmpty()) {
QDate date = qMin(SKGServices::periodToDate(period), QDate::currentDate().addDays(1 - QDate::currentDate().day()).addMonths(1).addDays(-1));
auto* doc = qobject_cast<SKGDocumentBank*>(m_document);
if (doc != nullptr) {
SKGServices::SKGUnitInfo primary = doc->getPrimaryUnit();
// Get list of operations
SKGObjectBase::SKGListSKGObjectBase objs;
SKGError err = doc->getObjects(QStringLiteral("v_operation_display"), "d_date<'" % SKGServices::dateToSqlString(QDateTime(date)) % "' AND rc_unit_id IN (SELECT id FROM v_unit_display WHERE t_type='S' AND f_QUANTITYOWNED>0.01) ORDER BY t_UNIT", objs);
int nb = objs.count();
if (!err && nb > 0) {
table.reserve(nb + 1);
QVariantList line;
line << doc->getDisplay(QStringLiteral("t_symbol"))
<< doc->getDisplay(QStringLiteral("t_UNIT"))
<< i18nc("Column table title", "Quantity")
<< i18nc("Column table title", "Purchase amount")
<< i18nc("Column table title", "Initial amount")
<< QLocale().toString(date, QLocale::ShortFormat)
<< i18nc("Column table title", "Variation")
<< i18nc("Column table title", "Variation %");
table << QVariant(line);
QVector<unitValues> listUnitValues;
unitValues current;
current.initalAmount = 0.0;
current.purchaseAmount = 0.0;
current.currentAmount = 0.0;
current.quantity = 0.0;
listUnitValues.reserve(nb);
for (int i = 0; i < nb; ++i) {
SKGOperationObject obj(objs.at(i));
SKGUnitObject unit;
obj.getUnit(unit);
if (i != 0 && current.unit != unit) {
listUnitValues.push_back(current);
current.initalAmount = 0.0;
current.purchaseAmount = 0.0;
current.currentAmount = 0.0;
current.quantity = 0.0;
}
current.unit = unit;
current.initalAmount += obj.getAmount(obj.getDate());
current.currentAmount += obj.getAmount(date);
SKGObjectBase::SKGListSKGObjectBase oGroupedOperations;
obj.getGroupedOperations(oGroupedOperations);
oGroupedOperations.removeAll(obj);
if (oGroupedOperations.count() == 1) {
SKGOperationObject obj2(oGroupedOperations.at(0));
current.purchaseAmount += obj2.getAmount(obj.getDate());
}
current.quantity += SKGServices::stringToDouble(obj.getAttribute(QStringLiteral("f_QUANTITY")));
}
if (!current.unit.getName().isEmpty()) {
listUnitValues.push_back(current);
}
nb = listUnitValues.count();
for (int j = 0; j < nb; ++j) {
unitValues current2 = listUnitValues.at(j);
SKGServices::SKGUnitInfo ui = current2.unit.getUnitInfo();
ui.Value = 1;
QVariantList line2; // clazy:exclude=container-inside-loop
line2 << current2.unit.getSymbol()
<< current2.unit.getName()
<< doc->formatMoney(current2.quantity, ui, false)
<< current2.purchaseAmount
<< current2.initalAmount
<< current2.currentAmount
<< current2.currentAmount - current2.initalAmount
<< (current2.initalAmount == 0.0 ? 0.0 : 100.0 * (current2.currentAmount - current2.initalAmount) / current2.initalAmount);
table << QVariant(line2);
}
}
}
}
m_cache[cacheId] = table;
}
return table;
}
QVariantList SKGReportBank::getUnitTable()
{
QString cacheId = QStringLiteral("getUnitTable");
QVariantList table = m_cache.value(cacheId).toList();
if (table.isEmpty()) {
SKGTRACEINFUNC(10)
QString period = getPeriod();
if (!period.isEmpty()) {
QDate date1 = SKGServices::periodToDate(getPreviousPeriod());
QDate date2 = SKGServices::periodToDate(period);
auto* doc = qobject_cast<SKGDocumentBank*>(m_document);
if (doc != nullptr) {
SKGServices::SKGUnitInfo primary = doc->getPrimaryUnit();
SKGObjectBase::SKGListSKGObjectBase units;
SKGError err = doc->getObjects(QStringLiteral("v_unit_display"), QStringLiteral("1=1 ORDER BY t_TYPENLS"), units);
int nbUnits = units.count();
if (nbUnits != 0) {
table.reserve(nbUnits + 1);
QVariantList line;
line << "sum"
<< doc->getDisplay(QStringLiteral("t_UNIT"))
<< QLocale().toString(date1, QLocale::ShortFormat)
<< QLocale().toString(date2, QLocale::ShortFormat)
<< "%"
<< doc->getDisplay(QStringLiteral("t_symbol"));
table << QVariant(line);
for (const auto& item : qAsConst(units)) {
SKGUnitObject unit(item);
double v1 = unit.getAmount(date1);
double v2 = unit.getAmount(date2);
QVariantList line2; // clazy:exclude=container-inside-loop
line2 << false << unit.getName() << v1 << v2 << (100.0 * (v2 - v1) / qAbs(v1)) << unit.getSymbol();
table << QVariant(line2);
}
}
}
}
m_cache[cacheId] = table;
}
return table;
}
QVariantList SKGReportBank::getAccountTable()
{
QString cacheId = QStringLiteral("getAccountTable");
QVariantList table = m_cache.value(cacheId).toList();
if (table.isEmpty()) {
SKGTRACEINFUNC(10)
QString period = getPeriod();
if (!period.isEmpty()) {
QDate date1 = SKGServices::periodToDate(getPreviousPeriod());
QDate date2 = SKGServices::periodToDate(period);
QDate date3 = date2.addYears(-1);
if (date3 == date1) {
date3 = date3.addYears(-1);
}
auto* doc = qobject_cast<SKGDocumentBank*>(m_document);
if (doc != nullptr) {
SKGServices::SKGUnitInfo primary = doc->getPrimaryUnit();
SKGObjectBase::SKGListSKGObjectBase accounts;
SKGError err = doc->getObjects(QStringLiteral("v_account"), QStringLiteral("1=1 ORDER BY t_TYPENLS, t_BANK, t_name"), accounts);
IFOK(err) {
table.push_back(QVariantList() << "sum" << doc->getDisplay(QStringLiteral("t_ACCOUNT")) << QLocale().toString(date1, QLocale::ShortFormat) << QLocale().toString(date2, QLocale::ShortFormat) <<
"%" << QLocale().toString(date3, QLocale::ShortFormat) << QLocale().toString(date2, QLocale::ShortFormat) << "%");
double sumTypeV1 = 0;
double sumTypeV2 = 0;
double sumTypeV3 = 0;
double sumV1 = 0;
double sumV2 = 0;
double sumV3 = 0;
QString currentType;
int nb = accounts.count();
for (int i = 0; !err && i < nb; ++i) {
SKGAccountObject account(accounts.at(i));
double v1 = account.getAmount(date1);
double v2 = account.getAmount(date2);
double v3 = account.getAmount(date3);
QString type = account.getAttribute(QStringLiteral("t_TYPENLS"));
bool closed = account.isClosed();
if (type != currentType) {
if (!currentType.isEmpty()) {
table.push_back(QVariantList() << true << i18nc("Noun", "Total of %1", currentType) << sumTypeV1 << sumTypeV2 <<
(100.0 * (sumTypeV2 - sumTypeV1) / qAbs(sumTypeV1)) << sumTypeV3 << sumTypeV2
<< (100.0 * (sumTypeV2 - sumTypeV3) / qAbs(sumTypeV3))
<< "" << "");
sumTypeV1 = 0;
sumTypeV2 = 0;
sumTypeV3 = 0;
}
currentType = type;
}
if (!closed || qAbs(v1) > 0.01 || qAbs(v2) > 0.01 || qAbs(v3) > 0.01) {
QString icon = account.getAttribute(QStringLiteral("t_ICON"));
if (!icon.isEmpty()) {
QString iconfile = QStandardPaths::locate(QStandardPaths::GenericDataLocation, "skrooge/images/logo/" % icon);
if (!iconfile.isEmpty()) {
icon = iconfile;
}
}
table.push_back(QVariantList() << false << account.getName() << v1 << v2 << (100.0 * (v2 - v1) / qAbs(v1)) << v3 << v2
<< (100.0 * (v2 - v3) / qAbs(v3)) << account.getAttribute(QStringLiteral("t_BANK")) << icon);
}
sumTypeV1 += v1;
sumTypeV2 += v2;
sumTypeV3 += v3;
sumV1 += v1;
sumV2 += v2;
sumV3 += v3;
}
table.push_back(QVariantList() << true << i18nc("Noun", "Total of %1", currentType) << sumTypeV1 << sumTypeV2
<< (100.0 * (sumTypeV2 - sumTypeV1) / qAbs(sumTypeV1)) << sumTypeV3 << sumTypeV2 << (100.0 * (sumTypeV2 - sumTypeV3) / qAbs(sumTypeV3))
<< "" << "");
table.push_back(QVariantList() << true << i18nc("Noun, the numerical total of a sum of values", "Total") << sumV1 << sumV2
<< (100.0 * (sumV2 - sumV1) / qAbs(sumV1)) << sumV3 << sumV2 << (100.0 * (sumV2 - sumV3) / qAbs(sumV3))
<< "" << "");
}
}
}
m_cache[cacheId] = table;
}
return table;
}
QVariantList SKGReportBank::getBankTable()
{
QString cacheId = QStringLiteral("getBankTable");
QVariantList table = m_cache.value(cacheId).toList();
if (table.isEmpty()) {
SKGTRACEINFUNC(10)
QString period = getPeriod();
if (!period.isEmpty()) {
QDate date1 = SKGServices::periodToDate(getPreviousPeriod());
QDate date2 = SKGServices::periodToDate(period);
QDate date3 = date2.addYears(-1);
if (date3 == date1) {
date3 = date3.addYears(-1);
}
auto* doc = qobject_cast<SKGDocumentBank*>(m_document);
if (doc != nullptr) {
SKGServices::SKGUnitInfo primary = doc->getPrimaryUnit();
SKGObjectBase::SKGListSKGObjectBase accounts;
SKGError err = doc->getObjects(QStringLiteral("v_account"), QStringLiteral("1=1 ORDER BY t_BANK"), accounts);
IFOK(err) {
table.push_back(QVariantList() << "sum" << doc->getDisplay(QStringLiteral("t_BANK")) << QLocale().toString(date1, QLocale::ShortFormat) << QLocale().toString(date2, QLocale::ShortFormat) <<
"%" << QLocale().toString(date3, QLocale::ShortFormat) << QLocale().toString(date2, QLocale::ShortFormat) << "%");
double sumTypeV1 = 0;
double sumTypeV2 = 0;
double sumTypeV3 = 0;
double sumV1 = 0;
double sumV2 = 0;
double sumV3 = 0;
QString currentName;
QString currentIcon;
bool currentOpen = false;
int nb = accounts.count();
for (int i = 0; !err && i < nb; ++i) {
SKGAccountObject account(accounts.at(i));
double v1 = account.getAmount(date1);
double v2 = account.getAmount(date2);
double v3 = account.getAmount(date3);
QString name = account.getAttribute(QStringLiteral("t_BANK"));
QString icon = account.getAttribute(QStringLiteral("t_ICON"));
if (!icon.isEmpty()) {
QString iconfile = QStandardPaths::locate(QStandardPaths::GenericDataLocation, "skrooge/images/logo/" % icon);
if (!iconfile.isEmpty()) {
icon = iconfile;
}
}
bool open = !account.isClosed();
if (name != currentName) {
if (!currentName.isEmpty() && currentOpen) {
table.push_back(QVariantList() << false << currentName << sumTypeV1 << sumTypeV2 <<
(100.0 * (sumTypeV2 - sumTypeV1) / qAbs(sumTypeV1)) << sumTypeV3 << sumTypeV2 << (100.0 * (sumTypeV2 - sumTypeV3) / qAbs(sumTypeV3)) <<
currentIcon);
sumTypeV1 = 0;
sumTypeV2 = 0;
sumTypeV3 = 0;
currentOpen = open;
}
currentName = name;
currentIcon = icon;
}
currentOpen = currentOpen || open;
sumTypeV1 += v1;
sumTypeV2 += v2;
sumTypeV3 += v3;
sumV1 += v1;
sumV2 += v2;
sumV3 += v3;
}
if (currentOpen) {
table.push_back(QVariantList() << false << currentName << sumTypeV1 << sumTypeV2
<< (100.0 * (sumTypeV2 - sumTypeV1) / qAbs(sumTypeV1)) << sumTypeV3
<< sumTypeV2 << (100.0 * (sumTypeV2 - sumTypeV3) / qAbs(sumTypeV3))
<< currentIcon);
}
table.push_back(QVariantList() << true << i18nc("Noun, the numerical total of a sum of values", "Total") << sumV1 << sumV2 << (100.0 * (sumV2 - sumV1) / qAbs(sumV1)) << sumV3 << sumV2 << (100.0 * (sumV2 - sumV3) / qAbs(sumV3)));
}
}
}
m_cache[cacheId] = table;
}
return table;
}
QVariantList SKGReportBank::getScheduledOperations()
{
QString cacheId = QStringLiteral("getScheduledOperations");
QVariantList table = m_cache.value(cacheId).toList();
if (table.isEmpty()) {
SKGTRACEINFUNC(10)
SKGObjectBase::SKGListSKGObjectBase objs;
auto scheduled_operation_days_max = m_parameters.value(QStringLiteral("scheduled_operation_days_max"), QStringLiteral("30")).toString();
SKGError err = m_document->getObjects(QStringLiteral("v_recurrentoperation_display"),
QStringLiteral("i_nb_times!=0 AND d_date<=date('now','+") + scheduled_operation_days_max + " day') ORDER BY d_date", objs);
QDate d = QDate::currentDate().addDays(SKGServices::stringToInt(scheduled_operation_days_max));
QString dateFormatShort = QLocale::system().dateFormat(QLocale::ShortFormat);
IFOK(err) {
int nb = objs.count();
if (nb != 0) {
table.reserve(nb);
for (int i = 0; i < nb; ++i) {
SKGRecurrentOperationObject obj(objs.at(i));
bool first = true;
auto obj_date = obj.getDate().toString(dateFormatShort);
while (true) {
if (obj.getDate() > d || (obj.hasTimeLimit() && obj.getTimeLimit() == 0)) {
break;
} else {
bool bold = false;
if (obj.isWarnEnabled() && QDate::currentDate() >= obj.getDate().addDays(-obj.getWarnDays())) {
bold = true;
}
auto name = obj.getDisplayName();
if (!first) {
name = name.replace(obj_date, obj.getDate().toString(dateFormatShort));
}
table.push_back(QVariantList() << bold << name << (first ? obj.getUniqueID() : QString()) << obj.getDate());
first = false;
obj.setDate(obj.getNextDate());
if (obj.hasTimeLimit()) {
obj.setTimeLimit(obj.getTimeLimit() - 1);
}
}
}
}
}
std::sort(table.begin(), table.end(), [](const QVariant & v1, const QVariant & v2) {
return v1.toList().at(3).toDate() < v2.toList().at(3).toDate();
});
m_cache[cacheId] = table;
}
}
return table;
}
QVariantList SKGReportBank::getMainCategoriesForPeriod()
{
QString cacheId = QStringLiteral("getMainCategoriesForPeriod");
QVariantList table = m_cache.value(cacheId).toList();
if (table.isEmpty()) {
SKGTRACEINFUNC(10)
auto* doc = qobject_cast<SKGDocumentBank*>(m_document);
table = doc != nullptr ? doc->getMainCategories(getPeriod(), 5) : QVariantList();
m_cache[cacheId] = table;
}
return table;
}
QVariantList SKGReportBank::getMainCategoriesForPreviousPeriod()
{
QString cacheId = QStringLiteral("getMainCategoriesForPreviousPeriod");
QVariantList table = m_cache.value(cacheId).toList();
if (table.isEmpty()) {
SKGTRACEINFUNC(10)
auto* doc = qobject_cast<SKGDocumentBank*>(m_document);
table = doc != nullptr ? doc->getMainCategories(getPreviousPeriod(), 5) : QVariantList();
m_cache[cacheId] = table;
}
return table;
}
QStringList SKGReportBank::get5MainCategoriesVariation()
{
QString cacheId = QStringLiteral("get5MainCategoriesVariation");
QStringList table = m_cache.value(cacheId).toStringList();
if (table.isEmpty()) {
SKGTRACEINFUNC(10)
auto* doc = qobject_cast<SKGDocumentBank*>(m_document);
table = doc != nullptr ? doc->get5MainCategoriesVariationList(getPeriod(), getPreviousPeriod(), false) : QStringList();
m_cache[cacheId] = table;
}
return table;
}
QStringList SKGReportBank::get5MainCategoriesVariationIssue()
{
QString cacheId = QStringLiteral("get5MainCategoriesVariationIssue");
QStringList table = m_cache.value(cacheId).toStringList();
if (table.isEmpty()) {
SKGTRACEINFUNC(10)
auto* doc = qobject_cast<SKGDocumentBank*>(m_document);
table = doc != nullptr ? doc->get5MainCategoriesVariationList(getPeriod(), getPreviousPeriod(), true) : QStringList();
m_cache[cacheId] = table;
}
return table;
}
QVariantMap SKGReportBank::getPersonalFinanceScoreDetails(bool iTransfer, bool iTracker)
{
KColorScheme scheme(QPalette::Normal, KColorScheme::Window);
QVariantMap output;
double pfs = getPersonalFinanceScore(iTransfer, iTracker);
output[QStringLiteral("value")] = pfs;
if (pfs < 0) {
output[QStringLiteral("level")] = QStringLiteral("danger");
output[QStringLiteral("message")] = i18nc("An advice", "You must try to get out of debt.");
output[QStringLiteral("color")] = scheme.foreground(KColorScheme::NegativeText).color().name().right(6);
} else if (pfs >= 25) {
output[QStringLiteral("level")] = QStringLiteral("success");
output[QStringLiteral("message")] = i18nc("An advice", "Congratulations, you are now financially independent.");
output[QStringLiteral("color")] = scheme.foreground(KColorScheme::PositiveText).color().name().right(6);
} else if (pfs >= 10) {
output[QStringLiteral("level")] = QStringLiteral("success");
output[QStringLiteral("message")] = i18nc("An advice", "Congratulations, You saved up ten year’s worth of expenses.");
output[QStringLiteral("color")] = scheme.foreground(KColorScheme::PositiveText).color().name().right(6);
} else if (pfs >= 2) {
output[QStringLiteral("level")] = QStringLiteral("warning");
output[QStringLiteral("message")] = i18nc("An advice", "You saved up %1 year’s worth of expenses. You should continue your effort.", SKGServices::intToString(pfs));
output[QStringLiteral("color")] = scheme.foreground(KColorScheme::NeutralText).color().name().right(6);
} else if (pfs >= 1) {
output[QStringLiteral("level")] = QStringLiteral("warning");
output[QStringLiteral("message")] = i18nc("An advice", "You saved up one year’s worth of expenses. You should maintain your effort.");
output[QStringLiteral("color")] = scheme.foreground(KColorScheme::NeutralText).color().name().right(6);
} else {
output[QStringLiteral("level")] = QStringLiteral("warning");
output[QStringLiteral("message")] = i18nc("An advice", "You do not have debt but you have no margin. You must maintain your effort.");
output[QStringLiteral("color")] = scheme.foreground(KColorScheme::NeutralText).color().name().right(6);
}
return output;
}
double SKGReportBank::getPersonalFinanceScore(bool iTransfer, bool iTracker)
{
double as = getAnnualSpending(iTransfer, iTracker);
return (as == 0.0 ? 0.0 : getNetWorth(iTransfer, iTracker) / as);
}
double SKGReportBank::getAnnualSpending(bool iTransfer, bool iTracker)
{
QString cacheId = QStringLiteral("getAnnualSpending-") % (iTransfer ? QStringLiteral("Y") : QStringLiteral("N")) % (iTracker ? QStringLiteral("Y") : QStringLiteral("N"));
double output = m_cache.value(cacheId).toDouble();
if (!m_cache.contains(cacheId)) {
SKGTRACEINFUNC(10)
auto* doc = qobject_cast<SKGDocumentBank*>(m_document);
if (doc != nullptr) {
QString result;
QDate d2 = SKGServices::periodToDate(getPeriod());
QDate d1 = d2.addYears(-1);
doc->executeSingleSelectSqliteOrder("SELECT TOTAL(f_REALCURRENTAMOUNT) FROM v_suboperation_consolidated WHERE d_date BETWEEN '" %
SKGServices::dateToSqlString(d1) % "' AND '" % SKGServices::dateToSqlString(d2) %
"' AND t_TYPEEXPENSE='-'"
% (iTransfer ? "" : " AND t_TRANSFER='N'")
% (iTracker ? "" : " AND t_REFUND=''")
, result);
output = -SKGServices::stringToDouble(result);
m_cache[cacheId] = output;
}
}
return output;
}
double SKGReportBank::getNetWorth(bool iTransfer, bool iTracker)
{
QString cacheId = QStringLiteral("getNetWorth-") % (iTransfer ? QStringLiteral("Y") : QStringLiteral("N")) % (iTracker ? QStringLiteral("Y") : QStringLiteral("N"));
double output = m_cache.value(cacheId).toDouble();
if (!m_cache.contains(cacheId)) {
SKGTRACEINFUNC(10)
auto* doc = qobject_cast<SKGDocumentBank*>(m_document);
if (doc != nullptr) {
QString result;
QDate d = SKGServices::periodToDate(getPeriod());
doc->executeSingleSelectSqliteOrder("SELECT TOTAL(f_REALCURRENTAMOUNT) FROM v_suboperation_consolidated WHERE d_date<='" %
SKGServices::dateToSqlString(d) % "' "
% (iTransfer ? "" : " AND t_TRANSFER='N'")
% (iTracker ? "" : " AND t_REFUND=''")
, result);
output = SKGServices::stringToDouble(result);
m_cache[cacheId] = output;
}
}
return output;
}
QVariantList SKGReportBank::getIncomeVsExpenditure(bool iOnSubOperation, bool iGrouped, bool iTransfer, bool iTracker, const QString& iWhereClause1, const QString& iWhereClause2)
{
QString cacheId = QStringLiteral("getIncomeVsExpenditure-") % (iOnSubOperation ? QStringLiteral("Y") : QStringLiteral("N")) % (iGrouped ? QStringLiteral("Y") : QStringLiteral("N")) % (iTransfer ? QStringLiteral("Y") : QStringLiteral("N")) % (iTracker ? QStringLiteral("Y") : QStringLiteral("N")) % iWhereClause1 % iWhereClause2;
QVariantList table = m_cache.value(cacheId).toList();
if (table.isEmpty()) {
SKGTRACEINFUNC(10)
auto* doc = qobject_cast<SKGDocumentBank*>(m_document);
if (doc != nullptr) {
QString tableDb = (iOnSubOperation ? QStringLiteral("v_suboperation_consolidated") : QStringLiteral("v_operation_display"));
QString amount = (iOnSubOperation ? QStringLiteral("f_REALCURRENTAMOUNT") : QStringLiteral("f_CURRENTAMOUNT"));
SKGStringListList listTmp;
QString wc1 = iWhereClause1;
if (wc1.isEmpty()) {
wc1 = SKGServices::getPeriodWhereClause(getPeriod());
}
QString wc2 = iWhereClause2;
if (wc2.isEmpty()) {
wc2 = SKGServices::getPeriodWhereClause(getPreviousPeriod());
}
SKGError err = doc->executeSelectSqliteOrder(
"SELECT TOTAL(" % amount % "), '1' from " % tableDb % " WHERE " % wc1 % " AND t_TYPEACCOUNT<>'L'"
% (iGrouped ? "" : " AND i_group_id=0")
% (iTransfer ? "" : " AND t_TRANSFER='N'")
% (iTracker ? "" : (iOnSubOperation ? " AND t_REALREFUND=''" : " AND t_REFUND=''"))
% " group by t_TYPEEXPENSE "
% " UNION ALL "
% "SELECT TOTAL(" % amount % "), '2' from " % tableDb % " WHERE " % wc2 % " AND t_TYPEACCOUNT<>'L'"
% (iGrouped ? "" : " AND i_group_id=0")
% (iTransfer ? "" : " AND t_TRANSFER='N'")
% (iTracker ? "" : (iOnSubOperation ? " AND t_REALREFUND=''" : " AND t_REFUND=''"))
% " group by t_TYPEEXPENSE ",
listTmp);
IFOK(err) {
double income_previous_period = 0;
double expense_previous_period = 0;
double income_period = 0;
double expense_period = 0;
int nbval = listTmp.count();
for (int i = 1; i < nbval; ++i) { // Ignore header
QString m = listTmp.at(i).at(1);
double v = SKGServices::stringToDouble(listTmp.at(i).at(0));
if (v > 0 && m == QStringLiteral("1")) {
income_period = v;
} else if (v < 0 && m == QStringLiteral("1")) {
expense_period = v;
} else if (v > 0 && m == QStringLiteral("2")) {
income_previous_period = v;
} else if (v < 0 && m == QStringLiteral("2")) {
expense_previous_period = v;
}
}
double saving_previous_period = income_previous_period + expense_previous_period;
double saving_period = income_period + expense_period;
table.push_back(QVariantList() << QStringLiteral("sum") << QLatin1String("") << getPreviousPeriod() << getPeriod() << QStringLiteral("max"));
table.push_back(QVariantList() << false << doc->getDisplay(QStringLiteral("f_CURRENTAMOUNT_INCOME")) << qAbs(income_previous_period) << qAbs(income_period));
table.push_back(QVariantList() << false << doc->getDisplay(QStringLiteral("f_CURRENTAMOUNT_EXPENSE")) << qAbs(expense_previous_period) << qAbs(expense_period));
table.push_back(QVariantList() << true << i18nc("Noun", "Savings possible") << saving_previous_period << saving_period);
table.push_back(QVariantList() << true << i18nc("Noun", "Max") << qMax(qAbs(income_previous_period), qAbs(expense_previous_period)) << qMax(qAbs(income_period), qAbs(expense_period)));
}
m_cache[cacheId] = table;
}
}
return table;
}
void SKGReportBank::addItemsInMapping(QVariantHash& iMapping)
{
SKGReport::addItemsInMapping(iMapping);
iMapping.insert(QStringLiteral("about_forumpage"), QStringLiteral("http://forum.kde.org/viewforum.php?f=210"));
- iMapping.insert(QStringLiteral("about_newspage"), QStringLiteral("http://skrooge.org/news"));
+ iMapping.insert(QStringLiteral("about_newspage"), QStringLiteral("https://skrooge.org/news"));
iMapping.insert(QStringLiteral("about_operationpage"), QStringLiteral("skg://Skrooge_operation_plugin/"));
iMapping.insert(QStringLiteral("about_accountpage"), QStringLiteral("skg://Skrooge_bank_plugin/"));
iMapping.insert(QStringLiteral("about_importurl"), QStringLiteral("skg://import_operation/"));
iMapping.insert(QStringLiteral("about_maintext"), i18nc("The main text of skrooge",
"Skrooge allows you to keep a hold on your expenses, by tracking and budgeting them.<br/>"
"What should you do now ?<br/>"
"<ul>"
"<li>Create at least one <a href=\"%1\">account</a></li>"
"<li>Add some operations, using <a href=\"%3\">import</a> or <a href=\"%2\">manual input</a></li>"
"<li>Categorize them</li>"
"</ul>"
"<p>You may come back to this page any time by closing all tabs.<br/>"
"For more information about using Skrooge, check the <a href=\"http://skrooge.org\">Skrooge website</a>.</p>"
"<p>We hope that you will enjoy Skrooge</p>"
" The Skrooge Team",
iMapping[QStringLiteral("about_accountpage")].toString(), iMapping[QStringLiteral("about_operationpage")].toString(), iMapping[QStringLiteral("about_importurl")].toString()));
iMapping.insert(QStringLiteral("logo"), QUrl::fromLocalFile(QStandardPaths::locate(QStandardPaths::GenericDataLocation, QStringLiteral("icons/breeze/apps/48/skrooge.svg"))).url());
iMapping.insert(QStringLiteral("logo_black"), QUrl::fromLocalFile(QStandardPaths::locate(QStandardPaths::GenericDataLocation, QStringLiteral("icons/breeze/apps/48/skrooge-black.svg"))).url());
iMapping.insert(QStringLiteral("title_main"), i18nc("A monthly report title", "Report for %1", getPeriod()));
iMapping.insert(QStringLiteral("title_budget"), i18nc("A monthly report title", "Budget"));
iMapping.insert(QStringLiteral("title_main_categories"), i18nc("A monthly report title", "5 main categories of expenditure"));
iMapping.insert(QStringLiteral("title_variations"), i18nc("A monthly report title", "5 main variations"));
iMapping.insert(QStringLiteral("title_account"), i18nc("A monthly report title", "Amounts in accounts"));
iMapping.insert(QStringLiteral("title_unit"), i18nc("A monthly report title", "Amounts of units"));
iMapping.insert(QStringLiteral("title_advice"), i18nc("A monthly report title", "Advice"));
iMapping.insert(QStringLiteral("title_portfolio"), i18nc("A monthly report title", "Stock portfolio"));
iMapping.insert(QStringLiteral("title_interests"), i18nc("A monthly report title", "Estimated interests"));
iMapping.insert(QStringLiteral("title_alarms"), i18nc("A monthly report title", "Alarms"));
iMapping.insert(QStringLiteral("title_highlighted"), i18nc("A monthly report title", "Highlighted operations"));
iMapping.insert(QStringLiteral("title_networth"), i18nc("A monthly report title", "Net Worth"));
iMapping.insert(QStringLiteral("title_annual_spending"), i18nc("A monthly report title", "Annual Spending"));
iMapping.insert(QStringLiteral("title_personal_finance_score"), i18nc("A monthly report title", "Personal Finance Score"));
iMapping.insert(QStringLiteral("msg_no_variation"), i18nc("A monthly report message", "No variation found."));
iMapping.insert(QStringLiteral("msg_no_scheduled"), i18nc("A monthly report message", R"(No scheduled operations defined on the "<a href="%1">Scheduled operations</a>" page.)", "skg://Skrooge_scheduled_plugin/"));
iMapping.insert(QStringLiteral("msg_no_highlighted"), i18nc("A monthly report message", R"(No highlighted operations defined on the "<a href="%1">Operations</a>" page.)", "skg://Skrooge_operation_plugin/"));
iMapping.insert(QStringLiteral("msg_no_budget"), i18nc("A monthly report message", R"(No budget defined on the "<a href="%1">Budget</a>" page.)", "skg://Skrooge_budget_plugin/"));
iMapping.insert(QStringLiteral("msg_no_share"), i18nc("A monthly report message", R"(No share defined on the "<a href="%1">Unit</a>" page.)", "skg://Skrooge_unit_plugin/"));
iMapping.insert(QStringLiteral("msg_amount_unit_date"), i18nc("A monthly report message", "All amounts are calculated using the unit rates of the last day of the corresponding period."));
}
diff --git a/skgbankmodeler/skgreportbank.h b/skgbankmodeler/skgreportbank.h
index 0d6ed94d4..39cbc800b 100644
--- a/skgbankmodeler/skgreportbank.h
+++ b/skgbankmodeler/skgreportbank.h
@@ -1,315 +1,315 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGREPORTBANK_H
#define SKGREPORTBANK_H
/** @file
* A report class for bank document
*
* @author Stephane MANKOWSKI
*/
#include <qvariant.h>
#include "skgbankmodeler_export.h"
#include "skgerror.h"
#include "skgreport.h"
#include "skgunitobject.h"
class SKGDocument;
/**
* A report class for bank document
*/
class SKGBANKMODELER_EXPORT SKGReportBank : public SKGReport
{
Q_OBJECT
/**
* The budget table
* WARNING: Notification is launched only when cleanCache or setPeriod are called. So do not forget to connect cleanCache with SKGDocument::transactionSuccessfullyEnded
*/
Q_PROPERTY(QVariantList budget_table READ getBudgetTable NOTIFY changed2)
/**
* The unit table
* WARNING: Notification is launched only when cleanCache or setPeriod are called. So do not forget to connect cleanCache with SKGDocument::transactionSuccessfullyEnded
*/
Q_PROPERTY(QVariantList unit_table READ getUnitTable NOTIFY changed2)
/**
* The portfolio
* WARNING: Notification is launched only when cleanCache or setPeriod are called. So do not forget to connect cleanCache with SKGDocument::transactionSuccessfullyEnded
*/
Q_PROPERTY(QVariantList portfolio READ getPortfolio NOTIFY changed2)
/**
* The account table
* WARNING: Notification is launched only when cleanCache or setPeriod are called. So do not forget to connect cleanCache with SKGDocument::transactionSuccessfullyEnded
*/
Q_PROPERTY(QVariantList account_table READ getAccountTable NOTIFY changed2)
/**
* The bank table
* WARNING: Notification is launched only when cleanCache or setPeriod are called. So do not forget to connect cleanCache with SKGDocument::transactionSuccessfullyEnded
*/
Q_PROPERTY(QVariantList bank_table READ getBankTable NOTIFY changed2)
/**
* The alarms
* WARNING: Notification is launched only when cleanCache or setPeriod are called. So do not forget to connect cleanCache with SKGDocument::transactionSuccessfullyEnded
*/
Q_PROPERTY(QVariantList alarms READ getAlarms NOTIFY changed2)
/**
* The interests
* WARNING: Notification is launched only when cleanCache or setPeriod are called. So do not forget to connect cleanCache with SKGDocument::transactionSuccessfullyEnded
*/
Q_PROPERTY(QVariantList interests READ getInterests NOTIFY changed2)
/**
* The scheduled operations
* WARNING: Notification is launched only when cleanCache or setPeriod are called. So do not forget to connect cleanCache with SKGDocument::transactionSuccessfullyEnded
*/
Q_PROPERTY(QVariantList scheduled_operations READ getScheduledOperations NOTIFY changed2)
/**
* The main categories of the period
* WARNING: Notification is launched only when cleanCache or setPeriod are called. So do not forget to connect cleanCache with SKGDocument::transactionSuccessfullyEnded
*/
Q_PROPERTY(QVariantList categories_period READ getMainCategoriesForPeriod NOTIFY changed2)
/**
* The main categories of the previous period
* WARNING: Notification is launched only when cleanCache or setPeriod are called. So do not forget to connect cleanCache with SKGDocument::transactionSuccessfullyEnded
*/
Q_PROPERTY(QVariantList categories_previous_period READ getMainCategoriesForPreviousPeriod NOTIFY changed2)
/**
* The main categories of the period (for compatibility)
* WARNING: Notification is launched only when cleanCache or setPeriod are called. So do not forget to connect cleanCache with SKGDocument::transactionSuccessfullyEnded
*/
Q_PROPERTY(QVariantList categories_month READ getMainCategoriesForPeriod NOTIFY changed2)
/**
* The main categories of the previous period (for compatibility)
* WARNING: Notification is launched only when cleanCache or setPeriod are called. So do not forget to connect cleanCache with SKGDocument::transactionSuccessfullyEnded
*/
Q_PROPERTY(QVariantList categories_previous_month READ getMainCategoriesForPreviousPeriod NOTIFY changed2)
/**
* The income versus expenditure
* WARNING: Notification is launched only when cleanCache or setPeriod are called. So do not forget to connect cleanCache with SKGDocument::transactionSuccessfullyEnded
*/
Q_PROPERTY(QVariantList income_vs_expenditure READ getIncomeVsExpenditure NOTIFY changed2)
/**
* The net worth
* WARNING: Notification is launched only when cleanCache or setPeriod are called. So do not forget to connect cleanCache with SKGDocument::transactionSuccessfullyEnded
*/
Q_PROPERTY(double networth READ getNetWorth NOTIFY changed2)
/**
* The annual spending
* WARNING: Notification is launched only when cleanCache or setPeriod are called. So do not forget to connect cleanCache with SKGDocument::transactionSuccessfullyEnded
*/
Q_PROPERTY(double annual_spending READ getAnnualSpending NOTIFY changed2)
/**
* The personal finance score
* WARNING: Notification is launched only when cleanCache or setPeriod are called. So do not forget to connect cleanCache with SKGDocument::transactionSuccessfullyEnded
*/
Q_PROPERTY(double personal_finance_score READ getPersonalFinanceScore NOTIFY changed2)
/**
* The personal finance score details
* WARNING: Notification is launched only when cleanCache or setPeriod are called. So do not forget to connect cleanCache with SKGDocument::transactionSuccessfullyEnded
*/
Q_PROPERTY(QVariantMap personal_finance_score_details READ getPersonalFinanceScoreDetails NOTIFY changed2)
/**
* The main categories variations
* WARNING: Notification is launched only when cleanCache or setPeriod are called. So do not forget to connect cleanCache with SKGDocument::transactionSuccessfullyEnded
*/
Q_PROPERTY(QStringList categories_variations READ get5MainCategoriesVariation NOTIFY changed2)
/**
* The main categories variations which are issues (expenditure increasing or incomes decreasing
* WARNING: Notification is launched only when cleanCache or setPeriod are called. So do not forget to connect cleanCache with SKGDocument::transactionSuccessfullyEnded
*/
Q_PROPERTY(QStringList categories_variations_issues READ get5MainCategoriesVariationIssue NOTIFY changed2)
public:
/**
* Default Constructor
*/
explicit SKGReportBank(SKGDocument* iDocument);
/**
* Default Destructor
*/
~SKGReportBank() override;
/**
* Get the budget table
* @return the budget table
*/
Q_INVOKABLE virtual QVariantList getBudgetTable();
/**
* Get the unit table
* @return the unit table
*/
Q_INVOKABLE virtual QVariantList getUnitTable();
/**
* Get the portfolio
* @return the portfolio
*/
Q_INVOKABLE virtual QVariantList getPortfolio();
/**
* Get the account table
* @return the account table
*/
Q_INVOKABLE virtual QVariantList getAccountTable();
/**
* Get the bank table
* @return the bank table
*/
Q_INVOKABLE virtual QVariantList getBankTable();
/**
* Get the scheduled operations
* Parameters supported:
* scheduled_operation_days_max: number max of days displayed (default: 30)
* @return the scheduled operations
*/
Q_INVOKABLE virtual QVariantList getScheduledOperations();
/**
* Get the main categories of the period
* @return the main categories of the period
*/
Q_INVOKABLE virtual QVariantList getMainCategoriesForPeriod();
/**
* Get the main categories of the previous period
* @return the main categories of the previous period
*/
Q_INVOKABLE virtual QVariantList getMainCategoriesForPreviousPeriod();
/**
* Get the main categories variations
* @return the main categories variations
*/
Q_INVOKABLE virtual QStringList get5MainCategoriesVariation();
/**
* Get the main categories variations which are issues (expenditure increasing or incomes decreasing)
* @return the main categories variations
*/
Q_INVOKABLE virtual QStringList get5MainCategoriesVariationIssue();
/**
* Get the income versus expenditure
* @param iOnSubOperation the computation is done on sub operation
* @param iGrouped the computation includes grouped (sub) operation
* @param iTransfer the computation includes Transfers
* @param iTracker the computation includes tracked operations
* @param iWhereClause1 the period where clause (if empty then use the period of the report)
* @param iWhereClause2 the period where clause (if empty then use the previous period of the report)
* @return the income versus expenditure
*/
Q_INVOKABLE virtual QVariantList getIncomeVsExpenditure(bool iOnSubOperation = true,
bool iGrouped = true,
bool iTransfer = false,
bool iTracker = true,
const QString& iWhereClause1 = QString(),
const QString& iWhereClause2 = QString());
/**
* Get the net worth
* @param iTransfer the computation includes Transfers
* @param iTracker the computation includes tracked operations
* @return the net worth
*/
Q_INVOKABLE virtual double getNetWorth(bool iTransfer = false, bool iTracker = true);
/**
* Get the annual spending
* @param iTransfer the computation includes Transfers
* @param iTracker the computation includes tracked operations
* @return the annual spending
*/
Q_INVOKABLE virtual double getAnnualSpending(bool iTransfer = false, bool iTracker = true);
/**
* Get the personal finance score (https://jlyblog.wordpress.com/2013/10/13/the-new-score-that-outweighs-your-credit-score/)
* @param iTransfer the computation includes Transfers
* @param iTracker the computation includes tracked operations
* @return the personal finance score
*/
Q_INVOKABLE virtual double getPersonalFinanceScore(bool iTransfer = false, bool iTracker = true);
/**
* Get the personal finance score (https://jlyblog.wordpress.com/2013/10/13/the-new-score-that-outweighs-your-credit-score/)
* @param iTransfer the computation includes Transfers
* @param iTracker the computation includes tracked operations
* @return the personal finance score + (success, warning or danger) + advice string + color
*/
Q_INVOKABLE virtual QVariantMap getPersonalFinanceScoreDetails(bool iTransfer = false, bool iTracker = true);
/**
* Get the alarms
* @return the alarms
*/
Q_INVOKABLE virtual QVariantList getAlarms();
/**
* Get the interests
* @return the interests
*/
Q_INVOKABLE virtual QVariantList getInterests();
Q_SIGNALS:
/**
* Emitted when the report changed
*/
void changed2();
protected:
/**
* Enrich the grantlee mapping
* @param iMapping the mapping
*/
void addItemsInMapping(QVariantHash& iMapping) override;
private:
Q_DISABLE_COPY(SKGReportBank)
struct unitValues {
SKGUnitObject unit;
double initalAmount{};
double purchaseAmount{};
double currentAmount{};
double quantity{};
};
};
/**
* Declare the class
*/
Q_DECLARE_TYPEINFO(SKGReportBank, Q_MOVABLE_TYPE);
#endif // SKGREPORTBANK_H
diff --git a/skgbankmodeler/skgruleobject.cpp b/skgbankmodeler/skgruleobject.cpp
index 4e8710731..94b38dcf7 100644
--- a/skgbankmodeler/skgruleobject.cpp
+++ b/skgbankmodeler/skgruleobject.cpp
@@ -1,866 +1,866 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file defines classes SKGRuleObject.
*
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgruleobject.h"
#include <klocalizedstring.h>
#include <qdom.h>
#include "skgdocumentbank.h"
#include "skgoperationobject.h"
#include "skgtraces.h"
#include "skgtransactionmng.h"
#include "skgunitvalueobject.h"
SKGRuleObject::SKGRuleObject() : SKGRuleObject(nullptr)
{}
SKGRuleObject::SKGRuleObject(SKGDocument* iDocument, int iID) : SKGObjectBase(iDocument, QStringLiteral("v_rule"), iID)
{}
SKGRuleObject::SKGRuleObject(const SKGRuleObject& iObject) = default;
SKGRuleObject::SKGRuleObject(const SKGObjectBase& iObject)
{
if (iObject.getRealTable() == QStringLiteral("rule")) {
copyFrom(iObject);
} else {
*this = SKGObjectBase(iObject.getDocument(), QStringLiteral("v_rule"), iObject.getID());
}
}
SKGRuleObject& SKGRuleObject::operator= (const SKGObjectBase& iObject)
{
copyFrom(iObject);
return *this;
}
SKGRuleObject::~SKGRuleObject()
= default;
QString SKGRuleObject::getDisplayName() const
{
return getSearchDescription();
}
SKGError SKGRuleObject::bookmark(bool iBookmark)
{
return setAttribute(QStringLiteral("t_bookmarked"), iBookmark ? QStringLiteral("Y") : QStringLiteral("N"));
}
bool SKGRuleObject::isBookmarked() const
{
return getAttribute(QStringLiteral("t_bookmarked")) == QStringLiteral("Y");
}
SKGError SKGRuleObject::save(bool iInsertOrUpdate, bool iReloadAfterSave)
{
// Do the save
SKGError err = SKGObjectBase::save(iInsertOrUpdate, iReloadAfterSave);
// Raise alarm
if (!err && getActionType() == ALARM) {
err = execute();
}
return err;
}
SKGError SKGRuleObject::setXMLSearchDefinition(const QString& iXml)
{
setSearchDescription(SKGRuleObject::getDescriptionFromXML(getDocument(), iXml, false, SEARCH));
return setAttribute(QStringLiteral("t_definition"), iXml);
}
QString SKGRuleObject::getXMLSearchDefinition() const
{
return getAttribute(QStringLiteral("t_definition"));
}
SKGError SKGRuleObject::setXMLActionDefinition(const QString& iXml)
{
setActionDescription(SKGRuleObject::getDescriptionFromXML(getDocument(), iXml, false, getActionType()));
return setAttribute(QStringLiteral("t_action_definition"), iXml);
}
QString SKGRuleObject::getXMLActionDefinition() const
{
return getAttribute(QStringLiteral("t_action_definition"));
}
SKGError SKGRuleObject::setSearchDescription(const QString& iDescription)
{
return setAttribute(QStringLiteral("t_description"), iDescription);
}
QString SKGRuleObject::getSearchDescription() const
{
return getAttribute(QStringLiteral("t_description"));
}
SKGError SKGRuleObject::setActionDescription(const QString& iDescription)
{
return setAttribute(QStringLiteral("t_action_description"), iDescription);
}
QString SKGRuleObject::getActionDescription() const
{
return getAttribute(QStringLiteral("t_action_description"));
}
SKGError SKGRuleObject::setActionType(SKGRuleObject::ActionType iType)
{
SKGError err = setAttribute(QStringLiteral("t_action_type"),
(iType == SEARCH ? QStringLiteral("S") :
(iType == UPDATE ? QStringLiteral("U") :
(iType == APPLYTEMPLATE ? QStringLiteral("T") :
QStringLiteral("A")))));
return err;
}
SKGRuleObject::ActionType SKGRuleObject::getActionType() const
{
QString typeString = getAttribute(QStringLiteral("t_action_type"));
return (typeString == QStringLiteral("S") ? SEARCH :
(typeString == QStringLiteral("U") ? UPDATE :
(typeString == QStringLiteral("T") ? APPLYTEMPLATE :
ALARM)));
}
SKGError SKGRuleObject::setOrder(double iOrder)
{
SKGError err;
double order = iOrder;
if (order == -1) {
order = 1;
SKGStringListList result;
err = getDocument()->executeSelectSqliteOrder(QStringLiteral("SELECT max(f_sortorder) from rule"), result);
if (!err && result.count() == 2) {
order = SKGServices::stringToDouble(result.at(1).at(0)) + 1;
}
}
IFOKDO(err, setAttribute(QStringLiteral("f_sortorder"), SKGServices::doubleToString(order)))
return err;
}
QString SKGRuleObject::getSelectSqlOrder(const QString& iAdditionalCondition) const
{
QString wc = iAdditionalCondition;
QString wc2 = SKGRuleObject::getDescriptionFromXML(getDocument(), getXMLSearchDefinition(), true, SEARCH);
if (!wc2.isEmpty()) {
if (wc.isEmpty()) {
wc = wc2;
} else {
wc = '(' % wc % ") AND (" % wc2 % ')';
}
}
if (wc.isEmpty()) {
wc = QStringLiteral("1=1");
}
wc = "t_template='N' AND d_date!='0000-00-00' AND (" % wc % ')';
return wc;
}
SKGRuleObject::SKGAlarmInfo SKGRuleObject::getAlarmInfo() const
{
SKGTRACEINFUNC(10)
SKGRuleObject::SKGAlarmInfo alarm;
alarm.Raised = false;
alarm.Message = QLatin1String("");
alarm.Amount = 0.0;
alarm.Limit = 0.0;
if (getActionType() == SKGRuleObject::ALARM) {
// Alarm mode
QString wc = getSelectSqlOrder();
if (wc.isEmpty()) {
wc = QStringLiteral("1=1");
}
SKGDocument* doc = getDocument();
QStringList list = SKGRuleObject::getFromXML(doc, getXMLActionDefinition(), true, ALARM, false);
if (!list.isEmpty()) {
QString sql = list.at(0);
sql.replace(QStringLiteral("#WC#"), wc);
SKGStringListList result;
doc->executeSelectSqliteOrder(sql, result);
if (result.count() == 2) {
const auto& r = result.at(1);
alarm.Raised = (r.at(0) == QStringLiteral("1"));
alarm.Message = r.at(3);
alarm.Amount = SKGServices::stringToDouble(r.at(1));
alarm.Limit = SKGServices::stringToDouble(r.at(2));
}
}
}
return alarm;
}
SKGError SKGRuleObject::execute(ProcessMode iMode)
{
SKGError err;
SKGTRACEINFUNCRC(10, err)
if (getActionType() == SKGRuleObject::UPDATE) {
// Update mode
QString addSql;
if (iMode == IMPORTED) {
addSql = QStringLiteral("t_imported!='N'");
} else if (iMode == IMPORTEDNOTVALIDATE) {
addSql = QStringLiteral("t_imported='P'");
} else if (iMode == IMPORTING) {
addSql = QStringLiteral("t_imported='T'");
} else if (iMode == NOTCHECKED) {
addSql = QStringLiteral("t_status!='Y'");
}
QString wc = getSelectSqlOrder(addSql);
SKGDocument* doc = getDocument();
if (doc != nullptr) {
QStringList list = SKGRuleObject::getFromXML(doc, getXMLActionDefinition(), true, UPDATE, true); // SQL + SET clause
int nb = list.count();
err = doc->beginTransaction("#INTERNAL#" % i18nc("Progression step", "Apply rule"), nb);
IFOK(err) {
// All sql orders must be executed to be sure than i_tmp is reset
SKGError err2;
for (int i = 0; i < nb; ++i) {
QString sql = list.at(i);
sql.replace(QStringLiteral("#WC#"), wc);
err2 = doc->executeSqliteOrder(sql);
if (!err2) {
err2 = doc->stepForward(i + 1);
}
if (err2 && !err) {
err = err2;
}
}
}
IFOK(err) {
SKGStringListList result;
err = doc->executeSelectSqliteOrder(QStringLiteral("SELECT changes()"), result);
if (!err && result.count() == 2) {
int nbChanges = SKGServices::stringToInt(result.at(1).at(0));
if (nbChanges != 0) {
doc->sendMessage(i18np("1 operation modified by %2", "%1 operations modified by %2", nbChanges, getAttribute(QStringLiteral("i_ORDER"))));
}
}
}
SKGENDTRANSACTION(doc, err)
}
} else if (getActionType() == SKGRuleObject::ALARM) {
// Alarm mode
auto doc = qobject_cast<SKGDocumentBank*>(getDocument());
if (doc != nullptr) {
SKGRuleObject::SKGAlarmInfo alarm = getAlarmInfo();
if (!alarm.Message.isEmpty()) {
SKGServices::SKGUnitInfo unit = doc->getPrimaryUnit();
// Build the message
if (alarm.Message.contains(QLatin1String("%3"))) {
alarm.Message = alarm.Message.arg(doc->formatMoney(alarm.Amount, unit, false), doc->formatMoney(alarm.Limit, unit, false), doc->formatMoney(alarm.Amount - alarm.Limit, unit, false));
} else if (alarm.Message.contains(QLatin1String("%2"))) {
alarm.Message = alarm.Message.arg(doc->formatMoney(alarm.Amount, unit, false), doc->formatMoney(alarm.Limit, unit, false));
} else if (alarm.Message.contains(QLatin1String("%1"))) {
alarm.Message = alarm.Message.arg(doc->formatMoney(alarm.Amount, unit, false));
}
getDocument()->sendMessage(alarm.Message);
}
}
} else if (getActionType() == SKGRuleObject::APPLYTEMPLATE) {
// Template mode
QString addSql;
if (iMode == IMPORTED) {
addSql = QStringLiteral("t_imported!='N'");
} else if (iMode == IMPORTEDNOTVALIDATE) {
addSql = QStringLiteral("t_imported='P'");
} else if (iMode == IMPORTING) {
addSql = QStringLiteral("t_imported='T'");
}
QString wc = getSelectSqlOrder(addSql);
auto doc = qobject_cast<SKGDocumentBank*>(getDocument());
if (doc != nullptr) {
QStringList list = SKGRuleObject::getFromXML(doc, getXMLActionDefinition(), true, APPLYTEMPLATE, false);
if (!list.isEmpty()) {
const QString& id = list.at(0);
// Get template
SKGOperationObject templateToApply(doc, SKGServices::stringToInt(id));
// Get operations to modify
SKGObjectBase::SKGListSKGObjectBase objectsToModify;
IFOKDO(err, doc->getObjects(QStringLiteral("v_operation_prop"), wc, objectsToModify))
int nb = objectsToModify.count();
for (int i = 0; !err && i < nb; ++i) {
SKGOperationObject operationObj(doc, SKGServices::stringToInt(objectsToModify.at(i).getAttribute(QStringLiteral("i_OPID"))));
SKGOperationObject op;
IFOKDO(err, templateToApply.duplicate(op))
IFOKDO(err, op.mergeAttribute(operationObj, SKGOperationObject::PROPORTIONAL, false))
}
}
}
}
IFKO(err) err.addError(ERR_FAIL, i18nc("Error message", "Rule %1 failed", getAttribute(QStringLiteral("i_ORDER"))));
return err;
}
double SKGRuleObject::getOrder() const
{
return SKGServices::stringToDouble(getAttribute(QStringLiteral("f_sortorder")));
}
QString SKGRuleObject::getDisplayForOperator(const QString& iOperator, const QString& iParam1, const QString& iParam2, const QString& iAtt2)
{
QString output = iOperator;
if (output == QStringLiteral("#ATT# LIKE '%#V1S#%'")) {
output = i18nc("Description of a condition. Do not translate key words (#V1S#, #V1#, ...)", "contains '#V1S#'").replace(QStringLiteral("#V1S#"), iParam1);
} else if (output == QStringLiteral("#ATT# NOT LIKE '%#V1S#%'")) {
output = i18nc("Description of a condition. Do not translate key words (#V1S#, #V1#, ...)", "does not contain '#V1S#'").replace(QStringLiteral("#V1S#"), iParam1);
} else if (output == QStringLiteral("#ATT# LIKE '#V1S#%'")) {
output = i18nc("Description of a condition. Do not translate key words (#V1S#, #V1#, ...)", "starts with '#V1S#'").replace(QStringLiteral("#V1S#"), iParam1);
} else if (output == QStringLiteral("#ATT# NOT LIKE '#V1S#%'")) {
output = i18nc("Description of a condition. Do not translate key words (#V1S#, #V1#, ...)", "does not start with '#V1S#'").replace(QStringLiteral("#V1S#"), iParam1);
} else if (output == QStringLiteral("#ATT# LIKE '%#V1S#'")) {
output = i18nc("Description of a condition. Do not translate key words (#V1S#, #V1#, ...)", "ends with '#V1S#'").replace(QStringLiteral("#V1S#"), iParam1);
} else if (output == QStringLiteral("#ATT# NOT LIKE '%#V1S#'")) {
output = i18nc("Description of a condition. Do not translate key words (#V1S#, #V1#, ...)", "does not end with '#V1S#'").replace(QStringLiteral("#V1S#"), iParam1);
} else if (output == QStringLiteral("#ATT#=''")) {
output = i18nc("Description of a condition. Do not translate key words (#V1S#, #V1#, ...)", "is empty");
} else if (output == QStringLiteral("#ATT#!=''")) {
output = i18nc("Description of a condition. Do not translate key words (#V1S#, #V1#, ...)", "is not empty");
} else if (output == QStringLiteral("#ATT#=REGEXPCAPTURE('#V1S#', #ATT2#, #V2#)")) {
output = i18nc("Description of a condition. Do not translate key words (#V1S#, #V1#, ...)", "=regexpcapture(#ATT2#, '#V1S#', #V2#)").replace(QStringLiteral("#V1S#"), iParam1).replace(QStringLiteral("#V2#"), iParam2).replace(QStringLiteral("#ATT2#"), iAtt2);
} else if (output == QStringLiteral("REGEXP('#V1S#', #ATT#)")) {
output = i18nc("Description of a condition. Do not translate key words (#V1S#, #V1#, ...)", "regexp '#V1S#'").replace(QStringLiteral("#V1S#"), iParam1);
} else if (output == QStringLiteral("NOT(REGEXP('#V1S#', #ATT#))")) {
output = i18nc("Description of a condition. Do not translate key words (#V1S#, #V1#, ...)", "not regexp '#V1S#'").replace(QStringLiteral("#V1S#"), iParam1);
} else if (output == QStringLiteral("WILDCARD('#V1S#', #ATT#)")) {
output = i18nc("Description of a condition. Do not translate key words (#V1S#, #V1#, ...)", "wildcard '#V1S#'").replace(QStringLiteral("#V1S#"), iParam1);
} else if (output == QStringLiteral("NOT(WILDCARD('#V1S#', #ATT#))")) {
output = i18nc("Description of a condition. Do not translate key words (#V1S#, #V1#, ...)", "not wildcard '#V1S#'").replace(QStringLiteral("#V1S#"), iParam1);
} else if (output == QStringLiteral("#ATT#=#V1#")) {
output = i18nc("Description of a condition. Do not translate key words (#V1S#, #V1#, ...)", "=#V1#").replace(QStringLiteral("#V1#"), iParam1);
} else if (output == QStringLiteral("#ATT#!=#V1#")) {
output = i18nc("Description of a condition. Do not translate key words (#V1S#, #V1#, ...)", "!=#V1#").replace(QStringLiteral("#V1#"), iParam1);
} else if (output == QStringLiteral("#ATT#>#V1#")) {
output = i18nc("Description of a condition. Do not translate key words (#V1S#, #V1#, ...)", ">#V1#").replace(QStringLiteral("#V1#"), iParam1);
} else if (output == QStringLiteral("#ATT#<#V1#")) {
output = i18nc("Description of a condition. Do not translate key words (#V1S#, #V1#, ...)", "<#V1#").replace(QStringLiteral("#V1#"), iParam1);
} else if (output == QStringLiteral("#ATT#>=#V1#")) {
output = i18nc("Description of a condition. Do not translate key words (#V1S#, #V1#, ...)", ">=#V1#").replace(QStringLiteral("#V1#"), iParam1);
} else if (output == QStringLiteral("#ATT#<=#V1#")) {
output = i18nc("Description of a condition. Do not translate key words (#V1S#, #V1#, ...)", "<=#V1#").replace(QStringLiteral("#V1#"), iParam1);
} else if (output == QStringLiteral("#ATT#='#V1S#'")) {
output = i18nc("Description of a condition. Do not translate key words (#V1S#, #V1#, ...)", "='#V1S#'").replace(QStringLiteral("#V1S#"), iParam1);
} else if (output == QStringLiteral("#ATT#!='#V1S#'")) {
output = i18nc("Description of a condition. Do not translate key words (#V1S#, #V1#, ...)", "!='#V1S#'").replace(QStringLiteral("#V1S#"), iParam1);
} else if (output == QStringLiteral("#ATT#>'#V1S#'")) {
output = i18nc("Description of a condition. Do not translate key words (#V1S#, #V1#, ...)", ">'#V1S#'").replace(QStringLiteral("#V1S#"), iParam1);
} else if (output == QStringLiteral("#ATT#<'#V1S#'")) {
output = i18nc("Description of a condition. Do not translate key words (#V1S#, #V1#, ...)", "<'#V1S#'").replace(QStringLiteral("#V1S#"), iParam1);
} else if (output == QStringLiteral("#ATT#>='#V1S#'")) {
output = i18nc("Description of a condition. Do not translate key words (#V1S#, #V1#, ...)", ">='#V1S#'").replace(QStringLiteral("#V1S#"), iParam1);
} else if (output == QStringLiteral("#ATT#<='#V1S#'")) {
output = i18nc("Description of a condition. Do not translate key words (#V1S#, #V1#, ...)", "<='#V1S#'").replace(QStringLiteral("#V1S#"), iParam1);
} else if (output == QStringLiteral("#ATT#>=#V1# AND #ATT#<=#V2#")) {
output = i18nc("Description of a condition. Do not translate key words (#V1S#, #V1#, ...)", "is between #V1# and #V2#").replace(QStringLiteral("#V1#"), iParam1).replace(QStringLiteral("#V2#"), iParam2);
} else if (output == QStringLiteral("((#ATT#>='#V1S#' AND #ATT#<='#V2S#') OR (#ATT#>='#V2S#' AND #ATT#<='#V1S#'))")) {
output = i18nc("Description of a condition. Do not translate key words (#V1S#, #V1#, ...)", "is between '#V1S#' and '#V2S#'").replace(QStringLiteral("#V1S#"), iParam1).replace(QStringLiteral("#V2S#"), iParam2);
} else if (output == QStringLiteral("#ATT#=lower(#ATT#)")) {
output = i18nc("Description of a condition. Do not translate key words (#V1S#, #V1#, ...)", "is set to lower");
} else if (output == QStringLiteral("#ATT#=upper(#ATT#)")) {
output = i18nc("Description of a condition. Do not translate key words (#V1S#, #V1#, ...)", "is set to upper");
} else if (output == QStringLiteral("#ATT#=capitalize(#ATT#)")) {
output = i18nc("Description of a condition. Do not translate key words (#V1S#, #V1#, ...)", "is set to capitalize");
} else if (output == QStringLiteral("#ATT#!=lower(#ATT#)")) {
output = i18nc("Description of a condition. Do not translate key words (#V1S#, #V1#, ...)", "is not lower");
} else if (output == QStringLiteral("#ATT#!=upper(#ATT#)")) {
output = i18nc("Description of a condition. Do not translate key words (#V1S#, #V1#, ...)", "is not upper");
} else if (output == QStringLiteral("#ATT#!=capitalize(#ATT#)")) {
output = i18nc("Description of a condition. Do not translate key words (#V1S#, #V1#, ...)", "is not capitalize");
} else if (output == QStringLiteral("#ATT#= lower(#ATT#)")) {
output = i18nc("Description of a condition. Do not translate key words (#V1S#, #V1#, ...)", "is lower");
} else if (output == QStringLiteral("#ATT#= upper(#ATT#)")) {
output = i18nc("Description of a condition. Do not translate key words (#V1S#, #V1#, ...)", "is upper");
} else if (output == QStringLiteral("#ATT#= capitalize(#ATT#)")) {
output = i18nc("Description of a condition. Do not translate key words (#V1S#, #V1#, ...)", "is capitalize");
} else if (output == QStringLiteral("#ATT#=replace(#ATT2#,'#V1S#','#V2S#')")) {
output = i18nc("Description of a condition. Do not translate key words (#V1S#, #V1#, ...)", "=#ATT2# with '#V1S#' replaced by '#V2S#'").replace(QStringLiteral("#V1S#"), iParam1).replace(QStringLiteral("#V2S#"), iParam2).replace(QStringLiteral("#ATT2#"), iAtt2);
} else if (output == QStringLiteral("#ATT#=substr(#ATT2#,'#V1#','#V2#')")) {
output = i18nc("Description of a condition. Do not translate key words (#V1S#, #V1#, ...)", "=substring of #ATT2# from #V1# to #V2#").replace(QStringLiteral("#V1#"), iParam1).replace(QStringLiteral("#V2#"), iParam2).replace(QStringLiteral("#ATT2#"), iAtt2);
} else if (output == QStringLiteral("#ATT#=#ATT2#")) {
output = i18nc("Description of a condition. Do not translate key words (#V1S#, #V1#, ...)", "=#ATT2#").replace(QStringLiteral("#ATT2#"), iAtt2);
} else if (output == QStringLiteral("#ATT#=WORD(#ATT2#,#V1S#)")) {
output = i18nc("Description of a condition. Do not translate key words (#V1S#, #V1#, ...)", "=word(#ATT2#,#V1S#)").replace(QStringLiteral("#ATT2#"), iAtt2).replace(QStringLiteral("#V1S#"), iParam1);
} else if (output == QStringLiteral("#ATT#=todate(#ATT2#,'#DF#')")) {
output = i18nc("Description of a condition. Do not translate key words (#V1S#, #V1#, ...)", "=#ATT2# as date with format #DF#").replace(QStringLiteral("#ATT2#"), iAtt2).replace(QStringLiteral("#DF#"), iParam2);
} else if (output == QStringLiteral("#ATT#=todate(WORD(#ATT2#,#V1S#),'#DF#')")) {
output = i18nc("Description of a condition. Do not translate key words (#V1S#, #V1#, ...)", "=word(#ATT2#,#V1S#) as date with format #DF#").replace(QStringLiteral("#ATT2#"), iAtt2).replace(QStringLiteral("#V1S#"), iParam1).replace(QStringLiteral("#DF#"), iParam2);
} else if (output == QStringLiteral("STRFTIME('%Y-%m',#ATT#)=STRFTIME('%Y-%m',date('now'))")) {
output = i18nc("Description of a condition. Do not translate key words (#V1S#, #V1#, ...)", "is in current month");
} else if (output == QStringLiteral("STRFTIME('%Y-%m',#ATT#)=STRFTIME('%Y-%m',date('now','start of month','-1 month'))")) {
output = i18nc("Description of a condition. Do not translate key words (#V1S#, #V1#, ...)", "is in previous month");
} else if (output == QStringLiteral("STRFTIME('%Y',#ATT#)=STRFTIME('%Y',date('now'))")) {
output = i18nc("Description of a condition. Do not translate key words (#V1S#, #V1#, ...)", "is in current year");
} else if (output == QStringLiteral("STRFTIME('%Y',#ATT#)=STRFTIME('%Y',date('now','start of month','-1 year'))")) {
output = i18nc("Description of a condition. Do not translate key words (#V1S#, #V1#, ...)", "is in previous year");
} else if (output == QStringLiteral("#ATT#>date('now','-30 day') AND #ATT#<=date('now')")) {
output = i18nc("Description of a condition. Do not translate key words (#V1S#, #V1#, ...)", "is in last 30 days");
} else if (output == QStringLiteral("#ATT#>date('now','-3 month') AND #ATT#<=date('now')")) {
output = i18nc("Description of a condition. Do not translate key words (#V1S#, #V1#, ...)", "is in last 3 months");
} else if (output == QStringLiteral("#ATT#>date('now','-6 month') AND #ATT#<=date('now')")) {
output = i18nc("Description of a condition. Do not translate key words (#V1S#, #V1#, ...)", "is in last 6 months");
} else if (output == QStringLiteral("#ATT#>date('now','-12 month') AND #ATT#<=date('now')")) {
output = i18nc("Description of a condition. Do not translate key words (#V1S#, #V1#, ...)", "is in last 12 months");
} else if (output == QStringLiteral("#ATT#>date('now','-2 year') AND #ATT#<=date('now')")) {
output = i18nc("Description of a condition. Do not translate key words (#V1S#, #V1#, ...)", "is in last 2 years");
} else if (output == QStringLiteral("#ATT#>date('now','-3 year') AND #ATT#<=date('now')")) {
output = i18nc("Description of a condition. Do not translate key words (#V1S#, #V1#, ...)", "is in last 3 years");
} else if (output == QStringLiteral("#ATT#>date('now','-5 year') AND #ATT#<=date('now')")) {
output = i18nc("Description of a condition. Do not translate key words (#V1S#, #V1#, ...)", "is in last 5 years");
} else if (output == QStringLiteral("ABS(TOTAL(#ATT#))#OP##V1#,ABS(TOTAL(#ATT#)), #V1#, '#V2S#'")) {
output = i18nc("Description of a condition. Do not translate key words (#V1S#, #V1#, ...)", "If total(#ATT#)#OP##V1# then send '#V2S#'").replace(QStringLiteral("#V1#"), iParam1).replace(QStringLiteral("#V2S#"), iParam2).replace(QStringLiteral("#OP#"), iAtt2);
} else if (output == QStringLiteral("APPLYTEMPLATE(#V1#)")) {
output = i18nc("Description of a condition. Do not translate key words (#V1S#, #V1#, ...)", "Apply the template '#V2S#'").replace(QStringLiteral("#V2S#"), iParam2);
}
return output;
}
QString SKGRuleObject::getToolTipForOperator(const QString& iOperator)
{
QString output = iOperator;
if (output == QStringLiteral("#ATT# LIKE '%#V1S#%'")) {
output = i18nc("Help for a condition", "To find out if the attribute contains a given string");
} else if (output == QStringLiteral("#ATT# NOT LIKE '%#V1S#%'")) {
output = i18nc("Help for a condition", "To find out if the attribute doesn't contain a given string");
} else if (output == QStringLiteral("#ATT# LIKE '#V1S#%'")) {
output = i18nc("Help for a condition", "To find out if the attribute is starting by a given string");
} else if (output == QStringLiteral("#ATT# NOT LIKE '#V1S#%'")) {
output = i18nc("Help for a condition", "To find out if the attribute is not starting by a given string");
} else if (output == QStringLiteral("#ATT# LIKE '%#V1S#'")) {
output = i18nc("Help for a condition", "To find out if the attribute is ending by a given string");
} else if (output == QStringLiteral("#ATT# NOT LIKE '%#V1S#'")) {
output = i18nc("Help for a condition", "To find out if the attribute is not ending by a given string");
} else if (output == QStringLiteral("#ATT#=''")) {
output = i18nc("Help for a condition", "To find out if the attribute is empty");
} else if (output == QStringLiteral("#ATT#!=''")) {
output = i18nc("Help for a condition", "To find out if the attribute is not empty");
} else if (output == QStringLiteral("#ATT#=REGEXPCAPTURE('#V1S#', #ATT2#, #V2#)")) {
output = i18nc("Help for a condition", "To get a captured value by a given regular expression (eg. \"(\\d+)(\\s*)(cm|inch(es)?)\")");
} else if (output == QStringLiteral("REGEXP('#V1S#', #ATT#)")) {
output = i18nc("Help for a condition", "To find out if the attribute is matching a given regular expression (eg. \"^[H,h]ello$\")");
} else if (output == QStringLiteral("NOT(REGEXP('#V1S#', #ATT#))")) {
output = i18nc("Help for a condition", "To find out if the attribute is not matching a given regular expression (eg. \"^[H,h]ello$\")");
} else if (output == QStringLiteral("WILDCARD('#V1S#', #ATT#)")) {
output = i18nc("Help for a condition", "To find out if the attribute is matching a given wildcard expression (eg. \"_ello\")");
} else if (output == QStringLiteral("NOT(WILDCARD('#V1S#', #ATT#))")) {
output = i18nc("Help for a condition", "To find out if the attribute is not matching a given wildcard expression (eg. \"_ello\")");
} else if (output == QStringLiteral("#ATT#=#V1#")) {
output = i18nc("Help for a condition", "To find out if the attribute is equal to a given value");
} else if (output == QStringLiteral("#ATT#!=#V1#")) {
output = i18nc("Help for a condition", "To find out if the attribute is not equal to a given value");
} else if (output == QStringLiteral("#ATT#>#V1#")) {
output = i18nc("Help for a condition", "To find out if the attribute is greater than a given value");
} else if (output == QStringLiteral("#ATT#<#V1#")) {
output = i18nc("Help for a condition", "To find out if the attribute is smaller than a given value");
} else if (output == QStringLiteral("#ATT#>=#V1#")) {
output = i18nc("Help for a condition", "To find out if the attribute is greater or equal to a given value");
} else if (output == QStringLiteral("#ATT#<=#V1#")) {
output = i18nc("Help for a condition", "To set the attribute with a given value");
} else if (output == QStringLiteral("#ATT#='#V1S#'")) {
output = i18nc("Help for a condition", "To find out if the attribute is equal to a given string");
} else if (output == QStringLiteral("#ATT#!='#V1S#'")) {
output = i18nc("Help for a condition", "To find out if the attribute is not equal to a given string");
} else if (output == QStringLiteral("#ATT#>'#V1S#'")) {
output = i18nc("Help for a condition", "To find out if the attribute is greater than a given string");
} else if (output == QStringLiteral("#ATT#<'#V1S#'")) {
output = i18nc("Help for a condition", "To find out if the attribute is smaller than a given string");
} else if (output == QStringLiteral("#ATT#>='#V1S#'")) {
output = i18nc("Help for a condition", "To find out if the attribute is greater or equal to a given string");
} else if (output == QStringLiteral("#ATT#<='#V1S#'")) {
output = i18nc("Help for a condition", "To find out if the attribute is smaller or equal to a given string");
} else if (output == QStringLiteral("#ATT#>=#V1# AND #ATT#<=#V2#")) {
output = i18nc("Help for a condition", "To find out if the attribute is between two given values");
} else if (output == QStringLiteral("((#ATT#>='#V1S#' AND #ATT#<='#V2S#') OR (#ATT#>='#V2S#' AND #ATT#<='#V1S#'))")) {
output = i18nc("Help for a condition", "To find out if the attribute is between two given strings");
} else if (output == QStringLiteral("#ATT#=lower(#ATT#)")) {
output = i18nc("Help for a condition", "To set the attribute in lower case (eg. hello)");
} else if (output == QStringLiteral("#ATT#=upper(#ATT#)")) {
output = i18nc("Help for a condition", "To set the attribute in upper case (eg. HELLO)");
} else if (output == QStringLiteral("#ATT#=capitalize(#ATT#)")) {
output = i18nc("Help for a condition", "To set the attribute in capitalized case (eg. Hello)");
} else if (output == QStringLiteral("#ATT#!=lower(#ATT#)")) {
output = i18nc("Help for a condition", "To find out if the attribute is not in lower case (eg. hello)");
} else if (output == QStringLiteral("#ATT#!=upper(#ATT#)")) {
output = i18nc("Help for a condition", "To find out if the attribute is not in upper case (eg. HELLO)");
} else if (output == QStringLiteral("#ATT#!=capitalize(#ATT#)")) {
output = i18nc("Help for a condition", "To find out if the attribute is not in capitalized case (eg. Hello)");
} else if (output == QStringLiteral("#ATT#= lower(#ATT#)")) {
output = i18nc("Help for a condition", "To find out if the attribute is in lower case (eg. hello)");
} else if (output == QStringLiteral("#ATT#= upper(#ATT#)")) {
output = i18nc("Help for a condition", "To find out if the attribute is in upper case (eg. HELLO)");
} else if (output == QStringLiteral("#ATT#= capitalize(#ATT#)")) {
output = i18nc("Help for a condition", "To find out if the attribute is in capitalized case (eg. Hello)");
} else if (output == QStringLiteral("#ATT#=replace(#ATT2#,'#V1S#','#V2S#')")) {
output = i18nc("Help for a condition", "To set the attribute with the value of another attribute where a value is replaced by another one");
} else if (output == QStringLiteral("#ATT#=substr(#ATT2#,'#V1#','#V2#')")) {
output = i18nc("Help for a condition", "To set the attribute with a part of the value of another attribute");
} else if (output == QStringLiteral("#ATT#=#ATT2#")) {
output = i18nc("Help for a condition", "To set the attribute with the value of another attribute");
} else if (output == QStringLiteral("#ATT#=WORD(#ATT2#,#V1S#)")) {
output = i18nc("Help for a condition", "To set the attribute with a word of the value of another attribute converted in date format");
} else if (output == QStringLiteral("#ATT#=todate(#ATT2#,'#DF#')")) {
output = i18nc("Help for a condition", "To set the date attribute with the value of another attribute");
} else if (output == QStringLiteral("#ATT#=todate(WORD(#ATT2#,#V1S#),'#DF#')")) {
output = i18nc("Help for a condition", "To set the date attribute with a word of another attribute converted in date format");
} else if (output == QStringLiteral("STRFTIME('%Y-%m',#ATT#)=STRFTIME('%Y-%m',date('now'))")) {
output = i18nc("Help for a condition", "To find out if the date of the operation is today");
} else if (output == QStringLiteral("STRFTIME('%Y-%m',#ATT#)=STRFTIME('%Y-%m',date('now','start of month','-1 month'))")) {
output = i18nc("Help for a condition", "To find out if the date of the operation is in previous month");
} else if (output == QStringLiteral("STRFTIME('%Y',#ATT#)=STRFTIME('%Y',date('now'))")) {
output = i18nc("Help for a condition", "To find out if the date of the operation is in current year");
} else if (output == QStringLiteral("STRFTIME('%Y',#ATT#)=STRFTIME('%Y',date('now','start of month','-1 year'))")) {
output = i18nc("Help for a condition", "To find out if the date of the operation is in previous year");
} else if (output == QStringLiteral("#ATT#>date('now','-30 day') AND #ATT#<=date('now')")) {
output = i18nc("Help for a condition", "To find out if the date of the operation is in last 30 days");
} else if (output == QStringLiteral("#ATT#>date('now','-3 month') AND #ATT#<=date('now')")) {
output = i18nc("Help for a condition", "To find out if the date of the operation is in last 3 months");
} else if (output == QStringLiteral("#ATT#>date('now','-6 month') AND #ATT#<=date('now')")) {
output = i18nc("Help for a condition", "To find out if the date of the operation is in last 6 months");
} else if (output == QStringLiteral("#ATT#>date('now','-12 month') AND #ATT#<=date('now')")) {
output = i18nc("Help for a condition", "To find out if the date of the operation is in last 12 months");
} else if (output == QStringLiteral("#ATT#>date('now','-2 year') AND #ATT#<=date('now')")) {
output = i18nc("Help for a condition", "To find out if the date of the operation is in last 2 years");
} else if (output == QStringLiteral("#ATT#>date('now','-3 year') AND #ATT#<=date('now')")) {
output = i18nc("Help for a condition", "To find out if the date of the operation is in last 3 years");
} else if (output == QStringLiteral("#ATT#>date('now','-5 year') AND #ATT#<=date('now')")) {
output = i18nc("Help for a condition", "To find out if the date of the operation is in last 5 years");
}
return output;
}
QStringList SKGRuleObject::getListOfOperators(SKGServices::AttributeType iAttributeType, SKGRuleObject::ActionType iType)
{
QStringList output;
if (iType == UPDATE) {
// Mode update
if (iAttributeType == SKGServices::TEXT) {
output.push_back(QStringLiteral("#ATT#='#V1S#'"));
output.push_back(QStringLiteral("#ATT#=lower(#ATT#)"));
output.push_back(QStringLiteral("#ATT#=upper(#ATT#)"));
output.push_back(QStringLiteral("#ATT#=capitalize(#ATT#)"));
output.push_back(QStringLiteral("#ATT#=replace(#ATT2#,'#V1S#','#V2S#')"));
output.push_back(QStringLiteral("#ATT#=REGEXPCAPTURE('#V1S#', #ATT2#, #V2#)"));
} else if (iAttributeType == SKGServices::INTEGER || iAttributeType == SKGServices::FLOAT) {
output.push_back(QStringLiteral("#ATT#=#V1#"));
} else if (iAttributeType == SKGServices::DATE || iAttributeType == SKGServices::BOOL || iAttributeType == SKGServices::TRISTATE) {
output.push_back(QStringLiteral("#ATT#='#V1S#'"));
}
if (iAttributeType == SKGServices::DATE) {
output.push_back(QStringLiteral("#ATT#=todate(#ATT2#,'#DF#')"));
output.push_back(QStringLiteral("#ATT#=todate(WORD(#ATT2#,#V1S#),'#DF#')"));
} else if (iAttributeType != SKGServices::BOOL && iAttributeType != SKGServices::TRISTATE) {
output.push_back(QStringLiteral("#ATT#=substr(#ATT2#,'#V1#','#V2#')"));
output.push_back(QStringLiteral("#ATT#=#ATT2#"));
output.push_back(QStringLiteral("#ATT#=WORD(#ATT2#,#V1S#)"));
}
} else if (iType == SEARCH) {
// Mode query
if (iAttributeType == SKGServices::TEXT) {
output.push_back(QStringLiteral("#ATT# LIKE '%#V1S#%'"));
output.push_back(QStringLiteral("#ATT# NOT LIKE '%#V1S#%'"));
output.push_back(QStringLiteral("#ATT# LIKE '#V1S#%'"));
output.push_back(QStringLiteral("#ATT# NOT LIKE '#V1S#%'"));
output.push_back(QStringLiteral("#ATT# LIKE '%#V1S#'"));
output.push_back(QStringLiteral("#ATT# NOT LIKE '%#V1S#'"));
output.push_back(QStringLiteral("#ATT#=''"));
output.push_back(QStringLiteral("#ATT#!=''"));
output.push_back(QStringLiteral("#ATT#= lower(#ATT#)"));
output.push_back(QStringLiteral("#ATT#!=lower(#ATT#)"));
output.push_back(QStringLiteral("#ATT#= upper(#ATT#)"));
output.push_back(QStringLiteral("#ATT#!=upper(#ATT#)"));
output.push_back(QStringLiteral("#ATT#= capitalize(#ATT#)"));
output.push_back(QStringLiteral("#ATT#!=capitalize(#ATT#)"));
output.push_back(QStringLiteral("REGEXP('#V1S#', #ATT#)"));
output.push_back(QStringLiteral("NOT(REGEXP('#V1S#', #ATT#))"));
output.push_back(QStringLiteral("WILDCARD('#V1S#', #ATT#)"));
output.push_back(QStringLiteral("NOT(WILDCARD('#V1S#', #ATT#))"));
}
if (iAttributeType == SKGServices::INTEGER || iAttributeType == SKGServices::FLOAT) {
output.push_back(QStringLiteral("#ATT#=#V1#"));
output.push_back(QStringLiteral("#ATT#!=#V1#"));
output.push_back(QStringLiteral("#ATT#>#V1#"));
output.push_back(QStringLiteral("#ATT#<#V1#"));
output.push_back(QStringLiteral("#ATT#>=#V1#"));
output.push_back(QStringLiteral("#ATT#<=#V1#"));
output.push_back(QStringLiteral("#ATT#>=#V1# AND #ATT#<=#V2#"));
}
if (iAttributeType == SKGServices::BOOL || iAttributeType == SKGServices::TRISTATE || iAttributeType == SKGServices::TEXT || iAttributeType == SKGServices::DATE) {
output.push_back(QStringLiteral("#ATT#='#V1S#'"));
}
if (iAttributeType == SKGServices::TRISTATE || iAttributeType == SKGServices::TEXT || iAttributeType == SKGServices::DATE) {
output.push_back(QStringLiteral("#ATT#!='#V1S#'"));
}
if (iAttributeType == SKGServices::TEXT || iAttributeType == SKGServices::DATE) {
output.push_back(QStringLiteral("#ATT#>'#V1S#'"));
output.push_back(QStringLiteral("#ATT#<'#V1S#'"));
output.push_back(QStringLiteral("#ATT#>='#V1S#'"));
output.push_back(QStringLiteral("#ATT#<='#V1S#'"));
output.push_back(QStringLiteral("((#ATT#>='#V1S#' AND #ATT#<='#V2S#') OR (#ATT#>='#V2S#' AND #ATT#<='#V1S#'))"));
}
if (iAttributeType == SKGServices::DATE) {
output.push_back(QStringLiteral("STRFTIME('%Y-%m',#ATT#)=STRFTIME('%Y-%m',date('now'))"));
output.push_back(QStringLiteral("STRFTIME('%Y-%m',#ATT#)=STRFTIME('%Y-%m',date('now','start of month','-1 month'))"));
output.push_back(QStringLiteral("STRFTIME('%Y',#ATT#)=STRFTIME('%Y',date('now'))"));
output.push_back(QStringLiteral("STRFTIME('%Y',#ATT#)=STRFTIME('%Y',date('now','start of month','-1 year'))"));
output.push_back(QStringLiteral("#ATT#>date('now','-30 day') AND #ATT#<=date('now')"));
output.push_back(QStringLiteral("#ATT#>date('now','-3 month') AND #ATT#<=date('now')"));
output.push_back(QStringLiteral("#ATT#>date('now','-6 month') AND #ATT#<=date('now')"));
output.push_back(QStringLiteral("#ATT#>date('now','-12 month') AND #ATT#<=date('now')"));
output.push_back(QStringLiteral("#ATT#>date('now','-2 year') AND #ATT#<=date('now')"));
output.push_back(QStringLiteral("#ATT#>date('now','-3 year') AND #ATT#<=date('now')"));
output.push_back(QStringLiteral("#ATT#>date('now','-5 year') AND #ATT#<=date('now')"));
}
} else if (iType == ALARM) {
output.push_back(QStringLiteral("ABS(TOTAL(#ATT#))#OP##V1#,ABS(TOTAL(#ATT#)), #V1#, '#V2S#'"));
} else if (iType == APPLYTEMPLATE) {
output.push_back(QStringLiteral("APPLYTEMPLATE(#V1#)"));
}
return output;
}
QStringList SKGRuleObject::getFromXML(SKGDocument* iDocument, const QString& iXML, bool iSQL, SKGRuleObject::ActionType iType, bool iFullUpdate)
{
QStringList output;
if (iFullUpdate) {
// Add markers
output.push_back(QStringLiteral("UPDATE v_operation_prop set i_tmp=1 WHERE #WC#"));
}
QDomDocument doc(QStringLiteral("SKGML"));
doc.setContent(iXML);
QDomElement root = doc.documentElement();
if (root.tagName() == QStringLiteral("element") || iType != SEARCH) {
// Mode advanced
QDomNode l = root.firstChild();
while (!l.isNull()) {
QDomElement elementl = l.toElement();
if (!elementl.isNull()) {
QString lineDescription;
QDomNode n = elementl.firstChild();
bool parenthesisNeeded = false;
while (!n.isNull()) {
QDomElement element = n.toElement();
if (!element.isNull()) {
// Build element description
QString elementDescription;
QString attribute = element.attribute(QStringLiteral("attribute"));
QString propName;
if (iSQL) {
attribute = SKGServices::stringToSqlString(attribute);
if (attribute.startsWith(QLatin1String("p_"))) {
// Case property
propName = attribute.right(attribute.length() - 2);
if (iType == SEARCH) {
attribute = "i_PROPPNAME='" % SKGServices::stringToSqlString(propName) % "' AND i_PROPVALUE";
} else {
attribute = QStringLiteral("t_value");
}
}
QString part = element.attribute(QStringLiteral("operator"));
part = part.replace(QStringLiteral("#V1#"), SKGServices::stringToSqlString(element.attribute(QStringLiteral("value"))));
part = part.replace(QStringLiteral("#V1S#"), SKGServices::stringToSqlString(element.attribute(QStringLiteral("value"))));
part = part.replace(QStringLiteral("#V2#"), SKGServices::stringToSqlString(element.attribute(QStringLiteral("value2"))));
part = part.replace(QStringLiteral("#V2S#"), SKGServices::stringToSqlString(element.attribute(QStringLiteral("value2"))));
part = part.replace(QStringLiteral("#DF#"), SKGServices::stringToSqlString(element.attribute(QStringLiteral("value2"))));
part = part.replace(QStringLiteral("#OP#"), SKGServices::stringToSqlString(element.attribute(QStringLiteral("operator2"))));
elementDescription += part;
} else {
attribute = "operation." % attribute;
if (iDocument != nullptr) {
attribute = iDocument->getDisplay(attribute);
}
if (iType != ALARM && iType != APPLYTEMPLATE) {
elementDescription = attribute;
elementDescription += ' ';
}
QString tmp = element.attribute(QStringLiteral("att2s"));
if (tmp.isEmpty()) {
tmp = element.attribute(QStringLiteral("operator2"));
}
QString part = SKGRuleObject::getDisplayForOperator(element.attribute(QStringLiteral("operator")),
element.attribute(QStringLiteral("value")),
element.attribute(QStringLiteral("value2")),
tmp);
elementDescription += part;
}
elementDescription = elementDescription.replace(QStringLiteral("#ATT#"), attribute);
// Att2
QString attribute2 = element.attribute(QStringLiteral("att2"));
if (iSQL) {
attribute2 = SKGServices::stringToSqlString(attribute2);
if (attribute2.startsWith(QLatin1String("p_"))) {
QString propertyName = attribute2.right(attribute2.length() - 2);
attribute2 = "IFNULL((SELECT op2.i_PROPVALUE FROM v_operation_prop op2 WHERE op2.id=v_operation_prop.id AND op2.i_PROPPNAME='" % SKGServices::stringToSqlString(propertyName) % "'),'')";
}
if (element.attribute(QStringLiteral("attribute")).startsWith(QLatin1String("p_"))) {
attribute2 = "(SELECT " % attribute2 % " FROM v_operation_prop WHERE i_PROPPID=parameters.id)";
}
}
elementDescription = elementDescription.replace(QStringLiteral("#ATT2#"), attribute2);
// Add it to line description
if (iSQL) {
if (iType == UPDATE) {
if (!iFullUpdate) {
output.push_back(elementDescription);
} else {
if (attribute == QStringLiteral("t_REALCATEGORY")) {
elementDescription.replace(attribute, QStringLiteral("t_fullname"));
QString parentcat;
QString cat = element.attribute(QStringLiteral("value"));
bool stop = false;
while (!stop) {
int posSeparator = cat.indexOf(OBJECTSEPARATOR);
if (posSeparator == -1) {
if (parentcat.isEmpty()) {
output.push_back(QStringLiteral("UPDATE category SET rd_category_id=0 WHERE rd_category_id IS NULL OR rd_category_id=''"));
output.push_back("INSERT OR IGNORE INTO category (t_name, rd_category_id) VALUES ('" % SKGServices::stringToSqlString(cat) % "', 0)");
} else {
output.push_back("INSERT OR IGNORE INTO category (t_name, rd_category_id) VALUES ('" % SKGServices::stringToSqlString(cat) % "',(SELECT id FROM category WHERE t_fullname='" % SKGServices::stringToSqlString(parentcat) % "'))");
}
stop = true;
} else {
// Get first and second parts of the branch
QString first = cat.mid(0, posSeparator);
QString second = cat.mid(posSeparator + QString(OBJECTSEPARATOR).length(), cat.length() - posSeparator - QString(OBJECTSEPARATOR).length());
if (parentcat.isEmpty()) {
output.push_back(QStringLiteral("UPDATE category SET rd_category_id=0 WHERE rd_category_id IS NULL OR rd_category_id=''"));
output.push_back("INSERT OR IGNORE INTO category (t_name, rd_category_id) VALUES ('" % SKGServices::stringToSqlString(first) % "', 0)");
} else {
output.push_back("INSERT OR IGNORE INTO category (t_name, rd_category_id) VALUES ('" % SKGServices::stringToSqlString(first) % "',(SELECT id FROM category WHERE t_fullname='" % SKGServices::stringToSqlString(parentcat) % "'))");
}
if (parentcat.isEmpty()) {
parentcat = first;
} else {
parentcat = parentcat % OBJECTSEPARATOR % first;
}
cat = second;
}
}
output.push_back("UPDATE suboperation set r_category_id=(SELECT id FROM category WHERE " % elementDescription % ") WHERE i_tmp=1");
} else if (element.attribute(QStringLiteral("attribute")).startsWith(QLatin1String("p_"))) {
output.push_back("INSERT OR IGNORE INTO parameters (t_uuid_parent, t_name, i_tmp) SELECT o.id||'-operation', '" % SKGServices::stringToSqlString(propName) % "', 1 FROM operation o WHERE o.i_tmp=1");
output.push_back("UPDATE parameters set " % elementDescription % " WHERE i_tmp=1 AND t_name='" % SKGServices::stringToSqlString(propName) % "' AND NOT(" % elementDescription % ')');
output.push_back("DELETE FROM parameters WHERE i_tmp=1 AND t_name='" % SKGServices::stringToSqlString(propName) % "' AND t_value=''");
} else {
output.push_back("UPDATE v_operation_prop set " % elementDescription % " WHERE i_tmp=1 AND NOT(" % elementDescription % ')');
}
}
} else if (iType == ALARM) {
output.push_back("SELECT " % elementDescription % " FROM v_operation_prop WHERE #WC#");
} else if (iType == APPLYTEMPLATE) {
output.push_back(element.attribute(QStringLiteral("value")));
}
}
if (!lineDescription.isEmpty()) {
lineDescription += (iType == UPDATE ? QStringLiteral(" , ") : (iSQL ? QStringLiteral(" AND ") : i18nc("logical operator in a search query", " and ")));
parenthesisNeeded = true;
}
lineDescription += elementDescription;
}
n = n.nextSibling();
}
if (!(iType != SEARCH && iSQL) && !lineDescription.isEmpty()) {
if (iType == SEARCH && parenthesisNeeded) {
lineDescription = '(' % lineDescription % ')';
}
output.push_back(lineDescription);
}
}
l = l.nextSibling();
}
} else {
output.push_back(root.attribute(iSQL ? QStringLiteral("sql") : QStringLiteral("query")));
}
if (iFullUpdate) {
// Remove markers
output.push_back(QStringLiteral("UPDATE v_operation_prop set i_tmp=0 WHERE i_tmp=1"));
}
return output;
}
QString SKGRuleObject::getDescriptionFromXML(SKGDocument* iDocument, const QString& iXML, bool iSQL, SKGRuleObject::ActionType iType)
{
QString output;
QStringList list = getFromXML(iDocument, iXML, iSQL, iType);
int nb = list.count();
for (int i = 0; i < nb; ++i) {
output.append(list.at(i));
if (i < nb - 1) {
output.append(iType != SEARCH ? QStringLiteral(" , ") : (iSQL ? QStringLiteral(" OR ") : i18nc("logical operator in a search query", " or ")));
}
}
return output;
}
SKGError SKGRuleObject::createPayeeCategoryRule(SKGDocument* iDocument, const QString& iPayee, const QString& iCategory, SKGRuleObject& oRule)
{
SKGError err;
oRule = SKGRuleObject(iDocument);
// TODO(Stephane MANKOWSKI): escape values
IFOKDO(err, oRule.setActionType(SKGRuleObject::UPDATE))
IFOKDO(err, oRule.setSearchDescription(iDocument->getDisplay(QStringLiteral("t_PAYEE")) % ' ' % getDisplayForOperator(QStringLiteral("#ATT#='#V1S#'"), iPayee, QString(), QString())))
IFOKDO(err, oRule.setXMLSearchDefinition("<!DOCTYPE SKGML><element> <!--OR--> <element> <!--AND--> <element value=\"" % iPayee % "\" attribute=\"t_PAYEE\" operator=\"#ATT#='#V1S#'\"/> </element></element>"))
IFOKDO(err, oRule.setActionDescription(iDocument->getDisplay(QStringLiteral("t_REALCATEGORY")) % ' ' % getDisplayForOperator(QStringLiteral("#ATT#='#V1S#'"), iCategory, QString(), QString())))
IFOKDO(err, oRule.setXMLActionDefinition("<!DOCTYPE SKGML><element> <!--OR--> <element> <!--AND--> <element value=\"" % iCategory % "\" attribute=\"t_REALCATEGORY\" operator=\"#ATT#='#V1S#'\"/> </element></element>"))
IFOKDO(err, oRule.save())
return err;
}
diff --git a/skgbankmodeler/skgruleobject.h b/skgbankmodeler/skgruleobject.h
index 43593e6bf..738600823 100644
--- a/skgbankmodeler/skgruleobject.h
+++ b/skgbankmodeler/skgruleobject.h
@@ -1,337 +1,337 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGRULEOBJECT_H
#define SKGRULEOBJECT_H
/** @file
* This file defines classes SKGRuleObject.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgbankmodeler_export.h"
#include "skgdocument.h"
#include "skgerror.h"
#include "skgobjectbase.h"
/**
* This class allows to define rules
*/
class SKGBANKMODELER_EXPORT SKGRuleObject final : public SKGObjectBase
{
Q_OBJECT
public:
/**
* Alarm
*/
struct SKGAlarmInfo {
/** To know if the alarm is raised */
bool Raised{};
/** The message to display */
QString Message;
/** The amount in absolute value */
double Amount{};
/** The limit */
double Limit{};
};
/**
* Process mode
*/
enum ProcessMode {ALL,
NOTCHECKED,
IMPORTED,
IMPORTEDNOTVALIDATE,
IMPORTING
};
/**
* Process mode
*/
Q_ENUM(ProcessMode)
/**
* Action type
*/
enum ActionType {SEARCH,
UPDATE,
ALARM,
APPLYTEMPLATE
};
/**
* Action type
*/
Q_ENUM(ActionType)
/**
* Default constructor
*/
explicit SKGRuleObject();
/**
* Constructor
* @param iDocument the document containing the object
* @param iID the identifier of the object
*/
explicit SKGRuleObject(SKGDocument* iDocument, int iID = 0);
/**
* Copy constructor
* @param iObject the object to copy
*/
SKGRuleObject(const SKGRuleObject& iObject);
/**
* Copy constructor
* @param iObject the object to copy
*/
explicit SKGRuleObject(const SKGObjectBase& iObject);
/**
* Operator affectation
* @param iObject the object to copy
*/
SKGRuleObject& operator= (const SKGObjectBase& iObject);
/**
* Destructor
*/
~SKGRuleObject() override;
/**
* Return the name of the object for the display
* @return name of the object
*/
QString getDisplayName() const override;
/**
* Set the XML for the search definition
* @param iXml the XML search definition
* @code example:
* <!DOCTYPE SKGML>
* <element> <!--OR-->
* <element> <!--AND-->
* <element attribute="d_date" operator="STRFTIME('%Y',#ATT#)=STRFTIME('%Y',date('now'))" />
* </element>
* </element>
* @endcode
* @return an object managing the error
* @see SKGError
*/
SKGError setXMLSearchDefinition(const QString& iXml);
/**
* Get the XML for the search definition
* @return the XML
*/
QString getXMLSearchDefinition() const;
/**
* Set the XML for the action definition
* @param iXml the XML action definition
* @code example for an update action:
* <!DOCTYPE SKGML>
* <element> <!--OR-->
* <element> <!--AND-->
* <element attribute="t_number" att2="t_PAYEE" value2="10000000" operator="#ATT#=substr(#ATT2#,'#V1#','#V2#')" att2s="Payee" value="11" />
* </element>
* </element>
* @endcode
* @code example for an alarm action:
* <!DOCTYPE SKGML>
* <element> <!--OR-->
* <element> <!--AND-->
* <element attribute="f_REALCURRENTAMOUNT" operator="ABS(TOTAL(#ATT#))#OP##V1#,ABS(TOTAL(#ATT#)), #V1#, '#V2S#'" value="1000" value2="Take care!" operator2=">="/>
* </element>
* </element>
* @endcode
* @code example to apply a template:
* <!DOCTYPE SKGML>
* <element> <!--OR-->
* <element> <!--AND-->
* <element attribute="id" operator="APPLYTEMPLATE(#V1#)" value="123" value2="The template name"/>
* </element>
* </element>
* @endcode*
* @return an object managing the error
* @see SKGError
*/
SKGError setXMLActionDefinition(const QString& iXml);
/**
* Get the XML for the action definition
* @return the XML
*/
QString getXMLActionDefinition() const;
/**
* Set the search description
* @param iDescription the search description
* @return an object managing the error
* @see SKGError
*/
SKGError setSearchDescription(const QString& iDescription);
/**
* Get the search description
* @return the description
*/
QString getSearchDescription() const;
/**
* Set the action description
* @param iDescription the action description
* @return an object managing the error
* @see SKGError
*/
SKGError setActionDescription(const QString& iDescription);
/**
* Get the action description
* @return the description
*/
QString getActionDescription() const;
/**
* Set the action type
* @param iType the action type
* @return an object managing the error
* @see SKGError
*/
SKGError setActionType(SKGRuleObject::ActionType iType);
/**
* Get the action type
* @return the type
*/
SKGRuleObject::ActionType getActionType() const;
/**
* Set the order for the rule
* @param iOrder the order. (-1 means "at the end")
* @return an object managing the error
* @see SKGError
*/
SKGError setOrder(double iOrder);
/**
* Get the order for the rule
* @return the order
*/
double getOrder() const;
/**
* To bookmark or not an account
* @param iBookmark the bookmark: true or false
* @return an object managing the error
* @see SKGError
*/
SKGError bookmark(bool iBookmark);
/**
* To know if the account is bookmarked
* @return an object managing the error
* @see SKGError
*/
bool isBookmarked() const;
/**
* save the object into the database
* @param iInsertOrUpdate the save mode.
* true: try an insert, if the insert failed then try an update.
* false: try an insert, if the insert failed then return an error.
* @param iReloadAfterSave to reload the object after save. Set false if you are sure that you will not use this object after save
* @return an object managing the error
* @see SKGError
*/
SKGError save(bool iInsertOrUpdate = true, bool iReloadAfterSave = true) override;
/**
* Execute actions
* @param iMode mode
* @return an object managing the error
* @see SKGError
*/
SKGError execute(ProcessMode iMode = SKGRuleObject::ALL);
/**
* Get where clause corresponding to search condition
* @param iAdditionalCondition additional select condition
* @return the where clause
*/
QString getSelectSqlOrder(const QString& iAdditionalCondition = QString()) const;
/**
* Get alarm info
* @return alarm info
*/
SKGRuleObject::SKGAlarmInfo getAlarmInfo() const;
/**
* Create a rule to update a category on operations having a specific payee
* @param iDocument the document containing the object
* @param iPayee the payee
* @param iCategory the category
* @param oRule the created rule
* @return an object managing the error
* @see SKGError
*/
static SKGError createPayeeCategoryRule(SKGDocument* iDocument, const QString& iPayee, const QString& iCategory, SKGRuleObject& oRule);
/**
* Get the list of supported operators
* @param iAttributeType type of attribute
* @param iType mode
* @return list of supported operators
*/
static QStringList getListOfOperators(SKGServices::AttributeType iAttributeType, SKGRuleObject::ActionType iType = SEARCH);
/**
* Get the NLS display of an operator
* @param iOperator the operator (see @see getListOfOperators)
* @param iParam1 parameter
* @param iParam2 parameter
* @param iAtt2 attribute number 2
* @return the NLS display
*/
static QString getDisplayForOperator(const QString& iOperator, const QString& iParam1, const QString& iParam2, const QString& iAtt2);
/**
* Get the NLS tooltip of an operator
* @param iOperator the operator (see @see getListOfOperators)
* @return the NLS display
*/
static QString getToolTipForOperator(const QString& iOperator);
protected:
/**
* Get the description of an XML definition
* @param iDocument the document
* @param iXML the XML
* @param iSQL to define if you want the TXT or SQL description
* @param iType mode
* @return the description
*/
static QString getDescriptionFromXML(SKGDocument* iDocument, const QString& iXML, bool iSQL = false, SKGRuleObject::ActionType iType = SEARCH);
private:
static QStringList getFromXML(SKGDocument* iDocument, const QString& iXML, bool iSQL = false, SKGRuleObject::ActionType iType = SEARCH, bool iFullUpdate = false);
};
/**
* Declare the class
*/
Q_DECLARE_TYPEINFO(SKGRuleObject, Q_MOVABLE_TYPE);
#endif
diff --git a/skgbankmodeler/skgsuboperationobject.cpp b/skgbankmodeler/skgsuboperationobject.cpp
index 7344fe5d2..89749ef01 100644
--- a/skgbankmodeler/skgsuboperationobject.cpp
+++ b/skgbankmodeler/skgsuboperationobject.cpp
@@ -1,167 +1,167 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file implements classes SKGSubOperationObject.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgsuboperationobject.h"
#include <klocalizedstring.h>
#include "skgcategoryobject.h"
#include "skgdocument.h"
#include "skgoperationobject.h"
#include "skgservices.h"
#include "skgtrackerobject.h"
SKGSubOperationObject::SKGSubOperationObject(): SKGSubOperationObject(nullptr)
{}
SKGSubOperationObject::SKGSubOperationObject(SKGDocument* iDocument, int iID): SKGObjectBase(iDocument, QStringLiteral("v_suboperation"), iID)
{}
SKGSubOperationObject::~SKGSubOperationObject()
= default;
SKGSubOperationObject::SKGSubOperationObject(const SKGSubOperationObject& iObject)
= default;
SKGSubOperationObject::SKGSubOperationObject(const SKGObjectBase& iObject)
{
if (iObject.getRealTable() == QStringLiteral("suboperation")) {
copyFrom(iObject);
} else {
*this = SKGObjectBase(iObject.getDocument(), QStringLiteral("v_suboperation"), iObject.getID());
}
}
SKGSubOperationObject& SKGSubOperationObject::operator= (const SKGObjectBase& iObject)
{
copyFrom(iObject);
return *this;
}
SKGError SKGSubOperationObject::setDate(QDate iDate)
{
return setAttribute(QStringLiteral("d_date"), iDate.isValid() ? SKGServices::dateToSqlString(QDateTime(iDate)) : QLatin1String(""));
}
QDate SKGSubOperationObject::getDate() const
{
return SKGServices::stringToTime(getAttribute(QStringLiteral("d_date"))).date();
}
SKGError SKGSubOperationObject::setOrder(int iOrder)
{
return setAttribute(QStringLiteral("i_order"), SKGServices::intToString(iOrder));
}
int SKGSubOperationObject::getOrder() const
{
return SKGServices::stringToInt(getAttribute(QStringLiteral("i_order")));
}
SKGError SKGSubOperationObject::setComment(const QString& iComment)
{
return setAttribute(QStringLiteral("t_comment"), iComment);
}
QString SKGSubOperationObject::getComment() const
{
return getAttribute(QStringLiteral("t_comment"));
}
QString SKGSubOperationObject::getFormula() const
{
return getAttribute(QStringLiteral("t_formula"));
}
SKGError SKGSubOperationObject::setFormula(const QString& iFormula)
{
return setAttribute(QStringLiteral("t_formula"), iFormula);
}
SKGError SKGSubOperationObject::getParentOperation(SKGOperationObject& oOperation) const
{
SKGError err = getDocument()->getObject(QStringLiteral("v_operation"), "id=" % getAttribute(QStringLiteral("rd_operation_id")), oOperation);
return err;
}
SKGError SKGSubOperationObject::setParentOperation(const SKGOperationObject& iOperation)
{
SKGError err;
if (!getDate().isValid()) {
err = setDate(iOperation.getDate());
}
IFOKDO(err, setAttribute(QStringLiteral("rd_operation_id"), SKGServices::intToString(iOperation.getID())))
return err;
}
SKGError SKGSubOperationObject::getCategory(SKGCategoryObject& oCategory) const
{
SKGError err = getDocument()->getObject(QStringLiteral("v_category"), "id=" % getAttribute(QStringLiteral("r_category_id")), oCategory);
return err;
}
SKGError SKGSubOperationObject::setCategory(const SKGCategoryObject& iCategory)
{
return setAttribute(QStringLiteral("r_category_id"), SKGServices::intToString(iCategory.getID()));
}
SKGError SKGSubOperationObject::setQuantity(double iValue)
{
return setAttribute(QStringLiteral("f_value"), SKGServices::doubleToString(iValue));
}
double SKGSubOperationObject::getQuantity() const
{
return SKGServices::stringToDouble(getAttribute(QStringLiteral("f_value")));
}
SKGError SKGSubOperationObject::setTracker(const SKGTrackerObject& iTracker, bool iForce)
{
SKGError err;
SKGTrackerObject previous;
getTracker(previous);
if (iTracker != previous) {
if (!iForce && previous.isClosed()) {
err = SKGError(ERR_FAIL, i18nc("Error message", "Impossible to remove an operation from a closed tracker"));
} else if (!iForce && iTracker.isClosed()) {
err = SKGError(ERR_FAIL, i18nc("Error message", "Impossible to add an operation in a closed tracker"));
} else {
err = setAttribute(QStringLiteral("r_refund_id"), SKGServices::intToString(iTracker.getID()));
}
}
return err;
}
SKGError SKGSubOperationObject::getTracker(SKGTrackerObject& oTracker) const
{
QString idS = getAttribute(QStringLiteral("r_refund_id"));
if (idS.isEmpty()) {
idS = '0';
}
SKGError err;
if ((getDocument() != nullptr) && idS != QStringLiteral("0")) {
err = getDocument()->getObject(QStringLiteral("v_refund"), "id=" % idS, oTracker);
}
return err;
}
diff --git a/skgbankmodeler/skgsuboperationobject.h b/skgbankmodeler/skgsuboperationobject.h
index 516adbbde..b11412841 100644
--- a/skgbankmodeler/skgsuboperationobject.h
+++ b/skgbankmodeler/skgsuboperationobject.h
@@ -1,199 +1,199 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGSUBOPERATIONOBJECT_H
#define SKGSUBOPERATIONOBJECT_H
/** @file
* This file defines classes SKGSubOperationObject.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgbankmodeler_export.h"
#include "skgobjectbase.h"
class SKGOperationObject;
class SKGCategoryObject;
class SKGTrackerObject;
/**
* This class manages suboperation object
*/
class SKGBANKMODELER_EXPORT SKGSubOperationObject final : public SKGObjectBase
{
Q_OBJECT
public:
/**
* Default constructor
*/
explicit SKGSubOperationObject();
/**
* Constructor
* @param iDocument the document containing the object
* @param iID the identifier in @p iTable of the object
*/
explicit SKGSubOperationObject(SKGDocument* iDocument, int iID = 0);
/**
* Copy constructor
* @param iObject the object to copy
*/
SKGSubOperationObject(const SKGSubOperationObject& iObject);
/**
* Copy constructor
* @param iObject the object to copy
*/
explicit SKGSubOperationObject(const SKGObjectBase& iObject);
/**
* Operator affectation
* @param iObject the object to copy
*/
SKGSubOperationObject& operator= (const SKGObjectBase& iObject);
/**
* Destructor
*/
~SKGSubOperationObject() override;
/**
* Set date of this suboperation
* @param iDate the date
* @return an object managing the error
* @see SKGError
*/
// cppcheck-suppress passedByValue
SKGError setDate(QDate iDate);
/**
* Get date of this suboperation
* @return the date
*/
QDate getDate() const;
/**
* Set the order of suboperation
* @param iOrder the order
* @return an object managing the error
* @see SKGError
*/
SKGError setOrder(int iOrder);
/**
* Get order of this suboperation
* @return the order
*/
int getOrder() const;
/**
* Set the comment of suboperation
* @param iComment the comment
* @return an object managing the error
* @see SKGError
*/
SKGError setComment(const QString& iComment);
/**
* Get the comment of this suboperation
* @return the comment
*/
QString getComment() const;
/**
* Get the parent operation
* @param oOperation the parent operation
* @return an object managing the error.
* @see SKGError
*/
SKGError getParentOperation(SKGOperationObject& oOperation) const;
/**
* Set the parent operation
* @param iOperation the parent operation
* @return an object managing the error.
* @see SKGError
*/
SKGError setParentOperation(const SKGOperationObject& iOperation);
/**
* Set the category
* @param iCategory the category
* @return an object managing the error
* @see SKGError
*/
SKGError setCategory(const SKGCategoryObject& iCategory);
/**
* Get the category
* @param oCategory the category
* @return an object managing the error
* @see SKGError
*/
SKGError getCategory(SKGCategoryObject& oCategory) const;
/**
* Set the tracker
* @param iTracker the tracker
* @param iForce force the change of the tracker even if closed
* @return an object managing the error
* @see SKGError
*/
SKGError setTracker(const SKGTrackerObject& iTracker, bool iForce = false);
/**
* Get the tracker
* @param oTracker the tracker
* @return an object managing the error
* @see SKGError
*/
SKGError getTracker(SKGTrackerObject& oTracker) const;
/**
* Set the quantity of the suboperation
* @param iValue the value
* @return an object managing the error
* @see SKGError
*/
SKGError setQuantity(double iValue);
/**
* Get the quantity of the suboperation
* @return the value
*/
double getQuantity() const;
/**
* Set the formula
* @param iFormula the formula
* @return an object managing the error
* @see SKGError
*/
SKGError setFormula(const QString& iFormula);
/**
* Get the formula
* @return the formula
*/
QString getFormula() const;
};
/**
* Declare the class
*/
Q_DECLARE_TYPEINFO(SKGSubOperationObject, Q_MOVABLE_TYPE);
#endif
diff --git a/skgbankmodeler/skgtrackerobject.cpp b/skgbankmodeler/skgtrackerobject.cpp
index 05d1406ae..d5f2a6bd2 100644
--- a/skgbankmodeler/skgtrackerobject.cpp
+++ b/skgbankmodeler/skgtrackerobject.cpp
@@ -1,135 +1,135 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file implements classes SKGTrackerObject.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgtrackerobject.h"
#include <klocalizedstring.h>
#include "skgdocumentbank.h"
#include "skgsuboperationobject.h"
#include "skgtraces.h"
SKGTrackerObject::SKGTrackerObject(): SKGTrackerObject(nullptr)
{}
SKGTrackerObject::SKGTrackerObject(SKGDocument* iDocument, int iID): SKGNamedObject(iDocument, QStringLiteral("v_refund"), iID)
{}
SKGTrackerObject::~SKGTrackerObject()
= default;
SKGTrackerObject::SKGTrackerObject(const SKGTrackerObject& iObject) = default;
SKGTrackerObject::SKGTrackerObject(const SKGObjectBase& iObject)
{
if (iObject.getRealTable() == QStringLiteral("refund")) {
copyFrom(iObject);
} else {
*this = SKGNamedObject(iObject.getDocument(), QStringLiteral("v_refund"), iObject.getID());
}
}
SKGTrackerObject& SKGTrackerObject::operator= (const SKGObjectBase& iObject)
{
copyFrom(iObject);
return *this;
}
SKGError SKGTrackerObject::createTracker(SKGDocumentBank* iDocument,
const QString& iName,
SKGTrackerObject& oTracker,
bool iSendPopupMessageOnCreation)
{
SKGError err;
SKGTRACEINFUNCRC(10, err)
// Check if refund is already existing
if (iName.isEmpty()) {
oTracker = SKGTrackerObject(nullptr, 0);
} else if (iDocument != nullptr) {
iDocument->getObject(QStringLiteral("v_refund"), "t_name='" % SKGServices::stringToSqlString(iName) % '\'', oTracker);
if (oTracker.getID() == 0) {
// No, we have to create it
oTracker = SKGTrackerObject(iDocument);
err = oTracker.setName(iName);
IFOKDO(err, oTracker.save())
if (!err && iSendPopupMessageOnCreation) {
err = iDocument->sendMessage(i18nc("Information message", "Tracker '%1' has been created", iName), SKGDocument::Positive);
}
}
}
return err;
}
SKGError SKGTrackerObject::getSubOperations(SKGListSKGObjectBase& oSubOperations) const
{
SKGError err = getDocument()->getObjects(QStringLiteral("v_suboperation"),
"r_refund_id=" % SKGServices::intToString(getID()),
oSubOperations);
return err;
}
SKGError SKGTrackerObject::setClosed(bool iClosed)
{
return setAttribute(QStringLiteral("t_close"), iClosed ? QStringLiteral("Y") : QStringLiteral("N"));
}
bool SKGTrackerObject::isClosed() const
{
return (getAttribute(QStringLiteral("t_close")) == QStringLiteral("Y"));
}
SKGError SKGTrackerObject::setComment(const QString& iComment)
{
return setAttribute(QStringLiteral("t_comment"), iComment);
}
QString SKGTrackerObject::getComment() const
{
return getAttribute(QStringLiteral("t_comment"));
}
double SKGTrackerObject::getCurrentAmount() const
{
return SKGServices::stringToDouble(getAttributeFromView(QStringLiteral("v_refund_amount"), QStringLiteral("f_CURRENTAMOUNT")));
}
SKGError SKGTrackerObject::merge(const SKGTrackerObject& iTracker)
{
SKGError err;
SKGObjectBase::SKGListSKGObjectBase ops;
IFOKDO(err, iTracker.getSubOperations(ops))
int nb = ops.count();
for (int i = 0; !err && i < nb; ++i) {
SKGSubOperationObject op(ops.at(i));
err = op.setTracker(*this);
IFOKDO(err, op.save(true, false))
}
IFOKDO(err, iTracker.remove(false))
return err;
}
diff --git a/skgbankmodeler/skgtrackerobject.h b/skgbankmodeler/skgtrackerobject.h
index 812aad866..4918458a9 100644
--- a/skgbankmodeler/skgtrackerobject.h
+++ b/skgbankmodeler/skgtrackerobject.h
@@ -1,141 +1,141 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGTRACKEROBJECT_H
#define SKGTRACKEROBJECT_H
/** @file
* This file defines classes SKGTrackerObject.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgbankmodeler_export.h"
#include "skgnamedobject.h"
class SKGDocumentBank;
/**
* This class manages tracker object
*/
class SKGBANKMODELER_EXPORT SKGTrackerObject final : public SKGNamedObject
{
Q_OBJECT
public:
/**
* Default constructor
*/
explicit SKGTrackerObject();
/**
* Constructor
* @param iDocument the document containing the object
* @param iID the identifier in @p iTable of the object
*/
explicit SKGTrackerObject(SKGDocument* iDocument, int iID = 0);
/**
* Copy constructor
* @param iObject the object to copy
*/
SKGTrackerObject(const SKGTrackerObject& iObject);
/**
* Copy constructor
* @param iObject the object to copy
*/
explicit SKGTrackerObject(const SKGObjectBase& iObject);
/**
* Operator affectation
* @param iObject the object to copy
*/
SKGTrackerObject& operator= (const SKGObjectBase& iObject);
/**
* Destructor
*/
~SKGTrackerObject() override;
/**
* Create a tracker if needed and return it
* @param iDocument the document where to create
* @param iName the name
* @param oTracker the tracker
* @param iSendPopupMessageOnCreation to send a creation message if the tracker is created
* @return an object managing the error.
* @see SKGError
*/
static SKGError createTracker(SKGDocumentBank* iDocument,
const QString& iName,
SKGTrackerObject& oTracker,
bool iSendPopupMessageOnCreation = false);
/**
* Get all suboperations of this tracker
* @param oSubOperations all suboperations of this operation
* @return an object managing the error
* @see SKGError
*/
SKGError getSubOperations(SKGListSKGObjectBase& oSubOperations) const;
/**
* Set the comment of tracker
* @param iComment the comment
* @return an object managing the error
* @see SKGError
*/
SKGError setComment(const QString& iComment);
/**
* Get the comment of this tracker
* @return the comment
*/
QString getComment() const;
/**
* To set the closed attribute of this tracker
* @param iClosed the closed attribute: true or false
* @return an object managing the error
* @see SKGError
*/
SKGError setClosed(bool iClosed);
/**
* To know if the tracker has been closed or not
* @return an object managing the error
* @see SKGError
*/
bool isClosed() const;
/**
* Get the current amount
* @return the current amount
*/
double getCurrentAmount() const;
/**
* Merge iTracker in current tracker
* @param iTracker the tracker. All operations will be transferred into this tracker. The tracker will be removed
* @return an object managing the error
* @see SKGError
*/
SKGError merge(const SKGTrackerObject& iTracker);
};
/**
* Declare the class
*/
Q_DECLARE_TYPEINFO(SKGTrackerObject, Q_MOVABLE_TYPE);
#endif
diff --git a/skgbankmodeler/skgunitobject.cpp b/skgbankmodeler/skgunitobject.cpp
index 51f611322..f913401c9 100644
--- a/skgbankmodeler/skgunitobject.cpp
+++ b/skgbankmodeler/skgunitobject.cpp
@@ -1,2578 +1,2578 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+* along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file defines classes SKGUnitObject.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgunitobject.h"
#include <qdesktopservices.h>
#include <qdir.h>
#include <qdiriterator.h>
#include <qfile.h>
#include <qfileinfo.h>
#include <qmath.h>
#include <qprocess.h>
#include <qregexp.h>
#include <qsavefile.h>
#include <qstandardpaths.h>
#include <kconfig.h>
#include <kconfiggroup.h>
#include <klocalizedstring.h>
#include <kservice.h>
#include <kservicetypetrader.h>
#include "skgdocumentbank.h"
#include "skgoperationobject.h"
#include "skgtraces.h"
#include "skgtransactionmng.h"
#include "skgunitvalueobject.h"
SKGUnitObject::SKGUnitObject() : SKGUnitObject(nullptr)
{}
SKGUnitObject::SKGUnitObject(SKGDocument* iDocument, int iID) : SKGNamedObject(iDocument, QStringLiteral("v_unit"), iID)
{}
SKGUnitObject::~SKGUnitObject()
= default;
SKGUnitObject::SKGUnitObject(const SKGUnitObject& iObject) = default;
SKGUnitObject::SKGUnitObject(const SKGNamedObject& iObject)
{
if (iObject.getRealTable() == QStringLiteral("unit")) {
copyFrom(iObject);
} else {
*this = SKGNamedObject(iObject.getDocument(), QStringLiteral("v_unit"), iObject.getID());
}
}
SKGUnitObject::SKGUnitObject(const SKGObjectBase& iObject)
{
if (iObject.getRealTable() == QStringLiteral("unit")) {
copyFrom(iObject);
} else {
*this = SKGNamedObject(iObject.getDocument(), QStringLiteral("v_unit"), iObject.getID());
}
}
SKGUnitObject& SKGUnitObject::operator= (const SKGObjectBase& iObject)
{
copyFrom(iObject);
return *this;
}
QString SKGUnitObject::getWhereclauseId() const
{
QString output = SKGObjectBase::getWhereclauseId(); // clazy:exclude=skipped-base-method
if (output.isEmpty()) {
QString name = getName();
if (!name.isEmpty()) {
output = "t_name='" % SKGServices::stringToSqlString(name) % '\'';
}
QString symbol = getSymbol();
if (!symbol.isEmpty()) {
if (!output.isEmpty()) {
output += QStringLiteral(" OR ");
}
output += "t_symbol='" % SKGServices::stringToSqlString(symbol) % '\'';
}
if (!output.isEmpty()) {
output = '(' % output % ')';
}
}
return output;
}
QList<SKGServices::SKGUnitInfo> SKGUnitObject::currencies;
QStringList SKGUnitObject::getListofKnownCurrencies(bool iIncludingObsolete)
{
SKGTRACEINFUNC(10)
if (currencies.isEmpty()) {
// Search currencies
const QStringList dirs = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QStringLiteral("skrooge/currency/"), QStandardPaths::LocateDirectory);
for (const auto& dir : dirs) {
auto listDesktopFiles = QDir(dir).entryList(QStringList() << QStringLiteral("*.desktop"));
for (const auto& path : qAsConst(listDesktopFiles)) {
// Read the file
QFileInfo file(QStandardPaths::locate(QStandardPaths::GenericDataLocation, QStringLiteral("skrooge/currency/") + path));
KConfig cgFile(file.absoluteFilePath());
KConfigGroup cg(&cgFile, QStringLiteral("Currency Code"));
SKGServices::SKGUnitInfo unit;
unit.Name = cg.readEntry(QStringLiteral("Name"), QString()) + QStringLiteral(" (") + cg.readEntry(QStringLiteral("CurrencyCodeIsoAlpha3"), QString()) + QStringLiteral(")");
unit.Symbol = cg.readEntry(QStringLiteral("CurrencyUnitSymbolDefault"), QString());
if (unit.Symbol.isEmpty()) {
unit.Symbol = cg.readEntry(QStringLiteral("CurrencyCodeIsoAlpha3"), file.baseName());
}
unit.Value = 1;
unit.NbDecimal = cg.readEntry(QStringLiteral("CurrencyDecimalPlacesDisplay"), 2);
unit.Source = QStringLiteral("GrandTrunk");
unit.Date = cg.readEntry(QStringLiteral("CurrencyIntroducedDate"), QDate::currentDate());
unit.Obsolete = (cg.readEntry(QStringLiteral("CurrencySuspendedDate"), cg.readEntry(QStringLiteral("CurrencyWithdrawnDate"), QDate())) != QDate());
currencies.push_back(unit);
}
}
// Add other units
{
// CAC40
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a currency", "CAC 40");
info.Symbol = info.Name;
info.Country = i18nc("Noun, a country", "France");
info.Date = QDate(1987, 1, 1);
info.Internet = QStringLiteral("^FCHI");
info.Source = QStringLiteral("Yahoo");
info.NbDecimal = 2;
info.Value = -1;
currencies.push_back(info);
}
{
// NASDAQ
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a currency", "NASDAQ");
info.Symbol = info.Name;
info.Country = i18nc("Noun, a country", "United States");
info.Date = QDate(1971, 2, 5);
info.Internet = QStringLiteral("^IXIC");
info.Source = QStringLiteral("Yahoo");
info.NbDecimal = 2;
info.Value = -1;
currencies.push_back(info);
}
{
// Dow Jones
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a currency", "Dow Jones (DJIA)");
info.Symbol = QStringLiteral("DJIA");
info.Country = i18nc("Noun, a country", "United States");
info.Date = QDate(1884, 1, 1);
info.Internet = QStringLiteral("^DJI");
info.Source = QStringLiteral("Yahoo");
info.NbDecimal = 2;
info.Value = -1;
currencies.push_back(info);
}
{
// SBF 120
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a currency", "SBF 120");
info.Symbol = info.Name;
info.Country = i18nc("Noun, a country", "France");
info.Date = QDate(1990, 12, 31);
info.Internet = QStringLiteral("^SBF120");
info.Source = QStringLiteral("Yahoo");
info.NbDecimal = 2;
info.Value = -1;
currencies.push_back(info);
}
{
// S&P 500
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a currency", "S&P 500");
info.Symbol = info.Name;
info.Country = i18nc("Noun, a country", "United States");
info.Date = QDate(1920, 1, 1);
info.Internet = QStringLiteral("^GSPC");
info.Source = QStringLiteral("Yahoo");
info.NbDecimal = 2;
info.Value = -1;
currencies.push_back(info);
}
{
// FTSE 100
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a currency", "FTSE 100");
info.Symbol = info.Name;
info.Country = i18nc("Noun, a country", "England");
info.Date = QDate(1984, 1, 3);
info.Internet = QStringLiteral("^FTSE");
info.Source = QStringLiteral("Yahoo");
info.NbDecimal = 2;
info.Value = -1;
currencies.push_back(info);
}
{
// DAX
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a currency", "DAX");
info.Symbol = info.Name;
info.Country = i18nc("Noun, a country", "Germany");
info.Date = QDate(1920, 1, 1);
info.Internet = QStringLiteral("^GDAXI");
info.Source = QStringLiteral("Yahoo");
info.NbDecimal = 2;
info.Value = -1;
currencies.push_back(info);
}
{
// NIKKEI 225
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a currency", "NIKKEI 225");
info.Symbol = info.Name;
info.Country = i18nc("Noun, a country", "Japan");
info.Date = QDate(1920, 1, 1);
info.Internet = QStringLiteral("^N225");
info.Source = QStringLiteral("Yahoo");
info.NbDecimal = 2;
info.Value = -1;
currencies.push_back(info);
}
{
// HANG SENG
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a currency", "HANG SENG");
info.Symbol = info.Name;
info.Country = i18nc("Noun, a country", "China");
info.Date = QDate(1920, 1, 1);
info.Internet = QStringLiteral("^HSI");
info.Source = QStringLiteral("Yahoo");
info.NbDecimal = 2;
info.Value = -1;
currencies.push_back(info);
}
{
// STRAITS TIMES
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a currency", "STRAITS TIMES");
info.Symbol = info.Name;
info.Date = QDate(1920, 1, 1);
info.Country = i18nc("Noun, a country", "Singapore");
info.Internet = QStringLiteral("^STI");
info.Source = QStringLiteral("Yahoo");
info.NbDecimal = 2;
info.Value = -1;
currencies.push_back(info);
}
{
// BITCOIN
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a currency", "Bitcoin");
info.Symbol = QStringLiteral("BTC");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("BTC");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// ETHEREUM
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Ethereum");
info.Symbol = QStringLiteral("ETH");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("ETH");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// RIPPLE
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Ripple");
info.Symbol = QStringLiteral("XRP");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("XRP");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// BITCOIN-CASH
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Bitcoin Cash");
info.Symbol = QStringLiteral("BCH");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("BCH");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// CARDANO
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Cardano");
info.Symbol = QStringLiteral("ADA");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("ADA");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// NEM
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "NEM");
info.Symbol = QStringLiteral("XEM");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("XEM");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// LITECOIN
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Litecoin");
info.Symbol = QStringLiteral("LTC");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("LTC");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// STELLAR
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Stellar");
info.Symbol = QStringLiteral("XLM");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("XLM");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// IOTA
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "IOTA");
info.Symbol = QStringLiteral("MIOTA");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("MIOTA");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// TRON
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "TRON");
info.Symbol = QStringLiteral("TRX");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("TRX");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// DASH
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Dash");
info.Symbol = QStringLiteral("DASH");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("DASH");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// NEO
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "NEO");
info.Symbol = QStringLiteral("NEO");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("NEO");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// MONERO
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Monero");
info.Symbol = QStringLiteral("XMR");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("XMR");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// EOS
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "EOS");
info.Symbol = QStringLiteral("EOS");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("EOS");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// QTUM
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Qtum");
info.Symbol = QStringLiteral("QTUM");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("QTUM");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// ICON
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "ICON");
info.Symbol = QStringLiteral("ICX");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("ICX");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// BITCOIN-GOLD
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Bitcoin Gold");
info.Symbol = QStringLiteral("BTG");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("BTG");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// LISK
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Lisk");
info.Symbol = QStringLiteral("LSK");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("LSK");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// RAIBLOCKS
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "RaiBlocks");
info.Symbol = QStringLiteral("XRB");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("XRB");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// ETHEREUM-CLASSIC
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Ethereum Classic");
info.Symbol = QStringLiteral("ETC");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("ETC");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// VERGE
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Verge");
info.Symbol = QStringLiteral("XVG");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("XVG");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// SIACOIN
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Siacoin");
info.Symbol = QStringLiteral("SC");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("SC");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// OMISEGO
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "OmiseGO");
info.Symbol = QStringLiteral("OMG");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("OMG");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// BYTECOIN-BCN
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Bytecoin");
info.Symbol = QStringLiteral("BCN");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("BCN");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// BITCONNECT
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "BitConnect");
info.Symbol = QStringLiteral("BCC");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("BCC");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// POPULOUS
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Populous");
info.Symbol = QStringLiteral("PPT");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("PPT");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// STRATIS
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Stratis");
info.Symbol = QStringLiteral("STRAT");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("STRAT");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// ZCASH
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Zcash");
info.Symbol = QStringLiteral("ZEC");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("ZEC");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// DENTACOIN
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Dentacoin");
info.Symbol = QStringLiteral("DCN");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("DCN");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// BITSHARES
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "BitShares");
info.Symbol = QStringLiteral("BTS");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("BTS");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// BINANCE-COIN
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Binance Coin");
info.Symbol = QStringLiteral("BNB");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("BNB");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// DOGECOIN
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Dogecoin");
info.Symbol = QStringLiteral("DOGE");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("DOGE");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// STATUS
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Status");
info.Symbol = QStringLiteral("SNT");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("SNT");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// ARDOR
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Ardor");
info.Symbol = QStringLiteral("ARDR");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("ARDR");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// KUCOIN-SHARES
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "KuCoin Shares");
info.Symbol = QStringLiteral("KCS");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("KCS");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// TETHER
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Tether");
info.Symbol = QStringLiteral("USDT");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("USDT");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// STEEM
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Steem");
info.Symbol = QStringLiteral("STEEM");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("STEEM");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// WAVES
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Waves");
info.Symbol = QStringLiteral("WAVES");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("WAVES");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// VECHAIN
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "VeChain");
info.Symbol = QStringLiteral("VEN");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("VEN");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// DIGIBYTE
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "DigiByte");
info.Symbol = QStringLiteral("DGB");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("DGB");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// KOMODO
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Komodo");
info.Symbol = QStringLiteral("KMD");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("KMD");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// DRAGONCHAIN
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Dragonchain");
info.Symbol = QStringLiteral("DRGN");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("DRGN");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// AUGUR
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Augur");
info.Symbol = QStringLiteral("REP");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("REP");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// GOLEM-NETWORK-TOKENS
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Golem");
info.Symbol = QStringLiteral("GNT");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("GNT");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// VERITASEUM
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Veritaseum");
info.Symbol = QStringLiteral("VERI");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("VERI");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// HSHARE
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Hshare");
info.Symbol = QStringLiteral("HSR");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("HSR");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// KIN
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Kin");
info.Symbol = QStringLiteral("KIN");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("KIN");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// SALT
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "SALT");
info.Symbol = QStringLiteral("SALT");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("SALT");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// ELECTRONEUM
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Electroneum");
info.Symbol = QStringLiteral("ETN");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("ETN");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// ARK
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Ark");
info.Symbol = QStringLiteral("ARK");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("ARK");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// DENT
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Dent");
info.Symbol = QStringLiteral("DENT");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("DENT");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// ETHOS
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Ethos");
info.Symbol = QStringLiteral("ETHOS");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("ETHOS");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// BASIC-ATTENTION-TOKEN
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Basic Attention Token");
info.Symbol = QStringLiteral("BAT");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("BAT");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// REDDCOIN
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "ReddCoin");
info.Symbol = QStringLiteral("RDD");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("RDD");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// 0X
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "0x");
info.Symbol = QStringLiteral("ZRX");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("ZRX");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// DECRED
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Decred");
info.Symbol = QStringLiteral("DCR");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("DCR");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// NEXUS
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Nexus");
info.Symbol = QStringLiteral("NXS");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("NXS");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// EXPERIENCE-POINTS
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Experience Points");
info.Symbol = QStringLiteral("XP");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("XP");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// QASH
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "QASH");
info.Symbol = QStringLiteral("QASH");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("QASH");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// KYBER-NETWORK
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Kyber Network");
info.Symbol = QStringLiteral("KNC");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("KNC");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// PIVX
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "PIVX");
info.Symbol = QStringLiteral("PIVX");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("PIVX");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// FUNFAIR
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "FunFair");
info.Symbol = QStringLiteral("FUN");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("FUN");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// FACTOM
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Factom");
info.Symbol = QStringLiteral("FCT");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("FCT");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// NEBLIO
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Neblio");
info.Symbol = QStringLiteral("NEBL");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("NEBL");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// REQUEST-NETWORK
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Request Network");
info.Symbol = QStringLiteral("REQ");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("REQ");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// AETERNITY
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Aeternity");
info.Symbol = QStringLiteral("AE");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("AE");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// SUBSTRATUM
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Substratum");
info.Symbol = QStringLiteral("SUB");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("SUB");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// POWER-LEDGER
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Power Ledger");
info.Symbol = QStringLiteral("POWR");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("POWR");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// WAX
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "WAX");
info.Symbol = QStringLiteral("WAX");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("WAX");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// AELF
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "aelf");
info.Symbol = QStringLiteral("ELF");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("ELF");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// BYTOM
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Bytom");
info.Symbol = QStringLiteral("BTM");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("BTM");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// AION
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Aion");
info.Symbol = QStringLiteral("AION");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("AION");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// RCHAIN
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "RChain");
info.Symbol = QStringLiteral("RHOC");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("RHOC");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// DIGITALNOTE
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "DigitalNote");
info.Symbol = QStringLiteral("XDN");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("XDN");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// ENIGMA-PROJECT
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Enigma");
info.Symbol = QStringLiteral("ENG");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("ENG");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// NXT
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Nxt");
info.Symbol = QStringLiteral("NXT");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("NXT");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// TIME-NEW-BANK
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Time New Bank");
info.Symbol = QStringLiteral("TNB");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("TNB");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// BITCOINDARK
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "BitcoinDark");
info.Symbol = QStringLiteral("BTCD");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("BTCD");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// MONACOIN
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "MonaCoin");
info.Symbol = QStringLiteral("MONA");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("MONA");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// QUANTSTAMP
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Quantstamp");
info.Symbol = QStringLiteral("QSP");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("QSP");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// MAIDSAFECOIN
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "MaidSafeCoin");
info.Symbol = QStringLiteral("MAID");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("MAID");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// BYTEBALL
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Byteball Bytes");
info.Symbol = QStringLiteral("GBYTE");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("GBYTE");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// GAS
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Gas");
info.Symbol = QStringLiteral("GAS");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("GAS");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// CHAINLINK
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "ChainLink");
info.Symbol = QStringLiteral("LINK");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("LINK");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// SYSCOIN
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Syscoin");
info.Symbol = QStringLiteral("SYS");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("SYS");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// SANTIMENT
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Santiment Network Token");
info.Symbol = QStringLiteral("SAN");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("SAN");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// COBINHOOD
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Cobinhood");
info.Symbol = QStringLiteral("COB");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("COB");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// RED-PULSE
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Red Pulse");
info.Symbol = QStringLiteral("RPX");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("RPX");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// DIGIXDAO
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "DigixDAO");
info.Symbol = QStringLiteral("DGD");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("DGD");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// TENX
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "TenX");
info.Symbol = QStringLiteral("PAY");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("PAY");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// ICONOMI
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Iconomi");
info.Symbol = QStringLiteral("ICN");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("ICN");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// POET
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Po.et");
info.Symbol = QStringLiteral("POE");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("POE");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// ZCOIN
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "ZCoin");
info.Symbol = QStringLiteral("XZC");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("XZC");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// GNOSIS-GNO
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Gnosis");
info.Symbol = QStringLiteral("GNO");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("GNO");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// BLOCKV
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "BLOCKv");
info.Symbol = QStringLiteral("VEE");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("VEE");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// WALTON
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Walton");
info.Symbol = QStringLiteral("WTC");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("WTC");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// PACCOIN
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "PACcoin");
info.Symbol = QStringLiteral("PAC");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("PAC");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// DEEPBRAIN-CHAIN
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "DeepBrain Chain");
info.Symbol = QStringLiteral("DBC");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("DBC");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// ETHLEND
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "ETHLend");
info.Symbol = QStringLiteral("LEND");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("LEND");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
{
// CIVIC
SKGServices::SKGUnitInfo info;
info.Name = i18nc("Noun, a cryptocurrency", "Civic");
info.Symbol = QStringLiteral("CVC");
info.Date = QDate(2009, 2, 4);
info.Country = i18nc("Noun, the country of bitcoin", "Internet");
info.Internet = QStringLiteral("CVC");
info.Source = QStringLiteral("CoinMarketCap");
info.Parent = QStringLiteral("USD");
info.NbDecimal = 4;
info.Value = -1;
currencies.push_back(info);
}
}
QStringList output;
output.reserve(currencies.count());
for (const auto& unit : qAsConst(currencies)) {
if (iIncludingObsolete || !unit.Obsolete) {
output.push_back(unit.Name);
}
}
output.sort();
return output;
}
QString SKGUnitObject::getInternationalCode(const QString& iUnitName)
{
SKGTRACEINFUNC(10)
QString output = iUnitName;
QRegExp rx(QStringLiteral(".*\\(([^\\(\\)]+)\\)[^\\(\\)]*"));
if (rx.indexIn(iUnitName) != -1) {
output = rx.cap(1);
}
return output;
}
SKGServices::SKGUnitInfo SKGUnitObject::getUnitInfo()
{
SKGTRACEINFUNC(10)
SKGServices::SKGUnitInfo info;
info.Name = getName();
info.Value = getAmount();
info.NbDecimal = getNumberDecimal();
info.Symbol = getSymbol();
info.Country = getCountry();
info.Internet = getInternetCode();
info.Date = QDate::currentDate();
return info;
}
SKGServices::SKGUnitInfo SKGUnitObject::getUnitInfo(const QString& iUnitName)
{
SKGTRACEINFUNC(10)
SKGServices::SKGUnitInfo info;
if (currencies.isEmpty()) {
getListofKnownCurrencies(false);
}
QString isoCode = getInternationalCode(iUnitName);
for (const auto& unit : qAsConst(currencies)) {
if (getInternationalCode(unit.Name) == isoCode) {
info = unit;
break;
}
}
return info;
}
SKGError SKGUnitObject::createCurrencyUnit(SKGDocumentBank* iDocument, const QString& iUnitName, SKGUnitObject& oUnit)
{
SKGError err;
SKGTRACEINFUNCRC(10, err)
if (iDocument != nullptr) {
SKGUnitObject parentUnit;
oUnit = SKGUnitObject(iDocument);
SKGUnitObject::UnitType type = SKGUnitObject::CURRENCY;
SKGServices::SKGUnitInfo prim = iDocument->getPrimaryUnit();
SKGServices::SKGUnitInfo seco = iDocument->getSecondaryUnit();
// Get information on the unit
SKGServices::SKGUnitInfo info = getUnitInfo(iUnitName);
if (info.Name.isEmpty()) {
err = SKGError(ERR_INVALIDARG, i18nc("Error message", "Unknown unit '%1'", iUnitName));
}
if (!err && !info.Parent.isEmpty()) {
err = createCurrencyUnit(iDocument, info.Parent, parentUnit);
}
// Set the type
if (info.Name == info.Symbol) {
// This is an index
type = SKGUnitObject::INDEX;
} else if (!info.Parent.isEmpty()) {
// This is a secondary unit
type = (seco.Symbol.isEmpty() || seco.Symbol == info.Symbol ? SKGUnitObject::SECONDARY : SKGUnitObject::CURRENCY);
} else {
// As primary
type = (prim.Symbol.isEmpty() || prim.Symbol == info.Symbol ? SKGUnitObject::PRIMARY : SKGUnitObject::CURRENCY);
}
// Point on primary unit
if (info.Value == 1 && !err && (type == SKGUnitObject::CURRENCY || type == SKGUnitObject::SECONDARY)) {
SKGUnitObject primunit(iDocument);
err = primunit.setSymbol(prim.Symbol);
IFOKDO(err, primunit.load())
IFOK(err) {
QString codeprimunit = getInternationalCode(primunit.getName());
QString codeunit = getInternationalCode(info.Name);
if (!codeprimunit.isEmpty()) {
info.Internet = codeunit % '/' % codeprimunit;
info.Value = -1;
parentUnit = SKGUnitObject(iDocument);
err = parentUnit.setSymbol(prim.Symbol);
IFOKDO(err, parentUnit.load())
}
}
}
IFOKDO(err, oUnit.setName(info.Name))
if (!err && oUnit.exist()) {
err = oUnit.load();
}
IFOKDO(err, oUnit.setType(type))
IFOKDO(err, oUnit.setSymbol(info.Symbol))
IFOKDO(err, oUnit.setInternetCode(info.Internet))
IFOKDO(err, oUnit.setDownloadSource(info.Source))
IFOKDO(err, oUnit.setCountry(info.Country))
IFOKDO(err, oUnit.setNumberDecimal(info.NbDecimal))
if (!err && parentUnit.exist()) {
err = oUnit.setUnit(parentUnit);
}
IFOKDO(err, oUnit.save())
// Creation of the value
if (info.Value > 0) {
SKGUnitValueObject unitValue;
IFOKDO(err, oUnit.addUnitValue(unitValue))
IFOKDO(err, unitValue.setDate(info.Date))
IFOKDO(err, unitValue.setQuantity(info.Value))
IFOKDO(err, unitValue.save())
}
}
return err;
}
double SKGUnitObject::convert(double iValue, const SKGUnitObject& iUnitFrom, const SKGUnitObject& iUnitTo, QDate iDate)
{
double output = iValue;
if (iUnitFrom != iUnitTo) {
double valFrom = iUnitFrom.getAmount(iDate);
double valTo = iUnitTo.getAmount(iDate);
output = iValue * valFrom / valTo;
}
return output;
}
SKGError SKGUnitObject::setSymbol(const QString& iSymbol)
{
return setAttribute(QStringLiteral("t_symbol"), iSymbol);
}
QString SKGUnitObject::getSymbol() const
{
return getAttribute(QStringLiteral("t_symbol"));
}
QString SKGUnitObject::getDownloadSource() const
{
return getAttribute(QStringLiteral("t_source"));
}
SKGError SKGUnitObject::setDownloadSource(const QString& iSource)
{
return setAttribute(QStringLiteral("t_source"), iSource);
}
SKGError SKGUnitObject::setNumberDecimal(int iNb)
{
return setAttribute(QStringLiteral("i_nbdecimal"), SKGServices::intToString(iNb));
}
int SKGUnitObject::getNumberDecimal() const
{
return SKGServices::stringToInt(getAttribute(QStringLiteral("i_nbdecimal")));
}
SKGError SKGUnitObject::setCountry(const QString& iCountry)
{
return setAttribute(QStringLiteral("t_country"), iCountry);
}
QString SKGUnitObject::getCountry() const
{
return getAttribute(QStringLiteral("t_country"));
}
SKGError SKGUnitObject::setInternetCode(const QString& iCode)
{
return setAttribute(QStringLiteral("t_internet_code"), iCode);
}
QString SKGUnitObject::getInternetCode() const
{
return getAttribute(QStringLiteral("t_internet_code"));
}
SKGError SKGUnitObject::setType(SKGUnitObject::UnitType iType)
{
SKGError err;
if (getAttribute(QStringLiteral("t_type")).isEmpty() || this->getType() != iType) {
// Guaranty that PRIMARY and SECONDARY is unique
if (iType == PRIMARY || iType == SECONDARY) {
// Set old SECONDARY as CURRENCY
err = getDocument()->executeSqliteOrder(QStringLiteral("UPDATE unit SET t_type='C' WHERE t_type='2'"));
// Set old PRIMARY as SECONDARY
if (!err && iType == PRIMARY) {
err = getDocument()->executeSqliteOrder(QStringLiteral("UPDATE unit SET t_type='2' WHERE t_type='1'"));
}
}
}
IFOKDO(err, setAttribute(QStringLiteral("t_type"), (iType == CURRENCY ? QStringLiteral("C") : (iType == PRIMARY ? QStringLiteral("1") : (iType == SECONDARY ? QStringLiteral("2") : (iType == SHARE ? QStringLiteral("S") : (iType == INDEX ? QStringLiteral("I") : QStringLiteral("O"))))))))
return err;
}
SKGUnitObject::UnitType SKGUnitObject::getType() const
{
QString typeString = getAttribute(QStringLiteral("t_type"));
return (typeString == QStringLiteral("C") ? CURRENCY : (typeString == QStringLiteral("S") ? SHARE : (typeString == QStringLiteral("1") ? PRIMARY : (typeString == QStringLiteral("2") ? SECONDARY : (typeString == QStringLiteral("I") ? INDEX : OBJECT)))));
}
SKGError SKGUnitObject::getUnit(SKGUnitObject& oUnit) const
{
SKGError err;
if (getDocument() != nullptr) {
err = getDocument()->getObject(QStringLiteral("v_unit"), "id=" % getAttribute(QStringLiteral("rd_unit_id")), oUnit);
}
return err;
}
SKGError SKGUnitObject::setUnit(const SKGUnitObject& iUnit)
{
SKGError err;
if (*this == iUnit && iUnit.getID() != 0) {
err = SKGError(ERR_INVALIDARG, i18nc("Error message", "Reference unit of a unit cannot be itself."));
} else {
err = setAttribute(QStringLiteral("rd_unit_id"), SKGServices::intToString(iUnit.getID()));
}
return err;
}
SKGError SKGUnitObject::removeUnit()
{
return setAttribute(QStringLiteral("rd_unit_id"), QStringLiteral("0"));
}
SKGError SKGUnitObject::addUnitValue(SKGUnitValueObject& oUnitValue)
{
SKGError err;
if (getID() == 0) {
err = SKGError(ERR_FAIL, i18nc("Error message", "%1 failed because linked object is not yet saved in the database.", QStringLiteral("SKGUnitObject::addUnitValue")));
} else {
oUnitValue = SKGUnitValueObject(qobject_cast<SKGDocumentBank*>(getDocument()));
err = oUnitValue.setAttribute(QStringLiteral("rd_unit_id"), SKGServices::intToString(getID()));
}
return err;
}
SKGError SKGUnitObject::simplify()
{
SKGListSKGObjectBase values;
SKGError err = getUnitValues(values);
int nb = values.count();
if (!err && (nb != 0)) {
QHash<QString, SKGListSKGObjectBase> groups;
SKGBEGINPROGRESSTRANSACTION(*getDocument(), "#INTERNAL#" % i18nc("Progression step", "Simplify unit"), err, 2)
// Build groups
{
SKGBEGINPROGRESSTRANSACTION(*getDocument(), "#INTERNAL#" % i18nc("Progression step", "Analyze unit"), err, nb)
QDate limit1 = QDate::currentDate().addMonths(-3);
QDate limit2 = QDate::currentDate().addYears(-1);
QDate limit3 = QDate::currentDate().addYears(-3);
for (int i = nb - 1; !err && i >= 0 ; --i) {
SKGUnitValueObject v(values.at(i));
QDate date = v.getDate();
if (date >= limit1) {
// No simplification ==> nothing to do
} else if (date >= limit2) {
// Simplification by group of 30 days
QString key = limit1.addDays(30 * (limit1.daysTo(date) / 30)).toString();
SKGListSKGObjectBase group = groups[key];
group.push_back(v);
groups[key] = group;
} else if (date >= limit3) {
// Simplification by group of 2 months
QString key = limit2.addDays(60 * (limit2.daysTo(date) / 60)).toString();
SKGListSKGObjectBase group = groups[key];
group.push_back(v);
groups[key] = group;
} else {
// Simplification by group of 6 months
QString key = limit3.addDays(180 * (limit2.daysTo(date) / 180)).toString();
SKGListSKGObjectBase group = groups[key];
group.push_back(v);
groups[key] = group;
}
IFOKDO(err, getDocument()->stepForward(nb - i))
}
}
IFOKDO(err, getDocument()->stepForward(1))
// Simplify
{
QList<QString> keys = groups.keys();
nb = keys.count();
SKGBEGINPROGRESSTRANSACTION(*getDocument(), "#INTERNAL#" % i18nc("Progression step", "Remove useless values"), err, nb)
for (int i = 0; !err && i < nb ; ++i) {
const QString& k = keys.at(i);
SKGListSKGObjectBase group = groups[k];
// Simplify the group
int nb2 = group.count();
// Compute min and max
double min = 10e20;
double max = 0;
for (int j = 0; j < nb2; ++j) {
SKGUnitValueObject v1(group.at(j));
double y1 = v1.getQuantity();
min = qMin(y1, min);
max = qMax(y1, max);
}
// Simplify
for (int j = 1; !err && j < nb2 - 1; ++j) {
SKGUnitValueObject v1(group.at(j));
double y1 = v1.getQuantity();
if (y1 != min && y1 != max) {
err = v1.remove();
}
}
IFOKDO(err, getDocument()->stepForward(i + 1))
}
}
IFOKDO(err, getDocument()->stepForward(2))
}
return err;
}
SKGError SKGUnitObject::getUnitValues(SKGListSKGObjectBase& oUnitValueList) const
{
SKGError err = getDocument()->getObjects(QStringLiteral("v_unitvalue"),
"rd_unit_id=" % SKGServices::intToString(getID()) % " ORDER BY d_date",
oUnitValueList);
return err;
}
SKGError SKGUnitObject::getLastUnitValue(SKGUnitValueObject& oUnitValue) const
{
return SKGObjectBase::getDocument()->getObject(QStringLiteral("v_unitvalue"),
"rd_unit_id=" % SKGServices::intToString(getID()) % " AND d_date=(select MAX(u2.d_date) from unitvalue u2 where u2.rd_unit_id=" % SKGServices::intToString(getID()) % ')',
oUnitValue);
}
SKGError SKGUnitObject::getUnitValue(QDate iDate, SKGUnitValueObject& oUnitValue) const
{
QString ids = SKGServices::intToString(getID());
QString dates = SKGServices::dateToSqlString(QDateTime(iDate));
SKGError err = SKGObjectBase::getDocument()->getObject(QStringLiteral("v_unitvalue"),
"rd_unit_id=" % ids % " AND d_date<='" % dates %
"' AND ABS(strftime('%s','" % dates %
"')-strftime('%s',d_date))=(select MIN(ABS(strftime('%s','" % dates %
"')-strftime('%s',u2.d_date))) from unitvalue u2 where u2.rd_unit_id=" % ids %
" AND u2.d_date<='" % dates % "')",
oUnitValue);
// If not found then get first
IFKO(err) err = SKGObjectBase::getDocument()->getObject(QStringLiteral("v_unitvalue"),
"rd_unit_id=" % SKGServices::intToString(getID()) % " AND d_date=(select MIN(d_date) from unitvalue where rd_unit_id=" %
SKGServices::intToString(getID()) % ')',
oUnitValue);
return err;
}
double SKGUnitObject::getAmount(QDate iDate) const
{
SKGTRACEINFUNC(10)
double output = 0;
if (getType() == SKGUnitObject::PRIMARY) {
output = 1.0;
} else if (getDocument() != nullptr) {
// Search result in cache
QString ids = SKGServices::intToString(getID());
QString dates = SKGServices::dateToSqlString(QDateTime(iDate));
QString key = "unitvalue-" % ids % '-' % dates;
QString val = getDocument()->getCachedValue(key);
if (val.isEmpty()) {
// Get quantity
double quantity = 1;
SKGUnitValueObject uv;
if (getUnitValue(iDate, uv).isSucceeded()) {
quantity = uv.getQuantity();
}
SKGUnitObject unit;
double coef = 1;
if (getUnit(unit).isSucceeded()) {
if (unit != *this) {
coef = unit.getAmount(iDate);
}
}
output = coef * quantity;
getDocument()->addValueInCache(key, SKGServices::doubleToString(output));
if (getAttribute(QStringLiteral("i_NBVALUES")) == QStringLiteral("1")) {
// Store value for this symbol for all date
getDocument()->addValueInCache("unitvalue-" % ids, SKGServices::doubleToString(output));
}
} else {
output = SKGServices::stringToDouble(val);
}
}
return output;
}
double SKGUnitObject::getDailyChange(QDate iDate) const
{
double output = 0;
SKGStringListList result;
SKGError err = getDocument()->executeSelectSqliteOrder(
"SELECT d_date, f_quantity from unitvalue where rd_unit_id=" %
SKGServices::intToString(getID()) %
" AND d_date<='" % SKGServices::dateToSqlString(QDateTime(iDate)) %
"' ORDER BY d_date DESC LIMIT 2",
result);
if (!err && result.count() == 3) {
double v2 = SKGServices::stringToDouble(result.at(1).at(1));
double v1 = SKGServices::stringToDouble(result.at(2).at(1));
QDate d2 = SKGServices::stringToTime(result.at(1).at(0)).date();
QDate d1 = SKGServices::stringToTime(result.at(2).at(0)).date();
output = 100 * (qExp(qLn(v2 / v1) / (SKGServices::nbWorkingDays(d1, d2))) - 1);
}
return output;
}
SKGError SKGUnitObject::split(double iRatio) const
{
SKGError err;
if (iRatio > 0) {
err = getDocument()->executeSqliteOrder("UPDATE unitvalue SET f_quantity=f_quantity/" % SKGServices::doubleToString(iRatio) %
" WHERE rd_unit_id=" % SKGServices::intToString(getID()));
IFOKDO(err, getDocument()->executeSqliteOrder("UPDATE suboperation SET f_value=f_value*" % SKGServices::doubleToString(iRatio) %
" WHERE rd_operation_id IN (SELECT id FROM operation WHERE rc_unit_id=" % SKGServices::intToString(getID()) % ')'));
} else {
err = SKGError(ERR_INVALIDARG, i18nc("Error message", "Invalid ratio. Ratio must be greater than 0."));
}
return err;
}
QStringList SKGUnitObject::downloadSources()
{
QStringList sources;
// Get sources from .txt file (old mode) TODO: Remove
QString a = QStringLiteral("skrooge/quotes");
const auto list = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, a, QStandardPaths::LocateDirectory);
for (const auto& dir : list) {
QDirIterator it(dir, QStringList() << QStringLiteral("*.txt"));
while (it.hasNext()) {
QFileInfo f(it.next());
QString file2 = f.completeBaseName();
if (!sources.contains(file2)) {
sources.push_back(file2);
}
}
}
// Get sources from.desktop file
const auto list2 = KServiceTypeTrader::self()->query(QStringLiteral("skrooge/source"));
for (const auto& service : list2) {
auto name = service->property(QStringLiteral("X-KDE-PluginInfo-Name"), QVariant::String).toString();
if (!sources.contains(name)) {
sources.push_back(name);
}
}
sources.sort();
return sources;
}
QString SKGUnitObject::getCommentFromSource(const QString& iSource)
{
QString output;
const auto list2 = KServiceTypeTrader::self()->query(QStringLiteral("skrooge/source"));
for (const auto& service : list2) {
auto name = service->property(QStringLiteral("X-KDE-PluginInfo-Name"), QVariant::String).toString();
if (name == iSource) {
output = service->property(QStringLiteral("Comment"), QVariant::String).toString();
break;
}
}
return output;
}
SKGError SKGUnitObject::addSource(const QString& iNewSource, bool iOpenSource)
{
SKGError err;
QString path = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation);
QDir(path).mkpath(QStringLiteral("skrooge/quotes/"));
QString newfile = path + "/skrooge/quotes/" % iNewSource % ".txt";
// Create the new file
QSaveFile file(newfile);
// Check if file already existing
if (!QFile(newfile).exists()) {
// Creation of the template
if (!file.open(QIODevice::WriteOnly)) {
err.setReturnCode(ERR_INVALIDARG).setMessage(i18nc("Error message", "Save file '%1' failed", newfile));
} else {
QTextStream out(&file);
out << "#" << i18nc("Description test for a text file used to define a source of download",
"The URL or the SCRIPT of the source. %1 will be replaced by the internet code of the unit", "%1") << endl;
out << "#" << i18nc("Description test for a text file used to define a source of download",
"%1 will be replaced by the current day in format yyyy-MM-dd", "%2") << endl;
out << "#" << i18nc("Description test for a text file used to define a source of download",
"%1 will be replaced by the previous date in format yyyy-MM-dd", "%3") << endl;
out << "url=http://server/?s=%1" << endl;
out << "or" << endl;
out << "script=mydownloadscript %1" << endl << endl;
out << "#" << i18nc("Description test for a text file used to define a source of download",
"The mode (HTML or CSV or CSVR). In HTML mode, only one value will be extracted from downloaded page. In CSV mode, a value per line will be extracted. CSVR means CSV in reverse mode.") << endl;
out << "mode=CSV, CSVR or or HTML" << endl << endl;
out << "#" << i18nc("Description test for a text file used to define a source of download",
"The regular expression for the price (see %1)", "http://doc.qt.io/qt-5/qregexp.html") << endl;
out << "price=" << endl << endl;
out << "#" << i18nc("Description test for a text file used to define a source of download",
"The regular expression for the date (see %1)", "http://doc.qt.io/qt-5/qregexp.html") << endl;
out << "date=" << endl << endl;
out << "#" << i18nc("Description test for a text file used to define a source of download",
"The format of the date (see %1) or \"UNIX\" for unix time", "http://doc.qt.io/qt-5/qdate.html#fromString-1") << endl;
out << "dateformat=yyyy-MM-dd" << endl;
// Close file
file.commit();
}
}
// Open the created or already existing file
if (iOpenSource) {
QDesktopServices::openUrl(QUrl::fromLocalFile(newfile));
}
return err;
}
SKGError SKGUnitObject::deleteSource(const QString& iSource)
{
SKGError err;
QString fileName = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QLatin1Char('/') + QStringLiteral("skrooge/quotes/") % iSource % ".txt";
// Delete the file
QFile file(fileName);
if (!file.remove()) {
err.setReturnCode(ERR_INVALIDARG).setMessage(i18nc("Error message", "Deletion of '%1' failed", fileName));
}
return err;
}
bool SKGUnitObject::isWritable(const QString& iSource)
{
QString fileName = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QLatin1Char('/') + QStringLiteral("skrooge/quotes/") % iSource % ".txt";
return QFileInfo(fileName).isWritable();
}
SKGError SKGUnitObject::downloadUnitValue(UnitDownloadMode iMode, int iNbMaxValues)
{
SKGError err;
SKGTRACEINFUNCRC(10, err)
QString unitname = getName();
QString code = getInternetCode();
bool invert = code.contains(QStringLiteral(" /"));
code.remove(QStringLiteral(" /"));
QString source = getDownloadSource();
auto* doc = qobject_cast<SKGDocumentBank*>(getDocument());
if (!code.isEmpty() && (doc != nullptr)) {
// Get last date
QDate firstDate;
SKGStringListList result;
doc->executeSelectSqliteOrder("SELECT MAX(d_date) FROM unitvalue where rd_unit_id=" % SKGServices::intToString(getID()), result);
if (result.count() == 2) {
firstDate = SKGServices::stringToTime(result.at(1).at(0)).date().addDays(-1);
}
if (code.startsWith(QLatin1String("="))) {
// MODE FORMULAR
// Set 1st january if date is not found
if (!firstDate.isValid()) {
firstDate.setDate(QDate::currentDate().year(), 1, 1);
}
// Compute yearly rate
double rate = SKGServices::stringToDouble(code.right(code.length() - 1));
// Compute rate for step
double step = (iMode == LAST_MONTHLY || iMode == ALL_MONTHLY ? 12.0 : (iMode == LAST_WEEKLY || iMode == ALL_WEEKLY ? 365.0 / 7.0 : 365));
double rate2 = 100.0 * (qExp(qLn(1 + rate / 100.0) / step) - 1.0);
// Get last value
SKGStringListList result2;
double value = 100;
doc->executeSelectSqliteOrder("SELECT f_quantity FROM unitvalue where rd_unit_id=(SELECT id from unit where t_name='" % SKGServices::stringToSqlString(unitname) % "') AND d_date='" % SKGServices::dateToSqlString(QDateTime(firstDate)) % '\'', result2);
if (result2.count() == 2) {
value = SKGServices::stringToDouble(result2.at(1).at(0));
}
// Compute and add values
while (!err && firstDate <= QDate::currentDate()) {
// Compute next date and value
if (iMode == LAST_MONTHLY || iMode == ALL_MONTHLY) {
firstDate = firstDate.addMonths(1);
} else if (iMode == LAST_WEEKLY || iMode == ALL_WEEKLY) {
firstDate = firstDate.addDays(7);
} else {
firstDate = firstDate.addDays(1);
}
value *= (1 + rate2 / 100.0);
// Create value
SKGUnitValueObject val;
err = addUnitValue(val);
IFOKDO(err, val.setDate(firstDate))
IFOKDO(err, val.setQuantity(value))
IFOKDO(err, val.save())
}
} else {
// Quote download
// Set 1st january 1970 if date is not found
if (!firstDate.isValid()) {
firstDate.setDate(1970, 1, 1);
}
QString interval = QStringLiteral("1d");
bool last = (iMode == LAST);
if (last) {
interval = QStringLiteral("1d");
} else if (iMode == LAST_MONTHLY) {
interval = QStringLiteral("1mo");
} else if (iMode == LAST_WEEKLY) {
interval = QStringLiteral("1wk");
} else if (iMode == LAST_DAILY) {
interval = QStringLiteral("1d");
} else if (iMode == ALL_MONTHLY) {
firstDate = QDate(1970, 01, 01);
interval = QStringLiteral("1mo");
} else if (iMode == ALL_WEEKLY) {
firstDate = QDate(1970, 01, 01);
interval = QStringLiteral("1wk");
} else if (iMode == ALL_DAILY) {
firstDate = QDate(1970, 01, 01);
interval = QStringLiteral("1d");
}
bool modeScript = false;
QString path;
QString mode;
QString price;
QString date;
QString dateFormat;
QString fileName = QStandardPaths::locate(QStandardPaths::GenericDataLocation, "skrooge/quotes/" % source % ".txt");
if (fileName.isEmpty()) {
const auto list2 = KServiceTypeTrader::self()->query(QStringLiteral("skrooge/source"));
for (const auto& service : list2) {
auto name = service->property(QStringLiteral("X-KDE-PluginInfo-Name"), QVariant::String).toString();
if (name == source) {
path = service->property(QStringLiteral("X-SKROOGE-url"), QVariant::String).toString();
if (path.isEmpty()) {
path = service->property(QStringLiteral("X-SKROOGE-script"), QVariant::String).toString();
modeScript = true;
}
mode = service->property(QStringLiteral("X-SKROOGE-mode"), QVariant::String).toString().toUpper();
price = service->property(QStringLiteral("X-SKROOGE-price"), QVariant::String).toString().replace(QStringLiteral("%1"), code);
date = service->property(QStringLiteral("X-SKROOGE-date"), QVariant::String).toString().replace(QStringLiteral("%1"), code);
dateFormat = service->property(QStringLiteral("X-SKROOGE-dateformat"), QVariant::String).toString();
break;
}
}
if (path.isEmpty()) {
err = SKGError(ERR_FAIL, i18nc("Error message", "Source of download %1 is not installed.", source));
}
} else {
// Read source file from .txt file
QHash< QString, QString > properties;
err = SKGServices::readPropertyFile(fileName, properties);
IFOK(err) {
path = properties[QStringLiteral("url")];
if (path.isEmpty()) {
path = properties[QStringLiteral("script")];
modeScript = true;
}
mode = properties[QStringLiteral("mode")].toUpper();
price = properties[QStringLiteral("price")].replace(QStringLiteral("%1"), code);
date = properties[QStringLiteral("date")].replace(QStringLiteral("%1"), code);
dateFormat = properties[QStringLiteral("dateformat")];
} else {
doc->sendMessage(i18nc("An information message", "Open url '%1' failed", path), SKGDocument::Warning);
}
}
IFOK(err) {
path = path.replace(QStringLiteral("%1"), code);
path = path.replace(QStringLiteral("%2"), QDate::currentDate().toString(QStringLiteral("yyyy-MM-dd")));
path = path.replace(QStringLiteral("%3"), firstDate.toString(QStringLiteral("yyyy-MM-dd")));
path = path.replace(QStringLiteral("%4"), interval);
SKGTRACEL(1) << "path=[" << path << "]" << endl;
SKGTRACEL(1) << "mode=[" << mode << "]" << endl;
SKGTRACEL(1) << "price=[" << price << "]" << endl;
SKGTRACEL(1) << "date=[" << date << "]" << endl;
SKGTRACEL(1) << "dateFormat=[" << dateFormat << "]" << endl;
// Download url
QByteArray stream;
if (modeScript) {
path = SKGServices::getFullPathCommandLine(path);
SKGTRACEL(1) << "full path=[" << path << "]" << endl;
QProcess p;
p.start(path);
if (p.waitForFinished(1000 * 60 * 2) && p.exitCode() == 0) {
stream = p.readAllStandardOutput();
} else {
err.setReturnCode(ERR_FAIL).setMessage(i18nc("Error message", "The following command line failed with code %2:\n'%1'", path, p.exitCode()));
}
} else {
SKGServices::downloadToStream(QUrl::fromUserInput(path), stream);
}
if (!err && !stream.isEmpty()) {
SKGTRACEL(1) << "stream=[" << stream << "]" << endl;
// Parse data
QRegExp priceRegExp(price, Qt::CaseInsensitive);
QRegExp dateRegExp(date, Qt::CaseInsensitive);
QStringList lines = (mode.startsWith(QLatin1String("CSV")) ? SKGServices::splitCSVLine(stream, '\n') : QStringList() << QLatin1String("") << stream);
int nb = lines.count();
int nbLoaded = 0;
for (int i = 1; i < nb && !err && (i < iNbMaxValues || iNbMaxValues == 0); ++i) {
QString data = lines.at(mode == QStringLiteral("CSVR") ? nb - i : i).trimmed();
if (!data.isEmpty()) {
SKGTRACEL(1) << "Downloaded data from [" << path << "]=[" << data << "]" << endl;
double val = 0.0;
if (priceRegExp.indexIn(data) > -1) {
val = SKGServices::stringToDouble(priceRegExp.cap(1));
}
QString date2;
if (dateRegExp.indexIn(data) > -1) {
date2 = dateRegExp.cap(1);
}
SKGTRACEL(1) << "Price found=[" << val << "]" << endl;
SKGTRACEL(1) << "Date found=[" << date2 << "]" << endl;
// Set value
if (val != 0.0) {
QDate ds;
if (dateFormat == QStringLiteral("UNIX")) {
ds = QDateTime::fromTime_t(SKGServices::stringToInt(date2)).date();
} else {
ds = QDate::fromString(date2, dateFormat);
// Try with an english locale
if (!ds.isValid()) {
QLocale en(QStringLiteral("en_EN"));
ds = en.toDate(date2, dateFormat);
}
}
if (!ds.isValid()) {
ds = QDate::currentDate();
SKGTRACE << "WARNING:" << date2 << " not well parsed with format " << dateFormat << endl;
}
if (!dateFormat.contains(QStringLiteral("yyyy")) && ds.year() < 2000) {
ds = ds.addYears(100);
}
// Creation or update of the value
SKGUnitValueObject value;
IFOKDO(err, addUnitValue(value))
IFOKDO(err, value.setDate(ds))
IFOKDO(err, value.setQuantity(invert && val != 0 ? 1 / val : val))
IFOKDO(err, value.save())
if (last) {
break;
}
nbLoaded++;
}
}
if (nbLoaded == 0 && !data.isEmpty()) {
err = doc->sendMessage(i18nc("Information message", "Price not found for '%1' with regular expression '%2' in line '%3'", getName(), SKGServices::stringToHtml(price), data), SKGDocument::Warning); // TODO(Stephane MANKOWSKI) does not work with html
}
}
}
}
}
}
IFKO(err) {
err.addError(ERR_FAIL, i18nc("Error message", "Impossible to download unit %1 with Internet code %2 on the source %3.", unitname, code, source));
}
return err;
}
SKGError SKGUnitObject::getUrl(QUrl& oUrl) const
{
SKGError err;
SKGTRACEINFUNCRC(10, err)
QString url;
QString code = getInternetCode();
code.remove(QStringLiteral(" /"));
QString source = getDownloadSource();
if (!code.isEmpty()) {
if (code.startsWith(QLatin1String("="))) {
// MODE FORMULAR
} else {
// ALTERNATIVE MODE
QString fileName = QStandardPaths::locate(QStandardPaths::GenericDataLocation, "skrooge/quotes/" % source % ".txt");
if (fileName.isEmpty()) {
const auto list2 = KServiceTypeTrader::self()->query(QStringLiteral("skrooge/source"));
for (const auto& service : list2) {
auto name = service->property(QStringLiteral("X-KDE-PluginInfo-Name"), QVariant::String).toString();
if (name == source) {
url = service->property(QStringLiteral("X-SKROOGE-url"), QVariant::String).toString().replace(QStringLiteral("%1"), code);
url = url.replace(QStringLiteral("%2"), QDate::currentDate().toString(QStringLiteral("yyyy-MM-dd")));
url = url.replace(QStringLiteral("%3"), QDate::currentDate().addDays(-15).toString(QStringLiteral("yyyy-MM-dd")));
break;
}
}
if (url.isEmpty()) {
err = SKGError(ERR_FAIL, i18nc("Error message", "Source of download %1 is not installed.", source));
}
} else {
// Read source file
QHash< QString, QString > properties;
err = SKGServices::readPropertyFile(fileName, properties);
IFOK(err) {
url = properties[QStringLiteral("url")].replace(QStringLiteral("%1"), code);
url = url.replace(QStringLiteral("%2"), QDate::currentDate().toString(QStringLiteral("yyyy-MM-dd")));
url = url.replace(QStringLiteral("%3"), QDate::currentDate().addDays(-15).toString(QStringLiteral("yyyy-MM-dd")));
}
}
}
}
IFOK(err) {
oUrl = QUrl(url);
}
return err;
}
SKGError SKGUnitObject::openURL() const
{
QUrl url;
SKGError err = getUrl(url);
IFKO(err) {
err.addError(ERR_FAIL, i18nc("Error message", "Impossible to open unit %1 with Internet code %2.", getName(), getInternetCode()));
} else {
QDesktopServices::openUrl(url);
}
return err;
}
SKGError SKGUnitObject::getOperations(SKGObjectBase::SKGListSKGObjectBase& oOperations) const
{
SKGError err = getDocument()->getObjects(QStringLiteral("v_operation"),
"rc_unit_id=" % SKGServices::intToString(getID()),
oOperations);
return err;
}
SKGError SKGUnitObject::merge(const SKGUnitObject& iUnit)
{
SKGError err;
SKGObjectBase::SKGListSKGObjectBase ops;
IFOKDO(err, iUnit.getOperations(ops))
int nb = ops.count();
for (int i = 0; !err && i < nb; ++i) {
SKGOperationObject op(ops.at(i));
err = op.setUnit(*this);
IFOKDO(err, op.save(true, false))
}
IFOKDO(err, iUnit.remove(false))
return err;
}
diff --git a/skgbankmodeler/skgunitobject.h b/skgbankmodeler/skgunitobject.h
index 1af0fe759..c1621711e 100644
--- a/skgbankmodeler/skgunitobject.h
+++ b/skgbankmodeler/skgunitobject.h
@@ -1,432 +1,432 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGUNITOBJECT_H
#define SKGUNITOBJECT_H
/** @file
* This file defines classes SKGUnitObject.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include <qurl.h>
#include "skgbankmodeler_export.h"
#include "skgerror.h"
#include "skgnamedobject.h"
#include "skgservices.h"
class SKGUnitValueObject;
class SKGDocumentBank;
/**
* This class is a unit
*/
class SKGBANKMODELER_EXPORT SKGUnitObject final : public SKGNamedObject
{
Q_OBJECT
public:
/**
* This enumerate defines type of units
*/
enum UnitType {PRIMARY, /**< to define the main currency (only one)*/
SECONDARY, /**< to define the secondary currency (only one)*/
CURRENCY, /**< for currency: dollar, euro, yen, ... */
SHARE, /**< for stock: Google, EDF, ... */
INDEX, /**< for index: CAC 40, ... */
OBJECT /**< for objects: cars, houses, ... */
};
/**
* This enumerate defines type of units
*/
Q_ENUM(UnitType)
/**
* This enumerate defines the mode of download
*/
enum UnitDownloadMode {LAST, /**< last value only*/
LAST_MONTHLY, /**< one value par month since last download*/
LAST_WEEKLY, /**< one value par week since last download*/
LAST_DAILY, /**< one value par day since last download*/
ALL_MONTHLY, /**< one value par month*/
ALL_WEEKLY, /**< one value par week*/
ALL_DAILY /**< one value par day*/
};
/**
* This enumerate defines the mode of download
*/
Q_ENUM(UnitDownloadMode)
/**
* Default constructor
*/
explicit SKGUnitObject();
/**
* Constructor
* @param iDocument the document containing the object
* @param iID the identifier in @p iTable of the object
*/
explicit SKGUnitObject(SKGDocument* iDocument, int iID = 0);
/**
* Destructor
*/
~SKGUnitObject() override;
/**
* Copy constructor
* @param iObject the object to copy
*/
SKGUnitObject(const SKGUnitObject& iObject);
/**
* Copy constructor
* @param iObject the object to copy
*/
explicit SKGUnitObject(const SKGNamedObject& iObject);
/**
* Copy constructor
* @param iObject the object to copy
*/
explicit SKGUnitObject(const SKGObjectBase& iObject);
/**
* Operator affectation
* @param iObject the object to copy
*/
SKGUnitObject& operator= (const SKGObjectBase& iObject);
/**
* Get unit information
* @return the unit information
* @see SKGUnitInfo
*/
SKGServices::SKGUnitInfo getUnitInfo();
/**
* Get unit information
* @param iUnitName the currency unit name (nls), or the international code, or the symbol (@see getListofKnownCurrencies)
* @return the unit information
* @see SKGUnitInfo
*/
static SKGServices::SKGUnitInfo getUnitInfo(const QString& iUnitName);
/**
* Create an existing currency unit
* @param iDocument the document containing the object
* @param iUnitName the currency unit name (nls), or the international code, or the symbol (@see getListofKnownCurrencies)
* @param oUnit the created unit object
* @return an object managing the error
* @see SKGError
*/
static SKGError createCurrencyUnit(SKGDocumentBank* iDocument, const QString& iUnitName, SKGUnitObject& oUnit);
/**
* Return the list of known currencies.
* @param iIncludingObsolete including obsolete currencies
* @return the list of known currencies
*/
static QStringList getListofKnownCurrencies(bool iIncludingObsolete = false);
/**
* Return the International code of currencies.
* @param iUnitName the currency unit name (nls)
* @return the International code
*/
static QString getInternationalCode(const QString& iUnitName);
/**
* Convert a value from one unit to another one
* @param iValue initial value
* @param iUnitFrom source unit
* @param iUnitTo target unit
* @param iDate the date to use to compute the units values
* @return Value in target unit
*/
// cppcheck-suppress passedByValue
static double convert(double iValue, const SKGUnitObject& iUnitFrom, const SKGUnitObject& iUnitTo, QDate iDate = QDate::currentDate());
/**
* Set the symbol of this unit
* @param iSymbol the symbol
* @return an object managing the error
* @see SKGError
*/
SKGError setSymbol(const QString& iSymbol);
/**
* Get the symbol of this unit
* @return the symbol
*/
QString getSymbol() const;
/**
* Set the download source of this unit
* @param iSource the download source ("" means native source)
* @return an object managing the error
* @see SKGError
*/
SKGError setDownloadSource(const QString& iSource);
/**
* Get the download source of this unit
* @return the download source ("" means native source)
*/
QString getDownloadSource() const;
/**
* Set the number of decimal of this unit
* @param iNb number of decimal
* @return an object managing the error
* @see SKGError
*/
SKGError setNumberDecimal(int iNb);
/**
* Get the number of decimal of this unit
* @return the number of decimal
*/
int getNumberDecimal() const;
/**
* Set the country of this unit
* @param iCountry the country
* @return an object managing the error
* @see SKGError
*/
SKGError setCountry(const QString& iCountry);
/**
* Get the country of this unit
* @return the country
*/
QString getCountry() const;
/**
* Set the Internet code of this unit
* @param iCode the Internet code
* @return an object managing the error
* @see SKGError
*/
SKGError setInternetCode(const QString& iCode);
/**
* Get the Internet code of this unit
* @return the Internet code
*/
QString getInternetCode() const;
/**
* Set the type of this unit
* @param iType the type
* @return an object managing the error
* @see SKGError
*/
SKGError setType(SKGUnitObject::UnitType iType);
/**
* Get the type of this unit
* @return the type
*/
SKGUnitObject::UnitType getType() const;
/**
* Add a unit value
* @param oUnitValue the created unit value
* @return an object managing the error.
* @see SKGError
*/
SKGError addUnitValue(SKGUnitValueObject& oUnitValue);
/**
* Get unit values
* @param oUnitValueList the list of unit values of this unit
* @return an object managing the error
* @see SKGError
*/
SKGError getUnitValues(SKGListSKGObjectBase& oUnitValueList) const;
/**
* Get last unit value
* @param oUnitValue the last unit value
* @return an object managing the error.
* @see SKGError
*/
SKGError getLastUnitValue(SKGUnitValueObject& oUnitValue) const;
/**
* Get unit value at a date
* @param iDate the date
* @param oUnitValue the last unit value
* @return an object managing the error.
* @see SKGError
*/
// cppcheck-suppress passedByValue
SKGError getUnitValue(QDate iDate, SKGUnitValueObject& oUnitValue) const;
/**
* Download values
* @param iMode download mode (used only for native source)
* @param iNbMaxValues nb max of values to download (used only for native source)
* @return an object managing the error
* @see SKGError
*/
SKGError downloadUnitValue(UnitDownloadMode iMode = LAST, int iNbMaxValues = 50);
/**
* Open the URL where the values are downloaded
* @return an object managing the error
* @see SKGError
*/
SKGError openURL() const;
/**
* Get the URL where the values are downloaded
* @param oUrl the url
* @return an object managing the error
* @see SKGError
*/
SKGError getUrl(QUrl& oUrl) const;
/**
* Get the list of sources for the download
* @return the list of sources
*/
static QStringList downloadSources();
/**
* Get the source comment/help
* @param iSource the source name (@see downloadSources)
* @return the comment/help
*/
static QString getCommentFromSource(const QString& iSource);
/**
* Create a new source
* @param iNewSource the name of the new source
* @param iOpenSource to open the created source with the appropriate editor
* @return an object managing the error
* @see SKGError
*/
static SKGError addSource(const QString& iNewSource, bool iOpenSource = true);
/**
* To know if a source can be modified or deleted
* @param iSource the name of the source to modified or deleted
* @return true or false
*/
static bool isWritable(const QString& iSource);
/**
* Delete a new source
* @param iSource the name of the source to delete
* @return an object managing the error
* @see SKGError
*/
static SKGError deleteSource(const QString& iSource);
/**
* Get amount of the unit at a date
* @param iDate date
* @return amount of the unit
*/
// cppcheck-suppress passedByValue
double getAmount(QDate iDate = QDate::currentDate()) const;
/**
* Get daily change in percentage at a date.
* @param iDate date
* @return daily change
*/
// cppcheck-suppress passedByValue
double getDailyChange(QDate iDate = QDate::currentDate()) const;
/**
* Set the unit
* @param iUnit the unit
* @return an object managing the error
* @see SKGError
*/
SKGError setUnit(const SKGUnitObject& iUnit);
/**
* Remove the unit
* @return an object managing the error
* @see SKGError
*/
SKGError removeUnit();
/**
* Get the unit
* @param oUnit the unit
* @return an object managing the error
* @see SKGError
*/
SKGError getUnit(SKGUnitObject& oUnit) const;
/**
* Split unit.
* All quantity in operations will be multiply by iRatio.
* All unit values will be divise by iRatio.
* @param iRatio the split ratio
* @return an object managing the error
* @see SKGError
*/
SKGError split(double iRatio) const;
/**
* Get all operations of this unit
* @param oOperations all operations of this unit
* @return an object managing the error
* @see SKGError
*/
SKGError getOperations(SKGListSKGObjectBase& oOperations) const;
/**
* Merge iUnit in current unit
* @param iUnit the unit. All operations will be transferred into this unit. The unit will be removed
* @return an object managing the error
* @see SKGError
*/
SKGError merge(const SKGUnitObject& iUnit);
/**
* Remove all unit values not relevant.
* The curve is preserved but useless values are removed.
* @return an object managing the error.
* @see SKGError
*/
SKGError simplify();
protected:
/**
* Get where clause needed to identify objects.
* For this class, the whereclause is based on name
* @return the where clause
*/
QString getWhereclauseId() const override;
private:
static QList<SKGServices::SKGUnitInfo> currencies;
};
/**
* Declare the class
*/
Q_DECLARE_TYPEINFO(SKGUnitObject, Q_MOVABLE_TYPE);
#endif
diff --git a/skgbankmodeler/skgunitvalueobject.cpp b/skgbankmodeler/skgunitvalueobject.cpp
index 3a49bac4c..ba83d080c 100644
--- a/skgbankmodeler/skgunitvalueobject.cpp
+++ b/skgbankmodeler/skgunitvalueobject.cpp
@@ -1,99 +1,99 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file defines classes SKGUnitValueObject.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgunitvalueobject.h"
#include <klocalizedstring.h>
#include "skgdocument.h"
#include "skgunitobject.h"
SKGUnitValueObject::SKGUnitValueObject() : SKGUnitValueObject(nullptr)
{}
SKGUnitValueObject::SKGUnitValueObject(SKGDocument* iDocument, int iID) : SKGObjectBase(iDocument, QStringLiteral("v_unitvalue"), iID)
{}
SKGUnitValueObject::SKGUnitValueObject(const SKGUnitValueObject& iObject) = default;
SKGUnitValueObject::SKGUnitValueObject(const SKGObjectBase& iObject)
{
if (iObject.getRealTable() == QStringLiteral("unitvalue")) {
copyFrom(iObject);
} else {
*this = SKGObjectBase(iObject.getDocument(), QStringLiteral("v_unitvalue"), iObject.getID());
}
}
SKGUnitValueObject& SKGUnitValueObject::operator= (const SKGObjectBase& iObject)
{
copyFrom(iObject);
return *this;
}
SKGUnitValueObject::~SKGUnitValueObject()
= default;
SKGError SKGUnitValueObject::setQuantity(double iValue)
{
if (iValue < 0) {
return SKGError(ERR_INVALIDARG, i18nc("Error message", "Value of a currency cannot be a negative value"));
}
return setAttribute(QStringLiteral("f_quantity"), SKGServices::doubleToString(iValue));
}
double SKGUnitValueObject::getQuantity() const
{
return SKGServices::stringToDouble(getAttribute(QStringLiteral("f_quantity")));
}
SKGError SKGUnitValueObject::setDate(QDate iDate)
{
return setAttribute(QStringLiteral("d_date"), SKGServices::dateToSqlString(QDateTime(iDate)));
}
QDate SKGUnitValueObject::getDate() const
{
return SKGServices::stringToTime(getAttribute(QStringLiteral("d_date"))).date();
}
QString SKGUnitValueObject::getWhereclauseId() const
{
// Could we use the id
QString output = SKGObjectBase::getWhereclauseId();
if (output.isEmpty()) {
// No, so we use the date and parent
if (!(getAttribute(QStringLiteral("d_date")).isEmpty()) && !(getAttribute(QStringLiteral("rd_unit_id")).isEmpty())) {
output = "d_date='" % getAttribute(QStringLiteral("d_date")) % "' AND rd_unit_id=" % getAttribute(QStringLiteral("rd_unit_id"));
}
}
return output;
}
SKGError SKGUnitValueObject::getUnit(SKGUnitObject& oUnit) const
{
SKGError err;
if (getDocument() != nullptr) {
err = getDocument()->getObject(QStringLiteral("v_unit"), "id=" % getAttribute(QStringLiteral("rd_unit_id")), oUnit);
}
return err;
}
diff --git a/skgbankmodeler/skgunitvalueobject.h b/skgbankmodeler/skgunitvalueobject.h
index 66d87fdd6..572c3d398 100644
--- a/skgbankmodeler/skgunitvalueobject.h
+++ b/skgbankmodeler/skgunitvalueobject.h
@@ -1,123 +1,123 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGUNITVALUEOBJECT_H
#define SKGUNITVALUEOBJECT_H
/** @file
* This file defines classes SKGUnitValueObject.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgbankmodeler_export.h"
#include "skgerror.h"
#include "skgobjectbase.h"
class SKGUnitObject;
/**
* This class is a value at a time for a unit
*/
class SKGBANKMODELER_EXPORT SKGUnitValueObject final : public SKGObjectBase
{
Q_OBJECT
public:
/**
* Default constructor
*/
explicit SKGUnitValueObject();
/**
* Constructor
* @param iDocument the document containing the object
* @param iID the identifier in @p iTable of the object
*/
explicit SKGUnitValueObject(SKGDocument* iDocument, int iID = 0);
/**
* Copy constructor
* @param iObject the object to copy
*/
SKGUnitValueObject(const SKGUnitValueObject& iObject);
/**
* Copy constructor
* @param iObject the object to copy
*/
explicit SKGUnitValueObject(const SKGObjectBase& iObject);
/**
* Operator affectation
* @param iObject the object to copy
*/
SKGUnitValueObject& operator= (const SKGObjectBase& iObject);
/**
* Destructor
*/
~SKGUnitValueObject() override;
/**
* Set the quantity for the date of this unit
* @param iValue the quantity
* @return an object managing the error
* @see SKGError
*/
SKGError setQuantity(double iValue);
/**
* Get the quantity for the date of this unit
* @return the quantity
*/
double getQuantity() const;
/**
* Set date of this value
* @param iDate the date
* @return an object managing the error
* @see SKGError
*/
// cppcheck-suppress passedByValue
SKGError setDate(QDate iDate);
/**
* Get date of this value
* @return the date
*/
QDate getDate() const;
/**
* Get the parent unit
* @param oUnit the parent unit
* @return an object managing the error
* @see SKGError
*/
SKGError getUnit(SKGUnitObject& oUnit) const;
protected:
/**
* Get where clause needed to identify objects.
* For this class, the whereclause is based on date + unit
* @return the where clause
*/
QString getWhereclauseId() const override;
};
/**
* Declare the class
*/
Q_DECLARE_TYPEINFO(SKGUnitValueObject, Q_MOVABLE_TYPE);
#endif
diff --git a/skgbankmodeler/sources/org.kde.skrooge-source-coinmarketcap.desktop b/skgbankmodeler/sources/org.kde.skrooge-source-coinmarketcap.desktop
index ca5678796..0688c0a2a 100644
--- a/skgbankmodeler/sources/org.kde.skrooge-source-coinmarketcap.desktop
+++ b/skgbankmodeler/sources/org.kde.skrooge-source-coinmarketcap.desktop
@@ -1,68 +1,68 @@
[Desktop Entry]
Name=CoinMarketCap
Name[ca]=CoinMarketCap
Name[ca@valencia]=CoinMarketCap
Name[en_GB]=CoinMarketCap
Name[es]=CoinMarketCap
Name[fr]=CoinMarketCap
Name[gl]=CoinMarketCap
Name[it]=CoinMarketCap
Name[nl]=CoinMarketCap
Name[pl]=CoinMarketCap
Name[pt]=CoinMarketCap
Name[sv]=CoinMarketCap
Name[uk]=CoinMarketCap
Name[x-test]=xxCoinMarketCapxx
Comment=You can get the list of available quotes from <a href="https://coinmarketcap.com">CoinMarketCap</a>.<br/>Then, enter the expected quote (the xxx in the url like this https://coinmarketcap.com/currencies/xxx/).
Comment[ca]=Podeu obtenir la llista de les cotitzacions disponibles a <a href="https://coinmarketcap.com">CoinMarketCap</a>.<br/>Després introduïu la cotització esperada (les «xxx» a l'URL com aquest https://coinmarketcap.com/currencies/xxx/).
Comment[ca@valencia]=Podeu obtindre la llista de les cotitzacions disponibles a <a href="https://coinmarketcap.com">CoinMarketCap</a>.<br/>Després introduïu la cotització esperada (les «xxx» a l'URL com aquest https://coinmarketcap.com/currencies/xxx/).
Comment[en_GB]=You can get the list of available quotes from <a href="https://coinmarketcap.com">CoinMarketCap</a>.<br/>Then, enter the expected quote (the xxx in the URL like this https://coinmarketcap.com/currencies/xxx/).
Comment[es]=Puede obtener la lista de las cotizaciones disponibles de <a href="https://coinmarketcap.com">CoinMarketCap</a>.<br/>A continuación, introduzca la cotización esperada (el xxx del url, como en https://coinmarketcap.com/currencies/xxx/).
Comment[fr]=Vous pouvez récupérer la liste des cotation disponibles depuis <a href="https://coinmarketcap.com">CoinMarketCap</a>.<br/> Ensuite, saisissez la cotation souhaitée (le xxx dans l'adresse comme celle-ci https://coinmarketcap.com/currencies/xxx/).
Comment[gl]=Pode obter a lista de cotizacións dispoñíbeis de <a href="https://coinmarketcap.com">CoinMarketCap</a>.<br/>A continuación escriba a cotización esperada (o xxx dos URL coa forma https://coinmarketcap.com/currencies/xxx/).
Comment[it]=Puoi ottenere un elenco delle quotazioni disponibili da <a href="https://coinmarketcap.com/it">CoinMarketCap</a>.<br/>Digita, quindi la quotazione attesa (la xxx nell'URL, tipo https://coinmarketcap.com/currencies/xxx/).
Comment[nl]=U kunt de lijst met namen van beschikbare koersen ophalen uit <a href="https://coinmarketcap.com">CoinMarketCap</a>.<br/>Voer dan de naam van de gevraagde koers in (de xxx in de url zoals deze https://coinmarketcap.com/currencies/xxx/).
Comment[pl]=Wykaz dostępnych wycen można pobrać z <a href="https://coinmarketcap.com">CoinMarketCap</a>.<br/>Następnie podaj żądaną wycenę(trzy iksy xxx w adresie url tak jak w https://coinmarketcap.com/currencies/xxx/).
Comment[pt]=Poderá obter a lista de cotações disponíveis a partir de <a href="https://coinmarketcap.com">CoinMarketCap</a>.<br/>Depois, indique a cotação esperada (o 'xxx' num URL como o seguinte: https://coinmarketcap.com/currencies/xxx/).
Comment[sv]=Listan över tillgängliga kursnoteringar kan hämtas från <a href="https://coinmarketcap.com">CoinMarkedCap</a>.<br/>Skriv därefter in förväntad kurs (xxx i webbadressen https://coinmarketcap.com/currencies/xxx/).
Comment[uk]=Список доступних курсів можна отримати з <a href="https://coinmarketcap.com">CoinMarketCap</a>.<br/>Далі, введіть потрібний курс (xxx у адресі, наприклад https://coinmarketcap.com/currencies/xxx/).
Comment[x-test]=xxYou can get the list of available quotes from <a href="https://coinmarketcap.com">CoinMarketCap</a>.<br/>Then, enter the expected quote (the xxx in the url like this https://coinmarketcap.com/currencies/xxx/).xx
Encoding=UTF-8
Icon=skrooge
Type=Service
X-KDE-ServiceTypes=skrooge/source
X-Krunner-ID=coinmarketcap
X-KDE-PluginInfo-Author=Stephane MANKOWSKI,miraks
X-KDE-PluginInfo-Email=stephane@mankowski.fr
X-KDE-PluginInfo-Name=CoinMarketCap
X-KDE-PluginInfo-Version=1.0
-X-KDE-PluginInfo-Website=http://skrooge.org/
+X-KDE-PluginInfo-Website=https://skrooge.org/
X-KDE-PluginInfo-Category=Plugins
X-KDE-PluginInfo-Depends=
X-KDE-PluginInfo-License=GPL
X-KDE-PluginInfo-EnabledByDefault=true
#The url or the command line to get the list of accounts in the standard output, something like this:
#%1 will be replaced by the internet code of the unit
#%2 will be replaced by the current day in format yyyy-MM-dd
#%3 will be replaced by the previous date in format yyyy-MM-dd
#Example:
-# X-SKROOGE-url=http://server/?s=%1
+# X-SKROOGE-url=https://server/?s=%1
# or
# X-SKROOGE-script=mydownloadscript %1
#This parameter is MANDATORY
X-SKROOGE-script=skrooge-coinmarketcap.py %1
#The mode (HTML or CSV or CSVR). In HTML mode, only one value will be extracted from downloaded page. In CSV mode, a value per line will be extracted. CSVR means CSV in reverse mode
X-SKROOGE-mode=CSV
#Regular expression to capture the price of the quote
#This parameter is not MANDATORY.
X-SKROOGE-price=[^,]*,([^,]*)
#Regular expression to capture the date of the quote
#This parameter is not MANDATORY.
X-SKROOGE-date=([^,]*),.*
#The date format
X-SKROOGE-dateformat=yyyy-MM-dd
diff --git a/skgbankmodeler/sources/org.kde.skrooge-source-grandtrunk.desktop b/skgbankmodeler/sources/org.kde.skrooge-source-grandtrunk.desktop
index 8c94b3eb2..9f283caf4 100644
--- a/skgbankmodeler/sources/org.kde.skrooge-source-grandtrunk.desktop
+++ b/skgbankmodeler/sources/org.kde.skrooge-source-grandtrunk.desktop
@@ -1,68 +1,68 @@
[Desktop Entry]
Name=Grand Trunk
Name[ca]=Grand Trunk
Name[ca@valencia]=Grand Trunk
Name[en_GB]=Grand Trunk
Name[es]=Grand Trunk
Name[fr]=Grand Trunk
Name[gl]=Grand Trunk
Name[it]=Grand Trunk
Name[nl]=Grand Trunk
Name[pl]=Grand Trunk
Name[pt]=Grand Trunk
Name[sv]=Grand Trunk
Name[uk]=Grand Trunk
Name[x-test]=xxGrand Trunkxx
Comment=You can get the list of supported currencies from <a href="http://currencies.apps.grandtrunk.net/currencies">here</a>.<br/>Then, enter the expected currency.
Comment[ca]=Podeu obtenir la llista de les divises admeses <a href="http://currencies.apps.grandtrunk.net/currencies">aquí</a>.<br/>Després introduïu la divisa esperada.
Comment[ca@valencia]=Podeu obtindre la llista de les divises admeses <a href="http://currencies.apps.grandtrunk.net/currencies">ací</a>.<br/>Després introduïu la divisa esperada.
Comment[en_GB]=You can get the list of supported currencies from <a href="http://currencies.apps.grandtrunk.net/currencies">here</a>.<br/>Then, enter the expected currency.
Comment[es]=Puede obtener la lista de las monedas permitidas de <a href="http://currencies.apps.grandtrunk.net/currencies">aquí</a>.<br/>A continuación, introduzca la moneda esperada.
Comment[fr]=Vous pouvez récupérer la liste des cotation disponibles depuis <a href="http://currencies.apps.grandtrunk.net/currencies">ici</a>.<br/> Ensuite, saisissez la devise souhaitée.
Comment[gl]=Pode obter a lista de divisas compatíbeis de <a href="http://currencies.apps.grandtrunk.net/currencies">aquí</a>.<br/>A continuación escriba a divisa esperada.
Comment[it]=Puoi ottenere un elenco delle valute supportate <a href="http://currencies.apps.grandtrunk.net/currencies">qui</a>.<br/>Digita, quindi, la valuta desiderata.
Comment[nl]=U kunt de lijst met ondersteunde valuta ophalen vanaf <a href="http://currencies.apps.grandtrunk.net/currencies">hier</a>.<br/>Voer dan de naam van de gewenste valuta in.
Comment[pl]=Możesz pobrać wykaz dostępnych walut <a href="http://currencies.apps.grandtrunk.net/currencies">stąd</a>.<br/>Następnie podaj żądaną walutę.
Comment[pt]=Poderá obter a lista de moedas suportadas a partir de <a href="http://currencies.apps.grandtrunk.net/currencies">aqui</a>.<br/>Depois, introduza a moeda esperada.
Comment[sv]=Lista över valutor som stöds kan hämtas <a href="http://currencies.apps.grandtrunk.net/currencies">här</a>. Skriv därefter in förväntad valuta.
Comment[uk]=Ознайомитися зі списком підтримуваних валют можна <a href="http://currencies.apps.grandtrunk.net/currencies">тут</a>.<br/>Далі, введіть потрібну валюту.
Comment[x-test]=xxYou can get the list of supported currencies from <a href="http://currencies.apps.grandtrunk.net/currencies">here</a>.<br/>Then, enter the expected currency.xx
Encoding=UTF-8
Icon=skrooge
Type=Service
X-KDE-ServiceTypes=skrooge/source
X-Krunner-ID=grandtrunk
X-KDE-PluginInfo-Author=Stephane MANKOWSKI,miraks
X-KDE-PluginInfo-Email=stephane@mankowski.fr
X-KDE-PluginInfo-Name=GrandTrunk
X-KDE-PluginInfo-Version=1.0
-X-KDE-PluginInfo-Website=http://skrooge.org/
+X-KDE-PluginInfo-Website=https://skrooge.org/
X-KDE-PluginInfo-Category=Plugins
X-KDE-PluginInfo-Depends=
X-KDE-PluginInfo-License=GPL
X-KDE-PluginInfo-EnabledByDefault=true
#The url or the command line to get the list of accounts in the standard output, something like this:
#%1 will be replaced by the internet code of the unit
#%2 will be replaced by the current day in format yyyy-MM-dd
#%3 will be replaced by the previous date in format yyyy-MM-dd
#Example:
-# X-SKROOGE-url=http://server/?s=%1
+# X-SKROOGE-url=https://server/?s=%1
# or
# X-SKROOGE-script=mydownloadscript %1
#This parameter is MANDATORY
X-SKROOGE-url=http://currencies.apps.grandtrunk.net/getrange/%3/%2/%1
#The mode (HTML or CSV or CSVR). In HTML mode, only one value will be extracted from downloaded page. In CSV mode, a value per line will be extracted. CSVR means CSV in reverse mode
X-SKROOGE-mode=CSVR
#Regular expression to capture the price of the quote
#This parameter is not MANDATORY.
X-SKROOGE-price=^[^ ]* (.*)$
#Regular expression to capture the date of the quote
#This parameter is not MANDATORY.
X-SKROOGE-date=^(.*) [^ ]*$
#The date format
X-SKROOGE-dateformat=yyyy-MM-dd
diff --git a/skgbankmodeler/sources/org.kde.skrooge-source-msn.desktop b/skgbankmodeler/sources/org.kde.skrooge-source-msn.desktop
index 957cdf5b3..01bc46a6a 100644
--- a/skgbankmodeler/sources/org.kde.skrooge-source-msn.desktop
+++ b/skgbankmodeler/sources/org.kde.skrooge-source-msn.desktop
@@ -1,71 +1,71 @@
[Desktop Entry]
Name=MSN
Name[ca]=MSN
Name[ca@valencia]=MSN
Name[cs]=MSN
Name[de]=MSN
Name[en_GB]=MSN
Name[es]=MSN
Name[fr]=MSN
Name[gl]=MSN
Name[it]=MSN
Name[nl]=MSN
Name[pl]=MSN
Name[pt]=MSN
Name[sv]=MSN
Name[uk]=MSN
Name[x-test]=xxMSNxx
Comment=You can get the list of available quotes from <a href="https://www.msn.com/en-us/money/">MSN</a>.<br/>Then, enter the code of the expected quote (the xxx in the url like https://www.msn.com/en-us/money/stockdetails/xxx).
Comment[ca]=Podeu obtenir la llista de les cotitzacions disponibles a <a href="https://www.msn.com/en-us/money/">MSN</a>.<br/>Després introduïu el codi de la cotització esperada (les «xxx» a l'URL com aquest https://www.msn.com/en-us/money/stockdetails/xxx).
Comment[ca@valencia]=Podeu obtindre la llista de les cotitzacions disponibles a <a href="https://www.msn.com/en-us/money/">MSN</a>.<br/>Després introduïu el codi de la cotització esperada (les «xxx» a l'URL com aquest https://www.msn.com/en-us/money/stockdetails/xxx).
Comment[en_GB]=You can get the list of available quotes from <a href="https://www.msn.com/en-us/money/">MSN</a>.<br/>Then, enter the code of the expected quote (the xxx in the URL like https://www.msn.com/en-us/money/stockdetails/xxx).
Comment[es]=Puede obtener la lista de las cotizaciones disponibles de <a href="https://www.msn.com/en-us/money/">MSN</a>.<br/>A continuación, introduzca el símbolo de la cotización esperada (el xxx del url, como en https://www.msn.com/en-us/money/stockdetails/xxx).
Comment[fr]=Vous pouvez récupérer la liste des cotation disponibles depuis <a href="https://www.msn.com/en-us/money/">MSN</a>.<br/> Ensuite, saisissez la cotation souhaitée (le xxx dans l'adresse comme celle-ci https://www.msn.com/en-us/money/stockdetails/xxx).
Comment[gl]=Pode obter a lista de cotizacións dispoñíbeis de <a href="https://www.msn.com/en-us/money/">MSN</a>.<br/>A continuación escriba a cotización esperada (o xxx dos URL coa forma https://www.msn.com/en-us/money/stockdetails/xxx).
Comment[it]=Puoi ottenere un elenco delle quotazioni disponibili da <a href="https://www.msn.com/it-it/money/">MSN</a>.<br/>Digita, quindi, il codice della quotazione desiderata (la xxx nell'URL, tipo https://www.msn.com/en-us/money/stockdetails/xxx).
Comment[nl]=U kunt de lijst met namen van beschikbare koersen ophalen uit <a href="https://www.msn.com/en-us/money/">MSN</a>.<br/>Voer dan de naam van de gevraagde koers in (de xxx in de url zoals deze https://www.msn.com/en-us/money/stockdetails/xxx/).
Comment[pl]=Wykaz dostępnych wycen można pobrać z <a href="https://www.msn.com/en-us/money/">MSN</a>.<br/>Następnie podaj żądaną wycenę(trzy iksy xxx w adresie url tak jak w https://www.msn.com/en-us/money/stockdetails/xxx).
Comment[pt]=Poderá obter a lista de cotações disponíveis a partir do <a href="https://msn.com/en-us/money/">MSN</a>.<br/>Depois, indique a cotação esperada (o 'xxx' num URL como o seguinte: https://msn.com/en-us/money/stockdetails/xxx/).
Comment[sv]=Listan över tillgängliga kursnoteringar kan hämtas från <a href="https://www.msn.com/en-us/money/">MSN</a>.<br/>Skriv därefter in förväntad kurs (xxx i webbadressen https://www.msn.com/en-us/money/stockdetails/xxx).
Comment[uk]=Список доступних курсів можна отримати з <a href="https://www.msn.com/en-us/money/">MSN</a>.<br/>Далі, введіть потрібний курс (xxx у адресі, наприклад https://www.msn.com/en-us/money/stockdetails/xxx).
Comment[x-test]=xxYou can get the list of available quotes from <a href="https://www.msn.com/en-us/money/">MSN</a>.<br/>Then, enter the code of the expected quote (the xxx in the url like https://www.msn.com/en-us/money/stockdetails/xxx).xx
Encoding=UTF-8
Icon=skrooge
Type=Service
X-KDE-ServiceTypes=skrooge/source
X-Krunner-ID=msn
X-KDE-PluginInfo-Author=Stephane MANKOWSKI,miraks
X-KDE-PluginInfo-Email=stephane@mankowski.fr
X-KDE-PluginInfo-Name=MSN
X-KDE-PluginInfo-Version=1.0
-X-KDE-PluginInfo-Website=http://skrooge.org/
+X-KDE-PluginInfo-Website=https://skrooge.org/
X-KDE-PluginInfo-Category=Plugins
X-KDE-PluginInfo-Depends=
X-KDE-PluginInfo-License=GPL
X-KDE-PluginInfo-EnabledByDefault=true
#The url or the command line to get the list of accounts in the standard output, something like this:
#%1 will be replaced by the internet code of the unit
#%2 will be replaced by the current day in format yyyy-MM-dd
#%3 will be replaced by the previous date in format yyyy-MM-dd
#Example:
-# X-SKROOGE-url=http://server/?s=%1
+# X-SKROOGE-url=https://server/?s=%1
# or
# X-SKROOGE-script=mydownloadscript %1
#This parameter is MANDATORY
X-SKROOGE-url=http://www.msn.com/en-us/money/stockdetails/%1
#The mode (HTML or CSV or CSVR). In HTML mode, only one value will be extracted from downloaded page. In CSV mode, a value per line will be extracted. CSVR means CSV in reverse mode
X-SKROOGE-mode=HTML
#Regular expression to capture the price of the quote
#This parameter is not MANDATORY.
X-SKROOGE-price="currentvalue">([^<]*)<
#Regular expression to capture the date of the quote
#This parameter is not MANDATORY.
#X-SKROOGE-date=%1,([^,]*),.*
#The date format
#X-SKROOGE-dateformat=yyyy-MM-dd
diff --git a/skgbankmodeler/sources/org.kde.skrooge-source-ratesapi.desktop b/skgbankmodeler/sources/org.kde.skrooge-source-ratesapi.desktop
index 0dbfaae16..7bd11be6e 100644
--- a/skgbankmodeler/sources/org.kde.skrooge-source-ratesapi.desktop
+++ b/skgbankmodeler/sources/org.kde.skrooge-source-ratesapi.desktop
@@ -1,66 +1,66 @@
[Desktop Entry]
Name=RatesAPI
Name[ca]=RatesAPI
Name[cs]=RatesAPI
Name[en_GB]=RatesAPI
Name[es]=RatesAPI
Name[gl]=RatesAPI
Name[it]=RatesAPI
Name[nl]=RatesAPI
Name[pl]=RatesAPI
Name[pt]=RatesAPI
Name[sv]=RatesAPI
Name[uk]=RatesAPI
Name[x-test]=xxRatesAPIxx
Comment=You can get the list of available quotes from <a href="http://ratesapi.io/">RatesAPI</a>.<br/>Then, enter the expected quote in format CURRENCY/BASE (eg. USD/EUR).
Comment[ca]=Podeu obtenir la llista de les cotitzacions disponibles a <a href="http://ratesapi.io/">RatesAPI</a>.<br/>Després introduïu la cotització desitjada en format DIVISA/BASE (p. ex. USD/EUR).
Comment[en_GB]=You can get the list of available quotes from <a href="http://ratesapi.io/">RatesAPI</a>.<br/>Then, enter the expected quote in format CURRENCY/BASE (eg. USD/EUR).
Comment[es]=Puede obtener la lista de las cotizaciones disponibles de <a href="http://ratesapi.io">RatesAPI</a>.<br/>A continuación, introduzca la cotización esperada con el formato DIVISA/BASE (por ejemplo, USD/EUR).
Comment[gl]=Pode obter a lista de cotizacións dispoñíbeis de <a href="http://ratesapi.io/">RatesAPI</a>.<br/>A continuación escriba a cotización esperada no formato DIVISA/BASE (p. ex. USD/EUR).
Comment[it]=Puoi ottenere l'elenco delle quotazioni disponibili da <a href="http://ratesapi.io/">RatesAPI</a>.<br/>Digita, quindi, la quotazione attesa nel formato VALUTA/BASE (es. USD/EUR).
Comment[nl]=U kunt de lijst met namen van beschikbare koersen ophalen uit <a href="http://ratesapi.io/">RatesAPI</a>.<br/>Voer dan de gewenste koers in in het formaat VALUTA/BASIS (bijv. USD/EUR).
Comment[pl]=Możesz pobrać wykaz dostępnych wycen z <<a href="http://ratesapi.io/">RatesAPI</a>.<br/>Następnie podaj symbol żądanej wyceny w postaci WALUTA DOCELOWA/WALUTA ODNIESIENIA (np. USD/EUR).
Comment[pt]=Poderá obter a lista de cotações disponíveis a partir do <a href="http://ratesapi.io/">RatesAPI</a>.<br/>Depois, indique o símbolo das cotações esperadas no formato MOEDA/BASE (p.ex., USD/EUR).
Comment[sv]=Listan över tillgängliga kursnoteringar kan hämtas från <a href="http://ratesapi.io/">RatesAPI</a>.<br/>Skriv därefter in förväntad kursnotering på formatet VALUTA/BAS (t.ex. USD/EUR).
Comment[uk]=Ви можете отримати список доступних курсів з сайта <a href="http://ratesapi.io/">RatesAPI</a>.<br/>Далі, введіть потрібний вам курс у форматі ВАЛЮТА/ЕТАЛОН (наприклад USD/EUR).
Comment[x-test]=xxYou can get the list of available quotes from <a href="http://ratesapi.io/">RatesAPI</a>.<br/>Then, enter the expected quote in format CURRENCY/BASE (eg. USD/EUR).xx
Encoding=UTF-8
Icon=skrooge
Type=Service
X-KDE-ServiceTypes=skrooge/source
X-Krunner-ID=ratesapi
X-KDE-PluginInfo-Author=Stephane MANKOWSKI,miraks
X-KDE-PluginInfo-Email=stephane@mankowski.fr
X-KDE-PluginInfo-Name=RatesAPI
X-KDE-PluginInfo-Version=1.0
-X-KDE-PluginInfo-Website=http://skrooge.org/
+X-KDE-PluginInfo-Website=https://skrooge.org/
X-KDE-PluginInfo-Category=Plugins
X-KDE-PluginInfo-Depends=
X-KDE-PluginInfo-License=GPL
X-KDE-PluginInfo-EnabledByDefault=true
#The url or the command line to get the list of accounts in the standard output, something like this:
#%1 will be replaced by the internet code of the unit
#%2 will be replaced by the current day in format yyyy-MM-dd
#%3 will be replaced by the previous date in format yyyy-MM-dd
#Example:
-# X-SKROOGE-url=http://server/?s=%1
+# X-SKROOGE-url=https://server/?s=%1
# or
# X-SKROOGE-script=mydownloadscript %1
#This parameter is MANDATORY
X-SKROOGE-script=skrooge-ratesapi.py %1
#The mode (HTML or CSV or CSVR). In HTML mode, only one value will be extracted from downloaded page. In CSV mode, a value per line will be extracted. CSVR means CSV in reverse mode
X-SKROOGE-mode=CSV
#Regular expression to capture the price of the quote
#This parameter is not MANDATORY.
X-SKROOGE-price=[^,]*,([^,]*)
#Regular expression to capture the date of the quote
#This parameter is not MANDATORY.
X-SKROOGE-date=([^,]*),.*
#The date format
X-SKROOGE-dateformat=yyyy-MM-dd
diff --git a/skgbankmodeler/sources/org.kde.skrooge-source-skrooge.desktop b/skgbankmodeler/sources/org.kde.skrooge-source-skrooge.desktop
index fcb6048ea..0b312c064 100644
--- a/skgbankmodeler/sources/org.kde.skrooge-source-skrooge.desktop
+++ b/skgbankmodeler/sources/org.kde.skrooge-source-skrooge.desktop
@@ -1,86 +1,86 @@
[Desktop Entry]
Name=Skrooge
Name[bs]=Skrooge
Name[ca]=Skrooge
Name[ca@valencia]=Skrooge
Name[cs]=Skrooge
Name[da]=Skrooge
Name[de]=Skrooge
Name[el]=Skrooge
Name[en_GB]=Skrooge
Name[eo]=Skrooge
Name[es]=Skrooge
Name[et]=Skrooge
Name[fi]=Skrooge
Name[fr]=Skrooge
Name[gl]=Skrooge
Name[hu]=Skrooge
Name[it]=Skrooge
Name[lt]=Skrooge
Name[nb]=Skrooge
Name[nl]=Skrooge
Name[pl]=Skrooge
Name[pt]=Skrooge
Name[pt_BR]=Skrooge
Name[ru]=Skrooge
Name[sk]=Skrooge
Name[sv]=Skrooge
Name[tr]=Skrooge
Name[uk]=Skrooge
Name[x-test]=xxSkroogexx
Name[zh_CN]=Skrooge
Name[zh_TW]=Skrooge
Comment=Here is the list of available quotes: fr_inflation.
Comment[ca]=Aquí hi ha la llista de cotitzacions disponibles: fr_inflation.
Comment[ca@valencia]=Ací hi ha la llista de cotitzacions disponibles: fr_inflation.
Comment[en_GB]=Here is the list of available quotes: fr_inflation.
Comment[es]=Esta es la lista de las cotizaciones disponibles: fr_inflation.
Comment[fr]=Voici la liste des cotations disponibles: fr_inflation.
Comment[gl]=Esta é a lista de cotizacións dispoñíbeis: fr_inflation.
Comment[it]=Ecco l'elenco delle quotazioni disponibili: fr_inflation.
Comment[nl]=Hier is de lijst met beschikbare quotes: fr_inflation.
Comment[pl]=Oto lista dostępnych wycen: fr_inflation.
Comment[pt]=Aqui está a lista de cotações disponíveis: fr_inflation.
Comment[sv]=Här är listan över tillgängliga kursnoteringar: fr_inflation
Comment[uk]=Ось список доступних курсів: fr_inflation.
Comment[x-test]=xxHere is the list of available quotes: fr_inflation.xx
Encoding=UTF-8
Icon=skrooge
Type=Service
X-KDE-ServiceTypes=skrooge/source
X-Krunner-ID=skrooge
X-KDE-PluginInfo-Author=Stephane MANKOWSKI,miraks
X-KDE-PluginInfo-Email=stephane@mankowski.fr
X-KDE-PluginInfo-Name=Skrooge
X-KDE-PluginInfo-Version=1.0
-X-KDE-PluginInfo-Website=http://skrooge.org/
+X-KDE-PluginInfo-Website=https://skrooge.org/
X-KDE-PluginInfo-Category=Plugins
X-KDE-PluginInfo-Depends=
X-KDE-PluginInfo-License=GPL
X-KDE-PluginInfo-EnabledByDefault=true
#The url or the command line to get the list of accounts in the standard output, something like this:
#%1 will be replaced by the internet code of the unit
#%2 will be replaced by the current day in format yyyy-MM-dd
#%3 will be replaced by the previous date in format yyyy-MM-dd
#Example:
-# X-SKROOGE-url=http://server/?s=%1
+# X-SKROOGE-url=https://server/?s=%1
# or
# X-SKROOGE-script=mydownloadscript %1
#This parameter is MANDATORY
X-SKROOGE-url=https://filedn.com/lfh5wtnkbtUFtBhIeKEriJz/skrooge/%1.csv
#The mode (HTML or CSV or CSVR). In HTML mode, only one value will be extracted from downloaded page. In CSV mode, a value per line will be extracted. CSVR means CSV in reverse mode
X-SKROOGE-mode=CSV
#Regular expression to capture the price of the quote
#This parameter is not MANDATORY.
X-SKROOGE-price=[^,]*,([^,]*)
#Regular expression to capture the date of the quote
#This parameter is not MANDATORY.
X-SKROOGE-date=([^,]*),.*
#The date format
X-SKROOGE-dateformat=yyyy
diff --git a/skgbankmodeler/sources/org.kde.skrooge-source-stooq.desktop b/skgbankmodeler/sources/org.kde.skrooge-source-stooq.desktop
index 73769a59e..c573955db 100644
--- a/skgbankmodeler/sources/org.kde.skrooge-source-stooq.desktop
+++ b/skgbankmodeler/sources/org.kde.skrooge-source-stooq.desktop
@@ -1,70 +1,70 @@
[Desktop Entry]
Name=Stooq
Name[ca]=Stooq
Name[ca@valencia]=Stooq
Name[de]=Stooq
Name[en_GB]=Stooq
Name[es]=Stooq
Name[fr]=Stooq
Name[gl]=Stooq
Name[it]=Stooq
Name[nl]=Stooq
Name[pl]=Stooq
Name[pt]=Stooq
Name[sv]=Stooq
Name[uk]=Stooq
Name[x-test]=xxStooqxx
Comment=You can get the list of available quotes from <a href="https://stooq.pl">Stooq</a>.<br/>Then, enter the symbol of the expected quotes.
Comment[ca]=Podeu obtenir la llista de les cotitzacions disponibles a <a href="https://stooq.pl">Stooq</a>.<br/>Després introduïu el símbol de les cotitzacions esperades.
Comment[ca@valencia]=Podeu obtindre la llista de les cotitzacions disponibles a <a href="https://stooq.pl">Stooq</a>.<br/>Després introduïu el símbol de les cotitzacions esperades.
Comment[en_GB]=You can get the list of available quotes from <a href="https://stooq.pl">Stooq</a>.<br/>Then, enter the symbol of the expected quotes.
Comment[es]=Puede obtener la lista de las cotizaciones disponibles de <a href="https://stooq.pl">Stooq</a>.<br/>A continuación, introduzca el símbolo de las cotizaciones esperadas.
Comment[fr]=Vous pouvez récupérer la liste des cotation disponibles depuis <a href="https://stooq.pl">Stooq</a>.<br/> Ensuite, entrez le symbole de la cotation souhaitée.
Comment[gl]=Pode obter a lista de cotizacións dispoñíbeis de <a href="https://stooq.pl">Stooq</a>.<br/>A continuación escriba o símbolo das cotizacións esperadas.
Comment[it]=Puoi ottenere l'elenco delle quotazioni disponibili da <a href="https://stooq.pl">Stooq</a>.<br/>Digita, quindi, il simbolo delle quotazioni desiderate.
Comment[nl]=U kunt de lijst met namen van beschikbare koersen ophalen uit <a href="https://stooq.pl">Stooq</a>.<br/>Voer dan het symbool van de gewenste koers in.
Comment[pl]=Możesz pobrać wykaz dostępnych wycen z <a href="https://stooq.pl">Stooq</a>.<br/>Następnie podaj symbol żądanej wyceny.
Comment[pt]=Poderá obter a lista de cotações disponíveis a partir do <a href="https://stooq.pl">Stooq</a>.<br/>Depois, indique o símbolo das cotações esperadas.
Comment[sv]=Listan över tillgängliga kursnoteringar kan hämtas från <a href="https://stooq.pl">Stooq</a>.<br/>Skriv därefter in symbolen för de förväntade kurserna.
Comment[uk]=Список доступних курсів можна отримати з <a href="https://stooq.pl">Stooq</a><br/>Далі, введіть позначення потрібного курсу.
Comment[x-test]=xxYou can get the list of available quotes from <a href="https://stooq.pl">Stooq</a>.<br/>Then, enter the symbol of the expected quotes.xx
Encoding=UTF-8
Icon=skrooge
Type=Service
X-KDE-ServiceTypes=skrooge/source
X-Krunner-ID=stooq
X-KDE-PluginInfo-Author=Stephane MANKOWSKI,miraks
X-KDE-PluginInfo-Email=stephane@mankowski.fr
X-KDE-PluginInfo-Name=Stooq
X-KDE-PluginInfo-Version=1.0
-X-KDE-PluginInfo-Website=http://skrooge.org/
+X-KDE-PluginInfo-Website=https://skrooge.org/
X-KDE-PluginInfo-Category=Plugins
X-KDE-PluginInfo-Depends=
X-KDE-PluginInfo-License=GPL
X-KDE-PluginInfo-EnabledByDefault=true
#The url or the command line to get the list of accounts in the standard output, something like this:
#%1 will be replaced by the internet code of the unit
#%2 will be replaced by the current day in format yyyy-MM-dd
#%3 will be replaced by the previous date in format yyyy-MM-dd
#Example:
-# X-SKROOGE-url=http://server/?s=%1
+# X-SKROOGE-url=https://server/?s=%1
# or
# X-SKROOGE-script=mydownloadscript %1
#This parameter is MANDATORY
X-SKROOGE-url=http://stooq.com.ph/q/l/?s=%1&f=sd2t2ohlcv&h&e=csv
#The mode (HTML or CSV or CSVR). In HTML mode, only one value will be extracted from downloaded page. In CSV mode, a value per line will be extracted. CSVR means CSV in reverse mode
X-SKROOGE-mode=CSV
#Regular expression to capture the price of the quote
#This parameter is not MANDATORY.
X-SKROOGE-price=%1,[^,]*,[^,]*,[^,]*,[^,]*,[^,]*,([^,]*),.*
#Regular expression to capture the date of the quote
#This parameter is not MANDATORY.
X-SKROOGE-date=%1,([^,]*),.*
#The date format
X-SKROOGE-dateformat=yyyy-MM-dd
diff --git a/skgbankmodeler/sources/org.kde.skrooge-source-yahoo.desktop b/skgbankmodeler/sources/org.kde.skrooge-source-yahoo.desktop
index ff9f79fee..d19a7427e 100644
--- a/skgbankmodeler/sources/org.kde.skrooge-source-yahoo.desktop
+++ b/skgbankmodeler/sources/org.kde.skrooge-source-yahoo.desktop
@@ -1,72 +1,72 @@
[Desktop Entry]
Name=Yahoo
Name[ca]=Yahoo
Name[ca@valencia]=Yahoo
Name[cs]=Yahoo
Name[de]=Yahoo
Name[en_GB]=Yahoo
Name[es]=Yahoo
Name[fr]=Yahoo
Name[gl]=Yahoo
Name[it]=Yahoo
Name[nl]=Yahoo
Name[pl]=Yahoo
Name[pt]=Yahoo
Name[sv]=Yahoo
Name[uk]=Yahoo
Name[x-test]=xxYahooxx
Name[zh_CN]=Yahoo
Comment=You can get the list of available quotes from <a href="https://finance.yahoo.com">Yahoo Finance</a>.<br/>Then, enter the symbol of the expected quotes.
Comment[ca]=Podeu obtenir la llista de les cotitzacions disponibles a <a href="https://finance.yahoo.com">Yahoo Finance</a>.<br/>Després introduïu el símbol de les cotitzacions esperades.
Comment[ca@valencia]=Podeu obtindre la llista de les cotitzacions disponibles a <a href="https://finance.yahoo.com">Yahoo Finance</a>.<br/>Després introduïu el símbol de les cotitzacions esperades.
Comment[en_GB]=You can get the list of available quotes from <a href="https://finance.yahoo.com">Yahoo Finance</a>.<br/>Then, enter the symbol of the expected quotes.
Comment[es]=Puede obtener la lista de las cotizaciones disponibles de <a href="https://finance.yahoo.com">Yahoo Finance</a>.<br/>A continuación, introduzca el símbolo de las cotizaciones esperadas.
Comment[fr]=Vous pouvez récupérer la liste des cotation disponibles depuis <a href="https://finance.yahoo.com">Yahoo Finance</a>.<br/> Ensuite, entrez le symbole de la cotation souhaitée.
Comment[gl]=Pode obter a lista de cotizacións dispoñíbeis de <a href="https://finance.yahoo.com">Yahoo Finance</a>.A continuación escriba o símbolo das cotizacións esperadas.
Comment[it]=Puoi ottenere l'elenco delle quotazioni disponibili da <a href="https://it.finance.yahoo.com/">Yahoo Finanza</a>.<br/>Digita, quindi, il simbolo delle quotazioni desiderate.
Comment[nl]=U kunt de lijst met namen van beschikbare koersen ophalen uit <a href="https://finance.yahoo.com">Yahoo Finance</a>.<br/>Voer dan de naam van de gewenste koers in.
Comment[pl]=Możesz pobrać wykaz dostępnych wycen z <a href="https://finance.yahoo.com">Yahoo Finance</a>.<br/>Następnie podaj symbol żądanej wyceny.
Comment[pt]=Poderá obter a lista de cotações disponíveis a partir do <a href="https://finance.yahoo.com">Yahoo Finance</a>. Depois, indique o símbolo das cotações esperadas.
Comment[sv]=Listan över tillgängliga kursnoteringar kan hämtas från <a href="https://finance.yahoo.com">Yahoo Finance</a>.<br/>Skriv därefter in symbolen för de förväntade kurserna.
Comment[uk]=Список доступних курсів можна отримати з <a href="https://finance.yahoo.com">Yahoo Finance</a>.<br/>Далі, введіть позначення потрібних курсів.
Comment[x-test]=xxYou can get the list of available quotes from <a href="https://finance.yahoo.com">Yahoo Finance</a>.<br/>Then, enter the symbol of the expected quotes.xx
Encoding=UTF-8
Icon=skrooge
Type=Service
X-KDE-ServiceTypes=skrooge/source
X-Krunner-ID=yahoo
X-KDE-PluginInfo-Author=Stephane MANKOWSKI,miraks
X-KDE-PluginInfo-Email=stephane@mankowski.fr
X-KDE-PluginInfo-Name=Yahoo
X-KDE-PluginInfo-Version=1.0
-X-KDE-PluginInfo-Website=http://skrooge.org/
+X-KDE-PluginInfo-Website=https://skrooge.org/
X-KDE-PluginInfo-Category=Plugins
X-KDE-PluginInfo-Depends=
X-KDE-PluginInfo-License=GPL
X-KDE-PluginInfo-EnabledByDefault=true
#The url or the command line to get the list of accounts in the standard output, something like this:
#%1 will be replaced by the internet code of the unit
#%2 will be replaced by the current day in format yyyy-MM-dd
#%3 will be replaced by the previous date in format yyyy-MM-dd
#Example:
-# X-SKROOGE-url=http://server/?s=%1
+# X-SKROOGE-url=https://server/?s=%1
# or
# X-SKROOGE-script=mydownloadscript %1
#This parameter is MANDATORY
X-SKROOGE-script=skrooge-yahoodl.py %1 %3 %2 %4
#The mode (HTML or CSV or CSVR). In HTML mode, only one value will be extracted from downloaded page. In CSV mode, a value per line will be extracted. CSVR means CSV in reverse mode
X-SKROOGE-mode=CSV
#Regular expression to capture the price of the quote
#This parameter is not MANDATORY.
X-SKROOGE-price=[^,]*,[^,]*,[^,]*,([^,]*)
#Regular expression to capture the date of the quote
#This parameter is not MANDATORY.
X-SKROOGE-date=([^,]*),.*
#The date format
X-SKROOGE-dateformat=yyyy-MM-dd
diff --git a/skgbasegui/CMakeLists.txt b/skgbasegui/CMakeLists.txt
index f2e284877..be0e5f607 100644
--- a/skgbasegui/CMakeLists.txt
+++ b/skgbasegui/CMakeLists.txt
@@ -1,108 +1,108 @@
#***************************************************************************
#* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
#* *
#* 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 <http://www.gnu.org/licenses/> *
+#* along with this program. If not, see <https://www.gnu.org/licenses/> *
#***************************************************************************
MESSAGE( STATUS "..:: CMAKE SKGBASEGUI ::..")
PROJECT(SKGBASEGUI)
FIND_PACKAGE(KF5Activities)
FIND_PACKAGE(KF5 5.0.0 REQUIRED COMPONENTS
GuiAddons # Tier 1
Notifications # Tier 3
NotifyConfig # Tier 3
)
IF(SKG_WEBENGINE)
MESSAGE( STATUS " Mode WebEngine")
ADD_DEFINITIONS(-DSKG_WEBENGINE=${SKG_WEBENGINE})
ENDIF(SKG_WEBENGINE)
LINK_DIRECTORIES (${LIBRARY_OUTPUT_PATH})
SET(skgbasegui_SRCS
skgmainpanel.cpp
skgobjectmodelbase.cpp
skgwidget.cpp
skgperiodedit.cpp
skgtabwidget.cpp
skgtablewidget.cpp
skgtabpage.cpp
skginterfaceplugin.cpp
skgtableview.cpp
skgfilteredtableview.cpp
skgtreeview.cpp
skgcombobox.cpp
skgcolorbutton.cpp
skgzoomselector.cpp
skgcalculatoredit.cpp
skggraphicsscene.cpp
skggraphicsview.cpp
skghtmlboardwidget.cpp
skgboardwidget.cpp
skgtablewithgraph.cpp
skgdateedit.cpp
skgprogressbar.cpp
kdateedit.cpp
kdatepickerpopup.cpp
kdatevalidator.cpp
skgsortfilterproxymodel.cpp
skgflowlayout.cpp
skgwebview.cpp
skgshow.cpp
skgwidgetselector.cpp
skgsimpleperiodedit.cpp
)
SET(LIBS KF5::Parts KF5::KIOFileWidgets KF5::NotifyConfig KF5::Notifications Qt5::QuickWidgets Qt5::PrintSupport Qt5::Svg skgbasemodeler)
IF(SKG_WEBENGINE)
SET(LIBS ${LIBS} Qt5::WebEngineWidgets)
ELSE(SKG_WEBENGINE)
SET(LIBS ${LIBS} Qt5::WebKitWidgets)
ENDIF(SKG_WEBENGINE)
IF(KActivities_FOUND)
MESSAGE( STATUS " KActivity FOUND" )
SET(LIBS ${LIBS} KF5::Activities)
ENDIF(KActivities_FOUND)
ki18n_wrap_ui(skgbasegui_SRCS skgmainpanel_base.ui skgmainpanel_pref.ui skggraphicsview.ui skgtablewithgraph.ui skgcolorbutton.ui skgzoomselector.ui skgperiodedit.ui skgfilteredtableview.ui skgwidgetselector.ui )
kconfig_add_kcfg_files(skgbasegui_SRCS skgbasegui_settings.kcfgc )
ADD_LIBRARY(skgbasegui SHARED ${skgbasegui_SRCS})
TARGET_LINK_LIBRARIES(skgbasegui LINK_PUBLIC ${LIBS})
SET_TARGET_PROPERTIES(skgbasegui PROPERTIES VERSION ${SKG_VERSION} SOVERSION ${SOVERSION} )
GENERATE_EXPORT_HEADER(skgbasegui BASE_NAME skgbasegui)
########### install files ###############
INSTALL(TARGETS skgbasegui ${INSTALL_TARGETS_DEFAULT_ARGS} LIBRARY NAMELINK_SKIP )
INSTALL(FILES ${PROJECT_SOURCE_DIR}/skgmainpanel.rc DESTINATION ${KDE_INSTALL_KXMLGUI5DIR}/skg )
INSTALL(FILES ${PROJECT_SOURCE_DIR}/skgbasegui_settings.kcfg DESTINATION ${KDE_INSTALL_KCFGDIR} )
INSTALL(FILES ${PROJECT_SOURCE_DIR}/org.kde.skg-plugin.desktop DESTINATION ${KDE_INSTALL_KSERVICETYPES5DIR})
INSTALL(DIRECTORY icons_breeze/ DESTINATION ${ICON_INSTALL_DIR}/breeze/actions/22 FILES_MATCHING PATTERN "*.svgz")
INSTALL(DIRECTORY icons_breeze-dark/ DESTINATION ${ICON_INSTALL_DIR}/breeze-dark/actions/22 FILES_MATCHING PATTERN "*.svgz")
ECM_INSTALL_ICONS(ICONS
icons_hicolor/16-actions-skg-chart-bubble.png
icons_hicolor/22-actions-skg-chart-bubble.png
icons_hicolor/32-actions-skg-chart-bubble.png
icons_hicolor/48-actions-skg-chart-bubble.png
icons_hicolor/64-actions-skg-chart-bubble.png
icons_hicolor/128-actions-skg-chart-bubble.png
icons_hicolor/256-actions-skg-chart-bubble.png
icons_hicolor/512-actions-skg-chart-bubble.png
icons_hicolor/sc-actions-skg-chart-bubble.svgz
DESTINATION ${ICON_INSTALL_DIR}
THEME hicolor
)
diff --git a/skgbasegui/skgboardwidget.cpp b/skgbasegui/skgboardwidget.cpp
index 727722473..95c8128e1 100644
--- a/skgbasegui/skgboardwidget.cpp
+++ b/skgbasegui/skgboardwidget.cpp
@@ -1,314 +1,314 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is a generic for board widget.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgboardwidget.h"
#include <qdom.h>
#include <qinputdialog.h>
#include <qmenu.h>
#include <qpushbutton.h>
#include <qtoolbutton.h>
#include <qwidgetaction.h>
#include <klocalizedstring.h>
#include "skgmainpanel.h"
#include "skgtraces.h"
#include "skgzoomselector.h"
SKGBoardWidget::SKGBoardWidget(QWidget* iParent, SKGDocument* iDocument, const QString& iTitle, bool iZoomable)
: SKGWidget(iParent, iDocument), m_menu(nullptr), m_zoomMenu(nullptr), m_zoomRatio(1.0), m_title(iTitle), m_titleDefault(iTitle)
{
SKGTRACEINFUNC(10)
// Created widgets
auto horizontalLayout = new QHBoxLayout(this);
horizontalLayout->setSpacing(0);
horizontalLayout->setContentsMargins(0, 0, 0, 0);
m_frame = new QFrame(this);
m_frame->setObjectName(QStringLiteral("frame"));
m_frame->setFrameShape(QFrame::StyledPanel);
m_frame->setFrameShadow(QFrame::Raised);
m_gridLayout = new QGridLayout(m_frame);
m_gridLayout->setSpacing(2);
m_gridLayout->setContentsMargins(0, 0, 0, 0);
m_toolButton = new QToolButton(m_frame);
m_toolButton->setIconSize(QSize(16, 16));
m_toolButton->setMaximumSize(QSize(22, 22));
m_toolButton->setPopupMode(QToolButton::InstantPopup);
m_toolButton->setAutoRaise(true);
m_toolButton->hide();
m_gridLayout->addWidget(m_toolButton, 0, 0, 1, 1);
m_Title = new QLabel(m_frame);
QFont boldFont = m_Title->font();
boldFont.setBold(true);
m_Title->setFont(boldFont);
m_Title->setAlignment(Qt::AlignCenter);
m_Title->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed));
getDragWidget()->setCursor(QCursor(Qt::OpenHandCursor));
m_gridLayout->addWidget(m_Title, 0, 1, 1, 1);
m_line = new QFrame(m_frame);
m_line->setFrameShape(QFrame::HLine);
m_line->setFrameShadow(QFrame::Sunken);
m_gridLayout->addWidget(m_line, 1, 0, 1, 2);
horizontalLayout->addWidget(m_frame);
// Add default actions
auto w = new QWidget(this);
auto hlayoutMove = new QHBoxLayout(w);
hlayoutMove->setSpacing(2);
hlayoutMove->setContentsMargins(0, 0, 0, 0);
auto pbFirst = new QPushButton(w);
pbFirst->setToolTip(i18nc("Move tooltip", "Move first"));
pbFirst->setIcon(SKGServices::fromTheme(QStringLiteral("go-first-view")));
pbFirst->setMaximumSize(QSize(22, 22));
pbFirst->setFlat(true);
connect(pbFirst, &QPushButton::clicked, this, &SKGBoardWidget::requestMoveFirst);
hlayoutMove->addWidget(pbFirst);
auto pbBefore = new QPushButton(w);
pbBefore->setToolTip(i18nc("Move tooltip", "Move before"));
pbBefore->setIcon(SKGServices::fromTheme(QStringLiteral("go-previous-view")));
pbBefore->setMaximumSize(QSize(22, 22));
pbBefore->setFlat(true);
connect(pbBefore, &QPushButton::clicked, this, &SKGBoardWidget::requestMoveBefore);
hlayoutMove->addWidget(pbBefore);
auto pbDelete = new QPushButton(w);
pbDelete->setToolTip(i18nc("Move tooltip", "Delete"));
pbDelete->setIcon(SKGServices::fromTheme(QStringLiteral("edit-delete")));
pbDelete->setMaximumSize(QSize(22, 22));
pbDelete->setFlat(true);
connect(pbDelete, &QPushButton::clicked, this, &SKGBoardWidget::requestRemove);
hlayoutMove->addWidget(pbDelete);
auto pbAfter = new QPushButton(w);
pbAfter->setToolTip(i18nc("Move tooltip", "Move after"));
pbAfter->setIcon(SKGServices::fromTheme(QStringLiteral("go-next-view")));
pbAfter->setMaximumSize(QSize(22, 22));
pbAfter->setFlat(true);
connect(pbAfter, &QPushButton::clicked, this, &SKGBoardWidget::requestMoveAfter);
hlayoutMove->addWidget(pbAfter);
auto pbLast = new QPushButton(w);
pbLast->setToolTip(i18nc("Move tooltip", "Move last"));
pbLast->setIcon(SKGServices::fromTheme(QStringLiteral("go-last-view")));
pbLast->setMaximumSize(QSize(22, 22));
pbLast->setFlat(true);
connect(pbLast, &QPushButton::clicked, this, &SKGBoardWidget::requestMoveLast);
hlayoutMove->addWidget(pbLast);
auto moveWidget = new QWidgetAction(this);
moveWidget->setDefaultWidget(w);
addAction(moveWidget);
if (iZoomable) {
m_zoomMenu = new SKGZoomSelector(this);
m_zoomMenu->setResetValue(-10);
m_zoomMenu->setValue(-10, false);
connect(m_zoomMenu, &SKGZoomSelector::changed, this, &SKGBoardWidget::onZoom);
auto zoomWidget = new QWidgetAction(this);
zoomWidget->setDefaultWidget(m_zoomMenu);
addAction(zoomWidget);
}
m_menuRename = new QAction(SKGServices::fromTheme(QStringLiteral("edit-rename")), i18nc("Verb, change the name of an item", "Rename"), this);
connect(m_menuRename, &QAction::triggered, this, &SKGBoardWidget::onRenameTitle);
addAction(m_menuRename);
auto sep = new QAction(this);
sep->setSeparator(true);
addAction(sep);
// Set main title
setMainTitle(iTitle);
// Set default icon
m_toolButton->setIcon(SKGServices::fromTheme(QStringLiteral("configure")));
}
SKGBoardWidget::~SKGBoardWidget()
{
SKGTRACEINFUNC(10)
m_menuRename = nullptr;
}
QWidget* SKGBoardWidget::getDragWidget()
{
return m_Title;
}
double SKGBoardWidget::getZoomRatio()
{
return m_zoomRatio;
}
void SKGBoardWidget::onZoom(int iZoom)
{
setZoomRatio((iZoom + 15.0) / 5.0);
}
void SKGBoardWidget::requestMoveAfter()
{
Q_EMIT requestMove(1);
}
void SKGBoardWidget::requestMoveBefore()
{
Q_EMIT requestMove(-1);
}
void SKGBoardWidget::requestMoveFirst()
{
Q_EMIT requestMove(-100000);
}
void SKGBoardWidget::requestMoveLast()
{
Q_EMIT requestMove(100000);
}
void SKGBoardWidget::setZoomRatio(double iRatio)
{
if (m_zoomMenu != nullptr) {
if (m_zoomRatio == 1.0) {
// Memorize initial size
m_initialSize = minimumSize();
}
// Move zoom widget
m_zoomRatio = iRatio;
if (m_zoomRatio < 1.0) {
m_zoomRatio = 1.0;
} else if (m_zoomRatio > 5.0) {
m_zoomRatio = 5.0;
}
m_zoomMenu->setValue(5.0 * iRatio - 15.0, false);
// Resize widget
QSize newSize(m_initialSize.width()*iRatio, m_initialSize.height()*iRatio);
setMinimumSize(newSize);
}
}
void SKGBoardWidget::setState(const QString& iState)
{
QDomDocument doc(QStringLiteral("SKGML"));
if (doc.setContent(iState)) {
QDomElement root = doc.documentElement();
QString title = root.attribute(QStringLiteral("title"));
if (!title.isEmpty()) {
m_title = title;
setMainTitle(title);
}
}
}
QString SKGBoardWidget::getState()
{
QDomDocument doc(QStringLiteral("SKGML"));
QDomElement root = doc.createElement(QStringLiteral("parameters"));
doc.appendChild(root);
root.setAttribute(QStringLiteral("title"), m_title);
return doc.toString();
}
void SKGBoardWidget::onRenameTitle()
{
bool ok = false;
QString newTitle = QInputDialog::getText(SKGMainPanel::getMainPanel(), i18nc("Question", "Title"),
i18nc("Question", "New title (Empty to retrieve the default title):"), QLineEdit::Normal, getOriginalTitle(), &ok);
if (ok) {
m_title = newTitle;
if (m_title.isEmpty()) {
m_title = m_titleDefault;
}
setMainTitle(m_title);
}
}
void SKGBoardWidget::setMainWidget(QWidget* iWidget)
{
iWidget->setParent(m_frame);
m_gridLayout->addWidget(iWidget, 2, 0, 1, 2);
}
void SKGBoardWidget::insertAction(int iPos, QAction* iAction)
{
auto l = m_menu->actions();
m_menu->insertAction(l[iPos], iAction);
// Change icon
if (!iAction->isCheckable() && !iAction->isSeparator()) {
m_toolButton->setIcon(SKGServices::fromTheme(QStringLiteral("run-build-configure")));
}
}
void SKGBoardWidget::addAction(QAction* iAction)
{
if (m_menu == nullptr) {
m_menu = new QMenu(this);
m_toolButton->show();
m_toolButton->setMenu(m_menu);
}
m_menu->addAction(iAction);
// Change icon
if (!iAction->isCheckable() && !iAction->isSeparator()) {
m_toolButton->setIcon(SKGServices::fromTheme(QStringLiteral("run-build-configure")));
}
}
void SKGBoardWidget::hideTitle()
{
m_toolButton->hide();
m_Title->hide();
m_line->hide();
}
void SKGBoardWidget::setMainTitle(const QString& iTitle)
{
m_Title->setText(iTitle);
}
QString SKGBoardWidget::getMainTitle()
{
return m_Title->text();
}
QString SKGBoardWidget::getOriginalTitle()
{
return m_title;
}
#include "skgboardwidget.h"
diff --git a/skgbasegui/skgboardwidget.h b/skgbasegui/skgboardwidget.h
index 5a8120a09..ad01bb368 100644
--- a/skgbasegui/skgboardwidget.h
+++ b/skgbasegui/skgboardwidget.h
@@ -1,174 +1,174 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGBOARDWIDGET_H
#define SKGBOARDWIDGET_H
/** @file
* This file is a generic for board widget.
* @see SKGReport
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgbasegui_export.h"
#include "skgwidget.h"
class QAction;
class QMenu;
class QToolButton;
class QFrame;
class QGridLayout;
class QLabel;
class QAction;
class QMenu;
class SKGZoomSelector;
/**
* This file is a generic for board widget
*/
class SKGBASEGUI_EXPORT SKGBoardWidget : public SKGWidget
{
Q_OBJECT
public:
/**
* Default Constructor
* @param iParent the parent widget
* @param iDocument the document
* @param iTitle the title
* @param iZoomable for a zoomable widget
*/
explicit SKGBoardWidget(QWidget* iParent, SKGDocument* iDocument, const QString& iTitle, bool iZoomable = false);
/**
* Default Destructor
*/
~SKGBoardWidget() override;
/**
* Get the current state
* MUST BE OVERWRITTEN
* @return a string containing all information needed to set the same state.
* Could be an XML stream
*/
QString getState() override;
/**
* Set the current state
* MUST BE OVERWRITTEN
* @param iState must be interpreted to set the state of the widget
*/
void setState(const QString& iState) override;
/**
* Get the widget for drag and drop
* MUST BE OVERWRITTEN
* @return the widget.
*/
virtual QWidget* getDragWidget();
/**
* Set the main widget
* @param iWidget the main widget
*/
virtual void setMainWidget(QWidget* iWidget);
/**
* Set the main title
* @param iTitle the main title
*/
virtual void setMainTitle(const QString& iTitle);
/**
* Get the main title
* @return the main title
*/
virtual QString getMainTitle();
/**
* Get the original title
* @return the original title
*/
virtual QString getOriginalTitle();
/**
* Set the zoom ratio
* @param iRatio the zoom ratio (1 <= iRatio <=5)
*/
virtual void setZoomRatio(double iRatio);
/**
* Get the zoom ratio
* @return the zoom ratio
*/
virtual double getZoomRatio();
/**
* Add an action
* @param iAction the action to add
*/
virtual void addAction(QAction* iAction);
/**
* Insert an action
* @param iPos the position of the insertion
* @param iAction the action to add
*/
virtual void insertAction(int iPos, QAction* iAction);
/**
* Hide title and configuration widget
*/
virtual void hideTitle();
Q_SIGNALS:
/**
* Sent when the remove is requested
*/
void requestRemove();
/**
* Sent when the move is requested
* @param iMove the move to apply
*/
void requestMove(int iMove);
private Q_SLOTS:
void onZoom(int iZoom);
void requestMoveBefore();
void requestMoveAfter();
void requestMoveFirst();
void requestMoveLast();
void onRenameTitle();
private:
Q_DISABLE_COPY(SKGBoardWidget)
QLabel* m_Title{};
QGridLayout* m_gridLayout{};
QFrame* m_frame;
QToolButton* m_toolButton;
QMenu* m_menu;
SKGZoomSelector* m_zoomMenu;
double m_zoomRatio;
QSize m_initialSize;
QFrame* m_line;
QAction* m_menuRename;
QString m_title;
QString m_titleDefault;
};
#endif // SKGBOARDWIDGET_H
diff --git a/skgbasegui/skgcalculatoredit.cpp b/skgbasegui/skgcalculatoredit.cpp
index 186edd028..bc30044b5 100644
--- a/skgbasegui/skgcalculatoredit.cpp
+++ b/skgbasegui/skgcalculatoredit.cpp
@@ -1,274 +1,274 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* A QLineEdit with calculator included.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgcalculatoredit.h"
#include <kcolorscheme.h>
#include <qcompleter.h>
#include <qevent.h>
#include <qscriptengine.h>
#include <qstringlistmodel.h>
#include <qvalidator.h>
#include "skgservices.h"
#include "skgtraces.h"
SKGCalculatorEdit::SKGCalculatorEdit(QWidget* iParent)
: QLineEdit(iParent), m_lastValue(0), m_lastOperator(0), m_currentMode(EXPRESSION)
{
setMode(CALCULATOR);
m_fontColor = palette().color(QPalette::Text);
}
SKGCalculatorEdit::~SKGCalculatorEdit()
= default;
double SKGCalculatorEdit::value()
{
bool test;
return getEvaluatedValue(test);
}
int SKGCalculatorEdit::sign() const
{
QString t = text();
if (!t.isEmpty() && t[0] == '+') {
return 1;
}
if (!t.isEmpty() && t[0] == '-') {
return -1;
}
return 0;
}
SKGCalculatorEdit::Mode SKGCalculatorEdit::mode() const
{
return m_currentMode;
}
void SKGCalculatorEdit::setMode(Mode iMode)
{
if (m_currentMode != iMode) {
m_currentMode = iMode;
if (iMode == CALCULATOR) {
auto newValidator = new QDoubleValidator(this);
setValidator(newValidator);
setAlignment(Qt::AlignRight);
} else {
setValidator(nullptr);
}
Q_EMIT modified();
}
}
void SKGCalculatorEdit::setValue(double iValue)
{
setText(SKGServices::doubleToString(iValue));
}
void SKGCalculatorEdit::setText(const QString& iText)
{
// Set default color
QPalette field_palette = palette();
field_palette.setColor(QPalette::Text, m_fontColor);
setPalette(field_palette);
// Set text (to be sure than keyPressEvent is able to get it)
QLineEdit::setText(iText);
// Simulate a validation
if (mode() == EXPRESSION) {
bool previous = this->blockSignals(true);
keyPressEvent(Qt::Key_Return);
this->blockSignals(previous);
}
// Set text (to display the input value)
if (valid()) {
QLineEdit::setText(iText);
}
Q_EMIT modified();
}
bool SKGCalculatorEdit::valid()
{
bool test;
getEvaluatedValue(test);
return test;
}
QString SKGCalculatorEdit::formula()
{
return m_formula;
}
void SKGCalculatorEdit::addParameterValue(const QString& iParameter, double iValue)
{
m_parameters.insert(iParameter, iValue);
QStringList list;
auto keys = m_parameters.keys();
list.reserve(keys.count());
for (const auto& a : qAsConst(keys)) {
list.append('=' % a);
}
// Refresh completion
auto comp = new QCompleter(list);
comp->setCaseSensitivity(Qt::CaseInsensitive);
comp->setFilterMode(Qt::MatchContains);
setCompleter(comp);
}
void SKGCalculatorEdit::keyPressEvent(QKeyEvent* iEvent)
{
if (iEvent != nullptr) {
int key = iEvent->key();
if (mode() == CALCULATOR) {
bool hasText = !text().isEmpty() && selectedText() != text();
if (iEvent->count() == 1 && ((key == Qt::Key_Plus && hasText) || (key == Qt::Key_Minus && hasText) || key == Qt::Key_Asterisk || key == Qt::Key_Slash || key == Qt::Key_Return || key == Qt::Key_Enter)) {
keyPressEvent(key);
iEvent->accept();
} else {
QLineEdit::keyPressEvent(iEvent);
}
} else {
// Set default color
QPalette field_palette = palette();
field_palette.setColor(QPalette::Text, m_fontColor);
setPalette(field_palette);
keyPressEvent(key);
QLineEdit::keyPressEvent(iEvent);
}
}
}
void SKGCalculatorEdit::focusOutEvent(QFocusEvent* iEvent)
{
if (iEvent->reason() != Qt::ActiveWindowFocusReason) {
keyPressEvent(Qt::Key_Return);
}
QLineEdit::focusOutEvent(iEvent);
}
void SKGCalculatorEdit::keyPressEvent(int key)
{
if (mode() == CALCULATOR) {
if (m_lastOperator != 0) {
if (m_lastOperator == Qt::Key_Plus) {
m_lastValue += value();
setValue(m_lastValue);
} else if (m_lastOperator == Qt::Key_Minus) {
m_lastValue -= value();
setValue(m_lastValue);
} else if (m_lastOperator == Qt::Key_Asterisk) {
m_lastValue *= value();
setValue(m_lastValue);
} else if (m_lastOperator == Qt::Key_Slash && value() != 0) {
m_lastValue /= value();
setValue(m_lastValue);
}
} else {
m_lastValue = value();
}
if (key == Qt::Key_Return || key == Qt::Key_Enter) {
m_lastOperator = 0;
m_lastValue = 0;
} else {
m_lastOperator = key;
QLineEdit::setText(QLatin1String(""));
}
} else {
if (key == Qt::Key_Return || key == Qt::Key_Enter) {
bool test;
double v = getEvaluatedValue(test);
if (test) {
QString t = text();
QLineEdit::setText((!t.isEmpty() && t[0] == '+' && v > 0 ? "+" : "") % SKGServices::doubleToString(v));
} else {
QPalette field_palette = palette();
field_palette.setColor(QPalette::Text, KColorScheme(QPalette::Normal).foreground(KColorScheme::NegativeText).color());
setPalette(field_palette);
}
emit textChanged(text());
}
}
}
double SKGCalculatorEdit::getEvaluatedValue(bool& iOk)
{
qsreal output = 0;
iOk = false;
QString t = text().trimmed();
if (!t.isEmpty()) {
m_formula = t;
t = t.replace(',', '.'); // Replace comma by a point in case of typo
t = t.remove(' '); // Remove space to support this kind of values 3 024,25
if (!QLocale().groupSeparator().isNull()) {
t = t.replace(QLocale().groupSeparator(), '.');
}
// Remove double . in numbers
int toRemoveIndex = -1;
int nbc = t.count();
for (int i = 0; i < nbc; ++i) {
if (t.at(i) == '.') {
if (toRemoveIndex != -1) {
t = t.remove(toRemoveIndex, 1);
--nbc;
--i;
toRemoveIndex = i;
} else {
toRemoveIndex = i;
}
} else if (t.at(i) < '0' || t.at(i) > '9') {
toRemoveIndex = -1;
}
}
if (t.startsWith(QLatin1String("="))) {
t = t.right(t.length() - 1);
QMapIterator<QString, double> i(m_parameters);
while (i.hasNext()) {
i.next();
t.replace(i.key(), SKGServices::doubleToString(i.value()));
}
} else {
m_formula = QLatin1String("");
}
QScriptEngine myEngine;
QScriptValue result = myEngine.evaluate(t);
if (result.isNumber()) {
output = result.toNumber();
iOk = true;
}
}
return output;
}
diff --git a/skgbasegui/skgcalculatoredit.h b/skgbasegui/skgcalculatoredit.h
index 691c1c7bd..cec9d7d6a 100644
--- a/skgbasegui/skgcalculatoredit.h
+++ b/skgbasegui/skgcalculatoredit.h
@@ -1,168 +1,168 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGCALCULATOREDIT_H
#define SKGCALCULATOREDIT_H
/** @file
* A QLineEdit with calculator included.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgbasegui_export.h"
#include <qlineedit.h>
/**
* This file is a QLineEdit with calculator included
*/
class SKGBASEGUI_EXPORT SKGCalculatorEdit : public QLineEdit
{
Q_OBJECT
/**
* Value of the calculator editor
*/
Q_PROPERTY(double value READ value WRITE setValue USER true NOTIFY modified)
/**
* Mode of the calculator editor
*/
Q_PROPERTY(SKGCalculatorEdit::Mode mode READ mode WRITE setMode NOTIFY modified)
/**
* Sign of the calculator editor
*/
Q_PROPERTY(double sign READ sign NOTIFY modified)
/**
* To know if the text is valid
*/
Q_PROPERTY(bool valid READ valid NOTIFY modified)
public:
/**
* This enumerate defines type of calculator
*/
enum Mode {CALCULATOR, /**< simple calculator */
EXPRESSION /**< expression is evaluated */
};
/**
* Mode of the calculator editor
*/
Q_ENUM(Mode)
/**
* Default Constructor
* @param iParent the parent
*/
explicit SKGCalculatorEdit(QWidget* iParent);
/**
* Default Destructor
*/
~SKGCalculatorEdit() override;
/**
* Get the mode
* @return the mode
*/
virtual Mode mode() const;
/**
* Set the mode
* @param iMode the mode
*/
virtual void setMode(Mode iMode);
/**
* Get the value
* @return the value
*/
virtual double value();
/**
* Set the value
* @param iValue the value
*/
virtual void setValue(double iValue);
/**
* Set the text
* @param iText the text
*/
virtual void setText(const QString& iText);
/**
* Get the sign of the value.
* 1 if the value is write like "+5"
* -1 if the value is write like "-5"
* 0 if the value is write like "5"
* @return the sign
*/
virtual int sign() const;
/**
* To know if the text is a valid value
* @return validation
*/
virtual bool valid();
/**
* To formula
* @return the formula
*/
virtual QString formula();
/**
* Add a parameter
* @param iParameter the parameter name
* @param iValue the value
*/
virtual void addParameterValue(const QString& iParameter, double iValue);
Q_SIGNALS:
/**
* This signal is launched when the object is modified
*/
void modified();
protected:
/**
* This event handler, for event event, can be reimplemented in a subclass to receive key press events for the widget.
* @param iEvent the event
*/
void keyPressEvent(QKeyEvent* iEvent) override;
/**
* This event handler can be reimplemented in a subclass to receive keyboard focus events (focus lost) for the widget. The events is passed in the event parameter.
* @param iEvent the event
*/
void focusOutEvent(QFocusEvent* iEvent) override;
private:
Q_DISABLE_COPY(SKGCalculatorEdit)
void keyPressEvent(int key);
double getEvaluatedValue(bool& iOk);
double m_lastValue;
int m_lastOperator;
Mode m_currentMode;
QColor m_fontColor;
QMap<QString, double> m_parameters;
QString m_formula;
};
#endif // SKGCALCULATOREDIT_H
diff --git a/skgbasegui/skgcolorbutton.cpp b/skgbasegui/skgcolorbutton.cpp
index 7aa617d93..f5d017201 100644
--- a/skgbasegui/skgcolorbutton.cpp
+++ b/skgbasegui/skgcolorbutton.cpp
@@ -1,66 +1,66 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* A color button with more features.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgcolorbutton.h"
SKGColorButton::SKGColorButton(QWidget* iParent)
: QWidget(iParent)
{
ui.setupUi(this);
connect(ui.button, &KColorButton::changed, this, &SKGColorButton::changed);
}
SKGColorButton::~SKGColorButton()
= default;
QString SKGColorButton::text() const
{
return m_text;
}
void SKGColorButton::setText(const QString& iText)
{
m_text = iText;
ui.label->setText(iText);
}
QColor SKGColorButton::color() const
{
return ui.button->color();
}
void SKGColorButton::setColor(const QColor& iColor)
{
ui.button->setColor(iColor);
}
QColor SKGColorButton::defaultColor() const
{
return ui.button->defaultColor();
}
void SKGColorButton::setDefaultColor(const QColor& iColor)
{
ui.button->setDefaultColor(iColor);
}
diff --git a/skgbasegui/skgcolorbutton.h b/skgbasegui/skgcolorbutton.h
index 4cbf7e240..518cb256d 100644
--- a/skgbasegui/skgcolorbutton.h
+++ b/skgbasegui/skgcolorbutton.h
@@ -1,108 +1,108 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGCOLORBUTTON_H
#define SKGCOLORBUTTON_H
/** @file
* A color button with more features.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgbasegui_export.h"
#include "ui_skgcolorbutton.h"
/**
* This file is a color selector box with more features.
*/
class SKGBASEGUI_EXPORT SKGColorButton : public QWidget
{
Q_OBJECT
/**
* Text of the color selector
*/
Q_PROPERTY(QString text READ text WRITE setText NOTIFY changed USER true)
/**
* Color of the color selector
*/
Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY changed)
/**
* Default color of the color selector
*/
Q_PROPERTY(QColor defaultColor READ defaultColor WRITE setDefaultColor NOTIFY changed)
public:
/**
* Default Constructor
* @param iParent the parent
*/
explicit SKGColorButton(QWidget* iParent);
/**
* Default Destructor
*/
~SKGColorButton() override;
/**
* Get the text for the color selector
* @return the text
*/
virtual QString text() const;
/**
* Set the text for the color selector
* @param iText the text
*/
virtual void setText(const QString& iText);
/**
* Get the color for the color selector
* @return the text
*/
virtual QColor color() const;
/**
* Set the color for the color selector
* @param iColor the color
*/
virtual void setColor(const QColor& iColor);
/**
* Get the default color for the color selector
* @return the text
*/
virtual QColor defaultColor() const;
/**
* Set the default color for the color selector
* @param iColor the color
*/
virtual void setDefaultColor(const QColor& iColor);
Q_SIGNALS:
/**
* Emitted when the color is changed
* @param iColor the color
*/
void changed(const QColor& iColor);
private:
Ui::skgcolorbutton_base ui{};
QString m_text{};
};
#endif // SKGCOLORBUTTON_H
diff --git a/skgbasegui/skgcombobox.cpp b/skgbasegui/skgcombobox.cpp
index eecc101bc..211a35def 100644
--- a/skgbasegui/skgcombobox.cpp
+++ b/skgbasegui/skgcombobox.cpp
@@ -1,54 +1,54 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* A combo box with more features.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgcombobox.h"
#include <qlineedit.h>
SKGComboBox::SKGComboBox(QWidget* iParent)
: KComboBox(iParent)
{
}
SKGComboBox::~SKGComboBox()
= default;
QString SKGComboBox::text() const
{
return currentText();
}
void SKGComboBox::setText(const QString& iText)
{
int pos2 = findText(iText);
if (pos2 == -1) {
pos2 = 0;
insertItem(pos2, iText);
}
setCurrentIndex(pos2);
}
void SKGComboBox::setPalette(const QPalette& iPalette)
{
KComboBox::setPalette(iPalette);
lineEdit()->setPalette(iPalette);
}
diff --git a/skgbasegui/skgcombobox.h b/skgbasegui/skgcombobox.h
index cc5e2ee3d..81f644e59 100644
--- a/skgbasegui/skgcombobox.h
+++ b/skgbasegui/skgcombobox.h
@@ -1,72 +1,72 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGCOMBOBOX_H
#define SKGCOMBOBOX_H
/** @file
* A combo box with more features.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgbasegui_export.h"
#include <kcombobox.h>
/**
* This file is a combo box with more features.
*/
class SKGBASEGUI_EXPORT SKGComboBox : public KComboBox
{
Q_OBJECT
/**
* Text of the combobox
*/
Q_PROPERTY(QString text READ text WRITE setText USER true) // clazy:exclude=qproperty-without-notify
public:
/**
* Default Constructor
* @param iParent the parent
*/
explicit SKGComboBox(QWidget* iParent = nullptr);
/**
* Default Destructor
*/
~SKGComboBox() override;
/**
* Get the text for the combo
* @return the text
*/
virtual QString text() const;
/**
* Set the text for the combo
* @param iText the text
*/
virtual void setText(const QString& iText);
/**
* Set the Palette for the combobox.
* Reimplemented since the base method does
* not apply the Palette to the underlying
* QlineEdit
* @param iPalette the new palette
*/
virtual void setPalette(const QPalette& iPalette);
};
#endif // SKGCOMBOBOX_H
diff --git a/skgbasegui/skgdateedit.cpp b/skgbasegui/skgdateedit.cpp
index ba337cfb7..4257bd456 100644
--- a/skgbasegui/skgdateedit.cpp
+++ b/skgbasegui/skgdateedit.cpp
@@ -1,57 +1,57 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* A date editor with more features.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgdateedit.h"
#include <kdatevalidator.h>
#include <qlineedit.h>
#include <klocalizedstring.h>
SKGDateEdit::SKGDateEdit(QWidget* iParent, const char* name)
: KPIM::KDateEdit(iParent), m_mode(CURRENT)
{
setObjectName(name);
setMode(CURRENT);
setToolTip(i18n("Date of the operation\nup or down to add or remove one day\nCTRL + up or CTRL + down to add or remove one month"));
}
SKGDateEdit::~SKGDateEdit()
= default;
SKGDateEdit::Mode SKGDateEdit::mode() const
{
return m_mode;
}
void SKGDateEdit::setMode(Mode iMode)
{
if (iMode != m_mode) {
m_mode = iMode;
auto* val = qobject_cast<KPIM::KDateValidator*>(const_cast<QValidator*>(validator()));
val->setFixupBehavior(m_mode == CURRENT ? KPIM::KDateValidator::FixupCurrent : m_mode == NEXT ? KPIM::KDateValidator::FixupForward : KPIM::KDateValidator::FixupBackward);
emit modeChanged();
}
}
diff --git a/skgbasegui/skgdateedit.h b/skgbasegui/skgdateedit.h
index dd8826f5d..99f440369 100644
--- a/skgbasegui/skgdateedit.h
+++ b/skgbasegui/skgdateedit.h
@@ -1,85 +1,85 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGDATEEDIT_H
#define SKGDATEEDIT_H
/** @file
* A date edit with more features.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "kdateedit.h"
#include "skgbasegui_export.h"
/**
* This file is a tab widget used by plugins
* based on KDateEdit of PIM
*/
class SKGBASEGUI_EXPORT SKGDateEdit : public KPIM::KDateEdit
{
Q_OBJECT
/**
* Mode of the editor
*/
Q_PROPERTY(SKGDateEdit::Mode mode READ mode WRITE setMode NOTIFY modeChanged)
public:
/**
* Mode of the editor
*/
enum Mode {PREVIOUS, /**< if date is incompleted, the previous one is selected */
CURRENT, /**< if date is incomplete, the current month is selected */
NEXT /**< if date is incomplete, the next one is selected */
};
/**
* Mode of the editor
*/
Q_ENUM(Mode)
/**
* Constructor
* @param iParent the parent
* @param name name
*/
explicit SKGDateEdit(QWidget* iParent, const char* name = nullptr);
/**
* Destructor
*/
~SKGDateEdit() override;
/**
* Get the mode
* @return the mode
*/
Mode mode() const;
/**
* Set the mode
* @param iMode the mode
*/
void setMode(Mode iMode);
Q_SIGNALS:
/**
* Emitted when the mode changed
*/
void modeChanged();
private:
Mode m_mode;
};
#endif
diff --git a/skgbasegui/skgfilteredtableview.cpp b/skgbasegui/skgfilteredtableview.cpp
index 13fc0fd57..1ab8ff8f5 100644
--- a/skgbasegui/skgfilteredtableview.cpp
+++ b/skgbasegui/skgfilteredtableview.cpp
@@ -1,246 +1,246 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* filetered SKGTableView.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgfilteredtableview.h"
#include <qdom.h>
#include <qlineedit.h>
#include "skgmainpanel.h"
#include "skgobjectmodelbase.h"
#include "skgsortfilterproxymodel.h"
SKGFilteredTableView::SKGFilteredTableView(QWidget* iParent)
: QWidget(iParent), m_objectModel(nullptr), m_refreshNeeded(true)
{
ui.setupUi(this);
ui.kTitle->hide();
ui.kResetInternalFilter->hide();
connect(ui.kResetInternalFilter, &QToolButton::clicked, this, &SKGFilteredTableView::resetFilter);
ui.kResetInternalFilter->setIcon(SKGServices::fromTheme(QStringLiteral("dialog-cancel")));
ui.kConfigure->setIcon(SKGServices::fromTheme(QStringLiteral("configure")));
ui.kConfigure->setPopupMode(QToolButton::InstantPopup);
ui.kConfigure->setAutoRaise(true);
ui.kConfigure->setMenu(ui.kView->getHeaderMenu());
m_timer.setSingleShot(true);
connect(&m_timer, &QTimer::timeout, this, &SKGFilteredTableView::onTextFilterChanged, Qt::QueuedConnection);
connect(ui.kFilterEdit, &QLineEdit::textChanged, this, [ = ]() {
m_timer.start(300);
});
connect(ui.kShow, &SKGShow::stateChanged, this, &SKGFilteredTableView::onFilterChanged, Qt::QueuedConnection);
if (SKGMainPanel::getMainPanel() != nullptr) {
connect(SKGMainPanel::getMainPanel(), &SKGMainPanel::currentPageChanged, this, &SKGFilteredTableView::pageChanged, Qt::QueuedConnection);
}
}
SKGFilteredTableView::~SKGFilteredTableView()
{
m_objectModel = nullptr;
}
QString SKGFilteredTableView::getState()
{
QDomDocument doc(QStringLiteral("SKGML"));
QDomElement root = doc.createElement(QStringLiteral("parameters"));
doc.appendChild(root);
root.setAttribute(QStringLiteral("show"), ui.kShow->getState());
root.setAttribute(QStringLiteral("filter"), getSearchField()->text());
// Memorize table settings
root.setAttribute(QStringLiteral("view"), ui.kView->getState());
return doc.toString();
}
void SKGFilteredTableView::setState(const QString& iState)
{
QDomDocument doc(QStringLiteral("SKGML"));
doc.setContent(iState);
QDomElement root = doc.documentElement();
QString show2 = root.attribute(QStringLiteral("show"));
QString filter = root.attribute(QStringLiteral("filter"));
if (!show2.isEmpty()) {
ui.kShow->setState(show2);
}
getSearchField()->setText(filter);
if (m_objectModel != nullptr) {
bool previous = m_objectModel->blockRefresh(true);
onFilterChanged();
m_objectModel->blockRefresh(previous);
}
// !!! Must be done here after onFilterChanged
ui.kView->setState(root.attribute(QStringLiteral("view")));
}
SKGShow* SKGFilteredTableView::getShowWidget() const
{
return ui.kShow;
}
SKGTreeView* SKGFilteredTableView::getView() const
{
return ui.kView;
}
QLineEdit* SKGFilteredTableView::getSearchField() const
{
return ui.kFilterEdit;
}
void SKGFilteredTableView::onFilterChanged()
{
QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
// Update model
if ((m_objectModel != nullptr) && ui.kShow->isEnabled() && m_objectModel->setFilter(ui.kShow->getWhereClause())) {
m_objectModel->dataModified();
}
QApplication::restoreOverrideCursor();
}
void SKGFilteredTableView::pageChanged()
{
if (m_refreshNeeded) {
dataModified(QLatin1String(""), 0);
}
}
void SKGFilteredTableView::dataModified(const QString& iTableName, int iIdTransaction)
{
Q_UNUSED(iIdTransaction)
if (((m_objectModel != nullptr) && iTableName == m_objectModel->getTable()) || iTableName.isEmpty()) {
SKGTabPage* page = SKGTabPage::parentTabPage(this);
if (page != nullptr && SKGMainPanel::getMainPanel() != nullptr && page != SKGMainPanel::getMainPanel()->currentPage()) {
m_refreshNeeded = true;
return;
}
m_refreshNeeded = false;
if (getView()->isAutoResized()) {
getView()->resizeColumnsToContentsDelayed();
}
getView()->onSelectionChanged();
}
}
void SKGFilteredTableView::setModel(SKGObjectModelBase* iModel)
{
m_objectModel = iModel;
if (m_objectModel != nullptr) {
auto modelProxy = new SKGSortFilterProxyModel(this);
modelProxy->setSourceModel(m_objectModel);
modelProxy->setSortRole(Qt::UserRole);
modelProxy->setDynamicSortFilter(true);
connect(modelProxy, &SKGSortFilterProxyModel::rowsInserted, ui.kView, &SKGTreeView::scroolOnSelection);
ui.kView->setModel(modelProxy);
onTextFilterChanged();
ui.kView->sortByColumn(0, Qt::AscendingOrder);
connect(m_objectModel, &SKGObjectModelBase::beforeReset, ui.kView, &SKGTreeView::saveSelection);
connect(m_objectModel, &SKGObjectModelBase::afterReset, ui.kView, &SKGTreeView::resetSelection);
connect(m_objectModel->getDocument(), &SKGDocument::tableModified, this, &SKGFilteredTableView::dataModified, Qt::QueuedConnection);
}
dataModified(QLatin1String(""), 0);
}
void SKGFilteredTableView::resetFilter()
{
getShowWidget()->setEnabled(true);
ui.kTitle->hide();
ui.kResetInternalFilter->hide();
m_objectModel->setFilter(QLatin1String(""));
m_objectModel->refresh();
}
void SKGFilteredTableView::setFilter(const QIcon& iIcon, const QString& iText, const QString& iWhereClause)
{
if ((m_objectModel != nullptr) && !iWhereClause.isEmpty()) {
getShowWidget()->setEnabled(false);
QFontMetrics fm(fontMetrics());
ui.kTitle->setComment("<html><body><b>" % SKGServices::stringToHtml(fm.elidedText(iText, Qt::ElideMiddle, 2000)) % "</b></body></html>");
ui.kTitle->setToolTip(iText);
ui.kResetInternalFilter->show();
ui.kTitle->setPixmap(iIcon.pixmap(22, 22), KTitleWidget::ImageLeft);
m_objectModel->setFilter(iWhereClause);
m_objectModel->refresh();
}
}
void SKGFilteredTableView::onTextFilterChanged()
{
auto filter = ui.kFilterEdit->text();
auto modelProxy = qobject_cast<SKGSortFilterProxyModel*>(ui.kView->model());
if (modelProxy != nullptr) {
modelProxy->setFilterKeyColumn(-1);
modelProxy->setFilterCaseSensitivity(Qt::CaseInsensitive);
modelProxy->setFilterFixedString(filter);
QStringList attributes;
QAbstractItemModel* model = modelProxy->sourceModel();
if (model != nullptr) {
int nbcol = model->columnCount();
attributes.reserve(nbcol);
for (int j = 0; j < nbcol; ++j) {
attributes.append(model->headerData(j, Qt::Horizontal).toString());
}
}
auto tooltip = i18nc("Tooltip", "<html><head/><body><p>Searching is case-insensitive. So table, Table, and TABLE are all the same.<br/>"
"If you just put a word or series of words in the search box, the application will filter the table to keep all lines having these words (logical operator AND). <br/>"
"If you want to add (logical operator OR) some lines, you must prefix your word by '+'.<br/>"
"If you want to remove (logical operator NOT) some lines, you must prefix your word by '-'.<br/>"
"If you want to search only on some columns, you must prefix your word by the beginning of column name like: col1:word.<br/>"
"If you want to search only on one column, you must prefix your word by the column name and a dot like: col1.:word.<br/>"
"If you want to use the character ':' in value, you must specify the column name like this: col1:value:rest.<br/>"
"If you want to search for a phrase or something that contains spaces, you must put it in quotes, like: 'yes, this is a phrase'.</p>"
"<p>You can also use operators '&lt;', '&gt;', '&lt;=', '&gt;=', '=' and '#' (for regular expression).</p>"
"<p><span style=\"font-weight:600; text-decoration: underline;\">Examples:</span><br/>"
"+val1 +val2 =&gt; Keep lines containing val1 OR val2<br/>"
"+val1 -val2 =&gt; Keep lines containing val1 but NOT val2<br/>"
"'abc def' =&gt; Keep lines containing the sentence 'abc def' <br/>"
"'-att:abc def' =&gt; Remove lines having a column name starting by abc and containing 'abc def' <br/>"
"abc:def =&gt; Keep lines having a column name starting by abc and containing def<br/>"
":abc:def =&gt; Keep lines containing 'abc:def'<br/>"
"Date&gt;2015-03-01 =&gt; Keep lines where at least one attribute starting by Date is greater than 2015-03-01<br/>"
"Date.&gt;2015-03-01 =&gt; Keep lines where at the Date attribute is greater than 2015-03-01<br/>"
"Amount&lt;10 =&gt;Keep lines where at least one attribute starting by Amount is less than 10<br/>"
"Amount=10 =&gt;Keep lines where at least one attribute starting by Amount is equal to 10<br/>"
"Amount&lt;=10 =&gt;Keep lines where at least one attribute starting by Amount is less or equal to 10<br/>"
"abc#^d.*f$ =&gt; Keep lines having a column name starting by abc and matching the regular expression ^d.*f$</p>"
"<span style=\"font-weight:600; text-decoration: underline;\">Your filter is understood like this:</span><br/>"
"%1</body></html>", SKGServices::searchCriteriasToWhereClause(SKGServices::stringToSearchCriterias(filter), attributes, m_objectModel->getDocument(), true));
ui.kFilterEdit->setToolTip(tooltip);
}
}
diff --git a/skgbasegui/skgfilteredtableview.h b/skgbasegui/skgfilteredtableview.h
index 78aa2667e..21808f0e9 100644
--- a/skgbasegui/skgfilteredtableview.h
+++ b/skgbasegui/skgfilteredtableview.h
@@ -1,125 +1,125 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGFILTEREDTABLEVIEW_H
#define SKGFILTEREDTABLEVIEW_H
/** @file
* A filetered SKGTableView.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include <qtimer.h>
#include <qwidget.h>
#include "skgbasegui_export.h"
#include "ui_skgfilteredtableview.h"
class SKGShow;
class SKGObjectModelBase;
/**
* This file is a filetered SKGTableView
*/
class SKGBASEGUI_EXPORT SKGFilteredTableView : public QWidget
{
Q_OBJECT
public:
/**
* Default Constructor
* @param iParent the parent
*/
explicit SKGFilteredTableView(QWidget* iParent);
/**
* Default Destructor
*/
~SKGFilteredTableView() override;
/**
* Get the current state
* @return a string containing all activated item identifiers (separated by ;)
*/
virtual QString getState();
/**
* Set the current state
* @param iState a string containing all activated item identifiers (separated by ;)
*/
virtual void setState(const QString& iState);
/**
* @brief Get show widget
*
* @return SKGShow
**/
virtual SKGShow* getShowWidget() const;
/**
* @brief Get table or tree view
*
* @return SKGTreeView
**/
virtual SKGTreeView* getView() const;
/**
* @brief Get the search field
*
* @return QLineEdit
**/
virtual QLineEdit* getSearchField() const;
/**
* @brief Set model
*
* @param iModel the model
* @return void
**/
virtual void setModel(SKGObjectModelBase* iModel);
public Q_SLOTS:
/**
* @brief Set the filter. This filter disable the "show" menu
*
* @param iIcon the icon
* @param iText the text to display
* @param iWhereClause the where clause
* @return void
**/
virtual void setFilter(const QIcon& iIcon, const QString& iText, const QString& iWhereClause);
/**
* @brief Reset the filter
* @return void
**/
virtual void resetFilter();
private Q_SLOTS:
void pageChanged();
void onFilterChanged();
void onTextFilterChanged();
void dataModified(const QString& iTableName, int iIdTransaction);
private:
Q_DISABLE_COPY(SKGFilteredTableView)
Ui::skgfilteredtableview_base ui{};
SKGObjectModelBase* m_objectModel;
bool m_refreshNeeded;
QTimer m_timer;
};
#endif // SKGFILTEREDTABLEVIEW_H
diff --git a/skgbasegui/skgflowlayout.cpp b/skgbasegui/skgflowlayout.cpp
index 285e1628b..2e8d6e0de 100644
--- a/skgbasegui/skgflowlayout.cpp
+++ b/skgbasegui/skgflowlayout.cpp
@@ -1,211 +1,211 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file defines classes SKGFlowLayout.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgflowlayout.h"
#include "skgdefine.h"
#include <qlayout.h>
#include <qwidget.h>
SKGFlowLayout::SKGFlowLayout(QWidget* iParent, int iMargin, int hSpacing, int vSpacing)
: QLayout(iParent), m_hSpace(hSpacing), m_vSpace(vSpacing)
{
setContentsMargins(iMargin, iMargin, iMargin, iMargin);
}
SKGFlowLayout::SKGFlowLayout(int iMargin, int hSpacing, int vSpacing)
: m_hSpace(hSpacing), m_vSpace(vSpacing)
{
setContentsMargins(iMargin, iMargin, iMargin, iMargin);
}
SKGFlowLayout::~SKGFlowLayout()
{
while (count() != 0) {
QLayoutItem* child = takeAt(0);
if (child != nullptr) {
QWidget* w = child->widget();
delete w;
delete child;
}
}
}
void SKGFlowLayout::addItem(QLayoutItem* item)
{
m_itemList.append(item);
}
void SKGFlowLayout::setSpacing(int space)
{
m_hSpace = space;
m_vSpace = space;
}
int SKGFlowLayout::horizontalSpacing() const
{
if (m_hSpace >= 0) {
return m_hSpace;
}
return smartSpacing(QStyle::PM_LayoutHorizontalSpacing);
}
int SKGFlowLayout::verticalSpacing() const
{
if (m_vSpace >= 0) {
return m_vSpace;
}
return smartSpacing(QStyle::PM_LayoutVerticalSpacing);
}
int SKGFlowLayout::count() const
{
return m_itemList.size();
}
QLayoutItem* SKGFlowLayout::itemAt(int index) const
{
return m_itemList.value(index);
}
QLayoutItem* SKGFlowLayout::takeAt(int index)
{
if (index >= 0 && index < m_itemList.size()) {
return m_itemList.takeAt(index);
}
return nullptr;
}
Qt::Orientations SKGFlowLayout::expandingDirections() const
{
return nullptr;
}
bool SKGFlowLayout::hasHeightForWidth() const
{
return true;
}
int SKGFlowLayout::heightForWidth(int width) const
{
int height = doLayout(QRect(0, 0, width, 0), true);
return height;
}
void SKGFlowLayout::setGeometry(const QRect& rect) // clazy:exclude=function-args-by-value
{
QLayout::setGeometry(rect);
doLayout(rect, false);
}
QSize SKGFlowLayout::sizeHint() const
{
return minimumSize();
}
QSize SKGFlowLayout::minimumSize() const
{
QSize size;
for (auto item : qAsConst(m_itemList)) {
size = size.expandedTo(item->minimumSize());
}
size += QSize(2 * margin(), 2 * margin());
return size;
}
int SKGFlowLayout::doLayout(const QRect rect, bool testOnly) const
{
int left, top, right, bottom;
getContentsMargins(&left, &top, &right, &bottom);
QRect effectiveRect = rect.adjusted(+left, +top, -right, -bottom);
int x = effectiveRect.x();
int y = effectiveRect.y();
int lineHeight = 0;
int x1 = x;
int y1 = y;
for (auto item : qAsConst(m_itemList)) {
QWidget* wid = item->widget();
if (wid != nullptr) {
// Get spaces
int spaceX = horizontalSpacing();
if (spaceX == -1) {
spaceX = wid->style()->layoutSpacing(QSizePolicy::PushButton, QSizePolicy::PushButton, Qt::Horizontal);
}
int spaceY = verticalSpacing();
if (spaceY == -1) {
spaceY = wid->style()->layoutSpacing(QSizePolicy::PushButton, QSizePolicy::PushButton, Qt::Vertical);
}
// Try option
bool optionUsed = false;
if ((lineHeight != 0) && (x1 != 0)) {
int nextX = x1 + item->sizeHint().width() + spaceX;
if (nextX <= x && y1 - y + item->sizeHint().height() <= lineHeight) {
optionUsed = true;
// Position item
if (!testOnly) {
item->setGeometry(QRect(QPoint(x1, y1), item->sizeHint()));
}
x1 = nextX;
}
}
if (!optionUsed) {
int nextX = x + item->sizeHint().width() + spaceX;
if (nextX - spaceX > effectiveRect.right() && lineHeight > 0) {
x = effectiveRect.x();
y = y + lineHeight + spaceY;
nextX = x + item->sizeHint().width() + spaceX;
lineHeight = 0;
}
// Position item
if (!testOnly) {
item->setGeometry(QRect(QPoint(x, y), item->sizeHint()));
}
x1 = x;
y1 = y + item->sizeHint().height() + spaceY;
x = nextX;
lineHeight = qMax(lineHeight, item->sizeHint().height());
}
}
}
return y + lineHeight - rect.y() + bottom;
}
int SKGFlowLayout::smartSpacing(QStyle::PixelMetric pm) const
{
QObject* p = this->parent();
if (p == nullptr) {
return -1;
}
if (p->isWidgetType()) {
auto* pw = qobject_cast<QWidget*>(p);
return pw->style()->pixelMetric(pm, nullptr, pw);
}
return qobject_cast<QLayout*>(p)->spacing();
}
diff --git a/skgbasegui/skgflowlayout.h b/skgbasegui/skgflowlayout.h
index c74a0d3e6..2d61bc534 100644
--- a/skgbasegui/skgflowlayout.h
+++ b/skgbasegui/skgflowlayout.h
@@ -1,153 +1,153 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGFLOWLAYOUT_H
#define SKGFLOWLAYOUT_H
/** @file
* This file defines classes SKGFlowLayout.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include <qlayout.h>
#include <qstyle.h>
#include "skgbasegui_export.h"
/**
* This file is a flow layout
*/
class SKGBASEGUI_EXPORT SKGFlowLayout : public QLayout
{
Q_OBJECT
public:
/**
* Constructor
* @param iParent the parent
* @param iMargin margin
* @param hSpacing horizontal spacing
* @param vSpacing vertical spacing
*/
explicit SKGFlowLayout(QWidget* iParent, int iMargin = -1, int hSpacing = -1, int vSpacing = -1);
/**
* Constructor
* @param iMargin margin
* @param hSpacing horizontal spacing
* @param vSpacing vertical spacing
*/
explicit SKGFlowLayout(int iMargin = -1, int hSpacing = -1, int vSpacing = -1);
/**
* Default Destructor
*/
~SKGFlowLayout() override;
/**
* Add an item
* @param item the item to add
*/
void addItem(QLayoutItem* item) override;
/**
* Set horizontal and vertical spacing
* @param space the space
*/
virtual void setSpacing(int space);
/**
* Get horizontal spacing
* @return horizontal spacing
*/
virtual int horizontalSpacing() const;
/**
* Get vertical spacing
* @return vertical spacing
*/
virtual int verticalSpacing() const;
/**
* Get expanding directions
* @return expanding directions
*/
Qt::Orientations expandingDirections() const override;
/**
* Returns true if this layout's preferred height depends on its width; otherwise returns false.
* The default implementation returns false.
* Reimplement this function in layout managers that support height for width.
* @return true of false
*/
bool hasHeightForWidth() const override;
/**
* Returns the preferred height for this layout item, given the width w.
* The default implementation returns -1, indicating that the preferred height is independent of the width of the item. Using the function hasHeightForWidth() will typically be much faster than calling this function and testing for -1.
* Reimplement this function in layout managers that support height for width
* @return height
*/
int heightForWidth(int /*width*/ /*unused*/) const override;
/**
* Returns the number of items
* @return number of items
*/
int count() const override;
/**
* Returns the item for an index
* @param index the index
* @return the item
*/
QLayoutItem* itemAt(int index) const override;
/**
* Returns the minimum size
* @return the minimum size
*/
QSize minimumSize() const override;
/**
* Set the geometry
* @param rect the geometry
*/
void setGeometry(const QRect& rect) override;
/**
* Returns the preferred size
* @return the preferred size
*/
QSize sizeHint() const override;
/**
* Takes the item for an index
* @param index the index
* @return the item
*/
QLayoutItem* takeAt(int index) override;
private:
int doLayout(QRect rect, bool testOnly) const;
int smartSpacing(QStyle::PixelMetric pm) const;
QList<QLayoutItem*> m_itemList;
int m_hSpace;
int m_vSpace;
};
#endif
diff --git a/skgbasegui/skggraphicsscene.cpp b/skgbasegui/skggraphicsscene.cpp
index 54173a1f3..72a491254 100644
--- a/skgbasegui/skggraphicsscene.cpp
+++ b/skgbasegui/skggraphicsscene.cpp
@@ -1,39 +1,39 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file defines classes SKGGraphicsScene.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skggraphicsscene.h"
SKGGraphicsScene::SKGGraphicsScene(QObject* iParent)
: QGraphicsScene(iParent)
{
}
SKGGraphicsScene::~SKGGraphicsScene()
= default;
void SKGGraphicsScene::mouseDoubleClickEvent(QGraphicsSceneMouseEvent* mouseEvent)
{
Q_EMIT doubleClicked();
QGraphicsScene::mouseDoubleClickEvent(mouseEvent);
}
diff --git a/skgbasegui/skggraphicsscene.h b/skgbasegui/skggraphicsscene.h
index f8e269320..39f5ed9d0 100644
--- a/skgbasegui/skggraphicsscene.h
+++ b/skgbasegui/skggraphicsscene.h
@@ -1,63 +1,63 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGGRAPHICSSCENE_H
#define SKGGRAPHICSSCENE_H
/** @file
* This file defines a graphic scene with more features.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgbasegui_export.h"
#include <qgraphicsscene.h>
/**
* A graphic scene with more features
*/
class SKGBASEGUI_EXPORT SKGGraphicsScene : public QGraphicsScene
{
Q_OBJECT
public:
/**
* Default constructor
* @param iParent the parent
*/
explicit SKGGraphicsScene(QObject* iParent = nullptr);
/**
* Destructor
*/
~SKGGraphicsScene() override;
Q_SIGNALS:
/**
* This signal is launched when a double click is done
*/
void doubleClicked();
protected:
/**
* This event handler, for event mouseEvent, can be reimplemented in a subclass to receive mouse doubleclick events for the scene.
* @param mouseEvent the event
*/
void mouseDoubleClickEvent(QGraphicsSceneMouseEvent* mouseEvent) override;
private:
Q_DISABLE_COPY(SKGGraphicsScene)
};
#endif
diff --git a/skgbasegui/skggraphicsview.cpp b/skgbasegui/skggraphicsview.cpp
index 9d22c3f1a..0d070e7a3 100644
--- a/skgbasegui/skggraphicsview.cpp
+++ b/skgbasegui/skggraphicsview.cpp
@@ -1,308 +1,308 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* A Graphic view with more functionalities.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skggraphicsview.h"
#include <qapplication.h>
#include <qclipboard.h>
#include <qdesktopservices.h>
#include <qdom.h>
#include <qfileinfo.h>
#include <qgraphicssceneevent.h>
#include <qheaderview.h>
#include <qmath.h>
#include <qmenu.h>
#include <qprintdialog.h>
#include <qprinter.h>
#include <qsvggenerator.h>
#include <qwidgetaction.h>
#include "skgmainpanel.h"
#include "skgservices.h"
#include "skgtraces.h"
SKGGraphicsView::SKGGraphicsView(QWidget* iParent)
: QWidget(iParent), m_oscale(1), m_toolBarVisible(true)
{
ui.setupUi(this);
setAntialiasing(true);
ui.kGraphicsView->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
ui.kGraphicsView->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
graphicsView()->installEventFilter(this);
// Set icons
ui.kPrint->setIcon(SKGServices::fromTheme(QStringLiteral("printer")));
ui.kCopy->setIcon(SKGServices::fromTheme(QStringLiteral("edit-copy")));
// Build contextual menu
graphicsView()->setContextMenuPolicy(Qt::CustomContextMenu);
m_mainMenu = new QMenu(graphicsView());
// Zoom in menu
auto zoomMenu = new SKGZoomSelector(this);
zoomMenu->setResetValue(ui.kZoom->resetValue());
zoomMenu->setValue(ui.kZoom->value());
auto zoomWidget = new QWidgetAction(this);
zoomWidget->setDefaultWidget(zoomMenu);
m_mainMenu->addAction(zoomWidget);
connect(zoomMenu, &SKGZoomSelector::changed, this, [ = ](int val) {
ui.kZoom->setValue(val);
});
connect(ui.kZoom, &SKGZoomSelector::changed, this, [ = ](int val) {
zoomMenu->setValue(val);
});
m_actShowToolBar = m_mainMenu->addAction(SKGServices::fromTheme(QStringLiteral("show-menu")), i18nc("Noun, user action", "Show tool bar"));
if (m_actShowToolBar != nullptr) {
m_actShowToolBar->setCheckable(true);
m_actShowToolBar->setChecked(true);
connect(m_actShowToolBar, &QAction::triggered, this, &SKGGraphicsView::onSwitchToolBarVisibility);
}
m_mainMenu->addSeparator();
QAction* actCopy = m_mainMenu->addAction(ui.kCopy->icon(), ui.kCopy->toolTip());
connect(actCopy, &QAction::triggered, this, &SKGGraphicsView::onCopy);
QAction* actPrint = m_mainMenu->addAction(ui.kPrint->icon(), ui.kPrint->toolTip());
connect(actPrint, &QAction::triggered, this, &SKGGraphicsView::onPrint);
QAction* actExport = m_mainMenu->addAction(SKGServices::fromTheme(QStringLiteral("document-export")), i18nc("Noun, user action", "Export..."));
connect(actExport, &QAction::triggered, this, &SKGGraphicsView::onExport);
connect(graphicsView(), &QHeaderView::customContextMenuRequested, this, &SKGGraphicsView::showMenu);
connect(ui.kPrint, &QToolButton::clicked, this, &SKGGraphicsView::onPrint);
connect(ui.kCopy, &QToolButton::clicked, this, &SKGGraphicsView::onCopy);
connect(ui.kZoom, &SKGZoomSelector::changed, this, &SKGGraphicsView::onZoom);
// Timer to refresh
m_timer.setSingleShot(true);
connect(&m_timer, &QTimer::timeout, ui.kZoom, &SKGZoomSelector::initializeZoom, Qt::QueuedConnection);
}
SKGGraphicsView::~SKGGraphicsView()
{
m_actShowToolBar = nullptr;
m_actZoomOriginal = nullptr;
m_mainMenu = nullptr;
m_actAntialiasing = nullptr;
}
void SKGGraphicsView::setScene(QGraphicsScene* iScene)
{
graphicsView()->setScene(iScene);
if (iScene != nullptr) {
iScene->installEventFilter(this);
}
onZoom();
}
QGraphicsView* SKGGraphicsView::graphicsView()
{
return ui.kGraphicsView;
}
QString SKGGraphicsView::getState() const
{
SKGTRACEINFUNC(10)
QDomDocument doc(QStringLiteral("SKGML"));
QDomElement root = doc.createElement(QStringLiteral("parameters"));
doc.appendChild(root);
root.setAttribute(QStringLiteral("isToolBarVisible"), isToolBarVisible() ? QStringLiteral("Y") : QStringLiteral("N"));
return doc.toString();
}
void SKGGraphicsView::setState(const QString& iState)
{
SKGTRACEINFUNC(10)
QDomDocument doc(QStringLiteral("SKGML"));
doc.setContent(iState);
QDomElement root = doc.documentElement();
setToolBarVisible(root.attribute(QStringLiteral("isToolBarVisible")) != QStringLiteral("N"));
}
QMenu* SKGGraphicsView::getContextualMenu() const
{
return m_mainMenu;
}
void SKGGraphicsView::showMenu(const QPoint iPos)
{
if (m_mainMenu != nullptr) {
m_mainMenu->popup(graphicsView()->mapToGlobal(iPos));
}
}
void SKGGraphicsView::setToolBarVisible(bool iVisibility)
{
if (m_toolBarVisible != iVisibility) {
m_toolBarVisible = iVisibility;
ui.toolBar->setVisible(m_toolBarVisible);
if (m_actShowToolBar != nullptr) {
m_actShowToolBar->setChecked(m_toolBarVisible);
}
Q_EMIT toolBarVisiblyChanged();
}
}
bool SKGGraphicsView::isToolBarVisible() const
{
return m_toolBarVisible;
}
void SKGGraphicsView::addToolbarWidget(QWidget* iWidget)
{
ui.layout->insertWidget(3, iWidget);
}
void SKGGraphicsView::onSwitchToolBarVisibility()
{
setToolBarVisible(!isToolBarVisible());
}
void SKGGraphicsView::setAntialiasing(bool iAntialiasing)
{
graphicsView()->setRenderHint(QPainter::Antialiasing, iAntialiasing);
}
bool SKGGraphicsView::eventFilter(QObject* iObject, QEvent* iEvent)
{
if (iObject == graphicsView()->scene() && (iEvent != nullptr) && iEvent->type() == QEvent::GraphicsSceneWheel) {
auto* e = dynamic_cast<QGraphicsSceneWheelEvent*>(iEvent);
if ((e != nullptr) && e->orientation() == Qt::Vertical && ((QApplication::keyboardModifiers() &Qt::ControlModifier) != 0u)) {
int numDegrees = e->delta() / 8;
int numTicks = numDegrees / 15;
if (numTicks > 0) {
ui.kZoom->zoomIn();
} else {
ui.kZoom->zoomOut();
}
e->setAccepted(true);
return true;
}
} else if (iObject == graphicsView() && (iEvent != nullptr) && iEvent->type() == QEvent::Resize) {
Q_EMIT resized();
if (ui.kZoom->value() == ui.kZoom->resetValue()) {
m_timer.start(300);
}
}
return QWidget::eventFilter(iObject, iEvent);
}
void SKGGraphicsView::initializeZoom()
{
ui.kZoom->initializeZoom();
}
void SKGGraphicsView::onZoom()
{
_SKGTRACEINFUNC(10)
int sliderValue = ui.kZoom->value();
if (graphicsView()->scene() != nullptr) {
if (sliderValue == -10) {
graphicsView()->fitInView(graphicsView()->scene()->sceneRect(), Qt::KeepAspectRatio);
m_oscale = 1;
} else {
qreal scale = qPow(qreal(1.5), (sliderValue + 10.0) / qreal(4));
graphicsView()->scale(scale / m_oscale, scale / m_oscale);
m_oscale = scale;
}
}
}
void SKGGraphicsView::onPrint()
{
_SKGTRACEINFUNC(10)
QPrinter printer;
QPointer<QPrintDialog> dialog = new QPrintDialog(&printer, this);
if (dialog->exec() == QDialog::Accepted) {
QPainter painter(&printer);
graphicsView()->render(&painter);
painter.end();
}
}
void SKGGraphicsView::onExport()
{
_SKGTRACEINFUNC(10)
QString fileName = SKGMainPanel::getSaveFileName(QStringLiteral("kfiledialog:///IMPEXP"), QStringLiteral("application/pdf image/svg+xml image/png image/jpeg image/gif image/tiff"), this, nullptr);
if (fileName.isEmpty()) {
return;
}
exportInFile(fileName);
QDesktopServices::openUrl(QUrl(fileName));
}
void SKGGraphicsView::exportInFile(const QString& iFileName)
{
_SKGTRACEINFUNC(10)
QString extension = QFileInfo(iFileName).suffix().toUpper();
if (extension == QStringLiteral("PDF")) {
QPrinter printer;
printer.setOutputFileName(iFileName);
QPainter painter(&printer);
graphicsView()->render(&painter);
painter.end();
} else if (extension == QStringLiteral("SVG")) {
QSvgGenerator generator;
generator.setFileName(iFileName);
generator.setSize(QSize(200, 200));
generator.setViewBox(QRect(0, 0, 200, 200));
generator.setTitle(i18nc("Title of the content SVG export", "Skrooge SVG export"));
generator.setDescription(i18nc("Description of the content SVG export", "A SVG drawing created by the Skrooge."));
QPainter painter(&generator);
graphicsView()->render(&painter);
painter.end();
} else {
QImage image(graphicsView()->size(), QImage::Format_ARGB32);
QPainter painter(&image);
graphicsView()->render(&painter);
painter.end();
image.save(iFileName);
}
}
void SKGGraphicsView::onCopy()
{
_SKGTRACEINFUNC(10)
QClipboard* clipboard = QApplication::clipboard();
if (clipboard != nullptr) {
QImage image(graphicsView()->size(), QImage::Format_ARGB32);
QPainter painter(&image);
graphicsView()->render(&painter);
painter.end();
clipboard->setImage(image);
}
}
diff --git a/skgbasegui/skggraphicsview.h b/skgbasegui/skggraphicsview.h
index 2d3bccc43..198005ed3 100644
--- a/skgbasegui/skggraphicsview.h
+++ b/skgbasegui/skggraphicsview.h
@@ -1,186 +1,186 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGGRAPHICSVIEW_H
#define SKGGRAPHICSVIEW_H
/** @file
* A Graphic view with more functionalities.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include <qtimer.h>
#include <qwidget.h>
#include "skgbasegui_export.h"
#include "ui_skggraphicsview.h"
class QGraphicsScene;
class QGraphicsView;
class QMenu;
class QAction;
/**
* This file is a Graphic view with more functionalities
*/
class SKGBASEGUI_EXPORT SKGGraphicsView : public QWidget
{
Q_OBJECT
public:
/**
* Default Constructor
* @param iParent the parent
*/
explicit SKGGraphicsView(QWidget* iParent);
/**
* Default Destructor
*/
~SKGGraphicsView() override;
/**
* Set current scene
* @param iScene The scene
*/
void setScene(QGraphicsScene* iScene);
/**
* Get the internal Graphic view
* @return the internal Graphic view
*/
QGraphicsView* graphicsView();
/**
* Set the visibility of the ToolBar
* @param iVisibility visibility
*/
void setToolBarVisible(bool iVisibility);
/**
* Get the visibility of the ToolBar
* @return visibility
*/
bool isToolBarVisible() const;
/**
* Add a widget in the toolbar
* @param iWidget widget
*/
void addToolbarWidget(QWidget* iWidget);
/**
* Get the current state
* @return a string containing all information needed to set the same state.
* Could be an XML stream
*/
QString getState() const;
/**
* Set the current state
* MUST BE OVERWRITTEN
* @param iState must be interpreted to set the state of the widget
*/
void setState(const QString& iState);
/**
* Get a pointer on the contextual menu
* @return contextual menu
*/
QMenu* getContextualMenu() const;
public Q_SLOTS:
/**
* Set the zoom
*/
void onZoom();
/**
* Print
*/
void onPrint();
/**
* Export to a file
* @param iFileName the file name
*/
void exportInFile(const QString& iFileName);
/**
* Export
*/
void onExport();
/**
* Copy
*/
void onCopy();
/**
* Swith tool bar visibility
*/
void onSwitchToolBarVisibility();
/**
* Set antialiasing
* @param iAntialiasing enabled or disabled
*/
void setAntialiasing(bool iAntialiasing);
/**
* Reinitialize zoom
*/
void initializeZoom();
Q_SIGNALS:
/**
* View is resized
*/
void resized();
/**
* The tool bar visibily changed
*/
void toolBarVisiblyChanged();
protected:
/**
* Event filtering
* @param iObject object
* @param iEvent event
* @return In your reimplementation of this function, if you want to filter the event out, i.e. stop it being handled further, return true; otherwise return false.
*/
bool eventFilter(QObject* iObject, QEvent* iEvent) override;
private Q_SLOTS:
void showMenu(QPoint iPos);
private:
Q_DISABLE_COPY(SKGGraphicsView)
Ui::skggraphicview_base ui{};
double m_oscale;
QMenu* m_mainMenu{};
QAction* m_actZoomOriginal{};
QAction* m_actShowToolBar;
QAction* m_actAntialiasing{};
bool m_toolBarVisible;
QTimer m_timer;
};
#endif // SKGGRAPHICSVIEW_H
diff --git a/skgbasegui/skghtmlboardwidget.cpp b/skgbasegui/skghtmlboardwidget.cpp
index 288b84e6c..3bd6bd9d9 100644
--- a/skgbasegui/skghtmlboardwidget.cpp
+++ b/skgbasegui/skghtmlboardwidget.cpp
@@ -1,263 +1,263 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is a generic Skrooge plugin for html reports.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skghtmlboardwidget.h"
#include <qdom.h>
#include <qfileinfo.h>
#include <qqmlcontext.h>
#include <qquickitem.h>
#include <qquickwidget.h>
#include <qtemporaryfile.h>
#include <qtoolbutton.h>
#include <qwidgetaction.h>
#include <klocalizedstring.h>
#include <kcolorscheme.h>
#include "skgdocument.h"
#include "skgmainpanel.h"
#include "skgreport.h"
#include "skgtraces.h"
SKGHtmlBoardWidget::SKGHtmlBoardWidget(QWidget* iParent, SKGDocument* iDocument, const QString& iTitle, const QString& iTemplate, QStringList iTablesRefreshing, SKGSimplePeriodEdit::Modes iOptions)
: SKGBoardWidget(iParent, iDocument, iTitle), m_Quick(nullptr), m_Report(iDocument->getReport()), m_Text(nullptr), m_Template(iTemplate), m_TablesRefreshing(std::move(iTablesRefreshing)), m_refreshNeeded(false), m_period(nullptr)
{
SKGTRACEINFUNC(10)
// Create menu
if (iOptions != SKGSimplePeriodEdit::NONE) {
setContextMenuPolicy(Qt::ActionsContextMenu);
m_period = new SKGSimplePeriodEdit(this);
m_period->setMode(iOptions);
QDate date = QDate::currentDate();
QStringList list;
// TODO(Stephane MANKOWSKI): v_operation_display must be generic
getDocument()->getDistinctValues(QStringLiteral("v_operation_display"), QStringLiteral("MIN(d_DATEMONTH)"), QStringLiteral("d_date<=CURRENT_DATE"), list);
if (!list.isEmpty()) {
if (!list[0].isEmpty()) {
date = SKGServices::periodToDate(list[0]);
}
}
m_period->setFirstDate(date);
auto periodEditWidget = new QWidgetAction(this);
periodEditWidget->setDefaultWidget(m_period);
addAction(periodEditWidget);
}
// Enrich with tips of the day
m_Report->setTipsOfDay(SKGMainPanel::getMainPanel()->getTipsOfDay());
// Create main widget
QString ext = QFileInfo(iTemplate).suffix().toLower();
if (ext == QStringLiteral("qml")) {
// Mode QML
m_Quick = new QQuickWidget(this);
m_Quick->setResizeMode(QQuickWidget::SizeViewToRootObject);
m_Quick->setClearColor(Qt::transparent);
m_Quick->setAttribute(Qt::WA_AlwaysStackOnTop);
m_Quick->setAttribute(Qt::WA_TranslucentBackground);
m_Quick->setObjectName(QStringLiteral("m_Quick"));
QSizePolicy newSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
newSizePolicy.setHorizontalStretch(0);
newSizePolicy.setVerticalStretch(0);
m_Quick->setSizePolicy(newSizePolicy);
// Set properties
QVariantHash mapping = m_Report->getContextProperty();
auto keys = mapping.keys();
for (const auto& k : qAsConst(keys)) {
m_Quick->rootContext()->setContextProperty(k, mapping[k]);
}
m_Quick->rootContext()->setContextProperty(QStringLiteral("periodWidget"), m_period);
m_Quick->rootContext()->setContextProperty(QStringLiteral("panel"), SKGMainPanel::getMainPanel());
setMainWidget(m_Quick);
} else {
// Mode template HTML
m_Text = new QLabel(this);
m_Text->setObjectName(QStringLiteral("m_Text"));
m_Text->setTextFormat(Qt::RichText);
m_Text->setAlignment(Qt::AlignLeading | Qt::AlignLeft | Qt::AlignTop);
m_Text->setTextInteractionFlags(Qt::TextBrowserInteraction);
connect(m_Text, &QLabel::linkActivated, this, [ = ](const QString & val) {
SKGMainPanel::getMainPanel()->openPage(val);
});
setMainWidget(m_Text);
}
// Connects
connect(getDocument(), &SKGDocument::tableModified, this, &SKGHtmlBoardWidget::dataModified, Qt::QueuedConnection);
if (m_period != nullptr) {
connect(m_period, static_cast<void (SKGComboBox::*)(const QString&)>(&SKGComboBox::currentTextChanged), this, [ = ]() {
this->dataModified();
});
}
connect(SKGMainPanel::getMainPanel(), &SKGMainPanel::currentPageChanged, this, &SKGHtmlBoardWidget::pageChanged, Qt::QueuedConnection);
}
SKGHtmlBoardWidget::~SKGHtmlBoardWidget()
{
SKGTRACEINFUNC(10)
m_period = nullptr;
if (m_Report != nullptr) {
delete m_Report;
m_Report = nullptr;
}
}
QString SKGHtmlBoardWidget::getState()
{
SKGTRACEINFUNC(10)
QDomDocument doc(QStringLiteral("SKGML"));
doc.setContent(SKGBoardWidget::getState());
QDomElement root = doc.documentElement();
// Get state
if (m_period != nullptr) {
root.setAttribute(QStringLiteral("period"), m_period->text());
}
return doc.toString();
}
void SKGHtmlBoardWidget::setState(const QString& iState)
{
SKGTRACEINFUNC(10)
SKGBoardWidget::setState(iState);
QDomDocument doc(QStringLiteral("SKGML"));
doc.setContent(iState);
QDomElement root = doc.documentElement();
// Set state
if (m_period != nullptr) {
QString oldMode = root.attribute(QStringLiteral("previousMonth"));
if (oldMode.isEmpty()) {
QString period = root.attribute(QStringLiteral("period"));
if (!period.isEmpty() && m_period->contains(period)) {
m_period->setText(period);
}
} else {
m_period->setText(oldMode == QStringLiteral("N") ? i18nc("The current month", "Current month") : i18nc("The month before the current month", "Last month"));
}
}
dataModified(QLatin1String(""), 0);
}
void SKGHtmlBoardWidget::setPointSize(int iPointSize) const
{
if (m_Report != nullptr) {
m_Report->setPointSize(iPointSize);
}
}
void SKGHtmlBoardWidget::pageChanged()
{
if (m_refreshNeeded) {
dataModified();
}
}
void SKGHtmlBoardWidget::dataModified(const QString& iTableName, int iIdTransaction)
{
SKGTRACEINFUNC(10)
Q_UNUSED(iIdTransaction)
// Set title
QString period = (m_period != nullptr ? m_period->period() : QLatin1String(""));
QString title = getOriginalTitle();
if (title.contains(QStringLiteral("%1"))) {
setMainTitle(title.arg(period));
}
if (m_Report != nullptr) {
m_Report->setPeriod((m_period != nullptr ? m_period->period() : SKGServices::dateToPeriod(QDate::currentDate(), QStringLiteral("M"))));
}
if (m_TablesRefreshing.isEmpty() || m_TablesRefreshing.contains(iTableName) || iTableName.isEmpty()) {
// Is this the current page
SKGTabPage* page = SKGTabPage::parentTabPage(this);
if (page != nullptr && page != SKGMainPanel::getMainPanel()->currentPage()) {
// No, we memorize that we have to compute later the report
m_refreshNeeded = true;
return;
}
QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
if (m_Quick != nullptr) {
// Set the source
if (!m_Quick->source().isValid()) {
m_Quick->setSource(QUrl::fromLocalFile(m_Template));
QQuickItem* root = m_Quick->rootObject();
if (root != nullptr) {
connect(root, &QQuickItem::widthChanged, this, [ = ]() {
m_Quick->setMinimumSize(QSize(root->width(), root->height()));
});
connect(root, &QQuickItem::heightChanged, this, [ = ]() {
m_Quick->setMinimumSize(QSize(root->width(), root->height()));
});
m_Quick->setMinimumSize(QSize(root->width(), root->height()));
m_Quick->setMinimumSize(QSize(root->width(), root->height()));
}
} else {
// Clean the cache to trigger the modification
m_Report->cleanCache();
}
m_refreshNeeded = false;
}
if (m_Text != nullptr) {
// Clean the cache to trigger the modification
m_Report->cleanCache();
QString stream;
SKGError err = SKGReport::getReportFromTemplate(m_Report, m_Template, stream);
IFKO(err) stream = err.getFullMessage();
stream = stream.remove(QRegExp(QStringLiteral("<img[^>]*/>")));
// Remove color of hyperlinks
KColorScheme scheme(QPalette::Normal, KColorScheme::Window);
auto color = scheme.foreground(KColorScheme::NormalText).color().name().right(6);
stream = stream.replace(QStringLiteral("<a href"), QStringLiteral("<a style=\"color: #") + color + ";\" href");
m_Text->setText(stream);
m_refreshNeeded = false;
}
QApplication::restoreOverrideCursor();
}
// TODO(Stephane MANKOWSKI): No widget if no account (must not be hardcoded)
bool exist = false;
getDocument()->existObjects(QStringLiteral("account"), QLatin1String(""), exist);
if (parentWidget() != nullptr) {
setVisible(exist);
}
}
#include "skghtmlboardwidget.h"
diff --git a/skgbasegui/skghtmlboardwidget.h b/skgbasegui/skghtmlboardwidget.h
index 1a1ca4480..77e3e818c 100644
--- a/skgbasegui/skghtmlboardwidget.h
+++ b/skgbasegui/skghtmlboardwidget.h
@@ -1,96 +1,96 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGHTMLBOARDWIDGET_H
#define SKGHTMLBOARDWIDGET_H
/** @file
* This file is a generic Skrooge plugin for html/qml reports.
* @see SKGReport
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgbasegui_export.h"
#include "skgboardwidget.h"
#include "skgsimpleperiodedit.h"
class QLabel;
class QQuickWidget;
class SKGReport;
/**
* This file is a generic Skrooge plugin for html/qml reports
*/
class SKGBASEGUI_EXPORT SKGHtmlBoardWidget : public SKGBoardWidget
{
Q_OBJECT
public:
/**
* Default Constructor
* @param iParent the parent widget
* @param iDocument the document
* @param iTitle the title
* @param iTemplate the html template (.html) or the qml file (.qml)
* @param iTablesRefreshing the list of table refreshing the report when the table is updated. (empty means all)
* @param iOptions to enable options in menu
*/
explicit SKGHtmlBoardWidget(QWidget* iParent, SKGDocument* iDocument, const QString& iTitle, const QString& iTemplate, QStringList iTablesRefreshing = QStringList(), SKGSimplePeriodEdit::Modes iOptions = SKGSimplePeriodEdit::NONE);
/**
* Default Destructor
*/
~SKGHtmlBoardWidget() override;
/**
* Get the current state
* MUST BE OVERWRITTEN
* @return a string containing all information needed to set the same state.
* Could be an XML stream
*/
QString getState() override;
/**
* Set the current state
* MUST BE OVERWRITTEN
* @param iState must be interpreted to set the state of the widget
*/
void setState(const QString& iState) override;
/**
* Set the font point size
* @param iPointSize font point size
*/
virtual void setPointSize(int iPointSize) const;
protected Q_SLOTS:
void pageChanged();
virtual void dataModified(const QString& iTableName = QString(), int iIdTransaction = 0);
protected:
QQuickWidget* m_Quick;
SKGReport* m_Report;
private:
Q_DISABLE_COPY(SKGHtmlBoardWidget)
QLabel* m_Text;
QString m_Template;
QStringList m_TablesRefreshing;
bool m_refreshNeeded;
SKGSimplePeriodEdit* m_period;
};
#endif // SKGHTMLBOARDWIDGET_H
diff --git a/skgbasegui/skginterfaceplugin.cpp b/skgbasegui/skginterfaceplugin.cpp
index 71860fe95..7d8ff97c4 100644
--- a/skgbasegui/skginterfaceplugin.cpp
+++ b/skgbasegui/skginterfaceplugin.cpp
@@ -1,150 +1,150 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is a plugin interface default implementation.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skginterfaceplugin.h"
#include "skgmainpanel.h"
#include "kactioncollection.h"
SKGInterfacePlugin::SKGInterfacePlugin(QObject* iParent)
: KParts::ReadOnlyPart(iParent)
{}
SKGInterfacePlugin::~SKGInterfacePlugin()
= default;
QStringList SKGInterfacePlugin::processArguments(const QStringList& iArgument)
{
return iArgument;
}
void SKGInterfacePlugin::close()
{
disconnect(this);
}
void SKGInterfacePlugin::refresh() {}
void SKGInterfacePlugin::registerGlobalAction(const QString& iIdentifier, QAction* iAction,
const QStringList& iListOfTable, int iMinSelection, int iMaxSelection,
int iRanking, bool iSelectionMustHaveFocus)
{
actionCollection()->addAction(iIdentifier, iAction);
if (SKGMainPanel::getMainPanel() != nullptr) {
SKGMainPanel::getMainPanel()->registerGlobalAction(iIdentifier, iAction, false, iListOfTable, iMinSelection, iMaxSelection, iRanking, iSelectionMustHaveFocus);
}
}
QDockWidget* SKGInterfacePlugin::getDockWidget()
{
return nullptr;
}
SKGTabPage* SKGInterfacePlugin::getWidget()
{
return nullptr;
}
int SKGInterfacePlugin::getNbDashboardWidgets()
{
return 0;
}
QString SKGInterfacePlugin::getDashboardWidgetTitle(int iIndex)
{
Q_UNUSED(iIndex)
return QLatin1String("");
}
SKGBoardWidget* SKGInterfacePlugin::getDashboardWidget(int iIndex)
{
Q_UNUSED(iIndex)
return nullptr;
}
QWidget* SKGInterfacePlugin::getPreferenceWidget()
{
return nullptr;
}
KConfigSkeleton* SKGInterfacePlugin::getPreferenceSkeleton()
{
return nullptr;
}
SKGError SKGInterfacePlugin::savePreferences() const
{
return SKGError();
}
int SKGInterfacePlugin::getOrder() const
{
return 999;
}
QString SKGInterfacePlugin::statusTip() const
{
return toolTip();
}
QString SKGInterfacePlugin::icon() const
{
return QLatin1String("");
}
QString SKGInterfacePlugin::toolTip() const
{
return title();
}
QStringList SKGInterfacePlugin::tips() const
{
return QStringList();
}
QStringList SKGInterfacePlugin::subPlugins() const
{
return QStringList();
}
bool SKGInterfacePlugin::isInPagesChooser() const
{
return false;
}
bool SKGInterfacePlugin::isEnabled() const
{
return true;
}
SKGAdviceList SKGInterfacePlugin::advice(const QStringList& iIgnoredAdvice)
{
Q_UNUSED(iIgnoredAdvice)
return SKGAdviceList();
}
SKGError SKGInterfacePlugin::executeAdviceCorrection(const QString& iAdviceIdentifier, int iSolution)
{
Q_UNUSED(iAdviceIdentifier)
Q_UNUSED(iSolution)
return SKGError(ERR_NOTIMPL, QLatin1String(""));
}
diff --git a/skgbasegui/skginterfaceplugin.h b/skgbasegui/skginterfaceplugin.h
index ca50858c3..5228b4aaf 100644
--- a/skgbasegui/skginterfaceplugin.h
+++ b/skgbasegui/skginterfaceplugin.h
@@ -1,239 +1,239 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGINTERFACEPLUGIN_H
#define SKGINTERFACEPLUGIN_H
/** @file
* This file is a plugin interface definition.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include <kparts/readonlypart.h>
#include <qstringlist.h>
#include "skgadvice.h"
#include "skgbasegui_export.h"
#include "skgdocument.h"
#include "skgerror.h"
#include "skgtabpage.h"
class SKGBoardWidget;
class QAction;
class KConfigSkeleton;
class QDockWidget;
/**
* This file is a plugin interface definition.
*/
class SKGBASEGUI_EXPORT SKGInterfacePlugin : public KParts::ReadOnlyPart
{
Q_OBJECT
public:
/**
* Default constructor
* @param iParent the parent of the plugin
*/
explicit SKGInterfacePlugin(QObject* iParent = nullptr);
/**
* Default destructor
*/
~SKGInterfacePlugin() override;
/**
* Called to initialise the plugin
* @param iDocument the main document
* @return true if the plugin is compatible with the document
*/
virtual bool setupActions(SKGDocument* iDocument) = 0;
/**
* Register a global action
* @param iIdentifier identifier of the action
* @param iAction action pointer
* @param iListOfTable list of table where this action must be enabled (empty list means all)
* You can also add only one item like this to set the list dynamically:
* query:the sql condition on sqlite_master
* @param iMinSelection the minimum number of selected item to enable the action
* 0 : no need selection but need a page opened containing a table
* -1 : no need selection and need a page opened (not containing a table)
* -2 : no need selection and no need a page opened
* @param iMaxSelection the maximum number of selected item to enable the action (-1 = infinite)
* @param iRanking the ranking to sort actions in contextual menus
* -1: automatic by creation order
* 0: not in contextual menu
* @param iSelectionMustHaveFocus the action will be activated only if the widget containing the selection has the focus
*
* Actions can be set in differents groups by changing hundred:
* 0 to 99 is a group
* 100 to 200 is an other group
*/
virtual void registerGlobalAction(const QString& iIdentifier, QAction* iAction,
const QStringList& iListOfTable = QStringList(),
int iMinSelection = -2,
int iMaxSelection = -1,
int iRanking = -1,
bool iSelectionMustHaveFocus = false);
/**
* This function is called when the application is launched again with new arguments
* @param iArgument the arguments
* @return the rest of arguments to treat
*/
virtual QStringList processArguments(const QStringList& iArgument);
/**
* Must be modified to close properly the plugin.
*/
virtual void close();
/**
* Must be modified to refresh widgets after a modification.
*/
virtual void refresh();
/**
* The page widget of the plugin.
* @return The page widget of the plugin
*/
virtual SKGTabPage* getWidget();
/**
* The number of dashboard widgets of the plugin.
* @return The number of dashboard widgets of the plugin
*/
virtual int getNbDashboardWidgets();
/**
* Get a dashboard widget title of the plugin.
* @param iIndex the index of the widget
* @return The title
*/
virtual QString getDashboardWidgetTitle(int iIndex);
/**
* Get a dashboard widget of the plugin.
* @param iIndex the index of the widget
* @return The dashboard widget of the plugin
*/
virtual SKGBoardWidget* getDashboardWidget(int iIndex);
/**
* The dock widget of the plugin.
* @return The dock widget of the plugin
*/
virtual QDockWidget* getDockWidget();
/**
* The preference widget of the plugin.
* @return The preference widget of the plugin
*/
virtual QWidget* getPreferenceWidget();
/**
* The preference skeleton of the plugin.
* @return The preference skeleton of the plugin
*/
virtual KConfigSkeleton* getPreferenceSkeleton();
/**
* This function is called when preferences have been modified. Must be used to save some parameters into the document.
* A transaction is already opened
* @return an object managing the error.
* @see SKGError
*/
virtual SKGError savePreferences() const;
/**
* The title of the plugin.
* @return The title of the plugin
*/
virtual QString title() const = 0;
/**
* The icon of the plugin.
* @return The icon of the plugin
*/
virtual QString icon() const;
/**
* The statusTip of the plugin.
* @return The toolTip of the plugin
*/
virtual QString statusTip() const;
/**
* The toolTip of the plugin.
* @return The toolTip of the plugin
*/
virtual QString toolTip() const;
/**
* The tips list of the plugin.
* @return The tips list of the plugin
*/
virtual QStringList tips() const;
/**
* The sub plugins services types list of the plugin.
* This will be used to display authors in the "About" of the application
* @return The sub plugins list of the plugin
*/
virtual QStringList subPlugins() const;
/**
* Must be implemented to set the position of the plugin.
* @return integer value between 0 and 999 (default = 999)
*/
virtual int getOrder() const;
/**
* Must be implemented to know if a plugin must be display in pages chooser.
* @return true of false (default = false)
*/
virtual bool isInPagesChooser() const;
/**
* Must be implemented to know if this plugin is enabled
* @return true of false (default = true)
*/
virtual bool isEnabled() const;
/**
* The advice list of the plugin.
* @return The advice list of the plugin
*/
virtual SKGAdviceList advice(const QStringList& iIgnoredAdvice);
/**
* Must be implemented to execute the automatic correction for the advice.
* @param iAdviceIdentifier the identifier of the advice
* @param iSolution the identifier of the possible solution
* @return an object managing the error. MUST return ERR_NOTIMPL if iAdviceIdentifier is not known
* @see SKGError
*/
virtual SKGError executeAdviceCorrection(const QString& iAdviceIdentifier, int iSolution);
private:
Q_DISABLE_COPY(SKGInterfacePlugin)
};
/**
* This plugin interface definition.
*/
Q_DECLARE_INTERFACE(SKGInterfacePlugin, "skrooge.com.SKGInterfacePlugin/1.0")
#endif // SKGINTERFACEPLUGIN_H
diff --git a/skgbasegui/skgmainpanel.cpp b/skgbasegui/skgmainpanel.cpp
index 2b7026f31..5a86c685b 100644
--- a/skgbasegui/skgmainpanel.cpp
+++ b/skgbasegui/skgmainpanel.cpp
@@ -1,2740 +1,2740 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+* along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file defines classes skgmainpanel.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgmainpanel.h"
#include <kaboutdata.h>
#include <kactioncollection.h>
#include <kactionmenu.h>
#include <kcombobox.h>
#include <kconfigdialog.h>
#include <kencodingfiledialog.h>
#include <kformat.h>
#include <kmessagebox.h>
#include <kmessagewidget.h>
#include <knotification.h>
#include <knotifyconfigwidget.h>
#include <kselectaction.h>
#include <kservice.h>
#include <kservicetypetrader.h>
#include <kstandardaction.h>
#include <kstatusnotifieritem.h>
#include <kstringhandler.h>
#include <ktoggleaction.h>
#include <ktoolbar.h>
#include <ktoolbarpopupaction.h>
#include <kxmlguifactory.h>
#ifdef KActivities_FOUND
#include <kactivities/resourceinstance.h>
#endif
#include <QDBusConnection>
#include <QDBusMessage>
#include <qaction.h>
#include <qapplication.h>
#include <qcollator.h>
#include <qcompleter.h>
#include <qdesktopservices.h>
#include <qdir.h>
#include <qdom.h>
#include <qevent.h>
#include <qfiledialog.h>
#include <qheaderview.h>
#include <qlineedit.h>
#include <qmenu.h>
#include <qprocess.h>
#include <qprogressbar.h>
#include <qpushbutton.h>
#include <qscrollarea.h>
#include <qsplashscreen.h>
#include <qtabbar.h>
#include <qtabwidget.h>
#include <qtextcodec.h>
#include <qurlquery.h>
#include <algorithm> // std::sort
#include "skgdefine.h"
#include "skginterfaceplugin.h"
#include "skgservices.h"
#include "skgtraces.h"
#include "skgtransactionmng.h"
#include "skgtreeview.h"
#include "skgwebview.h"
#include "skgzoomselector.h"
struct doublePointer {
void* p1;
void* p2;
};
struct historyPage {
SKGTabPage::SKGPageHistoryItem current;
SKGTabPage::SKGPageHistoryItemList next;
SKGTabPage::SKGPageHistoryItemList previous;
};
struct actionDetails {
QPointer<QAction> action;
QStringList tables;
int min{};
int max{};
int ranking{};
bool focus{};
};
class SKGMainPanelPrivate
{
public:
Ui::skgmainpanel_base ui{};
Ui::skgmainpanel_pref uipref{};
SKGTabWidget* m_tabWidget;
QSplashScreen* m_splashScreen;
SKGDocument* m_currentDocument;
QList<SKGInterfacePlugin*> m_pluginsList;
QMap<QString, actionDetails > m_registeredGlogalAction;
QList<historyPage> m_historyClosedPages;
QMenu* m_contextMenu;
QAction* m_actHideContextItem;
QAction* m_actShowAllContextItems;
QAction* m_actDelete;
QAction* m_closePageAction;
QAction* m_closeAllOtherPagesAction;
QAction* m_switchPinState;
QAction* m_saveDefaultStateAction;
QAction* m_resetDefaultStateAction;
QAction* m_overwriteBookmarkStateAction;
QAction* m_configureAction;
QAction* m_enableEditorAction;
QAction* m_fullScreenAction;
QAction* m_actLock;
QAction* m_actUnLock;
QAction* m_reopenLastClosed;
KStatusNotifierItem* m_kSystemTrayIcon;
QLabel* m_kNormalMessage;
SKGZoomSelector* m_zoomSelector;
KToolBarPopupAction* m_previousAction;
KToolBarPopupAction* m_nextAction;
KToolBarPopupAction* m_buttonMenuAction;
KToggleAction* m_showMenuBarAction;
QMenu* m_previousMenu;
QMenu* m_nextMenu;
QMenu* m_buttonMenu;
QWidget* m_mainWidget;
QVBoxLayout* m_mainLayout{};
doublePointer m_progressObjects{};
bool m_middleClick;
bool m_saveOnClose;
QString m_fileName;
SKGWidget* m_widgetHavingSelection;
QStringList m_tipsOfTheDay;
#ifdef KActivities_FOUND
KActivities::ResourceInstance* m_activityResourceInstance;
#endif
static bool m_currentActionCanceled;
static SKGMainPanel* m_mainPanel;
SKGMainPanelPrivate()
{
m_actHideContextItem = nullptr; m_actShowAllContextItems = nullptr; m_actDelete = nullptr;
m_closePageAction = nullptr; m_closeAllOtherPagesAction = nullptr; m_switchPinState = nullptr; m_saveDefaultStateAction = nullptr;
m_resetDefaultStateAction = nullptr; m_overwriteBookmarkStateAction = nullptr; m_configureAction = nullptr; m_enableEditorAction = nullptr; m_fullScreenAction = nullptr; m_actLock = nullptr;
m_actUnLock = nullptr;
m_kSystemTrayIcon = nullptr;
m_kNormalMessage = nullptr; m_zoomSelector = nullptr; m_previousAction = nullptr; m_nextAction = nullptr; m_buttonMenuAction = nullptr;
m_mainWidget = nullptr; m_mainLayout = nullptr; m_middleClick = false; m_saveOnClose = false;
m_widgetHavingSelection = nullptr;
m_tabWidget = nullptr; m_splashScreen = nullptr; m_currentDocument = nullptr;
m_contextMenu = nullptr;
m_reopenLastClosed = nullptr;
m_showMenuBarAction = nullptr;
m_previousMenu = nullptr;
m_nextMenu = nullptr;
m_buttonMenu = nullptr;
m_progressObjects.p1 = nullptr;
m_progressObjects.p2 = nullptr;
#ifdef KActivities_FOUND
m_activityResourceInstance = nullptr;
#endif
}
static int progressBarCallBack(int iPos, qint64 iTime, const QString& iName, void* iProgressBar)
{
Q_UNUSED(iTime)
QProgressBar* progressBar = nullptr;
QPushButton* button = nullptr;
auto* pointers = static_cast<doublePointer*>(iProgressBar);
if (pointers != nullptr) {
progressBar = static_cast<QProgressBar*>(pointers->p1);
button = static_cast<QPushButton*>(pointers->p2);
}
bool visible = (iPos > 0 && iPos <= 100);
if (progressBar != nullptr) {
QString commonFormat = QStringLiteral("%p%");
/*if (iPos > 0) {
* qint64 estimatedTime = 100 * iTime / iPos;
* qint64 remainingTime = estimatedTime - iTime;
* commonFormat = commonFormat % " - " % i18nc("To print a remaining time (in seconde) / estimated time (in second)", "%1s / %2s",
* SKGServices::intToString(remainingTime / 1000),
* SKGServices::intToString(estimatedTime / 1000));
}*/
progressBar->setFormat(iName.isEmpty() ? commonFormat : commonFormat % '\n' % iName);
progressBar->setValue(iPos);
progressBar->setVisible(visible);
if (iPos == 100) {
QTimer::singleShot(300, Qt::CoarseTimer, progressBar, &QProgressBar::hide);
}
progressBar->setToolTip(iName);
QDBusMessage message = QDBusMessage::createSignal(QLatin1String("/org/") + KAboutData::applicationData().componentName() + QLatin1String("/UnityLauncher"),
QStringLiteral("com.canonical.Unity.LauncherEntry"),
QStringLiteral("Update"));
message << "application://org.kde.skrooge.desktop";
QVariantMap setProperty;
if (iPos == 100) {
setProperty.insert(QStringLiteral("progress"), 0.0);
setProperty.insert(QStringLiteral("progress-visible"), false);
} else {
setProperty.insert(QStringLiteral("progress"), static_cast<double>(iPos / 100.0));
setProperty.insert(QStringLiteral("progress-visible"), true);
}
message << setProperty;
QDBusConnection::sessionBus().send(message);
}
if (button != nullptr) {
button->setVisible(visible);
if (iPos == 100) {
QTimer::singleShot(300, Qt::CoarseTimer, button, &QPushButton::hide);
}
}
SKGMainPanelPrivate::m_currentActionCanceled = false;
if (iPos != 0 && iPos != 100) {
qApp->processEvents(QEventLoop::AllEvents, 500);
}
return (SKGMainPanelPrivate::m_currentActionCanceled ? 1 : 0);
}
static bool adviceLessThan(const SKGAdvice& s1, const SKGAdvice& s2)
{
if (s1.getPriority() == s2.getPriority()) {
return (s1.getShortMessage() > s2.getShortMessage());
}
return (s1.getPriority() > s2.getPriority());
}
static void setAttribute(QDomElement& iRoot, const QString& iPath, const QString& iValue)
{
int pos = iPath.indexOf('.');
if (pos == -1) {
iRoot.setAttribute(iPath, iValue);
} else {
QString newElementName = iPath.left(pos);
QString newAttribue = iPath.right(iPath.count() - pos - 1);
QDomDocument doc(QStringLiteral("SKGML"));
doc.setContent(iRoot.attribute(newElementName));
QDomElement root = doc.documentElement();
if (root.isNull()) {
root = doc.createElement(QStringLiteral("parameters"));
doc.appendChild(root);
}
setAttribute(root, newAttribue, iValue);
iRoot.setAttribute(newElementName, doc.toString());
}
}
void refreshTabPosition()
{
m_tabWidget->setTabPosition(static_cast<QTabWidget::TabPosition>(skgbasegui_settings::main_tabs_position()));
}
void rebuildSystemTray()
{
if (skgbasegui_settings::icon_in_system_tray()) {
if (m_kSystemTrayIcon == nullptr) {
m_kSystemTrayIcon = new KStatusNotifierItem(m_mainPanel);
m_kSystemTrayIcon->setStandardActionsEnabled(true);
m_kSystemTrayIcon->setAssociatedWidget(m_mainPanel);
KAboutData about = KAboutData::applicationData();
m_kSystemTrayIcon->setIconByName(about.programIconName());
}
} else {
if (m_kSystemTrayIcon != nullptr) {
delete m_kSystemTrayIcon;
m_kSystemTrayIcon = nullptr;
}
}
}
};
bool SKGMainPanelPrivate::m_currentActionCanceled = false;
SKGMainPanel* SKGMainPanelPrivate::m_mainPanel = nullptr;
SKGMainPanel::SKGMainPanel(QSplashScreen* iSplashScreen, SKGDocument* iDocument)
: d(new SKGMainPanelPrivate)
{
SKGTRACEINFUNC(1)
d->m_tabWidget = new SKGTabWidget(this);
d->m_splashScreen = iSplashScreen;
d->m_currentDocument = iDocument;
setComponentName(QStringLiteral("skg"), KAboutData::applicationData().displayName());
setObjectName(qApp->applicationDisplayName());
// Set main panel
SKGMainPanelPrivate::m_mainPanel = this;
auto w = new QScrollArea(this);
w->setFrameShape(QFrame::NoFrame);
w->setFocusPolicy(Qt::NoFocus);
d->m_mainLayout = new QVBoxLayout(w);
d->m_mainLayout->setSpacing(0);
d->m_mainLayout->setContentsMargins(0, 0, 0, 0);
d->m_mainLayout->addWidget(d->m_tabWidget);
d->ui.setupUi(this);
// setMainWidget(new QLabel("hello"));
// Initialize settings
KSharedConfigPtr config = KSharedConfig::openConfig();
KConfigGroup prefskg = config->group("Main Panel");
int option = prefskg.readEntry("update_modified_contexts", 100);
if (option == 100) {
// First call, we set default values
prefskg.writeEntry("update_modified_contexts", 2, KConfigBase::Normal);
// NEVER: set following setting
KMessageBox::saveDontShowAgainYesNo(QStringLiteral("updateContextOnClose"), KMessageBox::No);
SKGTRACEL(1) << "update_modified_contexts set to NEVER" << endl;
SKGTRACEL(1) << "updateContextOnClose set to No" << endl;
}
option = prefskg.readEntry("update_modified_bookmarks", 100);
if (option == 100) {
// First call, we set default values
prefskg.writeEntry("update_modified_bookmarks", 2, KConfigBase::Normal);
// NEVER: set following setting
KMessageBox::saveDontShowAgainYesNo(QStringLiteral("updateBookmarkOnClose"), KMessageBox::No);
SKGTRACEL(1) << "update_modified_bookmarks set to NEVER" << endl;
SKGTRACEL(1) << "updateBookmarkOnClose set to No" << endl;
}
// Search plugins
KService::List offers = KServiceTypeTrader::self()->query(QStringLiteral("SKG GUI/Plugin"));
// Load plugins
int nb = offers.count();
SKGTRACEL(1) << nb << " plugins found" << endl;
if (d->m_splashScreen != nullptr) {
d->m_splashScreen->showMessage(i18nc("Splash screen message", "Loading plugins..."), Qt::AlignLeft, QColor(221, 130, 8)); // krazy:exclude=qmethods
}
SKGError err;
QStringList listAuthors;
QStringList listTasks;
QStringList listEmails;
QStringList listOscs;
for (int i = 0; i < nb; ++i) {
KService::Ptr service = offers.at(i);
QString name = service->name();
QString version = service->property(QStringLiteral("X-KDE-PluginInfo-Version"), QVariant::String).toString();
QString id = service->property(QStringLiteral("X-Krunner-ID"), QVariant::String).toString();
QString msg = i18nc("Splash screen message", "Loading plugin %1/%2: %3...", i + 1, nb, name);
SKGTRACEL(1) << msg << endl;
if (d->m_splashScreen != nullptr) {
d->m_splashScreen->showMessage(msg, Qt::AlignLeft, QColor(221, 130, 8)); // krazy:exclude=qmethods
}
KPluginLoader loader(service->library());
if (version.isEmpty() || SKGServices::stringToDouble(version) < 1) {
SKGTRACE << "WARNING: plugin [" << name << "] not loaded because of version too old (<1)" << endl;
} else {
KPluginFactory* factory2 = loader.factory();
if (factory2 != nullptr) {
auto* pluginInterface = factory2->create<SKGInterfacePlugin> (this);
if (pluginInterface != nullptr) {
if (pluginInterface->isEnabled() && pluginInterface->setupActions(getDocument())) {
// Add plugin in about
QStringList listOfAuthors;
QStringList listOfEmails;
QStringList listOfPlugins;
QString author = service->property(QStringLiteral("X-KDE-PluginInfo-Author"), QVariant::String).toString();
QString email = service->property(QStringLiteral("X-KDE-PluginInfo-Email"), QVariant::String).toString();
if (!author.isEmpty()) {
listOfAuthors.push_back(author);
listOfEmails.push_back(email);
listOfPlugins.push_back(name);
}
const auto subPlugins = pluginInterface->subPlugins();
for (const QString& subPlugin : subPlugins) {
KService::List subOffers = KServiceTypeTrader::self()->query(subPlugin);
int nbSubOffers = subOffers.count();
for (int j = 0; j < nbSubOffers; ++j) {
KService::Ptr subService = subOffers.at(j);
QString author2 = subService->property(QStringLiteral("X-KDE-PluginInfo-Author"), QVariant::String).toString();
QString email2 = subService->property(QStringLiteral("X-KDE-PluginInfo-Email"), QVariant::String).toString();
if (!author2.isEmpty()) {
listOfAuthors.push_back(author2);
listOfEmails.push_back(email2);
listOfPlugins.push_back(subService->name());
}
}
}
int nbAuthors = listOfAuthors.count();
for (int j = 0; j < nbAuthors; ++j) {
QString authorId;
QString author = listOfAuthors.at(j);
QStringList authors = SKGServices::splitCSVLine(author, ',');
if (authors.count() == 2) {
author = authors.at(0);
authorId = authors.at(1);
}
int pos2 = listAuthors.indexOf(author);
if (pos2 == -1) {
listAuthors.push_back(author);
listTasks.push_back(i18n("Developer of plugin '%1'", listOfPlugins.at(j)));
listEmails.push_back(listOfEmails.at(j));
listOscs.push_back(authorId);
} else {
listTasks[pos2] += i18n(", '%1'", listOfPlugins.at(j));
}
}
// Store plugin
int nbplugin = d->m_pluginsList.count();
int pos3 = nbplugin;
for (int j = nbplugin - 1; j >= 0; --j) {
if (pluginInterface->getOrder() < d->m_pluginsList.at(j)->getOrder()) {
pos3 = j;
}
}
d->m_pluginsList.insert(pos3, pluginInterface);
pluginInterface->setObjectName(id);
// Add tips
d->m_tipsOfTheDay += pluginInterface->tips();
}
}
} else {
QString msg2 = i18nc("An information message", "Loading plugin %1 failed because the factory could not be found in %2: %3", id, service->library(), loader.errorString());
getDocument()->sendMessage(msg2);
SKGTRACEL(1) << "WARNING:" << msg2 << endl;
}
}
}
// Add credits
KAboutData about = KAboutData::applicationData();
nb = listAuthors.count();
for (int i = 0; i < nb; ++i) {
about.addCredit(listAuthors.at(i), listTasks.at(i), listEmails.at(i), QLatin1String(""), listOscs.at(i));
}
KAboutData::setApplicationData(about);
// accept dnd
setAcceptDrops(true);
// tell the KXmlGuiWindow that this is indeed the main widget
setCentralWidget(w);
d->refreshTabPosition();
d->m_tabWidget->setMovable(true);
d->m_tabWidget->setTabsClosable(true);
d->m_tabWidget->setUsesScrollButtons(true);
d->m_tabWidget->tabBar()->setSelectionBehaviorOnRemove(QTabBar::SelectPreviousTab);
d->m_tabWidget->setDocumentMode(true);
d->m_tabWidget->show();
// System tray
d->rebuildSystemTray();
// then, setup our actions
setupActions();
displayErrorMessage(err);
// Add a status bar
statusBar()->show();
QPalette palette2 = QApplication::palette();
palette2.setColor(QPalette::Base, Qt::transparent);
d->ui.kContextList->setPalette(palette2);
QAction* toggle = d->ui.kDockContext->toggleViewAction();
QAction* panelAction = actionCollection()->addAction(QStringLiteral("view_context"));
registerGlobalAction(QStringLiteral("view_context"), panelAction);
panelAction->setCheckable(true);
panelAction->setChecked(toggle->isChecked());
panelAction->setText(toggle->text());
actionCollection()->setDefaultShortcut(panelAction, Qt::SHIFT + Qt::Key_F9);
connect(panelAction, &QAction::triggered, toggle, &QAction::trigger);
connect(toggle, &QAction::toggled, panelAction, &QAction::setChecked);
QAction* toggle2 = d->ui.kDockMessages->toggleViewAction();
QAction* panelAction2 = actionCollection()->addAction(QStringLiteral("view_messages"));
registerGlobalAction(QStringLiteral("view_messages"), panelAction2);
panelAction2->setCheckable(true);
panelAction2->setChecked(toggle2->isChecked());
panelAction2->setText(toggle2->text());
actionCollection()->setDefaultShortcut(panelAction2, Qt::SHIFT + Qt::Key_F8);
connect(panelAction2, &QAction::triggered, toggle2, &QAction::trigger);
connect(toggle2, &QAction::toggled, panelAction2, &QAction::setChecked);
auto contextMenu = new KSelectAction(SKGServices::fromTheme(QStringLiteral("tab-new")), i18nc("Noun", "Pages"), this);
registerGlobalAction(QStringLiteral("view_contextmenu"), contextMenu);
// Add plugin in client in right order
QList<QListWidgetItem*> pageNotVisible;
KConfigGroup prefContextVisibility = config->group("Context Visibility");
int shortCutIndex = 0;
QString shortCutPrefix = QStringLiteral("Ctrl+");
int nbplugin = d->m_pluginsList.count();
QList<QAction*> contextActionList;
for (int j = 0; j < nbplugin; ++j) {
SKGInterfacePlugin* pluginInterface = d->m_pluginsList.at(j);
if (pluginInterface != nullptr) {
// Creation of the item
QString title = pluginInterface->title();
SKGTRACEL(1) << "Add plugin (" << pluginInterface->getOrder() << ") : " << title << endl;
if (!title.isEmpty()) {
// Add menu item with shortcuts
if (pluginInterface->isInPagesChooser()) {
bool visible = prefContextVisibility.readEntry(pluginInterface->objectName(), true);
QIcon icon = SKGServices::fromTheme(pluginInterface->icon());
auto contextItem = new QListWidgetItem(icon, title);
contextItem->setStatusTip(pluginInterface->statusTip());
contextItem->setToolTip(pluginInterface->toolTip());
contextItem->setData(12, j); // context item ==> plugin
int page2 = d->ui.kContextList->count();
pluginInterface->setProperty("contextItem", page2); // plugin ==> context item
d->ui.kContextList->addItem(contextItem);
QAction* newAction = contextMenu->addAction(icon, title);
if (newAction != nullptr) {
newAction->setCheckable(false);
newAction->setData(page2);
contextItem->setData(15, QVariant::fromValue(static_cast<void*>(newAction))); // context item ==> action
if (!shortCutPrefix.isEmpty()) {
++shortCutIndex;
if (shortCutIndex == 10) {
shortCutIndex = 0;
if (shortCutPrefix == QStringLiteral("Ctrl+")) {
shortCutPrefix += QStringLiteral("Alt+");
} else {
shortCutPrefix = QLatin1String("");
}
}
if (!shortCutPrefix.isEmpty()) {
actionCollection()->setDefaultShortcut(newAction, QString(shortCutPrefix % SKGServices::intToString(shortCutIndex)));
}
}
connect(newAction, &QAction::triggered, this, &SKGMainPanel::onOpenContext);
contextActionList.append(newAction);
if (!visible) {
pageNotVisible.push_back(contextItem);
}
// Register action
QString id = "page_" % pluginInterface->objectName();
registerGlobalAction(id, newAction);
registerGlobalAction(id, newAction);
}
}
// Create dock if needed
QDockWidget* dockWidget = pluginInterface->getDockWidget();
if (dockWidget != nullptr) {
addDockWidget(Qt::LeftDockWidgetArea, dockWidget);
tabifyDockWidget(d->ui.kDockContext, dockWidget);
tabifyDockWidget(dockWidget, d->ui.kDockContext);
}
}
}
}
// Lock docs if needed
KConfigGroup pref = getMainConfigGroup();
if (pref.readEntry("docks_locked", false)) {
onLockDocks();
}
if (!pref.readEntry("first_launch", false)) {
this->setWindowState(windowState() | Qt::WindowMaximized);
pref.writeEntry("first_launch", true);
}
// a call to KXmlGuiWindow::setupGUI() populates the GUI
// with actions, using KXMLGUI.
// It also applies the saved mainwindow settings, if any, and ask the
// mainwindow to automatically save settings if changed: window size,
// toolbar position, icon size, etc.
setupGUI(Default, QStringLiteral("skgmainpanel.rc"));
plugActionList(QStringLiteral("context_actionlist"), contextActionList);
for (int j = 0; j < nbplugin; ++j) {
SKGInterfacePlugin* pluginInterface = d->m_pluginsList.at(j);
if (pluginInterface != nullptr) {
QString title = pluginInterface->title();
SKGTRACEL(1) << "Add plugin client (" << pluginInterface->getOrder() << ") : " << title << endl;
guiFactory()->addClient(pluginInterface);
}
}
// Hide items in context
nb = pageNotVisible.count();
for (int i = 0; i < nb; ++i) {
setContextVisibility(pageNotVisible.at(i), false);
}
// Set status bar
d->m_kNormalMessage = new QLabel(this);
d->m_kNormalMessage->setSizePolicy(QSizePolicy(QSizePolicy::Ignored, QSizePolicy::Preferred));
auto kProgressBar = new QProgressBar(this);
kProgressBar->setObjectName(QStringLiteral("kProgressBar"));
kProgressBar->setValue(0);
kProgressBar->setMinimumSize(100, 20);
QSizePolicy sizePolicyProgessBar(QSizePolicy::Fixed, QSizePolicy::Expanding);
kProgressBar->setSizePolicy(sizePolicyProgessBar);
kProgressBar->setToolTip(i18nc("Widget description", "Progress of the current action"));
QFont f = kProgressBar->font();
f.setPointSize(6.0);
kProgressBar->setFont(f);
kProgressBar->setVisible(false);
kProgressBar->setAlignment(Qt::AlignTop | Qt::AlignHCenter);
kProgressBar->setRange(0, 100);
d->m_zoomSelector = new SKGZoomSelector(this);
d->m_zoomSelector->setSizePolicy(sizePolicyProgessBar);
connect(d->m_zoomSelector, &SKGZoomSelector::changed, this, &SKGMainPanel::onZoomChanged);
statusBar()->addWidget(d->m_kNormalMessage, 1);
statusBar()->addPermanentWidget(kProgressBar);
// Set Cancel button
auto kCancelButton = new QPushButton();
kCancelButton->setObjectName(QStringLiteral("kCancelButton"));
kCancelButton->setIcon(SKGServices::fromTheme(QStringLiteral("media-playback-stop")));
kCancelButton->setToolTip(i18nc("Widget description", "Cancel the current action"));
kCancelButton->setStatusTip(i18nc("Widget description", "Cancel the current action"));
kCancelButton->setVisible(false);
connect(kCancelButton, &QPushButton::clicked, this, &SKGMainPanel::onCancelCurrentAction);
//
d->ui.kClearMessageBtn->setIcon(SKGServices::fromTheme(QStringLiteral("edit-clear")));
connect(d->ui.kClearMessageBtn, &QPushButton::clicked, this, &SKGMainPanel::onClearMessages);
// Add special button in toolbar
KToolBar* tb = toolBar();
if (tb != nullptr) {
auto label = new QLabel(this);
QSizePolicy sizePolicyLabel(QSizePolicy::Expanding, QSizePolicy::Preferred);
sizePolicyLabel.setHorizontalStretch(0);
sizePolicyLabel.setVerticalStretch(0);
sizePolicyLabel.setHeightForWidth(label->sizePolicy().hasHeightForWidth());
label->setSizePolicy(sizePolicyLabel);
tb->addWidget(label);
tb->addAction(d->m_buttonMenuAction);
}
statusBar()->addPermanentWidget(kCancelButton);
statusBar()->addPermanentWidget(d->m_zoomSelector);
// Set progress bar call back
if (getDocument() != nullptr) {
d->m_progressObjects.p1 = static_cast<void*>(kProgressBar);
d->m_progressObjects.p2 = static_cast<void*>(kCancelButton);
getDocument()->setProgressCallback(&SKGMainPanelPrivate::progressBarCallBack, static_cast<void*>(&d->m_progressObjects));
}
// Connection
if (getDocument() != nullptr) {
connect(getDocument(), &SKGDocument::transactionSuccessfullyEnded, this, &SKGMainPanel::refresh, Qt::QueuedConnection);
connect(getDocument(), &SKGDocument::transactionSuccessfullyEnded, this, &SKGMainPanel::notify, Qt::QueuedConnection);
}
connect(d->ui.kContextList, &QListWidget::itemPressed, this, &SKGMainPanel::onBeforeOpenContext);
connect(d->ui.kContextList, &QListWidget::itemPressed, this, &SKGMainPanel::onOpenContext);
connect(d->m_tabWidget->tabBar(), &QTabBar::tabCloseRequested, this, &SKGMainPanel::closePageByIndex);
connect(d->m_tabWidget->tabBar(), &QTabBar::tabBarClicked, this, [ = ](int index) {
if ((QApplication::mouseButtons() & Qt::MidButton) != 0u) {
closePageByIndex(index);
}
});
connect(d->m_tabWidget->tabBar(), &QTabBar::tabBarDoubleClicked, this, &SKGMainPanel::addTab);
connect(d->m_tabWidget->tabBar(), &QTabBar::currentChanged, this, &SKGMainPanel::currentPageChanged);
connect(this, &SKGMainPanel::currentPageChanged, this, &SKGMainPanel::refresh);
connect(this, &SKGMainPanel::currentPageChanged, this, &SKGMainPanel::selectionChanged);
// Refresh
refresh();
d->ui.kContextList->installEventFilter(this);
// Build contextual menu
d->ui.kContextList->setContextMenuPolicy(Qt::CustomContextMenu);
d->m_contextMenu = new QMenu(d->ui.kContextList);
d->m_actHideContextItem = d->m_contextMenu->addAction(SKGServices::fromTheme(QStringLiteral("layer-visible-off")), i18nc("Verb", "Hide"));
connect(d->m_actHideContextItem, &QAction::triggered, this, &SKGMainPanel::onHideContextItem);
d->m_actShowAllContextItems = d->m_contextMenu->addAction(SKGServices::fromTheme(QStringLiteral("layer-visible-on")), i18nc("Verb", "Show all"));
connect(d->m_actShowAllContextItems, &QAction::triggered, this, &SKGMainPanel::onShowAllContextItems);
d->m_contextMenu->addSeparator();
d->m_contextMenu->addAction(getGlobalAction(QStringLiteral("tab_savedefaultstate")));
d->m_contextMenu->addAction(getGlobalAction(QStringLiteral("tab_resetdefaultstate")));
connect(d->ui.kContextList, &QListWidget::customContextMenuRequested, this, &SKGMainPanel::showMenu);
#ifdef KActivities_FOUND
// Initialize kactivities resource instance
d->m_activityResourceInstance = new KActivities::ResourceInstance(window()->winId());
d->m_activityResourceInstance->setParent(this);
#endif
// Show menu bar and status bar
menuBar()->show();
statusBar()->show();
notify(); // Due to sendMessage not in a transaction
d->m_splashScreen = nullptr;
}
SKGMainPanel::~SKGMainPanel()
{
SKGTRACEINFUNC(1)
SKGMainPanelPrivate::m_mainPanel = nullptr;
disconnect(getDocument(), nullptr, this, nullptr);
// close plugins
int nb = d->m_pluginsList.count();
for (int i = 0; i < nb; ++i) {
getPluginByIndex(i)->close();
}
if (getDocument() != nullptr) {
getDocument()->close();
}
delete d;
}
void SKGMainPanel::showMenu(const QPoint iPos)
{
if (d->m_contextMenu != nullptr) {
d->m_contextMenu->popup(d->ui.kContextList->mapToGlobal(iPos));
}
}
void SKGMainPanel::setContextVisibility(QListWidgetItem* iItem, bool iVisibility)
{
if (iItem != nullptr) {
// Hide item in context
iItem->setHidden(!iVisibility);
// Hide corresponding action
QAction* act = static_cast< QAction* >(iItem->data(15).value<void*>());
if (act != nullptr) {
act->setVisible(iVisibility);
}
// Save state in settings
SKGInterfacePlugin* plugin = getPluginByIndex(iItem->data(12).toInt());
if (plugin != nullptr) {
KSharedConfigPtr config = KSharedConfig::openConfig();
KConfigGroup pref = config->group("Context Visibility");
pref.writeEntry(plugin->objectName(), iVisibility);
}
}
}
void SKGMainPanel::setContextVisibility(int iPage, bool iVisibility)
{
setContextVisibility(d->ui.kContextList->item(iPage), iVisibility);
}
void SKGMainPanel::onHideContextItem()
{
setContextVisibility(d->ui.kContextList->currentRow(), false);
}
void SKGMainPanel::onShowAllContextItems()
{
int nb = d->ui.kContextList->count();
for (int i = 0; i < nb; ++i) {
setContextVisibility(i, true);
}
}
SKGDocument* SKGMainPanel::getDocument() const
{
return d->m_currentDocument;
}
QStringList SKGMainPanel::processArguments(const QStringList& iArgument)
{
QStringList output = iArgument;
for (auto plugin : qAsConst(d->m_pluginsList)) {
if (plugin != nullptr) {
output = plugin->processArguments(output);
}
}
return output;
}
void SKGMainPanel::registerGlobalAction(const QString& iIdentifier, QAction* iAction, bool iAddInCollection,
const QStringList& iListOfTable, int iMinSelection, int iMaxSelection,
int iRanking, bool iSelectionMustHaveFocus)
{
if (iAction == nullptr) {
SKGTRACE << "WARNING: registerGlobalAction(" << iIdentifier << ",nullptr)" << endl;
} else {
QStringList keys = d->m_registeredGlogalAction.keys();
for (const auto& id : qAsConst(keys)) {
QPointer<QAction> act = d->m_registeredGlogalAction.value(id).action;
if ((act != nullptr) && iIdentifier != id && act != iAction && !act->shortcut().isEmpty() && act->shortcut() == iAction->shortcut()) {
SKGTRACE << "WARNING: The actions [" << iAction->text() << " (" << iIdentifier << ")] and [" << act->text() << " (" << id << ")] has same shortcut [" << iAction->shortcut().toString() << "]" << endl;
}
}
actionDetails actDetails;
actDetails.action = iAction;
actDetails.tables = iListOfTable;
actDetails.min = iMinSelection;
actDetails.max = iMaxSelection;
actDetails.focus = iSelectionMustHaveFocus;
actDetails.ranking = (iRanking == -1 ? 10 * (d->m_registeredGlogalAction.count() + 1) : iRanking);
d->m_registeredGlogalAction[iIdentifier] = actDetails;
// This connect has not been migrated on new connect mechanism to avoid crash when leaving the application
connect(iAction, SIGNAL(destroyed(QObject*)), this, SLOT(unRegisterGlobalAction(QObject*))); // clazy:exclude=old-style-connect
if (iAddInCollection) {
QKeySequence shortCut = iAction->shortcut();
if (!shortCut.isEmpty()) {
iAction->setShortcut(QKeySequence());
}
actionCollection()->addAction(iIdentifier, iAction);
if (!shortCut.isEmpty()) {
actionCollection()->setDefaultShortcut(iAction, shortCut);
}
}
}
}
void SKGMainPanel::unRegisterGlobalAction(QObject* iAction)
{
auto* act = qobject_cast< QAction* >(iAction);
if (act != nullptr) {
const auto keys = d->m_registeredGlogalAction.keys();
for (const auto& id : keys) {
if (d->m_registeredGlogalAction.value(id).action == QPointer<QAction>(act)) {
d->m_registeredGlogalAction.remove(id);
}
}
}
}
QPointer<QAction> SKGMainPanel::getGlobalAction(const QString& iIdentifier, bool iWarnIfNotExist)
{
QAction* act = d->m_registeredGlogalAction.value(iIdentifier).action;
if (act == nullptr && iWarnIfNotExist) {
SKGTRACE << "WARNING: getGlobalAction(" << iIdentifier << ")=nullptr" << endl;
}
return act;
}
QList< QPointer< QAction > > SKGMainPanel::getActionsForContextualMenu(const QString& iTable)
{
// Filter action
QVector<actionDetails> tmp;
for (const auto& actDetails : qAsConst(d->m_registeredGlogalAction)) {
if (actDetails.ranking > 0 && actDetails.min > 0) {
if (actDetails.tables.isEmpty() || actDetails.tables.contains(iTable)) {
tmp.push_back(actDetails);
} else if (actDetails.tables.count() == 1 && actDetails.tables.at(0).startsWith(QLatin1String("query:"))) {
// Dynamic mode
QStringList tmpListTable;
getDocument()->getDistinctValues(QStringLiteral("sqlite_master"), QStringLiteral("name"), actDetails.tables.at(0).right(actDetails.tables.at(0).count() - 6), tmpListTable);
if (tmpListTable.contains(iTable)) {
tmp.push_back(actDetails);
}
}
}
}
// Sort
std::sort(tmp.begin(), tmp.end(), [&](const actionDetails & a, const actionDetails & b) {
return a.ranking < b.ranking;
});
// Generate output
int previousGroup = -1;
QList< QPointer< QAction > > output;
output.reserve(tmp.count());
for (const auto& actDetails : qAsConst(tmp)) {
int currentGroup = (actDetails.ranking) / 100;
if (currentGroup != previousGroup) {
output.push_back(nullptr);
previousGroup = currentGroup;
}
output.push_back(actDetails.action);
}
return output;
}
QMap<QString, QPointer<QAction> > SKGMainPanel::getGlobalActions() const
{
QMap<QString, QPointer<QAction> > map;
const auto keys = d->m_registeredGlogalAction.keys();
for (const auto& id : keys) {
map[id] = d->m_registeredGlogalAction[id].action;
}
return map;
}
SKGInterfacePlugin* SKGMainPanel::getPluginByIndex(int iIndex)
{
SKGInterfacePlugin* output = nullptr;
if (iIndex >= 0 && iIndex < d->m_pluginsList.count()) {
output = d->m_pluginsList.value(iIndex);
}
return output;
}
SKGInterfacePlugin* SKGMainPanel::getPluginByName(const QString& iName)
{
SKGInterfacePlugin* output = nullptr;
int nbplugin = d->m_pluginsList.count();
QString name = iName.toLower();
for (int j = 0; (output == nullptr) && j < nbplugin; ++j) {
QString namep = d->m_pluginsList.at(j)->objectName().toLower();
if (namep == name || namep.replace(' ', '_') == name) {
output = d->m_pluginsList.at(j);
}
}
return output;
}
void SKGMainPanel::setupActions()
{
SKGTRACEINFUNC(1)
// Std File
KStandardAction::quit(this, SLOT(onQuitAction()), actionCollection());
KStandardAction::configureNotifications(this, SLOT(onConfigureNotifications()), actionCollection());
// Preferences
KStandardAction::preferences(this, SLOT(optionsPreferences()), actionCollection());
// New Tab
auto actAddTab = new QAction(SKGServices::fromTheme(QStringLiteral("tab-new-background")), i18nc("Noun, user action", "New Tab"), this);
actionCollection()->setDefaultShortcut(actAddTab, Qt::CTRL + Qt::SHIFT + Qt::Key_W);
connect(actAddTab, &QAction::triggered, this, &SKGMainPanel::addTab);
registerGlobalAction(QStringLiteral("new_tab"), actAddTab, true, QStringList(), -1);
// Add new tab widget
auto addTabButton = new QToolButton(this);
addTabButton->setIcon(actAddTab->icon());
addTabButton->setAutoRaise(true);
addTabButton->raise();
addTabButton->setDefaultAction(actAddTab);
addTabButton->setToolButtonStyle(Qt::ToolButtonIconOnly);
addTabButton->setFocusPolicy(Qt::NoFocus);
d->m_tabWidget->setCornerWidget(addTabButton);
d->m_actLock = new QAction(SKGServices::fromTheme(QStringLiteral("document-encrypt")), i18nc("Verb", "Lock panels"), this);
connect(d->m_actLock, &QAction::triggered, this, &SKGMainPanel::onLockDocks);
registerGlobalAction(QStringLiteral("view_lock"), d->m_actLock);
d->m_actUnLock = new QAction(SKGServices::fromTheme(QStringLiteral("document-decrypt")), i18nc("Verb", "Unlock panels"), this);
connect(d->m_actUnLock, &QAction::triggered, this, &SKGMainPanel::onUnlockDocks);
registerGlobalAction(QStringLiteral("view_unlock"), d->m_actUnLock);
d->m_switchPinState = new QAction(SKGServices::fromTheme(QStringLiteral("document-encrypt")), i18nc("Noun, user action", "Pin this page"), this);
connect(d->m_switchPinState, &QAction::triggered, this, [ = ] {this->switchPinPage(nullptr);});
registerGlobalAction(QStringLiteral("tab_switchpin"), d->m_switchPinState);
//
d->m_closePageAction = actionCollection()->addAction(KStandardAction::Close, QStringLiteral("tab_close"), this, SLOT(closeCurrentPage()));
registerGlobalAction(QStringLiteral("tab_close"), d->m_closePageAction);
//
auto actCloseAllPages = new QAction(SKGServices::fromTheme(QStringLiteral("window-close")), i18nc("Noun, user action", "Close All"), this);
actionCollection()->setDefaultShortcut(actCloseAllPages, Qt::ALT + Qt::Key_W);
connect(actCloseAllPages, &QAction::triggered, this, &SKGMainPanel::closeAllPages);
registerGlobalAction(QStringLiteral("tab_closeall"), actCloseAllPages, true, QStringList(), -1);
//
d->m_closeAllOtherPagesAction = new QAction(SKGServices::fromTheme(QStringLiteral("window-close")), i18nc("Noun, user action", "Close All Other"), this);
actionCollection()->setDefaultShortcut(d->m_closeAllOtherPagesAction, Qt::CTRL + Qt::ALT + Qt::Key_W);
connect(d->m_closeAllOtherPagesAction, &QAction::triggered, this, [ = ] {this->closeAllOtherPages(nullptr);});
registerGlobalAction(QStringLiteral("tab_closeallother"), d->m_closeAllOtherPagesAction);
//
d->m_saveDefaultStateAction = new QAction(SKGServices::fromTheme(QStringLiteral("document-save")), i18nc("Noun, user action", "Save page state"), this);
actionCollection()->setDefaultShortcut(d->m_saveDefaultStateAction, Qt::CTRL + Qt::ALT + Qt::Key_S);
connect(d->m_saveDefaultStateAction, &QAction::triggered, this, &SKGMainPanel::saveDefaultState);
registerGlobalAction(QStringLiteral("tab_savedefaultstate"), d->m_saveDefaultStateAction);
//
d->m_resetDefaultStateAction = new QAction(SKGServices::fromTheme(QStringLiteral("edit-clear")), i18nc("Noun, user action", "Reset page state"), this);
actionCollection()->setDefaultShortcut(d->m_resetDefaultStateAction, Qt::CTRL + Qt::ALT + Qt::Key_R);
connect(d->m_resetDefaultStateAction, &QAction::triggered, this, &SKGMainPanel::resetDefaultState);
registerGlobalAction(QStringLiteral("tab_resetdefaultstate"), d->m_resetDefaultStateAction);
//
d->m_reopenLastClosed = new QAction(SKGServices::fromTheme(QStringLiteral("tab-new")), i18nc("Noun, user action", "Reopen last page closed"), this);
actionCollection()->setDefaultShortcut(d->m_reopenLastClosed, Qt::CTRL + Qt::ALT + Qt::Key_T);
connect(d->m_reopenLastClosed, &QAction::triggered, this, &SKGMainPanel::onReopenLastClosed);
registerGlobalAction(QStringLiteral("tab_reopenlastclosed"), d->m_reopenLastClosed);
//
QStringList overlay;
overlay.push_back(QStringLiteral("bookmarks"));
d->m_overwriteBookmarkStateAction = new QAction(SKGServices::fromTheme(QStringLiteral("document-save"), overlay), i18nc("Noun, user action", "Overwrite bookmark state"), this);
connect(d->m_overwriteBookmarkStateAction, &QAction::triggered, this, &SKGMainPanel::overwriteBookmarkState);
actionCollection()->setDefaultShortcut(d->m_overwriteBookmarkStateAction, Qt::CTRL + Qt::ALT + Qt::Key_B);
registerGlobalAction(QStringLiteral("tab_overwritebookmark"), d->m_overwriteBookmarkStateAction);
//
d->m_configureAction = new QAction(SKGServices::fromTheme(QStringLiteral("configure")), i18nc("Noun, user action", "Configure..."), this);
connect(d->m_configureAction, &QAction::triggered, this, [ = ] {this->optionsPreferences();});
registerGlobalAction(QStringLiteral("tab_configure"), d->m_configureAction);
// Menu
d->m_buttonMenuAction = new KToolBarPopupAction(SKGServices::fromTheme(QStringLiteral("configure")), QLatin1String(""), this);
d->m_buttonMenuAction->setToolTip(i18nc("Noun, user action", "Menu"));
d->m_buttonMenu = d->m_buttonMenuAction->menu();
connect(d->m_buttonMenu, &QMenu::aboutToShow, this, &SKGMainPanel::onShowButtonMenu);
d->m_buttonMenuAction->setDelayed(false);
registerGlobalAction(QStringLiteral("view_menu"), d->m_buttonMenuAction);
d->m_showMenuBarAction = KStandardAction::showMenubar(this, SLOT(onShowMenuBar()), actionCollection());
KConfigGroup pref = getMainConfigGroup();
d->m_showMenuBarAction->setChecked(pref.readEntry("menubar_shown", true));
QTimer::singleShot(200, Qt::CoarseTimer, this, &SKGMainPanel::onShowMenuBar);
registerGlobalAction(QStringLiteral("options_show_menubar"), d->m_showMenuBarAction);
//
d->m_previousAction = new KToolBarPopupAction(SKGServices::fromTheme(QStringLiteral("go-previous")), i18nc("Noun, user action", "Previous"), this);
connect(d->m_previousAction, &QAction::triggered, this, &SKGMainPanel::onPrevious);
actionCollection()->setDefaultShortcut(d->m_previousAction, Qt::ALT + Qt::Key_Left);
d->m_previousAction->setPriority(QAction::LowPriority);
d->m_previousMenu = d->m_previousAction->menu();
connect(d->m_previousMenu, &QMenu::aboutToShow, this, &SKGMainPanel::onShowPreviousMenu);
d->m_previousAction->setStickyMenu(false);
d->m_previousAction->setData(0);
registerGlobalAction(QStringLiteral("go_previous"), d->m_previousAction);
//
d->m_nextAction = new KToolBarPopupAction(SKGServices::fromTheme(QStringLiteral("go-next")), i18nc("Noun, user action", "Next"), this);
connect(d->m_nextAction, &QAction::triggered, this, &SKGMainPanel::onNext);
actionCollection()->setDefaultShortcut(d->m_nextAction, Qt::ALT + Qt::Key_Right);
d->m_nextAction->setPriority(QAction::LowPriority);
d->m_nextMenu = d->m_nextAction->menu();
connect(d->m_nextMenu, &QMenu::aboutToShow, this, &SKGMainPanel::onShowNextMenu);
d->m_nextAction->setStickyMenu(false);
d->m_nextAction->setData(0);
registerGlobalAction(QStringLiteral("go_next"), d->m_nextAction);
//
d->m_fullScreenAction = actionCollection()->addAction(KStandardAction::FullScreen, QStringLiteral("fullscreen"), this, SLOT(onFullScreen()));
registerGlobalAction(QStringLiteral("fullscreen"), d->m_fullScreenAction);
//
d->m_enableEditorAction = new QAction(SKGServices::fromTheme(QStringLiteral("appointment-new")), i18nc("Noun, user action", "Enable editor"), this);
actionCollection()->setDefaultShortcut(d->m_enableEditorAction, Qt::CTRL + Qt::Key_Insert);
connect(d->m_enableEditorAction, &QAction::triggered, this, &SKGMainPanel::enableEditor);
registerGlobalAction(QStringLiteral("enable_editor"), d->m_enableEditorAction);
//
auto migrateSQLCipher = new QAction(SKGServices::fromTheme(QStringLiteral("run-build")), i18nc("Noun, user action", "Migrate to SQLCipher format"), this);
connect(migrateSQLCipher, &QAction::triggered, this, &SKGMainPanel::onMigrateToSQLCipher);
registerGlobalAction(QStringLiteral("migrate_sqlcipher"), migrateSQLCipher);
// Contextual menu
d->m_tabWidget->setContextMenuPolicy(Qt::ActionsContextMenu);
d->m_tabWidget->insertAction(nullptr, getGlobalAction(QStringLiteral("new_tab")));
d->m_tabWidget->insertAction(nullptr, getGlobalAction(QStringLiteral("tab_reopenlastclosed")));
d->m_tabWidget->insertAction(nullptr, getGlobalAction(QStringLiteral("tab_close")));
d->m_tabWidget->insertAction(nullptr, getGlobalAction(QStringLiteral("tab_closeall")));
d->m_tabWidget->insertAction(nullptr, getGlobalAction(QStringLiteral("tab_closeallother")));
{
auto sep = new QAction(this);
sep->setSeparator(true);
d->m_tabWidget->insertAction(nullptr, sep);
}
d->m_tabWidget->insertAction(nullptr, getGlobalAction(QStringLiteral("tab_switchpin")));
d->m_tabWidget->insertAction(nullptr, getGlobalAction(QStringLiteral("tab_resetdefaultstate")));
d->m_tabWidget->insertAction(nullptr, getGlobalAction(QStringLiteral("tab_savedefaultstate")));
d->m_tabWidget->insertAction(nullptr, getGlobalAction(QStringLiteral("tab_overwritebookmark")));
d->m_tabWidget->insertAction(nullptr, getGlobalAction(QStringLiteral("tab_configure")));
{
auto sep = new QAction(this);
sep->setSeparator(true);
d->m_tabWidget->insertAction(nullptr, sep);
}
d->m_tabWidget->insertAction(nullptr, getGlobalAction(QStringLiteral("fullscreen")));
}
void SKGMainPanel::enableEditor()
{
SKGTabPage* cPage = currentPage();
if (cPage != nullptr) {
cPage->activateEditor();
}
}
void SKGMainPanel::onPrevious()
{
SKGError err;
SKGTRACEINFUNCRC(10, err)
SKGTabPage* cPage = currentPage();
if (cPage != nullptr) {
// Get index in history of page to refresh
int indexPrevious = qobject_cast<QAction*>(sender())->data().toInt();
// Get lists
SKGTabPage::SKGPageHistoryItemList listPrevious = cPage->getPreviousPages();
if (indexPrevious < listPrevious.count()) {
SKGTabPage::SKGPageHistoryItemList listNext = cPage->getNextPages();
SKGTabPage::SKGPageHistoryItem current = currentPageHistoryItem();
// Get item to refresh
SKGTabPage::SKGPageHistoryItem item = listPrevious.at(indexPrevious);
// Open page
cPage = openPage(getPluginByName(item.plugin), currentPageIndex(), item.state, item.name, item.bookmarkID);
if (cPage != nullptr) {
cPage->setBookmarkID(item.bookmarkID);
// Update lists
listNext.insert(0, current);
listPrevious.removeAt(indexPrevious);
for (int i = 0; i < indexPrevious; ++i) {
SKGTabPage::SKGPageHistoryItem itemPrevious = listPrevious.at(0); // Because the list is modified
listNext.insert(0, itemPrevious);
listPrevious.removeAt(0);
}
// Set lists
cPage->setPreviousPages(listPrevious);
cPage->setNextPages(listNext);
}
refresh();
}
}
}
void SKGMainPanel::onShowPreviousMenu()
{
if (d->m_previousMenu != nullptr) {
d->m_previousMenu->clear();
SKGTabPage* cPage = currentPage();
if (cPage != nullptr) {
SKGTabPage::SKGPageHistoryItemList list = cPage->getPreviousPages();
int nb = list.count();
for (int i = 0; i < nb; ++i) {
QAction* act = d->m_previousMenu->addAction(SKGServices::fromTheme(list.at(i).icon), list.at(i).name);
if (act != nullptr) {
act->setData(i);
connect(act, &QAction::triggered, this, &SKGMainPanel::onPrevious);
}
}
}
}
}
void SKGMainPanel::onShowMenuBar()
{
bool test = d->m_showMenuBarAction->isChecked();
menuBar()->setVisible(test);
d->m_buttonMenuAction->setVisible(!test);
KConfigGroup pref = getMainConfigGroup();
pref.writeEntry("menubar_shown", test);
}
void SKGMainPanel::onFullScreen()
{
auto* p = d->m_tabWidget;
if (p != nullptr) {
if (!d->m_fullScreenAction->isChecked()) {
// No Full screen
p->setWindowState(p->windowState() & ~Qt::WindowFullScreen); // reset
d->m_mainLayout->addWidget(d->m_tabWidget);
} else {
bool atLeastOnePageOpened = (d->m_tabWidget->count() > 0);
if (atLeastOnePageOpened) {
// Activate Full screen mode
p->setParent(nullptr);
p->setWindowFlags(p->windowFlags() | Qt::CustomizeWindowHint | Qt::WindowStaysOnTopHint | Qt::WindowMaximizeButtonHint | Qt::WindowCloseButtonHint);
p->setWindowState(p->windowState() | Qt::WindowFullScreen); // set
p->show();
displayMessage(i18nc("Information message", "You can exit full screen mode with %1 or with the contextual menu", d->m_fullScreenAction->shortcut().toString()));
} else {
d->m_fullScreenAction->setChecked(false);
displayMessage(i18nc("Information message", "At least one page must be opened to enable full screen mode"), SKGDocument::Error);
}
}
}
}
void SKGMainPanel::onNext()
{
SKGError err;
SKGTRACEINFUNCRC(10, err)
SKGTabPage* cPage = currentPage();
if (cPage != nullptr) {
// Get index in history of page to refresh
int posNext = qobject_cast<QAction*>(sender())->data().toInt();
// Get lists
SKGTabPage::SKGPageHistoryItemList listPrevious = cPage->getPreviousPages();
SKGTabPage::SKGPageHistoryItemList listNext = cPage->getNextPages();
SKGTabPage::SKGPageHistoryItem current = currentPageHistoryItem();
// Get item to refresh
SKGTabPage::SKGPageHistoryItem item = listNext.at(posNext);
// Open page
cPage = openPage(getPluginByName(item.plugin), currentPageIndex(), item.state, item.name, item.bookmarkID);
if (cPage != nullptr) {
cPage->setBookmarkID(item.bookmarkID);
// Update lists
listPrevious.insert(0, current);
listNext.removeAt(posNext);
for (int i = 0; i < posNext; ++i) {
SKGTabPage::SKGPageHistoryItem itemNext = listNext.at(0); // Because the list is modified
listPrevious.insert(0, itemNext);
listNext.removeAt(0);
}
// Set lists
cPage->setPreviousPages(listPrevious);
cPage->setNextPages(listNext);
}
refresh();
}
}
void SKGMainPanel::onReopenLastClosed()
{
SKGError err;
SKGTRACEINFUNCRC(10, err)
SKGTabPage::SKGPageHistoryItem current = currentPageHistoryItem();
// Get item to refresh
historyPage item = d->m_historyClosedPages.takeLast();
// Open page
SKGTabPage* cPage = openPage(getPluginByName(item.current.plugin), -1, item.current.state, item.current.name, item.current.bookmarkID);
if (cPage != nullptr) {
cPage->setBookmarkID(item.current.bookmarkID);
cPage->setNextPages(item.next);
cPage->setPreviousPages(item.previous);
}
refresh();
}
void SKGMainPanel::onLockDocks()
{
QObjectList cs = children();
for (auto c : qAsConst(cs)) {
auto* doc = qobject_cast<QDockWidget*>(c);
if (doc != nullptr) {
doc->setFeatures(QDockWidget::NoDockWidgetFeatures);
}
}
KConfigGroup pref = getMainConfigGroup();
pref.writeEntry("docks_locked", true);
refresh();
}
void SKGMainPanel::onUnlockDocks()
{
QObjectList cs = children();
for (auto c : qAsConst(cs)) {
auto* doc = qobject_cast<QDockWidget*>(c);
if (doc != nullptr) {
doc->setFeatures(QDockWidget::AllDockWidgetFeatures);
}
}
KConfigGroup pref = getMainConfigGroup();
pref.writeEntry("docks_locked", false);
refresh();
}
void SKGMainPanel::onConfigureNotifications()
{
KNotifyConfigWidget::configure(this);
}
void SKGMainPanel::onShowNextMenu()
{
if (d->m_nextMenu != nullptr) {
d->m_nextMenu->clear();
SKGTabPage* cPage = currentPage();
if (cPage != nullptr) {
SKGTabPage::SKGPageHistoryItemList list = cPage->getNextPages();
int nb = list.count();
for (int i = 0; i < nb; ++i) {
QAction* act = d->m_nextMenu->addAction(SKGServices::fromTheme(list.at(i).icon), list.at(i).name);
if (act != nullptr) {
act->setData(i);
connect(act, &QAction::triggered, this, &SKGMainPanel::onNext);
}
}
}
}
}
void SKGMainPanel::onShowButtonMenu()
{
if (d->m_buttonMenu != nullptr) {
d->m_buttonMenu->clear();
QMenuBar* mb = menuBar();
if (mb != nullptr) {
d->m_buttonMenu->addActions(mb->actions());
}
}
}
bool SKGMainPanel::queryClose()
{
SKGTRACEINFUNC(1)
// Bug 2777697: To be sure that all page modifications are closed
closeAllPages();
// Bug 2777697:
bool output = queryFileClose();
// To be sure that the application is not closed in fullscreen mode
if (output) {
if (d->m_fullScreenAction->isChecked()) {
d->m_fullScreenAction->trigger();
}
}
return output;
}
void SKGMainPanel::setSaveOnClose(bool iSaveOnClose)
{
d->m_saveOnClose = iSaveOnClose;
}
bool SKGMainPanel::queryFileClose()
{
SKGTRACEINFUNC(1)
bool output = true;
if (getDocument()->getCurrentTransaction() != 0) {
displayMessage(i18nc("skgtestimportskg", "The application cannot be closed when an operation is running."), SKGDocument::Error);
output = false;
} else if (getDocument()->isFileModified()) {
QApplication::setOverrideCursor(QCursor(Qt::ArrowCursor));
int code = KMessageBox::Yes;
QString fileName = getDocument()->getCurrentFileName();
QAction* save = getGlobalAction(fileName.isEmpty() ? QStringLiteral("file_save_as") : QStringLiteral("file_save"));
if (save != nullptr) {
if (!d->m_saveOnClose) {
code = KMessageBox::questionYesNoCancel(this, i18nc("Question", "The document has been modified.\nDo you want to save it before closing?"),
QString(),
KGuiItem(fileName.isEmpty() ? i18nc("Question", "Save as") : i18nc("Question", "Save"),
SKGServices::fromTheme(fileName.isEmpty() ? QStringLiteral("document-save-as") : QStringLiteral("document-save"))),
KGuiItem(i18nc("Question", "Do not save")));
}
if (code == KMessageBox::Yes) {
save->trigger();
}
output = (code == KMessageBox::No || code == KMessageBox::Yes);
} else {
code = KMessageBox::questionYesNo(this, i18nc("Question", "Current modifications will not be saved.\nDo you want to continue?"));
output = (code == KMessageBox::Yes);
}
QApplication::restoreOverrideCursor();
}
return output;
}
SKGObjectBase SKGMainPanel::getFirstSelectedObject() const
{
SKGObjectBase selection;
SKGWidget* cPage = (d->m_widgetHavingSelection != nullptr ? d->m_widgetHavingSelection : currentPage());
if (cPage != nullptr) {
selection = cPage->getFirstSelectedObject();
}
return selection;
}
SKGObjectBase::SKGListSKGObjectBase SKGMainPanel::getSelectedObjects() const
{
SKGObjectBase::SKGListSKGObjectBase selection;
SKGWidget* cPage = (d->m_widgetHavingSelection != nullptr ? d->m_widgetHavingSelection : currentPage());
if (cPage != nullptr) {
selection = cPage->getSelectedObjects();
}
return selection;
}
int SKGMainPanel::getNbSelectedObjects() const
{
int nb = 0;
SKGWidget* cPage = (d->m_widgetHavingSelection != nullptr ? d->m_widgetHavingSelection : currentPage());
if (cPage != nullptr) {
nb = cPage->getNbSelectedObjects();
}
return nb;
}
bool SKGMainPanel::hasSelectionWithFocus()
{
bool output = false;
SKGWidget* cPage = (d->m_widgetHavingSelection != nullptr ? d->m_widgetHavingSelection : currentPage());
if (cPage != nullptr) {
output = cPage->hasSelectionWithFocus();
}
return output;
}
SKGAdviceList SKGMainPanel::getAdvice() const
{
SKGTRACEINFUNC(1)
// Get list of ignored advice
QString currentMonth = QDate::currentDate().toString(QStringLiteral("yyyy-MM"));
QStringList ignoredAdvice = getDocument()->getParameters(QStringLiteral("advice"), "t_value='I' OR t_value='I_" % currentMonth % '\'');
// Build the list of all advice by requesting all plugins
SKGAdviceList globalAdviceList;
int index = 0;
while (index >= 0) {
SKGInterfacePlugin* plugin = SKGMainPanel::getMainPanel()->getPluginByIndex(index);
if (plugin != nullptr) {
const auto list = plugin->advice(ignoredAdvice);
for (const auto& ad : list) {
if (!ignoredAdvice.contains(ad.getUUID()) && !ignoredAdvice.contains(SKGServices::splitCSVLine(ad.getUUID(), '|').at(0))) {
globalAdviceList.push_back(ad);
}
}
} else {
index = -2;
}
++index;
}
std::sort(globalAdviceList.begin(), globalAdviceList.end(), SKGMainPanelPrivate::adviceLessThan);
return globalAdviceList;
}
KConfigGroup SKGMainPanel::getMainConfigGroup()
{
KSharedConfigPtr config = KSharedConfig::openConfig();
return config->group("Main Panel");
}
void SKGMainPanel::optionsPreferences(const QString& iPluginName)
{
SKGTRACEINFUNC(1)
// Compute page
QString pluginName = iPluginName;
if (pluginName.isEmpty()) {
auto* act = qobject_cast<QAction*>(sender());
if (act != nullptr) {
pluginName = act->property("page").toString();
}
}
if (pluginName.isEmpty() && (this->currentPage() != nullptr)) {
pluginName = this->currentPage()->objectName();
}
SKGTRACEL(1) << "Open setting page: " << pluginName << endl;
// Synchronize setting with confirmation panel
if (skgbasegui_settings::update_modified_bookmarks() == 0) {
KMessageBox::ButtonCode confirm;
bool ask = KMessageBox::shouldBeShownYesNo(QStringLiteral("updateBookmarkOnClose"), confirm);
KConfigGroup pref = getMainConfigGroup();
if (ask) {
pref.writeEntry("update_modified_bookmarks", 0, KConfigBase::Normal);
SKGTRACEL(1) << "update_modified_bookmarks set to ASK" << endl;
} else if (confirm == KMessageBox::Yes) {
pref.writeEntry("update_modified_bookmarks", 1, KConfigBase::Normal);
SKGTRACEL(1) << "update_modified_bookmarks set to ALWAYS" << endl;
} else {
pref.writeEntry("update_modified_bookmarks", 2, KConfigBase::Normal);
SKGTRACEL(1) << "update_modified_bookmarks set to NEVER" << endl;
}
}
if (skgbasegui_settings::update_modified_contexts() == 0) {
KMessageBox::ButtonCode confirm;
bool ask = KMessageBox::shouldBeShownYesNo(QStringLiteral("updateContextOnClose"), confirm);
KConfigGroup pref = getMainConfigGroup();
if (ask) {
pref.writeEntry("update_modified_contexts", 0, KConfigBase::Normal);
SKGTRACEL(1) << "update_modified_contexts set to ASK" << endl;
} else if (confirm == KMessageBox::Yes) {
pref.writeEntry("update_modified_contexts", 1, KConfigBase::Normal);
SKGTRACEL(1) << "update_modified_contexts set to ALWAYS" << endl;
} else {
pref.writeEntry("update_modified_contexts", 2, KConfigBase::Normal);
SKGTRACEL(1) << "update_modified_contexts set to NEVER" << endl;
}
}
skgbasegui_settings::self()->load();
if (KConfigDialog::showDialog(QStringLiteral("settings"))) {
return;
}
auto dialog = new KConfigDialog(this, QStringLiteral("settings"), skgbasegui_settings::self());
// Add main
auto w = new QWidget();
d->uipref.setupUi(w);
d->uipref.kcfg_date_format->addItem(i18nc("Date format", "Short date (%1, %2)",
QLocale().toString(QDate::currentDate(), QLocale::ShortFormat),
QLocale().toString(QDate::currentDate().addDays(-10), QLocale::ShortFormat)));
d->uipref.kcfg_date_format->addItem(i18nc("Date format", "Long date (%1, %2)",
QLocale().toString(QDate::currentDate(), QLocale::LongFormat),
QLocale().toString(QDate::currentDate().addDays(-10), QLocale::LongFormat)));
d->uipref.kcfg_date_format->addItem(i18nc("Date format", "Fancy short date (%1, %2)",
KFormat().formatRelativeDate(QDate::currentDate(), QLocale::ShortFormat),
KFormat().formatRelativeDate(QDate::currentDate().addDays(-10), QLocale::ShortFormat)));
d->uipref.kcfg_date_format->addItem(i18nc("Date format", "Fancy long date (%1, %2)",
KFormat().formatRelativeDate(QDate::currentDate(), QLocale::LongFormat),
KFormat().formatRelativeDate(QDate::currentDate().addDays(-10), QLocale::LongFormat)));
d->uipref.kcfg_date_format->addItem(i18nc("Date format", "ISO date (%1, %2)",
QDate::currentDate().toString(Qt::ISODate),
QDate::currentDate().addDays(-10).toString(Qt::ISODate)));
dialog->addPage(w, skgbasegui_settings::self(), i18nc("Noun", "General"), QStringLiteral("preferences-other"));
// Add plugin in client in right order
int nbplugin = d->m_pluginsList.count();
for (int j = 0; j < nbplugin; ++j) {
SKGInterfacePlugin* pluginInterface = getPluginByIndex(j);
if (pluginInterface != nullptr) {
QWidget* w2 = pluginInterface->getPreferenceWidget();
if (w2 != nullptr) {
auto icon = SKGServices::fromTheme(pluginInterface->icon());
KPageWidgetItem* p = dialog->addPage(w2, pluginInterface->getPreferenceSkeleton(), pluginInterface->title(), icon.name());
if ((p != nullptr) && pluginName == pluginInterface->objectName()) {
dialog->setCurrentPage(p);
}
}
}
}
connect(dialog, &KConfigDialog::settingsChanged, this, &SKGMainPanel::onSettingsChanged);
dialog->setAttribute(Qt::WA_DeleteOnClose);
dialog->show();
// Refresh
refresh();
}
void SKGMainPanel::onSettingsChanged()
{
SKGError err;
SKGTRACEINFUNCRC(1, err) {
int nb = d->m_pluginsList.count();
SKGBEGINPROGRESSTRANSACTION(*getDocument(), i18nc("Noun, name of the user action", "Save settings"), err, nb)
// Refresh plugins
for (int i = 0; !err && i < nb; ++i) {
err = getPluginByIndex(i)->savePreferences();
IFOKDO(err, getDocument()->stepForward(i + 1))
}
// Setting for tab position
d->refreshTabPosition();
// Setting for bookmarks modification
{
int option = skgbasegui_settings::update_modified_bookmarks();
if (option == 0) {
// ASK: remove following setting
KMessageBox::enableMessage(QStringLiteral("updateBookmarkOnClose"));
SKGTRACEL(1) << "updateBookmarkOnClose set to ASK" << endl;
} else if (option == 1) {
// ALWAYS: set following setting
KMessageBox::saveDontShowAgainYesNo(QStringLiteral("updateBookmarkOnClose"), KMessageBox::Yes);
SKGTRACEL(1) << "updateBookmarkOnClose set to Yes" << endl;
} else {
// NEVER: set following setting
KMessageBox::saveDontShowAgainYesNo(QStringLiteral("updateBookmarkOnClose"), KMessageBox::No);
SKGTRACEL(1) << "updateBookmarkOnClose set to No" << endl;
}
}
{
int option = skgbasegui_settings::update_modified_contexts();
if (option == 0) {
// ASK: remove following setting
KMessageBox::enableMessage(QStringLiteral("updateContextOnClose"));
SKGTRACEL(1) << "updateContextOnClose set to ASK" << endl;
} else if (option == 1) {
// ALWAYS: set following setting
KMessageBox::saveDontShowAgainYesNo(QStringLiteral("updateContextOnClose"), KMessageBox::Yes);
SKGTRACEL(1) << "updateContextOnClose set to Yes" << endl;
} else {
// NEVER: set following setting
KMessageBox::saveDontShowAgainYesNo(QStringLiteral("updateContextOnClose"), KMessageBox::No);
SKGTRACEL(1) << "updateContextOnClose set to No" << endl;
}
}
skgbasegui_settings::self()->load();
}
// Rebuild system tray
d->rebuildSystemTray();
emit settingsChanged();
// Display error
displayErrorMessage(err);
}
void SKGMainPanel::refresh()
{
SKGTRACEINFUNC(1)
QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
// Show/hide main widget
bool atLeastOnePageOpened = (d->m_tabWidget->count() > 0);
d->m_tabWidget->setVisible(atLeastOnePageOpened);
if (d->m_mainWidget != nullptr) {
d->m_mainWidget->setVisible(!atLeastOnePageOpened);
}
// Refresh actions
d->m_widgetHavingSelection = qobject_cast<SKGWidget*>(sender());
SKGObjectBase selection = SKGMainPanel::getMainPanel()->getFirstSelectedObject();
int nbSelectedItems = SKGMainPanel::getMainPanel()->getNbSelectedObjects();
bool hasFocus = SKGMainPanel::getMainPanel()->hasSelectionWithFocus();
QString selectedTable = (nbSelectedItems > 0 ? selection.getRealTable() : QLatin1String(""));
for (const auto& actDetails : qAsConst(d->m_registeredGlogalAction)) {
QStringList tables = actDetails.tables;
if (tables.count() == 1 && tables.at(0).startsWith(QLatin1String("query:"))) {
// Dynamic mode
getDocument()->getDistinctValues(QStringLiteral("sqlite_master"), QStringLiteral("name"), tables.at(0).right(tables.at(0).count() - 6), tables);
}
bool enabled = (tables.contains(selectedTable) || tables.isEmpty()) &&
(nbSelectedItems >= actDetails.min) &&
(nbSelectedItems <= actDetails.max || actDetails.max == -1) &&
(!actDetails.focus || hasFocus);
if (enabled && nbSelectedItems == 0 && (actDetails.min == 0 || actDetails.min == -1)) {
// Check if a page is opened
SKGTabPage* page = SKGMainPanel::getMainPanel()->currentPage();
if (page != nullptr) {
auto* view = qobject_cast<QAbstractItemView*>(page->mainWidget());
enabled = (actDetails.min == -1 || view != nullptr);
} else {
enabled = false;
}
}
if (actDetails.action != nullptr) {
actDetails.action->setEnabled(enabled);
}
}
// Refresh plugins
int nb = d->m_pluginsList.count();
for (int i = 0; i < nb; ++i) {
getPluginByIndex(i)->refresh();
}
// Enable addTabeAction
SKGTabPage* toSave = currentPage();
if (d->m_switchPinState != nullptr) {
if ((toSave != nullptr) && toSave->isPin()) {
d->m_switchPinState->setText(i18nc("Noun, user action", "Unpin this page"));
} else {
d->m_switchPinState->setText(i18nc("Noun, user action", "Pin this page"));
}
}
if (d->m_closePageAction != nullptr) {
d->m_closePageAction->setEnabled(atLeastOnePageOpened && (toSave != nullptr) && !toSave->isPin());
}
if (d->m_switchPinState != nullptr) {
d->m_switchPinState->setEnabled(atLeastOnePageOpened);
}
if (d->m_closeAllOtherPagesAction != nullptr) {
d->m_closeAllOtherPagesAction->setEnabled(d->m_tabWidget->count() > 1);
}
if (d->m_reopenLastClosed != nullptr) {
d->m_reopenLastClosed->setEnabled(!d->m_historyClosedPages.isEmpty());
}
if (d->m_saveDefaultStateAction != nullptr) {
d->m_saveDefaultStateAction->setEnabled((toSave != nullptr) && !toSave->getDefaultStateAttribute().isEmpty());
}
if (d->m_resetDefaultStateAction != nullptr) {
d->m_resetDefaultStateAction->setEnabled((toSave != nullptr) && !toSave->getDefaultStateAttribute().isEmpty());
}
if (d->m_overwriteBookmarkStateAction != nullptr) {
d->m_overwriteBookmarkStateAction->setEnabled((toSave != nullptr) && !toSave->getBookmarkID().isEmpty());
}
if (d->m_enableEditorAction != nullptr) {
d->m_enableEditorAction->setEnabled((toSave != nullptr) && toSave->isEditor());
}
if (d->m_zoomSelector != nullptr) {
d->m_zoomSelector->setVisible((toSave != nullptr) && toSave->isZoomable());
if (toSave != nullptr) {
d->m_zoomSelector->setValue(toSave->zoomPosition());
QWidget* zoomWidget = toSave->zoomableWidget();
auto* treeView = qobject_cast<SKGTreeView*>(zoomWidget);
if (treeView != nullptr) {
disconnect(treeView, &SKGTreeView::zoomChanged, nullptr, nullptr);
connect(treeView, &SKGTreeView::zoomChanged, this, [ = ](int val) {
d->m_zoomSelector->setValue(val);
});
} else {
auto* webView = qobject_cast<SKGWebView*>(zoomWidget);
if (webView != nullptr) {
disconnect(webView, &SKGWebView::zoomChanged, nullptr, nullptr);
connect(webView, &SKGWebView::zoomChanged, this, [ = ](int val) {
d->m_zoomSelector->setValue(val);
});
}
}
}
}
if (d->m_actLock != nullptr) {
d->m_actLock->setVisible(d->ui.kDockContext->features() == QDockWidget::AllDockWidgetFeatures);
}
if (d->m_actUnLock != nullptr) {
d->m_actUnLock->setVisible(d->ui.kDockContext->features() == QDockWidget::NoDockWidgetFeatures);
}
if (d->m_previousAction != nullptr) {
SKGTabPage::SKGPageHistoryItemList list;
if (toSave != nullptr) {
list = toSave->getPreviousPages();
}
d->m_previousAction->setEnabled(!list.isEmpty());
}
if (d->m_nextAction != nullptr) {
SKGTabPage::SKGPageHistoryItemList list;
if (toSave != nullptr) {
list = toSave->getNextPages();
}
d->m_nextAction->setEnabled(!list.isEmpty());
}
// Set current selection of context
d->ui.kContextList->clearSelection();
if (toSave != nullptr) {
// Get plugin of current page
SKGInterfacePlugin* plugin = getPluginByName(toSave->objectName());
int index = (plugin != nullptr ? plugin->property("contextItem").toInt() : -1);
if (index != -1) {
d->ui.kContextList->setCurrentItem(d->ui.kContextList->item(index));
}
}
// Set window title
QString modified;
if (getDocument()->isFileModified()) {
modified += i18nc("Noun, indicate that current document is modified", " [modified]");
}
if (getDocument()->isReadOnly()) {
modified += i18nc("Noun, indicate that current document is loaded in read only", " [read only]");
}
QString fileName = getDocument()->getCurrentFileName();
if (fileName.isEmpty()) {
fileName = i18nc("Noun, default name for a new document", "Untitled");
} else {
if (fileName != d->m_fileName) {
// The file name has been changed
onClearMessages();
d->m_fileName = fileName;
#ifdef KActivities_FOUND
if (!d->m_fileName.isEmpty()) {
d->m_activityResourceInstance->setUri(d->m_fileName);
}
#endif
}
}
setWindowTitle(i18nc("Title of the main window", "%1%2", fileName, modified));
QApplication::restoreOverrideCursor();
}
SKGTabPage::SKGPageHistoryItem SKGMainPanel::currentPageHistoryItem() const
{
SKGTabPage::SKGPageHistoryItem cpage;
int currentIndex = currentPageIndex();
SKGTabPage* cPage = currentPage();
if (currentIndex >= 0 && (cPage != nullptr)) {
cpage.plugin = cPage->objectName();
SKGInterfacePlugin* plugin = SKGMainPanel::getMainPanel()->getPluginByName(cpage.plugin);
if (plugin != nullptr) {
cpage.name = d->m_tabWidget->tabText(currentIndex);
cpage.icon = plugin->icon();
}
cpage.state = cPage->getState();
cpage.bookmarkID = cPage->getBookmarkID();
}
return cpage;
}
SKGTabPage* SKGMainPanel::openPage(SKGInterfacePlugin* plugin, int index, const QString& parameters, const QString& title, const QString& iID, bool iSetCurrent)
{
SKGTRACEINFUNC(1)
QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
bool previous = d->m_tabWidget->blockSignals(true);
// If the current page is pin, then open new page
SKGTabPage* cPage = currentPage();
if ((cPage != nullptr) && cPage->isPin()) {
index = -1;
iSetCurrent = true;
}
SKGTabPage* w = nullptr;
SKGTabPage::SKGPageHistoryItemList previousPages;
if (index != -1) {
int currentIndex = currentPageIndex();
if (currentIndex >= 0 && (cPage != nullptr)) {
previousPages = cPage->getPreviousPages();
previousPages.insert(0, currentPageHistoryItem());
d->m_tabWidget->removeTab(currentIndex);
closePage(cPage);
// Repair the history of closed page
if (!d->m_historyClosedPages.isEmpty()) {
d->m_historyClosedPages.removeLast();
}
}
}
if (plugin != nullptr) {
w = plugin->getWidget();
if (w != nullptr) {
// Title
QString title2 = (title.isEmpty() ? plugin->title() : title);
w->setObjectName(plugin->objectName());
if (!iID.isEmpty()) {
w->setBookmarkID(iID);
}
QString param = parameters;
if (param.isEmpty()) {
QString def = w->getDefaultStateAttribute();
if (!def.isEmpty()) {
param = getDocument()->getParameter(def);
}
}
SKGTRACEL(10) << "state=[" << param << "]" << endl;
w->setState(param);
connect(w, &SKGTabPage::selectionChanged, this, &SKGMainPanel::refresh);
connect(w, &SKGTabPage::selectionChanged, this, &SKGMainPanel::selectionChanged);
connect(w, &SKGTabPage::selectionFocusChanged, this, &SKGMainPanel::refresh);
if (index == -1) {
SKGTRACEINFUNC(20)
d->m_tabWidget->addTab(w, SKGServices::fromTheme(plugin->icon()), title2);
if (iSetCurrent) {
d->m_tabWidget->setCurrentWidget(w);
}
} else {
SKGTRACEINFUNC(20)
d->m_tabWidget->insertTab(index, w, SKGServices::fromTheme(plugin->icon()), title2);
if (iSetCurrent) {
d->m_tabWidget->setCurrentWidget(w);
}
w->setPreviousPages(previousPages);
SKGTabPage::SKGPageHistoryItemList empty;
w->setNextPages(empty);
}
SKGTRACEL(1) << "opening plugin [" << plugin->objectName() << ']' << endl;
Q_EMIT pageOpened();
}
} else {
getDocument()->sendMessage(i18nc("An information message", "Impossible to open the page because the plugin was not found"), SKGDocument::Error);
notify(); // Due to sendMessage not in a transaction
}
// Show/hide main widget
bool atLeastOnePageOpened = (d->m_tabWidget->count() > 0);
d->m_tabWidget->setVisible(atLeastOnePageOpened);
if (d->m_mainWidget != nullptr) {
d->m_mainWidget->setVisible(!atLeastOnePageOpened);
}
d->m_tabWidget->blockSignals(previous);
if (iSetCurrent) {
Q_EMIT currentPageChanged();
}
QApplication::restoreOverrideCursor();
return w;
}
int SKGMainPanel::currentPageIndex() const
{
return d->m_tabWidget->currentIndex();
}
SKGTabPage* SKGMainPanel::currentPage() const
{
return qobject_cast< SKGTabPage* >(d->m_tabWidget->currentWidget());
}
int SKGMainPanel::pageIndex(SKGTabPage* iPage) const
{
int nb = countPages();
for (int i = 0; i < nb; ++i) {
if (page(i) == iPage) {
return i;
}
}
return -1;
}
QSplashScreen* SKGMainPanel::splashScreen() const
{
return d->m_splashScreen;
}
int SKGMainPanel::countPages() const
{
return d->m_tabWidget->count();
}
SKGTabPage* SKGMainPanel::page(int iIndex) const
{
return qobject_cast<SKGTabPage*>(d->m_tabWidget->widget(iIndex));
}
void SKGMainPanel::setCurrentPage(int iIndex)
{
d->m_tabWidget->setCurrentIndex(iIndex);
}
void SKGMainPanel::onBeforeOpenContext()
{
d->m_middleClick = ((QApplication::mouseButtons() & Qt::MidButton) != 0u);
}
bool SKGMainPanel::openPage(const QUrl& iUrl, bool iNewPage)
{
const QUrl& url(iUrl);
if (url.scheme() == QStringLiteral("skg")) {
// Get plugin
SKGInterfacePlugin* plugin = getPluginByName(url.host());
if (plugin != nullptr) {
// Open special page
SKGTabPage* w = plugin->getWidget();
if (w != nullptr) {
// Create xml
QString path = url.path().remove('/');
QDomDocument doc(QStringLiteral("SKGML"));
doc.setContent(getDocument()->getParameter(path.isEmpty() ? w->getDefaultStateAttribute() : path));
QDomElement root = doc.documentElement();
if (root.isNull()) {
root = doc.createElement(QStringLiteral("parameters"));
doc.appendChild(root);
}
auto params = QUrlQuery(url).queryItems();
for (const auto& p : qAsConst(params)) {
QString value = QUrl::fromPercentEncoding(p.second.toUtf8());
SKGMainPanelPrivate::setAttribute(root, p.first, value);
}
// Open page
openPage(plugin, iNewPage ? -1 : currentPageIndex(), doc.toString());
return true;
}
} else {
// Trigger action
QAction* act = SKGMainPanel::getMainPanel()->getGlobalAction(url.host());
if (act != nullptr) {
auto params = QUrlQuery(url).queryItems();
for (const auto& p : qAsConst(params)) {
QString value = QUrl::fromPercentEncoding(p.second.toUtf8());
act->setProperty(p.first.toUtf8().data(), value);
}
act->trigger();
return true;
}
}
} else {
QDesktopServices::openUrl(iUrl);
return true;
}
displayErrorMessage(SKGError(ERR_ABORT, i18nc("Error message", "Unknown plugin or action [%1] in url [%2]", url.host(), iUrl.toString())));
return false;
}
bool SKGMainPanel::openPage()
{
return openPage(QString());
}
bool SKGMainPanel::openPage(const QString& iUrl, bool iNewPage)
{
// Get the url
QString urlString(iUrl);
if (urlString.isEmpty()) {
auto* act = qobject_cast< QAction* >(sender());
if (act != nullptr) {
urlString = act->data().toString();
}
}
return openPage(QUrl(urlString), iNewPage);
}
SKGTabPage* SKGMainPanel::openPage(int iPage, bool iNewPage)
{
SKGTRACEINFUNC(1)
SKGTRACEL(1) << "iPage=" << iPage << endl;
int index = d->ui.kContextList->item(iPage)->data(12).toInt();
return openPage(getPluginByIndex(index), iNewPage ? -1 : currentPageIndex());
}
void SKGMainPanel::onOpenContext()
{
SKGTRACEINFUNC(1)
if (!(QApplication::mouseButtons() & Qt::RightButton)) {
int cpage = -1;
auto* s = qobject_cast<QAction*>(this->sender());
if (s != nullptr) {
cpage = s->data().toInt();
} else {
cpage = d->ui.kContextList->currentRow();
}
if (cpage != -1) {
openPage(cpage, ((QApplication::keyboardModifiers() &Qt::ControlModifier) != 0u) || d->m_middleClick || ((QGuiApplication::mouseButtons() & Qt::MidButton) != 0u));
}
}
d->m_middleClick = false;
}
void SKGMainPanel::switchPinPage(QWidget* iWidget)
{
auto* toSwitch = qobject_cast< SKGTabPage* >(iWidget);
if (toSwitch == nullptr) {
toSwitch = currentPage();
}
if (toSwitch != nullptr) {
toSwitch->setPin(!toSwitch->isPin());
Q_EMIT currentPageChanged();
}
}
void SKGMainPanel::closePageByIndex(int iIndex)
{
QWidget* w = nullptr;
if (iIndex >= 0) {
w = d->m_tabWidget->widget(iIndex);
} else {
w = d->m_tabWidget->currentWidget();
}
closePage(w);
}
void SKGMainPanel::closeCurrentPage()
{
closePage(nullptr);
}
void SKGMainPanel::closePage(QWidget* iWidget, bool iForce)
{
SKGTRACEINFUNC(1)
if (getDocument()->getCurrentTransaction() != 0) {
QApplication::setOverrideCursor(QCursor(Qt::ArrowCursor));
displayMessage(i18nc("Information message", "A page cannot be closed when an operation is running."), SKGDocument::Information);
QApplication::restoreOverrideCursor();
} else {
auto* toRemove = qobject_cast< SKGTabPage* >(iWidget);
if (toRemove == nullptr) {
toRemove = currentPage();
}
if ((toRemove != nullptr) && toRemove->close(iForce)) {
historyPage item;
item.current = currentPageHistoryItem();
item.next = toRemove->getNextPages();
item.previous = toRemove->getPreviousPages();
d->m_historyClosedPages.push_back(item);
delete toRemove;
emit pageClosed();
}
}
// Show/hide main widget
bool atLeastOnePageOpened = (d->m_tabWidget->count() > 0);
d->m_tabWidget->setVisible(atLeastOnePageOpened);
if (d->m_mainWidget != nullptr) {
d->m_mainWidget->setVisible(!atLeastOnePageOpened);
}
if (!atLeastOnePageOpened) {
d->m_fullScreenAction->setChecked(false);
onFullScreen();
}
}
void SKGMainPanel::closeAllPages(bool iForce)
{
SKGTRACEINFUNC(1)
bool previous = d->m_tabWidget->blockSignals(true);
int nb = d->m_tabWidget->count();
for (int i = nb - 1; i >= 0; --i) {
auto* w = qobject_cast< SKGTabPage* >(d->m_tabWidget->widget(i));
if ((w != nullptr) && (iForce || !w->isPin())) {
closePage(w, iForce);
}
}
d->m_tabWidget->blockSignals(previous);
KMessageBox::enableMessage(QStringLiteral("closepinnedpage"));
Q_EMIT currentPageChanged();
}
void SKGMainPanel::closeAllOtherPages(QWidget* iWidget)
{
SKGTRACEINFUNC(1)
bool previous = d->m_tabWidget->blockSignals(true);
QWidget* toKeep = iWidget;
if (toKeep == nullptr) {
toKeep = currentPage();
}
int nb = d->m_tabWidget->count();
for (int i = nb - 1; i >= 0; --i) {
auto* w = qobject_cast< SKGTabPage* >(d->m_tabWidget->widget(i));
if ((w != nullptr) && w != toKeep && !w->isPin()) {
closePage(w);
}
}
d->m_tabWidget->blockSignals(previous);
Q_EMIT currentPageChanged();
}
void SKGMainPanel::saveDefaultState()
{
SKGTRACEINFUNC(1)
SKGError err;
SKGTabPage* toSave = currentPage();
if (toSave != nullptr) {
// Get bookmarks uuid
QString uuid = toSave->getBookmarkID();
// Reset bookmarks uuid to overwrite page state
toSave->setBookmarkID(QLatin1String(""));
// Overwrite
toSave->overwrite(false);
// Set original bookmarks uuid
toSave->setBookmarkID(uuid);
}
}
void SKGMainPanel::overwriteBookmarkState()
{
SKGTRACEINFUNC(1)
SKGError err;
SKGTabPage* toSave = currentPage();
if (toSave != nullptr) {
// Get bookmarks uuid
QString uuid = toSave->getBookmarkID();
if (!uuid.isEmpty()) {
// Overwrite
toSave->overwrite(false);
}
}
}
void SKGMainPanel::resetDefaultState()
{
SKGTRACEINFUNC(1)
SKGError err;
SKGTabPage* toSave = currentPage();
if (toSave != nullptr) {
QString name = toSave->getDefaultStateAttribute();
if (!name.isEmpty()) {
SKGBEGINLIGHTTRANSACTION(*getDocument(), i18nc("Noun, name of the user action", "Reset default state"), err)
IFOKDO(err, getDocument()->setParameter(name, QStringLiteral("<!DOCTYPE SKGML>")))
// Refresh panel
IFOK(err) toSave->setState(QLatin1String(""));
}
}
// status bar
IFOKDO(err, SKGError(0, i18nc("Successful message after an user action", "Default state has been reset")))
displayErrorMessage(err);
}
void SKGMainPanel::addTab()
{
SKGTRACEINFUNC(1)
SKGTabPage* cPage = currentPage();
if (cPage != nullptr) {
openPage(getPluginByName(cPage->objectName()));
}
}
bool SKGMainPanel::eventFilter(QObject* iObject, QEvent* iEvent)
{
if ((iObject != nullptr) && (iEvent != nullptr) && iEvent->type() == QEvent::Resize) {
auto* rEvent = dynamic_cast<QResizeEvent*>(iEvent);
if (rEvent != nullptr) {
QSize newSize = rEvent->size();
// Compute icon size
int s = qMax(qMin(newSize.width() / 5, 64), 16);
d->ui.kContextList->setIconSize(QSize(s, s));
}
}
return KXmlGuiWindow::eventFilter(iObject, iEvent);
}
QStringList SKGMainPanel::getTipsOfDay() const
{
return d->m_tipsOfTheDay;
}
QString SKGMainPanel::getTipOfDay() const
{
auto tips = getTipsOfDay();
return SKGServices::htmlToString(tips.at(qrand() % tips.size()));
}
void SKGMainPanel::notify(int iTransaction)
{
SKGTRACEINFUNC(1)
SKGTRACEL(1) << "iTransaction=" << iTransaction << endl;
// Notify
SKGObjectBase transaction(getDocument(), QStringLiteral("doctransaction"), iTransaction);
if (iTransaction == 0 || transaction.getAttribute(QStringLiteral("t_mode")) != QStringLiteral("R")) {
SKGDocument::SKGMessageList msg;
getDocument()->getMessages(iTransaction, msg, false);
int nbMessages = msg.count();
if (nbMessages != 0) {
// Build list of types
SKGDocument::MessageType maxType = SKGDocument::Positive;
QList<SKGDocument::MessageType> listGroups;
listGroups.reserve(nbMessages);
for (int i = 0; i < nbMessages; ++i) {
SKGDocument::SKGMessage m = msg.at(i);
// if the message has an action, it can not be grouped
if (!m.Action.isEmpty()) {
displayMessage(m.Text, m.Type, m.Action);
msg.removeAt(i);
i--;
nbMessages--;
} else {
if (listGroups.isEmpty() || m.Type != listGroups.at(listGroups.count() - 1)) {
listGroups.push_back(m.Type);
}
if (static_cast<int>(m.Type) >= static_cast<int>(maxType)) {
maxType = m.Type;
}
}
}
// Is the number of type acceptable?
bool modeGrouped = false;
if (listGroups.count() > 5 || nbMessages > 20) {
// Too many group ==> simplification
listGroups.clear();
listGroups.push_back(maxType);
modeGrouped = true;
}
// Build message
if (nbMessages != 0) {
QString message;
int indexGroup = 0;
for (int i = 0; i < nbMessages; ++i) {
auto m = msg.at(i);
auto t = m.Type;
if (modeGrouped) {
if (t == SKGDocument::Warning) {
m.Text = i18nc("Warning header", "Warning: %1", m.Text);
} else if (t == SKGDocument::Error) {
m.Text = i18nc("Error header", "Error: %1", m.Text);
} else if (t == SKGDocument::Information) {
m.Text = i18nc("Information header", "Information: %1", m.Text);
} else if (t == SKGDocument::Positive) {
m.Text = i18nc("Done header", "Done: %1", m.Text);
}
}
if (modeGrouped || t == listGroups.at(indexGroup)) {
// Same group
if (!message.isEmpty()) {
message += QStringLiteral("<br>");
}
message += m.Text;
} else {
// Different group
displayMessage(message, listGroups.at(indexGroup));
// Reset message
message = m.Text;
indexGroup++;
}
}
if (nbMessages < 21 || !SKGServices::getEnvVariable(QStringLiteral("SKGTEST")).isEmpty()) {
// Display a simple notification
/*auto notify = new KNotification(KAboutData::applicationData().componentName() % "_info_event" , this);
notify->setText(message);
notify->sendEvent();*/
displayMessage(message, listGroups.at(indexGroup));
} else {
// Too many message, display a warning panel
KMessageBox::information(SKGMainPanel::getMainPanel(), message, i18nc("Noun", "Notification"));
}
}
}
}
}
void SKGMainPanel::changeEvent(QEvent* e)
{
KXmlGuiWindow::changeEvent(e);
}
QLabel* SKGMainPanel::statusNormalMessage() const
{
return d->m_kNormalMessage;
}
KMessageWidget* SKGMainPanel::getMessageWidget(const QString& iMessage, SKGDocument::MessageType iType, const QString& iAction, bool iAutoKillOnClick)
{
KMessageWidget* msg = nullptr;
if (!iMessage.isEmpty()) {
msg = new KMessageWidget(this);
msg->setText(iMessage);
msg->setMessageType(static_cast<KMessageWidget::MessageType>(iType));
if (!iAction.isEmpty()) {
QUrl url(iAction);
if (url.scheme() == QStringLiteral("skg")) {
QAction* action = SKGMainPanel::getMainPanel()->getGlobalAction(url.host(), false);
QAction* act = nullptr;
if (action != nullptr) {
// This is an action
act = new QAction(action->icon(), action->text(), SKGMainPanel::getMainPanel());
} else {
// This is a default action
act = new QAction(SKGServices::fromTheme(QStringLiteral("open")), i18nc("Verb", "Open ..."), SKGMainPanel::getMainPanel());
}
act->setData(iAction);
msg->addAction(act);
connect(act, &QAction::triggered, this, [ = ] { openPage(QUrl(qobject_cast< QAction* >(sender())->data().toString()), true);});
if (iAutoKillOnClick) {
connect(act, &QAction::triggered, msg, &KMessageWidget::deleteLater, Qt::QueuedConnection);
}
}
}
}
return msg;
}
KMessageWidget* SKGMainPanel::displayMessage(const QString& iMessage, SKGDocument::MessageType iType, const QString& iAction)
{
// Create message widget
KMessageWidget* msg = nullptr;
if (!iMessage.isEmpty()) {
msg = getMessageWidget(iMessage, iType, iAction, true);
QTimer::singleShot(iType == SKGDocument::Positive ? 5000 : iType == SKGDocument::Information ? 10000 : 20000, Qt::CoarseTimer, msg, &KMessageWidget::deleteLater);
d->m_mainLayout->insertWidget(qMax(d->m_mainLayout->indexOf(d->m_mainWidget) - 1, 0), msg);
// Store message
auto msg2 = getMessageWidget(iMessage, iType, iAction, false);
auto* l = qobject_cast< QVBoxLayout* >(d->ui.kMessagesLayout->layout());
if (l != nullptr) {
l->insertWidget(0, msg2);
}
}
// Emit message
// [Event/error]
// [Event/neutral]
// [Event/positive]
auto notification = new KNotification(iType == SKGDocument::Error ? QStringLiteral("error") :
(iType == SKGDocument::Positive ? QStringLiteral("positive") :
(iType == SKGDocument::Warning ? QStringLiteral("negative") :
QStringLiteral("neutral"))), this);
notification->setText(iMessage);
notification->sendEvent();
// Alert
if (iType == SKGDocument::Error || iType == SKGDocument::Warning) {
qApp->alert(this);
}
return msg;
}
KMessageWidget* SKGMainPanel::displayErrorMessage(const QString& iMessage)
{
QString msg = iMessage;
if (msg.isEmpty()) {
auto* act = qobject_cast< QAction* >(sender());
if (act != nullptr) {
msg = act->data().toString();
}
}
return displayMessage(msg, SKGDocument::Error);
}
KMessageWidget* SKGMainPanel::displayErrorMessage(const SKGError& iError, bool iNotifyIfNoError)
{
return displayErrorMessage(iError, nullptr, iNotifyIfNoError);
}
KMessageWidget* SKGMainPanel::displayErrorMessage(const SKGError& iError, QAction* iAction, bool iNotifyIfNoError)
{
SKGTRACEINFUNC(1)
KMessageWidget* msg = nullptr;
SKGMainPanel* parent = SKGMainPanel::getMainPanel();
if (parent != nullptr) {
if (iError) {
// Get the message
msg = parent->displayMessage(iError.getFullMessage(), SKGDocument::Error, iError.getAction());
// Add history action in case of
if (iError.getHistoricalSize() != 0) {
auto history = new QAction(i18nc("Noun", "History"), msg);
history->setIcon(SKGServices::fromTheme(QStringLiteral("dialog-information")));
history->setData(iError.getFullMessageWithHistorical());
msg->addAction(history);
connect(history, &QAction::triggered, parent, [ = ] { parent->displayErrorMessage();});
connect(history, &QAction::triggered, msg, &KMessageWidget::deleteLater, Qt::QueuedConnection);
}
// Add the additional action
if (iAction != nullptr) {
iAction->setParent(msg);
msg->addAction(iAction);
connect(iAction, &QAction::triggered, msg, &KMessageWidget::deleteLater, Qt::QueuedConnection);
}
} else {
if (iNotifyIfNoError) {
auto notification = new KNotification(QStringLiteral("positive"), parent);
notification->setText(iError.getFullMessage());
notification->sendEvent();
}
// Status bar
QLabel* label = parent->statusNormalMessage();
QString message = iError.getMessage();
if ((label != nullptr) && !message.isEmpty()) {
label->setText(message);
}
}
}
return msg;
}
void SKGMainPanel::onCancelCurrentAction()
{
SKGMainPanelPrivate::m_currentActionCanceled = true;
}
void SKGMainPanel::onQuitAction()
{
// Bug 2777697: To be sure that all page modifications are closed
closeAllPages(true);
// Bug 2777697:
qApp->closeAllWindows();
}
QString SKGMainPanel::getSaveFileName(const QString& iStartDir, const QString& iFilter, QWidget* iParent, QString* iCodec)
{
QString fileName;
QString lastCodecUsed = QTextCodec::codecForLocale()->name();
KEncodingFileDialog::Result result = KEncodingFileDialog::getSaveUrlAndEncoding(lastCodecUsed, QUrl(iStartDir), iFilter, iParent);
if (!result.URLs.isEmpty()) {
fileName = result.URLs.at(0).toLocalFile();
}
if (iCodec != nullptr) {
*iCodec = result.encoding;
}
if (fileName.isEmpty()) {
return QLatin1String("");
}
QFile f(fileName);
if (f.exists() && KMessageBox::warningContinueCancel(iParent,
i18nc("Question", "File <b>%1</b> already exists. Do you really want to overwrite it?", fileName),
i18nc("Question", "Warning"),
KGuiItem(i18nc("Verb", "Save"), SKGServices::fromTheme(QStringLiteral("document-save")))) != KMessageBox::Continue) {
return QLatin1String("");
}
return fileName;
}
void SKGMainPanel::fillWithDistinctValue(
const QList<QWidget*>& iWidgets,
SKGDocument* iDoc,
const QString& iTable,
const QString& iAttribut,
const QString& iWhereClause,
bool iAddoperators)
{
SKGTRACEINFUNC(10)
if (iDoc != nullptr) {
{
// Get list
QStringList list;
{
SKGTRACEIN(10, "SKGMainPanel::fillWithDistinctValue-build list " % iTable % " " % iAttribut)
iDoc->getDistinctValues(iTable, iAttribut, iWhereClause, list);
if (!list.isEmpty() && !list.at(0).isEmpty()) {
list.insert(0, QLatin1String(""));
}
// Sorting list
{
SKGTRACEIN(10, "SKGMainPanel::fillWithDistinctValue-build list sorting " % iTable % " " % iAttribut)
// Correction bug 202341 vvv
QCollator c;
std::sort(list.begin(), list.end(), [&](const QString & a, const QString & b) {
return c.compare(a, b) < 0;
});
}
// Add operator
if (iAddoperators) {
list.push_back('=' % i18nc("Key word to modify a string into a field", "capitalize"));
list.push_back('=' % i18nc("Key word to modify a string into a field", "capwords"));
list.push_back('=' % i18nc("Key word to modify a string into a field", "lower"));
list.push_back('=' % i18nc("Key word to modify a string into a field", "trim"));
list.push_back('=' % i18nc("Key word to modify a string into a field", "upper"));
}
}
{
SKGTRACEIN(10, "SKGMainPanel::fillWithDistinctValue-fill " % iTable % " " % iAttribut)
SKGTRACEL(10) << "list.count()=" << list.count() << endl;
for (auto w : qAsConst(iWidgets)) {
auto comp = new QCompleter(list, w);
if (comp != nullptr) {
comp->setCaseSensitivity(Qt::CaseInsensitive);
comp->setFilterMode(Qt::MatchContains);
// Fill completion
auto* kcmb = qobject_cast<KComboBox*> (w);
if (kcmb != nullptr) {
// Fill combo
kcmb->clear();
kcmb->addItems(list);
kcmb->setCompleter(comp);
} else {
auto* kline = qobject_cast<QLineEdit*> (w);
if (kline != nullptr) {
kline->setClearButtonEnabled(true);
kline->setCompleter(comp);
}
}
}
}
}
}
}
}
SKGMainPanel* SKGMainPanel::getMainPanel()
{
return SKGMainPanelPrivate::m_mainPanel;
}
void SKGMainPanel::onZoomChanged()
{
SKGTabPage* toSave = currentPage();
if (toSave != nullptr) {
toSave->setZoomPosition(d->m_zoomSelector->value());
d->m_zoomSelector->setValue(toSave->zoomPosition()); // In case of a limit is reached
}
}
void SKGMainPanel::setMainWidget(QWidget* iWidget)
{
if (d->m_mainWidget == nullptr && d->m_mainLayout != nullptr && iWidget != nullptr) {
d->m_mainWidget = iWidget;
d->m_mainLayout->addWidget(d->m_mainWidget);
// Show/hide main widget
d->m_tabWidget->setVisible(d->m_tabWidget->count() != 0);
if (d->m_mainWidget != nullptr) {
d->m_mainWidget->setVisible(!d->m_tabWidget->isVisible());
}
}
}
SKGTabWidget* SKGMainPanel::getTabWidget() const
{
return d->m_tabWidget;
}
void SKGMainPanel::onClearMessages()
{
QLayout* l = d->ui.kMessagesLayout->layout();
if (l != nullptr) {
// Remove all item of the layout
while (l->count() > 1) {
QLayoutItem* child = l->takeAt(0);
if (child != nullptr) {
QWidget* w = child->widget();
delete w;
delete child;
}
}
}
}
void SKGMainPanel::onMigrateToSQLCipher()
{
SKGError err;
SKGTRACEINFUNCRC(10, err)
if (getDocument()->isFileModified()) {
err = SKGError(ERR_ABORT, i18nc("An information message", "The document must be saved to be migrated."), QStringLiteral("skg://file_save"));
} else {
QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
// Set parameters
QString input = getDocument()->getCurrentFileName();
QString tmp = input % ".sqlcipher";
QString output = input % "_migrated.skg";
output = output.replace(QStringLiteral(".skg_migrated"), QStringLiteral("_migrated"));
// Build argument
QStringList arg;
arg.push_back(QStringLiteral("--in"));
arg.push_back(input);
arg.push_back(QStringLiteral("--out"));
arg.push_back(tmp);
QString password = getDocument()->getPassword();
if (!password.isEmpty()) {
arg.push_back(QStringLiteral("--param"));
arg.push_back(QStringLiteral("password"));
arg.push_back(QStringLiteral("--value"));
arg.push_back(password);
password = " --param password --value \"" % password % "\"";
}
// Conversion skg => sqlcipher
QString cmd = "skroogeconvert --in \"" % input % "\" --out \"" % tmp % "\"" % password;
int rc = QProcess::execute(QStringLiteral("skroogeconvert"), arg);
if (rc != 0) {
err.setReturnCode(ERR_FAIL).setMessage(i18nc("Error message", "The following command line failed with code %2:\n'%1'", cmd, rc));
} else {
cmd = "skroogeconvert --in \"" % tmp % "\" --out \"" % output % "\"" % password;
arg[1] = tmp;
arg[3] = output;
rc = QProcess::execute(QStringLiteral("skroogeconvert"), arg);
if (rc != 0) {
err.setReturnCode(ERR_FAIL).setMessage(i18nc("Error message", "The following command line failed with code %2:\n'%1'", cmd, rc));
} else {
getDocument()->sendMessage(i18nc("Positive message", "You document has been migrated.\nHere is the new file:\n%1", output), SKGDocument::Positive, "skg://file_open/?filename=" % output);
notify();
}
}
QFile(tmp).remove();
QApplication::restoreOverrideCursor();
}
// Display error
SKGMainPanel::displayErrorMessage(err);
}
QString SKGMainPanel::dateToString(QDate iDate)
{
switch (skgbasegui_settings::date_format()) {
case 0:
return QLocale().toString(iDate, QLocale::ShortFormat);
case 1:
return QLocale().toString(iDate, QLocale::LongFormat);
case 3:
return KFormat().formatRelativeDate(iDate, QLocale::LongFormat);
case 4:
return iDate.toString(Qt::ISODate);
case 2:
default:
return KFormat().formatRelativeDate(iDate, QLocale::ShortFormat);
}
}
diff --git a/skgbasegui/skgmainpanel.h b/skgbasegui/skgmainpanel.h
index ab6bad178..491d82e05 100644
--- a/skgbasegui/skgmainpanel.h
+++ b/skgbasegui/skgmainpanel.h
@@ -1,558 +1,558 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGMAINPANEL_H
#define SKGMAINPANEL_H
/** @file
* This file defines a main panel.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include <kxmlguiwindow.h>
#include <qsystemtrayicon.h>
#include <qurl.h>
#include "skgbasegui_export.h"
#include "skgbasegui_settings.h"
#include "skginterfaceplugin.h"
#include "skgobjectbase.h"
#include "skgtabpage.h"
#include "skgtabwidget.h"
#include "ui_skgmainpanel_base.h"
#include "ui_skgmainpanel_pref.h"
class SKGDocument;
class SKGMainPanelPrivate;
class QSplashScreen;
class KMessageWidget;
class QListWidgetItem;
/**
* This class serves as the main window. It handles the
* menus, toolbars, and status bars.
*/
class SKGBASEGUI_EXPORT SKGMainPanel : public KXmlGuiWindow
{
Q_OBJECT
public:
/**
* Default Constructor
* @param iSplashScreen the splash screen
* @param iDocument the document to manage data
*/
explicit SKGMainPanel(QSplashScreen* iSplashScreen, SKGDocument* iDocument);
/**
* Default Destructor
*/
~SKGMainPanel() override;
/**
* Return the document of the main panel
* @return document of the main panel
*/
SKGDocument* getDocument() const;
/**
* Creates a modal file dialog and returns the selected filename or an empty string if none was chosen.
* A confirmation message is displayed if needed
* @param iStartDir this can either be
* @li the URL of the directory to start in.
* @li a QUrl) to start in the current working directory, or the last directory where a file has been selected.
* @li an URL starting with 'kfiledialog:///\<keyword\>' to start in the directory last used by a filedialog in the same application that specified the same keyword.
* @li an URL starting with 'kfiledialog:///\<keyword\>?global' to start in the directory last used by a filedialog in any application that specified the same keyword.
* @param iFilter a shell glob or a mime-type-filter that specifies which files to display. The preferred option is to set a list of mimetype names, see setMimeFilter() for details. Otherwise you can set the text to be displayed for the each glob, and provide multiple globs, see setFilter() for details.
* @param iParent the widget the dialog will be centered on initially.
* @param iCodec a valid QString to get the codec or nullptr.
* @return the file name
*/
static QString getSaveFileName(const QString& iStartDir, const QString& iFilter, QWidget* iParent, QString* iCodec = nullptr);
/**
* Display an error message
* @param iError the error
* @param iNotifyIfNoError to launch a notification even if there is no error
* @return the message widget
*/
static KMessageWidget* displayErrorMessage(const SKGError& iError, bool iNotifyIfNoError = false);
/**
* Display an error message
* @param iError the error
* @param iAction the additional action to add
* @param iNotifyIfNoError to launch a notification even if there is no error
* @return the message widget
*/
static KMessageWidget* displayErrorMessage(const SKGError& iError, QAction* iAction, bool iNotifyIfNoError = false);
/**
* Fill a widget with distinct values
* @param iWidgets the widgets
* @param iDoc document
* @param iTable table
* @param iAttribut attribute
* @param iWhereClause where clause
* @param iAddoperators to add operators (=upper, =lower to the list)
*/
static void fillWithDistinctValue(
const QList<QWidget*>& iWidgets,
SKGDocument* iDoc,
const QString& iTable,
const QString& iAttribut,
const QString& iWhereClause,
bool iAddoperators = false);
/**
* Return main panel
*/
static SKGMainPanel* getMainPanel();
/**
* Get main config groupe
* @return main config groupe
*/
static KConfigGroup getMainConfigGroup();
/**
* Convert a QDate into a QString based on application settings.
* @param iDate the date
* @return the converted QString
*/
// cppcheck-suppress passedByValue
static QString dateToString(QDate iDate);
/**
* Get the first selected object
* @return first selected object
*/
SKGObjectBase getFirstSelectedObject() const;
/**
* Get the current selection
* @return selected objects
*/
SKGObjectBase::SKGListSKGObjectBase getSelectedObjects() const;
/**
* Get the number of selected object
* @return number of selected objects
*/
int getNbSelectedObjects() const;
/**
* To know if the widget having the selection has the focus
* Default implementation is based on mainWidget
* @return true of false
*/
bool hasSelectionWithFocus();
/**
* To know if the closure of the application is authorized
* @return true if close is authorized else false
*/
bool queryClose() override;
/**
* To know if the closure of the file is authorized
* @return true if close is authorized else false
*/
bool queryFileClose();
/**
* Return the plugin number by index
* @param iIndex the index of the plugin
* @return the plugin pointer. Can be nullptr. Mustn't be deleted
*/
SKGInterfacePlugin* getPluginByIndex(int iIndex);
/**
* Return the plugin number by name
* @param iName the name of the plugin
* @return the plugin pointer. Can be nullptr. Mustn't be deleted
*/
SKGInterfacePlugin* getPluginByName(const QString& iName);
/**
* Get the label for normal message in status bar
* @return the label
*/
QLabel* statusNormalMessage() const;
/**
* Get the current splash screen. nullptr if the splash screen is closed.
* @return the splash screen
*/
QSplashScreen* splashScreen() const;
/**
* Set the main widget
* @param iWidget the widget to display when all pages are closed
*/
void setMainWidget(QWidget* iWidget);
/**
* Get the tab widget.
* @return the tab widget
*/
SKGTabWidget* getTabWidget() const;
/**
* Get the history item of the current page
* @return the history item
*/
SKGTabPage::SKGPageHistoryItem currentPageHistoryItem() const;
/**
* Get the index of the current page
* @return index of the current page
*/
int currentPageIndex() const;
/**
* Get the current page
* @return the current page
*/
SKGTabPage* currentPage() const;
/**
* Get a index of a page
* @param iPage the page
* @return the index (-1 if not found)
*/
int pageIndex(SKGTabPage* iPage) const;
/**
* Get a page
* @param iIndex an index
* @return the page
*/
SKGTabPage* page(int iIndex) const;
/**
* Get then number of pages
* @return the number of pages
*/
int countPages() const;
/**
* Register a global action
* @param iIdentifier identifier of the action
* @param iAction action pointer
* @param iAddInCollection to add or not the action in the main panel collection
* @param iListOfTable list of table where this action must be enabled (empty list means all)
* You can also add only one item like this to set the list dynamically:
* query:the sql condition on sqlite_master
* @param iMinSelection the minimum number of selected item to enable the action
* 0 : no need selection but need a page opened containing a table
* -1 : no need selection and need a page opened (not containing a table)
* -2 : no need selection and no need a page opened
* @param iMaxSelection the maximum number of selected item to enable the action (-1 = infinite)
* @param iRanking the ranking to sort actions in contextual menus
* @param iRanking the ranking to sort actions in contextual menus
* -1: automatic by creation order
* 0: not in contextual menu
* @param iSelectionMustHaveFocus the action will be activated only if the widget containing the selection has the focus
*
* Actions can be set in differents groups by changing hundred:
* 0 to 99 is a group
* 100 to 200 is another group
*/
void registerGlobalAction(const QString& iIdentifier, QAction* iAction,
bool iAddInCollection = true,
const QStringList& iListOfTable = QStringList(),
int iMinSelection = -2,
int iMaxSelection = -1,
int iRanking = -1,
bool iSelectionMustHaveFocus = false);
/**
* Get a registered global action
* @param iIdentifier identifier of the action
* @param iWarnIfNotExist warn if the action does not exist
* @return action pointer
*/
QPointer<QAction> getGlobalAction(const QString& iIdentifier, bool iWarnIfNotExist = true);
/**
* Get a list of actions enable for a contextual menu
* @param iTable the table
* @return the list of actions
*/
QList<QPointer<QAction> > getActionsForContextualMenu(const QString& iTable);
/**
* Get all registered global actions
* @return actions
*/
QMap<QString, QPointer<QAction> > getGlobalActions() const;
/**
* Get the tips of days
* @return the tips of days
*/
QStringList getTipsOfDay() const;
/**
* Get the tip of days
* @return the tip of days
*/
QString getTipOfDay() const;
/**
* Define if the document must be saved when closed
* @param iSaveOnClose the save on close mode
*/
void setSaveOnClose(bool iSaveOnClose);
/**
* Get all advice
* @return the list of advice
*/
SKGAdviceList getAdvice() const;
public Q_SLOTS:
/**
* Display a message
* @param iMessage the message
* @param iType the type
* @param iAction the associated action
* @return the message widget
*/
KMessageWidget* displayMessage(const QString& iMessage, SKGDocument::MessageType iType = SKGDocument::Information, const QString& iAction = QString());
/**
* Display an error message
* @param iMessage the error message. If the message is "", the data of the sender will be used
* @return the message widget
*/
KMessageWidget* displayErrorMessage(const QString& iMessage = QString());
/**
* This function is called when the application is launched again with new arguments
* @param iArgument the arguments
* @return the rest of arguments to treat
*/
QStringList processArguments(const QStringList& iArgument);
/**
* Set the current page
* @param iIndex the current page
*/
void setCurrentPage(int iIndex);
/**
* Set the context item visibility
* @param iPage index of the page in the pages chooser
* @param iVisibility the visibility
*/
void setContextVisibility(int iPage, bool iVisibility);
/**
* Set the context item visibility
* @param iItem item in the pages chooser
* @param iVisibility the visibility
*/
void setContextVisibility(QListWidgetItem* iItem, bool iVisibility);
/**
* Open a plugin in a page described in sender()->data()
* @return true if the url has been opened
*/
bool openPage();
/**
* Open a plugin in a page
* @param iUrl the url like this "skg://plugin_name/?param1=value1&param2=value2&..." to open a special page
* or "skg://action" to trigger an action
* or "http://..." to open a web page
* @param iNewPage to open a new page or not
* @return true if the url has been opened
*/
bool openPage(const QUrl& iUrl, bool iNewPage = true);
/**
* Open a plugin in a page
* @param iUrl the url like this "skg://plugin_name/?param1=value1&param2=value2&..." to open a special page
* or "skg://action/?param1=value1&param2=value2&..." to trigger an action, parameters can be found as property on the sender QAction
* or "http://..." to open a web page
* if empty then url will be get from sender()->data()
* @param iNewPage to open a new page or not
* @return true if the url has been opened
*/
bool openPage(const QString& iUrl, bool iNewPage = true);
/**
* Open a plugin in a page
* @param iPage index of the page in the pages chooser
* @param iNewPage to open a new page or not
* @return the opened tab
*/
SKGTabPage* openPage(int iPage, bool iNewPage = true);
/**
* Open a plugin in a page
* @param plugin the plugin
* @param index index of the tab to replace or -1 to add a new one
* @param parameters parameters of the plugin
* @param title title of the page
* @param iID id of the new page
* @param iSetCurrent to set the new page as the current one
* @return the opened tab
*/
SKGTabPage* openPage(SKGInterfacePlugin* plugin, int index = -1, const QString& parameters = QString(), const QString& title = QString(), const QString& iID = QString(), bool iSetCurrent = true);
/**
* Switch the pin state of the page
* @param iWidget the page to remove (nullptr means current one)
*/
void switchPinPage(QWidget* iWidget);
/**
* Close a page
* @param iIndex the page to remove (-1 means current one)
*/
void closePageByIndex(int iIndex = -1);
/**
* Close a page
* @param iWidget the page to remove (nullptr means current one)
* @param iForce to close pinned pages too
*/
void closePage(QWidget* iWidget, bool iForce = false);
/**
* Close the current page
*/
void closeCurrentPage();
/**
* Close all other pages
* @param iWidget the page to keep (nullptr means current one)
*/
void closeAllOtherPages(QWidget* iWidget);
/**
* Close all pages
* @param iForce to close pinned pages too
*/
void closeAllPages(bool iForce = false);
/**
* Force the refresh of the object.
*/
void refresh();
/**
* Send notifications corresponding to the transaction.
* @param iTransaction the transaction identifier
*/
void notify(int iTransaction = 0);
/**
* Open settings panel on dedicated page.
* @param iPluginName the name of the plugin (pluginInterface->objectName())
*/
void optionsPreferences(const QString& iPluginName = QString());
/**
* Unregister a global action
* @param iAction action pointer
*/
void unRegisterGlobalAction(QObject* iAction);
Q_SIGNALS:
/**
* This signal is sent when a new page is opened.
*/
void pageOpened();
/**
* This signal is sent when a new page is opened.
*/
void pageClosed();
/**
* This signal is sent when the current page changes.
*/
void currentPageChanged();
/**
* This signal is sent when settings changes.
*/
void settingsChanged();
/**
* This signal is sent when selection changes.
*/
void selectionChanged();
protected:
/**
* event
* @param e event
*/
void changeEvent(QEvent* e) override;
/**
* Event filtering
* @param iObject object
* @param iEvent event
* @return In your reimplementation of this function, if you want to filter the event out, i.e. stop it being handled further, return true; otherwise return false.
*/
bool eventFilter(QObject* iObject, QEvent* iEvent) override;
private Q_SLOTS:
KMessageWidget* getMessageWidget(const QString& iMessage, SKGDocument::MessageType iType, const QString& iAction, bool iAutoKillOnClick);
void showMenu(QPoint iPos);
void onSettingsChanged();
void onCancelCurrentAction();
void onQuitAction();
void addTab();
void onBeforeOpenContext();
void onOpenContext();
void saveDefaultState();
void resetDefaultState();
void overwriteBookmarkState();
void enableEditor();
void onPrevious();
void onNext();
void onReopenLastClosed();
void onFullScreen();
void onShowPreviousMenu();
void onShowNextMenu();
void onZoomChanged();
void onShowMenuBar();
void onShowButtonMenu();
void onHideContextItem();
void onShowAllContextItems();
void onLockDocks();
void onUnlockDocks();
void onConfigureNotifications();
void onClearMessages();
void onMigrateToSQLCipher();
private:
Q_DISABLE_COPY(SKGMainPanel)
void setupActions();
SKGMainPanelPrivate* const d;
};
#endif // SKGMAINPANEL_H
diff --git a/skgbasegui/skgmainpanel_base.ui b/skgbasegui/skgmainpanel_base.ui
index 5b9a1c400..9bcd86d66 100644
--- a/skgbasegui/skgmainpanel_base.ui
+++ b/skgbasegui/skgmainpanel_base.ui
@@ -1,217 +1,217 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>skgmainpanel_base</class>
<widget class="QMainWindow" name="skgmainpanel_base">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>361</width>
<height>335</height>
</rect>
</property>
<property name="windowTitle">
<string>Skrooge</string>
</property>
<widget class="QWidget" name="centralwidget"/>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>361</width>
<height>30</height>
</rect>
</property>
</widget>
<widget class="QStatusBar" name="statusbar"/>
<widget class="QDockWidget" name="kDockContext">
<property name="allowedAreas">
<set>Qt::LeftDockWidgetArea|Qt::RightDockWidgetArea</set>
</property>
<property name="windowTitle">
<string>Pages</string>
</property>
<attribute name="dockWidgetArea">
<number>1</number>
</attribute>
<widget class="QWidget" name="dockWidgetContents">
<layout class="QVBoxLayout" name="verticalLayout">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QListWidget" name="kContextList">
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="toolTip">
- <string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
+ <string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;https://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'DejaVu Sans'; font-size:10pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;this list allows you to open new pages&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Ctrl&lt;/span&gt; to open in a new page&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="statusTip">
<string>this list allows you to open new pages</string>
</property>
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="lineWidth">
<number>0</number>
</property>
<property name="alternatingRowColors">
<bool>false</bool>
</property>
<property name="selectionBehavior">
<enum>QAbstractItemView::SelectRows</enum>
</property>
<property name="iconSize">
<size>
<width>32</width>
<height>32</height>
</size>
</property>
<property name="verticalScrollMode">
<enum>QAbstractItemView::ScrollPerPixel</enum>
</property>
<property name="resizeMode">
<enum>QListView::Adjust</enum>
</property>
<property name="uniformItemSizes">
<bool>true</bool>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
<widget class="QDockWidget" name="kDockMessages">
<property name="windowTitle">
<string>&amp;Messages</string>
</property>
<attribute name="dockWidgetArea">
<number>1</number>
</attribute>
<widget class="QWidget" name="layout">
<layout class="QVBoxLayout" name="verticalLayout_2">
<property name="spacing">
<number>2</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QScrollArea" name="kMessagesArea">
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="widgetResizable">
<bool>true</bool>
</property>
<widget class="QWidget" name="kMessagesLayout">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>256</width>
<height>72</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<property name="spacing">
<number>2</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</widget>
</item>
<item>
<widget class="QPushButton" name="kClearMessageBtn">
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="toolTip">
<string>Clear all messages</string>
</property>
<property name="statusTip">
<string>Clear all messages</string>
</property>
<property name="text">
<string>Clear messages</string>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
</widget>
<tabstops>
<tabstop>kContextList</tabstop>
</tabstops>
<resources/>
<connections/>
<slots>
<slot>onAddBookmark()</slot>
<slot>onRemoveBookmark()</slot>
<slot>onBookmarkSelectionChanged()</slot>
<slot>onAddBookmarkGroup()</slot>
<slot>onRenameBookmark()</slot>
<slot>onBookmarkEditorChanged()</slot>
<slot>onBookmarkFilterRegExpChanged()</slot>
</slots>
</ui>
diff --git a/skgbasegui/skgobjectmodelbase.cpp b/skgbasegui/skgobjectmodelbase.cpp
index 5e2a8faa9..9d3c19477 100644
--- a/skgbasegui/skgobjectmodelbase.cpp
+++ b/skgbasegui/skgobjectmodelbase.cpp
@@ -1,1143 +1,1143 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file defines classes SKGObjectModelBase.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgobjectmodelbase.h"
#include <kcolorscheme.h>
#include <kformat.h>
#include <klocalizedstring.h>
#include <qapplication.h>
#include <qcolor.h>
#include <qdir.h>
#include <qicon.h>
#include <qmimedata.h>
#include "skgdocument.h"
#include "skgmainpanel.h"
#include "skgnodeobject.h"
#include "skgpropertyobject.h"
#include "skgtraces.h"
#include "skgtransactionmng.h"
SKGObjectModelBase::SKGObjectModelBase(SKGDocument* iDocument,
const QString& iTable,
QString iWhereClause,
QWidget* iParent,
QString iParentAttribute,
bool iResetOnCreation)
: QAbstractItemModel(iParent), m_isResetRealyNeeded(iResetOnCreation), m_cache(new QMap<QString, QVariant>()), m_document(iDocument),
m_whereClause(std::move(iWhereClause)),
m_parentAttribute(std::move(iParentAttribute)),
m_doctransactionTable(false), m_nodeTable(false), m_parametersTable(false),
m_refreshBlocked(false)
{
SKGTRACEINFUNC(1)
setTable(iTable);
connect(m_document, &SKGDocument::tableModified, this, &SKGObjectModelBase::dataModified);
if (SKGMainPanel::getMainPanel() != nullptr) {
connect(SKGMainPanel::getMainPanel(), &SKGMainPanel::currentPageChanged, this, &SKGObjectModelBase::pageChanged, Qt::QueuedConnection);
}
}
SKGObjectModelBase::~SKGObjectModelBase()
{
SKGTRACEINFUNC(1)
clear();
m_document = nullptr;
delete m_cache;
m_cache = nullptr;
}
void SKGObjectModelBase::clear()
{
SKGTRACEINFUNC(1)
QHashIterator<int, SKGObjectBase*> i(m_objectsHashTable);
while (i.hasNext()) {
i.next();
SKGObjectBase* val = i.value();
delete val;
val = nullptr;
}
m_listObjects.clear();
m_parentChildRelations.clear();
m_childParentRelations.clear();
m_objectsHashTable.clear();
m_objectsHashTableRows.clear();
}
SKGDocument::SKGModelTemplateList SKGObjectModelBase::getSchemas() const
{
return m_listSchema;
}
void SKGObjectModelBase::setSupportedAttributes(const QStringList& iListAttribute)
{
SKGTRACEINFUNC(1)
m_listSupported.clear();
m_listVisibility.clear();
m_listSize.clear();
QStringList l = iListAttribute;
if (!m_listSchema.isEmpty()) {
l += SKGServices::splitCSVLine(m_listSchema.at(0).schema);
}
QStringList attributesAvailablesTmp;
if (!m_listSchema.isEmpty()) {
attributesAvailablesTmp = SKGServices::splitCSVLine(m_listSchema.at(0).schema);
}
int nb = attributesAvailablesTmp.count();
QStringList attributesAvailables;
attributesAvailables.reserve(nb);
for (int i = 0; i < nb; ++i) {
attributesAvailables.push_back(attributesAvailablesTmp.at(i).split('|').at(0));
}
nb = l.count();
for (int i = 0; i < nb; ++i) {
QStringList values = l.at(i).split('|');
int nbValues = values.count();
const QString& att = values.at(0);
if (nbValues > 0 && !m_listSupported.contains(att) && attributesAvailables.contains(att)) {
m_listSupported.push_back(att);
bool visible = true;
if (nbValues > 1) {
visible = (i == 0 || values.at(1) == QStringLiteral("Y")); // First column is always visible to support grouping
}
m_listVisibility.push_back(visible);
if (nbValues > 2) {
m_listSize.push_back(SKGServices::stringToInt(values.at(2)));
} else {
m_listSize.push_back(-1);
}
}
}
m_isResetRealyNeeded = true;
}
bool SKGObjectModelBase::setFilter(const QString& iWhereClause)
{
if (iWhereClause != m_whereClause) {
m_isResetRealyNeeded = true;
}
m_whereClause = iWhereClause;
return m_isResetRealyNeeded;
}
void SKGObjectModelBase::setTable(const QString& iTable)
{
if (iTable != m_table) {
if (!m_table.isEmpty()) {
m_isResetRealyNeeded = true;
}
m_table = iTable;
m_realTable = SKGServices::getRealTable(m_table);
if (m_document != nullptr) {
m_listSchema = m_document->getDisplaySchemas(m_realTable);
}
}
}
QString SKGObjectModelBase::getTable() const
{
return m_table;
}
void SKGObjectModelBase::setGroupBy(const QString& iAttribute)
{
if (iAttribute != m_groupby) {
m_isResetRealyNeeded = true;
m_groupby = iAttribute;
}
}
QString SKGObjectModelBase::getGroupBy() const
{
return m_groupby;
}
QString SKGObjectModelBase::getParentChildAttribute() const
{
return m_parentAttribute;
}
QString SKGObjectModelBase::getRealTable() const
{
return m_realTable;
}
QString SKGObjectModelBase::getWhereClause() const
{
return m_whereClause;
}
SKGDocument* SKGObjectModelBase::getDocument() const
{
return m_document;
}
void SKGObjectModelBase::buidCache()
{
SKGTRACEINFUNC(1)
m_doctransactionTable = (getRealTable() == QStringLiteral("doctransaction"));
m_nodeTable = (getRealTable() == QStringLiteral("node"));
m_parametersTable = (getRealTable() == QStringLiteral("parameters"));
// Get std colors
KColorScheme scheme(QPalette::Normal);
m_fontNegativeColor = QVariant::fromValue(scheme.foreground(KColorScheme::NegativeText).color());
}
bool SKGObjectModelBase::blockRefresh(bool iBlocked)
{
bool previous = m_refreshBlocked;
m_refreshBlocked = iBlocked;
return previous;
}
bool SKGObjectModelBase::isRefreshBlocked()
{
return m_refreshBlocked;
}
void SKGObjectModelBase::refresh()
{
if (!m_isResetRealyNeeded || isRefreshBlocked()) {
return;
}
SKGTRACEIN(1, "SKGObjectModelBase::refresh-" % getTable())
QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
beginResetModel();
Q_EMIT beforeReset();
m_cache->clear();
{
_SKGTRACEINFUNC(10)
clear();
m_listAttibutes.clear();
m_listAttributeTypes.clear();
/*beginRemoveRows(QModelIndex(), 0, rowCount(QModelIndex())-1);
endRemoveRows();*/
}
{
_SKGTRACEINFUNC(10)
QStringList listAttibutesTmp;
if (m_document != nullptr && m_document->getAttributesList(m_table, listAttibutesTmp).isSucceeded()) {
m_isResetRealyNeeded = false;
if (!listAttibutesTmp.isEmpty()) {
// Filter attributes
int nb = m_listSupported.count();
if (nb == 0) {
setSupportedAttributes(QStringList());
nb = m_listSupported.count();
}
for (int i = 0 ; i < nb ; ++i) {
QString att = m_listSupported.at(i);
if (listAttibutesTmp.contains(att) || att.startsWith(QLatin1String("p_"))) {
m_listAttibutes.push_back(att);
if (att.startsWith(QLatin1String("t_")) || att.startsWith(QLatin1String("p_")) ||
att == QLatin1String("d_DATEWEEK") || att == QLatin1String("d_DATEMONTH") || att == QLatin1String("d_DATEQUARTER") || att == QLatin1String("d_DATESEMESTER") || att == QLatin1String("d_DATEYEAR")) {
m_listAttributeTypes.push_back(SKGServices::TEXT);
} else if (att.startsWith(QLatin1String("f_"))) {
m_listAttributeTypes.push_back(SKGServices::FLOAT);
} else if (att.startsWith(QLatin1String("i_"))) {
m_listAttributeTypes.push_back(SKGServices::INTEGER);
} else if (att.startsWith(QLatin1String("d_"))) {
m_listAttributeTypes.push_back(SKGServices::DATE);
} else {
m_listAttributeTypes.push_back(SKGServices::OTHER);
}
}
}
// Remove double
nb = m_listAttibutes.count();
for (int i = nb - 1 ; i >= 0 ; --i) {
QString att = m_listAttibutes.at(i);
if (att.contains(QStringLiteral("_REAL"))) {
att.replace(QStringLiteral("_REAL"), QStringLiteral("_"));
int p = m_listAttibutes.indexOf(att);
if (p == -1) {
att = att.toLower();
p = m_listAttibutes.indexOf(att);
}
if (p != -1) {
m_listAttibutes.removeAt(p);
m_listAttributeTypes.removeAt(p);
if (p < i) {
--i;
}
}
}
}
}
// Get objects
QString wc = m_whereClause;
if (!m_groupby.isEmpty()) {
if (wc.isEmpty()) {
wc = QStringLiteral("1=1");
}
if (m_groupby.startsWith(QLatin1String("p_"))) {
wc += " ORDER BY (SELECT t_value FROM parameters WHERE t_uuid_parent=" % getTable() % ".id||'-" % getRealTable() % "' AND t_name='" % m_groupby % "')";
} else {
wc += " ORDER BY " % m_groupby;
}
}
if (m_document != nullptr) {
m_document->getObjects(m_table, wc, m_listObjects);
}
// Initialize object to treat
QString currentGroup;
int currentGoupId = 0;
bool groupByDate = (m_groupby.startsWith(QLatin1String("d_")) &&
m_groupby != QLatin1String("d_DATEWEEK") &&
m_groupby != QLatin1String("d_DATEMONTH") &&
m_groupby != QLatin1String("d_DATEQUARTER") &&
m_groupby != QLatin1String("d_DATESEMESTER") &&
m_groupby != QLatin1String("d_DATEYEAR"));
bool groupByNum = (m_groupby.startsWith(QLatin1String("f_")) || m_groupby.startsWith(QLatin1String("i_")));
int nb = m_listObjects.count();
SKGTRACEL(1) << nb << " objects found" << endl;
for (int t = 0; t < nb; ++t) {
auto c = new SKGObjectBase(m_listObjects.at(t));
int id = (c != nullptr ? c->getID() : 0);
int idparent = 0;
if (m_groupby.isEmpty()) {
// Grouping by tree
if (!m_parentAttribute.isEmpty()) {
int idp = SKGServices::stringToInt(c->getAttribute(m_parentAttribute));
if (idp > 0) {
idparent = idp;
}
}
} else {
// Grouping on specified attribute
QString att = getAttributeForGrouping(*c, m_groupby);
if (groupByDate) {
QDate date = SKGServices::stringToTime(att).date();
if (date == QDate::currentDate()) {
att = i18nc("A group name for grouping by date attibute", "Today");
} else if (date > QDate::currentDate()) {
// In future
if (date < QDate::currentDate().addDays(7)) {
att = i18nc("A group name for grouping by date attibute", "Next 7 days");
} else if (date < QDate::currentDate().addDays(15)) {
att = i18nc("A group name for grouping by date attibute", "Next 15 days");
} else if (date < QDate::currentDate().addMonths(1)) {
att = i18nc("A group name for grouping by date attibute", "Next month");
} else if (date < QDate::currentDate().addMonths(3)) {
att = i18nc("A group name for grouping by date attibute", "Next 3 months");
} else if (date < QDate::currentDate().addMonths(6)) {
att = i18nc("A group name for grouping by date attibute", "Next 6 months");
} else if (date < QDate::currentDate().addYears(1)) {
att = i18nc("A group name for grouping by date attibute", "Next year");
} else if (date < QDate::currentDate().addYears(3)) {
att = i18nc("A group name for grouping by date attibute", "Next 3 years");
} else {
att = i18nc("A group name for grouping by date attibute", "Far away in the future");
}
} else {
// In the past
if (date > QDate::currentDate().addDays(-7)) {
att = i18nc("A group name for grouping by date attibute", "Last 7 days");
} else if (date > QDate::currentDate().addDays(-15)) {
att = i18nc("A group name for grouping by date attibute", "Last 15 days");
} else if (date > QDate::currentDate().addMonths(-1)) {
att = i18nc("A group name for grouping by date attibute", "Last month");
} else if (date > QDate::currentDate().addMonths(-3)) {
att = i18nc("A group name for grouping by date attibute", "Last 3 months");
} else if (date > QDate::currentDate().addMonths(-6)) {
att = i18nc("A group name for grouping by date attibute", "Last 6 months");
} else if (date > QDate::currentDate().addYears(-1)) {
att = i18nc("A group name for grouping by date attibute", "Last year");
} else if (date > QDate::currentDate().addYears(-3)) {
att = i18nc("A group name for grouping by date attibute", "Last 3 years");
} else {
att = i18nc("A group name for grouping by date attibute", "Far away in the past");
}
}
} else if (groupByNum) {
if (att != QChar(8734)) {
double d = SKGServices::stringToDouble(att);
if (d > 10000.0) {
att = i18nc("A group name for grouping by numerical attibute", "> 10000");
} else if (d > 1000.0) {
att = i18nc("A group name for grouping by numerical attibute", "> 1000");
} else if (d > 100.0) {
att = i18nc("A group name for grouping by numerical attibute", "> 100");
} else if (d > 10.0) {
att = i18nc("A group name for grouping by numerical attibute", "> 10");
} else if (d > 0.0) {
att = i18nc("A group name for grouping by numerical attibute", "> 0");
} else if (d < -10000.0) {
att = i18nc("A group name for grouping by numerical attibute", "< -10000");
} else if (d < -1000.0) {
att = i18nc("A group name for grouping by numerical attibute", "< -1000");
} else if (d < -100.0) {
att = i18nc("A group name for grouping by numerical attibute", "< -100");
} else if (d < -10.0) {
att = i18nc("A group name for grouping by numerical attibute", "< -10");
} else if (d < 0.0) {
att = i18nc("A group name for grouping by numerical attibute", "< 0");
} else {
att = i18nc("A group name for grouping by numerical attibute", "= 0");
}
}
}
if (att != currentGroup || currentGoupId == 0) {
// Addition of a new group
currentGroup = att;
currentGoupId--;
auto group = new SKGObjectBase(m_document, QLatin1String(""), currentGoupId);
group->setAttribute(QStringLiteral("t_title"), currentGroup);
m_childParentRelations.insert(currentGoupId, 0);
QList<int> childrensids = m_parentChildRelations.value(0);
childrensids.push_back(currentGoupId);
m_parentChildRelations.insert(0, childrensids);
m_objectsHashTableRows.insert(currentGoupId, childrensids.count() - 1);
m_objectsHashTable.insert(currentGoupId, group);
}
idparent = currentGoupId;
}
m_childParentRelations.insert(id, idparent);
QList<int> childrensids = m_parentChildRelations.value(idparent);
childrensids.push_back(id);
m_parentChildRelations.insert(idparent, childrensids);
m_objectsHashTableRows.insert(id, childrensids.count() - 1);
m_objectsHashTable.insert(id, c);
}
}
// Build cache
buidCache();
}
endResetModel();
Q_EMIT afterReset();
QApplication::restoreOverrideCursor();
}
bool SKGObjectModelBase::hasChildren(const QModelIndex& iParent) const
{
if (iParent.column() > 0) {
return false;
}
_SKGTRACEINFUNC(10)
if (iParent.isValid() && m_parentAttribute.isEmpty() && m_groupby.isEmpty()) {
return false;
}
return QAbstractItemModel::hasChildren(iParent);
}
int SKGObjectModelBase::rowCount(const QModelIndex& iParent) const
{
if (iParent.column() > 0) {
return 0;
}
_SKGTRACEINFUNC(10)
int idParent = 0;
if (iParent.isValid()) {
idParent = iParent.internalId();
}
return m_parentChildRelations.value(idParent).count();
}
int SKGObjectModelBase::columnCount(const QModelIndex& iParent) const
{
Q_UNUSED(iParent)
return m_listAttibutes.count();
}
QModelIndex SKGObjectModelBase::index(int row, int column, const QModelIndex& iParent) const
{
if (!hasIndex(row, column, iParent)) {
return {};
}
_SKGTRACEINFUNC(10)
int idParent = 0;
if (iParent.isValid()) {
idParent = iParent.internalId();
}
int idChild = m_parentChildRelations.value(idParent).at(row);
// SKGTRACE << table << "-" << idParent << "(" << row << ") ==> " << idChild << endl;
return (idChild != 0 ? createIndex(row, column, idChild) : QModelIndex());
}
QModelIndex SKGObjectModelBase::parent(const QModelIndex& iIndex) const
{
if (!iIndex.isValid()) {
return {};
}
_SKGTRACEINFUNC(10)
int idChild = 0;
if (iIndex.isValid()) {
idChild = iIndex.internalId();
}
int idParent = m_childParentRelations.value(idChild);
int row = m_objectsHashTableRows.value(idParent);
// SKGTRACE << table << "-" << idChild << "(" << row << ") <== " << idParent << endl;
return idParent != 0 ? createIndex(row, 0, idParent) : QModelIndex();
}
int SKGObjectModelBase::getIndexAttribute(const QString& iAttributeName) const
{
int output = m_listAttibutes.indexOf(iAttributeName);
if (output == -1) {
SKGTRACE << "[" << iAttributeName << "] not found in [" << getRealTable() << "]" << endl;
}
return output;
}
QString SKGObjectModelBase::getAttribute(int iIndex) const
{
return m_listAttibutes.value(iIndex);
}
SKGServices::AttributeType SKGObjectModelBase::getAttributeType(int iIndex) const
{
return m_listAttributeTypes.value(iIndex);
}
QVariant SKGObjectModelBase::headerData(int iSection, Qt::Orientation iOrientation, int iRole) const
{
_SKGTRACEINFUNC(10)
if (iOrientation == Qt::Horizontal) {
if (iRole == Qt::DisplayRole) {
QString att;
if (iSection >= 0 && iSection < m_listAttibutes.count()) {
att = m_listAttibutes.at(iSection);
} else {
att = SKGServices::intToString(iSection);
}
return getDocument()->getDisplay(getTable() % '.' % att).remove(getTable() % '.');
}
if (iRole == Qt::UserRole) {
QString att;
if (iSection >= 0 && iSection < m_listAttibutes.count()) {
att = m_listAttibutes.at(iSection);
} else {
att = SKGServices::intToString(iSection);
}
int indexAtt = m_listSupported.indexOf(att);
att = getDocument()->getDisplay(getTable() % '.' % att).remove(getTable() % '.');
if (indexAtt >= 0 && indexAtt < m_listVisibility.count()) {
bool visible = m_listVisibility.at(indexAtt);
att += QStringLiteral("|") % (visible ? QStringLiteral("Y") : QStringLiteral("N"));
if (indexAtt >= 0 && indexAtt < m_listSize.count()) {
att += '|' % SKGServices::intToString(m_listSize.at(indexAtt));
}
}
return att;
}
if (iRole == Qt::DecorationRole) {
QString att;
if (iSection >= 0 && iSection < m_listAttibutes.count()) {
att = m_listAttibutes.at(iSection);
} else {
att = SKGServices::intToString(iSection);
}
return getDocument()->getIcon(getTable() % '.' % att);
}
}
return QVariant();
}
SKGObjectBase SKGObjectModelBase::getObject(const QModelIndex& iIndex) const
{
SKGObjectBase* obj = getObjectPointer(iIndex);
SKGObjectBase output;
if (obj != nullptr) {
output = *obj;
}
return output;
}
SKGObjectBase* SKGObjectModelBase::getObjectPointer(const QModelIndex& iIndex) const
{
_SKGTRACEINFUNC(10)
return m_objectsHashTable.value(iIndex.internalId());
}
QVariant SKGObjectModelBase::data(const QModelIndex& iIndex, int iRole) const
{
if (!iIndex.isValid()) {
return QVariant();
}
_SKGTRACEINFUNC(10)
// Build cache id
QString idcache = getObjectPointer(iIndex)->getUniqueID() %
"-" % SKGServices::intToString(iIndex.row()) %
"-" % SKGServices::intToString(iIndex.column()) %
"-" % SKGServices::intToString(iRole);
// Check cache
if (!m_cache->contains(idcache)) {
// Compute value
m_cache->insert(idcache, computeData(iIndex, iRole));
}
return m_cache->value(idcache);
}
QVariant SKGObjectModelBase::computeData(const QModelIndex& iIndex, int iRole) const
{
if (!iIndex.isValid()) {
return QVariant();
}
_SKGTRACEINFUNC(10)
switch (iRole) {
case Qt::BackgroundRole: {
SKGObjectBase* obj = getObjectPointer(iIndex);
if (obj->getTable().isEmpty()) {
// This is a group
return QApplication::palette().brush(QPalette::Button);
}
break;
}
case Qt::DisplayRole:
case Qt::EditRole:
case Qt::UserRole: {
SKGObjectBase* obj = getObjectPointer(iIndex);
QString att = m_listAttibutes.at(iIndex.column());
if (obj->getTable().isEmpty()) {
// This is a group
if (iIndex.column() == 0) {
if (iRole == Qt::UserRole) {
return -obj->getID(); // For sorting
}
int nb = rowCount(iIndex);
// Is it possible to compute sums of f_CURRENTAMOUNT ?
int posAmount = m_listAttibutes.indexOf(QStringLiteral("f_CURRENTAMOUNT"));
if (posAmount == -1) {
posAmount = m_listAttibutes.indexOf(QStringLiteral("f_REALCURRENTAMOUNT"));
}
if (posAmount != -1 && nb > 0) {
// Compute sums
double sum = 0.0;
double average = 0.0;
double min = std::numeric_limits<double>::max();
double max = -std::numeric_limits<double>::max();
for (int i = 0; i < nb ; ++i) {
double amount = data(SKGObjectModelBase::index(i, posAmount, iIndex), Qt::UserRole).toDouble();
sum += amount;
max = qMax(max, amount);
min = qMin(min, amount);
}
average = sum / nb;
return i18nc("How to display a grouping title. Here \"title (count) Sum= [min , average , max]\"", "%1: %2 (%3) Sum=%4 [%5 , %6 , %7]",
getDocument()->getDisplay(m_groupby),
obj->getAttribute(QStringLiteral("t_title")),
nb,
formatMoney(sum),
formatMoney(min),
formatMoney(average),
formatMoney(max));
}
return i18nc("How to display a grouping title. Here \"title (count)\"", "%1: %2 (%3)",
getDocument()->getDisplay(m_groupby),
obj->getAttribute(QStringLiteral("t_title")),
nb);
}
return "";
}
QString val;
if (att.startsWith(QLatin1String("p_"))) {
// This is a property
val = obj->getProperty(att.right(att.count() - 2));
} else {
// This is a real attribute
val = obj->getAttribute(att);
switch (getAttributeType(iIndex.column())) {
case SKGServices::FLOAT: {
double dval = SKGServices::stringToDouble(val);
return dval;
}
case SKGServices::INTEGER: {
return SKGServices::stringToInt(val);
}
case SKGServices::DATE: {
QDate dval = SKGServices::stringToTime(val).date();
if (iRole == Qt::DisplayRole) {
return SKGMainPanel::dateToString(dval);
}
if (iRole == Qt::UserRole) {
return dval;
}
}
default: {
}
}
if (m_doctransactionTable && att == QStringLiteral("t_savestep")) {
return "";
}
}
// return val+"("+SKGServices::intToString(rowCount(index))+")";
return val;
}
case Qt::FontRole: {
SKGObjectBase* obj = getObjectPointer(iIndex);
// Text color
if (obj->getTable().isEmpty()) {
// This is a group
if (iIndex.column() == 0) {
QFont f;
f.setBold(true);
return QVariant::fromValue(f);
}
return "";
}
int propertyId = data(iIndex, 101).toInt();
if (propertyId != 0) {
SKGPropertyObject p(m_document, propertyId);
if (!p.getUrl().scheme().isEmpty()) {
QFont f;
f.setUnderline(true);
return QVariant::fromValue(f);
}
}
break;
}
case Qt::TextColorRole: {
// Text color
if (getAttributeType(iIndex.column()) == SKGServices::FLOAT) {
QVariant value_displayed = SKGObjectModelBase::data(iIndex, Qt::UserRole);
bool ok = false;
double value_double = value_displayed.toDouble(&ok);
if (ok && value_double < 0) {
return m_fontNegativeColor;
}
}
int propertyId = data(iIndex, 101).toInt();
if (propertyId != 0) {
SKGPropertyObject p(m_document, propertyId);
if (!p.getUrl().scheme().isEmpty()) {
KColorScheme scheme(QPalette::Normal);
return QVariant::fromValue(scheme.foreground(KColorScheme::ActiveText).color());
}
}
break;
}
case Qt::TextAlignmentRole: {
// Text alignment
SKGServices::AttributeType attType = getAttributeType(iIndex.column());
return static_cast<int>(Qt::AlignVCenter | (attType == SKGServices::FLOAT || attType == SKGServices::INTEGER ? Qt::AlignRight : Qt::AlignLeft));
}
case Qt::DecorationRole: {
// Decoration
SKGObjectBase* obj = getObjectPointer(iIndex);
QString att = m_listAttibutes.at(iIndex.column());
if (obj->getTable().isEmpty()) {
// This is a group
if (iIndex.column() == 0) {
return QVariant::fromValue(SKGServices::fromTheme(QStringLiteral("arrow-right")));
};
return "";
}
if (iIndex.column() == 0 && m_nodeTable) {
SKGNodeObject node(*obj);
return QVariant::fromValue(node.getIcon());
}
if (iIndex.column() == 0 && m_doctransactionTable) {
return QVariant::fromValue(SKGServices::fromTheme(obj->getAttribute(QStringLiteral("t_mode")) == QStringLiteral("U") ? QStringLiteral("edit-undo") : QStringLiteral("edit-redo")));
}
if (m_doctransactionTable && att == QStringLiteral("t_savestep")) {
if (obj->getAttribute(QStringLiteral("t_savestep")) == QStringLiteral("Y")) {
return QVariant::fromValue(SKGServices::fromTheme(QStringLiteral("document-save")));
}
}
break;
}
case Qt::ToolTipRole: {
// Tooltip
QString toolTipString;
SKGObjectBase* obj = getObjectPointer(iIndex);
if (obj != nullptr && m_document != nullptr) {
if (m_doctransactionTable) {
SKGDocument::SKGMessageList msg;
m_document->getMessages(obj->getID(), msg);
int nbMessages = msg.count();
if (nbMessages > 0) {
for (int i = 0; i < nbMessages; ++i) {
if (i != 0) {
toolTipString += '\n';
}
toolTipString += msg.at(i).Text;
}
}
} else if (getAttributeType(iIndex.column()) == SKGServices::DATE) {
QString att = m_listAttibutes.at(iIndex.column());
QString val = obj->getAttribute(att);
QDate dval = SKGServices::stringToTime(val).date();
QString fancyDate = QLocale().toString(dval, QLocale::LongFormat);
QString shortDate = QLocale().toString(dval, QLocale::ShortFormat);
if (shortDate != fancyDate) {
toolTipString = shortDate;
}
}
// Add properties
QStringList props = obj->getProperties();
if (!props.isEmpty() && !toolTipString.isEmpty()) {
toolTipString += '\n';
}
for (const auto& prop : qAsConst(props)) {
if (!toolTipString.isEmpty()) {
toolTipString += '\n';
}
toolTipString += i18nc("To display a property and its value", "%1=%2", prop, obj->getProperty(prop));
}
// Add UUID
IFSKGTRACEL(1) {
toolTipString += '\n' % obj->getUniqueID();
}
}
return toolTipString;
}
case 99: {
SKGObjectBase* obj = getObjectPointer(iIndex);
if (obj != nullptr) {
return SKGServices::stringToDouble(obj->getAttribute(QStringLiteral("f_sortorder")));
}
break;
}
case 101: {
SKGObjectBase* obj = getObjectPointer(iIndex);
// Is it a URL ?
QString att = m_listAttibutes.at(iIndex.column());
if (att.startsWith(QLatin1String("p_"))) {
SKGPropertyObject p(obj->getPropertyObject(att.right(att.count() - 2)));
if (!p.getUrl().scheme().isEmpty()) {
return QVariant::fromValue(p.getID());
}
} else if (m_parametersTable && att == QStringLiteral("t_value")) {
SKGPropertyObject p(*obj);
if (!p.getUrl().scheme().isEmpty()) {
return QVariant::fromValue(p.getID());
}
}
return 0;
}
default : {
}
}
return QVariant();
}
Qt::ItemFlags SKGObjectModelBase::flags(const QModelIndex& iIndex) const
{
_SKGTRACEINFUNC(10)
Qt::ItemFlags f = QAbstractItemModel::flags(iIndex) | Qt::ItemIsDropEnabled;
if (iIndex.isValid()) {
f |= Qt::ItemIsUserCheckable;
}
if (m_nodeTable && iIndex.isValid()) {
f |= Qt::ItemIsEditable | Qt::ItemIsDragEnabled;
}
if (iIndex.isValid()) {
QString att = m_listAttibutes.at(iIndex.column());
if (att.toLower() == att || !getDocument()->getRealAttribute(att).isEmpty()) {
f |= Qt::ItemIsEditable;
}
SKGObjectBase* obj = getObjectPointer(iIndex);
if (obj->getTable().isEmpty()) {
f = Qt::ItemIsEnabled;
}
}
return f;
}
bool SKGObjectModelBase::setData(const QModelIndex& iIndex, const QVariant& iValue, int iRole)
{
if (!iIndex.isValid()) {
return false;
}
if (iRole == Qt::EditRole) {
SKGError err;
if (m_nodeTable) {
SKGNodeObject obj(getObject(iIndex));
QString name = iValue.toString();
SKGBEGINTRANSACTION(*getDocument(), i18nc("Noun, name of the user action", "Bookmark update '%1'", name), err)
IFOKDO(err, err = obj.setName(name))
IFOKDO(err, obj.save())
} else {
SKGObjectBase obj(getObject(iIndex));
SKGBEGINTRANSACTION(*getDocument(), i18nc("Noun, name of the user action", "Update object"), err)
SKGObjectBase obj2(obj.getDocument(), obj.getRealTable(), obj.getID()); // To be sure this is not a complex object
QString att = m_listAttibutes.at(iIndex.column());
IFOKDO(err, obj2.setAttribute(att, att.startsWith(QLatin1String("d_")) && iValue.canConvert<QDateTime>() ? SKGServices::dateToSqlString(iValue.toDateTime()) : iValue.toString()))
IFOKDO(err, obj2.save())
}
SKGMainPanel::displayErrorMessage(err);
return !err;
}
return QAbstractItemModel::setData(iIndex, iValue, iRole);
}
Qt::DropActions SKGObjectModelBase::supportedDragActions() const
{
return (m_nodeTable ? Qt::MoveAction : Qt::IgnoreAction);
}
Qt::DropActions SKGObjectModelBase::supportedDropActions() const
{
return Qt::MoveAction | Qt::LinkAction | Qt::CopyAction;
}
QStringList SKGObjectModelBase::mimeTypes() const
{
QStringList types;
types << "application/skg." % getRealTable() % ".ids";
types << QStringLiteral("application/data");
types << QStringLiteral("text/uri-list");
return types;
}
QMimeData* SKGObjectModelBase::mimeData(const QModelIndexList& iIndexes) const
{
auto md = new QMimeData();
QByteArray encodedData;
QDataStream stream(&encodedData, QIODevice::WriteOnly);
QString t = getTable();
for (const auto& idx : qAsConst(iIndexes)) {
if (idx.isValid() && idx.column() == 0) {
SKGObjectBase obj = getObject(idx);
t = obj.getRealTable();
stream << t;
stream << obj.getID();
}
}
md->setData("application/skg." % t % ".ids", encodedData);
return md;
}
bool SKGObjectModelBase::dropMimeData(const QMimeData* iData,
Qt::DropAction iAction,
int iRow, int iColumn,
const QModelIndex& iParent)
{
Q_UNUSED(iRow)
if (iAction == Qt::IgnoreAction) {
return true;
}
if ((iData == nullptr) || !(iData->hasFormat(QStringLiteral("application/skg.node.ids")) || iData->hasUrls())) {
return false; // TODO(Stephane MANKOWSKI): accept all
}
if (iColumn > 0) {
return false;
}
SKGError err;
// Drop files
if (iData->hasUrls() && iParent.isValid() && getRealTable() != QStringLiteral("node")) {
QList<QUrl> urls = iData->urls();
int nb = urls.count();
{
SKGObjectBase obj(getObject(iParent));
SKGBEGINPROGRESSTRANSACTION(*getDocument(), i18nc("Noun, name of the user action", "Property creation"), err, nb)
for (int i = 0; !err && i < nb; ++i) {
QString name = i18n("File");
int idx = 1;
while (!err && !obj.getProperty(name).isEmpty()) {
idx++;
name = i18n("File") % " (" % SKGServices::intToString(idx) % ')';
}
QString f = urls.at(i).toLocalFile();
err = obj.setProperty(name, f, iAction == Qt::LinkAction ? QLatin1String("") : f);
if (!err && iAction == Qt::MoveAction) {
QFile(f).remove();
}
IFOKDO(err, getDocument()->stepForward(i + 1))
}
}
} else if (iData->hasFormat(QStringLiteral("application/skg.node.ids"))) {
// Drop nodes
QByteArray encodedData = iData->data(QStringLiteral("application/skg.node.ids"));
QDataStream stream(&encodedData, QIODevice::ReadOnly);
QStringList newItems;
QModelIndex parentIndex = iParent;
SKGNodeObject parentNode;
if (parentIndex.isValid()) {
parentNode = getObject(parentIndex);
if (!parentNode.isFolder()) {
// The parent is not a directory
parentNode.getParentNode(parentNode);
parentIndex = parentIndex.parent();
}
}
{
SKGBEGINTRANSACTION(*getDocument(), i18nc("Noun, name of the user action", "Move bookmark"), err)
double min = 0;
double max = 0;
if (iRow >= 1) {
QModelIndex previousIndex = SKGObjectModelBase::index(iRow - 1, 0, parentIndex);
SKGNodeObject previousObject(getObject(previousIndex));
min = previousObject.getOrder();
}
if (iRow >= rowCount(parentIndex)) {
max = min + 1;
} else {
QModelIndex nextIndex = SKGObjectModelBase::index(iRow, 0, parentIndex);
SKGNodeObject nextObject(getObject(nextIndex));
max = nextObject.getOrder();
}
if (max <= min) {
max = min + 1;
}
while (!stream.atEnd() && !err) {
int o_id;
QString o_table;
stream >> o_table;
stream >> o_id;
// Set parent
SKGNodeObject child(getDocument(), o_id);
err = child.load();
QString oldName = child.getDisplayName();
IFOK(err) {
if (parentIndex.isValid()) {
err = child.setParentNode(parentNode);
} else {
err = child.removeParentNode();
}
}
// Set order
IFOKDO(err, child.setOrder((min + max) / 2.0))
// Save
IFOKDO(err, child.save())
// Send message
IFOKDO(err, getDocument()->sendMessage(i18nc("An information to the user", "The bookmark '%1' has been moved to '%2'", oldName, child.getDisplayName()), SKGDocument::Hidden))
}
}
}
SKGMainPanel::displayErrorMessage(err);
return !err;
}
void SKGObjectModelBase::pageChanged()
{
if (m_isResetRealyNeeded) {
dataModified(QLatin1String(""), 0);
}
}
void SKGObjectModelBase::dataModified(const QString& iTableName, int iIdTransaction)
{
if (getTable() == iTableName || iTableName.isEmpty()) {
SKGTRACEINFUNC(1)
SKGTRACEL(1) << "getTable=" << getRealTable() << endl;
SKGTRACEL(1) << "Parameters=" << iTableName << " , " << iIdTransaction << endl;
SKGTabPage* page = SKGTabPage::parentTabPage(qobject_cast< QWidget* >(this->QObject::parent()));
SKGTabPage* cpage = SKGMainPanel::getMainPanel() != nullptr ? SKGMainPanel::getMainPanel()->currentPage() : nullptr;
if (page != nullptr && page != cpage) {
m_isResetRealyNeeded = true;
return;
}
// Full refresh
m_isResetRealyNeeded = true;
// Refresh model
refresh();
}
}
QString SKGObjectModelBase::getAttributeForGrouping(const SKGObjectBase& iObject, const QString& iAttribute) const
{
if (iAttribute.startsWith(QLatin1String("p_"))) {
// This is a property
return iObject.getProperty(iAttribute.right(iAttribute.count() - 2));
}
// This is a real attribute
return iObject.getAttribute(iAttribute);
}
QString SKGObjectModelBase::formatMoney(double iValue) const
{
return SKGServices::doubleToString(iValue);
}
diff --git a/skgbasegui/skgobjectmodelbase.h b/skgbasegui/skgobjectmodelbase.h
index 08b23b653..79d240f3e 100644
--- a/skgbasegui/skgobjectmodelbase.h
+++ b/skgbasegui/skgobjectmodelbase.h
@@ -1,404 +1,404 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGOBJECTMODELBASE_H
#define SKGOBJECTMODELBASE_H
/** @file
* This file defines classes skgbjectmodelbase.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include <qabstractitemmodel.h>
#include <qstringlist.h>
#include "skgbasegui_export.h"
#include "skgdocument.h"
#include "skgobjectbase.h"
class QWidget;
/**
* The Table model managing SKGObjectBase
*/
class SKGBASEGUI_EXPORT SKGObjectModelBase : public QAbstractItemModel
{
Q_OBJECT
public:
/**
* Default constructor
* @param iDocument the document where to search
* @param iTable the table where to search
* @param iWhereClause the where clause
* @param iParent parent QT object
* @param iParentAttribute the attribute to find the parent of an object clause to find children
* @param iResetOnCreation to reset data during creation
*/
SKGObjectModelBase(SKGDocument* iDocument,
const QString& iTable,
QString iWhereClause,
QWidget* iParent,
QString iParentAttribute = QString(),
bool iResetOnCreation = true);
/**
* Destructor
*/
~SKGObjectModelBase() override;
/**
* Allows to block a refresh
* @param iBlocked blocking status
* @return previous value
*/
virtual bool blockRefresh(bool iBlocked);
/**
* To know if the refresh is blocked
* @return true or false
*/
virtual bool isRefreshBlocked();
/**
* Returns true if parent has at least one child.
* @param iParent the parent
* @return true or false
*/
bool hasChildren(const QModelIndex& iParent = QModelIndex()) const override;
/**
* Returns the number of row for the given parent.
* @param iParent the parent
* @return the number of row
*/
int rowCount(const QModelIndex& iParent = QModelIndex()) const override;
/**
* Returns the index of the item in the model specified by the given row, column and parent index.
* @param row row
* @param column column
* @param iParent parent
* @return the index
*/
QModelIndex index(int row, int column, const QModelIndex& iParent = QModelIndex()) const override;
/**
* Returns the parent of the model item with the given index, or QModelIndex() if it has no parent.
* @param iIndex index
* @return the parent
*/
QModelIndex parent(const QModelIndex& iIndex) const override;
/**
* Returns the number of columns for the given parent.
* @param iParent the parent
* @return the number of column
*/
int columnCount(const QModelIndex& iParent = QModelIndex()) const override;
/**
* Returns the data stored under the given role for the item referred to by the index.
* @param iIndex the index
* @param iRole the role
* @return the returned value
*/
QVariant data(const QModelIndex& iIndex, int iRole = Qt::DisplayRole) const override;
/**
* Returns the data stored under the given role for the item referred to by the index.
* @param iIndex the index
* @param iRole the role
* @return the returned value
*/
virtual QVariant computeData(const QModelIndex& iIndex, int iRole = Qt::DisplayRole) const;
/**
* Returns the SKGObjectBase for the item referred to by the index.
* @param iIndex the index
* @return the returned SKGObjectBase
*/
virtual SKGObjectBase getObject(const QModelIndex& iIndex) const;
/**
* Returns the SKGObjectBase for the item referred to by the index.
* @param iIndex the index
* @return the returned SKGObjectBase. Do not delete it !
*/
virtual SKGObjectBase* getObjectPointer(const QModelIndex& iIndex) const;
/**
* Returns the data for the given role and section in the header with the specified orientation.
* @param iSection the section
* @param iOrientation the orientation
* @param iRole the role
* @return the header data
*/
QVariant headerData(int iSection, Qt::Orientation iOrientation, int iRole = Qt::DisplayRole) const override;
/**
* Returns the item flags for the given index.
* @param iIndex index of the object
* @return flags of the given index
*/
Qt::ItemFlags flags(const QModelIndex& iIndex) const override;
/**
* Sets the role data for the item at index to value. Returns true if successful; otherwise returns false.
* @param iIndex index of the object
* @param iValue value
* @param iRole role
* @return
*/
bool setData(const QModelIndex& iIndex, const QVariant& iValue, int iRole = Qt::EditRole) override;
/**
* Return the index of the attribute, -1 if not found
* @param iAttributeName the attribute name
* @return index of this attribute
*/
virtual int getIndexAttribute(const QString& iAttributeName) const;
/**
* Return the attribute for an index
* @param iIndex the index
* @return attribute
*/
virtual QString getAttribute(int iIndex) const;
/**
* Return the type of attribute for an index
* @param iIndex the index
* @return type of attribute
*/
virtual SKGServices::AttributeType getAttributeType(int iIndex) const;
/**
* Set the table. Do not forget to do a reset after that.
* @param iTable the table name
*/
void setTable(const QString& iTable);
/**
* Get table name
* @return table name
*/
virtual QString getTable() const;
/**
* Set the attribute used for grouping
* @param iAttribute the attribute name
*/
virtual void setGroupBy(const QString& iAttribute = QString());
/**
* Get the attribute used for grouping
* @return attribute name
*/
virtual QString getGroupBy() const;
/**
* Get the attribute used for parent / child relationship
* @return attribute name
*/
virtual QString getParentChildAttribute() const;
/**
* Get real table name
* @return real table name
*/
virtual QString getRealTable() const;
/**
* Get where clause
* @return where clause
*/
virtual QString getWhereClause() const;
/**
* Get document
* @return document
*/
virtual SKGDocument* getDocument() const;
/**
* Set the list of supported attributes. Do not forget to do a reset after that.
* @param iListAttribute the list of attributes. If the list is empty then the default list is set.
* The format of this string is the following one: attribute name[|visibility Y or N[|size]];attribute name[|visibility Y or N[|size]];...
*/
virtual void setSupportedAttributes(const QStringList& iListAttribute);
/**
* Set the filter. Do not forget to do a reset after that.
* @param iWhereClause the where clause
* @return true is the filter is really changed
*/
virtual bool setFilter(const QString& iWhereClause);
/**
* Returns the actions supported by the data in this model.
* @return Qt::DropActions
*/
Qt::DropActions supportedDragActions() const override;
/**
* Returns the actions supported by the data in this model.
* @return Qt::DropActions
*/
Qt::DropActions supportedDropActions() const override;
/**
* Get list of supported schemas
* @return list of schemas @see SKGModelTemplate
*/
virtual SKGDocument::SKGModelTemplateList getSchemas() const;
/**
* Returns a list of MIME types that can be used to describe a list of model indexes.
* @return list of mime types
*/
QStringList mimeTypes() const override;
/**
* Returns an object that contains serialized items of data corresponding to the list of indexes specified.
*The formats used to describe the encoded data is obtained from the mimeTypes() function.
* If the list of indexes is empty, or there are no supported MIME types, 0 is returned rather than a serialized empty list.
* @param iIndexes the index object
* @return the mime data
*/
QMimeData* mimeData(const QModelIndexList& iIndexes) const override;
/**
* Handles the data supplied by a drag and drop operation that ended with the given action.
* Returns true if the data and action can be handled by the model; otherwise returns false.
* Although the specified row, column and parent indicate the location of an item in the model where the operation ended,
*it is the responsibility of the view to provide a suitable location for where the data should be inserted.
* @param iData mime data
* @param iAction action
* @param iRow row
* @param iColumn column
* @param iParent parent
* @return true if the dropping was successful otherwise false.
*/
bool dropMimeData(const QMimeData* iData,
Qt::DropAction iAction,
int iRow, int iColumn,
const QModelIndex& iParent) override;
Q_SIGNALS:
/**
* Emitted before reset
*/
void beforeReset();
/**
* Emitted after reset
*/
void afterReset();
public Q_SLOTS:
/**
* Refresh the model.
*/
virtual void refresh();
/**
* data are modified
* @param iTableName table name
* @param iIdTransaction the id of the transaction for direct modifications of the table (update of modify objects is enough)
*or 0 in case of modifications by impact (full table must be refreshed)
*/
virtual void dataModified(const QString& iTableName = QString(), int iIdTransaction = 0);
protected Q_SLOTS:
/**
* This method is called by refresh to build the cache (to improve performance)
*/
virtual void buidCache();
protected:
/**
*list of attributes
*/
QStringList m_listAttibutes;
/**
*list of attributes
*/
QList<SKGServices::AttributeType> m_listAttributeTypes;
/**
*list of supported schemas
*/
SKGDocument::SKGModelTemplateList m_listSchema;
/**
*To disable/enable reset
*/
bool m_isResetRealyNeeded;
/**
*A cache for value computed in data
*/
QMap<QString, QVariant>* m_cache;
/**
* Get the attribute value for grouping
* @param iObject the object
* @param iAttribute the attribute name
* @return the value of the attribute
*/
virtual QString getAttributeForGrouping(const SKGObjectBase& iObject, const QString& iAttribute) const;
/**
*The negative color
*/
QVariant m_fontNegativeColor;
/**
* Get the string of an amount
* @param iValue the value
* @return the string
*/
virtual QString formatMoney(double iValue) const;
private Q_SLOTS:
void pageChanged();
private:
Q_DISABLE_COPY(SKGObjectModelBase)
void clear();
SKGDocument* m_document;
QString m_table;
QString m_realTable;
QString m_whereClause;
QString m_parentAttribute;
QString m_groupby;
SKGObjectBase::SKGListSKGObjectBase m_listObjects;
QHash<int, SKGIntList> m_parentChildRelations;
QHash<int, int> m_childParentRelations;
QHash<int, SKGObjectBase*> m_objectsHashTable;
QHash<int, int> m_objectsHashTableRows;
QStringList m_listSupported;
QList<bool> m_listVisibility;
QList<int> m_listSize;
bool m_doctransactionTable;
bool m_nodeTable;
bool m_parametersTable;
bool m_refreshBlocked;
};
#endif
diff --git a/skgbasegui/skgperiodedit.cpp b/skgbasegui/skgperiodedit.cpp
index 017f0883c..1926bf4a9 100644
--- a/skgbasegui/skgperiodedit.cpp
+++ b/skgbasegui/skgperiodedit.cpp
@@ -1,607 +1,607 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* A period editor.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgperiodedit.h"
#include "skgmainpanel.h"
#include <qdom.h>
#include "skgservices.h"
#include "skgtraces.h"
SKGPeriodEdit::SKGPeriodEdit(QWidget* iParent, bool iModeEnabled)
: QWidget(iParent), m_modeEnable(iModeEnabled), m_count(0)
{
ui.setupUi(this);
ui.kPeriod->addItem(i18nc("Period mode", "All Dates"), static_cast<int>(SKGPeriodEdit::ALL));
ui.kPeriod->addItem(i18nc("Period mode", "Current..."), static_cast<int>(SKGPeriodEdit::CURRENT));
ui.kPeriod->addItem(i18nc("Period mode", "Previous..."), static_cast<int>(SKGPeriodEdit::PREVIOUS));
ui.kPeriod->addItem(i18nc("Period mode", "Last..."), static_cast<int>(SKGPeriodEdit::LAST));
ui.kPeriod->addItem(i18nc("Period mode", "Custom..."), static_cast<int>(SKGPeriodEdit::CUSTOM));
ui.kPeriod->addItem(i18nc("Period mode", "Timeline..."), static_cast<int>(SKGPeriodEdit::TIMELINE));
ui.kInterval->addItem(i18nc("Period interval", "day(s)"), 0);
ui.kInterval->addItem(i18nc("Period interval", "week(s)"), 1);
ui.kInterval->addItem(i18nc("Period interval", "month(s)"), 2);
ui.kInterval->addItem(i18nc("Period interval", "quarter(s)"), 4);
ui.kInterval->addItem(i18nc("Period interval", "semester(s)"), 5);
ui.kInterval->addItem(i18nc("Period interval", "year(s)"), 3);
ui.kPeriod->setCurrentIndex(1);
ui.kInterval->setCurrentIndex(2);
connect(ui.kPeriod, static_cast<void (SKGComboBox::*)(const QString&)>(&SKGComboBox::currentTextChanged), this, &SKGPeriodEdit::refresh);
connect(ui.kInterval, static_cast<void (SKGComboBox::*)(const QString&)>(&SKGComboBox::currentTextChanged), this, &SKGPeriodEdit::refresh);
connect(ui.kDateBegin, &SKGDateEdit::dateEntered, this, &SKGPeriodEdit::refresh);
connect(ui.kDateEnd, &SKGDateEdit::dateEntered, this, &SKGPeriodEdit::refresh);
connect(ui.kNbIntervals, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), this, &SKGPeriodEdit::refresh);
connect(ui.kTimeline, &QSlider::valueChanged, this, &SKGPeriodEdit::refresh);
connect(ui.kFuture, &QCheckBox::stateChanged, this, &SKGPeriodEdit::refresh);
}
SKGPeriodEdit::~SKGPeriodEdit()
= default;
QString SKGPeriodEdit::getState()
{
SKGTRACEINFUNC(10)
QDomDocument doc(QStringLiteral("SKGML"));
QDomElement root = doc.createElement(QStringLiteral("parameters"));
doc.appendChild(root);
root.setAttribute(QStringLiteral("period"), SKGServices::intToString(mode()));
if (mode() == CUSTOM) {
root.setAttribute(QStringLiteral("date_begin"), SKGServices::intToString(ui.kDateBegin->date().toJulianDay()));
root.setAttribute(QStringLiteral("date_end"), SKGServices::intToString(ui.kDateEnd->date().toJulianDay()));
}
root.setAttribute(QStringLiteral("interval"), SKGServices::intToString(ui.kInterval->itemData(ui.kInterval->currentIndex()).toInt()));
root.setAttribute(QStringLiteral("nb_intervals"), SKGServices::intToString(ui.kNbIntervals->value()));
root.setAttribute(QStringLiteral("timeline"), SKGServices::intToString(ui.kTimeline->value()));
root.setAttribute(QStringLiteral("future"), ui.kFuture->isChecked() ? QStringLiteral("Y") : QStringLiteral("N"));
return doc.toString();
}
void SKGPeriodEdit::setState(const QString& iState)
{
SKGTRACEINFUNC(10)
QDomDocument doc(QStringLiteral("SKGML"));
doc.setContent(iState);
QDomElement root = doc.documentElement();
QString period = root.attribute(QStringLiteral("period"));
QString interval = root.attribute(QStringLiteral("interval"));
QString nb_interval = root.attribute(QStringLiteral("nb_intervals"));
QString timeline = root.attribute(QStringLiteral("timeline"));
QString date_begin = root.attribute(QStringLiteral("date_begin"));
QString date_end = root.attribute(QStringLiteral("date_end"));
QString future = root.attribute(QStringLiteral("future"));
// Default values
if (period.isEmpty()) {
period = '1';
}
if (interval.isEmpty()) {
interval = '2';
}
if (nb_interval.isEmpty()) {
nb_interval = '1';
}
if (timeline.isEmpty()) {
timeline = '1';
}
ui.kPeriod->setCurrentIndex(ui.kPeriod->findData(SKGServices::stringToInt(period)));
ui.kInterval->setCurrentIndex(ui.kInterval->findData(SKGServices::stringToInt(interval)));
ui.kTimeline->setValue(SKGServices::stringToInt(timeline));
ui.kNbIntervals->setValue(SKGServices::stringToInt(nb_interval));
ui.kFuture->setChecked(future == QStringLiteral("Y"));
if (!date_begin.isEmpty()) {
ui.kDateBegin->setDate(QDate::fromJulianDay(SKGServices::stringToInt(date_begin)));
}
if (!date_end.isEmpty()) {
ui.kDateEnd->setDate(QDate::fromJulianDay(SKGServices::stringToInt(date_end)));
}
refresh();
}
QString SKGPeriodEdit::text() const
{
QString during = ui.kPeriod->text().remove(QStringLiteral("..."));
SKGPeriodEdit::PeriodMode m = mode();
if (m == CUSTOM || m == TIMELINE) {
during = i18nc("A period", "From %1 to %2", SKGMainPanel::dateToString(ui.kDateBegin->date()), SKGMainPanel::dateToString(ui.kDateEnd->date()));
} else if (m != ALL) {
if (m == PREVIOUS) {
switch (ui.kInterval->itemData(ui.kInterval->currentIndex()).toInt()) {
case 0:
during = i18ncp("A period", "Previous day", "%1 previous days", ui.kNbIntervals->value());
break;
case 1:
during = i18ncp("A period", "Previous week", "%1 previous weeks", ui.kNbIntervals->value());
break;
case 2:
during = i18ncp("A period", "Previous month", "%1 previous months", ui.kNbIntervals->value());
break;
case 3:
during = i18ncp("A period", "Previous year", "%1 previous years", ui.kNbIntervals->value());
break;
case 4:
during = i18ncp("A period", "Previous quarter", "%1 previous quarters", ui.kNbIntervals->value());
break;
case 5:
default:
during = i18ncp("A period", "Previous semester", "%1 previous semesters", ui.kNbIntervals->value());
break;
}
} else if (m == LAST) {
switch (ui.kInterval->itemData(ui.kInterval->currentIndex()).toInt()) {
case 0:
during = i18ncp("A period", "Last day", "%1 last days", ui.kNbIntervals->value());
break;
case 1:
during = i18ncp("A period", "Last week", "%1 last weeks", ui.kNbIntervals->value());
break;
case 2:
during = i18ncp("A period", "Last month", "%1 last months", ui.kNbIntervals->value());
break;
case 3:
during = i18ncp("A period", "Last year", "%1 last years", ui.kNbIntervals->value());
break;
case 4:
during = i18ncp("A period", "Last quarter", "%1 last quarters", ui.kNbIntervals->value());
break;
case 5:
default:
during = i18ncp("A period", "Last semester", "%1 last semesters", ui.kNbIntervals->value());
break;
}
} else if (m == CURRENT) {
switch (ui.kInterval->itemData(ui.kInterval->currentIndex()).toInt()) {
case 0:
during = i18nc("A period", "Current day");
break;
case 1:
during = i18nc("A period", "Current week");
break;
case 2:
during = i18nc("A period", "Current month");
break;
case 3:
during = i18nc("A period", "Current year");
break;
case 4:
during = i18nc("A period", "Current quarter");
break;
case 5:
default:
during = i18nc("A period", "Current semester");
break;
}
}
}
return during;
}
SKGPeriodEdit::PeriodMode SKGPeriodEdit::mode() const
{
return static_cast<PeriodMode>(ui.kPeriod->itemData(ui.kPeriod->currentIndex()).toInt());
}
void SKGPeriodEdit::getDates(SKGPeriodEdit::PeriodMode iPeriod, SKGPeriodEdit::PeriodInterval iInterval, int iValue, QDate& oBeginDate, QDate& oEndDate, QDate iDate)
{
QDate a = iDate;
QDate b = a;
int val = iValue;
switch (iInterval) {
case DAY:
// Interval is in days
break;
case WEEK:
// Interval is in weeks
val *= 7;
break;
case MONTH:
default:
// Interval is in months
break;
case QUARTER:
// Interval is in quarter
val *= 3;
break;
case SEMESTER:
// Interval is in semester
val *= 6;
break;
case YEAR:
// Interval is in years
break;
}
switch (iPeriod) {
case CURRENT:
// Current Interval
switch (iInterval) {
case DAY:
// Interval is in days
break;
case WEEK:
// Interval is in weeks
a = a.addDays(1 - a.dayOfWeek());
b = a.addDays(7 - 1);
break;
case MONTH:
default:
// Interval is in months
a = a.addDays(1 - a.day());
b = a.addMonths(1).addDays(-1);
break;
case YEAR:
// Interval is in years
a = a.addDays(1 - a.day()).addMonths(1 - a.month());
b = a.addYears(1).addDays(-1);
break;
case QUARTER:
// Interval is in quarter
a = a.addDays(1 - a.day()).addMonths(1 - ((a.month() - 1) % 4));
b = a.addMonths(3).addDays(-1);
break;
case SEMESTER:
// Interval is in semester
a = a.addDays(1 - a.day()).addMonths(- ((a.month() - 1) % 6));
b = a.addMonths(6).addDays(-1);
break;
}
break;
case PREVIOUS:
// Previous Interval
switch (iInterval) {
case DAY:
// Interval is in days
b = b.addDays(-1);
a = b.addDays(-val + 1);
break;
case WEEK:
// Interval is in weeks
b = b.addDays(-a.dayOfWeek());
a = b.addDays(-val + 1);
break;
case MONTH:
default:
// Interval is in months
b = b.addDays(-b.day());
a = b.addDays(1).addMonths(-val);
break;
case YEAR:
// Interval is in years
b = b.addMonths(1 - b.month()).addDays(-b.day());
a = b.addDays(1).addYears(-val);
break;
case QUARTER:
// Interval is in quarter
b = b.addMonths(1 - ((b.month() - 1) % 4)).addDays(-b.day());
a = b.addDays(1).addMonths(-val);
break;
case SEMESTER:
// Interval is in semester
b = b.addMonths(- ((b.month() - 1) % 6)).addDays(-b.day());
a = b.addDays(1).addMonths(-val);
break;
}
break;
case LAST:
// Last Interval
switch (iInterval) {
case DAY:
// Interval is in days
a = a.addDays(-val);
break;
case WEEK:
// Interval is in weeks
a = a.addDays(-val);
break;
case MONTH:
default:
// Interval is in months
a = a.addMonths(-val);
break;
case YEAR:
// Interval is in years
a = a.addYears(-val);
break;
case QUARTER:
// Interval is in quarter
a = a.addMonths(-val);
break;
case SEMESTER:
// Interval is in semester
a = a.addMonths(-val);
break;
}
a = a.addDays(1);
break;
case TIMELINE:
// Timeline
switch (iInterval) {
case DAY:
// Interval is in days
a = a.addDays(iValue - 12);
b = a;
break;
case WEEK:
// Interval is in weeks
a = a.addDays(1 - a.dayOfWeek()).addDays((iValue - 12) * 7);
b = a.addDays(7 - 1);
break;
case MONTH:
default:
// Interval is in months
a = a.addDays(1 - a.day()).addMonths(iValue - 12);
b = a.addMonths(1).addDays(-1);
break;
case YEAR:
// Interval is in years
a = a.addDays(1 - a.day()).addMonths(1 - a.month()).addYears(iValue - 12);
b = a.addYears(1).addDays(-1);
break;
case QUARTER:
// Interval is in quarter
a = a.addDays(1 - a.day()).addMonths(1 - ((a.month() - 1) % 4)).addMonths(3 * (iValue - 12));
b = a.addMonths(3).addDays(-1);
break;
case SEMESTER:
// Interval is in semester
a = a.addDays(1 - a.day()).addMonths(- ((a.month() - 1) % 6)).addMonths(6 * (iValue - 12));
b = a.addMonths(6).addDays(-1);
break;
}
break;
default:
// Take all dates
a = a.addYears(-1);
break;
}
oBeginDate = a;
oEndDate = b;
}
void SKGPeriodEdit::getDates(QDate& oBeginDate, QDate& oEndDate)
{
SKGPeriodEdit::PeriodInterval interval = static_cast<SKGPeriodEdit::PeriodInterval>(ui.kInterval->itemData(ui.kInterval->currentIndex()).toInt());
int val = ui.kNbIntervals->value();
getDates(mode(), interval, mode() == TIMELINE ? ui.kTimeline->value() : val, oBeginDate, oEndDate);
}
QString SKGPeriodEdit::getWhereClause(bool iForecast, QString* oWhereClausForPreviousData, QString* oWhereClausForForecastData) const
{
// Build where clause
QString wc;
SKGPeriodEdit::PeriodInterval interval = static_cast<SKGPeriodEdit::PeriodInterval>(ui.kInterval->itemData(ui.kInterval->currentIndex()).toInt());
QString strfFormat;
QString sqlInterval;
QString sqlAttribute;
int val = ui.kNbIntervals->value();
int one = 1;
QDate a;
QDate b;
getDates(mode(), interval, mode() == TIMELINE ? ui.kTimeline->value() : val, a, b);
switch (interval) {
case DAY:
// Interval is in days
sqlAttribute = QStringLiteral("d_date");
strfFormat = QStringLiteral("'D'");
sqlInterval = QStringLiteral("DAY");
break;
case WEEK:
// Interval is in weeks
sqlAttribute = QStringLiteral("d_DATEWEEK");
strfFormat = QStringLiteral("'W'");
sqlInterval = QStringLiteral("DAY");
val *= 7;
one *= 7;
break;
case MONTH:
default:
// Interval is in months
sqlAttribute = QStringLiteral("d_DATEMONTH");
strfFormat = QStringLiteral("'M'");
sqlInterval = QStringLiteral("MONTH");
break;
case QUARTER:
// Interval is in quarter
sqlAttribute = QStringLiteral("d_DATEQUARTER");
strfFormat = QStringLiteral("'Q'");
sqlInterval = QStringLiteral("MONTH");
val *= 3;
one *= 3;
break;
case SEMESTER:
// Interval is in quarter
sqlAttribute = QStringLiteral("d_DATESEMESTER");
strfFormat = QStringLiteral("'S'");
sqlInterval = QStringLiteral("MONTH");
val *= 6;
one *= 6;
break;
case YEAR:
// Interval is in years
sqlAttribute = QStringLiteral("d_DATEYEAR");
strfFormat = QStringLiteral("'Y'");
sqlInterval = QStringLiteral("YEAR");
break;
}
switch (mode()) {
case CURRENT:
if (ui.kFuture->isChecked()) {
b = QDate(2099, 12, 31);
}
ui.kDateBegin->setDate(a);
ui.kDateEnd->setDate(b);
wc = sqlAttribute % " = (SELECT period(date('now'), " % strfFormat % "))";
if (ui.kFuture->isChecked()) {
wc += QStringLiteral(" OR d_date > (SELECT date('now'))");
}
if (oWhereClausForPreviousData != nullptr) {
*oWhereClausForPreviousData = sqlAttribute % " < (SELECT period(date('now'), " % strfFormat % "))";
}
if (oWhereClausForForecastData != nullptr) {
*oWhereClausForForecastData = QStringLiteral("d_date > (SELECT date('now'))");
}
break;
case PREVIOUS:
ui.kDateBegin->setDate(a);
ui.kDateEnd->setDate(b);
wc = sqlAttribute % ">=(SELECT period(date('now','start of month', '-" % SKGServices::intToString(val) % ' ' % sqlInterval % "')," % strfFormat % "))";
if (iForecast) {
wc += " AND period(d_date, " % strfFormat % ")<=(SELECT period(date('now','start of month', '-" % SKGServices::intToString(one) % ' ' % sqlInterval % "')," % strfFormat % "))"; // For forecast based on scheduled operations
if (oWhereClausForPreviousData != nullptr) {
*oWhereClausForPreviousData = sqlAttribute % " < (SELECT period(date('now','start of month', '-" % SKGServices::intToString(val) % ' ' % sqlInterval % "')," % strfFormat % "))";
}
if (oWhereClausForForecastData != nullptr) {
*oWhereClausForForecastData = sqlAttribute % " > (SELECT period(date('now','start of month', '-" % SKGServices::intToString(one) % ' ' % sqlInterval % "')," % strfFormat % "))";
}
}
break;
case LAST:
if (ui.kFuture->isChecked()) {
b = QDate(2099, 12, 31);
}
ui.kDateBegin->setDate(a);
ui.kDateEnd->setDate(b);
wc = "d_date > (SELECT date('now','-" % SKGServices::intToString(val) % ' ' % sqlInterval % "'))";
if (iForecast) {
wc += QStringLiteral(" AND d_date<=(SELECT date('now'))"); // For forecast based on scheduled operations
}
if (ui.kFuture->isChecked()) {
wc += QStringLiteral(" OR d_date > (SELECT date('now'))");
}
if (oWhereClausForPreviousData != nullptr) {
*oWhereClausForPreviousData = "d_date <= (SELECT date('now','-" % SKGServices::intToString(val) % ' ' % sqlInterval % "'))";
}
if (oWhereClausForForecastData != nullptr) {
*oWhereClausForForecastData = QStringLiteral("d_date > (SELECT date('now'))");
}
break;
case CUSTOM:
// Custom Date
wc = "d_date>='" % SKGServices::dateToSqlString(QDateTime(ui.kDateBegin->date())) % '\'';
if (iForecast) {
wc += "AND d_date<='" % SKGServices::dateToSqlString(QDateTime(ui.kDateEnd->date())) % '\''; // For forecast based on scheduled operations
}
if (oWhereClausForPreviousData != nullptr) {
*oWhereClausForPreviousData = "d_date<'" % SKGServices::dateToSqlString(QDateTime(ui.kDateBegin->date())) % '\'';
}
if (oWhereClausForForecastData != nullptr) {
*oWhereClausForForecastData = QStringLiteral("d_date > (SELECT date('now'))");
}
break;
case TIMELINE:
// Timeline
ui.kDateBegin->setDate(a);
ui.kDateEnd->setDate(b);
wc = "d_date>='" % SKGServices::dateToSqlString(QDateTime(ui.kDateBegin->date())) % '\'';
if (iForecast) {
wc += "AND d_date<='" % SKGServices::dateToSqlString(QDateTime(ui.kDateEnd->date())) % '\''; // For forecast based on scheduled operations
}
if (oWhereClausForPreviousData != nullptr) {
*oWhereClausForPreviousData = "d_date<'" % SKGServices::dateToSqlString(QDateTime(ui.kDateBegin->date())) % '\'';
}
if (oWhereClausForForecastData != nullptr) {
*oWhereClausForForecastData = "d_date>'" % SKGServices::dateToSqlString(QDateTime(ui.kDateEnd->date())) % '\'';
}
break;
default:
// Take all dates
a = a.addYears(-1);
ui.kDateBegin->setDate(a);
ui.kDateEnd->setDate(b);
wc = QStringLiteral("1=1");
if (oWhereClausForPreviousData != nullptr) {
*oWhereClausForPreviousData = QStringLiteral("1=0");
}
if (oWhereClausForForecastData != nullptr) {
*oWhereClausForForecastData = QStringLiteral("d_date > (SELECT date('now'))");
}
break;
}
wc = "((" % wc % ") OR d_date='0000') AND d_date!='0000-00-00'";
if (oWhereClausForPreviousData != nullptr) {
*oWhereClausForPreviousData = "((" % *oWhereClausForPreviousData % ") OR d_date='0000-00-00')";
}
return wc;
}
void SKGPeriodEdit::refresh()
{
int p = ui.kPeriod->currentIndex();
// Check dates
QDate d1 = ui.kDateBegin->date();
QDate d2 = ui.kDateEnd->date();
if (d1 > d2) {
ui.kDateBegin->setDate(d2);
ui.kDateEnd->setDate(d1);
}
++m_count;
if (m_count == 5) {
m_modeEnable = false;
}
ui.kDateSelect->setEnabled(p != ALL);
ui.kTimeline->setEnabled(p == TIMELINE);
ui.kFuture->setEnabled(p == CURRENT || p == LAST);
ui.kInterval->setEnabled(p == CURRENT || p == PREVIOUS || p == LAST || p == TIMELINE);
ui.kNbIntervals->setEnabled(p == PREVIOUS || p == LAST);
if (!m_modeEnable) {
ui.kDateSelect->setVisible(p != ALL);
ui.kTimeline->setVisible(p == TIMELINE);
ui.kFuture->setVisible(p == CURRENT || p == LAST);
ui.kInterval->setVisible(p == CURRENT || p == PREVIOUS || p == LAST || p == TIMELINE);
ui.kNbIntervals->setVisible(p == PREVIOUS || p == LAST);
}
ui.kDateSelect->setEnabled(p == CUSTOM);
// Needed to refresh dates
getWhereClause();
emit changed();
}
diff --git a/skgbasegui/skgperiodedit.h b/skgbasegui/skgperiodedit.h
index 11b1afd70..6978c4e65 100644
--- a/skgbasegui/skgperiodedit.h
+++ b/skgbasegui/skgperiodedit.h
@@ -1,159 +1,159 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGPERIODEDIT_H
#define SKGPERIODEDIT_H
/** @file
* A period editor.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgbasegui_export.h"
#include "ui_skgperiodedit.h"
/**
* This file is a period editor.
*/
class SKGBASEGUI_EXPORT SKGPeriodEdit : public QWidget
{
Q_OBJECT
/**
* Where clause
*/
Q_PROPERTY(QString whereClause READ getWhereClause NOTIFY changed)
/**
* Text
*/
Q_PROPERTY(QString text READ text NOTIFY changed)
public:
/**
* This enumerate defines the period mode
*/
enum PeriodMode {ALL, /**< All date*/
CURRENT, /**< Current month, year, ...*/
PREVIOUS, /**< Previous month, year, ...*/
LAST, /**< Last month, year, ...*/
CUSTOM, /**< Custom dates*/
TIMELINE /**< Timeline.*/
};
/**
* This enumerate defines the period mode
*/
Q_ENUM(PeriodMode)
/**
* This enumerate defines the period mode
*/
enum PeriodInterval {DAY = 0, /**< Day*/
WEEK = 1, /**< Week (7 days)*/
MONTH = 2, /**< Month*/
QUARTER = 4, /**< Quarter (3 months)*/
SEMESTER = 5, /**< Semester (6 months)*/
YEAR = 3 /**< Year*/
};
/**
* This enumerate defines the period interval
*/
Q_ENUM(PeriodInterval)
/**
* Default Constructor
* @param iParent the parent
* @param iModeEnabled if true then the widgets are enabled/disabled instead of shown/hidden
*/
explicit SKGPeriodEdit(QWidget* iParent, bool iModeEnabled = false);
/**
* Default Destructor
*/
~SKGPeriodEdit() override;
/**
* Get the current state
* MUST BE OVERWRITTEN
* @return a string containing all information needed to set the same state.
* Could be an XML stream
*/
virtual QString getState();
/**
* Set the current state
* MUST BE OVERWRITTEN
* @param iState must be interpreted to set the state of the widget
*/
virtual void setState(const QString& iState);
/**
* Get the text
* @return the text
*/
virtual QString text() const;
/**
* Get the mode
* @return the mode
*/
virtual SKGPeriodEdit::PeriodMode mode() const;
/**
* Get the where clauses
* @param iForecast enable forecast where clause
* @param oWhereClausForPreviousData the where clause for previous data. Can be nullptr.
* @param oWhereClausForForecastData the where clause for forecast data. Can be nullptr.
* @return the where clause
*/
virtual QString getWhereClause(bool iForecast = true, QString* oWhereClausForPreviousData = nullptr, QString* oWhereClausForForecastData = nullptr) const;
/**
* Get begin and end dates
* @param iPeriod the period
* @param iInterval the interval
* @param iValue the number of iInterval
* @param oBeginDate the begin date of the period
* @param oEndDate the end date of the period
* @param iDate the input date
*/
// cppcheck-suppress passedByValue
static void getDates(PeriodMode iPeriod, PeriodInterval iInterval, int iValue, QDate& oBeginDate, QDate& oEndDate, QDate iDate = QDate::currentDate());
/**
* Get begin and end dates
* @param oBeginDate the begin date of the period
* @param oEndDate the end date of the period
*/
// cppcheck-suppress passedByValue
void getDates(QDate& oBeginDate, QDate& oEndDate);
private Q_SLOTS:
void refresh();
Q_SIGNALS:
/**
* Emitted when the period change
*/
void changed();
private:
Ui::skgperiodedit_base ui{};
bool m_modeEnable;
int m_count;
};
#endif // SKGPERIODEDIT_H
diff --git a/skgbasegui/skgprogressbar.cpp b/skgbasegui/skgprogressbar.cpp
index 480c7075f..cac09d7c6 100644
--- a/skgbasegui/skgprogressbar.cpp
+++ b/skgbasegui/skgprogressbar.cpp
@@ -1,75 +1,75 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* A progress bar with colors.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgprogressbar.h"
#include <kcolorscheme.h>
#include <qstringbuilder.h>
SKGProgressBar::SKGProgressBar(QWidget* iParent)
: QProgressBar(iParent), m_negative(-1), m_neutral(-1), m_positive(-1)
{
// Define color style
KColorScheme scheme(QPalette::Normal);
QString negative = scheme.foreground(KColorScheme::NegativeText).color().name();
QString neutral = scheme.foreground(KColorScheme::NeutralText).color().name();
QString positive = scheme.foreground(KColorScheme::PositiveText).color().name();
m_negativeStyleSheet = QStringLiteral(" QProgressBar { text-align: center; padding: 0.5px;} QProgressBar::chunk {text-align: center; border-radius:4px; background-color: ") % negative % ";}" % styleSheet();
m_neutralStyleSheet = QStringLiteral(" QProgressBar { text-align: center; padding: 0.5px;} QProgressBar::chunk {text-align: center; border-radius:4px; background-color: ") % neutral % ";}" % styleSheet();
m_positiveStyleSheet = QStringLiteral(" QProgressBar { text-align: center; padding: 0.5px;} QProgressBar::chunk {text-align: center; border-radius:4px; background-color: ") % positive % ";}" % styleSheet();
}
SKGProgressBar::~SKGProgressBar()
= default;
void SKGProgressBar::setLimits(int negative, int neutral, int positive)
{
m_negative = negative;
m_neutral = neutral;
m_positive = positive;
setValue(value());
}
void SKGProgressBar::setValue(int iValue)
{
QProgressBar::setValue(iValue);
if (m_negative <= m_positive) {
if (iValue <= m_negative) {
setStyleSheet(m_negativeStyleSheet);
} else if (iValue <= m_neutral) {
setStyleSheet(m_neutralStyleSheet);
} else if (iValue <= m_positive) {
setStyleSheet(m_positiveStyleSheet);
}
} else {
if (iValue <= m_positive) {
setStyleSheet(m_positiveStyleSheet);
} else if (iValue <= m_neutral) {
setStyleSheet(m_neutralStyleSheet);
} else if (iValue <= m_negative) {
setStyleSheet(m_negativeStyleSheet);
}
}
}
diff --git a/skgbasegui/skgprogressbar.h b/skgbasegui/skgprogressbar.h
index e0c07ab70..fdf62774e 100644
--- a/skgbasegui/skgprogressbar.h
+++ b/skgbasegui/skgprogressbar.h
@@ -1,75 +1,75 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGPROGRESSBAR_H
#define SKGPROGRESSBAR_H
/** @file
* A progress bar with colors
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgbasegui_export.h"
#include <qprogressbar.h>
/**
* A progress bar with colors
*/
class SKGBASEGUI_EXPORT SKGProgressBar : public QProgressBar
{
Q_OBJECT
/**
* Property value
*/
Q_PROPERTY(int value READ value WRITE setValue) // clazy:exclude=qproperty-without-notify
public:
/**
* Constructor
* @param iParent the parent
*/
explicit SKGProgressBar(QWidget* iParent);
/**
* Destructor
*/
~SKGProgressBar() override;
/**
* Set the limits
* @param negative if the value @see setValue is less than @param negative the color will be negative
* @param neutral if the value @see setValue is less than @param neutral the color will be neutral
* @param positive if the value @see setValue is less than @param positive the color will be positive
*/
virtual void setLimits(int negative, int neutral, int positive);
/**
* Set the value
* @param iValue the value
*/
virtual void setValue(int iValue);
private:
int m_negative;
int m_neutral;
int m_positive;
QString m_negativeStyleSheet;
QString m_neutralStyleSheet;
QString m_positiveStyleSheet;
};
#endif
diff --git a/skgbasegui/skgshow.cpp b/skgbasegui/skgshow.cpp
index d75199f55..4104a6354 100644
--- a/skgbasegui/skgshow.cpp
+++ b/skgbasegui/skgshow.cpp
@@ -1,516 +1,516 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* A widget to select what to show.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgshow.h"
#include <klocalizedstring.h>
#include <qdom.h>
#include <qicon.h>
#include <qmenu.h>
#include <qwidgetaction.h>
#include "skgperiodedit.h"
#include "skgservices.h"
SKGShow::SKGShow(QWidget* iParent)
: QToolButton(iParent), m_mode(OR), m_inTrigger(false), m_displayTitle(true)
{
setPopupMode(QToolButton::InstantPopup);
setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
setAutoRaise(true);
m_menu = new QMenu(this);
setMenu(m_menu);
// Time to emit stateChanged
m_timer.setSingleShot(true);
connect(&m_timer, &QTimer::timeout, this, &SKGShow::stateChanged, Qt::QueuedConnection);
hide();
}
SKGShow::~SKGShow()
{
m_menu = nullptr;
}
SKGShow::OperatorMode SKGShow::getMode()
{
return m_mode;
}
void SKGShow::setMode(SKGShow::OperatorMode iMode)
{
if (m_mode != iMode) {
m_mode = iMode;
Q_EMIT modified();
}
}
QString SKGShow::getState()
{
QStringList itemsChecked;
if (m_menu != nullptr) {
QList<QAction*> actionsList = m_menu->actions();
int nb = actionsList.count();
itemsChecked.reserve(nb);
for (int i = 0; i < nb; ++i) {
QAction* act = actionsList.at(i);
if (act != nullptr) {
auto* wact = qobject_cast<QWidgetAction*>(act);
if (wact != nullptr) {
auto* pedit = qobject_cast<SKGPeriodEdit*>(wact->defaultWidget());
itemsChecked.push_back(act->data().toString() % ":" % pedit->getState());
} else {
if (act->isChecked()) {
itemsChecked.push_back(act->data().toString());
}
}
}
}
}
return SKGServices::stringsToCsv(itemsChecked);
}
void SKGShow::setDefaultState(const QString& iState)
{
m_defaultState = iState;
setState(m_defaultState);
}
void SKGShow::setState(const QString& iState)
{
if (m_menu != nullptr) {
QStringList itemsChecked = SKGServices::splitCSVLine(iState.isEmpty() ? m_defaultState : iState);
int nb = m_actions.count();
for (int i = 0; i < nb; ++i) {
QAction* act = m_actions.at(i);
if (act != nullptr) {
QString identifier = m_actions.at(i)->data().toString();
auto* wact = qobject_cast<QWidgetAction*>(act);
if (wact != nullptr) {
auto* pedit = qobject_cast<SKGPeriodEdit*>(wact->defaultWidget());
for (const auto& item : qAsConst(itemsChecked)) {
if (item.startsWith(identifier % ":")) {
pedit->setState(item.right(item.length() - identifier.length() - 1));
break;
}
}
} else {
act->setChecked(itemsChecked.contains(identifier));
}
}
}
// Change tooltip
setToolTip(getTitle());
// Emit event
emit stateChanged();
}
}
QString SKGShow::getWhereClause() const
{
QString wc;
if (m_menu != nullptr) {
QList<QAction*> actionsList = m_menu->actions();
int nb = actionsList.count();
bool noCheck = true;
for (int i = 0; i < nb; ++i) {
QAction* act = actionsList.at(i);
if (act != nullptr) {
auto* wact = qobject_cast<QWidgetAction*>(act);
if (wact != nullptr) {
auto* pedit = qobject_cast<SKGPeriodEdit*>(wact->defaultWidget());
if (!wc.isEmpty()) {
wc += (m_mode == OR ? QStringLiteral(" OR ") : QStringLiteral(" AND "));
}
wc += '(' % pedit->getWhereClause() % ')';
noCheck = false;
} else {
if (act->isChecked()) {
if (!wc.isEmpty()) {
wc += (m_mode == OR ? QStringLiteral(" OR ") : QStringLiteral(" AND "));
}
wc += '(' % m_whereclause.value(act) % ')';
noCheck = false;
if (m_whereclause.value(act).isEmpty()) {
wc = QLatin1String("");
break;
}
}
}
}
}
if ((nb != 0) && noCheck) {
wc = QStringLiteral("1=0");
}
}
return wc;
}
QString SKGShow::getTitle() const
{
QString wc;
if (m_menu != nullptr) {
int nb = m_actions.count();
for (int i = 0; i < nb; ++i) {
QAction* act = m_actions.at(i);
if (act != nullptr) {
auto* wact = qobject_cast<QWidgetAction*>(act);
if (wact != nullptr) {
auto* pedit = qobject_cast<SKGPeriodEdit*>(wact->defaultWidget());
if (!wc.isEmpty()) {
wc += (m_mode == OR ? QStringLiteral(" + ") : QStringLiteral(" , "));
}
wc += pedit->text();
} else {
if (act->isChecked()) {
if (!wc.isEmpty()) {
wc += (m_mode == OR ? QStringLiteral(" + ") : QStringLiteral(" , "));
}
wc += act->toolTip();
}
}
}
}
}
return wc;
}
void SKGShow::clear()
{
m_check_to_check.clear();
m_uncheck_to_check.clear();
m_check_to_uncheck.clear();
m_uncheck_to_uncheck.clear();
m_actions.clear();
m_icons.clear();
m_whereclause.clear();
m_defaultState.clear();
m_menu->clear();
}
int SKGShow::count()
{
return m_check_to_check.count();
}
int SKGShow::addGroupedItem(const QString& iIdentifier, const QString& iText, const QString& iIcon,
const QString& iWhereClose, const QString& iGroup, const QKeySequence& iShortcut)
{
if (m_menu != nullptr) {
QActionGroup* groupAction = m_groups.value(iGroup);
if (groupAction == nullptr) {
groupAction = new QActionGroup(this);
m_groups[iGroup] = groupAction;
}
QString name = iText;
name = name.replace('&', QStringLiteral("&&"));
QAction* act = m_menu->addAction(name);
if (act != nullptr) {
act->setToolTip(name);
act->setIcon(SKGServices::fromTheme(iIcon));
act->setData(iIdentifier);
act->setCheckable(true);
if (!iShortcut.isEmpty()) {
act->setShortcuts(QList<QKeySequence>() << iShortcut << QKeySequence::fromString("Ctrl+Alt+" % iShortcut.toString()));
}
m_check_to_check[act] = QLatin1String("");
m_check_to_uncheck[act] = QLatin1String("");
m_uncheck_to_check[act] = QLatin1String("");
m_uncheck_to_uncheck[act] = QLatin1String("");
m_actions.push_back(act);
m_icons.push_back(iIcon);
m_whereclause[act] = iWhereClose;
connect(act, &QAction::toggled, this, &SKGShow::trigger);
groupAction->addAction(act);
}
show();
return (m_actions.count() - 1);
}
return -1;
}
int SKGShow::addPeriodItem(const QString& iIdentifier)
{
if (m_menu != nullptr) {
auto m_periodEdit1 = new SKGPeriodEdit(this);
// Set default
QDomDocument doc(QStringLiteral("SKGML"));
QDomElement root = doc.createElement(QStringLiteral("parameters"));
doc.appendChild(root);
root.setAttribute(QStringLiteral("period"), SKGServices::intToString(static_cast<int>(SKGPeriodEdit::ALL)));
m_periodEdit1->setState(doc.toString());
// Add widget in menu
auto act = new QWidgetAction(this);
if (act != nullptr) {
act->setData(iIdentifier);
act->setDefaultWidget(m_periodEdit1);
m_check_to_check[act] = QLatin1String("");
m_check_to_uncheck[act] = QLatin1String("");
m_uncheck_to_check[act] = QLatin1String("");
m_uncheck_to_uncheck[act] = QLatin1String("");
m_actions.push_back(act);
m_icons.push_back(QLatin1String(""));
m_whereclause[act] = QLatin1String("");
connect(m_periodEdit1, &SKGPeriodEdit::changed, this, &SKGShow::triggerRefreshOnly);
m_menu->addAction(act);
}
show();
return (m_actions.count() - 1);
}
return -1;
}
int SKGShow::addItem(const QString& iIdentifier, const QString& iText, const QString& iIcon,
const QString& iWhereClose,
const QString& iListIdToCheckWhenChecked,
const QString& iListIdToUncheckWhenChecked,
const QString& iListIdToCheckWhenUnchecked,
const QString& iListIdToUncheckWhenUnchecked,
const QKeySequence& iShortcut
)
{
if (m_menu != nullptr) {
QString name = iText;
name = name.replace('&', QStringLiteral("&&"));
QAction* act = m_menu->addAction(name);
if (act != nullptr) {
act->setToolTip(name);
act->setIcon(SKGServices::fromTheme(iIcon));
act->setData(iIdentifier);
act->setCheckable(true);
if (!iShortcut.isEmpty()) {
act->setShortcuts(QList<QKeySequence>() << iShortcut << QKeySequence::fromString("Ctrl+Alt+" % iShortcut.toString()));
}
m_check_to_check[act] = iListIdToCheckWhenChecked;
m_check_to_uncheck[act] = iListIdToUncheckWhenChecked;
m_uncheck_to_check[act] = iListIdToCheckWhenUnchecked;
m_uncheck_to_uncheck[act] = iListIdToUncheckWhenUnchecked;
m_actions.push_back(act);
m_icons.push_back(iIcon);
m_whereclause[act] = iWhereClose;
connect(act, &QAction::toggled, this, &SKGShow::trigger);
}
show();
return (m_actions.count() - 1);
}
return -1;
}
void SKGShow::setListIdToCheckWhenChecked(int iIndex, const QString& iIds)
{
m_check_to_check[m_actions.at(iIndex)] = iIds;
}
void SKGShow::setListIdToCheckWhenUnchecked(int iIndex, const QString& iIds)
{
m_uncheck_to_check[m_actions.at(iIndex)] = iIds;
}
void SKGShow::setListIdToUncheckWhenChecked(int iIndex, const QString& iIds)
{
m_check_to_uncheck[m_actions.at(iIndex)] = iIds;
}
void SKGShow::setListIdToUncheckWhenUnchecked(int iIndex, const QString& iIds)
{
m_uncheck_to_uncheck[m_actions.at(iIndex)] = iIds;
}
void SKGShow::addSeparator()
{
if (m_menu != nullptr) {
m_menu->addSeparator();
}
}
void SKGShow::trigger()
{
auto* act = qobject_cast<QAction*>(sender());
if ((act != nullptr) && !m_inTrigger) {
m_inTrigger = true;
// Apply rules
QStringList over;
if (act->isChecked()) {
{
// Check items
QStringList items = SKGServices::splitCSVLine(m_check_to_check.value(act));
int nb = items.count();
for (int i = 0; i < nb; ++i) {
QAction* act2 = getAction(items.at(i));
if ((act2 != nullptr) && act2 != act) {
act2->setChecked(true);
}
}
}
{
// Uncheck items
QStringList items = SKGServices::splitCSVLine(m_check_to_uncheck.value(act));
int nb = items.count();
for (int i = 0; i < nb; ++i) {
QAction* act2 = getAction(items.at(i));
if ((act2 != nullptr) && act2 != act) {
act2->setChecked(false);
}
}
}
} else {
{
// Check items
QStringList items = SKGServices::splitCSVLine(m_uncheck_to_check.value(act));
int nb = items.count();
for (int i = 0; i < nb; ++i) {
QAction* act2 = getAction(items.at(i));
if ((act2 != nullptr) && act2 != act) {
act2->setChecked(true);
}
}
}
{
// Uncheck items
QStringList items = SKGServices::splitCSVLine(m_uncheck_to_uncheck.value(act));
int nb = items.count();
for (int i = 0; i < nb; ++i) {
QAction* act2 = getAction(items.at(i));
if ((act2 != nullptr) && act2 != act) {
act2->setChecked(false);
}
}
}
}
// Change tooltip
setToolTip(getTitle());
// Change icon
QStringList icons;
QString mainIcon;
if (m_menu != nullptr) {
int nb = m_actions.count();
icons.reserve(nb);
for (int i = 0; i < nb; ++i) {
QAction* act2 = m_actions.at(i);
if ((act2 != nullptr) && act2->isChecked()) {
if (!m_icons.at(i).isEmpty()) {
if (mainIcon.isEmpty()) {
mainIcon = m_icons.at(i);
} else {
icons.push_back(m_icons.at(i));
}
} else {
if (mainIcon.isEmpty()) {
mainIcon = QStringLiteral("show-menu");
}
}
}
}
}
if (mainIcon.isEmpty()) {
mainIcon = QStringLiteral("show-menu");
}
setIcon(SKGServices::fromTheme(mainIcon, icons));
triggerRefreshOnly();
m_inTrigger = false;
}
}
void SKGShow::triggerRefreshOnly()
{
// Emit event
m_timer.start(300);
// Change title
refreshTitle();
}
bool SKGShow::getDisplayTitle()
{
return m_displayTitle;
}
void SKGShow::setDisplayTitle(bool iDisplay)
{
if (m_displayTitle != iDisplay) {
m_displayTitle = iDisplay;
refreshTitle();
Q_EMIT modified();
}
}
void SKGShow::refreshTitle()
{
if (m_displayTitle) {
setText(i18n("Show: %1", getTitle()));
} else {
setText(i18n("Show"));
}
}
QAction* SKGShow::getAction(const QString& iIdentifier) const
{
QAction* output = nullptr;
if (m_menu != nullptr) {
QList<QAction*> actionsList = m_menu->actions();
int nb = actionsList.count();
for (int i = 0; (output == nullptr) && i < nb; ++i) {
QAction* act = actionsList.at(i);
if ((act != nullptr) && act->data().toString() == iIdentifier) {
output = act;
}
}
}
return output;
}
diff --git a/skgbasegui/skgshow.h b/skgbasegui/skgshow.h
index 6b8c1d1d1..209c67d36 100644
--- a/skgbasegui/skgshow.h
+++ b/skgbasegui/skgshow.h
@@ -1,277 +1,277 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGSHOW_H
#define SKGSHOW_H
/** @file
* A widget to select what to show.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include <qmap.h>
#include <qtimer.h>
#include <qtoolbutton.h>
#include "skgbasegui_export.h"
class QMenu;
class QAction;
class QActionGroup;
/**
* This file is a widget to select what to show
*/
class SKGBASEGUI_EXPORT SKGShow : public QToolButton
{
Q_OBJECT
/**
* Mode
*/
Q_PROPERTY(OperatorMode mode READ getMode WRITE setMode NOTIFY modified)
/**
* Display Title
*/
Q_PROPERTY(bool displayTitle READ getDisplayTitle WRITE setDisplayTitle NOTIFY modified)
public:
/**
* This enumerate defines type of operator
*/
enum OperatorMode {AND, /**< AND*/
OR /**< OR*/
};
/**
* This enumerate defines type of operator
*/
Q_ENUM(OperatorMode)
/**
* Default Constructor
* @param iParent the parent
*/
explicit SKGShow(QWidget* iParent);
/**
* Default Destructor
*/
~SKGShow() override;
/**
* Get the current state
* @return a string containing all activated item identifiers (separated by ;)
*/
virtual QString getState();
/**
* Set the current state
* @param iState a string containing all activated item identifiers (separated by ;)
*/
virtual void setState(const QString& iState);
/**
* Get the current mode
* @return the mode
*/
virtual OperatorMode getMode();
/**
* Set the current mode
* @param iMode the mode
*/
virtual void setMode(OperatorMode iMode);
/**
* Set the default state
* @param iState a string containing all activated item identifiers (separated by ;)
*/
virtual void setDefaultState(const QString& iState);
/**
* Get the current display mode
* @return true of false
*/
virtual bool getDisplayTitle();
/**
* Set the current display mode
* @param iDisplay true if you want to see the selected filter of false
*/
virtual void setDisplayTitle(bool iDisplay);
/**
* Get the current where clause
* @return a where clause string
*/
virtual QString getWhereClause() const;
/**
* Remove all items
*/
virtual void clear();
/**
* @brief Get the number of items
*
* @return the number of items
**/
virtual int count();
/**
* @brief Get the action for an identifier
*
* @param iIdentifier unique identifier of the item
* @return the action
**/
virtual QAction* getAction(const QString& iIdentifier) const;
/**
* @brief Add an item to the menu
*
* @param iIdentifier unique identifier of the item
* @param iText text
* @param iIcon icon Defaults to "".
* @param iWhereClose icon Defaults to "".
* @param iListIdToCheckWhenChecked list of item identifiers (separated by ;) to check when checked Defaults to "".
* @param iListIdToUncheckWhenChecked list of item identifiers (separated by ;) to uncheck when unchecked Defaults to "".
* @param iListIdToCheckWhenUnchecked list of item identifiers (separated by ;) to check when checked Defaults to "".
* @param iListIdToUncheckWhenUnchecked list of item identifiers (separated by ;) to uncheck when unchecked Defaults to "".
* @param iShortcut the associated shortcut.
* @return the index of the new item
**/
virtual int addItem(const QString& iIdentifier, const QString& iText, const QString& iIcon = QString(),
const QString& iWhereClose = QString(),
const QString& iListIdToCheckWhenChecked = QString(),
const QString& iListIdToUncheckWhenChecked = QString(),
const QString& iListIdToCheckWhenUnchecked = QString(),
const QString& iListIdToUncheckWhenUnchecked = QString(),
const QKeySequence& iShortcut = QKeySequence());
/**
* @brief Add a period item to the menu
*
* @param iIdentifier unique identifier of the item
* @return the index of the new item
**/
virtual int addPeriodItem(const QString& iIdentifier);
/**
* @brief Add an item to the menu
*
* @param iIdentifier unique identifier of the item
* @param iText text
* @param iIcon icon Defaults to "".
* @param iWhereClose icon Defaults to "".
* @param iGroup the group of actions.
* @param iShortcut the associated shortcut.
* @return the index of the new item
**/
virtual int addGroupedItem(const QString& iIdentifier,
const QString& iText,
const QString& iIcon = QString(),
const QString& iWhereClose = QString(),
const QString& iGroup = QString(),
const QKeySequence& iShortcut = QKeySequence());
/**
* @brief Set the list of items to check when iIndex is checked
*
* @param iIndex index of the item (@see addItem)
* @param iIds list of item identifiers (separated by ;)
**/
virtual void setListIdToCheckWhenChecked(int iIndex, const QString& iIds);
/**
* @brief Set the list of items to uncheck when iIndex is checked
*
* @param iIndex index of the item (@see addItem)
* @param iIds list of item identifiers (separated by ;)
**/
virtual void setListIdToUncheckWhenChecked(int iIndex, const QString& iIds);
/**
* @brief Set the list of items to check when iIndex is unchecked
*
* @param iIndex index of the item (@see addItem)
* @param iIds list of item identifiers (separated by ;)
**/
virtual void setListIdToCheckWhenUnchecked(int iIndex, const QString& iIds);
/**
* @brief Set the list of items to uncheck when iIndex is unchecked
*
* @param iIndex index of the item (@see addItem)
* @param iIds list of item identifiers (separated by ;)
**/
virtual void setListIdToUncheckWhenUnchecked(int iIndex, const QString& iIds);
/**
* @brief Add a separator
*
* @return void
**/
virtual void addSeparator();
Q_SIGNALS:
/**
* @brief Emitted when an item is changed
*
* @return void
**/
void stateChanged();
/**
* This signal is launched when the error is modified
*/
void modified();
private Q_SLOTS:
/**
* @brief trigger
**/
void trigger();
/**
* @brief trigger
**/
void triggerRefreshOnly();
private:
Q_DISABLE_COPY(SKGShow)
QString getTitle() const;
void refreshTitle();
QMenu* m_menu;
QTimer m_timer;
QString m_defaultState;
OperatorMode m_mode;
bool m_inTrigger;
bool m_displayTitle;
QList<QAction*> m_actions;
QStringList m_icons;
QMap<QAction*, QString> m_check_to_check;
QMap<QAction*, QString> m_uncheck_to_check;
QMap<QAction*, QString> m_check_to_uncheck;
QMap<QAction*, QString> m_uncheck_to_uncheck;
QMap<QAction*, QString> m_whereclause;
QMap<QString, QActionGroup*> m_groups;
};
#endif // SKGSHOW_H
diff --git a/skgbasegui/skgsimpleperiodedit.cpp b/skgbasegui/skgsimpleperiodedit.cpp
index cc98cc9c9..c3bd046e5 100644
--- a/skgbasegui/skgsimpleperiodedit.cpp
+++ b/skgbasegui/skgsimpleperiodedit.cpp
@@ -1,166 +1,166 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* A simple period selector.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgsimpleperiodedit.h"
#include <skgservices.h>
SKGSimplePeriodEdit::SKGSimplePeriodEdit(QWidget* iParent)
: SKGComboBox(iParent), m_Mode(PREVIOUS_MONTHS) {}
SKGSimplePeriodEdit::~SKGSimplePeriodEdit() = default;
QDate SKGSimplePeriodEdit::firstDate() const
{
return m_FirstDate;
}
void SKGSimplePeriodEdit::setFirstDate(QDate iDate)
{
if (m_FirstDate != iDate) {
m_FirstDate = iDate;
refreshList();
emit changed();
}
}
SKGSimplePeriodEdit::Modes SKGSimplePeriodEdit::mode() const
{
return m_Mode;
}
void SKGSimplePeriodEdit::setMode(SKGSimplePeriodEdit::Modes iMode)
{
if (m_Mode != iMode) {
m_Mode = iMode;
refreshList();
emit changed();
}
}
QString SKGSimplePeriodEdit::period() const
{
QString period = currentData().toString();
if (period.isEmpty()) {
// Specific month
period = text();
}
return period;
}
void SKGSimplePeriodEdit::refreshList()
{
QDate today = QDate::currentDate();
QDate c = SKGServices::periodToDate(SKGServices::dateToPeriod(m_FirstDate, QStringLiteral("M")));
if (!c.isValid()) {
c = today;
}
c = c.addDays(1 - c.day());
QString smonth = SKGServices::dateToPeriod(today, QStringLiteral("M"));
QString squarter = SKGServices::dateToPeriod(today, QStringLiteral("Q"));
QString ssemester = SKGServices::dateToPeriod(today, QStringLiteral("S"));
QString syear = SKGServices::dateToPeriod(today, QStringLiteral("Y"));
// Build the list
QStringList list;
do {
QString cmonth = SKGServices::dateToPeriod(c, QStringLiteral("M"));
QString cquarter = SKGServices::dateToPeriod(c, QStringLiteral("Q"));
QString csemester = SKGServices::dateToPeriod(c, QStringLiteral("S"));
QString cyear = SKGServices::dateToPeriod(c, QStringLiteral("Y"));
if ((cmonth != smonth && (((m_Mode & PREVIOUS_MONTHS)) != 0u)) ||
(cmonth == smonth && (((m_Mode & CURRENT_MONTH)) != 0u))) {
list.insert(0, cmonth);
}
if (!list.contains(cquarter) && ((cquarter != squarter && (((m_Mode & PREVIOUS_PERIODS)) != 0u)) ||
(cquarter == squarter && (((m_Mode & CURRENT_PERIOD)) != 0u)))) {
list.insert(0, cquarter);
}
if (!list.contains(csemester) && ((csemester != ssemester && (((m_Mode & PREVIOUS_PERIODS)) != 0u)) ||
(csemester == ssemester && (((m_Mode & CURRENT_PERIOD)) != 0u)))) {
list.insert(0, csemester);
}
if (!list.contains(cyear) && ((cyear != syear && ((((m_Mode & PREVIOUS_PERIODS)) != 0u) || (((m_Mode & PREVIOUS_YEARS)) != 0u))) ||
(cyear == syear && ((((m_Mode & CURRENT_PERIOD)) != 0u) || (((m_Mode & CURRENT_YEAR)) != 0u))))) {
list.insert(0, cyear);
}
if (cmonth == smonth || c >= today) {
break;
}
c = c.addMonths(1);
} while (true);
// Set the list and the current item
QString current = text();
bool previous = blockSignals(true);
clear();
// Add dynamic items
if (list.contains(smonth) && (((m_Mode & ALL)) != 0u)) {
addItem(i18nc("A period including all dates", "All dates"), "ALL");
}
if (list.contains(smonth)) {
addItem(i18nc("The current month", "Current month"), smonth);
}
if (list.contains(squarter)) {
addItem(i18nc("The current quarter", "Current quarter"), squarter);
}
if (list.contains(ssemester)) {
addItem(i18nc("The current semester", "Current semester"), ssemester);
}
if (list.contains(syear)) {
addItem(i18nc("The current year", "Current year"), syear);
}
QString period = SKGServices::getNeighboringPeriod(smonth);
if (list.contains(period)) {
addItem(i18nc("The month before the current month", "Last month"), period);
}
period = SKGServices::getNeighboringPeriod(squarter);
if (list.contains(period)) {
addItem(i18nc("The quarter before the current quarter", "Last quarter"), period);
}
period = SKGServices::getNeighboringPeriod(ssemester);
if (list.contains(period)) {
addItem(i18nc("The semester before the current semester", "Last semester"), period);
}
period = SKGServices::getNeighboringPeriod(syear);
if (list.contains(period)) {
addItem(i18nc("The year before the current year", "Last year"), period);
}
addItems(list);
if (!current.isEmpty()) {
setText(current);
} else {
setCurrentIndex(0);
}
blockSignals(previous);
}
diff --git a/skgbasegui/skgsimpleperiodedit.h b/skgbasegui/skgsimpleperiodedit.h
index aa59a6bd9..31c112328 100644
--- a/skgbasegui/skgsimpleperiodedit.h
+++ b/skgbasegui/skgsimpleperiodedit.h
@@ -1,134 +1,134 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGSIMPLEPERIODEDIT_H
#define SKGSIMPLEPERIODEDIT_H
/** @file
* A simple period selector.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include <qdatetime.h>
#include <qflags.h>
#include "skgbasegui_export.h"
#include "skgcombobox.h"
/**
* This file is a simple period selector.
*/
class SKGBASEGUI_EXPORT SKGSimplePeriodEdit : public SKGComboBox
{
Q_OBJECT
/**
* First date
*/
Q_PROPERTY(QDate firstDate READ firstDate WRITE setFirstDate NOTIFY changed USER true)
/**
* Previous mode
*/
Q_PROPERTY(Modes mode READ mode WRITE setMode NOTIFY changed)
/**
* Period
*/
Q_PROPERTY(QString period READ period NOTIFY changed)
public:
/**
* This enumerate for mode
*/
enum Mode {
NONE = 0u, /**< None */
PREVIOUS_MONTHS = 1u, /**< Only previous months */
PREVIOUS_YEARS = 32u, /**< Only previous years */
PREVIOUS_PERIODS = 2u, /**< All previous periods including quarters, semesters and years*/
CURRENT_MONTH = 4u, /**< Current month */
CURRENT_YEAR = 64u, /**< Current years */
CURRENT_PERIOD = 8u, /**< Current period including quarter, semester and year */
ALL = 16u, /**< The "All dates" period */
PREVIOUS_AND_CURRENT_MONTHS = 1u | 4u, /**< Previous and current months*/
PREVIOUS_AND_CURRENT_YEARS = 32u | 64u, /**< Previous and current years*/
PREVIOUS_AND_CURRENT_PERIODS = 1u | 2u | 4u | 8u, /**< Previous and current periods including quarters, semesters and years*/
ALL_PERIODS = 1u | 2u | 4u | 8u | 16u /**< All periods*/
};
/**
* This enumerate for additional options in menu
*/
Q_ENUM(Mode)
Q_DECLARE_FLAGS(Modes, Mode)
/**
* Default Constructor
* @param iParent the parent
*/
explicit SKGSimplePeriodEdit(QWidget* iParent);
/**
* Default Destructor
*/
~SKGSimplePeriodEdit() override;
/**
* Get the period
* @return the period
*/
virtual QString period() const;
/**
* Get the first date to take into account
* @return the first date to take into account
*/
virtual QDate firstDate() const;
/**
* Set the first date to take into account
* @param iDate the first date to take into account
*/
// cppcheck-suppress passedByValue
virtual void setFirstDate(QDate iDate);
/**
* To know if the mode of widget (default: PREVIOUS_MONTHS)
* @return previous mode
*/
virtual Modes mode() const;
/**
* Set the widget mode
* @param iMode the mode
*/
virtual void setMode(Modes iMode);
Q_SIGNALS:
/**
* Emitted when the changed
*/
void changed();
private:
QDate m_FirstDate;
Modes m_Mode;
void refreshList();
};
Q_DECLARE_OPERATORS_FOR_FLAGS(SKGSimplePeriodEdit::Modes)
#endif // SKGSIMPLEPERIODEDIT_H
diff --git a/skgbasegui/skgsortfilterproxymodel.cpp b/skgbasegui/skgsortfilterproxymodel.cpp
index 14ecaac4c..922de95bb 100644
--- a/skgbasegui/skgsortfilterproxymodel.cpp
+++ b/skgbasegui/skgsortfilterproxymodel.cpp
@@ -1,355 +1,355 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is a proxy model with better filter mechanism.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgsortfilterproxymodel.h"
#include <qregexp.h>
#include "skgobjectmodelbase.h"
#include "skgservices.h"
#include "skgtraces.h"
/**
* This private class of SKGObjectBase
*/
class SKGSortFilterProxyModelPrivate
{
public:
/**
* the previous sort column
*/
int m_previous;
/**
* the current sort column
*/
int m_current;
/**
* to know if we are in a sub sort
*/
bool m_insubsort;
};
SKGSortFilterProxyModel::SKGSortFilterProxyModel(QObject* iParent)
: QSortFilterProxyModel(iParent), d(new SKGSortFilterProxyModelPrivate)
{
_SKGTRACEINFUNC(10)
setSortCaseSensitivity(Qt::CaseInsensitive);
setSortLocaleAware(true);
setFilterKeyColumn(0);
d->m_previous = -1;
d->m_current = -1;
d->m_insubsort = false;
}
SKGSortFilterProxyModel::~SKGSortFilterProxyModel()
{
_SKGTRACEINFUNC(10)
delete d;
}
int SKGSortFilterProxyModel::getPreviousSortColumn() const
{
return d->m_previous;
}
void SKGSortFilterProxyModel::setPreviousSortColumn(int iCol)
{
if (d->m_previous != iCol) {
d->m_previous = iCol;
Q_EMIT previousSortColumnModified();
}
}
bool SKGSortFilterProxyModel::lessThan(const QModelIndex& left,
const QModelIndex& right) const
{
// Get source
auto* model = qobject_cast<SKGObjectModelBase*>(this->sourceModel());
if ((model != nullptr) && (d != nullptr)) {
// Set previous column
if (!d->m_insubsort) {
int newCol = left.column();
if (newCol != d->m_current && d->m_current != -1) {
d->m_previous = d->m_current;
}
d->m_current = newCol;
}
// Special sort order
if (d->m_current != -1) {
auto columname = model->getAttribute(d->m_current);
if (columname.startsWith(QStringLiteral("f_BALANCE"))) {
auto d_date_index = model->getIndexAttribute(QStringLiteral("d_date"));
if (d_date_index != -1) {
d->m_current = d_date_index;
d->m_previous = -1;
SKGTRACEL(5) << "SKGSortFilterProxyModel::lessThan-Special sort order on " << columname << endl;
}
}
}
// Comparison
QVariant leftData = model->data(model->index(left.row(), d->m_current, left.parent()), Qt::UserRole);
QVariant rightData = model->data(model->index(right.row(), d->m_current, right.parent()), Qt::UserRole);
SKGObjectBase* leftObj = model->getObjectPointer(left);
if (leftData == rightData && (leftObj != nullptr)) {
if (leftObj->getTable().isEmpty() && d->m_current != 0 && !d->m_insubsort) {
// Groups
d->m_insubsort = true;
bool test = SKGSortFilterProxyModel::lessThan(model->index(left.row(), 0), model->index(right.row(), 0));
d->m_insubsort = false;
return test;
}
// Compare on previous column
if (!d->m_insubsort && d->m_previous != -1 && !d->m_insubsort) {
d->m_insubsort = true;
auto vl = model->index(left.row(), d->m_previous, left.parent());
auto vr = model->index(right.row(), d->m_previous, right.parent());
bool test = QSortFilterProxyModel::lessThan(vl, vr);
d->m_insubsort = false;
return test;
}
// Compare on ID for stability
SKGObjectBase* rightObj = model->getObjectPointer(right);
return ((rightObj != nullptr) && leftObj->getID() < rightObj->getID());
}
// For better performances, and avoid too many calls to QAbstractItemModel::data
// return QSortFilterProxyModel::lessThan(left, right);
return lessThan(leftData, rightData);
}
return false;
}
bool SKGSortFilterProxyModel::lessThan(const QVariant& iLeftData, const QVariant& iRightData) const
{
switch (iLeftData.userType()) {
case QVariant::Invalid:
return (iRightData.type() != QVariant::Invalid);
case QVariant::Int:
return iLeftData.toInt() < iRightData.toInt();
case QVariant::UInt:
return iLeftData.toUInt() < iRightData.toUInt();
case QVariant::LongLong:
return iLeftData.toLongLong() < iRightData.toLongLong();
case QVariant::ULongLong:
return iLeftData.toULongLong() < iRightData.toULongLong();
case QMetaType::Float:
return iLeftData.toFloat() < iRightData.toFloat();
case QVariant::Double:
return iLeftData.toDouble() < iRightData.toDouble();
case QVariant::Char:
return iLeftData.toChar() < iRightData.toChar();
case QVariant::Date:
return iLeftData.toDate() < iRightData.toDate();
case QVariant::Time:
return iLeftData.toTime() < iRightData.toTime();
case QVariant::DateTime:
return iLeftData.toDateTime() < iRightData.toDateTime();
case QVariant::String:
default:
if (this->isSortLocaleAware()) {
return iLeftData.toString().localeAwareCompare(iRightData.toString()) < 0;
} else {
return iLeftData.toString().compare(iRightData.toString(), this->sortCaseSensitivity()) < 0;
}
}
}
bool SKGSortFilterProxyModel::moreThan(const QVariant& iLeftData, const QVariant& iRightData) const
{
switch (iLeftData.userType()) {
case QVariant::Invalid:
return (iRightData.type() != QVariant::Invalid);
case QVariant::Int:
return iLeftData.toInt() > iRightData.toInt();
case QVariant::UInt:
return iLeftData.toUInt() > iRightData.toUInt();
case QVariant::LongLong:
return iLeftData.toLongLong() > iRightData.toLongLong();
case QVariant::ULongLong:
return iLeftData.toULongLong() > iRightData.toULongLong();
case QMetaType::Float:
return iLeftData.toFloat() > iRightData.toFloat();
case QVariant::Double:
return iLeftData.toDouble() > iRightData.toDouble();
case QVariant::Char:
return iLeftData.toChar() > iRightData.toChar();
case QVariant::Date:
return iLeftData.toDate() > iRightData.toDate();
case QVariant::Time:
return iLeftData.toTime() > iRightData.toTime();
case QVariant::DateTime:
return iLeftData.toDateTime() > iRightData.toDateTime();
case QVariant::String:
default:
if (this->isSortLocaleAware()) {
return iLeftData.toString().localeAwareCompare(iRightData.toString()) > 0;
} else {
return iLeftData.toString().compare(iRightData.toString(), this->sortCaseSensitivity()) > 0;
}
}
}
bool SKGSortFilterProxyModel::filterAcceptsRow(int source_row, const QModelIndex& source_parent) const
{
_SKGTRACEINFUNC(10)
// Initialisation
bool output = (filterRegExp().isEmpty());
if (!output) {
// Build list of criterias
SKGServices::SKGSearchCriteriaList criterias = SKGServices::stringToSearchCriterias(filterRegExp().pattern());
// Check if at least one group validate the line
int nbList = criterias.count();
output = false;
for (int i = 0; i < nbList; ++i) {
QChar mode = criterias.at(i).mode;
bool validateAllWords = filterAcceptsRowWords(source_row, source_parent, criterias.at(i).words);
if (mode == '+') {
output |= validateAllWords;
} else if (mode == '-' && validateAllWords) {
output = false;
}
}
if (!output) {
QAbstractItemModel* model = this->sourceModel();
if (model != nullptr) {
QModelIndex index0 = model->index(source_row, 0, source_parent);
int nb = model->rowCount(index0);
for (int i = 0; !output && i < nb; ++i) {
output = filterAcceptsRow(i, index0);
}
}
}
}
return output;
}
bool SKGSortFilterProxyModel::filterAcceptsRowWords(int source_row, const QModelIndex& source_parent, const QStringList& iWords) const
{
_SKGTRACEINFUNC(10)
// Initialisation
bool output = true;
// Get source
QAbstractItemModel* model = this->sourceModel();
if (model != nullptr) {
int nbwords = iWords.count();
for (int w = 0; output && w < nbwords; ++w) {
QString word = iWords.at(w).toLower();
QString att;
QString op(':');
bool modeStartWith = true;
int pos = word.indexOf(QStringLiteral(":"));
int pos2 = word.indexOf(QStringLiteral("<="));
int pos3 = word.indexOf(QStringLiteral(">="));
int pos4 = word.indexOf(QStringLiteral("="));
int pos5 = word.indexOf(QStringLiteral("<"));
int pos6 = word.indexOf(QStringLiteral(">"));
int pos7 = word.indexOf(QStringLiteral("#"));
int opLength = 1;
if (pos2 != -1 && (pos2 < pos || pos == -1)) {
pos = pos2;
opLength = 2;
}
if (pos3 != -1 && (pos3 < pos || pos == -1)) {
pos = pos3;
opLength = 2;
}
if (pos4 != -1 && (pos4 < pos || pos == -1)) {
pos = pos4;
}
if (pos5 != -1 && (pos5 < pos || pos == -1)) {
pos = pos5;
}
if (pos6 != -1 && (pos6 < pos || pos == -1)) {
pos = pos6;
}
if (pos7 != -1 && (pos7 < pos || pos == -1)) {
pos = pos7;
}
if (pos != -1) {
att = word.left(pos);
if (att.endsWith(QStringLiteral("."))) {
modeStartWith = false;
att = att.left(att.count() - 1);
}
op = word.mid(pos, opLength);
word = word.right(word.count() - pos - op.count());
}
// Is this word validated by at least one column ?
output = false;
int nbcol = model->columnCount();
for (int i = 0; !output && i < nbcol; ++i) {
QModelIndex index0 = model->index(source_row, i, source_parent);
if (index0.isValid()) {
// Check if the header validates the attribute
if (att.isEmpty() ||
(modeStartWith && model->headerData(i, Qt::Horizontal).toString().startsWith(att, Qt::CaseInsensitive)) ||
(!modeStartWith && model->headerData(i, Qt::Horizontal).toString().compare(att, Qt::CaseInsensitive) == 0)) {
// Check if the value validate the attribute
if (op == QStringLiteral(":")) {
output = model->data(index0).toString().contains(word, Qt::CaseInsensitive);
if (!output) {
output = model->data(index0, Qt::UserRole).toString().contains(word, Qt::CaseInsensitive);
}
} else if (op == QStringLiteral("<")) {
QVariant var = model->data(index0, Qt::UserRole);
output = lessThan(var, QVariant(word));
} else if (op == QStringLiteral(">")) {
QVariant var = model->data(index0, Qt::UserRole);
output = moreThan(var, QVariant(word));
} else if (op == QStringLiteral("<=")) {
QVariant var = model->data(index0, Qt::UserRole);
output = (var == QVariant(word)) || lessThan(var, QVariant(word));
} else if (op == QStringLiteral(">=")) {
QVariant var = model->data(index0, Qt::UserRole);
output = (var == QVariant(word)) || moreThan(var, QVariant(word));
} else if (op == QStringLiteral("=")) {
QVariant var = model->data(index0, Qt::UserRole);
output = (var == QVariant(word));
} else if (op == QStringLiteral("#")) {
QVariant var = model->data(index0, Qt::UserRole);
QRegExp pattern(word, Qt::CaseInsensitive, QRegExp::RegExp2);
output = pattern.exactMatch(var.toString());
}
}
}
}
}
}
return output;
}
diff --git a/skgbasegui/skgsortfilterproxymodel.h b/skgbasegui/skgsortfilterproxymodel.h
index 94a207f03..572955f37 100644
--- a/skgbasegui/skgsortfilterproxymodel.h
+++ b/skgbasegui/skgsortfilterproxymodel.h
@@ -1,99 +1,99 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGSORTFILTERPROXYMODEL_H
#define SKGSORTFILTERPROXYMODEL_H
/** @file
* This file is a proxy model with better filter mechanism.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgbasegui_export.h"
#include <qsortfilterproxymodel.h>
class SKGSortFilterProxyModelPrivate;
/**
* This class is a proxy model with better filter mechanism
*/
class SKGBASEGUI_EXPORT SKGSortFilterProxyModel : public QSortFilterProxyModel
{
Q_OBJECT
/**
* The previous sort column
*/
Q_PROPERTY(int previousSortColumn READ getPreviousSortColumn WRITE setPreviousSortColumn USER true NOTIFY previousSortColumnModified)
public:
/**
* Constructor
* @param iParent parent widget
*/
explicit SKGSortFilterProxyModel(QObject* iParent = nullptr);
/**
* Destructor
*/
~SKGSortFilterProxyModel() override;
/**
* @brief Set the previous sort column (-1 = none).
*
* @param iCol the column index
*/
virtual void setPreviousSortColumn(int iCol);
/**
* @brief Get the previous sort column (-1 = none).
* @return the column index
*/
virtual int getPreviousSortColumn() const;
protected:
/**
* To know if a row must be displayed or not
* @param source_row source row
* @param source_parent prent
* @return true of false
*/
bool filterAcceptsRow(int source_row, const QModelIndex& source_parent) const override;
/**
* To sort items
* @param left left item
* @param right right item
* @return true of false
*/
bool lessThan(const QModelIndex& left, const QModelIndex& right) const override;
Q_SIGNALS:
/**
* This signal is launched when the property is modified
*/
void previousSortColumnModified();
private:
bool filterAcceptsRowWords(int source_row, const QModelIndex& source_parent, const QStringList& iWords) const;
bool lessThan(const QVariant& iLeftData, const QVariant& iRightData) const;
bool moreThan(const QVariant& iLeftData, const QVariant& iRightData) const;
SKGSortFilterProxyModelPrivate* const d;
};
#endif
diff --git a/skgbasegui/skgtableview.cpp b/skgbasegui/skgtableview.cpp
index dbb286ace..ce139145f 100644
--- a/skgbasegui/skgtableview.cpp
+++ b/skgbasegui/skgtableview.cpp
@@ -1,37 +1,37 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* A table view with more features.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgtableview.h"
#include <qheaderview.h>
SKGTableView::SKGTableView(QWidget* iParent)
: SKGTreeView(iParent)
{
this->setAllColumnsShowFocus(true);
this->setRootIsDecorated(false);
this->setUniformRowHeights(true);
header()->setStretchLastSection(false);
}
SKGTableView::~SKGTableView()
= default;
diff --git a/skgbasegui/skgtableview.h b/skgbasegui/skgtableview.h
index b01673c40..2fa86db2f 100644
--- a/skgbasegui/skgtableview.h
+++ b/skgbasegui/skgtableview.h
@@ -1,46 +1,46 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGTABLEVIEW_H
#define SKGTABLEVIEW_H
/** @file
* A table view with more features.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgbasegui_export.h"
#include "skgtreeview.h"
/**
* This file is a tab widget used by plugins
*/
class SKGBASEGUI_EXPORT SKGTableView : public SKGTreeView
{
Q_OBJECT
public:
/**
* Default Constructor
* @param iParent the parent
*/
explicit SKGTableView(QWidget* iParent);
/**
* Default Destructor
*/
~SKGTableView() override;
};
#endif // SKGTABLEVIEW_H
diff --git a/skgbasegui/skgtablewidget.cpp b/skgbasegui/skgtablewidget.cpp
index df5438110..ce4ebb0be 100644
--- a/skgbasegui/skgtablewidget.cpp
+++ b/skgbasegui/skgtablewidget.cpp
@@ -1,174 +1,174 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* A table widget with more features.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgtablewidget.h"
#include <qapplication.h>
#include <qclipboard.h>
#include <qevent.h>
#include <qscrollbar.h>
#include <algorithm>
#include "skgtraces.h"
SKGTableWidget::SKGTableWidget(QWidget* iParent)
: QTableWidget(iParent), stickH(false), stickV(false)
{
this->installEventFilter(this);
connect(horizontalScrollBar(), &QScrollBar::valueChanged, this, &SKGTableWidget::onActionTriggered);
connect(verticalScrollBar(), &QScrollBar::valueChanged, this, &SKGTableWidget::onActionTriggered);
connect(horizontalScrollBar(), &QScrollBar::rangeChanged, this, &SKGTableWidget::onRangeChanged);
connect(verticalScrollBar(), &QScrollBar::rangeChanged, this, &SKGTableWidget::onRangeChanged);
}
SKGTableWidget::~SKGTableWidget()
= default;
void SKGTableWidget::onRangeChanged()
{
auto* scrollb = qobject_cast<QScrollBar*>(sender());
if ((stickH && scrollb == horizontalScrollBar()) || (stickV && scrollb == verticalScrollBar())) {
scrollb->setValue(scrollb->maximum());
}
}
void SKGTableWidget::onActionTriggered()
{
auto* scrollb = qobject_cast<QScrollBar*>(sender());
if (scrollb != nullptr) {
if (scrollb == horizontalScrollBar()) {
stickH = (scrollb->value() == scrollb->maximum());
}
if (scrollb == verticalScrollBar()) {
stickV = (scrollb->value() == scrollb->maximum());
}
}
}
void SKGTableWidget::setStickHorizontal(bool iStick)
{
stickH = iStick;
}
bool SKGTableWidget::stickHorizontal() const
{
return stickH;
}
void SKGTableWidget::setStickVertical(bool iStick)
{
stickV = iStick;
}
bool SKGTableWidget::stickVertical() const
{
return stickV;
}
bool SKGTableWidget::eventFilter(QObject* iObject, QEvent* iEvent)
{
if (iObject == this && iEvent != nullptr && iEvent->type() == QEvent::KeyPress) {
auto* kevent = dynamic_cast<QKeyEvent*>(iEvent);
if (kevent != nullptr) {
if (kevent->key() == Qt::Key_Delete && state() != QAbstractItemView::EditingState) {
QList<QTableWidgetItem*> listOfSelectedItems = this->selectedItems();
int nb = listOfSelectedItems.count();
if (nb > 0) {
// Build list of indexes
QList<int> listIndex;
listIndex.reserve(nb);
for (int i = 0; i < nb; ++i) {
QModelIndex mIndex = this->indexFromItem(listOfSelectedItems.at(i));
if (!listIndex.contains(mIndex.row())) {
listIndex.append(mIndex.row());
}
}
// Sort reverse
std::sort(listIndex.begin(), listIndex.end(), std::greater<int>());
// Emit events
nb = listIndex.count();
for (int i = 0; i < nb; ++i) {
Q_EMIT removeLine(listIndex.at(i));
}
if (iEvent != nullptr) {
iEvent->accept();
}
return true; // stop the process
}
} else if (kevent->matches(QKeySequence::Copy) && this->state() != QAbstractItemView::EditingState) {
copy();
if (iEvent != nullptr) {
iEvent->accept();
}
return true; // stop the process
}
}
}
return QTableWidget::eventFilter(iObject, iEvent);
}
void SKGTableWidget::copy()
{
QItemSelectionModel* selection = selectionModel();
if (selection != nullptr) {
QModelIndexList indexes = selection->selectedIndexes();
if (indexes.empty()) {
return;
}
std::sort(indexes.begin(), indexes.end());
// You need a pair of indexes to find the row changes
QModelIndex previous = indexes.first();
indexes.removeFirst();
QString header_text;
bool header_done = false;
QString selected_text;
for (const auto& current : qAsConst(indexes)) {
selected_text.append(model()->data(previous).toString());
if (!header_done) {
header_text.append(model()->headerData(previous.column(), Qt::Horizontal).toString());
}
if (current.row() != previous.row()) {
selected_text.append(QLatin1Char('\n'));
header_done = true;
} else {
selected_text.append(QLatin1Char(';'));
if (!header_done) {
header_text.append(QLatin1Char(';'));
}
}
previous = current;
}
// add last element
selected_text.append(model()->data(previous).toString());
selected_text.append(QLatin1Char('\n'));
QApplication::clipboard()->setText(header_text + '\n' + selected_text);
}
}
diff --git a/skgbasegui/skgtablewidget.h b/skgbasegui/skgtablewidget.h
index d870ca321..d29bc9c9f 100644
--- a/skgbasegui/skgtablewidget.h
+++ b/skgbasegui/skgtablewidget.h
@@ -1,95 +1,95 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGTABLEWIDGET_H
#define SKGTABLEWIDGET_H
/** @file
* A table widget with more features.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgbasegui_export.h"
#include <qtablewidget.h>
/**
* This file is a combo box with more features.
*/
class SKGBASEGUI_EXPORT SKGTableWidget : public QTableWidget
{
Q_OBJECT
public:
/**
* Default Constructor
* @param iParent the parent
*/
explicit SKGTableWidget(QWidget* iParent);
/**
* Default Destructor
*/
~SKGTableWidget() override;
/**
* Set the horizontal scroll bar stick to the maximum
* @param iStick the stick state
*/
virtual void setStickHorizontal(bool iStick);
/**
* Get the horizontal scroll bar stick to the maximum
* @return the stick state
*/
virtual bool stickHorizontal() const;
/**
* Set the vertical scroll bar stick to the maximum
* @param iStick the stick state
*/
virtual void setStickVertical(bool iStick);
/**
* Get the vertical scroll bar stick to the maximum
* @return the stick state
*/
virtual bool stickVertical() const;
Q_SIGNALS:
/**
* Line must be removed
*/
void removeLine(int /*_t1*/);
protected:
/**
* Event filtering
* @param iObject object
* @param iEvent event
* @return In your reimplementation of this function, if you want to filter the event out, i.e. stop it being handled further, return true; otherwise return false.
*/
bool eventFilter(QObject* iObject, QEvent* iEvent) override;
private Q_SLOTS:
void copy();
void onActionTriggered();
void onRangeChanged();
private:
bool stickH;
bool stickV;
};
#endif // SKGTABLEWIDGET_H
diff --git a/skgbasegui/skgtablewithgraph.cpp b/skgbasegui/skgtablewithgraph.cpp
index c0739a67c..4035fc897 100644
--- a/skgbasegui/skgtablewithgraph.cpp
+++ b/skgbasegui/skgtablewithgraph.cpp
@@ -1,2850 +1,2850 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* A table with graph with more features.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgtablewithgraph.h"
#include <kcolorscheme.h>
#include <kstringhandler.h>
#include <qcollator.h>
#include <qdesktopservices.h>
#include <qdom.h>
#include <qfileinfo.h>
#include <qgraphicseffect.h>
#include <qgraphicsitem.h>
#include <qheaderview.h>
#include <qmath.h>
#include <qmenu.h>
#include <qpainter.h>
#include <qprinter.h>
#include <qregexp.h>
#include <qsavefile.h>
#include <qscriptengine.h>
#include <qscrollbar.h>
#include <qtablewidget.h>
#include <qtextcodec.h>
#include <qtimer.h>
#include <qwidgetaction.h>
#include <algorithm>
#include "skgcolorbutton.h"
#include "skgcombobox.h"
#include "skggraphicsscene.h"
#include "skgmainpanel.h"
#include "skgservices.h"
#include "skgtraces.h"
#include "skgtreemap.h"
/**
* Data identifier for value
*/
static const int DATA_VALUE = 12;
/**
* Data identifier for color
*/
static const int DATA_COLOR_H = 11;
/**
* Data identifier for color
*/
static const int DATA_COLOR_S = 12;
/**
* Data identifier for color
*/
static const int DATA_COLOR_V = 13;
/**
* Data identifier for Z value
*/
static const int DATA_Z_VALUE = 14;
/**
* Data identifier for mode
*/
static const int DATA_MODE = 15;
/**
* Alpha value
*/
static const int ALPHA = 200;
/**
* Box size
*/
static const double BOX_SIZE = 120.0;
/**
* Box margin
*/
static const double BOX_MARGIN = 10.0;
#define cloneAction(MENU, ACTION, SLOTTOCALL) \
auto act = (MENU)->addAction((ACTION)->icon(), (ACTION)->text()); \
act->setCheckable(true); \
act->setChecked((ACTION)->isChecked()); \
connect(act, &QAction::triggered, this, SLOTTOCALL); \
connect(act, &QAction::toggled, ACTION, &QAction::setChecked); \
connect(ACTION, &QAction::toggled, act, &QAction::setChecked);
SKGTableWithGraph::SKGTableWithGraph() : SKGTableWithGraph(nullptr)
{}
SKGTableWithGraph::SKGTableWithGraph(QWidget* iParent)
: QWidget(iParent), m_scene(nullptr), m_additionalInformation(NONE), m_nbVirtualColumns(0),
m_selectable(true), m_toolBarVisible(true), m_graphTypeVisible(true), m_limitVisible(true), m_averageVisible(true),
m_linearRegressionVisible(true), m_paretoVisible(false), m_legendVisible(false), m_graphVisible(true), m_tableVisible(true), m_textVisible(false), m_zeroVisible(true), m_decimalsVisible(true), m_shadow(true),
m_mainMenu(nullptr),
m_indexSum(-1), m_indexAverage(-1), m_indexMin(-1), m_indexLinearRegression(-1), m_sortOrder(Qt::AscendingOrder), m_sortColumn(0)
{
m_axisColor = Qt::gray;
m_gridColor = Qt::lightGray;
m_minColor = Qt::red;
m_maxColor = Qt::green;
m_paretoColor = Qt::darkRed;
m_averageColor = Qt::blue;
m_tendencyColor = Qt::darkYellow;
m_backgroundColor = Qt::white;
m_textColor = Qt::black;
m_NegativeColor = KColorScheme(QPalette::Normal).foreground(KColorScheme::NegativeText);
m_WhiteColor = QBrush(Qt::white);
ui.setupUi(this);
ui.kTextEdit->hide();
ui.kFilterEdit->setPlaceholderText(i18n("Search"));
m_displayMode = new SKGComboBox(this);
m_displayMode->addItem(SKGServices::fromTheme(QStringLiteral("office-chart-bar-stacked")), i18nc("Noun, a type of graph, with bars stacked upon each other", "Stack of lines"), static_cast<int>(STACK));
m_displayMode->addItem(SKGServices::fromTheme(QStringLiteral("office-chart-bar-stacked")), i18nc("Noun, a type of graph, with bars stacked upon each other", "Stack of columns"), static_cast<int>(STACKCOLUMNS));
m_displayMode->addItem(SKGServices::fromTheme(QStringLiteral("office-chart-bar")), i18nc("Noun, a type of graph, with bars placed besides each other", "Histogram"), static_cast<int>(HISTOGRAM));
m_displayMode->addItem(SKGServices::fromTheme(QStringLiteral("office-chart-scatter")), i18nc("Noun, a type of graph with only points", "Point"), static_cast<int>(POINT));
m_displayMode->addItem(SKGServices::fromTheme(QStringLiteral("office-chart-line")), i18nc("Noun, a type of graph with only lines", "Line"), static_cast<int>(LINE));
m_displayMode->addItem(SKGServices::fromTheme(QStringLiteral("office-chart-area-stacked")), i18nc("Noun, a type of graph, with lines stacked upon each other", "Stacked area"), static_cast<int>(STACKAREA));
m_displayMode->addItem(SKGServices::fromTheme(QStringLiteral("skg-chart-bubble")), i18nc("Noun, a type of graph, with bubbles", "Bubble"), static_cast<int>(BUBBLE));
m_displayMode->addItem(SKGServices::fromTheme(QStringLiteral("office-chart-pie")), i18nc("Noun, a type of graph that looks like a sliced pie", "Pie"), static_cast<int>(PIE));
m_displayMode->addItem(SKGServices::fromTheme(QStringLiteral("office-chart-ring")), i18nc("Noun, a type of graph that looks like concentric slices of a pie (a la filelight)", "Concentric pie"), static_cast<int>(CONCENTRICPIE));
m_displayMode->addItem(SKGServices::fromTheme(QStringLiteral("map-flat")), i18nc("Noun, a type of graph that looks treemap", "Treemap"), static_cast<int>(TREEMAP));
ui.graphicView->addToolbarWidget(m_displayMode);
ui.kShow->addItem(QStringLiteral("table"), i18n("Table"), QStringLiteral("view-list-details"), QString(), QString(), QStringLiteral("text"), QStringLiteral("graph"), QString(), Qt::META + Qt::Key_T);
ui.kShow->addItem(QStringLiteral("graph"), i18n("Graph"), QStringLiteral("office-chart-pie"), QString(), QString(), QStringLiteral("text"), QStringLiteral("table"), QString(), Qt::META + Qt::Key_G);
ui.kShow->addItem(QStringLiteral("text"), i18n("Text"), QStringLiteral("view-list-text"), QString(), QString(), QStringLiteral("table;graph"), QStringLiteral("table;graph"), QString(), Qt::META + Qt::Key_R);
ui.kShow->setDefaultState(QStringLiteral("table;graph"));
connect(ui.kShow, &SKGShow::stateChanged, this, &SKGTableWithGraph::onDisplayModeChanged, Qt::QueuedConnection);
m_timer.setSingleShot(true);
connect(&m_timer, &QTimer::timeout, this, &SKGTableWithGraph::refresh, Qt::QueuedConnection);
m_timerRedraw.setSingleShot(true);
connect(&m_timerRedraw, &QTimer::timeout, this, &SKGTableWithGraph::redrawGraph, Qt::QueuedConnection);
// Build contextual menu
ui.kTable->setContextMenuPolicy(Qt::CustomContextMenu);
connect(ui.kTable, &SKGTableWidget::customContextMenuRequested, this, &SKGTableWithGraph::showMenu);
m_mainMenu = new QMenu(ui.kTable);
QAction* actExport = m_mainMenu->addAction(SKGServices::fromTheme(QStringLiteral("document-export")), i18nc("Noun, user action", "Export..."));
connect(actExport, &QAction::triggered, this, &SKGTableWithGraph::onExport);
// Add graph mode in menu
getGraphContextualMenu()->addSeparator();
auto displayModeMenu = new SKGComboBox(this);
displayModeMenu->addItem(SKGServices::fromTheme(QStringLiteral("office-chart-bar-stacked")), i18nc("Noun, a type of graph, with bars stacked upon each other", "Stack of lines"), static_cast<int>(STACK));
displayModeMenu->addItem(SKGServices::fromTheme(QStringLiteral("office-chart-bar-stacked")), i18nc("Noun, a type of graph, with bars stacked upon each other", "Stack of columns"), static_cast<int>(STACKCOLUMNS));
displayModeMenu->addItem(SKGServices::fromTheme(QStringLiteral("office-chart-bar")), i18nc("Noun, a type of graph, with bars placed besides each other", "Histogram"), static_cast<int>(HISTOGRAM));
displayModeMenu->addItem(SKGServices::fromTheme(QStringLiteral("office-chart-scatter")), i18nc("Noun, a type of graph with only points", "Point"), static_cast<int>(POINT));
displayModeMenu->addItem(SKGServices::fromTheme(QStringLiteral("office-chart-line")), i18nc("Noun, a type of graph with only lines", "Line"), static_cast<int>(LINE));
displayModeMenu->addItem(SKGServices::fromTheme(QStringLiteral("office-chart-area-stacked")), i18nc("Noun, a type of graph, with lines stacked upon each other", "Stacked area"), static_cast<int>(STACKAREA));
displayModeMenu->addItem(SKGServices::fromTheme(QStringLiteral("skg-chart-bubble")), i18nc("Noun, a type of graph, with bubbles", "Bubble"), static_cast<int>(BUBBLE));
displayModeMenu->addItem(SKGServices::fromTheme(QStringLiteral("office-chart-pie")), i18nc("Noun, a type of graph that looks like a sliced pie", "Pie"), static_cast<int>(PIE));
displayModeMenu->addItem(SKGServices::fromTheme(QStringLiteral("office-chart-ring")), i18nc("Noun, a type of graph that looks like concentric slices of a pie (a la filelight)", "Concentric pie"), static_cast<int>(CONCENTRICPIE));
displayModeMenu->addItem(SKGServices::fromTheme(QStringLiteral("map-flat")), i18nc("Noun, a type of graph that looks treemap", "Treemap"), static_cast<int>(TREEMAP));
m_displayModeWidget = new QWidgetAction(this);
m_displayModeWidget->setDefaultWidget(displayModeMenu);
getGraphContextualMenu()->addAction(m_displayModeWidget);
connect(displayModeMenu, static_cast<void (SKGComboBox::*)(int)>(&SKGComboBox::currentIndexChanged), m_displayMode, &SKGComboBox::setCurrentIndex);
connect(m_displayMode, static_cast<void (SKGComboBox::*)(int)>(&SKGComboBox::currentIndexChanged), displayModeMenu, &SKGComboBox::setCurrentIndex);
// Reset Colors
QAction* resetColorsAction = m_mainMenu->addAction(SKGServices::fromTheme(QStringLiteral("format-fill-color")), i18nc("Noun, user action", "Reset default colors"));
connect(resetColorsAction, &QAction::triggered, this, &SKGTableWithGraph::resetColors);
getGraphContextualMenu()->addAction(resetColorsAction);
// Add item in menu of the graph
m_allPositiveMenu = getGraphContextualMenu()->addAction(SKGServices::fromTheme(QStringLiteral("go-up-search")), i18nc("Noun, user action", "All values in positive"));
if (m_allPositiveMenu != nullptr) {
m_allPositiveMenu->setCheckable(true);
}
connect(m_allPositiveMenu, &QAction::toggled, this, &SKGTableWithGraph::redrawGraphDelayed, Qt::QueuedConnection);
// Add item in menu of the graph
m_actShowLimits = getGraphContextualMenu()->addAction(i18nc("Noun, user action", "Show limits"));
if (m_actShowLimits != nullptr) {
m_actShowLimits->setCheckable(true);
m_actShowLimits->setChecked(m_limitVisible);
connect(m_actShowLimits, &QAction::triggered, this, &SKGTableWithGraph::switchLimitsVisibility);
// Clone action on table contextual menu
cloneAction(m_mainMenu, m_actShowLimits, &SKGTableWithGraph::switchLimitsVisibility)
}
// Add item in menu of the graph
m_actShowAverage = getGraphContextualMenu()->addAction(i18nc("Noun, user action", "Show average"));
if (m_actShowAverage != nullptr) {
m_actShowAverage->setCheckable(true);
m_actShowAverage->setChecked(m_averageVisible);
connect(m_actShowAverage, &QAction::triggered, this, &SKGTableWithGraph::switchAverageVisibility);
// Clone action on table contextual menu
cloneAction(m_mainMenu, m_actShowAverage, &SKGTableWithGraph::switchAverageVisibility)
}
// Add item in menu of the graph
m_actShowLinearRegression = getGraphContextualMenu()->addAction(i18nc("Noun, user action", "Show tendency line"));
if (m_actShowLinearRegression != nullptr) {
m_actShowLinearRegression->setCheckable(true);
m_actShowLinearRegression->setChecked(m_linearRegressionVisible);
connect(m_actShowLinearRegression, &QAction::triggered, this, &SKGTableWithGraph::switchLinearRegressionVisibility);
// Clone action on table contextual menu
cloneAction(m_mainMenu, m_actShowLinearRegression, &SKGTableWithGraph::switchLinearRegressionVisibility)
}
// Add item in menu of the graph
m_actShowPareto = getGraphContextualMenu()->addAction(i18nc("Noun, user action", "Show Pareto curve"));
if (m_actShowPareto != nullptr) {
m_actShowPareto->setCheckable(true);
m_actShowPareto->setChecked(m_paretoVisible);
connect(m_actShowPareto, &QAction::triggered, this, &SKGTableWithGraph::switchParetoVisibility);
}
// Add item in menu of the graph
m_actShowLegend = getGraphContextualMenu()->addAction(SKGServices::fromTheme(QStringLiteral("help-contents")), i18nc("Noun, user action", "Show legend"));
if (m_actShowLegend != nullptr) {
m_actShowLegend->setCheckable(true);
m_actShowLegend->setChecked(m_legendVisible);
connect(m_actShowLegend, &QAction::triggered, this, &SKGTableWithGraph::switchLegendVisibility);
}
// Add item in menu of the graph
m_actShowZero = getGraphContextualMenu()->addAction(SKGServices::fromTheme(QStringLiteral("labplot-xy-plot-two-axes-centered-origin")), i18nc("Noun, user action", "Show origin"));
if (m_actShowZero != nullptr) {
m_actShowZero->setCheckable(true);
m_actShowZero->setChecked(m_zeroVisible);
connect(m_actShowZero, &QAction::triggered, this, &SKGTableWithGraph::swithOriginVisibility);
}
// Add item in menu of the graph
m_actShowDecimal = getGraphContextualMenu()->addAction(SKGServices::fromTheme(QStringLiteral("format-precision-less")), i18nc("Noun, user action", "Show decimals"));
if (m_actShowDecimal != nullptr) {
m_actShowDecimal->setCheckable(true);
m_actShowDecimal->setChecked(m_decimalsVisible);
connect(m_actShowDecimal, &QAction::triggered, this, &SKGTableWithGraph::swithDecimalsVisibility);
// Clone action on table contextual menu
cloneAction(m_mainMenu, m_actShowDecimal, &SKGTableWithGraph::swithDecimalsVisibility)
}
// Set headers parameters
QHeaderView* verticalHeader = ui.kTable->verticalHeader();
if (verticalHeader != nullptr) {
verticalHeader->hide();
verticalHeader->setDefaultSectionSize(verticalHeader->minimumSectionSize());
// verticalHeader->setSectionResizeMode(QHeaderView::ResizeToContents);
}
ui.kTable->setSortingEnabled(false); // sort must be enable for refresh method
QHeaderView* horizontalHeader = ui.kTable->horizontalHeader();
if (horizontalHeader != nullptr) {
horizontalHeader->setSectionResizeMode(QHeaderView::ResizeToContents);
horizontalHeader->show();
horizontalHeader->setSortIndicatorShown(true);
horizontalHeader->setSortIndicator(m_sortColumn, m_sortOrder);
connect(horizontalHeader, &QHeaderView::sortIndicatorChanged, this, &SKGTableWithGraph::refresh);
}
connect(ui.kTable->horizontalScrollBar(), &QScrollBar::valueChanged, this, &SKGTableWithGraph::onHorizontalScrollBarChanged);
connect(m_displayMode, static_cast<void (SKGComboBox::*)(const QString&)>(&SKGComboBox::currentTextChanged), this, &SKGTableWithGraph::redrawGraphDelayed, Qt::QueuedConnection);
connect(ui.graphicView, &SKGGraphicsView::resized, this, &SKGTableWithGraph::redrawGraphDelayed, Qt::QueuedConnection);
connect(ui.kTable, &SKGTableWidget::cellDoubleClicked, this, &SKGTableWithGraph::onDoubleClick);
connect(ui.kTable, &SKGTableWidget::itemSelectionChanged, this, &SKGTableWithGraph::onSelectionChanged);
connect(ui.kFilterEdit, &QLineEdit::textChanged, this, &SKGTableWithGraph::onFilterModified);
#ifdef SKG_WEBENGINE
connect(ui.kTextEdit, &SKGWebView::linkClicked, this, &SKGTableWithGraph::onLinkClicked);
#else
ui.kTextEdit->page()->setLinkDelegationPolicy(QWebPage::DelegateAllLinks);
connect(ui.kTextEdit, &SKGWebView::linkClicked, this, &SKGTableWithGraph::onLinkClicked);
#endif
}
SKGTableWithGraph::~SKGTableWithGraph()
{
delete m_scene;
m_scene = nullptr;
m_mainMenu = nullptr;
m_actShowLimits = nullptr;
m_actShowLinearRegression = nullptr;
m_actShowPareto = nullptr;
m_displayModeWidget = nullptr;
m_displayMode = nullptr;
}
void SKGTableWithGraph::onHorizontalScrollBarChanged(int iValue)
{
QHeaderView* verticalHeader = ui.kTable->verticalHeader();
if (verticalHeader != nullptr) {
verticalHeader->setVisible(iValue > 0);
}
}
bool SKGTableWithGraph::isGraphVisible() const
{
return m_graphVisible;
}
bool SKGTableWithGraph::isTableVisible() const
{
return m_tableVisible;
}
bool SKGTableWithGraph::isTextReportVisible() const
{
return m_textVisible;
}
SKGShow* SKGTableWithGraph::getShowWidget() const
{
return ui.kShow;
}
void SKGTableWithGraph::setAverageColor(const QColor& iColor)
{
m_averageColor = iColor;
}
void SKGTableWithGraph::setAxisColor(const QColor& iColor)
{
m_axisColor = iColor;
}
void SKGTableWithGraph::setGridColor(const QColor& iColor)
{
m_gridColor = iColor;
}
void SKGTableWithGraph::setMaxColor(const QColor& iColor)
{
m_maxColor = iColor;
}
void SKGTableWithGraph::setParetoColor(const QColor& iColor)
{
m_paretoColor = iColor;
}
void SKGTableWithGraph::setMinColor(const QColor& iColor)
{
m_minColor = iColor;
}
void SKGTableWithGraph::setTendencyColor(const QColor& iColor)
{
m_tendencyColor = iColor;
}
void SKGTableWithGraph::setOutlineColor(const QColor& iColor)
{
m_outlineColor = iColor;
}
void SKGTableWithGraph::setBackgroundColor(const QColor& iColor)
{
m_backgroundColor = iColor;
}
void SKGTableWithGraph::setTextColor(const QColor& iColor)
{
m_textColor = iColor;
}
void SKGTableWithGraph::setAntialiasing(bool iAntialiasing)
{
ui.graphicView->setAntialiasing(iAntialiasing);
}
void SKGTableWithGraph::setGraphTypeSelectorVisible(bool iVisible)
{
if (m_graphTypeVisible != iVisible) {
m_graphTypeVisible = iVisible;
if (m_displayMode != nullptr) {
m_displayMode->setVisible(m_graphTypeVisible);
}
if (m_displayModeWidget != nullptr) {
m_displayModeWidget->setVisible(m_graphTypeVisible);
}
Q_EMIT modified();
}
}
bool SKGTableWithGraph::isGraphTypeSelectorVisible() const
{
return m_graphTypeVisible;
}
bool SKGTableWithGraph::switchLimitsVisibility()
{
m_limitVisible = !m_limitVisible;
refresh();
return m_limitVisible;
}
bool SKGTableWithGraph::switchAverageVisibility()
{
m_averageVisible = !m_averageVisible;
refresh();
return m_averageVisible;
}
bool SKGTableWithGraph::switchLegendVisibility()
{
m_legendVisible = !m_legendVisible;
redrawGraphDelayed();
return m_legendVisible;
}
bool SKGTableWithGraph::swithOriginVisibility()
{
m_zeroVisible = !m_zeroVisible;
redrawGraphDelayed();
return m_zeroVisible;
}
bool SKGTableWithGraph::swithDecimalsVisibility()
{
m_decimalsVisible = !m_decimalsVisible;
refresh();
return m_decimalsVisible;
}
bool SKGTableWithGraph::switchLinearRegressionVisibility()
{
m_linearRegressionVisible = !m_linearRegressionVisible;
refresh();
return m_linearRegressionVisible;
}
bool SKGTableWithGraph::switchParetoVisibility()
{
m_paretoVisible = !m_paretoVisible;
redrawGraphDelayed();
return m_paretoVisible;
}
QMenu* SKGTableWithGraph::getTableContextualMenu() const
{
return m_mainMenu;
}
QMenu* SKGTableWithGraph::getGraphContextualMenu() const
{
return ui.graphicView->getContextualMenu();
}
void SKGTableWithGraph::showMenu(const QPoint iPos)
{
if (m_mainMenu != nullptr) {
m_mainMenu->popup(ui.kTable->mapToGlobal(iPos));
}
}
QTableWidget* SKGTableWithGraph::table() const
{
return ui.kTable;
}
SKGGraphicsView* SKGTableWithGraph::graph() const
{
return ui.graphicView;
}
SKGWebView* SKGTableWithGraph::textReport() const
{
return ui.kTextEdit;
}
SKGStringListList SKGTableWithGraph::getTable()
{
// Build table
SKGStringListList output;
// Get header names
int nb2 = ui.kTable->rowCount();
int nb = ui.kTable->columnCount();
output.reserve(nb2 + 1);
QStringList cols;
cols.reserve(2 * nb);
for (int i = 0; i < nb; ++i) {
cols.append(ui.kTable->horizontalHeaderItem(i)->text());
cols.append(i18n("%1 (raw)", ui.kTable->horizontalHeaderItem(i)->text()));
}
output.append(cols);
// Get content
for (int i = 0; i < nb2; ++i) {
QStringList row;
row.reserve(nb);
for (int j = 0; j < nb; j++) {
auto* button = qobject_cast<SKGColorButton*>(ui.kTable->cellWidget(i, j));
if (button != nullptr) {
row.append(button->text());
row.append(button->color().toRgb().name());
} else {
row.append(ui.kTable->item(i, j)->text());
QString raw = ui.kTable->item(i, j)->data(DATA_VALUE).toString();
if (raw.isEmpty()) {
raw = ui.kTable->item(i, j)->text();
}
row.append(raw);
}
}
output.append(row);
}
return output;
}
QString SKGTableWithGraph::getState()
{
SKGTRACEINFUNC(10)
QDomDocument doc(QStringLiteral("SKGML"));
QDomElement root = doc.createElement(QStringLiteral("parameters"));
doc.appendChild(root);
if (ui.graphicView->isVisible() && ui.kTable->isVisible()) {
root.setAttribute(QStringLiteral("splitterState"), QString(ui.splitter->saveState().toHex()));
}
root.setAttribute(QStringLiteral("graphMode"), SKGServices::intToString(static_cast<int>(getGraphType())));
root.setAttribute(QStringLiteral("allPositive"), m_allPositiveMenu->isChecked() ? QStringLiteral("Y") : QStringLiteral("N"));
root.setAttribute(QStringLiteral("filter"), ui.kFilterEdit->text());
root.setAttribute(QStringLiteral("limitVisible"), m_limitVisible ? QStringLiteral("Y") : QStringLiteral("N"));
root.setAttribute(QStringLiteral("averageVisible"), m_averageVisible ? QStringLiteral("Y") : QStringLiteral("N"));
root.setAttribute(QStringLiteral("linearRegressionVisible"), m_linearRegressionVisible ? QStringLiteral("Y") : QStringLiteral("N"));
root.setAttribute(QStringLiteral("paretoVisible"), m_paretoVisible ? QStringLiteral("Y") : QStringLiteral("N"));
root.setAttribute(QStringLiteral("legendVisible"), m_legendVisible ? QStringLiteral("Y") : QStringLiteral("N"));
root.setAttribute(QStringLiteral("zeroVisible"), m_zeroVisible ? QStringLiteral("Y") : QStringLiteral("N"));
root.setAttribute(QStringLiteral("decimalsVisible"), m_decimalsVisible ? QStringLiteral("Y") : QStringLiteral("N"));
QMapIterator<QString, QColor> i(m_mapTitleColor);
while (i.hasNext()) {
i.next();
QDomElement color = doc.createElement(QStringLiteral("color"));
root.appendChild(color);
color.setAttribute(QStringLiteral("key"), i.key());
color.setAttribute(QStringLiteral("value"), i.value().name());
}
QHeaderView* horizontalHeader = ui.kTable->horizontalHeader();
root.setAttribute(QStringLiteral("sortOrder"), SKGServices::intToString(horizontalHeader->sortIndicatorOrder()));
root.setAttribute(QStringLiteral("sortColumn"), SKGServices::intToString(horizontalHeader->sortIndicatorSection()));
root.setAttribute(QStringLiteral("graphicViewState"), ui.graphicView->getState());
root.setAttribute(QStringLiteral("web"), ui.kTextEdit->getState());
root.setAttribute(QStringLiteral("show"), ui.kShow->getState());
if (ui.kTable->stickHorizontal()) {
root.setAttribute(QStringLiteral("stickH"), QStringLiteral("Y"));
}
if (ui.kTable->stickVertical()) {
root.setAttribute(QStringLiteral("stickV"), QStringLiteral("Y"));
}
return doc.toString();
}
void SKGTableWithGraph::setState(const QString& iState)
{
SKGTRACEINFUNC(10)
m_timer.stop();
m_timerRedraw.stop();
QDomDocument doc(QStringLiteral("SKGML"));
doc.setContent(iState);
QDomElement root = doc.documentElement();
m_mapTitleColor.clear();
QDomNodeList colors = root.elementsByTagName(QStringLiteral("color"));
int nb = colors.count();
for (int i = 0; i < nb; ++i) {
QDomElement c = colors.at(i).toElement();
m_mapTitleColor[c.attribute(QStringLiteral("key"))] = QColor(c.attribute(QStringLiteral("value")));
}
QString splitterStateString = root.attribute(QStringLiteral("splitterState"));
if (!splitterStateString.isEmpty()) {
ui.splitter->restoreState(QByteArray::fromHex(splitterStateString.toLatin1()));
}
QString graphModeString = root.attribute(QStringLiteral("graphMode"));
QString allPositiveString = root.attribute(QStringLiteral("allPositive"));
QString limitVisibleString = root.attribute(QStringLiteral("limitVisible"));
QString averageVisibleString = root.attribute(QStringLiteral("averageVisible"));
QString legendVisibleString = root.attribute(QStringLiteral("legendVisible"));
QString zeroVisibleString = root.attribute(QStringLiteral("zeroVisible"));
QString decimalsVisibleString = root.attribute(QStringLiteral("decimalsVisible"));
QString linearRegressionVisibleString = root.attribute(QStringLiteral("linearRegressionVisible"));
QString paretorVisibleString = root.attribute(QStringLiteral("paretoVisible"));
QString sortOrderString = root.attribute(QStringLiteral("sortOrder"));
QString sortColumnString = root.attribute(QStringLiteral("sortColumn"));
QString graphicViewStateString = root.attribute(QStringLiteral("graphicViewState"));
QString webString = root.attribute(QStringLiteral("web"));
QString showString = root.attribute(QStringLiteral("show"));
ui.kTable->setStickHorizontal(root.attribute(QStringLiteral("stickH")) == QStringLiteral("Y"));
ui.kTable->setStickVertical(root.attribute(QStringLiteral("stickV")) == QStringLiteral("Y"));
// Default value in case of reset
if (graphModeString.isEmpty()) {
graphModeString = SKGServices::intToString(LINE);
}
if (allPositiveString.isEmpty()) {
allPositiveString = 'N';
}
if (limitVisibleString.isEmpty()) {
limitVisibleString = 'Y';
}
if (averageVisibleString.isEmpty()) {
averageVisibleString = 'Y';
}
if (legendVisibleString.isEmpty()) {
legendVisibleString = 'N';
}
if (linearRegressionVisibleString.isEmpty()) {
linearRegressionVisibleString = 'Y';
}
if (paretorVisibleString.isEmpty()) {
paretorVisibleString = 'N';
}
if (sortOrderString.isEmpty()) {
sortOrderString = '0';
}
if (sortColumnString.isEmpty()) {
sortColumnString = '0';
}
// Set
setGraphType(SKGTableWithGraph::HISTOGRAM);
if (m_displayMode != nullptr) {
m_displayMode->setCurrentIndex(1);
}
setGraphType(static_cast<SKGTableWithGraph::GraphType>(SKGServices::stringToInt(graphModeString)));
m_allPositiveMenu->setChecked(allPositiveString == QStringLiteral("Y"));
ui.kFilterEdit->setText(root.attribute(QStringLiteral("filter")));
m_limitVisible = (limitVisibleString == QStringLiteral("Y"));
if (m_actShowLimits != nullptr) {
m_actShowLimits->setChecked(m_limitVisible);
}
m_averageVisible = (averageVisibleString == QStringLiteral("Y"));
if (m_actShowAverage != nullptr) {
m_actShowAverage->setChecked(m_averageVisible);
}
m_legendVisible = (legendVisibleString == QStringLiteral("Y"));
if (m_actShowLegend != nullptr) {
m_actShowLegend->setChecked(m_legendVisible);
}
m_zeroVisible = (zeroVisibleString != QStringLiteral("N"));
if (m_actShowZero != nullptr) {
m_actShowZero->setChecked(m_zeroVisible);
}
m_decimalsVisible = (decimalsVisibleString != QStringLiteral("N"));
if (m_actShowDecimal != nullptr) {
m_actShowDecimal->setChecked(m_decimalsVisible);
}
m_linearRegressionVisible = (linearRegressionVisibleString == QStringLiteral("Y"));
if (m_actShowLinearRegression != nullptr) {
m_actShowLinearRegression->setChecked(m_linearRegressionVisible);
}
m_paretoVisible = (paretorVisibleString == QStringLiteral("Y"));
if (m_actShowPareto != nullptr) {
m_actShowPareto->setChecked(m_paretoVisible);
}
ui.kTable->setColumnCount(SKGServices::stringToInt(sortColumnString) + 1);
QHeaderView* horizontalHeader = ui.kTable->horizontalHeader();
if (horizontalHeader != nullptr) {
bool previous = horizontalHeader->blockSignals(true);
horizontalHeader->setSortIndicator(SKGServices::stringToInt(sortColumnString), static_cast<Qt::SortOrder>(SKGServices::stringToInt(sortOrderString)));
horizontalHeader->blockSignals(previous);
}
ui.graphicView->setState(graphicViewStateString);
ui.kTextEdit->setState(webString);
if (!showString.isEmpty()) {
ui.kShow->setState(showString);
}
}
void SKGTableWithGraph::setFilterVisibility(bool iVisibility) const
{
ui.kToolbar->setVisible(iVisibility);
}
void SKGTableWithGraph::onFilterModified()
{
m_timerRedraw.stop();
m_timer.start(300);
}
void SKGTableWithGraph::onDisplayModeChanged()
{
QStringList mode = SKGServices::splitCSVLine(ui.kShow->getState());
// Hide all
if (m_scene != nullptr) {
m_scene->clear();
delete m_scene;
}
m_scene = new SKGGraphicsScene();
ui.graphicView->setScene(m_scene);
ui.graphicView->hide();
ui.kTextEdit->hide();
bool p = ui.kTable->blockSignals(true);
ui.kTable->hide();
ui.kTable->blockSignals(p);
m_graphVisible = false;
m_tableVisible = false;
m_textVisible = false;
m_mapItemGraphic.clear();
// Show needed widget
if (mode.contains(QStringLiteral("table"))) {
ui.kTable->show();
m_tableVisible = true;
}
if (mode.contains(QStringLiteral("graph"))) {
ui.graphicView->show();
m_graphVisible = true;
redrawGraphDelayed();
}
if (mode.contains(QStringLiteral("text"))) {
QTimer::singleShot(100, Qt::CoarseTimer, ui.kTextEdit, &SKGWebView::show);
m_textVisible = true;
redrawText();
}
}
void SKGTableWithGraph::setData(const SKGStringListList& iData,
const SKGServices::SKGUnitInfo& iPrimaryUnit,
const SKGServices::SKGUnitInfo& iSecondaryUnit,
SKGTableWithGraph::DisplayAdditionalFlag iAdditionalInformation,
int iNbVirtualColumn)
{
SKGTRACEINFUNC(10)
m_data = iData;
m_primaryUnit = iPrimaryUnit;
m_secondaryUnit = iSecondaryUnit;
m_additionalInformation = iAdditionalInformation;
m_nbVirtualColumns = iNbVirtualColumn;
onFilterModified();
}
SKGTableWithGraph::DisplayAdditionalFlag SKGTableWithGraph::getAdditionalDisplayMode() const
{
return m_additionalInformation;
}
QStringList SKGTableWithGraph::getSumItems(const QString& iString) const
{
QStringList output;
QString current = iString;
int index = -1;
do {
output.insert(0, current);
index = current.lastIndexOf(OBJECTSEPARATOR);
if (index != -1) {
current = current.left(index);
}
} while (index != -1);
return output;
}
void SKGTableWithGraph::addSums(SKGStringListList& ioTable, int& iNblines)
{
SKGTRACEINFUNC(10)
int nbCols = -1;
if (!ioTable.isEmpty()) {
nbCols = ioTable.at(0).count();
}
// Create a list of sums lines associated to the index where to add them
QMap<double, QStringList> sums;
for (int i = 1; i < nbCols; ++i) {
QStringList previousHeaderSum;
QList<double> sum;
QList<int> nbElem;
for (int j = 1; j < iNblines; ++j) {
double indextoadd = j + 1 - 0.01;
QStringList currentHeaderSum = getSumItems(ioTable.at(j).at(0));
if (previousHeaderSum.isEmpty()) {
previousHeaderSum = currentHeaderSum;
}
int nb = qMax(currentHeaderSum.count(), previousHeaderSum.count());
for (int k = 0; k < nb; ++k) {
QString chString = currentHeaderSum.value(k);
QString phString = previousHeaderSum.value(k);
if (chString != phString) {
// Add this sum
if (nbElem.value(k) > 1) {
QStringList thisSum;
if (i == 1) {
thisSum.push_back(phString);
} else {
thisSum = sums[indextoadd];
}
thisSum.push_back(SKGServices::doubleToString(sum.value(k)));
sums[indextoadd] = thisSum;
indextoadd -= 0.01;
}
// Reset sum
if (k < sum.count()) {
sum[k] = 0;
} else {
sum.push_back(0);
}
if (k < nbElem.count()) {
nbElem[k] = 0;
} else {
nbElem.push_back(0);
}
}
if (j < iNblines - 1) {
sum = sum.mid(0, previousHeaderSum.count());
nbElem = nbElem.mid(0, previousHeaderSum.count());
QString valstring = ioTable.at(j).at(i);
double v = 0.0;
if (!valstring.isEmpty()) {
v = SKGServices::stringToDouble(valstring);
}
if (k < sum.count()) {
sum[k] += v;
} else {
sum.push_back(v);
}
if (k < nbElem.count()) {
nbElem[k] = nbElem[k] + 1;
} else {
nbElem.push_back(1);
}
}
}
previousHeaderSum = currentHeaderSum;
}
}
// Add all sums in table
QList<double> keys = sums.keys();
std::sort(keys.begin(), keys.end());
int nbkey = keys.count();
for (int i = nbkey - 1; i >= 0; --i) {
double key = keys.at(i);
ioTable.insert(key, sums[key]);
m_sumRows.insert(key, true);
++iNblines;
}
}
void SKGTableWithGraph::refresh()
{
SKGTRACEINFUNC(10)
QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
// Set parameters for static method
QHeaderView* horizontalHeader = ui.kTable->horizontalHeader();
m_sortOrder = horizontalHeader->sortIndicatorOrder();
m_sortColumn = horizontalHeader->sortIndicatorSection();
SKGStringListList groupedTable = m_data;
int nbCols = -1;
if (!groupedTable.isEmpty()) {
nbCols = groupedTable.at(0).count();
}
int nbRealCols = nbCols;
// Create filtered table
{
// Build list of criterias
SKGServices::SKGSearchCriteriaList criterias = SKGServices::stringToSearchCriterias(ui.kFilterEdit->text());
// Check all lines
int nblists = criterias.count();
if ((nblists != 0) && (nbCols != 0)) {
for (int i = groupedTable.count() - 1; i >= 1; --i) { // The first line is not filtered because it is the title
QStringList line = groupedTable.at(i);
// Get title of the line
const QString& val = line.at(0);
// Filtered
bool ok = false;
for (int l = 0; l < nblists; ++l) {
QStringList words = criterias[l].words;
QChar mode = criterias[l].mode;
int nbwords = words.count();
bool validateAllWords = true;
for (int w = 0; validateAllWords && w < nbwords; ++w) {
validateAllWords = val.contains(words.at(w), Qt::CaseInsensitive);
}
if (mode == '+') {
ok |= validateAllWords;
} else if (mode == '-' && validateAllWords) {
ok = false;
}
}
if (!ok) {
groupedTable.removeAt(i);
}
}
}
}
// Initialise sumRows
int nblines = groupedTable.count();
m_sumRows.clear();
for (int j = 0; j < nblines; ++j) {
m_sumRows.push_back(false);
}
// Compute sums line
if ((m_additionalInformation & SUM) != 0u) {
QStringList sums;
sums.reserve(nbCols + 1);
sums.push_back(QString());
for (int i = 1; i < nbCols; ++i) {
double sum = 0;
for (int j = 1; j < nblines; ++j) {
QString valstring = groupedTable.at(j).at(i);
if (!valstring.isEmpty()) {
sum += SKGServices::stringToDouble(valstring);
}
}
sums.push_back(SKGServices::doubleToString(sum));
}
groupedTable.push_back(sums);
m_sumRows.push_back(true);
++nblines;
}
// Compute sub sums lines
if ((m_additionalInformation & SUM) != 0u && m_sortColumn == 0 && m_sortOrder == Qt::AscendingOrder) {
addSums(groupedTable, nblines);
}
// Compute sum and average column
m_indexSum = -1;
m_indexAverage = -1;
m_indexMin = -1;
m_indexLinearRegression = -1;
if (nbCols > 2 && ((m_additionalInformation & SUM) != 0u || (m_averageVisible && (m_additionalInformation & AVERAGE) != 0u) || (m_limitVisible && (m_additionalInformation & LIMITS) != 0u))) {
SKGTRACEINFUNC(10)
// Add title
QStringList newLine = groupedTable.at(0);
if ((m_additionalInformation & SUM) != 0u) {
m_indexSum = newLine.count();
newLine.push_back(i18nc("Noun, the numerical sum of a list of values", "Sum"));
}
if (m_averageVisible && (m_additionalInformation & AVERAGE) != 0u) {
m_indexAverage = newLine.count();
newLine.push_back(i18nc("Noun, the numerical average of a list of values", "Average"));
}
if (m_limitVisible && (m_additionalInformation & LIMITS) != 0u) {
m_indexMin = newLine.count();
newLine.push_back(i18nc("Noun, the minimum value of a list of values", "Min"));
newLine.push_back(i18nc("Noun, the maximum value of a list of values", "Max"));
}
if (m_linearRegressionVisible) {
m_indexLinearRegression = newLine.count();
newLine.push_back(i18nc("Noun", "Tendency line"));
}
groupedTable.replace(0, newLine);
for (int i = 1; i < nblines; ++i) {
QStringList newLine2 = groupedTable.at(i);
double sumy = 0;
double sumx = 0;
double sumx2 = 0;
double sumxy = 0;
double min = 10e20;
double max = -10e20;
int nbVals = 0;
for (int j = 1; j < nbCols - m_nbVirtualColumns; ++j) {
const QString& valstring = newLine2.at(j);
if (!valstring.isEmpty()) {
double v = SKGServices::stringToDouble(valstring);
sumx += j;
sumx2 += j * j;
sumy += v;
sumxy += j * v;
min = qMin(min, v);
max = qMax(max, v);
++nbVals;
}
}
if ((m_additionalInformation & SUM) != 0u) {
newLine2.push_back(SKGServices::doubleToString(sumy));
}
if (m_averageVisible && (m_additionalInformation & AVERAGE) != 0u) {
if (nbVals != 0) {
newLine2.push_back(SKGServices::doubleToString(sumy / nbVals));
} else {
newLine2.push_back(QStringLiteral("0"));
}
}
if (m_limitVisible && (m_additionalInformation & LIMITS) != 0u) {
if (nbVals != 0) {
newLine2.push_back(SKGServices::doubleToString(min));
newLine2.push_back(SKGServices::doubleToString(max));
} else {
newLine2.push_back(QStringLiteral("0"));
newLine2.push_back(QStringLiteral("0"));
}
}
if (nbVals != 0) {
double s2x = sumx2 / nbVals - sumx * sumx / (nbVals * nbVals);
double sxy = sumxy / nbVals - (sumx / nbVals) * (sumy / nbVals);
double a = (s2x != 0.0 ? sxy / s2x : 0.0);
double b = sumy / nbVals - a * sumx / nbVals;
newLine2.push_back("y=" % SKGServices::doubleToString(a) % "*x+" % SKGServices::doubleToString(b));
} else {
newLine2.push_back(QStringLiteral("y=0"));
}
groupedTable.replace(i, newLine2);
}
if (m_linearRegressionVisible) {
++nbCols;
}
if ((m_additionalInformation & SUM) != 0u) {
++nbCols;
}
if (m_averageVisible && (m_additionalInformation & AVERAGE) != 0u) {
++nbCols;
}
if (m_limitVisible && (m_additionalInformation & LIMITS) != 0u) {
nbCols += 2;
}
}
// Sort lines
if (m_sortColumn != 0 || m_sortOrder != Qt::AscendingOrder) {
SKGTRACEINFUNC(10)
// Extract title and sums
if (!groupedTable.isEmpty()) {
QStringList fist = groupedTable.takeFirst();
QStringList last;
if ((m_additionalInformation & SUM) != 0u && !groupedTable.isEmpty()) {
last = groupedTable.takeLast();
}
// Sort
QCollator comp;
comp.setCaseSensitivity(Qt::CaseInsensitive);
std::sort(groupedTable.begin(), groupedTable.end(), [&](const QStringList & s1, const QStringList & s2) {
if (m_sortColumn >= s1.count()) {
m_sortColumn = s1.count() - 1;
}
if (m_sortColumn >= 0) {
const QString& v1 = s1.at(m_sortColumn);
const QString& v2 = s2.at(m_sortColumn);
if (m_sortColumn == 0) {
int v = comp.compare(v1, v2);
return (m_sortOrder != 0u ? v > 0 : v < 0);
}
double vd1 = SKGServices::stringToDouble(v1);
double vd2 = SKGServices::stringToDouble(v2);
return (m_sortOrder != 0u ? vd1 > vd2 : vd1 < vd2);
}
return false;
});
// Add title and sums
groupedTable.insert(0, fist);
if ((m_additionalInformation & SUM) != 0u) {
groupedTable.push_back(last);
}
}
}
IFSKGTRACEL(10) {
QStringList dump = SKGServices::tableToDump(groupedTable, SKGServices::DUMP_TEXT);
int nbl = dump.count();
for (int i = 0; i < nbl; ++i) {
SKGTRACE << dump.at(i) << endl;
}
}
// Fill table
{
SKGTRACEINFUNC(10)
int nbRealColumns = nbRealCols - m_nbVirtualColumns;
ui.kTable->hide();
QHeaderView* hHeader = ui.kTable->horizontalHeader();
if (hHeader != nullptr) {
hHeader->setSectionResizeMode(QHeaderView::Fixed); // Needed to improve performances of setHorizontalHeaderLabels
}
ui.kTable->clear();
ui.kTable->setRowCount(nblines - 1);
ui.kTable->setColumnCount(nbCols);
for (int i = 0; i < nblines; ++i) {
const QStringList& line = groupedTable.at(i);
if (i == 0) {
SKGTRACEINFUNC(10)
// Set header
ui.kTable->setHorizontalHeaderLabels(line);
} else {
for (int j = 0; j < nbCols; ++j) {
const QString& val = line.at(j);
QTableWidgetItem* item;
if (j == 0) {
// Create the line header
if (m_sumRows.at(i)) {
item = new QTableWidgetItem(val.isEmpty() ?
i18nc("Noun, the numerical sum of a list of values", "Sum")
: i18nc("Noun, the numerical sum of a list of values", "Sum of '%1'", val));
item->setData(1, val);
QFont f = item->font();
f.setBold(true);
item->setFont(f);
if (m_indexLinearRegression != -1) {
item->setData(DATA_VALUE, line.at(m_indexLinearRegression));
}
ui.kTable->setItem(i - 1, j, item);
// Set header
ui.kTable->setVerticalHeaderItem(i - 1, new QTableWidgetItem(*item));
} else {
// New color selector
QColor defaultColor;
int color_h = (240 + 360 * (i - 1) / nblines) % 360; // First color is blue to be compliant with min (red) and max (green)
defaultColor = QColor::fromHsv(color_h, 255, 255);
QColor color;
if (m_mapTitleColor.contains(val)) {
color = m_mapTitleColor[val];
} else {
color = defaultColor;
m_mapTitleColor[val] = color;
}
auto colorSelector = new SKGColorButton(this);
colorSelector->setText(val);
colorSelector->setToolTip(val);
colorSelector->setColor(color);
colorSelector->setDefaultColor(defaultColor);
connect(colorSelector, &SKGColorButton::changed, this, &SKGTableWithGraph::onChangeColor);
ui.kTable->setCellWidget(i - 1, 0, colorSelector);
// Set header
auto itemTmp = new QTableWidgetItem(val);
itemTmp->setBackground(color);
itemTmp->setToolTip(val);
ui.kTable->setVerticalHeaderItem(i - 1, itemTmp);
}
} else {
// Add a value
QString tooltip = line.at(0) % '\n' % groupedTable.at(0).at(j);
if (!val.isEmpty()) {
if (j == m_indexLinearRegression) {
// A linear regression value
item = new QTableWidgetItem(val);
} else {
// A single value
double vald = SKGServices::stringToDouble(val);
QString vals = SKGServices::toCurrencyString(vald, m_primaryUnit.Symbol, m_decimalsVisible ? m_primaryUnit.NbDecimal : 0);
tooltip += '\n' % vals;
item = new QTableWidgetItem(vals);
item->setToolTip(tooltip);
if (!m_secondaryUnit.Symbol.isEmpty() && (m_secondaryUnit.Value != 0.0)) {
item->setToolTip(tooltip % '\n' % SKGServices::toCurrencyString(vald / m_secondaryUnit.Value, m_secondaryUnit.Symbol, m_decimalsVisible ? m_secondaryUnit.NbDecimal : 0));
}
item->setData(DATA_VALUE, vald);
item->setTextAlignment(Qt::AlignRight);
if (vald < 0) {
item->setForeground(m_NegativeColor);
}
if (m_sumRows.at(i)) {
QFont f = item->font();
f.setBold(true);
item->setFont(f);
}
}
} else {
// An empty value
item = new QTableWidgetItem(QString());
item->setToolTip(tooltip);
item->setData(DATA_VALUE, "");
}
item->setFlags((j >= nbRealColumns && j != m_indexSum) || ui.kTable->horizontalHeaderItem(j)->text() == QStringLiteral("0000") ? Qt::NoItemFlags : Qt::ItemIsEnabled | Qt::ItemIsSelectable);
ui.kTable->setItem(i - 1, j, item);
}
}
}
}
// Refresh graphic view
redrawGraph();
// Refresh text area
redrawText();
if (hHeader != nullptr) {
hHeader->setSectionResizeMode(QHeaderView::ResizeToContents);
}
if (m_tableVisible) {
ui.kTable->show();
}
if ((hHeader != nullptr) && (hHeader->count() != 0)) {
hHeader->resizeSection(0, 100);
hHeader->setSectionResizeMode(0, QHeaderView::Interactive);
}
}
QApplication::restoreOverrideCursor();
}
void SKGTableWithGraph::onChangeColor()
{
auto* colorButton = qobject_cast<SKGColorButton*>(sender());
if (colorButton != nullptr) {
m_mapTitleColor[colorButton->text()] = colorButton->color();
refresh();
}
}
void SKGTableWithGraph::resetColors()
{
m_mapTitleColor.clear();
refresh();
}
void SKGTableWithGraph::onSelectionChanged()
{
_SKGTRACEINFUNC(10)
if (m_graphVisible) {
// Unset color on previous selection
int nbRow = ui.kTable->rowCount();
int nbCol = ui.kTable->columnCount();
for (int r = 0; r < nbRow; ++r) {
for (int c = 0; c < nbCol; ++c) {
QTableWidgetItem* previous = ui.kTable->item(r, c);
if (previous != nullptr) {
QGraphicsItem* val = m_mapItemGraphic.value(previous);
if (val != nullptr) {
auto* graphicItem = qgraphicsitem_cast<QAbstractGraphicsShapeItem*>(val);
if (graphicItem != nullptr) {
QColor color = QColor::fromHsv(graphicItem->data(DATA_COLOR_H).toInt(),
graphicItem->data(DATA_COLOR_S).toInt(),
graphicItem->data(DATA_COLOR_V).toInt());
color.setAlpha(ALPHA);
if (graphicItem->data(DATA_MODE).toInt() == 1) {
QPen pen = graphicItem->pen();
pen.setColor(color);
graphicItem->setPen(pen);
} else {
graphicItem->setBrush(QBrush(color));
}
graphicItem->setZValue(graphicItem->data(DATA_Z_VALUE).toReal());
if (graphicItem->isSelected()) {
graphicItem->setSelected(false);
}
}
}
}
}
}
// Set highlight color on current selection
QList<QTableWidgetItem*> selected = ui.kTable->selectedItems();
int nb = selected.count();
for (int i = 0; i < nb; ++i) {
QTableWidgetItem* current = selected.at(i);
if (current != nullptr) {
QGraphicsItem* val = m_mapItemGraphic.value(current);
auto* graphicItem = qgraphicsitem_cast<QAbstractGraphicsShapeItem*>(val);
if (graphicItem != nullptr) {
if (graphicItem->data(DATA_MODE).toInt() == 1) {
QPen pen = graphicItem->pen();
pen.setColor(QApplication::palette().color(QPalette::Highlight));
graphicItem->setPen(pen);
} else {
graphicItem->setBrush(QBrush(QApplication::palette().color(QPalette::Highlight)));
}
graphicItem->setZValue(15);
graphicItem->setSelected(true);
graphicItem->ensureVisible();
}
}
}
}
emit selectionChanged();
}
void SKGTableWithGraph::onDoubleClickGraph()
{
if (m_scene != nullptr) {
// Get selection
QList<QGraphicsItem*> selectedGraphItems = m_scene->selectedItems();
if (!selectedGraphItems.isEmpty()) {
Q_EMIT cellDoubleClicked(selectedGraphItems[0]->data(1).toInt(), selectedGraphItems[0]->data(2).toInt());
}
}
}
void SKGTableWithGraph::onDoubleClick(int row, int column)
{
Q_EMIT cellDoubleClicked(row, column);
}
void SKGTableWithGraph::onLinkClicked(const QUrl& url)
{
QString path = url.toString().remove(QStringLiteral("http://linkclicked/"));
QStringList items = SKGServices::splitCSVLine(path, ',');
if (items.count() == 2) {
Q_EMIT cellDoubleClicked(SKGServices::stringToInt(items[0]), SKGServices::stringToInt(items[1]));
}
}
void SKGTableWithGraph::onSelectionChangedInGraph()
{
_SKGTRACEINFUNC(10)
if (m_scene != nullptr) {
bool previous = ui.kTable->blockSignals(true);
ui.kTable->clearSelection();
// Get selection
QList<QGraphicsItem*> selectedGraphItems = m_scene->selectedItems();
int nb = selectedGraphItems.count();
for (int i = 0; i < nb; ++i) {
ui.kTable->setCurrentCell(selectedGraphItems.at(i)->data(1).toInt(), selectedGraphItems.at(i)->data(2).toInt(), QItemSelectionModel::Select);
}
ui.kTable->blockSignals(previous);
previous = m_scene->blockSignals(true);
onSelectionChanged();
m_scene->blockSignals(previous);
}
}
void SKGTableWithGraph::redrawGraphDelayed()
{
m_timerRedraw.start(300);
}
void SKGTableWithGraph::redrawText()
{
if (!m_textVisible) {
return;
}
SKGTRACEINFUNC(10)
QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
QString html = QStringLiteral("<? xml version = \"1.0\" encoding=\"utf-8\"?>"
- "<!DOCTYPE html PUBLIC \"-// W3C// DTD XHTML 1.0 Strict// EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">"
- "<html xmlns=\"http://www.w3.org/1999/xhtml\">"
+ "<!DOCTYPE html PUBLIC \"-// W3C// DTD XHTML 1.0 Strict// EN\" \"https://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">"
+ "<html xmlns=\"https://www.w3.org/1999/xhtml\">"
"<head>"
"<meta http-equiv=\"content-type\" content=\"text/html;charset=utf-8\" />"
"<meta http-equiv=\"Content-Style-Type\" content=\"text/css\" />"
"<style type=\"text/css\">"
"body{background-color: #FFFFFF; font-size : small; display: inline;} a{color: inherit; text-decoration: inherit;} h1{text-decoration: underline; color: #FF3333;} h2{text-decoration: underline; color: #FF9933;} .table{border: thin solid #000000; border-collapse: collapse; background-color: #000000;} .tabletitle{background-color: #6495ed; color : #FFFF33; font-weight : bold; font-size : normal} .tabletotal{background-color: #D0E3FA;font-weight : bold;} tr{background-color: #FFFFFF;padding: 2px;} td{padding: 2px; white-space: nowrap;}"
"</style>"
"</head>"
"<body>"
"<table class=\"table\"><tr class=\"tabletitle\">");
// Dump header
int nbCols = ui.kTable->columnCount();
for (int i = 0; i < nbCols; ++i) {
QTableWidgetItem* item = ui.kTable->horizontalHeaderItem(i);
if (item != nullptr) {
html += R"(<td align="center" width="1000"><b>)" % item->text() % "</b></td>";
}
}
html += QStringLiteral("</tr>");
// Dump values
int nbLines = ui.kTable->rowCount();
for (int j = 0; j < nbLines; ++j) {
html += QStringLiteral("<tr") % (m_sumRows.at(j + 1) ? " class=\"tabletotal\"" : "") % '>';
for (int i = 0; i < nbCols; ++i) {
QTableWidgetItem* item = ui.kTable->item(j, i);
if (item != nullptr) {
bool red = (item->data(DATA_VALUE).toDouble() < 0);
html += QStringLiteral("<td align=\"right\">") % (red ? "<font color=\"red\">" : "");
if ((item->flags()&Qt::ItemIsSelectable) != 0u) {
html += "<a href=\"http://linkclicked/" % SKGServices::intToString(j) % "," % SKGServices::intToString(i) % "\">";
}
html += item->text();
if ((item->flags()&Qt::ItemIsSelectable) != 0u) {
html += QStringLiteral("</a>");
}
html += QString(red ? QStringLiteral("</font>") : QString()) % "</td>";
} else {
auto* colorButton = qobject_cast<SKGColorButton*>(ui.kTable->cellWidget(j, i));
if (colorButton != nullptr) {
html += "<td><b>" % colorButton->text() % "</b></td>";
}
}
}
html += QStringLiteral("</tr>");
}
html += QStringLiteral("</table>");
html += QStringLiteral("</body></html>");
ui.kTextEdit->setHtml(html);
QApplication::restoreOverrideCursor();
}
void SKGTableWithGraph::redrawGraph()
{
SKGTRACEINFUNC(10)
m_mapItemGraphic.clear();
if (!m_graphVisible) {
return;
}
QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
ui.graphicView->hide();
ui.kTable->hide();
// Recreate scene
if (m_scene != nullptr) {
SKGTRACEINFUNC(10)
m_scene->clear();
delete m_scene;
}
m_scene = new SKGGraphicsScene();
{
SKGTRACEINFUNC(10)
m_scene->setBackgroundBrush(m_backgroundColor);
// Get current selection
int crow = ui.kTable->currentRow();
int ccolumn = ui.kTable->currentColumn();
// Get nb columns and rows
int nbRows = ui.kTable->rowCount();
int nbRealRows = nbRows;
for (int posy = 0; posy < nbRows; ++posy) {
if (m_sumRows.at(posy + 1)) {
--nbRealRows;
}
}
int nbColumns = getNbColumns(false);
int nbRealColumns = nbColumns - m_nbVirtualColumns;
// Get graphic mode
GraphType mode = getGraphType();
// Get in positive
bool inPositive = false;
if (mode == STACK || mode == STACKCOLUMNS || mode == HISTOGRAM || mode == POINT || mode == LINE || mode == STACKAREA) {
m_allPositiveMenu->setEnabled(true);
inPositive = (m_allPositiveMenu->isChecked());
} else {
m_allPositiveMenu->setEnabled(false);
if (mode == CONCENTRICPIE || mode == PIE || mode == TREEMAP) {
inPositive = true;
}
}
// Get show origin
bool showOrigin = true;
if (mode == HISTOGRAM || mode == POINT || mode == LINE) {
m_actShowZero->setEnabled(true);
showOrigin = (m_actShowZero->isChecked());
} else {
m_actShowZero->setEnabled(false);
}
// Compute y limits
double minLimit = (showOrigin ? 0 : 9999999);
double maxLimit = (showOrigin ? 0 : -9999999);
int nbLevel = 0;
SKGTRACEL(3) << "mode=" << static_cast<unsigned int>(mode) << endl;
SKGTRACEL(3) << "nb rows =" << nbRows << endl;
SKGTRACEL(3) << "nb real rows =" << nbRealRows << endl;
SKGTRACEL(3) << "nb columns =" << nbColumns << endl;
SKGTRACEL(3) << "nb real columns=" << nbRealColumns << endl;
SKGTRACEL(3) << "selected row =" << crow << endl;
SKGTRACEL(3) << "selected column=" << ccolumn << endl;
if (mode == STACK) {
// STACK
for (int posx = 0; posx < nbRows; ++posx) {
if (!m_sumRows[posx + 1]) {
double sumPositive = 0;
double sumNegative = 0;
for (int posy = 0; posy < nbColumns; ++posy) {
QTableWidgetItem* tableItem = ui.kTable->item(posx, posy);
if (tableItem != nullptr) {
QVariant valQ = tableItem->data(DATA_VALUE);
if (valQ.type() == QVariant::Double) {
double val = valQ.toDouble();
if (inPositive || val >= 0) {
sumPositive += qAbs(val);
} else {
sumNegative += val;
}
}
}
}
minLimit = qMin(minLimit, sumNegative);
maxLimit = qMax(maxLimit, sumPositive);
}
}
} else if (mode == STACKAREA || mode == STACKCOLUMNS || mode == PIE || mode == CONCENTRICPIE || mode == TREEMAP) {
// STACKAREA or STACKCOLUMNS or PIE or CONCENTRICPIE
for (int posy = 0; posy < nbColumns; ++posy) {
double sumPositive = 0;
double sumNegative = 0;
for (int posx = 0; posx < nbRows; ++posx) {
if (!m_sumRows[posx + 1]) {
QTableWidgetItem* tableItem = ui.kTable->item(posx, posy);
if (tableItem != nullptr) {
QVariant valQ = tableItem->data(DATA_VALUE);
if (valQ.type() == QVariant::Double) {
double val = valQ.toDouble();
if (inPositive || val >= 0) {
sumPositive += qAbs(val);
} else {
sumNegative += val;
}
}
}
}
}
if (mode == TREEMAP) {
// TREEMAP
minLimit = 0;
maxLimit = qAbs(sumNegative) + sumPositive;
} else {
minLimit = qMin(minLimit, sumNegative);
maxLimit = qMax(maxLimit, sumPositive);
}
}
} else if (mode == HISTOGRAM || mode == POINT || mode == LINE) {
// HISTOGRAM or POINTS or LINES
for (int posx = 0; posx < nbRows; ++posx) {
if (!m_sumRows[posx + 1]) {
for (int posy = 0; posy < nbColumns; ++posy) {
QTableWidgetItem* tableItem = ui.kTable->item(posx, posy);
if (tableItem != nullptr) {
QVariant valQ = tableItem->data(DATA_VALUE);
if (valQ.type() == QVariant::Double) {
double val = valQ.toDouble();
if (inPositive) {
maxLimit = qMax(maxLimit, qAbs(val));
minLimit = qMin(minLimit, qAbs(val));
} else {
minLimit = qMin(minLimit, val);
maxLimit = qMax(maxLimit, val);
}
}
}
}
}
}
} else if (mode == BUBBLE) {
for (int posx = 0; posx < nbRows; ++posx) {
if (!m_sumRows[posx + 1]) {
for (int posy = 0; posy < nbColumns; ++posy) {
QTableWidgetItem* tableItem = ui.kTable->item(posx, posy);
if (tableItem != nullptr) {
QVariant valQ = tableItem->data(DATA_VALUE);
if (valQ.type() == QVariant::Double) {
double val = valQ.toDouble();
maxLimit = qMax(maxLimit, qAbs(val));
}
}
}
}
}
}
if (mode == CONCENTRICPIE) {
for (int posx = 0; posx < nbRows; ++posx) {
auto* btn = qobject_cast<SKGColorButton*>(ui.kTable->cellWidget(posx, 0));
if (btn != nullptr) {
QString xname = btn->text();
QStringList vals = xname.split(OBJECTSEPARATOR);
int nbvals = vals.count();
nbLevel = qMax(nbLevel, nbvals - 1);
}
}
}
// Compute
double yorigin = 0.0;
double widthItem = 10;
double maxX = 0;
double margin = 0;
double marginLeft = 0;
double xstep = 0.0;
double radius = 0.0;
int jstep = qMax(computeStepSize(nbColumns, 10), static_cast<double>(1.0));
double ystep = computeStepSize(maxLimit - minLimit, 10);
if (mode != BUBBLE && mode != PIE && mode != CONCENTRICPIE && mode != TREEMAP && ystep != 0) {
double newMinLimit = ystep * qRound(minLimit / ystep);
minLimit = (minLimit - newMinLimit < -EPSILON ? newMinLimit - ystep : newMinLimit);
double newMaxLimit = ystep * qRound(maxLimit / ystep);
maxLimit = (maxLimit - newMaxLimit > EPSILON ? newMaxLimit + ystep : newMaxLimit);
}
if ((nbRealRows != 0) && ystep != 0) {
QRect vSize = ui.graphicView->rect();
if (mode == STACK) {
margin = (maxLimit - minLimit) * 0.3;
if (!showOrigin) {
if (minLimit > 0) {
yorigin = ystep * (qRound(minLimit / ystep));
} else if (maxLimit < 0) {
yorigin = ystep * (qRound(maxLimit / ystep));
}
}
widthItem = (maxLimit - minLimit) / (nbRealRows + 1);
widthItem = widthItem * (static_cast<double>(vSize.width())) / (static_cast<double>(vSize.height()));
xstep = widthItem * (nbRealRows + 1);
marginLeft = widthItem;
maxX = widthItem * nbRealRows + margin;
} else if (mode == HISTOGRAM || mode == POINT || mode == LINE || mode == STACKAREA || mode == STACKCOLUMNS) {
margin = (maxLimit - minLimit) * 0.3;
if (!showOrigin) {
if (minLimit > 0) {
yorigin = ystep * (qRound(minLimit / ystep));
} else if (maxLimit < 0) {
yorigin = ystep * (qRound(maxLimit / ystep));
}
}
widthItem = (maxLimit - minLimit) / ((nbRealRows + 1) * (nbColumns - 1));
widthItem = widthItem * (static_cast<double>(vSize.width())) / (static_cast<double>(vSize.height()));
xstep = widthItem * (nbRealRows + 1);
marginLeft = qMin(jstep * xstep, widthItem * (nbColumns - 1));
maxX = xstep * (nbColumns - 1);
if (mode == POINT || mode == LINE || mode == STACKAREA) {
maxX -= xstep;
}
// radius = qMax(margin / 100.0, qMin(width, qMin(ystep / 4, jstep * xstep / 4)));
radius = qMax(margin / 200, qMin(widthItem, qMin(ystep / 8, jstep * xstep / 8)));
} else if (mode == BUBBLE) {
margin = ystep * nbRealRows * 0.3;
widthItem = ystep * nbRealRows / (nbRealRows * (nbColumns - 1));
widthItem = widthItem * (static_cast<double>(vSize.width())) / (static_cast<double>(vSize.height()));
xstep = widthItem * (nbRealRows + 1);
marginLeft = jstep * xstep;
maxX = widthItem * (nbColumns - 1) * (nbRealRows + 1);
}
}
SKGTRACEL(3) << "minLimit=" << minLimit << endl;
SKGTRACEL(3) << "maxLimit=" << maxLimit << endl;
SKGTRACEL(3) << "ystep=" << ystep << endl;
SKGTRACEL(3) << "yorigin=" << yorigin << endl;
SKGTRACEL(3) << "width=" << widthItem << endl;
SKGTRACEL(3) << "maxX=" << maxX << endl;
SKGTRACEL(3) << "margin=" << margin << endl;
SKGTRACEL(3) << "xstep=" << xstep << endl;
SKGTRACEL(3) << "marginLeft=" << marginLeft << endl;
// Initialise pens
QPen axisPen = QPen(Qt::SolidLine);
axisPen.setColor(m_axisColor);
axisPen.setWidthF(margin / 30.0);
axisPen.setJoinStyle(Qt::RoundJoin);
QPen gridPen = QPen(Qt::SolidLine);
gridPen.setColor(m_gridColor);
gridPen.setWidthF(margin / 100.0);
QPen dotPen = QPen(Qt::SolidLine); // WARNING: Qt::DotLine is very bad for performances
dotPen.setWidthF(margin / 50.0);
QPen outlinePen(m_outlineColor);
outlinePen.setWidthF(margin / 500.0);
// Set rect
int nbColInMode2 = (nbColumns > 2 ? sqrt(nbColumns - 1) + .5 : 1);
m_scene->setItemIndexMethod(QGraphicsScene::NoIndex);
SKGTRACEL(10) << "Items:" << nbRealRows << "x" << (nbColumns - 1) << "=" << nbRealRows*(nbColumns - 1) << endl;
SKGTRACEL(10) << "nbColInMode2=" << nbColInMode2 << endl;
// Compute treemap
QMap<QString, SKGTreeMap> treemap;
if (mode == TREEMAP) {
SKGTreeMap treemapobj(QString(), 0, 0, 0, BOX_SIZE, BOX_SIZE);
for (int j = 1; j < nbColumns; ++j) {
SKGTreeMap treemapobj2;
for (int xx = 0; xx < nbRows; ++xx) {
auto* colorButton = qobject_cast<SKGColorButton*>(ui.kTable->cellWidget(xx, 0));
if (colorButton != nullptr) {
// Get cell value
QTableWidgetItem* tableItem = ui.kTable->item(xx, j);
if (tableItem != nullptr) {
QVariant valQ = tableItem->data(DATA_VALUE);
if (valQ.type() == QVariant::Double) {
double val = qAbs(valQ.toDouble());
QString id = SKGServices::intToString(xx) % QStringLiteral("-") % SKGServices::intToString(j);
treemapobj2.addChild(SKGTreeMap(id, val));
}
}
}
}
treemapobj.addChild(treemapobj2);
}
treemapobj.compute();
treemap = treemapobj.getAllTilesById();
}
// Redraw scene
double x0 = 0;
double x1 = 0;
double ymin = (showOrigin || mode == STACK || mode == STACKCOLUMNS ? 0 : 9999999);
double ymax = (showOrigin || mode == STACK || mode == STACKCOLUMNS ? 0 : -9999999);
int posx = 0;
int nbRowsDrawed = 0;
QMap<int, double> previousStackedPlus;
QMap<int, double> previousStackedMoins;
QMap<double, double> paretoPoints;
for (int xx = 0; xx < nbRows; ++xx) {
auto* colorButton = qobject_cast<SKGColorButton*>(ui.kTable->cellWidget(xx, 0));
if (colorButton != nullptr) {
QString xname = colorButton->text();
QColor initialColor = colorButton->color();
double yPlus = 0;
double yMoins = 0;
int jprevious = -1;
++nbRowsDrawed;
for (int j = 1; j < nbColumns; ++j) {
// Get cell value
QTableWidgetItem* tableItem = ui.kTable->item(xx, j);
if (tableItem != nullptr) {
QVariant valQ = tableItem->data(DATA_VALUE);
if (valQ.type() == QVariant::Double) {
double val = valQ.toDouble();
QString valstring = tableItem->text();
if (inPositive) {
val = qAbs(val);
}
int color_h;
int color_s;
int color_v;
initialColor.getHsv(&color_h, &color_s, &color_v);
color_s = color_s - color_s * 155 / 255 * (nbColumns - 1 - j) / nbColumns;
color_v = color_v - color_v * 155 / 255 * (nbColumns - 1 - j) / nbColumns;
if (j >= nbRealColumns) {
// Yellow
color_h = 60;
color_s = 255;
color_v = 255;
}
QColor color;
if (posx == crow && j == ccolumn) {
color = QApplication::palette().color(QPalette::Highlight);
} else {
color = QColor::fromHsv(color_h, color_s, color_v);
}
color.setAlpha(ALPHA);
QBrush brush(color);
QGraphicsItem* graphItem = nullptr;
if (mode == STACK) {
// STACK
if (val >= 0) {
graphItem = m_scene->addRect(widthItem * posx, -yPlus - qAbs(val), widthItem, qAbs(val), outlinePen, brush);
yPlus += qAbs(val);
if (yPlus > ymax) {
ymax = yPlus;
}
} else {
graphItem = m_scene->addRect(widthItem * posx, -yMoins, widthItem, -val, outlinePen, brush);
yMoins += val;
if (yMoins < ymin) {
ymin = yMoins;
}
}
if (graphItem != nullptr) {
graphItem->setZValue(5 + nbColumns - j);
}
}
if (mode == STACKAREA) {
// STACKAREA
// Empty cells are ignored
if (j == 1) {
x0 = widthItem * (j - 1) * (nbRealRows + 1);
}
if (j == nbColumns - m_nbVirtualColumns - 1) {
x1 = widthItem * (j - 1) * (nbRealRows + 1);
}
if (!valstring.isEmpty()) {
if (jprevious == -1) {
jprevious = j;
}
QTableWidgetItem* tableItem2 = ui.kTable->item(xx, jprevious);
if (tableItem2 != nullptr) {
QString val2string = tableItem->text();
if (!val2string.isEmpty()) {
double val2 = tableItem2->data(DATA_VALUE).toDouble();
if (j == jprevious) {
val2 = 0;
}
if (inPositive) {
val2 = qAbs(val2);
}
if (val > EPSILON || (qAbs(val) <= EPSILON && val2 >= EPSILON)) {
double xp = widthItem * (jprevious - 1) * (nbRealRows + 1) - (jprevious == j ? widthItem / 20.0 : 0);
double xn = widthItem * (j - 1) * (nbRealRows + 1);
double yp = (previousStackedPlus.contains(jprevious) ? previousStackedPlus[jprevious] : -val2);
double yn = previousStackedPlus[j] - val;
QPolygonF polygon;
polygon << QPointF(xp, yp + val2) << QPointF(xp, yp)
<< QPointF(xn, yn) << QPointF(xn, previousStackedPlus[j]);
graphItem = m_scene->addPolygon(polygon, outlinePen, brush);
previousStackedPlus[j] = yn;
if (-yn > ymax) {
ymax = -yn;
}
} else {
double xp = widthItem * (jprevious - 1) * (nbRealRows + 1) - (jprevious == j ? widthItem / 20.0 : 0);
double xn = widthItem * (j - 1) * (nbRealRows + 1);
double yp = (previousStackedMoins.contains(jprevious) ? previousStackedMoins[jprevious] : -val2);
double yn = previousStackedMoins[j] - val;
QPolygonF polygon;
polygon << QPointF(xp, yp + val2) << QPointF(xp, yp)
<< QPointF(xn, yn) << QPointF(xn, previousStackedMoins[j]);
graphItem = m_scene->addPolygon(polygon, outlinePen, brush);
previousStackedMoins[j] = yn;
if (-yn < ymin) {
ymin = -yn;
}
}
jprevious = j;
}
}
}
}
if (mode == STACKCOLUMNS) {
// STACKCOLUMNS
if (val >= 0) {
graphItem = m_scene->addRect(widthItem * (j - 1) * (nbRealRows + 1), -previousStackedPlus[j] - qAbs(val), widthItem * (nbRealRows + 1), qAbs(val), outlinePen, brush);
previousStackedPlus[j] += qAbs(val);
if (previousStackedPlus[j] > ymax) {
ymax = previousStackedPlus[j];
}
} else {
graphItem = m_scene->addRect(widthItem * (j - 1) * (nbRealRows + 1), -previousStackedMoins[j], widthItem * (nbRealRows + 1), -val, outlinePen, brush);
previousStackedMoins[j] += val;
if (previousStackedMoins[j] < ymin) {
ymin = previousStackedMoins[j];
}
}
if (graphItem != nullptr) {
graphItem->setZValue(5 + nbRows - posx);
}
} else if (mode == HISTOGRAM) {
// HISTOGRAM
if (j == 1) {
x0 = widthItem * ((j - 1) * (nbRealRows + 1) + posx) + widthItem;
}
if (j == nbColumns - m_nbVirtualColumns - 1) {
x1 = widthItem * ((j - 1) * (nbRealRows + 1) + posx) + widthItem;
}
graphItem = m_scene->addRect(widthItem * ((j - 1) * (nbRealRows + 1) + posx) + widthItem / 2.0, (val < 0 ? -yorigin : -val), widthItem, (val < 0 ? yorigin - val : -yorigin + val), outlinePen, brush);
if (val > ymax) {
ymax = val;
}
if (val < ymin) {
ymin = val;
}
} else if (mode == POINT) {
// POINTS
double xmin = widthItem * (j - 1) * (nbRealRows + 1) - radius;
if (j == 1) {
x0 = xmin + radius;
}
if (j == nbColumns - m_nbVirtualColumns - 1) {
x1 = xmin + radius;
}
graphItem = drawPoint(xmin, -val, radius, posx, brush);
if (val > ymax) {
ymax = val;
}
if (val < ymin) {
ymin = val;
}
} else if (mode == LINE) {
// LINES
// Empty cells are ignored
if (j == 1) {
x0 = widthItem * (j - 1) * (nbRealRows + 1);
}
if (j == nbColumns - m_nbVirtualColumns - 1) {
x1 = widthItem * (j - 1) * (nbRealRows + 1);
}
if (!valstring.isEmpty()) {
if (jprevious == -1) {
jprevious = j;
}
// Create pen
color.setAlpha(255);
QPen pen = QPen(color);
pen.setWidthF(radius);
pen.setCapStyle(Qt::RoundCap);
pen.setJoinStyle(Qt::RoundJoin);
QTableWidgetItem* tableItem2 = ui.kTable->item(xx, jprevious);
if (tableItem2 != nullptr) {
QString val2string = tableItem->text();
if (!val2string.isEmpty()) {
double val2 = tableItem2->data(DATA_VALUE).toDouble();
if (inPositive) {
val2 = qAbs(val2);
}
QGraphicsLineItem* line = m_scene->addLine(widthItem * (jprevious - 1) * (nbRealRows + 1) - (jprevious == j ? widthItem / 20.0 : 0), -val2, widthItem * (j - 1) * (nbRealRows + 1), -val, pen);
line->setZValue(10);
if (isShadowVisible()) {
auto line_shadow = new QGraphicsDropShadowEffect();
line_shadow->setOffset(3);
line->setGraphicsEffect(line_shadow);
}
graphItem = drawPoint(widthItem * (j - 1) * (nbRealRows + 1) - radius * 0.7, -val, radius * 0.7, posx % 5, brush);
if (isShadowVisible()) {
auto line_shadow = new QGraphicsDropShadowEffect();
line_shadow->setOffset(3);
line->setGraphicsEffect(line_shadow);
}
graphItem->setZValue(20);
if (val > ymax) {
ymax = val;
}
if (val < ymin) {
ymin = val;
}
jprevious = j;
}
}
}
} else if (mode == BUBBLE) {
// BUBBLE
ymin = 0;
ymax = ystep * nbRealRows;
radius = sqrt(qAbs(val) / maxLimit) * qMin(ystep, jstep * xstep);
double xmin = widthItem * (j - 1) * (nbRealRows + 1) - radius;
graphItem = m_scene->addEllipse(xmin, -ystep * posx - radius, 2 * radius, 2 * radius, outlinePen, brush);
if (graphItem != nullptr) {
graphItem->setZValue(5 + 5 * (maxLimit - qAbs(val)) / maxLimit);
}
} else if (mode == PIE || mode == CONCENTRICPIE) {
// PIE
val = qAbs(val);
// Compute absolute sum of the column
double previousSum = 0;
for (int x2 = 0; x2 < nbRows; ++x2) {
if (!m_sumRows[x2 + 1]) {
QTableWidgetItem* tabItem = ui.kTable->item(x2, j);
if (tabItem != nullptr) {
double absVal = qAbs(tabItem->data(DATA_VALUE).toDouble());
if (x2 < xx) {
previousSum += absVal;
}
}
}
}
if (maxLimit != 0.0) {
int nbvals = xname.split(OBJECTSEPARATOR).count();
double step = 0;
double p = 0;
if (mode == CONCENTRICPIE) {
step = 100.0 / static_cast<double>(nbLevel + 1);
p = step * (nbLevel + 1 - nbvals);
}
QPainterPath path;
path.moveTo(BOX_SIZE * ((j - 1) % nbColInMode2) + BOX_SIZE / 2.0, BOX_SIZE * floor((j - 1) / nbColInMode2) + BOX_SIZE / 2.0);
path.arcTo(BOX_SIZE * ((j - 1) % nbColInMode2) + BOX_MARGIN + p / 2.0, BOX_SIZE * floor((j - 1) / nbColInMode2) + BOX_MARGIN + p / 2.0, BOX_SIZE - 2 * BOX_MARGIN - p, BOX_SIZE - 2 * BOX_MARGIN - p, 90.0 - 360.0 * previousSum / maxLimit, -360.0 * val / maxLimit);
path.closeSubpath();
if (mode == CONCENTRICPIE && nbvals <= nbLevel + 1 && nbvals > 1) {
p = step * (nbLevel + 1 - nbvals + 1);
QPainterPath path2;
path2.addEllipse(BOX_SIZE * ((j - 1) % nbColInMode2) + BOX_MARGIN + p / 2.0,
BOX_SIZE * floor((j - 1) / nbColInMode2) + BOX_MARGIN + p / 2.0,
BOX_SIZE - 2 * BOX_MARGIN - p,
BOX_SIZE - 2 * BOX_MARGIN - p);
path -= path2;
}
graphItem = m_scene->addPath(path, outlinePen, brush);
}
} else if (mode == TREEMAP) {
// TREEMAP
QString id = SKGServices::intToString(xx) % QStringLiteral("-") % SKGServices::intToString(j);
SKGTreeMap tm = treemap[id];
graphItem = m_scene->addRect(tm.getX(), tm.getY(), tm.getW(), tm.getH(), outlinePen, brush);
}
// Compute pareto points
if (mode == POINT || mode == LINE) {
paretoPoints[widthItem * (j - 1) * (nbRealRows + 1)] = val;
} else if (mode == HISTOGRAM) {
paretoPoints[widthItem * ((j - 1) * (nbRealRows + 1) + posx) + widthItem] = val;
}
if (graphItem != nullptr) {
if (graphItem->zValue() == 0) {
graphItem->setZValue(5);
}
graphItem->setToolTip(tableItem->toolTip());
bool isSelect = (isSelectable() && ((tableItem->flags() & Qt::ItemIsEnabled) != 0u));
graphItem->setFlag(QGraphicsItem::ItemIsSelectable, isSelect);
if (isSelect) {
graphItem->setCursor(Qt::PointingHandCursor);
}
graphItem->setData(1, xx);
graphItem->setData(2, j);
graphItem->setData(DATA_COLOR_H, color_h);
graphItem->setData(DATA_COLOR_S, color_s);
graphItem->setData(DATA_COLOR_V, color_v);
graphItem->setData(DATA_Z_VALUE, graphItem->zValue());
m_mapItemGraphic[tableItem] = graphItem;
}
}
} else {
SKGTRACE << "WARNING: cell " << posx << "," << j << " null" << endl;
}
}
++posx;
}
}
// Draw axis
double scaleText = 0.0;
auto nbRowInMode2 = static_cast<int>(((nbColumns - 1) / nbColInMode2));
if (nbRealRows != 0) {
if (mode == TREEMAP) {
// TREEMAP
} else if (mode == PIE || mode == CONCENTRICPIE) {
// PIE
if (nbRowInMode2 * nbColInMode2 < nbColumns - 1) {
++nbRowInMode2;
}
for (int i = 0; i <= nbColInMode2; ++i) {
QGraphicsLineItem* item = m_scene->addLine(BOX_SIZE * i, 0, BOX_SIZE * i, BOX_SIZE * nbRowInMode2);
item->setPen(axisPen);
item->setFlag(QGraphicsItem::ItemIsSelectable, false);
}
for (int i = 0; i <= nbRowInMode2; ++i) {
QGraphicsLineItem* item = m_scene->addLine(0, BOX_SIZE * i, BOX_SIZE * nbColInMode2, BOX_SIZE * i);
item->setPen(axisPen);
item->setFlag(QGraphicsItem::ItemIsSelectable, false);
}
for (int j = 1; j < nbColumns; ++j) {
// Get column name
QString yname = ui.kTable->horizontalHeaderItem(j)->text();
QGraphicsTextItem* textItem = m_scene->addText(yname);
textItem->setDefaultTextColor(m_textColor);
textItem->setPos(BOX_SIZE * ((j - 1) % nbColInMode2) + 2, BOX_SIZE * floor((j - 1) / nbColInMode2) + 2);
textItem->setScale(.5);
textItem->setFlag(QGraphicsItem::ItemIsSelectable, false);
textItem->setZValue(20);
}
} else {
// STACK & HISTOGRAMM
QGraphicsLineItem* item;
// Compute scale text
if (mode != BUBBLE) {
QGraphicsTextItem* t = m_scene->addText(SKGServices::toCurrencyString(-qMax(qAbs(ymax), qAbs(ymin)), m_primaryUnit.Symbol, m_decimalsVisible ? m_primaryUnit.NbDecimal : 0));
QRectF bRect = t->boundingRect();
scaleText = 0.8 * qMin(marginLeft / bRect.width(), qMin(marginLeft / bRect.height(), ystep / bRect.height()));
m_scene->removeItem(t);
} else {
maxLimit = ystep * nbRealRows;
}
if (ystep > 0) {
// Draw
int i = 1;
for (double posy = yorigin + ystep ; posy <= maxLimit ; posy = posy + ystep) {
item = m_scene->addLine(0, -posy, maxX, -posy);
item->setPen(gridPen);
item->setFlag(QGraphicsItem::ItemIsSelectable, false);
item->setZValue(1);
QGraphicsTextItem* textItem;
if (mode == BUBBLE) {
auto* cel = qobject_cast<SKGColorButton*>(ui.kTable->cellWidget(i, 0));
++i;
if (cel == nullptr) {
cel = qobject_cast<SKGColorButton*>(ui.kTable->cellWidget(i, 0));
++i;
}
textItem = m_scene->addText(cel != nullptr ? cel->text() : QString());
} else {
textItem = m_scene->addText(SKGServices::toCurrencyString(posy, m_primaryUnit.Symbol, m_decimalsVisible ? m_primaryUnit.NbDecimal : 0));
}
QRectF textRect = textItem->boundingRect();
if (scaleText == 0) {
scaleText = 0.8 * qMin(marginLeft / textRect.width(), qMin(marginLeft / textRect.height(), ystep / textRect.height()));
}
textItem->setDefaultTextColor(m_textColor);
textItem->setScale(scaleText);
textItem->setFlag(QGraphicsItem::ItemIsSelectable, false);
textItem->setZValue(20);
double delta = scaleText * textRect.height() / 2.0;
textItem->setPos(-marginLeft, -posy - delta);
}
i = 0;
for (double posy = yorigin ; (posy == yorigin) || posy >= minLimit; posy = posy - ystep) {
item = m_scene->addLine(0, -posy, maxX, -posy);
item->setPen(gridPen);
item->setFlag(QGraphicsItem::ItemIsSelectable, false);
item->setZValue(1);
QGraphicsTextItem* textItem;
if (mode == BUBBLE) {
auto* cel = qobject_cast<SKGColorButton*>(ui.kTable->cellWidget(i, 0));
textItem = m_scene->addText(cel != nullptr ? cel->text() : QString());
} else {
textItem = m_scene->addText(SKGServices::toCurrencyString(posy, m_primaryUnit.Symbol, m_decimalsVisible ? m_primaryUnit.NbDecimal : 0));
}
QRectF textRect = textItem->boundingRect();
if (scaleText == 0) {
scaleText = 0.8 * qMin(marginLeft / textRect.width(), qMin(marginLeft / textRect.height(), ystep / textRect.height()));
}
textItem->setDefaultTextColor(m_textColor);
textItem->setScale(scaleText);
textItem->setFlag(QGraphicsItem::ItemIsSelectable, false);
textItem->setZValue(20);
double delta = scaleText * textRect.height() / 2.0;
textItem->setPos(-marginLeft, -posy - delta);
}
}
if (mode == HISTOGRAM || mode == POINT || mode == LINE || mode == BUBBLE || mode == STACKAREA || mode == STACKCOLUMNS) {
// Line y
for (int j = 1; j < nbColumns; j += jstep) {
QString yname = ui.kTable->horizontalHeaderItem(j)->text();
double posx2 = xstep + (j - 2) * xstep;
QGraphicsTextItem* textItem = m_scene->addText(yname);
QRectF textRect = textItem->boundingRect();
if (scaleText == 0) {
scaleText = 0.8 * qMin(marginLeft / textRect.width(), qMin(marginLeft / textRect.height(), ystep / textRect.height()));
}
textItem->setDefaultTextColor(m_textColor);
textItem->setScale(scaleText);
textItem->setFlag(QGraphicsItem::ItemIsSelectable, false);
textItem->setZValue(20);
double delta = scaleText * textRect.height() / 2.0;
textItem->setRotation(90);
textItem->moveBy(textRect.height() *scaleText, 0);
textItem->setPos(posx2 + delta, -yorigin);
QGraphicsLineItem* graphicItem = m_scene->addLine(posx2, qMax(-yorigin, -minLimit), posx2, qMin(-yorigin, -maxLimit));
graphicItem->setPen(gridPen);
graphicItem->setFlag(QGraphicsItem::ItemIsSelectable, false);
}
}
// Axis x
if (yorigin == 0.0) {
item = m_scene->addLine(0, -yorigin, maxX, -yorigin, axisPen);
item->setFlag(QGraphicsItem::ItemIsSelectable, false);
item->setZValue(2);
}
// Rect
{
QGraphicsRectItem* graphicItem = m_scene->addRect(0, qMax(-yorigin, -minLimit), maxX, qMin(-yorigin, -maxLimit) - (qMax(-yorigin, -minLimit)), axisPen);
graphicItem->setFlag(QGraphicsItem::ItemIsSelectable, false);
graphicItem->setZValue(2);
}
}
}
// Draw Average
bool lineCondition = (mode == HISTOGRAM || mode == POINT || mode == LINE) && (scaleText != 0.0) && nbRowsDrawed == 1;
int averageCol = getAverageColumnIndex();
if (m_averageVisible && lineCondition && averageCol != -1) {
QTableWidgetItem* tableItem = ui.kTable->item(0, averageCol);
if (tableItem != nullptr) {
double posy = tableItem->data(DATA_VALUE).toDouble();
if (inPositive) {
posy = qAbs(posy);
}
QGraphicsLineItem* item = m_scene->addLine(0, -posy, maxX, -posy);
dotPen.setColor(m_averageColor);
item->setPen(dotPen);
item->setFlag(QGraphicsItem::ItemIsSelectable, false);
item->setZValue(1);
item->setToolTip(tableItem->toolTip());
QGraphicsTextItem* textItem = m_scene->addText(SKGServices::toCurrencyString(posy, m_primaryUnit.Symbol, m_decimalsVisible ? m_primaryUnit.NbDecimal : 0));
QRectF textRect = textItem->boundingRect();
double delta = scaleText * textRect.height() / 2.0;
textItem->setPos(maxX, -posy - delta);
textItem->setDefaultTextColor(m_averageColor);
textItem->setScale(scaleText);
textItem->setFlag(QGraphicsItem::ItemIsSelectable, false);
textItem->setZValue(20);
textItem->setToolTip(tableItem->toolTip());
}
}
// Draw Min & Max limits
int minCol = getMinColumnIndex();
if (lineCondition && minCol != -1) {
// Min
{
QTableWidgetItem* tableItem = ui.kTable->item(0, minCol);
if (tableItem != nullptr) {
double posy = tableItem->data(DATA_VALUE).toDouble();
if (inPositive) {
posy = qAbs(posy);
}
QGraphicsLineItem* item = m_scene->addLine(0, -posy, maxX, -posy);
dotPen.setColor(m_minColor);
item->setPen(dotPen);
item->setFlag(QGraphicsItem::ItemIsSelectable, false);
item->setZValue(1);
item->setToolTip(tableItem->toolTip());
QGraphicsTextItem* textItem = m_scene->addText(SKGServices::toCurrencyString(posy, m_primaryUnit.Symbol, m_decimalsVisible ? m_primaryUnit.NbDecimal : 0));
QRectF textRect = textItem->boundingRect();
double delta = scaleText * textRect.height() / 2.0;
textItem->setPos(maxX, -posy - delta);
textItem->setDefaultTextColor(m_minColor);
textItem->setScale(scaleText);
textItem->setFlag(QGraphicsItem::ItemIsSelectable, false);
textItem->setZValue(20);
textItem->setToolTip(tableItem->toolTip());
}
}
// Max
{
QTableWidgetItem* tableItem = ui.kTable->item(0, minCol + 1);
if (tableItem != nullptr) {
double posy = tableItem->data(DATA_VALUE).toDouble();
if (inPositive) {
posy = qAbs(posy);
}
QGraphicsLineItem* item = m_scene->addLine(0, -posy, maxX, -posy);
dotPen.setColor(m_maxColor);
item->setPen(dotPen);
item->setFlag(QGraphicsItem::ItemIsSelectable, false);
item->setZValue(1);
item->setToolTip(tableItem->toolTip());
QGraphicsTextItem* textItem = m_scene->addText(SKGServices::toCurrencyString(posy, m_primaryUnit.Symbol, m_decimalsVisible ? m_primaryUnit.NbDecimal : 0));
QRectF textRect = textItem->boundingRect();
double delta = scaleText * textRect.height() / 2.0;
textItem->setPos(maxX, -posy - delta);
textItem->setDefaultTextColor(m_maxColor);
textItem->setScale(scaleText);
textItem->setFlag(QGraphicsItem::ItemIsSelectable, false);
textItem->setZValue(20);
textItem->setToolTip(tableItem->toolTip());
}
}
}
// Draw Linear Regression
if (m_linearRegressionVisible && lineCondition && m_indexLinearRegression != -1) {
QTableWidgetItem* tableItem = ui.kTable->item(0, m_indexLinearRegression);
if (tableItem != nullptr) {
QString f = tableItem->text();
QScriptEngine myEngine;
QString f0 = f;
f0 = f0.remove(QStringLiteral("y="));
f0 = f0.replace('x', '1');
f0 = f0.replace(',', '.'); // Replace comma by a point in case of typo
if (inPositive) {
f0 = "Math.abs(" % f0 % ')';
}
double y0 = myEngine.evaluate(f0).toNumber();
QString f1 = f;
f1 = f1.remove(QStringLiteral("y="));
f1 = f1.replace('x', SKGServices::intToString(nbRealColumns - 1));
f1 = f1.replace(',', '.'); // Replace comma by a point in case of typo
if (inPositive) {
f1 = "Math.abs(" % f1 % ')';
}
double y1 = myEngine.evaluate(f1).toNumber();
QGraphicsLineItem* item = m_scene->addLine(x0, -y0, x1, -y1);
dotPen.setColor(m_tendencyColor);
item->setPen(dotPen);
item->setFlag(QGraphicsItem::ItemIsSelectable, false);
item->setZValue(1);
item->setToolTip(f);
}
}
// Draw pareto
if (lineCondition && m_paretoVisible && !paretoPoints.isEmpty()) {
// Compute the sum
double sum = 0.0;
QList<double> list = paretoPoints.keys();
for (auto xp1 : qAsConst(list)) {
sum += paretoPoints[xp1];
}
// Draw the second axis
for (int i = 0 ; i <= 100 ; i = i + 10) {
double posy = (maxLimit - minLimit) * static_cast<double>(i) / 100.0 + minLimit;
QGraphicsTextItem* textItem = m_scene->addText(SKGServices::intToString(i) % "%");
QRectF textRect = textItem->boundingRect();
textItem->setDefaultTextColor(m_paretoColor);
textItem->setScale(scaleText);
textItem->setFlag(QGraphicsItem::ItemIsSelectable, false);
textItem->setZValue(19);
double delta = scaleText * textRect.height() / 2.0;
textItem->setPos(maxX, -posy - delta);
}
// Draw the curve
double x00 = -1;
double y00 = -1;
double csum = 0.0;
for (auto xp2 : qAsConst(list)) {
csum += paretoPoints[xp2];
if (x00 != -1) {
QGraphicsLineItem* item = m_scene->addLine(x00, -((maxLimit - minLimit) * y00 / sum + minLimit), xp2, -((maxLimit - minLimit) * csum / sum + minLimit));
dotPen.setColor(m_paretoColor);
item->setPen(dotPen);
item->setFlag(QGraphicsItem::ItemIsSelectable, false);
item->setZValue(1);
}
x00 = xp2;
y00 = csum;
}
}
// Draw legend
if (m_legendVisible) {
QPointF legendPosition;
double maxY;
if (mode == TREEMAP) {
scaleText = 0.2;
margin = BOX_SIZE / 10;
legendPosition = QPointF(BOX_SIZE + margin, 0);
maxY = BOX_SIZE * nbRowInMode2;
} else if (mode == PIE || mode == CONCENTRICPIE) {
if (nbRowInMode2 * nbColInMode2 < nbColumns - 1) {
++nbRowInMode2;
}
scaleText = 0.2;
margin = BOX_SIZE / 10;
legendPosition = QPointF(BOX_SIZE * nbColInMode2 + margin, 0);
maxY = BOX_SIZE * nbRowInMode2;
} else {
legendPosition = QPointF(maxX + margin, qMin(-yorigin, -maxLimit) - margin / 6);
maxY = qMax(-yorigin, -minLimit);
}
addLegend(legendPosition, margin / 4, scaleText, maxY);
}
}
{
SKGTRACEINFUNC(10)
m_scene->setSceneRect(QRectF());
ui.graphicView->setScene(m_scene);
ui.graphicView->show();
if (m_tableVisible) {
ui.kTable->show();
}
ui.graphicView->initializeZoom();
// Add selection event on scene
connect(m_scene, &SKGGraphicsScene::selectionChanged, this, &SKGTableWithGraph::onSelectionChangedInGraph, Qt::QueuedConnection);
connect(m_scene, &SKGGraphicsScene::doubleClicked, this, &SKGTableWithGraph::onDoubleClickGraph, Qt::QueuedConnection);
}
QApplication::restoreOverrideCursor();
}
int SKGTableWithGraph::getNbColumns(bool iWithComputed) const
{
int nbColumns = ui.kTable->columnCount();
if (!iWithComputed) {
if (m_indexMin != -1) {
nbColumns -= 2;
}
if (m_indexAverage != -1) {
--nbColumns;
}
if (m_indexSum != -1) {
--nbColumns;
}
if (m_indexLinearRegression != -1) {
--nbColumns;
}
}
return nbColumns;
}
int SKGTableWithGraph::getAverageColumnIndex() const
{
return m_indexAverage;
}
int SKGTableWithGraph::getMinColumnIndex() const
{
return m_indexMin;
}
double SKGTableWithGraph::computeStepSize(double iRange, double iTargetSteps)
{
// Calculate an initial guess at step size
double tempStep = iRange / iTargetSteps;
// Get the magnitude of the step size
double mag = floor(log10(tempStep));
double magPow = pow(static_cast<double>(10.0), mag);
// Calculate most significant digit of the new step size
double magMsd = static_cast<int>(tempStep / magPow + .5);
// promote the MSD to either 1, 2, or 5
if (magMsd > 5.0) {
magMsd = 10.0;
} else if (magMsd > 2.0) {
magMsd = 5.0;
} else if (magMsd > 1.0) {
magMsd = 2.0;
}
return magMsd * magPow;
}
void SKGTableWithGraph::addLegend(const QPointF iPosition, double iSize, double iScaleText, double iMaxY)
{
SKGTRACEINFUNC(10)
QPen outlinePen(m_outlineColor);
outlinePen.setWidthF(iScaleText * 4.0 / 500.0);
if (m_scene != nullptr) {
GraphType mode = getGraphType();
int nbRows = ui.kTable->rowCount();
int nbRealRows = nbRows;
for (int posy = 0; posy < nbRows; ++posy) {
if (m_sumRows.at(posy + 1)) {
--nbRealRows;
}
}
int nbColumns = getNbColumns(false);
if (nbColumns > 1) {
double margin = 1.2;
double currentYPos = iPosition.y();
double currentXPos = iPosition.x();
double currentXMaxSize = 0;
for (int i = 0; i < nbRows; ++i) {
auto* btn = qobject_cast<SKGColorButton*>(ui.kTable->cellWidget(i, 0));
if (btn != nullptr) {
// Get title
QString title = btn->text();
// Build brush
QColor color1;
QTableWidgetItem* it = ui.kTable->item(i, 1);
if (it != nullptr) {
QGraphicsItem* graphicItem = m_mapItemGraphic.value(it);
if (graphicItem != nullptr) {
// Draw box
color1 = QColor::fromHsv(graphicItem->data(DATA_COLOR_H).toInt(),
graphicItem->data(DATA_COLOR_S).toInt(),
graphicItem->data(DATA_COLOR_V).toInt());
color1.setAlpha(ALPHA);
}
}
QColor color2;
it = ui.kTable->item(i, nbColumns - 1 - m_nbVirtualColumns);
if (it != nullptr) {
QGraphicsItem* graphicItem = m_mapItemGraphic.value(it);
if (graphicItem != nullptr) {
// Draw box
color2 = QColor::fromHsv(graphicItem->data(DATA_COLOR_H).toInt(),
graphicItem->data(DATA_COLOR_S).toInt(),
graphicItem->data(DATA_COLOR_V).toInt());
color2.setAlpha(ALPHA);
}
}
QLinearGradient grandient(currentXPos, currentYPos, currentXPos + 2.0 * iSize, currentYPos);
grandient.setColorAt(0, color1);
grandient.setColorAt(1, color2);
// Draw legend item
QGraphicsItem* item = nullptr;
if (mode == POINT || mode == LINE) {
item = drawPoint(currentXPos, currentYPos + iSize / 2.0, iSize / 2.0, mode == POINT ? i : (i % 5), QBrush(grandient));
} else if (mode == BUBBLE) {
item = m_scene->addEllipse(currentXPos, currentYPos, iSize, iSize, outlinePen, QBrush(grandient));
} else if (mode == PIE || mode == CONCENTRICPIE) {
QPainterPath path;
path.moveTo(currentXPos + iSize / 2.0, currentYPos + iSize / 2.0);
path.arcTo(currentXPos, currentYPos, iSize, iSize, 45, 270);
path.closeSubpath();
if (mode == CONCENTRICPIE) {
QPainterPath path2;
double p = iSize / 3.0;
path2.addEllipse(currentXPos + p, currentYPos + p, iSize - 2.0 * p, iSize - 2.0 * p);
path -= path2;
}
item = m_scene->addPath(path, outlinePen, QBrush(grandient));
} else {
item = m_scene->addRect(currentXPos, currentYPos, iSize, iSize, outlinePen, QBrush(grandient));
}
if (item != nullptr) {
item->setFlag(QGraphicsItem::ItemIsSelectable, false);
item->setToolTip(title);
// Set shadow
if (isShadowVisible()) {
auto ellipse_shadow = new QGraphicsDropShadowEffect();
ellipse_shadow->setOffset(3);
item->setGraphicsEffect(ellipse_shadow);
}
}
// Draw text
QGraphicsTextItem* textItem = m_scene->addText(title);
textItem->setDefaultTextColor(m_textColor);
textItem->setScale(iScaleText);
textItem->setPos(currentXPos + margin * iSize, currentYPos + iSize / 2.0 - textItem->boundingRect().height()*iScaleText / 2.0);
textItem->setFlag(QGraphicsItem::ItemIsSelectable, false);
// Compute next position
currentYPos += margin * iSize;
QRectF textRect = textItem->boundingRect();
currentXMaxSize = qMax(currentXMaxSize, static_cast<double>(iScaleText * textRect.width()));
if (currentYPos > iMaxY) {
currentYPos = iPosition.y();
currentXPos += currentXMaxSize + 2 * margin * iSize;
currentXMaxSize = 0;
}
}
}
}
}
}
void SKGTableWithGraph::addArrow(const QPointF iPeak, double iSize, double iArrowAngle, double iDegree)
{
if (m_scene != nullptr) {
QPolygonF pol;
double radian = 3.14 * iArrowAngle / 360.0;
pol << QPointF(0, 0) << QPointF(iSize * cos(radian), iSize * sin(radian)) << QPointF(iSize * cos(radian), -iSize * sin(radian)) << QPointF(0, 0);
QGraphicsPolygonItem* item = m_scene->addPolygon(pol, QPen(m_axisColor, iSize / 20.0), QBrush(m_axisColor));
item->setRotation(iDegree);
item->moveBy(iPeak.x(), iPeak.y());
item->setFlag(QGraphicsItem::ItemIsSelectable, false);
item->setZValue(2);
}
}
QGraphicsItem* SKGTableWithGraph::drawPoint(qreal iX, qreal iY, qreal iRadius, int iMode, const QBrush& iBrush)
{
QGraphicsItem* graphItem = nullptr;
int nbMode = 13;
if (m_scene != nullptr) {
QPen outlinePen(m_outlineColor);
outlinePen.setWidthF(iRadius / 10);
QPen pen;
if ((iMode % nbMode) <= 4) {
pen = QPen(iBrush.color());
const QGradient* grad = iBrush.gradient();
if (grad != nullptr) {
auto stops = grad->stops();
auto stop = stops.last();
pen = QPen(stop.second);
}
pen.setWidthF(iRadius / 10);
}
switch (iMode % nbMode) {
case 0: {
graphItem = m_scene->addEllipse(iX, iY - iRadius, 2 * iRadius, 2 * iRadius, pen, m_WhiteColor);
break;
}
case 1: {
graphItem = m_scene->addRect(iX, iY - iRadius, 2 * iRadius, 2 * iRadius, pen, m_WhiteColor);
break;
}
case 2: {
QPolygonF polygon;
polygon << QPointF(iX + iRadius, iY + iRadius) << QPointF(iX + 2 * iRadius, iY - iRadius)
<< QPointF(iX, iY - iRadius) << QPointF(iX + iRadius, iY + iRadius);
graphItem = m_scene->addPolygon(polygon, pen, m_WhiteColor);
break;
}
case 3: {
QPolygonF polygon;
polygon << QPointF(iX, iY) << QPointF(iX + iRadius, iY + iRadius)
<< QPointF(iX + 2 * iRadius, iY) << QPointF(iX + iRadius, iY - iRadius) << QPointF(iX, iY);
graphItem = m_scene->addPolygon(polygon, pen, m_WhiteColor);
break;
}
case 4: {
QPolygonF polygon;
polygon << QPointF(iX + iRadius, iY - iRadius) << QPointF(iX + 2 * iRadius, iY + iRadius)
<< QPointF(iX, iY + iRadius) << QPointF(iX + iRadius, iY - iRadius);
graphItem = m_scene->addPolygon(polygon, pen, m_WhiteColor);
break;
}
case 5: {
graphItem = m_scene->addEllipse(iX, iY - iRadius, 2 * iRadius, 2 * iRadius, outlinePen, iBrush);
break;
}
case 6: {
graphItem = m_scene->addRect(iX, iY - iRadius, 2 * iRadius, 2 * iRadius, outlinePen, iBrush);
break;
}
case 7: {
QPolygonF polygon;
polygon << QPointF(iX, iY - iRadius) << QPointF(iX + 2 * iRadius, iY + iRadius)
<< QPointF(iX + 2 * iRadius, iY - iRadius) << QPointF(iX, iY + iRadius);
graphItem = m_scene->addPolygon(polygon, outlinePen, iBrush);
break;
}
case 8: {
QPolygonF polygon;
polygon << QPointF(iX + iRadius, iY + iRadius) << QPointF(iX + 2 * iRadius, iY - iRadius)
<< QPointF(iX, iY - iRadius) << QPointF(iX + iRadius, iY + iRadius);
graphItem = m_scene->addPolygon(polygon, outlinePen, iBrush);
break;
}
case 9: {
QPolygonF polygon;
polygon << QPointF(iX, iY) << QPointF(iX + iRadius, iY + iRadius)
<< QPointF(iX + 2 * iRadius, iY) << QPointF(iX + iRadius, iY - iRadius) << QPointF(iX, iY);
graphItem = m_scene->addPolygon(polygon, outlinePen, iBrush);
break;
}
case 10: {
QPolygonF polygon;
polygon << QPointF(iX, iY - iRadius) << QPointF(iX + 2 * iRadius, iY - iRadius)
<< QPointF(iX, iY + iRadius) << QPointF(iX + 2 * iRadius, iY + iRadius);
graphItem = m_scene->addPolygon(polygon, outlinePen, iBrush);
break;
}
case 11: {
QPolygonF polygon;
polygon << QPointF(iX + iRadius, iY - iRadius) << QPointF(iX + 2 * iRadius, iY + iRadius)
<< QPointF(iX, iY + iRadius) << QPointF(iX + iRadius, iY - iRadius);
graphItem = m_scene->addPolygon(polygon, outlinePen, iBrush);
break;
}
case 12:
default: {
QPainterPath path;
path.addEllipse(iX, iY - iRadius, 2 * iRadius, 2 * iRadius);
path.closeSubpath();
QPainterPath path2;
path2.addEllipse(iX + iRadius / 2.0, iY - iRadius / 2.0, iRadius, iRadius);
path -= path2;
graphItem = m_scene->addPath(path, outlinePen, iBrush);
break;
}
}
}
if ((graphItem != nullptr) && (iMode % nbMode) <= 4) {
graphItem->setData(DATA_MODE, 1);
}
return graphItem;
}
SKGError SKGTableWithGraph::exportInFile(const QString& iFileName)
{
SKGError err;
_SKGTRACEINFUNCRC(10, err)
QString lastCodecUsed = QTextCodec::codecForLocale()->name();
QString extension = QFileInfo(iFileName).suffix().toUpper();
if (extension == QStringLiteral("CSV")) {
// Write file
QSaveFile file(iFileName);
if (!file.open(QIODevice::WriteOnly)) {
err.setReturnCode(ERR_INVALIDARG).setMessage(i18nc("Error message", "Save file '%1' failed", iFileName));
} else {
QTextStream out(&file);
out.setCodec(lastCodecUsed.toLatin1().constData());
QStringList dump = SKGServices::tableToDump(getTable(), SKGServices::DUMP_CSV);
int nbl = dump.count();
for (int i = 0; i < nbl; ++i) {
out << dump.at(i) << endl;
}
// Close file
file.commit();
}
} else {
// Write file
QSaveFile file(iFileName);
if (!file.open(QIODevice::WriteOnly)) {
err.setReturnCode(ERR_INVALIDARG).setMessage(i18nc("Error message", "Save file '%1' failed", iFileName));
} else {
QTextStream out(&file);
out.setCodec(lastCodecUsed.toLatin1().constData());
QStringList dump = SKGServices::tableToDump(getTable(), SKGServices::DUMP_TEXT);
int nbl = dump.count();
for (int i = 0; i < nbl; ++i) {
out << dump.at(i) << endl;
}
// Close file
file.commit();
}
}
return err;
}
void SKGTableWithGraph::onExport()
{
_SKGTRACEINFUNC(10)
SKGError err;
QString fileName = SKGMainPanel::getSaveFileName(QStringLiteral("kfiledialog:///IMPEXP"), QStringLiteral("text/csv text/plain"), this);
if (!fileName.isEmpty()) {
err = exportInFile(fileName);
SKGMainPanel::displayErrorMessage(err);
QDesktopServices::openUrl(QUrl(fileName));
}
}
void SKGTableWithGraph::setGraphType(SKGTableWithGraph::GraphType iType)
{
if (m_displayMode != nullptr) {
auto newIndex = m_displayMode->findData(static_cast<int>(iType));
if (m_displayMode->currentIndex() != newIndex) {
m_displayMode->setCurrentIndex(newIndex);
Q_EMIT modified();
}
}
}
SKGTableWithGraph::GraphType SKGTableWithGraph::getGraphType() const
{
GraphType mode = static_cast<GraphType>(m_displayMode->itemData(m_displayMode->currentIndex()).toInt());
return mode;
}
void SKGTableWithGraph::setSelectable(bool iSelectable)
{
if (m_selectable != iSelectable) {
m_selectable = iSelectable;
Q_EMIT modified();
}
}
bool SKGTableWithGraph::isSelectable() const
{
return m_selectable;
}
void SKGTableWithGraph::setShadowVisible(bool iShadow)
{
if (m_shadow != iShadow) {
m_shadow = iShadow;
Q_EMIT modified();
}
}
bool SKGTableWithGraph::isShadowVisible() const
{
return m_shadow;
}
diff --git a/skgbasegui/skgtablewithgraph.h b/skgbasegui/skgtablewithgraph.h
index f964797e3..8b26b2816 100644
--- a/skgbasegui/skgtablewithgraph.h
+++ b/skgbasegui/skgtablewithgraph.h
@@ -1,515 +1,515 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGTABLEWITHGRAPH_H
#define SKGTABLEWITHGRAPH_H
/** @file
* A table with graph with more features.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include <qwidget.h>
#include "skgbasegui_export.h"
#include "skgcombobox.h"
#include "skgservices.h"
#include "ui_skgtablewithgraph.h"
class SKGGraphicsScene;
class QMenu;
class QTimer;
class QWidgetAction;
class QGraphicsItem;
/**
* This file is a table with graph with more features
*/
class SKGBASEGUI_EXPORT SKGTableWithGraph : public QWidget
{
Q_OBJECT
public:
/**
* Graph type
*/
enum GraphType {STACK,
HISTOGRAM,
PIE,
CONCENTRICPIE,
POINT,
LINE,
STACKAREA,
BUBBLE,
STACKCOLUMNS,
TREEMAP
};
/**
* Graph type
*/
Q_ENUM(GraphType)
/**
* Additional information to display
*/
enum DisplayAdditional {NONE = 0x0,
SUM = 0x1,
AVERAGE = 0x2,
LIMITS = 0x4,
ALL = 255
};
/**
* Additional information to display
*/
Q_ENUM(DisplayAdditional)
/**
* Additional information to display
*/
Q_DECLARE_FLAGS(DisplayAdditionalFlag, DisplayAdditional)
/**
* Graph Type widget visibility
*/
Q_PROPERTY(bool graphTypeSelectorVisible READ isGraphTypeSelectorVisible WRITE setGraphTypeSelectorVisible NOTIFY modified)
/**
* Items selectable or not
*/
Q_PROPERTY(bool selectable READ isSelectable WRITE setSelectable NOTIFY modified)
/**
* Items with shadow or not
*/
Q_PROPERTY(bool shadow READ isShadowVisible WRITE setShadowVisible NOTIFY modified)
/**
* Graph Type
*/
Q_PROPERTY(GraphType graphType READ getGraphType WRITE setGraphType NOTIFY modified)
/**
* Default Constructor
*/
SKGTableWithGraph();
/**
* Constructor
* @param iParent the parent
*/
explicit SKGTableWithGraph(QWidget* iParent);
/**
* Default Destructor
*/
~SKGTableWithGraph() override;
/**
* Get the current state
* MUST BE OVERWRITTEN
* @return a string containing all information needed to set the same state.
* Could be an XML stream
*/
QString getState();
/**
* Returns the table.
* @return table
*/
QTableWidget* table() const;
/**
* Returns the graph.
* @return graph
*/
SKGGraphicsView* graph() const;
/**
* Returns the text report.
* @return text report
*/
SKGWebView* textReport() const;
/**
* Get the mode for the additional display
* @return the mode
*/
SKGTableWithGraph::DisplayAdditionalFlag getAdditionalDisplayMode() const;
/**
* Get the table content
* @return the table content
*/
SKGStringListList getTable();
/**
* Get a pointer on the contextual menu of the table
* @return contextual menu
*/
QMenu* getTableContextualMenu() const;
/**
* Get a pointer on the contextual menu of the graph
* @return contextual menu
*/
QMenu* getGraphContextualMenu() const;
/**
* Get the visibility of the graph type selector zone
* @return the visibility
*/
bool isGraphTypeSelectorVisible() const;
/**
* Get the selectability of items
* @return the selectability
*/
bool isSelectable() const;
/**
* Get the shadows visibility
* @return the visibility
*/
bool isShadowVisible() const;
/**
* Get the graph type
* @return the type of graph
*/
SKGTableWithGraph::GraphType getGraphType() const;
/**
* Get the number of columns
* @param iWithComputed with compute columns (average, sum, forecast, ...) or not
* @return the number of columns
*/
int getNbColumns(bool iWithComputed = false) const;
/**
* @brief Get show widget
*
* @return SKGShow*
**/
SKGShow* getShowWidget() const;
/**
* To know if the table is visible
* @return the visibility
*/
bool isTableVisible() const;
/**
* To know if the graph is visible
* @return the visibility
*/
bool isGraphVisible() const;
/**
* To know if the text report is visible
* @return the visibility
*/
bool isTextReportVisible() const;
public Q_SLOTS:
/**
* Set the current state
* MUST BE OVERWRITTEN
* @param iState must be interpreted to set the state of the widget
*/
void setState(const QString& iState);
/**
* Set Data
* @param iData the data
* @param iPrimaryUnit the primary unit
* @param iSecondaryUnit the secondary unit
* @param iAdditionalInformation show sum and average columns
* @param iNbVirtualColumn number of columns
*/
void setData(const SKGStringListList& iData,
const SKGServices::SKGUnitInfo& iPrimaryUnit,
const SKGServices::SKGUnitInfo& iSecondaryUnit,
SKGTableWithGraph::DisplayAdditionalFlag iAdditionalInformation = SKGTableWithGraph::ALL,
int iNbVirtualColumn = 0);
/**
* Set the visibility of the graph type selector zone
* @param iVisible the visibility
*/
void setGraphTypeSelectorVisible(bool iVisible);
/**
* Enable / disable the selectability of items
* @param iSelectable the selectability
*/
void setSelectable(bool iSelectable);
/**
* Enable / disable the shadows
* @param iShadow the shadows
*/
void setShadowVisible(bool iShadow);
/**
* Set the graph type
* @param iType the type of graph
*/
void setGraphType(SKGTableWithGraph::GraphType iType);
/**
* Set tool bar visibility
* @param iVisibility the visibility
*/
void setFilterVisibility(bool iVisibility) const;
/**
* Set the axis color
* @param iColor the color
*/
void setAxisColor(const QColor& iColor = Qt::gray);
/**
* Set the grid color
* @param iColor the color
*/
void setGridColor(const QColor& iColor = Qt::lightGray);
/**
* Set the min color
* @param iColor the color
*/
void setMinColor(const QColor& iColor = Qt::red);
/**
* Set the max color
* @param iColor the color
*/
void setMaxColor(const QColor& iColor = Qt::green);
/**
* Set the pareto color
* @param iColor the color
*/
void setParetoColor(const QColor& iColor = Qt::darkRed);
/**
* Set the average color
* @param iColor the color
*/
void setAverageColor(const QColor& iColor = Qt::blue);
/**
* Set the tendency color
* @param iColor the color
*/
void setTendencyColor(const QColor& iColor = Qt::darkYellow);
/**
* Set the outline color
* @param iColor the color
*/
void setOutlineColor(const QColor& iColor = Qt::black);
/**
* Set the background color
* @param iColor the color
*/
void setBackgroundColor(const QColor& iColor = Qt::white);
/**
* Set the text color
* @param iColor the color
*/
void setTextColor(const QColor& iColor = Qt::black);
/**
* Set antialiasing
* @param iAntialiasing enabled or disabled
*/
void setAntialiasing(bool iAntialiasing = true);
/**
* Redraw the graph after some milliseconds
*/
void redrawGraphDelayed();
/**
* Switch the limits visibility
* @return the new visibility
*/
bool switchLimitsVisibility();
/**
* Switch the average visibility
* @return the new visibility
*/
bool switchAverageVisibility();
/**
* Switch the linear regression visibility
* @return the new visibility
*/
bool switchLinearRegressionVisibility();
/**
* Switch the pareto curve visibility
* @return the new visibility
*/
bool switchParetoVisibility();
/**
* Switch the legend visibility
* @return the new visibility
*/
bool switchLegendVisibility();
/**
* Switch the origin visibility
* @return the new visibility
*/
bool swithOriginVisibility();
/**
* Switch the decimals visibility
* @return the new visibility
*/
bool swithDecimalsVisibility();
/**
* Reset the colors
*/
void resetColors();
/**
* Export to a file
* @param iFileName the file name
* @return an object managing the error
* @see SKGError
*/
SKGError exportInFile(const QString& iFileName);
Q_SIGNALS:
/**
* Emitted when a cell is double clicked
* @param row row of the cell
* @param column column of the cell
*/
void cellDoubleClicked(int row, int column);
/**
* Selection changed
*/
void selectionChanged();
/**
* The object is modified
*/
void modified();
private Q_SLOTS:
void onExport();
void onSelectionChanged();
void onSelectionChangedInGraph();
void onDoubleClick(int row, int column);
void onDoubleClickGraph();
void onLinkClicked(const QUrl& url);
void onFilterModified();
void onDisplayModeChanged();
void onChangeColor();
void onHorizontalScrollBarChanged(int /*iValue*/);
void refresh();
void redrawText();
void redrawGraph();
void showMenu(QPoint iPos);
private:
Q_DISABLE_COPY(SKGTableWithGraph)
double computeStepSize(double iRange, double iTargetSteps);
void addArrow(QPointF iPeak, double iSize, double iArrowAngle = 45, double iDegree = 90);
void addLegend(QPointF iPosition, double iSize, double iScaleText, double iMaxY);
QGraphicsItem* drawPoint(qreal iX, qreal iY, qreal iRadius, int iMode, const QBrush& iBrush);
int getAverageColumnIndex() const;
int getMinColumnIndex() const;
QStringList getSumItems(const QString& iString) const;
void addSums(SKGStringListList& ioTable, int& iNblines);
Ui::skgtablewithgraph_base ui{};
SKGGraphicsScene* m_scene;
SKGStringListList m_data;
QList<bool> m_sumRows;
SKGServices::SKGUnitInfo m_primaryUnit;
SKGServices::SKGUnitInfo m_secondaryUnit;
DisplayAdditionalFlag m_additionalInformation;
int m_nbVirtualColumns;
bool m_selectable;
bool m_toolBarVisible;
bool m_graphTypeVisible;
bool m_limitVisible;
bool m_averageVisible;
bool m_linearRegressionVisible;
bool m_paretoVisible;
bool m_legendVisible;
bool m_graphVisible;
bool m_tableVisible;
bool m_textVisible;
bool m_zeroVisible;
bool m_decimalsVisible;
bool m_shadow;
QMenu* m_mainMenu;
QTimer m_timer;
QTimer m_timerRedraw;
QAction* m_actShowLimits;
QAction* m_actShowAverage;
QAction* m_actShowLinearRegression;
QAction* m_actShowPareto;
QAction* m_actShowLegend;
QAction* m_actShowZero;
QAction* m_actShowDecimal;
QAction* m_allPositiveMenu;
QWidgetAction* m_displayModeWidget{};
int m_indexSum;
int m_indexAverage;
int m_indexMin;
int m_indexLinearRegression;
QMap<QString, QColor> m_mapTitleColor;
QMap<QTableWidgetItem*, QGraphicsItem*> m_mapItemGraphic{};
QColor m_axisColor;
QColor m_backgroundColor;
QColor m_textColor;
QColor m_gridColor;
QColor m_minColor;
QColor m_maxColor;
QColor m_paretoColor;
QColor m_averageColor;
QColor m_tendencyColor;
QColor m_outlineColor;
QBrush m_NegativeColor;
QBrush m_WhiteColor;
SKGComboBox* m_displayMode{};
Qt::SortOrder m_sortOrder;
int m_sortColumn;
};
Q_DECLARE_OPERATORS_FOR_FLAGS(SKGTableWithGraph::DisplayAdditionalFlag)
#endif // SKGTABLEWITHGRAPH_H
diff --git a/skgbasegui/skgtabpage.cpp b/skgbasegui/skgtabpage.cpp
index a3e3640c1..aef933686 100644
--- a/skgbasegui/skgtabpage.cpp
+++ b/skgbasegui/skgtabpage.cpp
@@ -1,328 +1,328 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is a class managing widget.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgtabpage.h"
#include <klocalizedstring.h>
#include <kmessagebox.h>
#include <qwidget.h>
#ifdef SKG_WEBENGINE
#include <qwebengineview.h>
#else
#include <qwebview.h>
#endif
#include <qmath.h>
#include <cmath>
#include "skgdocument.h"
#include "skghtmlboardwidget.h"
#include "skgmainpanel.h"
#include "skgnodeobject.h"
#include "skgservices.h"
#include "skgtraces.h"
#include "skgtransactionmng.h"
#include "skgtreeview.h"
SKGTabPage::SKGTabPage(QWidget* iParent, SKGDocument* iDocument)
: SKGWidget(iParent, iDocument), m_pin(false)
{
SKGTRACEINFUNC(5)
// Save original size
m_fontOriginalPointSize = this->font().pointSize(); // Use this instead of zoomableWidget()
}
SKGTabPage::~SKGTabPage()
{
SKGTRACEINFUNC(5)
}
bool SKGTabPage::close(bool iForce)
{
SKGTRACEINFUNC(5)
int conf = KMessageBox::Yes;
if (!iForce && isPin()) {
QApplication::setOverrideCursor(QCursor(Qt::ArrowCursor));
conf = KMessageBox::questionYesNo(this,
i18nc("Question", "Do you really want to close this pinned page?"),
i18nc("Question", "Pinned page"),
KStandardGuiItem::yes(),
KStandardGuiItem::no(),
QStringLiteral("closepinnedpage"));
QApplication::restoreOverrideCursor();
}
overwrite();
if (conf == KMessageBox::No) {
return false;
}
return QWidget::close();
}
void SKGTabPage::setBookmarkID(const QString& iId)
{
m_bookmarkID = iId;
}
QString SKGTabPage::getBookmarkID()
{
return m_bookmarkID;
}
SKGTabPage::SKGPageHistoryItemList SKGTabPage::getPreviousPages()
{
return m_previousPages;
}
void SKGTabPage::setPreviousPages(const SKGTabPage::SKGPageHistoryItemList& iPages)
{
m_previousPages = iPages;
}
SKGTabPage::SKGPageHistoryItemList SKGTabPage::getNextPages()
{
return m_nextPages;
}
void SKGTabPage::setNextPages(const SKGTabPage::SKGPageHistoryItemList& iPages)
{
m_nextPages = iPages;
}
bool SKGTabPage::isOverwriteNeeded()
{
// Is this widget linked to a bookmark ?
if (!m_bookmarkID.isEmpty()) {
// Yes. Is state modified ?
SKGNodeObject node(getDocument(), SKGServices::stringToInt(m_bookmarkID));
if (node.exist()) {
QStringList d = SKGServices::splitCSVLine(node.getData());
if (d.count() > 2) {
QString currentState = getState().trimmed();
QString oldState = d[2].trimmed();
currentState.remove('\n');
oldState.remove('\n');
SKGTRACEL(20) << "oldState =[" << oldState << ']' << endl;
SKGTRACEL(20) << "currentState =[" << currentState << ']' << endl;
SKGTRACEL(20) << "Bookmark diff =" << (currentState != oldState ? "TRUE" : "FALSE") << endl;
return (currentState != oldState);
}
}
} else {
// No. It is a page opened from context or from another page
QString name = getDefaultStateAttribute();
if (!name.isEmpty()) {
QString currentState = getState().trimmed();
QString oldState = getDocument()->getParameter(name);
currentState.remove('\n');
oldState.remove('\n');
SKGTRACEL(20) << "oldState =[" << oldState << ']' << endl;
SKGTRACEL(20) << "currentState =[" << currentState << ']' << endl;
SKGTRACEL(20) << "Page diff =" << (currentState != oldState ? "TRUE" : "FALSE") << endl;
return (currentState != oldState);
}
}
return false;
}
void SKGTabPage::overwrite(bool iUserConfirmation)
{
SKGTRACEINFUNC(10)
// Is this widget linked to a bookmark ?
if (!m_bookmarkID.isEmpty()) {
// Yes. Is state modified ?
SKGNodeObject node(getDocument(), SKGServices::stringToInt(m_bookmarkID));
if (node.exist()) {
QStringList d = SKGServices::splitCSVLine(node.getData());
QString fullname = node.getFullName();
if (d.count() > 2) {
QString currentState = getState().trimmed();
QString oldState = d[2].trimmed();
currentState.remove('\n');
oldState.remove('\n');
SKGTRACEL(20) << "oldState =[" << oldState << ']' << endl;
SKGTRACEL(20) << "currentState =[" << currentState << ']' << endl;
if (currentState != oldState) {
QApplication::setOverrideCursor(QCursor(Qt::ArrowCursor));
int conf = KMessageBox::Yes;
KMessageBox::ButtonCode button;
SKGTRACEL(10) << (KMessageBox::shouldBeShownYesNo(QStringLiteral("updateBookmarkOnClose"), button) ? "updateBookmarkOnClose: Ask confirmation" : "updateBookmarkOnClose: Do not ask confirmation") << endl;
if (iUserConfirmation && !oldState.isEmpty()) {
conf = KMessageBox::questionYesNo(this,
i18nc("Question", "Bookmark '%1' has been modified. Do you want to update it with the current state?", fullname),
i18nc("Question", "Bookmark has been modified"),
KStandardGuiItem::yes(),
KStandardGuiItem::no(),
QStringLiteral("updateBookmarkOnClose"));
}
QApplication::restoreOverrideCursor();
if (conf == KMessageBox::Yes) {
SKGError err;
{
SKGBEGINLIGHTTRANSACTION(*getDocument(), i18nc("Noun, name of the user action", "Bookmark update '%1'", fullname), err)
d[2] = currentState;
IFOKDO(err, node.setData(SKGServices::stringsToCsv(d)))
IFOKDO(err, node.save())
}
IFOKDO(err, SKGError(0, i18nc("Successful message after an user action", "Bookmark updated")))
SKGMainPanel::displayErrorMessage(err);
}
}
}
}
} else {
// No. It is a page opened from context or from another page
QString name = getDefaultStateAttribute();
if (!name.isEmpty()) {
QString currentState = getState().trimmed();
QString oldState = getDocument()->getParameter(name);
SKGTRACEL(20) << "oldState =[" << oldState << ']' << endl;
SKGTRACEL(20) << "currentState =[" << currentState << ']' << endl;
currentState.remove('\n');
oldState.remove('\n');
if (currentState != oldState) {
QApplication::setOverrideCursor(QCursor(Qt::ArrowCursor));
int conf = KMessageBox::Yes;
KMessageBox::ButtonCode button;
SKGTRACEL(10) << (KMessageBox::shouldBeShownYesNo(QStringLiteral("updateContextOnClose"), button) ? "updateBookmarkOnClose: Ask confirmation" : "updateBookmarkOnClose: Do not ask confirmation") << endl;
if (iUserConfirmation && !oldState.isEmpty()) {
conf = KMessageBox::questionYesNo(this,
i18nc("Question", "Page has been modified. Do you want to update it with the current state?"),
i18nc("Question", "Page has been modified"),
KStandardGuiItem::yes(),
KStandardGuiItem::no(),
QStringLiteral("updateContextOnClose"));
}
QApplication::restoreOverrideCursor();
if (conf == KMessageBox::Yes) {
SKGError err;
{
SKGBEGINLIGHTTRANSACTION(*getDocument(), i18nc("Noun, name of the user action", "Save default state"), err)
err = getDocument()->setParameter(name, currentState);
}
IFOKDO(err, SKGError(0, i18nc("Successful message after an user action", "Default state saved")))
SKGMainPanel::displayErrorMessage(err);
}
}
}
}
}
bool SKGTabPage::isEditor()
{
return false;
}
void SKGTabPage::activateEditor() {}
QWidget* SKGTabPage::zoomableWidget()
{
return mainWidget();
}
QList< QWidget* > SKGTabPage::printableWidgets()
{
QList< QWidget* > output;
output.push_back(mainWidget());
return output;
}
bool SKGTabPage::isZoomable()
{
return (zoomableWidget() != nullptr);
}
void SKGTabPage::setZoomPosition(int iValue)
{
QWidget* widget = zoomableWidget();
auto* treeView = qobject_cast<SKGTreeView*>(widget);
if (treeView != nullptr) {
treeView->setZoomPosition(iValue);
} else {
#ifdef SKG_WEBENGINE
auto webView = qobject_cast<QWebEngineView*>(widget);
#else
auto webView = qobject_cast<QWebView*>(widget);
#endif
if (webView != nullptr) {
webView->setZoomFactor(qPow(10, static_cast<qreal>(iValue) / 30.0));
} else {
int pointSize = qMax(1, m_fontOriginalPointSize + iValue);
QFont f = widget->font();
f.setPointSize(pointSize);
widget->setFont(f);
auto cs = widget->findChildren<SKGHtmlBoardWidget*>();
for (auto c : qAsConst(cs)) {
c->setPointSize(pointSize);
}
}
}
}
int SKGTabPage::zoomPosition()
{
int output = 0;
QWidget* widget = zoomableWidget();
auto* treeView = qobject_cast<SKGTreeView*>(widget);
if (treeView != nullptr) {
output = treeView->zoomPosition();
} else {
#ifdef SKG_WEBENGINE
auto webView = qobject_cast<QWebEngineView*>(widget);
#else
auto webView = qobject_cast<QWebView*>(widget);
#endif
if (webView != nullptr) {
output = qRound(30.0 * log10(webView->zoomFactor()));
} else if (widget != nullptr) {
output = widget->font().pointSize() - m_fontOriginalPointSize;
}
}
return output;
}
SKGTabPage* SKGTabPage::parentTabPage(QWidget* iWidget)
{
auto* output = qobject_cast< SKGTabPage* >(iWidget);
if ((output == nullptr) && (iWidget != nullptr)) {
QWidget* iParent = iWidget->parentWidget();
if (iParent != nullptr) {
output = SKGTabPage::parentTabPage(iParent);
}
}
return output;
}
bool SKGTabPage::isPin() const
{
return m_pin;
}
void SKGTabPage::setPin(bool iPin)
{
m_pin = iPin;
}
diff --git a/skgbasegui/skgtabpage.h b/skgbasegui/skgtabpage.h
index de9d44e1e..dc7874be2 100644
--- a/skgbasegui/skgtabpage.h
+++ b/skgbasegui/skgtabpage.h
@@ -1,198 +1,198 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGTABPAGE_H
#define SKGTABPAGE_H
/** @file
* This file is a class managing widget.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include <qlist.h>
#include <qwidget.h>
#include "skgbasegui_export.h"
#include "skgwidget.h"
/**
* This file is a tab widget used by plugins
*/
class SKGBASEGUI_EXPORT SKGTabPage : public SKGWidget
{
Q_OBJECT
public:
/**
* Describe a history item
*/
struct SKGPageHistoryItem {
QString plugin; /**< The plugin name */
QString name; /**< The name */
QString state; /**< The state */
QString icon; /**< The icon */
QString bookmarkID; /**< The bookmarkID */
};
/**
* List of history item
*/
using SKGPageHistoryItemList = QVector<SKGTabPage::SKGPageHistoryItem>;
/**
* Default Constructor
* @param iParent the parent widget
* @param iDocument the document
*/
explicit SKGTabPage(QWidget* iParent, SKGDocument* iDocument);
/**
* Default Destructor
*/
~SKGTabPage() override;
/**
* Set the bookmark id
* @param iId bookmark id
*/
virtual void setBookmarkID(const QString& iId);
/**
* Get the bookmark id
* @return bookmark id
*/
virtual QString getBookmarkID();
/**
* To know if an overwrite is needed
*/
virtual bool isOverwriteNeeded();
/**
* Overwrite bookmark if page is opened from a bookmark
* Overwrite context if page is opened from a context
* @param iUserConfirmation to display a confirmation panel
*/
virtual void overwrite(bool iUserConfirmation = true);
/**
* Get previous pages
* @return the list
*/
virtual SKGTabPage::SKGPageHistoryItemList getPreviousPages();
/**
* Set previous pages
* @param iPages the list
*/
virtual void setPreviousPages(const SKGTabPage::SKGPageHistoryItemList& iPages);
/**
* Get next pages
* @return the list
*/
virtual SKGTabPage::SKGPageHistoryItemList getNextPages();
/**
* Set next pages
* @param iPages the list
*/
virtual void setNextPages(const SKGTabPage::SKGPageHistoryItemList& iPages);
/**
* To know if this page contains an editor. MUST BE OVERWRITTEN
* @return the editor state
*/
virtual bool isEditor();
/**
* To activate the editor by setting focus on right widget. MUST BE OVERWRITTEN
*/
virtual void activateEditor();
/**
* Get the zoomable widget.
* The default implementation returns the main widget.
* @return the zoomable widget.
*/
virtual QWidget* zoomableWidget();
/**
* Get the printable widgets.
* The default implementation returns the main widget.
* @return the printable widgets.
*/
virtual QList<QWidget*> printableWidgets();
/**
* To know if this page is zoomable. MUST BE OVERWRITTEN
* @return true or false
*/
virtual bool isZoomable();
/**
* Get the zoom position. MUST BE OVERWRITTEN
* @return the position (-10<=value<=10)
*/
virtual int zoomPosition();
/**
* Set the zoom position. MUST BE OVERWRITTEN
* @param iValue the position (-10<=value<=10)
*/
virtual void setZoomPosition(int iValue);
/**
* Get the tab page of a widget
* @param iWidget the widget
* @return the iParent tab page or nullptr
*/
static SKGTabPage* parentTabPage(QWidget* iWidget);
/**
* Get the pin status
* @return the pin status
*/
virtual bool isPin() const;
public Q_SLOTS:
/**
* Set the pin status
* @param iPin the pin status
*/
virtual void setPin(bool iPin);
/**
* Closes this widget
* @param iForce to close pinned pages too
* @return true if the widget was closed; otherwise returns false.
*/
virtual bool close(bool iForce = false);
private:
Q_DISABLE_COPY(SKGTabPage)
QString m_bookmarkID;
SKGTabPage::SKGPageHistoryItemList m_previousPages;
SKGTabPage::SKGPageHistoryItemList m_nextPages;
int m_fontOriginalPointSize;
bool m_pin;
};
#endif // SKGTABPAGE_H
diff --git a/skgbasegui/skgtabwidget.cpp b/skgbasegui/skgtabwidget.cpp
index 0a4f23d38..0f459883b 100644
--- a/skgbasegui/skgtabwidget.cpp
+++ b/skgbasegui/skgtabwidget.cpp
@@ -1,144 +1,144 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* A QTabWidget with more features.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgtabwidget.h"
#include <klocalizedstring.h>
#include <qicon.h>
#include <qpushbutton.h>
#include <qstringlist.h>
#include <qtabbar.h>
#include <qtimer.h>
#include "skgmainpanel.h"
#include "skgtabpage.h"
#include "skgtraces.h"
SKGTabWidget::SKGTabWidget(QWidget* iParent)
: QTabWidget(iParent)
{
m_timerSave.setSingleShot(true);
connect(&m_timerSave, &QTimer::timeout, this, &SKGTabWidget::onRefreshSaveIcon, Qt::QueuedConnection);
connect(tabBar(), &QTabBar::tabMoved, this, &::SKGTabWidget::onMoveTab);
if (iParent != nullptr) {
connect(qobject_cast<SKGMainPanel*>(iParent), &SKGMainPanel::currentPageChanged, this, &SKGTabWidget::onCurrentChanged);
}
// Use new KDE for moving tabs.
tabBar()->setMovable(true);
m_timerSave.start(1000);
}
SKGTabWidget::~SKGTabWidget()
= default;
void SKGTabWidget::onCurrentChanged()
{
if ((currentWidget() != nullptr) && !m_tabIndexSaveButton.contains(currentWidget())) {
// Build widgets
auto kSave = new QPushButton(this);
kSave->setIcon(SKGServices::fromTheme(QStringLiteral("document-save")));
kSave->setToolTip(i18nc("Verb", "Save this tab"));
kSave->setFlat(true);
kSave->setMaximumSize(QSize(16, 16));
kSave->show();
connect(kSave, &QPushButton::clicked, this, &SKGTabWidget::onSaveRequested);
tabBar()->setTabButton(currentIndex(), QTabBar::LeftSide, kSave);
m_tabIndexSaveButton.insert(currentWidget(), kSave);
}
// Rebuild indexes
QHash<QWidget*, QPushButton*> TabIndexSaveButton2;
int nb = count();
for (int i = 0; i < nb; ++i) {
QWidget* w = widget(i);
QPushButton* save = m_tabIndexSaveButton.value(w);
if ((w != nullptr) && (save != nullptr)) {
save->setVisible(false);
TabIndexSaveButton2[w] = save;
}
}
m_tabIndexSaveButton = TabIndexSaveButton2;
onRefreshSaveIcon();
}
void SKGTabWidget::removeTab(int index)
{
m_tabIndexSaveButton.clear();
QTabWidget::removeTab(index);
}
void SKGTabWidget::onMoveTab(int oldPos, int newPos)
{
Q_UNUSED(oldPos)
Q_UNUSED(newPos)
m_tabIndexSaveButton.clear();
onCurrentChanged();
}
void SKGTabWidget::onSaveRequested()
{
auto* page = qobject_cast<SKGTabPage*>(currentWidget());
if (page != nullptr) {
page->overwrite(false);
onRefreshSaveIcon();
}
}
void SKGTabWidget::onRefreshSaveIcon()
{
auto* page = qobject_cast<SKGTabPage*>(currentWidget());
if (page != nullptr) {
QPushButton* save = m_tabIndexSaveButton.value(page);
if (save != nullptr) {
if (page->isOverwriteNeeded()) {
save->show();
save->setEnabled(true);
QStringList overlay;
if (page->isPin()) {
overlay.push_back(QStringLiteral("document-encrypt"));
}
if (!page->getBookmarkID().isEmpty()) {
overlay.push_back(QStringLiteral("bookmarks"));
}
save->setIcon(SKGServices::fromTheme(QStringLiteral("document-save"), overlay));
} else if (page->isPin()) {
save->show();
save->setEnabled(false);
save->setIcon(SKGServices::fromTheme(QStringLiteral("document-encrypt")));
} else {
save->hide();
}
}
m_timerSave.start(1000);
}
}
diff --git a/skgbasegui/skgtabwidget.h b/skgbasegui/skgtabwidget.h
index e9cd699be..eb8b0f7a0 100644
--- a/skgbasegui/skgtabwidget.h
+++ b/skgbasegui/skgtabwidget.h
@@ -1,70 +1,70 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGTABWIDGET_H
#define SKGTABWIDGET_H
/** @file
* A QTabWidget with more features.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include <qhash.h>
#include <qtabwidget.h>
#include <qtimer.h>
#include "skgbasegui_export.h"
class QPushButton;
/**
* A QTabWidget with more features.
*/
class SKGBASEGUI_EXPORT SKGTabWidget : public QTabWidget
{
Q_OBJECT
public:
/**
* Default Constructor
* @param iParent the parent
*/
explicit SKGTabWidget(QWidget* iParent);
/**
* Default Destructor
*/
~SKGTabWidget() override;
public Q_SLOTS:
/**
* Remove a tab
* @param index the tab index
*/
virtual void removeTab(int index);
private Q_SLOTS:
void onCurrentChanged();
void onRefreshSaveIcon();
void onSaveRequested();
void onMoveTab(int oldPos, int newPos);
private:
QTimer m_timerSave;
QHash<QWidget*, QPushButton*> m_tabIndexSaveButton;
};
#endif // SKGTABWIDGET_H
diff --git a/skgbasegui/skgtreeview.cpp b/skgbasegui/skgtreeview.cpp
index fbd265f75..a36a0aa10 100644
--- a/skgbasegui/skgtreeview.cpp
+++ b/skgbasegui/skgtreeview.cpp
@@ -1,1441 +1,1441 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* A tree view with more features.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgtreeview.h"
#include <klocalizedstring.h>
#include <kstandardaction.h>
#include <qapplication.h>
#include <qbasictimer.h>
#include <qclipboard.h>
#include <qdesktopservices.h>
#include <qdom.h>
#include <qevent.h>
#include <qfileinfo.h>
#include <qheaderview.h>
#include <qicon.h>
#include <qmenu.h>
#include <qpainter.h>
#include <qprinter.h>
#include <qpushbutton.h>
#include <qsavefile.h>
#include <qscrollbar.h>
#include <qsvggenerator.h>
#include <qtextbrowser.h>
#include <qtextcodec.h>
#include <qtextdocumentwriter.h>
#include <qtextobject.h>
#include <qtexttable.h>
#include <qtimer.h>
#include <algorithm>
#include "skgdocument.h"
#include "skgerror.h"
#include "skgmainpanel.h"
#include "skgobjectbase.h"
#include "skgobjectmodelbase.h"
#include "skgpropertyobject.h"
#include "skgservices.h"
#include "skgsortfilterproxymodel.h"
#include "skgtableview.h"
#include "skgtraces.h"
#include "skgtransactionmng.h"
SKGTreeView::SKGTreeView(QWidget* iParent)
: QTreeView(iParent),
m_autoResize(true), m_autoResizeDone(false), m_actAutoResize(nullptr),
m_document(nullptr), m_textResizable(true),
m_model(nullptr), m_proxyModel(nullptr),
m_actGroupByNone(nullptr),
stickH(false), stickV(false)
{
// Initialize
setTextElideMode(Qt::ElideMiddle);
setAutoExpandDelay(300);
setAnimated(true);
m_timerDelayedResize.setSingleShot(true);
connect(&m_timerDelayedResize, &QTimer::timeout, this, &SKGTreeView::resizeColumnsToContents, Qt::QueuedConnection);
m_timerSelectionChanged.setSingleShot(true);
connect(&m_timerSelectionChanged, &QTimer::timeout, this, &SKGTreeView::selectionChangedDelayed, Qt::QueuedConnection);
m_timerScrollSelection.setSingleShot(true);
connect(&m_timerScrollSelection, &QTimer::timeout, this, &SKGTreeView::scroolOnSelection, Qt::QueuedConnection);
// Menu
QHeaderView* hori = header();
hori->setContextMenuPolicy(Qt::CustomContextMenu);
m_headerMenu = new QMenu(this);
setContextMenuPolicy(Qt::ActionsContextMenu);
connect(hori, &QHeaderView::customContextMenuRequested, this, static_cast<void (SKGTreeView::*)(const QPoint)>(&SKGTreeView::showHeaderMenu));
connect(hori, &QHeaderView::sortIndicatorChanged, this, &SKGTreeView::onSortChanged);
//
m_actCopy = KStandardAction::copy(this, SLOT(copy()), nullptr);
m_actCopy->setProperty("isShortcutConfigurable", false);
m_actCopy->setShortcutContext(Qt::WidgetShortcut);
m_actExpandAll = new QAction(SKGServices::fromTheme(QStringLiteral("format-indent-more")), i18nc("Noun, user action", "Expand all"), this);
m_actExpandAll->setShortcut(Qt::ALT + Qt::Key_Plus);
m_actExpandAll->setProperty("isShortcutConfigurable", false);
m_actExpandAll->setShortcutContext(Qt::WidgetShortcut);
connect(m_actExpandAll, &QAction::triggered, this, &SKGTreeView::expandAll);
m_actCollapseAll = new QAction(SKGServices::fromTheme(QStringLiteral("format-indent-less")), i18nc("Noun, user action", "Collapse all"), this);
m_actCollapseAll->setShortcut(Qt::ALT + Qt::Key_Minus);
m_actCollapseAll->setProperty("isShortcutConfigurable", false);
m_actCollapseAll->setShortcutContext(Qt::WidgetShortcut);
connect(m_actCollapseAll, &QAction::triggered, this, &SKGTreeView::collapseAll);
if (SKGMainPanel::getMainPanel() != nullptr) {
SKGMainPanel::getMainPanel()->registerGlobalAction(QStringLiteral("edit_copy"), m_actCopy);
SKGMainPanel::getMainPanel()->registerGlobalAction(QStringLiteral("edit_expandall"), m_actExpandAll);
SKGMainPanel::getMainPanel()->registerGlobalAction(QStringLiteral("edit_collapseall"), m_actCollapseAll);
}
// Scroll bars
connect(horizontalScrollBar(), &QScrollBar::actionTriggered, this, &SKGTreeView::onActionTriggered);
connect(verticalScrollBar(), &QScrollBar::actionTriggered, this, &SKGTreeView::onActionTriggered);
connect(horizontalScrollBar(), &QScrollBar::rangeChanged, this, &SKGTreeView::onRangeChanged);
connect(verticalScrollBar(), &QScrollBar::rangeChanged, this, &SKGTreeView::onRangeChanged);
// Headers
hori->setSectionsMovable(true);
hori->setSectionResizeMode(QHeaderView::Fixed);
setWordWrap(false);
connect(header(), &QHeaderView::sectionMoved, this, &SKGTreeView::setupHeaderMenu, Qt::QueuedConnection);
connect(this, &SKGTreeView::clicked, this, &SKGTreeView::onClick);
connect(this, &SKGTreeView::collapsed, this, &SKGTreeView::onCollapse);
connect(this, &SKGTreeView::expanded, this, &SKGTreeView::onExpand);
QWidget* vp = this->viewport();
if (vp != nullptr) {
vp->installEventFilter(this);
this->installEventFilter(this);
}
// Save original size
m_fontOriginalPointSize = this->font().pointSize();
m_iconOriginalSize = this->iconSize().height();
if (m_iconOriginalSize <= 0) {
m_iconOriginalSize = 16;
}
}
SKGTreeView::~SKGTreeView()
{
m_document = nullptr;
m_headerMenu = nullptr;
m_proxyModel = nullptr;
m_model = nullptr;
m_actExpandAll = nullptr;
m_actCollapseAll = nullptr;
}
bool SKGTreeView::isAutoResized()
{
return m_autoResize;
}
QString SKGTreeView::getState()
{
SKGTRACEINFUNC(10)
QDomDocument doc(QStringLiteral("SKGML"));
QDomElement root = doc.createElement(QStringLiteral("parameters"));
doc.appendChild(root);
QHeaderView* hHeader = header();
if ((hHeader != nullptr) && (m_model != nullptr)) {
if (isSortingEnabled()) {
root.setAttribute(QStringLiteral("sortOrder"), SKGServices::intToString(static_cast<int>(hHeader->sortIndicatorOrder())));
root.setAttribute(QStringLiteral("sortColumn"), m_model->getAttribute(hHeader->sortIndicatorSection()));
if (m_proxyModel != nullptr) {
root.setAttribute(QStringLiteral("sortPreviousColumn"), SKGServices::intToString(m_proxyModel->getPreviousSortColumn()));
}
}
root.setAttribute(QStringLiteral("groupBy"), m_groupby);
// Memorize order
int nb = hHeader->count();
if (nb != 0) {
QString columns;
QString columnsSize;
QString columnsVisibility;
for (int i = 0; i < nb; ++i) {
int idx = hHeader->logicalIndex(i);
if (i != 0) {
columns += ';';
}
columns += m_model->getAttribute(idx);
if (i != 0) {
columnsSize += ';';
}
columnsSize += SKGServices::intToString(hHeader->sectionSize(idx));
if (i != 0) {
columnsVisibility += ';';
}
columnsVisibility += (hHeader->isSectionHidden(idx) ? QStringLiteral("N") : QStringLiteral("Y"));
}
root.setAttribute(QStringLiteral("columns"), columns);
if (!m_autoResize) {
root.setAttribute(QStringLiteral("columnsSize"), columnsSize);
}
root.setAttribute(QStringLiteral("columnsVisibility"), columnsVisibility);
root.setAttribute(QStringLiteral("columnsAutoResize"), m_autoResize ? QStringLiteral("Y") : QStringLiteral("N"));
}
// Memorize expanded groups
if (!m_groupby.isEmpty()) {
root.setAttribute(QStringLiteral("expandedGroups"), m_expandedNodes.join(QStringLiteral(";")));
}
}
root.setAttribute(QStringLiteral("alternatingRowColors"), alternatingRowColors() ? QStringLiteral("Y") : QStringLiteral("N"));
root.setAttribute(QStringLiteral("zoomPosition"), SKGServices::intToString(zoomPosition()));
QScrollBar* scroll2 = horizontalScrollBar();
if ((scroll2 != nullptr) && scroll2->value() == scroll2->maximum() && scroll2->value() != scroll2->minimum()) {
root.setAttribute(QStringLiteral("stickH"), QStringLiteral("Y"));
}
scroll2 = verticalScrollBar();
if ((scroll2 != nullptr) && scroll2->value() == scroll2->maximum() && scroll2->value() != scroll2->minimum()) {
root.setAttribute(QStringLiteral("stickV"), QStringLiteral("Y"));
}
return doc.toString(-1);
}
void SKGTreeView::setState(const QString& iState)
{
SKGTRACEINFUNC(10)
resetColumnsOrder();
QDomDocument doc(QStringLiteral("SKGML"));
QString viewState = iState;
if (viewState.isEmpty() && (m_document != nullptr)) {
// Get default state
viewState = m_document->getParameter(m_parameterName);
}
Qt::SortOrder qtsortorder = Qt::AscendingOrder;
if (doc.setContent(viewState)) {
QDomElement root = doc.documentElement();
QString sortOrder = root.attribute(QStringLiteral("sortOrder"));
QString sortColumn = root.attribute(QStringLiteral("sortColumn"));
QString sortPreviousColumn = root.attribute(QStringLiteral("sortPreviousColumn"));
m_groupby = root.attribute(QStringLiteral("groupBy"));
QString columns = root.attribute(QStringLiteral("columns"));
QString columnsSize = root.attribute(QStringLiteral("columnsSize"));
QString columnsVisibility = root.attribute(QStringLiteral("columnsVisibility"));
QString columnsAutoResize = root.attribute(QStringLiteral("columnsAutoResize"));
QString alternatingRowColors2 = root.attribute(QStringLiteral("alternatingRowColors"));
QString zoomPositionString = root.attribute(QStringLiteral("zoomPosition"));
QString expandedGroups = root.attribute(QStringLiteral("expandedGroups"));
stickH = (root.attribute(QStringLiteral("stickH")) == QStringLiteral("Y"));
stickV = (root.attribute(QStringLiteral("stickV")) == QStringLiteral("Y"));
// Set column order
QStringList listAtt;
if (!columns.isEmpty()) {
listAtt = SKGServices::splitCSVLine(columns, ';');
QStringList sizes = SKGServices::splitCSVLine(columnsSize, ';');
QStringList visibilities = SKGServices::splitCSVLine(columnsVisibility, ';');
int nb = listAtt.count();
int nbvisibilities = visibilities.count();
int nbsizes = sizes.count();
for (int i = 0; i < nb; ++i) {
if (nbvisibilities == nb) {
listAtt[i] = listAtt.at(i) % '|' % visibilities.at(i);
if (nbsizes == nb) {
listAtt[i] = listAtt.at(i) % '|' % sizes.at(i);
}
}
}
}
if (m_model != nullptr) {
m_model->setSupportedAttributes(listAtt);
}
// Set autoResize
if (!columnsAutoResize.isEmpty()) {
m_autoResize = (columnsAutoResize == QStringLiteral("Y"));
header()->setSectionResizeMode(m_autoResize ? QHeaderView::Fixed : QHeaderView::Interactive);
if (!m_autoResize) {
m_timerDelayedResize.stop();
m_autoResizeDone = false;
}
}
// Set sort
if ((m_proxyModel != nullptr) && !sortPreviousColumn.isEmpty()) {
m_proxyModel->setPreviousSortColumn(SKGServices::stringToInt(sortPreviousColumn));
}
if ((m_model != nullptr) && isSortingEnabled() && !sortOrder.isEmpty() && !sortColumn.isEmpty()) {
int index = SKGServices::splitCSVLine(columns, ';').indexOf(sortColumn);
if (index == -1) {
index = m_model->getIndexAttribute(sortColumn);
}
if (index == -1) {
index = 0;
}
qtsortorder = static_cast<Qt::SortOrder>(SKGServices::stringToInt(sortOrder));
this->sortByColumn(index, qtsortorder);
}
if (m_model != nullptr) {
QString att = m_groupby;
if (att == QStringLiteral("#")) {
att = sortColumn;
}
m_model->setGroupBy(att);
m_model->dataModified();
refreshExpandCollapse();
}
// Set alternatingRowColors
if (!alternatingRowColors2.isEmpty()) {
setAlternatingRowColors(alternatingRowColors2 == QStringLiteral("Y"));
}
if (!zoomPositionString.isEmpty()) {
setZoomPosition(SKGServices::stringToInt(zoomPositionString));
}
// Set expanded groups
m_expandedNodes = SKGServices::splitCSVLine(expandedGroups);
resetSelection();
} else {
if (m_model != nullptr) {
m_model->setSupportedAttributes(QStringList());
m_groupby = QLatin1String("");
m_model->setGroupBy(m_groupby);
m_model->dataModified();
refreshExpandCollapse();
}
this->sortByColumn(0, qtsortorder);
}
}
void SKGTreeView::refreshExpandCollapse()
{
bool treeMode = !m_model->getParentChildAttribute().isEmpty();
setRootIsDecorated(treeMode && m_groupby.isEmpty());
if (m_actExpandAll != nullptr) {
m_actExpandAll->setVisible(treeMode || !m_groupby.isEmpty());
}
if (m_actCollapseAll != nullptr) {
m_actCollapseAll->setVisible(treeMode || !m_groupby.isEmpty());
}
}
void SKGTreeView::respanFirstColumns()
{
// Span groups
int nbRow = m_model->rowCount();
for (int row = 0; row < nbRow; ++row) {
this -> setFirstColumnSpanned(row, QModelIndex(), !m_groupby.isEmpty());
}
}
void SKGTreeView::onRangeChanged()
{
auto* scroll2 = qobject_cast<QScrollBar*>(sender());
if ((stickH && scroll2 == horizontalScrollBar()) || (stickV && scroll2 == verticalScrollBar())) {
scroll2->setValue(scroll2->maximum());
}
}
void SKGTreeView::onActionTriggered(int action)
{
auto* scroll2 = qobject_cast<QScrollBar*>(sender());
if ((scroll2 != nullptr) && action == QAbstractSlider::SliderToMaximum) {
if (scroll2 == horizontalScrollBar()) {
stickH = true;
}
if (scroll2 == verticalScrollBar()) {
stickV = true;
}
} else {
if (scroll2 == horizontalScrollBar()) {
stickH = false;
}
if (scroll2 == verticalScrollBar()) {
stickV = false;
}
}
}
void SKGTreeView::insertGlobalAction(const QString& iRegisteredAction)
{
if (iRegisteredAction.isEmpty()) {
auto sep = new QAction(this);
sep->setSeparator(true);
this->insertAction(nullptr, sep);
} else if (SKGMainPanel::getMainPanel() != nullptr) {
QAction* act = SKGMainPanel::getMainPanel()->getGlobalAction(iRegisteredAction);
this->insertAction(nullptr, act);
}
}
void SKGTreeView::resizeColumnsToContentsDelayed()
{
SKGTRACEINFUNC(10)
m_timerDelayedResize.start(300);
}
void SKGTreeView::resizeColumnsToContents()
{
SKGTRACEINFUNC(10) {
SKGTRACEIN(10, "SKGTreeView::resizeColumnsToContents-respanFirstColumns")
respanFirstColumns();
}
int nb = header()->count();
for (int i = nb - 1; i >= 0; --i) {
SKGTRACEIN(10, "SKGTreeView::resizeColumnsToContents-resizeColumnToContents(" + SKGServices::intToString(i) + ')')
if (!isColumnHidden(i)) {
resizeColumnToContents(i);
}
}
}
void SKGTreeView::showHeaderMenu()
{
showHeaderMenu(header()->mapFromGlobal(QCursor::pos()));
}
void SKGTreeView::showHeaderMenu(const QPoint iPos)
{
if (m_headerMenu != nullptr) {
m_headerMenu->popup(header()->mapToGlobal(iPos));
}
}
void SKGTreeView::setDefaultSaveParameters(SKGDocument* iDocument, const QString& iParameterName)
{
m_document = iDocument;
m_parameterName = iParameterName;
}
void SKGTreeView::setupHeaderMenu()
{
SKGTRACEINFUNC(10)
if ((m_model != nullptr) && m_model->isRefreshBlocked()) {
return;
}
setCornerWidget(nullptr);
if ((m_model != nullptr) && (m_headerMenu != nullptr)) {
// Corner button on tables to show the contextual menu
auto btn = new QPushButton(this);
btn->setIcon(SKGServices::fromTheme(QStringLiteral("configure")));
btn->setFocusPolicy(Qt::NoFocus);
connect(btn, &QPushButton::clicked, this, static_cast<void (SKGTreeView::*)()>(&SKGTreeView::showHeaderMenu));
setCornerWidget(btn);
m_headerMenu->clear();
// Processing
QMenu* columns = m_headerMenu->addMenu(i18nc("Noun, Menu name", "Columns"));
// Get current groupby column
QMenu* groupbymenu = nullptr;
QActionGroup* groupby = nullptr;
if (!m_model->getWhereClause().contains(QStringLiteral("ORDER BY"))) {
groupbymenu = m_headerMenu->addMenu(i18nc("Noun, Menu name", "Group by"));
groupby = new QActionGroup(groupbymenu);
m_actGroupByNone = groupbymenu->addAction(i18nc("Noun, grouping option", "None"));
if (m_actGroupByNone != nullptr) {
m_actGroupByNone->setIcon(SKGServices::fromTheme(QStringLiteral("dialog-cancel")));
m_actGroupByNone->setCheckable(true);
m_actGroupByNone->setChecked(m_groupby.isEmpty());
m_actGroupByNone->setData(QLatin1String(""));
groupby->addAction(m_actGroupByNone);
}
if (m_proxyModel != nullptr) {
QAction* actSort = groupbymenu->addAction(i18nc("Noun, grouping option", "Sorted column"));
if (actSort != nullptr) {
actSort->setIcon(SKGServices::fromTheme(QStringLiteral("view-sort-ascending")));
actSort->setCheckable(true);
actSort->setChecked(m_groupby == QStringLiteral("#"));
actSort->setData(QStringLiteral("#"));
groupby->addAction(actSort);
}
}
groupbymenu->addSeparator();
}
// Set right click menu
SKGDocument::SKGModelTemplateList schemas = m_model->getSchemas();
int nbSchemas = schemas.count();
if (nbSchemas != 0) {
QMenu* viewAppearanceMenu = columns->addMenu(SKGServices::fromTheme(QStringLiteral("view-file-columns")), i18nc("Noun, user action", "View appearance"));
for (int i = 0; i < nbSchemas; ++i) {
SKGDocument::SKGModelTemplate schema = schemas.at(i);
QAction* act = viewAppearanceMenu->addAction(schema.name);
if (!schema.icon.isEmpty()) {
act->setIcon(SKGServices::fromTheme(schema.icon));
}
act->setData(schema.schema);
connect(act, &QAction::triggered, this, &SKGTreeView::changeSchema);
}
}
QAction* actResize = columns->addAction(SKGServices::fromTheme(QStringLiteral("zoom-fit-width")), i18nc("Noun, user action", "Resize to content"));
connect(actResize, &QAction::triggered, this, &SKGTreeView::resizeColumnsToContents);
m_actAutoResize = columns->addAction(SKGServices::fromTheme(QStringLiteral("zoom-fit-width"), QStringList() << QStringLiteral("run-build")), i18nc("Noun, user action", "Auto resize"));
m_actAutoResize->setCheckable(true);
m_actAutoResize->setChecked(m_autoResize);
connect(m_actAutoResize, &QAction::triggered, this, &SKGTreeView::switchAutoResize);
QAction* actAlternatingRowColors = m_headerMenu->addAction(i18nc("Noun, user action", "Alternate row colors"));
if (actAlternatingRowColors != nullptr) {
actAlternatingRowColors->setCheckable(true);
actAlternatingRowColors->setChecked(alternatingRowColors());
connect(actAlternatingRowColors, &QAction::triggered, this, &SKGTreeView::setAlternatingRowColors);
}
if (m_document != nullptr) {
QAction* actDefault = m_headerMenu->addAction(SKGServices::fromTheme(QStringLiteral("document-save")), i18nc("Noun, user action", "Save parameters"));
connect(actDefault, &QAction::triggered, this, &SKGTreeView::saveDefaultClicked);
}
columns->addSeparator();
if (m_model != nullptr) {
// Build menus for columns
QHeaderView* hHeader = header();
int nbcol = hHeader->count();
for (int i = 0; i < nbcol; ++i) {
int idx = hHeader->logicalIndex(i);
QString col = m_model->headerData(idx, Qt::Horizontal, Qt::UserRole).toString();
QStringList values = col.split('|');
if (!m_autoResizeDone) {
if (values.count() > 1) {
hHeader->setSectionHidden(idx, values.at(1) == QStringLiteral("N"));
}
if (values.count() > 2) {
auto s = SKGServices::stringToInt(values.at(2));
if (s > 0) {
hHeader->resizeSection(idx, s);
}
}
}
// Column menu
QAction* act = columns->addAction(values.at(0));
if (act != nullptr) {
act->setCheckable(true);
act->setChecked(!hHeader->isSectionHidden(idx));
act->setIcon(m_model->headerData(idx, Qt::Horizontal, Qt::DecorationRole).value<QIcon>());
act->setData(idx);
act->setEnabled(i > 0);
connect(act, &QAction::triggered, this, &SKGTreeView::showHideColumn);
// Group by menu
QString att = m_model->getAttribute(idx);
if ((groupbymenu != nullptr) && (groupby != nullptr)) {
QAction* act2 = groupbymenu->addAction(values.at(0));
if (act2 != nullptr) {
act2->setCheckable(true);
act2->setChecked(att == m_groupby);
act2->setIcon(act->icon());
act2->setData(att);
groupby->addAction(act2);
}
}
}
}
m_autoResizeDone = true;
}
if (groupby != nullptr) {
connect(groupby, &QActionGroup::triggered, this, &SKGTreeView::groupByChanged);
}
m_headerMenu->addSeparator();
QAction* actExport = m_headerMenu->addAction(SKGServices::fromTheme(QStringLiteral("document-export")), i18nc("Noun, user action", "Export..."));
connect(actExport, &QAction::triggered, this, &SKGTreeView::onExport);
if (m_autoResize) {
resizeColumnsToContentsDelayed();
}
}
}
void SKGTreeView::setSelectionModel(QItemSelectionModel* iSelectionModel)
{
if (this->selectionModel() != nullptr) {
disconnect(this->selectionModel(), &QItemSelectionModel::selectionChanged, this, &SKGTreeView::onSelectionChanged);
}
QTreeView::setSelectionModel(iSelectionModel);
if (iSelectionModel != nullptr) {
connect(iSelectionModel, &QItemSelectionModel::selectionChanged, this, &SKGTreeView::onSelectionChanged);
}
}
void SKGTreeView::onSelectionChanged()
{
SKGTRACEINFUNC(10)
SKGObjectBase::SKGListSKGObjectBase selection;
SKGObjectBase::SKGListSKGObjectBase selectionparents;
QItemSelectionModel* selModel = selectionModel();
if (selModel != nullptr) {
if (m_model != nullptr) {
auto indexes = selModel->selectedRows();
int nb = indexes.count();
QVector<QModelIndex> indexesToSource;
indexesToSource.reserve(indexes.count());
for (const auto& index : qAsConst(indexes)) {
indexesToSource.push_back(m_proxyModel != nullptr ? m_proxyModel->mapToSource(index) : index);
}
selection.reserve(indexesToSource.count());
selectionparents.reserve(nb);
for (int i = 0; i < nb; ++i) {
QModelIndex index = indexes.at(i);
QModelIndex idxs = indexesToSource.at(i);
// Get above
QModelIndex idxtmp = (m_proxyModel != nullptr ? m_proxyModel->mapToSource(indexAbove(index)) : indexAbove(index));
auto* tmp = m_model->getObjectPointer(idxtmp);
if (tmp != nullptr && idxtmp.parent() == idxs.parent() && !indexesToSource.contains(idxtmp)) {
selectionparents.push_back(*tmp);
} else {
// Get below
idxtmp = (m_proxyModel != nullptr ? m_proxyModel->mapToSource(indexBelow(index)) : indexBelow(index));
tmp = m_model->getObjectPointer(idxtmp);
if (tmp != nullptr && idxtmp.parent() == idxs.parent() && !indexesToSource.contains(idxtmp)) {
selectionparents.push_back(*tmp);
} else {
// Get parent
tmp = m_model->getObjectPointer(idxs.parent());
if (tmp != nullptr) {
selectionparents.push_back(*tmp);
}
}
}
SKGObjectBase obj = m_model->getObject(idxs);
selection.push_back(obj);
}
}
}
// if (selection != m_lastSelection) { // WARNING: selection can be equal but attributes of selected objects modified
m_lastSelection = selection;
m_lastSelection_if_deleted = selectionparents;
m_timerSelectionChanged.start(300);
// }
}
void SKGTreeView::saveDefaultClicked()
{
if (m_document != nullptr) {
SKGError err;
SKGBEGINTRANSACTION(*m_document, i18nc("Noun, name of the user action", "Save default parameters"), err)
err = m_document->setParameter(m_parameterName, getState());
}
}
void SKGTreeView::switchAutoResize()
{
m_autoResize = m_actAutoResize->isChecked();
header()->setSectionResizeMode(m_autoResize ? QHeaderView::Fixed : QHeaderView::Interactive);
if (m_autoResize) {
resizeColumnsToContentsDelayed();
} else {
m_timerDelayedResize.stop();
m_autoResizeDone = false;
}
}
void SKGTreeView::groupByChanged(QAction* iAction)
{
if ((m_model != nullptr) && m_model->isRefreshBlocked()) {
return;
}
if ((iAction != nullptr) && (m_model != nullptr)) {
m_groupby = iAction->data().toString();
QString att = m_groupby;
if (att == QStringLiteral("#") && (m_proxyModel != nullptr)) {
att = m_model->getAttribute(m_proxyModel->sortColumn());
}
m_model->setGroupBy(att);
m_model->refresh();
refreshExpandCollapse();
respanFirstColumns();
}
}
void SKGTreeView::onSortChanged(int iIndex, Qt::SortOrder iOrder)
{
Q_UNUSED(iOrder)
if (m_groupby == QStringLiteral("#") && (m_model != nullptr)) {
m_model->setGroupBy(m_model->getAttribute(iIndex));
m_model->refresh();
}
m_timerScrollSelection.start(300);
}
void SKGTreeView::showHideColumn()
{
auto* send = qobject_cast<QAction*>(this->sender());
if (send != nullptr) {
QHeaderView* hHeader = header();
int idx = send->data().toInt();
bool hidden = !hHeader->isSectionHidden(idx);
hHeader->setSectionHidden(idx, hidden);
}
}
void SKGTreeView::resetColumnsOrder()
{
QHeaderView* hHeader = header();
int nbcol = hHeader->count();
for (int i = 0; i < nbcol; ++i) {
int idx = hHeader->visualIndex(i);
if (idx != i) {
hHeader->moveSection(idx, i);
}
}
}
void SKGTreeView::changeSchema()
{
QStringList list;
auto* send = qobject_cast<QAction*>(this->sender());
if (send != nullptr) {
list = SKGServices::splitCSVLine(send->data().toString(), ';');
}
if (m_model != nullptr) {
// Reset column oder
resetColumnsOrder();
m_model->setSupportedAttributes(list);
bool tmp = m_autoResizeDone;
m_autoResizeDone = false;
m_model->dataModified();
m_autoResizeDone = tmp;
header()->setSortIndicator(0, Qt::AscendingOrder);
}
}
QStringList SKGTreeView::getCurrentSchema() const
{
QStringList list;
QHeaderView* hHeader = header();
if ((hHeader != nullptr) && (m_model != nullptr)) {
int nb = hHeader->count();
if (nb != 0) {
QString att;
for (int i = 0; i < nb; ++i) {
int idx = hHeader->logicalIndex(i);
att = m_model->getAttribute(idx);
att += QStringLiteral("|") % (hHeader->isSectionHidden(idx) ? QStringLiteral("N") : QStringLiteral("Y"));
att += QStringLiteral("|") % SKGServices::intToString(hHeader->sectionSize(idx));
list.push_back(att);
}
}
}
return list;
}
void SKGTreeView::setAlternatingRowColors(bool enable)
{
QTreeView::setAlternatingRowColors(enable);
}
SKGObjectBase SKGTreeView::getFirstSelectedObject()
{
return m_lastSelection.value(0);
}
SKGObjectBase::SKGListSKGObjectBase SKGTreeView::getSelectedObjects()
{
return m_lastSelection;
}
int SKGTreeView::getNbSelectedObjects()
{
return m_lastSelection.count();
}
void SKGTreeView::saveSelection()
{
SKGTRACEINFUNC(10)
m_selection.clear();
SKGObjectBase::SKGListSKGObjectBase objs = getSelectedObjects();
int nb = objs.count();
// We save the selection only if not too big
if (nb <= 100) {
for (int i = 0; i < nb; ++i) {
QString id = objs.at(i).getUniqueID();
m_selection.push_back(id);
}
}
SKGTRACEL(10) << m_selection.count() << " objects saved" << endl;
}
void SKGTreeView::selectObject(const QString& iUniqueID)
{
SKGTRACEINFUNC(10)
QStringList tmp;
tmp.push_back(iUniqueID);
selectObjects(tmp, true);
}
void SKGTreeView::selectObjects(const QStringList& iUniqueIDs, bool iFocusOnFirstOne)
{
SKGTRACEINFUNC(10)
SKGTRACEL(10) << iUniqueIDs.count() << " objects to select" << endl;
int nbset = 0;
QItemSelectionModel* selModel = selectionModel();
if (selModel != nullptr) {
bool previous = selModel->blockSignals(true);
selModel->clearSelection();
if (m_model != nullptr) {
// Get all indexes
QVector<QModelIndex> items;
items.reserve(items.count() * 2);
items.push_back(QModelIndex());
for (int i = 0; i < items.count(); ++i) { // Dynamic size because the list is modified
QModelIndex mi = items.at(i);
int nbRows = m_model->rowCount(mi);
for (int j = 0; j < nbRows; ++j) {
items.push_back(m_model->index(j, 0, mi));
}
}
items.removeAt(0);
int nbRows = items.count();
if (nbRows != 0) {
// Expand nodes
bool previousForThis = this->blockSignals(true);
for (int i = 0; i < nbRows; ++i) {
QModelIndex index = items.at(i);
SKGObjectBase obj = m_model->getObject(index);
if (m_expandedNodes.contains(obj.getUniqueID())) {
QModelIndex idxs = (m_proxyModel != nullptr ? m_proxyModel->mapFromSource(index) : index);
setExpanded(idxs, true);
}
}
this->blockSignals(previousForThis);
// Set selection
bool focusDone = false;
for (int i = 0; i < nbRows; ++i) {
QModelIndex index = items.at(i);
SKGObjectBase obj = m_model->getObject(index);
if (iUniqueIDs.contains(obj.getUniqueID())) {
QModelIndex idxs = (m_proxyModel != nullptr ? m_proxyModel->mapFromSource(index) : index);
selModel->select(idxs, QItemSelectionModel::Select | QItemSelectionModel::Rows);
selModel->setCurrentIndex(idxs, QItemSelectionModel::NoUpdate);
++nbset;
if (iFocusOnFirstOne && !focusDone) {
scrollTo(idxs);
focusDone = true;
}
}
}
}
}
selModel->blockSignals(previous);
}
SKGTRACEL(10) << nbset << " objects selected" << endl;
onSelectionChanged();
}
void SKGTreeView::resetSelection()
{
SKGTRACEINFUNC(10)
auto lastSelection_parents_save = m_lastSelection_if_deleted; // because selectObjects will modify m_lastSelection_if_deleted
selectObjects(m_selection);
if ((lastSelection_parents_save.count() != 0) && (getSelectedObjects().count() == 0)) {
// Try to select parent objects
int nb = lastSelection_parents_save.count();
// We save the selection only if not too big
if (nb <= 100) {
QStringList sel;
sel.reserve(nb);
for (int i = 0; i < nb; ++i) {
QString id = lastSelection_parents_save.at(i).getUniqueID();
sel.push_back(id);
}
selectObjects(sel);
}
}
}
void SKGTreeView::scroolOnSelection()
{
QItemSelectionModel* selModel = selectionModel();
if (selModel != nullptr) {
if (m_model != nullptr) {
QModelIndexList indexes = selModel->selectedRows();
if (!indexes.isEmpty()) {
scrollTo(indexes.at(0));
}
}
}
}
void SKGTreeView::onExpand(const QModelIndex& index)
{
SKGTRACEINFUNC(10)
if (index.isValid() && (m_model != nullptr)) {
QModelIndex idxs = (m_proxyModel != nullptr ? m_proxyModel->mapToSource(index) : index);
SKGObjectBase obj = m_model->getObject(idxs);
QString id = obj.getUniqueID();
m_expandedNodes.push_back(id);
}
if (m_autoResize) {
resizeColumnsToContentsDelayed();
}
}
void SKGTreeView::expandAll()
{
SKGTRACEINFUNC(10)
QTreeView::expandAll();
if (m_autoResize) {
resizeColumnsToContentsDelayed();
}
}
void SKGTreeView::onCollapse(const QModelIndex& index)
{
SKGTRACEINFUNC(10)
if (index.isValid() && (m_model != nullptr)) {
QModelIndex idxs = (m_proxyModel != nullptr ? m_proxyModel->mapToSource(index) : index);
SKGObjectBase obj = m_model->getObject(idxs);
QString id = obj.getUniqueID();
m_expandedNodes.removeOne(id);
}
if (m_autoResize) {
resizeColumnsToContentsDelayed();
}
}
void SKGTreeView::onClick(const QModelIndex& index)
{
SKGTRACEINFUNC(10)
if (index.isValid() && (m_actExpandAll != nullptr) && m_actExpandAll->isVisible()) {
this->setExpanded(index, !this->isExpanded(index));
}
}
void SKGTreeView::copy()
{
QItemSelectionModel* selection = selectionModel();
if (selection != nullptr) {
QModelIndexList indexes = selection->selectedIndexes();
if (indexes.empty()) {
return;
}
std::sort(indexes.begin(), indexes.end());
// You need a pair of indexes to find the row changes
QModelIndex previous = indexes.first();
indexes.removeFirst();
bool header_done = false;
QStringList colums_title;
colums_title.reserve(indexes.count());
SKGStringListList columns_values;
int index = 0;
for (const auto& current : qAsConst(indexes)) {
if (columns_values.count() < index + 1) {
columns_values.append(QStringList());
columns_values.append(QStringList());
}
columns_values[index].append(model()->data(previous).toString());
columns_values[index + 1].append(model()->data(previous, Qt::UserRole).toString());
if (!header_done) {
auto header_title = model()->headerData(previous.column(), Qt::Horizontal).toString();
if (header_title.isEmpty()) {
header_title = SKGServices::splitCSVLine(model()->headerData(previous.column(), Qt::Horizontal, Qt::UserRole).toString(), QLatin1Char('|')).at(0);
}
colums_title.append(header_title);
colums_title.append(header_title + QLatin1String("_raw"));
}
if (current.row() != previous.row()) {
index = 0;
header_done = true;
} else {
index = index + 2;
}
previous = current;
}
// Add last element
if (columns_values.count() < index + 1) {
columns_values.append(QStringList());
columns_values.append(QStringList());
}
columns_values[index].append(model()->data(previous).toString());
columns_values[index + 1].append(model()->data(previous, Qt::UserRole).toString());
// Remove useless raw columns (when all raw values = displayed values)
int nbCols = columns_values.count();
int nbRows = 0;
if (nbCols > 0) {
nbRows = columns_values.at(0).count();
for (int c = nbCols - 1; c >= 0; c = c - 2) {
bool allEqual = true;
bool allDisplayedEmpty = true;
auto displayedValues = columns_values.at(c - 1);
auto rawValues = columns_values.at(c);
for (int r = 0; r < nbRows; ++r) {
if (!displayedValues.at(r).isEmpty()) {
allDisplayedEmpty = false;
}
if (rawValues.at(r) != displayedValues.at(r)) {
allEqual = false;
}
}
// Remove the raw column
if (allEqual) {
// Remove the useless raw column
colums_title.removeAt(c);
columns_values.removeAt(c);
nbCols--;
} else if (allDisplayedEmpty) {
// Remove the empty column and keep the raw version
colums_title.removeAt(c - 1);
columns_values.removeAt(c - 1);
nbCols--;
}
}
}
// Build text
QString text = colums_title.join(QLatin1Char(';')) + QLatin1Char('\n');
if (nbCols > 0) {
for (int r = 0; r < nbRows; ++r) {
for (int c = 0; c < nbCols; ++c) {
if (c != 0) {
text += QLatin1Char(';');
}
text += columns_values.at(c).at(r);
}
text += QLatin1Char('\n');
}
}
auto clipBoard = QApplication::clipboard();
if (clipBoard != nullptr) {
clipBoard->setText(text);
}
}
}
void SKGTreeView::setZoomPosition(int iZoomPosition)
{
int newZoomPos = qMax(qMin(iZoomPosition, 10), -10);
if (newZoomPos != zoomPosition() && m_fontOriginalPointSize + newZoomPos > 1) {
QFont newFont = this->font();
newFont.setPointSize(m_fontOriginalPointSize + newZoomPos);
int newIconSize = qMax(m_iconOriginalSize + newZoomPos, 1);
this->setFont(newFont);
this->setIconSize(QSize(newIconSize, newIconSize));
header()->setIconSize(QSize(newIconSize, newIconSize));
if (m_autoResize) {
resizeColumnsToContentsDelayed();
}
Q_EMIT zoomChanged(newZoomPos);
}
}
int SKGTreeView::zoomPosition()
{
return this->font().pointSize() - m_fontOriginalPointSize;
}
bool SKGTreeView::eventFilter(QObject* iObject, QEvent* iEvent)
{
if (iObject == this && iEvent != nullptr && iEvent->type() == QEvent::Wheel) {
auto* e = dynamic_cast<QWheelEvent*>(iEvent);
if (m_textResizable && (e != nullptr) && e->orientation() == Qt::Vertical && ((QApplication::keyboardModifiers() &Qt::ControlModifier) != 0u)) {
int numDegrees = e->delta() / 8;
int numTicks = numDegrees / 15;
setZoomPosition(zoomPosition() + (numTicks > 0 ? 1 : -1));
e->setAccepted(true);
return true;
}
}
if (iObject == this && iEvent != nullptr && iEvent->type() == QEvent::KeyPress) {
auto* kevent = dynamic_cast<QKeyEvent*>(iEvent);
if (kevent != nullptr) {
if (kevent->matches(QKeySequence::Copy) && this->state() != QAbstractItemView::EditingState) {
copy();
if (iEvent != nullptr) {
iEvent->accept();
}
return true; // stop the process
}
}
}
return QTreeView::eventFilter(iObject, iEvent);
}
void SKGTreeView::mousePressEvent(QMouseEvent* iEvent)
{
if ((iEvent != nullptr) && iEvent->button() == Qt::LeftButton && !(this->indexAt(iEvent->pos()).isValid())) {
Q_EMIT clickEmptyArea();
clearSelection();
}
if ((iEvent != nullptr) && iEvent->button() == Qt::LeftButton && (m_proxyModel != nullptr) && (m_model != nullptr)) {
int propertyUUID = m_proxyModel->data(indexAt(iEvent->pos()), 101).toInt();
if (propertyUUID != 0) {
SKGPropertyObject prop(m_model->getDocument(), propertyUUID);
QDesktopServices::openUrl(prop.getUrl(true));
}
}
QTreeView::mousePressEvent(iEvent);
}
bool SKGTreeView::isTextResizable() const
{
return m_textResizable;
}
void SKGTreeView::setTextResizable(bool resizable)
{
if (m_textResizable != resizable) {
m_textResizable = resizable;
Q_EMIT modified();
}
}
QTextBrowser* SKGTreeView::getTextBrowser() const
{
auto output = new QTextBrowser();
QTextCursor tcursor = output->textCursor();
tcursor.beginEditBlock();
// Create table format
QTextTableFormat tableFormat;
tableFormat.setAlignment(Qt::AlignHCenter);
tableFormat.setAlignment(Qt::AlignLeft);
tableFormat.setBackground(QColor(255, 255, 255));
tableFormat.setCellPadding(5);
tableFormat.setCellSpacing(5);
// Create table
SKGStringListList table = getTable();
int nbRows = table.count();
int nbCol = table.at(0).count();
QTextTable* tableau = tcursor.insertTable(nbRows, nbCol, tableFormat);
// Create frame
QTextFrame* frame = tcursor.currentFrame();
QTextFrameFormat frameFormat = frame->frameFormat();
frameFormat.setBorder(0);
frame->setFrameFormat(frameFormat);
// Create header table format
QTextCharFormat headerFormat;
headerFormat.setFontPointSize(6);
headerFormat.setFontWeight(QFont::Bold);
// Create text format
QTextCharFormat textFormat;
textFormat.setFontPointSize(6);
// Create header
for (int r = 0; r < nbRows; ++r) {
const QStringList& line = table.at(r);
for (int c = 0 ; c < nbCol ; ++c) {
QTextCursor cellCursor = tableau->cellAt(r, c).firstCursorPosition();
cellCursor.insertText(line.at(c), (r == 0 ? headerFormat : textFormat));
}
}
// End
tcursor.endEditBlock();
return output;
}
SKGStringListList SKGTreeView::getTable(const QModelIndex& iIndex) const
{
// Build table
SKGStringListList table;
// Get header names
if (m_model != nullptr) {
// Header
int nb = m_model->columnCount();
int nb2 = m_model->rowCount(iIndex);
table.reserve(1 + nb2 * 2);
if (!iIndex.isValid()) {
QStringList cols;
cols.reserve(nb);
for (int i = 0; i < nb; ++i) {
cols.append(m_model->headerData(i, Qt::Horizontal, Qt::UserRole).toString().split('|').at(0));
}
table.append(cols);
}
// Get content
for (int i = 0; i < nb2; ++i) {
QStringList row;
row.reserve(nb);
for (int j = 0; j < nb; j++) {
// We have to check the type for 214849
QModelIndex idx = m_model->index(i, j, iIndex);
SKGServices::AttributeType type = m_model->getAttributeType(j);
QString display = m_model->data(idx, type == SKGServices::FLOAT || m_model->getObject(idx).getTable().isEmpty() ? Qt::DisplayRole : Qt::UserRole).toString();
if (display.isEmpty()) {
display = m_model->data(idx, Qt::DisplayRole).toString();
}
row.append(display);
}
table.append(row);
QModelIndex idx0 = m_model->index(i, 0, iIndex);
if (m_model->hasChildren(idx0)) {
table.append(getTable(idx0));
}
}
}
return table;
}
SKGError SKGTreeView::exportInFile(const QString& iFileName)
{
SKGError err;
_SKGTRACEINFUNC(10)
QString codec = QTextCodec::codecForLocale()->name();
QString extension = QFileInfo(iFileName).suffix().toUpper();
if (extension == QStringLiteral("CSV")) {
// Write file
QSaveFile file(iFileName);
if (!file.open(QIODevice::WriteOnly)) {
err.setReturnCode(ERR_INVALIDARG).setMessage(i18nc("Error message", "Save file '%1' failed", iFileName));
} else {
QTextStream out(&file);
out.setCodec(codec.toLatin1().constData());
QStringList dump = SKGServices::tableToDump(getTable(), SKGServices::DUMP_CSV);
int nbl = dump.count();
for (int i = 0; i < nbl; ++i) {
out << dump.at(i) << endl;
}
// Close file
file.commit();
}
} else if (extension == QStringLiteral("PDF")) {
QImage image(this->size(), QImage::Format_ARGB32);
QPainter painter(&image);
this->render(&painter);
painter.end();
{
QPrinter printer(QPrinter::HighResolution);
printer.setOutputFileName(iFileName);
QPainter newPainter(&printer);
QRect painterRect = newPainter.viewport();
QSize imageSize = image.size();
imageSize.scale(painterRect.size(), Qt::KeepAspectRatio);
newPainter.setViewport(painterRect.x(), painterRect.y(), imageSize.width(), imageSize.height());
newPainter.setWindow(image.rect());
newPainter.drawImage(0, 0, image);
newPainter.end();
}
} else if (extension == QStringLiteral("SVG")) {
QSvgGenerator generator;
generator.setFileName(iFileName);
generator.setTitle(i18nc("Title of the content SVG export", "Skrooge SVG export"));
generator.setDescription(i18nc("Description of the content SVG export", "A SVG drawing created by the Skrooge."));
QPainter painter(&generator);
QWidget* w = this->viewport();
w->render(&painter);
generator.setSize(QSize(w->widthMM(), w->heightMM()));
generator.setViewBox(QRect(0, 0, w->widthMM(), w->heightMM()));
painter.end();
} else if (extension == QStringLiteral("HTML")) {
// Write file
QSaveFile file(iFileName);
if (!file.open(QIODevice::WriteOnly)) {
err.setReturnCode(ERR_INVALIDARG).setMessage(i18nc("Error message", "Save file '%1' failed", iFileName));
} else {
QTextStream out(&file);
out.setCodec(codec.toLatin1().constData());
QTextBrowser* tb = getTextBrowser();
if (tb != nullptr) {
out << tb->toHtml().replace(QStringLiteral("<meta name=\"qrichtext\" content=\"1\" />"), QStringLiteral("<meta http-equiv=\"content-type\" content=\"text/html; charset=utf-8\" />")) << endl;
delete tb;
}
// Close file
file.commit();
}
} else if (extension == QStringLiteral("ODT")) {
QTextBrowser* tb = getTextBrowser();
if (tb != nullptr) {
QTextDocument doc;
doc.setHtml(tb->toHtml());
QTextDocumentWriter docWriter(iFileName);
docWriter.write(&doc);
delete tb;
}
} else {
// Write file
QSaveFile file(iFileName);
if (!file.open(QIODevice::WriteOnly)) {
err.setReturnCode(ERR_INVALIDARG).setMessage(i18nc("Error message", "Save file '%1' failed", iFileName));
} else {
QTextStream out(&file);
out.setCodec(codec.toLatin1().constData());
QStringList dump = SKGServices::tableToDump(getTable(), SKGServices::DUMP_TEXT);
int nbl = dump.count();
for (int i = 0; i < nbl; ++i) {
out << dump.at(i) << endl;
}
// Close file
file.commit();
}
}
return err;
}
void SKGTreeView::onExport()
{
_SKGTRACEINFUNC(10)
QString fileName = SKGMainPanel::getSaveFileName(QStringLiteral("kfiledialog:///IMPEXP"), QStringLiteral("text/csv text/plain text/html application/vnd.oasis.opendocument.text image/svg+xml application/pdf"), this);
if (!fileName.isEmpty()) {
SKGError err = exportInFile(fileName);
SKGMainPanel::displayErrorMessage(err);
QDesktopServices::openUrl(QUrl::fromLocalFile(fileName));
}
}
void SKGTreeView::setModel(QAbstractItemModel* iModel)
{
if (iModel != this->model()) {
m_model = qobject_cast<SKGObjectModelBase*>(iModel);
m_proxyModel = qobject_cast<SKGSortFilterProxyModel*> (iModel);
if (m_proxyModel != nullptr) {
m_model = qobject_cast<SKGObjectModelBase*>(m_proxyModel->sourceModel());
}
if (m_model != nullptr) {
connect(m_model, &SKGObjectModelBase::afterReset, this, &SKGTreeView::setupHeaderMenu);
// connect(m_model, &SKGObjectModelBase::afterReset, this, &SKGTreeView::onSelectionChanged);
connect(m_model, &SKGObjectModelBase::afterReset, this, &SKGTreeView::respanFirstColumns, Qt::QueuedConnection);
}
QTreeView::setModel(iModel);
rebuildContextualMenu();
refreshExpandCollapse();
}
}
QMenu* SKGTreeView::getHeaderMenu() const
{
return m_headerMenu;
}
void SKGTreeView::rebuildContextualMenu()
{
// Remove all Actions
const auto list = actions();
for (auto act : list) {
removeAction(act);
}
if (selectionMode() != NoSelection) {
// Build contextual menu
this->insertAction(nullptr, m_actCopy);
this->insertAction(nullptr, m_actExpandAll);
this->insertAction(nullptr, m_actCollapseAll);
if ((m_model != nullptr) && (SKGMainPanel::getMainPanel() != nullptr)) {
const auto list = SKGMainPanel::getMainPanel()->getActionsForContextualMenu(m_model->getRealTable());
for (const auto& act : list) {
if (act == nullptr) {
insertGlobalAction();
} else {
insertAction(nullptr, act);
}
}
}
}
}
diff --git a/skgbasegui/skgtreeview.h b/skgbasegui/skgtreeview.h
index d054d6f9c..5ddc4edad 100644
--- a/skgbasegui/skgtreeview.h
+++ b/skgbasegui/skgtreeview.h
@@ -1,358 +1,358 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGTREEVIEW_H
#define SKGTREEVIEW_H
/** @file
* A tree view with more features.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include <qmenu.h>
#include <qstringlist.h>
#include <qtreeview.h>
#include "skgbasegui_export.h"
#include "skgmainpanel.h"
#include "skgobjectbase.h"
#include "skgservices.h"
#include "skgtraces.h"
class SKGObjectModelBase;
class SKGDocument;
class QTextBrowser;
class SKGSortFilterProxyModel;
class QTimer;
/**
* This file is a tab widget used by plugins
*/
class SKGBASEGUI_EXPORT SKGTreeView : public QTreeView
{
Q_OBJECT
/**
* Text resizable by CTRL+wheel
*/
Q_PROPERTY(bool textResizable READ isTextResizable WRITE setTextResizable NOTIFY modified)
/**
* Auto resize mode of the view
*/
Q_PROPERTY(bool autoResized READ isAutoResized CONSTANT)
public:
/**
* Default Constructor
* @param iParent the parent
*/
explicit SKGTreeView(QWidget* iParent);
/**
* Default Destructor
*/
~SKGTreeView() override;
/**
* Get the current state
* @return a string containing all information needed to set the same state.
* Could be an XML stream
*/
virtual QString getState();
/**
* Set the current state
* MUST BE OVERWRITTEN
* @param iState must be interpreted to set the state of the widget
*/
virtual void setState(const QString& iState);
/**
* To know if the autoresized mode is enable
*/
virtual bool isAutoResized();
/**
* Set parameter to activate and save default state of this table
* @param iDocument document pointer
* @param iParameterName parameter name in this document
*/
virtual void setDefaultSaveParameters(SKGDocument* iDocument, const QString& iParameterName);
/**
* Get the table content as QTextBrowser
* @return the table content (MUST BE DELETED)
*/
virtual QTextBrowser* getTextBrowser() const;
/**
* Get the table content
* @param iIndex the line index
* @return the table content
*/
virtual SKGStringListList getTable(const QModelIndex& iIndex = QModelIndex()) const;
/**
* Get the current selection
* @return selected objects
*/
virtual SKGObjectBase::SKGListSKGObjectBase getSelectedObjects();
/**
* Get the first selected object
* @return first selected object
*/
virtual SKGObjectBase getFirstSelectedObject();
/**
* Get the number of selected object
* @return number of selected objects
*/
virtual int getNbSelectedObjects();
/**
* Sets the current selection model to the given selectionModel.
* @param iSelectionModel the selection model
*/
void setSelectionModel(QItemSelectionModel* iSelectionModel) override;
/**
* Insert a registered action
* @see SKGMainPanel::registerGlobalAction
* @param iRegisteredAction the registered action. "" means separator
*/
virtual void insertGlobalAction(const QString& iRegisteredAction = QString());
/**
* @brief Set model
*
* @param iModel the model
* @return void
**/
void setModel(QAbstractItemModel* iModel) override;
/**
* @brief Get the header menu
* @return the header menu
**/
virtual QMenu* getHeaderMenu() const;
/**
* Export to a file
* @param iFileName the file name
* @return an object managing the error
* @see SKGError
*/
virtual SKGError exportInFile(const QString& iFileName);
/**
* Get the current schema
* @return the current schema
*/
virtual QStringList getCurrentSchema() const;
/**
* Get the property to know if text is resizable
* @return the property
*/
virtual bool isTextResizable() const;
public Q_SLOTS:
/**
* This property holds whether to autorize text size modification by CTRL+wheel.
* @param resizable true of false
*/
virtual void setTextResizable(bool resizable);
/**
* Set the zoom position.
* @param iZoomPosition zoom position (-10<=zoom position<=10)
*/
virtual void setZoomPosition(int iZoomPosition);
/**
* Get zoom position
* @return zoom position (-10<=zoom position<=10)
*/
virtual int zoomPosition();
/**
* Save the selection
*/
virtual void saveSelection();
/**
* Reset the selection
*/
virtual void resetSelection();
/**
* Scroll on selected lines.
*/
virtual void scroolOnSelection();
/**
* Select an object and focus on it
* @param iUniqueID unique ID of the object
*/
virtual void selectObject(const QString& iUniqueID);
/**
* Select objects and focus on the first one
* @param iUniqueIDs unique IDs of objects
* @param iFocusOnFirstOne set the focus on the first one
*/
virtual void selectObjects(const QStringList& iUniqueIDs, bool iFocusOnFirstOne = false);
/**
* This property holds whether to draw the background using alternating colors.
* @param enable true of false
*/
virtual void setAlternatingRowColors(bool enable);
/**
* Reset columns order
*/
virtual void resetColumnsOrder();
/**
* Resizes all columns based on the size hints of the delegate used to render each item in the columns.
*/
virtual void resizeColumnsToContents();
/**
* Resizes all columns based on the size hints of the delegate used to render each item in the columns.
*/
virtual void resizeColumnsToContentsDelayed();
/**
* When the selection changed
*/
virtual void onSelectionChanged();
/**
* Expand all and resize columns if needed
*/
virtual void expandAll();
/**
* Copy selection in clipboard
*/
virtual void copy();
/**
* Switch auto resize
*/
virtual void switchAutoResize();
protected:
/**
* This function is called with the given event when a mouse button is pressed while the cursor is inside the widget.
* If a valid item is pressed on it is made into the current item. This function emits the pressed() signal.
* @param iEvent the event
*/
void mousePressEvent(QMouseEvent* iEvent) override;
Q_SIGNALS:
/**
* Emitted when the empty area
*/
void clickEmptyArea();
/**
* Emitted 300ms after selection changed
*/
void selectionChangedDelayed();
/**
* Emitted when zoom changed
* @param iZoomPosition zoom position (-10<=zoom position<=10)
*/
void zoomChanged(int iZoomPosition);
/**
* When properties are modified
*/
void modified();
protected:
/**
* Event filtering
* @param iObject object
* @param iEvent event
* @return In your reimplementation of this function, if you want to filter the event out, i.e. stop it being handled further, return true; otherwise return false.
*/
bool eventFilter(QObject* iObject, QEvent* iEvent) override;
private Q_SLOTS:
void onExport();
void setupHeaderMenu();
void showHeaderMenu();
void showHeaderMenu(QPoint iPos);
void showHideColumn();
void respanFirstColumns();
void refreshExpandCollapse();
void changeSchema();
void saveDefaultClicked();
void groupByChanged(QAction* /*iAction*/);
void onSortChanged(int /*iIndex*/, Qt::SortOrder /*iOrder*/);
void onExpand(const QModelIndex& index);
void onCollapse(const QModelIndex& index);
void onClick(const QModelIndex& index);
void onActionTriggered(int action);
void onRangeChanged();
void rebuildContextualMenu();
private:
Q_DISABLE_COPY(SKGTreeView)
QMenu* m_headerMenu;
bool m_autoResize;
bool m_autoResizeDone;
QAction* m_actAutoResize;
QAction* m_actCopy;
QAction* m_actExpandAll;
QAction* m_actCollapseAll;
SKGDocument* m_document;
QString m_parameterName;
QStringList m_selection;
QStringList m_expandedNodes;
QString m_groupby;
QTimer m_timerDelayedResize;
QTimer m_timerSelectionChanged;
QTimer m_timerScrollSelection;
bool m_textResizable;
int m_fontOriginalPointSize;
int m_iconOriginalSize;
SKGObjectModelBase* m_model;
SKGSortFilterProxyModel* m_proxyModel;
QAction* m_actGroupByNone;
SKGObjectBase::SKGListSKGObjectBase m_lastSelection;
SKGObjectBase::SKGListSKGObjectBase m_lastSelection_if_deleted;
QString m_lastSelection_previous;
bool stickH;
bool stickV;
};
#endif // SKGTREEVIEW_H
diff --git a/skgbasegui/skgwebview.cpp b/skgbasegui/skgwebview.cpp
index 1469458c0..8648106bf 100644
--- a/skgbasegui/skgwebview.cpp
+++ b/skgbasegui/skgwebview.cpp
@@ -1,347 +1,347 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* A web viewer with more features.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgwebview.h"
#include <qapplication.h>
#include <qclipboard.h>
#include <qdesktopservices.h>
#include <qevent.h>
#include <qpointer.h>
#include <qprintdialog.h>
#include <qprintpreviewdialog.h>
#include <qtextdocument.h>
#include <qtextdocumentwriter.h>
#ifdef SKG_WEBENGINE
#include <qwebenginepage.h>
#else
#include <qwebframe.h>
#endif
#include <qfileinfo.h>
#include <qmath.h>
#include <kstandardaction.h>
#include <qdir.h>
#include <qdom.h>
#include <qicon.h>
#include <qmenu.h>
#include <qnetworkreply.h>
#include <qnetworkrequest.h>
#include <qsavefile.h>
#include <cmath>
#include "skgmainpanel.h"
#include "skgtraces.h"
#ifdef SKG_WEBENGINE
class SKGWebEnginePage : public QWebEnginePage
{
Q_DISABLE_COPY(SKGWebEnginePage)
public:
explicit SKGWebEnginePage(QObject* p = nullptr)
: QWebEnginePage(p)
{}
virtual bool acceptNavigationRequest(const QUrl& url, NavigationType type, bool isMainFrame) override
{
if (type == QWebEnginePage::NavigationTypeLinkClicked) {
if (url.toString().startsWith(QLatin1String("http://linkclicked/"))) {
SKGWebView* v = qobject_cast<SKGWebView*>(this->view());
if (v) {
v->emitLinkClicked(url);
return false;
}
} else {
SKGMainPanel::getMainPanel()->openPage(url);
return false;
}
}
return QWebEnginePage::acceptNavigationRequest(url, type, isMainFrame);
}
};
SKGWebView::SKGWebView(QWidget* iParent, const char* name, bool iWithContextualMenu)
: QWebEngineView(iParent), m_ContextualMenu(iWithContextualMenu)
{
setObjectName(name);
setPage(new SKGWebEnginePage(this));
if (m_ContextualMenu) {
this->installEventFilter(this);
page()->installEventFilter(this);
}
connect(this, &SKGWebView::fileExporter, this, [](const QString & iFileName) {
QDesktopServices::openUrl(QUrl::fromLocalFile(iFileName));
});
}
void SKGWebView::emitLinkClicked(const QUrl& iURL)
{
Q_EMIT linkClicked(iURL);
}
#else
SKGWebView::SKGWebView(QWidget* iParent, const char* name)
: QWebView(iParent)
{
setObjectName(name);
this->installEventFilter(this);
page()->installEventFilter(this);
connect(this, &SKGWebView::fileExporter, this, [](const QString & iFileName) {
QDesktopServices::openUrl(QUrl::fromLocalFile(iFileName));
});
connect(this, &SKGWebView::linkClicked, this, [ = ](const QUrl & val) {
SKGMainPanel::getMainPanel()->openPage(val);
});
this->page()->setForwardUnsupportedContent(true);
connect(this->page(), &QWebPage::unsupportedContent, this, [ = ](QNetworkReply * reply) {
openReply(reply);
});
connect(this->page(), &QWebPage::downloadRequested, this, [ = ](const QNetworkRequest & request) {
QNetworkAccessManager manager;
openReply(manager.get(request));
});
}
void SKGWebView::openReply(QNetworkReply* reply)
{
QString fileName = QDir::tempPath() + '/' + "export.csv";
QFile file(fileName);
if (file.open(QIODevice::WriteOnly | QIODevice::Text)) {
file.write(reply->readAll());
file.close();
}
QDesktopServices::openUrl(QUrl::fromLocalFile(fileName));
reply->deleteLater();
}
#endif
SKGWebView::~SKGWebView()
= default;
QString SKGWebView::getState()
{
SKGTRACEINFUNC(10)
QDomDocument doc(QStringLiteral("SKGML"));
QDomElement root = doc.createElement(QStringLiteral("parameters"));
doc.appendChild(root);
root.setAttribute(QStringLiteral("zoomFactor"), SKGServices::intToString(qMax(qRound(30.0 * log10(zoomFactor())), -10)));
return doc.toString();
}
void SKGWebView::setState(const QString& iState)
{
SKGTRACEINFUNC(10)
QDomDocument doc(QStringLiteral("SKGML"));
doc.setContent(iState);
QDomElement root = doc.documentElement();
QString zoomPosition = root.attribute(QStringLiteral("zoomFactor"));
if (zoomPosition.isEmpty()) {
zoomPosition = '0';
}
double z = qPow(10, (static_cast<qreal>(SKGServices::stringToInt(zoomPosition)) / 30.0));
setZoomFactor(z);
emit zoomChanged(z);
}
void SKGWebView::contextMenuEvent(QContextMenuEvent* iEvent)
{
if (iEvent != nullptr) {
auto menu = new QMenu(this);
#ifdef SKG_WEBENGINE
menu->addAction(pageAction(QWebEnginePage::Copy));
#else
menu->addAction(pageAction(QWebPage::Copy));
#endif
QAction* actPrint = menu->addAction(SKGServices::fromTheme(QStringLiteral("printer")), i18nc("Action", "Print..."));
connect(actPrint, &QAction::triggered, this, &SKGWebView::onPrint);
menu->addAction(KStandardAction::printPreview(this, SLOT(onPrintPreview()), this));
QAction* actExport = menu->addAction(SKGServices::fromTheme(QStringLiteral("document-export")), i18nc("Noun, user action", "Export..."));
connect(actExport, &QAction::triggered, this, &SKGWebView::onExport);
menu->popup(this->mapToGlobal(iEvent->pos()));
iEvent->accept();
}
}
bool SKGWebView::eventFilter(QObject* iObject, QEvent* iEvent)
{
SKGTRACEINFUNC(10)
if ((iEvent != nullptr) && iEvent->type() == QEvent::Wheel) {
auto* e = dynamic_cast<QWheelEvent*>(iEvent);
if (e != nullptr) {
if (e->orientation() == Qt::Vertical && ((QApplication::keyboardModifiers() &Qt::ControlModifier) != 0u)) {
int numDegrees = e->delta() / 8;
int numTicks = numDegrees / 15;
if (numTicks > 0) {
onZoomIn();
} else {
onZoomOut();
}
e->setAccepted(true);
return true;
}
}
}
return QWidget::eventFilter(iObject, iEvent);
}
void SKGWebView::onZoomIn()
{
_SKGTRACEINFUNC(10)
int z = qMin(static_cast<int>(qRound(30.0 * log10(zoomFactor()))) + 1, 10);
setZoomFactor(qPow(10, static_cast<qreal>(z) / 30.0));
emit zoomChanged(z);
}
void SKGWebView::onZoomOut()
{
_SKGTRACEINFUNC(10)
int z = qMax(static_cast<int>(qRound(30.0 * log10(zoomFactor()))) - 1, -10);
setZoomFactor(qPow(10, static_cast<qreal>(z) / 30.0));
emit zoomChanged(z);
}
void SKGWebView::onZoomOriginal()
{
_SKGTRACEINFUNC(10)
setZoomFactor(0);
emit zoomChanged(0);
}
void SKGWebView::exportInFile(const QString& iFileName)
{
QString extension = QFileInfo(iFileName).suffix().toUpper();
if (extension == QStringLiteral("ODT")) {
#ifdef SKG_WEBENGINE
page()->toHtml([ = ](const QString & result) {
QTextDocument doc;
QTextDocumentWriter docWriter(iFileName);
doc.setHtml(result);
docWriter.write(&doc);
emit fileExporter(iFileName);
});
#else
QTextDocument doc;
QTextDocumentWriter docWriter(iFileName);
doc.setHtml(page()->mainFrame()->toHtml());
docWriter.write(&doc);
emit fileExporter(iFileName);
#endif
} else if (extension == QStringLiteral("PDF")) {
#ifdef SKG_WEBENGINE
page()->printToPdf(iFileName);
connect(page(), &QWebEnginePage::pdfPrintingFinished, this, &SKGWebView::fileExporter);
#else
QPrinter printer;
printer.setOutputFileName(iFileName);
print(&printer);
emit fileExporter(iFileName);
#endif
} else if (extension == QStringLiteral("HTML") || extension == QStringLiteral("HTM")) {
#ifdef SKG_WEBENGINE
page()->toHtml([ = ](const QString & result) {
QSaveFile file(iFileName);
if (file.open(QIODevice::WriteOnly)) {
QTextStream out(&file);
out << result;
// Close file
file.commit();
emit fileExporter(iFileName);
}
});
#else
QSaveFile file(iFileName);
if (file.open(QIODevice::WriteOnly)) {
QTextStream out(&file);
out << page()->mainFrame()->toHtml();
// Close file
file.commit();
emit fileExporter(iFileName);
}
#endif
} else {
QImage image(this->size(), QImage::Format_ARGB32);
QPainter painter(&image);
this->render(&painter);
painter.end();
image.save(iFileName);
emit fileExporter(iFileName);
}
}
void SKGWebView::onExport()
{
_SKGTRACEINFUNC(10)
QString fileName = SKGMainPanel::getSaveFileName(QStringLiteral("kfiledialog:///IMPEXP"), QStringLiteral("application/pdf text/html application/vnd.oasis.opendocument.text image/png image/jpeg image/gif image/tiff"), this);
if (fileName.isEmpty()) {
return;
}
exportInFile(fileName);
}
void SKGWebView::onPrintPreview()
{
SKGTRACEINFUNC(10)
QPointer<QPrintPreviewDialog> dialog = new QPrintPreviewDialog(this);
#ifdef SKG_WEBENGINE
// TODO(SMI): QWebEngine
connect(dialog.data(), &QPrintPreviewDialog::paintRequested, page(), [&](QPrinter * printer) {
page()->print(printer, [](bool) {});
});
#else
connect(dialog.data(), &QPrintPreviewDialog::paintRequested, this, &SKGWebView::print);
#endif
dialog->exec();
}
void SKGWebView::onPrint()
{
_SKGTRACEINFUNC(10)
QPointer<QPrintDialog> dialog = new QPrintDialog(&m_printer, this);
if (dialog->exec() == QDialog::Accepted) {
QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
#ifdef SKG_WEBENGINE
page()->print(&m_printer, [](bool) {});
#else
print(&m_printer);
#endif
QApplication::restoreOverrideCursor();
}
}
diff --git a/skgbasegui/skgwebview.h b/skgbasegui/skgwebview.h
index bd077ad2b..8ea8f1bcb 100644
--- a/skgbasegui/skgwebview.h
+++ b/skgbasegui/skgwebview.h
@@ -1,166 +1,166 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGWEBVIEW_H
#define SKGWEBVIEW_H
/** @file
* A web viewer with more features.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include <qprinter.h>
#ifdef SKG_WEBENGINE
#include <qwebengineview.h>
#else
#include <qwebview.h>
#endif
#include "skgbasegui_export.h"
/**
* This file is a web viewer
*/
#ifdef SKG_WEBENGINE
class SKGBASEGUI_EXPORT SKGWebView : public QWebEngineView
#else
class SKGBASEGUI_EXPORT SKGWebView : public QWebView
#endif
{
Q_OBJECT
public:
/**
* Constructor
* @param iParent the parent
* @param name name
*/
#ifdef SKG_WEBENGINE
explicit SKGWebView(QWidget* iParent, const char* name = nullptr, bool iWithContextualMenu = true);
/**
* To emit that a link is clicked
* @param iURL the url of the link
*/
void emitLinkClicked(const QUrl& iURL);
#else
explicit SKGWebView(QWidget* iParent, const char* name = nullptr);
#endif
/**
* Destructor
*/
~SKGWebView() override;
/**
* Get the current state
* @return a string containing all information needed to set the same state.
* Could be an XML stream
*/
virtual QString getState();
/**
* Set the current state
* MUST BE OVERWRITTEN
* @param iState must be interpreted to set the state of the widget
*/
virtual void setState(const QString& iState);
/**
* Export in the file (PDF, ODT, png, jpeg, ...)
* @param iFileName the file name
*/
virtual void exportInFile(const QString& iFileName);
Q_SIGNALS:
/**
* Emitted when zoom changed
* @param iZoomPosition zoom position (-10<=zoom position<=10)
*/
void zoomChanged(int iZoomPosition);
/**
* Emitted when a file is exported
* @param iFileName the exported file name
*/
void fileExporter(const QString& iFileName);
#ifdef SKG_WEBENGINE
/**
* Emitted when a link is clicked
* @param iURL the url of the link
*/
void linkClicked(const QUrl& iURL);
#endif
public Q_SLOTS:
/**
* Zoom in
*/
virtual void onZoomIn();
/**
* Zoom out
*/
virtual void onZoomOut();
/**
* Fit on scene
*/
virtual void onZoomOriginal();
/**
* Print
*/
virtual void onPrint();
/**
* Export
*/
virtual void onExport();
/**
* Print preview
*/
virtual void onPrintPreview();
protected:
/**
* Contextual event
* @param iEvent the event
*/
void contextMenuEvent(QContextMenuEvent* iEvent) override;
/**
* Event filtering
* @param iObject object
* @param iEvent event
* @return In your reimplementation of this function, if you want to filter the event out, i.e. stop it being handled further, return true; otherwise return false.
*/
bool eventFilter(QObject* iObject, QEvent* iEvent) override;
private:
Q_DISABLE_COPY(SKGWebView)
QPrinter m_printer;
#ifdef SKG_WEBENGINE
bool m_ContextualMenu;
#else
void openReply(QNetworkReply* reply);
#endif
};
#endif
diff --git a/skgbasegui/skgwidget.cpp b/skgbasegui/skgwidget.cpp
index edb356a2c..9cc566dec 100644
--- a/skgbasegui/skgwidget.cpp
+++ b/skgbasegui/skgwidget.cpp
@@ -1,113 +1,113 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is a class managing widget.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgwidget.h"
#include <qwidget.h>
#include "skgtraces.h"
#include "skgtreeview.h"
SKGWidget::SKGWidget(QWidget* iParent, SKGDocument* iDocument)
: QWidget(iParent), m_document(iDocument)
{
SKGTRACEINFUNC(5)
}
SKGWidget::~SKGWidget()
{
SKGTRACEINFUNC(5)
m_document = nullptr;
}
SKGDocument* SKGWidget::getDocument() const
{
return m_document;
}
QString SKGWidget::getState()
{
return QLatin1String("");
}
QString SKGWidget::getDefaultStateAttribute()
{
return QLatin1String("");
}
void SKGWidget::setState(const QString& /*iState*/)
{
}
SKGObjectBase::SKGListSKGObjectBase SKGWidget::getSelectedObjects()
{
SKGObjectBase::SKGListSKGObjectBase selection;
auto* treeView = qobject_cast<SKGTreeView*>(mainWidget());
if (treeView != nullptr) {
selection = treeView->getSelectedObjects();
}
return selection;
}
SKGObjectBase SKGWidget::getFirstSelectedObject()
{
SKGObjectBase first;
auto* treeView = qobject_cast<SKGTreeView*>(mainWidget());
if (treeView != nullptr) {
first = treeView->getFirstSelectedObject();
}
return first;
}
int SKGWidget::getNbSelectedObjects()
{
int output = 0;
auto* treeView = qobject_cast<SKGTreeView*>(mainWidget());
if (treeView != nullptr) {
output = treeView->getNbSelectedObjects();
} else {
output = getSelectedObjects().count();
}
return output;
}
bool SKGWidget::hasSelectionWithFocus()
{
return (mainWidget()->hasFocus());
}
bool SKGWidget::eventFilter(QObject* iObject, QEvent* iEvent)
{
if (iObject == mainWidget() && (iEvent != nullptr) && (iEvent->type() == QEvent::FocusIn || iEvent->type() == QEvent::FocusOut)) {
emit selectionFocusChanged();
}
return QObject::eventFilter(iObject, iEvent);
}
QWidget* SKGWidget::mainWidget()
{
return this;
}
diff --git a/skgbasegui/skgwidget.h b/skgbasegui/skgwidget.h
index 3e1603697..57a1b1369 100644
--- a/skgbasegui/skgwidget.h
+++ b/skgbasegui/skgwidget.h
@@ -1,140 +1,140 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGWIDGET_H
#define SKGWIDGET_H
/** @file
* This file is a class managing widget.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include <qwidget.h>
#include "skgbasegui_export.h"
#include "skgobjectbase.h"
class SKGDocument;
/**
* This file is a tab widget used by plugins
*/
class SKGBASEGUI_EXPORT SKGWidget : public QWidget
{
Q_OBJECT
public:
/**
* Default Constructor
* @param iParent the parent widget
* @param iDocument the document
*/
explicit SKGWidget(QWidget* iParent, SKGDocument* iDocument);
/**
* Default Destructor
*/
~SKGWidget() override;
/**
* Get main document
* @return pointer on main document
*/
virtual SKGDocument* getDocument() const;
/**
* Get the current state
* MUST BE OVERWRITTEN
* @return a string containing all information needed to set the same state.
* Could be an XML stream
*/
virtual QString getState();
/**
* Set the current state
* MUST BE OVERWRITTEN
* @param iState must be interpreted to set the state of the widget
*/
virtual void setState(const QString& iState);
/**
* Get attribute name to save the default state
* MUST BE OVERWRITTEN
* @return attribute name to save the default state.
*/
virtual QString getDefaultStateAttribute();
/**
* Get the current selection
* MUST BE OVERWRITTEN
* @return selected objects
*/
virtual SKGObjectBase::SKGListSKGObjectBase getSelectedObjects();
/**
* Get the first selected object
* @return first selected object
*/
virtual SKGObjectBase getFirstSelectedObject();
/**
* Get the number of selected object
* CAN BE OVERWRITTEN FOR OPTIMIZATION
* @return number of selected objects
*/
virtual int getNbSelectedObjects();
/**
* To know if the widget having the selection has the focus
* Default implementation is based on mainWidget
* Don't forget to do mainWidget()->installEventFilter(this);
* @return true of false
*/
virtual bool hasSelectionWithFocus();
/**
* Get the main widget
* @return a widget
*/
virtual QWidget* mainWidget();
Q_SIGNALS:
/**
* This signal must be launched when the selection is modified
*/
void selectionChanged();
/**
* This signal must be launched when the widget having the selection has win or lost the focus
*/
void selectionFocusChanged();
protected:
/**
* Event filtering
* @param iObject object
* @param iEvent event
* @return In your reimplementation of this function, if you want to filter the event out, i.e. stop it being handled further, return true; otherwise return false.
*/
bool eventFilter(QObject* iObject, QEvent* iEvent) override;
private:
Q_DISABLE_COPY(SKGWidget)
SKGDocument* m_document;
};
#endif // SKGWIDGET_H
diff --git a/skgbasegui/skgwidgetselector.cpp b/skgbasegui/skgwidgetselector.cpp
index 0fe6ed5ee..29dec02fc 100644
--- a/skgbasegui/skgwidgetselector.cpp
+++ b/skgbasegui/skgwidgetselector.cpp
@@ -1,187 +1,187 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* A widget selector.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgwidgetselector.h"
#include "skgdefine.h"
#include <qtoolbutton.h>
SKGWidgetSelector::SKGWidgetSelector(QWidget* iParent)
: QWidget(iParent), m_currentMode(-1), m_alwaysOneOpen(false)
{
ui.setupUi(this);
}
SKGWidgetSelector::~SKGWidgetSelector()
= default;
void SKGWidgetSelector::addButton(const QIcon& iIcon, const QString& iTitle, const QString& iToolTip, QWidget* iWidgets)
{
SKGListQWidget list;
list.push_back(iWidgets);
addButton(iIcon, iTitle, iToolTip, list);
}
void SKGWidgetSelector::addButton(const QIcon& iIcon, const QString& iTitle, const QString& iToolTip, const SKGWidgetSelector::SKGListQWidget& iListOfShownWidgets)
{
// Create button
auto btn = new QToolButton(this);
btn->setCheckable(true);
btn->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
btn->setAutoRaise(true);
btn->setText(iTitle);
btn->setToolTip(iToolTip);
btn->setIcon(iIcon);
ui.horizontalLayout->insertWidget(m_listButton.count(), btn);
connect(btn, &QToolButton::clicked, this, &SKGWidgetSelector::onButtonClicked);
// Memorize items
m_listButton.push_back(btn);
// Hide widgets
SKGWidgetSelector::SKGListQWidget list;
for (auto w : qAsConst(iListOfShownWidgets)) {
if (w != nullptr) {
// Addition of an intermediate widget
/*auto widget = new QWidget(w->parentWidget());
widget->setObjectName(w->objectName()+"_intermediate");
auto horizontalLayout = new QHBoxLayout(widget);
horizontalLayout->setSpacing(0);
horizontalLayout->setContentsMargins(0, 0, 0, 0);
horizontalLayout->setObjectName(w->objectName()+"_horizontalLayout");
w->setParent(widget);
horizontalLayout->addWidget(w);*/
list.push_back(w);
w->hide();
}
}
m_listWidgets.push_back(list);
}
int SKGWidgetSelector::getSelectedMode() const
{
return m_currentMode;
}
void SKGWidgetSelector::setSelectedMode(int iMode)
{
if (iMode != m_currentMode) {
// Hide current widgets
if (m_currentMode >= 0) {
m_listButton.at(m_currentMode)->setChecked(false);
SKGListQWidget list = m_listWidgets.at(m_currentMode);
for (auto w : qAsConst(list)) {
if (w != nullptr) {
/*if (iMode == -1) {
auto anim1 = new QPropertyAnimation(w, "geometry");
QRect r=w->geometry();
m_originGeometries[w]=r;
// anim1->setStartValue(m_originGeometries[w]);
r.setY(r.y()+r.height());
m_endGeometries[w]=r;
anim1->setEndValue(m_endGeometries[w]);
anim1->setEasingCurve(QEasingCurve::InOutSine);
anim1->setDuration(500);
anim1->start(QAbstractAnimation::DeleteWhenStopped);
connect(anim1, &QPropertyAnimation::finished, w, &QWidget::hide);
} else */
w->hide();
}
}
}
// Set current mode
// int previousmode = m_currentMode;
m_currentMode = iMode;
if (m_currentMode >= m_listWidgets.count()) {
m_currentMode = -1;
}
// Show widgets
if (m_currentMode >= 0) {
m_listButton.at(m_currentMode)->setChecked(true);
for (auto w : qAsConst(m_listWidgets.at(m_currentMode))) {
if (w != nullptr) {
w->show();
/*if (previousmode == -1) {
auto anim1 = new QPropertyAnimation(w, "geometry");
// anim1->setStartValue(m_endGeometries[w]);
anim1->setEndValue(m_originGeometries[w]);
anim1->setEasingCurve(QEasingCurve::InOutSine);
anim1->setDuration(500);
anim1->start(QAbstractAnimation::DeleteWhenStopped);
}*/
}
}
}
if (m_currentMode < -1) {
this->hide();
}
emit selectedModeChanged(m_currentMode);
}
}
void SKGWidgetSelector::setEnabledMode(int iMode, bool iEnabled)
{
if (iMode >= 0 && iMode < m_listButton.count()) {
m_listButton.at(iMode)->setEnabled(iEnabled);
}
}
void SKGWidgetSelector::onButtonClicked()
{
auto* clickedButton = qobject_cast<QToolButton*>(sender());
int newMode = m_listButton.indexOf(clickedButton);
if (m_currentMode == newMode) {
if (getAlwaysOneOpen()) {
--newMode;
if (newMode == -1) {
newMode = m_listButton.count() - 1;
}
} else {
newMode = -1;
}
}
setSelectedMode(newMode);
}
bool SKGWidgetSelector::getAlwaysOneOpen() const
{
return m_alwaysOneOpen;
}
void SKGWidgetSelector::setAlwaysOneOpen(bool iMode)
{
if (m_alwaysOneOpen != iMode) {
m_alwaysOneOpen = iMode;
Q_EMIT alwaysOneOpenChanged();
}
}
diff --git a/skgbasegui/skgwidgetselector.h b/skgbasegui/skgwidgetselector.h
index 6633b0340..ab4cc98cb 100644
--- a/skgbasegui/skgwidgetselector.h
+++ b/skgbasegui/skgwidgetselector.h
@@ -1,139 +1,139 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGWIDGETSELECTOR_H
#define SKGWIDGETSELECTOR_H
/** @file
* A widget selector.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgbasegui_export.h"
#include "ui_skgwidgetselector.h"
class QToolButton;
/**
* This file is a color selector box with more features.
*/
class SKGBASEGUI_EXPORT SKGWidgetSelector : public QWidget
{
Q_OBJECT
/**
* The selected mode
*/
Q_PROPERTY(int selectedMode READ getSelectedMode WRITE setSelectedMode NOTIFY selectedModeChanged USER true)
/**
* The default mode
*/
Q_PROPERTY(bool alwaysOneOpen READ getAlwaysOneOpen WRITE setAlwaysOneOpen NOTIFY alwaysOneOpenChanged USER true)
public:
/**
* A list of QWidget* ==> SKGListQWidget
*/
using SKGListQWidget = QList<QWidget*>;
/**
* Default Constructor
* @param iParent the parent
*/
explicit SKGWidgetSelector(QWidget* iParent);
/**
* Default Destructor
*/
~SKGWidgetSelector() override;
/**
* Add a button to the selector
* @param iIcon the icon
* @param iTitle the text
* @param iToolTip the tooltip
* @param iListOfShownWidgets the list of widget to display
*/
virtual void addButton(const QIcon& iIcon, const QString& iTitle, const QString& iToolTip, const SKGWidgetSelector::SKGListQWidget& iListOfShownWidgets);
/**
* Add a button to the selector
* @param iIcon the icon
* @param iTitle the text
* @param iToolTip the tooltip
* @param iWidgets the widget to display
*/
virtual void addButton(const QIcon& iIcon, const QString& iTitle, const QString& iToolTip, QWidget* iWidgets);
/**
* Get the current selected mode
* @return the current selected mode
*/
virtual int getSelectedMode() const;
/**
* Set the selected mode
* @param iMode the selected mode
*/
virtual void setSelectedMode(int iMode);
/**
* Enable/disable a mode
* @param iMode the mode
* @param iEnabled the state
*/
virtual void setEnabledMode(int iMode, bool iEnabled);
/**
* Get the "Always one open" mode
* @return the mode
*/
virtual bool getAlwaysOneOpen() const;
/**
* Set the "Always one open" mode.
* @param iMode the mode
*/
virtual void setAlwaysOneOpen(bool iMode);
Q_SIGNALS:
/**
* Emitted when the selected mode changed
* @param iMode the new selected mode
*/
void selectedModeChanged(int iMode);
/**
* Emitted when the property is modified
*/
void alwaysOneOpenChanged();
private Q_SLOTS:
void onButtonClicked();
private:
Ui::skgwidgetselector_base ui{};
QList<QToolButton*> m_listButton;
QList<SKGListQWidget> m_listWidgets;
// QHash<QWidget*, QRect> m_originGeometries;
// QHash<QWidget*, QRect> m_endGeometries;
int m_currentMode;
bool m_alwaysOneOpen;
};
#endif // SKGWIDGETSELECTOR_H
diff --git a/skgbasegui/skgzoomselector.cpp b/skgbasegui/skgzoomselector.cpp
index c619e32a2..f13fa8185 100644
--- a/skgbasegui/skgzoomselector.cpp
+++ b/skgbasegui/skgzoomselector.cpp
@@ -1,109 +1,109 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* A zoom selector.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgzoomselector.h"
#include "skgservices.h"
SKGZoomSelector::SKGZoomSelector(QWidget* iParent)
: QWidget(iParent), m_resetValue(0)
{
ui.setupUi(this);
// Set icons
ui.kZoomIn->setIcon(SKGServices::fromTheme(QStringLiteral("zoom-in")));
ui.kZoomOut->setIcon(SKGServices::fromTheme(QStringLiteral("zoom-out")));
ui.kZoomOriginal->setIcon(SKGServices::fromTheme(QStringLiteral("zoom-original")));
connect(ui.kZoomOriginal, &QToolButton::clicked, this, &SKGZoomSelector::initializeZoom);
connect(ui.kZoomOut, &QToolButton::clicked, this, &SKGZoomSelector::zoomOut);
connect(ui.kZoomIn, &QToolButton::clicked, this, &SKGZoomSelector::zoomIn);
connect(ui.kZoomSlider, &QSlider::valueChanged, this, &SKGZoomSelector::onZoomChangedDelayed);
// Init timer
m_timer.setSingleShot(true);
connect(&m_timer, &QTimer::timeout, this, &SKGZoomSelector::onZoomChanged, Qt::QueuedConnection);
}
SKGZoomSelector::~SKGZoomSelector()
= default;
void SKGZoomSelector::setValue(int iValue, bool iEmitEvent)
{
bool previous = ui.kZoomSlider->blockSignals(!iEmitEvent);
ui.kZoomSlider->setValue(iValue);
if (ui.kZoomOriginal != nullptr) {
ui.kZoomOriginal->setChecked(iValue == m_resetValue);
}
ui.kZoomSlider->blockSignals(previous);
}
int SKGZoomSelector::value() const
{
return ui.kZoomSlider->value();
}
int SKGZoomSelector::resetValue() const
{
return m_resetValue;
}
void SKGZoomSelector::setResetValue(int iValue)
{
m_resetValue = iValue;
}
void SKGZoomSelector::zoomIn()
{
ui.kZoomSlider->setValue(ui.kZoomSlider->value() + 1);
}
void SKGZoomSelector::zoomOut()
{
ui.kZoomSlider->setValue(ui.kZoomSlider->value() - 1);
}
void SKGZoomSelector::initializeZoom()
{
ui.kZoomSlider->setValue(m_resetValue);
}
void SKGZoomSelector::onZoomChangedDelayed()
{
m_timer.start(300);
}
void SKGZoomSelector::onZoomChanged()
{
int val = ui.kZoomSlider->value();
if (ui.kZoomIn != nullptr) {
ui.kZoomIn->setEnabled(val < 10);
}
if (ui.kZoomOut != nullptr) {
ui.kZoomOut->setEnabled(val > -10);
}
if (ui.kZoomOriginal != nullptr) {
ui.kZoomOriginal->setChecked(val == m_resetValue);
}
Q_EMIT changed(val);
}
diff --git a/skgbasegui/skgzoomselector.h b/skgbasegui/skgzoomselector.h
index e0ed85ab0..f97e92f42 100644
--- a/skgbasegui/skgzoomselector.h
+++ b/skgbasegui/skgzoomselector.h
@@ -1,115 +1,115 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGZOOMSELECTOR_H
#define SKGZOOMSELECTOR_H
/** @file
* A zoom selector.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgbasegui_export.h"
#include "ui_skgzoomselector.h"
#include <qtimer.h>
/**
* This file is a zoom selector.
*/
class SKGBASEGUI_EXPORT SKGZoomSelector : public QWidget
{
Q_OBJECT
/**
* Value of the zoom
*/
Q_PROPERTY(int value READ value WRITE setValue NOTIFY changed USER true)
/**
* Value of the zoom
*/
Q_PROPERTY(int resetValue READ resetValue WRITE setResetValue NOTIFY changed)
public:
/**
* Default Constructor
* @param iParent the parent
*/
explicit SKGZoomSelector(QWidget* iParent);
/**
* Default Destructor
*/
~SKGZoomSelector() override;
/**
* Get the value of the zoom
* @return the value
*/
virtual int value() const;
/**
* Get the value of the zoom when reseted
* @return the value
*/
virtual int resetValue() const;
public Q_SLOTS:
/**
* Set the value of the zoom
* @param iValue the value
* @param iEmitEvent to emit delayed event
*/
virtual void setValue(int iValue, bool iEmitEvent = true);
/**
* Set the value of the zoom when reseted
* @param iValue the value
*/
virtual void setResetValue(int iValue);
/**
* Reinitialize zoom
*/
virtual void initializeZoom();
/**
* Zoom in
*/
virtual void zoomIn();
/**
* Zoom out
*/
virtual void zoomOut();
Q_SIGNALS:
/**
* Emitted when the value is changed
* @param iValue the value
*/
void changed(int iValue);
private Q_SLOTS:
void onZoomChanged();
void onZoomChangedDelayed();
private:
Ui::skgzoomselector ui{};
QTimer m_timer;
int m_resetValue;
};
#endif // SKGZOOMSELECTOR_H
diff --git a/skgbaseguidesigner/CMakeLists.txt b/skgbaseguidesigner/CMakeLists.txt
index 8e4a991f2..5272563f9 100644
--- a/skgbaseguidesigner/CMakeLists.txt
+++ b/skgbaseguidesigner/CMakeLists.txt
@@ -1,67 +1,67 @@
#***************************************************************************
#* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
#* *
#* 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 <http://www.gnu.org/licenses/> *
+#* along with this program. If not, see <https://www.gnu.org/licenses/> *
#***************************************************************************
MESSAGE( STATUS "..:: CMAKE SKGBASEGUIDESIGNER ::..")
PROJECT(SKGBASEGUIDESIGNER)
LINK_DIRECTORIES (${LIBRARY_OUTPUT_PATH})
IF(SKG_WEBENGINE)
MESSAGE( STATUS " Mode WebEngine")
ADD_DEFINITIONS(-DSKG_WEBENGINE=${SKG_WEBENGINE})
ENDIF(SKG_WEBENGINE)
SET(skgbaseguidesigner_SRCS
skgwidgetcollectiondesignerplugin.cpp
skgtabwidgetdesignerplugin.cpp
skgtablewidgetdesignerplugin.cpp
skgtableviewdesignerplugin.cpp
skgfilteredtableviewdesignerplugin.cpp
skgtreeviewdesignerplugin.cpp
skgcomboboxdesignerplugin.cpp
skgcolorbuttondesignerplugin.cpp
skgwidgetselectordesignerplugin.cpp
skgwebviewdesignerplugin.cpp
skgzoomselectordesignerplugin.cpp
skgcalculatoreditdesignerplugin.cpp
skggraphicsviewdesignerplugin.cpp
skgshowdesignerplugin.cpp
skgtablewithgraphdesignerplugin.cpp
skgdateeditdesignerplugin.cpp
skgprogressbardesignerplugin.cpp
skgperiodeditdesignerplugin.cpp
skgsimpleperiodeditdesignerplugin.cpp
)
SET(LIBS Qt5::Designer skgbasegui)
IF(SKG_WEBENGINE)
SET(LIBS ${LIBS} Qt5::WebEngineWidgets)
ELSE(SKG_WEBENGINE)
SET(LIBS ${LIBS} Qt5::WebKitWidgets)
ENDIF(SKG_WEBENGINE)
ADD_LIBRARY(skgbaseguidesigner SHARED ${skgbaseguidesigner_SRCS})
TARGET_LINK_LIBRARIES(skgbaseguidesigner LINK_PUBLIC ${LIBS})
GENERATE_EXPORT_HEADER(skgbaseguidesigner BASE_NAME skgbaseguidesigner)
########### install files ###############
IF(WIN32)
INSTALL(TARGETS skgbaseguidesigner LIBRARY ARCHIVE DESTINATION ${PLUGIN_INSTALL_DIR}/designer )
ELSE(WIN32)
INSTALL(TARGETS skgbaseguidesigner LIBRARY DESTINATION ${PLUGIN_INSTALL_DIR}/designer )
ENDIF(WIN32)
diff --git a/skgbaseguidesigner/skgcalculatoreditdesignerplugin.cpp b/skgbaseguidesigner/skgcalculatoreditdesignerplugin.cpp
index 619c50fa0..bd6f046d4 100644
--- a/skgbaseguidesigner/skgcalculatoreditdesignerplugin.cpp
+++ b/skgbaseguidesigner/skgcalculatoreditdesignerplugin.cpp
@@ -1,103 +1,103 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* A QLineEdit with calculator (qt designer plugin).
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgcalculatoreditdesignerplugin.h"
#include "skgcalculatoredit.h"
#include "skgservices.h"
SKGCalculatorEditDesignerPlugin::SKGCalculatorEditDesignerPlugin(QObject* iParent)
: QObject(iParent)
{
m_initialized = false;
}
void SKGCalculatorEditDesignerPlugin::initialize(QDesignerFormEditorInterface* iCore)
{
Q_UNUSED(iCore)
if (m_initialized) {
return;
}
m_initialized = true;
}
bool SKGCalculatorEditDesignerPlugin::isInitialized() const
{
return m_initialized;
}
QWidget* SKGCalculatorEditDesignerPlugin::createWidget(QWidget* iParent)
{
return new SKGCalculatorEdit(iParent);
}
QString SKGCalculatorEditDesignerPlugin::name() const
{
return QStringLiteral("SKGCalculatorEdit");
}
QString SKGCalculatorEditDesignerPlugin::group() const
{
return QStringLiteral("SKG Widgets");
}
QIcon SKGCalculatorEditDesignerPlugin::icon() const
{
return SKGServices::fromTheme(QStringLiteral("quickopen"));
}
QString SKGCalculatorEditDesignerPlugin::toolTip() const
{
return QStringLiteral("A QLineEdit with calculator included");
}
QString SKGCalculatorEditDesignerPlugin::whatsThis() const
{
return QStringLiteral("A QLineEdit with calculator included");
}
bool SKGCalculatorEditDesignerPlugin::isContainer() const
{
return false;
}
QString SKGCalculatorEditDesignerPlugin::domXml() const
{
return QStringLiteral("<widget class=\"SKGCalculatorEdit\" name=\"SKGCalculatorEdit\">\n"
" <property name=\"geometry\">\n"
" <rect>\n"
" <x>0</x>\n"
" <y>0</y>\n"
" <width>100</width>\n"
" <height>10</height>\n"
" </rect>\n"
" </property>\n"
"</widget>\n");
}
QString SKGCalculatorEditDesignerPlugin::includeFile() const
{
return QStringLiteral("skgcalculatoredit.h");
}
diff --git a/skgbaseguidesigner/skgcalculatoreditdesignerplugin.h b/skgbaseguidesigner/skgcalculatoreditdesignerplugin.h
index 396003e36..4de880948 100644
--- a/skgbaseguidesigner/skgcalculatoreditdesignerplugin.h
+++ b/skgbaseguidesigner/skgcalculatoreditdesignerplugin.h
@@ -1,112 +1,112 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGCALCULATOREDITDESIGNERPLUGIN_H
#define SKGCALCULATOREDITDESIGNERPLUGIN_H
/** @file
* A QLineEdit with calculator included (qt designer plugin).
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include <customwidget.h>
/**
* QDesigner plugin for SKGCalculatorEdit
*/
class SKGCalculatorEditDesignerPlugin : public QObject, public QDesignerCustomWidgetInterface
{
Q_OBJECT
Q_INTERFACES(QDesignerCustomWidgetInterface)
public:
/**
* Constructor
* @param iParent parent
*/
explicit SKGCalculatorEditDesignerPlugin(QObject* iParent = nullptr);
/**
* To know if the component is a container
* @return true or false
*/
bool isContainer() const override;
/**
* To know if the component is initialized
* @return true or false
*/
bool isInitialized() const override;
/**
* To get the icon for this component
* @return the icon
*/
QIcon icon() const override;
/**
* To get the icon for this component
* @return
*/
QString domXml() const override;
/**
* To get the group for this component
* @return group
*/
QString group() const override;
/**
* To get the include file for this component
* @return the include file
*/
QString includeFile() const override;
/**
* To get the name for this component
* @return name
*/
QString name() const override;
/**
* To get the "tool tip" for this component
* @return the "tool tip"
*/
QString toolTip() const override;
/**
* To get the "whats this" for this component
* @return the "whats this"
*/
QString whatsThis() const override;
/**
* To get the widget representing the component
* @param iParent the parent of the widget
* @return the widget
*/
QWidget* createWidget(QWidget* iParent) override;
/**
* Initilialize the component
* @param iCore interface
*/
void initialize(QDesignerFormEditorInterface* iCore) override;
private:
bool m_initialized;
};
#endif
diff --git a/skgbaseguidesigner/skgcolorbuttondesignerplugin.cpp b/skgbaseguidesigner/skgcolorbuttondesignerplugin.cpp
index 8472aa72e..d5555176c 100644
--- a/skgbaseguidesigner/skgcolorbuttondesignerplugin.cpp
+++ b/skgbaseguidesigner/skgcolorbuttondesignerplugin.cpp
@@ -1,101 +1,101 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* A color button with more features (qt designer plugin).
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgcolorbuttondesignerplugin.h"
#include "skgcolorbutton.h"
#include "skgservices.h"
SKGColorButtonDesignerPlugin::SKGColorButtonDesignerPlugin(QObject* iParent)
: QObject(iParent)
{
m_initialized = false;
}
void SKGColorButtonDesignerPlugin::initialize(QDesignerFormEditorInterface* iCore)
{
Q_UNUSED(iCore)
if (m_initialized) {
return;
}
m_initialized = true;
}
bool SKGColorButtonDesignerPlugin::isInitialized() const
{
return m_initialized;
}
QWidget* SKGColorButtonDesignerPlugin::createWidget(QWidget* iParent)
{
return new SKGColorButton(iParent);
}
QString SKGColorButtonDesignerPlugin::name() const
{
return QStringLiteral("SKGColorButton");
}
QString SKGColorButtonDesignerPlugin::group() const
{
return QStringLiteral("SKG Widgets");
}
QIcon SKGColorButtonDesignerPlugin::icon() const
{
return SKGServices::fromTheme(QStringLiteral("quickopen"));
}
QString SKGColorButtonDesignerPlugin::toolTip() const
{
return QStringLiteral("A color button with more features");
}
QString SKGColorButtonDesignerPlugin::whatsThis() const
{
return QStringLiteral("A color button with more features");
}
bool SKGColorButtonDesignerPlugin::isContainer() const
{
return false;
}
QString SKGColorButtonDesignerPlugin::domXml() const
{
return QStringLiteral("<widget class=\"SKGColorButton\" name=\"SKGColorButton\">\n"
" <property name=\"geometry\">\n"
" <rect>\n"
" <x>0</x>\n"
" <y>0</y>\n"
" <width>100</width>\n"
" <height>10</height>\n"
" </rect>\n"
" </property>\n"
"</widget>\n");
}
QString SKGColorButtonDesignerPlugin::includeFile() const
{
return QStringLiteral("skgcolorbutton.h");
}
diff --git a/skgbaseguidesigner/skgcolorbuttondesignerplugin.h b/skgbaseguidesigner/skgcolorbuttondesignerplugin.h
index 1dcaa6655..e5a2ad101 100644
--- a/skgbaseguidesigner/skgcolorbuttondesignerplugin.h
+++ b/skgbaseguidesigner/skgcolorbuttondesignerplugin.h
@@ -1,112 +1,112 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGCOLORBUTTONDESIGNERPLUGIN_H
#define SKGCOLORBUTTONDESIGNERPLUGIN_H
/** @file
* A color button with more features (qt designer plugin).
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include <customwidget.h>
/**
* QDesigner plugin for SKGColorButton
*/
class SKGColorButtonDesignerPlugin : public QObject, public QDesignerCustomWidgetInterface
{
Q_OBJECT
Q_INTERFACES(QDesignerCustomWidgetInterface)
public:
/**
* Constructor
* @param iParent parent
*/
explicit SKGColorButtonDesignerPlugin(QObject* iParent = nullptr);
/**
* To know if the component is a container
* @return true or false
*/
bool isContainer() const override;
/**
* To know if the component is initialized
* @return true or false
*/
bool isInitialized() const override;
/**
* To get the icon for this component
* @return the icon
*/
QIcon icon() const override;
/**
* To get the icon for this component
* @return
*/
QString domXml() const override;
/**
* To get the group for this component
* @return group
*/
QString group() const override;
/**
* To get the include file for this component
* @return the include file
*/
QString includeFile() const override;
/**
* To get the name for this component
* @return name
*/
QString name() const override;
/**
* To get the "tool tip" for this component
* @return the "tool tip"
*/
QString toolTip() const override;
/**
* To get the "whats this" for this component
* @return the "whats this"
*/
QString whatsThis() const override;
/**
* To get the widget representing the component
* @param iParent the parent of the widget
* @return the widget
*/
QWidget* createWidget(QWidget* iParent) override;
/**
* Initilialize the component
* @param iCore interface
*/
void initialize(QDesignerFormEditorInterface* iCore) override;
private:
bool m_initialized;
};
#endif
diff --git a/skgbaseguidesigner/skgcomboboxdesignerplugin.cpp b/skgbaseguidesigner/skgcomboboxdesignerplugin.cpp
index d611e58db..f206d6575 100644
--- a/skgbaseguidesigner/skgcomboboxdesignerplugin.cpp
+++ b/skgbaseguidesigner/skgcomboboxdesignerplugin.cpp
@@ -1,101 +1,101 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* A combo box with more features (qt designer plugin).
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgcomboboxdesignerplugin.h"
#include "skgcombobox.h"
#include "skgservices.h"
SKGComboBoxDesignerPlugin::SKGComboBoxDesignerPlugin(QObject* iParent)
: QObject(iParent)
{
m_initialized = false;
}
void SKGComboBoxDesignerPlugin::initialize(QDesignerFormEditorInterface* iCore)
{
Q_UNUSED(iCore)
if (m_initialized) {
return;
}
m_initialized = true;
}
bool SKGComboBoxDesignerPlugin::isInitialized() const
{
return m_initialized;
}
QWidget* SKGComboBoxDesignerPlugin::createWidget(QWidget* iParent)
{
return new SKGComboBox(iParent);
}
QString SKGComboBoxDesignerPlugin::name() const
{
return QStringLiteral("SKGComboBox");
}
QString SKGComboBoxDesignerPlugin::group() const
{
return QStringLiteral("SKG Widgets");
}
QIcon SKGComboBoxDesignerPlugin::icon() const
{
return SKGServices::fromTheme(QStringLiteral("quickopen"));
}
QString SKGComboBoxDesignerPlugin::toolTip() const
{
return QStringLiteral("A combo box with more features");
}
QString SKGComboBoxDesignerPlugin::whatsThis() const
{
return QStringLiteral("A combo box with more features");
}
bool SKGComboBoxDesignerPlugin::isContainer() const
{
return false;
}
QString SKGComboBoxDesignerPlugin::domXml() const
{
return QStringLiteral("<widget class=\"SKGComboBox\" name=\"SKGComboBox\">\n"
" <property name=\"geometry\">\n"
" <rect>\n"
" <x>0</x>\n"
" <y>0</y>\n"
" <width>100</width>\n"
" <height>10</height>\n"
" </rect>\n"
" </property>\n"
"</widget>\n");
}
QString SKGComboBoxDesignerPlugin::includeFile() const
{
return QStringLiteral("skgcombobox.h");
}
diff --git a/skgbaseguidesigner/skgcomboboxdesignerplugin.h b/skgbaseguidesigner/skgcomboboxdesignerplugin.h
index 276a99c2a..e781ddc32 100644
--- a/skgbaseguidesigner/skgcomboboxdesignerplugin.h
+++ b/skgbaseguidesigner/skgcomboboxdesignerplugin.h
@@ -1,112 +1,112 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGCOMBOBOXDESIGNERPLUGIN_H
#define SKGCOMBOBOXDESIGNERPLUGIN_H
/** @file
* A combo box with more features (qt designer plugin).
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include <customwidget.h>
/**
* QDesigner plugin for SKGComboBox
*/
class SKGComboBoxDesignerPlugin : public QObject, public QDesignerCustomWidgetInterface
{
Q_OBJECT
Q_INTERFACES(QDesignerCustomWidgetInterface)
public:
/**
* Constructor
* @param iParent parent
*/
explicit SKGComboBoxDesignerPlugin(QObject* iParent = nullptr);
/**
* To know if the component is a container
* @return true or false
*/
bool isContainer() const override;
/**
* To know if the component is initialized
* @return true or false
*/
bool isInitialized() const override;
/**
* To get the icon for this component
* @return the icon
*/
QIcon icon() const override;
/**
* To get the icon for this component
* @return
*/
QString domXml() const override;
/**
* To get the group for this component
* @return group
*/
QString group() const override;
/**
* To get the include file for this component
* @return the include file
*/
QString includeFile() const override;
/**
* To get the name for this component
* @return name
*/
QString name() const override;
/**
* To get the "tool tip" for this component
* @return the "tool tip"
*/
QString toolTip() const override;
/**
* To get the "whats this" for this component
* @return the "whats this"
*/
QString whatsThis() const override;
/**
* To get the widget representing the component
* @param iParent the parent of the widget
* @return the widget
*/
QWidget* createWidget(QWidget* iParent) override;
/**
* Initilialize the component
* @param iCore interface
*/
void initialize(QDesignerFormEditorInterface* iCore) override;
private:
bool m_initialized;
};
#endif
diff --git a/skgbaseguidesigner/skgdateeditdesignerplugin.cpp b/skgbaseguidesigner/skgdateeditdesignerplugin.cpp
index c53981111..8fcb17135 100644
--- a/skgbaseguidesigner/skgdateeditdesignerplugin.cpp
+++ b/skgbaseguidesigner/skgdateeditdesignerplugin.cpp
@@ -1,103 +1,103 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* A date edit with more features (qt designer plugin).
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgdateeditdesignerplugin.h"
#include "skgdateedit.h"
#include "skgservices.h"
SKGDateEditDesignerPlugin::SKGDateEditDesignerPlugin(QObject* iParent)
: QObject(iParent)
{
m_initialized = false;
}
void SKGDateEditDesignerPlugin::initialize(QDesignerFormEditorInterface* iCore)
{
Q_UNUSED(iCore)
if (m_initialized) {
return;
}
m_initialized = true;
}
bool SKGDateEditDesignerPlugin::isInitialized() const
{
return m_initialized;
}
QWidget* SKGDateEditDesignerPlugin::createWidget(QWidget* iParent)
{
return new SKGDateEdit(iParent);
}
QString SKGDateEditDesignerPlugin::name() const
{
return QStringLiteral("SKGDateEdit");
}
QString SKGDateEditDesignerPlugin::group() const
{
return QStringLiteral("SKG Widgets");
}
QIcon SKGDateEditDesignerPlugin::icon() const
{
return SKGServices::fromTheme(QStringLiteral("quickopen"));
}
QString SKGDateEditDesignerPlugin::toolTip() const
{
return QStringLiteral("A date editor with more features");
}
QString SKGDateEditDesignerPlugin::whatsThis() const
{
return QStringLiteral("A date editor with more features");
}
bool SKGDateEditDesignerPlugin::isContainer() const
{
return false;
}
QString SKGDateEditDesignerPlugin::domXml() const
{
return QStringLiteral("<widget class=\"SKGDateEdit\" name=\"SKGDateEdit\">\n"
" <property name=\"geometry\">\n"
" <rect>\n"
" <x>0</x>\n"
" <y>0</y>\n"
" <width>100</width>\n"
" <height>10</height>\n"
" </rect>\n"
" </property>\n"
"</widget>\n");
}
QString SKGDateEditDesignerPlugin::includeFile() const
{
return QStringLiteral("skgdateedit.h");
}
diff --git a/skgbaseguidesigner/skgdateeditdesignerplugin.h b/skgbaseguidesigner/skgdateeditdesignerplugin.h
index 8b9f97096..cde9d473b 100644
--- a/skgbaseguidesigner/skgdateeditdesignerplugin.h
+++ b/skgbaseguidesigner/skgdateeditdesignerplugin.h
@@ -1,112 +1,112 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGDATEEDITDESIGNERPLUGIN_H
#define SKGDATEEDITDESIGNERPLUGIN_H
/** @file
* A date edit with more features (qt designer plugin).
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include <customwidget.h>
/**
* QDesigner plugin for SKGDateEdit
*/
class SKGDateEditDesignerPlugin : public QObject, public QDesignerCustomWidgetInterface
{
Q_OBJECT
Q_INTERFACES(QDesignerCustomWidgetInterface)
public:
/**
* Constructor
* @param iParent parent
*/
explicit SKGDateEditDesignerPlugin(QObject* iParent = nullptr);
/**
* To know if the component is a container
* @return true or false
*/
bool isContainer() const override;
/**
* To know if the component is initialized
* @return true or false
*/
bool isInitialized() const override;
/**
* To get the icon for this component
* @return the icon
*/
QIcon icon() const override;
/**
* To get the icon for this component
* @return
*/
QString domXml() const override;
/**
* To get the group for this component
* @return group
*/
QString group() const override;
/**
* To get the include file for this component
* @return the include file
*/
QString includeFile() const override;
/**
* To get the name for this component
* @return name
*/
QString name() const override;
/**
* To get the "tool tip" for this component
* @return the "tool tip"
*/
QString toolTip() const override;
/**
* To get the "whats this" for this component
* @return the "whats this"
*/
QString whatsThis() const override;
/**
* To get the widget representing the component
* @param iParent the parent of the widget
* @return the widget
*/
QWidget* createWidget(QWidget* iParent) override;
/**
* Initilialize the component
* @param iCore interface
*/
void initialize(QDesignerFormEditorInterface* iCore) override;
private:
bool m_initialized;
};
#endif
diff --git a/skgbaseguidesigner/skgfilteredtableviewdesignerplugin.cpp b/skgbaseguidesigner/skgfilteredtableviewdesignerplugin.cpp
index 990c1d471..0f9ce70c5 100644
--- a/skgbaseguidesigner/skgfilteredtableviewdesignerplugin.cpp
+++ b/skgbaseguidesigner/skgfilteredtableviewdesignerplugin.cpp
@@ -1,104 +1,104 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* A filetered SKGTableView (qt designer plugin).
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgfilteredtableviewdesignerplugin.h"
#include <qicon.h>
#include <qplugin.h>
#include "skgfilteredtableview.h"
SKGFilteredTableViewDesignerPlugin::SKGFilteredTableViewDesignerPlugin(QObject* iParent)
: QObject(iParent)
{
m_initialized = false;
}
void SKGFilteredTableViewDesignerPlugin::initialize(QDesignerFormEditorInterface* iCore)
{
Q_UNUSED(iCore)
if (m_initialized) {
return;
}
m_initialized = true;
}
bool SKGFilteredTableViewDesignerPlugin::isInitialized() const
{
return m_initialized;
}
QWidget* SKGFilteredTableViewDesignerPlugin::createWidget(QWidget* iParent)
{
return new SKGFilteredTableView(iParent);
}
QString SKGFilteredTableViewDesignerPlugin::name() const
{
return QStringLiteral("SKGFilteredTableView");
}
QString SKGFilteredTableViewDesignerPlugin::group() const
{
return QStringLiteral("SKG Widgets");
}
QIcon SKGFilteredTableViewDesignerPlugin::icon() const
{
return SKGServices::fromTheme(QStringLiteral("quickopen"));
}
QString SKGFilteredTableViewDesignerPlugin::toolTip() const
{
return QStringLiteral("A filetered SKGTableView");
}
QString SKGFilteredTableViewDesignerPlugin::whatsThis() const
{
return QStringLiteral("A filetered SKGTableView");
}
bool SKGFilteredTableViewDesignerPlugin::isContainer() const
{
return false;
}
QString SKGFilteredTableViewDesignerPlugin::domXml() const
{
return QStringLiteral("<widget class=\"SKGFilteredTableView\" name=\"SKGFilteredTableView\">\n"
" <property name=\"geometry\">\n"
" <rect>\n"
" <x>0</x>\n"
" <y>0</y>\n"
" <width>100</width>\n"
" <height>10</height>\n"
" </rect>\n"
" </property>\n"
"</widget>\n");
}
QString SKGFilteredTableViewDesignerPlugin::includeFile() const
{
return QStringLiteral("skgfilteredtableview.h");
}
diff --git a/skgbaseguidesigner/skgfilteredtableviewdesignerplugin.h b/skgbaseguidesigner/skgfilteredtableviewdesignerplugin.h
index 8a24eb2e7..ff765af06 100644
--- a/skgbaseguidesigner/skgfilteredtableviewdesignerplugin.h
+++ b/skgbaseguidesigner/skgfilteredtableviewdesignerplugin.h
@@ -1,112 +1,112 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGFILTEREDTABLEVIEWDESIGNERPLUGIN_H
#define SKGFILTEREDTABLEVIEWDESIGNERPLUGIN_H
/** @file
* A widget to select what to show (qt designer plugin).
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include <customwidget.h>
/**
* QDesigner plugin for SKGFilteredTableView
*/
class SKGFilteredTableViewDesignerPlugin : public QObject, public QDesignerCustomWidgetInterface
{
Q_OBJECT
Q_INTERFACES(QDesignerCustomWidgetInterface)
public:
/**
* Constructor
* @param iParent parent
*/
explicit SKGFilteredTableViewDesignerPlugin(QObject* iParent = nullptr);
/**
* To know if the component is a container
* @return true or false
*/
bool isContainer() const override;
/**
* To know if the component is initialized
* @return true or false
*/
bool isInitialized() const override;
/**
* To get the icon for this component
* @return the icon
*/
QIcon icon() const override;
/**
* To get the icon for this component
* @return
*/
QString domXml() const override;
/**
* To get the group for this component
* @return group
*/
QString group() const override;
/**
* To get the include file for this component
* @return the include file
*/
QString includeFile() const override;
/**
* To get the name for this component
* @return name
*/
QString name() const override;
/**
* To get the "tool tip" for this component
* @return the "tool tip"
*/
QString toolTip() const override;
/**
* To get the "whats this" for this component
* @return the "whats this"
*/
QString whatsThis() const override;
/**
* To get the widget representing the component
* @param iParent the parent of the widget
* @return the widget
*/
QWidget* createWidget(QWidget* iParent) override;
/**
* Initilialize the component
* @param iCore interface
*/
void initialize(QDesignerFormEditorInterface* iCore) override;
private:
bool m_initialized;
};
#endif
diff --git a/skgbaseguidesigner/skggraphicsviewdesignerplugin.cpp b/skgbaseguidesigner/skggraphicsviewdesignerplugin.cpp
index cd4212a8c..97583734a 100644
--- a/skgbaseguidesigner/skggraphicsviewdesignerplugin.cpp
+++ b/skgbaseguidesigner/skggraphicsviewdesignerplugin.cpp
@@ -1,103 +1,103 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* A Graphic view with more features (qt designer plugin).
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skggraphicsviewdesignerplugin.h"
#include "skggraphicsview.h"
#include "skgservices.h"
SKGGraphicsViewDesignerPlugin::SKGGraphicsViewDesignerPlugin(QObject* iParent)
: QObject(iParent)
{
m_initialized = false;
}
void SKGGraphicsViewDesignerPlugin::initialize(QDesignerFormEditorInterface* iCore)
{
Q_UNUSED(iCore)
if (m_initialized) {
return;
}
m_initialized = true;
}
bool SKGGraphicsViewDesignerPlugin::isInitialized() const
{
return m_initialized;
}
QWidget* SKGGraphicsViewDesignerPlugin::createWidget(QWidget* iParent)
{
return new SKGGraphicsView(iParent);
}
QString SKGGraphicsViewDesignerPlugin::name() const
{
return QStringLiteral("SKGGraphicsView");
}
QString SKGGraphicsViewDesignerPlugin::group() const
{
return QStringLiteral("SKG Widgets");
}
QIcon SKGGraphicsViewDesignerPlugin::icon() const
{
return SKGServices::fromTheme(QStringLiteral("quickopen"));
}
QString SKGGraphicsViewDesignerPlugin::toolTip() const
{
return QStringLiteral("A Graphic view");
}
QString SKGGraphicsViewDesignerPlugin::whatsThis() const
{
return QStringLiteral("A Graphic view");
}
bool SKGGraphicsViewDesignerPlugin::isContainer() const
{
return false;
}
QString SKGGraphicsViewDesignerPlugin::domXml() const
{
return QStringLiteral("<widget class=\"SKGGraphicsView\" name=\"SKGGraphicsView\">\n"
" <property name=\"geometry\">\n"
" <rect>\n"
" <x>0</x>\n"
" <y>0</y>\n"
" <width>100</width>\n"
" <height>100</height>\n"
" </rect>\n"
" </property>\n"
"</widget>\n");
}
QString SKGGraphicsViewDesignerPlugin::includeFile() const
{
return QStringLiteral("skggraphicsview.h");
}
diff --git a/skgbaseguidesigner/skggraphicsviewdesignerplugin.h b/skgbaseguidesigner/skggraphicsviewdesignerplugin.h
index 70a48b4cc..d4ab9a760 100644
--- a/skgbaseguidesigner/skggraphicsviewdesignerplugin.h
+++ b/skgbaseguidesigner/skggraphicsviewdesignerplugin.h
@@ -1,112 +1,112 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGGRAPHICSVIEWDESIGNERPLUGIN_H
#define SKGGRAPHICSVIEWDESIGNERPLUGIN_H
/** @file
* A Graphic view with more functionalities (qt designer plugin).
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include <customwidget.h>
/**
* QDesigner plugin for SKGGraphicsView
*/
class SKGGraphicsViewDesignerPlugin : public QObject, public QDesignerCustomWidgetInterface
{
Q_OBJECT
Q_INTERFACES(QDesignerCustomWidgetInterface)
public:
/**
* Constructor
* @param iParent parent
*/
explicit SKGGraphicsViewDesignerPlugin(QObject* iParent = nullptr);
/**
* To know if the component is a container
* @return true or false
*/
bool isContainer() const override;
/**
* To know if the component is initialized
* @return true or false
*/
bool isInitialized() const override;
/**
* To get the icon for this component
* @return the icon
*/
QIcon icon() const override;
/**
* To get the icon for this component
* @return
*/
QString domXml() const override;
/**
* To get the group for this component
* @return group
*/
QString group() const override;
/**
* To get the include file for this component
* @return the include file
*/
QString includeFile() const override;
/**
* To get the name for this component
* @return name
*/
QString name() const override;
/**
* To get the "tool tip" for this component
* @return the "tool tip"
*/
QString toolTip() const override;
/**
* To get the "whats this" for this component
* @return the "whats this"
*/
QString whatsThis() const override;
/**
* To get the widget representing the component
* @param iParent the parent of the widget
* @return the widget
*/
QWidget* createWidget(QWidget* iParent) override;
/**
* Initilialize the component
* @param iCore interface
*/
void initialize(QDesignerFormEditorInterface* iCore) override;
private:
bool m_initialized;
};
#endif
diff --git a/skgbaseguidesigner/skgperiodeditdesignerplugin.cpp b/skgbaseguidesigner/skgperiodeditdesignerplugin.cpp
index d31974c76..f979bda84 100644
--- a/skgbaseguidesigner/skgperiodeditdesignerplugin.cpp
+++ b/skgbaseguidesigner/skgperiodeditdesignerplugin.cpp
@@ -1,103 +1,103 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* A period editor (qt designer plugin).
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgperiodeditdesignerplugin.h"
#include "skgperiodedit.h"
#include "skgservices.h"
SKGPeriodEditDesignerPlugin::SKGPeriodEditDesignerPlugin(QObject* iParent)
: QObject(iParent)
{
m_initialized = false;
}
void SKGPeriodEditDesignerPlugin::initialize(QDesignerFormEditorInterface* iCore)
{
Q_UNUSED(iCore)
if (m_initialized) {
return;
}
m_initialized = true;
}
bool SKGPeriodEditDesignerPlugin::isInitialized() const
{
return m_initialized;
}
QWidget* SKGPeriodEditDesignerPlugin::createWidget(QWidget* iParent)
{
return new SKGPeriodEdit(iParent);
}
QString SKGPeriodEditDesignerPlugin::name() const
{
return QStringLiteral("SKGPeriodEdit");
}
QString SKGPeriodEditDesignerPlugin::group() const
{
return QStringLiteral("SKG Widgets");
}
QIcon SKGPeriodEditDesignerPlugin::icon() const
{
return SKGServices::fromTheme(QStringLiteral("quickopen"));
}
QString SKGPeriodEditDesignerPlugin::toolTip() const
{
return QStringLiteral("A period editor");
}
QString SKGPeriodEditDesignerPlugin::whatsThis() const
{
return QStringLiteral("A period editor");
}
bool SKGPeriodEditDesignerPlugin::isContainer() const
{
return false;
}
QString SKGPeriodEditDesignerPlugin::domXml() const
{
return QStringLiteral("<widget class=\"SKGPeriodEdit\" name=\"SKGPeriodEdit\">\n"
" <property name=\"geometry\">\n"
" <rect>\n"
" <x>0</x>\n"
" <y>0</y>\n"
" <width>100</width>\n"
" <height>10</height>\n"
" </rect>\n"
" </property>\n"
"</widget>\n");
}
QString SKGPeriodEditDesignerPlugin::includeFile() const
{
return QStringLiteral("skgperiodedit.h");
}
diff --git a/skgbaseguidesigner/skgperiodeditdesignerplugin.h b/skgbaseguidesigner/skgperiodeditdesignerplugin.h
index 4396a84d4..b9bfeaf84 100644
--- a/skgbaseguidesigner/skgperiodeditdesignerplugin.h
+++ b/skgbaseguidesigner/skgperiodeditdesignerplugin.h
@@ -1,112 +1,112 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGPERIODEDITDESIGNERPLUGIN_H
#define SKGPERIODEDITDESIGNERPLUGIN_H
/** @file
* A period editor (qt designer plugin).
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include <customwidget.h>
/**
* QDesigner plugin for SKGColorButton
*/
class SKGPeriodEditDesignerPlugin : public QObject, public QDesignerCustomWidgetInterface
{
Q_OBJECT
Q_INTERFACES(QDesignerCustomWidgetInterface)
public:
/**
* Constructor
* @param iParent parent
*/
explicit SKGPeriodEditDesignerPlugin(QObject* iParent = nullptr);
/**
* To know if the component is a container
* @return true or false
*/
bool isContainer() const override;
/**
* To know if the component is initialized
* @return true or false
*/
bool isInitialized() const override;
/**
* To get the icon for this component
* @return the icon
*/
QIcon icon() const override;
/**
* To get the icon for this component
* @return
*/
QString domXml() const override;
/**
* To get the group for this component
* @return group
*/
QString group() const override;
/**
* To get the include file for this component
* @return the include file
*/
QString includeFile() const override;
/**
* To get the name for this component
* @return name
*/
QString name() const override;
/**
* To get the "tool tip" for this component
* @return the "tool tip"
*/
QString toolTip() const override;
/**
* To get the "whats this" for this component
* @return the "whats this"
*/
QString whatsThis() const override;
/**
* To get the widget representing the component
* @param iParent the parent of the widget
* @return the widget
*/
QWidget* createWidget(QWidget* iParent) override;
/**
* Initilialize the component
* @param iCore interface
*/
void initialize(QDesignerFormEditorInterface* iCore) override;
private:
bool m_initialized;
};
#endif
diff --git a/skgbaseguidesigner/skgprogressbardesignerplugin.cpp b/skgbaseguidesigner/skgprogressbardesignerplugin.cpp
index e312ec750..a142881ee 100644
--- a/skgbaseguidesigner/skgprogressbardesignerplugin.cpp
+++ b/skgbaseguidesigner/skgprogressbardesignerplugin.cpp
@@ -1,103 +1,103 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* A progress bar with colors
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgprogressbardesignerplugin.h"
#include "skgprogressbar.h"
#include "skgservices.h"
SKGProgressBarDesignerPlugin::SKGProgressBarDesignerPlugin(QObject* iParent)
: QObject(iParent)
{
m_initialized = false;
}
void SKGProgressBarDesignerPlugin::initialize(QDesignerFormEditorInterface* iCore)
{
Q_UNUSED(iCore)
if (m_initialized) {
return;
}
m_initialized = true;
}
bool SKGProgressBarDesignerPlugin::isInitialized() const
{
return m_initialized;
}
QWidget* SKGProgressBarDesignerPlugin::createWidget(QWidget* iParent)
{
return new SKGProgressBar(iParent);
}
QString SKGProgressBarDesignerPlugin::name() const
{
return QStringLiteral("SKGProgressBar");
}
QString SKGProgressBarDesignerPlugin::group() const
{
return QStringLiteral("SKG Widgets");
}
QIcon SKGProgressBarDesignerPlugin::icon() const
{
return SKGServices::fromTheme(QStringLiteral("quickopen"));
}
QString SKGProgressBarDesignerPlugin::toolTip() const
{
return QStringLiteral("A progress bar with colors");
}
QString SKGProgressBarDesignerPlugin::whatsThis() const
{
return QStringLiteral("A progress bar with colors");
}
bool SKGProgressBarDesignerPlugin::isContainer() const
{
return false;
}
QString SKGProgressBarDesignerPlugin::domXml() const
{
return QStringLiteral("<widget class=\"SKGProgressBar\" name=\"SKGProgressBar\">\n"
" <property name=\"geometry\">\n"
" <rect>\n"
" <x>0</x>\n"
" <y>0</y>\n"
" <width>100</width>\n"
" <height>10</height>\n"
" </rect>\n"
" </property>\n"
"</widget>\n");
}
QString SKGProgressBarDesignerPlugin::includeFile() const
{
return QStringLiteral("skgprogressbar.h");
}
diff --git a/skgbaseguidesigner/skgprogressbardesignerplugin.h b/skgbaseguidesigner/skgprogressbardesignerplugin.h
index 540f004ed..1bf7baa53 100644
--- a/skgbaseguidesigner/skgprogressbardesignerplugin.h
+++ b/skgbaseguidesigner/skgprogressbardesignerplugin.h
@@ -1,112 +1,112 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGPROGRESSBARDESIGNERPLUGIN_H
#define SKGPROGRESSBARDESIGNERPLUGIN_H
/** @file
* A progress bar with colors
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include <customwidget.h>
/**
* QDesigner plugin for SKGProgressBar
*/
class SKGProgressBarDesignerPlugin : public QObject, public QDesignerCustomWidgetInterface
{
Q_OBJECT
Q_INTERFACES(QDesignerCustomWidgetInterface)
public:
/**
* Constructor
* @param iParent parent
*/
explicit SKGProgressBarDesignerPlugin(QObject* iParent = nullptr);
/**
* To know if the component is a container
* @return true or false
*/
bool isContainer() const override;
/**
* To know if the component is initialized
* @return true or false
*/
bool isInitialized() const override;
/**
* To get the icon for this component
* @return the icon
*/
QIcon icon() const override;
/**
* To get the icon for this component
* @return
*/
QString domXml() const override;
/**
* To get the group for this component
* @return group
*/
QString group() const override;
/**
* To get the include file for this component
* @return the include file
*/
QString includeFile() const override;
/**
* To get the name for this component
* @return name
*/
QString name() const override;
/**
* To get the "tool tip" for this component
* @return the "tool tip"
*/
QString toolTip() const override;
/**
* To get the "whats this" for this component
* @return the "whats this"
*/
QString whatsThis() const override;
/**
* To get the widget representing the component
* @param iParent the parent of the widget
* @return the widget
*/
QWidget* createWidget(QWidget* iParent) override;
/**
* Initilialize the component
* @param iCore interface
*/
void initialize(QDesignerFormEditorInterface* iCore) override;
private:
bool m_initialized;
};
#endif
diff --git a/skgbaseguidesigner/skgshowdesignerplugin.cpp b/skgbaseguidesigner/skgshowdesignerplugin.cpp
index 338821b2f..5bd81f68d 100644
--- a/skgbaseguidesigner/skgshowdesignerplugin.cpp
+++ b/skgbaseguidesigner/skgshowdesignerplugin.cpp
@@ -1,103 +1,103 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* A widget to select what to show (qt designer plugin).
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgshowdesignerplugin.h"
#include <qicon.h>
#include "skgservices.h"
#include "skgshow.h"
SKGShowDesignerPlugin::SKGShowDesignerPlugin(QObject* iParent)
: QObject(iParent)
{
m_initialized = false;
}
void SKGShowDesignerPlugin::initialize(QDesignerFormEditorInterface* iCore)
{
Q_UNUSED(iCore)
if (m_initialized) {
return;
}
m_initialized = true;
}
bool SKGShowDesignerPlugin::isInitialized() const
{
return m_initialized;
}
QWidget* SKGShowDesignerPlugin::createWidget(QWidget* iParent)
{
return new SKGShow(iParent);
}
QString SKGShowDesignerPlugin::name() const
{
return QStringLiteral("SKGShow");
}
QString SKGShowDesignerPlugin::group() const
{
return QStringLiteral("SKG Widgets");
}
QIcon SKGShowDesignerPlugin::icon() const
{
return SKGServices::fromTheme(QStringLiteral("quickopen"));
}
QString SKGShowDesignerPlugin::toolTip() const
{
return QStringLiteral("A widget to select what to show");
}
QString SKGShowDesignerPlugin::whatsThis() const
{
return QStringLiteral("A widget to select what to show");
}
bool SKGShowDesignerPlugin::isContainer() const
{
return false;
}
QString SKGShowDesignerPlugin::domXml() const
{
return QStringLiteral("<widget class=\"SKGShow\" name=\"SKGShow\">\n"
" <property name=\"geometry\">\n"
" <rect>\n"
" <x>0</x>\n"
" <y>0</y>\n"
" <width>100</width>\n"
" <height>10</height>\n"
" </rect>\n"
" </property>\n"
"</widget>\n");
}
QString SKGShowDesignerPlugin::includeFile() const
{
return QStringLiteral("skgshow.h");
}
diff --git a/skgbaseguidesigner/skgshowdesignerplugin.h b/skgbaseguidesigner/skgshowdesignerplugin.h
index 2f61dac43..a54e64248 100644
--- a/skgbaseguidesigner/skgshowdesignerplugin.h
+++ b/skgbaseguidesigner/skgshowdesignerplugin.h
@@ -1,112 +1,112 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGSHOWDESIGNERPLUGIN_H
#define SKGSHOWDESIGNERPLUGIN_H
/** @file
* A widget to select what to show (qt designer plugin).
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include <customwidget.h>
/**
* QDesigner plugin for SKGShow
*/
class SKGShowDesignerPlugin : public QObject, public QDesignerCustomWidgetInterface
{
Q_OBJECT
Q_INTERFACES(QDesignerCustomWidgetInterface)
public:
/**
* Constructor
* @param iParent parent
*/
explicit SKGShowDesignerPlugin(QObject* iParent = nullptr);
/**
* To know if the component is a container
* @return true or false
*/
bool isContainer() const override;
/**
* To know if the component is initialized
* @return true or false
*/
bool isInitialized() const override;
/**
* To get the icon for this component
* @return the icon
*/
QIcon icon() const override;
/**
* To get the icon for this component
* @return
*/
QString domXml() const override;
/**
* To get the group for this component
* @return group
*/
QString group() const override;
/**
* To get the include file for this component
* @return the include file
*/
QString includeFile() const override;
/**
* To get the name for this component
* @return name
*/
QString name() const override;
/**
* To get the "tool tip" for this component
* @return the "tool tip"
*/
QString toolTip() const override;
/**
* To get the "whats this" for this component
* @return the "whats this"
*/
QString whatsThis() const override;
/**
* To get the widget representing the component
* @param iParent the parent of the widget
* @return the widget
*/
QWidget* createWidget(QWidget* iParent) override;
/**
* Initilialize the component
* @param iCore interface
*/
void initialize(QDesignerFormEditorInterface* iCore) override;
private:
bool m_initialized;
};
#endif
diff --git a/skgbaseguidesigner/skgsimpleperiodeditdesignerplugin.cpp b/skgbaseguidesigner/skgsimpleperiodeditdesignerplugin.cpp
index 27d385829..961bd84d7 100644
--- a/skgbaseguidesigner/skgsimpleperiodeditdesignerplugin.cpp
+++ b/skgbaseguidesigner/skgsimpleperiodeditdesignerplugin.cpp
@@ -1,103 +1,103 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* A period editor (qt designer plugin).
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgsimpleperiodeditdesignerplugin.h"
#include "skgservices.h"
#include "skgsimpleperiodedit.h"
SKGSimplePeriodEditDesignerPlugin::SKGSimplePeriodEditDesignerPlugin(QObject* iParent)
: QObject(iParent)
{
m_initialized = false;
}
void SKGSimplePeriodEditDesignerPlugin::initialize(QDesignerFormEditorInterface* iCore)
{
Q_UNUSED(iCore)
if (m_initialized) {
return;
}
m_initialized = true;
}
bool SKGSimplePeriodEditDesignerPlugin::isInitialized() const
{
return m_initialized;
}
QWidget* SKGSimplePeriodEditDesignerPlugin::createWidget(QWidget* iParent)
{
return new SKGSimplePeriodEdit(iParent);
}
QString SKGSimplePeriodEditDesignerPlugin::name() const
{
return QStringLiteral("SKGSimplePeriodEdit");
}
QString SKGSimplePeriodEditDesignerPlugin::group() const
{
return QStringLiteral("SKG Widgets");
}
QIcon SKGSimplePeriodEditDesignerPlugin::icon() const
{
return SKGServices::fromTheme(QStringLiteral("quickopen"));
}
QString SKGSimplePeriodEditDesignerPlugin::toolTip() const
{
return QStringLiteral("A simple period editor");
}
QString SKGSimplePeriodEditDesignerPlugin::whatsThis() const
{
return QStringLiteral("A simple period editor");
}
bool SKGSimplePeriodEditDesignerPlugin::isContainer() const
{
return false;
}
QString SKGSimplePeriodEditDesignerPlugin::domXml() const
{
return QStringLiteral("<widget class=\"SKGSimplePeriodEdit\" name=\"SKGSimplePeriodEdit\">\n"
" <property name=\"geometry\">\n"
" <rect>\n"
" <x>0</x>\n"
" <y>0</y>\n"
" <width>100</width>\n"
" <height>10</height>\n"
" </rect>\n"
" </property>\n"
"</widget>\n");
}
QString SKGSimplePeriodEditDesignerPlugin::includeFile() const
{
return QStringLiteral("skgsimpleperiodedit.h");
}
diff --git a/skgbaseguidesigner/skgsimpleperiodeditdesignerplugin.h b/skgbaseguidesigner/skgsimpleperiodeditdesignerplugin.h
index 9da4c57a6..d4ff64d5c 100644
--- a/skgbaseguidesigner/skgsimpleperiodeditdesignerplugin.h
+++ b/skgbaseguidesigner/skgsimpleperiodeditdesignerplugin.h
@@ -1,112 +1,112 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGSIMPLEPERIODEDITDESIGNERPLUGIN_H
#define SKGSIMPLEPERIODEDITDESIGNERPLUGIN_H
/** @file
* A period editor (qt designer plugin).
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include <customwidget.h>
/**
* QDesigner plugin for SKGColorButton
*/
class SKGSimplePeriodEditDesignerPlugin : public QObject, public QDesignerCustomWidgetInterface
{
Q_OBJECT
Q_INTERFACES(QDesignerCustomWidgetInterface)
public:
/**
* Constructor
* @param iParent parent
*/
explicit SKGSimplePeriodEditDesignerPlugin(QObject* iParent = nullptr);
/**
* To know if the component is a container
* @return true or false
*/
bool isContainer() const override;
/**
* To know if the component is initialized
* @return true or false
*/
bool isInitialized() const override;
/**
* To get the icon for this component
* @return the icon
*/
QIcon icon() const override;
/**
* To get the icon for this component
* @return
*/
QString domXml() const override;
/**
* To get the group for this component
* @return group
*/
QString group() const override;
/**
* To get the include file for this component
* @return the include file
*/
QString includeFile() const override;
/**
* To get the name for this component
* @return name
*/
QString name() const override;
/**
* To get the "tool tip" for this component
* @return the "tool tip"
*/
QString toolTip() const override;
/**
* To get the "whats this" for this component
* @return the "whats this"
*/
QString whatsThis() const override;
/**
* To get the widget representing the component
* @param iParent the parent of the widget
* @return the widget
*/
QWidget* createWidget(QWidget* iParent) override;
/**
* Initilialize the component
* @param iCore interface
*/
void initialize(QDesignerFormEditorInterface* iCore) override;
private:
bool m_initialized;
};
#endif
diff --git a/skgbaseguidesigner/skgtableviewdesignerplugin.cpp b/skgbaseguidesigner/skgtableviewdesignerplugin.cpp
index a16052684..ee59baf96 100644
--- a/skgbaseguidesigner/skgtableviewdesignerplugin.cpp
+++ b/skgbaseguidesigner/skgtableviewdesignerplugin.cpp
@@ -1,102 +1,102 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* A table view with more features (qt designer plugin).
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgtableviewdesignerplugin.h"
#include <qicon.h>
#include "skgtableview.h"
SKGTableViewDesignerPlugin::SKGTableViewDesignerPlugin(QObject* iParent)
: QObject(iParent)
{
m_initialized = false;
}
void SKGTableViewDesignerPlugin::initialize(QDesignerFormEditorInterface* iCore)
{
Q_UNUSED(iCore)
if (m_initialized) {
return;
}
m_initialized = true;
}
bool SKGTableViewDesignerPlugin::isInitialized() const
{
return m_initialized;
}
QWidget* SKGTableViewDesignerPlugin::createWidget(QWidget* iParent)
{
return new SKGTableView(iParent);
}
QString SKGTableViewDesignerPlugin::name() const
{
return QStringLiteral("SKGTableView");
}
QString SKGTableViewDesignerPlugin::group() const
{
return QStringLiteral("SKG Widgets");
}
QIcon SKGTableViewDesignerPlugin::icon() const
{
return SKGServices::fromTheme(QStringLiteral("quickopen"));
}
QString SKGTableViewDesignerPlugin::toolTip() const
{
return QStringLiteral("A table view with more features");
}
QString SKGTableViewDesignerPlugin::whatsThis() const
{
return QStringLiteral("A table view with more features");
}
bool SKGTableViewDesignerPlugin::isContainer() const
{
return true;
}
QString SKGTableViewDesignerPlugin::domXml() const
{
return QStringLiteral("<widget class=\"SKGTableView\" name=\"SKGTableView\">\n"
" <property name=\"geometry\">\n"
" <rect>\n"
" <x>0</x>\n"
" <y>0</y>\n"
" <width>100</width>\n"
" <height>100</height>\n"
" </rect>\n"
" </property>\n"
"</widget>\n");
}
QString SKGTableViewDesignerPlugin::includeFile() const
{
return QStringLiteral("skgtableview.h");
}
diff --git a/skgbaseguidesigner/skgtableviewdesignerplugin.h b/skgbaseguidesigner/skgtableviewdesignerplugin.h
index 89bcfc5fb..25b5cf505 100644
--- a/skgbaseguidesigner/skgtableviewdesignerplugin.h
+++ b/skgbaseguidesigner/skgtableviewdesignerplugin.h
@@ -1,112 +1,112 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGTABLEVIEWDESIGNERPLUGIN_H
#define SKGTABLEVIEWDESIGNERPLUGIN_H
/** @file
* A table view with more features (qt designer plugin).
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include <customwidget.h>
/**
* QDesigner plugin for SKGTableView
*/
class SKGTableViewDesignerPlugin : public QObject, public QDesignerCustomWidgetInterface
{
Q_OBJECT
Q_INTERFACES(QDesignerCustomWidgetInterface)
public:
/**
* Constructor
* @param iParent parent
*/
explicit SKGTableViewDesignerPlugin(QObject* iParent = nullptr);
/**
* To know if the component is a container
* @return true or false
*/
bool isContainer() const override;
/**
* To know if the component is initialized
* @return true or false
*/
bool isInitialized() const override;
/**
* To get the icon for this component
* @return the icon
*/
QIcon icon() const override;
/**
* To get the icon for this component
* @return
*/
QString domXml() const override;
/**
* To get the group for this component
* @return group
*/
QString group() const override;
/**
* To get the include file for this component
* @return the include file
*/
QString includeFile() const override;
/**
* To get the name for this component
* @return name
*/
QString name() const override;
/**
* To get the "tool tip" for this component
* @return the "tool tip"
*/
QString toolTip() const override;
/**
* To get the "whats this" for this component
* @return the "whats this"
*/
QString whatsThis() const override;
/**
* To get the widget representing the component
* @param iParent the parent of the widget
* @return the widget
*/
QWidget* createWidget(QWidget* iParent) override;
/**
* Initilialize the component
* @param iCore interface
*/
void initialize(QDesignerFormEditorInterface* iCore) override;
private:
bool m_initialized;
};
#endif
diff --git a/skgbaseguidesigner/skgtablewidgetdesignerplugin.cpp b/skgbaseguidesigner/skgtablewidgetdesignerplugin.cpp
index c1b98a83f..3ce7a2a87 100644
--- a/skgbaseguidesigner/skgtablewidgetdesignerplugin.cpp
+++ b/skgbaseguidesigner/skgtablewidgetdesignerplugin.cpp
@@ -1,101 +1,101 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* A table widget with more features (qt designer plugin).
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgtablewidgetdesignerplugin.h"
#include "skgservices.h"
#include "skgtablewidget.h"
SKGTableWidgetDesignerPlugin::SKGTableWidgetDesignerPlugin(QObject* iParent)
: QObject(iParent)
{
m_initialized = false;
}
void SKGTableWidgetDesignerPlugin::initialize(QDesignerFormEditorInterface* iCore)
{
Q_UNUSED(iCore)
if (m_initialized) {
return;
}
m_initialized = true;
}
bool SKGTableWidgetDesignerPlugin::isInitialized() const
{
return m_initialized;
}
QWidget* SKGTableWidgetDesignerPlugin::createWidget(QWidget* iParent)
{
return new SKGTableWidget(iParent);
}
QString SKGTableWidgetDesignerPlugin::name() const
{
return QStringLiteral("SKGTableWidget");
}
QString SKGTableWidgetDesignerPlugin::group() const
{
return QStringLiteral("SKG Widgets");
}
QIcon SKGTableWidgetDesignerPlugin::icon() const
{
return SKGServices::fromTheme(QStringLiteral("quickopen"));
}
QString SKGTableWidgetDesignerPlugin::toolTip() const
{
return QStringLiteral("A table widget with more features");
}
QString SKGTableWidgetDesignerPlugin::whatsThis() const
{
return QStringLiteral("A table widget with more features");
}
bool SKGTableWidgetDesignerPlugin::isContainer() const
{
return false;
}
QString SKGTableWidgetDesignerPlugin::domXml() const
{
return QStringLiteral("<widget class=\"SKGTableWidget\" name=\"SKGTableWidget\">\n"
" <property name=\"geometry\">\n"
" <rect>\n"
" <x>0</x>\n"
" <y>0</y>\n"
" <width>100</width>\n"
" <height>10</height>\n"
" </rect>\n"
" </property>\n"
"</widget>\n");
}
QString SKGTableWidgetDesignerPlugin::includeFile() const
{
return QStringLiteral("skgtablewidget.h");
}
diff --git a/skgbaseguidesigner/skgtablewidgetdesignerplugin.h b/skgbaseguidesigner/skgtablewidgetdesignerplugin.h
index 839d519b7..64661f0c7 100644
--- a/skgbaseguidesigner/skgtablewidgetdesignerplugin.h
+++ b/skgbaseguidesigner/skgtablewidgetdesignerplugin.h
@@ -1,112 +1,112 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGTABLEWIDGETDESIGNERPLUGIN_H
#define SKGTABLEWIDGETDESIGNERPLUGIN_H
/** @file
* A table widget with more features (qt designer plugin).
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include <customwidget.h>
/**
* QDesigner plugin for SKGTableWidget
*/
class SKGTableWidgetDesignerPlugin : public QObject, public QDesignerCustomWidgetInterface
{
Q_OBJECT
Q_INTERFACES(QDesignerCustomWidgetInterface)
public:
/**
* Constructor
* @param iParent parent
*/
explicit SKGTableWidgetDesignerPlugin(QObject* iParent = nullptr);
/**
* To know if the component is a container
* @return true or false
*/
bool isContainer() const override;
/**
* To know if the component is initialized
* @return true or false
*/
bool isInitialized() const override;
/**
* To get the icon for this component
* @return the icon
*/
QIcon icon() const override;
/**
* To get the icon for this component
* @return
*/
QString domXml() const override;
/**
* To get the group for this component
* @return group
*/
QString group() const override;
/**
* To get the include file for this component
* @return the include file
*/
QString includeFile() const override;
/**
* To get the name for this component
* @return name
*/
QString name() const override;
/**
* To get the "tool tip" for this component
* @return the "tool tip"
*/
QString toolTip() const override;
/**
* To get the "whats this" for this component
* @return the "whats this"
*/
QString whatsThis() const override;
/**
* To get the widget representing the component
* @param iParent the parent of the widget
* @return the widget
*/
QWidget* createWidget(QWidget* iParent) override;
/**
* Initilialize the component
* @param iCore interface
*/
void initialize(QDesignerFormEditorInterface* iCore) override;
private:
bool m_initialized;
};
#endif
diff --git a/skgbaseguidesigner/skgtablewithgraphdesignerplugin.cpp b/skgbaseguidesigner/skgtablewithgraphdesignerplugin.cpp
index 7e9c5bea8..fcef81cc3 100644
--- a/skgbaseguidesigner/skgtablewithgraphdesignerplugin.cpp
+++ b/skgbaseguidesigner/skgtablewithgraphdesignerplugin.cpp
@@ -1,104 +1,104 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* A table with graph with more features (qt designer plugin).
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgtablewithgraphdesignerplugin.h"
#include <qicon.h>
#include "skgtablewithgraph.h"
SKGTableWithGraphDesignerPlugin::SKGTableWithGraphDesignerPlugin(QObject* iParent)
: QObject(iParent)
{
m_initialized = false;
}
void SKGTableWithGraphDesignerPlugin::initialize(QDesignerFormEditorInterface* iCore)
{
Q_UNUSED(iCore)
if (m_initialized) {
return;
}
m_initialized = true;
}
bool SKGTableWithGraphDesignerPlugin::isInitialized() const
{
return m_initialized;
}
QWidget* SKGTableWithGraphDesignerPlugin::createWidget(QWidget* iParent)
{
return new SKGTableWithGraph(iParent);
}
QString SKGTableWithGraphDesignerPlugin::name() const
{
return QStringLiteral("SKGTableWithGraph");
}
QString SKGTableWithGraphDesignerPlugin::group() const
{
return QStringLiteral("SKG Widgets");
}
QIcon SKGTableWithGraphDesignerPlugin::icon() const
{
return SKGServices::fromTheme(QStringLiteral("quickopen"));
}
QString SKGTableWithGraphDesignerPlugin::toolTip() const
{
return QStringLiteral("A Table with graph");
}
QString SKGTableWithGraphDesignerPlugin::whatsThis() const
{
return QStringLiteral("A Table with graph");
}
bool SKGTableWithGraphDesignerPlugin::isContainer() const
{
return false;
}
QString SKGTableWithGraphDesignerPlugin::domXml() const
{
return QStringLiteral("<widget class=\"SKGTableWithGraph\" name=\"SKGTableWithGraph\">\n"
" <property name=\"geometry\">\n"
" <rect>\n"
" <x>0</x>\n"
" <y>0</y>\n"
" <width>100</width>\n"
" <height>100</height>\n"
" </rect>\n"
" </property>\n"
"</widget>\n");
}
QString SKGTableWithGraphDesignerPlugin::includeFile() const
{
return QStringLiteral("skgtablewithgraph.h");
}
diff --git a/skgbaseguidesigner/skgtablewithgraphdesignerplugin.h b/skgbaseguidesigner/skgtablewithgraphdesignerplugin.h
index aae31ef86..3affd39a4 100644
--- a/skgbaseguidesigner/skgtablewithgraphdesignerplugin.h
+++ b/skgbaseguidesigner/skgtablewithgraphdesignerplugin.h
@@ -1,112 +1,112 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGTABLEWITHGRAPHDESIGNERPLUGIN_H
#define SKGTABLEWITHGRAPHDESIGNERPLUGIN_H
/** @file
* A table with graph (qt designer plugin).
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include <customwidget.h>
/**
* QDesigner plugin for SKGTableWithGraph
*/
class SKGTableWithGraphDesignerPlugin : public QObject, public QDesignerCustomWidgetInterface
{
Q_OBJECT
Q_INTERFACES(QDesignerCustomWidgetInterface)
public:
/**
* Constructor
* @param iParent parent
*/
explicit SKGTableWithGraphDesignerPlugin(QObject* iParent = nullptr);
/**
* To know if the component is a container
* @return true or false
*/
bool isContainer() const override;
/**
* To know if the component is initialized
* @return true or false
*/
bool isInitialized() const override;
/**
* To get the icon for this component
* @return the icon
*/
QIcon icon() const override;
/**
* To get the icon for this component
* @return
*/
QString domXml() const override;
/**
* To get the group for this component
* @return group
*/
QString group() const override;
/**
* To get the include file for this component
* @return the include file
*/
QString includeFile() const override;
/**
* To get the name for this component
* @return name
*/
QString name() const override;
/**
* To get the "tool tip" for this component
* @return the "tool tip"
*/
QString toolTip() const override;
/**
* To get the "whats this" for this component
* @return the "whats this"
*/
QString whatsThis() const override;
/**
* To get the widget representing the component
* @param iParent the parent of the widget
* @return the widget
*/
QWidget* createWidget(QWidget* iParent) override;
/**
* Initilialize the component
* @param iCore interface
*/
void initialize(QDesignerFormEditorInterface* iCore) override;
private:
bool m_initialized;
};
#endif
diff --git a/skgbaseguidesigner/skgtabwidgetdesignerplugin.cpp b/skgbaseguidesigner/skgtabwidgetdesignerplugin.cpp
index 15ad635ef..d3c3848e3 100644
--- a/skgbaseguidesigner/skgtabwidgetdesignerplugin.cpp
+++ b/skgbaseguidesigner/skgtabwidgetdesignerplugin.cpp
@@ -1,101 +1,101 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* A QTabWidget (qt designer plugin).
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgtabwidgetdesignerplugin.h"
#include "skgservices.h"
#include "skgtabwidget.h"
SKGTabWidgetDesignerPlugin::SKGTabWidgetDesignerPlugin(QObject* iParent)
: QObject(iParent)
{
m_initialized = false;
}
void SKGTabWidgetDesignerPlugin::initialize(QDesignerFormEditorInterface* iCore)
{
Q_UNUSED(iCore)
if (m_initialized) {
return;
}
m_initialized = true;
}
bool SKGTabWidgetDesignerPlugin::isInitialized() const
{
return m_initialized;
}
QWidget* SKGTabWidgetDesignerPlugin::createWidget(QWidget* iParent)
{
return new SKGTabWidget(iParent);
}
QString SKGTabWidgetDesignerPlugin::name() const
{
return QStringLiteral("SKGTabWidget");
}
QString SKGTabWidgetDesignerPlugin::group() const
{
return QStringLiteral("SKG Widgets");
}
QIcon SKGTabWidgetDesignerPlugin::icon() const
{
return SKGServices::fromTheme(QStringLiteral("quickopen"));
}
QString SKGTabWidgetDesignerPlugin::toolTip() const
{
return QStringLiteral("A QTabWidget with more feature");
}
QString SKGTabWidgetDesignerPlugin::whatsThis() const
{
return QStringLiteral("A QTabWidget with more feature");
}
bool SKGTabWidgetDesignerPlugin::isContainer() const
{
return false;
}
QString SKGTabWidgetDesignerPlugin::domXml() const
{
return QStringLiteral("<widget class=\"SKGTabWidget\" name=\"SKGTabWidget\">\n"
" <property name=\"geometry\">\n"
" <rect>\n"
" <x>0</x>\n"
" <y>0</y>\n"
" <width>100</width>\n"
" <height>100</height>\n"
" </rect>\n"
" </property>\n"
"</widget>\n");
}
QString SKGTabWidgetDesignerPlugin::includeFile() const
{
return QStringLiteral("skgtabwidget.h");
}
diff --git a/skgbaseguidesigner/skgtabwidgetdesignerplugin.h b/skgbaseguidesigner/skgtabwidgetdesignerplugin.h
index bf6d67d7a..726e0b344 100644
--- a/skgbaseguidesigner/skgtabwidgetdesignerplugin.h
+++ b/skgbaseguidesigner/skgtabwidgetdesignerplugin.h
@@ -1,112 +1,112 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGTABWIDGETDESIGNERPLUGIN_H
#define SKGTABWIDGETDESIGNERPLUGIN_H
/** @file
* A QTabWidget (qt designer plugin).
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include <customwidget.h>
/**
* QDesigner plugin for SKGTabWidget
*/
class SKGTabWidgetDesignerPlugin : public QObject, public QDesignerCustomWidgetInterface
{
Q_OBJECT
Q_INTERFACES(QDesignerCustomWidgetInterface)
public:
/**
* Constructor
* @param iParent parent
*/
explicit SKGTabWidgetDesignerPlugin(QObject* iParent = nullptr);
/**
* To know if the component is a container
* @return true or false
*/
bool isContainer() const override;
/**
* To know if the component is initialized
* @return true or false
*/
bool isInitialized() const override;
/**
* To get the icon for this component
* @return the icon
*/
QIcon icon() const override;
/**
* To get the icon for this component
* @return
*/
QString domXml() const override;
/**
* To get the group for this component
* @return group
*/
QString group() const override;
/**
* To get the include file for this component
* @return the include file
*/
QString includeFile() const override;
/**
* To get the name for this component
* @return name
*/
QString name() const override;
/**
* To get the "tool tip" for this component
* @return the "tool tip"
*/
QString toolTip() const override;
/**
* To get the "whats this" for this component
* @return the "whats this"
*/
QString whatsThis() const override;
/**
* To get the widget representing the component
* @param iParent the parent of the widget
* @return the widget
*/
QWidget* createWidget(QWidget* iParent) override;
/**
* Initilialize the component
* @param iCore interface
*/
void initialize(QDesignerFormEditorInterface* iCore) override;
private:
bool m_initialized;
};
#endif
diff --git a/skgbaseguidesigner/skgtreeviewdesignerplugin.cpp b/skgbaseguidesigner/skgtreeviewdesignerplugin.cpp
index c4e3e2f8e..b77e9214b 100644
--- a/skgbaseguidesigner/skgtreeviewdesignerplugin.cpp
+++ b/skgbaseguidesigner/skgtreeviewdesignerplugin.cpp
@@ -1,102 +1,102 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* A tree view with more features (qt designer plugin).
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgtreeviewdesignerplugin.h"
#include <qicon.h>
#include "skgtreeview.h"
SKGTreeViewDesignerPlugin::SKGTreeViewDesignerPlugin(QObject* iParent)
: QObject(iParent)
{
m_initialized = false;
}
void SKGTreeViewDesignerPlugin::initialize(QDesignerFormEditorInterface* iCore)
{
Q_UNUSED(iCore)
if (m_initialized) {
return;
}
m_initialized = true;
}
bool SKGTreeViewDesignerPlugin::isInitialized() const
{
return m_initialized;
}
QWidget* SKGTreeViewDesignerPlugin::createWidget(QWidget* iParent)
{
return new SKGTreeView(iParent);
}
QString SKGTreeViewDesignerPlugin::name() const
{
return QStringLiteral("SKGTreeView");
}
QString SKGTreeViewDesignerPlugin::group() const
{
return QStringLiteral("SKG Widgets");
}
QIcon SKGTreeViewDesignerPlugin::icon() const
{
return SKGServices::fromTheme(QStringLiteral("quickopen"));
}
QString SKGTreeViewDesignerPlugin::toolTip() const
{
return QStringLiteral("A tree view with more features");
}
QString SKGTreeViewDesignerPlugin::whatsThis() const
{
return QStringLiteral("A tree view with more features");
}
bool SKGTreeViewDesignerPlugin::isContainer() const
{
return true;
}
QString SKGTreeViewDesignerPlugin::domXml() const
{
return QStringLiteral("<widget class=\"SKGTreeView\" name=\"SKGTreeView\">\n"
" <property name=\"geometry\">\n"
" <rect>\n"
" <x>0</x>\n"
" <y>0</y>\n"
" <width>100</width>\n"
" <height>100</height>\n"
" </rect>\n"
" </property>\n"
"</widget>\n");
}
QString SKGTreeViewDesignerPlugin::includeFile() const
{
return QStringLiteral("skgtreeview.h");
}
diff --git a/skgbaseguidesigner/skgtreeviewdesignerplugin.h b/skgbaseguidesigner/skgtreeviewdesignerplugin.h
index 184912f00..12f32bb41 100644
--- a/skgbaseguidesigner/skgtreeviewdesignerplugin.h
+++ b/skgbaseguidesigner/skgtreeviewdesignerplugin.h
@@ -1,112 +1,112 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGTREEVIEWDESIGNERPLUGIN_H
#define SKGTREEVIEWDESIGNERPLUGIN_H
/** @file
* A tree view with more features (qt designer plugin).
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include <customwidget.h>
/**
* QDesigner plugin for SKGTreeView
*/
class SKGTreeViewDesignerPlugin : public QObject, public QDesignerCustomWidgetInterface
{
Q_OBJECT
Q_INTERFACES(QDesignerCustomWidgetInterface)
public:
/**
* Constructor
* @param iParent parent
*/
explicit SKGTreeViewDesignerPlugin(QObject* iParent = nullptr);
/**
* To know if the component is a container
* @return true or false
*/
bool isContainer() const override;
/**
* To know if the component is initialized
* @return true or false
*/
bool isInitialized() const override;
/**
* To get the icon for this component
* @return the icon
*/
QIcon icon() const override;
/**
* To get the icon for this component
* @return
*/
QString domXml() const override;
/**
* To get the group for this component
* @return group
*/
QString group() const override;
/**
* To get the include file for this component
* @return the include file
*/
QString includeFile() const override;
/**
* To get the name for this component
* @return name
*/
QString name() const override;
/**
* To get the "tool tip" for this component
* @return the "tool tip"
*/
QString toolTip() const override;
/**
* To get the "whats this" for this component
* @return the "whats this"
*/
QString whatsThis() const override;
/**
* To get the widget representing the component
* @param iParent the parent of the widget
* @return the widget
*/
QWidget* createWidget(QWidget* iParent) override;
/**
* Initilialize the component
* @param iCore interface
*/
void initialize(QDesignerFormEditorInterface* iCore) override;
private:
bool m_initialized;
};
#endif
diff --git a/skgbaseguidesigner/skgwebviewdesignerplugin.cpp b/skgbaseguidesigner/skgwebviewdesignerplugin.cpp
index 177b20fc7..cbb6e4a83 100644
--- a/skgbaseguidesigner/skgwebviewdesignerplugin.cpp
+++ b/skgbaseguidesigner/skgwebviewdesignerplugin.cpp
@@ -1,103 +1,103 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* A web viewer with more features (qt designer plugin).
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgwebviewdesignerplugin.h"
#include "skgservices.h"
#include "skgwebview.h"
SKGWebViewDesignerPlugin::SKGWebViewDesignerPlugin(QObject* iParent)
: QObject(iParent)
{
m_initialized = false;
}
void SKGWebViewDesignerPlugin::initialize(QDesignerFormEditorInterface* iCore)
{
Q_UNUSED(iCore)
if (m_initialized) {
return;
}
m_initialized = true;
}
bool SKGWebViewDesignerPlugin::isInitialized() const
{
return m_initialized;
}
QWidget* SKGWebViewDesignerPlugin::createWidget(QWidget* iParent)
{
return new SKGWebView(iParent);
}
QString SKGWebViewDesignerPlugin::name() const
{
return QStringLiteral("SKGWebView");
}
QString SKGWebViewDesignerPlugin::group() const
{
return QStringLiteral("SKG Widgets");
}
QIcon SKGWebViewDesignerPlugin::icon() const
{
return SKGServices::fromTheme(QStringLiteral("quickopen"));
}
QString SKGWebViewDesignerPlugin::toolTip() const
{
return QStringLiteral("A web viewer with more features");
}
QString SKGWebViewDesignerPlugin::whatsThis() const
{
return QStringLiteral("A web viewer with more features");
}
bool SKGWebViewDesignerPlugin::isContainer() const
{
return false;
}
QString SKGWebViewDesignerPlugin::domXml() const
{
return QStringLiteral("<widget class=\"SKGWebView\" name=\"SKGWebView\">\n"
" <property name=\"geometry\">\n"
" <rect>\n"
" <x>0</x>\n"
" <y>0</y>\n"
" <width>100</width>\n"
" <height>10</height>\n"
" </rect>\n"
" </property>\n"
"</widget>\n");
}
QString SKGWebViewDesignerPlugin::includeFile() const
{
return QStringLiteral("skgwebview.h");
}
diff --git a/skgbaseguidesigner/skgwebviewdesignerplugin.h b/skgbaseguidesigner/skgwebviewdesignerplugin.h
index 53372a8f4..a00bcc309 100644
--- a/skgbaseguidesigner/skgwebviewdesignerplugin.h
+++ b/skgbaseguidesigner/skgwebviewdesignerplugin.h
@@ -1,112 +1,112 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGWEBVIEWDESIGNERPLUGIN_H
#define SKGWEBVIEWDESIGNERPLUGIN_H
/** @file
* A web viewer with more features (qt designer plugin).
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include <customwidget.h>
/**
* QDesigner plugin for SKGWebView
*/
class SKGWebViewDesignerPlugin : public QObject, public QDesignerCustomWidgetInterface
{
Q_OBJECT
Q_INTERFACES(QDesignerCustomWidgetInterface)
public:
/**
* Constructor
* @param iParent parent
*/
explicit SKGWebViewDesignerPlugin(QObject* iParent = nullptr);
/**
* To know if the component is a container
* @return true or false
*/
bool isContainer() const override;
/**
* To know if the component is initialized
* @return true or false
*/
bool isInitialized() const override;
/**
* To get the icon for this component
* @return the icon
*/
QIcon icon() const override;
/**
* To get the icon for this component
* @return
*/
QString domXml() const override;
/**
* To get the group for this component
* @return group
*/
QString group() const override;
/**
* To get the include file for this component
* @return the include file
*/
QString includeFile() const override;
/**
* To get the name for this component
* @return name
*/
QString name() const override;
/**
* To get the "tool tip" for this component
* @return the "tool tip"
*/
QString toolTip() const override;
/**
* To get the "whats this" for this component
* @return the "whats this"
*/
QString whatsThis() const override;
/**
* To get the widget representing the component
* @param iParent the parent of the widget
* @return the widget
*/
QWidget* createWidget(QWidget* iParent) override;
/**
* Initilialize the component
* @param iCore interface
*/
void initialize(QDesignerFormEditorInterface* iCore) override;
private:
bool m_initialized;
};
#endif
diff --git a/skgbaseguidesigner/skgwidgetcollectiondesignerplugin.cpp b/skgbaseguidesigner/skgwidgetcollectiondesignerplugin.cpp
index 5b192ca35..8e598ed03 100644
--- a/skgbaseguidesigner/skgwidgetcollectiondesignerplugin.cpp
+++ b/skgbaseguidesigner/skgwidgetcollectiondesignerplugin.cpp
@@ -1,69 +1,69 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* A collection of widgets (qt designer plugin).
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgwidgetcollectiondesignerplugin.h"
#include "skgcalculatoreditdesignerplugin.h"
#include "skgcolorbuttondesignerplugin.h"
#include "skgcomboboxdesignerplugin.h"
#include "skgdateeditdesignerplugin.h"
#include "skgfilteredtableviewdesignerplugin.h"
#include "skggraphicsviewdesignerplugin.h"
#include "skgperiodeditdesignerplugin.h"
#include "skgprogressbardesignerplugin.h"
#include "skgshowdesignerplugin.h"
#include "skgsimpleperiodeditdesignerplugin.h"
#include "skgtableviewdesignerplugin.h"
#include "skgtablewidgetdesignerplugin.h"
#include "skgtablewithgraphdesignerplugin.h"
#include "skgtabwidgetdesignerplugin.h"
#include "skgtreeviewdesignerplugin.h"
#include "skgwebviewdesignerplugin.h"
#include "skgwidgetselectordesignerplugin.h"
#include "skgzoomselectordesignerplugin.h"
SKGWidgetCollectionDesignerPlugin::SKGWidgetCollectionDesignerPlugin(QObject* iParent)
: QObject(iParent)
{
m_widgets.append(new SKGCalculatorEditDesignerPlugin(this));
m_widgets.append(new SKGComboBoxDesignerPlugin(this));
m_widgets.append(new SKGColorButtonDesignerPlugin(this));
m_widgets.append(new SKGDateEditDesignerPlugin(this));
m_widgets.append(new SKGFilteredTableViewDesignerPlugin(this));
m_widgets.append(new SKGGraphicsViewDesignerPlugin(this));
m_widgets.append(new SKGShowDesignerPlugin(this));
m_widgets.append(new SKGTableViewDesignerPlugin(this));
m_widgets.append(new SKGTreeViewDesignerPlugin(this));
m_widgets.append(new SKGTableWithGraphDesignerPlugin(this));
m_widgets.append(new SKGTabWidgetDesignerPlugin(this));
m_widgets.append(new SKGTableWidgetDesignerPlugin(this));
m_widgets.append(new SKGWebViewDesignerPlugin(this));
m_widgets.append(new SKGWidgetSelectorDesignerPlugin(this));
m_widgets.append(new SKGZoomSelectorDesignerPlugin(this));
m_widgets.append(new SKGProgressBarDesignerPlugin(this));
m_widgets.append(new SKGPeriodEditDesignerPlugin(this));
m_widgets.append(new SKGSimplePeriodEditDesignerPlugin(this));
}
QList<QDesignerCustomWidgetInterface*> SKGWidgetCollectionDesignerPlugin::customWidgets() const
{
return m_widgets;
}
diff --git a/skgbaseguidesigner/skgwidgetcollectiondesignerplugin.h b/skgbaseguidesigner/skgwidgetcollectiondesignerplugin.h
index 9e3cf920e..8336cd97d 100644
--- a/skgbaseguidesigner/skgwidgetcollectiondesignerplugin.h
+++ b/skgbaseguidesigner/skgwidgetcollectiondesignerplugin.h
@@ -1,54 +1,54 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGWIDGETCOLLECTIONDESIGNERPLUGIN_H
#define SKGWIDGETCOLLECTIONDESIGNERPLUGIN_H
/** @file
* A collection of widgets (qt designer plugin).
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include <customwidget.h>
#include "skgbaseguidesigner_export.h"
/**
* QDesigner plugin collection
*/
class SKGBASEGUIDESIGNER_EXPORT SKGWidgetCollectionDesignerPlugin: public QObject, public QDesignerCustomWidgetCollectionInterface
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QDesignerCustomWidgetCollectionInterface")
Q_INTERFACES(QDesignerCustomWidgetCollectionInterface)
public:
/**
* Constructor
* @param iParent the parent
*/
explicit SKGWidgetCollectionDesignerPlugin(QObject* iParent = nullptr);
/**
* To get the list of widgets
* @return the list of widgets
*/
QList<QDesignerCustomWidgetInterface*> customWidgets() const override;
private:
QList<QDesignerCustomWidgetInterface*> m_widgets;
};
#endif // SKGWIDGETCOLLECTIONDESIGNERPLUGIN_H
diff --git a/skgbaseguidesigner/skgwidgetselectordesignerplugin.cpp b/skgbaseguidesigner/skgwidgetselectordesignerplugin.cpp
index 55561ccdb..9bf8fd73f 100644
--- a/skgbaseguidesigner/skgwidgetselectordesignerplugin.cpp
+++ b/skgbaseguidesigner/skgwidgetselectordesignerplugin.cpp
@@ -1,101 +1,101 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* A widget selector (qt designer plugin).
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgwidgetselectordesignerplugin.h"
#include "skgservices.h"
#include "skgwidgetselector.h"
SKGWidgetSelectorDesignerPlugin::SKGWidgetSelectorDesignerPlugin(QObject* iParent)
: QObject(iParent)
{
m_initialized = false;
}
void SKGWidgetSelectorDesignerPlugin::initialize(QDesignerFormEditorInterface* iCore)
{
Q_UNUSED(iCore)
if (m_initialized) {
return;
}
m_initialized = true;
}
bool SKGWidgetSelectorDesignerPlugin::isInitialized() const
{
return m_initialized;
}
QWidget* SKGWidgetSelectorDesignerPlugin::createWidget(QWidget* iParent)
{
return new SKGWidgetSelector(iParent);
}
QString SKGWidgetSelectorDesignerPlugin::name() const
{
return QStringLiteral("SKGWidgetSelector");
}
QString SKGWidgetSelectorDesignerPlugin::group() const
{
return QStringLiteral("SKG Widgets");
}
QIcon SKGWidgetSelectorDesignerPlugin::icon() const
{
return SKGServices::fromTheme(QStringLiteral("quickopen"));
}
QString SKGWidgetSelectorDesignerPlugin::toolTip() const
{
return QStringLiteral("A widget selector");
}
QString SKGWidgetSelectorDesignerPlugin::whatsThis() const
{
return QStringLiteral("A widget selector");
}
bool SKGWidgetSelectorDesignerPlugin::isContainer() const
{
return false;
}
QString SKGWidgetSelectorDesignerPlugin::domXml() const
{
return QStringLiteral("<widget class=\"SKGWidgetSelector\" name=\"SKGWidgetSelector\">\n"
" <property name=\"geometry\">\n"
" <rect>\n"
" <x>0</x>\n"
" <y>0</y>\n"
" <width>100</width>\n"
" <height>10</height>\n"
" </rect>\n"
" </property>\n"
"</widget>\n");
}
QString SKGWidgetSelectorDesignerPlugin::includeFile() const
{
return QStringLiteral("skgwidgetselector.h");
}
diff --git a/skgbaseguidesigner/skgwidgetselectordesignerplugin.h b/skgbaseguidesigner/skgwidgetselectordesignerplugin.h
index 1ec57f5d2..25c86bbfc 100644
--- a/skgbaseguidesigner/skgwidgetselectordesignerplugin.h
+++ b/skgbaseguidesigner/skgwidgetselectordesignerplugin.h
@@ -1,112 +1,112 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGWIDGETSELECTORDESIGNERPLUGIN_H
#define SKGWIDGETSELECTORDESIGNERPLUGIN_H
/** @file
* A widget selector (qt designer plugin).
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include <customwidget.h>
/**
* QDesigner plugin for SKGWidgetSelector
*/
class SKGWidgetSelectorDesignerPlugin : public QObject, public QDesignerCustomWidgetInterface
{
Q_OBJECT
Q_INTERFACES(QDesignerCustomWidgetInterface)
public:
/**
* Constructor
* @param iParent parent
*/
explicit SKGWidgetSelectorDesignerPlugin(QObject* iParent = nullptr);
/**
* To know if the component is a container
* @return true or false
*/
bool isContainer() const override;
/**
* To know if the component is initialized
* @return true or false
*/
bool isInitialized() const override;
/**
* To get the icon for this component
* @return the icon
*/
QIcon icon() const override;
/**
* To get the icon for this component
* @return
*/
QString domXml() const override;
/**
* To get the group for this component
* @return group
*/
QString group() const override;
/**
* To get the include file for this component
* @return the include file
*/
QString includeFile() const override;
/**
* To get the name for this component
* @return name
*/
QString name() const override;
/**
* To get the "tool tip" for this component
* @return the "tool tip"
*/
QString toolTip() const override;
/**
* To get the "whats this" for this component
* @return the "whats this"
*/
QString whatsThis() const override;
/**
* To get the widget representing the component
* @param iParent the parent of the widget
* @return the widget
*/
QWidget* createWidget(QWidget* iParent) override;
/**
* Initilialize the component
* @param iCore interface
*/
void initialize(QDesignerFormEditorInterface* iCore) override;
private:
bool m_initialized;
};
#endif
diff --git a/skgbaseguidesigner/skgzoomselectordesignerplugin.cpp b/skgbaseguidesigner/skgzoomselectordesignerplugin.cpp
index a40d87f42..d7039012e 100644
--- a/skgbaseguidesigner/skgzoomselectordesignerplugin.cpp
+++ b/skgbaseguidesigner/skgzoomselectordesignerplugin.cpp
@@ -1,103 +1,103 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* A color button with more features (qt designer plugin).
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgzoomselectordesignerplugin.h"
#include "skgservices.h"
#include "skgzoomselector.h"
SKGZoomSelectorDesignerPlugin::SKGZoomSelectorDesignerPlugin(QObject* iParent)
: QObject(iParent)
{
m_initialized = false;
}
void SKGZoomSelectorDesignerPlugin::initialize(QDesignerFormEditorInterface* iCore)
{
Q_UNUSED(iCore)
if (m_initialized) {
return;
}
m_initialized = true;
}
bool SKGZoomSelectorDesignerPlugin::isInitialized() const
{
return m_initialized;
}
QWidget* SKGZoomSelectorDesignerPlugin::createWidget(QWidget* iParent)
{
return new SKGZoomSelector(iParent);
}
QString SKGZoomSelectorDesignerPlugin::name() const
{
return QStringLiteral("SKGZoomSelector");
}
QString SKGZoomSelectorDesignerPlugin::group() const
{
return QStringLiteral("SKG Widgets");
}
QIcon SKGZoomSelectorDesignerPlugin::icon() const
{
return SKGServices::fromTheme(QStringLiteral("quickopen"));
}
QString SKGZoomSelectorDesignerPlugin::toolTip() const
{
return QStringLiteral("A color button with more features");
}
QString SKGZoomSelectorDesignerPlugin::whatsThis() const
{
return QStringLiteral("A color button with more features");
}
bool SKGZoomSelectorDesignerPlugin::isContainer() const
{
return false;
}
QString SKGZoomSelectorDesignerPlugin::domXml() const
{
return QStringLiteral("<widget class=\"SKGZoomSelector\" name=\"SKGZoomSelector\">\n"
" <property name=\"geometry\">\n"
" <rect>\n"
" <x>0</x>\n"
" <y>0</y>\n"
" <width>100</width>\n"
" <height>10</height>\n"
" </rect>\n"
" </property>\n"
"</widget>\n");
}
QString SKGZoomSelectorDesignerPlugin::includeFile() const
{
return QStringLiteral("skgzoomselector.h");
}
diff --git a/skgbaseguidesigner/skgzoomselectordesignerplugin.h b/skgbaseguidesigner/skgzoomselectordesignerplugin.h
index 600f6be42..9023a0468 100644
--- a/skgbaseguidesigner/skgzoomselectordesignerplugin.h
+++ b/skgbaseguidesigner/skgzoomselectordesignerplugin.h
@@ -1,112 +1,112 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGZOOMSELECTORDESIGNERPLUGIN_H
#define SKGZOOMSELECTORDESIGNERPLUGIN_H
/** @file
* A color button with more features (qt designer plugin).
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include <customwidget.h>
/**
* QDesigner plugin for SKGZoomSelector
*/
class SKGZoomSelectorDesignerPlugin : public QObject, public QDesignerCustomWidgetInterface
{
Q_OBJECT
Q_INTERFACES(QDesignerCustomWidgetInterface)
public:
/**
* Constructor
* @param iParent parent
*/
explicit SKGZoomSelectorDesignerPlugin(QObject* iParent = nullptr);
/**
* To know if the component is a container
* @return true or false
*/
bool isContainer() const override;
/**
* To know if the component is initialized
* @return true or false
*/
bool isInitialized() const override;
/**
* To get the icon for this component
* @return the icon
*/
QIcon icon() const override;
/**
* To get the icon for this component
* @return
*/
QString domXml() const override;
/**
* To get the group for this component
* @return group
*/
QString group() const override;
/**
* To get the include file for this component
* @return the include file
*/
QString includeFile() const override;
/**
* To get the name for this component
* @return name
*/
QString name() const override;
/**
* To get the "tool tip" for this component
* @return the "tool tip"
*/
QString toolTip() const override;
/**
* To get the "whats this" for this component
* @return the "whats this"
*/
QString whatsThis() const override;
/**
* To get the widget representing the component
* @param iParent the parent of the widget
* @return the widget
*/
QWidget* createWidget(QWidget* iParent) override;
/**
* Initilialize the component
* @param iCore interface
*/
void initialize(QDesignerFormEditorInterface* iCore) override;
private:
bool m_initialized;
};
#endif
diff --git a/skgbasemodeler/CMakeLists.txt b/skgbasemodeler/CMakeLists.txt
index 89f8d71d2..f9b3a8731 100644
--- a/skgbasemodeler/CMakeLists.txt
+++ b/skgbasemodeler/CMakeLists.txt
@@ -1,63 +1,63 @@
#***************************************************************************
#* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
#* *
#* 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 <http://www.gnu.org/licenses/> *
+#* along with this program. If not, see <https://www.gnu.org/licenses/> *
#***************************************************************************
MESSAGE( STATUS "..:: CMAKE SKGBASEMODELER ::..")
PROJECT(SKGBASEMODELER)
LINK_DIRECTORIES (${LIBRARY_OUTPUT_PATH})
FIND_PACKAGE(Qca-qt5 2.1.0 REQUIRED)
SET_PACKAGE_PROPERTIES(Qca-qt5 PROPERTIES DESCRIPTION "Support for encryption"
- URL "http://download.kde.org/stable/qca-qt5"
+ URL "https://download.kde.org/stable/qca-qt5"
TYPE REQUIRED)
INCLUDE_DIRECTORIES(${SQLCIPHER_INCLUDE_DIRS})
IF ( Qca-qt5_FOUND )
ADD_DEFINITIONS( -DQCA2 )
ENDIF()
SET(skgbasemodeler_SRCS
skgobjectbase.cpp
skgnamedobject.cpp
skgnodeobject.cpp
skgpropertyobject.cpp
skgdocument.cpp
skgdocumentprivate.cpp
skgtransactionmng.cpp
skgservices.cpp
skgerror.cpp
skgtraces.cpp
skgadvice.cpp
skgreport.cpp
skgtreemap.cpp
)
#build a shared library
ADD_LIBRARY(skgbasemodeler SHARED ${skgbasemodeler_SRCS})
#need to link to some other libraries ? just add them here
SET_TARGET_PROPERTIES(skgbasemodeler PROPERTIES VERSION ${SKG_VERSION} SOVERSION ${SOVERSION} )
TARGET_LINK_LIBRARIES(skgbasemodeler LINK_PUBLIC KF5::I18n KF5::IconThemes KF5::ConfigWidgets KF5::CoreAddons
Qt5::Core Qt5::Gui Qt5::Sql Qt5::Script Qt5::Xml Qt5::DBus Qt5::Concurrent qca-qt5
Grantlee5::Templates KF5::KIOCore
${SQLCIPHER_LIBRARIES} )
GENERATE_EXPORT_HEADER(skgbasemodeler BASE_NAME skgbasemodeler)
########### install files ###############
INSTALL(TARGETS skgbasemodeler ${INSTALL_TARGETS_DEFAULT_ARGS} LIBRARY NAMELINK_SKIP )
diff --git a/skgbasemodeler/skgadvice.cpp b/skgbasemodeler/skgadvice.cpp
index 9bd7b6809..d161cc3a0 100644
--- a/skgbasemodeler/skgadvice.cpp
+++ b/skgbasemodeler/skgadvice.cpp
@@ -1,126 +1,126 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file implements classes SKGAdvice.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgadvice.h"
#include "skgdefine.h"
SKGAdvice::SKGAdvice() : QObject()
{}
SKGAdvice::SKGAdvice(const SKGAdvice& iAdvice)
: QObject(), m_uuid(iAdvice.m_uuid), m_priority(iAdvice.m_priority),
m_shortMessage(iAdvice.m_shortMessage), m_longMessage(iAdvice.m_longMessage),
m_autoCorrections(iAdvice.m_autoCorrections)
{}
SKGAdvice::~SKGAdvice()
= default;
SKGAdvice& SKGAdvice::operator= (const SKGAdvice& iAdvice)
{
if (&iAdvice != this) {
m_priority = iAdvice.m_priority;
m_shortMessage = iAdvice.m_shortMessage;
m_longMessage = iAdvice.m_longMessage;
m_autoCorrections = iAdvice.m_autoCorrections;
m_uuid = iAdvice.m_uuid;
Q_EMIT modified();
}
return *this;
}
void SKGAdvice::setUUID(const QString& iUUID)
{
if (m_uuid != iUUID) {
m_uuid = iUUID;
Q_EMIT modified();
}
}
QString SKGAdvice::getUUID() const
{
return m_uuid;
}
void SKGAdvice::setPriority(int iPriority)
{
if (m_priority != iPriority) {
m_priority = iPriority;
Q_EMIT modified();
}
}
int SKGAdvice::getPriority() const
{
return m_priority;
}
void SKGAdvice::setShortMessage(const QString& iMessage)
{
if (m_shortMessage != iMessage) {
m_shortMessage = iMessage;
Q_EMIT modified();
}
}
QString SKGAdvice::getShortMessage() const
{
return m_shortMessage;
}
void SKGAdvice::setLongMessage(const QString& iMessage)
{
if (m_longMessage != iMessage) {
m_longMessage = iMessage;
Q_EMIT modified();
}
}
QString SKGAdvice::getLongMessage() const
{
return m_longMessage;
}
void SKGAdvice::setAutoCorrections(const QStringList& iCorrections)
{
SKGAdvice::SKGAdviceActionList tmp;
tmp.reserve(iCorrections.count());
for (const auto& c : qAsConst(iCorrections)) {
SKGAdviceAction a;
a.Title = c;
a.IsRecommended = false;
tmp.push_back(a);
}
setAutoCorrections(tmp);
}
void SKGAdvice::setAutoCorrections(const SKGAdvice::SKGAdviceActionList& iCorrections)
{
m_autoCorrections = iCorrections;
Q_EMIT modified();
}
SKGAdvice::SKGAdviceActionList SKGAdvice::getAutoCorrections() const
{
return m_autoCorrections;
}
diff --git a/skgbasemodeler/skgadvice.h b/skgbasemodeler/skgadvice.h
index ef127c40e..964af682b 100644
--- a/skgbasemodeler/skgadvice.h
+++ b/skgbasemodeler/skgadvice.h
@@ -1,223 +1,223 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGADVICE_H
#define SKGADVICE_H
/** @file
* This file defines classes SKGAdvice .
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include <qmetatype.h>
#include <qobject.h>
#include <qstring.h>
#include <qstringlist.h>
#include <qvector.h>
#include "skgbasemodeler_export.h"
/**
* This class manages errors
*/
class SKGBASEMODELER_EXPORT SKGAdvice final : public QObject
{
Q_OBJECT
public:
/**
* Advice action
*/
struct SKGAdviceAction {
/** The id of the action */
QString id;
/** The title of the action */
QString Title;
/** The name of the icon of the action */
QString IconName;
/** To know if this action is recommended*/
bool IsRecommended{};
};
/**
* List of advice action
*/
using SKGAdviceActionList = QVector<SKGAdvice::SKGAdviceAction>;
/**
* Priotity
*/
Q_PROPERTY(int priority READ getPriority WRITE setPriority NOTIFY modified)
/**
* Unique identifier
*/
Q_PROPERTY(QString uuid READ getUUID WRITE setUUID NOTIFY modified)
/**
* Short message
*/
Q_PROPERTY(QString shortMessage READ getShortMessage WRITE setShortMessage NOTIFY modified)
/**
* Long message
*/
Q_PROPERTY(QString longMessage READ getLongMessage WRITE setLongMessage NOTIFY modified)
/**
* Auto corrections
*/
Q_PROPERTY(SKGAdvice::SKGAdviceActionList autoCorrections READ getAutoCorrections WRITE setAutoCorrections NOTIFY modified)
/**
* Constructor
*/
explicit SKGAdvice();
/**
* Copy constructor
* @param iAdvice the advice to copy
*/
SKGAdvice(const SKGAdvice& iAdvice);
/**
* Destructor
*/
~SKGAdvice() override;
/**
* Operator affectation
* @param iAdvice the advice to copy
*/
SKGAdvice& operator= (const SKGAdvice& iAdvice);
/**
* Return the unique identifier
* @return the unique identifier
*/
QString getUUID() const;
/**
* Return the priority
* @return the priority
*/
int getPriority() const;
/**
* Return the short message
* @return the short message
*/
QString getShortMessage() const;
/**
* Return the long message
* @return the long message
*/
QString getLongMessage() const;
/**
* Return the auto corrections
* @return the auto corrections
*/
SKGAdvice::SKGAdviceActionList getAutoCorrections() const;
public Q_SLOTS:
/**
* Set the unique identifier
* @param iUUID the unique identifier
*/
void setUUID(const QString& iUUID);
/**
* Set the priority
* @param iPriority the priority
*/
void setPriority(int iPriority);
/**
* Set the short message
* @param iMessage the short message
*/
void setShortMessage(const QString& iMessage);
/**
* Set the long message
* @param iMessage the long message
*/
void setLongMessage(const QString& iMessage);
/**
* Set the auto corrections
* @param iCorrections the auto corrections
*/
void setAutoCorrections(const QStringList& iCorrections);
/**
* Set the auto corrections
* @param iCorrections the auto corrections
*/
void setAutoCorrections(const SKGAdvice::SKGAdviceActionList& iCorrections);
Q_SIGNALS:
/**
* This signal is launched when the object is modified
*/
void modified();
private:
/**
* the unique identifier
*/
QString m_uuid;
/**
* the priority
*/
int m_priority{1};
/**
* the short message
*/
QString m_shortMessage;
/**
* the short message
*/
QString m_longMessage;
/**
* the list of auto corrections
*/
SKGAdvice::SKGAdviceActionList m_autoCorrections;
};
/**
* Declare the meta type
*/
Q_DECLARE_METATYPE(SKGAdvice)
/**
* Declare the class
*/
Q_DECLARE_TYPEINFO(SKGAdvice, Q_MOVABLE_TYPE);
/**
* the SKGAdviceList
*/
using SKGAdviceList = QVector<SKGAdvice>;
/**
* Declare the meta type
*/
Q_DECLARE_METATYPE(QVector<SKGAdvice>)
#endif // SKGADVICE_H
diff --git a/skgbasemodeler/skgdefine.h b/skgbasemodeler/skgdefine.h
index ce4d87ff4..4b48d7afb 100644
--- a/skgbasemodeler/skgdefine.h
+++ b/skgbasemodeler/skgdefine.h
@@ -1,263 +1,263 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGDEFINE_H
#define SKGDEFINE_H
/** @file
* This file defines some macros.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include <qstring.h>
#include <qstringbuilder.h>
#include <klocalizedstring.h>
#include "skgbasemodeler_export.h"
/**
* @var OBJECTSEPARATOR
* Define the separator between object and subobject
*/
#define OBJECTSEPARATOR QStringLiteral(" > ")
/**
* @var DUMPSQLITE
* To display SQLLITE internals (tables, views, indexes, ...)
* @see dump
*/
#define DUMPSQLITE (2 << 0)
/**
* @var DUMPPARAMETERS
* To display parameters
* @see dump
*/
#define DUMPPARAMETERS (2 << 1)
/**
* @var DUMPTRANSACTIONS
* To display transactions
* @see dump
*/
#define DUMPTRANSACTIONS (2 << 2)
/**
* @var DUMPNODES
* To display nodes
* @see dump
*/
#define DUMPNODES (2 << 3)
/**
* @var DUMPALL
* To display display all=@p DUMPSQLITE +@p DUMPPARAMETERS +@p DUMPTRANSACTIONS
* @see dump
*/
#define DUMPALL ((2 << 10) - 1)
/**
* @var SKG_UNDO_MAX_DEPTH
* Default value for the max depth for the undo / redo mechanism
*/
#define SKG_UNDO_MAX_DEPTH 50
/**
* @var ERR_NOTIMPL
* Error number
*/
#define ERR_NOTIMPL 1
/**
* @var ERR_NOINTERFACE
* Error number
*/
#define ERR_NOINTERFACE 2
/**
* @var ERR_POINTER
* Error number
*/
#define ERR_POINTER 3
/**
* @var ERR_ABORT
* Error number
*/
#define ERR_ABORT 4
/**
* @var ERR_FAIL
* Error number
*/
#define ERR_FAIL 5
/**
* @var ERR_HANDLE
* Error number
*/
#define ERR_HANDLE 6
/**
* @var ERR_OUTOFMEMORY
* Error number
*/
#define ERR_OUTOFMEMORY 7
/**
* @var ERR_INVALIDARG
* Error number
*/
#define ERR_INVALIDARG 8
/**
* @var ERR_UNEXPECTED
* Error number
*/
#define ERR_UNEXPECTED 9
/**
* @var ERR_WRITEACCESS
* Error number
*/
#define ERR_WRITEACCESS 10
/**
* @var ERR_FORCEABLE
* Error number
*/
#define ERR_FORCEABLE 11
/**
* @var ERR_ENCRYPTION
* Error number
*/
#define ERR_ENCRYPTION 12
/**
* @var ERR_INSTALL
* Error number
*/
#define ERR_INSTALL 13
/**
* @var ERR_CORRUPTION
* Error number
*/
#define ERR_CORRUPTION 14
/**
* @var ERR_READACCESS
* Error number
*/
#define ERR_READACCESS 15
/**
* @brief For a not modified field
**/
#define NOUPDATE QStringLiteral("-------")
/**
* @var EPSILON
* Epsilon (for comparison)
*/
#define EPSILON 0.00001
/**
* @def DELETECASCADE
* Define a standard trigger for cascaded delete
*/
#define DELETECASCADE(TABLEPARENT,ATTPARENT,TABLECHILD,ATTCHILD)\
(QStringList() << QString()%"DROP TRIGGER IF EXISTS fkdc_"%(TABLEPARENT)%"_"%(TABLECHILD)%"_"%(ATTPARENT)%"_"%(ATTCHILD) \
<< QString()%"CREATE TRIGGER fkdc_"%(TABLEPARENT)%"_"%(TABLECHILD)%"_"%(ATTPARENT)%"_"%(ATTCHILD)%" "\
"BEFORE DELETE ON "%(TABLEPARENT)%" "\
"FOR EACH ROW BEGIN "\
" DELETE FROM "%(TABLECHILD)%" WHERE "%(TABLECHILD)%"."%(ATTCHILD)%" = OLD."%(ATTPARENT)%"; "\
"END")
/**
* @def INSERTUPDATECONSTRAINT
* Define a standard trigger for foreign constraint
*/
// Should these strings be translated ??? They look far too SQLish for that purpose
#define INSERTUPDATECONSTRAINT(TABLEPARENT,ATTPARENT,TABLECHILD,ATTCHILD)\
(QStringList() << QString()%"DROP TRIGGER IF EXISTS fki_"%(TABLECHILD)%"_"%(TABLEPARENT)%"_"%(ATTCHILD)%"_"%(ATTPARENT) \
<< QString()%"CREATE TRIGGER fki_"%(TABLECHILD)%"_"%(TABLEPARENT)%"_"%(ATTCHILD)%"_"%(ATTPARENT)%" "\
"BEFORE INSERT ON "%(TABLECHILD)%" "\
"FOR EACH ROW BEGIN "\
" SELECT RAISE(ABORT, '"%SKGServices::stringToSqlString(i18nc("Error message", "Impossible to insert object (%1 is used by %2).\nConstraint name: %3",TABLEPARENT, TABLECHILD, "fki_"%(TABLECHILD)%"_"%(TABLEPARENT)%"_"%(ATTCHILD)%"_"%(ATTPARENT)))%"') "\
" WHERE NEW."%(ATTCHILD)%"!=0 AND NEW."%(ATTCHILD)%"!='' AND (SELECT "%(ATTPARENT)%" FROM "%(TABLEPARENT)%" WHERE "%(ATTPARENT)%" = NEW."%(ATTCHILD)%") IS NULL; "\
"END"\
<< QString()%"DROP TRIGGER IF EXISTS fku_"%(TABLECHILD)%"_"%(TABLEPARENT)%"_"%(ATTCHILD)%"_"%(ATTPARENT) \
<< QString()%"CREATE TRIGGER fku_"%(TABLECHILD)%"_"%(TABLEPARENT)%"_"%(ATTCHILD)%"_"%(ATTPARENT)%" "\
"BEFORE UPDATE ON "%(TABLECHILD)%" "\
"FOR EACH ROW BEGIN "\
" SELECT RAISE(ABORT, '"%SKGServices::stringToSqlString(i18nc("Error message", "Impossible to update object (%1 is used by %2).\nConstraint name: %3",TABLEPARENT, TABLECHILD, "fku_"%(TABLECHILD)%"_"%(TABLEPARENT)%"_"%(ATTCHILD)%"_"%(ATTPARENT)))%"') "\
" WHERE NEW."%(ATTCHILD)%"!=0 AND NEW."%(ATTCHILD)%"!='' AND (SELECT "%(ATTPARENT)%" FROM "%(TABLEPARENT)%" WHERE "%(ATTPARENT)%" = NEW."%(ATTCHILD)%") IS NULL; "\
"END")
/**
* @def FOREIGNCONSTRAINT
* Define a standard trigger for foreign constraint
*/
#define FOREIGNCONSTRAINT(TABLEPARENT,ATTPARENT,TABLECHILD,ATTCHILD)\
(INSERTUPDATECONSTRAINT(TABLEPARENT,ATTPARENT,TABLECHILD,ATTCHILD)\
<< QString()%"DROP TRIGGER IF EXISTS fkd_"%(TABLECHILD)%"_"%(TABLEPARENT)%"_"%(ATTCHILD)%"_"%(ATTPARENT) \
<< QString()%"CREATE TRIGGER fkd_"%(TABLECHILD)%"_"%(TABLEPARENT)%"_"%(ATTCHILD)%"_"%(ATTPARENT)%" "\
"BEFORE DELETE ON "%(TABLEPARENT)%" "\
"FOR EACH ROW BEGIN "\
" SELECT RAISE(ABORT, '"%SKGServices::stringToSqlString(i18nc("Error message", "Impossible to delete used object (%1 is used by %2).\nConstraint name: %3",TABLEPARENT, TABLECHILD, "fkd_"%(TABLECHILD)%"_"%(TABLEPARENT)%"_"%(ATTCHILD)%"_"%(ATTPARENT)))%"') "\
" WHERE (SELECT "%(ATTCHILD)%" FROM "%(TABLECHILD)%" WHERE "%(ATTCHILD)%" = OLD."%(ATTPARENT)%") IS NOT NULL; "\
"END")
/**
* @def FOREIGNCONSTRAINTUPDATE
* Define a standard trigger for foreign constraint
*/
#define FOREIGNCONSTRAINTUPDATE(TABLEPARENT,ATTPARENT,TABLECHILD,ATTCHILD)\
(INSERTUPDATECONSTRAINT(TABLEPARENT,ATTPARENT,TABLECHILD,ATTCHILD)\
<< QString()%"DROP TRIGGER IF EXISTS fkd_"%(TABLECHILD)%"_"%(TABLEPARENT)%"_"%(ATTCHILD)%"_"%(ATTPARENT) \
<< QString()%"CREATE TRIGGER fkd_"%(TABLECHILD)%"_"%(TABLEPARENT)%"_"%(ATTCHILD)%"_"%(ATTPARENT)%" "\
"BEFORE DELETE ON "%(TABLEPARENT)%" "\
"FOR EACH ROW BEGIN "\
" UPDATE "%(TABLECHILD)%" SET "%(ATTCHILD)%"=0 WHERE "%(ATTCHILD)%"=OLD."%(ATTPARENT)%"; "\
"END")
/**
* @def FOREIGNCONSTRAINTCASCADE
* Define a standard trigger for foreign constraint cascade delete
*/
#define FOREIGNCONSTRAINTCASCADE(TABLEPARENT,ATTPARENT,TABLECHILD,ATTCHILD)\
INSERTUPDATECONSTRAINT(TABLEPARENT,ATTPARENT,TABLECHILD,ATTCHILD)\
<< DELETECASCADE(TABLEPARENT,ATTPARENT,TABLECHILD,ATTCHILD)
/**
* @def DELETECASCADEPARAMETER
* Define a cascaded delete to delete parameters associated with an object
*/
#define DELETECASCADEPARAMETER(TABLE) \
(QStringList() << QString()%"DROP TRIGGER IF EXISTS fkdc_"%(TABLE)%"_parameters_uuid" \
<< QString()%"CREATE TRIGGER fkdc_"%(TABLE)%"_parameters_uuid "\
"BEFORE DELETE ON "%(TABLE)%" "\
"FOR EACH ROW BEGIN "\
" DELETE FROM parameters WHERE parameters.t_uuid_parent=OLD.id||'-'||'"%(TABLE)%"'; "\
"END")
#endif
diff --git a/skgbasemodeler/skgdocument.cpp b/skgbasemodeler/skgdocument.cpp
index ec6ea19bb..72b89ebee 100644
--- a/skgbasemodeler/skgdocument.cpp
+++ b/skgbasemodeler/skgdocument.cpp
@@ -1,3503 +1,3503 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file implements classes SKGDocument.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgdocument.h"
#include <kcolorscheme.h>
#include <qapplication.h>
#include <qdbusconnection.h>
#include <qdir.h>
#include <qfile.h>
#include <qhash.h>
#include <qicon.h>
#include <qjsondocument.h>
#include <qprocess.h>
#include <qregexp.h>
#include <qregularexpression.h>
#include <qsqldatabase.h>
#include <qsqldriver.h>
#include <qsqlerror.h>
#include <qsqlquery.h>
#include <qtconcurrentrun.h>
#include <qthread.h>
#include <qurl.h>
#include <quuid.h>
#include <qvariant.h>
#include <sqlite3.h>
#include <cmath>
#include "skgdocumentprivate.h"
#include "skgerror.h"
#include "skgpropertyobject.h"
#include "skgreport.h"
#include "skgservices.h"
#include "skgtraces.h"
#include "skgtransactionmng.h"
#define SQLDRIVERNAME QStringLiteral("SKGSQLCIPHER")
/**
* Custom sqlite function.
*/
static void sleepFunction(sqlite3_context* context, int /*argc*/, sqlite3_value** argv)
{
int len1 = sqlite3_value_bytes16(argv[ 0 ]);
const void* data1 = sqlite3_value_text16(argv[ 0 ]);
if (Q_LIKELY(data1)) {
auto s = SKGServices::stringToInt(QString(reinterpret_cast<const QChar*>(data1), len1 / sizeof(QChar)));
QThread::sleep(s);
sqlite3_result_text(context, "OK", 2, SQLITE_TRANSIENT);
}
}
/**
* Custom sqlite function.
*/
static void periodFunction(sqlite3_context* context, int /*argc*/, sqlite3_value** argv)
{
int len1 = sqlite3_value_bytes16(argv[ 0 ]);
const void* data1 = sqlite3_value_text16(argv[ 0 ]);
int len2 = sqlite3_value_bytes16(argv[ 1 ]);
const void* data2 = sqlite3_value_text16(argv[ 1 ]);
if (Q_LIKELY(data1 && data2)) {
QDate date = SKGServices::stringToTime(QString(reinterpret_cast<const QChar*>(data1), len1 / sizeof(QChar))).date();
QString format = QString::fromRawData(reinterpret_cast<const QChar*>(data2), len2 / sizeof(QChar)).toUpper();
QString period = SKGServices::dateToPeriod(date, format);
QByteArray output = period.toUtf8();
sqlite3_result_text(context, output.constData(), output.size(), SQLITE_TRANSIENT);
}
}
/**
* Custom sqlite function.
*/
static void formattedDateFunction(sqlite3_context* context, int /*argc*/, sqlite3_value** argv)
{
int len1 = sqlite3_value_bytes16(argv[ 0 ]);
const void* data1 = sqlite3_value_text16(argv[ 0 ]);
int len2 = sqlite3_value_bytes16(argv[ 1 ]);
const void* data2 = sqlite3_value_text16(argv[ 1 ]);
if (Q_LIKELY(data1 && data2)) {
QString string(reinterpret_cast<const QChar*>(data1), len1 / sizeof(QChar));
QString format = QString::fromRawData(reinterpret_cast<const QChar*>(data2), len2 / sizeof(QChar));
QString date = QDate::fromString(string, QStringLiteral("yyyy-MM-dd")).toString(format);
QByteArray output = date.toUtf8();
sqlite3_result_text(context, output.constData(), output.size(), SQLITE_TRANSIENT);
}
}
/**
* Custom sqlite function.
*/
static void dateFunction(sqlite3_context* context, int /*argc*/, sqlite3_value** argv)
{
int len1 = sqlite3_value_bytes16(argv[ 0 ]);
const void* data1 = sqlite3_value_text16(argv[ 0 ]);
int len2 = sqlite3_value_bytes16(argv[ 1 ]);
const void* data2 = sqlite3_value_text16(argv[ 1 ]);
if (Q_LIKELY(data1 && data2)) {
QString string(reinterpret_cast<const QChar*>(data1), len1 / sizeof(QChar));
QString format = QString::fromRawData(reinterpret_cast<const QChar*>(data2), len2 / sizeof(QChar));
QString date = SKGServices::dateToSqlString(string, format).trimmed();
if (date.isEmpty()) {
date = QDate::currentDate().toString(QStringLiteral("yyyy-MM-dd"));
}
QByteArray output = date.toUtf8();
sqlite3_result_text(context, output.constData(), output.size(), SQLITE_TRANSIENT);
}
}
/**
* Custom sqlite function.
*/
static void currencyFunction(sqlite3_context* context, int /*argc*/, sqlite3_value** argv)
{
int len1 = sqlite3_value_bytes16(argv[ 0 ]);
const void* data1 = sqlite3_value_text16(argv[ 0 ]);
int len2 = sqlite3_value_bytes16(argv[ 1 ]);
const void* data2 = sqlite3_value_text16(argv[ 1 ]);
if (Q_LIKELY(data1 && data2)) {
double string = SKGServices::stringToDouble(QString::fromRawData(reinterpret_cast<const QChar*>(data1), len1 / sizeof(QChar)));
QString symbol = QString::fromRawData(reinterpret_cast<const QChar*>(data2), len2 / sizeof(QChar));
QString currency = SKGServices::toCurrencyString(string, symbol);
QByteArray output = currency.toUtf8();
sqlite3_result_text(context, output.constData(), output.size(), SQLITE_TRANSIENT);
}
}
/**
* Custom sqlite function.
*/
static void xorFunction(sqlite3_context* context, int /*argc*/, sqlite3_value** argv)
{
int len1 = sqlite3_value_bytes16(argv[ 0 ]);
const void* data1 = sqlite3_value_text16(argv[ 0 ]);
int len2 = sqlite3_value_bytes16(argv[ 1 ]);
const void* data2 = sqlite3_value_text16(argv[ 1 ]);
if (Q_LIKELY(data1 && data2)) {
auto string = QString::fromRawData(reinterpret_cast<const QChar*>(data1), len1 / sizeof(QChar)).toUtf8();
auto key = QString::fromRawData(reinterpret_cast<const QChar*>(data2), len2 / sizeof(QChar)).toUtf8();
if (string.startsWith(QByteArray("# "))) {
// Decrypt
string = QByteArray::fromHex(string.right(string.length() - 2));
QByteArray estring;
for (int i = 0; i < string.size(); ++i) {
estring += static_cast<char>(string[i] ^ key[i % key.size()]);
}
QByteArray output = estring;
sqlite3_result_text(context, output.constData(), output.size(), SQLITE_TRANSIENT);
} else {
// Encrypt
QByteArray estring;
for (int i = 0; i < string.size(); ++i) {
estring += static_cast<char>(string[i] ^ key[i % key.size()]);
}
QByteArray output = "# " + estring.toHex();
sqlite3_result_text(context, output.constData(), output.size(), SQLITE_TRANSIENT);
}
}
}
static void xordoubleFunction(sqlite3_context* context, int /*argc*/, sqlite3_value** argv)
{
int len1 = sqlite3_value_bytes16(argv[ 0 ]);
const void* data1 = sqlite3_value_text16(argv[ 0 ]);
int len2 = sqlite3_value_bytes16(argv[ 1 ]);
const void* data2 = sqlite3_value_text16(argv[ 1 ]);
if (Q_LIKELY(data1 && data2)) {
auto d = SKGServices::stringToDouble(QString::fromRawData(reinterpret_cast<const QChar*>(data1), len1 / sizeof(QChar)).toUtf8());
auto key = QString::fromRawData(reinterpret_cast<const QChar*>(data2), len2 / sizeof(QChar)).toUtf8();
int kk = 0;
for (int i = 0; i < key.size(); ++i) {
kk += key[i];
}
QByteArray output = SKGServices::doubleToString(static_cast<double>(kk) - d).toUtf8();
sqlite3_result_text(context, output.constData(), output.size(), SQLITE_TRANSIENT);
}
}
/**
* Custom sqlite function.
*/
static void wordFunction(sqlite3_context* context, int /*argc*/, sqlite3_value** argv)
{
int len1 = sqlite3_value_bytes16(argv[ 0 ]);
const void* data1 = sqlite3_value_text16(argv[ 0 ]);
int len2 = sqlite3_value_bytes16(argv[ 1 ]);
const void* data2 = sqlite3_value_text16(argv[ 1 ]);
if (Q_LIKELY(data1 && data2)) {
QString string1(reinterpret_cast<const QChar*>(data1), len1 / sizeof(QChar));
string1 = string1.simplified();
QRegularExpression re(QStringLiteral("(\\w+)"));
QRegularExpressionMatchIterator i = re.globalMatch(string1);
QStringList list;
while (i.hasNext()) {
QRegularExpressionMatch match = i.next();
QString word = match.captured(1);
list << word;
}
int pos = SKGServices::stringToInt(QString::fromRawData(reinterpret_cast<const QChar*>(data2), len2 / sizeof(QChar)));
if (pos == 0) {
pos = 1;
} else if (pos > list.count()) {
pos = list.count();
} else if (pos < -list.count()) {
pos = 1;
} else if (pos < 0) {
pos = list.count() + pos + 1;
}
QByteArray output = list[pos - 1].toUtf8();
sqlite3_result_text(context, output.constData(), output.size(), SQLITE_TRANSIENT);
}
}
/**
* Custom sqlite function.
*/
static void wildcardFunction(sqlite3_context* context, int /*argc*/, sqlite3_value** argv)
{
int len1 = sqlite3_value_bytes16(argv[ 0 ]);
const void* data1 = sqlite3_value_text16(argv[ 0 ]);
int len2 = sqlite3_value_bytes16(argv[ 1 ]);
const void* data2 = sqlite3_value_text16(argv[ 1 ]);
if (Q_LIKELY(data1 && data2)) {
QString string1(reinterpret_cast<const QChar*>(data1), len1 / sizeof(QChar));
QString string2 = QString::fromRawData(reinterpret_cast<const QChar*>(data2), len2 / sizeof(QChar));
QRegExp pattern(string1, Qt::CaseInsensitive, QRegExp::Wildcard);
if (pattern.isValid()) {
sqlite3_result_int(context, static_cast<int>(pattern.exactMatch(string2)));
} else {
sqlite3_result_error(context, pattern.errorString().toUtf8().constData(), -1);
}
}
}
/**
* Custom sqlite function.
*/
static void regexpFunction(sqlite3_context* context, int /*argc*/, sqlite3_value** argv)
{
int len1 = sqlite3_value_bytes16(argv[ 0 ]);
const void* data1 = sqlite3_value_text16(argv[ 0 ]);
int len2 = sqlite3_value_bytes16(argv[ 1 ]);
const void* data2 = sqlite3_value_text16(argv[ 1 ]);
if (Q_LIKELY(data1 && data2)) {
QString string1(reinterpret_cast<const QChar*>(data1), len1 / sizeof(QChar));
QString string2 = QString::fromRawData(reinterpret_cast<const QChar*>(data2), len2 / sizeof(QChar));
QRegExp pattern(string1, Qt::CaseInsensitive, QRegExp::RegExp2);
if (pattern.isValid()) {
sqlite3_result_int(context, static_cast<int>(pattern.exactMatch(string2)));
} else {
sqlite3_result_error(context, pattern.errorString().toUtf8().constData(), -1);
}
}
}
/**
* Custom sqlite function.
*/
static void regexpCaptureFunction(sqlite3_context* context, int /*argc*/, sqlite3_value** argv)
{
int len1 = sqlite3_value_bytes16(argv[ 0 ]);
const void* data1 = sqlite3_value_text16(argv[ 0 ]);
int len2 = sqlite3_value_bytes16(argv[ 1 ]);
const void* data2 = sqlite3_value_text16(argv[ 1 ]);
int len3 = sqlite3_value_bytes16(argv[ 2 ]);
const void* data3 = sqlite3_value_text16(argv[ 2 ]);
if (Q_LIKELY(data1 && data2 && data3)) {
int pos = SKGServices::stringToInt(QString::fromRawData(reinterpret_cast<const QChar*>(data3), len3 / sizeof(QChar)));
QString string1(reinterpret_cast<const QChar*>(data1), len1 / sizeof(QChar));
QString string2 = QString::fromRawData(reinterpret_cast<const QChar*>(data2), len2 / sizeof(QChar));
QRegExp pattern(string1, Qt::CaseInsensitive, QRegExp::RegExp2);
if (pattern.isValid()) {
pattern.indexIn(string2);
QByteArray output = pattern.capturedTexts().value(pos).toUtf8();
sqlite3_result_text(context, output.constData(), output.size(), SQLITE_TRANSIENT);
} else {
sqlite3_result_error(context, pattern.errorString().toUtf8().constData(), -1);
}
}
}
/**
* Custom sqlite function.
*/
static void upperFunction(sqlite3_context* context, int /*argc*/, sqlite3_value** argv)
{
int len1 = sqlite3_value_bytes16(argv[ 0 ]);
const void* data1 = sqlite3_value_text16(argv[ 0 ]);
if (Q_LIKELY(data1)) {
QByteArray output = QString::fromRawData(reinterpret_cast<const QChar*>(data1), len1 / sizeof(QChar)).toUpper().toUtf8();
sqlite3_result_text(context, output.constData(), output.size(), SQLITE_TRANSIENT);
}
}
/**
* Custom sqlite function.
*/
static void nextFunction(sqlite3_context* context, int /*argc*/, sqlite3_value** argv)
{
int len1 = sqlite3_value_bytes16(argv[ 0 ]);
const void* data1 = sqlite3_value_text16(argv[ 0 ]);
if (Q_LIKELY(data1)) {
QByteArray output = SKGServices::getNextString(QString::fromRawData(reinterpret_cast<const QChar*>(data1), len1 / sizeof(QChar))).toUtf8();
sqlite3_result_text(context, output.constData(), output.size(), SQLITE_TRANSIENT);
}
}
/**
* Custom sqlite function.
*/
static void lowerFunction(sqlite3_context* context, int /*argc*/, sqlite3_value** argv)
{
int len1 = sqlite3_value_bytes16(argv[ 0 ]);
const void* data1 = sqlite3_value_text16(argv[ 0 ]);
if (Q_LIKELY(data1)) {
QByteArray output = QString::fromRawData(reinterpret_cast<const QChar*>(data1), len1 / sizeof(QChar)).toLower().toUtf8();
sqlite3_result_text(context, output.constData(), output.size(), SQLITE_TRANSIENT);
}
}
/**
* Custom sqlite function.
*/
static void capitalizeFunction(sqlite3_context* context, int /*argc*/, sqlite3_value** argv)
{
int len1 = sqlite3_value_bytes16(argv[ 0 ]);
const void* data1 = sqlite3_value_text16(argv[ 0 ]);
if (Q_LIKELY(data1)) {
QString str = QString::fromRawData(reinterpret_cast<const QChar*>(data1), len1 / sizeof(QChar));
QByteArray output = (str.at(0).toUpper() + str.mid(1).toLower()).toUtf8();
sqlite3_result_text(context, output.constData(), output.size(), SQLITE_TRANSIENT);
}
}
static SKGError addSqliteAddon(QSqlDatabase* iDb)
{
SKGError err;
auto* sqlite_handle = iDb->driver()->handle().value<sqlite3*>();
if (sqlite_handle != nullptr) {
sqlite3_create_function(sqlite_handle, "REGEXP", 2, SQLITE_UTF16 | SQLITE_DETERMINISTIC, nullptr, &regexpFunction, nullptr, nullptr);
sqlite3_create_function(sqlite_handle, "REGEXPCAPTURE", 3, SQLITE_UTF16 | SQLITE_DETERMINISTIC, nullptr, &regexpCaptureFunction, nullptr, nullptr);
sqlite3_create_function(sqlite_handle, "WILDCARD", 2, SQLITE_UTF16 | SQLITE_DETERMINISTIC, nullptr, &wildcardFunction, nullptr, nullptr);
sqlite3_create_function(sqlite_handle, "WORD", 2, SQLITE_UTF16 | SQLITE_DETERMINISTIC, nullptr, &wordFunction, nullptr, nullptr);
sqlite3_create_function(sqlite_handle, "TODATE", 2, SQLITE_UTF16 | SQLITE_DETERMINISTIC, nullptr, &dateFunction, nullptr, nullptr);
sqlite3_create_function(sqlite_handle, "TOFORMATTEDDATE", 2, SQLITE_UTF16 | SQLITE_DETERMINISTIC, nullptr, &formattedDateFunction, nullptr, nullptr);
sqlite3_create_function(sqlite_handle, "PERIOD", 2, SQLITE_UTF16 | SQLITE_DETERMINISTIC, nullptr, &periodFunction, nullptr, nullptr);
sqlite3_create_function(sqlite_handle, "SLEEP", 1, SQLITE_UTF16 | SQLITE_DETERMINISTIC, nullptr, &sleepFunction, nullptr, nullptr);
sqlite3_create_function(sqlite_handle, "TOCURRENCY", 2, SQLITE_UTF16 | SQLITE_DETERMINISTIC, nullptr, &currencyFunction, nullptr, nullptr);
sqlite3_create_function(sqlite_handle, "XOR", 2, SQLITE_UTF16 | SQLITE_DETERMINISTIC, nullptr, &xorFunction, nullptr, nullptr);
sqlite3_create_function(sqlite_handle, "XORD", 2, SQLITE_UTF16 | SQLITE_DETERMINISTIC, nullptr, &xordoubleFunction, nullptr, nullptr);
sqlite3_create_function(sqlite_handle, "UPPER", 1, SQLITE_UTF16 | SQLITE_DETERMINISTIC, nullptr, &upperFunction, nullptr, nullptr);
sqlite3_create_function(sqlite_handle, "LOWER", 1, SQLITE_UTF16 | SQLITE_DETERMINISTIC, nullptr, &lowerFunction, nullptr, nullptr);
sqlite3_create_function(sqlite_handle, "NEXT", 1, SQLITE_UTF16 | SQLITE_DETERMINISTIC, nullptr, &nextFunction, nullptr, nullptr);
int rc = sqlite3_create_function(sqlite_handle, "CAPITALIZE", 1, SQLITE_UTF16 | SQLITE_DETERMINISTIC, nullptr, &capitalizeFunction, nullptr, nullptr);
if (rc != SQLITE_OK) {
err = SKGError(SQLLITEERROR + rc, QStringLiteral("sqlite3_create_function failed"));
}
} else {
SKGTRACE << "WARNING: Custom sqlite functions not added" << endl;
}
return err;
}
SKGDocument::SKGDocument()
: d(new SKGDocumentPrivate())
{
SKGTRACEINFUNC(10)
// Set the QThreadPool
// QThreadPool::globalInstance()->setMaxThreadCount(3*QThread::idealThreadCount());
// DBUS registration
QDBusConnection dbus = QDBusConnection::sessionBus();
dbus.registerObject(QStringLiteral("/skg/skgdocument"), this, QDBusConnection::ExportAllContents);
dbus.registerService(QStringLiteral("org.skg"));
// Initialisation of undoable tables
SKGListNotUndoable.push_back(QStringLiteral("T.doctransaction"));
SKGListNotUndoable.push_back(QStringLiteral("T.doctransactionitem"));
SKGListNotUndoable.push_back(QStringLiteral("T.doctransactionmsg"));
// Database unique identifier
++SKGDocumentPrivate::m_databaseUniqueIdentifier;
d->m_databaseIdentifier = "SKGDATABASE_" % SKGServices::intToString(SKGDocumentPrivate::m_databaseUniqueIdentifier);
// Initialisation of backup file parameters
setBackupParameters(QLatin1String(""), QStringLiteral(".old"));
// 320157 vvvv
// Disable OS lock
sqlite3_vfs* vfs = sqlite3_vfs_find("unix-none");
if (Q_LIKELY(vfs)) {
sqlite3_vfs_register(vfs, 1);
} else {
SKGTRACE << "WARNING: Impossible to use the 'unix-none' vfs mode of sqlite3. Use:'" << sqlite3_vfs_find(nullptr)->zName << "'" << endl;
}
// 320157 ^^^^
}
SKGDocument::~SKGDocument()
{
SKGTRACEINFUNC(10)
close();
d->m_progressFunction = nullptr;
d->m_progressData = nullptr;
d->m_checkFunctions.clear();
for (auto w : qAsConst(d->m_watchers)) {
delete w;
}
d->m_watchers.clear();
delete d->m_cacheSql;
d->m_cacheSql = nullptr;
delete d;
d = nullptr;
}
QString SKGDocument::getUniqueIdentifier() const
{
return d->m_uniqueIdentifier;
}
QString SKGDocument::getDatabaseIdentifier() const
{
return d->m_databaseIdentifier;
}
SKGError SKGDocument::setProgressCallback(FuncProgress iProgressFunction, void* iData)
{
d->m_progressFunction = iProgressFunction;
d->m_progressData = iData;
return SKGError();
}
SKGError SKGDocument::addEndOfTransactionCheck(SKGError(*iCheckFunction)(SKGDocument*))
{
d->m_checkFunctions.append(iCheckFunction);
return SKGError();
}
SKGError SKGDocument::stepForward(int iPosition, const QString& iText)
{
SKGError err;
// Increase the step for the last transaction
if (Q_LIKELY(getDepthTransaction())) {
d->m_posStepForTransaction.pop_back();
d->m_posStepForTransaction.push_back(iPosition);
}
// Check if a callback function exists
if (Q_LIKELY(d->m_progressFunction)) {
// YES ==> compute
double min = 0;
double max = 100;
bool emitevent = true;
auto nbIt = d->m_nbStepForTransaction.constBegin();
auto posIt = d->m_posStepForTransaction.constBegin();
for (; emitevent && nbIt != d->m_nbStepForTransaction.constEnd(); ++nbIt) {
int p = *posIt;
int n = *nbIt;
if (Q_UNLIKELY(p < 0 || p > n)) {
p = n;
}
if (Q_LIKELY(n != 0)) {
double pmin = min;
double pmax = max;
min = pmin + (pmax - pmin) * (static_cast<double>(p) / static_cast<double>(n));
max = pmin + (pmax - pmin) * (static_cast<double>(p + 1) / static_cast<double>(n));
if (Q_UNLIKELY(max > 100)) {
max = 100;
}
} else {
emitevent = false;
}
++posIt;
}
int posPercent = rint(min);
// Call the call back
if (emitevent) {
d->m_inProgress = true;
QString text;
qint64 time = QDateTime::currentMSecsSinceEpoch() - d->m_timeBeginTransaction;
if (Q_UNLIKELY(time > 3000)) {
text = iText;
if (text.isEmpty()) {
text = d->m_nameForTransaction.at(d->m_nameForTransaction.count() - 1);
}
}
if (Q_LIKELY(d->m_progressFunction(posPercent, time, text, d->m_progressData) != 0)) {
err.setReturnCode(ERR_ABORT).setMessage(i18nc("User interrupted something that Skrooge was performing", "The current operation has been interrupted"));
// Remove all untransactionnal messaged
m_unTransactionnalMessages.clear();
}
d->m_inProgress = false;
}
}
return err;
}
SKGError SKGDocument::beginTransaction(const QString& iName, int iNbStep, const QDateTime& iDate, bool iRefreshViews)
{
SKGError err;
SKGTRACEINFUNCRC(5, err)
SKGTRACEL(10) << "Input parameter [name]=[" << iName << "] [nb step]=[" << iNbStep << "] [refresh]=[" << (iRefreshViews ? QStringLiteral("Y") : QStringLiteral("N")) << ']' << endl;
bool overrideCursor = false;
if (d->m_nbStepForTransaction.isEmpty()) {
// Open SQLtransaction
err = executeSqliteOrder(QStringLiteral("BEGIN;"));
IFOK(err) {
overrideCursor = true;
// Create undo redo transaction
err = executeSqliteOrder(QStringLiteral("insert into doctransaction (d_date, t_name, i_parent") %
(!iRefreshViews ? ", t_refreshviews" : "") %
") values "
"('" % SKGServices::timeToString(iDate) %
"','" % SKGServices::stringToSqlString(iName) %
"', " % SKGServices::intToString(getTransactionToProcess(SKGDocument::UNDO)) %
(!iRefreshViews ? ",'N'" : "") %
");");
addValueInCache(QStringLiteral("SKG_REFRESH_VIEW"), (iRefreshViews ? QStringLiteral("Y") : QStringLiteral("N")));
d->m_currentTransaction = getTransactionToProcess(SKGDocument::UNDO);
d->m_timeBeginTransaction = QDateTime::currentMSecsSinceEpoch();
}
} else {
// A transaction already exists
// Check if the child transaction is a opened in the progress callback
if (d->m_inProgress) {
err.setReturnCode(ERR_FAIL).setMessage(i18nc("Something went wrong with SQL transactions", "A transaction cannot be started during execution of another one"));
}
}
IFOK(err) {
d->m_nbStepForTransaction.push_back(iNbStep);
d->m_posStepForTransaction.push_back(iNbStep);
QString n = iName;
n = n.remove(QStringLiteral("#INTERNAL#"));
if (n.isEmpty() && !d->m_nameForTransaction.isEmpty()) {
n = d->m_nameForTransaction.at(d->m_nameForTransaction.count() - 1);
}
d->m_nameForTransaction.push_back(n);
if (iNbStep > 0) {
err = stepForward(0);
}
} else {
executeSqliteOrder(QStringLiteral("ROLLBACK;"));
}
if (Q_LIKELY(overrideCursor && !err && qobject_cast<QGuiApplication*>(qApp) != nullptr)) { // clazy:excludeall=unneeded-cast
QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
}
return err;
}
SKGError SKGDocument::checkExistingTransaction() const
{
SKGError err;
if (d->m_nbStepForTransaction.isEmpty()) {
err.setReturnCode(ERR_ABORT).setMessage(i18nc("Something went wrong with SQL transactions", "A transaction must be opened to do this action"));
}
return err;
}
SKGError SKGDocument::endTransaction(bool succeedded)
{
SKGError err;
SKGError errOverwritten;
SKGTRACEINFUNCRC(5, err)
if (Q_UNLIKELY(d->m_nbStepForTransaction.empty())) {
err.setReturnCode(ERR_ABORT).setMessage(i18nc("Something went wrong with SQL transactions", "Closing transaction failed because too many transactions ended"));
} else {
stepForward(d->m_nbStepForTransaction.at(d->m_nbStepForTransaction.count() - 1)); // =100%
if (Q_LIKELY(d->m_nbStepForTransaction.size())) { // This test is needed. It is a security in some cases.
d->m_nbStepForTransaction.pop_back();
d->m_posStepForTransaction.pop_back();
d->m_nameForTransaction.pop_back();
}
QString currentTransactionString = SKGServices::intToString(getCurrentTransaction());
if (d->m_nbStepForTransaction.empty()) {
QStringList listModifiedTables;
// Check
if (succeedded) {
auto cachepointer = d->m_cache;
d->m_cache = QHash<QString, QString>();
for (auto check : qAsConst(d->m_checkFunctions)) {
errOverwritten = check(this);
IFKO(errOverwritten) {
succeedded = false;
SKGTRACEL(5) << "Transaction cancelled by a check" << endl;
break;
}
}
d->m_cache = cachepointer;
}
if (succeedded) {
// Link items on current transaction
IFOK(err) {
err = executeSqliteOrder("UPDATE doctransactionitem set rd_doctransaction_id=" % currentTransactionString % " WHERE rd_doctransaction_id=0;");
}
// Optimization of the current transaction
IFOK(err) {
SKGStringListList listTmp;
err = executeSelectSqliteOrder("SELECT count(1) FROM doctransactionitem where rd_doctransaction_id=" % currentTransactionString, listTmp);
IFOK(err) {
int nbItem = SKGServices::stringToInt(listTmp.at(1).at(0));
if (nbItem == 0) {
// Optimization is needed
// Get non hidden messages
SKGMessageList messages;
getMessages(getCurrentTransaction(), messages, false);
// Delete current transaction
err = executeSqliteOrder("DELETE FROM doctransaction WHERE id=" % currentTransactionString);
int nb = messages.count();
for (int i = 0; i < nb; ++i) {
m_unTransactionnalMessages.push_back(messages.at(i));
}
}
}
}
// Optimization 2: remove duplicate orders
IFOK(err) {
QString wc = "DELETE FROM doctransactionitem WHERE id IN "
"(SELECT a.id FROM doctransactionitem a INDEXED BY idx_doctransactionitem_optimization, doctransactionitem b INDEXED BY idx_doctransactionitem_optimization "
"WHERE a.rd_doctransaction_id=" % currentTransactionString % " AND b.rd_doctransaction_id=" % currentTransactionString %
" AND a.i_object_id=b.i_object_id AND a.t_object_table=b.t_object_table AND b.t_action=a.t_action AND b.t_sqlorder=a.t_sqlorder AND a.id>b.id );";
err = executeSqliteOrder(wc);
}
// Get current transaction information to be able to emit envent in case of SKG_UNDO_MAX_DEPTH=0
IFOK(err) {
err = this->getDistinctValues(QStringLiteral("doctransactionitem"),
QStringLiteral("t_object_table"),
"rd_doctransaction_id=" % currentTransactionString,
listModifiedTables);
}
// Remove oldest transaction
IFOK(err) {
QString maxdepthstring = getParameter(QStringLiteral("SKG_UNDO_MAX_DEPTH"));
if (maxdepthstring.isEmpty()) {
maxdepthstring = QStringLiteral("-1");
}
int maxdepth = SKGServices::stringToInt(maxdepthstring);
if (maxdepth >= 0) {
err = executeSqliteOrder("delete from doctransaction where id in (select id from doctransaction limit max(0,((select count(1) from doctransaction)-(" % maxdepthstring % "))))");
}
}
// Remove SKGDocument::REDO transactions if we are not in a undo / redo transaction
if (d->m_inundoRedoTransaction == 0) {
int i = 0;
while (((i = getTransactionToProcess(SKGDocument::REDO)) != 0) && !err) {
err = executeSqliteOrder("delete from doctransaction where id=" % SKGServices::intToString(i));
}
}
// Commit the transaction
IFOK(err) {
err = executeSqliteOrder(QStringLiteral("COMMIT;"));
}
}
// clean cache sql (must be done before event emit)
d->m_cacheSql->clear();
if (!succeedded || err) {
// Rollback the transaction
SKGError err2 = executeSqliteOrder(QStringLiteral("ROLLBACK;"));
// delete the transaction
IFOKDO(err2, executeSqliteOrder("delete from doctransaction where id=" % currentTransactionString))
if (err2) {
err.addError(err2.getReturnCode(), err2.getMessage());
}
} else {
// For better performance, events are submitted only for the first recursive undo
if (Q_UNLIKELY(d->m_inundoRedoTransaction <= 1)) {
// Is it a light transaction?
bool lightTransaction = (getCachedValue(QStringLiteral("SKG_REFRESH_VIEW")) != QStringLiteral("Y"));
// Emit modification events
QStringList tablesRefreshed;
tablesRefreshed.reserve(listModifiedTables.count());
for (const auto& table : qAsConst(listModifiedTables)) {
Q_EMIT tableModified(table, getCurrentTransaction(), lightTransaction);
tablesRefreshed.push_back(table);
}
// Remove temporary transaction if needed
IFOKDO(err, executeSqliteOrder(QStringLiteral("delete from doctransaction where t_name LIKE '#INTERNAL#%';")))
Q_EMIT tableModified(QStringLiteral("doctransaction"), getCurrentTransaction(), lightTransaction);
Q_EMIT tableModified(QStringLiteral("doctransactionitem"), getCurrentTransaction(), lightTransaction);
// WARNING: list is modified during treatement
for (int i = 0; !err && i < listModifiedTables.count(); ++i) {
QString table = listModifiedTables.at(i);
QStringList toAdd = getImpactedViews(table);
int nbToAdd = toAdd.count();
for (int j = 0; !err && j < nbToAdd; ++j) {
const QString& toAddTable = toAdd.at(j);
if (!listModifiedTables.contains(toAddTable)) {
// Compute materialized view of modified table
if (!lightTransaction) {
err = computeMaterializedViews(toAddTable);
}
listModifiedTables.push_back(toAddTable);
}
}
}
// Emit events
for (int i = tablesRefreshed.count(); i < listModifiedTables.count(); ++i) {
Q_EMIT tableModified(listModifiedTables.at(i), 0, lightTransaction);
}
Q_EMIT transactionSuccessfullyEnded(getCurrentTransaction());
}
}
// clean cache
d->m_cache.clear();
d->m_currentTransaction = 0;
if (Q_LIKELY(qobject_cast<QGuiApplication*>(qApp) != nullptr)) { // clazy:excludeall=unneeded-cast
QApplication::restoreOverrideCursor();
}
}
}
IFOK(err) {
err = errOverwritten;
}
return err;
}
SKGError SKGDocument::removeAllTransactions()
{
SKGError err;
SKGTRACEINFUNCRC(10, err)
// Check if a transaction is still opened
err = checkExistingTransaction();
IFOK(err) err.setReturnCode(ERR_ABORT).setMessage(i18nc("Something went wrong with SQL transactions", "Remove of transactions is forbidden inside a transaction"));
else {
err = SKGDocument::beginTransaction(QStringLiteral("#INTERNAL#"));
IFOKDO(err, executeSqliteOrder(QStringLiteral("delete from doctransaction")))
SKGENDTRANSACTION(this, err)
// Force the save
d->m_lastSavedTransaction = -1;
}
return err;
}
SKGError SKGDocument::computeMaterializedViews(const QString& iTable) const
{
SKGError err;
SKGTRACEINFUNCRC(5, err)
// Compute additional where clause
QStringList tables;
if (d->m_MaterializedViews.contains(iTable)) {
tables = d->m_MaterializedViews[iTable];
} else {
QString wc;
if (!iTable.isEmpty()) {
QString t = iTable;
if (t.startsWith(QLatin1String("v_"))) {
t.replace(0, 2, QStringLiteral("vm_"));
}
wc = " AND name='" % t % '\'';
}
// Get list of materialized table
err = getDistinctValues(QStringLiteral("sqlite_master"), QStringLiteral("name"), "type='table' AND name LIKE 'vm_%' " % wc, tables);
d->m_MaterializedViews[iTable] = tables;
}
// Refresh tables
int nb = tables.count();
for (int i = 0; !err && i < nb; ++i) {
const QString& table = tables.at(i);
QString view = table;
view.replace(0, 3, QStringLiteral("v_"));
// Remove previous table
{
SKGTRACEINRC(5, "SKGDocument::computeMaterializedViews-drop-" % table, err)
err = executeSqliteOrder("DROP TABLE IF EXISTS " % table);
}
{
// Recreate table
SKGTRACEINRC(5, "SKGDocument::computeMaterializedViews-create-" % table, err)
IFOKDO(err, executeSqliteOrder("CREATE TABLE " % table % " AS SELECT * FROM " % view))
}
}
return err;
}
SKGError SKGDocument::sendMessage(const QString& iMessage, MessageType iMessageType, const QString& iAction)
{
SKGError err;
SKGTRACEINFUNCRC(10, err)
// Associate message with transaction
if (!checkExistingTransaction()) {
SKGObjectBase msg(this, QStringLiteral("doctransactionmsg"));
err = msg.setAttribute(QStringLiteral("rd_doctransaction_id"), SKGServices::intToString(getCurrentTransaction()));
IFOKDO(err, msg.setAttribute(QStringLiteral("t_message"), iMessage))
IFOKDO(err, msg.setAttribute(QStringLiteral("t_type"), iMessageType == SKGDocument::Positive ? QStringLiteral("P") :
iMessageType == SKGDocument::Information ? QStringLiteral("I") :
iMessageType == SKGDocument::Warning ? QStringLiteral("W") :
iMessageType == SKGDocument::Error ? QStringLiteral("E") : QStringLiteral("H")))
IFOKDO(err, msg.save())
}
if (checkExistingTransaction() || !iAction.isEmpty()) {
// Addition message in global variable in case of no transaction opened
bool found = false;
for (const auto& m : qAsConst(m_unTransactionnalMessages)) {
if (m.Text == iMessage) {
found = true;
}
}
if (iMessageType != SKGDocument::Hidden && !found) {
SKGMessage m;
m.Text = iMessage;
m.Type = iMessageType;
m.Action = iAction;
m_unTransactionnalMessages.push_back(m);
}
}
return err;
}
SKGError SKGDocument::removeMessages(int iIdTransaction)
{
SKGError err;
SKGTRACEINFUNCRC(10, err)
if (!checkExistingTransaction()) {
err = executeSqliteOrder("DELETE FROM doctransactionmsg WHERE rd_doctransaction_id=" % SKGServices::intToString(iIdTransaction));
}
m_unTransactionnalMessages.clear();
return err;
}
SKGError SKGDocument::getMessages(int iIdTransaction, SKGMessageList& oMessages, bool iAll)
{
SKGError err;
SKGTRACEINFUNCRC(10, err)
oMessages = m_unTransactionnalMessages;
SKGStringListList listTmp;
err = executeSelectSqliteOrder(
QStringLiteral("SELECT t_message, t_type FROM doctransactionmsg WHERE ") %
(iAll ? "" : "t_type<>'H' AND ") %
"rd_doctransaction_id=" %
SKGServices::intToString(iIdTransaction) %
" ORDER BY id ASC",
listTmp);
int nb = listTmp.count();
for (int i = 1; !err && i < nb ; ++i) {
QString msg = listTmp.at(i).at(0);
QString type = listTmp.at(i).at(1);
bool found = false;
for (const auto& m : qAsConst(m_unTransactionnalMessages)) {
if (m.Text == msg) {
found = true;
}
}
if (!found) {
SKGMessage m;
m.Text = msg;
m.Type = type == QStringLiteral("P") ? SKGDocument::Positive : type == QStringLiteral("I") ? SKGDocument::Information : type == QStringLiteral("W") ? SKGDocument::Warning : type == QStringLiteral("E") ? SKGDocument::Error : SKGDocument::Hidden;
oMessages.push_back(m);
}
}
m_unTransactionnalMessages.clear();
return err;
}
SKGError SKGDocument::getModifications(int iIdTransaction, SKGObjectModificationList& oModifications) const
{
SKGError err;
SKGTRACEINFUNCRC(10, err)
oModifications.clear();
SKGStringListList listTmp;
err = executeSelectSqliteOrder(
"SELECT i_object_id,t_object_table,t_action FROM doctransactionitem WHERE rd_doctransaction_id=" %
SKGServices::intToString(iIdTransaction) %
" ORDER BY id ASC",
listTmp);
int nb = listTmp.count();
for (int i = 1; !err && i < nb ; ++i) {
SKGObjectModification mod;
mod.id = SKGServices::stringToInt(listTmp.at(i).at(0));
mod.table = listTmp.at(i).at(1);
QString type = listTmp.at(i).at(2);
mod.type = (type == QStringLiteral("D") ? I : (type == QStringLiteral("I") ? D : U)); // Normal because in database we have to sql order to go back.
mod.uuid = listTmp.at(i).at(0) % '-' % mod.table;
oModifications.push_back(mod);
}
return err;
}
QStringList SKGDocument::getImpactedViews(const QString& iTable) const
{
SKGTRACEINFUNC(10)
if (Q_UNLIKELY(d->m_ImpactedViews.isEmpty())) {
// Get list of tables and views
QStringList tables;
SKGStringListList result;
executeSelectSqliteOrder(QStringLiteral("SELECT tbl_name FROM sqlite_master WHERE tbl_name NOT LIKE '%_delete' AND type IN ('table', 'view')"), result);
int nb = result.count();
tables.reserve(nb);
for (int i = 1; i < nb; ++i) {
tables.push_back(result.at(i).at(0));
}
// First computation
executeSelectSqliteOrder(QStringLiteral("SELECT tbl_name, sql FROM sqlite_master WHERE tbl_name NOT LIKE '%_delete' AND type='view'"), result);
nb = result.count();
for (int i = 1; i < nb; ++i) {
const QStringList& line = result.at(i);
const QString& name = line.at(0);
const QString& sql = line.at(1);
QStringList words = SKGServices::splitCSVLine(sql, ' ', false);
words.push_back(QStringLiteral("parameters"));
int nbWords = words.count();
for (int j = 0; j < nbWords; ++j) {
QString word = words.at(j);
word = word.remove(',');
if (word.startsWith(QLatin1String("vm_"))) {
word.replace(0, 3, QStringLiteral("v_"));
}
if (word != name && tables.contains(word, Qt::CaseInsensitive)) {
QStringList l = d->m_ImpactedViews.value(word);
if (!l.contains(name)) {
l.push_back(name);
}
d->m_ImpactedViews[word] = l;
}
}
}
// Now, we have some thing like this
// d->m_ImpactedViews[A]={ B, C, D}
// d->m_ImpactedViews[B]={ E, F}
// We must build d->m_ImpactedViews[A]={ B, C, D, E, F}
QStringList keys = d->m_ImpactedViews.keys();
for (const auto& k : qAsConst(keys)) {
QStringList l = d->m_ImpactedViews.value(k);
for (int i = 0; i < l.count(); ++i) { // Warning: the size of l will change in the loop
QString item = l.at(i);
if (d->m_ImpactedViews.contains(item)) {
// No qAsConst here, item is already const
for (const auto& name : d->m_ImpactedViews.value(item)) {
if (!l.contains(name)) {
l.push_back(name);
}
}
}
}
d->m_ImpactedViews[k] = l;
}
}
return d->m_ImpactedViews.value(iTable);
}
SKGError SKGDocument::groupTransactions(int iFrom, int iTo)
{
SKGError err;
SKGTRACEINFUNCRC(5, err)
++d->m_inundoRedoTransaction; // It is a kind of undo redo
// Check if a transaction is still opened
err = checkExistingTransaction();
IFOK(err) err.setReturnCode(ERR_ABORT).setMessage(i18nc("Something went wrong with SQL transactions", "Creation of a group of transactions is forbidden inside a transaction"));
else {
int iidMaster = qMax(iFrom, iTo);
QString smin = SKGServices::intToString(qMin(iFrom, iTo));
QString smax = SKGServices::intToString(iidMaster);
// Get transaction
SKGStringListList transactions;
err = executeSelectSqliteOrder(
QStringLiteral("SELECT id, t_name, t_mode, i_parent FROM doctransaction WHERE id BETWEEN ") %
smin % " AND " %
smax % " ORDER BY id ASC",
transactions);
// Check and get main parameter for the group
int nb = transactions.count();
QString transactionMode;
QString communParent;
QString name;
for (int i = 1; !err && i < nb; ++i) { // We forget header
const QStringList& transaction = transactions.at(i);
const QString& mode = transaction.at(2);
if (!name.isEmpty()) {
name += ',';
}
name += transaction.at(1);
if (!transactionMode.isEmpty() && mode != transactionMode) {
err = SKGError(ERR_INVALIDARG, QStringLiteral("Undo and Redo transactions cannot be grouped"));
} else {
transactionMode = mode;
}
if (i == 1) {
communParent = transaction.at(3);
}
}
// Group
IFOK(err) {
err = SKGDocument::beginTransaction(QStringLiteral("#INTERNAL#"));
// Group items
IFOKDO(err, executeSqliteOrder(
QStringLiteral("UPDATE doctransactionitem set rd_doctransaction_id=") %
smax %
" where rd_doctransaction_id BETWEEN " %
smin % " AND " % smax))
IFOKDO(err, executeSqliteOrder(
QStringLiteral("UPDATE doctransaction set i_parent=") %
communParent %
", t_name='" % SKGServices::stringToSqlString(name) %
"' where id=" % smax))
IFOKDO(err, executeSqliteOrder(
QStringLiteral("DELETE FROM doctransaction WHERE id BETWEEN ") %
smin % " AND " % SKGServices::intToString(qMax(iFrom, iTo) - 1)))
SKGENDTRANSACTION(this, err)
}
}
--d->m_inundoRedoTransaction;
return err;
}
SKGError SKGDocument::undoRedoTransaction(UndoRedoMode iMode)
{
SKGError err;
SKGTRACEINFUNCRC(5, err)
// Check if a transaction is still opened
err = checkExistingTransaction();
IFOK(err) err.setReturnCode(ERR_ABORT).setMessage(i18nc("Something went wrong with SQL transactions", "Undo / Redo is forbidden inside a transaction"));
else {
if (iMode == SKGDocument::UNDOLASTSAVE) {
// Create group
SKGStringListList transactions;
err = executeSelectSqliteOrder(
QStringLiteral("SELECT id, t_savestep FROM doctransaction WHERE t_mode='U' ORDER BY id DESC"),
transactions);
int nb = transactions.count();
int min = 0;
int max = 0;
for (int i = 1; !err && i < nb; ++i) {
const QStringList& transaction = transactions.at(i);
if (i == 1) {
max = SKGServices::stringToInt(transaction.at(0));
}
if (i != 1 && transaction.at(1) == QStringLiteral("Y")) {
break;
}
min = SKGServices::stringToInt(transaction.at(0));
}
if (min == 0) {
min = max;
}
if (!err && min != max && min != 0) {
err = groupTransactions(min, max);
}
} else {
err = SKGError(); // To ignore error generated by checkExistingTransaction.
}
// Get ID of the transaction to undo
IFOK(err) {
QString name;
bool saveStep = false;
QDateTime date;
bool refreshViews;
int id = getTransactionToProcess(iMode, &name, &saveStep, &date, &refreshViews);
if (id == 0) {
// No transaction found ==> generate an error
err = SKGError(ERR_INVALIDARG, QStringLiteral("No transaction found. Undo / Redo impossible."));
} else {
// Undo transaction
SKGTRACEL(5) << "Undoing transaction [" << id << "]- [" << name << "]..." << endl;
SKGStringListList listSqlOrder;
err = executeSelectSqliteOrder(
"SELECT t_sqlorder FROM doctransactionitem WHERE rd_doctransaction_id=" %
SKGServices::intToString(id) %
" ORDER BY id DESC",
listSqlOrder);
IFOK(err) {
int nb = listSqlOrder.count();
err = SKGDocument::beginTransaction(name, nb + 3, date, refreshViews);
IFOK(err) {
++d->m_inundoRedoTransaction; // Because we will be in a undo/redo transaction
// Normal the first element is ignored because it is the header
for (int i = 1; !err && i < nb ; ++i) {
err = executeSqliteOrder(listSqlOrder.at(i).at(0));
IFOKDO(err, stepForward(i))
}
IFOK(err) {
// Set the NEW transaction in redo mode
int lastredo = getTransactionToProcess((iMode == SKGDocument::UNDO || iMode == SKGDocument::UNDOLASTSAVE ? SKGDocument::REDO : SKGDocument::UNDO));
int newredo = getTransactionToProcess(iMode);
IFOKDO(err, executeSqliteOrder(
QStringLiteral("UPDATE doctransaction set t_mode=") %
(iMode == SKGDocument::UNDO || iMode == SKGDocument::UNDOLASTSAVE ? QStringLiteral("'R'") : QStringLiteral("'U'")) %
", i_parent=" %
SKGServices::intToString(lastredo) %
" where id=" % SKGServices::intToString(newredo)))
IFOKDO(err, stepForward(nb))
// Move messages from previous transaction to new one
IFOKDO(err, executeSqliteOrder(
"UPDATE doctransactionmsg set rd_doctransaction_id=" %
SKGServices::intToString(getCurrentTransaction()) %
" where rd_doctransaction_id=" %
SKGServices::intToString(id)))
IFOKDO(err, stepForward(nb + 1))
// delete treated transaction
IFOKDO(err, executeSqliteOrder(
"DELETE from doctransaction where id="
% SKGServices::intToString(id)))
IFOKDO(err, stepForward(nb + 2))
// Check that new transaction has exactly the same number of item
/* IFOK (err) {
SKGStringListList listSqlOrder;
err=executeSelectSqliteOrder(
"SELECT count(1) FROM doctransactionitem WHERE rd_doctransaction_id=" %
SKGServices::intToString(getCurrentTransaction()),
listSqlOrder);
if (!err && SKGServices::stringToInt(listSqlOrder.at(1).at(0))!=nb-1) {
err=SKGError(ERR_ABORT, i18nc("Error message", "Invalid number of item after undo/redo. Expected (%1) != Result (%2)",nb-1,listSqlOrder.at(1).at(0)));
}
}*/
IFOKDO(err, stepForward(nb + 3))
}
SKGENDTRANSACTION(this, err)
--d->m_inundoRedoTransaction; // We left the undo / redo transaction
}
}
}
}
}
return err;
}
int SKGDocument::getDepthTransaction() const
{
return d->m_nbStepForTransaction.size();
}
int SKGDocument::getNbTransaction(UndoRedoMode iMode) const
{
SKGTRACEINFUNC(10)
int output = 0;
if (Q_LIKELY(getMainDatabase())) {
QString sqlorder = QStringLiteral("select count(1) from doctransaction where t_mode='");
sqlorder += (iMode == SKGDocument::UNDO || iMode == SKGDocument::UNDOLASTSAVE ? QStringLiteral("U") : QStringLiteral("R"));
sqlorder += '\'';
QSqlQuery query = getMainDatabase()->exec(sqlorder);
if (query.next()) {
output = query.value(0).toInt();
}
}
return output;
}
int SKGDocument::getTransactionToProcess(UndoRedoMode iMode, QString* oName, bool* oSaveStep, QDateTime* oDate, bool* oRefreshViews) const
{
SKGTRACEINFUNC(10)
// initialisation
int output = 0;
if (oName != nullptr) {
*oName = QLatin1String("");
}
if (Q_LIKELY(getMainDatabase())) {
QString sqlorder = QStringLiteral("select A.id , A.t_name, A.t_savestep, A.d_date, A.t_refreshviews from doctransaction A where "
"NOT EXISTS(select 1 from doctransaction B where B.i_parent=A.id) "
"and A.t_mode='");
sqlorder += (iMode == SKGDocument::UNDO || iMode == SKGDocument::UNDOLASTSAVE ? QStringLiteral("U") : QStringLiteral("R"));
sqlorder += '\'';
QSqlQuery query = getMainDatabase()->exec(sqlorder);
if (query.next()) {
output = query.value(0).toInt();
if (oName != nullptr) {
*oName = query.value(1).toString();
}
if (oSaveStep != nullptr) {
*oSaveStep = (query.value(2).toString() == QStringLiteral("Y"));
}
if (oDate != nullptr) {
*oDate = SKGServices::stringToTime(query.value(3).toString());
}
if (oRefreshViews != nullptr) {
*oRefreshViews = (query.value(4).toString() == QStringLiteral("Y"));
}
}
}
return output;
}
int SKGDocument::getCurrentTransaction() const
{
SKGTRACEINFUNC(10)
return d->m_currentTransaction;
}
QString SKGDocument::getPassword() const
{
if (!d->m_password_got) {
d->m_password = getParameter(QStringLiteral("SKG_PASSWORD"));
d->m_password_got = true;
}
return d->m_password;
}
SKGError SKGDocument::changePassword(const QString& iNewPassword)
{
SKGError err;
SKGTRACEINFUNCRC(10, err)
IFOK(checkExistingTransaction()) err.setReturnCode(ERR_ABORT).setMessage(i18nc("Something went wrong with SQL transactions", "Change password is forbidden inside a transaction"));
else {
IFOKDO(err, executeSqliteOrder("PRAGMA REKEY = '" % SKGServices::stringToSqlString(iNewPassword.isEmpty() ? QStringLiteral("DEFAULTPASSWORD") : iNewPassword) % "'"))
IFOKDO(err, beginTransaction(QStringLiteral("#INTERNAL#"), 0, QDateTime::currentDateTime(), false))
IFOKDO(err, setParameter(QStringLiteral("SKG_PASSWORD"), iNewPassword))
IFOKDO(err, setParameter(QStringLiteral("SKG_PASSWORD_LASTUPDATE"), SKGServices::dateToSqlString(QDate::currentDate())))
IFOKDO(err, sendMessage(iNewPassword.isEmpty() ? i18nc("Inform the user that the password protection was removed", "The document password has been removed.") :
i18nc("Inform the user that the password was successfully changed", "The document password has been modified."), SKGDocument::Positive))
SKGENDTRANSACTION(this, err)
// Force the save
IFOK(err) {
d->m_lastSavedTransaction = -1;
d->m_password = iNewPassword;
d->m_password_got = true;
// Close all thread connection
auto conNameMainConnection = getMainDatabase()->connectionName();
const auto conNames = QSqlDatabase::connectionNames();
for (const auto& conName : conNames) {
if (conName.startsWith(conNameMainConnection % "_")) {
/* NO NEED
{
auto con = QSqlDatabase::database(conName, false);
con.close();
}*/
QSqlDatabase::removeDatabase(conName);
}
}
}
}
return err;
}
SKGError SKGDocument::setLanguage(const QString& iLanguage)
{
SKGError err;
SKGTRACEINFUNCRC(5, err)
QString previousLanguage = getParameter(QStringLiteral("SKG_LANGUAGE"));
if (previousLanguage != iLanguage) {
// Save language into the document
IFOKDO(err, beginTransaction(QStringLiteral("#INTERNAL#"), 0, QDateTime::currentDateTime(), false))
IFOKDO(err, setParameter(QStringLiteral("SKG_LANGUAGE"), iLanguage))
// Migrate view for new language
IFOKDO(err, refreshViewsIndexesAndTriggers())
// close temporary transaction
SKGENDTRANSACTION(this, err)
}
return err;
}
SKGError SKGDocument::initialize()
{
SKGError err;
SKGTRACEINFUNCRC(5, err)
err = load(QLatin1String(""), QLatin1String(""));
return err;
}
SKGError SKGDocument::recover(const QString& iName, const QString& iPassword, QString& oRecoveredFile)
{
SKGError err;
SKGTRACEINFUNCRC(5, err)
SKGTRACEL(10) << "Input parameter [name]=[" << iName << ']' << endl;
QString sqliteFile = QString(iName % "_recovered.sqlite").replace(QStringLiteral(".skg_"), QStringLiteral("_"));
oRecoveredFile = QString(iName % "_recovered.skg").replace(QStringLiteral(".skg_"), QStringLiteral("_"));
bool mode;
err = SKGServices::cryptFile(iName, sqliteFile, iPassword, false, getDocumentHeader(), mode);
IFOK(err) {
QFile(oRecoveredFile).remove();
QString cmd = "echo .dump | sqlite3 \"" % sqliteFile % "\" | sed -e 's/ROLLBACK; -- due to errors/COMMIT;/g' | sqlite3 \"" % oRecoveredFile % '"';
QProcess p;
p.start(QStringLiteral("sh"), QStringList() << QStringLiteral("-c") << cmd);
if (!p.waitForFinished(1000 * 60 * 2) || p.exitCode() != 0) {
err.setReturnCode(ERR_FAIL).setMessage(i18nc("Error message", "The following command line failed with code %2:\n'%1'", cmd, p.exitCode()));
}
// Try to load the recovered file
IFOKDO(err, load(oRecoveredFile, QLatin1String("")))
IFOK(err) {
SKGBEGINTRANSACTION(*this, i18nc("Noun", "Recovery"), err)
IFOKDO(err, refreshViewsIndexesAndTriggers(true))
}
IFOKDO(err, save())
// Reset the current document
initialize();
// Clean useless file
IFOK(err) {
// We keep only the recovered
QFile(sqliteFile).remove();
} else {
// We keep the sqlite file in case of
QFile(oRecoveredFile).remove();
err.addError(ERR_FAIL, i18nc("Error message", "Impossible to recover this file"));
}
}
return err;
}
SKGError SKGDocument::load(const QString& iName, const QString& iPassword, bool iRestoreTmpFile, bool iForceReadOnly)
{
// Close previous document
SKGError err;
SKGTRACEINFUNCRC(5, err)
SKGTRACEL(10) << "Input parameter [name]=[" << iName << ']' << endl;
SKGTRACEL(10) << "Input parameter [iRestoreTmpFile]=[" << (iRestoreTmpFile ? "TRUE" : "FALSE") << ']' << endl;
SKGTRACEL(10) << "Input parameter [iForceReadOnly]=[" << (iForceReadOnly ? "TRUE" : "FALSE") << ']' << endl;
d->m_lastSavedTransaction = -1; // To avoid double event emission
d->m_modeSQLCipher = true;
d->m_blockEmits = true;
err = close();
d->m_blockEmits = false;
IFOK(err) {
if (!iName.isEmpty()) {
// File exist
QFileInfo fi(iName);
d->m_modeReadOnly = iForceReadOnly || !fi.permission(QFile::WriteUser);
// Temporary file
d->m_temporaryFile = SKGDocument::getTemporaryFile(iName, d->m_modeReadOnly);
bool temporaryFileExisting = QFile(d->m_temporaryFile).exists();
SKGTRACEL(10) << "Temporary file: [" << d->m_temporaryFile << ']' << endl;
SKGTRACEL(10) << "Temporary file existing: [" << (temporaryFileExisting ? "TRUE" : "FALSE") << ']' << endl;
if (!iRestoreTmpFile || !temporaryFileExisting) {
SKGTRACEL(10) << "Create the temporary file" << endl;
QFile::remove(d->m_temporaryFile); // Must remove it to be able to copy
err = SKGServices::cryptFile(iName, d->m_temporaryFile, iPassword, false, getDocumentHeader(), d->m_modeSQLCipher);
} else {
SKGTRACEL(10) << "The temporary file is existing, try a restore but we must check if the file is password protected first" << endl;
// 249955: Check if password protected vvv
// Temporary file will be loaded but first we must check if original document is password protected
QString temporaryFile2 = d->m_temporaryFile % '2';
err = SKGServices::cryptFile(iName, temporaryFile2, iPassword, false, getDocumentHeader(), d->m_modeSQLCipher);
// Try an open to check if well descrypted
IFOK(err) {
QSqlDatabase tryOpen(QSqlDatabase::addDatabase(SQLDRIVERNAME, QStringLiteral("tryOpen")));
tryOpen.setDatabaseName(temporaryFile2);
if (!tryOpen.open()) {
// Set error message
QSqlError sqlErr = tryOpen.lastError();
err = SKGError(SQLLITEERROR + sqlErr.nativeErrorCode().toInt(), sqlErr.text());
}
if (d->m_modeSQLCipher) {
IFOKDO(err, SKGServices::executeSqliteOrder(tryOpen, "PRAGMA KEY = '" % SKGServices::stringToSqlString(iPassword.isEmpty() ? QStringLiteral("DEFAULTPASSWORD") : iPassword) % "'"))
IFKO(err) {
SKGTRACEL(10) << "Wrong installation of sqlcipher (doesn't support encryption)" << endl;
err = SKGError(ERR_ENCRYPTION, i18nc("Error message", "Wrong installation"));
}
// Migrate to the last version of SQLCipher
IFOKDO(err, SKGServices::executeSqliteOrder(tryOpen, QStringLiteral("PRAGMA cipher_migrate")))
// Test the password
IFOKDO(err, SKGServices::executeSqliteOrder(tryOpen, QStringLiteral("SELECT count(*) FROM sqlite_master")))
IFKO(err) {
SKGTRACEL(10) << "Wrong password in restore mode" << endl;
err = SKGError(ERR_ENCRYPTION, i18nc("Error message", "Wrong password"));
}
}
IFOKDO(err, SKGServices::executeSqliteOrder(tryOpen, QStringLiteral("PRAGMA synchronous = OFF")))
}
QSqlDatabase::removeDatabase(QStringLiteral("tryOpen"));
QFile::remove(temporaryFile2);
// To avoid deletion of temporary file during next try
IFKO(err) d->m_temporaryFile = QLatin1String("");
// 249955: Check if password protected ^^^
}
// Create file database
IFOK(err) {
d->m_currentDatabase = QSqlDatabase::addDatabase(SQLDRIVERNAME, d->m_databaseIdentifier);
d->m_currentDatabase.setDatabaseName(d->m_temporaryFile);
if (!d->m_currentDatabase.open()) {
// Set error message
QSqlError sqlErr = d->m_currentDatabase.lastError();
err = SKGError(SQLLITEERROR + sqlErr.nativeErrorCode().toInt(), sqlErr.text());
}
d->m_directAccessDb = true;
if (QUrl::fromUserInput(iName).isLocalFile()) {
d->m_currentFileName = iName;
}
}
} else {
// Temporary file
d->m_temporaryFile = QDir::tempPath() % "/skg_" % QUuid::createUuid().toString() % ".skg";
// Create memory database
d->m_currentDatabase = QSqlDatabase::addDatabase(SQLDRIVERNAME, d->m_databaseIdentifier);
d->m_currentDatabase.setConnectOptions(QStringLiteral("QSQLITE_OPEN_URI"));
d->m_currentDatabase.setDatabaseName(QStringLiteral("file:") + d->m_databaseIdentifier + QStringLiteral("?mode=memory&cache=shared"));
if (!d->m_currentDatabase.open()) {
// Set error message
QSqlError sqlErr = d->m_currentDatabase.lastError();
err = SKGError(SQLLITEERROR + sqlErr.nativeErrorCode().toInt(), sqlErr.text());
}
d->m_directAccessDb = false;
}
if (d->m_modeSQLCipher) {
// This is an encrypted data base
IFOKDO(err, executeSqliteOrder("PRAGMA KEY = '" % SKGServices::stringToSqlString(iPassword.isEmpty() ? QStringLiteral("DEFAULTPASSWORD") : iPassword) % "'"))
IFKO(err) {
SKGTRACEL(10) << "Wrong installation of sqlcipher (doesn't support encryption)" << endl;
err = SKGError(ERR_ENCRYPTION, i18nc("Error message", "Wrong installation"));
}
// Migrate to the last version of SQLCipher
IFOKDO(err, executeSqliteOrder(QStringLiteral("PRAGMA cipher_migrate")))
// Test the password
IFOKDO(err, executeSqliteOrder(QStringLiteral("SELECT count(*) FROM sqlite_master")))
IFKO(err) {
SKGTRACEL(10) << "Wrong password on temporary file" << endl;
err = SKGError(ERR_ENCRYPTION, i18nc("Error message", "Wrong password"));
}
}
// Check if the database is correct
IFOK(err) {
IFOKDO(err, executeSqliteOrder(QStringLiteral("PRAGMA journal_mode=MEMORY")))
IFKO(err) {
err.addError(ERR_CORRUPTION, i18nc("Error message", "Oups, this file seems to be corrupted"));
}
}
// Optimization
QStringList optimization;
optimization << QStringLiteral("PRAGMA case_sensitive_like=true")
<< QStringLiteral("PRAGMA journal_mode=MEMORY")
<< QStringLiteral("PRAGMA temp_store=MEMORY")
// << QStringLiteral("PRAGMA locking_mode=EXCLUSIVE")
<< QStringLiteral("PRAGMA synchronous = OFF")
<< QStringLiteral("PRAGMA legacy_alter_table=ON") // For migration on sqlite >=3.25 (see https://sqlite.org/lang_altertable.html)
<< QStringLiteral("PRAGMA recursive_triggers=true");
IFOKDO(err, executeSqliteOrders(optimization))
// Add custom sqlite functions
IFOKDO(err, addSqliteAddon(getMainDatabase()))
if (!d->m_directAccessDb) {
// Create parameter and undo redo table
/**
* This constant is used to initialized the data model (table creation)
*/
QStringList InitialDataModel;
// ==================================================================
// Table parameters
InitialDataModel << QStringLiteral("CREATE TABLE parameters "
"(id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,"
"t_uuid_parent TEXT NOT NULL DEFAULT '',"
"t_name TEXT NOT NULL,"
"t_value TEXT NOT NULL DEFAULT '',"
"b_blob BLOB,"
"d_lastmodifdate DATE NOT NULL DEFAULT CURRENT_TIMESTAMP,"
"i_tmp INTEGER NOT NULL DEFAULT 0"
")")
// ==================================================================
// Table node
<< "CREATE TABLE node ("
"id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,"
"t_name TEXT NOT NULL DEFAULT '' CHECK (t_name NOT LIKE '%" % OBJECTSEPARATOR % "%'),"
"t_fullname TEXT,"
"t_icon TEXT DEFAULT '',"
"f_sortorder FLOAT,"
"t_autostart VARCHAR(1) DEFAULT 'N' CHECK (t_autostart IN ('Y', 'N')),"
"t_data TEXT,"
"rd_node_id INT CONSTRAINT fk_id REFERENCES node(id) ON DELETE CASCADE)"
// ==================================================================
// Table doctransaction
<< QStringLiteral("CREATE TABLE doctransaction ("
"id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,"
"t_name TEXT NOT NULL,"
"t_mode VARCHAR(1) DEFAULT 'U' CHECK (t_mode IN ('U', 'R')),"
"d_date DATE NOT NULL,"
"t_savestep VARCHAR(1) DEFAULT 'N' CHECK (t_savestep IN ('Y', 'N')),"
"t_refreshviews VARCHAR(1) DEFAULT 'Y' CHECK (t_refreshviews IN ('Y', 'N')),"
"i_parent INTEGER)")
// ==================================================================
// Table doctransactionitem
<< QStringLiteral("CREATE TABLE doctransactionitem ("
"id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, "
"rd_doctransaction_id INTEGER NOT NULL,"
"i_object_id INTEGER NOT NULL,"
"t_object_table TEXT NOT NULL,"
"t_action VARCHAR(1) DEFAULT 'I' CHECK (t_action IN ('I', 'U', 'D')),"
"t_sqlorder TEXT NOT NULL DEFAULT '')")
<< QStringLiteral("CREATE TABLE doctransactionmsg ("
"id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, "
"rd_doctransaction_id INTEGER NOT NULL,"
"t_message TEXT NOT NULL DEFAULT '',"
"t_type VARCHAR(1) DEFAULT 'I' CHECK (t_type IN ('P', 'I', 'W', 'E', 'H')))"); // Positive, Information, Warning, Error, Hidden
IFOKDO(err, executeSqliteOrders(InitialDataModel))
IFOKDO(err, SKGDocument::refreshViewsIndexesAndTriggers())
}
}
// migrate
IFOK(err) {
bool mig = false;
err = migrate(mig);
if (!err && getParameter(QStringLiteral("SKG_DATABASE_TYPE")) != SQLDRIVERNAME && !getPassword().isEmpty()) {
err = sendMessage(i18nc("Information message", "This document is protected by a password but the database is still in SQLite mode.\nDo you know that the SQLCipher mode is more secured because even the temporary file is encrypted?"), SKGDocument::Warning, QStringLiteral("skg://migrate_sqlcipher"));
}
if (!err && getParameter(QStringLiteral("SKG_PASSWORD_LASTUPDATE")) == QLatin1String("") && !getPassword().isEmpty()) {
err = sendMessage(i18nc("Information message", "A security hole has been detected and corrected on this version of the application. We strongly encourage you to change your password."), SKGDocument::Warning, QStringLiteral("skg://file_change_password"));
}
// To authorize manual repair of document in case of error during migration
// the error is not caught if traces are activated
if (err && (SKGTraces::SKGLevelTrace != 0)) {
err = sendMessage(i18nc("Popup message", "The migration failed but the document has been loaded without error because debug mode is activated"), SKGDocument::Warning);
}
if (!err && mig && !iName.isEmpty()) {
err = sendMessage(i18nc("The document has been upgraded to the latest Skrooge version format", "The document has been migrated"), SKGDocument::Positive);
}
}
// Optimization
IFOK(err) {
d->m_lastSavedTransaction = getTransactionToProcess(SKGDocument::UNDO);
executeSqliteOrder(QStringLiteral("ANALYZE"));
}
// Creation undo/redo triggers
IFOKDO(err, createUndoRedoTemporaryTriggers())
IFOK(err) {
QString sqliteQtVersion = getParameter(QStringLiteral("SKG_SQLITE_LAST_VERSION"));
QString sqliteSystemVersion(sqlite3_libversion());
QProcess sqlite3Process;
QString mode;
sqlite3Process.start(QStringLiteral("sqlcipher"), QStringList() << QStringLiteral("-version"));
mode = QStringLiteral("SQLCipher");
if (sqlite3Process.waitForFinished()) {
sqliteSystemVersion = SKGServices::splitCSVLine(sqlite3Process.readAll(), ' ').value(0);
}
SKGTRACEL(5) << "SQLite version of Qt :" << sqliteQtVersion << endl;
SKGTRACEL(5) << "SQLite version of the system:" << sqliteSystemVersion << endl;
if (!sqliteQtVersion.isEmpty() && !sqliteSystemVersion.isEmpty() && sqliteQtVersion != sqliteSystemVersion) {
QString message = i18nc("Error message", "This application can not run correctly because the %3 version of the system (%1) is not aligned with the %4 version embedded in Qt (%2). You should rebuild Qt with the option -system-sqlite.", sqliteSystemVersion, sqliteQtVersion, mode, mode);
err = sendMessage(message, Warning);
SKGTRACE << "WARNING:" << message << endl;
}
}
if (err && !iName.isEmpty()) {
close();
} else {
// Send event
d->m_uniqueIdentifier = QUuid::createUuid().toString();
d->m_password = iPassword;
d->m_password_got = true;
Q_EMIT tableModified(QLatin1String(""), 0, false);
Q_EMIT modified();
}
return err;
}
bool SKGDocument::isReadOnly() const
{
return d->m_modeReadOnly;
}
bool SKGDocument::isFileModified() const
{
// Get last executed transaction
int last = getTransactionToProcess(SKGDocument::UNDO);
// if (nbStepForTransaction.size()) --last;
return (d->m_lastSavedTransaction != last);
}
void SKGDocument::setFileNotModified() const
{
d->m_lastSavedTransaction = getTransactionToProcess(SKGDocument::UNDO);
}
QString SKGDocument::getCurrentFileName() const
{
return d->m_currentFileName;
}
SKGError SKGDocument::save()
{
SKGError err;
SKGTRACEINFUNCRC(5, err)
if (d->m_currentFileName.isEmpty()) {
err = SKGError(ERR_INVALIDARG, i18nc("Error message: Can not save a file if it has no name yet", "Save not authorized because the file name is not yet defined"));
} else {
// save
err = saveAs(d->m_currentFileName, true);
}
return err;
}
SKGError SKGDocument::saveAs(const QString& iName, bool iOverwrite)
{
SKGError err;
SKGTRACEINFUNCRC(5, err)
SKGTRACEL(10) << "Input parameter [name]=[" << iName << ']' << endl;
bool simulateFileSystemFull = !SKGServices::getEnvVariable(QStringLiteral("SKGFILESYSTEMFULL")).isEmpty();
// Check if a transaction is still opened
err = checkExistingTransaction();
IFOK(err) err.setReturnCode(ERR_ABORT).setMessage(i18nc("Cannot save the file while the application is still performing an SQL transaction", "Save is forbidden if a transaction is still opened"));
else {
err = SKGError();
if (getParameter(QStringLiteral("SKG_UNDO_CLEAN_AFTER_SAVE")) == QStringLiteral("Y")) {
err = executeSqliteOrder(QStringLiteral("delete from doctransaction"));
}
// No transaction opened ==> it is ok
// We mark the last transaction as a save point
IFOKDO(err, executeSqliteOrder(QStringLiteral("update doctransaction set t_savestep='Y' where id in (select A.id from doctransaction A where "
"NOT EXISTS(select 1 from doctransaction B where B.i_parent=A.id) "
"and A.t_mode='U')")))
Q_EMIT tableModified(QStringLiteral("doctransaction"), 0, false);
// Optimization
IFOK(err) {
err = executeSqliteOrder(QStringLiteral("VACUUM;"));
IFOK(err) {
// Check if file already exist
if (!iOverwrite && QFile(iName).exists()) {
err.setReturnCode(ERR_INVALIDARG).setMessage(i18nc("There is already a file with the same name", "File '%1' already exist", iName));
} else {
// Get backup file name
bool backupFileMustBeRemoved = false;
QString backupFileName = getBackupFile(iName);
if (backupFileName.isEmpty()) {
backupFileName = iName % ".tmp";
backupFileMustBeRemoved = true;
}
// Create backup file
QFile::remove(backupFileName % '~');
QFile::rename(backupFileName, backupFileName % '~');
if (QFile(iName).exists() && (simulateFileSystemFull || !QFile(iName).copy(backupFileName))) {
this->sendMessage(i18nc("Error message: Could not create a backup file", "Creation of backup file %1 failed", backupFileName), Warning);
}
// Save database
IFOK(err) {
QFile::remove(iName % '~');
QFile::rename(iName, iName % '~');
// To be sure that db is flushed
IFOKDO(err, executeSqliteOrder(QStringLiteral("PRAGMA synchronous = FULL")))
QString pwd = getPassword();
// Copy memory to tmp db
if (!d->m_directAccessDb && !err) {
QFile::remove(d->m_temporaryFile);
auto fileDb = QSqlDatabase::addDatabase(SQLDRIVERNAME, d->m_databaseIdentifier % "_tmp");
fileDb.setDatabaseName(d->m_temporaryFile);
if (!fileDb.open()) {
// Set error message
QSqlError sqlErr = fileDb.lastError();
err = SKGError(SQLLITEERROR + sqlErr.nativeErrorCode().toInt(), sqlErr.text());
} else {
IFOKDO(err, SKGServices::executeSqliteOrder(fileDb, "PRAGMA KEY = '" % SKGServices::stringToSqlString(pwd.isEmpty() ? QStringLiteral("DEFAULTPASSWORD") : pwd) % "'"))
addSqliteAddon(&fileDb);
IFOKDO(err, SKGServices::copySqliteDatabase(fileDb, d->m_currentDatabase, false, pwd.isEmpty() ? QStringLiteral("DEFAULTPASSWORD") : pwd))
}
fileDb.close();
QSqlDatabase::removeDatabase(d->m_databaseIdentifier % "_tmp");
}
// To simulate a file system full
if (!err && simulateFileSystemFull) {
err = SKGError(ERR_WRITEACCESS, i18nc("Error message: writing a file failed", "Write file '%1' failed", iName));
}
// Crypt the file
if (!err) {
bool mode;
err = SKGServices::cryptFile(d->m_temporaryFile, iName, pwd, true, getDocumentHeader(), mode);
}
if (!d->m_directAccessDb && !err) {
QFile(d->m_temporaryFile).remove();
}
// For performances
IFOKDO(err, executeSqliteOrder(QStringLiteral("PRAGMA synchronous = OFF")))
}
if (backupFileMustBeRemoved) {
QFile::remove(backupFileName);
}
IFOK(err) {
// The document is not modified
QString oldtemporaryFile = d->m_temporaryFile;
d->m_currentFileName = iName;
d->m_modeReadOnly = false;
d->m_temporaryFile = getTemporaryFile(d->m_currentFileName);
if (oldtemporaryFile != d->m_temporaryFile) {
QFile(oldtemporaryFile).rename(d->m_temporaryFile);
}
d->m_lastSavedTransaction = getTransactionToProcess(SKGDocument::UNDO);
// Commit save
QFile::remove(backupFileName % '~');
QFile::remove(iName % '~');
} else {
// Rollback file
QFile::remove(backupFileName);
QFile::rename(backupFileName % '~', backupFileName);
QFile::remove(iName);
QFile::rename(iName % '~', iName);
}
}
}
}
Q_EMIT transactionSuccessfullyEnded(0);
}
return err;
}
SKGError SKGDocument::close()
{
SKGTRACEINFUNC(5)
if (getMainDatabase() != nullptr) {
QString conNameMainConnection = getMainDatabase()->connectionName();
const auto& conNames = QSqlDatabase::connectionNames();
for (const auto& conName : conNames) {
if (conName.startsWith(conNameMainConnection % "_")) {
/* NO NEED
{
auto con = QSqlDatabase::database(conName, false);
con.close();
}*/
QSqlDatabase::removeDatabase(conName);
}
}
getMainDatabase()->close();
d->m_currentDatabase = QSqlDatabase(); // To avoid warning on remove
QSqlDatabase::removeDatabase(d->m_databaseIdentifier);
}
if (!d->m_temporaryFile.isEmpty()) {
QFile(d->m_temporaryFile).remove();
d->m_temporaryFile = QLatin1String("");
}
// Emit events ?
bool emitEvent = (d->m_lastSavedTransaction != -1);
// Init fields
d->m_currentFileName = QLatin1String("");
d->m_lastSavedTransaction = 0;
d->m_nbStepForTransaction.clear();
d->m_posStepForTransaction.clear();
d->m_nameForTransaction.clear();
d->m_password.clear();
d->m_password_got = false;
// Send event
if (!d->m_blockEmits && emitEvent && qApp && !qApp->closingDown()) {
Q_EMIT tableModified(QLatin1String(""), 0, false);
Q_EMIT transactionSuccessfullyEnded(0);
Q_EMIT modified();
}
return SKGError();
}
SKGError SKGDocument::dropViewsAndIndexes(const QStringList& iTables) const
{
SKGError err;
// Drop all views
SKGStringListList list;
err = executeSelectSqliteOrder(QStringLiteral("SELECT tbl_name, name, type FROM sqlite_master WHERE type IN ('view','index')"), list);
int nb = list.count();
for (int i = 1; !err && i < nb; ++i) {
QString name = list.at(i).at(1);
QString table = SKGServices::getRealTable(list.at(i).at(0));
QString type = list.at(i).at(2);
if (iTables.contains(table)) {
QString sql = "DROP " % type % " IF EXISTS " % name;
err = this->executeSqliteOrder(sql);
}
}
return err;
}
#include "skgdocument2.cpp"
SKGError SKGDocument::migrate(bool& oMigrationDone)
{
SKGError err;
SKGTRACEINFUNCRC(5, err)
oMigrationDone = false;
{
SKGBEGINPROGRESSTRANSACTION(*this, "#INTERNAL#" % i18nc("Progression step", "Migrate document"), err, 3)
if (getParameter(QStringLiteral("SKG_UNDO_MAX_DEPTH")).isEmpty()) {
IFOKDO(err, setParameter(QStringLiteral("SKG_UNDO_MAX_DEPTH"), SKGServices::intToString(SKG_UNDO_MAX_DEPTH)))
}
if (getParameter(QStringLiteral("SKG_UNDO_CLEAN_AFTER_SAVE")).isEmpty()) {
IFOKDO(err, setParameter(QStringLiteral("SKG_UNDO_CLEAN_AFTER_SAVE"), QStringLiteral("N")))
}
if (!err && getParameter(QStringLiteral("SKG_DATABASE_TYPE")) != (d->m_modeSQLCipher ? SQLDRIVERNAME : QStringLiteral("QSQLITE"))) {
IFOKDO(err, setParameter(QStringLiteral("SKG_DATABASE_TYPE"), d->m_modeSQLCipher ? SQLDRIVERNAME : QStringLiteral("QSQLITE")))
}
QString version = getParameter(QStringLiteral("SKG_DB_VERSION"));
QString initialversion = version;
QString lastversion = QStringLiteral("1.6");
if (!err && version.isEmpty()) {
// First creation
SKGTRACEL(10) << "Migration from 0 to " << lastversion << endl;
// Set new version
version = lastversion;
IFOKDO(err, setParameter(QStringLiteral("SKG_DB_VERSION"), version))
// Set sqlite creation version
SKGStringListList listTmp;
IFOKDO(err, executeSelectSqliteOrder(QStringLiteral("select sqlite_version()"), listTmp))
if (!err && listTmp.count() == 2) {
err = setParameter(QStringLiteral("SKG_SQLITE_CREATION_VERSION"), listTmp.at(1).at(0));
}
oMigrationDone = true;
}
if (!err && SKGServices::stringToDouble(version) > SKGServices::stringToDouble(lastversion)) {
err = SKGError(ERR_ABORT, i18nc("Error message", "Impossible to load a document generated by a more recent version"));
}
{
// Migration steps
if (!err && version == QStringLiteral("0.1")) {
// Migration from version 0.1 to 0.2
SKGTRACEL(10) << "Migration from 0.1 to 0.2" << endl;
// ==================================================================
// Table doctransactionmsg
QStringList sqlOrders;
sqlOrders << QStringLiteral("DROP TABLE IF EXISTS doctransactionmsg")
<< QStringLiteral("CREATE TABLE doctransactionmsg ("
"id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, "
"rd_doctransaction_id INTEGER NOT NULL,"
"t_message TEXT NOT NULL DEFAULT '')");
err = executeSqliteOrders(sqlOrders);
// Set new version
version = QStringLiteral("0.2");
IFOKDO(err, SKGDocument::setParameter(QStringLiteral("SKG_DB_VERSION"), version))
oMigrationDone = true;
}
if (!err && version == QStringLiteral("0.2")) {
// Migration from version 0.2 to 0.3
SKGTRACEL(10) << "Migration from 0.2 to 0.3" << endl;
err = executeSqliteOrder(QStringLiteral("UPDATE node set f_sortorder=id"));
// Set new version
version = QStringLiteral("0.3");
IFOKDO(err, SKGDocument::setParameter(QStringLiteral("SKG_DB_VERSION"), version))
oMigrationDone = true;
}
if (!err && version == QStringLiteral("0.3")) {
// Migration from version 0.3 to 0.4
SKGTRACEL(10) << "Migration from 0.3 to 0.4" << endl;
err = executeSqliteOrder(QStringLiteral("ALTER TABLE node ADD COLUMN t_autostart VARCHAR(1) DEFAULT 'N' CHECK (t_autostart IN ('Y', 'N'))"));
IFOKDO(err, executeSqliteOrder("UPDATE node set t_autostart='Y' where t_name='" % i18nc("Verb, automatically load when the application is started", "autostart") % '\''))
// Set new version
version = QStringLiteral("0.4");
IFOKDO(err, SKGDocument::setParameter(QStringLiteral("SKG_DB_VERSION"), version))
oMigrationDone = true;
}
if (!err && version == QStringLiteral("0.4")) {
// Migration from version 0.4 to 0.5
SKGTRACEL(10) << "Migration from 0.4 to 0.5" << endl;
err = executeSqliteOrder(QStringLiteral("ALTER TABLE doctransactionmsg ADD COLUMN t_popup VARCHAR(1) DEFAULT 'Y' CHECK (t_popup IN ('Y', 'N'))"));
// Set new version
version = QStringLiteral("0.5");
IFOKDO(err, SKGDocument::setParameter(QStringLiteral("SKG_DB_VERSION"), version))
oMigrationDone = true;
}
if (!err && version == QStringLiteral("0.5")) {
// Migration from version 0.5 to 0.6
SKGTRACEL(10) << "Migration from 0.5 to 0.6" << endl;
err = executeSqliteOrder(QStringLiteral("UPDATE node set t_autostart='N' where t_autostart NOT IN ('Y', 'N')"));
// Set new version
version = QStringLiteral("0.6");
IFOKDO(err, SKGDocument::setParameter(QStringLiteral("SKG_DB_VERSION"), version))
oMigrationDone = true;
}
if (!err && version == QStringLiteral("0.6")) {
// Migration from version 0.6 to 0.7
SKGTRACEL(10) << "Migration from 0.6 to 0.7" << endl;
err = executeSqliteOrder(QStringLiteral("ALTER TABLE parameters ADD COLUMN b_blob BLOB"));
// Set new version
version = QStringLiteral("0.7");
IFOKDO(err, SKGDocument::setParameter(QStringLiteral("SKG_DB_VERSION"), version))
oMigrationDone = true;
}
if (!err && version == QStringLiteral("0.7")) {
// Migration from version 0.7 to 0.8
SKGTRACEL(10) << "Migration from 0.7 to 0.8" << endl;
err = executeSqliteOrder(QStringLiteral("UPDATE parameters set t_name='SKG_LANGUAGE' where t_name='SKGLANGUAGE'"));
// Set new version
version = QStringLiteral("0.8");
IFOKDO(err, SKGDocument::setParameter(QStringLiteral("SKG_DB_VERSION"), version))
oMigrationDone = true;
}
if (!err && version == QStringLiteral("0.8")) {
SKGTRACEL(10) << "Migration from 0.8 to 0.9" << endl;
QStringList sql;
sql << QStringLiteral("ALTER TABLE parameters ADD COLUMN i_tmp INTEGER NOT NULL DEFAULT 0")
<< QStringLiteral("UPDATE parameters set i_tmp=0");
err = executeSqliteOrders(sql);
// Set new version
version = QStringLiteral("0.9");
IFOKDO(err, SKGDocument::setParameter(QStringLiteral("SKG_DB_VERSION"), version))
oMigrationDone = true;
}
if (!err && version == QStringLiteral("0.9")) {
SKGTRACEL(10) << "Migration from 0.9 to 1.0" << endl;
err = SKGDocument::setParameter(QStringLiteral("SKG_UNIQUE_ID"), QLatin1String(""));
// Set new version
version = QStringLiteral("1.0");
IFOKDO(err, SKGDocument::setParameter(QStringLiteral("SKG_DB_VERSION"), version))
oMigrationDone = true;
}
if (!err && version == QStringLiteral("1.0")) {
// Migration from version 1.0 to 1.1
SKGTRACEL(10) << "Migration from 1.0 to 1.1" << endl;
err = executeSqliteOrder(QStringLiteral("ALTER TABLE node ADD COLUMN t_icon TEXT DEFAULT ''"));
IFOK(err) {
SKGStringListList result;
err = executeSelectSqliteOrder(QStringLiteral("SELECT id,t_data from node"), result);
int nb = result.count();
for (int i = 1; !err && i < nb; ++i) {
const QStringList& line = result.at(i);
QString icon = QStringLiteral("folder-bookmark");
QStringList data = SKGServices::splitCSVLine(line.at(1));
if (data.count() > 2) {
icon = data.at(2);
}
data.removeAt(2);
err = executeSqliteOrder("UPDATE node set t_icon='" % SKGServices::stringToSqlString(icon) %
"', t_data='" % SKGServices::stringToSqlString(SKGServices::stringsToCsv(data)) % "' where id=" % line.at(0));
}
}
// Set new version
version = QStringLiteral("1.1");
IFOKDO(err, SKGDocument::setParameter(QStringLiteral("SKG_DB_VERSION"), version))
oMigrationDone = true;
}
if (!err && version == QStringLiteral("1.1")) {
// Migration from version 1.1 to 1.2
SKGTRACEL(10) << "Migration from 1.1 to 1.2" << endl;
QStringList sql;
sql << QStringLiteral("ALTER TABLE doctransaction ADD COLUMN t_refreshviews VARCHAR(1) DEFAULT 'Y' CHECK (t_refreshviews IN ('Y', 'N'))")
<< QStringLiteral("UPDATE doctransaction set t_refreshviews='Y'");
err = executeSqliteOrders(sql);
// Set new version
version = QStringLiteral("1.2");
IFOKDO(err, SKGDocument::setParameter(QStringLiteral("SKG_DB_VERSION"), version))
oMigrationDone = true;
}
if (!err && version == QStringLiteral("1.2")) {
// Migration from version 1.2 to 1.3
SKGTRACEL(10) << "Migration from 1.2 to 1.3" << endl;
err = SKGDocument::refreshViewsIndexesAndTriggers();
QStringList sql;
sql << QStringLiteral("DELETE FROM node WHERE (r_node_id IS NULL OR r_node_id='') AND EXISTS (SELECT 1 FROM node n WHERE n.t_name=node.t_name AND r_node_id=0)")
<< QStringLiteral("UPDATE node SET t_name=t_name");
IFOKDO(err, executeSqliteOrders(sql))
// Set new version
version = QStringLiteral("1.3");
IFOKDO(err, SKGDocument::setParameter(QStringLiteral("SKG_DB_VERSION"), version))
oMigrationDone = true;
}
if (!err && version == QStringLiteral("1.3")) {
// Migration from version 1.3 to 1.4
SKGTRACEL(10) << "Migration from 1.3 to 1.4" << endl;
QStringList sql;
sql << "CREATE TABLE node2 ("
"id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,"
"t_name TEXT NOT NULL DEFAULT '' CHECK (t_name NOT LIKE '%" % OBJECTSEPARATOR % "%'),"
"t_fullname TEXT,"
"t_icon TEXT DEFAULT '',"
"f_sortorder FLOAT,"
"t_autostart VARCHAR(1) DEFAULT 'N' CHECK (t_autostart IN ('Y', 'N')),"
"t_data TEXT,"
"rd_node_id INT CONSTRAINT fk_id REFERENCES node(id) ON DELETE CASCADE)"
<< QStringLiteral("INSERT INTO node2 (id, t_name, t_fullname, t_icon, f_sortorder, t_autostart, t_data, rd_node_id) "
"SELECT id, t_name, t_fullname, t_icon, f_sortorder, t_autostart, t_data, r_node_id FROM node")
<< QStringLiteral("DROP TABLE IF EXISTS node")
<< QStringLiteral("ALTER TABLE node2 RENAME TO node");
err = executeSqliteOrders(sql);
// Set new version
version = QStringLiteral("1.4");
IFOKDO(err, SKGDocument::setParameter(QStringLiteral("SKG_DB_VERSION"), version))
oMigrationDone = true;
}
if (!err && version == QStringLiteral("1.4")) {
// Migration from version 1.4 to 1.5
SKGTRACEL(10) << "Migration from 1.4 to 1.5" << endl;
err = SKGDocument::refreshViewsIndexesAndTriggers();
QStringList sql;
sql << QStringLiteral("UPDATE parameters SET t_uuid_parent='advice' WHERE t_uuid_parent='advices'");
IFOKDO(err, executeSqliteOrders(sql))
// Set new version
version = QStringLiteral("1.5");
IFOKDO(err, SKGDocument::setParameter(QStringLiteral("SKG_DB_VERSION"), version))
oMigrationDone = true;
}
if (!err && version == QStringLiteral("1.5")) {
// Migration from version 1.5 to 1.6
SKGTRACEL(10) << "Migration from 1.5 to 1.6" << endl;
err = SKGDocument::refreshViewsIndexesAndTriggers();
QStringList sql;
sql << QStringLiteral("DROP TABLE IF EXISTS doctransactionmsg2")
<< QStringLiteral("CREATE TABLE doctransactionmsg2 ("
"id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, "
"rd_doctransaction_id INTEGER NOT NULL,"
"t_message TEXT NOT NULL DEFAULT '',"
"t_type VARCHAR(1) DEFAULT 'I' CHECK (t_type IN ('P', 'I', 'W', 'E', 'H')))") // Positive, Information, Warning, Error, Hidden
<< QStringLiteral("INSERT INTO doctransactionmsg2 (id, rd_doctransaction_id, t_message, t_type) SELECT id, rd_doctransaction_id, t_message, (CASE WHEN t_popup='Y' THEN 'I' ELSE 'H' END) FROM doctransactionmsg")
<< QStringLiteral("DROP TABLE IF EXISTS doctransactionmsg")
<< QStringLiteral("ALTER TABLE doctransactionmsg2 RENAME TO doctransactionmsg");
IFOKDO(err, executeSqliteOrders(sql))
// Set new version
version = QStringLiteral("1.6");
IFOKDO(err, SKGDocument::setParameter(QStringLiteral("SKG_DB_VERSION"), version))
oMigrationDone = true;
}
}
IFOKDO(err, stepForward(1, i18nc("Progression step", "Refresh views")))
// Set sqlite last version
SKGStringListList listTmp;
IFOKDO(err, executeSelectSqliteOrder(QStringLiteral("select sqlite_version()"), listTmp))
if (!err && listTmp.count() == 2) {
err = setParameter(QStringLiteral("SKG_SQLITE_LAST_VERSION"), listTmp.at(1).at(0));
}
// Refresh views
IFOKDO(err, refreshViewsIndexesAndTriggers())
IFOKDO(err, stepForward(2, i18nc("Progression step", "Update materialized views")))
// Refresh materialized views
if (!err && oMigrationDone) {
err = computeMaterializedViews();
}
IFOKDO(err, stepForward(3))
IFKO(err) err.addError(ERR_FAIL, i18nc("Error message: Could not perform database migration", "Database migration from version %1 to version %2 failed", initialversion, version));
}
return err;
}
SKGError SKGDocument::createUndoRedoTemporaryTriggers() const
{
SKGError err;
SKGTRACEINFUNCRC(10, err)
// Create triggers
QStringList tables;
err = this->getTablesList(tables);
int nbTables = tables.count();
for (int i = 0; !err && i < nbTables; ++i) {
// Get table name
const QString& table = tables.at(i);
// Do we have to treat this table
if (!SKGListNotUndoable.contains("T." % table) && !table.startsWith(QLatin1String("vm_"))) {
// YES
// Get attributes name
QStringList attributes;
err = getAttributesList(table, attributes);
// Build sqlorder for update and insert
QString sqlorderForUpdate2;
QString sqlorderForInsert1;
QString sqlorderForInsert2;
int nbAttributes = attributes.count();
for (int j = 0; !err && j < nbAttributes; ++j) {
// Get attribute
const QString& att = attributes.at(j);
// Do we have to treat this attribute
if (!SKGListNotUndoable.contains("A." % table % '.' % att)) {
// Build for update
if (!sqlorderForUpdate2.isEmpty()) {
sqlorderForUpdate2 += ',';
}
sqlorderForUpdate2 += att % "='||quote(old." % att % ")||'";
// Build for insert part 1
if (!sqlorderForInsert1.isEmpty()) {
sqlorderForInsert1 += ',';
}
sqlorderForInsert1 += att;
// Build for insert part 2
if (!sqlorderForInsert2.isEmpty()) {
sqlorderForInsert2 += ',';
}
sqlorderForInsert2 += "'||quote(old." % att % ")||'";
}
}
// Create specific triggers for the current transaction
QStringList sqlOrders;
// DROP DELETE trigger
sqlOrders << "DROP TRIGGER IF EXISTS UR_" % table % "_IN"
// Create DELETE trigger
<< "CREATE TEMP TRIGGER UR_" % table % "_IN "
"AFTER INSERT ON " % table % " BEGIN "
"INSERT INTO doctransactionitem (rd_doctransaction_id, t_sqlorder,i_object_id,t_object_table,t_action) VALUES(0,'DELETE FROM " % table %
" WHERE id='||new.id,new.id,'" % table % "','D');END"
// DROP UPDATE trigger
<< "DROP TRIGGER IF EXISTS UR_" % table % "_UP"
// Create UPDATE trigger
<< "CREATE TEMP TRIGGER UR_" % table % "_UP "
"AFTER UPDATE ON " % table % " BEGIN "
"INSERT INTO doctransactionitem (rd_doctransaction_id, t_sqlorder,i_object_id,t_object_table,t_action) VALUES(0,'UPDATE " % table %
" SET " % sqlorderForUpdate2 %
" WHERE id='||new.id,new.id,'" % table % "','U');END"
// DROP INSERT trigger
<< "DROP TRIGGER IF EXISTS UR_" % table % "_DE"
// Create INSERT trigger
<< "CREATE TEMP TRIGGER UR_" % table % "_DE "
"AFTER DELETE ON " % table %
" BEGIN "
"INSERT INTO doctransactionitem (rd_doctransaction_id, t_sqlorder,i_object_id,t_object_table,t_action) VALUES(0,'INSERT INTO " % table %
'(' % sqlorderForInsert1 % ") VALUES(" % sqlorderForInsert2 % ")',old.id,'" % table % "','I'); END";
err = executeSqliteOrders(sqlOrders);
}
}
return err;
}
QStringList SKGDocument::getParameters(const QString& iParentUUID, const QString& iWhereClause)
{
SKGTRACEINFUNC(10)
QStringList output;
QString wc = "t_uuid_parent='" % SKGServices::stringToSqlString(iParentUUID) % '\'';
if (!iWhereClause.isEmpty()) {
wc += " AND (" % iWhereClause % ')';
}
this->getDistinctValues(QStringLiteral("parameters"), QStringLiteral("t_name"), wc, output);
return output;
}
QString SKGDocument::getParameter(const QString& iName, const QString& iParentUUID) const
{
SKGTRACEINFUNC(10)
SKGTRACEL(10) << "Input parameter [iName]=[" << iName << ']' << endl;
QString output;
// Get parameter
SKGObjectBase param;
SKGError err = getObject(QStringLiteral("parameters"), "t_name='" % SKGServices::stringToSqlString(iName) %
"' AND t_uuid_parent='" % SKGServices::stringToSqlString(iParentUUID) % '\'', param);
IFOK(err) {
output = param.getAttribute(QStringLiteral("t_value"));
}
return output;
}
QVariant SKGDocument::getParameterBlob(const QString& iName, const QString& iParentUUID) const
{
SKGTRACEINFUNC(10)
SKGTRACEL(10) << "Input parameter [iName]=[" << iName << ']' << endl;
QVariant output;
if (getMainDatabase() != nullptr) {
QString sqlQuery = QStringLiteral("SELECT b_blob FROM parameters WHERE t_name=? AND t_uuid_parent=?");
QSqlQuery query(*getMainDatabase());
query.prepare(sqlQuery);
query.addBindValue(iName);
query.addBindValue(iParentUUID);
if (Q_LIKELY(!query.exec())) {
QSqlError sqlError = query.lastError();
SKGTRACE << "WARNING: " << sqlQuery << endl;
SKGTRACE << " returns :" << sqlError.text() << endl;
} else {
if (query.next()) {
output = query.value(0);
}
}
}
return output;
}
SKGError SKGDocument::setParameter(const QString& iName, const QString& iValue, const QString& iFileName, const QString& iParentUUID, SKGPropertyObject* oObjectCreated) const
{
SKGError err;
SKGTRACEINFUNCRC(10, err)
SKGTRACEL(10) << "Input parameter [iName] =[" << iName << ']' << endl;
SKGTRACEL(10) << "Input parameter [iValue] =[" << iValue << ']' << endl;
SKGTRACEL(10) << "Input parameter [iFileName]=[" << iFileName << ']' << endl;
QVariant blob;
QString value = iValue;
QFile file(iFileName);
if (file.exists()) {
QFileInfo fileInfo(iFileName);
if (fileInfo.isDir()) {
value = "file://" % iFileName;
} else {
// Open file
if (Q_UNLIKELY(!file.open(QIODevice::ReadOnly))) {
err = SKGError(ERR_INVALIDARG, i18nc("Error message: Could not open a file", "Open file '%1' failed", iFileName));
} else {
QByteArray blob_bytes = file.readAll();
if (blob_bytes.isEmpty()) {
err = SKGError(ERR_INVALIDARG, i18nc("Error message: Could not open a file", "Open file '%1' failed", iFileName));
} else {
blob = blob_bytes;
value = fileInfo.fileName();
}
// close file
file.close();
}
}
}
IFOKDO(err, setParameter(iName, value, blob, iParentUUID, oObjectCreated))
return err;
}
SKGError SKGDocument::setParameter(const QString& iName, const QString& iValue, const QVariant& iBlob, const QString& iParentUUID, SKGPropertyObject* oObjectCreated) const
{
SKGError err;
SKGTRACEINFUNCRC(10, err)
SKGTRACEL(10) << "Input parameter [iName] =[" << iName << ']' << endl;
SKGTRACEL(10) << "Input parameter [iValue] =[" << iValue << ']' << endl;
if (getMainDatabase() == nullptr) {
err = SKGError(ERR_POINTER, i18nc("Error message", "No database defined"));
} else {
SKGPropertyObject param(const_cast<SKGDocument*>(this));
IFOKDO(err, param.setName(iName))
IFOKDO(err, param.setValue(iValue))
IFOKDO(err, param.setParentId(iParentUUID))
IFOKDO(err, param.save(true, oObjectCreated != nullptr))
if (!err && !iBlob.isNull()) {
err = param.load();
IFOK(err) {
// Set blob
QString sqlQuery = QStringLiteral("UPDATE parameters SET b_blob=? WHERE id=?");
QSqlQuery query(*getMainDatabase());
query.prepare(sqlQuery);
query.addBindValue(iBlob);
query.addBindValue(param.getID());
if (Q_LIKELY(!query.exec())) {
QSqlError sqlError = query.lastError();
QString msg = sqlQuery % ':' % sqlError.text();
err = SKGError(SQLLITEERROR + sqlError.nativeErrorCode().toInt(), msg);
}
}
}
if (!err && oObjectCreated != nullptr) {
*oObjectCreated = param;
}
}
return err;
}
SKGError SKGDocument::dump(int iMode) const
{
SKGError err;
// dump parameters
SKGTRACE << "=== START DUMP ===" << endl;
if ((iMode & DUMPSQLITE) != 0) {
SKGTRACE << "=== DUMPSQLITE ===" << endl;
err.addError(dumpSelectSqliteOrder(QStringLiteral("SELECT * FROM sqlite_master order by type")));
SKGTRACE << "=== DUMPSQLITE (TEMPORARY) ===" << endl;
err.addError(dumpSelectSqliteOrder(QStringLiteral("SELECT * FROM sqlite_temp_master order by type")));
}
if ((iMode & DUMPPARAMETERS) != 0) {
SKGTRACE << "=== DUMPPARAMETERS ===" << endl;
err.addError(dumpSelectSqliteOrder(QStringLiteral("SELECT * FROM parameters order by id")));
}
if ((iMode & DUMPNODES) != 0) {
SKGTRACE << "=== DUMPNODES ===" << endl;
err.addError(dumpSelectSqliteOrder(QStringLiteral("SELECT * FROM node order by id")));
}
if ((iMode & DUMPTRANSACTIONS) != 0) {
// dump transaction
SKGTRACE << "=== DUMPTRANSACTIONS ===" << endl;
err.addError(dumpSelectSqliteOrder(QStringLiteral("SELECT * FROM doctransaction order by id")));
// dump transaction
SKGTRACE << "=== DUMPTRANSACTIONS (ITEMS) ===" << endl;
err.addError(dumpSelectSqliteOrder(QStringLiteral("SELECT * FROM doctransactionitem order by rd_doctransaction_id, id")));
}
SKGTRACE << "=== END DUMP ===" << endl;
return err;
}
QSqlDatabase* SKGDocument::getMainDatabase() const
{
if (!d->m_currentDatabase.isOpen()) {
return nullptr;
}
return const_cast<QSqlDatabase*>(&d->m_currentDatabase);
}
QSqlDatabase SKGDocument::getThreadDatabase() const
{
if (qApp->thread() != QThread::currentThread()) {
d->m_mutex.lock();
QString pwd = getPassword();
QString dbName = getMainDatabase()->databaseName();
QString conName = getMainDatabase()->connectionName();
QString id = conName % "_" % QString::number((quint64)QThread::currentThread(), 16);
d->m_mutex.unlock();
auto tmpDatabase = QSqlDatabase::database(id);
if (!tmpDatabase.isValid()) {
tmpDatabase = QSqlDatabase::addDatabase(SQLDRIVERNAME, id);
}
if (tmpDatabase.databaseName() != dbName) {
tmpDatabase.setConnectOptions(QStringLiteral("QSQLITE_OPEN_URI"));
tmpDatabase.setDatabaseName(dbName);
if (tmpDatabase.open()) {
addSqliteAddon(&tmpDatabase);
if (d->m_modeSQLCipher) {
SKGServices::executeSqliteOrder(tmpDatabase, "PRAGMA KEY = '" % SKGServices::stringToSqlString(pwd.isEmpty() ? QStringLiteral("DEFAULTPASSWORD") : pwd) % "'");
}
}
}
return tmpDatabase;
}
return d->m_currentDatabase;
}
SKGError SKGDocument::getConsolidatedView(const QString& iTable,
const QString& iAsColumn,
const QString& iAsRow,
const QString& iAttribute,
const QString& iOpAtt,
const QString& iWhereClause,
SKGStringListList& oTable,
const QString& iMissingValue) const
{
SKGError err;
SKGTRACEINFUNCRC(10, err)
SKGTRACEL(10) << "Input parameter [iTable]=[" << iTable << ']' << endl;
SKGTRACEL(10) << "Input parameter [iAsColumn]=[" << iAsColumn << ']' << endl;
SKGTRACEL(10) << "Input parameter [iAsRow]=[" << iAsRow << ']' << endl;
SKGTRACEL(10) << "Input parameter [iAttribute]=[" << iAttribute << ']' << endl;
SKGTRACEL(10) << "Input parameter [iOpAtt]=[" << iOpAtt << ']' << endl;
SKGTRACEL(10) << "Input parameter [iWhereClause]=[" << iWhereClause << ']' << endl;
SKGTRACEL(10) << "Input parameter [iMissingValue]=[" << iMissingValue << ']' << endl;
// Mode
int mode = 0;
if (!iAsColumn.isEmpty()) {
mode += 1;
}
if (!iAsRow.isEmpty()) {
mode += 2;
}
oTable.clear();
oTable.push_back(QStringList());
QStringList titles = oTable.at(0);
if (mode == 3) {
titles.push_back(iAsRow % '/' % iAsColumn);
} else {
if (mode == 1) {
titles.push_back(iAsColumn);
QStringList sums;
sums.push_back(i18nc("Noun, the numerical sum of a list of values", "Sum"));
oTable.push_back(sums);
} else {
if (mode == 2) {
titles.push_back(iAsRow);
titles.push_back(i18nc("Noun, the numerical sum of a list of values", "Sum"));
}
}
}
oTable.removeAt(0);
oTable.insert(0, titles);
// Create sqlorder
QString asColumn = iAsColumn;
if (asColumn.startsWith(QLatin1String("p_"))) {
QString propertyName = asColumn.right(asColumn.length() - 2);
asColumn = "(SELECT t_value FROM parameters WHERE t_uuid_parent=" % iTable % ".id||'-" % SKGServices::getRealTable(iTable) % "' AND t_name='" % propertyName % "')";
}
QString asRow = iAsRow;
if (asRow.startsWith(QLatin1String("p_"))) {
QString propertyName = asRow.right(asRow.length() - 2);
asRow = "(SELECT t_value FROM parameters WHERE t_uuid_parent=" % iTable % ".id||'-" % SKGServices::getRealTable(iTable) % "' AND t_name='" % propertyName % "')";
}
QString att = asColumn;
if (!att.isEmpty() && !asRow.isEmpty()) {
att += ',';
}
att += asRow;
QString sort = asRow;
if (!sort.isEmpty() && !asColumn.isEmpty()) {
sort += ',';
}
sort += asColumn;
if (!att.isEmpty()) {
QString sql = "SELECT " % att % ',' % iOpAtt % '(' % iAttribute % ") FROM " % iTable;
if (!iWhereClause.isEmpty()) {
sql += " WHERE " % iWhereClause;
}
if (!iOpAtt.isEmpty()) {
sql += " GROUP BY " % att;
}
sql += " ORDER BY " % sort;
QHash<QString, int> cols;
QHash<QString, int> rows;
SKGTRACEL(10) << "sqlorder=[" << sql << ']' << endl;
SKGStringListList listTmp;
err = executeSelectSqliteOrder(sql, listTmp);
int nb = listTmp.count();
for (int i = 1; !err && i < nb; ++i) { // Title is ignored
const QStringList& line = listTmp.at(i);
int rowindex = -1;
int colindex = -1;
if (mode >= 2) {
const QString& rowname = line.at(mode == 3 ? 1 : 0);
if (!rows.contains(rowname)) {
QStringList r;
int nbx = oTable.at(0).count();
r.reserve(nbx);
r.push_back(rowname);
for (int j = 1; j < nbx; ++j) {
r.push_back(iMissingValue);
}
oTable.push_back(r);
rowindex = oTable.count() - 1;
rows.insert(rowname, rowindex);
} else {
rowindex = rows[rowname];
}
} else {
rowindex = 1;
}
if (mode == 1 || mode == 3) {
const QString& colname = line.at(0);
if (!cols.contains(colname)) {
// Search better position of this column
colindex = -1;
{
QHashIterator<QString, int> cols_i(cols);
while (cols_i.hasNext()) {
cols_i.next();
if (colname > cols_i.key() && cols_i.value() > colindex) {
colindex = cols_i.value();
}
}
}
if (colindex == -1) {
colindex = 1;
} else {
++colindex;
}
int nbx = oTable.count();
for (int j = 0; j < nbx; ++j) {
if (j == 0) {
oTable[j].insert(colindex, colname);
} else {
oTable[j].insert(colindex, iMissingValue);
}
}
{
QHash<QString, int> tmp;
QHashIterator<QString, int> cols_i(cols);
while (cols_i.hasNext()) {
cols_i.next();
tmp.insert(cols_i.key(), cols_i.value() + (cols_i.value() >= colindex ? 1 : 0));
}
cols = tmp;
}
cols.insert(colname, colindex);
} else {
colindex = cols[colname];
}
} else {
colindex = 1;
}
const QString& sum = line.at(mode == 3 ? 2 : 1);
oTable[rowindex][colindex] = sum;
}
IFSKGTRACEL(10) {
QStringList dump2 = SKGServices::tableToDump(oTable, SKGServices::DUMP_TEXT);
int nbl = dump2.count();
for (int i = 0; i < nbl; ++i) {
SKGTRACE << dump2.at(i) << endl;
}
}
// Correction bug 205466 vvv
// If some months or years are missing, we must add them.
if (asColumn.startsWith(QLatin1String("d_"))) {
for (int c = 1; c < oTable[0].count() - 1; ++c) { // Dynamic size
bool forecast = false;
QString title = oTable.at(0).at(c);
if (title.isEmpty()) {
title = QStringLiteral("0000");
}
if (title.endsWith(QLatin1String("999"))) {
title = title.left(title.count() - 3);
forecast = true;
}
QString nextTitle = oTable.at(0).at(c + 1);
if (nextTitle.endsWith(QLatin1String("999"))) {
nextTitle = nextTitle.left(nextTitle.count() - 3);
forecast = true;
}
QString dateFormat = (asColumn == QStringLiteral("d_date") ? QStringLiteral("yyyy-MM-dd") :
(asColumn == QStringLiteral("d_DATEMONTH") ? QStringLiteral("yyyy-MM") :
(asColumn == QStringLiteral("d_DATEQUARTER") ? QStringLiteral("yyyy-QM") :
(asColumn == QStringLiteral("d_DATESEMESTER") ? QStringLiteral("yyyy-SM") :
(asColumn == QStringLiteral("d_DATEWEEK") ? QStringLiteral("yyyy-WM") : QStringLiteral("yyyy"))))));
QDate nextExpected = QDate::fromString(title, dateFormat);
QString nextExpectedString;
if (asColumn == QStringLiteral("d_DATEWEEK")) {
/* TODO(Stephane MANKOWSKI)
QStringList items=SKGServices::splitCSVLine(oTable.at(0).at(c),'-');
nextExpected=QDate(SKGServices::stringToInt(items.at(0)), 1, 1);
QString w=items.at(1);
w.remove('W');
nextExpected=nextExpected.addDays(7*SKGServices::stringToInt(w));
QString newW=SKGServices::intToString(nextExpected.weekNumber());
if(newW.count()==1) newW='0'+newW;
*/
nextExpectedString = nextTitle;
} else if (asColumn == QStringLiteral("d_DATEMONTH")) {
nextExpected = nextExpected.addMonths(1);
nextExpectedString = nextExpected.toString(dateFormat);
} else if (asColumn == QStringLiteral("d_DATEQUARTER")) {
nextExpected = nextExpected.addMonths(nextExpected.month() * 3 - nextExpected.month()); // convert quarter in month
nextExpected = nextExpected.addMonths(3);
nextExpectedString = nextExpected.toString(QStringLiteral("yyyy-Q")) % (nextExpected.month() <= 3 ? '1' : (nextExpected.month() <= 6 ? '2' : (nextExpected.month() <= 9 ? '3' : '4')));
} else if (asColumn == QStringLiteral("d_DATESEMESTER")) {
nextExpected = nextExpected.addMonths(nextExpected.month() * 6 - nextExpected.month()); // convert semester in month
nextExpected = nextExpected.addMonths(6);
nextExpectedString = nextExpected.toString(QStringLiteral("yyyy-S")) % (nextExpected.month() <= 6 ? '1' : '2');
} else if (asColumn == QStringLiteral("d_DATEYEAR")) {
nextExpected = nextExpected.addYears(1);
nextExpectedString = nextExpected.toString(dateFormat);
} else {
nextExpected = nextExpected.addDays(1);
nextExpectedString = nextExpected.toString(dateFormat);
}
if (title != QStringLiteral("0000") && nextTitle != nextExpectedString && nextTitle != title) {
int colindex = c + 1;
if (forecast) {
nextExpectedString += QStringLiteral("999");
}
int nbx = oTable.count();
oTable[0].insert(colindex, nextExpectedString);
for (int j = 1; j < nbx; ++j) {
oTable[j].insert(colindex, iMissingValue);
}
}
}
}
// Correction bug 205466 ^^^
}
return err;
}
SKGDocument::SKGModelTemplateList SKGDocument::getDisplaySchemas(const QString& iRealTable) const
{
SKGDocument::SKGModelTemplateList listSchema;
// Build schemas
if (iRealTable == QStringLiteral("doctransaction")) {
SKGModelTemplate def;
def.id = QStringLiteral("default");
def.name = i18nc("Noun, the default value of an item", "Default");
def.icon = QStringLiteral("edit-undo");
def.schema = QStringLiteral("t_name;t_value;d_lastmodifdate;t_savestep");
listSchema.push_back(def);
SKGModelTemplate minimum;
minimum.id = QStringLiteral("minimum");
minimum.name = i18nc("Noun, the minimum value of an item", "Minimum");
minimum.icon = QLatin1String("");
minimum.schema = QStringLiteral("t_name;t_value;d_lastmodifdate|N;t_savestep|N");
listSchema.push_back(minimum);
} else if (iRealTable == QStringLiteral("parameters")) {
SKGModelTemplate def;
def.id = QStringLiteral("default");
def.name = i18nc("Noun, the default value of an item", "Default");
def.icon = QStringLiteral("edit-undo");
def.schema = QStringLiteral("t_name;t_value");
listSchema.push_back(def);
} else if (iRealTable == QStringLiteral("node")) {
SKGModelTemplate def;
def.id = QStringLiteral("default");
def.name = i18nc("Noun, the default value of an item", "Default");
def.icon = QStringLiteral("edit-undo");
def.schema = QStringLiteral("t_name");
listSchema.push_back(def);
} else {
SKGModelTemplate def;
def.id = QStringLiteral("default");
def.name = i18nc("Noun, the default value of an item", "Default");
def.icon = QStringLiteral("edit-undo");
def.schema = QLatin1String("");
SKGStringListList lines;
executeSelectSqliteOrder("PRAGMA table_info(" % iRealTable % ");", lines);
for (const auto& line : qAsConst(lines)) {
if (!def.schema.isEmpty()) {
def.schema += ';';
}
def.schema += line[1];
}
listSchema.push_back(def);
}
return listSchema;
}
QString SKGDocument::getDisplay(const QString& iString) const
{
QString output = iString.toLower();
if (output.endsWith(QLatin1String("t_name"))) {
output = i18nc("Noun, the name of an item", "Name");
} else if (output.endsWith(QLatin1String("d_date"))) {
output = i18nc("Noun, the date of an item", "Date");
} else if (output.endsWith(QLatin1String("t_savestep"))) {
output = i18nc("Verb, save a document", "Save");
} else if (output.endsWith(QLatin1String("t_value"))) {
output = i18nc("Noun, the value of an item", "Value");
} else if (output.endsWith(QLatin1String("d_lastmodifdate"))) {
output = i18nc("Noun, date of last modification", "Last modification");
} else if (output.startsWith(QLatin1String("p_"))) {
output = iString;
output = output.right(output.count() - 2);
} else if (output.contains(QStringLiteral(".p_"))) {
output = iString;
output = output.replace(QStringLiteral(".p_"), QStringLiteral("."));
} else {
output = iString;
}
return output;
}
QString SKGDocument::getIconName(const QString& iString) const
{
QString output = iString.toLower();
if (output.startsWith(QLatin1String("p_")) || output.contains(QStringLiteral("p_"))) {
return QStringLiteral("tag");
}
return QLatin1String("");
}
QIcon SKGDocument::getIcon(const QString& iString) const
{
return SKGServices::fromTheme(getIconName(iString));
}
QString SKGDocument::getRealAttribute(const QString& iString) const
{
if (iString == iString.toLower()) {
return iString;
}
return QLatin1String("");
}
SKGServices::AttributeType SKGDocument::getAttributeType(const QString& iAttributeName) const
{
SKGServices::AttributeType output = SKGServices::TEXT;
if (iAttributeName.startsWith(QLatin1String("d_"))) {
output = SKGServices::DATE;
} else if (iAttributeName.startsWith(QLatin1String("i_"))) {
output = SKGServices::INTEGER;
} else if (iAttributeName.startsWith(QLatin1String("rd_")) || iAttributeName.startsWith(QLatin1String("rc_")) || iAttributeName.startsWith(QLatin1String("r_")) || iAttributeName.startsWith(QLatin1String("id_"))) {
output = SKGServices::LINK;
} else if (iAttributeName.startsWith(QLatin1String("f_"))) {
output = SKGServices::FLOAT;
} else if (iAttributeName.startsWith(QLatin1String("b_"))) {
output = SKGServices::BLOB;
} else if (iAttributeName == QStringLiteral("id")) {
output = SKGServices::ID;
} else if (iAttributeName == QStringLiteral("t_savestep") || iAttributeName == QStringLiteral("t_refreshviews")) {
output = SKGServices::BOOL;
}
return output;
}
SKGServices::SKGUnitInfo SKGDocument::getUnit(const QString& iPrefixInCache) const
{
SKGServices::SKGUnitInfo output;
output.Name = getCachedValue(iPrefixInCache % "UnitCache");
if (output.Name.isEmpty()) {
refreshCache(QStringLiteral("unit"));
output.Name = getCachedValue(iPrefixInCache % "UnitCache");
}
output.Symbol = getCachedValue(iPrefixInCache % "UnitSymbolCache");
QString val = getCachedValue(iPrefixInCache % "UnitValueCache");
if (!val.isEmpty()) {
output.Value = SKGServices::stringToDouble(val);
} else {
output.Value = 1;
}
val = getCachedValue(iPrefixInCache % "UnitDecimalCache");
if (!val.isEmpty()) {
output.NbDecimal = SKGServices::stringToInt(val);
} else {
output.NbDecimal = 2;
}
return output;
}
QString SKGDocument::formatMoney(double iValue, const SKGServices::SKGUnitInfo& iUnit, bool iHtml) const
{
QString val = SKGServices::toCurrencyString(iValue / iUnit.Value, iUnit.Symbol, iUnit.NbDecimal);
if (iHtml) {
// Return value
if (iValue < 0) {
// Get std colors
KColorScheme scheme(QPalette::Normal);
return QStringLiteral("<font color=\"") % scheme.foreground(KColorScheme::NegativeText).color().name() % "\">" % SKGServices::stringToHtml(val) % "</font>";
}
return SKGServices::stringToHtml(val);
}
return val;
}
QString SKGDocument::formatPrimaryMoney(double iValue) const
{
return SKGServices::doubleToString(iValue);
}
QString SKGDocument::formatSecondaryMoney(double iValue)const
{
return SKGServices::doubleToString(iValue);
}
QString SKGDocument::formatPercentage(double iValue, bool iInvertColors) const
{
// Get std colors
KColorScheme scheme(QPalette::Normal);
QString negative = scheme.foreground(KColorScheme::NegativeText).color().name();
QString positive = scheme.foreground(KColorScheme::PositiveText).color().name();
// Return value
QString p = SKGServices::toPercentageString(iValue);
if (iValue > 0) {
p = '+' % p;
}
if (p.count() > 10 || std::isnan(iValue) || std::isinf(iValue)) {
p = QChar(8734);
}
return "<font color=\"" %
QString((iValue < 0 && !iInvertColors) || (iValue >= 0 && iInvertColors) ? negative : positive) %
"\">" % SKGServices::stringToHtml(p) %
"</font>";
}
QString SKGDocument::getFileExtension() const
{
return QStringLiteral("skgc");
}
QString SKGDocument::getDocumentHeader() const
{
return QStringLiteral("SKG");
}
void SKGDocument::addValueInCache(const QString& iKey, const QString& iValue) const
{
d->m_cache[iKey] = iValue;
}
void SKGDocument::addSqlResultInCache(const QString& iKey, const SKGStringListList& iValue) const
{
d->m_mutex.lock();
(*d->m_cacheSql)[iKey] = iValue;
d->m_mutex.unlock();
}
QString SKGDocument::getCachedValue(const QString& iKey) const
{
return d->m_cache.value(iKey);
}
SKGStringListList SKGDocument::getCachedSqlResult(const QString& iKey) const
{
return d->m_cacheSql->value(iKey);
}
void SKGDocument::refreshCache(const QString& iTable) const
{
Q_UNUSED(iTable)
}
void SKGDocument::setBackupParameters(const QString& iPrefix, const QString& iSuffix) const
{
d->m_backupPrefix = iPrefix;
d->m_backupSuffix = iSuffix;
}
QString SKGDocument::getCurrentTemporaryFile() const
{
return d->m_temporaryFile;
}
QString SKGDocument::getTemporaryFile(const QString& iFileName, bool iForceReadOnly)
{
QString output;
QFileInfo fi(iFileName);
QFileInfo di(fi.dir().path());
if (iForceReadOnly || !QUrl::fromUserInput(iFileName).isLocalFile() || !di.permission(QFile::WriteUser)) {
output = QDir::tempPath();
} else {
output = fi.absolutePath();
}
return output += "/." % fi.fileName() % ".wrk";
}
QString SKGDocument::getBackupFile(const QString& iFileName) const
{
QString output;
if (!d->m_backupPrefix.isEmpty() || !d->m_backupSuffix.isEmpty()) {
QFileInfo fi(iFileName);
if (d->m_backupSuffix.endsWith(QLatin1String(".skg"))) {
output = d->m_backupPrefix % fi.baseName() % d->m_backupSuffix;
} else {
output = d->m_backupPrefix % fi.fileName() % d->m_backupSuffix;
}
output = output.replace(QStringLiteral("<DATE>"), SKGServices::dateToSqlString(QDateTime::currentDateTime().date()));
output = output.replace(QStringLiteral("<TIME>"), SKGServices::timeToString(QDateTime::currentDateTime()));
if (!QFileInfo(output).isAbsolute()) {
output = fi.absolutePath() % '/' % output;
}
}
return output;
}
SKGError SKGDocument::getObjects(const QString& iTable, const QString& iWhereClause, SKGObjectBase::SKGListSKGObjectBase& oListObject) const
{
SKGError err;
// Initialisation
oListObject.clear();
// Execute sqlorder
SKGStringListList result;
err = executeSelectSqliteOrder(
QString("SELECT * FROM " % iTable %
(!iWhereClause.isEmpty() ? QString(" WHERE " % iWhereClause) : QString())),
result);
// Create output
IFOK(err) {
SKGStringListList::const_iterator itrow = result.constBegin();
QStringList columns = *(itrow);
++itrow;
for (; !err && itrow != result.constEnd(); ++itrow) {
QStringList values = *(itrow);
SKGObjectBase tmp(const_cast<SKGDocument*>(this), iTable);
err = tmp.setAttributes(columns, values);
oListObject.push_back(tmp);
}
}
return err;
}
SKGError SKGDocument::existObjects(const QString& iTable, const QString& iWhereClause, bool& oExist) const
{
SKGError err;
// Initialisation
oExist = false;
// Execute sqlorder
SKGStringListList result;
err = executeSelectSqliteOrder(
"SELECT EXISTS(SELECT 1 FROM " % iTable % " WHERE " %
(!iWhereClause.isEmpty() ? iWhereClause : QStringLiteral("1=1")) % ')',
result);
// Create output
IFOK(err) oExist = (result.at(1).at(0) == QStringLiteral("1"));
return err;
}
SKGError SKGDocument::getNbObjects(const QString& iTable, const QString& iWhereClause, int& oNbObjects) const
{
SKGError err;
// Initialisation
oNbObjects = 0;
// Execute sqlorder
SKGStringListList result;
err = executeSelectSqliteOrder(
QString("SELECT count(1) FROM " % iTable %
(!iWhereClause.isEmpty() ? QString(" WHERE " % iWhereClause) : QString())),
result);
// Create output
IFOK(err) oNbObjects = SKGServices::stringToInt(result.at(1).at(0));
return err;
}
SKGError SKGDocument::getObject(const QString& iTable, const QString& iWhereClause, SKGObjectBase& oObject) const
{
SKGObjectBase::SKGListSKGObjectBase temporaryResult;
oObject.resetID();
SKGError err = SKGDocument::getObjects(iTable, iWhereClause, temporaryResult);
IFOK(err) {
int size = temporaryResult.size();
if (Q_UNLIKELY(size > 1)) {
err = SKGError(ERR_INVALIDARG, i18nc("Error message: We expected only one object in the result, but got more", "More than one object returned in '%1' for '%2'", iTable, iWhereClause));
} else {
if (Q_UNLIKELY(size == 0)) {
err = SKGError(ERR_INVALIDARG, i18nc("Error message: We expected at least one object in the result, but got none", "No object returned in '%1' for '%2'", iTable, iWhereClause));
} else {
oObject = *(temporaryResult.begin());
}
}
}
return err;
}
SKGError SKGDocument::getObject(const QString& iTable, int iId, SKGObjectBase& oObject) const
{
return getObject(iTable, "id=" % SKGServices::intToString(iId), oObject);
}
SKGError SKGDocument::getTablesList(QStringList& oResult) const
{
return getDistinctValues(QStringLiteral("sqlite_master"), QStringLiteral("name"),
QStringLiteral("type='table' AND name NOT LIKE 'sqlite_%'"),
oResult);
}
SKGError SKGDocument::getDistinctValues(const QString& iTable, const QString& iAttribute, const QString& iWhereClause, QStringList& oResult) const
{
SKGError err;
_SKGTRACEINFUNCRC(10, err)
// initialisation
oResult.clear();
// Search
SKGStringListList temporaryResult;
err = executeSelectSqliteOrder(
"SELECT DISTINCT " % iAttribute %
" FROM " % iTable % " WHERE (" %
(!iWhereClause.isEmpty() ? iWhereClause : QStringLiteral("1=1")) %
") ORDER BY " % iAttribute
// Correction bug 202167 vvv
% " COLLATE NOCASE"
// Correction bug 202167 ^^^
, temporaryResult);
IFOK(err) {
SKGStringListList::const_iterator it = temporaryResult.constBegin();
++it; // to forget column name
for (; it != temporaryResult.constEnd(); ++it) {
oResult.push_back(*(it->constBegin()));
}
}
return err;
}
SKGError SKGDocument::getDistinctValues(const QString& iTable, const QString& iAttribute, QStringList& oResult) const
{
return getDistinctValues(iTable, iAttribute,
iAttribute % " IS NOT NULL AND " % iAttribute % "!=''",
oResult);
}
SKGError SKGDocument::executeSqliteOrder(const QString& iSqlOrder, int* iLastId) const
{
SKGError err;
_SKGTRACEINFUNCRC(10, err)
if (getMainDatabase() == nullptr) {
err = SKGError(ERR_POINTER, i18nc("Error message", "No database defined"));
} else {
err = SKGServices::executeSqliteOrder(*getMainDatabase(), iSqlOrder, iLastId);
}
return err;
}
SKGError SKGDocument::executeSqliteOrder(const QString& iSqlOrder) const
{
return SKGDocument::executeSqliteOrder(iSqlOrder, nullptr);
}
SKGError SKGDocument::executeSqliteOrders(const QStringList& iSqlOrders) const
{
SKGError err;
_SKGTRACEINFUNCRC(10, err)
if (getMainDatabase() == nullptr) {
err = SKGError(ERR_POINTER, i18nc("Error message", "No database defined"));
} else {
err = SKGServices::executeSqliteOrders(*getMainDatabase(), iSqlOrders);
}
return err;
}
SKGError SKGDocument::executeSqliteOrder(const QString& iSqlOrder, const QMap< QString, QVariant >& iBind, int* iLastId) const
{
SKGError err;
_SKGTRACEINFUNCRC(10, err)
if (getMainDatabase() == nullptr) {
err = SKGError(ERR_POINTER, i18nc("Error message", "No database defined"));
} else {
err = SKGServices::executeSqliteOrder(*getMainDatabase(), iSqlOrder, iBind, iLastId);
}
return err;
}
SKGError SKGDocument::dumpSelectSqliteOrder(const QString& iSqlOrder, QTextStream* oStream, SKGServices::DumpMode iMode) const
{
SKGError err;
_SKGTRACEINFUNCRC(10, err)
if (getMainDatabase() == nullptr) {
err = SKGError(ERR_POINTER, i18nc("Error message", "No database defined"));
} else {
err = SKGServices::dumpSelectSqliteOrder(*getMainDatabase(), iSqlOrder, oStream, iMode);
}
return err;
}
SKGError SKGDocument::dumpSelectSqliteOrder(const QString& iSqlOrder, QString& oResult, SKGServices::DumpMode iMode) const
{
SKGError err;
_SKGTRACEINFUNCRC(10, err)
if (getMainDatabase() == nullptr) {
err = SKGError(ERR_POINTER, i18nc("Error message", "No database defined"));
} else {
err = SKGServices::dumpSelectSqliteOrder(*getMainDatabase(), iSqlOrder, oResult, iMode);
}
return err;
}
SKGError SKGDocument::dumpSelectSqliteOrder(const QString& iSqlOrder, QStringList& oResult, SKGServices::DumpMode iMode) const
{
SKGError err;
_SKGTRACEINFUNCRC(10, err)
if (getMainDatabase() == nullptr) {
err = SKGError(ERR_POINTER, i18nc("Error message", "No database defined"));
} else {
err = SKGServices::dumpSelectSqliteOrder(*getMainDatabase(), iSqlOrder, oResult, iMode);
}
return err;
}
SKGError SKGDocument::executeSingleSelectSqliteOrder(const QString& iSqlOrder, QString& oResult, bool iUseCache) const
{
SKGError err;
_SKGTRACEINFUNCRC(10, err)
// Is the select in cache?
if (iUseCache && d->m_cache.contains(iSqlOrder)) {
// Yes => get the value
oResult = getCachedValue(iSqlOrder);
SKGTRACEL(10) << "Result retrieved from cache for:" << iSqlOrder << endl;
} else {
// No => Run the select
oResult.clear();
double elapse = SKGServices::getMicroTime();
if (getMainDatabase() == nullptr) {
err = SKGError(ERR_POINTER, i18nc("Error message", "No database defined"));
} else {
err = SKGServices::executeSingleSelectSqliteOrder(*getMainDatabase(), iSqlOrder, oResult);
}
// Is the execution time too long
if (SKGServices::getMicroTime() - elapse > 50) {
// Yes => put the result in cache
addValueInCache(iSqlOrder, oResult);
}
}
return err;
}
SKGError SKGDocument::executeSelectSqliteOrder(const QString& iSqlOrder, SKGStringListList& oResult, bool iUseCache) const
{
SKGError err;
_SKGTRACEINFUNCRC(10, err)
// Is the select in cache?
if (iUseCache && d->m_cacheSql->contains(iSqlOrder)) {
// Yes => get the value
oResult = getCachedSqlResult(iSqlOrder);
SKGTRACEL(10) << "Result retrieved from cache for:" << iSqlOrder << endl;
} else {
// No => Run the select
oResult.clear();
double elapse = SKGServices::getMicroTime();
if (getMainDatabase() == nullptr) {
err = SKGError(ERR_POINTER, i18nc("Error message", "No database defined"));
} else {
err = SKGServices::executeSelectSqliteOrder(*getMainDatabase(), iSqlOrder, oResult);
}
// Is the execution time too long
if (SKGServices::getMicroTime() - elapse > 50) {
// Yes => put the result in cache
addSqlResultInCache(iSqlOrder, oResult);
}
}
return err;
}
void SKGDocument::concurrentExecuteSelectSqliteOrder(const QString& iSqlOrder, const FuncSelect& iFunction, bool iExecuteInMainThread) const
{
// Is the select in cache?
if (d->m_cacheSql->contains(iSqlOrder)) {
// Yes => get the value and call the function
iFunction(getCachedSqlResult(iSqlOrder));
SKGTRACEL(10) << "Result retrieved from cache for:" << iSqlOrder << endl;
} else {
// No => Run the select asynchronously
// Search a watcher free
QFutureWatcher<SKGStringListList>* watcher = nullptr;
if (iExecuteInMainThread) {
for (auto w : qAsConst(d->m_watchers)) {
if (w->isFinished()) {
watcher = w;
break;
}
}
if (watcher == nullptr) {
d->m_watchers.push_back(new QFutureWatcher<SKGStringListList>());
watcher = d->m_watchers.at(d->m_watchers.count() - 1);
}
watcher->disconnect();
connect(watcher, &QFutureWatcherBase::finished, this, [ = ] {
auto w = dynamic_cast< QFutureWatcher<SKGStringListList>* >(sender());
iFunction(w->result());
});
}
// Launch in another thread the select
auto future = QtConcurrent::run([ = ] {
auto tmpDatabase = this->getThreadDatabase();
double elapse = SKGServices::getMicroTime();
SKGStringListList listTmp;
SKGServices::executeSelectSqliteOrder(tmpDatabase, iSqlOrder, listTmp);
// Is the execution time too long
if (SKGServices::getMicroTime() - elapse > 50)
{
// Yes => put the result in cache
addSqlResultInCache(iSqlOrder, listTmp);
}
if (!iExecuteInMainThread)
{
iFunction(listTmp);
}
return listTmp;
});
if (watcher != nullptr) {
watcher->setFuture(future);
}
}
}
void SKGDocument::concurrentExistObjects(const QString& iTable, const QString& iWhereClause, const FuncExist& iFunction, bool iExecuteInMainThread)
{
// Execute sqlorder
concurrentExecuteSelectSqliteOrder("SELECT EXISTS(SELECT 1 FROM " % iTable % " WHERE " % (!iWhereClause.isEmpty() ? iWhereClause : QStringLiteral("1=1")) % ')',
[ = ](const SKGStringListList & iResult) {
iFunction(iResult.count() > 0 && (iResult.at(1).at(0) == QStringLiteral("1")));
}, iExecuteInMainThread);
}
SKGError SKGDocument::getAttributesDescription(const QString& iTable, SKGServices::SKGAttributesList& oResult) const
{
SKGError err;
_SKGTRACEINFUNCRC(10, err)
// initialisation
oResult.clear();
// Search
SKGStringListList temporaryResult;
err = this->executeSelectSqliteOrder("PRAGMA table_info( " % iTable % " );", temporaryResult);
IFOK(err) {
int nblines = temporaryResult.count();
QString realTable = SKGServices::getRealTable(iTable);
for (int i = 1; i < nblines; ++i) { // the first one is ignored because it is the headers
QStringList line = temporaryResult.at(i);
SKGServices::SKGAttributeInfo attribute;
attribute.name = line[1];
QString attname = realTable % '.' % attribute.name;
attribute.display = getDisplay(attname);
if (attribute.display == attname) {
attribute.display = QLatin1String("");
}
attribute.icon = getIcon(attname);
attribute.type = getAttributeType(attribute.name);
attribute.notnull = (line[3] == QStringLiteral("0"));
attribute.defaultvalue = line[4];
oResult.push_back(attribute);
}
}
return err;
}
SKGError SKGDocument::getAttributesList(const QString& iTable, QStringList& oResult) const
{
SKGError err;
_SKGTRACEINFUNCRC(10, err)
oResult.clear();
SKGServices::SKGAttributesList attDesc;
err = getAttributesDescription(iTable, attDesc);
int nblines = attDesc.count();
for (int i = 0; !err && i < nblines; ++i) {
oResult.push_back(attDesc.at(i).name);
}
return err;
}
SKGReport* SKGDocument::getReport() const
{
return new SKGReport(const_cast<SKGDocument*>(this));
}
SKGError SKGDocument::copyToJson(QString& oDocument) const
{
SKGError err;
SKGTRACEINFUNCRC(10, err)
QVariantMap doc;
// Copy the tables
QVariantList list;
QStringList listTables = getMainDatabase()->tables();
int nb = listTables.count();
for (int i = 0; !err && i < nb; ++i) {
const QString& tableName = listTables.at(i);
if (Q_UNLIKELY(!tableName.startsWith(QLatin1String("sqlite_")) && !tableName.startsWith(QLatin1String("vm_")))) {
list.clear();
SKGStringListList listRows;
if (getMainDatabase() == nullptr) {
err = SKGError(ERR_POINTER, i18nc("Error message", "No database defined"));
} else {
err = SKGServices::executeSelectSqliteOrder(*getMainDatabase(), "SELECT * FROM " % tableName, listRows);
}
int nbRows = listRows.count();
if (Q_LIKELY(nbRows)) {
QVariantMap item;
const QStringList& titles = listRows.at(0);
for (int j = 1; !err && j < nbRows; ++j) { // Forget title
const QStringList& values = listRows.at(j);
int nbVals = values.count();
for (int k = 0; k < nbVals; ++k) {
const QString& t = titles.at(k);
SKGServices::AttributeType type = getAttributeType(t);
if (type == SKGServices::ID || type == SKGServices::INTEGER || type == SKGServices::LINK) {
item.insert(t, SKGServices::stringToInt(values.at(k)));
} else if (type == SKGServices::FLOAT) {
item.insert(t, SKGServices::stringToDouble(values.at(k)));
} else if (type == SKGServices::BOOL) {
item.insert(t, values.at(k) == QStringLiteral("Y"));
} else {
item.insert(t, values.at(k));
}
}
list << item;
}
}
doc.insert(tableName, list);
}
}
QJsonDocument serializer = QJsonDocument::fromVariant(doc);
oDocument = serializer.toJson(QJsonDocument::Compact);
return err;
}
Q_DECLARE_METATYPE(sqlite3*) // NOLINT(readability/casting)
Q_DECLARE_OPAQUE_POINTER(sqlite3*) // NOLINT(readability/casting)
diff --git a/skgbasemodeler/skgdocument.h b/skgbasemodeler/skgdocument.h
index a77a1e767..1abee374b 100644
--- a/skgbasemodeler/skgdocument.h
+++ b/skgbasemodeler/skgdocument.h
@@ -1,1029 +1,1029 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGDOCUMENT_H
#define SKGDOCUMENT_H
/** @file
* This file defines classes SKGDocument.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include <qdatetime.h>
#include <qfuturewatcher.h>
#include <qhash.h>
#include <qicon.h>
#include <qsqldatabase.h>
#include <qstringlist.h>
#include <qvariant.h>
#include <functional>
#include "skgbasemodeler_export.h"
#include "skgobjectbase.h"
#include "skgservices.h"
class SKGObjectBase;
class SKGError;
class SKGPropertyObject;
class SKGReport;
class SKGDocumentPrivate;
using FuncSelect = std::function<void (const SKGStringListList&)>; // NOLINT(whitespace/parens)
using FuncExist = std::function<void (bool)>; // NOLINT(whitespace/parens)
using FuncProgress = std::function<int (int, qint64, const QString&, void*)>; // NOLINT(whitespace/parens)
/**
* This class manages skg documents
*/
class SKGBASEMODELER_EXPORT SKGDocument : public QObject
{
Q_OBJECT
Q_CLASSINFO("D-Bus Interface", "org.skg.SKGDocument")
using progressFunction = int (*)(int, qint64, const QString&, void*);
/**
* The unique identifier
*/
Q_PROPERTY(QString uuid READ getUniqueIdentifier NOTIFY modified)
/**
* The current file name
*/
Q_PROPERTY(QString fileName READ getCurrentFileName NOTIFY modified)
/**
* To know if the document is read only
*/
Q_PROPERTY(bool readOnly READ isReadOnly NOTIFY modified)
/**
* To know if the document is modifier
*/
Q_PROPERTY(bool modified READ isFileModified NOTIFY transactionSuccessfullyEnded)
public:
/**
* This enumerate defines a type of modification
*/
enum ModificationType {
U, /**< Update */
I, /**< Insert */
D /**< Delete */
};
/**
* This enumerate defines a type of modification
*/
Q_ENUM(ModificationType)
/**
* This enumerate defines a type of message
*/
enum MessageType {
Positive, /**< Positive */
Information, /**< Information */
Warning, /**< Warning */
Error, /**< Error */
Hidden /**< Hidden */
};
/**
* This enumerate defines a type of message
*/
Q_ENUM(MessageType)
/**
* Describe a modification of an object
*/
struct SKGObjectModification {
QString uuid; /**< The uuid of the object */
int id{}; /**< The id of the object */
QString table; /**< The table of the object */
ModificationType type; /**< The type of modification */
};
/**
* Describe a modification of an object
*/
struct SKGMessage {
QString Text; /**< The text of the message */
MessageType Type; /**< The type of the message */
QString Action; /**< The action associated */
};
/**
* This structure represents a template to display data
*/
struct SKGModelTemplate {
QString id; /**< Identifier of the schema */
QString name; /**< The nls name */
QString icon; /**< The icon */
QString schema; /**< The schema. The format of this string is the following one: attribute name[|visibility Y or N[|size]];attribute name[|visibility Y or N[|size]];... */
};
/**
* A list of SKGModelTemplate ==> SKGModelTemplateList
*/
using SKGModelTemplateList = QVector<SKGModelTemplate>;
/**
* A list of SKGObjectModification ==> SKGObjectModificationList
*/
using SKGObjectModificationList = QVector<SKGObjectModification>;
/**
* A list of SKGMessage ==> SKGObjectModificationList
*/
using SKGMessageList = QVector<SKGMessage>;
/**
* This enumerate defines the direction of the UNDO / REDO mechanism
*/
enum UndoRedoMode {
UNDOLASTSAVE, /**< To do/get an undo=cancel of the last successfully extecuted transactions until last save */
UNDO, /**< To do/get an undo=cancel of the last successfully extecuted transaction */
REDO /**< To do/get a redo=replay the last cancelled transaction */
};
/**
* This enumerate defines the direction of the UNDO / REDO mechanism
*/
Q_ENUM(UndoRedoMode)
/**
* Constructor
*/
explicit SKGDocument();
/**
* Destructor
*/
~SKGDocument() override;
/**
* Set the callback function to follow the progress of the transaction.
* the first parameter is the progress between 0% and 100%.
* the callback must return 0 to continue and !=0 to cancel the transaction.
* @param iProgressFunction the pointer of the function
* @param iData the data for the progress call back
* @return an object managing the error
* @see SKGError
*/
virtual SKGError setProgressCallback(FuncProgress iProgressFunction, void* iData);
/**
* Add a check function at the end of successfully executed transaction.
* If an error is returned, the transaction will be cancelled.
* @param iCheckFunction the pointer of the function
* @return an object managing the error
* @see SKGError
*/
virtual SKGError addEndOfTransactionCheck(SKGError(*iCheckFunction)(SKGDocument*));
/**
* Get unique identifier
* @return the unique identifier
*/
virtual QString getUniqueIdentifier() const;
/**
* Get database identifier
* @return the database identifier
*/
virtual QString getDatabaseIdentifier() const;
/**
* Get message attached to a transaction.
* @param iIdTransaction the identifier of a transaction
* @param oMessages the messages
* @param iAll to get all message (true) or only non hidden messages (false)
* @return an object managing the error
* @see SKGError
*/
virtual SKGError getMessages(int iIdTransaction, SKGMessageList& oMessages, bool iAll = true);
/**
* Remove all message attached to a transaction.
* @param iIdTransaction the identifier of a transaction
* @return an object managing the error
* @see SKGError
*/
virtual SKGError removeMessages(int iIdTransaction);
/**
* Get list of direct modifications done in a transaction
* @param iIdTransaction the identifier of a transaction
* @param oModifications list of modifications
* @return an object managing the error
* @see SKGError
*/
virtual SKGError getModifications(int iIdTransaction, SKGObjectModificationList& oModifications) const;
/**
* Undo or redo the last transaction.
* @param iMode the mode
* @return an object managing the error
* @see SKGError
*/
virtual SKGError undoRedoTransaction(UndoRedoMode iMode = SKGDocument::UNDO);
/**
* Group transactions
* @param iFrom the first id transaction of the group, it will be the master of the group.
* @param iTo the last id transaction of the group.
* @return an object managing the error
* @see SKGError
*/
virtual SKGError groupTransactions(int iFrom, int iTo);
/**
* Return the number of transaction stored including the current one
* @param iMode the mode
* @return the number of transaction
*/
virtual int getNbTransaction(UndoRedoMode iMode = SKGDocument::UNDO) const;
/**
* Return the internal identifier of the transaction
* which must be treated for an undo or a redo
* @param iMode the mode
* @param oName if you want also the name of the transaction
* @param oSaveStep if you want also to know if it is a save step
* @param oDate if you want also the date of the transaction
* @param oRefreshViews if you want also to know if views must be refreshed
* @return the internal identifier of the last transaction
* 0 if no transaction found
*/
virtual int getTransactionToProcess(UndoRedoMode iMode, QString* oName = nullptr, bool* oSaveStep = nullptr, QDateTime* oDate = nullptr, bool* oRefreshViews = nullptr) const;
/**
* Return the identifier of the current transaction
* @return the internal identifier of the current transaction
* 0 if no transaction found
*/
virtual int getCurrentTransaction() const;
/**
* Return the depth of the current transaction
* @return the depth
*/
virtual int getDepthTransaction() const;
/**
* To know if a transaction is opened or not
* @return an object managing the error.
* @see SKGError
*/
virtual SKGError checkExistingTransaction() const;
/**
* Get the current password.
* @return the password
*/
virtual QString getPassword() const;
/**
* To know if the current document has been modified or not.
* @return true: the document has been modified, save is possible/needed.
* false: the document hasn't been modified, save is not needed.
*/
virtual bool isFileModified() const;
/**
* To know if the document is loaded in read only.
* @return true: the document is loaded in read only.
* false: the document is loaded in read write.
*/
virtual bool isReadOnly() const;
/**
* Return the file name of the current document.
* To set it, you must use saveAs.
* @return the file name of the current document.
*/
virtual QString getCurrentFileName() const;
/**
* Set a parameter.
* WARNING: This method must be used in a transaction.
* @see beginTransaction
* @param iName the parameter unique identifier.
* @param iValue the parameter value.
* @param iFileName the file name.
* @param iParentUUID the unique identifier of the object owning this parameter.
* @param oObjectCreated the parameter object created. Can be nullptr
* @return an object managing the error.
* @see SKGError
*/
virtual SKGError setParameter(const QString& iName, const QString& iValue,
const QString& iFileName = QString(),
const QString& iParentUUID = QStringLiteral("document"),
SKGPropertyObject* oObjectCreated = nullptr) const;
/**
* Set a parameter.
* WARNING: This method must be used in a transaction.
* @see beginTransaction
* @param iName the parameter unique identifier.
* @param iValue the parameter value.
* @param iBlob the parameter blob.
* @param iParentUUID the unique identifier of the object owning this parameter.
* @param oObjectCreated the parameter object created. Can be nullptr
* @return an object managing the error.
* @see SKGError
*/
virtual SKGError setParameter(const QString& iName, const QString& iValue,
const QVariant& iBlob,
const QString& iParentUUID = QStringLiteral("document"),
SKGPropertyObject* oObjectCreated = nullptr) const;
/**
* Get the list of parameters
* @param iParentUUID the unique identifier of the object owning parameters.
* @param iWhereClause the additional where clause.
* @return the list of parameters.
*/
virtual QStringList getParameters(const QString& iParentUUID, const QString& iWhereClause = QString());
/**
* Get a parameter value
* @param iName the parameter unique identifier.
* @param iParentUUID the unique identifier of the object owning this parameter.
* @return the value.
*/
virtual QString getParameter(const QString& iName, const QString& iParentUUID = QStringLiteral("document")) const;
/**
* Get a parameter blob
* @param iName the parameter unique identifier.
* @param iParentUUID the unique identifier of the object owning this parameter.
* @return the blob.
*/
virtual QVariant getParameterBlob(const QString& iName, const QString& iParentUUID = QStringLiteral("document")) const;
/**
* Get the database pointer.
* This is the database connection of the main thread
* @return the database pointer.
* MUST NOT BE REMOVED
*/
QSqlDatabase* getMainDatabase() const;
/**
* Get the database pointer.
* This is the database connection of the current thread
* @return the database pointer.
*/
virtual QSqlDatabase getThreadDatabase() const;
/**
* dump the document in the std output.
* It is useful for debug.
* @param iMode the select what you want to dump.
* @code
* document->dump (DUMPPARAMETERS|DUMPTRANSACTIONS);
* @endcode
* @return an object managing the error.
* @see SKGError
*/
virtual SKGError dump(int iMode = DUMPPARAMETERS | DUMPTRANSACTIONS) const;
/**
* Create a consolidated view
* @param iTable Table name
* @param iAsColumn Attribute used as column names
* @param iAsRow Attribute used as lines names
* @param iAttribute Attribute
* @param iOpAtt Operation to apply on @p iAttribute
* @param iWhereClause Where clause
* @param oTable the consolidated view
* @param iMissingValue value to put if no value found
* @return an object managing the error.
* @see SKGError
*/
virtual SKGError getConsolidatedView(const QString& iTable,
const QString& iAsColumn,
const QString& iAsRow,
const QString& iAttribute,
const QString& iOpAtt,
const QString& iWhereClause,
SKGStringListList& oTable,
const QString& iMissingValue = QStringLiteral("0")) const;
/**
* Get the display string for any modeler object (table, attribute)
* @param iString the name of the object (example: v_operation, v_unit.t_name)
* @return the display string
*/
virtual QString getDisplay(const QString& iString) const;
/**
* Get display schemas
* @param iRealTable the real table name
* @return list of schemas
*/
virtual SKGDocument::SKGModelTemplateList getDisplaySchemas(const QString& iRealTable) const;
/**
* Get the icon for attribute
* @param iString the name of the attribute
* @return the icon name
*/
virtual QString getIconName(const QString& iString) const;
/**
* Get the icon for attribute
* @param iString the name of the attribute
* @return the icon
*/
virtual QIcon getIcon(const QString& iString) const;
/**
* Get the real attribute
* @param iString the name of the attribute (something like t_BANK)
* @return the real attribute (something like bank.rd_bank_id.t_name)
*/
virtual QString getRealAttribute(const QString& iString) const;
/**
* Get the attribute type
* @param iAttributeName the name of an attribute
* @return the type
*/
virtual SKGServices::AttributeType getAttributeType(const QString& iAttributeName) const;
/**
* Get unit. WARNING: This value can be not uptodated in a transaction.
* @param iPrefixInCache the prefix of the unit in the cache
* @return unit.
*/
virtual SKGServices::SKGUnitInfo getUnit(const QString& iPrefixInCache) const;
/**
* Get the cached sql result
* @param iKey key
* @return the sql result
*/
virtual SKGStringListList getCachedSqlResult(const QString& iKey) const;
/**
* Get the cached value
* @param iKey key
* @return the value
*/
virtual QString getCachedValue(const QString& iKey) const;
/**
* Get the corresponding backup file
* @param iFileName the file to save
* @return the corresponding backup file
*/
virtual QString getBackupFile(const QString& iFileName) const;
/**
* Get the temporary file for a file
* @param iFileName the file
* @param iForceReadOnly force the read only mode
* @return the temporary file
*/
static QString getTemporaryFile(const QString& iFileName, bool iForceReadOnly = false);
/**
* Get the temporary file for a document
* @return the temporary file
*/
virtual QString getCurrentTemporaryFile() const;
/**
* Get the file extension for this kind of document (must be overwritten)
* @return file extension (like skg)
*/
virtual QString getFileExtension() const;
/**
* Get the header of the file (useful for magic mime type).
* @return document header
*/
virtual QString getDocumentHeader() const;
/**
* Return a number of objects (@p oNbObjects) corresponding to a where clause (@p iWhereClause )
* @param iTable the table where to search
* @param iWhereClause the where clause
* @param oNbObjects the result
* @return an object managing the error
* @see SKGError
*/
virtual SKGError getNbObjects(const QString& iTable, const QString& iWhereClause, int& oNbObjects) const;
/**
* To execute a function when at least one object exist corresponding to a where clause (@p iWhereClause)
* @param iTable the table where to search
* @param iWhereClause the where clause
* @param iFunction the function to call
* @param iExecuteInMainThread to execute the function in the main thread or not
*/
virtual void concurrentExistObjects(const QString& iTable, const QString& iWhereClause, const FuncExist& iFunction, bool iExecuteInMainThread = true);
/**
* To know if at least one object exist corresponding to a where clause (@p iWhereClause)
* @param iTable the table where to search
* @param iWhereClause the where clause
* @param oExist the result
* @return an object managing the error
* @see SKGError
*/
virtual SKGError existObjects(const QString& iTable, const QString& iWhereClause, bool& oExist) const;
/**
* Return a list of objects (@p oListObject) corresponding to a where clause (@p iWhereClause )
* @param iTable the table where to search
* @param iWhereClause the where clause
* @param oListObject the result
* @return an object managing the error
* @see SKGError
*/
virtual SKGError getObjects(const QString& iTable, const QString& iWhereClause, SKGObjectBase::SKGListSKGObjectBase& oListObject) const;
/**
* Return the object (@p oObject) corresponding to a where clause (@p iWhereClause ).
* If more than one objects are returned by the query, then an error is generated
* If 0 object is returned by the query, then an error is generated
* @param iTable the table where to search
* @param iWhereClause the where clause
* @param oObject the result
* @return an object managing the error
* @see SKGError
*/
virtual SKGError getObject(const QString& iTable, const QString& iWhereClause, SKGObjectBase& oObject) const;
/**
* Return the object (@p oObject) corresponding to an id (@p iId ).
* If more than one objects are returned by the query, then an error is generated
* If 0 object is returned by the query, then an error is generated
* @param iTable the table where to search
* @param iId id of the object in @p iTable
* @param oObject the result
* @return an object managing the error
* @see SKGError
*/
virtual SKGError getObject(const QString& iTable, int iId, SKGObjectBase& oObject) const;
/**
* Retrieve list of tables
* @param oResult the output result
* @return An object managing the error
* @see SKGError
*/
virtual SKGError getTablesList(QStringList& oResult) const;
/**
* Retrieve all distinct values of an attribute of a table
* @param iTable the table where to look for
* @param iAttribute the attribute wanted (only one)
* @param iWhereClause a whereclause
* @param oResult the output result
* @return An object managing the error
* @see SKGError
*/
virtual SKGError getDistinctValues(const QString& iTable, const QString& iAttribute, const QString& iWhereClause, QStringList& oResult) const;
/**
* Retrieve all distinct values of an attribute of a table
* @param iTable the table where to look for
* @param iAttribute the attribute wanted (only one)
* @param oResult the output result
* @return An object managing the error
* @see SKGError
*/
virtual SKGError getDistinctValues(const QString& iTable, const QString& iAttribute, QStringList& oResult) const;
/**
* Execute a sqlite orders
* @param iSqlOrders the sql orders
* @return An object managing the error
* @see SKGError
*/
virtual SKGError executeSqliteOrders(const QStringList& iSqlOrders) const;
/**
* Execute a sqlite order
* @param iSqlOrder the sql order
* @param iBind the binded variables and values
* @param iLastId to retrieve the id of the last created object
* @return An object managing the error
* @see SKGError
*/
virtual SKGError executeSqliteOrder(const QString& iSqlOrder, const QMap<QString, QVariant>& iBind, int* iLastId) const;
/**
* Execute a sqlite order
* @param iSqlOrder the sql order
* @param iLastId to retrieve the id of the last created object. Can be nullptr
* @return An object managing the error
* @see SKGError
*/
virtual SKGError executeSqliteOrder(const QString& iSqlOrder, int* iLastId) const;
/**
* Execute a sqlite order
* @param iSqlOrder the sql order
* @return An object managing the error
* @see SKGError
*/
virtual SKGError executeSqliteOrder(const QString& iSqlOrder) const;
/**
* Execute a select sqlite order returning one value and return the result in @p oResult
* @param iSqlOrder the sql order
* @param oResult the result of the select
* @param iUseCache to use the cache
* @return An object managing the error
* @see SKGError
*/
virtual SKGError executeSingleSelectSqliteOrder(const QString& iSqlOrder, QString& oResult, bool iUseCache = true) const;
/**
* Execute a select sqlite order and return the result in @p oResult
* @param iSqlOrder the sql order
* @param oResult the result of the select. It is a vector of vector of QString
* @param iUseCache to use the cache
* @return An object managing the error
* @see SKGError
*/
virtual SKGError executeSelectSqliteOrder(const QString& iSqlOrder, SKGStringListList& oResult, bool iUseCache = true) const;
/**
* Execute a select sqlite order and pass the result to the function @p iFunction. This is done in another thread.
* @param iSqlOrder the sql order
* @param iFunction the function to call
* @param iExecuteInMainThread to execute the function in the main thread or not
*/
virtual void concurrentExecuteSelectSqliteOrder(const QString& iSqlOrder, const FuncSelect& iFunction, bool iExecuteInMainThread = true) const;
/**
* dump a select sqlite order
* @param iSqlOrder the sql order
* @param oStream the output stream, nullptr for std output (cout)
* @param iMode dump mode
* @return An object managing the error
* @see SKGError
*/
virtual SKGError dumpSelectSqliteOrder(const QString& iSqlOrder, QTextStream* oStream = nullptr, SKGServices::DumpMode iMode = SKGServices::DUMP_TEXT) const;
/**
* dump a select sqlite order
* @param iSqlOrder the sql order
* @param oResult the output
* @param iMode dump mode
* @return An object managing the error
* @see SKGError
*/
virtual SKGError dumpSelectSqliteOrder(const QString& iSqlOrder, QString& oResult, SKGServices::DumpMode iMode = SKGServices::DUMP_TEXT) const;
/**
* dump a select sqlite order
* @param iSqlOrder the sql order
* @param oResult the output
* @param iMode dump mode
* @return An object managing the error
* @see SKGError
*/
virtual SKGError dumpSelectSqliteOrder(const QString& iSqlOrder, QStringList& oResult, SKGServices::DumpMode iMode = SKGServices::DUMP_TEXT) const;
/**
* Retrieve description of each attribute of a table
* @param iTable the table where to look for
* @param oResult the output result
* @return An object managing the error
* @see SKGError
*/
virtual SKGError getAttributesDescription(const QString& iTable, SKGServices::SKGAttributesList& oResult) const;
/**
* Retrieve list of attributes
* @param iTable the table where to look for
* @param oResult the output result
* @return An object managing the error
* @see SKGError
*/
virtual SKGError getAttributesList(const QString& iTable, QStringList& oResult) const;
/**
* Get the report
* Do not forget to delete the pointer
* @return the report
*/
virtual SKGReport* getReport() const;
/**
* Copy a document into an JSON document.
* @param oDocument the json document
* @return An object managing the error
* @see SKGError
*/
virtual SKGError copyToJson(QString& oDocument) const;
/**
* Refresh all views and indexes in the database
* @param iForce force the refresh
* @return an object managing the error.
* @see SKGError
*/
virtual SKGError refreshViewsIndexesAndTriggers(bool iForce = false) const;
/**
* Get formated money
* @param iValue value
* @param iUnit unit
* @param iHtml colored output
* @return formated value in red or black
*/
Q_INVOKABLE virtual QString formatMoney(double iValue, const SKGServices::SKGUnitInfo& iUnit, bool iHtml = true) const;
/**
* Get formated money in primary unit
* @param iValue value
* @return formated value in red or black
*/
Q_INVOKABLE virtual QString formatPrimaryMoney(double iValue) const;
/**
* Get formated money in primary unit
* @param iValue value
* @return formated value in red or black
*/
Q_INVOKABLE virtual QString formatSecondaryMoney(double iValue) const;
/**
* Get formated percentage
* @param iValue value
* @param iInvertColors to set positive value in red and negative values in green
* @return formated value in red or black
*/
Q_INVOKABLE virtual QString formatPercentage(double iValue, bool iInvertColors = false) const;
public Q_SLOTS:
/**
* Call the progress callstack.
* @param iPosition the position in the current transaction.
* The value must be between 0 and the value passed to beginTransaction.
* @param iText the text to display. If empty then the name of the last transaction is used.
* @return an object managing the error
* @see SKGError
*/
virtual SKGError stepForward(int iPosition, const QString& iText = QString());
/**
* Start a transaction.
* A transaction is needed to modify the SKGDocument.
* This transaction is also used to manage the undo/redo.
* @see endTransaction
* @param iName the name of the transaction
* @param iNbStep the number of step in this transaction.
* It is used to call the progress callback.
* @param iDate date of the transaction.
* @param iRefreshViews at the end of the transaction, computed views will be recomputed.
* @return an object managing the error
* @see SKGError
*/
virtual SKGError beginTransaction(const QString& iName,
int iNbStep = 0,
const QDateTime& iDate = QDateTime::currentDateTime(),
bool iRefreshViews = true);
/**
* Close the current transaction.
* A transaction is needed to modify the SKGDocument.
* This transaction is also used to manage the undo/redo.
* @see beginTransaction
* @param succeedded : true to indicate that current transaction has been successfully executed
* : false to indicate that current transaction has failed
* @return an object managing the error
* @see SKGError
*/
virtual SKGError endTransaction(bool succeedded);
/**
* Remove all transactions of the history.
* @return an object managing the error
* @see SKGError
*/
virtual SKGError removeAllTransactions();
/**
* Send a message attached to the current transaction.
* @param iMessage the message
* @param iMessageType the message type
* @param iAction the associated action
* @return an object managing the error
* @see SKGError
*/
virtual SKGError sendMessage(const QString& iMessage, SKGDocument::MessageType iMessageType = SKGDocument::Information, const QString& iAction = QString());
/**
* Change the passord of the document.
* WARNING: This method must NOT be used in a transaction.
* @see beginTransaction
* @param iNewPassword the new password
* @return an object managing the error
* @see SKGError
*/
virtual SKGError changePassword(const QString& iNewPassword);
/**
* Change the language of the document.
* @param iLanguage the new language
* @return an object managing the error
* @see SKGError
*/
virtual SKGError setLanguage(const QString& iLanguage);
/**
* Initialize a new document.
* WARNING: This method must NOT be used in a transaction.
* @see endTransaction
* @return an object managing the error
* @see SKGError
*/
virtual SKGError initialize();
/**
* Recover a corrupted file.
* WARNING: This method must NOT be used in a transaction.
* @see endTransaction
* @param iName the file name to load.
* @param iPassword the password of the SKGDocument.
* @param oRecoveredFile the recovered file.
* @return an object managing the error.
* @see SKGError
*/
virtual SKGError recover(const QString& iName, const QString& iPassword, QString& oRecoveredFile);
/**
* Load an existing document.
* WARNING: This method must NOT be used in a transaction.
* @see endTransaction
* @param iName the file name to load.
* @param iPassword the password of the SKGDocument.
* @param iRestoreTmpFile restore the temporary file if existing.
* @param iForceReadOnly force the read only mode.
* @return an object managing the error.
* @see SKGError
*/
virtual SKGError load(const QString& iName, const QString& iPassword = QString(), bool iRestoreTmpFile = false, bool iForceReadOnly = false);
/**
* Set the file not modified.
*/
virtual void setFileNotModified() const;
/**
* save the current SKGDocument.
* WARNING: This method must NOT be used in a transaction.
* @see endTransaction.
* @return an object managing the error.
* @see SKGError
*/
virtual SKGError save();
/**
* save the current SKGDocument.
* WARNING: This method must NOT be used in a transaction.
* @see endTransaction
* @param iName the file name to save.
* @param iOverwrite to authorize the overwrite or not.
* @return an object managing the error.
* @see SKGError
*/
virtual SKGError saveAs(const QString& iName, bool iOverwrite = false);
/**
* close the current SKGDocument.
* @return an object managing the error.
* @see SKGError
*/
SKGError close();
/**
* Add a sql result in the cache. Cache is cleaned after each transaction
* @param iKey the key
* @param iValue the sql result
*/
virtual void addSqlResultInCache(const QString& iKey, const SKGStringListList& iValue) const;
/**
* Add a value in the cache. Cache is cleaned after each transaction
* @param iKey the key
* @param iValue the value
*/
virtual void addValueInCache(const QString& iKey, const QString& iValue) const;
/**
* Refresh the case.
* @param iTable the modified table triggering the cache refresh.
*/
virtual void refreshCache(const QString& iTable) const;
/**
* Set backup parameters.
* The key word \<DATE\> is supported.
* Call setBackupParameters() to avoid backup creation.
* @param iPrefix the prefix for the backup file
* @param iSuffix the suffix for backup file
*/
void setBackupParameters(const QString& iPrefix = QString(), const QString& iSuffix = QString()) const;
Q_SIGNALS:
/**
* This signal is launched by endTransaction on all tables modified when a huge modification occures on the model
* @param iTableName the name of the modified table. iTableName="" if all tables must be refreshed
* @param iIdTransaction the id of the transaction for direct modifications of the table (update of modify objects is enough)
* @param iLightTransaction to if the transaction is light
*or 0 in case of modifications by impact (full table must be refreshed)
*/
void tableModified(const QString& iTableName, int iIdTransaction, bool iLightTransaction);
/**
* This signal is launched by endTransaction when a transaction is successfully ended
* @param iIdTransaction the id of the transaction for direct modifications of the table (update of modify objects is enough)
*/
void transactionSuccessfullyEnded(int iIdTransaction);
/**
* This signal is launched when the status of the document is changed (read only, modified)
*/
void modified();
protected:
/**
* Drop views and indexes attached to a list of tables
* @param iTables the list of tables.
* @return an object managing the error.
* @see SKGError
*/
virtual SKGError dropViewsAndIndexes(const QStringList& iTables) const;
/**
* Migrate the current SKGDocument to the latest version of the data model.
* WARNING: This method must be used in a transaction.
* @see beginTransaction
* @param oMigrationDone to know if a migration has been done or not.
* @return an object managing the error.
* @see SKGError
*/
virtual SKGError migrate(bool& oMigrationDone);
/**
* Create dynamic triggers for "undoable" tables.
* @return an object managing the error.
* @see SKGError
*/
virtual SKGError createUndoRedoTemporaryTriggers() const;
/**
* This list must contain a list of object
* where the undo / redo is NOT applicable.
* For a full table, the syntax is: T.nameofthetable
* For an attribute, the syntax is: A.nameofthetable.nameoftheattribute
*/
QStringList SKGListNotUndoable;
/**
* Get impacted views if one object of @p iTable is modifier.
* @param iTable name of a table
* @return impacted views
*/
virtual QStringList getImpactedViews(const QString& iTable) const;
/**
* Compute all materialized views.
* @param iTable Compute only materialized views linked to this table. If empty then compute all materialized views
* @return an object managing the error.
* @see SKGError
*/
virtual SKGError computeMaterializedViews(const QString& iTable = QString()) const;
private:
Q_DISABLE_COPY(SKGDocument)
SKGMessageList m_unTransactionnalMessages;
SKGDocumentPrivate* d;
};
/**
* Declare the class
*/
Q_DECLARE_TYPEINFO(SKGDocument, Q_MOVABLE_TYPE);
#endif
diff --git a/skgbasemodeler/skgdocument2.cpp b/skgbasemodeler/skgdocument2.cpp
index 806be1dd9..be62741e2 100644
--- a/skgbasemodeler/skgdocument2.cpp
+++ b/skgbasemodeler/skgdocument2.cpp
@@ -1,142 +1,142 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file implements classes SKGDocument.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgdocument.h"
SKGError SKGDocument::refreshViewsIndexesAndTriggers(bool iForce) const
{
Q_UNUSED(iForce)
SKGError err;
SKGTRACEINFUNCRC(5, err)
/**
* This constant is used to initialized the data model (trigger creation)
*/
QString rd_node_id;
QStringList attsOfNodes;
err = getAttributesList(QStringLiteral("node"), attsOfNodes);
rd_node_id = (attsOfNodes.contains(QStringLiteral("rd_node_id")) ? QStringLiteral("rd_node_id") : QStringLiteral("r_node_id"));
QStringList InitialDataModelTrigger;
InitialDataModelTrigger
<< DELETECASCADEPARAMETER("parameters")
<< DELETECASCADEPARAMETER("node")
// Compute fullname
<< QStringLiteral("DROP TRIGGER IF EXISTS cpt_node_fullname3")
/*<< "CREATE TRIGGER cpt_node_fullname1 " // This trigger must be the first
"AFTER UPDATE OF t_fullname ON node BEGIN "
"UPDATE node SET t_name=t_name WHERE rd_node_id=new.id;"
"END"*/
<< QStringLiteral("DROP TRIGGER IF EXISTS cpt_node_fullname1")
<< "CREATE TRIGGER cpt_node_fullname1 "
"AFTER INSERT ON node BEGIN "
"UPDATE node SET t_fullname="
"CASE WHEN new.rd_node_id IS NULL OR new." % rd_node_id % "='' OR new." % rd_node_id % "=0 THEN new.t_name ELSE (SELECT c.t_fullname from node c where c.id=new." % rd_node_id % ")||'" % OBJECTSEPARATOR % "'||new.t_name END "
"WHERE id=new.id;"
"END"
<< QStringLiteral("DROP TRIGGER IF EXISTS cpt_node_fullname2")
<< "CREATE TRIGGER cpt_node_fullname2 "
"AFTER UPDATE OF t_name, " % rd_node_id % " ON node BEGIN "
"UPDATE node SET t_fullname="
"CASE WHEN new." % rd_node_id % " IS NULL OR new." % rd_node_id % "='' OR new." % rd_node_id % "=0 THEN new.t_name ELSE (SELECT c.t_fullname from node c where c.id=new." % rd_node_id % ")||'" % OBJECTSEPARATOR % "'||new.t_name END "
"WHERE id=new.id;"
"UPDATE node SET t_name=t_name WHERE " % rd_node_id % "=new.id;"
"END"
<< QStringLiteral("DROP TRIGGER IF EXISTS fkdc_node_parent_id_node_id");
/**
* This constant is used to initialized the data model (index creation)
*/
QStringList InitialDataModelIndex;
InitialDataModelIndex << QStringLiteral("CREATE UNIQUE INDEX uidx_parameters_uuid_parent_name ON parameters (t_uuid_parent, t_name)")
<< "CREATE UNIQUE INDEX uidx_node_parent_id_name ON node(t_name," % rd_node_id % ")"
<< QStringLiteral("CREATE INDEX idx_node_fullname ON node(t_fullname)")
<< QStringLiteral("CREATE INDEX idx_doctransaction_parent ON doctransaction (i_parent)")
<< QStringLiteral("CREATE INDEX idx_doctransactionitem_i_object_id ON doctransactionitem (i_object_id)")
<< QStringLiteral("CREATE INDEX idx_doctransactionitem_t_object_table ON doctransactionitem (t_object_table)")
<< QStringLiteral("CREATE INDEX idx_doctransactionitem_t_action ON doctransactionitem (t_action)")
<< QStringLiteral("CREATE INDEX idx_doctransactionitem_rd_doctransaction_id ON doctransactionitem (rd_doctransaction_id)")
<< QStringLiteral("CREATE INDEX idx_doctransactionitem_optimization ON doctransactionitem (rd_doctransaction_id, i_object_id, t_object_table, t_action, t_sqlorder, id)");
/**
* This constant is used to initialized the data model (view creation)
*/
QStringList InitialDataModelView;
InitialDataModelView << QStringLiteral("CREATE VIEW v_node AS SELECT * from node")
<< QStringLiteral("CREATE VIEW v_node_displayname AS SELECT *, t_fullname AS t_displayname from node")
<< QStringLiteral("CREATE VIEW v_parameters_displayname AS SELECT *, t_name AS t_displayname from parameters")
<< QStringLiteral("CREATE VIEW v_doctransaction_displayname AS SELECT *, t_name AS t_displayname from doctransaction");
IFOKDO(err, dropViewsAndIndexes(QStringList() << QStringLiteral("node") << QStringLiteral("parameters") << QStringLiteral("doctransactionitem") << QStringLiteral("doctransaction")))
IFOKDO(err, executeSqliteOrders(InitialDataModelIndex))
IFOKDO(err, executeSqliteOrders(InitialDataModelView))
IFOKDO(err, executeSqliteOrders(InitialDataModelTrigger))
IFOK(err) {
// Refresh dynamic triggers
QRegExp rx_rd(QStringLiteral("rd_([^_]+)_([^_]+).*"));
QRegExp rx_rc(QStringLiteral("rc_([^_]+)_([^_]+).*"));
QRegExp rx_r(QStringLiteral("r_([^_]+)_([^_]+).*"));
QStringList dbTables;
err = this->getDistinctValues(QStringLiteral("sqlite_master"), QStringLiteral("name"), QStringLiteral("type='table'"), dbTables);
int nb = dbTables.count();
for (int i = 0; !err && i < nb; ++i) {
const QString& table = dbTables.at(i);
SKGStringListList attributes;
err = executeSelectSqliteOrder("PRAGMA table_info(" % table % ");", attributes);
int nb2 = attributes.count();
for (int j = 1; !err && j < nb2; ++j) { // Header is ignored
QString att = attributes.at(j).at(1);
if (rx_rd.indexIn(att) != -1) {
// Get parameters
QString tab2 = rx_rd.cap(1);
QString att2 = rx_rd.cap(2);
QStringList sqlOrders;
sqlOrders << FOREIGNCONSTRAINTCASCADE(tab2, att2, table, att);
err = executeSqliteOrders(sqlOrders);
} else if (rx_rc.indexIn(att) != -1) {
// Get parameters
QString tab2 = rx_rc.cap(1);
QString att2 = rx_rc.cap(2);
QStringList sqlOrders;
sqlOrders << FOREIGNCONSTRAINT(tab2, att2, table, att);
err = executeSqliteOrders(sqlOrders);
} else if (rx_r.indexIn(att) != -1) {
// Get parameters
QString tab2 = rx_r.cap(1);
QString att2 = rx_r.cap(2);
QStringList sqlOrders;
sqlOrders << FOREIGNCONSTRAINTUPDATE(tab2, att2, table, att);
err = executeSqliteOrders(sqlOrders);
// The following sql order error is not caught because this repair order is not mandatory
executeSqliteOrder("UPDATE " % table % " SET " % att % "=0 WHERE " % att % "!=0 AND " % att % " NOT IN (SELECT DISTINCT(" % att2 % ") FROM " % tab2 % ')');
}
}
}
}
IFOKDO(err, executeSqliteOrder(QStringLiteral("ANALYZE")))
return err;
}
diff --git a/skgbasemodeler/skgdocumentprivate.cpp b/skgbasemodeler/skgdocumentprivate.cpp
index 3ceaa6407..5fa25f09a 100644
--- a/skgbasemodeler/skgdocumentprivate.cpp
+++ b/skgbasemodeler/skgdocumentprivate.cpp
@@ -1,44 +1,44 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file implements classes SKGDocumentPrivate.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgdocumentprivate.h"
/**
* Last error.
*/
SKGError SKGDocumentPrivate::m_lastCallbackError;
/**
* Unique identifier.
*/
int SKGDocumentPrivate::m_databaseUniqueIdentifier = 0;
SKGDocumentPrivate::SKGDocumentPrivate()
: m_currentFileName(QLatin1String(""))
{
m_cacheSql = new QHash<QString, SKGStringListList>();
}
SKGDocumentPrivate::~SKGDocumentPrivate()
{
delete m_cacheSql;
m_cacheSql = nullptr;
}
diff --git a/skgbasemodeler/skgdocumentprivate.h b/skgbasemodeler/skgdocumentprivate.h
index 57a792a39..90b8c9392 100644
--- a/skgbasemodeler/skgdocumentprivate.h
+++ b/skgbasemodeler/skgdocumentprivate.h
@@ -1,93 +1,93 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGDOCUMENTPRIVATE_H
#define SKGDOCUMENTPRIVATE_H
/** @file
* This file defines classes SKGDocumentPrivate.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include <qfuturewatcher.h>
#include <qhash.h>
#include <qsqldatabase.h>
#include <qstringlist.h>
#include <functional>
#include "skgdefine.h"
#include "skgerror.h"
#include "skgservices.h"
using FuncProgress = std::function<int(int, qint64, const QString&, void*)>;
using checksFunction = SKGError(*)(SKGDocument*);
/**
* This class manages skg documents
*/
class SKGDocumentPrivate
{
public:
/**
* Constructor
*/
explicit SKGDocumentPrivate();
/**
* Destructor
*/
virtual ~SKGDocumentPrivate();
static SKGError m_lastCallbackError;
static int m_databaseUniqueIdentifier;
int m_lastSavedTransaction{0};
FuncProgress m_progressFunction{nullptr};
QList<checksFunction> m_checkFunctions;
void* m_progressData{nullptr};
QString m_currentFileName;
QString m_databaseIdentifier;
QSqlDatabase m_currentDatabase;
SKGIntList m_nbStepForTransaction;
SKGIntList m_posStepForTransaction;
QStringList m_nameForTransaction;
int m_inundoRedoTransaction{0};
int m_currentTransaction{0};
qint64 m_timeBeginTransaction{0};
QString m_temporaryFile;
QString m_uniqueIdentifier;
// SKGMessageList m_unTransactionnalMessages;
QMap<QString, QStringList> m_ImpactedViews;
QMap<QString, QStringList> m_MaterializedViews;
QHash<QString, QString> m_cache;
QHash<QString, SKGStringListList>* m_cacheSql;
bool m_inProgress{false};
QString m_backupPrefix;
QString m_backupSuffix;
bool m_directAccessDb{false};
bool m_modeReadOnly{false};
bool m_modeSQLCipher{false};
QList<QFutureWatcher<SKGStringListList>*> m_watchers;
bool m_blockEmits{false};
QMutex m_mutex;
QString m_password;
bool m_password_got{false};
};
#endif
diff --git a/skgbasemodeler/skgerror.cpp b/skgbasemodeler/skgerror.cpp
index 12a889f3d..aba8cc623 100644
--- a/skgbasemodeler/skgerror.cpp
+++ b/skgbasemodeler/skgerror.cpp
@@ -1,202 +1,202 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file implements classes SKGError.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgerror.h"
SKGError::SKGError()
: QObject(), m_message(QLatin1String(""))
{}
SKGError::SKGError(int iRc, QString iMessage, QString iAction)
: QObject(), m_rc(iRc), m_message(std::move(iMessage)), m_action(std::move(iAction)), m_previousError(nullptr)
{}
SKGError::SKGError(const SKGError& iError)
: QObject()
{
m_rc = iError.m_rc;
m_message = iError.m_message;
m_action = iError.m_action;
if (Q_UNLIKELY(iError.m_previousError != nullptr)) {
m_previousError = new SKGError(*iError.m_previousError);
} else {
m_previousError = nullptr;
}
}
SKGError::SKGError(SKGError&& iError) noexcept
: QObject()
{
m_rc = iError.m_rc;
m_message = iError.m_message;
m_action = iError.m_action;
m_previousError = iError.m_previousError;
iError.m_previousError = nullptr;
}
SKGError::~SKGError()
{
delete m_previousError;
m_previousError = nullptr;
}
SKGError& SKGError::operator= (const SKGError& iError)
{
if (Q_LIKELY(&iError != this)) {
delete m_previousError;
m_previousError = nullptr;
m_rc = iError.m_rc;
m_message = iError.m_message;
m_action = iError.m_action;
if (Q_UNLIKELY(iError.m_previousError != nullptr)) {
m_previousError = new SKGError(*iError.m_previousError);
}
}
Q_EMIT modified();
return *this;
}
bool SKGError::operator!() const
{
return isSucceeded();
}
SKGError::operator bool() const
{
return isFailed();
}
bool SKGError::isFailed() const
{
return (m_rc > 0);
}
bool SKGError::isSucceeded() const
{
return (m_rc <= 0);
}
bool SKGError::isWarning() const
{
return (m_rc < 0);
}
int SKGError::getReturnCode() const
{
return m_rc;
}
SKGError& SKGError::setReturnCode(int iReturnCode)
{
if (m_rc != iReturnCode) {
m_rc = iReturnCode;
Q_EMIT modified();
}
return *this;
}
SKGError& SKGError::setMessage(const QString& iMessage)
{
if (m_message != iMessage) {
m_message = iMessage;
Q_EMIT modified();
}
return *this;
}
QString SKGError::getMessage() const
{
return m_message;
}
QString SKGError::getFullMessage() const
{
QString output('[');
output += (m_rc == 0 ? QStringLiteral("SUC") : (m_rc > 0 ? QStringLiteral("ERR") : QStringLiteral("WAR")));
output += '-';
QString tmp;
tmp.setNum(m_rc);
output += tmp;
output += ']';
if (Q_LIKELY(!m_message.isEmpty())) {
output += ": " % m_message;
}
return output;
}
QString SKGError::getFullMessageWithHistorical() const
{
QString output = getFullMessage();
if (Q_UNLIKELY(m_previousError)) {
output += '\n' % m_previousError->getFullMessageWithHistorical();
}
return output;
}
int SKGError::getHistoricalSize() const
{
int output = 0;
if (Q_UNLIKELY(m_previousError)) {
output += 1 + m_previousError->getHistoricalSize();
}
return output;
}
SKGError& SKGError::setAction(const QString& iAction)
{
if (m_action != iAction) {
m_action = iAction;
Q_EMIT modified();
}
return *this;
}
QString SKGError::getAction() const
{
return m_action;
}
SKGError& SKGError::addError(int iRc, const QString& iMessage, const QString& iAction)
{
auto pe = new SKGError(*this);
setReturnCode(iRc);
setMessage(iMessage);
setAction(iAction);
delete m_previousError;
m_previousError = pe;
Q_EMIT modified();
return *this;
}
SKGError& SKGError::addError(const SKGError& iError)
{
return addError(iError.getReturnCode(), iError.getMessage());
}
SKGError* SKGError::getPreviousError() const
{
return m_previousError;
}
diff --git a/skgbasemodeler/skgerror.h b/skgbasemodeler/skgerror.h
index ff12e8093..94df17d14 100644
--- a/skgbasemodeler/skgerror.h
+++ b/skgbasemodeler/skgerror.h
@@ -1,260 +1,260 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGERROR_H
#define SKGERROR_H
/** @file
* This file defines classes SKGError and macros.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include <qobject.h>
#include <qstring.h>
#include "skgbasemodeler_export.h"
#include "skgdefine.h"
/**
* To facilitate the error management
*/
#define IFKO(ERROR) \
if (Q_UNLIKELY(ERROR))
/**
* To facilitate the error management
*/
#define IFOK(ERROR) \
if (Q_LIKELY(!(ERROR)))
/**
* To facilitate the error management
*/
#define IFOKDO(ERROR, ACTION) \
IFOK(ERROR) {(ERROR) = ACTION;}
/**
* This class manages errors
*/
class SKGBASEMODELER_EXPORT SKGError final : public QObject
{
Q_OBJECT
/**
* Return code of the error
*/
Q_PROPERTY(int returnCode READ getReturnCode WRITE setReturnCode NOTIFY modified)
/**
* Message of the error
*/
Q_PROPERTY(QString message READ getMessage WRITE setMessage NOTIFY modified)
/**
* Action of the error
*/
Q_PROPERTY(QString action READ getAction WRITE setAction NOTIFY modified)
/**
* To know if it is a success of the error
*/
Q_PROPERTY(bool succeeded READ isSucceeded NOTIFY modified)
/**
* To know if it is a failure of the error
*/
Q_PROPERTY(bool failed READ isFailed NOTIFY modified)
public:
/**
* Constructor
*/
explicit SKGError();
/**
* Copy constructor
* @param iError the error to copy
*/
SKGError(const SKGError& iError);
/**
* Move constructor
* @param iError the error to copy
*/
SKGError(SKGError&& iError) noexcept;
/**
* Constructor
* @param iRc the error code
* @param iMessage the error message
* @param iAction the error action. This is normally a recovery action (example: skg://file_save, http://google.com, ...)
*/
SKGError(int iRc, QString iMessage, QString iAction = QString());
/**
* Destructor
*/
~SKGError() override;
/**
* Operator affectation
* @param iError the error to copy
*/
SKGError& operator= (const SKGError& iError);
/**
* To know if this is an error or not. Equivalent to @see isSucceeded
* @return true or false
*/
bool operator!() const;
/**
* To know if this is an error or not. Equivalent to @see isFailed
* @return true or false
*/
operator bool() const;
/**
* To know if it is an error or not
* @return true: It is an error
* false: It is not an error (it could be a warning)
*/
bool isFailed() const;
/**
* To know if it is an error or not
* @return true: It is not an error (it could be a warning)
* false: It is an error
*/
bool isSucceeded() const;
/**
* To know if it is a warning or not
* @return true: It is a warning
* false: It is not a warning
*/
bool isWarning() const;
/**
* Return the return code associated to this error
* @return 0 : It is not an error (SUCCEEDED)
* <0: It is just a warning (SUCCEEDED)
* >0: It is not error (FAILED)
*/
int getReturnCode() const;
/**
* Return the message associated to this error
* @return the message
*/
QString getMessage() const;
/**
* Return the full message associated to this error
* @return the full message
*/
QString getFullMessage() const;
/**
* Return the full message with historical associated to this error
* @return the full message
*/
QString getFullMessageWithHistorical() const;
/**
* Return the size of the historical associated to this error
* @return the size
*/
int getHistoricalSize() const;
/**
* Return the action associated to this error
* @return the action
*/
QString getAction() const;
/**
* Return previous error associated to this SKGError in the historical
* @return previous error (null if not exist)
* WARNING: this pointer mustn't be deleted
*/
SKGError* getPreviousError() const;
public Q_SLOTS:
/**
* Set the return code associated to this error
* @param iReturnCode the return code
* 0 : It is not an error (SUCCEEDED)
* <0: It is just a warning (SUCCEEDED)
* >0: It is not error (FAILED)
* @return itself to facilitate usage
*/
SKGError& setReturnCode(int iReturnCode);
/**
* Set the message associated to this error
* @param iMessage the message
* @return itself to facilitate usage
*/
SKGError& setMessage(const QString& iMessage);
/**
* Set the action associated to this error
* @param iAction the action
* @return itself to facilitate usage
*/
SKGError& setAction(const QString& iAction);
/**
* Add a new historical message to the current error.
* @param iRc the error code
* @param iMessage the error message
* @param iAction the error action. This is normally a recovery action (example: skg://file_save, http://google.com, ...)
* @return itself to facilitate usage
*/
SKGError& addError(int iRc, const QString& iMessage, const QString& iAction = QString());
/**
* Add a new historical message to the current error.
* @param iError the error
* @return itself to facilitate usage
*/
SKGError& addError(const SKGError& iError);
Q_SIGNALS:
/**
* This signal is launched when the error is modified
*/
void modified();
private:
/**
* the return code of the error
* 0 : It is not an error (SUCCEEDED)
* <0: It is just a warning (SUCCEEDED)
* >0: It is not error (FAILED)
*/
int m_rc{0};
/**
* the message of the error
*/
QString m_message;
/**
* the action of the error
*/
QString m_action;
/**
* the previous error on this branch
*/
SKGError* m_previousError{nullptr};
};
#endif // SKGERROR_H
diff --git a/skgbasemodeler/skgnamedobject.cpp b/skgbasemodeler/skgnamedobject.cpp
index cb23a56e7..68873beb5 100644
--- a/skgbasemodeler/skgnamedobject.cpp
+++ b/skgbasemodeler/skgnamedobject.cpp
@@ -1,72 +1,72 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file defines classes SKGNamedObject.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgnamedobject.h"
#include "skgdocument.h"
SKGNamedObject::SKGNamedObject() : SKGNamedObject(nullptr)
{}
SKGNamedObject::SKGNamedObject(SKGDocument* iDocument, const QString& iTable, int iID) : SKGObjectBase(iDocument, iTable, iID)
{}
SKGNamedObject::SKGNamedObject(const SKGNamedObject& iObject) = default;
SKGNamedObject::SKGNamedObject(const SKGObjectBase& iObject) : SKGObjectBase(iObject)
{}
SKGNamedObject& SKGNamedObject::operator= (const SKGObjectBase& iObject)
{
copyFrom(iObject);
return *this;
}
SKGNamedObject::~SKGNamedObject()
= default;
SKGError SKGNamedObject::setName(const QString& iName)
{
return setAttribute(QStringLiteral("t_name"), iName);
}
QString SKGNamedObject::getName() const
{
return getAttribute(QStringLiteral("t_name"));
}
QString SKGNamedObject::getWhereclauseId() const
{
// Could we use the id
QString output = SKGObjectBase::getWhereclauseId();
if (output.isEmpty()) {
// No, so we use the name
QString name = SKGServices::stringToSqlString(getName());
if (!name.isEmpty() || getID() == 0) {
output = "t_name='" % name % '\'';
}
}
return output;
}
SKGError SKGNamedObject::getObjectByName(SKGDocument* iDocument, const QString& iTable, const QString& iName, SKGObjectBase& oObject)
{
return iDocument != nullptr ? iDocument->getObject(iTable, "t_name='" % SKGServices::stringToSqlString(iName) % '\'', oObject) : SKGError();
}
diff --git a/skgbasemodeler/skgnamedobject.h b/skgbasemodeler/skgnamedobject.h
index 9880a06fb..d4cba2213 100644
--- a/skgbasemodeler/skgnamedobject.h
+++ b/skgbasemodeler/skgnamedobject.h
@@ -1,118 +1,118 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGNAMEDOBJECT_H
#define SKGNAMEDOBJECT_H
/** @file
* This file defines classes SKGNamedObject.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgdefine.h"
#include "skgerror.h"
#include "skgobjectbase.h"
/**
* This class is a named object base.
* This is a generic way to manipulate objects with name.
*/
class SKGBASEMODELER_EXPORT SKGNamedObject : public SKGObjectBase
{
Q_OBJECT
/**
* Name of the object
*/
Q_PROPERTY(QString name READ getName WRITE setName USER true) // clazy:exclude=qproperty-without-notify
public:
/**
* Return the object (@p oObject) corresponding to a name (@p iName ).
* If more than one objects are returned by the query, then an error is generated
* If 0 object is returned by the query, then an error is generated
* @param iDocument the document where to search
* @param iTable the table where to search
* @param iName name of the object in @p iTable
* @param oObject the result
* @return an object managing the error
* @see SKGError
*/
static SKGError getObjectByName(SKGDocument* iDocument, const QString& iTable,
const QString& iName, SKGObjectBase& oObject);
/**
* Default constructor
*/
explicit SKGNamedObject();
/**
* Constructor
* @param iDocument the document containing the object
* @param iTable the table of the object
* @param iID the identifier in @p iTable of the object
*/
explicit SKGNamedObject(SKGDocument* iDocument, const QString& iTable = QString(), int iID = 0);
/**
* Copy constructor
* @param iObject the object to copy
*/
SKGNamedObject(const SKGNamedObject& iObject);
/**
* Copy constructor
* @param iObject the object to copy
*/
explicit SKGNamedObject(const SKGObjectBase& iObject);
/**
* Operator affectation
* @param iObject the object to copy
*/
SKGNamedObject& operator= (const SKGObjectBase& iObject);
/**
* Destructor
*/
~SKGNamedObject() override;
/**
* Set the name of this object
* @param iName the name
* @return an object managing the error
* @see SKGError
*/
virtual SKGError setName(const QString& iName);
/**
* Get the name of this object
* @return the name
*/
virtual QString getName() const;
protected:
/**
* Get where clause needed to identify objects.
* For this class, the whereclause is based on name
* @return the where clause
*/
QString getWhereclauseId() const override;
};
/**
* Declare the class
*/
Q_DECLARE_TYPEINFO(SKGNamedObject, Q_MOVABLE_TYPE);
#endif
diff --git a/skgbasemodeler/skgnodeobject.cpp b/skgbasemodeler/skgnodeobject.cpp
index 113cd8858..22f3974ee 100644
--- a/skgbasemodeler/skgnodeobject.cpp
+++ b/skgbasemodeler/skgnodeobject.cpp
@@ -1,276 +1,276 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file implements classes SKGNodeObject.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgnodeobject.h"
#include <klocalizedstring.h>
#include <qicon.h>
#include "skgdefine.h"
#include "skgdocument.h"
#include "skgtraces.h"
SKGNodeObject::SKGNodeObject(): SKGNodeObject(nullptr)
{}
SKGNodeObject::SKGNodeObject(SKGDocument* iDocument, int iID): SKGNamedObject(iDocument, QStringLiteral("v_node"), iID), opened(false)
{}
SKGNodeObject::~SKGNodeObject()
= default;
SKGNodeObject::SKGNodeObject(const SKGNodeObject& iObject) : SKGNamedObject(iObject), opened(false)
{}
SKGNodeObject::SKGNodeObject(const SKGObjectBase& iObject) : SKGNamedObject(iObject.getDocument(), QStringLiteral("v_node"), iObject.getID()), opened(false)
{}
SKGNodeObject& SKGNodeObject::operator= (const SKGObjectBase& iObject)
{
copyFrom(iObject);
return *this;
}
SKGError SKGNodeObject::setName(const QString& iName)
{
SKGError err;
if (iName.contains(OBJECTSEPARATOR)) {
err = SKGError(ERR_FAIL, i18nc("Error message: an invalid character was found", "The name '%1' is invalid : the '%2' character is forbidden ", iName, QString(OBJECTSEPARATOR)));
} else {
err = SKGNamedObject::setName(iName);
}
return err;
}
QString SKGNodeObject::getWhereclauseId() const
{
// Could we use the id
QString output = SKGObjectBase::getWhereclauseId(); // clazy:exclude=skipped-base-method
if (output.isEmpty()) {
if (!(getAttribute(QStringLiteral("t_name")).isEmpty())) {
output = "t_name='" % SKGServices::stringToSqlString(getAttribute(QStringLiteral("t_name"))) % '\'';
}
QString rd_node_id = getAttribute(QStringLiteral("rd_node_id"));
if (!output.isEmpty()) {
output += QStringLiteral(" AND ");
}
if (rd_node_id.isEmpty()) {
output += QStringLiteral("(rd_node_id=0 OR rd_node_id IS NULL OR rd_node_id='')");
} else {
output += "rd_node_id=" % rd_node_id;
}
}
return output;
}
QString SKGNodeObject::getFullName() const
{
return getAttribute(QStringLiteral("t_fullname"));
}
SKGError SKGNodeObject::setData(const QString& iData)
{
return setAttribute(QStringLiteral("t_data"), iData);
}
QString SKGNodeObject::getData() const
{
return getAttribute(QStringLiteral("t_data"));
}
bool SKGNodeObject::isFolder() const
{
return getData().isEmpty();
}
SKGError SKGNodeObject::setIcon(const QString& iIcon)
{
return setAttribute(QStringLiteral("t_icon"), iIcon);
}
QIcon SKGNodeObject::getIcon() const
{
QStringList overlay;
if (isAutoStart()) {
overlay.push_back(QStringLiteral("media-playback-start"));
}
return SKGServices::fromTheme(getAttribute(QStringLiteral("t_icon")), overlay);
}
SKGError SKGNodeObject::setAutoStart(bool iAutoStart)
{
return setAttribute(QStringLiteral("t_autostart"), iAutoStart ? QStringLiteral("Y") : QStringLiteral("N"));
}
bool SKGNodeObject::isAutoStart() const
{
return (getAttribute(QStringLiteral("t_autostart")) == QStringLiteral("Y"));
}
SKGError SKGNodeObject::setOrder(double iOrder)
{
SKGError err;
double order = iOrder;
if (order == -1) {
order = 1;
SKGStringListList result;
err = getDocument()->executeSelectSqliteOrder(QStringLiteral("SELECT max(f_sortorder) from node"), result);
if (!err && result.count() == 2) {
order = SKGServices::stringToDouble(result.at(1).at(0)) + 1;
}
}
IFOKDO(err, setAttribute(QStringLiteral("f_sortorder"), SKGServices::doubleToString(order)))
return err;
}
double SKGNodeObject::getOrder() const
{
return SKGServices::stringToDouble(getAttribute(QStringLiteral("f_sortorder")));
}
SKGError SKGNodeObject::createPathNode(SKGDocument* iDocument,
const QString& iFullPath,
SKGNodeObject& oNode,
bool iRenameIfAlreadyExist)
{
SKGError err;
SKGTRACEINFUNCRC(10, err)
SKGTRACEL(10) << "Input parameter [iFullPath]=" << iFullPath << endl;
// Check if node is already existing
if (!iRenameIfAlreadyExist && iDocument != nullptr) {
iDocument->getObject(QStringLiteral("v_node"), "t_fullname='" % SKGServices::stringToSqlString(iFullPath) % '\'', oNode);
}
if (oNode.getID() == 0) {
// No, we have to create it
// Search node separator
int posSeparator = iFullPath.lastIndexOf(OBJECTSEPARATOR);
if (posSeparator == -1) {
oNode = SKGNodeObject(iDocument);
err = oNode.setName(iFullPath);
// Check if already existing
if (!err && iRenameIfAlreadyExist) {
int index = 1;
while (!err && oNode.exist()) {
index++;
err = oNode.setName(iFullPath % " (" % SKGServices::intToString(index) % ')');
}
}
IFOKDO(err, oNode.setIcon(QStringLiteral("folder-orange")))
IFOKDO(err, oNode.setOrder(-1))
IFOKDO(err, oNode.save())
} else {
// Get first and second parts of the branch
QString first = iFullPath.mid(0, posSeparator);
QString second = iFullPath.mid(posSeparator + QString(OBJECTSEPARATOR).length(), iFullPath.length() - posSeparator - QString(OBJECTSEPARATOR).length());
// Get first node
SKGNodeObject FirstNode;
err = SKGNodeObject::createPathNode(iDocument, first, FirstNode);
IFOK(err) {
// Get second node
err = FirstNode.addNode(oNode);
// Add second under first
IFOKDO(err, oNode.setName(second))
// Check if already existing
if (!err && iRenameIfAlreadyExist) {
int index = 2;
while (!err && oNode.exist()) {
err = oNode.setName(second % " (" % SKGServices::intToString(index) % ')');
++index;
}
}
// save
IFOKDO(err, oNode.setIcon(QStringLiteral("folder-orange")))
IFOKDO(err, oNode.setOrder(-1))
IFOKDO(err, oNode.save())
}
}
}
return err;
}
SKGError SKGNodeObject::addNode(SKGNodeObject& oNode)
{
SKGError err;
SKGTRACEINFUNCRC(10, err)
if (getID() == 0) {
err = SKGError(ERR_FAIL, i18nc("Error message: Something failed because of a database issue", "%1 failed because linked object is not yet saved in the database.", QStringLiteral("SKGNodeObject::addNode")));
} else {
oNode = SKGNodeObject(getDocument());
err = oNode.setAttribute(QStringLiteral("rd_node_id"), SKGServices::intToString(getID()));
}
return err;
}
SKGError SKGNodeObject::removeParentNode()
{
return setAttribute(QStringLiteral("rd_node_id"), QLatin1String(""));
}
SKGError SKGNodeObject::setParentNode(const SKGNodeObject& iNode)
{
SKGError err;
SKGTRACEINFUNCRC(10, err)
if (iNode.getID() == 0) {
err = SKGError(ERR_FAIL, i18nc("Error message: Something failed because of a database issue", "%1 failed because linked object is not yet saved in the database.", QStringLiteral("SKGNodeObject::setParentNode")));
} else {
// Check if it is a loop
SKGNodeObject current = iNode;
do {
if (current == *this) {
err = SKGError(ERR_FAIL, i18nc("Error message: Loops are forbidden in Skrooge data structures", "You cannot create a loop, ie parent and child with the same name. For example, A > A is a loop. A > B > A is another kind of loop"));
} else {
SKGNodeObject parentNode;
current.getParentNode(parentNode);
current = parentNode;
}
} while (!err && current.getID() != 0);
IFOKDO(err, setAttribute(QStringLiteral("rd_node_id"), SKGServices::intToString(iNode.getID())))
}
return err;
}
SKGError SKGNodeObject::getParentNode(SKGNodeObject& oNode) const
{
SKGError err;
QString parent_id = getAttribute(QStringLiteral("rd_node_id"));
if (!parent_id.isEmpty()) {
err = getDocument()->getObject(QStringLiteral("v_node"), "id=" % parent_id, oNode);
} else {
oNode = SKGNodeObject();
}
return err;
}
SKGError SKGNodeObject::getNodes(SKGListSKGObjectBase& oNodeList) const
{
return getDocument()->getObjects(QStringLiteral("v_node"), "rd_node_id=" % SKGServices::intToString(getID()) % " ORDER BY f_sortorder, t_name", oNodeList);
}
diff --git a/skgbasemodeler/skgnodeobject.h b/skgbasemodeler/skgnodeobject.h
index 00e8b397d..9eb8b5fc1 100644
--- a/skgbasemodeler/skgnodeobject.h
+++ b/skgbasemodeler/skgnodeobject.h
@@ -1,233 +1,233 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGNODEOBJECT_H
#define SKGNODEOBJECT_H
/** @file
* This file defines classes SKGNodeObject.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgdefine.h"
#include "skgnamedobject.h"
class SKGDocument;
/**
* This class manages node object
*/
class SKGBASEMODELER_EXPORT SKGNodeObject final : public SKGNamedObject
{
Q_OBJECT
/**
* Order of the node
*/
Q_PROPERTY(double order READ getOrder WRITE setOrder) // clazy:exclude=qproperty-without-notify
/**
* Full name of the node
*/
Q_PROPERTY(QString fullName READ getFullName) // clazy:exclude=qproperty-without-notify
/**
* Data of the node
*/
Q_PROPERTY(QString data READ getData WRITE setData) // clazy:exclude=qproperty-without-notify
public:
/**
* Indicates if a node is opened
*/
bool opened;
/**
* default constructor
*/
explicit SKGNodeObject();
/**
* Constructor
* @param iDocument the document containing the object
* @param iID the identifier in @p iTable of the object
*/
explicit SKGNodeObject(SKGDocument* iDocument, int iID = 0);
/**
* Copy constructor
* @param iObject the object to copy
*/
SKGNodeObject(const SKGNodeObject& iObject);
/**
* Copy constructor
* @param iObject the object to copy
*/
explicit SKGNodeObject(const SKGObjectBase& iObject);
/**
* Operator affectation
* @param iObject the object to copy
*/
SKGNodeObject& operator= (const SKGObjectBase& iObject);
/**
* Destructor
*/
~SKGNodeObject() override;
/**
* Create a node branch if needed and return the leaf of the branch
* @param iDocument the document where to create
* @param iFullPath the full path. Example: cat1|cat2|cat3
* @param oNode the leaf of the branch
* @param iRenameIfAlreadyExist if a leaf with the expected name already exist than the leaf will be renamed and created
* @return an object managing the error.
* @see SKGError
*/
static SKGError createPathNode(SKGDocument* iDocument,
const QString& iFullPath,
SKGNodeObject& oNode,
bool iRenameIfAlreadyExist = false);
/**
* Set the name of this object
* @param iName the name
* @return an object managing the error
* @see SKGError
*/
SKGError setName(const QString& iName) override;
/**
* Get the full name of this node.
* The full name is the unique name of the node.
* It is computed by the concatenation of names for all
* the fathers of this node.
* @return the full name
*/
QString getFullName() const;
/**
* Add a node
* @param oNode the created node
* @return an object managing the error.
* @see SKGError
*/
SKGError addNode(SKGNodeObject& oNode);
/**
* Move the node by changing the parent
* @param iNode the parent node
* @return an object managing the error.
* @see SKGError
*/
SKGError setParentNode(const SKGNodeObject& iNode);
/**
* Get the parent node
* @param oNode the parent node
* @return an object managing the error.
* @see SKGError
*/
SKGError getParentNode(SKGNodeObject& oNode) const;
/**
* Remove the parent node. The node will be a root.
* @return an object managing the error.
* @see SKGError
*/
SKGError removeParentNode();
/**
* Get nodes
* @param oNodeList the list of nodes under the current one
* @return an object managing the error
* @see SKGError
*/
SKGError getNodes(SKGListSKGObjectBase& oNodeList) const;
/**
* Set the order for the node in its parent
* @param iOrder the order. (-1 means "at the end")
* @return an object managing the error
* @see SKGError
*/
SKGError setOrder(double iOrder);
/**
* Get the order for the node in its parent
* @return the order
*/
double getOrder() const;
/**
* Set data of this node
* @param iData the data
* @return an object managing the error
* @see SKGError
*/
SKGError setData(const QString& iData);
/**
* Get data of this node
* @return the data
*/
QString getData() const;
/**
* To know if the node is a folder or not
* @return true of false
*/
bool isFolder() const;
/**
* Set icon of this node
* @param iIcon the icon name
* @return an object managing the error
* @see SKGError
*/
SKGError setIcon(const QString& iIcon);
/**
* Get icon of this node
* @return the icon
*/
QIcon getIcon() const;
/**
* Set autostart mode of this node
* @param iAutoStart the autostart mode
* @return an object managing the error
* @see SKGError
*/
SKGError setAutoStart(bool iAutoStart);
/**
* Get autostart mode of this node
* @return the autostart mode
*/
bool isAutoStart() const;
protected:
/**
* Get where clause needed to identify objects.
* For this class, the whereclause is based on name + rd_node_id
* @return the where clause
*/
QString getWhereclauseId() const override;
};
/**
* Declare the class
*/
Q_DECLARE_TYPEINFO(SKGNodeObject, Q_MOVABLE_TYPE);
#endif
diff --git a/skgbasemodeler/skgobjectbase.cpp b/skgbasemodeler/skgobjectbase.cpp
index 35c6f5f32..c8d5725bb 100644
--- a/skgbasemodeler/skgobjectbase.cpp
+++ b/skgbasemodeler/skgobjectbase.cpp
@@ -1,589 +1,589 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file defines classes SKGObjectBase.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgobjectbase.h"
#include <qsqldatabase.h>
#include <klocalizedstring.h>
#include <kstringhandler.h>
#include <algorithm>
#include "skgdocument.h"
#include "skgnamedobject.h"
#include "skgservices.h"
#include "skgtraces.h"
/**
* This private class of SKGObjectBase
*/
class SKGObjectBasePrivate
{
public:
/**
* internal id
*/
int id = 0;
/**
* internal table
*/
QString table;
/**
* internal document
*/
SKGDocument* document = nullptr;
/**
* internal attributes
*/
SKGQStringQStringMap attributes;
/**
* objects to save
*/
SKGObjectBase::SKGListSKGObjectBase objects;
};
SKGObjectBase::SKGObjectBase() : SKGObjectBase(nullptr)
{}
SKGObjectBase::SKGObjectBase(SKGDocument* iDocument, const QString& iTable, int iID)
: d(new SKGObjectBasePrivate)
{
d->id = iID;
d->table = iTable;
d->document = iDocument;
if (Q_LIKELY(d->id != 0)) {
load();
}
}
SKGObjectBase::~SKGObjectBase()
{
delete d;
}
SKGObjectBase::SKGObjectBase(const SKGObjectBase& iObject)
: QObject(), d(new SKGObjectBasePrivate)
{
copyFrom(iObject);
}
SKGObjectBase::SKGObjectBase(SKGObjectBase&& iObject) noexcept
: d(iObject.d)
{
iObject.d = nullptr;
}
SKGObjectBase& SKGObjectBase::operator= (const SKGObjectBase& iObject)
{
copyFrom(iObject);
return *this;
}
bool SKGObjectBase::operator==(const SKGObjectBase& iObject) const
{
return (getUniqueID() == iObject.getUniqueID());
}
bool SKGObjectBase::operator!=(const SKGObjectBase& iObject) const
{
return !(*this == iObject);
}
bool SKGObjectBase::operator<(const SKGObjectBase& iObject) const
{
double d1 = SKGServices::stringToDouble(getAttribute(QStringLiteral("f_sortorder")));
double d2 = SKGServices::stringToDouble(iObject.getAttribute(QStringLiteral("f_sortorder")));
return (d1 < d2);
}
bool SKGObjectBase::operator>(const SKGObjectBase& iObject) const
{
double d1 = SKGServices::stringToDouble(getAttribute(QStringLiteral("f_sortorder")));
double d2 = SKGServices::stringToDouble(iObject.getAttribute(QStringLiteral("f_sortorder")));
return (d1 > d2);
}
QString SKGObjectBase::getUniqueID() const
{
return SKGServices::intToString(d->id) % '-' % getRealTable();
}
int SKGObjectBase::getID() const
{
return d->id;
}
QString SKGObjectBase::getAttributeFromView(const QString& iView, const QString& iName) const
{
QString output;
SKGStringListList result;
QString wc = getWhereclauseId();
if (wc.isEmpty()) {
wc = "id=" % SKGServices::intToString(d->id);
}
QString sql = "SELECT " % iName % " FROM " % iView % " WHERE " % wc;
if (getDocument() != nullptr) {
getDocument()->executeSelectSqliteOrder(sql, result, false);
}
if (result.count() == 2) {
output = result.at(1).at(0);
}
return output;
}
QString SKGObjectBase::getDisplayName() const
{
return getAttributeFromView("v_" % getRealTable() % "_displayname", QStringLiteral("t_displayname"));
}
void SKGObjectBase::copyFrom(const SKGObjectBase& iObject)
{
if (d == nullptr) {
d = new SKGObjectBasePrivate;
}
d->id = iObject.d->id;
d->table = iObject.d->table;
d->document = iObject.d->document;
d->attributes = iObject.d->attributes;
Q_EMIT modified();
}
SKGObjectBase SKGObjectBase::cloneInto()
{
return cloneInto(nullptr);
}
SKGObjectBase SKGObjectBase::cloneInto(SKGDocument* iDocument)
{
SKGDocument* targetDocument = iDocument;
if (targetDocument == nullptr) {
targetDocument = d->document;
}
SKGObjectBase output;
output.copyFrom(*this);
output.d->id = 0;
output.d->document = targetDocument;
Q_EMIT modified();
return output;
}
SKGError SKGObjectBase::resetID()
{
d->id = 0;
Q_EMIT modified();
return SKGError();
}
QString SKGObjectBase::getTable() const
{
return d->table;
}
QString SKGObjectBase::getRealTable() const
{
return SKGServices::getRealTable(d->table);
}
SKGDocument* SKGObjectBase::getDocument() const
{
return d->document;
}
SKGQStringQStringMap SKGObjectBase::getAttributes() const
{
return d->attributes;
}
int SKGObjectBase::getNbAttributes() const
{
return d->attributes.count();
}
SKGError SKGObjectBase::setAttributes(const QStringList& iNames, const QStringList& iValues)
{
SKGError err;
int nb = iNames.size();
for (int i = 0; !err && i < nb; ++i) {
const auto& att = iNames.at(i);
const auto& val = iValues.at(i);
if (Q_LIKELY(att != QStringLiteral("id"))) {
err = setAttribute(att, val);
} else {
d->id = SKGServices::stringToInt(val);
}
}
return err;
}
SKGError SKGObjectBase::setAttribute(const QString& iName, const QString& iValue)
{
SKGError err;
if (Q_LIKELY(iValue != NOUPDATE)) {
QString val = iValue;
// Case modification on pointed document
if (this->getRealTable() == this->getTable() && iName != iName.toLower()) {
QString realAttribute = d->document->getRealAttribute(iName);
if (!realAttribute.isEmpty()) {
QStringList l = realAttribute.split('.');
if (l.size() == 3) {
SKGObjectBase obj;
QString refId = getAttribute(l.at(1));
if (!refId.isEmpty()) {
err = getDocument()->getObject("v_" % l.at(0), "id=" % refId, obj);
IFOK(err) {
err = obj.setAttribute(l.at(2), iValue);
d->objects.push_back(obj);
}
}
}
}
} else if (iValue.startsWith(QLatin1String("="))) {
// Case modificator
QString op = iValue.right(iValue.length() - 1).toLower();
val = d->attributes[iName];
if (op == i18nc("Key word to modify a string into a field", "lower")) {
val = val.toLower();
} else if (op == i18nc("Key word to modify a string into a field", "upper")) {
val = val.toUpper();
} else if (op == i18nc("Key word to modify a string into a field", "capwords")) {
val = KStringHandler::capwords(val.toLower());
} else if (op == i18nc("Key word to modify a string into a field", "capitalize")) {
val = val.at(0).toUpper() % val.right(val.length() - 1).toLower();
} else if (op == i18nc("Key word to modify a string into a field", "trim")) {
val = val.trimmed();
} else {
val = iValue;
}
}
d->attributes[iName] = val;
}
Q_EMIT modified();
return err;
}
QString SKGObjectBase::getAttribute(const QString& iName) const
{
QString output;
if (Q_LIKELY(d->attributes.contains(iName))) {
output = d->attributes[iName];
} else if (iName == QStringLiteral("id")) {
output = SKGServices::intToString(getID());
} if (iName.startsWith(QLatin1String("p_"))) {
output = getProperty(iName.right(iName.length() - 2));
} else {
// Is the iName a number ?
bool ok;
int pos = iName.toInt(&ok);
if (ok) {
// What is the key corresponding to this name ?
QStringList keys = d->attributes.uniqueKeys();
std::sort(keys.begin(), keys.end());
if (pos >= 0 && pos < keys.count()) {
output = d->attributes[keys.at(pos)];
}
} else {
// Case modification on pointed document iName1.(iTable2)iName2 or iName1.iName2
int pos = iName.indexOf('.');
if (pos != -1) {
QString attributeref = iName.left(pos);
QString refId = getAttribute(attributeref);
if (!refId.isEmpty()) {
QString rest = iName.right(iName.length() - pos - 1);
QString table;
QString att;
QRegExp rx(QStringLiteral("^\\(([^\\)]*)\\)(.*)$"));
if (rx.indexIn(rest) != -1) {
// Case iName1.(iTable2)iName2
table = rx.cap(1);
att = rx.cap(2);
} else {
QRegExp rx2(QStringLiteral("^.*_(.*)_.*$"));
if (rx2.indexIn(attributeref) != -1) {
// Case iName1.iName2
table = "v_" % rx2.cap(1);
att = rest;
}
}
SKGObjectBase obj;
SKGError err = getDocument()->getObject(table, "id=" % refId, obj);
IFOK(err) {
output = obj.getAttribute(att);
}
}
}
}
}
return output;
}
bool SKGObjectBase::exist() const
{
SKGTRACEINFUNC(20)
SKGStringListList result;
QString wc = getWhereclauseId();
if (wc.isEmpty() && d->id != 0) {
wc = "id=" % SKGServices::intToString(d->id);
}
if (wc.isEmpty()) {
return false;
}
QString sql = "SELECT count(1) FROM " % d->table % " WHERE " % wc;
if (getDocument() != nullptr) {
getDocument()->executeSelectSqliteOrder(sql, result, false);
}
return (result.size() >= 2 && result.at(1).at(0) != QStringLiteral("0"));
}
SKGError SKGObjectBase::load()
{
SKGError err;
SKGTRACEINFUNCRC(20, err)
if (Q_LIKELY(getDocument() && !getTable().isEmpty())) {
// Prepare where clause
QString wc = getWhereclauseId();
if (wc.isEmpty()) {
wc = "id=" % SKGServices::intToString(d->id);
}
// Execute sql order
SKGStringListList result;
err = getDocument()->executeSelectSqliteOrder("SELECT * FROM " % d->table % " WHERE " % wc, result, false);
IFOK(err) {
int size = result.size();
if (Q_UNLIKELY(size == 1)) {
err = SKGError(ERR_INVALIDARG, i18nc("Error message: Could not load something because it is not in the database", "Load of '%1' with '%2' failed because it was not found in the database", d->table, wc));
} else if (Q_UNLIKELY(size != 2)) {
err = SKGError(ERR_INVALIDARG, i18np("Load of '%2' with '%3' failed because of bad size of result (found one object)",
"Load of '%2' with '%3' failed because of bad size of result (found %1 objects)",
size - 1, d->table, wc));
} else {
SKGStringListList::const_iterator itrow = result.constBegin();
QStringList columns = *(itrow);
++itrow;
QStringList values = *(itrow);
err = setAttributes(columns, values);
}
}
}
Q_EMIT modified();
return err;
}
QString SKGObjectBase::getWhereclauseId() const
{
int id = getID();
if (id != 0) {
return "id=" % SKGServices::intToString(id);
}
return QLatin1String("");
}
SKGError SKGObjectBase::save(bool iInsertOrUpdate, bool iReloadAfterSave)
{
SKGError err;
SKGTRACEINFUNCRC(20, err)
if (Q_UNLIKELY(!d->document)) {
err = SKGError(ERR_POINTER, i18nc("Error message", "Operation impossible because the document is missing"));
} else {
// Save linking objects
int nb = d->objects.count();
for (int i = 0; !err && i < nb; ++i) {
SKGObjectBase ref = d->objects.at(i);
err = ref.save(iInsertOrUpdate, iReloadAfterSave);
}
// Check if we are in a transaction
IFOKDO(err, d->document->checkExistingTransaction())
IFOK(err) {
// Table to use
QString tablename = getRealTable();
// Build order
QString part1Insert;
QString part2Insert;
QString partUpdate;
SKGQStringQStringMap::const_iterator it;
for (it = d->attributes.constBegin() ; it != d->attributes.constEnd(); ++it) {
QString att = SKGServices::stringToSqlString(it.key());
QString attlower = att.toLower();
if (att.length() > 2 && att == attlower) { // We must ignore attributes coming from views
QString value = '\'' % SKGServices::stringToSqlString(it.value()) % '\'';
if (!part1Insert.isEmpty()) {
part1Insert.append(',');
part2Insert.append(',');
partUpdate.append(',');
}
// Attribute
part1Insert.append('\'' % att % '\'');
// Value
part2Insert.append(value);
// Attribute=Value for update
partUpdate.append(att % '=' % value);
}
}
// We try an Insert
if (d->id == 0) {
// We have to try un insert
err = getDocument()->executeSqliteOrder("INSERT INTO " % tablename % " (" % part1Insert % ") VALUES (" % part2Insert % ')', &(d->id));
} else {
// We must try an update
err = SKGError(ERR_ABORT, QLatin1String("")); // Just to go in UPDATE code
}
if (err && iInsertOrUpdate) {
// INSERT failed, could we try an update ?
QString wc = this->getWhereclauseId();
if (!wc.isEmpty()) {
// Yes ==> Update
err = getDocument()->executeSqliteOrder("UPDATE " % tablename % " SET " % partUpdate % " WHERE " % wc);
}
}
}
}
// Reload object is updated
if (!err && iReloadAfterSave) {
// The object has been updated ==>load
err = load();
}
return err;
}
SKGError SKGObjectBase::remove(bool iSendMessage, bool iForce) const
{
SKGError err;
SKGTRACEINFUNCRC(20, err)
if (Q_UNLIKELY(!d->document)) {
err = SKGError(ERR_POINTER, i18nc("Error message", "Operation impossible because the document is missing"));
} else {
// Check if we are in a transaction
err = d->document->checkExistingTransaction();
// delete order
QString viewForDelete = QStringLiteral("v_") % getRealTable() % "_delete";
// Check if the delete view exist
SKGStringListList temporaryResult;
d->document->executeSelectSqliteOrder("PRAGMA table_info( " % viewForDelete % " );", temporaryResult);
if (!iForce && temporaryResult.count() > 1) { // At least one attribute
// Delete view exists, check if the delete is authorized
err = d->document->executeSelectSqliteOrder("SELECT t_delete_message FROM " % viewForDelete % " WHERE id=" % SKGServices::intToString(d->id), temporaryResult, false);
IFOK(err) {
QString msg;
if (temporaryResult.count() > 1) {
msg = temporaryResult.at(1).at(0);
}
// Should the string below be translated ??? It contains no word
if (!msg.isEmpty()) {
err = SKGError(ERR_FORCEABLE, i18nc("Error message for an object", "'%1': %2", getDisplayName(), msg));
}
}
}
QString displayname = getDisplayName(); // Must be done before the delete order
IFOKDO(err, d->document->executeSqliteOrder("DELETE FROM " % getRealTable() % " WHERE id=" % SKGServices::intToString(d->id)))
if (iSendMessage && !err && !displayname.isEmpty()) {
err = d->document->sendMessage(i18nc("An information to the user that something was deleted", "'%1' has been deleted", displayname), SKGDocument::Hidden);
}
}
return err;
}
SKGError SKGObjectBase::dump() const
{
// dump
SKGTRACE << "=== START DUMP [" << getUniqueID() << "]===" << endl;
SKGQStringQStringMap::const_iterator it;
for (it = d->attributes.constBegin() ; it != d->attributes.constEnd(); ++it) {
SKGTRACE << it.key() << "=[" << it.value() << ']' << endl;
}
SKGTRACE << "=== END DUMP [" << getUniqueID() << "]===" << endl;
return SKGError();
}
QStringList SKGObjectBase::getProperties() const
{
return Q_UNLIKELY(!getDocument()) ? QStringList() : getDocument()->getParameters(getUniqueID());
}
QString SKGObjectBase::getProperty(const QString& iName) const
{
return Q_UNLIKELY(!getDocument()) ? QString() : getDocument()->getParameter(iName, getUniqueID());
}
SKGObjectBase SKGObjectBase::getPropertyObject(const QString& iName) const
{
SKGObjectBase property;
if (getDocument() != nullptr) {
getDocument()->getObject(QStringLiteral("parameters"), "t_name='" % SKGServices::stringToSqlString(iName) %
"' AND t_uuid_parent='" % SKGServices::stringToSqlString(getUniqueID()) % '\'', property);
}
return property;
}
QVariant SKGObjectBase::getPropertyBlob(const QString& iName) const
{
return Q_UNLIKELY(!getDocument()) ? QVariant() : getDocument()->getParameterBlob(iName, getUniqueID());
}
SKGError SKGObjectBase::setProperty(const QString& iName, const QString& iValue, const QString& iFileName, SKGPropertyObject* oObjectCreated) const
{
SKGError err = Q_UNLIKELY(!getDocument()) ? SKGError() : getDocument()->setParameter(iName, iValue, iFileName, getUniqueID(), oObjectCreated);
// Send message
IFOKDO(err, Q_UNLIKELY(!getDocument()) ? SKGError() : getDocument()->sendMessage(i18nc("An information to the user", "The property '%1=%2' has been added on '%3'", iName, iValue, getDisplayName()), SKGDocument::Hidden))
return err;
}
SKGError SKGObjectBase::setProperty(const QString& iName, const QString& iValue, const QVariant& iBlob, SKGPropertyObject* oObjectCreated) const
{
SKGError err = Q_UNLIKELY(!getDocument()) ? SKGError() : getDocument()->setParameter(iName, iValue, iBlob, getUniqueID(), oObjectCreated);
// Send message
IFOKDO(err, Q_UNLIKELY(!getDocument()) ? SKGError() : getDocument()->sendMessage(i18nc("An information to the user", "The property '%1=%2' has been added on '%3'", iName, iValue, getDisplayName()), SKGDocument::Hidden))
return err;
}
diff --git a/skgbasemodeler/skgobjectbase.h b/skgbasemodeler/skgobjectbase.h
index 10248161c..eee1a74ea 100644
--- a/skgbasemodeler/skgobjectbase.h
+++ b/skgbasemodeler/skgobjectbase.h
@@ -1,367 +1,367 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGOBJECTBASE_H
#define SKGOBJECTBASE_H
/** @file
* This file defines classes SKGObjectBase.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include <qlist.h>
#include <qstring.h>
#include <qvariant.h>
#include "skgdefine.h"
#include "skgerror.h"
#include "skgservices.h"
class SKGDocument;
class SKGPropertyObject;
class SKGObjectBasePrivate;
/**
* This class is the base class for all objects.
* This class is a generic way to manipulate objects.
* Some important rules:
* R1: Each table must have a view named v_[tablename] where [tablename] is the name of the table.
* R2: Each computed attribute of the view must have a name starting with v_
*/
class SKGBASEMODELER_EXPORT SKGObjectBase : public QObject
{
Q_OBJECT
/**
* Unique ide of the object
*/
Q_PROPERTY(QString uniqueID READ getUniqueID CONSTANT)
/**
* Id of the object
*/
Q_PROPERTY(int ID READ getID CONSTANT)
/**
* Table of the object
*/
Q_PROPERTY(QString table READ getTable CONSTANT)
public:
/**
* A list of SKGObjectBase ==> SKGListSKGObjectBase
*/
using SKGListSKGObjectBase = QVector<SKGObjectBase>;
/**
* An iterator for SKGListSKGObjectBase
*/
using SKGListSKGObjectBaseIterator = QVector<SKGObjectBase>::Iterator;
/**
* Default constructor
*/
explicit SKGObjectBase();
/**
* Constructor
* @param iDocument the document containing the object
* @param iTable the table of the object
* @param iID the identifier in @p iTable of the object
*/
explicit SKGObjectBase(SKGDocument* iDocument, const QString& iTable = QString(), int iID = 0);
/**
* Copy constructor
* @param iObject the object to copy
*/
SKGObjectBase(const SKGObjectBase& iObject);
/**
* Move constructor
* @param iObject the object to copy
*/
SKGObjectBase(SKGObjectBase&& iObject) noexcept;
/**
* Operator comparison
* @param iObject The object to compare
*/
virtual bool operator==(const SKGObjectBase& iObject) const;
/**
* Operator comparison
* @param iObject The object to compare
*/
virtual bool operator!=(const SKGObjectBase& iObject) const;
/**
* Operator comparison
* @param iObject The object to compare
*/
virtual bool operator<(const SKGObjectBase& iObject) const;
/**
* Operator comparison
* @param iObject The object to compare
*/
virtual bool operator>(const SKGObjectBase& iObject) const;
/**
* Operator affectation
* @param iObject the object to copy
*/
SKGObjectBase& operator= (const SKGObjectBase& iObject);
/**
* Clone this object into a same document. The id is not kept. The cloned object is not saved into the target document
*/
virtual SKGObjectBase cloneInto();
/**
* Clone this object into a new document. The id is not kept. The cloned object is not saved into the target document
* @param iDocument the target document.
*/
virtual SKGObjectBase cloneInto(SKGDocument* iDocument);
/**
* Destructor
*/
~SKGObjectBase() override;
/**
* Return the unique id of this object
* @return unique id of this object
*/
virtual QString getUniqueID() const;
/**
* Return the id of this object
* @return id of this object
*/
virtual int getID() const;
/**
* Return the name of the object for the display
* @return name of the object
*/
virtual QString getDisplayName() const;
/**
* Reset the ID of this object.
* It is used to create a new object based on an existing one.
* By reseting the ID, the save will try an INSERT instead of an UPDATE.
* @return an object managing the error
* @see SKGError
*/
virtual SKGError resetID();
/**
* Return the table name of this object
* @return table name of this object
*/
virtual QString getTable() const;
/**
* Return the real table name of this object.
* This is useful for modification (UPDATE, DELETE)
* @return real table name of this object
*/
virtual QString getRealTable() const;
/**
* Return the document of this object
* @return document of this object
*/
SKGDocument* getDocument() const;
/**
* Return the attributes of this object
* @return attributes of this object
*/
virtual SKGQStringQStringMap getAttributes() const;
/**
* Return the number of attributes
* @return number of attributes
*/
virtual int getNbAttributes() const;
/**
* Get the value for an attribute
* @param iName the name of the attribute.
* This can be:
* The name of an attribute (eg. t_name)
* The name of a property (eg. p_myproperty)
* The name of an attribute on a pointed object (eg. rd_node_id.(v_node)t_name)
* @return the value of this attribute
*/
virtual QString getAttribute(const QString& iName) const;
/**
* Get the value for an attribute for another view
* @param iView the name of the view
* @param iName the name of the attribute
* @return the value of this attribute
*/
virtual QString getAttributeFromView(const QString& iView, const QString& iName) const;
/**
* Set the value for an attribute
* @param iName the name of the attribute
* @param iValue the value of the attribute
* @return an object managing the error
* @see SKGError
*/
virtual SKGError setAttribute(const QString& iName, const QString& iValue);
/**
* Set the values for attributes
* @param iNames list of attributes
* @param iValues list of values
* @return an object managing the error
* @see SKGError
*/
virtual SKGError setAttributes(const QStringList& iNames, const QStringList& iValues);
/**
* Get the list of properties
* @return the list of properties
*/
virtual QStringList getProperties() const;
/**
* Get the value for a property
* @param iName the name of the property
* @return the value of this property
*/
virtual QString getProperty(const QString& iName) const;
/**
* Get the property
* @param iName the name of the property
* @return the property
*/
virtual SKGObjectBase getPropertyObject(const QString& iName) const;
/**
* Get the blob for a property
* @param iName the name of the property
* @return the blob of this property
*/
virtual QVariant getPropertyBlob(const QString& iName) const;
/**
* Set the value for a property
* @param iName the property name
* @param iValue the property value
* @param iFileName the file name.
* @param oObjectCreated the property object created. Can be nullptr
* @return an object managing the property
* @see SKGError
*/
virtual SKGError setProperty(const QString& iName, const QString& iValue,
const QString& iFileName,
SKGPropertyObject* oObjectCreated = nullptr) const;
/**
* Set the value for a property
* @param iName the property name
* @param iValue the property value
* @param iBlob the property blob
* @param oObjectCreated the property object created. Can be nullptr
* @return an object managing the property
* @see SKGError
*/
virtual SKGError setProperty(const QString& iName, const QString& iValue,
const QVariant& iBlob = QVariant(),
SKGPropertyObject* oObjectCreated = nullptr) const;
/**
* To know if an object exists or not
* @return "true" if the object exists else "false".
*/
virtual bool exist() const;
/**
* load or reload the object from the database
* @return an object managing the error
* @see SKGError
*/
SKGError load();
/**
* save the object into the database
* @param iInsertOrUpdate the save mode.
* true: try an insert, if the insert failed then try an update.
* false: try an insert, if the insert failed then return an error.
* @param iReloadAfterSave to reload the object after save. Set false if you are sure that you will not use this object after save
* @return an object managing the error
* @see SKGError
*/
virtual SKGError save(bool iInsertOrUpdate = true, bool iReloadAfterSave = true);
/**
* delete the object into the database
* @param iSendMessage to send message when the object is deleted
* @param iForce to force the deletion
* @return an object managing the error
* @see SKGError
*/
virtual SKGError remove(bool iSendMessage = true, bool iForce = false) const;
/**
* dump the object
* @return an object managing the error
* @see SKGError
*/
virtual SKGError dump() const;
protected:
/**
* Copy from an existing object
* @param iObject the object to copy
*/
void copyFrom(const SKGObjectBase& iObject);
/**
* Get where clause needed to identify objects.
* For this class, the whereclause is based on id
* @return the where clause
*/
virtual QString getWhereclauseId() const;
Q_SIGNALS:
/**
* This signal is launched when the object is modified
*/
void modified();
private:
SKGObjectBasePrivate* d;
};
/**
* Declare the meta type
*/
Q_DECLARE_METATYPE(SKGObjectBase)
/**
* Declare the class
*/
Q_DECLARE_TYPEINFO(SKGObjectBase, Q_MOVABLE_TYPE);
/**
* Declare the meta type
*/
Q_DECLARE_METATYPE(SKGObjectBase::SKGListSKGObjectBase)
#endif
diff --git a/skgbasemodeler/skgpropertyobject.cpp b/skgbasemodeler/skgpropertyobject.cpp
index b2b2a06b2..33e427102 100644
--- a/skgbasemodeler/skgpropertyobject.cpp
+++ b/skgbasemodeler/skgpropertyobject.cpp
@@ -1,126 +1,126 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file implements classes SKGPropertyObject.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgpropertyobject.h"
#include <qdir.h>
SKGPropertyObject::SKGPropertyObject(): SKGPropertyObject(nullptr)
{}
SKGPropertyObject::SKGPropertyObject(SKGDocument* iDocument, int iID): SKGNamedObject(iDocument, QStringLiteral("parameters"), iID)
{}
SKGPropertyObject::~SKGPropertyObject()
= default;
SKGPropertyObject::SKGPropertyObject(const SKGPropertyObject& iObject) = default;
SKGPropertyObject::SKGPropertyObject(const SKGObjectBase& iObject) : SKGNamedObject(iObject.getDocument(), QStringLiteral("parameters"), iObject.getID())
{}
SKGPropertyObject& SKGPropertyObject::operator= (const SKGObjectBase& iObject)
{
copyFrom(iObject);
return *this;
}
SKGError SKGPropertyObject::setParentId(const QString& iParentId)
{
return setAttribute(QStringLiteral("t_uuid_parent"), iParentId);
}
QString SKGPropertyObject::getParentId() const
{
return getAttribute(QStringLiteral("t_uuid_parent"));
}
SKGError SKGPropertyObject::setValue(const QString& iValue)
{
return setAttribute(QStringLiteral("t_value"), iValue);
}
QString SKGPropertyObject::getValue() const
{
return getAttribute(QStringLiteral("t_value"));
}
QUrl SKGPropertyObject::getUrl(bool iBuildTemporaryFile) const
{
QUrl url;
if (getID() != 0) {
QStringList uuid = getParentId().split('-');
if (uuid.count() == 2) {
SKGObjectBase p(getDocument(), uuid.at(1), SKGServices::stringToInt(uuid.at(0)));
QVariant blob = p.getPropertyBlob(getName());
// Is it a copied file ?
if (!blob.isNull()) {
// Yes, this is a file
QString fileName = QDir::tempPath() % '/' % QFileInfo(getValue()).fileName();
if (iBuildTemporaryFile) {
// Yes, this is a file
QByteArray blob_bytes = blob.toByteArray();
// Save temporary file
QFile file(fileName);
file.setPermissions(QFile::ReadOwner | QFile::WriteOwner);
if (file.open(QIODevice::WriteOnly)) {
file.write(blob_bytes);
file.flush();
file.close();
file.setPermissions(QFile::ReadOwner); // To be sure that no modifications are done
}
}
url = QUrl::fromLocalFile(fileName);
} else if (QFile(getValue()).exists()) {
// Is it a linked file? Yes
url = QUrl::fromLocalFile(getValue());
} else {
// Is it a linked file? No, Is it a http url ?
QUrl url2 = QUrl(getValue());
if (!url2.scheme().isEmpty()) {
url = url2;
}
}
}
}
return url;
}
QString SKGPropertyObject::getWhereclauseId() const
{
// Could we use the id
QString output = SKGObjectBase::getWhereclauseId(); // clazy:exclude=skipped-base-method
if (output.isEmpty()) {
if (!(getAttribute(QStringLiteral("t_name")).isEmpty())) {
output = "t_name='" % SKGServices::stringToSqlString(getAttribute(QStringLiteral("t_name"))) % '\'';
}
if (!(getParentId().isEmpty())) {
if (!output.isEmpty()) {
output += QStringLiteral(" AND ");
}
output += "t_uuid_parent='" % getParentId() % '\'';
}
}
return output;
}
diff --git a/skgbasemodeler/skgpropertyobject.h b/skgbasemodeler/skgpropertyobject.h
index 445eae538..b72bb0b11 100644
--- a/skgbasemodeler/skgpropertyobject.h
+++ b/skgbasemodeler/skgpropertyobject.h
@@ -1,126 +1,126 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGPROPERTYOBJECT_H
#define SKGPROPERTYOBJECT_H
/** @file
* This file defines classes SKGPropertyObject.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgdefine.h"
#include "skgnamedobject.h"
class SKGDocument;
/**
* This class manages properties on objects
*/
class SKGBASEMODELER_EXPORT SKGPropertyObject final : public SKGNamedObject
{
Q_OBJECT
/**
* Value of the property
*/
Q_PROPERTY(QString value READ getValue WRITE setValue) // clazy:exclude=qproperty-without-notify
/**
* Parent identifier of the property
*/
Q_PROPERTY(QString parentId READ getParentId WRITE setParentId) // clazy:exclude=qproperty-without-notify
public:
/**
* Default constructor
*/
explicit SKGPropertyObject();
/**
* Constructor
* @param iDocument the document containing the object
* @param iID the identifier in @p iTable of the object
*/
explicit SKGPropertyObject(SKGDocument* iDocument, int iID = 0);
/**
* Copy constructor
* @param iObject the object to copy
*/
SKGPropertyObject(const SKGPropertyObject& iObject);
/**
* Copy constructor
* @param iObject the object to copy
*/
explicit SKGPropertyObject(const SKGObjectBase& iObject);
/**
* Operator affectation
* @param iObject the object to copy
*/
SKGPropertyObject& operator= (const SKGObjectBase& iObject);
/**
* Destructor
*/
~SKGPropertyObject() override;
/**
* Set the value of the property
* @param iValue the value of the property
* @return an object managing the error.
* @see SKGError
*/
SKGError setValue(const QString& iValue);
/**
* Get the value of the property
* @return the value of the property
*/
QString getValue() const;
/**
* Set the parent identifier
* @param iParentId the parent identifier
* @return an object managing the error.
* @see SKGError
*/
SKGError setParentId(const QString& iParentId);
/**
* Get the parent identifier
* @return the parent identifier
*/
QString getParentId() const;
/**
* Get the url of the property
* @param iBuildTemporaryFile to build the temporary file if needed
* @return the url of the property
*/
QUrl getUrl(bool iBuildTemporaryFile = false) const;
protected:
/**
* Get where clause needed to identify objects.
* For this class, the whereclause is based on name + t_uuid_parent
* @return the where clause
*/
QString getWhereclauseId() const override;
};
/**
* Declare the class
*/
Q_DECLARE_TYPEINFO(SKGPropertyObject, Q_MOVABLE_TYPE);
#endif
diff --git a/skgbasemodeler/skgreport.cpp b/skgbasemodeler/skgreport.cpp
index 09629af8b..60c14d329 100644
--- a/skgbasemodeler/skgreport.cpp
+++ b/skgbasemodeler/skgreport.cpp
@@ -1,243 +1,243 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* A report class for document
*
* @author Stephane MANKOWSKI
*/
#include "skgreport.h"
#include <grantlee/engine.h>
#include <grantlee/metatype.h>
#include <grantlee/qtlocalizer.h>
#include <grantlee/templateloader.h>
#include <kaboutdata.h>
#include <kcolorscheme.h>
#include <qdir.h>
#include <qfile.h>
#include <qfont.h>
#include <qfontdatabase.h>
#include <qstandardpaths.h>
#include <qurl.h>
#include "skgdocument.h"
#include "skgobjectbase.h"
#include "skgtraces.h"
GRANTLEE_BEGIN_LOOKUP(SKGObjectBase)
Q_UNUSED(object)
Q_UNUSED(property)
GRANTLEE_END_LOOKUP
SKGReport::SKGReport(SKGDocument* iDocument)
: m_document(iDocument), m_previous(nullptr), m_pointSize(10)
{
SKGTRACEINFUNC(1)
// Grantlee initialization
Grantlee::registerMetaType<SKGObjectBase>();
}
SKGReport::~SKGReport()
{
SKGTRACEINFUNC(1)
if (m_previous != nullptr) {
delete m_previous;
m_previous = nullptr;
}
}
void SKGReport::setPeriod(const QString& iPeriod)
{
if (iPeriod != m_cache[QStringLiteral("period")]) {
cleanCache(false);
if (m_previous != nullptr) {
delete m_previous;
m_previous = nullptr;
}
m_cache[QStringLiteral("period")] = iPeriod;
emit changed();
}
}
QString SKGReport::getPeriod()
{
QString month = m_cache.value(QStringLiteral("period")).toString();
if (month.isEmpty()) {
month = QDate::currentDate().toString(QStringLiteral("yyyy-MM"));
m_cache[QStringLiteral("period")] = month;
}
return month;
}
QString SKGReport::getPreviousPeriod()
{
QString previousmonth = m_cache.value(QStringLiteral("previousperiod")).toString();
if (previousmonth.isEmpty()) {
QString period = getPeriod();
if (!period.isEmpty()) {
previousmonth = SKGServices::getNeighboringPeriod(period);
}
m_cache[QStringLiteral("previousperiod")] = previousmonth;
}
return previousmonth;
}
SKGReport* SKGReport::getPrevious()
{
if (m_previous == nullptr) {
m_previous = m_document->getReport();
m_previous->setPeriod(getPreviousPeriod());
}
return m_previous;
}
void SKGReport::setTipsOfDay(const QStringList& iTipsOfDays)
{
m_tipsOfTheDay = iTipsOfDays;
emit changed();
}
QString SKGReport::getTipOfDay() const
{
auto tips = getTipsOfDay();
auto tip = tips.count() > 0 ? SKGServices::htmlToString(tips.at(qrand() % tips.size())) : QString();
return tip;
}
QStringList SKGReport::getTipsOfDay() const
{
return m_tipsOfTheDay;
}
QVariantHash SKGReport::getContextProperty()
{
QVariantHash mapping;
addItemsInMapping(mapping);
if (m_document != nullptr) {
mapping.insert(QStringLiteral("document"), QVariant::fromValue<QObject*>(m_document));
}
return mapping;
}
void SKGReport::addItemsInMapping(QVariantHash& iMapping)
{
iMapping.insert(QStringLiteral("report"), QVariant::fromValue<QObject*>(this));
iMapping.insert(QStringLiteral("current_date"), QDate::currentDate());
KColorScheme scheme(QPalette::Normal, KColorScheme::Window);
iMapping.insert(QStringLiteral("color_negativetext"), scheme.foreground(KColorScheme::NegativeText).color().name().right(6));
iMapping.insert(QStringLiteral("color_positivetext"), scheme.foreground(KColorScheme::PositiveText).color().name().right(6));
iMapping.insert(QStringLiteral("color_neutraltext"), scheme.foreground(KColorScheme::NeutralText).color().name().right(6));
iMapping.insert(QStringLiteral("color_normaltext"), scheme.foreground(KColorScheme::NormalText).color().name().right(6));
iMapping.insert(QStringLiteral("color_inactivetext"), scheme.foreground(KColorScheme::InactiveText).color().name().right(6));
iMapping.insert(QStringLiteral("color_activetext"), scheme.foreground(KColorScheme::ActiveText).color().name().right(6));
iMapping.insert(QStringLiteral("color_linktext"), scheme.foreground(KColorScheme::LinkText).color().name().right(6));
iMapping.insert(QStringLiteral("color_visitedtext"), scheme.foreground(KColorScheme::VisitedText).color().name().right(6));
iMapping.insert(QStringLiteral("color_normalbackground"), scheme.background(KColorScheme::NormalBackground).color().name().right(6));
iMapping.insert(QStringLiteral("color_activebackground"), scheme.background(KColorScheme::ActiveBackground).color().name().right(6));
QFont generalFont = QFontDatabase::systemFont(QFontDatabase::GeneralFont);
iMapping.insert(QStringLiteral("font_family"), generalFont.family());
QString dir = "file://" % QFileInfo(QStandardPaths::locate(QStandardPaths::GenericDataLocation, QStringLiteral("kf5/infopage/kde_infopage.css"))).dir().absolutePath() % '/';
{
QFile file(QStandardPaths::locate(QStandardPaths::GenericDataLocation, QStringLiteral("kf5/infopage/kde_infopage.css")));
if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
iMapping.insert(QStringLiteral("kde_infopage_css"), QString(file.readAll()).replace(QStringLiteral("url("), "url(" % dir));
}
}
KAboutData about = KAboutData::applicationData();
iMapping.insert(QStringLiteral("about_welcome"), i18nc("Welcome message", "Welcome to %1", about.displayName()));
iMapping.insert(QStringLiteral("about_programname"), about.displayName());
iMapping.insert(QStringLiteral("about_version"), about.version());
iMapping.insert(QStringLiteral("about_bugaddress"), about.bugAddress());
iMapping.insert(QStringLiteral("about_copyrightstatement"), about.copyrightStatement());
iMapping.insert(QStringLiteral("about_homepage"), about.homepage());
iMapping.insert(QStringLiteral("about_shortdescription"), about.shortDescription());
iMapping.insert(QStringLiteral("about_othertext"), about.otherText());
iMapping.insert(QStringLiteral("about_did_you_know"), i18nc("Title for tips of the day", "Did you know ...?"));
}
SKGError SKGReport::getReportFromTemplate(SKGReport* iReport, const QString& iFile, QString& oHtml)
{
SKGError err;
SKGTRACEINFUNCRC(10, err)
// Prepare grantlee engine
Grantlee::Engine gEngine;
gEngine.addDefaultLibrary(QStringLiteral("grantlee_skgfilters"));
QSharedPointer<Grantlee::FileSystemTemplateLoader> gLoader = QSharedPointer<Grantlee::FileSystemTemplateLoader>(new Grantlee::FileSystemTemplateLoader());
gLoader->setTemplateDirs(QStringList(QFileInfo(iFile).dir().absolutePath()));
gEngine.addTemplateLoader(gLoader);
Grantlee::Template gTemplate = gEngine.loadByName(QFileInfo(iFile).fileName());
if (gTemplate->error() != 0u) {
err = SKGError(gTemplate->error(), gTemplate->errorString());
} else {
QVariantHash mapping;
if (iReport != nullptr) {
mapping = iReport->getContextProperty();
}
Grantlee::Context gContext(mapping);
// Generation
{
SKGTRACEINFUNCRC(10, err)
oHtml = gTemplate->render(&gContext);
QRegExp rx(QStringLiteral("\\n\\s*\\n"));
oHtml = oHtml.replace(rx, QStringLiteral("\n"));
if (gTemplate->error() != 0u) {
err = SKGError(gTemplate->error(), gTemplate->errorString());
}
}
}
return err;
}
void SKGReport::cleanCache(bool iEmitSignal)
{
QString month = m_cache.value(QStringLiteral("period")).toString();
m_cache.clear();
if (!month.isEmpty()) {
m_cache[QStringLiteral("period")] = month;
}
if (iEmitSignal) {
emit changed();
}
}
void SKGReport::addParameter(const QString& iName, const QVariant& ivalue)
{
m_parameters[iName] = ivalue;
}
void SKGReport::setPointSize(int iPointSize)
{
m_pointSize = iPointSize;
emit changed();
}
int SKGReport::getPointSize() const
{
return m_pointSize;
}
diff --git a/skgbasemodeler/skgreport.h b/skgbasemodeler/skgreport.h
index f6d4f79a8..d12e3dcf6 100644
--- a/skgbasemodeler/skgreport.h
+++ b/skgbasemodeler/skgreport.h
@@ -1,202 +1,202 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGREPORT_H
#define SKGREPORT_H
/** @file
* A report class for document
*
* @author Stephane MANKOWSKI
*/
#include <qobject.h>
#include <qvariant.h>
#include "skgbasemodeler_export.h"
#include "skgerror.h"
class SKGDocument;
/**
* A report class for document
*/
class SKGBASEMODELER_EXPORT SKGReport : public QObject
{
Q_OBJECT
/**
* The period
*/
Q_PROPERTY(QString period READ getPeriod WRITE setPeriod NOTIFY changed)
/**
* The month (for compatibility in templates)
* WARNING: Notification is launched only when cleanCache or setPeriod are called. So do not forget to connect cleanCache with SKGDocument::transactionSuccessfullyEnded
*/
Q_PROPERTY(QString month READ getPeriod NOTIFY changed)
/**
* The previous object
* WARNING: Notification is launched only when cleanCache or setPeriod are called. So do not forget to connect cleanCache with SKGDocument::transactionSuccessfullyEnded
*/
Q_PROPERTY(SKGReport* previous READ getPrevious NOTIFY changed)
/**
* The previous period
* WARNING: Notification is launched only when cleanCache or setPeriod are called. So do not forget to connect cleanCache with SKGDocument::transactionSuccessfullyEnded
*/
Q_PROPERTY(QString previous_period READ getPreviousPeriod NOTIFY changed)
/**
* The previous month (for compatibility in templates)
* WARNING: Notification is launched only when cleanCache or setPeriod are called. So do not forget to connect cleanCache with SKGDocument::transactionSuccessfullyEnded
*/
Q_PROPERTY(QString previous_month READ getPreviousPeriod NOTIFY changed)
/**
* The zoom factor
*/
Q_PROPERTY(double point_size READ getPointSize WRITE setPointSize NOTIFY changed)
/**
* The tips of the day
*/
Q_PROPERTY(QStringList tips_of_day READ getTipsOfDay WRITE setTipsOfDay NOTIFY changed)
/**
* The tip of the day
*/
Q_PROPERTY(QString tip_of_day READ getTipOfDay NOTIFY changed)
public:
/**
* Default Constructor
*/
explicit SKGReport(SKGDocument* iDocument);
/**
* Default Destructor
*/
~SKGReport() override;
/**
* Set the current period
* @param iPeriod the period
*/
Q_INVOKABLE virtual void setPeriod(const QString& iPeriod);
/**
* Get the current period
* @return the current period
*/
Q_INVOKABLE virtual QString getPeriod();
/**
* Get the previous period
* @return the previous period
*/
Q_INVOKABLE virtual QString getPreviousPeriod();
/**
* Get the previous report
* @return the previous report (MUST NOT BE REMOVED)
*/
Q_INVOKABLE virtual SKGReport* getPrevious();
/**
* Set the font point size
* @param iPointSize font point size
*/
Q_INVOKABLE virtual void setPointSize(int iPointSize);
/**
* Get the font point
* @return the font point
*/
Q_INVOKABLE virtual int getPointSize() const;
/**
* Set the tips of the day
* @param iTipsOfDays the tips of the day
*/
Q_INVOKABLE virtual void setTipsOfDay(const QStringList& iTipsOfDays);
/**
* Get the tip of the day
* @return the tip of the day
*/
Q_INVOKABLE virtual QString getTipOfDay() const;
/**
* Get the tips of the day
* @return the tips of the day
*/
Q_INVOKABLE virtual QStringList getTipsOfDay() const;
/**
* Clean the cache
* @param iEmitSignal to emit modification signal
*/
Q_INVOKABLE virtual void cleanCache(bool iEmitSignal = true);
/**
* The context properties
*/
Q_INVOKABLE virtual QVariantHash getContextProperty();
/**
* To add a parameter for a computation
* @param iName the name of the parameter
* @param ivalue the value of the parameter
*/
Q_INVOKABLE virtual void addParameter(const QString& iName, const QVariant& ivalue);
/**
* Get report
* @param iReport the report
* @param iFile the template file name
* @param oHtml the html report
* @return an object managing the error
* @see SKGError
*/
static SKGError getReportFromTemplate(SKGReport* iReport, const QString& iFile, QString& oHtml);
Q_SIGNALS:
/**
* Emitted when the report changed
*/
void changed();
protected:
/**
* Enrich the grantlee mapping
* @param iMapping the mapping
*/
Q_INVOKABLE virtual void addItemsInMapping(QVariantHash& iMapping);
SKGDocument* m_document;
SKGReport* m_previous;
QHash<QString, QVariant> m_cache;
QHash<QString, QVariant> m_parameters;
int m_pointSize;
QStringList m_tipsOfTheDay;
private:
Q_DISABLE_COPY(SKGReport)
};
/**
* Declare the class
*/
Q_DECLARE_TYPEINFO(SKGReport, Q_MOVABLE_TYPE);
#endif // SKGREPORT_H
diff --git a/skgbasemodeler/skgservices.cpp b/skgbasemodeler/skgservices.cpp
index f1b1fbc11..1b410ec05 100644
--- a/skgbasemodeler/skgservices.cpp
+++ b/skgbasemodeler/skgservices.cpp
@@ -1,2042 +1,2042 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file implements classes SKGServices.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgservices.h"
#include <kaboutdata.h>
#include <kiconloader.h>
#include <kio/filecopyjob.h>
#include <klocalizedstring.h>
#ifndef Q_OS_WIN
#include <sys/time.h>
#endif
#include <qapplication.h>
#include <qca.h>
#include <qdom.h>
#include <qfile.h>
#include <qlocale.h>
#include <qmath.h>
#include <qregexp.h>
#include <qsavefile.h>
#include <qscriptengine.h>
#include <qsqldatabase.h>
#include <qsqldriver.h>
#include <qsqlerror.h>
#include <qsqlquery.h>
#include <qsqlrecord.h>
#include <qstandardpaths.h>
#include <qtemporaryfile.h>
#include <qvariant.h>
#include "skgdocument.h"
#include "skgtraces.h"
#define SQLCIPHERHEARDER "SQLCipher format"
int SKGServices::SKGSqlTraces = (SKGServices::getEnvVariable(QStringLiteral("SKGTRACESQL")).isEmpty() ? -1 : SKGServices::stringToInt(SKGServices::getEnvVariable(QStringLiteral("SKGTRACESQL"))));
SKGError SKGServices::m_lastCallbackError;
QString SKGServices::searchCriteriasToWhereClause(const SKGServices::SKGSearchCriteriaList& iSearchCriterias, const QStringList& iAttributes, const SKGDocument* iDocument, bool iForDisplay)
{
QString whereclause;
int nbCriterias = iSearchCriterias.count();
int nbAttributes = iAttributes.count();
for (int i = 0; i < nbCriterias; ++i) {
SKGSearchCriteria criteria = iSearchCriterias.at(i);
QString subWhereClause;
int nbWords = criteria.words.count();
for (int w = 0; w < nbWords; ++w) {
QString subWhereClause2;
QString word = criteria.words[w].toLower();
QString att;
QString op(':');
bool modeStartWith = true;
// Check if the word follows the format attribute:value
int pos = word.indexOf(QStringLiteral(":"));
int pos2 = word.indexOf(QStringLiteral("<="));
int pos3 = word.indexOf(QStringLiteral(">="));
int pos4 = word.indexOf(QStringLiteral("="));
int pos5 = word.indexOf(QStringLiteral("<"));
int pos6 = word.indexOf(QStringLiteral(">"));
int pos7 = word.indexOf(QStringLiteral("#"));
int opLength = 1;
if (pos2 != -1 && (pos2 < pos || pos == -1)) {
pos = pos2;
opLength = 2;
}
if (pos3 != -1 && (pos3 < pos || pos == -1)) {
pos = pos3;
opLength = 2;
}
if (pos4 != -1 && (pos4 < pos || pos == -1)) {
pos = pos4;
}
if (pos5 != -1 && (pos5 < pos || pos == -1)) {
pos = pos5;
}
if (pos6 != -1 && (pos6 < pos || pos == -1)) {
pos = pos6;
}
if (pos7 != -1 && (pos7 < pos || pos == -1)) {
pos = pos7;
}
if (pos != -1) {
att = word.left(pos);
if (att.endsWith(QStringLiteral("."))) {
modeStartWith = false;
att = att.left(att.count() - 1);
}
op = word.mid(pos, opLength);
word = word.right(word.count() - pos - op.count());
}
word = SKGServices::stringToSqlString(word);
for (int j = 0; j < nbAttributes; ++j) {
QString attDatabase = iAttributes.at(j);
QString attForComparison = (iDocument != nullptr ? iDocument->getDisplay(attDatabase) : attDatabase).toLower();
if (att.isEmpty() ||
(modeStartWith && attForComparison.startsWith(att)) ||
(!modeStartWith && attForComparison.compare(att, Qt::CaseInsensitive) == 0)) {
if (iForDisplay) {
QString n = attForComparison + op + word;
if (subWhereClause2.isEmpty()) {
subWhereClause2 = n;
} else {
subWhereClause2 = i18nc("Logical condition", "%1 or %2", subWhereClause2, n);
}
} else {
if (!subWhereClause2.isEmpty()) {
subWhereClause2 = subWhereClause2 % " OR ";
}
if (attDatabase.startsWith(QLatin1String("p_"))) {
// Case property
QString propName = attDatabase.right(attDatabase.length() - 2);
if (op == QStringLiteral(":")) {
subWhereClause2 = subWhereClause2 % "i_PROPPNAME='" % SKGServices::stringToSqlString(propName) % "' AND (lower(i_PROPVALUE) LIKE '%" % word % "%')";
} else if (op == QStringLiteral("#")) {
subWhereClause2 = subWhereClause2 % "i_PROPPNAME='" % SKGServices::stringToSqlString(propName) % "' AND REGEXP('" % word % "',i_PROPVALUE)";
} else {
attDatabase = "i_PROPPNAME='" % SKGServices::stringToSqlString(propName) % "' AND i_PROPVALUE";
subWhereClause2 = subWhereClause2 % attDatabase % op % word;
}
} else {
// Case normal attribute
if (op == QStringLiteral(":")) {
subWhereClause2 = subWhereClause2 % "lower(" % attDatabase % ") LIKE '%" % word % "%'";
} else if (op == QStringLiteral("#")) {
subWhereClause2 = subWhereClause2 % "REGEXP('" % word % "'," % attDatabase % ")";
} else {
if (attDatabase.startsWith(QLatin1String("f_")) || attDatabase.startsWith(QLatin1String("i_"))) {
subWhereClause2 = subWhereClause2 % attDatabase % op % word;
} else {
subWhereClause2 = subWhereClause2 % "lower(" % attDatabase % ")" % op % "'" % word % "'";
}
}
}
}
}
}
if (iForDisplay) {
if (!subWhereClause2.isEmpty()) {
if (subWhereClause.isEmpty()) {
subWhereClause = subWhereClause2;
} else {
subWhereClause = i18nc("Logical condition", "(%1) and (%2)", subWhereClause, subWhereClause2);
}
}
} else {
if (!subWhereClause2.isEmpty()) {
if (!subWhereClause.isEmpty()) {
subWhereClause = subWhereClause % " AND ";
}
subWhereClause = subWhereClause % "(" % subWhereClause2 % ")";
} else {
subWhereClause = QStringLiteral("1=0");
}
}
}
if (iForDisplay) {
if (!subWhereClause.isEmpty()) {
if (criteria.mode == '+') {
if (whereclause.isEmpty()) {
whereclause = subWhereClause;
} else {
whereclause = i18nc("Logical condition", "(%1) and (%2)", whereclause, subWhereClause);
}
} else if (criteria.mode == '-') {
if (subWhereClause.isEmpty()) {
whereclause = i18nc("Logical condition", "not (%1)", subWhereClause);
} else {
whereclause = i18nc("Logical condition", "(%1) and not (%2)", whereclause, subWhereClause);
}
}
}
} else {
if (!subWhereClause.isEmpty()) {
if (criteria.mode == '+') {
if (!whereclause.isEmpty()) {
whereclause = whereclause % " OR ";
}
whereclause = whereclause % "(" % subWhereClause % ")";
} else if (criteria.mode == '-') {
if (!whereclause.isEmpty()) {
whereclause = whereclause % " AND NOT";
} else {
whereclause = QStringLiteral("NOT");
}
whereclause = whereclause % "(" % subWhereClause % ")";
}
}
}
}
return whereclause;
}
SKGServices::SKGSearchCriteriaList SKGServices::stringToSearchCriterias(const QString& iString)
{
SKGServices::SKGSearchCriteriaList output;
QStringList words = SKGServices::splitCSVLine(iString, ' ', true);
int nbwords = words.count();
output.reserve(nbwords);
SKGServices::SKGSearchCriteria criteria;
criteria.mode = '+';
bool atLeastOnePlus = false;
for (int i = 0; i < nbwords; ++i) {
QString word = words.at(i);
bool isWordStartingByPlus = word.startsWith(QLatin1String("+"));
bool isWordStartingByLess = word.startsWith(QLatin1String("-"));
if (isWordStartingByPlus || isWordStartingByLess) {
QChar nextChar;
if (word.count() > 1) {
nextChar = word[1];
}
if (nextChar < '0' || nextChar > '9') {
word = word.right(word.length() - 1);
if (Q_LIKELY(i != 0)) {
if (criteria.mode == '-') {
output.push_back(criteria);
} else {
output.push_front(criteria);
atLeastOnePlus = true;
}
}
criteria.words.clear();
criteria.mode = (isWordStartingByPlus ? '+' : '-');
}
}
criteria.words.push_back(word);
}
if (criteria.mode == '-') {
output.push_back(criteria);
} else {
output.push_front(criteria);
atLeastOnePlus = true;
}
if (!atLeastOnePlus) {
// Add a '+' always true
SKGServices::SKGSearchCriteria criteria2;
criteria2.mode = '+';
criteria2.words.push_back(QLatin1String(""));
output.push_front(criteria2);
}
return output;
}
QString SKGServices::getEnvVariable(const QString& iAttribute)
{
return QString::fromUtf8(qgetenv(iAttribute.toUtf8().constData()));
}
QString SKGServices::intToString(qlonglong iNumber)
{
QString output;
output.setNum(iNumber);
return output;
}
qlonglong SKGServices::stringToInt(const QString& iNumber)
{
if (Q_UNLIKELY(iNumber.isEmpty())) {
return 0;
}
bool ok;
qlonglong output = iNumber.toLongLong(&ok);
if (Q_LIKELY(!ok)) {
SKGTRACE << "WARNING: SKGServices::stringToInt(" << iNumber << ") failed" << endl;
}
return output;
}
QString SKGServices::stringToSqlString(const QString& iString)
{
QString output;
for (const auto& c : iString) {
if (c.isPrint() || c == QChar('\n')) {
output.append(QChar(c));
}
}
output.replace('\'', QStringLiteral("''"));
return output;
}
QString SKGServices::stringToHtml(const QString& iString)
{
QString output = iString;
output.replace('&', QStringLiteral("&amp;")); // Must be done first
output.replace('<', QStringLiteral("&lt;"));
output.replace('>', QStringLiteral("&gt;"));
output.replace('"', QStringLiteral("&quot;"));
return output;
}
QString SKGServices::htmlToString(const QString& iString)
{
QString output = iString;
output.replace(QStringLiteral("&lt;"), QStringLiteral("<"));
output.replace(QStringLiteral("&gt;"), QStringLiteral(">"));
output.replace(QStringLiteral("&quot;"), QStringLiteral("\""));
output.replace(QStringLiteral("&amp;"), QStringLiteral("&"));
return output;
}
QString SKGServices::stringsToCsv(const QStringList& iList, QChar iSeparator)
{
QString output;
int nb = iList.count();
for (int i = 0; i < nb; ++i) {
output.append(SKGServices::stringToCsv(iList.at(i)));
if (Q_LIKELY(i < nb - 1)) {
output.append(iSeparator);
}
}
return output;
}
QString SKGServices::stringToCsv(const QString& iNumber)
{
QString output = iNumber;
output.replace('"', QStringLiteral("#SKGDOUBLECOTE#"));
output.replace(QStringLiteral("#SKGDOUBLECOTE#"), QStringLiteral("\"\""));
output = '"' % output % '"';
return output;
}
double SKGServices::stringToDouble(const QString& iNumber)
{
if (Q_UNLIKELY(iNumber.isEmpty() || iNumber == QStringLiteral("nan"))) {
return 0;
}
if (Q_UNLIKELY(iNumber == QStringLiteral("inf"))) {
return 1e300;
}
if (Q_UNLIKELY(iNumber == QStringLiteral("-inf"))) {
return -1e300;
}
QString number = iNumber;
number.remove(QRegExp(QStringLiteral("[^0-9-+/eE,.]")));
if (number.contains(QStringLiteral("/"))) {
// Use script engine
QScriptEngine myEngine;
QScriptValue result = myEngine.evaluate(number);
if (result.isNumber()) {
return result.toNumber();
}
}
bool ok;
double output = number.toDouble(&ok);
if (Q_LIKELY(!ok)) {
QString tmp = number;
tmp.replace(',', '.');
if (tmp.count('.') > 1) {
tmp.remove(tmp.indexOf('.'), 1);
}
output = tmp.toDouble(&ok);
if (Q_LIKELY(!ok)) {
QString tmp2 = number;
tmp2.replace('.', ',');
if (tmp2.count(',') > 1) {
tmp2.remove(tmp2.indexOf(','), 1);
}
output = tmp2.toDouble(&ok);
if (!ok) {
QString tmp3 = number;
tmp3.remove(',');
output = tmp3.toDouble(&ok);
}
}
}
if (Q_LIKELY(!ok)) {
SKGTRACE << "WARNING: SKGServices::stringToDouble(" << iNumber << ") failed" << endl;
}
return output;
}
QString SKGServices::doubleToString(double iNumber)
{
QString output;
output.setNum(iNumber, 'g', 10);
return output;
}
QString SKGServices::getNextString(const QString& iString)
{
QString output = iString;
bool ok;
qlonglong val = output.toLongLong(&ok);
if (Q_LIKELY(ok)) {
// This is a int
output = SKGServices::intToString(val + 1);
} else {
// This is a string
output = QLatin1String("");
}
return output;
}
QString SKGServices::dateToPeriod(QDate iDate, const QString& iPeriod)
{
QString period;
if (iPeriod == QStringLiteral("D")) {
// Day
period = iDate.toString(QStringLiteral("yyyy-MM-dd"));
} else if (iPeriod == QStringLiteral("W")) {
// Week
period = iDate.toString(QStringLiteral("yyyy-W")) % SKGServices::intToString(iDate.weekNumber()).rightJustified(2, '0');
} else if (iPeriod == QStringLiteral("M")) {
// Month
period = iDate.toString(QStringLiteral("yyyy-MM"));
} else if (iPeriod == QStringLiteral("Q")) {
// Quarter
period = iDate.toString(QStringLiteral("yyyy-Q")) % (iDate.month() <= 3 ? '1' : (iDate.month() <= 6 ? '2' : (iDate.month() <= 9 ? '3' : '4')));
} else if (iPeriod == QStringLiteral("S")) {
// Semester
period = iDate.toString(QStringLiteral("yyyy-S")) % (iDate.month() <= 6 ? '1' : '2');
} else if (iPeriod == QStringLiteral("Y")) {
// Year
period = iDate.toString(QStringLiteral("yyyy"));
}
return period;
}
QString SKGServices::timeToString(const QDateTime& iDateTime)
{
QDateTime d = iDateTime;
if (Q_UNLIKELY(!d.isValid())) {
d = QDateTime::currentDateTime();
}
return d.toString(QStringLiteral("yyyy-MM-dd HH:mm:ss"));
}
QString SKGServices::dateToSqlString(QDate iDate)
{
return dateToSqlString(QDateTime(iDate));
}
QString SKGServices::dateToSqlString(const QDateTime& iDateTime)
{
QDateTime d = iDateTime;
if (Q_UNLIKELY(!d.isValid())) {
d = QDateTime::currentDateTime();
}
return d.toString(QStringLiteral("yyyy-MM-dd"));
}
int SKGServices::nbWorkingDays(QDate iFrom, QDate iTo)
{
int nb = 0;
QDate min = (iFrom < iTo ? iFrom : iTo);
QDate max = (iFrom < iTo ? iTo : iFrom);
while (min != max) {
if (min.dayOfWeek() <= 5) {
++nb;
}
min = min.addDays(1);
}
if (nb == 0) {
nb = 1;
}
return nb;
}
QDateTime SKGServices::stringToTime(const QString& iDateString)
{
QDateTime output = QDateTime::fromString(iDateString, QStringLiteral("yyyy-MM-dd HH:mm:ss"));
if (Q_UNLIKELY(!output.isValid())) {
output = QDateTime::fromString(iDateString, QStringLiteral("yyyy-MM-dd"));
}
return output;
}
QDate SKGServices::partialStringToDate(const QString& iDateString, bool iFixupBackward)
{
QDate result;
QStringList items = iDateString.split('/');
int size = items.count();
bool ok = false;
if (size == 1) {
int dayCount = items.at(0).toInt(&ok);
result = QDate::currentDate();
result = result.addDays(dayCount - result.day());
if (iFixupBackward) {
if (result > QDate::currentDate()) {
result = result.addMonths(-1);
}
} else {
if (result < QDate::currentDate()) {
result = result.addMonths(1);
}
}
} else if (size == 2) {
int dayCount = items.at(0).toInt(&ok);
int monthCount = items.at(1).toInt(&ok);
result = QDate::currentDate();
result = result.addDays(dayCount - result.day());
result = result.addMonths(monthCount - result.month());
if (iFixupBackward) {
if (result > QDate::currentDate()) {
result = result.addYears(-1);
}
} else {
if (result < QDate::currentDate()) {
result = result.addYears(1);
}
}
} else if (size == 3) {
int dayCount = items.at(0).toInt(&ok);
int monthCount = items.at(1).toInt(&ok);
int yearCount = items.at(2).toInt(&ok);
int lengthYear = items.at(2).count();
result = QDate::currentDate();
result = result.addDays(dayCount - result.day());
result = result.addMonths(monthCount - result.month());
if (lengthYear < 4) {
auto y = static_cast<int>(result.year() / qPow(10, lengthYear)) * qPow(10, lengthYear) + yearCount;
if (y > result.year() && iFixupBackward) {
y = y - qPow(10, lengthYear);
} else if (y < result.year() && !iFixupBackward) {
y = y + qPow(10, lengthYear);
}
result = result.addYears(y - result.year());
} else {
result = result.addYears(yearCount - result.year());
}
}
if (!ok) {
result = QDate();
}
return result;
}
QStringList SKGServices::splitCSVLine(const QString& iString, QChar iSeparator, bool iCoteDefineBlock)
{
return splitCSVLine(iString, iSeparator, iCoteDefineBlock, nullptr);
}
QStringList SKGServices::splitCSVLine(const QString& iString, QChar iSeparator, bool iCoteDefineBlock, QChar* oRealSeparator)
{
QStringList items;
QString item;
bool isInBlock = false;
QChar realSeparator = iSeparator;
QChar cote = ' '; // Not yet defined
int nb = iString.length();
items.reserve(nb);
for (int pos = 0; pos < nb; ++pos) {
QChar c = iString.at(pos);
if (isInBlock) {
if (c == cote) {
if (pos < nb - 1 && iString.at(pos + 1) == cote) {
++pos; // separator escaped
} else {
items.push_back(item);
item.clear();
isInBlock = false;
// 320112 vvvv
// Reset the block character to autorize mix
cote = ' ';
// 320112 ^^^^
if (realSeparator != ' ') while (pos < nb - 1 && iString.at(pos + 1) == ' ') {
++pos;
}
++pos;
if (pos < nb) {
realSeparator = iString.at(pos); // To get the real separator
}
}
}
if (isInBlock) {
item += c;
}
} else if ((c == '\"' || c == '\'') && item.trimmed().isEmpty() && iCoteDefineBlock) {
if (cote == ' ') {
cote = c; // Set the real cote char
}
isInBlock = true;
item.clear();
} else if (QString(c) == realSeparator) {
items.push_back(item);
item.clear();
isInBlock = false;
// 320112 vvvv
// Reset the block character to autorize mix
cote = ' ';
// 320112 ^^^^
} else {
item += c;
}
}
if (!item.isEmpty() || (nb > 0 && iString.at(nb - 1) == realSeparator)) {
items.push_back(item);
}
if (oRealSeparator != nullptr) {
*oRealSeparator = realSeparator;
}
if (isInBlock) {
items.clear();
}
return items;
}
QString SKGServices::getDateFormat(const QStringList& iDates)
{
SKGTRACEINFUNC(2)
bool f_YYYY_MM_DD = true;
bool f_YYYYMMDD = true;
bool f_DDMMYYYY = true;
bool f_MMDDYYYY = true;
bool f_MM_DD_YY = true;
bool f_DD_MM_YY = true;
bool f_MM_DD_YYYY = true;
bool f_DD_MM_YYYY = true;
bool f_DDMMMYYYY = true;
bool f_DD_MMM_YY = true;
bool f_DD_MMM_YYYY = true;
// Build regexp
QRegExp rx(QStringLiteral("(.+)-(.+)-(.+)"));
// Check all dates
int nb = iDates.count();
for (int i = 0; i < nb; ++i) {
QString val = iDates.at(i).trimmed();
if (val.count() > 10) {
auto l = SKGServices::splitCSVLine(val, ' ');
val = l[0];
}
if (!val.isEmpty()) {
val = val.replace(' ', '0');
val = val.replace('\\', '-');
val = val.replace('/', '-');
val = val.replace('.', '-');
val = val.replace(QStringLiteral("'20"), QStringLiteral("-20"));
val = val.replace(QStringLiteral("' "), QStringLiteral("-200"));
val = val.replace('\'', QStringLiteral("-20"));
val = val.replace(QStringLiteral("-90"), QStringLiteral("-1990"));
val = val.replace(QStringLiteral("-91"), QStringLiteral("-1991"));
val = val.replace(QStringLiteral("-92"), QStringLiteral("-1992"));
val = val.replace(QStringLiteral("-93"), QStringLiteral("-1993"));
val = val.replace(QStringLiteral("-94"), QStringLiteral("-1994"));
val = val.replace(QStringLiteral("-95"), QStringLiteral("-1995"));
val = val.replace(QStringLiteral("-96"), QStringLiteral("-1996"));
val = val.replace(QStringLiteral("-97"), QStringLiteral("-1997"));
val = val.replace(QStringLiteral("-98"), QStringLiteral("-1998"));
val = val.replace(QStringLiteral("-99"), QStringLiteral("-1999"));
if (rx.indexIn(val) == -1) {
f_YYYY_MM_DD = false;
f_MM_DD_YY = false;
f_DD_MM_YY = false;
f_MM_DD_YYYY = false;
f_DD_MM_YYYY = false;
f_DD_MMM_YY = false;
f_DD_MMM_YYYY = false;
if (val.length() == 8) {
auto left2 = SKGServices::stringToInt(val.left(2));
if (left2 > 12) {
f_MMDDYYYY = false;
}
if (left2 > 31) {
f_DDMMYYYY = false;
}
auto mid2 = SKGServices::stringToInt(val.mid(2, 2));
if (mid2 > 12) {
f_DDMMYYYY = false;
}
if (mid2 > 31) {
f_MMDDYYYY = false;
}
auto mid4 = SKGServices::stringToInt(val.mid(4, 2));
if (mid4 > 12) {
f_YYYYMMDD = false;
}
auto right2 = SKGServices::stringToInt(val.right(2));
if (right2 > 31) {
f_YYYYMMDD = false;
}
f_DDMMMYYYY = false;
} else if (val.length() == 9) {
f_MMDDYYYY = false;
f_DDMMYYYY = false;
f_YYYYMMDD = false;
} else {
f_MMDDYYYY = false;
f_DDMMYYYY = false;
f_YYYYMMDD = false;
f_DDMMMYYYY = false;
}
} else {
f_YYYYMMDD = false;
f_DDMMYYYY = false;
f_MMDDYYYY = false;
f_DDMMMYYYY = false;
QString v1 = rx.cap(1);
QString v2 = rx.cap(2);
QString v3 = rx.cap(3);
if (SKGServices::stringToInt(v1) > 12) {
f_MM_DD_YY = false;
f_MM_DD_YYYY = false;
}
if (SKGServices::stringToInt(v2) > 12) {
f_DD_MM_YY = false;
f_DD_MM_YYYY = false;
}
if (v2.length() > 2) {
f_MM_DD_YY = false;
f_MM_DD_YYYY = false;
f_DD_MM_YY = false;
f_DD_MM_YYYY = false;
f_YYYY_MM_DD = false;
}
if (v2.length() != 3) {
f_DD_MMM_YYYY = false;
f_DD_MMM_YY = false;
}
if (SKGServices::stringToInt(v1) > 31 || SKGServices::stringToInt(v2) > 31) {
f_MM_DD_YY = false;
f_MM_DD_YYYY = false;
f_DD_MM_YY = false;
f_DD_MM_YYYY = false;
}
if (SKGServices::stringToInt(v3) > 31) {
f_YYYY_MM_DD = false;
}
if (v1.length() == 4) {
f_MM_DD_YY = false;
f_DD_MM_YY = false;
f_MM_DD_YYYY = false;
f_DD_MM_YYYY = false;
} else {
// To be more permissive and support mix of date: f_YYYY_MM_DD = false;
}
if (v3.length() == 4) {
f_YYYY_MM_DD = false;
f_MM_DD_YY = false;
f_DD_MM_YY = false;
} else {
// To be more permissive and support mix of date: f_MM_DD_YYYY = false;
// To be more permissive and support mix of date: f_DD_MM_YYYY = false;
}
}
}
}
if (f_YYYYMMDD) {
return QStringLiteral("YYYYMMDD");
}
if (f_MMDDYYYY) {
return QStringLiteral("MMDDYYYY");
}
if (f_DDMMYYYY) {
return QStringLiteral("DDMMYYYY");
}
if (f_DD_MM_YY && f_MM_DD_YY) {
QString sFormat = QLocale().dateFormat(QLocale::ShortFormat);
if (sFormat.startsWith(QLatin1String("%m")) || sFormat.startsWith(QLatin1String("%n"))) {
return QStringLiteral("MM-DD-YY");
}
return QStringLiteral("DD-MM-YY");
}
if (f_MM_DD_YY) {
return QStringLiteral("MM-DD-YY");
}
if (f_DD_MM_YY) {
return QStringLiteral("DD-MM-YY");
}
if (f_DD_MM_YYYY && f_MM_DD_YYYY) {
QString sFormat = QLocale().dateFormat(QLocale::ShortFormat);
if (sFormat.startsWith(QLatin1String("%m")) || sFormat.startsWith(QLatin1String("%n"))) {
return QStringLiteral("MM-DD-YYYY");
}
return QStringLiteral("DD-MM-YYYY");
}
if (f_MM_DD_YYYY) {
return QStringLiteral("MM-DD-YYYY");
}
if (f_DD_MM_YYYY) {
return QStringLiteral("DD-MM-YYYY");
}
if (f_YYYY_MM_DD) {
return QStringLiteral("YYYY-MM-DD");
}
if (f_DDMMMYYYY) {
return QStringLiteral("DDMMMYYYY");
}
if (f_DD_MMM_YY) {
return QStringLiteral("DD-MMM-YY");
}
if (f_DD_MMM_YYYY) {
return QStringLiteral("DD-MMM-YYYY");
}
return QLatin1String("");
}
QString SKGServices::toPercentageString(double iAmount, int iNbDecimal)
{
return toCurrencyString(iAmount, QString(), iNbDecimal) % " %";
}
QString SKGServices::toCurrencyString(double iAmount, const QString& iSymbol, int iNbDecimal)
{
if (iSymbol == QStringLiteral("%")) {
return toPercentageString(iAmount, iNbDecimal);
}
return QLocale::system().toCurrencyString(iAmount, iSymbol.isEmpty() ? QStringLiteral(" ") : iSymbol, iNbDecimal).trimmed();
}
QString SKGServices::dateToSqlString(const QString& iDate, const QString& iFormat)
{
QString input = iDate;
if (input.count() > 10) {
auto l = SKGServices::splitCSVLine(input, ' ');
input = l[0];
}
QString format = QStringLiteral("yyyy-MM-dd");
QString YYYY = QStringLiteral("0000");
QString MM = QStringLiteral("00");
QString DD = QStringLiteral("00");
if (iFormat == QStringLiteral("YYYYMMDD")) {
YYYY = input.mid(0, 4);
MM = input.mid(4, 2);
DD = input.mid(6, 2);
} else if (iFormat == QStringLiteral("DDMMYYYY") || iFormat == QStringLiteral("DDMMYY")) {
YYYY = input.mid(4, 4);
MM = input.mid(2, 2);
DD = input.mid(0, 2);
} else if (iFormat == QStringLiteral("DDMMMYYYY") || iFormat == QStringLiteral("DDMMMYY")) {
YYYY = input.mid(5, 4);
MM = input.mid(2, 3);
DD = input.mid(0, 2);
format = QStringLiteral("yyyy-MMM-dd");
} else if (iFormat == QStringLiteral("MMDDYYYY") || iFormat == QStringLiteral("MMDDYY")) {
YYYY = input.mid(4, 4);
MM = input.mid(0, 2);
DD = input.mid(2, 2);
} else {
QString val = input;
val = val.replace(' ', '0');
val = val.replace('\\', '-');
val = val.replace('/', '-');
val = val.replace('.', '-');
val = val.replace(QStringLiteral("'20"), QStringLiteral("-20"));
val = val.replace(QStringLiteral("' "), QStringLiteral("-200"));
val = val.replace('\'', QStringLiteral("-20"));
val = val.replace(QStringLiteral("-90"), QStringLiteral("-1990"));
val = val.replace(QStringLiteral("-91"), QStringLiteral("-1991"));
val = val.replace(QStringLiteral("-92"), QStringLiteral("-1992"));
val = val.replace(QStringLiteral("-93"), QStringLiteral("-1993"));
val = val.replace(QStringLiteral("-94"), QStringLiteral("-1994"));
val = val.replace(QStringLiteral("-95"), QStringLiteral("-1995"));
val = val.replace(QStringLiteral("-96"), QStringLiteral("-1996"));
val = val.replace(QStringLiteral("-97"), QStringLiteral("-1997"));
val = val.replace(QStringLiteral("-98"), QStringLiteral("-1998"));
val = val.replace(QStringLiteral("-99"), QStringLiteral("-1999"));
QRegExp rx(QStringLiteral("(.+)-(.+)-(.+)"));
if (rx.indexIn(val) != -1) {
QString v1 = rx.cap(1);
QString v2 = rx.cap(2);
QString v3 = rx.cap(3);
if (iFormat == QStringLiteral("YYYY-MM-DD")) {
YYYY = v1;
MM = v2;
DD = v3;
} else if (iFormat == QStringLiteral("MM/DD/YY") || iFormat == QStringLiteral("MM-DD-YY") || iFormat == QStringLiteral("MM/DD/YYYY") || iFormat == QStringLiteral("MM-DD-YYYY")) {
MM = v1;
DD = v2;
YYYY = v3;
} else if (iFormat == QStringLiteral("DD/MM/YY") || iFormat == QStringLiteral("DD-MM-YY") || iFormat == QStringLiteral("DD/MM/YYYY") || iFormat == QStringLiteral("DD-MM-YYYY")) {
DD = v1;
MM = v2;
YYYY = v3;
} else if (iFormat == QStringLiteral("DD/MMM/YY") || iFormat == QStringLiteral("DD-MMM-YY") || iFormat == QStringLiteral("DD/MMM/YYYY") || iFormat == QStringLiteral("DD-MMM-YYYY")) {
DD = v1;
MM = v2;
YYYY = v3;
format = QStringLiteral("yyyy-MMM-dd");
}
}
}
if (MM.length() == 1) {
MM = '0' % MM;
}
if (DD.length() == 1) {
DD = '0' % DD;
}
if (YYYY.length() == 1) {
YYYY = '0' % YYYY;
}
if (YYYY.length() == 2) {
if (stringToInt(YYYY) > 70) {
YYYY = "19" % YYYY;
} else {
YYYY = "20" % YYYY;
}
}
QString date = YYYY % '-' % MM % '-' % DD;
date.replace(' ', '0');
return dateToSqlString(QDateTime::fromString(date, format));
}
QString SKGServices::getPeriodWhereClause(const QString& iPeriod, const QString& iDateAttribute)
{
QString output = QStringLiteral("1=0");
if (iPeriod == QStringLiteral("ALL")) {
output = QStringLiteral("1=1");
} else if (iPeriod.length() == 4) {
// 2014
output = "STRFTIME('%Y'," + SKGServices::stringToSqlString(iDateAttribute) + ")='" + SKGServices::stringToSqlString(iPeriod) + '\'';
} else if (iPeriod.length() == 7 && iPeriod[4] == '-') {
if (iPeriod[5] == 'S') {
// 2014-S1
output = "STRFTIME('%Y'," + SKGServices::stringToSqlString(iDateAttribute) + ")||'-S'||(CASE WHEN STRFTIME('%m'," + SKGServices::stringToSqlString(iDateAttribute) + ")<='06' THEN '1' ELSE '2' END)='" + SKGServices::stringToSqlString(iPeriod) + '\'';
} else if (iPeriod[5] == 'Q') {
// 2014-Q1
output = "STRFTIME('%Y'," + SKGServices::stringToSqlString(iDateAttribute) + ")||'-Q'||(CASE WHEN STRFTIME('%m'," + SKGServices::stringToSqlString(iDateAttribute) + ")<='03' THEN '1' WHEN STRFTIME('%m'," + SKGServices::stringToSqlString(iDateAttribute) + ")<='06' THEN '2' WHEN STRFTIME('%m'," + SKGServices::stringToSqlString(iDateAttribute) + ")<='09' THEN '3' ELSE '4' END)='" + SKGServices::stringToSqlString(iPeriod) + '\'';
} else {
// 2014-07
output = "STRFTIME('%Y-%m'," + SKGServices::stringToSqlString(iDateAttribute) + ")='" + SKGServices::stringToSqlString(iPeriod) + '\'';
}
}
return output;
}
QDate SKGServices::periodToDate(const QString& iPeriod)
{
QDate output;
if (iPeriod == QStringLiteral("ALL")) {
output = QDate::currentDate();
} else if (iPeriod.length() == 4) {
// 2014
output = QDate::fromString(iPeriod, QStringLiteral("yyyy")).addYears(1).addDays(-1);
} else if (iPeriod.length() == 7) {
if (iPeriod[5] == 'S') {
// 2014-S1
output = QDate::fromString(iPeriod, QStringLiteral("yyyy-SM"));
output = output.addMonths(output.month() * 6 - output.month()); // convert semester in month
output = output.addMonths(1).addDays(-1);
} else if (iPeriod[5] == 'Q') {
// 2014-Q1
output = QDate::fromString(iPeriod, QStringLiteral("yyyy-QM"));
output = output.addMonths(output.month() * 3 - output.month()); // convert quarter in month
output = output.addMonths(1).addDays(-1);
} else {
// 2014-07
output = QDate::fromString(iPeriod, QStringLiteral("yyyy-MM")).addMonths(1).addDays(-1);
}
}
return output;
}
QString SKGServices::getNeighboringPeriod(const QString& iPeriod, int iDelta)
{
QString output = QStringLiteral("1=0");
if (iPeriod.length() == 4) {
// 2014
QDate date = QDate::fromString(iPeriod, QStringLiteral("yyyy")).addYears(iDelta);
output = date.toString(QStringLiteral("yyyy"));
} else if (iPeriod.length() == 7) {
if (iPeriod[5] == 'S') {
// 2014-S1
QDate date2 = QDate::fromString(iPeriod, QStringLiteral("yyyy-SM"));
date2 = date2.addMonths(date2.month() * 6 - date2.month()); // convert semester in month
date2 = date2.addMonths(6 * iDelta);
output = date2.toString(QStringLiteral("yyyy-S")) % (date2.month() <= 6 ? '1' : '2');
} else if (iPeriod[5] == 'Q') {
// 2014-Q1
QDate date2 = QDate::fromString(iPeriod, QStringLiteral("yyyy-QM"));
date2 = date2.addMonths(date2.month() * 3 - date2.month()); // convert quarter in month
date2 = date2.addMonths(3 * iDelta);
output = date2.toString(QStringLiteral("yyyy-Q")) % (date2.month() <= 3 ? '1' : (date2.month() <= 6 ? '2' : (date2.month() <= 9 ? '3' : '4')));
} else {
// 2014-07
QDate date2 = QDate::fromString(iPeriod, QStringLiteral("yyyy-MM")).addMonths(iDelta);
output = date2.toString(QStringLiteral("yyyy-MM"));
}
}
return output;
}
QStringList SKGServices::tableToDump(const SKGStringListList& iTable, SKGServices::DumpMode iMode)
{
SKGTRACEINFUNC(10)
// initialisation
QStringList oResult;
// Compute max size of each column
int* maxSizes = nullptr;
int nbMaxSizes = 0;
if (iMode == DUMP_TEXT) {
int nb = iTable.count();
for (int i = 0; i < nb; ++i) {
const QStringList& line = iTable.at(i);
int nb2 = line.size();
if (maxSizes == nullptr) {
nbMaxSizes = nb2;
maxSizes = new int[nbMaxSizes];
for (int j = 0; j < nbMaxSizes; ++j) {
maxSizes[j] = 0;
}
}
for (int j = 0; j < nb2; ++j) {
const QString& s = line.at(j);
if (j < nbMaxSizes && s.length() > maxSizes[j]) {
maxSizes[j] = s.length();
}
}
}
}
// dump
int nb = iTable.count();
oResult.reserve(nb);
for (int i = 0; i < nb; ++i) {
QString lineFormated;
if (iMode == DUMP_TEXT) {
lineFormated = QStringLiteral("| ");
}
const QStringList& line = iTable.at(i);
int nb2 = line.size();
for (int j = 0; j < nb2; ++j) {
QString s = line.at(j);
s.remove('\n');
if (iMode == DUMP_CSV) {
if (j > 0) {
lineFormated += ';';
}
lineFormated += stringToCsv(s);
} else if (maxSizes != nullptr) {
if (j < nbMaxSizes) {
s = s.leftJustified(maxSizes[j], ' ');
}
lineFormated += s % " | ";
}
}
oResult.push_back(lineFormated);
}
// delete
if (maxSizes != nullptr) {
delete [] maxSizes;
maxSizes = nullptr;
}
return oResult;
}
QString SKGServices::getRealTable(const QString& iTable)
{
QString output = iTable;
if (output.length() > 2 && output.startsWith(QLatin1String("v_"))) {
output = output.mid(2, output.length() - 2);
int pos = output.indexOf(QStringLiteral("_"));
if (pos != -1) {
output = output.left(pos);
}
}
return output;
}
SKGError SKGServices::downloadToStream(const QUrl& iSourceUrl, QByteArray& oStream)
{
SKGError err;
SKGTRACEINFUNCRC(10, err)
QString tmpFile;
if (iSourceUrl.isLocalFile()) {
tmpFile = iSourceUrl.toLocalFile();
} else {
err = download(iSourceUrl, tmpFile);
}
IFOK(err) {
// Open file
QFile file(tmpFile);
if (Q_UNLIKELY(!file.open(QIODevice::ReadOnly))) {
err.setReturnCode(ERR_FAIL).setMessage(i18nc("An information message", "Open file '%1' failed", tmpFile));
} else {
oStream = file.readAll();
// close file
file.close();
}
if (!iSourceUrl.isLocalFile()) {
QFile(tmpFile).remove();
}
}
return err;
}
SKGError SKGServices::download(const QUrl& iSourceUrl, QString& oTemporaryFile)
{
SKGError err;
SKGTRACEINFUNCRC(10, err)
QTemporaryFile tmpFile;
tmpFile.setAutoRemove(false);
if (tmpFile.open()) {
err = upload(iSourceUrl, QUrl::fromLocalFile(tmpFile.fileName()));
IFOK(err) oTemporaryFile = tmpFile.fileName();
}
return err;
}
SKGError SKGServices::upload(const QUrl& iSourceUrl, const QUrl& iDescUrl)
{
SKGError err;
SKGTRACEINFUNCRC(10, err)
if (iDescUrl != iSourceUrl) {
if (iDescUrl.isLocalFile() && iSourceUrl.isLocalFile()) {
QFile(iDescUrl.toLocalFile()).remove();
if (!QFile::copy(iSourceUrl.toLocalFile(), iDescUrl.toLocalFile())) {
err = SKGError(ERR_ABORT, i18nc("Error message", "Impossible to copy '%1' to '%2'", iSourceUrl.toDisplayString(), iDescUrl.toDisplayString()));
}
} else {
KIO::FileCopyJob* getJob = KIO::file_copy(iSourceUrl, iDescUrl, -1, KIO::Overwrite | KIO::HideProgressInfo);
if (!getJob->exec()) {
err.setReturnCode(ERR_ABORT).setMessage(getJob->errorString());
err.addError(ERR_ABORT, i18nc("Error message", "Impossible to copy '%1' to '%2'", iSourceUrl.toDisplayString(), iDescUrl.toDisplayString()));
}
}
}
return err;
}
SKGError SKGServices::cryptFile(const QString& iFileSource, const QString& iFileTarget, const QString& iPassword, bool iEncrypt, const QString& iHeaderFile, bool& oModeSQLCipher)
{
SKGError err;
SKGTRACEINFUNCRC(10, err)
SKGTRACEL(10) << "Input parameter [iFileSource]=[" << iFileSource << ']' << endl;
SKGTRACEL(10) << "Input parameter [iFileTarget]=[" << iFileTarget << ']' << endl;
SKGTRACEL(10) << "Input parameter [iPassword] =[" << iPassword << ']' << endl;
SKGTRACEL(10) << "Input parameter [iHeaderFile]=[" << iHeaderFile << ']' << endl;
oModeSQLCipher = false;
// Read document
QByteArray input;
QByteArray uba;
err = downloadToStream(QUrl::fromUserInput(iFileSource), input);
IFOK(err) {
bool isFileEncrypted = (input.startsWith(QByteArray((iHeaderFile % "_ENCRYPT").toLatin1())));
bool sqliteMode = (input.left(15) == "SQLite format 3");
SKGTRACEL(10) << "isFileEncrypted=[" << static_cast<unsigned int>(isFileEncrypted) << ']' << endl;
// !!!!! Remove Cipher encryption to remove security hole (thank you to Vincent P) !!!!!
// Only in sqlcipher mode. WARNING: in sqlite mode the issue is still there => add a message to push people to swith in sqlcipher mode
if (iEncrypt && !sqliteMode) {
// The input file is a sqlcipher file and we must save it
// We just have to add a new header to the input file
uba.reserve(input.length() + iHeaderFile.length() + 11);
uba.append(iHeaderFile.toLatin1());
uba.append(!iPassword.isEmpty() ? "_ENCRYPTE3-" : "_DECRYPTE3-");
uba.append(input);
oModeSQLCipher = true;
} else if (!iEncrypt && input.startsWith(QByteArray((iHeaderFile % "_ENCRYPTE3-").toLatin1()))) {
// This check is done to improve performances
if (iPassword.isEmpty() || iPassword == QStringLiteral("DEFAULTPASSWORD")) {
err = SKGError(ERR_ENCRYPTION, i18nc("Error message", "Wrong password"));
} else {
// The input file encrypter with the new mode
// We just have to remove the header
if (!iHeaderFile.isEmpty() && input.startsWith(iHeaderFile.toLatin1())) {
input = input.right(input.length() - iHeaderFile.length() - 11);
}
uba = input;
oModeSQLCipher = true;
}
} else {
// WARNING: This part is not really secured but is kept for compatibility
SKGTRACEL(10) << "Mode not secured" << endl;
QCA::Initializer init;
QCA::SymmetricKey key(QByteArray("skrooge"));
SKGTRACEL(10) << "QCA::Initializer done" << endl;
if (!iPassword.isEmpty() && !QCA::isSupported("aes128-ecb")) {
// Set error message
err.setReturnCode(ERR_INSTALL); // To avoid password request
err.setMessage(i18nc("An error message about encryption", "AES128 encryption is not supported (%1). Please install qca-ossl.", QCA::supportedFeatures().join(QStringLiteral(","))));
} else {
QCA::Cipher* cipher = nullptr;
QCA::InitializationVector iv(iPassword.toLatin1());
// Create a 128 bit AES cipher object using Cipher Block Chaining (CBC) mode
if ((isFileEncrypted || iEncrypt) && !iPassword.isEmpty()) {
cipher = new QCA::Cipher(QStringLiteral("aes128"), QCA::Cipher::CBC,
// use Default padding, which is equivalent to PKCS7 for CBC
QCA::Cipher::DefaultPadding,
iEncrypt ? QCA::Encode : QCA::Decode,
key, iv);
}
// BUG 249955 vvv
if ((cipher == nullptr) && isFileEncrypted) {
err = SKGError(ERR_ENCRYPTION, i18nc("Error message about encrypting a file", "Encryption failed"));
}
// BUG 249955 ^^^
// Suppress header
SKGTRACEL(10) << "input=[" << input.left(50) << "...]" << endl;
if (!iHeaderFile.isEmpty() && input.startsWith(iHeaderFile.toLatin1())) {
input = input.right(input.length() - iHeaderFile.length() - 11);
}
SKGTRACEL(10) << "input without header=[" << input.left(50) << "...]" << endl;
QCA::SecureArray u;
if (cipher != nullptr) {
if (!err) {
// Process encryption or decryption
u = cipher->process(input);
// We need to check if that update() call worked.
if (!cipher->ok()) {
err = SKGError(ERR_UNEXPECTED, i18nc("Error message about encrypting a file", "Encryption failed"));
} else {
uba = u.toByteArray();
}
}
} else {
uba = input;
}
IFOK(err) {
// Check if decryption is OK
SKGTRACEL(10) << "output 1=[" << uba.left(50) << "...]" << endl;
if (!iEncrypt) {
if (!uba.startsWith(QByteArray("SQLite format 3"))) {
if (!uba.startsWith(SQLCIPHERHEARDER)) {
if (isFileEncrypted) {
err = SKGError(ERR_ENCRYPTION, i18nc("Error message", "Wrong password"));
} else {
oModeSQLCipher = true;
}
} else {
uba = uba.right(uba.length() - QStringLiteral(SQLCIPHERHEARDER).length());
oModeSQLCipher = true;
}
}
}
}
IFOK(err) {
// Add headers
if (iEncrypt && !iHeaderFile.isEmpty()) {
QByteArray h = (iHeaderFile % (cipher != nullptr ? "_ENCRYPTED-" : "_DECRYPTED-")).toLatin1();
uba = uba.insert(0, h);
}
}
delete cipher;
cipher = nullptr;
}
}
SKGTRACEL(10) << "output 2=[" << uba.left(50) << "...]" << endl;
// output the results of that stage
IFOK(err) {
SKGTRACEIN(10, "SKGServices::cryptFile-save file")
QSaveFile fileOutput(iFileTarget);
if (!fileOutput.open(QIODevice::WriteOnly)) {
err = SKGError(ERR_WRITEACCESS, i18nc("Error message: writing a file failed", "Write file '%1' failed", iFileTarget));
} else {
// Write document
fileOutput.write(uba);
// Close the file
if (!fileOutput.commit()) {
IFOK(err) {
err = SKGError(ERR_WRITEACCESS, i18nc("Error message: writing a file failed", "Write file '%1' failed", iFileTarget));
}
}
}
}
}
SKGTRACEL(10) << "Output parameter [oModeSQLCipher]=[" << static_cast<unsigned int>(oModeSQLCipher) << ']' << endl;
return err;
}
SKGError SKGServices::copySqliteDatabaseToXml(const QSqlDatabase& iDb, QDomDocument& oDocument)
{
SKGError err;
SKGTRACEINFUNCRC(10, err)
oDocument = QDomDocument(QStringLiteral("SKGML"));
QDomElement document = oDocument.createElement(QStringLiteral("document"));
oDocument.appendChild(document);
// Copy the tables
QStringList listTables = iDb.tables();
int nb = listTables.count();
for (int i = 0; !err && i < nb; ++i) {
const QString& tableName = listTables.at(i);
if (!tableName.startsWith(QLatin1String("sqlite_")) && !tableName.startsWith(QLatin1String("vm_"))) {
QDomElement table = oDocument.createElement(QStringLiteral("table"));
document.appendChild(table);
table.setAttribute(QStringLiteral("name"), tableName);
SKGStringListList listRows;
err = SKGServices::executeSelectSqliteOrder(iDb, "SELECT * FROM " % tableName, listRows);
int nbRows = listRows.count();
if (nbRows != 0) {
const QStringList& titles = listRows.at(0);
for (int j = 1; !err && j < nbRows; ++j) { // Forget title
const QStringList& values = listRows.at(j);
QDomElement row = oDocument.createElement(QStringLiteral("row"));
table.appendChild(row);
int nbVals = values.count();
for (int k = 0; k < nbVals; ++k) {
row.setAttribute(titles.at(k), values.at(k));
}
}
}
}
}
return err;
}
SKGError SKGServices::copySqliteDatabase(const QSqlDatabase& iFileDb, const QSqlDatabase& iMemoryDb, bool iFromFileToMemory, const QString& iPassword)
{
SKGError err;
SKGTRACEINFUNCRC(10, err)
SKGTRACEL(20) << "Input parameter [iFileDb]=[" << iFileDb.databaseName() << ']' << endl;
SKGTRACEL(20) << "Input parameter [iMemoryDb]=[" << iMemoryDb.databaseName() << ']' << endl;
SKGTRACEL(10) << "Input parameter [iFromFileToMemory]=[" << (iFromFileToMemory ? "FILE->MEMORY" : "MEMORY->FILE") << ']' << endl;
QString dbFileName = iFileDb.databaseName();
// Copy the tables
SKGStringListList listTables;
int nb = 0;
IFOK(err) {
err = SKGServices::executeSelectSqliteOrder((iFromFileToMemory ? iFileDb : iMemoryDb),
QStringLiteral("SELECT sql, tbl_name FROM sqlite_master WHERE type='table' AND sql NOT NULL and name NOT LIKE 'sqlite_%'"),
listTables);
nb = listTables.count();
for (int i = 1; !err && i < nb; ++i) { // Forget header
QString val = listTables.at(i).at(0);
err = SKGServices::executeSqliteOrder((iFromFileToMemory ? iMemoryDb : iFileDb), val);
}
}
// Attach db
IFOK(err) {
QString add;
if (!iPassword.isEmpty()) {
add = " KEY '" % SKGServices::stringToSqlString(iPassword) % "'";
}
err = SKGServices::executeSqliteOrder(iMemoryDb, "ATTACH DATABASE '" % dbFileName % "' as source" % add);
}
// Copy records
IFOK(err) {
err = SKGServices::executeSqliteOrder(iMemoryDb, QStringLiteral("BEGIN"));
IFOK(err) {
for (int i = 1; !err && i < nb; ++i) { // Forget header
QString val = listTables.at(i).at(1);
if (iFromFileToMemory) {
err = SKGServices::executeSqliteOrder(iMemoryDb, "insert into main." % val % " select * from source." % val);
} else {
err = SKGServices::executeSqliteOrder(iMemoryDb, "insert into source." % val % " select * from main." % val);
}
}
}
SKGServices::executeSqliteOrder(iMemoryDb, QStringLiteral("COMMIT"));
}
// Detach
{
SKGError err2 = SKGServices::executeSqliteOrder(iMemoryDb, QStringLiteral("DETACH DATABASE source"));
if (!err && err2) {
err = err2;
}
}
// Optimization
IFOK(err) {
QStringList optimization;
optimization << QStringLiteral("PRAGMA case_sensitive_like=true")
<< QStringLiteral("PRAGMA journal_mode=MEMORY")
<< QStringLiteral("PRAGMA temp_store=MEMORY")
// << QStringLiteral("PRAGMA locking_mode=EXCLUSIVE")
<< QStringLiteral("PRAGMA synchronous = OFF")
<< QStringLiteral("PRAGMA recursive_triggers=true");
err = SKGServices::executeSqliteOrders(iFromFileToMemory ? iMemoryDb : iFileDb, optimization);
}
// Copy the indexes
IFOK(err) {
SKGStringListList listSqlOrder;
err = SKGServices::executeSelectSqliteOrder((iFromFileToMemory ? iFileDb : iMemoryDb),
QStringLiteral("SELECT sql FROM sqlite_master WHERE type='index' AND sql NOT NULL and name NOT LIKE 'sqlite_%'"),
listSqlOrder);
int nb2 = listSqlOrder.count();
for (int i = 1; !err && i < nb2; ++i) { // Forget header
QString val = listSqlOrder.at(i).at(0);
err = SKGServices::executeSqliteOrder((iFromFileToMemory ? iMemoryDb : iFileDb), val);
}
}
// Copy the views
IFOK(err) {
SKGStringListList listSqlOrder;
err = SKGServices::executeSelectSqliteOrder((iFromFileToMemory ? iFileDb : iMemoryDb),
QStringLiteral("SELECT sql FROM sqlite_master WHERE type='view' AND sql NOT NULL and name NOT LIKE 'sqlite_%'"),
listSqlOrder);
int nb2 = listSqlOrder.count();
for (int i = 1; !err && i < nb2; ++i) { // Forget header
QString val = listSqlOrder.at(i).at(0);
err = SKGServices::executeSqliteOrder((iFromFileToMemory ? iMemoryDb : iFileDb), val);
}
}
// Copy the triggers, must be done after the views
IFOK(err) {
SKGStringListList listSqlOrder;
err = SKGServices::executeSelectSqliteOrder((iFromFileToMemory ? iFileDb : iMemoryDb),
QStringLiteral("SELECT sql FROM sqlite_master WHERE type='trigger' AND sql NOT NULL and name NOT LIKE 'sqlite_%'"),
listSqlOrder);
int nb2 = listSqlOrder.count();
for (int i = 1; !err && i < nb2; ++i) { // Forget header
QString val = listSqlOrder.at(i).at(0);
err = SKGServices::executeSqliteOrder((iFromFileToMemory ? iMemoryDb : iFileDb), val);
}
}
// Check if created file exists
if (!err && !iFromFileToMemory && !QFile(dbFileName).exists()) {
err.setReturnCode(ERR_FAIL).setMessage(i18nc("An error message: creating a file failed", "Creation file '%1' failed", dbFileName));
}
IFKO(err) {
err.addError(SQLLITEERROR + ERR_FAIL, i18nc("Error message: something failed", "%1 failed", QStringLiteral("SKGServices::copySqliteDatabase()")));
}
return err;
}
SKGError SKGServices::executeSqliteOrders(const QSqlDatabase& iDb, const QStringList& iSqlOrders)
{
SKGError err;
_SKGTRACEINFUNCRC(10, err)
int nb = iSqlOrders.count();
for (int i = 0; !err && i < nb; ++i) {
err = executeSqliteOrder(iDb, iSqlOrders.at(i));
}
return err;
}
SKGError SKGServices::executeSqliteOrder(const QSqlDatabase& iDb, const QString& iSqlOrder, const QMap<QString, QVariant>& iBind, int* iLastId)
{
SKGError err;
_SKGTRACEINFUNCRC(10, err)
SKGTRACEL(20) << "Input parameter [iSqlOrder]=[" << iSqlOrder << ']' << endl;
QSqlQuery query(QString(), iDb);
query.setForwardOnly(true);
double elapse = 0;
if (SKGServices::SKGSqlTraces != -1) {
elapse = SKGServices::getMicroTime();
}
// Prepare sql order
bool prep = query.prepare(iSqlOrder);
// Bind values
QMapIterator<QString, QVariant> i(iBind);
while (i.hasNext()) {
i.next();
query.bindValue(i.key(), i.value());
}
if (!prep || !query.exec()) {
QSqlError sqlError = query.lastError();
if (sqlError.nativeErrorCode().toInt() != 19 /*SQLITE_CONSTRAINT*/ && iSqlOrder != QStringLiteral("SELECT count(*) FROM sqlite_master") /*Test password*/) {
SKGTRACE << "WARNING: " << iSqlOrder << endl;
SKGTRACE << " returns :" << sqlError.text() << endl;
}
err = SKGError(SQLLITEERROR + sqlError.nativeErrorCode().toInt(), iSqlOrder);
err.addError(SQLLITEERROR + sqlError.nativeErrorCode().toInt(), sqlError.text());
if (sqlError.nativeErrorCode().toInt() == 19 && iSqlOrder.startsWith(QLatin1String("INSERT "))) {
err.addError(ERR_FAIL, i18nc("Error message", "Creation failed. The object already exists."));
}
} else {
if (iLastId != nullptr) {
*iLastId = query.lastInsertId().toInt();
}
}
if (SKGServices::SKGSqlTraces != -1) {
elapse = SKGServices::getMicroTime() - elapse;
if (elapse >= SKGServices::SKGSqlTraces) {
SKGTRACE << "executeSqliteOrder :" << iSqlOrder << " TIME=" << elapse << " ms" << endl;
}
}
return err;
}
SKGError SKGServices::executeSqliteOrder(const QSqlDatabase& iDb, const QString& iSqlOrder, int* iLastId)
{
return executeSqliteOrder(iDb, iSqlOrder, QMap< QString, QVariant >(), iLastId);
}
SKGError SKGServices::dumpSelectSqliteOrder(const QSqlDatabase& iDb, const QString& iSqlOrder, SKGServices::DumpMode iMode)
{
return dumpSelectSqliteOrder(iDb, iSqlOrder, nullptr, iMode);
}
SKGError SKGServices::dumpSelectSqliteOrder(const QSqlDatabase& iDb, const QString& iSqlOrder, QTextStream* oStream, SKGServices::DumpMode iMode)
{
SKGError err;
_SKGTRACEINFUNCRC(10, err)
SKGTRACEL(20) << "Input parameter [iSqlOrder]=[" << iSqlOrder << ']' << endl;
// initialisation
QStringList oResult;
err = SKGServices::dumpSelectSqliteOrder(iDb, iSqlOrder, oResult, iMode);
IFOK(err) {
// dump
int nb = oResult.size();
for (int i = 0; i < nb; ++i) {
if (oStream == nullptr) {
SKGTRACESUITE << oResult.at(i) << endl;
} else {
*oStream << oResult.at(i) << endl;
}
}
}
return err;
}
SKGError SKGServices::dumpSelectSqliteOrder(const QSqlDatabase& iDb, const QString& iSqlOrder, QString& oResult, SKGServices::DumpMode iMode)
{
SKGError err;
_SKGTRACEINFUNCRC(10, err)
// initialisation
oResult = QLatin1String("");
QStringList oResultTmp;
err = SKGServices::dumpSelectSqliteOrder(iDb, iSqlOrder, oResultTmp, iMode);
IFOK(err) {
// dump
int nb = oResultTmp.size();
for (int i = 0; i < nb; ++i) {
oResult += oResultTmp.at(i) % '\n';
}
}
return err;
}
SKGError SKGServices::dumpSelectSqliteOrder(const QSqlDatabase& iDb, const QString& iSqlOrder, QStringList& oResult, SKGServices::DumpMode iMode)
{
SKGError err;
_SKGTRACEINFUNCRC(10, err)
// Execution of sql order
SKGStringListList oResultTmp;
err = executeSelectSqliteOrder(iDb, iSqlOrder, oResultTmp);
IFOK(err) oResult = tableToDump(oResultTmp, iMode);
return err;
}
SKGError SKGServices::executeSingleSelectSqliteOrder(const QSqlDatabase& iDb, const QString& iSqlOrder, QString& oResult)
{
SKGStringListList result;
SKGError err = executeSelectSqliteOrder(iDb, iSqlOrder, result);
oResult = result.value(1).value(0);
return err;
}
SKGError SKGServices::executeSelectSqliteOrder(const QSqlDatabase& iDb, const QString& iSqlOrder, SKGStringListList& oResult)
{
SKGError err;
_SKGTRACEINFUNCRC(10, err)
// initialisation
oResult.clear();
QSqlQuery query(QString(), iDb);
query.setForwardOnly(true);
double elapse = 0;
if (SKGServices::SKGSqlTraces != -1) {
elapse = SKGServices::getMicroTime();
}
if (!query.exec(iSqlOrder)) {
QSqlError sqlError = query.lastError();
if (qApp->thread() == QThread::currentThread()) {
SKGTRACE << "WARNING: " << iSqlOrder << endl;
SKGTRACE << " returns :" << sqlError.text() << endl;
}
err = SKGError(SQLLITEERROR + sqlError.nativeErrorCode().toInt(), iSqlOrder);
err.addError(SQLLITEERROR + sqlError.nativeErrorCode().toInt(), sqlError.text());
} else {
double elapse1 = 0;
if (SKGServices::SKGSqlTraces != -1) {
elapse1 = SKGServices::getMicroTime() - elapse;
}
// Addition of column names
QSqlRecord rec = query.record();
QStringList line;
int index = 0;
while (index != -1) {
QString val = rec.fieldName(index);
if (!val.isEmpty()) {
line.push_back(val);
++index;
} else {
index = -1;
}
}
oResult.push_back(line);
// Addition of rows
while (query.next()) {
QStringList line2;
int index2 = 0;
while (index2 != -1) {
QVariant val = query.value(index2);
if (val.isValid()) {
line2.push_back(val.toString());
++index2;
} else {
index2 = -1;
}
}
oResult.push_back(line2);
}
if (SKGServices::SKGSqlTraces != -1) {
double elapse2 = SKGServices::getMicroTime() - elapse;
if (elapse1 >= SKGServices::SKGSqlTraces) {
SKGTRACE << "executeSqliteOrder:" << iSqlOrder << " TIME=" << elapse1 << " ms, (with fetch):" << elapse2 << " ms" << endl;
}
}
}
return err;
}
SKGError SKGServices::readPropertyFile(const QString& iFileName, QHash< QString, QString >& oProperties)
{
SKGError err;
oProperties.clear();
// Open file
QFile file(iFileName);
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
err = SKGError(ERR_FAIL, i18nc("An erro message", "Open file '%1' failed", iFileName));
} else {
// Read file
QTextStream stream(&file);
while (!stream.atEnd() && !err) {
// Read line
QString line = stream.readLine().trimmed();
if (!line.isEmpty() && !line.startsWith(QLatin1String("#"))) {
int pos = line.indexOf(QStringLiteral("="));
if (pos != -1) {
oProperties[line.left(pos).trimmed().toLower()] = line.right(line.count() - pos - 1);
}
}
}
// close file
file.close();
}
return err;
}
double SKGServices::getMicroTime()
{
#ifdef Q_OS_WIN
return static_cast<double>(GetTickCount());
#else
struct timeval tv {};
struct timezone tz {};
// get time
gettimeofday(&tv, &tz);
// return time
return (static_cast<double>(1000.0 * tv.tv_sec)) + (static_cast<double>(tv.tv_usec / 1000));
#endif
}
SKGStringListList SKGServices::getBase100Table(const SKGStringListList& iTable)
{
SKGTRACEINFUNC(10)
// Build history
SKGStringListList output;
int nblines = iTable.count();
int nbCols = 0;
if (nblines != 0) {
nbCols = iTable.at(0).count();
}
output.reserve(nblines + 1);
output.push_back(iTable.at(0));
// Create table
for (int i = 1; i < nblines; ++i) {
QStringList newLine;
newLine.reserve(nbCols + 1);
newLine.push_back(iTable.at(i).at(0));
double valInitial = 0;
for (int j = 1; j < nbCols; ++j) {
double val = SKGServices::stringToDouble(iTable.at(i).at(j));
if (j == 1) {
valInitial = val;
val = 100.0;
} else {
if (valInitial != 0.0) {
val = 100.0 * val / valInitial;
}
}
newLine.push_back(SKGServices::doubleToString(val));
}
output.push_back(newLine);
}
return output;
}
SKGStringListList SKGServices::getPercentTable(const SKGStringListList& iTable, bool iOfColumns, bool iAbsolute)
{
SKGTRACEINFUNC(10)
// Build history
SKGStringListList output;
int nblines = iTable.count();
int nbCols = 0;
if (nblines != 0) {
nbCols = iTable.at(0).count();
}
output.reserve(nblines + 1);
output.push_back(iTable.at(0));
// Compute sums
QList<double> sums;
if (iOfColumns) {
// Compute sum of columns
sums.reserve(nbCols);
for (int j = 1; j < nbCols; ++j) {
// Compute sum
double sum = 0;
for (int i = 1; i < nblines; ++i) {
double v = SKGServices::stringToDouble(iTable.at(i).at(j));
sum += (iAbsolute ? qAbs(v) : v);
}
sums.push_back(sum);
}
} else {
// Compute sum of lines
sums.reserve(nblines);
for (int j = 1; j < nblines; ++j) {
// Compute sum
double sum = 0;
for (int i = 1; i < nbCols; ++i) {
double v = SKGServices::stringToDouble(iTable.at(j).at(i));
sum += (iAbsolute ? qAbs(v) : v);
}
sums.push_back(sum);
}
}
// Create table
for (int i = 1; i < nblines; ++i) {
QStringList newLine;
newLine.reserve(nbCols + 1);
newLine.push_back(iTable.at(i).at(0));
for (int j = 1; j < nbCols; ++j) {
double val = SKGServices::stringToDouble(iTable.at(i).at(j));
val = (iAbsolute ? qAbs(val) : val);
double sum = (iOfColumns ? sums.at(j - 1) : sums.at(i - 1));
newLine.push_back(SKGServices::doubleToString(sum == 0.0 ? 0.0 : 100.0 * val / sum));
}
output.push_back(newLine);
}
return output;
}
SKGStringListList SKGServices::getHistorizedTable(const SKGStringListList& iTable)
{
SKGTRACEINFUNC(10)
// Build history
SKGStringListList output;
int nblines = iTable.count();
int nbCols = 0;
if (nblines != 0) {
nbCols = iTable.at(0).count();
}
output.reserve(nblines + 1);
output.push_back(iTable.at(0));
for (int i = 1; i < nblines; ++i) {
QStringList newLine;
newLine.reserve(nbCols + 1);
newLine.push_back(iTable.at(i).at(0));
double sum = 0;
for (int j = 1; j < nbCols; ++j) {
sum += SKGServices::stringToDouble(iTable.at(i).at(j));
newLine.push_back(SKGServices::doubleToString(sum));
}
output.push_back(newLine);
}
return output;
}
QString SKGServices::encodeForUrl(const QString& iString)
{
return QUrl::toPercentEncoding(iString);
}
QIcon SKGServices::fromTheme(const QString& iName, const QStringList& iOverlays)
{
QIcon output;
if (!iOverlays.isEmpty()) {
output = KDE::icon(iName, iOverlays);
} else {
output = KDE::icon(iName);
}
if (output.isNull() && !iName.isEmpty()) {
static QHash<QString, QString> alternatives;
if (alternatives.count() == 0) {
// Build alternatives
alternatives[QStringLiteral("arrow-down")] = QStringLiteral("go-down");
alternatives[QStringLiteral("arrow-right")] = QStringLiteral("go-next");
alternatives[QStringLiteral("arrow-up")] = QStringLiteral("go-up");
alternatives[QStringLiteral("arrow-down-double")] = QStringLiteral("go-down");
alternatives[QStringLiteral("arrow-up-double")] = QStringLiteral("go-up");
alternatives[QStringLiteral("bookmark")] = QStringLiteral("bookmark-new");
alternatives[QStringLiteral("bookmarks")] = QStringLiteral("bookmark-new");
alternatives[QStringLiteral("checkbox")] = QStringLiteral("emblem-symbolic-link");
alternatives[QStringLiteral("chronometer")] = QStringLiteral("appointment");
alternatives[QStringLiteral("configure")] = QStringLiteral("preferences-desktop");
alternatives[QStringLiteral("dashboard-show")] = QStringLiteral("user-desktop");
alternatives[QStringLiteral("dialog-cancel")] = QStringLiteral("process-stop");
alternatives[QStringLiteral("dialog-close")] = QStringLiteral("process-stop");
alternatives[QStringLiteral("dialog-ok")] = QLatin1String("");
alternatives[QStringLiteral("download-later")] = QStringLiteral("internet-services");
alternatives[QStringLiteral("download")] = QStringLiteral("internet-services");
alternatives[QStringLiteral("draw-freehand")] = QStringLiteral("accessories-text-editor");
alternatives[QStringLiteral("edit-guides")] = QStringLiteral("text-x-generic");
alternatives[QStringLiteral("edit-rename")] = QStringLiteral("accessories-text-editor");
alternatives[QStringLiteral("emblem-locked")] = QStringLiteral("lock");
alternatives[QStringLiteral("exchange-positions")] = QLatin1String("");
alternatives[QStringLiteral("format-fill-color")] = QLatin1String("");
alternatives[QStringLiteral("games-solve")] = QStringLiteral("application-certificate");
alternatives[QStringLiteral("get-hot-new-stuff")] = QStringLiteral("applications-other");
alternatives[QStringLiteral("irc-operator")] = QLatin1String("");
alternatives[QStringLiteral("ktip")] = QStringLiteral("dialog-information");
alternatives[QStringLiteral("labplot-xy-plot-two-axes-centered-origin")] = QStringLiteral("x-office-spreadsheet");
alternatives[QStringLiteral("layer-visible-off")] = QLatin1String("");
alternatives[QStringLiteral("layer-visible-on")] = QLatin1String("");
alternatives[QStringLiteral("merge")] = QLatin1String("");
alternatives[QStringLiteral("office-chart-area")] = QStringLiteral("x-office-spreadsheet");
alternatives[QStringLiteral("office-chart-area-stacked")] = QStringLiteral("x-office-spreadsheet");
alternatives[QStringLiteral("office-chart-bar-percentage")] = QStringLiteral("x-office-spreadsheet");
alternatives[QStringLiteral("office-chart-bar")] = QStringLiteral("x-office-spreadsheet");
alternatives[QStringLiteral("office-chart-bar-stacked")] = QStringLiteral("x-office-spreadsheet");
alternatives[QStringLiteral("office-chart-line")] = QStringLiteral("x-office-spreadsheet");
alternatives[QStringLiteral("office-chart-line-stacked")] = QStringLiteral("x-office-spreadsheet");
alternatives[QStringLiteral("office-chart-pie")] = QStringLiteral("x-office-spreadsheet");
alternatives[QStringLiteral("office-chart-ring")] = QStringLiteral("x-office-spreadsheet");
alternatives[QStringLiteral("map-flat")] = QStringLiteral("x-office-spreadsheet");
alternatives[QStringLiteral("office-chart-scatter")] = QStringLiteral("x-office-spreadsheet");
alternatives[QStringLiteral("preview")] = QStringLiteral("document-print-preview");
alternatives[QStringLiteral("quickopen")] = QStringLiteral("emblem-symbolic-link");
alternatives[QStringLiteral("run-build-configure")] = QStringLiteral("media-playback-start");
alternatives[QStringLiteral("run-build")] = QStringLiteral("media-playback-start");
alternatives[QStringLiteral("show-menu")] = QStringLiteral("applications-system");
alternatives[QStringLiteral("skrooge_category")] = QStringLiteral("folder-open");
alternatives[QStringLiteral("split")] = QStringLiteral("edit-cut");
alternatives[QStringLiteral("taxes-finances")] = QStringLiteral("fonts");
alternatives[QStringLiteral("tools-wizard")] = QStringLiteral("applications-other");
alternatives[QStringLiteral("user-group-properties")] = QStringLiteral("system-users");
alternatives[QStringLiteral("user-properties")] = QStringLiteral("document-properties");
alternatives[QStringLiteral("utilities-file-archiver")] = QStringLiteral("package-x-generic");
alternatives[QStringLiteral("vcs-conflicting")] = QStringLiteral("dialog-warning");
alternatives[QStringLiteral("vcs-normal")] = QStringLiteral("dialog-information");
alternatives[QStringLiteral("view-bank-account-checking")] = QStringLiteral("go-home");
alternatives[QStringLiteral("view-bank-account")] = QStringLiteral("x-office-address-book");
alternatives[QStringLiteral("view-bank-account-savings")] = QStringLiteral("go-home");
alternatives[QStringLiteral("view-bank")] = QStringLiteral("go-home");
alternatives[QStringLiteral("view-calendar-journal")] = QStringLiteral("x-office-calendar");
alternatives[QStringLiteral("view-calendar-month")] = QStringLiteral("x-office-calendar");
alternatives[QStringLiteral("view-calendar")] = QStringLiteral("x-office-calendar");
alternatives[QStringLiteral("view-calendar-week")] = QStringLiteral("x-office-calendar");
alternatives[QStringLiteral("view-calendar-whatsnext")] = QStringLiteral("x-office-calendar");
alternatives[QStringLiteral("view-categories")] = QStringLiteral("folder-open");
alternatives[QStringLiteral("view-categories-expenditures")] = QStringLiteral("face-sad");
alternatives[QStringLiteral("view-categories-incomes")] = QStringLiteral("face-smile");
alternatives[QStringLiteral("view-file-columns")] = QStringLiteral("go-home");
alternatives[QStringLiteral("view-financial-list")] = QStringLiteral("go-home");
alternatives[QStringLiteral("view-investment")] = QStringLiteral("go-home");
alternatives[QStringLiteral("view-list-details")] = QStringLiteral("go-home");
alternatives[QStringLiteral("view-list-text")] = QStringLiteral("go-home");
alternatives[QStringLiteral("view-pim-calendar")] = QStringLiteral("x-office-spreadsheet");
alternatives[QStringLiteral("view-statistics")] = QStringLiteral("x-office-spreadsheet");
alternatives[QStringLiteral("window-duplicate")] = QStringLiteral("edit-copy");
alternatives[QStringLiteral("zoom-fit-width")] = QStringLiteral("media-playback-stop");
alternatives[QStringLiteral("smallclock")] = QLatin1String("");
alternatives[QStringLiteral("edit_undo")] = QStringLiteral("edit-undo");
alternatives[QStringLiteral("nextuntranslated")] = QStringLiteral("debug-execute-to-cursor");
alternatives[QStringLiteral("format-precision-less")] = QStringLiteral("visibility");
}
bool alternativeEmpty = false;
if (alternatives.contains(iName)) {
auto alternative = alternatives.value(iName);
alternativeEmpty = (alternative.isEmpty());
if (!alternativeEmpty) {
if (!iOverlays.isEmpty()) {
output = KDE::icon(alternative, iOverlays);
} else {
output = KDE::icon(alternative);
}
}
}
if (output.isNull() && !alternativeEmpty) {
SKGTRACE << "WARNING: Icon [" << iName << "] not found" << endl;
output = KDE::icon(QStringLiteral("script-error"));
if (output.isNull()) {
output = KDE::icon(QStringLiteral("image-missing"));
}
}
}
return output;
}
QString SKGServices::getMajorVersion(const QString& iVersion)
{
QString output = iVersion;
int pos = output.indexOf('.');
if (pos != -1) {
pos = output.indexOf('.', pos + 1);
if (pos != -1) {
output = output.left(pos);
}
}
return output;
}
QString SKGServices::getFullPathCommandLine(const QString& iCommandLine)
{
QString output = iCommandLine;
if (!output.isEmpty()) {
auto pathWords = SKGServices::splitCSVLine(output, QLatin1Char(' '));
QString fullpath = QStandardPaths::locate(QStandardPaths::GenericDataLocation, qApp->applicationName() % "/" % pathWords.at(0));
if (!fullpath.isEmpty()) {
pathWords[0] = fullpath;
output = pathWords.join(QLatin1Char(' '));
}
}
return output;
}
diff --git a/skgbasemodeler/skgservices.h b/skgbasemodeler/skgservices.h
index c3ecb2f78..760cf0c6f 100644
--- a/skgbasemodeler/skgservices.h
+++ b/skgbasemodeler/skgservices.h
@@ -1,662 +1,662 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGSERVICES_H
#define SKGSERVICES_H
/** @file
* This file defines classes SKGServices.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include <qurl.h>
#include <qdatetime.h>
#include <qhash.h>
#include <qicon.h>
#include <qstringlist.h>
#include "skgbasemodeler_export.h"
#include "skgdefine.h"
#include "skgerror.h"
/**
* @var SQLLITEERROR
* Must be used to generate a SKGError on an error coming from sqlite's API
* Example of usage:
* @code
* int rc=QSqlDatabase_close ( currentDatabase );
* if(rc!=SQLITE_OK) err=SKGError(SQLLITEERROR+rc, QSqlDatabase_errmsg(currentDatabase));
* @see SKGError
* @endcode
*/
static const int SQLLITEERROR = 10000;
class QSqlDatabase;
class QTextStream;
class QDomDocument;
class SKGDocument;
/**
* A map of strings ==> SKGQStringQStringMap
*/
using SKGQStringQStringMap = QHash<QString, QString>;
/**
* A list of QStringList ==> SKGStringListList
*/
using SKGStringListList = QList<QStringList>;
/**
* A list of int ==> SKGIntList
*/
using SKGIntList = QList<int>;
/**
* This class containing various static services
*/
class SKGBASEMODELER_EXPORT SKGServices : public QObject
{
Q_OBJECT
public:
/**
* Unit value
*/
struct SKGUnitInfo {
/** The name of the unit */
QString Name;
/** The amount of the unit */
double Value = 0.0;
/** The number of decimal of the unit*/
int NbDecimal = 2;
/** The symbol of the unit */
QString Symbol;
/** The country of the unit */
QString Country;
/** The Internet code of the unit */
QString Internet;
/** The download source */
QString Source;
/** The parent unit of the unit */
QString Parent;
/** The date of the unit */
QDate Date;
/** To know if the unit is obsolete or not */
bool Obsolete = false;
};
/**
* This structure defines attributes types
*/
enum AttributeType {
TEXT, /**< Text */
INTEGER, /**< Integer */
FLOAT, /**< Float */
DATE, /**< Date */
ID, /**< Unique identifier */
LINK, /**< Link */
BLOB, /**< Blob */
BOOL, /**< Boolean (Y, N) */
TRISTATE, /**< Tri-state (N, P, C) */
OTHER /**< Other or undefined */
};
/**
* This enumerate defines attributes types
*/
Q_ENUM(AttributeType)
/**
* Describe an attribute
*/
struct SKGAttributeInfo {
QString name; /**< The internal name of the attribute */
QString display; /**< The name for display of the attribute */
QIcon icon; /**< The icon for display of the attribute */
AttributeType type; /**< The type of the attribute */
bool notnull{}; /**< To know if the attribute can be null or not */
QString defaultvalue; /**< The default value of the attribute */
};
/**
* Search criteria
*/
struct SKGSearchCriteria {
QChar mode; /**< The mode '+' or '-' */
QStringList words; /**< The list of words */
};
/**
* A list of SKGSearchCriteria ==> SKGAttributesList
*/
using SKGSearchCriteriaList = QVector<SKGSearchCriteria>;
/**
* A list of SKGAttributeInfo ==> SKGAttributesList
*/
using SKGAttributesList = QVector<SKGAttributeInfo>;
/**
* This enumerate defines dump modes
*/
enum DumpMode {
DUMP_CSV, /**< To dump in CSV mode */
DUMP_TEXT /**< To dump in DUMP_TEXT mode */
};
/**
* This enumerate defines dump modes
*/
Q_ENUM(DumpMode)
/**
* Get list of search criteria of a string (example: +cat1 -abc +auto)
* @param iString a string to analyze
* @return the search criteria list
*/
static SKGServices::SKGSearchCriteriaList stringToSearchCriterias(const QString& iString);
/**
* Compute a SQL where clause with criteria and list of attributes
* @param iSearchCriterias the list of criteria
* @param iAttributes the list of attributes
* @param iDocument if a document is given, this document will be used to find the synonym of attributes
* @param iForDisplay to build the human readable string explaining the query
* @return the where clause
*/
static QString searchCriteriasToWhereClause(const SKGServices::SKGSearchCriteriaList& iSearchCriterias,
const QStringList& iAttributes,
const SKGDocument* iDocument,
bool iForDisplay = false);
/**
* Get environment variable
* @param iAttribute name of the variable
* @return value of the variable
*/
static QString getEnvVariable(const QString& iAttribute);
/**
* Convert a integer into a QString
* @param iNumber the integer to convert
* @return the converted QString
*/
static QString intToString(qlonglong iNumber);
/**
* Convert a QString into an integer
* @param iNumber the QString to convert
* @return the converted integer
*/
static qlonglong stringToInt(const QString& iNumber);
/**
* Convert a QString into a csv QString
* @param iNumber the QString to convert
* @return the converted csv string
*/
static QString stringToCsv(const QString& iNumber);
/**
* Convert a QStringList into a csv QString
* @param iList the QStringList to convert
* @param iSeparator the separator
* @return the converted csv string
*/
static QString stringsToCsv(const QStringList& iList, QChar iSeparator = QLatin1Char(';'));
/**
* Convert a QString to a html QString
* @param iString the QString to convert
* @return the converted html string
*/
static QString stringToHtml(const QString& iString);
/**
* Convert a html QString to a QString
* @param iString the QString to convert
* @return the converted string
*/
static QString htmlToString(const QString& iString);
/**
* Convert a double into a QString
* @param iNumber the double to convert
* @return the converted QString
*/
static QString doubleToString(double iNumber);
/**
* Convert a QString into an double
* @param iNumber the QString to convert
* @return the converted double
*/
static double stringToDouble(const QString& iNumber);
/**
* Convert a QDateTime into a QString ready for sql order.
* The output format is "%Y-%m-%d %H-%M-%S"
* @param iDateTime the time
* @return the converted QString
*/
static QString timeToString(const QDateTime& iDateTime);
/**
* Convert a date in a period
* @param iDate the time
* @param iPeriod the period.
* D for day, example: 2013-05-21
* W for week, example: 2013-W10
* M for month, example: 2013-05
* Q for quarter, example: 2013-Q2
* S for semester, example: 2013-S1
* Y for year, example: 2013
* @return the period string
*/
// cppcheck-suppress passedByValue
static QString dateToPeriod(QDate iDate, const QString& iPeriod);
/**
* Compute the number of working days between two dates.
* @param iFrom first date
* @param iTo seconde date
* @return the number of working days.
*/
// cppcheck-suppress passedByValue
static int nbWorkingDays(QDate iFrom, QDate iTo);
/**
* Convert a QString to QDateTime.
* @param iDateString the time. The format must be "%Y-%m-%d %H-%M-%S" or "%Y-%m-%d"
* @return the converted QDateTime
*/
static QDateTime stringToTime(const QString& iDateString);
/**
* Convert a QString to QDate.
* @param iDateString the date string. Could be a partial date like 1/12.
* @param iFixupBackward the date string is fixed in backward mode.
* @return the converted QDate
*/
static QDate partialStringToDate(const QString& iDateString, bool iFixupBackward = true);
/**
* Convert a QDateTime into a QString ready for sql order.
* The output format is "%Y-%m-%d"
* @param iDateTime the time
* @return the converted QString
*/
static QString dateToSqlString(const QDateTime& iDateTime);
/**
* Convert a QDate into a QString ready for sql order.
* The output format is "%Y-%m-%d"
* @param iDate the date
* @return the converted QString
*/
// cppcheck-suppress passedByValue
static QString dateToSqlString(QDate iDate);
/**
* Format a date.
* The output format is "YYYY-MM-DD"
* @param iDate the QString representing the input date
* @param iFormat the format of the input date. Must be in the following list:
* "YYYYMMDD","DDMMYYYY", "MMDDYYYY" "YYYY-MM-DD"
* "MM/DD/YY", "MM-DD-YY", "DD/MM/YY", "DD-MM-YY"
* "MM/DD/YYYY", "MM-DD-YYYY", "DD/MM/YYYY", "DD-MM-YYYY"
* "DD/MMM/YY" "DD-MMM-YY" DDMMMYY
* "DD/MMM/YYYY" "DD-MMM-YYYY" DDMMMYYYY
* @return the converted QString
*/
static QString dateToSqlString(const QString& iDate, const QString& iFormat);
/**
* Get the sql where clause corresponding to a period date.
* @param iPeriod the period date (some thing like "ALL" "2014" or "2014-04" or "2014-Q2" or "2014-S2"
* @param iDateAttribute the date attribute
* @return the where clause
*/
static QString getPeriodWhereClause(const QString& iPeriod, const QString& iDateAttribute = QStringLiteral("d_date"));
/**
* Get the last date of a period.
* @param iPeriod the period date
* @return the last date
*/
static QDate periodToDate(const QString& iPeriod);
/**
* Get the neighboring period.
* @param iPeriod the period date (some thing like "ALL" "2014" or "2014-04" or "2014-Q2" or "2014-S2"
* @param iDelta the delta to apply (-1 = previous, +1 = next)
* @return the neighboring period
*/
static QString getNeighboringPeriod(const QString& iPeriod, int iDelta = -1);
/**
* Get the format of a list of string dates
* @param iDates a list of string dates
* @return the supported format of all of these dates.
*/
static QString getDateFormat(const QStringList& iDates);
/**
* Get the string representing the percentage
* @param iAmount the amount
* @param iNbDecimal the number of decimals
* @return the string.
*/
static QString toPercentageString(double iAmount, int iNbDecimal = 2);
/**
* Get the string representing the amount
* @param iAmount the amount
* @param iSymbol the symbol
* @param iNbDecimal the number of decimals
* @return the string.
*/
static QString toCurrencyString(double iAmount, const QString& iSymbol = QString(), int iNbDecimal = 2);
/**
* Return string ready for sql order
* @param iString the string
* @return the escaped string
*/
static QString stringToSqlString(const QString& iString);
/**
* Split a csv line
* @param iString the csv line
* @param iSeparator the csv separator
* @param iCoteDefineBlock to indicate if the character double cote define a block
* @param oRealSeparator the real csv separator. If the csv string is strictly all enclosed then oRealSeparator will contain the real separator. Can be nullptr
* @return the list of all values in this csv line. Return an empty list if some cote are opened and not closed
*/
static QStringList splitCSVLine(const QString& iString, QChar iSeparator, bool iCoteDefineBlock, QChar* oRealSeparator);
/**
* Split a csv line
* @param iString the csv line
* @param iSeparator the csv separator
* @param iCoteDefineBlock to indicate if the character double cote define a block
* @return the list of all values in this csv line. Return an empty list if some cote are opened and not closed
*/
static QStringList splitCSVLine(const QString& iString, QChar iSeparator = QLatin1Char(';'), bool iCoteDefineBlock = true);
/**
* To dump a table
* @param iTable A table
* @param iMode dump mode
* @return the dump of the table
*/
static QStringList tableToDump(const SKGStringListList& iTable, SKGServices::DumpMode iMode);
/**
* Get the table name corresponding to a table or a view
* @param iTable table or view
* @return table name corresponding
*/
static QString getRealTable(const QString& iTable);
/**
* Copy a sqlite database from memory to file or from file to memory.
* It is used to do a load or a save
* @param iFileDb the sqlite pointer corresponding to a file database
* @param iMemoryDb the sqlite pointer corresponding to memory database
* @param iFromFileToMemory
* true: the copy is done from iFileDb to iMemoryDb (needed of a load)
* false: the copy is done from iMemoryDb to iFileDb (needed of a save)
* @param iPassword the password
* @return An object managing the error
* @see SKGError
*/
static SKGError copySqliteDatabase(const QSqlDatabase& iFileDb, const QSqlDatabase& iMemoryDb, bool iFromFileToMemory, const QString& iPassword = QString());
/**
* Copy a sqlite database into an XML document.
* @param iDb the sqlite pointer corresponding to database
* @param oDocument the xml document
* @return An object managing the error
* @see SKGError
*/
static SKGError copySqliteDatabaseToXml(const QSqlDatabase& iDb, QDomDocument& oDocument);
/**
* Execute a sqlite orders
* @param iDb a database pointer
* @param iSqlOrders the sql orders
* @return An object managing the error
* @see SKGError
*/
static SKGError executeSqliteOrders(const QSqlDatabase& iDb, const QStringList& iSqlOrders);
/**
* Execute a sqlite order
* @param iDb a database pointer
* @param iSqlOrder the sql order
* @param iBind the binded variables and values
* @param iLastId to retrieve the id of the last created object. Can be nullptr
* @return An object managing the error
* @see SKGError
*/
static SKGError executeSqliteOrder(const QSqlDatabase& iDb, const QString& iSqlOrder, const QMap<QString, QVariant>& iBind, int* iLastId);
/**
* Execute a sqlite order
* @param iDb a database pointer
* @param iSqlOrder the sql order
* @param iLastId to retrieve the id of the last created object. Can be nullptr
* @return An object managing the error
* @see SKGError
*/
static SKGError executeSqliteOrder(const QSqlDatabase& iDb, const QString& iSqlOrder, int* iLastId = nullptr);
/**
* Execute a select sqlite order and return the result in @p oResult
* @param iDb A database pointer
* @param iSqlOrder the sql order
* @param oResult the result of the select. It is a vector of vector of QString
* @return An object managing the error
* @see SKGError
*/
static SKGError executeSelectSqliteOrder(const QSqlDatabase& iDb, const QString& iSqlOrder, SKGStringListList& oResult);
/**
* Execute a select sqlite order returning one value and return the result in @p oResult
* @param iDb A database pointer
* @param iSqlOrder the sql order
* @param oResult the result of the select
* @return An object managing the error
* @see SKGError
*/
static SKGError executeSingleSelectSqliteOrder(const QSqlDatabase& iDb, const QString& iSqlOrder, QString& oResult);
/**
* dump a select sqlite order
* @param iDb A database pointer
* @param iSqlOrder the sql order
* @param iMode dump mode
* @return An object managing the error
* @see SKGError
*/
static SKGError dumpSelectSqliteOrder(const QSqlDatabase& iDb, const QString& iSqlOrder, SKGServices::DumpMode iMode = DUMP_TEXT);
/**
* dump a select sqlite order
* @param iDb A database pointer
* @param iSqlOrder the sql order
* @param oStream the output stream, nullptr for std output (cout)
* @param iMode dump mode
* @return An object managing the error
* @see SKGError
*/
static SKGError dumpSelectSqliteOrder(const QSqlDatabase& iDb, const QString& iSqlOrder, QTextStream* oStream, SKGServices::DumpMode iMode = DUMP_TEXT);
/**
* dump a select sqlite order
* @param iDb A database pointer
* @param iSqlOrder the sql order
* @param oResult the output
* @param iMode dump mode
* @return An object managing the error
* @see SKGError
*/
static SKGError dumpSelectSqliteOrder(const QSqlDatabase& iDb, const QString& iSqlOrder, QString& oResult, SKGServices::DumpMode iMode = DUMP_TEXT);
/**
* dump a select sqlite order
* @param iDb A database pointer
* @param iSqlOrder the sql order
* @param oResult the output
* @param iMode dump mode
* @return An object managing the error
* @see SKGError
*/
static SKGError dumpSelectSqliteOrder(const QSqlDatabase& iDb, const QString& iSqlOrder, QStringList& oResult, SKGServices::DumpMode iMode = DUMP_TEXT);
/**
* Read a property file
* @param iFileName A file name
* @param oProperties the properties
* @return An object managing the error
* @see SKGError
*/
static SKGError readPropertyFile(const QString& iFileName, QHash<QString, QString>& oProperties);
/**
* Return the current time in millisecond
* @return current
*/
static double getMicroTime();
/**
* Encrypt or decrypt a file
* @param iFileSource source file
* @param iFileTarget target file
* @param iPassword password
* @param iEncrypt true to encrypt, false to decrypt
* @param iHeaderFile the header file (useful for a magic mime type)
* @param oModeSQLCipher to know if the file is in SQLite or SQLCipher mode
* @return An object managing the error
* @see SKGError
*/
static SKGError cryptFile(const QString& iFileSource,
const QString& iFileTarget,
const QString& iPassword,
bool iEncrypt,
const QString& iHeaderFile,
bool& oModeSQLCipher);
/**
* Download a non local URL to a string
* @param iSourceUrl the non local URL
* @param oStream the downloaded string
* @return An object managing the error
* @see SKGError
*/
static SKGError downloadToStream(const QUrl& iSourceUrl, QByteArray& oStream);
/**
* Download a non local URL to a temporary file
* @param iSourceUrl the non local URL
* @param oTemporaryFile a temporary file. You have to delete it
* @return An object managing the error
* @see SKGError
*/
static SKGError download(const QUrl& iSourceUrl, QString& oTemporaryFile);
/**
* Upload from a source to a destination
* @param iSourceUrl the source
* @param iDescUrl the destination
* @return An object managing the error
* @see SKGError
*/
static SKGError upload(const QUrl& iSourceUrl, const QUrl& iDescUrl);
/**
* To enable, disable sql traces
*/
static int SKGSqlTraces;
/**
* Create a table with all values expressed in % of the column
* @param iTable table
* @param iOfColumns false to compute percentage of lines, true to compute perceentage of columns
* @param iAbsolute transform all values in absolute
* @return the table
*/
static SKGStringListList getPercentTable(const SKGStringListList& iTable, bool iOfColumns = true, bool iAbsolute = false);
/**
* Create a table in base 100
* @param iTable table
* @return the table
*/
static SKGStringListList getBase100Table(const SKGStringListList& iTable);
/**
* Create an historized table.
* Each column is the sum of previous ones
* @param iTable table
* @return the table
*/
static SKGStringListList getHistorizedTable(const SKGStringListList& iTable);
/**
* Encode a string for an url
* @param iString the decoded string
* @return the encoded string
*/
static QString encodeForUrl(const QString& iString);
/**
* Return the icon form theme with expected overlays
*
* @param iName The name of the icon
* @param iOverlays List of overlays
* @return The icon
*/
static QIcon fromTheme(const QString& iName, const QStringList& iOverlays = QStringList());
/**
* Get a major version (ex: 4.3) of a version (ex: 4.3.1)
* @param iVersion the version
* @return the major version
*/
static QString getMajorVersion(const QString& iVersion);
/**
* Get a full path command line
* @param iCommandLine command line
* @return the full path command line
*/
static QString getFullPathCommandLine(const QString& iCommandLine);
/**
* Get the next string
* @param iString the string
* @return the next string
*/
static QString getNextString(const QString& iString);
private:
Q_DISABLE_COPY(SKGServices)
static SKGError m_lastCallbackError;
};
#endif
diff --git a/skgbasemodeler/skgtraces.cpp b/skgbasemodeler/skgtraces.cpp
index 77638d574..1c0f73b95 100644
--- a/skgbasemodeler/skgtraces.cpp
+++ b/skgbasemodeler/skgtraces.cpp
@@ -1,226 +1,226 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file implements classes SKGTraces.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgtraces.h"
#ifdef Q_OS_WIN
#include <windows.h>
#else
#include <sys/time.h>
#endif
#include "skgerror.h"
#include "skgservices.h"
/**
* To generate a colorized string
*/
#define COLORED(TEXT) \
("\x1b[3"%QString::number(1+(((SKGTraces::SKGIndentTrace.count()-2)/2)%7))%'m'%(TEXT)%"\x1b[39m")
/**
* To generate a red string
*/
#define COLOREDRED(TEXT) \
(QStringLiteral("\x1b[31m")%(TEXT)%"\x1b[39m")
// ===================================================================
int SKGTraces::SKGLevelTrace = SKGServices::stringToInt(SKGServices::getEnvVariable(QStringLiteral("SKGTRACE")));
bool SKGTraces::SKGPerfo = !SKGServices::getEnvVariable(QStringLiteral("SKGTRACEPERFO")).isEmpty();
QString SKGTraces::SKGIndentTrace = QStringLiteral("##");
SKGPerfoMap SKGTraces::m_SKGPerfoMethode;
SKGQStringStack SKGTraces::m_SKGPerfoPathMethode;
QTextStream SKGTraces::SKGCout(stdout, QIODevice::WriteOnly);
// ===================================================================
SKGTraces::SKGTraces(int iLevel, const char* iName, SKGError* iRC)
{
init(iLevel, QLatin1String(iName), iRC);
}
SKGTraces::SKGTraces(int iLevel, const QString& iName, SKGError* iRC)
{
init(iLevel, iName, iRC);
}
void SKGTraces::init(int iLevel, const QString& iName, SKGError* iRC)
{
IFSKGTRACEL(iLevel) {
m_mame = iName;
m_output = true;
m_rc = iRC;
SKGIndentTrace += QStringLiteral(" ");
SKGTRACE << COLORED('>' % m_mame) << endl;
} else {
m_rc = nullptr;
m_output = false;
}
if (SKGPerfo) {
m_profiling = true;
m_mame = iName;
// Push the method in the stack
SKGTraces::m_SKGPerfoPathMethode.push(m_mame);
// Pour les mesures de perfos
#ifdef Q_OS_WIN
m_elapse = static_cast<double>(GetTickCount());
#else
struct timeval tv {};
struct timezone tz {};
gettimeofday(&tv, &tz);
m_elapse = (static_cast<double>(1000.0 * tv.tv_sec)) + (static_cast<double>(tv.tv_usec / 1000.0));
#endif
// Searching the key in the map
m_it = SKGTraces::m_SKGPerfoMethode.find(m_mame);
if (m_it == SKGTraces::m_SKGPerfoMethode.end()) {
// Not found ==> initialisation
SKGPerfoInfo init{};
init.NbCall = 0;
init.Time = 0;
init.TimePropre = 0;
init.TimeMin = 99999999;
init.TimeMax = -1;
// Add the line
SKGTraces::m_SKGPerfoMethode[m_mame] = init;
// find again
m_it = SKGTraces::m_SKGPerfoMethode.find(m_mame);
}
} else {
m_profiling = false;
m_elapse = -1;
}
}
SKGTraces::~SKGTraces()
{
// Get delta time
if (m_elapse >= 0) {
#ifdef Q_OS_WIN
m_elapse = static_cast<double>(GetTickCount());
#else
struct timeval tv {};
struct timezone tz {};
gettimeofday(&tv, &tz);
m_elapse = (static_cast<double>(1000.0 * tv.tv_sec)) + (static_cast<double>(tv.tv_usec / 1000.0)) - m_elapse;
#endif
}
if (m_output) {
SKGTRACESUITE << SKGTraces::SKGIndentTrace << COLORED('<' % m_mame);
if (m_rc != nullptr) {
SKGTRACESUITE << (m_rc->isSucceeded() ? QString(COLORED(" RC=" % m_rc->getFullMessage())) : QString(COLOREDRED(" RC=" % m_rc->getFullMessage())));
}
if (m_profiling) {
SKGTRACESUITE << QStringLiteral(" TIME=") << m_elapse << QStringLiteral(" ms");
}
SKGTRACESUITE << endl;
SKGIndentTrace.resize(SKGIndentTrace.length() - 2);
m_rc = nullptr;
}
if (m_profiling) {
// Update values
++(m_it.value().NbCall);
m_it.value().Time += m_elapse;
m_it.value().TimePropre += m_elapse;
if (m_elapse > m_it.value().TimeMax) {
m_it.value().TimeMax = m_elapse;
}
if (m_elapse < m_it.value().TimeMin) {
m_it.value().TimeMin = m_elapse;
}
if (!SKGTraces::m_SKGPerfoPathMethode.empty() && SKGTraces::m_SKGPerfoPathMethode.top() == m_mame) {
// Remove current method from stack
SKGTraces::m_SKGPerfoPathMethode.pop();
// Get previous method name
if (!SKGTraces::m_SKGPerfoPathMethode.empty()) {
QString previousMethode = qAsConst(SKGTraces::m_SKGPerfoPathMethode).top();
// Searching the key in the map
m_it = SKGTraces::m_SKGPerfoMethode.find(previousMethode);
if (m_it != SKGTraces::m_SKGPerfoMethode.end()) {
m_it.value().TimePropre -= m_elapse;
}
}
}
}
}
void SKGTraces::cleanProfilingStatistics()
{
SKGTraces::m_SKGPerfoMethode.clear();
}
void SKGTraces::dumpProfilingStatistics()
{
QStringList dump = getProfilingStatistics();
int nbl = dump.count();
for (int i = 0; i < nbl; ++i) {
SKGTRACE << dump.at(i) << endl;
}
}
QStringList SKGTraces::getProfilingStatistics()
{
QStringList output;
if (SKGPerfo) {
output.push_back(QStringLiteral("method ; nb call ; millisecondes ; average ; min ; max ; own time ; average own time"));
SKGPerfoMap SKGPerfoMethodeCopy = m_SKGPerfoMethode;
while (!SKGPerfoMethodeCopy.empty()) {
// Recheche du temps propre maximal
double maxtime = -1;
SKGPerfoMapIterator max;
SKGPerfoMapIterator it2;
for (it2 = SKGPerfoMethodeCopy.begin() ; it2 != SKGPerfoMethodeCopy.end(); ++it2) {
if (it2.value().TimePropre > maxtime || maxtime == -1) {
maxtime = it2.value().TimePropre;
max = it2;
}
}
// dump max
if (maxtime != -1) {
output.push_back(max.key()
% " ; " % SKGServices::intToString(max.value().NbCall)
% " ; " % SKGServices::doubleToString(max.value().Time)
% " ; " % SKGServices::doubleToString((max.value().Time) / (static_cast<double>(max.value().NbCall)))
% " ; " % SKGServices::doubleToString(max.value().TimeMin)
% " ; " % SKGServices::doubleToString(max.value().TimeMax)
% " ; " % SKGServices::doubleToString(max.value().TimePropre)
% " ; " % SKGServices::doubleToString((max.value().TimePropre) / (static_cast<double>(max.value().NbCall))));
// Remove it
SKGPerfoMethodeCopy.erase(max);
}
}
}
return output;
}
diff --git a/skgbasemodeler/skgtraces.h b/skgbasemodeler/skgtraces.h
index 930509d3a..f8bfad952 100644
--- a/skgbasemodeler/skgtraces.h
+++ b/skgbasemodeler/skgtraces.h
@@ -1,262 +1,262 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGTRACES_H
#define SKGTRACES_H
/** @file
* This file defines classes SKGTraces an macros.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include <qmap.h>
#include <qstack.h>
#include <qstringlist.h>
#include <qtextstream.h>
#include "skgdefine.h"
/**
* Macro for traces
*/
#define SKGTRACE SKGTRACESUITE << SKGTraces::SKGIndentTrace
/**
* Macro for traces
*/
#define SKGTRACESUITE SKGTraces::SKGCout
/**
* Macro for traces
*/
#define SKGTRACESEPARATOR SKGTRACE << "##############################################\n" << flush;
#ifdef SKGNOTRACES
/**
* Macro for traces
*/
#define IFSKGTRACEL(Level) if (false)
#else
/**
* Macro for traces
*/
#define IFSKGTRACEL(Level) if ((Level) <= SKGTraces::SKGLevelTrace)
#endif
/**
* Macro for traces
*/
#define SKGTRACEL(Level) SKGTRACESUITEL(Level) << SKGTraces::SKGIndentTrace
/**
* Macro for traces
*/
#define SKGTRACESUITEL(Level) IFSKGTRACEL(Level) SKGTRACESUITE
/**
* This structure represents one performance measure
*/
struct SKGPerfoInfo {
/** The number of call for the method */
int NbCall;
/** The global time passed in the method */
double Time;
/** The time consumed by the method */
double TimePropre;
/** The minimum time passed in the method */
double TimeMin;
/** The maximum time passed in the method */
double TimeMax;
};
/**
* A map of strings ==> SKGPerfoInfo
* @see SKGPerfoMapIterator
*/
using SKGPerfoMap = QMap<QString, SKGPerfoInfo>;
/**
* A iterator for SKGPerfoMap ==> SKGPerfoInfo
* @see SKGPerfoMap
*/
using SKGPerfoMapIterator = QMap<QString, SKGPerfoInfo>::Iterator;
/**
* A stack of strings
*/
using SKGQStringStack = QStack<QString>;
class SKGError;
/**
* This class manages traces
*/
class SKGBASEMODELER_EXPORT SKGTraces final
{
public:
/**
* Constructor
* @param iName The message to display
* @param iLevel The level to display this error.
* The error will be display if the level of traces asked is greater or equal than
* the level of this trace (iLevel)
* @param iRC A pointer of the error object of the calling method
* The SKGError
*/
explicit SKGTraces(int iLevel, const char* iName, SKGError* iRC);
/**
* Constructor
* @param iName The message to display
* @param iLevel The level to display this error.
* The error will be display if the level of traces asked is greater or equal than
* the level of this trace (iLevel)
* @param iRC A pointer of the error object of the calling method
* The SKGError
*/
SKGTraces(int iLevel, const QString& iName, SKGError* iRC);
/**
* Destructor
*/
~SKGTraces();
/**
* Clean profiling statistics
*/
static void cleanProfilingStatistics();
/**
* Get profiling statistics
*/
static QStringList getProfilingStatistics();
/**
* Dump profiling statistics
*/
static void dumpProfilingStatistics();
/**
* Standard output stream for traces
*/
static QTextStream SKGCout;
/**
* The current level of indentation
*/
static QString SKGIndentTrace;
/**
* The current level of taces
*/
static int SKGLevelTrace;
/**
* To enable, disable profiling
*/
static bool SKGPerfo;
private:
Q_DISABLE_COPY(SKGTraces)
void init(int iLevel, const QString& iName, SKGError* iRC);
QString m_mame;
bool m_output = false;
bool m_profiling = false;
SKGError* m_rc = nullptr;
double m_elapse = 0.0;
SKGPerfoMapIterator m_it;
static SKGPerfoMap m_SKGPerfoMethode;
static SKGQStringStack m_SKGPerfoPathMethode;
};
/**
* Macro for traces
*/
#define TOKENPASTE(x, y) x ## y
/**
* Macro for traces
*/
#define TOKENPASTE2(x, y) TOKENPASTE(x, y)
#ifdef SKGNOTRACES
/**
* Macro for traces
*/
#define SKGTRACEINRC(Level, Name, RC)
/**
* Macro for traces
*/
#define SKGTRACEIN(Level, Name)
#else
/**
* Macro for traces
*/
#define SKGTRACEINRC(Level, Name, RC) \
SKGTraces TOKENPASTE2(trace1_, __LINE__)(Level, Name, &(RC));
/**
* Macro for traces
*/
#define SKGTRACEIN(Level, Name) \
SKGTraces TOKENPASTE2(trace2_, __LINE__)(Level, Name, nullptr);
#endif
#ifdef SKGFULLTRACES
/**
* Macro for traces
*/
#define _SKGTRACEINRC(Level, Name, RC) SKGTRACEINRC(Level, Name, RC)
/**
* Macro for traces
*/
#define _SKGTRACEIN(Level, Name) SKGTRACEIN(Level, Name)
#else
/**
* Macro for traces
*/
#define _SKGTRACEINRC(Level, Name, RC)
/**
* Macro for traces
*/
#define _SKGTRACEIN(Level, Name)
#endif
/**
* Macro for traces
*/
#define SKGTRACEINFUNCRC(Level, RC) \
SKGTRACEINRC(Level, Q_FUNC_INFO, RC)
/**
* Macro for traces
*/
#define SKGTRACEINFUNC(Level) \
SKGTRACEIN(Level, Q_FUNC_INFO)
/**
* Macro for traces
*/
#define _SKGTRACEINFUNCRC(Level, RC) \
_SKGTRACEINRC(Level, Q_FUNC_INFO, RC)
/**
* Macro for traces
*/
#define _SKGTRACEINFUNC(Level) \
_SKGTRACEIN(Level, Q_FUNC_INFO)
#endif
diff --git a/skgbasemodeler/skgtransactionmng.cpp b/skgbasemodeler/skgtransactionmng.cpp
index cc7613564..677aca1cd 100644
--- a/skgbasemodeler/skgtransactionmng.cpp
+++ b/skgbasemodeler/skgtransactionmng.cpp
@@ -1,59 +1,59 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file implements classes SKGTransactionMng.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgtransactionmng.h"
#include "skgdocument.h"
#include "skgerror.h"
SKGTransactionMng::SKGTransactionMng(SKGDocument* iDocument,
const QString& iName,
SKGError* iError,
int iNbStep,
bool iRefreshViews)
{
m_parentDocument = iDocument;
m_error = iError;
m_errorInBeginTransaction = false;
if ((m_parentDocument != nullptr) && (m_error != nullptr)) {
*m_error = m_parentDocument->beginTransaction(iName, iNbStep, QDateTime::currentDateTime(), iRefreshViews);
m_errorInBeginTransaction = (m_error->isFailed());
}
}
SKGTransactionMng::~SKGTransactionMng()
{
if ((m_parentDocument != nullptr) && (m_error != nullptr)) {
// close the transaction based on error
if (!m_errorInBeginTransaction) {
if (m_error->isSucceeded()) {
SKGError opError = *m_error; // In case of the message is not empty
*m_error = m_parentDocument->endTransaction(true);
if (m_error->isSucceeded()) {
*m_error = opError;
}
} else {
m_parentDocument->endTransaction(false);
}
}
m_parentDocument = nullptr;
m_error = nullptr;
}
}
diff --git a/skgbasemodeler/skgtransactionmng.h b/skgbasemodeler/skgtransactionmng.h
index 45e9e8d35..d45b844c9 100644
--- a/skgbasemodeler/skgtransactionmng.h
+++ b/skgbasemodeler/skgtransactionmng.h
@@ -1,143 +1,143 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGTRANSACTIONMNG_H
#define SKGTRANSACTIONMNG_H
/** @file
* This file defines classes SKGTransactionMng and a macro.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgdefine.h"
#include "skgtraces.h"
#include <qstring.h>
/**
* @def SKGBEGINTRANSACTION(Document, Name, Error)
* Macro to start a new transaction
* Example of usage:
* @code
* { // BEGIN OF THE TRANSACTION SCOPE
* // Error management of the scope
* SKGError err;
*
* // Begin transaction
* SKGBEGINTRANSACTION(Your_SKGDocument, QStringLiteral("The_Name_Of_The_Transaction"), err)
*
* // Check the error
* if(!err)
* {
* // You code here
* // At the end the err variable must contain the result of your operation
* }
*
* // A commit or rollback is done here because the scope is close
* } // END OF THE TRANSACTION
* @endcode
*/
#define SKGBEGINTRANSACTION(Document, Name, Error) \
SKGTransactionMng TOKENPASTE2(transaction_, __LINE__)(&(Document), Name, &(Error));
/**
* @def SKGBEGINLIGHTTRANSACTION(Document, Name, Error)
* Macro to start a new light transaction (without views computation)
*/
#define SKGBEGINLIGHTTRANSACTION(Document, Name, Error) \
SKGTransactionMng transactionlight_(&(Document), Name, &(Error), 1, false);
/**
* @def SKGBEGINPROGRESSTRANSACTION(Document, Name, Error)
* Macro to start a new transaction
* Example of usage:
* @code
* { // BEGIN OF THE TRANSACTION SCOPE
* // Error management of the scope
* SKGError err;
*
* // Begin transaction
* SKGBEGINPROGRESSTRANSACTION(Your_SKGDocument, "The_Name_Of_The_Transaction", err, 5)
*
* // Check the error
* if(!err)
* {
* // You code here
* // At the end the err variable must contain the result of your operation
* Your_SKGDocument.stepForward(1);
* ...
* Your_SKGDocument.stepForward(2);
* ...
* Your_SKGDocument.stepForward(3);
* ...
* }
*
* // A commit or rollback is done here because the scope is close
* } // END OF THE TRANSACTION
* @endcode
*/
#define SKGBEGINPROGRESSTRANSACTION(Document, Name, Error, Nb) \
SKGTransactionMng TOKENPASTE2(transaction_, __LINE__)(&(Document), Name, &(Error), Nb);
/**
* @def SKGBEGINLIGHTPROGRESSTRANSACTION(Document, Name, Error)
* Macro to start a new light transaction (without views computation)
*/
#define SKGBEGINLIGHTPROGRESSTRANSACTION(Document, Name, Error, Nb) \
SKGTransactionMng TOKENPASTE2(transactionlight_, __LINE__)(&(Document), Name, &(Error), Nb, false);
/**
* @def SKGENDTRANSACTION(Document, Error)
* End correctly a transaction
*/
#define SKGENDTRANSACTION(Document, Error) \
if (!(Error)) {(Error) = (Document)->endTransaction(true);} \
else {(Document)->endTransaction(false);}
class SKGError;
class SKGDocument;
/**
* Facilitate the transaction management
*/
class SKGBASEMODELER_EXPORT SKGTransactionMng
{
public:
/**
* Constructor.
* This class must be used with the macro
* @see SKGBEGINTRANSACTION
* @param iDocument The parent document of the transaction
* @param iName The message of the transaction
* @param iError A pointer of the error object of the calling scope
* @param iNbStep the number of step in this transaction.
* @param iRefreshViews at the end of the transaction, computed views will be recomputed.
* It is used to call the progress callback.
* @see The SKGError
*/
explicit SKGTransactionMng(SKGDocument* iDocument, const QString& iName, SKGError* iError, int iNbStep = 1, bool iRefreshViews = true);
/**
* Destructor
*/
virtual ~SKGTransactionMng();
private:
Q_DISABLE_COPY(SKGTransactionMng)
SKGError* m_error;
SKGDocument* m_parentDocument;
bool m_errorInBeginTransaction;
};
#endif
diff --git a/skgbasemodeler/skgtreemap.cpp b/skgbasemodeler/skgtreemap.cpp
index 9f8ad8dce..10404c12f 100644
--- a/skgbasemodeler/skgtreemap.cpp
+++ b/skgbasemodeler/skgtreemap.cpp
@@ -1,279 +1,279 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file implements classes SKGTreeMap.
*
* @author Stephane MANKOWSKI
*/
#include "skgtreemap.h"
#include "skgtraces.h"
SKGTreeMap::SKGTreeMap(QString iID,
double iValue,
double iX,
double iY,
double iW,
double iH)
: m_id(std::move(iID)), m_value(iValue), m_x(iX), m_y(iY), m_w(iW), m_h(iH)
{}
SKGTreeMap::~SKGTreeMap() = default;
QString SKGTreeMap::getID() const
{
return m_id;
}
double SKGTreeMap::getValue() const
{
return m_value;
}
void SKGTreeMap::setX(double iX)
{
m_x = iX;
}
double SKGTreeMap::getX() const
{
return m_x;
}
void SKGTreeMap::setY(double iY)
{
m_y = iY;
}
double SKGTreeMap::getY() const
{
return m_y;
}
void SKGTreeMap::setW(double iW)
{
m_w = iW;
}
double SKGTreeMap::getW() const
{
return m_w;
}
void SKGTreeMap::setH(double iH)
{
m_h = iH;
}
double SKGTreeMap::getH() const
{
return m_h;
}
void SKGTreeMap::addChild(const SKGTreeMap& iChildren)
{
m_children.append(iChildren);
}
QList<SKGTreeMap> SKGTreeMap::getChildren() const
{
return m_children;
}
void SKGTreeMap::computeValuesAndSort()
{
// Compute the value
if (m_children.count() != 0) {
// Compute the value
double sum = 0.0;
for (auto& item : m_children) {
item.computeValuesAndSort();
sum += item.getValue();
}
// Set sum on tile
m_value = sum;
// Sort the children by abs(value) desc
std::sort(m_children.begin(), m_children.end(), [](const SKGTreeMap & a, const SKGTreeMap & b) -> bool {
if (qAbs(a.getValue() - b.getValue()) < 10e-5)
{
return a.getID() < b.getID();
}
return a.getValue() > b.getValue();
});
}
}
QMap<QString, SKGTreeMap> SKGTreeMap::getAllTilesById() const
{
QMap<QString, SKGTreeMap> output;
output.insert(getID(), *this);
for (const auto& item : qAsConst(m_children)) {
output.insert(item.getID(), item);
auto children = item.getAllTilesById();
for (const auto& item2 : qAsConst(children)) {
output.insert(item2.getID(), item2);
}
}
return output;
}
void SKGTreeMap::compute()
{
// Prepare all the structure
computeValuesAndSort();
// If value = 0
bool isValueZero = (getValue() < 10e-5);
// Start the layout
int nb = m_children.count();
if (nb == 0) {
// Nothing to do
} else if (nb == 1) {
// The child item must take the full place
m_children[0].setX(getX());
m_children[0].setY(getY());
m_children[0].setW(getW());
m_children[0].setH(getH());
m_children[0].compute();
} else if (nb == 2) {
if (getW() >= getH()) {
// Horizontal mode
// Set the first
m_children[0].setX(getX());
m_children[0].setY(getY());
m_children[0].setW(isValueZero ? 0.0 : getW()*m_children.at(0).getValue() / getValue());
m_children[0].setH(getH());
m_children[0].compute();
// Set the second
m_children[1].setX(getX() + m_children.at(0).getW());
m_children[1].setY(getY());
m_children[1].setW(getW() - m_children.at(0).getW());
m_children[1].setH(getH());
m_children[1].compute();
} else {
// Vertical
// Set the first
m_children[0].setX(getX());
m_children[0].setY(getY());
m_children[0].setW(getW());
m_children[0].setH(isValueZero ? 0.0 : getH()*m_children.at(0).getValue() / getValue());
m_children[0].compute();
// Set the second
m_children[1].setX(getX());
m_children[1].setY(getY() + m_children.at(0).getH());
m_children[1].setW(getW());
m_children[1].setH(getH() - m_children.at(0).getH());
m_children[1].compute();
}
} else {
// Compute the number of element that can be aligned
double sum = 0.0;
int optimum = 0;
double lastratio = 1000.0;
double previous_gw = 0.0;
double previous_gh = 0.0;
for (int i = 0; i < nb; ++i) {
sum += m_children.at(i).getValue();
if (getW() >= getH()) {
double gw = isValueZero ? 0.0 : getW() * sum / getValue();
double ih = isValueZero ? 0.0 : m_children.at(i).getValue() * getW() * getH() / (gw * getValue());
double ratio = qMax(ih / gw, gw / ih);
if (ratio > lastratio) {
// This ratio is worst than te previous one
sum -= m_children.at(i).getValue();
optimum = i - 1;
break;
}
lastratio = ratio;
previous_gw = gw;
} else {
double gh = isValueZero ? 0.0 : getH() * sum / getValue();
double iw = isValueZero ? 0.0 : m_children.at(i).getValue() * getW() * getH() / (gh * getValue());
double ratio = qMax(gh / iw, iw / gh);
if (ratio > lastratio) {
// This ratio is worst than te previous one
sum -= m_children.at(i).getValue();
optimum = i - 1;
break;
}
lastratio = ratio;
previous_gh = gh;
}
}
// Set the layout
double current_xy = 0.0;
for (int i = 0; i <= optimum; ++i) {
if (getW() >= getH()) {
double ih = isValueZero ? 0.0 : m_children.at(i).getValue() * getW() * getH() / (previous_gw * getValue());
m_children[i].setX(getX());
m_children[i].setY(getY() + current_xy);
m_children[i].setW(previous_gw);
m_children[i].setH(ih);
current_xy += ih;
m_children[i].compute();
} else {
double iw = isValueZero ? 0.0 : m_children.at(i).getValue() * getW() * getH() / (previous_gh * getValue());
m_children[i].setX(getX() + current_xy);
m_children[i].setY(getY());
m_children[i].setW(iw);
m_children[i].setH(previous_gh);
current_xy += iw;
m_children[i].compute();
}
}
// Treat the rest
if (optimum == -1) {
optimum = 1;
}
if (optimum < nb - 1) {
// Create a new SKGTreeMap corresponding to the rest
double x = getW() >= getH() ? getX() + previous_gw : getX();
double y = getW() >= getH() ? getY() : getY() + previous_gh;
double w = getW() >= getH() ? getW() - previous_gw : getW();
double h = getW() >= getH() ? getH() : getH() - previous_gh;
SKGTreeMap rest(QLatin1String(""), getValue() - sum, x, y, w, h);
// Add all items to compute
for (int i = optimum + 1; i < nb; ++i) {
rest.addChild(m_children.at(i));
}
// Compute
rest.compute();
auto computed = rest.getChildren();
for (int i = optimum + 1; i < nb; ++i) {
m_children[i] = computed[i - optimum - 1];
}
}
}
}
diff --git a/skgbasemodeler/skgtreemap.h b/skgbasemodeler/skgtreemap.h
index bb95bfae3..82e2e76c8 100644
--- a/skgbasemodeler/skgtreemap.h
+++ b/skgbasemodeler/skgtreemap.h
@@ -1,152 +1,152 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGTREEMAP_H
#define SKGTREEMAP_H
/** @file
* This file defines classes SKGTreeMap.
*
* @author Stephane MANKOWSKI
*/
#include <qlist.h>
#include <qmap.h>
#include <qstring.h>
#include "skgbasemodeler_export.h"
/**
* This class allows to compute a tree map
*/
class SKGBASEMODELER_EXPORT SKGTreeMap
{
public:
/**
* Constructor
* @param iID The ID of this tile
* @param iValue The value (this attribute is only needed for leaves)
* @param iX The x of the tile
* @param iY The y of the tile
* @param iW The width of the tile
* @param iH The height of the tile
*/
explicit SKGTreeMap(QString iID = QLatin1String(""),
double iValue = 0.0,
double iX = 0.0,
double iY = 0.0,
double iW = 100.0,
double iH = 100.0);
/**
* Destructor
*/
~SKGTreeMap();
/**
* Add a child tile
* @param iChildren The child tile
*/
void addChild(const SKGTreeMap& iChildren);
/**
* Compute the tiles layout
*/
void compute();
/**
* Get children tile
* @return children tile
*/
QList<SKGTreeMap> getChildren() const;
/**
* Get the ID of the tile
* @return the ID of the tile
*/
QString getID() const;
/**
* Get the value of the tile
* @return value x of the tile
*/
double getValue() const;
/**
* Set the x of the tile
* @param iX The x of the tile
*/
void setX(double iX);
/**
* Get the x of the tile
* @return the x of the tile
*/
double getX() const;
/**
* Set the y of the tile
* @param iY The y of the tile
*/
void setY(double iY);
/**
* Get the y of the tile
* @return the y of the tile
*/
double getY() const;
/**
* Set the width of the tile
* @param iW The width of the tile
*/
void setW(double iW);
/**
* Get the width of the tile
* @return the width of the tile
*/
double getW() const;
/**
* Set the height of the tile
* @param iH The height of the tile
*/
void setH(double iH);
/**
* Get the height of the tile
* @return the height of the tile
*/
double getH() const;
/**
* Get all tiles by ID
* @return all tiles
*/
QMap<QString, SKGTreeMap> getAllTilesById() const;
private:
QString m_id;
double m_value;
double m_x;
double m_y;
double m_w;
double m_h;
QList<SKGTreeMap> m_children;
void computeValuesAndSort();
};
#endif // SKGTREEMAP_H
diff --git a/skgsqlcipher/CMakeLists.txt b/skgsqlcipher/CMakeLists.txt
index e009f00d2..12fbd375c 100644
--- a/skgsqlcipher/CMakeLists.txt
+++ b/skgsqlcipher/CMakeLists.txt
@@ -1,33 +1,33 @@
#***************************************************************************
#* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
#* *
#* 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 <http://www.gnu.org/licenses/> *
+#* along with this program. If not, see <https://www.gnu.org/licenses/> *
#***************************************************************************
MESSAGE( STATUS "..:: SKGSQLCIPHER ::..")
PROJECT(skgsqlcipher)
LINK_DIRECTORIES (${LIBRARY_OUTPUT_PATH})
SET(skgsqlcipher_sources skgsqlcipherdriverplugin.cpp qsql_sqlite.cpp)
ADD_LIBRARY(libskgsqlcipher MODULE ${skgsqlcipher_sources})
TARGET_INCLUDE_DIRECTORIES(libskgsqlcipher PRIVATE ${Qt5Sql_PRIVATE_INCLUDE_DIRS} ${SQLCIPHER_INCLUDE_DIRS})
TARGET_LINK_LIBRARIES(libskgsqlcipher Qt5::Sql ${SQLCIPHER_LIBRARIES})
GENERATE_EXPORT_HEADER(libskgsqlcipher BASE_NAME skgsqlcipher)
########### install files ###############
INSTALL(TARGETS libskgsqlcipher DESTINATION ${KDE_INSTALL_QTPLUGINDIR}/sqldrivers)
diff --git a/skgsqlcipher/skgsqlcipherdriverplugin.cpp b/skgsqlcipher/skgsqlcipherdriverplugin.cpp
index 5695b47a2..dba3aa524 100644
--- a/skgsqlcipher/skgsqlcipherdriverplugin.cpp
+++ b/skgsqlcipher/skgsqlcipherdriverplugin.cpp
@@ -1,51 +1,51 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+* along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file defines classes SKGSQLCipherDriverPlugin.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "qsql_sqlite_p.h"
#include <qsqldriverplugin.h>
#include <qstringlist.h>
QT_BEGIN_NAMESPACE
class SKGSQLCipherDriverPlugin : public QSqlDriverPlugin
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QSqlDriverFactoryInterface" FILE "skgsqlcipherdriverplugin.json")
public:
SKGSQLCipherDriverPlugin()
= default;
QSqlDriver* create(const QString& iName) override
{
if (iName == QStringLiteral("SKGSQLCIPHER")) {
auto driver = new QSQLiteDriver();
return driver;
}
return nullptr;
}
};
QT_END_NAMESPACE
#include "skgsqlcipherdriverplugin.moc"
diff --git a/skrooge/CMakeLists.txt b/skrooge/CMakeLists.txt
index 11f94e870..dc8afd428 100644
--- a/skrooge/CMakeLists.txt
+++ b/skrooge/CMakeLists.txt
@@ -1,105 +1,105 @@
#***************************************************************************
#* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
#* *
#* 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 <http://www.gnu.org/licenses/> *
+#* along with this program. If not, see <https://www.gnu.org/licenses/> *
#***************************************************************************
MESSAGE( STATUS "..:: CMAKE SKROOGE ::..")
PROJECT(SKROOGE)
IF(SKG_WEBENGINE)
MESSAGE( STATUS " Mode WebEngine")
ADD_DEFINITIONS(-DSKG_WEBENGINE=${SKG_WEBENGINE})
ENDIF(SKG_WEBENGINE)
FIND_PACKAGE(KF5 5.0.0 REQUIRED COMPONENTS
DBusAddons # Tier 1
)
LINK_DIRECTORIES (${LIBRARY_OUTPUT_PATH})
SET(skrooge_SRCS
main.cpp
)
INCLUDE(ECMAddAppIcon)
file(GLOB ICONS_SRCS "${CMAKE_CURRENT_SOURCE_DIR}/icons_hicolor/[0-9][0-9]-apps-skrooge.png")
ECM_ADD_APP_ICON(skrooge_SRCS ICONS
"${CMAKE_CURRENT_SOURCE_DIR}/icons_hicolor/256-apps-skrooge.png"
"${CMAKE_CURRENT_SOURCE_DIR}/icons_hicolor/128-apps-skrooge.png"
${ICONS_SRCS})
ADD_EXECUTABLE(skrooge ${skrooge_SRCS})
TARGET_LINK_LIBRARIES(skrooge KF5::DBusAddons skgbasemodeler skgbasegui skgbankmodeler skgbankgui)
########### install files ###############
INSTALL(TARGETS skrooge ${INSTALL_TARGETS_DEFAULT_ARGS} )
INSTALL(PROGRAMS org.kde.skrooge.desktop DESTINATION ${XDG_APPS_INSTALL_DIR} )
INSTALL(FILES org.kde.skrooge.appdata.xml DESTINATION ${KDE_INSTALL_METAINFODIR} )
INSTALL(DIRECTORY theme DESTINATION ${KDE_INSTALL_DATADIR}/skrooge FILES_MATCHING PATTERN "*.css"
PATTERN ".svn" EXCLUDE
PATTERN "CMakeFiles" EXCLUDE
PATTERN "Testing" EXCLUDE)
INSTALL(FILES ${PROJECT_SOURCE_DIR}/skrooge.notifyrc DESTINATION ${KDE_INSTALL_KNOTIFY5RCDIR} )
ECM_INSTALL_ICONS(ICONS
icons_hicolor/16-apps-skrooge-black.png
icons_hicolor/16-apps-skrooge.png
icons_hicolor/16-mimetypes-application-x-skg.png
icons_hicolor/16-mimetypes-application-x-skgc.png
icons_hicolor/22-apps-skrooge-black.png
icons_hicolor/22-apps-skrooge.png
icons_hicolor/22-mimetypes-application-x-skg.png
icons_hicolor/22-mimetypes-application-x-skgc.png
icons_hicolor/32-apps-skrooge-black.png
icons_hicolor/32-apps-skrooge.png
icons_hicolor/32-mimetypes-application-x-skg.png
icons_hicolor/32-mimetypes-application-x-skgc.png
icons_hicolor/48-apps-skrooge-black.png
icons_hicolor/48-apps-skrooge.png
icons_hicolor/48-mimetypes-application-x-skg.png
icons_hicolor/48-mimetypes-application-x-skgc.png
icons_hicolor/64-apps-skrooge-black.png
icons_hicolor/64-apps-skrooge.png
icons_hicolor/64-mimetypes-application-x-skg.png
icons_hicolor/64-mimetypes-application-x-skgc.png
icons_hicolor/128-apps-skrooge-black.png
icons_hicolor/128-apps-skrooge.png
icons_hicolor/128-mimetypes-application-x-skg.png
icons_hicolor/128-mimetypes-application-x-skgc.png
icons_hicolor/256-apps-skrooge-black.png
icons_hicolor/256-apps-skrooge.png
icons_hicolor/256-mimetypes-application-x-skg.png
icons_hicolor/256-mimetypes-application-x-skgc.png
icons_hicolor/512-apps-skrooge-black.png
icons_hicolor/512-apps-skrooge.png
icons_hicolor/512-mimetypes-application-x-skg.png
icons_hicolor/512-mimetypes-application-x-skgc.png
icons_hicolor/sc-apps-skrooge-black.svgz
icons_hicolor/sc-apps-skrooge-initial.svgz
icons_hicolor/sc-apps-skrooge.svgz
icons_hicolor/sc-mimetypes-application-x-skg.svgz
icons_hicolor/sc-mimetypes-application-x-skgc.svgz
DESTINATION ${ICON_INSTALL_DIR}
THEME hicolor
)
if (NOT SHARED_MIME_INFO_MINIMUM_VERSION)
set(SHARED_MIME_INFO_MINIMUM_VERSION "0.23")
endif (NOT SHARED_MIME_INFO_MINIMUM_VERSION)
find_package(SharedMimeInfo REQUIRED)
install(FILES x-skg.xml DESTINATION ${XDG_MIME_INSTALL_DIR})
update_xdg_mimetypes(${XDG_MIME_INSTALL_DIR})
diff --git a/skrooge/main.cpp b/skrooge/main.cpp
index 119168469..70d934911 100644
--- a/skrooge/main.cpp
+++ b/skrooge/main.cpp
@@ -1,218 +1,218 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file defines the main of skrooge.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgmainpanel.h"
#include "skgdocumentbank.h"
#include "skgtraces.h"
#include <kaboutdata.h>
#include <kdbusservice.h>
#include <kdelibs4configmigrator.h>
#include <klocalizedstring.h>
#include <qbitmap.h>
#include <qcommandlineoption.h>
#include <qcommandlineparser.h>
#include <qsplashscreen.h>
/**
* To compute the version
*/
#define VER1_(x) #x
/**
* To compute the version
*/
#define VER_(x) VER1_(x)
/**
* To compute the version
*/
#define VER VER_(SKGVERSION)
void SKGMessageOutput(QtMsgType type, const QMessageLogContext& context, const QString& msg)
{
Q_UNUSED(context)
switch (type) {
case QtDebugMsg:
SKGTRACEL(1) << "DEBUG: " << msg << endl;
break;
case QtWarningMsg:
SKGTRACE << "WARNING: " << msg << endl;
break;
case QtCriticalMsg:
SKGTRACE << "CRITICAL: " << msg << endl;
break;
case QtFatalMsg:
SKGTRACE << "FATAL: " << msg << endl;
abort();
default:
SKGTRACE << "INFO: " << msg << endl;
break;
}
}
/**
* The main of the application
* @param argc number of arguments
* @param argv arguments
* @return return code
*/
int main(int argc, char** argv)
{
qInstallMessageHandler(SKGMessageOutput);
if (!SKGServices::getEnvVariable(QStringLiteral("SKGHIGHDPI")).isEmpty()) {
QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
}
QApplication app(argc, argv);
QIcon appIcon = SKGServices::fromTheme(QStringLiteral("skrooge"));
if (!appIcon.isNull()) {
app.setWindowIcon(appIcon);
}
// Migration kf4 => kf5
Kdelibs4ConfigMigrator migrate(QStringLiteral("skrooge"));
migrate.setConfigFiles(QStringList() << QStringLiteral("skroogerc"));
migrate.migrate();
// To use CPU instead CPU for QML (needed for printing)
qputenv("QMLSCENE_DEVICE", "softwarecontext");
#ifdef SKG_WEBENGINE
// DrKonqi
// https://www.dvratil.cz/2018/10/drkonqi-and-qtwebengine/
const auto chromiumFlags = qgetenv("QTWEBENGINE_CHROMIUM_FLAGS");
if (!chromiumFlags.contains("disable-in-process-stack-traces")) {
qputenv("QTWEBENGINE_CHROMIUM_FLAGS", chromiumFlags + " --disable-in-process-stack-traces");
}
#endif
KLocalizedString::setApplicationDomain("skrooge");
KAboutData about(QStringLiteral("skrooge"),
i18nc("The name of the application", "Skrooge"),
QStringLiteral(VER),
i18nc("The description of the application", "Personal finances management made simple"),
KAboutLicense::GPL_V3,
i18nc("Fullname", "(c) 2007-%1 Stephane MANKOWSKI & Guillaume DE BURE", QDate::currentDate().toString(QStringLiteral("yyyy"))),
QLatin1String(""),
QStringLiteral("http://skrooge.org"));
about.addAuthor(i18nc("Fullname", "Stephane MANKOWSKI"), i18nc("A job description", "Architect & Developer"), QStringLiteral("stephane@mankowski.fr"), QLatin1String("")
, QStringLiteral("miraks")
);
about.addAuthor(i18nc("Fullname", "Guillaume DE BURE"), i18nc("A job description", "Developer"), QStringLiteral("guillaume.debure@gmail.com"), QLatin1String("")
, QStringLiteral("willy9")
);
about.addAuthor(i18nc("Fullname", "Siddharth SHARMA"), i18nc("A job description", "Developer - Google Summer Of Code 2010"), QStringLiteral("siddharth.kde@gmail.com"), QLatin1String("")
, QStringLiteral("h4xordood")
);
about.setOtherText(i18nc("The description of the application", "The application name is inspired by Charles Dicken's tale <i>A Christmas Carol</i>, where the main character, Ebenezer Scrooge, a grumpy old narrow man, gets visited by three ghosts who change the way he sees the world, in a good way."));
about.setTranslator(i18nc("NAME OF TRANSLATORS", "Your names"), i18nc("EMAIL OF TRANSLATORS", "Your emails"));
about.setOrganizationDomain("kde.org");
about.addCredit(QStringLiteral("vicnet, noidea, rbruce, JesusM, schunka, SylvaiNN, Wolf, Hizoka, neutron68, blep0, BigaAl, steffie, skierpage ..."), i18nc("Reason of the about/credit", "Users helping us to improve this application"));
KAboutData::setApplicationData(about);
QApplication::setApplicationName(about.componentName());
QApplication::setOrganizationDomain(about.organizationDomain());
QApplication::setApplicationVersion(about.version());
QCommandLineParser parser;
parser.addVersionOption();
parser.addHelpOption();
parser.addPositionalArgument(QStringLiteral("URL"), i18nc("Application argument", "Document to open"));
QCommandLineOption envOption(QStringList() << QStringLiteral("e") << QStringLiteral("env"), i18nc("Application argument", "Display environment variables used by this application."));
parser.addOption(envOption);
about.setupCommandLine(&parser);
parser.process(app);
about.processCommandLine(&parser);
if (parser.isSet(envOption)) {
SKGTRACESUITE << parser.helpText() << endl;
SKGTRACESUITE << i18nc("Help", "Environment variables:") << endl;
SKGTRACESUITE << i18nc("Help, do not translate x", " %1: To enable traces. x is the level of traces expected. This enables the debug mode too.", "export SKGTRACE=x") << endl;
SKGTRACESUITE << i18nc("Help", " %1: To enable the profiling. This enables the debug mode too.", "export SKGTRACEPERFO=1") << endl;
SKGTRACESUITE << i18nc("Help do not translate x", " %1: To dump sql order taking more than x ms.", "export SKGTRACESQL=x") << endl;
SKGTRACESUITE << i18nc("Help", " %1: To enable the high DPI mode.", "export SKGHIGHDPI=1") << endl;
return 0;
}
// Manage unicity
KDBusService service(SKGServices::getEnvVariable(QStringLiteral("SKGNOTUNIQUE")).isEmpty() ? KDBusService::Unique : KDBusService::Multiple);
QObject::connect(&service, &KDBusService::activateRequested, &service, [ = ](const QStringList & arguments, const QString & workingDirectory) {
Q_UNUSED(workingDirectory)
SKGMainPanel::getMainPanel()->processArguments(arguments);
});
// Creating a main panel on a bank document
SKGDocumentBank doc;
if (!SKGServices::getEnvVariable(QStringLiteral("SKGTEST")).isEmpty()) {
QTimer::singleShot(5000, Qt::CoarseTimer, &app, &QApplication::quit);
}
// Build list of arguments
QStringList argument = parser.positionalArguments();
// Creation splash screen
QSplashScreen* m_splash = nullptr;
KConfigGroup pref = SKGMainPanel::getMainConfigGroup();
if (pref.readEntry("show_splash_screen", true)) {
QString splashPathRelativePath = KAboutData::applicationData().componentName() % "/images/splash.png";
QString splashPath = QStandardPaths::locate(QStandardPaths::GenericDataLocation, splashPathRelativePath.toLatin1());
if (!splashPath.isEmpty()) {
QPixmap pix(splashPath);
m_splash = new QSplashScreen(pix);
if (m_splash != nullptr) {
m_splash->setMask(pix.createMaskFromColor(Qt::blue));
m_splash->show();
m_splash->showMessage(i18nc("Splash screen message", "Loading ..."), Qt::AlignLeft, QColor(221, 130, 8)); // krazy:exclude=qmethods
}
} else {
SKGTRACE << "WARNING: Splash screen (" << splashPathRelativePath << ") not found !" << endl;
}
}
// First instance
QApplication::setAttribute(Qt::AA_DontCreateNativeWidgetSiblings, true);
#ifdef SKG_WEBENGINE
QApplication::setAttribute(Qt::AA_ShareOpenGLContexts, true);
#endif
auto m_widget = new SKGMainPanel(m_splash, &doc);
m_widget->processArguments(argument);
m_widget->setUnifiedTitleAndToolBarOnMac(true);
m_widget->show();
if (m_splash != nullptr) {
SKGTRACEINFUNC(1)
m_splash->clearMessage();
m_splash->finish(m_widget);
}
int rc = QApplication::exec(); // krazy:exclude=crashy
delete m_splash;
SKGTraces::dumpProfilingStatistics();
return rc;
}
diff --git a/skroogeakonadi/CMakeLists.txt b/skroogeakonadi/CMakeLists.txt
index 755a35c19..54cac6424 100644
--- a/skroogeakonadi/CMakeLists.txt
+++ b/skroogeakonadi/CMakeLists.txt
@@ -1,81 +1,81 @@
#***************************************************************************
#* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
#* *
#* 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 <http://www.gnu.org/licenses/> *
+#* along with this program. If not, see <https://www.gnu.org/licenses/> *
#***************************************************************************
MESSAGE( STATUS "..:: SKROOGEAKONADI ::..")
PROJECT(skroogeakonadi)
FIND_PACKAGE (KdepimLibs REQUIRED)
INCLUDE(MacroLibrary)
INCLUDE(MacroOptionalAddSubdirectory)
INCLUDE(CheckIncludeFiles)
FIND_PROGRAM(XSLTPROC_EXECUTABLE xsltproc)
-MACRO_LOG_FEATURE(XSLTPROC_EXECUTABLE "xsltproc" "The command line XSLT processor from libxslt" "http://xmlsoft.org/XSLT/" FALSE "" "Needed for building Akonadi resources. Recommended.")
+MACRO_LOG_FEATURE(XSLTPROC_EXECUTABLE "xsltproc" "The command line XSLT processor from libxslt" "https://xmlsoft.org/XSLT/" FALSE "" "Needed for building Akonadi resources. Recommended.")
if (XSLTPROC_EXECUTABLE)
# generates a D-Bus interface description from a KConfigXT file
macro( kcfg_generate_dbus_interface _kcfg _name )
add_custom_command(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${_name}.xml
COMMAND ${XSLTPROC_EXECUTABLE} --stringparam interfaceName ${_name}
${KDEPIMLIBS_DATA_DIR}/akonadi-kde/kcfg2dbus.xsl
${_kcfg}
> ${CMAKE_CURRENT_BINARY_DIR}/${_name}.xml
DEPENDS ${KDEPIMLIBS_DATA_DIR}/akonadi-kde/kcfg2dbus.xsl
${_kcfg}
)
endmacro( kcfg_generate_dbus_interface )
endif (XSLTPROC_EXECUTABLE)
if(WIN32)
set(LIB_INSTALL_DIR ${LIB_INSTALL_DIR}
RUNTIME DESTINATION ${BIN_INSTALL_DIR}
LIBRARY DESTINATION ${LIB_INSTALL_DIR}
ARCHIVE DESTINATION ${LIB_INSTALL_DIR} )
endif(WIN32)
set(KDE4_ICON_DIR ${KDE4_INSTALL_DIR}/share/icons)
include_directories(
${KDE4_INCLUDES}
${KDEPIMLIBS_INCLUDE_DIRS}
${CMAKE_SOURCE_DIR}/skgbasemodeler
${CMAKE_SOURCE_DIR}/${skgbankmodeler}
)
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${KDE4_ENABLE_EXCEPTIONS}" )
########### next target ###############
set( skroogeakonadiresource_SRCS
skroogeakonadiresource.cpp
)
install(FILES org.kde.skroogeakonadiresource.desktop DESTINATION "${CMAKE_INSTALL_PREFIX}/share/akonadi/agents" )
KCONFIG_ADD_KCFG_FILES(skroogeakonadiresource_SRCS settings.kcfgc)
KCFG_GENERATE_DBUS_INTERFACE(${CMAKE_CURRENT_SOURCE_DIR}/skroogeakonadiresource.kcfg org.kde.Akonadi.skroogeakonadi.Settings)
QT5_ADD_DBUS_ADAPTOR(skroogeakonadiresource_SRCS
${CMAKE_CURRENT_BINARY_DIR}/org.kde.Akonadi.skroogeakonadi.Settings.xml settings.h Settings
)
#TODO(Stephane MANKOWSKI) KF5 ADD_EXECUTABLE(akonadi_skroogeakonadi_resource RUN_UNINSTALLED ${skroogeakonadiresource_SRCS})
ADD_EXECUTABLE(akonadi_skroogeakonadi_resource ${skroogeakonadiresource_SRCS})
TARGET_LINK_LIBRARIES(akonadi_skroogeakonadi_resource ${KDE4_AKONADI_LIBS} ${KDEPIMLIBS_KCALCORE_LIBS} KF5::KIOWidgets Qt5::Core Qt5::DBus skgbasemodeler skgbankmodeler)
INSTALL(TARGETS akonadi_skroogeakonadi_resource ${INSTALL_TARGETS_DEFAULT_ARGS} LIBRARY NAMELINK_SKIP)
diff --git a/skroogeakonadi/skroogeakonadiresource.cpp b/skroogeakonadi/skroogeakonadiresource.cpp
index 7461f9ac5..6d6c32d2c 100644
--- a/skroogeakonadi/skroogeakonadiresource.cpp
+++ b/skroogeakonadi/skroogeakonadiresource.cpp
@@ -1,191 +1,191 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This akonadi resource.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skroogeakonadiresource.h"
#include <qdbusconnection.h>
#include <kdirwatch.h>
#include <klocalizedstring.h>
#include <akonadicore/entitydisplayattribute.h>
#include <kcalcore/todo.h>
#include <kpassworddialog.h>
#include <qfiledialog.h>
#include "settings.h"
#include "settingsadaptor.h"
#include "skgcategoryobject.h"
#include "skgdocumentbank.h"
#include "skgoperationobject.h"
#include "skgrecurrentoperationobject.h"
skroogeakonadiResource::skroogeakonadiResource(const QString& id) : ResourceBase(id)
{
setObjectName(QStringLiteral("SkroogeResource"));
setNeedsNetwork(false);
new SettingsAdaptor(Settings::self());
QDBusConnection::sessionBus().registerObject(QStringLiteral("/Settings"),
Settings::self(), QDBusConnection::ExportAdaptors);
if (!KDirWatch::self()->contains(Settings::self()->path())) {
KDirWatch::self()->addFile(Settings::self()->path());
}
QObject::connect(KDirWatch::self(), &KDirWatch::dirty, this, &skroogeakonadiResource::refresh);
synchronize();
}
skroogeakonadiResource::~skroogeakonadiResource() = default;
void skroogeakonadiResource::retrieveCollections()
{
Akonadi::Collection c;
c.setRemoteId(Settings::self()->path());
c.setName(i18nc("Name of a collection akonadi", "Skrooge scheduled operations"));
c.setRights(Akonadi::Collection::ReadOnly);
c.setParentCollection(Akonadi::Collection::root());
c.setContentMimeTypes(QStringList() << QStringLiteral("application/x-vnd.akonadi.calendar.todo"));
Akonadi::EntityDisplayAttribute* const attribute = new Akonadi::EntityDisplayAttribute();
attribute->setIconName("skrooge");
c.addAttribute(attribute);
collectionsRetrieved(Akonadi::Collection::List() << c);
if (!KDirWatch::self()->contains(Settings::self()->path())) {
KDirWatch::self()->addFile(Settings::self()->path());
}
}
void skroogeakonadiResource::retrieveItems(const Akonadi::Collection& collection)
{
Akonadi::Item::List items;
// Open the document
SKGDocumentBank doc;
SKGError err = doc.load(collection.remoteId(), Settings::self()->password(), false, true);
IFOK(err) {
SKGObjectBase::SKGListSKGObjectBase objs;
err = doc.getObjects(QStringLiteral("v_recurrentoperation_display"), QStringLiteral("i_nb_times!=0 ORDER BY d_date"), objs);
IFOK(err) {
int nb = objs.count();
if (nb) {
for (int i = 0; i < nb; ++i) {
Akonadi::Item item(QStringLiteral("application/x-vnd.akonadi.calendar.todo"));
item.setRemoteId(collection.remoteId() % ";" % SKGServices::intToString(objs.at(i).getID()));
items << item;
}
}
}
}
doc.close();
itemsRetrieved(items);
}
bool skroogeakonadiResource::retrieveItem(const Akonadi::Item& item, const QSet<QByteArray>& parts)
{
Q_UNUSED(parts)
QStringList params = SKGServices::splitCSVLine(item.remoteId(), ';');
bool output = false;
SKGDocumentBank doc;
SKGError err = doc.load(params.at(0), Settings::self()->password(), false, true);
IFOK(err) {
SKGRecurrentOperationObject obj(&doc, SKGServices::stringToInt(params.at(1)));
SKGOperationObject op;
obj.getParentOperation(op);
KCalCore::auto akonadiItem = new KCalCore::Todo();
KCalCore::Todo::Ptr akonadiItemPtr(akonadiItem);
akonadiItem->setDtDue(KDateTime(obj.getDate()));
akonadiItem->setDescription(op.getDisplayName().right(op.getDisplayName().count() - 11));
if (!obj.hasTimeLimit() || obj.getTimeLimit() > 1) {
akonadiItem->setDtRecurrence(KDateTime(obj.getNextDate()));
}
SKGOperationObject ope;
obj.getParentOperation(ope);
akonadiItem->setCategories(QStringList() << ope.getAttribute(QStringLiteral("t_CATEGORY")));
Akonadi::Item newItem(item);
newItem.setMimeType(QStringLiteral("application/x-vnd.akonadi.calendar.todo"));
newItem.setPayload<KCalCore::Incidence::Ptr>(akonadiItemPtr);
itemRetrieved(newItem);
output = true;
}
doc.close();
return output;
}
void skroogeakonadiResource::configure(WId windowId)
{
Q_UNUSED(windowId)
// Get the old path
const QString oldPath = Settings::self()->path();
QUrl url;
if (!oldPath.isEmpty()) {
url = QUrl::fromLocalFile(oldPath);
} else {
url = QUrl::fromLocalFile(QDir::homePath());
}
const QString newPath = QFileDialog::getOpenFileName("Skrooge document", 0, url, "*.skg|" % i18nc("A file format", "Skrooge document"), 0, i18nc("@title:window", "Select Skrooge document"));
if (newPath.isEmpty() || oldPath == newPath) {
return;
}
// Password dialog
QString password;
QPointer<KPasswordDialog> dlg = new KPasswordDialog();
dlg->setPrompt(i18nc("Question", "If the file is protected.\nPlease enter the password."));
if (dlg->exec() == QDialog::Accepted) {
password = dlg->password();
}
delete dlg;
// Save settings
Settings::self()->setPath(newPath);
Settings::self()->setPassword(password);
Settings::self()->save();
KDirWatch::self()->removeDir(oldPath);
KDirWatch::self()->addFile(newPath);
synchronize();
}
void skroogeakonadiResource::refresh()
{
invalidateCache(currentCollection());
synchronize();
}
AKONADI_RESOURCE_MAIN(skroogeakonadiResource)
diff --git a/skroogeakonadi/skroogeakonadiresource.h b/skroogeakonadi/skroogeakonadiresource.h
index 986e54987..e314c257e 100644
--- a/skroogeakonadi/skroogeakonadiresource.h
+++ b/skroogeakonadi/skroogeakonadiresource.h
@@ -1,42 +1,42 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKROOGEAKONADIRESOURCE_H
#define SKROOGEAKONADIRESOURCE_H
#include <akonadi/resourcebase.h>
class skroogeakonadiResource : public Akonadi::ResourceBase,
public Akonadi::AgentBase::Observer
{
Q_OBJECT
public:
explicit skroogeakonadiResource(const QString& id);
~skroogeakonadiResource();
public Q_SLOTS:
virtual void configure(WId windowId);
protected Q_SLOTS:
void retrieveCollections();
void retrieveItems(const Akonadi::Collection& collection);
bool retrieveItem(const Akonadi::Item& item, const QSet<QByteArray>& parts);
void refresh();
};
#endif
diff --git a/skroogeconvert/CMakeLists.txt b/skroogeconvert/CMakeLists.txt
index 952f0b158..36c37537b 100644
--- a/skroogeconvert/CMakeLists.txt
+++ b/skroogeconvert/CMakeLists.txt
@@ -1,34 +1,34 @@
#***************************************************************************
#* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
#* *
#* 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 <http://www.gnu.org/licenses/> *
+#* along with this program. If not, see <https://www.gnu.org/licenses/> *
#***************************************************************************
MESSAGE( STATUS "..:: CMAKE SKROOGECONVERT ::..")
PROJECT(SKROOGECONVERT)
INCLUDE(ECMMarkNonGuiExecutable)
LINK_DIRECTORIES (${LIBRARY_OUTPUT_PATH})
SET(skroogeconvert_SRCS
main.cpp
)
ADD_EXECUTABLE(skroogeconvert ${skroogeconvert_SRCS})
ECM_MARK_NONGUI_EXECUTABLE(skroogeconvert)
TARGET_LINK_LIBRARIES(skroogeconvert Qt5::Widgets skgbasemodeler skgbankmodeler)
########### install files ###############
INSTALL(TARGETS skroogeconvert ${INSTALL_TARGETS_DEFAULT_ARGS} )
diff --git a/skroogeconvert/main.cpp b/skroogeconvert/main.cpp
index a4a547f9a..a69378202 100644
--- a/skroogeconvert/main.cpp
+++ b/skroogeconvert/main.cpp
@@ -1,202 +1,202 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file defines the main of skroogeconvert.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgdocumentbank.h"
#include "skgimportexportmanager.h"
#include "skgtraces.h"
#include "skgtransactionmng.h"
#include <kaboutdata.h>
#include <qapplication.h>
#include <qcommandlineoption.h>
#include <qcommandlineparser.h>
#include <qcoreapplication.h>
#include <qfileinfo.h>
#include <qurl.h>
/**
* To compute the version
*/
#define VER1_(x) #x
/**
* To compute the version
*/
#define VER_(x) VER1_(x)
/**
* To compute the version
*/
#define VER VER_(SKGVERSION)
/**
* The main of the application
* @param argc number of arguments
* @param argv arguments
* @return return code
*/
int main(int argc, char** argv)
{
KLocalizedString::setApplicationDomain("skrooge");
KAboutData about(QStringLiteral("skroogeconvert"),
i18nc("The name of the application", "Skrooge Convert"),
QStringLiteral(VER),
i18nc("The description of the application", "A conversion tool for financial files (KMyMoney, GnuCash, Skrooge, ...)"),
KAboutLicense::GPL_V3,
i18nc("Fullname", "(c) 2007-%1 Stephane MANKOWSKI & Guillaume DE BURE", QDate::currentDate().toString(QStringLiteral("yyyy"))),
QString(),
QStringLiteral("http://skrooge.org"));
about.addAuthor(i18nc("Fullname", "Stephane MANKOWSKI"), i18nc("A job description", "Architect & Developer"), QStringLiteral("stephane@mankowski.fr"), QString()
, QStringLiteral("miraks")
);
about.addAuthor(i18nc("Fullname", "Guillaume DE BURE"), i18nc("A job description", "Developer"), QStringLiteral("guillaume.debure@gmail.com"), QString()
, QStringLiteral("willy9")
);
about.setOtherText(i18nc("The description of the application", "The application name is inspired by Charles Dicken's tale <i>A Christmas Carol</i>, where the main character, Ebenezer Scrooge, a grumpy old narrow man, gets visited by three ghosts who change the way he sees the world, in a good way."));
about.setTranslator(i18nc("NAME OF TRANSLATORS", "Your names"), i18nc("EMAIL OF TRANSLATORS", "Your emails"));
KAboutData::setApplicationData(about);
QCoreApplication app(argc, argv);
QCoreApplication::setApplicationName(about.componentName());
QCoreApplication::setOrganizationDomain(about.organizationDomain());
QCoreApplication::setApplicationVersion(about.version());
QCommandLineParser parser;
parser.addVersionOption();
parser.addHelpOption();
parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("in"), i18nc("Application argument", "Input file. Supported formats:\n%1", SKGImportExportManager::getImportMimeTypeFilter(false)), QStringLiteral("file")));
parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("out"), i18nc("Application argument", "Output file. Supported formats:\n%1", SKGImportExportManager::getExportMimeTypeFilter(false)), QStringLiteral("file")));
parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("param"), i18nc("Application argument", "Name of a parameter"), QStringLiteral("name")));
parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("value"), i18nc("Application argument", "Value of a parameter"), QStringLiteral("value")));
parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("param_export"), i18nc("Application argument", "Name of a parameter for export"), QStringLiteral("name_export")));
parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("value_export"), i18nc("Application argument", "Value of a parameter for export"), QStringLiteral("value_export")));
about.setupCommandLine(&parser);
parser.process(app);
about.processCommandLine(&parser);
// Build list of arguments
SKGError err;
if (!parser.isSet(QStringLiteral("in"))) {
err = SKGError(ERR_INVALIDARG, i18nc("Error message", "Missing -in option"));
} else if (!parser.isSet(QStringLiteral("out"))) {
err = SKGError(ERR_INVALIDARG, i18nc("Error message", "Missing -out option"));
}
// Initialisation of a bank document
SKGDocumentBank document;
document.setComputeBalances(false);
IFOKDO(err, document.initialize())
IFOK(err) {
// Import
QString file = parser.value(QStringLiteral("in"));
QFileInfo fi(file);
if (fi.exists()) {
file = fi.absoluteFilePath();
}
SKGImportExportManager imp(&document, QUrl::fromLocalFile(file));
QMap<QString, QString> parameters = imp.getImportParameters();
QStringList params = parser.values(QStringLiteral("param"));
QStringList values = parser.values(QStringLiteral("value"));
int nb = qMin(params.count(), values.count());
for (int i = 0; i < nb; ++i) {
parameters[params.at(i)] = values.at(i);
}
imp.setImportParameters(parameters);
SKGTRACESEPARATOR;
SKGTRACE << i18nc("Title of a console trace section", " Import parameters") << endl;
QMapIterator<QString, QString> i(imp.getImportParameters());
while (i.hasNext()) {
i.next();
SKGTRACE << " " << i.key() << "=" << i.value() << endl;
}
SKGTRACESEPARATOR;
SKGTRACE << i18nc("Title of a console trace section", " Imported file:") << imp.getFileName().toDisplayString() << endl;
if (fi.suffix().toUpper() == QStringLiteral("SKG") || fi.suffix().toUpper() == QStringLiteral("SQLITE") || fi.suffix().toUpper() == QStringLiteral("SQLCIPHER")) {
err = document.load(file, parameters[QStringLiteral("password")]);
} else {
SKGBEGINTRANSACTION(document, QStringLiteral("IMPORT"), err)
IFOKDO(err, imp.importFile())
}
}
IFOK(err) {
// Export
QString file = parser.value(QStringLiteral("out"));
QFileInfo fi(file);
if (fi.exists()) {
file = fi.absoluteFilePath();
}
SKGImportExportManager exp(&document, QUrl::fromLocalFile(file));
QMap<QString, QString> parameters = exp.getExportParameters();
QStringList params = parser.values(QStringLiteral("param_export"));
QStringList values = parser.values(QStringLiteral("value_export"));
int nb = qMin(params.count(), values.count());
for (int i = 0; i < nb; ++i) {
parameters[params.at(i)] = values.at(i);
}
exp.setExportParameters(parameters);
SKGTRACESEPARATOR;
SKGTRACE << i18nc("Title of a console trace section", " Export parameters") << endl;
QMapIterator<QString, QString> i(exp.getExportParameters());
while (i.hasNext()) {
i.next();
SKGTRACE << " " << i.key() << "=" << i.value() << endl;
}
SKGTRACESEPARATOR;
SKGTRACE << i18nc("Title of a console trace section", " Exported file:") << exp.getFileName().toDisplayString() << endl;
if (fi.suffix().toUpper() == QStringLiteral("SKG")) {
err = document.saveAs(file, true);
} else {
err = exp.exportFile();
}
}
// Dump getMessages
SKGDocument::SKGMessageList oMessages;
IFOKDO(err, document.getMessages(document.getCurrentTransaction(), oMessages))
int nb = oMessages.count();
if (nb > 0) {
SKGTRACESEPARATOR;
for (int i = 0; i < nb; ++i) {
SKGTRACE << oMessages.at(i).Text << endl;
}
}
IFKO(err) {
SKGTRACESUITE << err.getFullMessageWithHistorical() << endl;
SKGTRACESEPARATOR;
SKGTRACE << i18nc("Title of a console trace section", " FAILED") << endl;
SKGTRACESEPARATOR;
} else {
SKGTRACESEPARATOR;
SKGTRACE << i18nc("Title of a console trace section", " SUCCESSFUL") << endl;
SKGTRACESEPARATOR;
}
SKGTraces::dumpProfilingStatistics();
return err.getReturnCode();
}
diff --git a/templates/skrooge_import_xxx/CMakeLists.txt b/templates/skrooge_import_xxx/CMakeLists.txt
index dcf35cd21..7d5f6b5d8 100644
--- a/templates/skrooge_import_xxx/CMakeLists.txt
+++ b/templates/skrooge_import_xxx/CMakeLists.txt
@@ -1,33 +1,33 @@
#***************************************************************************
#* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
#* *
#* 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 <http://www.gnu.org/licenses/> *
+#* along with this program. If not, see <https://www.gnu.org/licenses/> *
#***************************************************************************
MESSAGE( STATUS "..:: CMAKE PLUGIN_IMPORT_XXX ::..")
PROJECT(plugin_import_xxx)
LINK_DIRECTORIES (${LIBRARY_OUTPUT_PATH})
SET(skrooge_import_xxx_SRCS
skgimportpluginxxx.cpp
)
ADD_LIBRARY(skrooge_import_xxx MODULE ${skrooge_import_xxx_SRCS})
TARGET_LINK_LIBRARIES(skrooge_import_xxx KF5::Parts skgbasemodeler skgbasegui skgbankmodeler skgbankgui)
########### install files ###############
INSTALL(TARGETS skrooge_import_xxx DESTINATION ${KDE_INSTALL_QTPLUGINDIR})
INSTALL(FILES ${PROJECT_SOURCE_DIR}/org.kde.skrooge-import-xxx.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR})
diff --git a/templates/skrooge_import_xxx/org.kde.skrooge-import-xxx.desktop b/templates/skrooge_import_xxx/org.kde.skrooge-import-xxx.desktop
index d2caecb5e..df32069d9 100644
--- a/templates/skrooge_import_xxx/org.kde.skrooge-import-xxx.desktop
+++ b/templates/skrooge_import_xxx/org.kde.skrooge-import-xxx.desktop
@@ -1,74 +1,74 @@
[Desktop Entry]
Name=Skrooge import XXX plugin
Name[bs]=Skrooge dodatak za XXX uvoz
Name[ca]=Connector d'importació de XXX de l'Skrooge
Name[ca@valencia]=Connector d'importació de XXX de l'Skrooge
Name[cs]=Modul Skrooge pro import XXX
Name[da]=Plugin til import af XXX til Skrooge
Name[de]=Skrooge-XXX-Importmodul
Name[el]=Skrooge import XXX plugin
Name[en_GB]=Skrooge import XXX plugin
Name[es]=Complemento de Skrooge para la importación de XXX
Name[et]=Skrooge XXX impordi plugin
Name[fi]=Skroogen XXX-tuontiliitännäinen
-Name[fr]=Module externe de Skrooge pour l'importation « XXX »
+Name[fr]=Module externe de Skrooge pour l'importation « XXX »
Name[gl]=Complemento de importación de XXX a Skrooge
Name[hu]=Skrooge XXX importáló bővítmény
Name[it]=Estensione di Skrooge per l'importazione XXX
Name[lt]=Skrooge XXX importavimo papildinys
Name[nb]=Skrooge-modul for XXX-import
Name[nl]=Plugin van Skrooge voor importeren van XXX
Name[pl]=Wtyczka importu XXX dla Skrooge
Name[pt]='Plugin' de importação de XXX para o Skrooge
Name[pt_BR]=Plugin de importação de XXX para o Skrooge
Name[ru]=Модуль импорта файлов XXX
Name[sk]=Skrooge importný XXX plugin
Name[sv]=Skrooge XXX-importinsticksprogram
Name[tr]=Skrooge içe aktarma XXX eklentisi
Name[uk]=Додаток імпортування XXX до Skrooge
Name[x-test]=xxSkrooge import XXX pluginxx
Name[zh_TW]=Skrooge 匯入 XXX 外掛程式
Comment=A Skrooge plugin to import XXX files
Comment[bs]=Skrooge dodatak za uvoz XXX datoteka
Comment[ca]=Un connector de l'Skrooge per importar fitxers XXX
Comment[ca@valencia]=Un connector de l'Skrooge per importar fitxers XXX
Comment[cs]=Modul Skrooge pro import souborů XXX
Comment[da]=Et Skrooge-plugin til at importere XXX-filer
Comment[de]=Ein Skrooge-Modul zum Import von XXX-Dateien
Comment[el]=Ένα πρόσθετο του Skrooge για την εισαγωγή αρχείων XXX
Comment[en_GB]=A Skrooge plugin to import XXX files
Comment[es]=Complemento de Skrooge para importar archivos XXX
Comment[et]=Skrooge plugin XXX-failide importimiseks
Comment[fi]=Skroogen XXX-tiedostojen tuontiliitännäinen
-Comment[fr]=Un module externe de Skrooge pour l'importation « XXX »
+Comment[fr]=Un module externe de Skrooge pour l'importation « XXX »
Comment[gl]=Un complemento de Skrooge para importar ficheiros XXX.
Comment[hu]=Egy Skrooge bővítmény XXX fájlok importálásához
Comment[it]=Un'estensione di Skrooge per importare i file XXX
Comment[lt]=Skrooge XXX failų importavimo papildinys
Comment[nb]=En Skrooge-modul for å importere XXX-filer
Comment[nl]=Een Skrooge-plugin voor het importeren van XXX-bestanden
Comment[pl]=Wtyczka Skrooge do importu plików XXX
Comment[pt]=Um 'plugin' do Skrooge para importar ficheiros XXX
Comment[pt_BR]=Um plugin do Skrooge para importar arquivos XXX
Comment[ru]=Модуль импорта файлов XXX
Comment[sk]=Plugin Skrooge na import XXX súborov
Comment[sv]=Ett insticksprogram till Skrooge för att importera XXX-filer
Comment[tr]=XXX dosyalarını içe aktarmak için Skrooge eklentisi
Comment[uk]=Додаток до Skrooge для імпортування даних з файлів XXX
Comment[x-test]=xxA Skrooge plugin to import XXX filesxx
Comment[zh_TW]=Skrooge 匯入 XXX 檔用的外掛程式
Encoding=UTF-8
Icon=skrooge
Type=Service
X-KDE-ServiceTypes=SKG IMPORT/Plugin
X-KDE-Library=skrooge_import_xxx
X-Krunner-ID=Skrooge import XXX plugin
X-KDE-PluginInfo-Author=##AUTHOR##
X-KDE-PluginInfo-Email=##EMAIL##
X-KDE-PluginInfo-Name=skrooge_import_xxx
X-KDE-PluginInfo-Version=1.0
-X-KDE-PluginInfo-Website=http://skrooge.org/
+X-KDE-PluginInfo-Website=https://skrooge.org/
X-KDE-PluginInfo-Category=Plugins
X-KDE-PluginInfo-Depends=
X-KDE-PluginInfo-License=GPL
X-KDE-PluginInfo-EnabledByDefault=true
diff --git a/templates/skrooge_import_xxx/skgimportpluginxxx.cpp b/templates/skrooge_import_xxx/skgimportpluginxxx.cpp
index eec9135ff..ed8ba8e94 100644
--- a/templates/skrooge_import_xxx/skgimportpluginxxx.cpp
+++ b/templates/skrooge_import_xxx/skgimportpluginxxx.cpp
@@ -1,73 +1,73 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is Skrooge plugin for XXX import / export.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgimportpluginxxx.h"
#include <klocalizedstring.h>
#include <kpluginfactory.h>
#include "skgtraces.h"
/**
* This plugin factory.
*/
K_PLUGIN_FACTORY(SKGImportPluginXXXFactory, registerPlugin<SKGImportPluginXXX>();)
SKGImportPluginXXX::SKGImportPluginXXX(QObject* iImporter, const QVariantList& iArg)
: SKGImportPlugin(iImporter)
{
SKGTRACEINFUNC(10)
Q_UNUSED(iArg)
}
SKGImportPluginXXX::~SKGImportPluginXXX()
{
}
bool SKGImportPluginXXX::isImportPossible()
{
SKGTRACEINFUNC(10)
return (!m_importer ? true : m_importer->getFileNameExtension() == "XXX");
}
SKGError SKGImportPluginXXX::importFile()
{
return SKGImportPlugin::importFile();
}
bool SKGImportPluginXXX::isExportPossible()
{
SKGTRACEINFUNC(10)
return isImportPossible();
}
SKGError SKGImportPluginXXX::exportFile()
{
return SKGImportPlugin::exportFile();
}
QString SKGImportPluginXXX::getMimeTypeFilter() const
{
return "*.xxx|" % i18nc("A file format", "XXX file");
}
diff --git a/templates/skrooge_import_xxx/skgimportpluginxxx.h b/templates/skrooge_import_xxx/skgimportpluginxxx.h
index 1555c78dd..a41a05ba0 100644
--- a/templates/skrooge_import_xxx/skgimportpluginxxx.h
+++ b/templates/skrooge_import_xxx/skgimportpluginxxx.h
@@ -1,84 +1,84 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGIMPORTPLUGINXXX_H
#define SKGIMPORTPLUGINXXX_H
/** @file
* This file is Skrooge plugin for XXX import / export.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgimportplugin.h"
/**
* This file is Skrooge plugin for XXX import / export.
*/
class SKGImportPluginXXX : public SKGImportPlugin
{
Q_OBJECT
Q_INTERFACES(SKGImportPlugin);
public:
/**
* Default constructor
* @param iImporter the parent importer
* @param iArg the arguments
*/
explicit SKGImportPluginXXX(QObject* iImporter, const QVariantList& iArg);
/**
* Default Destructor
*/
virtual ~SKGImportPluginXXX();
/**
* To know if import is possible with this plugin
*/
virtual bool isImportPossible() override;
/**
* Import a file
* @return an object managing the error.
* @see SKGError
*/
virtual SKGError importFile() override;
/**
* To know if export is possible with this plugin
* @return true or false
*/
virtual bool isExportPossible() override;
/**
* Export a file
* @return an object managing the error.
* @see SKGError
*/
virtual SKGError exportFile() override;
/**
* Return the mime type filter
* @return the mime type filter. Example: "*.csv|CSV file"
*/
virtual QString getMimeTypeFilter() const override;
private:
Q_DISABLE_COPY(SKGImportPluginXXX);
};
#endif // SKGIMPORTPLUGINXXX_H
diff --git a/templates/skrooge_xxx/CMakeLists.txt b/templates/skrooge_xxx/CMakeLists.txt
index 71b7995be..c3a38f32e 100644
--- a/templates/skrooge_xxx/CMakeLists.txt
+++ b/templates/skrooge_xxx/CMakeLists.txt
@@ -1,39 +1,39 @@
#***************************************************************************
#* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
#* *
#* 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 <http://www.gnu.org/licenses/> *
+#* along with this program. If not, see <https://www.gnu.org/licenses/> *
#***************************************************************************
MESSAGE( STATUS "..:: CMAKE PLUGIN_XXX ::..")
PROJECT(plugin_xxx)
LINK_DIRECTORIES (${LIBRARY_OUTPUT_PATH})
SET(skrooge_xxx_SRCS
skgxxxplugin.cpp
skgxxxpluginwidget.cpp)
ki18n_wrap_ui(skrooge_xxx_SRCS skgxxxpluginwidget_base.ui skgxxxpluginwidget_pref.ui)
kconfig_add_kcfg_files(skrooge_xxx_SRCS skgxxx_settings.kcfgc )
ADD_LIBRARY(skrooge_xxx MODULE ${skrooge_xxx_SRCS})
TARGET_LINK_LIBRARIES(skrooge_xxx KF5::Parts skgbasemodeler skgbasegui)
########### install files ###############
INSTALL(TARGETS skrooge_xxx DESTINATION ${KDE_INSTALL_QTPLUGINDIR})
INSTALL(FILES ${PROJECT_SOURCE_DIR}/org.kde.skrooge-plugin-xxx.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR})
INSTALL(FILES ${PROJECT_SOURCE_DIR}/skrooge_xxx.rc DESTINATION ${KDE_INSTALL_KXMLGUI5DIR}/skrooge_xxx )
INSTALL(FILES ${PROJECT_SOURCE_DIR}/skgxxx_settings.kcfg DESTINATION ${KDE_INSTALL_KCFGDIR} )
ECM_INSTALL_ICONS(${ICON_INSTALL_DIR})
diff --git a/templates/skrooge_xxx/org.kde.skrooge-plugin-xxx.desktop b/templates/skrooge_xxx/org.kde.skrooge-plugin-xxx.desktop
index 7dd85fda6..e0144b999 100644
--- a/templates/skrooge_xxx/org.kde.skrooge-plugin-xxx.desktop
+++ b/templates/skrooge_xxx/org.kde.skrooge-plugin-xxx.desktop
@@ -1,84 +1,84 @@
[Desktop Entry]
Name=Skrooge xxx plugin
Name[bs]=Skrooge dodatak za xxx
Name[ca]=Connector xxx de l'Skrooge
Name[ca@valencia]=Connector xxx de l'Skrooge
Name[cs]=Modul Skrooge xxx
Name[da]=xxx-plugin til Skrooge
Name[de]=Skrooge-xxx-Modul
Name[el]=Skrooge xxx plugin
Name[en_GB]=Skrooge xxx plugin
Name[eo]=Skrooge xxx kromaĵo
Name[es]=Complemento de xxx de Skrooge
Name[et]=Skrooge XXX plugin
Name[fi]=Skroogen xxx-liitännäinen
-Name[fr]=Module externe de Skrooge « xxx »
+Name[fr]=Module externe de Skrooge « xxx »
Name[gl]=Complemento de XXX para Skrooge
Name[hu]=Skrooge xxx bővítmény
Name[it]=Estensione XXX di Skrooge
Name[lt]=Skrooge XXX papildinys
Name[ms]=Plugin xxx Skrooge
Name[nb]=Skrooge xxx-modul
Name[nds]=XXX-Moduul för Skrooge
Name[nl]=Xxx-plugin voor Skrooge
Name[pl]=Wtyczka xxx dla Skrooge
Name[pt]='Plugin' XXX do Skrooge
Name[pt_BR]=Plugin xxx do Skrooge
Name[ru]=Модуль xxx
Name[sk]=Skrooge xxx plugin
Name[sv]=Skrooge insticksprogram för någonting
Name[tr]=Skrooge xxx eklentisi
Name[uk]=Додаток xxx Skrooge
Name[x-test]=xxSkrooge xxx pluginxx
Name[zh_CN]=Skrooge xxx 插件
Name[zh_TW]=Skrooge xxx 外掛程式
Comment=##DESCRIPTION##
Comment[bs]=##OPIS##
Comment[ca]=##DESCRIPCIÓ##
Comment[ca@valencia]=##DESCRIPCIÓ##
Comment[cs]=##DESCRIPTION##
Comment[da]=##BESKRIVELSE##
Comment[de]=##Beschreibung##
Comment[el]=##ΠΕΡΙΓΡΑΦΗ##
Comment[en_GB]=##DESCRIPTION##
Comment[eo]=##PRISKRIBO##
Comment[es]=##DESCRIPCIÓN##
Comment[et]=##KIRJELDUS##
Comment[fi]=##KUVAUS##
Comment[fr]=##DESCRIPTION##
Comment[ga]=##CUR SÍOS##
Comment[gl]=##DESCRICIÓN##
Comment[hu]=##LEÍRÁS##
Comment[ia]=##DESCRIPTION##
Comment[it]=##DESCRIZIONE##
Comment[lt]=##APRAŠYMAS##
Comment[mr]=##वर्णन##
Comment[nb]=##Beskrivelse##
Comment[nds]=-- Beschrieven --
Comment[nl]=##BESCHRIJVING##
Comment[pl]=##OPIS##
Comment[pt]=##DESCRIÇÃO##
Comment[pt_BR]=##DESCRIÇÃO##
Comment[ru]=##ОПИСАНИЕ##
Comment[sk]=##POPIS##
Comment[sv]=##BESKRIVNING##
Comment[tr]=##AÇIKLAMA##
Comment[uk]=##ОПИС##
Comment[x-test]=xx##DESCRIPTION##xx
Comment[zh_CN]=##描述##
Comment[zh_TW]=##描述##
Encoding=UTF-8
Icon=quickopen
Type=Service
X-KDE-ServiceTypes=SKG GUI/Plugin
X-KDE-Library=skrooge_xxx
X-Krunner-ID=Skrooge xxx plugin
X-KDE-PluginInfo-Author=##AUTHOR##
X-KDE-PluginInfo-Email=##EMAIL##
X-KDE-PluginInfo-Name=skrooge_xxx
X-KDE-PluginInfo-Version=1.0
-X-KDE-PluginInfo-Website=http://skrooge.org/
+X-KDE-PluginInfo-Website=https://skrooge.org/
X-KDE-PluginInfo-Category=Plugins
X-KDE-PluginInfo-Depends=
X-KDE-PluginInfo-License=GPL
X-KDE-PluginInfo-EnabledByDefault=true
diff --git a/templates/skrooge_xxx/skgxxxplugin.cpp b/templates/skrooge_xxx/skgxxxplugin.cpp
index 7b398e081..60fa06faf 100644
--- a/templates/skrooge_xxx/skgxxxplugin.cpp
+++ b/templates/skrooge_xxx/skgxxxplugin.cpp
@@ -1,129 +1,129 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* ##DESCRIPTION##
*
* @author ##AUTHOR##
*/
#include "skgxxxplugin.h"
#include <kactioncollection.h>
#include <kstandardaction.h>
#include <kaboutdata.h>
#include <kpluginfactory.h>
#include "skgxxxpluginwidget.h"
#include "skgxxx_settings.h"
#include "skgtraces.h"
/**
* This plugin factory.
*/
K_PLUGIN_FACTORY(SKGXXXPluginFactory, registerPlugin<SKGXXXPlugin>();)
SKGXXXPlugin::SKGXXXPlugin(QWidget* iWidget, QObject* iParent, const QVariantList& /*iArg*/) :
SKGInterfacePlugin(iParent), m_currentDocument(nullptr)
{
Q_UNUSED(iWidget)
SKGTRACEINFUNC(10)
}
SKGXXXPlugin::~SKGXXXPlugin()
{
SKGTRACEINFUNC(10)
m_currentDocument = nullptr;
}
bool SKGXXXPlugin::setupActions(SKGDocument* iDocument)
{
SKGTRACEINFUNC(10)
m_currentDocument = iDocument;
setComponentName("skrooge_xxx", title());
setXMLFile("skrooge_xxx.rc");
// Create yours actions here
return true;
}
void SKGXXXPlugin::refresh()
{
SKGTRACEINFUNC(10)
}
SKGTabPage* SKGXXXPlugin::getWidget()
{
SKGTRACEINFUNC(10)
return new SKGXXXPluginWidget(SKGMainPanel::getMainPanel(), m_currentDocument);
}
QWidget* SKGXXXPlugin::getPreferenceWidget()
{
SKGTRACEINFUNC(10)
auto w = new QWidget();
ui.setupUi(w);
return w;
}
KConfigSkeleton* SKGXXXPlugin::getPreferenceSkeleton()
{
return skgxxx_settings::self();
}
SKGError SKGXXXPlugin::savePreferences() const
{
return SKGError();
}
QString SKGXXXPlugin::title() const
{
return i18nc("The title", "xxx"); // TODO(You) MUST BE CHANGED
}
QString SKGXXXPlugin::icon() const
{
return "dialog-information"; // TODO(You) MUST BE CHANGED
}
QString SKGXXXPlugin::toolTip() const
{
return i18nc("The tool tip", "xxx"); // TODO(You) MUST BE CHANGED
}
int SKGXXXPlugin::getOrder() const
{
return 999;
}
QStringList SKGXXXPlugin::tips() const
{
QStringList output;
output.push_back(i18nc("Description of a tips", "<p>... xxx is the best plugin of the world</p>")); // TODO(You) MUST BE CHANGED
return output;
}
bool SKGXXXPlugin::isInPagesChooser() const
{
return true;
}
#include <skgxxxplugin.moc>
diff --git a/templates/skrooge_xxx/skgxxxplugin.h b/templates/skrooge_xxx/skgxxxplugin.h
index 1df204028..04ef2d88e 100644
--- a/templates/skrooge_xxx/skgxxxplugin.h
+++ b/templates/skrooge_xxx/skgxxxplugin.h
@@ -1,131 +1,131 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGXXXPLUGIN_H
#define SKGXXXPLUGIN_H
/** @file
* ##DESCRIPTION##.
*
* @author ##AUTHOR##
*/
#include "skginterfaceplugin.h"
#include "ui_skgxxxpluginwidget_pref.h"
/**
* ##DESCRIPTION##
*/
class SKGXXXPlugin : public SKGInterfacePlugin
{
Q_OBJECT
Q_INTERFACES(SKGInterfacePlugin)
public:
/**
* Default Constructor
*/
explicit SKGXXXPlugin(QWidget* iWidget, QObject* iParent, const QVariantList& iArg);
/**
* Default Destructor
*/
virtual ~SKGXXXPlugin();
/**
* Called to initialise the plugin
* @param iDocument the main document
* @return true if the plugin is compatible with the document
*/
virtual bool setupActions(SKGDocument* iDocument) override;
/**
* Must be modified to refresh widgets after a modification.
*/
virtual void refresh() override;
/**
* The preference widget of the plugin.
* @return The preference widget of the plugin
*/
virtual QWidget* getPreferenceWidget() override;
/**
* The preference skeleton of the plugin.
* @return The preference skeleton of the plugin
*/
virtual KConfigSkeleton* getPreferenceSkeleton() override;
/**
* The page widget of the plugin.
* @return The page widget of the plugin
*/
virtual SKGTabPage* getWidget() override;
/**
* This function is called when preferences have been modified. Must be used to save some parameters into the document.
* A transaction is already opened
* @return an object managing the error.
* @see SKGError
*/
virtual SKGError savePreferences() const override;
/**
* The title of the plugin.
* @return The title of the plugin
*/
virtual QString title() const override;
/**
* The icon of the plugin.
* @return The icon of the plugin
*/
virtual QString icon() const override;
/**
* The toolTip of the plugin.
* @return The toolTip of the plugin
*/
virtual QString toolTip() const override;
/**
* The tips list of the plugin.
* @return The tips list of the plugin
*/
virtual QStringList tips() const override;
/**
* Must be implemented to set the position of the plugin.
* @return integer value between 0 and 999 (default = 999)
*/
virtual int getOrder() const override;
/**
* Must be implemented to know if a plugin must be display in pages chooser.
* @return true of false (default = false)
*/
virtual bool isInPagesChooser() const override;
private Q_SLOTS:
private:
Q_DISABLE_COPY(SKGXXXPlugin)
SKGDocument* m_currentDocument;
Ui::skgxxxplugin_pref ui;
};
#endif // SKGXXXPLUGIN_H
diff --git a/templates/skrooge_xxx/skgxxxpluginwidget.cpp b/templates/skrooge_xxx/skgxxxpluginwidget.cpp
index 77630e763..a19dd0d3e 100644
--- a/templates/skrooge_xxx/skgxxxpluginwidget.cpp
+++ b/templates/skrooge_xxx/skgxxxpluginwidget.cpp
@@ -1,97 +1,97 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* ##DESCRIPTION##.
*
* @author ##AUTHOR##
*/
#include "skgxxxpluginwidget.h"
#include <qdom.h>
#include "skgmainpanel.h"
#include "skgtraces.h"
#include "skgdocument.h"
SKGXXXPluginWidget::SKGXXXPluginWidget(QWidget* iParent, SKGDocument* iDocument)
: SKGTabPage(iParent, iDocument)
{
SKGTRACEINFUNC(1)
if (!iDocument) {
return;
}
ui.setupUi(this);
// Build you panel here
}
SKGXXXPluginWidget::~SKGXXXPluginWidget()
{
SKGTRACEINFUNC(1)
}
QString SKGXXXPluginWidget::getState()
{
SKGTRACEINFUNC(10)
QDomDocument doc("SKGML");
QDomElement root = doc.createElement("parameters");
doc.appendChild(root);
// Get state
// Example: QString account=root.attribute ( "account");
// if (account.isEmpty()) root.setAttribute(QStringLiteral("account"), ui.kDisplayAccountCombo->currentText());
return doc.toString();
}
void SKGXXXPluginWidget::setState(const QString& iState)
{
SKGTRACEINFUNC(10)
QDomDocument doc("SKGML");
doc.setContent(iState);
QDomElement root = doc.documentElement();
// Set state
// Example: QString account=root.attribute ( "account");
}
QString SKGXXXPluginWidget::getDefaultStateAttribute()
{
return "";
}
QWidget* SKGXXXPluginWidget::mainWidget()
{
return this;
}
void SKGXXXPluginWidget::refresh()
{
SKGTRACEINFUNC(1)
QSqlDatabase* db = getDocument()->getDatabase();
setEnabled(db != nullptr);
if (db != nullptr) {
// Refresh yours widgets here
}
}
diff --git a/templates/skrooge_xxx/skgxxxpluginwidget.h b/templates/skrooge_xxx/skgxxxpluginwidget.h
index d0c32f380..120e45822 100644
--- a/templates/skrooge_xxx/skgxxxpluginwidget.h
+++ b/templates/skrooge_xxx/skgxxxpluginwidget.h
@@ -1,90 +1,90 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGXXXPLUGINWIDGET_H
#define SKGXXXPLUGINWIDGET_H
/** @file
* ##DESCRIPTION##
*
* @author ##AUTHOR##
*/
#include "ui_skgxxxpluginwidget_base.h"
#include "skgtabpage.h"
/**
* ##DESCRIPTION##
*/
class SKGXXXPluginWidget : public SKGTabPage
{
Q_OBJECT
public:
/**
* Default Constructor
* @param iParent the parent widget
* @param iDocument the document
*/
explicit SKGXXXPluginWidget(QWidget* iParent, SKGDocument* iDocument);
/**
* Default Destructor
*/
virtual ~SKGXXXPluginWidget();
/**
* Get the current state
* MUST BE OVERWRITTEN
* @return a string containing all information needed to set the same state.
* Could be an XML stream
*/
virtual QString getState() override;
/**
* Set the current state
* MUST BE OVERWRITTEN
* @param iState must be interpreted to set the state of the widget
*/
virtual void setState(const QString& iState) override;
/**
* Get attribute name to save the default state
* MUST BE OVERWRITTEN
* @return attribute name to save the default state.
*/
virtual QString getDefaultStateAttribute() override;
/**
* Get the main widget
* @return a widget
*/
virtual QWidget* mainWidget() override;
public Q_SLOTS:
/**
* Refresh the content.
*/
virtual void refresh();
private Q_SLOTS:
private:
Q_DISABLE_COPY(SKGXXXPluginWidget)
Ui::skgxxxplugin_base ui;
};
#endif // SKGXXXPLUGINWIDGET_H
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index 6177f5c4f..be94cc9c6 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -1,32 +1,32 @@
#***************************************************************************
#* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
#* *
#* 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 <http://www.gnu.org/licenses/> *
+#* along with this program. If not, see <https://www.gnu.org/licenses/> *
#***************************************************************************
MESSAGE( STATUS "..:: CMAKE TESTS ::..")
PROJECT(TESTS)
ADD_SUBDIRECTORY(skgbasemodelertest)
ADD_SUBDIRECTORY(skgbankmodelertest)
ADD_SUBDIRECTORY(skgbaseguitest)
ADD_SUBDIRECTORY(skgbankguitest)
ADD_SUBDIRECTORY(skroogetest)
#ADD_SUBDIRECTORY(skgmyapplitest) #<-- Experimental plugin, do not activate
#TESTS
CONFIGURE_FILE(${PROJECT_SOURCE_DIR}/scripts/init.sh.in ${PROJECT_SOURCE_DIR}/scripts/init.sh @ONLY)
ENABLE_TESTING()
INCLUDE(Dart)
INCLUDE(CTest)
diff --git a/tests/input/skgtestimportbackend/bulk/bulk.desktop b/tests/input/skgtestimportbackend/bulk/bulk.desktop
index 3291a7b9f..ba44e071e 100644
--- a/tests/input/skgtestimportbackend/bulk/bulk.desktop
+++ b/tests/input/skgtestimportbackend/bulk/bulk.desktop
@@ -1,23 +1,23 @@
[Desktop Entry]
Name=Bulk backend
Comment=A backend to test bulk mode
Encoding=UTF-8
Icon=skrooge
Type=Service
X-KDE-ServiceTypes=Skrooge/Import/Backend
X-Krunner-ID=bulk
X-KDE-PluginInfo-Author=Stephane MANKOWSKI,miraks
X-KDE-PluginInfo-Email=stephane@mankowski.fr
X-KDE-PluginInfo-Name=bulk
X-KDE-PluginInfo-Version=1.0
-X-KDE-PluginInfo-Website=http://skrooge.org/
+X-KDE-PluginInfo-Website=https://skrooge.org/
X-KDE-PluginInfo-Category=Plugins
X-KDE-PluginInfo-Depends=
X-KDE-PluginInfo-License=GPL
X-KDE-PluginInfo-EnabledByDefault=true
X-SKROOGE-getaccounts=printf "id\n12345@bankname\n78900@bankname"
X-SKROOGE-getaccountid=(.*)
X-SKROOGE-getbulk=cp 12345@bankname.csv 78900@bankname.csv %1/.
X-SKROOGE-csvcolumns=date|mode|comment|payee|amount
diff --git a/tests/input/template.txt b/tests/input/template.txt
index 3d9967334..9478070ae 100644
--- a/tests/input/template.txt
+++ b/tests/input/template.txt
@@ -1,318 +1,318 @@
<!--***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************-->
<?xml version="1.0" encoding="utf-8"?>
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml">
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="https://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8" />
<meta http-equiv="Content-Style-Type" content="text/css" />
<link rel="stylesheet" href="http://getbootstrap.com/dist/css/bootstrap.min.css">
</head>
<body>
<h1>Introduction</h1>
Welcome to this tutorial. You will learn how to develop a template to personalize your how report.<br>
The template engine is based on <a href="http://www.grantlee.org/apidox/">Grantlee</a>.<br>
<br>
You can find information here:<br>
<a href="http://www.grantlee.org/apidox/for_themers.html">http://www.grantlee.org/apidox/for_themers.html</a><br>
<a href="https://docs.djangoproject.com/en/dev/ref/templates/builtins/">https://docs.djangoproject.com/en/dev/ref/templates/builtins/</a><br>
<h1>The main variables</h1>
<h2>The simple values:</h2>
You can have access to simple values:
<div class="panel panel-primary">
<div class="panel-heading">Code</div>
<div class="panel-body">
color_negativetext: &#123;{ color_negativetext }}<br/>
color_positivetext: &#123;{ color_positivetext }}<br/>
color_neutraltext: &#123;{ color_neutraltext }}<br/>
color_normaltext: &#123;{ color_normaltext }}<br/>
color_inactivetext: &#123;{ color_inactivetext }}<br/>
color_activetext: &#123;{ color_activetext }}<br/>
color_linktext: &#123;{ color_linktext }}<br/>
color_visitedtext: &#123;{ color_visitedtext }}<br/>
color_activebackground: &#123;{ color_activebackground }}<br/>
font_family: &#123;{ font_family }}<br/>
logo: &#123;{ logo }} &lt;img src="&#123;{ logo }}" /><br/>
logo_black: &#123;{ logo_black }} &lt;img src="&#123;{ logo_black }}" /><br/>
title_main: &#123;{ title_main }}<br/>
title_budget: &#123;{ title_budget }}<br/>
title_main_categories: &#123;{ title_main_categories }}<br/>
title_variations: &#123;{ title_variations }}<br/>
title_account: &#123;{ title_account }}<br/>
title_unit: &#123;{ title_unit }}<br/>
title_advice: &#123;{ title_advice }}<br/>
title_portfolio: &#123;{ title_portfolio }}<br/>
title_highlighted: &#123;{ title_highlighted }}<br/>
title_networth: &#123;{ title_networth }}<br/>
title_annual_spending: &#123;{ title_annual_spending }}<br/>
title_personal_finance_score: &#123;{ title_personal_finance_score }}<br/>
msg_no_variation: &#123;{ msg_no_variation|safe }}<br/>
msg_no_scheduled: &#123;{ msg_no_scheduled|safe }}<br/>
msg_no_highlighted: &#123;{ msg_no_highlighted|safe }}<br/>
msg_no_budget: &#123;{ msg_no_budget|safe }}<br/>
msg_no_share: &#123;{ msg_no_share|safe }}<br/>
msg_amount_unit_date: &#123;{ msg_amount_unit_date|safe }}<br/>
about_welcome: &#123;{ about_welcome|safe }}<br/>
about_programname: &#123;{ about_programname|safe }}<br/>
about_version: &#123;{ about_version|safe }}<br/>
about_bugaddress: &#123;{ about_bugaddress|safe }}<br/>
about_copyrightstatement: &#123;{ about_copyrightstatement|safe }}<br/>
about_homepage: &#123;{ about_homepage|safe }}<br/>
about_forumpage: &#123;{ about_forumpage|safe }}<br/>
about_newspage: &#123;{ about_newspage|safe }}<br/>
about_operationpage: &#123;{ about_operationpage|safe }}<br/>
about_accountpage: &#123;{ about_accountpage|safe }}<br/>
about_shortdescription: &#123;{ about_shortdescription|safe }}<br/>
about_othertext: &#123;{ about_othertext|safe }}<br/>
about_maintext: &#123;{ about_maintext|safe }}<br/>
</div>
</div>
<div class="panel panel-primary">
<div class="panel-heading">Result</div>
<div class="panel-body">
color_negativetext: {{ color_negativetext }}<br/>
color_positivetext: {{ color_positivetext }}<br/>
color_neutraltext: {{ color_neutraltext }}<br/>
color_normaltext: {{ color_normaltext }}<br/>
color_inactivetext: {{ color_inactivetext }}<br/>
color_activetext: {{ color_activetext }}<br/>
color_linktext: {{ color_linktext }}<br/>
color_visitedtext: {{ color_visitedtext }}<br/>
color_activebackground: {{ color_activebackground }}<br/>
font_family: {{ font_family }}<br/>
logo: {{ logo }} <img src="{{ logo }}" /><br/>
logo_black: {{ logo_black }} <img src="{{ logo_black }}" /><br/>
title_main: {{ title_main }}<br/>
title_budget: {{ title_budget }}<br/>
title_main_categories: {{ title_main_categories }}<br/>
title_variations: {{ title_variations }}<br/>
title_account: {{ title_account }}<br/>
title_unit: {{ title_unit }}<br/>
title_advice: {{ title_advice }}<br/>
title_portfolio: {{ title_portfolio }}<br/>
title_highlighted: {{ title_highlighted }}<br/>
title_networth: {{ title_networth }}<br/>
title_annual_spending: {{ title_annual_spending }}<br/>
title_personal_finance_score: {{ title_personal_finance_score }}<br/>
msg_no_variation: {{ msg_no_variation|safe }}<br/>
msg_no_scheduled: {{ msg_no_scheduled|safe }}<br/>
msg_no_highlighted: {{ msg_no_highlighted|safe }}<br/>
msg_no_budget: {{ msg_no_budget|safe }}<br/>
msg_no_share: {{ msg_no_share|safe }}<br/>
msg_amount_unit_date: {{ msg_amount_unit_date|safe }}<br/>
about_welcome: {{ about_welcome|safe }}<br/>
about_programname: {{ about_programname|safe }}<br/>
about_version: {{ about_version|safe }}<br/>
about_bugaddress: {{ about_bugaddress|safe }}<br/>
about_copyrightstatement: {{ about_copyrightstatement|safe }}<br/>
about_homepage: {{ about_homepage|safe }}<br/>
about_forumpage: {{ about_forumpage|safe }}<br/>
about_newspage: {{ about_newspage|safe }}<br/>
about_operationpage: {{ about_operationpage|safe }}<br/>
about_accountpage: {{ about_accountpage|safe }}<br/>
about_shortdescription: {{ about_shortdescription|safe }}<br/>
about_othertext: {{ about_othertext|safe }}<br/>
about_maintext: {{ about_maintext|safe }}<br/>
</div>
</div>
<h2>The report:</h2>
From this object you can have access to more complex values:
<div class="panel panel-primary">
<div class="panel-heading">Code</div>
<div class="panel-body">
report.period=&#123;{ report.period }}<br/>
report.previous_period=&#123;{ report.previous_period }}<br/>
report.previous.period=&#123;{ report.previous.period }}<br/>
report.previous.previous_period=&#123;{ report.previous.previous_period }}<br/>
report.budget_table=&#123;{ report.budget_table|dump|safe }}<br/>
report.unit_table=&#123;{ report.unit_table|dump|safe }}<br/>
report.portfolio=&#123;{ report.portfolio|dump|safe }}<br/>
report.account_table=&#123;{ report.account_table|dump|safe }}<br/>
report.bank_table=&#123;{ report.bank_table|dump|safe }}<br/>
report.scheduled_operations=&#123;{ report.scheduled_operations|dump|safe }}<br/>
report.categories_period=&#123;{ report.categories_period|dump|safe }}<br/>
report.categories_previous_period=&#123;{ report.categories_previous_period|dump|safe }}<br/>
report.income_vs_expenditure=&#123;{ report.income_vs_expenditure|dump|safe }}<br/>
report.networth=&#123;{ report.networth|money|safe }}<br/>
report.annual_spending=&#123;{ report.annual_spending|money|safe }}<br/>
report.personal_finance_score=&#123;{ report.personal_finance_score }}<br/>
report.categories_variations=&#123;{ report.categories_variations|dump|safe }}<br/>
report.categories_variations_issues=&#123;{ report.categories_variations_issues|dump|safe }}<br/>
</div>
</div>
<div class="panel panel-primary">
<div class="panel-heading">Result</div>
<div class="panel-body">
report.period={{ report.period }}<br/>
report.previous_period={{ report.previous_period }}<br/>
report.previous.period={{ report.previous.period }}<br/>
report.previous.previous_period={{ report.previous.previous_period }}<br/>
report.budget_table={{ report.budget_table|dump|safe }}<br/>
report.unit_table={{ report.unit_table|dump|safe }}<br/>
report.portfolio={{ report.portfolio|dump|safe }}<br/>
report.account_table={{ report.account_table|dump|safe }}<br/>
report.bank_table={{ report.bank_table|dump|safe }}<br/>
report.scheduled_operations={{ report.scheduled_operations|dump|safe }}<br/>
report.categories_period={{ report.categories_period|dump|safe }}<br/>
report.categories_previous_period={{ report.categories_previous_period|dump|safe }}<br/>
report.income_vs_expenditure={{ report.income_vs_expenditure|dump|safe }}<br/>
report.networth={{ report.networth|money|safe }}<br/>
report.annual_spending={{ report.annual_spending|money|safe }}<br/>
report.personal_finance_score={{ report.personal_finance_score }}<br/>
report.categories_variations={{ report.categories_variations|dump|safe }}<br/>
report.categories_variations_issues={{ report.categories_variations_issues|dump|safe }}<br/>
</div>
</div>
<h2>The document:</h2>
From this object you can have access to more complex values:
<div class="panel panel-primary">
<div class="panel-heading">Code</div>
<div class="panel-body">
&#123;{ document|dump|safe }}
</div>
</div>
<div class="alert alert-success" role="alert">The "dump" filter allows to dump the object</div>
<div class="panel panel-primary">
<div class="panel-heading">Result</div>
<div class="panel-body">
{{ document|dump|safe }}
</div>
</div>
<h1>The filters</h1>
In addition of standard filters, you can the following filters developed for Skrooge.
<div class="panel panel-primary">
<div class="panel-heading">Code</div>
<div class="panel-body">
&#123;{ 10.1|money|safe }}<br/>
&#123;{ -10.2|money|safe }}<br/>
&#123;{ -10.2|money:"nocolor" }}<br/>
&#123;{ 10.1|money:"1"|safe }}<br/>
&#123;{ -10.2|money:"1"|safe }}<br/>
&#123;{ 10.1|money:"2"|safe }}<br/>
&#123;{ -10.2|money:"2"|safe }}<br/>
&#123;{ -10.2|money:"2;nocolor" }}<br/>
&#123;{ 10.1|percent|safe }}<br/>
&#123;{ -10.2|percent|safe }}<br/>
&#123;{ 70000|filesizeformat }}<br/>
</div>
</div>
<div class="alert alert-success" role="alert">The "money" filter display a numerical value as a money. With "1", in primary money. With "2", in secondary money</div>
<div class="alert alert-success" role="alert">The "percent" filter display a numerical value as a percent</div>
<div class="alert alert-success" role="alert">The "filesizeformat" filter display a numerical value as a file size format</div>
<div class="panel panel-primary">
<div class="panel-heading">Result</div>
<div class="panel-body">
{{ 10.1|money|safe }}<br/>
{{ -10.2|money|safe }}<br/>
{{ -10.2|money:"nocolor" }}<br/>
{{ 10.1|money:"1"|safe }}<br/>
{{ -10.2|money:"1"|safe }}<br/>
{{ 10.1|money:"2"|safe }}<br/>
{{ -10.2|money:"2"|safe }}<br/>
{{ -10.2|money:"2;nocolor" }}<br/>
{{ 10.1|percent|safe }}<br/>
{{ -10.2|percent|safe }}<br/>
{{ 70000|filesizeformat }}<br/>
</div>
</div>
The following code will display the list of opened accounts with current amount:<br/>
<div class="panel panel-primary">
<div class="panel-heading">Code</div>
<div class="panel-body">
&#123;% for item in document|table:"v_account_display,t_close='N' ORDER BY t_name" %}<br/>
&#123;{ item|att:"t_name" }}:&#123;{ item|att:"f_CURRENTAMOUNT"|money|safe }}&lt;br/&gt;<br/>
&#123;% endfor %}
</div>
</div>
<div class="alert alert-success" role="alert">The "table" filter allows to search objects</div>
<div class="alert alert-success" role="alert">The "att" filter allows to get an attribute of an object</div>
<div class="panel panel-primary">
<div class="panel-heading">Result</div>
<div class="panel-body">
{% for item in document|table:"v_account_display,t_close='N' ORDER BY t_name" %}
{{ item|att:"t_name" }}:{{ item|att:"f_CURRENTAMOUNT"|money|safe }}<br/>
{% endfor %}
</div>
</div>
The following code will execute a sql order and display the result:<br/>
<div class="panel panel-primary">
<div class="panel-heading">Code</div>
<div class="panel-body">
&#123;% for item in document|query:"select t_name as name, (select count(1) from operation where rd_account_id=account.id) as id from account" %}<br/>
&#123;{ item.0 }}:&#123;{ item.1 }}&lt;br/&gt;<br/>
&#123;% endfor %}
</div>
</div>
<div class="alert alert-success" role="alert">The "query" filter allows to execute the sql order you want</div>
<div class="panel panel-primary">
<div class="panel-heading">Result</div>
<div class="panel-body">
{% for item in document|query:"select t_name as name, (select count(1) from operation where rd_account_id=account.id) as id from account" %}
{{ item.0 }}:{{ item.1 }}<br/>
{% endfor %}
</div>
</div>
You can also use external libraries to display values as you want:
<div class="panel panel-primary">
<div class="panel-heading">Code</div>
<div class="panel-body">
&lt;img src="http://chart.apis.google.com/chart?cht=bvs&chxs=0,&#123;{ color_normaltext }}|1,&#123;{ color_normaltext }}&chbh=100&chxt=x,y&chxr=1,0,&#123;{ report.income_vs_expenditure.4.3 }}&chf=bg,s,&#123;{ color_normalbackground }}&chco=&#123;{ color_negativetext }}|&#123;{ color_positivetext }}&chd=t:&#123;{ report.income_vs_expenditure.2.3 }},&#123;{ report.income_vs_expenditure.1.3 }}&chds=0,&#123;{ report.income_vs_expenditure.4.3 }}&chs=300x200&chl=&#123;{ document|display:"f_CURRENTAMOUNT_EXPENSE" }}|&#123;{ document|display:"f_CURRENTAMOUNT_INCOME" }}&chts=&#123;{ color_normaltext }}&chtt=&#123;{ document|display:"f_CURRENTAMOUNT_EXPENSE" }} vs &#123;{ document|display:"f_CURRENTAMOUNT_INCOME" }}|&#123;{ report.period }}"/>
</div>
</div>
<div class="panel panel-primary">
<div class="panel-heading">Result</div>
<div class="panel-body">
<img src="http://chart.apis.google.com/chart?cht=bvs&chxs=0,{{ color_normaltext }}|1,{{ color_normaltext }}&chbh=100&chxt=x,y&chxr=1,0,{{ report.income_vs_expenditure.4.3 }}&chf=bg,s,{{ color_normalbackground }}&chco={{ color_negativetext }}|{{ color_positivetext }}&chd=t:{{ report.income_vs_expenditure.2.3 }},{{ report.income_vs_expenditure.1.3 }}&chds=0,{{ report.income_vs_expenditure.4.3 }}&chs=300x200&chl={{ document|display:"f_CURRENTAMOUNT_EXPENSE" }}|{{ document|display:"f_CURRENTAMOUNT_INCOME" }}&chts={{ color_normaltext }}&chtt={{ document|display:"f_CURRENTAMOUNT_EXPENSE" }} vs {{ document|display:"f_CURRENTAMOUNT_INCOME" }}|{{ report.period }}"/>
</div>
</div>
</body>
</html>
diff --git a/tests/skgbankguitest/CMakeLists.txt b/tests/skgbankguitest/CMakeLists.txt
index e4e781a5b..3789ef11d 100644
--- a/tests/skgbankguitest/CMakeLists.txt
+++ b/tests/skgbankguitest/CMakeLists.txt
@@ -1,53 +1,53 @@
#***************************************************************************
#* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
#* *
#* 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 <http://www.gnu.org/licenses/> *
+#* along with this program. If not, see <https://www.gnu.org/licenses/> *
#***************************************************************************
MESSAGE( STATUS "..:: CMAKE SKGBANKGUITEST ::..")
PROJECT(SKBBASEMODELERTEST)
ADD_DEFINITIONS(-DQT_GUI_LIB)
LINK_DIRECTORIES (${LIBRARY_OUTPUT_PATH})
INCLUDE_DIRECTORIES( ${CMAKE_SOURCE_DIR}/tests/skgbasemodelertest )
#Make executables
ADD_EXECUTABLE(skgtestpredicatcreator skgtestpredicatcreator.cpp)
ADD_EXECUTABLE(skgtestmainpanel skgtestmainpanel.cpp)
ADD_EXECUTABLE(skgtestactions skgtestactions.cpp)
ADD_EXECUTABLE(skgtesttreeview skgtesttreeview.cpp)
ADD_EXECUTABLE(skgtestbankwidgets skgtestbankwidgets.cpp)
ADD_EXECUTABLE(skgtestmodel skgtestmodel.cpp modeltest.cpp)
TARGET_LINK_LIBRARIES(skgtestpredicatcreator Qt5::Gui Qt5::Core Qt5::Test skgbasemodeler skgbankmodeler skgbankgui skgbasegui)
TARGET_LINK_LIBRARIES(skgtestmainpanel Qt5::Gui Qt5::Core Qt5::Test skgbasemodeler skgbankmodeler skgbankgui skgbasegui)
TARGET_LINK_LIBRARIES(skgtestactions Qt5::Gui Qt5::Core Qt5::Test skgbasemodeler skgbankmodeler skgbankgui skgbasegui)
TARGET_LINK_LIBRARIES(skgtesttreeview Qt5::Core KF5::KIOWidgets Qt5::Test skgbankmodeler skgbasemodeler skgbankgui skgbasegui)
TARGET_LINK_LIBRARIES(skgtestbankwidgets Qt5::Core KF5::KIOWidgets Qt5::Test skgbankmodeler skgbasemodeler skgbankguidesigner skgbasegui)
TARGET_LINK_LIBRARIES(skgtestmodel Qt5::Core KF5::KIOWidgets Qt5::Test skgbankmodeler skgbasemodeler skgbankgui skgbasegui)
#Add test
ENABLE_TESTING()
ADD_TEST(NAME skgtestpredicatcreator COMMAND ${CMAKE_SOURCE_DIR}/tests/scripts/skgtestpredicatcreator.sh)
ADD_TEST(NAME skgtestmainpanel COMMAND ${CMAKE_SOURCE_DIR}/tests/scripts/skgtestmainpanel.sh)
ADD_TEST(NAME skgtestactions COMMAND ${CMAKE_SOURCE_DIR}/tests/scripts/skgtestactions.sh)
ADD_TEST(NAME skgtesttreeview COMMAND ${CMAKE_SOURCE_DIR}/tests/scripts/skgtesttreeview.sh)
ADD_TEST(NAME skgtestbankwidgets COMMAND ${CMAKE_SOURCE_DIR}/tests/scripts/skgtestbankwidgets.sh)
ADD_TEST(NAME skgtestmodel COMMAND ${CMAKE_SOURCE_DIR}/tests/scripts/skgtestmodel.sh)
#TODO: TO LONG ADD_TEST(NAME skgtestskrooge COMMAND ${CMAKE_SOURCE_DIR}/tests/scripts/skgtestskrooge.sh)
INCLUDE(CTest)
diff --git a/tests/skgbankguitest/modeltest.cpp b/tests/skgbankguitest/modeltest.cpp
index 51418e28e..f351fa9c5 100644
--- a/tests/skgbankguitest/modeltest.cpp
+++ b/tests/skgbankguitest/modeltest.cpp
@@ -1,589 +1,589 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/****************************************************************************
**
** Copy right ( C ) 2012 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "modeltest.h"
#include <QtTest>
#undef Q_ASSERT
#define Q_ASSERT QVERIFY
Q_DECLARE_METATYPE(QModelIndex)
/*!
Connect to all of the models signals. Whenever anything happens recheck everything.
*/
ModelTest::ModelTest(QAbstractItemModel* model, QObject* iParent) : QObject(iParent), model(model), fetchingMore(false)
{
Q_ASSERT(model);
connect(model, &QAbstractItemModel::columnsAboutToBeInserted, this, &ModelTest::runAllTests);
connect(model, &QAbstractItemModel::columnsAboutToBeRemoved, this, &ModelTest::runAllTests);
connect(model, &QAbstractItemModel::columnsInserted, this, &ModelTest::runAllTests);
connect(model, &QAbstractItemModel::columnsRemoved, this, &ModelTest::runAllTests);
connect(model, &QAbstractItemModel::dataChanged, this, &ModelTest::runAllTests);
connect(model, &QAbstractItemModel::headerDataChanged, this, &ModelTest::runAllTests);
connect(model, &QAbstractItemModel::layoutAboutToBeChanged, this, &ModelTest::runAllTests);
connect(model, &QAbstractItemModel::layoutChanged, this, &ModelTest::runAllTests);
connect(model, &QAbstractItemModel::modelReset, this, &ModelTest::runAllTests);
connect(model, &QAbstractItemModel::rowsAboutToBeInserted, this, &ModelTest::runAllTests);
connect(model, &QAbstractItemModel::rowsAboutToBeRemoved, this, &ModelTest::runAllTests);
connect(model, &QAbstractItemModel::rowsInserted, this, &ModelTest::runAllTests);
connect(model, &QAbstractItemModel::rowsRemoved, this, &ModelTest::runAllTests);
// Special checks for inserting/removing
connect(model, &QAbstractItemModel::layoutAboutToBeChanged, this, &ModelTest::layoutAboutToBeChanged);
connect(model, &QAbstractItemModel::layoutChanged, this, &ModelTest::layoutChanged);
connect(model, &QAbstractItemModel::rowsAboutToBeInserted, this, &ModelTest::rowsAboutToBeInserted);
connect(model, &QAbstractItemModel::rowsAboutToBeRemoved, this, &ModelTest::rowsAboutToBeRemoved);
connect(model, &QAbstractItemModel::rowsInserted, this, &ModelTest::rowsInserted);
connect(model, &QAbstractItemModel::rowsRemoved, this, &ModelTest::rowsRemoved);
runAllTests();
}
void ModelTest::runAllTests()
{
if (fetchingMore) {
return;
}
nonDestructiveBasicTest();
rowCount();
columnCount();
hasIndex();
index();
parent();
data();
}
/*!
nonDestructiveBasicTest tries to call a number of the basic functions (not all)
to make sure the model doesn't outright segfault, testing the functions that makes sense.
*/
void ModelTest::nonDestructiveBasicTest()
{
Q_ASSERT(model->buddy(QModelIndex()) == QModelIndex());
model->canFetchMore(QModelIndex());
Q_ASSERT(model->columnCount(QModelIndex()) >= 0);
Q_ASSERT(model->data(QModelIndex()) == QVariant());
fetchingMore = true;
model->fetchMore(QModelIndex());
fetchingMore = false;
Qt::ItemFlags flags = model->flags(QModelIndex());
Q_ASSERT(flags == Qt::ItemIsDropEnabled || flags == 0);
model->hasChildren(QModelIndex());
model->hasIndex(0, 0);
model->headerData(0, Qt::Horizontal);
model->index(0, 0);
model->itemData(QModelIndex());
QVariant cache;
model->match(QModelIndex(), -1, cache);
model->mimeTypes();
Q_ASSERT(model->parent(QModelIndex()) == QModelIndex());
Q_ASSERT(model->rowCount() >= 0);
QVariant variant;
model->setData(QModelIndex(), variant, -1);
model->setHeaderData(-1, Qt::Horizontal, QVariant());
model->setHeaderData(999999, Qt::Horizontal, QVariant());
model->sibling(0, 0, QModelIndex());
model->span(QModelIndex());
model->supportedDropActions();
}
/*!
Tests model's implementation of QAbstractItemModel::rowCount() and hasChildren()
Models that are dynamically populated are not as fully tested here.
*/
void ModelTest::rowCount()
{
// qDebug() << "rc";
// check top row
QModelIndex topIndex = model->index(0, 0, QModelIndex());
int rows = model->rowCount(topIndex);
Q_ASSERT(rows >= 0);
if (rows > 0) {
Q_ASSERT(model->hasChildren(topIndex) == true);
}
QModelIndex secondLevelIndex = model->index(0, 0, topIndex);
if (secondLevelIndex.isValid()) { // not the top level
// check a row count where parent is valid
rows = model->rowCount(secondLevelIndex);
Q_ASSERT(rows >= 0);
if (rows > 0) {
Q_ASSERT(model->hasChildren(secondLevelIndex) == true);
}
}
// The models rowCount() is tested more extensively in checkChildren(),
// but this catches the big mistakes
}
/*!
Tests model's implementation of QAbstractItemModel::columnCount() and hasChildren()
*/
void ModelTest::columnCount()
{
// check top row
QModelIndex topIndex = model->index(0, 0, QModelIndex());
Q_ASSERT(model->columnCount(topIndex) >= 0);
// check a column count where parent is valid
QModelIndex childIndex = model->index(0, 0, topIndex);
if (childIndex.isValid()) {
Q_ASSERT(model->columnCount(childIndex) >= 0);
}
// columnCount() is tested more extensively in checkChildren(),
// but this catches the big mistakes
}
/*!
Tests model's implementation of QAbstractItemModel::hasIndex()
*/
void ModelTest::hasIndex()
{
// qDebug() << "hi";
// Make sure that invalid values returns an invalid index
Q_ASSERT(model->hasIndex(-2, -2) == false);
Q_ASSERT(model->hasIndex(-2, 0) == false);
Q_ASSERT(model->hasIndex(0, -2) == false);
int rows = model->rowCount();
int columns = model->columnCount();
// check out of bounds
Q_ASSERT(model->hasIndex(rows, columns) == false);
Q_ASSERT(model->hasIndex(rows + 1, columns + 1) == false);
if (rows > 0) {
Q_ASSERT(model->hasIndex(0, 0) == true);
}
// hasIndex() is tested more extensively in checkChildren(),
// but this catches the big mistakes
}
/*!
Tests model's implementation of QAbstractItemModel::index()
*/
void ModelTest::index()
{
// qDebug() << "i";
// Make sure that invalid values returns an invalid index
Q_ASSERT(model->index(-2, -2) == QModelIndex());
Q_ASSERT(model->index(-2, 0) == QModelIndex());
Q_ASSERT(model->index(0, -2) == QModelIndex());
int rows = model->rowCount();
int columns = model->columnCount();
if (rows == 0) {
return;
}
// Catch off by one errors
Q_ASSERT(model->index(rows, columns) == QModelIndex());
Q_ASSERT(model->index(0, 0).isValid() == true);
// Make sure that the same index is *always* returned
QModelIndex a = model->index(0, 0);
QModelIndex b = model->index(0, 0);
Q_ASSERT(a == b);
// index() is tested more extensively in checkChildren(),
// but this catches the big mistakes
}
/*!
Tests model's implementation of QAbstractItemModel::parent()
*/
void ModelTest::parent()
{
// qDebug() << "p";
// Make sure the model wont crash and will return an invalid QModelIndex
// when asked for the parent of an invalid index.
Q_ASSERT(model->parent(QModelIndex()) == QModelIndex());
if (model->rowCount() == 0) {
return;
}
// Column 0 | Column 1 |
// QModelIndex() | |
// \- topIndex | topIndex1 |
// \- childIndex | childIndex1 |
// Common error test #1, make sure that a top level index has a parent
// that is a invalid QModelIndex.
QModelIndex topIndex = model->index(0, 0, QModelIndex());
Q_ASSERT(model->parent(topIndex) == QModelIndex());
// Common error test #2, make sure that a second level index has a parent
// that is the first level index.
if (model->rowCount(topIndex) > 0) {
QModelIndex childIndex = model->index(0, 0, topIndex);
Q_ASSERT(model->parent(childIndex) == topIndex);
}
// Common error test #3, the second column should NOT have the same children
// as the first column in a row.
// Usually the second column shouldn't have children.
QModelIndex topIndex1 = model->index(0, 1, QModelIndex());
if (model->rowCount(topIndex1) > 0) {
QModelIndex childIndex = model->index(0, 0, topIndex);
QModelIndex childIndex1 = model->index(0, 0, topIndex1);
Q_ASSERT(childIndex != childIndex1);
}
// Full test, walk n levels deep through the model making sure that all
// parent's children correctly specify their parent.
checkChildren(QModelIndex());
}
/*!
Called from the parent() test.
A model that returns an index of parent X should also return X when asking
for the parent of the index.
This recursive function does pretty extensive testing on the whole model in an
effort to catch edge cases.
This function assumes that rowCount(), columnCount() and index() already work.
If they have a bug it will point it out, but the above tests should have already
found the basic bugs because it is easier to figure out the problem in
those tests then this one.
*/
void ModelTest::checkChildren(const QModelIndex& iParent, int currentDepth)
{
// First just try walking back up the tree.
QModelIndex p = iParent;
while (p.isValid()) {
p = p.parent();
}
// For models that are dynamically populated
if (model->canFetchMore(iParent)) {
fetchingMore = true;
model->fetchMore(iParent);
fetchingMore = false;
}
int rows = model->rowCount(iParent);
int columns = model->columnCount(iParent);
if (rows > 0) {
Q_ASSERT(model->hasChildren(iParent));
}
// Some further testing against rows(), columns(), and hasChildren()
Q_ASSERT(rows >= 0);
Q_ASSERT(columns >= 0);
if (rows > 0) {
Q_ASSERT(model->hasChildren(iParent) == true);
}
// qDebug() << "iParent:" << model->data(iParent).toString() << "rows:" << rows
// << "columns:" << columns << "iParent column:" << iParent.column();
Q_ASSERT(model->hasIndex(rows + 1, 0, iParent) == false);
for (int r = 0; r < rows; ++r) {
if (model->canFetchMore(iParent)) {
fetchingMore = true;
model->fetchMore(iParent);
fetchingMore = false;
}
Q_ASSERT(model->hasIndex(r, columns + 1, iParent) == false);
for (int c = 0; c < columns; ++c) {
Q_ASSERT(model->hasIndex(r, c, iParent) == true);
QModelIndex idx = model->index(r, c, iParent);
// rowCount() and columnCount() said that it existed...
Q_ASSERT(idx.isValid() == true);
// index() should always return the same index when called twice in a row
QModelIndex modifiedIndex = model->index(r, c, iParent);
Q_ASSERT(idx == modifiedIndex);
// Make sure we get the same index if we request it twice in a row
QModelIndex a = model->index(r, c, iParent);
QModelIndex b = model->index(r, c, iParent);
Q_ASSERT(a == b);
// Some basic checking on the index that is returned
Q_ASSERT(idx.model() == model);
Q_ASSERT(idx.row() == r);
Q_ASSERT(idx.column() == c);
// While you can technically return a QVariant usually this is a sign
// of an bug in data() Disable if this really is ok in your model.
Q_ASSERT(model->data(idx, Qt::DisplayRole).isValid() == true);
// If the next test fails here is some somewhat useful debug you play with.
if (model->parent(idx) != iParent) {
qDebug() << r << c << currentDepth << model->data(idx).toString()
<< model->data(iParent).toString();
qDebug() << idx << iParent << model->parent(idx);
// And a view that you can even use to show the model.
// QTreeView view;
// view.setModel(model);
// view.show();
}
// Check that we can get back our real parent.
// qDebug() << model->parent ( index ) << parent;
Q_ASSERT(model->parent(idx) == iParent);
// recursively go down the children
if (model->hasChildren(idx) && currentDepth < 10) {
// qDebug() << r << c << "has children" << model->rowCount(index);
checkChildren(idx, ++currentDepth);
}/* else { if (currentDepth >= 10) qDebug() << "checked 10 deep"; };*/
// make sure that after testing the children that the index doesn't change.
QModelIndex newerIndex = model->index(r, c, iParent);
Q_ASSERT(idx == newerIndex);
}
}
}
/*!
Tests model's implementation of QAbstractItemModel::data()
*/
void ModelTest::data()
{
// Invalid index should return an invalid qvariant
Q_ASSERT(!model->data(QModelIndex()).isValid());
int nbRows = model->rowCount();
int nbColumns = model->columnCount();
if (nbRows == 0 || nbColumns == 0) {
return;
}
for (int r = 0; r < nbRows; ++r) {
for (int c = 0; c < nbColumns; ++c) {
// A valid index should have a valid QVariant data
Q_ASSERT(model->index(r, c).isValid());
// shouldn't be able to set data on an invalid index
Q_ASSERT(model->setData(QModelIndex(), QStringLiteral("foo"), Qt::DisplayRole) == false);
// General Purpose roles that should return a QString
QVariant variant = model->data(model->index(r, c), Qt::ToolTipRole);
if (variant.isValid()) {
Q_ASSERT(variant.canConvert<QString>());
}
variant = model->data(model->index(r, c), Qt::StatusTipRole);
if (variant.isValid()) {
Q_ASSERT(variant.canConvert<QString>());
}
variant = model->data(model->index(r, c), Qt::WhatsThisRole);
if (variant.isValid()) {
Q_ASSERT(variant.canConvert<QString>());
}
// General Purpose roles that should return a QSize
variant = model->data(model->index(r, c), Qt::SizeHintRole);
if (variant.isValid()) {
Q_ASSERT(variant.canConvert<QSize> ());
}
// MANKOWSKI: UserRole
variant = model->data(model->index(r, c), Qt::UserRole);
if (variant.isValid()) {
Q_ASSERT(variant.canConvert<QString>());
}
// General Purpose roles that should return a QFont
QVariant fontVariant = model->data(model->index(r, c), Qt::FontRole);
if (fontVariant.isValid()) {
Q_ASSERT(fontVariant.canConvert<QFont> ());
}
// Check that the alignment is one we know about
QVariant textAlignmentVariant = model->data(model->index(r, c), Qt::TextAlignmentRole);
if (textAlignmentVariant.isValid()) {
int alignment = textAlignmentVariant.toInt();
Q_ASSERT(static_cast<unsigned int>(alignment) == static_cast<unsigned int>(alignment & (Qt::AlignHorizontal_Mask | Qt::AlignVertical_Mask)));
}
// General Purpose roles that should return a QColor
QVariant colorVariant = model->data(model->index(r, c), Qt::BackgroundColorRole);
if (colorVariant.isValid()) {
Q_ASSERT(colorVariant.canConvert<QColor> ());
}
colorVariant = model->data(model->index(r, c), Qt::TextColorRole);
if (colorVariant.isValid()) {
Q_ASSERT(colorVariant.canConvert<QColor> ());
}
// Check that the "check state" is one we know about.
QVariant checkStateVariant = model->data(model->index(r, c), Qt::CheckStateRole);
if (checkStateVariant.isValid()) {
int state = checkStateVariant.toInt();
Q_ASSERT(state == Qt::Unchecked ||
state == Qt::PartiallyChecked ||
state == Qt::Checked);
}
}
}
}
/*!
Store what is about to be inserted to make sure it actually happens
\sa rowsInserted()
*/
void ModelTest::rowsAboutToBeInserted(const QModelIndex& iParent, int start, int end)
{
Q_UNUSED(end)
// qDebug() << "rowsAboutToBeInserted" << "start=" << start << "end=" << end << "parent=" << model->data ( parent ).toString()
// << "current count of parent=" << model->rowCount ( parent ); // << "display of last=" << model->data( model->index(start-1, 0, parent) );
// qDebug() << model->index(start-1, 0, parent) << model->data( model->index(start-1, 0, parent) );
Changing c;
c.parent = iParent;
c.oldSize = model->rowCount(iParent);
c.last = model->data(model->index(start - 1, 0, iParent));
c.next = model->data(model->index(start, 0, iParent));
insert.push(c);
}
/*!
Confirm that what was said was going to happen actually did
\sa rowsAboutToBeInserted()
*/
void ModelTest::rowsInserted(const QModelIndex& iParent, int start, int end)
{
Changing c = insert.pop();
Q_ASSERT(c.parent == iParent);
// qDebug() << "rowsInserted" << "start=" << start << "end=" << end << "oldsize=" << c.oldSize
// << "parent=" << model->data ( parent ).toString() << "current rowcount of parent=" << model->rowCount ( parent );
// for (int ii=start; ii <= end; ii++)
// {
// qDebug() << "itemWasInserted:" << ii << model->data ( model->index ( ii, 0, parent ));
// }
// qDebug();
Q_ASSERT(c.oldSize + (end - start + 1) == model->rowCount(iParent));
Q_ASSERT(c.last == model->data(model->index(start - 1, 0, c.parent)));
if (c.next != model->data(model->index(end + 1, 0, c.parent))) {
qDebug() << start << end;
for (int i = 0; i < model->rowCount(); ++i) {
qDebug() << model->index(i, 0).data().toString();
}
qDebug() << c.next << model->data(model->index(end + 1, 0, c.parent));
}
Q_ASSERT(c.next == model->data(model->index(end + 1, 0, c.parent)));
}
void ModelTest::layoutAboutToBeChanged()
{
for (int i = 0; i < qBound(0, model->rowCount(), 100); ++i) {
changing.append(QPersistentModelIndex(model->index(i, 0)));
}
}
void ModelTest::layoutChanged()
{
for (int i = 0; i < changing.count(); ++i) {
QPersistentModelIndex p = changing.at(i);
Q_ASSERT(p == model->index(p.row(), p.column(), p.parent()));
}
changing.clear();
}
/*!
Store what is about to be inserted to make sure it actually happens
\sa rowsRemoved()
*/
void ModelTest::rowsAboutToBeRemoved(const QModelIndex& iParent, int start, int end)
{
qDebug() << "ratbr" << iParent << start << end;
Changing c;
c.parent = iParent;
c.oldSize = model->rowCount(iParent);
c.last = model->data(model->index(start - 1, 0, iParent));
c.next = model->data(model->index(end + 1, 0, iParent));
remove.push(c);
}
/*!
Confirm that what was said was going to happen actually did
\sa rowsAboutToBeRemoved()
*/
void ModelTest::rowsRemoved(const QModelIndex& iParent, int start, int end)
{
qDebug() << "rr" << iParent << start << end;
Changing c = remove.pop();
Q_ASSERT(c.parent == iParent);
Q_ASSERT(c.oldSize - (end - start + 1) == model->rowCount(iParent));
Q_ASSERT(c.last == model->data(model->index(start - 1, 0, c.parent)));
Q_ASSERT(c.next == model->data(model->index(start, 0, c.parent)));
}
diff --git a/tests/skgbankguitest/modeltest.h b/tests/skgbankguitest/modeltest.h
index 7014e4078..1a3cda495 100644
--- a/tests/skgbankguitest/modeltest.h
+++ b/tests/skgbankguitest/modeltest.h
@@ -1,111 +1,111 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/****************************************************************************
**
** Copy right ( C ) 2012 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef MODELTEST_H
#define MODELTEST_H
#include <qabstractitemmodel.h>
#include <qobject.h>
#include <qstack.h>
class ModelTest : public QObject
{
Q_OBJECT
public:
explicit ModelTest(QAbstractItemModel* model, QObject* iParent = nullptr);
private Q_SLOTS:
void nonDestructiveBasicTest();
void rowCount();
void columnCount();
void hasIndex();
void index();
void parent();
void data();
protected Q_SLOTS:
void runAllTests();
void layoutAboutToBeChanged();
void layoutChanged();
void rowsAboutToBeInserted(const QModelIndex& iParent, int start, int end);
void rowsInserted(const QModelIndex& iParent, int start, int end);
void rowsAboutToBeRemoved(const QModelIndex& iParent, int start, int end);
void rowsRemoved(const QModelIndex& iParent, int start, int end);
private:
void checkChildren(const QModelIndex& iParent, int currentDepth = 0);
QAbstractItemModel* model;
struct Changing {
QModelIndex parent;
int oldSize{};
QVariant last;
QVariant next;
};
QStack<Changing> insert;
QStack<Changing> remove;
bool fetchingMore;
QList<QPersistentModelIndex> changing;
};
#endif
diff --git a/tests/skgbankguitest/skgtestactions.cpp b/tests/skgbankguitest/skgtestactions.cpp
index f619adadf..7d9ff2b31 100644
--- a/tests/skgbankguitest/skgtestactions.cpp
+++ b/tests/skgbankguitest/skgtestactions.cpp
@@ -1,151 +1,151 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is a test for actions.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgtestactions.h"
#include "skgboardwidget.h"
#include "skgdocumentbank.h"
#include "skgmainpanel.h"
#include "skgtestmacro.h"
#include "skgtraces.h"
void SKGTESTActions::Test()
{
// Initialize document
SKGDocumentBank doc;
// Create main panel
SKGMainPanel mainpanel(nullptr, &doc);
mainpanel.show();
QVERIFY2(!doc.load(SKGTest::getTestPath(QStringLiteral("IN")) % "/advice.skg"), "Load document failed");
{
SKGError err;
SKGBEGINTRANSACTION(doc, QStringLiteral("DELETE"), err)
doc.executeSqliteOrder(QStringLiteral("DELETE FROM operation WHERE d_date<'") + SKGServices::dateToSqlString(QDate::currentDate().addMonths(-2)) + '\'');
}
// Scenario
QStringList actionsToExecute;
actionsToExecute
// Reinitialize document
<< QStringLiteral("tab_closeall") << QStringLiteral("fullscreen") << QStringLiteral("fullscreen") << QStringLiteral("fullscreen") << QStringLiteral("edit_undolastsave") << QStringLiteral("view_unlock") << QStringLiteral("view_unlock") << QStringLiteral("options_show_menubar") << QStringLiteral("options_show_menubar")
// Bank page
<< QStringLiteral("page_Skrooge bank plugin") << QStringLiteral("enable_editor") << QStringLiteral("edit_select_all") << QStringLiteral("edit_copy") << QStringLiteral("edit_switch_highlight") << QStringLiteral("edit_select_all") << QStringLiteral("edit_delete")
// Undo
<< QStringLiteral("edit_undo") << QStringLiteral("edit_redo") << QStringLiteral("edit_undolastsave") << QStringLiteral("edit_clear_history")
// Clean
<< QStringLiteral("edit_select_all") << QStringLiteral("open_report") << QStringLiteral("edit_find")
<< QStringLiteral("page_Skrooge bank plugin") << QStringLiteral("edit_select_all") << QStringLiteral("edit_reconciliate")
<< QStringLiteral("page_Skrooge bank plugin") << QStringLiteral("edit_select_all") << QStringLiteral("edit_find")
// Operation
<< QStringLiteral("page_Skrooge operation plugin") << QStringLiteral("enable_editor") << QStringLiteral("fast_edition") << QStringLiteral("edit_select_all") << QStringLiteral("edit_switch_highlight") << QStringLiteral("edit_point_selected_operation")
<< QStringLiteral("merge_sub_operations")
// Too long << "edit_select_all" << "edit_duplicate_operation"
<< QStringLiteral("edit_select_all") << QStringLiteral("edit_group_operation") << QStringLiteral("merge_imported_operation")
<< QStringLiteral("edit_select_all") << QStringLiteral("open_report")
<< QStringLiteral("page_Skrooge operation plugin") << QStringLiteral("edit_select_all") << QStringLiteral("edit_find")
// Category
<< QStringLiteral("page_Skrooge categories plugin") << QStringLiteral("edit_expandall") << QStringLiteral("edit_collapseal")
<< QStringLiteral("edit_select_all") << QStringLiteral("open_report")
<< QStringLiteral("page_Skrooge categories plugin") << QStringLiteral("edit_select_all") << QStringLiteral("edit_find")
// Search page
<< QStringLiteral("page_Skrooge search plugin") << QStringLiteral("edit_select_all")
<< QStringLiteral("execute_all") << QStringLiteral("execute_notchecked") << QStringLiteral("execute_imported") << QStringLiteral("execute_not_validated")
<< QStringLiteral("open_report")
// All other pages
<< QStringLiteral("page_Dashboard plugin") << QStringLiteral("500")
<< QStringLiteral("page_Skrooge budget plugin") << QStringLiteral("tool_process_budget_rules") << QStringLiteral("edit_select_all") << QStringLiteral("open_report")
<< QStringLiteral("page_Skrooge budget plugin") << QStringLiteral("edit_select_all") << QStringLiteral("edit_find")
<< QStringLiteral("page_Skrooge calculator plugin")
<< QStringLiteral("page_Skrooge payee plugin") << QStringLiteral("edit_select_all") << QStringLiteral("open_report")
<< QStringLiteral("page_Skrooge payee plugin") << QStringLiteral("edit_select_all") << QStringLiteral("edit_find")
<< QStringLiteral("page_Skrooge report plugin")
<< QStringLiteral("page_Skrooge scheduled plugin") << QStringLiteral("edit_select_all") << QStringLiteral("open_report")
<< QStringLiteral("page_Skrooge scheduled plugin") << QStringLiteral("edit_select_all") << QStringLiteral("edit_find")
<< QStringLiteral("page_Skrooge tracker plugin") << QStringLiteral("edit_select_all") << QStringLiteral("open_report")
<< QStringLiteral("page_Skrooge tracker plugin") << QStringLiteral("edit_select_all") << QStringLiteral("edit_find")
<< QStringLiteral("page_Skrooge unit plugin") << QStringLiteral("edit_select_all") << QStringLiteral("open_report")
<< QStringLiteral("page_Skrooge unit plugin") << QStringLiteral("edit_select_all") << QStringLiteral("edit_find")
// Go
<< QStringLiteral("page_Monthly plugin") << QStringLiteral("go_previous") << QStringLiteral("go_next") << QStringLiteral("go_home") << QStringLiteral("new_tab")
// imports
<< QStringLiteral("import") << QStringLiteral("import_backends") << QStringLiteral("import_standard_bookmarks") << QStringLiteral("import_standard_categories")
// Processing
<< QStringLiteral("clean_align_comment") << QStringLiteral("clean_delete_unused_categories") << QStringLiteral("clean_delete_unused_payees") << QStringLiteral("clean_delete_unused_units") << QStringLiteral("clean_remove_group_with_one_operation")
<< QStringLiteral("process_banks") << QStringLiteral("process_foundtransfer") << QStringLiteral("process_validate") << QStringLiteral("processing") << QStringLiteral("switch_validation_imported_operation")
// Views
<< QStringLiteral("view_bookmarks") << QStringLiteral("view_context") << QStringLiteral("view_contextmenu") << QStringLiteral("view_lock") << QStringLiteral("view_menu") << QStringLiteral("view_open_duplicates") << QStringLiteral("view_open_highlight")
<< QStringLiteral("view_open_last_modified") << QStringLiteral("view_open_not_validated") << QStringLiteral("view_open_operation_in_group_of_one") << QStringLiteral("view_open_operation_with_comment_not_aligned")
<< QStringLiteral("view_open_operation_without_category") << QStringLiteral("view_open_operation_without_mode") << QStringLiteral("view_open_operation_without_payee") << QStringLiteral("view_open_suboperations")
<< QStringLiteral("view_open_transfers_without_category") << QStringLiteral("view_open_transfers_without_payee") << QStringLiteral("view_open_very_old_operations") << QStringLiteral("view_properties") << QStringLiteral("view_transactions")
// Close
<< QStringLiteral("tab_close") << QStringLiteral("tab_closeallother") << QStringLiteral("tab_closeall")
// Tabs
<< QStringLiteral("tab_reopenlastclosed") << QStringLiteral("tab_resetdefaultstate") << QStringLiteral("tab_savedefaultstate") << QStringLiteral("tab_switchpin") << QStringLiteral("tab_overwritebookmark")
// File
<< QStringLiteral("file_save") << QStringLiteral("file_new");
// Dump actions
QMap< QString, QPointer<QAction> > actions = mainpanel.getGlobalActions();
QStringList keys = actions.keys();
for (const auto& key : qAsConst(keys)) {
if (!actionsToExecute.contains(key)) {
SKGTRACE << " [" << key << "]" << endl;
}
}
// Trigger actions
for (const auto& key : qAsConst(actionsToExecute)) {
if (key == QStringLiteral("edit_select_all")) {
SKGTRACE << " Wait" << endl;
QTest::qWait(10);
}
SKGTRACE << QDateTime::currentDateTime().toString(QStringLiteral("yyyy-MM-dd hh:mm:ss")) << " [" << key << "]: ";
QAction* act = mainpanel.getGlobalAction(key);
if (act != nullptr) {
act->trigger();
SKGTRACESUITE << "DONE" << endl;
} else {
SKGTRACESUITE << "UNKNOWN" << endl;
}
if (key == QStringLiteral("edit_select_all")) {
SKGTabPage* page = mainpanel.currentPage();
if (page != nullptr) {
SKGTRACE << " Current page:" << page->objectName() << endl;
}
SKGTRACE << " Nb objects selected:" << mainpanel.getNbSelectedObjects() << endl;
}
}
}
QTEST_MAIN(SKGTESTActions)
diff --git a/tests/skgbankguitest/skgtestactions.h b/tests/skgbankguitest/skgtestactions.h
index b13c576e4..3c73fe3cf 100644
--- a/tests/skgbankguitest/skgtestactions.h
+++ b/tests/skgbankguitest/skgtestactions.h
@@ -1,35 +1,35 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGTESTACTIONS_H
#define SKGTESTACTIONS_H
/** @file
* This file is a test for actions.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include <qtest.h>
/**
* A unit test
*/
class SKGTESTActions: public QObject
{
Q_OBJECT
private Q_SLOTS:
void Test();
};
#endif
diff --git a/tests/skgbankguitest/skgtestbankwidgets.cpp b/tests/skgbankguitest/skgtestbankwidgets.cpp
index ec914e349..d2b4aa20e 100644
--- a/tests/skgbankguitest/skgtestbankwidgets.cpp
+++ b/tests/skgbankguitest/skgtestbankwidgets.cpp
@@ -1,113 +1,113 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is a test for bank widgets.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgtestbankwidgets.h"
#include "skgbkwidgetcollectiondesignerplugin.h"
#include "skgdocumentbank.h"
#include "skgquerycreator.h"
#include "skgtestmacro.h"
#include "skgunitcombobox.h"
void SKGTESTBankWidgets::TestSKGUnitComboBox()
{
SKGDocumentBank doc;
QVERIFY2(!doc.load(SKGTest::getTestPath(QStringLiteral("OUT")) % "/advice.skg"), "Load document failed");
SKGUnitComboBox unitWidget(nullptr);
unitWidget.setDocument(&doc);
unitWidget.setWhereClauseCondition(QStringLiteral("t_type='S'"));
SKGUnitObject unit = unitWidget.getUnit();
unitWidget.setUnit(unit);
unitWidget.setText(QStringLiteral("newunit"));
SKGUnitObject newunit = unitWidget.getUnit();
}
void SKGTESTBankWidgets::TestSKGQueryCreator()
{
SKGDocumentBank doc;
QVERIFY2(!doc.load(SKGTest::getTestPath(QStringLiteral("OUT")) % "/advice.skg"), "Load document failed");
QStringList attributeForQuery;
attributeForQuery << QStringLiteral("d_date") << QStringLiteral("t_number") << QStringLiteral("t_mode") << QStringLiteral("t_PAYEE") << QStringLiteral("t_comment") << QStringLiteral("t_REALCOMMENT") << QStringLiteral("t_REALCATEGORY") << QStringLiteral("t_status") << QStringLiteral("t_bookmarked") << QStringLiteral("t_imported") << QStringLiteral("t_TRANSFER") << QStringLiteral("t_UNIT") << QStringLiteral("t_ACCOUNT") << QStringLiteral("t_TOACCOUNT") << QStringLiteral("f_REALCURRENTAMOUNT") << QStringLiteral("t_REALREFUND") << QStringLiteral("f_BALANCE");
SKGQueryCreator creator(nullptr);
creator.setParameters(&doc, QStringLiteral("v_operation"), attributeForQuery);
QCOMPARE(creator.getColumnsCount(), 0);
QCOMPARE(creator.getLinesCount(), 1);
QString cond = QStringLiteral("<!DOCTYPE SKGML><element> <!--OR--> <element> <!--AND--> <element operator=\"#ATT# LIKE '%#V1S#%'\" att2s=\"\" attribute=\"t_PAYEE\" att2=\"\" value=\"VIR CAF \" value2=\"\"/> </element></element>");
creator.setXMLCondition(cond);
QTest::qWait(100);
QString result = creator.getXMLCondition();
QVERIFY(result.contains(QStringLiteral("operator=\"#ATT# LIKE '%#V1S#%'\"")));
QVERIFY(result.contains(QStringLiteral("att2s=\"\"")));
QVERIFY(result.contains(QStringLiteral("attribute=\"t_PAYEE\"")));
QVERIFY(result.contains(QStringLiteral("att2=\"\"")));
QVERIFY(result.contains(QStringLiteral("value=\"VIR CAF \"")));
QVERIFY(result.contains(QStringLiteral("value2=\"\"")));
QCOMPARE(creator.getColumnsCount(), 1);
QCOMPARE(creator.getLinesCount(), 2);
creator.addNewLine();
QCOMPARE(creator.getColumnsCount(), 1);
QCOMPARE(creator.getLinesCount(), 3);
creator.removeLine(0);
creator.removeLine(0);
QCOMPARE(creator.getColumnsCount(), 1);
QCOMPARE(creator.getLinesCount(), 1);
creator.removeColumn(0);
QCOMPARE(creator.getColumnsCount(), 0);
QCOMPARE(creator.getLinesCount(), 1);
creator.removeLine(0);
QCOMPARE(creator.getColumnsCount(), 0);
QCOMPARE(creator.getLinesCount(), 1);
}
void SKGTESTBankWidgets::TestSKGBKWidgetCollectionDesignerPlugin()
{
SKGBKWidgetCollectionDesignerPlugin col(nullptr);
QList<QDesignerCustomWidgetInterface*> items = col.customWidgets();
for (auto item : qAsConst(items)) {
QCOMPARE(item != nullptr, true);
item->isContainer();
QCOMPARE(item->isInitialized(), false);
item->initialize(nullptr);
QCOMPARE(item->isInitialized(), true);
item->icon();
QCOMPARE(item->domXml() != QLatin1String(""), true);
QCOMPARE(item->group(), QStringLiteral("SKG Widgets"));
QCOMPARE(item->includeFile() != QLatin1String(""), true);
QCOMPARE(item->name() != QLatin1String(""), true);
QCOMPARE(item->toolTip() != QLatin1String(""), true);
QCOMPARE(item->whatsThis() != QLatin1String(""), true);
QCOMPARE(item->createWidget(nullptr) != nullptr, true);
}
}
QTEST_MAIN(SKGTESTBankWidgets)
diff --git a/tests/skgbankguitest/skgtestbankwidgets.h b/tests/skgbankguitest/skgtestbankwidgets.h
index 9db1dc5c5..fcbd57bd4 100644
--- a/tests/skgbankguitest/skgtestbankwidgets.h
+++ b/tests/skgbankguitest/skgtestbankwidgets.h
@@ -1,37 +1,37 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGTESTBANKWIDGETS_H
#define SKGTESTBANKWIDGETS_H
/** @file
* This file is a test for bank widgets.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include <qtest.h>
/**
* A unit test
*/
class SKGTESTBankWidgets: public QObject
{
Q_OBJECT
private Q_SLOTS:
void TestSKGUnitComboBox();
void TestSKGQueryCreator();
void TestSKGBKWidgetCollectionDesignerPlugin();
};
#endif
diff --git a/tests/skgbankguitest/skgtestmainpanel.cpp b/tests/skgbankguitest/skgtestmainpanel.cpp
index fbda8b0b9..393ad7996 100644
--- a/tests/skgbankguitest/skgtestmainpanel.cpp
+++ b/tests/skgbankguitest/skgtestmainpanel.cpp
@@ -1,138 +1,138 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is a test for SKGMainPanel component.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgtestmainpanel.h"
#include "skgboardwidget.h"
#include "skgdocumentbank.h"
#include "skgmainpanel.h"
#include "skgtestmacro.h"
#include "skgtraces.h"
void SKGTESTMainPanel::Test()
{
// Initialize document
SKGDocumentBank doc;
// Create main panel
SKGMainPanel mainpanel(nullptr, &doc);
QVERIFY2(!doc.load(SKGTest::getTestPath(QStringLiteral("IN")) % "/advice.skg"), "Load document failed");
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(doc, QStringLiteral("PROP"), err)
doc.setParameter(QStringLiteral("SKG_LAST_BUDGET_PROCESSING"), QLatin1String(""));
}
// Check plugins
{
SKGBEGINTRANSACTION(doc, QStringLiteral("PLUGINS"), err)
int i = 0;
SKGInterfacePlugin* plugin = nullptr;
do {
plugin = mainpanel.getPluginByIndex(i);
if (plugin != nullptr) {
SKGTRACE << i << ": " << plugin->title() << "(" << plugin->icon() << ")" << endl;
plugin->statusTip();
plugin->toolTip();
plugin->tips();
plugin->getOrder();
plugin->isInPagesChooser();
plugin->isEnabled();
SKGTabPage* tab = plugin->getWidget();
if (tab != nullptr) {
tab->printableWidgets();
tab->activateEditor();
tab->getBookmarkID();
tab->setState(tab->getState());
if (tab->isZoomable()) {
tab->zoomableWidget();
tab->setZoomPosition(5);
QCOMPARE(tab->zoomPosition(), 5);
}
}
int nbd = plugin->getNbDashboardWidgets();
for (int j = 0; j < nbd + 1; ++j) {
SKGTRACE << " Dashboard " << j << "/" << nbd + 1 << ": " << plugin->getDashboardWidgetTitle(j) << endl;
SKGBoardWidget* bw = plugin->getDashboardWidget(j);
if (bw != nullptr) {
bw->setState(bw->getState());
bw->getDefaultStateAttribute();
bw->getFirstSelectedObject();
}
}
plugin->getDockWidget();
plugin->getPreferenceWidget();
plugin->getPreferenceSkeleton();
plugin->savePreferences();
SKGAdviceList adviceList = plugin->advice(QStringList());
for (const auto& advice : qAsConst(adviceList)) {
SKGTRACE << " Advice: " << advice.getUUID() << endl;
for (int k = 0; k < 5; ++k) {
plugin->executeAdviceCorrection(advice.getUUID(), k);
}
}
}
++i;
} while (plugin != nullptr);
// Compute advices
SKGTRACE << "getAdvice" << endl;
mainpanel.getAdvice();
}
// Functions
SKGTRACE << "processArguments" << endl;
mainpanel.processArguments(QStringList());
mainpanel.openPage(QStringLiteral("skg://skrooge_operation_plugin"));
SKGTabPage* page = mainpanel.currentPage();
mainpanel.switchPinPage(page);
mainpanel.currentPageHistoryItem();
mainpanel.openPage(0, true);
mainpanel.openPage(0, false);
mainpanel.setCurrentPage(0);
mainpanel.getNbSelectedObjects();
mainpanel.countPages();
mainpanel.page(0);
mainpanel.currentPageIndex();
mainpanel.closeAllOtherPages(page);
mainpanel.closeAllPages(true);
mainpanel.splashScreen();
mainpanel.getTabWidget();
mainpanel.setContextVisibility(1, true);
mainpanel.setContextVisibility(1, false);
}
QTEST_MAIN(SKGTESTMainPanel)
diff --git a/tests/skgbankguitest/skgtestmainpanel.h b/tests/skgbankguitest/skgtestmainpanel.h
index 6e8257738..692d5d347 100644
--- a/tests/skgbankguitest/skgtestmainpanel.h
+++ b/tests/skgbankguitest/skgtestmainpanel.h
@@ -1,35 +1,35 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGTESTMAINPANEL_H
#define SKGTESTMAINPANEL_H
/** @file
* This file is a test for SKGMainPanel component.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include <qtest.h>
/**
* A unit test
*/
class SKGTESTMainPanel: public QObject
{
Q_OBJECT
private Q_SLOTS:
void Test();
};
#endif
diff --git a/tests/skgbankguitest/skgtestmodel.cpp b/tests/skgbankguitest/skgtestmodel.cpp
index 5e933f1cd..b694f35a7 100644
--- a/tests/skgbankguitest/skgtestmodel.cpp
+++ b/tests/skgbankguitest/skgtestmodel.cpp
@@ -1,157 +1,157 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is a test for SKGObjectModel component.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgtestmodel.h"
#include "modeltest.h"
#include "skgobjectmodel.h"
#include "skgsortfilterproxymodel.h"
#include "skgtestmacro.h"
void SKGTESTModel::Test()
{
int wait = 1;
// Initialize document
SKGDocumentBank doc;
QVERIFY2(!doc.load(SKGTest::getTestPath(QStringLiteral("IN")) % "/advice.skg"), "Load document failed");
\
QStringList tables;
doc.getDistinctValues(QStringLiteral("sqlite_master"), QStringLiteral("name"), QStringLiteral("type='view' AND name LIKE 'v_%_display' OR "
"name IN ('v_rule', 'v_account', 'v_recurrentoperation', 'v_operation_display_all', 'v_unit', 'v_operation_displayname', 'v_node')"), tables);
{
SKGError err;
SKGBEGINTRANSACTION(doc, QStringLiteral("DELETE"), err)
doc.executeSqliteOrder(QStringLiteral("DELETE FROM operation WHERE d_date<'") + SKGServices::dateToSqlString(QDate::currentDate().addMonths(-2)) + '\'');
}
for (const auto& table : qAsConst(tables)) {
SKGTRACE << QDateTime::currentDateTime().toString(QStringLiteral("yyyyMMdd-HHmmss-zzz")) << "..:: " << table << " ::.." << endl;
// Initilialization model
auto model = new SKGObjectModel(&doc,
table,
(table == QStringLiteral("v_account_display") || table == QStringLiteral("v_refund_display") ? QStringLiteral("t_close='N'") : QLatin1String("")),
nullptr,
(table == QStringLiteral("v_category_display") ? QStringLiteral("rd_category_id") : QLatin1String("")));
if (table == QStringLiteral("v_rule")) {
model->setGroupBy(QStringLiteral("t_action_type"));
}
if (table == QStringLiteral("v_account")) {
model->setGroupBy(QStringLiteral("t_close"));
}
if (table == QStringLiteral("v_recurrentoperation")) {
model->setGroupBy(QStringLiteral("i_nb_times"));
}
if (table == QStringLiteral("v_operation_display_all")) {
model->setGroupBy(QStringLiteral("t_status"));
}
if (table == QStringLiteral("v_operation")) {
model->setGroupBy(QStringLiteral("d_date"));
}
if (table == QStringLiteral("v_unit")) {
model->setGroupBy(QStringLiteral("t_TYPENLS"));
}
if (table == QStringLiteral("v_operation_displayname")) {
model->setGroupBy(QStringLiteral("p_myproperty"));
}
model->getGroupBy();
model->refresh();
model->supportedDragActions();
QTest::qWait(wait);
int nbCols = model->columnCount();
SKGTRACE << QDateTime::currentDateTime().toString(QStringLiteral("yyyyMMdd-HHmmss-zzz")) << " Nb rows=" << model->rowCount() << endl;
SKGTRACE << QDateTime::currentDateTime().toString(QStringLiteral("yyyyMMdd-HHmmss-zzz")) << " Nb Cols=" << nbCols << endl;
for (int i = 0; i < nbCols; ++i) {
SKGTRACE << " " << model->getAttribute(i) << endl;
}
// Set Data
if (table == QStringLiteral("v_account_display")) {
SKGTRACE << QDateTime::currentDateTime().toString(QStringLiteral("yyyyMMdd-HHmmss-zzz")) << " setData(t_close, Checked)" << endl;
model->setData(model->index(1, model->getIndexAttribute(QStringLiteral("t_close"))), QVariant(static_cast<unsigned int>(Qt::Checked)), Qt::CheckStateRole);
}
if (table == QStringLiteral("v_refund_display")) {
SKGTRACE << QDateTime::currentDateTime().toString(QStringLiteral("yyyyMMdd-HHmmss-zzz")) << " setData(t_close, Checked)" << endl;
model->setData(model->index(1, model->getIndexAttribute(QStringLiteral("t_close"))), QVariant(static_cast<unsigned int>(Qt::Checked)), Qt::CheckStateRole);
}
if (table == QStringLiteral("v_operation_display")) {
SKGTRACE << QDateTime::currentDateTime().toString(QStringLiteral("yyyyMMdd-HHmmss-zzz")) << " setData(t_status, Checked)" << endl;
model->setData(model->index(1, model->getIndexAttribute(QStringLiteral("t_status"))), QVariant(static_cast<unsigned int>(Qt::Checked)), Qt::CheckStateRole);
}
if (table == QStringLiteral("v_recurrentoperation_display")) {
SKGTRACE << QDateTime::currentDateTime().toString(QStringLiteral("yyyyMMdd-HHmmss-zzz")) << " setData(i_warn_days, Checked)" << endl;
model->setData(model->index(1, model->getIndexAttribute(QStringLiteral("i_warn_days"))), QVariant(static_cast<unsigned int>(Qt::Checked)), Qt::CheckStateRole);
SKGTRACE << QDateTime::currentDateTime().toString(QStringLiteral("yyyyMMdd-HHmmss-zzz")) << " setData(i_auto_write_days, Checked)" << endl;
model->setData(model->index(1, model->getIndexAttribute(QStringLiteral("i_auto_write_days"))), QVariant(static_cast<unsigned int>(Qt::Checked)), Qt::CheckStateRole);
SKGTRACE << QDateTime::currentDateTime().toString(QStringLiteral("yyyyMMdd-HHmmss-zzz")) << " setData(i_nb_times, Checked)" << endl;
model->setData(model->index(1, model->getIndexAttribute(QStringLiteral("i_nb_times"))), QVariant(static_cast<unsigned int>(Qt::Checked)), Qt::CheckStateRole);
}
if (table == QStringLiteral("v_budgetrule_display")) {
SKGTRACE << QDateTime::currentDateTime().toString(QStringLiteral("yyyyMMdd-HHmmss-zzz")) << " setData(i_year, Checked)" << endl;
model->setData(model->index(1, model->getIndexAttribute(QStringLiteral("i_year"))), QVariant(static_cast<unsigned int>(Qt::Checked)), Qt::CheckStateRole);
SKGTRACE << QDateTime::currentDateTime().toString(QStringLiteral("yyyyMMdd-HHmmss-zzz")) << " setData(i_month, Checked)" << endl;
model->setData(model->index(1, model->getIndexAttribute(QStringLiteral("i_month"))), QVariant(static_cast<unsigned int>(Qt::Checked)), Qt::CheckStateRole);
SKGTRACE << QDateTime::currentDateTime().toString(QStringLiteral("yyyyMMdd-HHmmss-zzz")) << " setData(t_CATEGORYCONDITION, Checked)" << endl;
model->setData(model->index(1, model->getIndexAttribute(QStringLiteral("t_CATEGORYCONDITION"))), QVariant(static_cast<unsigned int>(Qt::Checked)), Qt::CheckStateRole);
SKGTRACE << QDateTime::currentDateTime().toString(QStringLiteral("yyyyMMdd-HHmmss-zzz")) << " setData(t_CATEGORY, Checked)" << endl;
model->setData(model->index(1, model->getIndexAttribute(QStringLiteral("t_CATEGORY"))), QVariant(static_cast<unsigned int>(Qt::Checked)), Qt::CheckStateRole);
}
if (table == QStringLiteral("v_budget_display")) {
SKGTRACE << QDateTime::currentDateTime().toString(QStringLiteral("yyyyMMdd-HHmmss-zzz")) << " setData(t_CATEGORY, Checked)" << endl;
model->setData(model->index(1, model->getIndexAttribute(QStringLiteral("t_CATEGORY"))), QVariant(static_cast<unsigned int>(Qt::Checked)), Qt::CheckStateRole);
}
if (table == QStringLiteral("node")) {
SKGTRACE << QDateTime::currentDateTime().toString(QStringLiteral("yyyyMMdd-HHmmss-zzz")) << " setData(t_name, new name)" << endl;
model->setData(model->index(1, model->getIndexAttribute(QStringLiteral("t_name"))), QVariant("new name"), Qt::EditRole);
}
if (table == QStringLiteral("v_unit_display")) {
SKGTRACE << QDateTime::currentDateTime().toString(QStringLiteral("yyyyMMdd-HHmmss-zzz")) << " setData(t_name, new name)" << endl;
model->setData(model->index(1, model->getIndexAttribute(QStringLiteral("t_name"))), QVariant("new name"), Qt::EditRole);
}
if ((table == QStringLiteral("v_node") || table.endsWith(QLatin1String("_display"))) && (model->supportedDragActions()&Qt::MoveAction) != 0u && (model->supportedDropActions()&Qt::MoveAction) != 0u) {
SKGTRACE << QDateTime::currentDateTime().toString(QStringLiteral("yyyyMMdd-HHmmss-zzz")) << " Drag & Drop" << endl;
model->mimeTypes();
QMimeData* md = model->mimeData(QModelIndexList() << model->index(0, 0));
QCOMPARE(model->dropMimeData(md, Qt::MoveAction, 1, 0, model->index(1, 0)), true);
}
// test
SKGTRACE << QDateTime::currentDateTime().toString(QStringLiteral("yyyyMMdd-HHmmss-zzz")) << " new ModelTest" << endl;
auto modeltest = new ModelTest(model);
QTest::qWait(wait);
delete modeltest;
delete model;
SKGTRACE << QDateTime::currentDateTime().toString(QStringLiteral("yyyyMMdd-HHmmss-zzz")) << " end" << endl;
}
}
QTEST_MAIN(SKGTESTModel)
diff --git a/tests/skgbankguitest/skgtestmodel.h b/tests/skgbankguitest/skgtestmodel.h
index a3d7384c7..12ed79656 100644
--- a/tests/skgbankguitest/skgtestmodel.h
+++ b/tests/skgbankguitest/skgtestmodel.h
@@ -1,35 +1,35 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGTESTMODEL_H
#define SKGTESTMODEL_H
/** @file
* This file is a test for SKGObjectModel component.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include <qtest.h>
/**
* A unit test
*/
class SKGTESTModel: public QObject
{
Q_OBJECT
private Q_SLOTS:
void Test();
};
#endif
diff --git a/tests/skgbankguitest/skgtestpredicatcreator.cpp b/tests/skgbankguitest/skgtestpredicatcreator.cpp
index 7e4c8a100..6b57d04ba 100644
--- a/tests/skgbankguitest/skgtestpredicatcreator.cpp
+++ b/tests/skgbankguitest/skgtestpredicatcreator.cpp
@@ -1,100 +1,100 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is a test for SKGPredicatCreator component.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgtestpredicatcreator.h"
#include "skgdocumentbank.h"
#include "skgpredicatcreator.h"
#include "skgquerycreator.h"
void SKGTESTPredicatCreator::Test()
{
SKGDocumentBank doc;
QStringList attributeForQuery;
attributeForQuery << QStringLiteral("d_date") << QStringLiteral("t_number") << QStringLiteral("t_mode") << QStringLiteral("t_PAYEE") << QStringLiteral("p_prop") << QStringLiteral("t_status");
SKGPredicatCreator d_col_s(nullptr, &doc, QStringLiteral("d_date"), false, attributeForQuery);
d_col_s.setXmlDescription(d_col_s.xmlDescription());
d_col_s.text();
SKGPredicatCreator d_col_u(nullptr, &doc, QStringLiteral("d_date"), true, attributeForQuery);
d_col_u.setXmlDescription(d_col_u.xmlDescription());
d_col_u.text();
SKGPredicatCreator i_col_s(nullptr, &doc, QStringLiteral("t_number"), false, attributeForQuery);
i_col_s.setXmlDescription(i_col_s.xmlDescription());
i_col_s.text();
SKGPredicatCreator i_col_u(nullptr, &doc, QStringLiteral("t_number"), true, attributeForQuery);
i_col_u.setXmlDescription(i_col_u.xmlDescription());
i_col_u.text();
SKGPredicatCreator t_col_s(nullptr, &doc, QStringLiteral("t_mode"), false, attributeForQuery);
t_col_s.setXmlDescription(t_col_s.xmlDescription());
t_col_s.text();
SKGPredicatCreator t_col_u(nullptr, &doc, QStringLiteral("t_mode"), true, attributeForQuery);
t_col_u.setXmlDescription(t_col_s.xmlDescription());
t_col_u.text();
SKGPredicatCreator t2_col_s(nullptr, &doc, QStringLiteral("t_PAYEE"), false, attributeForQuery);
t2_col_s.setXmlDescription(t2_col_s.xmlDescription());
t2_col_s.text();
SKGPredicatCreator t2_col_u(nullptr, &doc, QStringLiteral("t_PAYEE"), true, attributeForQuery);
t2_col_u.setXmlDescription(t2_col_u.xmlDescription());
t2_col_u.text();
SKGPredicatCreator p_col_s(nullptr, &doc, QStringLiteral("p_prop"), false, attributeForQuery);
p_col_s.setXmlDescription(p_col_s.xmlDescription());
p_col_s.text();
SKGPredicatCreator p_col_u(nullptr, &doc, QStringLiteral("p_prop"), true, attributeForQuery);
p_col_u.setXmlDescription(p_col_u.xmlDescription());
p_col_u.text();
SKGPredicatCreator t3_col_s(nullptr, &doc, QStringLiteral("t_status"), false, attributeForQuery);
t3_col_s.setXmlDescription(t3_col_s.xmlDescription());
t3_col_s.text();
SKGPredicatCreator t3_col_u(nullptr, &doc, QStringLiteral("t_status"), true, attributeForQuery);
t3_col_u.setXmlDescription(t3_col_u.xmlDescription());
t3_col_u.text();
QString xml = QStringLiteral("<!DOCTYPE SKGML>"
"<element> <!--OR-->"
"<element> <!--AND-->"
"<element attribute=\"d_date\" operator=\"STRFTIME('%Y',#ATT#)=STRFTIME('%Y',date('now'))\" />"
"</element>"
"</element>");
SKGQueryCreator c1(nullptr);
c1.setParameters(&doc, QStringLiteral("v_suboperation_consolidated"), attributeForQuery, false);
c1.setXMLCondition(xml);
c1.clearContents();
SKGQueryCreator c2(nullptr);
c2.setParameters(&doc, QStringLiteral("v_suboperation_consolidated"), attributeForQuery, true);
c2.setXMLCondition(xml);
c1.getXMLCondition();
}
QTEST_MAIN(SKGTESTPredicatCreator)
diff --git a/tests/skgbankguitest/skgtestpredicatcreator.h b/tests/skgbankguitest/skgtestpredicatcreator.h
index a1560ad75..3452f6848 100644
--- a/tests/skgbankguitest/skgtestpredicatcreator.h
+++ b/tests/skgbankguitest/skgtestpredicatcreator.h
@@ -1,35 +1,35 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGTESTPREDICATCREATOR_H
#define SKGTESTPREDICATCREATOR_H
/** @file
* This file is a test for SKGPredicatCreator component.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include <qtest.h>
/**
* A unit test
*/
class SKGTESTPredicatCreator: public QObject
{
Q_OBJECT
private Q_SLOTS:
void Test();
};
#endif
diff --git a/tests/skgbankguitest/skgtesttreeview.cpp b/tests/skgbankguitest/skgtesttreeview.cpp
index 83e4d0396..b5a4b0ed1 100644
--- a/tests/skgbankguitest/skgtesttreeview.cpp
+++ b/tests/skgbankguitest/skgtesttreeview.cpp
@@ -1,92 +1,92 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is a test for SKGTreeView component.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgtesttreeview.h"
#include "skgfilteredtableview.h"
#include "skgobjectmodel.h"
#include "skgsortfilterproxymodel.h"
#include "skgtestmacro.h"
#include "skgtreeview.h"
void SKGTESTTreeView::Test()
{
// Initialize document
SKGDocumentBank doc;
QVERIFY2(!doc.load(SKGTest::getTestPath(QStringLiteral("OUT")) % "/advice.skg"), "Load document failed");
// Initilialization view and model
SKGFilteredTableView tableView(nullptr);
auto m_objectModel = new SKGObjectModel(&doc, QStringLiteral("v_account_display"), QLatin1String(""), nullptr);
tableView.setModel(m_objectModel);
m_objectModel->setTable(QStringLiteral("v_operation_display_all"));
QCOMPARE(m_objectModel->getGroupBy(), QLatin1String(""));
m_objectModel->setGroupBy(QStringLiteral("d_date"));
QCOMPARE(m_objectModel->getGroupBy(), QStringLiteral("d_date"));
m_objectModel->setGroupBy(QStringLiteral("t_status"));
m_objectModel->refresh();
QTest::qWait(300);
// SKGFilteredTableView
tableView.setState(tableView.getState());
QTest::qWait(2000);
// SKGTreeView
SKGTreeView* tree = tableView.getView();
tree->exportInFile(SKGTest::getTestPath(QStringLiteral("OUT")) % "/skgtesttreeview/SKGTreeView.csv");
tree->exportInFile(SKGTest::getTestPath(QStringLiteral("OUT")) % "/skgtesttreeview/SKGTreeView.txt");
tree->exportInFile(SKGTest::getTestPath(QStringLiteral("OUT")) % "/skgtesttreeview/SKGTreeView.svg");
tree->exportInFile(SKGTest::getTestPath(QStringLiteral("OUT")) % "/skgtesttreeview/SKGTreeView.pdf");
tree->exportInFile(SKGTest::getTestPath(QStringLiteral("OUT")) % "/skgtesttreeview/SKGTreeView.html");
tree->exportInFile(SKGTest::getTestPath(QStringLiteral("OUT")) % "/skgtesttreeview/SKGTreeView.odt");
tree->getTable();
tree->getFirstSelectedObject();
tree->setTextResizable(true);
QCOMPARE(tree->isTextResizable(), true);
tree->setTextResizable(false);
QCOMPARE(tree->isTextResizable(), false);
tree->setZoomPosition(5);
QCOMPARE(tree->zoomPosition(), 5);
tree->setZoomPosition(6);
QCOMPARE(tree->zoomPosition(), 6);
tree->switchAutoResize();
tree->setState(tree->getState());
tree->getCurrentSchema();
tableView.getSearchField()->setText(QStringLiteral("e +a -i"));
tree->copy();
for (int i = 0; i < 10; ++i) {
tree->sortByColumn(i, Qt::AscendingOrder);
QTest::qWait(1000);
tree->sortByColumn(i, Qt::DescendingOrder);
QTest::qWait(1000);
}
}
QTEST_MAIN(SKGTESTTreeView)
diff --git a/tests/skgbankguitest/skgtesttreeview.h b/tests/skgbankguitest/skgtesttreeview.h
index a6dd1a561..3a9f28807 100644
--- a/tests/skgbankguitest/skgtesttreeview.h
+++ b/tests/skgbankguitest/skgtesttreeview.h
@@ -1,35 +1,35 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGTESTTREEVIEW_H
#define SKGTESTTREEVIEW_H
/** @file
* This file is a test for SKGTreeView component.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include <qtest.h>
/**
* A unit test
*/
class SKGTESTTreeView: public QObject
{
Q_OBJECT
private Q_SLOTS:
void Test();
};
#endif
diff --git a/tests/skgbankmodelertest/CMakeLists.txt b/tests/skgbankmodelertest/CMakeLists.txt
index 6e2f3c696..65e2944c8 100644
--- a/tests/skgbankmodelertest/CMakeLists.txt
+++ b/tests/skgbankmodelertest/CMakeLists.txt
@@ -1,35 +1,35 @@
#***************************************************************************
#* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
#* *
#* 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 <http://www.gnu.org/licenses/> *
+#* along with this program. If not, see <https://www.gnu.org/licenses/> *
#***************************************************************************
MESSAGE( STATUS "..:: CMAKE SKGBANKMODELERTEST ::..")
PROJECT(SKGBANKMODELERTEST)
LINK_DIRECTORIES (${LIBRARY_OUTPUT_PATH})
INCLUDE_DIRECTORIES( ${CMAKE_SOURCE_DIR}/tests/skgbasemodelertest )
#Add test
ENABLE_TESTING()
FILE(GLOB cpp_files "skgtest*.cpp")
LIST(SORT cpp_files)
FOREACH(file ${cpp_files})
GET_FILENAME_COMPONENT(utname ${file} NAME_WE)
ADD_EXECUTABLE(${utname} ${file})
TARGET_LINK_LIBRARIES(${utname} Qt5::Core KF5::KIOWidgets skgbankmodeler skgbasemodeler)
ADD_TEST(NAME ${utname} COMMAND ${CMAKE_SOURCE_DIR}/tests/scripts/${utname}.sh)
ENDFOREACH()
INCLUDE(CTest)
diff --git a/tests/skgbankmodelertest/skgtestautoreconcile.cpp b/tests/skgbankmodelertest/skgtestautoreconcile.cpp
index d10414f35..91dbad0dc 100644
--- a/tests/skgbankmodelertest/skgtestautoreconcile.cpp
+++ b/tests/skgbankmodelertest/skgtestautoreconcile.cpp
@@ -1,138 +1,138 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is a test script.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgtestmacro.h"
#include "skgbankincludes.h"
#include "skgimportexportmanager.h"
/**
* The main function of the unit test
* @param argc the number of arguments
* @param argv the list of arguments
*/
int main(int argc, char** argv)
{
Q_UNUSED(argc)
Q_UNUSED(argv)
// Init test
SKGINITTEST(true)
{
// Test import bankperfect
SKGError err;
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true) {
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_BP_CSV"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportcsv/bankperfect.csv"));
SKGTESTERROR(QStringLiteral("imp1.importFile"), imp1.importFile(), true)
}
{
SKGBEGINTRANSACTION(document1, QStringLiteral("AUTORECONCILE"), err)
SKGAccountObject account1(&document1);
SKGTESTERROR(QStringLiteral("ACCOUNT.setName"), account1.setName(QStringLiteral("bankperfect")), true)
SKGTESTERROR(QStringLiteral("ACCOUNT.load"), account1.load(), true)
auto soluces = account1.getPossibleReconciliations(3547.14);
SKGTEST(QStringLiteral("ACCOUNT.getPossibleReconciliations"), soluces.count(), 1)
SKGTESTERROR(QStringLiteral("ACCOUNT.autoReconcile"), account1.autoReconcile(3547.14), true)
}
}
{
// Test import bankperfect
SKGError err;
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.load()"), document1.load(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestautoreconcile/complex.skg"), true) {
SKGBEGINTRANSACTION(document1, QStringLiteral("AUTORECONCILE"), err) {
SKGAccountObject account1(&document1);
SKGTESTERROR(QStringLiteral("ACCOUNT.setName"), account1.setName(QStringLiteral("EURO")), true)
SKGTESTERROR(QStringLiteral("ACCOUNT.load"), account1.load(), true)
auto soluces = account1.getPossibleReconciliations(3699.67);
SKGTEST(QStringLiteral("ACCOUNT.getPossibleReconciliations"), soluces.count(), 1)
SKGTESTERROR(QStringLiteral("ACCOUNT.autoReconcile"), account1.autoReconcile(3699.67), true)
soluces = account1.getPossibleReconciliations(3699.67);
SKGTEST(QStringLiteral("ACCOUNT.getPossibleReconciliations"), soluces.count(), 1)
SKGTESTERROR(QStringLiteral("ACCOUNT.autoReconcile"), account1.autoReconcile(3699.67), true)
}
{
SKGAccountObject account1(&document1);
SKGTESTERROR(QStringLiteral("ACCOUNT.setName"), account1.setName(QStringLiteral("DOLLAR")), true)
SKGTESTERROR(QStringLiteral("ACCOUNT.load"), account1.load(), true)
auto soluces = account1.getPossibleReconciliations(3699.67);
SKGTEST(QStringLiteral("ACCOUNT.getPossibleReconciliations"), soluces.count(), 1)
SKGTESTERROR(QStringLiteral("ACCOUNT.autoReconcile"), account1.autoReconcile(3699.67), true)
SKGTESTERROR(QStringLiteral("ACCOUNT.autoReconcile"), account1.autoReconcile(3699.67), true)
}
}
}
{
// Test many combinations
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestautoreconcile/many_combinations.csv"));
SKGTESTERROR(QStringLiteral("CSV.importFile"), imp1.importFile(), true)
document1.dump(DUMPOPERATION | DUMPACCOUNT);
}
{
SKGAccountObject account1(&document1);
SKGTESTERROR(QStringLiteral("ACCOUNT.setName"), account1.setName(QStringLiteral("many combinations")), true)
SKGTESTERROR(QStringLiteral("ACCOUNT.load"), account1.load(), true)
auto soluces = account1.getPossibleReconciliations(53, true);
SKGTEST(QStringLiteral("ACCOUNT.getPossibleReconciliations"), soluces.count(), 1)
SKGBEGINTRANSACTION(document1, QStringLiteral("CREATE OPERATIONS"), err)
double oBalance;
SKGUnitObject oUnit;
QDate now = QDate::currentDate();
account1.getInitialBalance(oBalance, oUnit);
int nb = 38;
for (int i = 1; i <= nb; ++i) {
SKGOperationObject op;
SKGTESTERROR(QStringLiteral("ACCOUNT:addOperation"), account1.addOperation(op), true)
SKGTESTERROR(QStringLiteral("OPE:setDate"), op.setDate(now), true)
SKGTESTERROR(QStringLiteral("OPE:setUnit"), op.setUnit(oUnit), true)
SKGTESTERROR(QStringLiteral("OPE:setImported"), op.setImported(true), true)
SKGTESTERROR(QStringLiteral("OPE:save"), op.save(), true)
SKGSubOperationObject subop;
SKGTESTERROR(QStringLiteral("OPE:addSubOperation"), op.addSubOperation(subop), true)
SKGTESTERROR(QStringLiteral("OPE:setQuantity"), subop.setQuantity(10), true)
SKGTESTERROR(QStringLiteral("SUBOPE:save"), subop.save(), true)
}
// Test performance
soluces = account1.getPossibleReconciliations(-23 + 10 * nb, true);
}
}
// End test
SKGENDTEST()
}
diff --git a/tests/skgbankmodelertest/skgtestbankandaccount.cpp b/tests/skgbankmodelertest/skgtestbankandaccount.cpp
index 351d871dd..41af8417b 100644
--- a/tests/skgbankmodelertest/skgtestbankandaccount.cpp
+++ b/tests/skgbankmodelertest/skgtestbankandaccount.cpp
@@ -1,249 +1,249 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is a test script.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgtestmacro.h"
#include "skgbankincludes.h"
/**
* The main function of the unit test
* @param argc the number of arguments
* @param argv the list of arguments
*/
int main(int argc, char** argv)
{
Q_UNUSED(argc)
Q_UNUSED(argv)
// Init test
SKGINITTEST(true)
// ============================================================================
// Init
{
// Test bank1 document
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("BANK_T1"), err)
// Creation unit
SKGUnitObject unit_euro(&document1);
SKGTESTERROR(QStringLiteral("BANK:setName"), unit_euro.setName(QStringLiteral("euro")), true)
SKGTESTERROR(QStringLiteral("BANK:setSymbol"), unit_euro.setSymbol(QStringLiteral("euro")), true)
SKGTESTERROR(QStringLiteral("BANK:save"), unit_euro.save(), true)
// Creation unitvalue
SKGUnitValueObject unit_euro_val1;
SKGTESTERROR(QStringLiteral("BANK:addUnitValue"), unit_euro.addUnitValue(unit_euro_val1), true)
SKGTESTERROR(QStringLiteral("BANK:setQuantity"), unit_euro_val1.setQuantity(1), true)
SKGTESTERROR(QStringLiteral("BANK:setDate"), unit_euro_val1.setDate(QDate::currentDate()), true)
SKGTESTERROR(QStringLiteral("BANK:save"), unit_euro_val1.save(), true)
// Creation bank1
SKGBankObject bank1(&document1);
SKGAccountObject account1;
SKGTESTERROR(QStringLiteral("BANK:addAccount"), bank1.addAccount(account1), false)
SKGTESTERROR(QStringLiteral("BANK:setName"), bank1.setName(QStringLiteral("CREDIT COOP")), true)
SKGTESTERROR(QStringLiteral("BANK:setIcon"), bank1.setIcon(QStringLiteral("credit cooperatif")), true)
SKGTESTERROR(QStringLiteral("BANK:setNumber"), bank1.setNumber(QStringLiteral("111111")), true)
SKGTESTERROR(QStringLiteral("BANK:save"), bank1.save(), true)
SKGTEST(QStringLiteral("BANK:getIcon"), bank1.getIcon(), QStringLiteral("credit cooperatif"))
SKGTEST(QStringLiteral("BANK:getNumber"), bank1.getNumber(), QStringLiteral("111111"))
SKGBankObject bank11(bank1); // For coverage
SKGTESTBOOL("BANK:comparison", (bank11 == bank1), true)
SKGBankObject bank12 = bank1; // For coverage
SKGTESTBOOL("BANK:comparison", (bank12 == bank1), true)
SKGBankObject bank13((SKGNamedObject(bank1))); // For coverage
SKGTESTBOOL("BANK:comparison", (bank12 == SKGNamedObject(bank1)), true)
SKGNamedObject bank1n(bank1);
SKGBankObject bank14(bank1n); // For coverage
SKGBankObject bank15(SKGObjectBase(bank1.getDocument(), QStringLiteral("xxx"), bank1.getID())); // For coverage
SKGBankObject bank16(SKGNamedObject(bank1.getDocument(), QStringLiteral("xxx"), bank1.getID())); // For coverage
// Creation account1
SKGTESTERROR(QStringLiteral("BANK:addAccount"), bank1.addAccount(account1), true)
SKGOperationObject op;
SKGTESTERROR(QStringLiteral("ACCOUNT:addOperation"), account1.addOperation(op), false)
SKGInterestObject it;
SKGTESTERROR(QStringLiteral("ACCOUNT:addOperation"), account1.addInterest(it), false)
SKGTESTERROR(QStringLiteral("ACCOUNT:setName"), account1.setName(QStringLiteral("Courant steph")), true)
SKGTESTERROR(QStringLiteral("ACCOUNT:setNumber"), account1.setNumber(QStringLiteral("12345P")), true)
SKGTESTERROR(QStringLiteral("ACCOUNT:setAgencyNumber"), account1.setAgencyNumber(QStringLiteral("99999")), true)
SKGTESTERROR(QStringLiteral("ACCOUNT:setAgencyAddress"), account1.setAgencyAddress(QStringLiteral("10 rue Albert CAMUS\n31000 TOULOUSE")), true)
SKGTESTERROR(QStringLiteral("ACCOUNT:setType"), account1.setType(SKGAccountObject::CURRENT), true)
SKGTESTERROR(QStringLiteral("ACCOUNT:setComment"), account1.setComment(QStringLiteral("bla bla")), true)
SKGTESTERROR(QStringLiteral("ACCOUNT:setMaxLimitAmount"), account1.setMaxLimitAmount(15000.0), true)
SKGTESTERROR(QStringLiteral("ACCOUNT:setMinLimitAmount"), account1.setMinLimitAmount(-500.0), true)
SKGTESTERROR(QStringLiteral("ACCOUNT:maxLimitAmountEnabled"), account1.maxLimitAmountEnabled(true), true)
SKGTESTERROR(QStringLiteral("ACCOUNT:minLimitAmountEnabled"), account1.minLimitAmountEnabled(false), true)
SKGTESTERROR(QStringLiteral("ACCOUNT:save"), account1.save(), true)
SKGTEST(QStringLiteral("ACCOUNT:getNumber"), account1.getNumber(), QStringLiteral("12345P"))
SKGTEST(QStringLiteral("ACCOUNT:getAgencyNumber"), account1.getAgencyNumber(), QStringLiteral("99999"))
SKGTEST(QStringLiteral("ACCOUNT:getAgencyAddress"), account1.getAgencyAddress(), QStringLiteral("10 rue Albert CAMUS\n31000 TOULOUSE"))
SKGTEST(QStringLiteral("ACCOUNT:getMaxLimitAmount"), account1.getMaxLimitAmount(), 15000.0)
SKGTEST(QStringLiteral("ACCOUNT:getMinLimitAmount"), account1.getMinLimitAmount(), -500.0)
SKGTESTERROR(QStringLiteral("ACCOUNT:setMaxLimitAmount"), account1.setMaxLimitAmount(-1000.0), true)
SKGTEST(QStringLiteral("ACCOUNT:getMaxLimitAmount"), account1.getMaxLimitAmount(), -1000.0)
SKGTEST(QStringLiteral("ACCOUNT:getMinLimitAmount"), account1.getMinLimitAmount(), -1000.0)
SKGTESTBOOL("ACCOUNT:isMaxLimitAmountEnabled", account1.isMaxLimitAmountEnabled(), true)
SKGTESTBOOL("ACCOUNT:isMinLimitAmountEnabled", account1.isMinLimitAmountEnabled(), false)
SKGTEST(QStringLiteral("ACCOUNT:getType"), static_cast<unsigned int>(account1.getType()), static_cast<unsigned int>(SKGAccountObject::CURRENT))
SKGTESTERROR(QStringLiteral("ACCOUNT:setType"), account1.setType(SKGAccountObject::CREDITCARD), true)
SKGTEST(QStringLiteral("ACCOUNT:getType"), static_cast<unsigned int>(account1.getType()), static_cast<unsigned int>(SKGAccountObject::CREDITCARD))
SKGTESTERROR(QStringLiteral("ACCOUNT:setType"), account1.setType(SKGAccountObject::ASSETS), true)
SKGTEST(QStringLiteral("ACCOUNT:getType"), static_cast<unsigned int>(account1.getType()), static_cast<unsigned int>(SKGAccountObject::ASSETS))
SKGTESTERROR(QStringLiteral("ACCOUNT:setType"), account1.setType(SKGAccountObject::INVESTMENT), true)
SKGTEST(QStringLiteral("ACCOUNT:getType"), static_cast<unsigned int>(account1.getType()), static_cast<unsigned int>(SKGAccountObject::INVESTMENT))
SKGTESTERROR(QStringLiteral("ACCOUNT:setType"), account1.setType(SKGAccountObject::WALLET), true)
SKGTEST(QStringLiteral("ACCOUNT:getType"), static_cast<unsigned int>(account1.getType()), static_cast<unsigned int>(SKGAccountObject::WALLET))
SKGTESTERROR(QStringLiteral("ACCOUNT:setType"), account1.setType(SKGAccountObject::LOAN), true)
SKGTEST(QStringLiteral("ACCOUNT:getType"), static_cast<unsigned int>(account1.getType()), static_cast<unsigned int>(SKGAccountObject::LOAN))
SKGTESTERROR(QStringLiteral("ACCOUNT:setType"), account1.setType(SKGAccountObject::SAVING), true)
SKGTEST(QStringLiteral("ACCOUNT:getType"), static_cast<unsigned int>(account1.getType()), static_cast<unsigned int>(SKGAccountObject::SAVING))
SKGTESTERROR(QStringLiteral("ACCOUNT:setType"), account1.setType(SKGAccountObject::OTHER), true)
SKGTEST(QStringLiteral("ACCOUNT:getType"), static_cast<unsigned int>(account1.getType()), static_cast<unsigned int>(SKGAccountObject::OTHER))
SKGTESTERROR(QStringLiteral("ACCOUNT:setType"), account1.setType(SKGAccountObject::PENSION), true)
SKGTEST(QStringLiteral("ACCOUNT:getType"), static_cast<unsigned int>(account1.getType()), static_cast<unsigned int>(SKGAccountObject::PENSION))
SKGTEST(QStringLiteral("ACCOUNT:getComment"), account1.getComment(), QStringLiteral("bla bla"))
QDate n = QDate::currentDate();
SKGTESTERROR(QStringLiteral("ACCOUNT:setReconciliationDate"), account1.setReconciliationDate(n), true)
SKGTEST(QStringLiteral("ACCOUNT:getReconciliationDate"), SKGServices::dateToSqlString(QDateTime(account1.getReconciliationDate())), SKGServices::dateToSqlString(QDateTime(n)))
SKGTESTERROR(QStringLiteral("ACCOUNT:setReconciliationBalance"), account1.setReconciliationBalance(125), true)
SKGTEST(QStringLiteral("ACCOUNT:getReconciliationBalance"), SKGServices::doubleToString(account1.getReconciliationBalance()), SKGServices::doubleToString(125))
SKGTESTERROR(QStringLiteral("ACCOUNT:setInitialBalance"), account1.setInitialBalance(125, unit_euro), true)
double init = 0;
SKGUnitObject unit;
SKGTESTERROR(QStringLiteral("ACCOUNT:getInitialBalance"), account1.getInitialBalance(init, unit), true)
SKGTESTBOOL("ACCOUNT:getInitialBalance", (unit == unit_euro), true)
SKGTEST(QStringLiteral("ACCOUNT:getInitialBalance"), init, 125)
SKGAccountObject account11(account1); // For coverage
SKGTESTBOOL("BANK:comparison", (account11 == account1), true)
SKGAccountObject account12(static_cast<SKGNamedObject>(account1)); // For coverage
SKGTESTBOOL("BANK:comparison", (account12 == account1), true)
SKGAccountObject account13(static_cast<SKGObjectBase>(account1)); // For coverage
SKGTESTBOOL("BANK:comparison", (account13 == account1), true)
SKGAccountObject account14(SKGObjectBase(account1.getDocument(), QStringLiteral("xxx"), account1.getID())); // For coverage
SKGAccountObject account15(SKGNamedObject(account1.getDocument(), QStringLiteral("xxx"), account1.getID())); // For coverage
// Creation bank2
SKGBankObject bank2(&document1);
SKGTESTERROR(QStringLiteral("BANK:setName"), bank2.setName(QStringLiteral("NEF")), true)
SKGTESTERROR(QStringLiteral("BANK:save"), bank2.save(), true)
// Creation account2
SKGAccountObject account2;
SKGTESTERROR(QStringLiteral("BANK:addAccount"), bank2.addAccount(account2), true)
SKGTESTERROR(QStringLiteral("ACCOUNT:setName"), account2.setName(QStringLiteral("Courant steph")), true)
SKGTESTERROR(QStringLiteral("ACCOUNT:setNumber"), account2.setNumber(QStringLiteral("98765A")), true)
SKGTESTERROR(QStringLiteral("ACCOUNT:save"), account2.save(false), false)
SKGAccountObject account3;
SKGTESTERROR(QStringLiteral("BANK:addAccount"), bank2.addAccount(account3), true)
SKGTESTERROR(QStringLiteral("ACCOUNT:setName"), account3.setName(QStringLiteral("Courant vero")), true)
SKGTESTERROR(QStringLiteral("ACCOUNT:setNumber"), account3.setNumber(QStringLiteral("98765A")), true)
SKGTESTERROR(QStringLiteral("ACCOUNT:save"), account3.save(), true)
QStringList oResult;
SKGTESTERROR(QStringLiteral("BANK:getDistinctValues"), document1.getDistinctValues(QStringLiteral("bank"), QStringLiteral("t_name"), oResult), true)
SKGTEST(QStringLiteral("BANK:oResult.size"), oResult.size(), 2)
SKGTESTERROR(QStringLiteral("BANK:getDistinctValues"), document1.getDistinctValues(QStringLiteral("account"), QStringLiteral("t_name"), oResult), true)
SKGTEST(QStringLiteral("BANK:oResult.size"), oResult.size(), 2)
SKGObjectBase::SKGListSKGObjectBase oAccountList;
SKGTESTERROR(QStringLiteral("BANK:getAccounts"), bank1.getAccounts(oAccountList), true)
SKGTEST(QStringLiteral("ACCOUNT:count"), oAccountList.count(), 1)
SKGTESTERROR(QStringLiteral("BANK:getAccounts"), bank2.getAccounts(oAccountList), true)
SKGTEST(QStringLiteral("ACCOUNT:count"), oAccountList.count(), 1)
// Modification account1
SKGBankObject tmpBank;
SKGTESTERROR(QStringLiteral("ACCOUNT:getBank"), account3.getBank(tmpBank), true)
SKGTESTBOOL("BANK:tmpBank==bank2", (tmpBank == bank2), true)
SKGTESTERROR(QStringLiteral("ACCOUNT:setBank"), account3.setBank(bank1), true)
SKGTESTERROR(QStringLiteral("ACCOUNT:getBank"), account3.getBank(tmpBank), true)
SKGTESTBOOL("BANK:tmpBank==bank2", (tmpBank == bank1), true)
SKGTESTERROR(QStringLiteral("ACCOUNT:save"), account3.save(), true)
SKGTESTERROR(QStringLiteral("BANK:getAccounts"), bank1.getAccounts(oAccountList), true)
SKGTEST(QStringLiteral("ACCOUNT:count"), oAccountList.count(), 2)
SKGTESTERROR(QStringLiteral("BANK:getAccounts"), bank2.getAccounts(oAccountList), true)
SKGTEST(QStringLiteral("ACCOUNT:count"), oAccountList.count(), 0)
SKGTESTBOOL("ACCOUNT:isBookmarked", account3.isBookmarked(), false)
SKGTESTERROR(QStringLiteral("ACCOUNT:bookmark"), account3.bookmark(true), true)
SKGTESTBOOL("ACCOUNT:isBookmarked", account3.isBookmarked(), true)
SKGTESTBOOL("ACCOUNT:isClosed", account3.isClosed(), false)
SKGTESTERROR(QStringLiteral("ACCOUNT:setClosed"), account3.setClosed(true), true)
SKGTESTBOOL("ACCOUNT:isClosed", account3.isClosed(), true)
SKGTESTERROR(QStringLiteral("ACCOUNT:save"), account3.save(), true)
// Merge
SKGTESTERROR(QStringLiteral("ACCOUNT:merge"), account2.merge(account3, true), true)
// interest
SKGObjectBase::SKGListSKGObjectBase oInterestList;
SKGTESTERROR(QStringLiteral("ACCOUNT:getInterests"), account2.getInterests(oInterestList), true)
SKGInterestObject oInterest;
SKGTESTERROR(QStringLiteral("ACCOUNT:getInterests"), account2.getInterest(QDate::currentDate(), oInterest), false)
SKGObjectBase account4(&document1, QStringLiteral("account"), account1.getID());
SKGTESTERROR(QStringLiteral("ACCOUNT:load"), account4.load(), true)
SKGTESTERROR(QStringLiteral("ACCOUNT:setAttribute"), account4.setAttribute(QStringLiteral("t_BANK"), QStringLiteral("bankname")), true)
SKGTESTERROR(QStringLiteral("ACCOUNT:save"), account4.save(), true)
SKGTESTERROR(QStringLiteral("BANK:load"), bank1.load(), true)
SKGTEST(QStringLiteral("BANK:getName"), bank1.getName(), QStringLiteral("bankname"))
SKGTESTERROR(QStringLiteral("DOC:dump"), document1.dump(DUMPACCOUNT), true)
}
}
// End test
SKGENDTEST()
}
diff --git a/tests/skgbankmodelertest/skgtestbankreport.cpp b/tests/skgbankmodelertest/skgtestbankreport.cpp
index 915500dab..efca599ab 100644
--- a/tests/skgbankmodelertest/skgtestbankreport.cpp
+++ b/tests/skgbankmodelertest/skgtestbankreport.cpp
@@ -1,85 +1,85 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is a test script.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include <qdesktopservices.h>
#include "skgbankincludes.h"
#include "skgreportbank.h"
#include "skgtestmacro.h"
/**
* The main function of the bank report test
* @param argc the number of arguments
* @param argv the list of arguments
*/
int main(int argc, char** argv)
{
Q_UNUSED(argc)
Q_UNUSED(argv)
// Init test
SKGINITTEST(true)
{
// Test unit et unitvalue
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.load()"), document1.load(SKGTest::getTestPath(QStringLiteral("IN")) % QStringLiteral("/advice.skg")), true)
auto* rep = qobject_cast<SKGReportBank*>(document1.getReport());
rep->setPeriod(QStringLiteral("2013"));
rep->get5MainCategoriesVariation();
rep->getAlarms();
rep->getInterests();
rep->getAccountTable();
rep->getBankTable();
rep->getBudgetTable();
rep->getIncomeVsExpenditure();
rep->getIncomeVsExpenditure();
rep->getMainCategoriesForPeriod();
rep->getMainCategoriesForPreviousPeriod();
rep->get5MainCategoriesVariationIssue();
rep->getPortfolio();
rep->getScheduledOperations();
rep->getUnitTable();
rep->getNetWorth();
rep->getAnnualSpending();
rep->getPersonalFinanceScore();
rep->getPrevious();
rep->getTipOfDay();
rep->getTipsOfDay();
rep->setTipsOfDay(QStringList() << QStringLiteral("Hello") << QStringLiteral("world"));
rep->getTipOfDay();
rep->getTipsOfDay();
rep->setPointSize(10);
SKGTEST(QStringLiteral("REP:getPointSize"), rep->getPointSize(), 10)
QString html;
SKGTESTERROR(QStringLiteral("SKGReportBank::getReportFromTemplate"), SKGReportBank::getReportFromTemplate(rep, SKGTest::getTestPath(QStringLiteral("IN")) % QStringLiteral("/template.txt"), html), true)
delete rep;
}
// End test
SKGENDTEST()
}
diff --git a/tests/skgbankmodelertest/skgtestbigdocument.cpp b/tests/skgbankmodelertest/skgtestbigdocument.cpp
index 896367a39..04d2b563d 100644
--- a/tests/skgbankmodelertest/skgtestbigdocument.cpp
+++ b/tests/skgbankmodelertest/skgtestbigdocument.cpp
@@ -1,203 +1,203 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is a test script.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include <qfile.h>
#include "skgbankincludes.h"
#include "skgtestmacro.h"
#include "skgtraces.h"
/**
* The main function of the unit test
* @param argc the number of arguments
* @param argv the list of arguments
*/
int main(int argc, char** argv)
{
Q_UNUSED(argc)
Q_UNUSED(argv)
// Init test
SKGINITTEST(true)
QDate now = QDate::currentDate();
// ============================================================================
// Init
QString filename = SKGTest::getTestPath(QStringLiteral("OUT")) % "/skgtestbigdocument/skgtestbigdocument.skg";
{
// Test bank document
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGUnitValueObject unit_euro_val1;
SKGBankObject bank(&document1);
SKGAccountObject account;
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("BANK_T1"), err)
// Creation bank
SKGTESTERROR(QStringLiteral("BANK:setName"), bank.setName(QStringLiteral("CREDIT COOP")), true)
SKGTESTERROR(QStringLiteral("BANK:save"), bank.save(), true)
// Creation account
SKGTESTERROR(QStringLiteral("BANK:addAccount"), bank.addAccount(account), true)
SKGTESTERROR(QStringLiteral("ACCOUNT:setName"), account.setName(QStringLiteral("Courant steph")), true)
SKGTESTERROR(QStringLiteral("ACCOUNT:setNumber"), account.setNumber(QStringLiteral("12345P")), true)
SKGTESTERROR(QStringLiteral("ACCOUNT:save"), account.save(), true)
// Creation unit
SKGUnitObject unit_euro(&document1);
SKGTESTERROR(QStringLiteral("UNIT:setName"), unit_euro.setName(QStringLiteral("euro")), true)
SKGTESTERROR(QStringLiteral("UNIT:save"), unit_euro.save(), true)
// Creation unitvalue
SKGTESTERROR(QStringLiteral("UNIT:addUnitValue"), unit_euro.addUnitValue(unit_euro_val1), true)
SKGTESTERROR(QStringLiteral("UNITVALUE:setQuantity"), unit_euro_val1.setQuantity(1), true)
SKGTESTERROR(QStringLiteral("UNITVALUE:setDate"), unit_euro_val1.setDate(now), true)
SKGTESTERROR(QStringLiteral("UNITVALUE:save"), unit_euro_val1.save(), true)
// Creation categories
auto cats = new SKGCategoryObject[30];
for (int i = 0; i < 10; ++i) {
cats[i] = SKGCategoryObject(&document1);
SKGTESTERROR(QStringLiteral("CAT:setName"), cats[i].setName("cat_" % SKGServices::intToString(i)), true)
SKGTESTERROR(QStringLiteral("CAT:save"), cats[i].save(), true)
for (int j = 0; j < 2; ++j) {
int indexSubCat = 10 * (j + 1) + i;
SKGTESTERROR(QStringLiteral("CAT:addCategory"), cats[i].addCategory(cats[indexSubCat]), true)
SKGTESTERROR(QStringLiteral("CAT:setName"), cats[indexSubCat].setName("cat_" % SKGServices::intToString(i) % '_' % SKGServices::intToString(j)), true)
SKGTESTERROR(QStringLiteral("CAT:save"), cats[indexSubCat].save(), true)
}
}
// Creation payees
auto payees = new SKGPayeeObject[10];
for (int i = 0; i < 10; ++i) {
payees[i] = SKGPayeeObject(&document1);
SKGTESTERROR(QStringLiteral("PAY:setName"), payees[i].setName("pay_" % SKGServices::intToString(i)), true)
SKGTESTERROR(QStringLiteral("PAY:save"), payees[i].save(), true)
}
// Mode
auto modes = new QString[5];
modes[0] = QStringLiteral("cheque");
modes[1] = QStringLiteral("carte");
modes[2] = QStringLiteral("tip");
modes[3] = QStringLiteral("virement");
modes[4] = QStringLiteral("espece");
// Comments
auto comments = new QString[3];
comments[0] = QStringLiteral("bla bla");
comments[1] = QStringLiteral("hello world");
comments[2] = QStringLiteral("youpi");
// Creation operation
SKGOperationObject mainOperation;
for (int i = 1; i <= 365 * 10; ++i) {
SKGOperationObject op_1;
SKGTESTERROR(QStringLiteral("ACCOUNT:addOperation"), account.addOperation(op_1), true)
SKGTESTERROR(QStringLiteral("OPE:setNumber"), op_1.setNumber(SKGServices::intToString(1000 + i)), true)
SKGTESTERROR(QStringLiteral("OPE:setMode"), op_1.setMode(modes[i % 5]), true)
SKGTESTERROR(QStringLiteral("OPE:setComment"), op_1.setComment(comments[i % 3]), true)
SKGTESTERROR(QStringLiteral("OPE:setDate"), op_1.setDate(now.addDays(-i)), true)
SKGTESTERROR(QStringLiteral("OPE:setUnit"), op_1.setUnit(unit_euro), true)
SKGTESTERROR(QStringLiteral("OPE:setStatus"), op_1.setStatus((i < 20 ? SKGOperationObject::NONE : (i < 40 ? SKGOperationObject::POINTED : SKGOperationObject::CHECKED))), true)
SKGTESTERROR(QStringLiteral("OPE:bookmark"), op_1.bookmark(i % 2 == 0), true)
SKGTESTERROR(QStringLiteral("OPE:save"), op_1.save(), true)
if (i == 1) {
mainOperation = op_1;
mainOperation.setGroupOperation(mainOperation);
SKGTESTERROR(QStringLiteral("OPE:save"), mainOperation.save(), true)
} else {
if (!op_1.isBookmarked()) {
op_1.setGroupOperation(mainOperation);
}
SKGTESTERROR(QStringLiteral("OPE:save"), op_1.save(), true)
}
// Creation suboperation
for (int j = 1; j <= 2; ++j) {
SKGSubOperationObject subop_1;
SKGTESTERROR(QStringLiteral("OPE:addSubOperation"), op_1.addSubOperation(subop_1), true)
SKGTESTERROR(QStringLiteral("SUBOPE:setCategory"), subop_1.setCategory(cats[i % 30]), true)
SKGTESTERROR(QStringLiteral("SUBOPE:setQuantity"), subop_1.setQuantity(((i * j) % 60) - 10), true)
SKGTESTERROR(QStringLiteral("SUBOPE:setOrder"), subop_1.setOrder(i), true)
SKGTEST(QStringLiteral("SUBOPE:getOrder"), subop_1.getOrder(), i)
SKGTESTERROR(QStringLiteral("SUBOPE:save"), subop_1.save(), true)
}
}
cats[0].merge(cats[1]);
payees[0].merge(payees[1]);
// Delete
delete [] cats;
delete [] modes;
delete [] comments;
delete [] payees;
} // A commit is done here because the scope is close
SKGTESTERROR(QStringLiteral("ACCOUNT:getCurrentAmount"), account.load(), true)
SKGTEST(QStringLiteral("ACCOUNT:getCurrentAmount"), account.getCurrentAmount(), 140165)
QFile(filename).remove();
SKGTESTERROR(QStringLiteral("DOC:saveAs"), document1.saveAs(filename), true)
}
// ============================================================================
{
SKGTraces::SKGPerfo = true;
SKGTRACEIN(0, "openTest")
// Test bank document
SKGDocumentBank document1;
{
SKGTRACEIN(0, "openTest-Load")
SKGTESTERROR(QStringLiteral("document1.load"), document1.load(SKGTest::getTestPath(QStringLiteral("OUT")) % "/skgtestbigdocument/skgtestbigdocument.skg"), true)
}
{
SKGTRACEIN(0, "openTest-Get")
SKGAccountObject account;
SKGTESTERROR(QStringLiteral("SKGAccountObject::getObjectByName"), SKGAccountObject::getObjectByName(&document1, QStringLiteral("v_account"), QStringLiteral("Courant steph"), account), true)
SKGTEST(QStringLiteral("ACCOUNT:getCurrentAmount"), account.getCurrentAmount(), 140165)
SKGAccountObject::SKGListSKGObjectBase objects;
SKGTESTERROR(QStringLiteral("SKGAccountObject::getObjects"), document1.getObjects(QStringLiteral("v_operation"), QLatin1String(""), objects), true)
int nbobj = 0;
SKGTESTERROR(QStringLiteral("SKGAccountObject::getNbObjects"), document1.getNbObjects(QStringLiteral("v_operation"), QLatin1String(""), nbobj), true)
}
{
SKGTRACEIN(0, "openTest-Save")
SKGTESTERROR(QStringLiteral("document1.save"), document1.save(), true)
}
}
// End test
SKGENDTEST()
}
diff --git a/tests/skgbankmodelertest/skgtestbudget.cpp b/tests/skgbankmodelertest/skgtestbudget.cpp
index 915ff8d61..6eb789f0a 100644
--- a/tests/skgbankmodelertest/skgtestbudget.cpp
+++ b/tests/skgbankmodelertest/skgtestbudget.cpp
@@ -1,159 +1,159 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is a test script.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgtestmacro.h"
#include "skgbankincludes.h"
#include "skgimportexportmanager.h"
/**
* The main function of the unit test
* @param argc the number of arguments
* @param argv the list of arguments
*/
int main(int argc, char** argv)
{
Q_UNUSED(argc)
Q_UNUSED(argv)
// Init test
SKGINITTEST(true)
// ============================================================================
{
// Import
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.load()"), document1.load(SKGTest::getTestPath(QStringLiteral("IN")) % "skgtestbudget/budget.skg"), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("BUDGET_CREATION"), err)
SKGTESTERROR(QStringLiteral("BUDGET.createAutomaticBudget"), SKGBudgetObject::createAutomaticBudget(&document1, 2010, 2010, true, true), true)
SKGTESTERROR(QStringLiteral("BUDGET.balanceBudget"), SKGBudgetObject::balanceBudget(&document1, 2010), true)
}
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("BUDGETRULE_CREATION"), err)
SKGBudgetRuleObject br(&document1);
SKGTESTERROR(QStringLiteral("BUDGETRULE.enableYearCondition"), br.enableYearCondition(true), true)
SKGTESTBOOL("BUDGETRULE.isYearConditionEnabled", br.isYearConditionEnabled(), true)
SKGTESTERROR(QStringLiteral("BUDGETRULE.enableYearCondition"), br.enableYearCondition(false), true)
SKGTESTBOOL("BUDGETRULE.isYearConditionEnabled", br.isYearConditionEnabled(), false)
SKGTESTERROR(QStringLiteral("BUDGETRULE.setBudgetYear"), br.setBudgetYear(2010), true)
SKGTEST(QStringLiteral("BUDGETRULE.getBudgetYear"), br.getBudgetYear(), 2010)
SKGTESTERROR(QStringLiteral("BUDGETRULE.enableMonthCondition"), br.enableMonthCondition(true), true)
SKGTESTBOOL("BUDGETRULE.isMonthConditionEnabled", br.isMonthConditionEnabled(), true)
SKGTESTERROR(QStringLiteral("BUDGETRULE.enableMonthCondition"), br.enableMonthCondition(false), true)
SKGTESTBOOL("BUDGETRULE.isMonthConditionEnabled", br.isMonthConditionEnabled(), false)
SKGTESTERROR(QStringLiteral("BUDGETRULE.setBudgetMonth"), br.setBudgetMonth(10), true)
SKGTEST(QStringLiteral("BUDGETRULE.getBudgetMonth"), br.getBudgetMonth(), 10)
SKGTESTERROR(QStringLiteral("BUDGETRULE.setOrder"), br.setOrder(1.0), true)
SKGTEST(QStringLiteral("BUDGETRULE.getOrder"), br.getOrder(), 1.0)
SKGTESTERROR(QStringLiteral("BUDGETRULE.setOrder"), br.setOrder(-1), true)
SKGTEST(QStringLiteral("BUDGETRULE.getOrder"), br.getOrder(), 1.0)
SKGTESTERROR(QStringLiteral("BUDGETRULE.enableCategoryCondition"), br.enableCategoryCondition(true), true)
SKGTESTBOOL("BUDGETRULE.isCategoryConditionEnabled", br.isCategoryConditionEnabled(), true)
SKGCategoryObject cat;
SKGTESTERROR(QStringLiteral("BUDGETRULE.enableCategoryChange"), br.enableCategoryChange(br.isCategoryChangeEnabled()), true)
SKGTESTERROR(QStringLiteral("BUDGETRULE.getBudgetCategory"), br.getBudgetCategory(cat), false)
SKGTESTERROR(QStringLiteral("BUDGETRULE.createPathCategory"), SKGCategoryObject::createPathCategory(&document1, QStringLiteral("category_55 > category_57"), cat), true)
SKGTESTERROR(QStringLiteral("BUDGETRULE.removeBudgetCategory"), br.removeBudgetCategory(), true)
SKGTESTERROR(QStringLiteral("BUDGETRULE.setBudgetCategory"), br.setBudgetCategory(cat), true)
SKGTESTERROR(QStringLiteral("BUDGETRULE.setCondition"), br.setCondition(SKGBudgetRuleObject::NEGATIVE), true)
SKGTEST(QStringLiteral("BUDGETRULE.getCondition"), static_cast<unsigned int>(br.getCondition()), static_cast<unsigned int>(SKGBudgetRuleObject::NEGATIVE))
SKGTESTERROR(QStringLiteral("BUDGETRULE.setCondition"), br.setCondition(SKGBudgetRuleObject::POSITIVE), true)
SKGTEST(QStringLiteral("BUDGETRULE.getCondition"), static_cast<unsigned int>(br.getCondition()), static_cast<unsigned int>(SKGBudgetRuleObject::POSITIVE))
SKGTESTERROR(QStringLiteral("BUDGETRULE.setCondition"), br.setCondition(SKGBudgetRuleObject::ALL), true)
SKGTEST(QStringLiteral("BUDGETRULE.getCondition"), static_cast<unsigned int>(br.getCondition()), static_cast<unsigned int>(SKGBudgetRuleObject::ALL))
SKGTESTERROR(QStringLiteral("BUDGETRULE.setQuantity"), br.setQuantity(100, false), true)
SKGTEST(QStringLiteral("BUDGETRULE.getQuantity"), br.getQuantity(), 100)
SKGTESTBOOL("BUDGETRULE.isAbolute", br.isAbolute(), false)
SKGTESTERROR(QStringLiteral("BUDGETRULE.setTransfer"), br.setTransfer(SKGBudgetRuleObject::CURRENT), true)
SKGTEST(QStringLiteral("BUDGETRULE.getTransferMode"), static_cast<unsigned int>(br.getTransferMode()), static_cast<unsigned int>(SKGBudgetRuleObject::CURRENT))
SKGTESTERROR(QStringLiteral("BUDGETRULE.setTransfer"), br.setTransfer(SKGBudgetRuleObject::NEXT), true)
SKGTEST(QStringLiteral("BUDGETRULE.getTransferMode"), static_cast<unsigned int>(br.getTransferMode()), static_cast<unsigned int>(SKGBudgetRuleObject::NEXT))
SKGTESTERROR(QStringLiteral("BUDGETRULE.save"), br.save(), true)
SKGBudgetRuleObject br2 = br;
SKGBudgetRuleObject br3(br);
SKGBudgetRuleObject br4(static_cast<SKGObjectBase>(br));
SKGBudgetRuleObject br5(SKGObjectBase(&document1, QStringLiteral("xxx"), br.getID()));
SKGTESTERROR(QStringLiteral("BUDGETRULE.processAllRules"), SKGBudgetRuleObject::processAllRules(&document1), true)
SKGTESTERROR(QStringLiteral("BUDGETRULE.setTransfer"), br.setTransfer(SKGBudgetRuleObject::YEAR), true)
SKGTEST(QStringLiteral("BUDGETRULE.getTransferMode"), static_cast<unsigned int>(br.getTransferMode()), static_cast<unsigned int>(SKGBudgetRuleObject::YEAR))
SKGTESTERROR(QStringLiteral("BUDGETRULE.save"), br.save(), true)
SKGTESTERROR(QStringLiteral("BUDGETRULE.processAllRules"), SKGBudgetRuleObject::processAllRules(&document1), true)
}
SKGTESTERROR(QStringLiteral("document1.saveAs()"), document1.saveAs(SKGTest::getTestPath(QStringLiteral("OUT")) % "skgtestbudget/budget.skg", true), true)
}
// ============================================================================
{
// Import
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.load()"), document1.load(SKGTest::getTestPath(QStringLiteral("IN")) % "skgtestbudget/320323.skg"), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("BUDGET_PROCESS"), err)
SKGTESTERROR(QStringLiteral("BUDGETRULE.processAllRules"), SKGBudgetRuleObject::processAllRules(&document1), true)
}
document1.dump(DUMPBUDGET);
bool check = false;
document1.existObjects(QStringLiteral("v_budget_display"), QStringLiteral("t_PERIOD='2013-02' AND t_CATEGORY='Alimentation' AND f_budgeted_modified=300"), check);
SKGTESTBOOL("BUDGETRULE.Alimentation 2013-02 300", check, true)
document1.existObjects(QStringLiteral("v_budget_display"), QStringLiteral("t_PERIOD='2013-02' AND t_CATEGORY='Loisirs' AND f_budgeted_modified=2100"), check);
SKGTESTBOOL("BUDGETRULE.Loisirs 2013-02 2100", check, true)
SKGObjectBase bo;
SKGTESTERROR(QStringLiteral("document1.getObject()"), document1.getObject(QStringLiteral("v_budget_display"), QStringLiteral("t_PERIOD='2013-02' AND t_CATEGORY='Loisirs' AND f_budgeted_modified=2100"), bo), true)
SKGBudgetObject b(bo);
SKGTEST(QStringLiteral("BUDGET.getBudgetedAmount"), b.getBudgetedAmount(), 300)
SKGCategoryObject cat;
SKGTESTERROR(QStringLiteral("BUDGET.getCategory"), b.getCategory(cat), true)
SKGTEST(QStringLiteral("BUDGET.getModificationReasons"), b.getModificationReasons(), QStringLiteral("Transfer of -1800 from ' 2013-01 2000.0' to 'Loisirs 2013-02 300.0' due to the rule 'All 100.0% Next Loisirs'"))
SKGTESTERROR(QStringLiteral("BUDGET.removeCategory"), b.removeCategory(), true)
SKGTESTERROR(QStringLiteral("BUDGET.enableSubCategoriesInclusion"), b.enableSubCategoriesInclusion(true), true)
SKGTESTBOOL(QStringLiteral("BUDGET.isSubCategoriesInclusionEnabled"), b.isSubCategoriesInclusionEnabled(), true)
SKGTESTERROR(QStringLiteral("BUDGET.enableSubCategoriesInclusion"), b.enableSubCategoriesInclusion(false), true)
SKGTESTBOOL(QStringLiteral("BUDGET.isSubCategoriesInclusionEnabled"), b.isSubCategoriesInclusionEnabled(), false)
SKGBudgetObject bu;
}
// End test
SKGENDTEST()
}
diff --git a/tests/skgbankmodelertest/skgtestcategory.cpp b/tests/skgbankmodelertest/skgtestcategory.cpp
index 0e72502c9..8a322b326 100644
--- a/tests/skgbankmodelertest/skgtestcategory.cpp
+++ b/tests/skgbankmodelertest/skgtestcategory.cpp
@@ -1,287 +1,287 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is a test script.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgtestmacro.h"
#include "skgbankincludes.h"
/**
* The main function of the unit test
* @param argc the number of arguments
* @param argv the list of arguments
*/
int main(int argc, char** argv)
{
Q_UNUSED(argc)
Q_UNUSED(argv)
// Init test
SKGINITTEST(true)
{
// Test category
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
SKGCategoryObject parent2;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("CAT_T1"), err)
// Create category 0
SKGCategoryObject cat0(&document1);
SKGTESTERROR(QStringLiteral("CAT:setName+invalid name"), cat0.setName('a' % OBJECTSEPARATOR % 'b'), false)
SKGTESTBOOL("CAT:exist", cat0.exist(), false)
SKGTESTERROR(QStringLiteral("CAT:save"), cat0.save(), false)
// Create category 1
SKGCategoryObject cat1(&document1);
SKGCategoryObject cat1_1;
SKGTESTERROR(QStringLiteral("CAT:addCategory"), cat1.addCategory(cat1_1), false)
SKGTESTERROR(QStringLiteral("CAT:setParentCategory"), cat1.setParentCategory(cat1_1), false)
SKGTESTERROR(QStringLiteral("CAT:setName"), cat1.setName(QStringLiteral("root1")), true)
SKGTESTBOOL("CAT:getFullName", cat1.isBookmarked(), false)
SKGTESTERROR(QStringLiteral("CAT:bookmark"), cat1.bookmark(true), true)
SKGTESTBOOL("CAT:getFullName", cat1.isBookmarked(), true)
SKGTESTERROR(QStringLiteral("CAT:save"), cat1.save(), true)
SKGTEST(QStringLiteral("CAT:getFullName"), cat1.getFullName(), QStringLiteral("root1"))
SKGTESTERROR(QStringLiteral("CAT:load"), cat1.load(), true)
SKGTEST(QStringLiteral("CAT:getFullName"), cat1.getFullName(), QStringLiteral("root1"))
SKGTESTBOOL("REF:isClosed", cat1.isClosed(), false)
SKGTESTERROR(QStringLiteral("REF:setClosed"), cat1.setClosed(true), true)
SKGTESTBOOL("REF:isClosed", cat1.isClosed(), true)
SKGObjectBase obj1 = static_cast<SKGObjectBase>(cat1);
SKGCategoryObject cat11(obj1);
// Update with bad name
SKGTESTERROR(QStringLiteral("CAT:setName"), cat1.setName("root1" % OBJECTSEPARATOR % 'A'), false)
SKGTESTERROR(QStringLiteral("CAT:load"), cat1.load(), true)
SKGTEST(QStringLiteral("CAT:getFullName"), cat1.getFullName(), QStringLiteral("root1"))
// Create category 1.1
SKGTESTERROR(QStringLiteral("CAT:addCategory"), cat1.addCategory(cat1_1), true)
SKGTESTERROR(QStringLiteral("CAT:setName"), cat1_1.setName(QStringLiteral("cat1")), true)
SKGTESTERROR(QStringLiteral("CAT:save"), cat1_1.save(), true)
SKGTEST(QStringLiteral("CAT:getFullName"), cat1_1.getFullName(), "root1" % OBJECTSEPARATOR % "cat1")
// Update cat1_1
SKGTESTERROR(QStringLiteral("CAT:setName"), cat1_1.setName(QStringLiteral("CAT1")), true)
SKGTESTERROR(QStringLiteral("CAT:save"), cat1_1.save(), true)
SKGTEST(QStringLiteral("CAT:getFullName"), cat1_1.getFullName(), "root1" % OBJECTSEPARATOR % "CAT1")
// Update cat1
SKGTESTERROR(QStringLiteral("CAT:setName"), cat1.setName(QStringLiteral("ROOT1")), true)
SKGTESTERROR(QStringLiteral("CAT:save"), cat1.save(), true)
SKGTEST(QStringLiteral("CAT:getFullName"), cat1.getFullName(), QStringLiteral("ROOT1"))
SKGTESTERROR(QStringLiteral("CAT:load"), cat1_1.load(), true)
SKGTEST(QStringLiteral("CAT:getFullName"), cat1_1.getFullName(), "ROOT1" % OBJECTSEPARATOR % "CAT1")
// Create category 1.2
SKGCategoryObject cat1_2;
SKGTESTERROR(QStringLiteral("CAT:addCategory"), cat1.addCategory(cat1_2), true)
SKGTESTERROR(QStringLiteral("CAT:setName"), cat1_2.setName(QStringLiteral("CAT2")), true)
SKGTESTERROR(QStringLiteral("CAT:save"), cat1_2.save(), true)
SKGTEST(QStringLiteral("CAT:getFullName"), cat1_2.getFullName(), "ROOT1" % OBJECTSEPARATOR % "CAT2")
// Create category end
SKGCategoryObject end1;
SKGTESTERROR(QStringLiteral("CAT:addCategory"), cat1_1.addCategory(end1), true)
SKGTESTERROR(QStringLiteral("CAT:setName"), end1.setName(QStringLiteral("END")), true)
SKGTESTERROR(QStringLiteral("CAT:save"), end1.save(), true)
SKGTEST(QStringLiteral("CAT:getFullName"), end1.getFullName(), "ROOT1" % OBJECTSEPARATOR % "CAT1" % OBJECTSEPARATOR % "END")
// Create category end
SKGCategoryObject end2;
SKGTESTERROR(QStringLiteral("CAT:addCategory"), cat1_2.addCategory(end2), true)
SKGTESTERROR(QStringLiteral("CAT:setName"), end2.setName(QStringLiteral("END")), true)
SKGTESTERROR(QStringLiteral("CAT:save"), end2.save(), true)
SKGTEST(QStringLiteral("CAT:getFullName"), end2.getFullName(), "ROOT1" % OBJECTSEPARATOR % "CAT2" % OBJECTSEPARATOR % "END")
SKGCategoryObject end2_1;
SKGTESTERROR(QStringLiteral("CAT:addCategory"), end2.addCategory(end2_1), true)
SKGTESTERROR(QStringLiteral("CAT:setName"), end2_1.setName(QStringLiteral("REALEND")), true)
SKGTESTERROR(QStringLiteral("CAT:save"), end2_1.save(), true)
SKGTEST(QStringLiteral("CAT:getFullName"), end2_1.getFullName(), "ROOT1" % OBJECTSEPARATOR % "CAT2" % OBJECTSEPARATOR % "END" % OBJECTSEPARATOR % "REALEND")
// Get parent
SKGCategoryObject parent1;
SKGTESTERROR(QStringLiteral("CAT:getParentCategory"), end2.getParentCategory(parent1), true)
SKGTEST(QStringLiteral("CAT:getFullName"), parent1.getFullName(), "ROOT1" % OBJECTSEPARATOR % "CAT2")
// Get parent
SKGTESTERROR(QStringLiteral("CAT:getParentCategory"), parent1.getParentCategory(parent2), true)
SKGTEST(QStringLiteral("CAT:getFullName"), parent2.getFullName(), QStringLiteral("ROOT1"))
SKGCategoryObject root;
SKGTESTERROR(QStringLiteral("CAT:getRootCategory"), end2_1.getRootCategory(root), true)
SKGTEST(QStringLiteral("CAT:getFullName"), root.getFullName(), QStringLiteral("ROOT1"))
// Get children
SKGObjectBase::SKGListSKGObjectBase CategoryList;
SKGTESTERROR(QStringLiteral("CAT:getCategories"), parent2.getCategories(CategoryList), true)
SKGTEST(QStringLiteral("CAT:nb categories"), CategoryList.size(), 2)
// Simple delete
SKGTESTERROR(QStringLiteral("CAT:delete"), end1.remove(), true)
QStringList oResult;
SKGTESTERROR(QStringLiteral("CAT:getDistinctValues"), document1.getDistinctValues(QStringLiteral("category"), QStringLiteral("id"), oResult), true)
SKGTEST(QStringLiteral("CAT:oResult.size"), oResult.size(), 5)
}
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("CAT_T2"), err)
// Cascading delete
SKGTESTERROR(QStringLiteral("CAT:delete"), parent2.remove(), true)
QStringList oResult;
SKGTESTERROR(QStringLiteral("CAT:getDistinctValues"), document1.getDistinctValues(QStringLiteral("category"), QStringLiteral("id"), oResult), true)
SKGTEST(QStringLiteral("CAT:oResult.size"), oResult.size(), 0)
}
// Undo
SKGTESTERROR(QStringLiteral("CAT:undoRedoTransaction"), document1.undoRedoTransaction(), true)
QStringList oResult;
SKGTESTERROR(QStringLiteral("CAT:getDistinctValues"), document1.getDistinctValues(QStringLiteral("category"), QStringLiteral("id"), oResult), true)
SKGTEST(QStringLiteral("CAT:oResult.size"), oResult.size(), 5)
SKGTESTERROR(QStringLiteral("CAT:undoRedoTransaction"), document1.undoRedoTransaction(), true)
SKGTESTERROR(QStringLiteral("CAT:getDistinctValues"), document1.getDistinctValues(QStringLiteral("category"), QStringLiteral("id"), oResult), true)
SKGTEST(QStringLiteral("CAT:oResult.size"), oResult.size(), 0)
// Redo
SKGTESTERROR(QStringLiteral("CAT:undoRedoTransaction(SKGDocument::REDO)"), document1.undoRedoTransaction(SKGDocument::REDO), true)
SKGTESTERROR(QStringLiteral("CAT:getDistinctValues"), document1.getDistinctValues(QStringLiteral("category"), QStringLiteral("id"), oResult), true)
SKGTEST(QStringLiteral("CAT:oResult.size"), oResult.size(), 5)
SKGTESTERROR(QStringLiteral("CAT:undoRedoTransaction(SKGDocument::REDO)"), document1.undoRedoTransaction(SKGDocument::REDO), true)
SKGTESTERROR(QStringLiteral("CAT:getDistinctValues"), document1.getDistinctValues(QStringLiteral("category"), QStringLiteral("id"), oResult), true)
SKGTEST(QStringLiteral("CAT:oResult.size"), oResult.size(), 0)
}
{
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("CAT_T1"), err)
SKGCategoryObject cat;
SKGTESTERROR(QStringLiteral("CAT:createPathCategory"), SKGCategoryObject::createPathCategory(&document1, QLatin1String(""), cat), true)
SKGTESTERROR(QStringLiteral("CAT:createPathCategory"), SKGCategoryObject::createPathCategory(&document1, 'A' % OBJECTSEPARATOR % 'A', cat, true), true)
SKGTEST(QStringLiteral("CAT:getName"), cat.getName(), QStringLiteral("A"))
QStringList oResult;
SKGTESTERROR(QStringLiteral("CAT:getDistinctValues"), document1.getDistinctValues(QStringLiteral("category"), QStringLiteral("id"), oResult), true)
SKGTEST(QStringLiteral("CAT:oResult.size"), oResult.size(), 2)
SKGTESTERROR(QStringLiteral("CAT:createPathCategory"), SKGCategoryObject::createPathCategory(&document1, 'A' % OBJECTSEPARATOR % 'B', cat, true, true), true)
SKGTEST(QStringLiteral("CAT:getName"), cat.getName(), QStringLiteral("B"))
SKGTESTERROR(QStringLiteral("CAT:createPathCategory"), SKGCategoryObject::createPathCategory(&document1, 'A' % OBJECTSEPARATOR % 'B', cat, true, true), true)
SKGTEST(QStringLiteral("CAT:getName"), cat.getName(), QStringLiteral("B (2)"))
SKGTESTERROR(QStringLiteral("CAT:createPathCategory"), SKGCategoryObject::createPathCategory(&document1, QStringLiteral("C"), cat, true, true), true)
SKGTEST(QStringLiteral("CAT:getName"), cat.getName(), QStringLiteral("C"))
SKGTESTERROR(QStringLiteral("CAT:createPathCategory"), SKGCategoryObject::createPathCategory(&document1, QStringLiteral("C"), cat, true, true), true)
SKGTEST(QStringLiteral("CAT:getName"), cat.getName(), QStringLiteral("C (2)"))
}
}
{
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("NODE_T1"), err)
SKGCategoryObject categoryB;
SKGTESTERROR(QStringLiteral("NOD:createPathCategory"), SKGCategoryObject::createPathCategory(&document1, 'A' % OBJECTSEPARATOR % 'B', categoryB), true)
SKGCategoryObject categoryC;
SKGTESTERROR(QStringLiteral("NOD:createPathCategory"), SKGCategoryObject::createPathCategory(&document1, QStringLiteral("C"), categoryC), true)
SKGCategoryObject categoryA;
SKGTESTERROR(QStringLiteral("NOD:getParentCategory"), categoryB.getParentCategory(categoryA), true)
SKGTESTERROR(QStringLiteral("NOD:setParentCategory"), categoryA.setParentCategory(categoryB), false)
SKGTESTERROR(QStringLiteral("NOD:setParentCategory"), categoryA.setParentCategory(categoryA), false)
SKGTESTERROR(QStringLiteral("NOD:setParentCategory"), categoryB.setParentCategory(categoryB), false)
SKGTESTERROR(QStringLiteral("NOD:setParentCategory"), categoryC.setParentCategory(categoryB), true)
SKGTESTERROR(QStringLiteral("NOD:removeParentCategory"), categoryB.removeParentCategory(), true)
}
}
// Bug 245254
{
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("NODE_T1"), err)
SKGCategoryObject categoryB;
SKGTESTERROR(QStringLiteral("NOD:createPathCategory"), SKGCategoryObject::createPathCategory(&document1, 'A' % OBJECTSEPARATOR % 'B', categoryB), true)
SKGCategoryObject categoryC;
SKGTESTERROR(QStringLiteral("NOD:createPathCategory"), SKGCategoryObject::createPathCategory(&document1, QStringLiteral("C"), categoryC), true)
SKGCategoryObject categoryA;
SKGTESTERROR(QStringLiteral("NOD:createPathCategory"), SKGCategoryObject::createPathCategory(&document1, 'C' % OBJECTSEPARATOR % 'A', categoryA), true)
QStringList oResult;
SKGTESTERROR(QStringLiteral("CAT:getDistinctValues"), document1.getDistinctValues(QStringLiteral("category"), QStringLiteral("id"), oResult), true)
SKGTEST(QStringLiteral("CAT:oResult.size"), oResult.size(), 4)
// Merge
SKGTESTERROR(QStringLiteral("CAT:merge"), categoryB.merge(categoryA), true)
}
}
// Cascading delete
{
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("NODE_T1"), err)
SKGCategoryObject categoryA;
SKGTESTERROR(QStringLiteral("NOD:createPathCategory"), SKGCategoryObject::createPathCategory(&document1, QStringLiteral("A"), categoryA), true)
SKGCategoryObject categoryC;
SKGTESTERROR(QStringLiteral("NOD:createPathCategory"), SKGCategoryObject::createPathCategory(&document1, 'A' % OBJECTSEPARATOR % 'B' % OBJECTSEPARATOR % 'C', categoryC), true)
QStringList oResult;
SKGTESTERROR(QStringLiteral("CAT:getDistinctValues"), document1.getDistinctValues(QStringLiteral("category"), QStringLiteral("id"), oResult), true)
SKGTEST(QStringLiteral("CAT:oResult.size"), oResult.size(), 3)
// Delete
SKGTESTERROR(QStringLiteral("CAT:remove"), categoryA.remove(), true)
SKGTESTERROR(QStringLiteral("CAT:getDistinctValues"), document1.getDistinctValues(QStringLiteral("category"), QStringLiteral("id"), oResult), true)
SKGTEST(QStringLiteral("CAT:oResult.size"), oResult.size(), 0)
}
}
// End test
SKGENDTEST()
}
diff --git a/tests/skgbankmodelertest/skgtestdocparameter.cpp b/tests/skgbankmodelertest/skgtestdocparameter.cpp
index c569a9980..e7a2729f5 100644
--- a/tests/skgbankmodelertest/skgtestdocparameter.cpp
+++ b/tests/skgbankmodelertest/skgtestdocparameter.cpp
@@ -1,126 +1,126 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is a test script.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgtestmacro.h"
#include "skgbankincludes.h"
/**
* The main function of the unit test
* @param argc the number of arguments
* @param argv the list of arguments
*/
int main(int argc, char** argv)
{
Q_UNUSED(argc)
Q_UNUSED(argv)
// Init test
SKGINITTEST(true)
// test class SKGDocument / PARAMETERS
{
SKGDocument document1;
SKGTESTERROR(QStringLiteral("PARAM:initialize"), document1.initialize(), true)
SKGTESTERROR(QStringLiteral("PARAM:beginTransaction"), document1.beginTransaction(QStringLiteral("t1")), true)
SKGTESTERROR(QStringLiteral("PARAM:setParameter"), document1.setParameter(QStringLiteral("ATT1"), QStringLiteral("VAL1")), true)
SKGTEST(QStringLiteral("PARAM:getParameter"), document1.getParameter(QStringLiteral("ATT1")), QStringLiteral("VAL1"))
SKGTESTERROR(QStringLiteral("PARAM:setParameter"), document1.setParameter(QStringLiteral("ATT1"), QStringLiteral("VAL1UPDATED")), true)
SKGTEST(QStringLiteral("PARAM:getParameter"), document1.getParameter(QStringLiteral("ATT1")), QStringLiteral("VAL1UPDATED"))
SKGTESTERROR(QStringLiteral("PARAM:setParameter"), document1.setParameter(QStringLiteral("ATT2"), QStringLiteral("VAL2")), true)
SKGTEST(QStringLiteral("PARAM:getParameter"), document1.getParameter(QStringLiteral("ATT1")), QStringLiteral("VAL1UPDATED"))
SKGTEST(QStringLiteral("PARAM:getParameter"), document1.getParameter(QStringLiteral("ATT2")), QStringLiteral("VAL2"))
SKGTEST(QStringLiteral("PARAM:getParameter"), document1.getParameter(QStringLiteral("NOTFOUND")), QLatin1String(""))
SKGTESTERROR(QStringLiteral("PARAM:setParameter+sql injection"), document1.setParameter(QStringLiteral("'"), QStringLiteral("VAL3")), true)
SKGTEST(QStringLiteral("PARAM:getParameter+sql injection"), document1.getParameter(QStringLiteral("'")), QStringLiteral("VAL3"))
SKGTESTERROR(QStringLiteral("PARAM:endTransaction"), document1.endTransaction(true), true)
}
// Test parameters on object
{
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("PROP:initialize"), document1.initialize(), true)
SKGTESTERROR(QStringLiteral("PROP:beginTransaction"), document1.beginTransaction(QStringLiteral("t1")), true)
SKGTESTERROR(QStringLiteral("PROP:setParameter"), document1.setParameter(QStringLiteral("ATT1"), QStringLiteral("VAL1")), true)
SKGObjectBase obj1(&document1, QStringLiteral("bank"));
SKGTESTERROR(QStringLiteral("PROP:setAttribute"), obj1.setAttribute(QStringLiteral("t_name"), QStringLiteral("CL")), true)
SKGTESTERROR(QStringLiteral("PROP:Replace"), obj1.save(), true)
SKGTESTERROR(QStringLiteral("PROP:setProperty"), obj1.setProperty(QStringLiteral("ATT1"), QStringLiteral("VAL2"), QVariant(145)), true)
// Check
SKGTEST(QStringLiteral("PROP:getParameter"), document1.getParameter(QStringLiteral("ATT1")), QStringLiteral("VAL1"))
SKGTEST(QStringLiteral("PROP:getProperty"), obj1.getProperty(QStringLiteral("ATT1")), QStringLiteral("VAL2"))
SKGTEST(QStringLiteral("PROP:getProperty"), obj1.getPropertyBlob(QStringLiteral("ATT1")).toInt(), 145)
QStringList oResult;
SKGTESTERROR(QStringLiteral("PROP:getDistinctValues"), document1.getDistinctValues(QStringLiteral("parameters"), QStringLiteral("t_value"), QStringLiteral("t_value like 'VAL%'"), oResult), true)
SKGTEST(QStringLiteral("PROP:oResult.size"), oResult.size(), 2)
// delete cascade
SKGTESTERROR(QStringLiteral("PROP:Replace"), obj1.remove(), true)
SKGTESTERROR(QStringLiteral("PROP:getDistinctValues"), document1.getDistinctValues(QStringLiteral("parameters"), QStringLiteral("t_value"), QStringLiteral("t_value like 'VAL%'"), oResult), true)
SKGTEST(QStringLiteral("PROP:oResult.size"), oResult.size(), 1)
SKGTESTERROR(QStringLiteral("PROP:setProperty"), obj1.setProperty(QStringLiteral("ATT4"), QStringLiteral("VAL4"), SKGTest::getTestPath(QStringLiteral("IN")) % "/dates.txt"), true)
SKGTESTERROR(QStringLiteral("PROP:setProperty"), obj1.setProperty(QStringLiteral("ATT5"), QStringLiteral("VAL5"), SKGTest::getTestPath(QStringLiteral("IN"))), true)
{
// Scope of the transaction
SKGError err;
SKGBEGINTRANSACTION(document1, QStringLiteral("T1"), err)
SKGPropertyObject propAdded1;
SKGTESTERROR(QStringLiteral("PROP.setProperty"), obj1.setProperty(QStringLiteral("normal"), QStringLiteral("value"), QVariant(), &propAdded1), true)
SKGTEST(QStringLiteral("PROP.getUrl"), propAdded1.getUrl().toDisplayString(), QLatin1String(""))
SKGPropertyObject propAdded2;
SKGTESTERROR(QStringLiteral("PROP.setProperty"), obj1.setProperty(QStringLiteral("url"), QStringLiteral("https://skrooge.org/"), QVariant(), &propAdded2), true)
SKGTEST(QStringLiteral("PROP.getUrl"), propAdded2.getUrl().toDisplayString(), QStringLiteral("https://skrooge.org/"))
SKGPropertyObject propAdded3;
SKGTESTERROR(QStringLiteral("PROP.setProperty"), obj1.setProperty(QStringLiteral("file copied"), SKGTest::getTestPath(QStringLiteral("IN")) % "dates.txt", QVariant(), &propAdded3), true)
SKGTEST(QStringLiteral("PROP.getUrl"), propAdded3.getUrl().toDisplayString(), "file://" % SKGTest::getTestPath(QStringLiteral("IN")) % "dates.txt")
SKGPropertyObject propAdded4;
SKGTESTERROR(QStringLiteral("PROP.setProperty"), obj1.setProperty(QStringLiteral("file moved"), QStringLiteral("test.txt"), QVariant("ABC"), &propAdded4), true)
SKGTESTBOOL("PROP.getUrl", propAdded4.getUrl().toDisplayString().startsWith(QLatin1String("file://")), true)
SKGTESTBOOL("PROP.getUrl", propAdded4.getUrl().toDisplayString().endsWith(QLatin1String("test.txt")), true)
SKGTESTBOOL("PROP.getUrl", propAdded4.getUrl(true).toDisplayString().startsWith(QLatin1String("file://")), true)
SKGTESTBOOL("PROP.getUrl", propAdded4.getUrl(true).toDisplayString().endsWith(QLatin1String("test.txt")), true)
}
}
{
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("DOC:initialize"), document1.initialize(), true)
QStringList listTables;
SKGTESTERROR(QStringLiteral("DOC::getTablesList"), document1.getTablesList(listTables), true)
for (const auto& table : qAsConst(listTables)) {
document1.getDisplaySchemas(table);
}
}
// End test
SKGENDTEST()
}
diff --git a/tests/skgbankmodelertest/skgtestimportafb120.cpp b/tests/skgbankmodelertest/skgtestimportafb120.cpp
index 2c7c123b6..a204f2947 100644
--- a/tests/skgbankmodelertest/skgtestimportafb120.cpp
+++ b/tests/skgbankmodelertest/skgtestimportafb120.cpp
@@ -1,106 +1,106 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is a test script.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgtestmacro.h"
#include "skgbankincludes.h"
#include "skgimportexportmanager.h"
/**
* The main function of the unit test
* @param argc the number of arguments
* @param argv the list of arguments
*/
int main(int argc, char** argv)
{
Q_UNUSED(argc)
Q_UNUSED(argv)
// Init test
SKGINITTEST(true)
{
// Test import AFB120
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
SKGTESTERROR(QStringLiteral("DOC:changePassword"), document1.changePassword(QStringLiteral("test")), true)
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_AFB120"), err)
SKGImportExportManager impmissing(&document1, QUrl::fromLocalFile(QStringLiteral("missingfile.cfo")));
SKGTESTERROR(QStringLiteral("AFB120.importFile"), impmissing.importFile(), false)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportafb120/gs_01139_021239S.cfo"));
SKGTESTERROR(QStringLiteral("AFB120.importFile"), imp1.importFile(), true)
document1.dump(DUMPOPERATION | DUMPACCOUNT);
}
{
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("AFB120.setName"), account.setName(QStringLiteral("0000021239S")), true)
SKGTESTERROR(QStringLiteral("AFB120.load"), account.load(), true)
SKGTEST(QStringLiteral("AFB120:getCurrentAmount"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("2555.48"))
}
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_AFB120"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportafb120/gs_01139_021239S.cfo"));
SKGTESTERROR(QStringLiteral("AFB120.importFile"), imp1.importFile(), true)
}
{
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("AFB120.setName"), account.setName(QStringLiteral("0000021239S")), true)
SKGTESTERROR(QStringLiteral("AFB120.load"), account.load(), true)
SKGTEST(QStringLiteral("AFB120:getCurrentAmount"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("2555.48"))
}
QString fano;
{
QString f = SKGTest::getTestPath(QStringLiteral("OUT")) % QStringLiteral("/skgtestimportafb120/anonymize.skg");
QFile(f).remove();
SKGImportExportManager imp1(&document1);
SKGTESTERROR(QStringLiteral("AFB120:anonymize"), imp1.anonymize(QLatin1String("")), false)
SKGTESTERROR(QStringLiteral("AFB120.saveAs"), document1.saveAs(f), true)
SKGTESTERROR(QStringLiteral("AFB120:anonymize"), imp1.anonymize(QLatin1String("")), true)
fano = document1.getCurrentFileName();
SKGTEST(QStringLiteral("AFB120:getCurrentFileName"), static_cast<unsigned int>(fano != f), static_cast<unsigned int>(true))
document1.close();
}
{
// Load anonymized file
SKGDocumentBank document2;
SKGTESTERROR(QStringLiteral("DOC:load"), document2.load(fano), true)
SKGImportExportManager imp1(&document2);
SKGTESTERROR(QStringLiteral("AFB120:anonymize"), imp1.anonymize(QStringLiteral("KEY")), true)
}
}
// End test
SKGENDTEST()
}
diff --git a/tests/skgbankmodelertest/skgtestimportcsv.cpp b/tests/skgbankmodelertest/skgtestimportcsv.cpp
index 2ad0fdf39..8d9405812 100644
--- a/tests/skgbankmodelertest/skgtestimportcsv.cpp
+++ b/tests/skgbankmodelertest/skgtestimportcsv.cpp
@@ -1,815 +1,815 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is a test script.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgtestmacro.h"
#include "skgbankincludes.h"
#include "skgimportexportmanager.h"
/**
* The main function of the unit test
* @param argc the number of arguments
* @param argv the list of arguments
*/
int main(int argc, char** argv)
{
Q_UNUSED(argc)
Q_UNUSED(argv)
// Init test
SKGINITTEST(true)
QDate now = QDate::currentDate();
{
// Test import SKGImportExportManager::CSV skrooge
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_CSV"), err)
SKGImportExportManager impmissing(&document1, QUrl::fromLocalFile(QStringLiteral("missingfile.csv")));
impmissing.setAutomaticApplyRules(true);
SKGTESTERROR(QStringLiteral("imp1.importFile"), impmissing.importFile(), false)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportcsv/skrooge_partial.csv"));
SKGImportExportManager::getImportMimeTypeFilter();
SKGImportExportManager::getExportMimeTypeFilter();
imp1.setCodec(QLatin1String(""));
SKGTESTERROR(QStringLiteral("imp1.importFile"), imp1.importFile(), true)
}
SKGAccountObject account;
SKGTESTERROR(QStringLiteral("ACCOUNT.getObjectByName"), SKGNamedObject::getObjectByName(&document1, QStringLiteral("v_account"), QStringLiteral("Courant steph"), account), true)
SKGTESTERROR(QStringLiteral("ACCOUNT.load"), account.load(), true)
SKGTEST(QStringLiteral("ACCOUNT:getCurrentAmount"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("-935"))
SKGTEST(QStringLiteral("document1:getCategoryForPayee"), document1.getCategoryForPayee(QStringLiteral("Anthony Hopkins"), false), QStringLiteral("Entertain > Movie"))
SKGTEST(QStringLiteral("document1:getCategoryForPayee"), document1.getCategoryForPayee(QStringLiteral("NOT FOUND")), QLatin1String(""))
}
{
// Test import QIF 1
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGBankObject bank(&document1);
SKGAccountObject account;
SKGUnitObject unit_euro(&document1);
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_INIT"), err)
// Creation bank
SKGTESTERROR(QStringLiteral("BANK:setName"), bank.setName(QStringLiteral("CREDIT COOP")), true)
SKGTESTERROR(QStringLiteral("BANK:save"), bank.save(), true)
// Creation account
SKGTESTERROR(QStringLiteral("BANK:addAccount"), bank.addAccount(account), true)
SKGTESTERROR(QStringLiteral("ACCOUNT:setName"), account.setName(QStringLiteral("Courant steph")), true)
SKGTESTERROR(QStringLiteral("ACCOUNT:setNumber"), account.setNumber(QStringLiteral("12345P")), true)
SKGTESTERROR(QStringLiteral("ACCOUNT:save"), account.save(), true)
// Creation unit
SKGTESTERROR(QStringLiteral("UNIT:setName"), unit_euro.setName(QStringLiteral("euro")), true)
SKGTESTERROR(QStringLiteral("UNIT:save"), unit_euro.save(), true)
// Creation unitvalue
SKGUnitValueObject unit_euro_val1;
SKGTESTERROR(QStringLiteral("UNIT:addUnitValue"), unit_euro.addUnitValue(unit_euro_val1), true)
SKGTESTERROR(QStringLiteral("UNITVALUE:setQuantity"), unit_euro_val1.setQuantity(1), true)
SKGTESTERROR(QStringLiteral("UNITVALUE:setDate"), unit_euro_val1.setDate(now), true)
SKGTESTERROR(QStringLiteral("UNITVALUE:save"), unit_euro_val1.save(), true)
}
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_CSV"), err)
// Date;Libelle;Libelle complementaire;Montant;Sens;Numero de cheque
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportcsv/coopanet.csv"));
QMap<QString, QString> parameters = imp1.getImportParameters();
parameters[QStringLiteral("automatic_search_header")] = 'N';
parameters[QStringLiteral("columns_positions")] = QStringLiteral("date|comment||amount|sign|number");
imp1.setImportParameters(parameters);
SKGTESTERROR(QStringLiteral("QIF.setDefaultAccount"), imp1.setDefaultAccount(&account), true)
SKGTESTERROR(QStringLiteral("imp1.importFile"), imp1.importFile(), true)
}
SKGTESTERROR(QStringLiteral("ACCOUNT.load"), account.load(), true)
SKGTEST(QStringLiteral("ACCOUNT:getCurrentAmount"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("-680.28"))
}
{
// Test import bankperfect
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGBankObject bank(&document1);
SKGAccountObject account1;
SKGAccountObject account2;
SKGUnitObject unit_euro(&document1);
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_INIT"), err)
// Creation bank
SKGTESTERROR(QStringLiteral("BANK:setName"), bank.setName(QStringLiteral("CREDIT COOP")), true)
SKGTESTERROR(QStringLiteral("BANK:save"), bank.save(), true)
// Creation account
SKGTESTERROR(QStringLiteral("BANK:addAccount"), bank.addAccount(account1), true)
SKGTESTERROR(QStringLiteral("ACCOUNT:setName"), account1.setName(QStringLiteral("Courant steph")), true)
SKGTESTERROR(QStringLiteral("ACCOUNT:setNumber"), account1.setNumber(QStringLiteral("12345P")), true)
SKGTESTERROR(QStringLiteral("ACCOUNT:save"), account1.save(), true)
SKGTESTERROR(QStringLiteral("BANK:addAccount"), bank.addAccount(account2), true)
SKGTESTERROR(QStringLiteral("ACCOUNT:setName"), account2.setName(QStringLiteral("PEL")), true)
SKGTESTERROR(QStringLiteral("ACCOUNT:save"), account2.save(), true)
// Creation unit
SKGTESTERROR(QStringLiteral("UNIT:setName"), unit_euro.setName(QStringLiteral("euro")), true)
SKGTESTERROR(QStringLiteral("UNIT:save"), unit_euro.save(), true)
// Creation unitvalue
SKGUnitValueObject unit_euro_val1;
SKGTESTERROR(QStringLiteral("UNIT:addUnitValue"), unit_euro.addUnitValue(unit_euro_val1), true)
SKGTESTERROR(QStringLiteral("UNITVALUE:setQuantity"), unit_euro_val1.setQuantity(1), true)
SKGTESTERROR(QStringLiteral("UNITVALUE:setDate"), unit_euro_val1.setDate(now), true)
SKGTESTERROR(QStringLiteral("UNITVALUE:save"), unit_euro_val1.save(), true)
}
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_BP_CSV"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportcsv/bankperfect.csv"));
SKGTESTERROR(QStringLiteral("QIF.setDefaultAccount"), imp1.setDefaultAccount(&account1), true)
SKGTESTERROR(QStringLiteral("imp1.importFile"), imp1.importFile(), true)
}
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_BP_CSV"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportcsv/bankperfect2.csv"));
SKGTESTERROR(QStringLiteral("QIF.setDefaultAccount"), imp1.setDefaultAccount(&account2), true)
SKGTESTERROR(QStringLiteral("imp1.importFile"), imp1.importFile(), true)
int NbOperationsMerged = 0;
SKGTESTERROR(QStringLiteral("imp1.findAndGroupTransfers"), imp1.findAndGroupTransfers(NbOperationsMerged), true)
SKGTEST(QStringLiteral("imp1:NbOperationsMerged"), NbOperationsMerged, 6)
}
SKGTESTERROR(QStringLiteral("ACCOUNT.load"), account1.load(), true)
SKGTEST(QStringLiteral("ACCOUNT:getCurrentAmount"), SKGServices::doubleToString(account1.getCurrentAmount()), QStringLiteral("2624.071111"))
SKGTESTERROR(QStringLiteral("ACCOUNT.load"), account2.load(), true)
SKGTEST(QStringLiteral("ACCOUNT:getCurrentAmount"), SKGServices::doubleToString(account2.getCurrentAmount()), QStringLiteral("1500"))
SKGImportExportManager exp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("OUT")) % "/skgtestimportcsv/bankperfect.csv"));
SKGTESTERROR(QStringLiteral("SKGImportExportManager::CSV.exportFile"), exp1.exportFile(), true)
{
SKGStringListList oTable;
SKGTESTERROR(QStringLiteral("SKGImportExportManager::CSV.exportFile"), document1.getConsolidatedView(QStringLiteral("v_operation_display"), QStringLiteral("d_DATEMONTH"), QStringLiteral("t_CATEGORY"), QStringLiteral("f_CURRENTAMOUNT"), QStringLiteral("SUM"), QLatin1String(""), oTable), true)
QStringList dump = SKGServices::tableToDump(oTable, SKGServices::DUMP_TEXT);
int nbl = dump.count();
for (int i = 0; i < nbl; ++i) {
SKGTRACE << dump.at(i) << endl;
}
}
{
SKGStringListList oTable;
SKGTESTERROR(QStringLiteral("SKGImportExportManager::CSV.exportFile"), document1.getConsolidatedView(QStringLiteral("v_operation_display"), QLatin1String(""), QStringLiteral("t_CATEGORY"), QStringLiteral("f_CURRENTAMOUNT"), QStringLiteral("SUM"), QLatin1String(""), oTable), true)
QStringList dump = SKGServices::tableToDump(oTable, SKGServices::DUMP_TEXT);
int nbl = dump.count();
for (int i = 0; i < nbl; ++i) {
SKGTRACE << dump.at(i) << endl;
}
}
{
SKGStringListList oTable;
SKGTESTERROR(QStringLiteral("SKGImportExportManager::CSV.exportFile"), document1.getConsolidatedView(QStringLiteral("v_operation_display"), QStringLiteral("d_DATEWEEK"), QLatin1String(""), QStringLiteral("f_CURRENTAMOUNT"), QStringLiteral("SUM"), QLatin1String(""), oTable), true)
SKGTESTERROR(QStringLiteral("SKGImportExportManager::CSV.exportFile"), document1.getConsolidatedView(QStringLiteral("v_operation_display"), QStringLiteral("d_DATEQUARTER"), QLatin1String(""), QStringLiteral("f_CURRENTAMOUNT"), QStringLiteral("SUM"), QLatin1String(""), oTable), true)
SKGTESTERROR(QStringLiteral("SKGImportExportManager::CSV.exportFile"), document1.getConsolidatedView(QStringLiteral("v_operation_display"), QStringLiteral("d_DATESEMESTER"), QLatin1String(""), QStringLiteral("f_CURRENTAMOUNT"), QStringLiteral("SUM"), QLatin1String(""), oTable), true)
SKGTESTERROR(QStringLiteral("SKGImportExportManager::CSV.exportFile"), document1.getConsolidatedView(QStringLiteral("v_operation_display"), QStringLiteral("d_DATEYEAR"), QLatin1String(""), QStringLiteral("f_CURRENTAMOUNT"), QStringLiteral("SUM"), QLatin1String(""), oTable), true)
SKGTESTERROR(QStringLiteral("SKGImportExportManager::CSV.exportFile"), document1.getConsolidatedView(QStringLiteral("v_operation_display"), QStringLiteral("d_date"), QLatin1String(""), QStringLiteral("f_CURRENTAMOUNT"), QStringLiteral("SUM"), QLatin1String(""), oTable), true)
SKGTESTERROR(QStringLiteral("SKGImportExportManager::CSV.exportFile"), document1.getConsolidatedView(QStringLiteral("v_operation_display"), QStringLiteral("d_DATEMONTH"), QLatin1String(""), QStringLiteral("f_CURRENTAMOUNT"), QStringLiteral("SUM"), QLatin1String(""), oTable), true)
QStringList dump = SKGServices::tableToDump(oTable, SKGServices::DUMP_TEXT);
int nbl = dump.count();
for (int i = 0; i < nbl; ++i) {
SKGTRACE << dump.at(i) << endl;
}
}
}
{
// Test import skrooge
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_SKROOGE_CSV"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("OUT")) % "/skgtestimportcsv/bankperfect.csv"));
SKGTESTERROR(QStringLiteral("imp1.importFile"), imp1.importFile(), true)
}
SKGImportExportManager exp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("OUT")) % "/skgtestimportcsv/bankperfect2.csv"));
SKGTESTERROR(QStringLiteral("SKGImportExportManager::CSV.exportFile"), exp1.exportFile(), true)
}
{
// Test import skrooge+optimization
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_OPTIM"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportcsv/bankperfect.csv"));
SKGTESTERROR(QStringLiteral("OPTIM.importFile"), imp1.importFile(), true)
}
SKGTESTERROR(QStringLiteral("OPTIM.undoRedoTransaction"), document1.undoRedoTransaction(SKGDocument::UNDOLASTSAVE), true)
}
{
// Test import skrooge in double to check merge
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportcsv/remi_1.csv"));
SKGTESTERROR(QStringLiteral("OPTIM.importFile"), imp1.importFile(), true)
}
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportcsv/remi_1.csv"));
SKGTESTERROR(QStringLiteral("OPTIM.importFile"), imp1.importFile(), true)
}
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("ACCOUNT.load"), account.setName(QStringLiteral("remi 1")), true)
SKGTESTERROR(QStringLiteral("ACCOUNT.load"), account.load(), true)
SKGTEST(QStringLiteral("ACCOUNT:getCurrentAmount"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("-767.26"))
}
{
// Test import 2638120
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportcsv/XXXXXXMxxxXXXXXXX.csv"));
SKGTESTERROR(QStringLiteral("CSV.importFile"), imp1.importFile(), true)
}
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("ACCOUNT.load"), account.setName(QStringLiteral("XXXXXXMxxxXXXXXXX")), true)
SKGTESTERROR(QStringLiteral("ACCOUNT.load"), account.load(), true)
SKGTEST(QStringLiteral("ACCOUNT:getCurrentAmount"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("8114.26"))
}
{
// Test import 206894
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportcsv/206894.csv"));
SKGTESTERROR(QStringLiteral("CSV.importFile"), imp1.importFile(), true)
}
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("ACCOUNT.load"), account.setName(QStringLiteral("206894")), true)
SKGTESTERROR(QStringLiteral("ACCOUNT.load"), account.load(), true)
SKGTEST(QStringLiteral("ACCOUNT:getCurrentAmount"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("-2986.39"))
}
{
// Test import 397055
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportcsv/397055.csv"));
SKGTESTERROR(QStringLiteral("CSV.importFile"), imp1.importFile(), true)
}
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("ACCOUNT.load"), account.setName(QStringLiteral("397055")), true)
SKGTESTERROR(QStringLiteral("ACCOUNT.load"), account.load(), true)
SKGTEST(QStringLiteral("ACCOUNT:getCurrentAmount"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("50"))
}
{
// Test import with tabulation
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportcsv/mutual fund.csv"));
SKGTESTERROR(QStringLiteral("CSV.importFile"), imp1.importFile(), true)
}
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("ACCOUNT.load"), account.setName(QStringLiteral("Janus Twenty Fund")), true)
SKGTESTERROR(QStringLiteral("ACCOUNT.load"), account.load(), true)
SKGTEST(QStringLiteral("ACCOUNT:getCurrentAmount"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("24.51428572"))
}
{
// Test import shares with original amount
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportcsv/209705.csv"));
SKGTESTERROR(QStringLiteral("CSV.importFile"), imp1.importFile(), true)
}
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportcsv/209705_2.csv"));
SKGTESTERROR(QStringLiteral("CSV.importFile"), imp1.importFile(), true)
}
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT"), err)
SKGImportExportManager imp1(&document1);
int out = 0;
SKGTESTERROR(QStringLiteral("CSV.findAndGroupTransfers"), imp1.findAndGroupTransfers(out), true)
SKGTEST(QStringLiteral("CSV:nb"), out, 2)
}
SKGObjectBase::SKGListSKGObjectBase grouped;
SKGTESTERROR(QStringLiteral("CSV.getObjects"), document1.getObjects(QStringLiteral("operation"), QStringLiteral("i_group_id!=0"), grouped), true)
SKGTEST(QStringLiteral("CSV:grouped.count"), grouped.count(), 2)
}
{
// Test import transactions split and grouped
SKGAccountObject la;
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportcsv/compte.csv"));
SKGTESTERROR(QStringLiteral("CSV.importFile"), imp1.importFile(), true)
SKGObjectBase::SKGListSKGObjectBase banks;
SKGTESTERROR(QStringLiteral("CSV.getObjects"), document1.getObjects(QStringLiteral("bank"), QLatin1String(""), banks), true)
SKGBankObject bank(banks.at(0));
bank.setName(QStringLiteral("bp"));
bank.save();
}
SKGObjectBase::SKGListSKGObjectBase grouped;
SKGTESTERROR(QStringLiteral("CSV.getObjects"), document1.getObjects(QStringLiteral("operation"), QLatin1String(""), grouped), true)
SKGTEST(QStringLiteral("CSV:grouped.count"), grouped.count(), 4)
SKGTESTERROR(QStringLiteral("CSV.getObjects"), document1.getObjects(QStringLiteral("operation"), QStringLiteral("i_group_id!=0"), grouped), true)
SKGTEST(QStringLiteral("CSV:grouped.count"), grouped.count(), 2)
SKGObjectBase::SKGListSKGObjectBase result;
SKGTESTERROR(QStringLiteral("DOC.getObjects"), document1.getObjects(QStringLiteral("account"), QStringLiteral("t_name='PEL'"), result), true)
SKGTEST(QStringLiteral("DOC.getObjects.count"), result.count(), 1)
if (result.count() != 0) {
la = result.at(0);
}
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("EXPORT_CSV"), err)
SKGImportExportManager exp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("OUT")) % "/skgtestimportcsv/export_all.csv"));
SKGTESTERROR(QStringLiteral("QIF.exportFile"), exp1.exportFile(), true)
}
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("EXPORT_CSV"), err)
SKGImportExportManager exp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("OUT")) % "/skgtestimportcsv/export_la.csv"));
QMap<QString, QString> params;
params[QStringLiteral("uuid_of_selected_accounts_or_operations")] = la.getUniqueID();
exp1.setExportParameters(params);
SKGTESTERROR(QStringLiteral("QIF.exportFile"), exp1.exportFile(), true)
}
}
{
// Test import mmex
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportcsv/mmex.csv"));
SKGTESTERROR(QStringLiteral("CSV.importFile"), imp1.importFile(), true)
}
int nb = 0;
SKGTESTERROR(QStringLiteral("CATEGORY.getNbObjects"), document1.getNbObjects(QStringLiteral("category"), QStringLiteral("t_fullname='Alimentation > Restaurant'"), nb), true)
SKGTEST(QStringLiteral("CATEGORY:nb"), nb, 1)
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("ACCOUNT.setName"), account.setName(QStringLiteral("mmex")), true)
SKGTESTERROR(QStringLiteral("ACCOUNT.load"), account.load(), true)
SKGTEST(QStringLiteral("ACCOUNT:getCurrentAmount"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("1418.44"))
}
{
// Test import mmex
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportcsv/mmex_no_header.csv"));
QMap<QString, QString> parameters = imp1.getImportParameters();
parameters[QStringLiteral("automatic_search_columns")] = 'N';
parameters[QStringLiteral("columns_positions")] = QStringLiteral("date|comment|sign|amount|category");
parameters[QStringLiteral("automatic_search_header")] = 'N';
parameters[QStringLiteral("header_position")] = '0';
imp1.setImportParameters(parameters);
SKGTESTERROR(QStringLiteral("CSV.importFile"), imp1.importFile(), true)
}
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("ACCOUNT.setName"), account.setName(QStringLiteral("mmex no header")), true)
SKGTESTERROR(QStringLiteral("ACCOUNT.load"), account.load(), true)
SKGTEST(QStringLiteral("ACCOUNT:getCurrentAmount"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("1418.44"))
}
{
// 263263
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportcsv/263263.csv"));
QMap<QString, QString> parameters = imp1.getImportParameters();
parameters[QStringLiteral("mapping_debit")] = QStringLiteral("kreditrente");
parameters[QStringLiteral("automatic_search_columns")] = 'N';
parameters[QStringLiteral("columns_positions")] = QStringLiteral("date||number|sign|comment|amount|amount");
parameters[QStringLiteral("automatic_search_header")] = 'N';
parameters[QStringLiteral("header_position")] = '1';
imp1.setImportParameters(parameters);
SKGTESTERROR(QStringLiteral("CSV.importFile"), imp1.importFile(), true)
}
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("ACCOUNT.setName"), account.setName(QStringLiteral("263263")), true)
SKGTESTERROR(QStringLiteral("ACCOUNT.load"), account.load(), true)
SKGTEST(QStringLiteral("ACCOUNT:getCurrentAmount"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("800.09"))
}
{
// CREDIT-DEBIT
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportcsv/credit-debit.csv"));
SKGTESTERROR(QStringLiteral("CSV.importFile"), imp1.importFile(), true)
}
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("ACCOUNT.setName"), account.setName(QStringLiteral("credit debit")), true)
SKGTESTERROR(QStringLiteral("ACCOUNT.load"), account.load(), true)
SKGTEST(QStringLiteral("ACCOUNT:getCurrentAmount"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("1500"))
}
{
// BACKSLASHES
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportcsv/backslashes.csv"));
SKGTESTERROR(QStringLiteral("CSV.importFile"), imp1.importFile(), true)
}
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("ACCOUNT.setName"), account.setName(QStringLiteral("backslashes")), true)
SKGTESTERROR(QStringLiteral("ACCOUNT.load"), account.load(), true)
SKGTEST(QStringLiteral("ACCOUNT:getCurrentAmount"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("1000"))
}
{
// MULTILINE
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportcsv/multiline.csv"));
SKGTESTERROR(QStringLiteral("CSV.importFile"), imp1.importFile(), true)
}
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("ACCOUNT.setName"), account.setName(QStringLiteral("multiline")), true)
SKGTESTERROR(QStringLiteral("ACCOUNT.load"), account.load(), true)
SKGTEST(QStringLiteral("ACCOUNT:getCurrentAmount"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("3000"))
}
{
// MULTILINE
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportcsv/non_numerical_amount.csv"));
SKGTESTERROR(QStringLiteral("CSV.importFile"), imp1.importFile(), true)
}
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("ACCOUNT.setName"), account.setName(QStringLiteral("non numerical amount")), true)
SKGTESTERROR(QStringLiteral("ACCOUNT.load"), account.load(), true)
SKGTEST(QStringLiteral("ACCOUNT:getCurrentAmount"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("-119.56"))
}
{
// Test import 320112
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportcsv/320112.csv"));
QMap<QString, QString> parameters = imp1.getImportParameters();
parameters[QStringLiteral("automatic_search_columns")] = 'N';
parameters[QStringLiteral("columns_positions")] = QStringLiteral("date|mode|payee|comment|amount");
imp1.setImportParameters(parameters);
SKGTESTERROR(QStringLiteral("CSV.importFile"), imp1.importFile(), true)
}
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("ACCOUNT.setName"), account.setName(QStringLiteral("320112")), true)
SKGTESTERROR(QStringLiteral("ACCOUNT.load"), account.load(), true)
SKGTEST(QStringLiteral("ACCOUNT:getCurrentAmount"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("6.13"))
}
{
// Test import date DDMMMYYYY
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportcsv/date_DDMMMYYYY.csv"));
SKGTESTERROR(QStringLiteral("CSV.importFile"), imp1.importFile(), true)
}
document1.dump(DUMPOPERATION | DUMPACCOUNT);
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("ACCOUNT.setName"), account.setName(QStringLiteral("date DDMMMYYYY")), true)
SKGTESTERROR(QStringLiteral("ACCOUNT.load"), account.load(), true)
SKGTEST(QStringLiteral("ACCOUNT:getAmount"), SKGServices::doubleToString(account.getAmount(QDate(2004, 12, 31))), QStringLiteral("35"))
}
{
// Test import separator tab
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportcsv/tabs.csv"));
SKGTESTERROR(QStringLiteral("CSV.importFile"), imp1.importFile(), true)
}
}
{
// Test import separator comma
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportcsv/commas.csv"));
SKGTESTERROR(QStringLiteral("CSV.importFile"), imp1.importFile(), true)
}
}
{
// BUG 406488
//
// "Date","Type","Number","Payee","Withdrawal (-)","Amount"
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportcsv/406488.csv"));
QMap<QString, QString> parameters = imp1.getImportParameters();
parameters[QStringLiteral("automatic_search_columns")] = 'N';
parameters[QStringLiteral("columns_positions")] = QStringLiteral("date|mode|number|payee|amount|amount");
imp1.setImportParameters(parameters);
SKGError err = imp1.importFile();
SKGTESTERROR(QStringLiteral("CSV.importFile"), err, false)
SKGTEST(QStringLiteral("CSV:error message"), err.getMessage(), QStringLiteral("Invalid number of columns in line 2. Expected 6. Found 1."))
}
}
{
// Test import separator comma
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportcsv/349961.csv"));
SKGTESTERROR(QStringLiteral("CSV.importFile"), imp1.importFile(), true)
}
int nb = 0;
SKGTESTERROR(QStringLiteral("CSV.getObjects"), document1.getNbObjects(QStringLiteral("operation"), QLatin1String(""), nb), true)
SKGTEST(QStringLiteral("CSV:nb operations"), nb, 1)
SKGTESTERROR(QStringLiteral("CSV.getObjects"), document1.getNbObjects(QStringLiteral("suboperation"), QStringLiteral("d_date='2015-07-07'"), nb), true)
SKGTEST(QStringLiteral("CSV:nb suboperations 2015-07-07"), nb, 1)
SKGTESTERROR(QStringLiteral("CSV.getObjects"), document1.getNbObjects(QStringLiteral("suboperation"), QStringLiteral("d_date='2015-07-08'"), nb), true)
SKGTEST(QStringLiteral("CSV:nb suboperations 2015-07-08"), nb, 1)
SKGTESTERROR(QStringLiteral("CSV.getObjects"), document1.getNbObjects(QStringLiteral("suboperation"), QStringLiteral("d_date='2015-07-09'"), nb), true)
SKGTEST(QStringLiteral("CSV:nb suboperations 2015-07-09"), nb, 1)
}
{
// Test import separator comma
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportcsv/362231.csv"));
SKGTESTERROR(QStringLiteral("CSV.importFile"), imp1.importFile(), true)
}
int nb = 0;
SKGTESTERROR(QStringLiteral("CSV.getObjects"), document1.getNbObjects(QStringLiteral("operation"), QStringLiteral("d_date!='0000-00-00'"), nb), true)
SKGTEST(QStringLiteral("CSV:nb operation"), nb, 1)
SKGTESTERROR(QStringLiteral("CSV.getObjects"), document1.getNbObjects(QStringLiteral("suboperation"), QStringLiteral("d_date='2016-05-15'"), nb), true)
SKGTEST(QStringLiteral("CSV:nb suboperations 2016-05-15"), nb, 1)
SKGTESTERROR(QStringLiteral("CSV.getObjects"), document1.getNbObjects(QStringLiteral("suboperation"), QStringLiteral("d_date='2016-05-20'"), nb), true)
SKGTEST(QStringLiteral("CSV:nb suboperations 2016-05-20"), nb, 1)
}
{
// 381562
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGBankObject bank(&document1);
SKGAccountObject account;
SKGUnitObject unit_euro(&document1);
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_INIT"), err)
// Creation bank
SKGTESTERROR(QStringLiteral("BANK:setName"), bank.setName(QStringLiteral("CREDIT COOP")), true)
SKGTESTERROR(QStringLiteral("BANK:save"), bank.save(), true)
// Creation account
SKGTESTERROR(QStringLiteral("BANK:addAccount"), bank.addAccount(account), true)
SKGTESTERROR(QStringLiteral("ACCOUNT:setName"), account.setName(QStringLiteral("Courant steph")), true)
SKGTESTERROR(QStringLiteral("ACCOUNT:setNumber"), account.setNumber(QStringLiteral("DE00 1234 5678 9012 3456 78")), true)
SKGTESTERROR(QStringLiteral("ACCOUNT:save"), account.save(), true)
// Creation unit
SKGTESTERROR(QStringLiteral("UNIT:setName"), unit_euro.setName(QStringLiteral("euro")), true)
SKGTESTERROR(QStringLiteral("UNIT:save"), unit_euro.save(), true)
// Creation unitvalue
SKGUnitValueObject unit_euro_val1;
SKGTESTERROR(QStringLiteral("UNIT:addUnitValue"), unit_euro.addUnitValue(unit_euro_val1), true)
SKGTESTERROR(QStringLiteral("UNITVALUE:setQuantity"), unit_euro_val1.setQuantity(1), true)
SKGTESTERROR(QStringLiteral("UNITVALUE:setDate"), unit_euro_val1.setDate(now), true)
SKGTESTERROR(QStringLiteral("UNITVALUE:save"), unit_euro_val1.save(), true)
}
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_CSV"), err)
// Date;Libelle;Libelle complementaire;Montant;Sens;Numero de cheque
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportcsv/DE00 1234 5678 9012 3456 78.csv"));
QMap<QString, QString> parameters = imp1.getImportParameters();
parameters[QStringLiteral("automatic_search_header")] = 'N';
parameters[QStringLiteral("columns_positions")] = QStringLiteral("date|comment||amount|sign|number");
imp1.setImportParameters(parameters);
SKGTESTERROR(QStringLiteral("imp1.importFile"), imp1.importFile(), true)
}
SKGTESTERROR(QStringLiteral("ACCOUNT.load"), account.load(), true)
SKGTEST(QStringLiteral("ACCOUNT:getCurrentAmount"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("-680.28"))
}
{
// Test 411958
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportcsv/411958.csv"));
QMap<QString, QString> parameters = imp1.getImportParameters();
parameters[QStringLiteral("mapping_date")] = QStringLiteral("^Buchungstag");
parameters[QStringLiteral("mapping_payee")] = QStringLiteral("^payee|^tiers|^.*Zahlungspflichtiger");
parameters[QStringLiteral("mapping_comment")] = QStringLiteral("^comment|^libell?|^d?tail|^info|^Vorgang.*");
parameters[QStringLiteral("mapping_amount")] = QStringLiteral("^value|^amount|^valeur|^montant|^credit|^debit|^Umsatz");
parameters[QStringLiteral("mapping_account")] = QStringLiteral("^Konto");
parameters[QStringLiteral("mapping_sign")] = QStringLiteral("^sign|^sens");
parameters[QStringLiteral("mapping_unit")] = QStringLiteral("^Währung");
parameters[QStringLiteral("mapping_debit")] = QStringLiteral("^S");
parameters[QStringLiteral("automatic_search_columns")] = 'Y';
parameters[QStringLiteral("automatic_search_header")] = 'Y';
imp1.setImportParameters(parameters);
SKGTESTERROR(QStringLiteral("CSV.importFile"), imp1.importFile(), true)
}
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("ACCOUNT.setName"), account.setName(QStringLiteral("411958")), true)
SKGTESTERROR(QStringLiteral("ACCOUNT.load"), account.load(), true)
SKGTEST(QStringLiteral("ACCOUNT:getCurrentAmount"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("658.88"))
}
{
// Test import with footer
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportcsv/footer.csv"));
QMap<QString, QString> parameters = imp1.getImportParameters();
parameters[QStringLiteral("automatic_search_columns")] = 'N';
parameters[QStringLiteral("columns_positions")] = QStringLiteral("date|mode|payee|amount|");
imp1.setImportParameters(parameters);
SKGTESTERROR(QStringLiteral("CSV.importFile"), imp1.importFile(), true)
}
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("ACCOUNT.load"), account.setName(QStringLiteral("footer")), true)
SKGTESTERROR(QStringLiteral("ACCOUNT.load"), account.load(), true)
SKGTEST(QStringLiteral("ACCOUNT:getCurrentAmount"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("-2"))
}
{
// Test import separator comma
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportcsv/commas_2.csv"));
QMap<QString, QString> parameters = imp1.getImportParameters();
parameters[QStringLiteral("automatic_search_columns")] = 'N';
parameters[QStringLiteral("header_position")] = QStringLiteral("1");
parameters[QStringLiteral("columns_positions")] = QStringLiteral("|date||payee|amount||||mode");
imp1.setImportParameters(parameters);
SKGTESTERROR(QStringLiteral("CSV.importFile"), imp1.importFile(), true)
}
}
// End test
SKGENDTEST()
} // NOLINT(readability/fn_size)
diff --git a/tests/skgbankmodelertest/skgtestimportcsvrule.cpp b/tests/skgbankmodelertest/skgtestimportcsvrule.cpp
index 254aaa597..949b3d3d2 100644
--- a/tests/skgbankmodelertest/skgtestimportcsvrule.cpp
+++ b/tests/skgbankmodelertest/skgtestimportcsvrule.cpp
@@ -1,67 +1,67 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is a test script.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgtestmacro.h"
#include "skgbankincludes.h"
#include "skgimportexportmanager.h"
/**
* The main function of the import rule test
* @param argc the number of arguments
* @param argv the list of arguments
*/
int main(int argc, char** argv)
{
Q_UNUSED(argc)
Q_UNUSED(argv)
// Init test
SKGINITTEST(true)
SKGError err;
{
// Test import SKGImportExportManager::CSV skrooge
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true) {
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT"), err) {
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportcsvrule/notfound.csv"));
QMap<QString, QString> parameters = imp1.getImportParameters();
parameters[QStringLiteral("mode_csv_rule")] = 'Y';
imp1.setImportParameters(parameters);
SKGTESTERROR(QStringLiteral("imp1.importFile"), imp1.importFile(), false) // FILE NOT FOUND
}
{
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportcsvrule/test1.csv"));
QMap<QString, QString> parameters = imp1.getImportParameters();
parameters[QStringLiteral("mode_csv_rule")] = 'Y';
imp1.setImportParameters(parameters);
SKGTESTERROR(QStringLiteral("imp1.importFile"), imp1.importFile(), true)
}
}
int nb = 0;
SKGTESTERROR(QStringLiteral("imp1.getNbObjects"), document1.getNbObjects(QStringLiteral("rule"), QLatin1String(""), nb), true)
SKGTEST(QStringLiteral("imp1.nb"), nb, 3)
}
// End test
SKGENDTEST()
}
diff --git a/tests/skgbankmodelertest/skgtestimportcsvunit.cpp b/tests/skgbankmodelertest/skgtestimportcsvunit.cpp
index 06bc8ac5d..e678ab657 100644
--- a/tests/skgbankmodelertest/skgtestimportcsvunit.cpp
+++ b/tests/skgbankmodelertest/skgtestimportcsvunit.cpp
@@ -1,101 +1,101 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is a test script.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgtestmacro.h"
#include "skgbankincludes.h"
#include "skgimportexportmanager.h"
/**
* The main function of the unit test
* @param argc the number of arguments
* @param argv the list of arguments
*/
int main(int argc, char** argv)
{
Q_UNUSED(argc)
Q_UNUSED(argv)
// Init test
SKGINITTEST(true)
SKGError err;
{
// Test import SKGImportExportManager::CSV skrooge
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true) {
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT"), err) {
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportcsvunit/notfound.csv"));
QMap<QString, QString> parameters = imp1.getImportParameters();
parameters[QStringLiteral("mode_csv_unit")] = 'Y';
imp1.setImportParameters(parameters);
SKGTESTERROR(QStringLiteral("imp1.importFile"), imp1.importFile(), false) // FILE NOT FOUND
}
{
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportcsvunit/test.csv"));
QMap<QString, QString> parameters = imp1.getImportParameters();
parameters[QStringLiteral("mode_csv_unit")] = 'Y';
imp1.setImportParameters(parameters);
SKGTESTERROR(QStringLiteral("imp1.importFile"), imp1.importFile(), true)
}
{
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportcsvunit/test2.csv"));
QMap<QString, QString> parameters = imp1.getImportParameters();
parameters[QStringLiteral("mode_csv_unit")] = 'Y';
imp1.setImportParameters(parameters);
SKGTESTERROR(QStringLiteral("imp1.importFile"), imp1.importFile(), true)
}
}
document1.dump(DUMPUNIT);
{
SKGUnitObject unit(&document1);
SKGTESTERROR(QStringLiteral("UNIT.setName"), unit.setName(QStringLiteral("test")), true)
SKGTESTERROR(QStringLiteral("UNIT.load"), unit.load(), true)
SKGUnitValueObject UnitValue;
SKGTESTERROR(QStringLiteral("UNIT.getLastUnitValue"), unit.getLastUnitValue(UnitValue), true)
SKGTEST(QStringLiteral("UNIT:getQuantity"), SKGServices::doubleToString(UnitValue.getQuantity()), QStringLiteral("50"))
}
{
SKGUnitObject unit(&document1);
SKGTESTERROR(QStringLiteral("UNIT.setName"), unit.setName(QStringLiteral("test2")), true)
SKGTESTERROR(QStringLiteral("UNIT.load"), unit.load(), true)
SKGUnitValueObject UnitValue;
SKGTESTERROR(QStringLiteral("UNIT.getLastUnitValue"), unit.getLastUnitValue(UnitValue), true)
SKGTEST(QStringLiteral("UNIT:getQuantity"), SKGServices::doubleToString(UnitValue.getQuantity()), QStringLiteral("25.16"))
}
}
{
// Test import SKGImportExportManager::CSV skrooge
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true) {
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT"), err) {
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportcsvunit/coma.csv"));
QMap<QString, QString> parameters = imp1.getImportParameters();
parameters[QStringLiteral("mode_csv_unit")] = 'Y';
imp1.setImportParameters(parameters);
SKGTESTERROR(QStringLiteral("imp1.importFile"), imp1.importFile(), true)
}
}
}
// End test
SKGENDTEST()
}
diff --git a/tests/skgbankmodelertest/skgtestimportgnucash.cpp b/tests/skgbankmodelertest/skgtestimportgnucash.cpp
index 91bcfd78a..cce5b6700 100644
--- a/tests/skgbankmodelertest/skgtestimportgnucash.cpp
+++ b/tests/skgbankmodelertest/skgtestimportgnucash.cpp
@@ -1,593 +1,593 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is a test script.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgtestmacro.h"
#include "skgbankincludes.h"
#include "skgimportexportmanager.h"
/**
* The main function of the unit test
* @param argc the number of arguments
* @param argv the list of arguments
*/
int main(int argc, char** argv)
{
Q_UNUSED(argc)
Q_UNUSED(argv)
// Init test
SKGINITTEST(true)
{
// Test import GNUCASH
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_GNUCASH"), err)
SKGImportExportManager impmissing(&document1, QUrl::fromLocalFile(QStringLiteral("/not-existing/missingfile.uncompressed")));
SKGTESTERROR(QStringLiteral("imp1.importFile"), impmissing.importFile(), false)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportgnucash/test_data.uncompressed"));
SKGTESTERROR(QStringLiteral("GNUCASH.importFile"), imp1.importFile(), true)
}
{
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("GNUCASH.setName"), account.setName(QStringLiteral("Accounts Receivable")), true)
SKGTESTERROR(QStringLiteral("GNUCASH.load"), account.load(), true)
SKGTEST(QStringLiteral("GNUCASH:getCurrentAmount"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("231.11"))
}
}
{
// Test import GNUCASH
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_GNUCASH"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportgnucash/all.uncompressed"));
SKGTESTERROR(QStringLiteral("GNUCASH.importFile"), imp1.importFile(), true)
}
{
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("GNUCASH.setName"), account.setName(QStringLiteral("COMPTE COURANT")), true)
SKGTESTERROR(QStringLiteral("GNUCASH.load"), account.load(), true)
SKGTEST(QStringLiteral("GNUCASH:getCurrentAmount"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("-700"))
}
{
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("GNUCASH.setName"), account.setName(QStringLiteral("COMPTE EPARGNE")), true)
SKGTESTERROR(QStringLiteral("GNUCASH.load"), account.load(), true)
SKGTEST(QStringLiteral("GNUCASH:getCurrentAmount"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("250"))
}
{
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("GNUCASH.setName"), account.setName(QStringLiteral("Actif")), true)
SKGTESTERROR(QStringLiteral("GNUCASH.load"), account.load(), true)
SKGTEST(QStringLiteral("GNUCASH:getCurrentAmount"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("-420"))
}
{
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("GNUCASH.setName"), account.setName(QStringLiteral("TITRE")), true)
SKGTESTERROR(QStringLiteral("GNUCASH.load"), account.load(), true)
SKGTEST(QStringLiteral("GNUCASH:getCurrentAmount"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("520"))
}
}
{
// Test import GNUCASH
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_GNUCASH"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportgnucash/initial_balance.uncompressed"));
SKGTESTERROR(QStringLiteral("GNUCASH.importFile"), imp1.importFile(), true)
}
{
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("GNUCASH.setName"), account.setName(QStringLiteral("CCP")), true)
SKGTESTERROR(QStringLiteral("GNUCASH.load"), account.load(), true)
SKGTEST(QStringLiteral("GNUCASH:getCurrentAmount"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("100"))
}
int nb = 0;
SKGTESTERROR(QStringLiteral("GNUCASH:getNbObjects(unit, PRIMARY)"), document1.getNbObjects(QStringLiteral("unit"), QStringLiteral("t_type='1'"), nb), true)
SKGTEST(QStringLiteral("GNUCASH:getNbObjects(unit, PRIMARY)"), nb, 1)
SKGTESTERROR(QStringLiteral("GNUCASH:getNbObjects(unit, SHARE)"), document1.getNbObjects(QStringLiteral("unit"), QStringLiteral("t_type='S'"), nb), true)
SKGTEST(QStringLiteral("GNUCASH:getNbObjects(unit, SHARE)"), nb, 13)
}
{
// Test import GNUCASH
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_GNUCASH"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportgnucash/transfer-CPP-vers-PEE.uncompressed"));
SKGTESTERROR(QStringLiteral("GNUCASH.importFile"), imp1.importFile(), true)
}
{
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("GNUCASH.setName"), account.setName(QStringLiteral("CCP")), true)
SKGTESTERROR(QStringLiteral("GNUCASH.load"), account.load(), true)
SKGTEST(QStringLiteral("GNUCASH:getCurrentAmount"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("750"))
}
{
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("GNUCASH.setName"), account.setName(QStringLiteral("CEL Donald")), true)
SKGTESTERROR(QStringLiteral("GNUCASH.load"), account.load(), true)
SKGTEST(QStringLiteral("GNUCASH:getCurrentAmount"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("150"))
}
{
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("GNUCASH.setName"), account.setName(QStringLiteral("PEEs")), true)
SKGTESTERROR(QStringLiteral("GNUCASH.load"), account.load(), true)
SKGTEST(QStringLiteral("GNUCASH:getCurrentAmount"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("190"))
}
{
int nb = 0;
SKGTESTERROR(QStringLiteral("GNUCASH:getNbObjects"), document1.getNbObjects(QStringLiteral("category"), QLatin1String(""), nb), true)
SKGTEST(QStringLiteral("GNUCASH:getNbObjects"), nb, 27)
}
}
{
// Test import GNUCASH
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_GNUCASH"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportgnucash/transfer-PEE-vers-CCP.uncompressed"));
SKGTESTERROR(QStringLiteral("GNUCASH.importFile"), imp1.importFile(), true)
}
{
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("GNUCASH.setName"), account.setName(QStringLiteral("CCP")), true)
SKGTESTERROR(QStringLiteral("GNUCASH.load"), account.load(), true)
SKGTEST(QStringLiteral("GNUCASH:getCurrentAmount"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("1140"))
}
{
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("GNUCASH.setName"), account.setName(QStringLiteral("CEL Donald")), true)
SKGTESTERROR(QStringLiteral("GNUCASH.load"), account.load(), true)
SKGTEST(QStringLiteral("GNUCASH:getCurrentAmount"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("150"))
}
{
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("GNUCASH.setName"), account.setName(QStringLiteral("PEEs")), true)
SKGTESTERROR(QStringLiteral("GNUCASH.load"), account.load(), true)
SKGTEST(QStringLiteral("GNUCASH:getCurrentAmount"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("100"))
}
{
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_GNUCASH"), err)
SKGCategoryObject cat;
SKGTESTERROR(QStringLiteral("GNUCASH.createPathCategory"), SKGCategoryObject::createPathCategory(&document1, QStringLiteral("Depenses > Frais bancaires"), cat), true)
SKGTEST(QStringLiteral("GNUCASH:getCurrentAmount"), SKGServices::doubleToString(cat.getCurrentAmount()), QStringLiteral("-10"))
}
SKGTESTERROR(QStringLiteral("DOC:dump"), document1.dump(DUMPCATEGORY), true)
}
{
// Test import GNUCASH
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_GNUCASH"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportgnucash/interet-revenue-frais.gnucash"));
SKGTESTERROR(QStringLiteral("GNUCASH.importFile"), imp1.importFile(), true)
}
{
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("GNUCASH.setName"), account.setName(QStringLiteral("CCP")), true)
SKGTESTERROR(QStringLiteral("GNUCASH.load"), account.load(), true)
SKGTEST(QStringLiteral("GNUCASH:getCurrentAmount"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("750"))
}
{
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("GNUCASH.setName"), account.setName(QStringLiteral("CEL Donald")), true)
SKGTESTERROR(QStringLiteral("GNUCASH.load"), account.load(), true)
SKGTEST(QStringLiteral("GNUCASH:getCurrentAmount"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("150"))
}
{
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("GNUCASH.setName"), account.setName(QStringLiteral("PEEs")), true)
SKGTESTERROR(QStringLiteral("GNUCASH.load"), account.load(), true)
SKGTEST(QStringLiteral("GNUCASH:getCurrentAmount"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("640"))
}
}
{
// Test import GNUCASH
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_GNUCASH"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportgnucash/interet-revenue-frais-emprunt.gnucash"));
SKGTESTERROR(QStringLiteral("GNUCASH.importFile"), imp1.importFile(), true)
}
{
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("GNUCASH.setName"), account.setName(QStringLiteral("CCP")), true)
SKGTESTERROR(QStringLiteral("GNUCASH.load"), account.load(), true)
SKGTEST(QStringLiteral("GNUCASH:getCurrentAmount"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("250"))
}
{
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("GNUCASH.setName"), account.setName(QStringLiteral("Emprunts")), true)
SKGTESTERROR(QStringLiteral("GNUCASH.load"), account.load(), true)
SKGTEST(QStringLiteral("GNUCASH:getCurrentAmount"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("-99620"))
}
{
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("GNUCASH.setName"), account.setName(QStringLiteral("Maison")), true)
SKGTESTERROR(QStringLiteral("GNUCASH.load"), account.load(), true)
SKGTEST(QStringLiteral("GNUCASH:getCurrentAmount"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("100000"))
}
}
{
// Test import GNUCASH
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_GNUCASH"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportgnucash/rapprochement-incorrect.uncompressed"));
SKGTESTERROR(QStringLiteral("GNUCASH.importFile"), imp1.importFile(), true)
}
{
int nb = 0;
SKGTESTERROR(QStringLiteral("GNUCASH:getNbObjects"), document1.getNbObjects(QStringLiteral("operation"), QStringLiteral("t_status='Y'"), nb), true)
SKGTEST(QStringLiteral("GNUCASH:getNbObjects"), nb, 7)
}
}
{
// Test import GNUCASH
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_GNUCASH"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportgnucash/scheduled-action.uncompressed"));
SKGTESTERROR(QStringLiteral("GNUCASH.importFile"), imp1.importFile(), true)
}
{
SKGObjectBase::SKGListSKGObjectBase recurrentoperations;
SKGTESTERROR(QStringLiteral("GNUCASH:SKGListSKGObjectBase"), document1.getObjects(QStringLiteral("recurrentoperation"), QLatin1String(""), recurrentoperations), true)
SKGTEST(QStringLiteral("GNUCASH:nb"), recurrentoperations.count(), 1)
if (recurrentoperations.count() == 1) {
SKGRecurrentOperationObject recu(recurrentoperations.at(0));
SKGTEST(QStringLiteral("GNUCASH:getDate"), recu.getDate().toString(), QDate(2010, 03, 02).toString())
SKGTEST(QStringLiteral("GNUCASH:getAutoWriteDays"), recu.getAutoWriteDays(), 10)
SKGTEST(QStringLiteral("GNUCASH:getPeriodIncrement"), recu.getPeriodIncrement(), 1)
SKGTEST(QStringLiteral("GNUCASH:getPeriodUnit"), static_cast<unsigned int>(recu.getPeriodUnit()), static_cast<unsigned int>(SKGRecurrentOperationObject::MONTH))
SKGTEST(QStringLiteral("GNUCASH:getWarnDays"), recu.getWarnDays(), 0)
SKGTESTBOOL("GNUCASH:isAutoWriteEnabled", recu.isAutoWriteEnabled(), false)
SKGTESTBOOL("GNUCASH:isWarnEnabled", recu.isWarnEnabled(), false)
SKGTESTBOOL("GNUCASH:hasTimeLimit", recu.hasTimeLimit(), false)
}
}
}
{
// Test import GNUCASH - bug 228808
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_GNUCASH"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportgnucash/228808.gnc"));
SKGTESTERROR(QStringLiteral("GNUCASH.importFile"), imp1.importFile(), true)
}
{
SKGObjectBase::SKGListSKGObjectBase recurrentoperations;
SKGTESTERROR(QStringLiteral("GNUCASH:SKGListSKGObjectBase"), document1.getObjects(QStringLiteral("recurrentoperation"), QStringLiteral("1=1 ORDER BY d_date"), recurrentoperations), true)
SKGTEST(QStringLiteral("GNUCASH:nb"), recurrentoperations.count(), 2)
if (recurrentoperations.count() == 2) {
SKGRecurrentOperationObject recu(recurrentoperations.at(0));
SKGOperationObject op;
SKGTESTERROR(QStringLiteral("GNUCASH:getParentOperation"), recu.getParentOperation(op), true)
SKGTEST(QStringLiteral("GNUCASH:getCurrentAmount"), op.getCurrentAmount(), -50)
recu = recurrentoperations.at(1);
SKGTESTERROR(QStringLiteral("GNUCASH:getParentOperation"), recu.getParentOperation(op), true)
SKGTEST(QStringLiteral("GNUCASH:getCurrentAmount"), op.getCurrentAmount(), -18.75)
}
}
}
{
// Test import GNUCASH - bug 228904
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_GNUCASH"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportgnucash/228904.gnucash"));
SKGTESTERROR(QStringLiteral("GNUCASH.importFile"), imp1.importFile(), true)
}
{
SKGObjectBase::SKGListSKGObjectBase recurrentoperations;
SKGTESTERROR(QStringLiteral("GNUCASH:SKGListSKGObjectBase"), document1.getObjects(QStringLiteral("recurrentoperation"), QStringLiteral("1=1 ORDER BY d_date"), recurrentoperations), true)
SKGTEST(QStringLiteral("GNUCASH:nb"), recurrentoperations.count(), 3)
}
}
{
// Test import 228901
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_GNUCASH"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportgnucash/228901.gnucash"));
SKGTESTERROR(QStringLiteral("GNUCASH.importFile"), imp1.importFile(), true)
}
{
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("GNUCASH.setName"), account.setName(QStringLiteral("Compte emprunt")), true)
SKGTESTERROR(QStringLiteral("GNUCASH.load"), account.load(), true)
SKGTEST(QStringLiteral("GNUCASH:getCurrentAmount"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("-9476.01"))
}
// Test second import
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_GNUCASH"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportgnucash/228901.gnucash"));
SKGTESTERROR(QStringLiteral("GNUCASH.importFile"), imp1.importFile(), true)
}
}
{
// Test import 234608
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_GNUCASH"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportgnucash/234608.gnc"));
SKGTESTERROR(QStringLiteral("GNUCASH.importFile"), imp1.importFile(), true)
}
}
{
// Test import 234597
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_GNUCASH"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportgnucash/234597.gnc"));
SKGTESTERROR(QStringLiteral("GNUCASH.importFile"), imp1.importFile(), true)
}
{
int nb = 0;
SKGTESTERROR(QStringLiteral("GNUCASH:getNbObjects"), document1.getNbObjects(QStringLiteral("account"), QLatin1String(""), nb), true)
SKGTEST(QStringLiteral("GNUCASH:getNbObjects"), nb, 11)
}
{
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("GNUCASH.setName"), account.setName(QStringLiteral("Compte cheques")), true)
SKGTESTERROR(QStringLiteral("GNUCASH.load"), account.load(), true)
SKGTEST(QStringLiteral("GNUCASH:getCurrentAmount"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("-260"))
}
{
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("GNUCASH.setName"), account.setName(QStringLiteral("Compte cheques (2)")), true)
SKGTESTERROR(QStringLiteral("GNUCASH.load"), account.load(), true)
SKGTEST(QStringLiteral("GNUCASH:getCurrentAmount"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("-40"))
}
{
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("GNUCASH.setName"), account.setName(QStringLiteral("Argent du porte-monnaie")), true)
SKGTESTERROR(QStringLiteral("GNUCASH.load"), account.load(), true)
SKGTEST(QStringLiteral("GNUCASH:getCurrentAmount"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("0"))
}
}
{
// Test import 243738
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_GNUCASH"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportgnucash/243738.gnucash"));
SKGTESTERROR(QStringLiteral("GNUCASH.importFile"), imp1.importFile(), true)
}
}
{
// Test import without book
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_GNUCASH"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportgnucash/without_book.gnucash"));
SKGTESTERROR(QStringLiteral("GNUCASH.importFile"), imp1.importFile(), true)
}
}
{
// Test import 302388
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_GNUCASH"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportgnucash/302388.gnc"));
SKGTESTERROR(QStringLiteral("GNUCASH.importFile"), imp1.importFile(), false)
}
}
{
// Test import 325174
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_GNUCASH"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportgnucash/325174.gnucash"));
SKGTESTERROR(QStringLiteral("GNUCASH.importFile"), imp1.importFile(), true)
}
int nb = 0;
SKGTESTERROR(QStringLiteral("GNUCASH:getNbObjects(account)"), document1.getNbObjects(QStringLiteral("account"), QLatin1String(""), nb), true)
SKGTEST(QStringLiteral("GNUCASH:getNbObjects(account)"), nb, 11)
}
{
// Test import wallet
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_GNUCASH"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportgnucash/wallet.gnucash"));
SKGTESTERROR(QStringLiteral("GNUCASH.importFile"), imp1.importFile(), true)
}
{
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("GNUCASH.setName"), account.setName(QStringLiteral("Espece")), true)
SKGTESTERROR(QStringLiteral("GNUCASH.load"), account.load(), true)
SKGBankObject bank;
SKGTESTERROR(QStringLiteral("GNUCASH.load"), account.getBank(bank), true)
SKGTEST(QStringLiteral("GNUCASH:getName"), bank.getName(), QLatin1String(""))
}
{
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("GNUCASH.setName"), account.setName(QStringLiteral("Courant")), true)
SKGTESTERROR(QStringLiteral("GNUCASH.load"), account.load(), true)
SKGBankObject bank;
SKGTESTERROR(QStringLiteral("GNUCASH.load"), account.getBank(bank), true)
SKGTEST(QStringLiteral("GNUCASH:getName"), bank.getName(), QStringLiteral("GNUCASH"))
}
}
{
// 407257
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_GNUCASH"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportgnucash/407257.gnucash"));
SKGTESTERROR(QStringLiteral("GNUCASH.importFile"), imp1.importFile(), true)
}
{
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("GNUCASH.setName"), account.setName(QStringLiteral("AccountName (Nom de compte)")), true)
SKGTESTERROR(QStringLiteral("GNUCASH.load"), account.load(), true)
SKGTEST(QStringLiteral("GNUCASH:getNumber"), account.getNumber(), QStringLiteral("123_AccountCode(CodeCompte)"))
SKGTEST(QStringLiteral("GNUCASH:getComment"), account.getComment(), QStringLiteral("DescriptionAccount(Compte123)"))
SKGUnitObject unit;
SKGTESTERROR(QStringLiteral("GNUCASH.getUnit"), account.getUnit(unit), true)
SKGTEST(QStringLiteral("GNUCASH:getName"), unit.getName(), QStringLiteral("Canadian Dollar (CAD)"))
}
{
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("GNUCASH.setName"), account.setName(QStringLiteral("Account2Name(no transaction)")), true)
SKGTESTERROR(QStringLiteral("GNUCASH.load"), account.load(), true)
}
}
// End test
SKGENDTEST()
}
diff --git a/tests/skgbankmodelertest/skgtestimportgsb.cpp b/tests/skgbankmodelertest/skgtestimportgsb.cpp
index b9145239d..a1e0932d5 100644
--- a/tests/skgbankmodelertest/skgtestimportgsb.cpp
+++ b/tests/skgbankmodelertest/skgtestimportgsb.cpp
@@ -1,176 +1,176 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is a test script.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include <klocalizedstring.h>
#include "skgbankincludes.h"
#include "skgimportexportmanager.h"
#include "skgtestmacro.h"
/**
* The main function of the unit test
* @param argc the number of arguments
* @param argv the list of arguments
*/
int main(int argc, char** argv)
{
Q_UNUSED(argc)
Q_UNUSED(argv)
// Init test
SKGINITTEST(true)
{
// Test import GSK
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_GSB"), err)
SKGImportExportManager impmissing(&document1, QUrl::fromLocalFile(QStringLiteral("missingfile.gsb")));
SKGTESTERROR(QStringLiteral("imp1.importFile"), impmissing.importFile(), false)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportgsb/test-obfuscated.gsb"));
SKGTESTERROR(QStringLiteral("GSB.importFile"), imp1.importFile(), true)
}
{
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("GSB.setName"), account.setName(QStringLiteral("Account 0")), true)
SKGTESTERROR(QStringLiteral("GSB.load"), account.load(), true)
SKGTEST(QStringLiteral("GSB:getCurrentAmount"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("1029"))
}
{
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("GSB.setName"), account.setName(QStringLiteral("Account 4")), true)
SKGTESTERROR(QStringLiteral("GSB.load"), account.load(), true)
SKGTEST(QStringLiteral("GSB:getCurrentAmount"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("7.5"))
}
{
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("GSB.setName"), account.setName(QStringLiteral("Account 1")), true)
SKGTESTERROR(QStringLiteral("GSB.load"), account.load(), true)
SKGTEST(QStringLiteral("GSB:getCurrentAmount"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("757.5"))
}
{
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("GSB.setName"), account.setName(QStringLiteral("Account 3")), true)
SKGTESTERROR(QStringLiteral("GSB.load"), account.load(), true)
SKGTEST(QStringLiteral("GSB:getCurrentAmount"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("43.5"))
}
}
{
// Test import GSK
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_GSB"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportgsb/version_0.5.9.gsb"));
SKGTESTERROR(QStringLiteral("GSB.importFile"), imp1.importFile(), false)
}
}
{
// Double import
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_GSB"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportgsb/essai.gsb"));
SKGTESTERROR(QStringLiteral("GSB.importFile"), imp1.importFile(), true)
}
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_GSB"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportgsb/essai.gsb"));
SKGTESTERROR(QStringLiteral("GSB.importFile"), imp1.importFile(), true)
}
}
{
// Split
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_GSB"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportgsb/split.gsb"));
SKGTESTERROR(QStringLiteral("GSB.importFile"), imp1.importFile(), true)
}
{
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("GSB.setName"), account.setName(QStringLiteral("Compte banque A")), true)
SKGTESTERROR(QStringLiteral("GSB.load"), account.load(), true)
SKGTEST(QStringLiteral("GSB:getCurrentAmount"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("350"))
}
{
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("GSB.setName"), account.setName(QStringLiteral("Compte banque B")), true)
SKGTESTERROR(QStringLiteral("GSB.load"), account.load(), true)
SKGTEST(QStringLiteral("GSB:getCurrentAmount"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("-9400"))
}
}
{
// Budget
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_GSB"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportgsb/imputations_budgetaires.gsb"));
SKGTESTERROR(QStringLiteral("GSB.importFile"), imp1.importFile(), true)
}
{
SKGObjectBase::SKGListSKGObjectBase operations;
SKGTESTERROR(QStringLiteral("GSB.getObjects"), document1.getObjects(QStringLiteral("v_operation_display"), QStringLiteral("d_date='2013-08-11'"), operations), true)
SKGTEST(QStringLiteral("GSB:count"), operations.count(), 1)
SKGOperationObject op(operations[0]);
SKGTEST(QStringLiteral("GSB:Budgetary allocation"), op.getProperty(i18nc("Noun", "Budgetary allocation")), QStringLiteral("imputation1"))
SKGTEST(QStringLiteral("GSB:Fiscal year"), op.getProperty(i18nc("Noun", "Fiscal year")), QStringLiteral("2013"))
SKGTEST(QStringLiteral("GSB:category"), op.getAttribute(QStringLiteral("t_CATEGORY")), QStringLiteral("categorie1"))
}
{
SKGObjectBase::SKGListSKGObjectBase operations;
SKGTESTERROR(QStringLiteral("GSB.getObjects"), document1.getObjects(QStringLiteral("v_operation_display"), QStringLiteral("d_date='2013-08-12'"), operations), true)
SKGTEST(QStringLiteral("GSB:count"), operations.count(), 1)
SKGOperationObject op(operations[0]);
SKGTEST(QStringLiteral("GSB:Budgetary allocation"), op.getProperty(i18nc("Noun", "Budgetary allocation")), "imputation1" % OBJECTSEPARATOR % "subimputation1")
SKGTEST(QStringLiteral("GSB:Fiscal year"), op.getProperty(i18nc("Noun", "Fiscal year")), QStringLiteral("2013"))
SKGTEST(QStringLiteral("GSB:category"), op.getAttribute(QStringLiteral("t_CATEGORY")), "categorie1" % OBJECTSEPARATOR % "subcategorie1")
}
}
// End test
SKGENDTEST()
}
diff --git a/tests/skgbankmodelertest/skgtestimportiif.cpp b/tests/skgbankmodelertest/skgtestimportiif.cpp
index 8547387a8..40d720ee5 100644
--- a/tests/skgbankmodelertest/skgtestimportiif.cpp
+++ b/tests/skgbankmodelertest/skgtestimportiif.cpp
@@ -1,235 +1,235 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is a test script.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgtestmacro.h"
#include "skgbankincludes.h"
#include "skgimportexportmanager.h"
/**
* The main function of the unit test
* @param argc the number of arguments
* @param argv the list of arguments
*/
int main(int argc, char** argv)
{
Q_UNUSED(argc)
Q_UNUSED(argv)
// Init test
SKGINITTEST(true)
{
// Test import full_check.iif
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_IIF"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportiif/full_check.iif"));
imp1.setCodec(QStringLiteral("UTF-8"));
SKGTESTERROR(QStringLiteral("IIF.importFile"), imp1.importFile(), true)
}
{
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("IIF.setName"), account.setName(QStringLiteral("Checking")), true)
SKGTESTERROR(QStringLiteral("IIF.load"), account.load(), true)
SKGTEST(QStringLiteral("IIF:getValue"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("-36.15"))
}
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("EXPORT_IIF"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("OUT")) % "/skgtestimportiif/full_check.iif"));
imp1.setCodec(QStringLiteral("UTF-8"));
SKGTESTERROR(QStringLiteral("IIF.exportFile"), imp1.exportFile(), true)
}
}
{
// Test import full_deposit.iif
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_IIF"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportiif/full_deposit.iif"));
SKGTESTERROR(QStringLiteral("IIF.importFile"), imp1.importFile(), true)
}
{
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("IIF.setName"), account.setName(QStringLiteral("Checking")), true)
SKGTESTERROR(QStringLiteral("IIF.load"), account.load(), true)
SKGTEST(QStringLiteral("IIF:getValue"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("10000"))
}
}
{
// Test import full_bill.iif
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_IIF"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportiif/full_bill.iif"));
SKGTESTERROR(QStringLiteral("IIF.importFile"), imp1.importFile(), true)
}
{
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("IIF.setName"), account.setName(QStringLiteral("Accounts Payable")), true)
SKGTESTERROR(QStringLiteral("IIF.load"), account.load(), true)
SKGTEST(QStringLiteral("IIF:getValue"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("-59.25"))
}
}
{
// Test import full_cash_sale.iif
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_IIF"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportiif/full_cash_sale.iif"));
SKGTESTERROR(QStringLiteral("IIF.importFile"), imp1.importFile(), true)
}
{
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("IIF.setName"), account.setName(QStringLiteral("Undeposited Funds")), true)
SKGTESTERROR(QStringLiteral("IIF.load"), account.load(), true)
SKGTEST(QStringLiteral("IIF:getValue"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("1969.98"))
}
}
{
// Test import full_transfer.iif
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_IIF"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportiif/full_transfer.iif"));
SKGTESTERROR(QStringLiteral("IIF.importFile"), imp1.importFile(), true)
}
{
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("IIF.setName"), account.setName(QStringLiteral("Checking")), true)
SKGTESTERROR(QStringLiteral("IIF.load"), account.load(), true)
SKGTEST(QStringLiteral("IIF:getValue"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("-500"))
}
{
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("IIF.setName"), account.setName(QStringLiteral("Savings")), true)
SKGTESTERROR(QStringLiteral("IIF.load"), account.load(), true)
SKGTEST(QStringLiteral("IIF:getValue"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("500"))
}
}
{
// Test import full_bill_payment.iif
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_IIF"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportiif/full_bill_payment.iif"));
SKGTESTERROR(QStringLiteral("IIF.importFile"), imp1.importFile(), true)
}
{
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("IIF.setName"), account.setName(QStringLiteral("Checking")), true)
SKGTESTERROR(QStringLiteral("IIF.load"), account.load(), true)
SKGTEST(QStringLiteral("IIF:getValue"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("-35"))
}
{
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("IIF.setName"), account.setName(QStringLiteral("Accounts Payable")), true)
SKGTESTERROR(QStringLiteral("IIF.load"), account.load(), true)
SKGTEST(QStringLiteral("IIF:getValue"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("35"))
}
}
{
// Test import full_customer_payment.iif
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_IIF"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportiif/full_customer_payment.iif"));
SKGTESTERROR(QStringLiteral("IIF.importFile"), imp1.importFile(), true)
}
SKGAccountObject la;
{
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("IIF.setName"), account.setName(QStringLiteral("Undeposited Funds")), true)
SKGTESTERROR(QStringLiteral("IIF.load"), account.load(), true)
SKGTEST(QStringLiteral("IIF:getValue"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("53.5"))
la = account;
}
{
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("IIF.setName"), account.setName(QStringLiteral("Accounts Receivable")), true)
SKGTESTERROR(QStringLiteral("IIF.load"), account.load(), true)
SKGTEST(QStringLiteral("IIF:getValue"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("-53.5"))
}
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("EXPORT_IIF"), err)
SKGImportExportManager exp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("OUT")) % "/skgtestimportiif/export_all.iif"));
SKGTESTERROR(QStringLiteral("IIF.exportFile"), exp1.exportFile(), true)
}
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("EXPORT_IIF"), err)
SKGImportExportManager exp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("OUT")) % "/skgtestimportiif/export_la.iif"));
QMap<QString, QString> params;
params[QStringLiteral("uuid_of_selected_accounts_or_operations")] = la.getUniqueID();
exp1.setExportParameters(params);
SKGTESTERROR(QStringLiteral("IIF.exportFile"), exp1.exportFile(), true)
}
}
// End test
SKGENDTEST()
}
diff --git a/tests/skgbankmodelertest/skgtestimportkmy1.cpp b/tests/skgbankmodelertest/skgtestimportkmy1.cpp
index f2e0b7c8c..d864349a1 100644
--- a/tests/skgbankmodelertest/skgtestimportkmy1.cpp
+++ b/tests/skgbankmodelertest/skgtestimportkmy1.cpp
@@ -1,188 +1,188 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is a test script.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgtestmacro.h"
#include "skgbankincludes.h"
#include "skgimportexportmanager.h"
/**
* The main function of the unit test
* @param argc the number of arguments
* @param argv the list of arguments
*/
int main(int argc, char** argv)
{
Q_UNUSED(argc)
Q_UNUSED(argv)
// Init test
SKGINITTEST(true)
{
// Test import KMY
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_KMY"), err)
SKGImportExportManager impmissing(&document1, QUrl::fromLocalFile(QStringLiteral("missingfile.kmy")));
SKGTESTERROR(QStringLiteral("imp1.importFile"), impmissing.importFile(), false)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportkmy/rapprochement-incorrect.kmy"));
SKGTESTERROR(QStringLiteral("KMY.importFile"), imp1.importFile(), true)
}
{
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("KMY.setName"), account.setName(QStringLiteral("CCP")), true)
SKGTESTERROR(QStringLiteral("KMY.load"), account.load(), true)
SKGTEST(QStringLiteral("KMY:getCurrentAmount"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("750"))
}
{
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("KMY.setName"), account.setName(QStringLiteral("CEL Donald")), true)
SKGTESTERROR(QStringLiteral("KMY.load"), account.load(), true)
SKGTEST(QStringLiteral("KMY:getCurrentAmount"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("150"))
}
{
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("KMY.setName"), account.setName(QStringLiteral("PEEs")), true)
SKGTESTERROR(QStringLiteral("KMY.load"), account.load(), true)
SKGTEST(QStringLiteral("KMY:getCurrentAmount"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("640"))
}
{
// Scope of the transaction
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("OUT")) % "/skgtestimportkmy1/rapprochement-incorrect.kmy"));
SKGTESTERROR(QStringLiteral("KMY.exportFile"), imp1.exportFile(), true)
}
}
{
// Test import KMY
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_KMY"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportkmy/mytest.kmy"));
SKGTESTERROR(QStringLiteral("KMY.importFile"), imp1.importFile(), true)
}
int nb = 0;
SKGTESTERROR(QStringLiteral("KMY:getNbObjects(recurrentoperation)"), document1.getNbObjects(QStringLiteral("recurrentoperation"), QLatin1String(""), nb), true)
SKGTEST(QStringLiteral("KMY:getNbObjects(recurrentoperation)"), nb, 8)
}
{
// Test import KMY
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_KMY"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportkmy/action.kmy"));
SKGTESTERROR(QStringLiteral("KMY.importFile"), imp1.importFile(), true)
}
{
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("KMY.setName"), account.setName(QStringLiteral("courant")), true)
SKGTESTERROR(QStringLiteral("KMY.load"), account.load(), true)
SKGTEST(QStringLiteral("KMY:getCurrentAmount"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("-600"))
}
{
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("KMY.setName"), account.setName(QStringLiteral("actions")), true)
SKGTESTERROR(QStringLiteral("KMY.load"), account.load(), true)
SKGTEST(QStringLiteral("KMY:getCurrentAmount"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("100"))
}
// test multi import
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_KMY"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportkmy/action.kmy"));
SKGTESTERROR(QStringLiteral("KMY.importFile"), imp1.importFile(), true)
}
}
{
// Test import KMY
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_KMY"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportkmy/252869.kmy"));
SKGTESTERROR(QStringLiteral("KMY.importFile"), imp1.importFile(), true)
}
int nb = 0;
SKGTESTERROR(QStringLiteral("KMY:getNbObjects(recurrentoperation)"), document1.getNbObjects(QStringLiteral("bank"), QStringLiteral("t_name='Test Bank'"), nb), true)
SKGTEST(QStringLiteral("KMY:getNbObjects(recurrentoperation)"), nb, 1)
}
{
// 384119
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_KMY"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportkmy/384119.kmy"));
SKGTESTERROR(QStringLiteral("KMY.importFile"), imp1.importFile(), true)
}
int nb = 0;
SKGTESTERROR(QStringLiteral("KMY:getNbObjects(operations without suboperation)"), document1.getNbObjects(QStringLiteral("operation"), QStringLiteral("NOT EXISTS (SELECT 1 FROM suboperation where rd_operation_id=operation.id)"), nb), true)
SKGTEST(QStringLiteral("KMY:getNbObjects(operations without suboperation)"), nb, 0)
}
{
// Non utf8
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_KMY"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportkmy/non_utf8.kmy"));
SKGTESTERROR(QStringLiteral("KMY.importFile"), imp1.importFile(), true)
}
}
// End test
SKGENDTEST()
}
diff --git a/tests/skgbankmodelertest/skgtestimportkmy2.cpp b/tests/skgbankmodelertest/skgtestimportkmy2.cpp
index 8d4d04b09..f22f492e7 100644
--- a/tests/skgbankmodelertest/skgtestimportkmy2.cpp
+++ b/tests/skgbankmodelertest/skgtestimportkmy2.cpp
@@ -1,55 +1,55 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is a test script.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgtestmacro.h"
#include "skgbankincludes.h"
#include "skgimportexportmanager.h"
/**
* The main function of the unit test
* @param argc the number of arguments
* @param argv the list of arguments
*/
int main(int argc, char** argv)
{
Q_UNUSED(argc)
Q_UNUSED(argv)
// Init test
SKGINITTEST(true)
{
// Test import KMY
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_KMY"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportkmy2/to_skrooge.anon.kmy"));
SKGTESTERROR(QStringLiteral("KMY.importFile"), imp1.importFile(), true)
}
}
// End test
SKGENDTEST()
}
diff --git a/tests/skgbankmodelertest/skgtestimportkmy3.cpp b/tests/skgbankmodelertest/skgtestimportkmy3.cpp
index 4288f390f..4164427b7 100644
--- a/tests/skgbankmodelertest/skgtestimportkmy3.cpp
+++ b/tests/skgbankmodelertest/skgtestimportkmy3.cpp
@@ -1,102 +1,102 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is a test script.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgtestmacro.h"
#include "skgbankincludes.h"
#include "skgimportexportmanager.h"
/**
* The main function of the unit test
* @param argc the number of arguments
* @param argv the list of arguments
*/
int main(int argc, char** argv)
{
Q_UNUSED(argc)
Q_UNUSED(argv)
// Init test
SKGINITTEST(true) {
// Test import 304313
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_KMY"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportkmy/304313.kmy"));
SKGTESTERROR(QStringLiteral("KMY.importFile"), imp1.importFile(), true)
}
}
{
// Test import SKG
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_SKG"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/advice.skg"));
SKGTESTERROR(QStringLiteral("KMY.importFile"), imp1.importFile(), true)
}
{
// Scope of the transaction
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("OUT")) % "/skgtestimportkmy3/advice.kmy"));
SKGTESTERROR(QStringLiteral("KMY.exportFile"), imp1.exportFile(), true)
}
}
{
// Test import wallet
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_KMY"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportkmy3/wallet.kmy"));
SKGTESTERROR(QStringLiteral("KMY.importFile"), imp1.importFile(), true)
}
{
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("KMY.setName"), account.setName(QStringLiteral("Espece")), true)
SKGTESTERROR(QStringLiteral("KMY.load"), account.load(), true)
SKGBankObject bank;
SKGTESTERROR(QStringLiteral("KMY.load"), account.getBank(bank), true)
SKGTEST(QStringLiteral("KMY:getName"), bank.getName(), QLatin1String(""))
}
{
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("KMY.setName"), account.setName(QStringLiteral("Courant")), true)
SKGTESTERROR(QStringLiteral("KMY.load"), account.load(), true)
SKGBankObject bank;
SKGTESTERROR(QStringLiteral("KMY.load"), account.getBank(bank), true)
SKGTEST(QStringLiteral("KMY:getName"), bank.getName(), QStringLiteral("KMYMONEY"))
}
}
// End test
SKGENDTEST()
}
diff --git a/tests/skgbankmodelertest/skgtestimportkmy4.cpp b/tests/skgbankmodelertest/skgtestimportkmy4.cpp
index b9289bbcc..28d4a47cc 100644
--- a/tests/skgbankmodelertest/skgtestimportkmy4.cpp
+++ b/tests/skgbankmodelertest/skgtestimportkmy4.cpp
@@ -1,144 +1,144 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is a test script.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgtestmacro.h"
#include "skgbankincludes.h"
#include "skgimportexportmanager.h"
/**
* The main function of the unit test
* @param argc the number of arguments
* @param argv the list of arguments
*/
int main(int argc, char** argv)
{
Q_UNUSED(argc)
Q_UNUSED(argv)
// Init test
SKGINITTEST(true)
int nboperation = 0;
{
// Test export 320066
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.load()"), document1.load(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportkmy4/320066.skg"), true)
SKGTESTERROR(QStringLiteral("document1.getNbObjects()"), document1.getNbObjects(QStringLiteral("v_operation_display"), QLatin1String(""), nboperation), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("EXPORT_KMY"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("OUT")) % "/skgtestimportkmy4/320066.kmy"));
SKGTESTERROR(QStringLiteral("KMY.exportFile"), imp1.exportFile(), true)
}
}
{
// Test import 320066
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_KMY"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("OUT")) % "/skgtestimportkmy4/320066.kmy"));
SKGTESTERROR(QStringLiteral("KMY.importFile"), imp1.importFile(), true)
int nboperation2 = 0;
SKGTESTERROR(QStringLiteral("document1.getNbObjects()"), document1.getNbObjects(QStringLiteral("v_operation_display"), QLatin1String(""), nboperation2), true)
SKGTEST(QStringLiteral("document1:nb operations"), nboperation2, nboperation)
}
}
{
// Test import randy1
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_KMY"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportkmy4/randy1.kmy"));
SKGTESTERROR(QStringLiteral("KMY.importFile"), imp1.importFile(), true)
}
// Actif
SKGTESTACCOUNT(document1, QStringLiteral("A000290"), 23182500.00);
// Action
/*SKGTESTACCOUNT(document1, QStringLiteral("A000014"), 2432032.27);
SKGTESTACCOUNT(document1, QStringLiteral("A000016"), 236769.78);
SKGTESTACCOUNT(document1, QStringLiteral("A000018"), 0.00);
SKGTESTACCOUNT(document1, QStringLiteral("A000020"), 0.00);
SKGTESTACCOUNT(document1, QStringLiteral("A000022"), 326254.23);
SKGTESTACCOUNT(document1, QStringLiteral("A000023"), 459915.34);
SKGTESTACCOUNT(document1, QStringLiteral("A000025"), 618975.84);
SKGTESTACCOUNT(document1, QStringLiteral("A000027"), 301501.09);
SKGTESTACCOUNT(document1, QStringLiteral("A000032"), 12358550.29);
SKGTESTACCOUNT(document1, QStringLiteral("A000294"), 1193772.30);
SKGTESTACCOUNT(document1, QStringLiteral("A000300"), 12304427.59);
SKGTESTACCOUNT(document1, QStringLiteral("A000312"), 2822127.36);
SKGTESTACCOUNT(document1, QStringLiteral("A000366"), 14150464.39);
SKGTESTACCOUNT(document1, QStringLiteral("A000371"), 2160798.86);*/
// Carte de credit
SKGTESTACCOUNT(document1, QStringLiteral("A000120"), -316721.001);
SKGTESTACCOUNT(document1, QStringLiteral("A000407"), -1438.158);
SKGTESTACCOUNT(document1, QStringLiteral("A000409"), 0.00);
// Cheques
SKGTESTACCOUNT(document1, QStringLiteral("A000030"), -6371673.033);
SKGTESTACCOUNT(document1, QStringLiteral("A000040"), 429856.659);
SKGTESTACCOUNT(document1, QStringLiteral("A000273"), 2479805.892);
SKGTESTACCOUNT(document1, QStringLiteral("A000378"), 845357.871);
// Especes
SKGTESTACCOUNT(document1, QStringLiteral("A000314"), 0.00);
SKGTESTACCOUNT(document1, QStringLiteral("A000354"), 863.232);
// Epargne
SKGTESTACCOUNT(document1, QStringLiteral("A000041"), 402257.682);
SKGTESTACCOUNT(document1, QStringLiteral("A000301"), 951074.286);
SKGTESTACCOUNT(document1, QStringLiteral("A000330"), 0.00);
SKGTESTACCOUNT(document1, QStringLiteral("A000353"), 1753.44);
SKGTESTACCOUNT(document1, QStringLiteral("A000379"), 4955771.076);
SKGTESTACCOUNT(document1, QStringLiteral("A000387"), 849701.007);
SKGTESTACCOUNT(document1, QStringLiteral("A000388"), 4681634.22);
SKGTESTACCOUNT(document1, QStringLiteral("A000400"), 255912.039);
}
{
// Test import cat
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.load()"), document1.load(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportkmy4/bug_import_cat.skg"), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_KMY"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportkmy4/bug_import_cat.kmy"));
SKGTESTERROR(QStringLiteral("KMY.importFile"), imp1.importFile(), true)
int nb = 0;
SKGTESTERROR(QStringLiteral("document1.getNbObjects()"), document1.getNbObjects(QStringLiteral("category"), QStringLiteral("t_name='Cantine'"), nb), true)
SKGTEST(QStringLiteral("document1:nb category"), nb, 1)
}
}
// End test
SKGENDTEST()
}
diff --git a/tests/skgbankmodelertest/skgtestimportkmy5.cpp b/tests/skgbankmodelertest/skgtestimportkmy5.cpp
index e5a9064bc..bec7cccf3 100644
--- a/tests/skgbankmodelertest/skgtestimportkmy5.cpp
+++ b/tests/skgbankmodelertest/skgtestimportkmy5.cpp
@@ -1,101 +1,101 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is a test script.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgtestmacro.h"
#include "skgbankincludes.h"
#include "skgimportexportmanager.h"
/**
* The main function of the unit test
* @param argc the number of arguments
* @param argv the list of arguments
*/
int main(int argc, char** argv)
{
Q_UNUSED(argc)
Q_UNUSED(argv)
// Init test
SKGINITTEST(true) {
// Test import solde initial
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_KMY"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportkmy5/solde_initial.kmy"));
SKGTESTERROR(QStringLiteral("KMY.importFile"), imp1.importFile(), true)
}
SKGTESTACCOUNT(document1, QStringLiteral("AAA"), 123456.00);
int nboperation = 0;
SKGTESTERROR(QStringLiteral("document1.getNbObjects()"), document1.getNbObjects(QStringLiteral("v_operation_display"), QLatin1String(""), nboperation), true)
SKGTEST(QStringLiteral("document1:nb operations"), nboperation, 0)
}
{
// Test import steffy
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_KMY"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportkmy5/steffie.kmy"));
SKGTESTERROR(QStringLiteral("KMY.importFile"), imp1.importFile(), true)
}
SKGTESTACCOUNT(document1, QStringLiteral("A000007"), 2695.00);
SKGTESTACCOUNT(document1, QStringLiteral("A000548"), 175494.48);
SKGTESTACCOUNT(document1, QStringLiteral("A000549"), 1186034.71);
SKGTESTACCOUNT(document1, QStringLiteral("A000573"), 30968132.93);
SKGTESTACCOUNT(document1, QStringLiteral("A000584"), 2493455.65);
SKGTESTACCOUNT(document1, QStringLiteral("A000429"), -3723.51);
SKGTESTACCOUNT(document1, QStringLiteral("A000433"), -12809.09);
// Closed accounts
SKGTESTACCOUNT(document1, QStringLiteral("A000004"), 0.0);
SKGTESTACCOUNT(document1, QStringLiteral("A000005"), 0.0);
SKGTESTACCOUNT(document1, QStringLiteral("A000006"), 0.0);
SKGTESTACCOUNT(document1, QStringLiteral("A000490"), 0.0);
SKGTESTACCOUNT(document1, QStringLiteral("A000430"), 0.0);
SKGTESTACCOUNT(document1, QStringLiteral("A000431"), 0.0);
SKGTESTACCOUNT(document1, QStringLiteral("A000432"), 0.0);
SKGTESTACCOUNT(document1, QStringLiteral("A000533"), 0.0);
SKGTESTACCOUNT(document1, QStringLiteral("A000435"), 0.0);
SKGTESTACCOUNT(document1, QStringLiteral("A000436"), 0.0);
SKGTESTACCOUNT(document1, QStringLiteral("A000437"), 0.0);
SKGTESTACCOUNT(document1, QStringLiteral("A000487"), 0.0);
SKGTESTACCOUNT(document1, QStringLiteral("A000492"), 0.0);
SKGTESTACCOUNT(document1, QStringLiteral("A000495"), 0.0);
SKGTESTACCOUNT(document1, QStringLiteral("A000497"), 0.0);
SKGTESTACCOUNT(document1, QStringLiteral("A000499"), 0.0);
SKGTESTACCOUNT(document1, QStringLiteral("A000526"), 0.0);
SKGTESTACCOUNT(document1, QStringLiteral("A000543"), 0.0);
SKGTESTACCOUNT(document1, QStringLiteral("A000553"), 0.0);
SKGTESTACCOUNT(document1, QStringLiteral("A000560"), 0.0);
}
// End test
SKGENDTEST()
}
diff --git a/tests/skgbankmodelertest/skgtestimportledger.cpp b/tests/skgbankmodelertest/skgtestimportledger.cpp
index 9b46c683d..62cfb4e7f 100644
--- a/tests/skgbankmodelertest/skgtestimportledger.cpp
+++ b/tests/skgbankmodelertest/skgtestimportledger.cpp
@@ -1,57 +1,57 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is a test script.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include <klocalizedstring.h>
#include "skgbankincludes.h"
#include "skgimportexportmanager.h"
#include "skgtestmacro.h"
/**
* The main function of the unit test
* @param argc the number of arguments
* @param argv the list of arguments
*/
int main(int argc, char** argv)
{
Q_UNUSED(argc)
Q_UNUSED(argv)
// Init test
SKGINITTEST(true)
{
// Test import GSB
SKGDocumentBank document1;
SKGError err;
SKGTESTERROR(QStringLiteral("DOC.load"), document1.load(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportskg/all_types.skg"), true)
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("EXPORT_LEDGE"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("OUT")) % "/skgtestimportledger/test-obfuscated.ledger"));
SKGTESTERROR(QStringLiteral("LEDGE.exportFile"), imp1.exportFile(), true)
}
}
// End test
SKGENDTEST()
}
diff --git a/tests/skgbankmodelertest/skgtestimportmmb.cpp b/tests/skgbankmodelertest/skgtestimportmmb.cpp
index b5b48c4e9..6ac4268d5 100644
--- a/tests/skgbankmodelertest/skgtestimportmmb.cpp
+++ b/tests/skgbankmodelertest/skgtestimportmmb.cpp
@@ -1,102 +1,102 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is a test script.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgtestmacro.h"
#include "skgbankincludes.h"
#include "skgimportexportmanager.h"
/**
* The main function of the unit test
* @param argc the number of arguments
* @param argv the list of arguments
*/
int main(int argc, char** argv)
{
Q_UNUSED(argc)
Q_UNUSED(argv)
// Init test
SKGINITTEST(true)
{
// Test import GSK
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_MMB"), err)
SKGImportExportManager impmissing(&document1, QUrl::fromLocalFile(QStringLiteral("missingfile.mmb")));
SKGTESTERROR(QStringLiteral("imp1.importFile"), impmissing.importFile(), false)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportmmb/test.mmb"));
SKGTESTERROR(QStringLiteral("MMB.importFile"), imp1.importFile(), true)
}
{
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("MMB.setName"), account.setName(QStringLiteral("COURANT")), true)
SKGTESTERROR(QStringLiteral("MMB.load"), account.load(), true)
SKGTEST(QStringLiteral("GSB:getCurrentAmount"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("-144.05"))
}
{
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("MMB.setName"), account.setName(QStringLiteral("CPT2")), true)
SKGTESTERROR(QStringLiteral("MMB.load"), account.load(), true)
SKGTEST(QStringLiteral("GSB:getCurrentAmount"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("40"))
}
{
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("MMB.setName"), account.setName(QStringLiteral("NOTFAVORITE")), true)
SKGTESTERROR(QStringLiteral("MMB.load"), account.load(), true)
SKGTEST(QStringLiteral("GSB:getCurrentAmount"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("150"))
}
{
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("MMB.setName"), account.setName(QStringLiteral("LEP")), true)
SKGTESTERROR(QStringLiteral("MMB.load"), account.load(), true)
SKGTEST(QStringLiteral("GSB:getCurrentAmount"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("6000"))
}
}
{
// Test import GSK
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_MMB"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportmmb/jd.mmb"));
SKGTESTERROR(QStringLiteral("MMB.importFile"), imp1.importFile(), true)
}
{
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("MMB.setName"), account.setName(QStringLiteral("credit")), true)
SKGTESTERROR(QStringLiteral("MMB.load"), account.load(), true)
SKGTEST(QStringLiteral("GSB:getCurrentAmount"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("-974.04"))
}
}
// End test
SKGENDTEST()
}
diff --git a/tests/skgbankmodelertest/skgtestimportmny1.cpp b/tests/skgbankmodelertest/skgtestimportmny1.cpp
index fead8603c..c8983570d 100644
--- a/tests/skgbankmodelertest/skgtestimportmny1.cpp
+++ b/tests/skgbankmodelertest/skgtestimportmny1.cpp
@@ -1,174 +1,174 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is a test script.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgtestmacro.h"
#include "skgbankincludes.h"
#include "skgimportexportmanager.h"
struct test {
QString fileName;
QString password;
QMap<QString, double> expectedAccountAmount;
};
/**
* The main function of the unit test
* @param argc the number of arguments
* @param argv the list of arguments
*/
int main(int argc, char** argv)
{
Q_UNUSED(argc)
Q_UNUSED(argv)
// Init test
SKGINITTEST(true)
{
// Test import MNY
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_MNY"), err)
SKGImportExportManager impmissing(&document1, QUrl::fromLocalFile(QStringLiteral("/not-existing/missingfile.mny")));
{
QMap<QString, QString> params = impmissing.getImportParameters();
params[QStringLiteral("install_sunriise")] = 'Y';
impmissing.setImportParameters(params);
}
SKGTESTERROR(QStringLiteral("imp1.importFile"), impmissing.importFile(), false)
SKGImportExportManager impwrong(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportmny1/wrongfile.mny"));
{
QMap<QString, QString> params = impwrong.getImportParameters();
params[QStringLiteral("install_sunriise")] = 'Y';
impwrong.setImportParameters(params);
}
SKGTESTERROR(QStringLiteral("imp1.importFile"), impwrong.importFile(), false)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportmny1/money2004-pwd:123@ABC!.mny"));
{
QMap<QString, QString> params = imp1.getImportParameters();
params[QStringLiteral("password")] = QStringLiteral("wrong password");
params[QStringLiteral("install_sunriise")] = 'Y';
imp1.setImportParameters(params);
}
SKGTEST(QStringLiteral("imp1.importFile"), imp1.importFile().getReturnCode(), ERR_ENCRYPTION)
}
}
QVector<test> listTests;
{
test t1;
t1.fileName = QStringLiteral("A B/money2002.mny");
QMap<QString, double> accounts;
accounts[QStringLiteral("None Investment (Cash)")] = 0.0;
accounts[QStringLiteral("Investments to Watch")] = 0.0;
accounts[QStringLiteral("None Investment")] = 1.49;
t1.expectedAccountAmount = accounts;
listTests << t1;
}
{
test t1;
t1.fileName = QStringLiteral("money2001.mny");
QMap<QString, double> accounts;
accounts[QStringLiteral("Investments to Watch")] = 0.0;
t1.expectedAccountAmount = accounts;
listTests << t1;
}
{
test t1;
t1.fileName = QStringLiteral("money2004-pwd:123@ABC!.mny");
t1.password = QStringLiteral("123@ABC!");
QMap<QString, double> accounts;
accounts[QStringLiteral("Investments to Watch")] = 0.0;
t1.expectedAccountAmount = accounts;
listTests << t1;
}
{
test t1;
t1.fileName = QStringLiteral("money2005-pwd:123@ABC!.mny");
t1.password = QStringLiteral("123@ABC!");
QMap<QString, double> accounts;
accounts[QStringLiteral("George's Pension Plan")] = 250.0;
accounts[QStringLiteral("Investments to Watch")] = 0.0;
accounts[QStringLiteral("Invoice Sales Ledger")] = 1780.71;
accounts[QStringLiteral("Stocks and Shares")] = 830.5;
accounts[QStringLiteral("Stocks and Shares (Cash)")] = -178.0;
accounts[QStringLiteral("Woodgrove Bank Credit Card")] = 1013.0;
accounts[QStringLiteral("Woodgrove Bank Current")] = 20280.14;
accounts[QStringLiteral("Woodgrove Bank Savings")] = 800.0;
t1.expectedAccountAmount = accounts;
listTests << t1;
}
{
test t1;
t1.fileName = QStringLiteral("money2008-pwd:TEST12345.mny");
t1.password = QStringLiteral("TEST12345");
QMap<QString, double> accounts;
accounts[QStringLiteral("Investments to Watch")] = 0.0;
t1.expectedAccountAmount = accounts;
listTests << t1;
}
for (const auto& t : qAsConst(listTests)) {
// Test import MNY
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_MNY"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportmny1/" % t.fileName));
QMap<QString, QString> params = imp1.getImportParameters();
params[QStringLiteral("password")] = t.password;
params[QStringLiteral("install_sunriise")] = 'Y';
imp1.setImportParameters(params);
SKGTESTERROR(t.fileName % ".importFile", imp1.importFile(), true)
}
QStringList keys = t.expectedAccountAmount.keys();
for (const auto& k : qAsConst(keys)) {
SKGAccountObject account(&document1);
SKGTESTERROR(t.fileName % ".setName(QStringLiteral(" % k % "))", account.setName(k), true)
SKGTESTERROR(t.fileName % ".load(QStringLiteral(" % k % "))", account.load(), true)
SKGTEST(t.fileName % ".getCurrentAmount(" % k % ")", SKGServices::doubleToString(account.getCurrentAmount()), SKGServices::doubleToString(t.expectedAccountAmount[k]))
}
if (t.fileName == QStringLiteral("money2005-pwd:123@ABC!.mny")) {
bool check = false;
SKGTESTERROR(t.fileName % ".existObjects", document1.existObjects(QStringLiteral("v_operation"), QStringLiteral("t_TRANSFER='Y'"), check), true)
SKGTESTBOOL(t.fileName % ".existObjects", check, true)
}
}
// End test
SKGENDTEST()
}
diff --git a/tests/skgbankmodelertest/skgtestimportmny2.cpp b/tests/skgbankmodelertest/skgtestimportmny2.cpp
index 21bd6bcf0..d6b0d0478 100644
--- a/tests/skgbankmodelertest/skgtestimportmny2.cpp
+++ b/tests/skgbankmodelertest/skgtestimportmny2.cpp
@@ -1,133 +1,133 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is a test script.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgtestmacro.h"
#include "skgbankincludes.h"
#include "skgimportexportmanager.h"
class SKGTestImportMny2
{
public:
/**
* To check the progress
*/
static QString previousProgress;
/**
* To test progress
* @param iPos the current position
* @return 0
*/
static int progress1(int iPos, qint64 iTime, const QString& iName, void* /*iData*/)
{
if (SKGTestImportMny2::previousProgress != iName) {
SKGTRACE << iPos << "-" << iTime << ":" << iName << endl;
SKGTestImportMny2::previousProgress = iName;
}
return 0;
}
};
QString SKGTestImportMny2::previousProgress = QLatin1String("");
struct test {
QString fileName;
QString password;
QMap<QString, double> expectedAccountAmount;
};
/**
* The main function of the unit test
* @param argc the number of arguments
* @param argv the list of arguments
*/
int main(int argc, char** argv)
{
Q_UNUSED(argc)
Q_UNUSED(argv)
// Init test
SKGINITTEST(true)
QVector<test> listTests;
{
test t1;
t1.fileName = QStringLiteral("sunset-sample-5-pwd:12@a!.mny");
t1.password = QStringLiteral("12@a!");
QMap<QString, double> accounts;
// TODO(Stephane MANKOWSKI): accounts["Charlie & May’s Joint Inv (Cash)"] = -10004.15;
accounts[QStringLiteral("Charlie's 401(k)")] = 24749.18;
accounts[QStringLiteral("Charlie's 401(k) (Contributions)")] = 13192.68;
accounts[QStringLiteral("Commodities")] = 8745.0000;
accounts[QStringLiteral("Commodities (Cash)")] = 255.0;
accounts[QStringLiteral("ETF Brokerage Account")] = 690.0;
accounts[QStringLiteral("ETF Brokerage Account (Cash)")] = 2310.0;
accounts[QStringLiteral("Escrow Account")] = 28100.0;
accounts[QStringLiteral("Home Loan")] = -149122.08;
accounts[QStringLiteral("Investments to Watch")] = 0.0;
accounts[QStringLiteral("Previous card (No longer used)")] = -984.25;
accounts[QStringLiteral("Primary Residence")] = 355000.0;
accounts[QStringLiteral("WoodGrove Finance Stock Options")] = 0.0;
accounts[QStringLiteral("WoodGrove Finance Stock Options (Cash)")] = 0.0;
accounts[QStringLiteral("Woodgrove Bank Checking")] = 22871.06;
accounts[QStringLiteral("Woodgrove Bank Credit Card")] = 19305.74;
accounts[QStringLiteral("Woodgrove Bank Savings")] = 22946.30;
accounts[QStringLiteral("Woodgrove Bond Account")] = 57916.20;
accounts[QStringLiteral("Woodgrove Bond Account (Cash)")] = -57916.20;
accounts[QStringLiteral("Woodgrove Investments")] = 1574.62;
accounts[QStringLiteral("Woodgrove Investments (Cash)")] = -1594.62;
accounts[QStringLiteral("Woodgrove Platinum Card")] = -836.0;
t1.expectedAccountAmount = accounts;
listTests << t1;
}
for (const auto& t : qAsConst(listTests)) {
// Test import MNY
SKGTRACE << "Filename:" << t.fileName << endl;
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGTRACE << "SKG_SQLITE_LAST_VERSION:" << document1.getParameter(QStringLiteral("SKG_SQLITE_LAST_VERSION")) << endl;
SKGTESTERROR(QStringLiteral("document1.setProgressCallback"), document1.setProgressCallback(&SKGTestImportMny2::progress1, nullptr), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_MNY"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportmny2/" % t.fileName));
QMap<QString, QString> params = imp1.getImportParameters();
params[QStringLiteral("password")] = t.password;
params[QStringLiteral("install_sunriise")] = 'Y';
imp1.setImportParameters(params);
SKGTESTERROR(t.fileName % ".importFile", imp1.importFile(), true)
}
QStringList keys = t.expectedAccountAmount.keys();
for (const auto& k : qAsConst(keys)) {
SKGAccountObject account(&document1);
SKGTESTERROR(t.fileName % ".setName(QStringLiteral(" % k % "))", account.setName(k), true)
SKGTESTERROR(t.fileName % ".load(QStringLiteral(" % k % "))", account.load(), true)
SKGTEST(t.fileName % ".getCurrentAmount(" % k % ")", SKGServices::doubleToString(account.getCurrentAmount()), SKGServices::doubleToString(t.expectedAccountAmount[k]))
}
}
// End test
SKGENDTEST()
}
diff --git a/tests/skgbankmodelertest/skgtestimportmny3.cpp b/tests/skgbankmodelertest/skgtestimportmny3.cpp
index 3e5c6df85..81d0f1823 100644
--- a/tests/skgbankmodelertest/skgtestimportmny3.cpp
+++ b/tests/skgbankmodelertest/skgtestimportmny3.cpp
@@ -1,129 +1,129 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is a test script.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgtestmacro.h"
#include "skgbankincludes.h"
#include "skgimportexportmanager.h"
struct test {
QString fileName;
QString password;
QMap<QString, double> expectedAccountAmount;
};
/**
* The main function of the unit test
* @param argc the number of arguments
* @param argv the list of arguments
*/
int main(int argc, char** argv)
{
Q_UNUSED(argc)
Q_UNUSED(argv)
// Init test
SKGINITTEST(true)
{
// Test import MNY
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_MNY"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportmny1/A B/money2002.mny"));
QMap<QString, QString> params = imp1.getImportParameters();
params[QStringLiteral("install_sunriise")] = 'Y';
imp1.setImportParameters(params);
SKGTESTERROR(QStringLiteral("imp1.importFile"), imp1.importFile(), true)
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("MNY.setName"), account.setName(QStringLiteral("None Investment")), true)
SKGTESTERROR(QStringLiteral("MNY.load"), account.load(), true)
SKGTEST(QStringLiteral("MNY.getCurrentAmount"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("1.49"))
}
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_MNY"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportmny1/A B/money2002.mny"));
QMap<QString, QString> params = imp1.getImportParameters();
params[QStringLiteral("install_sunriise")] = 'Y';
imp1.setImportParameters(params);
SKGTESTERROR(QStringLiteral("imp1.importFile"), imp1.importFile(), true)
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("MNY.setName"), account.setName(QStringLiteral("None Investment")), true)
SKGTESTERROR(QStringLiteral("MNY.load"), account.load(), true)
SKGTEST(QStringLiteral("MNY.getCurrentAmount"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("1.49"))
}
}
{
// Test import MNY
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_MNY"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportmny1/notreadable.mny"));
QMap<QString, QString> params = imp1.getImportParameters();
params[QStringLiteral("install_sunriise")] = 'Y';
imp1.setImportParameters(params);
SKGTEST(QStringLiteral("imp1.importFile"), imp1.importFile().getReturnCode(), ERR_READACCESS)
}
}
{
// Test import MNY
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_MNY"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportmny3/transfer_and_mode.mny"));
QMap<QString, QString> params = imp1.getImportParameters();
params[QStringLiteral("install_sunriise")] = 'Y';
imp1.setImportParameters(params);
SKGTESTERROR(QStringLiteral("imp1.importFile"), imp1.importFile(), true)
}
bool test2 = false;
SKGTESTERROR(QStringLiteral("MNY.existObjects"), document1.existObjects(QStringLiteral("operation"), QStringLiteral("t_comment='Mode should be ''text''' AND t_mode='text'"), test2), true)
SKGTEST(QStringLiteral("MNY.existObjects-test"), static_cast<unsigned int>(test2), static_cast<unsigned int>(true))
SKGTESTERROR(QStringLiteral("MNY.existObjects"), document1.existObjects(QStringLiteral("operation"), QStringLiteral("t_comment='Number should be 123456' AND t_number='123456'"), test2), true)
SKGTEST(QStringLiteral("MNY.existObjects-test"), static_cast<unsigned int>(test2), static_cast<unsigned int>(true))
SKGTESTERROR(QStringLiteral("MNY.existObjects"), document1.existObjects(QStringLiteral("operation"), QStringLiteral("t_comment='True transfert' AND i_group_id<>0"), test2), true)
SKGTEST(QStringLiteral("MNY.existObjects-test"), static_cast<unsigned int>(test2), static_cast<unsigned int>(true))
SKGTESTERROR(QStringLiteral("MNY.existObjects"), document1.existObjects(QStringLiteral("operation"), QStringLiteral("t_comment='Not a transfert, just same date/amount' AND i_group_id=0"), test2), true)
SKGTEST(QStringLiteral("MNY.existObjects-test"), static_cast<unsigned int>(test2), static_cast<unsigned int>(true))
}
// End test
SKGENDTEST()
}
diff --git a/tests/skgbankmodelertest/skgtestimportmt940.cpp b/tests/skgbankmodelertest/skgtestimportmt940.cpp
index e65fa8b3a..cf6da55fe 100644
--- a/tests/skgbankmodelertest/skgtestimportmt940.cpp
+++ b/tests/skgbankmodelertest/skgtestimportmt940.cpp
@@ -1,174 +1,174 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is a test script.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgtestmacro.h"
#include "skgbankincludes.h"
#include "skgimportexportmanager.h"
/**
* The main function of the unit test
* @param argc the number of arguments
* @param argv the list of arguments
*/
int main(int argc, char** argv)
{
Q_UNUSED(argc)
Q_UNUSED(argv)
// Init test
SKGINITTEST(true)
{
// Test import MT940
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_MT940"), err)
SKGImportExportManager impmissing(&document1, QUrl::fromLocalFile(QStringLiteral("missingfile.mt940")));
SKGTESTERROR(QStringLiteral("imp1.importFile"), impmissing.importFile(), false)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportmt940/test1.mt940"));
SKGTESTERROR(QStringLiteral("MT940.importFile"), imp1.importFile(), true)
}
{
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("MT940.setName"), account.setName(QStringLiteral("NUMERO DE COMPTE IBAN 2")), true)
SKGTESTERROR(QStringLiteral("MT940.load"), account.load(), true)
SKGTEST(QStringLiteral("MT940:getCurrentAmount"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("11.4"))
}
}
{
// Test import MT940
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_MT940"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportmt940/583501.mt940"));
SKGTESTERROR(QStringLiteral("MT940.importFile"), imp1.importFile(), true)
}
{
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("MT940.setName"), account.setName(QStringLiteral("12345.12")), true)
SKGTESTERROR(QStringLiteral("MT940.load"), account.load(), true)
SKGTEST(QStringLiteral("MT940:getCurrentAmount"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("12145.12"))
}
}
{
// Test import MT940
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_MT940"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportmt940/341076.mt940"));
SKGTESTERROR(QStringLiteral("MT940.importFile"), imp1.importFile(), true)
}
{
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("MT940.setName"), account.setName(QStringLiteral("2602272001")), true)
SKGTESTERROR(QStringLiteral("MT940.load"), account.load(), true)
SKGTEST(QStringLiteral("MT940:getCurrentAmount"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("-12.56"))
}
}
{
// Test import MT940
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_MT940"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportmt940/267442_1.mt940"));
SKGTESTERROR(QStringLiteral("MT940.importFile"), imp1.importFile(), true)
}
{
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("MT940.setName"), account.setName(QStringLiteral("55555.55")), true)
SKGTESTERROR(QStringLiteral("MT940.load"), account.load(), true)
SKGTEST(QStringLiteral("MT940:getCurrentAmount"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("1972.1"))
}
}
{
// Test import MT940
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_MT940"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportmt940/267442_2.mt940"));
SKGTESTERROR(QStringLiteral("MT940.importFile"), imp1.importFile(), true)
}
{
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("MT940.setName"), account.setName(QStringLiteral("54842.79")), true)
SKGTESTERROR(QStringLiteral("MT940.load"), account.load(), true)
SKGTEST(QStringLiteral("MT940:getCurrentAmount"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("1030.5"))
}
}
{
// 280897
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_MT940"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportmt940/test1.mt940"));
SKGTESTERROR(QStringLiteral("MT940.importFile"), imp1.importFile(), true)
}
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_MT940"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportmt940/test1.mt940"));
SKGTESTERROR(QStringLiteral("MT940.importFile"), imp1.importFile(), true)
}
{
bool oExist = false;
SKGTESTERROR(QStringLiteral("document1.existObjects"), document1.existObjects(QStringLiteral("operation"), QStringLiteral("rc_unit_id=0"), oExist), true)
SKGTESTBOOL("document1.existObjects", oExist, false)
}
}
// End test
SKGENDTEST()
}
diff --git a/tests/skgbankmodelertest/skgtestimportofx.cpp b/tests/skgbankmodelertest/skgtestimportofx.cpp
index e2fb7a7a5..d79fa6c40 100644
--- a/tests/skgbankmodelertest/skgtestimportofx.cpp
+++ b/tests/skgbankmodelertest/skgtestimportofx.cpp
@@ -1,476 +1,476 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is a test script.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgtestmacro.h"
#include "skgbankincludes.h"
#include "skgimportexportmanager.h"
/**
* The main function of the unit test
* @param argc the number of arguments
* @param argv the list of arguments
*/
int main(int argc, char** argv)
{
Q_UNUSED(argc)
Q_UNUSED(argv)
// Init test
SKGINITTEST(true) {
// Test import OFX skrooge
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_OFX"), err)
SKGImportExportManager impmissing(&document1, QUrl::fromLocalFile(QStringLiteral("missingfile.ofx")));
SKGTESTERROR(QStringLiteral("imp1.importFile"), impmissing.importFile(), false)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportofx/ofx_spec160_stmtrs_example.ofx"));
SKGTESTERROR(QStringLiteral("imp1.importFile"), imp1.importFile(), true)
// document1.dump ( DUMPOPERATION|DUMPACCOUNT );
}
{
// To check double import
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_OFX"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportofx/ofx_spec160_stmtrs_example.ofx"));
SKGTESTERROR(QStringLiteral("imp1.importFile"), imp1.importFile(), true)
}
SKGAccountObject account;
SKGTESTERROR(QStringLiteral("ACCOUNT.getObjectByName"), SKGNamedObject::getObjectByName(&document1, QStringLiteral("v_account"), QStringLiteral("999988"), account), true)
SKGTESTERROR(QStringLiteral("ACCOUNT.load"), account.load(), true)
SKGTEST(QStringLiteral("ACCOUNT:getCurrentAmount"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("200.29"))
}
{
// Test import OFX skrooge
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_OFX"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportofx/ofx_spec201_stmtrs_example.ofx"));
SKGTESTERROR(QStringLiteral("imp1.importFile"), imp1.importFile(), true)
// document1.dump ( DUMPOPERATION|DUMPACCOUNT );
}
SKGAccountObject account;
SKGTESTERROR(QStringLiteral("ACCOUNT.getObjectByName"), SKGNamedObject::getObjectByName(&document1, QStringLiteral("v_account"), QStringLiteral("999988"), account), true)
SKGTESTERROR(QStringLiteral("ACCOUNT.load"), account.load(), true)
SKGTEST(QStringLiteral("ACCOUNT:getCurrentAmount"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("200.29"))
}
{
// Test import OFX skrooge
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_OFX"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportofx/t1.ofx"));
SKGTESTERROR(QStringLiteral("imp1.importFile"), imp1.importFile(), true)
// document1.dump ( DUMPOPERATION|DUMPACCOUNT );
}
SKGAccountObject account;
SKGTESTERROR(QStringLiteral("ACCOUNT.getObjectByName"), SKGNamedObject::getObjectByName(&document1, QStringLiteral("v_account"), QStringLiteral("Investment account 12345 at broker ameritrade.com"), account), true)
SKGTESTERROR(QStringLiteral("ACCOUNT.load"), account.load(), true)
SKGTEST(QStringLiteral("ACCOUNT:getCurrentAmount"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("1672.84"))
}
{
// Test import OFX skrooge
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_OFX"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportofx/385366.ofx"));
SKGTESTERROR(QStringLiteral("imp1.importFile"), imp1.importFile(), true)
// document1.dump ( DUMPOPERATION|DUMPACCOUNT );
}
SKGAccountObject account;
SKGTESTERROR(QStringLiteral("ACCOUNT.getObjectByName"), SKGNamedObject::getObjectByName(&document1, QStringLiteral("v_account"), QStringLiteral("Investment account 209830947 at broker fidelity.com"), account), true)
SKGTESTERROR(QStringLiteral("ACCOUNT.load"), account.load(), true)
SKGTEST(QStringLiteral("ACCOUNT:getCurrentAmount"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("-1.818989404e-12"))
}
{
// Test import OFX skrooge
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_OFX"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportofx/430130.ofx"));
SKGTESTERROR(QStringLiteral("imp1.importFile"), imp1.importFile(), true)
// document1.dump ( DUMPOPERATION|DUMPACCOUNT );
}
SKGAccountObject account;
SKGTESTERROR(QStringLiteral("ACCOUNT.getObjectByName"), SKGNamedObject::getObjectByName(&document1, QStringLiteral("v_account"), QStringLiteral("1234567L123"), account), true)
SKGTESTERROR(QStringLiteral("ACCOUNT.load"), account.load(), true)
SKGTEST(QStringLiteral("ACCOUNT:getCurrentAmount"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("-8238.77"))
}
{
// Test import OFX skrooge
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_OFX"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportofx/ca_remi.ofx"));
SKGTESTERROR(QStringLiteral("imp1.importFile"), imp1.importFile(), true)
// document1.dump ( DUMPOPERATION|DUMPACCOUNT );
}
QStringList oResult;
SKGTESTERROR(QStringLiteral("ACCOUNT:getDistinctValues"), document1.getDistinctValues(QStringLiteral("account"), QStringLiteral("t_name"), oResult), true)
SKGTEST(QStringLiteral("ACCOUNT:oResult.size"), oResult.size(), 5)
/*SKGAccountObject account;
SKGTESTERROR(QStringLiteral("ACCOUNT.getObjectByName"), SKGNamedObject::getObjectByName(&document1,QStringLiteral("v_account"), QStringLiteral("1234567L123"), account), true)
SKGTESTERROR(QStringLiteral("ACCOUNT.load"), account.load(), true)
SKGTEST(QStringLiteral("ACCOUNT:getCurrentAmount"),SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("3366.86"))*/
}
{
// Test import OFX with initial balance
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_OFX"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportofx/initial_balance.ofx"));
SKGTESTERROR(QStringLiteral("imp1.importFile"), imp1.importFile(), true)
// document1.dump ( DUMPOPERATION|DUMPACCOUNT );
}
SKGAccountObject account;
SKGTESTERROR(QStringLiteral("ACCOUNT.getObjectByName"), SKGNamedObject::getObjectByName(&document1, QStringLiteral("v_account"), QStringLiteral("40080030367683"), account), true)
SKGTESTERROR(QStringLiteral("ACCOUNT.load"), account.load(), true)
SKGTEST(QStringLiteral("ACCOUNT:getCurrentAmount"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("5036.46"))
}
{
// Test import OFX with initial balance after rename of account
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Create account
SKGBEGINTRANSACTION(document1, QStringLiteral("CREATE_ACCOUNT"), err)
SKGTESTERROR(QStringLiteral("DOC.addOrModifyAccount"), document1.addOrModifyAccount(QStringLiteral("COURANT"), QStringLiteral("111111"), QStringLiteral("BANK")), true)
}
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_OFX"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportofx/bug_statement.ofx"));
SKGTESTERROR(QStringLiteral("imp1.importFile"), imp1.importFile(), true)
// document1.dump ( DUMPOPERATION|DUMPACCOUNT );
}
SKGAccountObject account;
SKGTESTERROR(QStringLiteral("ACCOUNT.getObjectByName"), SKGNamedObject::getObjectByName(&document1, QStringLiteral("v_account"), QStringLiteral("COURANT"), account), true)
SKGTESTERROR(QStringLiteral("ACCOUNT.load"), account.load(), true)
SKGTEST(QStringLiteral("ACCOUNT:getCurrentAmount"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("7645.86"))
}
{
// Test BUG 234771
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Create an account without number
SKGBEGINTRANSACTION(document1, QStringLiteral("CREATE_ACCOUNT"), err)
SKGTESTERROR(QStringLiteral("DOC.addOrModifyAccount"), document1.addOrModifyAccount(QStringLiteral("COURANT"), QLatin1String(""), QStringLiteral("BANK")), true)
}
{
// Create an account without number
SKGBEGINTRANSACTION(document1, QStringLiteral("CREATE_ACCOUNT"), err)
SKGTESTERROR(QStringLiteral("DOC.addOrModifyAccount"), document1.addOrModifyAccount(QStringLiteral("COURANT2"), QLatin1String(""), QStringLiteral("BANK")), true)
}
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_OFX"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportofx/234771.ofx"));
SKGTESTERROR(QStringLiteral("imp1.importFile"), imp1.importFile(), true)
// document1.dump ( DUMPOPERATION|DUMPACCOUNT );
}
// Test BUG 319706
bool existMode = false;
SKGTESTERROR(QStringLiteral("doc.existObjects"), document1.existObjects(QStringLiteral("operation"), QStringLiteral("t_mode<>''"), existMode), true)
SKGTESTBOOL("doc.existMode", existMode, true)
}
{
// Test UTF-8 - 284843
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_OFX"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportofx/284843.ofx"));
SKGTESTERROR(QStringLiteral("imp1.importFile"), imp1.importFile(), true)
}
int nb = 0;
SKGTESTERROR(QStringLiteral("PAYEE.getNbObjects"), document1.getNbObjects(QStringLiteral("v_payee"), "t_name='" % QStringLiteral("カ-ド") % "'", nb), true)
SKGTEST(QStringLiteral("PAYEE.getNbObjects"), nb, 1)
document1.dump(DUMPPAYEE);
}
{
// Test UTF-8
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_OFX"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportofx/UTF8.ofx"));
SKGTESTERROR(QStringLiteral("imp1.importFile"), imp1.importFile(), true)
}
}
{
// Test 255133
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_OFX"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportofx/exception.ofx"));
SKGTESTERROR(QStringLiteral("imp1.importFile"), imp1.importFile(), true)
}
}
{
// Test import OFX skrooge
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_OFX"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportofx/missing_file.ofx"));
SKGTESTERROR(QStringLiteral("imp1.importFile"), imp1.importFile(), false)
}
}
{
// Test export OFX skrooge
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGImportExportManager exp(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("OUT")) % "/skgtestimportofx/export.ofx"));
SKGTESTERROR(QStringLiteral("imp1.exportFile"), exp.exportFile(), false)
}
}
{
// Test 336320
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_OFX"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportofx/336320.ofx"));
SKGTESTERROR(QStringLiteral("imp1.importFile"), imp1.importFile(), true)
}
int nb1 = 0;
SKGTESTERROR(QStringLiteral("PAYEE.getNbObjects"), document1.getNbObjects(QStringLiteral("operation"), QLatin1String(""), nb1), true)
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_OFX"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportofx/336320.ofx"));
SKGTESTERROR(QStringLiteral("imp1.importFile"), imp1.importFile(), true)
}
int nb2 = 0;
SKGTESTERROR(QStringLiteral("PAYEE.getNbObjects"), document1.getNbObjects(QStringLiteral("operation"), QLatin1String(""), nb2), true)
SKGTEST(QStringLiteral("PAYEE.getNbObjects"), nb1, nb2)
}
{
// Test handling of debit amount with wrong sign
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_OFX"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportofx/debit_pos.ofx"));
SKGTESTERROR(QStringLiteral("imp1.importFile"), imp1.importFile(), true)
}
bool existDebitPos = false;
SKGTESTERROR(QStringLiteral("doc.existObjects"), document1.existObjects(QStringLiteral("v_operation"), QStringLiteral("t_mode='Debit' and f_currentamount>0"), existDebitPos), true)
SKGTESTBOOL("doc.existDebitPos", existDebitPos, false)
}
{
// Test import OFX with missing id on transactions (Theo Raves)
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_OFX"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportofx/mut.ofx"));
SKGTESTERROR(QStringLiteral("imp1.importFile"), imp1.importFile(), true)
}
SKGAccountObject account;
SKGTESTERROR(QStringLiteral("ACCOUNT.getObjectByName"), SKGNamedObject::getObjectByName(&document1, QStringLiteral("v_account"), QStringLiteral("11111111000"), account), true)
SKGTESTERROR(QStringLiteral("ACCOUNT.load"), account.load(), true)
SKGTEST(QStringLiteral("ACCOUNT:getCurrentAmount"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("-12.34"))
}
{
// Test import OFX from GNUCASH fr Android
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_OFX"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportofx/20150818_133327_gnucash_export.ofx"));
SKGTESTERROR(QStringLiteral("imp1.importFile"), imp1.importFile(), true)
}
}
{
// Test import OFX from GNUCASH fr Android
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_OFX"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportofx/FEE.ofx"));
SKGTESTERROR(QStringLiteral("imp1.importFile"), imp1.importFile(), true)
}
SKGAccountObject account;
SKGTESTERROR(QStringLiteral("ACCOUNT.getObjectByName"), SKGNamedObject::getObjectByName(&document1, QStringLiteral("v_account"), QStringLiteral("1234567L123"), account), true)
SKGTESTERROR(QStringLiteral("ACCOUNT.load"), account.load(), true)
SKGTEST(QStringLiteral("ACCOUNT:getCurrentAmount"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("-18294.69"))
}
{
// 406321
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.load()"), document1.load(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportofx/406321.skg"), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_OFX"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportofx/406321.ofx"));
SKGTESTERROR(QStringLiteral("imp1.importFile"), imp1.importFile(), true)
}
// 406741
int nb2 = 0;
SKGTESTERROR(QStringLiteral("imp1.getNbObjects"), document1.getNbObjects(QStringLiteral("operation"), QStringLiteral("d_date>'2000-01-01'"), nb2), true)
SKGTEST(QStringLiteral("OPERATION:nb"), SKGServices::intToString(nb2), QStringLiteral("5"))
}
{
// 406321
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.load()"), document1.load(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportofx/406321.skg"), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_OFX"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportofx/406321_2.ofx"));
SKGTESTERROR(QStringLiteral("imp1.importFile"), imp1.importFile(), true)
}
}
{
// 412494
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_OFX"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportofx/412494.qfx"));
SKGTESTERROR(QStringLiteral("imp1.importFile"), imp1.importFile(), true)
SKGDocument::SKGMessageList messages;
SKGTESTERROR(QStringLiteral("imp1.getMessages"), document1.getMessages(document1.getCurrentTransaction(), messages, true), true)
bool test = false;
for (const auto& msg : qAsConst(messages)) {
SKGTRACE << "Message:" << msg.Text << endl;
if (msg.Text.contains(QStringLiteral("0 operations imported"))) {
test = true;
}
}
SKGTEST(QStringLiteral("message.0 operations imported"), static_cast<unsigned int>(test), 1)
}
}
// End test
SKGENDTEST()
}
diff --git a/tests/skgbankmodelertest/skgtestimportpdf.cpp b/tests/skgbankmodelertest/skgtestimportpdf.cpp
index 05c4a6a0f..60af138c4 100644
--- a/tests/skgbankmodelertest/skgtestimportpdf.cpp
+++ b/tests/skgbankmodelertest/skgtestimportpdf.cpp
@@ -1,71 +1,71 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is a test script.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgtestmacro.h"
#include "skgbankincludes.h"
#include "skgimportexportmanager.h"
/**
* The main function of the unit test
* @param argc the number of arguments
* @param argv the list of arguments
*/
int main(int argc, char** argv)
{
Q_UNUSED(argc)
Q_UNUSED(argv)
// Init test
SKGINITTEST(true) {
// Test import PDF skrooge
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_PDF"), err)
QString dir = SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportpdf/";
auto listFiles = QDir(dir).entryList(QStringList() << QStringLiteral("*.pdf"), QDir::Files, QDir::Name);
for (const auto& file : listFiles) {
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(dir % file));
SKGTESTERROR(QStringLiteral("imp1.importFile"), imp1.importFile(), true)
}
document1.dump(DUMPOPERATION | DUMPACCOUNT);
}
SKGAccountObject account;
SKGTESTERROR(QStringLiteral("ACCOUNT.getObjectByName"), SKGNamedObject::getObjectByName(&document1, QStringLiteral("v_account"), QStringLiteral("Facture allopneus"), account), true)
SKGTESTERROR(QStringLiteral("ACCOUNT.load"), account.load(), true)
SKGTEST(QStringLiteral("ACCOUNT:getCurrentAmount"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("-2041.24"))
int nb = 0;
SKGTESTERROR(QStringLiteral("DOC:getNbObjects"), document1.getNbObjects(QStringLiteral("operation"), QLatin1String(""), nb), true)
SKGTEST(QStringLiteral("DOC:getNbObjects"), nb, 11)
SKGTESTERROR(QStringLiteral("DOC:getNbObjects"), document1.getNbObjects(QStringLiteral("operation"), QStringLiteral("d_date='") + SKGServices::dateToSqlString(QDate::currentDate()) + '\'', nb), true)
SKGTEST(QStringLiteral("DOC:getNbObjects"), nb, 0)
}
// End test
SKGENDTEST()
}
diff --git a/tests/skgbankmodelertest/skgtestimportqif1.cpp b/tests/skgbankmodelertest/skgtestimportqif1.cpp
index e36c55712..27b86f5a8 100644
--- a/tests/skgbankmodelertest/skgtestimportqif1.cpp
+++ b/tests/skgbankmodelertest/skgtestimportqif1.cpp
@@ -1,847 +1,847 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is a test script.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgtestmacro.h"
#include "skgbankincludes.h"
#include "skgimportexportmanager.h"
/**
* The main function of the unit test
* @param argc the number of arguments
* @param argv the list of arguments
*/
int main(int argc, char** argv)
{
Q_UNUSED(argc)
Q_UNUSED(argv)
// Init test
SKGINITTEST(true)
QDate d(1970, 1, 1);
{
// Test import QIF 1
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGBankObject bank(&document1);
SKGAccountObject account;
SKGUnitObject unit_euro(&document1);
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_INIT"), err)
SKGImportExportManager impmissing(&document1, QUrl::fromLocalFile(QStringLiteral("missingfile.qif")));
SKGTESTERROR(QStringLiteral("imp1.importFile"), impmissing.importFile(), false)
SKGImportExportManager::getParameterDefaultValue(QStringLiteral("mapping_date"));
// Creation bank
SKGTESTERROR(QStringLiteral("BANK:setName"), bank.setName(QStringLiteral("CREDIT COOP")), true)
SKGTESTERROR(QStringLiteral("BANK:setNumber"), bank.setNumber(QStringLiteral("0003")), true)
SKGTESTERROR(QStringLiteral("BANK:save"), bank.save(), true)
// Creation account
SKGTESTERROR(QStringLiteral("BANK:addAccount"), bank.addAccount(account), true)
SKGTESTERROR(QStringLiteral("ACCOUNT:setName"), account.setName(QStringLiteral("Courant steph")), true)
SKGTESTERROR(QStringLiteral("ACCOUNT:setNumber"), account.setNumber(QStringLiteral("12345P")), true)
SKGTESTERROR(QStringLiteral("ACCOUNT:setAgencyNumber"), account.setAgencyNumber(QStringLiteral("98765")), true)
SKGTESTERROR(QStringLiteral("ACCOUNT:setAgencyNumber"), account.setAgencyAddress(QStringLiteral("10 rue Dupon, 31000 TOULOUSE")), true)
SKGTESTERROR(QStringLiteral("ACCOUNT:save"), account.save(), true)
// Creation unit
SKGTESTERROR(QStringLiteral("UNIT:setName"), unit_euro.setName(QStringLiteral("euro")), true)
SKGTESTERROR(QStringLiteral("UNIT:save"), unit_euro.save(), true)
// Creation unitvalue
SKGUnitValueObject unit_euro_val1;
SKGTESTERROR(QStringLiteral("UNIT:addUnitValue"), unit_euro.addUnitValue(unit_euro_val1), true)
SKGTESTERROR(QStringLiteral("UNITVALUE:setQuantity"), unit_euro_val1.setQuantity(1), true)
SKGTESTERROR(QStringLiteral("UNITVALUE:setDate"), unit_euro_val1.setDate(d), true)
SKGTESTERROR(QStringLiteral("UNITVALUE:save"), unit_euro_val1.save(), true)
}
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_BP_QIF"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportqif1/ref.qif"));
SKGTESTERROR(QStringLiteral("QIF.setDefaultAccount"), imp1.setDefaultAccount(&account), true)
SKGTESTERROR(QStringLiteral("QIF.setDefaultUnit"), imp1.setDefaultUnit(&unit_euro), true)
SKGTESTERROR(QStringLiteral("QIF.importFile"), imp1.importFile(), true)
}
SKGTESTERROR(QStringLiteral("ACCOUNT:load"), account.load(), true)
SKGTEST(QStringLiteral("ACCOUNT:getCurrentAmount"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("-935"))
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_BP_QIF"), err)
SKGImportExportManager imp1(&document1);
SKGTESTERROR(QStringLiteral("QIF.cleanBankImport"), imp1.cleanBankImport(), true)
int out = 0;
SKGTESTERROR(QStringLiteral("QIF.findAndGroupTransfers"), imp1.findAndGroupTransfers(out), true)
SKGImportExportManager exp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("OUT")) % "/skgtestimportqif1/ref.qif"));
SKGTESTERROR(QStringLiteral("QIF.exportFile"), exp1.exportFile(), true)
}
SKGTESTERROR(QStringLiteral("ACCOUNT:load"), account.load(), true)
SKGTEST(QStringLiteral("ACCOUNT:getCurrentAmount"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("-935"))
}
{
// Test import QIF 2
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGBankObject bank(&document1);
SKGAccountObject account;
SKGUnitObject unit_euro(&document1);
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_INIT"), err)
// Creation bank
SKGTESTERROR(QStringLiteral("BANK:setName"), bank.setName(QStringLiteral("CREDIT COOP")), true)
SKGTESTERROR(QStringLiteral("BANK:save"), bank.save(), true)
// Creation account
SKGTESTERROR(QStringLiteral("BANK:addAccount"), bank.addAccount(account), true)
SKGTESTERROR(QStringLiteral("ACCOUNT:setName"), account.setName(QStringLiteral("Courant Guillaume")), true)
SKGTESTERROR(QStringLiteral("ACCOUNT:setNumber"), account.setNumber(QStringLiteral("98765A")), true)
SKGTESTERROR(QStringLiteral("ACCOUNT:save"), account.save(), true)
// Creation unit
SKGTESTERROR(QStringLiteral("UNIT:setName"), unit_euro.setName(QStringLiteral("euro")), true)
SKGTESTERROR(QStringLiteral("UNIT:save"), unit_euro.save(), true)
// Creation unitvalue
SKGUnitValueObject unit_euro_val1;
SKGTESTERROR(QStringLiteral("UNIT:addUnitValue"), unit_euro.addUnitValue(unit_euro_val1), true)
SKGTESTERROR(QStringLiteral("UNITVALUE:setQuantity"), unit_euro_val1.setQuantity(1), true)
SKGTESTERROR(QStringLiteral("UNITVALUE:setDate"), unit_euro_val1.setDate(d), true)
SKGTESTERROR(QStringLiteral("UNITVALUE:save"), unit_euro_val1.save(), true)
}
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_BP_QIF"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportqif1/E0269787.qif"));
SKGTESTERROR(QStringLiteral("QIF.setDefaultAccount"), imp1.setDefaultAccount(&account), true)
SKGTESTERROR(QStringLiteral("QIF.setDefaultUnit"), imp1.setDefaultUnit(&unit_euro), true)
SKGTESTERROR(QStringLiteral("QIF.importFile"), imp1.importFile(), true)
SKGTESTERROR(QStringLiteral("QIF.cleanBankImport"), imp1.cleanBankImport(), true)
int out = 0;
SKGTESTERROR(QStringLiteral("QIF.findAndGroupTransfers"), imp1.findAndGroupTransfers(out), true)
SKGImportExportManager exp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("OUT")) % "/skgtestimportqif1/E0269787.qif"));
SKGTESTERROR(QStringLiteral("QIF.exportFile"), exp1.exportFile(), true)
}
SKGTESTERROR(QStringLiteral("ACCOUNT:load"), account.load(), true)
SKGTEST(QStringLiteral("ACCOUNT:getCurrentAmount"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("-1684.58"))
// Check import with account retrieved from file
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
unit_euro = SKGUnitObject(&document1);
{
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_INIT"), err)
// Creation unit
SKGTESTERROR(QStringLiteral("UNIT:setName"), unit_euro.setName(QStringLiteral("euro")), true)
SKGTESTERROR(QStringLiteral("UNIT:save"), unit_euro.save(), true)
// Creation unitvalue
SKGUnitValueObject unit_euro_val1;
SKGTESTERROR(QStringLiteral("UNIT:addUnitValue"), unit_euro.addUnitValue(unit_euro_val1), true)
SKGTESTERROR(QStringLiteral("UNITVALUE:setQuantity"), unit_euro_val1.setQuantity(1), true)
SKGTESTERROR(QStringLiteral("UNITVALUE:setDate"), unit_euro_val1.setDate(d), true)
SKGTESTERROR(QStringLiteral("UNITVALUE:save"), unit_euro_val1.save(), true)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("OUT")) % "/skgtestimportqif1/E0269787.qif"));
SKGTESTERROR(QStringLiteral("QIF.importFile"), imp1.importFile(), true)
SKGTESTERROR(QStringLiteral("QIF.cleanBankImport"), imp1.cleanBankImport(), true)
int out = 0;
SKGTESTERROR(QStringLiteral("QIF.findAndGroupTransfers"), imp1.findAndGroupTransfers(out), true)
SKGImportExportManager exp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("OUT")) % "/skgtestimportqif1/E0269787_bis.qif"));
SKGTESTERROR(QStringLiteral("QIF.exportFile"), exp1.exportFile(), true)
}
// Check multi import
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true) {
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("OUT")) % "/skgtestimportqif1/ref.qif"));
SKGTESTERROR(QStringLiteral("QIF.importFile"), imp1.importFile(), true)
SKGTESTERROR(QStringLiteral("QIF.importFile"), imp1.importFile(), true) // Double import
SKGTESTERROR(QStringLiteral("QIF.cleanBankImport"), imp1.cleanBankImport(), true)
int out = 0;
SKGTESTERROR(QStringLiteral("QIF.findAndGroupTransfers"), imp1.findAndGroupTransfers(out), true)
}
// Check import with account retrieved from files
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true) {
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("OUT")) % "/skgtestimportqif1/ref.qif"));
SKGTESTERROR(QStringLiteral("QIF.importFile"), imp1.importFile(), true)
SKGImportExportManager imp2(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("OUT")) % "/skgtestimportqif1/E0269787.qif"));
SKGTESTERROR(QStringLiteral("QIF.importFile"), imp2.importFile(), true)
SKGTESTERROR(QStringLiteral("QIF.cleanBankImport"), imp1.cleanBankImport(), true)
int out = 0;
SKGTESTERROR(QStringLiteral("QIF.findAndGroupTransfers"), imp1.findAndGroupTransfers(out), true)
SKGImportExportManager exp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("OUT")) % "/skgtestimportqif1/E0269787_ref.qif"));
SKGTESTERROR(QStringLiteral("QIF.exportFile"), exp1.exportFile(), true)
}
// Check import qif multi accounts
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true) {
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("OUT")) % "/skgtestimportqif1/E0269787_ref.qif"));
SKGTESTERROR(QStringLiteral("QIF.importFile"), imp1.importFile(), true)
SKGTESTERROR(QStringLiteral("QIF.cleanBankImport"), imp1.cleanBankImport(), true)
int out = 0;
SKGTESTERROR(QStringLiteral("QIF.findAndGroupTransfers"), imp1.findAndGroupTransfers(out), true)
QStringList oResult;
SKGTESTERROR(QStringLiteral("ACCOUNT:getDistinctValues"), document1.getDistinctValues(QStringLiteral("account"), QStringLiteral("t_name"), oResult), true)
SKGTEST(QStringLiteral("ACCOUNT:oResult.size"), oResult.size(), 3)
}
}
{
// Test import QIF 2
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGBankObject bank(&document1);
SKGAccountObject account;
SKGUnitObject unit_euro(&document1);
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_INIT"), err)
// Creation bank
SKGTESTERROR(QStringLiteral("BANK:setName"), bank.setName(QStringLiteral("ING")), true)
SKGTESTERROR(QStringLiteral("BANK:save"), bank.save(), true)
// Creation account
SKGTESTERROR(QStringLiteral("BANK:addAccount"), bank.addAccount(account), true)
SKGTESTERROR(QStringLiteral("ACCOUNT:setName"), account.setName(QStringLiteral("ING")), true)
SKGTESTERROR(QStringLiteral("ACCOUNT:setNumber"), account.setNumber(QStringLiteral("ING")), true)
SKGTESTERROR(QStringLiteral("ACCOUNT:save"), account.save(), true)
// Creation unit
SKGTESTERROR(QStringLiteral("UNIT:setName"), unit_euro.setName(QStringLiteral("euro")), true)
SKGTESTERROR(QStringLiteral("UNIT:save"), unit_euro.save(), true)
// Creation unitvalue
SKGUnitValueObject unit_euro_val1;
SKGTESTERROR(QStringLiteral("UNIT:addUnitValue"), unit_euro.addUnitValue(unit_euro_val1), true)
SKGTESTERROR(QStringLiteral("UNITVALUE:setQuantity"), unit_euro_val1.setQuantity(1), true)
SKGTESTERROR(QStringLiteral("UNITVALUE:setDate"), unit_euro_val1.setDate(d), true)
SKGTESTERROR(QStringLiteral("UNITVALUE:save"), unit_euro_val1.save(), true)
}
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_ING_QIF"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportqif1/ing.qif"));
SKGTESTERROR(QStringLiteral("QIF.setDefaultAccount"), imp1.setDefaultAccount(&account), true)
SKGTESTERROR(QStringLiteral("QIF.setDefaultUnit"), imp1.setDefaultUnit(&unit_euro), true)
SKGTESTERROR(QStringLiteral("QIF.importFile"), imp1.importFile(), true)
SKGTESTERROR(QStringLiteral("QIF.cleanBankImport"), imp1.cleanBankImport(), true)
int out = 0;
SKGTESTERROR(QStringLiteral("QIF.findAndGroupTransfers"), imp1.findAndGroupTransfers(out), true)
SKGImportExportManager exp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("OUT")) % "/skgtestimportqif1/ing.qif"));
SKGTESTERROR(QStringLiteral("QIF.exportFile"), exp1.exportFile(), true)
}
}
{
// Test import QIF MOTO
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_ING_QIF"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportqif1/moto.qif"));
SKGTESTERROR(QStringLiteral("QIF.importFile"), imp1.importFile(), true)
}
{
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("QIF.setName"), account.setName(QStringLiteral("ACTIF Moto")), true)
SKGTESTERROR(QStringLiteral("QIF.load"), account.load(), true)
SKGTEST(QStringLiteral("QIF:getValue"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("26198.77"))
}
}
{
// Test import QIF MOTO with euro and franc
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_INIT"), err)
SKGUnitObject unit;
SKGTESTERROR(QStringLiteral("SKGUnitObject::createCurrencyUnit"), SKGUnitObject::createCurrencyUnit(&document1, QStringLiteral("EUR"), unit), true)
SKGTESTERROR(QStringLiteral("SKGUnitObject::createCurrencyUnit"), SKGUnitObject::createCurrencyUnit(&document1, QStringLiteral("FRF"), unit), true)
SKGTESTERROR(QStringLiteral("FRANC.addOrModifyUnitValue"), document1.addOrModifyUnitValue(QStringLiteral("French Franc (FRF)"), QDate(1963, 1, 1), 1.0 / 6.55957), true)
}
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_ING_QIF"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportqif1/moto.qif"));
SKGTESTERROR(QStringLiteral("QIF.importFile"), imp1.importFile(), true)
}
{
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("QIF.setName"), account.setName(QStringLiteral("ACTIF Moto")), true)
SKGTESTERROR(QStringLiteral("QIF.load"), account.load(), true)
SKGTEST(QStringLiteral("QIF:getValue"), SKGServices::doubleToString(static_cast<int>(account.getCurrentAmount())), QStringLiteral("5009"))
}
}
{
// Test import QIF KMM
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_KMM_QIF"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportqif1/kmm-without-category.qif"));
SKGTESTERROR(QStringLiteral("QIF.importFile"), imp1.importFile(), true)
}
{
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("QIF.setName"), account.setName(QStringLiteral("CCP")), true)
SKGTESTERROR(QStringLiteral("QIF.load"), account.load(), true)
SKGTEST(QStringLiteral("QIF:getValue"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("-52.36"))
}
}
{
// Test import QIF KMM with category
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_KMM_QIF"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportqif1/kmm-with-category.qif"));
SKGTESTERROR(QStringLiteral("QIF.importFile"), imp1.importFile(), true)
}
{
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("QIF.setName"), account.setName(QStringLiteral("CCP")), true)
SKGTESTERROR(QStringLiteral("QIF.load"), account.load(), true)
SKGTEST(QStringLiteral("QIF:getValue"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("-52.36"))
}
}
{
// Test import QIF REMI in double to check merge
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_REMI_QIF"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportqif1/remi_2.qif"));
SKGTESTERROR(QStringLiteral("QIF.importFile"), imp1.importFile(), true)
}
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_REMI_QIF"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportqif1/remi_2.qif"));
SKGTESTERROR(QStringLiteral("QIF.importFile"), imp1.importFile(), true)
}
{
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("QIF.setName"), account.setName(QStringLiteral("remi 2")), true)
SKGTESTERROR(QStringLiteral("QIF.load"), account.load(), true)
SKGTEST(QStringLiteral("QIF:getValue"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("-1208.63"))
}
}
{
// Test import QIF REMI in double to check merge
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_DOUBLE"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportqif1/double.qif"));
SKGTESTERROR(QStringLiteral("QIF.importFile"), imp1.importFile(), true)
}
{
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("QIF.setName"), account.setName(QStringLiteral("double")), true)
SKGTESTERROR(QStringLiteral("QIF.load"), account.load(), true)
SKGTEST(QStringLiteral("QIF:getValue"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("-243"))
}
}
{
// Test import bug GNUCash 350286
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportqif1/350286.qif"));
SKGTESTERROR(QStringLiteral("QIF.importFile"), imp1.importFile(), true)
}
{
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("QIF.setName"), account.setName(QStringLiteral("350286")), true)
SKGTESTERROR(QStringLiteral("QIF.load"), account.load(), true)
SKGTEST(QStringLiteral("QIF:getValue"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("1057.37"))
}
}
{
// Test import bug GNUCash 393596
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportqif1/393596.qif"));
SKGTESTERROR(QStringLiteral("QIF.importFile"), imp1.importFile(), true)
}
{
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("QIF.setName"), account.setName(QStringLiteral("393596")), true)
SKGTESTERROR(QStringLiteral("QIF.load"), account.load(), true)
SKGTEST(QStringLiteral("QIF:getValue"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("12.34"))
}
}
{
// Test import bug GNUCash 503166
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportqif1/503166.qif"));
SKGTESTERROR(QStringLiteral("QIF.importFile"), imp1.importFile(), true)
}
{
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("QIF.setName"), account.setName(QStringLiteral("My Investments")), true)
SKGTESTERROR(QStringLiteral("QIF.load"), account.load(), true)
SKGTEST(QStringLiteral("QIF:getValue"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("20"))
}
}
{
// Test import bug GNUCash 392707
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportqif1/392707.qif"));
SKGTESTERROR(QStringLiteral("QIF.importFile"), imp1.importFile(), true)
}
{
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("QIF.setName"), account.setName(QStringLiteral("392707")), true)
SKGTESTERROR(QStringLiteral("QIF.load"), account.load(), true)
SKGTEST(QStringLiteral("QIF:getValue"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("1219.06"))
}
}
{
// Test import bug GNUCash 373584
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportqif1/373584.qif"));
SKGTESTERROR(QStringLiteral("QIF.importFile"), imp1.importFile(), true)
}
{
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("QIF.setName"), account.setName(QStringLiteral("My Investments")), true)
SKGTESTERROR(QStringLiteral("QIF.load"), account.load(), true)
SKGTEST(QStringLiteral("QIF:getValue"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("1000000"))
}
}
{
// Test import bug 199818
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportqif1/199818.qif"));
SKGTESTERROR(QStringLiteral("QIF.importFile"), imp1.importFile(), true)
}
{
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("QIF.setName"), account.setName(QStringLiteral("199818")), true)
SKGTESTERROR(QStringLiteral("QIF.load"), account.load(), true)
SKGTEST(QStringLiteral("QIF:getValue"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("-345.64"))
}
}
{
// Test import bug 201316
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportqif1/201316.qif"));
SKGTESTERROR(QStringLiteral("QIF.importFile"), imp1.importFile(), true)
}
{
SKGStringListList listTmp;
SKGTESTERROR(QStringLiteral("QIF.executeSelectSqliteOrder"), document1.executeSelectSqliteOrder(
QStringLiteral("SELECT TOTAL(f_CURRENTAMOUNT),t_status FROM v_operation_display GROUP BY t_status ORDER BY t_status"), listTmp), true);
SKGTEST(QStringLiteral("QIF:listTmp.count"), listTmp.count(), 4)
if (listTmp.count() == 4) {
SKGTEST(QStringLiteral("QIF:listTmp.at(1).at(0)"), listTmp.at(1).at(0), QStringLiteral("-10"))
SKGTEST(QStringLiteral("QIF:listTmp.at(2).at(0)"), listTmp.at(2).at(0), QStringLiteral("-100"))
SKGTEST(QStringLiteral("QIF:listTmp.at(3).at(0)"), listTmp.at(3).at(0), QStringLiteral("-1000"))
}
}
}
{
// Test import bug 201451
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportqif1/201451.qif"));
SKGTESTERROR(QStringLiteral("QIF.importFile"), imp1.importFile(), true)
}
{
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("QIF.setName"), account.setName(QStringLiteral("liability")), true)
SKGTESTERROR(QStringLiteral("QIF.load"), account.load(), true)
SKGTEST(QStringLiteral("QIF:getValue"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("-123.45"))
}
}
{
// Test import bug 214809
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportqif1/BNP_CC_virement.qif"));
SKGTESTERROR(QStringLiteral("QIF.importFile"), imp1.importFile(), true)
}
{
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("QIF.setName"), account.setName(QStringLiteral("BNP CC")), true)
SKGTESTERROR(QStringLiteral("QIF.load"), account.load(), true)
SKGTEST(QStringLiteral("QIF:getValue"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("696.64"))
}
{
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("QIF.setName"), account.setName(QStringLiteral("BNP CEL")), true)
SKGTESTERROR(QStringLiteral("QIF.load"), account.load(), true)
SKGTEST(QStringLiteral("QIF:getValue"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("500"))
}
}
{
// Test import bug 214851
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportqif1/Fortuneo PEA (Caisse).qif"));
SKGTESTERROR(QStringLiteral("QIF.importFile"), imp1.importFile(), true)
SKGImportExportManager imp2(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportqif1/Fortuneo PEA.qif"));
SKGTESTERROR(QStringLiteral("QIF.importFile"), imp2.importFile(), true)
}
{
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("QIF.setName"), account.setName(QStringLiteral("BNP CC")), true)
SKGTESTERROR(QStringLiteral("QIF.load"), account.load(), true)
SKGTEST(QStringLiteral("QIF:getValue"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("-3604"))
}
{
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("QIF.setName"), account.setName(QStringLiteral("Fortuneo PEA")), true)
SKGTESTERROR(QStringLiteral("QIF.load"), account.load(), true)
SKGTEST(QStringLiteral("QIF:getValue"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("86.29"))
}
{
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("QIF.setName"), account.setName(QStringLiteral("Fortuneo PEA (Caisse)")), true)
SKGTESTERROR(QStringLiteral("QIF.load"), account.load(), true)
SKGTEST(QStringLiteral("QIF:getValue"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("10319.5"))
}
{
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("QIF.setName"), account.setName(QStringLiteral("Fortuneo Titres (Caisse)")), true)
SKGTESTERROR(QStringLiteral("QIF.load"), account.load(), true)
SKGTEST(QStringLiteral("QIF:getValue"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("-6700"))
}
}
{
// Test import bug 215620
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportqif1/Cortal PEA.qif"));
SKGTESTERROR(QStringLiteral("QIF.importFile"), imp1.importFile(), true)
SKGImportExportManager imp2(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportqif1/EADS.qif"));
SKGTESTERROR(QStringLiteral("QIF.importFile"), imp2.importFile(), true)
}
}
{
// Test import bug 216520
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportqif1/216520.qif"));
SKGTESTERROR(QStringLiteral("QIF.importFile"), imp1.importFile(), true)
}
{
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("QIF.setName"), account.setName(QStringLiteral("BNP CC")), true)
SKGTESTERROR(QStringLiteral("QIF.load"), account.load(), true)
SKGTEST(QStringLiteral("QIF:getValue"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("11196.64"))
}
}
{
// Test import investment
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_INIT"), err)
SKGUnitObject unit;
SKGTESTERROR(QStringLiteral("EUR.setName"), SKGUnitObject::createCurrencyUnit(&document1, QStringLiteral("Euro (EUR)"), unit), true)
}
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportqif1/exp_inv.qif"));
imp1.setCodec(QStringLiteral("UTF-8"));
SKGTESTERROR(QStringLiteral("QIF.importFile"), imp1.importFile(), true)
SKGImportExportManager exp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("OUT")) % "/skgtestimportqif1/exp_inv.qif"));
exp1.setCodec(QStringLiteral("UTF-8"));
SKGTESTERROR(QStringLiteral("QIF.exportFile"), exp1.exportFile(), true)
}
}
{
// Test transfer qif
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportqif1/t2.qif"));
SKGTESTERROR(QStringLiteral("QIF.importFile"), imp1.importFile(), true)
}
{
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("QIF.setName"), account.setName(QStringLiteral("COURANT")), true)
SKGTESTERROR(QStringLiteral("QIF.load"), account.load(), true)
SKGTEST(QStringLiteral("QIF:getValue"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("4767.97"))
}
{
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("QIF.setName"), account.setName(QStringLiteral("CODEVI")), true)
SKGTESTERROR(QStringLiteral("QIF.load"), account.load(), true)
SKGTEST(QStringLiteral("QIF:getValue"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("-4767.97"))
}
}
{
// 233930
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportqif1/233930.qif"));
SKGTESTERROR(QStringLiteral("QIF.importFile"), imp1.importFile(), true)
}
}
{
// Quicken
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportqif1/quicken.qif"));
SKGTESTERROR(QStringLiteral("QIF.importFile"), imp1.importFile(), true)
}
}
{
// 267996
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportqif1/267996.qif"));
SKGTESTERROR(QStringLiteral("QIF.importFile"), imp1.importFile(), true)
}
{
SKGImportExportManager exp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("OUT")) % "/skgtestimportqif1/267996.csv"));
SKGTESTERROR(QStringLiteral("QIF.exportFile"), exp1.exportFile(), true)
}
}
{
// 271708
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT"), err)
{
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportqif1/271708/10Compte A.qif"));
SKGTESTERROR(QStringLiteral("QIF.importFile"), imp1.importFile(), true)
}
{
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportqif1/271708/20Compte B.qif"));
SKGTESTERROR(QStringLiteral("QIF.importFile"), imp1.importFile(), true)
}
{
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportqif1/271708/30Compte C.qif"));
SKGTESTERROR(QStringLiteral("QIF.importFile"), imp1.importFile(), true)
}
{
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportqif1/271708/40Compte D.qif"));
SKGTESTERROR(QStringLiteral("QIF.importFile"), imp1.importFile(), true)
}
}
{
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("QIF.setName"), account.setName(QStringLiteral("10Compte A")), true)
SKGTESTERROR(QStringLiteral("QIF.load"), account.load(), true)
SKGTEST(QStringLiteral("QIF:getValue"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("0"))
}
{
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("QIF.setName"), account.setName(QStringLiteral("20Compte B")), true)
SKGTESTERROR(QStringLiteral("QIF.load"), account.load(), true)
SKGTEST(QStringLiteral("QIF:getValue"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("10"))
}
{
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("QIF.setName"), account.setName(QStringLiteral("30Compte C")), true)
SKGTESTERROR(QStringLiteral("QIF.load"), account.load(), true)
SKGTEST(QStringLiteral("QIF:getValue"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("20"))
}
{
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("QIF.setName"), account.setName(QStringLiteral("40Compte D")), true)
SKGTESTERROR(QStringLiteral("QIF.load"), account.load(), true)
SKGTEST(QStringLiteral("QIF:getValue"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("40"))
}
}
// End test
SKGENDTEST()
} // NOLINT(readability/fn_size)
diff --git a/tests/skgbankmodelertest/skgtestimportqif2.cpp b/tests/skgbankmodelertest/skgtestimportqif2.cpp
index 0dc03f087..c66ae54d9 100644
--- a/tests/skgbankmodelertest/skgtestimportqif2.cpp
+++ b/tests/skgbankmodelertest/skgtestimportqif2.cpp
@@ -1,457 +1,457 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is a test script.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgtestmacro.h"
#include "skgbankincludes.h"
#include "skgimportexportmanager.h"
/**
* The main function of the unit test
* @param argc the number of arguments
* @param argv the list of arguments
*/
int main(int argc, char** argv)
{
Q_UNUSED(argc)
Q_UNUSED(argv)
// Init test
SKGINITTEST(true)
QDate d(1970, 1, 1);
{
// 275963
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGBankObject bank(&document1);
SKGUnitObject unit_euro(&document1);
SKGUnitObject unit_dollar(&document1);
SKGError err;
{
SKGAccountObject account;
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_INIT"), err)
// Creation unit
SKGTESTERROR(QStringLiteral("UNIT:setName"), unit_euro.setName(QStringLiteral("euro")), true)
SKGTESTERROR(QStringLiteral("UNIT:setSymbol"), unit_euro.setSymbol(QStringLiteral("EUR")), true)
SKGTESTERROR(QStringLiteral("UNIT:setType"), unit_euro.setType(SKGUnitObject::PRIMARY), true)
SKGTESTERROR(QStringLiteral("UNIT:save"), unit_euro.save(), true)
// Creation unitvalue
SKGUnitValueObject unit_euro_val1;
SKGTESTERROR(QStringLiteral("UNIT:addUnitValue"), unit_euro.addUnitValue(unit_euro_val1), true)
SKGTESTERROR(QStringLiteral("UNITVALUE:setQuantity"), unit_euro_val1.setQuantity(1), true)
SKGTESTERROR(QStringLiteral("UNITVALUE:setDate"), unit_euro_val1.setDate(d), true)
SKGTESTERROR(QStringLiteral("UNITVALUE:save"), unit_euro_val1.save(), true)
// Creation unit
SKGTESTERROR(QStringLiteral("UNIT:setName"), unit_dollar.setName(QStringLiteral("dollar")), true)
SKGTESTERROR(QStringLiteral("UNIT:setSymbol"), unit_dollar.setSymbol(QStringLiteral("USD")), true)
SKGTESTERROR(QStringLiteral("UNIT:setType"), unit_dollar.setType(SKGUnitObject::CURRENCY), true)
SKGTESTERROR(QStringLiteral("UNIT:save"), unit_dollar.save(), true)
// Creation unitvalue
SKGUnitValueObject unit_dollar_val1;
SKGTESTERROR(QStringLiteral("UNIT:addUnitValue"), unit_dollar.addUnitValue(unit_dollar_val1), true)
SKGTESTERROR(QStringLiteral("UNITVALUE:setQuantity"), unit_dollar_val1.setQuantity(2), true)
SKGTESTERROR(QStringLiteral("UNITVALUE:setDate"), unit_dollar_val1.setDate(d), true)
SKGTESTERROR(QStringLiteral("UNITVALUE:save"), unit_dollar_val1.save(), true)
// Creation bank
SKGTESTERROR(QStringLiteral("BANK:setName"), bank.setName(QStringLiteral("CREDIT COOP")), true)
SKGTESTERROR(QStringLiteral("BANK:setNumber"), bank.setNumber(QStringLiteral("0003")), true)
SKGTESTERROR(QStringLiteral("BANK:save"), bank.save(), true)
// Creation account
SKGTESTERROR(QStringLiteral("BANK:addAccount"), bank.addAccount(account), true)
SKGTESTERROR(QStringLiteral("ACCOUNT:setName"), account.setName(QStringLiteral("CODEVI")), true)
SKGTESTERROR(QStringLiteral("ACCOUNT:save"), account.save(), true)
SKGTESTERROR(QStringLiteral("ACCOUNT:setInitialBalance"), account.setInitialBalance(100, unit_dollar), true)
SKGTESTERROR(QStringLiteral("ACCOUNT:save"), account.save(), true)
}
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportqif2/t2.qif"));
SKGTESTERROR(QStringLiteral("QIF.importFile"), imp1.importFile(), true)
}
{
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("QIF.setName"), account.setName(QStringLiteral("CODEVI")), true)
SKGTESTERROR(QStringLiteral("QIF.load"), account.load(), true)
SKGTEST(QStringLiteral("QIF:getValue"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("-9335.94"))
}
}
{
// 275963
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.load(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportqif2/export_qif.skg"), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_BP_QIF"), err)
SKGImportExportManager exp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("OUT")) % "/skgtestimportqif2/export_qif.qif"));
SKGTESTERROR(QStringLiteral("QIF.exportFile"), exp1.exportFile(), true)
}
}
{
// Support qif file having Type:Class with description
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
SKGAccountObject la;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportqif2/MoneydanceExportExample.qif"));
SKGTESTERROR(QStringLiteral("QIF.importFile"), imp1.importFile(), true)
SKGObjectBase::SKGListSKGObjectBase result;
SKGTESTERROR(QStringLiteral("DOC.getObjects"), document1.getObjects(QStringLiteral("account"), QStringLiteral("t_name='Wells Fargo:Checking'"), result), true)
SKGTEST(QStringLiteral("DOC.getObjects.count"), result.count(), 1)
if (result.count() != 0) {
la = result.at(0);
}
}
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("EXPORT_QIF"), err)
SKGImportExportManager exp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("OUT")) % "/skgtestimportqif2/export_all.qif"));
SKGTESTERROR(QStringLiteral("QIF.exportFile"), exp1.exportFile(), true)
}
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("EXPORT_QIF"), err)
SKGImportExportManager exp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("OUT")) % "/skgtestimportqif2/export_la.qif"));
QMap<QString, QString> params;
params[QStringLiteral("uuid_of_selected_accounts_or_operations")] = la.getUniqueID();
exp1.setExportParameters(params);
SKGTESTERROR(QStringLiteral("QIF.exportFile"), exp1.exportFile(), true)
}
}
{
// Default account
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportqif2/LA-1234567@ing.qif"));
SKGTESTERROR(QStringLiteral("QIF.importFile"), imp1.importFile(), true)
}
{
SKGBEGINTRANSACTION(document1, QStringLiteral("MODIF"), err)
SKGObjectBase::SKGListSKGObjectBase result;
SKGTESTERROR(QStringLiteral("DOC.getObjects"), document1.getObjects(QStringLiteral("bank"), QStringLiteral("t_name='ing'"), result), true)
SKGTEST(QStringLiteral("DOC.getObjects.count"), result.count(), 1)
SKGBankObject bank(result.at(0));
SKGTESTERROR(QStringLiteral("BANK.setName"), bank.setName(QStringLiteral("ING Direct")), true)
SKGTESTERROR(QStringLiteral("BANK.save"), bank.save(), true)
SKGTESTERROR(QStringLiteral("DOC.getObjects"), document1.getObjects(QStringLiteral("account"), QStringLiteral("t_number='1234567'"), result), true)
SKGTEST(QStringLiteral("DOC.getObjects.count"), result.count(), 1)
SKGTESTERROR(QStringLiteral("DOC.getObjects"), document1.getObjects(QStringLiteral("account"), QStringLiteral("t_name='LA'"), result), true)
SKGTEST(QStringLiteral("DOC.getObjects.count"), result.count(), 1)
SKGAccountObject acc(result.at(0));
SKGTESTERROR(QStringLiteral("ACC.setName"), acc.setName(QStringLiteral("Livret A")), true)
SKGTESTERROR(QStringLiteral("ACC.save"), acc.save(), true)
}
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportqif2/LA-1234567@ing.qif"));
SKGTESTERROR(QStringLiteral("QIF.importFile"), imp1.importFile(), true)
}
document1.dump(DUMPACCOUNT);
{
SKGObjectBase::SKGListSKGObjectBase result;
SKGTESTERROR(QStringLiteral("DOC.getObjects"), document1.getObjects(QStringLiteral("account"), QStringLiteral("t_number='1234567'"), result), true)
SKGTEST(QStringLiteral("DOC.getObjects.count"), result.count(), 1)
}
}
{
// Bug import date
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportqif2/date_money.qif"));
SKGTESTERROR(QStringLiteral("QIF.importFile"), imp1.importFile(), true)
}
}
{
// Autorepair
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportqif2/autorepair.qif"));
SKGTESTERROR(QStringLiteral("QIF.importFile"), imp1.importFile(), true)
}
{
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("QIF.setName"), account.setName(QStringLiteral("autorepair")), true)
SKGTESTERROR(QStringLiteral("QIF.load"), account.load(), true)
SKGTEST(QStringLiteral("QIF:getValue"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("-400"))
}
}
{
// Error
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportqif2/error.qif"));
SKGTESTERROR(QStringLiteral("QIF.importFile"), imp1.importFile(), true)
}
}
{
// Split and transfer
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportqif2/split_and_transfer.qif"));
SKGTESTERROR(QStringLiteral("QIF.importFile"), imp1.importFile(), true)
}
{
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("QIF.setName"), account.setName(QStringLiteral("Joint Checking")), true)
SKGTESTERROR(QStringLiteral("QIF.load"), account.load(), true)
SKGTEST(QStringLiteral("QIF:getValue"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("-1181.25")) // -600 if sum of splits
}
{
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("QIF.setName"), account.setName(QStringLiteral("2012 Acadia Loan")), true)
SKGTESTERROR(QStringLiteral("QIF.load"), account.load(), true)
SKGTEST(QStringLiteral("QIF:getValue"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("1162.5")) // 581.25 if sum of splits
}
}
{
// Split and transfer 2
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportqif2/split_and_transfer_2.qif"));
SKGTESTERROR(QStringLiteral("QIF.importFile"), imp1.importFile(), true)
}
{
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("QIF.setName"), account.setName(QStringLiteral("Joint Checking")), true)
SKGTESTERROR(QStringLiteral("QIF.load"), account.load(), true)
SKGTEST(QStringLiteral("QIF:getValue"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("2714.31"))
}
{
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("QIF.setName"), account.setName(QStringLiteral("Credit Union")), true)
SKGTESTERROR(QStringLiteral("QIF.load"), account.load(), true)
SKGTEST(QStringLiteral("QIF:getValue"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("400"))
}
{
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("QIF.setName"), account.setName(QStringLiteral("TSP")), true)
SKGTESTERROR(QStringLiteral("QIF.load"), account.load(), true)
SKGTEST(QStringLiteral("QIF:getValue"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("437.88"))
}
{
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("QIF.setName"), account.setName(QStringLiteral("FSA")), true)
SKGTESTERROR(QStringLiteral("QIF.load"), account.load(), true)
SKGTEST(QStringLiteral("QIF:getValue"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("88.26"))
}
{
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("QIF.setName"), account.setName(QStringLiteral("TSP - Roth")), true)
SKGTESTERROR(QStringLiteral("QIF.load"), account.load(), true)
SKGTEST(QStringLiteral("QIF:getValue"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("250"))
}
}
{
// 400724
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportqif2/400724.qif"));
SKGTESTERROR(QStringLiteral("QIF.importFile"), imp1.importFile(), true)
}
}
{
// 402330
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportqif2/402330.qif"));
SKGTESTERROR(QStringLiteral("QIF.importFile"), imp1.importFile(), true)
}
}
{
// 403725
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportqif2/403725.qif"));
SKGTESTERROR(QStringLiteral("QIF.importFile"), imp1.importFile(), true)
}
SKGObjectBase::SKGListSKGObjectBase result;
SKGTESTERROR(QStringLiteral("DOC.getObjects"), document1.getObjects(QStringLiteral("refund"), QLatin1String(""), result), true)
SKGTEST(QStringLiteral("DOC.getObjects.count"), result.count(), 2)
}
{
// 406243
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportqif2/406243.qif"));
SKGTESTERROR(QStringLiteral("QIF.importFile"), imp1.importFile(), true)
}
{
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("QIF.setName"), account.setName(QStringLiteral("406243")), true)
SKGTESTERROR(QStringLiteral("QIF.load"), account.load(), true)
SKGTEST(QStringLiteral("QIF:getValue"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("794"))
}
}
{
// 406243
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportqif2/406271.qif"));
SKGTESTERROR(QStringLiteral("QIF.importFile"), imp1.importFile(), true)
}
{
SKGTrackerObject tracker(&document1);
SKGTESTERROR(QStringLiteral("QIF.setName"), tracker.setName(QStringLiteral("Jane")), true)
SKGTESTERROR(QStringLiteral("QIF.load"), tracker.load(), true)
SKGTEST(QStringLiteral("QIF:getComment"), tracker.getComment(), QStringLiteral("expenses that Jane incurs"))
}
}
{
// 406266
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportqif2/406266.qif"));
SKGTESTERROR(QStringLiteral("QIF.importFile"), imp1.importFile(), true)
}
{
SKGUnitObject unit(&document1);
SKGTESTERROR(QStringLiteral("QIF.setName"), unit.setName(QStringLiteral("ACME CORP")), true)
SKGTESTERROR(QStringLiteral("QIF.load"), unit.load(), true)
SKGTEST(QStringLiteral("QIF:getSymbol"), unit.getSymbol(), QStringLiteral("ACMW"))
SKGTEST(QStringLiteral("QIF:getSymbol"), static_cast<unsigned int>(unit.getType()), static_cast<unsigned int>(SKGUnitObject::SHARE))
}
}
{
// 406270
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportqif2/406270.qif"));
SKGTESTERROR(QStringLiteral("QIF.importFile"), imp1.importFile(), true)
}
SKGObjectBase::SKGListSKGObjectBase result;
SKGTESTERROR(QStringLiteral("DOC.getObjects"), document1.getObjects(QStringLiteral("unit"), QLatin1String(""), result), true)
SKGTEST(QStringLiteral("DOC.getObjects.count"), static_cast<unsigned int>(result.count()), static_cast<unsigned int>(1))
}
// End test
SKGENDTEST()
}
diff --git a/tests/skgbankmodelertest/skgtestimportskg.cpp b/tests/skgbankmodelertest/skgtestimportskg.cpp
index 2135c28fa..cdb957df5 100644
--- a/tests/skgbankmodelertest/skgtestimportskg.cpp
+++ b/tests/skgbankmodelertest/skgtestimportskg.cpp
@@ -1,234 +1,234 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is a test script.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgtestmacro.h"
#include "skgbankincludes.h"
#include "skgimportexportmanager.h"
/**
* The main function of the unit test
* @param argc the number of arguments
* @param argv the list of arguments
*/
int main(int argc, char** argv)
{
Q_UNUSED(argc)
Q_UNUSED(argv)
// Init test
SKGINITTEST(true)
{
// Test import SKG
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_SKG"), err)
SKGImportExportManager impmissing(&document1, QUrl::fromLocalFile(QStringLiteral("missingfile.skg")));
SKGTESTERROR(QStringLiteral("imp1.importFile"), impmissing.importFile(), false)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportskg/all_types.skg"));
SKGTESTERROR(QStringLiteral("SKG.importFile"), imp1.importFile(), true)
}
{
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("SKG.setName"), account.setName(QStringLiteral("FRANC")), true)
SKGTESTERROR(QStringLiteral("SKG.load"), account.load(), true)
SKGTEST(QStringLiteral("SKG:getCurrentAmount"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("1.524490172"))
}
{
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("SKG.setName"), account.setName(QStringLiteral("COURANT")), true)
SKGTESTERROR(QStringLiteral("SKG.load"), account.load(), true)
SKGTEST(QStringLiteral("SKG:getCurrentAmount"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("-55"))
}
{
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("SKG.setName"), account.setName(QStringLiteral("EPARGNE")), true)
SKGTESTERROR(QStringLiteral("SKG.load"), account.load(), true)
SKGTEST(QStringLiteral("SKG:getCurrentAmount"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("1130.52449"))
}
// test multi import
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_SKG"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportskg/all_types.skg"));
SKGTESTERROR(QStringLiteral("SKG.importFile"), imp1.importFile(), true)
}
// Export xml
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("EXPORT_XML"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("OUT")) % "/skgtestimportskg/all_types.xml"));
SKGTESTERROR(QStringLiteral("SKG.exportFile"), imp1.exportFile(), true)
}
// Export json
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("EXPORT_JSON"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("OUT")) % "/skgtestimportskg/all_types.json"));
SKGTESTERROR(QStringLiteral("SKG.exportFile"), imp1.exportFile(), true)
}
// Export json
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_JSON"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("OUT")) % "/skgtestimportskg/all_types.json"));
SKGTESTERROR(QStringLiteral("SKG.importFile"), imp1.importFile(), false)
}
}
{
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
// Export skg from memory
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("EXPORT_SKG"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("OUT")) % "/skgtestimportskg/all_types_exp_from_mem.skg"));
SKGTESTERROR(QStringLiteral("SKG.exportFile from memory"), imp1.exportFile(), true)
SKGTESTERROR(QStringLiteral("SKG.importFile from file"), imp1.importFile(), true)
}
SKGTESTERROR(QStringLiteral("SKG.saveAs"), document1.saveAs(SKGTest::getTestPath(QStringLiteral("OUT")) % "/skgtestimportskg/all_types_save.skg", true), true)
// Export skg from file
SKGTESTERROR(QStringLiteral("SKG.load"), document1.load(SKGTest::getTestPath(QStringLiteral("OUT")) % "/skgtestimportskg/all_types_save.skg"), true) {
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("EXPORT_SKG"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("OUT")) % "/skgtestimportskg/all_types_exp_from_file.skg"));
SKGTESTERROR(QStringLiteral("SKG.exportFile from file"), imp1.exportFile(), true)
SKGTESTERROR(QStringLiteral("SKG.importFile from file"), imp1.importFile(), true)
}
}
{
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
// Export sqlite from memory
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("EXPORT_SQLITE"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("OUT")) % "/skgtestimportskg/all_types_exp_from_mem.sqlite"));
SKGTESTERROR(QStringLiteral("SQLITE.exportFile from memory"), imp1.exportFile(), true)
SKGTESTERROR(QStringLiteral("SQLITE.importFile from file"), imp1.importFile(), true)
}
// Export skg from file
SKGTESTERROR(QStringLiteral("SKG.load"), document1.load(SKGTest::getTestPath(QStringLiteral("OUT")) % "/skgtestimportskg/all_types_save.skg"), true) {
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("EXPORT_SQLITE"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("OUT")) % "/skgtestimportskg/all_types_exp_from_file.sqlite"));
SKGTESTERROR(QStringLiteral("SQLITE.exportFile from file"), imp1.exportFile(), true)
SKGTESTERROR(QStringLiteral("SQLITE.importFile from file"), imp1.importFile(), true)
}
}
{
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
// Export sqlcipher from memory
{
// Scope of the transaction
SKGTESTERROR(QStringLiteral("SQLCIPHER.changePassword"), document1.changePassword(QStringLiteral("password")), true)
SKGBEGINTRANSACTION(document1, QStringLiteral("EXPORT_SQLCIPHER"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("OUT")) % "/skgtestimportskg/all_types_exp_from_mem.sqlcipher"));
SKGTESTERROR(QStringLiteral("SQLCIPHER.exportFile from memory"), imp1.exportFile(), true)
QMap<QString, QString> parameters;
parameters[QStringLiteral("password")] = QStringLiteral("password");
imp1.setImportParameters(parameters);
SKGTESTERROR(QStringLiteral("SQLCIPHER.importFile from file"), imp1.importFile(), true)
}
// Export skg from file
SKGTESTERROR(QStringLiteral("SKG.load"), document1.load(SKGTest::getTestPath(QStringLiteral("OUT")) % "/skgtestimportskg/all_types_save.skg"), true) {
// Scope of the transaction
SKGTESTERROR(QStringLiteral("SQLCIPHER.changePassword"), document1.changePassword(QStringLiteral("password")), true)
SKGBEGINTRANSACTION(document1, QStringLiteral("EXPORT_SQLCIPHER"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("OUT")) % "/skgtestimportskg/all_types_exp_from_file.sqlcipher"));
SKGTESTERROR(QStringLiteral("SQLCIPHER.exportFile from file"), imp1.exportFile(), true)
QMap<QString, QString> parameters;
parameters[QStringLiteral("password")] = QStringLiteral("password");
imp1.setImportParameters(parameters);
SKGTESTERROR(QStringLiteral("SQLCIPHER.importFile from file"), imp1.importFile(), true)
}
}
{
// Test import encrypted SKG
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_SKG"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportskg/encrypted.skg"));
QMap<QString, QString> parameters;
parameters[QStringLiteral("password")] = QStringLiteral("password");
imp1.setImportParameters(parameters);
SKGTESTERROR(QStringLiteral("SKG.importFile"), imp1.importFile(), true)
}
}
{
// Test import SKG
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_SKG"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportskg/euro_bitcoin_dollar.skg"));
SKGTESTERROR(QStringLiteral("SKG.importFile"), imp1.importFile(), true)
}
}
{
// Test import SKG
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_SKG"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/advice.skg"));
SKGTESTERROR(QStringLiteral("SKG.importFile"), imp1.importFile(), true)
}
}
// End test
SKGENDTEST()
}
diff --git a/tests/skgbankmodelertest/skgtestimportstockqif.cpp b/tests/skgbankmodelertest/skgtestimportstockqif.cpp
index 8d1619e5c..6e5a24397 100644
--- a/tests/skgbankmodelertest/skgtestimportstockqif.cpp
+++ b/tests/skgbankmodelertest/skgtestimportstockqif.cpp
@@ -1,98 +1,98 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is a test script.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include <klocalizedstring.h>
#include "skgbankincludes.h"
#include "skgimportexportmanager.h"
#include "skgtestmacro.h"
/**
* The main function of the unit test
* @param argc the number of arguments
* @param argv the list of arguments
*/
int main(int argc, char** argv)
{
Q_UNUSED(argc)
Q_UNUSED(argv)
// Init test
SKGINITTEST(true) {
// Test import QIF 1
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_STOCK_UNIT"), err)
SKGUnitObject unit;
SKGTESTERROR(QStringLiteral("QIF.createCurrencyUnit"), SKGUnitObject::createCurrencyUnit(&document1, QStringLiteral("FRF"), unit), true)
}
document1.dump(DUMPUNIT);
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_STOCK_1"), err)
SKGUnitObject unit;
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportstockqif/La Poste GMO.qif"));
SKGTESTERROR(QStringLiteral("QIF.importFile"), imp1.importFile(), true)
SKGImportExportManager imp2(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportstockqif/La Poste GMO (Caisse).qif"));
SKGTESTERROR(QStringLiteral("QIF.importFile"), imp2.importFile(), true)
SKGImportExportManager imp3(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportstockqif/goog.qif"));
SKGTESTERROR(QStringLiteral("QIF.importFile"), imp3.importFile(), true)
}
document1.dump(DUMPOPERATION | DUMPUNIT | DUMPACCOUNT);
}
{
// Test import QIF -Correction bug 2307068
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_2307068"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportstockqif/2307068-BNP CC.qif"));
SKGTESTERROR(QStringLiteral("QIF.importFile"), imp1.importFile(), true)
SKGImportExportManager imp12(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportstockqif/2307068-Compte Titre.qif"));
SKGTESTERROR(QStringLiteral("QIF.importFile"), imp12.importFile(), true)
}
document1.dump(DUMPOPERATION | DUMPUNIT | DUMPACCOUNT);
{
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("QIF.setName"), account.setName(QStringLiteral("BNP CC")), true)
SKGTESTERROR(QStringLiteral("QIF.load"), account.load(), true)
SKGTEST(QStringLiteral("QIF:getValue"), SKGServices::toCurrencyString(account.getCurrentAmount(), QLatin1String(""), 2), QStringLiteral("-520.00"))
}
{
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("QIF.setName"), account.setName(QStringLiteral("Compte Titre")), true)
SKGTESTERROR(QStringLiteral("QIF.load"), account.load(), true)
SKGTEST(QStringLiteral("QIF:getValue"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("520"))
}
}
// End test
SKGENDTEST()
}
diff --git a/tests/skgbankmodelertest/skgtestimporturls.cpp b/tests/skgbankmodelertest/skgtestimporturls.cpp
index c27d882bd..5f871ccaa 100644
--- a/tests/skgbankmodelertest/skgtestimporturls.cpp
+++ b/tests/skgbankmodelertest/skgtestimporturls.cpp
@@ -1,92 +1,92 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is a test script.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgtestmacro.h"
#include "skgbankincludes.h"
#include "skgimportexportmanager.h"
/**
* The main function of the unit test
* @param argc the number of arguments
* @param argv the list of arguments
*/
int main(int argc, char** argv)
{
Q_UNUSED(argc)
Q_UNUSED(argv)
// Init test
SKGINITTEST(true)
QStringList extensions;
extensions << QStringLiteral("csv") << QStringLiteral("cfo") << QStringLiteral("gnucash") << QStringLiteral("gsb") << QStringLiteral("kmy") << QStringLiteral("mmb") << QStringLiteral("mt940") << QStringLiteral("ofx") << QStringLiteral("qif") << QStringLiteral("skg") << QStringLiteral("xhb");
int nb = extensions.count();
for (int i = 0; i < nb; ++i) {
const QString& ext = extensions.at(i);
- QString filename = "http://skrooge.org/files/skgtestimporturl/test." % ext;
+ QString filename = "https://skrooge.org/files/skgtestimporturl/test." % ext;
SKGTRACE << i + 1 << "/" << nb << ": Import " << filename << endl;
// Test import
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT"), err)
SKGImportExportManager imp1(&document1, QUrl::fromUserInput(filename));
SKGTESTERROR(ext % ".importFile", imp1.importFile(), true)
}
if (ext == QStringLiteral("skg") && SKGServices::getEnvVariable(QStringLiteral("USER")) == QStringLiteral("s")) {
QStringList extensionsExport;
extensionsExport.push_back(QStringLiteral("csv"));
extensionsExport.push_back(QStringLiteral("kmy"));
extensionsExport.push_back(QStringLiteral("qif"));
extensionsExport.push_back(QStringLiteral("skg"));
extensionsExport.push_back(QStringLiteral("xml"));
extensionsExport.push_back(QStringLiteral("sqlite"));
int nb2 = extensionsExport.count();
for (int j = 0; j < nb2; ++j) {
const QString& ext2 = extensionsExport.at(j);
QString filename2 = "ftp://skrooge.org/files/skgtestimporturl/output/test." % ext2;
SKGTRACE << " " << j + 1 << "/" << nb2 << ": Export " << filename2 << endl;
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("EXPORT"), err)
SKGImportExportManager imp1(&document1, QUrl::fromUserInput(filename2));
SKGTESTERROR(ext2 % ".exportFile", imp1.exportFile(), true)
}
}
}
{
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
- SKGTESTERROR(QStringLiteral("document1.load()"), document1.load(QStringLiteral("http://skrooge.org/files/skgtestimporturl/test.skg")), true)
+ SKGTESTERROR(QStringLiteral("document1.load()"), document1.load(QStringLiteral("https://skrooge.org/files/skgtestimporturl/test.skg")), true)
}
// End test
SKGENDTEST()
}
diff --git a/tests/skgbankmodelertest/skgtestimportweboob.cpp b/tests/skgbankmodelertest/skgtestimportweboob.cpp
index c6fd39d5b..cab284ce6 100644
--- a/tests/skgbankmodelertest/skgtestimportweboob.cpp
+++ b/tests/skgbankmodelertest/skgtestimportweboob.cpp
@@ -1,526 +1,526 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is a test script.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgtestmacro.h"
#include "skgbankincludes.h"
#include "skgimportexportmanager.h"
/**
* The main function of the unit test
* @param argc the number of arguments
* @param argv the list of arguments
*/
int main(int argc, char** argv)
{
Q_UNUSED(argc)
Q_UNUSED(argv)
// Init test
SKGINITTEST(true)
QString path = qgetenv("PATH");
QString in = qgetenv("IN");
{
// Test import Weboob
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.load()"), document1.load(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportbackend/fake1/fake1.skg"), true)
SKGError err;
{
SKGTESTBOOL("PUTENV.fake1", qputenv("PATH", (in + "/skgtestimportbackend/fake1/:" + path).toLatin1()), true)
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_WEBOOB"), err)
SKGImportExportManager imp1(&document1, QUrl(QStringLiteral(".weboob")));
SKGTESTERROR(QStringLiteral("WEBOOB.importFile"), imp1.importFile(), true)
}
// Check
{
SKGAccountObject account;
SKGTESTERROR(QStringLiteral("ACCOUNT.getObjectByName"), SKGNamedObject::getObjectByName(&document1, QStringLiteral("v_account"), QStringLiteral("12345"), account), true)
SKGTESTERROR(QStringLiteral("ACCOUNT.load"), account.load(), true)
SKGTEST(QStringLiteral("ACCOUNT:getCurrentAmount"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("1523.99"))
SKGTEST(QStringLiteral("ACCOUNT:getAmount"), SKGServices::doubleToString(account.getAmount(QDate(2013, 5, 1))), QStringLiteral("1471.22"))
SKGTESTERROR(QStringLiteral("ACCOUNT.getObjectByName"), SKGNamedObject::getObjectByName(&document1, QStringLiteral("v_account"), QStringLiteral("47896"), account), true)
SKGTESTERROR(QStringLiteral("ACCOUNT.load"), account.load(), true)
SKGTEST(QStringLiteral("ACCOUNT:getCurrentAmount"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("-30"))
SKGTEST(QStringLiteral("ACCOUNT:getAmount"), SKGServices::doubleToString(account.getAmount(QDate(2013, 5, 1))), QStringLiteral("0"))
SKGObjectBase::SKGListSKGObjectBase result;
SKGTESTERROR(QStringLiteral("DOC.getObjects"), document1.getObjects(QStringLiteral("v_operation"), QStringLiteral("t_comment='SNCF'"), result), true)
SKGTEST(QStringLiteral("DOC.getObjects.count"), result.count(), 2)
SKGTESTERROR(QStringLiteral("DOC.getObjects"), document1.getObjects(QStringLiteral("v_operation"), QStringLiteral("d_date='2013-05-26'"), result), true)
SKGTEST(QStringLiteral("DOC.getObjects.count"), result.count(), 1)
}
}
{
// BUG: 320716
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
SKGTESTBOOL("PUTENV.320716_1", qputenv("PATH", (in + "/skgtestimportbackend/320716_1/:" + path).toLatin1()), true)
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_WEBOOB"), err)
SKGImportExportManager imp1(&document1, QUrl(QStringLiteral(".weboob")));
SKGTESTERROR(QStringLiteral("WEBOOB.importFile"), imp1.importFile(), true)
}
// Check
{
SKGAccountObject account;
SKGTESTERROR(QStringLiteral("ACCOUNT.getObjectByName"), SKGNamedObject::getObjectByName(&document1, QStringLiteral("v_account"), QStringLiteral("12345"), account), true)
SKGTESTERROR(QStringLiteral("ACCOUNT.load"), account.load(), true)
SKGTEST(QStringLiteral("ACCOUNT:getCurrentAmount"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("100"))
}
{
SKGTESTBOOL("PUTENV.320716_1", qputenv("PATH", (in + "/skgtestimportbackend/320716_2/:" + path).toLatin1()), true)
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_WEBOOB"), err)
SKGImportExportManager imp1(&document1, QUrl(QStringLiteral(".weboob")));
SKGTESTERROR(QStringLiteral("WEBOOB.importFile"), imp1.importFile(), true)
}
// Check
{
SKGAccountObject account;
SKGTESTERROR(QStringLiteral("ACCOUNT.getObjectByName"), SKGNamedObject::getObjectByName(&document1, QStringLiteral("v_account"), QStringLiteral("12345"), account), true)
SKGTESTERROR(QStringLiteral("ACCOUNT.load"), account.load(), true)
SKGTEST(QStringLiteral("ACCOUNT:getCurrentAmount"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("0"))
}
}
{
// Test error
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
SKGTESTBOOL("PUTENV.fake1", qputenv("PATH", (in + "/skgtestimportbackend/error1/:" + path).toLatin1()), true)
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_WEBOOB"), err)
SKGImportExportManager imp1(&document1, QUrl(QStringLiteral(".weboob")));
SKGTEST(QStringLiteral("WEBOOB.importFile"), imp1.importFile().getReturnCode(), ERR_FAIL)
}
}
{
// Test error
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
SKGTESTBOOL("PUTENV.fake1", qputenv("PATH", (in + "/skgtestimportbackend/error2/:" + path).toLatin1()), true)
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_WEBOOB"), err)
SKGImportExportManager imp1(&document1, QUrl(QStringLiteral(".weboob")));
SKGTEST(QStringLiteral("WEBOOB.importFile"), imp1.importFile().getReturnCode(), ERR_FAIL)
}
}
{
// Test error
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
SKGTESTBOOL("PUTENV.fake1", qputenv("PATH", (in + "/skgtestimportbackend/error3/:" + path).toLatin1()), true)
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_WEBOOB"), err)
document1.sendMessage(QStringLiteral("Hello"));
SKGImportExportManager imp1(&document1, QUrl(QStringLiteral(".weboob")));
SKGTEST(QStringLiteral("WEBOOB.importFile"), imp1.importFile().getReturnCode(), ERR_FAIL)
}
}
{
// Test error
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
SKGTESTBOOL("PUTENV.fake1", qputenv("PATH", (in + "/skgtestimportbackend/error4/:" + path).toLatin1()), true)
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_WEBOOB"), err)
SKGImportExportManager imp1(&document1, QUrl(QStringLiteral(".weboob")));
SKGTEST(QStringLiteral("WEBOOB.importFile"), imp1.importFile().getReturnCode(), ERR_FAIL)
}
}
{
// Better account selection
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("CREATE ACCOUNT"), err)
// Creation the bank
SKGBankObject bank(&document1);
SKGTESTERROR(QStringLiteral("BANK.setName"), bank.setName(QStringLiteral("caisse-epargne")), true)
SKGTESTERROR(QStringLiteral("BANK.setNumber"), bank.setNumber(QStringLiteral("13135")), true)
SKGTESTERROR(QStringLiteral("BANK.save"), bank.save(), true)
// Creation the account
SKGAccountObject account;
SKGTESTERROR(QStringLiteral("BANK.addAccount"), bank.addAccount(account), true)
SKGTESTERROR(QStringLiteral("ACCOUNT.setName"), account.setName(QStringLiteral("test")), true)
SKGTESTERROR(QStringLiteral("ACCOUNT.setNumber"), account.setNumber(QStringLiteral("123456789")), true)
SKGTESTERROR(QStringLiteral("ACCOUNT.setAgencyNumber"), account.setAgencyNumber(QStringLiteral("00080")), true)
SKGTESTERROR(QStringLiteral("ACCOUNT.save"), account.save(), true)
}
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_WEBOOB"), err)
SKGTESTBOOL("PUTENV.weboob", qputenv("PATH", (in + "/skgtestimportbackend/betterselection/:" + path).toLatin1()), true)
SKGImportExportManager imp1(&document1, QUrl(QStringLiteral(".weboob")));
SKGTESTERROR(QStringLiteral("WEBOOB.importFile"), imp1.importFile(), true)
}
// Check
{
SKGAccountObject account;
SKGTESTERROR(QStringLiteral("ACCOUNT.getObjectByName"), SKGNamedObject::getObjectByName(&document1, QStringLiteral("v_account"), QStringLiteral("test"), account), true)
SKGTESTERROR(QStringLiteral("ACCOUNT.load"), account.load(), true)
SKGTEST(QStringLiteral("ACCOUNT:getCurrentAmount"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("-147994.82"))
}
}
{
// Better account selection
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_WEBOOB"), err)
SKGTESTBOOL("PUTENV.weboob", qputenv("PATH", (in + "/skgtestimportbackend/joint_accounts/:" + path).toLatin1()), true)
SKGImportExportManager imp1(&document1, QUrl(QStringLiteral(".weboob")));
SKGTESTERROR(QStringLiteral("WEBOOB.importFile"), imp1.importFile(), true)
}
// Check
{
SKGAccountObject account;
SKGTESTERROR(QStringLiteral("ACCOUNT.getObjectByName"), SKGNamedObject::getObjectByName(&document1, QStringLiteral("v_account"), QStringLiteral("12345"), account), true)
SKGTESTERROR(QStringLiteral("ACCOUNT.load"), account.load(), true)
SKGTEST(QStringLiteral("ACCOUNT:getCurrentAmount"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("1000"))
}
}
{
// BULK import
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_BULK"), err)
SKGTESTBOOL("PUTENV.bulk", qputenv("PATH", (in + "/skgtestimportbackend/bulk/:" + path).toLatin1()), true)
SKGImportExportManager imp1(&document1, QUrl(QStringLiteral(".bulk")));
SKGTESTERROR(QStringLiteral("WEBOOB.importFile"), imp1.importFile(), true)
}
// Check
{
SKGAccountObject account;
SKGTESTERROR(QStringLiteral("ACCOUNT.getObjectByName"), SKGNamedObject::getObjectByName(&document1, QStringLiteral("v_account"), QStringLiteral("12345"), account), true)
SKGTESTERROR(QStringLiteral("ACCOUNT.load"), account.load(), true)
SKGTEST(QStringLiteral("ACCOUNT:getCurrentAmount"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("10"))
}
// Check
{
SKGAccountObject account;
SKGTESTERROR(QStringLiteral("ACCOUNT.getObjectByName"), SKGNamedObject::getObjectByName(&document1, QStringLiteral("v_account"), QStringLiteral("78900"), account), true)
SKGTESTERROR(QStringLiteral("ACCOUNT.load"), account.load(), true)
SKGTEST(QStringLiteral("ACCOUNT:getCurrentAmount"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("20"))
}
}
{
// STAMM
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("CREATE ACCOUNT"), err)
// Creation the bank
SKGBankObject bank(&document1);
SKGTESTERROR(QStringLiteral("BANK.setName"), bank.setName(QStringLiteral("ldlc")), true)
SKGTESTERROR(QStringLiteral("BANK.save"), bank.save(), true)
// Creation the accounts
{
SKGAccountObject account;
SKGTESTERROR(QStringLiteral("BANK.addAccount"), bank.addAccount(account), true)
SKGTESTERROR(QStringLiteral("ACCOUNT.setName"), account.setName(QStringLiteral("acc1")), true)
SKGTESTERROR(QStringLiteral("ACCOUNT.setNumber"), account.setNumber(QStringLiteral("1234567A")), true)
SKGTESTERROR(QStringLiteral("ACCOUNT.setAgencyNumber"), account.setAgencyNumber(QStringLiteral("00080")), true)
SKGTESTERROR(QStringLiteral("ACCOUNT.save"), account.save(), true)
}
{
SKGAccountObject account;
SKGTESTERROR(QStringLiteral("BANK.addAccount"), bank.addAccount(account), true)
SKGTESTERROR(QStringLiteral("ACCOUNT.setName"), account.setName(QStringLiteral("acc2")), true)
SKGTESTERROR(QStringLiteral("ACCOUNT.setNumber"), account.setNumber(QStringLiteral("987654321")), true)
SKGTESTERROR(QStringLiteral("ACCOUNT.setAgencyNumber"), account.setAgencyNumber(QStringLiteral("00080")), true)
SKGTESTERROR(QStringLiteral("ACCOUNT.save"), account.save(), true)
}
{
SKGAccountObject account;
SKGTESTERROR(QStringLiteral("BANK.addAccount"), bank.addAccount(account), true)
SKGTESTERROR(QStringLiteral("ACCOUNT.setName"), account.setName(QStringLiteral("acc3")), true)
SKGTESTERROR(QStringLiteral("ACCOUNT.setNumber"), account.setNumber(QStringLiteral("1111111A")), true)
SKGTESTERROR(QStringLiteral("ACCOUNT.setAgencyNumber"), account.setAgencyNumber(QStringLiteral("00080")), true)
SKGTESTERROR(QStringLiteral("ACCOUNT.save"), account.save(), true)
}
}
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_WEBOOB"), err)
SKGTESTBOOL("PUTENV.weboob", qputenv("PATH", (in + "/skgtestimportbackend/stamm/:" + path).toLatin1()), true)
SKGImportExportManager imp1(&document1, QUrl(QStringLiteral(".weboob")));
SKGTESTERROR(QStringLiteral("WEBOOB.importFile"), imp1.importFile(), true)
}
// Checks
{
SKGAccountObject account;
SKGTESTERROR(QStringLiteral("ACCOUNT.getObjectByName"), SKGNamedObject::getObjectByName(&document1, QStringLiteral("v_account"), QStringLiteral("acc1"), account), true)
SKGTESTERROR(QStringLiteral("ACCOUNT.load"), account.load(), true)
SKGTEST(QStringLiteral("ACCOUNT:getCurrentAmount"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("-50"))
}
{
SKGAccountObject account;
SKGTESTERROR(QStringLiteral("ACCOUNT.getObjectByName"), SKGNamedObject::getObjectByName(&document1, QStringLiteral("v_account"), QStringLiteral("acc2"), account), true)
SKGTESTERROR(QStringLiteral("ACCOUNT.load"), account.load(), true)
SKGTEST(QStringLiteral("ACCOUNT:getCurrentAmount"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("-50"))
}
{
SKGAccountObject account;
SKGTESTERROR(QStringLiteral("ACCOUNT.getObjectByName"), SKGNamedObject::getObjectByName(&document1, QStringLiteral("v_account"), QStringLiteral("acc3"), account), true)
SKGTESTERROR(QStringLiteral("ACCOUNT.load"), account.load(), true)
SKGTEST(QStringLiteral("ACCOUNT:getCurrentAmount"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("-50"))
}
{
SKGAccountObject account;
SKGTESTERROR(QStringLiteral("ACCOUNT.getObjectByName"), SKGNamedObject::getObjectByName(&document1, QStringLiteral("v_account"), QStringLiteral("1234567W089"), account), true)
SKGTESTERROR(QStringLiteral("ACCOUNT.load"), account.load(), true)
SKGTEST(QStringLiteral("ACCOUNT:getCurrentAmount"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("-50"))
}
{
SKGAccountObject account;
SKGTESTERROR(QStringLiteral("ACCOUNT.getObjectByName"), SKGNamedObject::getObjectByName(&document1, QStringLiteral("v_account"), QStringLiteral("MYACCOUNTNAME"), account), true)
SKGTESTERROR(QStringLiteral("ACCOUNT.load"), account.load(), true)
SKGTEST(QStringLiteral("ACCOUNT:getCurrentAmount"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("-50"))
}
}
{
// Avoid merge of account due to same name
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_WEBOOB"), err)
SKGTESTBOOL("PUTENV.weboob", qputenv("PATH", (in + "/skgtestimportbackend/merge/:" + path).toLatin1()), true)
SKGImportExportManager imp1(&document1, QUrl(QStringLiteral(".weboob")));
SKGTESTERROR(QStringLiteral("WEBOOB.importFile"), imp1.importFile(), true)
}
// Checks
{
SKGAccountObject account;
SKGTESTERROR(QStringLiteral("ACCOUNT.getObjectByName"), SKGNamedObject::getObjectByName(&document1, QStringLiteral("v_account"), QStringLiteral("CPT"), account), true)
SKGTESTERROR(QStringLiteral("ACCOUNT.load"), account.load(), true)
SKGTEST(QStringLiteral("ACCOUNT:getCurrentAmount"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("-50"))
}
{
SKGAccountObject account;
SKGTESTERROR(QStringLiteral("ACCOUNT.getObjectByName"), SKGNamedObject::getObjectByName(&document1, QStringLiteral("v_account"), QStringLiteral("CPT2"), account), true)
SKGTESTERROR(QStringLiteral("ACCOUNT.load"), account.load(), true)
SKGTEST(QStringLiteral("ACCOUNT:getCurrentAmount"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("-50"))
}
}
{
// Avoid merge of account due to same name
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_WEBOOB"), err)
SKGTESTBOOL("PUTENV.weboob", qputenv("PATH", (in + "/skgtestimportbackend/kevin/:" + path).toLatin1()), true)
SKGImportExportManager imp1(&document1, QUrl(QStringLiteral(".weboob")));
SKGTESTERROR(QStringLiteral("WEBOOB.importFile"), imp1.importFile(), true)
}
// Checks
QStringList accounts;
accounts << QStringLiteral("COMPTE 1") << QStringLiteral("COMPTE 2") << QStringLiteral("LIVRET 1") << QStringLiteral("LIVRET 2") << QStringLiteral("EPARGNE 1") << QStringLiteral("EPARGNE 2") << QStringLiteral("EPARGNE 3");
for (const auto& acc : qAsConst(accounts)) {
SKGAccountObject account;
SKGTESTERROR(QStringLiteral("ACCOUNT.getObjectByName"), SKGNamedObject::getObjectByName(&document1, QStringLiteral("v_account"), acc, account), true)
SKGTESTERROR(QStringLiteral("ACCOUNT.load"), account.load(), true)
SKGTEST(QStringLiteral("ACCOUNT:getCurrentAmount"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("-10"))
}
}
{
// Avoid merge of account due to same name
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_WEBOOB"), err)
SKGTESTBOOL("PUTENV.weboob", qputenv("PATH", (in + "/skgtestimportbackend/double/:" + path).toLatin1()), true)
SKGImportExportManager imp1(&document1, QUrl(QStringLiteral(".weboob")));
SKGTESTERROR(QStringLiteral("WEBOOB.importFile"), imp1.importFile(), true)
}
// Checks
{
SKGAccountObject account;
SKGTESTERROR(QStringLiteral("ACCOUNT.getObjectByName"), SKGNamedObject::getObjectByName(&document1, QStringLiteral("v_account"), QStringLiteral("CPT"), account), true)
SKGTESTERROR(QStringLiteral("ACCOUNT.load"), account.load(), true)
SKGTEST(QStringLiteral("ACCOUNT:getCurrentAmount"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("-100"))
}
}
{
// Avoid merge of account due to same name
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_WEBOOB"), err)
SKGTESTBOOL("PUTENV.weboob", qputenv("PATH", (in + "/skgtestimportbackend/397055/:" + path).toLatin1()), true)
SKGImportExportManager imp1(&document1, QUrl(QStringLiteral(".weboob")));
SKGTESTERROR(QStringLiteral("WEBOOB.importFile"), imp1.importFile(), true)
}
// Checks
{
SKGAccountObject account;
SKGTESTERROR(QStringLiteral("ACCOUNT.getObjectByName"), SKGNamedObject::getObjectByName(&document1, QStringLiteral("v_account"), QStringLiteral("LEO"), account), true)
SKGTESTERROR(QStringLiteral("ACCOUNT.load"), account.load(), true)
SKGTEST(QStringLiteral("ACCOUNT:getCurrentAmount"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("-20"))
}
}
{
// rdate Not available
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_WEBOOB"), err)
SKGTESTBOOL("PUTENV.weboob", qputenv("PATH", (in + "/skgtestimportbackend/397611/:" + path).toLatin1()), true)
SKGImportExportManager imp1(&document1, QUrl(QStringLiteral(".weboob")));
SKGTESTERROR(QStringLiteral("WEBOOB.importFile"), imp1.importFile(), true)
}
// Checks
{
SKGAccountObject account;
SKGTESTERROR(QStringLiteral("ACCOUNT.getObjectByName"), SKGNamedObject::getObjectByName(&document1, QStringLiteral("v_account"), QStringLiteral("LEO"), account), true)
SKGTESTERROR(QStringLiteral("ACCOUNT.load"), account.load(), true)
SKGTEST(QStringLiteral("ACCOUNT:getCurrentAmount"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("598.8"))
SKGObjectBase::SKGListSKGObjectBase result;
SKGTESTERROR(QStringLiteral("DOC.getObjects"), document1.getObjects(QStringLiteral("v_operation"), QStringLiteral("d_date!='0000-00-00'"), result), true)
SKGTEST(QStringLiteral("DOC.getObjects.count"), result.count(), 3)
}
}
{
// Double transferts
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_WEBOOB"), err)
SKGTESTBOOL("PUTENV.weboob", qputenv("PATH", (in + "/skgtestimportbackend/double_transferts/:" + path).toLatin1()), true)
SKGImportExportManager imp1(&document1, QUrl(QStringLiteral(".weboob")));
SKGTESTERROR(QStringLiteral("WEBOOB.importFile"), imp1.importFile(), true)
}
// Checks
{
SKGObjectBase::SKGListSKGObjectBase result;
SKGTESTERROR(QStringLiteral("DOC.getObjects"), document1.getObjects(QStringLiteral("v_operation"), QStringLiteral("d_date!='0000-00-00'"), result), true)
SKGTEST(QStringLiteral("DOC.getObjects.count"), result.count(), 4)
}
}
// End test
SKGENDTEST()
}
diff --git a/tests/skgbankmodelertest/skgtestimportxhb.cpp b/tests/skgbankmodelertest/skgtestimportxhb.cpp
index 2341889b1..9db112ee0 100644
--- a/tests/skgbankmodelertest/skgtestimportxhb.cpp
+++ b/tests/skgbankmodelertest/skgtestimportxhb.cpp
@@ -1,165 +1,165 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is a test script.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgtestmacro.h"
#include "skgbankincludes.h"
#include "skgimportexportmanager.h"
/**
* The main function of the unit test
* @param argc the number of arguments
* @param argv the list of arguments
*/
int main(int argc, char** argv)
{
Q_UNUSED(argc)
Q_UNUSED(argv)
// Init test
SKGINITTEST(true)
{
// Test import XHB
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_XHB"), err)
SKGImportExportManager impmissing(&document1, QUrl::fromLocalFile(QStringLiteral("missingfile.xhb")));
SKGTESTERROR(QStringLiteral("imp1.importFile"), impmissing.importFile(), false)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportxhb/test.xhb"));
SKGTESTERROR(QStringLiteral("XHB.importFile"), imp1.importFile(), true)
}
{
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("XHB.setName"), account.setName(QStringLiteral("COURANT")), true)
SKGTESTERROR(QStringLiteral("XHB.load"), account.load(), true)
SKGTEST(QStringLiteral("XHB:getCurrentAmount"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("35"))
}
// test multi import
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_XHB"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportxhb/test.xhb"));
SKGTESTERROR(QStringLiteral("XHB.importFile"), imp1.importFile(), true)
}
}
{
// Test import XHB
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_XHB"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportxhb/example_budget.xhb"));
SKGTESTERROR(QStringLiteral("XHB.importFile"), imp1.importFile(), true)
}
{
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("XHB.setName"), account.setName(QStringLiteral("Cheque Account")), true)
SKGTESTERROR(QStringLiteral("XHB.load"), account.load(), true)
SKGTEST(QStringLiteral("XHB:getCurrentAmount"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("5758.22"))
}
{
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("XHB.setName"), account.setName(QStringLiteral("Savings Account")), true)
SKGTESTERROR(QStringLiteral("XHB.load"), account.load(), true)
SKGTEST(QStringLiteral("XHB:getCurrentAmount"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("1024.66"))
}
}
{
// Test import XHB
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_XHB"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportxhb/comptes.xhb"));
SKGTESTERROR(QStringLiteral("XHB.importFile"), imp1.importFile(), true)
}
{
SKGStringListList result;
SKGTESTERROR(QStringLiteral("XHB.executeSelectSqliteOrder"), document1.executeSelectSqliteOrder(QStringLiteral("SELECT distinct t_type FROM account"), result), true)
SKGTEST(QStringLiteral("XHB:distinct t_type"), result.count(), 6)
}
}
{
// Test import wallet
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_XHB"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportxhb/wallet.xhb"));
SKGTESTERROR(QStringLiteral("XHB.importFile"), imp1.importFile(), true)
}
{
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("XHB.setName"), account.setName(QStringLiteral("Espece")), true)
SKGTESTERROR(QStringLiteral("XHB.load"), account.load(), true)
SKGBankObject bank;
SKGTESTERROR(QStringLiteral("XHB.load"), account.getBank(bank), true)
SKGTEST(QStringLiteral("XHB:getName"), bank.getName(), QLatin1String(""))
}
{
SKGAccountObject account(&document1);
SKGTESTERROR(QStringLiteral("XHB.setName"), account.setName(QStringLiteral("Courant")), true)
SKGTESTERROR(QStringLiteral("XHB.load"), account.load(), true)
SKGBankObject bank;
SKGTESTERROR(QStringLiteral("XHB.load"), account.getBank(bank), true)
SKGTEST(QStringLiteral("XHB:getName"), bank.getName(), QStringLiteral("HOMEBANK"))
}
}
{
// Test import
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_XHB"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportxhb/error_import.xhb"));
SKGTESTERROR(QStringLiteral("XHB.importFile"), imp1.importFile(), true)
}
}
// End test
SKGENDTEST()
}
diff --git a/tests/skgbankmodelertest/skgtestinterest.cpp b/tests/skgbankmodelertest/skgtestinterest.cpp
index d8f756863..c4db61025 100644
--- a/tests/skgbankmodelertest/skgtestinterest.cpp
+++ b/tests/skgbankmodelertest/skgtestinterest.cpp
@@ -1,197 +1,197 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is a test script.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgtestmacro.h"
#include "skgbankincludes.h"
/**
* The main function of the unit test
* @param argc the number of arguments
* @param argv the list of arguments
*/
int main(int argc, char** argv)
{
Q_UNUSED(argc)
Q_UNUSED(argv)
// Init test
SKGINITTEST(true)
// ============================================================================
// Init
{
// Test interest document
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("BANK_T1"), err)
// Creation bank1
SKGBankObject bank1(&document1);
SKGTESTERROR(QStringLiteral("BANK:setName"), bank1.setName(QStringLiteral("CREDIT COOP")), true)
SKGTESTERROR(QStringLiteral("BANK:save"), bank1.save(), true)
// Creation account1
SKGAccountObject account1;
SKGTESTERROR(QStringLiteral("BANK:addAccount"), bank1.addAccount(account1), true)
SKGTESTERROR(QStringLiteral("ACCOUNT:setName"), account1.setName(QStringLiteral("Livre A")), true)
SKGTESTERROR(QStringLiteral("ACCOUNT:save"), account1.save(), true)
// Add interest parameters
SKGInterestObject interest1;
SKGTESTERROR(QStringLiteral("ACCOUNT:addInterest"), account1.addInterest(interest1), true)
SKGTESTERROR(QStringLiteral("INTEREST:setDate"), interest1.setDate(QDate::currentDate()), true)
SKGTESTERROR(QStringLiteral("INTEREST:setRate"), interest1.setRate(1.25), true)
SKGTESTERROR(QStringLiteral("INTEREST:setIncomeValueDateMode"), interest1.setIncomeValueDateMode(SKGInterestObject::J1), true)
SKGTESTERROR(QStringLiteral("INTEREST:setExpenditueValueDateMode"), interest1.setExpenditueValueDateMode(SKGInterestObject::J2), true)
SKGTESTERROR(QStringLiteral("INTEREST:setInterestComputationMode"), interest1.setInterestComputationMode(SKGInterestObject::DAYS360), true)
SKGTEST(QStringLiteral("INTEREST:getRate"), interest1.getRate(), 1.25)
SKGTEST(QStringLiteral("INTEREST:getIncomeValueDateMode"), static_cast<unsigned int>(interest1.getIncomeValueDateMode()), static_cast<unsigned int>(SKGInterestObject::J1))
SKGTEST(QStringLiteral("INTEREST:getExpenditueValueDateMode"), static_cast<unsigned int>(interest1.getExpenditueValueDateMode()), static_cast<unsigned int>(SKGInterestObject::J2))
SKGTEST(QStringLiteral("INTEREST:getInterestComputationMode"), static_cast<unsigned int>(interest1.getInterestComputationMode()), static_cast<unsigned int>(SKGInterestObject::DAYS360))
SKGTESTERROR(QStringLiteral("INTEREST:save"), interest1.save(), true)
SKGInterestObject interest11(static_cast<SKGObjectBase>(interest1));
SKGInterestObject interest12 = interest1;
SKGInterestObject interest13(SKGObjectBase(&document1, QStringLiteral("xxx"), interest1.getID()));
SKGInterestObject interest14;
interest14 = static_cast<SKGObjectBase>(interest1);
}
// Test interest computation
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true) {
QDate firstday = QDate::currentDate();
firstday = firstday.addMonths(1 - firstday.month());
firstday = firstday.addDays(1 - firstday.day());
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("BANK_T1"), err)
// Creation bank1
SKGBankObject bank1(&document1);
SKGTESTERROR(QStringLiteral("BANK:setName"), bank1.setName(QStringLiteral("CREDIT COOP")), true)
SKGTESTERROR(QStringLiteral("BANK:save"), bank1.save(), true)
// Creation account1
SKGAccountObject account1;
SKGTESTERROR(QStringLiteral("BANK:addAccount"), bank1.addAccount(account1), true)
SKGTESTERROR(QStringLiteral("ACCOUNT:setName"), account1.setName(QStringLiteral("Livre A")), true)
SKGTESTERROR(QStringLiteral("ACCOUNT:save"), account1.save(), true)
// Creation unit
SKGUnitObject unit_euro(&document1);
SKGTESTERROR(QStringLiteral("UNIT:setName"), unit_euro.setName(QStringLiteral("euro")), true)
SKGTESTERROR(QStringLiteral("UNIT:save"), unit_euro.save(), true)
// Creation unitvalue
SKGUnitValueObject unit_euro_val1;
SKGTESTERROR(QStringLiteral("UNIT:addUnitValue"), unit_euro.addUnitValue(unit_euro_val1), true)
SKGTESTERROR(QStringLiteral("UNITVALUE:setQuantity"), unit_euro_val1.setQuantity(1), true)
SKGTESTERROR(QStringLiteral("UNITVALUE:setDate"), unit_euro_val1.setDate(firstday), true)
SKGTESTERROR(QStringLiteral("UNITVALUE:save"), unit_euro_val1.save(), true)
// Add interest parameters
SKGInterestObject interest1;
SKGTESTERROR(QStringLiteral("ACCOUNT:addInterest"), account1.addInterest(interest1), true)
SKGTESTERROR(QStringLiteral("INTEREST:setDate"), interest1.setDate(firstday.addDays(-10)), true)
SKGTESTERROR(QStringLiteral("INTEREST:setRate"), interest1.setRate(4), true)
SKGTESTERROR(QStringLiteral("INTEREST:save"), interest1.save(), true)
SKGInterestObject interest2;
SKGTESTERROR(QStringLiteral("ACCOUNT:addInterest"), account1.addInterest(interest2), true)
SKGTESTERROR(QStringLiteral("INTEREST:setDate"), interest2.setDate(firstday.addMonths(1)), true)
SKGTESTERROR(QStringLiteral("INTEREST:setRate"), interest2.setRate(2.5), true)
SKGTESTERROR(QStringLiteral("INTEREST:save"), interest2.save(), true)
SKGInterestObject interest3;
SKGTESTERROR(QStringLiteral("ACCOUNT:addInterest"), account1.addInterest(interest3), true)
SKGTESTERROR(QStringLiteral("INTEREST:setDate"), interest3.setDate(firstday.addMonths(4)), true)
SKGTESTERROR(QStringLiteral("INTEREST:setRate"), interest3.setRate(1.75), true)
SKGTESTERROR(QStringLiteral("INTEREST:save"), interest3.save(), true)
// Add operations
{
SKGOperationObject op_1;
SKGTESTERROR(QStringLiteral("ACCOUNT:addOperation"), account1.addOperation(op_1), true)
SKGTESTERROR(QStringLiteral("OPE:setDate"), op_1.setDate(firstday.addDays(-1)), true)
SKGTESTERROR(QStringLiteral("OPE:setUnit"), op_1.setUnit(unit_euro), true)
SKGTESTERROR(QStringLiteral("OPE:save"), op_1.save(), true)
SKGSubOperationObject subop_1;
SKGTESTERROR(QStringLiteral("OPE:addSubOperation"), op_1.addSubOperation(subop_1), true)
SKGTESTERROR(QStringLiteral("SUBOPE:setQuantity"), subop_1.setQuantity(100), true)
SKGTESTERROR(QStringLiteral("SUBOPE:save"), subop_1.save(), true)
}
{
SKGOperationObject op_1;
SKGTESTERROR(QStringLiteral("ACCOUNT:addOperation"), account1.addOperation(op_1), true)
SKGTESTERROR(QStringLiteral("OPE:setDate"), op_1.setDate(firstday.addDays(14)), true)
SKGTESTERROR(QStringLiteral("OPE:setUnit"), op_1.setUnit(unit_euro), true)
SKGTESTERROR(QStringLiteral("OPE:save"), op_1.save(), true)
SKGSubOperationObject subop_1;
SKGTESTERROR(QStringLiteral("OPE:addSubOperation"), op_1.addSubOperation(subop_1), true)
SKGTESTERROR(QStringLiteral("SUBOPE:setQuantity"), subop_1.setQuantity(100), true)
SKGTESTERROR(QStringLiteral("SUBOPE:save"), subop_1.save(), true)
}
{
SKGOperationObject op_1;
SKGTESTERROR(QStringLiteral("ACCOUNT:addOperation"), account1.addOperation(op_1), true)
SKGTESTERROR(QStringLiteral("OPE:setDate"), op_1.setDate(firstday.addMonths(5).addDays(28)), true)
SKGTESTERROR(QStringLiteral("OPE:setUnit"), op_1.setUnit(unit_euro), true)
SKGTESTERROR(QStringLiteral("OPE:save"), op_1.save(), true)
SKGSubOperationObject subop_1;
SKGTESTERROR(QStringLiteral("OPE:addSubOperation"), op_1.addSubOperation(subop_1), true)
SKGTESTERROR(QStringLiteral("SUBOPE:setQuantity"), subop_1.setQuantity(-100), true)
SKGTESTERROR(QStringLiteral("SUBOPE:save"), subop_1.save(), true)
}
SKGAccountObject::SKGInterestItemList oInterestList;
double oInterests = 0;
SKGTESTERROR(QStringLiteral("ACCOUNT:getInterestItems"), account1.getInterestItems(oInterestList, oInterests), true)
int nb = oInterestList.count();
for (int i = 0; i < nb; ++i) {
SKGAccountObject::SKGInterestItem item = oInterestList.at(i);
SKGTRACE << "[" << item.object.getDisplayName() << "]: "
<< SKGServices::dateToSqlString(QDateTime(item.date))
<< " " << SKGServices::dateToSqlString(QDateTime(item.valueDate))
<< " " << item.amount
<< " " << item.coef
<< " " << item.rate
<< " " << item.annualInterest
<< " " << item.accruedInterest
<< endl;
}
SKGTEST(QStringLiteral("INTEREST:oInterestList.count"), oInterestList.count(), 5)
SKGTESTBOOL("INTEREST:oInterestList.at(1).date", (oInterestList.at(0).date == firstday), true)
SKGTESTBOOL("INTEREST:oInterestList.at(2).date", (oInterestList.at(1).date == firstday.addDays(14)), true)
SKGTESTBOOL("INTEREST:oInterestList.at(3).date", (oInterestList.at(2).date == firstday.addMonths(1)), true)
SKGTESTBOOL("INTEREST:oInterestList.at(6).date", (oInterestList.at(3).date == firstday.addMonths(4)), true)
SKGTESTBOOL("INTEREST:oInterestList.at(7).date", (oInterestList.at(4).date == firstday.addMonths(5).addDays(28)), true)
SKGTEST(QStringLiteral("INTEREST:oInterests"), SKGServices::doubleToString(oInterests), QStringLiteral("3.135416667"))
}
}
// End test
SKGENDTEST()
}
diff --git a/tests/skgbankmodelertest/skgtestmigration.cpp b/tests/skgbankmodelertest/skgtestmigration.cpp
index 045d9887a..e1a4daa14 100644
--- a/tests/skgbankmodelertest/skgtestmigration.cpp
+++ b/tests/skgbankmodelertest/skgtestmigration.cpp
@@ -1,56 +1,56 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is a test script.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include <qfile.h>
#include "skgdocumentbank.h"
#include "skgtestmacro.h"
/**
* The main function of the unit test
* @param argc the number of arguments
* @param argv the list of arguments
*/
int main(int argc, char** argv)
{
Q_UNUSED(argc)
Q_UNUSED(argv)
// Init test
SKGINITTEST(true) {
// Test load old version of files
{
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("DOC:load"), document1.load(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestmigration/version_0.1.skg"), true)
}
{
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("DOC:load"), document1.load(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestmigration/version_0.3.skg"), true)
}
{
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("DOC:load"), document1.load(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestmigration/version_1.12.skg"), true)
}
}
// End test
SKGENDTEST()
}
diff --git a/tests/skgbankmodelertest/skgtestobjects.cpp b/tests/skgbankmodelertest/skgtestobjects.cpp
index f760d8e60..7d90b666f 100644
--- a/tests/skgbankmodelertest/skgtestobjects.cpp
+++ b/tests/skgbankmodelertest/skgtestobjects.cpp
@@ -1,190 +1,190 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is a test script.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgtestmacro.h"
#include "skgbankincludes.h"
/**
* The main function of the unit test
* @param argc the number of arguments
* @param argv the list of arguments
*/
int main(int argc, char** argv)
{
Q_UNUSED(argc)
Q_UNUSED(argv)
// Init test
SKGINITTEST(true)
QDate now = QDate::currentDate();
{
// Test objectbase
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
SKGTEST(QStringLiteral("DOC:getDisplay"), document1.getDisplay(QStringLiteral("v_node.unknown")), QStringLiteral("v_node.unknown"))
SKGTEST(QStringLiteral("DOC:getDisplay"), document1.getDisplay(QStringLiteral("t_comment")), QStringLiteral("Comment"))
SKGTEST(QStringLiteral("DOC:getDisplay"), document1.getDisplay(QStringLiteral("p_Test")), QStringLiteral("Test"))
SKGTEST(QStringLiteral("DOC:getDisplay"), document1.getDisplay(QStringLiteral("operation.p_Test")), QStringLiteral("operation.Test"))
SKGServices::SKGAttributesList undoredoAttributes;
SKGTESTERROR(QStringLiteral("OBJBASE:getAttributesDescription)"), document1.getAttributesDescription(QStringLiteral("doctransaction"), undoredoAttributes), true)
SKGTEST(QStringLiteral("OBJBASE:undoredoAttributes.count"), undoredoAttributes.count(), 7)
SKGTEST(QStringLiteral("OBJBASE:undoredoAttributes.name"), undoredoAttributes[0].name, QStringLiteral("id"))
SKGTEST(QStringLiteral("OBJBASE:undoredoAttributes.type"), static_cast<unsigned int>(undoredoAttributes[0].type), static_cast<unsigned int>(SKGServices::ID))
SKGTESTBOOL("OBJBASE:undoredoAttributes.notnull", undoredoAttributes[0].notnull, false)
SKGTEST(QStringLiteral("OBJBASE:undoredoAttributes.defaultvalue"), undoredoAttributes[0].defaultvalue, QLatin1String(""))
SKGTEST(QStringLiteral("OBJBASE:undoredoAttributes.name"), undoredoAttributes[2].name, QStringLiteral("t_mode"))
SKGTEST(QStringLiteral("OBJBASE:undoredoAttributes.type"), static_cast<unsigned int>(undoredoAttributes[2].type), static_cast<unsigned int>(SKGServices::TEXT))
SKGTESTBOOL("OBJBASE:undoredoAttributes.notnull", undoredoAttributes[2].notnull, true)
SKGTEST(QStringLiteral("OBJBASE:undoredoAttributes.defaultvalue"), undoredoAttributes[2].defaultvalue, QStringLiteral("'U'"))
/*
| cid | name | t_type | notnull | dflt_value | pk |
| 0 | id | INTEGER | 99 | | 1 |
| 1 | name | TEXT | 99 | | 0 |
| 2 | t_mode | VARCHAR(1) | 0 | 'U' | 0 |
| 3 | d_date | DATE | 99 | | 0 |
| 4 | t_savestep | VARCHAR(1) | 0 | 'N' | 0 |
| 5 | parent | INTEGER | 0 | | 0 |
*/
QStringList undoredoAttributeNames;
SKGTESTERROR(QStringLiteral("OBJBASE:getAttributesList)"), document1.getAttributesList(QStringLiteral("doctransaction"), undoredoAttributeNames), true)
SKGTEST(QStringLiteral("OBJBASE:undoredoAttributeNames.count"), undoredoAttributeNames.count(), 7)
SKGTEST(QStringLiteral("OBJBASE:undoredoAttributeNames"), undoredoAttributeNames[0], QStringLiteral("id"))
SKGTEST(QStringLiteral("OBJBASE:undoredoAttributeNames"), undoredoAttributeNames[1], QStringLiteral("t_name"))
SKGTEST(QStringLiteral("OBJBASE:undoredoAttributeNames"), undoredoAttributeNames[2], QStringLiteral("t_mode"))
SKGTEST(QStringLiteral("OBJBASE:undoredoAttributeNames"), undoredoAttributeNames[3], QStringLiteral("d_date"))
SKGTEST(QStringLiteral("OBJBASE:undoredoAttributeNames"), undoredoAttributeNames[4], QStringLiteral("t_savestep"))
SKGTEST(QStringLiteral("OBJBASE:undoredoAttributeNames"), undoredoAttributeNames[5], QStringLiteral("t_refreshviews"))
SKGTEST(QStringLiteral("OBJBASE:undoredoAttributeNames"), undoredoAttributeNames[6], QStringLiteral("i_parent"))
SKGBEGINTRANSACTION(document1, QStringLiteral("OBJBASE 1"), err)
SKGObjectBase obj1(&document1, QStringLiteral("bank"));
SKGTESTERROR(QStringLiteral("OBJBASE:setAttribute"), obj1.setAttribute(QStringLiteral("t_name"), QStringLiteral("CL")), true)
SKGTESTERROR(QStringLiteral("OBJBASE:save"), obj1.save(), true)
SKGObjectBase obj2(&document1, QStringLiteral("bank"), obj1.getID());
SKGTESTERROR(QStringLiteral("OBJBASE:load"), obj2.load(), true)
SKGTEST(QStringLiteral("OBJBASE:getAttribute"), obj2.getAttribute(QStringLiteral("t_name")), QStringLiteral("CL"))
SKGTESTERROR(QStringLiteral("OBJBASE:setAttribute"), obj2.setAttribute(QStringLiteral("t_name"), QStringLiteral("CC")), true)
SKGTESTERROR(QStringLiteral("OBJBASE:save"), obj2.save(), true)
SKGObjectBase obj3(&document1, QStringLiteral("v_bank"), obj2.getID());
SKGTESTERROR(QStringLiteral("OBJBASE:load"), obj3.load(), true)
SKGTEST(QStringLiteral("OBJBASE:getAttribute"), obj3.getAttribute(QStringLiteral("t_name")), QStringLiteral("CC"))
SKGTEST(QStringLiteral("OBJBASE:getTable"), obj3.getTable(), QStringLiteral("v_bank"))
SKGTESTERROR(QStringLiteral("OBJBASE:save"), obj3.save(), true)
SKGObjectBase obj4(&document1);
SKGTESTBOOL("OBJBASE:Operator =", (obj2 == obj1), true)
SKGTESTBOOL("OBJBASE:Operator =", (obj3 == obj1), true)
SKGTESTBOOL("OBJBASE:Operator =", (obj4 == obj1), false)
SKGTESTBOOL("OBJBASE:Operator !=", (obj2 != obj1), false)
SKGTESTBOOL("OBJBASE:Operator !=", (obj3 != obj1), false)
SKGTESTBOOL("OBJBASE:Operator !=", (obj4 != obj1), true)
SKGQStringQStringMap att = obj3.getAttributes();
int nb = obj3.getNbAttributes();
SKGTEST(QStringLiteral("OBJBASE:getNbAttributes"), obj3.getNbAttributes(), att.count())
for (int i = 0; i < nb; ++i) {
SKGTRACE << i << ":" << obj3.getAttribute(SKGServices::intToString(i)) << endl;
}
SKGTEST(QStringLiteral("OBJBASE:getAttribute"), obj3.getAttribute(QStringLiteral("2")), QStringLiteral("CC"))
SKGTESTBOOL("OBJBASE:exist", obj3.exist(), true)
SKGTESTERROR(QStringLiteral("OBJBASE:dump"), obj3.dump(), true)
SKGTEST(QStringLiteral("OBJBASE:getID"), obj3.getID(), 1)
SKGTESTERROR(QStringLiteral("OBJBASE:resetID"), obj3.resetID(), true)
SKGTEST(QStringLiteral("OBJBASE:getID"), obj3.getID(), 0)
SKGNamedObject tmp1(obj3);
const SKGNamedObject& tmp2 = tmp1;
SKGTEST(QStringLiteral("OBJBASE:getAttribute"), tmp2.getAttribute(QStringLiteral("t_name")), QStringLiteral("CC"))
// Test error
SKGObjectBase notFound;
SKGTESTERROR(QStringLiteral("OBJBASE:getObject"), document1.getObject(QStringLiteral("v_bank"), QStringLiteral("t_name='NOTFOUND'"), notFound), false)
SKGTESTERROR(QStringLiteral("OBJBASE:getObject"), document1.getObject(QStringLiteral("parameters"), QStringLiteral("'"), notFound), false)
SKGTESTERROR(QStringLiteral("OBJBASE:getObject"), document1.getObject(QStringLiteral("v_bank"), 9999, notFound), false)
}
}
// ============================================================================
// ============================================================================
{
// Test bank document
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
SKGTEST(QStringLiteral("BANK:getNbTransaction"), document1.getNbTransaction(), 0) {
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("BANK_T1"), err)
// The code here
IFOK(err) {
SKGTEST(QStringLiteral("BANK:getDepthTransaction"), document1.getDepthTransaction(), 1)
// Example; operation succeeded
SKGTESTERROR(QStringLiteral("BANK:setParameter"), document1.setParameter(QStringLiteral("ATT1"), QStringLiteral("VAL1")), true)
SKGTESTERROR(QStringLiteral("BANK:setParameter"), document1.setParameter(QStringLiteral("ATT2"), QStringLiteral("VAL2")), true)
SKGTESTERROR(QStringLiteral("BANK:setParameter"), document1.setParameter(QStringLiteral("ATT3"), QStringLiteral("VAL2")), true)
QStringList oResult;
SKGTESTERROR(QStringLiteral("BANK:getDistinctValues"), document1.getDistinctValues(QStringLiteral("parameters"), QStringLiteral("t_value"), QStringLiteral("t_value like 'VAL%'"), oResult), true)
SKGTEST(QStringLiteral("BANK:oResult.size"), oResult.size(), 2)
// Test account
SKGTESTERROR(QStringLiteral("BANK:addOrModifyAccount"), document1.addOrModifyAccount(QStringLiteral("Courant"), QStringLiteral("123"), QStringLiteral("LCL")), true)
SKGTESTERROR(QStringLiteral("BANK:addOrModifyAccount"), document1.addOrModifyAccount(QStringLiteral("Livret A"), QStringLiteral("456"), QStringLiteral("CREDIT COOP")), true)
SKGTESTERROR(QStringLiteral("BANK:addOrModifyAccount"), document1.addOrModifyAccount(QStringLiteral("Codevi"), QStringLiteral("789"), QStringLiteral("NEF")), true)
SKGTESTERROR(QStringLiteral("BANK:addOrModifyAccount"), document1.addOrModifyAccount(QStringLiteral("PEA"), QStringLiteral("ABC"), QStringLiteral("CA")), true)
SKGTESTERROR(QStringLiteral("BANK:getDistinctValues"), document1.getDistinctValues(QStringLiteral("account"), QStringLiteral("t_name"), oResult), true)
SKGTEST(QStringLiteral("BANK:oResult.size"), oResult.size(), 4)
// Test units
SKGTESTERROR(QStringLiteral("BANK:addOrModifyUnitValue"), document1.addOrModifyUnitValue(QStringLiteral("E"), now, 1), true)
SKGTESTERROR(QStringLiteral("BANK:addOrModifyUnitValue"), document1.addOrModifyUnitValue(QStringLiteral("$"), now, 1.6), true) // Oups, it is an error
SKGTESTERROR(QStringLiteral("BANK:addOrModifyUnitValue"), document1.addOrModifyUnitValue(QStringLiteral("$"), now, 0.625), true) // it is better now
SKGTESTERROR(QStringLiteral("BANK:getDistinctValues"), document1.getDistinctValues(QStringLiteral("unitvalue"), QStringLiteral("rd_unit_id"), oResult), true)
SKGTEST(QStringLiteral("BANK:oResult.size"), oResult.size(), 2)
}
} // A commit is done here because the scope is close
QStringList oResult;
SKGTESTERROR(QStringLiteral("BANK:getDistinctValues"), document1.getDistinctValues(QStringLiteral("unit"), QStringLiteral("t_name"), oResult), true)
SKGTEST(QStringLiteral("BANK:oResult.size"), oResult.size(), 2)
SKGTESTERROR(QStringLiteral("BANK:undoRedoTransaction(BANK_T1, SKGDocument::UNDO)"), document1.undoRedoTransaction(), true)
SKGTESTERROR(QStringLiteral("BANK:getDistinctValues"), document1.getDistinctValues(QStringLiteral("unit"), QStringLiteral("t_name"), oResult), true)
SKGTEST(QStringLiteral("BANK:oResult.size"), oResult.size(), 0)
SKGTESTERROR(QStringLiteral("BANK:undoRedoTransaction(BANK_T1, SKGDocument::REDO)"), document1.undoRedoTransaction(SKGDocument::REDO), true)
SKGTESTERROR(QStringLiteral("BANK:getDistinctValues"), document1.getDistinctValues(QStringLiteral("unit"), QStringLiteral("t_name"), oResult), true)
SKGTEST(QStringLiteral("BANK:oResult.size"), oResult.size(), 2)
SKGTESTERROR(QStringLiteral("BANK:err"), err, true)
}
// End test
SKGENDTEST()
}
diff --git a/tests/skgbankmodelertest/skgtestoperation.cpp b/tests/skgbankmodelertest/skgtestoperation.cpp
index e72b0bead..8b13d576c 100644
--- a/tests/skgbankmodelertest/skgtestoperation.cpp
+++ b/tests/skgbankmodelertest/skgtestoperation.cpp
@@ -1,496 +1,496 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is a test script.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include <qfile.h>
#include "skgbankincludes.h"
#include "skgtestmacro.h"
/**
* The main function of the unit test
* @param argc the number of arguments
* @param argv the list of arguments
*/
int main(int argc, char** argv)
{
Q_UNUSED(argc)
Q_UNUSED(argv)
// Init test
SKGINITTEST(true)
QString filename = SKGTest::getTestPath(QStringLiteral("OUT")) % "/skgtestoperation.skg";
QDate now = QDate::currentDate();
QDate tomorrow = QDate::currentDate().addDays(+1);
// ============================================================================
{
// Test bank document
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGUnitValueObject unit_euro_val1;
SKGBankObject bank(&document1);
SKGUnitObject unit_euro(&document1);
SKGAccountObject account;
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("BANK_T1"), err)
// Creation bank
SKGTESTERROR(QStringLiteral("BANK:setName"), bank.setName(QStringLiteral("CREDIT COOP")), true)
SKGTESTERROR(QStringLiteral("BANK:save"), bank.save(), true)
// Creation account
SKGTESTERROR(QStringLiteral("BANK:addAccount"), bank.addAccount(account), true)
SKGTESTERROR(QStringLiteral("ACCOUNT:setName"), account.setName(QStringLiteral("Courant steph")), true)
SKGOperationObject op_1;
SKGTESTERROR(QStringLiteral("ACCOUNT:addOperation"), account.addOperation(op_1), false)
SKGTESTERROR(QStringLiteral("OP:setParentAccount"), op_1.setParentAccount(account), false)
SKGTESTERROR(QStringLiteral("ACCOUNT:setClosed"), account.setClosed(true), true)
SKGTESTERROR(QStringLiteral("ACCOUNT:save"), account.save(), true)
// Creation operation ==> failed
SKGTESTERROR(QStringLiteral("ACCOUNT:addOperation"), account.addOperation(op_1), false)
// Reopen account
SKGTESTERROR(QStringLiteral("ACCOUNT:setClosed"), account.setClosed(false), true)
SKGTESTERROR(QStringLiteral("ACCOUNT:save"), account.save(), true)
// Creation unit
SKGTESTERROR(QStringLiteral("UNIT:setName"), unit_euro.setName(QStringLiteral("euro")), true)
SKGTESTERROR(QStringLiteral("UNIT:save"), unit_euro.save(), true)
// Creation unitvalue
SKGTESTERROR(QStringLiteral("UNIT:addUnitValue"), unit_euro.addUnitValue(unit_euro_val1), true)
SKGTESTERROR(QStringLiteral("UNITVALUE:setQuantity"), unit_euro_val1.setQuantity(1), true)
SKGTESTERROR(QStringLiteral("UNITVALUE:setDate"), unit_euro_val1.setDate(now), true)
SKGTESTERROR(QStringLiteral("UNITVALUE:save"), unit_euro_val1.save(), true)
// Creation operation ==> OK
SKGTESTERROR(QStringLiteral("ACCOUNT:addOperation"), account.addOperation(op_1), true)
SKGSubOperationObject subop_1;
SKGTESTERROR(QStringLiteral("OPE:addSubOperation"), op_1.addSubOperation(subop_1), false)
SKGTESTERROR(QStringLiteral("OPE:setDate"), op_1.setDate(now), true)
SKGTESTERROR(QStringLiteral("OPE:setUnit"), op_1.setUnit(unit_euro), true)
SKGTESTERROR(QStringLiteral("OPE:save"), op_1.save(), true)
SKGTESTERROR(QStringLiteral("OPE:addSubOperation"), op_1.addSubOperation(subop_1), true)
SKGTESTERROR(QStringLiteral("SUBOPE:save"), subop_1.save(), true)
SKGTESTERROR(QStringLiteral("OPE:setDate"), op_1.setDate(now), true)
SKGTESTERROR(QStringLiteral("OPE:save"), op_1.save(), true)
SKGTEST(QStringLiteral("OPE:getDate"), SKGServices::dateToSqlString(op_1.getDate()), SKGServices::dateToSqlString(now))
SKGTEST(QStringLiteral("SUBOPE:getDate"), SKGServices::dateToSqlString(subop_1.getDate()), SKGServices::dateToSqlString(now))
SKGTESTERROR(QStringLiteral("SUBOPE:setDate"), subop_1.setDate(tomorrow), true)
SKGTESTERROR(QStringLiteral("SUBOPE:save"), subop_1.save(), true)
SKGTEST(QStringLiteral("SUBOPE:getDate"), SKGServices::dateToSqlString(subop_1.getDate()), SKGServices::dateToSqlString(tomorrow))
SKGTESTERROR(QStringLiteral("OPE:setDate"), op_1.setDate(tomorrow), true)
SKGTESTERROR(QStringLiteral("OPE:save"), op_1.save(), true)
SKGTESTERROR(QStringLiteral("SUBOPE:load"), subop_1.load(), true)
SKGTEST(QStringLiteral("OPE:getDate"), SKGServices::dateToSqlString(op_1.getDate()), SKGServices::dateToSqlString(tomorrow))
SKGTEST(QStringLiteral("SUBOPE:getDate"), SKGServices::dateToSqlString(subop_1.getDate()), SKGServices::dateToSqlString(tomorrow.addDays(+1)))
}
}
// ============================================================================
{
// Test bank document
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGUnitValueObject unit_euro_val1;
SKGBankObject bank(&document1);
SKGUnitObject unit_euro(&document1);
SKGAccountObject account;
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("BANK_T1"), err)
// Creation bank
SKGTESTERROR(QStringLiteral("BANK:setName"), bank.setName(QStringLiteral("CREDIT COOP")), true)
SKGTESTERROR(QStringLiteral("BANK:save"), bank.save(), true)
// Creation account
SKGTESTERROR(QStringLiteral("BANK:addAccount"), bank.addAccount(account), true)
SKGTESTERROR(QStringLiteral("ACCOUNT:setName"), account.setName(QStringLiteral("Courant steph")), true)
SKGTESTERROR(QStringLiteral("ACCOUNT:setNumber"), account.setNumber(QStringLiteral("12345P")), true)
SKGTESTERROR(QStringLiteral("ACCOUNT:save"), account.save(), true)
// Creation unit
SKGTESTERROR(QStringLiteral("UNIT:setName"), unit_euro.setName(QStringLiteral("euro")), true)
SKGTESTERROR(QStringLiteral("UNIT:save"), unit_euro.save(), true)
// Creation unitvalue
SKGTESTERROR(QStringLiteral("UNIT:addUnitValue"), unit_euro.addUnitValue(unit_euro_val1), true)
SKGTESTERROR(QStringLiteral("UNITVALUE:setQuantity"), unit_euro_val1.setQuantity(1), true)
SKGTESTERROR(QStringLiteral("UNITVALUE:setDate"), unit_euro_val1.setDate(now), true)
SKGTESTERROR(QStringLiteral("UNITVALUE:save"), unit_euro_val1.save(), true)
// Creation categories
SKGCategoryObject cat_1(&document1);
SKGTESTERROR(QStringLiteral("CAT:setName"), cat_1.setName(QStringLiteral("transport")), true)
SKGTESTERROR(QStringLiteral("CAT:save"), cat_1.save(), true)
SKGCategoryObject cat_2;
SKGTESTERROR(QStringLiteral("CAT:addCategory"), cat_1.addCategory(cat_2), true)
SKGTESTERROR(QStringLiteral("CAT:setName"), cat_2.setName(QStringLiteral("train")), true)
SKGTESTERROR(QStringLiteral("CAT:save"), cat_2.save(), true)
// Creation operation
SKGOperationObject mainOperation;
double balance = 0;
for (int i = 1; i <= 10; ++i) {
SKGOperationObject op_1;
SKGTESTERROR(QStringLiteral("ACCOUNT:addOperation"), account.addOperation(op_1), true)
SKGTESTERROR(QStringLiteral("OPE:setTemplate"), op_1.setTemplate(true), true)
SKGTESTBOOL("OPE:isTemplate", op_1.isTemplate(), true)
SKGTESTERROR(QStringLiteral("OPE:setTemplate"), op_1.setTemplate(false), true)
SKGTESTBOOL("OPE:isTemplate", op_1.isTemplate(), false)
SKGTESTERROR(QStringLiteral("OPE:setNumber"), op_1.setNumber(SKGServices::intToString(1000 + i)), true)
SKGTESTERROR(QStringLiteral("OPE:setMode"), op_1.setMode(QStringLiteral("cheque")), true)
SKGTESTERROR(QStringLiteral("OPE:setComment"), op_1.setComment(QStringLiteral("10 tickets")), true)
SKGTESTERROR(QStringLiteral("OPE:setDate"), op_1.setDate(now), true)
SKGTESTERROR(QStringLiteral("OPE:setUnit"), op_1.setUnit(unit_euro), true)
SKGUnitObject u;
SKGTESTERROR(QStringLiteral("OPE:setUnit"), op_1.getUnit(u), true)
SKGTESTERROR(QStringLiteral("OPE:bookmark"), op_1.bookmark(i % 2 == 0), true)
SKGTESTERROR(QStringLiteral("OPE:save"), op_1.save(), true)
if (i == 1) {
mainOperation = op_1;
SKGTESTERROR(QStringLiteral("OPE:setGroupOperation"), mainOperation.setGroupOperation(mainOperation), true)
SKGTESTERROR(QStringLiteral("OPE:save"), mainOperation.save(), true)
} else {
if (!op_1.isBookmarked()) {
SKGTESTERROR(QStringLiteral("OPE:setGroupOperation"), op_1.setGroupOperation(mainOperation), true)
}
SKGTESTERROR(QStringLiteral("OPE:save"), op_1.save(), true)
}
// Creation suboperation
for (int j = 1; j <= 5; ++j) {
SKGSubOperationObject subop_1;
SKGTESTERROR(QStringLiteral("OPE:addSubOperation"), op_1.addSubOperation(subop_1), true)
SKGTESTERROR(QStringLiteral("SUBOPE:setCategory"), subop_1.setCategory(cat_2), true)
SKGTESTERROR(QStringLiteral("SUBOPE:setComment"), subop_1.setComment(QStringLiteral("subop")), true)
SKGTEST(QStringLiteral("SUBOPE:getComment"), subop_1.getComment(), QStringLiteral("subop"))
SKGTESTERROR(QStringLiteral("OPE:setFormula"), subop_1.setFormula(QStringLiteral("total*0.196")), true)
SKGTEST(QStringLiteral("SUBOPE:getFormula"), subop_1.getFormula(), QStringLiteral("total*0.196"))
SKGTESTERROR(QStringLiteral("SUBOPE:setQuantity"), subop_1.setQuantity(i * j), true)
SKGTESTERROR(QStringLiteral("SUBOPE:save"), subop_1.save(), true)
SKGTESTERROR(QStringLiteral("SUBOPE:load"), subop_1.load(), true)
SKGOperationObject opget;
SKGTESTERROR(QStringLiteral("SUBOPE:getParentOperation"), subop_1.getParentOperation(opget), true)
SKGTESTBOOL("OPE:comparison", (opget == op_1), true)
SKGSubOperationObject subop_12 = subop_1;
SKGSubOperationObject subop_13((SKGObjectBase(subop_1)));
SKGSubOperationObject subop_14 = SKGSubOperationObject(subop_1);
SKGObjectBase subop_base = subop_1;
SKGSubOperationObject subop_15;
subop_15 = subop_base;
}
// Checks
SKGTESTERROR(QStringLiteral("OPE:load"), op_1.load(), true)
SKGTEST(QStringLiteral("OPE:getCurrentAmount"), op_1.getCurrentAmount(), i * 15)
balance += i * 15;
SKGTEST(QStringLiteral("OPE:getNbSubOperations"), op_1.getNbSubOperations(), 5)
SKGTEST(QStringLiteral("OPE:getBalance"), op_1.getBalance(), balance)
}
SKGTESTERROR(QStringLiteral("ACCOUNT:load"), account.load(), true)
SKGTEST(QStringLiteral("ACCOUNT:getCurrentAmount"), account.getCurrentAmount(), 55 * 15)
SKGTEST(QStringLiteral("ACCOUNT:getAmount"), account.getAmount(QDate::currentDate()), 55 * 15)
SKGUnitObject getUnit;
SKGTESTERROR(QStringLiteral("ACCOUNT:getUnit"), account.getUnit(getUnit), true)
SKGTESTBOOL("ACCOUNT:unit", (getUnit == unit_euro), true)
SKGTESTERROR(QStringLiteral("OPE:load"), mainOperation.load(), true)
SKGObjectBase::SKGListSKGObjectBase oGroupedOperations;
SKGTESTERROR(QStringLiteral("OPE:getGroupedOperations"), mainOperation.getGroupedOperations(oGroupedOperations), true)
SKGTEST(QStringLiteral("OPE:oGroupedOperations"), oGroupedOperations.size(), 2) // Normal
SKGTESTBOOL("OPE:isInGroup", mainOperation.isInGroup(), true) // Normal
SKGOperationObject mainOpe;
SKGTESTERROR(QStringLiteral("OPE:getGroupedOperations"), mainOperation.getGroupOperation(mainOpe), true)
SKGTESTBOOL("OPE:isImported", mainOperation.isImported(), false)
SKGTESTBOOL("OPE:isTransfer", mainOperation.isTransfer(mainOpe), false)
SKGTEST(QStringLiteral("OPE:getAmount"), mainOpe.getAmount(QDate::currentDate()), 135)
SKGAccountObject acc;
SKGTESTERROR(QStringLiteral("OPE:getParentAccount"), mainOperation.getParentAccount(acc), true)
SKGTESTBOOL("OPE:account==acc", (account == acc), true)
SKGTEST(QStringLiteral("OPE:getImportID"), mainOperation.getImportID(), QLatin1String(""))
SKGObjectBase::SKGListSKGObjectBase oSubOperations;
SKGTESTERROR(QStringLiteral("OPE:getSubOperations"), mainOperation.getSubOperations(oSubOperations), true)
SKGTEST(QStringLiteral("OPE:oSubOperations"), oSubOperations.size(), 5)
SKGTESTERROR(QStringLiteral("BANK:load"), bank.load(), true)
} // A commit is done here because the scope is close
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("BANK_T2"), err)
SKGTESTERROR(QStringLiteral("UNITVALUE:setQuantity"), unit_euro_val1.setQuantity(2.5), true)
SKGTESTERROR(QStringLiteral("UNITVALUE:save"), unit_euro_val1.save(), true)
SKGTESTERROR(QStringLiteral("ACCOUNT:load"), account.load(), true)
SKGTEST(QStringLiteral("ACCOUNT:getCurrentAmount"), account.getCurrentAmount(), 55 * 15 * 2.5)
SKGTESTERROR(QStringLiteral("BANK:load"), bank.load(), true)
SKGTEST(QStringLiteral("BANK:getCurrentAmount"), bank.getCurrentAmount(), 55 * 15 * 2.5)
}
QFile(filename).remove();
SKGTESTERROR(QStringLiteral("DOC:saveAs"), document1.saveAs(filename), true)
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("BANK_T3"), err)
// Test foreign key constrain
SKGTESTERROR(QStringLiteral("UNIT:remove"), unit_euro.remove(), false)
}
}
// ============================================================================
{
// Test bank document
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.load"), document1.load(filename), true)
SKGAccountObject account;
SKGTESTERROR(QStringLiteral("SKGAccountObject::getObjectByName"), SKGAccountObject::getObjectByName(&document1, QStringLiteral("v_account"), QStringLiteral("Courant steph"), account), true)
SKGTEST(QStringLiteral("ACCOUNT:getCurrentAmount"), account.getCurrentAmount(), 55 * 15 * 2.5)
SKGBankObject bank;
SKGTESTERROR(QStringLiteral("SKGBankObject::getObjectByName"), SKGBankObject::getObjectByName(&document1, QStringLiteral("v_bank"), QStringLiteral("CREDIT COOP"), bank), true)
SKGTEST(QStringLiteral("BANK:getCurrentAmount"), bank.getCurrentAmount(), 55 * 15 * 2.5)
SKGTESTERROR(QStringLiteral("BANK:undoRedoTransaction"), document1.undoRedoTransaction(), true)
SKGTESTERROR(QStringLiteral("ACCOUNT:load"), account.load(), true)
SKGTEST(QStringLiteral("ACCOUNT:getCurrentAmount"), account.getCurrentAmount(), 55 * 15)
SKGTESTERROR(QStringLiteral("BANK:load"), bank.load(), true)
SKGTEST(QStringLiteral("BANK:getCurrentAmount"), bank.getCurrentAmount(), 55 * 15)
// delete cascade
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("BANK_T2"), err)
SKGTESTERROR(QStringLiteral("BANK:delete"), bank.remove(), true)
}
QStringList oResult;
SKGTESTERROR(QStringLiteral("BANK:getDistinctValues"), document1.getDistinctValues(QStringLiteral("bank"), QStringLiteral("id"), oResult), true)
SKGTEST(QStringLiteral("BANK:oResult.size"), oResult.size(), 0)
SKGTESTERROR(QStringLiteral("ACCOUNT:getDistinctValues"), document1.getDistinctValues(QStringLiteral("account"), QStringLiteral("id"), oResult), true)
SKGTEST(QStringLiteral("ACCOUNT:oResult.size"), oResult.size(), 0)
SKGTESTERROR(QStringLiteral("OPE:getDistinctValues"), document1.getDistinctValues(QStringLiteral("operation"), QStringLiteral("id"), oResult), true)
SKGTEST(QStringLiteral("OPE:oResult.size"), oResult.size(), 0)
SKGTESTERROR(QStringLiteral("SUBOPE:getDistinctValues"), document1.getDistinctValues(QStringLiteral("suboperation"), QStringLiteral("id"), oResult), true)
SKGTEST(QStringLiteral("SUBOPE:oResult.size"), oResult.size(), 0)
SKGTESTERROR(QStringLiteral("BANK:undoRedoTransaction"), document1.undoRedoTransaction(), true)
SKGTESTERROR(QStringLiteral("BANK:undoRedoTransaction(SKGDocument::REDO)"), document1.undoRedoTransaction(SKGDocument::REDO), true)
QFile(filename).remove();
}
// ============================================================================
{
// Test bank document
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGUnitValueObject unit_euro_val1;
SKGBankObject bank(&document1);
SKGUnitObject unit_euro(&document1);
SKGAccountObject account1;
SKGAccountObject account2;
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("BANK_T1"), err)
// Creation bank
SKGTESTERROR(QStringLiteral("BANK:setName"), bank.setName(QStringLiteral("CREDIT COOP")), true)
SKGTESTERROR(QStringLiteral("BANK:save"), bank.save(), true)
// Creation account
SKGTESTERROR(QStringLiteral("BANK:addAccount"), bank.addAccount(account1), true)
SKGTESTERROR(QStringLiteral("ACCOUNT:setName"), account1.setName(QStringLiteral("Courant steph")), true)
SKGTESTERROR(QStringLiteral("ACCOUNT:setType"), account1.setType(SKGAccountObject::CURRENT), true)
SKGTESTERROR(QStringLiteral("ACCOUNT:save"), account1.save(), true)
SKGTESTERROR(QStringLiteral("BANK:addAccount"), bank.addAccount(account2), true)
SKGTESTERROR(QStringLiteral("ACCOUNT:setName"), account2.setName(QStringLiteral("Loan")), true)
SKGTESTERROR(QStringLiteral("ACCOUNT:setType"), account2.setType(SKGAccountObject::CURRENT), true)
SKGTESTERROR(QStringLiteral("ACCOUNT:save"), account2.save(), true)
// Creation unit
SKGTESTERROR(QStringLiteral("UNIT:setName"), unit_euro.setName(QStringLiteral("euro")), true)
SKGTESTERROR(QStringLiteral("UNIT:save"), unit_euro.save(), true)
// Creation unitvalue
SKGTESTERROR(QStringLiteral("UNIT:addUnitValue"), unit_euro.addUnitValue(unit_euro_val1), true)
SKGTESTERROR(QStringLiteral("UNITVALUE:setQuantity"), unit_euro_val1.setQuantity(1), true)
SKGTESTERROR(QStringLiteral("UNITVALUE:setDate"), unit_euro_val1.setDate(now), true)
SKGTESTERROR(QStringLiteral("UNITVALUE:save"), unit_euro_val1.save(), true)
// Creation operations
SKGOperationObject op_1;
SKGTESTERROR(QStringLiteral("ACCOUNT:addOperation"), account1.addOperation(op_1), true)
SKGTESTERROR(QStringLiteral("OPE:setDate"), op_1.setDate(now), true)
SKGTESTERROR(QStringLiteral("OPE:setUnit"), op_1.setUnit(unit_euro), true)
SKGTESTERROR(QStringLiteral("OPE:setNumber"), op_1.setNumber(QStringLiteral("5490990004")), true)
SKGTESTERROR(QStringLiteral("OPE:save"), op_1.save(), true)
SKGTEST(QStringLiteral("OPE:getNumber"), op_1.getNumber(), QStringLiteral("5490990004"))
SKGSubOperationObject subop_1;
SKGTESTERROR(QStringLiteral("OPE:addSubOperation"), op_1.addSubOperation(subop_1), true)
SKGTESTERROR(QStringLiteral("SUBOPE:setQuantity"), subop_1.setQuantity(10), true)
SKGTESTERROR(QStringLiteral("SUBOPE:save"), subop_1.save(), true)
SKGOperationObject op_2;
SKGTESTERROR(QStringLiteral("ACCOUNT:addOperation"), account2.addOperation(op_2), true)
SKGTESTERROR(QStringLiteral("OPE:setDate"), op_2.setDate(now), true)
SKGTESTERROR(QStringLiteral("OPE:setUnit"), op_2.setUnit(unit_euro), true)
SKGTESTERROR(QStringLiteral("OPE:save"), op_2.save(), true)
SKGSubOperationObject subop_2;
SKGTESTERROR(QStringLiteral("OPE:addSubOperation"), op_2.addSubOperation(subop_2), true)
SKGTESTERROR(QStringLiteral("SUBOPE:setQuantity"), subop_2.setQuantity(-10), true)
SKGTESTERROR(QStringLiteral("SUBOPE:save"), subop_2.save(), true)
SKGTESTERROR(QStringLiteral("OPE:setGroupOperation"), op_1.setGroupOperation(op_2), true)
SKGTESTERROR(QStringLiteral("OPE:setStatus"), op_1.setStatus(SKGOperationObject::POINTED), true)
SKGTESTERROR(QStringLiteral("OPE:save"), op_1.save(), true)
SKGOperationObject tmp;
SKGOperationObject tmp2;
SKGTESTBOOL("OPE:isTransfer", op_1.isTransfer(tmp), true)
SKGTESTBOOL("OPE:isTransfer", tmp.isTransfer(tmp2), true)
SKGTESTBOOL("OPE:equal", (tmp == op_2), true)
SKGTESTERROR(QStringLiteral("ACCOUNT:setType"), account2.setType(SKGAccountObject::LOAN), true)
SKGTESTERROR(QStringLiteral("ACCOUNT:save"), account2.save(), true)
SKGTESTERROR(QStringLiteral("OPE:load"), op_1.load(), true)
SKGTESTBOOL("OPE:isTransfer", op_1.isTransfer(tmp), false)
SKGTESTBOOL("OPE:isTransfer", tmp.isTransfer(tmp2), false)
SKGTESTBOOL("OPE:equal", (tmp == op_2), true)
SKGTESTERROR(QStringLiteral("OPE:mergeSuboperations"), op_1.mergeSuboperations(op_2), true)
SKGTESTERROR(QStringLiteral("ACCOUNT:setLinkedAccount"), account1.setLinkedAccount(account2), true)
SKGAccountObject account2_2;
SKGTESTERROR(QStringLiteral("ACCOUNT:getLinkedAccount"), account1.getLinkedAccount(account2_2), true)
SKGTESTBOOL("OPE:equal", (account2 == account2_2), true)
SKGObjectBase::SKGListSKGObjectBase accounts;
SKGTESTERROR(QStringLiteral("ACCOUNT:getLinkedByAccounts"), account2.getLinkedByAccounts(accounts), true)
SKGTESTERROR(QStringLiteral("ACCOUNT:transferDeferredOperations"), account1.transferDeferredOperations(account2), true)
// Creation template
SKGOperationObject template1;
SKGTESTERROR(QStringLiteral("ACCOUNT:addOperation"), account1.addOperation(template1), true)
SKGTESTERROR(QStringLiteral("OPE:setDate"), template1.setDate(now.addDays(-5)), true)
SKGTESTERROR(QStringLiteral("OPE:setUnit"), template1.setUnit(unit_euro), true)
SKGTESTERROR(QStringLiteral("OPE:setComment"), template1.setComment(QStringLiteral("Comment op")), true)
SKGTESTERROR(QStringLiteral("OPE:setTemplate"), template1.setTemplate(true), true)
SKGTESTERROR(QStringLiteral("OPE:save"), template1.save(), true)
SKGSubOperationObject template1_1;
SKGTESTERROR(QStringLiteral("OPE:addSubOperation"), template1.addSubOperation(template1_1), true)
SKGTESTERROR(QStringLiteral("SUBOPE:setDate"), template1_1.setDate(now.addDays(-4)), true)
SKGTESTERROR(QStringLiteral("SUBOPE:setQuantity"), template1_1.setQuantity(10), true)
SKGTESTERROR(QStringLiteral("SUBOPE:setComment"), template1.setComment(QStringLiteral("Comment sub op 1")), true)
SKGTESTERROR(QStringLiteral("SUBOPE:save"), template1_1.save(), true)
SKGSubOperationObject template1_2;
SKGTESTERROR(QStringLiteral("OPE:addSubOperation"), template1.addSubOperation(template1_2), true)
SKGTESTERROR(QStringLiteral("SUBOPE:setDate"), template1_2.setDate(now.addDays(-3)), true)
SKGTESTERROR(QStringLiteral("SUBOPE:setQuantity"), template1_2.setQuantity(90), true)
SKGTESTERROR(QStringLiteral("SUBOPE:setComment"), template1_2.setComment(QStringLiteral("Comment sub op 2")), true)
SKGTESTERROR(QStringLiteral("SUBOPE:save"), template1_2.save(), true)
// Creation op
SKGOperationObject opbasic;
SKGTESTERROR(QStringLiteral("ACCOUNT:addOperation"), account1.addOperation(opbasic), true)
SKGTESTERROR(QStringLiteral("OPE:setDate"), opbasic.setDate(now), true)
SKGTESTERROR(QStringLiteral("OPE:setUnit"), opbasic.setUnit(unit_euro), true)
SKGTESTERROR(QStringLiteral("OPE:setComment"), opbasic.setComment(QStringLiteral("Comment op2")), true)
SKGTESTERROR(QStringLiteral("OPE:save"), opbasic.save(), true)
SKGSubOperationObject opbasic_1;
SKGTESTERROR(QStringLiteral("OPE:addSubOperation"), opbasic.addSubOperation(opbasic_1), true)
SKGTESTERROR(QStringLiteral("SUBOPE:setQuantity"), opbasic_1.setQuantity(200), true)
SKGTESTERROR(QStringLiteral("SUBOPE:save"), opbasic_1.save(), true)
document1.dump(DUMPOPERATION);
SKGTESTERROR(QStringLiteral("SUBOPE:load"), template1.load(), true)
SKGTEST(QStringLiteral("OPE:getCurrentAmount"), template1.getCurrentAmount(), 100)
SKGTEST(QStringLiteral("OPE:getNbSubOperations"), template1.getNbSubOperations(), 2)
SKGTESTERROR(QStringLiteral("SUBOPE:load"), opbasic.load(), true)
SKGTEST(QStringLiteral("OPE:getCurrentAmount"), opbasic.getCurrentAmount(), 200)
SKGTEST(QStringLiteral("OPE:getNbSubOperations"), opbasic.getNbSubOperations(), 1)
// Apply the template
SKGOperationObject op;
SKGTESTERROR(QStringLiteral("OPE:duplicate"), template1.duplicate(op), true)
SKGTESTERROR(QStringLiteral("OPE:load"), op.load(), true)
SKGTEST(QStringLiteral("OPE:d_createdate"), static_cast<unsigned int>(op.getAttribute(QStringLiteral("d_createdate")) != QLatin1String("")), static_cast<unsigned int>(true))
SKGTESTERROR(QStringLiteral("OPE:mergeAttribute"), op.mergeAttribute(opbasic, SKGOperationObject::PROPORTIONAL), true)
document1.dump(DUMPOPERATION);
SKGTEST(QStringLiteral("OPE:getCurrentAmount"), template1.getCurrentAmount(), 100)
SKGTEST(QStringLiteral("OPE:getNbSubOperations"), template1.getNbSubOperations(), 2)
SKGTEST(QStringLiteral("OPE:getCurrentAmount"), op.getCurrentAmount(), 200)
SKGTEST(QStringLiteral("OPE:getNbSubOperations"), op.getNbSubOperations(), 2)
}
}
// End test
SKGENDTEST()
}
diff --git a/tests/skgbankmodelertest/skgtestpayee.cpp b/tests/skgbankmodelertest/skgtestpayee.cpp
index ba4f78d31..6d3810909 100644
--- a/tests/skgbankmodelertest/skgtestpayee.cpp
+++ b/tests/skgbankmodelertest/skgtestpayee.cpp
@@ -1,126 +1,126 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is a test script.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgtestmacro.h"
#include "skgbankincludes.h"
#include "skgservices.h"
/**
* The main function of the unit test
* @param argc the number of arguments
* @param argv the list of arguments
*/
int main(int argc, char** argv)
{
Q_UNUSED(argc)
Q_UNUSED(argv)
// Init test
SKGINITTEST(true)
// ============================================================================
{
// Test bank document
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGBankObject bank(&document1);
SKGAccountObject account;
SKGUnitObject unit_euro(&document1);
SKGUnitValueObject unit_euro_val1;
QDate d1 = QDate::currentDate().addMonths(-6);
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("BANK_T1"), err)
// Creation bank
SKGTESTERROR(QStringLiteral("BANK:setName"), bank.setName(QStringLiteral("CREDIT COOP")), true)
SKGTESTERROR(QStringLiteral("BANK:save"), bank.save(), true)
// Creation account
SKGTESTERROR(QStringLiteral("BANK:addAccount"), bank.addAccount(account), true)
SKGTESTERROR(QStringLiteral("ACCOUNT:setName"), account.setName(QStringLiteral("Courant steph")), true)
SKGTESTERROR(QStringLiteral("ACCOUNT:save"), account.save(), true)
// Creation unit
SKGTESTERROR(QStringLiteral("UNIT:setName"), unit_euro.setName(QStringLiteral("euro")), true)
SKGTESTERROR(QStringLiteral("UNIT:save"), unit_euro.save(), true)
// Creation unitvalue
SKGTESTERROR(QStringLiteral("UNIT:addUnitValue"), unit_euro.addUnitValue(unit_euro_val1), true)
SKGTESTERROR(QStringLiteral("UNITVALUE:setQuantity"), unit_euro_val1.setQuantity(1), true)
SKGTESTERROR(QStringLiteral("UNITVALUE:setDate"), unit_euro_val1.setDate(d1), true)
SKGTESTERROR(QStringLiteral("UNITVALUE:save"), unit_euro_val1.save(), true)
// Creation operation
SKGOperationObject op;
SKGTESTERROR(QStringLiteral("ACCOUNT:addOperation"), account.addOperation(op), true)
SKGTESTERROR(QStringLiteral("OPE:setMode"), op.setMode(QStringLiteral("cheque")), true)
SKGTESTERROR(QStringLiteral("OPE:setDate"), op.setDate(d1), true)
SKGTESTERROR(QStringLiteral("OPE:setUnit"), op.setUnit(unit_euro), true)
SKGTESTERROR(QStringLiteral("OPE:save"), op.save(), true)
SKGPayeeObject payee(&document1);
SKGPayeeObject payeeCopy(payee);
SKGPayeeObject payeeCopy2(static_cast<SKGObjectBase>(payee));
SKGTESTERROR(QStringLiteral("REF:setName"), payee.setName(QStringLiteral("payee")), true)
SKGTESTERROR(QStringLiteral("REF:setAddress"), payee.setAddress(QStringLiteral("address")), true)
SKGTESTBOOL("REF:isBookmarked", payee.isBookmarked(), false)
SKGTESTERROR(QStringLiteral("REF:bookmark"), payee.bookmark(true), true)
SKGTESTBOOL("REF:isBookmarked", payee.isBookmarked(), true)
SKGTESTBOOL("REF:isClosed", payee.isClosed(), false)
SKGTESTERROR(QStringLiteral("REF:setClosed"), payee.setClosed(true), true)
SKGTESTBOOL("REF:isClosed", payee.isClosed(), true)
SKGTESTERROR(QStringLiteral("REF:save"), payee.save(), true)
SKGTEST(QStringLiteral("REF:getName"), payee.getName(), QStringLiteral("payee"))
SKGTEST(QStringLiteral("REF:getAddress"), payee.getAddress(), QStringLiteral("address"))
SKGTESTERROR(QStringLiteral("OPE:setPayee"), op.setPayee(payee), true)
SKGTESTERROR(QStringLiteral("OPE:save"), op.save(), true)
SKGPayeeObject payee2;
SKGTESTERROR(QStringLiteral("OPE:getPayee"), op.getPayee(payee2), true)
SKGTESTBOOL("OPE:compare", (payee == payee2), true)
SKGCategoryObject cat;
SKGTESTERROR(QStringLiteral("REF:getCategory"), payee.getCategory(cat), false)
SKGTESTERROR(QStringLiteral("CAT:createPathCategory"), SKGCategoryObject::createPathCategory(&document1, QStringLiteral("A"), cat), true)
SKGTESTERROR(QStringLiteral("REF:setCategory"), payee.setCategory(cat), true)
SKGTESTERROR(QStringLiteral("REF:getCategory"), payee.getCategory(cat), true)
SKGTESTERROR(QStringLiteral("REF:save"), payee.save(), true)
SKGTESTERROR(QStringLiteral("REF:load"), payee.load(), true)
SKGPayeeObject pay;
SKGTESTERROR(QStringLiteral("REF:createPayee"), SKGPayeeObject::createPayee(&document1, QStringLiteral("pay"), pay, true), true)
SKGTEST(QStringLiteral("DOC:getCategoryForPayee"), document1.getCategoryForPayee(QStringLiteral("payee")), QStringLiteral("A"))
// Merge
SKGTESTERROR(QStringLiteral("CAT:merge"), payee2.merge(pay), true)
}
}
// End test
SKGENDTEST()
}
diff --git a/tests/skgbankmodelertest/skgtestpfs.cpp b/tests/skgbankmodelertest/skgtestpfs.cpp
index 6ab82d1d9..7abc9a754 100644
--- a/tests/skgbankmodelertest/skgtestpfs.cpp
+++ b/tests/skgbankmodelertest/skgtestpfs.cpp
@@ -1,67 +1,67 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is a test script.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgtestmacro.h"
#include "skgbankincludes.h"
#include "skgreportbank.h"
/**
* The main function of the unit test
* @param argc the number of arguments
* @param argv the list of arguments
*/
int main(int argc, char** argv)
{
Q_UNUSED(argc)
Q_UNUSED(argv)
// Init test
SKGINITTEST(true)
// ============================================================================
{
// Test import OFX skrooge
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.load()"), document1.load(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestpfs/personalfinancescore.skg"), true)
SKGError err;
auto* rep = qobject_cast<SKGReportBank*>(document1.getReport());
rep->setPeriod(QStringLiteral("2010"));
SKGTEST(QStringLiteral("SKGReportBank:getPersonalFinanceScore"), SKGServices::doubleToString(rep->getPersonalFinanceScoreDetails().value(QStringLiteral("value")).toDouble()), QStringLiteral("-0.04761904762"))
SKGTEST(QStringLiteral("SKGReportBank:getPersonalFinanceScore"), rep->getPersonalFinanceScoreDetails().value(QStringLiteral("level")).toString(), QStringLiteral("danger"))
rep->setPeriod(QStringLiteral("2011"));
SKGTEST(QStringLiteral("SKGReportBank:getPersonalFinanceScore"), SKGServices::doubleToString(rep->getPersonalFinanceScoreDetails().value(QStringLiteral("value")).toDouble()), QStringLiteral("3.75"))
SKGTEST(QStringLiteral("SKGReportBank:getPersonalFinanceScore"), rep->getPersonalFinanceScoreDetails().value(QStringLiteral("level")).toString(), QStringLiteral("warning"))
rep->setPeriod(QStringLiteral("2012"));
SKGTEST(QStringLiteral("SKGReportBank:getPersonalFinanceScore"), SKGServices::doubleToString(rep->getPersonalFinanceScoreDetails().value(QStringLiteral("value")).toDouble()), QStringLiteral("9.833333333"))
SKGTEST(QStringLiteral("SKGReportBank:getPersonalFinanceScore"), rep->getPersonalFinanceScoreDetails().value(QStringLiteral("level")).toString(), QStringLiteral("warning"))
rep->setPeriod(QStringLiteral("2013"));
SKGTEST(QStringLiteral("SKGReportBank:getPersonalFinanceScore"), SKGServices::doubleToString(rep->getPersonalFinanceScoreDetails().value(QStringLiteral("value")).toDouble()), QStringLiteral("11.95"))
SKGTEST(QStringLiteral("SKGReportBank:getPersonalFinanceScore"), rep->getPersonalFinanceScoreDetails().value(QStringLiteral("level")).toString(), QStringLiteral("success"))
rep->setPeriod(QStringLiteral("2014"));
SKGTEST(QStringLiteral("SKGReportBank:getPersonalFinanceScore"), SKGServices::doubleToString(rep->getPersonalFinanceScoreDetails().value(QStringLiteral("value")).toDouble()), QStringLiteral("35.95"))
SKGTEST(QStringLiteral("SKGReportBank:getPersonalFinanceScore"), rep->getPersonalFinanceScoreDetails().value(QStringLiteral("level")).toString(), QStringLiteral("success"))
}
// End test
SKGENDTEST()
}
diff --git a/tests/skgbankmodelertest/skgtestrecurrent.cpp b/tests/skgbankmodelertest/skgtestrecurrent.cpp
index f67c07670..90e436930 100644
--- a/tests/skgbankmodelertest/skgtestrecurrent.cpp
+++ b/tests/skgbankmodelertest/skgtestrecurrent.cpp
@@ -1,184 +1,184 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is a test script.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgtestmacro.h"
#include "skgbankincludes.h"
#include "skgservices.h"
/**
* The main function of the unit test
* @param argc the number of arguments
* @param argv the list of arguments
*/
int main(int argc, char** argv)
{
Q_UNUSED(argc)
Q_UNUSED(argv)
// Init test
SKGINITTEST(true)
// ============================================================================
{
// Test bank document
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGBankObject bank(&document1);
SKGAccountObject account;
SKGUnitObject unit_euro(&document1);
SKGUnitValueObject unit_euro_val1;
QDate d1 = QDate::currentDate().addMonths(-6);
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("BANK_T1"), err)
// Creation bank
SKGTESTERROR(QStringLiteral("BANK:setName"), bank.setName(QStringLiteral("CREDIT COOP")), true)
SKGTESTERROR(QStringLiteral("BANK:save"), bank.save(), true)
// Creation account
SKGTESTERROR(QStringLiteral("BANK:addAccount"), bank.addAccount(account), true)
SKGTESTERROR(QStringLiteral("ACCOUNT:setName"), account.setName(QStringLiteral("Courant steph")), true)
SKGTESTERROR(QStringLiteral("ACCOUNT:save"), account.save(), true)
// Creation unit
SKGTESTERROR(QStringLiteral("UNIT:setName"), unit_euro.setName(QStringLiteral("euro")), true)
SKGTESTERROR(QStringLiteral("UNIT:save"), unit_euro.save(), true)
// Creation unitvalue
SKGTESTERROR(QStringLiteral("UNIT:addUnitValue"), unit_euro.addUnitValue(unit_euro_val1), true)
SKGTESTERROR(QStringLiteral("UNITVALUE:setQuantity"), unit_euro_val1.setQuantity(1), true)
SKGTESTERROR(QStringLiteral("UNITVALUE:setDate"), unit_euro_val1.setDate(d1), true)
SKGTESTERROR(QStringLiteral("UNITVALUE:save"), unit_euro_val1.save(), true)
// Creation operation
SKGOperationObject op;
SKGTESTERROR(QStringLiteral("ACCOUNT:addOperation"), account.addOperation(op), true)
SKGObjectBase::SKGListSKGObjectBase recups;
SKGTESTERROR(QStringLiteral("OP:getRecurrentOperations"), op.getRecurrentOperations(recups), false)
SKGRecurrentOperationObject recuope;
SKGTESTERROR(QStringLiteral("OP:addRecurrentOperation"), op.addRecurrentOperation(recuope), false)
SKGTESTERROR(QStringLiteral("OPE:setMode"), op.setMode(QStringLiteral("cheque")), true)
SKGTESTERROR(QStringLiteral("OPE:setComment"), op.setComment(QStringLiteral("10 tickets")), true)
SKGTESTERROR(QStringLiteral("OPE:setDate"), op.setDate(d1), true)
SKGTESTERROR(QStringLiteral("OPE:setUnit"), op.setUnit(unit_euro), true)
SKGTESTERROR(QStringLiteral("OPE:save"), op.save(), true)
{
SKGSubOperationObject subop;
SKGTESTERROR(QStringLiteral("OPE:addSubOperation"), op.addSubOperation(subop), true)
SKGTESTERROR(QStringLiteral("SUBOPE:setQuantity"), subop.setQuantity(8.5), true)
SKGTESTERROR(QStringLiteral("SUBOPE:save"), subop.save(), true)
}
{
SKGSubOperationObject subop;
SKGTESTERROR(QStringLiteral("OPE:addSubOperation"), op.addSubOperation(subop), true)
SKGTESTERROR(QStringLiteral("SUBOPE:setQuantity"), subop.setQuantity(10), true)
SKGTESTERROR(QStringLiteral("SUBOPE:save"), subop.save(), true)
}
// Checks
SKGTESTERROR(QStringLiteral("OPE:load"), op.load(), true) {
SKGOperationObject op2;
SKGTESTERROR(QStringLiteral("ACCOUNT:addOperation"), account.addOperation(op2), true)
SKGTESTERROR(QStringLiteral("OPE:setMode"), op2.setMode(QStringLiteral("cheque")), true)
SKGTESTERROR(QStringLiteral("OPE:setComment"), op2.setComment(QStringLiteral("10 tickets")), true)
SKGTESTERROR(QStringLiteral("OPE:setDate"), op2.setDate(d1), true)
SKGTESTERROR(QStringLiteral("OPE:setUnit"), op2.setUnit(unit_euro), true)
SKGTESTERROR(QStringLiteral("OPE:save"), op2.save(), true)
SKGSubOperationObject subop;
SKGTESTERROR(QStringLiteral("OPE:addSubOperation"), op2.addSubOperation(subop), true)
SKGTESTERROR(QStringLiteral("SUBOPE:setQuantity"), subop.setQuantity(8.5), true)
SKGTESTERROR(QStringLiteral("SUBOPE:save"), subop.save(), true)
SKGTESTERROR(QStringLiteral("OPE:save"), op.setGroupOperation(op2), true)
SKGTESTERROR(QStringLiteral("OPE:save"), op.save(), true)
}
// Add recurrent operation
SKGTESTERROR(QStringLiteral("OP:addRecurrentOperation"), op.addRecurrentOperation(recuope), true)
SKGTESTERROR(QStringLiteral("RECOP:setPeriodIncrement"), recuope.setPeriodIncrement(2), true)
SKGTESTERROR(QStringLiteral("RECOP:setPeriodUnit"), recuope.setPeriodUnit(SKGRecurrentOperationObject::MONTH), true)
SKGTESTERROR(QStringLiteral("RECOP:setAutoWriteDays"), recuope.setAutoWriteDays(6), true)
SKGTESTERROR(QStringLiteral("RECOP:autoWriteEnabled"), recuope.autoWriteEnabled(true), true)
SKGTESTERROR(QStringLiteral("RECOP:setWarnDays"), recuope.setWarnDays(10), true)
SKGTESTERROR(QStringLiteral("RECOP:warnEnabled"), recuope.warnEnabled(true), true)
SKGTESTERROR(QStringLiteral("RECOP:setTimeLimit"), recuope.setTimeLimit(QDate::currentDate().addMonths(-4)), true)
SKGTESTERROR(QStringLiteral("RECOP:timeLimit"), recuope.timeLimit(true), true)
SKGTESTERROR(QStringLiteral("RECOP:save"), recuope.save(), true)
SKGRecurrentOperationObject recuope2(recuope);
SKGRecurrentOperationObject recuope3(SKGObjectBase(recuope.getDocument(), QStringLiteral("xxx"), recuope.getID()));
SKGRecurrentOperationObject recuope4(SKGNamedObject(recuope.getDocument(), QStringLiteral("xxx"), recuope.getID()));
SKGObjectBase::SKGListSKGObjectBase recops;
SKGTESTERROR(QStringLiteral("OP:getRecurrentOperations"), op.getRecurrentOperations(recops), true)
SKGTEST(QStringLiteral("RECOP:recops.count"), recops.count(), 1)
SKGTEST(QStringLiteral("RECOP:getPeriodIncrement"), recuope.getPeriodIncrement(), 2)
SKGTEST(QStringLiteral("RECOP:getPeriodUnit"), static_cast<unsigned int>(recuope.getPeriodUnit()), static_cast<unsigned int>(SKGRecurrentOperationObject::MONTH))
SKGTEST(QStringLiteral("RECOP:getAutoWriteDays"), recuope.getAutoWriteDays(), 6)
SKGTESTBOOL("RECOP:isAutoWriteEnabled", recuope.isAutoWriteEnabled(), true)
SKGTEST(QStringLiteral("RECOP:getWarnDays"), recuope.getWarnDays(), 10)
SKGTESTBOOL("RECOP:isWarnEnabled", recuope.isWarnEnabled(), true)
SKGTEST(QStringLiteral("RECOP:getTimeLimit"), recuope.getTimeLimit(), 3)
SKGTESTBOOL("RECOP:hasTimeLimit", recuope.hasTimeLimit(), true)
SKGTEST(QStringLiteral("RECOP:getDate"), recuope.getDate().toString(), d1.toString())
SKGOperationObject ope2;
SKGTESTERROR(QStringLiteral("RECOP:getParentOperation"), recuope.getParentOperation(ope2), true)
SKGTESTBOOL("RECOP:op==ope2", (op == ope2), true)
document1.dump(DUMPOPERATION);
int nbi = 0;
SKGTESTERROR(QStringLiteral("RECOP:process"), recuope.process(nbi), true)
SKGTEST(QStringLiteral("RECOP:nbi"), nbi, 3)
SKGTESTERROR(QStringLiteral("RECOP:getParentOperation"), recuope.getParentOperation(ope2), true)
SKGTESTBOOL("RECOP:op!=ope2", (op != ope2), true)
SKGTESTERROR(QStringLiteral("RECOP:getRecurredOperations"), recuope.getRecurredOperations(recops), true)
SKGTEST(QStringLiteral("RECOP:recops.count"), recops.count(), 3)
SKGTESTERROR(QStringLiteral("RECOP:SKGRecurrentOperationObject::process"), SKGRecurrentOperationObject::process(&document1, nbi), true)
document1.dump(DUMPOPERATION);
SKGTESTERROR(QStringLiteral("RECOP:setPeriodIncrement"), recuope.setPeriodIncrement(2), true)
SKGTESTERROR(QStringLiteral("RECOP:setPeriodUnit"), recuope.setPeriodUnit(SKGRecurrentOperationObject::DAY), true)
recuope.getNextDate();
SKGTESTERROR(QStringLiteral("RECOP:setPeriodUnit"), recuope.setPeriodUnit(SKGRecurrentOperationObject::WEEK), true)
recuope.getNextDate();
SKGTESTERROR(QStringLiteral("RECOP:setPeriodUnit"), recuope.setPeriodUnit(SKGRecurrentOperationObject::MONTH), true)
recuope.getNextDate();
SKGTESTERROR(QStringLiteral("RECOP:setPeriodUnit"), recuope.setPeriodUnit(SKGRecurrentOperationObject::YEAR), true)
recuope.getNextDate();
}
}
// End test
SKGENDTEST()
}
diff --git a/tests/skgbankmodelertest/skgtestrefund.cpp b/tests/skgbankmodelertest/skgtestrefund.cpp
index bffca4ff6..36b1a866b 100644
--- a/tests/skgbankmodelertest/skgtestrefund.cpp
+++ b/tests/skgbankmodelertest/skgtestrefund.cpp
@@ -1,152 +1,152 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is a test script.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgtestmacro.h"
#include "skgbankincludes.h"
#include "skgservices.h"
/**
* The main function of the unit test
* @param argc the number of arguments
* @param argv the list of arguments
*/
int main(int argc, char** argv)
{
Q_UNUSED(argc)
Q_UNUSED(argv)
// Init test
SKGINITTEST(true)
// ============================================================================
{
// Test bank document
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGBankObject bank(&document1);
SKGAccountObject account;
SKGUnitObject unit_euro(&document1);
SKGUnitValueObject unit_euro_val1;
QDate d1 = QDate::currentDate().addMonths(-6);
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("BANK_T1"), err)
// Creation bank
SKGTESTERROR(QStringLiteral("BANK:setName"), bank.setName(QStringLiteral("CREDIT COOP")), true)
SKGTESTERROR(QStringLiteral("BANK:save"), bank.save(), true)
// Creation account
SKGTESTERROR(QStringLiteral("BANK:addAccount"), bank.addAccount(account), true)
SKGTESTERROR(QStringLiteral("ACCOUNT:setName"), account.setName(QStringLiteral("Courant steph")), true)
SKGTESTERROR(QStringLiteral("ACCOUNT:save"), account.save(), true)
// Creation unit
SKGTESTERROR(QStringLiteral("UNIT:setName"), unit_euro.setName(QStringLiteral("euro")), true)
SKGTESTERROR(QStringLiteral("UNIT:save"), unit_euro.save(), true)
// Creation unitvalue
SKGTESTERROR(QStringLiteral("UNIT:addUnitValue"), unit_euro.addUnitValue(unit_euro_val1), true)
SKGTESTERROR(QStringLiteral("UNITVALUE:setQuantity"), unit_euro_val1.setQuantity(1), true)
SKGTESTERROR(QStringLiteral("UNITVALUE:setDate"), unit_euro_val1.setDate(d1), true)
SKGTESTERROR(QStringLiteral("UNITVALUE:save"), unit_euro_val1.save(), true)
// Creation operation
SKGOperationObject op;
SKGTESTERROR(QStringLiteral("ACCOUNT:addOperation"), account.addOperation(op), true)
SKGTESTERROR(QStringLiteral("OPE:setMode"), op.setMode(QStringLiteral("cheque")), true)
SKGTESTERROR(QStringLiteral("OPE:setDate"), op.setDate(d1), true)
SKGTESTERROR(QStringLiteral("OPE:setUnit"), op.setUnit(unit_euro), true)
SKGTESTERROR(QStringLiteral("OPE:save"), op.save(), true)
SKGSubOperationObject subop1;
SKGTESTERROR(QStringLiteral("OPE:addSubOperation"), op.addSubOperation(subop1), true)
SKGTESTERROR(QStringLiteral("SUBOPE:setQuantity"), subop1.setQuantity(21), true)
SKGTESTERROR(QStringLiteral("SUBOPE:save"), subop1.save(), true)
SKGSubOperationObject subop2;
SKGTESTERROR(QStringLiteral("OPE:addSubOperation"), op.addSubOperation(subop2), true)
SKGTESTERROR(QStringLiteral("SUBOPE:setQuantity"), subop2.setQuantity(1), true)
SKGTESTERROR(QStringLiteral("SUBOPE:save"), subop2.save(), true)
SKGTrackerObject tracker(&document1);
SKGTrackerObject trackerCopy(tracker);
SKGTrackerObject trackerCopy2(static_cast<SKGObjectBase>(tracker));
SKGTESTERROR(QStringLiteral("REF:setName"), tracker.setName(QStringLiteral("tracker")), true)
SKGTESTERROR(QStringLiteral("REF:setComment"), tracker.setComment(QStringLiteral("comment")), true)
SKGTESTERROR(QStringLiteral("REF:save"), tracker.save(), true)
SKGTEST(QStringLiteral("REF:getName"), tracker.getName(), QStringLiteral("tracker"))
SKGTEST(QStringLiteral("REF:getComment"), tracker.getComment(), QStringLiteral("comment"))
SKGTESTBOOL("REF:isClosed", tracker.isClosed(), false)
SKGTESTERROR(QStringLiteral("OPE:setClosed"), tracker.setClosed(true), true)
SKGTESTBOOL("REF:isClosed", tracker.isClosed(), true)
SKGTESTERROR(QStringLiteral("OPE:setClosed"), tracker.setClosed(false), true)
SKGTESTBOOL("REF:isClosed", tracker.isClosed(), false)
SKGTESTERROR(QStringLiteral("OPE:setTracker"), subop1.setTracker(tracker), true)
SKGTESTERROR(QStringLiteral("OPE:save"), subop1.save(), true)
SKGTESTERROR(QStringLiteral("OPE:setClosed"), tracker.setClosed(true), true)
SKGTESTERROR(QStringLiteral("OPE:save"), tracker.save(), true)
// BUG 250350 vvv
SKGTESTERROR(QStringLiteral("OPE:setTracker"), subop1.setTracker(tracker), true)
SKGTESTERROR(QStringLiteral("OPE:setTracker"), subop1.setTracker(tracker), true)
SKGTrackerObject trackerclose(&document1);
SKGTESTERROR(QStringLiteral("REF:setName"), trackerclose.setName(QStringLiteral("trackerclose")), true)
SKGTESTERROR(QStringLiteral("OPE:setClosed"), trackerclose.setClosed(true), true)
SKGTESTERROR(QStringLiteral("REF:save"), trackerclose.save(), true)
SKGTESTERROR(QStringLiteral("OPE:setTracker"), subop1.setTracker(trackerclose), false)
SKGTrackerObject trackeropen(&document1);
SKGTESTERROR(QStringLiteral("REF:setName"), trackeropen.setName(QStringLiteral("trackeropen")), true)
SKGTESTERROR(QStringLiteral("OPE:setClosed"), trackerclose.setClosed(true), true)
SKGTESTERROR(QStringLiteral("OPE:setTracker"), subop1.setTracker(trackeropen), false)
// BUG 250350 ^^^
SKGTrackerObject tracker2;
SKGTESTERROR(QStringLiteral("OPE:getTracker"), subop1.getTracker(tracker2), true)
SKGTESTBOOL("OPE:compare", (tracker == tracker2), true)
SKGTESTERROR(QStringLiteral("REF:load"), tracker.load(), true)
SKGTEST(QStringLiteral("REF:getCurrentAmount"), tracker.getCurrentAmount(), 21)
SKGObjectBase::SKGListSKGObjectBase oSubOperations;
SKGTESTERROR(QStringLiteral("REF:getSubOperations"), tracker.getSubOperations(oSubOperations), true)
SKGTEST(QStringLiteral("REF:compare"), oSubOperations.count(), 1)
SKGTrackerObject track;
SKGTESTERROR(QStringLiteral("REF:createTracker"), SKGTrackerObject::createTracker(&document1, QStringLiteral("track"), track, true), true)
SKGTESTERROR(QStringLiteral("OPE:setClosed"), tracker.setClosed(false), true)
SKGTESTERROR(QStringLiteral("REF:save"), tracker.save(), true)
SKGTESTERROR(QStringLiteral("REF:merge"), track.merge(tracker), true)
SKGTrackerObject trackBlank;
SKGTESTERROR(QStringLiteral("REF:createTracker"), SKGTrackerObject::createTracker(&document1, QLatin1String(""), trackBlank, true), true)
}
}
// End test
SKGENDTEST()
}
diff --git a/tests/skgbankmodelertest/skgtestrestore.cpp b/tests/skgbankmodelertest/skgtestrestore.cpp
index abddd17aa..5dde4f24d 100644
--- a/tests/skgbankmodelertest/skgtestrestore.cpp
+++ b/tests/skgbankmodelertest/skgtestrestore.cpp
@@ -1,75 +1,75 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is a test script.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgtestmacro.h"
#include "skgbankincludes.h"
/**
* The main function of the unit test
* @param argc the number of arguments
* @param argv the list of arguments
*/
int main(int argc, char** argv)
{
Q_UNUSED(argc)
Q_UNUSED(argv)
// Init test
SKGINITTEST(true)
{
// Test restore
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGTESTERROR(QStringLiteral("document1.load(nopwd.skg)"), document1.load(SKGTest::getTestPath(QStringLiteral("OUT")) % "/skgtestrestore/nopwd.skg", QLatin1String(""), true), true)
SKGTESTERROR(QStringLiteral("document1.load(pwd.skg)"), document1.load(SKGTest::getTestPath(QStringLiteral("OUT")) % "/skgtestrestore/pwd.skg", QLatin1String(""), true), false)
SKGTESTERROR(QStringLiteral("document1.load(pwd.skg, a)"), document1.load(SKGTest::getTestPath(QStringLiteral("OUT")) % "/skgtestrestore/pwd.skg", QStringLiteral("a"), true), true)
QFile(SKGTest::getTestPath(QStringLiteral("OUT")) % "/skgtestrestore/.nopwd.skg.wrk").remove();
SKGTESTERROR(QStringLiteral("document1.load(nopwd.skg)"), document1.load(SKGTest::getTestPath(QStringLiteral("OUT")) % "/skgtestrestore/nopwd.skg", QLatin1String(""), true), true)
}
{
// Test load file
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGTESTERROR(QStringLiteral("document1.load(sqlite_no_pwd.skg)"), document1.load(SKGTest::getTestPath(QStringLiteral("OUT")) % "/skgtestrestore/sqlite_no_pwd.skg", QLatin1String(""), true), true)
SKGTESTERROR(QStringLiteral("document1.load(sqlite_pwd_ABC.skg)"), document1.load(SKGTest::getTestPath(QStringLiteral("OUT")) % "/skgtestrestore/sqlite_pwd_ABC.skg", QStringLiteral("ABC"), true), true)
SKGTESTERROR(QStringLiteral("document1.load(sqlcipher_no_pwd.skg)"), document1.load(SKGTest::getTestPath(QStringLiteral("OUT")) % "/skgtestrestore/sqlcipher_no_pwd.skg", QLatin1String(""), true), true)
SKGTESTERROR(QStringLiteral("document1.load(sqlcipher_pwd_ABC.skg)"), document1.load(SKGTest::getTestPath(QStringLiteral("OUT")) % "/skgtestrestore/sqlcipher_pwd_ABC.skg", QStringLiteral("ABC"), true), true)
}
{
// Test load (sqlite mode) + save + load
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGTESTERROR(QStringLiteral("document1.load(nopwd.skg)"), document1.load(SKGTest::getTestPath(QStringLiteral("OUT")) % "/skgtestrestore/nopwd.skg", QLatin1String(""), true), true)
SKGTESTERROR(QStringLiteral("document1.saveas(nopwd2.skg)"), document1.saveAs(SKGTest::getTestPath(QStringLiteral("OUT")) % "/skgtestrestore/nopwd2.skg", true), true)
SKGTESTERROR(QStringLiteral("document1.load(nopwd2.skg)"), document1.load(SKGTest::getTestPath(QStringLiteral("OUT")) % "/skgtestrestore/nopwd2.skg", QLatin1String(""), true), true)
}
{
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("DOC:load"), document1.load(SKGTest::getTestPath(QStringLiteral("OUT")) % QStringLiteral("skgtestrestore/recovery.skg"), QLatin1String(""), true), true)
}
// End test
SKGENDTEST()
}
diff --git a/tests/skgbankmodelertest/skgtestrule.cpp b/tests/skgbankmodelertest/skgtestrule.cpp
index 123fbdcfe..d34c5b004 100644
--- a/tests/skgbankmodelertest/skgtestrule.cpp
+++ b/tests/skgbankmodelertest/skgtestrule.cpp
@@ -1,280 +1,280 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is a test script.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgtestmacro.h"
#include "skgbankincludes.h"
#include "skgimportexportmanager.h"
/**
* The main function of the unit test
* @param argc the number of arguments
* @param argv the list of arguments
*/
int main(int argc, char** argv)
{
Q_UNUSED(argc)
Q_UNUSED(argv)
// Init test
SKGINITTEST(true)
// ============================================================================
{
// Test import OFX skrooge
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
// Initialisation document
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_OFX"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportofx/385366.ofx"));
SKGTESTERROR(QStringLiteral("imp1.importFile"), imp1.importFile(), true)
}
// Check static methods
{
auto list = SKGRuleObject::getListOfOperators(SKGServices::TEXT, SKGRuleObject::SEARCH);
list << SKGRuleObject::getListOfOperators(SKGServices::TEXT, SKGRuleObject::UPDATE);
list << SKGRuleObject::getListOfOperators(SKGServices::INTEGER, SKGRuleObject::SEARCH);
list << SKGRuleObject::getListOfOperators(SKGServices::INTEGER, SKGRuleObject::UPDATE);
list << SKGRuleObject::getListOfOperators(SKGServices::BOOL, SKGRuleObject::SEARCH);
list << SKGRuleObject::getListOfOperators(SKGServices::BOOL, SKGRuleObject::UPDATE);
list << SKGRuleObject::getListOfOperators(SKGServices::DATE, SKGRuleObject::SEARCH);
list << SKGRuleObject::getListOfOperators(SKGServices::DATE, SKGRuleObject::UPDATE);
list << SKGRuleObject::getListOfOperators(SKGServices::TEXT, SKGRuleObject::ALARM);
list << SKGRuleObject::getListOfOperators(SKGServices::TEXT, SKGRuleObject::APPLYTEMPLATE);
for (const auto& i : qAsConst(list)) {
SKGRuleObject::getDisplayForOperator(i, QLatin1String(""), QLatin1String(""), QLatin1String(""));
SKGRuleObject::getToolTipForOperator(i);
}
SKGRuleObject::getListOfOperators(SKGServices::INTEGER, SKGRuleObject::SEARCH);
SKGRuleObject::getListOfOperators(SKGServices::FLOAT, SKGRuleObject::SEARCH);
SKGRuleObject::getListOfOperators(SKGServices::DATE, SKGRuleObject::SEARCH);
SKGRuleObject::getListOfOperators(SKGServices::BOOL, SKGRuleObject::SEARCH);
SKGRuleObject::getListOfOperators(SKGServices::TRISTATE, SKGRuleObject::SEARCH);
SKGRuleObject::getListOfOperators(SKGServices::BOOL, SKGRuleObject::SEARCH);
SKGRuleObject::getListOfOperators(SKGServices::BOOL, SKGRuleObject::SEARCH);
SKGRuleObject::getListOfOperators(SKGServices::BOOL, SKGRuleObject::SEARCH);
SKGRuleObject::getListOfOperators(SKGServices::TEXT, SKGRuleObject::UPDATE);
SKGRuleObject::getListOfOperators(SKGServices::INTEGER, SKGRuleObject::UPDATE);
SKGRuleObject::getListOfOperators(SKGServices::FLOAT, SKGRuleObject::UPDATE);
SKGRuleObject::getListOfOperators(SKGServices::DATE, SKGRuleObject::UPDATE);
SKGRuleObject::getListOfOperators(SKGServices::BOOL, SKGRuleObject::UPDATE);
SKGRuleObject::getListOfOperators(SKGServices::TRISTATE, SKGRuleObject::UPDATE);
SKGRuleObject::getListOfOperators(SKGServices::BOOL, SKGRuleObject::UPDATE);
SKGRuleObject::getListOfOperators(SKGServices::BOOL, SKGRuleObject::UPDATE);
SKGRuleObject::getListOfOperators(SKGServices::BOOL, SKGRuleObject::UPDATE);
SKGRuleObject::getListOfOperators(SKGServices::TEXT, SKGRuleObject::ALARM);
SKGRuleObject::getListOfOperators(SKGServices::TEXT, SKGRuleObject::APPLYTEMPLATE);
}
// Rule creation
SKGRuleObject rule1;
{
SKGBEGINTRANSACTION(document1, QStringLiteral("RULE_1"), err)
// Create rule
rule1 = SKGRuleObject(&document1);
QString searchDef = QStringLiteral("<element> <!--OR-->"
"<element> <!--AND-->"
"<element attribute=\"t_comment\" operator=\"#ATT#='#V1S#'\" value=\"REINVESTMENT\"/>"
"</element>"
"</element>");
SKGTESTERROR(QStringLiteral("RULE:setXMLSearchDefinition"), rule1.setXMLSearchDefinition(searchDef), true)
SKGTEST(QStringLiteral("RULE:getXMLSearchDefinition"), rule1.getXMLSearchDefinition(), searchDef)
QString actionDef = QStringLiteral("<element> <!--OR-->"
"<element> <!--AND-->"
"<element attribute=\"t_mode\" operator=\"#ATT#='#V1#'\" value=\"modified\" />"
"</element>"
"</element>");
SKGTESTERROR(QStringLiteral("RULE:setXMLActionDefinition"), rule1.setXMLActionDefinition(actionDef), true)
SKGTEST(QStringLiteral("RULE:getXMLActionDefinition"), rule1.getXMLActionDefinition(), actionDef)
SKGTESTERROR(QStringLiteral("RULE:setSearchDescription"), rule1.setSearchDescription(QStringLiteral("search description")), true)
SKGTEST(QStringLiteral("RULE:getSearchDescription"), rule1.getSearchDescription(), QStringLiteral("search description"))
SKGTESTERROR(QStringLiteral("RULE:setActionDescription"), rule1.setActionDescription(QStringLiteral("action description")), true)
SKGTEST(QStringLiteral("RULE:getActionDescription"), rule1.getActionDescription(), QStringLiteral("action description"))
SKGTESTERROR(QStringLiteral("RULE:setActionType"), rule1.setActionType(SKGRuleObject::SEARCH), true)
SKGTESTERROR(QStringLiteral("RULE:setActionType"), rule1.setActionType(SKGRuleObject::APPLYTEMPLATE), true)
SKGTESTERROR(QStringLiteral("RULE:setActionType"), rule1.setActionType(SKGRuleObject::UPDATE), true)
SKGTEST(QStringLiteral("RULE:getActionType"), static_cast<unsigned int>(rule1.getActionType()), static_cast<unsigned int>(SKGRuleObject::UPDATE))
SKGTESTERROR(QStringLiteral("RULE:setOrder"), rule1.setOrder(-1), true)
SKGTEST(QStringLiteral("RULE:getOrder"), rule1.getOrder(), 1)
SKGTESTBOOL("RULE:setOrder", rule1.isBookmarked(), false)
SKGTESTERROR(QStringLiteral("RULE:getOrder"), rule1.bookmark(true), true)
SKGTESTBOOL("RULE:setOrder", rule1.isBookmarked(), true)
SKGTESTERROR(QStringLiteral("UNIT:save"), rule1.save(), true)
SKGTESTERROR(QStringLiteral("UNIT:load"), rule1.load(), true)
rule1.getDisplayName();
SKGRuleObject rule1bis = SKGRuleObject(rule1);
SKGRuleObject rule1ter = SKGRuleObject(static_cast<SKGObjectBase>(rule1));
SKGRuleObject rule4;
rule4 = static_cast<SKGObjectBase>(rule1);
SKGRuleObject rule5(SKGObjectBase(&document1, QStringLiteral("xxx"), rule1.getID()));
}
// Rule creation (ALARM)
SKGRuleObject alarm1;
{
SKGBEGINTRANSACTION(document1, QStringLiteral("ALARM_1"), err)
// Create rule
alarm1 = SKGRuleObject(&document1);
QString searchDef = QStringLiteral("<element> <!--OR-->"
"<element> <!--AND-->"
"<element attribute=\"t_comment\" operator=\"#ATT#='#V1S#'\" value=\"REINVESTMENT\"/>"
"</element>"
"</element>");
SKGTESTERROR(QStringLiteral("RULE:setXMLSearchDefinition"), alarm1.setXMLSearchDefinition(searchDef), true)
SKGTEST(QStringLiteral("RULE:getXMLSearchDefinition"), alarm1.getXMLSearchDefinition(), searchDef)
QString actionDef = QStringLiteral("<element> <!--OR-->"
"<element> <!--AND-->"
"<element attribute=\"f_REALCURRENTAMOUNT\" operator=\"ABS(TOTAL(#ATT#))#OP##V1#,ABS(TOTAL(#ATT#)), #V1#, '#V2S#'\" value=\"100\" value2=\"Take care!\"operator2=\">=\"/>"
"</element>"
"</element>");
SKGTESTERROR(QStringLiteral("RULE:setXMLActionDefinition"), alarm1.setXMLActionDefinition(actionDef), true)
SKGTEST(QStringLiteral("RULE:getXMLActionDefinition"), alarm1.getXMLActionDefinition(), actionDef)
SKGTESTERROR(QStringLiteral("RULE:setSearchDescription"), alarm1.setSearchDescription(QStringLiteral("search description")), true)
SKGTEST(QStringLiteral("RULE:getSearchDescription"), alarm1.getSearchDescription(), QStringLiteral("search description"))
SKGTESTERROR(QStringLiteral("RULE:setActionDescription"), alarm1.setActionDescription(QStringLiteral("action description")), true)
SKGTEST(QStringLiteral("RULE:getActionDescription"), alarm1.getActionDescription(), QStringLiteral("action description"))
SKGTESTERROR(QStringLiteral("RULE:setActionType"), alarm1.setActionType(SKGRuleObject::ALARM), true)
SKGTEST(QStringLiteral("RULE:getActionType"), static_cast<unsigned int>(alarm1.getActionType()), static_cast<unsigned int>(SKGRuleObject::ALARM))
SKGTESTERROR(QStringLiteral("RULE:setOrder"), alarm1.setOrder(-1), true)
SKGTEST(QStringLiteral("RULE:getOrder"), alarm1.getOrder(), 2)
SKGTESTERROR(QStringLiteral("UNIT:save"), alarm1.save(), true)
SKGTESTERROR(QStringLiteral("UNIT:load"), alarm1.load(), true)
SKGTEST(QStringLiteral("RULE:getAlarmInfo"), alarm1.getAlarmInfo().Message, QStringLiteral("Take care!"))
SKGTEST(QStringLiteral("RULE:getAlarmInfo"), static_cast<unsigned int>(alarm1.getAlarmInfo().Raised), static_cast<unsigned int>(true))
SKGTEST(QStringLiteral("RULE:getAlarmInfo"), alarm1.getAlarmInfo().Amount, 121.41)
SKGTEST(QStringLiteral("RULE:getAlarmInfo"), alarm1.getAlarmInfo().Limit, 100)
}
// Process rule1
{
SKGBEGINTRANSACTION(document1, QStringLiteral("PROCESS_1"), err)
SKGTESTERROR(QStringLiteral("RULE:execute"), rule1.execute(), true)
SKGTESTERROR(QStringLiteral("RULE:execute"), rule1.execute(SKGRuleObject::IMPORTING), true)
SKGTESTERROR(QStringLiteral("RULE:execute"), rule1.execute(SKGRuleObject::IMPORTEDNOTVALIDATE), true)
SKGTESTERROR(QStringLiteral("RULE:execute"), rule1.execute(SKGRuleObject::IMPORTED), true)
SKGTESTERROR(QStringLiteral("RULE:execute"), rule1.execute(SKGRuleObject::NOTCHECKED), true)
}
// Rule creation (BUG:345974)
{
SKGBEGINTRANSACTION(document1, QStringLiteral("ALARM_2"), err)
// Create rule
alarm1 = SKGRuleObject(&document1);
QString searchDef = QStringLiteral("<element> <!--OR-->"
"<element> <!--AND-->"
"<element attribute=\"t_comment\" operator=\"#ATT#='#V1S#'\" value=\"REINVESTMENT\"/>"
"</element>"
"</element>");
SKGTESTERROR(QStringLiteral("RULE:setXMLSearchDefinition"), alarm1.setXMLSearchDefinition(searchDef), true)
SKGTEST(QStringLiteral("RULE:getXMLSearchDefinition"), alarm1.getXMLSearchDefinition(), searchDef)
QString actionDef = QStringLiteral("<element> <!--OR-->"
"<element> <!--AND-->"
"<element attribute=\"f_REALCURRENTAMOUNT\" operator=\"ABS(TOTAL(#ATT#))#OP##V1#,ABS(TOTAL(#ATT#)), #V1#, '#V2S#'\" value=\"200\" value2=\"Take care!\"operator2=\">=\"/>"
"</element>"
"</element>");
SKGTESTERROR(QStringLiteral("RULE:setXMLActionDefinition"), alarm1.setXMLActionDefinition(actionDef), true)
SKGTEST(QStringLiteral("RULE:getXMLActionDefinition"), alarm1.getXMLActionDefinition(), actionDef)
SKGTESTERROR(QStringLiteral("RULE:setSearchDescription"), alarm1.setSearchDescription(QStringLiteral("search description")), true)
SKGTEST(QStringLiteral("RULE:getSearchDescription"), alarm1.getSearchDescription(), QStringLiteral("search description"))
SKGTESTERROR(QStringLiteral("RULE:setActionDescription"), alarm1.setActionDescription(QStringLiteral("action description")), true)
SKGTEST(QStringLiteral("RULE:getActionDescription"), alarm1.getActionDescription(), QStringLiteral("action description"))
SKGTESTERROR(QStringLiteral("RULE:setActionType"), alarm1.setActionType(SKGRuleObject::ALARM), true)
SKGTEST(QStringLiteral("RULE:getActionType"), static_cast<unsigned int>(alarm1.getActionType()), static_cast<unsigned int>(SKGRuleObject::ALARM))
SKGTESTERROR(QStringLiteral("UNIT:save"), alarm1.save(), true)
SKGTESTERROR(QStringLiteral("UNIT:load"), alarm1.load(), true)
SKGTEST(QStringLiteral("RULE:getAlarmInfo"), alarm1.getAlarmInfo().Message, QStringLiteral("Take care!"))
SKGTEST(QStringLiteral("RULE:getAlarmInfo"), static_cast<unsigned int>(alarm1.getAlarmInfo().Raised), static_cast<unsigned int>(false))
SKGTEST(QStringLiteral("RULE:getAlarmInfo"), alarm1.getAlarmInfo().Amount, 121.41)
SKGTEST(QStringLiteral("RULE:getAlarmInfo"), alarm1.getAlarmInfo().Limit, 200)
}
// Process rule1
{
SKGBEGINTRANSACTION(document1, QStringLiteral("PROCESS_1"), err)
SKGTESTERROR(QStringLiteral("RULE:execute"), rule1.execute(), true)
SKGTESTERROR(QStringLiteral("RULE:execute"), rule1.execute(SKGRuleObject::IMPORTING), true)
SKGTESTERROR(QStringLiteral("RULE:execute"), rule1.execute(SKGRuleObject::IMPORTEDNOTVALIDATE), true)
SKGTESTERROR(QStringLiteral("RULE:execute"), rule1.execute(SKGRuleObject::IMPORTED), true)
}
document1.dump(DUMPOPERATION | DUMPACCOUNT);
}
// ============================================================================
{
// Test import OFX skrooge
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.load()"), document1.load(SKGTest::getTestPath(QStringLiteral("IN")) % "skgtestrule/file.skg"), true)
// Process rules
SKGError err;
{
SKGBEGINTRANSACTION(document1, QStringLiteral("PROCESS_1"), err)
SKGObjectBase::SKGListSKGObjectBase rules;
SKGTESTERROR(QStringLiteral("RULE:execute"), document1.getObjects(QStringLiteral("rule"), QLatin1String(""), rules), true)
for (int i = 0; i < rules.count(); ++i) {
SKGRuleObject rule(rules.at(i));
SKGTESTERROR(QStringLiteral("RULE:execute"), rule.execute(), true)
}
}
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_OFX"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestimportofx/ofx_spec201_stmtrs_example.ofx"));
imp1.setAutomaticApplyRules(true);
SKGTESTERROR(QStringLiteral("imp1.importFile"), imp1.importFile(), true)
}
}
// End test
SKGENDTEST()
}
diff --git a/tests/skgbankmodelertest/skgtestunit.cpp b/tests/skgbankmodelertest/skgtestunit.cpp
index bc00db35f..c11acd4a5 100644
--- a/tests/skgbankmodelertest/skgtestunit.cpp
+++ b/tests/skgbankmodelertest/skgtestunit.cpp
@@ -1,441 +1,441 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is a test script.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include <qdesktopservices.h>
#include "skgbankincludes.h"
#include "skgtestmacro.h"
/**
* The main function of the unit test
* @param argc the number of arguments
* @param argv the list of arguments
*/
int main(int argc, char** argv)
{
Q_UNUSED(argc)
Q_UNUSED(argv)
// Init test
SKGINITTEST(true)
{
QStringList sources = SKGUnitObject::downloadSources();
SKGTESTBOOL("UNIT:downloadSources", (sources.count() >= 4), true)
for (const QString& source : sources) {
SKGUnitObject::getCommentFromSource(source);
}
// Test unit et unitvalue
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
SKGTEST(QStringLiteral("UNIT:getNbTransaction"), document1.getNbTransaction(), 0)
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("BANK_T1"), err)
// Create unit
SKGUnitObject unit1(&document1);
SKGTESTERROR(QStringLiteral("UNIT:setName"), unit1.setName(QStringLiteral("UNIT1")), true)
SKGTESTERROR(QStringLiteral("UNIT:setSymbol"), unit1.setSymbol(QStringLiteral("F")), true)
SKGTEST(QStringLiteral("UNIT:getSymbol"), unit1.getSymbol(), QStringLiteral("F"))
SKGTESTERROR(QStringLiteral("UNIT:setCountry"), unit1.setCountry(QStringLiteral("France")), true)
SKGTEST(QStringLiteral("UNIT:getSymbol"), unit1.getCountry(), QStringLiteral("France"))
SKGTESTERROR(QStringLiteral("UNIT:setInternetCode"), unit1.setInternetCode(QStringLiteral("code Internet")), true)
SKGTEST(QStringLiteral("UNIT:getInternetCode"), unit1.getInternetCode(), QStringLiteral("code Internet"))
SKGTESTERROR(QStringLiteral("UNIT:setType"), unit1.setType(SKGUnitObject::OBJECT), true)
SKGTEST(QStringLiteral("UNIT:getType"), static_cast<unsigned int>(unit1.getType()), static_cast<unsigned int>(SKGUnitObject::OBJECT))
SKGTESTERROR(QStringLiteral("UNIT:setNumberDecimal"), unit1.setNumberDecimal(4), true)
SKGTEST(QStringLiteral("UNIT:getNumberDecimal"), unit1.getNumberDecimal(), 4)
SKGUnitValueObject unitvalue1;
SKGTESTERROR(QStringLiteral("UNIT:addUnitValue"), unit1.addUnitValue(unitvalue1), false)
SKGTESTERROR(QStringLiteral("UNIT:save"), unit1.save(), true)
// Create unit value
SKGTESTERROR(QStringLiteral("UNIT:addUnitValue"), unit1.addUnitValue(unitvalue1), true)
SKGTESTERROR(QStringLiteral("UNITVALUE:setQuantity"), unitvalue1.setQuantity(119999.11), true)
SKGTESTERROR(QStringLiteral("UNITVALUE:setDate"), unitvalue1.setDate(SKGServices::stringToTime(QStringLiteral("1970-07-16")).date()), true)
SKGTESTERROR(QStringLiteral("UNITVALUE:save"), unitvalue1.save(), true)
SKGUnitValueObject unitvalue1bis = SKGUnitValueObject(unitvalue1);
SKGUnitValueObject unitvalue1ter = SKGUnitValueObject(static_cast<SKGObjectBase>(unitvalue1));
SKGUnitValueObject unitvalue14(SKGNamedObject(&document1, QStringLiteral("xxx"), unitvalue1.getID()));
SKGUnitObject unit_get;
SKGTESTERROR(QStringLiteral("UNITVALUE:getUnit"), unitvalue1.getUnit(unit_get), true)
SKGTESTBOOL("UNIT:comparison", (unit_get == unit1), true)
SKGUnitValueObject unitvalue2;
SKGTESTERROR(QStringLiteral("UNIT:addUnitValue"), unit1.addUnitValue(unitvalue2), true)
SKGTESTERROR(QStringLiteral("UNITVALUE:setQuantity"), unitvalue2.setQuantity(34.12), true)
SKGTESTERROR(QStringLiteral("UNITVALUE:setDate"), unitvalue2.setDate(SKGServices::stringToTime(QStringLiteral("1973-02-04")).date()), true)
SKGTESTERROR(QStringLiteral("UNITVALUE:save"), unitvalue2.save(), true)
// Retrieve unit
SKGNamedObject unit2Named;
SKGTESTERROR(QStringLiteral("UNIT:getObjectByName"), SKGNamedObject::getObjectByName(&document1, QStringLiteral("unit"), QStringLiteral("UNIT1"), unit2Named), true)
SKGUnitObject unit2(unit2Named);
// Retrieve unit value
SKGUnitValueObject unitvalue3;
SKGTESTERROR(QStringLiteral("UNIT:getLastUnitValue"), unit2.getLastUnitValue(unitvalue3), true)
SKGUnitValueObject unitvalue19700101;
SKGTESTERROR(QStringLiteral("UNIT:getUnitValue"), unit2.getUnitValue(SKGServices::stringToTime(QStringLiteral("1970-01-01")).date(), unitvalue19700101), true)
SKGUnitValueObject unitvalue19700716;
SKGTESTERROR(QStringLiteral("UNIT:getUnitValue"), unit2.getUnitValue(SKGServices::stringToTime(QStringLiteral("1970-07-16")).date(), unitvalue19700716), true)
SKGUnitValueObject unitvalue19720716;
SKGTESTERROR(QStringLiteral("UNIT:getUnitValue"), unit2.getUnitValue(SKGServices::stringToTime(QStringLiteral("1972-07-16")).date(), unitvalue19720716), true)
SKGUnitValueObject unitvalue19730204;
SKGTESTERROR(QStringLiteral("UNIT:getUnitValue"), unit2.getUnitValue(SKGServices::stringToTime(QStringLiteral("1973-02-04")).date(), unitvalue19730204), true)
SKGUnitValueObject unitvalue19750204;
SKGTESTERROR(QStringLiteral("UNIT:getUnitValue"), unit2.getUnitValue(SKGServices::stringToTime(QStringLiteral("1975-02-04")).date(), unitvalue19750204), true)
// Check unit value
SKGTESTBOOL("UNITVALUE:==", (unitvalue3 == unitvalue2), true)
SKGTESTBOOL("UNITVALUE:==", (unitvalue19700101 == unitvalue1), true)
SKGTESTBOOL("UNITVALUE:==", (unitvalue19700716 == unitvalue1), true)
SKGTESTBOOL("UNITVALUE:==", (unitvalue19720716 == unitvalue1), true)
SKGTESTBOOL("UNITVALUE:==", (unitvalue19730204 == unitvalue2), true)
SKGTESTBOOL("UNITVALUE:==", (unitvalue19750204 == unitvalue2), true)
SKGTEST(QStringLiteral("UNITVALUE:getQuantity"), unitvalue1.getQuantity() - 119999.11, 0)
SKGTEST(QStringLiteral("UNITVALUE:getQuantity"), unitvalue3.getQuantity() - 34.12, 0)
SKGTEST(QStringLiteral("UNITVALUE:getDate"), SKGServices::dateToSqlString(QDateTime(unitvalue3.getDate())), QStringLiteral("1973-02-04"))
// Check cascading delete
SKGTESTERROR(QStringLiteral("UNIT:delete"), unit2.remove(), true)
QStringList oResult;
SKGTESTERROR(QStringLiteral("UNIT:getDistinctValues"), document1.getDistinctValues(QStringLiteral("unit"), QStringLiteral("id"), oResult), true)
SKGTEST(QStringLiteral("UNIT:oResult.size"), oResult.size(), 0)
SKGTESTERROR(QStringLiteral("UNITVALUE:getDistinctValues"), document1.getDistinctValues(QStringLiteral("unitvalue"), QStringLiteral("rd_unit_id"), oResult), true)
SKGTEST(QStringLiteral("UNITVALUE:oResult.size"), oResult.size(), 0)
// Merge
SKGTESTERROR(QStringLiteral("UNIT:merge"), unit1.merge(unit2), true)
}
{
// Test unit et unitvalue
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
SKGTEST(QStringLiteral("DOC:getPrimaryUnit"), document1.getPrimaryUnit().Symbol, QLatin1String(""))
SKGTEST(QStringLiteral("DOC:getSecondaryUnit"), document1.getSecondaryUnit().Symbol, QLatin1String(""))
SKGUnitObject franc(&document1);
{
SKGBEGINTRANSACTION(document1, QStringLiteral("UNIT_1"), err)
// Create unit
SKGTESTERROR(QStringLiteral("FRANC:setName"), franc.setName(QStringLiteral("F")), true)
SKGTESTERROR(QStringLiteral("FRANC:setSymbol"), franc.setSymbol(QStringLiteral("F")), true)
SKGTESTERROR(QStringLiteral("FRANC:setType"), franc.setType(SKGUnitObject::PRIMARY), true)
SKGTEST(QStringLiteral("FRANC:getType"), static_cast<unsigned int>(franc.getType()), static_cast<unsigned int>(SKGUnitObject::PRIMARY))
SKGTESTERROR(QStringLiteral("FRANC:save"), franc.save(), true)
SKGTEST(QStringLiteral("DOC:getPrimaryUnit"), document1.getPrimaryUnit().Symbol, QStringLiteral("F"))
}
SKGTEST(QStringLiteral("DOC:getPrimaryUnit"), document1.getPrimaryUnit().Symbol, QStringLiteral("F"))
SKGTEST(QStringLiteral("DOC:getSecondaryUnit"), document1.getSecondaryUnit().Symbol, QLatin1String(""))
SKGTEST(QStringLiteral("DOC:getSecondaryUnit"), document1.getSecondaryUnit().Value, 1)
{
SKGBEGINTRANSACTION(document1, QStringLiteral("UNIT_2"), err)
SKGUnitObject euro(&document1);
SKGTESTERROR(QStringLiteral("EURO:setName"), euro.setName(QStringLiteral("E")), true)
SKGTESTERROR(QStringLiteral("EURO:setSymbol"), euro.setSymbol(QStringLiteral("E")), true)
SKGTESTERROR(QStringLiteral("EURO:setType"), euro.setType(SKGUnitObject::PRIMARY), true)
SKGTEST(QStringLiteral("EURO:getType"), static_cast<unsigned int>(euro.getType()), static_cast<unsigned int>(SKGUnitObject::PRIMARY))
SKGTESTERROR(QStringLiteral("EURO:save"), euro.save(), true)
SKGTESTERROR(QStringLiteral("FRANC:load"), franc.load(), true)
SKGTEST(QStringLiteral("FRANC:getType"), static_cast<unsigned int>(franc.getType()), static_cast<unsigned int>(SKGUnitObject::SECONDARY))
SKGTEST(QStringLiteral("EURO:getType"), static_cast<unsigned int>(euro.getType()), static_cast<unsigned int>(SKGUnitObject::PRIMARY))
SKGTESTERROR(QStringLiteral("EURO:save"), euro.save(), true)
}
SKGTEST(QStringLiteral("DOC:getPrimaryUnit"), document1.getPrimaryUnit().Symbol, QStringLiteral("E"))
SKGTEST(QStringLiteral("DOC:getSecondaryUnit"), document1.getSecondaryUnit().Symbol, QStringLiteral("F"))
}
{
// Test unit et unitvalue
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
QStringList units = SKGUnitObject::getListofKnownCurrencies(false);
SKGTEST(QStringLiteral("UNIT:getListofKnownCurrencies"), units.count(), 276)
units = SKGUnitObject::getListofKnownCurrencies(true);
SKGTEST(QStringLiteral("UNIT:getListofKnownCurrencies"), units.count(), 316)
for (const auto& unit : qAsConst(units)) {
SKGBEGINTRANSACTION(document1, QStringLiteral("UNIT_1"), err)
SKGUnitObject unitObj;
SKGTESTERROR(QStringLiteral("UNIT:createCurrencyUnit-") % unit, SKGUnitObject::createCurrencyUnit(&document1, unit, unitObj), true)
unitObj.getUnitInfo();
}
SKGBEGINTRANSACTION(document1, QStringLiteral("UNIT_1"), err)
SKGUnitObject unitObj;
SKGTESTERROR(QStringLiteral("UNIT:createCurrencyUnit"), SKGUnitObject::createCurrencyUnit(&document1, QStringLiteral("ZZZZZZZ"), unitObj), false)
}
}
{
// Compute unit amount at a date
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
SKGUnitObject unit1(&document1);
SKGUnitObject unit2(&document1);
{
SKGBEGINTRANSACTION(document1, QStringLiteral("UNIT"), err)
SKGTESTERROR(QStringLiteral("UNIT:setName"), unit1.setName(QStringLiteral("U1")), true)
SKGTESTERROR(QStringLiteral("UNIT:setSymbol"), unit1.setSymbol(QStringLiteral("U1")), true)
SKGTESTERROR(QStringLiteral("UNIT:save"), unit1.save(), true)
SKGTESTERROR(QStringLiteral("UNIT:addOrModifyUnitValue"), document1.addOrModifyUnitValue(QStringLiteral("U1"), SKGServices::stringToTime(QStringLiteral("2001-01-01")).date(), 1), true)
SKGTESTERROR(QStringLiteral("UNIT:addOrModifyUnitValue"), document1.addOrModifyUnitValue(QStringLiteral("U1"), SKGServices::stringToTime(QStringLiteral("2006-01-01")).date(), 6), true)
SKGTESTERROR(QStringLiteral("UNIT:addOrModifyUnitValue"), document1.addOrModifyUnitValue(QStringLiteral("U1"), SKGServices::stringToTime(QStringLiteral("2007-01-01")).date(), 7), true)
SKGTESTERROR(QStringLiteral("UNIT:addOrModifyUnitValue"), document1.addOrModifyUnitValue(QStringLiteral("U1"), SKGServices::stringToTime(QStringLiteral("2008-01-01")).date(), 8), true)
SKGTESTERROR(QStringLiteral("UNIT:setName"), unit2.setName(QStringLiteral("U2")), true)
SKGTESTERROR(QStringLiteral("UNIT:setSymbol"), unit2.setSymbol(QStringLiteral("U2")), true)
SKGTESTERROR(QStringLiteral("UNIT:removeUnit"), unit2.removeUnit(), true)
SKGTESTERROR(QStringLiteral("UNIT:save"), unit2.save(), true)
SKGTESTERROR(QStringLiteral("UNIT:setUnit"), unit2.setUnit(unit2), false)
SKGTESTERROR(QStringLiteral("UNIT:setUnit"), unit2.setUnit(unit1), true)
SKGTESTERROR(QStringLiteral("UNIT:save"), unit2.save(), true)
SKGTESTERROR(QStringLiteral("UNIT:addOrModifyUnitValue"), document1.addOrModifyUnitValue(QStringLiteral("U2"), SKGServices::stringToTime(QStringLiteral("2001-02-01")).date(), 10), true)
SKGTESTERROR(QStringLiteral("UNIT:addOrModifyUnitValue"), document1.addOrModifyUnitValue(QStringLiteral("U2"), SKGServices::stringToTime(QStringLiteral("2006-01-01")).date(), 60), true)
SKGTESTERROR(QStringLiteral("UNIT:addOrModifyUnitValue"), document1.addOrModifyUnitValue(QStringLiteral("U2"), SKGServices::stringToTime(QStringLiteral("2007-02-01")).date(), 70), true)
SKGTESTERROR(QStringLiteral("UNIT:addOrModifyUnitValue"), document1.addOrModifyUnitValue(QStringLiteral("U2"), SKGServices::stringToTime(QStringLiteral("2008-01-01")).date(), 80), true)
}
SKGTEST(QStringLiteral("DOC:getAmount"), unit1.getAmount(SKGServices::stringToTime(QStringLiteral("2001-01-01")).date()), 1)
SKGTEST(QStringLiteral("DOC:getAmount"), unit1.getAmount(SKGServices::stringToTime(QStringLiteral("2001-02-01")).date()), 1)
SKGTEST(QStringLiteral("DOC:getAmount"), unit1.getAmount(SKGServices::stringToTime(QStringLiteral("2006-01-01")).date()), 6)
SKGTEST(QStringLiteral("DOC:getAmount"), unit1.getAmount(SKGServices::stringToTime(QStringLiteral("2006-02-01")).date()), 6)
SKGTEST(QStringLiteral("DOC:getAmount"), unit1.getAmount(SKGServices::stringToTime(QStringLiteral("2007-01-01")).date()), 7)
SKGTEST(QStringLiteral("DOC:getAmount"), unit1.getAmount(SKGServices::stringToTime(QStringLiteral("2007-02-01")).date()), 7)
SKGTEST(QStringLiteral("DOC:getAmount"), unit1.getAmount(SKGServices::stringToTime(QStringLiteral("2008-01-01")).date()), 8)
SKGTEST(QStringLiteral("DOC:getAmount"), unit1.getAmount(SKGServices::stringToTime(QStringLiteral("2008-02-01")).date()), 8)
SKGTEST(QStringLiteral("DOC:getAmount"), unit2.getAmount(SKGServices::stringToTime(QStringLiteral("2001-01-01")).date()), 1 * 10)
SKGTEST(QStringLiteral("DOC:getAmount"), unit2.getAmount(SKGServices::stringToTime(QStringLiteral("2001-02-01")).date()), 1 * 10)
SKGTEST(QStringLiteral("DOC:getAmount"), unit2.getAmount(SKGServices::stringToTime(QStringLiteral("2006-01-01")).date()), 6 * 60)
SKGTEST(QStringLiteral("DOC:getAmount"), unit2.getAmount(SKGServices::stringToTime(QStringLiteral("2006-02-01")).date()), 6 * 60)
SKGTEST(QStringLiteral("DOC:getAmount"), unit2.getAmount(SKGServices::stringToTime(QStringLiteral("2007-01-01")).date()), 7 * 60)
SKGTEST(QStringLiteral("DOC:getAmount"), unit2.getAmount(SKGServices::stringToTime(QStringLiteral("2007-02-01")).date()), 7 * 70)
SKGTEST(QStringLiteral("DOC:getAmount"), unit2.getAmount(SKGServices::stringToTime(QStringLiteral("2008-01-01")).date()), 8 * 80)
SKGTEST(QStringLiteral("DOC:getAmount"), unit2.getAmount(SKGServices::stringToTime(QStringLiteral("2008-02-01")).date()), 8 * 80)
SKGTESTERROR(QStringLiteral("UNIT:load"), unit1.load(), true)
SKGTESTERROR(QStringLiteral("UNIT:load"), unit2.load(), true)
SKGTEST(QStringLiteral("DOC:convert"), SKGUnitObject::convert(100, unit1, unit1), 100)
SKGTEST(QStringLiteral("DOC:convert"), SKGUnitObject::convert(100, unit1, unit2), 1.25)
}
{
// Split unit
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
SKGUnitObject unit1(&document1);
{
SKGBEGINTRANSACTION(document1, QStringLiteral("UNIT"), err)
SKGTESTERROR(QStringLiteral("UNIT:setName"), unit1.setName(QStringLiteral("U1")), true)
SKGTESTERROR(QStringLiteral("UNIT:setSymbol"), unit1.setSymbol(QStringLiteral("U1")), true)
SKGTESTERROR(QStringLiteral("UNIT:save"), unit1.save(), true)
SKGTESTERROR(QStringLiteral("UNIT:addOrModifyUnitValue"), document1.addOrModifyUnitValue(QStringLiteral("U1"), SKGServices::stringToTime(QStringLiteral("2001-01-01")).date(), 100), true)
}
{
SKGBEGINTRANSACTION(document1, QStringLiteral("UNIT-SPLIT"), err)
SKGTESTERROR(QStringLiteral("DOC:getAmount"), unit1.split(-2), false)
SKGTESTERROR(QStringLiteral("DOC:getAmount"), unit1.split(2), true)
}
SKGTESTERROR(QStringLiteral("UNIT:load"), unit1.load(), true)
SKGTEST(QStringLiteral("UNIT:getAmount"), unit1.getAmount(SKGServices::stringToTime(QStringLiteral("2001-01-01")).date()), 50)
}
{
// Unit Daily change
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
SKGUnitObject unit1(&document1);
{
SKGBEGINTRANSACTION(document1, QStringLiteral("UNIT"), err)
SKGTESTERROR(QStringLiteral("UNIT:setName"), unit1.setName(QStringLiteral("U1")), true)
SKGTESTERROR(QStringLiteral("UNIT:setSymbol"), unit1.setSymbol(QStringLiteral("U1")), true)
SKGTESTERROR(QStringLiteral("UNIT:save"), unit1.save(), true)
SKGTESTERROR(QStringLiteral("UNIT:addOrModifyUnitValue"), document1.addOrModifyUnitValue(QStringLiteral("U1"), SKGServices::stringToTime(QStringLiteral("2009-01-01")).date(), 100), true)
SKGTESTERROR(QStringLiteral("UNIT:addOrModifyUnitValue"), document1.addOrModifyUnitValue(QStringLiteral("U1"), SKGServices::stringToTime(QStringLiteral("2009-01-02")).date(), 105), true)
SKGTESTERROR(QStringLiteral("UNIT:addOrModifyUnitValue"), document1.addOrModifyUnitValue(QStringLiteral("U1"), SKGServices::stringToTime(QStringLiteral("2009-02-01")).date(), 110), true)
}
SKGTEST(QStringLiteral("UNIT:getDailyChange"), SKGServices::intToString(365 * unit1.getDailyChange(SKGServices::stringToTime(QStringLiteral("2009-01-02")).date())), QStringLiteral("1825"))
SKGTEST(QStringLiteral("UNIT:getDailyChange"), SKGServices::intToString(365 * unit1.getDailyChange(SKGServices::stringToTime(QStringLiteral("2009-02-01")).date())), QStringLiteral("80"))
}
{
// Unit download
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
SKGUnitObject unit1(&document1);
{
SKGBEGINTRANSACTION(document1, QStringLiteral("UNIT"), err)
SKGTESTERROR(QStringLiteral("UNIT:setName"), unit1.setName(QStringLiteral("DS")), true)
SKGTESTERROR(QStringLiteral("UNIT:setSymbol"), unit1.setSymbol(QStringLiteral("DS")), true)
SKGTESTERROR(QStringLiteral("UNIT:setDownloadSource"), unit1.setDownloadSource(QStringLiteral("Yahoo")), true)
SKGTESTERROR(QStringLiteral("UNIT:setInternetCode"), unit1.setInternetCode(QStringLiteral("DSY.PA")), true)
SKGTESTERROR(QStringLiteral("UNIT:save"), unit1.save(), true)
SKGTESTERROR(QStringLiteral("UNIT:downloadUnitValue"), unit1.downloadUnitValue(SKGUnitObject::ALL_DAILY, 20), true)
SKGObjectBase::SKGListSKGObjectBase values;
SKGTESTERROR(QStringLiteral("UNIT:getUnitValues"), unit1.getUnitValues(values), true)
SKGTESTBOOL("UNIT:getUnitValues", (!values.isEmpty()), true)
// All download modes
SKGTESTERROR(QStringLiteral("UNIT:downloadUnitValue"), unit1.downloadUnitValue(SKGUnitObject::LAST_WEEKLY, 20), true)
SKGTESTERROR(QStringLiteral("UNIT:downloadUnitValue"), unit1.downloadUnitValue(SKGUnitObject::LAST_DAILY, 20), true)
SKGTESTERROR(QStringLiteral("UNIT:downloadUnitValue"), unit1.downloadUnitValue(SKGUnitObject::LAST_MONTHLY, 20), true)
SKGTESTERROR(QStringLiteral("UNIT:downloadUnitValue"), unit1.downloadUnitValue(SKGUnitObject::ALL_MONTHLY, 20), true)
SKGTESTERROR(QStringLiteral("UNIT:downloadUnitValue"), unit1.downloadUnitValue(SKGUnitObject::ALL_WEEKLY, 20), true)
SKGTESTERROR(QStringLiteral("UNIT:getUnitValues"), unit1.getUnitValues(values), true)
SKGTESTBOOL("UNIT:getUnitValues", static_cast<unsigned int>(values.count() > 1), static_cast<unsigned int>(true))
QUrl url;
unit1.getUrl(url); // For coverage
}
}
{
// Unit download
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
SKGUnitObject unit1(&document1);
{
SKGBEGINTRANSACTION(document1, QStringLiteral("UNIT"), err)
SKGTESTERROR(QStringLiteral("UNIT:setName"), unit1.setName(QStringLiteral("FORMULA")), true)
SKGTESTERROR(QStringLiteral("UNIT:setSymbol"), unit1.setSymbol(QStringLiteral("FORMULA")), true)
SKGTESTERROR(QStringLiteral("UNIT:setInternetCode"), unit1.setInternetCode(QStringLiteral("=5")), true)
SKGTESTERROR(QStringLiteral("UNIT:save"), unit1.save(), true)
SKGTESTERROR(QStringLiteral("UNIT:downloadUnitValue"), unit1.downloadUnitValue(SKGUnitObject::ALL_DAILY, 20), true)
SKGObjectBase::SKGListSKGObjectBase values;
SKGTESTERROR(QStringLiteral("UNIT:getUnitValues"), unit1.getUnitValues(values), true)
SKGTESTBOOL("UNIT:getUnitValues", (!values.isEmpty()), true)
}
}
{
// Unit download
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
SKGUnitObject unit1(&document1);
{
SKGBEGINTRANSACTION(document1, QStringLiteral("UNIT"), err)
SKGTESTERROR(QStringLiteral("UNIT:createCurrencyUnit"), SKGUnitObject::createCurrencyUnit(&document1, QStringLiteral("Bitcoin"), unit1), true)
SKGTESTERROR(QStringLiteral("UNIT:downloadUnitValue"), unit1.downloadUnitValue(SKGUnitObject::LAST), true)
SKGObjectBase::SKGListSKGObjectBase values;
SKGTESTERROR(QStringLiteral("UNIT:getUnitValues"), unit1.getUnitValues(values), true)
SKGTESTBOOL("UNIT:getUnitValues", (!values.isEmpty()), true)
}
}
{
// Unit download
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
SKGBEGINTRANSACTION(document1, QStringLiteral("UNIT"), err)
SKGUnitObject euro;
SKGTESTERROR(QStringLiteral("UNIT:createCurrencyUnit"), SKGUnitObject::createCurrencyUnit(&document1, QStringLiteral("EUR"), euro), true)
SKGUnitObject fr;
SKGTESTERROR(QStringLiteral("UNIT:createCurrencyUnit"), SKGUnitObject::createCurrencyUnit(&document1, QStringLiteral("GBP"), fr), true)
SKGTESTERROR(QStringLiteral("UNIT:downloadUnitValue"), fr.downloadUnitValue(SKGUnitObject::LAST), true)
SKGObjectBase::SKGListSKGObjectBase values;
SKGTESTERROR(QStringLiteral("UNIT:getUnitValues"), fr.getUnitValues(values), true)
SKGTESTBOOL("UNIT:getUnitValues", values.isEmpty(), false)
}
}
{
// Unit simplify
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
SKGUnitObject unit1(&document1);
{
SKGBEGINTRANSACTION(document1, QStringLiteral("UNIT"), err)
SKGTESTERROR(QStringLiteral("UNIT:setName"), unit1.setName(QStringLiteral("U1")), true)
SKGTESTERROR(QStringLiteral("UNIT:setSymbol"), unit1.setSymbol(QStringLiteral("U1")), true)
SKGTESTERROR(QStringLiteral("UNIT:save"), unit1.save(), true)
SKGTESTERROR(QStringLiteral("UNIT:addOrModifyUnitValue"), document1.addOrModifyUnitValue(QStringLiteral("U1"), QDate::currentDate().addDays(-7), 1), true)
SKGTESTERROR(QStringLiteral("UNIT:addOrModifyUnitValue"), document1.addOrModifyUnitValue(QStringLiteral("U1"), QDate::currentDate().addDays(-6), 2), true)
SKGTESTERROR(QStringLiteral("UNIT:addOrModifyUnitValue"), document1.addOrModifyUnitValue(QStringLiteral("U1"), QDate::currentDate().addDays(-5), 3), true)
SKGTESTERROR(QStringLiteral("UNIT:addOrModifyUnitValue"), document1.addOrModifyUnitValue(QStringLiteral("U1"), QDate::currentDate().addMonths(-3).addDays(-7), 1), true)
SKGTESTERROR(QStringLiteral("UNIT:addOrModifyUnitValue"), document1.addOrModifyUnitValue(QStringLiteral("U1"), QDate::currentDate().addMonths(-3).addDays(-6), 2), true)
SKGTESTERROR(QStringLiteral("UNIT:addOrModifyUnitValue"), document1.addOrModifyUnitValue(QStringLiteral("U1"), QDate::currentDate().addMonths(-3).addDays(-5), 3), true)
SKGTESTERROR(QStringLiteral("UNIT:addOrModifyUnitValue"), document1.addOrModifyUnitValue(QStringLiteral("U1"), QDate::currentDate().addYears(-1).addDays(-7), 1), true)
SKGTESTERROR(QStringLiteral("UNIT:addOrModifyUnitValue"), document1.addOrModifyUnitValue(QStringLiteral("U1"), QDate::currentDate().addMonths(-1).addDays(-6), 2), true)
SKGTESTERROR(QStringLiteral("UNIT:addOrModifyUnitValue"), document1.addOrModifyUnitValue(QStringLiteral("U1"), QDate::currentDate().addMonths(-1).addDays(-5), 3), true)
SKGTESTERROR(QStringLiteral("UNIT:addOrModifyUnitValue"), document1.addOrModifyUnitValue(QStringLiteral("U1"), SKGServices::stringToTime(QStringLiteral("2009-01-01")).date(), 1), true)
SKGTESTERROR(QStringLiteral("UNIT:addOrModifyUnitValue"), document1.addOrModifyUnitValue(QStringLiteral("U1"), SKGServices::stringToTime(QStringLiteral("2009-01-02")).date(), 2), true)
SKGTESTERROR(QStringLiteral("UNIT:addOrModifyUnitValue"), document1.addOrModifyUnitValue(QStringLiteral("U1"), SKGServices::stringToTime(QStringLiteral("2009-01-03")).date(), 3), true)
}
{
SKGBEGINTRANSACTION(document1, QStringLiteral("SYMPLIFY"), err)
SKGTESTERROR(QStringLiteral("UNIT:setName"), unit1.simplify(), true)
}
SKGObjectBase::SKGListSKGObjectBase oUnitValueList;
SKGTESTERROR(QStringLiteral("UNIT:getUnitValues"), unit1.getUnitValues(oUnitValueList), true)
SKGTESTBOOL("UNIT:oUnitValueList", (oUnitValueList.count() == 10 || oUnitValueList.count() == 11), true)
}
{
SKGTESTERROR(QStringLiteral("UNIT:addSource"), SKGUnitObject::addSource(QStringLiteral("test"), false), true)
SKGTESTBOOL("UNIT:isWritable", SKGUnitObject::isWritable(QStringLiteral("test")), true)
SKGTESTERROR(QStringLiteral("UNIT:deleteSource"), SKGUnitObject::deleteSource(QStringLiteral("test")), true)
SKGTESTERROR(QStringLiteral("UNIT:deleteSource"), SKGUnitObject::deleteSource(QStringLiteral("notfound")), false)
}
// End test
SKGENDTEST()
}
diff --git a/tests/skgbankmodelertest/skgtestvariousbugs.cpp b/tests/skgbankmodelertest/skgtestvariousbugs.cpp
index d9aac85ba..13da1d4fc 100644
--- a/tests/skgbankmodelertest/skgtestvariousbugs.cpp
+++ b/tests/skgbankmodelertest/skgtestvariousbugs.cpp
@@ -1,160 +1,160 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is a test script.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgtestmacro.h"
#include "skgbankincludes.h"
#include "skgimportexportmanager.h"
#include "skgimportplugin.h"
#include "skgreportbank.h"
/**
* The main function of the unit test
* @param argc the number of arguments
* @param argv the list of arguments
*/
int main(int argc, char** argv)
{
Q_UNUSED(argc)
Q_UNUSED(argv)
// Init test
SKGINITTEST(true) {
// Test bug 324649
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.load()"), document1.load(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestvariousbugs/324649.skg"), true)
// Check
{
auto* report = qobject_cast<SKGReportBank*>(document1.getReport());
report->setPeriod(QStringLiteral("2013-09"));
QVariantList values = report->getBankTable();
SKGTEST(QStringLiteral("324649:getCurrentAmount"), values.count(), 4)
SKGTEST(QStringLiteral("324649:title"), values[0].toList()[0].toString(), QStringLiteral("sum"))
SKGTEST(QStringLiteral("324649:10"), values[1].toList()[2].toString(), QStringLiteral("20"))
SKGTEST(QStringLiteral("324649:20"), values[2].toList()[2].toString(), QStringLiteral("10"))
SKGTEST(QStringLiteral("324649:30"), values[3].toList()[2].toString(), QStringLiteral("30"))
}
}
{
// Test bug 324972
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_CSV"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestvariousbugs/324972_1.csv"));
SKGTESTERROR(QStringLiteral("imp1.importFile"), imp1.importFile(), true)
}
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("IMPORT_CSV"), err)
SKGImportExportManager imp1(&document1, QUrl::fromLocalFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestvariousbugs/324972_2.csv"));
SKGTESTERROR(QStringLiteral("imp1.importFile"), imp1.importFile(), true)
SKGDocument::SKGMessageList messages;
SKGTESTERROR(QStringLiteral("DOC.getMessages"), document1.getMessages(document1.getCurrentTransaction(), messages, true), true)
bool test = false;
for (const auto& msg : qAsConst(messages)) {
SKGTRACE << "Message:" << msg.Text << endl;
if (msg.Text.contains(QStringLiteral("last imported one"))) {
test = true;
}
}
SKGTEST(QStringLiteral("message.last imported one"), static_cast<unsigned int>(test), 1)
}
SKGAccountObject account;
SKGTESTERROR(QStringLiteral("ACCOUNT.getObjectByName"), SKGNamedObject::getObjectByName(&document1, QStringLiteral("v_account"), QStringLiteral("My account"), account), true)
SKGTESTERROR(QStringLiteral("ACCOUNT.load"), account.load(), true)
SKGTEST(QStringLiteral("ACCOUNT:getCurrentAmount"), SKGServices::doubleToString(account.getCurrentAmount()), QStringLiteral("1000"))
}
{
// Test import Weboob
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.load()"), document1.load(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestvariousbugs/interests_and_shares.skg"), true)
// Check
{
SKGAccountObject act(&document1);
SKGTESTERROR(QStringLiteral("account.setName()"), act.setName(QStringLiteral("TEST")), true)
SKGTESTERROR(QStringLiteral("account.load()"), act.load(), true)
SKGAccountObject::SKGInterestItemList oInterestList;
double oInterests;
SKGTESTERROR(QStringLiteral("account.getInterestItems()"), act.getInterestItems(oInterestList, oInterests, 2013), true)
SKGTEST(QStringLiteral("oInterestList"), oInterestList.count(), 4)
SKGTEST(QStringLiteral("oInterests"), static_cast<unsigned int>(oInterests > 3.20 && oInterests < 3.22), 1)
SKGTESTERROR(QStringLiteral("account.getInterestItems()"), act.getInterestItems(oInterestList, oInterests, 2014), true)
}
}
{
// Test open invalid files
SKGDocumentBank document1;
SKGTEST(QStringLiteral("document1.load(interests_and_shares.skg,notneededpassword)"), document1.load(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestvariousbugs/interests_and_shares.skg", QStringLiteral("notneededpassword")).getReturnCode(), 0)
SKGTEST(QStringLiteral("document1.load(invalid.skg)"), document1.load(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestvariousbugs/invalid.skg").getReturnCode(), ERR_CORRUPTION)
SKGTEST(QStringLiteral("document1.load(invalid_protected.skg)"), document1.load(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestvariousbugs/invalid_protected.skg").getReturnCode(), ERR_ENCRYPTION)
SKGTEST(QStringLiteral("document1.load(protected.skg)"), document1.load(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestvariousbugs/protected.skg").getReturnCode(), ERR_ENCRYPTION)
SKGTEST(QStringLiteral("document1.load(protected.skg, pwd)"), document1.load(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestvariousbugs/protected.skg", QStringLiteral("pwd")).getReturnCode(), 0)
SKGTEST(QStringLiteral("document1.load(forrecovery.skg)"), document1.load(SKGTest::getTestPath(QStringLiteral("OUT")) % "/skgtestvariousbugs/forrecovery.skg").getReturnCode(), ERR_CORRUPTION)
QString recoveredFile;
SKGTESTERROR(QStringLiteral("document1.recover(forrecovery.skg)"), document1.recover(SKGTest::getTestPath(QStringLiteral("OUT")) % "/skgtestvariousbugs/forrecovery.skg", QLatin1String(""), recoveredFile), true)
SKGTEST(QStringLiteral("document1.load(forrecovery_recovered.skg)"), document1.load(recoveredFile).getReturnCode(), 0)
}
{
// Test 329568
SKGDocumentBank document1;
SKGTESTERROR(QStringLiteral("document1.load()"), document1.load(SKGTest::getTestPath(QStringLiteral("IN")) % "/skgtestvariousbugs/329568.skg"), true)
// Check
{
SKGAccountObject act(&document1);
SKGTESTERROR(QStringLiteral("account.setName()"), act.setName(QStringLiteral("T")), true)
SKGTESTERROR(QStringLiteral("account.load()"), act.load(), true)
SKGAccountObject::SKGInterestItemList oInterestList;
double oInterests;
SKGTESTERROR(QStringLiteral("account.getInterestItems()"), act.getInterestItems(oInterestList, oInterests, 2014), true)
SKGTEST(QStringLiteral("oInterestList"), oInterestList.count(), 4)
SKGTEST(QStringLiteral("oInterests"), static_cast<unsigned int>(oInterests > 8.20 && oInterests < 8.22), 1)
}
{
auto imp1 = new SKGImportPlugin();
SKGTESTERROR(QStringLiteral("SKGImportPlugin.importFile"), imp1->importFile(), false)
SKGTESTERROR(QStringLiteral("SKGImportPlugin.exportFile"), imp1->exportFile(), false)
imp1->getMimeTypeFilter();
delete imp1;
}
}
// End test
SKGENDTEST()
}
diff --git a/tests/skgbaseguitest/CMakeLists.txt b/tests/skgbaseguitest/CMakeLists.txt
index 08e0806a0..053f45e71 100644
--- a/tests/skgbaseguitest/CMakeLists.txt
+++ b/tests/skgbaseguitest/CMakeLists.txt
@@ -1,41 +1,41 @@
#***************************************************************************
#* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
#* *
#* 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 <http://www.gnu.org/licenses/> *
+#* along with this program. If not, see <https://www.gnu.org/licenses/> *
#***************************************************************************
MESSAGE( STATUS "..:: CMAKE SKGBASEGUITEST ::..")
PROJECT(SKBBASEMODELERTEST)
IF(SKG_WEBENGINE)
MESSAGE( STATUS " Mode WebEngine")
ADD_DEFINITIONS(-DSKG_WEBENGINE=${SKG_WEBENGINE})
ENDIF(SKG_WEBENGINE)
ADD_DEFINITIONS(-DQT_GUI_LIB)
LINK_DIRECTORIES (${LIBRARY_OUTPUT_PATH})
INCLUDE_DIRECTORIES( ${CMAKE_SOURCE_DIR}/tests/skgbasemodelertest )
#Add test
ENABLE_TESTING()
FILE(GLOB cpp_files "skgtest*.cpp")
LIST(SORT cpp_files)
FOREACH(file ${cpp_files})
GET_FILENAME_COMPONENT(utname ${file} NAME_WE)
ADD_EXECUTABLE(${utname} ${file})
TARGET_LINK_LIBRARIES(${utname} Qt5::Gui Qt5::Core Qt5::Test skgbasegui skgbaseguidesigner skgbasemodeler)
ADD_TEST(NAME ${utname} COMMAND ${CMAKE_SOURCE_DIR}/tests/scripts/${utname}.sh)
ENDFOREACH()
INCLUDE(CTest)
diff --git a/tests/skgbaseguitest/skgtestcalculatoredit.cpp b/tests/skgbaseguitest/skgtestcalculatoredit.cpp
index b92b2af0a..0ab081519 100644
--- a/tests/skgbaseguitest/skgtestcalculatoredit.cpp
+++ b/tests/skgbaseguitest/skgtestcalculatoredit.cpp
@@ -1,284 +1,284 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is a test for SKGCalculatorEdit component.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgtestcalculatoredit.h"
#include <qtestevent.h>
#include <qtestkeyboard.h>
#include "skgcalculatoredit.h"
void SKGTESTCalculatorEdit::TestValueCALCULATOR_data()
{
QTest::addColumn<QTestEventList>("events");
QTest::addColumn<double>("expected");
{
QTestEventList list;
list.addKeyClicks(QStringLiteral("5.1"));
QTest::newRow("simple positive value") << list << 5.1;
}
{
QTestEventList list;
list.addKeyClicks(QStringLiteral("-7.2"));
QTest::newRow("simple negative value") << list << -7.2;
}
{
QTestEventList list;
list.addKeyClicks(QStringLiteral("10+5"));
list.addKeyClick(Qt::Key_Return);
QTest::newRow("enter +") << list << 15.0;
}
{
QTestEventList list;
list.addKeyClicks(QStringLiteral("3.5*3"));
list.addKeyClick(Qt::Key_Return);
QTest::newRow("enter *") << list << 10.5;
}
{
QTestEventList list;
list.addKeyClicks(QStringLiteral("5/2"));
list.addKeyClick(Qt::Key_Return);
QTest::newRow("enter /") << list << 2.5;
}
{
QTestEventList list;
list.addKeyClicks(QStringLiteral("-5*2/4-6.2+3.1+4.5"));
list.addKeyClick(Qt::Key_Return);
QTest::newRow("enter complex operation") << list << -1.1;
}
{
QTestEventList list;
list.addKeyClicks(QStringLiteral("3,5*3"));
list.addKeyClick(Qt::Key_Return);
QTest::newRow("enter ,") << list << 10.5;
}
{
QTestEventList list;
list.addKeyClicks(QStringLiteral("3 024,25"));
list.addKeyClick(Qt::Key_Return);
QTest::newRow("enter 3 024,25") << list << 3024.25;
}
}
void SKGTESTCalculatorEdit::TestValueCALCULATOR()
{
QFETCH(QTestEventList, events);
QFETCH(double, expected);
SKGCalculatorEdit calculator(nullptr);
calculator.setMode(SKGCalculatorEdit::CALCULATOR);
events.simulate(&calculator);
calculator.valid();
calculator.formula();
calculator.addParameterValue(QStringLiteral("a"), 5.1);
QCOMPARE(calculator.value(), expected);
}
void SKGTESTCalculatorEdit::TestValueEXPRESSION_data()
{
QTest::addColumn<QTestEventList>("events");
QTest::addColumn<bool>("valid");
QTest::addColumn<double>("expected");
{
QTestEventList list;
list.addKeyClicks(QStringLiteral("abc"));
list.addKeyClick(Qt::Key_Return);
QTest::newRow("invalid expression") << list << false << 0.0;
}
{
QTestEventList list;
list.addKeyClicks(QStringLiteral("1e"));
list.addKeyClick(Qt::Key_Return);
list.addKeyClicks(QStringLiteral("1"));
QTest::newRow("valid expression after invalid one") << list << true << 10.0;
}
{
QTestEventList list;
list.addKeyClicks(QStringLiteral("5.1"));
QTest::newRow("simple positive value") << list << true << 5.1;
}
{
QTestEventList list;
list.addKeyClicks(QStringLiteral("-7.2"));
QTest::newRow("simple negative value") << list << true << -7.2;
}
{
QTestEventList list;
list.addKeyClicks(QStringLiteral("10+5"));
list.addKeyClick(Qt::Key_Return);
QTest::newRow("enter +") << list << true << 15.0;
}
{
QTestEventList list;
list.addKeyClicks(QStringLiteral("3.5*3"));
list.addKeyClick(Qt::Key_Return);
QTest::newRow("enter *") << list << true << 10.5;
}
{
QTestEventList list;
list.addKeyClicks(QStringLiteral("5/2"));
list.addKeyClick(Qt::Key_Return);
QTest::newRow("enter /") << list << true << 2.5;
}
{
QTestEventList list;
list.addKeyClicks(QStringLiteral("-5*2/4-6.2+3.1+4.5"));
list.addKeyClick(Qt::Key_Return);
QTest::newRow("enter complex operation") << list << true << -1.1;
}
{
QTestEventList list;
list.addKeyClicks(QStringLiteral("3,5*3"));
list.addKeyClick(Qt::Key_Return);
QTest::newRow("enter ,") << list << true << 10.5;
}
{
QTestEventList list;
list.addKeyClicks(QStringLiteral("3 024,25"));
list.addKeyClick(Qt::Key_Return);
QTest::newRow("enter 3 024,25") << list << true << 3024.25;
}
}
void SKGTESTCalculatorEdit::TestValueEXPRESSION()
{
QFETCH(QTestEventList, events);
QFETCH(bool, valid);
QFETCH(double, expected);
SKGCalculatorEdit calculator(nullptr);
calculator.setMode(SKGCalculatorEdit::EXPRESSION);
events.simulate(&calculator);
QCOMPARE(calculator.valid(), valid);
QCOMPARE(calculator.value(), expected);
}
void SKGTESTCalculatorEdit::TestString_data()
{
QTest::addColumn<QTestEventList>("events");
QTest::addColumn<QString>("expected");
{
QTestEventList list;
list.addKeyClicks(QStringLiteral("3,5*3"));
list.addKeyClick(Qt::Key_Return);
QTest::newRow("enter , as string") << list << "10.5";
}
{
QTestEventList list;
list.addKeyClicks(QStringLiteral("5a"));
list.addKeyClick(Qt::Key_Return);
QTest::newRow("invalid expression") << list << "5a";
}
{
QTestEventList list;
list.addKeyClicks(QStringLiteral("-7.2"));
list.addKeyClick(Qt::Key_Return);
QTest::newRow("simple negative value") << list << "-7.2";
}
{
QTestEventList list;
list.addKeyClicks(QStringLiteral("+7.2"));
list.addKeyClick(Qt::Key_Return);
QTest::newRow("simple positive value") << list << "+7.2";
}
{
QTestEventList list;
list.addKeyClicks(QStringLiteral("-1.84*4-0.46*2-1.89-3.7"));
list.addKeyClick(Qt::Key_Return);
QTest::newRow("Bug 261318") << list << "-13.87";
}
}
void SKGTESTCalculatorEdit::TestString()
{
QFETCH(QTestEventList, events);
QFETCH(QString, expected);
SKGCalculatorEdit calculator(nullptr);
calculator.setMode(SKGCalculatorEdit::EXPRESSION);
events.simulate(&calculator);
QCOMPARE(calculator.text(), expected);
}
void SKGTESTCalculatorEdit::TestSign_data()
{
QTest::addColumn<QTestEventList>("events");
QTest::addColumn<int>("expected");
{
QTestEventList list;
list.addKeyClicks(QStringLiteral("5.1"));
QTest::newRow("simple positive value") << list << 0;
}
{
QTestEventList list;
list.addKeyClicks(QStringLiteral("-7.2"));
QTest::newRow("simple negative value") << list << -1;
}
{
QTestEventList list;
list.addKeyClicks(QStringLiteral("+7.2"));
QTest::newRow("simple positive value") << list << 1;
}
}
void SKGTESTCalculatorEdit::TestSign()
{
QFETCH(QTestEventList, events);
QFETCH(int, expected);
SKGCalculatorEdit calculator(nullptr);
calculator.setMode(SKGCalculatorEdit::CALCULATOR);
events.simulate(&calculator);
QCOMPARE(calculator.sign(), expected);
}
QTEST_MAIN(SKGTESTCalculatorEdit)
diff --git a/tests/skgbaseguitest/skgtestcalculatoredit.h b/tests/skgbaseguitest/skgtestcalculatoredit.h
index 6749573cb..d848237c8 100644
--- a/tests/skgbaseguitest/skgtestcalculatoredit.h
+++ b/tests/skgbaseguitest/skgtestcalculatoredit.h
@@ -1,45 +1,45 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGTESTCALCULATOREDIT_H
#define SKGTESTCALCULATOREDIT_H
/** @file
* This file is a test for SKGCalculatorEdit component.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include <qtest.h>
/**
* A unit test
*/
class SKGTESTCalculatorEdit: public QObject
{
Q_OBJECT
private Q_SLOTS:
void TestValueCALCULATOR();
void TestValueCALCULATOR_data();
void TestValueEXPRESSION();
void TestValueEXPRESSION_data();
void TestString();
void TestString_data();
void TestSign();
void TestSign_data();
};
#endif
diff --git a/tests/skgbaseguitest/skgtestcolorbutton.cpp b/tests/skgbaseguitest/skgtestcolorbutton.cpp
index 410464993..f4f91e7ad 100644
--- a/tests/skgbaseguitest/skgtestcolorbutton.cpp
+++ b/tests/skgbaseguitest/skgtestcolorbutton.cpp
@@ -1,37 +1,37 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is a test for SKGDateEdit component.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgtestcolorbutton.h"
#include "skgcolorbutton.h"
void SKGTESTColorButton::Test()
{
SKGColorButton color(nullptr);
color.setText(QStringLiteral("Hello"));
QCOMPARE(color.text(), QStringLiteral("Hello"));
color.setColor(Qt::white);
QCOMPARE(color.color(), QColor(Qt::white));
color.setDefaultColor(Qt::black);
QCOMPARE(color.defaultColor(), QColor(Qt::black));
}
QTEST_MAIN(SKGTESTColorButton)
diff --git a/tests/skgbaseguitest/skgtestcolorbutton.h b/tests/skgbaseguitest/skgtestcolorbutton.h
index 00feee813..b3fad3ee6 100644
--- a/tests/skgbaseguitest/skgtestcolorbutton.h
+++ b/tests/skgbaseguitest/skgtestcolorbutton.h
@@ -1,35 +1,35 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGTESTCOLORBUTTON_H
#define SKGTESTCOLORBUTTON_H
/** @file
* This file is a test for SKGColorButton component.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include <qtest.h>
/**
* A unit test
*/
class SKGTESTColorButton: public QObject
{
Q_OBJECT
private Q_SLOTS:
void Test();
};
#endif
diff --git a/tests/skgbaseguitest/skgtestcombobox.cpp b/tests/skgbaseguitest/skgtestcombobox.cpp
index 49d36075c..1ffc81c6e 100644
--- a/tests/skgbaseguitest/skgtestcombobox.cpp
+++ b/tests/skgbaseguitest/skgtestcombobox.cpp
@@ -1,47 +1,47 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is a test for SKGComboBox component.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgtestcombobox.h"
#include <qtestkeyboard.h>
#include "skgcombobox.h"
void SKGTESTComboBox::Test()
{
SKGComboBox combo;
QVERIFY(combo.text() == QLatin1String(""));
combo.setText(QStringLiteral("Hello"));
QVERIFY(combo.text() == QStringLiteral("Hello"));
combo.setEditable(false);
QTest::keyClicks(&combo, QStringLiteral("ABCD"));
QCOMPARE(combo.text(), QStringLiteral("Hello"));
combo.setEditable(true);
QTest::keyClicks(&combo, QStringLiteral("ABCD"));
QCOMPARE(combo.text(), QStringLiteral("HelloABCD"));
combo.setPalette(combo.palette());
}
QTEST_MAIN(SKGTESTComboBox)
diff --git a/tests/skgbaseguitest/skgtestcombobox.h b/tests/skgbaseguitest/skgtestcombobox.h
index d5a4a98a7..8e8f551d2 100644
--- a/tests/skgbaseguitest/skgtestcombobox.h
+++ b/tests/skgbaseguitest/skgtestcombobox.h
@@ -1,35 +1,35 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGTESTCOMBOBOX_H
#define SKGTESTCOMBOBOX_H
/** @file
* This file is a test for SKGComboBox component.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include <qtest.h>
/**
* A unit test
*/
class SKGTESTComboBox: public QObject
{
Q_OBJECT
private Q_SLOTS:
void Test();
};
#endif
diff --git a/tests/skgbaseguitest/skgtestdateedit.cpp b/tests/skgbaseguitest/skgtestdateedit.cpp
index e0bcd63f6..9c4fd31fb 100644
--- a/tests/skgbaseguitest/skgtestdateedit.cpp
+++ b/tests/skgbaseguitest/skgtestdateedit.cpp
@@ -1,114 +1,114 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is a test for SKGDateEdit component.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgtestdateedit.h"
#include <qtestevent.h>
#include <qtestkeyboard.h>
#include "skgdateedit.h"
void SKGTESTDateEdit::Test_data()
{
QTest::addColumn<QTestEventList>("events");
QTest::addColumn<QDate>("expected");
// Day
{
QTestEventList list;
list.addKeyClick(Qt::Key_Up);
list.addKeyClick(Qt::Key_Up);
QTest::newRow("++") << list << QDate(1970, 7, 18);
}
{
QTestEventList list;
list.addKeyClick(Qt::Key_Up);
list.addKeyClick(Qt::Key_Down);
QTest::newRow("+-") << list << QDate(1970, 7, 16);
}
{
QTestEventList list;
list.addKeyClick(Qt::Key_Down);
list.addKeyClick(Qt::Key_Down);
QTest::newRow("--") << list << QDate(1970, 7, 14);
}
{
QTestEventList list;
list.addKeyClick(Qt::Key_Down);
list.addKeyClick(Qt::Key_Up);
QTest::newRow("-+") << list << QDate(1970, 7, 16);
}
// Month
{
QTestEventList list;
list.addKeyClick(Qt::Key_PageUp);
list.addKeyClick(Qt::Key_PageUp);
QTest::newRow("++ctrl") << list << QDate(1970, 9, 16);
}
{
QTestEventList list;
list.addKeyClick(Qt::Key_PageUp);
list.addKeyClick(Qt::Key_PageDown);
QTest::newRow("+-ctrl") << list << QDate(1970, 7, 16);
}
{
QTestEventList list;
list.addKeyClick(Qt::Key_PageDown);
list.addKeyClick(Qt::Key_PageDown);
QTest::newRow("--ctrl") << list << QDate(1970, 5, 16);
}
{
QTestEventList list;
list.addKeyClick(Qt::Key_PageDown);
list.addKeyClick(Qt::Key_PageUp);
QTest::newRow("-+ctrl") << list << QDate(1970, 7, 16);
}
// Today
{
QTestEventList list;
list.addKeyClick(Qt::Key_Equal);
QTest::newRow("=") << list << QDate::currentDate();
}
}
void SKGTESTDateEdit::Test()
{
QFETCH(QTestEventList, events);
QFETCH(QDate, expected);
SKGDateEdit dateEditor(nullptr);
dateEditor.setDate(QDate(1970, 7, 16));
events.simulate(&dateEditor);
dateEditor.mode();
QCOMPARE(dateEditor.date(), expected);
}
QTEST_MAIN(SKGTESTDateEdit)
diff --git a/tests/skgbaseguitest/skgtestdateedit.h b/tests/skgbaseguitest/skgtestdateedit.h
index 9057effe1..cedf106ff 100644
--- a/tests/skgbaseguitest/skgtestdateedit.h
+++ b/tests/skgbaseguitest/skgtestdateedit.h
@@ -1,36 +1,36 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGTESTDATEEDIT_H
#define SKGTESTDATEEDIT_H
/** @file
* This file is a test for SKGDateEdit component.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include <qtest.h>
/**
* A unit test
*/
class SKGTESTDateEdit: public QObject
{
Q_OBJECT
private Q_SLOTS:
void Test();
void Test_data();
};
#endif
diff --git a/tests/skgbaseguitest/skgtestperiodedit.cpp b/tests/skgbaseguitest/skgtestperiodedit.cpp
index 22ee80573..32baa35c9 100644
--- a/tests/skgbaseguitest/skgtestperiodedit.cpp
+++ b/tests/skgbaseguitest/skgtestperiodedit.cpp
@@ -1,96 +1,96 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is a test for SKGPeriodEdit component.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgtestperiodedit.h"
#include "skgperiodedit.h"
void SKGTESTPeriodEdit::TestPeriods_data()
{
QTest::addColumn<int>("period");
QTest::addColumn<int>("interval");
QTest::addColumn<int>("value");
QTest::addColumn<QDate>("date");
QTest::addColumn<QDate>("expectedBeginDate");
QTest::addColumn<QDate>("expectedEndDate");
QTest::newRow("CURRENT DAY") << static_cast<int>(SKGPeriodEdit::CURRENT) << static_cast<int>(SKGPeriodEdit::DAY) << 0 << QDate(2014, 12, 3) << QDate(2014, 12, 3) << QDate(2014, 12, 3);
QTest::newRow("CURRENT WEEK") << static_cast<int>(SKGPeriodEdit::CURRENT) << static_cast<int>(SKGPeriodEdit::WEEK) << 0 << QDate(2014, 12, 3) << QDate(2014, 12, 1) << QDate(2014, 12, 7);
QTest::newRow("CURRENT MONTH") << static_cast<int>(SKGPeriodEdit::CURRENT) << static_cast<int>(SKGPeriodEdit::MONTH) << 0 << QDate(2014, 12, 3) << QDate(2014, 12, 1) << QDate(2014, 12, 31);
QTest::newRow("CURRENT QUARTER") << static_cast<int>(SKGPeriodEdit::CURRENT) << static_cast<int>(SKGPeriodEdit::QUARTER) << 0 << QDate(2014, 12, 3) << QDate(2014, 10, 1) << QDate(2014, 12, 31);
QTest::newRow("CURRENT SEMESTER") << static_cast<int>(SKGPeriodEdit::CURRENT) << static_cast<int>(SKGPeriodEdit::SEMESTER) << 0 << QDate(2014, 12, 3) << QDate(2014, 7, 1) << QDate(2014, 12, 31);
QTest::newRow("CURRENT YEAR") << static_cast<int>(SKGPeriodEdit::CURRENT) << static_cast<int>(SKGPeriodEdit::YEAR) << 0 << QDate(2014, 12, 3) << QDate(2014, 1, 1) << QDate(2014, 12, 31);
QTest::newRow("PREVIOUS DAY") << static_cast<int>(SKGPeriodEdit::PREVIOUS) << static_cast<int>(SKGPeriodEdit::DAY) << 1 << QDate(2014, 12, 3) << QDate(2014, 12, 2) << QDate(2014, 12, 2);
QTest::newRow("PREVIOUS WEEK") << static_cast<int>(SKGPeriodEdit::PREVIOUS) << static_cast<int>(SKGPeriodEdit::WEEK) << 1 << QDate(2014, 12, 3) << QDate(2014, 11, 24) << QDate(2014, 11, 30);
QTest::newRow("PREVIOUS MONTH") << static_cast<int>(SKGPeriodEdit::PREVIOUS) << static_cast<int>(SKGPeriodEdit::MONTH) << 1 << QDate(2014, 12, 3) << QDate(2014, 11, 1) << QDate(2014, 11, 30);
QTest::newRow("PREVIOUS QUARTER") << static_cast<int>(SKGPeriodEdit::PREVIOUS) << static_cast<int>(SKGPeriodEdit::QUARTER) << 1 << QDate(2014, 12, 3) << QDate(2014, 7, 1) << QDate(2014, 9, 30);
QTest::newRow("PREVIOUS SEMESTER") << static_cast<int>(SKGPeriodEdit::PREVIOUS) << static_cast<int>(SKGPeriodEdit::SEMESTER) << 1 << QDate(2014, 12, 3) << QDate(2014, 1, 1) << QDate(2014, 6, 30);
QTest::newRow("PREVIOUS YEAR") << static_cast<int>(SKGPeriodEdit::PREVIOUS) << static_cast<int>(SKGPeriodEdit::YEAR) << 1 << QDate(2014, 12, 3) << QDate(2013, 1, 1) << QDate(2013, 12, 31);
QTest::newRow("LAST DAY") << static_cast<int>(SKGPeriodEdit::LAST) << static_cast<int>(SKGPeriodEdit::DAY) << 1 << QDate(2014, 12, 3) << QDate(2014, 12, 3) << QDate(2014, 12, 3);
QTest::newRow("LAST WEEK") << static_cast<int>(SKGPeriodEdit::LAST) << static_cast<int>(SKGPeriodEdit::WEEK) << 1 << QDate(2014, 12, 3) << QDate(2014, 11, 27) << QDate(2014, 12, 3);
QTest::newRow("LAST MONTH") << static_cast<int>(SKGPeriodEdit::LAST) << static_cast<int>(SKGPeriodEdit::MONTH) << 1 << QDate(2014, 12, 3) << QDate(2014, 11, 4) << QDate(2014, 12, 3);
QTest::newRow("LAST QUARTER") << static_cast<int>(SKGPeriodEdit::LAST) << static_cast<int>(SKGPeriodEdit::QUARTER) << 1 << QDate(2014, 12, 3) << QDate(2014, 9, 4) << QDate(2014, 12, 3);
QTest::newRow("LAST SEMESTER") << static_cast<int>(SKGPeriodEdit::LAST) << static_cast<int>(SKGPeriodEdit::SEMESTER) << 1 << QDate(2014, 12, 3) << QDate(2014, 6, 4) << QDate(2014, 12, 3);
QTest::newRow("LAST YEAR") << static_cast<int>(SKGPeriodEdit::LAST) << static_cast<int>(SKGPeriodEdit::YEAR) << 1 << QDate(2014, 12, 3) << QDate(2013, 12, 4) << QDate(2014, 12, 3);
QTest::newRow("PREVIOUS 2 DAY") << static_cast<int>(SKGPeriodEdit::PREVIOUS) << static_cast<int>(SKGPeriodEdit::DAY) << 2 << QDate(2014, 12, 3) << QDate(2014, 12, 1) << QDate(2014, 12, 2);
QTest::newRow("PREVIOUS 2 WEEK") << static_cast<int>(SKGPeriodEdit::PREVIOUS) << static_cast<int>(SKGPeriodEdit::WEEK) << 2 << QDate(2014, 12, 3) << QDate(2014, 11, 17) << QDate(2014, 11, 30);
QTest::newRow("PREVIOUS 2 MONTH") << static_cast<int>(SKGPeriodEdit::PREVIOUS) << static_cast<int>(SKGPeriodEdit::MONTH) << 2 << QDate(2014, 12, 3) << QDate(2014, 10, 1) << QDate(2014, 11, 30);
QTest::newRow("PREVIOUS 2 QUARTER") << static_cast<int>(SKGPeriodEdit::PREVIOUS) << static_cast<int>(SKGPeriodEdit::QUARTER) << 2 << QDate(2014, 12, 3) << QDate(2014, 4, 1) << QDate(2014, 9, 30);
QTest::newRow("PREVIOUS 2 SEMESTER") << static_cast<int>(SKGPeriodEdit::PREVIOUS) << static_cast<int>(SKGPeriodEdit::SEMESTER) << 2 << QDate(2014, 12, 3) << QDate(2013, 7, 1) << QDate(2014, 6, 30);
QTest::newRow("PREVIOUS 2 YEAR") << static_cast<int>(SKGPeriodEdit::PREVIOUS) << static_cast<int>(SKGPeriodEdit::YEAR) << 2 << QDate(2014, 12, 3) << QDate(2012, 1, 1) << QDate(2013, 12, 31);
QTest::newRow("LAST 2 DAY") << static_cast<int>(SKGPeriodEdit::LAST) << static_cast<int>(SKGPeriodEdit::DAY) << 2 << QDate(2014, 12, 3) << QDate(2014, 12, 2) << QDate(2014, 12, 3);
QTest::newRow("LAST 2 WEEK") << static_cast<int>(SKGPeriodEdit::LAST) << static_cast<int>(SKGPeriodEdit::WEEK) << 2 << QDate(2014, 12, 3) << QDate(2014, 11, 20) << QDate(2014, 12, 3);
QTest::newRow("LAST 2 MONTH") << static_cast<int>(SKGPeriodEdit::LAST) << static_cast<int>(SKGPeriodEdit::MONTH) << 2 << QDate(2014, 12, 3) << QDate(2014, 10, 4) << QDate(2014, 12, 3);
QTest::newRow("LAST 2 QUARTER") << static_cast<int>(SKGPeriodEdit::LAST) << static_cast<int>(SKGPeriodEdit::QUARTER) << 2 << QDate(2014, 12, 3) << QDate(2014, 6, 4) << QDate(2014, 12, 3);
QTest::newRow("LAST 2 SEMESTER") << static_cast<int>(SKGPeriodEdit::LAST) << static_cast<int>(SKGPeriodEdit::SEMESTER) << 2 << QDate(2014, 12, 3) << QDate(2013, 12, 4) << QDate(2014, 12, 3);
QTest::newRow("LAST 2 YEAR") << static_cast<int>(SKGPeriodEdit::LAST) << static_cast<int>(SKGPeriodEdit::YEAR) << 2 << QDate(2014, 12, 3) << QDate(2012, 12, 4) << QDate(2014, 12, 3);
QTest::newRow("TIMELINE 12 DAY") << static_cast<int>(SKGPeriodEdit::TIMELINE) << static_cast<int>(SKGPeriodEdit::DAY) << 12 << QDate(2014, 12, 3) << QDate(2014, 12, 3) << QDate(2014, 12, 3);
QTest::newRow("TIMELINE 12 WEEK") << static_cast<int>(SKGPeriodEdit::TIMELINE) << static_cast<int>(SKGPeriodEdit::WEEK) << 12 << QDate(2014, 12, 3) << QDate(2014, 12, 1) << QDate(2014, 12, 7);
QTest::newRow("TIMELINE 12 MONTH") << static_cast<int>(SKGPeriodEdit::TIMELINE) << static_cast<int>(SKGPeriodEdit::MONTH) << 12 << QDate(2014, 12, 3) << QDate(2014, 12, 1) << QDate(2014, 12, 31);
QTest::newRow("TIMELINE 12 QUARTER") << static_cast<int>(SKGPeriodEdit::TIMELINE) << static_cast<int>(SKGPeriodEdit::QUARTER) << 12 << QDate(2014, 12, 3) << QDate(2014, 10, 1) << QDate(2014, 12, 31);
QTest::newRow("TIMELINE 12 SEMESTER") << static_cast<int>(SKGPeriodEdit::TIMELINE) << static_cast<int>(SKGPeriodEdit::SEMESTER) << 12 << QDate(2014, 12, 3) << QDate(2014, 7, 1) << QDate(2014, 12, 31);
QTest::newRow("TIMELINE 12 YEAR") << static_cast<int>(SKGPeriodEdit::TIMELINE) << static_cast<int>(SKGPeriodEdit::YEAR) << 12 << QDate(2014, 12, 3) << QDate(2014, 1, 1) << QDate(2014, 12, 31);
}
void SKGTESTPeriodEdit::TestPeriods()
{
QFETCH(int, period);
QFETCH(int, interval);
QFETCH(int, value);
QFETCH(QDate, date);
QFETCH(QDate, expectedBeginDate);
QFETCH(QDate, expectedEndDate);
QDate oBeginDate;
QDate oEndDate;
SKGPeriodEdit::getDates(static_cast<SKGPeriodEdit::PeriodMode>(period), static_cast<SKGPeriodEdit::PeriodInterval>(interval), value, oBeginDate, oEndDate, date);
QCOMPARE(oBeginDate, expectedBeginDate);
QCOMPARE(oEndDate, expectedEndDate);
}
QTEST_MAIN(SKGTESTPeriodEdit)
diff --git a/tests/skgbaseguitest/skgtestperiodedit.h b/tests/skgbaseguitest/skgtestperiodedit.h
index 37b77e1bc..ed4f3d755 100644
--- a/tests/skgbaseguitest/skgtestperiodedit.h
+++ b/tests/skgbaseguitest/skgtestperiodedit.h
@@ -1,36 +1,36 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef skgtestperiodedit_h
#define skgtestperiodedit_h
/** @file
* This file is a test for SKGPeriodEdit component.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include <qtest.h>
/**
* A unit test
*/
class SKGTESTPeriodEdit: public QObject
{
Q_OBJECT
private Q_SLOTS:
void TestPeriods();
void TestPeriods_data();
};
#endif
diff --git a/tests/skgbaseguitest/skgtesttablewithgraph.cpp b/tests/skgbaseguitest/skgtesttablewithgraph.cpp
index 30f0f1553..eb08b9a40 100644
--- a/tests/skgbaseguitest/skgtesttablewithgraph.cpp
+++ b/tests/skgbaseguitest/skgtesttablewithgraph.cpp
@@ -1,145 +1,145 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is a test for SKGTableWithGraph component.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgtesttablewithgraph.h"
#include "skgtablewithgraph.h"
#include "skgtestmacro.h"
void SKGTESTTableWithGraph::Test()
{
SKGTableWithGraph graph(nullptr);
SKGStringListList data;
data.append(QStringList() << QStringLiteral("Category") << QStringLiteral("2013-01") << QStringLiteral("2013-02") << QStringLiteral("2013-03") << QStringLiteral("2013-04") << QStringLiteral("2013-05") << QStringLiteral("2013-06"));
data.append(QStringList() << QStringLiteral("Auto") << QStringLiteral("-50") << QStringLiteral("-40.5") << QStringLiteral("-40") << QStringLiteral("-60") << QStringLiteral("-70") << QStringLiteral("-100"));
data.append(QStringList() << QStringLiteral("Food") << QStringLiteral("-510.0") << QStringLiteral("-520") << QStringLiteral("-530.55") << QLatin1String("") << QStringLiteral("-535") << QStringLiteral("-520"));
data.append(QStringList() << QStringLiteral("s1") << QStringLiteral("1") << QStringLiteral("2") << QStringLiteral("3") << QLatin1String("") << QStringLiteral("4") << QStringLiteral("5"));
data.append(QStringList() << QStringLiteral("s2") << QStringLiteral("1") << QStringLiteral("2") << QStringLiteral("3") << QLatin1String("") << QStringLiteral("4") << QStringLiteral("5"));
data.append(QStringList() << QStringLiteral("s3") << QStringLiteral("1") << QStringLiteral("2") << QStringLiteral("3") << QLatin1String("") << QStringLiteral("4") << QStringLiteral("5"));
data.append(QStringList() << QStringLiteral("s4") << QStringLiteral("1") << QStringLiteral("2") << QStringLiteral("3") << QLatin1String("") << QStringLiteral("4") << QStringLiteral("5"));
data.append(QStringList() << QStringLiteral("s5") << QStringLiteral("1") << QStringLiteral("2") << QStringLiteral("3") << QLatin1String("") << QStringLiteral("4") << QStringLiteral("5"));
data.append(QStringList() << QStringLiteral("s6") << QStringLiteral("1") << QStringLiteral("2") << QStringLiteral("3") << QLatin1String("") << QStringLiteral("4") << QStringLiteral("5"));
data.append(QStringList() << QStringLiteral("s7") << QStringLiteral("1") << QStringLiteral("2") << QStringLiteral("3") << QLatin1String("") << QStringLiteral("4") << QStringLiteral("5"));
data.append(QStringList() << QStringLiteral("s8") << QStringLiteral("1") << QStringLiteral("2") << QStringLiteral("3") << QLatin1String("") << QStringLiteral("4") << QStringLiteral("5"));
data.append(QStringList() << QStringLiteral("s9") << QStringLiteral("1") << QStringLiteral("2") << QStringLiteral("3") << QLatin1String("") << QStringLiteral("4") << QStringLiteral("5"));
data.append(QStringList() << QStringLiteral("s10") << QStringLiteral("1") << QStringLiteral("2") << QStringLiteral("3") << QLatin1String("") << QStringLiteral("4") << QStringLiteral("5"));
data.append(QStringList() << QStringLiteral("s11") << QStringLiteral("1") << QStringLiteral("2") << QStringLiteral("3") << QLatin1String("") << QStringLiteral("4") << QStringLiteral("5"));
data.append(QStringList() << QStringLiteral("s12") << QStringLiteral("1") << QStringLiteral("2") << QStringLiteral("3") << QLatin1String("") << QStringLiteral("4") << QStringLiteral("5"));
SKGServices::SKGUnitInfo info1;
info1.Symbol = 'P';
info1.Name = 'P';
info1.Date = QDate::currentDate();
info1.NbDecimal = 2;
info1.Value = 1;
SKGServices::SKGUnitInfo info2;
info2.Symbol = 'S';
info2.Name = 'S';
info2.Date = QDate::currentDate();
info2.NbDecimal = 4;
info2.Value = 0.5;
graph.setData(data, info1, info2);
graph.setBackgroundColor(Qt::black);
QCOMPARE(graph.isGraphVisible(), true);
QCOMPARE(graph.isTableVisible(), true);
QCOMPARE(graph.isTextReportVisible(), false);
QCOMPARE(graph.isGraphTypeSelectorVisible(), true);
QCOMPARE(graph.switchLegendVisibility(), true);
QCOMPARE(graph.switchLinearRegressionVisibility(), false);
QCOMPARE(graph.switchLinearRegressionVisibility(), true);
QCOMPARE(graph.switchLimitsVisibility(), false);
QCOMPARE(graph.switchLimitsVisibility(), true);
QCOMPARE(graph.swithOriginVisibility(), false);
QCOMPARE(graph.swithOriginVisibility(), true);
QCOMPARE(graph.getAdditionalDisplayMode(), SKGTableWithGraph::ALL);
graph.setShadowVisible(true);
QCOMPARE(graph.isShadowVisible(), true);
graph.setShadowVisible(false);
QCOMPARE(graph.isShadowVisible(), false);
graph.setSelectable(true);
QCOMPARE(graph.isSelectable(), true);
graph.setSelectable(false);
QCOMPARE(graph.isSelectable(), false);
for (int i = 0; i < 9; ++i) {
graph.setGraphType(static_cast<SKGTableWithGraph::GraphType>(i));
QCOMPARE(graph.getGraphType(), static_cast<SKGTableWithGraph::GraphType>(i));
QTest::qWait(1000);
graph.graph()->exportInFile(SKGTest::getTestPath(QStringLiteral("OUT")) % "/skgtesttablewithgraph/SKGGraphicsView_" + SKGServices::intToString(i) + ".png");
}
// Graph
QTest::qWait(2000);
graph.resetColors();
SKGGraphicsView* g = graph.graph();
g->onCopy();
g->onSwitchToolBarVisibility();
g->onSwitchToolBarVisibility();
g->exportInFile(SKGTest::getTestPath(QStringLiteral("OUT")) % "/skgtesttablewithgraph/SKGGraphicsView.svg");
g->exportInFile(SKGTest::getTestPath(QStringLiteral("OUT")) % "/skgtesttablewithgraph/SKGGraphicsView.pdf");
g->exportInFile(SKGTest::getTestPath(QStringLiteral("OUT")) % "/skgtesttablewithgraph/SKGGraphicsView.jpeg");
g->setAntialiasing(false);
g->setAntialiasing(true);
SKGShow* show = graph.getShowWidget();
show->setState(QStringLiteral("text"));
show->getMode();
show->setDisplayTitle(true);
QCOMPARE(show->getDisplayTitle(), true);
show->setDisplayTitle(false);
QCOMPARE(show->getDisplayTitle(), false);
/*QCOMPARE(graph.isGraphVisible(), true);
QCOMPARE(graph.isTableVisible(), true);
QCOMPARE(graph.isTextReportVisible(), true);*/
SKGWebView* t = graph.textReport();
QTest::qWait(2000);
t->onZoomIn();
t->onZoomOriginal();
t->onZoomOut();
t->exportInFile(SKGTest::getTestPath(QStringLiteral("OUT")) % "/skgtesttablewithgraph/SKGWebView.odt");
t->exportInFile(SKGTest::getTestPath(QStringLiteral("OUT")) % "/skgtesttablewithgraph/SKGWebView.pdf");
t->exportInFile(SKGTest::getTestPath(QStringLiteral("OUT")) % "/skgtesttablewithgraph/SKGWebView.html");
t->exportInFile(SKGTest::getTestPath(QStringLiteral("OUT")) % "/skgtesttablewithgraph/SKGWebView.htm");
t->exportInFile(SKGTest::getTestPath(QStringLiteral("OUT")) % "/skgtesttablewithgraph/SKGWebView.png");
graph.exportInFile(SKGTest::getTestPath(QStringLiteral("OUT")) % "/skgtesttablewithgraph/SKGTableWithGraph.csv");
graph.exportInFile(SKGTest::getTestPath(QStringLiteral("OUT")) % "/skgtesttablewithgraph/SKGTableWithGraph.txt");
graph.getTable();
}
QTEST_MAIN(SKGTESTTableWithGraph)
diff --git a/tests/skgbaseguitest/skgtesttablewithgraph.h b/tests/skgbaseguitest/skgtesttablewithgraph.h
index fa29f402e..0a83e8a63 100644
--- a/tests/skgbaseguitest/skgtesttablewithgraph.h
+++ b/tests/skgbaseguitest/skgtesttablewithgraph.h
@@ -1,35 +1,35 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGTESTTABLEWITHGRAPH_H
#define SKGTESTTABLEWITHGRAPH_H
/** @file
* This file is a test for SKGTableWithGraph component.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include <qtest.h>
/**
* A unit test
*/
class SKGTESTTableWithGraph: public QObject
{
Q_OBJECT
private Q_SLOTS:
void Test();
};
#endif
diff --git a/tests/skgbaseguitest/skgtestwidgetcollection.cpp b/tests/skgbaseguitest/skgtestwidgetcollection.cpp
index d7b3bd117..832e265ce 100644
--- a/tests/skgbaseguitest/skgtestwidgetcollection.cpp
+++ b/tests/skgbaseguitest/skgtestwidgetcollection.cpp
@@ -1,72 +1,72 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is a test for SKGWidgetCollectionDesignerPlugin component.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgtestwidgetcollection.h"
#include <qicon.h>
#include "skggraphicsscene.h"
#include "skgtestmacro.h"
#include "skgwebview.h"
#include "skgwidgetcollectiondesignerplugin.h"
#include "skgzoomselector.h"
void SKGTESTWidgetCollection::Test()
{
SKGWidgetCollectionDesignerPlugin col(this);
QList<QDesignerCustomWidgetInterface*> widgets = col.customWidgets();
for (int i = 0; i < widgets.count(); ++i) {
QDesignerCustomWidgetInterface* widget = widgets.at(i);
QCOMPARE(widget != nullptr, true);
widget->isContainer();
QCOMPARE(widget->isInitialized(), false);
widget->initialize(nullptr);
QCOMPARE(widget->isInitialized(), true);
widget->icon();
QCOMPARE(widget->domXml() != QLatin1String(""), true);
QCOMPARE(widget->group(), QStringLiteral("SKG Widgets"));
QCOMPARE(widget->includeFile() != QLatin1String(""), true);
QCOMPARE(widget->name() != QLatin1String(""), true);
QCOMPARE(widget->toolTip() != QLatin1String(""), true);
QCOMPARE(widget->whatsThis() != QLatin1String(""), true);
QCOMPARE(widget->createWidget(nullptr) != nullptr, true);
}
// Test zoom
SKGZoomSelector zoom(nullptr);
zoom.zoomIn();
zoom.zoomOut();
zoom.initializeZoom();
// Test web view
SKGWebView web(nullptr);
web.onZoomIn();
web.onZoomOut();
web.exportInFile(SKGTest::getTestPath(QStringLiteral("OUT")) % "/skgtestwidgetcollection/export.pdf");
web.exportInFile(SKGTest::getTestPath(QStringLiteral("OUT")) % "/skgtestwidgetcollection/export.html");
web.exportInFile(SKGTest::getTestPath(QStringLiteral("OUT")) % "/skgtestwidgetcollection/export.jpg");
SKGGraphicsScene graphScene;
}
QTEST_MAIN(SKGTESTWidgetCollection)
diff --git a/tests/skgbaseguitest/skgtestwidgetcollection.h b/tests/skgbaseguitest/skgtestwidgetcollection.h
index 7ec8e1ec2..467caa443 100644
--- a/tests/skgbaseguitest/skgtestwidgetcollection.h
+++ b/tests/skgbaseguitest/skgtestwidgetcollection.h
@@ -1,35 +1,35 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGTESTWIDGETCOLLECTION_H
#define SKGTESTWIDGETCOLLECTION_H
/** @file
* This file is a test for SKGWidgetCollectionDesignerPlugin component.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include <qtest.h>
/**
* A unit test
*/
class SKGTESTWidgetCollection: public QObject
{
Q_OBJECT
private Q_SLOTS:
void Test();
};
#endif
diff --git a/tests/skgbasemodelertest/CMakeLists.txt b/tests/skgbasemodelertest/CMakeLists.txt
index f25d2f68d..28d01cda7 100644
--- a/tests/skgbasemodelertest/CMakeLists.txt
+++ b/tests/skgbasemodelertest/CMakeLists.txt
@@ -1,33 +1,33 @@
#***************************************************************************
#* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
#* *
#* 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 <http://www.gnu.org/licenses/> *
+#* along with this program. If not, see <https://www.gnu.org/licenses/> *
#***************************************************************************
MESSAGE( STATUS "..:: CMAKE SKBBASEMODELERTEST ::..")
PROJECT(SKBBASEMODELERTEST)
LINK_DIRECTORIES (${LIBRARY_OUTPUT_PATH})
#Add test
ENABLE_TESTING()
FILE(GLOB cpp_files "skgtest*.cpp")
LIST(SORT cpp_files)
FOREACH(file ${cpp_files})
GET_FILENAME_COMPONENT(utname ${file} NAME_WE)
ADD_EXECUTABLE(${utname} ${file})
TARGET_LINK_LIBRARIES(${utname} Qt5::Core KF5::KIOWidgets skgbasemodeler)
ADD_TEST(NAME ${utname} COMMAND ${CMAKE_SOURCE_DIR}/tests/scripts/${utname}.sh)
ENDFOREACH()
INCLUDE(CTest)
diff --git a/tests/skgbasemodelertest/skgtestbase.cpp b/tests/skgbasemodelertest/skgtestbase.cpp
index dd24c3187..927bd9e11 100644
--- a/tests/skgbasemodelertest/skgtestbase.cpp
+++ b/tests/skgbasemodelertest/skgtestbase.cpp
@@ -1,738 +1,738 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is a test script.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgtestmacro.h"
/**
* The main function of the unit test
* @param argc the number of arguments
* @param argv the list of arguments
*/
void test_getPeriodWhereClause(int& nberror, int& nbcheck, bool showonlyfailures)
{
SKGTEST(QStringLiteral("CONV:getPeriodWhereClause"), SKGServices::getPeriodWhereClause(QStringLiteral("2014")), QStringLiteral("STRFTIME('%Y',d_date)='2014'"))
SKGTEST(QStringLiteral("CONV:getPeriodWhereClause"), SKGServices::getPeriodWhereClause(QStringLiteral("2014-02")), QStringLiteral("STRFTIME('%Y-%m',d_date)='2014-02'"))
SKGTEST(QStringLiteral("CONV:getPeriodWhereClause"), SKGServices::getPeriodWhereClause(QStringLiteral("2014-10")), QStringLiteral("STRFTIME('%Y-%m',d_date)='2014-10'"))
SKGTEST(QStringLiteral("CONV:getPeriodWhereClause"), SKGServices::getPeriodWhereClause(QStringLiteral("2014-Q2")), QStringLiteral("STRFTIME('%Y',d_date)||'-Q'||(CASE WHEN STRFTIME('%m',d_date)<='03' THEN '1' WHEN STRFTIME('%m',d_date)<='06' THEN '2' WHEN STRFTIME('%m',d_date)<='09' THEN '3' ELSE '4' END)='2014-Q2'"))
SKGTEST(QStringLiteral("CONV:getPeriodWhereClause"), SKGServices::getPeriodWhereClause(QStringLiteral("2014-S2")), QStringLiteral("STRFTIME('%Y',d_date)||'-S'||(CASE WHEN STRFTIME('%m',d_date)<='06' THEN '1' ELSE '2' END)='2014-S2'"))
SKGTEST(QStringLiteral("CONV:getPeriodWhereClause"), SKGServices::getPeriodWhereClause(QStringLiteral("INVALID STRING")), QStringLiteral("1=0"))
SKGTEST(QStringLiteral("CONV:getPeriodWhereClause"), SKGServices::getPeriodWhereClause(QStringLiteral("ALL")), QStringLiteral("1=1"))
}
void test_getNeighboringPeriod(int& nberror, int& nbcheck, bool showonlyfailures)
{
SKGTEST(QStringLiteral("CONV:getNeighboringPeriod"), SKGServices::getNeighboringPeriod(QStringLiteral("2014")), QStringLiteral("2013"))
SKGTEST(QStringLiteral("CONV:getNeighboringPeriod"), SKGServices::getNeighboringPeriod(QStringLiteral("2014-10")), QStringLiteral("2014-09"))
SKGTEST(QStringLiteral("CONV:getNeighboringPeriod"), SKGServices::getNeighboringPeriod(QStringLiteral("2014-01")), QStringLiteral("2013-12"))
SKGTEST(QStringLiteral("CONV:getNeighboringPeriod"), SKGServices::getNeighboringPeriod(QStringLiteral("2014-Q2")), QStringLiteral("2014-Q1"))
SKGTEST(QStringLiteral("CONV:getNeighboringPeriod"), SKGServices::getNeighboringPeriod(QStringLiteral("2014-Q1")), QStringLiteral("2013-Q4"))
SKGTEST(QStringLiteral("CONV:getNeighboringPeriod"), SKGServices::getNeighboringPeriod(QStringLiteral("2014-S2")), QStringLiteral("2014-S1"))
SKGTEST(QStringLiteral("CONV:getNeighboringPeriod"), SKGServices::getNeighboringPeriod(QStringLiteral("2014-S1")), QStringLiteral("2013-S2"))
SKGTEST(QStringLiteral("CONV:getNeighboringPeriod"), SKGServices::getNeighboringPeriod(QStringLiteral("INVALID STRING")), QStringLiteral("1=0"))
SKGTEST(QStringLiteral("CONV:getNeighboringPeriod"), SKGServices::getNeighboringPeriod(QStringLiteral("ALL")), QStringLiteral("1=0"))
SKGTEST(QStringLiteral("CONV:getNeighboringPeriod +1"), SKGServices::getNeighboringPeriod(QStringLiteral("2014"), 1), QStringLiteral("2015"))
SKGTEST(QStringLiteral("CONV:getNeighboringPeriod +1"), SKGServices::getNeighboringPeriod(QStringLiteral("2014-10"), 1), QStringLiteral("2014-11"))
SKGTEST(QStringLiteral("CONV:getNeighboringPeriod +1"), SKGServices::getNeighboringPeriod(QStringLiteral("2014-01"), 1), QStringLiteral("2014-02"))
SKGTEST(QStringLiteral("CONV:getNeighboringPeriod +1"), SKGServices::getNeighboringPeriod(QStringLiteral("2014-Q4"), 1), QStringLiteral("2015-Q1"))
SKGTEST(QStringLiteral("CONV:getNeighboringPeriod +1"), SKGServices::getNeighboringPeriod(QStringLiteral("2014-Q2"), 1), QStringLiteral("2014-Q3"))
SKGTEST(QStringLiteral("CONV:getNeighboringPeriod +1"), SKGServices::getNeighboringPeriod(QStringLiteral("2014-Q1"), 1), QStringLiteral("2014-Q2"))
SKGTEST(QStringLiteral("CONV:getNeighboringPeriod +1"), SKGServices::getNeighboringPeriod(QStringLiteral("2014-S2"), 1), QStringLiteral("2015-S1"))
SKGTEST(QStringLiteral("CONV:getNeighboringPeriod +1"), SKGServices::getNeighboringPeriod(QStringLiteral("2014-S1"), 1), QStringLiteral("2014-S2"))
}
void test_periodToDate(int& nberror, int& nbcheck, bool showonlyfailures)
{
SKGTEST(QStringLiteral("CONV:periodToDate"), SKGServices::periodToDate(QStringLiteral("2014")).toString(), QDate(2014, 12, 31).toString())
SKGTEST(QStringLiteral("CONV:periodToDate"), SKGServices::periodToDate(QStringLiteral("2014-S1")).toString(), QDate(2014, 6, 30).toString())
SKGTEST(QStringLiteral("CONV:periodToDate"), SKGServices::periodToDate(QStringLiteral("2014-S2")).toString(), QDate(2014, 12, 31).toString())
SKGTEST(QStringLiteral("CONV:periodToDate"), SKGServices::periodToDate(QStringLiteral("2014-Q1")).toString(), QDate(2014, 3, 31).toString())
SKGTEST(QStringLiteral("CONV:periodToDate"), SKGServices::periodToDate(QStringLiteral("2014-Q2")).toString(), QDate(2014, 6, 30).toString())
SKGTEST(QStringLiteral("CONV:periodToDate"), SKGServices::periodToDate(QStringLiteral("2014-Q3")).toString(), QDate(2014, 9, 30).toString())
SKGTEST(QStringLiteral("CONV:periodToDate"), SKGServices::periodToDate(QStringLiteral("2014-Q4")).toString(), QDate(2014, 12, 31).toString())
SKGTEST(QStringLiteral("CONV:periodToDate"), SKGServices::periodToDate(QStringLiteral("2014-01")).toString(), QDate(2014, 1, 31).toString())
SKGTEST(QStringLiteral("CONV:periodToDate"), SKGServices::periodToDate(QStringLiteral("2014-07")).toString(), QDate(2014, 7, 31).toString())
SKGTEST(QStringLiteral("CONV:periodToDate"), SKGServices::periodToDate(QStringLiteral("ALL")).toString(), QDate::currentDate().toString())
}
void test_partialStringToDate(int& nberror, int& nbcheck, bool showonlyfailures)
{
SKGTEST(QStringLiteral("CONV:partialStringToDate"), SKGServices::partialStringToDate(QStringLiteral("INVALID"), true).toString(), QLatin1String(""))
QDate currentMonth10 = QDate::currentDate();
currentMonth10 = currentMonth10.addDays(10 - QDate::currentDate().day());
QDate current0102(QDate::currentDate().year(), 2, 1);
SKGTEST(QStringLiteral("CONV:partialStringToDate"), SKGServices::partialStringToDate(QStringLiteral("10"), true).toString(), (currentMonth10 <= QDate::currentDate() ? currentMonth10 : currentMonth10.addMonths(-1)).toString())
SKGTEST(QStringLiteral("CONV:partialStringToDate"), SKGServices::partialStringToDate(QStringLiteral("1/2"), true).toString(), (current0102 <= QDate::currentDate() ? current0102 : current0102.addYears(-1)).toString())
SKGTEST(QStringLiteral("CONV:partialStringToDate"), SKGServices::partialStringToDate(QStringLiteral("1/2/14"), true).toString(), QDate(2014, 2, 1).toString())
SKGTEST(QStringLiteral("CONV:partialStringToDate"), SKGServices::partialStringToDate(QStringLiteral("1/2/99"), true).toString(), QDate(1999, 2, 1).toString())
SKGTEST(QStringLiteral("CONV:partialStringToDate"), SKGServices::partialStringToDate(QStringLiteral("1/2/014"), true).toString(), QDate(2014, 2, 1).toString())
SKGTEST(QStringLiteral("CONV:partialStringToDate"), SKGServices::partialStringToDate(QStringLiteral("1/2/199"), true).toString(), QDate(1199, 2, 1).toString())
SKGTEST(QStringLiteral("CONV:partialStringToDate"), SKGServices::partialStringToDate(QStringLiteral("1/2/1014"), true).toString(), QDate(1014, 2, 1).toString())
SKGTEST(QStringLiteral("CONV:partialStringToDate"), SKGServices::partialStringToDate(QStringLiteral("1/2/2222"), true).toString(), QDate(2222, 2, 1).toString())
SKGTEST(QStringLiteral("CONV:partialStringToDate"), SKGServices::partialStringToDate(QStringLiteral("10"), false).toString(), (currentMonth10 >= QDate::currentDate() ? currentMonth10 : currentMonth10.addMonths(1)).toString())
SKGTEST(QStringLiteral("CONV:partialStringToDate"), SKGServices::partialStringToDate(QStringLiteral("1/2"), false).toString(), (current0102 >= QDate::currentDate() ? current0102 : current0102.addYears(1)).toString())
SKGTEST(QStringLiteral("CONV:partialStringToDate"), SKGServices::partialStringToDate(QStringLiteral("1/2/14"), false).toString(), QDate(2114, 2, 1).toString())
SKGTEST(QStringLiteral("CONV:partialStringToDate"), SKGServices::partialStringToDate(QStringLiteral("1/2/99"), false).toString(), QDate(2099, 2, 1).toString())
SKGTEST(QStringLiteral("CONV:partialStringToDate"), SKGServices::partialStringToDate(QStringLiteral("1/2/014"), false).toString(), QDate(3014, 2, 1).toString())
SKGTEST(QStringLiteral("CONV:partialStringToDate"), SKGServices::partialStringToDate(QStringLiteral("1/2/199"), false).toString(), QDate(2199, 2, 1).toString())
SKGTEST(QStringLiteral("CONV:partialStringToDate"), SKGServices::partialStringToDate(QStringLiteral("1/2/1014"), false).toString(), QDate(1014, 2, 1).toString())
SKGTEST(QStringLiteral("CONV:partialStringToDate"), SKGServices::partialStringToDate(QStringLiteral("1/2/2222"), false).toString(), QDate(2222, 2, 1).toString())
}
void test_conversions(int& nberror, int& nbcheck, bool showonlyfailures)
{
SKGTEST(QStringLiteral("CONV:dateToPeriod"), SKGServices::dateToPeriod(QDate(2013, 03, 05), QStringLiteral("D")), QStringLiteral("2013-03-05"))
SKGTEST(QStringLiteral("CONV:dateToPeriod"), SKGServices::dateToPeriod(QDate(2013, 01, 01), QStringLiteral("W")), QStringLiteral("2013-W01"))
SKGTEST(QStringLiteral("CONV:dateToPeriod"), SKGServices::dateToPeriod(QDate(2013, 03, 05), QStringLiteral("W")), QStringLiteral("2013-W10"))
SKGTEST(QStringLiteral("CONV:dateToPeriod"), SKGServices::dateToPeriod(QDate(2013, 03, 05), QStringLiteral("M")), QStringLiteral("2013-03"))
SKGTEST(QStringLiteral("CONV:dateToPeriod"), SKGServices::dateToPeriod(QDate(2013, 03, 05), QStringLiteral("Q")), QStringLiteral("2013-Q1"))
SKGTEST(QStringLiteral("CONV:dateToPeriod"), SKGServices::dateToPeriod(QDate(2013, 03, 05), QStringLiteral("S")), QStringLiteral("2013-S1"))
SKGTEST(QStringLiteral("CONV:dateToPeriod"), SKGServices::dateToPeriod(QDate(2013, 03, 05), QStringLiteral("Y")), QStringLiteral("2013"))
SKGTEST(QStringLiteral("CONV:intToString"), SKGServices::intToString(10), QStringLiteral("10"))
SKGTEST(QStringLiteral("CONV:intToString"), SKGServices::intToString(5490990004), QStringLiteral("5490990004"))
SKGTEST(QStringLiteral("CONV:stringToInt"), SKGServices::stringToInt(QStringLiteral("56")), 56)
SKGTEST(QStringLiteral("CONV:stringToInt"), SKGServices::stringToInt(QStringLiteral("HELLO")), 0)
SKGTEST(QStringLiteral("CONV:stringToInt"), SKGServices::stringToInt(QStringLiteral("5HELLO")), 0)
SKGTEST(QStringLiteral("CONV:stringToInt"), SKGServices::stringToInt(QStringLiteral("5490990004")), 5490990004)
SKGTEST(QStringLiteral("CONV:doubleToString"), SKGServices::doubleToString(10), QStringLiteral("10"))
SKGTEST(QStringLiteral("CONV:doubleToString"), SKGServices::doubleToString(5.3), QStringLiteral("5.3"))
SKGTEST(QStringLiteral("CONV:doubleToString"), SKGServices::doubleToString(11111115.33), QStringLiteral("11111115.33"))
SKGTEST(QStringLiteral("CONV:doubleToString"), SKGServices::doubleToString(119999.11), QStringLiteral("119999.11"))
SKGTEST(QStringLiteral("CONV:stringToDouble"), SKGServices::stringToDouble(QStringLiteral("10")) - 10, 0)
SKGTEST(QStringLiteral("CONV:stringToDouble"), SKGServices::stringToDouble(QStringLiteral("5.3")) - 5.3, 0)
SKGTEST(QStringLiteral("CONV:stringToDouble"), SKGServices::stringToDouble(QStringLiteral("11111115.33")) - 11111115.33, 0)
SKGTEST(QStringLiteral("CONV:stringToDouble"), SKGServices::stringToDouble(QStringLiteral("25,000.00")) - 25000.00, 0)
SKGTEST(QStringLiteral("CONV:stringToDouble"), SKGServices::stringToDouble(QStringLiteral("1.307,40")) - 1307.40, 0)
SKGTEST(QStringLiteral("CONV:stringToDouble"), SKGServices::stringToDouble(QStringLiteral("2 150,10")) - 2150.10, 0)
SKGTEST(QStringLiteral("CONV:stringToDouble"), SKGServices::stringToDouble(QStringLiteral("-$8.35")) + 8.35, 0)
SKGTEST(QStringLiteral("CONV:stringToDouble"), SKGServices::stringToDouble(QStringLiteral("8.35€")) - 8.35, 0)
SKGTEST(QStringLiteral("CONV:stringToDouble"), SKGServices::stringToDouble(QStringLiteral("1234.56e-02")) - 12.3456, 0)
SKGTEST(QStringLiteral("CONV:stringToDouble"), SKGServices::stringToDouble(QStringLiteral("31238/100")) - 312.38, 0)
SKGTEST(QStringLiteral("CONV:stringToDouble"), SKGServices::stringToDouble(QStringLiteral("31238/abc")), 0)
SKGTEST(QStringLiteral("CONV:stringToDouble"), SKGServices::stringToDouble(QStringLiteral("nan")), 0)
SKGTEST(QStringLiteral("CONV:stringToDouble"), SKGServices::stringToDouble(QStringLiteral("inf")), 1e300)
SKGTEST(QStringLiteral("CONV:stringToDouble"), SKGServices::stringToDouble(QStringLiteral("-inf")), -1e300)
SKGTEST(QStringLiteral("CONV:stringToDouble"), SKGServices::stringToDouble(QStringLiteral("00000000194065")), 194065)
SKGServices::timeToString(QDateTime());
SKGTEST(QStringLiteral("CONV:stringToTime"), SKGServices::timeToString(SKGServices::stringToTime(QStringLiteral("1970-07-16"))), QStringLiteral("1970-07-16 00:00:00"))
SKGTEST(QStringLiteral("CONV:stringToTime"), SKGServices::timeToString(SKGServices::stringToTime(QStringLiteral("2008-04-20"))), QStringLiteral("2008-04-20 00:00:00"))
SKGTEST(QStringLiteral("CONV:stringToTime"), SKGServices::dateToSqlString(SKGServices::stringToTime(QStringLiteral("1970-07-16"))), QStringLiteral("1970-07-16"))
SKGTEST(QStringLiteral("CONV:stringToTime"), SKGServices::dateToSqlString(SKGServices::stringToTime(QStringLiteral("2008-04-20"))), QStringLiteral("2008-04-20"))
SKGTESTBOOL("CONV:SKGServices::getMicroTime", (SKGServices::getMicroTime() > 0), true)
SKGTEST(QStringLiteral("STR:dateToSqlString"), SKGServices::dateToSqlString(QStringLiteral("20080525"), QStringLiteral("YYYYMMDD")), QStringLiteral("2008-05-25"))
SKGTEST(QStringLiteral("STR:dateToSqlString"), SKGServices::dateToSqlString(QStringLiteral("2008-05-25"), QStringLiteral("YYYY-MM-DD")), QStringLiteral("2008-05-25"))
SKGTEST(QStringLiteral("STR:dateToSqlString"), SKGServices::dateToSqlString(QStringLiteral("2008-05-25 00:00:00"), QStringLiteral("YYYY-MM-DD")), QStringLiteral("2008-05-25"))
SKGTEST(QStringLiteral("STR:dateToSqlString"), SKGServices::dateToSqlString(QStringLiteral("05/25/08"), QStringLiteral("MM/DD/YY")), QStringLiteral("2008-05-25"))
SKGTEST(QStringLiteral("STR:dateToSqlString"), SKGServices::dateToSqlString(QStringLiteral("05/25/78"), QStringLiteral("MM/DD/YY")), QStringLiteral("1978-05-25"))
SKGTEST(QStringLiteral("STR:dateToSqlString"), SKGServices::dateToSqlString(QStringLiteral("05-25-08"), QStringLiteral("MM-DD-YY")), QStringLiteral("2008-05-25"))
SKGTEST(QStringLiteral("STR:dateToSqlString"), SKGServices::dateToSqlString(QStringLiteral("05-25-78"), QStringLiteral("MM-DD-YY")), QStringLiteral("1978-05-25"))
SKGTEST(QStringLiteral("STR:dateToSqlString"), SKGServices::dateToSqlString(QStringLiteral("5/25/08"), QStringLiteral("MM/DD/YY")), QStringLiteral("2008-05-25"))
SKGTEST(QStringLiteral("STR:dateToSqlString"), SKGServices::dateToSqlString(QStringLiteral("5/25/78"), QStringLiteral("MM/DD/YY")), QStringLiteral("1978-05-25"))
SKGTEST(QStringLiteral("STR:dateToSqlString"), SKGServices::dateToSqlString(QStringLiteral("5-25-08"), QStringLiteral("MM-DD-YY")), QStringLiteral("2008-05-25"))
SKGTEST(QStringLiteral("STR:dateToSqlString"), SKGServices::dateToSqlString(QStringLiteral("5-6-08"), QStringLiteral("MM-DD-YY")), QStringLiteral("2008-05-06"))
SKGTEST(QStringLiteral("STR:dateToSqlString"), SKGServices::dateToSqlString(QStringLiteral("5-25-78"), QStringLiteral("MM-DD-YY")), QStringLiteral("1978-05-25"))
SKGTEST(QStringLiteral("STR:dateToSqlString"), SKGServices::dateToSqlString(QStringLiteral("25/05/08"), QStringLiteral("DD/MM/YY")), QStringLiteral("2008-05-25"))
SKGTEST(QStringLiteral("STR:dateToSqlString"), SKGServices::dateToSqlString(QStringLiteral("25/05/78"), QStringLiteral("DD/MM/YY")), QStringLiteral("1978-05-25"))
SKGTEST(QStringLiteral("STR:dateToSqlString"), SKGServices::dateToSqlString(QStringLiteral("25-05-08"), QStringLiteral("DD-MM-YY")), QStringLiteral("2008-05-25"))
SKGTEST(QStringLiteral("STR:dateToSqlString"), SKGServices::dateToSqlString(QStringLiteral("25-05-78"), QStringLiteral("DD-MM-YY")), QStringLiteral("1978-05-25"))
SKGTEST(QStringLiteral("STR:dateToSqlString"), SKGServices::dateToSqlString(QStringLiteral("25/05/2008"), QStringLiteral("DD/MM/YYYY")), QStringLiteral("2008-05-25"))
SKGTEST(QStringLiteral("STR:dateToSqlString"), SKGServices::dateToSqlString(QStringLiteral("25-05-2008"), QStringLiteral("DD-MM-YYYY")), QStringLiteral("2008-05-25"))
SKGTEST(QStringLiteral("STR:dateToSqlString"), SKGServices::dateToSqlString(QStringLiteral("5/25/2008"), QStringLiteral("MM/DD/YYYY")), QStringLiteral("2008-05-25"))
SKGTEST(QStringLiteral("STR:dateToSqlString"), SKGServices::dateToSqlString(QStringLiteral("5-25-2008"), QStringLiteral("MM-DD-YYYY")), QStringLiteral("2008-05-25"))
SKGTEST(QStringLiteral("STR:dateToSqlString"), SKGServices::dateToSqlString(QStringLiteral("5-6-2008"), QStringLiteral("MM-DD-YYYY")), QStringLiteral("2008-05-06"))
SKGTEST(QStringLiteral("STR:dateToSqlString"), SKGServices::dateToSqlString(QStringLiteral("5-6-8"), QStringLiteral("MM-DD-YYYY")), QStringLiteral("2008-05-06"))
SKGTEST(QStringLiteral("STR:dateToSqlString"), SKGServices::dateToSqlString(QStringLiteral("3.21.01"), QStringLiteral("MM-DD-YY")), QStringLiteral("2001-03-21"))
SKGTEST(QStringLiteral("STR:dateToSqlString"), SKGServices::dateToSqlString(QStringLiteral("1/ 1' 6"), QStringLiteral("DD-MM-YY")), QStringLiteral("2006-01-01"))
SKGTEST(QStringLiteral("STR:dateToSqlString"), SKGServices::dateToSqlString(QStringLiteral("6/ 1/94"), QStringLiteral("DD-MM-YY")), QStringLiteral("1994-01-06"))
SKGTEST(QStringLiteral("STR:dateToSqlString"), SKGServices::dateToSqlString(QStringLiteral("21/12'2001"), QStringLiteral("DD-MM-YYYY")), QStringLiteral("2001-12-21"))
SKGTEST(QStringLiteral("STR:dateToSqlString"), SKGServices::dateToSqlString(QStringLiteral("21122001"), QStringLiteral("DDMMYYYY")), QStringLiteral("2001-12-21"))
SKGTEST(QStringLiteral("STR:dateToSqlString"), SKGServices::dateToSqlString(QStringLiteral("12212001"), QStringLiteral("MMDDYYYY")), QStringLiteral("2001-12-21"))
SKGTEST(QStringLiteral("STR:dateToSqlString"), SKGServices::dateToSqlString(QStringLiteral("010203"), QStringLiteral("MMDDYY")), QStringLiteral("2003-01-02"))
SKGTEST(QStringLiteral("STR:dateToSqlString"), SKGServices::dateToSqlString(QStringLiteral("010203"), QStringLiteral("DDMMYY")), QStringLiteral("2003-02-01"))
SKGTEST(QStringLiteral("STR:dateToSqlString"), SKGServices::dateToSqlString(QStringLiteral("3/9/04"), QStringLiteral("DD-MM-YY")), QStringLiteral("2004-09-03"))
SKGTEST(QStringLiteral("STR:dateToSqlString"), SKGServices::dateToSqlString(QStringLiteral("31Dec2005"), QStringLiteral("DDMMMYYYY")), QStringLiteral("2005-12-31"))
SKGTEST(QStringLiteral("STR:dateToSqlString"), SKGServices::dateToSqlString(QStringLiteral("31-Dec-2005"), QStringLiteral("DD-MMM-YYYY")), QStringLiteral("2005-12-31"))
SKGTEST(QStringLiteral("STR:dateToSqlString"), SKGServices::dateToSqlString(QStringLiteral("31/Dec/2005"), QStringLiteral("DD/MMM/YYYY")), QStringLiteral("2005-12-31"))
SKGTEST(QStringLiteral("STR:dateToSqlString"), SKGServices::dateToSqlString(QStringLiteral("31Dec05"), QStringLiteral("DDMMMYY")), QStringLiteral("2005-12-31"))
SKGTEST(QStringLiteral("STR:dateToSqlString"), SKGServices::dateToSqlString(QStringLiteral("31-Dec-05"), QStringLiteral("DD-MMM-YY")), QStringLiteral("2005-12-31"))
SKGTEST(QStringLiteral("STR:dateToSqlString"), SKGServices::dateToSqlString(QStringLiteral("31/Dec/05"), QStringLiteral("DD/MMM/YY")), QStringLiteral("2005-12-31"))
SKGTEST(QStringLiteral("STR:dateToSqlString"), SKGServices::dateToSqlString(QStringLiteral("31DEC2005"), QStringLiteral("DDMMMYYYY")), QStringLiteral("2005-12-31"))
SKGTEST(QStringLiteral("STR:dateToSqlString"), SKGServices::dateToSqlString(QStringLiteral("INVALIDDATE"), QStringLiteral("DD-MM-YY")), SKGServices::dateToSqlString(QDateTime::currentDateTime()))
SKGTEST(QStringLiteral("STR:dateToSqlString"), SKGServices::dateToSqlString(QStringLiteral("02.01.2015"), QStringLiteral("DD-MM-YYYY")), QStringLiteral("2015-01-02"))
}
void test_nbWorkingDays(int& nberror, int& nbcheck, bool showonlyfailures)
{
SKGTEST(QStringLiteral("SKGServices::nbWorkingDays"), SKGServices::nbWorkingDays(QDate(2010, 9, 3), QDate(2010, 9, 6)), 1)
SKGTEST(QStringLiteral("SKGServices::nbWorkingDays"), SKGServices::nbWorkingDays(QDate(2010, 9, 6), QDate(2010, 9, 3)), 1)
SKGTEST(QStringLiteral("SKGServices::nbWorkingDays"), SKGServices::nbWorkingDays(QDate(2010, 9, 3), QDate(2010, 9, 3)), 1)
SKGTEST(QStringLiteral("SKGServices::nbWorkingDays"), SKGServices::nbWorkingDays(QDate(2010, 9, 1), QDate(2010, 9, 3)), 2)
SKGTEST(QStringLiteral("SKGServices::nbWorkingDays"), SKGServices::nbWorkingDays(QDate(2010, 9, 1), QDate(2010, 9, 8)), 5)
}
void test_getnext(int& nberror, int& nbcheck, bool showonlyfailures)
{
SKGTEST(QStringLiteral("SKGServices::getNextString"), SKGServices::getNextString(QStringLiteral("12345")), QStringLiteral("12346"))
SKGTEST(QStringLiteral("SKGServices::getNextString"), SKGServices::getNextString(QStringLiteral("9")), QStringLiteral("10"))
}
void test_errors(int& nberror, int& nbcheck, bool showonlyfailures)
{
{
SKGTraces::cleanProfilingStatistics();
SKGError err;
SKGTEST(QStringLiteral("ERR:Default RC"), err.getReturnCode(), 0)
SKGTEST(QStringLiteral("ERR:Default RC"), err.getReturnCode(), 0)
SKGTESTBOOL("ERR:isWarning", err.isWarning(), false)
SKGTESTBOOL("ERR:isSucceeded", err.isSucceeded(), true)
SKGTESTBOOL("ERR:isFailed", err.isFailed(), false)
SKGTESTBOOL("ERR:!", !err, true)
SKGTESTBOOL("ERR:operator bool", err, false)
SKGTESTBOOL("ERR:getPreviousError", (err.getPreviousError() == nullptr), true)
SKGTEST(QStringLiteral("ERR:Default message"), err.getMessage(), QLatin1String(""))
err.setReturnCode(10);
err.setMessage(QStringLiteral("Invalid parameter"));
SKGTEST(QStringLiteral("ERR:getHistoricalSize"), err.getHistoricalSize(), 0)
SKGTEST(QStringLiteral("ERR:RC 10"), err.getReturnCode(), 10)
SKGTEST(QStringLiteral("ERR:MSG Invalid parameter"), err.getMessage(), QStringLiteral("Invalid parameter"))
err.addError(11, QStringLiteral("Message 11"));
SKGTESTBOOL("ERR:isWarning", err.isWarning(), false)
SKGTESTBOOL("ERR:isSucceeded", err.isSucceeded(), false)
SKGTESTBOOL("ERR:isFailed", err.isFailed(), true)
SKGTESTBOOL("ERR:!", !err, false)
SKGTESTBOOL("ERR:operator bool", err, true)
SKGTEST(QStringLiteral("ERR:getHistoricalSize"), err.getHistoricalSize(), 1)
err.addError(-12, QStringLiteral("Message 12"));
SKGTESTBOOL("ERR:isWarning", err.isWarning(), true)
SKGTESTBOOL("ERR:isSucceeded", err.isSucceeded(), true)
SKGTESTBOOL("ERR:isFailed", err.isFailed(), false)
SKGTESTBOOL("ERR:!", !err, true)
SKGTESTBOOL("ERR:operator bool", err, false)
SKGTEST(QStringLiteral("ERR:getHistoricalSize"), err.getHistoricalSize(), 2)
SKGTEST(QStringLiteral("ERR:getFullMessageWithHistorical"), err.getFullMessageWithHistorical(), QStringLiteral("[WAR--12]: Message 12\n[ERR-11]: Message 11\n[ERR-10]: Invalid parameter"))
}
{
SKGTraces::cleanProfilingStatistics();
SKGError err;
err.setReturnCode(10).setMessage(QStringLiteral("Invalid parameter")).addError(11, QStringLiteral("Message 11"));
SKGTEST(QStringLiteral("ERR:getHistoricalSize"), err.getHistoricalSize(), 1)
SKGTEST(QStringLiteral("ERR:RC 10"), err.getReturnCode(), 11)
SKGTEST(QStringLiteral("ERR:MSG Message 11"), err.getMessage(), QStringLiteral("Message 11"))
}
}
void test_getDateFormat(int& nberror, int& nbcheck, bool showonlyfailures)
{
{
QStringList dates;
dates << QStringLiteral("19/08/2008");
SKGTEST(QStringLiteral("STR:getDateFormat"), SKGServices::getDateFormat(dates), QStringLiteral("DD-MM-YYYY"))
}
{
QStringList dates;
dates << QStringLiteral("20080819");
SKGTEST(QStringLiteral("STR:getDateFormat"), SKGServices::getDateFormat(dates), QStringLiteral("YYYYMMDD"))
}
{
QStringList dates;
dates << QStringLiteral("10141989");
SKGTEST(QStringLiteral("STR:getDateFormat"), SKGServices::getDateFormat(dates), QStringLiteral("MMDDYYYY"))
}
{
QStringList dates;
dates << QStringLiteral("14101989");
SKGTEST(QStringLiteral("STR:getDateFormat"), SKGServices::getDateFormat(dates), QStringLiteral("DDMMYYYY"))
}
{
QStringList dates;
dates << QStringLiteral("05/08/2008") << QStringLiteral("19/08/2008");
SKGTEST(QStringLiteral("STR:getDateFormat"), SKGServices::getDateFormat(dates), QStringLiteral("DD-MM-YYYY"))
}
{
QStringList dates;
dates << QStringLiteral("19/ 1' 6");
SKGTEST(QStringLiteral("STR:getDateFormat"), SKGServices::getDateFormat(dates), QStringLiteral("DD-MM-YYYY"))
}
{
QStringList dates;
dates << QStringLiteral("21/12'2001");
SKGTEST(QStringLiteral("STR:getDateFormat"), SKGServices::getDateFormat(dates), QStringLiteral("DD-MM-YYYY"))
}
{
QStringList dates;
dates << QStringLiteral("6/ 1/94");
SKGTEST(QStringLiteral("STR:getDateFormat"), SKGServices::getDateFormat(dates), QStringLiteral("DD-MM-YYYY"))
}
{
QStringList dates;
dates << QStringLiteral("10.29.07");
SKGTEST(QStringLiteral("STR:getDateFormat"), SKGServices::getDateFormat(dates), QStringLiteral("MM-DD-YY"))
}
{
QStringList dates;
dates << QStringLiteral("10.05.07");
SKGTEST(QStringLiteral("STR:getDateFormat"), SKGServices::getDateFormat(dates), QStringLiteral("DD-MM-YY"))
}
{
QStringList dates;
dates << QStringLiteral("2001.10.25");
SKGTEST(QStringLiteral("STR:getDateFormat"), SKGServices::getDateFormat(dates), QStringLiteral("YYYY-MM-DD"))
}
{
QStringList dates;
dates << QStringLiteral("45450116");
SKGTEST(QStringLiteral("STR:getDateFormat"), SKGServices::getDateFormat(dates), QStringLiteral("YYYYMMDD"))
}
{
QStringList dates;
dates << QStringLiteral("7/14' 0") << QStringLiteral("11/30/99");
SKGTEST(QStringLiteral("STR:getDateFormat"), SKGServices::getDateFormat(dates), QStringLiteral("MM-DD-YYYY"))
}
{
QStringList dates;
dates << QStringLiteral("10/ 8'10");
SKGTEST(QStringLiteral("STR:getDateFormat"), SKGServices::getDateFormat(dates), QStringLiteral("DD-MM-YYYY"))
}
{
QStringList dates;
dates << QStringLiteral("7/8/06");
SKGTEST(QStringLiteral("STR:getDateFormat"), SKGServices::getDateFormat(dates), QStringLiteral("DD-MM-YY"))
}
{
QStringList dates;
dates << QStringLiteral("7/8/06") << QStringLiteral("11/30/99") << QStringLiteral("7/14' 0");
SKGTEST(QStringLiteral("STR:getDateFormat"), SKGServices::getDateFormat(dates), QStringLiteral("MM-DD-YYYY"))
}
{
QStringList dates;
dates << QStringLiteral("3/9/04");
SKGTEST(QStringLiteral("STR:getDateFormat"), SKGServices::getDateFormat(dates), QStringLiteral("DD-MM-YY"))
}
{
QStringList dates;
dates << QStringLiteral("31Dec2005");
SKGTEST(QStringLiteral("STR:getDateFormat"), SKGServices::getDateFormat(dates), QStringLiteral("DDMMMYYYY"))
}
{
QStringList dates;
dates << QStringLiteral("31-Dec-05");
SKGTEST(QStringLiteral("STR:getDateFormat"), SKGServices::getDateFormat(dates), QStringLiteral("DD-MMM-YY"))
}
{
QStringList dates;
dates << QStringLiteral("2008-05-25 00:00:00");
SKGTEST(QStringLiteral("STR:getDateFormat"), SKGServices::getDateFormat(dates), QStringLiteral("YYYY-MM-DD"))
}
{
QStringList dates;
dates << QStringLiteral("2008-05-25 01:02:03");
SKGTEST(QStringLiteral("STR:getDateFormat"), SKGServices::getDateFormat(dates), QStringLiteral("YYYY-MM-DD"))
}
{
QStringList dates;
QFile inputFile(SKGTest::getTestPath(QStringLiteral("IN")) % "/dates.txt");
if (inputFile.open(QIODevice::ReadOnly)) {
QTextStream in(&inputFile);
while (!in.atEnd()) {
QString l = in.readLine().trimmed();
if (!l.isEmpty()) {
dates << l;
}
}
inputFile.close();
}
SKGTEST(QStringLiteral("STR:dats.count"), dates.count(), 2364)
SKGTEST(QStringLiteral("STR:getDateFormat"), SKGServices::getDateFormat(dates), QStringLiteral("MM-DD-YY"))
}
{
QStringList dates;
dates << QStringLiteral(" 7/8/06 ") << QLatin1String("");
SKGTEST(QStringLiteral("STR:getDateFormat"), SKGServices::getDateFormat(dates), QStringLiteral("DD-MM-YY"))
}
{
QStringList dates;
dates << QStringLiteral("99999999") << QStringLiteral("9999999999");
SKGTEST(QStringLiteral("STR:getDateFormat"), SKGServices::getDateFormat(dates), QLatin1String(""))
}
}
void test_csv(int& nberror, int& nbcheck, bool showonlyfailures)
{
SKGTEST(QStringLiteral("STR:stringToCsv"), SKGServices::stringToCsv(QStringLiteral("ABC")), QStringLiteral("\"ABC\""))
SKGTEST(QStringLiteral("STR:stringToCsv"), SKGServices::stringToCsv(QStringLiteral("ABC;CDE")), QStringLiteral("\"ABC;CDE\""))
SKGTEST(QStringLiteral("STR:stringToCsv"), SKGServices::stringToCsv(QStringLiteral("AB \"C\" DE")), QStringLiteral("\"AB \"\"C\"\" DE\""))
SKGTEST(QStringLiteral("STR:stringToCsv"), SKGServices::stringToCsv(QStringLiteral("AB \"C\";DE")), QStringLiteral("\"AB \"\"C\"\";DE\""))
QStringList parameters = SKGServices::splitCSVLine(QStringLiteral("52.33,\"9/28/2010\",52.36,231803,52.33,0.00,+0.15,-,0.00,-,0.00,0.00,0.00,0.00,\"- - -\",\"-\",-,\"n\",N/A,0,+15.82,+43.33%,9,672,-1.08,-2.02%,-,-,\"51.76 - 52.57\",0.00,0.00,N/A,N/A,N/A,N/A,\"-\",51.91,52.18,-,\"+0.29%\",N/A,N/A,\"N/A\",N/A,\"N/A\",N/A,N/A,N/A,-,N/A,\"11:35am\",N/A,211524,-,\"36.51 - 53.41\",\"- - +0.29%\",\"Paris\",N/A,\"DASSAULT SYST.\""), ',');
SKGTEST(QStringLiteral("STR:splitCSVLine count"), parameters.count(), 59)
parameters = SKGServices::splitCSVLine(QStringLiteral("2013-04-02;transfer;\"a2\";'some text 2';-20,13"), ';', true);
SKGTEST(QStringLiteral("STR:splitCSVLine count"), parameters.count(), 5)
SKGTEST(QStringLiteral("STR:splitCSVLine"), parameters[0], QStringLiteral("2013-04-02"))
SKGTEST(QStringLiteral("STR:splitCSVLine"), parameters[1], QStringLiteral("transfer"))
SKGTEST(QStringLiteral("STR:splitCSVLine"), parameters[2], QStringLiteral("a2"))
SKGTEST(QStringLiteral("STR:splitCSVLine"), parameters[3], QStringLiteral("some text 2"))
SKGTEST(QStringLiteral("STR:splitCSVLine"), parameters[4], QStringLiteral("-20,13"))
parameters = SKGServices::splitCSVLine(QStringLiteral("\"A;'B\";'A;\"B'"), ';', true);
SKGTEST(QStringLiteral("STR:splitCSVLine count"), parameters.count(), 2)
SKGTEST(QStringLiteral("STR:splitCSVLine"), parameters[0], QStringLiteral("A;'B"))
SKGTEST(QStringLiteral("STR:splitCSVLine"), parameters[1], QStringLiteral("A;\"B"))
SKGTEST(QStringLiteral("STR:stringToHtml"), SKGServices::stringToHtml(QStringLiteral("<hello>&<world>")), QStringLiteral("&lt;hello&gt;&amp;&lt;world&gt;"))
SKGTEST(QStringLiteral("STR:htmlToString"), SKGServices::htmlToString(QStringLiteral("&lt;hello&gt;&amp;&lt;world&gt;")), QStringLiteral("<hello>&<world>"))
parameters = SKGServices::splitCSVLine(SKGServices::stringToCsv(QStringLiteral("Y")) % ';' % SKGServices::stringToCsv(QStringLiteral("A;B")));
SKGTEST(QStringLiteral("STR:splitCSVLine count"), parameters.count(), 2)
SKGTEST(QStringLiteral("STR:splitCSVLine"), parameters[0], QStringLiteral("Y"))
SKGTEST(QStringLiteral("STR:splitCSVLine"), parameters[1], QStringLiteral("A;B"))
parameters = SKGServices::splitCSVLine(QStringLiteral("A;\"B;C\";D"));
SKGTEST(QStringLiteral("STR:splitCSVLine count"), parameters.count(), 3)
SKGTEST(QStringLiteral("STR:splitCSVLine"), parameters[0], QStringLiteral("A"))
SKGTEST(QStringLiteral("STR:splitCSVLine"), parameters[1], QStringLiteral("B;C"))
SKGTEST(QStringLiteral("STR:splitCSVLine"), parameters[2], QStringLiteral("D"))
parameters = SKGServices::splitCSVLine(QStringLiteral("'A';'B'"));
SKGTEST(QStringLiteral("STR:splitCSVLine count"), parameters.count(), 2)
SKGTEST(QStringLiteral("STR:splitCSVLine"), parameters[0], QStringLiteral("A"))
SKGTEST(QStringLiteral("STR:splitCSVLine"), parameters[1], QStringLiteral("B"))
parameters = SKGServices::splitCSVLine(QStringLiteral("\"A ' B\",\"C\""));
SKGTEST(QStringLiteral("STR:splitCSVLine count"), parameters.count(), 2)
SKGTEST(QStringLiteral("STR:splitCSVLine"), parameters[0], QStringLiteral("A ' B"))
SKGTEST(QStringLiteral("STR:splitCSVLine"), parameters[1], QStringLiteral("C"))
parameters = SKGServices::splitCSVLine(QStringLiteral("'A \" B','C'"));
SKGTEST(QStringLiteral("STR:splitCSVLine count"), parameters.count(), 2)
SKGTEST(QStringLiteral("STR:splitCSVLine"), parameters[0], QStringLiteral("A \" B"))
SKGTEST(QStringLiteral("STR:splitCSVLine"), parameters[1], QStringLiteral("C"))
QChar realsep;
parameters = SKGServices::splitCSVLine(QStringLiteral("\"A\",18,\"B\""), ';', true, &realsep);
SKGTEST(QStringLiteral("STR:splitCSVLine count"), parameters.count(), 3)
SKGTEST(QStringLiteral("STR:splitCSVLine"), parameters[0], QStringLiteral("A"))
SKGTEST(QStringLiteral("STR:splitCSVLine"), parameters[1], QStringLiteral("18"))
SKGTEST(QStringLiteral("STR:splitCSVLine"), parameters[2], QStringLiteral("B"))
SKGTEST(QStringLiteral("STR:sep"), realsep, ',')
parameters = SKGServices::splitCSVLine(QStringLiteral("30/05/2008;RETRAIT ESPECES AGENCE; ; 100,00;DEBIT;"));
SKGTEST(QStringLiteral("STR:splitCSVLine count"), parameters.count(), 6)
parameters = SKGServices::splitCSVLine(QStringLiteral("A|\"B\";\"C\""), '|', false);
SKGTEST(QStringLiteral("STR:splitCSVLine count"), parameters.count(), 2)
SKGTEST(QStringLiteral("STR:splitCSVLine"), parameters[0], QStringLiteral("A"))
SKGTEST(QStringLiteral("STR:splitCSVLine"), parameters[1], QStringLiteral("\"B\";\"C\""))
parameters = SKGServices::splitCSVLine(QStringLiteral("+123 \"-abc def\" \"e:f\" e:f"), ' ', true);
SKGTEST(QStringLiteral("STR:splitCSVLine count"), parameters.count(), 4)
SKGTEST(QStringLiteral("STR:splitCSVLine"), parameters[0], QStringLiteral("+123"))
SKGTEST(QStringLiteral("STR:splitCSVLine"), parameters[1], QStringLiteral("-abc def"))
SKGTEST(QStringLiteral("STR:splitCSVLine"), parameters[2], QStringLiteral("e:f"))
SKGTEST(QStringLiteral("STR:splitCSVLine"), parameters[3], QStringLiteral("e:f"))
parameters = SKGServices::splitCSVLine(QStringLiteral("A; \"B\"; \"C\" ;\"D\" ;E"), ';', true);
SKGTEST(QStringLiteral("STR:splitCSVLine count"), parameters.count(), 5)
SKGTEST(QStringLiteral("STR:splitCSVLine"), parameters[0], QStringLiteral("A"))
SKGTEST(QStringLiteral("STR:splitCSVLine"), parameters[1], QStringLiteral("B"))
SKGTEST(QStringLiteral("STR:splitCSVLine"), parameters[2], QStringLiteral("C"))
SKGTEST(QStringLiteral("STR:splitCSVLine"), parameters[3], QStringLiteral("D"))
SKGTEST(QStringLiteral("STR:splitCSVLine"), parameters[4], QStringLiteral("E"))
SKGTEST(QStringLiteral("STR:splitCSVLine words"), SKGServices::splitCSVLine(QStringLiteral("w1 w2"), ' ', true).count(), 2)
SKGTEST(QStringLiteral("STR:splitCSVLine words"), SKGServices::splitCSVLine(QStringLiteral("\"w1 w1\""), ' ', true).count(), 1)
SKGTEST(QStringLiteral("STR:splitCSVLine words"), SKGServices::splitCSVLine(QStringLiteral("\"w1 w1\" w2 \"w3 w3 w3\" w4"), ' ', true).count(), 4)
QChar realseparator;
SKGTEST(QStringLiteral("STR:splitCSVLine comma"), SKGServices::splitCSVLine(QStringLiteral("date,payee,amount"), ';', true, &realseparator).count(), 1)
SKGTEST(QStringLiteral("STR:splitCSVLine comma"), realseparator, ';')
QString t(QStringLiteral("Export Format, Date (YYYY-MM-DD as UTC), Time (HH:MM:SS), Merchant, Txn Amount (Funding Card), Txn Currency (Funding Card), Txn Amount (Foreign Spend), Txn Currency (Foreign Spend), Card Name, Card Last 4 Digits, Type, Category, Notes"));
SKGTEST(QStringLiteral("STR:splitCSVLine comma"), SKGServices::splitCSVLine(t, ';', true, &realseparator).count(), 1)
SKGTEST(QStringLiteral("STR:splitCSVLine comma"), SKGServices::splitCSVLine(t, ',', true, &realseparator).count(), 13)
}
void test_stringToSearchCriterias(int& nberror, int& nbcheck, bool showonlyfailures)
{
SKGServices::SKGSearchCriteriaList criterias = SKGServices::stringToSearchCriterias(QStringLiteral("abc +def +ghi"));
SKGTEST(QStringLiteral("STR:stringToSearchCriterias count"), criterias.count(), 3)
SKGTEST(QStringLiteral("STR:stringToSearchCriterias mode"), criterias[0].mode, '+')
SKGTEST(QStringLiteral("STR:stringToSearchCriterias words count"), criterias[0].words.count(), 1)
SKGTEST(QStringLiteral("STR:stringToSearchCriterias word"), criterias[0].words[0], QStringLiteral("ghi"))
SKGTEST(QStringLiteral("STR:stringToSearchCriterias mode"), criterias[1].mode, '+')
SKGTEST(QStringLiteral("STR:stringToSearchCriterias words count"), criterias[1].words.count(), 1)
SKGTEST(QStringLiteral("STR:stringToSearchCriterias word"), criterias[1].words[0], QStringLiteral("def"))
SKGTEST(QStringLiteral("STR:stringToSearchCriterias mode"), criterias[2].mode, '+')
SKGTEST(QStringLiteral("STR:stringToSearchCriterias words count"), criterias[2].words.count(), 1)
SKGTEST(QStringLiteral("STR:stringToSearchCriterias word"), criterias[2].words[0], QStringLiteral("abc"))
criterias = SKGServices::stringToSearchCriterias(QStringLiteral("-abc +def ghi"));
SKGTEST(QStringLiteral("STR:stringToSearchCriterias count"), criterias.count(), 2)
SKGTEST(QStringLiteral("STR:stringToSearchCriterias mode"), criterias[0].mode, '+')
SKGTEST(QStringLiteral("STR:stringToSearchCriterias words count"), criterias[0].words.count(), 2)
SKGTEST(QStringLiteral("STR:stringToSearchCriterias word"), criterias[0].words[0], QStringLiteral("def"))
SKGTEST(QStringLiteral("STR:stringToSearchCriterias word"), criterias[0].words[1], QStringLiteral("ghi"))
SKGTEST(QStringLiteral("STR:stringToSearchCriterias mode"), criterias[1].mode, '-')
SKGTEST(QStringLiteral("STR:stringToSearchCriterias words count"), criterias[1].words.count(), 1)
SKGTEST(QStringLiteral("STR:stringToSearchCriterias word"), criterias[1].words[0], QStringLiteral("abc"))
criterias = SKGServices::stringToSearchCriterias(QStringLiteral("-abc +def ghi -10"));
SKGTEST(QStringLiteral("STR:stringToSearchCriterias count"), criterias.count(), 2)
SKGTEST(QStringLiteral("STR:stringToSearchCriterias mode"), criterias[0].mode, '+')
SKGTEST(QStringLiteral("STR:stringToSearchCriterias words count"), criterias[0].words.count(), 3)
SKGTEST(QStringLiteral("STR:stringToSearchCriterias word"), criterias[0].words[0], QStringLiteral("def"))
SKGTEST(QStringLiteral("STR:stringToSearchCriterias word"), criterias[0].words[1], QStringLiteral("ghi"))
SKGTEST(QStringLiteral("STR:stringToSearchCriterias word"), criterias[0].words[2], QStringLiteral("-10"))
SKGTEST(QStringLiteral("STR:stringToSearchCriterias mode"), criterias[1].mode, '-')
SKGTEST(QStringLiteral("STR:stringToSearchCriterias words count"), criterias[1].words.count(), 1)
SKGTEST(QStringLiteral("STR:stringToSearchCriterias word"), criterias[1].words[0], QStringLiteral("abc"))
criterias = SKGServices::stringToSearchCriterias(QStringLiteral("-10"));
SKGTEST(QStringLiteral("STR:stringToSearchCriterias count"), criterias.count(), 1)
SKGTEST(QStringLiteral("STR:stringToSearchCriterias mode"), criterias[0].mode, '+')
SKGTEST(QStringLiteral("STR:stringToSearchCriterias words count"), criterias[0].words.count(), 1)
SKGTEST(QStringLiteral("STR:stringToSearchCriterias word"), criterias[0].words[0], QStringLiteral("-10"))
criterias = SKGServices::stringToSearchCriterias(QStringLiteral("-abc"));
SKGTEST(QStringLiteral("STR:stringToSearchCriterias count"), criterias.count(), 2)
SKGTEST(QStringLiteral("STR:stringToSearchCriterias mode"), criterias[0].mode, '+')
SKGTEST(QStringLiteral("STR:stringToSearchCriterias words count"), criterias[0].words.count(), 1)
SKGTEST(QStringLiteral("STR:stringToSearchCriterias word"), criterias[0].words[0], QLatin1String(""))
SKGTEST(QStringLiteral("STR:stringToSearchCriterias mode"), criterias[1].mode, '-')
SKGTEST(QStringLiteral("STR:stringToSearchCriterias words count"), criterias[1].words.count(), 1)
SKGTEST(QStringLiteral("STR:stringToSearchCriterias word"), criterias[1].words[0], QStringLiteral("abc"))
criterias = SKGServices::stringToSearchCriterias(QStringLiteral("\"abc def ghi\" \"123 456\""));
SKGTEST(QStringLiteral("STR:stringToSearchCriterias count"), criterias.count(), 1)
SKGTEST(QStringLiteral("STR:stringToSearchCriterias mode"), criterias[0].mode, '+')
SKGTEST(QStringLiteral("STR:stringToSearchCriterias words count"), criterias[0].words.count(), 2)
SKGTEST(QStringLiteral("STR:stringToSearchCriterias word"), criterias[0].words[0], QStringLiteral("abc def ghi"))
SKGTEST(QStringLiteral("STR:stringToSearchCriterias word"), criterias[0].words[1], QStringLiteral("123 456"))
criterias = SKGServices::stringToSearchCriterias(QStringLiteral("\"-payee:abc def : ghi\" +amount:25"));
SKGTEST(QStringLiteral("STR:stringToSearchCriterias count"), criterias.count(), 2)
SKGTEST(QStringLiteral("STR:stringToSearchCriterias mode"), criterias[0].mode, '+')
SKGTEST(QStringLiteral("STR:stringToSearchCriterias words count"), criterias[0].words.count(), 1)
SKGTEST(QStringLiteral("STR:stringToSearchCriterias word"), criterias[0].words[0], QStringLiteral("amount:25"))
SKGTEST(QStringLiteral("STR:stringToSearchCriterias mode"), criterias[1].mode, '-')
SKGTEST(QStringLiteral("STR:stringToSearchCriterias words count"), criterias[1].words.count(), 1)
SKGTEST(QStringLiteral("STR:stringToSearchCriterias word"), criterias[1].words[0], QStringLiteral("payee:abc def : ghi"))
SKGTEST(QStringLiteral("STR:searchCriteriasToWhereClause"),
SKGServices::searchCriteriasToWhereClause(SKGServices::stringToSearchCriterias(QStringLiteral("ToTo")),
QStringList() << QStringLiteral("d_DATEOP") << QStringLiteral("i_number") << QStringLiteral("t_PAYEE") << QStringLiteral("t_bookmarked"), nullptr),
QStringLiteral("((lower(d_DATEOP) LIKE '%toto%' OR lower(i_number) LIKE '%toto%' OR lower(t_PAYEE) LIKE '%toto%' OR lower(t_bookmarked) LIKE '%toto%'))"));
SKGTEST(QStringLiteral("STR:searchCriteriasToWhereClause"),
SKGServices::searchCriteriasToWhereClause(SKGServices::stringToSearchCriterias(QStringLiteral("i_num:ToTo")),
QStringList() << QStringLiteral("d_DATEOP") << QStringLiteral("i_number") << QStringLiteral("t_PAYEE") << QStringLiteral("t_bookmarked"), nullptr),
QStringLiteral("((lower(i_number) LIKE '%toto%'))"));
SKGTEST(QStringLiteral("STR:searchCriteriasToWhereClause"),
SKGServices::searchCriteriasToWhereClause(SKGServices::stringToSearchCriterias(QStringLiteral("i_num=1234")),
QStringList() << QStringLiteral("d_DATEOP") << QStringLiteral("i_number") << QStringLiteral("t_PAYEE") << QStringLiteral("t_bookmarked"), nullptr),
QStringLiteral("((i_number=1234))"));
SKGTEST(QStringLiteral("STR:searchCriteriasToWhereClause"),
SKGServices::searchCriteriasToWhereClause(SKGServices::stringToSearchCriterias(QStringLiteral("t_PAYEE>ToTo")),
QStringList() << QStringLiteral("d_DATEOP") << QStringLiteral("i_number") << QStringLiteral("t_PAYEE") << QStringLiteral("t_bookmarked"), nullptr),
QStringLiteral("((lower(t_PAYEE)>'toto'))"));
SKGTEST(QStringLiteral("STR:searchCriteriasToWhereClause"),
SKGServices::searchCriteriasToWhereClause(SKGServices::stringToSearchCriterias(QStringLiteral("t_PAYEE<ToTo")),
QStringList() << QStringLiteral("d_DATEOP") << QStringLiteral("i_number") << QStringLiteral("t_PAYEE") << QStringLiteral("t_bookmarked"), nullptr),
QStringLiteral("((lower(t_PAYEE)<'toto'))"));
SKGTEST(QStringLiteral("STR:searchCriteriasToWhereClause"),
SKGServices::searchCriteriasToWhereClause(SKGServices::stringToSearchCriterias(QStringLiteral("t_PAYEE>=ToTo")),
QStringList() << QStringLiteral("d_DATEOP") << QStringLiteral("i_number") << QStringLiteral("t_PAYEE") << QStringLiteral("t_bookmarked"), nullptr),
QStringLiteral("((lower(t_PAYEE)>='toto'))"));
SKGTEST(QStringLiteral("STR:searchCriteriasToWhereClause"),
SKGServices::searchCriteriasToWhereClause(SKGServices::stringToSearchCriterias(QStringLiteral("t_PAYEE<=ToTo")),
QStringList() << QStringLiteral("d_DATEOP") << QStringLiteral("i_number") << QStringLiteral("t_PAYEE") << QStringLiteral("t_bookmarked"), nullptr),
QStringLiteral("((lower(t_PAYEE)<='toto'))"));
SKGTEST(QStringLiteral("STR:searchCriteriasToWhereClause"),
SKGServices::searchCriteriasToWhereClause(SKGServices::stringToSearchCriterias(QStringLiteral("t_PAYEE=ToTo")),
QStringList() << QStringLiteral("d_DATEOP") << QStringLiteral("i_number") << QStringLiteral("t_PAYEE") << QStringLiteral("t_bookmarked"), nullptr),
QStringLiteral("((lower(t_PAYEE)='toto'))"));
SKGTEST(QStringLiteral("STR:searchCriteriasToWhereClause"),
SKGServices::searchCriteriasToWhereClause(SKGServices::stringToSearchCriterias(QStringLiteral("t_PAYEE#^t[o|a]to$")),
QStringList() << QStringLiteral("d_DATEOP") << QStringLiteral("i_number") << QStringLiteral("t_PAYEE") << QStringLiteral("t_bookmarked"), nullptr),
QStringLiteral("((REGEXP('^t[o|a]to$',t_PAYEE)))"));
SKGTEST(QStringLiteral("STR:searchCriteriasToWhereClause"),
SKGServices::searchCriteriasToWhereClause(SKGServices::stringToSearchCriterias(QStringLiteral("+i_number<20 +i_number>30")),
QStringList() << QStringLiteral("d_DATEOP") << QStringLiteral("i_number") << QStringLiteral("t_PAYEE") << QStringLiteral("t_bookmarked"), nullptr),
QStringLiteral("((i_number>30)) OR ((i_number<20))"));
SKGTEST(QStringLiteral("STR:searchCriteriasToWhereClause"),
SKGServices::searchCriteriasToWhereClause(SKGServices::stringToSearchCriterias(QStringLiteral("d_DATEOP>2015-05-04")),
QStringList() << QStringLiteral("d_DATEOP") << QStringLiteral("i_number") << QStringLiteral("t_PAYEE") << QStringLiteral("t_bookmarked"), nullptr),
QStringLiteral("((lower(d_DATEOP)>'2015-05-04'))"));
SKGTEST(QStringLiteral("STR:searchCriteriasToWhereClause"),
SKGServices::searchCriteriasToWhereClause(SKGServices::stringToSearchCriterias(QStringLiteral("notfound:ToTo")),
QStringList() << QStringLiteral("d_DATEOP") << QStringLiteral("i_number") << QStringLiteral("t_PAYEE") << QStringLiteral("t_bookmarked"), nullptr),
QStringLiteral("(1=0)"));
SKGTEST(QStringLiteral("STR:searchCriteriasToWhereClause"),
SKGServices::searchCriteriasToWhereClause(SKGServices::stringToSearchCriterias(QStringLiteral("v1 v2 +v3 -v4 -v5")),
QStringList() << QStringLiteral("t_comment"), nullptr),
QStringLiteral("((lower(t_comment) LIKE '%v3%')) OR ((lower(t_comment) LIKE '%v1%') AND (lower(t_comment) LIKE '%v2%')) AND NOT((lower(t_comment) LIKE '%v4%')) AND NOT((lower(t_comment) LIKE '%v5%'))"));
SKGTEST(QStringLiteral("STR:searchCriteriasToWhereClause"),
SKGServices::searchCriteriasToWhereClause(SKGServices::stringToSearchCriterias(QStringLiteral("v1 v2 +v3 -v4 -v5")),
QStringList() << QStringLiteral("t_comment"), nullptr, true),
QStringLiteral("(((t_comment:v3) and ((t_comment:v1) and (t_comment:v2))) and not (t_comment:v4)) and not (t_comment:v5)"));
SKGTEST(QStringLiteral("STR:searchCriteriasToWhereClause"),
SKGServices::searchCriteriasToWhereClause(SKGServices::stringToSearchCriterias(QStringLiteral("-v5")),
QStringList() << QStringLiteral("t_comment"), nullptr),
QStringLiteral("((lower(t_comment) LIKE '%%')) AND NOT((lower(t_comment) LIKE '%v5%'))"));
SKGTEST(QStringLiteral("STR:searchCriteriasToWhereClause"),
SKGServices::searchCriteriasToWhereClause(SKGServices::stringToSearchCriterias(QStringLiteral("a'b")),
QStringList() << QStringLiteral("t_comment"), nullptr),
QStringLiteral("((lower(t_comment) LIKE '%a''b%'))"));
SKGTEST(QStringLiteral("STR:searchCriteriasToWhereClause"),
SKGServices::searchCriteriasToWhereClause(SKGServices::stringToSearchCriterias(QStringLiteral("-v5")),
QStringList() << QStringLiteral("t_comment"), nullptr, true),
QStringLiteral("(t_comment:) and not (t_comment:v5)"));
SKGTEST(QStringLiteral("STR:searchCriteriasToWhereClause"),
SKGServices::searchCriteriasToWhereClause(SKGServices::stringToSearchCriterias(QStringLiteral(":ToTo")),
QStringList() << QStringLiteral("p_prop1") << QStringLiteral("p_prop2"), nullptr),
QStringLiteral("((i_PROPPNAME='prop1' AND (lower(i_PROPVALUE) LIKE '%toto%') OR i_PROPPNAME='prop2' AND (lower(i_PROPVALUE) LIKE '%toto%')))"));
SKGTEST(QStringLiteral("STR:searchCriteriasToWhereClause"),
SKGServices::searchCriteriasToWhereClause(SKGServices::stringToSearchCriterias(QStringLiteral(":ToTo")),
QStringList() << QStringLiteral("p_prop1") << QStringLiteral("p_prop2"), nullptr, true),
QStringLiteral("p_prop1:toto or p_prop2:toto"));
SKGTEST(QStringLiteral("STR:searchCriteriasToWhereClause"),
SKGServices::searchCriteriasToWhereClause(SKGServices::stringToSearchCriterias(QStringLiteral("#ToTo")),
QStringList() << QStringLiteral("p_prop1") << QStringLiteral("p_prop2"), nullptr),
QStringLiteral("((i_PROPPNAME='prop1' AND REGEXP('toto',i_PROPVALUE) OR i_PROPPNAME='prop2' AND REGEXP('toto',i_PROPVALUE)))"));
SKGTEST(QStringLiteral("STR:searchCriteriasToWhereClause"),
SKGServices::searchCriteriasToWhereClause(SKGServices::stringToSearchCriterias(QStringLiteral("t_att>10")),
QStringList() << QStringLiteral("t_att") << QStringLiteral("t_att1"), nullptr),
QStringLiteral("((lower(t_att)>'10' OR lower(t_att1)>'10'))"));
SKGTEST(QStringLiteral("STR:searchCriteriasToWhereClause"),
SKGServices::searchCriteriasToWhereClause(SKGServices::stringToSearchCriterias(QStringLiteral("t_att.>10")),
QStringList() << QStringLiteral("t_att") << QStringLiteral("t_att1"), nullptr),
QStringLiteral("((lower(t_att)>'10'))"));
SKGTEST(QStringLiteral("STR:searchCriteriasToWhereClause"),
SKGServices::searchCriteriasToWhereClause(SKGServices::stringToSearchCriterias(QStringLiteral("t_att.>10")),
QStringList() << QStringLiteral("t_att") << QStringLiteral("t_att1"), nullptr, true),
QStringLiteral("t_att>10"));
}
int main(int argc, char** argv)
{
Q_UNUSED(argc)
Q_UNUSED(argv)
// Init test
SKGINITTEST(true)
// Test class SKGError
test_errors(nberror, nbcheck, showonlyfailures);
// SKGServices
{
test_getPeriodWhereClause(nberror, nbcheck, showonlyfailures);
test_getNeighboringPeriod(nberror, nbcheck, showonlyfailures);
test_periodToDate(nberror, nbcheck, showonlyfailures);
test_partialStringToDate(nberror, nbcheck, showonlyfailures);
test_conversions(nberror, nbcheck, showonlyfailures);
test_nbWorkingDays(nberror, nbcheck, showonlyfailures);
test_getDateFormat(nberror, nbcheck, showonlyfailures);
test_csv(nberror, nbcheck, showonlyfailures);
test_stringToSearchCriterias(nberror, nbcheck, showonlyfailures);
test_getnext(nberror, nbcheck, showonlyfailures);
// Various test
SKGStringListList table;
table.push_back(QStringList() << QStringLiteral("Person") << QStringLiteral("Salary") << QStringLiteral("Age"));
table.push_back(QStringList() << QStringLiteral("John") << QStringLiteral("58000") << QStringLiteral("33"));
table.push_back(QStringList() << QStringLiteral("Paul") << QStringLiteral("42000") << QStringLiteral("25"));
table.push_back(QStringList() << QStringLiteral("Alan") << QStringLiteral("65000") << QStringLiteral("41"));
SKGServices::getBase100Table(table);
SKGServices::getPercentTable(table, true, false);
SKGServices::getPercentTable(table, false, true);
SKGServices::getHistorizedTable(table);
SKGTEST(QStringLiteral("STR:encodeForUrl"), SKGServices::encodeForUrl(QStringLiteral("abc")), QStringLiteral("abc"))
SKGTEST(QStringLiteral("STR:getMajorVersion"), SKGServices::getMajorVersion(QStringLiteral("4.3.12.3")), QStringLiteral("4.3"))
SKGTEST(QStringLiteral("STR:getMajorVersion"), SKGServices::getMajorVersion(QStringLiteral("4.3.12")), QStringLiteral("4.3"))
SKGTEST(QStringLiteral("STR:getMajorVersion"), SKGServices::getMajorVersion(QStringLiteral("4.3")), QStringLiteral("4.3"))
SKGTEST(QStringLiteral("STR:getMajorVersion"), SKGServices::getMajorVersion(QStringLiteral("4")), QStringLiteral("4"))
SKGTEST(QStringLiteral("STR:toCurrencyString"), SKGServices::toCurrencyString(5.12341234, QStringLiteral("F"), 2).remove(' '), QStringLiteral("5.12F"))
SKGTEST(QStringLiteral("STR:toCurrencyString"), SKGServices::toCurrencyString(-5.12341234, QStringLiteral("F"), 4).remove(' '), QStringLiteral("-5.1234F"))
SKGTEST(QStringLiteral("STR:toPercentageString"), SKGServices::toPercentageString(5.12341234, 2), QStringLiteral("5.12 %"))
SKGTEST(QStringLiteral("STR:toPercentageString"), SKGServices::toPercentageString(5.12341234, 4), QStringLiteral("5.1234 %"))
QByteArray tmp;
SKGTESTERROR(QStringLiteral("STR:downloadToStream"), SKGServices::downloadToStream(QUrl::fromLocalFile(QStringLiteral("notfound")), tmp), false)
SKGTEST(QStringLiteral("STR:getFullPathCommandLine"), SKGServices::getFullPathCommandLine(QStringLiteral("skrooge-release.py --help")), QStringLiteral("skrooge-release.py --help"))
}
// End test
SKGENDTEST()
}
diff --git a/tests/skgbasemodelertest/skgtestfile.cpp b/tests/skgbasemodelertest/skgtestfile.cpp
index 517f8ba38..4e23b7d77 100644
--- a/tests/skgbasemodelertest/skgtestfile.cpp
+++ b/tests/skgbasemodelertest/skgtestfile.cpp
@@ -1,207 +1,207 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is a test script.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include <qfile.h>
#include <qsqldatabase.h>
#include "skgtestmacro.h"
/**
* The main function of the unit test
* @param argc the number of arguments
* @param argv the list of arguments
*/
int main(int argc, char** argv)
{
Q_UNUSED(argc)
Q_UNUSED(argv)
// Init test
SKGINITTEST(true) {
SKGTESTBOOL("QSQLITE:isDriverAvailable", QSqlDatabase::isDriverAvailable(QStringLiteral("QSQLITE")), true)
SKGTESTBOOL("SKGSQLCIPHER:isDriverAvailable", QSqlDatabase::isDriverAvailable(QStringLiteral("SKGSQLCIPHER")), true)
}
{
// test class SKGDocument / LOAD / SAVE
QString filename1 = SKGTest::getTestPath(QStringLiteral("IN")) % QStringLiteral("/filename1_e.skg");
qDebug("filename1=%s", filename1.toUtf8().constData());
{
SKGDocument document1;
QFile(filename1).remove();
SKGTESTERROR(QStringLiteral("DOC:initialize"), document1.initialize(), true)
SKGTESTERROR(QStringLiteral("DOC:setLanguage"), document1.setLanguage(QStringLiteral("en")), true)
SKGTESTERROR(QStringLiteral("DOC:setLanguage"), document1.setLanguage(QStringLiteral("fr")), true)
SKGTESTBOOL("DOC:isFileModified", document1.isFileModified(), false)
SKGTESTERROR(QStringLiteral("DOC:beginTransaction"), document1.beginTransaction(QStringLiteral("tt")), true)
SKGTESTERROR(QStringLiteral("DOC:setParameter"), document1.setParameter(QStringLiteral("ATT3"), QStringLiteral("VAL3")), true)
SKGTESTBOOL("DOC:isFileModified", document1.isFileModified(), true)
SKGTESTERROR(QStringLiteral("DOC:endTransaction"), document1.endTransaction(false), true)
SKGTESTBOOL("DOC:isFileModified", document1.isFileModified(), false)
SKGTESTERROR(QStringLiteral("DOC:beginTransaction"), document1.beginTransaction(QStringLiteral("tt")), true)
SKGTESTERROR(QStringLiteral("DOC:setParameter"), document1.setParameter(QStringLiteral("ATT3"), QStringLiteral("VAL3")), true)
SKGTESTBOOL("DOC:isFileModified", document1.isFileModified(), true)
SKGTESTERROR(QStringLiteral("DOC:endTransaction"), document1.endTransaction(true), true)
SKGTESTBOOL("DOC:isFileModified", document1.isFileModified(), true)
document1.setFileNotModified();
SKGTESTBOOL("DOC:isFileModified", document1.isFileModified(), false)
SKGTEST(QStringLiteral("DOC:getDisplay"), document1.getDisplay(QStringLiteral("t_name")), QStringLiteral("Name"))
SKGTEST(QStringLiteral("DOC:getDisplay"), document1.getDisplay(QStringLiteral("node.t_name")), QStringLiteral("Name"))
SKGTEST(QStringLiteral("DOC:getDisplay"), document1.getDisplay(QStringLiteral("v_node.t_name")), QStringLiteral("Name"))
SKGTEST(QStringLiteral("DOC:getDisplay"), document1.getDisplay(QStringLiteral("v_node.unknown")), QStringLiteral("v_node.unknown"))
QString oResult;
SKGTESTERROR(QStringLiteral("DOC:isFileModified"), document1.dumpSelectSqliteOrder(QStringLiteral("select * from parameters"), oResult), true)
}
{
SKGDocument document1;
QFile(filename1).remove();
SKGTESTERROR(QStringLiteral("DOC:initialize"), document1.initialize(), true)
SKGTESTBOOL("DOC:isFileModified", document1.isFileModified(), false)
SKGTESTERROR(QStringLiteral("DOC:beginTransaction"), document1.beginTransaction(QStringLiteral("tt")), true)
SKGTESTERROR(QStringLiteral("DOC:endTransaction"), document1.endTransaction(true), true)
SKGTESTBOOL("DOC:isFileModified", document1.isFileModified(), false) // because the transaction is empty
}
{
SKGDocument document1;
QFile(filename1).remove();
SKGTESTERROR(QStringLiteral("DOC:load"), document1.load(filename1, QLatin1String("")), false)
SKGTESTERROR(QStringLiteral("DOC:saveAs+invalid path"), document1.saveAs(QStringLiteral("/notfound/file.skg"), true), false)
SKGTEST(QStringLiteral("DOC:getCurrentFileName"), document1.getCurrentFileName(), QLatin1String(""))
SKGTESTBOOL("DOC:isFileModified", document1.isFileModified(), false)
SKGTESTERROR(QStringLiteral("DOC:initialize"), document1.initialize(), true)
SKGTESTBOOL("DOC:isFileModified", document1.isFileModified(), false)
SKGTESTERROR(QStringLiteral("DOC:beginTransaction"), document1.beginTransaction(QStringLiteral("t1")), true)
SKGTEST(QStringLiteral("DOC:getCurrentFileName"), document1.getCurrentFileName(), QLatin1String(""))
SKGTESTERROR(QStringLiteral("DOC:save"), document1.save(), false)
SKGTEST(QStringLiteral("DOC:getCurrentFileName"), document1.getCurrentFileName(), QLatin1String(""))
SKGTESTBOOL("DOC:isFileModified", document1.isFileModified(), true) // due to the beginTransaction
SKGTEST(QStringLiteral("DOC:getParameter"), document1.getParameter(QStringLiteral("ATT1")), QLatin1String(""))
SKGTESTERROR(QStringLiteral("DOC:setParameter"), document1.setParameter(QStringLiteral("ATT1"), QStringLiteral("VAL1")), true)
SKGTESTBOOL("DOC:isFileModified", document1.isFileModified(), true)
SKGTEST(QStringLiteral("DOC:getParameter"), document1.getParameter(QStringLiteral("ATT1")), QStringLiteral("VAL1"))
SKGTESTERROR(QStringLiteral("DOC:endTransaction"), document1.endTransaction(true), true)
SKGTESTERROR(QStringLiteral("DOC:saveAs+overwrite=false"), document1.saveAs(filename1, false), true)
SKGTESTBOOL("DOC:exist", QFile(filename1).exists(), true)
SKGTEST(QStringLiteral("DOC:getCurrentFileName"), document1.getCurrentFileName(), filename1)
SKGTESTERROR(QStringLiteral("DOC:saveAs+overwrite=false"), document1.saveAs(filename1, false), false)
SKGTESTBOOL("DOC:exist", QFile(filename1).exists(), true)
SKGTEST(QStringLiteral("DOC:getCurrentFileName"), document1.getCurrentFileName(), filename1)
SKGTESTERROR(QStringLiteral("DOC:save"), document1.save(), true)
SKGTESTBOOL("DOC:exist", QFile(filename1).exists(), true)
SKGTEST(QStringLiteral("DOC:getCurrentFileName"), document1.getCurrentFileName(), filename1)
SKGTESTERROR(QStringLiteral("DOC:beginTransaction"), document1.beginTransaction(QStringLiteral("t1")), true)
SKGTESTBOOL("DOC:isFileModified", document1.isFileModified(), true) // due to the beginTransaction
SKGTEST(QStringLiteral("DOC:getParameter"), document1.getParameter(QStringLiteral("ATT1")), QStringLiteral("VAL1"))
SKGTESTERROR(QStringLiteral("DOC:setParameter"), document1.setParameter(QStringLiteral("ATT1"), QStringLiteral("VAL2")), true)
SKGTEST(QStringLiteral("DOC:getParameter"), document1.getParameter(QStringLiteral("ATT1")), QStringLiteral("VAL2"))
SKGTESTBOOL("DOC:isFileModified", document1.isFileModified(), true)
SKGTESTERROR(QStringLiteral("DOC:endTransaction"), document1.endTransaction(true), true)
SKGTESTBOOL("DOC:exist", QFile(filename1).exists(), true)
SKGTESTERROR(QStringLiteral("DOC:load"), document1.load(filename1, QLatin1String("")), true)
SKGTESTBOOL("DOC:isFileModified", document1.isFileModified(), false)
SKGTESTBOOL("DOC:getCurrentFileName", (!document1.getCurrentFileName().isEmpty()), true)
SKGTEST(QStringLiteral("DOC:getParameter"), document1.getParameter(QStringLiteral("ATT1")), QStringLiteral("VAL1"))
}
{
SKGDocument document1;
SKGTESTERROR(QStringLiteral("DOC:load"), document1.load(filename1, QLatin1String("")), true)
SKGTESTERROR(QStringLiteral("DOC:beginTransaction"), document1.beginTransaction(QStringLiteral("t3")), true)
SKGTESTERROR(QStringLiteral("DOC:setParameter"), document1.setParameter(QStringLiteral("ATT3"), QStringLiteral("VAL3")), true)
SKGTESTERROR(QStringLiteral("DOC:endTransaction"), document1.endTransaction(true), true)
SKGTESTERROR(QStringLiteral("DOC:save"), document1.save(), true)
SKGTESTERROR(QStringLiteral("DOC:changePassword"), document1.changePassword(QStringLiteral("pwd1")), true)
SKGTESTERROR(QStringLiteral("DOC:changePassword"), document1.changePassword(QStringLiteral("pwd")), true)
SKGTESTERROR(QStringLiteral("DOC:beginTransaction"), document1.beginTransaction(QStringLiteral("tt")), true)
SKGTESTERROR(QStringLiteral("DOC:setParameter"), document1.setParameter(QStringLiteral("SAVE"), QStringLiteral("1")), true)
SKGTESTERROR(QStringLiteral("DOC:endTransaction"), document1.endTransaction(true), true)
SKGTEST(QStringLiteral("DOC:getParameter"), document1.getParameter(QStringLiteral("SAVE")), QStringLiteral("1"))
SKGTESTERROR(QStringLiteral("DOC:save"), document1.save(), true)
}
{
SKGDocument document1;
SKGTESTERROR(QStringLiteral("DOC:load"), document1.load(filename1, QLatin1String("")), false)
SKGTEST(QStringLiteral("DOC:load"), document1.load(filename1, QStringLiteral("wrong pwd")).getReturnCode(), ERR_ENCRYPTION)
}
{
SKGDocument document1;
SKGTESTERROR(QStringLiteral("DOC:load"), document1.load(filename1, QStringLiteral("pwd")), true)
SKGTESTERROR(QStringLiteral("DOC:changePassword"), document1.changePassword(QStringLiteral("pwd1")), true)
SKGTESTERROR(QStringLiteral("DOC:changePassword"), document1.changePassword(QLatin1String("")), true)
SKGTESTERROR(QStringLiteral("DOC:save"), document1.save(), true)
SKGTESTERROR(QStringLiteral("DOC:load"), document1.load(filename1, QLatin1String("")), true)
}
{
SKGDocument document1;
QFile(filename1).remove();
SKGTESTERROR(QStringLiteral("DOC:initialize"), document1.initialize(), true)
document1.setBackupParameters(QLatin1String(""), QStringLiteral("/invalid suffix"));
SKGTESTERROR(QStringLiteral("DOC:saveAs"), document1.saveAs(filename1, true), true)
SKGTESTERROR(QStringLiteral("DOC:saveAs"), document1.saveAs(filename1, true), true)
document1.setBackupParameters(QStringLiteral("."), QStringLiteral(".old"));
SKGTEST(QStringLiteral("DOC:getBackupFile"), document1.getBackupFile(QStringLiteral("/tmp/file.skg")), QStringLiteral("/tmp/.file.skg.old"))
document1.setBackupParameters(QLatin1String(""), QStringLiteral("_<DATE>.backup"));
SKGTEST(QStringLiteral("DOC:getBackupFile"), document1.getBackupFile(QStringLiteral("/tmp/file.skg")), QStringLiteral("/tmp/file.skg_") % SKGServices::dateToSqlString(QDateTime::currentDateTime().date()) % ".backup")
document1.setBackupParameters(QLatin1String(""), QStringLiteral("_<DATE>.skg"));
SKGTEST(QStringLiteral("DOC:getBackupFile"), document1.getBackupFile(QStringLiteral("/tmp/file.skg")), QStringLiteral("/tmp/file_") % SKGServices::dateToSqlString(QDateTime::currentDateTime().date()) % ".skg")
document1.setBackupParameters(QLatin1String(""), QStringLiteral("_<TIME>.backup"));
SKGTEST(QStringLiteral("DOC:getBackupFile"), document1.getBackupFile(QStringLiteral("/tmp/file.skg")), QStringLiteral("/tmp/file.skg_") % SKGServices::timeToString(QDateTime::currentDateTime()) % ".backup")
document1.setBackupParameters(QStringLiteral("/tmp/"), QStringLiteral(".old"));
SKGTEST(QStringLiteral("DOC:getBackupFile"), document1.getBackupFile(QStringLiteral("/home/user1/file.skg")), QStringLiteral("/tmp/file.skg.old"))
}
{
SKGDocument document1;
SKGTESTERROR(QStringLiteral("DOC:load"), document1.load(filename1, QLatin1String("")), true)
SKGTESTERROR(QStringLiteral("DOC:beginTransaction"), document1.beginTransaction(QStringLiteral("tt")), true)
SKGTESTERROR(QStringLiteral("DOC:setParameter"), document1.setParameter(QStringLiteral("SAVE"), QStringLiteral("1")), true)
SKGTEST(QStringLiteral("DOC:getParameter"), document1.getParameter(QStringLiteral("SAVE")), QStringLiteral("1"))
SKGTESTERROR(QStringLiteral("DOC:endTransaction"), document1.endTransaction(true), true)
SKGTESTERROR(QStringLiteral("DOC:save"), document1.save(), true)
// Check save when file system is full
qputenv("SKGFILESYSTEMFULL", "Y");
SKGTEST(QStringLiteral("DOC:getParameter"), static_cast<unsigned int>(QFile(filename1).exists()), static_cast<unsigned int>(true))
SKGTESTERROR(QStringLiteral("DOC:save"), document1.save(), false)
SKGTEST(QStringLiteral("DOC:getParameter"), static_cast<unsigned int>(QFile(filename1).exists()), static_cast<unsigned int>(true))
}
QFile(filename1).remove();
QFile(filename1 % ".old").remove();
}
// End test
SKGENDTEST()
}
diff --git a/tests/skgbasemodelertest/skgtestmacro.h b/tests/skgbasemodelertest/skgtestmacro.h
index 7f9f0f216..369a68efd 100644
--- a/tests/skgbasemodelertest/skgtestmacro.h
+++ b/tests/skgbasemodelertest/skgtestmacro.h
@@ -1,250 +1,250 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef SKGTESTMACRO_H
#define SKGTESTMACRO_H
/** @file
* This file contains macro for unit tests.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include <qcoreapplication.h>
#include <qdir.h>
#include <qfile.h>
#include <kaboutdata.h>
#include "skgdocument.h"
#include "skgerror.h"
#include "skgnodeobject.h"
#include "skgpropertyobject.h"
#include "skgservices.h"
#include "skgtraces.h"
#include "skgtransactionmng.h"
class SKGTest
{
public:
/**
* Return the test directory
* @param iPath can be IN or OUT or REF
* @return the test directory
*/
static QString getTestPath(const QString& iPath)
{
QString pPath = SKGServices::getEnvVariable(iPath);
if (pPath.isEmpty()) {
return QStringLiteral("./tests/") % (iPath == QStringLiteral("IN") ? "input" : (iPath == QStringLiteral("OUT") ? "output" : "ref"));
}
return pPath;
}
};
/**
* @def SKGINITTEST(SHOWERRONLY)
* Initialise the test
*/
#ifndef Q_OS_WIN
#define SKGINITTEST(SHOWERRONLY) \
QCoreApplication app(argc, argv); \
app.setApplicationName(QStringLiteral("qttest") ); \
KAboutData::setApplicationData(KAboutData(QStringLiteral("qttest"), QStringLiteral("qttest"), QStringLiteral("1.0"))); \
SKGTRACESEPARATOR; \
SKGTRACE << "STARTING TEST" << endl << flush; \
SKGTRACE << "homePath=" << QDir::homePath() << endl << flush; \
SKGTRACESEPARATOR; \
bool showonlyfailures = SHOWERRONLY; \
if (showonlyfailures) {SKGTRACE << "Only failures will be displayed" << endl;}\
int nberror = 0; \
int nbcheck = 0;
#else
#define SKGINITTEST(SHOWERRONLY) \
QCoreApplication app(argc, argv); \
app.setApplicationName(QStringLiteral("qttest")); \
KAboutData::setApplicationData(KAboutData(QStringLiteral("qttest"), QStringLiteral("qttest"), QStringLiteral("1.0"))); \
SKGTRACESEPARATOR; \
SKGTRACE << "STARTING TEST" << endl << flush; \
SKGTRACE << "homePath=" << QDir::homePath() << endl << flush; \
SKGTRACESEPARATOR; \
bool showonlyfailures = SHOWERRONLY; \
if (showonlyfailures) {SKGTRACE << "Only failures will be displayed" << endl;}\
int nberror = 0; \
int nbcheck = 0;
#endif
/*
*/
/**
* @def SKGENDTEST()
* Exit test
*/
#define SKGENDTEST()\
if (nbcheck > 0) \
{ \
SKGTRACE << nberror << " errors / " << nbcheck << " checks =" << (100.0*(static_cast<double>(nberror)) / (static_cast<double>(nbcheck))) << "%" << endl;\
} \
SKGTraces::dumpProfilingStatistics();\
return nberror;
/**
* @def SKGRETURNTEST()
* Return test
*/
#define SKGRETURNTEST()\
if (nbcheck > 0) \
{ \
SKGTRACE << nberror << " errors / " << nbcheck << " checks =" << (100.0*(static_cast<double>(nberror)) / (static_cast<double>(nbcheck))) << "%" << endl;\
} \
return nberror;
/**
* @def SKGTEST(MESSAGE, RESULT, EXPECTEDRESULT)
* To check the return of a method
* Example of usage:
* @code
* SKGTEST(QStringLiteral("ERR:getHistoricalSize"), err.getHistoricalSize(), 0)
* @endcode
*/
#define SKGTEST(MESSAGE, RESULT, EXPECTEDRESULT) \
if ((RESULT) == (EXPECTEDRESULT))\
{\
if (!showonlyfailures) {SKGTRACE << "Test [" << (MESSAGE) << "] : OK" << endl;}\
}\
else\
{\
SKGTRACE << "!!! Test [" << (MESSAGE) << "] : KO in line " << __LINE__ << endl;\
SKGTRACE << " Expected: [" << (EXPECTEDRESULT) << ']' << endl;\
SKGTRACE << " Result : [" << (RESULT) << ']' << endl;\
++nberror;\
}\
++nbcheck;
/**
* @def SKGTESTBOOL(MESSAGE, RESULT, EXPECTEDRESULT)
* To check the return of a method returning a boll
* Example of usage:
* @code
* SKGTESTBOOL("isWarning", err.isWarning(), true)
* @endcode
*/
#define SKGTESTBOOL(MESSAGE, RESULT, EXPECTEDRESULT) \
if ((RESULT) == (EXPECTEDRESULT))\
{\
if (!showonlyfailures) {SKGTRACE << "Test [" << (MESSAGE) << "] : OK" << endl;}\
}\
else\
{\
SKGTRACE << "!!! Test [" << (MESSAGE) << "] : KO in line " << __LINE__ << endl;\
SKGTRACE << " Expected: [" << ((EXPECTEDRESULT) ? "TRUE" : "FALSE") << ']' << endl;\
SKGTRACE << " Result : [" << ((RESULT) ? "TRUE" : "FALSE") << ']' << endl;\
++nberror;\
}\
++nbcheck;
/**
* @def SKGTESTERROR(MESSAGE, RESULT, EXPECTEDRESULT)
* To check the return of a method
* Example of usage:
* @code
* SKGTESTERROR(QStringLiteral("DOC:setParameter"), document1.setParameter(QStringLiteral("ATT1"), QStringLiteral("VAL1")), true)
* @endcode
*/
#define SKGTESTERROR(MESSAGE, RESULT, EXPECTEDRESULT) \
{ \
SKGError _err_ = RESULT; \
if (!_err_ == (EXPECTEDRESULT)) { \
if (!showonlyfailures) { \
SKGTRACE << "Test [" << (MESSAGE) << "] : OK" << endl; \
if (!(EXPECTEDRESULT)) { \
SKGTRACE << " Error Message :\n" << _err_.getFullMessageWithHistorical() << endl; \
} \
}\
} else {\
SKGTRACE << "!!! Test [" << (MESSAGE) << "] : KO in line " << __LINE__ << endl;\
SKGTRACE << " Expected: [" << ((EXPECTEDRESULT) ? "TRUE" : "FALSE") << ']' << endl;\
SKGTRACE << " Result : [" << (!_err_ ? "TRUE" : "FALSE") << ']' << endl;\
SKGTRACE << " Error Message :\n" << _err_.getFullMessageWithHistorical() << endl;\
++nberror;\
}\
++nbcheck;\
}
/**
* @def SKGTESTACCOUNT(DOC, ACCOUNT, AMOUNT)
* To check the account amount
* Example of usage:
* @code
* SKGTESTACCOUNT(document1, QStringLiteral("act1"), 12345);
* @endcode
*/
#define SKGTESTACCOUNT(DOC, ACCOUNT, AMOUNT) \
{ \
SKGAccountObject account(&(DOC)); \
SKGTESTERROR((ACCOUNT) % ".setName(QStringLiteral(" % (ACCOUNT) % "))", account.setName(ACCOUNT), true) \
SKGTESTERROR((ACCOUNT) % ".load(QStringLiteral(" % (ACCOUNT) % "))", account.load(), true) \
if (qAbs(account.getCurrentAmount()-AMOUNT) > 10e-4) {\
SKGTEST((ACCOUNT) % ".getCurrentAmount(" % (ACCOUNT) % ")", SKGServices::toCurrencyString(account.getCurrentAmount(), QStringLiteral("Euros"), 2), SKGServices::toCurrencyString(AMOUNT, QStringLiteral("Euros"), 2))\
}\
}
#endif
/**
* @def SKGTESTTRIGGERACTION(PLUGIN)
* To trigger an action
*/
#define SKGTESTTRIGGERACTION(NAME) \
{ \
QAction* act = plugin.action(NAME); \
QVERIFY(act != nullptr); \
act->trigger(); \
}
/**
* @def SKGTESTPLUGIN(PLUGIN)
* To do common checks on a plugin
*/
#define SKGTESTPLUGIN(PLUGIN, DOC) \
{ \
QVERIFY(!PLUGIN.setupActions(nullptr)); \
QVERIFY(PLUGIN.setupActions(&DOC)); \
QVERIFY(!PLUGIN.title().isEmpty()); \
QVERIFY(!PLUGIN.icon().isEmpty()); \
QVERIFY(!PLUGIN.toolTip().isEmpty()); \
QVERIFY(!PLUGIN.statusTip().isEmpty()); \
QVERIFY(PLUGIN.getOrder() > 0); \
SKGTabPage* page = plugin.getWidget(); \
plugin.getPreferenceWidget(); \
plugin.getPreferenceSkeleton(); \
plugin.savePreferences(); \
if (page) page->setState(page->getState()); \
int nb = PLUGIN.getNbDashboardWidgets(); \
for (int i = 0; i < nb; ++i) { \
QVERIFY(!PLUGIN.getDashboardWidgetTitle(i).isEmpty()); \
} \
auto tips = PLUGIN.tips(); \
for (int i = 0; i < tips.count(); ++i) { \
QVERIFY(!tips.at(i).isEmpty()); \
} \
auto subplugins = PLUGIN.subPlugins(); \
for (int i = 0; i < subplugins.count(); ++i) { \
QVERIFY(!subplugins.at(i).isEmpty()); \
} \
QStringList iIgnoredAdvice; \
SKGAdviceList adv = PLUGIN.advice(iIgnoredAdvice); \
for (int i = 0; i < adv.count(); ++i) { \
QVERIFY(!adv.at(i).getUUID().isEmpty()); \
} \
}
diff --git a/tests/skgbasemodelertest/skgtestmultidocument.cpp b/tests/skgbasemodelertest/skgtestmultidocument.cpp
index f8aeb7f45..e8e31b1b7 100644
--- a/tests/skgbasemodelertest/skgtestmultidocument.cpp
+++ b/tests/skgbasemodelertest/skgtestmultidocument.cpp
@@ -1,325 +1,325 @@
/**********************"*****************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is a test script.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgtestmacro.h"
#include <qsqldatabase.h>
#include <qthread.h>
#include <quuid.h>
#include <unistd.h>
void dumpConnections()
{
const auto conNames = QSqlDatabase::connectionNames();
for (const auto& conName : conNames) {
SKGTRACE << "### " << conName << " ###" << endl;
auto con = QSqlDatabase::database(conName, false);
SKGTRACE << " connectionName=" << con.connectionName() << endl;
SKGTRACE << " connectOptions=" << con.connectOptions() << endl;
SKGTRACE << " isOpen=" << (con.isOpen() ? "Y" : "N") << endl;
}
}
/**
* The main function of the unit test
* @param argc the number of arguments
* @param argv the list of arguments
*/
int main(int argc, char** argv)
{
Q_UNUSED(argc)
Q_UNUSED(argv)
// Init test
SKGINITTEST(true)
// test class SKGDocument / PARAMETERS
SKGDocument document1;
SKGTESTERROR(QStringLiteral("PARAM:initialize"), document1.initialize(), true)
SKGTESTERROR(QStringLiteral("PARAM:close"), document1.close(), true)
SKGTESTERROR(QStringLiteral("PARAM:initialize"), document1.initialize(), true)
SKGTESTERROR(QStringLiteral("PARAM:beginTransaction"), document1.beginTransaction(QStringLiteral("t1")), true)
SKGTESTERROR(QStringLiteral("PARAM:setParameter"), document1.setParameter(QStringLiteral("ATT1"), QStringLiteral("VAL1")), true)
SKGTESTERROR(QStringLiteral("PARAM:endTransaction"), document1.endTransaction(true), true)
SKGTEST(QStringLiteral("PARAM:getCachedValue"), document1.getCachedValue(QStringLiteral("NOTFOUND")), QLatin1String(""))
SKGDocument document2;
SKGTESTERROR(QStringLiteral("PARAM:initialize"), document2.initialize(), true)
SKGTESTERROR(QStringLiteral("PARAM:beginTransaction"), document2.beginTransaction(QStringLiteral("t2")), true)
SKGTESTERROR(QStringLiteral("PARAM:setParameter"), document2.setParameter(QStringLiteral("ATT2"), QStringLiteral("VAL2")), true)
SKGTESTERROR(QStringLiteral("PARAM:setParameter"), document2.setParameter(QStringLiteral("ATT3"), QStringLiteral("dates.txt"), SKGTest::getTestPath(QStringLiteral("IN")) % "/dates.txt"), true)
SKGTESTERROR(QStringLiteral("PARAM:endTransaction"), document2.endTransaction(true), true)
SKGTEST(QStringLiteral("PARAM:getParameter"), document1.getParameter(QStringLiteral("ATT1")), QStringLiteral("VAL1"))
SKGTEST(QStringLiteral("PARAM:getParameter"), document2.getParameter(QStringLiteral("ATT2")), QStringLiteral("VAL2"))
SKGTEST(QStringLiteral("PARAM:getFileExtension"), document2.getFileExtension(), QStringLiteral("skgc"))
document1.formatPercentage(1.1, true);
document1.formatPercentage(1.1, false);
SKGTEST(QStringLiteral("PARAM:getRealAttribute"), document2.getRealAttribute(QStringLiteral("t_ATT")), QLatin1String(""))
SKGTEST(QStringLiteral("PARAM:getRealAttribute"), document2.getRealAttribute(QStringLiteral("t_att")), QStringLiteral("t_att"))
document1.getDatabaseIdentifier();
document1.getParameters(QStringLiteral("document"), QStringLiteral("t_name like 'ATT%'"));
// Special SQL command
SKGTESTERROR(QStringLiteral("PARAM:executeSqliteOrder"), document1.executeSqliteOrder(QStringLiteral("SELECT * FROM (SELECT CAPITALIZE(LOWER(UPPER(WORD('Abc Def', 2)))) AS V) WHERE REGEXP('D.*', V) AND WILDCARD('D*', V)")), true)
QString result;
SKGTESTERROR(QStringLiteral("PARAM:executeSqliteOrder"), document1.executeSingleSelectSqliteOrder(QStringLiteral("SELECT TODATE('07162013', 'MMDDYYYY')"), result), true)
SKGTEST(QStringLiteral("PARAM:executeSqliteOrder-TODATE"), result, QStringLiteral("2013-07-16"))
SKGTESTERROR(QStringLiteral("PARAM:executeSqliteOrder"), document1.executeSingleSelectSqliteOrder(QStringLiteral("SELECT TOFORMATTEDDATE('2013-07-16', 'dd-MM-yyyy')"), result), true)
SKGTEST(QStringLiteral("PARAM:executeSqliteOrder-TODATE"), result, QStringLiteral("16-07-2013"))
SKGTESTERROR(QStringLiteral("PARAM:executeSqliteOrder"), document1.executeSingleSelectSqliteOrder(QStringLiteral("SELECT TOFORMATTEDDATE('2013-07-16', 'd M yy')"), result), true)
SKGTEST(QStringLiteral("PARAM:executeSqliteOrder-TODATE"), result, QStringLiteral("16 7 13"))
SKGTESTERROR(QStringLiteral("PARAM:executeSqliteOrder"), document1.executeSingleSelectSqliteOrder(QStringLiteral("SELECT TODATE('ABCDEFGHIJ', 'MMDDYYYY')"), result), true)
SKGTEST(QStringLiteral("PARAM:executeSqliteOrder-TODATE"), result, SKGServices::dateToSqlString(QDate::currentDate()))
SKGTESTERROR(QStringLiteral("PARAM:executeSqliteOrder"), document1.executeSingleSelectSqliteOrder(QStringLiteral("SELECT WORD('Abc Def Ghi', 0)"), result), true)
SKGTEST(QStringLiteral("PARAM:executeSqliteOrder-WORD"), result, QStringLiteral("Abc"))
SKGTESTERROR(QStringLiteral("PARAM:executeSqliteOrder"), document1.executeSingleSelectSqliteOrder(QStringLiteral("SELECT WORD('Abc Def Ghi', 1)"), result), true)
SKGTEST(QStringLiteral("PARAM:executeSqliteOrder-WORD"), result, QStringLiteral("Abc"))
SKGTESTERROR(QStringLiteral("PARAM:executeSqliteOrder"), document1.executeSingleSelectSqliteOrder(QStringLiteral("SELECT WORD('Abc Def Ghi', 2)"), result), true)
SKGTEST(QStringLiteral("PARAM:executeSqliteOrder-WORD"), result, QStringLiteral("Def"))
SKGTESTERROR(QStringLiteral("PARAM:executeSqliteOrder"), document1.executeSingleSelectSqliteOrder(QStringLiteral("SELECT WORD('Abc Def Ghi', 3)"), result), true)
SKGTEST(QStringLiteral("PARAM:executeSqliteOrder-WORD"), result, QStringLiteral("Ghi"))
SKGTESTERROR(QStringLiteral("PARAM:executeSqliteOrder"), document1.executeSingleSelectSqliteOrder(QStringLiteral("SELECT WORD('Abc Def Ghi', 99)"), result), true)
SKGTEST(QStringLiteral("PARAM:executeSqliteOrder-WORD"), result, QStringLiteral("Ghi"))
SKGTESTERROR(QStringLiteral("PARAM:executeSqliteOrder"), document1.executeSingleSelectSqliteOrder(QStringLiteral("SELECT WORD('Abc Def Ghi', -99)"), result), true)
SKGTEST(QStringLiteral("PARAM:executeSqliteOrder-WORD"), result, QStringLiteral("Abc"))
SKGTESTERROR(QStringLiteral("PARAM:executeSqliteOrder"), document1.executeSingleSelectSqliteOrder(QStringLiteral("SELECT WORD('Abc Def Ghi', -3)"), result), true)
SKGTEST(QStringLiteral("PARAM:executeSqliteOrder-WORD"), result, QStringLiteral("Abc"))
SKGTESTERROR(QStringLiteral("PARAM:executeSqliteOrder"), document1.executeSingleSelectSqliteOrder(QStringLiteral("SELECT WORD('Abc Def Ghi', -2)"), result), true)
SKGTEST(QStringLiteral("PARAM:executeSqliteOrder-WORD"), result, QStringLiteral("Def"))
SKGTESTERROR(QStringLiteral("PARAM:executeSqliteOrder"), document1.executeSingleSelectSqliteOrder(QStringLiteral("SELECT WORD('Abc Def Ghi', -1)"), result), true)
SKGTEST(QStringLiteral("PARAM:executeSqliteOrder-WORD"), result, QStringLiteral("Ghi"))
SKGTESTERROR(QStringLiteral("PARAM:executeSqliteOrder"), document1.executeSingleSelectSqliteOrder(QStringLiteral("SELECT WORD(' Abc Def Ghi ', 1)"), result), true)
SKGTEST(QStringLiteral("PARAM:executeSqliteOrder-WORD"), result, QStringLiteral("Abc"))
SKGTESTERROR(QStringLiteral("PARAM:executeSqliteOrder"), document1.executeSingleSelectSqliteOrder(QStringLiteral("SELECT WORD(' Abc Def Ghi ', 2)"), result), true)
SKGTEST(QStringLiteral("PARAM:executeSqliteOrder-WORD"), result, QStringLiteral("Def"))
SKGTESTERROR(QStringLiteral("PARAM:executeSqliteOrder"), document1.executeSingleSelectSqliteOrder(QStringLiteral("SELECT WORD(' Abc Def Ghi ', 3)"), result), true)
SKGTEST(QStringLiteral("PARAM:executeSqliteOrder-WORD"), result, QStringLiteral("Ghi"))
SKGTESTERROR(QStringLiteral("PARAM:executeSqliteOrder"), document1.executeSingleSelectSqliteOrder(QStringLiteral("SELECT WORD('N:1234', 1)"), result), true)
SKGTEST(QStringLiteral("PARAM:executeSqliteOrder-WORD"), result, QStringLiteral("N"))
SKGTESTERROR(QStringLiteral("PARAM:executeSqliteOrder"), document1.executeSingleSelectSqliteOrder(QStringLiteral("SELECT WORD('N:1234', 2)"), result), true)
SKGTEST(QStringLiteral("PARAM:executeSqliteOrder-WORD"), result, QStringLiteral("1234"))
SKGTESTERROR(QStringLiteral("PARAM:executeSqliteOrder"), document1.executeSingleSelectSqliteOrder(QStringLiteral("SELECT REGEXPCAPTURE('(.*) CARTE 1234.*', 'MyShopName CARTE 12345678 PAIEME', 0)"), result), true)
SKGTEST(QStringLiteral("PARAM:executeSqliteOrder-WORD"), result, QStringLiteral("MyShopName CARTE 12345678 PAIEME"))
SKGTESTERROR(QStringLiteral("PARAM:executeSqliteOrder"), document1.executeSingleSelectSqliteOrder(QStringLiteral("SELECT REGEXPCAPTURE('(.*) CARTE 1234.*', 'MyShopName CARTE 12345678 PAIEME', 1)"), result), true)
SKGTEST(QStringLiteral("PARAM:executeSqliteOrder-WORD"), result, QStringLiteral("MyShopName"))
SKGTESTERROR(QStringLiteral("PARAM:executeSqliteOrder"), document1.executeSingleSelectSqliteOrder(QStringLiteral("SELECT REGEXPCAPTURE('(.*) CARTE 1234.*', 'MyShopName CARTE 12345678 PAIEME', 12)"), result), true)
SKGTEST(QStringLiteral("PARAM:executeSqliteOrder-WORD"), result, QLatin1String(""))
QMap<QString, QVariant> map;
map[QStringLiteral(":2")] = "20";
SKGTESTERROR(QStringLiteral("PARAM:executeSqliteOrder"), document1.executeSqliteOrder(QStringLiteral("SELECT WORD('Abc Def', :2)"), map, nullptr), true)
SKGTESTERROR(QStringLiteral("PARAM:executeSqliteOrder"), document1.executeSingleSelectSqliteOrder(QStringLiteral("SELECT TOCURRENCY(1234, 'F')"), result), true)
SKGTEST(QStringLiteral("PARAM:executeSqliteOrder-1234 F"), result.remove(' '), QStringLiteral("1,234.00F"))
SKGTESTERROR(QStringLiteral("PARAM:executeSqliteOrder"), document1.executeSingleSelectSqliteOrder(QStringLiteral("SELECT TOCURRENCY(-1234, (SELECT 'F'))"), result), true)
SKGTEST(QStringLiteral("PARAM:executeSqliteOrder-1234 F"), result.remove(' '), QStringLiteral("-1,234.00F"))
SKGTESTERROR(QStringLiteral("PARAM:executeSqliteOrder"), document1.executeSingleSelectSqliteOrder(QStringLiteral("SELECT PERIOD((SELECT '2013-03-05'), (SELECT 'D'))"), result), true)
SKGTEST(QStringLiteral("PARAM:executeSqliteOrder-PERIOD D"), result, QStringLiteral("2013-03-05"))
SKGTESTERROR(QStringLiteral("PARAM:executeSqliteOrder"), document1.executeSingleSelectSqliteOrder(QStringLiteral("SELECT PERIOD('2013-03-05', 'W')"), result), true)
SKGTEST(QStringLiteral("PARAM:executeSqliteOrder-PERIOD W"), result, QStringLiteral("2013-W10"))
SKGTESTERROR(QStringLiteral("PARAM:executeSqliteOrder"), document1.executeSingleSelectSqliteOrder(QStringLiteral("SELECT PERIOD('2013-03-05', 'M')"), result), true)
SKGTEST(QStringLiteral("PARAM:executeSqliteOrder-PERIOD M"), result, QStringLiteral("2013-03"))
SKGTESTERROR(QStringLiteral("PARAM:executeSqliteOrder"), document1.executeSingleSelectSqliteOrder(QStringLiteral("SELECT PERIOD('2013-03-05', 'Q')"), result), true)
SKGTEST(QStringLiteral("PARAM:executeSqliteOrder-PERIOD Q"), result, QStringLiteral("2013-Q1"))
SKGTESTERROR(QStringLiteral("PARAM:executeSqliteOrder"), document1.executeSingleSelectSqliteOrder(QStringLiteral("SELECT PERIOD('2013-03-05', 'S')"), result), true)
SKGTEST(QStringLiteral("PARAM:executeSqliteOrder-PERIOD S"), result, QStringLiteral("2013-S1"))
SKGTESTERROR(QStringLiteral("PARAM:executeSqliteOrder"), document1.executeSingleSelectSqliteOrder(QStringLiteral("SELECT PERIOD('2013-03-05', 'Y')"), result), true)
SKGTEST(QStringLiteral("PARAM:executeSqliteOrder-PERIOD Y"), result, QStringLiteral("2013"))
SKGTESTERROR(QStringLiteral("PARAM:executeSqliteOrder"), document1.executeSingleSelectSqliteOrder(QStringLiteral("SELECT PERIOD('2014-07-16', 'D')"), result), true)
SKGTEST(QStringLiteral("PARAM:executeSqliteOrder-PERIOD D"), result, QStringLiteral("2014-07-16"))
SKGTESTERROR(QStringLiteral("PARAM:executeSqliteOrder"), document1.executeSingleSelectSqliteOrder(QStringLiteral("SELECT PERIOD('2014-07-16', 'W')"), result), true)
SKGTEST(QStringLiteral("PARAM:executeSqliteOrder-PERIOD W"), result, QStringLiteral("2014-W29"))
SKGTESTERROR(QStringLiteral("PARAM:executeSqliteOrder"), document1.executeSingleSelectSqliteOrder(QStringLiteral("SELECT PERIOD('2014-07-16', 'M')"), result), true)
SKGTEST(QStringLiteral("PARAM:executeSqliteOrder-PERIOD M"), result, QStringLiteral("2014-07"))
SKGTESTERROR(QStringLiteral("PARAM:executeSqliteOrder"), document1.executeSingleSelectSqliteOrder(QStringLiteral("SELECT PERIOD('2014-07-16', 'Q')"), result), true)
SKGTEST(QStringLiteral("PARAM:executeSqliteOrder-PERIOD Q"), result, QStringLiteral("2014-Q3"))
SKGTESTERROR(QStringLiteral("PARAM:executeSqliteOrder"), document1.executeSingleSelectSqliteOrder(QStringLiteral("SELECT PERIOD('2014-07-16', 'S')"), result), true)
SKGTEST(QStringLiteral("PARAM:executeSqliteOrder-PERIOD S"), result, QStringLiteral("2014-S2"))
SKGTESTERROR(QStringLiteral("PARAM:executeSqliteOrder"), document1.executeSingleSelectSqliteOrder(QStringLiteral("SELECT PERIOD('2014-07-16', 'Y')"), result), true)
SKGTEST(QStringLiteral("PARAM:executeSqliteOrder-PERIOD Y"), result, QStringLiteral("2014"))
SKGTESTERROR(QStringLiteral("PARAM:executeSqliteOrder"), document1.executeSingleSelectSqliteOrder(QStringLiteral("SELECT NEXT('12345')"), result), true)
SKGTEST(QStringLiteral("PARAM:executeSqliteOrder-NEXT"), result, QStringLiteral("12346"))
SKGTESTERROR(QStringLiteral("PARAM:executeSqliteOrder"), document1.executeSingleSelectSqliteOrder(QStringLiteral("SELECT NEXT('9')"), result), true)
SKGTEST(QStringLiteral("PARAM:executeSqliteOrder-NEXT"), result, QStringLiteral("10"))
SKGTESTERROR(QStringLiteral("PARAM:executeSqliteOrder"), document1.executeSingleSelectSqliteOrder(QStringLiteral("SELECT NEXT('ABC')"), result), true)
SKGTEST(QStringLiteral("PARAM:executeSqliteOrder-NEXT"), result, QLatin1String(""))
SKGTESTERROR(QStringLiteral("PARAM:executeSqliteOrder"), document1.executeSingleSelectSqliteOrder(QStringLiteral("SELECT XOR('HELLO WORLD!', 'KEY')"), result), true)
SKGTEST(QStringLiteral("PARAM:executeSqliteOrder-XOR"), result, QLatin1String("# 030015070a791c0a0b070178"))
for (int i = 1; i < 100; ++i) {
auto string = QUuid::createUuid().toString();
SKGTESTERROR(QStringLiteral("PARAM:executeSqliteOrder"), document1.executeSingleSelectSqliteOrder(QStringLiteral("SELECT XOR(XOR('") + string + "', 'KEY'), 'KEY')", result), true)
SKGTEST(QStringLiteral("PARAM:executeSqliteOrder-XOR"), result, string)
}
for (double i = -1200.53; i < 5023.25; i = i + 125.54) {
auto string = SKGServices::doubleToString(i);
SKGTESTERROR(QStringLiteral("PARAM:executeSqliteOrder"), document1.executeSingleSelectSqliteOrder(QStringLiteral("SELECT XORD(XORD(") + string + ", 'KEY'), 'KEY')", result), true)
SKGTEST(QStringLiteral("PARAM:executeSqliteOrder-XORD"), result, string)
}
SKGTRACE << "####### Before concurrent calls" << endl;
dumpConnections();
int nb = 5;
{
SKGTRACE << ">> executeSelectSqliteOrder same order" << endl;
QString output;
double elapse = SKGServices::getMicroTime();
for (int i = 0; i < nb; ++i) {
SKGStringListList oResult;
IFOK(document1.executeSelectSqliteOrder(QStringLiteral("SELECT SLEEP(1)"), oResult)) {
output = output + SKGServices::intToString(oResult.count());
}
}
double time = SKGServices::getMicroTime() - elapse;
SKGTRACE << nb << " x executeSelectSqliteOrder:" << output << " " << time << " ms" << endl;
SKGTEST(QStringLiteral("PARAM:executeSelectSqliteOrder-PERFO >=1000"), static_cast<unsigned int>(time >= 1000), static_cast<unsigned int>(true))
SKGTEST(QStringLiteral("PARAM:executeSelectSqliteOrder-PERFO <2000"), static_cast<unsigned int>(time < 2000), static_cast<unsigned int>(true))
SKGTEST(QStringLiteral("PARAM:executeSelectSqliteOrder"), output, QStringLiteral("22222"))
}
{
SKGTRACE << ">> concurrentExecuteSelectSqliteOrder same order" << endl;
QString output;
double elapse = SKGServices::getMicroTime();
for (int i = 0; i < nb; ++i) {
document1.concurrentExecuteSelectSqliteOrder(QStringLiteral("SELECT SLEEP(1), 2"),
[ &output ](const SKGStringListList & iResult) {
output = output + SKGServices::intToString(iResult.count());
});
}
double time = SKGServices::getMicroTime() - elapse;
SKGTRACE << nb << " x concurrentExecuteSelectSqliteOrder:" << output << " " << (SKGServices::getMicroTime() - elapse) << " ms" << endl;
qApp->processEvents(QEventLoop::AllEvents, 500);
for (int i = 1; i < 100; ++i) {
QThread::msleep(100);
qApp->processEvents(QEventLoop::AllEvents, 500);
time = SKGServices::getMicroTime() - elapse;
if (output == QStringLiteral("22222")) {
SKGTEST(QStringLiteral("PARAM:executeSelectSqliteOrder-PERFO >=1000"), static_cast<unsigned int>(time >= 1000), static_cast<unsigned int>(true))
SKGTEST(QStringLiteral("PARAM:executeSelectSqliteOrder-PERFO <3500"), static_cast<unsigned int>(time < 3500), static_cast<unsigned int>(true))
break;
}
}
SKGTRACE << nb << " x concurrentExecuteSelectSqliteOrder:" << output << " " << time << " ms" << endl;
SKGTEST(QStringLiteral("PARAM:concurrentExecuteSelectSqliteOrder"), output, QStringLiteral("22222"))
}
{
SKGTRACE << ">> executeSelectSqliteOrder different orders" << endl;
QString output;
double elapse = SKGServices::getMicroTime();
for (int i = 0; i < nb; ++i) {
SKGStringListList oResult;
IFOK(document1.executeSelectSqliteOrder(QStringLiteral("SELECT SLEEP(1), ") + SKGServices::intToString(1000 + i), oResult)) {
output = output + SKGServices::intToString(oResult.count());
}
}
double time = SKGServices::getMicroTime() - elapse;
SKGTRACE << nb << " x executeSelectSqliteOrder:" << output << " " << time << " ms" << endl;
SKGTEST(QStringLiteral("PARAM:executeSelectSqliteOrder-PERFO >5000"), static_cast<unsigned int>(time > 5000), static_cast<unsigned int>(true))
SKGTEST(QStringLiteral("PARAM:executeSelectSqliteOrder-PERFO <6000"), static_cast<unsigned int>(time < 6000), static_cast<unsigned int>(true))
SKGTEST(QStringLiteral("PARAM:executeSelectSqliteOrder"), output, QStringLiteral("22222"))
}
{
SKGTRACE << ">> concurrentExecuteSelectSqliteOrder different orders" << endl;
QString output;
double elapse = SKGServices::getMicroTime();
for (int i = 0; i < nb; ++i) {
document1.concurrentExecuteSelectSqliteOrder(QStringLiteral("SELECT SLEEP(1), ") + SKGServices::intToString(2000 + i),
[ &output ](const SKGStringListList & iResult) {
output = output + SKGServices::intToString(iResult.count());
});
}
double time = SKGServices::getMicroTime() - elapse;
SKGTRACE << nb << " x concurrentExecuteSelectSqliteOrder:" << output << " " << (SKGServices::getMicroTime() - elapse) << " ms" << endl;
qApp->processEvents(QEventLoop::AllEvents, 500);
for (int i = 1; i < 100; ++i) {
QThread::msleep(100);
qApp->processEvents(QEventLoop::AllEvents, 500);
time = SKGServices::getMicroTime() - elapse;
if (output == QStringLiteral("22222")) {
SKGTEST(QStringLiteral("PARAM:executeSelectSqliteOrder-PERFO >=1000"), static_cast<unsigned int>(time >= 1000), static_cast<unsigned int>(true))
SKGTEST(QStringLiteral("PARAM:executeSelectSqliteOrder-PERFO <3500"), static_cast<unsigned int>(time < 3500), static_cast<unsigned int>(true))
break;
}
}
SKGTRACE << nb << " x concurrentExecuteSelectSqliteOrder:" << output << " " << time << " ms" << endl;
SKGTEST(QStringLiteral("PARAM:concurrentExecuteSelectSqliteOrder"), output, QStringLiteral("22222"))
}
SKGTRACE << "####### Before close" << endl;
dumpConnections();
SKGTESTERROR(QStringLiteral("PARAM:close"), document1.close(), true)
SKGTRACE << "####### Before initialize" << endl;
dumpConnections();
SKGTESTERROR(QStringLiteral("PARAM:initialize"), document1.initialize(), true)
SKGTRACE << "####### Before concurrent calls" << endl;
dumpConnections();
{
SKGTRACE << ">> concurrentExecuteSelectSqliteOrder different orders (in other thread)" << endl;
QString output;
double elapse = SKGServices::getMicroTime();
for (int i = 0; i < nb; ++i) {
document1.concurrentExecuteSelectSqliteOrder(QStringLiteral("SELECT SLEEP(1), ") + SKGServices::intToString(3000 + i),
[ &output ](const SKGStringListList & iResult) {
QMutex mutex;
mutex.lock();
output = output + SKGServices::intToString(iResult.count());
mutex.unlock();
}, false);
}
double time = SKGServices::getMicroTime() - elapse;
SKGTRACE << nb << " x concurrentExecuteSelectSqliteOrder:" << output << " " << (SKGServices::getMicroTime() - elapse) << " ms" << endl;
for (int i = 1; i < 100; ++i) {
QThread::msleep(100);
time = SKGServices::getMicroTime() - elapse;
if (output == QStringLiteral("22222")) {
SKGTEST(QStringLiteral("PARAM:executeSelectSqliteOrder-PERFO >=1000"), static_cast<unsigned int>(time >= 1000), static_cast<unsigned int>(true))
SKGTEST(QStringLiteral("PARAM:executeSelectSqliteOrder-PERFO <3500"), static_cast<unsigned int>(time < 3500), static_cast<unsigned int>(true))
break;
}
}
SKGTRACE << nb << " x concurrentExecuteSelectSqliteOrder:" << output << " " << time << " ms" << endl;
SKGTEST(QStringLiteral("PARAM:concurrentExecuteSelectSqliteOrder"), output, QStringLiteral("22222"))
}
SKGTRACE << "####### End" << endl;
dumpConnections();
// End test
SKGENDTEST()
}
diff --git a/tests/skgbasemodelertest/skgtestnodes.cpp b/tests/skgbasemodelertest/skgtestnodes.cpp
index 5054e506b..d26def264 100644
--- a/tests/skgbasemodelertest/skgtestnodes.cpp
+++ b/tests/skgbasemodelertest/skgtestnodes.cpp
@@ -1,396 +1,396 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is a test script.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgtestmacro.h"
/**
* The main function of the unit test
* @param argc the number of arguments
* @param argv the list of arguments
*/
int main(int argc, char** argv)
{
Q_UNUSED(argc)
Q_UNUSED(argv)
// Init test
SKGINITTEST(true)
{
// Test node
SKGDocument document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
SKGNodeObject parent2;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("NODE_T1"), err)
// Create node 0
SKGNodeObject nod0(&document1);
SKGTESTERROR(QStringLiteral("NOD:setName+invalid name"), nod0.setName('a' % OBJECTSEPARATOR % 'b'), false)
SKGTESTERROR(QStringLiteral("NOD:save"), nod0.save(), false)
// Create node 1
SKGNodeObject nod1(&document1);
SKGTESTERROR(QStringLiteral("NOD:setName"), nod1.setName(QStringLiteral("root1")), true)
SKGTESTERROR(QStringLiteral("NOD:setData"), nod1.setData(QStringLiteral("data1")), true)
SKGTESTERROR(QStringLiteral("NOD:setOrder"), nod1.setOrder(12), true)
SKGTESTERROR(QStringLiteral("NOD:setAutoStart"), nod1.setAutoStart(true), true)
SKGTESTBOOL("NOD:exist", nod1.exist(), false)
SKGTESTERROR(QStringLiteral("NOD:save"), nod1.save(), true)
SKGTESTBOOL("NOD:exist", nod1.exist(), true)
SKGTEST(QStringLiteral("NOD:getFullName"), nod1.getFullName(), QStringLiteral("root1"))
SKGTEST(QStringLiteral("NOD:getData"), nod1.getData(), QStringLiteral("data1"))
SKGTEST(QStringLiteral("NOD:getOrder"), nod1.getOrder(), 12)
SKGTESTBOOL("NOD:isFolder", nod1.isFolder(), false)
SKGTESTBOOL("NOD:isAutoStart", nod1.isAutoStart(), true)
nod1.getIcon();
// Update with bad name
SKGTESTERROR(QStringLiteral("NOD:setName"), nod1.setName("root1" % OBJECTSEPARATOR % 'A'), false)
SKGTESTERROR(QStringLiteral("NOD:load"), nod1.load(), true)
SKGTEST(QStringLiteral("NOD:getFullName"), nod1.getFullName(), QStringLiteral("root1"))
// Create node 1.1
SKGNodeObject nod1_1;
SKGTESTERROR(QStringLiteral("NOD:addNode"), nod1.addNode(nod1_1), true)
SKGTESTERROR(QStringLiteral("NOD:setName"), nod1_1.setName(QStringLiteral("nod1")), true)
SKGTESTERROR(QStringLiteral("NOD:setOrder"), nod1_1.setOrder(1), true)
SKGTESTERROR(QStringLiteral("NOD:save"), nod1_1.save(), true)
SKGTEST(QStringLiteral("NOD:getFullName"), nod1_1.getFullName(), "root1" % OBJECTSEPARATOR % "nod1")
// Update nod1_1
SKGTESTERROR(QStringLiteral("NOD:setName"), nod1_1.setName(QStringLiteral("NODE1")), true)
SKGTESTERROR(QStringLiteral("NOD:save"), nod1_1.save(), true)
SKGTEST(QStringLiteral("NOD:getFullName"), nod1_1.getFullName(), "root1" % OBJECTSEPARATOR % "NODE1")
// Update nod1
SKGTESTERROR(QStringLiteral("NOD:setName"), nod1.setName(QStringLiteral("ROOT1")), true)
SKGTESTERROR(QStringLiteral("NOD:save"), nod1.save(), true)
SKGTEST(QStringLiteral("NOD:getFullName"), nod1.getFullName(), QStringLiteral("ROOT1"))
SKGTESTERROR(QStringLiteral("NOD:load"), nod1_1.load(), true)
SKGTEST(QStringLiteral("NOD:getFullName"), nod1_1.getFullName(), "ROOT1" % OBJECTSEPARATOR % "NODE1")
// Create node 1.2
SKGNodeObject nod1_2;
SKGTESTERROR(QStringLiteral("NOD:addNode"), nod1.addNode(nod1_2), true)
SKGTESTERROR(QStringLiteral("NOD:setName"), nod1_2.setName(QStringLiteral("NODE2")), true)
SKGTESTERROR(QStringLiteral("NOD:setOrder"), nod1_2.setOrder(2), true)
SKGTESTERROR(QStringLiteral("NOD:save"), nod1_2.save(), true)
SKGTEST(QStringLiteral("NOD:getFullName"), nod1_2.getFullName(), "ROOT1" % OBJECTSEPARATOR % "NODE2")
SKGTESTBOOL("NOD:<", (nod1_1 < nod1_2), true)
SKGTESTBOOL("NOD:>", (nod1_1 > nod1_2), false)
SKGTESTBOOL("NOD:<", (nod1_1 < nod1_1), false)
SKGTESTBOOL("NOD:>", (nod1_1 > nod1_1), false)
// Create node end
SKGNodeObject end1;
SKGTESTERROR(QStringLiteral("NOD:addNode"), nod1_1.addNode(end1), true)
SKGTESTERROR(QStringLiteral("NOD:setName"), end1.setName(QStringLiteral("END")), true)
SKGTESTERROR(QStringLiteral("NOD:save"), end1.save(), true)
SKGTEST(QStringLiteral("NOD:getFullName"), end1.getFullName(), "ROOT1" % OBJECTSEPARATOR % "NODE1" % OBJECTSEPARATOR % "END")
// Create node end
SKGNodeObject end2;
SKGTESTERROR(QStringLiteral("NOD:addNode"), nod1_2.addNode(end2), true)
SKGTESTERROR(QStringLiteral("NOD:setName"), end2.setName(QStringLiteral("END")), true)
SKGTESTERROR(QStringLiteral("NOD:save"), end2.save(), true)
SKGTEST(QStringLiteral("NOD:getFullName"), end2.getFullName(), "ROOT1" % OBJECTSEPARATOR % "NODE2" % OBJECTSEPARATOR % "END")
SKGNodeObject end2_1;
SKGTESTERROR(QStringLiteral("NOD:addNode"), end2.addNode(end2_1), true)
SKGTESTERROR(QStringLiteral("NOD:setName"), end2_1.setName(QStringLiteral("REALEND")), true)
SKGTESTERROR(QStringLiteral("NOD:save"), end2_1.save(), true)
SKGTEST(QStringLiteral("NOD:getFullName"), end2_1.getFullName(), "ROOT1" % OBJECTSEPARATOR % "NODE2" % OBJECTSEPARATOR % "END" % OBJECTSEPARATOR % "REALEND")
// Get parent
SKGNodeObject parent1;
SKGTESTERROR(QStringLiteral("NOD:addNode"), end2.getParentNode(parent1), true)
SKGTEST(QStringLiteral("NOD:getFullName"), parent1.getFullName(), "ROOT1" % OBJECTSEPARATOR % "NODE2")
// Get parent
SKGTESTERROR(QStringLiteral("NOD:addNode"), parent1.getParentNode(parent2), true)
SKGTEST(QStringLiteral("NOD:getFullName"), parent2.getFullName(), QStringLiteral("ROOT1"))
// Get children
SKGObjectBase::SKGListSKGObjectBase NodeList;
SKGTESTERROR(QStringLiteral("NOD:getNodes"), parent2.getNodes(NodeList), true)
SKGTEST(QStringLiteral("NOD:nb nodegories"), NodeList.size(), 2)
// Simple delete
SKGTESTERROR(QStringLiteral("NOD:delete"), end1.remove(), true)
QStringList oResult;
SKGTESTERROR(QStringLiteral("NOD:getDistinctValues"), document1.getDistinctValues(QStringLiteral("node"), QStringLiteral("id"), oResult), true)
SKGTEST(QStringLiteral("NOD:oResult.size"), oResult.size(), 5)
SKGNodeObject nodeROOT1BC;
SKGTESTERROR(QStringLiteral("NOD:addNode"), SKGNodeObject::createPathNode(&document1, "ROOT1" % OBJECTSEPARATOR % 'B' % OBJECTSEPARATOR % 'C', nodeROOT1BC), true)
SKGNodeObject nodeROOT1DE;
SKGTESTERROR(QStringLiteral("NOD:addNode"), SKGNodeObject::createPathNode(&document1, "ROOT1" % OBJECTSEPARATOR % 'D' % OBJECTSEPARATOR % 'E', nodeROOT1DE), true)
}
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("NODE_T2"), err)
// Cascading delete
SKGTESTERROR(QStringLiteral("NOD:delete"), parent2.remove(), true)
QStringList oResult;
SKGTESTERROR(QStringLiteral("NOD:getDistinctValues"), document1.getDistinctValues(QStringLiteral("node"), QStringLiteral("id"), oResult), true)
SKGTEST(QStringLiteral("NOD:oResult.size"), oResult.size(), 0)
}
// Undo
SKGTESTERROR(QStringLiteral("NOD:undoRedoTransaction"), document1.undoRedoTransaction(), true)
QStringList oResult;
SKGTESTERROR(QStringLiteral("NOD:getDistinctValues"), document1.getDistinctValues(QStringLiteral("node"), QStringLiteral("id"), oResult), true)
SKGTEST(QStringLiteral("NOD:oResult.size"), oResult.size(), 9)
SKGTESTERROR(QStringLiteral("NOD:undoRedoTransaction"), document1.undoRedoTransaction(), true)
SKGTESTERROR(QStringLiteral("NOD:getDistinctValues"), document1.getDistinctValues(QStringLiteral("node"), QStringLiteral("id"), oResult), true)
SKGTEST(QStringLiteral("NOD:oResult.size"), oResult.size(), 0)
// Redo
SKGTESTERROR(QStringLiteral("NOD:undoRedoTransaction(SKGDocument::REDO)"), document1.undoRedoTransaction(SKGDocument::REDO), true)
SKGTESTERROR(QStringLiteral("NOD:getDistinctValues"), document1.getDistinctValues(QStringLiteral("node"), QStringLiteral("id"), oResult), true)
SKGTEST(QStringLiteral("NOD:oResult.size"), oResult.size(), 9)
SKGTESTERROR(QStringLiteral("NOD:undoRedoTransaction(SKGDocument::REDO)"), document1.undoRedoTransaction(SKGDocument::REDO), true)
SKGTESTERROR(QStringLiteral("NOD:getDistinctValues"), document1.getDistinctValues(QStringLiteral("node"), QStringLiteral("id"), oResult), true)
SKGTEST(QStringLiteral("NOD:oResult.size"), oResult.size(), 0)
}
{
SKGDocument document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("NODE_T1"), err)
SKGNodeObject node;
SKGTESTERROR(QStringLiteral("NOD:createPathNode"), SKGNodeObject::createPathNode(&document1, 'A' % OBJECTSEPARATOR % "B1" % OBJECTSEPARATOR % 'C', node), true)
SKGTESTERROR(QStringLiteral("NOD:createPathNode"), SKGNodeObject::createPathNode(&document1, 'A' % OBJECTSEPARATOR % "B1" % OBJECTSEPARATOR % 'D', node), true)
SKGTESTERROR(QStringLiteral("NOD:createPathNode"), SKGNodeObject::createPathNode(&document1, 'A' % OBJECTSEPARATOR % "B2" % OBJECTSEPARATOR % 'E', node), true)
QStringList oResult;
SKGTESTERROR(QStringLiteral("NOD:getDistinctValues"), document1.getDistinctValues(QStringLiteral("node"), QStringLiteral("id"), oResult), true)
SKGTEST(QStringLiteral("NOD:oResult.size"), oResult.size(), 6)
}
}
{
SKGDocument document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("NODE_T1"), err)
SKGNodeObject node;
SKGTESTERROR(QStringLiteral("NOD:createPathNode"), SKGNodeObject::createPathNode(&document1, 'A' % OBJECTSEPARATOR % "B1" % OBJECTSEPARATOR % 'C', node), true)
SKGTESTERROR(QStringLiteral("NOD:createPathNode"), SKGNodeObject::createPathNode(&document1, 'A' % OBJECTSEPARATOR % "B2" % OBJECTSEPARATOR % 'C', node), true)
QStringList oResult;
SKGTESTERROR(QStringLiteral("NOD:getDistinctValues"), document1.getDistinctValues(QStringLiteral("node"), QStringLiteral("id"), oResult), true)
SKGTEST(QStringLiteral("NOD:oResult.size"), oResult.size(), 5)
}
}
{
SKGDocument document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("NODE_T1"), err)
SKGNodeObject node;
SKGTESTERROR(QStringLiteral("NOD:createPathNode"), SKGNodeObject::createPathNode(&document1, 'A' % OBJECTSEPARATOR % 'A', node), true)
QStringList oResult;
SKGTESTERROR(QStringLiteral("NOD:getDistinctValues"), document1.getDistinctValues(QStringLiteral("node"), QStringLiteral("id"), oResult), true)
SKGTEST(QStringLiteral("NOD:oResult.size"), oResult.size(), 2)
}
}
{
SKGDocument document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("NODE_T1"), err)
SKGNodeObject nodeB;
SKGTESTERROR(QStringLiteral("NOD:createPathNode"), SKGNodeObject::createPathNode(&document1, 'A' % OBJECTSEPARATOR % 'B', nodeB), true)
SKGNodeObject nodeC;
SKGTESTERROR(QStringLiteral("NOD:createPathNode"), SKGNodeObject::createPathNode(&document1, QStringLiteral("C"), nodeC), true)
SKGNodeObject nodeA;
SKGTESTERROR(QStringLiteral("NOD:getParentNode"), nodeB.getParentNode(nodeA), true)
SKGNamedObject nameB = static_cast<SKGNamedObject>(nodeB); // For coverage
SKGNodeObject nodeC2(static_cast<SKGObjectBase>(nodeC)); // For coverage
SKGTESTERROR(QStringLiteral("NOD:setParentNode"), nodeA.setParentNode(nodeB), false)
SKGTESTERROR(QStringLiteral("NOD:setParentNode"), nodeA.setParentNode(nodeA), false)
SKGTESTERROR(QStringLiteral("NOD:setParentNode"), nodeB.setParentNode(nodeB), false)
SKGTESTERROR(QStringLiteral("NOD:setParentNode"), nodeC.setParentNode(nodeB), true)
SKGTESTERROR(QStringLiteral("NOD:removeParentNode"), nodeB.removeParentNode(), true)
}
}
{
SKGDocument document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("NODE_T1"), err)
SKGNodeObject nodeB1;
SKGTESTERROR(QStringLiteral("NOD:createPathNode"), SKGNodeObject::createPathNode(&document1, 'A' % OBJECTSEPARATOR % 'B', nodeB1, true), true)
SKGNodeObject nodeB2;
SKGTESTERROR(QStringLiteral("NOD:createPathNode"), SKGNodeObject::createPathNode(&document1, 'A' % OBJECTSEPARATOR % 'B', nodeB2, true), true)
document1.dump(DUMPALL);
QStringList oResult;
SKGTESTERROR(QStringLiteral("NOD:getDistinctValues"), document1.getDistinctValues(QStringLiteral("node"), QStringLiteral("id"), oResult), true)
SKGTEST(QStringLiteral("NOD:oResult.size"), oResult.size(), 3)
}
}
{
SKGDocument document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("NODE_T1"), err)
SKGNodeObject nodeB1;
SKGTESTERROR(QStringLiteral("NOD:createPathNode"), SKGNodeObject::createPathNode(&document1, QStringLiteral("B"), nodeB1, true), true)
SKGNodeObject nodeB2;
SKGTESTERROR(QStringLiteral("NOD:createPathNode"), SKGNodeObject::createPathNode(&document1, QStringLiteral("B"), nodeB2, true), true)
QStringList oResult;
SKGTESTERROR(QStringLiteral("NOD:getDistinctValues"), document1.getDistinctValues(QStringLiteral("node"), QStringLiteral("id"), oResult), true)
SKGTEST(QStringLiteral("NOD:oResult.size"), oResult.size(), 2)
}
}
// Test properties
{
SKGDocument document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("NODE_T1"), err)
SKGNodeObject node1;
SKGTESTERROR(QStringLiteral("NOD:createPathNode"), SKGNodeObject::createPathNode(&document1, QStringLiteral("1"), node1, true), true)
SKGNodeObject node2;
SKGTESTERROR(QStringLiteral("NOD:createPathNode"), SKGNodeObject::createPathNode(&document1, QStringLiteral("2"), node2, true), true)
SKGTESTERROR(QStringLiteral("NOD:setProperty"), node1.setProperty(QStringLiteral("prop"), QStringLiteral("val1")), true)
SKGTESTERROR(QStringLiteral("NOD:setProperty"), node2.setProperty(QStringLiteral("prop"), QStringLiteral("val2")), true)
SKGTEST(QStringLiteral("NOD:getProperty"), node1.getProperty(QStringLiteral("prop")), QStringLiteral("val1"))
SKGTEST(QStringLiteral("NOD:getProperty"), node2.getProperty(QStringLiteral("prop")), QStringLiteral("val2"))
SKGTESTERROR(QStringLiteral("NOD:setProperty"), node1.setProperty(QStringLiteral("prop"), QStringLiteral("val3")), true)
SKGTEST(QStringLiteral("NOD:getProperty"), node1.getProperty(QStringLiteral("prop")), QStringLiteral("val3"))
SKGTEST(QStringLiteral("NOD:getProperty"), node2.getProperty(QStringLiteral("prop")), QStringLiteral("val2"))
}
}
// Test setAttribute
{
SKGDocument document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("NODE_T1"), err)
SKGNodeObject node1;
SKGTESTERROR(QStringLiteral("NOD:save"), node1.save(), false)
SKGTESTERROR(QStringLiteral("NOD:remove"), node1.remove(), false)
SKGNodeObject node2;
SKGTESTERROR(QStringLiteral("NOD:addNode"), node1.addNode(node2), false)
SKGTESTERROR(QStringLiteral("NOD:setParentNode"), node1.setParentNode(node2), false)
SKGTESTERROR(QStringLiteral("NOD:createPathNode"), SKGNodeObject::createPathNode(&document1, QStringLiteral("ABC DEF "), node1, true), true)
SKGTESTERROR(QStringLiteral("NOD:setAttribute"), node1.setAttribute(QStringLiteral("t_name"), QStringLiteral("=lower")), true)
SKGTEST(QStringLiteral("NOD:getAttribute"), node1.getAttribute(QStringLiteral("t_name")), QStringLiteral("abc def "))
SKGTESTERROR(QStringLiteral("NOD:setAttribute"), node1.setAttribute(QStringLiteral("t_name"), QStringLiteral("=upper")), true)
SKGTEST(QStringLiteral("NOD:getAttribute"), node1.getAttribute(QStringLiteral("t_name")), QStringLiteral("ABC DEF "))
SKGTESTERROR(QStringLiteral("NOD:setAttribute"), node1.setAttribute(QStringLiteral("t_name"), QStringLiteral("=capwords")), true)
SKGTEST(QStringLiteral("NOD:getAttribute"), node1.getAttribute(QStringLiteral("t_name")), QStringLiteral("Abc Def "))
SKGTESTERROR(QStringLiteral("NOD:setAttribute"), node1.setAttribute(QStringLiteral("t_name"), QStringLiteral("=capitalize")), true)
SKGTEST(QStringLiteral("NOD:getAttribute"), node1.getAttribute(QStringLiteral("t_name")), QStringLiteral("Abc def "))
SKGTESTERROR(QStringLiteral("NOD:setAttribute"), node1.setAttribute(QStringLiteral("t_name"), QStringLiteral("=trim")), true)
SKGTEST(QStringLiteral("NOD:getAttribute"), node1.getAttribute(QStringLiteral("t_name")), QStringLiteral("Abc def"))
SKGTESTERROR(QStringLiteral("NOD:setProperty"), node1.setProperty(QStringLiteral("prop"), QStringLiteral("prop on node 1")), true)
SKGTEST(QStringLiteral("NOD:getProperty"), node1.getProperty(QStringLiteral("prop")), QStringLiteral("prop on node 1"))
SKGTEST(QStringLiteral("NOD:getAttribute"), node1.getAttribute(QStringLiteral("p_prop")), QStringLiteral("prop on node 1"))
SKGTESTERROR(QStringLiteral("NOD:save"), node1.save(), true)
SKGTESTERROR(QStringLiteral("NOD:addNode"), node1.addNode(node2), true)
SKGTESTERROR(QStringLiteral("NOD:setAttribute"), node2.setAttribute(QStringLiteral("t_name"), QStringLiteral("node2")), true)
SKGTESTERROR(QStringLiteral("NOD:save"), node2.save(), true)
SKGTEST(QStringLiteral("NOD:getAttribute"), node2.getAttribute(QStringLiteral("rd_node_id.(v_node)t_name")), QStringLiteral("Abc def"))
SKGTEST(QStringLiteral("NOD:getAttribute"), node2.getAttribute(QStringLiteral("rd_node_id.(v_node)p_prop")), QStringLiteral("prop on node 1"))
SKGTEST(QStringLiteral("NOD:getAttribute"), node2.getAttribute(QStringLiteral("rd_node_id.t_name")), QStringLiteral("Abc def"))
SKGTEST(QStringLiteral("NOD:getAttribute"), node2.getAttribute(QStringLiteral("rd_node_id.p_prop")), QStringLiteral("prop on node 1"))
SKGNodeObject node3;
SKGTESTERROR(QStringLiteral("NOD:addNode"), node2.addNode(node3), true)
SKGTESTERROR(QStringLiteral("NOD:setAttribute"), node3.setAttribute(QStringLiteral("t_name"), QStringLiteral("node3")), true)
SKGTESTERROR(QStringLiteral("NOD:save"), node3.save(), true)
SKGTEST(QStringLiteral("NOD:getAttribute"), node3.getAttribute(QStringLiteral("rd_node_id.(v_node)t_name")), QStringLiteral("node2"))
SKGTEST(QStringLiteral("NOD:getAttribute"), node3.getAttribute(QStringLiteral("rd_node_id.(v_node)p_prop")), QLatin1String(""))
SKGTEST(QStringLiteral("NOD:getAttribute"), node3.getAttribute(QStringLiteral("rd_node_id.t_name")), QStringLiteral("node2"))
SKGTEST(QStringLiteral("NOD:getAttribute"), node3.getAttribute(QStringLiteral("rd_node_id.p_prop")), QLatin1String(""))
SKGTEST(QStringLiteral("NOD:getAttribute"), node3.getAttribute(QStringLiteral("rd_node_id.(v_node)rd_node_id.(v_node)t_name")), QStringLiteral("Abc def"))
SKGTEST(QStringLiteral("NOD:getAttribute"), node3.getAttribute(QStringLiteral("rd_node_id.(v_node)rd_node_id.(v_node)p_prop")), QStringLiteral("prop on node 1"))
SKGTEST(QStringLiteral("NOD:getAttribute"), node3.getAttribute(QStringLiteral("rd_node_id.rd_node_id.t_name")), QStringLiteral("Abc def"))
SKGTEST(QStringLiteral("NOD:getAttribute"), node3.getAttribute(QStringLiteral("rd_node_id.rd_node_id.p_prop")), QStringLiteral("prop on node 1"))
}
}
// End test
SKGENDTEST()
}
diff --git a/tests/skgbasemodelertest/skgtestpassword.cpp b/tests/skgbasemodelertest/skgtestpassword.cpp
index f7b17dbd2..2db6ebddf 100644
--- a/tests/skgbasemodelertest/skgtestpassword.cpp
+++ b/tests/skgbasemodelertest/skgtestpassword.cpp
@@ -1,48 +1,48 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is a test script.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgtestmacro.h"
/**
* The main function of the unit test
* @param argc the number of arguments
* @param argv the list of arguments
*/
int main(int argc, char** argv)
{
Q_UNUSED(argc)
Q_UNUSED(argv)
// Init test
SKGINITTEST(true)
QString filenameInput1 = SKGTest::getTestPath(QStringLiteral("IN")) % "/all_plugins.skg";
QString filenameOutput1 = SKGTest::getTestPath(QStringLiteral("OUT")) % "/all_plugins_encrypted.skg";
QString filenameOutput2 = SKGTest::getTestPath(QStringLiteral("OUT")) % "/all_plugins_decrypted.skg";
bool mode;
SKGTESTERROR(QStringLiteral("DOC:cryptFile"), SKGServices::cryptFile(QStringLiteral("notfound"), filenameOutput1, QStringLiteral("password"), true, QStringLiteral("SKROOGE"), mode), false)
SKGTESTERROR(QStringLiteral("DOC:cryptFile"), SKGServices::cryptFile(filenameInput1, filenameOutput1, QStringLiteral("password"), true, QStringLiteral("SKROOGE"), mode), true)
SKGTESTERROR(QStringLiteral("DOC:cryptFile"), SKGServices::cryptFile(filenameOutput1, filenameOutput2, QStringLiteral("password"), false, QStringLiteral("SKROOGE"), mode), true)
SKGTESTERROR(QStringLiteral("DOC:cryptFile"), SKGServices::cryptFile(QStringLiteral("notfound"), filenameOutput1, QStringLiteral("password"), false, QStringLiteral("SKROOGE"), mode), false)
// End test
SKGENDTEST()
}
diff --git a/tests/skgbasemodelertest/skgtestperfo.cpp b/tests/skgbasemodelertest/skgtestperfo.cpp
index d4381780c..9a3f60e28 100644
--- a/tests/skgbasemodelertest/skgtestperfo.cpp
+++ b/tests/skgbasemodelertest/skgtestperfo.cpp
@@ -1,55 +1,55 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is a test script.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgtestmacro.h"
/**
* The main function of the unit test
* @param argc the number of arguments
* @param argv the list of arguments
*/
int main(int argc, char** argv)
{
Q_UNUSED(argc)
Q_UNUSED(argv)
// Init test
SKGINITTEST(true)
// Test inserts
{
SKGDocument document1;
SKGTESTERROR(QStringLiteral("document1.initialize()"), document1.initialize(), true)
SKGError err;
{
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("INSERT"), err)
for (int i = 0; i < 10000; ++i) {
QString v = QString::number(i);
SKGTESTERROR(QStringLiteral("PARAM:setParameter"), document1.setParameter(v, v), true)
SKGTEST(QStringLiteral("PARAM:getParameter"), document1.getParameter(v), v)
}
}
}
// End test
SKGENDTEST()
}
diff --git a/tests/skgbasemodelertest/skgtestreport.cpp b/tests/skgbasemodelertest/skgtestreport.cpp
index 5215ecc8e..45825c4a6 100644
--- a/tests/skgbasemodelertest/skgtestreport.cpp
+++ b/tests/skgbasemodelertest/skgtestreport.cpp
@@ -1,59 +1,59 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is a test script.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgtestmacro.h"
#include "skgreport.h"
/**
* The main function of the unit test
* @param argc the number of arguments
* @param argv the list of arguments
*/
int main(int argc, char** argv)
{
Q_UNUSED(argc)
Q_UNUSED(argv)
// Init test
SKGINITTEST(true)
SKGDocument document1;
SKGTESTERROR(QStringLiteral("PARAM:initialize"), document1.initialize(), true)
SKGReport* rep = document1.getReport();
rep->getPeriod();
rep->setPeriod(QStringLiteral("2013-01"));
rep->getPrevious();
SKGTEST(QStringLiteral("REP:getMonth"), rep->getPeriod(), QStringLiteral("2013-01"))
SKGTEST(QStringLiteral("REP:getPreviousMonth"), rep->getPreviousPeriod(), QStringLiteral("2012-12"))
QString html;
SKGTESTERROR(QStringLiteral("REP:getReportFromTemplate"), SKGReport::getReportFromTemplate(rep, SKGTest::getTestPath(QStringLiteral("IN")) % "/missing.txt", html), false)
rep->getPrevious();
rep->setPeriod(QStringLiteral("2013-02"));
rep->cleanCache();
delete rep;
// End test
SKGENDTEST()
}
diff --git a/tests/skgbasemodelertest/skgtesttransaction.cpp b/tests/skgbasemodelertest/skgtesttransaction.cpp
index 485e19bd8..06817ba28 100644
--- a/tests/skgbasemodelertest/skgtesttransaction.cpp
+++ b/tests/skgbasemodelertest/skgtesttransaction.cpp
@@ -1,581 +1,581 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is a test script.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgtestmacro.h"
/**
* To check the progress
*/
static int previousProgress = 0;
/**
* To test progress
* @param iPos the current position
* @return 0
*/
int progress1(int iPos, qint64 /*iTime*/, const QString& /*iName*/, void* /*iData*/)
{
if (previousProgress > iPos) {
return 1;
}
previousProgress = iPos;
return 0;
}
/**
* To test progress
* @param iPos the current position
* @return 1
*/
int progress2(int iPos, qint64 /*iTime*/, const QString& /*iName*/, void* /*iData*/)
{
if (iPos > 50) {
return 1;
}
return 0;
}
/**
* The main function of the unit test
* @param argc the number of arguments
* @param argv the list of arguments
*/
int main(int argc, char** argv)
{
Q_UNUSED(argc)
Q_UNUSED(argv)
// Init test
SKGINITTEST(true)
// test class SKGDocument / COMMIT / ROLLBACK
{
SKGDocument document1;
SKGTEST(QStringLiteral("TRANS.getDepthTransaction"), document1.getDepthTransaction(), 0)
SKGTESTERROR(QStringLiteral("TRANS.beginTransaction(transaction1)"), document1.beginTransaction(QStringLiteral("transaction1")), false)
SKGTEST(QStringLiteral("TRANS.getDepthTransaction"), document1.getDepthTransaction(), 0)
SKGTESTERROR(QStringLiteral("TRANS.initialize"), document1.initialize(), true)
SKGTEST(QStringLiteral("TRANS.getDepthTransaction"), document1.getDepthTransaction(), 0)
SKGTESTERROR(QStringLiteral("TRANS.beginTransaction(transaction1)"), document1.beginTransaction(QStringLiteral("transaction1")), true)
SKGTEST(QStringLiteral("TRANS.getDepthTransaction"), document1.getDepthTransaction(), 1)
SKGTESTERROR(QStringLiteral("TRANS.endTransaction"), document1.endTransaction(false), true)
SKGTEST(QStringLiteral("TRANS.getDepthTransaction"), document1.getDepthTransaction(), 0)
SKGTESTERROR(QStringLiteral("TRANS.beginTransaction(transaction2)"), document1.beginTransaction(QStringLiteral("transaction2")), true)
SKGTEST(QStringLiteral("TRANS.getDepthTransaction"), document1.getDepthTransaction(), 1)
SKGTESTERROR(QStringLiteral("TRANS.setParameter"), document1.setParameter(QStringLiteral("ATT1"), QStringLiteral("VAL1")), true)
SKGTESTERROR(QStringLiteral("TRANS.endTransaction"), document1.endTransaction(true), true)
SKGTEST(QStringLiteral("TRANS.getDepthTransaction"), document1.getDepthTransaction(), 0)
SKGTESTERROR(QStringLiteral("TRANS.endTransaction TOO MANY !"), document1.endTransaction(true), false)
SKGTEST(QStringLiteral("TRANS.getDepthTransaction"), document1.getDepthTransaction(), 0)
// Test rollback
SKGTESTERROR(QStringLiteral("TRANS.beginTransaction"), document1.beginTransaction(QStringLiteral("transaction3")), true)
SKGTESTERROR(QStringLiteral("TRANS.setParameter"), document1.setParameter(QStringLiteral("ATT1"), QStringLiteral("VAL2")), true)
SKGTESTERROR(QStringLiteral("TRANS.endTransaction"), document1.endTransaction(false), true)
SKGTEST(QStringLiteral("TRANS.getParameter"), document1.getParameter(QStringLiteral("ATT1")), QStringLiteral("VAL1"))
// Test multi transaction in cascade
SKGTEST(QStringLiteral("TRANS.getDepthTransaction"), document1.getDepthTransaction(), 0)
SKGTESTERROR(QStringLiteral("TRANS.beginTransaction"), document1.beginTransaction(QStringLiteral("transaction4")), true)
SKGTEST(QStringLiteral("TRANS.getDepthTransaction"), document1.getDepthTransaction(), 1)
SKGTESTERROR(QStringLiteral("TRANS.beginTransaction"), document1.beginTransaction(QStringLiteral("transaction'5")), true)
SKGTEST(QStringLiteral("TRANS.getDepthTransaction"), document1.getDepthTransaction(), 2)
SKGTESTERROR(QStringLiteral("TRANS.setParameter"), document1.setParameter(QStringLiteral("ATT1"), QStringLiteral("VAL2")), true)
SKGTESTERROR(QStringLiteral("TRANS.endTransaction"), document1.endTransaction(false), true)
SKGTEST(QStringLiteral("TRANS.getDepthTransaction"), document1.getDepthTransaction(), 1)
SKGTEST(QStringLiteral("TRANS.getParameter"), document1.getParameter(QStringLiteral("ATT1")), QStringLiteral("VAL2"))
SKGTESTERROR(QStringLiteral("TRANS.endTransaction"), document1.endTransaction(false), true)
SKGTEST(QStringLiteral("TRANS.getDepthTransaction"), document1.getDepthTransaction(), 0)
SKGTEST(QStringLiteral("TRANS.getParameter"), document1.getParameter(QStringLiteral("ATT1")), QStringLiteral("VAL1"))
SKGPropertyObject prop(&document1);
SKGTESTERROR(QStringLiteral("PROP.getParameter"), prop.setName(QStringLiteral("ATT1")), true)
SKGTESTERROR(QStringLiteral("PROP.load"), prop.load(), true)
SKGTEST(QStringLiteral("PROP.getValue"), prop.getValue(), QStringLiteral("VAL1"))
prop.getParentId();
SKGPropertyObject prop2(prop);
SKGPropertyObject prop3(static_cast<SKGObjectBase>(prop));
SKGPropertyObject prop4;
prop4 = static_cast<SKGObjectBase>(prop);
}
// test class SKGDocument / COMMIT / ROLLBACK with SKGTransactionMng
{
// Test with a succeeded transaction
SKGError err;
SKGDocument document1;
SKGTESTERROR(QStringLiteral("TRANSMNG.initialize()"), document1.initialize(), true)
SKGTEST(QStringLiteral("TRANSMNG.getNbTransaction"), document1.getNbTransaction(), 0) {
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("T1"), err)
// The code here
IFOK(err) {
SKGTEST(QStringLiteral("TRANSMNG.getDepthTransaction"), document1.getDepthTransaction(), 1)
// Example; an error is generated
err = SKGError(1, QStringLiteral("Error1"));
}
// A rollback is done here because the scope is close
}
SKGTESTERROR(QStringLiteral("TRANSMNG.err"), err, false)
SKGTEST(QStringLiteral("TRANSMNG.getNbTransaction"), document1.getNbTransaction(), 0)
SKGTEST(QStringLiteral("TRANSMNG.getDepthTransaction"), document1.getDepthTransaction(), 0)
}
{
// Test with a succeeded transaction
SKGError err;
SKGDocument document1;
SKGTESTERROR(QStringLiteral("TRANSMNG.initialize()"), document1.initialize(), true)
SKGTEST(QStringLiteral("TRANSMNG.getNbTransaction"), document1.getNbTransaction(), 0) {
// Scope of the transaction
SKGBEGINTRANSACTION(document1, QStringLiteral("T1"), err)
// The code here
IFOK(err) {
SKGTEST(QStringLiteral("TRANSMNG.getDepthTransaction"), document1.getDepthTransaction(), 1)
// Example; operation succeeded
SKGTESTERROR(QStringLiteral("TRANS.setParameter"), document1.setParameter(QStringLiteral("ATT1"), QStringLiteral("VAL2")), true)
}
// A commit is done here because the scope is close
}
SKGTESTERROR(QStringLiteral("TRANSMNG.err"), err, true)
SKGTEST(QStringLiteral("TRANSMNG.getNbTransaction"), document1.getNbTransaction(), 1)
SKGTEST(QStringLiteral("TRANSMNG.getDepthTransaction"), document1.getDepthTransaction(), 0)
}
{
// Test undo on parameters
SKGDocument document1;
SKGTESTERROR(QStringLiteral("TRANSUNDO.initialize()"), document1.initialize(), true)
SKGError err;
SKGTEST(QStringLiteral("TRANSUNDO.getParameter"), document1.getParameter(QStringLiteral("ATT1")), QLatin1String(""))
{
// In a scope to the then endTransaction automatically
SKGBEGINTRANSACTION(document1, QStringLiteral("T1"), err)
SKGTESTERROR(QStringLiteral("TRANSUNDO.setParameter"), document1.setParameter(QStringLiteral("ATT1"), QStringLiteral("VAL1_1")), true) // To test undo on more than one modification of an object in a transaction
SKGTESTERROR(QStringLiteral("TRANSUNDO.setParameter"), document1.setParameter(QStringLiteral("ATT1"), QStringLiteral("VAL1_2")), true) // To test undo on more than one modification of an object in a transaction
SKGTESTERROR(QStringLiteral("TRANSUNDO.setParameter"), document1.setParameter(QStringLiteral("ATT1"), QStringLiteral("VAL1")), true)
}
SKGTEST(QStringLiteral("TRANSUNDO.getParameter"), document1.getParameter(QStringLiteral("ATT1")), QStringLiteral("VAL1"))
SKGTEST(QStringLiteral("TRANSUNDO.getNbTransaction"), document1.getNbTransaction(), 1)
SKGTEST(QStringLiteral("TRANSUNDO.getNbTransaction(SKGDocument::REDO))"), document1.getNbTransaction(SKGDocument::REDO), 0)
{
// In a scope to the then endTransaction automatically
SKGBEGINTRANSACTION(document1, QStringLiteral("T2"), err)
SKGTESTERROR(QStringLiteral("TRANSUNDO.setParameter"), document1.setParameter(QStringLiteral("ATT1"), QStringLiteral("VAL2_1")), true) // To test undo on more than one modification of an object in a transaction
SKGTESTERROR(QStringLiteral("TRANSUNDO.setParameter"), document1.setParameter(QStringLiteral("ATT1"), QStringLiteral("VAL2_2")), true) // To test undo on more than one modification of an object in a transaction
SKGTESTERROR(QStringLiteral("TRANSUNDO.setParameter"), document1.setParameter(QStringLiteral("ATT1"), QStringLiteral("VAL2")), true)
}
SKGTEST(QStringLiteral("TRANSUNDO.getParameter"), document1.getParameter(QStringLiteral("ATT1")), QStringLiteral("VAL2"))
SKGTEST(QStringLiteral("TRANSUNDO.getNbTransaction"), document1.getNbTransaction(), 2)
SKGTEST(QStringLiteral("TRANSUNDO.getNbTransaction(SKGDocument::REDO))"), document1.getNbTransaction(SKGDocument::REDO), 0)
QStringList oResult;
int nbitemexpected = 6;
SKGTESTERROR(QStringLiteral("TRANSUNDO.getDistinctValues"), document1.getDistinctValues(QStringLiteral("doctransactionitem"), QStringLiteral("id"), oResult), true)
SKGTEST(QStringLiteral("TRANSUNDO.oResult.size"), oResult.size(), nbitemexpected)
SKGTESTERROR(QStringLiteral("TRANSUNDO.undoRedoTransaction(T2, SKGDocument::UNDO)"), document1.undoRedoTransaction(), true)
SKGTEST(QStringLiteral("TRANSUNDO.getParameter"), document1.getParameter(QStringLiteral("ATT1")), QStringLiteral("VAL1"))
SKGTEST(QStringLiteral("TRANSUNDO.getNbTransaction"), document1.getNbTransaction(), 1)
SKGTEST(QStringLiteral("TRANSUNDO.getNbTransaction(SKGDocument::REDO))"), document1.getNbTransaction(SKGDocument::REDO), 1)
SKGTESTERROR(QStringLiteral("TRANSUNDO.getDistinctValues"), document1.getDistinctValues(QStringLiteral("doctransactionitem"), QStringLiteral("id"), oResult), true)
SKGTEST(QStringLiteral("TRANSUNDO.oResult.size"), oResult.size(), nbitemexpected)
SKGTESTERROR(QStringLiteral("TRANSUNDO.undoRedoTransaction(T1, SKGDocument::UNDO)"), document1.undoRedoTransaction(), true)
SKGTEST(QStringLiteral("TRANSUNDO.getParameter"), document1.getParameter(QStringLiteral("ATT1")), QLatin1String(""))
SKGTEST(QStringLiteral("TRANSUNDO.getNbTransaction"), document1.getNbTransaction(), 0)
SKGTEST(QStringLiteral("TRANSUNDO.getNbTransaction(SKGDocument::REDO))"), document1.getNbTransaction(SKGDocument::REDO), 2)
SKGTESTERROR(QStringLiteral("TRANSUNDO.getDistinctValues"), document1.getDistinctValues(QStringLiteral("doctransactionitem"), QStringLiteral("id"), oResult), true)
SKGTEST(QStringLiteral("TRANSUNDO.oResult.size"), oResult.size(), nbitemexpected)
SKGTESTERROR(QStringLiteral("TRANSUNDO.undoRedoTransaction(T1, SKGDocument::REDO)"), document1.undoRedoTransaction(SKGDocument::REDO), true)
SKGTEST(QStringLiteral("TRANSUNDO.getParameter"), document1.getParameter(QStringLiteral("ATT1")), QStringLiteral("VAL1"))
SKGTEST(QStringLiteral("TRANSUNDO.getNbTransaction"), document1.getNbTransaction(), 1)
SKGTEST(QStringLiteral("TRANSUNDO.getNbTransaction(SKGDocument::REDO))"), document1.getNbTransaction(SKGDocument::REDO), 1)
SKGTESTERROR(QStringLiteral("TRANSUNDO.getDistinctValues"), document1.getDistinctValues(QStringLiteral("doctransactionitem"), QStringLiteral("id"), oResult), true)
SKGTEST(QStringLiteral("TRANSUNDO.oResult.size"), oResult.size(), nbitemexpected)
SKGTESTERROR(QStringLiteral("TRANSUNDO.undoRedoTransaction(T2, SKGDocument::REDO)"), document1.undoRedoTransaction(SKGDocument::REDO), true)
SKGTEST(QStringLiteral("TRANSUNDO.getParameter"), document1.getParameter(QStringLiteral("ATT1")), QStringLiteral("VAL2"))
SKGTEST(QStringLiteral("TRANSUNDO.getNbTransaction"), document1.getNbTransaction(), 2)
SKGTEST(QStringLiteral("TRANSUNDO.getNbTransaction(SKGDocument::REDO))"), document1.getNbTransaction(SKGDocument::REDO), 0)
SKGTESTERROR(QStringLiteral("TRANSUNDO.getDistinctValues"), document1.getDistinctValues(QStringLiteral("doctransactionitem"), QStringLiteral("id"), oResult), true)
SKGTEST(QStringLiteral("TRANSUNDO.oResult.size"), oResult.size(), nbitemexpected)
}
{
// Test max depth for transaction
SKGDocument document1;
SKGTESTERROR(QStringLiteral("MAXDEPTH.initialize()"), document1.initialize(), true)
SKGError err;
SKGTEST(QStringLiteral("MAXDEPTH.getNbTransaction"), document1.getNbTransaction(), 0) {
SKGBEGINTRANSACTION(document1, QStringLiteral("MAXDEPTH 1"), err)
SKGTESTERROR(QStringLiteral("MAXDEPTH.setParameter"), document1.setParameter(QStringLiteral("SKG_UNDO_MAX_DEPTH"), QStringLiteral("3")), true)
}
SKGTEST(QStringLiteral("MAXDEPTH.getNbTransaction"), document1.getNbTransaction(), 1) {
SKGBEGINTRANSACTION(document1, QStringLiteral("MAXDEPTH 2"), err)
SKGTESTERROR(QStringLiteral("TRANSUNDO.setParameter"), document1.setParameter(QStringLiteral("ATT"), QStringLiteral("VAL")), true)
}
SKGTESTERROR(QStringLiteral("MAXDEPTH.endTransaction"), err, true)
SKGTEST(QStringLiteral("MAXDEPTH.getNbTransaction"), document1.getNbTransaction(), 2) {
SKGBEGINTRANSACTION(document1, QStringLiteral("MAXDEPTH 3"), err)
SKGTESTERROR(QStringLiteral("TRANSUNDO.setParameter"), document1.setParameter(QStringLiteral("ATT"), QStringLiteral("VAL")), true)
}
SKGTESTERROR(QStringLiteral("MAXDEPTH.endTransaction"), err, true)
SKGTEST(QStringLiteral("MAXDEPTH.getNbTransaction"), document1.getNbTransaction(), 3) {
SKGBEGINTRANSACTION(document1, QStringLiteral("MAXDEPTH 4"), err)
SKGTESTERROR(QStringLiteral("TRANSUNDO.setParameter"), document1.setParameter(QStringLiteral("ATT"), QStringLiteral("VAL")), true)
}
SKGTESTERROR(QStringLiteral("MAXDEPTH.endTransaction"), err, true)
SKGTEST(QStringLiteral("MAXDEPTH.getNbTransaction"), document1.getNbTransaction(), 3) {
SKGBEGINTRANSACTION(document1, QStringLiteral("MAXDEPTH 5"), err)
SKGTESTERROR(QStringLiteral("TRANSUNDO.setParameter"), document1.setParameter(QStringLiteral("ATT"), QStringLiteral("VAL")), true)
SKGTESTERROR(QStringLiteral("TRANSUNDO.setParameter"), document1.setParameter(QStringLiteral("ATT5"), QStringLiteral("VAL")), true)
}
SKGTESTERROR(QStringLiteral("MAXDEPTH.endTransaction"), err, true)
SKGTEST(QStringLiteral("MAXDEPTH.getNbTransaction"), document1.getNbTransaction(), 3)
SKGDocument::SKGObjectModificationList oModifications;
SKGTESTERROR(QStringLiteral("MAXDEPTH.getModifications"), document1.getModifications(document1.getTransactionToProcess(SKGDocument::UNDO), oModifications), true)
SKGTEST(QStringLiteral("MAXDEPTH.oModifications.count"), oModifications.count(), 2)
SKGTEST(QStringLiteral("MAXDEPTH.oModifications.id"), oModifications[0].id, 7)
SKGTEST(QStringLiteral("MAXDEPTH.oModifications.table"), oModifications[0].table, QStringLiteral("parameters"))
SKGTEST(QStringLiteral("MAXDEPTH.oModifications.type"), static_cast<unsigned int>(oModifications[0].type), static_cast<unsigned int>(SKGDocument::U))
SKGTEST(QStringLiteral("MAXDEPTH.oModifications.id"), oModifications[1].id, 8)
SKGTEST(QStringLiteral("MAXDEPTH.oModifications.table"), oModifications[1].table, QStringLiteral("parameters"))
SKGTEST(QStringLiteral("MAXDEPTH.oModifications.type"), static_cast<unsigned int>(oModifications[1].type), static_cast<unsigned int>(SKGDocument::I))
}
{
// Redo delete after new transaction
SKGDocument document1;
SKGTESTERROR(QStringLiteral("REDO.initialize()"), document1.initialize(), true)
SKGError err;
SKGTEST(QStringLiteral("REDO.getNbTransaction"), document1.getNbTransaction(), 0) {
SKGBEGINTRANSACTION(document1, QStringLiteral("SKGDocument::REDO 1"), err)
SKGTESTERROR(QStringLiteral("REDO.setParameter"), document1.setParameter(QStringLiteral("ATT"), QStringLiteral("VAL")), true)
}
{
SKGBEGINTRANSACTION(document1, QStringLiteral("SKGDocument::REDO 2"), err)
SKGTESTERROR(QStringLiteral("REDO.setParameter"), document1.setParameter(QStringLiteral("ATT"), QStringLiteral("VAL")), true)
}
{
SKGBEGINTRANSACTION(document1, QStringLiteral("SKGDocument::REDO 3"), err)
SKGTESTERROR(QStringLiteral("REDO.setParameter"), document1.setParameter(QStringLiteral("ATT"), QStringLiteral("VAL")), true)
}
{
SKGBEGINTRANSACTION(document1, QStringLiteral("SKGDocument::REDO 4"), err)
SKGTESTERROR(QStringLiteral("REDO.setParameter"), document1.setParameter(QStringLiteral("ATT"), QStringLiteral("VAL")), true)
}
SKGTEST(QStringLiteral("REDO.getNbTransaction"), document1.getNbTransaction(), 4)
SKGTEST(QStringLiteral("REDO.getNbTransaction"), document1.getNbTransaction(SKGDocument::REDO), 0)
SKGTESTERROR(QStringLiteral("REDO.undoRedoTransaction"), document1.undoRedoTransaction(), true)
SKGTEST(QStringLiteral("REDO.getNbTransaction"), document1.getNbTransaction(), 3)
SKGTEST(QStringLiteral("REDO.getNbTransaction"), document1.getNbTransaction(SKGDocument::REDO), 1)
SKGTESTERROR(QStringLiteral("REDO.undoRedoTransaction"), document1.undoRedoTransaction(), true)
SKGTEST(QStringLiteral("REDO.getNbTransaction"), document1.getNbTransaction(), 2)
SKGTEST(QStringLiteral("REDO.getNbTransaction"), document1.getNbTransaction(SKGDocument::REDO), 2)
SKGTESTERROR(QStringLiteral("REDO.undoRedoTransaction"), document1.undoRedoTransaction(SKGDocument::REDO), true)
SKGTEST(QStringLiteral("REDO.getNbTransaction"), document1.getNbTransaction(), 3)
SKGTEST(QStringLiteral("REDO.getNbTransaction"), document1.getNbTransaction(SKGDocument::REDO), 1)
SKGTESTERROR(QStringLiteral("REDO.undoRedoTransaction"), document1.undoRedoTransaction(), true)
SKGTEST(QStringLiteral("REDO.getNbTransaction"), document1.getNbTransaction(), 2)
SKGTEST(QStringLiteral("REDO.getNbTransaction"), document1.getNbTransaction(SKGDocument::REDO), 2)
{
SKGBEGINTRANSACTION(document1, QStringLiteral("SKGDocument::REDO 5"), err)
SKGTESTERROR(QStringLiteral("REDO.setParameter"), document1.setParameter(QStringLiteral("ATT"), QStringLiteral("VAL")), true)
}
SKGTEST(QStringLiteral("REDO.getNbTransaction"), document1.getNbTransaction(), 3)
SKGTEST(QStringLiteral("REDO.getNbTransaction"), document1.getNbTransaction(SKGDocument::REDO), 0)
SKGTESTERROR(QStringLiteral("REDO.undoRedoTransaction"), document1.undoRedoTransaction(SKGDocument::UNDOLASTSAVE), true)
SKGTEST(QStringLiteral("REDO.getNbTransaction"), document1.getNbTransaction(), 0)
SKGTEST(QStringLiteral("REDO.getNbTransaction"), document1.getNbTransaction(SKGDocument::REDO), 1)
}
{
// Test progress
SKGDocument document1;
SKGTESTERROR(QStringLiteral("PROGRESS.initialize()"), document1.initialize(), true)
SKGTESTERROR(QStringLiteral("PROGRESS.setProgressCallback"), document1.setProgressCallback(&progress1, nullptr), true)
SKGTESTERROR(QStringLiteral("PROGRESS.beginTransaction"), document1.beginTransaction(QStringLiteral("PROGRESS1"), 5), true)
for (int i = 1; i <= 5; ++i) {
SKGTESTERROR(QStringLiteral("PROGRESS.stepForward"), document1.stepForward(i), true)
SKGTESTERROR(QStringLiteral("PROGRESS.beginTransaction"), document1.beginTransaction(QStringLiteral("PROGRESS2"), 3), true)
for (int j = 1; j <= 3; j++) {
SKGTESTERROR(QStringLiteral("PROGRESS.stepForward"), document1.stepForward(j), true)
}
SKGTESTERROR(QStringLiteral("PROGRESS.endTransaction"), document1.endTransaction(true), true)
}
SKGTESTERROR(QStringLiteral("PROGRESS.endTransaction"), document1.endTransaction(true), true)
SKGTESTERROR(QStringLiteral("PROGRESS.setProgressCallback"), document1.setProgressCallback(&progress2, nullptr), true)
SKGTESTERROR(QStringLiteral("PROGRESS.beginTransaction"), document1.beginTransaction(QStringLiteral("PROGRESS1"), 5), true)
for (int i = 1; i <= 5; ++i) {
SKGTESTERROR(QStringLiteral("PROGRESS.stepForward"), document1.stepForward(i), (i < 3))
SKGTESTERROR(QStringLiteral("PROGRESS.beginTransaction"), document1.beginTransaction(QStringLiteral("PROGRESS2"), 3), (i < 3))
for (int j = 1; j <= 3; j++) {
SKGTESTERROR(QStringLiteral("PROGRESS.stepForward"), document1.stepForward(j), (3 * i + j - 3 < 5))
}
SKGTESTERROR(QStringLiteral("PROGRESS.endTransaction"), document1.endTransaction(true), true)
}
SKGTESTERROR(QStringLiteral("PROGRESS.endTransaction"), document1.endTransaction(true), true)
}
{
// Test progress
SKGDocument document1;
SKGTESTERROR(QStringLiteral("PROGRESS.initialize()"), document1.initialize(), true)
SKGTESTERROR(QStringLiteral("PROGRESS.beginTransaction"), document1.beginTransaction(QStringLiteral("T1")), true)
SKGTESTERROR(QStringLiteral("PROGRESS.setParameter"), document1.setParameter(QStringLiteral("ATT"), QStringLiteral("VAL")), true)
SKGTESTERROR(QStringLiteral("PROGRESS.endTransaction"), document1.endTransaction(true), true)
SKGTEST(QStringLiteral("PROGRESS.getNbTransaction"), document1.getNbTransaction(), 1)
SKGTESTERROR(QStringLiteral("PROGRESS.beginTransaction"), document1.beginTransaction(QStringLiteral("T2")), true)
SKGTESTERROR(QStringLiteral("PROGRESS.setParameter"), document1.setParameter(QStringLiteral("ATT"), QStringLiteral("VAL")), true)
SKGTESTERROR(QStringLiteral("PROGRESS.endTransaction"), document1.endTransaction(true), true)
SKGTEST(QStringLiteral("PROGRESS.getNbTransaction"), document1.getNbTransaction(), 2)
SKGTESTERROR(QStringLiteral("PROGRESS.beginTransaction"), document1.beginTransaction(QStringLiteral("T3")), true)
SKGTESTERROR(QStringLiteral("PROGRESS.setParameter"), document1.setParameter(QStringLiteral("ATT"), QStringLiteral("VAL")), true)
SKGTESTERROR(QStringLiteral("PROGRESS.endTransaction"), document1.endTransaction(false), true)
SKGTEST(QStringLiteral("PROGRESS.getNbTransaction"), document1.getNbTransaction(), 2)
// Transaction failed with existing name
SKGTESTERROR(QStringLiteral("PROGRESS.beginTransaction"), document1.beginTransaction(QStringLiteral("T2")), true)
SKGTESTERROR(QStringLiteral("PROGRESS.setParameter"), document1.setParameter(QStringLiteral("ATT"), QStringLiteral("VAL")), true)
SKGTESTERROR(QStringLiteral("PROGRESS.endTransaction"), document1.endTransaction(false), true)
SKGTEST(QStringLiteral("PROGRESS.getNbTransaction"), document1.getNbTransaction(), 2)
}
{
// Test group of transactions on U
SKGDocument document1;
SKGTESTERROR(QStringLiteral("GROUP.initialize()"), document1.initialize(), true)
SKGTESTERROR(QStringLiteral("GROUP.beginTransaction"), document1.beginTransaction(QStringLiteral("T1")), true)
SKGTESTERROR(QStringLiteral("GROUP.setParameter"), document1.setParameter(QStringLiteral("ATT"), QStringLiteral("VAL1")), true)
SKGTESTERROR(QStringLiteral("GROUP.endTransaction"), document1.endTransaction(true), true)
SKGTESTERROR(QStringLiteral("GROUP.beginTransaction"), document1.beginTransaction(QStringLiteral("T2")), true)
SKGTESTERROR(QStringLiteral("GROUP.setParameter"), document1.setParameter(QStringLiteral("ATT"), QStringLiteral("VAL2")), true)
SKGTESTERROR(QStringLiteral("GROUP.endTransaction"), document1.endTransaction(true), true)
SKGTESTERROR(QStringLiteral("GROUP.beginTransaction"), document1.beginTransaction(QStringLiteral("T3")), true)
SKGTESTERROR(QStringLiteral("GROUP.setParameter"), document1.setParameter(QStringLiteral("ATT"), QStringLiteral("VAL3")), true)
SKGTESTERROR(QStringLiteral("GROUP.endTransaction"), document1.endTransaction(true), true)
SKGTESTERROR(QStringLiteral("GROUP.beginTransaction"), document1.beginTransaction(QStringLiteral("T4")), true)
SKGTESTERROR(QStringLiteral("GROUP.setParameter"), document1.setParameter(QStringLiteral("ATT"), QStringLiteral("VAL4")), true)
SKGTESTERROR(QStringLiteral("GROUP.endTransaction"), document1.endTransaction(true), true)
SKGTESTERROR(QStringLiteral("GROUP.groupTransactions("), document1.groupTransactions(3, 5), true)
SKGTEST(QStringLiteral("GROUP.getNbTransaction"), document1.getNbTransaction(), 2)
SKGTESTERROR(QStringLiteral("GROUP.undoRedoTransaction"), document1.undoRedoTransaction(), true)
SKGTEST(QStringLiteral("GROUP.getParameter"), document1.getParameter(QStringLiteral("ATT")), QStringLiteral("VAL1"))
// Remove all transaction
SKGTEST(QStringLiteral("GROUP.getNbTransaction"), document1.getNbTransaction(SKGDocument::UNDO), 1)
SKGTEST(QStringLiteral("GROUP.getNbTransaction"), document1.getNbTransaction(SKGDocument::REDO), 1)
SKGTESTERROR(QStringLiteral("GROUP.removeAllTransactions"), document1.removeAllTransactions(), true)
SKGTEST(QStringLiteral("GROUP.getNbTransaction"), document1.getNbTransaction(SKGDocument::UNDO), 0)
SKGTEST(QStringLiteral("GROUP.getNbTransaction"), document1.getNbTransaction(SKGDocument::REDO), 0)
}
{
// Test group of transactions on R
SKGDocument document1;
SKGTESTERROR(QStringLiteral("GROUP.initialize()"), document1.initialize(), true)
SKGTESTERROR(QStringLiteral("GROUP.beginTransaction"), document1.beginTransaction(QStringLiteral("T1")), true)
SKGTESTERROR(QStringLiteral("GROUP.setParameter"), document1.setParameter(QStringLiteral("ATT"), QStringLiteral("VAL1")), true)
SKGTESTERROR(QStringLiteral("GROUP.endTransaction"), document1.endTransaction(true), true)
SKGTESTERROR(QStringLiteral("GROUP.beginTransaction"), document1.beginTransaction(QStringLiteral("T2")), true)
SKGTESTERROR(QStringLiteral("GROUP.setParameter"), document1.setParameter(QStringLiteral("ATT"), QStringLiteral("VAL2")), true)
SKGTESTERROR(QStringLiteral("GROUP.endTransaction"), document1.endTransaction(true), true)
SKGTESTERROR(QStringLiteral("GROUP.beginTransaction"), document1.beginTransaction(QStringLiteral("T3")), true)
SKGTESTERROR(QStringLiteral("GROUP.setParameter"), document1.setParameter(QStringLiteral("ATT"), QStringLiteral("VAL3")), true)
SKGTESTERROR(QStringLiteral("GROUP.endTransaction"), document1.endTransaction(true), true)
SKGTESTERROR(QStringLiteral("GROUP.beginTransaction"), document1.beginTransaction(QStringLiteral("T4")), true)
SKGTESTERROR(QStringLiteral("GROUP.setParameter"), document1.setParameter(QStringLiteral("ATT"), QStringLiteral("VAL4")), true)
SKGTESTERROR(QStringLiteral("GROUP.endTransaction"), document1.endTransaction(true), true)
SKGTESTERROR(QStringLiteral("GROUP.undoRedoTransaction"), document1.undoRedoTransaction(), true)
SKGTESTERROR(QStringLiteral("GROUP.undoRedoTransaction"), document1.undoRedoTransaction(), true)
SKGTESTERROR(QStringLiteral("GROUP.undoRedoTransaction"), document1.undoRedoTransaction(), true)
SKGTESTERROR(QStringLiteral("GROUP.undoRedoTransaction"), document1.undoRedoTransaction(), true)
SKGTESTERROR(QStringLiteral("GROUP.groupTransactions("), document1.groupTransactions(7, 9), true)
SKGTEST(QStringLiteral("GROUP.getNbTransaction"), document1.getNbTransaction(SKGDocument::REDO), 2)
// document1.dump(DUMPTRANSACTIONS);
SKGTESTERROR(QStringLiteral("GROUP.undoRedoTransaction"), document1.undoRedoTransaction(SKGDocument::REDO), true)
SKGTEST(QStringLiteral("GROUP.getParameter"), document1.getParameter(QStringLiteral("ATT")), QStringLiteral("VAL3"))
}
{
// Test group of transactions on U and R
SKGDocument document1;
SKGTESTERROR(QStringLiteral("GROUP.initialize()"), document1.initialize(), true)
SKGTESTERROR(QStringLiteral("GROUP.beginTransaction"), document1.beginTransaction(QStringLiteral("T1")), true)
SKGTESTERROR(QStringLiteral("GROUP.setParameter"), document1.setParameter(QStringLiteral("ATT"), QStringLiteral("VAL1")), true)
SKGTESTERROR(QStringLiteral("GROUP.endTransaction"), document1.endTransaction(true), true)
SKGTESTERROR(QStringLiteral("GROUP.beginTransaction"), document1.beginTransaction(QStringLiteral("T2")), true)
SKGTESTERROR(QStringLiteral("GROUP.setParameter"), document1.setParameter(QStringLiteral("ATT"), QStringLiteral("VAL2")), true)
SKGTESTERROR(QStringLiteral("GROUP.endTransaction"), document1.endTransaction(true), true)
SKGTESTERROR(QStringLiteral("GROUP.beginTransaction"), document1.beginTransaction(QStringLiteral("T3")), true)
SKGTESTERROR(QStringLiteral("GROUP.setParameter"), document1.setParameter(QStringLiteral("ATT"), QStringLiteral("VAL3")), true)
SKGTESTERROR(QStringLiteral("GROUP.endTransaction"), document1.endTransaction(true), true)
SKGTESTERROR(QStringLiteral("GROUP.beginTransaction"), document1.beginTransaction(QStringLiteral("T4")), true)
SKGTESTERROR(QStringLiteral("GROUP.setParameter"), document1.setParameter(QStringLiteral("ATT"), QStringLiteral("VAL4")), true)
SKGTESTERROR(QStringLiteral("GROUP.endTransaction"), document1.endTransaction(true), true)
SKGTESTERROR(QStringLiteral("GROUP.undoRedoTransaction"), document1.undoRedoTransaction(), true)
SKGTESTERROR(QStringLiteral("GROUP.undoRedoTransaction"), document1.undoRedoTransaction(), true)
SKGTESTERROR(QStringLiteral("GROUP.groupTransactions("), document1.groupTransactions(3, 6), false)
// document1.dump(DUMPTRANSACTIONS);
SKGTEST(QStringLiteral("GROUP.getNbTransaction"), document1.getNbTransaction(SKGDocument::UNDO), 2)
SKGTEST(QStringLiteral("GROUP.getNbTransaction"), document1.getNbTransaction(SKGDocument::REDO), 2)
}
{
// Test group of transactions on R
SKGDocument document1;
SKGTESTERROR(QStringLiteral("GROUP.initialize()"), document1.initialize(), true)
SKGTESTERROR(QStringLiteral("GROUP.beginTransaction"), document1.beginTransaction(QStringLiteral("T1")), true)
SKGTESTERROR(QStringLiteral("GROUP.setParameter"), document1.setParameter(QStringLiteral("ATT"), QStringLiteral("VAL1")), true)
SKGTESTERROR(QStringLiteral("GROUP.endTransaction"), document1.endTransaction(true), true)
SKGTESTERROR(QStringLiteral("GROUP.beginTransaction"), document1.beginTransaction(QStringLiteral("T2")), true)
SKGTESTERROR(QStringLiteral("GROUP.setParameter"), document1.setParameter(QStringLiteral("ATT"), QStringLiteral("VAL2")), true)
SKGTESTERROR(QStringLiteral("GROUP.endTransaction"), document1.endTransaction(true), true)
QString filename1 = SKGTest::getTestPath(QStringLiteral("OUT")) % "/filename1.skg";
SKGTESTERROR(QStringLiteral("GROUP.saveAs"), document1.saveAs(filename1, true), true)
SKGTESTERROR(QStringLiteral("GROUP.beginTransaction"), document1.beginTransaction(QStringLiteral("T3")), true)
SKGTESTERROR(QStringLiteral("GROUP.setParameter"), document1.setParameter(QStringLiteral("ATT"), QStringLiteral("VAL3")), true)
SKGTESTERROR(QStringLiteral("GROUP.endTransaction"), document1.endTransaction(true), true)
SKGTESTERROR(QStringLiteral("GROUP.beginTransaction"), document1.beginTransaction(QStringLiteral("T4")), true)
SKGTESTERROR(QStringLiteral("GROUP.setParameter"), document1.setParameter(QStringLiteral("ATT"), QStringLiteral("VAL4")), true)
SKGTESTERROR(QStringLiteral("GROUP.endTransaction"), document1.endTransaction(true), true)
document1.dump(DUMPTRANSACTIONS);
SKGTESTERROR(QStringLiteral("GROUP.undoRedoTransaction"), document1.undoRedoTransaction(SKGDocument::UNDOLASTSAVE), true)
SKGTEST(QStringLiteral("GROUP.getParameter"), document1.getParameter(QStringLiteral("ATT")), QStringLiteral("VAL2"))
SKGTESTERROR(QStringLiteral("GROUP.undoRedoTransaction"), document1.undoRedoTransaction(SKGDocument::REDO), true)
SKGTEST(QStringLiteral("GROUP.getParameter"), document1.getParameter(QStringLiteral("ATT")), QStringLiteral("VAL4"))
QStringList oResult;
SKGTESTERROR(QStringLiteral("SKGServices::dumpSelectSqliteOrder"), document1.dumpSelectSqliteOrder(QStringLiteral("SELECT * from doctransaction"), oResult), true)
SKGTESTERROR(QStringLiteral("SKGServices::dumpSelectSqliteOrder"), document1.dumpSelectSqliteOrder(QStringLiteral("SELECT * from doctransaction")), true)
}
{
// Test error
SKGDocument document1;
SKGTESTERROR(QStringLiteral("ERROR.initialize()"), document1.initialize(), true)
SKGTESTERROR(QStringLiteral("ERROR.undoRedoTransaction"), document1.undoRedoTransaction(SKGDocument::UNDO), false) // No transaction
SKGTESTERROR(QStringLiteral("ERROR.beginTransaction"), document1.beginTransaction(QStringLiteral("T1")), true)
SKGTEST(QStringLiteral("ERROR.getCurrentTransaction"), document1.getCurrentTransaction(), 2)
SKGTESTERROR(QStringLiteral("ERROR.groupTransactions"), document1.groupTransactions(1, 1), false) // Not authorized into a transaction
SKGTESTERROR(QStringLiteral("ERROR.undoRedoTransaction"), document1.undoRedoTransaction(SKGDocument::UNDO), false) // Not authorized into a transaction
SKGTESTERROR(QStringLiteral("ERROR.saveAs"), document1.saveAs(SKGTest::getTestPath(QStringLiteral("OUT")) % "/filename1.skg", true), false) // Not authorized into a transaction
SKGTESTERROR(QStringLiteral("ERROR.endTransaction"), document1.endTransaction(true), true)
}
{
// Test messages
SKGDocument document1;
SKGTESTERROR(QStringLiteral("MSG.initialize()"), document1.initialize(), true)
SKGTESTERROR(QStringLiteral("MSG.sendMessage"), document1.sendMessage(QStringLiteral("Information"), SKGDocument::Information), true)
SKGTESTERROR(QStringLiteral("MSG.sendMessage"), document1.sendMessage(QStringLiteral("Warning"), SKGDocument::Warning), true)
SKGTESTERROR(QStringLiteral("MSG.sendMessage"), document1.sendMessage(QStringLiteral("Positive"), SKGDocument::Positive), true)
SKGTESTERROR(QStringLiteral("MSG.sendMessage"), document1.sendMessage(QStringLiteral("Error"), SKGDocument::Error), true)
SKGTESTERROR(QStringLiteral("MSG.sendMessage"), document1.sendMessage(QStringLiteral("Hidden"), SKGDocument::Hidden), true)
SKGTESTERROR(QStringLiteral("MSG.beginTransaction"), document1.beginTransaction(QStringLiteral("T1")), true)
SKGTESTERROR(QStringLiteral("MSG.setParameter"), document1.setParameter(QStringLiteral("ATT"), QStringLiteral("VAL")), true)
SKGTESTERROR(QStringLiteral("MSG.sendMessage"), document1.sendMessage(QStringLiteral("Hello")), true)
SKGTESTERROR(QStringLiteral("MSG.sendMessage"), document1.sendMessage(QStringLiteral("World")), true)
SKGTESTERROR(QStringLiteral("MSG.endTransaction"), document1.endTransaction(true), true)
SKGDocument::SKGMessageList msg;
SKGTESTERROR(QStringLiteral("MSG.getMessages"), document1.getMessages(document1.getTransactionToProcess(SKGDocument::UNDO), msg), true)
SKGTEST(QStringLiteral("MSG.msg.count"), msg.count(), 6)
SKGTEST(QStringLiteral("MSG.msg"), msg.at(0).Text, QStringLiteral("Information")); SKGTEST(QStringLiteral("MSG.type"), static_cast<unsigned int>(msg.at(0).Type), static_cast<unsigned int>(SKGDocument::Information))
SKGTEST(QStringLiteral("MSG.msg"), msg.at(1).Text, QStringLiteral("Warning")); SKGTEST(QStringLiteral("MSG.type"), static_cast<unsigned int>(msg.at(1).Type), static_cast<unsigned int>(SKGDocument::Warning))
SKGTEST(QStringLiteral("MSG.msg"), msg.at(2).Text, QStringLiteral("Positive")); SKGTEST(QStringLiteral("MSG.type"), static_cast<unsigned int>(msg.at(2).Type), static_cast<unsigned int>(SKGDocument::Positive))
SKGTEST(QStringLiteral("MSG.msg"), msg.at(3).Text, QStringLiteral("Error")); SKGTEST(QStringLiteral("MSG.type"), static_cast<unsigned int>(msg.at(3).Type), static_cast<unsigned int>(SKGDocument::Error))
SKGTEST(QStringLiteral("MSG.msg"), msg.at(4).Text, QStringLiteral("Hello")); SKGTEST(QStringLiteral("MSG.type"), static_cast<unsigned int>(msg.at(4).Type), static_cast<unsigned int>(SKGDocument::Information))
SKGTEST(QStringLiteral("MSG.msg"), msg.at(5).Text, QStringLiteral("World")); SKGTEST(QStringLiteral("MSG.type"), static_cast<unsigned int>(msg.at(5).Type), static_cast<unsigned int>(SKGDocument::Information))
}
{
// Test clean after save
SKGDocument document1;
SKGTESTERROR(QStringLiteral("CLEAN.initialize()"), document1.initialize(), true)
SKGTESTERROR(QStringLiteral("CLEAN.beginTransaction"), document1.beginTransaction(QStringLiteral("T1")), true)
SKGTESTERROR(QStringLiteral("CLEAN.setParameter"), document1.setParameter(QStringLiteral("SKG_UNDO_CLEAN_AFTER_SAVE"), QStringLiteral("Y")), true)
SKGTESTERROR(QStringLiteral("CLEAN.setParameter"), document1.setParameter(QStringLiteral("ATT"), QStringLiteral("VAL1")), true)
SKGTESTERROR(QStringLiteral("CLEAN.endTransaction"), document1.endTransaction(true), true)
SKGTESTERROR(QStringLiteral("CLEAN.beginTransaction"), document1.beginTransaction(QStringLiteral("T2")), true)
SKGTESTERROR(QStringLiteral("CLEAN.setParameter"), document1.setParameter(QStringLiteral("ATT"), QStringLiteral("VAL2")), true)
SKGTESTERROR(QStringLiteral("CLEAN.endTransaction"), document1.endTransaction(true), true)
SKGTEST(QStringLiteral("CLEAN.getNbTransaction"), document1.getNbTransaction(SKGDocument::UNDO), 2)
QString filename1 = SKGTest::getTestPath(QStringLiteral("OUT")) % "/filename1.skg";
SKGTESTERROR(QStringLiteral("CLEAN.saveAs"), document1.saveAs(filename1, true), true)
SKGTEST(QStringLiteral("CLEAN.getNbTransaction"), document1.getNbTransaction(SKGDocument::UNDO), 0)
}
// End test
SKGENDTEST()
}
diff --git a/tests/skgbasemodelertest/skgtesttreemap.cpp b/tests/skgbasemodelertest/skgtesttreemap.cpp
index a30c38285..0215a0c75 100644
--- a/tests/skgbasemodelertest/skgtesttreemap.cpp
+++ b/tests/skgbasemodelertest/skgtesttreemap.cpp
@@ -1,138 +1,138 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file is a test script.
*
* @author Stephane MANKOWSKI
*/
#include "skgtestmacro.h"
#include "skgtreemap.h"
#define SKGTESTLAYOUT(VARIABLE, NAME, X, Y, W, H, VALUE) \
SKGTEST(QStringLiteral("getID"), (VARIABLE).getID(), NAME)\
SKGTEST(QStringLiteral("getX"), SKGServices::doubleToString((VARIABLE).getX()), SKGServices::doubleToString(X))\
SKGTEST(QStringLiteral("getY"), SKGServices::doubleToString((VARIABLE).getY()), SKGServices::doubleToString(Y))\
SKGTEST(QStringLiteral("getW"), SKGServices::doubleToString((VARIABLE).getW()), SKGServices::doubleToString(W))\
SKGTEST(QStringLiteral("getH"), SKGServices::doubleToString((VARIABLE).getH()), SKGServices::doubleToString(H))\
SKGTEST(QStringLiteral("getValue"), SKGServices::doubleToString((VARIABLE).getValue()), SKGServices::doubleToString(VALUE))
int main(int argc, char** argv)
{
Q_UNUSED(argc)
Q_UNUSED(argv)
// Init test
SKGINITTEST(true)
// A Very simple case (1 element)
{
// Build initial test case
SKGTreeMap t1(QStringLiteral("Root"), 0, 0, 0, 6, 4);
t1.addChild(SKGTreeMap(QStringLiteral("1.1"), 100));
// Compute the layout
t1.compute();
// Check root
SKGTESTLAYOUT(t1, QStringLiteral("Root"), 0.0, 0.0, 6.0, 4.0, 100.0);
// Check the layout
auto tiles = t1.getChildren();
SKGTESTLAYOUT(tiles[0], QStringLiteral("1.1"), 0.0, 0.0, 6.0, 4.0, 100.0);
}
// A simple case (2 elements horizontal)
{
// Build initial test case
SKGTreeMap t1(QStringLiteral("Root"), 0, 0, 0, 6, 4);
t1.addChild(SKGTreeMap(QStringLiteral("1.1"), 100));
t1.addChild(SKGTreeMap(QStringLiteral("1.2"), 300));
// Compute the layout
t1.compute();
// Check root
SKGTESTLAYOUT(t1, QStringLiteral("Root"), 0.0, 0.0, 6.0, 4.0, 400.0);
// Check the layout
auto tiles = t1.getChildren();
SKGTESTLAYOUT(tiles[0], QStringLiteral("1.2"), 0.0, 0.0, 4.5, 4.0, 300.0);
SKGTESTLAYOUT(tiles[1], QStringLiteral("1.1"), 4.5, 0.0, 1.5, 4.0, 100.0);
}
// A simple case (2 elements vertical)
{
// Build initial test case
SKGTreeMap t1(QStringLiteral("Root"), 0, 0, 0, 4, 6);
t1.addChild(SKGTreeMap(QStringLiteral("1.1"), 100));
t1.addChild(SKGTreeMap(QStringLiteral("1.2"), 300));
// Compute the layout
t1.compute();
// Check root
SKGTESTLAYOUT(t1, QStringLiteral("Root"), 0.0, 0.0, 4.0, 6.0, 400.0);
// Check the layout
auto tiles = t1.getChildren();
SKGTESTLAYOUT(tiles[0], QStringLiteral("1.2"), 0.0, 0.0, 4.0, 4.5, 300.0);
SKGTESTLAYOUT(tiles[1], QStringLiteral("1.1"), 0.0, 4.5, 4.0, 1.5, 100.0);
}
// More complex case
// 4 |------------|
// | 6 |2|2|1|
// | |-----|
// 2 |-------4 |3|
// | 6 | | |
// | | | |
// 0 |------------|
// 0 3 6
{
// Build initial test case
SKGTreeMap t1(QStringLiteral("Root"), 0, 0, 0, 6, 4);
t1.addChild(SKGTreeMap(QStringLiteral("1.1"), 6));
t1.addChild(SKGTreeMap(QStringLiteral("1.6"), 2));
t1.addChild(SKGTreeMap(QStringLiteral("1.3"), 4));
t1.addChild(SKGTreeMap(QStringLiteral("1.4"), 3));
t1.addChild(SKGTreeMap(QStringLiteral("1.5"), 2));
t1.addChild(SKGTreeMap(QStringLiteral("1.2"), 6));
t1.addChild(SKGTreeMap(QStringLiteral("1.7"), 1));
t1.addChild(SKGTreeMap(QStringLiteral("1.8"), 0));
// Compute the layout
t1.compute();
// Check root
auto result = t1.getAllTilesById();
SKGTESTLAYOUT(result[QStringLiteral("Root")], QStringLiteral("Root"), 0.0, 0.0, 6.0, 4.0, 24.0);
// Check the layout
SKGTESTLAYOUT(result[QStringLiteral("1.1")], QStringLiteral("1.1"), 0.0, 0.0, 3.0, 2.0, 6.0);
SKGTESTLAYOUT(result[QStringLiteral("1.2")], QStringLiteral("1.2"), 0.0, 2.0, 3.0, 2.0, 6.0);
SKGTESTLAYOUT(result[QStringLiteral("1.3")], QStringLiteral("1.3"), 3.0, 0.0, 4.0 * 3.0 / 7.0, 7.0 / 3.0, 4.0);
SKGTESTLAYOUT(result[QStringLiteral("1.4")], QStringLiteral("1.4"), 3.0 + 4.0 * 3.0 / 7.0, 0.0, 3.0 * 3.0 / 7.0, 7.0 / 3.0, 3.0);
SKGTESTLAYOUT(result[QStringLiteral("1.5")], QStringLiteral("1.5"), 3.0, 7.0 / 3.0, 2.0 * 3.0 / 5.0, 4.0 - 7.0 / 3.0, 2.0);
SKGTESTLAYOUT(result[QStringLiteral("1.6")], QStringLiteral("1.6"), 3.0 + 2.0 * 3.0 / 5.0, 7.0 / 3.0, 2.0 * 3.0 / 5.0, 4.0 - 7.0 / 3.0, 2.0);
SKGTESTLAYOUT(result[QStringLiteral("1.7")], QStringLiteral("1.7"), 3.0 + 4.0 * 3.0 / 5.0, 7.0 / 3.0, 1.0 * 3.0 / 5.0, 4.0 - 7.0 / 3.0, 1.0);
SKGTESTLAYOUT(result[QStringLiteral("1.8")], QStringLiteral("1.8"), 3.0 + 4.0 * 3.0 / 5.0, 4.0, 0.6, 0, 0);
}
// End test
SKGENDTEST()
}
diff --git a/tests/skgmyapplitest/CMakeLists.txt b/tests/skgmyapplitest/CMakeLists.txt
index 222b447c6..7996b9cf1 100644
--- a/tests/skgmyapplitest/CMakeLists.txt
+++ b/tests/skgmyapplitest/CMakeLists.txt
@@ -1,34 +1,34 @@
#***************************************************************************
#* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
#* *
#* 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 <http://www.gnu.org/licenses/> *
+#* along with this program. If not, see <https://www.gnu.org/licenses/> *
#***************************************************************************
MESSAGE( STATUS "..:: CMAKE SKGMYAPPLITEST ::..")
PROJECT(skgmyapplitest)
LINK_DIRECTORIES (${LIBRARY_OUTPUT_PATH})
SET(skgmyapplitest_SRCS
main.cpp
)
kde4_ADD_EXECUTABLE(skgmyapplitest ${skgmyapplitest_SRCS})
TARGET_LINK_LIBRARIES(skgmyapplitest KF5::Parts skgbasemodeler skgbasegui )
########### install files ###############
INSTALL(TARGETS skgmyapplitest ${INSTALL_TARGETS_DEFAULT_ARGS} )
INSTALL(FILES ${PROJECT_SOURCE_DIR}/org.kde.skgmyapplitest.notifyrc DESTINATION ${KDE_INSTALL_KNOTIFY5RCDIR} )
INSTALL(PROGRAMS org.kde.skgmyapplitest.desktop DESTINATION ${XDG_APPS_INSTALL_DIR} )
ECM_INSTALL_ICONS( ${ICON_INSTALL_DIR} )
diff --git a/tests/skgmyapplitest/main.cpp b/tests/skgmyapplitest/main.cpp
index 2c6aa16d6..de3863e84 100644
--- a/tests/skgmyapplitest/main.cpp
+++ b/tests/skgmyapplitest/main.cpp
@@ -1,80 +1,80 @@
/***************************************************************************
* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
* *
* 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 <http://www.gnu.org/licenses/> *
+ * along with this program. If not, see <https://www.gnu.org/licenses/> *
***************************************************************************/
/** @file
* This file defines the main of SKGMyAppliTest.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skguniqueapplication.h"
#include "skgdocument.h"
#include "skgtraces.h"
#include <kaboutdata.h>
#include <qcommandlineparser.h>
#include <qcommandlineoption.h>
/**
* The main of the application
* @param argc number of arguments
* @param argv arguments
* @return return code
*/
int main(int argc, char** argv)
{
KAboutData about("skgmyapplitest",
0,
ki18nc("The name of the application", "SKGMyAppliTest"),
"0.1.0",
ki18nc("The description of the application", "Blablabla"),
KAboutLicense::GPL_V3,
i18nc("Fullname", "(c) 2007-%1 Stephane MANKOWSKI & Guillaume DE BURE", QDate::currentDate().toString(QStringLiteral("yyyy"))),
"",
"http://skrooge.org");
about.addAuthor(ki18nc("Fullname", "Stephane MANKOWSKI"), ki18nc("A job description", "Architect & Developer"), "stephane@mankowski.fr");
about.setOtherText(ki18nc("The description of the application", "An application test."));
QApplication app(argc, argv);
QCommandLineParser parser;
KAboutData::setApplicationData(aboutData);
app.setApplicationName(aboutData.componentName());
app.setApplicationDisplayName(aboutData.displayName());
app.setOrganizationDomain(aboutData.organizationDomain());
app.setApplicationVersion(aboutData.version());
parser.addVersionOption();
parser.addHelpOption();
//PORTING SCRIPT: adapt aboutdata variable if necessary
aboutData.setupCommandLine(&parser);
parser.process(app);
aboutData.processCommandLine(&parser);
parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("+[URL]"), i18nc("Application argument", "Document to open")));
int rc = 0;
if (!SKGUniqueApplication::start()) {
fprintf(stderr, "SKGMyAppliTest is already running!\n");
} else {
// Creating a main panel on a generic document
SKGDocument doc;
SKGUniqueApplication kApp(&doc);
rc = kApp.exec(); // krazy:exclude=crashy
}
SKGTraces::dumpProfilingStatistics();
return rc;
}
diff --git a/tests/skroogetest/CMakeLists.txt b/tests/skroogetest/CMakeLists.txt
index 0175a0353..2f8f2e280 100644
--- a/tests/skroogetest/CMakeLists.txt
+++ b/tests/skroogetest/CMakeLists.txt
@@ -1,34 +1,34 @@
#***************************************************************************
#* Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr *
#* *
#* 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 <http://www.gnu.org/licenses/> *
+#* along with this program. If not, see <https://www.gnu.org/licenses/> *
#***************************************************************************
MESSAGE( STATUS "..:: CMAKE SKROOGETEST ::..")
PROJECT(SKROOGETEST)
LINK_DIRECTORIES (${LIBRARY_OUTPUT_PATH})
#Add test
ENABLE_TESTING()
#ADD_TEST(NAME skg_sikuli_tst_budget COMMAND ${CMAKE_SOURCE_DIR}/tests/scripts/skg_sikuli_tst_budget.sh)
#ADD_TEST(NAME skg_sikuli_tst_operation COMMAND ${CMAKE_SOURCE_DIR}/tests/scripts/skg_sikuli_tst_operation.sh)
#ADD_TEST(NAME skg_sikuli_tst_print COMMAND ${CMAKE_SOURCE_DIR}/tests/scripts/skg_sikuli_tst_print.sh)
#ADD_TEST(NAME skg_sikuli_tst_tracker COMMAND ${CMAKE_SOURCE_DIR}/tests/scripts/skg_sikuli_tst_tracker.sh)
#ADD_TEST(NAME skg_sikuli_tst_search COMMAND ${CMAKE_SOURCE_DIR}/tests/scripts/skg_sikuli_tst_search.sh)
#ADD_TEST(NAME skg_sikuli_tst_unit COMMAND ${CMAKE_SOURCE_DIR}/tests/scripts/skg_sikuli_tst_unit.sh)
ADD_TEST(NAME skroogeconvert COMMAND ${CMAKE_SOURCE_DIR}/tests/scripts/skroogeconvert.sh)
INCLUDE(CTest)