# PDFedit layers

PDFEdit project is based on 3 layers model:

PDFedit layers

- Kernel - which has responsibility to maintain pdf document content and provides interface for changes.
- Script - which has responsibility to wrap kernel interface and export it to user or gui.
- Gui - which visualizes and makes comfortable usage of all the functionality which is accessible directly from kernel or Script layers.

Kernel layer is build on top of popular open source &xpdf_link_index; project (see ). 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.

Script layer is based on &qsa_link_index; - Qt script for applications, scripting language based on , developed by Trolltech.

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.

This chapter describes PDFedit layers, their comunication interface and responsibilities.

## Kernel layer

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 cobjects. More precisely - highlevel cobjects (CPdf, CPage, etc.) which provide higher pdf entities logic and lowlevel cobjects which are pdf data types carrier (CInt, CArray, CDict, CString, etc.). Values stored in lowlevel cobjects are also called properties and they are wrapped by `IProperty` 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 ).

Kernel uses &xpdf_link_index; code for document content parsing. XPdf's `XRef` class provides fetching and parsing functionality. Oposite way (from cobjects to file writing) is provided by `IPdfWriter` implementation. XPdf Stream class is replaced by StreamWriter kernel class.

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 for more information.

Kernel architecture

## Scripting layer

Scripting architecture

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 (`BaseGUI`, extended by GUI specific functions from `Base`). The `Base` will construct some necessary objects:

- `QSProject` - QSA class for scripting project

- `QSInterpreter` - script interpreter from `QSProject`

- `QSImporter` - Helper class used for adding and removing objects into scripting environment in runtime

- `QSUtilFactory` - Standard QSA utility factory, provides `File`, `Dir` and `Process` object, that will allow scripts to manipulate with files and directories (reading, writing, creating, ...) and with processes (running external commands)

- `QSInputDialogFactory` - Standard QSA input dialog factory, allowing scripts to create simple dialogs for requesting user input

Window will set `ConsoleWriter` object, that will handle script output. There are two classes derived from `ConsoleWriter`:

- `ConsoleWriterGui`, used in GUI mode, which transfers the output to command window

- `ConsoleWriterConsole`, used in console mode, which simply writes the output to STDOUT.

Class `Base` (respectively `BaseGui` or `BaseConsole`) export many functions as slots. These are visible as static functions in the script and they are main way of communication between the . `BaseCore` class, from which the `Base` 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.

### Wrappers

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 (`QSTreeItem`, `QSTreeItemContentStream`), PDF objects (`QSAnnotation`, `QSArray` , `QSContentStream`, `QSDict` , `QSIProperty`, `QSPage` , `QSPdf`, `QSPdfOperator` and `QSStream`), class for invoking popup menus (`QSMenu`) and helper classes related to PDF objects (`QSIPropertyarray` ,`QSPdfOperatorIterator` and `QSPdfOperatorStack`). All wrappers are derived from `QSCObject` class, which provides some basic function for memory handling and error handling.

### Source of script input

- One source of script input are init scripts - they are run on application startup.

- 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.

- 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)

- 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).

- Finally, user can use the commandline and type in any script code he want to execute.

### Scripting API documentation

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.

### Console mode

Functionality in console mode is similar, with few exceptions:

1. `BaseConsole` is used instead of `BaseGUI`. This class extend the `Base` class with few console-specific functions.

2. `ConsoleWindow` instead of `PDFEditWindow` is used. This class provide some of the functionality for running scripts on console (handling its input and output), similarly as `PDFEditWindow` does.

3. `PageSpace` object is unavailable.

4. There is no interactivity. Editor will run scripts, as specified on commandline, and the it will exit.

## Gui layer

Basic class in GUI is `PdfEditorWindow`, 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).

All toolbars are of `ToolBar` class, derived from QT class `QToolBar`. The menubar is standard QT `QMenuBar`, although filling the menubar and also toolbar with its items and maintaining them and their association to script code is responsility of class `Menu`. On bottom there is a statusbar, which can be used to show various information (class `StatusBar`, derived from QT class `QStatusBar`) 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 `PageSpace`) on top and commandline window, providing script input and output (class `CommandWindow`) on bottom. Right part is also divided by splitter, on upper part there is object tree view (class `MultiTreeWindow`), on lower part is property editor (class `PropertyEditor`).

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.

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:

- `AboutWindow` - window showing version of editor and information about program and its authors

- `AddItemDialog` - Dialog invoked when adding new properties to dictionary (`CDict`) or new elements to array (`CArray`) in the tree view.

- `AnnotDialog` - Dialog invoked when creating new annotation to fill in its data

- `HelpWindow` - Dialog invoked for displaying help. Basically a very simple HTML browser

- `MergeDialog` - 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

- `OptionWindow` - Dialog for editing the user preferences interactively. The options are organized into tabs, each tab containing elements derived from `Option` class, which maps one value in settings to widget for editing it. Sublasses of `Option` are:

  - `BoolOption` - editing with checkbox as boolean value

  - `ComboOption` - editing with combobox, allowing to select from list of predefined values

  - `DialogOption` - generic class for editable string, with "..." button allowing to invoke dialog to edit the option in some alternative and possibly more comfortable way

  - `FileOption`, derived from `DialogOption` - editing with possibility to invoke dialog to pick a filename

  - `FontOption`, derived from `DialogOption` - editing with possibility to invoke dialog to choose the font and it s parameters interactively

  - `StringOption` - editing with classical one line edit box

  - `IntOption`, derived from `StringOption` - allowed input is limited to integer numbers

  - `RealOption`, derived from `StringOption` - allowed input is limited to real numbers

  When the user presses "Ok" or "Apply" button, each of the option editing widgets is asked to save its state in the corresponding option.

- `RefPropertyDialog` - Dialog to interactively select target for reference while adding or editing it.

Also, some standard system dialogs (to pick font, color or name of file) are used.