1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310
|
<!-- vim:tabstop=4:shiftwidth=4:noexpandtab:textwidth=80
-->
<chapter id="general_layers_ch">
<title>PDFedit layers</title>
<para>
PDFEdit project is based on 3 layers model:
<mediaobject>
<imageobject align="center">
<imagedata fileref="images/layers.png" format="PNG"/>
</imageobject>
<caption><para>PDFedit layers</para></caption>
</mediaobject>
<itemizedlist>
<listitem>Kernel - which has responsibility to maintain pdf
document content and provides interface for changes.
</listitem>
<listitem>Script - which has responsibility to wrap kernel
interface and export it to user or gui.
</listitem>
<listitem>Gui - which visualizes and makes comfortable usage of
all the functionality which is accessible directly from
kernel or Script layers.
</listitem>
</itemizedlist>
</para>
<para>
Kernel layer is build on top of popular open source &xpdf_link_index;
project (see <xref linkend="general_xpdf_chapter"/>).
It reuses xpdf code for low-level pdf document access - reading
and decoding content and parsing it to objects as well as
displaying functionality. Xpdf objects are transformed to
interface internal pdfedit objects which provides additional
logic and as such they are exported to higher layers.
</para>
<para>
Script layer is based on &qsa_link_index; - Qt script for applications,
scripting language based on <xref linkend="ecmascript"/>, developed by Trolltech.
</para>
<para>
Gui layer uses &qt_link_index; framework also developed by Trolltech.
Most of gui parts are based on scripts, which means that user interface
is very flexible and changes are possible without need of code
recompilation, most changes can be done even in runtime.
</para>
<para>
This chapter describes PDFedit layers, their comunication interface and
responsibilities.
</para>
<sect1 id="general_kernel_layer">
<title>Kernel layer</title>
<para>
Kernel, as the lowest layer, is responsible for maintaing of pdf content from
file and to provide object interface for making changes to higher layer.
We will call this objects as <emphasis>cobjects</emphasis>. More
precisely - <emphasis>highlevel</emphasis> cobjects (CPdf, CPage, etc.) which provide higher
pdf entities logic and <emphasis>lowlevel</emphasis> cobjects which are pdf data types carrier
(CInt, CArray, CDict, CString, etc.). Values stored in lowlevel cobjects
are also called <emphasis>properties</emphasis> and they are wrapped
by <classname>IProperty</classname> class.
Properties are identified by indirect reference (the way how pdf
adresses entities).
User of kernel should start with CPdf instance which provides all
properties from document as well as access to document pages or
outlines. Pages then provide access to Annotations. All cobjects are
returned wrapped by shared_ptr (see <xref linkend="general_techn"/>).
</para>
<para>
Kernel uses &xpdf_link_index; code for document content parsing.
XPdf's <classname>XRef</classname> class provides fetching and parsing functionality.
Oposite way (from cobjects to file writing) is provided by
<classname>IPdfWriter</classname>
implementation. XPdf Stream class is replaced by StreamWriter kernel
class.
</para>
<para>
CXRef class inherits from XRef (xpdf class) and adds internals for
storing of changed objects not public for direct user. XRefWriter
enables interface for making changes inherited from CXRef. See
<xref linkend="kernel_3_layer_model"/> for more information.
</para>
<mediaobject>
<imageobject>
<imagedata fileref="images/kernel.png" format="PNG"/>
</imageobject>
<caption><para>Kernel architecture</para></caption>
</mediaobject>
</sect1>
<sect1 id="general_scripting_layer">
<title>Scripting layer</title>
<mediaobject>
<imageobject><imagedata fileref="images/scripting.png" format="PNG"/></imageobject>
<caption><para>Scripting architecture</para></caption>
</mediaobject>
<para>
Scripting is base of the editor functionality.
Each editor window have its own script context and scripts run independently in them.
On creating of each window, the scripting base is constructed (<classname>BaseGUI</classname>,
extended by GUI specific functions from <classname>Base</classname>).
The <classname>Base</classname> will construct some necessary objects:
<itemizedlist>
<listitem><para><classname>QSProject</classname>
- QSA class for scripting project</para></listitem>
<listitem><para><classname>QSInterpreter</classname>
- script interpreter from <classname>QSProject</classname></para></listitem>
<listitem><para><classname>QSImporter</classname>
- Helper class used for adding and removing objects into scripting environment in runtime</para></listitem>
<listitem><para><classname>QSUtilFactory</classname>
- Standard QSA utility factory, provides <classname>File</classname>, <classname>Dir</classname>
and <classname>Process</classname> object, that will allow scripts to manipulate with files and
directories (reading, writing, creating, ...) and with processes (running external commands)</para></listitem>
<listitem><para><classname>QSInputDialogFactory</classname>
- Standard QSA input dialog factory, allowing scripts to create simple dialogs for requesting user
input</para></listitem>
</itemizedlist>
Window will set <classname>ConsoleWriter</classname> object, that will handle script output.
There are two classes derived from <classname>ConsoleWriter</classname>:
<itemizedlist>
<listitem><para>
<classname>ConsoleWriterGui</classname>, used in GUI mode, which transfers the output to command window
</para></listitem>
<listitem><para>
<classname>ConsoleWriterConsole</classname>, used in console mode, which simply writes the output to STDOUT.
</para></listitem>
</itemizedlist>
Class <classname>Base</classname> (respectively <classname>BaseGui</classname>
or <classname>BaseConsole</classname>) export many functions as slots. These are visible as static
functions in the script and they are main way of communication between the .
<classname>BaseCore</classname> class, from which the <classname>Base</classname> class is extended
does not provide any static functions, but it provides basic script functionality - garbage collection,
support for callback functions, running init scripts and handling of script errors.
</para>
<formalpara>
<title>Wrappers</title>
Script need to manipulate with objects in PDf and in editor. Due to the limitations of QSA,
every C++ object (except some basic types, such as strings, numbers and some QT types, such as QColor)
need to be derived from QObject to be usable in scripting and only functions exported as slots will
be available for script. Due to this limitation, wrappers need to exist around most objects, like
tree items in object tree (<classname>QSTreeItem</classname>,
<classname>QSTreeItemContentStream</classname>), PDF objects
(<classname>QSAnnotation</classname>, <classname>QSArray</classname>
, <classname>QSContentStream</classname>, <classname>QSDict</classname>
, <classname>QSIProperty</classname>, <classname>QSPage</classname>
, <classname>QSPdf</classname>, <classname>QSPdfOperator</classname>
and <classname>QSStream</classname>), class for invoking popup menus (<classname>QSMenu</classname>)
and helper classes related to PDF objects (<classname>QSIPropertyarray</classname>
,<classname>QSPdfOperatorIterator</classname>
and <classname>QSPdfOperatorStack</classname>).
All wrappers are derived from <classname>QSCObject</classname> class, which provides
some basic function for memory handling and error handling.
</formalpara>
<formalpara>
<title>Source of script input</title>
<itemizedlist>
<listitem><para>
One source of script input are init scripts - they are run on application startup.
</para></listitem>
<listitem><para>
Another source of script input are menus and toolbars. Each menu or toolbar item have
some associated script code which is run when the item is activated. User can see
commands invoked by these scripts in teh console window.
</para></listitem>
<listitem><para>
Third source of script input is the preview window, as interaction with it can result in
script functions being called, depending on the mode of the window (different functions
will be called in "add new line" and "add new text" mde, for example)
</para></listitem>
<listitem><para>
Callbacks is anothe rsource of script input. There are some special toolbar items, which
either manipulate their internal state or edited document itself when interacted by user
(item to switch revision, select current color, edit text, item to show and edit current page number).
These items use callbacks to notify the script of their action, so the script may react
(for example reacting to another color being selected or react on text in the text edit
toolbar item being changed).
</para></listitem>
<listitem><para>
Finally, user can use the commandline and type in any script code he want to execute.
</para></listitem>
</itemizedlist>
</formalpara>
<formalpara>
<title>Scripting API documentation</title>
Description of static scripting functions, functions provided by settings and PageSpace objects and
description of scripting objects and their methods is included in the user documentation.
</formalpara>
<formalpara>
<title>Console mode</title>
Functionality in console mode is similar, with few exceptions:
<orderedlist>
<listitem><para><classname>BaseConsole</classname> is used instead of
<classname>BaseGUI</classname>. This class extend the <classname>Base</classname>
class with few console-specific functions.</para></listitem>
<listitem><para><classname>ConsoleWindow</classname> instead of
<classname>PDFEditWindow</classname> is used. This class provide some of the
functionality for running scripts on console (handling its input and output),
similarly as <classname>PDFEditWindow</classname> does.</para></listitem>
<listitem><para><classname>PageSpace</classname> object is unavailable.</para></listitem>
<listitem><para>There is no interactivity. Editor will run scripts,
as specified on commandline, and the it will exit.</para></listitem>
</orderedlist>
</formalpara>
</sect1>
<sect1 id="general_gui_layer">
<title>Gui layer</title>
<para>
Basic class in GUI is <classname>PdfEditorWindow</classname>, which represent the main editor window.
Application can have more such windows opened, in each of them editing different document.
On top of the window is menubar and toolbar (although being on top is only default position,
user can move all toolbars as he wants, all toolbars will dock on either of four sides of the
editor window, or they can float outside of it).
</para>
<para>
All toolbars are of <classname>ToolBar</classname> class,
derived from QT class <classname>QToolBar</classname>.
The menubar is standard QT <classname>QMenuBar</classname>, although filling the menubar and also
toolbar with its items and maintaining them and their association to script code is responsility
of class <classname>Menu</classname>.
On bottom there is a statusbar, which can be used to show various information
(class <classname>StatusBar</classname>, derived from QT class <classname>QStatusBar</classname>)
Rest of the area not occupied by statusbar, menu and any toolbars is divided by movable splitter on left
and right part. Left part is divided by another splitted into part with preview window
(class <classname>PageSpace</classname>) on top and commandline window, providing script input and output
(class <classname>CommandWindow</classname>) on bottom.
Right part is also divided by splitter, on upper part there is object tree view
(class <classname>MultiTreeWindow</classname>), on lower part is property editor
(class <classname>PropertyEditor</classname>).
</para>
<para>
Every element mentioned above (except menu and the preview window) can he hidden and shown by user. Application will
remember the element layout (size and position of window, position of splitters and position of toolbars)
in settings when closing and will reopen next time with the same layout.
</para>
<para>
Dialogs are also part of the GUI. Many simple dialogs are handled by script, but
as script is unable to create more complex dialogs, some of them had to be implemented directly in C++.
They are:
<itemizedlist>
<listitem><para>
<classname>AboutWindow</classname>
- window showing version of editor and information about program and its authors
</para></listitem>
<listitem><para>
<classname>AddItemDialog</classname>
- Dialog invoked when adding new properties to dictionary
(<classname>CDict</classname>) or new elements to array
(<classname>CArray</classname>) in the tree view.
</para></listitem>
<listitem><para>
<classname>AnnotDialog</classname>
- Dialog invoked when creating new annotation to fill in its data
</para></listitem>
<listitem><para>
<classname>HelpWindow</classname>
- Dialog invoked for displaying help. Basically a very simple HTML browser
</para></listitem>
<listitem><para>
<classname>MergeDialog</classname>
- Dialog invoked when function "Import pages from another document" is invoked.
The dialog allow to select pages from another document to import and specify
positions at which they should be imported
</para></listitem>
<listitem><para>
<classname>OptionWindow</classname>
- Dialog for editing the user preferences interactively.
The options are organized into tabs, each tab containing
elements derived from <classname>Option</classname> class,
which maps one value in settings to widget for editing it.
Sublasses of <classname>Option</classname> are:
<itemizedlist>
<listitem><para>
<classname>BoolOption</classname>
- editing with checkbox as boolean value</para></listitem>
<listitem><para>
<classname>ComboOption</classname>
- editing with combobox, allowing to select from list of predefined values</para></listitem>
<listitem><para>
<classname>DialogOption</classname>
- generic class for editable string, with "..." button allowing to invoke dialog
to edit the option in some alternative and possibly more comfortable way</para></listitem>
<listitem><para>
<classname>FileOption</classname>, derived from <classname>DialogOption</classname>
- editing with possibility to invoke dialog to pick a filename</para></listitem>
<listitem><para>
<classname>FontOption</classname>, derived from <classname>DialogOption</classname>
- editing with possibility to invoke dialog to choose the font and
it s parameters interactively</para></listitem>
<listitem><para>
<classname>StringOption</classname>
- editing with classical one line edit box</para></listitem>
<listitem><para>
<classname>IntOption</classname>, derived from <classname>StringOption</classname>
- allowed input is limited to integer numbers</para></listitem>
<listitem><para>
<classname>RealOption</classname>, derived from <classname>StringOption</classname>
- allowed input is limited to real numbers</para></listitem>
</itemizedlist>
When the user presses "Ok" or "Apply" button, each of the option editing widgets
is asked to save its state in the corresponding option.
</para></listitem>
<listitem><para>
<classname>RefPropertyDialog</classname>
- Dialog to interactively select target for reference while adding or editing it.
</para></listitem>
</itemizedlist>
Also, some standard system dialogs (to pick font, color or name of file) are used.
</para>
</sect1>
</chapter>
|