diff --git a/nw/config.py b/nw/config.py
index 5acf8774..fbb384ab 100644
--- a/nw/config.py
+++ b/nw/config.py
@@ -288,7 +288,8 @@ class Config:
return True
def loadConfig(self):
-
+ """Load preferences from file and replace default settings.
+ """
logger.debug("Loading config file")
cnfParse = configparser.ConfigParser()
try:
@@ -453,7 +454,8 @@ class Config:
return True
def saveConfig(self):
-
+ """Save the current preferences to file.
+ """
logger.debug("Saving config file")
cnfParse = configparser.ConfigParser()
@@ -546,7 +548,6 @@ class Config:
def loadRecentCache(self):
"""Load the cache file for recent projects.
"""
-
if self.dataPath is None:
return False
@@ -587,7 +588,6 @@ class Config:
def saveRecentCache(self):
"""Save the cache dictionary of recent projects.
"""
-
if self.dataPath is None:
return False
@@ -619,6 +619,18 @@ class Config:
}
return True
+ def removeFromRecentCache(self, thePath):
+ """Trying to remove a path from the recent projects cache.
+ """
+ if thePath in self.recentProj:
+ del self.recentProj[thePath]
+ logger.verbose("Removed recent: %s" % thePath)
+ self.saveRecentCache()
+ else:
+ logger.error("Unknown recent: %s" % thePath)
+ return False
+ return True
+
##
# Setters and Getters
##
@@ -737,7 +749,6 @@ class Config:
def _checkOptionalPackages(self):
"""Cheks if we have the optional packages used by some features.
"""
-
try:
import enchant
self.hasEnchant = True
diff --git a/nw/gui/dialogs/projectload.py b/nw/gui/dialogs/projectload.py
index 17950b37..3b64848b 100644
--- a/nw/gui/dialogs/projectload.py
+++ b/nw/gui/dialogs/projectload.py
@@ -28,24 +28,27 @@
import logging
import nw
+from os import path
from datetime import datetime
from PyQt5.QtCore import Qt
+from PyQt5.QtGui import QKeySequence
from PyQt5.QtWidgets import (
QDialog, QHBoxLayout, QVBoxLayout, QGridLayout, QPushButton, QTreeWidget,
- QAbstractItemView, QTreeWidgetItem, QDialogButtonBox, QLabel
+ QAbstractItemView, QTreeWidgetItem, QDialogButtonBox, QLabel, QShortcut,
+ QFileDialog, QLineEdit
)
from nw.common import formatInt
+from nw.constants import nwFiles
logger = logging.getLogger(__name__)
class GuiProjectLoad(QDialog):
- NONE_STATE = 0
- BROWSE_STATE = 1
- NEW_STATE = 2
- OPEN_STATE = 3
+ NONE_STATE = 0
+ NEW_STATE = 1
+ OPEN_STATE = 2
def __init__(self, theParent):
QDialog.__init__(self, theParent)
@@ -87,16 +90,23 @@ class GuiProjectLoad(QDialog):
treeHead.setTextAlignment(1, Qt.AlignRight)
treeHead.setTextAlignment(2, Qt.AlignRight)
- self.lblRecent = QLabel("Recently Opened:")
- self.lblPath = QLabel("Path:")
- self.selPath = QLabel("")
- self.selPath.setWordWrap(True)
+ self.lblRecent = QLabel("Recently Opened Projects")
+ self.lblPath = QLabel("Path")
+ self.selPath = QLineEdit("")
+ self.selPath.setEnabled(False)
- self.projectForm.addWidget(self.lblRecent, 0, 0, 1, 2)
- self.projectForm.addWidget(self.listBox, 1, 0, 1, 2)
- self.projectForm.addWidget(self.lblPath, 2, 0, 1, 1, Qt.AlignTop)
- self.projectForm.addWidget(self.selPath, 2, 1, 1, 1, Qt.AlignTop)
+ self.browseButton = QPushButton("...")
+ self.browseButton.setMaximumWidth(30)
+ self.browseButton.clicked.connect(self._doBrowse)
+
+ self.projectForm.addWidget(self.lblRecent, 0, 0, 1, 3)
+ self.projectForm.addWidget(self.listBox, 1, 0, 1, 3)
+ self.projectForm.addWidget(self.lblPath, 2, 0, 1, 1)
+ self.projectForm.addWidget(self.selPath, 2, 1, 1, 1)
+ self.projectForm.addWidget(self.browseButton, 2, 2, 1, 1)
+ self.projectForm.setColumnStretch(0, 0)
self.projectForm.setColumnStretch(1, 1)
+ self.projectForm.setColumnStretch(2, 0)
self.projectForm.setVerticalSpacing(4)
self.projectForm.setHorizontalSpacing(8)
@@ -109,9 +119,6 @@ class GuiProjectLoad(QDialog):
self.newButton = self.buttonBox.addButton("New", QDialogButtonBox.ActionRole)
self.newButton.clicked.connect(self._doNewProject)
- self.browseButton = self.buttonBox.addButton("Browse", QDialogButtonBox.ActionRole)
- self.browseButton.clicked.connect(self._doBrowse)
-
self.outerBox.addLayout(self.innerBox)
self.outerBox.addWidget(self.buttonBox)
self.setLayout(self.outerBox)
@@ -119,6 +126,10 @@ class GuiProjectLoad(QDialog):
self._populateList()
self._doSelectRecent()
+ keyDelete = QShortcut(self.listBox)
+ keyDelete.setKey(QKeySequence(Qt.Key_Delete))
+ keyDelete.activated.connect(self._keyPressDelete)
+
logger.debug("GuiProjectLoad initialisation complete")
return
@@ -155,10 +166,20 @@ class GuiProjectLoad(QDialog):
project browser dialog.
"""
logger.verbose("GuiProjectLoad browse button clicked")
- self._saveDialogState()
- self.openPath = None
- self.openState = self.BROWSE_STATE
- self.accept()
+ if self.mainConf.showGUI:
+ dlgOpt = QFileDialog.Options()
+ dlgOpt |= QFileDialog.DontUseNativeDialog
+ projFile, _ = QFileDialog.getOpenFileName(
+ self, "Open novelWriter Project", "",
+ "novelWriter Project File (%s);;All Files (*)" % nwFiles.PROJ_FILE,
+ options=dlgOpt
+ )
+ if projFile:
+ thePath = path.abspath(path.dirname(projFile))
+ self.selPath.setText(thePath)
+ self.openPath = thePath
+ self.openState = self.OPEN_STATE
+ self.accept()
return
def _doClose(self):
@@ -179,6 +200,15 @@ class GuiProjectLoad(QDialog):
self.accept()
return
+ def _keyPressDelete(self):
+ """Remove an entry from the recent projects list.
+ """
+ selList = self.listBox.selectedItems()
+ if selList:
+ self.mainConf.removeFromRecentCache(selList[0].text(3))
+ self._populateList()
+ return
+
##
# Internal Functions
##
diff --git a/nw/guimain.py b/nw/guimain.py
index b15edbe9..9c4d5d3a 100644
--- a/nw/guimain.py
+++ b/nw/guimain.py
@@ -264,8 +264,6 @@ class GuiMain(QMainWindow):
if dlgProj.result() == QDialog.Accepted:
if dlgProj.openState == GuiProjectLoad.OPEN_STATE:
self.openProject(dlgProj.openPath)
- elif dlgProj.openState == GuiProjectLoad.BROWSE_STATE:
- self.openProject(dlgProj.openPath)
elif dlgProj.openState == GuiProjectLoad.NEW_STATE:
self.newProject()
@@ -274,7 +272,6 @@ class GuiMain(QMainWindow):
def newProject(self, projPath=None, forceNew=False):
"""Create new project with a few default files and folders.
"""
-
if self.hasProject:
msgBox = QMessageBox()
msgRes = msgBox.warning(
@@ -354,13 +351,11 @@ class GuiMain(QMainWindow):
return saveOK
- def openProject(self, projFile=None):
+ def openProject(self, projFile):
"""Open a project. The parameter projFile is passed from the
- open recent projects menu, so it can be set. If not, we pop the
- dialog.
+ open recent projects menu, and must be set to be forwarded to
+ the project class. Otherwise, we just return.
"""
- if projFile is None:
- projFile = self.openProjectDialog()
if projFile is None:
return False
@@ -484,6 +479,8 @@ class GuiMain(QMainWindow):
return True
def saveDocument(self):
+ """Save the current documents.
+ """
if self.hasProject:
self.docEditor.saveText()
return True
@@ -491,7 +488,6 @@ class GuiMain(QMainWindow):
def viewDocument(self, tHandle=None):
"""Load a document for viewing in the view panel.
"""
-
if tHandle is None:
tHandle = self.treeView.getSelectedHandle()
if tHandle is None:
@@ -521,7 +517,6 @@ class GuiMain(QMainWindow):
"""Import the text contained in an out-of-project text file, and
insert the text into the currently open document.
"""
-
lastPath = self.mainConf.lastPath
extFilter = [
@@ -610,6 +605,8 @@ class GuiMain(QMainWindow):
##
def openSelectedItem(self):
+ """Open the selected documents.
+ """
tHandle = self.treeView.getSelectedHandle()
if tHandle is None:
logger.warning("No item selected")
@@ -626,6 +623,8 @@ class GuiMain(QMainWindow):
return True
def editItem(self):
+ """Open the edit item dialog.
+ """
tHandle = self.treeView.getSelectedHandle()
if tHandle is None:
logger.warning("No item selected")
@@ -654,7 +653,6 @@ class GuiMain(QMainWindow):
def rebuildIndex(self):
"""Rebuild the entire index.
"""
-
if not self.hasProject:
return False
@@ -708,19 +706,9 @@ class GuiMain(QMainWindow):
# Main Dialogs
##
- def openProjectDialog(self):
- dlgOpt = QFileDialog.Options()
- dlgOpt |= QFileDialog.DontUseNativeDialog
- projFile, _ = QFileDialog.getOpenFileName(
- self, "Open novelWriter Project", "",
- "novelWriter Project File (%s);;All Files (*)" % nwFiles.PROJ_FILE,
- options=dlgOpt
- )
- if projFile:
- return projFile
- return None
-
def saveProjectDialog(self):
+ """Select where to save project.
+ """
dlgOpt = QFileDialog.Options()
dlgOpt |= QFileDialog.ShowDirsOnly
dlgOpt |= QFileDialog.DontUseNativeDialog
@@ -732,6 +720,8 @@ class GuiMain(QMainWindow):
return None
def newProjectDialog(self):
+ """Select where to save new project.
+ """
dlgOpt = QFileDialog.Options()
dlgOpt |= QFileDialog.ShowDirsOnly
dlgOpt |= QFileDialog.DontUseNativeDialog
@@ -743,6 +733,8 @@ class GuiMain(QMainWindow):
return None
def editConfigDialog(self):
+ """Open the preferences dialog.
+ """
dlgConf = GuiConfigEditor(self, self.theProject)
if dlgConf.exec_() == QDialog.Accepted:
logger.debug("Applying new preferences")
@@ -754,6 +746,8 @@ class GuiMain(QMainWindow):
return True
def editProjectDialog(self):
+ """Open the project settings dialog.
+ """
if self.hasProject:
dlgProj = GuiProjectEditor(self, self.theProject)
dlgProj.exec_()
@@ -761,12 +755,16 @@ class GuiMain(QMainWindow):
return True
def buildProjectDialog(self):
+ """Open the build project dialog.
+ """
if self.hasProject:
dlgExport = GuiBuildNovel(self, self.theProject)
dlgExport.exec_()
return True
def showSessionLogDialog(self):
+ """Open the session log dialog.
+ """
if self.hasProject:
dlgTLine = GuiSessionLogView(self, self.theProject)
dlgTLine.exec_()
@@ -777,7 +775,6 @@ class GuiMain(QMainWindow):
can be either a string or an array of strings. Severity level is
0 = info, 1 = warning, and 2 = error.
"""
-
if isinstance(theMessage, list):
popMsg = " ".join(theMessage)
logMsg = theMessage
@@ -821,7 +818,8 @@ class GuiMain(QMainWindow):
##
def closeMain(self):
-
+ """Save everything, and close novelWriter.
+ """
if self.mainConf.showGUI and self.hasProject:
msgBox = QMessageBox()
msgRes = msgBox.question(
@@ -874,7 +872,6 @@ class GuiMain(QMainWindow):
"""Main GUI Zen Mode hides tree, view pane and optionally also
statusbar and menu.
"""
-
if self.docEditor.theHandle is None:
logger.error("No document open, so not activating Zen Mode")
return False
@@ -906,7 +903,6 @@ class GuiMain(QMainWindow):
if the user uses the system window manager. Currently, Qt
doesn't have access to the exact state of the window.
"""
-
self.setWindowState(self.windowState() ^ Qt.WindowFullScreen)
winState = self.windowState() & Qt.WindowFullScreen == Qt.WindowFullScreen