Merge branch 'master' into docs_updates

This commit is contained in:
Veronica K. B. Olsen
2020-08-02 21:46:08 +02:00
14 changed files with 233 additions and 78 deletions
+63 -20
View File
@@ -34,9 +34,10 @@ from os import path, remove, rename
from PyQt5.QtGui import QIcon from PyQt5.QtGui import QIcon
from PyQt5.QtWidgets import QApplication, QErrorMessage from PyQt5.QtWidgets import QApplication, QErrorMessage
from nw.error import exceptionHandler
from nw.config import Config from nw.config import Config
__package__ = "novelWriter" __package__ = "nw"
__author__ = "Veronica Berglyd Olsen" __author__ = "Veronica Berglyd Olsen"
__copyright__ = "Copyright 20182020, Veronica Berglyd Olsen" __copyright__ = "Copyright 20182020, Veronica Berglyd Olsen"
__license__ = "GPLv3" __license__ = "GPLv3"
@@ -45,8 +46,9 @@ __hexversion__ = "0x001002f0"
__date__ = "2020-07-29" __date__ = "2020-07-29"
__maintainer__ = "Veronica Berglyd Olsen" __maintainer__ = "Veronica Berglyd Olsen"
__email__ = "code@vkbo.net" __email__ = "code@vkbo.net"
__status__ = "Pre-Release" __status__ = "Beta"
__url__ = "https://github.com/vkbo/novelWriter" __url__ = "https://novelwriter.io"
__sourceurl__ = "https://github.com/vkbo/novelWriter"
__issuesurl__ = "https://github.com/vkbo/novelWriter/issues" __issuesurl__ = "https://github.com/vkbo/novelWriter/issues"
__domain__ = "novelwriter.io" __domain__ = "novelwriter.io"
__docurl__ = "https://novelwriter.readthedocs.io" __docurl__ = "https://novelwriter.readthedocs.io"
@@ -90,7 +92,6 @@ CONFIG = Config()
def main(sysArgs=None): def main(sysArgs=None):
"""Parses command line, sets up logging, and launches main GUI. """Parses command line, sets up logging, and launches main GUI.
""" """
if sysArgs is None: if sysArgs is None:
sysArgs = sys.argv[1:] sysArgs = sys.argv[1:]
@@ -111,7 +112,7 @@ def main(sysArgs=None):
] ]
helpMsg = ( helpMsg = (
"{appname} {version} ({status} {date})\n" "novelWriter {version} ({status} {date})\n"
"{copyright}\n" "{copyright}\n"
"\n" "\n"
"This program is distributed in the hope that it will be useful,\n" "This program is distributed in the hope that it will be useful,\n"
@@ -132,7 +133,6 @@ def main(sysArgs=None):
" --data= Alternative user data path.\n" " --data= Alternative user data path.\n"
" --testmode Do not display GUI. Used by the test suite.\n" " --testmode Do not display GUI. Used by the test suite.\n"
).format( ).format(
appname = __package__,
version = __version__, version = __version__,
status = __status__, status = __status__,
copyright = __copyright__, copyright = __copyright__,
@@ -167,7 +167,9 @@ def main(sysArgs=None):
print(helpMsg) print(helpMsg)
sys.exit() sys.exit()
elif inOpt in ("-v", "--version"): elif inOpt in ("-v", "--version"):
print("%s %s Version %s [%s]" % (__package__,__status__,__version__,__date__)) print("novelWriter %s Version %s [%s]" % (
__status__, __version__, __date__)
)
sys.exit() sys.exit()
elif inOpt == "--info": elif inOpt == "--info":
debugLevel = logging.INFO debugLevel = logging.INFO
@@ -197,7 +199,7 @@ def main(sysArgs=None):
CONFIG.cmdOpen = cmdOpen CONFIG.cmdOpen = cmdOpen
# Set Logging # Set Logging
logFmt = logging.Formatter(fmt=logFormat, datefmt="%Y-%m-%d %H:%M:%S", style="{") logFmt = logging.Formatter(fmt=logFormat, style="{")
if not logFile == "" and toFile: if not logFile == "" and toFile:
if path.isfile(logFile+".bak"): if path.isfile(logFile+".bak"):
@@ -217,8 +219,8 @@ def main(sysArgs=None):
logger.addHandler(cHandle) logger.addHandler(cHandle)
logger.setLevel(debugLevel) logger.setLevel(debugLevel)
logger.info("Starting %s %s (%s) %s" % ( logger.info("Starting novelWriter %s (%s) %s" % (
__package__, __version__, __hexversion__, __date__ __version__, __hexversion__, __date__
)) ))
# Check Packages and Versions # Check Packages and Versions
@@ -249,13 +251,14 @@ def main(sysArgs=None):
if errorData: if errorData:
errApp = QApplication([]) errApp = QApplication([])
errMsg = QErrorMessage() errMsg = QErrorMessage()
errMsg.setMinimumWidth(500) errMsg.resize(500, 300)
errMsg.setMinimumHeight(300)
errMsg.showMessage(( errMsg.showMessage((
"ERROR: %s cannot start due to the following issues:<br><br>" "<h3>A critical error has been encountered</h3>"
"&nbsp;-&nbsp;%s<br><br>Exiting." "<p>novelWriter cannot start due to the following issues:<p>"
"<p>&nbsp;-&nbsp;%s</p>"
"<p>Shutting down ...</p>"
) % ( ) % (
__package__, "<br>&nbsp;-&nbsp;".join(errorData) "<br>&nbsp;-&nbsp;".join(errorData)
)) ))
errApp.exec_() errApp.exec_()
sys.exit(1) sys.exit(1)
@@ -268,13 +271,53 @@ def main(sysArgs=None):
if testMode: if testMode:
nwGUI = GuiMain() nwGUI = GuiMain()
return nwGUI return nwGUI
else: else:
nwApp = QApplication([__package__,("-style=%s" % qtStyle)]) nwApp = QApplication([CONFIG.appName, ("-style=%s" % qtStyle)])
nwApp.setApplicationName(__package__) nwApp.setApplicationName(CONFIG.appName)
nwApp.setApplicationVersion(__version__) nwApp.setApplicationVersion(__version__)
nwApp.setWindowIcon(QIcon(CONFIG.appIcon)) nwApp.setWindowIcon(QIcon(CONFIG.appIcon))
nwApp.setOrganizationDomain("novelwriter.io") nwApp.setOrganizationDomain(__domain__)
nwGUI = GuiMain()
sys.exit(nwApp.exec_()) # We try to catch critical errors while setting up the main GUI
# by wrapping the main GUI in a try/except structure. This will
# not catch all exceptions for other parts of the application.
# For all other unhandled exceptions, we use a custom exception
# handler that pops a dialog box with the error message.
sys.excepthook = exceptionHandler
try:
nwGUI = GuiMain()
sys.exit(nwApp.exec_())
except Exception:
from traceback import print_tb
from nw.error import formatHtmlErrMsg
exType, exValue, exTrace = sys.exc_info()
logger.critical("%s: %s" % (exType.__name__, str(exValue)))
print_tb(exTrace)
try:
del nwApp
errApp = QApplication([])
errMsg = QErrorMessage()
errMsg.setWindowTitle("Critical Error")
errMsg.resize(800, 400)
errMsg.showMessage((
"<h3>A critical error has been encountered</h3>"
"%s"
"<p>Shutting down ...</p>"
) % formatHtmlErrMsg(exType, exValue, exTrace))
errApp.exec_()
except Exception as e:
logger.critical("Could not create error message dialog.")
logger.critical(str(e))
sys.exit(1)
return return
@@ -9,8 +9,8 @@
[Main] [Main]
name = Typicons Colour Dark name = Typicons Colour Dark
description = Coulorised icons for dark GUI theme based on Typicons. description = Coulorised icons for dark GUI theme based on Typicons.
author = Stephen Hutchings (original), Veronica Berglyd Olsen (adaptation) author = Veronica Berglyd Olsen (adaptation)
credit = Stephen Hutchings credit = Stephen Hutchings (icon design)
url = https://github.com/stephenhutchings/typicons.font url = https://github.com/stephenhutchings/typicons.font
license = CC BY-SA 4.0 license = CC BY-SA 4.0
licenseurl = https://creativecommons.org/licenses/by-sa/4.0/ licenseurl = https://creativecommons.org/licenses/by-sa/4.0/
@@ -9,8 +9,8 @@
[Main] [Main]
name = Typicons Colour Light name = Typicons Colour Light
description = Coulorised icons for light GUI theme based on Typicons. description = Coulorised icons for light GUI theme based on Typicons.
author = Stephen Hutchings (original), Veronica Berglyd Olsen (adaptation) author = Veronica Berglyd Olsen (adaptation)
credit = Stephen Hutchings credit = Stephen Hutchings (icon design)
url = https://github.com/stephenhutchings/typicons.font url = https://github.com/stephenhutchings/typicons.font
license = CC BY-SA 4.0 license = CC BY-SA 4.0
licenseurl = https://creativecommons.org/licenses/by-sa/4.0/ licenseurl = https://creativecommons.org/licenses/by-sa/4.0/
@@ -9,8 +9,8 @@
[Main] [Main]
name = Typicons Grey Dark name = Typicons Grey Dark
description = Greyscaled icons for dark GUI theme based on Typicons. description = Greyscaled icons for dark GUI theme based on Typicons.
author = Stephen Hutchings (original), Veronica Berglyd Olsen (adaptation) author = Veronica Berglyd Olsen (adaptation)
credit = Stephen Hutchings credit = Stephen Hutchings (icon design)
url = https://github.com/stephenhutchings/typicons.font url = https://github.com/stephenhutchings/typicons.font
license = CC BY-SA 4.0 license = CC BY-SA 4.0
licenseurl = https://creativecommons.org/licenses/by-sa/4.0/ licenseurl = https://creativecommons.org/licenses/by-sa/4.0/
@@ -9,8 +9,8 @@
[Main] [Main]
name = Typicons Grey Light name = Typicons Grey Light
description = Greyscaled icons for light GUI theme based on Typicons. description = Greyscaled icons for light GUI theme based on Typicons.
author = Stephen Hutchings (original), Veronica Berglyd Olsen (adaptation) author = Veronica Berglyd Olsen (adaptation)
credit = Stephen Hutchings credit = Stephen Hutchings (icon design)
url = https://github.com/stephenhutchings/typicons.font url = https://github.com/stephenhutchings/typicons.font
license = CC BY-SA 4.0 license = CC BY-SA 4.0
licenseurl = https://creativecommons.org/licenses/by-sa/4.0/ licenseurl = https://creativecommons.org/licenses/by-sa/4.0/
+2 -2
View File
@@ -52,8 +52,8 @@ class Config:
def __init__(self): def __init__(self):
# Set Application Variables # Set Application Variables
self.appName = nw.__package__ self.appName = "novelWriter"
self.appHandle = nw.__package__.lower() self.appHandle = self.appName.lower()
self.showGUI = True self.showGUI = True
self.debugInfo = False self.debugInfo = False
self.cmdOpen = None self.cmdOpen = None
+12 -14
View File
@@ -368,23 +368,21 @@ class NWProject():
if fileVersion == "1.0": if fileVersion == "1.0":
msgBox = QMessageBox() msgBox = QMessageBox()
msgRes = msgBox.question(self.theParent, "Old Project Version", ( msgRes = msgBox.question(self.theParent, "Old Project Version", (
"The project file and data is created by a %s version lower than 0.7. " "The project file and data is created by a novelWriter version "
"Do you want to upgrade the project to the most recent format?<br><br>" "lower than 0.7. Do you want to upgrade the project to the "
"Note that after the upgrade, you cannot open the project with an older " "most recent format?<br><br>Note that after the upgrade, you "
"version of %s any more, so make sure you have a recent backup." "cannot open the project with an older version of novelWriter "
) % ( "any more, so make sure you have a recent backup."
nw.__package__, nw.__package__
)) ))
if msgRes != QMessageBox.Yes: if msgRes != QMessageBox.Yes:
return False return False
elif fileVersion != "1.1" and fileVersion != "1.2": elif fileVersion != "1.1" and fileVersion != "1.2":
self.makeAlert(( self.makeAlert((
"Unknown or unsupported {nw:s} project file format. " "Unknown or unsupported novelWriter project file format. "
"The project cannot be opened by this version of {nw:s}. " "The project cannot be opened by this version of novelWriter. "
"The file was saved with {nw:s} version {vers:s}." "The file was saved with novelWriter version {vers:s}."
).format( ).format(
nw = nw.__package__,
vers = appVersion, vers = appVersion,
), nwAlert.ERROR) ), nwAlert.ERROR)
return False return False
@@ -395,11 +393,11 @@ class NWProject():
if int(hexVersion, 16) > int(nw.__hexversion__, 16) and self.mainConf.showGUI: if int(hexVersion, 16) > int(nw.__hexversion__, 16) and self.mainConf.showGUI:
msgBox = QMessageBox() msgBox = QMessageBox()
msgRes = msgBox.question(self.theParent, "Version Conflict", ( msgRes = msgBox.question(self.theParent, "Version Conflict", (
"This project was saved by a newer version of %s, version %s. This is version %s. " "This project was saved by a newer version of novelWriter, version %s. "
"If you continue to open the project, some attributes and settings may not be " "This is version %s. If you continue to open the project, some attributes "
"preserved. Continue opening the project?" "and settings may not be preserved. Continue opening the project?"
) % ( ) % (
nw.__package__, appVersion, nw.__version__ appVersion, nw.__version__
)) ))
if msgRes != QMessageBox.Yes: if msgRes != QMessageBox.Yes:
return False return False
+111
View File
@@ -0,0 +1,111 @@
# -*- coding: utf-8 -*-
"""novelWriter Init
novelWriter Exception Handling
==================================
Error handling functions
File History:
Created: 2020-08-02 [0.10.2]
This file is a part of novelWriter
Copyright 2020, 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/>.
"""
def formatHtmlErrMsg(exType, exValue, exTrace):
"""Generates a HTML version of an exception.
"""
try:
import sys
from traceback import format_tb
from nw import __issuesurl__, __version__
from PyQt5.Qt import PYQT_VERSION_STR
from PyQt5.QtCore import QT_VERSION_STR, QSysInfo
fmtTrace = ""
for trEntry in format_tb(exTrace):
for trLine in trEntry.split("\n"):
stripLine = trLine.lstrip(" ")
nIndent = len(trLine) - len(stripLine)
fmtTrace += "&nbsp;"*nIndent + stripLine + "<br>"
theMessage = (
"<p>Please report this error by submitting an issue report on "
"GitHub, providing a description and this error message. "
"URL: &lt;{issueUrl}&gt;.</p>"
"<p><b>Environment</b><br>Version: {nwVersion}, OS: {osType} ({osKernel}),"
"Python: {pyVersion} ({pyHexVer:#x}), Qt: {qtVers}, PyQt: {pyqtVers}</p>"
"<p><b>Error Type</b><br>{exType}: {exMessage}</p>"
"<p><b>Traceback</b><br>{exTrace}</p>"
).format(
nwVersion = __version__,
osType = sys.platform,
osKernel = QSysInfo.kernelVersion(),
pyVersion = sys.version.split()[0],
pyHexVer = sys.hexversion,
qtVers = QT_VERSION_STR,
pyqtVers = PYQT_VERSION_STR,
issueUrl = __issuesurl__,
exType = exType.__name__,
exMessage = str(exValue),
exTrace = fmtTrace
)
return theMessage
except Exception as e:
return "Could not generate error message.<br>%s" % str(e)
return "Could not generate error message."
def exceptionHandler(exType, exValue, exTrace):
"""Function to catch unhandled global exceptions.
"""
import logging
from traceback import print_tb, format_tb
from nw import CONFIG
from PyQt5.QtWidgets import qApp, QApplication, QErrorMessage, QMessageBox
logger = logging.getLogger(__name__)
logger.error("%s: %s" % (exType.__name__, str(exValue)))
print_tb(exTrace)
if not CONFIG.showGUI:
return
try:
nwGUI = None
for qWin in qApp.topLevelWidgets():
if qWin.objectName() == "GuiMain":
nwGUI = qWin
break
if nwGUI is None:
logger.warning("Could not find main GUI window so cannot open error dialog")
return
errMsg = QErrorMessage(nwGUI)
errMsg.setWindowTitle("Unhandled Error")
errMsg.resize(800, 400)
errMsg.showMessage((
"<h3>An unhandled error has been encountered</h3>%s"
) % formatHtmlErrMsg(exType, exValue, exTrace))
except Exception as e:
logger.error(str(e))
return
+3 -3
View File
@@ -54,13 +54,13 @@ class GuiAbout(QDialog):
self.innerBox = QHBoxLayout() self.innerBox = QHBoxLayout()
self.innerBox.setSpacing(self.mainConf.pxInt(16)) self.innerBox.setSpacing(self.mainConf.pxInt(16))
self.setWindowTitle("About %s" % nw.__package__) self.setWindowTitle("About %s" % self.mainConf.appName)
self.setMinimumWidth(self.mainConf.pxInt(650)) self.setMinimumWidth(self.mainConf.pxInt(650))
self.setMinimumHeight(self.mainConf.pxInt(600)) self.setMinimumHeight(self.mainConf.pxInt(600))
iPx = self.mainConf.pxInt(96) iPx = self.mainConf.pxInt(96)
self.guiDeco = self.theParent.theTheme.loadDecoration("nwicon", (iPx, iPx)) self.guiDeco = self.theParent.theTheme.loadDecoration("nwicon", (iPx, iPx))
self.lblName = QLabel("<b>%s</b>" % nw.__package__) self.lblName = QLabel("<b>%s</b>" % self.mainConf.appName)
self.lblVers = QLabel("v%s" % nw.__version__) self.lblVers = QLabel("v%s" % nw.__version__)
self.lblDate = QLabel(datetime.strptime(nw.__date__, "%Y-%m-%d").strftime("%x")) self.lblDate = QLabel(datetime.strptime(nw.__date__, "%Y-%m-%d").strftime("%x"))
@@ -132,7 +132,7 @@ class GuiAbout(QDialog):
"<h3>Credits</h3>" "<h3>Credits</h3>"
"<p>{credits:s}</p>" "<p>{credits:s}</p>"
).format( ).format(
name = nw.__package__, name = self.mainConf.appName,
copyright = nw.__copyright__, copyright = nw.__copyright__,
website = nw.__url__, website = nw.__url__,
domain = nw.__domain__, domain = nw.__domain__,
-1
View File
@@ -432,7 +432,6 @@ class GuiBuildNovel(QDialog):
def _buildPreview(self): def _buildPreview(self):
"""Build a preview of the project in the document viewer. """Build a preview of the project in the document viewer.
""" """
# Get Settings # Get Settings
fmtTitle = self.fmtTitle.text().strip() fmtTitle = self.fmtTitle.text().strip()
fmtChapter = self.fmtChapter.text().strip() fmtChapter = self.fmtChapter.text().strip()
+3 -3
View File
@@ -258,7 +258,7 @@ class GuiMainMenu(QMenuBar):
# Project > Exit # Project > Exit
self.aExitNW = QAction("Exit", self) self.aExitNW = QAction("Exit", self)
self.aExitNW.setStatusTip("Exit %s" % nw.__package__) self.aExitNW.setStatusTip("Exit %s" % self.mainConf.appName)
self.aExitNW.setShortcut("Ctrl+Q") self.aExitNW.setShortcut("Ctrl+Q")
self.aExitNW.triggered.connect(self._menuExit) self.aExitNW.triggered.connect(self._menuExit)
self.projMenu.addAction(self.aExitNW) self.projMenu.addAction(self.aExitNW)
@@ -804,8 +804,8 @@ class GuiMainMenu(QMenuBar):
self.helpMenu = self.addMenu("&Help") self.helpMenu = self.addMenu("&Help")
# Help > About # Help > About
self.aAboutNW = QAction("About %s" % nw.__package__, self) self.aAboutNW = QAction("About %s" % self.mainConf.appName, self)
self.aAboutNW.setStatusTip("About %s" % nw.__package__) self.aAboutNW.setStatusTip("About %s" % self.mainConf.appName)
self.aAboutNW.triggered.connect(self._showAbout) self.aAboutNW.triggered.connect(self._showAbout)
self.helpMenu.addAction(self.aAboutNW) self.helpMenu.addAction(self.aAboutNW)
+5 -5
View File
@@ -108,7 +108,7 @@ class GuiPreferences(PagedDialog):
msgBox = QMessageBox() msgBox = QMessageBox()
msgBox.information( msgBox.information(
self, "Preferences", self, "Preferences",
"Some changes will not be applied until %s has been restarted." % nw.__package__ "Some changes will not be applied until novelWriter has been restarted."
) )
if validEntries: if validEntries:
@@ -154,7 +154,7 @@ class GuiConfigEditGeneralTab(QWidget):
self.mainForm.addRow( self.mainForm.addRow(
"Main GUI theme", "Main GUI theme",
self.selectTheme, self.selectTheme,
"Changing this requires restarting %s." % nw.__package__ "Changing this requires restarting novelWriter."
) )
## Select Icon Theme ## Select Icon Theme
@@ -170,7 +170,7 @@ class GuiConfigEditGeneralTab(QWidget):
self.mainForm.addRow( self.mainForm.addRow(
"Main icon theme", "Main icon theme",
self.selectIcons, self.selectIcons,
"Changing this requires restarting %s." % nw.__package__ "Changing this requires restarting novelWriter."
) )
## Dark Icons ## Dark Icons
@@ -193,7 +193,7 @@ class GuiConfigEditGeneralTab(QWidget):
self.mainForm.addRow( self.mainForm.addRow(
"Font family", "Font family",
self.guiFont, self.guiFont,
"Changing this requires restarting %s." % nw.__package__, "Changing this requires restarting novelWriter.",
theButton = self.fontButton theButton = self.fontButton
) )
@@ -206,7 +206,7 @@ class GuiConfigEditGeneralTab(QWidget):
self.mainForm.addRow( self.mainForm.addRow(
"Font size", "Font size",
self.guiFontSize, self.guiFontSize,
"Changing this requires restarting %s." % nw.__package__, "Changing this requires restarting novelWriter.",
theUnit = "pt" theUnit = "pt"
) )
+10 -9
View File
@@ -56,6 +56,7 @@ class GuiMain(QMainWindow):
QMainWindow.__init__(self) QMainWindow.__init__(self)
logger.debug("Initialising GUI ...") logger.debug("Initialising GUI ...")
self.setObjectName("GuiMain")
self.mainConf = nw.CONFIG self.mainConf = nw.CONFIG
# Some runtime info useful for debugging # Some runtime info useful for debugging
@@ -220,7 +221,7 @@ class GuiMain(QMainWindow):
else: else:
self.manageProjects() self.manageProjects()
logger.debug("%s is ready ..." % nw.__package__) logger.debug("novelWriter is ready ...")
return return
@@ -384,13 +385,13 @@ class GuiMain(QMainWindow):
msgBox = QMessageBox() msgBox = QMessageBox()
msgRes = msgBox.warning( msgRes = msgBox.warning(
self, "Project Locked", ( self, "Project Locked", (
"The project is already open by another instance of %s, and is " "The project is already open by another instance of novelWriter, and "
"therefore locked. Override lock and continue anyway?<br><br>" "is therefore locked. Override lock and continue anyway?<br><br>"
"Note: If the program or the computer previously crashed, the lock " "Note: If the program or the computer previously crashed, the lock "
"can safely be overridden. If, however, another instance of %s has " "can safely be overridden. If, however, another instance of "
"the project open, overriding the lock may corrupt the project, and " "novelWriter has the project open, overriding the lock may corrupt "
"is not recommended.%s" "the project, and is not recommended.%s"
) % (nw.__package__, nw.__package__, lockDetails), ) % lockDetails,
QMessageBox.Yes | QMessageBox.No, QMessageBox.No QMessageBox.Yes | QMessageBox.No, QMessageBox.No
) )
if msgRes == QMessageBox.Yes: if msgRes == QMessageBox.Yes:
@@ -872,7 +873,7 @@ class GuiMain(QMainWindow):
if msgRes != QMessageBox.Yes: if msgRes != QMessageBox.Yes:
return False return False
logger.info("Exiting %s" % nw.__package__) logger.info("Exiting novelWriter")
if not self.isFocusMode: if not self.isFocusMode:
self.mainConf.setMainPanePos(self.splitMain.sizes()) self.mainConf.setMainPanePos(self.splitMain.sizes())
@@ -1037,7 +1038,7 @@ class GuiMain(QMainWindow):
return True return True
def _setWindowTitle(self, projName=None): def _setWindowTitle(self, projName=None):
winTitle = "%s" % nw.__package__ winTitle = self.mainConf.appName
if projName is not None: if projName is not None:
winTitle += " - %s" % projName winTitle += " - %s" % projName
self.setWindowTitle(winTitle) self.setWindowTitle(winTitle)
+16 -13
View File
@@ -1,19 +1,24 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import setuptools import setuptools
from nw import __version__, __url__, __docurl__, __issuesurl__, __sourceurl__
with open("README.md", "r") as inFile: with open("README.md", "r") as inFile:
long_description = inFile.read() longDescription = inFile.read()
with open("requirements.txt", "r") as inFile:
pkgRequirements = inFile.read().strip().splitlines()
setuptools.setup( setuptools.setup(
name = "novelWriter", name = "novelWriter",
version = "0.10.2", version = __version__,
author = "Veronica Berglyd Olsen", author = "Veronica Berglyd Olsen",
author_email = "code@vkbo.net", author_email = "code@vkbo.net",
description = "A markdown-like document editor for writing novels", description = "A markdown-like document editor for writing novels",
long_description = long_description, long_description = longDescription,
long_description_content_type = "text/markdown", long_description_content_type = "text/markdown",
license = "GNU General Public License v3", license = "GNU General Public License v3",
url = "https://github.com/vkbo/novelWriter", url = __url__,
entry_points = { entry_points = {
"console_scripts" : ["novelWriter-cli=nw:main"], "console_scripts" : ["novelWriter-cli=nw:main"],
"gui_scripts" : ["novelWriter=nw:main"], "gui_scripts" : ["novelWriter=nw:main"],
@@ -22,26 +27,24 @@ setuptools.setup(
include_package_data = True, include_package_data = True,
package_data = {"": ["*.conf"]}, package_data = {"": ["*.conf"]},
project_urls = { project_urls = {
"Bug Tracker": "https://github.com/vkbo/novelWriter/issues", "Bug Tracker": __issuesurl__,
"Documentation": "https://novelwriter.readthedocs.io/", "Documentation": __docurl__,
"Source Code": "https://github.com/vkbo/novelWriter", "Source Code": __sourceurl__,
}, },
classifiers = [ classifiers = [
"Programming Language :: Python :: 3 :: Only", "Programming Language :: Python :: 3 :: Only",
"Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.6",
"Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: Implementation :: CPython",
"License :: OSI Approved :: GNU General Public License v3 (GPLv3)", "License :: OSI Approved :: GNU General Public License v3 (GPLv3)",
"Development Status :: 3 - Alpha", "Development Status :: 4 - Beta",
"Operating System :: OS Independent", "Operating System :: OS Independent",
"Intended Audience :: End Users/Desktop", "Intended Audience :: End Users/Desktop",
"Natural Language :: English", "Natural Language :: English",
"Topic :: Text Editors", "Topic :: Text Editors",
], ],
python_requires = ">=3.6", python_requires = ">=3.6",
install_requires = [ install_requires = pkgRequirements,
"pyqt5>=5.2.1",
"lxml>=4.2.0",
"pyenchant>=3.0.0",
],
) )