Merge pull request #27 from vkbo/docs

Documentation
This commit is contained in:
Veronica K. Berglyd Olsen
2019-06-09 14:16:32 +02:00
committed by GitHub
9 changed files with 768 additions and 57 deletions
+598
View File
@@ -0,0 +1,598 @@
<html>
<head>
<title>novelWriter Help</title>
</head>
<body>
<h1>novelWriter Help</h1>
<a name="Content"></a>
<h3>Content:</h3>
<ul>
<li><a href="#Intro">1. Introduction</a></li>
<li><a href="#Proj">2. Novel Projects</a></li>
<ul>
<li><a href="#Proj_Structure">2.1 Project Structure</a></li>
<li><a href="#Proj_Settings">2.2 Project Settings</a></li>
<li><a href="#Proj_Documents">2.3 Writing Files</a></li>
</ul>
<li><a href="#Novel">3. Novel Structure</a></li>
<ul>
<li><a href="#Novel_Headings">3.1 Importance of Headings</a></li>
<li><a href="#Novel_Refs">3.2 Tag References</a></li>
<li><a href="#Novel_Files">3.3 Novel File Layout</a></li>
</ul>
<li><a href="#Notes">4. Supporting Files (Notes)</a></li>
<ul>
<li><a href="#Notes_Tags">4.1 File Tags</a></li>
</ul>
<li><a href="#GUI">5. User Interface</a></li>
<ul>
<li><a href="#GUI_Markdown">5.1 Markdown Format</a></li>
<li><a href="#GUI_Shortcuts">5.2 Keyboard Shortcuts</a></li>
</ul>
<li><a href="#Code">6. Technical Information</a></li>
<ul>
<li><a href="#Code_Project">6.1 How Data is Stored</a></li>
</ul>
</ul>
<a name="Intro"></a>
<h2>1. Introduction</h2>
<p><a href="#Content">Back to top</a></p>
<a name="Proj"></a>
<h2>2. Novel Projects</h2>
<p><a href="#Content">Back to top</a></p>
<p>A novelWriter project requires a dedicated folder for storing its files. See the
<a href="#Code">Technical Information</a> section for further details.</p>
<p>A new project can be created from the Project menu by selecting <mark>Project > New
Project</mark>. A list of recently opened projects is also maintained and can be selected
from the menu.</p>
<p>The project specific settings are available in <mark>Project > Project Settings</mark>. See
further details below.</p>
<a name="Proj_Structure"></a>
<h3>2.1 Project Structure</h3>
<p><a href="#Content">Back to top</a></p>
<p>Projects are structured into a set of root folders in the left side tree view panel.</p>
<p>The core novel files go into a root folder of type <mark>Novel</mark>. Other supporting files
go into root folders of types <mark>Plot</mark>, <mark>Characters</mark>,
<mark>Locations</mark>, <mark>Timeline</mark>, <mark>Objects</mark> or <mark>Custom</mark>.
These other root folder types are intended for your notes on the various elements of your
story. Using these are of course entirely optional.</p>
<table>
<tr>
<td><mark>Novel</mark></td>
<td>The root folder of all text that goes into the final novel. This class of files have
other rules and features than other files in the project. See the
<a href="#Novel">Novel Structure</a> section for more details.</td>
</tr>
<tr>
<td><mark>Plot</mark></td>
<td>This is the root folder where main plots can be outlined. It is optional, but adding
at least dummy files can be useful in order to generate the timeline view.</td>
</tr>
<tr>
<td><mark>Characters</mark></td>
<td>Character files go in this root folder. These are especially important if one wants
to use the timeline view to see which character appears where and which part of the
story is told from a specific character's point-of-view.</td>
</tr>
<tr>
<td><mark>Locations</mark></td>
<td>Location is for various scene locations that one wants to track in the timeline
view if that applies to the story.</td>
</tr>
<tr>
<td><mark>Timeline</mark></td>
<td>If the story jumps in time within the same plot, this class of files can be used to
track this.</td>
</tr>
<tr>
<td><mark>Objects</mark></td>
<td>Important objects in the story can be tracked here, and connected to the timeline as
well.</td>
</tr>
<tr>
<td><mark>Custom</mark></td>
<td>the custom root folder can be used for tracking anything else not covered by the
above options.</td>
</tr>
</table>
<p>Deleted files will be moved into a special <mark>TRASH</mark> root folder. Currently, these
files cannot be permanently deleted from the project.</p>
<h4>Orphaned Documents</h4>
<p>In the event the editor crashes or otherwise exits without saving the project state, files
that have been added to the project tree and are saved to disk will appear in a special
"Orphaned Items" root folder next time the application is started. These orphaned files will
not have any meta data associated with them, so the title and other information has to be
set again, and the files moved back to the correct location in the project.</p>
<h4>Using Project Folders</h4>
<p>Folders, aside from root folders, have no structural significance to the project. They are
there purely as a way for the user to organise the files in meaningful sections and to be
able to close them in the tree view. When processing the files in the novel, the folders are
ignored.</p>
<a name="Proj_Settings"></a>
<h3>2.2 Project Settings</h3>
<p><a href="#Content">Back to top</a></p>
<p>The project settings can be accessed from the <mark>Project > Project Settings</mark> menu
entry. This will open a dialog box.</p>
<h4>Settings Tab</h4>
<p>The Settings tab holds the project title and author settings. <em>Working Title</em> can be
set to a different title than the <em>Book Title</em>. The difference between them is simply
that the Working Title is used for the GUI (main window title) and when the export features
are added can optionally be printed to the cover sheet. The Book Title, on the other hand,
will only be printed to the title page on export.</p>
<p>The <em>Book Authors</em> text box takes one author per line. The line breaks matter in that
this is converted to a list for later correct formatting.</p>
<h4>Status Tab</h4>
<p>Each file of type <mark>NOVEL</mark> can be given a status level, signified by a coloured
icon. These are purely there for the user's convenience, and you are not required to use
them for any other feature to work. The intention is to use this list to set what stage of
writing you are on, although you can in principle make them whatever you want.</p>
<p>Note that status levels currently in use by a file cannot be deleted.</p>
<h4>Importance Tab</h4>
<p>Each file of types <mark>PLOT</mark>, <mark>CHARACTER</mark>, <mark>WORLD</mark>,
<mark>TIMELINE</mark>, <mark>OBJECT</mark> or <mark>CUSTOM</mark> can be given an importance
level, signified by a coloured icon like for status level. These are also purely there for
the user's convenience, and you are not required to use them for any other feature to work.
The intention is to use this list to set how important the character, plot element, or
otherwise, is for the story. Again, these can in principle be used for whatever you want.
<p>Note that importance levels currently in use by a file cannot be deleted.</p>
<h4>Auto-Replace Tab</h4>
<p>A set of automatically replaced keywords can be added in this tab. The keywords in the left
column wile be replaced by the text in the right column when documents are opened in the
viewer. This will also be applied to exports when the feature is added.</p>
<p>Note that a keyword cannot contain any spaces. The angle brackets are dded by default, and
when used in the text are a part of the keyword to be replaced. This is to ensure that parts
of the text isn't unintentionally replaced by the content of the list.</p>
<a name="Proj_Documents"></a>
<h2>2.3 Writing Files</h2>
<p><a href="#Content">Back to top</a></p>
<p>New document files can be created from the Document menu, or by pressing <mark>Ctrl+N</mark>
while in the tree view pane. This will create a new, empty file, and open the item settings
dialog where the filename and various other settings can be set. This dialog can also be
opened again later from either the menu, <mark>Project > Edit item</mark>, or by pressing
<mark>Ctrl+E</mark> or <mark>F2</mark> with the item selected.</p>
<p>The different classes of documents have some restrictions.</p>
<a name="Novel"></a>
<h2>3. Novel Structure</h2>
<p><a href="#Content">Back to top</a></p>
<p>This section concerns files under the <mark>Novel</mark> type root folder. There are some
restrictions and features that only applies to these type of files.</p>
<a name="Novel_Headings"></a>
<h3>3.1 Importance of Headings</h3>
<p><a href="#Content">Back to top</a></p>
<p>Subfolders under root folders have no impact on the structure of the novel itself. The
structure is instead dictated by the heading level. Four levels of headings are supported,
signified by the number of hashes preceding the title. See the
<a href="#GUI_Markdown">Markdown</a> section.</p>
<p>The header levels are not only important when generating the exported novel file, but is also
used by the indexer and timeline view. Each heading starts a new region where new References
to tags can be set, and will show up as a new row in the timeline view.</p>
<p>The different header levels are interpreted as specific section types of the novel.</p>
<table>
<tr>
<td><mark># Header1</mark></td>
<td>Header level 1 signifies that the text refers to either the novel title or the
name of a top level partition.</td>
</tr>
<tr>
<td><mark>## Header2</mark></td>
<td>Header level 2 signifies a chapter level partition.</td>
</tr>
<tr>
<td><mark>### Header3</mark></td>
<td>Header level 3 signifies a scene level partition.</td>
</tr>
<tr>
<td><mark>#### Header4</mark></td>
<td>Header level 4 signifies a sub-scene level partition.</td>
</tr>
</table>
<a name="Novel_Refs"></a>
<h3>3.2 Tag References</h3>
<p><a href="#Content">Back to top</a></p>
<p>Each section started by a heading can contain references to tags set in the supporting files
of the project. See the <a href="#Notes_Tags">File Tags</a> section.</p>
<p>The references are gathered by the indexer and used to generate the timeline view of how the
different parts of the novel are connected.</p>
<p>References are set as keyword and a list of corresponding tags. The valid keywords are listed
below. The format of such a line is <mark>@keyword: value1, [value2] ... [valueN]</mark>.
Note that not all keywords allow multiple values.</p>
<table>
<tr>
<td><mark>@pov</mark></td>
<td>The point-of-view character for the current section. The target must be a note tag
in the character root folder. Only one value is accepted. further values are
ignored.</td>
</tr>
<tr>
<td><mark>@char</mark></td>
<td>Other characters in the current section. The target must be a note tag in the
character root folder. Multiple values are allowed. This should not include the
point-of-view character.</td>
</tr>
<tr>
<td><mark>@plot</mark></td>
<td>The plot timelines touched by the current section. The target must be a note tag in
the plot root folder. Multiple values are allowed.</td>
</tr>
<tr>
<td><mark>@time</mark></td>
<td>The timelines touched by the current section. The target must be a note tag in the
timeline root folder. Multiple values are allowed.</td>
</tr>
<tr>
<td><mark>@location</mark></td>
<td>The location the current section takes place in. The target must be a note tag in
the locations root folder. Multiple values are allowed.</td>
</tr>
<tr>
<td><mark>@object</mark></td>
<td>Objects present in the current section. The target must be a note tag in the object
root folder. Multiple values are allowed.</td>
</tr>
<tr>
<td><mark>@custom</mark></td>
<td>Custom references in the current section. The target must be a note tag in the
custom root folder. Multiple values are allowed.</td>
</tr>
</table>
<p>the syntax highlighter will alert the user that only the correct keywords are used, and that
the tags referenced exist. If the index of defined tags is out of date, press
<mark>F9</mark> to regenerate it, or select <mark>Tools > Rebuild Indices</mark> from the
menu. In general, the index for a file is regenerated when a file is saved, so this
shouldn't normally be necessary.</p>
<a name="Novel_Files"></a>
<h3>3.3 Novel File Layout</h3>
<p><a href="#Content">Back to top</a></p>
<p>Files that exist under the <mark>NOVEL</mark> type root folder can have a number of layouts
set. See overview below. These layouts are currently not used for any internal feature, but
when the export feature is added they will be important in determining how the different
sections of the novel is formatted.</p>
<table>
<tr>
<td><mark>Title Page</mark></td>
<td>The title page layout. The title should be formatted as a heading level one.</td>
</tr>
<tr>
<td><mark>Book</mark></td>
<td>In principle, the entire novel can be contained in a single file. In that case, use
the Book layout on this file. The internal structure is then controlled by the
heading levels.</td>
</tr>
<tr>
<td><mark>Plain Page</mark></td>
<td>A plain page is just that, It is not included into content and the heading levels
are ignored.</td>
</tr>
<tr>
<td><mark>Partition</mark></td>
<td>A partition can be used to split a the novel into parts. Use a level one heading for
this.</td>
</tr>
<tr>
<td><mark>Chapter</mark></td>
<td>Signifies the start of a new chapter. If the text itself is contained in scene
files, these files should only contain the title and tag references for characters,
plot, etc. The heading for chapters should be level two.</td>
</tr>
<tr>
<td><mark>Un-Numbered</mark></td>
<td>Same as Chapter, but when exporting the files and automatic chapter numbering is
enabled, this file will not receive a number.</td>
</tr>
<tr>
<td><mark>Scene</mark></td>
<td>A scene file. This file should have a header of level three. Further sections can
have headers of level four. These will not impact the overall structure, but will
allow for setting new characters and plot references in parts of a scene if such
granularity is needed.</td>
</tr>
<tr>
<td><mark>Note</mark></td>
<td>A generic file that is ignored when the novel is exported. These layout is allowed
within the Novel root folder, and is the only layout allowed for a file outside the
Novel root folder.</td>
</tr>
</table>
<a name="Notes"></a>
<h2>4. Supporting Files (Notes)</h2>
<p><a href="#Content">Back to top</a></p>
<p>Supporting files, or notes, are any files stored in root folders that are not the Novel root
folder. These files are intended for summaries and outlines of the various plot elements,
characters, locations, and so on, of the novel. These are no required, but making at least
minimal files for each such element makes it possible to use the timeline view feature to
see how each element intersects with each section of the novel itself.</p>
<a name="Notes_Tags"></a>
<h2>4.1 File Tags</h2>
<p><a href="#Content">Back to top</a></p>
<p>Each note file can have a tag associated with it, The format of a tag is
<mark>@tag: tagname</mark>, where tagname is a unique identifier. tags can then be
referenced in the novel files and will then show up as dots in the timeline view.</p>
<p>The syntax highlighter will alert the user that the keyword is correctly used and that the
tag is allowed. Duplicate tags should be detected as long as the index is up to date.</p>
<p>The tag is the only part of these files that the application used. The rest of the file is
there for the writer to use in whatever way they wish.</p>
<a name="GUI"></a>
<h2>5. User Interface</h2>
<p><a href="#Content">Back to top</a></p>
<p>The user interface is kept as simple as possible to avoid distractions. The main window
contains a tree vew pane with the entire structure of the project, and a small details panel
below it to display additional information.</p>
<p>Editing a document can be done by either double-clicking on it, or hitting the return key
when the item is selected. This will open the source editor which uses a simplified markdown
format described in the section below.</p>
<p>The document can also be viewed as html with all the comments and commands stripped out. To
view a document, simply press <mark>Ctrl+R</mark> or select a file and go to <mark>Document
> View Document</mark> in the menu. The document viewed does not need to be the same
document currently being edited.</p>
<a name="GUI_Markdown"></a>
<h3>5.1 Markdown Format</h3>
<p><a href="#Content">Back to top</a></p>
<p>the document editor uses a simplified markdown format. That is, it supports basic formatting
like bold, italics and underline, as well as four levels of headings. The formats are listed
below.</p>
<p>In addition to these standard markdown features, the editor also allows for comments, that is
text that is ignored by the word counter and not exported or seen in the document viewer.
The editor also has a minimal set of commands used for setting tags and references between
files.</p>
<table>
<tr>
<td><mark># Title</mark></td>
<td>Heading level one. The space after the # is mandatory.</td>
</tr>
<tr>
<td><mark>## Title</mark></td>
<td>Heading level two. The space after the # is mandatory.</td>
</tr>
<tr>
<td><mark>### Title</mark></td>
<td>Heading level three. The space after the # is mandatory.</td>
</tr>
<tr>
<td><mark>#### Title</mark></td>
<td>Heading level four. The space after the # is mandatory.</td>
</tr>
<tr>
<td><mark>**text**</mark></td>
<td>The text is renderred as bold text.</td>
</tr>
<tr>
<td><mark>_text_</mark></td>
<td>The text is renderred as italics text.</td>
</tr>
<tr>
<td><mark>__text__</mark></td>
<td>The text is renderred as underlined text.</td>
</tr>
<tr>
<td><mark>% text...</mark></td>
<td>A comment. The text is not exported, seen in viewer, or counted towards word counts.</td>
</tr>
<tr>
<td><mark>@command: value</mark></td>
<td>A command followed by a value, or a comma separated list of values.</td>
</tr>
</table>
<a name="GUI_Shortcuts"></a>
<h3>5.2 Keyboard Shortcuts</h3>
<p><a href="#Content">Back to top</a></p>
<p>All features are available as keyboard shortcuts. These are as following:</p>
<table>
<tr>
<td><mark>Ctrl+Shift+O</mark></td>
<td>Open a project.</td>
</tr>
<tr>
<td><mark>Ctrl+Shift+S</mark></td>
<td>Save the current project.</td>
</tr>
<tr>
<td><mark>Ctrl+Shift+W</mark></td>
<td>Close the current project.</td>
</tr>
<tr>
<td><mark>Ctrl+Shift+,</mark></td>
<td>Change project settings.</td>
</tr>
<tr>
<td><mark>Ctrl+Shift+N</mark></td>
<td>Create new folder.</td>
</tr>
<tr>
<td><mark>Ctrl+E, F2</mark></td>
<td>If in tree view, edit a document or folder settings.</td>
</tr>
<tr>
<td><mark>Ctrl+Del</mark></td>
<td>If in tree view, move a document to trash, or delete a folder.</td>
</tr>
<tr>
<td><mark>Ctrl+Q</mark></td>
<td>Exit novelWriter.</td>
</tr>
<tr>
<td><mark>Ctrl+N</mark></td>
<td>Create new document.</td>
</tr>
<tr>
<td><mark>Ctrl+O</mark></td>
<td>Open selected document.</td>
</tr>
<tr>
<td><mark>Return</mark></td>
<td>If in tree view, open a document for editing.</td>
</tr>
<tr>
<td><mark>Ctrl+S</mark></td>
<td>Save the current document in the editor.</td>
</tr>
<tr>
<td><mark>Ctrl+W</mark></td>
<td>Close the current document in the editor.</td>
</tr>
<tr>
<td><mark>Ctrl+R</mark></td>
<td>If in tree view, open a document for viewing. If in editor pane, open current document for viewing.</td>
</tr>
<tr>
<td><mark>Ctrl+Shift+R</mark></td>
<td>Close the document view pane.</td>
</tr>
<tr>
<td><mark>Ctrl+Z</mark></td>
<td>Undo latest changes.</td>
</tr>
<tr>
<td><mark>Ctrl+Y</mark></td>
<td>Redo latest undo.</td>
</tr>
<tr>
<td><mark>Ctrl+C</mark></td>
<td>Copy selected text to clipboard.</td>
</tr>
<tr>
<td><mark>Ctrl+X</mark></td>
<td>Cut selected text to clipboard.</td>
</tr>
<tr>
<td><mark>Ctrl+V</mark></td>
<td>Paste text from clipboard to cursor position.</td>
</tr>
<tr>
<td><mark>Ctrl+A</mark></td>
<td>Select all text in document.</td>
</tr>
<tr>
<td><mark>Ctrl+Shift+A</mark></td>
<td>Select all text in current paragraph.</td>
</tr>
<tr>
<td><mark>Ctrl+1</mark></td>
<td>Switch focus to tree view pane.</td>
</tr>
<tr>
<td><mark>Ctrl+2</mark></td>
<td>Switch focus to document editor pane.</td>
</tr>
<tr>
<td><mark>Ctrl+3</mark></td>
<td>Switch focus to document viewer pane.</td>
</tr>
<tr>
<td><mark>Ctrl+T</mark></td>
<td>Show project timeline.</td>
</tr>
<tr>
<td><mark>Ctrl+B</mark></td>
<td>Format selected text, or word under cursor, as bold.</td>
</tr>
<tr>
<td><mark>Ctrl+I</mark></td>
<td>Format selected text, or word under cursor, as italic.</td>
</tr>
<tr>
<td><mark>Ctrl+U</mark></td>
<td>Format selected text, or word under cursor, as underline.</td>
</tr>
<tr>
<td><mark>Ctrl+D</mark></td>
<td>Wrap selected text, or word under cursor, in double quotes.</td>
</tr>
<tr>
<td><mark>Ctrl+Shift+D</mark></td>
<td>Wrap selected text, or word under cursor, in single quotes.</td>
</tr>
<tr>
<td><mark>Ctrl+Shift+Up</mark></td>
<td>Move item one step up in the tree view.</td>
</tr>
<tr>
<td><mark>Ctrl+Shift+Down</mark></td>
<td>Move item one step down in the tree view.</td>
</tr>
<tr>
<td><mark>Ctrl+F7</mark></td>
<td>Toggle spell checking.</td>
</tr>
<tr>
<td><mark>F7</mark></td>
<td>Re-run spell checker.</td>
</tr>
<tr>
<td><mark>Ctrl+.</mark></td>
<td>Correct word under cursor.</td>
</tr>
<tr>
<td><mark>F9</mark></td>
<td>Re-build project indices.</td>
</tr>
<tr>
<td><mark>F1</mark></td>
<td>Open documentation.</td>
</tr>
</table>
<a name="Code"></a>
<h2>6. Technical Information</h2>
<p><a href="#Content">Back to top</a></p>
<p>This section contains details of how novelWriter stores and handles the project data.</p>
<a name="Code_Project"></a>
<h3>6.1 How Data is Stored</h3>
<p><a href="#Content">Back to top</a></p>
<h4>Main Project File</h4>
<p>The project itself requires a dedicated folder for storing its files. The main project file
is stored as an XML file with the name <mark>nwProject.nwx</mark>. This file contains all
the meta data unique for the project. That includes project settings.</p>
<p>If this file is lost or corrupted, the structure of the project is lost. It is important to
keep this file backed up.</p>
<p>The project XML file is suitable for diff tools and version control, although a timesetamp is
set in the meta section on line 2 each time the file is saved.</p>
<h4>Project Documents</h4>
<p>The project documents are saved in folders staring with <mark>data_</mark>. Each document has
a file handle taken from the first 13 characters of a SHA256 hash of the system time. the
documents are saved with a folder and filename derived from this hash.</p>
<p>The reason for this is to avoid issues with file naming conventions and restrictions. The
file name set in the tree view is only saved in the project XML file.</p>
<p>Each document file contains a plain text version of the text from the editor. The file can in
principle be edited in any text editor, and is suitable for diffing and version control if
so desired.</p>
</body>
</html>
+1
View File
@@ -104,6 +104,7 @@ class Config:
self.homePath = path.expanduser("~")
self.appPath = path.dirname(__file__)
self.appRoot = path.join(self.appPath,path.pardir)
self.helpPath = path.join(self.appRoot,"help","en_GB")
self.guiPath = path.join(self.appPath,"gui")
self.themePath = path.join(self.appPath,"themes")
+47 -9
View File
@@ -20,6 +20,7 @@ from PyQt5.QtCore import Qt, QTimer
from PyQt5.QtWidgets import QTextEdit, QAction, QMenu, QShortcut
from PyQt5.QtGui import QTextCursor, QTextOption, QIcon, QKeySequence
from nw.project.document import NWDoc
from nw.gui.dochighlight import GuiDocHighlighter
from nw.gui.wordcounter import WordCounter
from nw.enum import nwDocAction, nwAlert
@@ -28,7 +29,7 @@ logger = logging.getLogger(__name__)
class GuiDocEditor(QTextEdit):
def __init__(self, theParent):
def __init__(self, theParent, theProject):
QTextEdit.__init__(self)
logger.debug("Initialising DocEditor ...")
@@ -36,10 +37,12 @@ class GuiDocEditor(QTextEdit):
# Class Variables
self.mainConf = nw.CONFIG
self.theParent = theParent
self.theProject = theProject
self.docChanged = False
self.pwlFile = None
self.spellCheck = False
self.theDocument = theParent.theDocument
self.theDocument = NWDoc(self.theProject, self.theParent)
self.theHandle = None
# Document Variables
self.charCount = 0
@@ -69,9 +72,6 @@ class GuiDocEditor(QTextEdit):
self.setMinimumWidth(300)
self.setAcceptRichText(False)
self.clearEditor()
self.initEditor()
self.theQDoc.setDocumentMargin(0)
self.theQDoc.contentsChange.connect(self._docChange)
@@ -87,13 +87,29 @@ class GuiDocEditor(QTextEdit):
self.wCounter = WordCounter(self)
self.wCounter.finished.connect(self._updateCounts)
self.clearEditor()
self.initEditor()
logger.debug("DocEditor initialisation complete")
return
def clearEditor(self):
self.theDocument.clearDocument()
self.setReadOnly(True)
self.clear()
self.wcTimer.stop()
self.theHandle = None
self.charCount = 0
self.wordCount = 0
self.paraCount = 0
self.lastEdit = 0
self.hasSelection = False
self.setDocumentChanged(False)
return True
def initEditor(self):
@@ -114,6 +130,7 @@ class GuiDocEditor(QTextEdit):
return True
def loadText(self, tHandle):
self.hLight.setHandle(tHandle)
self.setPlainText(self.theDocument.openDocument(tHandle))
self.setCursorPosition(self.theDocument.theItem.cursorPos)
@@ -122,6 +139,27 @@ class GuiDocEditor(QTextEdit):
self.wcTimer.start()
self.setDocumentChanged(False)
self.setReadOnly(False)
self.theHandle = tHandle
return True
def saveText(self):
if self.theDocument.theItem is None:
return False
docText = self.getText()
cursPos = self.getCursorPosition()
theItem = self.theDocument.theItem
theItem.setCharCount(self.charCount)
theItem.setWordCount(self.wordCount)
theItem.setParaCount(self.paraCount)
theItem.setCursorPos(cursPos)
self.theDocument.saveDocument(docText)
self.setDocumentChanged(False)
self.theParent.theIndex.scanText(theItem.itemHandle, docText)
return True
##
@@ -381,7 +419,7 @@ class GuiDocEditor(QTextEdit):
"""
logger.verbose("Updating word count")
tHandle = self.theParent.theDocument.docHandle
tHandle = self.theDocument.docHandle
self.charCount = self.wCounter.charCount
self.wordCount = self.wCounter.wordCount
self.paraCount = self.wCounter.paraCount
@@ -392,9 +430,9 @@ class GuiDocEditor(QTextEdit):
return
def _wrapSelection(self, tBefore, tAfter):
"""Wraps the selected text in whatever is in tBefore and tAfter. If there is no selection, the autoSelect setting decides
the action. AutoSelect will select the word under the cursor before wrapping it. If this feature is disabled, nothing is
done.
"""Wraps the selected text in whatever is in tBefore and tAfter. If there is no selection,
the autoSelect setting decides the action. AutoSelect will select the word under the cursor
before wrapping it. If this feature is disabled, nothing is done.
"""
theCursor = self.textCursor()
if self.mainConf.autoSelect and not theCursor.hasSelection():
+97 -9
View File
@@ -13,34 +13,76 @@
import logging
import nw
from PyQt5.QtCore import Qt
from PyQt5.QtCore import Qt, QUrl
from PyQt5.QtWidgets import QTextBrowser
from PyQt5.QtGui import QTextOption
from nw.convert.tokenizer import Tokenizer
from nw.convert.tohtml import ToHtml
from nw.enum import nwItemType
logger = logging.getLogger(__name__)
class GuiDocViewer(QTextBrowser):
def __init__(self, theParent):
def __init__(self, theParent, theProject):
QTextBrowser.__init__(self)
logger.debug("Initialising DocViewer ...")
# Class Variables
self.mainConf = nw.CONFIG
self.theParent = theParent
self.theTheme = theParent.theTheme
self.mainConf = nw.CONFIG
self.theProject = theProject
self.theParent = theParent
self.theTheme = theParent.theTheme
self.theHandle = None
self.theQDoc = self.document()
self.theQDoc.setDefaultStyleSheet((
"body {{"
" font-size: {textSize}pt;"
" color: rgb({tColR},{tColG},{tColB});"
"}}\n"
"h1, h2, h3, h4 {{"
" color: rgb({0},{1},{2});"
"}}"
" color: rgb({hColR},{hColG},{hColB});"
"}}\n"
"a {{"
" color: rgb({aColR},{aColG},{aColB});"
"}}\n"
"pre {{"
" color: rgb({cColR},{cColG},{cColB});"
" font-size: {preSize}pt;"
"}}\n"
"mark {{"
" color: rgb({eColR},{eColG},{eColB});"
"}}\n"
"table {{"
" margin: 10px 0px;"
"}}\n"
"td {{"
" padding: 0px 4px;"
"}}\n"
).format(
*self.theTheme.colHead
textSize = self.mainConf.textSize,
preSize = self.mainConf.textSize*0.9,
tColR = self.theTheme.colText[0],
tColG = self.theTheme.colText[1],
tColB = self.theTheme.colText[2],
hColR = self.theTheme.colHead[0],
hColG = self.theTheme.colHead[1],
hColB = self.theTheme.colHead[2],
cColR = self.theTheme.colComm[0],
cColG = self.theTheme.colComm[1],
cColB = self.theTheme.colComm[2],
eColR = self.theTheme.colEmph[0],
eColG = self.theTheme.colEmph[1],
eColB = self.theTheme.colEmph[2],
aColR = self.theTheme.colLink[0],
aColG = self.theTheme.colLink[1],
aColB = self.theTheme.colLink[2],
))
self.theQDoc.setDocumentMargin(self.mainConf.textMargin[0])
self.setMinimumWidth(300)
self.initEditor()
theOpt = QTextOption()
if self.mainConf.doJustify:
@@ -53,6 +95,52 @@ class GuiDocViewer(QTextBrowser):
def clearViewer(self):
self.clear()
self.setSearchPaths([""])
return True
def initEditor(self):
"""Set editor settings from mani config.
"""
self.theQDoc.setDocumentMargin(self.mainConf.textMargin[0])
theOpt = QTextOption()
if self.mainConf.doJustify:
theOpt.setAlignment(Qt.AlignJustify)
self.theQDoc.setDefaultTextOption(theOpt)
return True
def loadText(self, tHandle):
if tHandle == "Help":
self.loadHelp()
return True
tItem = self.theProject.getItem(tHandle)
if tItem is None:
logger.warning("Item not found")
return False
if tItem.itemType != nwItemType.FILE:
return False
logger.debug("Generating preview for item %s" % tHandle)
aDoc = ToHtml(self.theProject, self.theParent)
aDoc.setText(tHandle)
aDoc.doAutoReplace()
aDoc.tokenizeText()
aDoc.doConvert()
self.setHtml(aDoc.theResult)
self.theHandle = tHandle
self.theProject.setLastViewed(tHandle)
return True
def loadHelp(self):
self.clearViewer()
self.setSearchPaths([self.mainConf.helpPath])
self.setSource(QUrl("index.html"))
return True
# END Class GuiDocViewer
+10
View File
@@ -516,6 +516,16 @@ class GuiMainMenu(QMenuBar):
menuItem.triggered.connect(self._showAboutQt)
self.helpMenu.addAction(menuItem)
# Help > Separator
self.helpMenu.addSeparator()
# Document > Preview
menuItem = QAction(QIcon.fromTheme("text-html"), "Documentation", self)
menuItem.setStatusTip("View documentation")
menuItem.setShortcut("F1")
menuItem.triggered.connect(lambda : self.theParent.viewDocument("Help"))
self.helpMenu.addAction(menuItem)
return
# END Class GuiMainMenu
+11 -38
View File
@@ -35,8 +35,6 @@ from nw.project.project import NWProject
from nw.project.document import NWDoc
from nw.project.item import NWItem
from nw.project.index import NWIndex
from nw.convert.tokenizer import Tokenizer
from nw.convert.tohtml import ToHtml
from nw.tools.wordcount import countWords
from nw.theme import Theme
from nw.enum import nwItemType, nwAlert
@@ -53,7 +51,6 @@ class GuiMain(QMainWindow):
self.mainConf = nw.CONFIG
self.theTheme = Theme()
self.theProject = NWProject(self)
self.theDocument = NWDoc(self.theProject, self)
self.theIndex = NWIndex(self.theProject, self)
self.hasProject = False
@@ -63,12 +60,12 @@ class GuiMain(QMainWindow):
self.theTheme.loadTheme()
# Main GUI Elements
self.docEditor = GuiDocEditor(self)
self.docViewer = GuiDocViewer(self)
self.statusBar = GuiMainStatus(self)
self.docEditor = GuiDocEditor(self, self.theProject)
self.docViewer = GuiDocViewer(self, self.theProject)
self.docDetails = GuiDocDetails(self, self.theProject)
self.treeView = GuiDocTree(self, self.theProject)
self.mainMenu = GuiMainMenu(self, self.theProject)
self.statusBar = GuiMainStatus(self)
# Minor Gui Elements
self.statusIcons = []
@@ -284,7 +281,6 @@ class GuiMain(QMainWindow):
if self.hasProject:
if self.docEditor.docChanged:
self.saveDocument()
self.theDocument.clearDocument()
self.docEditor.clearEditor()
return True
@@ -298,17 +294,8 @@ class GuiMain(QMainWindow):
return True
def saveDocument(self):
if self.theDocument.theItem is not None and self.hasProject:
docText = self.docEditor.getText()
cursPos = self.docEditor.getCursorPosition()
theItem = self.theDocument.theItem
theItem.setCharCount(self.docEditor.charCount)
theItem.setWordCount(self.docEditor.wordCount)
theItem.setParaCount(self.docEditor.paraCount)
theItem.setCursorPos(cursPos)
self.theDocument.saveDocument(docText)
self.docEditor.setDocumentChanged(False)
self.theIndex.scanText(theItem.itemHandle, docText)
if self.hasProject:
self.docEditor.saveText()
return True
def viewDocument(self, tHandle=None):
@@ -316,30 +303,16 @@ class GuiMain(QMainWindow):
if tHandle is None:
tHandle = self.treeView.getSelectedHandle()
if tHandle is None:
logger.warning("No document selected, trying last viewed")
logger.debug("No document selected, trying last viewed")
tHandle = self.theProject.lastViewed
if tHandle is None:
logger.warning("No document selected, trying editor document")
tHandle = self.theDocument.docHandle
logger.debug("No document selected, trying editor document")
tHandle = self.docEditor.theHandle
if tHandle is None:
logger.warning("No document selected, giving up")
logger.debug("No document selected, giving up")
return False
tItem = self.theProject.getItem(tHandle)
if tItem is None:
logger.warning("Item not found")
return False
if tItem.itemType == nwItemType.FILE:
logger.debug("Generating preview for item %s" % tHandle)
aDoc = ToHtml(self.theProject, self)
aDoc.setText(tHandle)
aDoc.doAutoReplace()
aDoc.tokenizeText()
aDoc.doConvert()
self.docViewer.setHtml(aDoc.theResult)
self.theProject.setLastViewed(tHandle)
if self.docViewer.loadText(tHandle):
bPos = self.splitMain.sizes()
self.docViewer.setVisible(True)
vPos = [0,0]
@@ -596,7 +569,7 @@ class GuiMain(QMainWindow):
return
def _autoSaveDocument(self):
if self.hasProject and self.docEditor.docChanged and self.theDocument.theItem is not None:
if self.hasProject and self.docEditor.docChanged:
logger.debug("Autosaving document")
self.saveDocument()
return
+2
View File
@@ -86,6 +86,8 @@ class Theme:
## Syntax
cnfSec = "Syntax"
if confParser.has_section(cnfSec):
self.colText = self._loadColour(confParser,cnfSec,"text")
self.colLink = self._loadColour(confParser,cnfSec,"link")
self.colHead = self._loadColour(confParser,cnfSec,"headertext")
self.colHeadH = self._loadColour(confParser,cnfSec,"headertag")
self.colEmph = self._loadColour(confParser,cnfSec,"emphasis")
-1
View File
@@ -10,7 +10,6 @@ QTextEdit {
QTextBrowser {
background-color: #141414;
color: #c7cfd0;
/* padding: 40px; */
}
QTreeView, QHeaderView {
+2
View File
@@ -1,4 +1,6 @@
[Syntax]
text = 199, 207, 208
link = 184, 200, 0
headertext = 0, 155, 200
headertag = 0, 105, 135
emphasis = 200, 120, 0