@@ -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>
|
||||||
@@ -104,6 +104,7 @@ class Config:
|
|||||||
self.homePath = path.expanduser("~")
|
self.homePath = path.expanduser("~")
|
||||||
self.appPath = path.dirname(__file__)
|
self.appPath = path.dirname(__file__)
|
||||||
self.appRoot = path.join(self.appPath,path.pardir)
|
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.guiPath = path.join(self.appPath,"gui")
|
||||||
self.themePath = path.join(self.appPath,"themes")
|
self.themePath = path.join(self.appPath,"themes")
|
||||||
|
|
||||||
|
|||||||
+47
-9
@@ -20,6 +20,7 @@ from PyQt5.QtCore import Qt, QTimer
|
|||||||
from PyQt5.QtWidgets import QTextEdit, QAction, QMenu, QShortcut
|
from PyQt5.QtWidgets import QTextEdit, QAction, QMenu, QShortcut
|
||||||
from PyQt5.QtGui import QTextCursor, QTextOption, QIcon, QKeySequence
|
from PyQt5.QtGui import QTextCursor, QTextOption, QIcon, QKeySequence
|
||||||
|
|
||||||
|
from nw.project.document import NWDoc
|
||||||
from nw.gui.dochighlight import GuiDocHighlighter
|
from nw.gui.dochighlight import GuiDocHighlighter
|
||||||
from nw.gui.wordcounter import WordCounter
|
from nw.gui.wordcounter import WordCounter
|
||||||
from nw.enum import nwDocAction, nwAlert
|
from nw.enum import nwDocAction, nwAlert
|
||||||
@@ -28,7 +29,7 @@ logger = logging.getLogger(__name__)
|
|||||||
|
|
||||||
class GuiDocEditor(QTextEdit):
|
class GuiDocEditor(QTextEdit):
|
||||||
|
|
||||||
def __init__(self, theParent):
|
def __init__(self, theParent, theProject):
|
||||||
QTextEdit.__init__(self)
|
QTextEdit.__init__(self)
|
||||||
|
|
||||||
logger.debug("Initialising DocEditor ...")
|
logger.debug("Initialising DocEditor ...")
|
||||||
@@ -36,10 +37,12 @@ class GuiDocEditor(QTextEdit):
|
|||||||
# Class Variables
|
# Class Variables
|
||||||
self.mainConf = nw.CONFIG
|
self.mainConf = nw.CONFIG
|
||||||
self.theParent = theParent
|
self.theParent = theParent
|
||||||
|
self.theProject = theProject
|
||||||
self.docChanged = False
|
self.docChanged = False
|
||||||
self.pwlFile = None
|
self.pwlFile = None
|
||||||
self.spellCheck = False
|
self.spellCheck = False
|
||||||
self.theDocument = theParent.theDocument
|
self.theDocument = NWDoc(self.theProject, self.theParent)
|
||||||
|
self.theHandle = None
|
||||||
|
|
||||||
# Document Variables
|
# Document Variables
|
||||||
self.charCount = 0
|
self.charCount = 0
|
||||||
@@ -69,9 +72,6 @@ class GuiDocEditor(QTextEdit):
|
|||||||
self.setMinimumWidth(300)
|
self.setMinimumWidth(300)
|
||||||
self.setAcceptRichText(False)
|
self.setAcceptRichText(False)
|
||||||
|
|
||||||
self.clearEditor()
|
|
||||||
self.initEditor()
|
|
||||||
|
|
||||||
self.theQDoc.setDocumentMargin(0)
|
self.theQDoc.setDocumentMargin(0)
|
||||||
self.theQDoc.contentsChange.connect(self._docChange)
|
self.theQDoc.contentsChange.connect(self._docChange)
|
||||||
|
|
||||||
@@ -87,13 +87,29 @@ class GuiDocEditor(QTextEdit):
|
|||||||
self.wCounter = WordCounter(self)
|
self.wCounter = WordCounter(self)
|
||||||
self.wCounter.finished.connect(self._updateCounts)
|
self.wCounter.finished.connect(self._updateCounts)
|
||||||
|
|
||||||
|
self.clearEditor()
|
||||||
|
self.initEditor()
|
||||||
|
|
||||||
logger.debug("DocEditor initialisation complete")
|
logger.debug("DocEditor initialisation complete")
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
def clearEditor(self):
|
def clearEditor(self):
|
||||||
|
|
||||||
|
self.theDocument.clearDocument()
|
||||||
self.setReadOnly(True)
|
self.setReadOnly(True)
|
||||||
self.clear()
|
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
|
return True
|
||||||
|
|
||||||
def initEditor(self):
|
def initEditor(self):
|
||||||
@@ -114,6 +130,7 @@ class GuiDocEditor(QTextEdit):
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
def loadText(self, tHandle):
|
def loadText(self, tHandle):
|
||||||
|
|
||||||
self.hLight.setHandle(tHandle)
|
self.hLight.setHandle(tHandle)
|
||||||
self.setPlainText(self.theDocument.openDocument(tHandle))
|
self.setPlainText(self.theDocument.openDocument(tHandle))
|
||||||
self.setCursorPosition(self.theDocument.theItem.cursorPos)
|
self.setCursorPosition(self.theDocument.theItem.cursorPos)
|
||||||
@@ -122,6 +139,27 @@ class GuiDocEditor(QTextEdit):
|
|||||||
self.wcTimer.start()
|
self.wcTimer.start()
|
||||||
self.setDocumentChanged(False)
|
self.setDocumentChanged(False)
|
||||||
self.setReadOnly(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
|
return True
|
||||||
|
|
||||||
##
|
##
|
||||||
@@ -381,7 +419,7 @@ class GuiDocEditor(QTextEdit):
|
|||||||
"""
|
"""
|
||||||
logger.verbose("Updating word count")
|
logger.verbose("Updating word count")
|
||||||
|
|
||||||
tHandle = self.theParent.theDocument.docHandle
|
tHandle = self.theDocument.docHandle
|
||||||
self.charCount = self.wCounter.charCount
|
self.charCount = self.wCounter.charCount
|
||||||
self.wordCount = self.wCounter.wordCount
|
self.wordCount = self.wCounter.wordCount
|
||||||
self.paraCount = self.wCounter.paraCount
|
self.paraCount = self.wCounter.paraCount
|
||||||
@@ -392,9 +430,9 @@ class GuiDocEditor(QTextEdit):
|
|||||||
return
|
return
|
||||||
|
|
||||||
def _wrapSelection(self, tBefore, tAfter):
|
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
|
"""Wraps the selected text in whatever is in tBefore and tAfter. If there is no selection,
|
||||||
the action. AutoSelect will select the word under the cursor before wrapping it. If this feature is disabled, nothing is
|
the autoSelect setting decides the action. AutoSelect will select the word under the cursor
|
||||||
done.
|
before wrapping it. If this feature is disabled, nothing is done.
|
||||||
"""
|
"""
|
||||||
theCursor = self.textCursor()
|
theCursor = self.textCursor()
|
||||||
if self.mainConf.autoSelect and not theCursor.hasSelection():
|
if self.mainConf.autoSelect and not theCursor.hasSelection():
|
||||||
|
|||||||
+97
-9
@@ -13,34 +13,76 @@
|
|||||||
import logging
|
import logging
|
||||||
import nw
|
import nw
|
||||||
|
|
||||||
from PyQt5.QtCore import Qt
|
from PyQt5.QtCore import Qt, QUrl
|
||||||
from PyQt5.QtWidgets import QTextBrowser
|
from PyQt5.QtWidgets import QTextBrowser
|
||||||
from PyQt5.QtGui import QTextOption
|
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__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
class GuiDocViewer(QTextBrowser):
|
class GuiDocViewer(QTextBrowser):
|
||||||
|
|
||||||
def __init__(self, theParent):
|
def __init__(self, theParent, theProject):
|
||||||
QTextBrowser.__init__(self)
|
QTextBrowser.__init__(self)
|
||||||
|
|
||||||
logger.debug("Initialising DocViewer ...")
|
logger.debug("Initialising DocViewer ...")
|
||||||
|
|
||||||
# Class Variables
|
# Class Variables
|
||||||
self.mainConf = nw.CONFIG
|
self.mainConf = nw.CONFIG
|
||||||
self.theParent = theParent
|
self.theProject = theProject
|
||||||
self.theTheme = theParent.theTheme
|
self.theParent = theParent
|
||||||
|
self.theTheme = theParent.theTheme
|
||||||
|
self.theHandle = None
|
||||||
|
|
||||||
self.theQDoc = self.document()
|
self.theQDoc = self.document()
|
||||||
self.theQDoc.setDefaultStyleSheet((
|
self.theQDoc.setDefaultStyleSheet((
|
||||||
|
"body {{"
|
||||||
|
" font-size: {textSize}pt;"
|
||||||
|
" color: rgb({tColR},{tColG},{tColB});"
|
||||||
|
"}}\n"
|
||||||
"h1, h2, h3, h4 {{"
|
"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(
|
).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.setMinimumWidth(300)
|
||||||
|
self.initEditor()
|
||||||
|
|
||||||
theOpt = QTextOption()
|
theOpt = QTextOption()
|
||||||
if self.mainConf.doJustify:
|
if self.mainConf.doJustify:
|
||||||
@@ -53,6 +95,52 @@ class GuiDocViewer(QTextBrowser):
|
|||||||
|
|
||||||
def clearViewer(self):
|
def clearViewer(self):
|
||||||
self.clear()
|
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
|
return True
|
||||||
|
|
||||||
# END Class GuiDocViewer
|
# END Class GuiDocViewer
|
||||||
|
|||||||
@@ -516,6 +516,16 @@ class GuiMainMenu(QMenuBar):
|
|||||||
menuItem.triggered.connect(self._showAboutQt)
|
menuItem.triggered.connect(self._showAboutQt)
|
||||||
self.helpMenu.addAction(menuItem)
|
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
|
return
|
||||||
|
|
||||||
# END Class GuiMainMenu
|
# END Class GuiMainMenu
|
||||||
|
|||||||
+11
-38
@@ -35,8 +35,6 @@ from nw.project.project import NWProject
|
|||||||
from nw.project.document import NWDoc
|
from nw.project.document import NWDoc
|
||||||
from nw.project.item import NWItem
|
from nw.project.item import NWItem
|
||||||
from nw.project.index import NWIndex
|
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.tools.wordcount import countWords
|
||||||
from nw.theme import Theme
|
from nw.theme import Theme
|
||||||
from nw.enum import nwItemType, nwAlert
|
from nw.enum import nwItemType, nwAlert
|
||||||
@@ -53,7 +51,6 @@ class GuiMain(QMainWindow):
|
|||||||
self.mainConf = nw.CONFIG
|
self.mainConf = nw.CONFIG
|
||||||
self.theTheme = Theme()
|
self.theTheme = Theme()
|
||||||
self.theProject = NWProject(self)
|
self.theProject = NWProject(self)
|
||||||
self.theDocument = NWDoc(self.theProject, self)
|
|
||||||
self.theIndex = NWIndex(self.theProject, self)
|
self.theIndex = NWIndex(self.theProject, self)
|
||||||
self.hasProject = False
|
self.hasProject = False
|
||||||
|
|
||||||
@@ -63,12 +60,12 @@ class GuiMain(QMainWindow):
|
|||||||
self.theTheme.loadTheme()
|
self.theTheme.loadTheme()
|
||||||
|
|
||||||
# Main GUI Elements
|
# Main GUI Elements
|
||||||
self.docEditor = GuiDocEditor(self)
|
self.statusBar = GuiMainStatus(self)
|
||||||
self.docViewer = GuiDocViewer(self)
|
self.docEditor = GuiDocEditor(self, self.theProject)
|
||||||
|
self.docViewer = GuiDocViewer(self, self.theProject)
|
||||||
self.docDetails = GuiDocDetails(self, self.theProject)
|
self.docDetails = GuiDocDetails(self, self.theProject)
|
||||||
self.treeView = GuiDocTree(self, self.theProject)
|
self.treeView = GuiDocTree(self, self.theProject)
|
||||||
self.mainMenu = GuiMainMenu(self, self.theProject)
|
self.mainMenu = GuiMainMenu(self, self.theProject)
|
||||||
self.statusBar = GuiMainStatus(self)
|
|
||||||
|
|
||||||
# Minor Gui Elements
|
# Minor Gui Elements
|
||||||
self.statusIcons = []
|
self.statusIcons = []
|
||||||
@@ -284,7 +281,6 @@ class GuiMain(QMainWindow):
|
|||||||
if self.hasProject:
|
if self.hasProject:
|
||||||
if self.docEditor.docChanged:
|
if self.docEditor.docChanged:
|
||||||
self.saveDocument()
|
self.saveDocument()
|
||||||
self.theDocument.clearDocument()
|
|
||||||
self.docEditor.clearEditor()
|
self.docEditor.clearEditor()
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@@ -298,17 +294,8 @@ class GuiMain(QMainWindow):
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
def saveDocument(self):
|
def saveDocument(self):
|
||||||
if self.theDocument.theItem is not None and self.hasProject:
|
if self.hasProject:
|
||||||
docText = self.docEditor.getText()
|
self.docEditor.saveText()
|
||||||
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)
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def viewDocument(self, tHandle=None):
|
def viewDocument(self, tHandle=None):
|
||||||
@@ -316,30 +303,16 @@ class GuiMain(QMainWindow):
|
|||||||
if tHandle is None:
|
if tHandle is None:
|
||||||
tHandle = self.treeView.getSelectedHandle()
|
tHandle = self.treeView.getSelectedHandle()
|
||||||
if tHandle is None:
|
if tHandle is None:
|
||||||
logger.warning("No document selected, trying last viewed")
|
logger.debug("No document selected, trying last viewed")
|
||||||
tHandle = self.theProject.lastViewed
|
tHandle = self.theProject.lastViewed
|
||||||
if tHandle is None:
|
if tHandle is None:
|
||||||
logger.warning("No document selected, trying editor document")
|
logger.debug("No document selected, trying editor document")
|
||||||
tHandle = self.theDocument.docHandle
|
tHandle = self.docEditor.theHandle
|
||||||
if tHandle is None:
|
if tHandle is None:
|
||||||
logger.warning("No document selected, giving up")
|
logger.debug("No document selected, giving up")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
tItem = self.theProject.getItem(tHandle)
|
if self.docViewer.loadText(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)
|
|
||||||
|
|
||||||
bPos = self.splitMain.sizes()
|
bPos = self.splitMain.sizes()
|
||||||
self.docViewer.setVisible(True)
|
self.docViewer.setVisible(True)
|
||||||
vPos = [0,0]
|
vPos = [0,0]
|
||||||
@@ -596,7 +569,7 @@ class GuiMain(QMainWindow):
|
|||||||
return
|
return
|
||||||
|
|
||||||
def _autoSaveDocument(self):
|
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")
|
logger.debug("Autosaving document")
|
||||||
self.saveDocument()
|
self.saveDocument()
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -86,6 +86,8 @@ class Theme:
|
|||||||
## Syntax
|
## Syntax
|
||||||
cnfSec = "Syntax"
|
cnfSec = "Syntax"
|
||||||
if confParser.has_section(cnfSec):
|
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.colHead = self._loadColour(confParser,cnfSec,"headertext")
|
||||||
self.colHeadH = self._loadColour(confParser,cnfSec,"headertag")
|
self.colHeadH = self._loadColour(confParser,cnfSec,"headertag")
|
||||||
self.colEmph = self._loadColour(confParser,cnfSec,"emphasis")
|
self.colEmph = self._loadColour(confParser,cnfSec,"emphasis")
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ QTextEdit {
|
|||||||
QTextBrowser {
|
QTextBrowser {
|
||||||
background-color: #141414;
|
background-color: #141414;
|
||||||
color: #c7cfd0;
|
color: #c7cfd0;
|
||||||
/* padding: 40px; */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QTreeView, QHeaderView {
|
QTreeView, QHeaderView {
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
[Syntax]
|
[Syntax]
|
||||||
|
text = 199, 207, 208
|
||||||
|
link = 184, 200, 0
|
||||||
headertext = 0, 155, 200
|
headertext = 0, 155, 200
|
||||||
headertag = 0, 105, 135
|
headertag = 0, 105, 135
|
||||||
emphasis = 200, 120, 0
|
emphasis = 200, 120, 0
|
||||||
|
|||||||
Reference in New Issue
Block a user