Compare commits

...

113 Commits
v2.0 ... v2.0.5

Author SHA1 Message Date
Veronica Berglyd Olsen
0b9ba78fac Release 2.0.5 (#1356) 2023-02-12 16:10:48 +01:00
Veronica Berglyd Olsen
c42f2e755c Make ODT tests ignore version number 2023-02-12 16:07:36 +01:00
Veronica Berglyd Olsen
2f0018ddfe Merge branch 'patch' into release_2.0.5 2023-02-12 16:04:10 +01:00
Veronica Berglyd Olsen
c4fd25ba56 Update changelog and release notes 2023-02-12 16:03:43 +01:00
Veronica Berglyd Olsen
f6a9fdd7ca Update completed and new translations (#1341) 2023-02-12 15:55:57 +01:00
Veronica Berglyd Olsen
dcadaddedf Merge branch 'patch' into update_i18n 2023-02-12 15:49:41 +01:00
Veronica Berglyd Olsen
b0952a38be Make ODT build pass validation entries (#1360) 2023-02-12 15:33:44 +01:00
Veronica Berglyd Olsen
7638db21ec Fix tests 2023-02-12 15:12:39 +01:00
Veronica Berglyd Olsen
c39e37c799 Add more meta data to supporet adding fields in LibreOffice 2023-02-12 14:44:01 +01:00
Veronica Berglyd Olsen
5796d55531 Title elements should be paragraph, not heading to be valid ODF 2023-02-12 13:27:43 +01:00
Veronica Berglyd Olsen
cce1ef54d8 Fix Open Document warning on settings.xml and bump version to 1.3 2023-02-12 12:54:05 +01:00
Veronica Berglyd Olsen
4b7a4e0789 Fix capitalisation in Portuguese translation 2023-02-12 08:36:30 +01:00
Veronica Berglyd Olsen
c2dd579eb4 Add Italian translation 2023-02-12 08:32:02 +01:00
Veronica Berglyd Olsen
ee550c2213 Update translations 2023-02-12 08:31:55 +01:00
Veronica Berglyd Olsen
6ed7c6f5a7 Update version and changelog 2023-02-10 21:50:10 +01:00
Veronica Berglyd Olsen
cd4bae976f Merge branch 'patch' into update_i18n 2023-02-10 21:16:07 +01:00
Veronica Berglyd Olsen
917a4375db Fix issues with novel tree last column (#1355) 2023-02-10 21:07:27 +01:00
Veronica Berglyd Olsen
7fe85ddfde Update base translation file 2023-02-10 20:59:26 +01:00
Veronica Berglyd Olsen
c1f1013cfd Improve test coverage 2023-02-10 20:55:37 +01:00
Veronica Berglyd Olsen
cf742a89c0 Add a menu entry to change column size for last column in novel tree 2023-02-10 20:49:47 +01:00
Veronica Berglyd Olsen
fd14c682a9 Allow more than one item in extra column 2023-02-10 20:16:49 +01:00
Veronica Berglyd Olsen
032ab630c1 Fix block formatting issues (#1354) 2023-02-10 20:11:26 +01:00
Veronica Berglyd Olsen
aa3fe96158 Add some comments to explain what's going on in the block formatting 2023-02-10 20:07:52 +01:00
Veronica Berglyd Olsen
5b20061607 Only insert line break for block formats if the block already has text (#1349, #1350) 2023-02-10 20:01:46 +01:00
Veronica Berglyd Olsen
5c30e1ae33 Merge branch 'patch' into update_i18n 2023-02-05 18:48:43 +01:00
Veronica Berglyd Olsen
25ab8ccbce Add project content path check (#1342) 2023-02-05 18:39:36 +01:00
Veronica Berglyd Olsen
492d94ee6e Check that content path exists before returning it from storage class (#1317) 2023-02-05 18:12:50 +01:00
Veronica Berglyd Olsen
6d45194253 Update completed translations and add Russian project file 2023-02-05 14:13:21 +01:00
Veronica Berglyd Olsen
cdbfcafc38 Make patch workflow match main 2023-02-05 00:16:30 +01:00
Veronica Berglyd Olsen
5f6f853336 Only run packaging workflow on certain tags 2023-02-05 00:00:47 +01:00
Veronica Berglyd Olsen
75b20889f4 Changes to MacOS build (#1340) 2023-02-04 23:46:48 +01:00
Veronica Berglyd Olsen
6b1183392f Try using workflow_dispatch instead 2023-02-04 23:44:03 +01:00
Veronica Berglyd Olsen
652ce3848b Try out using environment in workflow 2023-02-04 23:34:00 +01:00
Veronica Berglyd Olsen
1d90ab9fc1 Reverting som changes that didn't matter 2023-02-04 23:12:14 +01:00
Veronica Berglyd Olsen
cc48f8f8aa Try removeing the python3.1 folder 2023-02-04 22:27:16 +01:00
Veronica Berglyd Olsen
44f624faf4 Try the -a option instead 2023-02-04 20:54:51 +01:00
Veronica Berglyd Olsen
b4813f904a Try the preserve symlinks flag in mac bundle build 2023-02-04 20:45:15 +01:00
Veronica Berglyd Olsen
8a5ff3ab85 Turn off short retention time for now 2023-02-04 19:47:10 +01:00
Veronica Berglyd Olsen
76e1d47d14 Merge branch 'patch' into feature/macos-bundle 2023-02-04 19:33:32 +01:00
Veronica Berglyd Olsen
0e529fd72f Rewrite macOS build workflow and make some changes to build script 2023-02-04 19:33:12 +01:00
Veronica Berglyd Olsen
74ead29433 Move MacOS plist info back to a template file, and simplify stuff in setup.py 2023-02-04 19:33:04 +01:00
Veronica Berglyd Olsen
08bc2938df Add MacOS bundle distribution (#1276) 2023-02-04 17:37:47 +01:00
Veronica Berglyd Olsen
a6d9ed0c8c Merge branch 'patch' into macos-appbundle 2023-02-04 17:35:04 +01:00
Veronica Berglyd Olsen
c9d768e138 Project Details dialog fixes (#1339) 2023-02-04 16:48:18 +01:00
Veronica Berglyd Olsen
4ba3297d17 Update base translation file 2023-02-04 16:45:53 +01:00
Veronica Berglyd Olsen
a5d05ab777 Improve time format of editing time on project details dialog (#1335) 2023-02-04 16:32:41 +01:00
Veronica Berglyd Olsen
4e815a5f86 Make sure project name, title and author cannot be set to string "None" 2023-02-04 16:29:51 +01:00
Veronica Berglyd Olsen
b1bc80a0cd Make sure title and author is always refreshed when project details dialog is opened (#1336) 2023-02-04 16:29:23 +01:00
Rachel Powers
af1233925e fix icns generation and bundle display name.
while the icns *can* be generated on linux it is much preferable to generate it on macos
it is checked in as a convience

this commit fixes the appbundle not displaying the icon corrected
and corrects the app being displayed as "python" in the top bar when the bundle is run

Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-01-31 17:10:36 -07:00
Veronica Berglyd Olsen
71a8e72180 Merge branch 'patch' into macos-appbundle 2023-01-30 12:14:57 +01:00
Veronica Berglyd Olsen
9d46dde1c5 Fix typo in 2.0 release notes 2023-01-29 11:53:08 +01:00
Veronica Berglyd Olsen
4f11990b93 Release 2.0.4 (#1326) 2023-01-29 02:44:08 +01:00
Veronica Berglyd Olsen
e4cc9ef5b5 Bump version to 2.0.4 and update changelog 2023-01-29 02:34:42 +01:00
Veronica Berglyd Olsen
fe6d4de025 Fix PyQt5 version check (#1325) 2023-01-29 02:27:06 +01:00
Veronica Berglyd Olsen
c9fe0cad05 Also fix import in the error handler 2023-01-29 02:22:14 +01:00
Veronica Berglyd Olsen
1437659a4e Drop the splitVersionNumber function 2023-01-29 02:14:21 +01:00
Veronica Berglyd Olsen
0c75a53e57 Fix wrong inport of PyQt5 version (#1324) 2023-01-29 02:13:32 +01:00
Veronica Berglyd Olsen
e2f7e77ec2 Mentione Qt SVG dependency for Arch Linux in the docs (#1319) 2023-01-21 23:03:46 +01:00
Rachel Powers
beb95c49fa fix: fit artifact uploads
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-01-09 00:53:15 -07:00
Rachel Powers
f912d55177 refactor: move plist gen into setup.py
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-01-08 22:09:32 -07:00
Rachel Powers
b7e7a087f8 fix: remove codesign for now, only build on tags
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-01-08 19:27:12 -07:00
Rachel Powers
82dd1c46cf fix: force build on this branch for testing
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-01-08 19:27:12 -07:00
Rachel Powers
a228c4b32a Squashed commit of the following:
commit a1f358b6f0a193be7d3d72fa4082fa09701ebe16
Author: Rachel Powers <508861+Ryex@users.noreply.github.com>
Date:   Thu Dec 1 11:48:38 2022 -0700

    fix: reneable the res of the build

    Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>

commit 8ed02b09aeb9c302e30023fcbf73c8b5e3bbc8ff
Author: Rachel Powers <508861+Ryex@users.noreply.github.com>
Date:   Thu Dec 1 11:41:19 2022 -0700

    fix: install qt for tools

    Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>

commit d68dc29d49f1a2547912fc97867126f4fc6d96c4
Author: Rachel Powers <508861+Ryex@users.noreply.github.com>
Date:   Thu Dec 1 11:32:07 2022 -0700

    fix: add tex-gyre to texlive install

    Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>

commit ff654a2a914cd00c867088baf147f8ccd70a185c
Author: Rachel Powers <508861+Ryex@users.noreply.github.com>
Date:   Thu Dec 1 11:08:46 2022 -0700

    fix: add required latex pkgs

    Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>

commit 1a4babc11c274f69c6c04edddfc5011f9162759e
Author: Rachel Powers <508861+Ryex@users.noreply.github.com>
Date:   Thu Dec 1 10:17:31 2022 -0700

    fix: install sphinx via pip3

    Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>

commit 4b602b0955fabc2b5067bae46c3408dab0f0dd72
Author: Rachel Powers <508861+Ryex@users.noreply.github.com>
Date:   Thu Dec 1 10:05:46 2022 -0700

    fix: ensure sphinx is properly installed

    Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>

commit 59ad26f434d6c5391c2448724aa44587c2cf7a46
Author: Rachel Powers <508861+Ryex@users.noreply.github.com>
Date:   Thu Dec 1 09:59:40 2022 -0700

    feat: install scheme-basic texlive pkg
    run setup.py in proper dir

    Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>

commit 16cd50307fbd4519fd6ebdc719e78e99eb37d02b
Author: Rachel Powers <508861+Ryex@users.noreply.github.com>
Date:   Thu Dec 1 09:54:42 2022 -0700

    feat: build manual, translations, and sample project zip

    Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>

Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-01-08 19:27:12 -07:00
Rachel Powers
682986d9b9 fix: add entitlements
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-01-08 19:27:12 -07:00
Rachel Powers
b29b6d6eef fix: don't remove the python symlink
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-01-08 19:27:12 -07:00
Rachel Powers
8a9a52da57 fix: pull the version from the python file
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-01-08 19:27:12 -07:00
Rachel Powers
faf302c6d8 feat: add github workflow to build for macos
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-01-08 19:27:12 -07:00
Rachel
f71afb5732 feat: cleanup build script
use python 3.10
use curl over wget (pre-installed)
ensure enchant is installed
cleanup better to limit app bundle size
fix Info.plist

Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-01-08 19:27:12 -07:00
Rachel Powers
0eb7185d40 feat: add a macos build script
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
2023-01-08 19:27:12 -07:00
Veronica Berglyd Olsen
a671878e26 Add build for Ubuntu 23.04 2023-01-08 19:26:37 +01:00
Veronica Berglyd Olsen
5f65819f40 Release 2.0.3 (#1311) 2023-01-08 19:14:54 +01:00
Veronica Berglyd Olsen
ef268dc386 Bump version to 2.0.3 and update changelog and release notes 2023-01-08 19:11:26 +01:00
Veronica Berglyd Olsen
41a0788b4c Update copyright year to 2023 2023-01-08 18:47:04 +01:00
Veronica Berglyd Olsen
073a945b8e Update translations 2023-01-08 18:42:28 +01:00
Veronica Berglyd Olsen
90721e244b Fix handling of item with missing parent item (#1309) 2023-01-08 18:23:45 +01:00
Veronica Berglyd Olsen
65bfd20ced Update tests 2023-01-08 18:11:06 +01:00
Veronica Berglyd Olsen
22d761dea3 Improve handling of unexpected project items (#1283) 2023-01-08 17:57:47 +01:00
Veronica Berglyd Olsen
5daf4ed6bc Update status/import label form code (#1308) 2023-01-08 17:30:03 +01:00
Veronica Berglyd Olsen
be1894ab97 Clean up the status/import form code a bit 2023-01-08 17:24:36 +01:00
Veronica Berglyd Olsen
9529a79707 Clear the staus/import form when no item is selected (#1290) 2023-01-08 17:16:27 +01:00
Veronica Berglyd Olsen
f6e5293d8e Fix convert folders and open from outline (#1306) 2023-01-05 23:59:19 +01:00
Veronica Berglyd Olsen
31403b4299 Fix it again, but now also for enter key (#1291) 2023-01-05 23:54:51 +01:00
Veronica Berglyd Olsen
3b9e3762d3 Make sure editor/viewer is visible on open doc request (#1291) 2023-01-05 23:50:27 +01:00
Veronica Berglyd Olsen
748d76dca6 Fix converting folder to file (#1305) 2023-01-05 23:45:48 +01:00
Veronica Berglyd Olsen
7e0e18787f Add a check that a non-new project actually exists (#1301) 2022-12-23 12:34:08 +01:00
Veronica Berglyd Olsen
3b95b2838c Update test and translation file 2022-12-23 12:28:48 +01:00
Veronica Berglyd Olsen
8749321614 Block opening a non-new project in a non-existing location (#1300) 2022-12-23 12:28:30 +01:00
Veronica Berglyd Olsen
12c09b1f6c Update icons and allow custom icon themes (#1299) 2022-12-20 12:56:55 +01:00
Veronica Berglyd Olsen
1664f92cc8 Also allow custom icon themes 2022-12-20 12:50:21 +01:00
Veronica Berglyd Olsen
6c76e31e0b Remove Inkscape meta data from a bunch of icons 2022-12-20 12:32:42 +01:00
Veronica Berglyd Olsen
b7744bbda2 Correct paths for input-none icons (#1297) 2022-12-20 12:25:15 +01:00
Veronica Berglyd Olsen
187a75c99a Update i18n and contributor credits (#1298) 2022-12-20 12:10:31 +01:00
Veronica Berglyd Olsen
670aab5224 Remove redundant CSS 2022-12-20 12:06:14 +01:00
Veronica Berglyd Olsen
1c4256ff4c Make links consistent 2022-12-20 12:03:25 +01:00
Veronica Berglyd Olsen
55e91f08dd Add a credits page to the About dialog 2022-12-20 11:54:45 +01:00
Veronica Berglyd Olsen
c581c774e9 Update credits doc 2022-12-20 11:33:51 +01:00
Veronica Berglyd Olsen
bce5025a66 Update Chinese translation 2022-12-20 10:40:08 +01:00
Veronica Berglyd Olsen
66cc3777dc Release 2.0.2 (#1279) 2022-12-01 23:41:38 +01:00
Veronica Berglyd Olsen
b1def7b568 Release 2.0.2 2022-12-01 23:33:16 +01:00
Veronica Berglyd Olsen
1b177ff5b5 Fix highlighting not updating on prefs change (#1278) 2022-12-01 23:24:36 +01:00
Veronica Berglyd Olsen
594ccd45c7 Fix linux workflow 2022-12-01 23:21:00 +01:00
Veronica Berglyd Olsen
2b0216a398 Changing colouring preferences on the highlighting tab needs to re-init the syntax highlighter (#1274) 2022-12-01 23:12:46 +01:00
Veronica Berglyd Olsen
347266a9bd Post release fix (#1272) 2022-11-29 17:41:16 +01:00
Veronica Berglyd Olsen
e7bce03be4 Add empty init files to subdirs of main package 2022-11-29 17:22:23 +01:00
Veronica Berglyd Olsen
9d08d83c2c Release 2.0.1 (#1270) 2022-11-29 16:37:29 +01:00
Veronica Berglyd Olsen
e0f7e50b64 Release 2.0.1 2022-11-29 16:28:19 +01:00
Veronica Berglyd Olsen
b57d53adcd Update French translation (#1265) 2022-11-28 21:37:22 +01:00
Veronica Berglyd Olsen
875bde2253 Update French translation 2022-11-28 21:30:45 +01:00
Veronica Berglyd Olsen
e77426f364 Add a icon theme fallback value (#1264) 2022-11-28 21:28:37 +01:00
Veronica Berglyd Olsen
9af6fa062c Add more info on custome themes in the docs 2022-11-28 21:25:48 +01:00
Veronica Berglyd Olsen
6bc59eb7de Make the theme class fall back to typicons lighht icon theme (#1263) 2022-11-28 21:05:34 +01:00
Veronica Berglyd Olsen
49cab9ec29 Use direct imports everywhere (#1262) 2022-11-28 18:31:54 +01:00
Veronica Berglyd Olsen
32d75567e3 Use direct imports everywhere 2022-11-28 18:23:36 +01:00
150 changed files with 9756 additions and 4891 deletions

75
.github/workflows/build.yml vendored Normal file
View File

@@ -0,0 +1,75 @@
name: Build
on: workflow_dispatch
jobs:
buildAssets:
runs-on: ubuntu-latest
steps:
- name: Python Setup
uses: actions/setup-python@v4
with:
python-version: 3
architecture: x64
- name: Install Packages (apt)
run: |
sudo apt update
sudo apt install qttools5-dev-tools python3-sphinx latexmk texlive texlive-latex-extra
- name: Checkout Source
uses: actions/checkout@v3
- name: Run Build Commands
run: python setup.py qtlrelease sample manual
- name: Upload Artifacts
uses: actions/upload-artifact@v3
with:
name: nw-assets-${{ github.sha }}
path: |
novelwriter/assets/sample.zip
novelwriter/assets/manual.pdf
novelwriter/assets/i18n/*.qm
if-no-files-found: error
retention-days: 1
buildMac:
needs: buildAssets
strategy:
fail-fast: false
runs-on: macos-12
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Get Version
shell: bash
run: |
NW_VERSION=`awk '/^__version__/{print substr($NF,2,length($NF)-2)}' novelwriter/__init__.py`
echo "novelWriter Version: $NW_VERSION"
echo "VERSION=$NW_VERSION" >> $GITHUB_ENV
- name: Download Artifact
uses: actions/download-artifact@v3
with:
name: nw-assets-${{ github.sha }}
path: novelwriter/assets
- name: Build
run: |
./setup/macos/build.sh
- name: Upload ZIP
uses: actions/upload-artifact@v3
with:
name: novelWriter-${{ env.VERSION }}-macos.app.zip
path: dist_macos/novelWriter-${{ env.VERSION }}.app.zip
# retention-days: 1
- name: Upload DMG
uses: actions/upload-artifact@v3
with:
name: novelWriter-${{ env.VERSION }}-macos.dmg
path: dist_macos/novelWriter-${{ env.VERSION }}.dmg
# retention-days: 1

View File

@@ -25,7 +25,7 @@ jobs:
- name: Install Packages (apt)
run: |
sudo apt update
sudo apt install libenchant-dev qttools5-dev-tools aspell-en
sudo apt install libenchant-2-dev qttools5-dev-tools aspell-en
- name: Checkout Source
uses: actions/checkout@v3
- name: Install Dependencies (pip)

1
.gitignore vendored
View File

@@ -9,6 +9,7 @@
setup.iss
/novelwriter.desktop
/novelWriter.pyw
/setup/macos/Info.plist
# Translations
/novelwriter/assets/i18n/*.qm

View File

@@ -1,5 +1,178 @@
# novelWriter Changelog
## Version 2.0.5 [2023-02-12]
### Release Notes
This is a patch release that fixes a number of minor bugs and usability issues.
The Project Details dialog now properly updates when another project is opened, and the "Total
editing time" value has a less ambiguous time format. The editor no longer inserts blank lines if
block formats are applied to an empty line. The optional last column in the Novel Tree will now
show all items of the selected type, not only the first, and the column size can be adjusted from
the same menu where the column content is selected. The Open Document build output has been updated
to ODF 1.3 extended format, and passes validation.
An Italian translation has been added, and Russian is currently available for project builds. A
full translation into Russian is on its way.
### Detailed Changelog
**Bugfixes**
* Fixed an issue where the Title, Project Name and Author values of the Project Dialog would not
refresh when a project was closed and another opened. The issue is with the Qt library and
caching of the dialog, but novelWriter forces a refresh of the labels. These three were
previously missing though. Issue #1336. PR #1339.
* Add a check to the data storage class that a path exists before it is returned to other classes
that uses them for file I/O. Issue #1317. PR #1342.
* Fixed some issues with the Open Document build format as the produced document wasn't compliant
with the standard. It is now compliant with ODF 1.3 extended format. Issue #1359. PR #1360.
**Usability Fixes**
* The "Total editing time" label on the Project Details dialog now uses the same time format as the
status bar. That is, HH:MM:SS for times less than 24 hours, and D-HH:MM:SS for times from 24
hours and above. Issue #1335. PR #1339.
* Fixed an issue where applying block formatting to an empty line would insert a blank line before
it. This is a consequence of the change from #1175. The line break is now only added if the line
is _not_ blank. Issues #1349 and #1350. PR #1354.
* The optional third column in the Novel Tree now shows all references for the selected category
instead of just the first one. The maximum width of the column can also be selected from the
Novel Tree config menu. Issue #1351. PR #1355.
* The Open Document produced by the build tool now has the necessary title and author meta data set
so that it can be used in LibreOffice. Other meta data has also been added. Issue #1359.
PR #1360.
**Internationalisation**
* Existing translations for US English, Norwegian, Brazilian Portuguese, Latin American Spanish,
and German have been updated. French and Dutch are partially updated. PR #1341.
* Russian project variables have been added. Full translation is forthcoming. Contributed by
Aleksey (@SKYnv). PR #1341.
* A complete Italian translation has been added. Contributed by Riccardo Mangili. PR #1341.
**Packaging**
* Added App Bundle and DMG packages for MacOS. Contributed by @Ryex. PRs #1276 and #1340.
----
## Version 2.0.4 [2023-01-29]
### Release Notes
This is a patch release that fixes a bug where novelWriter would crash if PyQt5 version 5.15.8 was
installed and imported.
### Detailed Changelog
**Bugfixes**
* Fixed an issue with the version check against PyQt5, which was imported from the wrong package
when running novelWriter with PyQt5 version 5.15.8, released 2023-01-28. Issue #1324. PR #1325.
----
## Version 2.0.3 [2023-01-08]
### Release Notes
This is a patch release that fixes a few bugs and usability issues. The editing of status and
importance labels in Project Settings should now be a bit more intuitive. Opening a document from
the Outline View that is already open in the editor should now switch to the editor view. The
convert folder to note or document feature in the project tree has also been fixed. Some icons have
been updated and a renderring issue with one of them fixed. Chinese, Norwegian, US English, German
and Spanish translations have been updated as well. A new credits tab has been added to the About
dialog box, replacing the Credits section on the main About tab.
### Detailed Changelog
**Bugfixes**
* Fixed an issue with one of the active icons for the project tree. The SVG paths were not properly
joined. Issue #1297. PR #1299.
* Fixed an issue where the new open project routine for 2.0 would not check that a project exists
before trying to open it. This resulted in the open process creating all the expected folders in
the designated location before realising there was no project there. Issue #1300. PR #1301.
* Fixed an issue with the convert folder to document or note functionality was no longer working.
The context menu entries were actually just calling the function for converting a file.
Issue #1305. PR #1306.
* Fixed an issue where the app may crash if an item is added as a child of an item that exists, but
has invalid settings such that it is rejected by the project tree builder function when the
project is opened. Now, only items with a parent item that has already been added will be allowed
into the project tree. The issue was caused by an invalid project file, and is not likely to
occur during normal use, but such events should still be handled rather than crash the app.
Issue #1283. PR #1309.
**User Interface**
* The CREDITS.md file has been updated, and its content is now also available in a "Credits" tab in
the About dialog in the app. The old credits section of the "About" tab has been removed.
PR #1298.
* Fixed a usability issue where double-clicking an entry in the Outline that belongs to a document
that is already open in the editor does nothing. Now, the app switches view to the editor when
the heading is clicked. Issue #1291. PR #1306.
* Change how the editing of status and importance labels work in Project Settings. The form at the
bottom of the tabs is now always active when a label is selected, and always inactive when none
is selected. Issue #1290. PR #1308.
**Internationalisation**
* Update Chinese translation. PR #1298.
* Update Norwegian, US English, German and Spanish translations. PR #1311.
**Other CHanges**
* An icon theme can now be loaded from the user's data folder alongside a custom user theme.
Issue #1297. PR #1299.
* Some Inkscape format SVG files have been converted to Plain SVG. PR #1299.
----
## Version 2.0.2 [2022-12-01]
### Release Notes
This is a patch release that fixes a minor issues with syntax highlighting not updating when the
highlighting preferences were changed. It also fixes an issue that broke the FreeBSD release.
### Detailed Changelog
**Bugfixes**
* Fixed an issue where changing the Highlighting Preferences for highlighting quotes, emphasis, and
multiple or trailing spaces would not reload the syntax highlighter in the editor. The changes
would only take effect after restarting the app. Issue #1274. PR #1278.
**Packaging and Installation**
* The 2.0.1 release was broken on Linux, but was fixed and the packages rebuilt. However, the
FreeBSD port was still broken. This release fixes this issue. Issue #1277. PR #1272.
----
## Version 2.0.1 [2022-11-29]
### Release Notes
This is a patch release that fixes a minor issues with loading custom GUI themes that haven't been
updated to include the icon theme setting. The patch also updates the French translation.
### Detailed Changelog
**Bugfixes**
* Fixed an issue where starting the app with a custom GUI theme enabled would not load any icons at
all if the `icontheme` setting isn't specified. The app now loads the `typicons_light` theme by
default if no icon theme is set. Issue #1263. PR #1264.
**Internationalisation**
* The French translations has now been completed by @aaribaud. PR #1265.
----
## Version 2.0 [2022-11-28]
### Release Notes
@@ -79,7 +252,7 @@ icons. They are technically no longer tree views, but rather a Table of Contents
novel root folder. If you have multiple novel root folders, you can select which one to view.
In the Novel Tree View, you now also have the option to hide or show a third column of data.
Currently, you can chose between "Point of View Character", "Focus Character" and "Novel Plot". If
Currently, you can choose between "Point of View Character", "Focus Character" and "Novel Plot". If
you referenced more than one in the document, the column will only show the first entry, so make
sure the most important one is listed first in your document if you use this feature. An arrow icon
is also visible at the end of each row in the tree, and if you click on it, a tool tip should pop
@@ -133,7 +306,7 @@ _These Release Notes also include the changes from 2.0 pre-releases._
**Code Improvements**
* Fix an issue with circular imports mainly triggered from the test suite. PR #1166.
* Fixed an issue with circular imports mainly triggered from the test suite. PR #1166.
* Instead of assigning headers in a document a key by its line number, the headings are now
assigned sequential keys. This makes it easier to detect actual meta data changes, which would
otherwise be triggered by a change of line number as well. PR #1241.
@@ -271,7 +444,7 @@ Interface. PR #1146.
**Bugfixes**
* Fix a typo in the Lorem Ipsum tool and set a max width for the views bar. PR #1065.
* Fixed a typo in the Lorem Ipsum tool and set a max width for the views bar. PR #1065.
* The language set in the Build Tool is now properly exported to Open Document files. Previously,
it would be set to English regardless of the user's selection. Issue #1073. PR #1077.
* Since the text editor cursor extends to the right of its position in the window, it would

View File

@@ -4,41 +4,53 @@
* Veronica Berglyd Olsen (@vkbo)
## Main Contributors
## Contributors
* Concept: Marian Lückhof (@Number042)
* Internationalisation: Bruno Meneguello (@bkmeneguello)
* Setup and Packaging: Rachel Powers (@Ryex)
For other contributions, see the project's [Contributors](https://github.com/vkbo/novelWriter/graphs/contributors) page.
## Translations
The default language is English (UK) with English (US) as an option.
The default language is English (UK) with English (US) as an option. These are the original
translators for the languages currently available:
* Dutch: Martijn van der Kleijn (@mvdkleijn)
* French: Jan Lüdke (@jyhelle)
* German: Myian (@heymyian)
* Italian: Riccardo Mangili
* Latin American Spanish: Tommy Marplatt (@tmarplatt)
* Norwegian: Veronica Berglyd Olsen (@vkbo)
* Portuguese: Bruno Meneguello (@bkmeneguello)
* Simplified Chinese: Qianzhi Long (@longqzh)
Additional larger translation contributions:
* French: Albert Aribaud (@aaribaud)
Translations are managed on [Crowdin](https://crowdin.com/project/novelwriter), and more
contributions are listed on the project's [Members](https://crowdin.com/project/novelwriter/members) page.
## Libraries
The following libraries are dependencies of novelWriter:
* Qt5 by [Qt Company](https://www.qt.io/)
* PyQt5 by [Riverbank Computing](https://www.riverbankcomputing.com/software/pyqt/)
* lxml by [Martijn Faassen](https://lxml.de/)
* Enchant by [Dom Lachowicz](https://abiword.github.io/enchant/)
* PyEnchant by [Dimitri Merejkowsky](https://pyenchant.github.io/pyenchant/)
* [Qt5](https://www.qt.io) by Qt Company
* [PyQt5](https://www.riverbankcomputing.com/software/pyqt) by Riverbank Computing
* [lxml](https://lxml.de) by Martijn Faassen
* [Enchant](https://abiword.github.io/enchant) by Dom Lachowicz
* [PyEnchant](https://pyenchant.github.io/pyenchant) by Dimitri Merejkowsky
## Assets
Some of the assets bundled with novelWriter were adapted from the following sources:
* Typicons icons by [Stephen Hutchings](https://github.com/stephenhutchings/typicons.font) (CC BY-SA 4.0)
* Tomorrow syntax themes by Chris Kempson (MIT License)
* Owl syntax themes by Sarah Drasner (MIT License)
* Solarized themes by Ethan Schoonover, added by @nullbasis (MIT License)
* [Typicons](https://github.com/stephenhutchings/typicons.font) icons by Stephen Hutchings (CC BY-SA 4.0)
* [Tomorrow](https://github.com/chriskempson/base16) syntax themes by Chris Kempson (MIT License)
* [Owl](https://github.com/sdras/night-owl-vscode-theme) syntax themes by Sarah Drasner (MIT License)
* [Solarized](https://github.com/altercation/solarized) themes by Ethan Schoonover (MIT License)
## Special Mentions

View File

@@ -52,14 +52,109 @@ modify it as you like.
`novelwriter/assets/syntax <https://github.com/vkbo/novelWriter/tree/main/novelwriter/assets/syntax>`_.
* The existing GUI themes are stored in
`novelwriter/assets/themes <https://github.com/vkbo/novelWriter/tree/main/novelwriter/assets/themes>`_.
* The existing icon themes are stored in
`novelwriter/assets/icons <https://github.com/vkbo/novelWriter/tree/main/novelwriter/assets/icons>`_.
Remember to also change the name of your theme by modifying the ``name`` setting at the top of the
file, otherwise you may not be able to distinguish them in :guilabel:`Preferences`.
For novelWriter to be able to locate the custom theme files, you must copy them to the
:ref:`a_locations_data` location in your home or user area. There should be a folder there named
``syntax`` for syntax themes and just ``themes`` for GUI themes. These folders are created the
first time you start novelWriter.
``syntax`` for syntax themes, just ``themes`` for GUI themes, and ``icons`` for icon themes. These
folders are created the first time you start novelWriter.
Once the files are copied there, they should show up in :guilabel:`Preferences` with the label you
set as ``name`` inside the file.
.. note::
In novelWriter 2.0 the ``icontheme`` value was added to GUI themes. Make sure you set this value
in existing custom themes. Otherwise it defaults to ``typicons_light``, which may not match your
theme colour scheme.
Gustom GUI and Icons Theme
--------------------------
A GUI theme conf file consists of the follwing settings:
.. code-block:: cfg
[Main]
name = My Custom Theme
description = A description of my custom theme
author = Jane Doe
credit = John Doe
url = https://example.com
license = CC BY-SA 4.0
licenseurl = https://creativecommons.org/licenses/by-sa/4.0/
icontheme = typicons_light
[Palette]
window = 100, 100, 100
windowtext = 100, 100, 100
base = 100, 100, 100
alternatebase = 100, 100, 100
text = 100, 100, 100
tooltipbase = 100, 100, 100
tooltiptext = 100, 100, 100
button = 100, 100, 100
buttontext = 100, 100, 100
brighttext = 100, 100, 100
highlight = 100, 100, 100
highlightedtext = 100, 100, 100
link = 100, 100, 100
linkvisited = 100, 100, 100
[GUI]
statusnone = 100, 100, 100
statussaved = 100, 100, 100
statusunsaved = 100, 100, 100
In the Main section you must at least define the ``name`` and ``icontheme`` settings. The
``icontheme`` settings should correspond to one of the internal icon themes, either
``typicons_light`` or ``typicons_dark``, or to an icon theme in your custom icons directory. The
setting must match the icon theme's folder name.
The Palette values correspond the the Qt enum values for QPalette::ColorRole, see the
`Qt documentation <https://doc.qt.io/qt-5.15/qpalette.html#ColorRole-enum>`_ for more details. The
colour values are RGB numbers on the format ``r, g, b`` where each is an integer from to 255.
Omitted values are not loaded and will use default values.
Custom Syntax Theme
-------------------
A syntax theme conf file consists of the follwing settings:
.. code-block:: cfg
[Main]
name = My Syntax Theme
author = Jane Doe
credit = John Doe
url = https://example.com
license = CC BY-SA 4.0
licenseurl = https://creativecommons.org/licenses/by-sa/4.0/
[Syntax]
background = 255, 255, 255
text = 0, 0, 0
link = 0, 0, 0
headertext = 0, 0, 0
headertag = 0, 0, 0
emphasis = 0, 0, 0
straightquotes = 0, 0, 0
doublequotes = 0, 0, 0
singlequotes = 0, 0, 0
hidden = 0, 0, 0
keyword = 0, 0, 0
value = 0, 0, 0
spellcheckline = 0, 0, 0
errorline = 0, 0, 0
replacetag = 0, 0, 0
modifier = 0, 0, 0
In the Main section, you must define at least the ``name`` setting. The Syntax colour values are
RGB numbers on the format ``r, g, b`` where each is an integer from to 255. Omitted values are set
to black, except ``background`` which defaults to white,

View File

@@ -48,6 +48,13 @@ source, dependencies can still be installed from PyPi with:
pip install -r requirements.txt
.. note::
On Linux distros, the Qt library is usually split up into multiple packages. In some cases,
secondary dependencies may not be installed automatically. For novelWriter, the library files
for renderring the SVG icons may be left out and needs to be installed manually. This is the
case on for instance Arch Linux.
.. _a_source_install:

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

4480
i18n/nw_it_IT.ts Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -7,7 +7,7 @@ File History:
Created: 2018-09-22 [0.0.1]
This file is a part of novelWriter
Copyright 2018–2022, Veronica Berglyd Olsen
Copyright 2018–2023, Veronica Berglyd Olsen
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -54,14 +54,14 @@ from novelwriter.config import Config
##
__package__ = "novelwriter"
__copyright__ = "Copyright 2018–2022, Veronica Berglyd Olsen"
__copyright__ = "Copyright 2018–2023, Veronica Berglyd Olsen"
__license__ = "GPLv3"
__author__ = "Veronica Berglyd Olsen"
__maintainer__ = "Veronica Berglyd Olsen"
__email__ = "code@vkbo.net"
__version__ = "2.0"
__hexversion__ = "0x020000f0"
__date__ = "2022-11-28"
__version__ = "2.0.5"
__hexversion__ = "0x020005f0"
__date__ = "2023-02-12"
__status__ = "Stable"
__domain__ = "novelwriter.io"
__url__ = "https://novelwriter.io"
@@ -179,12 +179,12 @@ def main(sysArgs=None):
"At least Python 3.7 is required, found %s" % CONFIG.verPyString
)
errorCode |= 0x04
if CONFIG.verQtValue < 51000:
if CONFIG.verQtValue < 0x050a00:
errorData.append(
"At least Qt5 version 5.10 is required, found %s" % CONFIG.verQtString
)
errorCode |= 0x08
if CONFIG.verPyQtValue < 51000:
if CONFIG.verPyQtValue < 0x050a00:
errorData.append(
"At least PyQt5 version 5.10 is required, found %s" % CONFIG.verPyQtString
)

View File

@@ -0,0 +1,105 @@
{
"Synopsis": "Sinossi",
"Comment": "Commento",
"Notes": "Note",
"0": "Zero",
"1": "Uno",
"2": "Due",
"3": "Tre",
"4": "Quattro",
"5": "Cinque",
"6": "Sei",
"7": "Sette",
"8": "Otto",
"9": "Nove",
"10": "Dieci",
"11": "Undici",
"12": "Dodici",
"13": "Tredici",
"14": "Quattordici",
"15": "Quindici",
"16": "Sedici",
"17": "Diciassette",
"18": "Diciotto",
"19": "Diciannove",
"20": "Venti",
"21": "Ventuno",
"22": "Ventidue",
"23": "Ventitré",
"24": "Ventiquattro",
"25": "Venticinque",
"26": "Ventisei",
"27": "Ventisette",
"28": "Ventotto",
"29": "Ventinove",
"30": "Trenta",
"31": "Trentuno",
"32": "Trentadue",
"33": "Trentatré",
"34": "Trentaquattro",
"35": "Trentacinque",
"36": "Trentasei",
"37": "Trentasette",
"38": "Trentotto",
"39": "Trentanove",
"40": "Quaranta",
"41": "Quarantuno",
"42": "Quarantadue",
"43": "Quarantatré",
"44": "Quarantaquattro",
"45": "Quarantacinque",
"46": "Quarantasei",
"47": "Quarantasette",
"48": "Quarantotto",
"49": "Quarantanove",
"50": "Cinquanta",
"51": "Cinquantuno",
"52": "Cinquantadue",
"53": "Cinquantatré",
"54": "Cinquantaquattro",
"55": "Cinquantacinque",
"56": "Cinquantasei",
"57": "Cinquantasette",
"58": "Cinquantotto",
"59": "Cinquantanove",
"60": "Sessanta",
"61": "Sessantuno",
"62": "Sessantadue",
"63": "Sessantatre",
"64": "Sessantaquattro",
"65": "Sessantacinque",
"66": "Sessantasei",
"67": "Sessantasette",
"68": "Sessantotto",
"69": "Sessantanove",
"70": "Settanta",
"71": "Settantuno",
"72": "Settantadue",
"73": "Settantatré",
"74": "Settantaquattro",
"75": "Settantacinque",
"76": "Settantasei",
"77": "Settantasette",
"78": "Settantotto",
"79": "Settantanove",
"80": "Ottanta",
"81": "Ottantuno",
"82": "Ottantadue",
"83": "Ottantatré",
"84": "Ottantaquattro",
"85": "Ottantacinque",
"86": "Ottantasei",
"87": "Ottantasette",
"88": "Ottantotto",
"89": "Ottantanove",
"90": "Novanta",
"91": "Novantuno",
"92": "Novantadue",
"93": "Novantatré",
"94": "Novantaquattro",
"95": "Novantacinque",
"96": "Novantasei",
"97": "Novantasette",
"98": "Novantotto",
"99": "Novantanove"
}

View File

@@ -0,0 +1,105 @@
{
"Synopsis": "Сводка",
"Comment": "Комментарий",
"Notes": "Заметки",
"0": "Ноль",
"1": "Один",
"2": "Два",
"3": "Три",
"4": "Четыре",
"5": "Пять",
"6": "Шесть",
"7": "Семь",
"8": "Восемь",
"9": "Девять",
"10": "Десять",
"11": "Одиннадцать",
"12": "Двенадцать",
"13": "Тринадцать",
"14": "Четырнадцать",
"15": "Пятнадцать",
"16": "Шестнадцать",
"17": "Семнадцать",
"18": "Восемнадцатая",
"19": "Девятнадцать",
"20": "Двадцать",
"21": "Двадцать один",
"22": "Двадцать два",
"23": "Двадцать три",
"24": "Двадцать четыре",
"25": "Двадцать пять",
"26": "Двадцать шесть",
"27": "Двадцать семь",
"28": "Двадцать восемь",
"29": "Двадцать девять",
"30": "Тридцать",
"31": "Тридцать один",
"32": "Тридцать два",
"33": "Тридцать три",
"34": "Тридцать четыре",
"35": "Тридцать пятая",
"36": "Тридцать пять",
"37": "Тридцать семь",
"38": "Тридцать восемь",
"39": "Тридцать девять",
"40": "Сорок",
"41": "Сорок один",
"42": "Сорок два",
"43": "Сорок три",
"44": "Сорок четыре",
"45": "Сорок пять",
"46": "Сорок шесть",
"47": "Сорок семь",
"48": "Сорок восемь",
"49": "Сорок девять",
"50": "Пятьдесят",
"51": "Пятьдесят один",
"52": "Пятьдесят два",
"53": "Пятьдесят три",
"54": "Пятьдесят четыре",
"55": "Пятьдесят пять",
"56": "Пятьдесят шесть",
"57": "Пятьдесят семь",
"58": "Пятьдесят восемь",
"59": "Пятьдесят девять",
"60": "Шестьдесят",
"61": "Шестьдесят один",
"62": "Шестьдесят два",
"63": "Шестьдесят три",
"64": "Шестьдесят четыре",
"65": "Шестьдесят пять",
"66": "Шестьдесят шесть",
"67": "Шестьдесят семь",
"68": "Шестьдесят восемь",
"69": "Шестьдесят девять",
"70": "Семьдесят",
"71": "Семьдесят один",
"72": "Семьдесят два",
"73": "Семьдесят три",
"74": "Семьдесят четыре",
"75": "Семьдесят пять",
"76": "Семьдесят шесть",
"77": "Семьдесят семь",
"78": "Семьдесят восемь",
"79": "Семьдесят девять",
"80": "Восемьдесят",
"81": "Восемьдесят один",
"82": "Восемьдесят два",
"83": "Восемьдесят три",
"84": "Восемьдесят четыре",
"85": "Восемьдесят пять",
"86": "Восемьдесят шесть",
"87": "Восемьдесят семь",
"88": "Восемьдесят восемь",
"89": "Восемьдесят девять",
"90": "Девяносто",
"91": "Девяносто один",
"92": "Девяносто два",
"93": "Девяносто три",
"94": "Девяносто четыре",
"95": "Девяносто пять",
"96": "Девяносто шесть",
"97": "Девяносто семь",
"98": "Девяносто восемь",
"99": "Девяносто девять"
}

View File

@@ -1,37 +1,15 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
version="1.2"
width="24"
height="24"
viewBox="0 0 24 24"
id="svg7536"
sodipodi:docname="mixed_edit.svg"
inkscape:version="1.1.2 (0a00cf5339, 2022-02-04)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/">
<sodipodi:namedview
id="namedview1259"
pagecolor="#505050"
bordercolor="#eeeeee"
borderopacity="1"
inkscape:pageshadow="0"
inkscape:pageopacity="0"
inkscape:pagecheckerboard="0"
showgrid="false"
inkscape:zoom="34.625"
inkscape:cx="8.7364621"
inkscape:cy="11.98556"
inkscape:window-width="2560"
inkscape:window-height="1330"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="svg7536" />
id="svg7536">
<metadata
id="metadata7542">
<rdf:RDF>
@@ -40,6 +18,7 @@
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

@@ -25,10 +25,9 @@
</rdf:RDF>
</metadata>
<path
d="m2 17.714v-11.429c0-2.3629 1.9229-4.2857 4.2857-4.2857h11.429c2.3629 0 4.2857 1.9229 4.2857 4.2857v7.1429c0 0.79-0.64 1.4286-1.4286 1.4286-0.78857 0-1.4286-0.63857-1.4286-1.4286v-7.1429c0-0.78857-0.64143-1.4286-1.4286-1.4286h-11.429c-0.78714 0-1.4286 0.64-1.4286 1.4286v11.429c0 0.78857 0.64143 1.4286 1.4286 1.4286h4.2857c0.78857 0 1.4286 0.63857 1.4286 1.4286s-0.64 1.4286-1.4286 1.4286h-4.2857c-2.3629 0-4.2857-1.9229-4.2857-4.2857zm15.714 4.2857h-11.429c-2.3629 0-4.2857-1.9229-4.2857-4.2857v-11.429c0-2.3629 1.9229-4.2857 4.2857-4.2857h7.1429c0.79 0 1.4286 0.64 1.4286 1.4286 0 0.78857-0.63857 1.4286-1.4286 1.4286h-7.1429c-0.78857 0-1.4286 0.64143-1.4286 1.4286v11.429c0 0.78714 0.64 1.4286 1.4286 1.4286h11.429c0.78857 0 1.4286-0.64143 1.4286-1.4286v-4.2857c0-0.78857 0.63857-1.4286 1.4286-1.4286s1.4286 0.64 1.4286 1.4286v4.2857c0 2.3629-1.9229 4.2857-4.2857 4.2857z"
fill="#848484"
stroke-width="1.4286"
id="path2927" />
id="path2927"
style="fill:#848484;fill-opacity:1"
d="M 6.2851562,2 C 3.9296438,1.9318024 1.8530839,4.1116184 2,6.4548618 2.0068983,10.304935 1.9861657,14.15563 2.0104329,18.005313 2.1401885,20.174302 4.0868901,22.059322 6.2851562,22 c 3.8832648,-0.0037 7.7667178,0.0074 11.6498648,-0.0056 C 20.253096,21.935675 22.190613,19.73469 22,17.432001 21.996299,13.643017 22.007418,9.8538453 21.994414,6.0649793 21.935675,3.7469037 19.734691,1.8093866 17.432001,2 13.716386,2 10.000771,2 6.2851562,2 Z m 7.1621098,2.8554688 c 1.517767,0.018193 3.040205,-0.037158 4.55493,0.029088 0.831903,0.1432784 1.247019,1.0200413 1.140382,1.796579 -0.0049,3.726426 0.0098,7.453347 -0.0074,11.179464 -0.06228,0.897202 -0.990183,1.406807 -1.816343,1.281978 -3.726391,-0.005 -7.4532932,0.0099 -11.1793638,-0.0075 -0.8893499,-0.06498 -1.4061831,-0.991209 -1.2820783,-1.81622 0.00424,-3.720679 -0.00847,-7.4417768 0.00635,-11.1621953 0.056947,-0.8627405 0.9413144,-1.4230927 1.7608001,-1.2992468 2.2741995,-0.00131 4.5486615,0.00261 6.8226985,-0.00195 z" />
<rect
x="7"
y="10.1"

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

@@ -5,10 +5,6 @@
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
inkscape:version="1.0 (4035a4fb49, 2020-05-01)"
sodipodi:docname="arrow-maximise.svg"
id="svg7486"
viewBox="0 0 24 24"
height="24"
@@ -28,26 +24,6 @@
</metadata>
<defs
id="defs7490" />
<sodipodi:namedview
inkscape:current-layer="svg7486"
inkscape:window-maximized="1"
inkscape:window-y="1"
inkscape:window-x="2560"
inkscape:cy="12"
inkscape:cx="12"
inkscape:zoom="38.125"
showgrid="false"
id="namedview7488"
inkscape:window-height="1370"
inkscape:window-width="2560"
inkscape:pageshadow="2"
inkscape:pageopacity="0"
guidetolerance="10"
gridtolerance="10"
objecttolerance="10"
borderopacity="1"
bordercolor="#666666"
pagecolor="#ffffff" />
<path
style="stroke-width:1.25;fill:#6699cc;fill-opacity:1"
id="path7484"

Before

Width:  |  Height:  |  Size: 2.5 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@@ -5,10 +5,6 @@
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
inkscape:version="1.0 (4035a4fb49, 2020-05-01)"
sodipodi:docname="arrow-minimise.svg"
id="svg8816"
viewBox="0 0 24 24"
height="24"
@@ -28,26 +24,6 @@
</metadata>
<defs
id="defs8820" />
<sodipodi:namedview
inkscape:current-layer="svg8816"
inkscape:window-maximized="1"
inkscape:window-y="1"
inkscape:window-x="2560"
inkscape:cy="12"
inkscape:cx="12"
inkscape:zoom="38.125"
showgrid="false"
id="namedview8818"
inkscape:window-height="1370"
inkscape:window-width="2560"
inkscape:pageshadow="2"
inkscape:pageopacity="0"
guidetolerance="10"
gridtolerance="10"
objecttolerance="10"
borderopacity="1"
bordercolor="#666666"
pagecolor="#ffffff" />
<path
style="fill:#6699cc;fill-opacity:1;stroke-width:1.24999"
id="path8814"

Before

Width:  |  Height:  |  Size: 3.0 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

@@ -5,10 +5,6 @@
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
inkscape:version="1.0 (4035a4fb49, 2020-05-01)"
sodipodi:docname="refresh.svg"
id="svg6649"
viewBox="0 0 24 24"
height="24"
@@ -28,26 +24,6 @@
</metadata>
<defs
id="defs6653" />
<sodipodi:namedview
inkscape:current-layer="svg6649"
inkscape:window-maximized="1"
inkscape:window-y="1"
inkscape:window-x="2560"
inkscape:cy="12"
inkscape:cx="12"
inkscape:zoom="38.125"
showgrid="false"
id="namedview6651"
inkscape:window-height="1370"
inkscape:window-width="2560"
inkscape:pageshadow="2"
inkscape:pageopacity="0"
guidetolerance="10"
gridtolerance="10"
objecttolerance="10"
borderopacity="1"
bordercolor="#666666"
pagecolor="#ffffff" />
<path
style="fill:#99cc99;fill-opacity:1;stroke-width:1.33321"
id="path6647"

Before

Width:  |  Height:  |  Size: 2.5 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@@ -5,35 +5,11 @@
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
version="1.2"
width="24"
height="24"
viewBox="0 0 24 24"
id="svg5291"
sodipodi:docname="status_lines-dark.svg"
inkscape:version="1.0.1 (3bc2e813f5, 2020-09-07)">
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="2560"
inkscape:window-height="1344"
id="namedview6681"
showgrid="false"
inkscape:zoom="38.125"
inkscape:cx="12.065574"
inkscape:cy="12"
inkscape:window-x="2560"
inkscape:window-y="27"
inkscape:window-maximized="1"
inkscape:current-layer="svg5291" />
id="svg5291">
<metadata
id="metadata5297">
<rdf:RDF>
@@ -42,7 +18,7 @@
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@@ -1,37 +1,15 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
version="1.2"
width="24"
height="24"
viewBox="0 0 24 24"
id="svg7536"
sodipodi:docname="mixed_edit.svg"
inkscape:version="1.1.2 (0a00cf5339, 2022-02-04)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/">
<sodipodi:namedview
id="namedview1259"
pagecolor="#505050"
bordercolor="#eeeeee"
borderopacity="1"
inkscape:pageshadow="0"
inkscape:pageopacity="0"
inkscape:pagecheckerboard="0"
showgrid="false"
inkscape:zoom="34.625"
inkscape:cx="3.1913357"
inkscape:cy="11.98556"
inkscape:window-width="2560"
inkscape:window-height="1330"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="svg7536" />
id="svg7536">
<metadata
id="metadata7542">
<rdf:RDF>
@@ -40,6 +18,7 @@
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

@@ -25,10 +25,9 @@
</rdf:RDF>
</metadata>
<path
d="m2 17.714v-11.429c0-2.3629 1.9229-4.2857 4.2857-4.2857h11.429c2.3629 0 4.2857 1.9229 4.2857 4.2857v7.1429c0 0.79-0.64 1.4286-1.4286 1.4286-0.78857 0-1.4286-0.63857-1.4286-1.4286v-7.1429c0-0.78857-0.64143-1.4286-1.4286-1.4286h-11.429c-0.78714 0-1.4286 0.64-1.4286 1.4286v11.429c0 0.78857 0.64143 1.4286 1.4286 1.4286h4.2857c0.78857 0 1.4286 0.63857 1.4286 1.4286s-0.64 1.4286-1.4286 1.4286h-4.2857c-2.3629 0-4.2857-1.9229-4.2857-4.2857zm15.714 4.2857h-11.429c-2.3629 0-4.2857-1.9229-4.2857-4.2857v-11.429c0-2.3629 1.9229-4.2857 4.2857-4.2857h7.1429c0.79 0 1.4286 0.64 1.4286 1.4286 0 0.78857-0.63857 1.4286-1.4286 1.4286h-7.1429c-0.78857 0-1.4286 0.64143-1.4286 1.4286v11.429c0 0.78714 0.64 1.4286 1.4286 1.4286h11.429c0.78857 0 1.4286-0.64143 1.4286-1.4286v-4.2857c0-0.78857 0.63857-1.4286 1.4286-1.4286s1.4286 0.64 1.4286 1.4286v4.2857c0 2.3629-1.9229 4.2857-4.2857 4.2857z"
fill="#333"
stroke-width="1.4286"
id="path969" />
id="path969"
style="fill:#333333;fill-opacity:1"
d="M 6.2851562,2 C 3.9296438,1.9318024 1.8530839,4.1116184 2,6.4548618 2.0068983,10.304935 1.9861657,14.15563 2.0104329,18.005313 2.1401885,20.174302 4.0868901,22.059322 6.2851562,22 c 3.8832648,-0.0037 7.7667178,0.0074 11.6498648,-0.0056 C 20.253096,21.935675 22.190613,19.73469 22,17.432001 21.996299,13.643017 22.007418,9.8538453 21.994414,6.0649793 21.935675,3.7469037 19.734691,1.8093866 17.432001,2 13.716386,2 10.000771,2 6.2851562,2 Z m 7.1621098,2.8554688 c 1.517767,0.018193 3.040205,-0.037158 4.55493,0.029088 0.831903,0.1432784 1.247019,1.0200413 1.140382,1.796579 -0.0049,3.726426 0.0098,7.453347 -0.0074,11.179464 -0.06228,0.897202 -0.990183,1.406807 -1.816343,1.281978 -3.726391,-0.005 -7.4532932,0.0099 -11.1793638,-0.0075 -0.8893499,-0.06498 -1.4061831,-0.991209 -1.2820783,-1.81622 0.00424,-3.720679 -0.00847,-7.4417768 0.00635,-11.1621953 0.056947,-0.8627405 0.9413144,-1.4230927 1.7608001,-1.2992468 2.2741995,-0.00131 4.5486615,0.00261 6.8226985,-0.00195 z" />
<rect
x="7"
y="10.1"

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

@@ -5,15 +5,11 @@
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
version="1.2"
width="24"
height="24"
viewBox="0 0 24 24"
id="svg7486"
sodipodi:docname="arrow-maximise.svg"
inkscape:version="1.0 (4035a4fb49, 2020-05-01)">
id="svg7486">
<metadata
id="metadata7492">
<rdf:RDF>
@@ -28,27 +24,6 @@
</metadata>
<defs
id="defs7490" />
<sodipodi:namedview
inkscape:document-rotation="0"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="2560"
inkscape:window-height="1370"
id="namedview7488"
showgrid="false"
inkscape:zoom="38.125"
inkscape:cx="12"
inkscape:cy="12"
inkscape:window-x="2560"
inkscape:window-y="1"
inkscape:window-maximized="1"
inkscape:current-layer="svg7486" />
<path
d="m 15.75,2 c -0.69125,0 -1.25,0.56 -1.25,1.25 0,0.69 0.55875,1.25 1.25,1.25 h 1.9825 l -4.11625,4.11625 c -0.48875,0.48875 -0.48875,1.27875 0,1.7675 C 13.86,10.6275 14.18,10.75 14.5,10.75 c 0.32,0 0.64,-0.1225 0.88375,-0.36625 L 19.5,6.2675 V 8.25 c 0,0.69 0.55875,1.25 1.25,1.25 C 21.44125,9.5 22,8.94 22,8.25 V 2 Z M 8.61625,13.61625 4.5,17.7325 V 15.75 C 4.5,15.06 3.94125,14.5 3.25,14.5 2.55875,14.5 2,15.06 2,15.75 v 6.24875 H 3.245 L 8.25,22 C 8.94,22 9.5,21.44 9.5,20.75 9.5,20.06 8.94125,19.5 8.25,19.5 H 6.2675 l 4.11625,-4.115 c 0.48875,-0.48875 0.48875,-1.27875 0,-1.7675 C 9.895,13.12875 9.105,13.1275 8.61625,13.6163 Z M 5.75,12 C 6.44,12 7,11.44 7,10.75 V 7 h 3.75 C 11.44125,7 12,6.44 12,5.75 12,5.06 11.44125,4.5 10.75,4.5 H 4.50125 L 4.5,10.75 C 4.5,11.44 5.05875,12 5.75,12 Z m 12.5,0 C 17.55875,12 17,12.56 17,13.25 V 17 H 13.25 C 12.55875,17 12,17.56 12,18.25 c 0,0.69 0.55875,1.25 1.25,1.25 H 19.5 V 13.25 C 19.5,12.56 18.94125,12 18.25,12 Z"
id="path7484"

Before

Width:  |  Height:  |  Size: 2.5 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@@ -5,10 +5,6 @@
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
inkscape:version="1.0 (4035a4fb49, 2020-05-01)"
sodipodi:docname="arrow-minimise.svg"
id="svg8816"
viewBox="0 0 24 24"
height="24"
@@ -28,26 +24,6 @@
</metadata>
<defs
id="defs8820" />
<sodipodi:namedview
inkscape:current-layer="svg8816"
inkscape:window-maximized="1"
inkscape:window-y="1"
inkscape:window-x="2560"
inkscape:cy="12"
inkscape:cx="12"
inkscape:zoom="38.125"
showgrid="false"
id="namedview8818"
inkscape:window-height="1370"
inkscape:window-width="2560"
inkscape:pageshadow="2"
inkscape:pageopacity="0"
guidetolerance="10"
gridtolerance="10"
objecttolerance="10"
borderopacity="1"
bordercolor="#666666"
pagecolor="#ffffff" />
<path
style="fill:#4271ae;fill-opacity:1;stroke-width:1.24999"
id="path8814"

Before

Width:  |  Height:  |  Size: 3.0 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

@@ -1,34 +1,27 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
version="1.2"
width="24"
height="24"
viewBox="0 0 24 24"
id="svg1169"
sodipodi:docname="typ_export.svg"
inkscape:version="1.1.2 (0a00cf5339, 2022-02-04)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview2676"
pagecolor="#505050"
bordercolor="#eeeeee"
borderopacity="1"
inkscape:pageshadow="0"
inkscape:pageopacity="0"
inkscape:pagecheckerboard="0"
showgrid="false"
inkscape:zoom="34.625"
inkscape:cx="6.4259928"
inkscape:cy="11.98556"
inkscape:window-width="2560"
inkscape:window-height="1330"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="svg1169" />
id="svg1169">
<metadata
id="metadata13645">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs1173" />
<path

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@@ -5,15 +5,11 @@
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
version="1.2"
width="24"
height="24"
viewBox="0 0 24 24"
id="svg6649"
sodipodi:docname="refresh.svg"
inkscape:version="1.0 (4035a4fb49, 2020-05-01)">
id="svg6649">
<metadata
id="metadata6655">
<rdf:RDF>
@@ -28,27 +24,6 @@
</metadata>
<defs
id="defs6653" />
<sodipodi:namedview
inkscape:document-rotation="0"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="2560"
inkscape:window-height="1370"
id="namedview6651"
showgrid="false"
inkscape:zoom="38.125"
inkscape:cx="12"
inkscape:cy="12"
inkscape:window-x="2560"
inkscape:window-y="1"
inkscape:window-maximized="1"
inkscape:current-layer="svg6649" />
<path
d="M 13.162667,12.25611 H 20 V 5.4213831 C 19.989333,3.9083317 19.105333,3.5443996 18.036,4.6148668 L 16.497333,6.1585791 C 15.144,5.0987766 13.488,4.5188846 11.742667,4.5188846 9.676,4.5188846 7.7306667,5.3240679 6.2706667,6.7864621 4.8053333,8.242191 4,10.189828 4,12.25611 4,14.326391 4.8053333,16.271361 6.268,17.731089 7.7306667,19.193484 9.674667,20 11.742667,20 c 2.066666,0 4.012,-0.806516 5.474666,-2.270244 0.394667,-0.395926 0.744,-0.827845 1.04,-1.286427 C 18.72,15.72213 18.510667,14.763642 17.790667,14.303728 17.072,13.842481 16.113333,14.051775 15.652,14.770308 c -0.177333,0.275948 -0.389333,0.533234 -0.624,0.773189 -0.878667,0.87717 -2.045333,1.359747 -3.285333,1.359747 -1.24,0 -2.406667,-0.481244 -3.285334,-1.359747 -0.8759997,-0.87717 -1.3599997,-2.043619 -1.3599997,-3.286054 0,-1.239769 0.4826667,-2.406219 1.3599997,-3.280722 0.878667,-0.87717 2.045334,-1.36108 3.285334,-1.36108 0.917333,0 1.794666,0.26795 2.545333,0.762525 l -1.930667,1.934306 c -1.070666,1.069134 -0.706666,1.943638 0.805334,1.943638 z"
id="path6647"

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@@ -5,35 +5,11 @@
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
version="1.2"
width="24"
height="24"
viewBox="0 0 24 24"
id="svg5291"
sodipodi:docname="status_lines.svg"
inkscape:version="1.0.1 (3bc2e813f5, 2020-09-07)">
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="2560"
inkscape:window-height="1344"
id="namedview7270"
showgrid="false"
inkscape:zoom="38.125"
inkscape:cx="12.065574"
inkscape:cy="12"
inkscape:window-x="2560"
inkscape:window-y="27"
inkscape:window-maximized="1"
inkscape:current-layer="svg5291" />
id="svg5291">
<metadata
id="metadata5297">
<rdf:RDF>
@@ -42,7 +18,7 @@
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@@ -0,0 +1,70 @@
<!DOCTYPE html public "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<body>
<h2>Credits</h2>
<h3>Main Developer</h3>
<p>Veronica Berglyd Olsen (<a href="https://github.com/vkbo">@vkbo</a>)</p>
<h3>Contributors</h3>
<p>
<b>Concept:</b> Marian Lückhof (<a href="https://github.com/Number042">@Number042</a>)<br>
<b>Internationalisation:</b> Bruno Meneguello (<a href="https://github.com/bkmeneguello">@bkmeneguello</a>)<br>
<b>Setup and Packaging:</b> Rachel Powers (<a href="https://github.com/Ryex">@Ryex</a>)
</p>
<p>For other contributions, see the project's
<a href="https://github.com/vkbo/novelWriter/graphs/contributors">Contributors</a> page.</p>
<h3>Translations</h3>
<p>The default language is English (UK) with English (US) as an option. These are the original
translators for the languages currently available:</p>
<p>
<b>Dutch:</b> Martijn van der Kleijn (<a href="https://github.com/mvdkleijn">@mvdkleijn</a>)<br>
<b>French:</b> Jan Lüdke (<a href="https://github.com/jyhelle">@jyhelle</a>)<br>
<b>German:</b> Myian (<a href="https://github.com/heymyian">@heymyian</a>)<br>
<b>Italian:</b> Riccardo Mangili<br>
<b>Latin American Spanish:</b> Tommy Marplatt (<a href="https://github.com/tmarplatt">@tmarplatt</a>)<br>
<b>Norwegian:</b> Veronica Berglyd Olsen (<a href="https://github.com/vkbo">@vkbo</a>)<br>
<b>Portuguese:</b> Bruno Meneguello (<a href="https://github.com/bkmeneguello">@bkmeneguello</a>)<br>
<b>Simplified Chinese:</b> Qianzhi Long (<a href="https://github.com/longqzh">@longqzh</a>)
</p>
<p>Additional larger translation contributions:</p>
<p>
<b>French:</b> Albert Aribaud (<a href="https://github.com/aaribaud">@aaribaud</a>)
</p>
<p>Translations are managed on <a href="https://crowdin.com/project/novelwriter">Crowdin</a>, and
more contributions are listed on the project's <a href="https://crowdin.com/project/novelwriter/members">Members</a> page.</p>
<h3>Libraries</h3>
<p>The following libraries are dependencies of novelWriter:</p>
<p>
<a href="https://www.qt.io">Qt5</a> by Qt Company<br>
<a href="https://www.riverbankcomputing.com/software/pyqt">PyQt5</a> by Riverbank Computing<br>
<a href="https://lxml.de">lxml</a> by Martijn Faassen<br>
<a href="https://abiword.github.io/enchant">Enchant</a> by Dom Lachowicz<br>
<a href="https://pyenchant.github.io/pyenchant">PyEnchant</a> by Dimitri Merejkowsky
</p>
<h3>Assets</h3>
<p>Some of the assets bundled with novelWriter were adapted from the following sources:</p>
<p>
<a href="https://github.com/stephenhutchings/typicons.font">Typicons</a> icons by Stephen Hutchings (CC BY-SA 4.0)<br>
<a href="https://github.com/chriskempson/base16">Tomorrow</a> syntax themes by Chris Kempson (MIT License)<br>
<a href="https://github.com/sdras/night-owl-vscode-theme">Owl</a> syntax themes by Sarah Drasner (MIT License)<br>
<a href="https://github.com/altercation/solarized">Solarized</a> themes by Ethan Schoonover (MIT License)
</p>
<h3>Special Mentions</h3>
<p>Additional thanks to <a href="https://github.com/johnblommers">@johnblommers</a> who was an early user and who has provided a lot
of very useful feedback over the years.</p>
</body>
</html>

View File

@@ -5,6 +5,8 @@
<h2>Release Notes for 2.0</h2>
<p><i>Released on 28 November 2022</i></p>
<p>Scroll down for <a href="#patch">Patch Notes</a></p>
<p>This release includes a major update to the way your project is managed. It also modernises the
user interface. The project file format has also been updated, and your projects will be upgraded
the first time you open them in this release.</p>
@@ -68,7 +70,7 @@ document icons. They are technically no longer tree views, but rather a Table of
specific novel root folder. If you have multiple novel root folders, you can select which one to
view.</p>
<p>In the Novel Tree View, you now also have the option to hide or show a third column of data.
Currently, you can chose between "Point of View Character", "Focus Character" and "Novel Plot". If
Currently, you can choose between "Point of View Character", "Focus Character" and "Novel Plot". If
you referenced more than one in the document, the column will only show the first entry, so make
sure the most important one is listed first in your document if you use this feature. An arrow icon
is also visible at the end of each row in the tree, and if you click on it, a tool tip should pop
@@ -85,5 +87,44 @@ Project Settings dialog has been updated to reflect some of the same changes.</p
<p><i>See also the <a href="https://github.com/vkbo/novelWriter/releases">Releases</a> page.</i></p>
<a name="patch"></a><h2>Patch Notes</h2>
<h3>Patch 2.0.1 &ndash; 29 November 2022</h3>
<p>This is a patch release that fixes a minor issues with loading custom GUI themes that haven't
been updated to include the icon theme setting. The patch also updates the French translation.</p>
<h3>Patch 2.0.2 &ndash; 1 December 2022</h3>
<p>This is a patch release that fixes a minor issues with syntax highlighting not updating when the
highlighting preferences were changed. It also fixes an issue that broke the FreeBSD release.</p>
<h3>Patch 2.0.3 &ndash; 8 January 2023</h3>
<p>This is a patch release that fixes a few bugs and usability issues. The editing of status and
importance labels in Project Settings should now be a bit more intuitive. Opening a document from
the Outline View that is already open in the editor should now switch to the editor view. The
convert folder to note or document feature in the project tree has also been fixed. Some icons have
been updated and a renderring issue with one of them fixed. Chinese, Norwegian, US English, German
and Spanish translations have been updated as well. A new credits tab has been added to the About
dialog box, replacing the Credits section on the main About tab.</p>
<h3>Patch 2.0.4 &ndash; 29 January 2023</h3>
<p>This is a patch release that fixes a bug where novelWriter would crash if PyQt5 version 5.15.8
was installed and imported.</p>
<h3>Patch 2.0.5 &ndash; 12 February 2023</h3>
<p>This is a patch release that fixes a number of minor bugs and usability issues.</p>
<p>The Project Details dialog now properly updates when another project is opened, and the "Total
editing time" value has a less ambiguous time format. The editor no longer inserts blank lines if
block formats are applied to an empty line. The optional last column in the Novel Tree will now
show all items of the selected type, not only the first, and the column size can be adjusted from
the same menu where the column content is selected. The Open Document build output has been updated
to ODF 1.3 extended format, and passes validation.</p>
<p>An Italian translation has been added, and Russian is currently available for project builds. A
full translation into Russian is on its way.</p>
</body>
</html>

View File

@@ -7,7 +7,7 @@ File History:
Created: 2019-05-12 [0.1]
This file is a part of novelWriter
Copyright 2018–2022, Veronica Berglyd Olsen
Copyright 2018–2023, Veronica Berglyd Olsen
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -277,33 +277,6 @@ def yesNo(value):
return "yes" if value else "no"
def splitVersionNumber(value):
"""Split a version string on the form aa.bb.cc into major, minor
and patch, and computes an integer value aabbcc.
"""
if not isinstance(value, str):
return 0, 0, 0, 0
vMajor = 0
vMinor = 0
vPatch = 0
vInt = 0
vBits = value.split(".")
nBits = len(vBits)
if nBits > 0:
vMajor = checkInt(vBits[0], 0)
if nBits > 1:
vMinor = checkInt(vBits[1], 0)
if nBits > 2:
vPatch = checkInt(vBits[2], 0)
vInt = vMajor*10000 + vMinor*100 + vPatch
return vMajor, vMinor, vPatch, vInt
def transferCase(source, target):
"""Transfers the case of the source word to the target word. This
will consider all upper or lower, and first char capitalisation.

View File

@@ -7,7 +7,7 @@ File History:
Created: 2018-09-22 [0.0.1]
This file is a part of novelWriter
Copyright 2018–2022, Veronica Berglyd Olsen
Copyright 2018–2023, Veronica Berglyd Olsen
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -30,14 +30,13 @@ import logging
from time import time
from pathlib import Path
from PyQt5.Qt import PYQT_VERSION_STR
from PyQt5.QtCore import (
QT_VERSION_STR, QStandardPaths, QSysInfo, QLocale, QLibraryInfo,
QTranslator
QT_VERSION, QT_VERSION_STR, PYQT_VERSION, PYQT_VERSION_STR, QStandardPaths,
QSysInfo, QLocale, QLibraryInfo, QTranslator
)
from novelwriter.error import logException, formatException
from novelwriter.common import checkPath, splitVersionNumber, formatTimeStamp, NWConfigParser
from novelwriter.common import checkPath, formatTimeStamp, NWConfigParser
from novelwriter.constants import nwFiles, nwUnicode
logger = logging.getLogger(__name__)
@@ -190,25 +189,13 @@ class Config:
# ==========================
# Check Qt5 Versions
verQt = splitVersionNumber(QT_VERSION_STR)
self.verQtString = QT_VERSION_STR
self.verQtMajor = verQt[0]
self.verQtMinor = verQt[1]
self.verQtPatch = verQt[2]
self.verQtValue = verQt[3]
verQt = splitVersionNumber(PYQT_VERSION_STR)
self.verQtString = QT_VERSION_STR
self.verQtValue = QT_VERSION
self.verPyQtString = PYQT_VERSION_STR
self.verPyQtMajor = verQt[0]
self.verPyQtMinor = verQt[1]
self.verPyQtPatch = verQt[2]
self.verPyQtValue = verQt[3]
self.verPyQtValue = PYQT_VERSION
# Check Python Version
self.verPyString = sys.version.split()[0]
self.verPyMajor = sys.version_info[0]
self.verPyMinor = sys.version_info[1]
self.verPyPatch = sys.version_info[2]
self.verPyHexVal = sys.hexversion
# Check OS Type
@@ -461,10 +448,11 @@ class Config:
self._confPath.mkdir(exist_ok=True)
self._dataPath.mkdir(exist_ok=True)
# Also create the syntax and themes folders if possible
# Also create the syntax, themes and icons folders if possible
if self._dataPath.is_dir():
(self._dataPath / "syntax").mkdir(exist_ok=True)
(self._dataPath / "themes").mkdir(exist_ok=True)
(self._dataPath / "icons").mkdir(exist_ok=True)
# Check if config file exists, and load it. If not, we save defaults
if (self._confPath / nwFiles.CONF_FILE).is_file():

View File

@@ -7,7 +7,7 @@ File History:
Created: 2019-04-28 [0.0.1]
This file is a part of novelWriter
Copyright 2018–2022, Veronica Berglyd Olsen
Copyright 2018–2023, Veronica Berglyd Olsen
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@@ -1,40 +1,3 @@
"""
novelWriter – Core Init
=======================
This file is a part of novelWriter
Copyright 2018–2022, Veronica Berglyd Olsen
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
novelWriter – Core Init File
"""
from novelwriter.core.coretools import DocMerger, DocSplitter, ProjectBuilder
from novelwriter.core.index import countWords
from novelwriter.core.project import NWProject
from novelwriter.core.spellcheck import NWSpellEnchant
from novelwriter.core.tohtml import ToHtml
from novelwriter.core.toodt import ToOdt
from novelwriter.core.tomd import ToMarkdown
__all__ = [
"DocMerger",
"DocSplitter",
"ProjectBuilder",
"countWords",
"NWProject",
"NWSpellEnchant",
"ToHtml",
"ToOdt",
"ToMarkdown",
]

View File

@@ -8,7 +8,7 @@ Created: 2022-10-02 [2.0rc1] DocMerger
Created: 2022-10-11 [2.0rc1] DocSplitter
This file is a part of novelWriter
Copyright 2018–2022, Veronica Berglyd Olsen
Copyright 2018–2023, Veronica Berglyd Olsen
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@@ -7,7 +7,7 @@ File History:
Created: 2018-09-29 [0.0.1]
This file is a part of novelWriter
Copyright 2018–2022, Veronica Berglyd Olsen
Copyright 2018–2023, Veronica Berglyd Olsen
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@@ -12,7 +12,7 @@ Created: 2022-05-29 [2.0rc1] TagsIndex
Created: 2022-05-29 [2.0rc1] ItemIndex
This file is a part of novelWriter
Copyright 2018–2022, Veronica Berglyd Olsen
Copyright 2018–2023, Veronica Berglyd Olsen
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -36,10 +36,8 @@ from pathlib import Path
from novelwriter.enum import nwItemType, nwItemLayout
from novelwriter.error import logException
from novelwriter.common import checkInt, isHandle, isItemClass, isTitleTag, jsonEncode
from novelwriter.constants import nwFiles, nwKeyWords, nwUnicode, nwHeaders
from novelwriter.common import (
checkInt, isHandle, isItemClass, isTitleTag, jsonEncode
)
logger = logging.getLogger(__name__)

View File

@@ -7,7 +7,7 @@ File History:
Created: 2018-10-27 [0.0.1]
This file is a part of novelWriter
Copyright 2018–2022, Veronica Berglyd Olsen
Copyright 2018–2023, Veronica Berglyd Olsen
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@@ -8,7 +8,7 @@ Created: 2019-10-21 [0.3.1]
Rewritten: 2020-02-19 [0.4.5]
This file is a part of novelWriter
Copyright 2018–2022, Veronica Berglyd Olsen
Copyright 2018–2023, Veronica Berglyd Olsen
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -59,7 +59,7 @@ VALID_MAP = {
"widthCol3", "widthCol4", "wordsPerPage", "countFrom", "clearDouble",
},
"GuiWordList": {"winWidth", "winHeight"},
"GuiNovelView": {"lastCol"},
"GuiNovelView": {"lastCol", "lastColSize"},
}

View File

@@ -7,7 +7,7 @@ File History:
Created: 2018-09-29 [0.0.1]
This file is a part of novelWriter
Copyright 2018–2022, Veronica Berglyd Olsen
Copyright 2018–2023, Veronica Berglyd Olsen
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -251,6 +251,9 @@ class NWProject(QObject):
"""
self.clearProject()
if not self._storage.openProjectInPlace(projPath):
self.mainGui.makeAlert(self.tr(
"Could not open project with path: {0}"
).format(projPath), nwAlert.ERROR)
return False
logger.info("Opening project: %s", projPath)

View File

@@ -7,7 +7,7 @@ File History:
Created: 2022-10-30 [2.0rc2]
This file is a part of novelWriter
Copyright 2018–2022, Veronica Berglyd Olsen
Copyright 2018–2023, Veronica Berglyd Olsen
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -207,7 +207,7 @@ class NWProjectData:
"""Set a new project name.
"""
if value != self._name:
self._name = simplified(str(value))
self._name = simplified(str(value or ""))
self.theProject.setProjectChanged(True)
return
@@ -215,7 +215,7 @@ class NWProjectData:
"""Set a new novel title.
"""
if value != self._title:
self._title = simplified(str(value))
self._title = simplified(str(value or ""))
self.theProject.setProjectChanged(True)
return
@@ -223,7 +223,7 @@ class NWProjectData:
"""Set the author value.
"""
if value != self._title:
self._author = simplified(str(value))
self._author = simplified(str(value or ""))
self.theProject.setProjectChanged(True)
return

View File

@@ -9,7 +9,7 @@ Created: 2022-09-28 [2.0rc2] ProjectXMLReader
Created: 2022-10-31 [2.0rc2] ProjectXMLWriter
This file is a part of novelWriter
Copyright 2018–2022, Veronica Berglyd Olsen
Copyright 2018–2023, Veronica Berglyd Olsen
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@@ -7,7 +7,7 @@ File History:
Created: 2019-06-11 [0.1.5]
This file is a part of novelWriter
Copyright 2018–2022, Veronica Berglyd Olsen
Copyright 2018–2023, Veronica Berglyd Olsen
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@@ -8,7 +8,7 @@ Created: 2019-05-19 [0.1.3]
Rewritten: 2022-04-05 [2.0b1]
This file is a part of novelWriter
Copyright 2018–2022, Veronica Berglyd Olsen
Copyright 2018–2023, Veronica Berglyd Olsen
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@@ -7,7 +7,7 @@ File History:
Created: 2022-11-01 [2.0rc2] NWStorage
This file is a part of novelWriter
Copyright 2018–2022, Veronica Berglyd Olsen
Copyright 2018–2023, Veronica Berglyd Olsen
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -30,11 +30,11 @@ from time import time
from pathlib import Path
from zipfile import ZIP_DEFLATED, ZIP_STORED, ZipFile
from novelwriter.error import logException
from novelwriter.common import minmax
from novelwriter.constants import nwFiles
from novelwriter.core.document import NWDocument
from novelwriter.core.projectxml import ProjectXMLReader, ProjectXMLWriter
from novelwriter.error import logException
logger = logging.getLogger(__name__)
@@ -79,8 +79,16 @@ class NWStorage:
@property
def contentPath(self):
"""Return the path used for project content. The folder must
already exist, otherwise this property is None.
"""
if self._runtimePath is not None:
return self._runtimePath / "content"
contentPath = self._runtimePath / "content"
if contentPath.is_dir():
return contentPath
else:
logger.error("Path not found: %s", contentPath)
return None
return None
##
@@ -102,6 +110,10 @@ class NWStorage:
# but it can point to a folder containing files
inPath = inPath.parent
if not (inPath.is_dir() or newProject):
# If the project is not new, the folder must already exist.
return False
self._storagePath = inPath
self._runtimePath = inPath
self._lockFilePath = inPath / nwFiles.PROJ_LOCK
@@ -114,7 +126,9 @@ class NWStorage:
return True
def openProjectArchive(self, path): # pragma: no cover
pass
"""Placeholder for later implementation. See #977.
"""
return False
def runPostSaveTasks(self, autoSave=False): # pragma: no cover
"""Run tasks after the project has been saved.

View File

@@ -7,7 +7,7 @@ File History:
Created: 2019-05-07 [0.0.1]
This file is a part of novelWriter
Copyright 2018–2022, Veronica Berglyd Olsen
Copyright 2018–2023, Veronica Berglyd Olsen
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -25,8 +25,8 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
import logging
from novelwriter.core.tokenizer import Tokenizer
from novelwriter.constants import nwKeyWords, nwLabels, nwHtmlUnicode
from novelwriter.core.tokenizer import Tokenizer
logger = logging.getLogger(__name__)

View File

@@ -7,7 +7,7 @@ File History:
Created: 2019-05-05 [0.0.1]
This file is a part of novelWriter
Copyright 2018–2022, Veronica Berglyd Olsen
Copyright 2018–2023, Veronica Berglyd Olsen
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@@ -7,7 +7,7 @@ File History:
Created: 2021-02-06 [1.2b1]
This file is a part of novelWriter
Copyright 2018–2022, Veronica Berglyd Olsen
Copyright 2018–2023, Veronica Berglyd Olsen
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@@ -7,7 +7,7 @@ File History:
Created: 2021-01-26 [1.2b1]
This file is a part of novelWriter
Copyright 2018–2022, Veronica Berglyd Olsen
Copyright 2018–2023, Veronica Berglyd Olsen
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -44,12 +44,13 @@ XML_NS = {
"text": "urn:oasis:names:tc:opendocument:xmlns:text:1.0",
"meta": "urn:oasis:names:tc:opendocument:xmlns:meta:1.0",
"fo": "urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0",
"dc": "http://purl.org/dc/elements/1.1/",
}
MANI_NS = {
"manifest": "urn:oasis:names:tc:opendocument:xmlns:manifest:1.0"
}
OFFICE_NS = {
"office": XML_NS["office"]
"office": "urn:oasis:names:tc:opendocument:xmlns:office:1.0",
}
@@ -65,7 +66,7 @@ def _mkTag(nsName, tagName, nsMap=XML_NS):
# Mimetype and Version
X_MIME = "application/vnd.oasis.opendocument.text"
X_VERS = "1.2"
X_VERS = "1.3"
# Text Formatting Tags
TAG_BR = _mkTag("text", "line-break")
@@ -261,7 +262,7 @@ class ToOdt(Tokenizer):
# ===============
if self._headerText == "":
theTitle = self.theProject.data.title
theTitle = self.theProject.data.title or self.theProject.data.name
theAuth = self.theProject.data.author
self._headerText = f"{theTitle} / {theAuth} /"
@@ -328,13 +329,37 @@ class ToOdt(Tokenizer):
self._xText = etree.SubElement(self._xBody, _mkTag("office", "text"))
# Meta Data
timeStamp = datetime.now().isoformat(sep="T", timespec="seconds")
# Office Meta Data
xMeta = etree.SubElement(self._xMeta, _mkTag("meta", "creation-date"))
xMeta.text = datetime.now().isoformat(sep="T", timespec="seconds")
xMeta.text = timeStamp
xMeta = etree.SubElement(self._xMeta, _mkTag("meta", "generator"))
xMeta.text = f"novelWriter/{novelwriter.__version__}"
xMeta = etree.SubElement(self._xMeta, _mkTag("meta", "initial-creator"))
xMeta.text = self.theProject.data.author
xMeta = etree.SubElement(self._xMeta, _mkTag("meta", "editing-cycles"))
xMeta.text = str(self.theProject.data.saveCount)
# Format is: PnYnMnDTnHnMnS
# https://www.w3.org/TR/2004/REC-xmlschema-2-20041028/#duration
eT = self.theProject.data.editTime
xMeta = etree.SubElement(self._xMeta, _mkTag("meta", "editing-duration"))
xMeta.text = f"P{eT//86400:d}DT{eT%86400//3600:d}H{eT%3600//60:d}M{eT%60:d}S"
# Dublin Core Meta Data
xMeta = etree.SubElement(self._xMeta, _mkTag("dc", "title"))
xMeta.text = self.theProject.data.title or self.theProject.data.name
xMeta = etree.SubElement(self._xMeta, _mkTag("dc", "date"))
xMeta.text = timeStamp
xMeta = etree.SubElement(self._xMeta, _mkTag("dc", "creator"))
xMeta.text = self.theProject.data.author
self._pageStyles()
self._defaultStyles()
self._useableStyles()
@@ -408,7 +433,7 @@ class ToOdt(Tokenizer):
elif tType == self.T_TITLE:
tHead = tText.replace(r"\\", "\n")
self._addTextPar("Title", oStyle, tHead, isHead=True)
self._addTextPar("Title", oStyle, tHead, isHead=False) # Title must be text:p
elif tType == self.T_UNNUM:
tHead = tText.replace(r"\\", "\n")
@@ -503,9 +528,8 @@ class ToOdt(Tokenizer):
etree.SubElement(xMani, mFile, attrib={mPath: "styles.xml", mType: "text/xml"})
oRoot = _mkTag("office", "document-settings", nsMap=OFFICE_NS)
oSett = _mkTag("office", "settings", nsMap=OFFICE_NS)
xSett = etree.Element(oRoot, nsmap=OFFICE_NS)
etree.SubElement(xSett, oSett)
oVers = _mkTag("office", "version", nsMap=OFFICE_NS)
xSett = etree.Element(oRoot, nsmap=OFFICE_NS, attrib={oVers: X_VERS})
with ZipFile(savePath, mode="w") as outFile:
outFile.writestr("mimetype", X_MIME)

View File

@@ -7,7 +7,7 @@ File History:
Created: 2020-05-07 [0.4.5]
This file is a part of novelWriter
Copyright 2018–2022, Veronica Berglyd Olsen
Copyright 2018–2023, Veronica Berglyd Olsen
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@@ -9,7 +9,7 @@ Created: 2020-05-03 [0.4.5] QSwitch
Created: 2020-05-17 [0.5.1] PagedDialog
This file is a part of novelWriter
Copyright 2018–2022, Veronica Berglyd Olsen
Copyright 2018–2023, Veronica Berglyd Olsen
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@@ -1,46 +1,3 @@
"""
novelWriter – Dialogs Init
==========================
This file is a part of novelWriter
Copyright 2018–2022, Veronica Berglyd Olsen
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
novelWriter – Dialogs Init File
"""
from novelwriter.dialogs.about import GuiAbout
from novelwriter.dialogs.docmerge import GuiDocMerge
from novelwriter.dialogs.docsplit import GuiDocSplit
from novelwriter.dialogs.editlabel import GuiEditLabel
from novelwriter.dialogs.preferences import GuiPreferences
from novelwriter.dialogs.projdetails import GuiProjectDetails
from novelwriter.dialogs.projload import GuiProjectLoad
from novelwriter.dialogs.projsettings import GuiProjectSettings
from novelwriter.dialogs.quotes import GuiQuoteSelect
from novelwriter.dialogs.updates import GuiUpdates
from novelwriter.dialogs.wordlist import GuiWordList
__all__ = [
"GuiAbout",
"GuiDocMerge",
"GuiDocSplit",
"GuiEditLabel",
"GuiPreferences",
"GuiProjectDetails",
"GuiProjectLoad",
"GuiProjectSettings",
"GuiQuoteSelect",
"GuiUpdates",
"GuiWordList",
]

View File

@@ -7,7 +7,7 @@ File History:
Created: 2020-05-21 [0.5.2]
This file is a part of novelWriter
Copyright 2018–2022, Veronica Berglyd Olsen
Copyright 2018–2023, Veronica Berglyd Olsen
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -85,6 +85,10 @@ class GuiAbout(QDialog):
self.pageNotes.setOpenExternalLinks(True)
self.pageNotes.document().setDocumentMargin(self.mainConf.pxInt(16))
self.pageCredits = QTextBrowser()
self.pageCredits.setOpenExternalLinks(True)
self.pageCredits.document().setDocumentMargin(self.mainConf.pxInt(16))
self.pageLicense = QTextBrowser()
self.pageLicense.setOpenExternalLinks(True)
self.pageLicense.document().setDocumentMargin(self.mainConf.pxInt(16))
@@ -93,6 +97,7 @@ class GuiAbout(QDialog):
self.tabBox = QTabWidget()
self.tabBox.addTab(self.pageAbout, self.tr("About"))
self.tabBox.addTab(self.pageNotes, self.tr("Release"))
self.tabBox.addTab(self.pageCredits, self.tr("Credits"))
self.tabBox.addTab(self.pageLicense, self.tr("Licence"))
self.innerBox.addWidget(self.tabBox)
@@ -115,6 +120,7 @@ class GuiAbout(QDialog):
self._setStyleSheet()
self._fillAboutPage()
self._fillNotesPage()
self._fillCreditsPage()
self._fillLicensePage()
qApp.restoreOverrideCursor()
return
@@ -140,20 +146,12 @@ class GuiAbout(QDialog):
"<p>{license1}</p>"
"<p>{license2}</p>"
"<p>{license3}</p>"
"<h3>{title2}</h3>"
"<p>{credits}</p>"
).format(
title1=self.tr("About novelWriter"),
copy=novelwriter.__copyright__,
link=self.tr("Website: {0}").format(
f"<a href='{novelwriter.__url__}'>{novelwriter.__domain__}</a>"
),
title2=self.tr("Credits"),
credits=self._wrapTable([
(self.tr("Developer"), "Veronica Berglyd Olsen"),
(self.tr("Concept"), "Veronica Berglyd Olsen, Marian Lückhof"),
(self.tr("i18n"), "Bruno Meneguello"),
]),
intro=self.tr(
"novelWriter is a markdown-like text editor designed for organising and "
"writing novels. It is written in Python 3 with a Qt5 GUI, using PyQt5."
@@ -177,55 +175,6 @@ class GuiAbout(QDialog):
),
)
aboutMsg += "<h4>{0}</h4><p>{1}</p>".format(
self.tr("Translations"),
self._wrapTable([
("Deutsch", "Myian"),
("English", "Veronica Berglyd Olsen"),
("Español Latinoamericano", "Tommy Marplatt"),
("Français", "Jan Lüdke (jyhelle)"),
("Nederlands", "Martijn van der Kleijn"),
("Norsk Bokmål", "Veronica Berglyd Olsen"),
("Português", "Bruno Meneguello"),
("简体中文", "Qianzhi Long"),
])
)
mainTheme = self.mainGui.mainTheme
iconCache = self.mainGui.mainTheme.iconCache
if mainTheme.themeName and mainTheme.themeAuthor != "N/A":
licURL = f"<a href='{mainTheme.themeLicenseUrl}'>{mainTheme.themeLicense}</a>"
aboutMsg += "<h4>{0}</h4><p>{1}</p>".format(
self.tr("Theme: {0}").format(mainTheme.themeName),
self._wrapTable([
(self.tr("Author"), mainTheme.themeAuthor),
(self.tr("Credit"), mainTheme.themeCredit),
(self.tr("Licence"), licURL),
])
)
if iconCache.themeName:
licURL = f"<a href='{iconCache.themeLicenseUrl}'>{iconCache.themeLicense}</a>"
aboutMsg += "<h4>{0}</h4><p>{1}</p>".format(
self.tr("Icons: {0}").format(iconCache.themeName),
self._wrapTable([
(self.tr("Author"), iconCache.themeAuthor),
(self.tr("Credit"), iconCache.themeCredit),
(self.tr("Licence"), licURL),
])
)
if mainTheme.syntaxName:
licURL = f"<a href='{mainTheme.syntaxLicenseUrl}'>{mainTheme.syntaxLicense}</a>"
aboutMsg += "<h4>{0}</h4><p>{1}</p>".format(
self.tr("Syntax: {0}").format(mainTheme.syntaxName),
self._wrapTable([
(self.tr("Author"), mainTheme.syntaxAuthor),
(self.tr("Credit"), mainTheme.syntaxCredit),
(self.tr("Licence"), licURL),
])
)
self.pageAbout.setHtml(aboutMsg)
return
@@ -241,6 +190,17 @@ class GuiAbout(QDialog):
self.pageNotes.setHtml("Error loading release notes text ...")
return
def _fillCreditsPage(self):
"""Load the content for the Credits page.
"""
docPath = self.mainConf.assetPath("text") / "credits_en.htm"
docText = readTextFile(docPath)
if docText:
self.pageCredits.setHtml(docText)
else:
self.pageCredits.setHtml("Error loading credits text ...")
return
def _fillLicensePage(self):
"""Load the content for the Licence page.
"""
@@ -252,16 +212,6 @@ class GuiAbout(QDialog):
self.pageLicense.setHtml("Error loading licence text ...")
return
def _wrapTable(self, theData):
"""Wrap a list of label/value tuples in an html table.
"""
theTable = []
for aLabel, aValue in theData:
theTable.append(
f"<tr><td><b>{aLabel}:</b></td><td>{aValue}</td></tr>"
)
return "<table>{0}</table>".format("".join(theTable))
def _setStyleSheet(self):
"""Set stylesheet for all browser tabs
"""
@@ -275,9 +225,6 @@ class GuiAbout(QDialog):
".alt {{"
" color: rgb({kColR},{kColG},{kColB});"
"}}\n"
"td {{"
" padding-right: 0.8em;"
"}}\n"
).format(
hColR=self.mainGui.mainTheme.colHead[0],
hColG=self.mainGui.mainTheme.colHead[1],
@@ -288,6 +235,7 @@ class GuiAbout(QDialog):
)
self.pageAbout.document().setDefaultStyleSheet(styleSheet)
self.pageNotes.document().setDefaultStyleSheet(styleSheet)
self.pageCredits.document().setDefaultStyleSheet(styleSheet)
self.pageLicense.document().setDefaultStyleSheet(styleSheet)
return

View File

@@ -8,7 +8,7 @@ Created: 2020-01-23 [0.4.3]
Rewritten: 2022-10-06 [2.0rc1]
This file is a part of novelWriter
Copyright 2018–2022, Veronica Berglyd Olsen
Copyright 2018–2023, Veronica Berglyd Olsen
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@@ -8,7 +8,7 @@ Created: 2020-02-01 [0.4.3]
Rewritten: 2022-10-12 [2.0rc1]
This file is a part of novelWriter
Copyright 2018–2022, Veronica Berglyd Olsen
Copyright 2018–2023, Veronica Berglyd Olsen
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@@ -7,7 +7,7 @@ File History:
Created: 2022-06-11 [2.0rc1]
This file is a part of novelWriter
Copyright 2018–2022, Veronica Berglyd Olsen
Copyright 2018–2023, Veronica Berglyd Olsen
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@@ -7,7 +7,7 @@ File History:
Created: 2019-06-10 [0.1.5]
This file is a part of novelWriter
Copyright 2018–2022, Veronica Berglyd Olsen
Copyright 2018–2023, Veronica Berglyd Olsen
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -826,6 +826,7 @@ class GuiPreferencesSyntax(QWidget):
super().__init__(parent=prefsGui)
self.mainConf = novelwriter.CONFIG
self.prefsGui = prefsGui
self.mainGui = prefsGui.mainGui
self.mainTheme = prefsGui.mainGui.mainTheme
@@ -893,16 +894,21 @@ class GuiPreferencesSyntax(QWidget):
def saveValues(self):
"""Save the values set for this tab.
"""
# Quotes & Dialogue
self.mainConf.highlightQuotes = self.highlightQuotes.isChecked()
self.mainConf.allowOpenSQuote = self.allowOpenSQuote.isChecked()
self.mainConf.allowOpenDQuote = self.allowOpenDQuote.isChecked()
highlightQuotes = self.highlightQuotes.isChecked()
allowOpenSQuote = self.allowOpenSQuote.isChecked()
allowOpenDQuote = self.allowOpenDQuote.isChecked()
highlightEmph = self.highlightEmph.isChecked()
showMultiSpaces = self.showMultiSpaces.isChecked()
# Text Emphasis
self.mainConf.highlightEmph = self.highlightEmph.isChecked()
self.prefsGui._updateSyntax |= self.mainConf.highlightQuotes != highlightQuotes
self.prefsGui._updateSyntax |= self.mainConf.highlightEmph != highlightEmph
self.prefsGui._updateSyntax |= self.mainConf.showMultiSpaces != showMultiSpaces
# Text Errors
self.mainConf.showMultiSpaces = self.showMultiSpaces.isChecked()
self.mainConf.highlightQuotes = highlightQuotes
self.mainConf.allowOpenSQuote = allowOpenSQuote
self.mainConf.allowOpenDQuote = allowOpenDQuote
self.mainConf.highlightEmph = highlightEmph
self.mainConf.showMultiSpaces = showMultiSpaces
return

View File

@@ -7,7 +7,7 @@ File History:
Created: 2021-01-03 [1.1rc1]
This file is a part of novelWriter
Copyright 2018–2022, Veronica Berglyd Olsen
Copyright 2018–2023, Veronica Berglyd Olsen
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -34,7 +34,7 @@ from PyQt5.QtWidgets import (
QLineEdit, QSpinBox, QTreeWidget, QTreeWidgetItem, QVBoxLayout, QWidget
)
from novelwriter.common import numberToRoman
from novelwriter.common import formatTime, numberToRoman
from novelwriter.custom import PagedDialog, QSwitch
from novelwriter.constants import nwUnicode
from novelwriter.gui.components import NovelSelector
@@ -156,7 +156,7 @@ class GuiProjectDetailsMain(QWidget):
# Header
# ======
self.bookTitle = QLabel(self.theProject.data.title)
self.bookTitle = QLabel("")
bookFont = self.bookTitle.font()
bookFont.setPointSizeF(2.2*fPt)
bookFont.setWeight(QFont.Bold)
@@ -164,9 +164,7 @@ class GuiProjectDetailsMain(QWidget):
self.bookTitle.setAlignment(Qt.AlignHCenter)
self.bookTitle.setWordWrap(True)
self.projName = QLabel(
self.tr("Working Title: {0}").format(self.theProject.data.name)
)
self.projName = QLabel("")
workFont = self.projName.font()
workFont.setPointSizeF(0.8*fPt)
workFont.setItalic(True)
@@ -174,7 +172,7 @@ class GuiProjectDetailsMain(QWidget):
self.projName.setAlignment(Qt.AlignHCenter)
self.projName.setWordWrap(True)
self.bookAuthors = QLabel(self.tr("By {0}").format(self.theProject.data.author))
self.bookAuthors = QLabel("")
authFont = self.bookAuthors.font()
authFont.setPointSizeF(1.2*fPt)
self.bookAuthors.setFont(authFont)
@@ -251,11 +249,15 @@ class GuiProjectDetailsMain(QWidget):
nwCount = pIndex.getNovelWordCount()
edTime = self.theProject.getCurrentEditTime()
self.bookTitle.setText(self.theProject.data.title or self.theProject.data.name)
self.projName.setText(self.tr("Project: {0}").format(self.theProject.data.name))
self.bookAuthors.setText(self.tr("By {0}").format(self.theProject.data.author))
self.wordCountVal.setText(f"{nwCount:n}")
self.chapCountVal.setText(f"{hCounts[2]:n}")
self.sceneCountVal.setText(f"{hCounts[3]:n}")
self.revCountVal.setText(f"{self.theProject.data.saveCount:n}")
self.editTimeVal.setText(f"{edTime//3600:02d}:{edTime%3600//60:02d}")
self.editTimeVal.setText(formatTime(edTime))
self.projPathVal.setText(str(self.theProject.storage.storagePath))

View File

@@ -7,7 +7,7 @@ File History:
Created: 2020-02-26 [0.4.5]
This file is a part of novelWriter
Copyright 2018–2022, Veronica Berglyd Olsen
Copyright 2018–2023, Veronica Berglyd Olsen
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@@ -7,7 +7,7 @@ File History:
Created: 2018-09-29 [0.0.1]
This file is a part of novelWriter
Copyright 2018–2022, Veronica Berglyd Olsen
Copyright 2018–2023, Veronica Berglyd Olsen
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -26,8 +26,8 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
import logging
import novelwriter
from PyQt5.QtGui import QIcon, QPixmap, QColor, QBrush
from PyQt5.QtCore import Qt, QLocale
from PyQt5.QtGui import QIcon, QPixmap, QColor
from PyQt5.QtCore import Qt, QLocale, pyqtSlot
from PyQt5.QtWidgets import (
QColorDialog, QComboBox, QDialogButtonBox, QHBoxLayout, QLabel, QLineEdit,
QPushButton, QTreeWidget, QTreeWidgetItem, QVBoxLayout, QWidget
@@ -300,7 +300,7 @@ class GuiProjectEditStatus(QWidget):
self.colDeleted = []
self.colChanged = False
self.selColour = QColor(100, 100, 100)
self.selColour = QColor(100, 100, 100)
self.iPx = self.mainTheme.baseIconSize
@@ -338,16 +338,18 @@ class GuiProjectEditStatus(QWidget):
self.editName = QLineEdit()
self.editName.setMaxLength(40)
self.editName.setEnabled(False)
self.editName.setPlaceholderText(self.tr("Select item to edit"))
self.editName.setEnabled(False)
self.colPixmap = QPixmap(self.iPx, self.iPx)
self.colPixmap.fill(QColor(100, 100, 100))
self.colButton = QPushButton(QIcon(self.colPixmap), self.tr("Colour"))
self.colButton.setIconSize(self.colPixmap.rect().size())
self.colButton.setEnabled(False)
self.colButton.clicked.connect(self._selectColour)
self.saveButton = QPushButton(self.tr("Save"))
self.saveButton.setEnabled(False)
self.saveButton.clicked.connect(self._saveItem)
# Assemble
@@ -399,9 +401,10 @@ class GuiProjectEditStatus(QWidget):
return [], []
##
# User Actions
# Private Slots
##
@pyqtSlot()
def _selectColour(self):
"""Open a dialog to select the status icon colour.
"""
@@ -417,20 +420,20 @@ class GuiProjectEditStatus(QWidget):
self.colButton.setIconSize(pixmap.rect().size())
return
@pyqtSlot()
def _newItem(self):
"""Create a new status item.
"""
newItem = self._addItem(None, self.tr("New Item"), (100, 100, 100), 0)
newItem.setBackground(self.COL_LABEL, QBrush(QColor(0, 255, 0, 70)))
newItem.setBackground(self.COL_USAGE, QBrush(QColor(0, 255, 0, 70)))
self._addItem(None, self.tr("New Item"), (100, 100, 100), 0)
self.colChanged = True
return
@pyqtSlot()
def _delItem(self):
"""Delete a status item.
"""
selItem = self._getSelectedItem()
if selItem is not None:
if isinstance(selItem, QTreeWidgetItem):
iRow = self.listBox.indexOfTopLevelItem(selItem)
if selItem.data(self.COL_LABEL, self.NUM_ROLE) > 0:
self.mainGui.makeAlert(self.tr(
@@ -442,21 +445,60 @@ class GuiProjectEditStatus(QWidget):
self.colChanged = True
return
@pyqtSlot()
def _saveItem(self):
"""Save changes made to a status item.
"""
selItem = self._getSelectedItem()
if selItem is not None:
if isinstance(selItem, QTreeWidgetItem):
selItem.setText(self.COL_LABEL, simplified(self.editName.text()))
selItem.setIcon(self.COL_LABEL, self.colButton.icon())
selItem.setData(self.COL_LABEL, self.COL_ROLE, (
self.selColour.red(), self.selColour.green(), self.selColour.blue()
))
self.editName.setEnabled(False)
self.colChanged = True
return
@pyqtSlot()
def _selectedItem(self):
"""Extract the info of a selected item and populate the settings
boxes and button. If no item is selected, clear the form.
"""
selItem = self._getSelectedItem()
if isinstance(selItem, QTreeWidgetItem):
cols = selItem.data(self.COL_LABEL, self.COL_ROLE)
name = selItem.text(self.COL_LABEL)
pixmap = QPixmap(self.iPx, self.iPx)
pixmap.fill(QColor(*cols))
self.selColour = QColor(*cols)
self.editName.setText(name)
self.colButton.setIcon(QIcon(pixmap))
self.editName.selectAll()
self.editName.setFocus()
self.editName.setEnabled(True)
self.colButton.setEnabled(True)
self.saveButton.setEnabled(True)
else:
pixmap = QPixmap(self.iPx, self.iPx)
pixmap.fill(QColor(100, 100, 100))
self.selColour = QColor(100, 100, 100)
self.editName.setText("")
self.colButton.setIcon(QIcon(pixmap))
self.editName.setEnabled(False)
self.colButton.setEnabled(False)
self.saveButton.setEnabled(False)
return
##
# Internal Functions
##
def _addItem(self, key, name, cols, count):
"""Add a status item to the list.
"""
@@ -473,7 +515,7 @@ class GuiProjectEditStatus(QWidget):
self.listBox.addTopLevelItem(item)
return item
return
def _moveItem(self, step):
"""Move and item up or down step.
@@ -498,32 +540,6 @@ class GuiProjectEditStatus(QWidget):
return
def _selectedItem(self):
"""Extract the info of a selected item and populate the settings
boxes and button.
"""
selItem = self._getSelectedItem()
if selItem is None:
return
cols = selItem.data(self.COL_LABEL, self.COL_ROLE)
name = selItem.text(self.COL_LABEL)
pixmap = QPixmap(self.iPx, self.iPx)
pixmap.fill(QColor(*cols))
self.selColour = QColor(*cols)
self.editName.setText(name)
self.colButton.setIcon(QIcon(pixmap))
self.editName.setEnabled(True)
self.editName.selectAll()
self.editName.setFocus()
return
##
# Internal Functions
##
def _getSelectedItem(self):
"""Get the currently selected item.
"""

View File

@@ -7,7 +7,7 @@ File History:
Created: 2020-06-18 [0.9]
This file is a part of novelWriter
Copyright 2018–2022, Veronica Berglyd Olsen
Copyright 2018–2023, Veronica Berglyd Olsen
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@@ -7,7 +7,7 @@ File History:
Created: 2021-08-21 [1.5b1]
This file is a part of novelWriter
Copyright 2018–2022, Veronica Berglyd Olsen
Copyright 2018–2023, Veronica Berglyd Olsen
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@@ -7,7 +7,7 @@ File History:
Created: 2021-02-12 [1.2rc1]
This file is a part of novelWriter
Copyright 2018–2022, Veronica Berglyd Olsen
Copyright 2018–2023, Veronica Berglyd Olsen
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@@ -7,7 +7,7 @@ File History:
Created: 2018-11-02 [0.0.1]
This file is a part of novelWriter
Copyright 2018–2022, Veronica Berglyd Olsen
Copyright 2018–2023, Veronica Berglyd Olsen
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@@ -7,7 +7,7 @@ File History:
Created: 2020-08-02 [0.10.2]
This file is a part of novelWriter
Copyright 2018–2022, Veronica Berglyd Olsen
Copyright 2018–2023, Veronica Berglyd Olsen
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -112,8 +112,7 @@ class NWErrorMessage(QDialog):
"""
from traceback import format_tb
from novelwriter import __issuesurl__, __version__
from PyQt5.Qt import PYQT_VERSION_STR
from PyQt5.QtCore import QT_VERSION_STR, QSysInfo
from PyQt5.QtCore import QT_VERSION_STR, PYQT_VERSION_STR, QSysInfo
self.msgHead.setText((
"<p>An unhandled error has been encountered.</p>"

View File

@@ -1,45 +1,3 @@
"""
novelWriter – GUI Init
======================
This file is a part of novelWriter
Copyright 2018–2022, Veronica Berglyd Olsen
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
novelWriter – GUI Init File
"""
from novelwriter.gui.doceditor import GuiDocEditor
from novelwriter.gui.docviewer import GuiDocViewer, GuiDocViewDetails
from novelwriter.gui.itemdetails import GuiItemDetails
from novelwriter.gui.mainmenu import GuiMainMenu
from novelwriter.gui.noveltree import GuiNovelView
from novelwriter.gui.outline import GuiOutlineView
from novelwriter.gui.projtree import GuiProjectView
from novelwriter.gui.statusbar import GuiMainStatus
from novelwriter.gui.theme import GuiTheme
from novelwriter.gui.sidebar import GuiSideBar
__all__ = [
"GuiDocEditor",
"GuiDocViewDetails",
"GuiDocViewer",
"GuiItemDetails",
"GuiMainMenu",
"GuiMainStatus",
"GuiNovelView",
"GuiOutlineView",
"GuiProjectView",
"GuiTheme",
"GuiSideBar",
]

View File

@@ -8,7 +8,7 @@ Created: 2020-05-17 [0.5.1] StatusLED
Created: 2022-11-17 [2.0] NovelSelector
This file is a part of novelWriter
Copyright 2018–2022, Veronica Berglyd Olsen
Copyright 2018–2023, Veronica Berglyd Olsen
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@@ -13,7 +13,7 @@ Created: 2020-06-27 [0.10] GuiDocEditFooter
Rewritten: 2020-10-07 [1.0b3] BackgroundWordCounter
This file is a part of novelWriter
Copyright 2018–2022, Veronica Berglyd Olsen
Copyright 2018–2023, Veronica Berglyd Olsen
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -50,10 +50,11 @@ from PyQt5.QtWidgets import (
QFrame
)
from novelwriter.core import NWSpellEnchant, countWords
from novelwriter.enum import nwAlert, nwDocAction, nwDocInsert, nwDocMode, nwItemClass
from novelwriter.common import minmax, transferCase
from novelwriter.constants import nwConst, nwFiles, nwKeyWords, nwUnicode
from novelwriter.core.index import countWords
from novelwriter.core.spellcheck import NWSpellEnchant
from novelwriter.gui.dochighlight import GuiDocHighlighter
logger = logging.getLogger(__name__)
@@ -1749,6 +1750,7 @@ class GuiDocEditor(QTextEdit):
# Remove existing format first, if any
theText = theBlock.text()
hasText = len(theText) > 0
if theText.startswith("@"):
logger.error("Cannot apply block format to keyword/value line")
return False
@@ -1854,11 +1856,17 @@ class GuiDocEditor(QTextEdit):
posS = theCursor.selectionStart()
theCursor.removeSelectedText()
theCursor.setPosition(posS)
if posS > 0:
if posS > 0 and hasText:
# If the block already had text, we must insert a new block
# first before we can add back the text to it.
theCursor.insertBlock()
theCursor.insertText(theText)
if posO - cOffset >= 0:
theCursor.setPosition(posO - cOffset)
theCursor.endEditBlock()
self.setTextCursor(theCursor)
@@ -2511,7 +2519,7 @@ class GuiDocEditSearch(QFrame):
# Using the Unicode-capable QRegularExpression class was
# only added in Qt 5.13. Otherwise, 5.3 and up supports
# only the QRegExp class.
if self.mainConf.verQtValue >= 51300:
if self.mainConf.verQtValue >= 0x050d00:
rxOpt = QRegularExpression.UseUnicodePropertiesOption
if not self.isCaseSense:
rxOpt |= QRegularExpression.CaseInsensitiveOption

View File

@@ -7,7 +7,7 @@ File History:
Created: 2019-04-06 [0.0.1]
This file is a part of novelWriter
Copyright 2018–2022, Veronica Berglyd Olsen
Copyright 2018–2023, Veronica Berglyd Olsen
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -33,8 +33,8 @@ from PyQt5.QtGui import (
QColor, QTextCharFormat, QFont, QSyntaxHighlighter, QBrush
)
from novelwriter.constants import nwRegEx, nwUnicode
from novelwriter.common import checkInt
from novelwriter.constants import nwRegEx, nwUnicode
logger = logging.getLogger(__name__)

View File

@@ -11,7 +11,7 @@ Created: 2020-06-09 [0.8] GuiDocViewFooter
Created: 2020-09-08 [1.0b1] GuiDocViewHistory
This file is a part of novelWriter
Copyright 2018–2022, Veronica Berglyd Olsen
Copyright 2018–2023, Veronica Berglyd Olsen
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -41,10 +41,10 @@ from PyQt5.QtWidgets import (
QAction, QMenu, QFrame
)
from novelwriter.core import ToHtml
from novelwriter.enum import nwItemType, nwDocAction, nwDocMode
from novelwriter.error import logException
from novelwriter.constants import nwUnicode
from novelwriter.core.tohtml import ToHtml
logger = logging.getLogger(__name__)

View File

@@ -7,7 +7,7 @@ File History:
Created: 2019-04-24 [0.0.1]
This file is a part of novelWriter
Copyright 2018–2022, Veronica Berglyd Olsen
Copyright 2018–2023, Veronica Berglyd Olsen
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@@ -7,7 +7,7 @@ File History:
Created: 2019-04-27 [0.0.1]
This file is a part of novelWriter
Copyright 2018–2022, Veronica Berglyd Olsen
Copyright 2018–2023, Veronica Berglyd Olsen
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@@ -34,12 +34,13 @@ from time import time
from PyQt5.QtGui import QFont, QPalette
from PyQt5.QtCore import Qt, QSize, pyqtSlot, pyqtSignal
from PyQt5.QtWidgets import (
QAbstractItemView, QActionGroup, QFrame, QHBoxLayout, QHeaderView, QMenu,
QSizePolicy, QToolButton, QToolTip, QTreeWidget, QTreeWidgetItem,
QVBoxLayout, QWidget
QAbstractItemView, QActionGroup, QFrame, QHBoxLayout, QHeaderView,
QInputDialog, QMenu, QSizePolicy, QToolButton, QToolTip, QTreeWidget,
QTreeWidgetItem, QVBoxLayout, QWidget
)
from novelwriter.enum import nwDocMode, nwItemClass, nwOutline
from novelwriter.common import minmax
from novelwriter.constants import nwHeaders, nwKeyWords, nwLabels, trConst
from novelwriter.gui.components import NovelSelector
@@ -126,20 +127,28 @@ class GuiNovelView(QWidget):
lastCol = self.theProject.options.getEnum(
"GuiNovelView", "lastCol", NovelTreeColumn, NovelTreeColumn.HIDDEN
)
lastColSize = self.theProject.options.getInt(
"GuiNovelView", "lastColSize", 25
)
self.clearProject()
self.novelBar.buildNovelRootMenu()
self.novelBar.setLastColType(lastCol, doRefresh=False)
self.novelBar.setCurrentRoot(lastNovel)
self.novelBar.setEnabled(True)
self.novelTree.setLastColSize(lastColSize)
return
def closeProjectTasks(self):
"""Run closing project tasks.
"""
lastColType = self.novelTree.lastColType
lastColSize = self.novelTree.lastColSize
self.theProject.options.setValue("GuiNovelView", "lastCol", lastColType)
self.theProject.options.setValue("GuiNovelView", "lastColSize", lastColSize)
return
def setTreeFocus(self):
@@ -233,6 +242,10 @@ class GuiNovelToolBar(QWidget):
self._addLastColAction(NovelTreeColumn.FOCUS, self.tr("Focus Character"))
self._addLastColAction(NovelTreeColumn.PLOT, self.tr("Novel Plot"))
self.mLastCol.addSeparator()
self.aLastColSize = self.mLastCol.addAction(self.tr("Column Size"))
self.aLastColSize.triggered.connect(self._selectLastColumnSize)
self.tbMore = QToolButton(self)
self.tbMore.setToolTip(self.tr("More Options"))
self.tbMore.setIconSize(QSize(iPx, iPx))
@@ -339,6 +352,19 @@ class GuiNovelToolBar(QWidget):
self.novelView.novelTree.refreshTree(rootHandle=rootHandle, overRide=True)
return
@pyqtSlot()
def _selectLastColumnSize(self):
"""Set the maximum width for the last column.
"""
oldSize = self.novelView.novelTree.lastColSize
newSize, isOk = QInputDialog.getInt(
self, self.tr("Column Size"), self.tr("Maximum column size in %"), oldSize, 15, 75, 5
)
if isOk:
self.novelView.novelTree.setLastColSize(newSize)
self._refreshNovelTree()
return
##
# Internal Functions
##
@@ -379,10 +405,11 @@ class GuiNovelTree(QTreeWidget):
self.theProject = novelView.mainGui.theProject
# Internal Variables
self._treeMap = {}
self._lastBuild = 0
self._lastCol = NovelTreeColumn.POV
self._actHandle = None
self._treeMap = {}
self._lastBuild = 0
self._lastCol = NovelTreeColumn.POV
self._lastColSize = 0.25
self._actHandle = None
# Cached Strings
self._povLabel = trConst(nwLabels.KEY_NAME[nwKeyWords.POV_KEY])
@@ -470,6 +497,10 @@ class GuiNovelTree(QTreeWidget):
def lastColType(self):
return self._lastCol
@property
def lastColSize(self):
return int(self._lastColSize * 100)
##
# Class Methods
##
@@ -552,6 +583,12 @@ class GuiNovelTree(QTreeWidget):
self.refreshTree(rootHandle=lastNovel, overRide=True)
return
def setLastColSize(self, colSize):
"""Set the column size in integer values between 15 and 75.
"""
self._lastColSize = minmax(colSize, 15, 75)/100.0
return
def setActiveHandle(self, tHandle):
"""Highlight the rows associated with a given handle.
"""
@@ -619,7 +656,7 @@ class GuiNovelTree(QTreeWidget):
newW = event.size().width()
oldW = event.oldSize().width()
if newW != oldW:
eliW = int(0.25 * newW)
eliW = int(self._lastColSize * newW)
fMetric = self.fontMetrics()
for i in range(self.topLevelItemCount()):
trItem = self.topLevelItem(i)
@@ -709,7 +746,7 @@ class GuiNovelTree(QTreeWidget):
trItem.setData(self.C_MORE, Qt.DecorationRole, self._pMore)
# Custom column
mW = int(0.25 * self.viewport().width())
mW = int(self._lastColSize * self.viewport().width())
lastText, toolTip = self._getLastColumnText(tHandle, sTitle)
elideText = self.fontMetrics().elidedText(lastText, Qt.ElideRight, mW)
trItem.setText(self.C_EXTRA, elideText)
@@ -741,7 +778,7 @@ class GuiNovelTree(QTreeWidget):
if refData:
toolText = ", ".join(refData)
return refData[0], f"{refName}: {toolText}"
return toolText, f"{refName}: {toolText}"
return "", ""

View File

@@ -11,7 +11,7 @@ Created: 2019-11-16 [0.4.1] GuiOutlineHeaderMenu
Created: 2020-06-02 [0.7] GuiOutlineDetails
This file is a part of novelWriter
Copyright 2018–2022, Veronica Berglyd Olsen
Copyright 2018–2023, Veronica Berglyd Olsen
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@@ -9,7 +9,7 @@ Created: 2022-06-06 [2.0rc1] GuiProjectView
Created: 2022-06-06 [2.0rc1] GuiProjectToolBar
This file is a part of novelWriter
Copyright 2018–2022, Veronica Berglyd Olsen
Copyright 2018–2023, Veronica Berglyd Olsen
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -39,10 +39,13 @@ from PyQt5.QtWidgets import (
QVBoxLayout, QWidget
)
from novelwriter.core import DocMerger, DocSplitter
from novelwriter.enum import nwDocMode, nwItemType, nwItemClass, nwItemLayout, nwAlert
from novelwriter.dialogs import GuiDocMerge, GuiDocSplit, GuiEditLabel, GuiProjectSettings
from novelwriter.constants import nwHeaders, nwUnicode, trConst, nwLabels
from novelwriter.core.coretools import DocMerger, DocSplitter
from novelwriter.dialogs.docmerge import GuiDocMerge
from novelwriter.dialogs.docsplit import GuiDocSplit
from novelwriter.dialogs.editlabel import GuiEditLabel
from novelwriter.dialogs.projsettings import GuiProjectSettings
logger = logging.getLogger(__name__)
@@ -1248,18 +1251,30 @@ class GuiProjectTree(QTreeWidget):
isDocFile = isFile and tItem.isDocumentLayout()
isNoteFile = isFile and tItem.isNoteLayout()
if (isNoteFile or isFolder) and tItem.documentAllowed():
if isNoteFile and tItem.documentAllowed():
aConvert1 = mTrans.addAction(self.tr("Convert to {0}").format(trDoc))
aConvert1.triggered.connect(
lambda: self._changeItemLayout(tHandle, nwItemLayout.DOCUMENT)
)
if isDocFile or isFolder:
if isDocFile:
aConvert2 = mTrans.addAction(self.tr("Convert to {0}").format(trNote))
aConvert2.triggered.connect(
lambda: self._changeItemLayout(tHandle, nwItemLayout.NOTE)
)
if isFolder and tItem.documentAllowed():
aConvert3 = mTrans.addAction(self.tr("Convert to {0}").format(trDoc))
aConvert3.triggered.connect(
lambda: self._covertFolderToFile(tHandle, nwItemLayout.DOCUMENT)
)
if isFolder:
aConvert4 = mTrans.addAction(self.tr("Convert to {0}").format(trNote))
aConvert4.triggered.connect(
lambda: self._covertFolderToFile(tHandle, nwItemLayout.NOTE)
)
if hasChild and isFile:
aMerge1 = mTrans.addAction(self.tr("Merge Child Items into Self"))
aMerge1.triggered.connect(lambda: self._mergeDocuments(tHandle, False))
@@ -1678,19 +1693,23 @@ class GuiProjectTree(QTreeWidget):
del self._treeMap[tHandle]
return None
else:
elif pHandle in self._treeMap:
byIndex = -1
if nHandle is not None and nHandle in self._treeMap:
try:
byIndex = self._treeMap[pHandle].indexOfChild(self._treeMap[nHandle])
except Exception:
logger.error("Failed to get index of item with handle '%s'", nHandle)
byIndex = self._treeMap[pHandle].indexOfChild(self._treeMap[nHandle])
if byIndex >= 0:
self._treeMap[pHandle].insertChild(byIndex + 1, newItem)
else:
self._treeMap[pHandle].addChild(newItem)
self.propagateCount(tHandle, nwItem.wordCount, countChildren=True)
else:
self.mainGui.makeAlert(self.tr(
"There is nowhere to add item with name '{0}'."
).format(nwItem.itemName), nwAlert.ERROR)
del self._treeMap[tHandle]
return None
self.setTreeItemValues(tHandle)
newItem.setExpanded(nwItem.isExpanded)

View File

@@ -7,7 +7,7 @@ File History:
Created: 2022-05-10 [2.0rc1]
This file is a part of novelWriter
Copyright 2018–2022, Veronica Berglyd Olsen
Copyright 2018–2023, Veronica Berglyd Olsen
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@@ -8,7 +8,7 @@ Created: 2019-04-20 [0.0.1] GuiMainStatus
Created: 2020-05-17 [0.5.1] StatusLED
This file is a part of novelWriter
Copyright 2018–2022, Veronica Berglyd Olsen
Copyright 2018–2023, Veronica Berglyd Olsen
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@@ -8,7 +8,7 @@ Created: 2019-05-18 [0.1.3] GuiTheme
Created: 2019-11-08 [0.4] GuiIcons
This file is a part of novelWriter
Copyright 2018–2022, Veronica Berglyd Olsen
Copyright 2018–2023, Veronica Berglyd Olsen
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -246,7 +246,7 @@ class GuiTheme:
self.statSaved = self._parseColour(confParser, cnfSec, "statussaved")
# Icons
self.iconCache.loadTheme(self.themeIcons)
self.iconCache.loadTheme(self.themeIcons or "typicons_light")
# Update Dependant Colours
backCol = self._guiPalette.window().color()
@@ -507,8 +507,10 @@ class GuiIcons:
self._themeMap = {}
themePath = self._iconPath / iconTheme
if not themePath.is_dir():
logger.warning("No icons loaded for '%s'", iconTheme)
return False
themePath = self.mainConf.dataPath("icons") / iconTheme
if not themePath.is_dir():
logger.warning("No icons loaded for '%s'", iconTheme)
return False
themeConf = themePath / self._confName
logger.info("Loading icon theme '%s'", iconTheme)

View File

@@ -7,7 +7,7 @@ File History:
Created: 2018-09-22 [0.0.1]
This file is a part of novelWriter
Copyright 2018–2022, Veronica Berglyd Olsen
Copyright 2018–2023, Veronica Berglyd Olsen
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -38,19 +38,30 @@ from PyQt5.QtWidgets import (
QMessageBox, QDialog, QStackedWidget
)
from novelwriter.gui import (
GuiDocEditor, GuiDocViewDetails, GuiDocViewer, GuiItemDetails, GuiMainMenu,
GuiMainStatus, GuiNovelView, GuiOutlineView, GuiProjectView, GuiTheme,
GuiSideBar
)
from novelwriter.dialogs import (
GuiAbout, GuiPreferences, GuiProjectDetails, GuiProjectLoad,
GuiProjectSettings, GuiUpdates, GuiWordList
)
from novelwriter.tools import (
GuiBuildNovel, GuiLipsum, GuiProjectWizard, GuiWritingStats
)
from novelwriter.core import NWProject, ProjectBuilder
from novelwriter.gui.theme import GuiTheme
from novelwriter.gui.sidebar import GuiSideBar
from novelwriter.gui.outline import GuiOutlineView
from novelwriter.gui.mainmenu import GuiMainMenu
from novelwriter.gui.projtree import GuiProjectView
from novelwriter.gui.doceditor import GuiDocEditor
from novelwriter.gui.docviewer import GuiDocViewDetails, GuiDocViewer
from novelwriter.gui.noveltree import GuiNovelView
from novelwriter.gui.statusbar import GuiMainStatus
from novelwriter.gui.itemdetails import GuiItemDetails
from novelwriter.dialogs.about import GuiAbout
from novelwriter.dialogs.updates import GuiUpdates
from novelwriter.dialogs.projload import GuiProjectLoad
from novelwriter.dialogs.wordlist import GuiWordList
from novelwriter.dialogs.preferences import GuiPreferences
from novelwriter.dialogs.projdetails import GuiProjectDetails
from novelwriter.dialogs.projsettings import GuiProjectSettings
from novelwriter.tools.build import GuiBuildNovel
from novelwriter.tools.lipsum import GuiLipsum
from novelwriter.tools.projwizard import GuiProjectWizard
from novelwriter.tools.writingstats import GuiWritingStats
from novelwriter.core.project import NWProject
from novelwriter.core.coretools import ProjectBuilder
from novelwriter.enum import (
nwDocMode, nwItemType, nwItemClass, nwAlert, nwWidget, nwView
)
@@ -76,9 +87,9 @@ class GuiMain(QMainWindow):
logger.info("OS: %s", self.mainConf.osType)
logger.info("Kernel: %s", self.mainConf.kernelVer)
logger.info("Host: %s", self.mainConf.hostName)
logger.info("Qt5: %s (%d)", self.mainConf.verQtString, self.mainConf.verQtValue)
logger.info("PyQt5: %s (%d)", self.mainConf.verPyQtString, self.mainConf.verPyQtValue)
logger.info("Python: %s (0x%x)", self.mainConf.verPyString, self.mainConf.verPyHexVal)
logger.info("Qt5: %s (0x%06x)", self.mainConf.verQtString, self.mainConf.verQtValue)
logger.info("PyQt5: %s (0x%06x)", self.mainConf.verPyQtString, self.mainConf.verPyQtValue)
logger.info("Python: %s (0x%08x)", self.mainConf.verPyString, self.mainConf.verPyHexVal)
logger.info("GUI Language: %s", self.mainConf.guiLocale)
# Core Classes
@@ -599,6 +610,7 @@ class GuiMain(QMainWindow):
logger.debug("Requested item '%s' is not a document", tHandle)
return False
self._changeView(nwView.EDITOR)
cHandle = self.docEditor.docHandle()
if cHandle == tHandle:
self.docEditor.setCursorLine(tLine)
@@ -607,7 +619,6 @@ class GuiMain(QMainWindow):
return True
self.closeDocument(beforeOpen=True)
self._changeView(nwView.EDITOR)
if self.docEditor.loadText(tHandle, tLine):
self.theProject.data.setLastHandle(tHandle, "editor")
self.projView.setSelectedHandle(tHandle, doScroll=doScroll)

View File

@@ -1,32 +1,3 @@
"""
novelWriter – Tools Init
========================
This file is a part of novelWriter
Copyright 2018–2022, Veronica Berglyd Olsen
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
novelWriter – Tools Init File
"""
from novelwriter.tools.build import GuiBuildNovel
from novelwriter.tools.lipsum import GuiLipsum
from novelwriter.tools.projwizard import GuiProjectWizard
from novelwriter.tools.writingstats import GuiWritingStats
__all__ = [
"GuiBuildNovel",
"GuiLipsum",
"GuiProjectWizard",
"GuiWritingStats",
]

View File

@@ -7,7 +7,7 @@ File History:
Created: 2020-05-09 [0.5]
This file is a part of novelWriter
Copyright 2018–2022, Veronica Berglyd Olsen
Copyright 2018–2023, Veronica Berglyd Olsen
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -43,12 +43,14 @@ from PyQt5.QtWidgets import (
)
from PyQt5.QtPrintSupport import QPrinter, QPrintPreviewDialog
from novelwriter.core import ToHtml, ToOdt, ToMarkdown
from novelwriter.enum import nwAlert, nwItemType, nwItemLayout, nwItemClass
from novelwriter.error import formatException, logException
from novelwriter.common import fuzzyTime, makeFileNameSafe
from novelwriter.custom import QSwitch
from novelwriter.constants import nwConst, nwFiles
from novelwriter.core.tomd import ToMarkdown
from novelwriter.core.toodt import ToOdt
from novelwriter.core.tohtml import ToHtml
logger = logging.getLogger(__name__)

View File

@@ -7,7 +7,7 @@ File History:
Created: 2022-04-02 [2.0rc1]
This file is a part of novelWriter
Copyright 2018–2022, Veronica Berglyd Olsen
Copyright 2018–2023, Veronica Berglyd Olsen
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@@ -7,7 +7,7 @@ File History:
Created: 2020-07-11 [0.10.1]
This file is a part of novelWriter
Copyright 2018–2022, Veronica Berglyd Olsen
Copyright 2018–2023, Veronica Berglyd Olsen
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@@ -7,7 +7,7 @@ File History:
Created: 2019-10-20 [0.3]
This file is a part of novelWriter
Copyright 2018–2022, Veronica Berglyd Olsen
Copyright 2018–2023, Veronica Berglyd Olsen
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@@ -1,6 +1,6 @@
<?xml version='1.0' encoding='utf-8'?>
<novelWriterXML appVersion="2.0" hexVersion="0x020000f0" fileVersion="1.5" timeStamp="2022-11-28 17:12:35">
<project id="e2be99af-f9bf-4403-857a-c3d1ac25abea" saveCount="1458" autoCount="237" editTime="74191">
<novelWriterXML appVersion="2.0.5" hexVersion="0x020005f0" fileVersion="1.5" timeStamp="2023-02-12 16:02:30">
<project id="e2be99af-f9bf-4403-857a-c3d1ac25abea" saveCount="1471" autoCount="237" editTime="74437">
<name>Sample Project</name>
<title>Sample Project</title>
<author>Jane Smith</author>

View File

@@ -8,7 +8,7 @@ File History:
Created: 2019-05-16 [0.5.1]
This file is a part of novelWriter
Copyright 2018–2022, Veronica Berglyd Olsen
Copyright 2018–2023, Veronica Berglyd Olsen
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -396,6 +396,36 @@ def buildQtI18nTS(sysArgs):
return
##
# Generage MacOS PList
##
def genMacOSPlist():
"""Set necessary values for .plist file.
"""
numVers, _, _ = extractVersion()
pkgVers = compactVersion(numVers)
outDir = "setup/macos"
copyrightYear = datetime.datetime.now().year
# These keys are no longer used but are present for compatability
pkgVersMaj, pkgVersMin, _ = pkgVers.split(".")
plistXML = readFile(f"{outDir}/Info.plist.template").format(
macosBundleSVers=pkgVers,
macosBundleVers=numVers,
macosBundleVersMajor=pkgVersMaj,
macosBundleVersMinor=pkgVersMin,
macosBundleCopyright=f"Copyright 2018–{copyrightYear}, Veronica Berglyd Olsen",
)
print(f"Writing Info.plist to {outDir}/Info.plist")
writeFile(f"{outDir}/Info.plist", plistXML)
return
##
# Sample Project ZIP File Builder (sample)
##
@@ -835,7 +865,7 @@ def makeDebianPackage(signKey=None, sourceBuild=False, distName="unstable", buil
##
def makeForLaunchpad(doSign=False, isFirst=False, isSnapshot=False):
"""Wrapper for building debian packages for launcpad.
"""Wrapper for building debian packages for launchpad.
"""
print("")
print("Launchpad Packages")
@@ -853,6 +883,7 @@ def makeForLaunchpad(doSign=False, isFirst=False, isSnapshot=False):
("20.04", "focal"),
("22.04", "jammy"),
("22.10", "kinetic"),
("23.04", "lunar"),
]
tStamp = datetime.datetime.now().strftime("%Y%m%d~%H%M%S")
@@ -1146,7 +1177,7 @@ def makeWindowsEmbedded(sysArgs):
minimalZip = sysArgs[1]
if minimalZip is None:
print("Please provide the path to the minimal win pacage as an argument")
print("Please provide the path to the minimal win package as an argument")
sys.exit(1)
packVersion = os.path.basename(minimalZip).split("-")[1]
@@ -1861,6 +1892,7 @@ if __name__ == "__main__":
" The files to be updated must be provided as arguments.",
" qtlrelease Build the language files for internationalisation.",
" clean-assets Delete assets built by manual, sample and qtlrelease.",
" gen-plist Generates an Info.plist for use in a MacOS Bundle",
"",
"Python Packaging:",
"",
@@ -1943,6 +1975,10 @@ if __name__ == "__main__":
sys.argv.remove("clean-assets")
cleanBuiltAssets()
if "gen-plist" in sys.argv:
sys.argv.remove("gen-plist")
genMacOSPlist()
# Python Packaging
# ================

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.cs.disable-library-validation</key>
<true/>
<key>com.apple.security.cs.allow-dyld-environment-variables</key>
<true/>
</dict>
</plist>

View File

@@ -0,0 +1,62 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSPrincipalClass</key>
<string>NSApplication</string>
<key>NSHighResolutionCapable</key>
<string>True</string>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleExecutable</key>
<string>novelWriter</string>
<key>CFBundleGetInfoString</key>
<string>novelWriter: A markdown-like text editor for planning and writing novels.</string>
<key>CFBundleIconFile</key>
<string>novelwriter.icns</string>
<key>CFBundleIdentifier</key>
<string>io.novelwriter.novelWriter</string>
<key>CFBundleName</key>
<string>novelWriter</string>
<key>CFBundleDisplayName</key>
<string>novelWriter</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleShortVersionString</key>
<string>{macosBundleSVers}</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>{macosBundleVers}</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>NSHumanReadableCopyright</key>
<string>{macosBundleCopyright}</string>
<key>IFMajorVersion</key>
<integer>{macosBundleVersMajor}</integer>
<key>IFMinorVersion</key>
<integer>{macosBundleVersMinor}</integer>
<key>CFBundleDocumentTypes</key>
<array>
<dict>
<key>CFBundleTypeExtensions</key>
<array>
<string>nwx</string>
</array>
<key>CFBundleTypeName</key>
<string>novelWriter Project</string>
<key>CFBundleTypeOSTypes</key>
<array>
<string>TEXT</string>
<string>utxt</string>
<string>TUTX</string>
<string>****</string>
</array>
<key>CFBundleTypeRole</key>
<string>Viewer</string>
<key>LSHandlerRank</key>
<string>Alternate</string>
</dict>
</array>
</dict>
</plist>

171
setup/macos/build.sh Executable file
View File

@@ -0,0 +1,171 @@
#! /bin/bash
# use RAM disk if possible
if [ -d /dev/shm ]; then
TEMP_BASE=/dev/shm
else
TEMP_BASE=/tmp
fi
BUILD_DIR=$(mktemp -d "$TEMP_BASE/novelWriter-build-XXXXXX")
SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
SRC_DIR="$SCRIPT_DIR/../.."
RLS_DIR="$SRC_DIR/dist_macos"
echo "Script Dir: $SCRIPT_DIR"
cleanup () {
if [ -d "$BUILD_DIR" ]; then
rm -rf "$BUILD_DIR"
fi
}
trap cleanup EXIT
echo "Building in: $BUILD_DIR"
OLD_CWD="$(pwd)"
VERSION="$(awk '/^__version__/{print substr($NF,2,length($NF)-2)}' $SRC_DIR/novelwriter/__init__.py)"
pushd "$SRC_DIR" || exit 1
python3 setup.py gen-plist
if [ -f $SRC_DIR/setup/macos/Info.plist ]; then
echo "Found: setup/macos/Info.plist"
else
echo "Missing: setup/macos/Info.plist"
exit 1
fi
# Check that other assets are present
if [ -f $SRC_DIR/novelwriter/assets/sample.zip ]; then
echo "Found: novelwriter/assets/sample.zip"
else
echo "Missing: novelwriter/assets/sample.zip"
exit 1
fi
if [ -f $SRC_DIR/novelwriter/assets/manual.pdf ]; then
echo "Found: novelwriter/assets/manual.pdf"
else
echo "Missing: novelwriter/assets/manual.pdf"
exit 1
fi
if [ -f $SRC_DIR/novelwriter/assets/i18n/nw_en_US.qm ]; then
echo "Found: novelwriter/assets/i18n/nw_en_US.qm"
else
echo "Missing: novelwriter/assets/i18n/nw_en_US.qm"
exit 1
fi
ls -lah .
popd || exit 1
pushd "$BUILD_DIR"/ || exit 1
echo "Downloading Miniconda ..."
# install Miniconda, a self-contained Python distribution
curl -LO https://repo.continuum.io/miniconda/Miniconda3-latest-MacOSX-x86_64.sh
bash Miniconda3-latest-MacOSX-x86_64.sh -b -p ~/miniconda -f
rm Miniconda3-latest-MacOSX-x86_64.sh
export PATH="$HOME/miniconda/bin:$PATH"
echo "Creating conda env ..."
# create conda env
conda create -n novelWriter -c conda-forge python=3.10 --yes
source activate novelWriter
echo "installing dictionaries ..."
conda install -c conda-forge enchant hunspell-en --yes
echo "installing python deps ..."
# install dependencies
pip install -r "$SRC_DIR/requirements.txt"
# leave conda env
conda deactivate
echo "Building app bundle ..."
# create .app Framework
mkdir -p novelWriter.app/Contents/
mkdir novelWriter.app/Contents/MacOS novelWriter.app/Contents/Resources novelWriter.app/Contents/Resources/novelWriter
cp $SRC_DIR/setup/macos/Info.plist novelWriter.app/Contents/Info.plist
echo "Copying miniconda env to bundle ..."
cp -R ~/miniconda/envs/novelWriter/* novelWriter.app/Contents/Resources/
echo "Copying novelWriter to bundle ..."
FILES_COPY=(
"CHANGELOG.md" "MANIFEST.in" "CREDITS.md" "LICENSE.md"
"CONTRIBUTING.md" "CODE_OF_CONDUCT.md" "novelwriter"
"novelWriter.py"
)
for file in "${FILES_COPY[@]}"; do
echo "Copying $SRC_DIR/$file ..."
cp -R $SRC_DIR/$file novelWriter.app/Contents/Resources/novelWriter/
done
cp $SRC_DIR/setup/macos/novelwriter.icns novelWriter.app/Contents/Resources/
# create entry script
cat > novelWriter.app/Contents/MacOS/novelWriter <<\EOF
#!/bin/bash
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
$DIR/../Resources/bin/python -sE $DIR/../Resources/novelWriter/novelWriter.py $@
EOF
# make executable
chmod a+x novelWriter.app/Contents/MacOS/novelWriter
#do codesigning
#echo "Signing bundle ..."
#sudo codesign --sign - --deep --force --entitlements "$SCRIPT_DIR/../macos/App.entitlements" --options runtime "novelWriter.app/Contents/MacOS/novelWriter"
# remove bloat
pushd novelWriter.app/Contents/Resources || exit 1
echo "Cleaning unused files from bundle ..."
# cleanup commands HERE
find . -type d -iname '__pycache__' -print0 | xargs -0 rm -r
rm -rf pkgs
rm -rf cmake
rm -rf share/{gtk-,}doc
# Remove the files from the 3.1 symlink
rm -rf lib/python3.1
# remove web engine
rm lib/python3.*/site-packages/PyQt5/QtWebEngine* || true
rm -r lib/python3.*/site-packages/PyQt5/Qt/translations/qtwebengine* || true
rm lib/python3.*/site-packages/PyQt5/Qt/resources/qtwebengine* || true
rm -r lib/python3.*/site-packages/PyQt5/Qt/qml/QtWebEngine* || true
rm -r lib/python3.*/site-packages/PyQt5/Qt/plugins/webview/libqtwebview* || true
rm lib/python3.*/site-packages/PyQt5/Qt/libexec/QtWebEngineProcess* || true
rm lib/python3.*/site-packages/PyQt5/Qt/lib/libQt5WebEngine* || true
popd || exit 1
popd || exit 1
echo "Packageing App ..."
mkdir -p $RLS_DIR
# generate .dmg
brew install create-dmg
# "--skip-jenkins" is a temporary workaround for https://github.com/create-dmg/create-dmg/issues/72
create-dmg --volname "novelWriter $VERSION" --volicon $SRC_DIR/setup/macos/novelwriter.icns \
--window-pos 200 120 --window-size 800 400 --icon-size 100 --icon novelWriter.app 200 190 --hide-extension novelWriter.app \
--app-drop-link 600 185 $RLS_DIR/novelWriter-"${VERSION}".dmg "$BUILD_DIR"/
pushd $BUILD_DIR || exit 1
zip -qr novelWriter.app.zip novelWriter.app
popd || exit 1
mv $BUILD_DIR/novelWriter.app.zip $RLS_DIR/novelWriter-"${VERSION}".app.zip

70
setup/macos/generate_icns.sh Executable file
View File

@@ -0,0 +1,70 @@
#! /usr/bin/env bash
SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
function generate_linux () {
echo "Generating on Linux ..."
if ! command -v png2icns &> /dev/null
then
echo "png2icns cound not be found, it is required. Please install a package like icnsutils or libicns."
exit
fi
if ! command -v convert $> /dev/null
then
echo "convert could not be found, it is required. please install a imagemagick package."
exit
fi
mkdir -p $SCRIPT_DIR/icons
sizes=( 16 32 64 128 256 )
for base in "${sizes[@]}"; do
let basex2=${base}*2
size="${base}x${base}"
echo "Copying files for $size"
double=${basex2}x${basex2}
cp $SCRIPT_DIR/../data/hicolor/${size}/apps/novelwriter.png $SCRIPT_DIR/icons/icon_${size}.png
echo "Resizing ${size}@2x to $double from $size"
convert $SCRIPT_DIR/icons/icon_${size}.png -resize $double $SCRIPT_DIR/icons/icon_${size}@2x.png
done
png2icns $SCRIPT_DIR/novelwriter.icns $SCRIPT_DIR/icons/icon_*.png
rm -r $SCRIPT_DIR/icons
echo "Done"
}
function generate_macos () {
echo "Generating on MacOs ..."
mkdir -p $SCRIPT_DIR/icons
echo "Building Iconset ..."
sizes=( 16 32 64 128 256 )
for base in "${sizes[@]}"; do
let basex2=${base}*2
size="${base}x${base}"
echo "Copying files for $size"
double=${basex2}x${basex2}
cp $SCRIPT_DIR/../data/hicolor/${size}/apps/novelwriter.png $SCRIPT_DIR/icons/icon_${size}.png
cp $SCRIPT_DIR/../data/hicolor/${size}/apps/novelwriter.png $SCRIPT_DIR/icons/icon_${size}@2x.png
echo "Resizing ${size}@2x to $double from $size"
sips -Z $basex2 $SCRIPT_DIR/icons/icon_${size}@2x.png
done
rm -rf $SCRIPT_DIR/novelwriter.iconset
mv $SCRIPT_DIR/icons $SCRIPT_DIR/novelwriter.iconset
echo "Generating icns ..."
iconutil -c icns $SCRIPT_DIR/novelwriter.iconset
echo "Done"
}
unameOut="$(uname -s)"
case "$unameOut" in
Linux*) generate_linux;;
Darwin*) generate_macos;;
*) echo "Unsupported OS"
esac

Binary file not shown.

View File

@@ -3,7 +3,7 @@ novelWriter – Test Suite Configuration
======================================
This file is a part of novelWriter
Copyright 2018–2022, Veronica Berglyd Olsen
Copyright 2018–2023, Veronica Berglyd Olsen
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@@ -3,7 +3,7 @@ novelWriter – Test Suite Mocked Classes
=======================================
This file is a part of novelWriter
Copyright 2018–2022, Veronica Berglyd Olsen
Copyright 2018–2023, Veronica Berglyd Olsen
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@@ -1,8 +1,14 @@
<?xml version='1.0' encoding='utf-8'?>
<office:document xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" xmlns:loext="urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.0" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:meta:1.0" xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" office:version="1.2" office:mimetype="application/vnd.oasis.opendocument.text">
<office:document xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" xmlns:loext="urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.0" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:meta:1.0" xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" xmlns:dc="http://purl.org/dc/elements/1.1/" office:version="1.3" office:mimetype="application/vnd.oasis.opendocument.text">
<office:meta>
<meta:creation-date>2022-01-02T19:56:15</meta:creation-date>
<meta:generator>novelWriter/1.6-alpha0</meta:generator>
<meta:creation-date>2023-02-12T15:10:11</meta:creation-date>
<meta:generator>novelWriter/2.0.4</meta:generator>
<meta:initial-creator>Jane Smith</meta:initial-creator>
<meta:editing-cycles>1234</meta:editing-cycles>
<meta:editing-duration>P42DT12H34M56S</meta:editing-duration>
<dc:title>Test Project</dc:title>
<dc:date>2023-02-12T15:10:11</dc:date>
<dc:creator>Jane Smith</dc:creator>
</office:meta>
<office:font-face-decls>
<style:font-face style:name="Liberation Serif" style:font-pitch="variable"/>
@@ -66,7 +72,7 @@
<office:master-styles>
<style:master-page style:name="Standard" style:page-layout-name="PM1">
<style:header>
<text:p text:style-name="Header">/ / <text:page-number text:select-page="current">2</text:page-number></text:p>
<text:p text:style-name="Header">Test Project / Jane Smith / <text:page-number text:select-page="current">2</text:page-number></text:p>
</style:header>
<style:header-first>
<text:p text:style-name="Header"/>

View File

@@ -1,5 +1,5 @@
<?xml version='1.0' encoding='utf-8'?>
<office:document-content xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" xmlns:loext="urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.0" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:meta:1.0" xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" office:version="1.2">
<office:document-content xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" xmlns:loext="urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.0" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:meta:1.0" xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" xmlns:dc="http://purl.org/dc/elements/1.1/" office:version="1.3">
<office:font-face-decls>
<style:font-face style:name="Liberation Serif" style:font-pitch="variable"/>
</office:font-face-decls>

Some files were not shown because too many files have changed in this diff Show More