diff --git a/CHANGELOG b/CHANGELOG index 04ba1a020..8179e0685 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,1981 +1,1983 @@ skrooge (2.22.0) *Correction bug 417163: Date 31/12 => 02/12 *Correction bug 418686: no sounds from Skrooge flatpak app *Correction bug 419006: kdeapps "nightly" flatpak isn't using latest KDE/Qt runtime version 5.14 *Correction: Set the "Date of import" and "Import balance" when importing from OFX *Correction: Merge of number of operation *Correction: Fix Get Hot New Stuff legacy Endpoints *Correction: Files not able to be checked out on Windows *Correction: Bad display in dashboard when all accounts of a type are closed + *Correction: With last version of KDE, KMessageWidget are sometimes empty + *Correction: Add missing "Full screen" menu -- Stephane MANKOWSKI skrooge (2.21.0) *Correction bug 411958: Import CSV fails if account is empty *Correction bug 409166: skrooge appdata.xml missing release 2.20.0 *Correction bug 409703: No guide or tooltip for + icon in Categories form, and inconsistent *Correction bug 409165: skrooge appdata.xml gets warnings from validation-strict on flathub *Correction bug 412494: Skrooge flatpak silently fails to import anything from Amex QFX *Correction bug 412831: Filter for custom properties have to be prefixed with v_operation_display_all *Correction bug D22508: Get rid of obsolete methods *Correction bug D24327: Build flatpak with latest libofx 0.9.15 *Correction bug: Import CSV with comma when headers are forced (no automatic detection) *Correction bug: blank spaces at units "Internet code" (see: https://forum.kde.org/viewtopic.php?f=210&t=163184&p=424630&hilit=skrooge#p424630) *Correction: Import CSV file with footer line *Correction: Dashboard readability improvement (see: https://forum.kde.org/viewtopic.php?f=210&t=162650) *Feature D22484: Support using category, account, payee or unit properties in reports *Feature: New source of unite: ratesapi.io (see: https://forum.kde.org/viewtopic.php?f=210&t=162312&sid=c31044c567a38f04e7276263d3720df8) -- Stephane MANKOWSKI Sun, 01 Dec 2019 12:39:25 +0100 skrooge (2.20.0) *Correction bug 406903: no message when Skrooge can't open .skg file given on command line *Correction bug 406904: skrooge command-line help "--+[URL]" doesn't match its behavior *Correction bug 406741: QFX Date Import *Correction bug 407280: Skrooge flatpak unintentionally builds unused tests *Correction bug 407279: Skrooge flatpak needs later libofx *Correction bug 407257: Importing GNUcash (Account name instead of AccountID) *Correction bug 409026: skrooge appdata.xml fails validation on flathub, needs release and content_rating tags *Correction: aqbanking corrections: * Added auto repair for certain banks (Sprada, Netbank, Comdirect). * Added --disable-auto-repair command line option * Added --prefer-valutadate command line option * Removed --balance command line option *Correction: getNetWorth (used to compute PFS) is now computed by using all accounts *Correction: Remove color of hyperlinks in dashboard for a better rendering in dark theme *Correction: Remove broken quotes sources (BitcoinAverage, BitcoinCharts) *Correction: Better handling of the mode and comment field using the aqbanking import backend. *Feature: New REGEXPCAPTURE operator in "Search & Process" to capture a value by regular expression *Feature: Import backend aqbanking allows to import accounts without an IBAN. (See https://phabricator.kde.org/D20875) -- Stephane MANKOWSKI Sun, 23 Jun 2019 09:27:55 +0200 skrooge (2.19.0) *Correction bug 406321: ERR-8/ERR-5 importing qfx file, "More than one object returned in 'v_account' for 't_number='''" *Correction bug 406243: Skrooge does not import share operations in QIF file correctly *Correction bug 406270: Skrooge does not import investment operations in QIF correctly *Correction bug 406271: Skrooge does not import description of tags in QIF file into Tracker comment *Correction bug 406266: Skrooge does not import shares in QIF correctly *Correction bug 405578: build a nightly debug Skrooge flatpak *Correction bug 406488: crash importing a CSV *Correction bug 406549: Edit menu in Skrooge handbook is missing Skip, adds Find; missing context menu documentation *Correction: Add missing file categories_previous_period_table.html in monthly report *Correction: Migration failure with sqlite >= 3.25.0 due to ALTER TABLE behavior modification *Correction: Migration failure when some i_number are NULL *Correction: build skroogeconvert as a regular ("nongui") executable instead of an app bundle *Correction: prevent runtime discarding of the app icon if icon-from-theme lookup doesn't work (which it doesn't by default on OS X) *Correction: generate a multi-scale icon from all png icons size 256px and smaller *Feature: Tracker with running balance in "Operations" page *Performances: Better performances in payee view to compute recommended categories *Performances: Better performances in dashboard and monthly report when amounts by accounts *Performances: Better performances in dashboard to find all payee without operation *Performances: Better performances in "Delete payees without operation" -- Stephane MANKOWSKI Sat, 20 Apr 2019 14:03:43 +0200 skrooge (2.18.0) *Correction bug 403575: skrooge w/ -DSKG_WEBENGINE=ON: ui_skgtablewithgraph.h:15:10: fatal error: QtWebKitWidgets/QWebView: No such file or directory *Correction bug 403675: App crashes with segfault after second import *Correction bug 402330: error importing QIF File "SKGImportPluginQif::importFile() RC=[ERR-5]: SKGCategoryObject::addCategory failed because linked object is not yet saved in the database. *Correction bug 403725: import Quicken tags from QIF as Skrooge trackers *Correction bug 403985: kgbasegui/skgwebview.h:28:10: fatal error: qwebview.h: No such file or directory *Correction: Import KMYMONEY with non utf8 characters doesn't work (see https://forum.kde.org/viewtopic.php?f=210&t=156506) *Correction: Import KMYMONEY of scheduled operations from the next operation to add instead of the first one (to avoid duplicate) *Correction: Import KMYMONEY of shares with only one split must be done with the unit of the share *Correction: Nb occurrences and last date are not aligned on weekly schedules *Correction: Display all occurrences of a schedule in dashboard not only the first one *Correction: Display the currency symbol at the right place in scheduled operations *Correction: Display correctly the amount in "highlighted operations" in dashboard *Correction: The advice "Advice are very long to compute" can now be rejected *Correction: Add date in "Bank (light)" widget in html mode *Correction: Remove template from "Highlighted operation" widget *Feature: Better help for "Internet code" of sources in unit page *Feature: New MSN source of download for quotes *Feature: File can be made anonymous in a reversible mode *Feature: In "Operations" page, possibility to view all operations of an account + its credit cards associated *Feature: The number of years for forecasts based on scheduled operations can be choosen from settings *Feature: Possibility to choose the max date of schedules in dashboard *Feature: New action to skip scheduled operations *Feature: Possibility to skip scheduled operations from dashboard *Feature: Addition of options (Incomes, Expenditures, Transfers, ...) in contextual menu of graphs in "Account" page *Feature: Addition of options (Days, Weeks, Months, ...) in contextual menu of graphs in "Account" page -- Stephane MANKOWSKI Mon, 11 Feb 2019 21:32:09 +0100 skrooge (2.17.0) *Correction bug 400695: Designer plugins get installed as versioned libraries *Correction bug 400724: Import of Quicken 2012 .QIF file failed due to tags *Correction bug 402031: ERR-4/ERR-5 opening relative path to .skg from command line, then zombie Skrooge *Correction: Transfer created with value at 0. Regression due to 399672. (see https://forum.kde.org/viewtopic.php?f=210&t=155713&p=406978) *Correction: QIF import with transfer on split (see https://forum.kde.org/viewtopic.php?f=210&t=155614) *Correction: Add delay (300 ms) on text filter *Correction: "Search & Process" create a duplicate a duplicated category in some cases *Correction: Compliance with SQLCipher 4 *Correction: Close SQL database in mmb import *Feature: Like on transfer, the ratio is requested when creating a share operation (see https://forum.kde.org/viewtopic.php?f=210&t=155605&p=406979) *Feature: Progress bar in taskbar *Feature: Support only QT >= 5.7.0 -- Stephane MANKOWSKI Sun, 16 Dec 2018 17:50:46 +0100 skrooge (2.16.0) *Correction bug 398683: Periodic crashes on dashboard *Correction bug 397611: [ERR-5]: Format de date non pris en charge importation boobank *Correction bug 399480: Grammar mistake in .po file / - s missing in simple *Correction bug 399482: Wrong plural form in .po-File *Correction bug 399483: Spelling mistake in .po file "Transfert" should be "Transfer" *Correction bug 399672: Modifying multiple selected operations into transfers creates empty category and tracker if not identical *Correction: Ofx import must import FEE as debit *Correction: Document migration fails if format is "d.MM.yy 'г" (see: https://forum.kde.org/viewtopic.php?f=210&t=155575) *Correction: Inconsistency in "Incomes vs Expenditures" on sub operations with trackers *Correction: Build on windows *Correction: Use CPU instead CPU for QML (needed for printing) *Correction: Set background color on print to avoid print preview with black background on dark theme *Feature: Selection above, below or parent when delete an object *Performances: Solve performance issue due to new feature : More tooltips on "Operations" table -- Stephane MANKOWSKI Sun, 04 Nov 2018 14:12:43 +0100 skrooge (2.15.0) *Correction bug 397018: Check sqlcipher installation (issue detected on GENTOO) *Correction: Crash when sort a grouped view *Correction: Avoid to create 2 categories with the same name under the same category by using drag and drop *Correction: Avoid too many computation in SKGAccountObject::getPossibleReconciliations *Feature: Addition of a new option to check if import has been broken *Feature: More tooltips on "Operations" table -- Stephane MANKOWSKI Wed, 15 Aug 2018 22:01:16 +0200 skrooge (2.14.0) *Correction bug 394857: Reports do not graph operations by week correctly *Correction bug 395328: Bad perfo in SKGAccountObject::getPossibleReconciliations when too many operations *Correction: Sort on second column does not work with grouping *Correction: Change bootstrap url in templates *Correction: Better grouping for "Week", "Month", "Semester", ... *Correction: Report with forecast based on budget use the account using the most the category *Correction: Respan of group header must work when auto resize is disabled too *Correction: Import backend of account with "." in name *Correction: Remove error in boobank commands *Correction: Set automatically the bank account only when the icon is changed *Correction: The application is hidden when the dashboard is opened on an empty document *Correction: On operation page, the sort by the balance attribute sorts operations by date+id to have correct balances *Correction: Weboob backend doesn't work with option if account name has "id" *Feature: Addition of "Import date" on account object *Feature: Possibility to merge accounts with or without updating the initial balance *Performances: Improvement of performance of SKGTreeView::selectObjects and SKGTreeView::getState when grouping with many groups -- Stephane MANKOWSKI Sun, 24 Jun 2018 19:00:18 +0200 skrooge (2.13.0) *Correction bug 392828: Choose what to display on selection *Correction: Simple search in "Search & Process" doesn't escape words *Correction: Add notification (sound) on all creations / modifications of objects *Feature: Possibility to open concerned operations when auto reconciliation failed *Feature: Option on report to show decimals or not *Feature: Option "Execute on not checked operations" on "Search & Process" page *Feature: Addition of "Reconciliation balance" attribut on "Account" + icon to check if previous reconciliation has been broken or not *Feature: Addition of a new option to check if reconciliation has been broken -- Stephane MANKOWSKI Mon, 07 May 2018 20:31:26 +0200 skrooge (2.12.0) *Correction bug 389867: Amount Input Changes Value Prematurely *Correction bug 389866: Date Input Field Not Localized *Correction bug 389899: Split dates aren't updated when copying previous entry *Correction bug 390223: Opening d/l QFX file opens new skrooge file instead of importing into existing - opened file *Correction: Remove compilation warning (-Wsign-promo) *Correction: Can't resize the window and its width exceeds the screen (https://forum.kde.org/viewtopic.php?f=210&t=151023) *Correction: Search and process doesn't work in template mode with category used (see: https://forum.kde.org/viewtopic.php?f=210&t=150940) *Correction: No sound notification when an operation is created (see: https://forum.kde.org/viewtopic.php?f=210&t=151296) *Feature: All bookmarked report can be easily added to the dashboard with the + menu *Feature: New "Treemap" graph mode in reports *Feature: Automatic merge of payees, accounts and units when updated with another existing name *Feature: Alpha numerical values are now supported for number of operation (see: https://forum.kde.org/viewtopic.php?f=210&t=150988&p=394706) *Feature: Addition of a new option to displaythe environment variables used by Skrooge -- Stephane MANKOWSKI Thu, 08 Mar 2018 20:06:43 +0100 skrooge (2.11.0) *Correction bug 386942: .py scripts in /usr/bin *Correction bug 388955: Splitting Currency and Amount into separate columns *Correction: Better account number in weboob import *Correction: Weboob import is now importing account with better name (use of "label") *Correction: Weboob import compliant with utf8 *Correction: Failure when launching "skrooge filename.xxx" when filename.xxx is a file to import *Correction: "Switch closed" is available on unit but units are not closable *Correction: When a transfer is created only one of both operation has the tracker set: https://forum.kde.org/viewtopic.php?f=210&t=143127&p=384834#p384834 *Correction: Export of selection when selection size > 1 doesn't work *Correction: Define alternative icons when a "poor" icon set is used (like by default on gnome: Tango) *Feature: Tips of the day are now clickable and in the main page (not more popup panel) *Feature: Skrooge knows now 100 cryptocurrencies and is able to download their quotation *Feature: Enable AA_EnableHighDpiScaling if Qt version >= 5.6 *Performances: Better performances by resizing only visible columns (this is useful on payee table when category is hidden) *Performances: Better performances in the computation of the automatic category for a payee *Performances: Improvement of performance in SKGImportExportManager::findAndGroupTransfers. 11552 ms => 285 ms -- Stephane MANKOWSKI Sat, 03 Feb 2018 11:16:35 +0100 skrooge (2.10.5) *Correction bug 386594: Can not load share prices for French stocks -- Stephane MANKOWSKI Sat, 25 Nov 2017 23:15:27 +0100 skrooge (2.10.0) *Correction bug 383758: Report unreadable because element outlines are to thick *Correction bug 384119: Operation without suboperation after a kmy import *Correction bug 375865: Quick fill: select/enter item does not lock payee *Correction bug 384801: Converting multiple operations with different amounts to "transfer" type changes all amounts to 0 *Correction bug 384802: When creating multiple transfers into a different currency use the correct exchange rate for each date *Correction bug 385002: Display and edit default category for payee *Correction bug 385277: Wrong budget for split-operations with unaligned dates *Correction bug 384803: Creating many transfers to a different currency leads to uninterruptible series of dialog boxes *Correction bug 385990: Altered budgets aren't displayed until you reload the tab *Correction bug 386285: The minimum/maximum limit in account definition is interpreted as Primary Currency *Correction: Bad english in help on rules *Correction: Memory leaks *Correction: The source of unit download is now able to support date in "en_EN" locale event if this is not the system locale. Mandatory for implementing a Google Finance source. *Correction: Don't display the page of operations when the import is canceled *Correction: Better error messages in backend import *Correction: Optimisation in backend import *Correction: Optimise html of monthy reports *Correction: Port from QWebKit to QWebEngine *Correction: Avoid to compute too many combinations (and take hours) when trying to do an automatic reconciliation *Correction: Backend import must match account with id with letter like this 123456A@ldl *Correction: Never merge 2 accounts with same name in backend import *Correction: Crash when selecting many lines in search & process page *Correction: Enable print functions only when at least one page is opened *New feature: New "Google Finance" source of download for units *New feature: The source of unit download can be now an external script *New feature: New import backend "weboob_coming" importing coming operations (can be used for card with deferred debit) *New feature: A payee can be closed. Then it won't be available in combo boxes in operation page *New feature: A category can be closed. Then it won't be available in combo boxes in operation page *New feature: New parameters in boobank backend to be able to import operations only since a specified date *New feature: Export ledger format *New feature: The tooltip of "Search" explains now how the entered value is understood *Performances: Better performances on initial load (avoid to intialise a document before loading one other) -- Stephane MANKOWSKI Thu, 02 Nov 2017 21:17:06 +0100 skrooge (2.9.0) *Correction bug 380235: Reports table view: missing characters *Correction bug 380232: Yahoo api discontinued *Correction bug 380187: Shares always use the current rate/value. On unit page, you can choose if you want to see the history of the unit value or the history of the amount owned *Correction bug 380827: Pie chart alignment *Correction bug 380460: Failure when loading file from skrooge 1.12 *Correction bug 380821: Add keyboard shortcut to rename bookmarks *Correction bug 380820: Custom banks do not use their custom icon/image *Correction bug 380818: Cash account is not associated with a bank *Correction bug 380802: Going back and forth from "fullscreen mode" (Ctrl+Shift+F) loses the focus on "pages" tab on the left sidebar *Correction bug 381056: Dashboard portfolio widget: Wrong percentage values *Correction bug 381562: csv file import: unable to detect matching account *Correction bug 381168: Change tab order of properties editor *Correction bug 381847: Income & Expenditure widget does not match corresponding report *Correction bug 382162: Wrong budget in root categories if subcategories also include subcategories *Correction: Multithreading SQL connections must be compliant with SQLite mode *Correction: Temporary skg file protected by password are not well restore *Correction: Replacement of missing icons *Correction: Auto apply on advice duplicates remaining advice *Correction: The "duplicate" function creates operation with invalid creation date *Correction: Regular expressions for CSV import are now translatable *Correction: Values are not refreshed in amortization table when annual rate or insurance rate are modified *Correction: Zoom on dashboard widget in QML doesn't work *Correction: No refresh of "month" in the title of some dashboard widgets *Correction: In about, the authors of sub plugins are now displayed *New feature: New import backend using aqbanking *New feature: Import backends can now have parameters *New feature: Skrooge is now able to export only the selected accounts or operations *New feature: Bulk mode in import backends *New feature: In "Monthly Report", possibility to get attributes on pointed objects *New feature: Addition of new BitcoinAverage source to be able to download bitcoin rates (due to unavailability of BitcoinCharts) *Performances: Avoid advice computation in dashboard when the dashboard is not the current page *Performances: Better performance in advice "Some payees seem to be identical" *Performances: Better performances on load and save -- Stephane MANKOWSKI Sat, 12 Aug 2017 10:11:37 +0200 skrooge (2.8.1) *Correction: Bad display of information of current account when a second document is opened -- Stephane MANKOWSKI Sat, 15 Apr 2017 20:41:56 +0200 skrooge (2.8.0) *Correction bug 375721: Right-click (context menu) reload view *Correction bug 375875: Changing password does not work *Correction bug 375712: See operation for a payee *Correction bug 376025: Clear fields don't restore currency *Correction bug 375865: Quick fill: select/enter item does not lock payee is not well computed *Correction: The "Other" category in dashboard and report widget name "5 main categories of expenditure" *Correction: Sometimes the sort on date in operation table is not the same than the sort used to compute the balance, this causes troubles *Correction: Create fake operation doesn't work on account not having the primary unit (https://forum.kde.org/viewtopic.php?f=210&t=138803&sid=d0d34f728ef7f41bb6c32764ccf3d8f6) *Correction: "Income vs Expenditure" dashboard widget is not refreshed when data are modified *Correction: Bad display in "5 main categories of expenditure" in QML dashboard widget *Correction: Better performance in "Incomes vs Expenditures" dashboard widget *Correction: Duplication of operation must not duplicate the creation date *New feature 375866: Quick fill find operations in other account *New feature: New columns visible in operation table *New feature: New "budget" dashboard widget in QML *Performances: Better performances by using multithreading and caching *Performances: Better performances in "Apply all recommended corrections" -- Stephane MANKOWSKI Wed, 05 Apr 2017 20:24:45 +0200 skrooge (2.7.0) *Correction: Due to a security hole, sqlcipher is no more an option. If you use password protection, we strongly encourage you to use this version of Skrooge and to change your password *Correction: "Delete" and "Add property" are never activated in "Simulator" page *Correction: Current periods (Quarter, Semester, Year) must be available in some widgets of the dashboard *Correction: Only previous months are relevant in "Personal finance indicator" of the dashboard *Correction: Boobank backend does not import transactions when the date format is YYYY-MM-DD 00:00:00 *Correction: Remove "Stooq monthly history.txt" because it does not work *Correction: Description of SKGPeriodEdit is not correct *New feature: Addition of the "Other" category in dashboard and report widget name "5 main categories of expenditure" *New feature: New grantlee filter to execute the sql order you want on the document. This will improve html reports *New feature: New grantlee filter to convert an integer in file size format (example: 390.2 MB) *New feature: Ability to open a file property by url *New feature: CSV export from report is now able to export raw values (http://forum.kde.org/viewtopic.php?f=210&t=112209&p=290153#p290153) *New feature: Resize of account number in "Accounts" page to be able to entre IBAN number *New feature: "Rename" for all dashboard widget *New feature: "Search & process" is now possible on bank name. This allows to create an alarm based on the deposit guarantee level per bank -- Stephane MANKOWSKI Sun, 22 Jan 2017 17:45:58 +0100 skrooge (2.6.0) *Correction bug 372470: Scheduled transactions on dashboard *Correction bug 372938: merge imported operations wrong warning about different amounts *Correction bug 373147: Dashboard/Scheduled operations typo *Correction: Remove old skrooge icons to use the official breeze icons *Correction: Do not install namelink for private library *Correction: Avoid inconsistency when primary unit is not well defined (https://forum.kde.org/viewtopic.php?f=210&t=136856) *Correction: QIF import fails when non utf8 chars are found *Correction: Display all type of item in "Search & Process" *Correction: Execution of "template" rule after import destroys the template itself (https://forum.kde.org/viewtopic.php?f=210&t=137121&sid=b3336f56f03d79f50ad7d53b9e919076) *Correction: Recovery of the working copy doesn't work in sqlcypher mode *Correction: Better performances and memory use in SKGAccountObject::getPossibleReconciliations *Correction: Better automatic account selection by using bank and agency numbers *Correction: Bad unit symbols in min and max limits in accounts page *Correction: Impossible to duplicate a page not having selection (eg. Dashboard, monthly report) *Correction: The dock "Message" is not reinitialized when a new file is loaded *Correction: In budget module, replacement of "Remove existing budgets" by "Remove existing budgets for xxx" *Correction: BitcoinCharts currency import order must be inverted because CSV file has been inverted *Correction: Better display for "Income vs Expenditure" on QML dashboard *Correction: New limit to history size set to 999 instead of 99 *Correction: To avoid partial import with backend, the import is fully done in case of delta detected *Correction: weboob backend is now searching transactions on date AND rdate to avoid missing transaction *Correction: Skrooge is now able to download addition stuff (monthly report template, quote source) with knewstuff *Correction: Open file property fails when the property name contains the full path (https://forum.kde.org/viewtopic.php?f=210&t=137528) *Correction: Avoid duplicated operation when importing attached accounts with weboob *Correction: Group on suboperations must display min, average and maw amounts (https://forum.kde.org/viewtopic.php?f=210&t=137569) *Correction: The option "Import only operations since the last imported one" must not be applied with backend import *Correction: "Estimated interests" are now in QML in dashboard and are available for monthly reports *Correction: Addition of tooltips on each operator in "Search & Process" *New feature: Addition of "nocolor" to the "money" Grantlee filter *New feature: Remove .skg in backup file name if .skg is added in the prefix (https://forum.kde.org/viewtopic.php?f=210&t=136518&p=366065#p366065) *New feature: "Alarm" dashboard widget is now compliant with QML mode -- Stephane MANKOWSKI Tue, 27 Dec 2016 18:42:32 +0100 skrooge (2.5.0) *Correction bug 364407: Doesn't build with Qt 5.7 *Correction bug 366025: Skrooge perpetually asks me to save updated tab state *Correction bug 368196: Delete sub-operations in edit delete selected operation in list *Correction bug 368356: Show amount sign on lost focus *Correction bug 368195: No lock on target account for a transfer *Correction bug 369090: Transfers sub operation created by template has wrong date *Correction: Migration connect from ui file to cpp file *Correction: Better colors of amounts in tooltips of advices *Correction: The 31 of the month, in budget page, "Previous month" does not work *Correction: When a second instance of Skrooge is launched with a file as argument, the file must be imported in the first instance of Skrooge *Correction: Since QT5.7, no more dependency on KDELibs4Support *correction: Dates wrong on dashboard - date format instead of the date itself *Correction: Keep properties when 2 operations are merged *Correction: Correction in weboob backend to avoid missing transactions and improve performances *New feature: Massive update is now available for amount in "Operation" page *New feature: Massive update is now available for date in "Operation" page *New feature: Capability to set/change order of budget rules *New feature: Tooltip on modified amount of budget to explain the reasons of modifications *New feature: Import of PDF invoice -- Stephane MANKOWSKI Sun, 25 Sep 2016 09:00:24 +0200 skrooge (2.4.0) *Correction bug 359679: Building the v2.3.0 package on Arch Linux dies with an error 'isnan' was not declared in this scope *Correction bug 362231: Lost date in imported split operation *Correction: Corruption of document after removing the password *Correction: In unit page and dashboard widget the annual performance is now computed on a year (not with an extrapolation of the last performance) *Correction: Refresh "Interest" dashboard widget when operations are modified *Correction: Copy needed files in local when a new template (for monthly report) is created *Correction: All advices are not displayed in dashboard *Correction: More setPlaceholderText for better GUI *Correction: Responsive report is now using highchart *New feature: New tutorial grantlee template to learn how to develop a new template *New feature: New option to select if the dashboard must be in html or qml. Qml mode is still experimental -- Stephane MANKOWSKI Fri, 06 May 2016 21:07:29 +0200 skrooge (2.3.0) *Correction bug 357081: No option to disable tray icon *Correction bug 357414: Bad display amount in split editor *Correction bug 358315: Typo in .desktop file leads to KRunner freeze *Correction: Avoid failure in kmy import when sub category already exists *Correction: Better autoreconciliation (the autoreconciliation can be done even when operations are not well sorted) *Correction: Migration to nullptr *Correction: Replace "XXX* yyy = new XXX" by "auto yyy = new XXX" *Correction: Thanks to regular expression, the "word" function is now able to interpret "N:1234" as a 2 words "N" and "1234" *Correction: Better icons (correction of installation for breeze) *Correction: Autoreconciliation doesn't work for accounts in other units than the primary *Correction: Better computation of the preferred currency for QIF import *Correction: After a modification or an creation the focus must be given to the table *Correction: Error when launching Skrooge from krunner *Correction: Bad sums in reports *New feature: New column "Balance import" in account page with an indicator to know if the account is still aligned with import balance *New feature: Check balance of accounts after import with backend *New feature: New "Personal Finance Score" in monthly reports *New feature: New "Personal Finance Score" in dashboard *New feature: Selection sum is now in the status bar *New feature: On tables, when the filter changes, the selection remains visible *New feature: Ctrl+Maj+V allows to validate OR UNVALIDATE the imported operations -- Stephane MANKOWSKI Sun, 21 Feb 2016 21:55:44 +0100 skrooge (2.2.0) *Correction bug 352674: SQLite version of the system not aligned with embedded in Qt when using sqlcipher *Correction bug 349961: Values in "Text" report are clickable to open corresponding operations *Correction bug 349976: Default categories for payees *Correction bug 354139: Pb when opening operations in sub-operation view *Correction bug 341463: Monthly reports include transfers between accounts and shows as income/expenses *Correction bug 354439: Re-open close account with money: wrong warning *Correction bug 354463: Incomes/Expenditures in monthly reports do not account for sub-operations of split operations *Correction bug 354424: Displayed balance is 0,00 and operation is ignored afterwards *Correction bug 354817: Arrows should increment/decrement operation number *Correction bug 355376: Category too small in split editor *Correction bug 355956: Not existent type in dashboard *Correction: Drag and drop file is now able to move a file *Correction: The WORD function of "Search & Replace" is no more sensible of useless space *Correction: Open skrooge document from desktop *Correction: Set open source licence on svg files *Correction: Correction ofx import in ECM_ENABLE_SANITIZERS='address' mode *Correction: Better print of dashboards by printing each widget individually *Correction: Better counting of pages in print function *Correction: Monthly reports with "default" template is now printed in only one page (remove page-break-before: always) *Correction: Monthly reports with "responsive" template must not print url *Correction: Migration from sqlite to sqlcipher mode does not work when the password contains the character " *Correction: In "Search & Process", the between function must work when v1 Sun, 29 Nov 2015 18:48:31 +0100 skrooge (2.1.1) *Correction bug 351977: Missing Comment in desktop file *Correction bug 350722: Sudden date change from 20XX to 19XX *Correction: Upload of knewhotstuff does not work *Correction: Avoid performance issue when an operation is created very far in the future (example: 01/01/8015) *New feature: New source of download "GrandTrunk" better than yahoo finance for currencies -- Stephane MANKOWSKI Fri, 11 Sep 2015 13:10:09 +0200 skrooge (2.1.0) *Correction bug 349349: Allow to enter year with 2 digits only *Correction bug 349328: Bad date on split operation after fast edition *Correction bug 349327: Bad date format for sub-operation display in split tab *Correction bug 349624: Add operator on fast filter *Correction bug 349776: Freeze when splitting and editing a future operation *Correction bug 349329: Tools should display modifications before applying them *Correction bug 349961: Split value of operations in reports/exports *Correction bug 350154: Cannot change rate symbol (%) position in Simulations panel *Correction bug 350722: Sudden date change from 20XX to 19XX *Correction bug 350937: Some words are not translated *Correction bug 340647: Encrypted Skrooge file is decrypted in-place *Correction: Authorize only word characters and space in name of templates of reports *Correction: Authorize only word characters and space in name of source of quotes *Correction: Missing unit symbol in monthly report *Correction: Failure on export *Correction: Bad display in period selector of "Income & Expenditure" dashboard widget *Correction: Bad filters in some open file dialog *Correction: Error when open link with non ASCII characters *Correction: Better detection of unaligne dates between operations and sub operations *Correction: The first update of monthly report must take into account the selected template instead of using the default one *Correction: Add credits page in "About" *Correction: Double click on skrooge document opens skrooge but the document is not loaded *Correction: Code rework for contextual menus *New feature: "Open..." action in contextual menu of reports *New feature: New function to import simple rules (payee=xxx => category=yyy) from csv file *New feature: More period options in dashboard widgets *New feature: "5 main categories of expenditure" in dashboard and report is now clickable *New feature: "Quotes" in dashboard and report is now clickable *New feature: Addition of list of key users in credits *New feature: Messages/errors can have associated action *New feature: "Open operations modified by this transaction" *New feature: Delete items in history -- Stephane MANKOWSKI Thu, 27 Aug 2015 19:20:30 +0200 skrooge (2.0.0) *Correction bug 347762: Invalid error message for SQLite version check after an update of SQLite *Correction bug 324653: Auto-Hide Scrollbars for Report Graphs *Correction bug 348865: Do not show translated tooltip *Correction bug 348490: Split with almost 0 operation *Correction: Porting on KF5 / QT5 *Correction: Use of Q_DECL_OVERRIDE *Correction: Bad account selected in editor when a closed operation is selected *New feature: Close action available in menu and contectual menu -- Stephane MANKOWSKI Sun, 14 Jun 2015 18:16:43 +0200 skrooge (1.12.5) *Correction bug 348619: Freeze amount should freeze unit *Correction bug 348621: Field order with tab key *Correction bug 348620: Display of multiple operations with common fields *Correction bug 348568: Payee with operations in 0 operation group *Correction bug 345994: Bad unit on some operation after search *Correction: Build for QT built with -reduce-relocations -- Stephane MANKOWSKI Wed, 03 Jun 2015 22:07:31 +0200 skrooge (1.12.0) *Correction bug 345974: Skrooge alarms keep firing up regardless of specified alert amount *Correction bug 346151: Fast edition do not fill operation sign *Correction bug 345998: Add tooltip for all history actions *Correction bug 345799: Moved then hiden column displayed *New feature: Automatic point operations created during reconciliation *New feature: "Simple" mode in "Search and process" page *Performances: Better performances on selection change in "operation" page -- Stephane MANKOWSKI Thu, 07 May 2015 20:46:21 +0200 skrooge (1.11.0) *Correction bug 341020: End of text in lineedit hides under the "clear" icon button *Correction bug 341450: Empty skg_bill.csv is created every time I launch Skrooge *Correction bug 341463: Monthly reports include transfers between accounts and shows as income/expenses *Correction bug 342737: Multiple date modifications on scheduled operations *Correction bug 343730: Resize/hide internal filter panel in report *Correction bug 335945: Support making split operations from standard operations by search and process *Correction bug 344250: Bank ING-DIRECT in France has changed its bank number *Correction bug 345580: Share without tax should not be split *Correction bug 345654: Btn Add grayed after entering values information *Correction bug 345661: Selecting multiple operations: amount is not ----- *Correction bug 345719: Enhance fast search/filter on lists *Correction bug 345826: Bas edit fields on list sub-operation after search *Correction bug 345416: Crash when searching on 'type' field *Correction: "Search" and "Report" do not work on properties of suboperations *Correction: Bad tooltips in "Report" for expand and collapse *Correction: Support invalid OFX file having debit with positive amount *Correction: Timeline does not work in some cases *Correction: More flexibility during import of ofx file not having id on transactions *Correction: Anonymized file is renamed to avoid accidental overwrite of the current file *Correction: weboob backend compliant with version 1.0 *Correction: Avoid crash and generate an error when the sqlite version of the system is not aligned with the sqlite version embedded in QT *Correction: Open suboperation from multi selected operations *Correction: Avoid deletion of previous file and backup during save in case of file system full *Correction: When a folder of bookmark a tab doesn't have the right icon *Correction: Stable sort when sorting by date to avoid ununderstandable balance *Correction: In table, when rows are groupes, the row representing the group spans all columns *Correction: Avoid crash in Add properties on suboperations *New feature 343766: Better custom report configuration *New feature: New dock to be able to see all messages displayed *New feature: Alarm messages can be have parameters for the total amount (%1), alarm amount (%2) and difference (%3) *New feature: Show sum of spendings in tables when operations are grouped *New feature: New advice detecting scheduled operations having date not aligned with the last inserted operation *New feature: The target directory of the backuped file can be force *New feature: Now some advices are recommended *New feature: In settings, you can define default comments, payees and categories for fake, commission and tax operations *New feature: New button on advices widget to apply all recommended advices *New feature: Display average, min and max on groups in tables *New feature: WORD function is now able to extract word from the right by using negative parameters *New feature: Addition of "Creation date" on operations -- Stephane MANKOWSKI Sun, 05 Apr 2015 19:18:04 +0200 skrooge (1.10.0) *Correction bug 334626: When doing a transfer, my specification of + or - is ignored *Correction bug 335943: Please add column "number of operations" to categories view *Correction bug 336320: OFX file import duplicates the last 12 transactions *Correction bug 338351: Reconciliation with additional currencies *Correction bug 338993: Change main currency fails to update amounts *Correction bug 338994: Currency rate not saved for transactions *Correction: Open URL does not work in unit page *Correction: Wrong date in message "Operation 'XXX' will be inserted in YYY days" *Correction: Auto repair of qif file not having sum of suboperation amount != operation amount *Correction: Better error message on mny import when java is not installed *Correction: Weboob0g backend is now compliant with weboob version 0h *Correction: Correction in bitcoin quote download *Correction: Remove duplicate in "To Account" field on operations *Correction: Import of mode for mny files *Correction: Better detection of transfers in mny import *Correction: Automatic resize of columns in "Search and Process" edit panel to facilitate the creation/update of rules *Correction: Missing template "categories_month_table" *Correction: For credit card account, the binding of account is optional *Correction: Remove useless "Expand All" and "Collapse All" on history table *Correction: "Add property" and "Delete" is now working on sub operations *Correction: "Highlight" is disabled on sub operations *New feature: The future can be added or not in "Current" or "Last" periods *New feature: Defered credit card management *New feature: Capacity to apply a template on operations *New feature: Capacity to automatically apply a template on operations from "Search and Process" *New feature: Sort of table memorize the previous sort to be able to sort by column 1 and column 2 *New feature: New advice to inform the user when the monetary decimal symbol is not defined in KDE localization settings *New feature: 2 options in graphs, one for limits visibility, one for average visibility *New feature: New advice to detect similar payees *New feature: New advice to detect similar categories *New feature: Add in documentation how to use kdewallet with weboob backend *New feature: Import iif file *Performances: Better performances in "Possible schedule" *Performances: Better performances in dashboard -- Stephane MANKOWSKI Tue, 28 Oct 2014 20:57:41 +0100 skrooge (1.9.0) *Correction bug 327148: Version 1.8.0 doesn't build *Correction bug 328335: Wish for fixed table row header *Correction bug 326764: When printing hard copy of report, only data in view in window is printed, not full report data *Correction bug 329568: Simulator utility problem *Correction bug 329825: When opening crypted file with false password skrooge falsely states the file is corrupted *Correction bug 329876: Weboob import from paypal ignores dates and creates account "0" *Correction bug 330354: Budget forecast duplicates operation creation *Correction bug 330428: Sorting doesn't work on Reconciliation date in Accounts view *Correction bug 331191: Obsolete term „Context“ in docbook *Correction: Remove conflict on CTRL+C shortcut *Correction: Import mny does not work with space in file name *Correction: In case of failure during backup file creation a warning message is displayed instead of an error avoiding to save the file *Correction: Refresh delta during reconciliation *Correction: Better PDF export from Monthly report *Correction: Import CSV unit file with "," as separator *Correction: Better KMyMoney import *Correction: Imported "Wallet" accounts are in bank named '' *Correction: Avoid wrong transfert in Grisbi import *Correction: The option "Import only operations since the last imported one" uses a delay of 4 days to avoid missing operations due to value date *Correction: Avoid error in import of homebank file without parent attribute on categories *Correction: Correction for unit download with Stooq *New feature: More option in "Income & Expenditure" dashboard widget *New feature: New shortcuts for "Expand all" and "Collapse all" *New feature: Operations can be split by date *New feature: Imports (csv, qif) support date format like this: 31Dec2012 *New feature: Import CSV support now "semicolon", "comma" and "tab" as separator *New feature: Monthly report is now able to display reports on months, quarter, semesters and years *New feature: New "responsive" template for monthly reports *New feature: In graph, sums are now all computed *New feature: Pareto curve in graph *New feature: New "quarter" and "semester" period in graph and "Incomes & Expenditures" dashboard widget *New feature: Ability to reorder the suboperations in the split operation *New feature: Better date filtering in operation page *New feature: More operators is "Search" panel *New feature: New statistic plugin -- Stephane MANKOWSKI Sat, 12 Apr 2014 16:11:26 +0200 skrooge (1.8.0) *Correction bug 319706: OFX trntype not imported, rest okay *Correction bug 320114: Wrong bank balance at dashboard *Correction bug 320112: Importing CSV operations with mixed " and ' text field separators *Correction bug 320226: Monthly report does not work due to missing template *Correction bug 320240: Impossible to enter exact amount for given unit in pop-up *Correction bug 320242: Transaction confirmation pop-up doesn't use defined unit value for transaction date for suggested value *Correction bug 320261: Dashboard "Income & expenditure": no values, strange colors *Correction bug 320157: Skrooge not working when .skg file is located on Samba share *Correction bug 320323: Add function ("rest to") In budget *Correction bug 320298: Default automatic format detection while importing a file leads to wrong entries creation *Correction bug 320070: Allow changing operation date through "Search & Process" *Correction bug 320716: Skrooge does not import all operations using weboob *Correction bug 320717: Use rdate instead of date in weboob backend *Correction bug 319993: Please adopt application logo/icon for smaller resolutions ==> skrooge-mini can be choosen for small resolutions *Correction bug 319990: Please fix icon alignment in Pages tab *Correction bug 322306: Skrooge Crash using Forecast Schedule *Correction bug 322069: Designer plugins should be unversioned .so files *Correction bug 323380: Minor date bug when using the stock portfolio widgets *Correction bug 320066: Crash importing KmyMoney exported file from Skrooge *Correction bug 324972: Import fails without an error when account is defined in CSV *Correction bug 325081: Add a « Yesterday » choice in the date picker *Correction bug 325174: Importing from gnucash file doesn't import accounts fo types 'Mutual Fund' nor 'Credit Card' *Correction bug 325223: Crash when exiting skrooge *Correction bug 324008: Erreur when importing .mny file. Error when analysing categories.json *Correction bug 325675: Build error in skgfileplugin.cpp for openSUSE 12.2 KDE 4.9 *Correction: KMyMoney exports does not need a check of integrity anymore *Correction: Addition of all icons in size 256 and 512 *Correction: Block drop of a bookmark under another bookmark *Correction: Bad date format detection when the second value is 9 (example: 3/9/04) *Correction: Remove the "Bank account " string in the name of the account name created by an OFX import *Correction: Icon for "Amount entered" *Correction: Authorize long number for operations like 5490990004 *Correction: Default graph mode = line *Correction: Better detection of duplicate operations after import *Correction: JSON export based on QJson *Correction: The setting "Import only operations since the last imported one" allows importation for the same date (< instead of <=) *Correction: Impossible to change state of operation from suboperation view *Correction: More permissive "Open duplicate" *Correction: Better setting layout for import/export *Correction: Import/Export minimum and maximum balance in KMyMoney importer *Correction: Import minimum balance in Grisbi importer *Correction: Import minimum balance in Homebank importer *Correction: New "weboob0g" backend compliant with the Weboob 0.g *Correction: When a file is selected for the icon of the bank, the file name is displayed in the name of the bank *Correction: In simulation page, the interest are computed with only operations with type=currency, not with shares *Correction: Error when importing skg file by double clicking when skrooge already open *Correction: No more password panel when the user loads an invalid Skrooge file *Correction: In report, the forecast based on budget is displayed even when no operation in account *Correction: Shortcuts in "Show" menus *New feature: Notifications and error messages are now based on KMessageWidget *New feature: The restore file is now base on KMessageWidget *New feature: Option to auto download from backend on opening file (default=false) *New feature: Import Microsoft Money documents (.mny) protected or not *New feature: Tarballs are not uploaded on download.kde.org *New feature: Addition of russian banks *New feature: Reopen last page closed *New feature: Max and min limits on accounts *New feature: Better and new advices based on limits of accounts *New feature: Sound emmission on operation creation *New feature: Import "Budgetary allocation" and "Fiscal year" from Grisbi files as properties *New feature: Information message explaining how to exist full screen mode *New feature: Addition of date of last reconciliation on account *New feature: Amount owned on unit table *New feature: Download date on unit table *New feature: New account type: Pension *New feature: New set of categories for french people *New feature: Addition of "Configure notifications..." in configuration menu *New feature: Download and add bills as property by using boobill (weboob) *New feature: Rename of property *New feature: Export HTML and ODT from tables *New feature: Automatic process to recover a corrupted file *New feature: Possibility to print current page *Performances: Better performances in dashboard *Performances: Better performances in monthly report *Performances: Better performances in import of multi files (or from backend) by applying "search & process" rules only one time *Performances: Better performances in kmy export *Performances: Better performances by avoid to refresh autocompletion on widgets after light transactions -- Stephane MANKOWSKI Sat, 05 Oct 2013 18:54:16 +0200 skrooge (1.7.1) *Correction bug 319565: Bad performances on ubuntu 13.04 *New feature: Open report from dashboard widgets -- Stephane MANKOWSKI Thu, 09 May 2013 22:28:28 +0200 skrooge (1.7.0) *Correction bug 316604: Income and Expense widget on the dashboard does not respect suboperations in split operations *Correction bug 316796: Reports crash when closed normally *Correction bug 318063: New file format (AFB120 CFONB) *Correction bug 279967: When automatically started at login, Skrooge is always displayed on all desktops *Correction bug 319145: Multiple currency support still buggy *Correction: Group operations with more than 2 operations selected *Correction: Group operations with already grouped operations *Correction: Hide internal properties in "Search & process", in operation page and in the function "Add property" *Correction: QIF import does not support mix of date format *Correction: The advice action "Remove groups with only one operation" does not remove the operation but the group *Correction: Better performances in kmymoney import and all other imports *Correction: skroogeconvert does not support files without path (example: skroogeconvert -in t.csv -out t.kmy) *Correction: Better performances of skroogeconvert in case of skg import or export *Correction: Global better performances by using the right index on unit table *Correction: Rename "Undo document" to "Revert document" *Correction: Reduce the number of messages when using backend import *Correction: Possibility to group tables on properties *Correction: Better support of import/export with url *Correction: Better merging of operations in QIF import *New feature: More modification functions in "Search & Process" panel for Payee, Account, Tracker *New feature: New "capitalize" function in "Search & Process" panel *New feature: New attributes "Unit" and "Transfer" in "Search & Process" panel *New feature: All update functions are now available for properties in "Search & Process" panel *New feature: New icon in tab bar to create new page *New feature: 'To account' in operation table and "Search & Process" *New feature: More attributes in line and column in reports (graph) *New feature: Monthly reports and main page use the general font of KDE *New feature: Possibility to force the date format for qif and csv imports *New feature: More functions in tool menu *New feature: More tips of the days *New feature: Dispay option "Hide pointed operations" in operation page *New feature: Possibility to group tables on hidden column *New feature: Facilitate creation of standard currencies with auto completion *New feature: Addition of the new currency "Bitcoin" with automatic download of the rate *New feature: In dashboard and monthly report, banks can be clicked to open corresponding operations *New feature: In report, the graph correction can be done by multiply or divide -- Stephane MANKOWSKI Sat, 04 May 2013 16:49:45 +0200 skrooge (1.6.0) *Correction bug 314389: weboob import does not work *Correction bug 314743: Can not resize window when operations tab is displayed *Correction bug 313926: Version 1.5.1 shows warnings *Correction bug 313948: Skrooge crashed after double clicking on an account after using clean import tool *Correction bug 313928: Warnings during build on OS X > 10.6 *Correction: Splash screen and notifications on windows *Correction: Better error management in weboob import plugin *Correction: Faster and without notification units downloads *Correction: Facilitate toolbar customization *Correction: Bad date format identification in some cases *Correction: Remove traces "Attempt to use QAction 'XXX' with KXMLGUIFactory" *Correction: Activation of link in "Incomes and Expenditures" dashboard widget *Correction: Operations in "Loan" accounts are not more taken into account in budget and "Incomes and Expenditures" dashboard widget *Correction: More point styles in graph and better rendering *Correction: Display of infinity symbol in dashboards and monthly reports *New feature: "Open all" and "Bookmark current page here" in the bookmark button *New feature: Button in bookmark dock to discover the contextual menu *New feature: Buttons on dashboard widgets to discover the contextual menu *New feature: New cursor on dashboard widgets to show that widgets are moveable *New feature: New dashboard (fast remove, fast add, fast move, fast drag & drop) *New feature: ToolButton displaying contextual actions on top right of tables *New feature: "Pages" launchers can be added in the toolbar *New feature: New WORD function in "Search & process" to extract a word of an attribute *New feature: More generic import through backends *New feature: Support values like this "3128/100" in imports -- Stephane MANKOWSKI Mon, 25 Feb 2013 18:06:13 +0100 skrooge (1.5.1) *Correction: Avoid endless "wait cursor" in case of canceled load of protected file *Correction: More robust weboob import for backend not supporting parallel download *Correction: Operations page layout with very long comments -- Stephane MANKOWSKI Tue, 22 Jan 2013 21:09:04 +0100 skrooge (1.5.0) *Correction bug 311252: Creating account with existing name just modify the existing one *Correction bug 312609: Banks widgets at the dashboard show wrong values *Correction bug 312671: Compile warnings *Correction bug 312859: Searching for an empty payee doesn't seem to work *Correction bug 313140: Thousands of compile warnings when using [-pedantic] [PATCH provided by Andi Clemens] *Correction bug 313141: Adjust layout in preferences window [PATCH provided by Andi Clemens] *Correction bug 271292: "Set to upper" process does not work with all characters *Correction bug 263265: Support regexps on imported data *Correction bug 313268: Better layout fot the "comment" field in the operations view *Correction bug 313240: Transfers between accounts with different currencies show as income/expense *Correction: Disable "Pin this page" when no page is opened *Correction: Disable "Print" and "Print preview" when no page is opened *Correction: Correction in the show menu of the operation page when only one account with ";" in the name *Correction: Pb of propagation for budget rule with Period=Current Year *Correction: Avoid duplicate message in notification *Correction: Avoid to set an operation in more than one budget item when "garbage" budgets are used *Correction: Display reconciliation field when the "Reconcile" function is called from the page of accounts *Correction: Transfers ignored by default in" "Incomes & Expenditures" widget and reports *Correction: Adapt the size of the "Account" field to the lenght of the accounts names *Correction: Set focus on "Date:" field after insertion or update of an operation *New feature: New "Process Immediately" method to process immedialetly some scheduled operations *New feature: Multiselection for "Jump to the operation" in scheduled operation page *New feature: New advice to detect non alignment of comments (operation vs suboperation) for simpe operations *New feature: New advice to detect operations without mode *New feature: New option Automatic refresh/Manual refresh in advice dashboard widget *New feature: New advice to switch on "Manual refresh" when advice are very long to compute *New feature: New advice to detect too complex unit definition like this: IBM => $ => £ => € (not supported) *New feature: Possibility to do graphic reports with the bank as column of line *New feature: Automatic import through weboob (http://weboob.org/) *Perfo: Better performances in advices by avoiding to compute dismissed advice *Perfo: Better performances in categories and payees tables *Perfo: Big performances improvement for huge transaction like imports or massive delete of accounts -- Stephane MANKOWSKI Sat, 19 Jan 2013 16:31:49 +0100 skrooge (1.4.0) *Correction bug 306517: "Incomes & expenses" widget displays a wrong sum for expenses *Correction bug 308050: Untranslatable strings in 'Budget' Page *Correction bug 308395: "list of operations" screen : inoperative filters (hide closed operations >1 & 2 weeks) *Correction bug 310372: Word completion in the comment field in standard operation does not work even if it was added via split operation *Correction: Better colors in "Expenditures vs Icomes" dashboard widget *Correction: Support qif file having Type:Class with description *Correction: Remove "All" in operation menu when only one account is created *Correction: Move "Export ..." menu in "File" menu *Correction: Bad display of account having a "&" in operation page *Correction: Move "Processing" actions in the main menu named "Tools" *Correction: Hide title when reset filter in operation page *Correction: Better performances in SKGDocumentBank::computeBalances by using compound query *Correction: Avoid freeze when a very old value (example: 14-11-0012) is entered by error for a unit *Correction: Avoid freeze in reports when a very old operation (example: 14-11-0012) is entered by error *Correction: "Quantity owned" in unit page does not initial amount of accounts *New feature: New button on unit page for opening the web site of the download source *New feature: Warning on closing non null account *New feature: Support for Activities *New feature: "Stock portfolio" in monthly report *New feature: "Stock portfolio" dashboard widget based on monthly report *New feature: Possibility to add hyperlinks in monthly reports *New feature: Export html in monthly reports *New feature: New widgets for dashboard *New feature: 2 new templates for monthly report are delivered by default *New feature: 2 new advices detecting very old values of unit and very old operations *New feature: New advice checking if budgets rules are treated *New feature: New option for import to "Import only operations since the last imported one" -- Stephane MANKOWSKI Sun, 09 Dec 2012 11:51:43 +0100 skrooge (1.3.3) *Correction bug 305880: On the Dashboard, scheduled transactions have wrong number of decimal places *Correction bug 306119: Cannot open document created in 1.3.0 with 1.3.2 *Correction bug 305879: Account panel shows Edition - should be Addition *Correction: Smaller bank icon selector in "Accounts" page *Correction: Set default type as "currency" in "Units" page when primary and secondary units are already defined *New feature: Add "savings" as type of account *New feature: "Tracked" operations in option of "Income vs expenditure" widget of dashboard *New feature: Export JSON -- Stephane MANKOWSKI Mon, 03 Sep 2012 16:25:21 +0200 skrooge (1.3.2) *Correction bug 300228: Failed to import from KMyMoney file *Correction bug 301137: 'To Account' of an existing money transfer is displayed incorrectly in edit area *Correction bug 302388: Gnucash import failes: Better error message in case of negative value for a currency *Correction bug 302502: Message for possible schedule incomplete *Correction bug 303527:Support more time options for ‘show checked operations’ *Correction bug 304003: Crash when removing transaction number of transactions with duplicate account numbers *Correction bug 304313: Importing a KMyMoney file results in error: "[ERR-11]: 'KMYMONEY-KMYMONEY-TEMPORARY-ACCOUNT': You are not authorized to delete this account because it contains some checked operations" *Correction: Rename columns of budget table *Correction: Better CSV and TXT exports of tables grouped by a column *Correction: Better SVG export of tables *Correction: Restore palette in tables after print *Correction: Do not display disabled schedules in dashboard *Correction: Remove text on common icons in toolbar by using QAction::LowPriority *Correction: In "Scheduled operations" page, the button "Jump to the operation" opens the operation page in template mode to authorize updates *Correction: New wording; "To be Checked" instead of "Foreseen" or "In Transit"; "Checked" instead of "cleared" or "validated" *Correction: Better mouse icon when closing pined page *Correction: Remove X confirmation messages when close a document having X pinned pages *Correction: Focus on opened page from bookmarks when the current page is pinned *Correction: Allow massive update in account page *Correction: Avoid bad table display when grouped *New feature: Progress bar in budget table for active budgets *New feature: "Open report" button from search page to open report without saving the query *New feature: Option to ignore operation tracked in reports *New feature: Option to ignore operation grouped in reports -- Stephane MANKOWSKI Mon, 06 Aug 2012 12:24:18 +0200 skrooge (1.3.0) *Correction bug 291512: Show hide checked operations setting are not retained *Correction bug 291550: Advice (dashboard) about operations with empty category : case of transfers *Correction bug 292225: Skrooge 1.2.0 crash on opening report *Correction bug 293398: Display Graph windows during Account Creation *Correction bug 293397: Error on duplicate account name creation *Correction bug 293580: Select/unselect "import state" column will display empty field *Correction bug 293941: Skrooge crashed on deleting split operation *Correction bug 278220: Wrong values in Monthly Report "Amounts in accounts" *Correction bug 296204: add balance entered in Operations *Correction bug 297722: Copy/paste comment in the table of a split operation leads to a wrong behaviour *Correction: creation of subcategories with entered number *Correction: hide templates when open operations from other pages *Correction: Use radio button in "Show" menus when needed *Correction: Support import of gnucash file without "gnc:book" *Correction: Generate an error message when trying to import a missing ofx file *Correction: FastEdition does not work when more than one "operation" page is opened *Correction: Crash on QIF export when the document has 3 operations grouped with op1.value=-op2.value *Correction: Refresh of graphs when unit values are modified *Correction: Install the grantlee filter plugin into the correct location. *Correction: Avoid empty "Account" page when no account exist *Correction: No automatic resize of columns when "auto resize" is not check *Correction: Addition the "rate" in internet code tool tip. *Correction: Amounts are displayed with the right number of digits in "operation" and "account" table. *Correction: Refresh view when a new appearance is selected *Correction: Bad computation of fake operation in case of multi selection *New feature: Better display of "Show" menu in operation table *New feature: Colors in "Incomes and Expenditure" dashboard widget *New feature: "Search & Process" is now working on comments of sub operations *New feature: "Base 100" mode *New feature: Skrooge is now able to import file have amounts with unit symbole (example: -$8.35) *New feature: Possibility to pin/unpin pages -- Stephane MANKOWSKI Mon, 23 Apr 2012 11:45:09 +0200 skrooge (1.2.0) *Correction bug 288683: E: skrooge-common: arch-dependent-file-in-usr-share usr/share/kde4/apps/skrooge/plugins/grantlee/0.2/grantlee_skroogefilters.so *Correction bug 290626: No support of OFX format *Correction: Avoid suboperations pointing on unused category when all categories are deleted *Correction: Hide internal properties in property dock *Correction: A new document is no more considered as modified *Correction: Advice "xxx is an old tracker" modified to use the LASTDATE instead of the FIRSTDATE *Correction: Better display in "Income & Expenditure" dashboard widget + addition of "Saving" *Correction: In "Account" page, "Other ..." in icon list is now working *Correction: Correction for advice "Possible schedule 'xxx'" *Correction: Hide internal properties in graph *Correction: Bug on inline edition on comment & mode *Correction: Optimisation on "anonymize" function for big files *Correction: Highlight switch on category *Correction: In operations tab, provide a "show" menu as for other plugins *Correction: Avoid duplication of some categories when search and process is used *Correction: Avoid modifications in interest table *Correction: Fast edition refreshs the "comment" field *Correction: The autocompletion list for number displays only the numbers of the selected account *Correction: Monthly report create .kde directory event if .kde4 must be used *New feature: Fields of update part of the search & process panel are not editable to facilitate the completion *New feature: Import of non local files (example: http://myserver/document.qif) *New feature: Export of non local files (example: http://myserver/document.qif) *New feature: Dashboard > Shares & Indexes renamed to "Quotes" and provide a possibility to select all available Units (Objects, Currencies etc.) *New feature: Operations > Transfer: do not display a name of a chosen source account in the field of target account *New feature: New mode in reports *New feature: Memorize expanded groups in bookmarks *New feature: "Incomes & Expenditures" widget is clickable *New feature: Highlight on units *New feature: Addition of "Show" menu in scheduled operations *New feature: Hide title in "Scheduled operations" if at least one schedule is existing *New feature: Open "Scheduled operations" when an operation is scheduled *New feature: SKGTreeView scrollbars are sticked on maximum position *New feature: SKGTableWidget scrollbars are sticked on maximum position *New feature: New "Open operations" function in contextual menu (connected with double click - support multi selection) -- Stephane MANKOWSKI Mon, 09 Jan 2012 11:01:12 +0100 skrooge (1.1.1) *Correction: "Highlighted only" is by default disabled in "Account" widget *Correction: Mysterious crash in SKGTreeView::onExpand -- Stephane MANKOWSKI Wed, 23 Nov 2011 21:44:09 +0100 skrooge (1.1.0) *Correction bug 283683: Can not add a new operation after modifying the values on an existing one *Correction bug 284220: Closed account still showing up in accounts combobox of "operations" tab *Correction bug 283840: Skrooge is unable to download units for a past period, but it works for the current day ==> Better warning message *Correction bug 284073: Expressions in splitted operation amount are not calculated *Correction bug 283842: If I add today a past operation in a different unit than the principal, the amount calculated uses the present unit value, and not that of the specific date *Correction bug 284752: Skrooge does not look for Grantlee at build time *Correction bug 284843: OFX import does not work on UTF-8 encoded files *Correction bug 285289: Misspell found: reconciliation instead of reconciliation *Correction bug 285880: Cumulative amount of main categories do not appear *Correction bug 286538: Renaming categories doesn't rename relevant search/process rules (not fixed but better error management) *Correction: Better colors in "5 main variations" widget for dashboard *Correction: Installation of grantlee_skroogefilters.so in only one place and not hardcoded *Correction: No more error when importing skg file with payees *Correction: Addition of an error message on loading of a document generated by a most recent version (example loading on a 1.0.0 document into Skrooge 0.9.1) *Correction: Addition of missing date for x axis on unit graph *Correction: Import homebank set types of accounts *Correction: Possibility to remove an empty account without warning *Correction: Better performances during migration *Correction: Change language of the document on open if the language of KDE has changed *Correction: Better affectation of payees and comments during gnucash import *Correction: Better default size of the "category" panel in the split table to avoid manual resizing *Correction: Better performances during import of multi files by applying "search & process" rules only at the end *New feature: New type of account "Loan", transfer from/to this kind of account are considered as "expenditure" in reports *New feature: New function to remove useless values in unit (the curve is preserved but useless values are removed) *New feature: New tag for grantlee to be able to use standard palette. Colors of the "Default" template are coming from the KDE palette now. *New feature: Possibility to download values of units with regular expressions. *New feature: Possibility to create/modify monthy template directly from skrooge *New feature: More detail in progress bar *New feature: New advice to find and repair operations in groups with only one operation *New feature: New advice to find potential monthly schedule -- Stephane MANKOWSKI Mon, 21 Nov 2011 15:31:03 +0100 skrooge (1.0.0) *Correction bug 280362: Skrooge is not accepting dots or commas *Correction bug 280897: Unit wont set on mt940 import when there are existing operations *Correction bug 280915: The import logic should use an existing account based on bank name read from :20: and the account number read from :25: *Correction bug 282983: Multi-currency transactions not anchored to the exchange rate of the day of the transaction *Correction bug 283246: Some text is hard to read with dark color theme *Correction: Better performances in check box of operation, account, tracker pages *Correction: Grisbi import with split operations does not work *Correction: Capability to open read only file *Correction: Completion on substring available only in "Dropdown list" mode *Correction: To improve performances, the refresh of advices is done when dashboard is activated and only if refresh is needed *Correction: To improve performances, the refresh of models is done for views in current page *Correction: To improve performances, the refresh of graphs is done for graphs in current page *Correction: "Delete unused" of category page tries a delete only on categories really not used *Correction: Various correction in bookmarks (enable/disable in menu, bad management in parent/child relation) *Correction: Cascading delete in categories and bookmarks *New feature: New function to bookmark all opened page in one click *New feature: Addition of "Once a week" for scheduled operations *New feature: Merge of trackers by drag & drop *New feature: "Count" mode in reports *New feature: In table views, when at least one scroll bar is visible, the corner widget allows to display the contextual menu of the header *New feature: Graphs can be corrected by an indice defined in unit page *New feature: Less icon in tool bar by default. New "Fast edit" button in operation editor. *New feature: Add copy menu in contextual menu for cells *New feature: Advice for closed account with amount<>0 *New feature: "Autostart" and "Remove autostart" available in multi selection *New feature: In krunner, A string like "buy 10 ESSO" allows to quickly prepare add a new operation in skrooge. Advices in dashboard allows to finalize the creation *New feature: "Auto start" bookmarks are not opened if the key SHIFT is maintained pressed during the start of Skrooge *New feature: Grouping function in all tables *New feature: New menu to lock/unlock docks *New feature: Allow menu hiding *New feature: "Monthly report" widgets for the dashboard can be set on current month -- Stephane MANKOWSKI Mon, 03 Oct 2011 14:21:04 +0200 skrooge (0.9.1) *Correction bug 271294: Modifying transactions with spaces in their amounts causes them to be reset to 0 *Correction bug 275963: Operations imported in the primary currency unit, not the account unit *Correction bug 278004: Skrooge installs library files with wrong version numbers *Correction bug 278220: Wrong values in Monthly Report "Amounts in accounts" *Correction bug 279421: General reports problems/request *Correction bug 275956: Possibility to display different accounts in different currency units *Correction: Change icons and remove useless icons *Correction: Hide useless "Add" and "Update" buttons in amortization table of "Simulation" page *Correction: No display of initial value (0000) in graph when history mode is not selected *Correction: Now the forecast period is equal to the real period *Correction: Addition of "Add category" in contextual menu of "Category" page *Correction: Differentiation between "Sum" and "Pourcent" mode of PIE graphs *Correction: When "operation" page is an a particular account, the editor is cleaned with this account *Correction: Remove password when anonymize a document *Correction: Better performance by simulating "materialized views" with tables (used for categories and budgets) *Correction: In CSV import, if 2 "amount" columns are found then the first one is considered as a debit and the second one as a credit *Correction: During import, in case of doubt, MM_DD is preferred than DD_MM *Correction: Imports are supporting dates with backslashes like 29\06\2011 *Correction: Better performances *Correction: Saving the state of 'Categories Page' ignores the resized columns with (Auto resize: off) *Correction: CSV import supports multiline file like: date;amount;comment;type "1/1/2010";1000;"transfer 1 from account A to account B";TRANSFER "2/2/2010";2000;"transfer 2 from account A to account C";TRANSFER *Correction: Protection again empty date ==> if the user remove date string then the current date is used *Correction: Toolbar is realy configurable *Correction: Import of encrypted skrooge files *Correction: Better print when many pages are open *Correction: Missing gsb format in import file selection panel *New feature: Graphs in "Bank and Account" page *New feature: Addition of "Jump to the operation" in contextual menu of "Scheduled operations" page *New feature: Properties can be a copy of a file or a link to an existing file *New feature: In all pages, possibility to hide line by using operator - in "Search" field *New feature: Addition of "Highlight" status on catagories and payees *New feature: In reports, the first columns is resizable and has a tooltip for a better display *New feature: "Expand all" and "Collapse all" in category and bookmark trees *New feature: An option to set a frequency of units download (once a day/week/month) *New feature: Properties associated by drag & drop can be copied or linked (ALT+) *New feature: CTRL+C enables copying of selected cells of tables -- Stephane MANKOWSKI Mon, 15 Aug 2011 18:53:00 +0200 skrooge (0.9.0) *Correction bug 273692: Weird overlay in each dashboard widget *Correction bug 268933: Category editing is tedious and confusing *Correction bug 270207: Cannot enter positive value (credit) for operations in my account *Correction bug 270450: Add a wallet as a distinct account *Correction bug 271529: Add a search box to the Categories tab *Correction bug 271708: Wrong account transfer merging when importing QIF files *Correction bug 272863: Allow to choose which wallet store password in *Correction bug 274777: inconsistency between amounts&nb of operations displayed by modules Tiers, Categories and Operations *Correction bug 274993: Generation of forecast in a report depends on the option "auto-write" *Correction: Error during QIF import if unit is already existing *Correction: Open property file with space *Correction: Selected items always on top in graphs *Correction: Symbol in legend when "Point" is the selected mode of graph *Correction: Skrooge crashes on change of icon for folders in bookmark dock *Correction: Show progress bar only when needed *Correction: Bad values when customized dates are changed in reports *Correction: Better draw of pies in graphs *Correction: "Antialiasing" option in settings panel + automatic refresh of graphs after settings modification *Correction: "find and group transfer" does not work if 2 operations with same date and same amount *Correction: Homebank import supports budgets and scheduled operation *Correction: Change "Context" by "Pages" *Correction: Better computation of forecast period for "Scheduled" and "Budget" modes *Correction: Better performance in advice for scheduled operations *Correction: Better proportion in reports in BUBBLE mode *New feature: Formula is autorized in splitted amount (must start by =) *New feature: Ensure visibility of selected items in graph *New feature: New logo with rupee symbol *New feature: New button to reset internal filter in reports *New feature: Settings for "Reports" to select colors *New feature: Information zone in budget to display budgeted amount based on selected budgets *New feature: New contextual action "New category" on categories *New feature: Balance and balance of the day in account widgets (table, dashboard) *New feature: Merge of an imported operation with a manual operation is now possible even if amounts are different *New feature: Button on "Scheduled operations" to jump to the operation template for edition *New feature: New advice to align scheduled operation amount with the last amount inserted *New feature: New kind of graph "stack of columns" *New feature: New kind of graph (values in % of columns) *New feature: New setting to select the color of outline in reports *New feature: New setting to enable/disable balances computation -- Stephane MANKOWSKI Mon, 06 Jun 2011 14:00:49 +0200 skrooge (0.8.1) *Correction bug 259417: Units: graph unreadable when values are missing for some dates ==> "Show origin" allows to show/hide the origin of the graph for a better display *Correction bug 259416: Report: showing limits, average and tendency does not work in mode "Sum" *Correction bug 259414: Feature request: select previously selected tab when closing a tab *Correction bug 259412: Date chooser field: keyboard shortcuts do not work *Correction bug 257324: No icon for Skrooge in the Gnome menu *Correction bug 261001: Better integration on OS X *Correction bug 261318: Amount field calculator gives too many digits *Correction bug 262511: Wrong widget placement in properties subwindow *Correction bug 263263: Separate field for income and expenditure when importing CSV files *Correction bug 263716: Conversion multiple records to "transfer" type cause all have the same ammount *Correction bug 266703: Window exceeds screen size on Netbook *Correction bug 267442: Support for mt940 files *Correction bug 267773: Skrooge always start maximized *Correction bug 267996: Export CSV not unique identifier *Correction: Bad fullname and cumulative amount on categories after a drag and drop *Correction: Import csv with "sign" column before "amount" *Correction: All items are in "Skrooge" category in "Configure shortcuts" *Correction: No symbol for curves of indexes *Correction: "XX is an old tracker" advice does not give the right result when after 31 december *Correction: GNUCash import creates sometimes "wrong" splits with values close to 0 *Correction: Better initial state for the window (docks, maximized) *Correction: Bookmark of report *Correction: Many small correction in "interest" computation (tooltips, items in combo box, computation, ...) *Correction: Bad unit in "unit" page for units having a unit reference *Correction: Better tooltips in report (usefull for huge report where lines title is not visible) *Correction: Better management of codex for exports *Correction: Bad value when update of transfer is done from target account of the transfer *New feature: Import csv with ' as cote (for "Money Manager Ex" exports) *New feature: Import csv is now possible on file without header *New feature: Import csv supports more than one "category" column *New feature: Import "Money Manager EX" file *New feature: Change icon on bookmarks *New feature: "Open potential duplicates" *New feature: Massive update on budgets *New feature: Delete is more secured. *New feature: Force mode on delete. *New feature: Possibility to change the account of operations even when only operations of one account are displayed (useful for credit card) *New feature: New "Search & Process" panel *New feature: Property dock is able to display all properties *New feature: New "About" panel using KDE 4.6 features *New feature: Better mass update on "account", "payee", "tracker" and "unit" pages *New feature: Possibility to merge accounts by using massive update on name of accounts *New feature: Possibility to merge payees by using massive update on name of payees *New feature: Possibility to merge units by using massive update on name of units *New feature: Possibility to merge categories by using massive update on name of categories *New feature: Timeline in reports *New feature: Some fields are directly editable in view *New feature: Completion for all fields with operators (=upper and =lower for the moment) *New feature: New "stacked area" graph type *New feature: New "bubble" graph type *New feature: New button in "operation" page to freeze/unfreeze all fields with text *New feature: Better zoom widget in contextual menu of reports -- Stephane MANKOWSKI Mon, 14 Mar 2011 15:40:34 +0100 skrooge (0.8.0) *Correction bug 250350: Impossible to update an operation of a closed tracker *Correction bug 250403: Dashboard "Shares & Indexes" shows wrong percentaged variation *Correction bug 250677: Bank account choice do not use the country information *Correction bug 246973: Dashboard should be more customizable *Correction bug 251465: Wrong totals with second currency accounts *Correction bug 252869: Skrooge doesn't import KMM bank names correctly *Correction bug 255133: Skrooge crash on ofx import (With wrong data format. Bug in libOFX) *Correction bug 221207: Budget and forecast for accounts *Correction bug 256214: Skrooge after full screen mode I have only StartPage *Correction bug 257322: Installation doesn't depend from "QCA OSSL plugin for libqca2" (libqca2-plugin-ossl is not optional) *Correction bug 258307: comment from main split operation duplicated *Correction bug 258621: Skrooge crashes when KDE session is closed *Correction: Better dashboard display by using a flow layout *Correction: Bookmark of report having "Columns: -- Nothing --" *Correction: Support of "!type:prices" for QIF import and export *Correction: Better export KMyMoney *Correction: Better detection of double during imports *Correction: Protection again sql injection *Correction: Graph redraw even on hidden tabs *Correction: Crash on selection of a cell when graph is hidden in reports *Correction: Refresh of page in case of reset default state *Correction: Boorkmark of "operation" page in template mode *Correction: In report, hide columns or lines without property *New feature: On reports, average and limits are available if "All values in positive" is used too *New feature: Download of all additional information as properties for units (new setting to activate this mode) *New feature: Skrooge is able to store passwords in KDE wallet (new setting to activate this mode) *New feature: Scheduled operations with warning are in bold in dashboard *New feature: Show/hide properties as a column in tables *New feature: Auto point of imported operations to obtain the expected final balance *New feature: Reorder widget in dashboard by drag & drop *New feature: Floating panel in dashboard to remove or zoom widgets *New feature: Accounts can be merged by drag & drop (useful after an import) *New feature: Units can be merged by drag & drop (useful after an import) *New feature: Automatic import of csv columns as properties based on regular expression *New feature: New report capabilities *New feature: Sub total in reports *New feature: New advice for bank without account *New feature: New icons for banks of South Africa (Thank you David) *New feature: OR operator (+) supported in string filters *New feature: New contextual menu in html pages for export as pdf, odt, image and copy *New feature: Possible to show/hide items in context list *New feature: Forecast based on budgets *New feature: Multi selection in report table and graph *New feature: New "show" button *New feature: Better performances on dashboard *New feature: Better performances on tracker page *New feature: New function on operation: "Merge sub operations" *New feature: New advice for budgets *New feature: Possibility to dismiss kind of advices *New feature: Hide tendency line column -- Stephane MANKOWSKI Mon, 06 Dec 2010 15:31:21 +0100 skrooge (0.7.3) *Correction bug 245847: skrooge 0.7.3: 'pow10' was not declared in this scope *Correction bug 213786: Account balance is not displayed *Correction bug 246178: Dashboard "Income & Expenses" widget counting transfers *Correction bug 246408: Skrooge prints hardcopy *Correction bug 246977: In reports from selected data the date selection should be all data *Correction bug 247445: Linker error in skgbasemodelertest/skgtestnodes.cpp *Correction bug 246976: 'Select all' option in menu edit *Correction bug 249955: No password request after hardware crash *Correction: Better management of print option (collate, nb copy, from, to, last page first) *Correction: Do not authorize creation of operation with "-------" *Correction: In report, capability to create history with of property *Correction: In report, do not allow hiding table or graph by resizing *Correction: Import QIF with !Account section containing more than one account and with D attribute (Thank you Dennis) *New feature: Properties with a 'http' or 'file' url as value can be opened from skrooge (useful to set bank site on an account) *New feature: New daskboard component to know money per bank *New feature: Bookmarks in a menu *New feature: Context in a toolbar (useful for small screen) *New feature: Advice widget in dashboard *New feature: Full screen (useful for small screen) *New feature: Addition of file as property by drag and drop *New feature: Tables are scrolled "bottom" or "top" based on sort order -- Stephane MANKOWSKI Sun, 05 Sep 2010 07:36:37 +0200 skrooge (0.7.2) *Correction bug 237498: Skrooge crash on saving preferences (when system tray is not available) *Correction bug 238087: kAmountEdit widget in Operations plugin isn't properly localized *Correction bug 238477: Cannot open base if partition is full *Correction bug 240600: Skrooge must be able to export as a sqlite database *Correction bug 240640: Skrooge crash after password entered - input file DELETED at failure *Correction bug 234597: Gnucash import issues with two accounts with the same name *Correction bug 240601: Skrooge must be able to export an anonymized file *Correction bug 243738: Import of Gnucash file that has CNY currency fails *Correction bug 245254: Category creation failed on first level *Correction: Drag & drop of categories *Correction: Import skg file with tracker or interest simulation *Correction: No XML export of tables sqlite_sequence and sqlite_stat1 *Correction: Layouts compatible with small screen (1024x768) *Correction: Open right page when click on "Estimated interest" in dashboard applet *New feature: Zoom on tables by using CTRL+wheel *New feature: Search button is "Search & process" page to be able to search operations without creating a rule *New feature: Click on a column in "Search & process" editor removes the column *New feature: CTRL+F opens the "Search & process" panel with a condition based on current selection *New feature: Stability of colors in graph *New feature: Selection of colors in graph (saved and restored) *New feature: "Add property" to add easily properties *New feature: skg files saved on a FTP server can be loaded directly from Skrooge. Save is not possible. *New feature: New "Payee" page *New feature: Merge of payees by drag & drop *New feature: Report plugin is able to display graph based on properties *New feature: Possibility to select icon file for a bank *New feature: Any kind of file as property *New feature: Go home -- Stephane MANKOWSKI Sat, 24 Jul 2010 10:00:00 +0200 skrooge (0.7.1) *Correction bug 233895: Switching account from 1 type to another with multi-sel is modifying the initial balance *Correction bug 233930: QIF address field is not imported *Correction bug 234595: Better handling of category deletion ==> Reparent operations on parent category when a category is removed *Correction bug 234608: Some gnucash notes are lost during import phase *Correction bug 234771: Problem importing ofx file *Correction bug 234845: Bad Account after importing ofx *Correction bug 235689: Cannot localize quotation marks *Correction bug 234596: Customisable date format in operations panel *Correction bug 236753: Search but not process on attribute *Correction: Rename "Import CSV unit..." in "Import currency values..." *Correction: Better management of constraints in data model *Correction: Conflict on categories when importing twice a gnc document *Correction: Conflict on categories when importing twice a xhb document *Correction: Conflict on categories when importing twice a gsb document *Correction: Conflict during property update *Correction: Modification of trackers in splitter operations from "Search and process" *Correction: Transfer when signe + is specified before the value *Correction: Various modifications on "Search & Process" *Correction: Replacement of [%1] by '%1' for localization *Correction: No more direct sqlite prerequisit *New feature: Better performances on "File/New" (first Save is longer) *New feature: Usage of KNewPasswordDialog and KPasswordDialog for password protection *New feature: Applet for dashboard to display tip of the day *New feature: CSV import of splits and transfers *New feature: CSV import is able to oncatenate many attributes in "comment" or "payee" *New feature: CSV import is to import unknown attributes as properties *New feature: Export XML *New feature: "Search & Process" is able to search on properties values *New feature: "Search & Process" is able to update, insert and delete properties (prop='' to delete it) *New feature: All currencies are now available in unit page (Thanks to KCurrencyCode) *New feature: Properties are displayed on tooltips *New feature: Open property picture associated to an object -- Stephane MANKOWSKI Mon, 10 May 2010 15:21:33 +0200 skrooge (0.7.0) *Correction bug 225855: Monthly Report: difference in percentage is wrong *Correction bug 225980: Share download not in primary currency : value not correct *Correction bug 226451: .skg file incorrectly identified as password-protected ==> New document icon to identify encrypted files *Correction bug 228808: Gnucash import: scheduled operation at 0 euros *Correction bug 228904: Gnucash import should not take into account recurrent operation containing loan formulas *Correction bug 230175: Sometimes report plugin resizes Skrooge over the screen size *Correction bug 232937: Search & Process : if a category has no operation yet, it doesn't appear in the possible categories for "update" *Correction wis 228901: Manage Liability accounts (loan, etc...) *Correction wis 197409: There's no way to define initial balance of non-OFX account *Correction wis 224933: A legend in the graphics *Correction wis 224042: Possibility to store several CSV import schemes ==> Implemented by regular expression in automatic mapping. *Correction wis 225818: Change skrooge desktop file description *Correction wis 226963: Export CSV of split operations *Correction wis 228170: Skrooge must be able to import skg file *Correction of forecast computation on scheduled operations *Correction of export of "Initial balance" for QIF and CSV *Correction of import of "Initial balance" for QIF and CSV *Correction of import of "Initial balance" for OFX *Correction: Better error message in case of repository of document is RO *Correction on confirmation message *Correction selection on graph (histogram and stack) *New feature: "Weighted moving average" in reports *New feature: Specific font and color for disabled schedule (nbtime = 0) *New feature: Addition of "First date" and "Last date" in trackers *New feature: Amortization table *New feature: import gnucash document *New feature: import kmymoney document *New feature: import skrooge document (can be used to merge documents) *New feature: import grisbi document *New feature: import homebank document *New feature: export kmymoney document *New feature: export skrooge document (without history) *New feature: possible to create a bookmark even when a bookmark is already selected *New feature: button to clean history (reduce the size of the file) *New feature: all settings in only one file. WARNING: check your settings. *New feature: generic modeler is ready to be used by other applications. *New feature: "5 main variations" in monthly report. *New feature: New key accelerator to enable editor of current page -- Stephane MANKOWSKI Mon, 05 Apr 2010 20:00:00 +0200 skrooge (0.6.0) *Correction wis 215668: Dashboard is too big to be a real dashboard *Correction bug 216520: Incorrect import of a transfer when inside a splitted operation (a splitted operation can not be a transfer) *Correction bug 217896: UK Currency and Date formats displayed for Scheduled Transactions in Dashboard *Correction bug 217743: Configuring Banks and Accounts Section (Bank name update issue) *Correction bug 219791: No progress bar during export QIF *Correction bug 219750: Delete key in split table remove the full line *Correction bug 214508: Provide a balance evolution graph *Correction wis 220659: Option to "Apply rules on to imported operations" automatically after an import *Correction cra 220936: Crash on double click on bookmarks *Correction cra 222340: Freezes after some time *Correction bug 222339: CVS import: problem with decimal point and comma *Correction wis 220663: Selected operations must still visible after a sort modification *Correction wis 223848: make libofx an optional dependency *Correction wis 224676: keyboard shortcut for modify and add operation *Correction wis 209314: key scrolling does not work, and click on a line has odd behaviour *Correction bug 224932: Graphic Report SVG export bug + wish on a legend *Possible to define favorite account *Possible to define favorite search *New gui for search and process *Delete icon on each suboperation line *Compatibility with bespin theme *Do not collapse tree after editing one of its items *More options in "Report" page *New function to delete unused categories *Selection in pages list is now synchronized with current page *New option in contextual menu of report to hide bottom tool bar *Edition of splitted operations by single click *Clean button in operation table is renamed "Clear form" *Better export QIF for investment *Better display on reports (average, min and max are displayed if only one curve is drawn) *Better display on reports (linear regression is displayed if only one curve is drawn) *Option to show/hide average and limits in graph *Selection of year for interets computation *Correction in sum of operation computation when suboperations are selected *Graph proportion adapted to view size *"Account position" is replaced by "Ending balance" *Avoid cpu loop when double click on operation fields on KDE 4.4 *Completion based on substrings *Better import of QIF files when both side of the import do not have exactly the same date *Correction on update category and tracker for transfers *Completion on comments -- Stephane MANKOWSKI Sat, 06 Feb 2010 09:00:00 +0100 skrooge (0.5.5) *Disable some functions on sub-operations *Correction on update of a splitted operation by a split returned by Fast Edition *Correction bug 215995: SQL Error when attempting to display a report in history mode *Correction bug 215754: Invest account is incorrectly imported as current account *Correction bug 214809: Incorrect import of a transfer *Correction bug 214851: Incorrect import of 'investment account' QIF file *Correction bug 216348: Account filters synchronisation problem in the operation HMI *Correction bug 216522: Incorrect import of transfer (twice imported) *Correction bug 216551: Click in blank area make 'date' widget to extend its size *Correction bug 216514: Incorrect import of QIF file when account names are similar *Correction bug 216520: Incorrect import of a transfer when inside a splitted operation (transfer of suboperation is not supported) *Correction crash 215992: Skrooge crash when clicking on "rapport" menu *Correction regression on "Open report" (P0) *Invertion of colors in report (more saturation for new operations) -- Stephane MANKOWSKI Sun, 29 Nov 2009 15:00:00 +0100 skrooge (0.5.4) *Correction bug 211579: Irregular percent value in monthly report amounts in accounts *Correction bug 212313: Can not update a lot of operations *Correction bug 211029: Skrooge should have an better account evolution graphic *Correction bug 213783: Account balance computation is inaccurate *Correction bug 214045: Import CSV date format problem *Correction bug 214097: Can not search on multiple criteria. (OR is not supported) *Correction bug 214157: Impossible to import an ofx file from a directory containing special characters *Correction bug 214462: Does not use primary currency unit when importing, and does not warn on import of splitted operation with multiple currencies *Correction bug 214447: Auto save the open document at closing *Correction bug 214794: Incorrect report of warning when importing QIF file *Correction bug 214809: Incorrect import of a transfer *Correction bug 214849: CSV export from grid is not correct *Correction bug 214904: Can not download a stock/share quotation *Correction bug 214851: Incorrect import of 'investment account' QIF file *Correction bug 215114: Button to customize dashboard *Correction bug 215620: Can not import QIF file with skrooge version SVN 1052520 *Correction bug 215656: History reports are wrong if first date is not selected *Correction bug 215658: Some editors are modified when a bookmark is created *Correction on double click of a template of transfer *Update of both side of a transfer is now possible *Only one fast edition. User is be able to lock some fields before. *Interest can be computed with 360 and 365/366 days method *New splashscreen size *New graph gui with "Quarters", "Semesters", "Weeks" and "Days" *Zoom with CTRL+wheel on graph *Dashboard is automatically launched when a new document is created *Use of graph component in unit page *New button to clean editor in operations page *Correction on scheduled transfers *New report widget for dashboard (all reports can be added to dashboard) *Addition of "Del" shortcut to delete suboperations in split panel *New tooltip on operation status *New function "Open sub operations" to display all sub operations. Useful to filter them. *New function to reconciliate an account from bank page *Better QIF import/export of account type -- Stephane MANKOWSKI Mon, 23 Nov 2009 14:00:00 +0100 skrooge (0.5.3) *Correction bug 209451: Display quantity of each unit *Correction bug 209457: Number of decimal for each unit must be different *Correction bug 209453: Impot must avoid double even when operations are not validated *Correction bug 209529: Unable to reconcile. Delta zero but "Validate checked operations" tick still grayed out *Correction bug 208939: "Search and process" does not work anymore *Correction bug 209610: Skrooge doesn not work if "Maximum undo depth" is 0 *Correction bug 209542: Automatic conversion of schedule *Correction bug 209672: Amount of indexes must be displayed without unit symbol *Correction bug 209705: Importing investments from csv doesn't import the dollar amount of shares purchased *Correction bug 209705: Find&Group is now able to detect share purchase/sale *Correction bug 209702: Need the ability to be able to manually group transfers *Correction bug 209914: executable bits set for skgalarmboardwidget.h *Correction bug 209905: currency import is broken *Correction bug 209912: rpmlint warnings after installation: unused-direct-shlib-dependency *Correction bug 209053: Savings account support request *Correction bug 210946: columns are always resized to content when opening operations tab *Save icon in tab bar to overwrite bookmarks or current context *New dashboard plugin for highlighted operations *New dashboard plugin for estimated interests *"Backward" & "Forward" navigation on pages *New unit "Swedish krona" *New command to open operations modified during last user action (useful after an import or a processing) -- Stephane MANKOWSKI Mon, 19 Oct 2009 12:00:00 +0200 skrooge (0.5.2) *Correction bug 207927: skrooge summary field uncomplete bank account name *Correction bug 208130: 'Import CSV Unit' menu puts data into the 'Operations' tab *Correction bug 208210: Multiple clause research/update in french *Correction bug 208194: Skrooge loose all data on file migration *Correction bug 208040: Error when entering shares information *Correction bug 208459: Skrooge crashes when changing tab *Correction bug 209317: key scrolling very long *Better performance in report by using QTimer *Better performance bank page by using QTimer *New SKGDateEdit with more features *Delivery of default categories and bookmarks for pt. Thanks Caio de Campos Ferreira. *Better performance when opening pages *Correction on monthly report for a better display with dark theme *New widget on dashboard for alarms *SKGDateEdit validation on lose focus *Automatic detection of CSV separator during import -- Stephane MANKOWSKI Sun, 04 Oct 2009 16:00:00 +0200 skrooge (0.5.1) *Correction bug 205471: Impossible to know how to check an operation *Correction bug 205466: Date missing in reports *Correction bug 193426: Ability to create from scratch a "recurrent operation" *Correction bug 203787: Balance should be displayed for each operation in the operation context. Correction done: balance is displayed on tooltip because it is better for performances than in column. *Correction bug 206894: Crash second import CSV *Correction bug 206459: "Search & process" must be able to do complex update *Correction bug 199539: Dashboard must be customisable *Correction bug 207249: rpmlint error: debuginfo-without-sources (including a fix) *Correction bug 207246: rpmlint warning shared-lib-calls-exit /usr/lib64/libskgbasemodeler.so.0.5.0 exit@GLIBC_2.2.5 (for fedora packaging) *Correction bug 207232: skrooge must use kfilterproxysearchline *Correction bug 207274: "Fast edit" behavior must be modifiable by settings *Correction bug 191966: Treeviews collapsed when updated *Correction bug 207672: Align amount values on the right for cleaner views *Correction bug 207713: Display some information after applying a process *Correction bug 200790: Search creation doesn't take not validate predicate *New function to create template of operations *New function to schedule templates *New function to create template from existing operations *Double click on template creates the operation *New shortcut for import *Attribute to define the maximum number of occurrence for scheduled operations *Attribute to define the last occurrence date *A setting allows to create automatically a template when an operation is scheduled *Selection is done on duplicated object after a "Duplicate" *Selection is done on created template after a "Create template" *Correction message in history when an object is deleted *Download button always visible on unit plugin *Infinite symbol when number of occurrences is not checked *Addition of "Custom..." on graph dates *New spash screen *New function to overwrite bookmarks after a modification *Filter capability on "search & process" table *Editors are no more clean when the selection is empty. A second click is needed -- Stephane MANKOWSKI Sun, 20 Sep 2009 00:00:00 +0200 skrooge (0.5.0) *Correction bug 201316: import qif extra tag support *Correction bug 201157: Graphs no longer displayed *Correction bug 201289: Compiler error on GCC 4.1.2 (enum with KDE_EXPORT or similar macro) *Correction bug 201451: qif import other liability account type *Correction bug 201697: Pointed operation can be deleted *Correction bug 201800: Filter issue with number formatting *Correction bug 202167: Payee list should be ordered in a case insensitive way *Correction bug 202341: Combobox lists are not sorted in a locale-aware way *Correction bug 202384: Skrooge always wants to update report bookmarks on exit *Correction bug 202636: Hidden columns are sometimes displayed *Correction bug 203894: Skrooge crashes when launched with --nofork *Correction activation of "Values" button in "Units" page *New password is no more displayed when changed *New function to merge an imported operation with an operation manually entered *New refund icon *New widget for dashboard "Shares and indexes" *Modification titles on "operation" pages to differentiate "operations" and "sub operations" *"sub operations" can be identified by a specific font and color (see settings) *Correction bug: Created search is not selected after creation *Correction performance issue on zoom when antialiasing is enable *Addition of 5 main categories of expenditure in monthly reports *Rename "Bookmark" for operation by "Highlight" *Rename "Trait" by "Process" *Set minimum size for amounts fields *Only one "Import..." command for all supported format. *Support of QFX import *New settings for import CSV *Dashboard is now clickable *Dashboard is modifiable (see contextual menu on each widget) and state can be saved *Addition of "Fast edition" without amount modification. It is useful to modify imported operations *Only one instance of skrooge can be launched. *Imports can be done in command line. Example "skrooge myfile.ofx" with skrooge running *If an invalid expression is entered for the amount, the field is written in red, and the expression is kept to allow correction from the user (previously, 0 was displayed). *"New tab" is now managed by Ctrl+Shift+T *Popup to ask if you want to save current state of pages. *Bookmark storage is no more dependant of language translation -- Stephane MANKOWSKI Fri, 28 Aug 2009 21:00:00 +0200 skrooge (0.3.0) *Correction bug 191970: Attach receipts (images) to transactions *Addition of "Trackers" for lines in report *Correction bug 195254: Do not allow to link operations to a closed tracker *Correction bug 195026: A setting must allow to clean history when the application is [saved] *Correction bug 194826: End user must be to validate an import *Correction bug 196444: Can not validate reconciliation (delta = -0.00) *Correction bug 196745: Categories are not added to a split operation *Correction bug 197287: Add backup file management *Correction bug 197288: Manage working document copy *Correction bug 197835: Reconciliation mode : currency problem *Correction bug 198077: Comments do not appear in every Operations windows *Correction bug 198583: foreign currency accounts should display in their native currency in dashboard. *Correction bug 198786: Categories are not easily read *Correction bug 199196: build error in skgbankgui *Correction bug 199543: Splash screen display must be defined by settings *After an import, skrooge is able to execute some rules to clean imported operations *Correction in dashboard *Addition of "Reset state" on tabs to reset default state of plugins *Most important category and refund are displayed for split operations *Display detail of selected operations in information area of "operation" page *Main tab position can be selected in settings -- Stephane MANKOWSKI Sat, 11 Jul 2009 16:00:00 +0200 skrooge (0.2.9) *Correction bug 2787146: Single click on bookmarks *Correction bug 191972: Selection is not well kept *Correction bug 191975: Add Labels for X values in histograms and stack reports *Correction bug 191968: Information string on top of page is too long (no word wrap) *Correction bug 192687: fonts too large on report *Correction bug 192832: Do not take amount sign into account for transfers *Correction bug 191967: Skrooge must be able to display an history global and for each account. *Correction bug 193423: context list scrolls down only after 8 mouse molette rotation *Correction bug 193431: "recurrent operation" trigger can not be set on D day *Correction bug 193421: bugs to be registered via bug database (not email) *Correction bug 194650: Fast edit must work on Tracker attribute *Correction bug 194765: Number of operations by account must be displayed in bank plugin *Addition of bank icon on account combo boxes *Addition of Canadian dollar *Addition of one more view (based on selection) in operation plugin *Better managment of dependency between units *New settings on unit download *Skrooge tries to find the most adapted account during import file without account information inside *Update of nls part of data model when language is changed *"Open report" on an element of a report open a new report with exactly same settings than first one *Addition of "scheduled operations" in dashboard plugin *New operation editor *Better management of messages in status bar *New editor in unit plugin *Middle click is able to open new page from context or bookmarks -- Stephane MANKOWSKI Sun, 31 May 2009 23:00:00 +0200 skrooge (0.2.8) *Correction bug 2782399 :Skrooge must create a backup file *Correction bug 2783111 :Typo *Correction bug 2515571 :New plugin to follow refunds *Correction bug 2785938 :Single click *Correction bug 2786183 :Load standard categories? *Correction bug 2682777 :Label are not well placed *Correction bug 2579926 :Improve category plugin performances *Correction bug 2665265 :Edit names directly in treeview *Correction for amount comparison in validation mode *Correction import ofx when bankid is empty in ofx file *Correction mime type for KDE4 *Better performances on open document with password required -- Stephane MANKOWSKI Mon, 04 May 2009 15:00:00 +0200 skrooge (0.2.7) *Correction bug 2513827 :global print function *Correction bug 2692667 :Automatic icon resize is driven by bookmarks only *Correction bug 2714592 :Skrooge must be able to manage properties on all objects *Correction bug 2733958 :Auto hide *Correction bug 2747379 :Only allow to "pre-check" operations *Correction bug 2750464 :Impossible to update the date of a split operation *Correction bug 2778333 :Enhance hidden panels discoverability *Correction bug 2777697 :bookmark modifications are not kept when closing skrooge *Old method to split an operation is no more available *"Undo document" is no more in toolbar by default *Remove useless icons from tool bar *When "Save" is clicked in a new document, automatically interpret it as "Save as" *New menu with shortcuts to open pages *Better automatic linear scale in reports -- Stephane MANKOWSKI Mon, 27 Apr 2009 15:00:00 +0200 skrooge (0.2.6) *Correction bug 2692651 :antialias on graphs *Correction bug 2692665 :Wrong currency label in stock tab *Correction bug 2692605 :Title of a report for a selection contains only ",,,," *Correction bug 2692648 :New dialog box on exit *Correction bug 2692664 :add support for split & grouped operations in fast edition *Correction bug 2692656 :More details on recurrent operations view *Correction bug 2645610 :Bad performance on "find transfers" *Correction bug 2692681 :Reconciliate mode in operations view *Correction bug 2706987 :no report generated *Correction bug 2716734 :Better category & unit creation during operation creation *Correction bug 2720760 :Popup messages are displayed twice -- Stephane MANKOWSKI Sun, 29 Mar 2009 20:00:00 +0200 skrooge (0.2.5) *Correction bug 2664613 :Not possible to show a column without reseting all *Correction bug 2633375 :2 columns for quantity *Correction bug 2674862 :Bad performances on undo/redo for categories *Correction bug 2675606 :Bookmark reorder doesn't work *Correction bug 2685241 :Add postive sign in amount field for positive operations *Correction bug 2685236 :Option to ask again if modified bookmark should be saved *Correction bug 2685270 :Impossible to modify comment on operation and sub operations *Correction bug 2687115 :filter value is not save whan bookmark a report *Correction bug 2685335 :Pie like in firelight *Debug plugin is able to do a "EXPLAIN QUERY PLAN" *Path for bash is not more hardcoded in script for BSD compatibily -- Stephane MANKOWSKI Mon, 16 Mar 2009 14:00:00 +0100 skrooge (0.2.4) *Correction bug 2608762 :Cannot create a bookmark folder if no bookmark exist yet *Correction bug 2633444 :Add "import std categories" in import menu *Correction bug 2638120 :Unable to import cvs or qif from "la banque postale (fr) *Correction bug 2564982 :Creation of default bookmark *Correction bug 2640959 :Impossible to import OFX file -- Stephane MANKOWSKI Mon, 02 Mar 2009 20:00:00 +0100 skrooge (0.2.3) *Correction bug 2608762 :Creation of category branch in one shoot *Correction bug 2608768 :Crash in category creation *Correction bug 2586878 :skrooge crashes if category too deep *Correction bug 2446175 :better split operations *Correction bug :sum column always displays 0 in category page *Addition of comment on suboperations *Better performances to compute next values for operation numbers *Icon in system tray *"export SKGTRACESQL=xxx" is able to trace all sql order taking more than xxx ms -- Stephane MANKOWSKI Mon, 23 Feb 2009 21:51:12 +0100 skrooge (0.2.2) *Correction bug 2556346 :README should list kdesdk-scripts as buildtime dependency *Correction bug 2556406 :Pound sterling missing in currency list, difficult to add *Correction bug 2556340 :CMakeLists should use correct libraries and check for Sqlite (Thank you lindevel for the patch) *Correction bug 2555861 :"make package_source" contains too many files *Correction bug 2557366 :Wrong password *Correction bug 2556381 :Impossible to change negative quantities into positive ones? *Correction bug 2530932 :Better autostart bookmarks management -- Stephane MANKOWSKI Wed, 11 Feb 2009 21:51:12 +0100 skrooge (0.2.1) *Correction bug 2517386 :Move of category is not done *Correction bug 2519334 :Smooth scolling in category view *Correction bug 2517388 :Selection must be set on created operation *Correction bug 2519847 :Duplicate operation *Correction bug 2520516 :Security of skg file *Correction bug 2545021 :compilation fails because po/listFiles.sh is not executable *Correction bug 2549911 :Import standard categories *Correction bug 2526148 :Double click on graph in report *Correction bug 2520530 :KToolBarPopupAction for undo/redo *Addition of icon for stocks *Bookmark can be deleted from contextual menu *Icons are resized relative to list width -- Stephane MANKOWSKI Sun, 01 Feb 2009 20:00:00 +0100 skrooge (0.2.0) *Correction bug 2489823 :automatically remember changes on columns for bookmarks *Correction bug 2487934 :Specific Column for "scheduled" icon *Correction bug 2487866 :deselect lines in table views *Correction bug 2487981 :add a column for total of operations including subcategories *Monthly report is now base on QWebView and contain google graph *Addition of exports in report tables (TXT, CSV) *Report can be opened from bank, operation or unit page *Report can be opened from report *Better graph *Addition of print *Long transaction can be interrupted *Better warning message with history -- Stephane MANKOWSKI Mon, 19 Jan 2009 20:00:00 +0100 skrooge (0.1.9) *Better contextual menu on tables *New feature in monthly report *Better performances for monthy report generation *Better graphics in report plugin *Addition of exports in all tables *Addition of exports in report graphs (PDF, SVG, picture) -- Stephane MANKOWSKI Sat, 03 Jan 2009 20:00:00 +0100 skrooge (0.1.8) *Correction bug 2299303 :Calcul de balance erroné *Correction bug 2446162 :Distinction for future operations *Correction bug 2446184 :Reduce spacing between rows *Correction bug 2256687 :No more icon in application menu *Correction crach in qtdesigner due to SKGTableView *Addition "open bookmarks" to display all bookmarked operations *Addition of sale of stocks *Addition of "split of stock" -- Stephane MANKOWSKI Tue, 22 Dec 2009 20:00:00 +0100 skrooge (0.1.7) *Correction bug 2385144 :Unexpected display of unit in operations list *Correction bug 2390926 :Problem with Action/$/€ *Correction bug 2390747 :Operations transferred not found *Correction bug 2384834 :Multi-Selection and Ctrl-P does not work *Correction bug 2311993 :Difference between operation and valuation not done *Correction bug 2385059 :Possibility to remove (modify) buggy unit value *Correction bug: Inversion year(s) and day(s) in recurrent operations *Correction wrong mapping on all table when column are reordered *Correction request 2379612: categories edition & creation *Selection is now kept after modifications *New "Monthly report" plugin *Computation of RIB key *Addition contextual menu on all table *Addition contextual menu on tabs *Addition of short date in tooltip on fancy date *Addition of smooth scrolling in table views *Addition of indexes (CAC 40, NASDAQ, ...) in data model -- Stephane MANKOWSKI Tue, 15 Dec 2009 20:00:00 +0100 skrooge (0.1.6) *Support of import unit values in CSV format like: date;value 01/01/2008;50 03/03/2008;60 *Correction bug 2340201 :crash on QIF export *Correction bug in import if 2 operations with same attributes (date, amount, ...) *Correction concerning performance issue in all tables *Correction bug 2299354 :Ability to change and memorize column width *Columns can be switched in "auto resize" mode *Correction bug 2298982 :An account shall have a currency *Preferred table's organisation can be save as default *Better organisation of pies in report plugin -- Stephane MANKOWSKI Tue, 01 Dec 2009 20:00:00 +0100 skrooge (0.1.5) *Correction bug 2307068: Incorrect import of QIF file *Columns order is now saved in bookmark for operation, account, recurrent operations and unit plugins *Sort is now saved in bookmark for operation, account, recurrent operations and unit plugins *Correction bug 2327676: Many import QIF correction *Columns can be show or hidden (see contextual menu) and this state is saved in bookmarks *Better performances (x100) in report. *Correction bug 2316459: skrooge does not support out-of-source build *Correction bug 2298621: Unable to delete a "principal currency". ==> It is now possible to delete a unit except if this unit is already used by at least one operation *Correction bug 2326576: Field empty by default *Correction bug 2306914: "Tip of the day" dialog can not be removed -- Stephane MANKOWSKI Tue, 24 Nov 2009 20:00:00 +0100 skrooge (0.1.4) *New icons *Bookmarks folders are opened sorted and focus is set on the first one *Correction (inversion sign of operations) in transfer creation *Buy stock is now possible *Correction bug 2298773: Unit and amount are not aligned *Correction bug 2298674: Montant en EUR même si unité EUR n'existe pas *Correction bug 2298471: Unable to change type of a unit *Correction bug 2299384: File/Close closes the current page *Correction bug 2299524 *Correction bug 2299519: "Mode" should not be mandatory *Optimisation in open "operation" pages *Correction bug 2299600: Values of a unit are not sorted out *Correction bug 2299947: Unit can not be used if no symbol is defined ==> Symbol is now mandatory *Correction bug 2301337 *Correction bug 2300013:Une ventilation est une catégorie *Correction bug 2278703:Zoom fit when opening report tab *Comment on account *Tab name is now set with the name of the bookmark -- Stephane MANKOWSKI Tue, 17 Nov 2009 20:00:00 +0100 skrooge (0.1.3) *Vertical alignment in all views *Detection of the sign of an operation (during creation) based on category *Average in report *Sum column is now displayed only if more than one column is displayed in report plugin *Correction bug in report when sort is set on last column and the report is refreshed with less columns *Correction abend on delete *Modeler is now able to store messages on transaction. *Display messages by notification *Addition of recurrent operations (creation, update, delete, automatic insertion, warn, ...) *Correction in duplication of recurrent operations: Now, status, bookmark, importation id are not duplicated *Correction on optimisation of undo/redo transaction: optimisation removed :-) *Multi selection is supported by recurrent operations creation icon *Massive update on recurrent operation *Implementation enhancement 2272115 concerning calculator behavior *Correction update of split operations *Set default order in all tables *Sort bookmark by drag and drop -- Stephane MANKOWSKI Sat, 14 Nov 2009 20:00:00 +0100 skrooge (0.1.2) *Support of categories in QIF import *Support of csv file with empty lines *Support of categories in QIF export *Correction bug 2229770: automatic erase of duplicated operations *New design for operation and account plugin *Addition of first draft of recurrent operations -- Stephane MANKOWSKI Tue, 10 Nov 2009 20:00:00 +0100 skrooge (0.1.1) *Optimisation widget refresh after a huge QIF import *Optimisation performance of QIF export *Optimisation performance of CSV export *Optimisation performance of "find and Group transfers" *Addition of "Close", "Close All" and "Close All Other" to manage pages *Correction on download unit *Addition of the name of the file in the title of the man window *Addition of sort in report plugin -- Stephane MANKOWSKI Tue, 03 Nov 2009 20:00:00 +0100 skrooge (0.1.0) * QIF import/export * CSV import/export * Basic graphs * Several tabs to help you organize your work * Infinite undo/redo (even after the file was closed !) * Instant filtering on operations * Infinite levels of categories -- Stephane MANKOWSKI Mon, 02 Nov 2009 20:08:00 +0100 diff --git a/skgbasegui/skgmainpanel.cpp b/skgbasegui/skgmainpanel.cpp index d3cb875ad..9e12ac4db 100644 --- a/skgbasegui/skgmainpanel.cpp +++ b/skgbasegui/skgmainpanel.cpp @@ -1,2740 +1,2743 @@ /*************************************************************************** * Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see * ***************************************************************************/ /** @file * This file defines classes skgmainpanel. * * @author Stephane MANKOWSKI / Guillaume DE BURE */ #include "skgmainpanel.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef KActivities_FOUND #include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include // 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 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 m_pluginsList; QMap m_registeredGlogalAction; QList 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(iProgressBar); if (pointers != nullptr) { progressBar = static_cast(pointers->p1); button = static_cast(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(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(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 (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 pageNotVisible; KConfigGroup prefContextVisibility = config->group("Context Visibility"); int shortCutIndex = 0; QString shortCutPrefix = QStringLiteral("Ctrl+"); int nbplugin = d->m_pluginsList.count(); QList 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(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(kProgressBar); d->m_progressObjects.p2 = static_cast(kCancelButton); getDocument()->setProgressCallback(&SKGMainPanelPrivate::progressBarCallBack, static_cast(&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()); 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 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(act)) { d->m_registeredGlogalAction.remove(id); } } } } QPointer 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 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 > SKGMainPanel::getGlobalActions() const { QMap > 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(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(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(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(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(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(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(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(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(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(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(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(""))) // 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(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 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(m.Type) >= static_cast(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("
"); } 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->setIcon(SKGServices::fromTheme(iType == SKGDocument::Positive ? QStringLiteral("dialog-positive") : + iType == SKGDocument::Information ? QStringLiteral("dialog-information") : + iType == SKGDocument::Warning ? QStringLiteral("dialog-warning") : QStringLiteral("dialog-error"))); msg->setMessageType(static_cast(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); + msg->show(); 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 %1 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& 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 (w); if (kcmb != nullptr) { // Fill combo kcmb->clear(); kcmb->addItems(list); if(kcmb->isEditable()) kcmb->setCompleter(comp); } else { auto* kline = qobject_cast (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.rc b/skgbasegui/skgmainpanel.rc index 54506f27e..c578ce43d 100644 --- a/skgbasegui/skgmainpanel.rc +++ b/skgbasegui/skgmainpanel.rc @@ -1,84 +1,86 @@ File Edit View Panels + + Go Other Tools Main Toolbar