diff --git a/CHANGELOG.md b/CHANGELOG.md index b1b08033..d8e082fa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -89,6 +89,36 @@ final release. ---- +## Version 1.6.3 [2022-08-18] + +### Release Notes + +This is a bugfix release that fixes a rare problem causing novelWriter to crash if the spell +checker language setting was configured to an empty value. + +A few other minor issues have also been fixed: The project language setting is now properly +exported to ODT documents. Spaces are no longer inserted automatically in front of colons in +certain meta data settings when the feature is enabled (it is primarily used for French). Lastly, +the slider splitting the editor and viewer panels can no longer be dragged until the viewer +disappears. It was not necessarily obvious how the viewer panel could be restored in such cases. + +### Detailed Changelog + +**Bugfixes** + +* Fixed an issue where the project language setting was not exported when building Open Document + files. Issue #1073. PR #1087. +* Fixed an issue where the splitter in the main window could be dragged until it hid the document + viewer panel. This is no longer possible. Issue #1085. PR #1087. +* Fixed an issue where an empty spell check language setting would crash novelWriter. Issue #1096. + PR #1098. +* Added a checker that blocks the automatic insertion of spaces in front of special characters in + the cases where the character is a colon in either a meta tag, or as part of the synopsis + keyword. This feature is used for certain languages like French and Spanish. Issue #1090. + PR #1099. + +---- + ## Version 1.6.2 [2022-03-20] ### Release Notes diff --git a/setup.py b/setup.py index 3bbefb9f..9121cc1e 100755 --- a/setup.py +++ b/setup.py @@ -224,23 +224,20 @@ def buildPdfManual(): buildFile = os.path.join("docs", "build", "latex", "manual.pdf") finalFile = os.path.join("novelwriter", "assets", "manual.pdf") + if os.path.isfile(finalFile): + # Make sure a new file is always generated + os.unlink(finalFile) + try: subprocess.call(["make", "clean"], cwd="docs") - stdOut, stdErr, exCode = sysCall(["make latexpdf"], cwd="docs") + exCode = subprocess.call(["make", "latexpdf"], cwd="docs") if exCode == 0: if os.path.isfile(finalFile): os.unlink(finalFile) - outLines = stdOut.splitlines() - for aLine in outLines: - if aLine.startswith("processing manual.tex..."): - break - print(aLine) - print("\n[LaTeX output truncated ...]\n") - print("\n".join(outLines[-6:])) print("") os.rename(buildFile, finalFile) else: - raise Exception(stdErr) + raise Exception(f"Build returned error code {exCode}") print("PDF manual build: OK") print("") @@ -255,6 +252,13 @@ def buildPdfManual(): print(" * Package latexmk") print(" * LaTeX build system") print("") + print(" On Debian/Ubuntu, install: python3-sphinx latexmk texlive texlive-latex-extra") + print("") + sys.exit(1) + + if not os.path.isfile(finalFile): + print("No output file was found!") + print("") sys.exit(1) return @@ -432,6 +436,63 @@ def buildSampleZip(): return +def cleanBuiltAssets(): + """Remove assets built by this script. + """ + print("") + print("Removing Built Assets") + print("=====================") + print("") + + sampleZip = os.path.join("novelwriter", "assets", "sample.zip") + if os.path.isfile(sampleZip): + print(f"Deleted: {sampleZip}") + os.unlink(sampleZip) + + pdfManual = os.path.join("novelwriter", "assets", "manual.pdf") + if os.path.isfile(pdfManual): + print(f"Deleted: {pdfManual}") + os.unlink(pdfManual) + + i18nAssets = os.path.join("novelwriter", "assets", "i18n") + for i18nItem in os.listdir(i18nAssets): + i18nPath = os.path.join(i18nAssets, i18nItem) + if os.path.isfile(i18nPath) and i18nPath.endswith(".qm"): + print(f"Deleted: {i18nPath}") + os.unlink(i18nPath) + + print("") + + return + + +def checkAssetsExist(): + """Check that the necessary compiled assets exist ahead of a build. + """ + hasSample = False + hasManual = False + hasQmData = False + + sampleZip = os.path.join("novelwriter", "assets", "sample.zip") + if os.path.isfile(sampleZip): + print(f"Found: {sampleZip}") + hasSample = True + + pdfManual = os.path.join("novelwriter", "assets", "manual.pdf") + if os.path.isfile(pdfManual): + print(f"Found: {pdfManual}") + hasManual = True + + i18nAssets = os.path.join("novelwriter", "assets", "i18n") + for i18nItem in os.listdir(i18nAssets): + i18nPath = os.path.join(i18nAssets, i18nItem) + if os.path.isfile(i18nPath) and i18nPath.endswith(".qm"): + print(f"Found: {i18nPath}") + hasQmData = True + + return hasSample and hasManual and hasQmData + + # =============================================================================================== # # Python Packaging # =============================================================================================== # @@ -507,12 +568,12 @@ def makeMinimalPackage(targetOS): targName = "" print("") - # Build Additional Assets + # Check Additional Assets # ======================= - buildQtI18n() - buildSampleZip() - buildPdfManual() + if not checkAssetsExist(): + print("ERROR: Missing build assets") + sys.exit(1) # Build Minimal Zip # ================= @@ -604,6 +665,7 @@ def makeDebianPackage(signKey=None, sourceBuild=False, distName="unstable", buil print("") print("Build Debian Package") print("====================") + print("On Debian/Ubuntu install: dh-python python3-all debhelper devscripts") print("") # Version Info @@ -637,12 +699,12 @@ def makeDebianPackage(signKey=None, sourceBuild=False, distName="unstable", buil os.mkdir(outDir) - # Build Additional Assets + # Check Additional Assets # ======================= - buildQtI18n() - buildSampleZip() - buildPdfManual() + if not checkAssetsExist(): + print("ERROR: Missing build assets") + sys.exit(1) # Copy novelWriter Source # ======================= @@ -788,7 +850,6 @@ def makeForLaunchpad(doSign=False, isFirst=False, isSnapshot=False): distLoop = [ ("20.04", "focal"), - ("21.10", "impish"), ("22.04", "jammy"), ] @@ -1278,6 +1339,13 @@ def makeWindowsEmbedded(sysArgs): print(str(exc)) sys.exit(1) + issName = os.path.join("dist", f"novelwriter-{packVersion}-win10-amd64-setup.exe") + newName = os.path.join("dist", f"novelwriter-{packVersion}-py{pyVers}-win10-amd64-setup.exe") + os.replace(issName, newName) + + print(f"Installer: {newName}") + print("") + return @@ -1788,6 +1856,7 @@ if __name__ == "__main__": " qtlupdate Update translation files for internationalisation.", " 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.", "", "Python Packaging:", "", @@ -1866,6 +1935,10 @@ if __name__ == "__main__": sys.argv.remove("sample") buildSampleZip() + if "clean-assets" in sys.argv: + sys.argv.remove("clean-assets") + cleanBuiltAssets() + # Python Packaging # ================ diff --git a/setup/make_release.sh b/setup/make_release.sh index be75b962..98b142e6 100755 --- a/setup/make_release.sh +++ b/setup/make_release.sh @@ -6,6 +6,13 @@ if [ ! -f setup.py ]; then exit 1 fi +echo "" +echo " Building Dependencies" +echo "================================================================================" +echo "" +python3 setup.py clean-assets +python3 setup.py qtlrelease manual sample + echo "" echo " Building Minimal Packages" echo "================================================================================"