[Okular-devel] [PATCHES] Customizable annotation tools

Fabio D'Urso fabiodurso at hotmail.it
Mon Jul 30 19:20:21 UTC 2012


Hi everybody,

The attached patches allow the user to change the default settings of each 
annotation tool. They also allow creation of new tools (for example, to create 
a second highlighter with a different color) and removal of existing ones. 
It's possible to set predefined values for any property that can be edited in 
existing annotations. In fact, I reused the same widget as the proerties 
dialog.
I also added support for three new properties (inner color in polygons, line 
width in ink annotations, text alignment in inplace text annotations).
The patches also expose some tools that were mostly implemented but not shown 
to the user:
 - Squiggly and Strike out (both based on the TextSelector engine, which is
   currently used to highlight and underline text)
 - Rectangle (based on PickPoint engine, like Ellipse)
 - Polyline (based on PolyLine engine, with a fix to make it possible to end
   a path by double-clicking on the last point).

Currently, the tools' list is stored in a XML file (ui/data/tools.xml). In 
principle, editing this file is enough to edit and create tools.
The approach I've used is to store the tool list in the user's configuration, 
in form of a list of XML strings each representing a tool, and making the same 
functions that used to parse tools.xml parse these strings instead.
Note that tools.xml is still used: it now contains the default tools.

== Brief summary of patches ==
In patches 0001-0007, I renamed the "Identity" configuration tab to 
"Annotations" and added a stub widget to edit tools' raw XML data.

Patch 0008, together with patches 0030 and 0031 deals with translation issues.
The problem is basically that tools.xml contains translatable strings (tools' 
names and tooltips), which were translated after tools.xml was parsed. But now 
we are allowing the user to edit the tools and, in particular, set its own 
tool names, therefore we can't assume that texts from the tool list are meant 
to be translated, because those set by the user are not.
In patch 0008, I moved the translation phase to kcfg initialization. That is, 
tools.xml still contains translatable strings, but the setting property is 
translated. Therefore I can then assume that all texts in the tool list are 
already translated. Patches 0030 and 0031 go even further and remove all 
translatable texts from tools.xml.

Patches 0009-0012 change the way tool icons are painted. Currently, they're 
PNG images loaded from disk. With the patches, I only load a base image from 
disk and draw on top of it using QPainter. This enables us to draw icons the 
same color as the annotations they create.

Patches 0013 and 0015 make it possible to create tools using the same widgets 
as the annotation properties dialog. Internally, the new tool dialog creates a 
stub annotation and shows a widget to edit it. When the user has finished, it 
queries the stub annotation and configures the tool accordingly.

Patches 0014, 0016 and part of 0026 and 0037 are enhancements to annotation 
widgets:
 - Do not show the font selection field in pop-up annotations (0014)
 - Configurable line width in InkAnnotations (0016)
 - Configurable inner color in polygons (0026)
 - Text alignment in inplace text annotations (0037)

Patches 0017, 0020, 0025, the other part of 0026, 0028, 0035, the other part 
of 0037 are enhancements to the tools' engines, to apply configured values to 
newly created annotations.

Patches 0018 and 0019 are minor changes to the PickPoint engine to make sure 
that the preview of the stamp and its size are always available, even in case 
of our internal SVG stamps.

Patches 0021 and 0038 respectively show the tool's icon in the tool list panel 
and in the tool edit dialog, so that it's easier for the user to recognize the 
tool he's editing.

Up to patch 0022, it was mandatory for the user to make up a name for his 
tools. Patch 0022 assigns a default name, if none is provided, according to 
the annotation type.

Patch 0023 and 0024 fix the PolyLine engine to create open paths and create a 
tool to use this feature. Note that "classical" polygons are not affected. 
Polyline is a different tool.

Patch 0027 adds support in PagePainter for polygons' inner color. Note that, 
unlike in poppler, polygons are rendered semitransparently by PagePainter. We 
may want to change it to opaque in a future patch.

Patch 0029 sets new tools' default values the same as the corresponding 
default tool. Imho, since the default values look good in most documents, they 
are good predefined values.

Patches 0030 and 0031 are the final ones about translation issues. Patch 0030 
removes tooltips from the XML data and patch 0031 removes default names. Since 
default tools have default names, this effectively removes all translatable 
strings from tools.xml.

Patch 0032 is a rewrite of the way tools' XML descriptions are created by the 
new tool dialog: use DOM methods instead of (potentially) unsafe XML strings.

Until now it was only possible to add new tools. Patch 0033 makes it possible 
to also edit existing annotation tools.

Patch 0034 is a minor patch to make sure that tools created with default 
settings are identical to default tools (so that kcfg can recognize them as 
default settings).

Patch 0036 makes icons bigger in the tool list.

Patch 0037 changes all "Note" UI texts to "Pop-up Note" (to distinguish from 
"Inline Note").

Patch 0040 is a PagePainter fix to make sure that inline notes' contents are 
laid out correctly even at non-100% zoom.

Patch 0041 replaces the Stamp icon with a dynamically painted icon that 
includes a 16x16 preview of the stamp.

Patch 0042 fixes a situation in which annotations were drawn twice (see commit 
message).

Patch 0043 fixes the condition used by the PolyLine engine to detect point 
equality.

Patch 0044... there's no patch 0044. That's all folks!


P.S.: Before we begin to review and commit patches, I'd like to have some 
feedback about the GUI changes.

Fabio
-------------- next part --------------
From 50ea1e90a3b8003c0b185afa3c3b82c5e8d3f9d9 Mon Sep 17 00:00:00 2001
From: Fabio D'Urso <fabiodurso at hotmail.it>
Date: Sat, 9 Jun 2012 22:59:40 +0200
Subject: [PATCH 01/43] Renamed "Identity" -> "Annotations" config panel

It only contained an option to set annotations' author name
---
 CMakeLists.txt             |    4 +-
 conf/dlgannotations.cpp    |   19 ++++++++
 conf/dlgannotations.h      |   22 ++++++++++
 conf/dlgannotationsbase.ui |  101 ++++++++++++++++++++++++++++++++++++++++++++
 conf/dlgidentity.cpp       |   19 --------
 conf/dlgidentity.h         |   22 ----------
 conf/dlgidentitybase.ui    |  101 --------------------------------------------
 conf/preferencesdialog.cpp |    9 ++--
 conf/preferencesdialog.h   |    4 +-
 9 files changed, 150 insertions(+), 151 deletions(-)
 create mode 100644 conf/dlgannotations.cpp
 create mode 100644 conf/dlgannotations.h
 create mode 100644 conf/dlgannotationsbase.ui
 delete mode 100644 conf/dlgidentity.cpp
 delete mode 100644 conf/dlgidentity.h
 delete mode 100644 conf/dlgidentitybase.ui

diff --git a/CMakeLists.txt b/CMakeLists.txt
index e4cb88f..c008db4 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -137,7 +137,7 @@ set(okularpart_SRCS
    conf/dlgdebug.cpp
    conf/dlgeditor.cpp
    conf/dlggeneral.cpp
-   conf/dlgidentity.cpp
+   conf/dlgannotations.cpp
    conf/dlgperformance.cpp
    conf/dlgpresentation.cpp
    ui/embeddedfilesdialog.cpp
@@ -181,7 +181,7 @@ kde4_add_ui_files(okularpart_SRCS
    conf/dlgaccessibilitybase.ui
    conf/dlgeditorbase.ui
    conf/dlggeneralbase.ui
-   conf/dlgidentitybase.ui
+   conf/dlgannotationsbase.ui
    conf/dlgperformancebase.ui
    conf/dlgpresentationbase.ui
 )
diff --git a/conf/dlgannotations.cpp b/conf/dlgannotations.cpp
new file mode 100644
index 0000000..627b77e
--- /dev/null
+++ b/conf/dlgannotations.cpp
@@ -0,0 +1,19 @@
+/***************************************************************************
+ *   Copyright (C) 2006 by Pino Toscano <toscano.pino at tiscali.it>          *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ ***************************************************************************/
+
+#include "dlgannotations.h"
+
+#include "ui_dlgannotationsbase.h"
+
+DlgAnnotations::DlgAnnotations( QWidget * parent )
+    : QWidget( parent )
+{
+    Ui_DlgAnnotationsBase dlg;
+    dlg.setupUi( this );
+}
diff --git a/conf/dlgannotations.h b/conf/dlgannotations.h
new file mode 100644
index 0000000..bdc1399
--- /dev/null
+++ b/conf/dlgannotations.h
@@ -0,0 +1,22 @@
+/***************************************************************************
+ *   Copyright (C) 2006 by Pino Toscano <toscano.pino at tiscali.it>          *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ ***************************************************************************/
+
+#ifndef _DLGANNOTATIONS_H_
+#define _DLGANNOTATIONS_H_
+
+#include <qwidget.h>
+
+
+class DlgAnnotations : public QWidget
+{
+    public:
+        DlgAnnotations( QWidget * parent = 0 );
+};
+
+#endif
diff --git a/conf/dlgannotationsbase.ui b/conf/dlgannotationsbase.ui
new file mode 100644
index 0000000..477b8e1
--- /dev/null
+++ b/conf/dlgannotationsbase.ui
@@ -0,0 +1,101 @@
+<ui version="4.0" >
+ <class>DlgAnnotationsBase</class>
+ <widget class="QWidget" name="DlgAnnotationsBase" >
+  <property name="geometry" >
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>381</width>
+    <height>155</height>
+   </rect>
+  </property>
+  <layout class="QVBoxLayout" >
+   <property name="spacing" >
+    <number>6</number>
+   </property>
+   <property name="leftMargin" >
+    <number>0</number>
+   </property>
+   <property name="topMargin" >
+    <number>0</number>
+   </property>
+   <property name="rightMargin" >
+    <number>0</number>
+   </property>
+   <property name="bottomMargin" >
+    <number>0</number>
+   </property>
+   <item>
+    <widget class="QGroupBox" name="groupBox" >
+     <property name="title" >
+      <string>Identity</string>
+     </property>
+     <layout class="QGridLayout" >
+      <property name="leftMargin" >
+       <number>9</number>
+      </property>
+      <property name="topMargin" >
+       <number>9</number>
+      </property>
+      <property name="rightMargin" >
+       <number>9</number>
+      </property>
+      <property name="bottomMargin" >
+       <number>9</number>
+      </property>
+      <property name="horizontalSpacing" >
+       <number>6</number>
+      </property>
+      <property name="verticalSpacing" >
+       <number>6</number>
+      </property>
+      <item row="0" column="0" >
+       <widget class="QLabel" name="label" >
+        <property name="text" >
+         <string>&Author:</string>
+        </property>
+        <property name="alignment" >
+         <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+        </property>
+        <property name="buddy" >
+         <cstring>kcfg_IdentityAuthor</cstring>
+        </property>
+       </widget>
+      </item>
+      <item row="0" column="1" >
+       <widget class="QLineEdit" name="kcfg_IdentityAuthor" />
+      </item>
+      <item row="1" column="0" colspan="2" >
+       <widget class="QLabel" name="label_2" >
+        <property name="text" >
+         <string><b>Note</b>: the information here is used only for comments and reviews. Information inserted here will not be transmitted without your knowledge.</string>
+        </property>
+        <property name="alignment" >
+         <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
+        </property>
+        <property name="wordWrap" >
+         <bool>true</bool>
+        </property>
+       </widget>
+      </item>
+     </layout>
+    </widget>
+   </item>
+   <item>
+    <spacer>
+     <property name="orientation" >
+      <enum>Qt::Vertical</enum>
+     </property>
+     <property name="sizeHint" >
+      <size>
+       <width>20</width>
+       <height>4</height>
+      </size>
+     </property>
+    </spacer>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/conf/dlgidentity.cpp b/conf/dlgidentity.cpp
deleted file mode 100644
index 8585716..0000000
--- a/conf/dlgidentity.cpp
+++ /dev/null
@@ -1,19 +0,0 @@
-/***************************************************************************
- *   Copyright (C) 2006 by Pino Toscano <toscano.pino at tiscali.it>          *
- *                                                                         *
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- ***************************************************************************/
-
-#include "dlgidentity.h"
-
-#include "ui_dlgidentitybase.h"
-
-DlgIdentity::DlgIdentity( QWidget * parent )
-    : QWidget( parent )
-{
-    Ui_DlgIdentityBase dlg;
-    dlg.setupUi( this );
-}
diff --git a/conf/dlgidentity.h b/conf/dlgidentity.h
deleted file mode 100644
index 1bbd937..0000000
--- a/conf/dlgidentity.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/***************************************************************************
- *   Copyright (C) 2006 by Pino Toscano <toscano.pino at tiscali.it>          *
- *                                                                         *
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- ***************************************************************************/
-
-#ifndef _DLGIDENTITY_H_
-#define _DLGIDENTITY_H_
-
-#include <qwidget.h>
-
-
-class DlgIdentity : public QWidget
-{
-    public:
-        DlgIdentity( QWidget * parent = 0 );
-};
-
-#endif
diff --git a/conf/dlgidentitybase.ui b/conf/dlgidentitybase.ui
deleted file mode 100644
index 15752eb..0000000
--- a/conf/dlgidentitybase.ui
+++ /dev/null
@@ -1,101 +0,0 @@
-<ui version="4.0" >
- <class>DlgIdentityBase</class>
- <widget class="QWidget" name="DlgIdentityBase" >
-  <property name="geometry" >
-   <rect>
-    <x>0</x>
-    <y>0</y>
-    <width>381</width>
-    <height>155</height>
-   </rect>
-  </property>
-  <layout class="QVBoxLayout" >
-   <property name="spacing" >
-    <number>6</number>
-   </property>
-   <property name="leftMargin" >
-    <number>0</number>
-   </property>
-   <property name="topMargin" >
-    <number>0</number>
-   </property>
-   <property name="rightMargin" >
-    <number>0</number>
-   </property>
-   <property name="bottomMargin" >
-    <number>0</number>
-   </property>
-   <item>
-    <widget class="QGroupBox" name="groupBox" >
-     <property name="title" >
-      <string>Identity</string>
-     </property>
-     <layout class="QGridLayout" >
-      <property name="leftMargin" >
-       <number>9</number>
-      </property>
-      <property name="topMargin" >
-       <number>9</number>
-      </property>
-      <property name="rightMargin" >
-       <number>9</number>
-      </property>
-      <property name="bottomMargin" >
-       <number>9</number>
-      </property>
-      <property name="horizontalSpacing" >
-       <number>6</number>
-      </property>
-      <property name="verticalSpacing" >
-       <number>6</number>
-      </property>
-      <item row="0" column="0" >
-       <widget class="QLabel" name="label" >
-        <property name="text" >
-         <string>&Author:</string>
-        </property>
-        <property name="alignment" >
-         <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
-        </property>
-        <property name="buddy" >
-         <cstring>kcfg_IdentityAuthor</cstring>
-        </property>
-       </widget>
-      </item>
-      <item row="0" column="1" >
-       <widget class="QLineEdit" name="kcfg_IdentityAuthor" />
-      </item>
-      <item row="1" column="0" colspan="2" >
-       <widget class="QLabel" name="label_2" >
-        <property name="text" >
-         <string><b>Note</b>: the information here is used only for comments and reviews. Information inserted here will not be transmitted without your knowledge.</string>
-        </property>
-        <property name="alignment" >
-         <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
-        </property>
-        <property name="wordWrap" >
-         <bool>true</bool>
-        </property>
-       </widget>
-      </item>
-     </layout>
-    </widget>
-   </item>
-   <item>
-    <spacer>
-     <property name="orientation" >
-      <enum>Qt::Vertical</enum>
-     </property>
-     <property name="sizeHint" >
-      <size>
-       <width>20</width>
-       <height>4</height>
-      </size>
-     </property>
-    </spacer>
-   </item>
-  </layout>
- </widget>
- <resources/>
- <connections/>
-</ui>
diff --git a/conf/preferencesdialog.cpp b/conf/preferencesdialog.cpp
index 9f6d339..e881759 100644
--- a/conf/preferencesdialog.cpp
+++ b/conf/preferencesdialog.cpp
@@ -17,7 +17,7 @@
 #include "dlgperformance.h"
 #include "dlgaccessibility.h"
 #include "dlgpresentation.h"
-#include "dlgidentity.h"
+#include "dlgannotations.h"
 #include "dlgeditor.h"
 #include "dlgdebug.h"
 
@@ -28,7 +28,7 @@ PreferencesDialog::PreferencesDialog( QWidget * parent, KConfigSkeleton * skelet
     m_performance = new DlgPerformance( this );
     m_accessibility = new DlgAccessibility( this );
     m_presentation = 0;
-    m_identity = 0;
+    m_annotations = 0;
     m_editor = 0;
 #ifdef OKULAR_DEBUG_CONFIGPAGE
     m_debug = new DlgDebug( this );
@@ -44,12 +44,11 @@ PreferencesDialog::PreferencesDialog( QWidget * parent, KConfigSkeleton * skelet
     else
     {
         m_presentation = new DlgPresentation( this );
-        m_identity = new DlgIdentity( this );
+        m_annotations = new DlgAnnotations( this );
         m_editor = new DlgEditor( this );
         addPage( m_presentation, i18n("Presentation"), "view-presentation",
                  i18n("Options for Presentation Mode") );
-        addPage( m_identity, i18n("Identity"), "preferences-desktop-personal",
-                 i18n("Identity Settings") );
+        addPage( m_annotations, i18n("Annotations"), "draw-freehand", i18n("Annotation Options") );
         addPage( m_editor, i18n("Editor"), "accessories-text-editor", i18n("Editor Options") );
     }
 #ifdef OKULAR_DEBUG_CONFIGPAGE
diff --git a/conf/preferencesdialog.h b/conf/preferencesdialog.h
index 3340487..245c72e 100644
--- a/conf/preferencesdialog.h
+++ b/conf/preferencesdialog.h
@@ -21,7 +21,7 @@ class DlgGeneral;
 class DlgPerformance;
 class DlgAccessibility;
 class DlgPresentation;
-class DlgIdentity;
+class DlgAnnotations;
 class DlgEditor;
 class DlgDebug;
 
@@ -43,7 +43,7 @@ class PreferencesDialog : public KConfigDialog
         DlgPerformance * m_performance;
         DlgAccessibility * m_accessibility;
         DlgPresentation * m_presentation;
-        DlgIdentity * m_identity;
+        DlgAnnotations * m_annotations;
         DlgEditor * m_editor;
         DlgDebug * m_debug;
 };
-- 
1.7.6.5


From 49cae2efea5fb215c4121782c974190c4bdbf49d Mon Sep 17 00:00:00 2001
From: Fabio D'Urso <fabiodurso at hotmail.it>
Date: Sat, 9 Jun 2012 23:52:31 +0200
Subject: [PATCH 02/43] Make PageViewAnnotator reparse tool list on
 configuration change

This doesn't do anything useful at the moment. In next patch I'll turn
the tool list into a configurable option.
---
 ui/pageview.cpp          |    7 +++++++
 ui/pageviewannotator.cpp |    7 +++++++
 ui/pageviewannotator.h   |    2 ++
 3 files changed, 16 insertions(+), 0 deletions(-)

diff --git a/ui/pageview.cpp b/ui/pageview.cpp
index b74941d..ec186a4 100644
--- a/ui/pageview.cpp
+++ b/ui/pageview.cpp
@@ -716,6 +716,13 @@ void PageView::reparseConfig()
 
     updatePageStep();
 
+    if ( d->annotator )
+    {
+        d->annotator->setEnabled( false );
+        d->annotator->reparseConfig();
+        if ( d->aToggleAnnotator->isChecked() )
+            slotToggleAnnotator( true );
+    }
 }
 
 KAction *PageView::toggleFormsAction() const
diff --git a/ui/pageviewannotator.cpp b/ui/pageviewannotator.cpp
index 52a464b..4241944 100644
--- a/ui/pageviewannotator.cpp
+++ b/ui/pageviewannotator.cpp
@@ -606,6 +606,13 @@ PageViewAnnotator::PageViewAnnotator( PageView * parent, Okular::Document * stor
     m_toolBar( 0 ), m_engine( 0 ), m_textToolsEnabled( false ), m_toolsEnabled( false ),
     m_continuousMode( false ), m_lastToolID( -1 ), m_lockedItem( 0 )
 {
+    reparseConfig();
+}
+
+void PageViewAnnotator::reparseConfig()
+{
+    m_items.clear();
+
     // load the tools from the 'xml tools definition' file. store the tree internally.
     QFile infoFile( KStandardDirs::locate("data", "okular/tools.xml") );
     if ( infoFile.exists() && infoFile.open( QIODevice::ReadOnly ) )
diff --git a/ui/pageviewannotator.h b/ui/pageviewannotator.h
index e847208..28b9f43 100644
--- a/ui/pageviewannotator.h
+++ b/ui/pageviewannotator.h
@@ -67,6 +67,8 @@ class PageViewAnnotator : public QObject
         bool routePaints( const QRect & wantedRect ) const;
         void routePaint( QPainter * painter, const QRect & paintRect );
 
+        void reparseConfig();
+
     private slots:
         void slotToolSelected( int toolID );
         void slotSaveToolbarOrientation( int side );
-- 
1.7.6.5


From d85fe3f8aeec553303ba3af899895d2a1a0a0978 Mon Sep 17 00:00:00 2001
From: Fabio D'Urso <fabiodurso at hotmail.it>
Date: Sun, 10 Jun 2012 14:10:53 +0200
Subject: [PATCH 03/43] Turn the annotation tools list in a configurable
 option

Instead of using a system-wide tools.xml file containing a list of
<tool>...</tool> elements, store each tool element as string in a
stringlist configuration option.
Note that the global tools.xml file is still needed to read the
default values.
---
 conf/okular.kcfg         |   30 ++++++++++++++++++++
 conf/settings.kcfgc      |    1 +
 ui/pageviewannotator.cpp |   69 ++++++++++++++++++++++-----------------------
 ui/pageviewannotator.h   |    5 ++-
 4 files changed, 68 insertions(+), 37 deletions(-)

diff --git a/conf/okular.kcfg b/conf/okular.kcfg
index 6ad0e19..a151a13 100644
--- a/conf/okular.kcfg
+++ b/conf/okular.kcfg
@@ -312,5 +312,35 @@
   <entry key="ReviewsSearchRegularExpression" type="Bool">
    <default>false</default>
   </entry>
+  <entry key="AnnotationTools" type="StringList">
+    <code>
+      QStringList annotationTools;
+      // load the default tool list from the 'xml tools definition' file
+      QFile infoFile( KStandardDirs::locate("data", "okular/tools.xml") );
+      if ( infoFile.exists() && infoFile.open( QIODevice::ReadOnly ) )
+      {
+          QDomDocument doc;
+          if ( doc.setContent( &infoFile ) )
+          {
+              QDomElement toolsDefinition = doc.elementsByTagName("annotatingTools").item( 0 ).toElement();
+               // create the annotationTools list from the XML dom tree
+              QDomNode toolDescription = toolsDefinition.firstChild();
+              while ( toolDescription.isElement() )
+              {
+                  QDomElement toolElement = toolDescription.toElement();
+                  if ( toolElement.tagName() == "tool" )
+                  {
+                      QDomDocument temp;
+                      temp.appendChild( temp.importNode( toolElement, true) );
+                      // add each <tool>...</tool> as XML string
+                      annotationTools << temp.toString(-1);
+                  }
+                  toolDescription = toolDescription.nextSibling();
+              }
+          }
+      }
+    </code>
+    <default code="true">annotationTools</default>
+  </entry>
  </group>
 </kcfg>
diff --git a/conf/settings.kcfgc b/conf/settings.kcfgc
index 0b70390..86c161b 100644
--- a/conf/settings.kcfgc
+++ b/conf/settings.kcfgc
@@ -5,4 +5,5 @@ Mutators=true
 Singleton=true
 Visibility=OKULAR_EXPORT
 IncludeFiles=core/okular_export.h
+SourceIncludeFiles=kstandarddirs.h,qdom.h
 MemberVariables=dpointer
diff --git a/ui/pageviewannotator.cpp b/ui/pageviewannotator.cpp
index 4241944..87c884e 100644
--- a/ui/pageviewannotator.cpp
+++ b/ui/pageviewannotator.cpp
@@ -613,47 +613,46 @@ void PageViewAnnotator::reparseConfig()
 {
     m_items.clear();
 
-    // load the tools from the 'xml tools definition' file. store the tree internally.
-    QFile infoFile( KStandardDirs::locate("data", "okular/tools.xml") );
-    if ( infoFile.exists() && infoFile.open( QIODevice::ReadOnly ) )
+    // Read tool list from configuration. It's a list of XML <tool></tool> elements
+    const QStringList userTools = Okular::Settings::annotationTools();
+
+    // Populate m_toolsDefinition
+    QDomDocument doc;
+    m_toolsDefinition = doc.createElement( "annotatingTools" );
+    foreach ( const QString toolXml, userTools )
     {
-        QDomDocument doc( "annotatingTools" );
-        if ( doc.setContent( &infoFile ) )
-        {
-            m_toolsDefinition = doc.elementsByTagName("annotatingTools").item( 0 ).toElement();
+        QDomDocument entryParser;
+        if ( entryParser.setContent( toolXml ) )
+            m_toolsDefinition.appendChild( doc.importNode( entryParser.documentElement(), true ) );
+        else
+            kWarning() << "Skipping malformed tool XML in AnnotationTools setting";
+    }
 
-            // create the AnnotationToolItems from the XML dom tree
-            QDomNode toolDescription = m_toolsDefinition.firstChild();
-            while ( toolDescription.isElement() )
+    // Create the AnnotationToolItems from the XML dom tree
+    QDomNode toolDescription = m_toolsDefinition.firstChild();
+    while ( toolDescription.isElement() )
+    {
+        QDomElement toolElement = toolDescription.toElement();
+        if ( toolElement.tagName() == "tool" )
+        {
+            AnnotationToolItem item;
+            item.id = toolElement.attribute("id").toInt();
+            item.text = i18n( toolElement.attribute( "name" ).toUtf8() );
+            item.pixmap = toolElement.attribute("pixmap");
+            QDomNode shortcutNode = toolElement.elementsByTagName( "shortcut" ).item( 0 );
+            if ( shortcutNode.isElement() )
+                item.shortcut = shortcutNode.toElement().text();
+            QDomNodeList engineNodeList = toolElement.elementsByTagName( "engine" );
+            if ( engineNodeList.size() > 0 )
             {
-                QDomElement toolElement = toolDescription.toElement();
-                if ( toolElement.tagName() == "tool" )
-                {
-                    AnnotationToolItem item;
-                    item.id = toolElement.attribute("id").toInt();
-                    item.text = i18n( toolElement.attribute( "name" ).toUtf8() );
-                    item.pixmap = toolElement.attribute("pixmap");
-                    QDomNode shortcutNode = toolElement.elementsByTagName( "shortcut" ).item( 0 );
-                    if ( shortcutNode.isElement() )
-                        item.shortcut = shortcutNode.toElement().text();
-                    QDomNodeList engineNodeList = toolElement.elementsByTagName( "engine" );
-                    if ( engineNodeList.size() > 0 )
-                    {
-                        QDomElement engineEl = engineNodeList.item( 0 ).toElement();
-                        if ( !engineEl.isNull() && engineEl.hasAttribute( "type" ) )
-                            item.isText = engineEl.attribute( "type" ) == QLatin1String( "TextSelector" );
-                    }
-                    m_items.push_back( item );
-                }
-                toolDescription = toolDescription.nextSibling();
+                QDomElement engineEl = engineNodeList.item( 0 ).toElement();
+                if ( !engineEl.isNull() && engineEl.hasAttribute( "type" ) )
+                    item.isText = engineEl.attribute( "type" ) == QLatin1String( "TextSelector" );
             }
+            m_items.push_back( item );
         }
-        else
-            kWarning() << "AnnotatingTools XML file seems to be damaged";
-        infoFile.close();
+        toolDescription = toolDescription.nextSibling();
     }
-    else
-        kWarning() << "Unable to open AnnotatingTools XML definition";
 }
 
 PageViewAnnotator::~PageViewAnnotator()
diff --git a/ui/pageviewannotator.h b/ui/pageviewannotator.h
index 28b9f43..5884e36 100644
--- a/ui/pageviewannotator.h
+++ b/ui/pageviewannotator.h
@@ -39,11 +39,12 @@ class PageView;
  * to this class that performs a rough visual representation of what the
  * annotation will become when finished.
  *
- * "data/tools.xml" is the file that contains Annotations/Engine association
+ * m_toolsDefinition is a DOM object that contains Annotations/Engine association
  * for the items placed in the toolbar. The XML is parsed (1) when populating
  * the toolbar and (2)after selecting a toolbar item, in which case an Ann is
  * initialized with the values in the XML and an engine is created to handle
- * that annotation.
+ * that annotation. m_toolsDefinition is created in reparseConfig according to
+ * user configuration.
  */
 class PageViewAnnotator : public QObject
 {
-- 
1.7.6.5


From 95c1e674eaf15dc18bbd7db3094681f3f3ed0da6 Mon Sep 17 00:00:00 2001
From: Fabio D'Urso <fabiodurso at hotmail.it>
Date: Sun, 10 Jun 2012 15:48:05 +0200
Subject: [PATCH 04/43] Annotation settings: Added stub widget to edit raw XML
 tool data

---
 conf/dlgannotationsbase.ui |   12 ++++++++++++
 1 files changed, 12 insertions(+), 0 deletions(-)

diff --git a/conf/dlgannotationsbase.ui b/conf/dlgannotationsbase.ui
index 477b8e1..11720c5 100644
--- a/conf/dlgannotationsbase.ui
+++ b/conf/dlgannotationsbase.ui
@@ -82,6 +82,18 @@
     </widget>
    </item>
    <item>
+    <widget class="QGroupBox" name="annotToolsGroup">
+     <property name="title">
+      <string>Annotation tools</string>
+     </property>
+     <layout class="QGridLayout">
+      <item row="0" column="0">
+       <widget class="KEditListBox" name="kcfg_AnnotationTools"/>
+      </item>
+     </layout>
+    </widget>
+   </item>
+   <item>
     <spacer>
      <property name="orientation" >
       <enum>Qt::Vertical</enum>
-- 
1.7.6.5


From 7ae6125ed1165eeb99d388e4361ac290bc921f38 Mon Sep 17 00:00:00 2001
From: Fabio D'Urso <fabiodurso at hotmail.it>
Date: Sun, 10 Jun 2012 14:30:48 +0200
Subject: [PATCH 05/43] Annotation settings: Show the privacy notice in a
 tooltip instead of a huge label

---
 conf/dlgannotationsbase.ui |   13 ++-----------
 1 files changed, 2 insertions(+), 11 deletions(-)

diff --git a/conf/dlgannotationsbase.ui b/conf/dlgannotationsbase.ui
index 11720c5..7a0d78c 100644
--- a/conf/dlgannotationsbase.ui
+++ b/conf/dlgannotationsbase.ui
@@ -63,19 +63,10 @@
        </widget>
       </item>
       <item row="0" column="1" >
-       <widget class="QLineEdit" name="kcfg_IdentityAuthor" />
-      </item>
-      <item row="1" column="0" colspan="2" >
-       <widget class="QLabel" name="label_2" >
-        <property name="text" >
+       <widget class="QLineEdit" name="kcfg_IdentityAuthor">
+        <property name="toolTip">
          <string><b>Note</b>: the information here is used only for comments and reviews. Information inserted here will not be transmitted without your knowledge.</string>
         </property>
-        <property name="alignment" >
-         <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
-        </property>
-        <property name="wordWrap" >
-         <bool>true</bool>
-        </property>
        </widget>
       </item>
      </layout>
-- 
1.7.6.5


From ace1ae3408176236cada041645c3601c9e3b3837 Mon Sep 17 00:00:00 2001
From: Fabio D'Urso <fabiodurso at hotmail.it>
Date: Sun, 10 Jun 2012 20:15:38 +0200
Subject: [PATCH 06/43] Preliminary implementation of widget to edit
 annotation tools

It only supports removal, moveup and movedown.
---
 CMakeLists.txt               |    2 +
 conf/dlgannotations.cpp      |    9 +++
 conf/dlgannotationsbase.ui   |    6 +--
 conf/widgetannottools.cpp    |  161 ++++++++++++++++++++++++++++++++++++++++++
 conf/widgetannottools.h      |   47 ++++++++++++
 conf/widgetannottoolsbase.ui |   72 +++++++++++++++++++
 6 files changed, 292 insertions(+), 5 deletions(-)
 create mode 100644 conf/widgetannottools.cpp
 create mode 100644 conf/widgetannottools.h
 create mode 100644 conf/widgetannottoolsbase.ui

diff --git a/CMakeLists.txt b/CMakeLists.txt
index c008db4..720176b 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -140,6 +140,7 @@ set(okularpart_SRCS
    conf/dlgannotations.cpp
    conf/dlgperformance.cpp
    conf/dlgpresentation.cpp
+   conf/widgetannottools.cpp
    ui/embeddedfilesdialog.cpp
    ui/annotwindow.cpp
    ui/annotationmodel.cpp
@@ -184,6 +185,7 @@ kde4_add_ui_files(okularpart_SRCS
    conf/dlgannotationsbase.ui
    conf/dlgperformancebase.ui
    conf/dlgpresentationbase.ui
+   conf/widgetannottoolsbase.ui
 )
 
 qt4_add_dbus_interfaces(okularpart_SRCS ${KDE4_DBUS_INTERFACES_DIR}/org.kde.KSpeech.xml)
diff --git a/conf/dlgannotations.cpp b/conf/dlgannotations.cpp
index 627b77e..b6fc85a 100644
--- a/conf/dlgannotations.cpp
+++ b/conf/dlgannotations.cpp
@@ -9,6 +9,9 @@
 
 #include "dlgannotations.h"
 
+#include <kconfigdialogmanager.h>
+
+#include "widgetannottools.h"
 #include "ui_dlgannotationsbase.h"
 
 DlgAnnotations::DlgAnnotations( QWidget * parent )
@@ -16,4 +19,10 @@ DlgAnnotations::DlgAnnotations( QWidget * parent )
 {
     Ui_DlgAnnotationsBase dlg;
     dlg.setupUi( this );
+
+    WidgetAnnotTools * kcfg_AnnotationTools = new WidgetAnnotTools( dlg.annotToolsGroup );
+    dlg.annotToolsPlaceholder->addWidget( kcfg_AnnotationTools );
+    kcfg_AnnotationTools->setObjectName( "kcfg_AnnotationTools" );
+
+    KConfigDialogManager::changedMap()->insert( "WidgetAnnotTools" , SIGNAL(changed()) );
 }
diff --git a/conf/dlgannotationsbase.ui b/conf/dlgannotationsbase.ui
index 7a0d78c..15b358b 100644
--- a/conf/dlgannotationsbase.ui
+++ b/conf/dlgannotationsbase.ui
@@ -77,11 +77,7 @@
      <property name="title">
       <string>Annotation tools</string>
      </property>
-     <layout class="QGridLayout">
-      <item row="0" column="0">
-       <widget class="KEditListBox" name="kcfg_AnnotationTools"/>
-      </item>
-     </layout>
+     <layout class="QVBoxLayout" name="annotToolsPlaceholder" />
     </widget>
    </item>
    <item>
diff --git a/conf/widgetannottools.cpp b/conf/widgetannottools.cpp
new file mode 100644
index 0000000..6817b8b
--- /dev/null
+++ b/conf/widgetannottools.cpp
@@ -0,0 +1,161 @@
+/***************************************************************************
+ *   Copyright (C) 2012 by Fabio D'Urso <fabiodurso at hotmail.it>            *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ ***************************************************************************/
+
+#include "widgetannottools.h"
+
+#include <kdebug.h>
+#include <kicon.h>
+#include <kmessagebox.h>
+#include <kpushbutton.h>
+
+#include <QtGui/QListWidget>
+#include <QtGui/QListWidgetItem>
+#include <QtXml/QDomDocument>
+#include <QtXml/QDomElement>
+
+#include "ui_widgetannottoolsbase.h"
+
+WidgetAnnotTools::WidgetAnnotTools( QWidget * parent )
+    : QWidget( parent )
+{
+    m_ui = new Ui_WidgetAnnotToolsBase();
+    m_ui->setupUi( this );
+
+    m_ui->btnAdd->setIcon( KIcon("list-add") );
+    m_ui->btnRemove->setIcon( KIcon("list-remove") );
+    m_ui->btnRemove->setEnabled( false );
+    m_ui->btnMoveUp->setIcon( KIcon("arrow-up") );
+    m_ui->btnMoveUp->setEnabled( false );
+    m_ui->btnMoveDown->setIcon( KIcon("arrow-down") );
+    m_ui->btnMoveDown->setEnabled( false );
+
+    connect( m_ui->list, SIGNAL( currentRowChanged(int) ), this, SLOT( slotRowChanged(int) ) );
+    connect( m_ui->btnAdd, SIGNAL( clicked(bool) ), this, SLOT( slotAdd(bool) ) );
+    connect( m_ui->btnRemove, SIGNAL( clicked(bool) ), this, SLOT( slotRemove(bool) ) );
+    connect( m_ui->btnMoveUp, SIGNAL( clicked(bool) ), this, SLOT( slotMoveUp(bool) ) );
+    connect( m_ui->btnMoveDown, SIGNAL( clicked(bool) ), this, SLOT( slotMoveDown(bool) ) );
+}
+
+WidgetAnnotTools::~WidgetAnnotTools()
+{
+    delete m_ui;
+}
+
+/* Before returning the XML strings, this functions updates the name, id and
+ * shortcut properties.
+ * Note: The shortcut is only assigned to the first nine tools */
+QStringList WidgetAnnotTools::tools() const
+{
+    QStringList res;
+
+    const int count = m_ui->list->count();
+    for ( int i = 0; i < count; ++i )
+    {
+        QListWidgetItem * listEntry = m_ui->list->item(i);
+
+        // Parse associated DOM data
+        QDomDocument doc;
+        doc.setContent( listEntry->data( Qt::UserRole ).value<QString>() );
+
+        // Set name and id
+        QDomElement toolElement = doc.documentElement();
+        toolElement.setAttribute( "name", listEntry->text() );
+        toolElement.setAttribute( "id", i+1 );
+
+        // Remove old shortcut, if any
+        QDomNode oldShortcut = toolElement.elementsByTagName( "shortcut" ).item( 0 );
+        if ( oldShortcut.isElement() )
+            toolElement.removeChild( oldShortcut );
+
+        // Create new shortcut element
+        if ( i < 9 )
+        {
+            QDomElement newShortcut = doc.createElement( "shortcut" );
+            newShortcut.appendChild( doc.createTextNode(QString::number( i+1 )) );
+            toolElement.appendChild( newShortcut );
+        }
+
+        // Append to output
+        res << doc.toString(-1);
+    }
+
+    return res;
+}
+
+void WidgetAnnotTools::setTools(const QStringList& items)
+{
+    m_ui->list->clear();
+
+    // Parse each string and populate the list widget
+    foreach ( const QString &toolXml, items )
+    {
+        QDomDocument entryParser;
+        if ( !entryParser.setContent( toolXml ) )
+            kWarning() << "Skipping malformed tool XML string";
+
+        QDomElement toolElement = entryParser.documentElement();
+        if ( toolElement.tagName() == "tool" )
+        {
+            // Create list item and attach the source XML string as data
+            const QString itemText = toolElement.attribute( "name" );
+            QListWidgetItem * listEntry = new QListWidgetItem( itemText, m_ui->list );
+            listEntry->setData( Qt::UserRole, qVariantFromValue(toolXml) );
+        }
+    }
+
+    updateButtons();
+}
+
+void WidgetAnnotTools::updateButtons()
+{
+    const int row = m_ui->list->currentRow();
+    const int last = m_ui->list->count() - 1;
+
+    m_ui->btnRemove->setEnabled( row != -1 );
+    m_ui->btnMoveUp->setEnabled( row > 0 );
+    m_ui->btnMoveDown->setEnabled( row != -1 && row != last );
+}
+
+void WidgetAnnotTools::slotRowChanged( int )
+{
+    updateButtons();
+}
+
+void WidgetAnnotTools::slotAdd( bool )
+{
+    KMessageBox::sorry( this, i18n( "Not implemented yet" ) );
+}
+
+void WidgetAnnotTools::slotRemove( bool )
+{
+    const int row = m_ui->list->currentRow();
+    delete m_ui->list->takeItem(row);
+    updateButtons();
+    emit changed();
+}
+
+void WidgetAnnotTools::slotMoveUp( bool )
+{
+    const int row = m_ui->list->currentRow();
+    m_ui->list->insertItem( row, m_ui->list->takeItem(row-1) );
+    m_ui->list->scrollToItem( m_ui->list->currentItem() );
+    updateButtons();
+    emit changed();
+}
+
+void WidgetAnnotTools::slotMoveDown( bool )
+{
+    const int row = m_ui->list->currentRow();
+    m_ui->list->insertItem( row, m_ui->list->takeItem(row+1) );
+    m_ui->list->scrollToItem( m_ui->list->currentItem() );
+    updateButtons();
+    emit changed();
+}
+
+#include "moc_widgetannottools.cpp"
diff --git a/conf/widgetannottools.h b/conf/widgetannottools.h
new file mode 100644
index 0000000..9103288
--- /dev/null
+++ b/conf/widgetannottools.h
@@ -0,0 +1,47 @@
+/***************************************************************************
+ *   Copyright (C) 2012 by Fabio D'Urso <fabiodurso at hotmail.it>            *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ ***************************************************************************/
+
+#ifndef _WIDGETANNOTTOOLS_H_
+#define _WIDGETANNOTTOOLS_H_
+
+#include <qwidget.h>
+
+class QListWidgetItem;
+class Ui_WidgetAnnotToolsBase;
+
+class WidgetAnnotTools : public QWidget
+{
+    Q_OBJECT
+
+    Q_PROPERTY( QStringList tools READ tools WRITE setTools NOTIFY changed USER true )
+
+    public:
+        WidgetAnnotTools( QWidget * parent = 0 );
+        ~WidgetAnnotTools();
+
+        QStringList tools() const;
+        void setTools(const QStringList& items);
+
+    Q_SIGNALS:
+        void changed();
+
+    private:
+        void updateButtons();
+
+        Ui_WidgetAnnotToolsBase *m_ui;
+
+    private slots:
+        void slotRowChanged( int );
+        void slotAdd( bool );
+        void slotRemove( bool );
+        void slotMoveUp( bool );
+        void slotMoveDown( bool );
+};
+
+#endif
diff --git a/conf/widgetannottoolsbase.ui b/conf/widgetannottoolsbase.ui
new file mode 100644
index 0000000..0a3e0ce
--- /dev/null
+++ b/conf/widgetannottoolsbase.ui
@@ -0,0 +1,72 @@
+<ui version="4.0" >
+ <class>WidgetAnnotToolsBase</class>
+ <widget class="QWidget" name="WidgetAnnotToolsBase" >
+  <property name="geometry" >
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>374</width>
+    <height>327</height>
+   </rect>
+  </property>
+  <layout class="QHBoxLayout">
+   <item>
+    <widget class="QListWidget" name="list"/>
+   </item>
+   <item>
+    <layout class="QVBoxLayout" name="verticalLayout">
+     <item>
+      <widget class="KPushButton" name="btnAdd">
+       <property name="text">
+        <string>&Add...</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="KPushButton" name="btnRemove">
+       <property name="text">
+        <string>&Remove</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="KPushButton" name="btnMoveUp">
+       <property name="text">
+        <string>Move &Up</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="KPushButton" name="btnMoveDown">
+       <property name="text">
+        <string>Move &Down</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <spacer>
+       <property name="orientation">
+        <enum>Qt::Vertical</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>20</width>
+         <height>40</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+    </layout>
+   </item>
+  </layout>
+ </widget>
+ <customwidgets>
+  <customwidget>
+   <class>KPushButton</class>
+   <extends>QPushButton</extends>
+   <header>kpushbutton.h</header>
+  </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections/>
+</ui>
-- 
1.7.6.5


From 8e710a43210a9f64d4e485d1944fd86aa04e83cb Mon Sep 17 00:00:00 2001
From: Fabio D'Urso <fabiodurso at hotmail.it>
Date: Mon, 11 Jun 2012 18:13:18 +0200
Subject: [PATCH 07/43] Added support to create new annotation tools

---
 conf/widgetannottools.cpp |  161 ++++++++++++++++++++++++++++++++++++++++++++-
 conf/widgetannottools.h   |   24 +++++++
 2 files changed, 183 insertions(+), 2 deletions(-)

diff --git a/conf/widgetannottools.cpp b/conf/widgetannottools.cpp
index 6817b8b..0a55271 100644
--- a/conf/widgetannottools.cpp
+++ b/conf/widgetannottools.cpp
@@ -9,13 +9,19 @@
 
 #include "widgetannottools.h"
 
+#include <kcolorbutton.h>
+#include <kcombobox.h>
 #include <kdebug.h>
 #include <kicon.h>
-#include <kmessagebox.h>
+#include <klineedit.h>
+#include <knuminput.h>
 #include <kpushbutton.h>
 
+#include <QtGui/QGroupBox>
+#include <QtGui/QLabel>
 #include <QtGui/QListWidget>
 #include <QtGui/QListWidgetItem>
+#include <QtGui/QStackedWidget>
 #include <QtXml/QDomDocument>
 #include <QtXml/QDomElement>
 
@@ -129,7 +135,20 @@ void WidgetAnnotTools::slotRowChanged( int )
 
 void WidgetAnnotTools::slotAdd( bool )
 {
-    KMessageBox::sorry( this, i18n( "Not implemented yet" ) );
+    NewAnnotToolDialog t( this );
+
+    if ( t.exec() != QDialog::Accepted )
+        return;
+
+    // Create list entry and attach XML string as data
+    QListWidgetItem * listEntry = new QListWidgetItem( t.name(), m_ui->list );
+    listEntry->setData( Qt::UserRole, qVariantFromValue( t.toolXml() ) );
+
+    // Select and scroll
+    m_ui->list->setCurrentItem( listEntry );
+    m_ui->list->scrollToItem( listEntry );
+    updateButtons();
+    emit changed();
 }
 
 void WidgetAnnotTools::slotRemove( bool )
@@ -158,4 +177,142 @@ void WidgetAnnotTools::slotMoveDown( bool )
     emit changed();
 }
 
+NewAnnotToolDialog::NewAnnotToolDialog( QWidget *parent )
+    : KDialog( parent )
+{
+    setCaption( i18n("Create annotation tool") );
+    setButtons( Ok | Cancel );
+    enableButton( Ok, false );
+    setDefaultButton( Ok );
+
+    QLabel * tmplabel;
+    QWidget *widget = new QWidget( this );
+    QGridLayout * widgetLayout = new QGridLayout( widget );
+
+    setMainWidget(widget);
+
+    m_name = new KLineEdit( widget );
+    connect( m_name, SIGNAL( textEdited(const QString &) ), this, SLOT( slotNameEdited(const QString &) ) );
+    tmplabel = new QLabel( i18n( "&Name:" ), widget );
+    tmplabel->setBuddy( m_name );
+    widgetLayout->addWidget( tmplabel, 0, 0, Qt::AlignRight );
+    widgetLayout->addWidget( m_name, 0, 1 );
+
+    m_type = new KComboBox( false, widget );
+    tmplabel = new QLabel( i18n( "&Type:" ), widget );
+    tmplabel->setBuddy( m_type );
+    widgetLayout->addWidget( tmplabel, 1, 0, Qt::AlignRight );
+    widgetLayout->addWidget( m_type, 1, 1 );
+
+    QGroupBox * appearance = new QGroupBox( i18n( "Appearance" ), widget );
+    QGridLayout * appearanceLayout = new QGridLayout( appearance );
+
+    m_color = new KColorButton( appearance );
+    tmplabel = new QLabel( i18n( "&Color:" ), appearance );
+    m_color->setColor( Qt::green );
+    tmplabel->setBuddy( m_color );
+    appearanceLayout->addWidget( tmplabel, 0, 0, Qt::AlignRight );
+    appearanceLayout->addWidget( m_color, 0, 1 );
+
+    m_opacity = new KIntNumInput( appearance );
+    m_opacity->setRange( 0, 100 );
+    m_opacity->setValue( 100 );
+    m_opacity->setSuffix( i18nc( "Suffix for the opacity level, eg '80 %'", " %" ) );
+    tmplabel = new QLabel( i18n( "&Opacity:" ), appearance );
+    tmplabel->setBuddy( m_opacity );
+    appearanceLayout->addWidget( tmplabel, 1, 0, Qt::AlignRight );
+    appearanceLayout->addWidget( m_opacity, 1, 1 );
+
+    widgetLayout->addWidget( appearance, 2, 0, 1, 2 );
+
+#define TYPE(name, template) \
+    m_type->addItem( name, qVariantFromValue(QString( template )) )
+
+    TYPE( i18n("Note"),
+            "<tool pixmap=\"tool-note-okular\">"
+             "<engine type=\"PickPoint\" color=\"%1\" hoverIcon=\"tool-note\">"
+              "<annotation type=\"Text\" color=\"%1\" opacity=\"%2\" />"
+             "</engine>"
+            "</tool>" );
+    TYPE( i18n("Inline Note" ),
+            "<tool pixmap=\"tool-note-inline-okular\">"
+             "<engine type=\"PickPoint\" color=\"%1\" hoverIcon=\"tool-note-inline\" block=\"true\">"
+              "<annotation type=\"FreeText\" color=\"%1\" opacity=\"%2\" />"
+             "</engine>"
+            "</tool>" );
+    TYPE( i18n("Freehand Line" ),
+            "<tool pixmap=\"tool-ink-okular\">"
+             "<engine type=\"SmoothLine\" color=\"%1\">"
+              "<annotation type=\"Ink\" color=\"%1\" width=\"2\" opacity=\"%2\" />"
+             "</engine>"
+            "</tool>" );
+    TYPE( i18n("Straight Line" ),
+            "<tool pixmap=\"tool-line-okular\">"
+             "<engine type=\"PolyLine\" color=\"%1\" points=\"2\">"
+              "<annotation type=\"Line\" width=\"4\" color=\"%1\" opacity=\"%2\" />"
+             "</engine>"
+            "</tool>" );
+    TYPE( i18n("Polygon" ),
+            "<tool pixmap=\"tool-polygon-okular\">"
+             "<engine type=\"PolyLine\" color=\"%1\" points=\"-1\">"
+              "<annotation type=\"Line\" width=\"4\" color=\"%1\" opacity=\"%2\" />"
+             "</engine>"
+            "</tool>" );
+    TYPE( i18n("Highlight" ),
+            "<tool pixmap=\"tool-highlighter-okular\">"
+             "<engine type=\"TextSelector\" color=\"%1\">"
+              "<annotation type=\"Highlight\" color=\"%1\" opacity=\"%2\" />"
+             "</engine>"
+            "</tool>" );
+    TYPE( i18n("Squiggly" ),
+            "<tool pixmap=\"tool-highlighter-okular\">"
+             "<engine type=\"TextSelector\" color=\"%1\">"
+              "<annotation type=\"Squiggly\" color=\"%1\" opacity=\"%2\" />"
+             "</engine>"
+            "</tool>" );
+    TYPE( i18n("Underline" ),
+            "<tool pixmap=\"tool-underline-okular\">"
+             "<engine type=\"TextSelector\" color=\"%1\">"
+              "<annotation type=\"Underline\" color=\"%1\" opacity=\"%2\" />"
+             "</engine>"
+            "</tool>" );
+    TYPE( i18n("Strike out" ),
+            "<tool pixmap=\"tool-underline-okular\">"
+             "<engine type=\"TextSelector\" color=\"%1\">"
+              "<annotation type=\"StrikeOut\" color=\"%1\" opacity=\"%2\" />"
+             "</engine>"
+            "</tool>" );
+    TYPE( i18n("Ellipse" ),
+            "<tool pixmap=\"tool-ellipse-okular\">"
+             "<engine type=\"PickPoint\" color=\"%1\" block=\"true\">"
+              "<annotation type=\"GeomCircle\" color=\"%1\" opacity=\"%2\" />"
+             "</engine>"
+            "</tool>" );
+    TYPE( i18n("Rectangle" ),
+            "<tool pixmap=\"tool-ellipse-okular\">"
+             "<engine type=\"PickPoint\" color=\"%1\" block=\"true\">"
+              "<annotation type=\"GeomSquare\" color=\"%1\" opacity=\"%2\" />"
+             "</engine>"
+            "</tool>" );
+    // TODO: Stamp
+#undef ADDTYPE
+}
+
+QString NewAnnotToolDialog::name() const
+{
+    return m_name->text();
+}
+
+QString NewAnnotToolDialog::toolXml() const
+{
+    const QString templ = m_type->itemData( m_type->currentIndex() ).value<QString>();
+    const double opacity = (double)m_opacity->value() / 100.0;
+    return templ.arg( m_color->color().name() ).arg( opacity );
+}
+
+void NewAnnotToolDialog::slotNameEdited( const QString &new_name )
+{
+    enableButton( Ok, !new_name.isEmpty() );
+}
+
 #include "moc_widgetannottools.cpp"
diff --git a/conf/widgetannottools.h b/conf/widgetannottools.h
index 9103288..80c8c5f 100644
--- a/conf/widgetannottools.h
+++ b/conf/widgetannottools.h
@@ -10,8 +10,13 @@
 #ifndef _WIDGETANNOTTOOLS_H_
 #define _WIDGETANNOTTOOLS_H_
 
+#include <kdialog.h>
 #include <qwidget.h>
 
+class KLineEdit;
+class KComboBox;
+class KColorButton;
+class KIntNumInput;
 class QListWidgetItem;
 class Ui_WidgetAnnotToolsBase;
 
@@ -44,4 +49,23 @@ class WidgetAnnotTools : public QWidget
         void slotMoveDown( bool );
 };
 
+class NewAnnotToolDialog : public KDialog
+{
+    Q_OBJECT
+
+    public:
+        NewAnnotToolDialog( QWidget *parent = 0 );
+        QString name() const;
+        QString toolXml() const;
+
+    private:
+        KLineEdit * m_name;
+        KComboBox * m_type;
+        KColorButton * m_color;
+        KIntNumInput * m_opacity;
+
+    private slots:
+        void slotNameEdited( const QString &new_name );
+};
+
 #endif
-- 
1.7.6.5


From b66f68b6a13bdddb7d4e55e2c91b305ecb5baf50 Mon Sep 17 00:00:00 2001
From: Fabio D'Urso <fabiodurso at hotmail.it>
Date: Mon, 11 Jun 2012 19:11:48 +0200
Subject: [PATCH 08/43] Fixed localization issues

Translate strings when retrieving the default annotation tool list, so
that we can assume that strings in the AnnotationTools setting are
translated.

Note: In future patches, I'll remove i18n strings from the tool list at all
---
 conf/okular.kcfg         |   11 +++++++++++
 conf/settings.kcfgc      |    2 +-
 ui/pageviewannotator.cpp |    4 ++--
 3 files changed, 14 insertions(+), 3 deletions(-)

diff --git a/conf/okular.kcfg b/conf/okular.kcfg
index a151a13..157a63c 100644
--- a/conf/okular.kcfg
+++ b/conf/okular.kcfg
@@ -330,6 +330,17 @@
                   QDomElement toolElement = toolDescription.toElement();
                   if ( toolElement.tagName() == "tool" )
                   {
+                      // Translate strings
+                      toolElement.setAttribute( "name", i18n( toolElement.attribute("name").toUtf8() ) );
+                      QDomNode tooltip = toolElement.elementsByTagName( "tooltip" ).item( 0 );
+                      if ( tooltip.isElement() )
+                      {
+                          QDomElement trTooltip = doc.createElement( "tooltip" );
+                          QString trTooltipStr = i18nc( "Annotation tool",  tooltip.toElement().text().toUtf8() );
+                          trTooltip.appendChild( doc.createTextNode( trTooltipStr ) );
+                          toolElement.replaceChild( tooltip, trTooltip );
+                      }
+
                       QDomDocument temp;
                       temp.appendChild( temp.importNode( toolElement, true) );
                       // add each <tool>...</tool> as XML string
diff --git a/conf/settings.kcfgc b/conf/settings.kcfgc
index 86c161b..ab9b051 100644
--- a/conf/settings.kcfgc
+++ b/conf/settings.kcfgc
@@ -5,5 +5,5 @@ Mutators=true
 Singleton=true
 Visibility=OKULAR_EXPORT
 IncludeFiles=core/okular_export.h
-SourceIncludeFiles=kstandarddirs.h,qdom.h
+SourceIncludeFiles=klocalizedstring.h,kstandarddirs.h,qdom.h
 MemberVariables=dpointer
diff --git a/ui/pageviewannotator.cpp b/ui/pageviewannotator.cpp
index 87c884e..511b375 100644
--- a/ui/pageviewannotator.cpp
+++ b/ui/pageviewannotator.cpp
@@ -637,7 +637,7 @@ void PageViewAnnotator::reparseConfig()
         {
             AnnotationToolItem item;
             item.id = toolElement.attribute("id").toInt();
-            item.text = i18n( toolElement.attribute( "name" ).toUtf8() );
+            item.text = toolElement.attribute( "name" );
             item.pixmap = toolElement.attribute("pixmap");
             QDomNode shortcutNode = toolElement.elementsByTagName( "shortcut" ).item( 0 );
             if ( shortcutNode.isElement() )
@@ -906,7 +906,7 @@ void PageViewAnnotator::slotToolSelected( int toolID )
             {
                 QString tip = toolSubElement.text();
                 if ( !tip.isEmpty() )
-                    m_pageView->displayMessage( i18nc( "Annotation tool", tip.toUtf8() ), QString(), PageViewMessage::Annotation );
+                    m_pageView->displayMessage( tip, QString(), PageViewMessage::Annotation );
             }
         }
 
-- 
1.7.6.5


From 1353bd4b02719c425d6c21c1def65a57b14060a7 Mon Sep 17 00:00:00 2001
From: Fabio D'Urso <fabiodurso at hotmail.it>
Date: Mon, 11 Jun 2012 21:08:01 +0200
Subject: [PATCH 09/43] Don't hardcode pixmap name in annotation tools' XML
 description

First step towards dynamically-generated tool icons
---
 conf/widgetannottools.cpp |   22 +++++++++++-----------
 ui/data/tools.xml         |   18 +++++++++---------
 ui/pageviewannotator.cpp  |   43 ++++++++++++++++++++++++++++++++++++++++++-
 ui/pageviewannotator.h    |    1 +
 ui/pageviewutils.cpp      |    2 +-
 ui/pageviewutils.h        |    2 +-
 6 files changed, 65 insertions(+), 23 deletions(-)

diff --git a/conf/widgetannottools.cpp b/conf/widgetannottools.cpp
index 0a55271..b0a3945 100644
--- a/conf/widgetannottools.cpp
+++ b/conf/widgetannottools.cpp
@@ -229,67 +229,67 @@ NewAnnotToolDialog::NewAnnotToolDialog( QWidget *parent )
     m_type->addItem( name, qVariantFromValue(QString( template )) )
 
     TYPE( i18n("Note"),
-            "<tool pixmap=\"tool-note-okular\">"
+            "<tool type=\"note-linked\">"
              "<engine type=\"PickPoint\" color=\"%1\" hoverIcon=\"tool-note\">"
               "<annotation type=\"Text\" color=\"%1\" opacity=\"%2\" />"
              "</engine>"
             "</tool>" );
     TYPE( i18n("Inline Note" ),
-            "<tool pixmap=\"tool-note-inline-okular\">"
+            "<tool type=\"note-inline\">"
              "<engine type=\"PickPoint\" color=\"%1\" hoverIcon=\"tool-note-inline\" block=\"true\">"
               "<annotation type=\"FreeText\" color=\"%1\" opacity=\"%2\" />"
              "</engine>"
             "</tool>" );
     TYPE( i18n("Freehand Line" ),
-            "<tool pixmap=\"tool-ink-okular\">"
+            "<tool type=\"ink\">"
              "<engine type=\"SmoothLine\" color=\"%1\">"
               "<annotation type=\"Ink\" color=\"%1\" width=\"2\" opacity=\"%2\" />"
              "</engine>"
             "</tool>" );
     TYPE( i18n("Straight Line" ),
-            "<tool pixmap=\"tool-line-okular\">"
+            "<tool type=\"straight-line\">"
              "<engine type=\"PolyLine\" color=\"%1\" points=\"2\">"
               "<annotation type=\"Line\" width=\"4\" color=\"%1\" opacity=\"%2\" />"
              "</engine>"
             "</tool>" );
     TYPE( i18n("Polygon" ),
-            "<tool pixmap=\"tool-polygon-okular\">"
+            "<tool type=\"polygon\">"
              "<engine type=\"PolyLine\" color=\"%1\" points=\"-1\">"
               "<annotation type=\"Line\" width=\"4\" color=\"%1\" opacity=\"%2\" />"
              "</engine>"
             "</tool>" );
     TYPE( i18n("Highlight" ),
-            "<tool pixmap=\"tool-highlighter-okular\">"
+            "<tool type=\"highlight\">"
              "<engine type=\"TextSelector\" color=\"%1\">"
               "<annotation type=\"Highlight\" color=\"%1\" opacity=\"%2\" />"
              "</engine>"
             "</tool>" );
     TYPE( i18n("Squiggly" ),
-            "<tool pixmap=\"tool-highlighter-okular\">"
+            "<tool type=\"squiggly\">"
              "<engine type=\"TextSelector\" color=\"%1\">"
               "<annotation type=\"Squiggly\" color=\"%1\" opacity=\"%2\" />"
              "</engine>"
             "</tool>" );
     TYPE( i18n("Underline" ),
-            "<tool pixmap=\"tool-underline-okular\">"
+            "<tool type=\"underline\">"
              "<engine type=\"TextSelector\" color=\"%1\">"
               "<annotation type=\"Underline\" color=\"%1\" opacity=\"%2\" />"
              "</engine>"
             "</tool>" );
     TYPE( i18n("Strike out" ),
-            "<tool pixmap=\"tool-underline-okular\">"
+            "<tool type=\"strikeout\">"
              "<engine type=\"TextSelector\" color=\"%1\">"
               "<annotation type=\"StrikeOut\" color=\"%1\" opacity=\"%2\" />"
              "</engine>"
             "</tool>" );
     TYPE( i18n("Ellipse" ),
-            "<tool pixmap=\"tool-ellipse-okular\">"
+            "<tool type=\"ellipse\">"
              "<engine type=\"PickPoint\" color=\"%1\" block=\"true\">"
               "<annotation type=\"GeomCircle\" color=\"%1\" opacity=\"%2\" />"
              "</engine>"
             "</tool>" );
     TYPE( i18n("Rectangle" ),
-            "<tool pixmap=\"tool-ellipse-okular\">"
+            "<tool type=\"rectangle\">"
              "<engine type=\"PickPoint\" color=\"%1\" block=\"true\">"
               "<annotation type=\"GeomSquare\" color=\"%1\" opacity=\"%2\" />"
              "</engine>"
diff --git a/ui/data/tools.xml b/ui/data/tools.xml
index 5e3cb84..867bbd6 100644
--- a/ui/data/tools.xml
+++ b/ui/data/tools.xml
@@ -17,63 +17,63 @@ Engine/Annotation Types [specific attributes]:
     Geom
 -->
 <annotatingTools>
-    <tool id="1" name="Note" pixmap="tool-note-okular">
+    <tool id="1" name="Note" type="note-linked">
         <tooltip>Text Annotation</tooltip>
         <engine type="PickPoint" color="#FFFF00" hoverIcon="tool-note">
             <annotation type="Text" color="#FFFF00" />
         </engine>
         <shortcut>1</shortcut>
     </tool>
-    <tool id="2" name="Inline Note" pixmap="tool-note-inline-okular">
+    <tool id="2" name="Inline Note" type="note-inline">
         <tooltip>Inline Text Annotation (drag to select a zone)</tooltip>
         <engine type="PickPoint" color="#FFFF00" hoverIcon="tool-note-inline" block="true">
             <annotation type="FreeText" color="#FFFF00" />
         </engine>
         <shortcut>2</shortcut>
     </tool>
-    <tool id="3" name="Green Freehand Line" pixmap="tool-ink-okular">
+    <tool id="3" name="Green Freehand Line" type="ink">
         <tooltip>Green Ink</tooltip>
         <engine type="SmoothLine" color="#00FF00">
             <annotation type="Ink" color="#00FF00" width="2" />
         </engine>
         <shortcut>3</shortcut>
     </tool>
-    <tool id="4" name="Yellow Highlighter" pixmap="tool-highlighter-okular">
+    <tool id="4" name="Yellow Highlighter" type="highlight">
         <tooltip>Yellow Highlight</tooltip>
         <engine type="TextSelector" color="#FFFF00">
             <annotation type="Highlight" color="#FFFF00" />
         </engine>
         <shortcut>4</shortcut>
     </tool>
-    <tool id="5" name="Straight Yellow Line" pixmap="tool-line-okular">
+    <tool id="5" name="Straight Yellow Line" type="straight-line">
         <tooltip>Straight Yellow Line</tooltip>
         <engine type="PolyLine" color="#FFE000" points="2">
             <annotation type="Line" width="4" color="#FFE000" />
         </engine>
         <shortcut>5</shortcut>
     </tool>
-    <tool id="6" name="Blue Polygon" pixmap="tool-polygon-okular">
+    <tool id="6" name="Blue Polygon" type="polygon">
         <tooltip>Draw a polygon (click on the first point to close it)</tooltip>
         <engine type="PolyLine" color="#007EEE" points="-1">
             <annotation type="Line" width="4" color="#007EEE" />
         </engine>
         <shortcut>6</shortcut>
     </tool>
-    <tool id="7" name="Stamp" pixmap="tool-stamp-okular">
+    <tool id="7" name="Stamp" type="stamp">
         <tooltip>Put a stamp symbol</tooltip>
         <engine type="PickPoint" hoverIcon="okular" size="64" block="true">
             <annotation type="Stamp" icon="okular"/>
         </engine>
         <shortcut>7</shortcut>
   </tool>
-    <tool id="8" name="Black Underlining" pixmap="tool-underline-okular">
+    <tool id="8" name="Black Underlining" type="underline">
         <tooltip>Underline the text with a black line</tooltip>
         <engine type="TextSelector" color="#000000">
             <annotation type="Underline" color="#000000" />
         </engine>
         <shortcut>8</shortcut>
     </tool>
-    <tool id="9" name="Cyan Ellipse" pixmap="tool-ellipse-okular">
+    <tool id="9" name="Cyan Ellipse" type="ellipse">
         <tooltip>A cyan ellipse</tooltip>
         <engine type="PickPoint" color="#00ffff" block="true">
             <annotation type="GeomCircle" color="#00ffff" />
diff --git a/ui/pageviewannotator.cpp b/ui/pageviewannotator.cpp
index 511b375..ea1f308 100644
--- a/ui/pageviewannotator.cpp
+++ b/ui/pageviewannotator.cpp
@@ -638,7 +638,7 @@ void PageViewAnnotator::reparseConfig()
             AnnotationToolItem item;
             item.id = toolElement.attribute("id").toInt();
             item.text = toolElement.attribute( "name" );
-            item.pixmap = toolElement.attribute("pixmap");
+            item.pixmap = makeToolPixmap( toolElement );
             QDomNode shortcutNode = toolElement.elementsByTagName( "shortcut" ).item( 0 );
             if ( shortcutNode.isElement() )
                 item.shortcut = shortcutNode.toElement().text();
@@ -937,6 +937,47 @@ void PageViewAnnotator::detachAnnotation()
     m_toolBar->selectButton( -1 );
 }
 
+QPixmap PageViewAnnotator::makeToolPixmap( const QDomElement &toolElement )
+{
+    QPixmap pixmap(32, 32);
+    QString iconName;
+
+    const QString annotType = toolElement.attribute( "type" );
+
+    if ( annotType == "note-linked" )
+        iconName = "tool-note-okular";
+    else if ( annotType == "note-inline" )
+        iconName = "tool-note-inline-okular";
+    else if ( annotType == "ink" )
+        iconName = "tool-ink-okular";
+    else if ( annotType == "highlight" )
+        iconName = "tool-highlighter-okular";
+    else if ( annotType == "straight-line" )
+        iconName = "tool-line-okular";
+    else if ( annotType == "polygon" )
+        iconName = "tool-polygon-okular";
+    else if ( annotType == "stamp" )
+        iconName = "tool-stamp-okular";
+    else if ( annotType == "underline" )
+        iconName = "tool-underline-okular";
+    else if ( annotType == "ellipse" )
+        iconName = "tool-ellipse-okular";
+    else
+    {
+        /* Unrecognized annotation type */
+        pixmap.fill( Qt::red );
+    }
+
+    if ( !iconName.isEmpty() )
+    {
+        // Load static image file
+        const QString fileName = "okular/pics/" + iconName + ".png";
+        pixmap.load( KStandardDirs::locate("data", fileName ) );
+    }
+
+    return pixmap;
+}
+
 #include "pageviewannotator.moc"
 
 /* kate: replace-tabs on; indent-width 4; */
diff --git a/ui/pageviewannotator.h b/ui/pageviewannotator.h
index 5884e36..0c89d04 100644
--- a/ui/pageviewannotator.h
+++ b/ui/pageviewannotator.h
@@ -76,6 +76,7 @@ class PageViewAnnotator : public QObject
         void slotToolDoubleClicked( int toolID );
 
     private:
+        static QPixmap makeToolPixmap( const QDomElement &toolElement );
         void detachAnnotation();
 
         // global class pointers
diff --git a/ui/pageviewutils.cpp b/ui/pageviewutils.cpp
index 52196d5..2650867 100644
--- a/ui/pageviewutils.cpp
+++ b/ui/pageviewutils.cpp
@@ -444,7 +444,7 @@ ToolBarButton::ToolBarButton( QWidget * parent, const AnnotationToolItem &item )
     setAutoRaise( true );
     resize( buttonSize, buttonSize );
     setIconSize( QSize( iconSize, iconSize ) );
-    setIcon( KIcon( item.pixmap, GuiUtils::iconLoader() ) );
+    setIcon( QIcon( item.pixmap ) );
     // set shortcut if defined
     if ( !item.shortcut.isEmpty() )
         setShortcut( QKeySequence( item.shortcut ) );
diff --git a/ui/pageviewutils.h b/ui/pageviewutils.h
index 0aaf057..506fe4a 100644
--- a/ui/pageviewutils.h
+++ b/ui/pageviewutils.h
@@ -153,7 +153,7 @@ struct AnnotationToolItem
 
     int id;
     QString text;
-    QString pixmap;
+    QPixmap pixmap;
     QString shortcut;
     bool isText;
 };
-- 
1.7.6.5


From 3f8fb6e9270acdd2eb14638ed753bda71ada9012 Mon Sep 17 00:00:00 2001
From: Fabio D'Urso <fabiodurso at hotmail.it>
Date: Mon, 11 Jun 2012 22:09:49 +0200
Subject: [PATCH 10/43] Paint some annotation tool icons dynamically

So that they are the same color as the annotations they create.
This patch also adds some new icons.

Affected annotation tools:
 - Ellipse
 - Polygon
 - Rectangle (NEW)
 - Squiggly (NEW)
 - Line
 - Strikeout (NEW)
 - Underline

I'll edit the remaining icons in next patches.
---
 ui/data/CMakeLists.txt                |    5 +--
 ui/data/sources/tool-base-okular.svgz |  Bin 0 -> 10758 bytes
 ui/data/tool-base-okular.png          |  Bin 0 -> 870 bytes
 ui/pageviewannotator.cpp              |   86 +++++++++++++++++++++++++++++----
 4 files changed, 77 insertions(+), 14 deletions(-)
 create mode 100644 ui/data/sources/tool-base-okular.svgz
 create mode 100644 ui/data/tool-base-okular.png

diff --git a/ui/data/CMakeLists.txt b/ui/data/CMakeLists.txt
index 6501be5..0734f1a 100644
--- a/ui/data/CMakeLists.txt
+++ b/ui/data/CMakeLists.txt
@@ -8,17 +8,14 @@ install(FILES
 
 # install annotation tool images
 install(FILES
-   tool-ellipse-okular.png
+   tool-base-okular.png
    tool-highlighter-okular.png
    tool-ink-okular.png
-   tool-line-okular.png
    tool-note.png
    tool-note-okular.png
    tool-note-inline.png
    tool-note-inline-okular.png
-   tool-polygon-okular.png
    tool-stamp-okular.png
-   tool-underline-okular.png
    DESTINATION ${DATA_INSTALL_DIR}/okular/pics)
 # install annotation page images
 install(FILES
diff --git a/ui/data/sources/tool-base-okular.svgz b/ui/data/sources/tool-base-okular.svgz
new file mode 100644
index 0000000000000000000000000000000000000000..c761eff1780815edb5c80a0c21d83f092210482b
GIT binary patch
literal 10758
zcmV+hD*4qPiwFP!000000PTHSbK6*w=6nANuKQ&sMx at UD;<jrZreiiHVmBsYXFB#-
zCDFE~WXU0^%69$w&CD+kKoE4nJq?1YUMix>I3xfboXeM)UtaL$pTB&(Tm7<qe7b$O
zfBVXA%&XP*{`%qO_Wu3bSAY4>e_fYXtEcCy`<tt~hx_f at SN9LE{`rSLy!jvN_3B?9
zw^z^Go7Lyr=MSrYyZ`Cw`s&km^$#DOpFh36y!`z6^X67R+&nzKzx>D5di}#6{_y7M
zm-l~Ityc8A_fM~HuHU}W3qJk)cqb>`TwiYQwja0m&rg?jV=rIzr(gG{U-Pfu{<6J(
z`1tYR{z<O9fBNIj$&WYhy0f`ApS_%9Yps{YT{^d>GuBUE at 1L)}tcRCU9}ivXj4_w=
zU4Q2Ho%Q;O2J{pC*PY%z*gQS_{CK^6N7rpP_uJ>oKmX^SyD!&fbMt(&bDK7vgI^sC
z^8MAv?bD~L>+REJ`&_Oc%rJlO`S#}d12tWd=7;U=`w!23`}XGTD|!T%OhQ|4_PV=~
z*@UvOtH+uX?$~<$`sU%9yYcqb^TWg4`tJ6AyMFlT=ew)N4c+nA;qA6xK0Q1>uixF?
zZE?-zhlh{b%Xe2l-acGD{B(&6FMqzhyt#V5x|BQqc=goX at zeeLgE#zg^N9xAxlKIy
z_1FIEAL#oxUEjGAH^1C&Kl4?q)u*fXw7~8j9^bzD<2(6#g)e at 5c)Zy at wy%=>4ZeDy
zNw|IfN+YTtKm7P#+w14&hr8|L)%`U+sWtk|`$w9KL!bYAd$T?CMfWt^z3zt&e*5&{
z>gM4yJ?j3KpKtH!i?uF;6h>F;32kA7(w#v|qZ=ldyng)j;o&ns$=g@&uI`?;`?ve`
z;o&27V`Fl$F7AJO{e}B5`t<9ePqkxT4m`1bb!ag3tB+S-Za?1sy1hAY%Jt8Wj|4jF
zyQ{C;$A0;*E at g?_Y~MZg1Hdi%wzO|QZlAAsh4yE(Ph7HA78#vIc=P)I{P|zeqW1Om
z>;L=k_>(s2k59Pz@!@A0 at K--{AHTV|eoYAR@#^`9+mAG<3 at -mfi16mJ|6*|R^Vd(?
z{-(I?;}%eJ5N~g;Ki=|1m;dp6dw2J5{3H5gJ2$<3zT5sFzlp>46qouK`jD49Px<Du
z4TH4a_roKD+zrg9tLG2x$9U{k>sU9nRG%->#(P_AEUUHKuG57xe#2v$gIis%%!OH5
z8#c)p>*{{vZbi3A&S&p0)_NG|nzapnljzvfP1ba)jdQ*vy5iSYtsC4)?p83ib{{@H
zf4!p-)IImwY}}s+y6#@zlWhFc)AQrQPutgjH1elS?6B9NH5m^7>*4nP_2a|O_c!fR
z8vX6#9j(mg{>=6xwtaAOMZ5X&@#?GmTsJ=l1}|A1ys{}a6d&^b;6*>f;L%Mc2G586
zp_AcKES0hApR<3W_wAx*g1#qS;q+Kn&yTlX{=sd0akUhCLA}2~D|^emDg-Vu@*%Am
zQ**TcIOx#(8auSw>ra%w{r+?-oG0z- at qa#E-P{sD^gHW|efw(dX=r?nwO=Kx)mQ!^
zhE4P#)w1)&7x(s6j2mxj+&!H>4J1%q*!@(t$>5i*jV|q+ at m@dw%l+*$sUkl=Z6E)G
zh5x_b|Ai2EXZt=qKYZE+1QGA_8Q*ZXd)=_`munGkum4!&?@#hkKRCM=J-mDOw0&ks
z9e~Df{Hixozxt#6eb2AjonL)(IUKR>^W9CN+a%acD)qvpjVrtzNZq0ZbU~ZiMQ+#>
zsNqZHhD(_mp*s1-_zU?zH+*v3sFoW!7rsG~Yl5X+LHA7DD3R|*JB;=W&3|qUy2jBp
z{Hdw5c<Jg;c3L?^-gI;}ZN821m5+mQE51I-8I|^`*`!2Y`Hhc>w{|<zR=F%n!+YO1
zg3Y)wiDY?p>W2J`^xc#weX)tI at J4>fN*AKVdD-%h63BE70tR{zzK9>y6x$uU;2CW;
zCdeomFQbHpwLF-Kp6HI7>7va=krDSeiMBXB>29OcD))3Hau+SnTyTYsYslR(ZFvSZ
z>6`pmrbZ4j8qw`QRu5V==H1o#9YC?O{(ciGLZn6It+D%1ks^(W%X>gUpZXHQ5Lp;1
zB27Z5Q&8dk%uwOuNuVOX0H}y0P~C+Ky!x at djO^{mYtL9ggU}s at Br7vT*;vkn3%hYx
zy96V&{+t|#kOWisxYF+B1upOqQ)vzQK4yjoTJTuGbaOhzT5MvEpD3~o9pEW=cOgI3
zx99>oQ?`5bvR82h?;-j*KEY=`_F1m=d`z0UTu{P_A*-|oLq?XJ4uF$=F3$o)G!dYn
zEg*><z)G?TYF3~s_gG``qh1;@%3bM^2 at eG`Ng3qMu)aZ%Dmy>($hpY7J!dbF&70ho
zpvU}sMf%J4<6g+qB{_BkT at 0TDVSF2c@oS*Em%GXkX3yZ_bHT``*5DKPG*X$k5rZJM
z!9^uuzNnMGu0BFI1kBRvUwB0sSx^K>A#6&B+%Sb3iJs2+O^pG4p-mw7buyj~17v){
z%vZFs^qQ`;X1i9o!UIFPo=6kNy^c=0Mk*6OLdaN!+{gioEtCr$y1J6v at L5h|Mr9!v
z3lE%=k;+wO3xjWXkb~uOyk*gpYU+*&!=#I{PO=SH4Lo%fA}$sux0U(8gatfu33UZI
z$_upclSsGt4kba9$VDk*b;)4RJbVk-^KpRPks at kr*@yLzs7qlV)f2C>eMonkXi6DK
zhJ&CU%*>!3+$lgkgcktnnbsHWw9E*GjTWOQY}h14P+eflXWuuR_W)!ccVG?;Zxm&%
z5y=2V at JaTHleL-&K>;|jk4qFgmM at UCYvj}@U|U3mk_K%`*AzkTn-aB#YNc9~Xn3-f
z0w6;6Rls>x_AyjH99vdg^=$rq*ByKAJbwm7m=#8rL(qydqXJoAP}gkb?<#HQYxymC
z-r}<WY~X$eL1Wq;+^EsYX#)5mu`DTGdQONTpj}#ne?FmuUO?81D(a$iHVY_Ooh}{}
z(WqnXj$Lwih*;5Y5e*qgZMoM85NaR_ZLxsYCKY7j>P}0{V(y(_8!raSYl5HO33 at uw
z{(X at diB4cLS731xTm@!}?huSf5HB|%E3t1B6-ma(a-{wrMzaC5%!y`cLr9tS(Twfc
zTu4#h1GLQQXpLrsX_>X9_#K#*=f<>p3QUXk^q3ZDzme#5kqoK|iiegft45CWS5gCH
zmlu)pI1WXapJx8iUZX~WvX at 0<tGSp&sdA!BGP01GT174sh{|$>x{&~-&~1xPP(E1e
zjZPYwFp+s+=qO?yM%F|KBV<3*t=IIuZ^tbEvF}JB-od}xG*#>=MZ**U#<Hc8%Uz2*
ztpJ)5EK}*da||UZ$SJ^`07MF6)Yj-Q6p^1ebq#*r0HsnMoF9n4NkSk9zGi_WQDLZG
zqH(3}I96b+!hj1=&;rlNU_qLLJbV at 0ve4q9ShfsD+}WrN)-R2WGC!?@g%Wax)+iub
zV8JKWo*hmM{CGZeoCCum6n-E3Mro?Lt7?4j*c~1UTx;n(MN$52Qr at G8k)te%h!;#?
z5S27Ta}AYkq;KhM1AS>;y)6|tGRI?L_8<)mZ$`QjS!$b__K=Quor^<5{UFlCFf-D{
zbP}YS<O~-;y2O+TBb|_Uj1``@Fj+mkQJDuOow|mVBeCmR17?O%3q#bG?l{&0g#ori
zVgQP&^pNdM;1 at lV9+K>|7k!Z5^%c4r+t*|=ODAaW at IE69WGHjC2bBoh6NFk$K`^x)
z3qk->EbJ=Z9Vb?Klw1&<jJp>K)Yb;=P|1v7s&~qxi6!enIT*o=nEK<)q#plPhMgw>
zV;h_Ys~V(mXhtMKp@(x~j?=>h4{g>7Ti4K^)I;h~bpq?8;S%5%h7X>EcFYLn6xdB}
z%5&eU459)&s!BsY_CYi}kp$2}xz`HVP^C>$3Zcq(aw_vSeS={hL;$GI*fA?SnmY}l
zHALqF8(D+`@Uj2`jLw)v(&3R<=cRA@!{{(=2J|g7I$0_PEGdi)h&y9cA!W!km at zBF
zvk9v62M{iD7RVRvwC@|vHUmYeTH|(F-UNMkR*>bE@}PNzrNfUDMZI<y32-zKazYk~
zTIvy_Zvz&y3u?$nGdkEVSTaI9Yoj(M%7Q2{AZ46`o}S81s~>+O<1h3WKRHhVlmn5n
zrKuB<zky1CModAeXAHUwt&-xx$jgOdYH&~RqcRy#<2{HiG at Q@P^n*NY3Wib_x?+t7
zt)<+AJiD>r+pt|shJvNCn%Nn?J?KQ415q1rn2j>^P8UmzSnlY0l2!r at m%z0^kI|Lv
zmE&v2F#9~XO4%1U_EColng{C>oqlE5<3>}LfiVVVUoPJg*yT6^n}^JC1kadjA#6#>
zk7RZwMJeVmuv)}AsSMU`@cBWRo$SmqJNZ+{>@-Q<A75stLQ*<0(doQOiYTJDGD5LP
z<sF+~S<}FisNnS}Xd?8b03S_0%dI3DaS&EGL+y9W-v}rqFtOOR$?EO`QmQ7bW&>P7
zCGNCROpU}5xN{DsMH1N}8<(sm-N)GZ8BRCCN)V9XR|@1<Xbp=E2qOk~4t at bdgtZWZ
zvL%_L6_74sr1=KqjLx-hSoRz6>FQoA-La2K;$)CGLZSo!mX-aU=?rKL!fz*%XR0yC
z#&`XhQL$MX$whU%$y17U667I0bbUE?B}&IqQu(qH9|TZO%oD(zIPAQKfhJ5*7E_GW
zIaMs=!DtwSMfc#nSkDvb6$H->R6q+`%?LZ>bGHV>71N0?S2_vLOA59PA17Q9RI3uR
zYlqi~u+E|kWQJSVi>OvnBz9c at cxKfXfTUF|BMah7<&3uY*{~*3FA6-C9u}KFjIznZ
zqo8bHqt_h3SYK#tNAV2RGoi3=5{b=ez5`y%%<!5gLko at puX&P2Uj$xxak at mC2Nbp#
z1}-&^x@=FUYf{w5h+U2b`+x*7JVFh`0VZpbx42K(3(9uL3J#*rTC0TTPJ at YD0~%eS
zEAO<JrN)XEMbnqYB6LJ{u}mtlRYNclNpDkY27I##&}fB;Wj&UE-nhOYr$K$gj>Db~
zU^{FG%>cqbAc*abj>V6O&Aw_nxD{_!5L%aDm)RbKe#kMQp5R>p1<pYg%(QsGPEf-!
ziRP+4WDnxmi{+Kkh+t at pYYl!%t4JzN2pOd+HeRsc?8S4L#ThC+N;d1UaBpA%gFcs7
zvNeFnW?l}GFbDw^AV{l_<*ADO76pN&A^ukZTmT+aeU?!?Wv~|rIh2sHfG-vv*Fxh<
zHwAR1_u?@xp?1f?;7PLvYosc~q&h~jvY65fk&5b2fs+vCziUg&L+Zhu;8lBvF`{|^
zL@%s;pOib3?-C at ww!H0le_7zgLRYC5a5dh63FD!x=^I>qvhFBQZK)$eF#w>>?86y{
zo{<1&N5}}Q$s{*<sI(sh>m26>>&f7bqk#3Kf8h9FodfSe at K;J(fG-vvS%VBD3<JlZ
zBB;b8Uc`!7nxcky at Ril7mrCFOUa#a45P^s?*EJN!8x1R)SU^;LVTf+9P@}C?TU_;E
zyVH^=t9A*WioGZJ<CRSo0vub)7I+~c1uA2t27DydMO_A$6IvjK@@Cl2p at Kq)p=((P
zDM%2}Je9E*?`KAEixGOm!{QaVkiG1nT|;pTp#PjIXF_5}jqE50$cdtoLg~wLA1`8(
zX+rovVQC~04zSXt8x=ZdN`tWw1r$&pL<k^KqNqOwPUlqAqayRlwuwaZFayPL7wl9O
zIx2<I0!^YA>s~xS@~g6#Qg1w^uwzLHb1A?kGbpxz6VG!HDT8Ar4M43ms{~Igs;X7C
zNL;__#zp*xHe%<$hB2Y;3SFoGYG1$M0Z6tU1wRQV2`CTI36XuW`>sy1?|40r_<vHo
zNWq!r{|7gm13$}T9K|v4vrKv&7QoLUjx-m9C<auBT9LpKqy&#Ugmq-Chrq43*#ZC$
zp<PNjnBZH30j>cgv_!yWG8(`J?hQ<wn%EA27oZ$zE0xd`5&?7gPn~U>i9_|pl1;IL
z4g-{fA>A6)HQH9gb!}tx<U?55YBUGX63s4lCMxA8)^aZ0vGcIy8xao6A2AE8Nfy05
zLPR{aYQmLjMhHSAr3ItAfCdO<T~zYWC~7Ad>iY(nnUHA!4GY8-Jyx_rJuc7+HK2|i
zo|e#BpdT7=$TCD(P$^sC2fX!tBe4vE9RRh^DoqL|U9AFzE;Z35bWP`8Ml9r=#x92n
zB3=2^q8zG%oPo9EdqP#2AGuJ+Q00>Podkb13LE|c4a33Z?X;>&zkDOEcgTO8gPnV&
zHai|vO4to{_qYY3u(Q%bmbVLS8hMl`%NB%DXJW{qP$6utAW}WDTgbClh`Ybz70N2h
zt7n%;hFQS|k7FmcxP_8y4UL=uiGmFkeb=(0T<FlOjYggu)6sZF)EwS;-=s|jITSPM
z;(<fTN6usp`u5Hb!eB&}ILEs9e$-52mvqU~#7U_$%aS at 7zj6#&QYYE)<I9pltC6h#
zvoHDVOFsLO&%WfdFZm_;lG7lMX+~eNXZ1FwapI<rwCtlF1-d3rKsMse3ZYAJ)3#ro
zJ9D$1B6BmDmyo&1tH)jV%pqWE`$_1&@*12`X_3i at d>zKl(A$2h^TPIv3BKphj(O7t
zHT^VpzL8@}3xj|IwQn^k2ipiTKwG8pQrWdsNYP&<K_-ZBFM=Myb$Kf+t8$Z!9LyVA
zL+C)z<H$Dyc_y39fid!MGMC1kIanD%W7*5aj<dw}4fZzdBs7?o7o_=SzzK-O<|`S-
z#iPd&t`fxOLlw$uZ?JJtyJM#654cKT|29`i4&}o0|64YwaCBfIt)NL(%SD2VRip70
ziLs(@37_Rf%;DHs44_UVGktxYtvDv2l|&it=9Lbt1ai{T8nFpbQ7%Avf|?UioFP}M
zWerNgdU at Hg?xNlnv6W*%NVFtWl`Km%i1a8hyE`d`lwG6}C$V;I%P#Q-u446Wi0lO!
zS99lmDUcE-YA0d7GAAb*g+_H_kAQd#_%R<;<|kj(oaZZwsE#U2cV@$j9a$m#xWPFe
zAgcp7580ZMI~K$^#j)3AP*vtzj<A+~k(wQlSh*9ztZB;zEG3ql{g%5W94UjBL__i^
zk8Hd^v!Cq9#>;`m#gq|Yn8?x~oo&+LlFZCGyhC5nazf)J<nU&3e)@FI;XUW at 4s&=z
zpEMgab?)0aym)xY;Z4*jUQnFFn`B&kk{sShQk=etC(hyJB at X>ymK<L6>cly`DI6(>
z*A|-YGJ<yRc=+~9GZ3(coW at b5Nw|GKne&$H%z3=S0E5MV-M)Z4-sr?}LtD>9*K{4x
zuAr>eAhvrI%ngnSBnJ9*v-cyYqEZn_%0-PdM at t$8wO{0Xs8o7&3L2 at WTm!fdjdQ|x
zA at 8<|Q7?ooxo1m)q{Lcmf?VOiNm+`y1lJWqsY?9FPo<vIabSDUAZ%#Nx%z|bPAet3
zIdpD~$$^hqqP$ouh5~K`zS^-5h-^yD5ymH1qbjuK0aM2>g80_ew{X$vu2!_;1Op6>
ztV9Y3dn+7Cgp<XE?pQj<9Sg9+qQnb1RaJ$3$Qm)rs3Zee6B`p8GR2;?Jn*D{OIeJ^
z%A*Y|b^MrM2n>V=TmpsELNXj`-ba;6o%i)SP-W&!+M(NhF;sCcA(NISFP*i;v$i;o
zwg at E<kuV0U#OvvyH0YMjg_Eg^GnagM8R}v>QtB{Q?y<p)Yk3LkTQdgtz_G&zR7TG^
z*3+e5NPx}^?(P)H!)dzU;3CPxiMfD!F8y+0&ZS>|ccouaI!=D2XA}-~tg$-BPL;R^
zY1MQ1svFarnH{>*KCv{2ewhQ({3&uP({y3P1(JWfR7COl98ccj$^X|XIT{om6JO8a
z<on^|;)(e?3MYq5{JwDVe4Nb5NLC%$=?9fU6Ji)Cg|)D^EsUZHQenrXopuoUnbRkS
zp0mXebh--RBI%O^08AsElhdJPo|Ds8-=CcRzgH<rwJ^_Bg2ReXQjYTfm#OLHIQfp5
zm+wIZHL|BYjiaoMXKA@#Z9fYu76$J1gZLU|&UhTUua?8tmyq!&p(?D6rINegTGN6;
zYfByJjw`G<=lYED7NQd2pHT`dXH~vr|B8X-p`g~*Xx;?Td^Fw?I|D%IlbX1IQ&3|L
zTQkPG)2a<6QD9zB)e0MjU?YJCjb=q~Wdx at er2`1e@=aNWd8^;U7#HC38X_x at 2_W`}
zXM$oB5Q17%*A at d_!>Ow4?QCw`36?<NQVGHL-C-UiShFQ8NkFr3tZM|7G9Cd9gkjKB
zY0DArTuQNTNJR0fb5^Mc5JMJTF^jh&0I$KfCX1Ah7$qn^OVU4wv>OD(ThPwR;!1#A
zb~=BdQP0wMz!oeLtyEBY?g9boMy+{`po58`Y>y<#u=X3;EU|3mYj6WWdcTumW3k|X
zz!fSmOMKf>(755`8cCy(c@@rIm{3eNj>S3<+7ohtrz2^Ap_H2R9U7BT8+)55Xb?Jy
z|8L;%aq=du1nrMX#JbFyNZQ9>%M~d`#AhZj_sL9SaGW`7a_I0|41=d at H7<a`T-lO!
z+!{12(7_H=m$t+!N{X44Fm2LwVH#sE0f`GVEqJc1M8PLOm~e=|HSAIBdjO|b9EUU9
zwfq7=tYS1;rNzxkqJtJ{<##plu0V*ZIF8lr1&y{sKQ5M)IW>ceg#$Zk+-y+-(W++X
zQA9{P<X4DZ at 6_B3Uo#pK!Y*31y=blt;Eh4&Eu73f8?u471+JH3W6P1OyKX1s=y?S*
zp;WWF(JI$O6$|)6v+#tu$$f&P9J-e0qfxC!d}oMcO%_gdE%<7M6o4Pl^Dww5ln03>
z=(8wvQd$vT&H6)JtKqfbkx&}~dpJw!ykI(o{KHwbcd6)`T0;}qMMV2nf3`Jj18{?R
zvq&I<bPDQc#RJvQ;#(0 at VH=;(Q3PuVr3K3jqPFI)Wi%~{Zxw=S9DIfJR0{?>Bt*fw
zgLct{w`K`%Erak@*$x`t>bqmF3#L^NMto~dyYa0s3ZPxL_*T41N9F1_V7(qGg|X5q
z+S8)HYDsW1MD}azS;G53z25`&BH{LS+M^X`PGKB6`xXQC>4JU>q%iV^@SuOsDU9b7
z#`QUc at tneVPGNi*DU8`1Cxy|odg%QDaV>`Re$X<VOH*d{xv;_t%^;BXps-Fe=PwR@
z*oz74>GF^Z2<t2<hRlSW-_mh at ONW5V@Bb|w*&Zk9&KE}3QH?{JSzGWUjEl6YUEY6Z
zX0AL8b=skt=gzpxC&{>*F06Qbn5$lRkTc<bQo_If2H|ga3I9$7`|An+`T2e&Lk<%D
z<!>eY>yYsGe at BFWw#P}23xR76kIE!kiCGwxNn{$L)L|_w)-)aO6gN!_mASLy%1N^0
zrmHh90>ZSJecj~P!UE$(;~cGrX)P<Y>>O)+Fls)azP0W0+e`~NwumQ0Y=T4%w??RH
z)H=kyT159ngt-JjnwG`T7nP$lL{#%zf*#aUAPsMI$7B>?4&8B#*l!;8Gi=ucrPO1u
zR at c+IUNhxHwn%phifN~=E;I_4Yi&o32#418t$^I at j+H}JSO;~ZeMj?2Pc?emNfyE6
zN3RSg^{066rq!P^cLrHGNe0<;ExQE at 4!BJvaUBY~#WbJ{WiOouT_zD7Vl!k~_)cOb
z*HXV-<cEj%LZpUxGIHNwjX(`9xHr`HfYE at hptY2}QRxH+O0(AZ-nkiD2zBL52CM0*
z!aG_?X#+Q@##UF6J&Pkv6 at rZN>=9X4L2}y!5E6<`ihZTZfso8DKsQL;v81E%XWDtm
zErMQ_yhPX`$jxcaRqW|HO$yLPRDKA`qJ{RS)HU=9ZFn8Q1nLWMQ&qE3vF(#~tf_7p
zImLkqaHm;+K7mY4J7#<o5>#|4#83N{kikDI&P8!Q;h4k7SP#OZ(eTsK2~r3pS*wIH
zD$clX;LjkEe%>NkcK8nK7H)N*JaXYDtZwus*upP3C$!2_=u_uTajGXtahk5owE+4=
zCWaV&`UF-H at S4E7o56aF6xPyGSZ(J&K(Ij1L}(&om&1x=pxn3qiX2u=09gHY4r_Tq
zIjjPI6FIES7+NxiRWWoYhZSatR6OB2N4%!E;z<yroElv5Byd6Pi;z!T at nk=R6?MQy
zDXcQ~%Vn?{sl&21eFm%M27Xrx>+pRY^Hw}bIUaBykakHcdGz+%#76Z9+am`(Ouzd!
z4}N9_Y#%yRmcsTtT|jG*QdWhxUgc0Mc>7UTJ{$4&2YCAvy#1v$*xjy?P{N@^J+hLQ
zgtSBWyS+LkLPq41l&3RtELcT*fR7~x2`N|>rQ(EMcd0+_iH_QEMe>&5tbp<dvWxGS
zU~^R;rK-5ZCY9_4F7=k1A+_Zz>bcXhl$0eAG8`J!m3Tn}Qh+*_H980G4)G)>&C6``
zT-BU>sNt|>VOApl!DUS;?IIRh%SxT{yGFxf2t^Ck;_pb`(8SZMNo7EQR^SAb78uDs
z6sd3dR;e+g7 at ve<C8?=in)6d!9zE$5)DRZSA%g9P&w~y2b?4}CJB_6IvrSh>%9kPR
z02=lhoFz_LYv`Z2oYqE*E^4F84CF#G>)uNoG`ppFi8K7~GUOl?d1i}O53vk?4p{H1
z>U)F{!1)s;8cQ45H-|`21`h>!lr{vV3BNuD-^e?&Ec|OG$T|)^IcIw**---~g95I7
zLy9BF77%sacZa at IeYYBB+`{6~zKLa_iid2$76)NrJn0G&S#L`7IpY-y-;x^PI4N#x
z&oh?~<hW%nguCZrQMo~KI*oGNiepdLG#i-B%sFmDN7Z7IW4c1uB2{eyp&Cn$bC&S>
z{MM=STc>12d<#S4akALfkx9Ecd^;*M at 4yk(`%dkeSeTD9D2jMi(<G~#?aWzhLod^E
z2>JrD*ka=1d5oaH9lMkJ*qs)-qn=oV?jXHtw$PpQI}Y7JZJhs3=#D6+!l3@$hVJY(
zY!|xIOd-A=C3^n0(4BasG%<E!j7q9nj-Ae<WC9~}-$+X=)b%{|Hl*xk&Ji0r^cF+7
z>5^Ov)IkVRh4bvUx;Xo-j_$Wg$4O*jTQu7P at AWJsZ;COace_{<xa5}~YgnO#Nek7@
zoX9kE=Pial)77&UK%XR0f~;Sig9gt*gXf^Zzb0r9!>mz*sV7AyqXzSF5>%|r at F;qK
zgVAgpmq at i-R$yqXG6+}4Q#^cu)<GEdGpDEwJ#UM_ at N@~T1z<RfW9Dq;p3U69BQv)g
zCqu=Ox at pF5g-SeWBQuvNzA!R#tN0A33;yLWbAHOuPqZAyy at 33b?4`c&S=BtLs(CI*
zHBvQy4+W|I+p1<cPJ)W9Bw}1S<d)9P$2tm?w_KAoj&f9LV$a-n_*CM|IVwYE(_%n8
zT?=cGs#HuNg(6ih;D8l{PS-8F5-qB<TZxvi>@r at hn^QDk;~?NsE3_IxvZQtULxVSc
zg%RjVqhXy0;?aDMtkqUQ9HLf)wo=hr5gvtq9FSJhSj0z3yS1RAl-^ln2b3GU#8Mj~
zN!D;_t`XX??gKrvDybG34Tv at 3DpT^xCXM0p2<OeEJ9ZwbU at PO1c1S?H3byDE2vx}0
zJ8~NE3gCs8dx$T%!xh(Dx>jPYLaVVMZ~+|*jT#{!J>0PtzU;nSl^(O7c-6fw1>9^1
z;#3b7<yV3Af-YROi<No_rqM?7`X()d_%CC%&Vy}_x9*+7TGv!Wh0Z at -HI;W7yG0-%
zy|f at i(IOD)J_c*iLb^mh#j)+>rcsZ-7S0jRcF at ZO^!42exV)W)m^uBXsv06a7aq1P
z3?sFEF*~x}IdMwgxrKON=nYbhENeww%Ui}U;9qDZF|F*S3s(=Neyl{^$?!+6YvY;C
z<?ipq;AM at H;F4<`dnQ&Fmz8yFOh{du<XXevbqKOSQK2lLpqR9*hz%JU7-eECY2`1x
z9?T#aGJUJoY_7-2y>c97Y4d^CcX1h;a)7>YmA1fs>Q&7&8g)ALD#w{quZB*&#RST9
z4Xy<QO63ZH)9l5$z{c;iz(#pt^u;0tHipXWj0HC8hO70BoMoOXIgQok!dqs9a+W=R
zX*vxc&79&j^dK&WaxWmos|1NkkM{f)D|xu{TdZVue>ZQjD&|OuP0o`vb|c at v=c)jQ
z-pnVJ-0~<uog<RSmYS-Jmh;@1P5C65P1A*nW`?xiPEO+uQ}@{%rfiHq_;N+sG;UP)
zpcW3*Nz*w7dF~v8a*`Z_={hG%&Y{~>QY*%(B8m2!9VL%f*45H at 3OO0k<Y~>K%pK%h
zP7>riT`*(8DRi7GyzjraY;}wxs7M2}DHO9GLRHxoGvA>Z*11DC>q$a5r%MhjIDeVu
z&(!hzaw;3Or235B=tvf`H~R&>Nwp#+!%Q+5b>=X*p~17%43_D{;ss~WI!^Z7M^O5-
z*71ur3?r`F-+}xNBvSLHrmvWp!)JyoX0hp;&hA at w`bu{D(^of=%`)~$(di at v_w#(L
zDWrhAsTZXT6Nl!QKzoYVfHIw2w4?-Nu|{UiK7v|)_wB%Wh6(gsZzYc=FfxNQHGghq
zmtt|Ja4DAQ)QM&1&sTp?0*<LIj at TJhxZsGL80_@y&CK5ycMAT#OoyH?ID0;D)~FpN
zO4`D)hoc~VmpQe6WXD^s6XYl5pP!kUEdCVKWSI_HU2*~|*$Q>Pc(aux%8~ypIIhMp
z(mrXjZ75SIV8b+xIi at e1f`%#6 at pubPU&!n;AML)%4*l`;arLgSAHB^w4eiM(7OjMt
z8JH4J!N8R1D4qqUFOv2d!v6F*e*e_idmSQs?8e~9FR`60-8X#2>MYZD3ihQ;`^=Y|
zzPRDHiH~#_$2ojv^m>oTFBclJH8O#DGpt&5aQ at QF>`O_fU|-6#H*m at MWAya<ehB9|
zieSG=j*XS0&B{LgX<g)yfhqQ^q`A45d=l<u+V!y{fnC{2PqxGUi%v-`&8658hE~t+
zMLXg^xgff$X;OvBb2BjcBn-^7?_<eH^qcC<fr3?@Yax{|CSgq4q+$6(nL{ptpQduq
zN|~F3DJS7zrhOj^PGRDDJ)`K9%7szm0S=Ab`Qt4})91=$A&FAw=3wecIGAbQ$C4x{
z5B+dP*tQ_MAna*3?RC*)UX1h at E<S7O^aRdL!_-sIFm>AXu`G#Zsvk`ttEc-OB<mzt
zWJIFT$;J(xn}?>anwd$MYED7I)M?kplG9f?MrhxS8)%zVm&S&m_nWaA8o8p&FkR;0
z{MngVm}*bK!qjQc$C4x(ztxu{)4m}eC9lJd5tLsHIeh00_MqQHKWPe9J2Mkg-6@!u
zI_>;el1TGhD?E&+&~Yq`9TiRG_t+&rp25h;Ia5q_bu*JO)t!QjsnZUSC1<d5PVRn^
zx0C}+X*_?V-Q?&-*&vo~6Oy0YgMMZ at rutLRF?HGlvLqd22}TdR-9CDLgZAi6l03Dv
zVMm$_Se;2l#?MU1)Nl$yrcOISmYhK*WKtOsqA_yFb{X%&WI2sxWJ=H!(uSCFNz^bi
z9aF<8=$Ja~2wBpWC%HyS%UBSSj$?Bj7iLS26Ef{sAq~t5OokQKI5Qzr<0%N4I_(Zw
zG%VC4e;}-oCNa?>AM>J#T}!@>T)S{tOxg4`%}mM+so2HlaM~rZ;2f4sN&7Kq5}eIR
zG>41|!zpua<R2srHr8pCG|f!Q)N~SBX4)&VB(Ek3O9zmY=3^uZEtwA1jJ)#%ubFo2
zB#h>{d6|3?US`@MvgG^~u0OjU979S at ispbMbZHYq9BshFHA*LW(OTvvX39y3nQ3>(
zlEjSTw?B+63NE2s+|UUDt3GW~8mXg+)`6W2 at 2zESUZ$Remzj2mENRtq-J=}GQZTa*
z&>fh;yfMRY7)&8&rj^MltaB4H^(4g1v`b{!7`2q_*g=?>X(?qqg`sY;H=`-cT&+G&
zC^BwXI{I&)Lb~Azm>K%j7sbr at Lj@Ewzg at _<u^^0vBxD{>VC02hCsY}F^m&;Xrr=L8
zgVT<YCCz%rrJ%}a6Xw87%K;}-j9iv4jLdp2JX_6_pNXD+UT%hNcmi&Q*7l3yW-=Ef
z9KNSnC($!GGqNdoc1;~Sdy6Ae(M%Z?ZkVbz$0WKFa5MC)FNvEW6m+>Bm_#m+XnY-o
zjpn?eo$E(Cu~>rN;SN1GiGE&khHiKQa)y3&QF7+Z<$FGmf8Ja^{X+lzKfol#@r(-r
E0G{x^8UO$Q

literal 0
HcmV?d00001

diff --git a/ui/data/tool-base-okular.png b/ui/data/tool-base-okular.png
new file mode 100644
index 0000000000000000000000000000000000000000..cf6eb01338bf5a2d8bef652eae588d926226106a
GIT binary patch
literal 870
zcmV-s1DX7ZP)<h;3K|Lk000e1NJLTq001BW001Be1^@s6b9#F800004b3#c}2nYxW
zd<bNS00009a7bBm000Aa000Aa0e#hi%m4rY8FWQhbW?9;ba!ELWdL_~cP?peYja~^
zaAhuUa%Y?FJQ at H10^><UK~z|U?UYSRD at hcFpYD92M!{8Lzyt&ZAq<+uge*o7{W)&#
z at 40)IS-TM8MnP-{Xo#N)CNaj3*omE>ZMv(@Y_7R;hk?N{qZ{AVDX6OVsZ;fqAtHRH
z4B)p9_Vj=g`El}~*82NLx at WW5ZwChlCZGU<hGG2vkpNRuQ-QyZ&5tzyCw&2Y0R&%*
zN~J=#+a(+hv#_whU@%~EauUz;@O>ZCG>Jqa_`Z)}7`U#>#Kgq=0a~pVhGF3QK6iI_
zBoYY<g#v*<fJ`RC{{B8MFE6aDtdP&=Nu^SByIow at C6~)FGc)rp05cws^Z58kv)QE6
z=`cP%&iwp5y<U%Ivq`JfA|8*kySs~Nnz*jZ^71m_aF}Q``tA-OKjizqY;SK5>vFj)
zT5C~Cy-pFO)Gy=zqP4ZPKY)OUAR<5CKp+qxolXzy#l=Mc48!=@E_3v6_Lm)FvDnBB
z-URR&GCj`&pjxeReSOX5<|gOo=KzQZN-4C~!v(K*2cVQ<Fc^@}=P4G8IF9pXfMB6e
zAd|@qqm{{In46nJDTQTO?CtHbv9ZC{))up~v()Q#9LHg4X^DEhP9l+DFc^?drwN5Z
zZ|^|6-KNoKVB0ni4-YtwgNSf>dCAq)6{%DT%d&7Bhi<n^GMQv-Y>eaM<6#$G|B#!T
zn>PbsS(a$6#kOrxN=c{F5fKrswK$F=T5Ayz>G%86 at ApMS#C2U!N=duj77-EKw&m&R
zNiHrf-W)^zZNaGZcYx1N!KVW#rP$foq0{N0lmehwEYfH+cz%BV-vNTvYL!N#K{A=7
zR4Ne)g*ZJuWqo}e%d&{YVrZ>tx7*mZO*Wh5?CgwSFi0+!dq2S8;UUx0)70yAJkKK<
zjS`7Oh(@E_-`~^g_3%88TCK+F>MG at Od1U4QD5d1+=tx}Gl~SoBzVAz=QjvbYFDEA_
w!#LJzHMzaL72CGOb={Gr;46k-0G|%<CsQO~-e))YApigX07*qoM6N<$g3tJuh5!Hn

literal 0
HcmV?d00001

diff --git a/ui/pageviewannotator.cpp b/ui/pageviewannotator.cpp
index ea1f308..ea2a8a6 100644
--- a/ui/pageviewannotator.cpp
+++ b/ui/pageviewannotator.cpp
@@ -952,20 +952,86 @@ QPixmap PageViewAnnotator::makeToolPixmap( const QDomElement &toolElement )
         iconName = "tool-ink-okular";
     else if ( annotType == "highlight" )
         iconName = "tool-highlighter-okular";
-    else if ( annotType == "straight-line" )
-        iconName = "tool-line-okular";
-    else if ( annotType == "polygon" )
-        iconName = "tool-polygon-okular";
     else if ( annotType == "stamp" )
         iconName = "tool-stamp-okular";
-    else if ( annotType == "underline" )
-        iconName = "tool-underline-okular";
-    else if ( annotType == "ellipse" )
-        iconName = "tool-ellipse-okular";
     else
     {
-        /* Unrecognized annotation type */
-        pixmap.fill( Qt::red );
+        // Load base pixmap. We'll draw on top of it
+        pixmap.load( KStandardDirs::locate("data", "okular/pics/tool-base-okular.png" ) );
+
+        /* Parse the color */
+        QColor engineColor;
+        QDomNodeList engineNodeList = toolElement.elementsByTagName( "engine" );
+        if ( engineNodeList.size() > 0 )
+        {
+            QDomElement engineEl = engineNodeList.item( 0 ).toElement();
+            if ( !engineEl.isNull() && engineEl.hasAttribute( "color" ) )
+                engineColor = QColor( engineEl.attribute( "color" ) );
+        }
+
+        QPainter p( &pixmap );
+
+        if ( annotType == "ellipse" )
+        {
+            p.setRenderHint( QPainter::Antialiasing );
+            p.setPen( QPen( engineColor, 2 ) );
+            p.drawEllipse( 2, 7, 21, 14 );
+        }
+        else if ( annotType == "polygon" )
+        {
+            QPainterPath path;
+            path.moveTo( 0, 7 );
+            path.lineTo( 19, 7 );
+            path.lineTo( 19, 14 );
+            path.lineTo( 23, 14 );
+            path.lineTo( 23, 20 );
+            path.lineTo( 0, 20 );
+            p.setPen( QPen( engineColor, 1 ) );
+            p.drawPath( path );
+        }
+        else if ( annotType == "rectangle" )
+        {
+            p.setRenderHint( QPainter::Antialiasing );
+            p.setPen( QPen( engineColor, 2 ) );
+            p.drawRect( 2, 7, 21, 14 );
+        }
+        else if ( annotType == "squiggly" )
+        {
+            p.setPen( QPen( engineColor, 1, Qt::DotLine ) );
+            p.drawLine( 1, 13, 16, 13 );
+            p.drawLine( 2, 14, 15, 14 );
+            p.drawLine( 0, 20, 19, 20 );
+            p.drawLine( 1, 21, 18, 21 );
+        }
+        else if ( annotType == "straight-line" )
+        {
+            QPainterPath path;
+            path.moveTo( 1, 8 );
+            path.lineTo( 20, 8 );
+            path.lineTo( 1, 27 );
+            path.lineTo( 20, 27 );
+            p.setRenderHint( QPainter::Antialiasing );
+            p.setPen( QPen( engineColor, 1 ) );
+            p.drawPath( path ); // TODO To be discussed: This is not a straight line!
+        }
+        else if ( annotType == "strikeout" )
+        {
+            p.setPen( QPen( engineColor, 1 ) );
+            p.drawLine( 1, 11, 16, 11 );
+            p.drawLine( 0, 18, 19, 18 );
+        }
+        else if ( annotType == "underline" )
+        {
+            p.setPen( QPen( engineColor, 1 ) );
+            p.drawLine( 1, 13, 16, 13 );
+            p.drawLine( 0, 20, 19, 20 );
+        }
+        else
+        {
+            /* Unrecognized annotation type -- It shouldn't happen */
+            p.setPen( QPen( engineColor ) );
+            p.drawText( QPoint(20, 31), "?" );
+        }
     }
 
     if ( !iconName.isEmpty() )
-- 
1.7.6.5


From 47bd2d8474b2823fc894828df689cd8e311013e8 Mon Sep 17 00:00:00 2001
From: Fabio D'Urso <fabiodurso at hotmail.it>
Date: Tue, 12 Jun 2012 12:19:21 +0200
Subject: [PATCH 11/43] Paint some other annotation tool icons dynamically

Affected tools:
 - Note
 - Inline Note
 - Ink
 - Highlighter

Note that the Stamp tool is the only one that's left with a static icon
---
 ui/data/CMakeLists.txt                             |    8 ++--
 .../tool-highlighter-okular-colorizable.svgz       |  Bin 0 -> 10834 bytes
 ui/data/sources/tool-ink-okular-colorizable.svgz   |  Bin 0 -> 5130 bytes
 .../tool-note-inline-okular-colorizable.svgz       |  Bin 0 -> 5028 bytes
 ui/data/sources/tool-note-okular-colorizable.svgz  |  Bin 0 -> 13509 bytes
 ui/data/tool-highlighter-okular-colorizable.png    |  Bin 0 -> 1733 bytes
 ui/data/tool-ink-okular-colorizable.png            |  Bin 0 -> 1770 bytes
 ui/data/tool-note-inline-okular-colorizable.png    |  Bin 0 -> 515 bytes
 ui/data/tool-note-okular-colorizable.png           |  Bin 0 -> 670 bytes
 ui/guiutils.cpp                                    |   39 +++++++++++++
 ui/guiutils.h                                      |    5 ++
 ui/pagepainter.cpp                                 |   35 +------------
 ui/pagepainter.h                                   |    4 --
 ui/pageviewannotator.cpp                           |   57 +++++++++++++-------
 14 files changed, 87 insertions(+), 61 deletions(-)
 create mode 100644 ui/data/sources/tool-highlighter-okular-colorizable.svgz
 create mode 100644 ui/data/sources/tool-ink-okular-colorizable.svgz
 create mode 100644 ui/data/sources/tool-note-inline-okular-colorizable.svgz
 create mode 100644 ui/data/sources/tool-note-okular-colorizable.svgz
 create mode 100644 ui/data/tool-highlighter-okular-colorizable.png
 create mode 100644 ui/data/tool-ink-okular-colorizable.png
 create mode 100644 ui/data/tool-note-inline-okular-colorizable.png
 create mode 100644 ui/data/tool-note-okular-colorizable.png

diff --git a/ui/data/CMakeLists.txt b/ui/data/CMakeLists.txt
index 0734f1a..2fc16e2 100644
--- a/ui/data/CMakeLists.txt
+++ b/ui/data/CMakeLists.txt
@@ -9,12 +9,12 @@ install(FILES
 # install annotation tool images
 install(FILES
    tool-base-okular.png
-   tool-highlighter-okular.png
-   tool-ink-okular.png
+   tool-highlighter-okular-colorizable.png
+   tool-ink-okular-colorizable.png
    tool-note.png
-   tool-note-okular.png
+   tool-note-okular-colorizable.png
    tool-note-inline.png
-   tool-note-inline-okular.png
+   tool-note-inline-okular-colorizable.png
    tool-stamp-okular.png
    DESTINATION ${DATA_INSTALL_DIR}/okular/pics)
 # install annotation page images
diff --git a/ui/data/sources/tool-highlighter-okular-colorizable.svgz b/ui/data/sources/tool-highlighter-okular-colorizable.svgz
new file mode 100644
index 0000000000000000000000000000000000000000..58654400c27b5e7a65dd5d968e9856dd16fe0ebd
GIT binary patch
literal 10834
zcmV-YDy`KYiwFP!000000PTHiZyZOK<#+#zTK1PVwz3%Shb(!3*~T;m at M3|UZtQ28
zEJ<7!SwfMrB>(z7_YskiWKoo8j at 3I@$%gWskrDTvd+sBmUjEC+tKI6??cwHffBovj
zZp_JQdwssYxV(Pz>f|4P|F@}}tZr`4t}o7Z`|Itilk5G-zx?>!%l|e_tN(G>p51OQ
zRv#{J->&}s`j?yYvv=FopWoizzI$<c`r*Te&7~gP><@2Fzh6z$kKcXw^5)k!->p_F
zy!ZO%#l`un6TRWx`@@beyf{DI?zUIk>)V at CyRoMy^X2FB<>&PF%U`$W`>U({^$p*7
zee<W`;={%3el at k`gXfEEt at YHnQ|BgJG2MK+zCHUmEpJ5|kKO8wF{d~;U- at NMz4*98
zS3KAlK0Cf0-Tw~%_Z!-Q&CUM(;e7iVcWyV=+uPH>{QWQe<YYD%w->`>TJJC3yBLz|
zv#agRyR-A{&1pN%_kXy&xP1$0aD{i at ZZF@wy?u4!OW^&>i&rQ3zF at rP{Xu-JT%Zqo
z(a)GoC>y&v)SL`o(pvrEVt-D}cy)5S-|wckc+-yFwmnSyU*7M|4%7L5w?AC|cJ}jb
zyTMz3TfSlY@!kG#JH5W#ZRIhiZ}(T*)7NJ|U+z!$zntD~uil;h{SyR}POtW_SJ&GQ
ztJnM8#rAKfU-HU#*Kdx#@#Doi43Kl1c=YtA`Sg!C|MFt{`i8EP-lIKqpPa*42*CF2
z at YloH#U;dEt{a|-_UyLj7=g3hhqF&NC+z|joEL8oTL}7}md^+!n|>X=^4{q*KgPZ~
z$x!_iQx5&;Cmc-}G+(2ikA8F*W`p50wz&CP9L at Mvywur#^o_pkAJ><+(3JN#+rxj5
zwEeH^f81>EUG?|F+4T)X`|8!n)!FUg^5dV)rkG at WNo&Y<thOY-9ya<(S2m&I#dRIb
zrkb2%`Tk^e`uqC!XrCD!Fg*6=cK at zj3vs^vw1e=`L6M#pe=_{%2R^jNXJ6iadSN!s
zCLfZWJAVb4e0{S;1I%!YRSb9Hovwe%li&Kok+<37ZwqtBoi0CLk3!R+DeYc<>vVaI
zL+|!G0P_BNk}ELaH-G!<zn*+mhs&*@)G&AS>+N69-rw9 at o?ZXz?)_nC^kWaC{<-+e
z_SZ{p7GY5G24YgeoljrB0dG%3CrFb%D@(_v{{c-ou2n}h at IOg2zD_;w>w$Nvd_4p`
zG+Mo<pDb8iZhXl83*_eBh~vKa8L4sAM3<`nI-#H;wI-t1!ypti{4Q@&NWtF~mAWz3
zo3sE`?>EL<JK)6;T*}^0E`}*OKgAd^>iLVtC)+xeXs2Q#-)l>KM(nOBRu>CNDE=vs
z!C|AHv=JYelg(>vxg4DT0_;B01xG&R0nlt<SFFv8QNM?!TSI at BSZa>~_k##MysUoy
zWj}A}@8d7Cj{)?<;uzA#n=lMAgOLSXfQl?le8dptQgdENV{#i4fHCfK(pXHLVzHBT
zW{NdTrTQ;J3qw*Ir|cbu&`$LT5+0YvuNRkN?|O6uo&Wp at zIOEYnZ(7#N5tiV{yu}a
z(B9eZZl9fhgt*jAtqvBYKlc0+BqMGL0CO;D2iUGn at X7i(U;6s!1706}0Dbkc8KKxb
zS(B#}3kIr8Il3=~v<v|(7+?I8hj%|2(QauICTRO-vnFM64&St$(o=EjPWv7gg-4L%
zSz*fCZw^zwfCz<X@&c#GmGULm1x)$02>~wj5~l85dTbzS1~LVVK%Qy}ldtBB1T2O+
zIUojvU~=9}Xy`NAOrIbThHYlsG at ER)HEG;(VFQC=qhGU%fnmm{2;;GDd0apq0j3L2
zf1gVlAF<HKUS^&b1;N0ojWNXq3StCo%{Jr_1??t-YTIZRD0u$?ua7?97z(;HF|#Rk
z0>Dl#gf9}(0 at Is72vaswHD+@8`Ggb*n831fSerHBA($MH46a6nD#C%u*z}v6L(2In
zLV2w1kIG4S1ht;kG>0effF}v%@Ars83FRpsQ7F+YK62?10eURZ!+yO-1PWTgyUWre
z%4t(_DQSW2M=r(D;y1~J8p~(F-NmV-312Y**{%H|r6EOw13eW7Wvf8M^bC=#nLA9*
zf+YFO?vG8`+w^2l=Wa6}7ui43(+Pi+r?b=#KrPIsF%YEahc<lT<1XcB(+r<2#0{T2
z<~(qX7VNg*5Yc!ypLvo3#uA^TfU)GyD4??uIO!jZQ#}K6WHjI at 4bP>1rs2udQfquL
zmhv18k5B9I96#6N87vFV^H)X&3GzySB#r(Yvssw`n1+LdcqMN9V5ynP-o5S^je{dw
zK;J-SD{vvkFM>NFf5l}GV9<&()#nTS0Oy=b)%f+)Hr-JgJ5f%kS`)(Bg0t6}oP8>f
zU4F`=7!@C};m^uq;}a<JlL*5%6+$sfaK=Da)0F&|QB at i{YyAWio@}vG_0LCD0sFOj
zA6Wd_)-=f9ylJa}bw*<#lzHP#f+PG?QM~&(kITm+2J=~kF+D<+pGO#9o>GdFw|b_R
z60jG)UT!~p*PHb7Ss%!EXK%LL1jxv1{-Y;;-XAWuhjuFQpT#L{rBpBIvs<=-p4!iw
z<L7VQo?YxeK+Nx+{B6I#qPx0C&PfdN>+=1>6y9?8UUIQNe^2EM(|Zx*cOUQF`2KL9
z3wCFpw)jf^r;XFi+x>?(2R2w|yWU;>)(@B0X#LdqOfdIeuU9l;Q#;h(y at D82c;MWp
z&z!qD`*?YE`P=qlmWr2G+uO5?v)i+ItlJUT(dLu9JY2kf at wdPHTNm2%^B4bnfB0pV
zHoD;K=ly%MyXz5U)6ZX!rk~yZczJ~pq-u-*{_$!Dsp}^e7vFw*x1Ap<k3DRqn&M~y
z%EkHBCEaxTAGepg-M`aI2IbO+Uf%AuKk_?evwg*>enwM|;VWOBwr=3PH+MR8clPsk
z_v+*)8vm8O+ud&t`}gmz_7_`~kdwJ{7ZP)OJa##yR5m_2_kHXBcW1Y6JDAN0y6fxh
z`7MYSr1ICZ+xLg<n44C}0QuRyP(}TLc4lOf-NXCc_Qm!7`Zp*j(B!cHg?DG%CXraV
z0>*A!T<2uLv1(bFwcFT|;|g99j+ at mvw!rBEHZ4>!1jcY{L&1KI94o_>D>~?7;Y4V3
zh4#Hqma*RjK2Jt$4V0)p(=Moq7jLXO+D}mF%vq`xm<zp}Hg|N&ByNjYr%kNBP^0L@
zAY0T>53gfAIgp)#4}dR=R)tNryk}!5l`c-UrWJ8_K96QNzPazqSM$duZjXsxLV>{~
z{yc6!eFr`m?Xr4A`Y6EfvD8L-ai+%O{eIY`Yw>)%(R=BxkPV$EHF(+&i7u2^*GxU(
z=|%kJQY}A1 at 02If_0m5)RGWx~P`?ImGMik>&qcScX{c)7a~oIiWW%{?Z>bl!^{o>&
zCCE*>TTQMQ$Q9?GsIPIxyR`BfzHajLRO*jl1NSBPuqE-3zV&Ed4dZ^rfNEcx%*`^m
zf^(JFkRI^4%NF`3p!@iG7pQ$UI=j}Mpcl))XmdkOX*m)h<zbf^%^z=)ybF>+SK+o<
z*t%33=ZQ6&VtFq|5^0yKon?Y@|02`Ia)3bu#!#F2+B{yHFpTmZ9#oe^JMcP3!$y(2
z#pPWIs7t7z0e!~<ZQ&$xy+QT-KGv at 6ywe@Gq0h8L@>$YT4SYqhei-AnTT3Xc<d8jK
zXK)oW##lAPiM)}I&m&=^KXk`g8BY->i(3OLS at kqtDP>1b0M{eA5UFt_1|GY(r?9sI
zHzYvFTuq*Zj9=(CqM!QqY)s;2Iv;`#o5OBuBjNdTg0q=M!n2aMlaTt-cdc|K2|`7$
zF+u?Y6J?n|s0oBvR~T`qbvYFFq#_M3jzcKJnuTu#yfN}jmRI~s)gbh$0-p#EA(3<R
zr93XGE(t)%YK0ET+~qM?i!YY3nXJf)r5XrIOAu(`Jg(24V!rq~TX8x27OYq3BpM+r
zNeqBA4;Z>cfGn3`7kE=-(7aVe$Z{qsB8ygK#tQUJ60xu~k}|_ at G`_2-bY>h>)|X at g
ztD$zjOUcc9s)DZOBDTXh0wBNv%d$KTUx=O%@mF}{zB{M)yDU%yQRBXiq^RhGNaN#K
zUDy!NXmfk5Pb_67W)gGAdDT94xPR<(Cssv_4!YOmq!2(27sJHGWQE}+vwnGg03mE0
zcN^^cT=+|aBR at yAOAMVAlfv+qJu6i30^Xq}%Sgwqn$)_ at yTA|vdwLLzA$2$!NC at CI
z(t)JCd|`5dt%7y(+GNoT5_JH16ZN8)7pkd)S_p7b&zND~vB+a^=<6&ADx;E5f>Ycp
z+)~c~Do-x0`$)_{6i7m*21e8YUS81;h#8kM7DMA=id40fTq;{GmVLVsW7s5T5 at lo4
zjBylWK_G?0wTc*L)|F9e>9IbhOnMA>p?)d2I}<62WSAJUaD(SAGcYW;6ivpZFoL!u
z0t6B~LWG8}vQOQap)ovGIYh6oHH9AQ)r7Tc0W~%Y*$~~#0YJBAc at a}1-|Yl`&<Gb<
zfwCh*Md%cR7xc>1xHe|8kH-Ydq)vK{v4sth?)ok`#&CB9Bj8WAlG+LI>b++Lb-9(r
zQJ2JMxr>sikVz6O&z~ts<;CbsObrv)BW3RF42UA3WD8A<E{Wg;?G-fMtF)6TQN|Ei
zfSbT18AlOAYB&V3vrl?u^z*LWG!c%XgXb#`x?&Prc^+5#h(ujQR^8*%XbW^EP;jmC
zGhmA1s^Vyk+&Qd))~lVF7_qIXEVh6W+*%A}B6$2E-nrRWre|Vnc=#=e8xJ2I9r=LC
z0S6*Oy}X>@8GVJuRJM4ymF|eRf~_jFERi@$W4NM?#|GjkHro42=RK^S6(dBpJvFl;
z`pyUwD)$SBwx?GZz?HDUVk!%v%A_HaNvX<^yoeUaXTVqb#3sX0ucxNF`T|Ht%)Wy_
zB!Vm~FC>6VZuGHRoEQ?btwM?o1B?$-+TsZR6$S#43>HyzA;&}$xhLq-5)&I$kDj9M
z?ZV6|LKZ!Vk|t(w6fFe}=6;~=U{fR-iN}Epmza6 at 0knin1;|~b`4}KCfZU+_x7F3k
zW*HODLdf8mJySZCXXS^!dIlch4$8?{&Vy$|T0M&lgte0HWU}(=&yeN`)$nS($@URu
zgsRd;gsZCR)Fcj+b*-|MxQFe6#&)yQK_ixpjSwjcjSD%7+!irsReOl{e_I4F$@zu0
z=Q)n`?cHH2*d-y#P;(11%1kbbCCB&_AbxR-1kfN`>DtJ?0r*30UKuf9R-%}#7&mgn
z7^>JvlE6uKH&pWlqr-wzg#5%dAj!C4UnzEQf$Sjg-Z51uL5OiPgsfFWTU<5DC6Xa^
z47P?M;|xj0xHo(f-}EOUMX9b~X`p&uoeUB$9#aQwuU)VRaEK+02WnCmnuU>#EmR;d
zLKILXlBQ<0xWy25c939mNwS2oQ6K;|xbNF0X!JB=SkOQ{3mfU`gqt at Xml;4+DxTFJ
zZ1ja;gQ=r00><bEese+3Fc$=4#?U$?Z;A!tfC{+yOdcrZEvxiCx-{GFe<*zv$I%Lv
zb2&!|AmD=}fB;ZuF4zIEJ2#BU9D*=`T?Dv?LVhUx(peHW2 at Kc?LDi0PphR`pFWu9H
z5i}aqV0L4?DNHMz_6^Gn^K7rIC3aA<FePNA;b_G;-sHG5h66fGIe5YmswZYnk3VBn
zq3r`!ZDe0AmMTaebEpJRxq*&GaUeccggrATWfO(WS9oP<<z^SiN}PqPfq1DVFZ@&!
zyQ4~eBCN9L2tJZ2y|5h!W^|pzPule?UG0DvYVK(1CU{MaQ5h&S6Nn<*#LrFx+Ns1Y
ziQ539A)-|wjBZq9k$VuFP`$WwkPg1X3S4OPqfuDd-*t>Ot1)OL!znac>|`LdV;U|r
zhB7d*>ks<`)Zp0MyuiM6Ny1#1o2_i;RiT9kiiE)cpH{H4`cBKW-vz}ixe0`mOlM1i
zLZK0{1Odq)p(_5QAk^Y+IMR9POG23;;B-7BDOhWuuNspStW~pW8uK2)lD2*}E*YAl
z$@m-gW;iONLA(?=j#NyUgLK>vvqMHODi{VD01zU_+k%Wrb10Aiu0(NJ^lu=|l};B$
z(r{PGM&eyGy-z%yS}Y-cXK)S1Vki<C2*z+^rbeso6xpj)1M?>EDs&pAvOQi(4oc1A
zzG6RjsA4o66~bt1eVPZ9q>9v^iCW>FPQHi>>LC;C4G`UI?7!_3aRPdYg4yDW%x$QV
zZBRFv%8mjQTOulO6XIw at Hy%VO3`g9i at fbYJ5(=28J~x<gTD4##oAsowaj9PXXwql$
zcv8+vt6QAHHi7XRc5{{-4<e25h#TTc=(O*V#h2hE$Ihx(Pc^cUlm3|IXd{e~ihCV}
zS=_Tc9uYNdpBY5YO%U1vLF71*Z6-`Gbhpw-^Q4f#%4gx4RDo*G4zw-IDk#8`8LOSL
z?9#kmZ`j9!bTW}8Pl$tTG=|gzs_24t7+DUF1o+mW`}agj;rjLc9<C>c-DY+8jD%7s
zG^?oSlyeD3WjSSc5SN+4 at Kl?tDHzSWHUafK$94<_*c|yvjsv@(UK~atr-EFmBrzm-
zfQcNMki_X^53s7OAV79ed at FKR9lIa`>2Q(ooHnqoxy4@*DWCz7XL+O6x$46NhuRH|
zZki;Zsaj}Vu8h;B&bb8^9UNgGgo=x=UV>Q8F#CF@%ek?MhgEkm>=X+TDRABP%RXHd
zvU>9E<Fj+~t{d_(oLV8#0Q<At+f|Hrb2po5whL1?F~ckxtgbrhuJAaL225`DyPH|U
z8)Vp%(1s$xf7kkIG+{0oPT;`U3oin?MkY#LZ(rn5m<PbKBKONXKl^mR01A8$`;G9z
zHRqTMje<!%mTS5bXfh+Hv5khYjM_PZDzS=5%`!ejF9ayfzKUNsE+&&x!`-JLxg6#_
zcGZp25e_F8p}EOGrMmiip at 1ezxTskV5;iAcEjYRZz?7L^HOeLQT__9GXRSdiKXWje
zdQjW$4C9n!mFx_BXYphkALv2qek3yQ5RW at L0%piYVEZHXp;5|7yy!}C&*Jhds~q?X
z!>)!bnU;8oII^4LgKcS5iEB?1W#%k~CI#^-2AVd&ihgZ3CRLjr2zGT57oIa~hPk3C
z8Z1R$=-{xvm=WKZ>2ah~?Fk at -$I at 7t<LdFSx=bBNd*E<zpMm2^6oNv;9Cn6{t&2`n
zYgmbI&<%x?C_vfhS{909sIDiaI1a`trU7b3MpY$sIq`5&1S1&7Ui;Mfeobo8x#5Fz
z2CiNLM;5Dh65GNZj(idZh8CF7w;2xokn6&h824CqcQh*|+ma)x%>}SU1_<adIQ^VW
znK&7vnm`PTZ`Md!EV}2^Nm*;GnYq8QoaAr@`ZhB>P*F~aRLQ>rAS>lWFp5>&B+r?&
zX5f_#7U+p*CJn?A8BL{9xKf!{)=+{CP8?<e2T7$Gaa84sfqA!EObT8+5Qr?pi%YR#
z_Kcz4RL;|ZzZZ$il3&EMQRCdrd#`?(?M{LY6Q}s;5t)T{(mZGap$)p{S|~u0p`i{L
z at 7CTS9V*ci;DQw|qd<Ga4kdO at L-UWC%TqD#BAxK<C~^U3MiO)uK05VhQSVe_(`VJ9
zSk+4jLO2V2y)--FvkwR#K(27G>Kq$^o=Ji{NHVdTW99AllHkNG#w_?89B{@6g at Wi6
z_KlQIY6!9Um8~;dJdC(5dF25k0)t7JS{uo|NP<_fnb*`Z^C>cV870ZwrK$FPJE!IY
zad4qGk?AsggIZ<?SHF-IMaY|0VN{_AR4q(j3ok%|ycL$GlEToisE+`hugZ*S)88Tt
zgA`(<#M)aNx{<U3Y&h#&wvtbZ__jI+f at Ytq<RY(uQgRst_<t#DO<AlOqiY|(p;_3H
z;)crSB0gi9L$9_~JwUGn<t(6t!niTEq6xf$5)_I#t)QnwejK!!GrGWDrogaXOx#=8
zsFhK`c1X+%T5nh4B1+UOvkW$oQ;qRj!U5iB*yE>wh`19j%(lL%7!6V+&$Wl-F)p5C
z_!5#Y<YD&#h>fV{swpTyH5F_`xM{9xSe}xHWz(bbT-FTJ+M at C}8$Ge>X2u+4I&x~+
z6fMr6;CyJ3Hb%nWsT2F6ESFf3>?7x^j5X}SHt(c1FJBW}8CR;ADJ;&NQ|O2`yQDeg
zk+(C8SrGX-^6s^wfi;&obV+vTY9^Fy>7{yvm4x|`uwt%@fk)fC5mVWyG-o<$E?**b
zYPBROplLzq30DJj?^*&EoZiroc<6w^2p6K#El369b|ikZl1yedq_r^5tu+az*XGV8
zAKZMvw<c-?huL6oY}&=v+g6y7G%yG)b)Ks(V3|u6ripPReGw^$8#Q50*pKm?__v{G
z7(bKzn>idCTGkGvSFB?2!hTGNVt`rVhav;or%rOdlm6zP*;XYq$6pP1MovL$xEc=l
zXoWho1G#&}6f5E2p<_1RV)L6Jq at p@5fLw~O5twDm*wPfDOEOIf7M@=PnG4wsR at UN#
zthqTa#Eq(2ESMw%3%nIW>T;1mY%ggdGsPxJPO8}~FY7`MH({4Vg>*bat$y5><Q1W%
zq~E;DoLy)(I*oCv**q4CxX7rM&};fg1Xog>B8V#FrS}Rjde|qhF)gr6Tv^;~-?C`A
z8`IvQ^tG|}qL#UQ!qUPI?8Qk+4Lq6s10#H?W3+~bYx8dj(BU0vm|Loz<U@>>n^}ns
zstX90RuY0<N`I8u)5S*<b at iVzQD*`=s^&Y1I!l~|Qd#uXv94T#)Oshru_I`2(xCK;
zvN<dR#&H_J1fw!x4SP{7!meo&W%H at W#h9mxQ$WR6K?)KGg(y14sxN}&nju>T2Hle*
zgSp-d4aU2%L5Z;U0*I!Mi|pUmL<WCaW!j4CjGm at AIy>p);?K^<P>5qSuiOvhIkv<6
zU!vtv*h3TsJl6*NL5VS;zA!k=YiLB}r&S>|manb+wbQYr*fJw_KON>xq;jE^`0BQs
zRZf6m90e`lXuIZsO>+(tFOy<|Dli3(UbyJlCie77tHh191yZ8+_8_AHxaAm4G}>3l
zoUY9f;?RoO#z*uHzSfIFYvDlE9%1b+$JA0Mx*;Xt6+B#cRh7ct9*}NnYF{&#-;y<E
zS3t^Ggyh&30BO6>F5k*joumY9rJ9;nnWb_qzJX8#+jC#lDf21#6U9*z2I`fI-^qU9
zv`d<zq_8U2I20P7R-W4|DF)87-6dt7-N^v-pQ~+Ma~VlEXauE4s8Rs0cG-kEm*F=J
zDB$V`=8UFD2$+a=k7aOu>=4<=a924(ZTRLuWuBrrVNOr5eH*&SXl|S>L13pK6{+Gk
zo`KX`D@;toikkk5cwgp3o^d{KeN at g|w_<=Kp<}G4n!?~)wUi|UDOB*xEe`Mx?3nq~
z3ZIJJ7YasU2Pzv2zL!l|IG7`WV747)-XoPwQPB-P!%FB7FArSR(^Jb%<4Bb`J(W#y
zM5 at r#aE8U=%c^M<7fz{;M4AHMDyO*eFTj77%GqEHmuGbvk$b3?q6pNT8cL=m$RxDf
z0HZ}k=nXltr=2*mOR!U*M-srHj}XGw_8$nRTPZO89Rc-uazxAi1jS*>H0JRN=Zqx%
z+kwGLp&1X%K`h1H7m(4ByB`?>val$DE38vCTm@$}EO$JZo?0y3r(u7HrH2+wrz-v-
znBFTkdNf^HTau83?9v=2Z_@%ao-Q~y1l0X}Y1=y%QWx5l2N`KWb&cE3QFT8?)g{M%
zC#-I2%8RIalfJJDtM|ZG3#@mG{l|yavz=q>c04fqI22xI=U3*@P<(y<_)*5 at 7<*3z
z$1n!j!w~qGmQnW3ENFW4;z*qZoCIeXY!73w{dlNd$|}f_mf0fWP+N3>CRkjHlN4H>
z1D{T2l~E0#23*t%V}cu}o_1-j=<)L2aHqak>y&J(@RcCH%}#k at n8~l5$8{|7b$6<K
zbGlRJy9k3&op1e5EcDfKxrZx#rCiZV(9yNZaZ8g9%v?jHZT5jJU$sS?cXSjjlt?Mr
z%7)kV*yGdk)-vA+=Zoa6C5F@{iF8;RQ`hye-1Rh+9#TetRa{CB?P?mPX&kFQTsjJ=
z*``*;+{zCH`Fs7Lr2V_`_K%hyvWq;HANpQ>){mi?={YJ8Bdr)WRv_ljl^|;DMGFwM
zGU$H!Aydzx{IJC!S^=UTqcP7^f0&9g9Z(=9!cH6}e6t<m&V8a35V|NGj$DD&bKNz|
zOo)YbZ!;g|3&**S!$h}^?q4?haZEQXray{#jh5$A9hv{g{>fS<K<c&g49KBO;Y+4K
zx at M1MZp1hVGPWs@CJh-OcV`l0+kapdr2G6dNcY%0$kz2nC)*4&A!WkQ!&4!t(&b5$
zA<M8o&W4mJee-n4JP`iJ=0mz!OolK-n-Cf6-6 at e_ynZg4ohL<F9o9Z8a`A at l;|<dy
zTfB6b7ini_-g(;`^<ieDBm?KEkw=n&mTUAX4}GDirX*xD&pObtjGY&TAl3+IVU_3y
zFKLo0r0=oRUa>O3J+-&w$loZpmkK36=G at -#)Sm50J$pQzN7A=uk3%N at wkprL9kZLv
zE_*2AHr7g$NGK0XBEo)I<;e`{(T0r<R-aA^kk&guKg7_xIK)=kV7m|{)7xtsc at D*#
zZ|k2S=?~Uc0vHZM>C}hj-<vL&5)gVYhQAEpKPh?-U}r?)nK_b$%tYL~X?25Jl~R%{
zws%!$lqE^Fxe~a-beKqI*rgQ{0N%xM8EeGp2xOV<UB1tBDrmm2a*+UhVUc{iS*8KI
zS at 3uB=ZvaL2@?`qFfFN1hv4v3_-co0wjsG11Bc;czB#rT;@I(Woyf?r8(VCfUgQc*
z81lWGg}8m116r!}j+d^X=|xoRhZe~sUAToMtz4hR+$cA&WXNWE%CqVsOl)?-Op!Ej
z<G`Dx&{R^HiRKWMG~_btFs*}L62Sd*`XaE6=6Mkf_Zs`8P#~@9)V{lg<)A`bXB#Z5
zKD-Ae-;SqcwW#hGLwYc4xyV`G&sg?^Gce39-TNN!{o;(}T=0E2VF|`5Maw;5c}EnZ
z(;7zrJ1bK4)+!kyS+{d|xp_>UQeaUMCL9BH8TLDAVzg4;VDfdW)YL4FExim(A?qns
z4*wq(pEtG10YBQO52GK};JykZ&q1qkVw?0buMg0Xh^E$4sF6ziX|5DakE|I0nxw!y
zsm|!`w+z57qi+v~-h3MBg&GU_1LJN~;xtFzq`x1EylEk;#@$*a>px at U?Z0k8t6f&K
z-i^7<HLbp3^*?*WE$O(@Ixo$w;u2GNR2>!_kvI{pgD>bDEXNRlZ)qs5o>lGt85aNf
z3O%k!DauWIMu?!MXw6Q}ktsfKrHp~QmKmQk`VltWRLPtp>P{bc-4<78oNhJmGmOIs
zN6GNz6lIz+WX#)6xMq($NuaWjfUm5SmL=eeZKc7wOq352)qnv^d|4zHeU5BtBLqHV
zwWz4822g#o;H{*7bdx%&NPD7k(c{%B;zveLCQEmnR;h4K`0I;Q{O5{PxaP4hoe`w&
zu6NtL3KdD9QptJj(xfAJv<jry-&X~4dt|lJ<Q;}5>U!p(I{FG&XZq?2wzw{qG(W~X
z|8~;6sNw!%OAE!_ygE6*xjE<m at 3kBB%Pi|hLguP7klYk#J{sUhw1p@>FIHlcF}x~F
zhMg0y28}UPC5EBZdAz;^$MHKVPhelc5Fbr6?HP~fXfGE-Kvdupv1fyE_Z+V);MBru
zGli4VDg+XAN|)P8v;K(9A3L_=G;U#MhPozja+H=tgNg=Pwg8L;EUZ%KJQAG at k!#rq
z8aRv<1(e})Bo5 at mv#*jah3n=Wm)T`D#R0MqaXlFg;;1r-CX*_Y%7)CVqD0D1k{{;C
zWng8ye~8y+i4{;v1}4zzE598r4|;#t{rS#1rSzLu-#=V0wEcApLAV&}g?^Cbf#qTI
z at 0tyZioQ7_l=FIho=Sl6nQl9UHFz>?Fm&(xg>1>Hf79@*bp4rMBI<3AL>=x4m5U`7
zbo at 8JNM7{@a#+SC7)R~<8V&3!Q1353!E-hwm2Zm7eWf1}tDd=7*63A_BR1}4EsT+r
ztbyc-*PgV>KNT2?nU-leP0&dbaVX+9*67j-ro}-ma|jci%$R6~qSY6AI>BHKT at yr0
zHMgc{;I|>Fmsdxps|o-Ch6+n4U}Ad88#+HZ5fP**A2F5GLd>n`e>Z<rbNk?T5yz#(
z4ZN4O)>DO=Lf#V-rM?bN(znyhX0?}UL?C$86<NuOw`jSTXdJH#Md3zr;!_LoG-~z}
z6%z_i5-gzjBTtj&a;#Fg4%R0AeL7b#zGW=(l+LNGhQ>v;=gd`sF5)`y7MJYAA}fR>
zT8pC3>X<kctxNmjUuIcOYCv#w)rXLlnlModbEVP~>Hy at IAUfDFEmOjkErdN27ZRh@
z7~@PPxUkpt+d`=M_d6i?0X?)hF+vL?gQCQrB0W9puB_ntf at f-4kcirj6A(eMUL5xC
zuP?@f|7U-By*zq#36$Ag;-43x9h>1w4_utxygfS{&OVKe;iIy&?+bGTy6C6%zF)3@
z`a1#Oe~K2;1OQUQ8sJ5(Y9f&!CQd(^0=*6_kjYnFPQ1{>0 at zB+3u4gvZ-LUIxj2}(
zSPWr>Y?MF(1rY`xbD4fJ$7NcsN2|bT(i2akri~=a7rDR{R7EF5dFJ?VVB&U44K*UI
z;bseLN(pgz7E?6Y>c{+A9}C<Hc*a^E3H^CMbTIM{ip~+MbnKV^K4YbhRkc3nkX{kG
zVc1Oc>qL$~q`C3R;EVJ(ZxktmN|eZvjd1LUrzQN7gfJs~eJw^Khngx5z>t%KH;9xv
z@*$EbnUj;2=FLiWG8mar2ET)=rW|Eg2 at Q@MA~b~ON$XPp^BheDJ2F&E>9RFnHB?7_
z7Vql_#d8l8rFJV-REA2E`e+h+HzLi3WQhbOKsnhEsHo?qy)w=7b7Vv)7BBrqraRE+
z at kX94Nm^JE at N0<*W(QjAR_z(<{#ZQC(Ig4ZTIp7hbvMYqNS1-NczH{pK@|_m at f1^z
z$OI0Q6L~IVO?Rx{re^-3BHa=T?xQ5JdCT|f%5dESO73XZT#@zGKsB>xcZ=UB=~HS&
zm3PZGtoz42r2g&^nR@(J^1iM5v-{-vXUU+7K095pp#%-Kgu*jf9MyPgR)tm^;m`xs
zBXP|~CV>JIEhHBDuP^~?#5)2RWaAzz)m5*#ZXn6Zs&xChJ+E>8C`FsHMK&C`5@{v4
zwzcYK*Zr~w6dxb<br^mBm*&2y;`>BpT(rsnY$7i(;@Nkj0+r;8)`mJN0w4gkt$-oX
zU5i8X<MkXfgIOykF>@zpmAaS?ag7)ii$M at 5Jde%}<joMUgRwh;;6gutkfbyL`oe2k
z^c(fi{HERvj-X@?Hr#F4a at dY}LAZ*SN1Eo%<3CSAi7P|%HgbW;(M0j at ACL)mR3_%1
z{m#ZxwYC4 at VO_reTW?>d%SRo~Q0}lc!kMw9`nv(}Moa~vii^+azlG#^Sqi&2dHBe`
ziv!OGe$ev1!>0#NeWaghsI>T(S+Zo at k|}Q%!{YZYkB#8bU+_4(wKn$$Oo>+dIwijI
zi(=mtW<hSiqo6g((HfGLEjN+lU}fzP?+gc1TH3;zMrh at L&V1lFpEtT%jTdiM(@D+O
zRaY}eZkpGGF)cpGULIxV*-NJIZit%#Jc(S?oN9%$hC4Y#EpzcBC2b^*2n^S?x3$=>
z&6Zpq*inA7Ehi?6>FQLe;A8<c&7nJ*9KTp2Lc{P9raYGdN(qU>HRP|R&?7IxOqE{I
z at w%09Uc|`V_3?g(EYc4ox&Tg4*7W1b7DmQCgeE3FD4gxr1sCGSsXh?4;=ev76-#_x
z#||{0fRcN-jO&=GsI3^wKkJ~mO_?aG^8`&H2?3|q`3v4>nu~#BnWu5H)UcFtddJe_
ztX3$?Vi;sz)qFrjMss#bK$0wYK+7UXiEgICN6CpnUUdNz6PX`MT**;fNh3mq*S|_6
z+#=htQXG7u1yp^MS#hnIvv6yoAoXInmO1DL?r7Gx5Vq*;*9qGb;-0zW=a#V<18Lo0
zOF#GUUm625##R<Id43E;k4eekfPsb*2j36_qxYW?OG|%$zgWg+hrYrI&1ee+wMyY7
z%*Dq5v~*{KDxWAlGwFuyE{W|f31`FUY~ivTy6hp3B!-6rj>pK%y&nwxrv6B!Y<~?D
zqw~b-DP1-7J{!7&CxBX>Ma>&tdp6A-t7l|}C2bvZwWZG%zxMbgeRl8n?Vj9gFHhgJ
cpN4uPKMI9^Ueb?P{rKJg1!)46G?9$}0HxsNV*mgE

literal 0
HcmV?d00001

diff --git a/ui/data/sources/tool-ink-okular-colorizable.svgz b/ui/data/sources/tool-ink-okular-colorizable.svgz
new file mode 100644
index 0000000000000000000000000000000000000000..52c41229384a434d1af8140016a066bded35745b
GIT binary patch
literal 5130
zcmV+l6!q&LiwFP!000000Nq<_ZyPz5{hnV at tNzl#R+ad?Bpo}0oo-B{ff+2&5A0_}
zD%;wYB}0;9JHLL<Wxb`6B|FLl*cc7dEWUZ}x#yDX%fCI{Et1d0dNW at wuSPN#qoi0)
zSF`!@=4$lkAOFbwDA{Z$%h_bHS{7HM<!bb|kMA!3Bg>MX*2QF7%#z3X_BQ!-`PXJT
zxi69*Z at 1g~i}CpJ at iCuQnfYpcGk%|B*~fS9E;pZV-X%$bewUkz+4O2uRk(jxFJi&j
zbX+WoyJETBjAbszqqg|8Ek5Pm=bww|>h5l}+{Bv8%@3Wz>)CZvnn&}fV<8zr7z;I4
zDnp5E^Ss<np0a*bjB%){5<-metu1+4sf(utmg3-G;@58PSpIwb*Hox8^3CdDJuR+L
zv&fglcKq`nKQ|vUk<YfXPBZoD_xkN^$#Qa6Z0;x1Vl%GuWBteZY<mkdC?Eg4E#^13
z+pCfGCjLF2U5zk5Elh}ici<z-0##!d%@>gypUY$&9En(@9`(g+HRWMkjkc at RB16q=
z_1D8<vd*Tf#cDnOGWoP9a`g74-*WMEzglmz>-nN6tB-G2cg6U6@@c*rul^cui at W>r
zAI|_Je@<4{$+CD%u2+j$@!R;NuI`sNgFQXX?y(_C<#zD%bNl%tzF*FY>kXGHSBwAB
z!pis!U$NoEWc|x}GMfYDWw}n97|)`ZV#Ozm$I0_%R2PUqxwu^y0QL|4HjH<oDaT#*
zKTBbRZ@%ADxqmL_TR`|>Q>=ey82tD0&rPvc>W}qgxdG<xu10s0?Rx(7qsYA=p*^Jl
zoek2HPCJR_qw={4LdlRCkq6<N_3zus$g7b9;gBU~n%rmP5}=}k)ot#R0=NV~B&1hu
zS>!sbIHs=TC>ej<;_fe6T+@%$_sh+8bzheSez(sHppG+3_+0!T;=d0uYlY>UZ=Wwj
zt|Vzgl16Ra)%EqJzyL%iFWMApqEFRK<;}f*80bw7_h#CK8~3MQ<-)|a#k#H=dxh;F
z>wdKW1Fx1 at Spq=X{PxS=N3UA&va0dHv<rP*{4#miZ03{Y-xm+-&Y+Jq$m=uvx%fPf
z!(!4QEdUK~cBbC%0liaa5y~OGh^0R8j(~I+(1YOr#uj&)+3(wdmfF9bgAVOhv(j${
zR)ZTUf;j~^dt1&G=>^<a3n#AVm9XGVmBM1(O$QbX0OfKrWb`grLN25h)MGTQbD^c|
zFvcLAOOZKcv*2w;<T52r+94-HrcvA(%Dk3HpV27<vO!tT5XCPK5OxyHM`<xXN7AK8
zDQA=hM30g8J~t1{<N#^bWT%}oy*=OK(wXF+K9|Zt;y%dGozCdx&L)9>j&~-H5%gg&
z8p<KkeCU&r1YHPi``*=Jhnx at 2^{_}P2hu#LBUn_K(LRGd%zV(9A$=NM2#q>A3sz<n
zd}f6 at 5sj~h%TQlOx6q51xA1z(KWD;A$7c+7_DS>48Suh?O%}UrHhltKLLP$ho$Z at G
z0~$8>+H}XahV#meCaG;(^m?#?>%j(i*8O2HicAJ~n0Ydp78$*Q(TvNC1s!O|d;9f_
zw&f&zQ1PQk*;<rR-WD0Xm8W*bcN_{wsN<|W<^6Z(Dea+zj1{g&R2)oc??R8KH08!1
zXzugWUeRHiqRcTxVMn|YpsdpnW=+W8yE4l=830Z?m8MQ{n($#zsnKcHNs&9 at q@Zp}
zncPDZSe-^2gT}OPLF3R|jv^$SiJ4A<V>sfYKNbA56Yrdt2BE-$w3cj-2C)M&IB8s$
z24(IbwxyLl8r*N-da!|E8uVEp at L!+|fYs(iUkX5zFqs6jQPJ45K@<c?URY;Rkun`Z
z$SDyJY6Ms!0vLy+&Y`Wyxwk-af8 at t8a)h$3<G=F&5?bl?oxKT=Ump({Z~R-rA>(a-
zlKp51w1aIi^7YXW1Za at b`F=FyDEDwX)FbwRqR90+2R4HBFEcws$mtBRROVneL79_`
zhJCYwFa)AAn4KZ{^;XkrhfGO`B<*7OBQZWnZ;o_!MtK~x|Heqii+ at +7)3*>1Eu5wh
zfRfdw6Xe8vMb1iUm!Uq>M#OEM>qw3IbX!6~SfN$><xM7Ny?v7jTJK&kK_xACQXf2!
zI0JV$4B#yTcb)ih-~>(t9|FRJZ#Z!KwiS2wr4@$|5eS~&a0KKHkR+AuaUMH=OPx&S
zJa2RDY>)8v$_?|K${^e`ry&ps0qu$BbFBUX6fg(EP|=w at Ip97;CXj-F)sO>qlFE}w
zR_mP<m^vqINyt=cB&DJ7Rw=tXnWI!Ck2v#lN?9+D>E?4u+3$-*L{#ujO3F+_!08Sh
z9K#|>kx2)y20WirvI2opYoegjHkEZC*d~=Qh_NI=&|1nNVwKfzMdR*tjsxU~<2)}K
zkBH{;pz(6dcbzfST=DV^?CkTrczo9k>C>dy$ot7n5r+Vblv=v_ at M*Q473=yF#ecm|
z)hNqn3su|otpm5(d>6ytH at B17>Jd2K{rF|Iy5m~f?tY2kq1(^q at Gd~^Dc?Ai=HqNN
zec;y&*+U8E`=`C?59>7-SWKP^%r*Y1_jz->dc0Xj_cd8Gi`G<qoG&qlthuol;XsL6
z<`}!T7FCHSzLB5<A9;cef_6XNO`hg=^Do7$h2rI1v7O8&+ey3Ub&eLczO=bq&#o_i
z`}rRYc&F2g|5>g7YEj1pCZARh7<pq)e7!!sV2ht at KhE#4ll<J`KcDUvKwtBrS9tq;
zU$l*u&8~~`ImO@$l-cxd&XvZ$Z|94}uiQz;$f`!?+ePs)_E{$DS&XY`)MnC|<>k0u
zhWOXb&Vnu`pNhrR=%0*$MD8y4&3g54f47<y6-Gww;`T7J9X`s;h<vUI`}n?I|NF`I
zwqdpQ#%{SRrdud60Q2)?`>-y$m(|-L->+qW4zG>~Oprck2}%Xg8qYin&zlD=RA{dw
zTYkWdc&%X@)6HfY|Lgf29;NZr4uR2>7?(q at 2SX`=!>zDnl4&CI;L4%!)w>WXQHVCB
z;^Dxe1Hu)Xz$-$wY8$h>QP!azf&wR0${|It2|<}iG|wIcMUmrkV}rFE%^Bk{VbsCw
ztcoo=BZZ^HnA{)?HBdnTF^D2m9LifHa8kj03CF}sV+7<VhK~hIAZKzxl9vq?1c6gD
zGHouDhkt_4;;UV2Y?AT48lgo#riSNrD#<ixD`=G}jya{_npk;@@~K8BZ;;7-TSrD4
zzL<j$Rw2o3jxgI0p`s&agc-_OB!XAL7>ULZbUBxNX*aZVD(%|`<1h<h{0AuK#RaVE
z#~l^GH_Pwi*Vez4f36=E#YOSC05)duN$b^L1#q$~K9nN7Y^;4f&~e!}132vj<(9AQ
zjTf at WY+4$Gqz)=uW6I3#%;GfqPU>4dN&5Y#U;nFli!{{D&U>VxB0F!A_6+`XlOJ4x
z!~2Gf`U3ad-M3CtwM9ca>TVav{#W8<ygnB`g%LQ(Fi(C;VBnB&Y<rw5V9%1xpAZw9
z6p0|DcOlXI%uHLOQsZ-_gV#X6Vi5~zCR12YFbbgu3>UZ*q!gc~3jsWM09$FeCO&LO
zZ3HsT%f#lMtc9Ie6;BkrP9*q58E^-(G}i at p1lXE!(x+DE{3b*aGm(e6dBnajA1`5w
zCebW04bre43SKFnSc86z0X+ql>gY9*(W<S&K%giTSOt5?F9pGBlHZrW;z4UZ_uvmN
znGcNO`GD87K_jWd(kUVb?&ByHB*x?gT40-&@Bj{j(pW6Q#F>Aj#~2*f3nsww at ew8h
zNs|)FYpiXiu@)G*!dm1(NiKzH^W~U{G-_iOI?@gyS)^82CP*z)AZp93!Ff^{W;4e`
z$f{hTJQ>9-r9E5)Aq#m}5K7p4fU(e)#CmCum=e6~v62`oh|Xzgy-g$&9EO%+uZ2Jm
z5*JJZ9hS53MN3{(<%F^E1r4UAY@)b*Y$;Q`#1H@<Pr=BLMt(Fv6|e{7AX`h5dMpZP
zUSS_Ge66&=iUAi+fj>1i8NSu})WMYia#Axc2zi*3<5N at ty2JPpkQhLe0=yBB4mPIT
z25`G~DIp3I-U!|mu(eiJ!o4ZX4^`QHfWL{ifUvPjvI~$7Nlzw1nH07S*aKdG60g#X
zp)5%PRqUlf{tlVIFyFU{2wf*(GQ1NA_e3DLHJw|wBgLy{EgW2eEd<0=+#MiSSXh>U
z>;{Id<*mR_D&w$HOBrLV5Co8rAdC#i^IS|=KFH$r!v;(CoSJWpfenT#Td8GN2B-#N
ze32tKbAS+ at L@Qv4tq*%Z49r0A&uq-_ioyrr5~IOx#EnJFhqeF%14}XquaXBLsMPZX
zq9o7G6CTr)uTxOdcqR*Fg}3Za;qt9!++#5S2F1FD-7mr8wGq(GX<i4;QbAsLUt}f?
zSdmJG4R{^hlJ!kXj>kn8{}p`HT(DaU at jwh43t+w9Vc#1ml#^XO-FFMGaSW9h3$St4
zCa_aj)|3}lfl1=YkHGFgEk#0bBJhJXtVPf<3#{oZACPl(&X6)#;yn=%9Az~{QgIn@
zvtmjYd{n`8P~)G8hjZXIq>aDJ&IP8(>V|*E8n70{2T}rXRxv}@jh6jt{tzNNXuyKA
zfW3MsKwqi0%F*hwYq$W+2RZDFY%_C6L5Rn+O2qDsA_gB!20GPKoTy@~n>gl0J1HHf
zz}90yek|iGxYd`9SXdG(F9P3b#%8&ERQ0|{m<oA3 at fX_B0E2=wWJ8N7b`rpZ!(cM@
zu&|}1s-D*E at yr6aky|QNDcdGEoJBSE4NimKE=r1z4;8#{%!yMeIi8ycpe+&gszn*8
z%4sR+T#ED%Q#Rq1_bSpd`~aqyl*<dINmz?hyc@@F_6OM1xM#>snk__M{Om6F#RL?i
z01B#{5ja!{c0-t4RKd}0IgHw{8?sE1Jm)VxP{*rT03Tl6^geWjP!yz<$oYY;`KS7`
z49G8JjzO5<gRJve|H7~?5XmiP-OT at 8&6oXL1fa!wfxvouVd}hAZB-ew$>w&lUQeF8
zgNeE2dCi3wP|We&<okX+`;`pvuhI-H+$7s!fDAE7AjX7oF69ex$pV29Nt!(adlE0n
zYJ_d9Y7mVelYNDEa1kClT`*ac32zutz%bZcIereI955M5gX4Z38){5Y<Z<W{qwB1=
z{le*>bjmMzYTAIaA{Ivu!?c~YqEsnUO`cAxW<gvAZKPF`k`7_V_Rie;*cph1hF*2P
z5FHJv>~n7E9n%}O4bDC#e#wdGw_0yruDISY;giTDq%<p5PMDz_m?FHgiW_gCo*au8
ztRO!M1w&W~Uf>*(j;Ru=h at kW}huKnq!s4DFP=+<JzJYu({0sqb(o6>fSxkr0vrxh)
zEG9s1V5{Qkf|KI4TebJ- at pX~xx%Uc-8iMwgb)XdxT&{H^wHI;Gi)e&H?5VY7nH`By
z!C)1;5ksn4ICkEKw=X7K>r1HTOH5Eq`q*W~@+hg>NSkKSn#$qt*&MSfW#ZTzdzet3
zo*>1P4vA_)l<h20N{IlS%OWsi>F3#>E~0^p;Nm-!DpmS$&0eZb>870TlsjPMSR!qF
z86N}-;Bn+q_87~>QG~MZat>)TnM3xkj)3a;8_4f#|9q4O#l?_<Eow+>-Zn(Frqo{^
zfirt)C1Uu<=W7t5igP^2J1JiPE60E$*4V^SKK?GXfE49P9pqqi?+Dcp0><YO2oED3
zxO!T*SD!yYn8)}srr3*vSS-XylS-PeX;bWg<&$_dN$<TQ{H~U-30{c|M>~d at FJSt7
zkjQZng62|G6Jk_80MuB=QpzF%L9JevEU#*#ujC6d7d5t)Wf%kzZz&o-0SO>sUTwnx
z4O2TryJ8XsAZ&=G5GV%(?A?l0R at +lE46qlQp-c7$*59|GKnSJ4X&l!!$)PutASrMZ
zpAe+Z19J#7)%ydWP=laok2W2jj({XSykyL~FZo_)%!5ar#_#AhCYtU at tD7JMBoKMJ
zbE(Sznzt^RLmDf4AJ<Ru-GdHrqFVJoJs<qUw?=%j?}O+IWmIv3y{=K=$PRY4XlUO$
zsZ{K5SS7XSl~%m}X6(CiEhG-qR47k-;FF^JW{Hd-Forx at iFmpn!<=}WRLj~jqYSYG
zQ?Az{#6x}#km4(hN^4aiZxwMGiglT$t9n)FY0#IA!Loq3H8%I)6ssdIhk%&P at bMF0
zl}8h{;0P7tKE6WHN!<}gbTKU5%UJN?s464>*rR}+h%Fc;bs5>k8++x6oo<`KI)S}F
z{Quy1g&-6p#kzuzeBx;)Dfs260ua=*JVi)i>k+8kQ12`7$d6zZoObXj{|_`0o<<&G
z6k!hnbnrl3 at Y7<bHm_fQBVxThZ+HhS;33SlhL^Vv+v540Q9uES^3+4dgAh?}gz$_I
zD0^9Mn$`~DkMkTPdWp9Zr7RghM24Net<VV=nh^RK6=Y0_^-6`1D_?bZ(n6JINx{bV
zM~FDE^HJwHVWUVakCzl5FI5La-ZC<X!Chk8LS^cBpbGH_hb7_}P#k6pZnVz8jWSVI
zc2y#|&e*Z6?*TTe<?F!qhFdr1-MKN=a-iY+1RamE{~vRp!`>1fQhWmr#EKcW!-0Zt
zvcDq-TCKl5EbZB;k57t}a7yvfmL^XK7kwTaLPMXH2}DK`p8$+_dBiE;vig?RiHOHo
z%B6MjLt%+EhtC}k2%5b|q2Dzu37X>%VTi*L;Q}AwRSQAACE;)z49rFu6I3s5XcxEo
sq|>_e!Gj#zd)0f=y6rt+eDk`s_d#VM{<`GXNgv<+AH!-L?Q2H>0GvD7n*aa+

literal 0
HcmV?d00001

diff --git a/ui/data/sources/tool-note-inline-okular-colorizable.svgz b/ui/data/sources/tool-note-inline-okular-colorizable.svgz
new file mode 100644
index 0000000000000000000000000000000000000000..aecc47309117d11af2e816e6df855fb57558bd86
GIT binary patch
literal 5028
zcmV;V6I<*biwFP!000000M%OCZX?N&eebWR)nEY|W|4WnurJ192eUA+55{;F`)IJq
zlEiJ2C6J|-)L-ut5t+rJs2=yrK6n7TrKqf|%!m^wPDJ;IKR at qx&DZXD+V+Q!H+rsa
zn(nafH`~MA$D9B8?Uy#)G^b&8*sON_q5F7q=x_e~>D`BaYun~OkKJnMHqFy^xNrV)
z_;OmW9=hfa_rvh8Tr8fRp61(PocG7O#UGot{q*kLhtt=)cTLmayNA<qv;KHfUU+ys
z?s(y5z36t`zB>%3g`Vrh&3XCyynIbx-+t}Z{eIscPW<NK^wVVVadSJarqeuGUZiu*
z3uP9 at v{=!eUJk?RxxIW9XMF2bqm)|U*?HxUty-So&<Ff)TwV?HQ~!8ecei-2n;*Ji
z@$+v#j}Kcl-wd0{Hr1aOU%hbhVYTm0536-|T2wo~|Fqo<_lU1a{Of(Uy}KXIzi&4m
zZ*XE0RN&w136>)=)Z7|bTDF}&a%rxcV~#=bk_$LpY`5vxbi$7}L*MV(LqBxw_ORO?
zy0-uFxLY0Db-(M6+i$DSyKasHeY^Z*|2RB64u9{ShwdO>z?~-!;K%gd{NnQC``z<H
ze;nG|?XHt!EbjY#x42z>-u8?B%VOyE4~ySkfMR;w^ta8Sdund`-KP6>@gqlmINZJY
z#plffVsFgczxnv({P+`|f7o=lCt4?gq2Cah#Lw__eER`@e(2Ve1+seL>EVT7a=FwB
zmYRzwKK%U|A#9dSaQHv{=86|tp#g0Cq265cjnVWw`;;TJaMs-xq2qPV%me)wFW<qf
zCzmrR-ZTsL%z~W3KaDq~P;I_$yQj0qKCez)+3aC;*KveC-u!gS|CI-y`{SlN)<=AZ
zaPg=|8f}M{Gm58o!LH+T_4f1A{c6)cA*`<-e(U=^%ySi$)yBVmyhc3QkmkV}b at lEV
z-}8B{yj9A*eu(UPB-(5r58DCM^zeN3`s49P3wEoQ4%g;C>Nn05F}^pUiP3ht at 1O3D
z<mKDdZglhb1$xvz^xFd+U^qT@)7Kuio9^_z7wKX9`E&n#@!t6SX?uV>+wqj~%IRfA
zJ#=*XJ1YqA-+A=%{YU%N^LD at e)@^9X>r|v`Ptp5d`2Ck-zyIs8Q!f0i8wM2A(+F_M
z&gU0;Z8S<^(BVdBSL4g2kr*EPVX3>ezFb->!jZdb1b@?j>Av%1f@?EfKC!#0y?mB{
zUX%1XH`%`LhSg>@tj>vAEhcDPeTt&I{PpKwK9x^=Sg)7=+aJHwFE$M=SbYZBf4sT*
zG at 3tb)=QMp{c8BM-6Q>|0{;nR6O=JNxL8avIBzQ39y_VWZ;F!5dcUQY7JnPIyWL;t
zBjv`EO}E3Y`^4XrAL}g^<r?LZi^(lNEUFv$x4T#H+pRu#yN@^j4I<p_`sNDMcgOzm
zVc&1MlFv71_ww($hUN9f|Lnyp at +l|jQQxtkCid{M!wv-<%X1jP-PJV!jaBokv`=S}
z2YR)eM`M)@qp>Eh@$;0kO6Mmf at l%|u<a0<D#ezO&gFYL}sZi;6%L9b#`_pjjzjR9m
zyHe#>VUwk)zfxJpO_y-YVKX)U9|-Nz3Mjw}AcSG*s%`W^HEdQW0>|U(WqJm-_P4jE
zZdj`KI3YG#0%m{sNq%-Vt3O_s&;J+g0=6AB%UfT2rCZ)wGSMzI87^W!jYO%ybm`s1
zTm0+sao3TXzM=BgXpz_6inIF;D&qHn<lexY%QtTzH2!P*{$VxTzxI8Pl7B+!T59v~
z{9b;gM{qEBaVM6qtK)Wc7%ps2?8OTcLemZF`)V5?#@p3ydv{o(O*{_o`HJHGB?RNY
zzkfPzsra?TG|Szw9X^+r4(t2=Sl+5&Q1kd+pi&a`6;vj`kmKC0_S at ad@;`9)-TSsW
zsFkBaKW=ZgYxIfzL6(fJq~g;UH`iVnJ#%?(Vzk;eYSwByH`;q28g!pdC*x)ccCF{Z
z2c=!(=Eh|gjhN@&XYWkY`nk>8<N))&33CI968x+M)>23+Hf!E|9-~RgH`Gw+=<=+!
zz-~~+!IXnH-jXTX>>#Jr+}r5G46R^PSvyB($|hM$Td829 at i5^%I%Y9h+8ya&RhVhj
zwR905Gz9JpwcDDgePiYt`ZMA9CMT^keaU&;lwNe&&<;9j<z^77E?cjQMeCWxZaEp-
zv=N)r7Lcm&9S*6D4vyY|b_Gk5$p(jm!<4m--jK;yY#3*BC#xN=@)?>o(q3LEn;N=`
zx8BkTgHs_oTIH}T<2_I$?n#y$w6%0EpC}CUp2upNCng*`V%LPg(Bou{_vBHBVCCGj
z at P%>k8u`zptQ8-U9dBqIxsul5Cw$hy2A^c;%L|*GN9~l42tLl95Mz%IuA9~tC!vQ^
z<X1!;eKs7To%f3T>Wxjt!xDXRnWAo820CyDtjw9#!~_%pa&V(^Dd8JdC!6EhLi_lb
z=&R%x3z*UAfdbl-*2A}%Oj&1_bNvkaA^^EL)w39Kg?9*-sir`;P6~1JP3!1NSVAW-
z96ud{kCr_XvrX)EZ*l}&U<)Z=3q}LJXw3LUO}3a^40b%2r6}Rlfe<|&w(jR=fe_81
z&pHtpa45L3eeDrfzo&C`WRh)g7Qz*Na4C-_4geAx$w~PO7&>5POkX5#p5u-vKjdGJ
zcPj%puWbmF;9v&i7oR&sV3nNgLdcx1+8~0Vp+|s^CX;nmb9fEh<~d%-AnVBFtf!Qq
zOBm-3neaYAyO=DQ5D);c<T-q46ew!OC<DAJ6gfkT0VbQ>Bq=FbkoKNniZA<w63S=5
zxgy8L>zExQ1Qg%{`!q&)-c(z(lG0$(G|MG65HT*0+qD8|uqnXD1kQSN0!?xb>`Ql6
z#4xlYDsZ3>dPGoGVJkR<m?>Gu2LO=}5U>a*acBG)N;5c8$bwC<BoHCOyhEt`T!EpY
z6?y@~3Rx$7Hn<dpi>)$|{053AM`A;3vv^2H1BNDmAzA`T;LADqe~!Q;%K*b8i_3!q
zfg46WLx5udNF~N9f(Ck{TWM_#Sz^k at pACd!XIx<|aG-Yi6>G&9Rea4_2rZLVz_$uP
zDd&TvCeqMOZI;Fil)_w^f>sdGghuQuJcr7Js>j at qyyZ8*rJ8fVJB=*kkEQH at SxxXy
zPLPe5#ZqQssutQj0kR13SebMJ2)QyLg0`W00|xRlB7vwae+ik-YZ5rtP*M>pgPsWy
z+iHlYO(8~3bfO8op->?hAs}Chrc+jEKmh=y9wNJu6>c7o+g#Quld;ZFhA5-}ZbA^Z
zE|4W5<t!5;(m4 at rI1Mn_Goj)Ua!K>KKyF;?01g`nSWIpHY{6S8fkK$KIe#_z6xjwX
zKvV;WGc({1K$^n?KuH2Jr#Ava%N)w^q0<FmK{N5V94I_{)S|h=fheI3C8UYDfhj`+
zB`H?8w~JCG5>1(+<f-D~2tWZW3}|@MWU`TX0D;h1Y;*!q9Gr9#Q-#Z(Pns=PlUC}G
z9!-)&Kr50V7WPQcGns=0DZ<$TwXUgvgP;@6%AZ3XD53>aHx?sAR)&HKrp5bmbQCc#
z8Q}z(502h99x^|Ji$Dg%oGQF#cEpQ{2s1nLGs8gxM=91Ya7s8Ig$ChK8#&f+XslH4
zSmObdyav_S1?F%BLrj2PV2ainiYOFQRJ=D%2B%kAM^XiX4B^vLqG=1n(dCh4hEM_-
zXB6>?K`JKJbD&-$DhnyVpGF$7#<CnAavg}8(-oAOG^<Ms9%3mOkfqFo;7>0+Lngjy
z&>0nQ%wZ&1$edmP8niH=0v2VELk$>_G~hdJY8{dTDyo&l3?vPUC6QJH at nx=6Y8DV0
z&cG at OGsmVyg$A!%($#eSt`!{vFiRytMX^S%=8`a>CeG)(K_(bsfe at k|<HL(Gjb&#H
zCosA|8x)Z_2T^ZyEne^nXB?GUDLIya#UL?(S_iIs)`N<x&A3_~ar3HVk^*fKS;1vC
za+1{Q1CR693{J&$5&n&GDAEUxbPUKR38%5ioTa7IJP?VBdaQZA`p-bMgSFOG&k_4*
z&1r*<L|P1kcZ+Bzb--8&C<HEz^^o0XgYt3&@6l<n`%vp5pOh%jRZ}YWK_2VT13pqE
zq5eS`DP##N65*M54srq{iWd at hO3Q_<PecM9GO;KY$#}Xfl0`xVP%}JTFvXu5Ns*|=
zK!rkck0w{C!m{%mRA%JTI&mHZK1fsH^5hO8iR`IkVmb^#ahFD`ZKaW7Z71fvw3O#}
zM+&-lceGx<YoyEts&@gw_qB1w30ZV<CmG7;p-_|+d1_FMgvB7UxM_gny<iq~*e32Z
z=*nEP6=*auy(B6jjABqz=K2Duk(~seBo7 at NY$Pfcrl4$71j)JDLw7h~3X*(uSu~sI
zS_tYECKkRbDP}uo6cHp2qyxx|Vv4F5n5BUMPkImKObRUtKSxyqBFAvM3RcOM_yu)>
zM8Ie<NNumF^%5x;1acZ;Rum)1*NOHdzO{HEz&BE4*oBm=k?5824JD$vm!{T9notGy
z_AC~ZA!$&PlT#QyZ!Colih|%9C>N!NiTGlgm`G)#juY#((mEt&Crt$7L~q)n!_bI&
z&tNua1Pc=xs0?X*;6q!OEud54{m at qGTm_@n1@*uyg|C7x31C^-V$;OvSB^&-WBZRI
z1w)+`(T|Zn7JaGb8A7x~Nwp$M!;Ug<i{vq*z9$%=jpI^Q4A>?rurmv!6cHO~NYJ2V
zs!u?Pm%e4}gh`8-JhqvUYYQ;IoJIp1n<pm7T+3%+#zScnzClkAGYe-8=_l;M6_ZR6
z92Bw$5!{GfO+BWxxd1Fus2(ZuJOf3{NOF{8GFwvVFWJE<s7dTelf*!RbGVVpV10SV
zq8Vhe3 at EZb)-KHwn|Tza<R>OW!X3=b!UuZ8vp%AE2yj9P8-sY$cthc5<%<u6x<5Ck
z=t(p6I8YslqeyWzG}RzE$pVyAwBgwdFeqvR6--kY(H$ozqD3igpNd6<pD-O430st}
zGQy!K0 at BSm2oNhG+|#D*IM*1{gZz&!X==d^P%v}_p`<`8#X0~zfXD at u$zY}N)a0+4
z2to)54{xj?YD8gDgCwbjjU_>-QkCk4I(+Vs%PA4+D6%(DzuA`FfSWqBK7xn{B^=^d
z7)3D}TvoyhhRp05{3PM!Nx%p&;Q<Z3?&NT}+zKL{IEU*g2rN%+W80{tt%QW5;G;yQ
z`T{34WuXWu$S6ZWKuRGqs!t{1K$uF)+(W74>e$GRM+{BLC_au(5Tma4KCzOQi)B1=
zZg^a&K1Q&C-bS%hL<Nx8K%{B1WSxrgAd_L3W<@fps_0CN8p>3H;BSb7CNl|AdXRE)
zCSw?Gwiw3T(%~&fr@^f<Pcmd6A(IBl+5qCrMU6A|d78?dAx&IN$rw%Qg0O>pil%(c
zyH^bu3S|^s$Ac09CpxO4A)%ENi&?}y3GDze;sMAUC$kc6(%E%Xc7(Cc1>;<bxCIO6
z7R=hj4VNZ%7x68{z0`J5aWrgUK^98A<Zh6hWedZNmQr8TdE7%+wLImtnL56Ltjx39
z0L8|5WF;yhn~}z3L_V{~9-f*zB&GJXmuH-T-7HyD-~lU6o at 5*aWN=Sysdulnn5z&m
zJ8z3>qPVO?@Rh5*ybRGjJ0Q}aBGfQ*Uk2f?Wn8ZVs~MmM3XL{Kl(_E!!C4;sqxj1B
z3SbM0S&cev9=?OR1o2`aNr8ik+gLrH2`rT1gc<3JES`|hp>e{sd=L at YsIwd{?pK*v
zQc95vhpxh$@{#K^n8t~GrmmJ%3VNGh$3d$<TVy;$?xUxUa#T7V>_Jm<nwe0KGE$u&
z*x1?^z$F48C`zx&Bp&Tus(WjmM#0}`6i9%x&c|C+;86U_01HSkSxXu*ph=V=*JEG>
zkM240)RQ|Hz6tPvyquT_-rRUd8Aqz}35hXC?3J9g<5)I|_hTyRSQ4389*wT6Qd<g7
zq`x2W<CNw#YopxC1QD=+GGuR|H<p?L`58r&bJht{Sef2aD(KSBIyqdTag~{vXwrt>
z(Xhg6JyJju@<rkC_=kE$ORc<NVOJ1KQXl$^U5Ry;2M4q#!3GzK+ze13&5E4|T0G4z
zQrz)4gF;O&DD3ZehNVfX)QKFg0nqvHZK&hpO=(IQrUvq}kwF=hn<}9phN2WEH7$R)
zzzoF+N-}uVH!>+hK8S**o-yzkFL|zq3RQ`v3k{f690xMCsncW@#8BvFYGE}Mt6xE3
zGUpqW^R$aA^QBO`I6^^b$bW1G701eWo<aFnL#U+m)etIN524)k5X!z9LP0y5iy at Tz
zr&B1+k-wNi at n1+>OraP}(=n9OS7WHG($yGB=9!mcC^H>HMP}@aF%%EpFUL^&^%#oV
zzKbyw6#egyq0IFd%Dg#*a at RvBe?5dc4++O1lzw9f72g;_#p at wd_SZwGFxt*TsBk%i
ziq}IZF22(#luXSpr%?H73RT*`?@po4Q at n8srG8`r<<lDzsH*`~^luEH@*5K<doh8s
z`f3D~_4NqKU5%h(z8XQ%-*CJhLH*DK%K!cZiuBUOzlpis^-sU{{b17M-^HB&#b<vw
ubnBr%w(G~^*VXWN?9Tth at n7+uxO`aLeR}tS{&nA{cmDupc%p8;FaQA87nX_u

literal 0
HcmV?d00001

diff --git a/ui/data/sources/tool-note-okular-colorizable.svgz b/ui/data/sources/tool-note-okular-colorizable.svgz
new file mode 100644
index 0000000000000000000000000000000000000000..328ab91c4372867a0ac58256a413b1cb44c43c15
GIT binary patch
literal 13509
zcmV;$G&;*4iwFP!000000M&h6j~z#H<@@}KUJe$pvD258-<cdq#$pCu7?6O4?ZrMC
zEwU-~PP3b6wnpOo`i*lU^6U0(+i#2Iz!rIKR#jGJWMo9-iKuV>;kQrsSAV^I`f~U9
z at a-FSI^JB}KD>YYaQE=jw{QN}zy9NOeRK8Y`R3un&HdxU?YD0p9^d at Kcfb4Qzg%Bm
z{psoU=K1!+)vtHYKVSXR!(YC<zxjN7^>;r%KYxDr_U*5~{(8DI at bvif)7!tly1xGI
zcfb4Q%U^%`-PP5VJon+tyASWbePb7V{^jYO4L`hpdwYNT>Gt9I%UgGHZ{N)3?`QM(
zc>3L6Z{I(D`t<nlg;zd&`Tf%P>BGm-8ol{7u#s!6y*>O}@2{oB^_Q;?&o{qa at 0Us+
zFJ0=7<9I8-&6fYUR`0&ZfPR+$8_hd#`ttb8)BD?xa^3Ce;r99Mpa1pG<Hzgc^x^r#
za+^M$+f%neez^H``{nb^``a&XJI?EWz5DR|v&^rr{O8ZNcR&67JpX<7;oCRTW1o-A
zfA=1|8<KIHg4d>Y+x4edPwwiem3*+tCQjS!K0Llh55Il${P=i({qXpFd;R#AU+!<7
zuHQf2KR(_4?dHe(+mrO<Z~L<ze|i4=%k#h8{`P$PptqKnUEZ8O<GR!K*5mry-#$M+
zJzsykyT8 at vzy0~~)9u at jH$UDzzJ2`5+vnR)pWpuLR}o+QeD(P8>f!d+tB;TOA8!Bo
z?Z4aC&ksLceAI6rKFe%-e at YjB{yKmDPJaL9!|lf}Xs1(wf5}`_{wBYUt3S)ge!hJV
zx!2aq*gk)SVC+qUO3&3cZ=e6|H<`4ncUL*e|8o~xeAO0CL|OiGTx|0<%Fn-ZAM3)k
z4AxI~GG}ZT{VC&5*{_keUS7^O(L--JGH)>${M&d_%+ZIx-rfE>N9 at O&FSmBH&o at 8a
za)!Qr^ZSqdV?X@(`1IlSssF at I<n5<NSvYskU#Hxz?;>{{zaN)>|MK(AhsR%KTF-y{
z+vDRWflo&{g7fM8=l3!n*R7sPb0y^$zsdtsI~^$;M?C*g7Su1$l-IvJ+&zmn`uy9A
z%YS)#LWBF8ueb8v{7>)T)C%LeMKcWS%g>L${`7=l{&;gg#(6veKV5%*yn8?go}YfX
zT`&9P?!)bu*Dl15*FXOF_}g~f`2E+r2N}=n(aZ8;)U8GDbcybj7LfQ?e){_QPoHjn
zyZdzax7!bBa=sSv+N=2f5Bc{$K0SW=pHH_(%>Q!x{49Iumm%T0Jb(L&%Lb?`1DzX#
z-NCOr2&FFflcw<{`gKRUh|A(VhV)-uiH>{amqoDs+I+#|irZtSq>IkK`*J7xaGOYJ
z`v4{R;SBxqaP!&PV>IsX9&W!pKHPt`W_{tmT<^p`-9F!ZxOu*ri at zg2JJ+X4w)S`b
z{O5oC&Yt<r`}gnu_v6!FdKa#)(BS4r**U&_^X9t&fAit}JK2ms-8_GH_eqvC_VNEF
zo3E&$@x#^_(>iaew|%<RUHzhI^WpucJ6!bkU!L#o at Bax8u{U0BdiQ*P`yHRDf9-Ga
z)?UM2^6m1L- at NU^z<>R8CeimdKi=Md`{sL5uJ`wkS1;DdPfw4(eE#(K;nq~dn>oDv
zx9ih#e&he>!WYWWdh#e%f;8y5;`u9t#{}-(oJQFX`p}4c_;AW8hhuIWvLI3v<ydPi
z1MK=B=abLA#rccrk|K6x%whQf{l&vVc6AEsS+D*m2E_fl2Qh^Cx9k0f>!)AtZ}IEj
zWGngOm*=O)zudm#QacX&r|PnIvJ>!+4^98n(i>ng$S}Q=QGNKZg8xSp?2d{Y$q<Ty
zdVUu>_Tff0p{J*tuiDE6ef;?G%kA^K(UYz3a-(-5qks2%{d)}U`1>K1+az2b65DA1
z)1$I>PKU((zZ-x{G7w*pn3P@<vd}KbWSh+w=?#~Mc5CtP-fL{q?i5Ohwf at JwUEVGK
z2lD;<+l>GHe>$0CXg}XP|2#I|r<;c_P~Wmy+&n+s{q}e6B;)K${KFytll2(ouh+Sr
zqI2$Of4C0e<Xx`u at 6QM8<D(c;U&JVQ=ltj2{;2=NPtr%(9_|(S>&?^M&BODC{mNO}
zAnE<>^ZTDW_ACz0_09d=PY>_J=YD$rBZkVXn|ET1|JOhM`g8}g;u;F~-Tl+`^N)7X
z!~35fpX{nW7{{sDjG7WUo6*<jPhRY727mnJ`T4~Ja?UO&6ujEUn@@N5U*G+A8Hf8n
zUU%((t*<R+{@usB_u{}mK4_CM%p#{hTvZwU8vGId5RX%fKDcuA{ep&k%CUr&6s^gn
z>|a6U4l$%y9nf at Y;(E05I(p%06P2FjQ>eZ=d0Lad<($IRpH{S<sykv0z*6)rS74!r
z;xn)+Vpkn7cjQnSt}Z7Rj+&%pIn|Pyi@;(kc-3+ezgl_+s78lwb}ZxKD(a^t-`1A(
zlwEUyH*AO8JOZoj$UgDW)u-febvwE2r6)k6?0td?=3A+e9hd*4+&Y%@wWFBgRj=+X
z+o{BGG;JwL>EOVN-jbg2DR_(n=0%mYqCJ<tNQZ$YaeZ81FTMAfgO1mV1(*zpO%Hz6
zYXjDA)5&Qr at ml8;69>*gDKBF-F%Ec?p@?TK#l<S at VlBRjWXNpE%el(_wIJF+r#iWu
z4>k-ghFW)_XwDxoUKA9HPxG-J>0Eq>Mvh}mM|13tb48zi)X*IJC^M8|(Qyne6n&c@
z-4g`{p_aQG0az;XaAK*nBjj}~2F8(eM at VjKDWmJf1Jq?wMEE%iu_ft|KKt-00U~L+
zwivXR6aaB#lgxYJ%ar2F#2Q~ax1%JzxVIEhs4+OFH!QLof#nut0qLW?s}#uC^5N~#
z!PTHwW1Ts#FC(j7*H<h4 at awWsOoz;dXKQD}$onO^^)ldmvIuz9t8Hr7M;WoaP9ff<
zdeIh_Ci at 30hKA*ycWpCJ=m0#Z3ED)&YLRvD8Y*LOc$op|m7wXUMMvqVPDTV+_R?40
zRU}weIIx1PjknBV>Lk5bRDx at fS_ChjfwfR$NsDG_vR<-FK5RNjP%&kF%6rS`TJwC2
zE5QTFkTmPekz_ExXFHkO!k3XNMBUgOn at lPPK15l21(?gSZk at h%k~PTw1n7CgQnR6G
z`s~?IUJzI7m_-r5q9YNrZ1;S$Xu+ZvQ$_PJ6#mAs%|+HTumnxziD83KA&^(hdU4Dm
zPwY>XcPX5N7?0>F{0C$|cPvmcT#$$ByefEEFxG9T!6x)#`%&Y_iq8=@h at z*8Sdd(e
zM=6mnBq+p{Xb>m)D8NGUDP&#sa#Las!on3^q8OYUOW8;vY}zZ2{S{bhB4TyXpMrUD
zwPes&P20SvfEZm^TY4F6?01W*6-)$C<ag7xGP|{4F{!TgvSS02*E))-T5<a}1UL42
zrD2!`c at th(rOQFLx*7s*CXbcL%%&Tl=h){c+O65{nPlJ6_c+o~Rtc9kJ`UH?z81uU
zm%Z+2d&?$Ln7rQ6d%STJ15+eLA6;pRaIVlbUD`2M%6&X>$x$F{E;0 at Si>g|V(t=*y
zTVg0=A4-Zv+3ty at +Pp$Os9uuSlPwOy<7LU|su?H;L)0=Ce538+G6(3WUblGZP1BJ~
z0tMX`kDRFCF>KKARkx;US7U*sv}`yS%HX5-+twtgbiC*$KU;Ru<NA{q1195`0^3DV
zhs~SdX1+MZ9 at Yis0gvWh=fuzQ?&3=Nfv=4nP}i(zRiAWy!J=t#K{@KwK~((}>#Oof
zGIwf2Wr#SXpkjm3xovZOWij}Ub=$#<7qM^L5X+#_CNh-HM73q?ENerIxo82sp$v<(
z#O#bG%N7 at 6mvi)zO0BgNIXOWr8oi+?OfmH?j)ja+g4>HtXw_B|-8QUrk^v6oRTMU?
zXjM*II+=|Rb56`c2dL4W<??C4L7!(x-k}>2O<XP?@x^O)7&v*5XxbEkK@%K)U6A4_
zh-nhyzI0{3hFrU~rR?=^4vOBfrr>~yDsnmMv+?e at TI>h0LtE2cN<RxQ*egvZGSCMQ
zETx>I+qW#-U8axE#&F8G%O$c(V_dsaX(^YwcU<Kz*R`e06(U@^0Y};B3oz5sFcF*>
z?$ptuL7M1Z9r7y1QUDgk5VcKE{tKBlOl3ot`1cFC$$=O_DLPdV7f>2WJ|yeCpobc0
zrHHa}#6lK>MAy%8U?M9gT9q}IezbQN+fTK6hzXk;yC=>SM_2^kaWG{EG%Il0Ot^WL
z5upf*DG>N*Xg~GQ#EdJ1;&FsFpu;Y9SR!R<s59TpCOyP~;mnF0=C&_BnJ9ON=H$zm
zwN_4C%uN at cxE8Hrg<4q*1rFoDw!sx!75-0s1;vodwibduov2#bq9!SpNABiya($V|
zEI}<}&{{Bg5hu3gsK$^l8Q!H})0DTd5JyS$RV at 3UWo%3$PFq8-HUc0qnV`gEdB+mX
z*29C7UM!nu)Van^AE+C2DPr1+cm_})s#D}nHq8RTRZx#soR>_cB0I_v=)1}ylTB)1
z>ZVA$)b*62mo?pLmx*eU{)9v&Aof*-S+;;nghH0V3C3r94ZV1S4z7<{yR|hPs&>2U
z1@!VA_7{`=C(FJNeHX(4?e`4b^16)56pQ6qvG9RbxCB&35RgO+7M~hlFjt&l at icv-
zZtMWXzOC;h)~?tqz+%i>Fa%hRExJu*0u^n2#I0o#sk4?<mTyoDma^)4=)B0QlPK|I
z`|crDaVA#OY#bXoFmW?=k&E#af?eDkA_&lT;$l^=7`7xzW9GiQVTg9P)UWQSD86Km
zZg6~Q!@z3PM;Eon#b5U^#r|w)ON|wj8nxkwl!=p5vOXH70d)!ES<WsNAOA27!{7|Y
zk%6|wz~_jIdI_5=z_|$t_Sn|ab05YXMT2;o?5^DU#!j(laHSaol5q|yJ~gO$SOWg2
zptYc at lKY11;-~0K>Fv-DCZ*BQyo-Hb-%xSzv$sdXU#1~>z(+92E%cLMNc%2kDpE9n
zt&ie-#k7WD0LetUJv76yl|heNOPK at l;MQOd<+g}iZ($)yZj3sR7C-_PeJxI7Gq8Yn
zEFid&?P^0SZA^Pk5KBUhTA10kX2kgL>ad8ZG$h5#;OiFQL({bhD at 7e1$XU|&Zq4E~
zDtr3gW)?2(%<RGanm9hh%>9BneK at Lm&P+HCi_ORqPx}l)<#TbpoNGuxrY*$jf~|36
zib}?UZQK at Qw^84QD0K~FARY;mBb%r<aSl*Piea&Ha_E!kIuu3TSEqPaVi^*P*lxG!
z7VYGH&S!!FT@>ps7&2NhCdyw5jL!kXh+7ccV!l8_sqA+M(hE<BmN*1R%%reGl%8sr
zs>KdH6AP6lqT8wH@(`QGD<<}tIgQ=eB6`SdQ}~kfI}tmiv#QNn7Dc7+4Evgx$WE&E
z&SEddsO~8a$#lGHQO_h|4y#U!bx}t3IHJu}LHHY}7yB#{$|_O<9kg(P!F6J at L)PPw
z?P6MlTnf=dDq}gT%O_^uQ8q~S31<sof=LYS=Ja+hW{pHOksGg=*h1<G6^esiEPjG+
zGAXLi%Zqr%;bq_wLtDTqClp&0f<B>(XAi(ZdO0sLUV;0O#r~?wXJK%)P^X!)E(mT%
zjcveh*Ll&^zwDS|ii&4=zPI8SgYku>C4!RKT55oi0#T?XmQW;R43^^(vjmo!FVr1J
zu<pQgJ!}saH`jJ%*;8fzOPl6_)u+}wSAkw!v!}_KG2DUcyiWaApjvZZE{IO(CT`m`
zEY)ZcX+)vCEkK>E;M=^|<Qs;MOh~ff at y850sU$<Aw$;1mfP0m at r5*MieLeA>o$3vl
z$;b}!M513TW~~K5n^;A*Hd-)e3E`MCEVYzv^H at +ZN5rSmJ9fb>GK^lIeaOzmr<8sw
zz#hr2sE$lfa|CM8{4ea<KH1AOoz>x+sOYK9#CS|L$t%`Sq`y|vj7g6aWF at E@&GBwE
zQ}f6|6 at 8-<m?{;Amj~<Yi|JRn_Qk-^fDr{Mg`g)kvhZ3kacU`O^ei>KT}?rc!cw6r
zq8E3y!)S0(sL;7=dX82X3~IIeup8=C at QA@SqM9zSF-(wqm<&3w>vQZ8YV%aa)%k|S
z3=|s2$uzaoU8DB1CyK2&{d)LWa3*Q{ODlde)%tkvMqOcWsGYUMU)6ySb0Vs~EMmaX
zRGWH2v>u2%8uaC%A{Ay*dx>%Xba7Lbt=c(Jj)qR>WkqA{j)tHzsDa}Kd4%2*Ow1_1
zy`z%>Omz=o15{UZZ-`Z`L2*^Nzz}Fv>-ZQOK;zL?Ss#5Ml$yO;0`0(x_%<B09L?1x
z>RfZWsbk=XX(y#$A{B>TJbY1)<HP=Fb--z$h=ZAlr6zyp4&Lq21uLm`WjN5)k;6-R
zf9~E*v>~`<2GWX(RobwUf$;#GbICJbVo8rZ5R`D^;%XL2Vw at k4$FUt{Bg;(awIL%s
zjnRmXu@#*$TM#(ZvImdBK%~O!4aEk|E2dZDv~h3gl)S5VWZ(>#9uv^Gs!<0WoE&in
zHR>$dR4;~Mrl;THaC^Nt(Rif;Q8W at p6ungYO6@RU@)SKAmfphDSg|OYgEWQ(-R4I8
z8`<F7E9k4MXS)8<b{M)#+m7z{4X43TxP&f|UZ6(Y7@=NZ+JhPD1tv~^_FJeID0Ea<
zLcPvKm88Y)5J+St><5-W$tgH%i5+Z>^a2w{uH-G!D}5DdNN$bv0+aix?O>5!U>2iZ
zBE3MP>`-AwdI7<b*@6)+pY$|t at 3^SUqm_Kta)w+q(hCg7hHZ=V%H5>n7LC?GFCb7e
zmN;*R+!p7Z=q?3fqJ~l~gKL!6Kn-qMl$RJ at a*6Wt4aHE-Ta=e5BHv4x7nt~cHoO|<
zC8iO)CCm#n(2<^DULD_bED=jUaCJs(^62wbsbZFfh at u3wZ!F9UEQMxFnjYo_D#lj|
zOPH4!NG?m5w_{}q^G<9Z+&JSp7tqa=T2T%266yw|g?WLA at p<fFUapa9p0tH|fknK}
zIu=oel#cW^XyTl=v<)r}L90f+EXvE3jfvT!yg<v5kF<n&sTZ70g2s8NK9p0kgnEhg
zsDOofseW*twuE{&Y=n9zdRf)2YOyBWjbtM7a$LWnNpy1{;Ybt)^m+nX5eE!cHR_SF
zxb|g`kYZ<cOzclUU4Xm2wv^Fi2w$I0h7N{}ekvXUjYx)97`z=gyp#;VqzBk3Vjhek
z5FWYV%DM<*O?bT+%SN<XOrq&vDFcJ)?1_oiX))|rfI$=V>WLl*Qxv`9kw9mFY?cE0
z6pl9auqe(jDLQ#*Oe|_Zjn9toHvx$jlr;|seiQ6CYzSV at WI_MKI1;58cn%|$cLCO!
za at ZZzXbTIcE~>K0drR?>aiWVmYPeZ2YKBOx2c|LE*jxD=3t<aJ$^&0UWKvclBn4JG
zM}peexQHF~3!5>ShQAEHCVx{__0-&-PtO2hdZL>$n1w8+2vrDMkV6^O5y=bbENU3i
zts)fFAY#i-C5skC$_wQzD#xqr?Wz&_ayQ&DknnLS&>pgqb$H3i;yp2;5NI66WSqUq
zyMUP>R<>f$YJ$ZO)VkYRk|NXejxj;XqmmArKKmdcB`%yZ1iN#Dtr`dCOs)aZGjSe`
zOD5MiPz*a}s~84CUfTs4;mu at Rwvxp0Ru>;nu3%N_WRYkW*~gM7eq#coIw9%OM6aAx
zqAxhBF}~!i#`u!6ihjT3tU~n9IIGL5nViFQeGSg)(sFQCv1-mat6U;4II9?-bIvMW
z=A5&N*M7-ah1kE~tmX at x)qIh&nlErx^99aozQ9?{7dWfs0%x^c<gAvLoYnl2vzjk*
zR`W~FDpdP9XLSn7%2_=VA0s?ceVlVv^99aozQ|e47dWf=0%tW}<gDfkoYj1Rvzjk*
zR`UzaDqiNCvx?V#$yvpsJLjxYf1GhvH~ld<tBd{^oYh4y%-4=DIjdW{K8*1tXO&NW
z!C7S=&p4}mmov`lCISr+4Vt3sUNg~UTLOzwkGC#@m#<&;Do{F=WVMRhf(~s3lBk+2
zLs<z#BiwJw3e-QkS5sGk`KK(;se-_g(o?2YS%G7v-g{X1d^o&uZP8UAre)AmH(dqJ
zSCGxMF1m^=G}@R$RdpzAs%kbInhFr~Zdf!G=x-Y7Uo{nYWnw1BwrDEw%31}ZXlg3F
zi=Kl_O(obtS7s_Iu*#r|-J*V$@hThT6C|pzHgu=L0b3Lmc)xn|w`wYIe47W+c513k
zAWTzT5|SU3VXVgGE;>ZhqN#w1G1uCnsURg;2{enQ!s~$DmljP0swBj0HEWi^STq%R
zqm9PF+LC)nT{M-9xKr}Ls;LC!32vO43R4(d4t3E~hQStFG}Y2_Xe!<?lvo!{g-1hs
zwM|p8lhNtbrm6TcB}BhypyjoPrdoz)ZP$l!XsTtv7frQH&CpcK6b?;wX|hR-Mo2mD
znr1=6MnEJ*?o~7{Ofj<&)%7sGR^pqeansrL at b@)Z92R<g5~man3zdk`>yr|5S0{s%
zNS>T+8Yq#f5?03rR4DPU4}FgE>obqWdv`j&9u14R8Ixb1IzJUJY5aOHFGWzizPQrn
zlhV|xVMbO=I4LT}SxatsS?{O>`_y at Je0C?;%Mcx4!V)!teNsv#u}-j0i(5Du_DPxI
zoSx3GPim{trZ<9p8s=MC81`u~>Mlvgx)0%iRYY5jna%|OJFo;E(x=G<0FUqhF^fJ4
zxd4C=BBG`?E<mfAgh0hQxB%ooVsEC7P%c126bM}JRc|yN+w0X+!yxo8Q{?xS at KDv#
zG%i2`U0#=YUbz5=u1of^lK}*4=Clnqz=ADwfPtpT2M`RIA9Tf(4}fPQlZ58g-~%*0
z1v%K#_yBktxYQh8;{%YN+7Mv^*7*S7x8jhAsPO?n@{HEd=m40n-orr$0G|_EI-jC+
zfQA5+^4C+R1GK7oENlG2=m4O7Dt8#VNa+B;5TQ}`L-_z3HV6S5YK#EhQI&t}i~u~F
zF&gU2&IkYsmqu+xr39eoRZkpZrv%^yF=EsXgAzd5%@nlIDFGBy)wZEi0!Sw&Z7qgL
z34oX?j~ZG?DFF~uP?R?vCeD;G!d4vy(uQt?YfJJx{Hhfj1McQmPEG)hhJ08QEg+BZ
zFJHS;0>Eg=&4y=C0uDV!=SUhOfTx2&ee6yN;L(omPzxsjnKWLN)!+o6mwH|sJ0*bY
z%Yk}MT~`e&=7Gk^30P!2c1{3?2WMouWh#-sDeu4!%)}m?u&_3)%3HS^M&mn!tEPtM
zAO&E79I9$!Cj~$PAS|kml@!o1%J?7!Y%Prx0Bp#vkpjrI4%DY{k^+Dxs6?(2p6oU~
z&Q_<yNC9{m<4eVbuv~S&YP#suC}^4jpz#l71z^lH$p=fevjQ*=U~6!34_3foYz8cN
zqXi%<#5uLXCoKSHy-j_?K?^vTnnEkA(*h2j%&^%)3pl3!8N2{wn1L|`ZP<AM1IsHf
zU_l2jK<>yx3TW)k3s5egddZU)a2U at kPg;O18t{5FL~OJGYymuZ&XX1Z<qXr43g2h}
z+-ef7m}%P20bhLp=!(MqaJDqJTkoi}fM!%5Vrx2skKJuIUI26?eSW at n?BerchgM!R
z0;tp~D}&lVzml!RF;R=@GJ5d_VWVIhxR?`L(}e=P-1QQA`3{RgLdv4LAvzyQVpUEh
z8j5hH&Vgil3sLzS*=gdRk`4q6K~v>Gj>xW&0rYCGzUbCciFUveY|AUK$D7g>kr3eR
zP*+ep!N_{(pA=KJ1kwaB^~4IfKakFpI&sJ&O+$UCWb4YqRSh=r at ZNV!_H1WUG*BE#
zIcyz@(%gIv4Lc#;?(iCV<U at -FaF`s<pG9`W>Nxb2bfV#m{+=#ETc5_Ym(kpx{-+&9
zIz`b*^1j*<IgCvmPMYEhEJ0b=#a+DYypLE*Y90ELvqH9;f|J8Z*NX#^GF1?jK^}VI
zDo$kCamt(SrUTQ9mFKv(%*if>oBC4Fe^5q}#+LI!)c_|+`K_QuMiFpgw9qMlQ9L83
zET!f&o+0|KGnc$lYoOrtJ)o at E=Q7Dmau*~(Zu*TZC6W*Jmj19VB6ry<uM<ZYQS}=&
zl(M61KYruxT8R~nyCDdxN2V(VCe6`v4@!^FH88G~!(B+Y#g at WI5g(Ec4PO>$|7I6A
zGr5zV$gz)(gD88M9wPwL3{hZ{grB=+NSaZp<Woeoxf7Dwp(NF$ZXZswYV36B48ql7
zV3QT51RSs at Vu^Y~Bx!O7cM;NQvxO0h>f$kI#@W{yOx(eYkEpx{*aW$sMiWgM=&Vh|
zBpSw;IKptue(abYiHOr?Ds5?*ji+*yPT at jaPabZ(<*ZTQ06pdG;*6Lt7quOGgU-mL
zr5PVlexyCx;wVbtU82B;N))puhmz1?)Wh-B%%qHJ$^=iN8WTk_E8M7?ovUw(1#As!
ztucJ~y~!xKc|7>k at ElQ+y&16)HK17mtslw;oW1E<Fuqir$<351-IpRxhLzb5zcXkY
zgXh>m<p-o4jn}Rm?jX*AdJCo0X2N38mW7iHqq1%O2i3ws^4Qk0cm`NCglgnP8H23a
zT870B8ZYyGrsqWBq`nPuQ<PLfUa*~RAC1b#7{uL|<7g-aHB_^a;XxTKRcj_-bT#g}
zaPBc>p*EwSYMK+B5?f0P)_Q511x-vEJo at Vxigk{&XT`dPjR9#%imCsC*aGsL>}un#
zWlgbAo-B9*cHR|SQ3mUXr!KaQ3}rUEQb8MEogG*W7KSLAtxer|q{FDr=i9&!>!MFH
z8D3}CWwX(d_^t~tswt212i|fvWKC1wfbZh^(yIY1B#fK5p4l=6G<Qm{n4|Ibo8u$$
zD&{smNp~g77YIm`VGLTjr56XyUrL=6 at +Vsm_T&cF)LJ?-lMiuV@(xV`;fl&^wdz+5
zjlU$9o9$o5_Q2R!I4AckB#f at l*3#l#S(C(dAbKo_P#<nP@?IJacJN})6$bs((pWXL
zvcu at rlxq0~n$@4NsN@=5o!;0DVkO7csqSDf>yUwPR)$Pe4LM~^lUw9Olo$l}`-{>8
znQE3Ew#jY>H%m^u%RrXPWi&37M=*bbonm#$BN)O;=na$d2<mKUVH_|i?+}?~$D!v~
zo$@%?$y2X^>#BmfYC!N>op*anr*s^>qj4S`MCZ^j^5i_aPQnh8^XN_*<L`V&rLU$f
zSPXQWzIDE%KRM+qFJ1ALWwUqMb0aQWOPJwBnF53F2&YA3atqxtXyj1!uJIj1PqK=W
z at VH<L;c=k(j0;8 at +bd{XDUU>{q&wjehlz*sM+V{1v&sl}f`#ztElGqCDkD7lo(~u&
z;ZeK~Yqszm#beQ$F>&%8Jyo9iK}N|#ArB+7Oy-`~^W(jp=0C^Dc62Oep+`59?I_-?
zV_sUEY)5d4y$-`*I}R*Ow&TFIfpsS>Kk^D1SGMDVcD5sU+n`!9+B#N8Bmb5$u)%f&
zX}`Z at XFDERN@E=gR02X?)IMfN?K2B;HuMGMffl=uM0cmQ+d_9lCP-Ga(;cA`G*>ou
zx+7FasT$jybVs1xUa-?0p?X at -$atqa8m4jZL3f<!MJ=}m9|o}&I<^-aBF#8<N4yst
z0?JA!ROVW6h$LmCYpN;1f<wF~(|WMO_ku$t<_5-Qb1ygqDlAVBR)5Q-?n|zo8F<)C
zI#^pq=nf5|+3_=(tW0oPkDp0q^(93;erCZTrLrOsg2&IAiLgMu<j?}fUUNwAXMtj?
zIiyc+#}?MrF4FZ3z2*>K1r;VX-6t;%lk7}OCg$kwS`tBkV8MQ^IYbt<YR=UxciC9D
z^krCch!fk5daF6KV5^z6qE>TAG4ssK^a6zQel at +U<`9|3p=l6y)Epw(%_^%oq`YNX
z*16XlQg*%_X^omg9JU at Qw3<Uor9Q%XoW`NlZ1&|i4QMImu`ex6`f{&1M6P&I%XpL=
zqUiRRf|eZOH1sE1$)QVY=?7zBS6!l`<dC+dy_{yrA>OqbC(lX_Dal=(N~<`e9Cw<_
zaaJ5+*Y#Ly9L1C5u9n(3R^R|By=)cKqy?eQ8aj3DW3M>GxzQ7-ZG(uXadu`Uhxpz&
z577-mOCMYq3ye^m;hq at -b=A^ew-~6y!B&qpTMSe%mfl$-o30w8eT#uQgrF_*va~!p
zVWr1FT{+p&<QfBYut)7YxyL|(F`;&efeHr0pzbkHpuRg at W;6rqv85gaU9lMio#+}w
zbfrt-WpuS%=N(={XAl(Q6kJSu5Okv39meckMz@}gJ6uNBP^h7C4TW<44j<M~D6nKc
z<_LuXRDqnKP*=%3_iHQ^7_xTuSSV17D_STN;v|Y}3vfd0m;=0pLV;@X<JK~Fo~Fe@
zFUY*+9%x89xqhIogz#En_5m#{enG}_!SMJ$B#+HayaixjPstuDSkisFqR<J`u at Zvt
z97knaD=k;hrj!M+po19Y@|>__E<`QFGcjd}Yu&`9WzedNykjjq&L^**Da_~(ib#;Q
z8dQ5ZpaH=YwnUsj^r5^Xf at 7cwuUKeR&&oFx%vq2`1AP_I6$z<-JblMg^t37A05~V5
zm<Fvjkbrt96(v{Gf)<E$0DT#7wM8x(SsaI5+<5v5R9pxdRg&WooR7d}P65k<P0Z-=
z;Do~=oGlZNzhFqT?(<X)!ZvnsI6atJY%Uq7IX!~$Jjer!vQr*T#e!Q1hC=*{G|~^a
z&89<pZW#@zFOv8qi-3Y4U&$82J>i{4^t{<LBKgrP?EvosGOG at y$grqlkmkYj<I`;$
zLDq$aKs%-vBcZjVy`gc*a6<$vIkTuP5P3sU48~GNN(}5cb{uE2oJFgNnvlEevdaT2
zl%UG9|39rQvC3T5bQ7AflvMa)Dt|0vq${jNrC6btnqVfVF6L_1AO(6!kkDcY6Vnul
z7U9rtEn$gOZRxNxa27~}<PxbC-@|-~=z5|k43{)TBFKaiV}&7iQH_xAjcTQ0R&g*U
z- at Bv7k}lx2o&@H5qzfcX+Q5X3bOEG)vqBN%cccrDk(^gKFB&=v`-&*E^J-dKY9Sb1
zJ2PJ(X^@w)-}40qKOdrD`2v;x`oW&}d;!BM-+SZ>%$9EC3m`8+)(llx&ljjHsFOL}
zYrcS(rQYj2j(h>c6?7(MzJOOf0;M?e1(^QA`R at 4wh1O}<RPPwGP4%Ll8w=hpEwd6c
zvZ~&mFc70iT2|FNGX}Wgi>lt9F)-y~W(>TL6-p3OINiAfX<{b^(h>%cl7_4*4x}Xv
z;Mk5aUJm3;7&!X)%zOdQ2-~tm=1{DQshq~l%!Uo-nBH$>3xFF^?7=fz07oiK*G<nB
zptm3RCL>!QDs2U?ykraXmdBDU0OGkPHnRm-&6Rp;W(yzyF4D at DJzGFeJaxC4Spfa5
zk0o2c24`(HTJ>CkIo8LLD==r}SaJny@{T1{;KeL6RUl!hdzIQr^*0pje<@_m{1x{K
zijEHI+rg4To;rZUOD%7WW6H4T1u(<SpkFiyD^zp7x0Wah;kZi|sBK~?k?UjCZj)YI
zaMHtW@?=-J%RwzDD`Y^dX$TyH?sHYnm7pNT>TZS1N><B-c~ICg80*dtdu6dhfP%iO
z(jxm?)7%B5-l-LXmE=3-J*^$z5Vie&MVHCIOM?7UUqdm3mbuzdH3(oImp(|j>aNOT
zTVMzqYVT!lw^xs#0hLAba at 3hFhgTOHtZA|DYQj3XYDfj(-bA7w%c&xo7j!qb+L5SH
zP6CWUht>ZsC{&lXhAi}~x2rrxLmhS6UuqV0E-wpDfDwr|!6`u^c8E0?b-NJzD-4Vq
zgO6N0->>LJ at t-J*3>U4Z2h}nd#-orn)a>XLSVyex4!c7c#-L|FsZd87!#HT=3u^Pp
zFb;b3u6BnpjDx0zueM09WSlqk*{nvN-&;a&sD;rP#$ayq;1$pA3}Y0V*80Zir5^1G
zh5>GT8Dkg&OJf_TdS!3rI=h&6tB?RU$i<O$N_<(27%h5^s)yW|I=MJ<TQ3~hPA*o?
zY~~#&xp-t-3fjrV!Gbo)4RSFih1zd0i-RU}@e#%>_FB-AYO*tnz1C~wZZVm~UJZXr
zS!Wh|GGiOpMrRhU*kl&3XlE9~m|%nfE6bS0o(J5DP4()vG_RUY#w<quHjOsuIAa#e
z3mUhhEzDx8->s-Ii!IkgT^7 at EftGMlGjK4AgI2FmhsT)3K@(?I;}FSDOsm~hdmQ<|
zvt`tSAHAb7i*Y2u%7DE;R=k^WSFhWO=5Rzkkl|PuwHTQBx5uOwBUc0`GG51$++rpu
zunu%OI=8ry-cr at v9Ngm8!<<m#gIXMo@`+hAYH`%4t@<`bEsiXcq|VZ$7EcL32DLc$
z%$4auF|$l{%yhLd<VZdVdqaA`c0;8W2Ud*@XX+Xbv+9^*P>TbzL(K9vYO!JZf`eMT
zw(Qhm!G`d5YB9)XhdJwI$&<1#3Z$b`iv!I>-J?3S800e+Q^fij)M7{<^o*`Lr4|P*
z1>@D+QEG7{$w;FslUf{=P{Y-2)M88_IMHmW)Z!MIq*G}!4r(!kDkl`Pr_o4iF-6K#
zvpS;|Lwa(zEeExjDKo4!O>IVMF*A}}tGw8##fCMi??EkITKY~cZdR^_Esa`?XJgw`
zMc=8#=%kjshYO?JV!Wb$C<4xfa*La}vFdOPZgK3{P}mKPTO7N2H{F$G#23c~^Mx2r
zU0a3`3h{$m9GEhoj`fz!sYS%;?kKm|lecwfoXNPw7xre&3DSxd*pkL)H+qf<nvSn-
zRO1`rp7zm=9z*0ls^8qGJs}C59N*k16xmwzb at ZDXV&o&jv4+x6h~A<#>j35ct%{{3
zP7zq}XnKCEu}!wy>iKE;Y#e&h^V4r`Bu&(a>iO}b8!I%vx-r3He0Br(gC<uUpr73s
z)xB5s18N%RMC#D%XE(Aj>ZWEda)BN<t$RSZ;0S;!<Xy~qKmF(is?mUI!T3P`=7xUe
zMT3I<n;VrCjMW(L-`p at vSL^uZ#%$@vH#dMCAy!?({N at HS#7NtxMbW>x!GvAYDf62f
zSu3At+{wPVk=1PGwDfOoWX%XqY5?|cZe$HfdUchnU2W+TiwRdWAbDo&75yAf*jskd
z^W&QvMx9d!dVF)EFcPNEv2Sjao at t1V+c!5ZETbRz+CxXqZ*G8j$3&Kia?}~uD;lTN
zZ*EvoTuN2{=Ef+#PX~9dFOEiCTw%O8N*=C(MhuZw)Y;`!4>Ff_xqs$_W`KTjBWp1>
zb?Hah|7>|9-2C*D8=ddPxSD=(<HAT-wgL11)}TL7t&X+^{h3#Qxakt~2c{+PX3!s4
zK!)cQ^arX5JTvHzG?B_e=u at j`%9Jmg`e8l^E4?o2r&(g&4Ef``5o!vqA%A|MBHJN^
zh5V87q#3L;<iBAf<iDX7@<)~si+aw8KOO at 9Ufn(IM%J!+x)$+AT2 at piX@vaoE=F=$
zLjFkq;-4ktuPJIgMI2g5hm73&MStnw^2~Z^DU;wyv>zdVPFDoSU=8^L)u_b``E#=Q
zA*vbjSD`3pA%BWhOwMm1e?GlsRojE~47OM^cV0vO=sA4Qx`q7tKCHSoL;k>&u00nH
zM}th?Wr1<nSQdD1c=UB_A%CPORelCz4f$hwJU=fqL;gry3f<+gkpF@$A^#1vkU#F|
zbSOv2AJ0Y-MA$<9n)`aFuiJAOdYa<Yr<y93Yuq%ij!&rNtfjr;2>D|c4n2liLjIf^
zrWVhTKWDaEMHceEq(n5e2%esX4c6=;tyBm#ux1z88Jb_Si?mu2u=AXuj;Un$lX;&@
zOK%wsz-D%l(!roI*6bn+4f-{^NQ;6&h0W}u*lpe|yC^U>38OjFi$XG`xTF^iY)daP
z^jOn#9QU{M3c3b1=N(=}m-Hg96848!*Yu)+wmp|fXYVq)_pIOH71XauMhiNUjJ$Ch
zXmePS5sd0=cF0IFg6Wzx$T*UWynYBxjRwmy(sCGjOtxkj&6PB=jFhViXyy*Ng0B=z
ztY@&P39~fRdgjZ at d@1w#1%N{j0Tv5?7KUF<e68f}bai%~8?z~Vii?r2*))gRPm|}y
zTnbR0r;*QZaj<^Zy2&QvknOu{)GzC8EtNpH8u|JG3h;JUBcFMLeP%n)ZG59;82KAC
zcy1FMM!tTE!)fHI^W5-cvK=?w9`SL#w%GXkCdb*{ha92fe3MN4wBC6`m8fatGfj!P
zajTU-D)CPvf9B0hBY(l%noF>to#aL=n&EHx1(|-xX5;f4Cvd<w8=v2}AdhO=_#7Ng
z{xI?RfecpDSxtNnnfiUh#ODWXm at ctyAA0D!ZazAWv9HXfr3v0J at tIUcGURIFQ*1>u
z=V{_|68fV%$L+#8`a$2CG_%#j*S0ma&BQ0l(iGFg*IXmhww>h0L^lgZO_CdgrMb9R
z_<V2HQ(Encq at UG07gD8Dt_|a9T8GAQ<JU`q_GWV2DB^Zd-Z^e~Z)Q_XBmdG^V1%lc
z4m{h5tChOlcVYw-T-`R}YDKBn?G?l|H=&-cp?v4HVX at k<>pomgW-D*|u(*U8EnfCv
z`#i+D4a1uZY9%e(a5-66$FEr-tYo%r!;00jZFr#D2G+9%FQfa$*zfQvx@^Oxe`9Fd
zh6lRcp-<gqbnjWe!z<{v4KL`}h6`t-ZrgC-sY2ej;bI)wbsH|-g<ZB`WMCaCILkI%
z^)z+ehEcCBs*68%*J>XD+P7hl at SJyNEd$F1Ec at _FiT^?Q_{@q)ekJ}d=u+PQusl9W
zqm}nRtnl)>Kem&W<Jfo7W<`?smbu3cdwqYwhMl?9_ec6(Tc0hMBcpZh_rwl0`M2`^
zNAS9=M|uC+JLzYAe|!pqM_hib?_Z~dHR}6U%XEd>?e+Z^Y^m?x(Op{gLptYcqodfu
zMt%Pk?e+bEv9b=srdr=0m`3~jQs5uo7w7 at fUf~}Yi`PO}t-?R1LJyYxtnkk{^BUgh
z75*{1V_TaQ{w?a}_X_{MA5<<awQwNsXchkPl?@GOF9rS&R(n)UWd;5bTCkwSDDbb}
zsxRs^jspKMnJnHn3j81T at it6PFYtf#rR>%M{~g^X2cH)R=dMNvUtK**W(N+-%;jA&
zJ34=Rvv^%R)!{Am%#O&z)V5l at PP3xRZt)@;f=u1T;ze0-rerRw4>i2?oPS-XE?7Fm
z+S0SAOk6EqWHr_1cR~|T-*v>u>;SofM$fQ#S7>H-3~*Y!ydOS?vRJ%$a<fRvB+TP<
zfpuo4$;(%P4YgRZc<IPooYm%K)%4c(mM|z=T}@upYR|y}l{2v;^7uEcHZSINoG16h
zj)AQ<?~0DZ4q}VNOCT#dZb|F#{Sb3Cd7T;oWi@#@fo5`yw2swtoM|1w==Y1wiv&L&
zH%vp8vO_}1YVx9_eBOCsi{wp{7dbq|sVpyP9V~2Z=R=m(5yz89R>#YAq#w`7*_7{+
z)d5Q%g~K<C7k4mn@<{54r%tdONgYvHm%F{|;<T1WQiqlXtg9VMF>7 at f(O`u4y`5&!
zEcPxY=7qV787xL!8z~()74&+;k<#&UAbw!#NamNKc16|EU8nVwn at eCi_U}E6;N{Wt
z5OZhskAr?qu4!(k1TafVzh5-S1Nx<kq>FC*?nXQJQjzGyPll{5OHYt#R;&?_?}WHf
ztWg_wU#1sp<Skj=DIL97qvqI=L2~pGjO<W9-(K=>d*O|}Wjd6}ZnYXY7EBN3qpeos
zOkV=3wHldK#E+kmAjMjZn)zfWYok^p=OGnyu(ehrF{U;{4zyU~hK*v43wlvD2KwfA
zSNiAf!?$lf-ar2O&ySDKq88(utGD0DZ{NKA>AT;3^Y+VM<v;%yzQzN_ at t6Pru}hTY

literal 0
HcmV?d00001

diff --git a/ui/data/tool-highlighter-okular-colorizable.png b/ui/data/tool-highlighter-okular-colorizable.png
new file mode 100644
index 0000000000000000000000000000000000000000..5eea56db14f71954c8f96a33ad9196c3106094b8
GIT binary patch
literal 1733
zcmV;$20HnPP)<h;3K|Lk000e1NJLTq001BW003YJ1^@s6d?Ij|00004b3#c}2nYxW
zd<bNS00009a7bBm000Aa000Aa0e#hi%m4rY8FWQhbW?9;ba!ELWdL_~cP?peYja~^
zaAhuUa%Y?FJQ at H120}?hK~!jg?U`L{lh+x?f3KZ5c8j_cl~ui1iX8=sNz=Bf>Nc&g
zqG at bIlXk&i7n6YSf})n9UX+{NWfC`?Gzr%d+BEF~kqH5FoNdY&lx@%{Q#CfW0wGb0
z=+=hVAx=j={Mya?@$}-HH!&0^{tCHyAL%I0`}O}l&pH3|`Wzb~!dgaXP1OT{03ZO+
z0O7R+F=S~b`ZtgT+JNVQS>P$42z&w<`rIdg0Q36T2f%y4DPXu(fEHj(Ke(s?I)Ia?
z%4`SD12e#nfu92}0C#|Uz?Xr40G7VK<_G~@T6h$A2Urh$4fq(isapd0mj;~$x;4Ci
z?OEXMdH at U&8Ag at T0saX50Ps-dd=YSgR(-v#|F-Jm^S~r<8~7XW=XwC at 0dHEYxeZ%@
zmrx~tu(=hE&jaHqCo~=+QW6#a6p>L8`H6^J(Z at UyadeZiWAh^NcM*9`L};WLBJw7%
z1Nfh2`W$K=@PG_30Q?&G1 at Kk<{~*u~+(KEf?q~sWz<*Fy{1EsC%HP+35#Wo!5HJCJ
z9{4`Wj=yPC9Fz;b1$+;<3v597|7lbO?xDOMLiyj-;v=ZZ=^{(ktQ(+_`x}lmx8a%t
zw5)Lc7!XDEv)`Pu&vU53I|00p8b?h9coNv8MT@{yU>|DU4*|PSujjlz|102U%>?)e
z<%D&>IiOdIYyy6Svga>RHvXs<VLw)K!7%W3lm-8*K^{X*R*#omHwC-_yo<7C(*VAL
zdR13y1z=jYg<6EG1z7c1a~lQ#0YCr{00aO5KmZT`1ONfRN(+;Q!Y~X2wSOog;yy9}
z!!X)VTY3KWpJNz?Cl6TzG!4Koj4(?pCt+zJ8!Bs`sY1g5I@|SH+|{BEy7cAkVO6Lb
zz%Yy_P<uw}%0z|xGxi6$1K16BfgV)rfoE7+ochA$%|$KS3nH at Ynz3pC!!XtZ&jOJL
zPL*eCqc*u_MZ~M-xyu6RjGsj9nmw`1rT+(}M5IuSXjK4)VYCBrKAW*07HUf-U&-SQ
z0iZlwMC}dxB at X+-A~IjE=zSu={y+c_06a>uTeoht at xbqkj|5=%?%k2or%zufl}hht
zGMTq}dwZW+JlW`PJ}b3dyLLrRojUcGY&PpnPfyGE__z!W4ZVBh$dSiIWOXah-QC@`
zbLY+r+qP|cDHe+vrBVqIVe{tAUuth}|0%5Ecf#)O?zVmV_FdSrWy_XGBw`c_1zgv~
zbzO?Zq7jS5zOZTlJv}|qJ$v at NwRP*(Z$_h0V}5=f5y5p`EX!haboA!ct5;uN6#&yT
z69*3-ytrY*hK<o^)F>8<`0pFbvKSj1yP3&kzT4m5Ki+fz(=-!%_wGFxkH_P!t*zv8
zIik at h0EI$<k&%&`LqkK``}_Ov`1dpoz%<Q-X_|jZBobYbNQ6S6Kr9xcR4U<l9%Ex;
zqvy|`|IUdMCnn18YYKpAnu-1U_n%875?$eN7|XJ790%LB5fLUQCnpC72fuyt<jL%V
z_cm-p(=-!3Jw4|-J3BW;A`wcZ(xP}M6k=*>Dw|HH4?avB8mxd{_INzr6^TT!EDP6l
zaU2H`A)C!+)9LifsZ{C at m7Y;IfS-9Hk?3k^X~Flo<2bmkOD>noW-^(Vj~zSqyXBr!
z7eJ-V7Z%hKU}|bAJ1{WtN-~*TR=h3%Exwq!Wm(v^y*SJ1K7S>dOb%A_yqW+^(@Y#V
za9}a>^0EWu^ZD%Avu6*bQmLxMYXT at 2Z*6V8Z@}5MO+KH`Y4J=gNmXS-?eqKk+;JQn
z$HDVF^7(u&ole&*4ppoRdV702P1C&C(b2K7T-@(>Kl5ZVIZ&%ORM7=HcI at cy=;+v3
z!D_j5I{j)Ym8wg;Du7TZ)aJS_wr%5i-eTGB-o5LKr|T7m6~@5Pqeowh$K%gVPEIm6
zH^;)l0=8|F%jI%s&YU^is5nshJK^EOhdXcFxG_CGJ}%d<Uzg$GVYzngns at o~<$H$?
z9r|IjzB5)FgflZUM<ymF-Ux at o?##@LbLrBh;n~^QzfMn2|MvLt<L@<`xsHls!1KK4
z9LEXWzJ2 at 7l`B_%-`CgoYO_SE1^B at 8ym#8$+qd`i_06q at II!%xAUrZMvTn844Z#M*
bnge_angdj(l^~G;00000NkvXXu0mjf^dB$`

literal 0
HcmV?d00001

diff --git a/ui/data/tool-ink-okular-colorizable.png b/ui/data/tool-ink-okular-colorizable.png
new file mode 100644
index 0000000000000000000000000000000000000000..a79c37f0af326900a99e35efba43f5187271d913
GIT binary patch
literal 1770
zcmV<G1{L{<P)<h;3K|Lk000e1NJLTq001BW003YJ1^@s6d?Ij|00004b3#c}2nYxW
zd<bNS00009a7bBm000Aa000Aa0e#hi%m4rY8FWQhbW?9;ba!ELWdL_~cP?peYja~^
zaAhuUa%Y?FJQ at H124_h`K~!jg?V4R|6WJBVe-kHhnZ$vnrA;A;jbTeERNAgqEhQjr
z)k1 at a5HH!M_I*Df52%rBDX1|qs;o*Nv{I$EQeRh~er+p0vMS3%+t`F|5a}Yoin|s0
znsLAup at qaB_x54N?2tIljO~P~@{x`#dG6f*@0@$aGxv-YDJ3t{>RzgP4WI_FMgWSF
z!SxQts=$|lEx^_lKJNiP1m^8dsz at nc2et!Wv3MKM3Ty&4n%+=io}UB10LC2z^c<iX
zzeN86eg%92+yrLV8(^t at 8yK}SupY<*Pcc&50JxTnk-%dh1*9#X=_22yfJq=>m$V+Z
z2D}Fh16hnJuD8Ja2M~5AbZXWmc!sft{{Z5^KP{eK4}enk*aVpXJ_cgI-!ZbYE&#<W
zkCCmI>DPcM$FoQ&qf*KRS-EATl)scxdZm=ub;V3TBk-!}oj`}hJI&*EEere_7y_nO
z8(aV=Wp3b`z;`U(ZUbZn_&#vAQh;K%)dI5*_!h-)Y;(Xt;P#3$Ia#j~zD-K`Qz at lh
zq&8Ag%GXyqw^{%NZ;(>HDW&{)3B+GkE5d49GcW>tqmXEfJL|IB^jbWS)R|&muzaVO
z5X;QY14$e317I&kM1^w%khAy(jLUXwk$FD_{#_2hc8pYh$p&aCdyf?|uv$??id3}|
z6H>~bmC{(P1|F0d at dEGx@EXuxYM`B~;8o!B7=>i at 0=)GpSYrGF-o>bkRc);<L)-R$
zxiP5$)BtJ#HGmpG4WI^41E>M~ZviNZQl}`&iv43Jy<#V#E<Wow3e(Hp8`>3BFj_ec
zrdUB(F%K7Qh*b<=M!Ufj7rZFEbcyp-15gyjjnTrl3NPI~6(Y_{DT{Vn9RnzevH_z3
zQE1;=h3iaF1tZ$bO2Uo-OyL%mH?yq~=P)*=i^bNvEC5qj#c0>9WDCGkDP`7<s4W0R
zQ9g(9retZv1<PWz`JdX2))9bdIX-LQgR#b0Q#4bqsMTuQ^BO=6U|j*m#>SSt7F-vA
zzP>*9#fuj|Y;0_txOC~#p9cpAzxe!Mh3)xO{ltkA?h6+#T$`Mn6i=Q!krNXW^77@&
z<AZ~Ps+~@0MHUK$8V?*eaHXrO>$`1jZAvnkL<oW3 at 87Me>L9G)5`;pb#@)MjU){TR
z?;EYHt;*EY6uDdum&?Wc{Cu6NsvT<v(AU at J-m_=Vhx_*Jdt>wF&C1No4B2cJm&-*e
zl_HTy+<WlgK|id)Lunuo=<Mz7{YVJ0ebc5*=(>)S61Uq;GMOZiNZh}5>(;?YBr*k6
zz8M7qfzIyk?khWX?D)E>s@%SPo3^$#+-^7NbeecPe)s0hn+MOHJ^TE9V$}cwfk0<Z
zPtUN==lj~mjT<SX{o%uhG&eVsNF?r!jg5UT5{b-M&#MZ+z`%g_(4j+D{C at u~RaKdr
zn`3ct5g`OpN+u^KA78(Ieb>2j=a&7mqT(Vn#jpDP{#_oAhh#EICX+!*iOc0e(==^#
zbo58X#G%3>92gkzc6WCV`+UBg9*+lI*U4mz2c>*I&+P217L7*V3WvjgT4|250fNDx
z at 9^QnSA9O;&Zed&W at l%~WHJaLP!t7C)3jJD_SWgsr#~n)PgwxLV9?jo(=+V#dcSHd
zxPob#rjLw_yd4gQONv7oMOcX3 at AvOqT5v*$LfYRBhr at rcGoPa(3<iU~BS(%5`~Ci%
zEiEm}3ND#U>Z7Bh at 7NUw2N~$^@85Rp*s)=+*ZWFSQxkJ at b1W<@Af+Ui%c1MKcH_p4
zcS51i at 0|o?s|Nb}`?noEdi1K->wTrUxfxB<o=2`I3c9Xq(P;GDp`js1;<f-zo;>OA
z?d`qR(b3^+X=!;uTnK at tX}T%?JE!8d0QT?S|9*RWyH8bBW at cty5TBl&)}qnq at iS-6
zlqC)}ickpAAf+UkOp?uJDb$RnX-QN3x8;hj3UL1X`M&n{c5gf$CzVQ(&*#bIa!gH4
z=_4Z}?^Y^a65!OSQ`@_`x_+`{%a&G;$HSvXk9hX%nbb6GJ{F4|9~v6^O{L;c;xb%Z
zT>No79*+ni^180)#>dD1mdoY-nog(Rk3=HzYKTLLA{0WrCWNR<Bofp2 at 8ADpFc>^u
zEm2zl`F#FUAw;aczWz`!7<{r8;y}rLf$PqlJI!moZ>TjWUOK>k0p4U55d?p@>i_@%
M07*qoM6N<$g0po^L;wH)

literal 0
HcmV?d00001

diff --git a/ui/data/tool-note-inline-okular-colorizable.png b/ui/data/tool-note-inline-okular-colorizable.png
new file mode 100644
index 0000000000000000000000000000000000000000..b3f7c186f1d87ad13bdd98765fa352f90633003c
GIT binary patch
literal 515
zcmV+e0{s1nP)<h;3K|Lk000e1NJLTq001BW001Be1^@s6b9#F800004b3#c}2nYxW
zd<bNS00009a7bBm000Aa000Aa0e#hi%m4rY8FWQhbW?9;ba!ELWdL_~cP?peYja~^
zaAhuUa%Y?FJQ at H10f0$FK~z|U?UlW%8bKI_pNYG&%j$}asGzo@*jm^|mV;G_fY;)c
zr0 at n(q_jw<O^P&LfYWKSpkN`hEAG#vidg889L`}=><b^v at P5Pl%nZy3tu<NdQ>N)T
zKo0Of02sHE at p$}oFc^G!?+_{Fuf<~V?XIb{zSe9u`>sDg^ZESeZO&~yyn^+54L}q{
zTrL-qBq2!>f*>G{V*q^LCk#UXf*`ot^GwETrj!yXC51u(Aq2K<v)k=Rl7z`*!hXMJ
zwOS#BpjN9<sZ>x(A*G~PEHa%=F-`Mr0O#|WG)<{itJt>9;c&ol9J<{uN~!D4>-9QH
zDUQb at uImzpA-!JjdU9_DFbsocv&rdnqS0v3Znue|2+OjF;~2+ra9x+pW`pN>Y`0rV
zr4p at H3)3`7(-h0HUJbtoApQ=9!{O7#mSy329_4bGe!u^)Pirk6dE)jr9F0bwJDtwU
z)8v1Y at B6=(%jJ)!09h#WmoNv&0djyGAP2|+a)8VM{s8RH1Wsl>r&9m`002ovPDHLk
FV1htk<Lv+d

literal 0
HcmV?d00001

diff --git a/ui/data/tool-note-okular-colorizable.png b/ui/data/tool-note-okular-colorizable.png
new file mode 100644
index 0000000000000000000000000000000000000000..01ade5e6c9072a5aade5f5068bd81db49fe75b8e
GIT binary patch
literal 670
zcmV;P0%84$P)<h;3K|Lk000e1NJLTq001BW001Be1^@s6b9#F800004b3#c}2nYxW
zd<bNS00009a7bBm000Aa000Aa0e#hi%m4rY8FWQhbW?9;ba!ELWdL_~cP?peYja~^
zaAhuUa%Y?FJQ at H10vkz0K~z|U?UqezT0s<sAMZyr(Zo;GsEy#l8iU}%oj<|;<>0Dh
zVRxaR5El_OE>slc-aGeex=Kn&3*}D0E<DRQGw=H_XU=e9Qc8{)+ELw40RIDk5#`We
zF!+|w=i930v)ODIi_!(7(P&ny)xM|#42Q$-kxHOxTBvFc5R1iRq!Kue<D8wHDFaxR
zB_aVVm&;YZ-~Xx#Fr7}<N?ovCum75}ZTp`zBHh4iY&IJ#%VM|NF`Z5^3<J;eD3{Ar
zt5xRnIos_PUDs(gn>;)`(CKvOcDtVgAf?2zEKJkn?(U8t2nd3JWHQP5`8l5FQLon#
zLg2bC?RJ||sq{`m382+#vET1Wr_*e=TXMPFTkdc;aC>|E!O-(OT-W9G5i0>aK0Y#^
z&$+p|VX;_{N~Ne)t2{kDk<Dh&b)DzuXI85fS65dEAqc~eZnw+z^|d-cJRT>T%>t0g
zWY9E?QmKS(+Xx}Jyu1V;pU+dT*Lit)A(zXcX}{mT5<s)r{NsA7)glN2!Z1WiiLUGD
zx=yWD`><CDU^1EDI1aw=v)k>EQj$)mv2B}+iwpMqJ+A9gsZ<EV5XW&aO_N@)_okur
z516Kj=XnG{K%r0|kx1bC{#zFqhC#7d<Zw73gdmklQ7jhUX(-)5qtT$zXsAdWe;znG
zK%^4f-{1cfLinoY<MH at Mq=Do!<LD(g0h|C%07nP-1+xLrH0XK5L;wH)07*qoM6N<$
Eg7>E~$^ZZW

literal 0
HcmV?d00001

diff --git a/ui/guiutils.cpp b/ui/guiutils.cpp
index f66dc47..0710e27 100644
--- a/ui/guiutils.cpp
+++ b/ui/guiutils.cpp
@@ -219,4 +219,43 @@ void saveEmbeddedFile( Okular::EmbeddedFile *ef, QWidget *parent )
     f.close();
 }
 
+// from Arthur - qt4
+inline int qt_div_255(int x) { return (x + (x>>8) + 0x80) >> 8; }
+
+void colorizeImage( QImage & grayImage, const QColor & color, unsigned int destAlpha )
+{
+    // Make sure that the image is Format_ARGB32_Premultiplied
+    if ( grayImage.format() != QImage::Format_ARGB32_Premultiplied )
+        grayImage = grayImage.convertToFormat( QImage::Format_ARGB32_Premultiplied );
+
+    // iterate over all pixels changing the alpha component value
+    unsigned int * data = (unsigned int *)grayImage.bits();
+    unsigned int pixels = grayImage.width() * grayImage.height();
+    int red = color.red(),
+        green = color.green(),
+        blue = color.blue();
+
+    int source, sourceSat, sourceAlpha;
+    for( register unsigned int i = 0; i < pixels; ++i )
+    {   // optimize this loop keeping byte order into account
+        source = data[i];
+        sourceSat = qRed( source );
+        int newR = qt_div_255( sourceSat * red ),
+            newG = qt_div_255( sourceSat * green ),
+            newB = qt_div_255( sourceSat * blue );
+        if ( (sourceAlpha = qAlpha( source )) == 255 )
+        {
+            // use destAlpha
+            data[i] = qRgba( newR, newG, newB, destAlpha );
+        }
+        else
+        {
+            // use destAlpha * sourceAlpha product
+            if ( destAlpha < 255 )
+                sourceAlpha = qt_div_255( destAlpha * sourceAlpha );
+            data[i] = qRgba( newR, newG, newB, sourceAlpha );
+        }
+    }
+}
+
 }
diff --git a/ui/guiutils.h b/ui/guiutils.h
index b68e211..ec08370 100644
--- a/ui/guiutils.h
+++ b/ui/guiutils.h
@@ -12,6 +12,8 @@
 
 #include <QtCore/QString>
 
+class QColor;
+class QImage;
 class QPixmap;
 class QSize;
 class QWidget;
@@ -42,6 +44,9 @@ namespace GuiUtils
     KIconLoader* iconLoader();
 
     void saveEmbeddedFile( Okular::EmbeddedFile *ef, QWidget *parent );
+
+    // colorize a gray image to the given color
+    void colorizeImage( QImage & image, const QColor & color, unsigned int alpha = 255 );
 }
 
 
diff --git a/ui/pagepainter.cpp b/ui/pagepainter.cpp
index 537e5c5..e207d78 100644
--- a/ui/pagepainter.cpp
+++ b/ui/pagepainter.cpp
@@ -641,7 +641,7 @@ void PagePainter::paintCroppedPageOnPainter( QPainter * destPainter, const Okula
                     // use it to colorize the icon, otherwise the icon will be
                     // "gray"
                     if ( a->style().color().isValid() )
-                        colorizeImage( scaledImage, a->style().color(), opacity );
+                        GuiUtils::colorizeImage( scaledImage, a->style().color(), opacity );
                     pixmap = QPixmap::fromImage( scaledImage );
 
                 // draw the mangled image to painter
@@ -847,39 +847,6 @@ void PagePainter::changeImageAlpha( QImage & image, unsigned int destAlpha )
     }
 }
 
-void PagePainter::colorizeImage( QImage & grayImage, const QColor & color,
-    unsigned int destAlpha )
-{
-    // iterate over all pixels changing the alpha component value
-    unsigned int * data = (unsigned int *)grayImage.bits();
-    unsigned int pixels = grayImage.width() * grayImage.height();
-    int red = color.red(),
-        green = color.green(),
-        blue = color.blue();
-
-    int source, sourceSat, sourceAlpha;
-    for( register unsigned int i = 0; i < pixels; ++i )
-    {   // optimize this loop keeping byte order into account
-        source = data[i];
-        sourceSat = qRed( source );
-        int newR = qt_div_255( sourceSat * red ),
-            newG = qt_div_255( sourceSat * green ),
-            newB = qt_div_255( sourceSat * blue );
-        if ( (sourceAlpha = qAlpha( source )) == 255 )
-        {
-            // use destAlpha
-            data[i] = qRgba( newR, newG, newB, destAlpha );
-        }
-        else
-        {
-            // use destAlpha * sourceAlpha product
-            if ( destAlpha < 255 )
-                sourceAlpha = qt_div_255( destAlpha * sourceAlpha );
-            data[i] = qRgba( newR, newG, newB, sourceAlpha );
-        }
-    }
-}
-
 void PagePainter::drawShapeOnImage(
     QImage & image,
     const NormalizedPath & normPath,
diff --git a/ui/pagepainter.h b/ui/pagepainter.h
index 42a7313..830c9fe 100644
--- a/ui/pagepainter.h
+++ b/ui/pagepainter.h
@@ -63,10 +63,6 @@ class PagePainter
         // set the alpha component of the image to a given value
         static void changeImageAlpha( QImage & image, unsigned int alpha );
 
-        // colorize a gray image to the given color
-        static void colorizeImage( QImage & image, const QColor & color,
-            unsigned int alpha = 255 );
-
         // my pretty dear raster function
         typedef QList< Okular::NormalizedPoint > NormalizedPath;
         enum RasterOperation { Normal, Multiply };
diff --git a/ui/pageviewannotator.cpp b/ui/pageviewannotator.cpp
index ea2a8a6..793eb77 100644
--- a/ui/pageviewannotator.cpp
+++ b/ui/pageviewannotator.cpp
@@ -36,6 +36,7 @@
 #include "core/annotations.h"
 #include "settings.h"
 #include "annotationtools.h"
+#include "guiutils.h"
 #include "pageview.h"
 
 /** @short PickPointEngine */
@@ -940,20 +941,13 @@ void PageViewAnnotator::detachAnnotation()
 QPixmap PageViewAnnotator::makeToolPixmap( const QDomElement &toolElement )
 {
     QPixmap pixmap(32, 32);
-    QString iconName;
-
     const QString annotType = toolElement.attribute( "type" );
 
-    if ( annotType == "note-linked" )
-        iconName = "tool-note-okular";
-    else if ( annotType == "note-inline" )
-        iconName = "tool-note-inline-okular";
-    else if ( annotType == "ink" )
-        iconName = "tool-ink-okular";
-    else if ( annotType == "highlight" )
-        iconName = "tool-highlighter-okular";
-    else if ( annotType == "stamp" )
-        iconName = "tool-stamp-okular";
+    if ( annotType == "stamp" )
+    {
+        // Load static image file
+        pixmap.load( KStandardDirs::locate("data", "okular/pics/tool-stamp-okular.png" ) );
+    }
     else
     {
         // Load base pixmap. We'll draw on top of it
@@ -977,6 +971,38 @@ QPixmap PageViewAnnotator::makeToolPixmap( const QDomElement &toolElement )
             p.setPen( QPen( engineColor, 2 ) );
             p.drawEllipse( 2, 7, 21, 14 );
         }
+        else if ( annotType == "highlight" )
+        {
+            QImage overlay( KStandardDirs::locate("data", "okular/pics/tool-highlighter-okular-colorizable.png" ) );
+            QImage coloredOverlay = overlay;
+            GuiUtils::colorizeImage( coloredOverlay, engineColor );
+
+            p.drawImage( QPoint(0,0), coloredOverlay ); // Trail
+            p.drawImage( QPoint(0,-32), overlay ); // Shadow (uncolorized)
+            p.drawImage( QPoint(0,-64), coloredOverlay ); // Pen
+        }
+        else if ( annotType == "ink" )
+        {
+            QImage overlay( KStandardDirs::locate("data", "okular/pics/tool-ink-okular-colorizable.png" ) );
+            QImage coloredOverlay = overlay;
+            GuiUtils::colorizeImage( coloredOverlay, engineColor );
+
+            p.drawImage( QPoint(0,0), coloredOverlay ); // Trail
+            p.drawImage( QPoint(0,-32), overlay ); // Shadow (uncolorized)
+            p.drawImage( QPoint(0,-64), coloredOverlay ); // Pen
+        }
+        else if ( annotType == "note-inline" )
+        {
+            QImage overlay( KStandardDirs::locate("data", "okular/pics/tool-note-inline-okular-colorizable.png" ) );
+            GuiUtils::colorizeImage( overlay, engineColor );
+            p.drawImage( QPoint(0,0), overlay );
+        }
+        else if ( annotType == "note-linked" )
+        {
+            QImage overlay( KStandardDirs::locate("data", "okular/pics/tool-note-okular-colorizable.png" ) );
+            GuiUtils::colorizeImage( overlay, engineColor );
+            p.drawImage( QPoint(0,0), overlay );
+        }
         else if ( annotType == "polygon" )
         {
             QPainterPath path;
@@ -1034,13 +1060,6 @@ QPixmap PageViewAnnotator::makeToolPixmap( const QDomElement &toolElement )
         }
     }
 
-    if ( !iconName.isEmpty() )
-    {
-        // Load static image file
-        const QString fileName = "okular/pics/" + iconName + ".png";
-        pixmap.load( KStandardDirs::locate("data", fileName ) );
-    }
-
     return pixmap;
 }
 
-- 
1.7.6.5


From dfcbc784b9bfc49e8b558f52b5d2106e1ee678bd Mon Sep 17 00:00:00 2001
From: Fabio D'Urso <fabiodurso at hotmail.it>
Date: Tue, 12 Jun 2012 12:34:26 +0200
Subject: [PATCH 12/43] Removed unused PNG icons

Note: I'm only removing PNG files; source SVGs are still there
---
 ui/data/tool-ellipse-okular.png     |  Bin 1182 -> 0 bytes
 ui/data/tool-highlighter-okular.png |  Bin 1608 -> 0 bytes
 ui/data/tool-ink-okular.png         |  Bin 1789 -> 0 bytes
 ui/data/tool-line-okular.png        |  Bin 925 -> 0 bytes
 ui/data/tool-note-inline-okular.png |  Bin 876 -> 0 bytes
 ui/data/tool-note-okular.png        |  Bin 1053 -> 0 bytes
 ui/data/tool-polygon-okular.png     |  Bin 739 -> 0 bytes
 ui/data/tool-underline-okular.png   |  Bin 703 -> 0 bytes
 8 files changed, 0 insertions(+), 0 deletions(-)
 delete mode 100644 ui/data/tool-ellipse-okular.png
 delete mode 100644 ui/data/tool-highlighter-okular.png
 delete mode 100644 ui/data/tool-ink-okular.png
 delete mode 100644 ui/data/tool-line-okular.png
 delete mode 100644 ui/data/tool-note-inline-okular.png
 delete mode 100644 ui/data/tool-note-okular.png
 delete mode 100644 ui/data/tool-polygon-okular.png
 delete mode 100644 ui/data/tool-underline-okular.png

diff --git a/ui/data/tool-ellipse-okular.png b/ui/data/tool-ellipse-okular.png
deleted file mode 100644
index 6a3260ee673d14081703bacc2eff96fe0b2ba585..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 1182
zcmX}sc~BE~6bJAnfB_NF+G-K(0EJqlf^Ef80WC*B2CxWNV5Zhk6oyic5)KE8MbOEh
zL#-6G9CnZvq{tDZ9OWp)C}0JFa7Z9nt}G$hY&O?svq?7n at lQW9@4flGd4GQAR~mIX
z)OP#+?GOanhMfwI2GeP)tjs|V{{6-<80M_NuvjZAtHqVim%-CI>r?^@Z1c9ttZ=q?
z3 at q()81XqVnaMf%iP;yS{QP{+)QmJ%QexIc&&=$UYSeE(1koa*B4QaPlL_4a&)eHO
zC at 6@cC<qamAtD+gGDk!fh{zIww;?cnd4Vp2ZDjC{dA{xJ#7-H!OSZ9Fwz22M at E+O5
zo6mV~p&NVA4f~g)_NdsQzuOTNA3(*<sMxi+ at t_p;=<WPKzUjqj_QE7bFv-ys;ZaQD
zjY)hk>G8*HzW1yA719%!<TC{lfQW;oaD-A8qm(76&~qyEyh_e&Zeor+y`Yj`RLj%U
zSa#im9E~DZqsY at JE@>168buMVyoxJ}apg5!c^y}=aaAd<`Vr8oZfVuGfk#b0Yt_|+
zrlzLmS3*-;TU!SZ_-_D#*VorK0J!QQK;VsyjgNGAGa!arT3T8Gowlv5jl<!z13GO-
zN5`LlPTSep+11t6Etu~C76m;d at fSc6y#Pt{_4N$^B=I*u5`%+-TqX7dAay(*@7c3w
z!^6WPBO{}uqhrAM_?Vs?*OM=S#f1rg&!5m~C-mgh)D)l3pPrtcnVFfJn|lQq^z(p0
zFAxY878Zm;;nLF5YolS=XjoZUSp|%SHKSpDeO+WUz%aZ4C=_C`cyn`8Vl+ynQUpOz
z6vY6_s8A at BfWe@oD79Lxp(q at nC@n=107dC^I+7&yfXQS4OeP~>GJ&*EAVwyWvnX>C
zB*`i#`g9CrX728J-2ZuR1>yxkW}L9#fLNawNlYh;cnnGosio!l72UCJTt4#7P)NF^
zhlJ+;_2p02qBv8LRpvW<X4mWz56#1FT&{CN(h9Tb&=B{*?Xo6ja(MTLC)sDlabBM`
z<9NSU{M8cPzA)~pTMVnEV&)B2c^t!g-SzN^?=P`^>2ccvx!gZQd8;2$g#l%o--&L1
z{HnxN=wtEFDWN^?-n#{Su90mg|JROn-=4jvyqFQ_a(R+gTM^_C7GS})F0e|6*S at +L
zwQDHxYU^^*+at7JiqElau4$4TPxR~)7nRWM<V%$^?P!)S+eLVz?oP|0a{tTK1NkC#
z3M29#`7J>%!SP_*ei?8fw6eY?J0&nWDI)!cZ=$cn5l`IC_B&qBvOG+W%bZ+45?_E}
z4Uz0_`T5*Sn!A2yc81RM#Jf&7i#lv2L%KOX#|HMKOInpPo!wj+{w<?+pcJCF$-Wp9
zd(N#E(L7ax_ooKB3pB5J2UJ~-88)nAv)x!kWyxJ;^0k*u>Dv?HeG9V-$;S&JW3Kmp
zI(v at 4yW>6ggX3+3kN1XG2~Q^KpAK{!i}dfgf+}YhQ)`gadI)ka)j33!eVVxSGlVft
K2e$??i~j?j=e%bC

diff --git a/ui/data/tool-highlighter-okular.png b/ui/data/tool-highlighter-okular.png
deleted file mode 100644
index 594ba418384cfadfc14355bae0bba06a06a29eda..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 1608
zcmV-O2DkZ%P)<h;3K|Lk000e1NJLTq001BW001Be1^@s6b9#F800004b3#c}2nYxW
zd<bNS00009a7bBm000Aa000Aa0e#hi%m4rY8FWQhbW?9;ba!ELWdL_~cP?peYja~^
zaAhuUa%Y?FJQ at H11;t53K~#9!?Un0qlVupjF(xQMqZm;RMLBHUsT(>OhbbzeBH#(|
zgi(X~2Phx-pcs_s2V)FT)QC|NGIc{81I7*<<hXTPH`ealZCzK`T-zP!pzXHy-P``W
zdCHcUMcq{Ji*IseZ{Mu_UDy5GS33##Pj%@^yUI!uT{CJR8jV`6mLid%%8ZPROfhin
zr~$6Rr4NT`IkcYsnpK?qa_*V;)=r&qwG1eDbJ1EjyBzvH07n81**DrYFPk*wiW?Z#
zLbMdE0p}9%z9A-7qBqVUT(>N`f9oxuDFas$-dwmETn|FeHfX;Wz3C3LrWFLslG(R;
za`qK7FdQDjUT_JX0o`xGxkm(UK(jw4 at I-2MO>2B_^(4b(17Tno(1GYbhWC4%cuUfu
z>NfDa39d|m-$}UnVS%S$*?E&|%R`gy99_Z?vk}qMW~BU#iR!v!E{5jP=Z_=AJOWxg
z{eubeERhgN1cyxw>S_3b>4do#jg1Vml?asz?kQO&(B;teI#k?@-Y^HP<w*w0O*HRW
z$_tO0*8i at CXWem}^DLmgIg$LLMO4+KaIkn0MMu(c_s!!#VFo|tEtdQFWMyY^(!5Zf
zE#k+$OXzSvht3Ysx19In;VBjPx%;7WJ+vjD*G(m2zL}ueh&?+4e_t0XSFT+CI|D<}
z*$RI6SUOohWYXB0DAPz(fa=<0zWU}qPL-vx_rPMl-?L2ppO|Lf!3>$w5;R`H=ds`|
zT`KSgq3cy}2)y=s!ZsrV78BhEWs>LJ0AmektVd%VL;5-n|FQv%r{(@>>YCOOjy^>w
z@)R0RB9i+{dIF6Ry-1&DlO#_9mn8r7d1y<K<ku6bi6c<90B><BuIhY%F$Tu8!0Yu+
zc;VF8T`L5>5gc)nd<voJID!?4c#BeTR_zBEmw}0IyTDa)_a<mJ#o$(fm&MUtyl at 2m
z=LRB_5urk45mkw*iDDDgit0s;BD<(X)GF!{cv~#_*$1Fw12~K__9=4a0xyrpQ<N<5
zeE@%LAgIkzHMBbuaCOC9Uc?0TY$$4AKsPWLF)&hBuX_d_^DJ-)-2EEJ!U|l*9xw0&
zx)0qo0w14&!o&B_)jOYx>J(0y)2Op2AyB1~ic~({v4VhRP<1RhX~cPGo+Q6iwPysL
z97|qnj4fPI3T>5n0OL0xiLqEs6dz3|FMlzmmQ;en2KB|XCwD1QM^(e!UrYUt8e$9A
z^)fi(FONMzk|*LRHjRNtqfvBSClZPLu>s4OEojmA>G5qN9NA89|2Br%F3+~(^S>j1
z-<7JpA!lxkCGUC(oTk{=1s*Uj5O}J<_l`nBp%8&U0KebQ;NT#drYSRjrv+-^ddf0l
zziPie8%tg*$*soN!WASTaFz1Hg$sB*9#!YQzCQIj7z`>yGKs%upsiTIXGaz;Wi)xv
z9Iw7)?4>yh>Toz{Z*QlgqXW0wO;1k`KA&&Q6eet-dCy|>rgU)37r06;W1o-vU;-rv
zKF4OWQD0w=-ELPVTrL-#ot?^5Z*Q+M at TW&0qv6Df6Uyz#n5<T-N at 6?w0KVf>xp;g!
zq4LRutg)(f=Fg?@yT>WFyhBy>C)jGUX=p5^rKJU@(}}!SeO@>m{_7UBwziU$m8ITz
z`t)ha%gfoldpGu)GCap_M0c!Ws3sF%;S??&yM at lYX?*_vOuqa&PHH+GbJZ*=ZAn<`
z at 21tco&NrQwGZR2VQy|N1qB6a3P+9{QR#DXa_|rApsmqBsC6y=s(bkU?OVzE at OE~7
zG><QK85O*=Vht6QpVIC!t7RK=jmLnvMb1!dYC}VVItH1BRB#hD_8T}=cpdpWr;)pV
z4*A8iDLOifV<j^<Q+FF3-kA*Ovk8-m&MqRHp16TOtY6?=Y8un9xBQH~IiJR+ebm+O
zrOjD at KVTM^l_<@kZa`xk*F<Zm%UK5am#+!e at P7kW+`w<T^zV~9Zt?#B0000<MNUMn
GLSTY2nDlc1

diff --git a/ui/data/tool-ink-okular.png b/ui/data/tool-ink-okular.png
deleted file mode 100644
index 8a2eeb0f8df6efb56329520a844839858ecda400..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 1789
zcmV<Z1_JqsP)<h;3K|Lk000e1NJLTq001BW001Be1^@s6b9#F800004b3#c}2nYxW
zd<bNS00009a7bBm000Aa000Aa0e#hi%m4rY8FWQhbW?9;ba!ELWdL_~cP?peYja~^
zaAhuUa%Y?FJQ at H126{<EK~#9!?Urj$ROcPW?et4O^h2jJndwa0X`93(?Kp->MwCUP
zktB{GwL%)=Jw^~xgG!8unt}*MrL;~BNSh`kNV35QLIuRI?7FZa+=3V`a#>iE%W~U=
zU0{)g-R0N!ykmFF)E$j8+An=)p4qc!_q@;Zf6nv&pED2mpF&v+A25C+ at B^=axw*O8
z2L-ohrf$)qMJgfShh70ZfaP>K*>hzJ at jYRzDtYSiLx~Ul>_G{T<k9u(IbvIb!F8M%
ztBPkUA8DMI_^Th?cL6i*8FpRSK>XM$3Z~;YZVzEg{{murf;|he=bw}U?kD-qE9*IG
zUxRiwiA38=gqxoxp+AI(=4Jfi9}la)mjDm5Ok-o5K1OJzpIW-n(oO-5Wb+LfwD1LP
zoYHndE-HVKi!%wNjQ>H9`*CbAjO|U!3CMr4ZC>I}e=Y?~GQbE|Z*Higo%1xKrh!cA
zI7Kxl_==+#IN}qXT*SdJ0KMaVylH%aCpuN+-q<TE-)??}q=8T(o0sE%=85a`Vt?{W
zZwUXhNp9CcPS@{4-4ut;nS^HIuspAyO-6g;uskQfyOJq)CsXE-zf07SMlY2#j#sd&
zGni!C at Az~on#VgA^G3fPsUw?+YFWX$vS1dhdnWWdZCE%EPtjmJU$h?}tt5uezKtXO
zVhkCYx4B?F#QPUwIFY}T5^<dJc{G_{?<Gx~`|G)#h-<wf&W*<rVGQ6sk at i!Qn`PQx
z?VZnKZA;kNw2Uy#YRnUZ1O){x`;Gv^+<WA<C-8x8FDdG1&KeJr*Y&O>P&e);>7zHv
zsyaaW`8fV|W<S}wqf`!L at kvoCS0_s7qndjAm+a_#K?LsiWKZp2w;&Jgd4woaAW^L=
z_-$Pv1Cv7l|1F at I&l$yt%RP%$s|Aq9Ev-$s=A3vuZoEPCcqDFJJ@#I93fqqe+y6Pa
zjlI at qdFA@AiR=nwQ)2)dDppd``6a+ at 1$Z-1$#L{U>2y#;A5~arMG2^jX?!h7ZVVQc
zujNBWIJ+!MWaZmUD#BZqvR;rEcU%CtgMd4ric}i-h*r)?advtz*-b=uzAOT_hSO7j
zB-Xl|5QSV+{(6&&jbA<QCBH`jzL9H>C0q%dxaS#@Ti9(;N!vx`B5(nOl|M&OM=`*i
z1=P=GQpqv$Oz(2u9M5s}TS^cmQN`R5*>V-0WH0$yn?kNq$YrbTu?9-pBTY-$*1S|y
zzS0M|4*{j6rC2P(R9 at C_;cGSewj5gB1$^s1jk+e0gC`=<&nC%se81)`HeK;o0w*fp
z$~)F&vhoO#_RS)2q2>Ohw7)?oCCo5!cLLOEH4P07l$DiHSXfAHZ7nXBi>|IN^78V?
zJC}>Ds+eP+#tVB at veiCzM2Wx!@Jf%8b`=pKaG`pC5^6SjovPs^Q&<r10TRA%L4Cda
z!`RrEY%!b71|ZK(OiaknYqsm`=y*w1F33gTRuC%4mB4Lo5<)5#liajL&JQ^)-AP=U
z5tDKz6}zin?(0(kcUaxFYwR$tlC36emz7I$Qvh3=RU&XJ#30L|drn7%GnG<D0vds`
z8;8(26EV!DV0ZV)LheaGL_>%eugZjrMh+Qid!QuWXb2*|^<Ov~4(Z^SZ4}dZ9hH-(
z&`cddJDrG5IC0tav2@{{1cYgViRpilXp29x)w)!|_9eWkUyiyyhoPY%Mn*=kTCGxq
z-EPM=VWrZMrnn#ll#4EM<Gj59x7&?gua_4q$AAoFZ*MOj)PKmDdOz0IJ<ap2j}p-p
zz%~)M*93WH)hC$EW(Efb86F<SVzDqfIw~?WhGo1T!}MP$zomWM%-mjp(P$()I~$Y9
zgu!5-y1JUItSqYAY6$seA&1Qy*we9=mHPRtu6>HtrG7+ahmldZAFcT$mj==(AId;K
zl8(;yXLQp^a()=_f;!TDhfry?;^JcIf<~i})#v2o&@gpE5I at S%{>?;R4QBD*7xLPf
zAoi)(lbRnzzImTS!9W}(_CIlH_OQ>%*-wpc0ZKTUo11YuowT&HD7Qhnp`8jRy6wlj
ztbdqw#m|vhx0~$7xB0B~9dfV5QaExzNxP_4+UyhEXaT-|8`exGlW6p#z!FQb^&mw8
z3TcT=R6FCdTJMwfDra#p1aNNx=9JueCgmnJt_xhdiEhRuOgGVW3rzCea1PJiKMS}&
f>;D4oTEM>nbwi6&g}8fx00000NkvXXu0mjffJ9J+

diff --git a/ui/data/tool-line-okular.png b/ui/data/tool-line-okular.png
deleted file mode 100644
index a2dda948374aefac6189ba2a623cbb5b12ac5a40..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 925
zcmV;O17iG%P)<h;3K|Lk000e1NJLTq001BW001Be0{{R3M5Kzw00003b3#c}2nYz<
z;ZNWI000SaNLh0L00VXa00VXbebs`@0000PbVXQnQ*UN;cVTj60C#tHE@^ISb7Ns}
zWiD at WXPfRk8UO$RyiiP3MgRZ*000000000000000H8nLuLqq=l{*I20k&%&{oSdML
zKBA(cqobpxrKP5%m!_tsr<FCQq?o6tr>Ll?tgNi9t*x%EuCK4Ju&}VPv9YqUva_?Z
zw4XM#w6wLbnzgmHwzjsnx3{>sxVgExx}z?-y1Ki&yS%)-y}iA at zP`V^qrbnu!m2aE
zzNNy#!o$PE#l^+O!KcQ?#>cHH$jHda$;r&MK+Md{&CSiuvM0{8F3!%*&(F`$(9qG*
z(bBag(z-v=&b!jm($mhh)U_7Y*4Ee8*Vw^J*x1<F+1c9K+T6lE+}zyV#Y)}X-Qmbd
z;=?KA;K}6V<mKh%=H}+-=jZ6?=;_Z%>+9?6?CkE-N$&3M at 9*#M at bK~R@$%F<^43W5
z^78c2BJ|Zc^w>!B at 7DI$IQH?__V)Jp)FSxUIQZL0`1ttw`T6?VIQshf``bAC`}_Rc
zF8tg${QUg={r&#e6aLvC{@_Rc_R#+R{{Phg|JV}$*c1QQ6#v;9|Jon_-ZlT;H~-%{
z|KUgf;Yk1JcK_;q|L~>%^0NQ;&j0t%|M$@U_tF3O(*O9@|N7tm{OkY!|98)cG5`Po
z2y{|TQvd-2DK0ua$-0#6F8}}mKS at MER5;6HU?2oo at Bn5;paOP0fRzcTU@{)SHfR)d
zwPAp!3CIdMeas!R6PokWvzrS`Qkt8a8)_OSAt?wA^Hj7`Qj1a$j}kCc5DT5$UE4Sj
z*@|jUO+Ig5F?%j!DG|+3nIt56m?KLyCYQQZmrb5r2E at qna9@NY+}(pLkHwp)@|X&G
z>QLk%3JNCshwyn%t}ZQ`+*@8Tu{2N2CLTqBN~EQsdugdDM}fS9EWewwvv2{b34Au{
z(q=`zqGCpZx=s>e%C@}0VJHeLs$<GxCs!v`)g`A*&Mk|Y9Fysb&5?a*?n775SC2&=
zNdb0wh=Nj`n9_c$zzm$}!JEfl&xAWj-^<-VDqP<fQ-P?QwyL#IoS1?nr?Zwm78A-`
zvRsS(QavgY10texTEU<L#gV-&&FG+gkmU;ic?g at 7-<cNA00000NkvXXu0mjfNrL?;

diff --git a/ui/data/tool-note-inline-okular.png b/ui/data/tool-note-inline-okular.png
deleted file mode 100644
index 4d8187f5f42e44304b93f69ce0b2e2934520ae8e..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 876
zcmV-y1C#uTP)<h;3K|Lk000e1NJLTq001BW001Be0{{R3M5Kzw00003b3#c}2nYz<
z;ZNWI000SaNLh0L00VXa00VXbebs`@0000PbVXQnQ*UN;cVTj60C#tHE@^ISb7Ns}
zWiD at WXPfRk8UO$Ro={9wMgRZ*000000000000000H8nLuLqq=l{*I20k&%&|m0qBr
zprV;!qMBi%qN1atqokZ;rKP2&rlzN!WT&5Gr>Cc at qi3wFtgWPIt*x!EudlGMu(7eR
zva+(Yt8BEiw6&{jwY9aku5P%vxVf)yxw*Nzy1KiuaJ##^zO-__wQ|0`zQ4b}!L541
zw{*h7!o$PE#k+RJ#l^<5f5yCb#>U3Sy?4jQ$H>UY$-jBY$;ryVdCa$l%)xrh!h6ij
z%+0xm&AE}y&CSlbhtAH<&%}Js&(G4we$vv?)6>(`$$!+;)YitS*4Eb7!-?0#ir3fI
z*v*01*x1?G+1k&8+S=OO&$!&&+}+*X-_(ZT;o;)f#p2 at P<JXAf<mBbqiRI<x=H}+-
z+l%Mt=jhyv=;-L_-Hhq!>Few3?BI^<?CkB~j_&U6 at 9*#M<B;(1 at bTr5@$vEU<&pB{
zk at E8L^yiZF=#%vH^!4eJ_UV-N_V)Mcl=%4g`RtYX`T6?omiqeo`|g(e at 0a`g`~2^h
z{QUg={r&#_{{Qls|NsAGi9Bxr000PdQchC<0Rt&6Iz7p{l<Y4600AsXL_t(I%VS_5
z1X%C at W=5a_c07QU38<hG4`8F0f-oCwzz3ngxdR*UM^RwcQD58AQqkCvRM}D1(gb86
zDM&O1DhN?fQqdFO$#fSM(X`X!;;lzg(5~CjVQ6jQs%~ee7wfJiCt<5%rdNt)g=KtT
zL3T=BW_5vBkym6|c4iZ at 0taNb6~h>Q2nErO*gzQZ0oBkMksuh_+1}dL+1cLS*;*&*
zQi!5JHN(j$ptaS4qe0O_UdUJ3L$m?a1VI-KS*zx7aY<8AeGe%~WjFq~WE2JV?Ky3^
zo$V#<o#o}7HEmg)IaT5GP7kd*Ijx;8F;zGfgz`n`n{&tM2L~9)r0SbuDiD{~QF9T^
zmsFJI^w8GFVnUl|jdyEAc~E;vRC-R$03~}$6#xL(g?Pp5l5<!90000<MNUMnLSTZ&
CZ0JD%

diff --git a/ui/data/tool-note-okular.png b/ui/data/tool-note-okular.png
deleted file mode 100644
index a89c91b90c4c7ba65217d9e308a41553ac3eaa68..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 1053
zcmV+&1mgRNP)<h;3K|Lk000e1NJLTq001BW001Be0{{R3M5Kzw00003b3#c}2nYz<
z;ZNWI000SaNLh0L00VXa00VXbebs`@0000PbVXQnQ*UN;cVTj60C#tHE@^ISb7Ns}
zWiD at WXPfRk8UO$R-B3(aMgRZ*000000000000000mTMF>H8n#+L!NpusDK=%ejJl?
zCAF1F%duk2vSQ7tGSjas)2}Q3{{F$KUyhEBk&%&{oSdMbprWFprKP2&rlzN-r>Ll?
zsi0-7tgNlAt*)-Fu&}VPv9YqLYqGMkw6wIfwY9dkwzsZsx3{;suy47!xw^W#yRmS)
zySu!yalE{|y|Zz>y}iD)a=yO4zqNC}zrVn?bHTTC!nkz8!otJ3b;HBM#JYCHvv$S1
zcE!cT#>U3Sy?4jQ$H=vK$i8^U$jHgJdda_e%D{Qc!FtTXdd$qs&AN`w!+Xum&Cbrw
z&%}Jt#eLAw(9y<y(b3V;$9~e%($mO))6>(`$$!+;)YZd=*2{p_*4Ed=me<$U*v*32
z*x1>}i`mYC+1c6J$BWv}gWB5K+sKUD$&B03gWSoC+|h*G+}z#Lh27oV-qVHO)P~^I
zhT+zS;o;%p)w<%=h~nbn<JXAf*ooxi<mKh%=Guzp=H}<yi|6O(=;-L_&R6N_>FeK(
z>+9?6%|q<$?C#G-?(XjI at 9*&Bknr&E^78WY=aTgF^!E1l`0JJU`1tzmmiqeo`}_O+
z{QUj!nEn0z{_&Xp{{H{f0RP-3|MHpt|No;>p^N|k02FjmPE!B at 11T;wIz4oDc$cWW
zyu8E2$;{+%G4KEY0g_2XK~#9!&C=IS0znjjVeGwEY*?|2ii%>z%32UC3l=O`z=l|{
zcSTf05Z7gO&a=7%jV>E8#vA{+n|#TcNe<`7{JrGoLxWf^1^UteycG0%usz8rEHos5
z39eo|i(!Im7KmnovscfeXrS*^+AZLCu*1^=@+_QlbfU>0EG#kcGfgQiUFgDnfBy+6
zO(j>S=M5)HvePQZ5q^jZi*lrE9Rh4O9d`i$q8x|`iUc6ZWu#E!(`wnQv3jUk)o64B
zIE9av5xS)hJz@{hJ=)v=z5ullugBIaR0^4}P9)f4gC!~6(`_47tn{=RG3_x89AG%$
z>VP6h0BRAv=X`cL-+xhj+21ln5S{T3zA~=~t!cGV#pbkZ0Ml+Pjk*9=UY6VWq|e|<
zQpL)4q{8ZIb4o?30#SX1VATbBDKmKkl!XGT73PsgtVjMC^vy7ei--*75H)53<U0 at F
zuADB}AZ|<AZ<w2E$UYTI*dQaXrbM24$Kz)uD67Q42IPo+j4)U=lx6GOZ2xiX|0j3@
Xhv&`)k`JVb00000NkvXXu0mjf$2mi+

diff --git a/ui/data/tool-polygon-okular.png b/ui/data/tool-polygon-okular.png
deleted file mode 100644
index 66ba2cb21e1b54e8cf0c31739da92f2d305f7bd4..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 739
zcmV<90v!E`P)<h;3K|Lk000e1NJLTq001BW001Be0{{R3M5Kzw00003b3#c}2nYz<
z;ZNWI000SaNLh0L00VXa00VXbebs`@0000PbVXQnQ*UN;cVTj60C#tHE@^ISb7Ns}
zWiD at WXPfRk8UO$RBT!6KMgRZ*000000000000000H8nLuLqq=l{s3352VAfYV6qQk
zvnX-9EOfjtcD;^{j**d(oSdAXprE3nqNAgurKP2&rlzN-r>Ll?tgNi9t*x%EuCK4J
zu&}VPv9YqUva_?Zw6wIfwY9dkwzs#pxVX5vxw*Q!y1To(yu7@<y}iD^zQ4b}!otGC
z!^6eJ#m2_Q$H&LW$jHgb$;`~m&CSiu&d$%z&(P4&(b3V;($dq@)6~?|*4Eb7*VowC
z*xA|H+S=OO+}z#W-QnTk;^N}u<mBb$<>uz*=jZ3>=;-O`>Few3?Ck9B?(XmJ at 9*^b
z at bK{Q@$vHV^7Qod_V)Jo`uzC#`1tz$`T6<!`uh9(`~3X;{Qds@{r&#_{{R2~2&%RK
z00008bW%=J009FjE;>EQx|HlM0003VNkl<Zc-qa<TT_BS6u|NB7qPMnl3Q6)W|<_F
zQBjIO8d?wqgyFV(zW=AlCub0Xo|^v8zd3u(%ub~?m(c9=2rMQvKQjW5(83>qrD&@u
z6KrMzXbstSAn<$`VmAtmo^p75R5AG-GhgSC5dl=GvZ{ve*2Us>)i`isp1`Moo0I?$
z62AlVCzj0EwmnF=VvuE+Og04KP91{)^e0vYiU|OvfIpG+9s<WN*Yy_0mumqpm-5ZB
z%mv{ItaP$}HPi}7<OF#am2bAXy%1<ni at XALD7Y^8#01OJLSQ+*l`;5;@9X#f0oN=H
zQpfudsGGWQvC$RUt at C1E5Tl?_s#PTJ4e@(9`AmQ)Aou<Q)?I}<kI$B$`f2|s_y&?;
V1nq1*fwKSr002ovPDHLkV1f-#i>v?u

diff --git a/ui/data/tool-underline-okular.png b/ui/data/tool-underline-okular.png
deleted file mode 100644
index 924772f567373a9e15f3ee894ce3aa59886e6de3..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 703
zcmV;w0zmzVP)<h;3K|Lk000e1NJLTq001BW001Be0{{R3M5Kzw00003b3#c}2nYz<
z;ZNWI000SaNLh0L00VXa00VXbebs`@0000PbVXQnQ*UN;cVTj60C#tHE@^ISb7Ns}
zWiD at WXPfRk8UO$RAW%$HMgRZ*000000000000000H8nLuLqq=l{zgVdOiWBrP*7M{
zSXo(FT3T9LTU%UQTwY#YUteE}ii(boj**d(oSdAXprE3nqNAgurKP2&rlzN-r>Ll?
zs;a82tgNlAt*)-FudlDLu&}YQv9hwVv$M0bw6wLgwYIjlx3{;rxVX8wxw^W#ySux+
zy}iD^zQ4b}!otGC!^6eJ#m2_Q$H&LW$jHgb$;`~m&CSiu&d$%z&(P4&(b3V;($dq@
z)6~?|*4Eb7*VowC*xA|H+S=OO+}z#W-QnTk;^N}u<mBb$<>uz*=jZ3>=;-O`>Few3
z?Ck9B?(XpL at bU5S^78WZ^z`=j_W1bt`T6<!`uh9(`~3X;{r&y^{{H{}{|317_5c6?
z2y{|TQvd-2DK0ua$-0#6F8}}l{YgYYR5;6HU?2oo at Bn5;paOP0fRzcTARZ538$t@)
zEbJme<D<eO;-h22FctXtI&0Wy>IAAQ1WFmJ%llv`h;!DHbaj)r6*W<o(eqIa#k4|F
zfJ0D#OHe>iPymPpWwAKYkH+4Nig)*xbd8UTiH(nsi;Itml(z~&QJ@`QY3vjeV<sG>
zZl@;YsAVS|g=&JNm9C0;w40o~iL{}eqP&*1gqJUh0!~350Ujp>UO_=VK0$r~Zb2S?
zA$rGVj6qOLyp?A-P6e*w?uMpfUWP7CM#_GMCYTE3)C_d2q=V(vl|=0H4Y8OIYaihd
l;~wT57wX|36fs1TJpkrM5W;_%1iJtL002ovPDHLkV1i-TXi at +G

-- 
1.7.6.5


From 48ee2a4671247c921858881fac03def1dbaa86e2 Mon Sep 17 00:00:00 2001
From: Fabio D'Urso <fabiodurso at hotmail.it>
Date: Thu, 26 Jul 2012 19:16:13 +0200
Subject: [PATCH 13/43] Annotation properties dialog: Moved color and opacity
 fields from the dialog to the config widget itself

This patch moves the Color and Opacity fields into the AnnotationWidget
class. This will allow future reuse of the same widget to configure
annotation tools.
Note that AnnotationWidget is no longer abstract: a base
AnnotationWidget object only contains the Color and Opacity fields.
---
 ui/annotationpropertiesdialog.cpp |   55 +++++-------------------------
 ui/annotationpropertiesdialog.h   |    4 --
 ui/annotationwidgets.cpp          |   68 ++++++++++++++++++++++++++++++++----
 ui/annotationwidgets.h            |   14 +++++---
 4 files changed, 78 insertions(+), 63 deletions(-)

diff --git a/ui/annotationpropertiesdialog.cpp b/ui/annotationpropertiesdialog.cpp
index 4b02258..c0bca4a 100644
--- a/ui/annotationpropertiesdialog.cpp
+++ b/ui/annotationpropertiesdialog.cpp
@@ -15,11 +15,9 @@
 #include <qlabel.h>
 #include <qheaderview.h>
 #include <qtextedit.h>
-#include <kcolorbutton.h>
 #include <kicon.h>
 #include <klineedit.h>
 #include <klocale.h>
-#include <knuminput.h>
 #include <kglobal.h>
 
 // local includes
@@ -54,43 +52,16 @@ AnnotsPropertiesDialog::AnnotsPropertiesDialog( QWidget *parent, Okular::Documen
     QLabel* tmplabel;
   //1. Appearance
     //BEGIN tab1
-    QFrame *page = new QFrame( this );
-    addPage( page, i18n( "&Appearance" ) );
-    QGridLayout * gridlayout = new QGridLayout( page );
-
-    tmplabel = new QLabel( i18n( "&Color:" ), page );
-    gridlayout->addWidget( tmplabel, 0, 0, Qt::AlignRight );
-    colorBn = new KColorButton( page );
-    colorBn->setColor( ann->style().color() );
-    colorBn->setEnabled( canEditAnnotations );
-    tmplabel->setBuddy( colorBn );
-    gridlayout->addWidget( colorBn, 0, 1 );
-
-    tmplabel = new QLabel( i18n( "&Opacity:" ), page );
-    gridlayout->addWidget( tmplabel, 1, 0, Qt::AlignRight );
-    m_opacity = new KIntNumInput( page );
-    m_opacity->setRange( 0, 100 );
-    m_opacity->setValue( (int)( ann->style().opacity() * 100 ) );
-    m_opacity->setSuffix( i18nc( "Suffix for the opacity level, eg '80 %'", " %" ) );
-    m_opacity->setEnabled( canEditAnnotations );
-    tmplabel->setBuddy( m_opacity );
-    gridlayout->addWidget( m_opacity, 1, 1 );
-
-    QWidget * configWidget = 0;
-    if ( m_annotWidget && ( configWidget = m_annotWidget->styleWidget() ) )
-    {
-        gridlayout->addWidget( configWidget, 2, 0, 1, 2 );
-        configWidget->setEnabled( canEditAnnotations );
-    }
-
-    gridlayout->addItem( new QSpacerItem( 5, 5, QSizePolicy::Fixed, QSizePolicy::MinimumExpanding ), 3, 0 );
+    QWidget *appearanceWidget = m_annotWidget->appearanceWidget();
+    appearanceWidget->setEnabled( canEditAnnotations );
+    addPage( appearanceWidget, i18n( "&Appearance" ) );
     //END tab1
     
     //BEGIN tab 2
-    page = new QFrame( this );
+    QFrame* page = new QFrame( this );
     addPage( page, i18n( "&General" ) );
 //    m_tabitem[1]->setIcon( KIcon( "fonts" ) );
-    gridlayout = new QGridLayout( page );
+    QGridLayout* gridlayout = new QGridLayout( page );
     tmplabel = new QLabel( i18n( "&Author:" ), page );
     AuthorEdit = new KLineEdit( ann->author(), page );
     AuthorEdit->setEnabled( canEditAnnotations );
@@ -111,20 +82,15 @@ AnnotsPropertiesDialog::AnnotsPropertiesDialog( QWidget *parent, Okular::Documen
     gridlayout->addItem( new QSpacerItem( 5, 5, QSizePolicy::Fixed, QSizePolicy::MinimumExpanding ), 3, 0 );
     //END tab 2
 
-    QWidget * extraWidget = 0;
-    if ( m_annotWidget && ( extraWidget = m_annotWidget->extraWidget() ) )
+    QWidget * extraWidget = m_annotWidget->extraWidget();
+    if ( extraWidget )
     {
         addPage( extraWidget, extraWidget->windowTitle() );
     }
 
     //BEGIN connections
-    connect( colorBn, SIGNAL(changed(QColor)), this, SLOT(setModified()) );
-    connect( m_opacity, SIGNAL(valueChanged(int)), this, SLOT(setModified()) );
     connect( AuthorEdit, SIGNAL(textChanged(QString)), this, SLOT(setModified()) );
-    if ( m_annotWidget )
-    {
-        connect( m_annotWidget, SIGNAL(dataChanged()), this, SLOT(setModified()) );
-    }
+    connect( m_annotWidget, SIGNAL(dataChanged()), this, SLOT(setModified()) );
     //END
 
 #if 0
@@ -200,11 +166,8 @@ void AnnotsPropertiesDialog::slotapply()
 
     m_annot->setAuthor( AuthorEdit->text() );
     m_annot->setModificationDate( QDateTime::currentDateTime() );
-    m_annot->style().setColor( colorBn->color() );
-    m_annot->style().setOpacity( (double)m_opacity->value() / 100.0 );
 
-    if ( m_annotWidget )
-        m_annotWidget->applyChanges();
+    m_annotWidget->applyChanges();
 
     m_document->modifyPageAnnotation( m_page, m_annot );
 
diff --git a/ui/annotationpropertiesdialog.h b/ui/annotationpropertiesdialog.h
index d1a1c27..3e12104 100644
--- a/ui/annotationpropertiesdialog.h
+++ b/ui/annotationpropertiesdialog.h
@@ -14,8 +14,6 @@
 
 class QLabel;
 class QLineEdit;
-class KColorButton;
-class KIntNumInput;
 class AnnotationWidget;
 
 namespace Okular {
@@ -37,8 +35,6 @@ private:
     Okular::Annotation* m_annot;    //source annotation
     //dialog widgets:
     QLineEdit *AuthorEdit;
-    KColorButton *colorBn;
-    KIntNumInput *m_opacity;
     AnnotationWidget *m_annotWidget;
     QLabel *m_modifyDateLabel;
     
diff --git a/ui/annotationwidgets.cpp b/ui/annotationwidgets.cpp
index ce8a91b..2e8d88d 100644
--- a/ui/annotationwidgets.cpp
+++ b/ui/annotationwidgets.cpp
@@ -22,6 +22,7 @@
 #include <kicon.h>
 #include <kiconloader.h>
 #include <klocale.h>
+#include <knuminput.h>
 #include <kdebug.h>
 
 #include "core/document.h"
@@ -146,13 +147,13 @@ AnnotationWidget * AnnotationWidgetFactory::widgetFor( Okular::Annotation * ann
         default:
             ;
     }
-    // cases not covered yet
-    return 0;
+    // cases not covered yet: return a generic widget
+    return new AnnotationWidget( ann );
 }
 
 
 AnnotationWidget::AnnotationWidget( Okular::Annotation * ann )
-    : QObject(), m_ann( ann ), m_styleWidget( 0 ), m_extraWidget( 0 )
+    : QObject(), m_ann( ann ), m_appearanceWidget( 0 ), m_extraWidget( 0 )
 {
 }
 
@@ -165,13 +166,13 @@ Okular::Annotation::SubType AnnotationWidget::annotationType() const
     return m_ann->subType();
 }
 
-QWidget * AnnotationWidget::styleWidget()
+QWidget * AnnotationWidget::appearanceWidget()
 {
-    if ( m_styleWidget )
-        return m_styleWidget;
+    if ( m_appearanceWidget )
+        return m_appearanceWidget;
 
-    m_styleWidget = createStyleWidget();
-    return m_styleWidget;
+    m_appearanceWidget = createAppearanceWidget();
+    return m_appearanceWidget;
 }
 
 QWidget * AnnotationWidget::extraWidget()
@@ -183,6 +184,50 @@ QWidget * AnnotationWidget::extraWidget()
     return m_extraWidget;
 }
 
+void AnnotationWidget::applyChanges()
+{
+    m_ann->style().setColor( colorBn->color() );
+    m_ann->style().setOpacity( (double)m_opacity->value() / 100.0 );
+}
+
+QWidget * AnnotationWidget::createAppearanceWidget()
+{
+    QWidget * widget = new QWidget();
+    QGridLayout * gridlayout = new QGridLayout( widget );
+
+    QLabel * tmplabel = new QLabel( i18n( "&Color:" ), widget );
+    gridlayout->addWidget( tmplabel, 0, 0, Qt::AlignRight );
+    colorBn = new KColorButton( widget );
+    colorBn->setColor( m_ann->style().color() );
+    tmplabel->setBuddy( colorBn );
+    gridlayout->addWidget( colorBn, 0, 1 );
+
+    tmplabel = new QLabel( i18n( "&Opacity:" ), widget );
+    gridlayout->addWidget( tmplabel, 1, 0, Qt::AlignRight );
+    m_opacity = new KIntNumInput( widget );
+    m_opacity->setRange( 0, 100 );
+    m_opacity->setValue( (int)( m_ann->style().opacity() * 100 ) );
+    m_opacity->setSuffix( i18nc( "Suffix for the opacity level, eg '80 %'", " %" ) );
+    tmplabel->setBuddy( m_opacity );
+    gridlayout->addWidget( m_opacity, 1, 1 );
+
+    QWidget * styleWidget = createStyleWidget();
+    if ( styleWidget )
+        gridlayout->addWidget( styleWidget, 2, 0, 1, 2 );
+
+    gridlayout->addItem( new QSpacerItem( 5, 5, QSizePolicy::Fixed, QSizePolicy::MinimumExpanding ), 3, 0 );
+
+    connect( colorBn, SIGNAL(changed(QColor)), this, SIGNAL(dataChanged()) );
+    connect( m_opacity, SIGNAL(valueChanged(int)), this, SIGNAL(dataChanged()) );
+
+    return widget;
+}
+
+QWidget * AnnotationWidget::createStyleWidget()
+{
+    return 0;
+}
+
 QWidget * AnnotationWidget::createExtraWidget()
 {
     return 0;
@@ -238,6 +283,7 @@ QWidget * TextAnnotationWidget::createStyleWidget()
 
 void TextAnnotationWidget::applyChanges()
 {
+    AnnotationWidget::applyChanges();
     if ( m_textAnn->textType() == Okular::TextAnnotation::Linked )
     {
         m_textAnn->setTextIcon( m_pixmapSelector->icon() );
@@ -293,6 +339,7 @@ QWidget * StampAnnotationWidget::createStyleWidget()
 
 void StampAnnotationWidget::applyChanges()
 {
+    AnnotationWidget::applyChanges();
     m_stampAnn->setStampIconName( m_pixmapSelector->icon() );
 }
 
@@ -365,6 +412,7 @@ QWidget * LineAnnotationWidget::createStyleWidget()
 
 void LineAnnotationWidget::applyChanges()
 {
+    AnnotationWidget::applyChanges();
     if ( m_lineType == 0 )
     {
         m_lineAnn->setLineLeadingForwardPoint( m_spinLL->value() );
@@ -407,6 +455,7 @@ QWidget * HighlightAnnotationWidget::createStyleWidget()
 
 void HighlightAnnotationWidget::applyChanges()
 {
+    AnnotationWidget::applyChanges();
     m_hlAnn->setHighlightType( (Okular::HighlightAnnotation::HighlightType)m_typeCombo->currentIndex() );
 }
 
@@ -464,6 +513,7 @@ QWidget * GeomAnnotationWidget::createStyleWidget()
 
 void GeomAnnotationWidget::applyChanges()
 {
+    AnnotationWidget::applyChanges();
     m_geomAnn->setGeometricalType( (Okular::GeomAnnotation::GeomType)m_typeCombo->currentIndex() );
     if ( !m_useColor->isChecked() )
     {
@@ -553,6 +603,7 @@ QWidget * FileAttachmentAnnotationWidget::createExtraWidget()
 
 void FileAttachmentAnnotationWidget::applyChanges()
 {
+    AnnotationWidget::applyChanges();
     m_attachAnn->setFileIconName( m_pixmapSelector->icon() );
 }
 
@@ -608,6 +659,7 @@ QWidget * CaretAnnotationWidget::createStyleWidget()
 
 void CaretAnnotationWidget::applyChanges()
 {
+    AnnotationWidget::applyChanges();
     m_caretAnn->setCaretSymbol( caretSymbolFromIcon( m_pixmapSelector->icon() ) );
 }
 
diff --git a/ui/annotationwidgets.h b/ui/annotationwidgets.h
index 1832876..086cf85 100644
--- a/ui/annotationwidgets.h
+++ b/ui/annotationwidgets.h
@@ -20,6 +20,7 @@ class QDoubleSpinBox;
 class QLabel;
 class QWidget;
 class KColorButton;
+class KIntNumInput;
 class KFontRequester;
 class AnnotationWidget;
 
@@ -71,27 +72,30 @@ class AnnotationWidget
     Q_OBJECT
 
 public:
+    AnnotationWidget( Okular::Annotation * ann );
     virtual ~AnnotationWidget();
 
     virtual Okular::Annotation::SubType annotationType() const;
 
-    QWidget * styleWidget();
+    QWidget * appearanceWidget();
     QWidget * extraWidget();
 
-    virtual void applyChanges() = 0;
+    virtual void applyChanges();
 
 signals:
     void dataChanged();
 
 protected:
-    AnnotationWidget( Okular::Annotation * ann );
+    QWidget * createAppearanceWidget();
 
-    virtual QWidget * createStyleWidget() = 0;
+    virtual QWidget * createStyleWidget();
     virtual QWidget * createExtraWidget();
 
     Okular::Annotation * m_ann;
-    QWidget * m_styleWidget;
+    QWidget * m_appearanceWidget;
     QWidget * m_extraWidget;
+    KColorButton *colorBn;
+    KIntNumInput *m_opacity;
 };
 
 class TextAnnotationWidget
-- 
1.7.6.5


From 9a2641fd021d56e7683386848894a8442f583b4c Mon Sep 17 00:00:00 2001
From: Fabio D'Urso <fabiodurso at hotmail.it>
Date: Thu, 26 Jul 2012 19:23:38 +0200
Subject: [PATCH 14/43] Text annotation properties: show the font config field
 only if the text is in-place

---
 ui/annotationwidgets.cpp |   62 ++++++++++++++++++++++++---------------------
 1 files changed, 33 insertions(+), 29 deletions(-)

diff --git a/ui/annotationwidgets.cpp b/ui/annotationwidgets.cpp
index 2e8d88d..9d11750 100644
--- a/ui/annotationwidgets.cpp
+++ b/ui/annotationwidgets.cpp
@@ -248,35 +248,36 @@ QWidget * TextAnnotationWidget::createStyleWidget()
 
     if ( m_textAnn->textType() == Okular::TextAnnotation::Linked )
     {
-    QGroupBox * gb = new QGroupBox( widget );
-    lay->addWidget( gb );
-    gb->setTitle( i18n( "Icon" ) );
-    QHBoxLayout * gblay = new QHBoxLayout( gb );
-    m_pixmapSelector = new PixmapPreviewSelector( gb );
-    gblay->addWidget( m_pixmapSelector );
-
-    m_pixmapSelector->addItem( i18n( "Comment" ), "Comment" );
-    m_pixmapSelector->addItem( i18n( "Help" ), "Help" );
-    m_pixmapSelector->addItem( i18n( "Insert" ), "Insert" );
-    m_pixmapSelector->addItem( i18n( "Key" ), "Key" );
-    m_pixmapSelector->addItem( i18n( "New Paragraph" ), "NewParagraph" );
-    m_pixmapSelector->addItem( i18n( "Note" ), "Note" );
-    m_pixmapSelector->addItem( i18n( "Paragraph" ), "Paragraph" );
-    m_pixmapSelector->setIcon( m_textAnn->textIcon() );
-
-    connect( m_pixmapSelector, SIGNAL(iconChanged(QString)), this, SIGNAL(dataChanged()) );
+        QGroupBox * gb = new QGroupBox( widget );
+        lay->addWidget( gb );
+        gb->setTitle( i18n( "Icon" ) );
+        QHBoxLayout * gblay = new QHBoxLayout( gb );
+        m_pixmapSelector = new PixmapPreviewSelector( gb );
+        gblay->addWidget( m_pixmapSelector );
+
+        m_pixmapSelector->addItem( i18n( "Comment" ), "Comment" );
+        m_pixmapSelector->addItem( i18n( "Help" ), "Help" );
+        m_pixmapSelector->addItem( i18n( "Insert" ), "Insert" );
+        m_pixmapSelector->addItem( i18n( "Key" ), "Key" );
+        m_pixmapSelector->addItem( i18n( "New Paragraph" ), "NewParagraph" );
+        m_pixmapSelector->addItem( i18n( "Note" ), "Note" );
+        m_pixmapSelector->addItem( i18n( "Paragraph" ), "Paragraph" );
+        m_pixmapSelector->setIcon( m_textAnn->textIcon() );
+
+        connect( m_pixmapSelector, SIGNAL(iconChanged(QString)), this, SIGNAL(dataChanged()) );
+    }
+    else if ( m_textAnn->textType() == Okular::TextAnnotation::InPlace )
+    {
+        QHBoxLayout * fontlay = new QHBoxLayout();
+        QLabel * tmplabel = new QLabel( i18n( "Font:" ), widget );
+        fontlay->addWidget( tmplabel );
+        m_fontReq = new KFontRequester( widget );
+        fontlay->addWidget( m_fontReq );
+        lay->addLayout( fontlay );
+        m_fontReq->setFont( m_textAnn->textFont() );
+
+        connect( m_fontReq, SIGNAL(fontSelected(QFont)), this, SIGNAL(dataChanged()) );
     }
-
-    QHBoxLayout * fontlay = new QHBoxLayout();
-    QLabel * tmplabel = new QLabel( i18n( "Font:" ), widget );
-    fontlay->addWidget( tmplabel );
-    m_fontReq = new KFontRequester( widget );
-    fontlay->addWidget( m_fontReq );
-    lay->addLayout( fontlay );
-
-    m_fontReq->setFont( m_textAnn->textFont() );
-
-    connect( m_fontReq, SIGNAL(fontSelected(QFont)), this, SIGNAL(dataChanged()) );
 
     return widget;
 }
@@ -288,7 +289,10 @@ void TextAnnotationWidget::applyChanges()
     {
         m_textAnn->setTextIcon( m_pixmapSelector->icon() );
     }
-    m_textAnn->setTextFont( m_fontReq->font() );
+    else if ( m_textAnn->textType() == Okular::TextAnnotation::InPlace )
+    {
+        m_textAnn->setTextFont( m_fontReq->font() );
+    }
 }
 
 
-- 
1.7.6.5


From ebe85d01c7360d5e3d1ea3743d78073913f74aea Mon Sep 17 00:00:00 2001
From: Fabio D'Urso <fabiodurso at hotmail.it>
Date: Thu, 26 Jul 2012 21:19:47 +0200
Subject: [PATCH 15/43] Show the same widget as the annotation properties
 dialog when creating annotation tools

Note: Some properties are not stored in the tools' XML yet
---
 conf/widgetannottools.cpp |  336 ++++++++++++++++++++++++++++++++-------------
 conf/widgetannottools.h   |   19 ++-
 ui/annotationwidgets.h    |    1 +
 3 files changed, 256 insertions(+), 100 deletions(-)

diff --git a/conf/widgetannottools.cpp b/conf/widgetannottools.cpp
index b0a3945..436e30a 100644
--- a/conf/widgetannottools.cpp
+++ b/conf/widgetannottools.cpp
@@ -25,6 +25,8 @@
 #include <QtXml/QDomDocument>
 #include <QtXml/QDomElement>
 
+#include "core/annotations.h"
+#include "ui/annotationwidgets.h"
 #include "ui_widgetannottoolsbase.h"
 
 WidgetAnnotTools::WidgetAnnotTools( QWidget * parent )
@@ -178,7 +180,7 @@ void WidgetAnnotTools::slotMoveDown( bool )
 }
 
 NewAnnotToolDialog::NewAnnotToolDialog( QWidget *parent )
-    : KDialog( parent )
+    : KDialog( parent ), m_annotationWidget( 0 )
 {
     setCaption( i18n("Create annotation tool") );
     setButtons( Ok | Cancel );
@@ -199,103 +201,37 @@ NewAnnotToolDialog::NewAnnotToolDialog( QWidget *parent )
     widgetLayout->addWidget( m_name, 0, 1 );
 
     m_type = new KComboBox( false, widget );
+    connect( m_type, SIGNAL( currentIndexChanged(int) ), this, SLOT( slotTypeChanged(int) ) );
     tmplabel = new QLabel( i18n( "&Type:" ), widget );
     tmplabel->setBuddy( m_type );
     widgetLayout->addWidget( tmplabel, 1, 0, Qt::AlignRight );
     widgetLayout->addWidget( m_type, 1, 1 );
 
-    QGroupBox * appearance = new QGroupBox( i18n( "Appearance" ), widget );
-    QGridLayout * appearanceLayout = new QGridLayout( appearance );
-
-    m_color = new KColorButton( appearance );
-    tmplabel = new QLabel( i18n( "&Color:" ), appearance );
-    m_color->setColor( Qt::green );
-    tmplabel->setBuddy( m_color );
-    appearanceLayout->addWidget( tmplabel, 0, 0, Qt::AlignRight );
-    appearanceLayout->addWidget( m_color, 0, 1 );
-
-    m_opacity = new KIntNumInput( appearance );
-    m_opacity->setRange( 0, 100 );
-    m_opacity->setValue( 100 );
-    m_opacity->setSuffix( i18nc( "Suffix for the opacity level, eg '80 %'", " %" ) );
-    tmplabel = new QLabel( i18n( "&Opacity:" ), appearance );
-    tmplabel->setBuddy( m_opacity );
-    appearanceLayout->addWidget( tmplabel, 1, 0, Qt::AlignRight );
-    appearanceLayout->addWidget( m_opacity, 1, 1 );
-
-    widgetLayout->addWidget( appearance, 2, 0, 1, 2 );
-
-#define TYPE(name, template) \
-    m_type->addItem( name, qVariantFromValue(QString( template )) )
-
-    TYPE( i18n("Note"),
-            "<tool type=\"note-linked\">"
-             "<engine type=\"PickPoint\" color=\"%1\" hoverIcon=\"tool-note\">"
-              "<annotation type=\"Text\" color=\"%1\" opacity=\"%2\" />"
-             "</engine>"
-            "</tool>" );
-    TYPE( i18n("Inline Note" ),
-            "<tool type=\"note-inline\">"
-             "<engine type=\"PickPoint\" color=\"%1\" hoverIcon=\"tool-note-inline\" block=\"true\">"
-              "<annotation type=\"FreeText\" color=\"%1\" opacity=\"%2\" />"
-             "</engine>"
-            "</tool>" );
-    TYPE( i18n("Freehand Line" ),
-            "<tool type=\"ink\">"
-             "<engine type=\"SmoothLine\" color=\"%1\">"
-              "<annotation type=\"Ink\" color=\"%1\" width=\"2\" opacity=\"%2\" />"
-             "</engine>"
-            "</tool>" );
-    TYPE( i18n("Straight Line" ),
-            "<tool type=\"straight-line\">"
-             "<engine type=\"PolyLine\" color=\"%1\" points=\"2\">"
-              "<annotation type=\"Line\" width=\"4\" color=\"%1\" opacity=\"%2\" />"
-             "</engine>"
-            "</tool>" );
-    TYPE( i18n("Polygon" ),
-            "<tool type=\"polygon\">"
-             "<engine type=\"PolyLine\" color=\"%1\" points=\"-1\">"
-              "<annotation type=\"Line\" width=\"4\" color=\"%1\" opacity=\"%2\" />"
-             "</engine>"
-            "</tool>" );
-    TYPE( i18n("Highlight" ),
-            "<tool type=\"highlight\">"
-             "<engine type=\"TextSelector\" color=\"%1\">"
-              "<annotation type=\"Highlight\" color=\"%1\" opacity=\"%2\" />"
-             "</engine>"
-            "</tool>" );
-    TYPE( i18n("Squiggly" ),
-            "<tool type=\"squiggly\">"
-             "<engine type=\"TextSelector\" color=\"%1\">"
-              "<annotation type=\"Squiggly\" color=\"%1\" opacity=\"%2\" />"
-             "</engine>"
-            "</tool>" );
-    TYPE( i18n("Underline" ),
-            "<tool type=\"underline\">"
-             "<engine type=\"TextSelector\" color=\"%1\">"
-              "<annotation type=\"Underline\" color=\"%1\" opacity=\"%2\" />"
-             "</engine>"
-            "</tool>" );
-    TYPE( i18n("Strike out" ),
-            "<tool type=\"strikeout\">"
-             "<engine type=\"TextSelector\" color=\"%1\">"
-              "<annotation type=\"StrikeOut\" color=\"%1\" opacity=\"%2\" />"
-             "</engine>"
-            "</tool>" );
-    TYPE( i18n("Ellipse" ),
-            "<tool type=\"ellipse\">"
-             "<engine type=\"PickPoint\" color=\"%1\" block=\"true\">"
-              "<annotation type=\"GeomCircle\" color=\"%1\" opacity=\"%2\" />"
-             "</engine>"
-            "</tool>" );
-    TYPE( i18n("Rectangle" ),
-            "<tool type=\"rectangle\">"
-             "<engine type=\"PickPoint\" color=\"%1\" block=\"true\">"
-              "<annotation type=\"GeomSquare\" color=\"%1\" opacity=\"%2\" />"
-             "</engine>"
-            "</tool>" );
-    // TODO: Stamp
-#undef ADDTYPE
+    m_appearanceBox = new QGroupBox( i18n( "Appearance" ), widget );
+    m_appearanceBox->setLayout( new QVBoxLayout( m_appearanceBox ) );
+    widgetLayout->addWidget( m_appearanceBox, 2, 0, 1, 2 );
+
+    // Create a stub annotation of the default type
+    m_stubann = new Okular::TextAnnotation();
+    static_cast<Okular::TextAnnotation*>(m_stubann)->setTextType( Okular::TextAnnotation::Linked );
+    m_stubann->style().setColor( Qt::yellow );
+
+    // Populate combobox with annotation types
+    m_type->addItem( i18n("Note") );
+    m_type->addItem( i18n("Inline Note") );
+    m_type->addItem( i18n("Freehand Line") );
+    m_type->addItem( i18n("Straight Line") );
+    m_type->addItem( i18n("Polygon") );
+    m_type->addItem( i18n("Text markup") );
+    m_type->addItem( i18n("Geometrical shape") );
+    m_type->addItem( i18n("Stamp") );
+
+    rebuildAppearanceBox();
+}
+
+NewAnnotToolDialog::~NewAnnotToolDialog()
+{
+    delete m_annotationWidget;
 }
 
 QString NewAnnotToolDialog::name() const
@@ -305,9 +241,141 @@ QString NewAnnotToolDialog::name() const
 
 QString NewAnnotToolDialog::toolXml() const
 {
-    const QString templ = m_type->itemData( m_type->currentIndex() ).value<QString>();
-    const double opacity = (double)m_opacity->value() / 100.0;
-    return templ.arg( m_color->color().name() ).arg( opacity );
+    const QString color = m_stubann->style().color().name();
+    const double opacity = m_stubann->style().opacity();
+
+    switch ( m_type->currentIndex() )
+    {
+        case 0:
+        {
+            // Note
+            Okular::TextAnnotation * ta = static_cast<Okular::TextAnnotation*>( m_stubann );
+            Q_UNUSED( ta );
+            return QString( "<tool type=\"note-linked\">"
+                             "<engine type=\"PickPoint\" color=\"%1\" hoverIcon=\"tool-note\">"
+                              "<annotation type=\"Text\" color=\"%1\" opacity=\"%2\" />"
+                             "</engine>"
+                            "</tool>" ).arg( color ).arg( opacity );
+        }
+        case 1:
+        {
+            // Inline Note
+            Okular::TextAnnotation * ta = static_cast<Okular::TextAnnotation*>( m_stubann );
+            Q_UNUSED( ta );
+            return QString( "<tool type=\"note-inline\">"
+                             "<engine type=\"PickPoint\" color=\"%1\" hoverIcon=\"tool-note-inline\" block=\"true\">"
+                              "<annotation type=\"FreeText\" color=\"%1\" opacity=\"%2\" />"
+                             "</engine>"
+                            "</tool>" ).arg( color ).arg( opacity );
+        }
+        case 2:
+        {
+            // Freehand Line
+            Okular::InkAnnotation * ia = static_cast<Okular::InkAnnotation*>( m_stubann );
+            Q_UNUSED( ia );
+            return QString( "<tool type=\"ink\">"
+                             "<engine type=\"SmoothLine\" color=\"%1\">"
+                              "<annotation type=\"Ink\" color=\"%1\" width=\"2\" opacity=\"%2\" />"
+                             "</engine>"
+                            "</tool>").arg( color ).arg( opacity );
+        }
+        case 3:
+        {
+            // Straight Line
+            Okular::LineAnnotation * la = static_cast<Okular::LineAnnotation*>( m_stubann );
+            Q_UNUSED( la );
+            return QString( "<tool type=\"straight-line\">"
+                             "<engine type=\"PolyLine\" color=\"%1\" points=\"2\">"
+                              "<annotation type=\"Line\" width=\"4\" color=\"%1\" opacity=\"%2\" />"
+                             "</engine>"
+                            "</tool>" ).arg( color ).arg( opacity );
+        }
+        case 4:
+        {
+            // Polygon
+            Okular::LineAnnotation * la = static_cast<Okular::LineAnnotation*>( m_stubann );
+            Q_UNUSED( la );
+            return QString( "<tool type=\"polygon\">"
+                             "<engine type=\"PolyLine\" color=\"%1\" points=\"-1\">"
+                              "<annotation type=\"Line\" width=\"4\" color=\"%1\" opacity=\"%2\" />"
+                             "</engine>"
+                            "</tool>" ).arg( color ).arg( opacity );
+        }
+        case 5:
+        {
+            // Text Markup
+            Okular::HighlightAnnotation * ha = static_cast<Okular::HighlightAnnotation*>( m_stubann );
+
+            QString toolType, annotationType;
+            switch ( ha->highlightType() )
+            {
+                case Okular::HighlightAnnotation::Highlight:
+                    toolType = "highlight";
+                    annotationType = "Highlight";
+                    break;
+                case Okular::HighlightAnnotation::Squiggly:
+                    toolType = "squiggly";
+                    annotationType = "Squiggly";
+                    break;
+                case Okular::HighlightAnnotation::Underline:
+                    toolType = "underline";
+                    annotationType = "Underline";
+                    break;
+                case Okular::HighlightAnnotation::StrikeOut:
+                    toolType = "strikeout";
+                    annotationType = "StrikeOut";
+                    break;
+            }
+
+            return QString( "<tool type=\"%3\">"
+                             "<engine type=\"TextSelector\" color=\"%1\">"
+                              "<annotation type=\"%4\" color=\"%1\" opacity=\"%2\" />"
+                             "</engine>"
+                            "</tool>").arg( color ).arg( opacity )
+                                      .arg( toolType ).arg( annotationType );
+        }
+        case 6:
+        {
+            // Geometrical shape
+            Okular::GeomAnnotation * ga = static_cast<Okular::GeomAnnotation*>( m_stubann );
+            const bool isCircle = (ga->geometricalType() == Okular::GeomAnnotation::InscribedCircle);
+            return QString( "<tool type=\"%3\">"
+                             "<engine type=\"PickPoint\" color=\"%1\" block=\"true\">"
+                              "<annotation type=\"%4\" color=\"%1\" opacity=\"%2\" />"
+                             "</engine>"
+                            "</tool>").arg( color ).arg( opacity )
+                                      .arg( isCircle ? "ellipse" : "rectangle" )
+                                      .arg( isCircle ? "GeomCircle" : "GeomSquare" );
+        }
+        case 7:
+        {
+            // Stamp
+            Okular::StampAnnotation * sa = static_cast<Okular::StampAnnotation*>( m_stubann );
+            return QString( "<tool type=\"stamp\">"
+                             "<engine type=\"PickPoint\" hoverIcon=\"%1\" size=\"64\" block=\"true\">"
+                              "<annotation type=\"Stamp\" icon=\"%1\"/>"
+                             "</engine>"
+                            "</tool>" ).arg( sa->stampIconName() ); // FIXME: Check bad strings
+        }
+    }
+
+    return QString(); // This should never happen
+}
+
+void NewAnnotToolDialog::rebuildAppearanceBox()
+{
+    // Remove previous widget (if any)
+    if ( m_annotationWidget )
+    {
+        delete m_annotationWidget->appearanceWidget();
+        delete m_annotationWidget;
+    }
+
+    m_annotationWidget = AnnotationWidgetFactory::widgetFor( m_stubann );
+    m_appearanceBox->layout()->addWidget( m_annotationWidget->appearanceWidget() );
+
+    // Tell the widget to mirror changes back in the stub annotation
+    connect( m_annotationWidget, SIGNAL(dataChanged()), m_annotationWidget, SLOT(applyChanges()) );
 }
 
 void NewAnnotToolDialog::slotNameEdited( const QString &new_name )
@@ -315,4 +383,80 @@ void NewAnnotToolDialog::slotNameEdited( const QString &new_name )
     enableButton( Ok, !new_name.isEmpty() );
 }
 
+void NewAnnotToolDialog::slotTypeChanged( int index )
+{
+    delete m_stubann;
+
+    // Create stub annotation
+    switch ( index )
+    {
+        case 0:
+        {
+            // Note
+            Okular::TextAnnotation * ta = new Okular::TextAnnotation();
+            ta->setTextType( Okular::TextAnnotation::Linked );
+            m_stubann = ta;
+            break;
+        }
+        case 1:
+        {
+            // Inline Note
+            Okular::TextAnnotation * ta = new Okular::TextAnnotation();
+            ta->setTextType( Okular::TextAnnotation::InPlace );
+            m_stubann = ta;
+            break;
+        }
+        case 2:
+        {
+            // Freehand Line
+            m_stubann = new Okular::InkAnnotation();
+            break;
+        }
+        case 3:
+        {
+            // Straight Line
+            Okular::LineAnnotation * la = new Okular::LineAnnotation();
+            la->setLinePoints( QLinkedList<Okular::NormalizedPoint>() <<
+                                    Okular::NormalizedPoint(0,0) <<
+                                    Okular::NormalizedPoint(1,0) );
+            m_stubann = la;
+            break;
+        }
+        case 4:
+        {
+            // Polygon
+            Okular::LineAnnotation * la = new Okular::LineAnnotation();
+            la->setLinePoints( QLinkedList<Okular::NormalizedPoint>() <<
+                                    Okular::NormalizedPoint(0,0) <<
+                                    Okular::NormalizedPoint(1,0) <<
+                                    Okular::NormalizedPoint(1,1) );
+            m_stubann = la;
+            break;
+        }
+        case 5:
+        {
+            // Text Markup
+            m_stubann = new Okular::HighlightAnnotation();
+            break;
+        }
+        case 6:
+        {
+            // Geometrical shape
+            m_stubann = new Okular::GeomAnnotation();
+            break;
+        }
+        case 7:
+        {
+            // Stamp
+            Okular::StampAnnotation * sa = new Okular::StampAnnotation();
+            sa->setStampIconName( "okular" );
+            m_stubann = sa;
+            break;
+        }
+    }
+
+    m_stubann->style().setColor( Qt::yellow ); // TODO: Choose default color according to annotation type
+    rebuildAppearanceBox();
+}
+
 #include "moc_widgetannottools.cpp"
diff --git a/conf/widgetannottools.h b/conf/widgetannottools.h
index 80c8c5f..8b7653a 100644
--- a/conf/widgetannottools.h
+++ b/conf/widgetannottools.h
@@ -15,11 +15,16 @@
 
 class KLineEdit;
 class KComboBox;
-class KColorButton;
-class KIntNumInput;
 class QListWidgetItem;
+class QGroupBox;
+class AnnotationWidget;
 class Ui_WidgetAnnotToolsBase;
 
+namespace Okular
+{
+class Annotation;
+}
+
 class WidgetAnnotTools : public QWidget
 {
     Q_OBJECT
@@ -55,17 +60,23 @@ class NewAnnotToolDialog : public KDialog
 
     public:
         NewAnnotToolDialog( QWidget *parent = 0 );
+        ~NewAnnotToolDialog();
         QString name() const;
         QString toolXml() const;
 
     private:
+        void rebuildAppearanceBox();
+
         KLineEdit * m_name;
         KComboBox * m_type;
-        KColorButton * m_color;
-        KIntNumInput * m_opacity;
+        QGroupBox * m_appearanceBox;
+
+        Okular::Annotation *m_stubann;
+        AnnotationWidget *m_annotationWidget;
 
     private slots:
         void slotNameEdited( const QString &new_name );
+        void slotTypeChanged( int index );
 };
 
 #endif
diff --git a/ui/annotationwidgets.h b/ui/annotationwidgets.h
index 086cf85..65eaf3f 100644
--- a/ui/annotationwidgets.h
+++ b/ui/annotationwidgets.h
@@ -80,6 +80,7 @@ public:
     QWidget * appearanceWidget();
     QWidget * extraWidget();
 
+public slots:
     virtual void applyChanges();
 
 signals:
-- 
1.7.6.5


From bbf6195af682b6fdb1484155a21e90dc97c84e85 Mon Sep 17 00:00:00 2001
From: Fabio D'Urso <fabiodurso at hotmail.it>
Date: Thu, 26 Jul 2012 21:46:00 +0200
Subject: [PATCH 16/43] Added widget to edit InkAnnotation properties (line
 width only)

---
 ui/annotationwidgets.cpp |   41 +++++++++++++++++++++++++++++++++++++++++
 ui/annotationwidgets.h   |   18 ++++++++++++++++++
 2 files changed, 59 insertions(+), 0 deletions(-)

diff --git a/ui/annotationwidgets.cpp b/ui/annotationwidgets.cpp
index 9d11750..afcffaa 100644
--- a/ui/annotationwidgets.cpp
+++ b/ui/annotationwidgets.cpp
@@ -134,6 +134,9 @@ AnnotationWidget * AnnotationWidgetFactory::widgetFor( Okular::Annotation * ann
         case Okular::Annotation::AHighlight:
             return new HighlightAnnotationWidget( ann );
             break;
+        case Okular::Annotation::AInk:
+            return new InkAnnotationWidget( ann );
+            break;
         case Okular::Annotation::AGeom:
             return new GeomAnnotationWidget( ann );
             break;
@@ -427,6 +430,44 @@ void LineAnnotationWidget::applyChanges()
 
 
 
+InkAnnotationWidget::InkAnnotationWidget( Okular::Annotation * ann )
+    : AnnotationWidget( ann )
+{
+    m_inkAnn = static_cast< Okular::InkAnnotation * >( ann );
+}
+
+QWidget * InkAnnotationWidget::createStyleWidget()
+{
+    QWidget * widget = new QWidget();
+    QVBoxLayout * lay = new QVBoxLayout( widget );
+    lay->setMargin( 0 );
+
+    QGroupBox * gb2 = new QGroupBox( widget );
+    lay->addWidget( gb2 );
+    gb2->setTitle( i18n( "Style" ) );
+    QGridLayout * gridlay2 = new QGridLayout( gb2 );
+    QLabel * tmplabel2 = new QLabel( i18n( "&Size:" ), gb2 );
+    gridlay2->addWidget( tmplabel2, 0, 0, Qt::AlignRight );
+    m_spinSize = new QDoubleSpinBox( gb2 );
+    gridlay2->addWidget( m_spinSize, 0, 1 );
+    tmplabel2->setBuddy( m_spinSize );
+
+    m_spinSize->setRange( 1, 100 );
+    m_spinSize->setValue( m_inkAnn->style().width() );
+
+    connect( m_spinSize, SIGNAL(valueChanged(double)), this, SIGNAL(dataChanged()) );
+
+    return widget;
+}
+
+void InkAnnotationWidget::applyChanges()
+{
+    AnnotationWidget::applyChanges();
+    m_inkAnn->style().setWidth( m_spinSize->value() );
+}
+
+
+
 HighlightAnnotationWidget::HighlightAnnotationWidget( Okular::Annotation * ann )
     : AnnotationWidget( ann )
 {
diff --git a/ui/annotationwidgets.h b/ui/annotationwidgets.h
index 65eaf3f..a6df239 100644
--- a/ui/annotationwidgets.h
+++ b/ui/annotationwidgets.h
@@ -233,4 +233,22 @@ private:
     PixmapPreviewSelector * m_pixmapSelector;
 };
 
+class InkAnnotationWidget
+  : public AnnotationWidget
+{
+    Q_OBJECT
+
+public:
+    InkAnnotationWidget( Okular::Annotation * ann );
+
+    virtual void applyChanges();
+
+protected:
+    virtual QWidget * createStyleWidget();
+
+private:
+    Okular::InkAnnotation * m_inkAnn;
+    QDoubleSpinBox * m_spinSize;
+};
+
 #endif
-- 
1.7.6.5


From e77759ae5287ba32258fbb47b5de77b97699ba1c Mon Sep 17 00:00:00 2001
From: Fabio D'Urso <fabiodurso at hotmail.it>
Date: Thu, 26 Jul 2012 23:15:02 +0200
Subject: [PATCH 17/43] Made line width configurable in Ink, Line, Polygon,
 Square and Circle annotation tools

Note that previously the width attrubute was ignored by the PolyLine
engine and it always set width=1, that's why I had to change the default
value in tools.xml.
---
 conf/widgetannottools.cpp |   19 ++++++++++---------
 ui/data/tools.xml         |    6 +++---
 ui/pageviewannotator.cpp  |    6 +++++-
 3 files changed, 18 insertions(+), 13 deletions(-)

diff --git a/conf/widgetannottools.cpp b/conf/widgetannottools.cpp
index 436e30a..2da625f 100644
--- a/conf/widgetannottools.cpp
+++ b/conf/widgetannottools.cpp
@@ -243,6 +243,7 @@ QString NewAnnotToolDialog::toolXml() const
 {
     const QString color = m_stubann->style().color().name();
     const double opacity = m_stubann->style().opacity();
+    const double width = m_stubann->style().width();
 
     switch ( m_type->currentIndex() )
     {
@@ -275,9 +276,9 @@ QString NewAnnotToolDialog::toolXml() const
             Q_UNUSED( ia );
             return QString( "<tool type=\"ink\">"
                              "<engine type=\"SmoothLine\" color=\"%1\">"
-                              "<annotation type=\"Ink\" color=\"%1\" width=\"2\" opacity=\"%2\" />"
+                              "<annotation type=\"Ink\" color=\"%1\" opacity=\"%2\" width=\"%3\" />"
                              "</engine>"
-                            "</tool>").arg( color ).arg( opacity );
+                            "</tool>").arg( color ).arg( opacity ).arg( width );
         }
         case 3:
         {
@@ -286,9 +287,9 @@ QString NewAnnotToolDialog::toolXml() const
             Q_UNUSED( la );
             return QString( "<tool type=\"straight-line\">"
                              "<engine type=\"PolyLine\" color=\"%1\" points=\"2\">"
-                              "<annotation type=\"Line\" width=\"4\" color=\"%1\" opacity=\"%2\" />"
+                              "<annotation type=\"Line\" color=\"%1\" opacity=\"%2\" width=\"%3\" />"
                              "</engine>"
-                            "</tool>" ).arg( color ).arg( opacity );
+                            "</tool>" ).arg( color ).arg( opacity ).arg( width );
         }
         case 4:
         {
@@ -297,9 +298,9 @@ QString NewAnnotToolDialog::toolXml() const
             Q_UNUSED( la );
             return QString( "<tool type=\"polygon\">"
                              "<engine type=\"PolyLine\" color=\"%1\" points=\"-1\">"
-                              "<annotation type=\"Line\" width=\"4\" color=\"%1\" opacity=\"%2\" />"
+                              "<annotation type=\"Line\" color=\"%1\" opacity=\"%2\" width=\"%3\" />"
                              "</engine>"
-                            "</tool>" ).arg( color ).arg( opacity );
+                            "</tool>" ).arg( color ).arg( opacity ).arg( width );
         }
         case 5:
         {
@@ -339,11 +340,11 @@ QString NewAnnotToolDialog::toolXml() const
             // Geometrical shape
             Okular::GeomAnnotation * ga = static_cast<Okular::GeomAnnotation*>( m_stubann );
             const bool isCircle = (ga->geometricalType() == Okular::GeomAnnotation::InscribedCircle);
-            return QString( "<tool type=\"%3\">"
+            return QString( "<tool type=\"%4\">"
                              "<engine type=\"PickPoint\" color=\"%1\" block=\"true\">"
-                              "<annotation type=\"%4\" color=\"%1\" opacity=\"%2\" />"
+                              "<annotation type=\"%5\" color=\"%1\" opacity=\"%2\" width=\"%3\" />"
                              "</engine>"
-                            "</tool>").arg( color ).arg( opacity )
+                            "</tool>").arg( color ).arg( opacity ).arg( width )
                                       .arg( isCircle ? "ellipse" : "rectangle" )
                                       .arg( isCircle ? "GeomCircle" : "GeomSquare" );
         }
diff --git a/ui/data/tools.xml b/ui/data/tools.xml
index 867bbd6..1579a8e 100644
--- a/ui/data/tools.xml
+++ b/ui/data/tools.xml
@@ -48,14 +48,14 @@ Engine/Annotation Types [specific attributes]:
     <tool id="5" name="Straight Yellow Line" type="straight-line">
         <tooltip>Straight Yellow Line</tooltip>
         <engine type="PolyLine" color="#FFE000" points="2">
-            <annotation type="Line" width="4" color="#FFE000" />
+            <annotation type="Line" width="1" color="#FFE000" />
         </engine>
         <shortcut>5</shortcut>
     </tool>
     <tool id="6" name="Blue Polygon" type="polygon">
         <tooltip>Draw a polygon (click on the first point to close it)</tooltip>
         <engine type="PolyLine" color="#007EEE" points="-1">
-            <annotation type="Line" width="4" color="#007EEE" />
+            <annotation type="Line" width="1" color="#007EEE" />
         </engine>
         <shortcut>6</shortcut>
     </tool>
@@ -76,7 +76,7 @@ Engine/Annotation Types [specific attributes]:
     <tool id="9" name="Cyan Ellipse" type="ellipse">
         <tooltip>A cyan ellipse</tooltip>
         <engine type="PickPoint" color="#00ffff" block="true">
-            <annotation type="GeomCircle" color="#00ffff" />
+            <annotation type="GeomCircle" width="5" color="#00ffff" />
         </engine>
         <shortcut>9</shortcut>
     </tool>
diff --git a/ui/pageviewannotator.cpp b/ui/pageviewannotator.cpp
index 793eb77..72210eb 100644
--- a/ui/pageviewannotator.cpp
+++ b/ui/pageviewannotator.cpp
@@ -241,7 +241,8 @@ class PickPointEngine : public AnnotatorEngine
                     ga->setGeometricalType( Okular::GeomAnnotation::InscribedSquare );
                 else
                     ga->setGeometricalType( Okular::GeomAnnotation::InscribedCircle );
-                ga->style().setWidth( 5 );
+                if ( m_annotElement.hasAttribute( "width" ) )
+                    ann->style().setWidth( m_annotElement.attribute( "width" ).toDouble() );
                 //set boundary
                 rect.left = qMin( startpoint.x, point.x );
                 rect.top = qMin( startpoint.y, point.y );
@@ -415,6 +416,9 @@ class PolyLineEngine : public AnnotatorEngine
             if ( !ann )
                 return QList< Okular::Annotation* >();
 
+            if ( m_annotElement.hasAttribute( "width" ) )
+                ann->style().setWidth( m_annotElement.attribute( "width" ).toDouble() );
+
             // set common attributes
             ann->style().setColor( m_annotElement.hasAttribute( "color" ) ?
                     m_annotElement.attribute( "color" ) : m_engineColor );
-- 
1.7.6.5


From 436b7582430f67ea0607895730e46e64bd54cd70 Mon Sep 17 00:00:00 2001
From: Fabio D'Urso <fabiodurso at hotmail.it>
Date: Thu, 26 Jul 2012 23:43:18 +0200
Subject: [PATCH 18/43] Load hoverIcon through our icon loader, because
 DesktopEntry can't find SVG stamps

With the old code, a "?" icon was shortly shown instead
---
 ui/pageviewannotator.cpp |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/ui/pageviewannotator.cpp b/ui/pageviewannotator.cpp
index 72210eb..3279265 100644
--- a/ui/pageviewannotator.cpp
+++ b/ui/pageviewannotator.cpp
@@ -61,7 +61,7 @@ class PickPointEngine : public AnnotatorEngine
 
             // create engine objects
             if ( !pixmapName.simplified().isEmpty() )
-                pixmap = new QPixmap( DesktopIcon( pixmapName, size ) );
+                pixmap = new QPixmap( GuiUtils::loadStamp( pixmapName, QSize( size, size ) ) );
         }
 
         ~PickPointEngine()
-- 
1.7.6.5


From b1e0a05cc9c00d4e24f486abffb94d1ab8c13df9 Mon Sep 17 00:00:00 2001
From: Fabio D'Urso <fabiodurso at hotmail.it>
Date: Thu, 26 Jul 2012 23:56:12 +0200
Subject: [PATCH 19/43] Removed calls to query size of pixmap size in
 PickPointEngine::event

Since the size of pixmap is determined by the value of size variable,
we can directly read that variable instead of querying the pixmap.
Also note that "pixmap" comes from "hoverIcon", not from "icon", and
that piece of code wants to know the size of the latter. In case of
stamp annotations, however, they happen to be the same.
---
 ui/pageviewannotator.cpp |   10 +++++-----
 1 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/ui/pageviewannotator.cpp b/ui/pageviewannotator.cpp
index 3279265..c759740 100644
--- a/ui/pageviewannotator.cpp
+++ b/ui/pageviewannotator.cpp
@@ -101,18 +101,18 @@ class PickPointEngine : public AnnotatorEngine
             // update variables and extents (zoom invariant rect)
             point.x = nX;
             point.y = nY;
-            if ( center && pixmap )
+            if ( center )
             {
-                rect.left = nX - ( pixmap->width() / ( xScale * 2.0 ) );
-                rect.top = nY - ( pixmap->height() / ( yScale * 2.0 ) );
+                rect.left = nX - ( size / ( xScale * 2.0 ) );
+                rect.top = nY - ( size / ( yScale * 2.0 ) );
             }
             else
             {
                 rect.left = nX;
                 rect.top = nY;
             }
-            rect.right = rect.left + ( pixmap ? pixmap->width() / xScale : 0 );
-            rect.bottom = rect.top + ( pixmap ? pixmap->height() / yScale : 0 );
+            rect.right = rect.left + size;
+            rect.bottom = rect.top + size;
             QRect boundrect = rect.geometry( (int)xScale, (int)yScale ).adjusted( 0, 0, 1, 1 );
             if ( m_block )
             {
-- 
1.7.6.5


From ca4b4f660ef040525c6ad0fdaf3ce418faeae0e6 Mon Sep 17 00:00:00 2001
From: Fabio D'Urso <fabiodurso at hotmail.it>
Date: Fri, 27 Jul 2012 00:15:25 +0200
Subject: [PATCH 20/43] Made icon for Note annotations configurable

Unlike Stamp annotations, hoverIcon and icon are different in Note
annotations.
---
 conf/widgetannottools.cpp |    5 ++---
 ui/data/tools.xml         |    2 +-
 ui/pageviewannotator.cpp  |   18 +++++++++---------
 3 files changed, 12 insertions(+), 13 deletions(-)

diff --git a/conf/widgetannottools.cpp b/conf/widgetannottools.cpp
index 2da625f..02a314f 100644
--- a/conf/widgetannottools.cpp
+++ b/conf/widgetannottools.cpp
@@ -251,12 +251,11 @@ QString NewAnnotToolDialog::toolXml() const
         {
             // Note
             Okular::TextAnnotation * ta = static_cast<Okular::TextAnnotation*>( m_stubann );
-            Q_UNUSED( ta );
             return QString( "<tool type=\"note-linked\">"
                              "<engine type=\"PickPoint\" color=\"%1\" hoverIcon=\"tool-note\">"
-                              "<annotation type=\"Text\" color=\"%1\" opacity=\"%2\" />"
+                              "<annotation type=\"Text\" color=\"%1\" opacity=\"%2\" icon=\"%3\" />"
                              "</engine>"
-                            "</tool>" ).arg( color ).arg( opacity );
+                            "</tool>" ).arg( color ).arg( opacity ).arg( ta->textIcon() );
         }
         case 1:
         {
diff --git a/ui/data/tools.xml b/ui/data/tools.xml
index 1579a8e..cc9b8cd 100644
--- a/ui/data/tools.xml
+++ b/ui/data/tools.xml
@@ -20,7 +20,7 @@ Engine/Annotation Types [specific attributes]:
     <tool id="1" name="Note" type="note-linked">
         <tooltip>Text Annotation</tooltip>
         <engine type="PickPoint" color="#FFFF00" hoverIcon="tool-note">
-            <annotation type="Text" color="#FFFF00" />
+            <annotation type="Text" color="#FFFF00" icon="Note" />
         </engine>
         <shortcut>1</shortcut>
     </tool>
diff --git a/ui/pageviewannotator.cpp b/ui/pageviewannotator.cpp
index c759740..fcbc720 100644
--- a/ui/pageviewannotator.cpp
+++ b/ui/pageviewannotator.cpp
@@ -48,10 +48,10 @@ class PickPointEngine : public AnnotatorEngine
               xscale( 1.0 ), yscale( 1.0 )
         {
             // parse engine specific attributes
-            pixmapName = engineElement.attribute( "hoverIcon" );
-            QString stampname = m_annotElement.attribute( "icon" );
-            if ( m_annotElement.attribute( "type" ) == "Stamp" && !stampname.simplified().isEmpty() )
-                pixmapName = stampname;
+            hoverIconName = engineElement.attribute( "hoverIcon" );
+            iconName = m_annotElement.attribute( "icon" );
+            if ( m_annotElement.attribute( "type" ) == "Stamp" && !iconName.simplified().isEmpty() )
+                hoverIconName = iconName;
             center = QVariant( engineElement.attribute( "center" ) ).toBool();
             bool ok = true;
             size = engineElement.attribute( "size", "32" ).toInt( &ok );
@@ -60,8 +60,8 @@ class PickPointEngine : public AnnotatorEngine
             m_block = QVariant( engineElement.attribute( "block" ) ).toBool();
 
             // create engine objects
-            if ( !pixmapName.simplified().isEmpty() )
-                pixmap = new QPixmap( GuiUtils::loadStamp( pixmapName, QSize( size, size ) ) );
+            if ( !hoverIconName.simplified().isEmpty() )
+                pixmap = new QPixmap( GuiUtils::loadStamp( hoverIconName, QSize( size, size ) ) );
         }
 
         ~PickPointEngine()
@@ -188,7 +188,7 @@ class PickPointEngine : public AnnotatorEngine
                 Okular::TextAnnotation * ta = new Okular::TextAnnotation();
                 ann = ta;
                 ta->setTextType( Okular::TextAnnotation::Linked );
-                ta->setTextIcon( "Note" );
+                ta->setTextIcon( iconName );
                 ta->window().setText( QString() );
                 //ta->window.flags &= ~(Okular::Annotation::Hidden);
                 double iconhei=0.03;
@@ -204,7 +204,7 @@ class PickPointEngine : public AnnotatorEngine
             {
                 Okular::StampAnnotation * sa = new Okular::StampAnnotation();
                 ann = sa;
-                sa->setStampIconName( pixmapName );
+                sa->setStampIconName( iconName );
                 // set boundary
                 rect.left = qMin( startpoint.x, point.x );
                 rect.top = qMin( startpoint.y, point.y );
@@ -271,7 +271,7 @@ class PickPointEngine : public AnnotatorEngine
         Okular::NormalizedPoint startpoint;
         Okular::NormalizedPoint point;
         QPixmap * pixmap;
-        QString pixmapName;
+        QString hoverIconName, iconName;
         int size;
         double xscale,yscale;
         double pagewidth, pageheight;
-- 
1.7.6.5


From ba9422cef2f15f98d6dcd88bad44d7558cf7e17c Mon Sep 17 00:00:00 2001
From: Fabio D'Urso <fabiodurso at hotmail.it>
Date: Fri, 27 Jul 2012 01:02:00 +0200
Subject: [PATCH 21/43] Show tool icons in the configuration widget

---
 conf/widgetannottools.cpp |    9 ++++++++-
 ui/pageviewannotator.h    |    3 ++-
 2 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/conf/widgetannottools.cpp b/conf/widgetannottools.cpp
index 02a314f..7afd0c0 100644
--- a/conf/widgetannottools.cpp
+++ b/conf/widgetannottools.cpp
@@ -27,6 +27,7 @@
 
 #include "core/annotations.h"
 #include "ui/annotationwidgets.h"
+#include "ui/pageviewannotator.h"
 #include "ui_widgetannottoolsbase.h"
 
 WidgetAnnotTools::WidgetAnnotTools( QWidget * parent )
@@ -114,6 +115,7 @@ void WidgetAnnotTools::setTools(const QStringList& items)
             const QString itemText = toolElement.attribute( "name" );
             QListWidgetItem * listEntry = new QListWidgetItem( itemText, m_ui->list );
             listEntry->setData( Qt::UserRole, qVariantFromValue(toolXml) );
+            listEntry->setIcon( PageViewAnnotator::makeToolPixmap( toolElement ) );
         }
     }
 
@@ -142,9 +144,14 @@ void WidgetAnnotTools::slotAdd( bool )
     if ( t.exec() != QDialog::Accepted )
         return;
 
+    QDomDocument entryParser;
+    entryParser.setContent( t.toolXml() );
+    QDomElement toolElement = entryParser.documentElement();
+
     // Create list entry and attach XML string as data
     QListWidgetItem * listEntry = new QListWidgetItem( t.name(), m_ui->list );
-    listEntry->setData( Qt::UserRole, qVariantFromValue( t.toolXml() ) );
+    listEntry->setData( Qt::UserRole, qVariantFromValue( entryParser.toString(-1) ) );
+    listEntry->setIcon( PageViewAnnotator::makeToolPixmap( toolElement ) );
 
     // Select and scroll
     m_ui->list->setCurrentItem( listEntry );
diff --git a/ui/pageviewannotator.h b/ui/pageviewannotator.h
index 0c89d04..a1fb9e5 100644
--- a/ui/pageviewannotator.h
+++ b/ui/pageviewannotator.h
@@ -70,13 +70,14 @@ class PageViewAnnotator : public QObject
 
         void reparseConfig();
 
+        static QPixmap makeToolPixmap( const QDomElement &toolElement );
+
     private slots:
         void slotToolSelected( int toolID );
         void slotSaveToolbarOrientation( int side );
         void slotToolDoubleClicked( int toolID );
 
     private:
-        static QPixmap makeToolPixmap( const QDomElement &toolElement );
         void detachAnnotation();
 
         // global class pointers
-- 
1.7.6.5


From ad9487102ece1076b3b020420d0dd19794d7add6 Mon Sep 17 00:00:00 2001
From: Fabio D'Urso <fabiodurso at hotmail.it>
Date: Fri, 27 Jul 2012 01:44:24 +0200
Subject: [PATCH 22/43] Provide default name for new annotation tools

This patch also removes the slot qualification to AnnotationWidget::applyChanges()
that I had added in "Show the same widget as the annotation properties dialog when
creating annotation tools", because it's not needed any more.
---
 conf/widgetannottools.cpp |   65 ++++++++++++++++++++++++++++++++++++++++-----
 conf/widgetannottools.h   |    3 +-
 ui/annotationwidgets.h    |    1 -
 3 files changed, 60 insertions(+), 9 deletions(-)

diff --git a/conf/widgetannottools.cpp b/conf/widgetannottools.cpp
index 7afd0c0..80fe72e 100644
--- a/conf/widgetannottools.cpp
+++ b/conf/widgetannottools.cpp
@@ -191,7 +191,6 @@ NewAnnotToolDialog::NewAnnotToolDialog( QWidget *parent )
 {
     setCaption( i18n("Create annotation tool") );
     setButtons( Ok | Cancel );
-    enableButton( Ok, false );
     setDefaultButton( Ok );
 
     QLabel * tmplabel;
@@ -201,7 +200,6 @@ NewAnnotToolDialog::NewAnnotToolDialog( QWidget *parent )
     setMainWidget(widget);
 
     m_name = new KLineEdit( widget );
-    connect( m_name, SIGNAL( textEdited(const QString &) ), this, SLOT( slotNameEdited(const QString &) ) );
     tmplabel = new QLabel( i18n( "&Name:" ), widget );
     tmplabel->setBuddy( m_name );
     widgetLayout->addWidget( tmplabel, 0, 0, Qt::AlignRight );
@@ -234,6 +232,7 @@ NewAnnotToolDialog::NewAnnotToolDialog( QWidget *parent )
     m_type->addItem( i18n("Stamp") );
 
     rebuildAppearanceBox();
+    updateDefaultName();
 }
 
 NewAnnotToolDialog::~NewAnnotToolDialog()
@@ -243,7 +242,10 @@ NewAnnotToolDialog::~NewAnnotToolDialog()
 
 QString NewAnnotToolDialog::name() const
 {
-    return m_name->text();
+    QString userText = m_name->text();
+    if ( userText.isEmpty() )
+        userText = m_name->placeholderText();
+    return userText;
 }
 
 QString NewAnnotToolDialog::toolXml() const
@@ -381,13 +383,53 @@ void NewAnnotToolDialog::rebuildAppearanceBox()
     m_annotationWidget = AnnotationWidgetFactory::widgetFor( m_stubann );
     m_appearanceBox->layout()->addWidget( m_annotationWidget->appearanceWidget() );
 
-    // Tell the widget to mirror changes back in the stub annotation
-    connect( m_annotationWidget, SIGNAL(dataChanged()), m_annotationWidget, SLOT(applyChanges()) );
+    connect( m_annotationWidget, SIGNAL(dataChanged()), this, SLOT(slotDataChanged()) );
 }
 
-void NewAnnotToolDialog::slotNameEdited( const QString &new_name )
+void NewAnnotToolDialog::updateDefaultName()
 {
-    enableButton( Ok, !new_name.isEmpty() );
+    QString defaultName = m_type->currentText();
+
+    switch ( m_type->currentIndex() )
+    {
+        case 5:
+        {
+            // Text Markup
+            Okular::HighlightAnnotation * ha = static_cast<Okular::HighlightAnnotation*>( m_stubann );
+
+            switch ( ha->highlightType() )
+            {
+                case Okular::HighlightAnnotation::Highlight:
+                    defaultName = i18n( "Highlight" );
+                    break;
+                case Okular::HighlightAnnotation::Squiggly:
+                    defaultName = i18n( "Squiggly" );
+                    break;
+                case Okular::HighlightAnnotation::Underline:
+                    defaultName = i18n( "Underline" );
+                    break;
+                case Okular::HighlightAnnotation::StrikeOut:
+                    defaultName = i18n( "Strike out" );
+                    break;
+            }
+
+            break;
+        }
+        case 6:
+        {
+            // Geometrical shape
+            Okular::GeomAnnotation * ga = static_cast<Okular::GeomAnnotation*>( m_stubann );
+
+            if ( ga->geometricalType() == Okular::GeomAnnotation::InscribedCircle )
+                defaultName = i18n( "Ellipse" );
+            else
+                defaultName = i18n( "Rectangle" );
+
+            break;
+        }
+    }
+
+    m_name->setPlaceholderText( defaultName );
 }
 
 void NewAnnotToolDialog::slotTypeChanged( int index )
@@ -464,6 +506,15 @@ void NewAnnotToolDialog::slotTypeChanged( int index )
 
     m_stubann->style().setColor( Qt::yellow ); // TODO: Choose default color according to annotation type
     rebuildAppearanceBox();
+    updateDefaultName();
+}
+
+void NewAnnotToolDialog::slotDataChanged()
+{
+    // Mirror changes back in the stub annotation
+    m_annotationWidget->applyChanges();
+
+    updateDefaultName();
 }
 
 #include "moc_widgetannottools.cpp"
diff --git a/conf/widgetannottools.h b/conf/widgetannottools.h
index 8b7653a..15a394f 100644
--- a/conf/widgetannottools.h
+++ b/conf/widgetannottools.h
@@ -66,6 +66,7 @@ class NewAnnotToolDialog : public KDialog
 
     private:
         void rebuildAppearanceBox();
+        void updateDefaultName();
 
         KLineEdit * m_name;
         KComboBox * m_type;
@@ -75,8 +76,8 @@ class NewAnnotToolDialog : public KDialog
         AnnotationWidget *m_annotationWidget;
 
     private slots:
-        void slotNameEdited( const QString &new_name );
         void slotTypeChanged( int index );
+        void slotDataChanged();
 };
 
 #endif
diff --git a/ui/annotationwidgets.h b/ui/annotationwidgets.h
index a6df239..298b914 100644
--- a/ui/annotationwidgets.h
+++ b/ui/annotationwidgets.h
@@ -80,7 +80,6 @@ public:
     QWidget * appearanceWidget();
     QWidget * extraWidget();
 
-public slots:
     virtual void applyChanges();
 
 signals:
-- 
1.7.6.5


From 469f7d889aa8b769805a207fec168e8f5cfcbbcd Mon Sep 17 00:00:00 2001
From: Fabio D'Urso <fabiodurso at hotmail.it>
Date: Fri, 27 Jul 2012 03:04:36 +0200
Subject: [PATCH 23/43] Fixed PolyLine engine to create open paths

The existing code didn't work, bacause right clicks are not routed
to the annotator engine (see PageViewAnnotator::routeEvent).
With this patch, polylines can be ended with a double-click.
---
 ui/pageviewannotator.cpp |    8 +++++---
 1 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/ui/pageviewannotator.cpp b/ui/pageviewannotator.cpp
index fcbc720..a67af32 100644
--- a/ui/pageviewannotator.cpp
+++ b/ui/pageviewannotator.cpp
@@ -292,7 +292,7 @@ class PolyLineEngine : public AnnotatorEngine
             // numofpoints represents the max number of points for the current
             // polygon/polyline, with a pair of exceptions:
             // -1 means: the polyline must close on the first point (polygon)
-            // 0 means: construct as many points as you want, right-click
+            // 0 means: construct as many points as you want, double-click
             //   to construct the last point
             numofpoints = engineElement.attribute( "points" ).toInt( &ok );
             if ( !ok )
@@ -310,8 +310,6 @@ class PolyLineEngine : public AnnotatorEngine
             {
                 newPoint.x = nX;
                 newPoint.y = nY;
-                if ( button == Right )
-                    last = true;
             }
             // move the second point
             else if ( type == Move )
@@ -334,6 +332,10 @@ class PolyLineEngine : public AnnotatorEngine
                 {
                     last = true;
                 }
+                else if ( numofpoints == 0 && points.count() > 1 && ( fabs( points.last().x - newPoint.x + points.last().y - newPoint.y ) < 1e-2 ) )
+                {
+                    last = true;
+                }
                 else
                 {
                     points.append( newPoint );
-- 
1.7.6.5


From 9b34fa8b05823ad72a26eefbf0c957c7e79f1d85 Mon Sep 17 00:00:00 2001
From: Fabio D'Urso <fabiodurso at hotmail.it>
Date: Fri, 27 Jul 2012 03:22:22 +0200
Subject: [PATCH 24/43] Added Polyline tool to create open paths

It has the same icon that Straight line used to have.
Straight line's icon was changed to a single segment.
---
 conf/widgetannottools.cpp |   36 ++++++++++++++++++++++++++++++------
 ui/pageviewannotator.cpp  |   18 ++++++++++++------
 2 files changed, 42 insertions(+), 12 deletions(-)

diff --git a/conf/widgetannottools.cpp b/conf/widgetannottools.cpp
index 80fe72e..9a3d90a 100644
--- a/conf/widgetannottools.cpp
+++ b/conf/widgetannottools.cpp
@@ -227,6 +227,7 @@ NewAnnotToolDialog::NewAnnotToolDialog( QWidget *parent )
     m_type->addItem( i18n("Freehand Line") );
     m_type->addItem( i18n("Straight Line") );
     m_type->addItem( i18n("Polygon") );
+    m_type->addItem( i18n("Polyline") );
     m_type->addItem( i18n("Text markup") );
     m_type->addItem( i18n("Geometrical shape") );
     m_type->addItem( i18n("Stamp") );
@@ -312,6 +313,17 @@ QString NewAnnotToolDialog::toolXml() const
         }
         case 5:
         {
+            // Polyline
+            Okular::LineAnnotation * la = static_cast<Okular::LineAnnotation*>( m_stubann );
+            Q_UNUSED( la );
+            return QString( "<tool type=\"polyline\">"
+                             "<engine type=\"PolyLine\" color=\"%1\" points=\"0\">"
+                              "<annotation type=\"Line\" color=\"%1\" opacity=\"%2\" width=\"%3\" />"
+                             "</engine>"
+                            "</tool>" ).arg( color ).arg( opacity ).arg( width );
+        }
+        case 6:
+        {
             // Text Markup
             Okular::HighlightAnnotation * ha = static_cast<Okular::HighlightAnnotation*>( m_stubann );
 
@@ -343,7 +355,7 @@ QString NewAnnotToolDialog::toolXml() const
                             "</tool>").arg( color ).arg( opacity )
                                       .arg( toolType ).arg( annotationType );
         }
-        case 6:
+        case 7:
         {
             // Geometrical shape
             Okular::GeomAnnotation * ga = static_cast<Okular::GeomAnnotation*>( m_stubann );
@@ -356,7 +368,7 @@ QString NewAnnotToolDialog::toolXml() const
                                       .arg( isCircle ? "ellipse" : "rectangle" )
                                       .arg( isCircle ? "GeomCircle" : "GeomSquare" );
         }
-        case 7:
+        case 8:
         {
             // Stamp
             Okular::StampAnnotation * sa = static_cast<Okular::StampAnnotation*>( m_stubann );
@@ -392,7 +404,7 @@ void NewAnnotToolDialog::updateDefaultName()
 
     switch ( m_type->currentIndex() )
     {
-        case 5:
+        case 6:
         {
             // Text Markup
             Okular::HighlightAnnotation * ha = static_cast<Okular::HighlightAnnotation*>( m_stubann );
@@ -415,7 +427,7 @@ void NewAnnotToolDialog::updateDefaultName()
 
             break;
         }
-        case 6:
+        case 7:
         {
             // Geometrical shape
             Okular::GeomAnnotation * ga = static_cast<Okular::GeomAnnotation*>( m_stubann );
@@ -479,22 +491,34 @@ void NewAnnotToolDialog::slotTypeChanged( int index )
                                     Okular::NormalizedPoint(0,0) <<
                                     Okular::NormalizedPoint(1,0) <<
                                     Okular::NormalizedPoint(1,1) );
+            la->setLineClosed( true );
             m_stubann = la;
             break;
         }
         case 5:
         {
+            // Polyline
+            Okular::LineAnnotation * la = new Okular::LineAnnotation();
+            la->setLinePoints( QLinkedList<Okular::NormalizedPoint>() <<
+                                    Okular::NormalizedPoint(0,0) <<
+                                    Okular::NormalizedPoint(1,0) <<
+                                    Okular::NormalizedPoint(1,1) );
+            m_stubann = la;
+            break;
+        }
+        case 6:
+        {
             // Text Markup
             m_stubann = new Okular::HighlightAnnotation();
             break;
         }
-        case 6:
+        case 7:
         {
             // Geometrical shape
             m_stubann = new Okular::GeomAnnotation();
             break;
         }
-        case 7:
+        case 8:
         {
             // Stamp
             Okular::StampAnnotation * sa = new Okular::StampAnnotation();
diff --git a/ui/pageviewannotator.cpp b/ui/pageviewannotator.cpp
index a67af32..688a64e 100644
--- a/ui/pageviewannotator.cpp
+++ b/ui/pageviewannotator.cpp
@@ -1021,6 +1021,17 @@ QPixmap PageViewAnnotator::makeToolPixmap( const QDomElement &toolElement )
             p.setPen( QPen( engineColor, 1 ) );
             p.drawPath( path );
         }
+        else if ( annotType == "polyline" )
+        {
+            QPainterPath path;
+            path.moveTo( 1, 8 );
+            path.lineTo( 20, 8 );
+            path.lineTo( 1, 27 );
+            path.lineTo( 20, 27 );
+            p.setRenderHint( QPainter::Antialiasing );
+            p.setPen( QPen( engineColor, 1 ) );
+            p.drawPath( path );
+        }
         else if ( annotType == "rectangle" )
         {
             p.setRenderHint( QPainter::Antialiasing );
@@ -1037,14 +1048,9 @@ QPixmap PageViewAnnotator::makeToolPixmap( const QDomElement &toolElement )
         }
         else if ( annotType == "straight-line" )
         {
-            QPainterPath path;
-            path.moveTo( 1, 8 );
-            path.lineTo( 20, 8 );
-            path.lineTo( 1, 27 );
-            path.lineTo( 20, 27 );
             p.setRenderHint( QPainter::Antialiasing );
             p.setPen( QPen( engineColor, 1 ) );
-            p.drawPath( path ); // TODO To be discussed: This is not a straight line!
+            p.drawLine( 4, 22, 24, 10 );
         }
         else if ( annotType == "strikeout" )
         {
-- 
1.7.6.5


From 98c23ad1c82e0b233e9cbffe056ef1e22930071b Mon Sep 17 00:00:00 2001
From: Fabio D'Urso <fabiodurso at hotmail.it>
Date: Fri, 27 Jul 2012 04:06:39 +0200
Subject: [PATCH 25/43] Configurable innerColor in GeomAnnotation tools
 (rectangle, ellipse)

---
 conf/widgetannottools.cpp |   10 ++++++++--
 ui/pageviewannotator.cpp  |   15 ++++++++++++++-
 2 files changed, 22 insertions(+), 3 deletions(-)

diff --git a/conf/widgetannottools.cpp b/conf/widgetannottools.cpp
index 9a3d90a..81a6a60 100644
--- a/conf/widgetannottools.cpp
+++ b/conf/widgetannottools.cpp
@@ -359,14 +359,20 @@ QString NewAnnotToolDialog::toolXml() const
         {
             // Geometrical shape
             Okular::GeomAnnotation * ga = static_cast<Okular::GeomAnnotation*>( m_stubann );
+
             const bool isCircle = (ga->geometricalType() == Okular::GeomAnnotation::InscribedCircle);
+            QString innerColor;
+            if ( ga->geometricalInnerColor().isValid() )
+                innerColor = QString( "innerColor=\"%1\"" ).arg( ga->geometricalInnerColor().name() );
+
             return QString( "<tool type=\"%4\">"
                              "<engine type=\"PickPoint\" color=\"%1\" block=\"true\">"
-                              "<annotation type=\"%5\" color=\"%1\" opacity=\"%2\" width=\"%3\" />"
+                              "<annotation type=\"%5\" color=\"%1\" opacity=\"%2\" width=\"%3\" %6 />"
                              "</engine>"
                             "</tool>").arg( color ).arg( opacity ).arg( width )
                                       .arg( isCircle ? "ellipse" : "rectangle" )
-                                      .arg( isCircle ? "GeomCircle" : "GeomSquare" );
+                                      .arg( isCircle ? "GeomCircle" : "GeomSquare" )
+                                      .arg( innerColor );
         }
         case 8:
         {
diff --git a/ui/pageviewannotator.cpp b/ui/pageviewannotator.cpp
index 688a64e..41dfab1 100644
--- a/ui/pageviewannotator.cpp
+++ b/ui/pageviewannotator.cpp
@@ -243,6 +243,8 @@ class PickPointEngine : public AnnotatorEngine
                     ga->setGeometricalType( Okular::GeomAnnotation::InscribedCircle );
                 if ( m_annotElement.hasAttribute( "width" ) )
                     ann->style().setWidth( m_annotElement.attribute( "width" ).toDouble() );
+                if ( m_annotElement.hasAttribute( "innerColor" ) )
+                    ga->setGeometricalInnerColor( QColor( m_annotElement.attribute( "innerColor" ) ) );
                 //set boundary
                 rect.left = qMin( startpoint.x, point.x );
                 rect.top = qMin( startpoint.y, point.y );
@@ -960,7 +962,7 @@ QPixmap PageViewAnnotator::makeToolPixmap( const QDomElement &toolElement )
         pixmap.load( KStandardDirs::locate("data", "okular/pics/tool-base-okular.png" ) );
 
         /* Parse the color */
-        QColor engineColor;
+        QColor engineColor, innerColor;
         QDomNodeList engineNodeList = toolElement.elementsByTagName( "engine" );
         if ( engineNodeList.size() > 0 )
         {
@@ -968,12 +970,21 @@ QPixmap PageViewAnnotator::makeToolPixmap( const QDomElement &toolElement )
             if ( !engineEl.isNull() && engineEl.hasAttribute( "color" ) )
                 engineColor = QColor( engineEl.attribute( "color" ) );
         }
+        QDomNodeList annotationNodeList = toolElement.elementsByTagName( "annotation" );
+        if ( annotationNodeList.size() > 0 )
+        {
+            QDomElement annotationEl = annotationNodeList.item( 0 ).toElement();
+            if ( !annotationEl.isNull() && annotationEl.hasAttribute( "innerColor" ) )
+                innerColor = QColor( annotationEl.attribute( "innerColor" ) );
+        }
 
         QPainter p( &pixmap );
 
         if ( annotType == "ellipse" )
         {
             p.setRenderHint( QPainter::Antialiasing );
+            if ( innerColor.isValid() )
+                p.setBrush( innerColor );
             p.setPen( QPen( engineColor, 2 ) );
             p.drawEllipse( 2, 7, 21, 14 );
         }
@@ -1035,6 +1046,8 @@ QPixmap PageViewAnnotator::makeToolPixmap( const QDomElement &toolElement )
         else if ( annotType == "rectangle" )
         {
             p.setRenderHint( QPainter::Antialiasing );
+            if ( innerColor.isValid() )
+                p.setBrush( innerColor );
             p.setPen( QPen( engineColor, 2 ) );
             p.drawRect( 2, 7, 21, 14 );
         }
-- 
1.7.6.5


From 9a1a008f9b4525ac46928dd4e10c58f1a16d892d Mon Sep 17 00:00:00 2001
From: Fabio D'Urso <fabiodurso at hotmail.it>
Date: Fri, 27 Jul 2012 04:39:14 +0200
Subject: [PATCH 26/43] Made polygon annotations' inner color configurable

---
 conf/widgetannottools.cpp |   11 +++++--
 ui/annotationwidgets.cpp  |   77 +++++++++++++++++++++++++++++++++------------
 ui/annotationwidgets.h    |    2 +
 ui/pageviewannotator.cpp  |    6 +++
 4 files changed, 73 insertions(+), 23 deletions(-)

diff --git a/conf/widgetannottools.cpp b/conf/widgetannottools.cpp
index 81a6a60..a7b4147 100644
--- a/conf/widgetannottools.cpp
+++ b/conf/widgetannottools.cpp
@@ -304,12 +304,17 @@ QString NewAnnotToolDialog::toolXml() const
         {
             // Polygon
             Okular::LineAnnotation * la = static_cast<Okular::LineAnnotation*>( m_stubann );
-            Q_UNUSED( la );
+
+            QString innerColor;
+            if ( la->lineInnerColor().isValid() )
+                innerColor = QString( "innerColor=\"%1\"" ).arg( la->lineInnerColor().name() );
+
             return QString( "<tool type=\"polygon\">"
                              "<engine type=\"PolyLine\" color=\"%1\" points=\"-1\">"
-                              "<annotation type=\"Line\" color=\"%1\" opacity=\"%2\" width=\"%3\" />"
+                              "<annotation type=\"Line\" color=\"%1\" opacity=\"%2\" width=\"%3\" %4 />"
                              "</engine>"
-                            "</tool>" ).arg( color ).arg( opacity ).arg( width );
+                            "</tool>" ).arg( color ).arg( opacity ).arg( width )
+                                       .arg( innerColor );
         }
         case 5:
         {
diff --git a/ui/annotationwidgets.cpp b/ui/annotationwidgets.cpp
index afcffaa..277d3ed 100644
--- a/ui/annotationwidgets.cpp
+++ b/ui/annotationwidgets.cpp
@@ -371,20 +371,20 @@ QWidget * LineAnnotationWidget::createStyleWidget()
     lay->setMargin( 0 );
     if ( m_lineType == 0 )
     {
-    QGroupBox * gb = new QGroupBox( widget );
-    lay->addWidget( gb );
-    gb->setTitle( i18n( "Line Extensions" ) );
-    QGridLayout * gridlay = new QGridLayout( gb );
-    QLabel * tmplabel = new QLabel( i18n( "Leader Line Length:" ), gb );
-    gridlay->addWidget( tmplabel, 0, 0, Qt::AlignRight );
-    m_spinLL = new QDoubleSpinBox( gb );
-    gridlay->addWidget( m_spinLL, 0, 1 );
-    tmplabel->setBuddy( m_spinLL );
-    tmplabel = new QLabel( i18n( "Leader Line Extensions Length:" ), gb );
-    gridlay->addWidget( tmplabel, 1, 0, Qt::AlignRight );
-    m_spinLLE = new QDoubleSpinBox( gb );
-    gridlay->addWidget( m_spinLLE, 1, 1 );
-    tmplabel->setBuddy( m_spinLLE );
+        QGroupBox * gb = new QGroupBox( widget );
+        lay->addWidget( gb );
+        gb->setTitle( i18n( "Line Extensions" ) );
+        QGridLayout * gridlay = new QGridLayout( gb );
+        QLabel * tmplabel = new QLabel( i18n( "Leader Line Length:" ), gb );
+        gridlay->addWidget( tmplabel, 0, 0, Qt::AlignRight );
+        m_spinLL = new QDoubleSpinBox( gb );
+        gridlay->addWidget( m_spinLL, 0, 1 );
+        tmplabel->setBuddy( m_spinLL );
+        tmplabel = new QLabel( i18n( "Leader Line Extensions Length:" ), gb );
+        gridlay->addWidget( tmplabel, 1, 0, Qt::AlignRight );
+        m_spinLLE = new QDoubleSpinBox( gb );
+        gridlay->addWidget( m_spinLLE, 1, 1 );
+        tmplabel->setBuddy( m_spinLLE );
     }
 
     QGroupBox * gb2 = new QGroupBox( widget );
@@ -397,20 +397,46 @@ QWidget * LineAnnotationWidget::createStyleWidget()
     gridlay2->addWidget( m_spinSize, 0, 1 );
     tmplabel2->setBuddy( m_spinSize );
 
+    if ( m_lineType == 1 )
+    {
+        m_useColor = new QCheckBox( i18n( "Inner color:" ), gb2 );
+        gridlay2->addWidget( m_useColor, 1, 0 );
+        m_innerColor = new KColorButton( gb2 );
+        gridlay2->addWidget( m_innerColor, 1, 1 );
+    }
+
     if ( m_lineType == 0 )
     {
-    m_spinLL->setRange( -500, 500 );
-    m_spinLL->setValue( m_lineAnn->lineLeadingForwardPoint() );
-    m_spinLLE->setRange( 0, 500 );
-    m_spinLLE->setValue( m_lineAnn->lineLeadingBackwardPoint() );
+        m_spinLL->setRange( -500, 500 );
+        m_spinLL->setValue( m_lineAnn->lineLeadingForwardPoint() );
+        m_spinLLE->setRange( 0, 500 );
+        m_spinLLE->setValue( m_lineAnn->lineLeadingBackwardPoint() );
+    }
+    else if ( m_lineType == 1 )
+    {
+        m_innerColor->setColor( m_lineAnn->lineInnerColor() );
+        if ( m_lineAnn->lineInnerColor().isValid() )
+        {
+            m_useColor->setChecked( true );
+        }
+        else
+        {
+            m_innerColor->setEnabled( false );
+        }
     }
     m_spinSize->setRange( 1, 100 );
     m_spinSize->setValue( m_lineAnn->style().width() );
 
     if ( m_lineType == 0 )
     {
-    connect( m_spinLL, SIGNAL(valueChanged(double)), this, SIGNAL(dataChanged()) );
-    connect( m_spinLLE, SIGNAL(valueChanged(double)), this, SIGNAL(dataChanged()) );
+        connect( m_spinLL, SIGNAL(valueChanged(double)), this, SIGNAL(dataChanged()) );
+        connect( m_spinLLE, SIGNAL(valueChanged(double)), this, SIGNAL(dataChanged()) );
+    }
+    else if ( m_lineType == 1 )
+    {
+        connect( m_innerColor, SIGNAL(changed(QColor)), this, SIGNAL(dataChanged()) );
+        connect( m_useColor, SIGNAL(toggled(bool)), this, SIGNAL(dataChanged()) );
+        connect( m_useColor, SIGNAL(toggled(bool)), m_innerColor, SLOT(setEnabled(bool)) );
     }
     connect( m_spinSize, SIGNAL(valueChanged(double)), this, SIGNAL(dataChanged()) );
 
@@ -425,6 +451,17 @@ void LineAnnotationWidget::applyChanges()
         m_lineAnn->setLineLeadingForwardPoint( m_spinLL->value() );
         m_lineAnn->setLineLeadingBackwardPoint( m_spinLLE->value() );
     }
+    else if ( m_lineType == 1 )
+    {
+        if ( !m_useColor->isChecked() )
+        {
+            m_lineAnn->setLineInnerColor( QColor() );
+        }
+        else
+        {
+            m_lineAnn->setLineInnerColor( m_innerColor->color() );
+        }
+    }
     m_lineAnn->style().setWidth( m_spinSize->value() );
 }
 
diff --git a/ui/annotationwidgets.h b/ui/annotationwidgets.h
index 298b914..e11153d 100644
--- a/ui/annotationwidgets.h
+++ b/ui/annotationwidgets.h
@@ -153,6 +153,8 @@ private:
     int m_lineType;
     QDoubleSpinBox * m_spinLL;
     QDoubleSpinBox * m_spinLLE;
+    QCheckBox * m_useColor;
+    KColorButton * m_innerColor;
     QDoubleSpinBox * m_spinSize;
 };
 
diff --git a/ui/pageviewannotator.cpp b/ui/pageviewannotator.cpp
index 41dfab1..97f798e 100644
--- a/ui/pageviewannotator.cpp
+++ b/ui/pageviewannotator.cpp
@@ -410,7 +410,11 @@ class PolyLineEngine : public AnnotatorEngine
                 la->setLinePoints( list );
 
                 if ( numofpoints == -1 )
+                {
                     la->setLineClosed( true );
+                    if ( m_annotElement.hasAttribute( "innerColor" ) )
+                        la->setLineInnerColor( QColor( m_annotElement.attribute( "innerColor" ) ) );
+                }
 
                 la->setBoundingRectangle( normRect );
 
@@ -1029,6 +1033,8 @@ QPixmap PageViewAnnotator::makeToolPixmap( const QDomElement &toolElement )
             path.lineTo( 23, 14 );
             path.lineTo( 23, 20 );
             path.lineTo( 0, 20 );
+            if ( innerColor.isValid() )
+                p.setBrush( innerColor );
             p.setPen( QPen( engineColor, 1 ) );
             p.drawPath( path );
         }
-- 
1.7.6.5


From ae847f6f9bfea57e9c49d8dc2d4a5cffa1ca8070 Mon Sep 17 00:00:00 2001
From: Fabio D'Urso <fabiodurso at hotmail.it>
Date: Fri, 27 Jul 2012 04:45:16 +0200
Subject: [PATCH 27/43] Fill polygon annotations with their inner color in
 PagePainter (for non-PDF docs)

Note: Poppler doesn't blend multiply in this case. Maybe we can make this
annotation unbuffered in PagePainter too?
---
 ui/pagepainter.cpp |    6 +++++-
 1 files changed, 5 insertions(+), 1 deletions(-)

diff --git a/ui/pagepainter.cpp b/ui/pagepainter.cpp
index e207d78..5e86db5 100644
--- a/ui/pagepainter.cpp
+++ b/ui/pagepainter.cpp
@@ -394,11 +394,15 @@ void PagePainter::paintCroppedPageOnPainter( QPainter * destPainter, const Okula
                     }
 
                     const QPen linePen = buildPen( a, a->style().width(), a->style().color() );
+                    QBrush fillBrush;
+
+                    if ( la->lineClosed() && la->lineInnerColor().isValid() )
+                        fillBrush = QBrush( la->lineInnerColor() );
 
                     // draw the line as normalized path into image
                     drawShapeOnImage( backImage, path, la->lineClosed(),
                                       linePen,
-                                      QBrush(), pageScale ,Multiply);
+                                      fillBrush, pageScale ,Multiply);
 
                     if ( path.count() == 2 && fabs( la->lineLeadingForwardPoint() ) > 0.1 )
                     {
-- 
1.7.6.5


From 15229501bb127fe8d7c3aff00417794c59f429db Mon Sep 17 00:00:00 2001
From: Fabio D'Urso <fabiodurso at hotmail.it>
Date: Fri, 27 Jul 2012 11:22:14 +0200
Subject: [PATCH 28/43] Made line extensions configurable in the straight line
 annotation tool

---
 conf/widgetannottools.cpp |   11 ++++++++---
 ui/pageviewannotator.cpp  |    7 +++++++
 2 files changed, 15 insertions(+), 3 deletions(-)

diff --git a/conf/widgetannottools.cpp b/conf/widgetannottools.cpp
index a7b4147..e9b5727 100644
--- a/conf/widgetannottools.cpp
+++ b/conf/widgetannottools.cpp
@@ -293,12 +293,17 @@ QString NewAnnotToolDialog::toolXml() const
         {
             // Straight Line
             Okular::LineAnnotation * la = static_cast<Okular::LineAnnotation*>( m_stubann );
-            Q_UNUSED( la );
+
+            QString lineExt;
+            if ( la->lineLeadingForwardPoint() != 0 || la->lineLeadingBackwardPoint() != 0 )
+                lineExt = QString( "leadFwd=\"%1\" leadBack=\"%2\"" ).arg( la->lineLeadingForwardPoint() ).arg( la->lineLeadingBackwardPoint() );
+
             return QString( "<tool type=\"straight-line\">"
                              "<engine type=\"PolyLine\" color=\"%1\" points=\"2\">"
-                              "<annotation type=\"Line\" color=\"%1\" opacity=\"%2\" width=\"%3\" />"
+                              "<annotation type=\"Line\" color=\"%1\" opacity=\"%2\" width=\"%3\" %4 />"
                              "</engine>"
-                            "</tool>" ).arg( color ).arg( opacity ).arg( width );
+                            "</tool>" ).arg( color ).arg( opacity ).arg( width )
+                                       .arg( lineExt );
         }
         case 4:
         {
diff --git a/ui/pageviewannotator.cpp b/ui/pageviewannotator.cpp
index 97f798e..a89fca1 100644
--- a/ui/pageviewannotator.cpp
+++ b/ui/pageviewannotator.cpp
@@ -415,6 +415,13 @@ class PolyLineEngine : public AnnotatorEngine
                     if ( m_annotElement.hasAttribute( "innerColor" ) )
                         la->setLineInnerColor( QColor( m_annotElement.attribute( "innerColor" ) ) );
                 }
+                else if ( numofpoints == 2 )
+                {
+                    if ( m_annotElement.hasAttribute( "leadFwd" ) )
+                        la->setLineLeadingForwardPoint( m_annotElement.attribute( "leadFwd" ).toDouble() );
+                    if ( m_annotElement.hasAttribute( "leadBack" ) )
+                        la->setLineLeadingBackwardPoint( m_annotElement.attribute( "leadBack" ).toDouble() );
+                }
 
                 la->setBoundingRectangle( normRect );
 
-- 
1.7.6.5


From d94a640dc71726194fdb914acc7ce71a56b473f2 Mon Sep 17 00:00:00 2001
From: Fabio D'Urso <fabiodurso at hotmail.it>
Date: Fri, 27 Jul 2012 11:37:05 +0200
Subject: [PATCH 29/43] Set new tools' default values the same values as
 predefined tools

---
 conf/widgetannottools.cpp |   16 ++++++++++++++--
 1 files changed, 14 insertions(+), 2 deletions(-)

diff --git a/conf/widgetannottools.cpp b/conf/widgetannottools.cpp
index e9b5727..f444ba0 100644
--- a/conf/widgetannottools.cpp
+++ b/conf/widgetannottools.cpp
@@ -472,6 +472,8 @@ void NewAnnotToolDialog::slotTypeChanged( int index )
             // Note
             Okular::TextAnnotation * ta = new Okular::TextAnnotation();
             ta->setTextType( Okular::TextAnnotation::Linked );
+            ta->setTextIcon( "Note" );
+            ta->style().setColor( Qt::yellow );
             m_stubann = ta;
             break;
         }
@@ -480,6 +482,7 @@ void NewAnnotToolDialog::slotTypeChanged( int index )
             // Inline Note
             Okular::TextAnnotation * ta = new Okular::TextAnnotation();
             ta->setTextType( Okular::TextAnnotation::InPlace );
+            ta->style().setColor( Qt::yellow );
             m_stubann = ta;
             break;
         }
@@ -487,6 +490,8 @@ void NewAnnotToolDialog::slotTypeChanged( int index )
         {
             // Freehand Line
             m_stubann = new Okular::InkAnnotation();
+            m_stubann->style().setWidth( 2.0 );
+            m_stubann->style().setColor( Qt::green );
             break;
         }
         case 3:
@@ -496,6 +501,7 @@ void NewAnnotToolDialog::slotTypeChanged( int index )
             la->setLinePoints( QLinkedList<Okular::NormalizedPoint>() <<
                                     Okular::NormalizedPoint(0,0) <<
                                     Okular::NormalizedPoint(1,0) );
+            la->style().setColor( QColor( 0xff, 0xe0, 0x00 ) );
             m_stubann = la;
             break;
         }
@@ -508,6 +514,7 @@ void NewAnnotToolDialog::slotTypeChanged( int index )
                                     Okular::NormalizedPoint(1,0) <<
                                     Okular::NormalizedPoint(1,1) );
             la->setLineClosed( true );
+            la->style().setColor( QColor( 0x00, 0x7e, 0xee ) );
             m_stubann = la;
             break;
         }
@@ -519,6 +526,7 @@ void NewAnnotToolDialog::slotTypeChanged( int index )
                                     Okular::NormalizedPoint(0,0) <<
                                     Okular::NormalizedPoint(1,0) <<
                                     Okular::NormalizedPoint(1,1) );
+            la->style().setColor( QColor( 0xff, 0xe0, 0x00 ) );
             m_stubann = la;
             break;
         }
@@ -526,12 +534,17 @@ void NewAnnotToolDialog::slotTypeChanged( int index )
         {
             // Text Markup
             m_stubann = new Okular::HighlightAnnotation();
+            m_stubann->style().setColor( Qt::yellow );
             break;
         }
         case 7:
         {
             // Geometrical shape
-            m_stubann = new Okular::GeomAnnotation();
+            Okular::GeomAnnotation * ga = new Okular::GeomAnnotation();
+            ga->setGeometricalType( Okular::GeomAnnotation::InscribedCircle );
+            ga->style().setWidth( 5.0 );
+            ga->style().setColor( Qt::cyan );
+            m_stubann = ga;
             break;
         }
         case 8:
@@ -544,7 +557,6 @@ void NewAnnotToolDialog::slotTypeChanged( int index )
         }
     }
 
-    m_stubann->style().setColor( Qt::yellow ); // TODO: Choose default color according to annotation type
     rebuildAppearanceBox();
     updateDefaultName();
 }
-- 
1.7.6.5


From 9430e56d5a3da33c3a5dcb8410d06b357aa2f59f Mon Sep 17 00:00:00 2001
From: Fabio D'Urso <fabiodurso at hotmail.it>
Date: Fri, 27 Jul 2012 11:59:46 +0200
Subject: [PATCH 30/43] Moved (and partly rewritten) annotation tooltips from
 tools.xml to pageviewannotator

Two purposes:
 - Have tooltips available even for user-created annotations (not just
   the predefined ones)
 - Avoid i18n strings in settings (NOTE: the "name" attribute will be
   removed in next patch)

Some tooltips were created over new (eg for new tools), some were
rewritten to actually give instructions instead of repeating the name of
the tool, some were rewritten to avoid references to colors (because
colors are no longer fixed)
---
 conf/okular.kcfg         |    8 --------
 ui/data/tools.xml        |    9 ---------
 ui/pageviewannotator.cpp |   39 +++++++++++++++++++++++++++++++++------
 3 files changed, 33 insertions(+), 23 deletions(-)

diff --git a/conf/okular.kcfg b/conf/okular.kcfg
index 157a63c..9e6a8eb 100644
--- a/conf/okular.kcfg
+++ b/conf/okular.kcfg
@@ -332,14 +332,6 @@
                   {
                       // Translate strings
                       toolElement.setAttribute( "name", i18n( toolElement.attribute("name").toUtf8() ) );
-                      QDomNode tooltip = toolElement.elementsByTagName( "tooltip" ).item( 0 );
-                      if ( tooltip.isElement() )
-                      {
-                          QDomElement trTooltip = doc.createElement( "tooltip" );
-                          QString trTooltipStr = i18nc( "Annotation tool",  tooltip.toElement().text().toUtf8() );
-                          trTooltip.appendChild( doc.createTextNode( trTooltipStr ) );
-                          toolElement.replaceChild( tooltip, trTooltip );
-                      }
 
                       QDomDocument temp;
                       temp.appendChild( temp.importNode( toolElement, true) );
diff --git a/ui/data/tools.xml b/ui/data/tools.xml
index cc9b8cd..70a1a5a 100644
--- a/ui/data/tools.xml
+++ b/ui/data/tools.xml
@@ -18,63 +18,54 @@ Engine/Annotation Types [specific attributes]:
 -->
 <annotatingTools>
     <tool id="1" name="Note" type="note-linked">
-        <tooltip>Text Annotation</tooltip>
         <engine type="PickPoint" color="#FFFF00" hoverIcon="tool-note">
             <annotation type="Text" color="#FFFF00" icon="Note" />
         </engine>
         <shortcut>1</shortcut>
     </tool>
     <tool id="2" name="Inline Note" type="note-inline">
-        <tooltip>Inline Text Annotation (drag to select a zone)</tooltip>
         <engine type="PickPoint" color="#FFFF00" hoverIcon="tool-note-inline" block="true">
             <annotation type="FreeText" color="#FFFF00" />
         </engine>
         <shortcut>2</shortcut>
     </tool>
     <tool id="3" name="Green Freehand Line" type="ink">
-        <tooltip>Green Ink</tooltip>
         <engine type="SmoothLine" color="#00FF00">
             <annotation type="Ink" color="#00FF00" width="2" />
         </engine>
         <shortcut>3</shortcut>
     </tool>
     <tool id="4" name="Yellow Highlighter" type="highlight">
-        <tooltip>Yellow Highlight</tooltip>
         <engine type="TextSelector" color="#FFFF00">
             <annotation type="Highlight" color="#FFFF00" />
         </engine>
         <shortcut>4</shortcut>
     </tool>
     <tool id="5" name="Straight Yellow Line" type="straight-line">
-        <tooltip>Straight Yellow Line</tooltip>
         <engine type="PolyLine" color="#FFE000" points="2">
             <annotation type="Line" width="1" color="#FFE000" />
         </engine>
         <shortcut>5</shortcut>
     </tool>
     <tool id="6" name="Blue Polygon" type="polygon">
-        <tooltip>Draw a polygon (click on the first point to close it)</tooltip>
         <engine type="PolyLine" color="#007EEE" points="-1">
             <annotation type="Line" width="1" color="#007EEE" />
         </engine>
         <shortcut>6</shortcut>
     </tool>
     <tool id="7" name="Stamp" type="stamp">
-        <tooltip>Put a stamp symbol</tooltip>
         <engine type="PickPoint" hoverIcon="okular" size="64" block="true">
             <annotation type="Stamp" icon="okular"/>
         </engine>
         <shortcut>7</shortcut>
   </tool>
     <tool id="8" name="Black Underlining" type="underline">
-        <tooltip>Underline the text with a black line</tooltip>
         <engine type="TextSelector" color="#000000">
             <annotation type="Underline" color="#000000" />
         </engine>
         <shortcut>8</shortcut>
     </tool>
     <tool id="9" name="Cyan Ellipse" type="ellipse">
-        <tooltip>A cyan ellipse</tooltip>
         <engine type="PickPoint" color="#00ffff" block="true">
             <annotation type="GeomCircle" width="5" color="#00ffff" />
         </engine>
diff --git a/ui/pageviewannotator.cpp b/ui/pageviewannotator.cpp
index a89fca1..9d324d5 100644
--- a/ui/pageviewannotator.cpp
+++ b/ui/pageviewannotator.cpp
@@ -921,13 +921,40 @@ void PageViewAnnotator::slotToolSelected( int toolID )
                 else
                     kWarning().nospace() << "tools.xml: engine type:'" << type << "' is not defined!";
             }
+
             // display the tooltip
-            else if ( toolSubElement.tagName() == "tooltip" )
-            {
-                QString tip = toolSubElement.text();
-                if ( !tip.isEmpty() )
-                    m_pageView->displayMessage( tip, QString(), PageViewMessage::Annotation );
-            }
+            const QString annotType = toolElement.attribute( "type" );
+            QString tip;
+
+            if ( annotType == "ellipse" )
+                tip = i18nc( "Annotation tool", "Draw an ellipse (drag to select a zone)" );
+            else if ( annotType == "highlight" )
+                tip = i18nc( "Annotation tool", "Highlight text" );
+            else if ( annotType == "ink" )
+                tip = i18nc( "Annotation tool", "Draw a freehand line" );
+            else if ( annotType == "note-inline" )
+                tip = i18nc( "Annotation tool", "Inline Text Annotation (drag to select a zone)" );
+            else if ( annotType == "note-linked" )
+                tip = i18nc( "Annotation tool", "Put a pop-up note" );
+            else if ( annotType == "polygon" )
+                tip = i18nc( "Annotation tool", "Draw a polygon (click on the first point to close it)" );
+            else if ( annotType == "polyline" )
+                tip = i18nc( "Annotation tool", "Draw a polyline (double-click to finish)" );
+            else if ( annotType == "rectangle" )
+                tip = i18nc( "Annotation tool", "Draw a rectangle" );
+            else if ( annotType == "squiggly" )
+                tip = i18nc( "Annotation tool", "Squiggle text" );
+            else if ( annotType == "stamp" )
+                tip = i18nc( "Annotation tool", "Put a stamp symbol" );
+            else if ( annotType == "straight-line" )
+                tip = i18nc( "Annotation tool", "Draw a straight line" );
+            else if ( annotType == "strikeout" )
+                tip = i18nc( "Annotation tool", "Strike out text" );
+            else if ( annotType == "underline" )
+                tip = i18nc( "Annotation tool", "Underline text" );
+
+            if ( !tip.isEmpty() )
+                m_pageView->displayMessage( tip, QString(), PageViewMessage::Annotation );
         }
 
         // consistancy warning
-- 
1.7.6.5


From 5206df7a0ced1308d0346ef5032c0b8658faea2b Mon Sep 17 00:00:00 2001
From: Fabio D'Urso <fabiodurso at hotmail.it>
Date: Fri, 27 Jul 2012 12:36:53 +0200
Subject: [PATCH 31/43] Allow nameless tools (which default to predefined
 names)

Removed name attribute from default tools (ie those from tools.xml), so
that they now get default names, which automatically translated if the
application language is switched.

With this patch, tools.xml no longer contains strings to be translated.

NOTE: Messages.sh was not tested
---
 Messages.sh               |    2 -
 conf/okular.kcfg          |    3 --
 conf/settings.kcfgc       |    2 +-
 conf/widgetannottools.cpp |   70 ++++++++++++--------------------------------
 ui/data/tools.xml         |   18 ++++++------
 ui/pageviewannotator.cpp  |   39 ++++++++++++++++++++++++-
 ui/pageviewannotator.h    |    1 +
 7 files changed, 68 insertions(+), 67 deletions(-)

diff --git a/Messages.sh b/Messages.sh
index 6d0d0b0..d4a4705 100644
--- a/Messages.sh
+++ b/Messages.sh
@@ -1,6 +1,4 @@
 #!/bin/sh
 $EXTRACTRC *.rc */*.rc >> rc.cpp || exit 11
 $EXTRACTRC $(find conf/ -name "*.ui") $(find core/ -name "*.ui") $(find ui/ -name "*.ui") $(ls . | grep -E '\.ui') >> rc.cpp || exit 12
-$EXTRACTRC --tag=tooltip --context='Annotation tool' ui/data/tools.xml >> rc.cpp || exit 13
-$EXTRACTATTR -attr=tool,name ui/data/tools.xml >> rc.cpp || exit 14
 $XGETTEXT $(find conf/ -name "*.cpp" -o -name "*.h") $(find core/ -name "*.cpp" -o -name "*.h") $(find ui/ -name "*.cpp" -o -name "*.h") $(find shell/ -name "*.cpp" -o -name "*.h") $(ls . | grep -E '\.cpp$') $(ls . | grep -E '\.h$') -o $podir/okular.pot
diff --git a/conf/okular.kcfg b/conf/okular.kcfg
index 9e6a8eb..a151a13 100644
--- a/conf/okular.kcfg
+++ b/conf/okular.kcfg
@@ -330,9 +330,6 @@
                   QDomElement toolElement = toolDescription.toElement();
                   if ( toolElement.tagName() == "tool" )
                   {
-                      // Translate strings
-                      toolElement.setAttribute( "name", i18n( toolElement.attribute("name").toUtf8() ) );
-
                       QDomDocument temp;
                       temp.appendChild( temp.importNode( toolElement, true) );
                       // add each <tool>...</tool> as XML string
diff --git a/conf/settings.kcfgc b/conf/settings.kcfgc
index ab9b051..86c161b 100644
--- a/conf/settings.kcfgc
+++ b/conf/settings.kcfgc
@@ -5,5 +5,5 @@ Mutators=true
 Singleton=true
 Visibility=OKULAR_EXPORT
 IncludeFiles=core/okular_export.h
-SourceIncludeFiles=klocalizedstring.h,kstandarddirs.h,qdom.h
+SourceIncludeFiles=kstandarddirs.h,qdom.h
 MemberVariables=dpointer
diff --git a/conf/widgetannottools.cpp b/conf/widgetannottools.cpp
index f444ba0..2aafd63 100644
--- a/conf/widgetannottools.cpp
+++ b/conf/widgetannottools.cpp
@@ -56,7 +56,7 @@ WidgetAnnotTools::~WidgetAnnotTools()
     delete m_ui;
 }
 
-/* Before returning the XML strings, this functions updates the name, id and
+/* Before returning the XML strings, this functions updates the id and
  * shortcut properties.
  * Note: The shortcut is only assigned to the first nine tools */
 QStringList WidgetAnnotTools::tools() const
@@ -72,9 +72,8 @@ QStringList WidgetAnnotTools::tools() const
         QDomDocument doc;
         doc.setContent( listEntry->data( Qt::UserRole ).value<QString>() );
 
-        // Set name and id
+        // Set id
         QDomElement toolElement = doc.documentElement();
-        toolElement.setAttribute( "name", listEntry->text() );
         toolElement.setAttribute( "id", i+1 );
 
         // Remove old shortcut, if any
@@ -112,7 +111,9 @@ void WidgetAnnotTools::setTools(const QStringList& items)
         if ( toolElement.tagName() == "tool" )
         {
             // Create list item and attach the source XML string as data
-            const QString itemText = toolElement.attribute( "name" );
+            QString itemText = toolElement.attribute( "name" );
+            if ( itemText.isEmpty() )
+                itemText = PageViewAnnotator::defaultToolName( toolElement );
             QListWidgetItem * listEntry = new QListWidgetItem( itemText, m_ui->list );
             listEntry->setData( Qt::UserRole, qVariantFromValue(toolXml) );
             listEntry->setIcon( PageViewAnnotator::makeToolPixmap( toolElement ) );
@@ -148,8 +149,16 @@ void WidgetAnnotTools::slotAdd( bool )
     entryParser.setContent( t.toolXml() );
     QDomElement toolElement = entryParser.documentElement();
 
+    QString itemText = t.name();
+
+    // Store name attribute only if the user specified a customized name
+    if ( !itemText.isEmpty() )
+        toolElement.setAttribute( "name", itemText );
+    else
+        itemText = PageViewAnnotator::defaultToolName( toolElement );
+
     // Create list entry and attach XML string as data
-    QListWidgetItem * listEntry = new QListWidgetItem( t.name(), m_ui->list );
+    QListWidgetItem * listEntry = new QListWidgetItem( itemText, m_ui->list );
     listEntry->setData( Qt::UserRole, qVariantFromValue( entryParser.toString(-1) ) );
     listEntry->setIcon( PageViewAnnotator::makeToolPixmap( toolElement ) );
 
@@ -243,10 +252,7 @@ NewAnnotToolDialog::~NewAnnotToolDialog()
 
 QString NewAnnotToolDialog::name() const
 {
-    QString userText = m_name->text();
-    if ( userText.isEmpty() )
-        userText = m_name->placeholderText();
-    return userText;
+    return m_name->text();
 }
 
 QString NewAnnotToolDialog::toolXml() const
@@ -416,48 +422,10 @@ void NewAnnotToolDialog::rebuildAppearanceBox()
 
 void NewAnnotToolDialog::updateDefaultName()
 {
-    QString defaultName = m_type->currentText();
-
-    switch ( m_type->currentIndex() )
-    {
-        case 6:
-        {
-            // Text Markup
-            Okular::HighlightAnnotation * ha = static_cast<Okular::HighlightAnnotation*>( m_stubann );
-
-            switch ( ha->highlightType() )
-            {
-                case Okular::HighlightAnnotation::Highlight:
-                    defaultName = i18n( "Highlight" );
-                    break;
-                case Okular::HighlightAnnotation::Squiggly:
-                    defaultName = i18n( "Squiggly" );
-                    break;
-                case Okular::HighlightAnnotation::Underline:
-                    defaultName = i18n( "Underline" );
-                    break;
-                case Okular::HighlightAnnotation::StrikeOut:
-                    defaultName = i18n( "Strike out" );
-                    break;
-            }
-
-            break;
-        }
-        case 7:
-        {
-            // Geometrical shape
-            Okular::GeomAnnotation * ga = static_cast<Okular::GeomAnnotation*>( m_stubann );
-
-            if ( ga->geometricalType() == Okular::GeomAnnotation::InscribedCircle )
-                defaultName = i18n( "Ellipse" );
-            else
-                defaultName = i18n( "Rectangle" );
-
-            break;
-        }
-    }
-
-    m_name->setPlaceholderText( defaultName );
+    QDomDocument entryParser;
+    entryParser.setContent( toolXml() );
+    QDomElement toolElement = entryParser.documentElement();
+    m_name->setPlaceholderText( PageViewAnnotator::defaultToolName( toolElement ) );
 }
 
 void NewAnnotToolDialog::slotTypeChanged( int index )
diff --git a/ui/data/tools.xml b/ui/data/tools.xml
index 70a1a5a..2e7aeea 100644
--- a/ui/data/tools.xml
+++ b/ui/data/tools.xml
@@ -17,55 +17,55 @@ Engine/Annotation Types [specific attributes]:
     Geom
 -->
 <annotatingTools>
-    <tool id="1" name="Note" type="note-linked">
+    <tool id="1" type="note-linked">
         <engine type="PickPoint" color="#FFFF00" hoverIcon="tool-note">
             <annotation type="Text" color="#FFFF00" icon="Note" />
         </engine>
         <shortcut>1</shortcut>
     </tool>
-    <tool id="2" name="Inline Note" type="note-inline">
+    <tool id="2" type="note-inline">
         <engine type="PickPoint" color="#FFFF00" hoverIcon="tool-note-inline" block="true">
             <annotation type="FreeText" color="#FFFF00" />
         </engine>
         <shortcut>2</shortcut>
     </tool>
-    <tool id="3" name="Green Freehand Line" type="ink">
+    <tool id="3" type="ink">
         <engine type="SmoothLine" color="#00FF00">
             <annotation type="Ink" color="#00FF00" width="2" />
         </engine>
         <shortcut>3</shortcut>
     </tool>
-    <tool id="4" name="Yellow Highlighter" type="highlight">
+    <tool id="4" type="highlight">
         <engine type="TextSelector" color="#FFFF00">
             <annotation type="Highlight" color="#FFFF00" />
         </engine>
         <shortcut>4</shortcut>
     </tool>
-    <tool id="5" name="Straight Yellow Line" type="straight-line">
+    <tool id="5" type="straight-line">
         <engine type="PolyLine" color="#FFE000" points="2">
             <annotation type="Line" width="1" color="#FFE000" />
         </engine>
         <shortcut>5</shortcut>
     </tool>
-    <tool id="6" name="Blue Polygon" type="polygon">
+    <tool id="6" type="polygon">
         <engine type="PolyLine" color="#007EEE" points="-1">
             <annotation type="Line" width="1" color="#007EEE" />
         </engine>
         <shortcut>6</shortcut>
     </tool>
-    <tool id="7" name="Stamp" type="stamp">
+    <tool id="7" type="stamp">
         <engine type="PickPoint" hoverIcon="okular" size="64" block="true">
             <annotation type="Stamp" icon="okular"/>
         </engine>
         <shortcut>7</shortcut>
   </tool>
-    <tool id="8" name="Black Underlining" type="underline">
+    <tool id="8" type="underline">
         <engine type="TextSelector" color="#000000">
             <annotation type="Underline" color="#000000" />
         </engine>
         <shortcut>8</shortcut>
     </tool>
-    <tool id="9" name="Cyan Ellipse" type="ellipse">
+    <tool id="9" type="ellipse">
         <engine type="PickPoint" color="#00ffff" block="true">
             <annotation type="GeomCircle" width="5" color="#00ffff" />
         </engine>
diff --git a/ui/pageviewannotator.cpp b/ui/pageviewannotator.cpp
index 9d324d5..ef91161 100644
--- a/ui/pageviewannotator.cpp
+++ b/ui/pageviewannotator.cpp
@@ -657,7 +657,10 @@ void PageViewAnnotator::reparseConfig()
         {
             AnnotationToolItem item;
             item.id = toolElement.attribute("id").toInt();
-            item.text = toolElement.attribute( "name" );
+            if ( toolElement.hasAttribute( "name" ) )
+                item.text = toolElement.attribute( "name" );
+            else
+                item.text = defaultToolName( toolElement );
             item.pixmap = makeToolPixmap( toolElement );
             QDomNode shortcutNode = toolElement.elementsByTagName( "shortcut" ).item( 0 );
             if ( shortcutNode.isElement() )
@@ -984,6 +987,40 @@ void PageViewAnnotator::detachAnnotation()
     m_toolBar->selectButton( -1 );
 }
 
+QString PageViewAnnotator::defaultToolName( const QDomElement &toolElement )
+{
+    const QString annotType = toolElement.attribute( "type" );
+
+    if ( annotType == "ellipse" )
+        return i18n( "Ellipse" );
+    else if ( annotType == "highlight" )
+        return i18n( "Highlight" );
+    else if ( annotType == "ink" )
+        return i18n( "Freehand Line" );
+    else if ( annotType == "note-inline" )
+        return i18n( "Inline Note" );
+    else if ( annotType == "note-linked" )
+        return i18n( "Note" );
+    else if ( annotType == "polygon" )
+        return i18n( "Polygon" );
+    else if ( annotType == "polyline" )
+        return i18n( "Polyline" );
+    else if ( annotType == "rectangle" )
+        return i18n( "Rectangle" );
+    else if ( annotType == "squiggly" )
+        return i18n( "Squiggly" );
+    else if ( annotType == "stamp" )
+        return i18n( "Stamp" );
+    else if ( annotType == "straight-line" )
+        return i18n( "Straight Line" );
+    else if ( annotType == "strikeout" )
+        return i18n( "Strike out" );
+    else if ( annotType == "underline" )
+        return i18n( "Underline" );
+    else
+        return QString();
+}
+
 QPixmap PageViewAnnotator::makeToolPixmap( const QDomElement &toolElement )
 {
     QPixmap pixmap(32, 32);
diff --git a/ui/pageviewannotator.h b/ui/pageviewannotator.h
index a1fb9e5..568555b 100644
--- a/ui/pageviewannotator.h
+++ b/ui/pageviewannotator.h
@@ -70,6 +70,7 @@ class PageViewAnnotator : public QObject
 
         void reparseConfig();
 
+        static QString defaultToolName( const QDomElement &toolElement );
         static QPixmap makeToolPixmap( const QDomElement &toolElement );
 
     private slots:
-- 
1.7.6.5


From 7318a38c46b85f14dced335c75efc1dd5b42d60e Mon Sep 17 00:00:00 2001
From: Fabio D'Urso <fabiodurso at hotmail.it>
Date: Fri, 27 Jul 2012 14:04:47 +0200
Subject: [PATCH 32/43] Create tool XML entries via DOM methods

---
 conf/widgetannottools.cpp |  198 +++++++++++++++++++++++++-------------------
 conf/widgetannottools.h   |    3 +-
 2 files changed, 114 insertions(+), 87 deletions(-)

diff --git a/conf/widgetannottools.cpp b/conf/widgetannottools.cpp
index 2aafd63..234a87e 100644
--- a/conf/widgetannottools.cpp
+++ b/conf/widgetannottools.cpp
@@ -145,9 +145,8 @@ void WidgetAnnotTools::slotAdd( bool )
     if ( t.exec() != QDialog::Accepted )
         return;
 
-    QDomDocument entryParser;
-    entryParser.setContent( t.toolXml() );
-    QDomElement toolElement = entryParser.documentElement();
+    QDomDocument rootDoc = t.toolXml();
+    QDomElement toolElement = rootDoc.documentElement();
 
     QString itemText = t.name();
 
@@ -159,7 +158,7 @@ void WidgetAnnotTools::slotAdd( bool )
 
     // Create list entry and attach XML string as data
     QListWidgetItem * listEntry = new QListWidgetItem( itemText, m_ui->list );
-    listEntry->setData( Qt::UserRole, qVariantFromValue( entryParser.toString(-1) ) );
+    listEntry->setData( Qt::UserRole, qVariantFromValue( rootDoc.toString(-1) ) );
     listEntry->setIcon( PageViewAnnotator::makeToolPixmap( toolElement ) );
 
     // Select and scroll
@@ -255,8 +254,16 @@ QString NewAnnotToolDialog::name() const
     return m_name->text();
 }
 
-QString NewAnnotToolDialog::toolXml() const
+QDomDocument NewAnnotToolDialog::toolXml() const
 {
+    QDomDocument doc;
+    QDomElement toolElement = doc.createElement( "tool" );
+    QDomElement engineElement = doc.createElement( "engine" );
+    QDomElement annotationElement = doc.createElement( "annotation" );
+    doc.appendChild( toolElement );
+    toolElement.appendChild( engineElement );
+    engineElement.appendChild( annotationElement );
+
     const QString color = m_stubann->style().color().name();
     const double opacity = m_stubann->style().opacity();
     const double width = m_stubann->style().width();
@@ -267,142 +274,162 @@ QString NewAnnotToolDialog::toolXml() const
         {
             // Note
             Okular::TextAnnotation * ta = static_cast<Okular::TextAnnotation*>( m_stubann );
-            return QString( "<tool type=\"note-linked\">"
-                             "<engine type=\"PickPoint\" color=\"%1\" hoverIcon=\"tool-note\">"
-                              "<annotation type=\"Text\" color=\"%1\" opacity=\"%2\" icon=\"%3\" />"
-                             "</engine>"
-                            "</tool>" ).arg( color ).arg( opacity ).arg( ta->textIcon() );
+            toolElement.setAttribute( "type", "note-linked" );
+            engineElement.setAttribute( "type", "PickPoint" );
+            engineElement.setAttribute( "color", color );
+            engineElement.setAttribute( "hoverIcon", "tool-note" );
+            annotationElement.setAttribute( "type", "Text" );
+            annotationElement.setAttribute( "color", color );
+            annotationElement.setAttribute( "icon", ta->textIcon() );
+            break;
         }
         case 1:
         {
             // Inline Note
             Okular::TextAnnotation * ta = static_cast<Okular::TextAnnotation*>( m_stubann );
-            Q_UNUSED( ta );
-            return QString( "<tool type=\"note-inline\">"
-                             "<engine type=\"PickPoint\" color=\"%1\" hoverIcon=\"tool-note-inline\" block=\"true\">"
-                              "<annotation type=\"FreeText\" color=\"%1\" opacity=\"%2\" />"
-                             "</engine>"
-                            "</tool>" ).arg( color ).arg( opacity );
+            toolElement.setAttribute( "type", "note-inline" );
+            engineElement.setAttribute( "type", "PickPoint" );
+            engineElement.setAttribute( "color", color );
+            engineElement.setAttribute( "hoverIcon", "tool-note-inline" );
+            engineElement.setAttribute( "block", "true" );
+            annotationElement.setAttribute( "type", "FreeText" );
+            annotationElement.setAttribute( "color", color );
+            // TODO: Font
+            break;
         }
         case 2:
         {
             // Freehand Line
-            Okular::InkAnnotation * ia = static_cast<Okular::InkAnnotation*>( m_stubann );
-            Q_UNUSED( ia );
-            return QString( "<tool type=\"ink\">"
-                             "<engine type=\"SmoothLine\" color=\"%1\">"
-                              "<annotation type=\"Ink\" color=\"%1\" opacity=\"%2\" width=\"%3\" />"
-                             "</engine>"
-                            "</tool>").arg( color ).arg( opacity ).arg( width );
+            toolElement.setAttribute( "type", "ink" );
+            engineElement.setAttribute( "type", "SmoothLine" );
+            engineElement.setAttribute( "color", color );
+            annotationElement.setAttribute( "type", "Ink" );
+            annotationElement.setAttribute( "color", color );
+            annotationElement.setAttribute( "width", width );
+            break;
         }
         case 3:
         {
             // Straight Line
             Okular::LineAnnotation * la = static_cast<Okular::LineAnnotation*>( m_stubann );
-
-            QString lineExt;
+            toolElement.setAttribute( "type", "straight-line" );
+            engineElement.setAttribute( "type", "PolyLine" );
+            engineElement.setAttribute( "color", color );
+            engineElement.setAttribute( "points", "2" );
+            annotationElement.setAttribute( "type", "Line" );
+            annotationElement.setAttribute( "color", color );
+            annotationElement.setAttribute( "width", width );
             if ( la->lineLeadingForwardPoint() != 0 || la->lineLeadingBackwardPoint() != 0 )
-                lineExt = QString( "leadFwd=\"%1\" leadBack=\"%2\"" ).arg( la->lineLeadingForwardPoint() ).arg( la->lineLeadingBackwardPoint() );
-
-            return QString( "<tool type=\"straight-line\">"
-                             "<engine type=\"PolyLine\" color=\"%1\" points=\"2\">"
-                              "<annotation type=\"Line\" color=\"%1\" opacity=\"%2\" width=\"%3\" %4 />"
-                             "</engine>"
-                            "</tool>" ).arg( color ).arg( opacity ).arg( width )
-                                       .arg( lineExt );
+            {
+                annotationElement.setAttribute( "leadFwd", la->lineLeadingForwardPoint() );
+                annotationElement.setAttribute( "leadBack", la->lineLeadingBackwardPoint() );
+            }
+            break;
         }
         case 4:
         {
             // Polygon
             Okular::LineAnnotation * la = static_cast<Okular::LineAnnotation*>( m_stubann );
-
-            QString innerColor;
+            toolElement.setAttribute( "type", "polygon" );
+            engineElement.setAttribute( "type", "PolyLine" );
+            engineElement.setAttribute( "color", color );
+            engineElement.setAttribute( "points", "-1" );
+            annotationElement.setAttribute( "type", "Line" );
+            annotationElement.setAttribute( "color", color );
+            annotationElement.setAttribute( "width", width );
             if ( la->lineInnerColor().isValid() )
-                innerColor = QString( "innerColor=\"%1\"" ).arg( la->lineInnerColor().name() );
-
-            return QString( "<tool type=\"polygon\">"
-                             "<engine type=\"PolyLine\" color=\"%1\" points=\"-1\">"
-                              "<annotation type=\"Line\" color=\"%1\" opacity=\"%2\" width=\"%3\" %4 />"
-                             "</engine>"
-                            "</tool>" ).arg( color ).arg( opacity ).arg( width )
-                                       .arg( innerColor );
+            {
+                annotationElement.setAttribute( "innerColor", la->lineInnerColor().name() );
+            }
+            break;
         }
         case 5:
         {
             // Polyline
-            Okular::LineAnnotation * la = static_cast<Okular::LineAnnotation*>( m_stubann );
-            Q_UNUSED( la );
-            return QString( "<tool type=\"polyline\">"
-                             "<engine type=\"PolyLine\" color=\"%1\" points=\"0\">"
-                              "<annotation type=\"Line\" color=\"%1\" opacity=\"%2\" width=\"%3\" />"
-                             "</engine>"
-                            "</tool>" ).arg( color ).arg( opacity ).arg( width );
+            toolElement.setAttribute( "type", "polyline" );
+            engineElement.setAttribute( "type", "PolyLine" );
+            engineElement.setAttribute( "color", color );
+            engineElement.setAttribute( "points", "0" );
+            annotationElement.setAttribute( "type", "Line" );
+            annotationElement.setAttribute( "color", color );
+            annotationElement.setAttribute( "width", width );
+            break;
         }
         case 6:
         {
             // Text Markup
             Okular::HighlightAnnotation * ha = static_cast<Okular::HighlightAnnotation*>( m_stubann );
 
-            QString toolType, annotationType;
             switch ( ha->highlightType() )
             {
                 case Okular::HighlightAnnotation::Highlight:
-                    toolType = "highlight";
-                    annotationType = "Highlight";
+                    toolElement.setAttribute( "type", "highlight" );
+                    annotationElement.setAttribute( "type", "Highlight" );
                     break;
                 case Okular::HighlightAnnotation::Squiggly:
-                    toolType = "squiggly";
-                    annotationType = "Squiggly";
+                    toolElement.setAttribute( "type", "squiggly" );
+                    annotationElement.setAttribute( "type", "Squiggly" );
                     break;
                 case Okular::HighlightAnnotation::Underline:
-                    toolType = "underline";
-                    annotationType = "Underline";
+                    toolElement.setAttribute( "type", "underline" );
+                    annotationElement.setAttribute( "type", "Underline" );
                     break;
                 case Okular::HighlightAnnotation::StrikeOut:
-                    toolType = "strikeout";
-                    annotationType = "StrikeOut";
+                    toolElement.setAttribute( "type", "strikeout" );
+                    annotationElement.setAttribute( "type", "StrikeOut" );
                     break;
             }
 
-            return QString( "<tool type=\"%3\">"
-                             "<engine type=\"TextSelector\" color=\"%1\">"
-                              "<annotation type=\"%4\" color=\"%1\" opacity=\"%2\" />"
-                             "</engine>"
-                            "</tool>").arg( color ).arg( opacity )
-                                      .arg( toolType ).arg( annotationType );
+            engineElement.setAttribute( "type", "TextSelector" );
+            engineElement.setAttribute( "color", color );
+            annotationElement.setAttribute( "color", color );
+            break;
         }
         case 7:
         {
             // Geometrical shape
             Okular::GeomAnnotation * ga = static_cast<Okular::GeomAnnotation*>( m_stubann );
 
-            const bool isCircle = (ga->geometricalType() == Okular::GeomAnnotation::InscribedCircle);
-            QString innerColor;
+            if ( ga->geometricalType() == Okular::GeomAnnotation::InscribedCircle )
+            {
+                toolElement.setAttribute( "type", "ellipse" );
+                annotationElement.setAttribute( "type", "GeomCircle" );
+            }
+            else
+            {
+                toolElement.setAttribute( "type", "rectangle" );
+                annotationElement.setAttribute( "type", "GeomSquare" );
+            }
+
+            engineElement.setAttribute( "type", "PickPoint" );
+            engineElement.setAttribute( "color", color );
+            engineElement.setAttribute( "block", "true" );
+            annotationElement.setAttribute( "color", color );
+            annotationElement.setAttribute( "width", width );
+
             if ( ga->geometricalInnerColor().isValid() )
-                innerColor = QString( "innerColor=\"%1\"" ).arg( ga->geometricalInnerColor().name() );
-
-            return QString( "<tool type=\"%4\">"
-                             "<engine type=\"PickPoint\" color=\"%1\" block=\"true\">"
-                              "<annotation type=\"%5\" color=\"%1\" opacity=\"%2\" width=\"%3\" %6 />"
-                             "</engine>"
-                            "</tool>").arg( color ).arg( opacity ).arg( width )
-                                      .arg( isCircle ? "ellipse" : "rectangle" )
-                                      .arg( isCircle ? "GeomCircle" : "GeomSquare" )
-                                      .arg( innerColor );
+                annotationElement.setAttribute( "innerColor", ga->geometricalInnerColor().name() );
+            break;
         }
         case 8:
         {
             // Stamp
             Okular::StampAnnotation * sa = static_cast<Okular::StampAnnotation*>( m_stubann );
-            return QString( "<tool type=\"stamp\">"
-                             "<engine type=\"PickPoint\" hoverIcon=\"%1\" size=\"64\" block=\"true\">"
-                              "<annotation type=\"Stamp\" icon=\"%1\"/>"
-                             "</engine>"
-                            "</tool>" ).arg( sa->stampIconName() ); // FIXME: Check bad strings
+            toolElement.setAttribute( "type", "stamp" );
+            engineElement.setAttribute( "type", "PickPoint" );
+            engineElement.setAttribute( "hoverIcon", sa->stampIconName() );
+            engineElement.setAttribute( "size", "64" );
+            engineElement.setAttribute( "block", "true" );
+            annotationElement.setAttribute( "type", "Stamp" );
+            annotationElement.setAttribute( "icon", sa->stampIconName() );
+            break;
         }
     }
 
-    return QString(); // This should never happen
+    if ( opacity != 1 )
+        annotationElement.setAttribute( "opacity", opacity );
+
+    return doc;
 }
 
 void NewAnnotToolDialog::rebuildAppearanceBox()
@@ -422,9 +449,8 @@ void NewAnnotToolDialog::rebuildAppearanceBox()
 
 void NewAnnotToolDialog::updateDefaultName()
 {
-    QDomDocument entryParser;
-    entryParser.setContent( toolXml() );
-    QDomElement toolElement = entryParser.documentElement();
+    QDomDocument doc = toolXml();
+    QDomElement toolElement = doc.documentElement();
     m_name->setPlaceholderText( PageViewAnnotator::defaultToolName( toolElement ) );
 }
 
diff --git a/conf/widgetannottools.h b/conf/widgetannottools.h
index 15a394f..0c389bb 100644
--- a/conf/widgetannottools.h
+++ b/conf/widgetannottools.h
@@ -11,6 +11,7 @@
 #define _WIDGETANNOTTOOLS_H_
 
 #include <kdialog.h>
+#include <qdom.h>
 #include <qwidget.h>
 
 class KLineEdit;
@@ -62,7 +63,7 @@ class NewAnnotToolDialog : public KDialog
         NewAnnotToolDialog( QWidget *parent = 0 );
         ~NewAnnotToolDialog();
         QString name() const;
-        QString toolXml() const;
+        QDomDocument toolXml() const;
 
     private:
         void rebuildAppearanceBox();
-- 
1.7.6.5


From c6a38dc565f80daa488995176a794d7a1cf16cb6 Mon Sep 17 00:00:00 2001
From: Fabio D'Urso <fabiodurso at hotmail.it>
Date: Fri, 27 Jul 2012 14:47:55 +0200
Subject: [PATCH 33/43] Added support to edit existing annotation tools,
 renamed NewAnnotToolDialog to EditAnnotToolDialog

---
 conf/widgetannottools.cpp |  163 ++++++++++++++++++++++++++++++++++++++++++---
 conf/widgetannottools.h   |    8 ++-
 2 files changed, 158 insertions(+), 13 deletions(-)

diff --git a/conf/widgetannottools.cpp b/conf/widgetannottools.cpp
index 234a87e..bd91b00 100644
--- a/conf/widgetannottools.cpp
+++ b/conf/widgetannottools.cpp
@@ -44,6 +44,7 @@ WidgetAnnotTools::WidgetAnnotTools( QWidget * parent )
     m_ui->btnMoveDown->setIcon( KIcon("arrow-down") );
     m_ui->btnMoveDown->setEnabled( false );
 
+    connect( m_ui->list, SIGNAL( itemDoubleClicked(QListWidgetItem*) ), this, SLOT( slotItemDoubleClicked(QListWidgetItem*) ) );
     connect( m_ui->list, SIGNAL( currentRowChanged(int) ), this, SLOT( slotRowChanged(int) ) );
     connect( m_ui->btnAdd, SIGNAL( clicked(bool) ), this, SLOT( slotAdd(bool) ) );
     connect( m_ui->btnRemove, SIGNAL( clicked(bool) ), this, SLOT( slotRemove(bool) ) );
@@ -133,6 +134,40 @@ void WidgetAnnotTools::updateButtons()
     m_ui->btnMoveDown->setEnabled( row != -1 && row != last );
 }
 
+void WidgetAnnotTools::slotItemDoubleClicked( QListWidgetItem *listEntry )
+{
+    QDomDocument doc;
+    doc.setContent( listEntry->data( Qt::UserRole ).value<QString>() );
+    QDomElement toolElement = doc.documentElement();
+
+    EditAnnotToolDialog t( this, toolElement );
+
+    if ( t.exec() != QDialog::Accepted )
+        return;
+
+    doc = t.toolXml();
+    toolElement = doc.documentElement();
+
+    QString itemText = t.name();
+
+    // Store name attribute only if the user specified a customized name
+    if ( !itemText.isEmpty() )
+        toolElement.setAttribute( "name", itemText );
+    else
+        itemText = PageViewAnnotator::defaultToolName( toolElement );
+
+    // Create list entry and attach XML string as data
+    listEntry->setText( itemText );
+    listEntry->setData( Qt::UserRole, qVariantFromValue( doc.toString(-1) ) );
+    listEntry->setIcon( PageViewAnnotator::makeToolPixmap( toolElement ) );
+
+    // Select and scroll
+    m_ui->list->setCurrentItem( listEntry );
+    m_ui->list->scrollToItem( listEntry );
+    updateButtons();
+    emit changed();
+}
+
 void WidgetAnnotTools::slotRowChanged( int )
 {
     updateButtons();
@@ -140,7 +175,7 @@ void WidgetAnnotTools::slotRowChanged( int )
 
 void WidgetAnnotTools::slotAdd( bool )
 {
-    NewAnnotToolDialog t( this );
+    EditAnnotToolDialog t( this );
 
     if ( t.exec() != QDialog::Accepted )
         return;
@@ -194,10 +229,9 @@ void WidgetAnnotTools::slotMoveDown( bool )
     emit changed();
 }
 
-NewAnnotToolDialog::NewAnnotToolDialog( QWidget *parent )
+EditAnnotToolDialog::EditAnnotToolDialog( QWidget *parent, const QDomElement &initialState )
     : KDialog( parent ), m_annotationWidget( 0 )
 {
-    setCaption( i18n("Create annotation tool") );
     setButtons( Ok | Cancel );
     setDefaultButton( Ok );
 
@@ -240,21 +274,31 @@ NewAnnotToolDialog::NewAnnotToolDialog( QWidget *parent )
     m_type->addItem( i18n("Geometrical shape") );
     m_type->addItem( i18n("Stamp") );
 
+    if ( initialState.isNull() )
+    {
+        setCaption( i18n("Create annotation tool") );
+    }
+    else
+    {
+        setCaption( i18n("Edit annotation tool") );
+        loadTool( initialState );
+    }
+
     rebuildAppearanceBox();
     updateDefaultName();
 }
 
-NewAnnotToolDialog::~NewAnnotToolDialog()
+EditAnnotToolDialog::~EditAnnotToolDialog()
 {
     delete m_annotationWidget;
 }
 
-QString NewAnnotToolDialog::name() const
+QString EditAnnotToolDialog::name() const
 {
     return m_name->text();
 }
 
-QDomDocument NewAnnotToolDialog::toolXml() const
+QDomDocument EditAnnotToolDialog::toolXml() const
 {
     QDomDocument doc;
     QDomElement toolElement = doc.createElement( "tool" );
@@ -432,7 +476,7 @@ QDomDocument NewAnnotToolDialog::toolXml() const
     return doc;
 }
 
-void NewAnnotToolDialog::rebuildAppearanceBox()
+void EditAnnotToolDialog::rebuildAppearanceBox()
 {
     // Remove previous widget (if any)
     if ( m_annotationWidget )
@@ -447,14 +491,113 @@ void NewAnnotToolDialog::rebuildAppearanceBox()
     connect( m_annotationWidget, SIGNAL(dataChanged()), this, SLOT(slotDataChanged()) );
 }
 
-void NewAnnotToolDialog::updateDefaultName()
+void EditAnnotToolDialog::updateDefaultName()
 {
     QDomDocument doc = toolXml();
     QDomElement toolElement = doc.documentElement();
     m_name->setPlaceholderText( PageViewAnnotator::defaultToolName( toolElement ) );
 }
 
-void NewAnnotToolDialog::slotTypeChanged( int index )
+void EditAnnotToolDialog::loadTool( const QDomElement &toolElement )
+{
+    const QDomElement engineElement = toolElement.elementsByTagName( "engine" ).item( 0 ).toElement();
+    const QDomElement annotationElement = engineElement.elementsByTagName( "annotation" ).item( 0 ).toElement();
+    const QString annotType = toolElement.attribute( "type" );
+
+    if ( annotType == "ellipse" )
+    {
+        m_type->setCurrentIndex( 7 ); // Geometrical shape
+        Okular::GeomAnnotation * ga = static_cast<Okular::GeomAnnotation*>( m_stubann );
+        ga->setGeometricalType( Okular::GeomAnnotation::InscribedCircle );
+        if ( annotationElement.hasAttribute( "innerColor" ) )
+            ga->setGeometricalInnerColor( QColor( annotationElement.attribute( "innerColor" ) ) );
+    }
+    else if ( annotType == "highlight" )
+    {
+        m_type->setCurrentIndex( 6 ); // Text markup
+        Okular::HighlightAnnotation * ha = static_cast<Okular::HighlightAnnotation*>( m_stubann );
+        ha->setHighlightType( Okular::HighlightAnnotation::Highlight );
+    }
+    else if ( annotType == "ink" )
+    {
+        m_type->setCurrentIndex( 2 ); // Freehand line
+    }
+    else if ( annotType == "note-inline" )
+    {
+        m_type->setCurrentIndex( 1 ); // Inline note
+    }
+    else if ( annotType == "note-linked" )
+    {
+        m_type->setCurrentIndex( 0 ); // Note
+        Okular::TextAnnotation * ta = static_cast<Okular::TextAnnotation*>( m_stubann );
+        ta->setTextIcon( annotationElement.attribute( "icon" ) );
+    }
+    else if ( annotType == "polygon" )
+    {
+        m_type->setCurrentIndex( 4 ); // Polygon
+        Okular::LineAnnotation * la = static_cast<Okular::LineAnnotation*>( m_stubann );
+        if ( annotationElement.hasAttribute( "innerColor" ) )
+            la->setLineInnerColor( QColor( annotationElement.attribute( "innerColor" ) ) );
+    }
+    else if ( annotType == "polyline" )
+    {
+        m_type->setCurrentIndex( 5 ); // Polyline
+    }
+    else if ( annotType == "rectangle" )
+    {
+        m_type->setCurrentIndex( 7 ); // Geometrical shape
+        Okular::GeomAnnotation * ga = static_cast<Okular::GeomAnnotation*>( m_stubann );
+        ga->setGeometricalType( Okular::GeomAnnotation::InscribedSquare );
+        if ( annotationElement.hasAttribute( "innerColor" ) )
+            ga->setGeometricalInnerColor( QColor( annotationElement.attribute( "innerColor" ) ) );
+    }
+    else if ( annotType == "squiggly" )
+    {
+        m_type->setCurrentIndex( 6 ); // Text markup
+        Okular::HighlightAnnotation * ha = static_cast<Okular::HighlightAnnotation*>( m_stubann );
+        ha->setHighlightType( Okular::HighlightAnnotation::Squiggly );
+    }
+    else if ( annotType == "stamp" )
+    {
+        m_type->setCurrentIndex( 8 ); // Text markup
+        Okular::StampAnnotation * sa = static_cast<Okular::StampAnnotation*>( m_stubann );
+        sa->setStampIconName( annotationElement.attribute( "icon" ) );
+    }
+    else if ( annotType == "straight-line" )
+    {
+        m_type->setCurrentIndex( 3 ); // Straight line
+        Okular::LineAnnotation * la = static_cast<Okular::LineAnnotation*>( m_stubann );
+        if ( annotationElement.hasAttribute( "leadFwd" ) )
+            la->setLineLeadingForwardPoint( annotationElement.attribute( "leadFwd" ).toDouble() );
+        if ( annotationElement.hasAttribute( "leadBack" ) )
+            la->setLineLeadingBackwardPoint( annotationElement.attribute( "leadBack" ).toDouble() );
+    }
+    else if ( annotType == "strikeout" )
+    {
+        m_type->setCurrentIndex( 6 ); // Text markup
+        Okular::HighlightAnnotation * ha = static_cast<Okular::HighlightAnnotation*>( m_stubann );
+        ha->setHighlightType( Okular::HighlightAnnotation::StrikeOut );
+    }
+    else if ( annotType == "underline" )
+    {
+        m_type->setCurrentIndex( 6 ); // Text markup
+        Okular::HighlightAnnotation * ha = static_cast<Okular::HighlightAnnotation*>( m_stubann );
+        ha->setHighlightType( Okular::HighlightAnnotation::Underline );
+    }
+
+    // Common properties
+    if ( annotationElement.hasAttribute( "color" ) )
+        m_stubann->style().setColor( QColor( annotationElement.attribute( "color" ) ) );
+    if ( annotationElement.hasAttribute( "opacity" ) )
+        m_stubann->style().setOpacity( annotationElement.attribute( "opacity" ).toDouble() );
+    if ( annotationElement.hasAttribute( "width" ) )
+        m_stubann->style().setWidth( annotationElement.attribute( "width" ).toDouble() );
+
+    if ( toolElement.hasAttribute( "name" ) )
+        m_name->setText( toolElement.attribute( "name" ) );
+}
+
+void EditAnnotToolDialog::slotTypeChanged( int index )
 {
     delete m_stubann;
 
@@ -555,7 +698,7 @@ void NewAnnotToolDialog::slotTypeChanged( int index )
     updateDefaultName();
 }
 
-void NewAnnotToolDialog::slotDataChanged()
+void EditAnnotToolDialog::slotDataChanged()
 {
     // Mirror changes back in the stub annotation
     m_annotationWidget->applyChanges();
diff --git a/conf/widgetannottools.h b/conf/widgetannottools.h
index 0c389bb..b1cff4d 100644
--- a/conf/widgetannottools.h
+++ b/conf/widgetannottools.h
@@ -48,6 +48,7 @@ class WidgetAnnotTools : public QWidget
         Ui_WidgetAnnotToolsBase *m_ui;
 
     private slots:
+        void slotItemDoubleClicked( QListWidgetItem * );
         void slotRowChanged( int );
         void slotAdd( bool );
         void slotRemove( bool );
@@ -55,19 +56,20 @@ class WidgetAnnotTools : public QWidget
         void slotMoveDown( bool );
 };
 
-class NewAnnotToolDialog : public KDialog
+class EditAnnotToolDialog : public KDialog
 {
     Q_OBJECT
 
     public:
-        NewAnnotToolDialog( QWidget *parent = 0 );
-        ~NewAnnotToolDialog();
+        EditAnnotToolDialog( QWidget *parent = 0, const QDomElement &initialState = QDomElement() );
+        ~EditAnnotToolDialog();
         QString name() const;
         QDomDocument toolXml() const;
 
     private:
         void rebuildAppearanceBox();
         void updateDefaultName();
+        void loadTool( const QDomElement &toolElement );
 
         KLineEdit * m_name;
         KComboBox * m_type;
-- 
1.7.6.5


From e9d49eb60e4bb9febaa3d74d1280f3a8ef492a6d Mon Sep 17 00:00:00 2001
From: Fabio D'Urso <fabiodurso at hotmail.it>
Date: Fri, 27 Jul 2012 14:49:49 +0200
Subject: [PATCH 34/43] Put hex color codes in lower-case, so that kcfg can
 recognize default annotations

---
 ui/data/tools.xml |   24 ++++++++++++------------
 1 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/ui/data/tools.xml b/ui/data/tools.xml
index 2e7aeea..1fd5904 100644
--- a/ui/data/tools.xml
+++ b/ui/data/tools.xml
@@ -18,38 +18,38 @@ Engine/Annotation Types [specific attributes]:
 -->
 <annotatingTools>
     <tool id="1" type="note-linked">
-        <engine type="PickPoint" color="#FFFF00" hoverIcon="tool-note">
-            <annotation type="Text" color="#FFFF00" icon="Note" />
+        <engine type="PickPoint" color="#ffff00" hoverIcon="tool-note">
+            <annotation type="Text" color="#ffff00" icon="Note" />
         </engine>
         <shortcut>1</shortcut>
     </tool>
     <tool id="2" type="note-inline">
-        <engine type="PickPoint" color="#FFFF00" hoverIcon="tool-note-inline" block="true">
-            <annotation type="FreeText" color="#FFFF00" />
+        <engine type="PickPoint" color="#ffff00" hoverIcon="tool-note-inline" block="true">
+            <annotation type="FreeText" color="#ffff00" />
         </engine>
         <shortcut>2</shortcut>
     </tool>
     <tool id="3" type="ink">
-        <engine type="SmoothLine" color="#00FF00">
-            <annotation type="Ink" color="#00FF00" width="2" />
+        <engine type="SmoothLine" color="#00ff00">
+            <annotation type="Ink" color="#00ff00" width="2" />
         </engine>
         <shortcut>3</shortcut>
     </tool>
     <tool id="4" type="highlight">
-        <engine type="TextSelector" color="#FFFF00">
-            <annotation type="Highlight" color="#FFFF00" />
+        <engine type="TextSelector" color="#ffff00">
+            <annotation type="Highlight" color="#ffff00" />
         </engine>
         <shortcut>4</shortcut>
     </tool>
     <tool id="5" type="straight-line">
-        <engine type="PolyLine" color="#FFE000" points="2">
-            <annotation type="Line" width="1" color="#FFE000" />
+        <engine type="PolyLine" color="#ffe000" points="2">
+            <annotation type="Line" width="1" color="#ffe000" />
         </engine>
         <shortcut>5</shortcut>
     </tool>
     <tool id="6" type="polygon">
-        <engine type="PolyLine" color="#007EEE" points="-1">
-            <annotation type="Line" width="1" color="#007EEE" />
+        <engine type="PolyLine" color="#007eee" points="-1">
+            <annotation type="Line" width="1" color="#007eee" />
         </engine>
         <shortcut>6</shortcut>
     </tool>
-- 
1.7.6.5


From c39ff9bb45b1027c0eb98deeb33b38090b375324 Mon Sep 17 00:00:00 2001
From: Fabio D'Urso <fabiodurso at hotmail.it>
Date: Fri, 27 Jul 2012 15:46:44 +0200
Subject: [PATCH 35/43] Made font configurable in inplace text annotations

---
 conf/widgetannottools.cpp |   10 +++++++++-
 ui/pageviewannotator.cpp  |    7 +++++++
 2 files changed, 16 insertions(+), 1 deletions(-)

diff --git a/conf/widgetannottools.cpp b/conf/widgetannottools.cpp
index bd91b00..0ca3da3 100644
--- a/conf/widgetannottools.cpp
+++ b/conf/widgetannottools.cpp
@@ -338,7 +338,8 @@ QDomDocument EditAnnotToolDialog::toolXml() const
             engineElement.setAttribute( "block", "true" );
             annotationElement.setAttribute( "type", "FreeText" );
             annotationElement.setAttribute( "color", color );
-            // TODO: Font
+            if ( ta->textFont() != QApplication::font() )
+                annotationElement.setAttribute( "font", ta->textFont().toString() );
             break;
         }
         case 2:
@@ -525,6 +526,13 @@ void EditAnnotToolDialog::loadTool( const QDomElement &toolElement )
     else if ( annotType == "note-inline" )
     {
         m_type->setCurrentIndex( 1 ); // Inline note
+        Okular::TextAnnotation * ta = static_cast<Okular::TextAnnotation*>( m_stubann );
+        if ( annotationElement.hasAttribute( "font" ) )
+        {
+            QFont f;
+            f.fromString( annotationElement.attribute( "font" ) );
+            ta->setTextFont( f );
+        }
     }
     else if ( annotType == "note-linked" )
     {
diff --git a/ui/pageviewannotator.cpp b/ui/pageviewannotator.cpp
index ef91161..6fdc821 100644
--- a/ui/pageviewannotator.cpp
+++ b/ui/pageviewannotator.cpp
@@ -167,6 +167,13 @@ class PickPointEngine : public AnnotatorEngine
                     ann = ta;
                     ta->setInplaceText( note );
                     ta->setTextType( Okular::TextAnnotation::InPlace );
+                    //set font
+                    if ( m_annotElement.hasAttribute( "font" ) )
+                    {
+                        QFont f;
+                        f.fromString( m_annotElement.attribute( "font" ) );
+                        ta->setTextFont( f );
+                    }
                     //set boundary
                     rect.left = qMin(startpoint.x,point.x);
                     rect.top = qMin(startpoint.y,point.y);
-- 
1.7.6.5


From f2a5d6f1b50161f61f47316314d7c36a0e54d5db Mon Sep 17 00:00:00 2001
From: Fabio D'Urso <fabiodurso at hotmail.it>
Date: Fri, 27 Jul 2012 15:53:56 +0200
Subject: [PATCH 36/43] Show big icons in annotation tool configuration panel

---
 conf/widgetannottoolsbase.ui |    9 ++++++++-
 1 files changed, 8 insertions(+), 1 deletions(-)

diff --git a/conf/widgetannottoolsbase.ui b/conf/widgetannottoolsbase.ui
index 0a3e0ce..d81fcc3 100644
--- a/conf/widgetannottoolsbase.ui
+++ b/conf/widgetannottoolsbase.ui
@@ -11,7 +11,14 @@
   </property>
   <layout class="QHBoxLayout">
    <item>
-    <widget class="QListWidget" name="list"/>
+    <widget class="QListWidget" name="list">
+     <property name="iconSize">
+      <size>
+       <width>32</width>
+       <height>32</height>
+      </size>
+     </property>
+    </widget>
    </item>
    <item>
     <layout class="QVBoxLayout" name="verticalLayout">
-- 
1.7.6.5


From 00ad2df5eb81f986be9e212e0bac39ef43a00759 Mon Sep 17 00:00:00 2001
From: Fabio D'Urso <fabiodurso at hotmail.it>
Date: Sat, 28 Jul 2012 12:51:58 +0200
Subject: [PATCH 37/43] Consistently call "Note" -> "Pop-up Note" (as opposed
 to "Inline Note")

---
 conf/widgetannottools.cpp         |    8 ++++----
 ui/annotationpropertiesdialog.cpp |    2 +-
 ui/pageviewannotator.cpp          |    2 +-
 3 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/conf/widgetannottools.cpp b/conf/widgetannottools.cpp
index 0ca3da3..dd2f7c4 100644
--- a/conf/widgetannottools.cpp
+++ b/conf/widgetannottools.cpp
@@ -264,7 +264,7 @@ EditAnnotToolDialog::EditAnnotToolDialog( QWidget *parent, const QDomElement &in
     m_stubann->style().setColor( Qt::yellow );
 
     // Populate combobox with annotation types
-    m_type->addItem( i18n("Note") );
+    m_type->addItem( i18n("Pop-up Note") );
     m_type->addItem( i18n("Inline Note") );
     m_type->addItem( i18n("Freehand Line") );
     m_type->addItem( i18n("Straight Line") );
@@ -316,7 +316,7 @@ QDomDocument EditAnnotToolDialog::toolXml() const
     {
         case 0:
         {
-            // Note
+            // Pop-up Note
             Okular::TextAnnotation * ta = static_cast<Okular::TextAnnotation*>( m_stubann );
             toolElement.setAttribute( "type", "note-linked" );
             engineElement.setAttribute( "type", "PickPoint" );
@@ -536,7 +536,7 @@ void EditAnnotToolDialog::loadTool( const QDomElement &toolElement )
     }
     else if ( annotType == "note-linked" )
     {
-        m_type->setCurrentIndex( 0 ); // Note
+        m_type->setCurrentIndex( 0 ); // Pop-up Note
         Okular::TextAnnotation * ta = static_cast<Okular::TextAnnotation*>( m_stubann );
         ta->setTextIcon( annotationElement.attribute( "icon" ) );
     }
@@ -614,7 +614,7 @@ void EditAnnotToolDialog::slotTypeChanged( int index )
     {
         case 0:
         {
-            // Note
+            // Pop-up Note
             Okular::TextAnnotation * ta = new Okular::TextAnnotation();
             ta->setTextType( Okular::TextAnnotation::Linked );
             ta->setTextIcon( "Note" );
diff --git a/ui/annotationpropertiesdialog.cpp b/ui/annotationpropertiesdialog.cpp
index c0bca4a..fed0d0a 100644
--- a/ui/annotationpropertiesdialog.cpp
+++ b/ui/annotationpropertiesdialog.cpp
@@ -115,7 +115,7 @@ void AnnotsPropertiesDialog::setCaptionTextbyAnnotType()
     {
         case Okular::Annotation::AText:
             if(((Okular::TextAnnotation*)m_annot)->textType()==Okular::TextAnnotation::Linked)
-                captiontext = i18n( "Note Properties" );
+                captiontext = i18n( "Pop-up Note Properties" );
             else
                 captiontext = i18n( "Inline Note Properties" );
             break;
diff --git a/ui/pageviewannotator.cpp b/ui/pageviewannotator.cpp
index 6fdc821..c37ef5d 100644
--- a/ui/pageviewannotator.cpp
+++ b/ui/pageviewannotator.cpp
@@ -1007,7 +1007,7 @@ QString PageViewAnnotator::defaultToolName( const QDomElement &toolElement )
     else if ( annotType == "note-inline" )
         return i18n( "Inline Note" );
     else if ( annotType == "note-linked" )
-        return i18n( "Note" );
+        return i18n( "Pop-up Note" );
     else if ( annotType == "polygon" )
         return i18n( "Polygon" );
     else if ( annotType == "polyline" )
-- 
1.7.6.5


From b7c6b2cac23a85b384acc979ce7f2d768af9bb7c Mon Sep 17 00:00:00 2001
From: Fabio D'Urso <fabiodurso at hotmail.it>
Date: Sun, 29 Jul 2012 17:58:34 +0200
Subject: [PATCH 38/43] Show tool icon in EditAnnotToolDialog

---
 conf/widgetannottools.cpp |   16 +++++++++++-----
 conf/widgetannottools.h   |    4 +++-
 2 files changed, 14 insertions(+), 6 deletions(-)

diff --git a/conf/widgetannottools.cpp b/conf/widgetannottools.cpp
index dd2f7c4..cc63d95 100644
--- a/conf/widgetannottools.cpp
+++ b/conf/widgetannottools.cpp
@@ -254,9 +254,14 @@ EditAnnotToolDialog::EditAnnotToolDialog( QWidget *parent, const QDomElement &in
     widgetLayout->addWidget( tmplabel, 1, 0, Qt::AlignRight );
     widgetLayout->addWidget( m_type, 1, 1 );
 
+    m_toolIcon = new QLabel( widget );
+    m_toolIcon->setAlignment( Qt::AlignRight | Qt::AlignTop );
+    m_toolIcon->setMinimumSize( 40, 32 );
+    widgetLayout->addWidget( m_toolIcon, 0, 2, 2, 1 );
+
     m_appearanceBox = new QGroupBox( i18n( "Appearance" ), widget );
     m_appearanceBox->setLayout( new QVBoxLayout( m_appearanceBox ) );
-    widgetLayout->addWidget( m_appearanceBox, 2, 0, 1, 2 );
+    widgetLayout->addWidget( m_appearanceBox, 2, 0, 1, 3 );
 
     // Create a stub annotation of the default type
     m_stubann = new Okular::TextAnnotation();
@@ -285,7 +290,7 @@ EditAnnotToolDialog::EditAnnotToolDialog( QWidget *parent, const QDomElement &in
     }
 
     rebuildAppearanceBox();
-    updateDefaultName();
+    updateDefaultNameAndIcon();
 }
 
 EditAnnotToolDialog::~EditAnnotToolDialog()
@@ -492,11 +497,12 @@ void EditAnnotToolDialog::rebuildAppearanceBox()
     connect( m_annotationWidget, SIGNAL(dataChanged()), this, SLOT(slotDataChanged()) );
 }
 
-void EditAnnotToolDialog::updateDefaultName()
+void EditAnnotToolDialog::updateDefaultNameAndIcon()
 {
     QDomDocument doc = toolXml();
     QDomElement toolElement = doc.documentElement();
     m_name->setPlaceholderText( PageViewAnnotator::defaultToolName( toolElement ) );
+    m_toolIcon->setPixmap( PageViewAnnotator::makeToolPixmap( toolElement ) );
 }
 
 void EditAnnotToolDialog::loadTool( const QDomElement &toolElement )
@@ -703,7 +709,7 @@ void EditAnnotToolDialog::slotTypeChanged( int index )
     }
 
     rebuildAppearanceBox();
-    updateDefaultName();
+    updateDefaultNameAndIcon();
 }
 
 void EditAnnotToolDialog::slotDataChanged()
@@ -711,7 +717,7 @@ void EditAnnotToolDialog::slotDataChanged()
     // Mirror changes back in the stub annotation
     m_annotationWidget->applyChanges();
 
-    updateDefaultName();
+    updateDefaultNameAndIcon();
 }
 
 #include "moc_widgetannottools.cpp"
diff --git a/conf/widgetannottools.h b/conf/widgetannottools.h
index b1cff4d..0f4e1d7 100644
--- a/conf/widgetannottools.h
+++ b/conf/widgetannottools.h
@@ -16,6 +16,7 @@
 
 class KLineEdit;
 class KComboBox;
+class QLabel;
 class QListWidgetItem;
 class QGroupBox;
 class AnnotationWidget;
@@ -68,11 +69,12 @@ class EditAnnotToolDialog : public KDialog
 
     private:
         void rebuildAppearanceBox();
-        void updateDefaultName();
+        void updateDefaultNameAndIcon();
         void loadTool( const QDomElement &toolElement );
 
         KLineEdit * m_name;
         KComboBox * m_type;
+        QLabel * m_toolIcon;
         QGroupBox * m_appearanceBox;
 
         Okular::Annotation *m_stubann;
-- 
1.7.6.5


From 8c32ba4629a11edf7f3e0af11b0fa899d7ac9107 Mon Sep 17 00:00:00 2001
From: Fabio D'Urso <fabiodurso at hotmail.it>
Date: Sat, 28 Jul 2012 16:20:28 +0200
Subject: [PATCH 39/43] Made Inplace annotations' alignment configurable

Note that PagePainter support for this property is currently broken: it
only works at 100% zoom.
---
 conf/widgetannottools.cpp |    4 ++++
 ui/annotationwidgets.cpp  |   20 ++++++++++++++++----
 ui/annotationwidgets.h    |    1 +
 ui/pageviewannotator.cpp  |    2 ++
 4 files changed, 23 insertions(+), 4 deletions(-)

diff --git a/conf/widgetannottools.cpp b/conf/widgetannottools.cpp
index cc63d95..6a46d72 100644
--- a/conf/widgetannottools.cpp
+++ b/conf/widgetannottools.cpp
@@ -343,6 +343,8 @@ QDomDocument EditAnnotToolDialog::toolXml() const
             engineElement.setAttribute( "block", "true" );
             annotationElement.setAttribute( "type", "FreeText" );
             annotationElement.setAttribute( "color", color );
+            if ( ta->inplaceAlignment() != 0 )
+                annotationElement.setAttribute( "align", ta->inplaceAlignment() );
             if ( ta->textFont() != QApplication::font() )
                 annotationElement.setAttribute( "font", ta->textFont().toString() );
             break;
@@ -533,6 +535,8 @@ void EditAnnotToolDialog::loadTool( const QDomElement &toolElement )
     {
         m_type->setCurrentIndex( 1 ); // Inline note
         Okular::TextAnnotation * ta = static_cast<Okular::TextAnnotation*>( m_stubann );
+        if ( annotationElement.hasAttribute( "align" ) )
+            ta->setInplaceAlignment( annotationElement.attribute( "align" ).toInt() );
         if ( annotationElement.hasAttribute( "font" ) )
         {
             QFont f;
diff --git a/ui/annotationwidgets.cpp b/ui/annotationwidgets.cpp
index 277d3ed..91a40cc 100644
--- a/ui/annotationwidgets.cpp
+++ b/ui/annotationwidgets.cpp
@@ -271,15 +271,26 @@ QWidget * TextAnnotationWidget::createStyleWidget()
     }
     else if ( m_textAnn->textType() == Okular::TextAnnotation::InPlace )
     {
-        QHBoxLayout * fontlay = new QHBoxLayout();
+        QGridLayout * innerlay = new QGridLayout();
+        lay->addLayout( innerlay );
+
         QLabel * tmplabel = new QLabel( i18n( "Font:" ), widget );
-        fontlay->addWidget( tmplabel );
+        innerlay->addWidget( tmplabel, 0, 0 );
         m_fontReq = new KFontRequester( widget );
-        fontlay->addWidget( m_fontReq );
-        lay->addLayout( fontlay );
+        innerlay->addWidget( m_fontReq, 0, 1 );
         m_fontReq->setFont( m_textAnn->textFont() );
 
+        tmplabel = new QLabel( i18n( "Align:" ), widget );
+        innerlay->addWidget( tmplabel, 1, 0 );
+        m_textAlign = new KComboBox( widget );
+        innerlay->addWidget( m_textAlign, 1, 1 );
+        m_textAlign->addItem( i18n("Left") );
+        m_textAlign->addItem( i18n("Center") );
+        m_textAlign->addItem( i18n("Right") );
+        m_textAlign->setCurrentIndex( m_textAnn->inplaceAlignment() );
+
         connect( m_fontReq, SIGNAL(fontSelected(QFont)), this, SIGNAL(dataChanged()) );
+        connect( m_textAlign, SIGNAL(currentIndexChanged(int)), this, SIGNAL(dataChanged()) );
     }
 
     return widget;
@@ -295,6 +306,7 @@ void TextAnnotationWidget::applyChanges()
     else if ( m_textAnn->textType() == Okular::TextAnnotation::InPlace )
     {
         m_textAnn->setTextFont( m_fontReq->font() );
+        m_textAnn->setInplaceAlignment( m_textAlign->currentIndex() );
     }
 }
 
diff --git a/ui/annotationwidgets.h b/ui/annotationwidgets.h
index e11153d..3601cdb 100644
--- a/ui/annotationwidgets.h
+++ b/ui/annotationwidgets.h
@@ -115,6 +115,7 @@ private:
     Okular::TextAnnotation * m_textAnn;
     PixmapPreviewSelector * m_pixmapSelector;
     KFontRequester * m_fontReq;
+    QComboBox * m_textAlign;
 };
 
 class StampAnnotationWidget
diff --git a/ui/pageviewannotator.cpp b/ui/pageviewannotator.cpp
index c37ef5d..f1a4f6c 100644
--- a/ui/pageviewannotator.cpp
+++ b/ui/pageviewannotator.cpp
@@ -168,6 +168,8 @@ class PickPointEngine : public AnnotatorEngine
                     ta->setInplaceText( note );
                     ta->setTextType( Okular::TextAnnotation::InPlace );
                     //set font
+                    if ( m_annotElement.hasAttribute( "align" ) )
+                        ta->setInplaceAlignment( m_annotElement.attribute( "align" ).toInt() );
                     if ( m_annotElement.hasAttribute( "font" ) )
                     {
                         QFont f;
-- 
1.7.6.5


From 649e87211e26251ef0514e297458592462cc9523 Mon Sep 17 00:00:00 2001
From: Fabio D'Urso <fabiodurso at hotmail.it>
Date: Sat, 28 Jul 2012 16:39:24 +0200
Subject: [PATCH 40/43] Fixed Inplace annotations' layout in PagePainter

The bounding box was incorrectly calculated unless the zoom was at 100%.
It caused word wrapping and text alignment errors.
---
 ui/pagepainter.cpp |    7 +++++--
 1 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/ui/pagepainter.cpp b/ui/pagepainter.cpp
index 5e86db5..b50bb38 100644
--- a/ui/pagepainter.cpp
+++ b/ui/pagepainter.cpp
@@ -616,8 +616,11 @@ void PagePainter::paintCroppedPageOnPainter( QPainter * destPainter, const Okula
                     painter.setPen( Qt::black );
                     painter.setFont( text->textFont() );
                     Qt::AlignmentFlag halign = ( text->inplaceAlignment() == 1 ? Qt::AlignHCenter : ( text->inplaceAlignment() == 2 ? Qt::AlignRight : Qt::AlignLeft ) );
-                    painter.scale( 1.0 * scaledWidth / page->width(), 1.0 * scaledHeight / page->height() );
-                    painter.drawText( 2, 2, image.width() - 2, image.height() - 2,
+                    const double invXScale = (double)page->width() / scaledWidth;
+                    const double invYScale = (double)page->width() / scaledWidth;
+                    painter.scale( 1 / invXScale, 1 / invYScale );
+                    painter.drawText( 2 * invXScale, 2 * invYScale,
+                                      (image.width()-3) * invXScale, (image.height()-3) * invYScale,
                                       Qt::AlignTop | halign | Qt::TextWordWrap,
                                       text->inplaceText() );
                     painter.resetTransform();
-- 
1.7.6.5


From 5e1a1c17b2a62b4ddd02098005f83df18dc55f09 Mon Sep 17 00:00:00 2001
From: Fabio D'Urso <fabiodurso at hotmail.it>
Date: Sat, 28 Jul 2012 13:48:07 +0200
Subject: [PATCH 41/43] Show stamp preview in stamp tool icon

Note that if a low-res 16x16 version is available, it is shown instead
of the 64x64 version actually used by PagePainter.
e.g. try with the default stamp "Okular"
---
 ui/data/CMakeLists.txt        |    1 -
 ui/data/tool-stamp-okular.png |  Bin 1661 -> 0 bytes
 ui/pageviewannotator.cpp      |  255 +++++++++++++++++++++--------------------
 3 files changed, 128 insertions(+), 128 deletions(-)
 delete mode 100644 ui/data/tool-stamp-okular.png

diff --git a/ui/data/CMakeLists.txt b/ui/data/CMakeLists.txt
index 2fc16e2..491b993 100644
--- a/ui/data/CMakeLists.txt
+++ b/ui/data/CMakeLists.txt
@@ -15,7 +15,6 @@ install(FILES
    tool-note-okular-colorizable.png
    tool-note-inline.png
    tool-note-inline-okular-colorizable.png
-   tool-stamp-okular.png
    DESTINATION ${DATA_INSTALL_DIR}/okular/pics)
 # install annotation page images
 install(FILES
diff --git a/ui/data/tool-stamp-okular.png b/ui/data/tool-stamp-okular.png
deleted file mode 100644
index e53a04af38b307440ab1d227833a51b413294be1..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 1661
zcmV- at 27>vCP)<h;3K|Lk000e1NJLTq001BW001Be1^@s6b9#F800004b3#c}2nYxW
zd<bNS00009a7bBm000Aa000Aa0e#hi%m4rY8FWQhbW?9;ba!ELWdL_~cP?peYja~^
zaAhuUa%Y?FJQ at H11^P)uK~#9!?N{qhlUE$xvcG0u_RTL#_Q}6u-<Rx`Wr;3}$>tVk
zjN+WrO;HiCl)K!a6xv!_3Ru8WDn%)^H+p$Xd7&3t+EUs+JI_gc<5GoqiTkpXoKW7L
z_nhbV`#sO|JN*E_e>yondC&7>F+bD*)a&(y_c at OpJNBsn@R0 at p?|B?Qe*CjH22d^S
zBj<Sr^?@77kr_mFlh|k-hthAumU$7G#WhsYyYC*rL2eJ*(;kGc4<UHvo}8h-1|R{n
zj3IQjUwh8a1XtYHd^Z3xOFkYZH;>*mBD?HIDWM8b1(}h`P7ZtFB+8pR$SprZtkbN4
zNsi8<wqJQO0QG7Os>Q{PM4AoAJr2l&_th*4!2~i3Pf^*<VSg)wVl0KsqcxP0JN!<r
zi}&1@@5VYz%;4(*sMqR94ozztu&!mXc~L}KD_2mArZ{CbGA<wXB1r;~>k5H5^6OEQ
z;#=6VJd%4vZjBMd;Q#`G09-B?R#sM^&aYzaVy8 at JK~b?APazkIqna-wIW;dg_5I$(
zzyF%?Zi_6%!S0@%9LyBIQwHr2GHe8(C<>CvBz!&}j7B4t=N4f8z6q9-m!Kw+nCKtE
zNP9Qp3o97=@(iYbxD3;Yix at k14MFom?0SQYl!VmCNy4&(Y3CDWhbocZ<yHcX0Emi*
zTdh`fb#=khG62`Fw=j0T86J-Ztu41PH!_LIZ_i=;tKVR~)rCYf27|sA$$2l*^G}fX
zZODi#**xN17J1l?!z2DLXq=&fA~#1~U4m-0iu+S089_)a^iDfb2nj-|8BKn>;-I3U
zGSv;~=X>;ldgTBccMO!HP=|to;6r|GL;6JM at 4>@K7+rV_iGJoW(sN!CiR|Vxk=A7r
zNfIj7WhT>^W=2hNiqBQbl+lW^gfvdniu)w4+$($(0QJ6<o!p=p*+l(7Y}zhsivw}c
zmT6H&S1p!Niftj<W|Z~jsEM`ALdxi5+BH+E?v*rU9a;hoh0<dN9(s{~8j+hy1JX|c
zVgr^U>-KXg6{2|rM=7q#|2N0y$Oo-7l;rb4qBa1iR4U*I27_4B8!-CCFIbyjBC({?
z1^(<qV!*~U$_-1&ZB)zqj81+RzB_ at z!9gtcjN at rj2UQ_z9(fS}v&WJN(56NJCX)%O
zs$ywr363l6SopaaX<;s^;K96O7TuqpL_}xA#Mn5TKV8R!V1KtxkHynBVE*nr+{0${
z^z=X(pM^4Dm%LE!*)#x at A)S&&_0kMbdTzHH7K;VOrkj}g at e0!Jb!kik0|PLe`U8$r
zSJ9*IguSU1uC^fz4-aGbP6tf7J}irOJ32ZL^#!2B;?Lbr;{c_|@=y`sYeS6y=zjEq
zbUG~={N#cjsi_5ldJEhBh%^sr$s)pRB85ncP{EL0f(#pGB=h5Q%ShVYa9_}oXq22r
zNH!y8VcWiZv<gTx$}D_i1eHu)t6xkgfzhzVvJ0l2tB6YyY92r!()ntY14 at _An09tb
z-XFOBNB|sM%uR`&jfD|V>mssIf*{M~#vBLvB4x%5a<UKbF2KV{VtNDX&&H*-^CJPU
z;qWlNKt{6*vh9{rX?8{}YObLt&?jh2EDfJisyv*7cLkP%Qk8 at Z#2W$7f^9aN<N!Z&
zJesh=bM_AWmwRcY%mnMmhy*8s1ft!7UIfI_NRtwvc{qb%)Y2bDXJ6iq{eD06dcE`k
zhr<D<(+QnUhxJh#Y$q<kb-oQNMmromBN%J#L_)BA+G52+$BblmS=p9{iW;yqOgC>)
zbVE&!iC!zY at p1rCY6gSMg4t}QB&Dvi*(^pcx4<N{Zv6Tz+P^ss_oNLE+WIhkw;vpo
zSW$TV?rMnE%*j&8P8bnH=HYC`1o+AuQLR>k*Xu>OT*m6^D$5|VQ79DHrlo`Vn+M at O
za~rF|>7MBfP$r$SG})zfUfakOwq;4caPzRH461 at X;H_`Pv|-)}6Ma^0e(0pxY}?%I
zobUX10SEnozYW-~>3WQs#>M*~`M?JDmcI+$e*6#MwE+AB7Mumm3c`pw00000NkvXX
Hu0mjfyCDe^

diff --git a/ui/pageviewannotator.cpp b/ui/pageviewannotator.cpp
index f1a4f6c..1d9af5c 100644
--- a/ui/pageviewannotator.cpp
+++ b/ui/pageviewannotator.cpp
@@ -1035,140 +1035,141 @@ QPixmap PageViewAnnotator::makeToolPixmap( const QDomElement &toolElement )
     QPixmap pixmap(32, 32);
     const QString annotType = toolElement.attribute( "type" );
 
-    if ( annotType == "stamp" )
+    // Load base pixmap. We'll draw on top of it
+    pixmap.load( KStandardDirs::locate("data", "okular/pics/tool-base-okular.png" ) );
+
+    /* Parse color, innerColor and icon (if present) */
+    QColor engineColor, innerColor;
+    QString icon;
+    QDomNodeList engineNodeList = toolElement.elementsByTagName( "engine" );
+    if ( engineNodeList.size() > 0 )
     {
-        // Load static image file
-        pixmap.load( KStandardDirs::locate("data", "okular/pics/tool-stamp-okular.png" ) );
+        QDomElement engineEl = engineNodeList.item( 0 ).toElement();
+        if ( !engineEl.isNull() && engineEl.hasAttribute( "color" ) )
+            engineColor = QColor( engineEl.attribute( "color" ) );
     }
-    else
+    QDomNodeList annotationNodeList = toolElement.elementsByTagName( "annotation" );
+    if ( annotationNodeList.size() > 0 )
     {
-        // Load base pixmap. We'll draw on top of it
-        pixmap.load( KStandardDirs::locate("data", "okular/pics/tool-base-okular.png" ) );
-
-        /* Parse the color */
-        QColor engineColor, innerColor;
-        QDomNodeList engineNodeList = toolElement.elementsByTagName( "engine" );
-        if ( engineNodeList.size() > 0 )
-        {
-            QDomElement engineEl = engineNodeList.item( 0 ).toElement();
-            if ( !engineEl.isNull() && engineEl.hasAttribute( "color" ) )
-                engineColor = QColor( engineEl.attribute( "color" ) );
-        }
-        QDomNodeList annotationNodeList = toolElement.elementsByTagName( "annotation" );
-        if ( annotationNodeList.size() > 0 )
-        {
-            QDomElement annotationEl = annotationNodeList.item( 0 ).toElement();
-            if ( !annotationEl.isNull() && annotationEl.hasAttribute( "innerColor" ) )
-                innerColor = QColor( annotationEl.attribute( "innerColor" ) );
-        }
+        QDomElement annotationEl = annotationNodeList.item( 0 ).toElement();
+        if ( !annotationEl.isNull() && annotationEl.hasAttribute( "innerColor" ) )
+            innerColor = QColor( annotationEl.attribute( "innerColor" ) );
+        if ( !annotationEl.isNull() && annotationEl.hasAttribute( "icon" ) )
+            icon = annotationEl.attribute( "icon" );
+    }
 
-        QPainter p( &pixmap );
+    QPainter p( &pixmap );
 
-        if ( annotType == "ellipse" )
-        {
-            p.setRenderHint( QPainter::Antialiasing );
-            if ( innerColor.isValid() )
-                p.setBrush( innerColor );
-            p.setPen( QPen( engineColor, 2 ) );
-            p.drawEllipse( 2, 7, 21, 14 );
-        }
-        else if ( annotType == "highlight" )
-        {
-            QImage overlay( KStandardDirs::locate("data", "okular/pics/tool-highlighter-okular-colorizable.png" ) );
-            QImage coloredOverlay = overlay;
-            GuiUtils::colorizeImage( coloredOverlay, engineColor );
+    if ( annotType == "ellipse" )
+    {
+        p.setRenderHint( QPainter::Antialiasing );
+        if ( innerColor.isValid() )
+            p.setBrush( innerColor );
+        p.setPen( QPen( engineColor, 2 ) );
+        p.drawEllipse( 2, 7, 21, 14 );
+    }
+    else if ( annotType == "highlight" )
+    {
+        QImage overlay( KStandardDirs::locate("data", "okular/pics/tool-highlighter-okular-colorizable.png" ) );
+        QImage coloredOverlay = overlay;
+        GuiUtils::colorizeImage( coloredOverlay, engineColor );
 
-            p.drawImage( QPoint(0,0), coloredOverlay ); // Trail
-            p.drawImage( QPoint(0,-32), overlay ); // Shadow (uncolorized)
-            p.drawImage( QPoint(0,-64), coloredOverlay ); // Pen
-        }
-        else if ( annotType == "ink" )
-        {
-            QImage overlay( KStandardDirs::locate("data", "okular/pics/tool-ink-okular-colorizable.png" ) );
-            QImage coloredOverlay = overlay;
-            GuiUtils::colorizeImage( coloredOverlay, engineColor );
+        p.drawImage( QPoint(0,0), coloredOverlay ); // Trail
+        p.drawImage( QPoint(0,-32), overlay ); // Shadow (uncolorized)
+        p.drawImage( QPoint(0,-64), coloredOverlay ); // Pen
+    }
+    else if ( annotType == "ink" )
+    {
+        QImage overlay( KStandardDirs::locate("data", "okular/pics/tool-ink-okular-colorizable.png" ) );
+        QImage coloredOverlay = overlay;
+        GuiUtils::colorizeImage( coloredOverlay, engineColor );
 
-            p.drawImage( QPoint(0,0), coloredOverlay ); // Trail
-            p.drawImage( QPoint(0,-32), overlay ); // Shadow (uncolorized)
-            p.drawImage( QPoint(0,-64), coloredOverlay ); // Pen
-        }
-        else if ( annotType == "note-inline" )
-        {
-            QImage overlay( KStandardDirs::locate("data", "okular/pics/tool-note-inline-okular-colorizable.png" ) );
-            GuiUtils::colorizeImage( overlay, engineColor );
-            p.drawImage( QPoint(0,0), overlay );
-        }
-        else if ( annotType == "note-linked" )
-        {
-            QImage overlay( KStandardDirs::locate("data", "okular/pics/tool-note-okular-colorizable.png" ) );
-            GuiUtils::colorizeImage( overlay, engineColor );
-            p.drawImage( QPoint(0,0), overlay );
-        }
-        else if ( annotType == "polygon" )
-        {
-            QPainterPath path;
-            path.moveTo( 0, 7 );
-            path.lineTo( 19, 7 );
-            path.lineTo( 19, 14 );
-            path.lineTo( 23, 14 );
-            path.lineTo( 23, 20 );
-            path.lineTo( 0, 20 );
-            if ( innerColor.isValid() )
-                p.setBrush( innerColor );
-            p.setPen( QPen( engineColor, 1 ) );
-            p.drawPath( path );
-        }
-        else if ( annotType == "polyline" )
-        {
-            QPainterPath path;
-            path.moveTo( 1, 8 );
-            path.lineTo( 20, 8 );
-            path.lineTo( 1, 27 );
-            path.lineTo( 20, 27 );
-            p.setRenderHint( QPainter::Antialiasing );
-            p.setPen( QPen( engineColor, 1 ) );
-            p.drawPath( path );
-        }
-        else if ( annotType == "rectangle" )
-        {
-            p.setRenderHint( QPainter::Antialiasing );
-            if ( innerColor.isValid() )
-                p.setBrush( innerColor );
-            p.setPen( QPen( engineColor, 2 ) );
-            p.drawRect( 2, 7, 21, 14 );
-        }
-        else if ( annotType == "squiggly" )
-        {
-            p.setPen( QPen( engineColor, 1, Qt::DotLine ) );
-            p.drawLine( 1, 13, 16, 13 );
-            p.drawLine( 2, 14, 15, 14 );
-            p.drawLine( 0, 20, 19, 20 );
-            p.drawLine( 1, 21, 18, 21 );
-        }
-        else if ( annotType == "straight-line" )
-        {
-            p.setRenderHint( QPainter::Antialiasing );
-            p.setPen( QPen( engineColor, 1 ) );
-            p.drawLine( 4, 22, 24, 10 );
-        }
-        else if ( annotType == "strikeout" )
-        {
-            p.setPen( QPen( engineColor, 1 ) );
-            p.drawLine( 1, 11, 16, 11 );
-            p.drawLine( 0, 18, 19, 18 );
-        }
-        else if ( annotType == "underline" )
-        {
-            p.setPen( QPen( engineColor, 1 ) );
-            p.drawLine( 1, 13, 16, 13 );
-            p.drawLine( 0, 20, 19, 20 );
-        }
-        else
-        {
-            /* Unrecognized annotation type -- It shouldn't happen */
-            p.setPen( QPen( engineColor ) );
-            p.drawText( QPoint(20, 31), "?" );
-        }
+        p.drawImage( QPoint(0,0), coloredOverlay ); // Trail
+        p.drawImage( QPoint(0,-32), overlay ); // Shadow (uncolorized)
+        p.drawImage( QPoint(0,-64), coloredOverlay ); // Pen
+    }
+    else if ( annotType == "note-inline" )
+    {
+        QImage overlay( KStandardDirs::locate("data", "okular/pics/tool-note-inline-okular-colorizable.png" ) );
+        GuiUtils::colorizeImage( overlay, engineColor );
+        p.drawImage( QPoint(0,0), overlay );
+    }
+    else if ( annotType == "note-linked" )
+    {
+        QImage overlay( KStandardDirs::locate("data", "okular/pics/tool-note-okular-colorizable.png" ) );
+        GuiUtils::colorizeImage( overlay, engineColor );
+        p.drawImage( QPoint(0,0), overlay );
+    }
+    else if ( annotType == "polygon" )
+    {
+        QPainterPath path;
+        path.moveTo( 0, 7 );
+        path.lineTo( 19, 7 );
+        path.lineTo( 19, 14 );
+        path.lineTo( 23, 14 );
+        path.lineTo( 23, 20 );
+        path.lineTo( 0, 20 );
+        if ( innerColor.isValid() )
+            p.setBrush( innerColor );
+        p.setPen( QPen( engineColor, 1 ) );
+        p.drawPath( path );
+    }
+    else if ( annotType == "polyline" )
+    {
+        QPainterPath path;
+        path.moveTo( 1, 8 );
+        path.lineTo( 20, 8 );
+        path.lineTo( 1, 27 );
+        path.lineTo( 20, 27 );
+        p.setRenderHint( QPainter::Antialiasing );
+        p.setPen( QPen( engineColor, 1 ) );
+        p.drawPath( path );
+    }
+    else if ( annotType == "rectangle" )
+    {
+        p.setRenderHint( QPainter::Antialiasing );
+        if ( innerColor.isValid() )
+            p.setBrush( innerColor );
+        p.setPen( QPen( engineColor, 2 ) );
+        p.drawRect( 2, 7, 21, 14 );
+    }
+    else if ( annotType == "squiggly" )
+    {
+        p.setPen( QPen( engineColor, 1, Qt::DotLine ) );
+        p.drawLine( 1, 13, 16, 13 );
+        p.drawLine( 2, 14, 15, 14 );
+        p.drawLine( 0, 20, 19, 20 );
+        p.drawLine( 1, 21, 18, 21 );
+    }
+    else if ( annotType == "stamp" )
+    {
+        QPixmap stamp = GuiUtils::loadStamp( icon, QSize( 16, 16 ) );
+        p.setRenderHint( QPainter::Antialiasing );
+        p.drawPixmap( 16, 14, stamp );
+    }
+    else if ( annotType == "straight-line" )
+    {
+        p.setRenderHint( QPainter::Antialiasing );
+        p.setPen( QPen( engineColor, 1 ) );
+        p.drawLine( 4, 22, 24, 10 );
+    }
+    else if ( annotType == "strikeout" )
+    {
+        p.setPen( QPen( engineColor, 1 ) );
+        p.drawLine( 1, 11, 16, 11 );
+        p.drawLine( 0, 18, 19, 18 );
+    }
+    else if ( annotType == "underline" )
+    {
+        p.setPen( QPen( engineColor, 1 ) );
+        p.drawLine( 1, 13, 16, 13 );
+        p.drawLine( 0, 20, 19, 20 );
+    }
+    else
+    {
+        /* Unrecognized annotation type -- It shouldn't happen */
+        p.setPen( QPen( engineColor ) );
+        p.drawText( QPoint(20, 31), "?" );
     }
 
     return pixmap;
-- 
1.7.6.5


From d079522d53efa9e2b74077ec7b17ec78f799a538 Mon Sep 17 00:00:00 2001
From: Fabio D'Urso <fabiodurso at hotmail.it>
Date: Sat, 28 Jul 2012 17:09:44 +0200
Subject: [PATCH 42/43] Set clicked back to false when the creation of a
 PickPoint annotation is completed

So that the hoverIcon is not shown above the newly created annotation.
This was especially visible if the creation of the annotation triggers a
message box warning, because one could see both the annotation and the
hover icon as long as the warning wasn't closed.
---
 ui/pageviewannotator.cpp |    9 +++++++--
 1 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/ui/pageviewannotator.cpp b/ui/pageviewannotator.cpp
index 1d9af5c..bab105c 100644
--- a/ui/pageviewannotator.cpp
+++ b/ui/pageviewannotator.cpp
@@ -144,11 +144,13 @@ class PickPointEngine : public AnnotatorEngine
 
         QList< Okular::Annotation* > end()
         {
-            m_creationCompleted = false;
-
             // find out annotation's description node
             if ( m_annotElement.isNull() )
+            {
+                m_creationCompleted = false;
+                clicked = false;
                 return QList< Okular::Annotation* >();
+            }
 
             // find out annotation's type
             Okular::Annotation * ann = 0;
@@ -262,6 +264,9 @@ class PickPointEngine : public AnnotatorEngine
                 ga->setBoundingRectangle( rect );
             }
 
+            m_creationCompleted = false;
+            clicked = false;
+
             // safety check
             if ( !ann )
                 return QList< Okular::Annotation* >();
-- 
1.7.6.5


From 6e6f0e641920c552bf1e4eb6bf65560e723ae62b Mon Sep 17 00:00:00 2001
From: Fabio D'Urso <fabiodurso at hotmail.it>
Date: Sat, 28 Jul 2012 17:19:16 +0200
Subject: [PATCH 43/43] Fixed fuzzy detection of coord equality in PolyLine
 engine

Because (1,0) is not the same as (0,1).
Symptom: create a polygon with first vertex top-right, another
point in the middle the page and another vertex bottom-left.
The polygon gets closed and the bottom-left vertex is ignored.
---
 ui/pageviewannotator.cpp |    6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/ui/pageviewannotator.cpp b/ui/pageviewannotator.cpp
index bab105c..6df919c 100644
--- a/ui/pageviewannotator.cpp
+++ b/ui/pageviewannotator.cpp
@@ -341,14 +341,14 @@ class PolyLineEngine : public AnnotatorEngine
                 Okular::NormalizedPoint tmppoint;
                 tmppoint.x = nX;
                 tmppoint.y = nY;
-                if ( fabs( tmppoint.x - newPoint.x + tmppoint.y - newPoint.y ) > 1e-2 )
+                if ( fabs( tmppoint.x - newPoint.x ) + fabs( tmppoint.y - newPoint.y ) > 1e-2 )
                     return rect;
 
-                if ( numofpoints == -1 && points.count() > 1 && ( fabs( points[0].x - newPoint.x + points[0].y - newPoint.y ) < 1e-2 ) )
+                if ( numofpoints == -1 && points.count() > 1 && ( fabs( points[0].x - newPoint.x ) + fabs( points[0].y - newPoint.y ) < 1e-2 ) )
                 {
                     last = true;
                 }
-                else if ( numofpoints == 0 && points.count() > 1 && ( fabs( points.last().x - newPoint.x + points.last().y - newPoint.y ) < 1e-2 ) )
+                else if ( numofpoints == 0 && points.count() > 1 && ( fabs( points.last().x - newPoint.x ) + fabs( points.last().y - newPoint.y ) < 1e-2 ) )
                 {
                     last = true;
                 }
-- 
1.7.6.5

-------------- next part --------------
A non-text attachment was scrubbed...
Name: patched-toolbar-default-tools.png
Type: image/png
Size: 7070 bytes
Desc: not available
URL: <http://mail.kde.org/pipermail/okular-devel/attachments/20120730/0a7f3d0e/attachment-0003.png>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: patched-toolbar-fancy-tools.png
Type: image/png
Size: 9010 bytes
Desc: not available
URL: <http://mail.kde.org/pipermail/okular-devel/attachments/20120730/0a7f3d0e/attachment-0004.png>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: current-toolbar.png
Type: image/png
Size: 9182 bytes
Desc: not available
URL: <http://mail.kde.org/pipermail/okular-devel/attachments/20120730/0a7f3d0e/attachment-0005.png>


More information about the Okular-devel mailing list