diff -Nru kraft-0.95/Changes.txt kraft-0.96/Changes.txt --- kraft-0.95/Changes.txt 2020-08-28 16:01:48.000000000 +0000 +++ kraft-0.96/Changes.txt 2021-02-27 20:44:46.000000000 +0000 @@ -1,3 +1,20 @@ + +Changes since version 0.95: ######################################### + +- Found new MIT licensed icons to avoid uncertainess with CC license. +- Allow to use the "add new" button in the doc editor to add new + catalog templates. It presets the correct chapter. + +- Fix: Use the xmlArchivePath correctly (#80) +- Fix: Handling of Cancel button in template to doc dialog. +- Fix: Convert newlines in the items to
for the weasyprint doc + generation. +- Fix: In Followup document: If the standard text for pre and post + text of the target document type is empty, the one from the + source document is copied over instead. (#91) + +=> release v. 0.96 (xx, 2021) + Changes since version 0.90: ######################################### - Add Grantlee as templating engine. @@ -15,7 +32,7 @@ - Fix: Also change lastmodified-Timestamp if only an item was added. - Add the user manual. Open it according to user language. -=> release v. 0.95 (xx, 2020) +=> release v. 0.95 (Aug. 28, 2020) Changes since version 0.82: ######################################### diff -Nru kraft-0.95/debian/changelog kraft-0.96/debian/changelog --- kraft-0.95/debian/changelog 2020-08-29 05:40:06.000000000 +0000 +++ kraft-0.96/debian/changelog 2021-02-28 10:20:27.000000000 +0000 @@ -1,3 +1,14 @@ +kraft (0.96-1) unstable; urgency=medium + + * Team upload. + * New upstream release. + * Bump Standards-Version to 4.5.1, no changes required. + * Use secure URI in Homepage field. + * Set upstream metadata fields: Bug-Database, Bug-Submit, Repository, + Repository-Browse. + + -- Pino Toscano Sun, 28 Feb 2021 11:20:27 +0100 + kraft (0.95-1) unstable; urgency=medium * Team upload. diff -Nru kraft-0.95/debian/control kraft-0.96/debian/control --- kraft-0.95/debian/control 2020-08-29 05:30:09.000000000 +0000 +++ kraft-0.96/debian/control 2021-02-28 10:02:33.000000000 +0000 @@ -24,9 +24,9 @@ libqt5sql5-sqlite , xauth, xvfb, -Standards-Version: 4.5.0 +Standards-Version: 4.5.1 Rules-Requires-Root: no -Homepage: http://volle-kraft-voraus.de/ +Homepage: https://volle-kraft-voraus.de/ Vcs-Git: https://salsa.debian.org/qt-kde-team/extras/kraft.git Vcs-Browser: https://salsa.debian.org/qt-kde-team/extras/kraft diff -Nru kraft-0.95/debian/upstream/metadata kraft-0.96/debian/upstream/metadata --- kraft-0.95/debian/upstream/metadata 1970-01-01 00:00:00.000000000 +0000 +++ kraft-0.96/debian/upstream/metadata 2021-02-28 10:02:32.000000000 +0000 @@ -0,0 +1,5 @@ +--- +Bug-Database: https://github.com/dragotin/kraft/issues +Bug-Submit: https://github.com/dragotin/kraft/issues/new +Repository: https://github.com/dragotin/kraft.git +Repository-Browse: https://github.com/dragotin/kraft diff -Nru kraft-0.95/manual/kraft.adoc kraft-0.96/manual/kraft.adoc --- kraft-0.95/manual/kraft.adoc 2020-08-28 16:01:48.000000000 +0000 +++ kraft-0.96/manual/kraft.adoc 2021-02-27 20:44:46.000000000 +0000 @@ -547,19 +547,19 @@ === Output Document Customization -Each document type in Kraft can have it's own template that is used to create -a PDF. The template is filled with values from the document content that the user -entered in Krafts specialized editors on the desktop. After that it is converted to PDF -using a document creation script. +To create PDF output documents, the document data that was edited in the Kraft app is filled into a template. The template defines how the output document looks like, ie. by font settings, placing of elements and such. -This makes sure that Kraft documents are always high standard quality, similar looking -and generated very quickly. +The file that is assembled from data and the template is converted to PDF using a special document creation script. All that is started automatically by Kraft if a document should be printed. + +Each document type in Kraft can have it's own template that is used to create a PDF. Which one can be set in the Settings dialog for document types. ==== WeasyPrint Documents -With https://weasyprint.org[WeasyPrint] Kraft uses a very powerful HTML and CSS based generator that makes it very easy to create highly customized documents which fit the users expectations. The general idea is that Weasyprint loads html output that is processed to PDF, considering a Cascading Stylesheet file which has a huge impact on how the PDF document looks in the end. +With https://weasyprint.org[WeasyPrint] Kraft uses a very powerful HTML and CSS based generator that makes it very easy to create highly customized documents which fit the users expectations. The general idea is that Weasyprint loads html output that is processed to PDF. Usually it is considering a Cascading Stylesheet file which has a huge impact on how the PDF document looks in the end. + +To use a WeasyPrint based template for a document simply create a template file and save it with the extension *.gtmpl*. With that file extension Kraft automatically uses WeasyPrint and also the Grantlee templating for rendering. -To use a WeasyPrint based template for a document simply create a template file and save it with the extension *.gtmpl*. With that file extension Kraft automatically uses WeasyPrint and also the Grantlee templating for rendering. An example for a WeasyPrint document is can be found in the Kraft package in the reports directory and is called invoice.gtmpl. +An example for a WeasyPrint document can be found in the Kraft package in the reports directory and is called invoice.gtmpl. To use a WeasyPrint template with one of the Kraft document types just select the template file name (with the right extension `*.gtml`) in the Kraft Settings Dialog. diff -Nru kraft-0.95/manual/kraft-de.html kraft-0.96/manual/kraft-de.html --- kraft-0.95/manual/kraft-de.html 2020-08-28 16:01:48.000000000 +0000 +++ kraft-0.96/manual/kraft-de.html 2021-02-27 20:44:46.000000000 +0000 @@ -1591,14 +1591,19 @@

Output Document Customization

-

Each document type in Kraft can have it’s own template that is used to -create a PDF. The template is filled with values from the document content -that the user entered in Krafts specialized editors on the desktop. After -that it is converted to PDF using a document creation script.

+

To create PDF output documents, the document data that was edited in the +Kraft app is filled into a template. The template defines how the output +document looks like, ie. through font settings, placing of elements etc.

+
+
+

The file that is assembled from data and the template is converted to PDF +using a special document creation script. All that is started automatically +by Kraft if a document should be printed.

-

This makes sure that Kraft documents are always high standard quality, -similar looking and generated very quickly.

+

Each document type in Kraft can have it’s own template that is used to +create a PDF. Which one can be set in the Settings dialog for document +types.

WeasyPrint Documents

@@ -1606,16 +1611,19 @@

With WeasyPrint Kraft uses a very powerful HTML and CSS based generator that makes it very easy to create highly customized documents which fit the users expectations. The general idea is that -Weasyprint loads html output that is processed to PDF, considering a -Cascading Stylesheet file which has a huge impact on how the PDF document -looks in the end.

+Weasyprint loads html output that is processed to PDF. Usually it is +considering a Cascading Stylesheet file which has a huge impact on how the +PDF document looks in the end.

To use a WeasyPrint based template for a document simply create a template file and save it with the extension .gtmpl. With that file extension Kraft automatically uses WeasyPrint and also the Grantlee templating for -rendering. An example for a WeasyPrint document is can be found in the Kraft -package in the reports directory and is called invoice.gtmpl.

+rendering.

+
+
+

An example for a WeasyPrint document can be found in the Kraft package in +the reports directory and is called invoice.gtmpl.

To use a WeasyPrint template with one of the Kraft document types just @@ -1823,7 +1831,7 @@

diff -Nru kraft-0.95/manual/kraft-en.html kraft-0.96/manual/kraft-en.html --- kraft-0.95/manual/kraft-en.html 2020-08-28 16:01:48.000000000 +0000 +++ kraft-0.96/manual/kraft-en.html 2021-02-27 20:44:46.000000000 +0000 @@ -1534,22 +1534,24 @@

Output Document Customization

-

Each document type in Kraft can have it’s own template that is used to create -a PDF. The template is filled with values from the document content that the user -entered in Krafts specialized editors on the desktop. After that it is converted to PDF -using a document creation script.

+

To create PDF output documents, the document data that was edited in the Kraft app is filled into a template. The template defines how the output document looks like, ie. through font settings, placing of elements etc.

-

This makes sure that Kraft documents are always high standard quality, similar looking -and generated very quickly.

+

The file that is assembled from data and the template is converted to PDF using a special document creation script. All that is started automatically by Kraft if a document should be printed.

+
+
+

Each document type in Kraft can have it’s own template that is used to create a PDF. Which one can be set in the Settings dialog for document types.

WeasyPrint Documents

-

With WeasyPrint Kraft uses a very powerful HTML and CSS based generator that makes it very easy to create highly customized documents which fit the users expectations. The general idea is that Weasyprint loads html output that is processed to PDF, considering a Cascading Stylesheet file which has a huge impact on how the PDF document looks in the end.

+

With WeasyPrint Kraft uses a very powerful HTML and CSS based generator that makes it very easy to create highly customized documents which fit the users expectations. The general idea is that Weasyprint loads html output that is processed to PDF. Usually it is considering a Cascading Stylesheet file which has a huge impact on how the PDF document looks in the end.

+
+
+

To use a WeasyPrint based template for a document simply create a template file and save it with the extension .gtmpl. With that file extension Kraft automatically uses WeasyPrint and also the Grantlee templating for rendering.

-

To use a WeasyPrint based template for a document simply create a template file and save it with the extension .gtmpl. With that file extension Kraft automatically uses WeasyPrint and also the Grantlee templating for rendering. An example for a WeasyPrint document is can be found in the Kraft package in the reports directory and is called invoice.gtmpl.

+

An example for a WeasyPrint document can be found in the Kraft package in the reports directory and is called invoice.gtmpl.

To use a WeasyPrint template with one of the Kraft document types just select the template file name (with the right extension *.gtml) in the Kraft Settings Dialog.

@@ -1745,7 +1747,7 @@
diff -Nru kraft-0.95/README.md kraft-0.96/README.md --- kraft-0.95/README.md 2020-08-28 16:01:48.000000000 +0000 +++ kraft-0.96/README.md 2021-02-27 20:44:46.000000000 +0000 @@ -24,8 +24,8 @@ Kraft utilizes a bunch of very useful tools of the free softare world: - KDE addressbook for customer management - MySQL or alternatively SQLite for database support -- [ReportLab](http://www.reportlab.com/opensource/) for PDF generation: -- [ctemplate](https://github.com/OlafvdSpek/ctemplate) templating library. +- [WeasyPrint](https://weasyprint.org) or [ReportLab](http://www.reportlab.com/opensource/) for PDF generation. +- [Grantlee](https://github.com/steveire/grantlee) or [ctemplate](https://github.com/OlafvdSpek/ctemplate) templating library. ## Interested? @@ -34,5 +34,5 @@ For questions and comments, please speak up. Check the [web site](http://volle-kraft-voraus.de/Main/Contribution) for contact details. -Jun 2005-2020, Klaas Freitag +Jun 2005-2021, Klaas Freitag diff -Nru kraft-0.95/reports/invoice.gtmpl kraft-0.96/reports/invoice.gtmpl --- kraft-0.95/reports/invoice.gtmpl 2020-08-28 16:01:48.000000000 +0000 +++ kraft-0.96/reports/invoice.gtmpl 2021-02-27 20:44:46.000000000 +0000 @@ -46,7 +46,7 @@ Kraft Document -{% autoescape on %} +{% autoescape off %}

{{ me.ORGANISATION }} - {{ me.STREET }} - {{ me.POSTCODE }} {{ me.LOCALITY }} @@ -86,7 +86,7 @@ {% if item.kind == 'Alternative' or item.kind == 'Demand' %} {% endif %} - {{ item.text }} + {{ item.htmlText }} {% if item.kind == 'Alternative' or item.kind == 'Demand' %} {% endif %} diff -Nru kraft-0.95/reports/invoice_kfg.gtmpl kraft-0.96/reports/invoice_kfg.gtmpl --- kraft-0.95/reports/invoice_kfg.gtmpl 1970-01-01 00:00:00.000000000 +0000 +++ kraft-0.96/reports/invoice_kfg.gtmpl 2021-02-27 20:44:46.000000000 +0000 @@ -0,0 +1,180 @@ + + + + + + + + + + + + + + + Kraft Document + + + {% autoescape off %} + + + + +

+ {{ me.ORGANISATION }} - {{ me.STREET }} - {{ me.POSTCODE }} {{ me.LOCALITY }} +

+ + + + +
{{ doc.address }}
+ +
+
{{ label.DOC_NO }}
{{ doc.ident }}
+
{{ label.DATE }}
{{ doc.dateStr }}
+ {% if doc.projectLabel %} +
{{ label.PROJECT }}
+
{{ doc.projectLabel }}
+ {% endif %} +
+ +

{{ doc.docType }} {{ doc.ident }}

+ +

{{ doc.salut }}

+

+ {{ doc.preTextHtml|safe }} +

+ + {% for item in doc.items %} + + + + + + + + + + + + + + + + + + + + + + + + + + +
{{ item.itemNumber }}. + {% if item.kind == 'Alternative' or item.kind == 'Demand' %} + + {% endif %} + {{ item.htmlText }} + {% if item.kind == 'Alternative' or item.kind == 'Demand' %} + + {% endif %} +
{{ item.amount }} {{ item.unit }}{{ item.unitPrice }}{{ item.nettoPrice }} + {% if doc.hasIndividualTaxation %} + {{ item.taxMarker }}  + {% endif %} +
+ {% endfor %} + + + + + + + + + + {% if doc.hasIndividualTaxation %} + + + + + + + + + + + + {% else %} + + + + + + + + + {% endif %} + + + + + + +
{{ label.NET }}{{ doc.nettoSumStr }}
{{ doc.taxMarkerReduced }}  + +{{ doc.reducedTaxPercentStr }}% {{ label.VAT }}{{ doc.reducedTaxSumStr }}
{{ doc.taxMarkerFull }}  + +{{ doc.fullTaxPercentStr }}% {{ label.VAT }}{{ doc.fullTaxSumStr }}
+{{ doc.taxPercentStr }}% {{ label.VAT }}{{ doc.taxSumStr }}
{{ label.SUM }}{{ doc.bruttoSumStr }}
+

+ {{ doc.postTextHtml|safe }} +

+

+ {{ doc.goodbye }} +

+ +{% endautoescape %} + diff -Nru kraft-0.95/reports/kraft_kfg.css kraft-0.96/reports/kraft_kfg.css --- kraft-0.95/reports/kraft_kfg.css 1970-01-01 00:00:00.000000000 +0000 +++ kraft-0.96/reports/kraft_kfg.css 2021-02-27 20:44:46.000000000 +0000 @@ -0,0 +1,226 @@ + +@charset "UTF-8"; + +/* Use google web fonts */ +@import url("https://fonts.googleapis.com/css?family=Pacifico|Open+Sans+Pro:400,700"); +@import url("https://fonts.googleapis.com/css?family=Roboto"); +@import url("https://fonts.googleapis.com/css?family=Oxygen"); +@import url("https://fonts.googleapis.com/css2?family=Raleway"); +@import url("https://fonts.googleapis.com/css2?family=Inconsolata:wght@700"); + +/* General page settings for print */ +@page { + size: A4; + margin-left: 2.4cm; + margin-top:27mm; + margin-right: 1.6cm; + margin-bottom: 2cm; + color: #2f590a; +} + + +html { + font-family: 'Oxygen'; + + font-size: 10pt; + line-height: 1.6; +} + +html body { + margin: 0; + padding-top: 2mm; + +} + +html h1 { + color: #2f590a; + font-family: Roboto; + font-size: 14pt; + margin: 0; +} + +html address { + font-style: normal; + white-space: pre-line; + margin-bottom: 9mm; + height: 40mm; + border: solid 0px; +} + +html aside { + display: flex; + margin: 2em 0 4em; } + html aside address { + font-style: normal; + white-space: pre-line; } + html aside address#to { + color: #a9a; + flex: 1; } + html aside address#from { + text-align: right; +} + +/* + * A absolute positioned block to display document extra info + * on the right top of the document. + */ +html dl { + text-align: right; + position: absolute; + right: 0; + top: 8mm; } + html dl dt, html dl dd { + display: inline; + margin: 0; } + html dl dt { + color: #a9a; } + html dl dt::before { + content: ''; + display: block; } + html dl dt::after { + content: ':'; +} + +sup { + position: relative; + vertical-align: baseline; + top: -0.4em; +} + +img#logo { + position: absolute; + right: 0px; + top: -150px; + width: 178px; + height: 191px; + z-index: -1; +} + + +html p.letterheader { + font-size: 8pt; + text-decoration: underline; +} + +html p.entrytext { +} + +html p.bottomtext { +} + +html p.goodbye { +} + +/* + * Item-Table + * formats the item list. Each item is a line. + */ + html table.items { + border-collapse: collapse; + width: 16.8cm; + table-layout: fixed; + page-break-inside:avoid; + margin-right: 0px; + margin-left: 0px; + } + + html table tr { + page-break-inside:avoid; + page-break-after:auto; + } + + /* + * Table header. It is repeated on every page. + */ + html table th { + border-bottom: .2mm solid #555; + color: #555; + font-size: 10pt; + font-weight: 400; + padding-bottom: .25cm; + text-transform: uppercase; + } + + html table td { + vertical-align: top; + padding: 0px; + padding-top: 3mm; + } + + html table tr.secondline td { + padding-top: 1mm; + } + + .col-center { + text-align: center; + } + .col-right { + text-align: right; + } + .col-left { + text-align: left; + } + + /* The columns of the items table */ + .col-No { + width: 6%; + } + .col-Text { + width: 75%; + } + + .col-Amount { + width: 52%; + } + .col-Unit { + width: 12%; + } + .col-SPrice { + width: 15%; + } + .col-Sum { + width: 15%; + color: #2f590a; + font-weight: bold; + } + + .col-total-first { + width: 60%; + } + .col-total-mid { + width: 20%; + } + .col-total-last { + width: 20%; + } + /* + * The table to display the document sum + */ + html table#total { + border-collapse: collapse; + width: 16.8cm; + + table-layout: fixed; + text-align: right; + bottom: 0; + font-size: 10pt; + + /* The following margins pull the whole box to the right */ + margin-right: 0px; + margin-left: 0px; + margin-bottom: 12mm; + margin-top: 8mm; + } + + html table#total td { + padding-top: 1mm; + text-align: right; + } + + .col-total-line1 { + border-top: solid black 1px; + } + + .col-total-line2 { + border-top: solid black 2px; + } diff -Nru kraft-0.95/src/alldocsview.cpp kraft-0.96/src/alldocsview.cpp --- kraft-0.95/src/alldocsview.cpp 2020-08-28 16:01:48.000000000 +0000 +++ kraft-0.96/src/alldocsview.cpp 2021-02-27 20:44:46.000000000 +0000 @@ -33,7 +33,6 @@ #include #include "models/documentmodel.h" -#include "models/modeltest.h" #include "models/documentproxymodels.h" #include "filterheader.h" #include "alldocsview.h" diff -Nru kraft-0.95/src/archdocposition.cpp kraft-0.96/src/archdocposition.cpp --- kraft-0.95/src/archdocposition.cpp 2020-08-28 16:01:48.000000000 +0000 +++ kraft-0.96/src/archdocposition.cpp 2021-02-27 20:44:46.000000000 +0000 @@ -90,6 +90,21 @@ return re; } +QString ArchDocPosition::htmlText(const QString& paraStyle) const +{ + QString re; + + QString style( paraStyle ); + if ( style.isEmpty() ) style = QStringLiteral("text"); + + // Keep empty parts allows multiple newlines here + const QStringList li = mText.toHtmlEscaped().split( "\n", Qt::KeepEmptyParts ); + + re = li.join("
"); + + return re; +} + // ================================================================== ArchDocPositionList::ArchDocPositionList() diff -Nru kraft-0.95/src/archdocposition.h kraft-0.96/src/archdocposition.h --- kraft-0.95/src/archdocposition.h 2020-08-28 16:01:48.000000000 +0000 +++ kraft-0.96/src/archdocposition.h 2021-02-27 20:44:46.000000000 +0000 @@ -48,6 +48,7 @@ QString posNumber() const { return mPosNo; } QString text() const { return mText; } + QString htmlText(const QString ¶Style = QString()) const; QString unit() const { return mUnit; } @@ -106,6 +107,8 @@ return object.posNumber(); else if ( property == "text" ) return object.text(); +else if ( property == "htmlText" ) + return object.htmlText(); else if ( property == "kind" ) return object.kind(); else if ( property == "unit" ) diff -Nru kraft-0.95/src/archiveman.cpp kraft-0.96/src/archiveman.cpp --- kraft-0.95/src/archiveman.cpp 2020-08-28 16:01:48.000000000 +0000 +++ kraft-0.96/src/archiveman.cpp 2021-02-27 20:44:46.000000000 +0000 @@ -31,6 +31,7 @@ #include "kraftsettings.h" #include "documentman.h" #include "defaultprovider.h" +#include "format.h" Q_GLOBAL_STATIC(ArchiveMan, mSelf) @@ -107,8 +108,7 @@ docElem.appendChild( xmlTextElement( xmldoc, "salut", doc->salut() ) ); docElem.appendChild( xmlTextElement( xmldoc, "goodbye", doc->goodbye() ) ); - docElem.appendChild( xmlTextElement( xmldoc, "date", - DefaultProvider::self()->locale()->toString( doc->date() ) )); + docElem.appendChild( xmlTextElement( xmldoc, "date", Format::toDateString(doc->date(), Format::DateFormatIso))); root.appendChild( doc->positions().domElement( xmldoc ) ); @@ -268,15 +268,19 @@ QString ArchiveMan::xmlBaseDir() const { - QString outputDir = KraftSettings::self()->pdfOutputDir(); - if ( outputDir.isEmpty() ) { - outputDir = QStandardPaths::writableLocation( QStandardPaths::AppDataLocation ); - } + QString outputDir = KraftSettings::self()->xmlArchivePath(); + if ( outputDir.isEmpty() ) { + // stay bug compatible: Before issue #80, this was the pdfOutputDir + outputDir = KraftSettings::self()->pdfOutputDir(); + } + if (outputDir.isEmpty()) { + outputDir = QStandardPaths::writableLocation( QStandardPaths::AppDataLocation ); + } - if ( ! outputDir.endsWith( "/" ) ) outputDir += "/"; - ensureDirIsExisting(outputDir); + if ( ! outputDir.endsWith('/') ) outputDir += QChar('/'); + ensureDirIsExisting(outputDir); - return outputDir; + return outputDir; } QString ArchiveMan::pdfBaseDir() const @@ -286,7 +290,7 @@ outputDir = QStandardPaths::writableLocation( QStandardPaths::AppDataLocation ); } - if ( ! outputDir.endsWith( "/" ) ) outputDir += "/"; + if ( ! outputDir.endsWith('/') ) outputDir += QChar('/'); ensureDirIsExisting(outputDir); return outputDir; diff -Nru kraft-0.95/src/catalogselection.cpp kraft-0.96/src/catalogselection.cpp --- kraft-0.95/src/catalogselection.cpp 2020-08-28 16:01:48.000000000 +0000 +++ kraft-0.96/src/catalogselection.cpp 2021-02-27 20:44:46.000000000 +0000 @@ -1,4 +1,4 @@ -/*************************************************************************** +/*************************************************************************** katalogselection - widget to select catalog entries from ------------------- begin : 2006-08-30 @@ -40,8 +40,8 @@ CatalogSelection::CatalogSelection( QWidget *parent ) :QWidget( parent ), - mCatalogSelector( 0 ), - mWidgets( 0 ) + mCatalogSelector(nullptr), + mWidgets(nullptr) { QVBoxLayout *layout = new QVBoxLayout; layout->setMargin(0); @@ -103,73 +103,79 @@ return kat; } +QString CatalogSelection::currentSelectedKatChapter() +{ + QString chap; + const QString currentCat = mCatalogSelector->currentText(); + if( mWidgetMap.contains( currentCat ) ) { + KatalogListView *lv = mWidgetMap[currentCat]; + + chap = lv->selectedCatalogChapter(); + } + + return chap; +} + void CatalogSelection::slotSelectCatalog( const QString& katName ) { - Katalog *kat = KatalogMan::self()->getKatalog( katName ); + Katalog *kat = KatalogMan::self()->getKatalog( katName ); - if ( ! kat ) { - const QString type = KatalogMan::self()->catalogTypeString( katName ); + if ( !kat ) { + const QString type = KatalogMan::self()->catalogTypeString( katName ); - // qDebug () << "Catalog type for cat " << katName << " is " << type << endl; - if ( type == "TemplCatalog" ) { - kat = new TemplKatalog( katName ); - } else if ( type == "MaterialCatalog" ) { - kat = new MatKatalog( katName ); - } else { - // nothing. - } - if ( kat ) { - KatalogMan::self()->registerKatalog( kat ); - } else { - qCritical() << "Could not find a catalog type for catname " << katName << endl; + // qDebug () << "Catalog type for cat " << katName << " is " << type << endl; + if ( type == QStringLiteral("TemplCatalog") ) { + kat = new TemplKatalog( katName ); + } else if ( type == QStringLiteral("MaterialCatalog") ) { + kat = new MatKatalog( katName ); + } + + if ( kat ) { + KatalogMan::self()->registerKatalog( kat ); + } else { + qCritical() << "Could not find a valid catalog type for catalog named " << katName << endl; + } } - } - if ( kat ) { - if ( ! mWidgetMap.contains( katName ) ) { - KatalogListView *katListView = 0; - - if ( kat->type() == TemplateCatalog ) { - TemplKatalogListView *tmpllistview = new TemplKatalogListView( this ); - katListView = tmpllistview; - katListView->setSelectFromMode(); // mode to only select from - connect( tmpllistview, - SIGNAL( doubleClicked( QModelIndex ) ), - this, - SLOT( slotCatalogDoubleClicked( QModelIndex ) ) ); - tmpllistview->setShowCalcParts( false ); - tmpllistview->addCatalogDisplay( katName ); - tmpllistview->contextMenu()->addAction( i18n("Append to Document"), - this, SIGNAL( actionAppendPosition() ) ); - - mWidgets->addWidget( tmpllistview ); - mWidgetMap.insert( katName, tmpllistview ); - // qDebug () << "Creating a selection list for catalog " << katName << endl; - } else if ( kat->type() == MaterialCatalog ) { - MaterialKatalogListView *matListView = new MaterialKatalogListView( this ); - katListView = matListView; - katListView->setSelectFromMode(); // mode to only select from - connect( matListView, - SIGNAL( doubleClicked( QModelIndex ) ), - this, - SLOT( slCatalogDoubleClicked( QModelIndex ) ) ); - matListView->addCatalogDisplay( katName ); - matListView->contextMenu()->addAction( i18n("Append to Document"), - this, SIGNAL( actionAppendPosition() ) ); - mWidgets->addWidget( matListView ); - mWidgetMap.insert( katName, matListView ); - } - if ( katListView ) { - connect( katListView, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)), - this, SIGNAL( selectionChanged(QTreeWidgetItem*,QTreeWidgetItem*) ) ); - KatalogMan::self()->registerKatalogListView( katName, katListView ); + if ( kat ) { + KatalogListView *katListView = nullptr; + if ( ! mWidgetMap.contains( katName ) ) { - } - } - if ( mWidgetMap.contains( katName ) ) { - mWidgets->setCurrentWidget( mWidgetMap[katName] ); - mListSearchLine->setListView( mWidgetMap[katName] ); + if ( kat->type() == TemplateCatalog ) { + TemplKatalogListView *tmpllistview = new TemplKatalogListView( this ); + katListView = tmpllistview; + tmpllistview->setShowCalcParts( false ); + + // qDebug () << "Creating a selection list for catalog " << katName << endl; + } else if ( kat->type() == MaterialCatalog ) { + MaterialKatalogListView *matListView = new MaterialKatalogListView( this ); + katListView = matListView; + } + + if ( katListView ) { + mWidgets->addWidget(katListView); + mWidgetMap.insert( katName, katListView ); + katListView->contextMenu()->addAction( i18n("Append to Document"), + this, &CatalogSelection::actionAppendPosition); + katListView->addCatalogDisplay( katName ); + katListView->setSelectFromMode(); // mode to only select from + connect(katListView, &KatalogListView::doubleClicked, + this, &CatalogSelection::slotCatalogDoubleClicked); + connect(katListView, &KatalogListView::currentItemChanged, + this, &CatalogSelection::selectionChanged); + KatalogMan::self()->registerKatalogListView( katName, katListView ); + + } + } else { + katListView = mWidgetMap[katName]; + } + + // Select the widget + if ( katListView ) { + mWidgets->setCurrentWidget(katListView); + mListSearchLine->setListView(katListView); + emit selectionChanged(katListView->currentItem(), nullptr); + } } - } } diff -Nru kraft-0.95/src/catalogselection.h kraft-0.96/src/catalogselection.h --- kraft-0.95/src/catalogselection.h 2020-08-28 16:01:48.000000000 +0000 +++ kraft-0.96/src/catalogselection.h 2021-02-27 20:44:46.000000000 +0000 @@ -41,6 +41,7 @@ ~CatalogSelection() { }; Katalog* currentSelectedKat(); + QString currentSelectedKatChapter(); CatalogTemplateList currentSelectedPositions(); protected: diff -Nru kraft-0.95/src/catalogtemplateprovider.cpp kraft-0.96/src/catalogtemplateprovider.cpp --- kraft-0.95/src/catalogtemplateprovider.cpp 2020-08-28 16:01:48.000000000 +0000 +++ kraft-0.96/src/catalogtemplateprovider.cpp 2021-02-27 20:44:46.000000000 +0000 @@ -26,11 +26,21 @@ CatalogTemplateProvider::CatalogTemplateProvider( QWidget *parent ) :TemplateProvider( parent ), - mCatalogSelection( 0 ) + mCatalogSelection(nullptr) { } +Katalog *CatalogTemplateProvider::currentCatalog() +{ + Katalog *kat {nullptr}; + if (mCatalogSelection) { + kat = mCatalogSelection->currentSelectedKat(); + } + return kat; +} + + void CatalogTemplateProvider::setCatalogSelection( CatalogSelection *cs ) { mCatalogSelection = cs; @@ -41,12 +51,20 @@ void CatalogTemplateProvider::slotNewTemplate() { - // qDebug () << "SlotNewTemplate for Catalog called!" << endl; + qDebug () << "SlotNewTemplate for Catalog called!" << endl; + if ( mCatalogSelection ) { + Katalog *catalog = mCatalogSelection->currentSelectedKat(); + + CatalogTemplateList list; + const QString currKat = mCatalogSelection->currentSelectedKatChapter(); + emit templatesToDocument(catalog, list, currKat); + } } void CatalogTemplateProvider::slotEditTemplate() { // qDebug () << "SlotEditTemplate for Catalog called!" << endl; + // mCatalogSelection->currentSelectedPositions } void CatalogTemplateProvider::slotDeleteTemplate() @@ -60,7 +78,8 @@ if ( mCatalogSelection ) { Katalog *catalog = mCatalogSelection->currentSelectedKat(); - emit templatesToDocument( catalog, mCatalogSelection->currentSelectedPositions() ); + emit templatesToDocument(catalog, mCatalogSelection->currentSelectedPositions(), + QString()); } } diff -Nru kraft-0.95/src/catalogtemplateprovider.h kraft-0.96/src/catalogtemplateprovider.h --- kraft-0.95/src/catalogtemplateprovider.h 2020-08-28 16:01:48.000000000 +0000 +++ kraft-0.96/src/catalogtemplateprovider.h 2021-02-27 20:44:46.000000000 +0000 @@ -20,10 +20,10 @@ #include "templateprovider.h" #include "doctext.h" #include "catalogtemplate.h" +#include "katalog.h" class QWidget; class CatalogSelection; -class Katalog; class CatalogTemplateProvider : public TemplateProvider { @@ -32,8 +32,11 @@ CatalogTemplateProvider( QWidget* ); void setCatalogSelection( CatalogSelection * ); + Katalog *currentCatalog(); + signals: - void templatesToDocument( Katalog*, CatalogTemplateList ); + void templatesToDocument( Katalog*, CatalogTemplateList, const QString& ); + void catalogSelected(Katalog*); public slots: void slotNewTemplate(); diff -Nru kraft-0.95/src/docassistant.cpp kraft-0.96/src/docassistant.cpp --- kraft-0.95/src/docassistant.cpp 2020-08-28 16:01:48.000000000 +0000 +++ kraft-0.96/src/docassistant.cpp 2021-02-27 20:44:46.000000000 +0000 @@ -178,9 +178,8 @@ /* Catalog Template Provider */ mCatalogTemplateProvider = new CatalogTemplateProvider( parent ); mCatalogTemplateProvider->setCatalogSelection( mCatalogSelection ); - connect( mCatalogTemplateProvider, SIGNAL( templatesToDocument(Katalog*,CatalogTemplateList) ), - this, SIGNAL( templatesToDocument(Katalog*,CatalogTemplateList) ) ); - + connect(mCatalogTemplateProvider, &CatalogTemplateProvider::templatesToDocument, + this, &DocAssistant::templatesToDocument); mCurrTemplateProvider = mHeaderTemplateProvider; const QList sizes = KraftSettings::self()->assistantSplitterSetting(); @@ -200,12 +199,25 @@ void DocAssistant::slotTemplateSelectionChanged( ) { + if (!mCurrTemplateProvider) { + mPbNew->setEnabled(false); + mPbEdit->setEnabled(false); + mPbDel->setEnabled(false); + return; + } + if( mActivePage == KraftDoc::Positions ) { // no editing on the catalogs - mPbNew->setEnabled( false ); + bool enableNew {false}; + + auto kat = static_cast(mCurrTemplateProvider)->currentCatalog(); + if (kat->type() == KatalogType::TemplateCatalog) { + enableNew = true; + } + mPbNew->setEnabled(enableNew); mPbEdit->setEnabled( false ); mPbDel->setEnabled( false ); } else { - bool mv = false; + bool mv {false}; if( mActivePage == KraftDoc::Header ) { mv = mHeaderSelector->validSelection(); } else if( mActivePage == KraftDoc::Footer ) { @@ -220,13 +232,14 @@ void DocAssistant::slotCatalogSelectionChanged(QTreeWidgetItem *current ,QTreeWidgetItem *) { - // enable the move-to-document button. - // qDebug () << "catalog position selection changed!" << endl; - if ( current ) { - mPbAdd->setEnabled( true ); - } else { - mPbAdd->setEnabled( false ); - } + // enable the move-to-document button. + // qDebug () << "catalog position selection changed!" << endl; + if ( current ) { + mPbAdd->setEnabled( true ); + } else { + mPbAdd->setEnabled( false ); + } + slotTemplateSelectionChanged(); } void DocAssistant::slotNewTemplate() diff -Nru kraft-0.95/src/docassistant.h kraft-0.96/src/docassistant.h --- kraft-0.95/src/docassistant.h 2020-08-28 16:01:48.000000000 +0000 +++ kraft-0.96/src/docassistant.h 2021-02-27 20:44:46.000000000 +0000 @@ -84,7 +84,7 @@ signals: void selectPage( int ); - void templatesToDocument( Katalog*, CatalogTemplateList ); + void templatesToDocument( Katalog*, CatalogTemplateList, const QString&); void toggleShowTemplates( bool ); void addressTemplate( const Addressee& ); diff -Nru kraft-0.95/src/docposition.cpp kraft-0.96/src/docposition.cpp --- kraft-0.95/src/docposition.cpp 2020-08-28 16:01:48.000000000 +0000 +++ kraft-0.96/src/docposition.cpp 2021-02-27 20:44:46.000000000 +0000 @@ -353,16 +353,18 @@ posElem.appendChild( xmlTextElement( doc, "text", dp->text() ) ); double am = dp->amount(); - QString h = DefaultProvider::self()->locale()->toString( am, 'f', 2 ); + QString h = QString::number(am, 'f', 2 ); posElem.appendChild( xmlTextElement( doc, "amount", h )); Einheit e = dp->unit(); posElem.appendChild( xmlTextElement( doc, "unit", e.einheit( am ) ) ); Geld g = dp->unitPrice(); - posElem.appendChild( xmlTextElement( doc, "unitprice", g.toString() ) ); + posElem.appendChild( xmlTextElement( doc, "unitprice", QString::number(g.toDouble(), 'f', 2 ))); - posElem.appendChild( xmlTextElement( doc, "sumprice", Geld( g*am).toString() ) ); + Geld sum(g * am); + + posElem.appendChild( xmlTextElement( doc, "sumprice", QString::number(sum.toDouble(), 'f', 2 ) ) ); } } return topElem; diff -Nru kraft-0.95/src/documentman.cpp kraft-0.96/src/documentman.cpp --- kraft-0.95/src/documentman.cpp 2020-08-28 16:01:48.000000000 +0000 +++ kraft-0.96/src/documentman.cpp 2021-02-27 20:44:46.000000000 +0000 @@ -59,7 +59,7 @@ DocGuardedPtr DocumentMan::createDocument( const QString& docType, const QString& copyFromId, const DocPositionList& listToCopy) { - DocGuardedPtr doc = new KraftDoc( ); + DocGuardedPtr doc = new KraftDoc(); // qDebug () << "new document ID: " << doc->docID().toString() << endl; if ( ! copyFromId.isEmpty() ) { @@ -97,18 +97,32 @@ } doc->setPredecessor(sourceDoc->ident()); + + // Take the default pre- and posttext for the new docType, or, if that is empty, the texts of the old doc + QString newText = DefaultProvider::self()->defaultText( docType, KraftDoc::Header ); + if (newText.isEmpty() ) { + newText = sourceDoc->preText(); + } + doc->setPreText(newText); + + newText = DefaultProvider::self()->defaultText( docType, KraftDoc::Footer ); + if (newText.isEmpty() ) { + newText = sourceDoc->postText(); + } + doc->setPostText(newText); + delete sourceDoc; } } else { // Absolute new document doc->setDocType(docType); + doc->setPreText(DefaultProvider::self()->defaultText(docType, KraftDoc::Header)); + doc->setPostText(DefaultProvider::self()->defaultText(docType, KraftDoc::Footer)); doc->setGoodbye( KraftSettings::greeting() ); } // set the proper texts and other data doc->setLastModified( QDateTime::currentDateTime()); - doc->setPreText(DefaultProvider::self()->defaultText( docType, KraftDoc::Header )); - doc->setPostText(DefaultProvider::self()->defaultText( docType, KraftDoc::Footer)); return doc; } diff -Nru kraft-0.95/src/documenttemplate.cpp kraft-0.96/src/documenttemplate.cpp --- kraft-0.95/src/documenttemplate.cpp 2020-08-28 16:01:48.000000000 +0000 +++ kraft-0.96/src/documenttemplate.cpp 2021-02-27 20:44:46.000000000 +0000 @@ -314,7 +314,7 @@ h = DefaultProvider::self()->locale()->toString( archDoc->tax() ); // qDebug () << "Tax in archive document: " << h; - if ( archDoc->reducedTaxSum().toLong() > 0 ) { + if ( archDoc->reducedTaxSum().toLong() != 0 ) { tmpl.createDictionary( DICT( "SECTION_REDUCED_TAX" ) ); tmpl.setValue( DICT("SECTION_REDUCED_TAX"), TAG( "REDUCED_TAX_SUM" ), archDoc->reducedTaxSum().toString() ); @@ -322,7 +322,7 @@ tmpl.setValue( DICT("SECTION_REDUCED_TAX"), TAG( "REDUCED_TAX" ), h ); tmpl.setValue( DICT("SECTION_REDUCED_TAX"), TAG( "REDUCED_TAX_LABEL" ), i18n( "reduced VAT" ) ); } - if ( archDoc->fullTaxSum().toLong() > 0 ) { + if ( archDoc->fullTaxSum().toLong() != 0 ) { tmpl.createDictionary( DICT( "SECTION_FULL_TAX" ) ); tmpl.setValue( DICT("SECTION_FULL_TAX"), TAG( "FULL_TAX_SUM" ), archDoc->fullTaxSum().toString() ); diff -Nru kraft-0.95/src/inserttempldialog.cpp kraft-0.96/src/inserttempldialog.cpp --- kraft-0.95/src/inserttempldialog.cpp 2020-08-28 16:01:48.000000000 +0000 +++ kraft-0.96/src/inserttempldialog.cpp 2021-02-27 20:44:46.000000000 +0000 @@ -179,18 +179,26 @@ } } -void InsertTemplDialog::setCatalogChapters( const QList& chapters ) +void InsertTemplDialog::setCatalogChapters( const QList& chapters, const QString& selectedChap) { - if ( chapters.count() > 0 ) { - QStringList chapterNames; - foreach( CatalogChapter chapter, chapters ) { - chapterNames.append( chapter.name() ); + if ( chapters.count() > 0 ) { + QStringList chapterNames; + for( CatalogChapter chapter: chapters ) { + if (!chapter.name().isEmpty()) + chapterNames.append( chapter.name() ); + } + mBaseWidget->mKeepGroup->show(); + mBaseWidget->mComboChapter->insertItems( -1, chapterNames ); + + QString selChap { selectedChap }; + if (!selectedChap.isEmpty()) { + mBaseWidget->mKeepGroup->setChecked(true); + } else { + selChap = KraftSettings::self()->insertTemplChapterName(); + } + if (!selChap.isEmpty() && chapterNames.contains(selChap)) + mBaseWidget->mComboChapter->setCurrentIndex(mBaseWidget->mComboChapter->findText(selChap)); } - mBaseWidget->mKeepGroup->show(); - mBaseWidget->mComboChapter->insertItems( -1, chapterNames ); - mBaseWidget->mComboChapter->setCurrentIndex(mBaseWidget->mComboChapter->findText( - KraftSettings::self()->insertTemplChapterName() )); - } } // return only a chapter if the checkbox is checked. diff -Nru kraft-0.95/src/inserttempldialog.h kraft-0.96/src/inserttempldialog.h --- kraft-0.95/src/inserttempldialog.h 2020-08-28 16:01:48.000000000 +0000 +++ kraft-0.96/src/inserttempldialog.h 2021-02-27 20:44:46.000000000 +0000 @@ -34,13 +34,13 @@ InsertTemplDialog( QWidget* ); ~InsertTemplDialog(); - void setDocPosition( DocPosition*, bool, bool ); - DocPosition docPosition(); + void setDocPosition( DocPosition*, bool, bool ) override; + DocPosition docPosition() override; - void setCatalogChapters( const QList& ); - QString chapter() const; + void setCatalogChapters( const QList&, const QString& selectedChap) override; + QString chapter() const override; protected: - QComboBox *getPositionCombo(); + QComboBox *getPositionCombo() override; private: QString prepareText( const QString& input ); diff -Nru kraft-0.95/src/kataloglistview.cpp kraft-0.96/src/kataloglistview.cpp --- kraft-0.95/src/kataloglistview.cpp 2020-08-28 16:01:48.000000000 +0000 +++ kraft-0.96/src/kataloglistview.cpp 2021-02-27 20:44:46.000000000 +0000 @@ -237,6 +237,23 @@ return templates; } +QString KatalogListView::selectedCatalogChapter() +{ + QList items = selectedItems(); + QString chap; + + if (items.size() == 1) { + QTreeWidgetItem *item = items.first(); + if (!isChapter(item) && !isRoot(item)) { + item = item->parent(); + } + if (isChapter(item)) { + chap = static_cast(itemData(item))->name(); + } + } + return chap; +} + void* KatalogListView::itemData( QTreeWidgetItem *item ) { if ( item && m_dataDict.contains( item ) ) { diff -Nru kraft-0.95/src/kataloglistview.h kraft-0.96/src/kataloglistview.h --- kraft-0.95/src/kataloglistview.h 2020-08-28 16:01:48.000000000 +0000 +++ kraft-0.96/src/kataloglistview.h 2021-02-27 20:44:46.000000000 +0000 @@ -51,6 +51,7 @@ bool isChapter(QTreeWidgetItem*); bool isRoot(QTreeWidgetItem*); + QString selectedCatalogChapter(); virtual void setupChapters(); diff -Nru kraft-0.95/src/kraftview.cpp kraft-0.96/src/kraftview.cpp --- kraft-0.95/src/kraftview.cpp 2020-08-28 16:01:48.000000000 +0000 +++ kraft-0.96/src/kraftview.cpp 2021-02-27 20:44:46.000000000 +0000 @@ -81,7 +81,7 @@ KraftView::KraftView(QWidget *parent) : KraftViewBase( parent ), - mHelpLabel( 0 ), mRememberAmount( -1 ), mModified( false ), + mHelpLabel(nullptr), mRememberAmount( -1 ), mModified( false ), mTaxBefore( -1 ), mDocPosEditorIndx( -1 ) { setWindowTitle( i18n("Document" ) ); @@ -124,8 +124,8 @@ mCSplit->addWidget( mAssistant ); /* catalog template selection signal */ - connect( mAssistant, SIGNAL( templatesToDocument(Katalog*,CatalogTemplateList) ), - this, SLOT( slotAddItems( Katalog*, CatalogTemplateList ) ) ); + connect(mAssistant, &DocAssistant::templatesToDocument, + this, &KraftView::slotAddItems); /* signal to toggle the visibility of the template section in the assistant */ connect( mAssistant, SIGNAL( toggleShowTemplates( bool ) ), @@ -459,7 +459,7 @@ } else { if ( mHelpLabel ) { delete mHelpLabel; - mHelpLabel = 0; + mHelpLabel = nullptr; } } @@ -636,7 +636,7 @@ DocPositionList list = m_doc->positions(); int tt = -1; - DocPositionBase *dp = 0; + DocPositionBase *dp = nullptr; DocPositionListIterator it( list ); int taxIndex = 0; @@ -722,8 +722,8 @@ */ void KraftView::slotMovePositionUp( int pos ) { - PositionViewWidget *w1 = 0; - PositionViewWidget *w2 = 0; + PositionViewWidget *w1 = nullptr; + PositionViewWidget *w2 = nullptr; // qDebug () << "Moving position up: " << pos << endl; if( pos < 1 || pos > mPositionWidgetList.count() ) { @@ -759,8 +759,8 @@ */ void KraftView::slotMovePositionDown( int pos ) { - PositionViewWidget *w1 = 0; - PositionViewWidget *w2 = 0; + PositionViewWidget *w1 = nullptr; + PositionViewWidget *w2 = nullptr; // qDebug () << "Moving position down: " << pos << endl; if( pos < 0 || pos >= mPositionWidgetList.count() -1 ) { @@ -920,140 +920,141 @@ void KraftView::slotAddNewItem() { Katalog* kat = mAssistant->catalogSelection()->currentSelectedKat(); - slotAddItem( kat, 0 ); + slotAddItem( kat, nullptr, QString() ); } -void KraftView::slotAddItems( Katalog *kat, CatalogTemplateList templates) +void KraftView::slotAddItems( Katalog *kat, CatalogTemplateList templates, const QString& selectedChapter) { - foreach( CatalogTemplate *templ, templates ) { - slotAddItem( kat, templ ); - } + + if(templates.count() == 0) { + slotAddItem(kat, nullptr, selectedChapter); + } else { + for(CatalogTemplate *templ : templates ) { + slotAddItem( kat, templ, selectedChapter ); + } + } } -void KraftView::slotAddItem( Katalog *kat, CatalogTemplate *tmpl ) +void KraftView::slotAddItem( Katalog *kat, CatalogTemplate *tmpl, const QString& selectedChapter ) { - // newpos is a list position, starts counting at zero! - int newpos = mPositionWidgetList.count(); - // qDebug () << "Adding Position at list position " << newpos << endl; + // newpos is a list position, starts counting at zero! + int newpos = mPositionWidgetList.count(); + // qDebug () << "Adding Position at list position " << newpos << endl; - QScopedPointer dia; + QScopedPointer dia; - DocPosition *dp = new DocPosition(); - dp->setPositionNumber( newpos +1 ); - QSize s; + DocPosition *dp = new DocPosition(); + dp->setPositionNumber( newpos +1 ); - bool newTemplate = false; - if ( !tmpl ) { - newTemplate = true; - } - - dia.reset(new InsertTemplDialog( this )); - dia->setCatalogChapters( kat->getKatalogChapters() ); + bool newTemplate = false; + if ( !tmpl ) { + newTemplate = true; + } - int tmplId = 0; + dia.reset(new InsertTemplDialog( this )); + dia->setCatalogChapters( kat->getKatalogChapters(), selectedChapter); - if ( newTemplate ) { - // New templates may only go to the standard template catalog, FIXME - } else { - // it's not a new template - dp->setText(tmpl->getText()); - dp->setUnit(tmpl->unit()); - dp->setUnitPrice(tmpl->unitPrice()); + int tmplId = 0; - s = KraftSettings::self()->templateToPosDialogSize(); - } - - if ( mRememberAmount > 0 ) { - dp->setAmount( mRememberAmount ); - } + if ( !newTemplate ) { + // it's not a new template + dp->setText(tmpl->getText()); + dp->setUnit(tmpl->unit()); + dp->setUnitPrice(tmpl->unitPrice()); + } - KraftDoc *doc = getDocument(); - if(doc) { - DocType docType = doc->docType(); - dia->setDocPosition( dp, newTemplate, docType.pricesVisible() ); - } - DocPositionList list = currentPositionList(); - dia->setPositionList( list, newpos ); - - dia->resize( s ); - - if ( dia->exec() == QDialog::Accepted ) { - DocPosition diaPos = dia->docPosition(); - *dp = diaPos; - - // set the tax settings - if( currentTaxSetting() == DocPositionBase::TaxIndividual ) { - // FIXME: In case a new item is added, add the default tax type. - // otherwise add the tax of the template - dp->setTaxType( DocPositionBase::TaxFull ); - } else { - dp->setTaxType( currentTaxSetting() ); - } + if ( mRememberAmount > 0 ) { + dp->setAmount( mRememberAmount ); + } - // store the initial size of the template-to-doc-pos dialogs - s = dia->size(); - KraftSettings::self()->setTemplateToPosDialogSize( s ); - - if ( kat->type() == TemplateCatalog ) { - - // if it's a new position, create a catalog template in the incoming chapter - if ( newTemplate ) { - const QString chapter = dia->chapter(); - - int chapterId = 0; // find the chapter. - if( !chapter.isEmpty() ) { - chapterId = KatalogMan::self()->defaultTemplateCatalog()->chapterID(chapter).toInt(); - } - - FloskelTemplate *flos = new FloskelTemplate( -1, dp->text(), - dp->unit().id(), - chapterId, - 1 /* CalcKind = Manual */ ); - - flos->setManualPrice( dp->unitPrice() ); - flos->save(); - tmplId = flos->getTemplID(); - - // reload the entire katalog - Katalog *defaultKat = KatalogMan::self()->defaultTemplateCatalog(); - if( defaultKat ) { - defaultKat->load(); - KatalogMan::self()->notifyKatalogChange( defaultKat , dbID() ); - } - } else { - tmplId = static_cast(tmpl)->getTemplID(); - } - } else if ( kat->type() == MaterialCatalog ) { - if ( newTemplate ) { + KraftDoc *doc = getDocument(); + if(doc) { + DocType docType = doc->docType(); + dia->setDocPosition( dp, newTemplate, docType.pricesVisible() ); + } + DocPositionList list = currentPositionList(); + dia->setPositionList( list, newpos ); + + QSize s = KraftSettings::self()->templateToPosDialogSize(); + dia->resize( s ); + + int execResult = dia->exec(); + + if ( execResult == QDialog::Accepted ) { + DocPosition diaPos = dia->docPosition(); + *dp = diaPos; + + // set the tax settings + if( currentTaxSetting() == DocPositionBase::TaxIndividual ) { + // FIXME: In case a new item is added, add the default tax type. + // otherwise add the tax of the template + dp->setTaxType( DocPositionBase::TaxFull ); + } else { + dp->setTaxType( currentTaxSetting() ); + } - } - } + // store the initial size of the template-to-doc-pos dialogs + s = dia->size(); + KraftSettings::self()->setTemplateToPosDialogSize( s ); + + if ( kat->type() == TemplateCatalog ) { + + // save the template if it is has a valid chapter. + // the method chapter() considers the checkbox. If it is not checked to keep the template, + // an empty chapter is returned. + + const QString chapter = dia->chapter(); + if (!chapter.isEmpty()) { + int chapterId = KatalogMan::self()->defaultTemplateCatalog()->chapterID(chapter).toInt(); + + FloskelTemplate *flos = new FloskelTemplate( -1, dp->text(), + dp->unit().id(), + chapterId, + 1 /* CalcKind = Manual */ ); + flos->setManualPrice( dp->unitPrice() ); + flos->save(); + tmplId = flos->getTemplID(); + + // reload the entire katalog + Katalog *defaultKat = KatalogMan::self()->defaultTemplateCatalog(); + if( defaultKat ) { + defaultKat->load(); + KatalogMan::self()->notifyKatalogChange( defaultKat , dbID() ); + } + } + } + if (!newTemplate){ + tmplId = static_cast(tmpl)->getTemplID(); + } + } else if ( kat->type() == MaterialCatalog ) { + if ( newTemplate ) { + // FIXME + } + } - newpos = dia->insertAfterPosition(); + if (execResult == QDialog::Accepted) { + newpos = dia->insertAfterPosition(); - mRememberAmount = dp->amount(); - } else { - delete dp; - return; - } + mRememberAmount = dp->amount(); - if (tmplId > 0) { - kat->recordUsage(tmplId); - } + if (tmplId > 0) { + kat->recordUsage(tmplId); + } - PositionViewWidget *widget = createPositionViewWidget( dp, newpos ); - widget->slotModified(); - widget->slotAllowIndividualTax( currentTaxSetting() == DocPositionBase::TaxIndividual ); - - // Check if the new widget is supposed to display prices, based on the doc type - // FIXME: Shouldn't this be done by the positionViewWidget rather than here? - const QString dt = getDocument()->docType(); - if( !dt.isEmpty() ) { - DocType docType(dt); - widget->slotShowPrice(docType.pricesVisible()); - } - slotFocusItem( widget, newpos ); - refreshPostCard(); + PositionViewWidget *widget = createPositionViewWidget( dp, newpos ); + widget->slotModified(); + widget->slotAllowIndividualTax( currentTaxSetting() == DocPositionBase::TaxIndividual ); + + // Check if the new widget is supposed to display prices, based on the doc type + // FIXME: Shouldn't this be done by the positionViewWidget rather than here? + const QString dt = getDocument()->docType(); + if( !dt.isEmpty() ) { + DocType docType(dt); + widget->slotShowPrice(docType.pricesVisible()); + } + slotFocusItem( widget, newpos ); + refreshPostCard(); + } } void KraftView::slotImportItems() diff -Nru kraft-0.95/src/kraftview.h kraft-0.96/src/kraftview.h --- kraft-0.95/src/kraftview.h 2020-08-28 16:01:48.000000000 +0000 +++ kraft-0.96/src/kraftview.h 2021-02-27 20:44:46.000000000 +0000 @@ -125,9 +125,9 @@ void slotModifiedHeader(); void slotModifiedFooter(); - void slotAddItem( Katalog*, CatalogTemplate* ); + void slotAddItem( Katalog*, CatalogTemplate*, const QString& selectedChapter); void slotAddNewItem(); - void slotAddItems( Katalog*, CatalogTemplateList ); + void slotAddItems(Katalog*, CatalogTemplateList , const QString &selectedChapter); void slotAddExtraPosition(); void slotImportItems(); diff -Nru kraft-0.95/src/models/modeltest.cpp kraft-0.96/src/models/modeltest.cpp --- kraft-0.95/src/models/modeltest.cpp 2020-08-28 16:01:48.000000000 +0000 +++ kraft-0.96/src/models/modeltest.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,527 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2007 Trolltech ASA. All rights reserved. -** -** This file is part of the Qt Concurrent project on Trolltech Labs. -** -** This file may be used under the terms of the GNU General Public -** License version 2.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of -** this file. Please review the following information to ensure GNU -** General Public Licensing requirements will be met: -** http://www.trolltech.com/products/qt/opensource.html -** -** If you are unsure which license is appropriate for your use, please -** review the following information: -** http://www.trolltech.com/products/qt/licensing.html or contact the -** sales department at sales@trolltech.com. -** -** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE -** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. -** -****************************************************************************/ - -#include - -#include "modeltest.h" - -Q_DECLARE_METATYPE(QModelIndex) - -/*! - Connect to all of the models signals. Whenever anything happens recheck everything. -*/ -ModelTest::ModelTest(QAbstractItemModel *_model, QObject *parent) : QObject(parent), model(_model), fetchingMore(false) -{ - Q_ASSERT(model); - - connect(model, SIGNAL(columnsAboutToBeInserted(const QModelIndex &, int, int)), - this, SLOT(runAllTests())); - connect(model, SIGNAL(columnsAboutToBeRemoved(const QModelIndex &, int, int)), - this, SLOT(runAllTests())); - connect(model, SIGNAL(columnsInserted(const QModelIndex &, int, int)), - this, SLOT(runAllTests())); - connect(model, SIGNAL(columnsRemoved(const QModelIndex &, int, int)), - this, SLOT(runAllTests())); - connect(model, SIGNAL(dataChanged(const QModelIndex &, const QModelIndex &)), - this, SLOT(runAllTests())); - connect(model, SIGNAL(headerDataChanged(Qt::Orientation, int, int)), - this, SLOT(runAllTests())); - connect(model, SIGNAL(layoutAboutToBeChanged ()), this, SLOT(runAllTests())); - connect(model, SIGNAL(layoutChanged ()), this, SLOT(runAllTests())); - connect(model, SIGNAL(modelReset ()), this, SLOT(runAllTests())); - connect(model, SIGNAL(rowsAboutToBeInserted(const QModelIndex &, int, int)), - this, SLOT(runAllTests())); - connect(model, SIGNAL(rowsAboutToBeRemoved(const QModelIndex &, int, int)), - this, SLOT(runAllTests())); - connect(model, SIGNAL(rowsInserted(const QModelIndex &, int, int)), - this, SLOT(runAllTests())); - connect(model, SIGNAL(rowsRemoved(const QModelIndex &, int, int)), - this, SLOT(runAllTests())); - - // Special checks for inserting/removing - connect(model, SIGNAL(layoutAboutToBeChanged()), - this, SLOT(layoutAboutToBeChanged())); - connect(model, SIGNAL(layoutChanged()), - this, SLOT(layoutChanged())); - - connect(model, SIGNAL(rowsAboutToBeInserted(const QModelIndex &, int, int)), - this, SLOT(rowsAboutToBeInserted(const QModelIndex &, int, int))); - connect(model, SIGNAL(rowsAboutToBeRemoved(const QModelIndex &, int, int)), - this, SLOT(rowsAboutToBeRemoved(const QModelIndex &, int, int))); - connect(model, SIGNAL(rowsInserted(const QModelIndex &, int, int)), - this, SLOT(rowsInserted(const QModelIndex &, int, int))); - connect(model, SIGNAL(rowsRemoved(const QModelIndex &, int, int)), - this, SLOT(rowsRemoved(const QModelIndex &, int, int))); - - runAllTests(); -} - -void ModelTest::runAllTests() -{ - if (fetchingMore) - return; - nonDestructiveBasicTest(); - rowCount(); - columnCount(); - hasIndex(); - index(); - parent(); - data(); -} - -/*! - nonDestructiveBasicTest tries to call a number of the basic functions (not all) - to make sure the model doesn't outright segfault, testing the functions that makes sense. -*/ -void ModelTest::nonDestructiveBasicTest() -{ - Q_ASSERT(model->buddy(QModelIndex()) == QModelIndex()); - model->canFetchMore(QModelIndex()); - Q_ASSERT(model->columnCount(QModelIndex()) >= 0); - //Q_ASSERT(model->data(QModelIndex()) == QVariant()); - fetchingMore = true; - model->fetchMore(QModelIndex()); - fetchingMore = false; - // Q_ASSERT(flags == Qt::ItemIsDropEnabled || flags == 0); - model->hasChildren(QModelIndex()); - model->hasIndex(0, 0); - model->headerData(0, Qt::Horizontal); - model->index(0, 0); - model->itemData(QModelIndex()); - QVariant cache; - model->match(QModelIndex(), -1, cache); - model->mimeTypes(); - Q_ASSERT(model->parent(QModelIndex()) == QModelIndex()); - Q_ASSERT(model->rowCount() >= 0); - QVariant variant; - model->setData(QModelIndex(), variant, -1); - model->setHeaderData(-1, Qt::Horizontal, QVariant()); - model->setHeaderData(999999, Qt::Horizontal, QVariant()); - QMap roles; - model->sibling(0, 0, QModelIndex()); - model->span(QModelIndex()); - model->supportedDropActions(); -} - -/*! - Tests model's implementation of QAbstractItemModel::rowCount() and hasChildren() - - Models that are dynamically populated are not as fully tested here. - */ -void ModelTest::rowCount() -{ - // check top row - QModelIndex topIndex = model->index(0, 0, QModelIndex()); - int rows = model->rowCount(topIndex); - Q_ASSERT(rows >= 0); - if (rows > 0) - Q_ASSERT(model->hasChildren(topIndex) == true); - - QModelIndex secondLevelIndex = model->index(0, 0, topIndex); - if (secondLevelIndex.isValid()) { // not the top level - // check a row count where parent is valid - rows = model->rowCount(secondLevelIndex); - Q_ASSERT(rows >= 0); - if (rows > 0) - { - qDebug() << "row " << secondLevelIndex.row() << "column " << secondLevelIndex.column() << "internalid " << secondLevelIndex.internalId() << "rowcount" << rows; - qDebug() << model->hasChildren(secondLevelIndex); - Q_ASSERT(model->hasChildren(secondLevelIndex) == true); - } - } - - // The models rowCount() is tested more extensively in checkChildren(), - // but this catches the big mistakes -} - -/*! - Tests model's implementation of QAbstractItemModel::columnCount() and hasChildren() - */ -void ModelTest::columnCount() -{ - // check top row - QModelIndex topIndex = model->index(0, 0, QModelIndex()); - Q_ASSERT(model->columnCount(topIndex) >= 0); - - // check a column count where parent is valid - QModelIndex childIndex = model->index(0, 0, topIndex); - if (childIndex.isValid()) - Q_ASSERT(model->columnCount(childIndex) >= 0); - - // columnCount() is tested more extensively in checkChildren(), - // but this catches the big mistakes -} - -/*! - Tests model's implementation of QAbstractItemModel::hasIndex() - */ -void ModelTest::hasIndex() -{ - // Make sure that invalid values returns an invalid index - Q_ASSERT(model->hasIndex(-2, -2) == false); - Q_ASSERT(model->hasIndex(-2, 0) == false); - Q_ASSERT(model->hasIndex(0, -2) == false); - - int rows = model->rowCount(); - - // check out of bounds - int columns = model->columnCount(); - Q_ASSERT(model->hasIndex(rows, columns) == false); - Q_ASSERT(model->hasIndex(rows + 1, columns + 1) == false); - - if (rows > 0) - Q_ASSERT(model->hasIndex(0, 0) == true); - - // hasIndex() is tested more extensively in checkChildren(), - // but this catches the big mistakes -} - -/*! - Tests model's implementation of QAbstractItemModel::index() - */ -void ModelTest::index() -{ - // Make sure that invalid values returns an invalid index - Q_ASSERT(model->index(-2, -2) == QModelIndex()); - Q_ASSERT(model->index(-2, 0) == QModelIndex()); - Q_ASSERT(model->index(0, -2) == QModelIndex()); - - int rows = model->rowCount(); - - if (rows == 0) - return; - - // Catch off by one errors - int columns = model->columnCount(); - Q_ASSERT(model->index(rows, columns) == QModelIndex()); - Q_ASSERT(model->index(0, 0).isValid() == true); - - // Make sure that the same index is *always* returned - QModelIndex a = model->index(0, 0); - QModelIndex b = model->index(0, 0); - Q_ASSERT(a == b); - - // index() is tested more extensively in checkChildren(), - // but this catches the big mistakes -} - -/*! - Tests model's implementation of QAbstractItemModel::parent() - */ -void ModelTest::parent() -{ - // Make sure the model wont crash and will return an invalid QModelIndex - // when asked for the parent of an invalid index. - Q_ASSERT(model->parent(QModelIndex()) == QModelIndex()); - - if (model->rowCount() == 0) - return; - - // Column 0 | Column 1 | - // QModelIndex() | | - // \- topIndex | topIndex1 | - // \- childIndex | childIndex1 | - - // Common error test #1, make sure that a top level index has a parent - // that is a invalid QModelIndex. - QModelIndex topIndex = model->index(0, 0, QModelIndex()); - Q_ASSERT(model->parent(topIndex) == QModelIndex()); - - // Common error test #2, make sure that a second level index has a parent - // that is the first level index. - if (model->rowCount(topIndex) > 0) { - QModelIndex childIndex = model->index(0, 0, topIndex); - qDebug() << "row " << childIndex.row() << " column " << childIndex.column() << " internal id " << childIndex.internalId(); - Q_ASSERT(model->parent(childIndex) == topIndex); - } - - // Common error test #3, the second column should NOT have the same children - // as the first column in a row. - // Usually the second column shouldn't have children. - QModelIndex topIndex1 = model->index(0, 1, QModelIndex()); - if (model->rowCount(topIndex1) > 0) { - QModelIndex childIndex = model->index(0, 0, topIndex); - QModelIndex childIndex1 = model->index(0, 0, topIndex1); - Q_ASSERT(childIndex != childIndex1); - } - - // Full test, walk n levels deep through the model making sure that all - // parent's children correctly specify their parent. - checkChildren(QModelIndex()); -} - -/*! - Called from the parent() test. - - A model that returns an index of parent X should also return X when asking - for the parent of the index. - - This recursive function does pretty extensive testing on the whole model in an - effort to catch edge cases. - - This function assumes that rowCount(), columnCount() and index() already work. - If they have a bug it will point it out, but the above tests should have already - found the basic bugs because it is easier to figure out the problem in - those tests then this one. - */ -void ModelTest::checkChildren(const QModelIndex &parent, int currentDepth) -{ - // First just try walking back up the tree. - QModelIndex p = parent; - while (p.isValid()) - p = p.parent(); - - // For models that are dynamically populated - if (model->canFetchMore(parent)) { - fetchingMore = true; - model->fetchMore(parent); - fetchingMore = false; - } - - int rows = model->rowCount(parent); - int columns = model->columnCount(parent); - - if (rows > 0) - Q_ASSERT(model->hasChildren(parent)); - - // Some further testing against rows(), columns(), and hasChildren() - Q_ASSERT(rows >= 0); - Q_ASSERT(columns >= 0); - if (rows > 0) - Q_ASSERT(model->hasChildren(parent) == true); - - //qDebug() << "parent:" << model->data(parent).toString() << "rows:" << rows - // << "columns:" << columns << "parent column:" << parent.column(); - - Q_ASSERT(model->hasIndex(rows + 1, 0, parent) == false); - for (int r = 0; r < rows; ++r) { - if (model->canFetchMore(parent)) { - fetchingMore = true; - model->fetchMore(parent); - fetchingMore = false; - } - Q_ASSERT(model->hasIndex(r, columns + 1, parent) == false); - for (int c = 0; c < columns; ++c) { - Q_ASSERT(model->hasIndex(r, c, parent) == true); - QModelIndex index = model->index(r, c, parent); - // rowCount() and columnCount() said that it existed... - Q_ASSERT(index.isValid() == true); - - // index() should always return the same index when called twice in a row - QModelIndex modifiedIndex = model->index(r, c, parent); - Q_ASSERT(index == modifiedIndex); - - // Make sure we get the same index if we request it twice in a row - QModelIndex a = model->index(r, c, parent); - QModelIndex b = model->index(r, c, parent); - Q_ASSERT(a == b); - - // Some basic checking on the index that is returned - Q_ASSERT(index.model() == model); - Q_ASSERT(index.row() == r); - Q_ASSERT(index.column() == c); - // While you can technically return a QVariant usually this is a sign - // of an bug in data() Disable if this really is ok in your model. - Q_ASSERT(model->data(index, Qt::DisplayRole).isValid() == true); - - // If the next test fails here is some somewhat useful debug you play with. - /* - if (model->parent(index) != parent) { - qDebug() << r << c << currentDepth << model->data(index).toString() - << model->data(parent).toString(); - qDebug() << index << parent << model->parent(index); - // And a view that you can even use to show the model. - //QTreeView view; - //view.setModel(model); - //view.show(); - }*/ - - // Check that we can get back our real parent. - Q_ASSERT(model->parent(index) == parent); - - // recursively go down the children - if (model->hasChildren(index) && currentDepth < 10 ) { - //qDebug() << r << c << "has children" << model->rowCount(index); - checkChildren(index, ++currentDepth); - }/* else { if (currentDepth >= 10) qDebug() << "checked 10 deep"; };*/ - - // make sure that after testing the children that the index doesn't change. - QModelIndex newerIndex = model->index(r, c, parent); - Q_ASSERT(index == newerIndex); - } - } -} - -/*! - Tests model's implementation of QAbstractItemModel::data() - */ -void ModelTest::data() -{ - // Invalid index should return an invalid qvariant - Q_ASSERT(!model->data(QModelIndex()).isValid()); - - if (model->rowCount() == 0) - return; - - // A valid index should have a valid QVariant data - Q_ASSERT(model->index(0, 0).isValid()); - - // shouldn't be able to set data on an invalid index - Q_ASSERT(model->setData(QModelIndex(), QLatin1String("foo"), Qt::DisplayRole) == false); - - // General Purpose roles that should return a QString - QVariant variant = model->data(model->index(0, 0), Qt::ToolTipRole); - if (variant.isValid()) { - Q_ASSERT(qVariantCanConvert(variant)); - } - variant = model->data(model->index(0, 0), Qt::StatusTipRole); - if (variant.isValid()) { - Q_ASSERT(qVariantCanConvert(variant)); - } - variant = model->data(model->index(0, 0), Qt::WhatsThisRole); - if (variant.isValid()) { - Q_ASSERT(qVariantCanConvert(variant)); - } - - // General Purpose roles that should return a QSize - variant = model->data(model->index(0, 0), Qt::SizeHintRole); - if (variant.isValid()) { - Q_ASSERT(qVariantCanConvert(variant)); - } - - // General Purpose roles that should return a QFont - QVariant fontVariant = model->data(model->index(0, 0), Qt::FontRole); - if (fontVariant.isValid()) { - Q_ASSERT(qVariantCanConvert(fontVariant)); - } - - // Check that the alignment is one we know about - QVariant textAlignmentVariant = model->data(model->index(0, 0), Qt::TextAlignmentRole); - if (textAlignmentVariant.isValid()) { - int alignment = textAlignmentVariant.toInt(); - Q_ASSERT(alignment == (alignment & (Qt::AlignHorizontal_Mask | Qt::AlignVertical_Mask))); - } - - // General Purpose roles that should return a QColor - QVariant colorVariant = model->data(model->index(0, 0), Qt::BackgroundColorRole); - if (colorVariant.isValid()) { - Q_ASSERT(qVariantCanConvert(colorVariant)); - } - - colorVariant = model->data(model->index(0, 0), Qt::TextColorRole); - if (colorVariant.isValid()) { - Q_ASSERT(qVariantCanConvert(colorVariant)); - } - - // Check that the "check state" is one we know about. - QVariant checkStateVariant = model->data(model->index(0, 0), Qt::CheckStateRole); - if (checkStateVariant.isValid()) { - int state = checkStateVariant.toInt(); - Q_ASSERT(state == Qt::Unchecked || - state == Qt::PartiallyChecked || - state == Qt::Checked); - } -} - -/*! - Store what is about to be inserted to make sure it actually happens - - \sa rowsInserted() - */ -void ModelTest::rowsAboutToBeInserted(const QModelIndex &parent, int start, int end) -{ - Q_UNUSED(end); - Changing c; - c.parent = parent; - c.oldSize = model->rowCount(parent); - c.last = model->data(model->index(start - 1, 0, parent)); - c.next = model->data(model->index(start, 0, parent)); - insert.push(c); -} - -/*! - Confirm that what was said was going to happen actually did - - \sa rowsAboutToBeInserted() - */ -void ModelTest::rowsInserted(const QModelIndex & parent, int start, int end) -{ - Changing c = insert.pop(); - Q_ASSERT(c.parent == parent); - Q_ASSERT(c.oldSize + (end - start + 1) == model->rowCount(parent)); - Q_ASSERT(c.last == model->data(model->index(start - 1, 0, c.parent))); - /* - if (c.next != model->data(model->index(end + 1, 0, c.parent))) { - qDebug() << start << end; - for (int i=0; i < model->rowCount(); ++i) - qDebug() << model->index(i, 0).data().toString(); - qDebug() << c.next << model->data(model->index(end + 1, 0, c.parent)); - } - */ - Q_ASSERT(c.next == model->data(model->index(end + 1, 0, c.parent))); -} - -void ModelTest::layoutAboutToBeChanged() -{ - for (int i = 0; i < qBound(0, model->rowCount(), 100); ++i) - changing.append(QPersistentModelIndex(model->index(i, 0))); -} - -void ModelTest::layoutChanged() -{ - for (int i = 0; i < changing.count(); ++i) { - QPersistentModelIndex p = changing[i]; - Q_ASSERT(p == model->index(p.row(), p.column(), p.parent())); - } - changing.clear(); -} - -/*! - Store what is about to be inserted to make sure it actually happens - - \sa rowsRemoved() - */ -void ModelTest::rowsAboutToBeRemoved(const QModelIndex &parent, int start, int end) -{ - Changing c; - c.parent = parent; - c.oldSize = model->rowCount(parent); - c.last = model->data(model->index(start - 1, 0, parent)); - c.next = model->data(model->index(end + 1, 0, parent)); - remove.push(c); -} - -/*! - Confirm that what was said was going to happen actually did - - \sa rowsAboutToBeRemoved() - */ -void ModelTest::rowsRemoved(const QModelIndex & parent, int start, int end) -{ - Changing c = remove.pop(); - Q_ASSERT(c.parent == parent); - Q_ASSERT(c.oldSize - (end - start + 1) == model->rowCount(parent)); - Q_ASSERT(c.last == model->data(model->index(start - 1, 0, c.parent))); - Q_ASSERT(c.next == model->data(model->index(start, 0, c.parent))); -} - diff -Nru kraft-0.95/src/models/modeltest.h kraft-0.96/src/models/modeltest.h --- kraft-0.95/src/models/modeltest.h 2020-08-28 16:01:48.000000000 +0000 +++ kraft-0.96/src/models/modeltest.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,76 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2007 Trolltech ASA. All rights reserved. -** -** This file is part of the Qt Concurrent project on Trolltech Labs. -** -** This file may be used under the terms of the GNU General Public -** License version 2.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of -** this file. Please review the following information to ensure GNU -** General Public Licensing requirements will be met: -** http://www.trolltech.com/products/qt/opensource.html -** -** If you are unsure which license is appropriate for your use, please -** review the following information: -** http://www.trolltech.com/products/qt/licensing.html or contact the -** sales department at sales@trolltech.com. -** -** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE -** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. -** -****************************************************************************/ - -#ifndef MODELTEST_H -#define MODELTEST_H - -#include -#include -#include - -class ModelTest : public QObject -{ - Q_OBJECT - -public: - ModelTest(QAbstractItemModel *model, QObject *parent = 0); - -private Q_SLOTS: - void nonDestructiveBasicTest(); - void rowCount(); - void columnCount(); - void hasIndex(); - void index(); - void parent(); - void data(); - -protected Q_SLOTS: - void runAllTests(); - void layoutAboutToBeChanged(); - void layoutChanged(); - void rowsAboutToBeInserted(const QModelIndex &parent, int start, int end); - void rowsInserted(const QModelIndex & parent, int start, int end); - void rowsAboutToBeRemoved(const QModelIndex &parent, int start, int end); - void rowsRemoved(const QModelIndex & parent, int start, int end); - -private: - void checkChildren(const QModelIndex &parent, int currentDepth = 0); - - QAbstractItemModel *model; - - struct Changing - { - QModelIndex parent; - int oldSize; - QVariant last; - QVariant next; - }; - QStack insert; - QStack remove; - - bool fetchingMore; - - QList changing; -}; - -#endif diff -Nru kraft-0.95/src/pdfconverter.cpp kraft-0.96/src/pdfconverter.cpp --- kraft-0.95/src/pdfconverter.cpp 2020-08-28 16:01:48.000000000 +0000 +++ kraft-0.96/src/pdfconverter.cpp 2021-02-27 20:44:46.000000000 +0000 @@ -188,7 +188,12 @@ args << mFile.fileName(); args << "-u"; args << styleSheetDir; + if (!_templatePath.isEmpty() && _templatePath != styleSheetDir) { + args << "-u"; + args << _templatePath; + } + qDebug() << "Arguments for weasyprint:" << args; mProcess->setProgram( prg ); mProcess->setArguments(args); mOutput.clear(); diff -Nru kraft-0.95/src/pdfconverter.h kraft-0.96/src/pdfconverter.h --- kraft-0.95/src/pdfconverter.h 2020-08-28 16:01:48.000000000 +0000 +++ kraft-0.96/src/pdfconverter.h 2021-02-27 20:44:46.000000000 +0000 @@ -47,6 +47,12 @@ QString getErrors() { return mErrors; } + /* + * Sets the path of the template which can be used as base path to find + * stylesheets and images and such. + */ + void setTemplatePath(const QString& path) { _templatePath = path; } + signals: void docAvailable(const QString& fileName); void converterError( ConvError ); @@ -55,6 +61,7 @@ QString mErrors; QProcess *mProcess; QFile mFile; + QString _templatePath; }; diff -Nru kraft-0.95/src/pics/book-open.svg kraft-0.96/src/pics/book-open.svg --- kraft-0.95/src/pics/book-open.svg 1970-01-01 00:00:00.000000000 +0000 +++ kraft-0.96/src/pics/book-open.svg 2021-02-27 20:44:46.000000000 +0000 @@ -0,0 +1 @@ + Binary files /tmp/tmpV0_lKe/qXC0NLaBlJ/kraft-0.95/src/pics/catalogue.png and /tmp/tmpV0_lKe/r3EAROErV2/kraft-0.96/src/pics/catalogue.png differ diff -Nru kraft-0.95/src/pics/catalogue.svg kraft-0.96/src/pics/catalogue.svg --- kraft-0.95/src/pics/catalogue.svg 2020-08-28 16:01:48.000000000 +0000 +++ kraft-0.96/src/pics/catalogue.svg 1970-01-01 00:00:00.000000000 +0000 @@ -1,86 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff -Nru kraft-0.95/src/pics/cloud.svg kraft-0.96/src/pics/cloud.svg --- kraft-0.95/src/pics/cloud.svg 1970-01-01 00:00:00.000000000 +0000 +++ kraft-0.96/src/pics/cloud.svg 2021-02-27 20:44:46.000000000 +0000 @@ -0,0 +1 @@ + diff -Nru kraft-0.95/src/pics/cloud-up.svg kraft-0.96/src/pics/cloud-up.svg --- kraft-0.95/src/pics/cloud-up.svg 1970-01-01 00:00:00.000000000 +0000 +++ kraft-0.96/src/pics/cloud-up.svg 2021-02-27 20:44:46.000000000 +0000 @@ -0,0 +1 @@ + diff -Nru kraft-0.95/src/pics/CMakeLists.txt kraft-0.96/src/pics/CMakeLists.txt --- kraft-0.95/src/pics/CMakeLists.txt 2020-08-28 16:01:48.000000000 +0000 +++ kraft-0.96/src/pics/CMakeLists.txt 2021-02-27 20:44:46.000000000 +0000 @@ -11,6 +11,5 @@ 16-actions-kraft_notax.png 16-actions-kraft_redtax.png 22-actions-kraftdice.png - sc-apps-kraft_catalogue.svg DESTINATION share/icons) diff -Nru kraft-0.95/src/pics/document-clock.svg kraft-0.96/src/pics/document-clock.svg --- kraft-0.95/src/pics/document-clock.svg 1970-01-01 00:00:00.000000000 +0000 +++ kraft-0.96/src/pics/document-clock.svg 2021-02-27 20:44:46.000000000 +0000 @@ -0,0 +1 @@ + Binary files /tmp/tmpV0_lKe/qXC0NLaBlJ/kraft-0.95/src/pics/document-new.png and /tmp/tmpV0_lKe/r3EAROErV2/kraft-0.96/src/pics/document-new.png differ Binary files /tmp/tmpV0_lKe/qXC0NLaBlJ/kraft-0.95/src/pics/document-open-recent.png and /tmp/tmpV0_lKe/r3EAROErV2/kraft-0.96/src/pics/document-open-recent.png differ diff -Nru kraft-0.95/src/pics/document-search.svg kraft-0.96/src/pics/document-search.svg --- kraft-0.95/src/pics/document-search.svg 1970-01-01 00:00:00.000000000 +0000 +++ kraft-0.96/src/pics/document-search.svg 2021-02-27 20:44:46.000000000 +0000 @@ -0,0 +1 @@ + diff -Nru kraft-0.95/src/pics/document.svg kraft-0.96/src/pics/document.svg --- kraft-0.95/src/pics/document.svg 1970-01-01 00:00:00.000000000 +0000 +++ kraft-0.96/src/pics/document.svg 2021-02-27 20:44:46.000000000 +0000 @@ -0,0 +1 @@ + diff -Nru kraft-0.95/src/pics/folders.svg kraft-0.96/src/pics/folders.svg --- kraft-0.95/src/pics/folders.svg 1970-01-01 00:00:00.000000000 +0000 +++ kraft-0.96/src/pics/folders.svg 2021-02-27 20:44:46.000000000 +0000 @@ -0,0 +1 @@ + diff -Nru kraft-0.95/src/pics/kraft.qrc kraft-0.96/src/pics/kraft.qrc --- kraft-0.95/src/pics/kraft.qrc 2020-08-28 16:01:48.000000000 +0000 +++ kraft-0.96/src/pics/kraft.qrc 2021-02-27 20:44:46.000000000 +0000 @@ -1,13 +1,18 @@ - user.png - catalogue.png Calendar_page.png - document-new.png - document-open-recent.png postit.png kraft_customer.png + book-open.svg + cloud.svg + cloud-up.svg + document-clock.svg + document-search.svg + document.svg + folders.svg + puzzlepart.svg + global/32-apps-kraft.png global/kraft_small_arm.png Binary files /tmp/tmpV0_lKe/qXC0NLaBlJ/kraft-0.95/src/pics/postit.png and /tmp/tmpV0_lKe/r3EAROErV2/kraft-0.96/src/pics/postit.png differ diff -Nru kraft-0.95/src/pics/puzzlepart.svg kraft-0.96/src/pics/puzzlepart.svg --- kraft-0.95/src/pics/puzzlepart.svg 1970-01-01 00:00:00.000000000 +0000 +++ kraft-0.96/src/pics/puzzlepart.svg 2021-02-27 20:44:46.000000000 +0000 @@ -0,0 +1 @@ + diff -Nru kraft-0.95/src/pics/README.icons kraft-0.96/src/pics/README.icons --- kraft-0.95/src/pics/README.icons 1970-01-01 00:00:00.000000000 +0000 +++ kraft-0.96/src/pics/README.icons 2021-02-27 20:44:46.000000000 +0000 @@ -0,0 +1,4 @@ +Tabler icons MIT licensed icons from +https://iconify.design/icon-sets/tabler/ + + diff -Nru kraft-0.95/src/pics/sc-apps-kraft_catalogue.svg kraft-0.96/src/pics/sc-apps-kraft_catalogue.svg --- kraft-0.95/src/pics/sc-apps-kraft_catalogue.svg 2020-08-28 16:01:48.000000000 +0000 +++ kraft-0.96/src/pics/sc-apps-kraft_catalogue.svg 1970-01-01 00:00:00.000000000 +0000 @@ -1,86 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Binary files /tmp/tmpV0_lKe/qXC0NLaBlJ/kraft-0.95/src/pics/user.png and /tmp/tmpV0_lKe/r3EAROErV2/kraft-0.96/src/pics/user.png differ diff -Nru kraft-0.95/src/portalview.cpp kraft-0.96/src/portalview.cpp --- kraft-0.95/src/portalview.cpp 2020-08-28 16:01:48.000000000 +0000 +++ kraft-0.96/src/portalview.cpp 2021-02-27 20:44:46.000000000 +0000 @@ -79,20 +79,20 @@ void PortalView::createIcons() { QListWidgetItem *documentsButton = new QListWidgetItem(_contentsWidget); - documentsButton->setIcon(QIcon(":/kraft/document-new.png")); + documentsButton->setIcon(QIcon(":/kraft/document.svg")); documentsButton->setText(i18n("Documents")); documentsButton->setTextAlignment(Qt::AlignHCenter); documentsButton->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); QListWidgetItem *timeLineButton = new QListWidgetItem(_contentsWidget); - timeLineButton->setIcon(QIcon(":/kraft/document-open-recent.png")); + timeLineButton->setIcon(QIcon(":/kraft/document-clock.svg")); timeLineButton->setText(i18n("Timeline")); timeLineButton->setTextAlignment(Qt::AlignHCenter); timeLineButton->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); QListWidgetItem *catButton = new QListWidgetItem(_contentsWidget); - catButton->setIcon(QIcon(":/kraft/catalogue.png")); + catButton->setIcon(QIcon(":/kraft/book-open.svg")); catButton->setText(i18n("Catalogs")); catButton->setTextAlignment(Qt::AlignHCenter); catButton->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); diff -Nru kraft-0.95/src/prefsdialog.cpp kraft-0.96/src/prefsdialog.cpp --- kraft-0.95/src/prefsdialog.cpp 2020-08-28 16:01:48.000000000 +0000 +++ kraft-0.96/src/prefsdialog.cpp 2021-02-27 20:44:46.000000000 +0000 @@ -335,15 +335,15 @@ const QDate d = QDate::currentDate(); mCbDateFormats->setToolTip( i18n( "The default date format for documents." ) ); QString formattedDate = d.toString(Qt::ISODate); - mCbDateFormats->insertItem( 0, i18n("ISO-Format: %1").arg(formattedDate)); + mCbDateFormats->insertItem( 0, i18n("ISO-Format: %1", formattedDate)); formattedDate = d.toString(Qt::DefaultLocaleShortDate); - mCbDateFormats->insertItem( 1, i18n("Short-Date: %1").arg(formattedDate)); + mCbDateFormats->insertItem( 1, i18n("Short-Date: %1", formattedDate)); formattedDate = d.toString(Qt::DefaultLocaleLongDate); - mCbDateFormats->insertItem( 2, i18n("Long-Date: %1").arg(formattedDate)); + mCbDateFormats->insertItem( 2, i18n("Long-Date: %1", formattedDate)); formattedDate = d.toString(Qt::RFC2822Date); - mCbDateFormats->insertItem( 3, i18n("RFC 2822-Format: %1").arg(formattedDate)); + mCbDateFormats->insertItem( 3, i18n("RFC 2822-Format: %1", formattedDate)); formattedDate = d.toString("dd.MM.yyyy"); - mCbDateFormats->insertItem( 4, i18n("\"German Format\": %1").arg(formattedDate)); + mCbDateFormats->insertItem( 4, i18n("\"German Format\": %1", formattedDate)); mCbDateFormats->insertItem( 5, i18n("Custom Setting in Settingsfile")); vboxLay->addLayout( butLay ); @@ -545,7 +545,7 @@ } #define IDENTITY_TAG(X) QLatin1String(X) -#define QL1(X) QLatin1String(X) +#define QL1(X) QStringLiteral(X) void PrefsDialog::fillManualIdentityForm(const KContacts::Addressee& addressee) { @@ -581,6 +581,14 @@ QString addressBookInfo; _pbChangeIdentity->setEnabled(backendUp); + + QPalette p; + QColor c = p.color(QPalette::Normal, QPalette::ToolTipBase); + tmpl.setValue(IDENTITY_TAG("CSS_WARN_BACKGROUND_COLOR"), c.name()); + + c = p.color(QPalette::Normal, QPalette::QPalette::Base); + tmpl.setValue(IDENTITY_TAG("CSS_IDENTITY_IMAGE_BACKGROUND"), "#ea4e1d"); // c.name()); + if( !backendUp ) { addressBookInfo = i18n("The identity can not be found."); tmpl.createDictionary(QL1("NO_IDENTITY")); @@ -668,7 +676,8 @@ } } - mIdentityView->displayContent(tmpl.expand()); + const QString ex = tmpl.expand(); + mIdentityView->displayContent(ex); } TaxItemDelegate::TaxItemDelegate(QObject * parent) : QItemDelegate(parent) {} diff -Nru kraft-0.95/src/reportgenerator.cpp kraft-0.96/src/reportgenerator.cpp --- kraft-0.95/src/reportgenerator.cpp 2020-08-28 16:01:48.000000000 +0000 +++ kraft-0.96/src/reportgenerator.cpp 2021-02-27 20:44:46.000000000 +0000 @@ -165,6 +165,7 @@ QFileInfo fi(_tmplFile); if (!fi.exists()) { emit failure(i18n("Template file is not accessible.")); + return; } const QString ext = fi.completeSuffix(); @@ -182,6 +183,8 @@ converter = new WeasyPrintPDFConverter; } + converter->setTemplatePath(fi.path()); + // expand the template... const QString expanded = templateEngine->expand(&_archDoc, myContact, mCustomerContact); diff -Nru kraft-0.95/src/templateprovider.cpp kraft-0.96/src/templateprovider.cpp --- kraft-0.95/src/templateprovider.cpp 2020-08-28 16:01:48.000000000 +0000 +++ kraft-0.96/src/templateprovider.cpp 2021-02-27 20:44:46.000000000 +0000 @@ -20,7 +20,7 @@ #include "textselection.h" TemplateProvider::TemplateProvider( QWidget *parent ) - : QObject(), mParent( parent ), mTextSelection( 0 ) + : QObject(), mParent( parent ), mTextSelection(nullptr) { } diff -Nru kraft-0.95/src/templtopositiondialogbase.h kraft-0.96/src/templtopositiondialogbase.h --- kraft-0.95/src/templtopositiondialogbase.h 2020-08-28 16:01:48.000000000 +0000 +++ kraft-0.96/src/templtopositiondialogbase.h 2021-02-27 20:44:46.000000000 +0000 @@ -36,7 +36,7 @@ ~TemplToPositionDialogBase( ); virtual void setDocPosition( DocPosition*, bool, bool ) = 0; - virtual void setCatalogChapters( const QList& ) = 0; + virtual void setCatalogChapters( const QList&, const QString& ) = 0; virtual QString chapter() const = 0; void setPositionList( DocPositionList, int ); diff -Nru kraft-0.95/src/version.h kraft-0.96/src/version.h --- kraft-0.95/src/version.h 2020-08-28 16:01:48.000000000 +0000 +++ kraft-0.96/src/version.h 2021-02-27 20:44:46.000000000 +0000 @@ -1,4 +1,4 @@ -#define KRAFT_VERSION "0.95" +#define KRAFT_VERSION "0.96" #define KRAFT_CODENAME "Gunny" diff -Nru kraft-0.95/views/identity.thtml kraft-0.96/views/identity.thtml --- kraft-0.95/views/identity.thtml 2020-08-28 16:01:48.000000000 +0000 +++ kraft-0.96/views/identity.thtml 2021-02-27 20:44:46.000000000 +0000 @@ -14,7 +14,7 @@ #identityimage { padding: 5px; - background-color: #eeeeee; + background-color: {{CSS_IDENTITY_IMAGE_BACKGROUND}}; padding-left: 80px; background-image: url(identity.png); background-repeat:no-repeat; @@ -30,7 +30,7 @@ } #no_identity_warn { - background-color: #ffcbcb; + background-color: {{CSS_WARN_BACKGROUND_COLOR}}; -moz-border-radius: 6px; -webkit-border-radius: 6px; padding: 5px; diff -Nru kraft-0.95/views/systemviewdetails.thtml kraft-0.96/views/systemviewdetails.thtml --- kraft-0.95/views/systemviewdetails.thtml 2020-08-28 16:01:48.000000000 +0000 +++ kraft-0.96/views/systemviewdetails.thtml 2021-02-27 20:44:46.000000000 +0000 @@ -117,20 +117,4 @@ {{WEASYPRINT_TOOL}} - - - {{ACKNOWLEGEMENT_LABEL}} - - - - - {{ICON_ACKNOWLEDGEMENT_LABEL}} - Madebyoliver - from - www.flaticon.com, - licensed by - CC 3.0 BY - - -