Rename package from 'nw' to 'novelwriter' (#868)
* Rename nw folder to novelwriter * Rename nw to novelwriter in auxiliary files * Rename nw to novelwriter in main app source * Rename nw to novelwriter in tests * Make setup script for pdf docs less spammy
This commit is contained in:
committed by
GitHub
parent
2cf2eb9f55
commit
3403d98c72
@@ -0,0 +1,303 @@
|
||||
"""
|
||||
novelWriter – Init File
|
||||
=======================
|
||||
Application initialisation
|
||||
|
||||
File History:
|
||||
Created: 2018-09-22 [0.0.1]
|
||||
|
||||
This file is a part of novelWriter
|
||||
Copyright 2018–2021, 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/>.
|
||||
"""
|
||||
|
||||
import sys
|
||||
import getopt
|
||||
import logging
|
||||
|
||||
from PyQt5.QtGui import QIcon
|
||||
from PyQt5.QtWidgets import QApplication, QErrorMessage
|
||||
|
||||
from novelwriter.error import exceptionHandler, logException
|
||||
from novelwriter.config import Config
|
||||
|
||||
##
|
||||
# Version Scheme
|
||||
# ================
|
||||
# Generally follows PEP 440
|
||||
# Hex Version:
|
||||
# - Digit 1,2 : Major Version (01-ff)
|
||||
# - Digit 3,4 : Minor Version (01-ff)
|
||||
# - Digit 5,6 : Patch Version (01-ff)
|
||||
# - Digit 7 : Release Type (a: aplha, b: beta, c: candidate, f: final)
|
||||
# - Digit 8 : Release Number (0-f)
|
||||
#
|
||||
# Example : Full Short Description
|
||||
# -------------------------------------------------------------------------
|
||||
# 0x010200a0 : 1.2-alpha0 1.2a0 Use while developing next release
|
||||
# 0x010200a1 : 1.2-alpha1 1.2a1 First alpha release
|
||||
# 0x010200b1 : 1.2-beta1 1.2b1 First beta release
|
||||
# 0x010200c1 : 1.2-rc1 1.2rc1 First release candidate
|
||||
# 0x010200f0 : 1.2 1.2 Final release
|
||||
# 0x010200f1 : 1.2-post1 1.2.post1 Post release, but not a code patch!
|
||||
# 0x010201f0 : 1.2.1 1.2.1 Patch release
|
||||
##
|
||||
|
||||
__package__ = "novelwriter"
|
||||
__copyright__ = "Copyright 2018–2021, Veronica Berglyd Olsen"
|
||||
__license__ = "GPLv3"
|
||||
__author__ = "Veronica Berglyd Olsen"
|
||||
__maintainer__ = "Veronica Berglyd Olsen"
|
||||
__email__ = "code@vkbo.net"
|
||||
__version__ = "1.5-beta1"
|
||||
__hexversion__ = "0x010500b1"
|
||||
__date__ = "2021-08-22"
|
||||
__status__ = "Stable"
|
||||
__domain__ = "novelwriter.io"
|
||||
__url__ = "https://novelwriter.io"
|
||||
__sourceurl__ = "https://github.com/vkbo/novelWriter"
|
||||
__issuesurl__ = "https://github.com/vkbo/novelWriter/issues"
|
||||
__helpurl__ = "https://github.com/vkbo/novelWriter/discussions"
|
||||
__releaseurl__ = "https://github.com/vkbo/novelWriter/releases/latest"
|
||||
__docurl__ = "https://novelwriter.readthedocs.io"
|
||||
|
||||
##
|
||||
# Logging
|
||||
# =========
|
||||
# Standard used for logging levels in novelWriter:
|
||||
# CRITICAL Use for errors that result in termination of the program
|
||||
# ERROR Use when an action fails, but execution continues
|
||||
# WARNING When something unexpected, but non-critical happens
|
||||
# INFO Any useful user information like open, save, exit initiated
|
||||
# ----------- SPAM Threshold : Output above should be minimal -----------------
|
||||
# DEBUG Use for descriptions of main program flow
|
||||
# VERBOSE Use for outputting values and program flow details
|
||||
##
|
||||
|
||||
# Add verbose logging level
|
||||
VERBOSE = 5
|
||||
logging.addLevelName(VERBOSE, "VERBOSE")
|
||||
|
||||
|
||||
def logVerbose(self, message, *args, **kws):
|
||||
if self.isEnabledFor(VERBOSE):
|
||||
self._log(VERBOSE, message, args, **kws)
|
||||
|
||||
|
||||
logging.Logger.verbose = logVerbose
|
||||
|
||||
# Initiating logging
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
##
|
||||
# Main Program
|
||||
##
|
||||
|
||||
# Load the main config as a global object
|
||||
CONFIG = Config()
|
||||
|
||||
|
||||
def main(sysArgs=None):
|
||||
"""Parse command line, set up logging, and launches main GUI.
|
||||
"""
|
||||
if sysArgs is None:
|
||||
sysArgs = sys.argv[1:]
|
||||
|
||||
# Valid Input Options
|
||||
shortOpt = "hv"
|
||||
longOpt = [
|
||||
"help",
|
||||
"version",
|
||||
"info",
|
||||
"debug",
|
||||
"verbose",
|
||||
"style=",
|
||||
"config=",
|
||||
"data=",
|
||||
"testmode",
|
||||
]
|
||||
|
||||
helpMsg = (
|
||||
"novelWriter {version} ({date})\n"
|
||||
"{copyright}\n"
|
||||
"\n"
|
||||
"This program is distributed in the hope that it will be useful,\n"
|
||||
"but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
|
||||
"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
|
||||
"GNU General Public Licence for more details.\n"
|
||||
"\n"
|
||||
"Usage:\n"
|
||||
" -h, --help Print this message.\n"
|
||||
" -v, --version Print program version and exit.\n"
|
||||
" --info Print additional runtime information.\n"
|
||||
" --debug Print debug output. Includes --info.\n"
|
||||
" --verbose Increase verbosity of debug output. Includes --debug.\n"
|
||||
" --style= Sets Qt5 style flag. Defaults to 'Fusion'.\n"
|
||||
" --config= Alternative config file.\n"
|
||||
" --data= Alternative user data path.\n"
|
||||
).format(
|
||||
version=__version__,
|
||||
copyright=__copyright__,
|
||||
date=__date__,
|
||||
)
|
||||
|
||||
# Defaults
|
||||
logLevel = logging.WARN
|
||||
logFormat = "{levelname:8} {message:}"
|
||||
confPath = None
|
||||
dataPath = None
|
||||
testMode = False
|
||||
qtStyle = "Fusion"
|
||||
cmdOpen = None
|
||||
|
||||
# Parse Options
|
||||
try:
|
||||
inOpts, inRemain = getopt.getopt(sysArgs, shortOpt, longOpt)
|
||||
except getopt.GetoptError as E:
|
||||
print(helpMsg)
|
||||
print("ERROR: %s" % str(E))
|
||||
sys.exit(2)
|
||||
|
||||
if len(inRemain) > 0:
|
||||
cmdOpen = inRemain[0]
|
||||
|
||||
for inOpt, inArg in inOpts:
|
||||
if inOpt in ("-h", "--help"):
|
||||
print(helpMsg)
|
||||
sys.exit(0)
|
||||
elif inOpt in ("-v", "--version"):
|
||||
print("novelWriter Version %s [%s]" % (__version__, __date__))
|
||||
sys.exit(0)
|
||||
elif inOpt == "--info":
|
||||
logLevel = logging.INFO
|
||||
elif inOpt == "--debug":
|
||||
logLevel = logging.DEBUG
|
||||
logFormat = "[{asctime:}] {filename:>17}:{lineno:<4d} {levelname:8} {message:}"
|
||||
elif inOpt == "--verbose":
|
||||
logLevel = VERBOSE
|
||||
logFormat = "[{asctime:}] {filename:>17}:{lineno:<4d} {levelname:8} {message:}"
|
||||
elif inOpt == "--style":
|
||||
qtStyle = inArg
|
||||
elif inOpt == "--config":
|
||||
confPath = inArg
|
||||
elif inOpt == "--data":
|
||||
dataPath = inArg
|
||||
elif inOpt == "--testmode":
|
||||
testMode = True
|
||||
|
||||
# Set Config Options
|
||||
CONFIG.cmdOpen = cmdOpen
|
||||
|
||||
# Set Logging
|
||||
cHandle = logging.StreamHandler()
|
||||
cHandle.setFormatter(logging.Formatter(fmt=logFormat, style="{"))
|
||||
|
||||
pkgLogger = logging.getLogger(__package__)
|
||||
pkgLogger.addHandler(cHandle)
|
||||
pkgLogger.setLevel(logLevel)
|
||||
|
||||
logger.info("Starting novelWriter %s (%s) %s", __version__, __hexversion__, __date__)
|
||||
|
||||
# Check Packages and Versions
|
||||
errorData = []
|
||||
errorCode = 0
|
||||
if sys.hexversion < 0x030600f0:
|
||||
errorData.append(
|
||||
"At least Python 3.6.0 is required, found %s." % CONFIG.verPyString
|
||||
)
|
||||
errorCode |= 4
|
||||
if CONFIG.verQtValue < 50300:
|
||||
errorData.append(
|
||||
"At least Qt5 version 5.3 is required, found %s." % CONFIG.verQtString
|
||||
)
|
||||
errorCode |= 8
|
||||
if CONFIG.verPyQtValue < 50300:
|
||||
errorData.append(
|
||||
"At least PyQt5 version 5.3 is required, found %s." % CONFIG.verPyQtString
|
||||
)
|
||||
errorCode |= 16
|
||||
|
||||
try:
|
||||
import lxml # noqa: F401
|
||||
except ImportError:
|
||||
errorData.append("Python module 'lxml' is missing.")
|
||||
errorCode |= 32
|
||||
|
||||
if errorData:
|
||||
errApp = QApplication([])
|
||||
errMsg = QErrorMessage()
|
||||
errMsg.resize(500, 300)
|
||||
errMsg.showMessage((
|
||||
"<h3>A critical error has been encountered</h3>"
|
||||
"<p>novelWriter cannot start due to the following issues:<p>"
|
||||
"<p> - %s</p>"
|
||||
"<p>Shutting down ...</p>"
|
||||
) % (
|
||||
"<br> - ".join(errorData)
|
||||
))
|
||||
for errMsg in errorData:
|
||||
logger.critical(errMsg)
|
||||
errApp.exec_()
|
||||
sys.exit(errorCode)
|
||||
|
||||
# Finish initialising config
|
||||
CONFIG.initConfig(confPath, dataPath)
|
||||
|
||||
if CONFIG.osDarwin:
|
||||
try:
|
||||
from Foundation import NSBundle
|
||||
bundle = NSBundle.mainBundle()
|
||||
info = bundle.localizedInfoDictionary() or bundle.infoDictionary()
|
||||
info["CFBundleName"] = "novelWriter"
|
||||
except Exception:
|
||||
logger.error("Failed to set application name")
|
||||
logException()
|
||||
|
||||
elif CONFIG.osWindows:
|
||||
try:
|
||||
import ctypes
|
||||
appID = "io.novelwriter.%s" % __version__
|
||||
ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID(appID)
|
||||
except Exception:
|
||||
logger.error("Failed to set application name")
|
||||
logException()
|
||||
|
||||
# Import GUI (after dependency checks), and launch
|
||||
from novelwriter.guimain import GuiMain
|
||||
if testMode:
|
||||
nwGUI = GuiMain()
|
||||
return nwGUI
|
||||
|
||||
else:
|
||||
nwApp = QApplication([CONFIG.appName, ("-style=%s" % qtStyle)])
|
||||
nwApp.setApplicationName(CONFIG.appName)
|
||||
nwApp.setApplicationVersion(__version__)
|
||||
nwApp.setWindowIcon(QIcon(CONFIG.appIcon))
|
||||
nwApp.setOrganizationDomain(__domain__)
|
||||
|
||||
# Connect the exception handler before making the main GUI
|
||||
sys.excepthook = exceptionHandler
|
||||
|
||||
# Launch main GUI
|
||||
CONFIG.initLocalisation(nwApp)
|
||||
nwGUI = GuiMain()
|
||||
if not nwGUI.hasProject:
|
||||
nwGUI.showProjectLoadDialog()
|
||||
nwGUI.releaseNotes()
|
||||
|
||||
sys.exit(nwApp.exec_())
|
||||
|
||||
# END Function main
|
||||
Reference in New Issue
Block a user