summaryrefslogtreecommitdiffstats
path: root/chalk/plugins/tools
diff options
context:
space:
mode:
authortpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2011-06-26 00:41:16 +0000
committertpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2011-06-26 00:41:16 +0000
commit698569f8428ca088f764d704034a1330517b98c0 (patch)
treebf45be6946ebbbee9cce5a5bcf838f4c952d87e6 /chalk/plugins/tools
parent2785103a6bd4de55bd26d79e34d0fdd4b329a73a (diff)
downloadkoffice-698569f8428ca088f764d704034a1330517b98c0.tar.gz
koffice-698569f8428ca088f764d704034a1330517b98c0.zip
Finish rebranding of Krita as Chalk
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/applications/koffice@1238363 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'chalk/plugins/tools')
-rw-r--r--chalk/plugins/tools/Makefile.am3
-rw-r--r--chalk/plugins/tools/defaulttools/Makefile.am83
-rw-r--r--chalk/plugins/tools/defaulttools/chalkdefaulttools.desktop56
-rw-r--r--chalk/plugins/tools/defaulttools/closedhand_cursor.xpm28
-rw-r--r--chalk/plugins/tools/defaulttools/default_tools.cc88
-rw-r--r--chalk/plugins/tools/defaulttools/default_tools.h44
-rw-r--r--chalk/plugins/tools/defaulttools/kis_tool_brush.cc167
-rw-r--r--chalk/plugins/tools/defaulttools/kis_tool_brush.h87
-rw-r--r--chalk/plugins/tools/defaulttools/kis_tool_colorpicker.cc298
-rw-r--r--chalk/plugins/tools/defaulttools/kis_tool_colorpicker.h88
-rw-r--r--chalk/plugins/tools/defaulttools/kis_tool_duplicate.cc255
-rw-r--r--chalk/plugins/tools/defaulttools/kis_tool_duplicate.h92
-rw-r--r--chalk/plugins/tools/defaulttools/kis_tool_ellipse.cc186
-rw-r--r--chalk/plugins/tools/defaulttools/kis_tool_ellipse.h91
-rw-r--r--chalk/plugins/tools/defaulttools/kis_tool_fill.cc233
-rw-r--r--chalk/plugins/tools/defaulttools/kis_tool_fill.h109
-rw-r--r--chalk/plugins/tools/defaulttools/kis_tool_gradient.cc309
-rw-r--r--chalk/plugins/tools/defaulttools/kis_tool_gradient.h124
-rw-r--r--chalk/plugins/tools/defaulttools/kis_tool_line.cc254
-rw-r--r--chalk/plugins/tools/defaulttools/kis_tool_line.h100
-rw-r--r--chalk/plugins/tools/defaulttools/kis_tool_move.cc181
-rw-r--r--chalk/plugins/tools/defaulttools/kis_tool_move.h89
-rw-r--r--chalk/plugins/tools/defaulttools/kis_tool_pan.cc96
-rw-r--r--chalk/plugins/tools/defaulttools/kis_tool_pan.h80
-rw-r--r--chalk/plugins/tools/defaulttools/kis_tool_rectangle.cc187
-rw-r--r--chalk/plugins/tools/defaulttools/kis_tool_rectangle.h96
-rw-r--r--chalk/plugins/tools/defaulttools/kis_tool_text.cc198
-rw-r--r--chalk/plugins/tools/defaulttools/kis_tool_text.h81
-rw-r--r--chalk/plugins/tools/defaulttools/kis_tool_zoom.cc191
-rw-r--r--chalk/plugins/tools/defaulttools/kis_tool_zoom.h98
-rw-r--r--chalk/plugins/tools/defaulttools/openhand_cursor.xpm28
-rw-r--r--chalk/plugins/tools/defaulttools/tool_color_fill.pngbin0 -> 1102 bytes
-rw-r--r--chalk/plugins/tools/defaulttools/tool_colorpicker.pngbin0 -> 713 bytes
-rw-r--r--chalk/plugins/tools/defaulttools/tool_duplicate.pngbin0 -> 1087 bytes
-rw-r--r--chalk/plugins/tools/defaulttools/tool_duplicate_cursor.pngbin0 -> 309 bytes
-rw-r--r--chalk/plugins/tools/defaulttools/tool_ellipse.pngbin0 -> 524 bytes
-rw-r--r--chalk/plugins/tools/defaulttools/tool_ellipse_cursor.pngbin0 -> 309 bytes
-rw-r--r--chalk/plugins/tools/defaulttools/tool_fill_cursor.pngbin0 -> 516 bytes
-rw-r--r--chalk/plugins/tools/defaulttools/tool_freehand.pngbin0 -> 658 bytes
-rw-r--r--chalk/plugins/tools/defaulttools/tool_freehand_cursor.pngbin0 -> 261 bytes
-rw-r--r--chalk/plugins/tools/defaulttools/tool_gradient.pngbin0 -> 386 bytes
-rw-r--r--chalk/plugins/tools/defaulttools/tool_gradient_cursor.pngbin0 -> 294 bytes
-rw-r--r--chalk/plugins/tools/defaulttools/tool_line.pngbin0 -> 354 bytes
-rw-r--r--chalk/plugins/tools/defaulttools/tool_line_cursor.pngbin0 -> 248 bytes
-rw-r--r--chalk/plugins/tools/defaulttools/tool_move.pngbin0 -> 664 bytes
-rw-r--r--chalk/plugins/tools/defaulttools/tool_pan.pngbin0 -> 863 bytes
-rw-r--r--chalk/plugins/tools/defaulttools/tool_rectangle.pngbin0 -> 334 bytes
-rw-r--r--chalk/plugins/tools/defaulttools/tool_rectangle_cursor.pngbin0 -> 230 bytes
-rw-r--r--chalk/plugins/tools/defaulttools/tool_text.pngbin0 -> 891 bytes
-rw-r--r--chalk/plugins/tools/defaulttools/tool_text_cursor.pngbin0 -> 300 bytes
-rw-r--r--chalk/plugins/tools/defaulttools/tool_zoom.pngbin0 -> 877 bytes
-rw-r--r--chalk/plugins/tools/defaulttools/tool_zoom_minus_cursor.pngbin0 -> 283 bytes
-rw-r--r--chalk/plugins/tools/defaulttools/tool_zoom_plus_cursor.pngbin0 -> 302 bytes
-rw-r--r--chalk/plugins/tools/defaulttools/wdgcolorpicker.ui167
-rw-r--r--chalk/plugins/tools/selectiontools/Makefile.am56
-rw-r--r--chalk/plugins/tools/selectiontools/chalkselectiontools.desktop52
-rw-r--r--chalk/plugins/tools/selectiontools/kis_tool_move_selection.cc223
-rw-r--r--chalk/plugins/tools/selectiontools/kis_tool_move_selection.h75
-rw-r--r--chalk/plugins/tools/selectiontools/kis_tool_select_brush.cc168
-rw-r--r--chalk/plugins/tools/selectiontools/kis_tool_select_brush.h83
-rw-r--r--chalk/plugins/tools/selectiontools/kis_tool_select_contiguous.cc234
-rw-r--r--chalk/plugins/tools/selectiontools/kis_tool_select_contiguous.h95
-rw-r--r--chalk/plugins/tools/selectiontools/kis_tool_select_elliptical.cc321
-rw-r--r--chalk/plugins/tools/selectiontools/kis_tool_select_elliptical.h99
-rw-r--r--chalk/plugins/tools/selectiontools/kis_tool_select_eraser.cc156
-rw-r--r--chalk/plugins/tools/selectiontools/kis_tool_select_eraser.h82
-rw-r--r--chalk/plugins/tools/selectiontools/kis_tool_select_outline.cc295
-rw-r--r--chalk/plugins/tools/selectiontools/kis_tool_select_outline.h101
-rw-r--r--chalk/plugins/tools/selectiontools/kis_tool_select_polygonal.cc315
-rw-r--r--chalk/plugins/tools/selectiontools/kis_tool_select_polygonal.h106
-rw-r--r--chalk/plugins/tools/selectiontools/kis_tool_select_rectangular.cc323
-rw-r--r--chalk/plugins/tools/selectiontools/kis_tool_select_rectangular.h95
-rw-r--r--chalk/plugins/tools/selectiontools/selection_tools.cc77
-rw-r--r--chalk/plugins/tools/selectiontools/selection_tools.h44
-rw-r--r--chalk/plugins/tools/selectiontools/tool_brush_selection.pngbin0 -> 1052 bytes
-rw-r--r--chalk/plugins/tools/selectiontools/tool_brush_selection.svg827
-rw-r--r--chalk/plugins/tools/selectiontools/tool_brush_selection_cursor.pngbin0 -> 339 bytes
-rw-r--r--chalk/plugins/tools/selectiontools/tool_contiguous_selection.pngbin0 -> 836 bytes
-rw-r--r--chalk/plugins/tools/selectiontools/tool_contiguous_selection_cursor.pngbin0 -> 321 bytes
-rw-r--r--chalk/plugins/tools/selectiontools/tool_elliptical_selection.pngbin0 -> 703 bytes
-rw-r--r--chalk/plugins/tools/selectiontools/tool_elliptical_selection.svg256
-rw-r--r--chalk/plugins/tools/selectiontools/tool_elliptical_selection_cursor.pngbin0 -> 296 bytes
-rw-r--r--chalk/plugins/tools/selectiontools/tool_eraser_selection.pngbin0 -> 1087 bytes
-rw-r--r--chalk/plugins/tools/selectiontools/tool_eraser_selection.svg1993
-rw-r--r--chalk/plugins/tools/selectiontools/tool_eraser_selection_cursor.pngbin0 -> 341 bytes
-rw-r--r--chalk/plugins/tools/selectiontools/tool_outline_selection.pngbin0 -> 556 bytes
-rw-r--r--chalk/plugins/tools/selectiontools/tool_outline_selection.svg329
-rw-r--r--chalk/plugins/tools/selectiontools/tool_outline_selection_cursor.pngbin0 -> 359 bytes
-rw-r--r--chalk/plugins/tools/selectiontools/tool_polygonal_selection.pngbin0 -> 576 bytes
-rw-r--r--chalk/plugins/tools/selectiontools/tool_polygonal_selection.svg364
-rw-r--r--chalk/plugins/tools/selectiontools/tool_polygonal_selection_cursor.pngbin0 -> 433 bytes
-rw-r--r--chalk/plugins/tools/selectiontools/tool_rect_selection.pngbin0 -> 523 bytes
-rw-r--r--chalk/plugins/tools/selectiontools/tool_rect_selection.svg191
-rw-r--r--chalk/plugins/tools/selectiontools/tool_rectangular_selection_cursor.pngbin0 -> 224 bytes
-rw-r--r--chalk/plugins/tools/tool_crop/Makefile.am37
-rw-r--r--chalk/plugins/tools/tool_crop/chalktoolcrop.desktop47
-rw-r--r--chalk/plugins/tools/tool_crop/kis_tool_crop.cc925
-rw-r--r--chalk/plugins/tools/tool_crop/kis_tool_crop.h149
-rw-r--r--chalk/plugins/tools/tool_crop/tool_crop.cc62
-rw-r--r--chalk/plugins/tools/tool_crop/tool_crop.h43
-rw-r--r--chalk/plugins/tools/tool_crop/tool_crop.pngbin0 -> 693 bytes
-rw-r--r--chalk/plugins/tools/tool_crop/tool_crop_cursor.pngbin0 -> 306 bytes
-rw-r--r--chalk/plugins/tools/tool_crop/wdg_tool_crop.ui216
-rw-r--r--chalk/plugins/tools/tool_curves/Makefile.am56
-rw-r--r--chalk/plugins/tools/tool_curves/chalktoolcurves.desktop36
-rw-r--r--chalk/plugins/tools/tool_curves/kis_curve_framework.cc260
-rw-r--r--chalk/plugins/tools/tool_curves/kis_curve_framework.h354
-rw-r--r--chalk/plugins/tools/tool_curves/kis_tool_bezier.cc366
-rw-r--r--chalk/plugins/tools/tool_curves/kis_tool_bezier.h98
-rw-r--r--chalk/plugins/tools/tool_curves/kis_tool_bezier_paint.cc115
-rw-r--r--chalk/plugins/tools/tool_curves/kis_tool_bezier_paint.h63
-rw-r--r--chalk/plugins/tools/tool_curves/kis_tool_bezier_select.cc104
-rw-r--r--chalk/plugins/tools/tool_curves/kis_tool_bezier_select.h63
-rw-r--r--chalk/plugins/tools/tool_curves/kis_tool_curve.cc593
-rw-r--r--chalk/plugins/tools/tool_curves/kis_tool_curve.h205
-rw-r--r--chalk/plugins/tools/tool_curves/kis_tool_example.cc108
-rw-r--r--chalk/plugins/tools/tool_curves/kis_tool_example.h67
-rw-r--r--chalk/plugins/tools/tool_curves/kis_tool_moutline.cc809
-rw-r--r--chalk/plugins/tools/tool_curves/kis_tool_moutline.h132
-rw-r--r--chalk/plugins/tools/tool_curves/tool_bezier_cursor.pngbin0 -> 2854 bytes
-rw-r--r--chalk/plugins/tools/tool_curves/tool_bezier_paint.pngbin0 -> 680 bytes
-rw-r--r--chalk/plugins/tools/tool_curves/tool_bezier_select.pngbin0 -> 637 bytes
-rw-r--r--chalk/plugins/tools/tool_curves/tool_curve_dragging.pngbin0 -> 2956 bytes
-rw-r--r--chalk/plugins/tools/tool_curves/tool_curves.cc67
-rw-r--r--chalk/plugins/tools/tool_curves/tool_curves.h36
-rw-r--r--chalk/plugins/tools/tool_curves/tool_example.pngbin0 -> 2918 bytes
-rw-r--r--chalk/plugins/tools/tool_curves/tool_example_cursor.pngbin0 -> 2854 bytes
-rw-r--r--chalk/plugins/tools/tool_curves/tool_moutline.pngbin0 -> 778 bytes
-rw-r--r--chalk/plugins/tools/tool_curves/tool_moutline_cursor.pngbin0 -> 2858 bytes
-rw-r--r--chalk/plugins/tools/tool_curves/tool_moutline_editing.pngbin0 -> 2968 bytes
-rw-r--r--chalk/plugins/tools/tool_curves/wdg_tool_example.ui128
-rw-r--r--chalk/plugins/tools/tool_filter/Makefile.am38
-rw-r--r--chalk/plugins/tools/tool_filter/chalktoolfilter.desktop92
-rw-r--r--chalk/plugins/tools/tool_filter/kis_filterop.cc154
-rw-r--r--chalk/plugins/tools/tool_filter/kis_filterop.h63
-rw-r--r--chalk/plugins/tools/tool_filter/kis_tool_filter.cc154
-rw-r--r--chalk/plugins/tools/tool_filter/kis_tool_filter.h81
-rw-r--r--chalk/plugins/tools/tool_filter/tool_filter.cc68
-rw-r--r--chalk/plugins/tools/tool_filter/tool_filter.h43
-rw-r--r--chalk/plugins/tools/tool_filter/tool_filter.pngbin0 -> 497 bytes
-rw-r--r--chalk/plugins/tools/tool_filter/tool_filter.svg468
-rw-r--r--chalk/plugins/tools/tool_filter/tool_filter_cursor.pngbin0 -> 295 bytes
-rw-r--r--chalk/plugins/tools/tool_perspectivegrid/Makefile.am35
-rw-r--r--chalk/plugins/tools/tool_perspectivegrid/chalktoolperspectivegrid.desktop35
-rw-r--r--chalk/plugins/tools/tool_perspectivegrid/kis_tool_perspectivegrid.cc499
-rw-r--r--chalk/plugins/tools/tool_perspectivegrid/kis_tool_perspectivegrid.h111
-rw-r--r--chalk/plugins/tools/tool_perspectivegrid/tool_perspectivegrid.cc62
-rw-r--r--chalk/plugins/tools/tool_perspectivegrid/tool_perspectivegrid.h43
-rw-r--r--chalk/plugins/tools/tool_perspectivegrid/tool_perspectivegrid.pngbin0 -> 738 bytes
-rw-r--r--chalk/plugins/tools/tool_perspectivegrid/tool_perspectivegrid.svg87
-rw-r--r--chalk/plugins/tools/tool_perspectivetransform/Makefile.am35
-rw-r--r--chalk/plugins/tools/tool_perspectivetransform/chalktoolperspectivetransform.desktop37
-rw-r--r--chalk/plugins/tools/tool_perspectivetransform/kis_tool_perspectivetransform.cc742
-rw-r--r--chalk/plugins/tools/tool_perspectivetransform/kis_tool_perspectivetransform.h131
-rw-r--r--chalk/plugins/tools/tool_perspectivetransform/tool_perspectivetransform.cc63
-rw-r--r--chalk/plugins/tools/tool_perspectivetransform/tool_perspectivetransform.h43
-rw-r--r--chalk/plugins/tools/tool_perspectivetransform/tool_perspectivetransform.pngbin0 -> 691 bytes
-rw-r--r--chalk/plugins/tools/tool_perspectivetransform/tool_perspectivetransform.svg87
-rw-r--r--chalk/plugins/tools/tool_polygon/Makefile.am36
-rw-r--r--chalk/plugins/tools/tool_polygon/chalktoolpolygon.desktop52
-rw-r--r--chalk/plugins/tools/tool_polygon/kis_tool_polygon.cc252
-rw-r--r--chalk/plugins/tools/tool_polygon/kis_tool_polygon.h102
-rw-r--r--chalk/plugins/tools/tool_polygon/tool_polygon.cc62
-rw-r--r--chalk/plugins/tools/tool_polygon/tool_polygon.h39
-rw-r--r--chalk/plugins/tools/tool_polygon/tool_polygon.pngbin0 -> 773 bytes
-rw-r--r--chalk/plugins/tools/tool_polygon/tool_polygon_cursor.pngbin0 -> 402 bytes
-rw-r--r--chalk/plugins/tools/tool_polyline/Makefile.am36
-rw-r--r--chalk/plugins/tools/tool_polyline/chalktoolpolyline.desktop49
-rw-r--r--chalk/plugins/tools/tool_polyline/kis_tool_polyline.cc271
-rw-r--r--chalk/plugins/tools/tool_polyline/kis_tool_polyline.h109
-rw-r--r--chalk/plugins/tools/tool_polyline/polyline.pngbin0 -> 587 bytes
-rw-r--r--chalk/plugins/tools/tool_polyline/tool_polyline.cc64
-rw-r--r--chalk/plugins/tools/tool_polyline/tool_polyline.h43
-rw-r--r--chalk/plugins/tools/tool_polyline/tool_polyline_cursor.pngbin0 -> 397 bytes
-rw-r--r--chalk/plugins/tools/tool_selectsimilar/Makefile.am32
-rw-r--r--chalk/plugins/tools/tool_selectsimilar/chalktoolselectsimilar.desktop43
-rw-r--r--chalk/plugins/tools/tool_selectsimilar/kis_tool_selectsimilar.cc271
-rw-r--r--chalk/plugins/tools/tool_selectsimilar/kis_tool_selectsimilar.h102
-rw-r--r--chalk/plugins/tools/tool_selectsimilar/selectsimilar.cc61
-rw-r--r--chalk/plugins/tools/tool_selectsimilar/selectsimilar.h35
-rw-r--r--chalk/plugins/tools/tool_selectsimilar/tool_similar_selection.pngbin0 -> 724 bytes
-rw-r--r--chalk/plugins/tools/tool_selectsimilar/tool_similar_selection.svg2118
-rw-r--r--chalk/plugins/tools/tool_selectsimilar/tool_similar_selection_minus_cursor.pngbin0 -> 613 bytes
-rw-r--r--chalk/plugins/tools/tool_selectsimilar/tool_similar_selection_plus_cursor.pngbin0 -> 630 bytes
-rw-r--r--chalk/plugins/tools/tool_star/Makefile.am37
-rw-r--r--chalk/plugins/tools/tool_star/chalktoolstar.desktop52
-rw-r--r--chalk/plugins/tools/tool_star/kis_tool_star.cc245
-rw-r--r--chalk/plugins/tools/tool_star/kis_tool_star.h101
-rw-r--r--chalk/plugins/tools/tool_star/tool_star.cc62
-rw-r--r--chalk/plugins/tools/tool_star/tool_star.h43
-rw-r--r--chalk/plugins/tools/tool_star/tool_star.pngbin0 -> 625 bytes
-rw-r--r--chalk/plugins/tools/tool_star/tool_star_cursor.pngbin0 -> 367 bytes
-rw-r--r--chalk/plugins/tools/tool_star/wdg_tool_star.ui128
-rw-r--r--chalk/plugins/tools/tool_transform/Makefile.am37
-rw-r--r--chalk/plugins/tools/tool_transform/chalktooltransform.desktop46
-rw-r--r--chalk/plugins/tools/tool_transform/kis_tool_transform.cc916
-rw-r--r--chalk/plugins/tools/tool_transform/kis_tool_transform.h155
-rw-r--r--chalk/plugins/tools/tool_transform/rotate_cursor.xpm29
-rw-r--r--chalk/plugins/tools/tool_transform/tool_transform.cc64
-rw-r--r--chalk/plugins/tools/tool_transform/tool_transform.h43
-rw-r--r--chalk/plugins/tools/tool_transform/tool_transform.pngbin0 -> 458 bytes
-rw-r--r--chalk/plugins/tools/tool_transform/wdg_tool_transform.ui243
202 files changed, 25435 insertions, 0 deletions
diff --git a/chalk/plugins/tools/Makefile.am b/chalk/plugins/tools/Makefile.am
new file mode 100644
index 00000000..eb40c4e9
--- /dev/null
+++ b/chalk/plugins/tools/Makefile.am
@@ -0,0 +1,3 @@
+SUBDIRS = defaulttools selectiontools tool_crop tool_curves tool_filter \
+ tool_polygon tool_polyline tool_selectsimilar tool_star tool_transform \
+ tool_perspectivegrid tool_perspectivetransform
diff --git a/chalk/plugins/tools/defaulttools/Makefile.am b/chalk/plugins/tools/defaulttools/Makefile.am
new file mode 100644
index 00000000..b8998604
--- /dev/null
+++ b/chalk/plugins/tools/defaulttools/Makefile.am
@@ -0,0 +1,83 @@
+kde_services_DATA = chalkdefaulttools.desktop
+
+# all_includes must remain last!
+INCLUDES = -I$(srcdir)/../../../sdk \
+ -I$(srcdir)/../../../core \
+ -I$(srcdir)/../../../chalkcolor/ \
+ -I$(srcdir)/../../../ui \
+ -I$/../../../ui \
+ $(KOFFICE_INCLUDES) \
+ $(all_includes)
+
+chalkdefaulttools_la_SOURCES = \
+ default_tools.cc \
+ kis_tool_colorpicker.cc \
+ kis_tool_move.cc \
+ kis_tool_zoom.cc \
+ kis_tool_brush.cc \
+ kis_tool_line.cc \
+ kis_tool_duplicate.cc \
+ kis_tool_fill.cc \
+ kis_tool_rectangle.cc \
+ kis_tool_ellipse.cc \
+ kis_tool_pan.cc \
+ kis_tool_text.cc \
+ kis_tool_gradient.cc \
+ wdgcolorpicker.ui
+
+# Install this plugin in the KDE modules directory
+kde_module_LTLIBRARIES = chalkdefaulttools.la
+
+noinst_HEADERS = \
+ default_tools.h \
+ kis_tool_fill.h \
+ kis_tool_brush.h \
+ kis_tool_gradient.h \
+ kis_tool_rectangle.h \
+ kis_tool_colorpicker.h \
+ kis_tool_line.h \
+ kis_tool_text.h \
+ kis_tool_duplicate.h \
+ kis_tool_move.h \
+ kis_tool_zoom.h \
+ kis_tool_ellipse.h \
+ kis_tool_pan.h
+
+
+chalkdefaulttools_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) $(LIB_QT) -lkdecore -lkdeui -lkjs -lkdefx -lkio -lkparts -L../../../../chalk/chalkcolor/.libs -lchalkcolor -L../../../../chalk/core/.libs -lchalkimage \
+ -L../../../../chalk/ui/.libs -lchalkui
+chalkdefaulttools_la_LIBADD = ../../../libchalkcommon.la $(LIB_KOPAINTER) $(LIB_KOFFICECORE)
+
+chalkdefaulttools_la_METASOURCES = AUTO
+
+KDE_OPTIONS = nofinal
+
+chalkpics_DATA = \
+ tool_rectangle_cursor.png \
+ tool_ellipse_cursor.png \
+ tool_line_cursor.png \
+ tool_freehand_cursor.png \
+ tool_duplicate_cursor.png \
+ tool_fill_cursor.png \
+ tool_color_fill.png \
+ tool_text_cursor.png \
+ tool_gradient_cursor.png \
+ tool_gradient.png \
+ tool_line.png \
+ tool_rectangle.png \
+ tool_ellipse.png \
+ tool_pan.png \
+ tool_freehand.png \
+ tool_text.png \
+ openhand_cursor.xpm \
+ closedhand_cursor.xpm \
+ tool_zoom_plus_cursor.png \
+ tool_zoom_minus_cursor.png \
+ tool_move.png \
+ tool_colorpicker.png \
+ tool_duplicate.png \
+ tool_zoom.png
+
+
+chalkpicsdir = $(kde_datadir)/chalk/pics
+
diff --git a/chalk/plugins/tools/defaulttools/chalkdefaulttools.desktop b/chalk/plugins/tools/defaulttools/chalkdefaulttools.desktop
new file mode 100644
index 00000000..6472d637
--- /dev/null
+++ b/chalk/plugins/tools/defaulttools/chalkdefaulttools.desktop
@@ -0,0 +1,56 @@
+[Desktop Entry]
+Name=Default Tools
+Name[bg]=Инструменти по подразбиране
+Name[br]=Ostilhoù dre ziouer
+Name[ca]=Eines per defecte
+Name[cy]=Offer Rhagosodol
+Name[da]=Standardværktøjer
+Name[de]=Standardwerkzeuge
+Name[el]=Προκαθορισμένα εργαλεία
+Name[eo]=Aprioraj Iloj
+Name[es]=Herramientas predefinidas
+Name[et]=Vaiketööriistad
+Name[eu]=Tresna lehenetsiak
+Name[fa]=ابزارهای پیش‌فرض
+Name[fi]=Oletustyökalut
+Name[fr]=Outils par défaut
+Name[fy]=Standert ark
+Name[ga]=Uirlisí Réamhshocraithe
+Name[gl]=Ferramentas Predefinidas
+Name[he]=כלים המוגדרים כברירת מחדל
+Name[hi]=डिफ़ॉल्ट औज़ार
+Name[hr]=Zadani alati
+Name[hu]=Alapértelmezett eszközök
+Name[is]=Sjálfgefin tól
+Name[it]=Strumenti predefiniti
+Name[ja]=標準ツール
+Name[km]=ឧបករណ៍​លំនាំដើម
+Name[lt]=Numatyti įrankiai
+Name[lv]=Noklusējuma rīks
+Name[ms]=Alat Piawai
+Name[nb]=Standardverktøy
+Name[nds]=Standardwarktüüch
+Name[ne]=पूर्वनिर्धारित उपकरणहरू
+Name[nl]=Standaardgereedschappen
+Name[nn]=Standardverktøy
+Name[pl]=Domyślne narzędzia
+Name[pt]=Ferramentas Predefinidas
+Name[pt_BR]=Ferramentas Padrão
+Name[ru]=Стандартный инструментарий
+Name[se]=Standárdreaiddut
+Name[sk]=Štandardné nástroje
+Name[sl]=Privzeta orodja
+Name[sr]=Подразумевани алати
+Name[sr@Latn]=Podrazumevani alati
+Name[sv]=Standardverktyg
+Name[ta]=முன்னிருப்பு கருவிகள்
+Name[tr]=Öntanımlı Araçlar
+Name[uk]=Типові інструменти
+Name[uz]=Andoza vositalar
+Name[uz@cyrillic]=Андоза воситалар
+Name[zh_CN]=默认工具
+Name[zh_TW]=預設工具
+ServiceTypes=Chalk/Tool
+Type=Service
+X-KDE-Library=chalkdefaulttools
+X-Chalk-Version=2
diff --git a/chalk/plugins/tools/defaulttools/closedhand_cursor.xpm b/chalk/plugins/tools/defaulttools/closedhand_cursor.xpm
new file mode 100644
index 00000000..b3d98f85
--- /dev/null
+++ b/chalk/plugins/tools/defaulttools/closedhand_cursor.xpm
@@ -0,0 +1,28 @@
+/* XPM */
+static char *closedhand_cursor[]={
+"22 22 3 1",
+". c None",
+"# c #000000",
+"a c #ffffff",
+"......................",
+"......................",
+"......................",
+"......................",
+".......##.##.##.......",
+"......#aa#aa#aa###....",
+"......#aa#aa#aa#aa#...",
+"......#aa#aa#aa#aa#...",
+".....##aaaaaaaa#aa#...",
+"....#a#aaaaaaaaaaa#...",
+"....#a#aaaaaaaaaaa#...",
+"....#a#aaaaaaaaaaa#...",
+"....#aaaaaaaaaaaaa#...",
+".....#aaaaaaaaaaaa#...",
+".....#aaaaaaaaaaa#....",
+"......#aaaaaaaaaa#....",
+"......#aaaaaaaaaa#....",
+".......#aaaaaaaa#.....",
+".......#aaaaaaaa#.....",
+".......##########.....",
+"......................",
+"......................"};
diff --git a/chalk/plugins/tools/defaulttools/default_tools.cc b/chalk/plugins/tools/defaulttools/default_tools.cc
new file mode 100644
index 00000000..61d06e98
--- /dev/null
+++ b/chalk/plugins/tools/defaulttools/default_tools.cc
@@ -0,0 +1,88 @@
+/*
+ * default_tools.cc -- Part of Chalk
+ *
+ * Copyright (c) 2004 Boudewijn Rempt (boud@valdyas.org)
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+#include <stdlib.h>
+#include <vector>
+
+#include <tqpoint.h>
+
+#include <klocale.h>
+#include <kiconloader.h>
+#include <kinstance.h>
+#include <kmessagebox.h>
+#include <kstandarddirs.h>
+#include <ktempfile.h>
+#include <kdebug.h>
+#include <kgenericfactory.h>
+
+#include <kis_global.h>
+#include <kis_types.h>
+#include <kis_tool.h>
+#include <kis_tool_registry.h>
+#include "default_tools.h"
+
+#include "kis_tool_fill.h"
+#include "kis_tool_brush.h"
+#include "kis_tool_freehand.h"
+#include "kis_tool_gradient.h"
+#include "kis_tool_rectangle.h"
+#include "kis_tool_colorpicker.h"
+#include "kis_tool_line.h"
+#include "kis_tool_text.h"
+#include "kis_tool_duplicate.h"
+#include "kis_tool_move.h"
+#include "kis_tool_zoom.h"
+#include "kis_tool_ellipse.h"
+#include "kis_tool_pan.h"
+
+
+typedef KGenericFactory<DefaultTools> DefaultToolsFactory;
+K_EXPORT_COMPONENT_FACTORY( chalkdefaulttools, DefaultToolsFactory( "chalk" ) )
+
+
+DefaultTools::DefaultTools(TQObject *tqparent, const char *name, const TQStringList &)
+ : KParts::Plugin(tqparent, name)
+{
+ setInstance(DefaultToolsFactory::instance());
+
+ if ( tqparent->inherits("KisToolRegistry") )
+ {
+ KisToolRegistry * r = dynamic_cast<KisToolRegistry*>(tqparent);
+
+ r->add(new KisToolFillFactory());
+ r->add(new KisToolGradientFactory());
+ r->add(new KisToolBrushFactory());
+ r->add(new KisToolColorPickerFactory());
+ r->add(new KisToolLineFactory());
+ r->add(new KisToolTextFactory());
+ r->add(new KisToolDuplicateFactory());
+ r->add(new KisToolMoveFactory());
+ r->add(new KisToolZoomFactory());
+ r->add(new KisToolEllipseFactory());
+ r->add(new KisToolRectangleFactory());
+ r->add(new KisToolPanFactory());
+
+ }
+}
+
+DefaultTools::~DefaultTools()
+{
+}
+
+#include "default_tools.moc"
diff --git a/chalk/plugins/tools/defaulttools/default_tools.h b/chalk/plugins/tools/defaulttools/default_tools.h
new file mode 100644
index 00000000..c50a9147
--- /dev/null
+++ b/chalk/plugins/tools/defaulttools/default_tools.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2003 Boudewijn Rempt (boud@valdyas.org)
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef DEFAULT_TOOLS_H_
+#define DEFAULT_TOOLS_H_
+
+#include <kparts/plugin.h>
+
+/**
+ * A module wrapper around Chalk's default tools.
+ * Despite the fact that new tools are created for every new view,
+ * it is not possible to make tools standard parts of the type of the
+ * imagesize plugin, because we need to create a new set of tools for every
+ * pointer device (mouse, stylus, eraser, puck, etc.). So this plugin is
+ * a module which is loaded once into Chalk. For every tool there is a factory
+ * class that is registered with the tool registry, and that is used to create
+ * new instances of the tools.
+ */
+class DefaultTools : public KParts::Plugin
+{
+ Q_OBJECT
+ TQ_OBJECT
+public:
+ DefaultTools(TQObject *tqparent, const char *name, const TQStringList &);
+ virtual ~DefaultTools();
+
+};
+
+#endif // DEFAULT_TOOLS_H_
diff --git a/chalk/plugins/tools/defaulttools/kis_tool_brush.cc b/chalk/plugins/tools/defaulttools/kis_tool_brush.cc
new file mode 100644
index 00000000..373e0a07
--- /dev/null
+++ b/chalk/plugins/tools/defaulttools/kis_tool_brush.cc
@@ -0,0 +1,167 @@
+/*
+ * kis_tool_brush.cc - part of Chalk
+ *
+ * Copyright (c) 2003-2004 Boudewijn Rempt <boud@valdyas.org>
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+#include <tqevent.h>
+#include <tqlabel.h>
+#include <tqlayout.h>
+#include <tqwidget.h>
+#include <tqtimer.h>
+#include <tqpushbutton.h>
+#include <tqpainter.h>
+#include <tqrect.h>
+#include <tqcheckbox.h>
+
+#include <kdebug.h>
+#include <kaction.h>
+#include <kcommand.h>
+#include <klocale.h>
+
+#include "kis_config.h"
+#include "kis_brush.h"
+#include "kis_paintop.h"
+#include "kis_paintop_registry.h"
+#include "kis_cmb_composite.h"
+#include "kis_cursor.h"
+#include "kis_painter.h"
+#include "kis_tool_brush.h"
+#include "kis_canvas_subject.h"
+#include "kis_boundary.h"
+#include "kis_move_event.h"
+#include "kis_canvas.h"
+#include "kis_layer.h"
+
+KisToolBrush::KisToolBrush()
+ : super(i18n("Brush"))
+{
+ setName("tool_brush");
+ setCursor(KisCursor::load("tool_freehand_cursor.png", 5, 5));
+ m_rate = 100; // Conveniently hardcoded for now
+ m_timer = new TQTimer(this);
+ Q_CHECK_PTR(m_timer);
+
+ connect(m_timer, TQT_SIGNAL(timeout()), this, TQT_SLOT(timeoutPaint()));
+
+}
+
+KisToolBrush::~KisToolBrush()
+{
+ delete m_timer;
+ m_timer = 0;
+}
+
+void KisToolBrush::timeoutPaint()
+{
+ if (currentImage() && painter()) {
+ painter()->paintAt(m_prevPos, m_prevPressure, m_prevXTilt, m_prevYTilt);
+ currentImage()->activeLayer()->setDirty(painter()->dirtyRect());
+ }
+}
+
+
+void KisToolBrush::update(KisCanvasSubject *subject)
+{
+ super::update(subject);
+}
+
+void KisToolBrush::initPaint(KisEvent *e)
+{
+ super::initPaint(e);
+
+ if (!m_painter) {
+ kdWarning() << "Didn't create a painter! Something is wrong!\n";
+ return;
+ }
+ KisPaintOp * op = KisPaintOpRegistry::instance()->paintOp(m_subject->currentPaintop(), m_subject->currentPaintopSettings(), m_painter);
+ if (!op) return;
+
+ m_subject->canvasController()->kiscanvas()->update(); // remove the outline
+
+ painter()->setPaintOp(op); // And now the painter owns the op and will destroy it.
+
+ if (op->incremental()) {
+ m_timer->start( m_rate );
+ }
+}
+
+
+void KisToolBrush::endPaint()
+{
+ m_timer->stop();
+ super::endPaint();
+}
+
+
+void KisToolBrush::setup(KActionCollection *collection)
+{
+
+ m_action = static_cast<KRadioAction *>(collection->action(name()));
+
+ if (m_action == 0) {
+ m_action = new KRadioAction(i18n("&Brush"),
+ "tool_freehand", TQt::Key_B, this,
+ TQT_SLOT(activate()), collection,
+ name());
+ m_action->setToolTip(i18n("Draw freehand"));
+ m_action->setExclusiveGroup("tools");
+ m_ownAction = true;
+ }
+}
+
+void KisToolBrush::move(KisMoveEvent *e) {
+ KisToolFreehand::move(e);
+ KisConfig cfg;
+ if (m_mode != PAINT && cfg.cursorStyle() == CURSOR_STYLE_OUTLINE)
+ paintOutline(e->pos());
+}
+
+void KisToolBrush::leave(TQEvent */*e*/) {
+ m_subject->canvasController()->kiscanvas()->update(); // remove the outline
+}
+
+
+void KisToolBrush::slotSetPaintingMode( int mode )
+{
+ if (mode == TQButton::On) {
+ // Direct painting
+ m_paintIncremental = true;
+ }
+ else {
+ m_paintIncremental = false;
+ }
+}
+
+
+TQWidget* KisToolBrush::createOptionWidget(TQWidget* tqparent)
+{
+ TQWidget *widget = super::createOptionWidget(tqparent);
+ m_chkDirect = new TQCheckBox(i18n("Paint direct"), widget, "chkDirect");
+ m_chkDirect->setChecked(true);
+ connect(m_chkDirect, TQT_SIGNAL(stateChanged(int)), this, TQT_SLOT(slotSetPaintingMode(int)));
+
+ m_optionLayout = new TQGridLayout(widget, 3, 2, 0, 6);
+ Q_CHECK_PTR(m_optionLayout);
+
+ super::addOptionWidgetLayout(m_optionLayout);
+ m_optionLayout->addWidget(m_chkDirect, 0, 0);
+
+ return widget;
+}
+
+#include "kis_tool_brush.moc"
+
diff --git a/chalk/plugins/tools/defaulttools/kis_tool_brush.h b/chalk/plugins/tools/defaulttools/kis_tool_brush.h
new file mode 100644
index 00000000..a23e8d12
--- /dev/null
+++ b/chalk/plugins/tools/defaulttools/kis_tool_brush.h
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2003-2004 Boudewijn Rempt <boud@valdyas.org>
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef KIS_TOOL_BRUSH_H_
+#define KIS_TOOL_BRUSH_H_
+
+
+#include "kis_tool_freehand.h"
+
+#include "kis_tool_factory.h"
+#include "koffice_export.h"
+
+class TQTimer;
+class KisPoint;
+class TQHBoxLayout;
+class TQPainter;
+class TQRect;
+class TQCheckBox;
+class TQGridLayout;
+
+class KRITACORE_EXPORT KisToolBrush : public KisToolFreehand {
+ Q_OBJECT
+ TQ_OBJECT
+ typedef KisToolFreehand super;
+
+public:
+ KisToolBrush();
+ virtual ~KisToolBrush();
+ virtual void update(KisCanvasSubject *subject);
+ virtual void setup(KActionCollection *collection);
+ virtual enumToolType toolType() { return TOOL_SHAPE; }
+ virtual TQ_UINT32 priority() { return 0; }
+ TQWidget* createOptionWidget(TQWidget* tqparent);
+
+protected:
+
+ virtual void initPaint(KisEvent *e);
+ virtual void endPaint();
+ virtual void move(KisMoveEvent *e);
+ virtual void leave(TQEvent *e);
+
+private slots:
+
+ void timeoutPaint();
+ void slotSetPaintingMode( int mode );
+
+private:
+
+ TQ_INT32 m_rate;
+ TQTimer * m_timer;
+ TQGridLayout* m_optionLayout;
+ TQCheckBox * m_chkDirect;
+};
+
+class KisToolBrushFactory : public KisToolFactory {
+ typedef KisToolFactory super;
+public:
+ KisToolBrushFactory() : super() {};
+ virtual ~KisToolBrushFactory(){};
+
+ virtual KisTool * createTool(KActionCollection * ac) {
+ KisTool * t = new KisToolBrush();
+ Q_CHECK_PTR(t);
+ t->setup(ac);
+ return t;
+ }
+ virtual KisID id() { return KisID("brush", i18n("Brush Tool")); }
+};
+
+
+#endif // KIS_TOOL_BRUSH_H_
+
diff --git a/chalk/plugins/tools/defaulttools/kis_tool_colorpicker.cc b/chalk/plugins/tools/defaulttools/kis_tool_colorpicker.cc
new file mode 100644
index 00000000..32dbcf9d
--- /dev/null
+++ b/chalk/plugins/tools/defaulttools/kis_tool_colorpicker.cc
@@ -0,0 +1,298 @@
+/*
+ * Copyright (c) 1999 Matthias Elter <me@kde.org>
+ * Copyright (c) 2002 Patrick Julien <freak@codepimps.org>
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+#include <string.h>
+
+#include <tqpoint.h>
+#include <tqlayout.h>
+#include <tqcheckbox.h>
+#include <tqcombobox.h>
+#include <tqlistview.h>
+#include <tqspinbox.h>
+
+#include <kaction.h>
+#include <klocale.h>
+#include <tqcolor.h>
+#include <kmessagebox.h>
+
+#include "kis_layer.h"
+#include "kis_cursor.h"
+#include "kis_canvas_subject.h"
+#include "kis_image.h"
+#include "kis_paint_device.h"
+#include "kis_tool_colorpicker.h"
+#include "kis_tool_colorpicker.moc"
+#include "kis_button_press_event.h"
+#include "kis_canvas_subject.h"
+#include "kis_iterators_pixel.h"
+#include "kis_color.h"
+#include "kis_resourceserver.h"
+#include "kis_palette.h"
+#include "wdgcolorpicker.h"
+
+namespace {
+ // The location of the sample all visible layers in the combobox
+ const int SAMPLE_MERGED = 0;
+}
+
+KisToolColorPicker::KisToolColorPicker()
+ : super (i18n("Color Picker"))
+{
+ setName("tool_colorpicker");
+ setCursor(KisCursor::pickerCursor());
+ m_optionsWidget = 0;
+ m_subject = 0;
+ m_radius = 1;
+ m_addPalette = false;
+ m_updateColor = true;
+ m_normaliseValues = false;
+ m_pickedColor = KisColor();
+}
+
+KisToolColorPicker::~KisToolColorPicker()
+{
+}
+
+void KisToolColorPicker::update(KisCanvasSubject *subject)
+{
+ m_subject = subject;
+ super::update(m_subject);
+}
+
+void KisToolColorPicker::buttonPress(KisButtonPressEvent *e)
+{
+ if (m_subject) {
+ if (e->button() != Qt::LeftButton && e->button() != Qt::RightButton)
+ return;
+
+ KisImageSP img;
+
+ if (!m_subject || !(img = m_subject->currentImg()))
+ return;
+
+ KisPaintDeviceSP dev = img->activeDevice();
+
+ if (!dev) return;
+
+ bool sampleMerged = m_optionsWidget->cmbSources->currentItem() == SAMPLE_MERGED;
+ if (!sampleMerged) {
+ if (!img->activeLayer())
+ {
+ KMessageBox::information(0, i18n("Cannot pick a color as no layer is active."));
+ return;
+ }
+ if (!img->activeLayer()-> visible()) {
+ KMessageBox::information(0, i18n("Cannot pick a color as the active layer is not visible."));
+ return;
+ }
+ }
+
+ TQPoint pos = TQPoint(e->pos().floorX(), e->pos().floorY());
+
+ if (!img->bounds().tqcontains(pos)) {
+ return;
+ }
+
+ if (sampleMerged) {
+ dev = img->mergedImage();
+ }
+
+ if (m_radius == 1) {
+ m_pickedColor = dev->colorAt (pos.x(), pos.y());
+ } else {
+ // radius 2 ==> 9 pixels, 3 => 9 pixels, etc
+ static int counts[] = { 0, 1, 9, 25, 45, 69, 109, 145, 193, 249 };
+
+ KisColorSpace* cs = dev->colorSpace();
+ int pixelSize = cs->pixelSize();
+
+ TQ_UINT8* data = new TQ_UINT8[pixelSize];
+ TQ_UINT8** pixels = new TQ_UINT8*[counts[m_radius]];
+ TQ_UINT8* weights = new TQ_UINT8[counts[m_radius]];
+
+ int i = 0;
+ // dummy init
+ KisHLineIteratorPixel iter = dev->createHLineIterator(0, 0, 1, false);;
+ for (int y = - m_radius; y <= m_radius; y++) {
+ for (int x = - m_radius; x <= m_radius; x++) {
+ if (x*x + y*y < m_radius * m_radius) {
+ iter = dev->createHLineIterator(pos.x() + x, pos.y() + y, 1, false);
+
+ pixels[i] = new TQ_UINT8[pixelSize];
+ memcpy(pixels[i], iter.rawData(), pixelSize);
+
+ if (x == 0 && y == 0) {
+ // Because the sum of the weights must be 255,
+ // we cheat a bit, and weigh the center pixel differently in order
+ // to sum to 255 in total
+ // It's -(counts -1), because we'll add the center one implicitly
+ // through that calculation
+ weights[i] = 255 - (counts[m_radius]-1) * (255 / counts[m_radius]);
+ } else {
+ weights[i] = 255 / counts[m_radius];
+ }
+ i++;
+ }
+ }
+ }
+ // Weird, I can't do that directly :/
+ const TQ_UINT8** cpixels = const_cast<const TQ_UINT8**>(pixels);
+ cs->mixColors(cpixels, weights, counts[m_radius], data);
+ m_pickedColor = KisColor(data, cs);
+
+ for (i = 0; i < counts[m_radius]; i++)
+ delete[] pixels[i];
+ delete[] pixels;
+ delete[] data;
+ }
+
+ displayPickedColor();
+
+ if (m_updateColor) {
+ if (e->button() == Qt::LeftButton)
+ m_subject->setFGColor(m_pickedColor);
+ else
+ m_subject->setBGColor(m_pickedColor);
+ }
+
+ if (m_addPalette) {
+ // Convert to RGB to add to palette, we ought to have our own format :(
+ KisPaletteEntry ent;
+ ent.color = m_pickedColor.toTQColor();
+ // We don't ask for a name, too intrusive here
+
+ KisPalette* palette = m_palettes.at(m_optionsWidget-> cmbPalette->currentItem());
+ palette->add(ent);
+
+ if (!palette->save()) {
+ KMessageBox::error(0, i18n("Cannot write to palette file %1. Maybe it is read-only.").tqarg(palette->filename()), i18n("Palette"));
+ }
+ }
+ }
+}
+
+void KisToolColorPicker::displayPickedColor()
+{
+ if (m_pickedColor.data() && m_optionsWidget) {
+
+ TQValueVector<KisChannelInfo *> channels = m_pickedColor.colorSpace()->channels();
+ m_optionsWidget->listViewChannels->clear();
+
+ for (int i = channels.count() - 1; i >= 0 ; --i) {
+ TQString channelValueText;
+
+ if (m_normaliseValues) {
+ channelValueText = i18n("%1%").tqarg(m_pickedColor.colorSpace()->normalisedChannelValueText(m_pickedColor.data(), i));
+ } else {
+ channelValueText = m_pickedColor.colorSpace()->channelValueText(m_pickedColor.data(), i);
+ }
+
+ m_optionsWidget->listViewChannels->insertItem(new TQListViewItem(m_optionsWidget->listViewChannels,
+ channels[i]->name(),
+ channelValueText));
+ }
+ }
+}
+
+void KisToolColorPicker::setup(KActionCollection *collection)
+{
+ m_action = static_cast<KRadioAction *>(collection->action(name()));
+
+ if (m_action == 0) {
+ m_action = new KRadioAction(i18n("&Color Picker"), "tool_colorpicker", TQt::Key_P, this, TQT_SLOT(activate()), collection, name());
+ m_action->setToolTip(i18n("Color picker"));
+ m_action->setExclusiveGroup("tools");
+ m_ownAction = true;
+ }
+}
+
+TQWidget* KisToolColorPicker::createOptionWidget(TQWidget* tqparent)
+{
+ m_optionsWidget = new ColorPickerOptionsWidget(tqparent);
+
+ m_optionsWidget->cbUpdateCurrentColour->setChecked(m_updateColor);
+
+ m_optionsWidget->cmbSources->setCurrentItem(0);
+
+ m_optionsWidget->cbNormaliseValues->setChecked(m_normaliseValues);
+ m_optionsWidget->cbPalette->setChecked(m_addPalette);
+ m_optionsWidget->radius->setValue(m_radius);
+
+ m_optionsWidget->listViewChannels->setSorting(-1);
+
+ connect(m_optionsWidget->cbUpdateCurrentColour, TQT_SIGNAL(toggled(bool)), TQT_SLOT(slotSetUpdateColor(bool)));
+ connect(m_optionsWidget->cbNormaliseValues, TQT_SIGNAL(toggled(bool)), TQT_SLOT(slotSetNormaliseValues(bool)));
+ connect(m_optionsWidget->cbPalette, TQT_SIGNAL(toggled(bool)),
+ TQT_SLOT(slotSetAddPalette(bool)));
+ connect(m_optionsWidget->radius, TQT_SIGNAL(valueChanged(int)),
+ TQT_SLOT(slotChangeRadius(int)));
+
+ KisResourceServerBase* srv = KisResourceServerRegistry::instance()->get("PaletteServer");
+
+ if (!srv) {
+ return m_optionsWidget;
+ }
+
+ TQValueList<KisResource*> palettes = srv->resources();
+
+ for(uint i = 0; i < palettes.count(); i++) {
+ KisPalette* palette = dynamic_cast<KisPalette*>(*palettes.at(i));
+ if (palette) {
+ m_optionsWidget->cmbPalette->insertItem(palette->name());
+ m_palettes.append(palette);
+ }
+ }
+
+ connect(srv, TQT_SIGNAL(resourceAdded(KisResource*)), this, TQT_SLOT(slotAddPalette(KisResource*)));
+
+ return m_optionsWidget;
+}
+
+TQWidget* KisToolColorPicker::optionWidget()
+{
+ return m_optionsWidget;
+}
+
+void KisToolColorPicker::slotSetUpdateColor(bool state)
+{
+ m_updateColor = state;
+}
+
+
+void KisToolColorPicker::slotSetNormaliseValues(bool state)
+{
+ m_normaliseValues = state;
+ displayPickedColor();
+}
+
+void KisToolColorPicker::slotSetAddPalette(bool state) {
+ m_addPalette = state;
+}
+
+void KisToolColorPicker::slotChangeRadius(int value) {
+ m_radius = value;
+}
+
+void KisToolColorPicker::slotAddPalette(KisResource* resource) {
+ KisPalette* palette = dynamic_cast<KisPalette*>(resource);
+ if (palette) {
+ m_optionsWidget-> cmbPalette->insertItem(palette->name());
+ m_palettes.append(palette);
+ }
+}
+
diff --git a/chalk/plugins/tools/defaulttools/kis_tool_colorpicker.h b/chalk/plugins/tools/defaulttools/kis_tool_colorpicker.h
new file mode 100644
index 00000000..ab59ef17
--- /dev/null
+++ b/chalk/plugins/tools/defaulttools/kis_tool_colorpicker.h
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 1999 Matthias Elter
+ * Copyright (c) 2002 Patrick Julien
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef KIS_TOOL_COLOR_PICKER_H_
+#define KIS_TOOL_COLOR_PICKER_H_
+
+#include "kis_tool_non_paint.h"
+#include "kis_tool_factory.h"
+#include "tqvaluevector.h"
+
+class ColorPickerOptionsWidget;
+class KisResource;
+class KisPalette;
+
+class KisToolColorPicker : public KisToolNonPaint {
+
+ Q_OBJECT
+ TQ_OBJECT
+ typedef KisToolNonPaint super;
+
+public:
+ KisToolColorPicker();
+ virtual ~KisToolColorPicker();
+
+public:
+ virtual void update(KisCanvasSubject *subject);
+ virtual void setup(KActionCollection *collection);
+ virtual void buttonPress(KisButtonPressEvent *e);
+ virtual TQWidget* createOptionWidget(TQWidget* tqparent);
+ virtual TQWidget* optionWidget();
+ virtual enumToolType toolType() { return TOOL_FILL; }
+ virtual TQ_UINT32 priority() { return 3; }
+
+public slots:
+ void slotSetUpdateColor(bool);
+ void slotSetNormaliseValues(bool);
+ void slotSetAddPalette(bool);
+ void slotChangeRadius(int);
+ void slotAddPalette(KisResource* resource);
+
+private:
+ void displayPickedColor();
+
+ bool m_updateColor;
+ bool m_addPalette;
+ bool m_normaliseValues;
+ int m_radius;
+ KisColor m_pickedColor;
+
+ ColorPickerOptionsWidget *m_optionsWidget;
+ KisCanvasSubject *m_subject;
+ TQValueVector<KisPalette*> m_palettes;
+};
+
+class KisToolColorPickerFactory : public KisToolFactory {
+ typedef KisToolFactory super;
+public:
+ KisToolColorPickerFactory() : super() {};
+ virtual ~KisToolColorPickerFactory(){};
+
+ virtual KisTool * createTool(KActionCollection * ac) {
+ KisTool * t = new KisToolColorPicker();
+ Q_CHECK_PTR(t);
+ t->setup(ac);
+ return t;
+ }
+ virtual KisID id() { return KisID("colorpicker", i18n("Color Picker")); }
+};
+
+
+#endif // KIS_TOOL_COLOR_PICKER_H_
+
diff --git a/chalk/plugins/tools/defaulttools/kis_tool_duplicate.cc b/chalk/plugins/tools/defaulttools/kis_tool_duplicate.cc
new file mode 100644
index 00000000..9619c6ae
--- /dev/null
+++ b/chalk/plugins/tools/defaulttools/kis_tool_duplicate.cc
@@ -0,0 +1,255 @@
+/*
+ * kis_tool_duplicate.cc - part of Chalk
+ *
+ * Copyright (c) 2004 Cyrille Berger <cberger@cberger.net>
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <tqbitmap.h>
+#include <tqcheckbox.h>
+#include <tqpainter.h>
+#include <tqlabel.h>
+
+#include <kaction.h>
+#include <kdebug.h>
+#include <knuminput.h>
+#include <klocale.h>
+
+#include "kis_brush.h"
+#include "kis_cursor.h"
+#include "kis_image.h"
+#include "kis_tool_duplicate.h"
+#include "kis_painter.h"
+#include "kis_vec.h"
+#include "kis_button_press_event.h"
+#include "kis_button_release_event.h"
+#include "kis_move_event.h"
+#include "kis_paintop.h"
+#include "kis_paintop_registry.h"
+#include "kis_canvas_subject.h"
+#include "kis_perspective_grid.h"
+
+#include "kis_canvas_painter.h"
+#include "kis_boundary_painter.h"
+
+KisToolDuplicate::KisToolDuplicate()
+ : super(i18n("Duplicate Brush")), m_isOffsetNotUptodate(true), m_position(TQPoint(-1,-1))
+{
+ setName("tool_duplicate");
+ m_subject = 0;
+ setCursor(KisCursor::load("tool_duplicate_cursor.png", 5, 5));
+}
+
+KisToolDuplicate::~KisToolDuplicate()
+{
+}
+
+void KisToolDuplicate::activate()
+{
+ m_position = TQPoint(-1,-1);
+ super::activate();
+ if( m_subject->currentImg()->perspectiveGrid()->countSubGrids() != 1 )
+ {
+ m_perspectiveCorrection->setEnabled( false );
+ m_perspectiveCorrection->setChecked( false );
+ } else {
+ m_perspectiveCorrection->setEnabled( true );
+ }
+}
+
+void KisToolDuplicate::buttonPress(KisButtonPressEvent *e)
+{
+ if (e->state() == ShiftButton) {
+ m_position = e->pos();
+ m_isOffsetNotUptodate = true;
+ } else {
+ if (m_position != TQPoint(-1, -1)) {
+ super::buttonPress(e);
+ }
+ }
+}
+
+
+void KisToolDuplicate::setup(KActionCollection *collection)
+{
+ m_action = static_cast<KRadioAction *>(collection->action(name()));
+
+ if (m_action == 0) {
+ m_action = new KRadioAction(i18n("&Duplicate Brush"),
+ "tool_duplicate", TQt::Key_C, this,
+ TQT_SLOT(activate()), collection,
+ name());
+ m_action->setToolTip(i18n("Duplicate parts of the image. Shift-click to select the point to duplicate from to begin."));
+ m_action->setExclusiveGroup("tools");
+ m_ownAction = true;
+ }
+}
+
+void KisToolDuplicate::initPaint(KisEvent *e)
+{
+ if( m_position != TQPoint(-1,-1))
+ {
+ if(m_isOffsetNotUptodate)
+ {
+ m_offset = e->pos() - m_position;
+ m_isOffsetNotUptodate = false;
+ }
+ m_paintIncremental = false;
+ super::initPaint(e);
+ painter()->setDuplicateOffset( m_offset );
+ KisPaintOp * op = KisPaintOpRegistry::instance()->paintOp("duplicate", 0, painter());
+ if (op && m_source) {
+ op->setSource(m_source);
+ painter()->setPaintOp(op);
+ }
+ m_positionStartPainting = e->pos();
+ painter()->setDuplicateStart( e->pos() );
+ }
+}
+
+void KisToolDuplicate::move(KisMoveEvent *e)
+{
+
+ // Paint the outline where we will (or are) copying from
+ if( m_position == TQPoint(-1,-1) )
+ return;
+
+ TQPoint srcPos;
+ if (m_mode == PAINT) {
+ // if we are in perspective correction mode, update the offset when moving
+ if(m_perspectiveCorrection->isChecked())
+ {
+ double startM[3][3];
+ double endM[3][3];
+ for(int i = 0; i < 3; i++)
+ {
+ for(int j = 0; j < 3; j++)
+ {
+ startM[i][j] = 0.;
+ endM[i][j] = 0.;
+ }
+ startM[i][i] = 1.;
+ endM[i][i] = 1.;
+ }
+
+ // First look for the grid corresponding to the start point
+ KisSubPerspectiveGrid* subGridStart = *m_subject->currentImg()->perspectiveGrid()->begin();//device->image()->perspectiveGrid()->gridAt(KisPoint(srcPoint.x() +hotSpot.x(),srcPoint.y() +hotSpot.y()));
+ TQRect r = TQRect(0,0, m_subject->currentImg()->width(), m_subject->currentImg()->height());
+
+ if(subGridStart)
+ {
+ double* b = KisPerspectiveMath::computeMatrixTransfoFromPerspective( r, *subGridStart->topLeft(), *subGridStart->topRight(), *subGridStart->bottomLeft(), *subGridStart->bottomRight());
+ for(int i = 0; i < 3; i++)
+ {
+ for(int j = 0; j < 3; j++)
+ {
+ startM[i][j] = b[3*i+j];
+ }
+ }
+
+ }
+ // Second look for the grid corresponding to the end point
+ KisSubPerspectiveGrid* subGridEnd = *m_subject->currentImg()->perspectiveGrid()->begin();// device->image()->perspectiveGrid()->gridAt(pos);
+ if(subGridEnd)
+ {
+ double* b = KisPerspectiveMath::computeMatrixTransfoToPerspective(*subGridEnd->topLeft(), *subGridEnd->topRight(), *subGridEnd->bottomLeft(), *subGridEnd->bottomRight(), r);
+ for(int i = 0; i < 3; i++)
+ {
+ for(int j = 0; j < 3; j++)
+ {
+ endM[i][j] = b[3*i+j];
+ }
+ }
+ }
+ // Compute the translation in the perspective transformation space:
+ KisPoint translat;
+ {
+ KisPoint positionStartPaintingT = KisPerspectiveMath::matProd(endM, m_positionStartPainting);
+ KisPoint currentPositionT = KisPerspectiveMath::matProd(endM, e->pos() );
+ KisPoint duplicateStartPoisitionT = KisPerspectiveMath::matProd(endM, m_positionStartPainting - m_offset);
+ KisPoint duplicateRealPosition = KisPerspectiveMath::matProd(startM, duplicateStartPoisitionT + (currentPositionT - positionStartPaintingT) );
+ KisPoint p = e->pos() - duplicateRealPosition;
+ srcPos = p.floorTQPoint();
+ }
+
+ }else {
+ srcPos = painter()->duplicateOffset().floorTQPoint();
+ }
+ } else {
+ if(m_isOffsetNotUptodate)
+ srcPos = e->pos().floorTQPoint() - m_position.floorTQPoint();
+ else
+ srcPos = m_offset.floorTQPoint();
+ }
+
+ TQ_INT32 x;
+ TQ_INT32 y;
+
+ // like KisPaintOp::splitCoordinate
+ x = (TQ_INT32)((e->x() < 0) ? e->x() - 1 : e->x());
+ y = (TQ_INT32)((e->y() < 0) ? e->y() - 1 : e->y());
+ srcPos = TQPoint(x - srcPos.x(), y - srcPos.y());
+
+ paintOutline(srcPos);
+ super::move(e);
+}
+
+void KisToolDuplicate::paintAt(const KisPoint &pos,
+ const double pressure,
+ const double xtilt,
+ const double ytilt)
+{
+ if( m_position != TQPoint(-1,-1))
+ {
+ if(m_isOffsetNotUptodate)
+ {
+ m_offset = pos - m_position;
+ m_isOffsetNotUptodate = false;
+ }
+ painter()->setDuplicateHealing( m_healing->isChecked() );
+ painter()->setDuplicateHealingRadius( m_healingRadius->value() );
+ painter()->setDuplicatePerspectiveCorrection( m_perspectiveCorrection->isChecked() );
+ painter()->paintAt( pos, pressure, xtilt, ytilt);
+ }
+}
+
+TQString KisToolDuplicate::quickHelp() const {
+ return i18n("To start, shift-click on the place you want to duplicate from. Then you can start painting. An indication of where you are copying from will be displayed while drawing and moving the mouse.");
+}
+
+TQWidget* KisToolDuplicate::createOptionWidget(TQWidget* tqparent)
+{
+ TQWidget* widget = KisToolPaint::createOptionWidget(tqparent);
+ m_healing = new TQCheckBox(widget);
+ m_healing->setChecked( false);
+ addOptionWidgetOption(m_healing, new TQLabel(i18n("Healing"), widget ));
+ m_healingRadius = new KIntNumInput(widget);
+
+ KisBrush *brush = m_subject->currentBrush();
+ int healingradius = 20;
+ if( brush )
+ {
+ healingradius = 2 * TQMAX(brush->width(),brush->height());
+ }
+
+ m_healingRadius->setValue( healingradius );
+ addOptionWidgetOption(m_healingRadius, new TQLabel(i18n("Healing radius"), widget ));
+ m_perspectiveCorrection = new TQCheckBox(widget);
+ addOptionWidgetOption(m_perspectiveCorrection, new TQLabel(i18n("Correct the perspective"), widget ));
+ return widget;
+}
+
+#include "kis_tool_duplicate.moc"
diff --git a/chalk/plugins/tools/defaulttools/kis_tool_duplicate.h b/chalk/plugins/tools/defaulttools/kis_tool_duplicate.h
new file mode 100644
index 00000000..8a298318
--- /dev/null
+++ b/chalk/plugins/tools/defaulttools/kis_tool_duplicate.h
@@ -0,0 +1,92 @@
+/*
+ * kis_tool_duplicate.h - part of Chalk
+ *
+ * Copyright (c) 2004 Cyrille Berger <cberger@cberger.net>
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __KIS_TOOL_DUPLICATE_H__
+#define __KIS_TOOL_DUPLICATE_H__
+
+#include "kis_tool_freehand.h"
+#include "kis_tool_factory.h"
+
+class KisEvent;
+class KisButtonPressEvent;
+
+class TQCheckBox;
+class KIntNumInput;
+
+class KisToolDuplicate : public KisToolFreehand {
+
+ typedef KisToolFreehand super;
+ Q_OBJECT
+ TQ_OBJECT
+
+public:
+ KisToolDuplicate();
+ virtual ~KisToolDuplicate();
+
+ virtual void setup(KActionCollection *collection);
+ virtual enumToolType toolType() { return TOOL_FREEHAND; }
+ virtual TQ_UINT32 priority() { return 0; }
+ virtual void buttonPress(KisButtonPressEvent *e);
+ virtual void move(KisMoveEvent *e);
+
+ virtual void paintAt(const KisPoint &pos,
+ const double pressure,
+ const double xTilt,
+ const double yTilt);
+
+ virtual TQString quickHelp() const;
+ virtual TQWidget* createOptionWidget(TQWidget* tqparent);
+
+protected slots:
+ virtual void activate();
+
+protected:
+ virtual void initPaint(KisEvent *e);
+
+ // Tool starting duplicate
+ KisPoint m_offset; // This member give the offset from the click position to the point where we take the duplication
+ bool m_isOffsetNotUptodate; // Tells if the offset is update
+ KisPoint m_position; // Give the position of the last alt-click
+ KisPoint m_positionStartPainting;
+ TQCheckBox* m_healing;
+ KIntNumInput* m_healingRadius;
+ TQCheckBox* m_perspectiveCorrection;
+};
+
+
+class KisToolDuplicateFactory : public KisToolFactory {
+ typedef KisToolFactory super;
+public:
+ KisToolDuplicateFactory() : super() {};
+ virtual ~KisToolDuplicateFactory(){};
+
+ virtual KisTool * createTool(KActionCollection * ac) {
+ KisTool * t = new KisToolDuplicate();
+ Q_CHECK_PTR(t);
+ t->setup(ac);
+ return t;
+ }
+ virtual KisID id() { return KisID("duplicate", i18n("Duplicate Tool")); }
+};
+
+
+
+#endif //__KIS_TOOL_DUPLICATE_H__
+
diff --git a/chalk/plugins/tools/defaulttools/kis_tool_ellipse.cc b/chalk/plugins/tools/defaulttools/kis_tool_ellipse.cc
new file mode 100644
index 00000000..65593c23
--- /dev/null
+++ b/chalk/plugins/tools/defaulttools/kis_tool_ellipse.cc
@@ -0,0 +1,186 @@
+/*
+ * kis_tool_ellipse.cc - part of Krayon
+ *
+ * Copyright (c) 2000 John Califf <jcaliff@compuzone.net>
+ * Copyright (c) 2002 Patrick Julien <freak@codepimps.org>
+ * Copyright (c) 2004 Boudewijn Rempt <boud@valdyas.org>
+ * Copyright (c) 2004 Clarence Dang <dang@kde.org>
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <tqpainter.h>
+
+#include <kaction.h>
+#include <kdebug.h>
+#include <klocale.h>
+
+#include "kis_painter.h"
+#include "kis_canvas_subject.h"
+#include "kis_canvas_controller.h"
+#include "kis_tool_ellipse.h"
+#include "kis_button_press_event.h"
+#include "kis_button_release_event.h"
+#include "kis_move_event.h"
+#include "kis_paintop_registry.h"
+#include "kis_undo_adapter.h"
+#include "kis_canvas.h"
+#include "kis_canvas_painter.h"
+#include "kis_cursor.h"
+
+KisToolEllipse::KisToolEllipse()
+ : super(i18n ("Ellipse")),
+ m_dragging (false),
+ m_currentImage (0)
+{
+ setName("tool_ellipse");
+ setCursor(KisCursor::load("tool_ellipse_cursor.png", 6, 6));
+}
+
+KisToolEllipse::~KisToolEllipse()
+{
+}
+
+void KisToolEllipse::update (KisCanvasSubject *subject)
+{
+ super::update (subject);
+ if (m_subject)
+ m_currentImage = m_subject->currentImg ();
+}
+
+void KisToolEllipse::buttonPress(KisButtonPressEvent *event)
+{
+ if (m_currentImage && event->button() == Qt::LeftButton) {
+ m_dragging = true;
+ m_dragStart = m_dragCenter = m_dragEnd = event->pos();
+ draw(m_dragStart, m_dragEnd);
+ }
+}
+
+void KisToolEllipse::move(KisMoveEvent *event)
+{
+ if (m_dragging) {
+ // erase old lines on canvas
+ draw(m_dragStart, m_dragEnd);
+ // move (alt) or resize ellipse
+ if (event->state() & TQt::AltButton) {
+ KisPoint trans = event->pos() - m_dragEnd;
+ m_dragStart += trans;
+ m_dragEnd += trans;
+ } else {
+ KisPoint diag = event->pos() - (event->state() & TQt::ControlButton
+ ? m_dragCenter : m_dragStart);
+ // circle?
+ if (event->state() & TQt::ShiftButton) {
+ double size = TQMAX(fabs(diag.x()), fabs(diag.y()));
+ double w = diag.x() < 0 ? -size : size;
+ double h = diag.y() < 0 ? -size : size;
+ diag = KisPoint(w, h);
+ }
+
+ // resize around center point?
+ if (event->state() & TQt::ControlButton) {
+ m_dragStart = m_dragCenter - diag;
+ m_dragEnd = m_dragCenter + diag;
+ } else {
+ m_dragEnd = m_dragStart + diag;
+ }
+ }
+ // draw new lines on canvas
+ draw(m_dragStart, m_dragEnd);
+ m_dragCenter = KisPoint((m_dragStart.x() + m_dragEnd.x()) / 2,
+ (m_dragStart.y() + m_dragEnd.y()) / 2);
+ }
+}
+
+void KisToolEllipse::buttonRelease(KisButtonReleaseEvent *event)
+{
+ if (!m_subject || !m_currentImage)
+ return;
+
+ if (m_dragging && event->button() == Qt::LeftButton) {
+ // erase old lines on canvas
+ draw(m_dragStart, m_dragEnd);
+ m_dragging = false;
+
+ if (m_dragStart == m_dragEnd)
+ return;
+
+ if (!m_currentImage)
+ return;
+
+ if (!m_currentImage->activeDevice())
+ return;
+
+ KisPaintDeviceSP device = m_currentImage->activeDevice ();
+ KisPainter painter (device);
+ if (m_currentImage->undo()) painter.beginTransaction (i18n ("Ellipse"));
+
+ painter.setPaintColor(m_subject->fgColor());
+ painter.setBackgroundColor(m_subject->bgColor());
+ painter.setFillStyle(fillStyle());
+ painter.setBrush(m_subject->currentBrush());
+ painter.setPattern(m_subject->currentPattern());
+ painter.setOpacity(m_opacity);
+ painter.setCompositeOp(m_compositeOp);
+ KisPaintOp * op = KisPaintOpRegistry::instance()->paintOp(m_subject->currentPaintop(), m_subject->currentPaintopSettings(), &painter);
+ painter.setPaintOp(op); // Painter takes ownership
+
+ painter.paintEllipse(m_dragStart, m_dragEnd, PRESSURE_DEFAULT/*event->pressure()*/, event->xTilt(), event->yTilt());
+ device->setDirty( painter.dirtyRect() );
+ notifyModified();
+
+ KisUndoAdapter *adapter = m_currentImage->undoAdapter();
+ if (adapter) {
+ adapter->addCommand(painter.endTransaction());
+ }
+ }
+}
+
+void KisToolEllipse::draw(const KisPoint& start, const KisPoint& end )
+{
+ if (!m_subject || !m_currentImage)
+ return;
+
+ KisCanvasController *controller = m_subject->canvasController ();
+ KisCanvas *canvas = controller->kiscanvas();
+ KisCanvasPainter p (canvas);
+
+ p.setRasterOp (TQt::NotROP);
+ p.drawEllipse (TQRect (controller->windowToView (start).floorTQPoint(), controller->windowToView (end).floorTQPoint()));
+ p.end ();
+}
+
+void KisToolEllipse::setup(KActionCollection *collection)
+{
+ m_action = static_cast<KRadioAction *>(collection->action(name()));
+
+ if (m_action == 0) {
+ KShortcut shortcut(TQt::Key_Plus);
+ shortcut.append(KShortcut(TQt::Key_F7));
+ m_action = new KRadioAction(i18n("&Ellipse"),
+ "tool_ellipse",
+ shortcut,
+ this,
+ TQT_SLOT(activate()),
+ collection,
+ name());
+ m_action->setToolTip(i18n("Draw an ellipse"));
+ m_action->setExclusiveGroup("tools");
+ m_ownAction = true;
+ }
+}
+
+#include "kis_tool_ellipse.moc"
diff --git a/chalk/plugins/tools/defaulttools/kis_tool_ellipse.h b/chalk/plugins/tools/defaulttools/kis_tool_ellipse.h
new file mode 100644
index 00000000..4f79fbd6
--- /dev/null
+++ b/chalk/plugins/tools/defaulttools/kis_tool_ellipse.h
@@ -0,0 +1,91 @@
+/*
+ * kis_tool_ellipse.h - part of Krayon
+ *
+ * Copyright (c) 2000 John Califf <jcaliff@compuzone.net>
+ * Copyright (c) 2002 Patrick Julien <freak@codepimps.org>
+ * Copyright (c) 2004 Clarence Dang <dang@kde.org>
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __KIS_TOOL_ELLIPSE_H__
+#define __KIS_TOOL_ELLIPSE_H__
+
+#include "kis_tool_shape.h"
+
+class KisCanvas;
+class KisPainter;
+class KisRect;
+
+class KisToolEllipse : public KisToolShape {
+
+ typedef KisToolShape super;
+ Q_OBJECT
+ TQ_OBJECT
+
+public:
+ KisToolEllipse();
+ virtual ~KisToolEllipse();
+
+ //
+ // KisCanvasObserver interface
+ //
+
+ virtual void update (KisCanvasSubject *subject);
+
+ //
+ // KisToolPaint interface
+ //
+
+ virtual void setup(KActionCollection *collection);
+ virtual TQ_UINT32 priority() { return 3; }
+ virtual enumToolType toolType() { return TOOL_SHAPE; }
+ virtual void buttonPress(KisButtonPressEvent *event);
+ virtual void move(KisMoveEvent *event);
+ virtual void buttonRelease(KisButtonReleaseEvent *event);
+
+protected:
+ virtual void draw(const KisPoint& start, const KisPoint& stop);
+
+protected:
+ KisPoint m_dragCenter;
+ KisPoint m_dragStart;
+ KisPoint m_dragEnd;
+
+ bool m_dragging;
+ KisImageSP m_currentImage;
+};
+
+
+#include "kis_tool_factory.h"
+
+class KisToolEllipseFactory : public KisToolFactory {
+ typedef KisToolFactory super;
+public:
+ KisToolEllipseFactory() : super() {};
+ virtual ~KisToolEllipseFactory(){};
+
+ virtual KisTool * createTool(KActionCollection * ac) {
+ KisTool * t = new KisToolEllipse();
+ Q_CHECK_PTR(t);
+ t->setup(ac);
+ return t;
+ }
+ virtual KisID id() { return KisID("ellipse", i18n("Ellipse Tool")); }
+};
+
+
+#endif //__KIS_TOOL_ELLIPSE_H__
+
diff --git a/chalk/plugins/tools/defaulttools/kis_tool_fill.cc b/chalk/plugins/tools/defaulttools/kis_tool_fill.cc
new file mode 100644
index 00000000..1e2b82c5
--- /dev/null
+++ b/chalk/plugins/tools/defaulttools/kis_tool_fill.cc
@@ -0,0 +1,233 @@
+/*
+ * kis_tool_fill.cc - part of Krayon
+ *
+ * Copyright (c) 2000 John Califf <jcaliff@compuzone.net>
+ * Copyright (c) 2004 Boudewijn Rempt <boud@valdyas.org>
+ * Copyright (c) 2004 Bart Coppens <kde@bartcoppens.be>
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <kaction.h>
+#include <kdebug.h>
+#include <klocale.h>
+#include <kcommand.h>
+#include <tqlabel.h>
+#include <tqlayout.h>
+#include <tqcheckbox.h>
+
+#include <tqcolor.h>
+
+#include "knuminput.h"
+
+#include "kis_layer.h"
+#include "kis_cursor.h"
+#include "kis_painter.h"
+#include "kis_tool_brush.h"
+#include "kis_cmb_composite.h"
+#include "kis_tool_fill.h"
+#include "kis_colorspace.h"
+#include "kis_button_press_event.h"
+#include "kis_button_release_event.h"
+#include "kis_move_event.h"
+#include "kis_pattern.h"
+#include "kis_fill_painter.h"
+#include "kis_progress_display_interface.h"
+#include "kis_undo_adapter.h"
+#include "kis_canvas_subject.h"
+#include "kis_selection.h"
+
+KisToolFill::KisToolFill()
+ : super(i18n("Fill")), m_wasPressed(false)
+{
+ setName("tool_fill");
+ m_subject = 0;
+ m_oldColor = 0;
+ m_threshold = 15;
+ m_usePattern = false;
+ m_unmerged = false;
+ m_fillOnlySelection = false;
+
+ setCursor(KisCursor::load("tool_fill_cursor.png", 6, 6));
+}
+
+void KisToolFill::update(KisCanvasSubject *subject)
+{
+ m_subject = subject;
+ m_currentImage = subject->currentImg();
+
+ super::update(m_subject);
+}
+
+KisToolFill::~KisToolFill()
+{
+}
+
+bool KisToolFill::flood(int startX, int startY)
+{
+ KisPaintDeviceSP device = m_currentImage->activeDevice();
+ if (!device) return false;
+
+ if (m_fillOnlySelection) {
+ TQRect rc = device->selection()->selectedRect();
+ KisPaintDeviceSP filled = new KisPaintDevice(device->colorSpace(), "filled");
+ KisFillPainter painter(filled);
+ if (m_usePattern)
+ painter.fillRect(rc.x(), rc.y(), rc.width(), rc.height(),
+ m_subject->currentPattern());
+ else
+ painter.fillRect(rc.x(), rc.y(), rc.width(), rc.height(),
+ m_subject->fgColor(), m_opacity);
+ painter.end();
+ KisPainter painter2(device);
+ if (m_currentImage->undo()) painter2.beginTransaction(i18n("Fill"));
+ painter2.bltSelection(rc.x(), rc.y() , m_compositeOp, filled, m_opacity,
+ rc.x(), rc.y(), rc.width(), rc.height());
+
+ device->setDirty(filled->extent());
+ notifyModified();
+
+ if (m_currentImage->undo()) {
+ m_currentImage->undoAdapter()->addCommand(painter2.endTransaction());
+ }
+ return true;
+ }
+
+ KisFillPainter painter(device);
+ if (m_currentImage->undo()) painter.beginTransaction(i18n("Flood Fill"));
+ painter.setPaintColor(m_subject->fgColor());
+ painter.setOpacity(m_opacity);
+ painter.setFillThreshold(m_threshold);
+ painter.setCompositeOp(m_compositeOp);
+ painter.setPattern(m_subject->currentPattern());
+ painter.setSampleMerged(!m_unmerged);
+ painter.setCareForSelection(true);
+
+ KisProgressDisplayInterface *progress = m_subject->progressDisplay();
+ if (progress) {
+ progress->setSubject(&painter, true, true);
+ }
+
+ if (m_usePattern)
+ painter.fillPattern(startX, startY);
+ else
+ painter.fillColor(startX, startY);
+
+ device->setDirty(painter.dirtyRect());
+ notifyModified();
+
+ if (m_currentImage->undo()) {
+ m_currentImage->undoAdapter()->addCommand(painter.endTransaction());
+ }
+
+ return true;
+}
+
+void KisToolFill::buttonPress(KisButtonPressEvent *e)
+{
+ m_startPos = e->pos();
+ m_wasPressed = true;
+}
+
+void KisToolFill::buttonRelease(KisButtonReleaseEvent *e)
+{
+ if (!m_subject) return;
+ if (!m_currentImage || !m_currentImage->activeDevice()) return;
+ if (e->button() != Qt::LeftButton) return;
+ if(!m_wasPressed) return;
+ m_wasPressed = false;
+ int x, y;
+ x = m_startPos.floorX();
+ y = m_startPos.floorY();
+ if (!m_currentImage->bounds().tqcontains(x, y)) {
+ return;
+ }
+ flood(x, y);
+ notifyModified();
+}
+
+TQWidget* KisToolFill::createOptionWidget(TQWidget* tqparent)
+{
+ TQWidget *widget = super::createOptionWidget(tqparent);
+
+ m_lbThreshold = new TQLabel(i18n("Threshold: "), widget);
+ m_slThreshold = new KIntNumInput( widget, "int_widget");
+ m_slThreshold->setRange( 1, 100);
+ m_slThreshold->setSteps( 3, 3);
+ m_slThreshold->setValue(m_threshold);
+ connect(m_slThreshold, TQT_SIGNAL(valueChanged(int)), this, TQT_SLOT(slotSetThreshold(int)));
+
+ m_checkUsePattern = new TQCheckBox(i18n("Use pattern"), widget);
+ m_checkUsePattern->setChecked(m_usePattern);
+ connect(m_checkUsePattern, TQT_SIGNAL(toggled(bool)), this, TQT_SLOT(slotSetUsePattern(bool)));
+
+ m_checkSampleMerged = new TQCheckBox(i18n("Limit to current layer"), widget);
+ m_checkSampleMerged->setChecked(m_unmerged);
+ connect(m_checkSampleMerged, TQT_SIGNAL(toggled(bool)), this, TQT_SLOT(slotSetSampleMerged(bool)));
+
+ m_checkFillSelection = new TQCheckBox(i18n("Fill entire selection"), widget);
+ m_checkFillSelection->setChecked(m_fillOnlySelection);
+ connect(m_checkFillSelection, TQT_SIGNAL(toggled(bool)), this, TQT_SLOT(slotSetFillSelection(bool)));
+
+ addOptionWidgetOption(m_slThreshold, m_lbThreshold);
+
+ addOptionWidgetOption(m_checkFillSelection);
+ addOptionWidgetOption(m_checkSampleMerged);
+ addOptionWidgetOption(m_checkUsePattern);
+
+ return widget;
+}
+
+void KisToolFill::slotSetThreshold(int threshold)
+{
+ m_threshold = threshold;
+}
+
+void KisToolFill::slotSetUsePattern(bool state)
+{
+ m_usePattern = state;
+}
+
+void KisToolFill::slotSetSampleMerged(bool state)
+{
+ m_unmerged = state;
+}
+
+void KisToolFill::slotSetFillSelection(bool state)
+{
+ m_fillOnlySelection = state;
+ m_slThreshold->setEnabled(!state);
+ m_checkSampleMerged->setEnabled(!state);
+}
+
+void KisToolFill::setup(KActionCollection *collection)
+{
+ m_action = static_cast<KRadioAction *>(collection->action(name()));
+
+ if (m_action == 0) {
+ m_action = new KRadioAction(i18n("&Fill"),
+ "tool_color_fill",
+ TQt::Key_F,
+ this,
+ TQT_SLOT(activate()),
+ collection,
+ name());
+ m_action->setToolTip(i18n("Contiguous fill"));
+ m_action->setExclusiveGroup("tools");
+ m_ownAction = true;
+ }
+}
+
+#include "kis_tool_fill.moc"
diff --git a/chalk/plugins/tools/defaulttools/kis_tool_fill.h b/chalk/plugins/tools/defaulttools/kis_tool_fill.h
new file mode 100644
index 00000000..61087243
--- /dev/null
+++ b/chalk/plugins/tools/defaulttools/kis_tool_fill.h
@@ -0,0 +1,109 @@
+/*
+ * kis_tool_fill.h - part of Krayon^Chalk
+ *
+ * Copyright (c) 2004 Bart Coppens <kde@bartcoppens.be>
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __filltool_h__
+#define __filltool_h__
+
+#include <tqpoint.h>
+
+#include "kis_point.h"
+#include "kis_tool_paint.h"
+
+class KisPainter;
+class TQWidget;
+class TQLabel;
+class TQCheckBox;
+class KIntNumInput;
+class KActionCollection;
+
+class KisToolFill : public KisToolPaint {
+
+ typedef KisToolPaint super;
+ Q_OBJECT
+ TQ_OBJECT
+
+public:
+
+ KisToolFill();
+ virtual ~KisToolFill();
+
+ virtual void setup(KActionCollection *collection);
+ virtual enumToolType toolType() { return TOOL_FILL; }
+ virtual TQ_UINT32 priority() { return 0; }
+
+ virtual void update(KisCanvasSubject *subject);
+
+ virtual void buttonPress(KisButtonPressEvent*);
+ virtual void buttonRelease(KisButtonReleaseEvent*);
+
+ bool flood(int startX, int startY);
+
+ virtual TQWidget* createOptionWidget(TQWidget* tqparent);
+
+public slots:
+ virtual void slotSetThreshold(int);
+ virtual void slotSetUsePattern(bool);
+ virtual void slotSetSampleMerged(bool);
+ virtual void slotSetFillSelection(bool);
+
+private:
+ KisPoint m_startPos;
+ int m_threshold;
+ TQ_INT32 m_depth;
+ KisLayerSP m_lay;
+ TQ_UINT8* m_oldColor, *m_color;
+ KisPainter *m_painter;
+ KisCanvasSubject *m_subject;
+ KisImageSP m_currentImage;
+ bool *m_map, m_unmerged, m_usePattern, m_fillOnlySelection;
+ KisSelectionSP m_selection;
+
+ TQLabel *m_lbThreshold;
+ KIntNumInput *m_slThreshold;
+ TQCheckBox *m_checkUsePattern;
+ TQCheckBox *m_checkSampleMerged;
+ TQCheckBox *m_checkFillSelection;
+ bool m_wasPressed; // use for preventing bug:133148
+};
+
+
+#include "kis_tool_factory.h"
+
+class KisToolFillFactory : public KisToolFactory {
+ typedef KisToolFactory super;
+public:
+ KisToolFillFactory() : super() {};
+ virtual ~KisToolFillFactory(){};
+
+ virtual KisTool * createTool(KActionCollection * ac) {
+ KisToolFill * t = new KisToolFill();
+ Q_CHECK_PTR(t);
+ t->setup(ac);
+ return t;
+ }
+ virtual KisID id() { return KisID("fill", i18n("Fill Tool")); }
+
+};
+
+
+
+
+#endif //__filltool_h__
+
diff --git a/chalk/plugins/tools/defaulttools/kis_tool_gradient.cc b/chalk/plugins/tools/defaulttools/kis_tool_gradient.cc
new file mode 100644
index 00000000..4eb685a5
--- /dev/null
+++ b/chalk/plugins/tools/defaulttools/kis_tool_gradient.cc
@@ -0,0 +1,309 @@
+/*
+ * kis_tool_gradient.cc - part of Chalk
+ *
+ * Copyright (c) 2000 John Califf
+ * Copyright (c) 2002 Patrick Julien <freak@codepimps.org>
+ * Copyright (c) 2003 Boudewijn Rempt <boud@valdyas.org>
+ * Copyright (c) 2004 Adrian Page <adrian@pagenet.plus.com>
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <tqpainter.h>
+#include <tqlabel.h>
+#include <tqlayout.h>
+#include <tqcheckbox.h>
+
+#include <kdebug.h>
+#include <kaction.h>
+#include <kcommand.h>
+#include <klocale.h>
+#include <knuminput.h>
+
+#include "kis_button_press_event.h"
+#include "kis_button_release_event.h"
+#include "kis_canvas_subject.h"
+#include "kis_cmb_composite.h"
+#include "kis_cursor.h"
+#include "kis_double_widget.h"
+#include "kis_gradient_painter.h"
+#include "kis_move_event.h"
+#include "kis_painter.h"
+#include "kis_progress_display_interface.h"
+#include "kis_tool_gradient.h"
+#include "kis_undo_adapter.h"
+#include "kis_canvas.h"
+#include "kis_canvas_painter.h"
+
+KisToolGradient::KisToolGradient()
+ : super(i18n("Gradient")),
+ m_dragging( false )
+{
+ setName("tool_gradient");
+ setCursor(KisCursor::load("tool_gradient_cursor.png", 6, 6));
+
+ m_startPos = KisPoint(0, 0);
+ m_endPos = KisPoint(0, 0);
+
+ m_reverse = false;
+ m_tqshape = KisGradientPainter::GradientShapeLinear;
+ m_repeat = KisGradientPainter::GradientRepeatNone;
+ m_antiAliasThreshold = 0.2;
+}
+
+KisToolGradient::~KisToolGradient()
+{
+}
+
+void KisToolGradient::update(KisCanvasSubject *subject)
+{
+ m_subject = subject;
+ super::update(m_subject);
+}
+
+void KisToolGradient::paint(KisCanvasPainter& gc)
+{
+ if (m_dragging)
+ paintLine(gc);
+}
+
+void KisToolGradient::paint(KisCanvasPainter& gc, const TQRect&)
+{
+ if (m_dragging)
+ paintLine(gc);
+}
+
+void KisToolGradient::buttonPress(KisButtonPressEvent *e)
+{
+ if (!m_subject || !m_subject->currentImg()) {
+ return;
+ }
+
+ if (e->button() == Qt::LeftButton) {
+ m_dragging = true;
+ m_startPos = e->pos();
+ m_endPos = e->pos();
+ }
+}
+
+void KisToolGradient::move(KisMoveEvent *e)
+{
+ if (m_dragging) {
+ if (m_startPos != m_endPos) {
+ paintLine();
+ }
+
+ if ((e->state() & TQt::ShiftButton) == TQt::ShiftButton) {
+ m_endPos = straightLine(e->pos());
+ }
+ else {
+ m_endPos = e->pos();
+ }
+
+ paintLine();
+ }
+}
+
+void KisToolGradient::buttonRelease(KisButtonReleaseEvent *e)
+{
+ if (m_dragging && e->button() == Qt::LeftButton) {
+
+ KisCanvasController *controller = m_subject->canvasController();
+ KisImageSP img = m_subject->currentImg();
+
+ m_dragging = false;
+
+ if (m_startPos == m_endPos) {
+ controller->updateCanvas();
+ m_dragging = false;
+ return;
+ }
+
+ if ((e->state() & TQt::ShiftButton) == TQt::ShiftButton) {
+ m_endPos = straightLine(e->pos());
+ }
+ else {
+ m_endPos = e->pos();
+ }
+
+ KisPaintDeviceSP device;
+
+ if (img && (device = img->activeDevice())) {
+
+ KisGradientPainter painter(device);
+
+ if (img->undo()) painter.beginTransaction(i18n("Gradient"));
+
+ painter.setPaintColor(m_subject->fgColor());
+ painter.setGradient(*(m_subject->currentGradient()));
+ painter.setOpacity(m_opacity);
+ painter.setCompositeOp(m_compositeOp);
+
+ KisProgressDisplayInterface *progress = m_subject->progressDisplay();
+
+ if (progress) {
+ progress->setSubject(&painter, true, true);
+ }
+
+ bool painted = painter.paintGradient(m_startPos, m_endPos, m_tqshape, m_repeat, m_antiAliasThreshold, m_reverse, 0, 0, m_subject->currentImg()->width(), m_subject->currentImg()->height());
+
+ if (painted) {
+ // does whole thing at moment
+ device->setDirty(painter.dirtyRect());
+
+ notifyModified();
+
+ if (img->undo()) {
+ img->undoAdapter()->addCommand(painter.endTransaction());
+ }
+ }
+
+ /* remove remains of the line drawn while moving */
+ if (controller->kiscanvas()) {
+ controller->kiscanvas()->update();
+ }
+
+ }
+ }
+}
+
+KisPoint KisToolGradient::straightLine(KisPoint point)
+{
+ KisPoint comparison = point - m_startPos;
+ KisPoint result;
+
+ if ( fabs(comparison.x()) > fabs(comparison.y())) {
+ result.setX(point.x());
+ result.setY(m_startPos.y());
+ } else {
+ result.setX( m_startPos.x() );
+ result.setY( point.y() );
+ }
+
+ return result;
+}
+
+void KisToolGradient::paintLine()
+{
+ if (m_subject) {
+ KisCanvasController *controller = m_subject->canvasController();
+ KisCanvas *canvas = controller->kiscanvas();
+ KisCanvasPainter gc(canvas);
+
+ paintLine(gc);
+ }
+}
+
+void KisToolGradient::paintLine(KisCanvasPainter& gc)
+{
+ if (m_subject) {
+ KisCanvasController *controller = m_subject->canvasController();
+
+ KisPoint start = controller->windowToView(m_startPos);
+ KisPoint end = controller->windowToView(m_endPos);
+
+ RasterOp op = gc.rasterOp();
+ TQPen old = gc.pen();
+ TQPen pen(TQt::SolidLine);
+
+ gc.setRasterOp(TQt::NotROP);
+ gc.setPen(pen);
+ gc.drawLine(start.floorTQPoint(), end.floorTQPoint());
+ gc.setRasterOp(op);
+ gc.setPen(old);
+ }
+}
+
+TQWidget* KisToolGradient::createOptionWidget(TQWidget* tqparent)
+{
+ TQWidget *widget = super::createOptionWidget(tqparent);
+ Q_CHECK_PTR(widget);
+
+ m_lbShape = new TQLabel(i18n("Shape:"), widget);
+ m_lbRepeat = new TQLabel(i18n("Repeat:"), widget);
+
+ m_ckReverse = new TQCheckBox(i18n("Reverse"), widget, "reverse_check");
+ connect(m_ckReverse, TQT_SIGNAL(toggled(bool)), this, TQT_SLOT(slotSetReverse(bool)));
+
+ m_cmbShape = new TQComboBox(false, widget, "tqshape_combo");
+ connect(m_cmbShape, TQT_SIGNAL(activated(int)), this, TQT_SLOT(slotSetShape(int)));
+ m_cmbShape->insertItem(i18n("Linear"));
+ m_cmbShape->insertItem(i18n("Bi-Linear"));
+ m_cmbShape->insertItem(i18n("Radial"));
+ m_cmbShape->insertItem(i18n("Square"));
+ m_cmbShape->insertItem(i18n("Conical"));
+ m_cmbShape->insertItem(i18n("Conical Symmetric"));
+
+ m_cmbRepeat = new TQComboBox(false, widget, "repeat_combo");
+ connect(m_cmbRepeat, TQT_SIGNAL(activated(int)), this, TQT_SLOT(slotSetRepeat(int)));
+ m_cmbRepeat->insertItem(i18n("None"));
+ m_cmbRepeat->insertItem(i18n("Forwards"));
+ m_cmbRepeat->insertItem(i18n("Alternating"));
+
+ addOptionWidgetOption(m_cmbShape, m_lbShape);
+
+ addOptionWidgetOption(m_cmbRepeat, m_lbRepeat);
+
+ addOptionWidgetOption(m_ckReverse);
+
+ m_lbAntiAliasThreshold = new TQLabel(i18n("Anti-alias threshold:"), widget);
+
+ m_slAntiAliasThreshold = new KDoubleNumInput(widget, "threshold_slider");
+ m_slAntiAliasThreshold->setRange( 0, 1);
+ m_slAntiAliasThreshold->setValue(m_antiAliasThreshold);
+ connect(m_slAntiAliasThreshold, TQT_SIGNAL(valueChanged(double)), this, TQT_SLOT(slotSetAntiAliasThreshold(double)));
+
+ addOptionWidgetOption(m_slAntiAliasThreshold, m_lbAntiAliasThreshold);
+
+ return widget;
+}
+
+void KisToolGradient::slotSetShape(int tqshape)
+{
+ m_tqshape = static_cast<KisGradientPainter::enumGradientShape>(tqshape);
+}
+
+void KisToolGradient::slotSetRepeat(int repeat)
+{
+ m_repeat = static_cast<KisGradientPainter::enumGradientRepeat>(repeat);
+}
+
+void KisToolGradient::slotSetReverse(bool state)
+{
+ m_reverse = state;
+}
+
+void KisToolGradient::slotSetAntiAliasThreshold(double value)
+{
+ m_antiAliasThreshold = value;
+}
+
+void KisToolGradient::setup(KActionCollection *collection)
+{
+ m_action = static_cast<KRadioAction *>(collection->action(name()));
+
+ if (m_action == 0) {
+ m_action = new KRadioAction(i18n("&Gradient"),
+ "tool_gradient", TQt::Key_G, this,
+ TQT_SLOT(activate()), collection,
+ name());
+ m_action->setToolTip(i18n("Draw a gradient"));
+ m_action->setExclusiveGroup("tools");
+ m_ownAction = true;
+ }
+}
+
+#include "kis_tool_gradient.moc"
+
diff --git a/chalk/plugins/tools/defaulttools/kis_tool_gradient.h b/chalk/plugins/tools/defaulttools/kis_tool_gradient.h
new file mode 100644
index 00000000..59d78ad3
--- /dev/null
+++ b/chalk/plugins/tools/defaulttools/kis_tool_gradient.h
@@ -0,0 +1,124 @@
+/*
+ * kis_tool_line.h - part of Krayon
+ *
+ * Copyright (c) 2000 John Califf <jcaliff@comuzone.net>
+ * Copyright (c) 2002 Patrick Julien <freak@codepimps.org>
+ * Copyright (c) 2004 Boudewijn Rempt <boud@valdyas.org>
+ * Copyright (c) 2004 Adrian Page <adrian@pagenet.plus.com>
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef KIS_TOOL_GRADIENT_H_
+#define KIS_TOOL_GRADIENT_H_
+
+#include "kis_tool_paint.h"
+
+#include "kis_global.h"
+#include "kis_types.h"
+#include "kis_gradient_painter.h"
+#include "kis_tool_factory.h"
+
+class KIntNumInput;
+class KDoubleNumInput;
+
+class KisCmbComposite;
+class KisPainter;
+
+class TQLabel;
+class TQPoint;
+class TQWidget;
+class TQCheckBox;
+
+
+
+class KisToolGradient : public KisToolPaint {
+
+ Q_OBJECT
+ TQ_OBJECT
+ typedef KisToolPaint super;
+
+public:
+ KisToolGradient();
+ virtual ~KisToolGradient();
+
+ virtual void setup(KActionCollection *collection);
+ virtual enumToolType toolType() { return TOOL_FILL; }
+ virtual TQ_UINT32 priority() { return 1; }
+
+ virtual void update(KisCanvasSubject *subject);
+
+ virtual void buttonPress(KisButtonPressEvent *event);
+ virtual void move(KisMoveEvent *event);
+ virtual void buttonRelease(KisButtonReleaseEvent *event);
+
+ virtual void paint(KisCanvasPainter& gc);
+ virtual void paint(KisCanvasPainter& gc, const TQRect& rc);
+
+ TQWidget* createOptionWidget(TQWidget* tqparent);
+
+public slots:
+ void slotSetShape(int);
+ void slotSetRepeat(int);
+ void slotSetReverse(bool);
+ void slotSetAntiAliasThreshold(double);
+
+private:
+ void paintLine();
+ void paintLine(KisCanvasPainter& gc);
+
+ KisPoint straightLine(KisPoint point);
+
+ bool m_dragging;
+
+ KisPoint m_startPos;
+ KisPoint m_endPos;
+
+ KisCanvasSubject *m_subject;
+
+ KisGradientPainter::enumGradientShape m_tqshape;
+ KisGradientPainter::enumGradientRepeat m_repeat;
+
+ bool m_reverse;
+ double m_antiAliasThreshold;
+
+ TQLabel *m_lbShape;
+ TQLabel *m_lbRepeat;
+ TQCheckBox *m_ckReverse;
+ TQComboBox *m_cmbShape;
+ TQComboBox *m_cmbRepeat;
+ TQLabel *m_lbAntiAliasThreshold;
+ KDoubleNumInput *m_slAntiAliasThreshold;
+};
+
+class KisToolGradientFactory : public KisToolFactory {
+ typedef KisToolFactory super;
+public:
+ KisToolGradientFactory() : super() {};
+ virtual ~KisToolGradientFactory(){};
+
+ virtual KisTool * createTool(KActionCollection * ac) {
+ KisTool * t = new KisToolGradient();
+ Q_CHECK_PTR(t);
+ t->setup(ac);
+ return t;
+ }
+ virtual KisID id() { return KisID("gradient", i18n("Gradient Tool")); }
+};
+
+
+
+#endif //KIS_TOOL_GRADIENT_H_
+
diff --git a/chalk/plugins/tools/defaulttools/kis_tool_line.cc b/chalk/plugins/tools/defaulttools/kis_tool_line.cc
new file mode 100644
index 00000000..243052cf
--- /dev/null
+++ b/chalk/plugins/tools/defaulttools/kis_tool_line.cc
@@ -0,0 +1,254 @@
+/*
+ * kis_tool_line.cc - part of Krayon
+ *
+ * Copyright (c) 2000 John Califf
+ * Copyright (c) 2002 Patrick Julien <freak@codepimps.org>
+ * Copyright (c) 2003 Boudewijn Rempt <boud@valdyas.org>
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <tqpainter.h>
+#include <tqlayout.h>
+#include <tqwidget.h>
+
+#include <kdebug.h>
+#include <kaction.h>
+#include <kcommand.h>
+#include <klocale.h>
+
+#include "kis_cursor.h"
+#include "kis_painter.h"
+#include "kis_tool_line.h"
+#include "kis_button_press_event.h"
+#include "kis_button_release_event.h"
+#include "kis_move_event.h"
+#include "kis_paintop_registry.h"
+#include "kis_canvas_subject.h"
+#include "kis_undo_adapter.h"
+#include "kis_canvas.h"
+#include "kis_canvas_painter.h"
+#include "kis_cursor.h"
+#include "kis_layer.h"
+
+KisToolLine::KisToolLine()
+ : super(i18n("Line")),
+ m_dragging( false )
+{
+ setName("tool_line");
+ setCursor(KisCursor::load("tool_line_cursor.png", 6, 6));
+
+ m_painter = 0;
+ m_currentImage = 0;
+ m_startPos = KisPoint(0, 0);
+ m_endPos = KisPoint(0, 0);
+}
+
+KisToolLine::~KisToolLine()
+{
+}
+
+void KisToolLine::update(KisCanvasSubject *subject)
+{
+ m_subject = subject;
+ m_currentImage = subject->currentImg();
+
+ super::update(m_subject);
+}
+
+
+void KisToolLine::paint(KisCanvasPainter& gc)
+{
+ if (m_dragging)
+ paintLine(gc, TQRect());
+}
+
+void KisToolLine::paint(KisCanvasPainter& gc, const TQRect& rc)
+{
+ if (m_dragging)
+ paintLine(gc, rc);
+}
+
+void KisToolLine::buttonPress(KisButtonPressEvent *e)
+{
+ if (!m_subject || !m_currentImage) return;
+
+ if (!m_subject->currentBrush()) return;
+
+ if (e->button() == Qt::LeftButton) {
+ m_dragging = true;
+ //KisCanvasController *controller = m_subject->canvasController();
+ m_startPos = e->pos(); //controller->windowToView(e->pos());
+ m_endPos = e->pos(); //controller->windowToView(e->pos());
+ }
+}
+
+void KisToolLine::move(KisMoveEvent *e)
+{
+ if (m_dragging) {
+ if (m_startPos != m_endPos)
+ paintLine();
+ //KisCanvasController *controller = m_subject->canvasController();
+
+ if (e->state() & TQt::AltButton) {
+ KisPoint trans = e->pos() - m_endPos;
+ m_startPos += trans;
+ m_endPos += trans;
+ } else if (e->state() & TQt::ShiftButton)
+ m_endPos = straightLine(e->pos());
+ else
+ m_endPos = e->pos();//controller->windowToView(e->pos());
+ paintLine();
+ }
+}
+
+void KisToolLine::buttonRelease(KisButtonReleaseEvent *e)
+{
+ if (m_dragging && e->button() == Qt::LeftButton) {
+ m_dragging = false;
+ KisCanvasController *controller = m_subject->canvasController();
+ KisImageSP img = m_subject->currentImg();
+
+ if (m_startPos == m_endPos) {
+ controller->updateCanvas();
+ m_dragging = false;
+ return;
+ }
+
+ if ((e->state() & TQt::ShiftButton) == TQt::ShiftButton) {
+ m_endPos = straightLine(e->pos());
+ }
+ else {
+ m_endPos = e->pos();
+ }
+
+ KisPaintDeviceSP device;
+ if (m_currentImage &&
+ (device = m_currentImage->activeDevice()) &&
+ m_subject &&
+ m_subject->currentBrush())
+ {
+ delete m_painter;
+ m_painter = new KisPainter( device );
+ Q_CHECK_PTR(m_painter);
+
+ if (m_currentImage->undo()) m_painter->beginTransaction(i18n("Line"));
+
+ m_painter->setPaintColor(m_subject->fgColor());
+ m_painter->setBrush(m_subject->currentBrush());
+ m_painter->setOpacity(m_opacity);
+ m_painter->setCompositeOp(m_compositeOp);
+ KisPaintOp * op = KisPaintOpRegistry::instance()->paintOp(m_subject->currentPaintop(), m_subject->currentPaintopSettings(), m_painter);
+ m_painter->setPaintOp(op); // Painter takes ownership
+ m_painter->paintLine(m_startPos, PRESSURE_DEFAULT, 0, 0, m_endPos, PRESSURE_DEFAULT, 0, 0);
+ device->setDirty( m_painter->dirtyRect() );
+ notifyModified();
+
+ /* remove remains of the line drawn while moving */
+ if (controller->kiscanvas()) {
+ controller->kiscanvas()->update();
+ }
+
+ if (m_currentImage->undo() && m_painter) {
+ m_currentImage->undoAdapter()->addCommand(m_painter->endTransaction());
+ }
+ delete m_painter;
+ m_painter = 0;
+ } else {
+ if (m_painter)
+ controller->updateCanvas(m_painter->dirtyRect()); // Removes the last remaining line.
+ }
+ }
+
+}
+
+KisPoint KisToolLine::straightLine(KisPoint point)
+{
+ KisPoint comparison = point - m_startPos;
+ KisPoint result;
+
+ if ( fabs(comparison.x()) > fabs(comparison.y())) {
+ result.setX(point.x());
+ result.setY(m_startPos.y());
+ } else {
+ result.setX( m_startPos.x() );
+ result.setY( point.y() );
+ }
+
+ return result;
+}
+
+void KisToolLine::paintLine()
+{
+ if (m_subject) {
+ KisCanvasController *controller = m_subject->canvasController();
+ KisCanvas *canvas = controller->kiscanvas();
+ KisCanvasPainter gc(canvas);
+ TQRect rc;
+
+ paintLine(gc, rc);
+ }
+}
+
+void KisToolLine::paintLine(KisCanvasPainter& gc, const TQRect&)
+{
+ if (m_subject) {
+ KisCanvasController *controller = m_subject->canvasController();
+ RasterOp op = gc.rasterOp();
+ TQPen old = gc.pen();
+ TQPen pen(TQt::SolidLine);
+ KisPoint start;
+ KisPoint end;
+
+// Q_ASSERT(controller);
+ start = controller->windowToView(m_startPos);
+ end = controller->windowToView(m_endPos);
+// start.setX(start.x() - controller->horzValue());
+// start.setY(start.y() - controller->vertValue());
+// end.setX(end.x() - controller->horzValue());
+// end.setY(end.y() - controller->vertValue());
+// end.setX((end.x() - start.x()));
+// end.setY((end.y() - start.y()));
+// start *= m_subject->zoomFactor();
+// end *= m_subject->zoomFactor();
+ gc.setRasterOp(TQt::NotROP);
+ gc.setPen(pen);
+ gc.drawLine(start.floorTQPoint(), end.floorTQPoint());
+ gc.setRasterOp(op);
+ gc.setPen(old);
+ }
+}
+
+void KisToolLine::setup(KActionCollection *collection)
+{
+ m_action = static_cast<KRadioAction *>(collection->action(name()));
+
+ if (m_action == 0) {
+ m_action = new KRadioAction(i18n("&Line"),
+ "tool_line", TQt::Key_L, this,
+ TQT_SLOT(activate()), collection,
+ name());
+ m_action->setToolTip(i18n("Draw a line"));
+ m_action->setExclusiveGroup("tools");
+ m_ownAction = true;
+ }
+}
+
+TQString KisToolLine::quickHelp() const {
+ return i18n("Alt+Drag will move the origin of the currently displayed line around, Shift+Drag will force you to draw straight lines");
+}
+
+#include "kis_tool_line.moc"
+
diff --git a/chalk/plugins/tools/defaulttools/kis_tool_line.h b/chalk/plugins/tools/defaulttools/kis_tool_line.h
new file mode 100644
index 00000000..4ce0ff38
--- /dev/null
+++ b/chalk/plugins/tools/defaulttools/kis_tool_line.h
@@ -0,0 +1,100 @@
+/*
+ * kis_tool_line.h - part of Krayon
+ *
+ * Copyright (c) 2000 John Califf <jcaliff@comuzone.net>
+ * Copyright (c) 2002 Patrick Julien <freak@codepimps.org>
+ * Copyright (c) 2004 Boudewijn Rempt <boud@valdyas.org>
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef KIS_TOOL_LINE_H_
+#define KIS_TOOL_LINE_H_
+
+#include "kis_tool_paint.h"
+
+#include "kis_global.h"
+#include "kis_types.h"
+#include "kis_tool_factory.h"
+
+class KisBrush;
+class KisPainter;
+
+class TQPoint;
+class TQWidget;
+
+
+class KisToolLine : public KisToolPaint {
+
+ Q_OBJECT
+ TQ_OBJECT
+ typedef KisToolPaint super;
+
+ public:
+ KisToolLine();
+ virtual ~KisToolLine();
+
+ virtual void setup(KActionCollection *collection);
+ virtual enumToolType toolType() { return TOOL_SHAPE; }
+ virtual TQ_UINT32 priority() { return 1; }
+ virtual void update(KisCanvasSubject *subject);
+
+ virtual void buttonPress(KisButtonPressEvent *event);
+ virtual void move(KisMoveEvent *event);
+ virtual void buttonRelease(KisButtonReleaseEvent *event);
+
+ virtual void paint(KisCanvasPainter& gc);
+ virtual void paint(KisCanvasPainter& gc, const TQRect& rc);
+
+ virtual TQString quickHelp() const;
+
+ private:
+ void paintLine();
+ void paintLine(KisCanvasPainter& gc, const TQRect& rc);
+
+ KisPoint straightLine(KisPoint point);
+
+
+ bool m_dragging;
+
+ KisPoint m_startPos;
+ KisPoint m_endPos;
+
+ KisCanvasSubject *m_subject;
+ KisImageSP m_currentImage;
+ KisPainter *m_painter;
+};
+
+
+class KisToolLineFactory : public KisToolFactory {
+ typedef KisToolFactory super;
+public:
+ KisToolLineFactory() : super() {};
+ virtual ~KisToolLineFactory(){};
+
+ virtual KisTool * createTool(KActionCollection * ac) {
+ KisTool * t = new KisToolLine();
+ Q_CHECK_PTR(t);
+ t->setup(ac);
+ return t;
+ }
+ virtual KisID id() { return KisID("line", i18n("Line Tool")); }
+};
+
+
+
+
+#endif //KIS_TOOL_LINE_H_
+
diff --git a/chalk/plugins/tools/defaulttools/kis_tool_move.cc b/chalk/plugins/tools/defaulttools/kis_tool_move.cc
new file mode 100644
index 00000000..7c8733c9
--- /dev/null
+++ b/chalk/plugins/tools/defaulttools/kis_tool_move.cc
@@ -0,0 +1,181 @@
+/*
+ * Copyright (c) 1999 Matthias Elter <me@kde.org>
+ * 1999 Michael Koch <koch@kde.org>
+ * 2002 Patrick Julien <freak@codepimps.org>
+ * 2004 Boudewijn Rempt <boud@valdyas.org>
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <stdlib.h>
+#include <tqpoint.h>
+#include <kaction.h>
+#include <klocale.h>
+#include <tqcolor.h>
+#include "kis_canvas_subject.h"
+#include "kis_cursor.h"
+#include "kis_image.h"
+#include "kis_paint_device.h"
+#include "kis_tool_move.h"
+#include "kis_tool_move.moc"
+#include "kis_button_press_event.h"
+#include "kis_button_release_event.h"
+#include "kis_move_event.h"
+#include "kis_selection.h"
+#include "kis_selection_manager.h"
+#include "kis_layer.h"
+
+KisToolMove::KisToolMove()
+ : super(i18n("Move Tool"))
+ , m_subject( 0 )
+ , m_keyEvent( 0 )
+{
+ setName("tool_move");
+
+ setCursor(KisCursor::moveCursor());
+ m_repeatTimer = new TQTimer(this);
+ connect( m_repeatTimer, TQT_SIGNAL( timeout() ), this, TQT_SLOT( slotMove() ) );
+}
+
+KisToolMove::~KisToolMove()
+{
+}
+
+void KisToolMove::update(KisCanvasSubject *subject)
+{
+ m_subject = subject;
+ m_strategy.reset(subject);
+ super::update(subject);
+}
+
+void KisToolMove::buttonPress(KisButtonPressEvent *e)
+{
+ if (m_subject && e->button() == Qt::LeftButton) {
+ TQPoint pos = e->pos().floorTQPoint();
+ KisImageSP img = m_subject->currentImg();
+ KisLayerSP dev;
+
+ if (!img || !(dev = img->activeLayer()))
+ return;
+
+ m_strategy.startDrag(pos);
+ }
+}
+
+void KisToolMove::move(KisMoveEvent *e)
+{
+ if (m_subject && e->state() == Qt::LeftButton) {
+ TQPoint pos = e->pos().floorTQPoint();
+ if((e->state() & TQt::AltButton) || (e->state() & TQt::ControlButton)) {
+ if(fabs(pos.x() - m_dragStart.x()) > fabs(pos.y() - m_dragStart.y()))
+ pos.setY(m_dragStart.y());
+ else
+ pos.setX(m_dragStart.x());
+ }
+ m_strategy.drag(pos);
+ }
+}
+
+void KisToolMove::buttonRelease(KisButtonReleaseEvent *e)
+{
+ if (m_subject && e->button() == Qt::LeftButton) {
+ m_strategy.endDrag(e->pos().floorTQPoint());
+ }
+}
+
+void KisToolMove::setup(KActionCollection *collection)
+{
+ m_action = static_cast<KRadioAction *>(collection->action(name()));
+
+ if (m_action == 0) {
+ m_action = new KRadioAction(i18n("&Move"),
+ "tool_move",
+ TQt::SHIFT+TQt::Key_V,
+ this,
+ TQT_SLOT(activate()),
+ collection,
+ name());
+ m_action->setToolTip(i18n("Move"));
+ m_action->setExclusiveGroup("tools");
+ m_ownAction = true;
+ }
+}
+
+
+void KisToolMove::keyPress( TQKeyEvent *e )
+{
+ m_keyEvent = e;
+
+ if (m_subject) {
+
+ KisImageSP img = m_subject->currentImg();
+ KisLayerSP dev;
+
+ if (!img || !(dev = img->activeLayer()))
+ return;
+
+ m_dragStart = TQPoint( 0, 0 );
+ m_strategy.startDrag( m_dragStart );
+ m_steps = 1;
+ m_repeatTimer->start(200);
+
+ }
+}
+
+void KisToolMove::keyRelease(TQKeyEvent *)
+{
+ m_repeatTimer->stop();
+
+ if ( m_subject && m_keyEvent) {
+
+ if ( m_keyEvent->key() == TQt::Key_Left ) {
+ m_strategy.endDrag(TQPoint( -m_steps, 0 ));
+ }
+ else if ( m_keyEvent->key() == TQt::Key_Right ) {
+ m_strategy.endDrag(TQPoint(m_steps, 0) );
+ }
+ else if ( m_keyEvent->key() == TQt::Key_Up ) {
+ m_strategy.endDrag(TQPoint(0, -m_steps) );
+ }
+ else if ( m_keyEvent->key() == TQt::Key_Down ) {
+ m_strategy.endDrag(TQPoint(0, m_steps) );
+ }
+ }
+ m_steps = 0;
+ m_keyEvent = 0;
+
+}
+
+void KisToolMove::slotMove()
+{
+ if (m_subject && m_keyEvent) {
+
+ if ( m_keyEvent->key() == TQt::Key_Left ) {
+ m_strategy.drag(TQPoint(-m_steps, 0) );
+ }
+ else if ( m_keyEvent->key() == TQt::Key_Right ) {
+ m_strategy.drag(TQPoint(m_steps, 0) );
+ }
+ else if ( m_keyEvent->key() == TQt::Key_Up ) {
+ m_strategy.drag(TQPoint(0, -m_steps) );
+ }
+ else if ( m_keyEvent->key() == TQt::Key_Down ) {
+ m_strategy.drag(TQPoint(0, m_steps) );
+ }
+
+ ++m_steps;
+ }
+
+}
diff --git a/chalk/plugins/tools/defaulttools/kis_tool_move.h b/chalk/plugins/tools/defaulttools/kis_tool_move.h
new file mode 100644
index 00000000..274cc3c7
--- /dev/null
+++ b/chalk/plugins/tools/defaulttools/kis_tool_move.h
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 1999 Matthias Elter <me@kde.org>
+ * 1999 Michael Koch <koch@kde.org>
+ * 2003 Patrick Julien <freak@codepimps.org>
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef KIS_TOOL_MOVE_H_
+#define KIS_TOOL_MOVE_H_
+
+#include <tqtimer.h>
+
+#include "kis_strategy_move.h"
+#include "kis_tool_non_paint.h"
+#include "kis_tool_factory.h"
+
+class TQTimer;
+
+class KisToolMove : public KisToolNonPaint {
+
+ typedef KisToolNonPaint super;
+ Q_OBJECT
+ TQ_OBJECT
+
+public:
+ KisToolMove();
+ virtual ~KisToolMove();
+
+public:
+ virtual void update(KisCanvasSubject *subject);
+
+public:
+ virtual void setup(KActionCollection *collection);
+ virtual enumToolType toolType() { return TOOL_TRANSFORM; }
+ virtual TQ_UINT32 priority() { return 2; }
+
+ virtual void buttonPress(KisButtonPressEvent *e);
+ virtual void move(KisMoveEvent *e);
+ virtual void buttonRelease(KisButtonReleaseEvent *e);
+ virtual void keyPress(TQKeyEvent *e);
+ virtual void keyRelease(TQKeyEvent *e);
+
+private slots:
+
+ void slotMove();
+
+private:
+
+ KisCanvasSubject *m_subject;
+ KisStrategyMove m_strategy;
+ TQPoint m_dragStart;
+ TQTimer * m_repeatTimer;
+ TQKeyEvent * m_keyEvent;
+ int m_steps;
+};
+
+
+class KisToolMoveFactory : public KisToolFactory {
+ typedef KisToolFactory super;
+public:
+ KisToolMoveFactory() : super() {};
+ virtual ~KisToolMoveFactory(){};
+
+ virtual KisTool * createTool(KActionCollection * ac) {
+ KisTool * t = new KisToolMove();
+ Q_CHECK_PTR(t);
+ t->setup(ac);
+ return t;
+ }
+ virtual KisID id() { return KisID("move", i18n("Move Tool")); }
+};
+
+
+
+#endif // KIS_TOOL_MOVE_H_
+
diff --git a/chalk/plugins/tools/defaulttools/kis_tool_pan.cc b/chalk/plugins/tools/defaulttools/kis_tool_pan.cc
new file mode 100644
index 00000000..f7a92dcb
--- /dev/null
+++ b/chalk/plugins/tools/defaulttools/kis_tool_pan.cc
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2004 Adrian Page <adrian@pagenet.plus.com>
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <kaction.h>
+#include <klocale.h>
+
+#include "kis_canvas_controller.h"
+#include "kis_canvas_subject.h"
+#include "kis_cursor.h"
+#include "kis_tool_pan.h"
+#include "kis_button_press_event.h"
+#include "kis_button_release_event.h"
+#include "kis_move_event.h"
+
+KisToolPan::KisToolPan()
+ : super(i18n("Pan Tool"))
+{
+ setName("tool_pan");
+ m_subject = 0;
+ m_dragging = false;
+ m_openHandCursor = KisCursor::openHandCursor();
+ m_closedHandCursor = KisCursor::closedHandCursor();
+ setCursor(m_openHandCursor);
+}
+
+KisToolPan::~KisToolPan()
+{
+}
+
+void KisToolPan::update(KisCanvasSubject *subject)
+{
+ m_subject = subject;
+ super::update(m_subject);
+}
+
+void KisToolPan::buttonPress(KisButtonPressEvent *e)
+{
+ if (m_subject && !m_dragging && e->button() == Qt::LeftButton) {
+ KisCanvasController *controller = m_subject->canvasController();
+
+ m_origScrollX = controller->horzValue();
+ m_origScrollY = controller->vertValue();
+ m_dragPos = controller->windowToView(e->pos());
+ m_dragging = true;
+ setCursor(m_closedHandCursor);
+ }
+}
+
+void KisToolPan::move(KisMoveEvent *e)
+{
+ if (m_subject && m_dragging) {
+ KisCanvasController *controller = m_subject->canvasController();
+
+ KisPoint currPos = controller->windowToView(e->pos());
+ KisPoint delta = currPos - m_dragPos;
+ controller->scrollTo(m_origScrollX - delta.floorX(), m_origScrollY - delta.floorY());
+ }
+}
+
+void KisToolPan::buttonRelease(KisButtonReleaseEvent *e)
+{
+ if (m_subject && m_dragging && e->button() == Qt::LeftButton) {
+ setCursor(m_openHandCursor);
+ m_dragging = false;
+ }
+}
+
+void KisToolPan::setup(KActionCollection *collection)
+{
+ m_action = static_cast<KRadioAction *>(collection->action(name()));
+
+ if (m_action == 0) {
+ m_action = new KRadioAction(i18n("&Pan"), "tool_pan", TQt::SHIFT+TQt::Key_H, this, TQT_SLOT(activate()), collection, name());
+ m_action->setToolTip(i18n("Pan"));
+ m_action->setExclusiveGroup("tools");
+ m_ownAction = true;
+ }
+}
+
+#include "kis_tool_pan.moc"
+
diff --git a/chalk/plugins/tools/defaulttools/kis_tool_pan.h b/chalk/plugins/tools/defaulttools/kis_tool_pan.h
new file mode 100644
index 00000000..36ed9dcc
--- /dev/null
+++ b/chalk/plugins/tools/defaulttools/kis_tool_pan.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2004 Adrian Page <adrian@pagenet.plus.com>
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef KIS_TOOL_PAN_H_
+#define KIS_TOOL_PAN_H_
+
+#include "kis_point.h"
+#include "kis_tool_non_paint.h"
+#include "kis_tool_factory.h"
+#include <koffice_export.h>
+
+class KisCanvasSubject;
+class KisPoint;
+
+class KRITATOOL_EXPORT KisToolPan : public KisToolNonPaint
+{
+
+ typedef KisToolNonPaint super;
+ Q_OBJECT
+ TQ_OBJECT
+
+public:
+ KisToolPan();
+ virtual ~KisToolPan();
+
+ virtual void update(KisCanvasSubject *subject);
+
+ virtual void setup(KActionCollection *collection);
+ virtual enumToolType toolType() { return TOOL_VIEW; }
+ virtual TQ_UINT32 priority() { return 1; }
+
+ virtual void buttonPress(KisButtonPressEvent *e);
+ virtual void move(KisMoveEvent *e);
+ virtual void buttonRelease(KisButtonReleaseEvent *e);
+
+ virtual bool wantsAutoScroll() const { return false; }
+
+private:
+ KisCanvasSubject *m_subject;
+ KisPoint m_dragPos;
+ TQ_INT32 m_origScrollX;
+ TQ_INT32 m_origScrollY;
+ bool m_dragging;
+ TQCursor m_openHandCursor;
+ TQCursor m_closedHandCursor;
+};
+
+class KisToolPanFactory : public KisToolFactory {
+ typedef KisToolFactory super;
+public:
+ KisToolPanFactory() : super() {};
+ virtual ~KisToolPanFactory(){};
+
+ virtual KisTool * createTool(KActionCollection * ac) {
+ KisTool * t = new KisToolPan();
+ Q_CHECK_PTR(t);
+ t->setup(ac);
+ return t;
+ }
+ virtual KisID id() { return KisID("pan", i18n("Pan Tool")); }
+};
+
+
+#endif // KIS_TOOL_PAN_H_
+
diff --git a/chalk/plugins/tools/defaulttools/kis_tool_rectangle.cc b/chalk/plugins/tools/defaulttools/kis_tool_rectangle.cc
new file mode 100644
index 00000000..b8387d78
--- /dev/null
+++ b/chalk/plugins/tools/defaulttools/kis_tool_rectangle.cc
@@ -0,0 +1,187 @@
+/*
+ * kis_tool_rectangle.cc - part of Chalk
+ *
+ * Copyright (c) 2000 John Califf <jcaliff@compuzone.net>
+ * Copyright (c) 2002 Patrick Julien <freak@codepimps.org>
+ * Copyright (c) 2004 Boudewijn Rempt <boud@valdyas.org>
+ * Copyright (c) 2004 Clarence Dang <dang@k.org>
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <tqpainter.h>
+
+#include <kaction.h>
+#include <kdebug.h>
+#include <klocale.h>
+
+#include "kis_button_press_event.h"
+#include "kis_button_release_event.h"
+#include "kis_canvas_controller.h"
+#include "kis_canvas_subject.h"
+#include "kis_move_event.h"
+#include "kis_painter.h"
+#include "kis_paintop_registry.h"
+#include "kis_tool_rectangle.h"
+#include "kis_undo_adapter.h"
+#include "kis_canvas.h"
+#include "kis_canvas_painter.h"
+#include "kis_cursor.h"
+#include "kis_layer.h"
+
+KisToolRectangle::KisToolRectangle()
+ : super(i18n ("Rectangle")),
+ m_dragging (false),
+ m_currentImage (0)
+{
+ setName("tool_rectangle");
+ setCursor(KisCursor::load("tool_rectangle_cursor.png", 6, 6));
+}
+
+KisToolRectangle::~KisToolRectangle()
+{
+}
+
+void KisToolRectangle::update (KisCanvasSubject *subject)
+{
+ super::update (subject);
+ if (m_subject)
+ m_currentImage = m_subject->currentImg ();
+}
+
+void KisToolRectangle::buttonPress(KisButtonPressEvent *event)
+{
+ if (m_currentImage && event->button() == Qt::LeftButton) {
+ m_dragging = true;
+ m_dragStart = m_dragCenter = m_dragEnd = event->pos();
+ draw(m_dragStart, m_dragEnd);
+ }
+}
+
+void KisToolRectangle::move(KisMoveEvent *event)
+{
+ if (m_dragging) {
+ // erase old lines on canvas
+ draw(m_dragStart, m_dragEnd);
+ // move (alt) or resize rectangle
+ if (event->state() & TQt::AltButton) {
+ KisPoint trans = event->pos() - m_dragEnd;
+ m_dragStart += trans;
+ m_dragEnd += trans;
+ } else {
+ KisPoint diag = event->pos() - (event->state() & TQt::ControlButton
+ ? m_dragCenter : m_dragStart);
+ // square?
+ if (event->state() & TQt::ShiftButton) {
+ double size = TQMAX(fabs(diag.x()), fabs(diag.y()));
+ double w = diag.x() < 0 ? -size : size;
+ double h = diag.y() < 0 ? -size : size;
+ diag = KisPoint(w, h);
+ }
+
+ // resize around center point?
+ if (event->state() & TQt::ControlButton) {
+ m_dragStart = m_dragCenter - diag;
+ m_dragEnd = m_dragCenter + diag;
+ } else {
+ m_dragEnd = m_dragStart + diag;
+ }
+ }
+ // draw new lines on canvas
+ draw(m_dragStart, m_dragEnd);
+ m_dragCenter = KisPoint((m_dragStart.x() + m_dragEnd.x()) / 2,
+ (m_dragStart.y() + m_dragEnd.y()) / 2);
+ }
+}
+
+void KisToolRectangle::buttonRelease(KisButtonReleaseEvent *event)
+{
+ if (!m_subject)
+ return;
+
+ if (!m_currentImage)
+ return;
+
+ KisPaintDeviceSP device = m_currentImage->activeDevice ();
+ if (!device) return;
+
+ if (m_dragging && event->button() == Qt::LeftButton) {
+ // erase old lines on canvas
+ draw(m_dragStart, m_dragEnd);
+ m_dragging = false;
+
+ if (m_dragStart == m_dragEnd)
+ return;
+
+ if (!m_currentImage)
+ return;
+
+
+ KisPainter painter (device);
+ if (m_currentImage->undo()) painter.beginTransaction (i18n ("Rectangle"));
+
+ painter.setPaintColor(m_subject->fgColor());
+ painter.setBackgroundColor(m_subject->bgColor());
+ painter.setFillStyle(fillStyle());
+ painter.setBrush(m_subject->currentBrush());
+ painter.setPattern(m_subject->currentPattern());
+ painter.setOpacity(m_opacity);
+ painter.setCompositeOp(m_compositeOp);
+ KisPaintOp * op = KisPaintOpRegistry::instance()->paintOp(m_subject->currentPaintop(), m_subject->currentPaintopSettings(), &painter);
+ painter.setPaintOp(op);
+
+ painter.paintRect(m_dragStart, m_dragEnd, PRESSURE_DEFAULT/*event->pressure()*/, event->xTilt(), event->yTilt());
+ device->setDirty( painter.dirtyRect() );
+ notifyModified();
+
+ if (m_currentImage->undo()) {
+ m_currentImage->undoAdapter()->addCommand(painter.endTransaction());
+ }
+ }
+}
+
+void KisToolRectangle::draw(const KisPoint& start, const KisPoint& end )
+{
+ if (!m_subject)
+ return;
+
+ KisCanvasController *controller = m_subject->canvasController ();
+ KisCanvas *canvas = controller->kiscanvas();
+ KisCanvasPainter p (canvas);
+
+ p.setRasterOp (TQt::NotROP);
+ p.drawRect (TQRect (controller->windowToView (start).floorTQPoint(), controller->windowToView (end).floorTQPoint()));
+ p.end ();
+}
+
+void KisToolRectangle::setup(KActionCollection *collection)
+{
+ m_action = static_cast<KRadioAction *>(collection->action(name()));
+
+ if (m_action == 0) {
+ m_action = new KRadioAction(i18n("&Rectangle"),
+ "tool_rectangle",
+ TQt::Key_F6,
+ this,
+ TQT_SLOT(activate()),
+ collection,
+ name());
+ m_action->setToolTip(i18n("Draw a rectangle"));
+ m_action->setExclusiveGroup("tools");
+ m_ownAction = true;
+ }
+}
+
+#include "kis_tool_rectangle.moc"
diff --git a/chalk/plugins/tools/defaulttools/kis_tool_rectangle.h b/chalk/plugins/tools/defaulttools/kis_tool_rectangle.h
new file mode 100644
index 00000000..d9f898a9
--- /dev/null
+++ b/chalk/plugins/tools/defaulttools/kis_tool_rectangle.h
@@ -0,0 +1,96 @@
+/*
+ * kis_tool_rectangle.h - part of KImageShop^WKrayon^WChalk
+ *
+ * Copyright (c) 1999 Michael Koch <koch@kde.org>
+ * Copyright (c) 2002 Patrick Julien <freak@codepimps.org>
+ * Copyright (c) 2004 Boudewijn Rempt <boud@valdyas.org>
+ * Copyright (c) 2004 Clarence Dang <dang@kde.org>
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __KIS_TOOL_RECTANGLE_H__
+#define __KIS_TOOL_RECTANGLE_H__
+
+#include <tqrect.h>
+
+#include "kis_tool_shape.h"
+#include "kis_types.h"
+#include "kis_tool_factory.h"
+#include "kis_point.h"
+
+class TQPainter;
+class KisPainter;
+
+class KisToolRectangle : public KisToolShape {
+
+ typedef KisToolShape super;
+ Q_OBJECT
+ TQ_OBJECT
+
+public:
+ KisToolRectangle();
+ virtual ~KisToolRectangle();
+
+ //
+ // KisCanvasObserver interface
+ //
+
+ virtual void update (KisCanvasSubject *subject);
+
+ //
+ // KisToolPaint interface
+ //
+
+ virtual void setup(KActionCollection *collection);
+ virtual enumToolType toolType() { return TOOL_SHAPE; }
+ virtual TQ_UINT32 priority() { return 2; }
+ virtual void buttonPress(KisButtonPressEvent *event);
+ virtual void move(KisMoveEvent *event);
+ virtual void buttonRelease(KisButtonReleaseEvent *event);
+
+protected:
+ virtual void draw(const KisPoint&, const KisPoint&);
+
+protected:
+ int m_lineThickness;
+
+ KisPoint m_dragCenter;
+ KisPoint m_dragStart;
+ KisPoint m_dragEnd;
+ TQRect m_final_lines;
+
+ bool m_dragging;
+ KisImageSP m_currentImage;
+};
+
+class KisToolRectangleFactory : public KisToolFactory {
+ typedef KisToolFactory super;
+public:
+ KisToolRectangleFactory() : super() {};
+ virtual ~KisToolRectangleFactory(){};
+
+ virtual KisTool * createTool(KActionCollection * ac) {
+ KisTool * t = new KisToolRectangle();
+ Q_CHECK_PTR(t);
+ t->setup(ac);
+ return t;
+ }
+ virtual KisID id() { return KisID("rectangle", i18n("Rectangle Tool")); }
+};
+
+
+#endif // __KIS_TOOL_RECTANGLE_H__
+
diff --git a/chalk/plugins/tools/defaulttools/kis_tool_text.cc b/chalk/plugins/tools/defaulttools/kis_tool_text.cc
new file mode 100644
index 00000000..df247917
--- /dev/null
+++ b/chalk/plugins/tools/defaulttools/kis_tool_text.cc
@@ -0,0 +1,198 @@
+/*
+ * Copyright (c) 2004 Bart Coppens <kde@bartcoppens.be>
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <tqfont.h>
+#include <tqrect.h>
+#include <tqimage.h>
+#include <tqlayout.h>
+#include <tqwidget.h>
+#include <tqstring.h>
+#include <tqpixmap.h>
+#include <tqpainter.h>
+#include <tqpushbutton.h>
+#include <tqfontmetrics.h>
+#include <tqhbox.h>
+
+#include <kaction.h>
+#include <kinputdialog.h>
+#include <klocale.h>
+#include <kfontdialog.h>
+#include <ksqueezedtextlabel.h>
+
+#include <tqcolor.h>
+
+#include "kis_point.h"
+#include "kis_image.h"
+#include "kis_layer.h"
+#include "kis_group_layer.h"
+#include "kis_paint_layer.h"
+#include "kis_cursor.h"
+#include "kis_tool_text.h"
+#include "kis_paint_device.h"
+#include "kis_canvas_subject.h"
+#include "kis_button_press_event.h"
+#include "kis_button_release_event.h"
+#include "kis_color.h"
+#include "kis_undo_adapter.h"
+
+KisToolText::KisToolText()
+ : super(i18n("Text"))
+ , m_wasPressed( false )
+ , m_windowIsBeingShown( false )
+{
+ setName("tool_text");
+ m_subject = 0;
+ setCursor(KisCursor::load("tool_text_cursor.png", 6, 6));
+}
+
+KisToolText::~KisToolText()
+{
+}
+
+void KisToolText::update(KisCanvasSubject *subject)
+{
+ m_subject = subject;
+ super::update(subject);
+}
+
+void KisToolText::buttonPress(KisButtonPressEvent *e)
+{
+ if (m_subject && e->button() == Qt::LeftButton) {
+ m_wasPressed = true;
+ }
+}
+
+void KisToolText::buttonRelease(KisButtonReleaseEvent *e)
+{
+ if ( m_windowIsBeingShown ) return;
+
+ if (m_subject && e->button() == Qt::LeftButton) {
+ if(!m_wasPressed) return;
+ m_wasPressed = false;
+ KisImageSP img = m_subject->currentImg();
+
+ m_windowIsBeingShown = true;
+ bool ok;
+ TQString text = KInputDialog::getText(i18n("Font Tool"), i18n("Enter text:"),
+ TQString(), &ok);
+ if (!ok) {
+ m_windowIsBeingShown = false;
+ return;
+ }
+
+ KisUndoAdapter *undoAdapter = img->undoAdapter();
+ if (undoAdapter) {
+ undoAdapter->beginMacro(i18n("Text"));
+ }
+
+ TQFontMetrics metrics(m_font);
+ TQRect boundingRect = TQT_TQRECT_OBJECT(metrics.boundingRect(text)).normalize();
+ int xB = - boundingRect.x();
+ int yB = - boundingRect.y();
+
+ if (boundingRect.x() < 0 || boundingRect.y() < 0)
+ boundingRect.moveBy(- boundingRect.x(), - boundingRect.y());
+
+ TQPixmap pixels(boundingRect.width(), boundingRect.height());
+ {
+ TQPainter paint(&pixels);
+ paint.fillRect(boundingRect, TQt::white);
+ paint.setFont(m_font);
+ paint.setBrush(TQBrush(TQt::black));
+ paint.drawText(xB, yB, text);
+ }
+ TQImage image = pixels.convertToImage();
+
+ TQ_INT32 height = boundingRect.height();
+ TQ_INT32 width = boundingRect.width();
+ KisPaintLayer *layer = new KisPaintLayer(img, '"' + text + '"', OPACITY_OPAQUE);
+ KisGroupLayerSP tqparent = img->rootLayer();
+ if (img->activeLayer())
+ tqparent = img->activeLayer()->tqparent();
+ img->addLayer(layer, tqparent, img->activeLayer());
+ for (int y = 0; y < height; y++) {
+ for (int x = 0; x < width; x++) {
+ TQRgb pixel = image.pixel(x, y);
+ // use the 'blackness' as alpha :)
+ TQ_UINT8 alpha = 255 - tqRed(pixel) * OPACITY_OPAQUE / 255;
+ TQColor c = m_subject->fgColor().toTQColor();
+ layer->paintDevice()->setPixel(x, y, c, alpha);
+ }
+ }
+
+ layer->setOpacity(m_opacity);
+ layer->setCompositeOp(m_compositeOp);
+
+ layer->setVisible(false);
+ TQ_INT32 x = TQMAX(0, static_cast<int>(e->x() - width/2));
+ TQ_INT32 y = TQMAX(0, static_cast<int>(e->y() - height/2));
+ layer->setX(x);
+ layer->setY(y);
+ layer->setVisible(true);
+ layer->setDirty();
+
+ if (undoAdapter) {
+ undoAdapter->endMacro();
+ }
+
+ m_windowIsBeingShown = false;
+ }
+}
+
+void KisToolText::setFont() {
+ KFontDialog::getFont( m_font, false/*, TQWidget* tqparent! */ );
+ m_lbFontName->setText(TQString(m_font.family() + ", %1").tqarg(m_font.pointSize()));
+}
+
+TQWidget* KisToolText::createOptionWidget(TQWidget* tqparent)
+{
+ TQWidget *widget = super::createOptionWidget(tqparent);
+
+ m_lbFont = new TQLabel(i18n("Font: "), widget);
+
+ TQHBox *fontBox = new TQHBox(widget);
+ m_lbFontName = new KSqueezedTextLabel(TQString(m_font.family() + ", %1")
+ .tqarg(m_font.pointSize()), fontBox);
+ m_btnMoreFonts = new TQPushButton("...", fontBox);
+
+ connect(m_btnMoreFonts, TQT_SIGNAL(released()), this, TQT_SLOT(setFont()));
+
+ addOptionWidgetOption(fontBox, m_lbFont);
+
+ return widget;
+}
+
+void KisToolText::setup(KActionCollection *collection)
+{
+ m_action = static_cast<KRadioAction *>(collection->action(name()));
+
+ if (m_action == 0) {
+ m_action = new KRadioAction(i18n("T&ext"),
+ "tool_text",
+ TQt::SHIFT+TQt::Key_T,
+ this,
+ TQT_SLOT(activate()),
+ collection,
+ name());
+ m_action->setExclusiveGroup("tools");
+ m_action->setToolTip(i18n("Text"));
+ m_ownAction = true;
+ }
+}
+
+#include "kis_tool_text.moc"
diff --git a/chalk/plugins/tools/defaulttools/kis_tool_text.h b/chalk/plugins/tools/defaulttools/kis_tool_text.h
new file mode 100644
index 00000000..b2aa7e18
--- /dev/null
+++ b/chalk/plugins/tools/defaulttools/kis_tool_text.h
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2004 Bart Coppens <kde@bartcoppens.be>
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef KIS_TOOL_TEXT_H_
+#define KIS_TOOL_TEXT_H_
+
+#include "kis_tool_paint.h"
+
+#include "kis_tool_factory.h"
+
+class TQFont;
+class TQLabel;
+class TQWidget;
+class TQPushButton;
+class KSqueezedTextLabel;
+
+
+
+class KisToolText : public KisToolPaint {
+ typedef KisToolPaint super;
+ Q_OBJECT
+ TQ_OBJECT
+
+public:
+ KisToolText();
+ virtual ~KisToolText();
+
+ virtual void update(KisCanvasSubject *subject);
+ virtual void setup(KActionCollection *collection);
+ virtual enumToolType toolType() { return TOOL_FILL; }
+ virtual TQ_UINT32 priority() { return 2; }
+ virtual void buttonPress(KisButtonPressEvent*);
+ virtual void buttonRelease(KisButtonReleaseEvent *e);
+
+ virtual TQWidget* createOptionWidget(TQWidget* tqparent);
+public slots:
+ virtual void setFont();
+
+private:
+ KisCanvasSubject *m_subject;
+ TQFont m_font;
+ TQLabel *m_lbFont;
+ KSqueezedTextLabel *m_lbFontName;
+ TQPushButton *m_btnMoreFonts;
+ bool m_wasPressed; // use for preventing bug:136151
+ bool m_windowIsBeingShown;
+};
+
+
+class KisToolTextFactory : public KisToolFactory {
+ typedef KisToolFactory super;
+public:
+ KisToolTextFactory() : super() {};
+ virtual ~KisToolTextFactory(){};
+
+ virtual KisTool * createTool(KActionCollection * ac) {
+ KisTool * t = new KisToolText();
+ Q_CHECK_PTR(t);
+ t->setup(ac);
+ return t;
+ }
+ virtual KisID id() { return KisID("text", i18n("Text Tool")); }
+};
+
+
+#endif // KIS_TOOL_TEXT_H_
diff --git a/chalk/plugins/tools/defaulttools/kis_tool_zoom.cc b/chalk/plugins/tools/defaulttools/kis_tool_zoom.cc
new file mode 100644
index 00000000..f866e5e2
--- /dev/null
+++ b/chalk/plugins/tools/defaulttools/kis_tool_zoom.cc
@@ -0,0 +1,191 @@
+/*
+ * Copyright (c) 1999 Matthias Elter <me@kde.org>
+ * Copyright (c) 2002 Patrick Julien <freak@codepimps.org>
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <kaction.h>
+#include <klocale.h>
+#include <kapplication.h>
+
+#include "kis_image.h"
+#include "kis_paint_device.h"
+#include "kis_paint_layer.h"
+#include "kis_canvas_controller.h"
+#include "kis_canvas_subject.h"
+#include "kis_canvas.h"
+#include "kis_canvas_painter.h"
+#include "kis_cursor.h"
+#include "kis_button_press_event.h"
+#include "kis_button_release_event.h"
+#include "kis_move_event.h"
+#include "kis_tool_zoom.h"
+
+
+KisToolZoom::KisToolZoom()
+ : super(i18n("Zoom Tool"))
+{
+ setName("tool_zoom");
+ m_subject = 0;
+ m_dragging = false;
+ m_startPos = TQPoint(0, 0);
+ m_endPos = TQPoint(0, 0);
+ m_plusCursor = KisCursor::load("tool_zoom_plus_cursor.png", 8, 8);
+ m_minusCursor = KisCursor::load("tool_zoom_minus_cursor.png", 8, 8);
+ setCursor(m_plusCursor);
+ connect(&m_timer, TQT_SIGNAL(timeout()), TQT_SLOT(slotTimer()));
+}
+
+KisToolZoom::~KisToolZoom()
+{
+}
+
+void KisToolZoom::update(KisCanvasSubject *subject)
+{
+ m_subject = subject;
+ super::update(m_subject);
+}
+
+void KisToolZoom::paint(KisCanvasPainter& gc)
+{
+ if (m_dragging)
+ paintOutline(gc, TQRect());
+}
+
+void KisToolZoom::paint(KisCanvasPainter& gc, const TQRect& rc)
+{
+ if (m_dragging)
+ paintOutline(gc, rc);
+}
+
+void KisToolZoom::buttonPress(KisButtonPressEvent *e)
+{
+ if (m_subject && m_subject->currentImg() && !m_dragging) {
+ if (e->button() == Qt::LeftButton) {
+ m_startPos = e->pos().floorTQPoint();
+ m_endPos = e->pos().floorTQPoint();
+ m_dragging = true;
+ }
+ }
+}
+
+void KisToolZoom::move(KisMoveEvent *e)
+{
+ if (m_subject && m_dragging) {
+ if (m_startPos != m_endPos)
+ paintOutline();
+
+ m_endPos = e->pos().floorTQPoint();
+ paintOutline();
+ }
+}
+
+void KisToolZoom::buttonRelease(KisButtonReleaseEvent *e)
+{
+ if (m_subject && m_dragging && e->button() == Qt::LeftButton) {
+
+ KisCanvasController *controller = m_subject->canvasController();
+ m_endPos = e->pos().floorTQPoint();
+ m_dragging = false;
+
+ TQPoint delta = m_endPos - m_startPos;
+
+ if (sqrt(delta.x() * delta.x() + delta.y() * delta.y()) < 10) {
+ if (e->state() & TQt::ControlButton) {
+ controller->zoomOut(m_endPos.x(), m_endPos.y());
+ } else {
+ controller->zoomIn(m_endPos.x(), m_endPos.y());
+ }
+ } else {
+ controller->zoomTo(TQRect(m_startPos, m_endPos));
+ }
+ }
+}
+
+void KisToolZoom::activate()
+{
+ super::activate();
+ m_timer.start(50);
+}
+
+void KisToolZoom::deactivate()
+{
+ m_timer.stop();
+}
+
+void KisToolZoom::slotTimer()
+{
+#if KDE_IS_VERSION(3,4,0)
+ int state = kapp->keyboardMouseState() & (TQt::ShiftButton|TQt::ControlButton|TQt::AltButton);
+#else
+ int state = kapp->keyboardModifiers() & (KApplication::ShiftModifier
+ |KApplication::ControlModifier|KApplication::Modifier1);
+#endif
+
+ if (state & TQt::ControlButton) {
+ m_subject->canvasController()->setCanvasCursor(m_minusCursor);
+ } else {
+ m_subject->canvasController()->setCanvasCursor(m_plusCursor);
+ }
+}
+
+void KisToolZoom::paintOutline()
+{
+ if (m_subject) {
+ KisCanvasController *controller = m_subject->canvasController();
+ KisCanvas *canvas = controller->kiscanvas();
+ KisCanvasPainter gc(canvas);
+ TQRect rc;
+
+ paintOutline(gc, rc);
+ }
+}
+
+void KisToolZoom::paintOutline(KisCanvasPainter& gc, const TQRect&)
+{
+ if (m_subject) {
+ KisCanvasController *controller = m_subject->canvasController();
+ RasterOp op = gc.rasterOp();
+ TQPen old = gc.pen();
+ TQPen pen(TQt::DotLine);
+ TQPoint start;
+ TQPoint end;
+
+ Q_ASSERT(controller);
+ start = controller->windowToView(m_startPos);
+ end = controller->windowToView(m_endPos);
+
+ gc.setRasterOp(TQt::NotROP);
+ gc.setPen(pen);
+ gc.drawRect(TQRect(start, end));
+ gc.setRasterOp(op);
+ gc.setPen(old);
+ }
+}
+
+void KisToolZoom::setup(KActionCollection *collection)
+{
+ m_action = static_cast<KRadioAction *>(collection->action(name()));
+
+ if (m_action == 0) {
+ m_action = new KRadioAction(i18n("&Zoom"), "tool_zoom", TQt::Key_Z, this, TQT_SLOT(activate()), collection, name());
+ m_action->setToolTip(i18n("Zoom"));
+ m_action->setExclusiveGroup("tools");
+ m_ownAction = true;
+ }
+}
+
+#include "kis_tool_zoom.moc"
diff --git a/chalk/plugins/tools/defaulttools/kis_tool_zoom.h b/chalk/plugins/tools/defaulttools/kis_tool_zoom.h
new file mode 100644
index 00000000..3faa5bf1
--- /dev/null
+++ b/chalk/plugins/tools/defaulttools/kis_tool_zoom.h
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 1999 Matthias Elter <me@kde.org>
+ * Copyright (c) 2002 Patrick Julien <freak@codepimps.org>
+ * Copyright (c) 2004 Boudewijn Rempt <boud@valdyas.org>
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef KIS_ZOOM_TOOL_H_
+#define KIS_ZOOM_TOOL_H_
+
+#include <tqtimer.h>
+
+#include "kis_tool_non_paint.h"
+
+#include "kis_tool_factory.h"
+
+class KisCanvasSubject;
+
+class KisToolZoom : public KisToolNonPaint {
+
+ typedef KisToolNonPaint super;
+ Q_OBJECT
+ TQ_OBJECT
+
+public:
+ KisToolZoom();
+ virtual ~KisToolZoom();
+
+public:
+ virtual void update(KisCanvasSubject *subject);
+
+public:
+ virtual void setup(KActionCollection *collection);
+ virtual enumToolType toolType() { return TOOL_VIEW; }
+ virtual TQ_UINT32 priority() { return 2; }
+
+ virtual void buttonPress(KisButtonPressEvent *e);
+ virtual void move(KisMoveEvent *e);
+ virtual void buttonRelease(KisButtonReleaseEvent *e);
+
+ virtual void paint(KisCanvasPainter& gc);
+ virtual void paint(KisCanvasPainter& gc, const TQRect& rc);
+
+private:
+ void paintOutline();
+ void paintOutline(KisCanvasPainter& gc, const TQRect& rc);
+
+
+public slots:
+
+ void activate();
+ void deactivate();
+
+
+private slots:
+ void slotTimer();
+
+private:
+ KisCanvasSubject *m_subject;
+ TQPoint m_startPos;
+ TQPoint m_endPos;
+ bool m_dragging;
+ TQCursor m_plusCursor;
+ TQCursor m_minusCursor;
+ TQTimer m_timer;
+};
+
+
+class KisToolZoomFactory : public KisToolFactory {
+ typedef KisToolFactory super;
+public:
+ KisToolZoomFactory() : super() {};
+ virtual ~KisToolZoomFactory(){};
+
+ virtual KisTool * createTool(KActionCollection * ac) {
+ KisTool * t = new KisToolZoom();
+ Q_CHECK_PTR(t);
+ t->setup(ac);
+ return t;
+ }
+ virtual KisID id() { return KisID("zoom", i18n("Zoom Tool")); }
+};
+
+
+#endif // KIS_ZOOM_TOOL_H_
diff --git a/chalk/plugins/tools/defaulttools/openhand_cursor.xpm b/chalk/plugins/tools/defaulttools/openhand_cursor.xpm
new file mode 100644
index 00000000..607879d5
--- /dev/null
+++ b/chalk/plugins/tools/defaulttools/openhand_cursor.xpm
@@ -0,0 +1,28 @@
+/* XPM */
+static char *openhand_cursor[]={
+"22 22 3 1",
+". c None",
+"# c #000000",
+"a c #ffffff",
+"......................",
+"..........##..........",
+".........#aa###.......",
+".......###aa#aa#......",
+"......#aa#aa#aa##.....",
+"......#aa#aa#aa#a#....",
+"......#aa#aa#aa#aa#...",
+"..###.#aa#aa#aa#aa#...",
+"..#aa##aaaaaaaa#aa#...",
+"..#aaa#aaaaaaaaaaa#...",
+"...#aa#aaaaaaaaaaa#...",
+"....#a#aaaaaaaaaaa#...",
+"....#aaaaaaaaaaaaa#...",
+".....#aaaaaaaaaaaa#...",
+".....#aaaaaaaaaaa#....",
+"......#aaaaaaaaaa#....",
+"......#aaaaaaaaaa#....",
+".......#aaaaaaaa#.....",
+".......#aaaaaaaa#.....",
+".......##########.....",
+"......................",
+"......................"};
diff --git a/chalk/plugins/tools/defaulttools/tool_color_fill.png b/chalk/plugins/tools/defaulttools/tool_color_fill.png
new file mode 100644
index 00000000..fdbe9ae5
--- /dev/null
+++ b/chalk/plugins/tools/defaulttools/tool_color_fill.png
Binary files differ
diff --git a/chalk/plugins/tools/defaulttools/tool_colorpicker.png b/chalk/plugins/tools/defaulttools/tool_colorpicker.png
new file mode 100644
index 00000000..06164f7e
--- /dev/null
+++ b/chalk/plugins/tools/defaulttools/tool_colorpicker.png
Binary files differ
diff --git a/chalk/plugins/tools/defaulttools/tool_duplicate.png b/chalk/plugins/tools/defaulttools/tool_duplicate.png
new file mode 100644
index 00000000..1710cf5d
--- /dev/null
+++ b/chalk/plugins/tools/defaulttools/tool_duplicate.png
Binary files differ
diff --git a/chalk/plugins/tools/defaulttools/tool_duplicate_cursor.png b/chalk/plugins/tools/defaulttools/tool_duplicate_cursor.png
new file mode 100644
index 00000000..31418815
--- /dev/null
+++ b/chalk/plugins/tools/defaulttools/tool_duplicate_cursor.png
Binary files differ
diff --git a/chalk/plugins/tools/defaulttools/tool_ellipse.png b/chalk/plugins/tools/defaulttools/tool_ellipse.png
new file mode 100644
index 00000000..a8ac0bd1
--- /dev/null
+++ b/chalk/plugins/tools/defaulttools/tool_ellipse.png
Binary files differ
diff --git a/chalk/plugins/tools/defaulttools/tool_ellipse_cursor.png b/chalk/plugins/tools/defaulttools/tool_ellipse_cursor.png
new file mode 100644
index 00000000..b97f215b
--- /dev/null
+++ b/chalk/plugins/tools/defaulttools/tool_ellipse_cursor.png
Binary files differ
diff --git a/chalk/plugins/tools/defaulttools/tool_fill_cursor.png b/chalk/plugins/tools/defaulttools/tool_fill_cursor.png
new file mode 100644
index 00000000..66691cb1
--- /dev/null
+++ b/chalk/plugins/tools/defaulttools/tool_fill_cursor.png
Binary files differ
diff --git a/chalk/plugins/tools/defaulttools/tool_freehand.png b/chalk/plugins/tools/defaulttools/tool_freehand.png
new file mode 100644
index 00000000..c313410d
--- /dev/null
+++ b/chalk/plugins/tools/defaulttools/tool_freehand.png
Binary files differ
diff --git a/chalk/plugins/tools/defaulttools/tool_freehand_cursor.png b/chalk/plugins/tools/defaulttools/tool_freehand_cursor.png
new file mode 100644
index 00000000..194bb200
--- /dev/null
+++ b/chalk/plugins/tools/defaulttools/tool_freehand_cursor.png
Binary files differ
diff --git a/chalk/plugins/tools/defaulttools/tool_gradient.png b/chalk/plugins/tools/defaulttools/tool_gradient.png
new file mode 100644
index 00000000..a45075a8
--- /dev/null
+++ b/chalk/plugins/tools/defaulttools/tool_gradient.png
Binary files differ
diff --git a/chalk/plugins/tools/defaulttools/tool_gradient_cursor.png b/chalk/plugins/tools/defaulttools/tool_gradient_cursor.png
new file mode 100644
index 00000000..fd20079a
--- /dev/null
+++ b/chalk/plugins/tools/defaulttools/tool_gradient_cursor.png
Binary files differ
diff --git a/chalk/plugins/tools/defaulttools/tool_line.png b/chalk/plugins/tools/defaulttools/tool_line.png
new file mode 100644
index 00000000..49f6fe2b
--- /dev/null
+++ b/chalk/plugins/tools/defaulttools/tool_line.png
Binary files differ
diff --git a/chalk/plugins/tools/defaulttools/tool_line_cursor.png b/chalk/plugins/tools/defaulttools/tool_line_cursor.png
new file mode 100644
index 00000000..66ec6b05
--- /dev/null
+++ b/chalk/plugins/tools/defaulttools/tool_line_cursor.png
Binary files differ
diff --git a/chalk/plugins/tools/defaulttools/tool_move.png b/chalk/plugins/tools/defaulttools/tool_move.png
new file mode 100644
index 00000000..386224ed
--- /dev/null
+++ b/chalk/plugins/tools/defaulttools/tool_move.png
Binary files differ
diff --git a/chalk/plugins/tools/defaulttools/tool_pan.png b/chalk/plugins/tools/defaulttools/tool_pan.png
new file mode 100644
index 00000000..c45a9c69
--- /dev/null
+++ b/chalk/plugins/tools/defaulttools/tool_pan.png
Binary files differ
diff --git a/chalk/plugins/tools/defaulttools/tool_rectangle.png b/chalk/plugins/tools/defaulttools/tool_rectangle.png
new file mode 100644
index 00000000..4da56ecd
--- /dev/null
+++ b/chalk/plugins/tools/defaulttools/tool_rectangle.png
Binary files differ
diff --git a/chalk/plugins/tools/defaulttools/tool_rectangle_cursor.png b/chalk/plugins/tools/defaulttools/tool_rectangle_cursor.png
new file mode 100644
index 00000000..0dba614b
--- /dev/null
+++ b/chalk/plugins/tools/defaulttools/tool_rectangle_cursor.png
Binary files differ
diff --git a/chalk/plugins/tools/defaulttools/tool_text.png b/chalk/plugins/tools/defaulttools/tool_text.png
new file mode 100644
index 00000000..c1683fc0
--- /dev/null
+++ b/chalk/plugins/tools/defaulttools/tool_text.png
Binary files differ
diff --git a/chalk/plugins/tools/defaulttools/tool_text_cursor.png b/chalk/plugins/tools/defaulttools/tool_text_cursor.png
new file mode 100644
index 00000000..e241beaf
--- /dev/null
+++ b/chalk/plugins/tools/defaulttools/tool_text_cursor.png
Binary files differ
diff --git a/chalk/plugins/tools/defaulttools/tool_zoom.png b/chalk/plugins/tools/defaulttools/tool_zoom.png
new file mode 100644
index 00000000..10689553
--- /dev/null
+++ b/chalk/plugins/tools/defaulttools/tool_zoom.png
Binary files differ
diff --git a/chalk/plugins/tools/defaulttools/tool_zoom_minus_cursor.png b/chalk/plugins/tools/defaulttools/tool_zoom_minus_cursor.png
new file mode 100644
index 00000000..7089eaf3
--- /dev/null
+++ b/chalk/plugins/tools/defaulttools/tool_zoom_minus_cursor.png
Binary files differ
diff --git a/chalk/plugins/tools/defaulttools/tool_zoom_plus_cursor.png b/chalk/plugins/tools/defaulttools/tool_zoom_plus_cursor.png
new file mode 100644
index 00000000..52c59b45
--- /dev/null
+++ b/chalk/plugins/tools/defaulttools/tool_zoom_plus_cursor.png
Binary files differ
diff --git a/chalk/plugins/tools/defaulttools/wdgcolorpicker.ui b/chalk/plugins/tools/defaulttools/wdgcolorpicker.ui
new file mode 100644
index 00000000..a2b9d7d3
--- /dev/null
+++ b/chalk/plugins/tools/defaulttools/wdgcolorpicker.ui
@@ -0,0 +1,167 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>ColorPickerOptionsWidget</class>
+<widget class="TQWidget">
+ <property name="name">
+ <cstring>ColorPickerOptionsWidget</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>263</width>
+ <height>307</height>
+ </rect>
+ </property>
+ <property name="caption">
+ <string>Color Picker</string>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <widget class="TQComboBox">
+ <item>
+ <property name="text">
+ <string>Sample All Visible Layers</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Current Layer</string>
+ </property>
+ </item>
+ <property name="name">
+ <cstring>cmbSources</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>0</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="tqminimumSize">
+ <size>
+ <width>200</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="tqmaximumSize">
+ <size>
+ <width>200</width>
+ <height>32767</height>
+ </size>
+ </property>
+ </widget>
+ <widget class="TQCheckBox">
+ <property name="name">
+ <cstring>cbUpdateCurrentColour</cstring>
+ </property>
+ <property name="text">
+ <string>Update current color</string>
+ </property>
+ </widget>
+ <widget class="TQLayoutWidget">
+ <property name="name">
+ <cstring>tqlayout2</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="TQCheckBox">
+ <property name="name">
+ <cstring>cbPalette</cstring>
+ </property>
+ <property name="text">
+ <string>Add to palette:</string>
+ </property>
+ </widget>
+ <widget class="TQComboBox">
+ <property name="name">
+ <cstring>cmbPalette</cstring>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget class="TQCheckBox">
+ <property name="name">
+ <cstring>cbNormaliseValues</cstring>
+ </property>
+ <property name="text">
+ <string>Show colors as percentages</string>
+ </property>
+ </widget>
+ <widget class="TQLayoutWidget">
+ <property name="name">
+ <cstring>tqlayout1</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="TQLabel">
+ <property name="name">
+ <cstring>textLabel1</cstring>
+ </property>
+ <property name="text">
+ <string>Sample radius:</string>
+ </property>
+ </widget>
+ <widget class="TQSpinBox">
+ <property name="name">
+ <cstring>radius</cstring>
+ </property>
+ <property name="maxValue">
+ <number>9</number>
+ </property>
+ <property name="minValue">
+ <number>1</number>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget class="TQListView">
+ <column>
+ <property name="text">
+ <string>Channel</string>
+ </property>
+ <property name="clickable">
+ <bool>false</bool>
+ </property>
+ <property name="resizable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Value</string>
+ </property>
+ <property name="clickable">
+ <bool>false</bool>
+ </property>
+ <property name="resizable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <property name="name">
+ <cstring>listViewChannels</cstring>
+ </property>
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="selectionMode">
+ <enum>NoSelection</enum>
+ </property>
+ </widget>
+ </vbox>
+</widget>
+<tqlayoutdefaults spacing="6" margin="11"/>
+</UI>
diff --git a/chalk/plugins/tools/selectiontools/Makefile.am b/chalk/plugins/tools/selectiontools/Makefile.am
new file mode 100644
index 00000000..dc0ad90e
--- /dev/null
+++ b/chalk/plugins/tools/selectiontools/Makefile.am
@@ -0,0 +1,56 @@
+kde_services_DATA = chalkselectiontools.desktop
+
+# all_includes must remain last!
+INCLUDES = -I$(srcdir)/../../../sdk \
+ -I$(srcdir)/../../../core \
+ -I$(srcdir)/../../../chalkcolor/ \
+ -I$(srcdir)/../../../ui \
+ -I$/../../../ui \
+ $(KOFFICE_INCLUDES) \
+ $(all_includes)
+
+chalkselectiontools_la_SOURCES = kis_tool_move_selection.cc \
+ kis_tool_select_brush.cc kis_tool_select_contiguous.cc kis_tool_select_elliptical.cc \
+ kis_tool_select_eraser.cc kis_tool_select_outline.cc kis_tool_select_polygonal.cc \
+ kis_tool_select_rectangular.cc selection_tools.cc
+
+# Install this plugin in the KDE modules directory
+kde_module_LTLIBRARIES = chalkselectiontools.la
+
+noinst_HEADERS = \
+ selection_tools.h \
+ kis_tool_select_outline.h \
+ kis_tool_select_polygonal.h \
+ kis_tool_select_rectangular.h \
+ kis_tool_select_brush.h \
+ kis_tool_select_eraser.h \
+ kis_tool_select_contiguous.h \
+ kis_tool_select_elliptical.h
+
+
+chalkselectiontools_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) $(LIB_QT) -lkdecore -lkdeui -lkjs -lkdefx -lkio -lkparts -L../../../../chalk/chalkcolor/.libs -lchalkcolor -L../../../../chalk/core/.libs -lchalkimage \
+ -L../../../../chalk/ui/.libs -lchalkui
+chalkselectiontools_la_LIBADD = ../../../libchalkcommon.la
+
+chalkselectiontools_la_METASOURCES = AUTO
+
+KDE_OPTIONS = nofinal
+
+chalkpics_DATA = \
+ tool_rect_selection.png \
+ tool_eraser_selection.png \
+ tool_brush_selection.png \
+ tool_contiguous_selection.png \
+ tool_elliptical_selection.png \
+ tool_outline_selection.png \
+ tool_polygonal_selection.png \
+ tool_rectangular_selection_cursor.png \
+ tool_eraser_selection_cursor.png \
+ tool_brush_selection_cursor.png \
+ tool_contiguous_selection_cursor.png \
+ tool_elliptical_selection_cursor.png \
+ tool_outline_selection_cursor.png \
+ tool_polygonal_selection_cursor.png
+
+chalkpicsdir = $(kde_datadir)/chalk/pics
+
diff --git a/chalk/plugins/tools/selectiontools/chalkselectiontools.desktop b/chalk/plugins/tools/selectiontools/chalkselectiontools.desktop
new file mode 100644
index 00000000..72a7f217
--- /dev/null
+++ b/chalk/plugins/tools/selectiontools/chalkselectiontools.desktop
@@ -0,0 +1,52 @@
+[Desktop Entry]
+Name=Selection Tools
+Name[bg]=Инструмент за маркиране
+Name[br]=Ostilhoù choazh
+Name[ca]=Eines de selecció
+Name[cy]=Offer Detholi
+Name[da]=Markeringsværktøj
+Name[de]=Auswahlwerkzeuge
+Name[el]=Εργαλεία επιλογής
+Name[eo]=Elektado-iloj
+Name[es]=Herramientas de selección
+Name[et]=Valikutööriistad
+Name[eu]=Hautapen-tresnak
+Name[fa]=ابزارهای گزینش
+Name[fi]=Valintatyökalut
+Name[fr]=Outils de sélection
+Name[fy]=Seleksje-ark
+Name[ga]=Uirlisí Roghnúcháin
+Name[gl]=Ferramentas de Selección
+Name[he]=כלי בחירה
+Name[hu]=Kiválasztó eszközök
+Name[is]=Valtól
+Name[it]=Strumenti di selezione
+Name[ja]=選択ツール
+Name[km]=ឧបករណ៍​ជ្រើស​
+Name[lt]=Pažymėjimo įrankiai
+Name[lv]=Izvēles rīki
+Name[ms]=Alat Pemilihan
+Name[nb]=Velgeverktøy
+Name[nds]=Utwahlwarktüüch
+Name[ne]=चयन उपकरण
+Name[nl]=Selectiegereedschappen
+Name[nn]=Veljeverktøy
+Name[pl]=Narzędzia wyboru
+Name[pt]=Ferramentas de Selecção
+Name[pt_BR]=Ferramentas de Seleção
+Name[ru]=Инструменты выделения
+Name[se]=Válljenreaiddut
+Name[sk]=Štetec výberu
+Name[sl]=Orodja za izbiro
+Name[sr]=Алати за избор
+Name[sr@Latn]=Alati za izbor
+Name[sv]=Markeringsverktyg
+Name[uk]=Засоби виділення
+Name[uz]=Tanlash vositalari
+Name[uz@cyrillic]=Танлаш воситалари
+Name[zh_CN]=选择工具
+Name[zh_TW]=選取區工具
+ServiceTypes=Chalk/Tool
+Type=Service
+X-KDE-Library=chalkselectiontools
+X-Chalk-Version=2
diff --git a/chalk/plugins/tools/selectiontools/kis_tool_move_selection.cc b/chalk/plugins/tools/selectiontools/kis_tool_move_selection.cc
new file mode 100644
index 00000000..b7b123d7
--- /dev/null
+++ b/chalk/plugins/tools/selectiontools/kis_tool_move_selection.cc
@@ -0,0 +1,223 @@
+/*
+ * Copyright (c) 2006 Cyrille Berger <cberger@cberger.net>
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "kis_tool_move_selection.h"
+
+#include <stdlib.h>
+#include <tqpoint.h>
+#include <kaction.h>
+#include <kcommand.h>
+#include <klocale.h>
+#include <tqcolor.h>
+#include "kis_canvas_subject.h"
+#include "kis_cursor.h"
+#include "kis_image.h"
+#include "kis_layer.h"
+#include "kis_paint_layer.h"
+#include "kis_paint_device.h"
+#include "kis_button_press_event.h"
+#include "kis_button_release_event.h"
+#include "kis_move_event.h"
+#include "kis_selection.h"
+#include "kis_selection_manager.h"
+#include "kis_undo_adapter.h"
+
+class KisSelectionOffsetCommand : public KNamedCommand {
+ typedef KNamedCommand super;
+
+public:
+ KisSelectionOffsetCommand(KisSelectionSP layer, const TQPoint& oldpos, const TQPoint& newpos);
+ virtual ~KisSelectionOffsetCommand();
+
+ virtual void execute();
+ virtual void unexecute();
+
+private:
+ void moveTo(const TQPoint& pos);
+
+private:
+ KisSelectionSP m_layer;
+ TQPoint m_oldPos;
+ TQPoint m_newPos;
+};
+
+ KisSelectionOffsetCommand::KisSelectionOffsetCommand(KisSelectionSP layer, const TQPoint& oldpos, const TQPoint& newpos) :
+ super(i18n("Move Layer"))
+ {
+ m_layer = layer;
+ m_oldPos = oldpos;
+ m_newPos = newpos;
+
+ }
+
+ KisSelectionOffsetCommand::~KisSelectionOffsetCommand()
+ {
+ }
+
+ void KisSelectionOffsetCommand::execute()
+ {
+ moveTo(m_newPos);
+ }
+
+ void KisSelectionOffsetCommand::unexecute()
+ {
+ moveTo(m_oldPos);
+ }
+
+ void KisSelectionOffsetCommand::moveTo(const TQPoint& pos)
+ {
+ if (m_layer->undoAdapter()) {
+ m_layer->undoAdapter()->setUndo(false);
+ }
+
+ m_layer->setX(pos.x());
+ m_layer->setY(pos.y());
+
+ m_layer->tqparentPaintDevice()->setDirty();
+
+ if (m_layer->undoAdapter()) {
+ m_layer->undoAdapter()->setUndo(true);
+ }
+ }
+
+
+KisToolMoveSelection::KisToolMoveSelection()
+ : super(i18n("Move Selection Tool"))
+{
+ setName("tool_move_selection");
+ m_subject = 0;
+ setCursor(KisCursor::moveCursor());
+}
+
+KisToolMoveSelection::~KisToolMoveSelection()
+{
+}
+
+void KisToolMoveSelection::update(KisCanvasSubject *subject)
+{
+ m_subject = subject;
+ super::update(subject);
+ m_dragging = false;
+}
+
+void KisToolMoveSelection::buttonPress(KisButtonPressEvent *e)
+{
+ m_dragging = false;
+ if (m_subject && e->button() == Qt::LeftButton) {
+ TQPoint pos = e->pos().floorTQPoint();
+ KisImageSP img = m_subject->currentImg();
+ KisPaintLayerSP lay;
+
+ if (!img || !(lay = dynamic_cast<KisPaintLayer*>( img->activeLayer().data() )))
+ return;
+
+ m_dragStart = pos;
+
+ if ( !lay->visible() || !lay->paintDevice()->hasSelection())
+ return;
+ KisSelectionSP sel = lay->paintDevice()->selection();
+
+ m_dragging = true;
+ m_dragStart.setX(pos.x());
+ m_dragStart.setY(pos.y());
+ m_layerStart.setX(sel->getX());
+ m_layerStart.setY(sel->getY());
+ m_layerPosition = m_layerStart;
+
+ }
+}
+
+void KisToolMoveSelection::move(KisMoveEvent *e)
+{
+ if (m_subject && m_dragging) {
+ TQPoint pos = e->pos().floorTQPoint();
+ if((e->state() & TQt::AltButton) || (e->state() & TQt::ControlButton)) {
+ if(fabs(pos.x() - m_dragStart.x()) > fabs(pos.y() - m_dragStart.y()))
+ pos.setY(m_dragStart.y());
+ else
+ pos.setX(m_dragStart.x());
+ }
+
+ KisImageSP img = m_subject->currentImg();
+ KisPaintLayerSP lay = dynamic_cast<KisPaintLayer*>(m_subject->currentImg()->activeLayer().data());
+ if(!lay) return;
+ KisSelectionSP sel = lay->paintDevice()->selection();
+
+ TQRect rc;
+
+ pos -= m_dragStart; // convert to delta
+ rc = sel->selectedRect();
+ sel->setX(sel->getX() + pos.x());
+ sel->setY(sel->getY() + pos.y());
+ rc = rc.unite(sel->selectedRect());
+
+ m_layerPosition = TQPoint(sel->getX(), sel->getY());
+ m_dragStart = e->pos().floorTQPoint();
+
+ lay->paintDevice()->setDirty(rc);
+ }
+
+}
+
+void KisToolMoveSelection::buttonRelease(KisButtonReleaseEvent *e)
+{
+ if (m_subject && e->button() == Qt::LeftButton && m_dragging) {
+ m_dragging = false;
+ KisImageSP img = m_subject->currentImg();
+ if(!img) return;
+ KisPaintLayerSP lay = dynamic_cast<KisPaintLayer*>(img->activeLayer().data());
+
+ if (lay->paintDevice()->hasSelection()) {
+ KisSelectionSP dev = lay->paintDevice()->selection();
+ m_dragging = false;
+
+ if (img->undo()) {
+ KCommand *cmd = new KisSelectionOffsetCommand( dev, m_layerStart, m_layerPosition);
+ Q_CHECK_PTR(cmd);
+ KisUndoAdapter *adapter = img->undoAdapter();
+ if (adapter) {
+ adapter->addCommand(cmd);
+ } else {
+ delete cmd;
+ }
+ }
+ img->setModified();
+ lay->setDirty();
+ }
+ }
+}
+
+void KisToolMoveSelection::setup(KActionCollection *collection)
+{
+ m_action = static_cast<KRadioAction *>(collection->action(name()));
+
+ if (m_action == 0) {
+ m_action = new KRadioAction(i18n("&Move selection"),
+ "tool_move",
+ TQt::SHIFT+TQt::Key_V,
+ this,
+ TQT_SLOT(activate()),
+ collection,
+ name());
+ m_action->setToolTip(i18n("Move the selection"));
+ m_action->setExclusiveGroup("tools");
+ m_ownAction = true;
+ }
+}
+
+#include "kis_tool_move_selection.moc"
diff --git a/chalk/plugins/tools/selectiontools/kis_tool_move_selection.h b/chalk/plugins/tools/selectiontools/kis_tool_move_selection.h
new file mode 100644
index 00000000..60d73a9b
--- /dev/null
+++ b/chalk/plugins/tools/selectiontools/kis_tool_move_selection.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2006 Cyrille Berger <cberger@cberger.net>
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef KIS_TOOL_MOVE_H_
+#define KIS_TOOL_MOVE_H_
+
+#include "kis_tool_non_paint.h"
+#include "kis_tool_factory.h"
+
+// XXX: Moving is not nearly smooth enough!
+class KisToolMoveSelection : public KisToolNonPaint {
+
+ typedef KisToolNonPaint super;
+ Q_OBJECT
+ TQ_OBJECT
+
+public:
+ KisToolMoveSelection();
+ virtual ~KisToolMoveSelection();
+
+public:
+ virtual void update(KisCanvasSubject *subject);
+
+public:
+ virtual void setup(KActionCollection *collection);
+ virtual enumToolType toolType() { return TOOL_SELECT; }
+ virtual TQ_UINT32 priority() { return 10; }
+
+ virtual void buttonPress(KisButtonPressEvent *e);
+ virtual void move(KisMoveEvent *e);
+ virtual void buttonRelease(KisButtonReleaseEvent *e);
+
+private:
+ KisCanvasSubject *m_subject;
+ TQPoint m_dragStart;
+ TQPoint m_layerStart;
+ TQPoint m_layerPosition;
+ bool m_dragging;
+};
+
+
+class KisToolMoveSelectionFactory : public KisToolFactory {
+ typedef KisToolFactory super;
+public:
+ KisToolMoveSelectionFactory() : super() {};
+ virtual ~KisToolMoveSelectionFactory(){};
+
+ virtual KisTool * createTool(KActionCollection * ac) {
+ KisTool * t = new KisToolMoveSelection();
+ Q_CHECK_PTR(t);
+ t->setup(ac);
+ return t;
+ }
+ virtual KisID id() { return KisID("moveselection", i18n("Move Selection Tool")); }
+};
+
+
+
+#endif // KIS_TOOL_MOVE_H_
+
diff --git a/chalk/plugins/tools/selectiontools/kis_tool_select_brush.cc b/chalk/plugins/tools/selectiontools/kis_tool_select_brush.cc
new file mode 100644
index 00000000..ff5242d6
--- /dev/null
+++ b/chalk/plugins/tools/selectiontools/kis_tool_select_brush.cc
@@ -0,0 +1,168 @@
+/*
+ * kis_tool_select_brush.cc - part of Chalk
+ *
+ * Copyright (c) 2004 Boudewijn Rempt <boud@valdyas.org>
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <tqevent.h>
+#include <tqlabel.h>
+#include <tqlayout.h>
+#include <tqwidget.h>
+#include <tqrect.h>
+
+#include <kdebug.h>
+#include <kaction.h>
+#include <kcommand.h>
+#include <klocale.h>
+
+#include "kis_brush.h"
+#include "kis_button_press_event.h"
+#include "kis_button_release_event.h"
+#include "kis_cmb_composite.h"
+#include "kis_cursor.h"
+#include "kis_doc.h"
+#include "kis_paintop.h"
+#include "kis_paintop_registry.h"
+#include "kis_move_event.h"
+#include "kis_painter.h"
+#include "kis_selection.h"
+#include "kis_tool_select_brush.h"
+#include "kis_types.h"
+#include "kis_layer.h"
+#include "kis_view.h"
+#include "kis_selection_options.h"
+#include "kis_selected_transaction.h"
+
+KisToolSelectBrush::KisToolSelectBrush()
+ : super(i18n("SelectBrush"))
+{
+ setName("tool_select_brush");
+ m_optWidget = 0;
+ setCursor(KisCursor::load("tool_brush_selection_cursor.png", 5, 5));
+ m_paintOnSelection = true;
+}
+
+KisToolSelectBrush::~KisToolSelectBrush()
+{
+}
+
+void KisToolSelectBrush::activate()
+{
+ super::activate();
+
+ if (!m_optWidget)
+ return;
+
+ m_optWidget->slotActivated();
+}
+
+void KisToolSelectBrush::initPaint(KisEvent* /*e*/)
+{
+ if (!m_currentImage || !m_currentImage->activeDevice()) return;
+
+ m_mode = PAINT;
+ m_dragDist = 0;
+
+ // Create painter
+ KisPaintDeviceSP dev = m_currentImage->activeDevice();
+ if (m_painter)
+ delete m_painter;
+ bool hasSelection = dev->hasSelection();
+ if (m_currentImage->undo()) m_transaction = new KisSelectedTransaction(i18n("Selection Brush"), dev);
+ if(! hasSelection)
+ {
+ dev->selection()->clear();
+ dev->emitSelectionChanged();
+ }
+ KisSelectionSP selection = dev->selection();
+
+ m_target = selection;
+ m_painter = new KisPainter(selection.data());
+ Q_CHECK_PTR(m_painter);
+ m_painter->setPaintColor(KisColor(TQt::black, selection->colorSpace()));
+ m_painter->setBrush(m_subject->currentBrush());
+ m_painter->setOpacity(OPACITY_OPAQUE);//m_subject->fgColor().colorSpace()->intensity8(m_subject->fgColor().data()));
+ m_painter->setCompositeOp(COMPOSITE_OVER);
+ KisPaintOp * op = KisPaintOpRegistry::instance()->paintOp("paintbrush", 0, painter());
+ painter()->setPaintOp(op); // And now the painter owns the op and will destroy it.
+
+ // Set the cursor -- ideally. this should be a tqmask created from the brush,
+ // now that X11 can handle colored cursors.
+#if 0
+ // Setting cursors has no effect until the tool is selected again; this
+ // should be fixed.
+ setCursor(KisCursor::brushCursor());
+#endif
+}
+
+void KisToolSelectBrush::endPaint()
+{
+ m_mode = HOVER;
+ if (m_currentImage && m_currentImage->activeLayer()) {
+ if (m_currentImage->undo() && m_painter) {
+ // If painting in mouse release, make sure painter
+ // is destructed or end()ed
+ m_currentImage->undoAdapter()->addCommand(m_transaction);
+ }
+ delete m_painter;
+ m_painter = 0;
+ if (m_currentImage->activeDevice())
+ m_currentImage->activeDevice()->emitSelectionChanged();
+ notifyModified();
+ }
+}
+
+
+void KisToolSelectBrush::setup(KActionCollection *collection)
+{
+ m_action = static_cast<KRadioAction *>(collection->action(name()));
+
+ if (m_action == 0) {
+ m_action = new KRadioAction(i18n("&Selection Brush"),
+ "tool_brush_selection", "Ctrl+Shift+B", this,
+ TQT_SLOT(activate()), collection,
+ name());
+ Q_CHECK_PTR(m_action);
+ m_action->setToolTip(i18n("Paint a selection"));
+ m_action->setExclusiveGroup("tools");
+ m_ownAction = true;
+ }
+}
+
+TQWidget* KisToolSelectBrush::createOptionWidget(TQWidget* tqparent)
+{
+ Q_UNUSED(tqparent);
+ // Commented out due to the fact that this doesn't actually work if you change the action
+#if 0
+ m_optWidget = new KisSelectionOptions(tqparent, m_subject);
+ Q_CHECK_PTR(m_optWidget);
+ m_optWidget->setCaption(i18n("Selection Brush"));
+
+ TQVBoxLayout * l = dynamic_cast<TQVBoxLayout*>(m_optWidget->tqlayout());
+ l->addItem(new TQSpacerItem(1, 1, TQSizePolicy::Fixed, TQSizePolicy::Expanding));
+
+ return m_optWidget;
+#endif
+ return 0;
+}
+
+TQWidget* KisToolSelectBrush::optionWidget()
+{
+ return m_optWidget;
+}
+
+#include "kis_tool_select_brush.moc"
diff --git a/chalk/plugins/tools/selectiontools/kis_tool_select_brush.h b/chalk/plugins/tools/selectiontools/kis_tool_select_brush.h
new file mode 100644
index 00000000..374050f6
--- /dev/null
+++ b/chalk/plugins/tools/selectiontools/kis_tool_select_brush.h
@@ -0,0 +1,83 @@
+/*
+ * kis_tool_select_brush.h - part of Chalk
+ *
+ * Copyright (c) 2003-2004 Boudewijn Rempt <boud@valdyas.org>
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef KIS_TOOL_SELECT_BRUSH_H_
+#define KIS_TOOL_SELECT_BRUSH_H_
+
+#include <kis_tool.h>
+#include <kis_tool_freehand.h>
+#include <kis_tool_factory.h>
+
+class TQWidget;
+class KisPoint;
+class KisSelectedTransaction;
+class KisSelectionOptions;
+
+/**
+ * The selection brush creates a selection by painting with the current
+ * brush tqshape. Not sure what kind of an icon could represent this...
+ * Depends a bit on how we're going to visualize selections.
+ */
+class KisToolSelectBrush : public KisToolFreehand {
+ Q_OBJECT
+ TQ_OBJECT
+ typedef KisToolFreehand super;
+
+public:
+ KisToolSelectBrush();
+ virtual ~KisToolSelectBrush();
+
+ virtual void setup(KActionCollection *collection);
+ virtual TQ_UINT32 priority() { return 1; }
+ virtual enumToolType toolType() { return TOOL_SELECT; }
+ virtual TQWidget* createOptionWidget(TQWidget* tqparent);
+ virtual TQWidget* optionWidget();
+
+public slots:
+ virtual void activate();
+
+protected:
+
+ virtual void initPaint(KisEvent *e);
+ virtual void endPaint();
+
+private:
+ KisSelectionOptions * m_optWidget;
+ KisSelectedTransaction *m_transaction;
+};
+
+class KisToolSelectBrushFactory : public KisToolFactory {
+ typedef KisToolFactory super;
+public:
+ KisToolSelectBrushFactory() : super() {};
+ virtual ~KisToolSelectBrushFactory(){};
+
+ virtual KisTool * createTool(KActionCollection * ac) {
+ KisTool * t = new KisToolSelectBrush();
+ Q_CHECK_PTR(t);
+ t->setup(ac);
+ return t;
+ }
+ virtual KisID id() { return KisID("brushselect", i18n("Brush Select Tool")); }
+};
+
+
+#endif // KIS_TOOL_SELECT_BRUSH_H_
+
diff --git a/chalk/plugins/tools/selectiontools/kis_tool_select_contiguous.cc b/chalk/plugins/tools/selectiontools/kis_tool_select_contiguous.cc
new file mode 100644
index 00000000..c4c908fc
--- /dev/null
+++ b/chalk/plugins/tools/selectiontools/kis_tool_select_contiguous.cc
@@ -0,0 +1,234 @@
+/*
+ * kis_tool_select_contiguous - part of Krayon^WChalk
+ *
+ * Copyright (c) 1999 Michael Koch <koch@kde.org>
+ * Copyright (c) 2002 Patrick Julien <freak@codepimps.org>
+ * Copyright (c) 2004 Boudewijn Rempt <boud@valdyas.org>
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <tqpainter.h>
+#include <tqlayout.h>
+#include <tqlabel.h>
+#include <tqapplication.h>
+#include <tqcheckbox.h>
+
+#include <kaction.h>
+#include <kdebug.h>
+#include <klocale.h>
+#include <knuminput.h>
+#include <kcolorbutton.h>
+
+#include <kis_cursor.h>
+#include <kis_selection_manager.h>
+#include <kis_canvas_subject.h>
+#include <kis_image.h>
+#include <kis_layer.h>
+#include <kis_paint_device.h>
+#include <kis_button_press_event.h>
+#include <kis_canvas_subject.h>
+#include <kis_selection_options.h>
+#include <kis_selection.h>
+#include <kis_paint_device.h>
+#include <kis_iterators_pixel.h>
+#include <kis_selection_options.h>
+#include <kis_canvas_observer.h>
+#include <kis_fill_painter.h>
+#include <kis_undo_adapter.h>
+#include <kis_selected_transaction.h>
+
+#include "kis_tool_select_contiguous.h"
+
+KisToolSelectContiguous::KisToolSelectContiguous() : super(i18n("Contiguous Select"))
+{
+ setName("tool_select_contiguous");
+ m_subject = 0;
+ m_optWidget = 0;
+ m_fuzziness = 20;
+ m_sampleMerged = false;
+ m_selectAction = SELECTION_ADD;
+
+ setCursor(KisCursor::load("tool_contiguous_selection_cursor.png", 6, 6));
+}
+
+KisToolSelectContiguous::~KisToolSelectContiguous()
+{
+}
+
+void KisToolSelectContiguous::activate()
+{
+ super::activate();
+
+ if (!m_optWidget)
+ return;
+
+ m_optWidget->slotActivated();
+}
+
+void KisToolSelectContiguous::buttonPress(KisButtonPressEvent * e)
+{
+ if (m_subject) {
+
+ KisImageSP img;
+ KisPaintDeviceSP dev;
+ TQPoint pos;
+
+ if (e->button() != Qt::LeftButton && e->button() != Qt::RightButton)
+ return;
+
+ if (!(img = m_subject->currentImg()))
+ return;
+
+ dev = img->activeDevice();
+
+ if (!dev || !img->activeLayer()->visible())
+ return;
+
+ TQApplication::setOverrideCursor(KisCursor::waitCursor());
+
+ pos = TQPoint(e->pos().floorX(), e->pos().floorY());
+
+ KisFillPainter fillpainter(dev);
+ fillpainter.setFillThreshold(m_fuzziness);
+ fillpainter.setSampleMerged(m_sampleMerged);
+ KisSelectionSP selection = fillpainter.createFloodSelection(pos.x(), pos.y());
+ KisSelectedTransaction *t = 0;
+ if (img->undo()) t = new KisSelectedTransaction(i18n("Contiguous Area Selection"), dev);
+
+ if (!dev->hasSelection()) {
+ dev->selection()->clear();
+ if(m_selectAction==SELECTION_SUBTRACT)
+ selection->invert();
+ }
+
+ switch (m_selectAction) {
+ case SELECTION_SUBTRACT:
+ dev->subtractSelection(selection);
+ break;
+ case SELECTION_ADD:
+ default:
+ dev->addSelection(selection);
+ break;
+
+ }
+
+ dev->setDirty(selection->selectedRect()); // A bit too wide, but that's not that bad
+ dev->emitSelectionChanged();
+
+
+ if (img->undo())
+ img->undoAdapter()->addCommand(t);
+
+ TQApplication::restoreOverrideCursor();
+ }
+
+}
+
+void KisToolSelectContiguous::setup(KActionCollection *collection)
+{
+ m_action = static_cast<KRadioAction *>(collection->action(name()));
+
+ if (m_action == 0) {
+ m_action = new KRadioAction(i18n("&Contiguous Area Selection"),
+ "tool_contiguous_selection" ,
+ 0,
+ this,
+ TQT_SLOT(activate()),
+ collection,
+ name());
+ Q_CHECK_PTR(m_action);
+ m_action->setToolTip(i18n("Select a contiguous area"));
+ m_action->setExclusiveGroup("tools");
+ m_ownAction = true;
+ }
+}
+
+void KisToolSelectContiguous::update(KisCanvasSubject *subject)
+{
+ super::update(subject);
+ m_subject = subject;
+}
+
+void KisToolSelectContiguous::slotSetFuzziness(int fuzziness)
+{
+ m_fuzziness = fuzziness;
+}
+
+
+void KisToolSelectContiguous::slotSetAction(int action)
+{
+ if (action >= SELECTION_ADD && action <= SELECTION_SUBTRACT)
+ m_selectAction =(enumSelectionMode)action;
+// XXX: Fix cursors when then are done.
+// switch(m_selectAction) {
+// case SELECTION_ADD:
+// m_subject->setCanvasCursor(KisCursor::pickerPlusCursor());
+// break;
+// case SELECTION_SUBTRACT:
+// m_subject->setCanvasCursor(KisCursor::pickerMinusCursor());
+// };
+}
+
+
+TQWidget* KisToolSelectContiguous::createOptionWidget(TQWidget* tqparent)
+{
+ m_optWidget = new KisSelectionOptions(tqparent, m_subject);
+ Q_CHECK_PTR(m_optWidget);
+ m_optWidget->setCaption(i18n("Contiguous Area Selection"));
+
+ TQVBoxLayout * l = dynamic_cast<TQVBoxLayout*>(m_optWidget->tqlayout());
+ l->setSpacing( 6 );
+
+ connect (m_optWidget, TQT_SIGNAL(actionChanged(int)), this, TQT_SLOT(slotSetAction(int)));
+
+ TQHBoxLayout * hbox = new TQHBoxLayout(l);
+ Q_CHECK_PTR(hbox);
+
+ TQLabel * lbl = new TQLabel(i18n("Fuzziness: "), m_optWidget);
+ hbox->addWidget(lbl);
+
+ KIntNumInput * input = new KIntNumInput(m_optWidget, "fuzziness");
+ Q_CHECK_PTR(input);
+
+ input->setRange(0, 200, 10, true);
+ input->setValue(20);
+ hbox->addWidget(input);
+ connect(input, TQT_SIGNAL(valueChanged(int)), this, TQT_SLOT(slotSetFuzziness(int)));
+
+ TQCheckBox* samplemerged = new TQCheckBox(i18n("Sample merged"), m_optWidget);
+ l->addWidget( samplemerged );
+ samplemerged->setChecked(m_sampleMerged);
+ connect(samplemerged, TQT_SIGNAL(stateChanged(int)),
+ this, TQT_SLOT(slotSetSampleMerged(int)));
+
+ l->addItem(new TQSpacerItem(1, 1, TQSizePolicy::Fixed, TQSizePolicy::Expanding));
+
+ return m_optWidget;
+}
+
+TQWidget* KisToolSelectContiguous::optionWidget()
+{
+ return m_optWidget;
+}
+
+void KisToolSelectContiguous::slotSetSampleMerged(int state)
+{
+ if (state == TQButton::NoChange)
+ return;
+ m_sampleMerged = (state == TQButton::On);
+}
+
+#include "kis_tool_select_contiguous.moc"
diff --git a/chalk/plugins/tools/selectiontools/kis_tool_select_contiguous.h b/chalk/plugins/tools/selectiontools/kis_tool_select_contiguous.h
new file mode 100644
index 00000000..e4beb6b7
--- /dev/null
+++ b/chalk/plugins/tools/selectiontools/kis_tool_select_contiguous.h
@@ -0,0 +1,95 @@
+/*
+ * kis_tool_select_contiguous.h - part of KImageShop^WKrayon^Chalk
+ *
+ * Copyright (c) 1999 Michael Koch <koch@kde.org>
+ * Copyright (c) 2002 Patrick Julien <freak@codepimps.org>
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __KIS_TOOL_SELECT_CONTIGUOUS_H__
+#define __KIS_TOOL_SELECT_CONTIGUOUS_H__
+
+#include <kis_tool.h>
+#include <kis_tool_non_paint.h>
+#include <kis_tool_factory.h>
+#include <kis_selection.h>
+
+class KisCanvasSubject;
+class TQWidget;
+class TQVBoxLayout;
+class TQCheckBox;
+class KisSelectionOptions;
+
+/**
+ * The 'magic wand' selection tool -- in fact just
+ * a floodfill that only creates a selection.
+ */
+class KisToolSelectContiguous : public KisToolNonPaint {
+
+ typedef KisToolNonPaint super;
+ Q_OBJECT
+ TQ_OBJECT
+
+public:
+ KisToolSelectContiguous();
+ virtual ~KisToolSelectContiguous();
+
+public:
+ virtual void update(KisCanvasSubject *subject);
+
+ virtual void setup(KActionCollection *collection);
+ virtual TQ_UINT32 priority() { return 7; }
+ virtual enumToolType toolType() { return TOOL_SELECT; };
+
+ virtual TQWidget* createOptionWidget(TQWidget* tqparent);
+ virtual TQWidget* optionWidget();
+
+ virtual void buttonPress(KisButtonPressEvent *event);
+
+public slots:
+ virtual void slotSetFuzziness(int);
+ virtual void slotSetAction(int);
+ virtual void slotSetSampleMerged(int);
+ virtual void activate();
+
+
+private:
+ KisCanvasSubject *m_subject;
+ KisSelectionOptions * m_optWidget;
+
+ int m_fuzziness;
+ enumSelectionMode m_selectAction;
+ bool m_sampleMerged;
+};
+
+class KisToolSelectContiguousFactory : public KisToolFactory {
+ typedef KisToolFactory super;
+public:
+ KisToolSelectContiguousFactory() : super() {};
+ virtual ~KisToolSelectContiguousFactory(){};
+
+ virtual KisTool * createTool(KActionCollection * ac) {
+ KisTool * t = new KisToolSelectContiguous();
+ Q_CHECK_PTR(t);
+ t->setup(ac);
+ return t;
+ }
+ virtual KisID id() { return KisID("contiguousselect", i18n("Contiguous Select Tool")); }
+};
+
+
+#endif //__KIS_TOOL_SELECT_CONTIGUOUS_H__
+
diff --git a/chalk/plugins/tools/selectiontools/kis_tool_select_elliptical.cc b/chalk/plugins/tools/selectiontools/kis_tool_select_elliptical.cc
new file mode 100644
index 00000000..efdae2f3
--- /dev/null
+++ b/chalk/plugins/tools/selectiontools/kis_tool_select_elliptical.cc
@@ -0,0 +1,321 @@
+/*
+ * kis_tool_select_elliptical.cc -- part of Chalk
+ *
+ * Copyright (c) 2004 Boudewijn Rempt (boud@valdyas.org)
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <tqapplication.h>
+#include <tqpainter.h>
+#include <tqpen.h>
+#include <tqlayout.h>
+
+#include <kdebug.h>
+#include <kaction.h>
+#include <kcommand.h>
+#include <klocale.h>
+
+#include "kis_autobrush_resource.h"
+#include "kis_canvas_controller.h"
+#include "kis_canvas_subject.h"
+#include "kis_cursor.h"
+#include "kis_image.h"
+#include "kis_painter.h"
+#include "kis_tool_select_elliptical.h"
+#include "kis_layer.h"
+#include "kis_undo_adapter.h"
+#include "kis_button_press_event.h"
+#include "kis_button_release_event.h"
+#include "kis_move_event.h"
+#include "kis_selection.h"
+#include "kis_selection_options.h"
+#include "kis_selected_transaction.h"
+#include "kis_canvas.h"
+#include "kis_canvas_painter.h"
+
+KisToolSelectElliptical::KisToolSelectElliptical()
+ : super(i18n("Elliptical Select"))
+{
+ setName("tool_select_elliptical");
+ setCursor(KisCursor::load("tool_elliptical_selection_cursor.png", 6, 6));
+
+ m_subject = 0;
+ m_selecting = false;
+ m_centerPos = KisPoint(0, 0);
+ m_startPos = KisPoint(0, 0);
+ m_endPos = KisPoint(0, 0);
+ m_optWidget = 0;
+ m_selectAction = SELECTION_ADD;
+}
+
+KisToolSelectElliptical::~KisToolSelectElliptical()
+{
+}
+
+void KisToolSelectElliptical::activate()
+{
+ super::activate();
+
+ if (!m_optWidget)
+ return;
+
+ m_optWidget->slotActivated();
+}
+
+void KisToolSelectElliptical::update(KisCanvasSubject *subject)
+{
+ m_subject = subject;
+ super::update(m_subject);
+}
+
+void KisToolSelectElliptical::paint(KisCanvasPainter& gc)
+{
+ if (m_selecting)
+ paintOutline(gc, TQRect());
+}
+
+void KisToolSelectElliptical::paint(KisCanvasPainter& gc, const TQRect& rc)
+{
+ if (m_selecting)
+ paintOutline(gc, rc);
+}
+
+void KisToolSelectElliptical::clearSelection()
+{
+ if (m_subject) {
+ KisCanvasController *controller = m_subject->canvasController();
+ KisImageSP img = m_subject->currentImg();
+
+ Q_ASSERT(controller);
+
+// if (img && img->floatingSelection().data() != 0) {
+// img->unsetFloatingSelection();
+// controller->canvas()->update();
+// }
+
+ m_startPos = KisPoint(0, 0);
+ m_endPos = KisPoint(0, 0);
+ m_selecting = false;
+ }
+}
+
+void KisToolSelectElliptical::buttonPress(KisButtonPressEvent *e)
+{
+ if (m_subject) {
+ KisImageSP img = m_subject->currentImg();
+
+ if (img && img->activeDevice() && e->button() == Qt::LeftButton) {
+ clearSelection();
+ m_startPos = m_endPos = m_centerPos = e->pos();
+ m_selecting = true;
+ paintOutline();
+ }
+ }
+}
+
+void KisToolSelectElliptical::move(KisMoveEvent *e)
+{
+ if (m_subject && m_selecting) {
+ paintOutline();
+ // move (alt) or resize ellipse
+ if (e->state() & TQt::AltButton) {
+ KisPoint trans = e->pos() - m_endPos;
+ m_startPos += trans;
+ m_endPos += trans;
+ } else {
+ KisPoint diag = e->pos() - (e->state() & TQt::ControlButton
+ ? m_centerPos : m_startPos);
+ // circle?
+ if (e->state() & TQt::ShiftButton) {
+ double size = TQMAX(fabs(diag.x()), fabs(diag.y()));
+ double w = diag.x() < 0 ? -size : size;
+ double h = diag.y() < 0 ? -size : size;
+ diag = KisPoint(w, h);
+ }
+
+ // resize around center point?
+ if (e->state() & TQt::ControlButton) {
+ m_startPos = m_centerPos - diag;
+ m_endPos = m_centerPos + diag;
+ } else {
+ m_endPos = m_startPos + diag;
+ }
+ }
+ paintOutline();
+ m_centerPos = KisPoint((m_startPos.x() + m_endPos.x()) / 2,
+ (m_startPos.y() + m_endPos.y()) / 2);
+ }
+}
+
+void KisToolSelectElliptical::buttonRelease(KisButtonReleaseEvent *e)
+{
+ if (m_subject && m_selecting && e->button() == Qt::LeftButton) {
+
+ paintOutline();
+
+ if (m_startPos == m_endPos) {
+ clearSelection();
+ } else {
+ TQApplication::setOverrideCursor(KisCursor::waitCursor());
+ KisImageSP img = m_subject->currentImg();
+
+ if (!img)
+ return;
+
+ if (m_endPos.y() < 0)
+ m_endPos.setY(0);
+
+ if (m_endPos.y() > img->height())
+ m_endPos.setY(img->height());
+
+ if (m_endPos.x() < 0)
+ m_endPos.setX(0);
+
+ if (m_endPos.x() > img->width())
+ m_endPos.setX(img->width());
+
+ if (img && img->activeDevice()) {
+ KisPaintDeviceSP dev = img->activeDevice();
+ KisSelectedTransaction *t = 0;
+ if (img->undo()) t = new KisSelectedTransaction(i18n("Elliptical Selection"), dev);
+
+ bool hasSelection = dev->hasSelection();
+ if(! hasSelection)
+ {
+ dev->selection()->clear();
+ if(m_selectAction==SELECTION_SUBTRACT)
+ dev->selection()->invert();
+ }
+ TQRect rc( m_startPos.floorTQPoint(), m_endPos.floorTQPoint());
+ rc = rc.normalize();
+
+ KisSelectionSP tmpSel = new KisSelection(dev);
+ KisAutobrushCircleShape tqshape(rc.width(),rc.height(), 1, 1);
+ TQ_UINT8 value;
+ for (int y = 0; y <= rc.height(); y++)
+ for (int x = 0; x <= rc.width(); x++)
+ {
+ value = MAX_SELECTED - tqshape.valueAt(x,y);
+ tmpSel->setSelected( x+rc.x(), y+rc.y(), value);
+ }
+ switch(m_selectAction)
+ {
+ case SELECTION_ADD:
+ dev->addSelection(tmpSel);
+ break;
+ case SELECTION_SUBTRACT:
+ dev->subtractSelection(tmpSel);
+ break;
+ }
+
+ if(hasSelection) {
+ dev->setDirty(rc);
+ dev->emitSelectionChanged(rc);
+ } else {
+ dev->setDirty();
+ dev->emitSelectionChanged();
+ }
+
+ if (img->undo())
+ img->undoAdapter()->addCommand(t);
+
+ TQApplication::restoreOverrideCursor();
+ }
+ }
+ m_selecting = false;
+ }
+}
+
+void KisToolSelectElliptical::paintOutline()
+{
+ if (m_subject) {
+ KisCanvasController *controller = m_subject->canvasController();
+ KisCanvas *canvas = controller->kiscanvas();
+ KisCanvasPainter gc(canvas);
+ TQRect rc;
+
+ paintOutline(gc, rc);
+ }
+}
+
+void KisToolSelectElliptical::paintOutline(KisCanvasPainter& gc, const TQRect&)
+{
+ if (m_subject) {
+ KisCanvasController *controller = m_subject->canvasController();
+ RasterOp op = gc.rasterOp();
+ TQPen old = gc.pen();
+ TQPen pen(TQt::DotLine);
+ TQPoint start;
+ TQPoint end;
+
+ Q_ASSERT(controller);
+ start = controller->windowToView(m_startPos).floorTQPoint();
+ end = controller->windowToView(m_endPos).floorTQPoint();
+
+ gc.setRasterOp(TQt::NotROP);
+ gc.setPen(pen);
+ gc.drawEllipse(TQRect(start, end));
+ gc.setRasterOp(op);
+ gc.setPen(old);
+ }
+}
+
+void KisToolSelectElliptical::slotSetAction(int action) {
+ if (action >= SELECTION_ADD && action <= SELECTION_SUBTRACT)
+ m_selectAction =(enumSelectionMode)action;
+}
+
+void KisToolSelectElliptical::setup(KActionCollection *collection)
+{
+ m_action = static_cast<KRadioAction *>(collection->action(name()));
+
+ if (m_action == 0) {
+ m_action = new KRadioAction(i18n("&Elliptical Selection"),
+ "tool_elliptical_selection" ,
+ TQt::Key_J,
+ this,
+ TQT_SLOT(activate()),
+ collection,
+ name());
+ Q_CHECK_PTR(m_action);
+ m_action->setToolTip(i18n("Select an elliptical area"));
+ m_action->setExclusiveGroup("tools");
+ m_ownAction = true;
+ }
+}
+
+TQWidget* KisToolSelectElliptical::createOptionWidget(TQWidget* tqparent)
+{
+ m_optWidget = new KisSelectionOptions(tqparent, m_subject);
+ Q_CHECK_PTR(m_optWidget);
+ m_optWidget->setCaption(i18n("Elliptical Selection"));
+
+ connect (m_optWidget, TQT_SIGNAL(actionChanged(int)), this, TQT_SLOT(slotSetAction(int)));
+
+ TQVBoxLayout * l = dynamic_cast<TQVBoxLayout*>(m_optWidget->tqlayout());
+ l->addItem(new TQSpacerItem(1, 1, TQSizePolicy::Fixed, TQSizePolicy::Expanding));
+
+ return m_optWidget;
+}
+
+TQWidget* KisToolSelectElliptical::optionWidget()
+{
+ return m_optWidget;
+}
+
+
+
+#include "kis_tool_select_elliptical.moc"
diff --git a/chalk/plugins/tools/selectiontools/kis_tool_select_elliptical.h b/chalk/plugins/tools/selectiontools/kis_tool_select_elliptical.h
new file mode 100644
index 00000000..f0d1a039
--- /dev/null
+++ b/chalk/plugins/tools/selectiontools/kis_tool_select_elliptical.h
@@ -0,0 +1,99 @@
+/*
+ * kis_tool_select_elliptical.h - part of Krayon^WChalk
+ *
+ * Copyright (c) 2000 John Califf <jcaliff@compuzone.net>
+ * Copyright (c) 2002 Patrick Julien <freak@codepimps.org>
+ * Copyright (c) 2004 Boudewijn Rempt <boud@valdyas.org>
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __KIS_TOOL_SELECT_ELLIPTICAL_H__
+#define __KIS_TOOL_SELECT_ELLIPTICAL_H__
+
+#include <tqpoint.h>
+
+#include "kis_point.h"
+#include "kis_selection.h"
+#include "kis_tool_factory.h"
+#include "kis_tool_non_paint.h"
+
+class KisSelectionOptions;
+
+class KisToolSelectElliptical : public KisToolNonPaint {
+
+ typedef KisToolNonPaint super;
+ Q_OBJECT
+ TQ_OBJECT
+
+public:
+ KisToolSelectElliptical();
+ virtual ~KisToolSelectElliptical();
+
+ virtual void update(KisCanvasSubject *subject);
+
+ virtual void setup(KActionCollection *collection);
+ virtual TQ_UINT32 priority() { return 4; }
+ virtual TQWidget * createOptionWidget(TQWidget* tqparent);
+ virtual TQWidget* optionWidget();
+ virtual enumToolType toolType() { return TOOL_SELECT; }
+
+ virtual void paint(KisCanvasPainter& gc);
+ virtual void paint(KisCanvasPainter& gc, const TQRect& rc);
+ virtual void buttonPress(KisButtonPressEvent *e);
+ virtual void move(KisMoveEvent *e);
+ virtual void buttonRelease(KisButtonReleaseEvent *e);
+
+public slots:
+ virtual void slotSetAction(int);
+ virtual void activate();
+
+
+private:
+ void clearSelection();
+ void paintOutline();
+ void paintOutline(KisCanvasPainter& gc, const TQRect& rc);
+
+private:
+ KisCanvasSubject *m_subject;
+ KisPoint m_centerPos;
+ KisPoint m_startPos;
+ KisPoint m_endPos;
+ bool m_selecting;
+ KisSelectionOptions * m_optWidget;
+ enumSelectionMode m_selectAction;
+};
+
+class KisToolSelectEllipticalFactory : public KisToolFactory {
+ typedef KisToolFactory super;
+public:
+ KisToolSelectEllipticalFactory() : super() {};
+ virtual ~KisToolSelectEllipticalFactory(){};
+
+ virtual KisTool * createTool(KActionCollection * ac) {
+ KisTool * t = new KisToolSelectElliptical();
+ Q_CHECK_PTR(t);
+ t->setup(ac);
+ return t;
+ }
+ virtual KisID id() { return KisID("ellipticalselect", i18n("Elliptical Select Tool")); }
+};
+
+
+
+
+
+#endif //__KIS_TOOL_SELECT_ELLIPTICAL_H__
+
diff --git a/chalk/plugins/tools/selectiontools/kis_tool_select_eraser.cc b/chalk/plugins/tools/selectiontools/kis_tool_select_eraser.cc
new file mode 100644
index 00000000..58a7778c
--- /dev/null
+++ b/chalk/plugins/tools/selectiontools/kis_tool_select_eraser.cc
@@ -0,0 +1,156 @@
+/*
+ * kis_tool_select_brush.cc - part of Chalk
+ *
+ * Copyright (c) 2004 Boudewijn Rempt <boud@valdyas.org>
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <tqevent.h>
+#include <tqlabel.h>
+#include <tqlayout.h>
+#include <tqwidget.h>
+
+#include <kdebug.h>
+#include <kaction.h>
+#include <kcommand.h>
+#include <klocale.h>
+
+#include "kis_brush.h"
+#include "kis_layer.h"
+#include "kis_paintop.h"
+#include "kis_paintop_registry.h"
+#include "kis_button_press_event.h"
+#include "kis_button_release_event.h"
+#include "kis_cmb_composite.h"
+#include "kis_cursor.h"
+#include "kis_doc.h"
+#include "kis_move_event.h"
+#include "kis_painter.h"
+#include "kis_selection.h"
+#include "kis_tool_select_eraser.h"
+#include "kis_types.h"
+#include "kis_view.h"
+#include "kis_selection_options.h"
+
+KisToolSelectEraser::KisToolSelectEraser()
+ : super(i18n("SelectEraser"))
+{
+ setName("tool_select_eraser");
+ setCursor(KisCursor::load("tool_eraser_selection_cursor.png", 5, 5));
+ m_optWidget = 0;
+ m_paintOnSelection = true;
+}
+
+KisToolSelectEraser::~KisToolSelectEraser()
+{
+}
+
+void KisToolSelectEraser::activate()
+{
+ super::activate();
+
+ if (!m_optWidget)
+ return;
+
+ m_optWidget->slotActivated();
+}
+
+void KisToolSelectEraser::initPaint(KisEvent */*e*/)
+{
+ if (!m_currentImage || !m_currentImage->activeDevice()) return;
+
+ m_mode = PAINT;
+ m_dragDist = 0;
+
+ // Create painter
+ KisPaintDeviceSP dev = m_currentImage->activeDevice();
+
+ if (dev == 0) return;
+
+ if (m_painter)
+ delete m_painter;
+ if(! dev->hasSelection())
+ {
+ dev->selection()->clear();
+ dev->emitSelectionChanged();
+ }
+ KisSelectionSP selection = dev->selection();
+
+ m_target = selection;
+ m_painter = new KisPainter(selection.data());
+ Q_CHECK_PTR(m_painter);
+ m_painter->beginTransaction(i18n("Selection Eraser"));
+ m_painter->setPaintColor(KisColor(TQt::white, selection->colorSpace()));
+ m_painter->setBrush(m_subject->currentBrush());
+ m_painter->setOpacity(OPACITY_OPAQUE);
+ m_painter->setCompositeOp(COMPOSITE_ERASE);
+ KisPaintOp * op = KisPaintOpRegistry::instance()->paintOp("eraser", 0, painter());
+ painter()->setPaintOp(op); // And now the painter owns the op and will destroy it.
+
+ // Set the cursor -- ideally. this should be a tqmask created from the brush,
+ // now that X11 can handle colored cursors.
+#if 0
+ // Setting cursors has no effect until the tool is selected again; this
+ // should be fixed.
+ setCursor(KisCursor::eraserCursor());
+#endif
+}
+
+void KisToolSelectEraser::endPaint() {
+ super::endPaint();
+ if (m_currentImage && m_currentImage->activeDevice())
+ m_currentImage->activeDevice()->emitSelectionChanged();
+}
+void KisToolSelectEraser::setup(KActionCollection *collection)
+{
+ m_action = static_cast<KRadioAction *>(collection->action(name()));
+
+ if (m_action == 0) {
+ m_action = new KRadioAction(i18n("Selection &Eraser"),
+ "tool_eraser_selection", "Ctrl+Shift+E", this,
+ TQT_SLOT(activate()), collection,
+ name());
+ Q_CHECK_PTR(m_action);
+ m_action->setToolTip(i18n("Erase parts of a selection"));
+ m_action->setExclusiveGroup("tools");
+ m_ownAction = true;
+ }
+}
+
+TQWidget* KisToolSelectEraser::createOptionWidget(TQWidget* tqparent)
+{
+ Q_UNUSED(tqparent);
+ // Commented out due to the fact that this doesn't actually work if you change the action
+#if 0
+ m_optWidget = new KisSelectionOptions(tqparent, m_subject);
+ Q_CHECK_PTR(m_optWidget);
+ m_optWidget->setCaption(i18n("Selection Eraser"));
+
+ TQVBoxLayout * l = dynamic_cast<TQVBoxLayout*>(m_optWidget->tqlayout());
+ l->addItem(new TQSpacerItem(1, 1, TQSizePolicy::Fixed, TQSizePolicy::Expanding));
+
+ return m_optWidget;
+#endif
+ return 0;
+}
+
+TQWidget* KisToolSelectEraser::optionWidget()
+{
+ return m_optWidget;
+}
+
+#include "kis_tool_select_eraser.moc"
+
diff --git a/chalk/plugins/tools/selectiontools/kis_tool_select_eraser.h b/chalk/plugins/tools/selectiontools/kis_tool_select_eraser.h
new file mode 100644
index 00000000..85bd5509
--- /dev/null
+++ b/chalk/plugins/tools/selectiontools/kis_tool_select_eraser.h
@@ -0,0 +1,82 @@
+/*
+ * kis_tool_select_eraser.h - part of Chalk
+ *
+ * Copyright (c) 2003-2004 Boudewijn Rempt <boud@valdyas.org>
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef KIS_TOOL_SELECT_ERASER_H_
+#define KIS_TOOL_SELECT_ERASER_H_
+
+#include <kis_tool_factory.h>
+#include <kis_tool_freehand.h>
+
+class KisPoint;
+class KisSelectionOptions;
+
+
+/**
+ * The selection eraser makes a selection smaller by painting with the
+ * current eraser tqshape. Not sure what kind of an icon could represent
+ * this... Depends a bit on how we're going to visualize selections.
+ */
+class KisToolSelectEraser : public KisToolFreehand {
+ Q_OBJECT
+ TQ_OBJECT
+ typedef KisToolFreehand super;
+
+public:
+ KisToolSelectEraser();
+ virtual ~KisToolSelectEraser();
+
+ virtual void setup(KActionCollection *collection);
+ virtual TQ_UINT32 priority() { return 2; }
+ virtual enumToolType toolType() { return TOOL_SELECT; }
+ virtual TQWidget* createOptionWidget(TQWidget* tqparent);
+ virtual TQWidget* optionWidget();
+
+public slots:
+ virtual void activate();
+
+protected:
+
+ virtual void initPaint(KisEvent *e);
+ virtual void endPaint();
+private:
+ KisSelectionOptions * m_optWidget;
+
+};
+
+
+class KisToolSelectEraserFactory : public KisToolFactory {
+ typedef KisToolFactory super;
+public:
+ KisToolSelectEraserFactory() : super() {};
+ virtual ~KisToolSelectEraserFactory(){};
+
+ virtual KisTool * createTool(KActionCollection * ac) {
+ KisTool * t = new KisToolSelectEraser();
+ Q_CHECK_PTR(t);
+ t->setup(ac);
+ return t;
+ }
+ virtual KisID id() { return KisID("eraserselect", i18n("Eraser Select Tool")); }
+};
+
+
+
+#endif // KIS_TOOL_SELECT_ERASER_H_
+
diff --git a/chalk/plugins/tools/selectiontools/kis_tool_select_outline.cc b/chalk/plugins/tools/selectiontools/kis_tool_select_outline.cc
new file mode 100644
index 00000000..b81762fb
--- /dev/null
+++ b/chalk/plugins/tools/selectiontools/kis_tool_select_outline.cc
@@ -0,0 +1,295 @@
+/*
+ * kis_tool_select_freehand.h - part of Krayon^WChalk
+ *
+ * Copyright (c) 2000 John Califf <jcaliff@compuzone.net>
+ * Copyright (c) 2002 Patrick Julien <freak@codepimps.org>
+ * Copyright (c) 2004 Boudewijn Rempt <boud@valdyas.org>
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+#include <tqapplication.h>
+#include <tqpainter.h>
+#include <tqregion.h>
+#include <tqwidget.h>
+#include <tqlayout.h>
+
+#include <kaction.h>
+#include <kdebug.h>
+#include <kcommand.h>
+#include <klocale.h>
+
+#include <kis_layer.h>
+#include <kis_selection_options.h>
+#include <kis_canvas_controller.h>
+#include <kis_canvas_subject.h>
+#include <kis_cursor.h>
+#include <kis_image.h>
+#include <kis_tool_select_outline.h>
+#include <kis_vec.h>
+#include <kis_undo_adapter.h>
+#include <kis_button_press_event.h>
+#include <kis_button_release_event.h>
+#include <kis_move_event.h>
+#include "kis_selected_transaction.h"
+#include "kis_painter.h"
+#include "kis_paintop_registry.h"
+#include "kis_canvas.h"
+#include "kis_canvas_painter.h"
+
+KisToolSelectOutline::KisToolSelectOutline()
+ : super(i18n("Select Outline"))
+{
+ setName("tool_select_outline");
+ setCursor(KisCursor::load("tool_outline_selection_cursor.png", 5, 5));
+
+ m_subject = 0;
+ m_dragging = false;
+ m_optWidget = 0;
+ m_selectAction = SELECTION_ADD;
+}
+
+KisToolSelectOutline::~KisToolSelectOutline()
+{
+}
+
+void KisToolSelectOutline::activate()
+{
+ super::activate();
+
+ if (!m_optWidget)
+ return;
+
+ m_optWidget->slotActivated();
+}
+
+void KisToolSelectOutline::update (KisCanvasSubject *subject)
+{
+ m_subject = subject;
+ super::update(m_subject);
+}
+
+void KisToolSelectOutline::buttonPress(KisButtonPressEvent *event)
+{
+ if (event->button() == Qt::LeftButton) {
+ m_dragging = true;
+
+ m_dragStart = event->pos();
+ m_dragEnd = event->pos();
+ m_points.clear();
+ m_points.append(m_dragStart);
+ }
+}
+
+void KisToolSelectOutline::move(KisMoveEvent *event)
+{
+ if (m_dragging) {
+ m_dragStart = m_dragEnd;
+ m_dragEnd = event->pos();
+ m_points.append (m_dragEnd);
+ // draw new lines on canvas
+ draw();
+ }
+}
+
+void KisToolSelectOutline::buttonRelease(KisButtonReleaseEvent *event)
+{
+ if (!m_subject)
+ return;
+
+ if (m_dragging && event->button() == Qt::LeftButton) {
+ m_dragging = false;
+ deactivate();
+
+ KisImageSP img = m_subject->currentImg();
+
+ if (img && img->activeDevice()) {
+ TQApplication::setOverrideCursor(KisCursor::waitCursor());
+ KisPaintDeviceSP dev = img->activeDevice();
+ bool hasSelection = dev->hasSelection();
+ KisSelectedTransaction *t = 0;
+ if (img->undo()) t = new KisSelectedTransaction(i18n("Outline Selection"), dev);
+ KisSelectionSP selection = dev->selection();
+
+ if (!hasSelection) {
+ selection->clear();
+ }
+
+ KisPainter painter(selection.data());
+
+ painter.setPaintColor(KisColor(TQt::black, selection->colorSpace()));
+ painter.setFillStyle(KisPainter::FillStyleForegroundColor);
+ painter.setStrokeStyle(KisPainter::StrokeStyleNone);
+ painter.setBrush(m_subject->currentBrush());
+ painter.setOpacity(OPACITY_OPAQUE);
+ KisPaintOp * op = KisPaintOpRegistry::instance()->paintOp("paintbrush", 0, &painter);
+ painter.setPaintOp(op); // And now the painter owns the op and will destroy it.
+
+ switch (m_selectAction) {
+ case SELECTION_ADD:
+ painter.setCompositeOp(COMPOSITE_OVER);
+ break;
+ case SELECTION_SUBTRACT:
+ painter.setCompositeOp(COMPOSITE_SUBTRACT);
+ break;
+ default:
+ break;
+ }
+
+ painter.paintPolygon(m_points);
+
+
+ if(hasSelection) {
+ TQRect dirty(painter.dirtyRect());
+ dev->setDirty(dirty);
+ dev->emitSelectionChanged(dirty);
+ } else {
+ dev->setDirty();
+ dev->emitSelectionChanged();
+ }
+
+ if (img->undo())
+ img->undoAdapter()->addCommand(t);
+
+ TQApplication::restoreOverrideCursor();
+ }
+
+ m_points.clear();
+ }
+}
+
+void KisToolSelectOutline::paint(KisCanvasPainter& gc)
+{
+ draw(gc);
+}
+
+void KisToolSelectOutline::paint(KisCanvasPainter& gc, const TQRect&)
+{
+ draw(gc);
+}
+
+void KisToolSelectOutline::draw()
+{
+ if (m_subject) {
+ KisCanvasController *controller = m_subject->canvasController();
+ KisCanvas *canvas = controller->kiscanvas();
+ KisCanvasPainter gc(canvas);
+
+ draw(gc);
+ }
+}
+
+void KisToolSelectOutline::draw(KisCanvasPainter& gc)
+{
+ if (!m_subject)
+ return;
+
+ if (m_dragging && !m_points.empty()) {
+ TQPen pen(TQt::white, 0, TQt::DotLine);
+
+ gc.setPen(pen);
+ gc.setRasterOp(TQt::XorROP);
+
+ KisCanvasController *controller = m_subject->canvasController();
+ KisPoint start, end;
+ TQPoint startPos;
+ TQPoint endPos;
+
+ startPos = controller->windowToView(m_dragStart.floorTQPoint());
+ endPos = controller->windowToView(m_dragEnd.floorTQPoint());
+ gc.drawLine(startPos, endPos);
+ }
+}
+
+void KisToolSelectOutline::deactivate()
+{
+ if (m_subject) {
+ KisCanvasController *controller = m_subject->canvasController();
+ KisCanvas *canvas = controller->kiscanvas();
+ KisCanvasPainter gc(canvas);
+
+ TQPen pen(TQt::white, 0, TQt::DotLine);
+
+ gc.setPen(pen);
+ gc.setRasterOp(TQt::XorROP);
+
+ KisPoint start, end;
+ TQPoint startPos;
+ TQPoint endPos;
+
+ for (KisPointVector::iterator it = m_points.begin(); it != m_points.end(); ++it) {
+
+ if (it == m_points.begin())
+ {
+ start = (*it);
+ } else {
+ end = (*it);
+
+ startPos = controller->windowToView(start.floorTQPoint());
+ endPos = controller->windowToView(end.floorTQPoint());
+
+ gc.drawLine(startPos, endPos);
+
+ start = end;
+ }
+ }
+ }
+}
+
+void KisToolSelectOutline::setup(KActionCollection *collection)
+{
+ m_action = static_cast<KRadioAction *>(collection->action(name()));
+
+ if (m_action == 0) {
+ m_action = new KRadioAction(i18n("&Outline Selection"),
+ "tool_outline_selection",
+ 0,
+ this,
+ TQT_SLOT(activate()),
+ collection,
+ name());
+ Q_CHECK_PTR(m_action);
+ m_action->setExclusiveGroup("tools");
+ m_action->setToolTip(i18n("Select an outline"));
+ m_ownAction = true;
+ }
+}
+
+
+TQWidget* KisToolSelectOutline::createOptionWidget(TQWidget* tqparent)
+{
+ m_optWidget = new KisSelectionOptions(tqparent, m_subject);
+ Q_CHECK_PTR(m_optWidget);
+ m_optWidget->setCaption(i18n("Outline Selection"));
+
+ connect (m_optWidget, TQT_SIGNAL(actionChanged(int)), this, TQT_SLOT(slotSetAction(int)));
+
+ TQVBoxLayout * l = dynamic_cast<TQVBoxLayout*>(m_optWidget->tqlayout());
+ l->addItem(new TQSpacerItem(1, 1, TQSizePolicy::Fixed, TQSizePolicy::Expanding));
+
+ return m_optWidget;
+}
+
+TQWidget* KisToolSelectOutline::optionWidget()
+{
+ return m_optWidget;
+}
+
+void KisToolSelectOutline::slotSetAction(int action) {
+ if (action >= SELECTION_ADD && action <= SELECTION_SUBTRACT)
+ m_selectAction =(enumSelectionMode)action;
+}
+
+#include "kis_tool_select_outline.moc"
+
diff --git a/chalk/plugins/tools/selectiontools/kis_tool_select_outline.h b/chalk/plugins/tools/selectiontools/kis_tool_select_outline.h
new file mode 100644
index 00000000..74ecab78
--- /dev/null
+++ b/chalk/plugins/tools/selectiontools/kis_tool_select_outline.h
@@ -0,0 +1,101 @@
+/*
+ * kis_tool_select_freehand.h - part of Krayon^WChalk
+ *
+ * Copyright (c) 2000 John Califf <jcaliff@compuzone.net>
+ * Copyright (c) 2002 Patrick Julien <freak@codepimps.org>
+ * Copyright (c) 2004 Boudewijn Rempt <boud@valdyas.org>
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __selecttoolfreehand_h__
+#define __selecttoolfreehand_h__
+
+#include <tqpoint.h>
+#include <tqpointarray.h>
+
+#include "kis_point.h"
+#include "kis_tool_non_paint.h"
+#include "kis_tool_factory.h"
+#include "kis_selection.h"
+
+class KisSelectionOptions;
+
+class KisToolSelectOutline : public KisToolNonPaint {
+
+ typedef KisToolNonPaint super;
+ Q_OBJECT
+ TQ_OBJECT
+public:
+ KisToolSelectOutline();
+ virtual ~KisToolSelectOutline();
+
+ virtual void update (KisCanvasSubject *subject);
+
+ virtual void setup(KActionCollection *collection);
+ virtual TQ_UINT32 priority() { return 6; }
+ virtual enumToolType toolType() { return TOOL_SELECT; }
+
+ virtual void buttonPress(KisButtonPressEvent *event);
+ virtual void move(KisMoveEvent *event);
+ virtual void buttonRelease(KisButtonReleaseEvent *event);
+
+ TQWidget* createOptionWidget(TQWidget* tqparent);
+ virtual TQWidget* optionWidget();
+
+public slots:
+ virtual void slotSetAction(int);
+ virtual void activate();
+ void deactivate();
+
+protected:
+ virtual void paint(KisCanvasPainter& gc);
+ virtual void paint(KisCanvasPainter& gc, const TQRect& rc);
+ void draw(KisCanvasPainter& gc);
+ void draw();
+
+
+protected:
+ KisPoint m_dragStart;
+ KisPoint m_dragEnd;
+
+ bool m_dragging;
+private:
+ typedef TQValueVector<KisPoint> KisPointVector;
+ KisCanvasSubject *m_subject;
+ KisPointVector m_points;
+ KisSelectionOptions * m_optWidget;
+ enumSelectionMode m_selectAction;
+};
+
+
+class KisToolSelectOutlineFactory : public KisToolFactory {
+ typedef KisToolFactory super;
+public:
+ KisToolSelectOutlineFactory() : super() {};
+ virtual ~KisToolSelectOutlineFactory(){};
+
+ virtual KisTool * createTool(KActionCollection * ac) {
+ KisTool * t = new KisToolSelectOutline();
+ Q_CHECK_PTR(t);
+ t->setup(ac);
+ return t;
+ }
+ virtual KisID id() { return KisID("selectoutline", i18n("Select Outline tool")); }
+};
+
+
+#endif //__selecttoolfreehand_h__
+
diff --git a/chalk/plugins/tools/selectiontools/kis_tool_select_polygonal.cc b/chalk/plugins/tools/selectiontools/kis_tool_select_polygonal.cc
new file mode 100644
index 00000000..7bac7cc3
--- /dev/null
+++ b/chalk/plugins/tools/selectiontools/kis_tool_select_polygonal.cc
@@ -0,0 +1,315 @@
+/*
+ * kis_tool_select_polygonal.h - part of Krayon^WChalk
+ *
+ * Copyright (c) 2000 John Califf <jcaliff@compuzone.net>
+ * Copyright (c) 2002 Patrick Julien <freak@codepimps.org>
+ * Copyright (c) 2004 Boudewijn Rempt <boud@valdyas.org>
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+#include <tqapplication.h>
+#include <tqpainter.h>
+#include <tqregion.h>
+#include <tqwidget.h>
+#include <tqlayout.h>
+
+#include <kaction.h>
+#include <kdebug.h>
+#include <kcommand.h>
+#include <klocale.h>
+
+#include <kis_layer.h>
+#include <kis_selection_options.h>
+#include <kis_canvas_controller.h>
+#include <kis_canvas_subject.h>
+#include <kis_cursor.h>
+#include <kis_image.h>
+#include <kis_tool_select_polygonal.h>
+#include <kis_vec.h>
+#include <kis_undo_adapter.h>
+#include <kis_button_press_event.h>
+#include <kis_button_release_event.h>
+#include <kis_move_event.h>
+#include "kis_selected_transaction.h"
+#include "kis_painter.h"
+#include "kis_paintop_registry.h"
+#include "kis_canvas.h"
+#include "kis_canvas_painter.h"
+
+KisToolSelectPolygonal::KisToolSelectPolygonal()
+ : super(i18n("Select Polygonal"))
+{
+ setName("tool_select_polygonal");
+ setCursor(KisCursor::load("tool_polygonal_selection_cursor.png", 6, 6));
+
+ m_subject = 0;
+ m_dragging = false;
+ m_optWidget = 0;
+ m_selectAction = SELECTION_ADD;
+}
+
+KisToolSelectPolygonal::~KisToolSelectPolygonal()
+{
+}
+
+void KisToolSelectPolygonal::activate()
+{
+ m_points.clear();
+ super::activate();
+
+ if (!m_optWidget)
+ return;
+
+ m_optWidget->slotActivated();
+}
+
+void KisToolSelectPolygonal::deactivate()
+{
+ draw();
+ m_points.clear();
+ m_dragging = false;
+}
+
+
+void KisToolSelectPolygonal::update (KisCanvasSubject *subject)
+{
+ m_subject = subject;
+ super::update(m_subject);
+}
+
+void KisToolSelectPolygonal::buttonPress(KisButtonPressEvent *event)
+{
+ if (event->button() == Qt::LeftButton) {
+ m_dragging = true;
+
+ if (m_points.isEmpty())
+ {
+ m_dragStart = event->pos();
+ m_dragEnd = event->pos();
+ m_points.append(m_dragStart);
+ } else {
+ m_dragStart = m_dragEnd;
+ m_dragEnd = event->pos();
+ draw();
+ }
+ } else if (event->button() == Qt::LeftButton && event->state() == ShiftButton) {
+ finish();
+ }
+}
+
+
+void KisToolSelectPolygonal::doubleClick( KisDoubleClickEvent * )
+{
+ finish();
+}
+
+void KisToolSelectPolygonal::finish()
+{
+ // erase old lines on canvas
+ draw();
+ m_dragging = false;
+
+ KisImageSP img = m_subject->currentImg();
+
+ if (img && img->activeDevice()) {
+ TQApplication::setOverrideCursor(KisCursor::waitCursor());
+ KisPaintDeviceSP dev = img->activeDevice();
+
+ bool hasSelection = dev->hasSelection();
+ KisSelectedTransaction *t = 0;
+ if (img->undo()) t = new KisSelectedTransaction(i18n("Polygonal Selection"), dev);
+ KisSelectionSP selection = dev->selection();
+
+ if (!hasSelection)
+ {
+ selection->clear();
+ }
+
+ KisPainter painter(selection.data());
+ painter.setPaintColor(KisColor(TQt::black, selection->colorSpace()));
+ painter.setFillStyle(KisPainter::FillStyleForegroundColor);
+ painter.setStrokeStyle(KisPainter::StrokeStyleNone);
+ painter.setBrush(m_subject->currentBrush());
+ painter.setOpacity(OPACITY_OPAQUE);
+ KisPaintOp * op = KisPaintOpRegistry::instance()->paintOp("paintbrush", 0, &painter);
+ painter.setPaintOp(op); // And now the painter owns the op and will destroy it.
+
+ switch(m_selectAction)
+ {
+ case SELECTION_ADD:
+ painter.setCompositeOp(COMPOSITE_OVER);
+ break;
+ case SELECTION_SUBTRACT:
+ painter.setCompositeOp(COMPOSITE_SUBTRACT);
+ break;
+ default:
+ break;
+ }
+
+ painter.paintPolygon(m_points);
+
+ if(hasSelection) {
+ TQRect rect(painter.dirtyRect());
+ dev->setDirty(rect);
+ dev->emitSelectionChanged(rect);
+ } else {
+ dev->setDirty();
+ dev->emitSelectionChanged();
+ }
+
+ if (img->undo()) img->undoAdapter()->addCommand(t);
+
+ TQApplication::restoreOverrideCursor();
+ }
+
+ m_points.clear();
+
+}
+
+void KisToolSelectPolygonal::move(KisMoveEvent *event)
+{
+ if (m_dragging) {
+ // erase old lines on canvas
+ draw();
+ // get current mouse position
+ m_dragEnd = event->pos();
+ // draw new lines on canvas
+ draw();
+ }
+}
+
+void KisToolSelectPolygonal::buttonRelease(KisButtonReleaseEvent *event)
+{
+ if (!m_subject)
+ return;
+
+ if (m_dragging && event->button() == Qt::LeftButton) {
+ m_dragging = false;
+ m_points.append (m_dragEnd);
+ }
+
+ if (m_dragging && event->button() == Qt::RightButton) {
+
+ }
+}
+
+void KisToolSelectPolygonal::paint(KisCanvasPainter& gc)
+{
+ draw(gc);
+}
+
+void KisToolSelectPolygonal::paint(KisCanvasPainter& gc, const TQRect&)
+{
+ draw(gc);
+}
+
+void KisToolSelectPolygonal::draw()
+{
+ if (m_subject) {
+ KisCanvasController *controller = m_subject->canvasController();
+ KisCanvas *canvas = controller->kiscanvas();
+ KisCanvasPainter gc(canvas);
+
+ draw(gc);
+ }
+}
+
+void KisToolSelectPolygonal::draw(KisCanvasPainter& gc)
+{
+ if (!m_subject)
+ return;
+
+ TQPen pen(TQt::white, 0, TQt::DotLine);
+
+ gc.setPen(pen);
+ gc.setRasterOp(TQt::XorROP);
+
+ KisCanvasController *controller = m_subject->canvasController();
+ KisPoint start, end;
+ TQPoint startPos;
+ TQPoint endPos;
+
+ if (m_dragging) {
+ startPos = controller->windowToView(m_dragStart.floorTQPoint());
+ endPos = controller->windowToView(m_dragEnd.floorTQPoint());
+ gc.drawLine(startPos, endPos);
+ } else {
+ for (KisPointVector::iterator it = m_points.begin(); it != m_points.end(); ++it) {
+
+ if (it == m_points.begin())
+ {
+ start = (*it);
+ } else {
+ end = (*it);
+
+ startPos = controller->windowToView(start.floorTQPoint());
+ endPos = controller->windowToView(end.floorTQPoint());
+
+ gc.drawLine(startPos, endPos);
+
+ start = end;
+ }
+ }
+ }
+}
+
+
+void KisToolSelectPolygonal::setup(KActionCollection *collection)
+{
+ m_action = static_cast<KRadioAction *>(collection->action(name()));
+
+ if (m_action == 0) {
+ m_action = new KRadioAction(i18n("&Polygonal Selection"),
+ "tool_polygonal_selection" ,
+ 0,
+ this,
+ TQT_SLOT(activate()),
+ collection,
+ name());
+ Q_CHECK_PTR(m_action);
+ m_action->setExclusiveGroup("tools");
+ m_action->setToolTip(i18n("Select a polygonal area"));
+ m_ownAction = true;
+ }
+}
+
+
+TQWidget* KisToolSelectPolygonal::createOptionWidget(TQWidget* tqparent)
+{
+ m_optWidget = new KisSelectionOptions(tqparent, m_subject);
+ Q_CHECK_PTR(m_optWidget);
+ m_optWidget->setCaption(i18n("Polygonal Selection"));
+
+ connect (m_optWidget, TQT_SIGNAL(actionChanged(int)), this, TQT_SLOT(slotSetAction(int)));
+
+ TQVBoxLayout * l = dynamic_cast<TQVBoxLayout*>(m_optWidget->tqlayout());
+ l->addItem(new TQSpacerItem(1, 1, TQSizePolicy::Fixed, TQSizePolicy::Expanding));
+
+ return m_optWidget;
+}
+
+TQWidget* KisToolSelectPolygonal::optionWidget()
+{
+ return m_optWidget;
+}
+
+void KisToolSelectPolygonal::slotSetAction(int action) {
+ if (action >= SELECTION_ADD && action <= SELECTION_SUBTRACT)
+ m_selectAction =(enumSelectionMode)action;
+}
+
+
+
+#include "kis_tool_select_polygonal.moc"
diff --git a/chalk/plugins/tools/selectiontools/kis_tool_select_polygonal.h b/chalk/plugins/tools/selectiontools/kis_tool_select_polygonal.h
new file mode 100644
index 00000000..65a32ee6
--- /dev/null
+++ b/chalk/plugins/tools/selectiontools/kis_tool_select_polygonal.h
@@ -0,0 +1,106 @@
+/*
+ * kis_tool_select_polygonal.h - part of Krayon^WChalk
+ *
+ * Copyright (c) 2000 John Califf <jcaliff@compuzone.net>
+ * Copyright (c) 2002 Patrick Julien <freak@codepimps.org>
+ * Copyright (c) 2004 Boudewijn Rempt <boud@valdyas.org>
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __selecttoolpolygonal_h__
+#define __selecttoolpolygonal_h__
+
+#include "kis_point.h"
+#include "kis_tool_non_paint.h"
+#include "kis_tool_factory.h"
+#include "kis_selection.h"
+
+class KisSelectionOptions;
+
+class KisToolSelectPolygonal : public KisToolNonPaint {
+
+ typedef KisToolNonPaint super;
+ Q_OBJECT
+ TQ_OBJECT
+public:
+ KisToolSelectPolygonal();
+ virtual ~KisToolSelectPolygonal();
+
+ //
+ // KisCanvasObserver interface
+ //
+
+ virtual void update (KisCanvasSubject *subject);
+
+ //
+ // KisToolPaint interface
+ //
+
+ virtual void setup(KActionCollection *collection);
+ virtual TQ_UINT32 priority() { return 5; }
+ virtual enumToolType toolType() { return TOOL_SELECT; }
+ virtual void buttonPress(KisButtonPressEvent *event);
+ virtual void move(KisMoveEvent *event);
+ virtual void buttonRelease(KisButtonReleaseEvent *event);
+ virtual void doubleClick(KisDoubleClickEvent * event);
+
+ void finish();
+ TQWidget* createOptionWidget(TQWidget* tqparent);
+ virtual TQWidget* optionWidget();
+
+public slots:
+ virtual void slotSetAction(int);
+ virtual void activate();
+ void deactivate();
+
+protected:
+ virtual void paint(KisCanvasPainter& gc);
+ virtual void paint(KisCanvasPainter& gc, const TQRect& rc);
+ void draw(KisCanvasPainter& gc);
+ void draw();
+
+protected:
+ KisPoint m_dragStart;
+ KisPoint m_dragEnd;
+
+ bool m_dragging;
+private:
+ typedef TQValueVector<KisPoint> KisPointVector;
+ KisCanvasSubject *m_subject;
+ KisPointVector m_points;
+ KisSelectionOptions * m_optWidget;
+ enumSelectionMode m_selectAction;
+};
+
+
+class KisToolSelectPolygonalFactory : public KisToolFactory {
+ typedef KisToolFactory super;
+public:
+ KisToolSelectPolygonalFactory() : super() {};
+ virtual ~KisToolSelectPolygonalFactory(){};
+
+ virtual KisTool * createTool(KActionCollection * ac) {
+ KisTool * t = new KisToolSelectPolygonal();
+ Q_CHECK_PTR(t);
+ t->setup(ac);
+ return t;
+ }
+ virtual KisID id() { return KisID("polygonalselect", i18n("Polygonal Select Tool")); }
+};
+
+
+#endif //__selecttoolpolygonal_h__
+
diff --git a/chalk/plugins/tools/selectiontools/kis_tool_select_rectangular.cc b/chalk/plugins/tools/selectiontools/kis_tool_select_rectangular.cc
new file mode 100644
index 00000000..aa7052af
--- /dev/null
+++ b/chalk/plugins/tools/selectiontools/kis_tool_select_rectangular.cc
@@ -0,0 +1,323 @@
+
+/*
+ * kis_tool_select_rectangular.cc -- part of Chalk
+ *
+ * Copyright (c) 1999 Michael Koch <koch@kde.org>
+ * 2001 John Califf <jcaliff@compuzone.net>
+ * 2002 Patrick Julien <freak@codepimps.org>
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <tqapplication.h>
+#include <tqpainter.h>
+#include <tqpen.h>
+#include <tqlayout.h>
+
+#include <kdebug.h>
+#include <kaction.h>
+#include <kcommand.h>
+#include <klocale.h>
+
+#include "kis_canvas_controller.h"
+#include "kis_canvas_subject.h"
+#include "kis_cursor.h"
+#include "kis_image.h"
+#include "kis_painter.h"
+#include "kis_layer.h"
+#include "kis_tool_select_rectangular.h"
+#include "kis_undo_adapter.h"
+#include "kis_button_press_event.h"
+#include "kis_button_release_event.h"
+#include "kis_move_event.h"
+#include "kis_selection.h"
+#include "kis_selection_options.h"
+#include <kis_selected_transaction.h>
+#include "kis_canvas.h"
+#include "kis_canvas_painter.h"
+
+KisToolSelectRectangular::KisToolSelectRectangular()
+ : super(i18n("Rectangular Select Tool"))
+{
+ setName("tool_select_rectangular");
+ setCursor(KisCursor::load("tool_rectangular_selection_cursor.png", 6, 6));
+ m_subject = 0;
+ m_selecting = false;
+ m_centerPos = KisPoint(0, 0);
+ m_startPos = KisPoint(0, 0);
+ m_endPos = KisPoint(0, 0);
+ m_optWidget = 0;
+ m_selectAction = SELECTION_ADD;
+}
+
+KisToolSelectRectangular::~KisToolSelectRectangular()
+{
+}
+
+void KisToolSelectRectangular::activate()
+{
+ super::activate();
+
+ if (!m_optWidget)
+ return;
+
+ m_optWidget->slotActivated();
+}
+
+void KisToolSelectRectangular::update(KisCanvasSubject *subject)
+{
+ m_subject = subject;
+ super::update(m_subject);
+}
+
+void KisToolSelectRectangular::paint(KisCanvasPainter& gc)
+{
+ if (m_selecting)
+ paintOutline(gc, TQRect());
+}
+
+void KisToolSelectRectangular::paint(KisCanvasPainter& gc, const TQRect& rc)
+{
+ if (m_selecting)
+ paintOutline(gc, rc);
+}
+
+void KisToolSelectRectangular::clearSelection()
+{
+ if (m_subject) {
+ KisCanvasController *controller = m_subject->canvasController();
+ KisImageSP img = m_subject->currentImg();
+
+ Q_ASSERT(controller);
+
+ m_centerPos = KisPoint(0, 0);
+ m_startPos = KisPoint(0, 0);
+ m_endPos = KisPoint(0, 0);
+ m_selecting = false;
+ }
+}
+
+void KisToolSelectRectangular::buttonPress(KisButtonPressEvent *e)
+{
+ if (m_subject) {
+ KisImageSP img = m_subject->currentImg();
+
+ if (img && img->activeDevice() && e->button() == Qt::LeftButton) {
+ clearSelection();
+ m_startPos = m_endPos = m_centerPos = e->pos();
+ m_selecting = true;
+ }
+ }
+}
+
+void KisToolSelectRectangular::move(KisMoveEvent *e)
+{
+ if (m_subject && m_selecting) {
+ paintOutline();
+ // move (alt) or resize rectangle
+ if (e->state() & TQt::AltButton) {
+ KisPoint trans = e->pos() - m_endPos;
+ m_startPos += trans;
+ m_endPos += trans;
+ } else {
+ KisPoint diag = e->pos() - (e->state() & TQt::ControlButton
+ ? m_centerPos : m_startPos);
+ // square?
+ if (e->state() & TQt::ShiftButton) {
+ double size = TQMAX(fabs(diag.x()), fabs(diag.y()));
+ double w = diag.x() < 0 ? -size : size;
+ double h = diag.y() < 0 ? -size : size;
+ diag = KisPoint(w, h);
+ }
+
+ // resize around center point?
+ if (e->state() & TQt::ControlButton) {
+ m_startPos = m_centerPos - diag;
+ m_endPos = m_centerPos + diag;
+ } else {
+ m_endPos = m_startPos + diag;
+ }
+ }
+ paintOutline();
+ m_centerPos = KisPoint((m_startPos.x() + m_endPos.x()) / 2,
+ (m_startPos.y() + m_endPos.y()) / 2);
+ }
+}
+
+void KisToolSelectRectangular::buttonRelease(KisButtonReleaseEvent *e)
+{
+ if (m_subject && m_selecting && e->button() == Qt::LeftButton) {
+
+ paintOutline();
+
+ if (m_startPos == m_endPos) {
+ clearSelection();
+ } else {
+ KisImageSP img = m_subject->currentImg();
+
+ if (!img)
+ return;
+
+ if (m_endPos.y() < 0)
+ m_endPos.setY(0);
+
+ if (m_endPos.y() > img->height())
+ m_endPos.setY(img->height());
+
+ if (m_endPos.x() < 0)
+ m_endPos.setX(0);
+
+ if (m_endPos.x() > img->width())
+ m_endPos.setX(img->width());
+ if (img && img->activeDevice()) {
+
+ TQApplication::setOverrideCursor(KisCursor::waitCursor());
+ KisPaintDeviceSP dev = img->activeDevice();
+ bool hasSelection = dev->hasSelection();
+
+ KisSelectedTransaction *t = 0;
+ if (img->undo()) t = new KisSelectedTransaction(i18n("Rectangular Selection"), dev);
+ KisSelectionSP selection = dev->selection();
+ TQRect rc(m_startPos.floorTQPoint(), m_endPos.floorTQPoint());
+ rc = rc.normalize();
+
+ // We don't want the border of the 'rectangle' to be included in our selection
+ rc.setSize(rc.size() - TQSize(1,1));
+
+ if(! hasSelection)
+ {
+ selection->clear();
+ if(m_selectAction==SELECTION_SUBTRACT)
+ selection->invert();
+ }
+
+ KisSelectionSP tmpSel = new KisSelection(dev);
+ tmpSel->select(rc);
+ switch(m_selectAction)
+ {
+ case SELECTION_ADD:
+ dev->addSelection(tmpSel);
+ break;
+ case SELECTION_SUBTRACT:
+ dev->subtractSelection(tmpSel);
+ break;
+ default:
+ break;
+ }
+
+
+ if(hasSelection) {
+ dev->setDirty(rc);
+ dev->emitSelectionChanged(rc);
+ } else {
+ dev->setDirty();
+ dev->emitSelectionChanged();
+ }
+
+ if (img->undo())
+ img->undoAdapter()->addCommand(t);
+
+ KisCanvasController *controller = m_subject -> canvasController();
+ controller -> kiscanvas() -> update();
+
+ TQApplication::restoreOverrideCursor();
+ }
+ }
+
+ m_selecting = false;
+ }
+}
+
+void KisToolSelectRectangular::paintOutline()
+{
+ if (m_subject) {
+ KisCanvasController *controller = m_subject->canvasController();
+ KisCanvas *canvas = controller->kiscanvas();
+ KisCanvasPainter gc(canvas);
+ TQRect rc;
+
+ paintOutline(gc, rc);
+ }
+}
+
+void KisToolSelectRectangular::paintOutline(KisCanvasPainter& gc, const TQRect&)
+{
+ if (m_subject) {
+ KisCanvasController *controller = m_subject->canvasController();
+ RasterOp op = gc.rasterOp();
+ TQPen old = gc.pen();
+ TQPen pen(TQt::DotLine);
+ TQPoint start;
+ TQPoint end;
+
+ Q_ASSERT(controller);
+ start = controller->windowToView(m_startPos.floorTQPoint());
+ end = controller->windowToView(m_endPos.floorTQPoint());
+
+ gc.setRasterOp(TQt::NotROP);
+ gc.setPen(pen);
+ gc.drawRect(TQRect(start, end));
+ gc.setRasterOp(op);
+ gc.setPen(old);
+ }
+}
+
+void KisToolSelectRectangular::slotSetAction(int action) {
+ if (action >= SELECTION_ADD && action <= SELECTION_SUBTRACT)
+ m_selectAction =(enumSelectionMode)action;
+}
+
+void KisToolSelectRectangular::setup(KActionCollection *collection)
+{
+ m_action = static_cast<KRadioAction *>(collection->action(name()));
+
+ if (m_action == 0) {
+ m_action = new KRadioAction(i18n("&Rectangular Selection"),
+ "tool_rect_selection",
+ TQt::Key_R,
+ this,
+ TQT_SLOT(activate()),
+ collection,
+ name());
+ Q_CHECK_PTR(m_action);
+ m_action->setExclusiveGroup("tools");
+ m_action->setToolTip(i18n("Select a rectangular area"));
+ m_ownAction = true;
+ }
+}
+
+TQWidget* KisToolSelectRectangular::createOptionWidget(TQWidget* tqparent)
+{
+ m_optWidget = new KisSelectionOptions(tqparent, m_subject);
+ Q_CHECK_PTR(m_optWidget);
+ m_optWidget->setCaption(i18n("Rectangular Selection"));
+
+ connect (m_optWidget, TQT_SIGNAL(actionChanged(int)), this, TQT_SLOT(slotSetAction(int)));
+
+ TQVBoxLayout * l = dynamic_cast<TQVBoxLayout*>(m_optWidget->tqlayout());
+ l->addItem(new TQSpacerItem(1, 1, TQSizePolicy::Fixed, TQSizePolicy::Expanding));
+
+ return m_optWidget;
+}
+
+TQWidget* KisToolSelectRectangular::optionWidget()
+{
+ return m_optWidget;
+}
+
+
+
+
+#include "kis_tool_select_rectangular.moc"
diff --git a/chalk/plugins/tools/selectiontools/kis_tool_select_rectangular.h b/chalk/plugins/tools/selectiontools/kis_tool_select_rectangular.h
new file mode 100644
index 00000000..eb286cca
--- /dev/null
+++ b/chalk/plugins/tools/selectiontools/kis_tool_select_rectangular.h
@@ -0,0 +1,95 @@
+/*
+ * kis_tool_select_rectangular.h - part of Chalk
+ *
+ * Copyright (c) 1999 Michael Koch <koch@kde.org>
+ * 2002 Patrick Julien <freak@codepimps.org>
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef KIS_TOOL_SELECT_RECTANGULAR_H_
+#define KIS_TOOL_SELECT_RECTANGULAR_H_
+
+#include "kis_point.h"
+#include "kis_tool_non_paint.h"
+#include "kis_selection.h"
+#include "kis_tool_factory.h"
+
+class KisSelectionOptions;
+
+class KisToolSelectRectangular : public KisToolNonPaint {
+
+ typedef KisToolNonPaint super;
+ Q_OBJECT
+ TQ_OBJECT
+
+public:
+ KisToolSelectRectangular();
+ virtual ~KisToolSelectRectangular();
+
+ virtual void update(KisCanvasSubject *subject);
+
+ virtual void setup(KActionCollection *collection);
+ virtual TQ_UINT32 priority() { return 3; }
+ virtual enumToolType toolType() { return TOOL_SELECT; }
+ virtual TQWidget * createOptionWidget(TQWidget* tqparent);
+ virtual TQWidget* optionWidget();
+
+ virtual void paint(KisCanvasPainter& gc);
+ virtual void paint(KisCanvasPainter& gc, const TQRect& rc);
+ virtual void buttonPress(KisButtonPressEvent *e);
+ virtual void move(KisMoveEvent *e);
+ virtual void buttonRelease(KisButtonReleaseEvent *e);
+
+public slots:
+ virtual void slotSetAction(int);
+ virtual void activate();
+
+
+private:
+ void clearSelection();
+ void paintOutline();
+ void paintOutline(KisCanvasPainter& gc, const TQRect& rc);
+
+private:
+ KisCanvasSubject *m_subject;
+ KisPoint m_centerPos;
+ KisPoint m_startPos;
+ KisPoint m_endPos;
+ bool m_selecting;
+ KisSelectionOptions * m_optWidget;
+ enumSelectionMode m_selectAction;
+
+};
+
+class KisToolSelectRectangularFactory : public KisToolFactory {
+ typedef KisToolFactory super;
+public:
+ KisToolSelectRectangularFactory() : super() {};
+ virtual ~KisToolSelectRectangularFactory(){};
+
+ virtual KisTool * createTool(KActionCollection * ac) {
+ KisTool * t = new KisToolSelectRectangular();
+ t->setup(ac);
+ Q_CHECK_PTR(t);
+ return t;
+ }
+ virtual KisID id() { return KisID("rectangularselect", i18n("Rectangular Select Tool")); }
+};
+
+
+
+#endif // KIS_TOOL_SELECT_RECTANGULAR_H_
+
diff --git a/chalk/plugins/tools/selectiontools/selection_tools.cc b/chalk/plugins/tools/selectiontools/selection_tools.cc
new file mode 100644
index 00000000..db4df1ab
--- /dev/null
+++ b/chalk/plugins/tools/selectiontools/selection_tools.cc
@@ -0,0 +1,77 @@
+/*
+ * selection_tools.cc -- Part of Chalk
+ *
+ * Copyright (c) 2004 Boudewijn Rempt (boud@valdyas.org)
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+#include <stdlib.h>
+#include <vector>
+
+#include <tqpoint.h>
+
+#include <klocale.h>
+#include <kiconloader.h>
+#include <kinstance.h>
+#include <kmessagebox.h>
+#include <kstandarddirs.h>
+#include <ktempfile.h>
+#include <kdebug.h>
+#include <kgenericfactory.h>
+
+#include <kis_global.h>
+#include <kis_types.h>
+#include <kis_tool.h>
+#include <kis_tool_registry.h>
+
+#include "selection_tools.h"
+
+#include "kis_tool_select_outline.h"
+#include "kis_tool_select_polygonal.h"
+#include "kis_tool_select_rectangular.h"
+#include "kis_tool_select_contiguous.h"
+#include "kis_tool_select_elliptical.h"
+#include "kis_tool_select_eraser.h"
+#include "kis_tool_select_brush.h"
+#include "kis_tool_move_selection.h"
+
+typedef KGenericFactory<SelectionTools> SelectionToolsFactory;
+K_EXPORT_COMPONENT_FACTORY( chalkselectiontools, SelectionToolsFactory( "chalk" ) )
+
+
+SelectionTools::SelectionTools(TQObject *tqparent, const char *name, const TQStringList &)
+ : KParts::Plugin(tqparent, name)
+{
+ setInstance(SelectionToolsFactory::instance());
+
+ if ( tqparent->inherits("KisToolRegistry") )
+ {
+ KisToolRegistry * r = dynamic_cast<KisToolRegistry*>(tqparent);
+ r->add(new KisToolSelectOutlineFactory());
+ r->add(new KisToolSelectPolygonalFactory());
+ r->add(new KisToolSelectRectangularFactory());
+ r->add(new KisToolSelectBrushFactory());
+ r->add(new KisToolSelectContiguousFactory());
+ r->add(new KisToolSelectEllipticalFactory());
+ r->add(new KisToolSelectEraserFactory());
+ r->add(new KisToolMoveSelectionFactory());
+ }
+}
+
+SelectionTools::~SelectionTools()
+{
+}
+
+#include "selection_tools.moc"
diff --git a/chalk/plugins/tools/selectiontools/selection_tools.h b/chalk/plugins/tools/selectiontools/selection_tools.h
new file mode 100644
index 00000000..2e448e3e
--- /dev/null
+++ b/chalk/plugins/tools/selectiontools/selection_tools.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2003 Boudewijn Rempt (boud@valdyas.org)
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef SELECTION_TOOLS_H_
+#define SELECTION_TOOLS_H_
+
+#include <kparts/plugin.h>
+
+/**
+ * A module wrapper around Chalk's selection tools.
+ * Despite the fact that new tools are created for every new view,
+ * it is not possible to make tools standard parts of the type of the
+ * imagesize plugin, because we need to create a new set of tools for every
+ * pointer device (mouse, stylus, eraser, puck, etc.). So this plugin is
+ * a module which is loaded once into Chalk. For every tool there is a factory
+ * class that is registered with the tool registry, and that is used to create
+ * new instances of the tools.
+ */
+class SelectionTools : public KParts::Plugin
+{
+ Q_OBJECT
+ TQ_OBJECT
+public:
+ SelectionTools(TQObject *tqparent, const char *name, const TQStringList &);
+ virtual ~SelectionTools();
+
+};
+
+#endif // SELECTION_TOOLS_H_
diff --git a/chalk/plugins/tools/selectiontools/tool_brush_selection.png b/chalk/plugins/tools/selectiontools/tool_brush_selection.png
new file mode 100644
index 00000000..3d1bba3f
--- /dev/null
+++ b/chalk/plugins/tools/selectiontools/tool_brush_selection.png
Binary files differ
diff --git a/chalk/plugins/tools/selectiontools/tool_brush_selection.svg b/chalk/plugins/tools/selectiontools/tool_brush_selection.svg
new file mode 100644
index 00000000..228a411f
--- /dev/null
+++ b/chalk/plugins/tools/selectiontools/tool_brush_selection.svg
@@ -0,0 +1,827 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://web.resource.org/cc/"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://inkscape.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ inkscape:export-ydpi="33.000000"
+ inkscape:export-xdpi="33.000000"
+ inkscape:export-filename="/home/danny/tool_brush_selection.png"
+ sodipodi:docname="tool_brush_selection.svg"
+ sodipodi:docbase="/home/danny/work/kde/koffice/chalk/chalk"
+ inkscape:version="0.41"
+ sodipodi:version="0.32"
+ id="svg4694"
+ height="48.000000pt"
+ width="48.000000pt">
+ <defs
+ id="defs3">
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#light90to0"
+ id="radialGradient7969"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.000000,-2.592685,0.379735,0.000000,-30.45690,-1.224420)"
+ cx="-23.859682"
+ cy="95.221397"
+ fx="-23.859682"
+ fy="95.221397"
+ r="8.5514765" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#light90to0"
+ id="linearGradient7967"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.000000,-2.503650,0.399417,0.000000,-30.45690,-1.829360)"
+ x1="-16.569721"
+ y1="81.885979"
+ x2="-21.621279"
+ y2="85.112236" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#light90to0"
+ id="radialGradient7965"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.000000,-2.592685,0.379735,0.000000,-30.45690,-21.22442)"
+ cx="-23.859682"
+ cy="95.221397"
+ fx="-23.859682"
+ fy="95.221397"
+ r="8.5514765" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#light90to0"
+ id="linearGradient7963"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.000000,-2.503650,0.399417,0.000000,-30.45690,-21.82936)"
+ x1="-16.569721"
+ y1="81.885979"
+ x2="-21.621279"
+ y2="85.112236" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#light90to0"
+ id="radialGradient7961"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.000000,-2.592685,0.379735,0.000000,26.44710,-11.22442)"
+ cx="-23.859682"
+ cy="95.221397"
+ fx="-23.859682"
+ fy="95.221397"
+ r="8.5514765" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#light90to0"
+ id="linearGradient7959"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.000000,-2.503650,0.399417,0.000000,26.44710,-11.82936)"
+ x1="-16.569721"
+ y1="81.885979"
+ x2="-21.621279"
+ y2="85.112236" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#light90to0"
+ id="radialGradient7957"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.633416,0.000000,0.000000,0.379735,-44.86332,44.21180)"
+ cx="25.952410"
+ cy="52.497688"
+ fx="25.923746"
+ fy="51.904903"
+ r="14.270030" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#light90to0"
+ id="linearGradient7955"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.503650,0.000000,0.000000,0.399417,-44.86332,44.21180)"
+ x1="22.425571"
+ y1="35.206337"
+ x2="22.396454"
+ y2="41.545322" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#light90to0"
+ id="radialGradient7953"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.633416,0.000000,0.000000,0.379735,-22.86332,44.21180)"
+ cx="25.952410"
+ cy="52.497688"
+ fx="25.923746"
+ fy="51.904903"
+ r="14.270030" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#light90to0"
+ id="linearGradient7951"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.503650,0.000000,0.000000,0.399417,-22.86332,44.21180)"
+ x1="22.425571"
+ y1="35.206337"
+ x2="22.396454"
+ y2="41.545322" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#light90to0"
+ id="radialGradient7949"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.633416,0.000000,0.000000,0.379735,-38.65916,-12.48664)"
+ cx="25.952410"
+ cy="52.497688"
+ fx="25.923746"
+ fy="51.904903"
+ r="14.270030" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#light90to0"
+ id="linearGradient7947"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.503650,0.000000,0.000000,0.399417,-38.65916,-12.48664)"
+ x1="22.425571"
+ y1="35.206337"
+ x2="22.396454"
+ y2="41.545322" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#light90to0"
+ id="linearGradient7945"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.000000,-2.503650,0.399417,0.000000,26.44710,4.170640)"
+ x1="-16.569721"
+ y1="81.885979"
+ x2="-21.621279"
+ y2="85.112236" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#light90to0"
+ id="radialGradient7943"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.878497,0.000000,0.000000,1.138308,-18.65916,-0.486640)"
+ cx="92.643608"
+ cy="55.457653"
+ fx="92.643608"
+ fy="55.457653"
+ r="9.9914455" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#light90to0"
+ id="radialGradient7941"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.000000,-2.592685,0.379735,0.000000,26.44710,-31.22442)"
+ cx="-23.859682"
+ cy="95.221397"
+ fx="-23.859682"
+ fy="95.221397"
+ r="8.5514765" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#light90to0"
+ id="linearGradient7939"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.000000,-2.503650,0.399417,0.000000,26.44710,-31.82936)"
+ x1="-16.569721"
+ y1="81.885979"
+ x2="-21.621279"
+ y2="85.112236" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#light90to0"
+ id="radialGradient7937"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.633416,0.000000,0.000000,0.379735,-16.65916,-12.48664)"
+ cx="25.952410"
+ cy="52.497688"
+ fx="25.923746"
+ fy="51.904903"
+ r="14.270030" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#light90to0"
+ id="linearGradient7935"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.503650,0.000000,0.000000,0.399417,-16.65916,-12.48664)"
+ x1="22.425571"
+ y1="35.206337"
+ x2="22.396454"
+ y2="41.545322" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#light90to0"
+ id="radialGradient7933"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="scale(0.665867,1.501801)"
+ cx="8.0907059"
+ cy="9.5002232"
+ fx="8.0907059"
+ fy="9.5002232"
+ r="5.8189325" />
+ <linearGradient
+ id="light90to0">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.90833336;"
+ offset="0.0000000"
+ id="stop1890" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.0000000;"
+ offset="1.0000000"
+ id="stop1892" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#light90to0"
+ id="linearGradient7931"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.791643,0.000000,0.000000,1.263196,-1.626700,-5.630763)"
+ x1="4.4536543"
+ y1="6.5494914"
+ x2="14.101834"
+ y2="13.431447" />
+ <linearGradient
+ id="garylighttowite">
+ <stop
+ id="stop5106"
+ offset="0.0000000"
+ style="stop-color:#4f4f4f;stop-opacity:1.0000000;" />
+ <stop
+ id="stop5107"
+ offset="1.0000000"
+ style="stop-color:#7e7f7f;stop-opacity:1.0000000;" />
+ </linearGradient>
+ <linearGradient
+ y2="213.83318"
+ x2="197.10010"
+ y1="237.55226"
+ x1="169.41396"
+ gradientTransform="matrix(0.981884,0.000000,0.000000,1.249452,-125.2257,-270.2224)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient4240"
+ xlink:href="#garylighttowite"
+ inkscape:collect="always" />
+ <linearGradient
+ id="blacktowhite">
+ <stop
+ id="stop2476"
+ offset="0.0000000"
+ style="stop-color:#000000;stop-opacity:1.0000000;" />
+ <stop
+ id="stop2475"
+ offset="1.0000000"
+ style="stop-color:#e6e6e6;stop-opacity:1.0000000;" />
+ </linearGradient>
+ <linearGradient
+ y2="305.51498"
+ x2="-126.66700"
+ y1="316.87579"
+ x1="-134.10509"
+ gradientTransform="matrix(0.409156,-1.467734,0.742641,0.334392,-125.2257,-270.2224)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient4238"
+ xlink:href="#blacktowhite"
+ inkscape:collect="always" />
+ <linearGradient
+ id="linearGradient940">
+ <stop
+ style="stop-color:#7d5700;stop-opacity:1;"
+ offset="0.00000000"
+ id="stop941" />
+ <stop
+ style="stop-color:#c58500;stop-opacity:1.0000000;"
+ offset="1.0000000"
+ id="stop942" />
+ </linearGradient>
+ <linearGradient
+ y2="327.82533"
+ x2="477.19157"
+ y1="252.79109"
+ x1="405.98953"
+ gradientTransform="matrix(9.300968e-2,-0.317362,0.155311,2.621206e-2,-185.0894,-152.1973)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient4235"
+ xlink:href="#linearGradient940"
+ inkscape:collect="always" />
+ <linearGradient
+ id="linearGradient944">
+ <stop
+ style="stop-color:#c34700;stop-opacity:1.0000000;"
+ offset="0.0000000"
+ id="stop945" />
+ <stop
+ style="stop-color:#ddc800;stop-opacity:1.0000000;"
+ offset="1.0000000"
+ id="stop946" />
+ </linearGradient>
+ <linearGradient
+ y2="333.50655"
+ x2="492.61439"
+ y1="270.32615"
+ x1="410.61638"
+ gradientTransform="matrix(9.300968e-2,-0.317362,0.155311,2.621206e-2,-185.0894,-152.1973)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient4233"
+ xlink:href="#linearGradient944"
+ inkscape:collect="always" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#light90to0"
+ id="radialGradient1439"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.000000,-2.142981,0.309244,0.000000,-25.19724,11.47156)"
+ cx="-23.859682"
+ cy="95.221397"
+ fx="-23.859682"
+ fy="95.221397"
+ r="8.5514765" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#light90to0"
+ id="linearGradient1442"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.000000,-2.069389,0.325272,0.000000,-25.19724,10.97154)"
+ x1="-16.569721"
+ y1="81.885979"
+ x2="-21.621279"
+ y2="85.112236" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#light90to0"
+ id="radialGradient1446"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.000000,-2.142981,0.309244,0.000000,-25.19724,-5.806103)"
+ cx="-23.859682"
+ cy="95.221397"
+ fx="-23.859682"
+ fy="95.221397"
+ r="8.5514765" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#light90to0"
+ id="linearGradient1449"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.000000,-2.069389,0.325272,0.000000,-25.19724,-6.306116)"
+ x1="-16.569721"
+ y1="81.885979"
+ x2="-21.621279"
+ y2="85.112236" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#light90to0"
+ id="radialGradient1453"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.000000,-2.142981,0.309244,0.000000,21.05881,1.966237)"
+ cx="-23.859682"
+ cy="95.221397"
+ fx="-23.859682"
+ fy="95.221397"
+ r="8.5514765" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#light90to0"
+ id="linearGradient1456"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.000000,-2.069389,0.325272,0.000000,21.05881,1.466224)"
+ x1="-16.569721"
+ y1="81.885979"
+ x2="-21.621279"
+ y2="85.112236" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#light90to0"
+ id="radialGradient1460"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.144567,0.000000,0.000000,0.313870,-38.39521,48.31870)"
+ cx="25.952410"
+ cy="52.497688"
+ fx="25.923746"
+ fy="51.904903"
+ r="14.270030" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#light90to0"
+ id="linearGradient1463"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.038890,0.000000,0.000000,0.330138,-38.39521,48.31870)"
+ x1="22.425571"
+ y1="35.206337"
+ x2="22.396454"
+ y2="41.545322" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#light90to0"
+ id="radialGradient1467"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.144567,0.000000,0.000000,0.313870,-19.66477,48.31870)"
+ cx="25.952410"
+ cy="52.497688"
+ fx="25.923746"
+ fy="51.904903"
+ r="14.270030" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#light90to0"
+ id="linearGradient1470"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.038890,0.000000,0.000000,0.330138,-19.66477,48.31870)"
+ x1="22.425571"
+ y1="35.206337"
+ x2="22.396454"
+ y2="41.545322" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#light90to0"
+ id="radialGradient1474"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.144567,0.000000,0.000000,0.313870,-30.98448,1.415420)"
+ cx="25.952410"
+ cy="52.497688"
+ fx="25.923746"
+ fy="51.904903"
+ r="14.270030" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#light90to0"
+ id="linearGradient1477"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.038890,0.000000,0.000000,0.330138,-30.98448,1.415420)"
+ x1="22.425571"
+ y1="35.206337"
+ x2="22.396454"
+ y2="41.545322" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#light90to0"
+ id="linearGradient1481"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.000000,-2.069389,0.325272,0.000000,21.14350,15.18416)"
+ x1="-16.569721"
+ y1="81.885979"
+ x2="-21.621279"
+ y2="85.112236" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#light90to0"
+ id="radialGradient1484"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.715419,0.000000,0.000000,0.940867,-15.58955,11.33469)"
+ cx="92.643608"
+ cy="55.457653"
+ fx="92.643608"
+ fy="55.457653"
+ r="9.9914455" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#light90to0"
+ id="radialGradient1495"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.144567,0.000000,0.000000,0.313870,-12.33208,1.415420)"
+ cx="25.952410"
+ cy="52.497688"
+ fx="25.923746"
+ fy="51.904903"
+ r="14.270030" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#light90to0"
+ id="linearGradient1498"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.038890,0.000000,0.000000,0.330138,-12.33208,1.415420)"
+ x1="22.425571"
+ y1="35.206337"
+ x2="22.396454"
+ y2="41.545322" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#light90to0"
+ id="radialGradient1502"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.542260,0.000000,0.000000,1.241312,-0.394144,11.73692)"
+ cx="8.0907059"
+ cy="9.5002232"
+ fx="8.0907059"
+ fy="9.5002232"
+ r="5.8189325" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#light90to0"
+ id="linearGradient1505"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.644688,0.000000,0.000000,1.044093,-1.718875,7.082818)"
+ x1="4.4536543"
+ y1="6.5494914"
+ x2="14.101834"
+ y2="13.431447" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#blacktowhite"
+ id="linearGradient1427"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.409156,-1.467734,0.742641,0.334392,-125.2257,-270.2224)"
+ x1="-134.10509"
+ y1="316.87579"
+ x2="-126.66700"
+ y2="305.51498" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#garylighttowite"
+ id="linearGradient1429"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.981884,0.000000,0.000000,1.249452,-125.2257,-270.2224)"
+ x1="169.41396"
+ y1="237.55226"
+ x2="197.10010"
+ y2="213.83318" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient944"
+ id="linearGradient1431"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(9.300968e-2,-0.317362,0.155311,2.621206e-2,-185.0894,-152.1973)"
+ x1="410.61638"
+ y1="270.32615"
+ x2="492.61439"
+ y2="333.50655" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient940"
+ id="linearGradient1433"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(9.300968e-2,-0.317362,0.155311,2.621206e-2,-185.0894,-152.1973)"
+ x1="405.98953"
+ y1="252.79109"
+ x2="477.19157"
+ y2="327.82533" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#light90to0"
+ id="radialGradient1508"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.926025,0.000000,0.000000,0.943879,-3.764700,12.09394)"
+ cx="48.488476"
+ cy="46.914463"
+ fx="48.488476"
+ fy="46.914463"
+ r="31.677956" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#light90to0"
+ id="linearGradient1511"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.937632,0.000000,0.000000,0.932194,-3.191675,13.02262)"
+ x1="10.878086"
+ y1="4.5492039"
+ x2="39.857029"
+ y2="36.873619" />
+ <linearGradient
+ y2="333.50655"
+ x2="492.61439"
+ y1="270.32615"
+ x1="410.61638"
+ gradientTransform="matrix(8.609199e-2,-0.291516,0.143760,2.407732e-2,-172.7295,-138.4789)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1421"
+ xlink:href="#linearGradient944"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="327.82533"
+ x2="477.19157"
+ y1="252.79109"
+ x1="405.98953"
+ gradientTransform="matrix(8.609199e-2,-0.291516,0.143760,2.407732e-2,-172.7295,-138.4789)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1423"
+ xlink:href="#linearGradient940"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="305.51498"
+ x2="-126.66700"
+ y1="316.87579"
+ x1="-134.10509"
+ gradientTransform="matrix(0.378725,-1.348200,0.687406,0.307159,-117.3182,-246.8919)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1425"
+ xlink:href="#blacktowhite"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="213.83318"
+ x2="197.10010"
+ y1="237.55226"
+ x1="169.41396"
+ gradientTransform="matrix(0.908855,0.000000,0.000000,1.147695,-117.3182,-246.8919)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1428"
+ xlink:href="#garylighttowite"
+ inkscape:collect="always" />
+ </defs>
+ <sodipodi:namedview
+ inkscape:window-y="0"
+ inkscape:window-x="0"
+ inkscape:window-height="691"
+ inkscape:window-width="1020"
+ inkscape:grid-bbox="true"
+ inkscape:document-units="px"
+ showgrid="false"
+ inkscape:current-layer="layer1"
+ inkscape:cy="57.678721"
+ inkscape:cx="57.219249"
+ inkscape:zoom="8.5396765"
+ inkscape:pageshadow="2"
+ inkscape:pageopacity="0.0"
+ borderopacity="1.0"
+ bordercolor="#666666"
+ pagecolor="#ffffff"
+ id="base" />
+ <metadata
+ id="metadata4">
+ <rdf:RDF
+ id="RDF5">
+ <cc:Work
+ id="Work6"
+ rdf:about="">
+ <dc:format
+ id="format7">image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage"
+ id="type9" />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:groupmode="layer"
+ inkscape:label="Layer 1"
+ id="layer1">
+ <g
+ id="g3808">
+ <path
+ style="opacity:0.79446638;fill:#0028c6;fill-opacity:0.18099548;stroke:#000000;stroke-width:0.0000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:0.035294119"
+ d="M 6.2934619,13.951302 L 42.647661,13.951302 C 44.570005,13.951302 46.117596,15.941616 46.117596,18.413889 L 46.117596,53.617448 C 46.117596,56.089722 44.570005,58.080035 42.647661,58.080035 L 6.2934619,58.080035 C 4.3711186,58.080035 2.8235279,56.089722 2.8235279,53.617448 L 2.8235279,18.413889 C 2.8235279,15.941616 4.3711186,13.951302 6.2934619,13.951302 z "
+ id="rect7971" />
+ <path
+ style="opacity:0.79446638;fill:url(#linearGradient1511);fill-opacity:1.0000000;stroke:#000000;stroke-width:0.0000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:0.035294119"
+ d="M 6.8664881,14.879987 L 43.220688,14.879987 C 44.781208,38.443460 21.125930,25.243420 3.3965541,54.546133 L 3.3965541,19.342574 C 3.3965541,16.870301 4.9441448,14.879987 6.8664881,14.879987 z "
+ id="path8746"
+ sodipodi:nodetypes="ccccc" />
+ <path
+ style="stroke-opacity:1.0000000;stroke-miterlimit:4.0000000;stroke-linejoin:round;stroke-linecap:round;stroke-width:4.3000002;stroke:none;fill-rule:evenodd;fill-opacity:1.0000000;fill:#353640"
+ d="M 16.843790,11.999986 C 15.654649,11.999986 14.690659,12.962574 14.690659,14.149986 C 14.690659,15.337398 15.654649,16.299986 16.843790,16.299986 L 24.687528,16.299986 C 25.876670,16.299986 26.840659,15.337398 26.840659,14.149986 C 26.840659,12.962574 25.876670,11.999986 24.687528,11.999986 L 16.843790,11.999986 z "
+ id="path3802"
+ sodipodi:nodetypes="ccccccc" />
+ <path
+ style="opacity:0.97233200;fill:url(#radialGradient1508);fill-opacity:1.0000000;stroke:#000000;stroke-width:0.0000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:0.035294119"
+ d="M 6.2934619,13.951302 L 42.647661,13.951302 C 44.570005,13.951302 46.117596,15.941616 46.117596,18.413889 L 46.117596,53.617448 C 46.117596,56.089722 44.570005,58.080035 42.647661,58.080035 L 6.2934619,58.080035 C 4.3711186,58.080035 2.8235279,56.089722 2.8235279,53.617448 L 2.8235279,18.413889 C 2.8235279,15.941616 4.3711186,13.951302 6.2934619,13.951302 z "
+ id="path9514" />
+ <path
+ style="fill:#353640;fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:5.5999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000"
+ d="M 2.2036028,12.000753 C 1.6228812,11.985222 1.0606757,12.206108 0.64540735,12.612953 C 0.23013967,13.019798 -0.0027184452,13.577851 2.3951728e-05,14.159639 L 2.3951728e-05,20.996110 C 2.3951728e-05,22.188431 0.96515240,23.154996 2.1556989,23.154996 C 3.3462453,23.154996 4.3113738,22.188431 4.3113738,20.996110 L 4.3113738,16.342512 L 5.9401060,16.366499 C 6.7276964,16.418884 7.4804421,16.034101 7.9001215,15.364596 C 8.3198002,14.695092 8.3386812,13.848916 7.9492832,13.161304 C 7.5598858,12.473693 6.8250547,12.055619 6.0359137,12.072716 L 2.2036028,12.000753 z "
+ id="path7697" />
+ <path
+ style="fill:#353640;fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:5.5999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000"
+ d="M 45.820092,16.892010 C 45.247569,16.895838 44.700302,17.128591 44.299981,17.538518 C 43.899660,17.948446 43.679468,18.501564 43.688369,19.074883 L 43.688369,28.214166 C 43.688369,29.406486 44.653498,30.373052 45.844045,30.373052 C 47.034590,30.373052 47.999719,29.406486 47.999719,28.214166 L 47.999719,19.074883 C 48.008808,18.493207 47.782088,17.932680 47.371342,17.521322 C 46.960596,17.109964 46.400904,16.882908 45.820092,16.892010 L 45.820092,16.892010 z "
+ id="path1937"
+ sodipodi:nodetypes="cccccccccc" />
+ <path
+ style="fill:#353640;fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:5.5999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000"
+ d="M 44.073235,28.743247 C 44.961756,28.915834 45.380256,26.067378 45.314366,21.725701 C 45.260374,18.227435 46.727595,19.638901 46.838213,17.743808 C 46.855261,17.451725 46.461887,17.299850 45.986113,17.314502 C 45.510339,17.329154 44.952165,17.510332 44.639613,17.884350 C 44.461008,18.031995 44.322268,18.243187 44.228120,18.490651 C 44.133973,18.738115 44.084419,19.021851 44.084191,19.314591 C 44.083962,19.607329 44.075061,26.404202 44.073235,28.743247 z "
+ id="path4304"
+ sodipodi:nodetypes="cccccccc" />
+ <path
+ style="opacity:0.79446638;fill:#353640;fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:5.5999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000"
+ d="M 45.099708,27.978601 C 45.091646,28.876769 45.673295,29.612967 46.398859,29.622947 C 47.124423,29.632927 47.719145,28.912907 47.727206,28.014740 L 47.800192,18.997225 C 47.828734,18.401217 47.590002,17.834123 47.179013,17.521651 C 46.768024,17.209181 46.251475,17.202036 45.834946,17.503063 C 45.418421,17.804089 45.169513,18.364437 45.187290,18.961084 L 45.099708,27.978601 z "
+ id="path4306"
+ sodipodi:nodetypes="cccccccc" />
+ <path
+ style="fill:#353640;fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:5.5999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000"
+ d="M 45.820092,48.749786 C 45.247569,48.753613 44.700302,48.986367 44.299981,49.396295 C 43.899660,49.806222 43.679468,50.359340 43.688369,50.932659 L 43.688369,55.682207 L 42.011733,55.682207 C 40.821187,55.682207 39.856059,56.648773 39.856059,57.841093 C 39.856059,59.033414 40.821187,59.999979 42.011733,59.999979 L 45.844045,59.999979 C 46.416528,60.002488 46.966289,59.775839 47.371101,59.370424 C 47.775912,58.965009 48.002223,58.414430 47.999719,57.841093 L 47.999719,50.932659 C 48.008808,50.350983 47.782088,49.790456 47.371342,49.379097 C 46.960596,48.967740 46.400904,48.740683 45.820092,48.749786 z "
+ id="path7691" />
+ <path
+ style="fill:#353640;fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:5.5999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000"
+ d="M 45.740380,33.011663 C 45.167856,33.015085 44.620590,33.223093 44.220268,33.589441 C 43.819947,33.955789 43.599756,34.450105 43.608656,34.962473 L 43.608656,43.130152 C 43.608656,44.195717 44.573785,45.059526 45.764331,45.059526 C 46.954877,45.059526 47.920006,44.195717 47.920006,43.130152 L 47.920006,34.962473 C 47.929095,34.442636 47.702375,33.941699 47.291630,33.574073 C 46.880884,33.206447 46.321191,33.003529 45.740380,33.011663 L 45.740380,33.011663 z "
+ id="path7765"
+ sodipodi:nodetypes="cccccccccc" />
+ <path
+ style="fill:#353640;fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:5.5999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000"
+ d="M 2.2053264,25.793584 C 1.6328028,25.796681 1.0855366,25.985006 0.68521492,26.316687 C 0.28489404,26.648367 0.064703248,27.095906 0.073603407,27.559789 L 0.073603407,34.954562 C 0.073603407,35.919291 1.0387318,36.701359 2.2292783,36.701359 C 3.4198248,36.701359 4.3849533,35.919291 4.3849533,34.954562 L 4.3849533,27.559789 C 4.3940420,27.089143 4.1673224,26.635610 3.7565769,26.302773 C 3.3458306,25.969936 2.7861376,25.786219 2.2053264,25.793584 L 2.2053264,25.793584 z "
+ id="path7775"
+ sodipodi:nodetypes="cccccccccc" />
+ <path
+ style="fill:#353640;fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:5.5999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000"
+ d="M 2.2053264,41.839095 C 1.6328028,41.842251 1.0855366,42.034192 0.68521492,42.372239 C 0.28489404,42.710286 0.064703248,43.166416 0.073603407,43.639205 L 0.073603407,51.175929 C 0.073603407,52.159177 1.0387318,52.956257 2.2292783,52.956257 C 3.4198248,52.956257 4.3849533,52.159177 4.3849533,51.175929 L 4.3849533,43.639205 C 4.3940420,43.159524 4.1673224,42.697285 3.7565769,42.358057 C 3.3458306,42.018832 2.7861376,41.831589 2.2053264,41.839095 L 2.2053264,41.839095 z "
+ id="path7781"
+ sodipodi:nodetypes="cccccccccc" />
+ <path
+ style="stroke-opacity:1.0000000;stroke-miterlimit:4.0000000;stroke-linejoin:round;stroke-linecap:round;stroke-width:4.3000002;stroke:none;fill-rule:evenodd;fill-opacity:1.0000000;fill:#353640"
+ d="M 34.726123,11.999986 C 33.536982,11.999986 32.572992,12.962574 32.572992,14.149986 C 32.572992,15.337398 33.536982,16.299986 34.726123,16.299986 L 42.569861,16.299986 C 43.759003,16.299986 44.722992,15.337398 44.722992,14.149986 C 44.722992,12.962574 43.759003,11.999986 42.569861,11.999986 L 34.726123,11.999986 z "
+ id="path3804"
+ sodipodi:nodetypes="ccccccc" />
+ <path
+ style="fill:#353640;fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:4.3000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000"
+ d="M 7.5173157,55.699996 C 6.3281746,55.699996 5.3641852,56.662584 5.3641852,57.849996 C 5.3641852,59.037408 6.3281746,59.999996 7.5173157,59.999996 L 15.361054,59.999996 C 16.550196,59.999996 17.514185,59.037408 17.514185,57.849996 C 17.514185,56.662584 16.550196,55.699996 15.361054,55.699996 L 7.5173157,55.699996 z "
+ id="path1514"
+ sodipodi:nodetypes="ccccccc" />
+ <path
+ style="stroke-opacity:1.0000000;stroke-miterlimit:4.0000000;stroke-linejoin:round;stroke-linecap:round;stroke-width:4.3000002;stroke:none;fill-rule:evenodd;fill-opacity:1.0000000;fill:#353640"
+ d="M 24.984459,55.699996 C 23.795318,55.699996 22.831328,56.662584 22.831328,57.849996 C 22.831328,59.037408 23.795318,59.999996 24.984459,59.999996 L 32.828197,59.999996 C 34.017339,59.999996 34.981328,59.037408 34.981328,57.849996 C 34.981328,56.662584 34.017339,55.699996 32.828197,55.699996 L 24.984459,55.699996 z "
+ id="path3041"
+ sodipodi:nodetypes="ccccccc" />
+ </g>
+ <g
+ transform="matrix(1.134471,0.000000,0.000000,1.134471,-1.979056,-8.899644)"
+ id="g1392">
+ <g
+ id="g3005"
+ transform="matrix(0.966181,0.000000,0.000000,1.079600,-428.2439,-311.2579)">
+ <path
+ style="font-size:12.000000;fill:none;fill-opacity:0.29729697;fill-rule:evenodd;stroke:#000000;stroke-width:0.95595007pt;stroke-linejoin:round;stroke-opacity:0.095022626"
+ d="M 491.67350,290.74524 C 489.56264,292.14465 474.46858,315.88005 473.92350,319.90149 C 474.08915,319.99277 474.24280,320.54490 474.07975,320.46399 C 467.56083,324.58038 466.36005,333.74960 462.39225,337.49524 C 469.66515,335.09880 476.01586,329.63350 478.61100,323.08899 C 478.29575,322.85634 478.53111,322.59638 479.20475,323.15149 C 481.95923,320.93848 496.34001,306.25465 502.61100,296.27649 C 500.08842,293.80733 494.89908,293.21951 491.67350,290.74524 z "
+ id="path2954"
+ sodipodi:nodetypes="cccccccc" />
+ <path
+ style="font-size:12.000000;fill:none;fill-opacity:0.29729697;fill-rule:evenodd;stroke:#000000;stroke-width:1.7924063;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-opacity:0.027149322"
+ d="M 491.67350,290.74524 C 489.56264,292.14465 474.46858,315.88005 473.92350,319.90149 C 474.08915,319.99277 474.24280,320.54490 474.07975,320.46399 C 467.56083,324.58038 466.36005,333.74960 462.39225,337.49524 C 469.66515,335.09880 476.01586,329.63350 478.61100,323.08899 C 478.29575,322.85634 478.53111,322.59638 479.20475,323.15149 C 481.95923,320.93848 496.34001,306.25465 502.61100,296.27649 C 500.08842,293.80733 494.89908,293.21951 491.67350,290.74524 z "
+ id="path2993"
+ sodipodi:nodetypes="cccccccc" />
+ <path
+ style="font-size:12.000000;fill:none;fill-opacity:0.29729697;fill-rule:evenodd;stroke:#000000;stroke-width:2.2703812;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-opacity:0.027149322"
+ d="M 491.67350,290.74524 C 489.56264,292.14465 474.46858,315.88005 473.92350,319.90149 C 474.08915,319.99277 474.24280,320.54490 474.07975,320.46399 C 467.56083,324.58038 466.36005,333.74960 462.39225,337.49524 C 469.66515,335.09880 476.01586,329.63350 478.61100,323.08899 C 478.29575,322.85634 478.53111,322.59638 479.20475,323.15149 C 481.95923,320.93848 496.34001,306.25465 502.61100,296.27649 C 500.08842,293.80733 494.89908,293.21951 491.67350,290.74524 z "
+ id="path2995"
+ sodipodi:nodetypes="cccccccc" />
+ <path
+ style="font-size:12.000000;fill:none;fill-opacity:0.29729697;fill-rule:evenodd;stroke:#000000;stroke-width:2.7483566;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-opacity:0.027149322"
+ d="M 491.67350,290.74524 C 489.56264,292.14465 474.46858,315.88005 473.92350,319.90149 C 474.08915,319.99277 474.24280,320.54490 474.07975,320.46399 C 467.56083,324.58038 466.36005,333.74960 462.39225,337.49524 C 469.66515,335.09880 476.01586,329.63350 478.61100,323.08899 C 478.29575,322.85634 478.53111,322.59638 479.20475,323.15149 C 481.95923,320.93848 496.34001,306.25465 502.61100,296.27649 C 500.08842,293.80733 494.89908,293.21951 491.67350,290.74524 z "
+ id="path2997"
+ sodipodi:nodetypes="cccccccc" />
+ <path
+ style="font-size:12.000000;fill:none;fill-opacity:0.29729697;fill-rule:evenodd;stroke:#000000;stroke-width:3.4653189;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-opacity:0.027149322"
+ d="M 491.67350,290.74524 C 489.56264,292.14465 474.46858,315.88005 473.92350,319.90149 C 474.08915,319.99277 474.24280,320.54490 474.07975,320.46399 C 467.56083,324.58038 466.36005,333.74960 462.39225,337.49524 C 469.66515,335.09880 476.01586,329.63350 478.61100,323.08899 C 478.29575,322.85634 478.53111,322.59638 479.20475,323.15149 C 481.95923,320.93848 496.34001,306.25465 502.61100,296.27649 C 500.08842,293.80733 494.89908,293.21951 491.67350,290.74524 z "
+ id="path2999"
+ sodipodi:nodetypes="cccccccc" />
+ <path
+ style="font-size:12.000000;fill:none;fill-opacity:0.29729697;fill-rule:evenodd;stroke:#000000;stroke-width:4.5407624;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-opacity:0.027149322"
+ d="M 491.67350,290.74524 C 489.56264,292.14465 474.46858,315.88005 473.92350,319.90149 C 474.08915,319.99277 474.24280,320.54490 474.07975,320.46399 C 467.56083,324.58038 466.36005,333.74960 462.39225,337.49524 C 469.66515,335.09880 476.01586,329.63350 478.61100,323.08899 C 478.29575,322.85634 478.53111,322.59638 479.20475,323.15149 C 481.95923,320.93848 496.34001,306.25465 502.61100,296.27649 C 500.08842,293.80733 494.89908,293.21951 491.67350,290.74524 z "
+ id="path3001"
+ sodipodi:nodetypes="cccccccc" />
+ <path
+ style="font-size:12.000000;fill:none;fill-opacity:0.29729697;fill-rule:evenodd;stroke:#000000;stroke-width:4.5407624;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-opacity:0.027149322"
+ d="M 491.67350,290.74524 C 489.56264,292.14465 474.46858,315.88005 473.92350,319.90149 C 474.08915,319.99277 474.24280,320.54490 474.07975,320.46399 C 467.56083,324.58038 466.36005,333.74960 462.39225,337.49524 C 469.66515,335.09880 476.01586,329.63350 478.61100,323.08899 C 478.29575,322.85634 478.53111,322.59638 479.20475,323.15149 C 481.95923,320.93848 496.34001,306.25465 502.61100,296.27649 C 500.08842,293.80733 494.89908,293.21951 491.67350,290.74524 z "
+ id="path3003"
+ sodipodi:nodetypes="cccccccc" />
+ </g>
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path938"
+ d="M 30.205102,34.228614 C 23.906643,38.672669 22.743245,48.555533 18.909630,52.599327 C 25.936571,50.012119 32.081349,44.132293 34.588724,37.066839 C 33.364061,36.056960 31.643233,35.026039 30.205102,34.228614 z "
+ style="font-size:12.000000;fill:url(#linearGradient1421);fill-opacity:1.0000000;fill-rule:evenodd;stroke:url(#linearGradient1423);stroke-width:0.78106284;stroke-linejoin:round;stroke-miterlimit:4.0000000" />
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path12835"
+ d="M 30.617265,35.339501 C 27.907735,37.564006 24.907867,42.276687 23.152123,48.230671 C 27.752064,46.074807 31.876663,41.684797 33.559712,37.157947 C 32.737666,36.510921 31.582586,35.850411 30.617265,35.339501 z "
+ style="font-size:12.000000;fill:#e1e1e1;fill-opacity:0.31372550;fill-rule:evenodd;stroke:none;stroke-width:0.77429527;stroke-linejoin:round;stroke-opacity:1.0000000" />
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path12853"
+ d="M 31.194413,35.339501 C 29.016341,37.170395 26.604888,41.049182 25.193520,45.949638 C 28.891201,44.175240 32.206788,40.562023 33.559712,36.836183 C 32.898902,36.303648 31.970392,35.760006 31.194413,35.339501 z "
+ style="font-size:12.000000;fill:#ebebeb;fill-opacity:0.31372550;fill-rule:evenodd;stroke:none;stroke-width:0.77429527;stroke-linejoin:round;stroke-opacity:1.0000000" />
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path12855"
+ d="M 31.535862,35.339501 C 29.672214,36.937525 27.608876,40.322968 26.401246,44.600137 C 29.565142,43.051430 32.402092,39.897767 33.559712,36.645817 C 32.994294,36.181017 32.199822,35.706522 31.535862,35.339501 z "
+ style="font-size:12.000000;fill:#f5f5f5;fill-opacity:0.31372550;fill-rule:evenodd;stroke:none;stroke-width:0.77429527;stroke-linejoin:round;stroke-opacity:1.0000000" />
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path12857"
+ d="M 31.877311,35.339501 C 30.328087,36.471786 29.148090,38.870538 28.144199,41.901137 C 30.774308,40.803799 32.597396,38.569265 33.559712,36.265096 C 33.089685,35.935753 32.429251,35.599555 31.877311,35.339501 z "
+ style="font-size:12.000000;fill:#ffffff;fill-opacity:0.31221721;fill-rule:evenodd;stroke:none;stroke-width:0.77429527;stroke-linejoin:round;stroke-opacity:1.0000000" />
+ <g
+ id="g2174">
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path672"
+ d="M 30.061161,33.612605 C 31.056578,34.225526 33.958195,35.999839 35.166936,37.112820 C 37.828263,34.723643 51.706037,18.866520 57.764951,8.0940971 C 55.327672,5.4283921 50.326572,4.7999241 47.210077,2.1287023 C 45.170603,3.6395058 30.587806,29.271058 30.061161,33.612605 z "
+ style="font-size:12.000000;fill:url(#linearGradient1425);fill-opacity:1.0000000;fill-rule:evenodd;stroke:url(#linearGradient1428);stroke-width:0.36612317;stroke-miterlimit:4.0000000" />
+ <g
+ id="g2947"
+ transform="matrix(0.265500,1.659133e-2,2.488336e-2,-0.224834,-116.5236,67.75015)">
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path678"
+ d="M 544.06785,185.23884 C 561.08243,232.34141 580.07425,278.58522 603.52211,323.56081 C 599.37466,326.36530 596.20938,328.27876 592.98790,329.80588 C 570.09983,281.67195 552.65324,238.19755 537.96578,188.87058 C 540.53253,187.99599 540.34623,186.72968 544.06785,185.23884 z "
+ style="font-size:12.000000;fill:#45454e;fill-opacity:0.29729697;fill-rule:evenodd;stroke-width:1.0000000pt" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path680"
+ d="M 543.15031,185.88232 C 560.16489,232.98489 578.52789,278.42020 601.97577,323.39579 C 596.82690,324.29588 596.15986,324.48065 592.75040,324.68463 C 569.86231,276.55070 553.21963,237.11949 538.53218,187.79252 C 541.01119,186.88289 539.42870,187.37316 543.15031,185.88232 z "
+ style="font-size:12.000000;fill:#45454e;fill-opacity:0.29729697;fill-rule:evenodd;stroke-width:1.0000000pt" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path681"
+ d="M 542.08466,186.70727 C 559.09925,233.80985 576.02594,277.39172 599.47383,322.36731 C 594.32494,323.26740 597.13301,321.61744 593.72352,321.82142 C 570.83545,273.68748 554.05263,236.74635 539.36517,187.41938 C 542.09871,187.02170 538.36305,188.19811 542.08466,186.70727 z "
+ style="font-size:12.000000;fill:#45454e;fill-opacity:0.29729697;fill-rule:evenodd;stroke-width:1.0000000pt" />
+ </g>
+ </g>
+ </g>
+ </g>
+</svg>
diff --git a/chalk/plugins/tools/selectiontools/tool_brush_selection_cursor.png b/chalk/plugins/tools/selectiontools/tool_brush_selection_cursor.png
new file mode 100644
index 00000000..96929d8f
--- /dev/null
+++ b/chalk/plugins/tools/selectiontools/tool_brush_selection_cursor.png
Binary files differ
diff --git a/chalk/plugins/tools/selectiontools/tool_contiguous_selection.png b/chalk/plugins/tools/selectiontools/tool_contiguous_selection.png
new file mode 100644
index 00000000..fcc8f36d
--- /dev/null
+++ b/chalk/plugins/tools/selectiontools/tool_contiguous_selection.png
Binary files differ
diff --git a/chalk/plugins/tools/selectiontools/tool_contiguous_selection_cursor.png b/chalk/plugins/tools/selectiontools/tool_contiguous_selection_cursor.png
new file mode 100644
index 00000000..0e3572cd
--- /dev/null
+++ b/chalk/plugins/tools/selectiontools/tool_contiguous_selection_cursor.png
Binary files differ
diff --git a/chalk/plugins/tools/selectiontools/tool_elliptical_selection.png b/chalk/plugins/tools/selectiontools/tool_elliptical_selection.png
new file mode 100644
index 00000000..ad585848
--- /dev/null
+++ b/chalk/plugins/tools/selectiontools/tool_elliptical_selection.png
Binary files differ
diff --git a/chalk/plugins/tools/selectiontools/tool_elliptical_selection.svg b/chalk/plugins/tools/selectiontools/tool_elliptical_selection.svg
new file mode 100644
index 00000000..31ff66f4
--- /dev/null
+++ b/chalk/plugins/tools/selectiontools/tool_elliptical_selection.svg
@@ -0,0 +1,256 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://web.resource.org/cc/"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://inkscape.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="48.000000pt"
+ height="48.000000pt"
+ id="svg1409"
+ sodipodi:version="0.32"
+ inkscape:version="0.41"
+ sodipodi:docbase="/home/danny/work/kde/koffice/chalk/chalk"
+ sodipodi:docname="tool_elliptical_selection.svg"
+ inkscape:export-filename="/home/danny/work/kde/koffice/chalk/chalk/tool_elliptical_selection.png"
+ inkscape:export-xdpi="33.000000"
+ inkscape:export-ydpi="33.000000">
+ <defs
+ id="defs3">
+ <linearGradient
+ gradientUnits="userSpaceOnUse"
+ y2="36.873619"
+ x2="39.857029"
+ y1="4.5492039"
+ x1="10.878086"
+ gradientTransform="matrix(1.325250,0.000000,0.000000,1.003779,-5.702957,1.287849)"
+ id="linearGradient9512"
+ xlink:href="#light90to0"
+ inkscape:collect="always" />
+ <radialGradient
+ gradientUnits="userSpaceOnUse"
+ r="31.677956"
+ fy="46.914463"
+ fx="48.488476"
+ cy="46.914463"
+ cx="48.488476"
+ gradientTransform="matrix(1.261963,0.000000,0.000000,1.016360,-7.978266,-0.517425)"
+ id="radialGradient10280"
+ xlink:href="#light90to0"
+ inkscape:collect="always" />
+ <linearGradient
+ id="light90to0">
+ <stop
+ id="stop1890"
+ offset="0.0000000"
+ style="stop-color:#ffffff;stop-opacity:0.90833336;" />
+ <stop
+ id="stop1892"
+ offset="1.0000000"
+ style="stop-color:#ffffff;stop-opacity:0.0000000;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#light90to0"
+ id="linearGradient1331"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.325250,0.000000,0.000000,1.003779,-5.702957,1.287849)"
+ x1="10.878086"
+ y1="4.5492039"
+ x2="39.857029"
+ y2="36.873619" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#light90to0"
+ id="radialGradient1333"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.261963,0.000000,0.000000,1.016360,-7.978266,-0.517425)"
+ cx="48.488476"
+ cy="46.914463"
+ fx="48.488476"
+ fy="46.914463"
+ r="31.677956" />
+ <radialGradient
+ r="31.677956"
+ fy="46.914463"
+ fx="48.488476"
+ cy="46.914463"
+ cx="48.488476"
+ gradientTransform="matrix(1.181248,0.000000,0.000000,0.943878,-77.46799,5.346100)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient2089"
+ xlink:href="#light90to0"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="36.873619"
+ x2="39.857029"
+ y1="4.5492039"
+ x1="10.878086"
+ gradientTransform="matrix(1.240487,0.000000,0.000000,0.932195,-75.33821,7.022631)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient2092"
+ xlink:href="#light90to0"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="36.873619"
+ x2="39.857029"
+ y1="4.5492039"
+ x1="10.878086"
+ gradientTransform="matrix(1.240487,0.000000,0.000000,0.932195,-75.33821,7.022631)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient3660"
+ xlink:href="#light90to0"
+ inkscape:collect="always" />
+ <radialGradient
+ r="31.677956"
+ fy="46.914463"
+ fx="48.488476"
+ cy="46.914463"
+ cx="48.488476"
+ gradientTransform="matrix(1.181248,0.000000,0.000000,0.943878,-77.46799,5.346100)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient3662"
+ xlink:href="#light90to0"
+ inkscape:collect="always" />
+ <radialGradient
+ r="31.677956"
+ fy="46.914463"
+ fx="48.488476"
+ cy="46.914463"
+ cx="48.488476"
+ gradientTransform="matrix(1.472290,0.000000,0.000000,1.178586,-15.47463,-0.337081)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient3665"
+ xlink:href="#light90to0"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="36.873619"
+ x2="39.857029"
+ y1="4.5492039"
+ x1="10.878086"
+ gradientTransform="matrix(1.546124,0.000000,0.000000,1.163997,-42.82010,1.756341)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient3668"
+ xlink:href="#light90to0"
+ inkscape:collect="always" />
+ <radialGradient
+ r="31.677956"
+ fy="46.914463"
+ fx="48.488476"
+ cy="46.914463"
+ cx="48.488476"
+ gradientTransform="matrix(1.472290,0.000000,0.000000,1.178586,-15.47463,-0.337081)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient3678"
+ xlink:href="#light90to0"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="36.873619"
+ x2="39.857029"
+ y1="4.5492039"
+ x1="10.878086"
+ gradientTransform="matrix(1.546124,0.000000,0.000000,1.163997,-12.82010,1.756341)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient3682"
+ xlink:href="#light90to0"
+ inkscape:collect="always" />
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="4.3288472"
+ inkscape:cx="33.946093"
+ inkscape:cy="27.610797"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ inkscape:document-units="px"
+ inkscape:grid-bbox="true"
+ inkscape:window-width="1020"
+ inkscape:window-height="691"
+ inkscape:window-x="0"
+ inkscape:window-y="0" />
+ <metadata
+ id="metadata4">
+ <rdf:RDF
+ id="RDF5">
+ <cc:Work
+ rdf:about=""
+ id="Work6">
+ <dc:format
+ id="format7">image/svg+xml</dc:format>
+ <dc:type
+ id="type9"
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ id="layer1"
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer">
+ <path
+ id="rect7971"
+ d="M 30.000000,7.1250000 C 22.317773,7.1250000 15.355679,9.5078220 10.156250,13.500000 C 4.9568200,17.492177 1.4062500,23.269928 1.4062500,29.968750 C 1.4062500,36.667572 4.9568200,42.507823 10.156250,46.500000 C 15.355679,50.492180 22.317774,52.875000 30.000000,52.875000 C 37.682225,52.875002 44.675571,50.492178 49.875000,46.500000 C 55.074429,42.507825 58.593750,36.667572 58.593750,29.968750 C 58.593752,23.269928 55.074430,17.492177 49.875000,13.500000 C 44.675570,9.5078222 37.682226,7.1250000 30.000000,7.1250000 z "
+ style="opacity:0.79446638;fill:#0028c6;fill-opacity:0.18099548;stroke:#000000;stroke-width:0.0000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:0.035294119" />
+ <path
+ id="path8746"
+ d="M 30.000000,7.1250000 C 22.317773,7.1250000 15.355679,9.5078220 10.156250,13.500000 C 4.9568200,17.492177 1.4062500,23.269928 1.4062500,29.968750 C 1.4062500,35.373532 3.7824490,40.170227 7.4062500,43.937500 C 25.754627,28.015820 45.616873,27.218125 56.187500,20.750000 C 54.657054,17.958644 52.482639,15.502173 49.875000,13.500000 C 44.675570,9.5078222 37.682226,7.1250000 30.000000,7.1250000 z "
+ style="opacity:0.79446638;fill:url(#linearGradient3682);fill-opacity:1.0000000;stroke:#000000;stroke-width:0.0000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:0.035294119" />
+ <path
+ id="path9514"
+ d="M 30.000000,7.1250000 C 22.317773,7.1250000 15.355679,9.5078220 10.156250,13.500000 C 4.9568200,17.492177 1.4062500,23.269928 1.4062500,29.968750 C 1.4062500,36.667572 4.9568202,42.507823 10.156250,46.500000 C 15.355679,50.492180 22.317774,52.875000 30.000000,52.875000 C 37.682225,52.875002 44.675571,50.492178 49.875000,46.500000 C 55.074429,42.507825 58.593750,36.667572 58.593750,29.968750 C 58.593752,23.269928 55.074430,17.492177 49.875000,13.500000 C 44.675570,9.5078222 37.682226,7.1250000 30.000000,7.1250000 z "
+ style="opacity:0.97233200;fill:url(#radialGradient3678);fill-opacity:1.0000000;stroke:#000000;stroke-width:0.0000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:0.035294119" />
+ <g
+ transform="matrix(1.034994,0.000000,0.000000,0.947886,-1.049820,1.606088)"
+ id="g2879">
+ <path
+ sodipodi:nodetypes="cccccccc"
+ id="path2095"
+ d="M 15.715627,7.8733917 C 14.686976,8.3945360 14.043469,9.5270380 14.459506,10.644495 C 14.875544,11.761955 16.112458,12.333045 17.222232,11.920064 C 20.059953,10.583282 22.969503,9.5338180 25.735394,8.7716720 C 26.485511,8.5331940 27.042274,7.8985157 27.184094,7.1202427 C 27.325911,6.3419677 27.029771,5.5463973 26.413534,5.0501646 C 25.797297,4.5539337 25.042091,4.5727734 24.237406,4.7473875 C 21.253154,5.3584125 18.484391,6.3285845 15.715627,7.8733917 z "
+ style="fill:#313436;fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:5.5999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000" />
+ <path
+ sodipodi:nodetypes="cccccccc"
+ id="path2863"
+ d="M 15.040511,52.036580 C 14.011860,51.515436 13.368353,50.382934 13.784390,49.265477 C 14.200428,48.148017 15.437342,47.576927 16.547116,47.989908 C 19.384837,49.326690 22.294387,50.376154 25.060278,51.138300 C 25.810395,51.376778 26.367158,52.011456 26.508978,52.789729 C 26.650795,53.568004 26.354655,54.363575 25.738418,54.859807 C 25.122181,55.356038 24.366975,55.337199 23.562290,55.162585 C 20.578038,54.551560 17.809275,53.581388 15.040511,52.036580 z "
+ style="fill:#313436;fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:5.5999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000" />
+ <path
+ sodipodi:nodetypes="cccccccc"
+ id="path2865"
+ d="M 44.959488,7.8733920 C 45.988139,8.3945360 46.631646,9.5270380 46.215609,10.644495 C 45.799571,11.761955 44.562657,12.333045 43.452883,11.920064 C 40.615162,10.583282 37.705612,9.5338180 34.939721,8.7716720 C 34.189604,8.5331940 33.632841,7.8985160 33.491021,7.1202430 C 33.349204,6.3419677 33.645344,5.5463973 34.261581,5.0501646 C 34.877818,4.5539337 35.633024,4.5727734 36.437709,4.7473875 C 39.421961,5.3584125 42.190724,6.3285845 44.959488,7.8733920 z "
+ style="fill:#313436;fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:5.5999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000" />
+ <path
+ sodipodi:nodetypes="cccccccc"
+ id="path2867"
+ d="M 44.284370,52.036580 C 45.313021,51.515436 45.956528,50.382934 45.540491,49.265477 C 45.124453,48.148017 43.887539,47.576927 42.777765,47.989908 C 39.940044,49.326690 37.030494,50.376154 34.264603,51.138300 C 33.514486,51.376778 32.957723,52.011456 32.815903,52.789729 C 32.674086,53.568004 32.970226,54.363575 33.586463,54.859807 C 34.202700,55.356038 34.957906,55.337199 35.762591,55.162585 C 38.746843,54.551560 41.515606,53.581388 44.284370,52.036580 z "
+ style="fill:#313436;fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:5.5999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000" />
+ <path
+ sodipodi:nodetypes="cccccccc"
+ id="path2869"
+ d="M 1.1508292,24.851646 C 0.79196783,25.947517 1.1377395,27.203345 2.2220836,27.699323 C 3.3064305,28.195304 4.5848824,27.724495 5.0775894,26.647745 C 6.1389136,23.695925 7.4541930,20.896480 8.8710548,18.401782 C 9.2328376,17.702738 9.1777437,16.860263 8.7277037,16.209658 C 8.2776597,15.559055 7.5057040,15.205904 6.7190689,15.290760 C 5.9324353,15.375617 5.4117458,15.922950 4.9662183,16.615419 C 3.2880935,19.157664 2.0162977,21.801490 1.1508292,24.851646 z "
+ style="fill:#313436;fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:5.5999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000" />
+ <path
+ sodipodi:nodetypes="cccccccc"
+ id="path2871"
+ d="M 58.849170,35.058325 C 59.208032,33.962455 58.862260,32.706627 57.777916,32.210649 C 56.693569,31.714668 55.415117,32.185477 54.922410,33.262227 C 53.861086,36.214047 52.545807,39.013492 51.128945,41.508190 C 50.767162,42.207234 50.822256,43.049709 51.272296,43.700314 C 51.722340,44.350917 52.494296,44.704067 53.280930,44.619212 C 54.067564,44.534355 54.588254,43.987022 55.033782,43.294553 C 56.711907,40.752308 57.983702,38.108482 58.849170,35.058325 z "
+ style="fill:#313436;fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:5.5999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000" />
+ <path
+ sodipodi:nodetypes="cccccccc"
+ id="path2873"
+ d="M 4.3255135,45.237875 C 4.8466574,46.266526 5.9791594,46.910033 7.0966154,46.493995 C 8.2140765,46.077958 8.7851655,44.841044 8.3721854,43.731270 C 7.0354024,40.893548 5.9859395,37.983999 5.2237936,35.218107 C 4.9853145,34.467990 4.3506365,33.911227 3.5723636,33.769407 C 2.7940894,33.627590 1.9985185,33.923730 1.5022854,34.539967 C 1.0060545,35.156204 1.0248945,35.911410 1.1995086,36.716095 C 1.8105334,39.700347 2.7807056,42.469110 4.3255135,45.237875 z "
+ style="fill:#313436;fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:5.5999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000" />
+ <path
+ sodipodi:nodetypes="cccccccc"
+ id="path2875"
+ d="M 55.674487,14.672098 C 55.153343,13.643446 54.020841,12.999939 52.903385,13.415977 C 51.785924,13.832014 51.214835,15.068929 51.627815,16.178702 C 52.964598,19.016424 54.014061,21.925973 54.776208,24.691864 C 55.014687,25.441982 55.649364,25.998745 56.427637,26.140565 C 57.205913,26.282381 58.001483,25.986242 58.497714,25.370005 C 58.993947,24.753768 58.975106,23.998562 58.800494,23.193876 C 58.189469,20.209624 57.219295,17.440862 55.674487,14.672098 z "
+ style="fill:#313436;fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:5.5999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000" />
+ </g>
+ </g>
+</svg>
diff --git a/chalk/plugins/tools/selectiontools/tool_elliptical_selection_cursor.png b/chalk/plugins/tools/selectiontools/tool_elliptical_selection_cursor.png
new file mode 100644
index 00000000..5e02f87b
--- /dev/null
+++ b/chalk/plugins/tools/selectiontools/tool_elliptical_selection_cursor.png
Binary files differ
diff --git a/chalk/plugins/tools/selectiontools/tool_eraser_selection.png b/chalk/plugins/tools/selectiontools/tool_eraser_selection.png
new file mode 100644
index 00000000..ffe2e440
--- /dev/null
+++ b/chalk/plugins/tools/selectiontools/tool_eraser_selection.png
Binary files differ
diff --git a/chalk/plugins/tools/selectiontools/tool_eraser_selection.svg b/chalk/plugins/tools/selectiontools/tool_eraser_selection.svg
new file mode 100644
index 00000000..9c147c1b
--- /dev/null
+++ b/chalk/plugins/tools/selectiontools/tool_eraser_selection.svg
@@ -0,0 +1,1993 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://web.resource.org/cc/"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://inkscape.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="48.000000pt"
+ height="48.000000pt"
+ id="svg11941"
+ sodipodi:version="0.32"
+ inkscape:version="0.41"
+ sodipodi:docbase="/home/danny/work/kde/koffice/chalk/chalk/new"
+ sodipodi:docname="tool_eraser_selection.svg"
+ inkscape:export-filename="/home/danny/work/kde/koffice/chalk/chalk/new/tool_eraser_selection.png"
+ inkscape:export-xdpi="33.000000"
+ inkscape:export-ydpi="33.000000">
+ <defs
+ id="defs3">
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#light90to0"
+ id="linearGradient9512"
+ gradientTransform="matrix(0.996235,0.000000,0.000000,1.003779,-3.391158,13.41516)"
+ x1="10.878086"
+ y1="4.5492039"
+ x2="39.857029"
+ y2="36.873619"
+ gradientUnits="userSpaceOnUse" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#light90to0"
+ id="radialGradient10280"
+ gradientTransform="matrix(0.983903,0.000000,0.000000,1.016360,-3.999998,12.41516)"
+ cx="48.488476"
+ cy="46.914463"
+ fx="48.488476"
+ fy="46.914463"
+ r="31.677956"
+ gradientUnits="userSpaceOnUse" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#light90to0"
+ id="radialGradient7969"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.000000,-2.592685,0.379735,0.000000,-30.45690,-1.224420)"
+ cx="-23.859682"
+ cy="95.221397"
+ fx="-23.859682"
+ fy="95.221397"
+ r="8.5514765" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#light90to0"
+ id="linearGradient7967"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.000000,-2.503650,0.399417,0.000000,-30.45690,-1.829360)"
+ x1="-16.569721"
+ y1="81.885979"
+ x2="-21.621279"
+ y2="85.112236" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#light90to0"
+ id="radialGradient7965"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.000000,-2.592685,0.379735,0.000000,-30.45690,-21.22442)"
+ cx="-23.859682"
+ cy="95.221397"
+ fx="-23.859682"
+ fy="95.221397"
+ r="8.5514765" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#light90to0"
+ id="linearGradient7963"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.000000,-2.503650,0.399417,0.000000,-30.45690,-21.82936)"
+ x1="-16.569721"
+ y1="81.885979"
+ x2="-21.621279"
+ y2="85.112236" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#light90to0"
+ id="radialGradient7961"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.000000,-2.592685,0.379735,0.000000,26.44710,-11.22442)"
+ cx="-23.859682"
+ cy="95.221397"
+ fx="-23.859682"
+ fy="95.221397"
+ r="8.5514765" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#light90to0"
+ id="linearGradient7959"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.000000,-2.503650,0.399417,0.000000,26.44710,-11.82936)"
+ x1="-16.569721"
+ y1="81.885979"
+ x2="-21.621279"
+ y2="85.112236" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#light90to0"
+ id="radialGradient7957"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.633416,0.000000,0.000000,0.379735,-44.86332,44.21180)"
+ cx="25.952410"
+ cy="52.497688"
+ fx="25.923746"
+ fy="51.904903"
+ r="14.270030" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#light90to0"
+ id="linearGradient7955"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.503650,0.000000,0.000000,0.399417,-44.86332,44.21180)"
+ x1="22.425571"
+ y1="35.206337"
+ x2="22.396454"
+ y2="41.545322" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#light90to0"
+ id="radialGradient7953"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.633416,0.000000,0.000000,0.379735,-22.86332,44.21180)"
+ cx="25.952410"
+ cy="52.497688"
+ fx="25.923746"
+ fy="51.904903"
+ r="14.270030" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#light90to0"
+ id="linearGradient7951"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.503650,0.000000,0.000000,0.399417,-22.86332,44.21180)"
+ x1="22.425571"
+ y1="35.206337"
+ x2="22.396454"
+ y2="41.545322" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#light90to0"
+ id="radialGradient7949"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.633416,0.000000,0.000000,0.379735,-38.65916,-12.48664)"
+ cx="25.952410"
+ cy="52.497688"
+ fx="25.923746"
+ fy="51.904903"
+ r="14.270030" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#light90to0"
+ id="linearGradient7947"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.503650,0.000000,0.000000,0.399417,-38.65916,-12.48664)"
+ x1="22.425571"
+ y1="35.206337"
+ x2="22.396454"
+ y2="41.545322" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#light90to0"
+ id="linearGradient7945"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.000000,-2.503650,0.399417,0.000000,26.44710,4.170640)"
+ x1="-16.569721"
+ y1="81.885979"
+ x2="-21.621279"
+ y2="85.112236" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#light90to0"
+ id="radialGradient7943"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.878497,0.000000,0.000000,1.138308,-18.65916,-0.486640)"
+ cx="92.643608"
+ cy="55.457653"
+ fx="92.643608"
+ fy="55.457653"
+ r="9.9914455" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#light90to0"
+ id="radialGradient7941"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.000000,-2.592685,0.379735,0.000000,26.44710,-31.22442)"
+ cx="-23.859682"
+ cy="95.221397"
+ fx="-23.859682"
+ fy="95.221397"
+ r="8.5514765" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#light90to0"
+ id="linearGradient7939"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.000000,-2.503650,0.399417,0.000000,26.44710,-31.82936)"
+ x1="-16.569721"
+ y1="81.885979"
+ x2="-21.621279"
+ y2="85.112236" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#light90to0"
+ id="radialGradient7937"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.633416,0.000000,0.000000,0.379735,-16.65916,-12.48664)"
+ cx="25.952410"
+ cy="52.497688"
+ fx="25.923746"
+ fy="51.904903"
+ r="14.270030" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#light90to0"
+ id="linearGradient7935"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.503650,0.000000,0.000000,0.399417,-16.65916,-12.48664)"
+ x1="22.425571"
+ y1="35.206337"
+ x2="22.396454"
+ y2="41.545322" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#light90to0"
+ id="radialGradient7933"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="scale(0.665867,1.501801)"
+ cx="8.0907059"
+ cy="9.5002232"
+ fx="8.0907059"
+ fy="9.5002232"
+ r="5.8189325" />
+ <linearGradient
+ id="light90to0">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.90833336;"
+ offset="0.0000000"
+ id="stop1890" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.0000000;"
+ offset="1.0000000"
+ id="stop1892" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#light90to0"
+ id="linearGradient7931"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.791643,0.000000,0.000000,1.263196,-1.626700,-5.630763)"
+ x1="4.4536543"
+ y1="6.5494914"
+ x2="14.101834"
+ y2="13.431447" />
+ <linearGradient
+ id="wihitetolightgray">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1.0000000;"
+ offset="0.0000000"
+ id="stop1885" />
+ <stop
+ style="stop-color:#d5d4d4;stop-opacity:1.0000000;"
+ offset="1.0000000"
+ id="stop1886" />
+ </linearGradient>
+ <linearGradient
+ id="orangemoretoyelow">
+ <stop
+ style="stop-color:#ff0d00;stop-opacity:1.0000000;"
+ offset="0.0000000"
+ id="stop2671" />
+ <stop
+ style="stop-color:#ff3900;stop-opacity:1.0000000;"
+ offset="0.74641621"
+ id="stop2679" />
+ <stop
+ style="stop-color:#d05521;stop-opacity:1.0000000;"
+ offset="1.0000000"
+ id="stop2672" />
+ </linearGradient>
+ <linearGradient
+ id="graytoblack">
+ <stop
+ style="stop-color:#7d7d7d;stop-opacity:1.0000000;"
+ offset="0.0000000"
+ id="stop5097" />
+ <stop
+ style="stop-color:#000000;stop-opacity:1.0000000;"
+ offset="1.0000000"
+ id="stop5098" />
+ </linearGradient>
+ <linearGradient
+ id="shadow100to0">
+ <stop
+ style="stop-color:#000000;stop-opacity:1.0000000;"
+ offset="0.0000000"
+ id="stop3425" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0.0000000;"
+ offset="1.0000000"
+ id="stop3426" />
+ </linearGradient>
+ <linearGradient
+ id="light50to25to7">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.47450981;"
+ offset="0.0000000"
+ id="stop2791" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.25833333;"
+ offset="0.50000000"
+ id="stop2795" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.10833333;"
+ offset="1.0000000"
+ id="stop2793" />
+ </linearGradient>
+ <linearGradient
+ id="orangetoblackorange">
+ <stop
+ style="stop-color:#ff8b00;stop-opacity:1.0000000;"
+ offset="0.0000000"
+ id="stop4207" />
+ <stop
+ style="stop-color:#4d0200;stop-opacity:1.0000000;"
+ offset="1.0000000"
+ id="stop4209" />
+ </linearGradient>
+ <linearGradient
+ id="light100to0">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1.0000000;"
+ offset="0.0000000"
+ id="stop2764" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.0000000;"
+ offset="1.0000000"
+ id="stop2765" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#wihitetolightgray"
+ id="radialGradient13045"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.281643,-1.886110e-2,0.000000,0.179517,-4.383105,-16.75305)"
+ cx="86.514435"
+ cy="332.37268"
+ fx="86.514435"
+ fy="332.37268"
+ r="83.259750" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#light100to0"
+ id="linearGradient13047"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.281643,-1.886110e-2,0.000000,0.179517,-4.383105,-16.75305)"
+ x1="86.514435"
+ y1="335.76117"
+ x2="73.286217"
+ y2="247.07323" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#wihitetolightgray"
+ id="linearGradient13049"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.195716,-1.310673e-2,0.000000,0.258334,-4.383105,-16.75305)"
+ x1="132.72992"
+ y1="279.47504"
+ x2="84.003502"
+ y2="210.46336" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#light100to0"
+ id="linearGradient13051"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.195716,-1.310673e-2,0.000000,0.258334,-4.383105,-16.75305)"
+ x1="136.55682"
+ y1="213.43617"
+ x2="54.607849"
+ y2="250.54321" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#wihitetolightgray"
+ id="linearGradient13053"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.195716,-1.310673e-2,0.000000,0.258334,-4.383105,-16.75305)"
+ x1="145.42192"
+ y1="264.70230"
+ x2="198.28532"
+ y2="218.74910" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#light100to0"
+ id="linearGradient13055"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.180988,-1.212046e-2,0.000000,0.279356,-4.383105,-16.75305)"
+ x1="159.18221"
+ y1="219.68500"
+ x2="184.11906"
+ y2="234.35374" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#orangemoretoyelow"
+ id="linearGradient13057"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.273196,-8.526361e-2,0.000000,0.785425,-7.025630e-17,2.371150e-16)"
+ x1="36.606781"
+ y1="4.8842254"
+ x2="28.653791"
+ y2="47.244961" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#light100to0"
+ id="linearGradient13059"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.286285,-1.917198e-2,0.000000,0.176607,-4.383105,-16.75305)"
+ x1="134.59328"
+ y1="300.55457"
+ x2="126.82574"
+ y2="189.89319" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#orangemoretoyelow"
+ id="linearGradient13061"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.870407,-5.828951e-2,0.000000,1.148888,-7.025630e-17,2.371150e-16)"
+ x1="77.830383"
+ y1="43.692036"
+ x2="40.120766"
+ y2="18.127838" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#light100to0"
+ id="linearGradient13063"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.218024,-1.460066e-2,0.000000,0.231901,-4.383105,-16.75305)"
+ x1="188.09673"
+ y1="173.35371"
+ x2="269.30646"
+ y2="220.31316" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#graytoblack"
+ id="linearGradient13065"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.262073,-1.755056e-2,0.000000,0.217660,-4.383105,-17.56717)"
+ spreadMethod="reflect"
+ x1="138.68466"
+ y1="221.05045"
+ x2="90.955330"
+ y2="574.66980" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#shadow100to0"
+ id="linearGradient13067"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.273027,-1.828417e-2,0.000000,0.185183,-4.383100,-12.51208)"
+ x1="124.51332"
+ y1="199.20517"
+ x2="99.415497"
+ y2="224.95407" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#shadow100to0"
+ id="linearGradient13069"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.273027,-1.828417e-2,0.000000,0.185183,-4.383100,-12.51208)"
+ x1="124.51332"
+ y1="199.20517"
+ x2="99.415497"
+ y2="224.95407" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#shadow100to0"
+ id="linearGradient13071"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.273027,-1.828417e-2,0.000000,0.185183,-4.383100,-12.51208)"
+ x1="163.74318"
+ y1="301.15747"
+ x2="137.31036"
+ y2="301.15750" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#light50to25to7"
+ id="radialGradient13073"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.282097,-1.889158e-2,0.000000,0.179229,-4.383100,-12.51208)"
+ cx="145.82777"
+ cy="265.90030"
+ fx="145.82777"
+ fy="265.90030"
+ r="24.113470" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#orangetoblackorange"
+ id="linearGradient13075"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.302207,-2.036411e-2,1.731823e-2,0.187588,-5.784573,-19.06245)"
+ spreadMethod="reflect"
+ x1="119.80309"
+ y1="179.83293"
+ x2="129.06503"
+ y2="189.54620" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#orangetoblackorange"
+ id="linearGradient13077"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.302207,-2.036411e-2,1.731823e-2,0.187588,-0.406378,-15.67507)"
+ spreadMethod="reflect"
+ x1="119.80309"
+ y1="179.83293"
+ x2="129.06503"
+ y2="189.54620" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#orangetoblackorange"
+ id="linearGradient13079"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.302207,-2.036411e-2,1.731823e-2,0.187588,4.903646,-12.38550)"
+ spreadMethod="reflect"
+ x1="119.80309"
+ y1="179.83293"
+ x2="129.06503"
+ y2="189.54620" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#orangetoblackorange"
+ id="linearGradient13081"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.250582,0.000000,0.000000,0.227641,-4.383105,-17.56717)"
+ spreadMethod="reflect"
+ x1="203.79491"
+ y1="203.68118"
+ x2="120.08266"
+ y2="229.92639" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#light100to0"
+ id="linearGradient13083"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.331788,0.000000,0.000000,0.171926,-4.383100,-17.56719)"
+ x1="24.253796"
+ y1="213.05858"
+ x2="189.53893"
+ y2="213.05858" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#light100to0"
+ id="linearGradient13085"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.182201,0.000000,0.000000,0.313078,-4.383100,-17.56719)"
+ x1="42.080868"
+ y1="215.05040"
+ x2="88.821419"
+ y2="172.01805" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#light100to0"
+ id="linearGradient13087"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.331788,0.000000,0.000000,0.171926,-4.383100,-17.56719)"
+ x1="149.74805"
+ y1="120.63583"
+ x2="144.13652"
+ y2="216.48166" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#graytoblack"
+ id="radialGradient16881"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.281643,-1.886110e-2,0.000000,0.179517,-4.383105,-16.75305)"
+ cx="86.514435"
+ cy="332.37268"
+ fx="86.514435"
+ fy="332.37268"
+ r="83.259750" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#graytoblack"
+ id="linearGradient18401"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.195716,-1.310673e-2,0.000000,0.258334,-4.383105,-16.75305)"
+ x1="132.72992"
+ y1="279.47504"
+ x2="84.003502"
+ y2="210.46336" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#graytoblack"
+ id="linearGradient19163"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.195716,-1.310673e-2,0.000000,0.258334,-4.383105,-16.75305)"
+ x1="145.42192"
+ y1="264.70230"
+ x2="198.28532"
+ y2="218.74910" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#light90to0"
+ id="radialGradient19963"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.000000,-2.142981,0.309244,0.000000,-25.58840,11.38378)"
+ cx="-23.859682"
+ cy="95.221397"
+ fx="-23.859682"
+ fy="95.221397"
+ r="8.5514765" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#light90to0"
+ id="linearGradient19966"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.000000,-2.069389,0.325272,0.000000,-25.58840,10.88376)"
+ x1="-16.569721"
+ y1="81.885979"
+ x2="-21.621279"
+ y2="85.112236" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#light90to0"
+ id="radialGradient19970"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.000000,-2.142981,0.309244,0.000000,-25.58840,-5.893883)"
+ cx="-23.859682"
+ cy="95.221397"
+ fx="-23.859682"
+ fy="95.221397"
+ r="8.5514765" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#light90to0"
+ id="linearGradient19973"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.000000,-2.069389,0.325272,0.000000,-25.58840,-6.393896)"
+ x1="-16.569721"
+ y1="81.885979"
+ x2="-21.621279"
+ y2="85.112236" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#light90to0"
+ id="radialGradient19977"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.000000,-2.142981,0.309244,0.000000,20.66765,1.878457)"
+ cx="-23.859682"
+ cy="95.221397"
+ fx="-23.859682"
+ fy="95.221397"
+ r="8.5514765" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#light90to0"
+ id="linearGradient19980"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.000000,-2.069389,0.325272,0.000000,20.66765,1.378444)"
+ x1="-16.569721"
+ y1="81.885979"
+ x2="-21.621279"
+ y2="85.112236" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#light90to0"
+ id="radialGradient19984"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.144567,0.000000,0.000000,0.313870,-38.78637,48.23092)"
+ cx="25.952410"
+ cy="52.497688"
+ fx="25.923746"
+ fy="51.904903"
+ r="14.270030" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#light90to0"
+ id="linearGradient19987"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.038890,0.000000,0.000000,0.330138,-38.78637,48.23092)"
+ x1="22.425571"
+ y1="35.206337"
+ x2="22.396454"
+ y2="41.545322" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#light90to0"
+ id="radialGradient19991"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.144567,0.000000,0.000000,0.313870,-20.05593,48.23092)"
+ cx="25.952410"
+ cy="52.497688"
+ fx="25.923746"
+ fy="51.904903"
+ r="14.270030" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#light90to0"
+ id="linearGradient19994"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.038890,0.000000,0.000000,0.330138,-20.05593,48.23092)"
+ x1="22.425571"
+ y1="35.206337"
+ x2="22.396454"
+ y2="41.545322" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#light90to0"
+ id="radialGradient19998"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.144567,0.000000,0.000000,0.313870,-31.37563,1.327640)"
+ cx="25.952410"
+ cy="52.497688"
+ fx="25.923746"
+ fy="51.904903"
+ r="14.270030" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#light90to0"
+ id="linearGradient20001"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.038890,0.000000,0.000000,0.330138,-31.37563,1.327640)"
+ x1="22.425571"
+ y1="35.206337"
+ x2="22.396454"
+ y2="41.545322" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#light90to0"
+ id="linearGradient20005"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.000000,-2.069389,0.325272,0.000000,20.75234,15.09638)"
+ x1="-16.569721"
+ y1="81.885979"
+ x2="-21.621279"
+ y2="85.112236" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#light90to0"
+ id="radialGradient20008"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.715419,0.000000,0.000000,0.940867,-15.98071,11.24691)"
+ cx="92.643608"
+ cy="55.457653"
+ fx="92.643608"
+ fy="55.457653"
+ r="9.9914455" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#light90to0"
+ id="radialGradient20019"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.144567,0.000000,0.000000,0.313870,-12.72324,1.327640)"
+ cx="25.952410"
+ cy="52.497688"
+ fx="25.923746"
+ fy="51.904903"
+ r="14.270030" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#light90to0"
+ id="linearGradient20022"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.038890,0.000000,0.000000,0.330138,-12.72324,1.327640)"
+ x1="22.425571"
+ y1="35.206337"
+ x2="22.396454"
+ y2="41.545322" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#light90to0"
+ id="radialGradient20026"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.542260,0.000000,0.000000,1.241312,-0.785301,11.64914)"
+ cx="8.0907059"
+ cy="9.5002232"
+ fx="8.0907059"
+ fy="9.5002232"
+ r="5.8189325" />
+ <linearGradient
+ y2="36.873619"
+ x2="39.857029"
+ y1="4.5492039"
+ x1="10.878086"
+ gradientTransform="matrix(0.996235,0.000000,0.000000,1.003779,-3.391158,13.41516)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1472"
+ xlink:href="#light90to0"
+ inkscape:collect="always" />
+ <radialGradient
+ r="31.677956"
+ fy="46.914463"
+ fx="48.488476"
+ cy="46.914463"
+ cx="48.488476"
+ gradientTransform="matrix(0.983903,0.000000,0.000000,1.016360,-3.999998,12.41516)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient1474"
+ xlink:href="#light90to0"
+ inkscape:collect="always" />
+ <radialGradient
+ r="83.259750"
+ fy="332.37268"
+ fx="86.514435"
+ cy="332.37268"
+ cx="86.514435"
+ gradientTransform="matrix(0.281643,-1.886110e-2,0.000000,0.179517,-4.383105,-16.75305)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient1476"
+ xlink:href="#wihitetolightgray"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="247.07323"
+ x2="73.286217"
+ y1="335.76117"
+ x1="86.514435"
+ gradientTransform="matrix(0.281643,-1.886110e-2,0.000000,0.179517,-4.383105,-16.75305)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1478"
+ xlink:href="#light100to0"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="210.46336"
+ x2="84.003502"
+ y1="279.47504"
+ x1="132.72992"
+ gradientTransform="matrix(0.195716,-1.310673e-2,0.000000,0.258334,-4.383105,-16.75305)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1480"
+ xlink:href="#wihitetolightgray"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="250.54321"
+ x2="54.607849"
+ y1="213.43617"
+ x1="136.55682"
+ gradientTransform="matrix(0.195716,-1.310673e-2,0.000000,0.258334,-4.383105,-16.75305)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1482"
+ xlink:href="#light100to0"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="218.74910"
+ x2="198.28532"
+ y1="264.70230"
+ x1="145.42192"
+ gradientTransform="matrix(0.195716,-1.310673e-2,0.000000,0.258334,-4.383105,-16.75305)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1484"
+ xlink:href="#wihitetolightgray"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="234.35374"
+ x2="184.11906"
+ y1="219.68500"
+ x1="159.18221"
+ gradientTransform="matrix(0.180988,-1.212046e-2,0.000000,0.279356,-4.383105,-16.75305)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1486"
+ xlink:href="#light100to0"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="47.244961"
+ x2="28.653791"
+ y1="4.8842254"
+ x1="36.606781"
+ gradientTransform="matrix(1.273196,-8.526361e-2,0.000000,0.785425,-1.806714e-15,-3.087808e-16)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1488"
+ xlink:href="#orangemoretoyelow"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="189.89319"
+ x2="126.82574"
+ y1="300.55457"
+ x1="134.59328"
+ gradientTransform="matrix(0.286285,-1.917198e-2,0.000000,0.176607,-4.383105,-16.75305)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1490"
+ xlink:href="#light100to0"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="18.127838"
+ x2="40.120766"
+ y1="43.692036"
+ x1="77.830383"
+ gradientTransform="matrix(0.870407,-5.828951e-2,0.000000,1.148888,-1.806714e-15,-3.087808e-16)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1492"
+ xlink:href="#orangemoretoyelow"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="220.31316"
+ x2="269.30646"
+ y1="173.35371"
+ x1="188.09673"
+ gradientTransform="matrix(0.218024,-1.460066e-2,0.000000,0.231901,-4.383105,-16.75305)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1494"
+ xlink:href="#light100to0"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="574.66980"
+ x2="90.955330"
+ y1="221.05045"
+ x1="138.68466"
+ spreadMethod="reflect"
+ gradientTransform="matrix(0.262073,-1.755056e-2,0.000000,0.217660,-4.383105,-17.56717)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1496"
+ xlink:href="#graytoblack"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="224.95407"
+ x2="99.415497"
+ y1="199.20517"
+ x1="124.51332"
+ gradientTransform="matrix(0.273027,-1.828417e-2,0.000000,0.185183,-4.383100,-12.51208)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1498"
+ xlink:href="#shadow100to0"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="224.95407"
+ x2="99.415497"
+ y1="199.20517"
+ x1="124.51332"
+ gradientTransform="matrix(0.273027,-1.828417e-2,0.000000,0.185183,-4.383100,-12.51208)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1500"
+ xlink:href="#shadow100to0"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="301.15750"
+ x2="137.31036"
+ y1="301.15747"
+ x1="163.74318"
+ gradientTransform="matrix(0.273027,-1.828417e-2,0.000000,0.185183,-4.383100,-12.51208)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1502"
+ xlink:href="#shadow100to0"
+ inkscape:collect="always" />
+ <radialGradient
+ r="24.113470"
+ fy="265.90030"
+ fx="145.82777"
+ cy="265.90030"
+ cx="145.82777"
+ gradientTransform="matrix(0.282097,-1.889158e-2,0.000000,0.179229,-4.383100,-12.51208)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient1504"
+ xlink:href="#light50to25to7"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="189.54620"
+ x2="129.06503"
+ y1="179.83293"
+ x1="119.80309"
+ spreadMethod="reflect"
+ gradientTransform="matrix(0.302207,-2.036411e-2,1.731823e-2,0.187588,-5.784573,-19.06245)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1506"
+ xlink:href="#orangetoblackorange"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="189.54620"
+ x2="129.06503"
+ y1="179.83293"
+ x1="119.80309"
+ spreadMethod="reflect"
+ gradientTransform="matrix(0.302207,-2.036411e-2,1.731823e-2,0.187588,-0.406378,-15.67507)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1508"
+ xlink:href="#orangetoblackorange"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="189.54620"
+ x2="129.06503"
+ y1="179.83293"
+ x1="119.80309"
+ spreadMethod="reflect"
+ gradientTransform="matrix(0.302207,-2.036411e-2,1.731823e-2,0.187588,4.903646,-12.38550)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1510"
+ xlink:href="#orangetoblackorange"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="229.92639"
+ x2="120.08266"
+ y1="203.68118"
+ x1="203.79491"
+ spreadMethod="reflect"
+ gradientTransform="matrix(0.250582,0.000000,0.000000,0.227641,-4.383105,-17.56717)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1512"
+ xlink:href="#orangetoblackorange"
+ inkscape:collect="always" />
+ <radialGradient
+ r="83.259750"
+ fy="332.37268"
+ fx="86.514435"
+ cy="332.37268"
+ cx="86.514435"
+ gradientTransform="matrix(0.281643,-1.886110e-2,0.000000,0.179517,-4.383105,-16.75305)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient1514"
+ xlink:href="#graytoblack"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="247.07323"
+ x2="73.286217"
+ y1="335.76117"
+ x1="86.514435"
+ gradientTransform="matrix(0.281643,-1.886110e-2,0.000000,0.179517,-4.383105,-16.75305)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1516"
+ xlink:href="#light100to0"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="213.05858"
+ x2="189.53893"
+ y1="213.05858"
+ x1="24.253796"
+ gradientTransform="matrix(0.331788,0.000000,0.000000,0.171926,-4.383100,-17.56719)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1518"
+ xlink:href="#light100to0"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="218.74910"
+ x2="198.28532"
+ y1="264.70230"
+ x1="145.42192"
+ gradientTransform="matrix(0.195716,-1.310673e-2,0.000000,0.258334,-4.383105,-16.75305)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1520"
+ xlink:href="#graytoblack"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="234.35374"
+ x2="184.11906"
+ y1="219.68500"
+ x1="159.18221"
+ gradientTransform="matrix(0.180988,-1.212046e-2,0.000000,0.279356,-4.383105,-16.75305)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1522"
+ xlink:href="#light100to0"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="210.46336"
+ x2="84.003502"
+ y1="279.47504"
+ x1="132.72992"
+ gradientTransform="matrix(0.195716,-1.310673e-2,0.000000,0.258334,-4.383105,-16.75305)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1524"
+ xlink:href="#graytoblack"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="250.54321"
+ x2="54.607849"
+ y1="213.43617"
+ x1="136.55682"
+ gradientTransform="matrix(0.195716,-1.310673e-2,0.000000,0.258334,-4.383105,-16.75305)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1526"
+ xlink:href="#light100to0"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="172.01805"
+ x2="88.821419"
+ y1="215.05040"
+ x1="42.080868"
+ gradientTransform="matrix(0.182201,0.000000,0.000000,0.313078,-4.383100,-17.56719)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1528"
+ xlink:href="#light100to0"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="216.48166"
+ x2="144.13652"
+ y1="120.63583"
+ x1="149.74805"
+ gradientTransform="matrix(0.331788,0.000000,0.000000,0.171926,-4.383100,-17.56719)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1530"
+ xlink:href="#light100to0"
+ inkscape:collect="always" />
+ <radialGradient
+ r="31.677956"
+ fy="46.914463"
+ fx="48.488476"
+ cy="46.914463"
+ cx="48.488476"
+ gradientTransform="matrix(0.922906,0.000000,0.000000,0.953351,-3.844255,9.876188)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient1575"
+ xlink:href="#light90to0"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="36.873619"
+ x2="39.857029"
+ y1="4.5492039"
+ x1="10.878086"
+ gradientTransform="matrix(0.934473,0.000000,0.000000,0.941550,-3.273160,10.81419)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1578"
+ xlink:href="#light90to0"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="36.873619"
+ x2="39.857029"
+ y1="4.5492039"
+ x1="10.878086"
+ gradientTransform="matrix(0.934473,0.000000,0.000000,0.941550,-3.273160,10.81419)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1474"
+ xlink:href="#light90to0"
+ inkscape:collect="always" />
+ <radialGradient
+ r="31.677956"
+ fy="46.914463"
+ fx="48.488476"
+ cy="46.914463"
+ cx="48.488476"
+ gradientTransform="matrix(0.922906,0.000000,0.000000,0.953351,-3.844255,9.876188)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient1477"
+ xlink:href="#light90to0"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="36.873619"
+ x2="39.857029"
+ y1="4.5492039"
+ x1="10.878086"
+ gradientTransform="matrix(0.934473,0.000000,0.000000,0.941550,-3.273160,10.81419)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1527"
+ xlink:href="#light90to0"
+ inkscape:collect="always" />
+ <radialGradient
+ r="31.677956"
+ fy="46.914463"
+ fx="48.488476"
+ cy="46.914463"
+ cx="48.488476"
+ gradientTransform="matrix(0.922906,0.000000,0.000000,0.953351,-3.844255,9.876188)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient1529"
+ xlink:href="#light90to0"
+ inkscape:collect="always" />
+ <radialGradient
+ r="83.259750"
+ fy="332.37268"
+ fx="86.514435"
+ cy="332.37268"
+ cx="86.514435"
+ gradientTransform="matrix(0.281643,-1.886110e-2,0.000000,0.179517,-4.383105,-16.75305)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient1531"
+ xlink:href="#wihitetolightgray"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="247.07323"
+ x2="73.286217"
+ y1="335.76117"
+ x1="86.514435"
+ gradientTransform="matrix(0.281643,-1.886110e-2,0.000000,0.179517,-4.383105,-16.75305)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1533"
+ xlink:href="#light100to0"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="210.46336"
+ x2="84.003502"
+ y1="279.47504"
+ x1="132.72992"
+ gradientTransform="matrix(0.195716,-1.310673e-2,0.000000,0.258334,-4.383105,-16.75305)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1535"
+ xlink:href="#wihitetolightgray"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="250.54321"
+ x2="54.607849"
+ y1="213.43617"
+ x1="136.55682"
+ gradientTransform="matrix(0.195716,-1.310673e-2,0.000000,0.258334,-4.383105,-16.75305)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1537"
+ xlink:href="#light100to0"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="218.74910"
+ x2="198.28532"
+ y1="264.70230"
+ x1="145.42192"
+ gradientTransform="matrix(0.195716,-1.310673e-2,0.000000,0.258334,-4.383105,-16.75305)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1539"
+ xlink:href="#wihitetolightgray"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="234.35374"
+ x2="184.11906"
+ y1="219.68500"
+ x1="159.18221"
+ gradientTransform="matrix(0.180988,-1.212046e-2,0.000000,0.279356,-4.383105,-16.75305)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1541"
+ xlink:href="#light100to0"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="47.244961"
+ x2="28.653791"
+ y1="4.8842254"
+ x1="36.606781"
+ gradientTransform="matrix(1.273196,-8.526361e-2,0.000000,0.785425,-3.588275e-15,-4.926614e-16)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1543"
+ xlink:href="#orangemoretoyelow"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="189.89319"
+ x2="126.82574"
+ y1="300.55457"
+ x1="134.59328"
+ gradientTransform="matrix(0.286285,-1.917198e-2,0.000000,0.176607,-4.383105,-16.75305)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1545"
+ xlink:href="#light100to0"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="18.127838"
+ x2="40.120766"
+ y1="43.692036"
+ x1="77.830383"
+ gradientTransform="matrix(0.870407,-5.828951e-2,0.000000,1.148888,4.887488e-6,1.380840e-15)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1547"
+ xlink:href="#orangemoretoyelow"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="220.31316"
+ x2="269.30646"
+ y1="173.35371"
+ x1="188.09673"
+ gradientTransform="matrix(0.218024,-1.460066e-2,0.000000,0.231901,-4.383105,-16.75305)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1549"
+ xlink:href="#light100to0"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="574.66980"
+ x2="90.955330"
+ y1="221.05045"
+ x1="138.68466"
+ spreadMethod="reflect"
+ gradientTransform="matrix(0.262073,-1.755056e-2,0.000000,0.217660,-4.383105,-17.56717)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1551"
+ xlink:href="#graytoblack"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="224.95407"
+ x2="99.415497"
+ y1="199.20517"
+ x1="124.51332"
+ gradientTransform="matrix(0.273027,-1.828417e-2,0.000000,0.185183,-4.383100,-12.51208)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1553"
+ xlink:href="#shadow100to0"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="224.95407"
+ x2="99.415497"
+ y1="199.20517"
+ x1="124.51332"
+ gradientTransform="matrix(0.273027,-1.828417e-2,0.000000,0.185183,-4.383100,-12.51208)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1555"
+ xlink:href="#shadow100to0"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="301.15750"
+ x2="137.31036"
+ y1="301.15747"
+ x1="163.74318"
+ gradientTransform="matrix(0.273027,-1.828417e-2,0.000000,0.185183,-4.383100,-12.51208)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1557"
+ xlink:href="#shadow100to0"
+ inkscape:collect="always" />
+ <radialGradient
+ r="24.113470"
+ fy="265.90030"
+ fx="145.82777"
+ cy="265.90030"
+ cx="145.82777"
+ gradientTransform="matrix(0.282097,-1.889158e-2,0.000000,0.179229,-4.383100,-12.51208)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient1559"
+ xlink:href="#light50to25to7"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="189.54620"
+ x2="129.06503"
+ y1="179.83293"
+ x1="119.80309"
+ spreadMethod="reflect"
+ gradientTransform="matrix(0.302207,-2.036411e-2,1.731823e-2,0.187588,-5.784573,-19.06245)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1561"
+ xlink:href="#orangetoblackorange"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="189.54620"
+ x2="129.06503"
+ y1="179.83293"
+ x1="119.80309"
+ spreadMethod="reflect"
+ gradientTransform="matrix(0.302207,-2.036411e-2,1.731823e-2,0.187588,-0.406378,-15.67507)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1563"
+ xlink:href="#orangetoblackorange"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="189.54620"
+ x2="129.06503"
+ y1="179.83293"
+ x1="119.80309"
+ spreadMethod="reflect"
+ gradientTransform="matrix(0.302207,-2.036411e-2,1.731823e-2,0.187588,4.903646,-12.38550)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1565"
+ xlink:href="#orangetoblackorange"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="229.92639"
+ x2="120.08266"
+ y1="203.68118"
+ x1="203.79491"
+ spreadMethod="reflect"
+ gradientTransform="matrix(0.250582,0.000000,0.000000,0.227641,-4.383105,-17.56717)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1567"
+ xlink:href="#orangetoblackorange"
+ inkscape:collect="always" />
+ <radialGradient
+ r="83.259750"
+ fy="332.37268"
+ fx="86.514435"
+ cy="332.37268"
+ cx="86.514435"
+ gradientTransform="matrix(0.281643,-1.886110e-2,0.000000,0.179517,-4.383105,-16.75305)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient1569"
+ xlink:href="#graytoblack"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="247.07323"
+ x2="73.286217"
+ y1="335.76117"
+ x1="86.514435"
+ gradientTransform="matrix(0.281643,-1.886110e-2,0.000000,0.179517,-4.383105,-16.75305)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1571"
+ xlink:href="#light100to0"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="213.05858"
+ x2="189.53893"
+ y1="213.05858"
+ x1="24.253796"
+ gradientTransform="matrix(0.331788,0.000000,0.000000,0.171926,-4.383100,-17.56719)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1573"
+ xlink:href="#light100to0"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="218.74910"
+ x2="198.28532"
+ y1="264.70230"
+ x1="145.42192"
+ gradientTransform="matrix(0.195716,-1.310673e-2,0.000000,0.258334,-4.383105,-16.75305)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1575"
+ xlink:href="#graytoblack"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="234.35374"
+ x2="184.11906"
+ y1="219.68500"
+ x1="159.18221"
+ gradientTransform="matrix(0.180988,-1.212046e-2,0.000000,0.279356,-4.383105,-16.75305)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1577"
+ xlink:href="#light100to0"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="210.46336"
+ x2="84.003502"
+ y1="279.47504"
+ x1="132.72992"
+ gradientTransform="matrix(0.195716,-1.310673e-2,0.000000,0.258334,-4.383105,-16.75305)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1579"
+ xlink:href="#graytoblack"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="250.54321"
+ x2="54.607849"
+ y1="213.43617"
+ x1="136.55682"
+ gradientTransform="matrix(0.195716,-1.310673e-2,0.000000,0.258334,-4.383105,-16.75305)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1581"
+ xlink:href="#light100to0"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="172.01805"
+ x2="88.821419"
+ y1="215.05040"
+ x1="42.080868"
+ gradientTransform="matrix(0.182201,0.000000,0.000000,0.313078,-4.383100,-17.56719)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1583"
+ xlink:href="#light100to0"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="216.48166"
+ x2="144.13652"
+ y1="120.63583"
+ x1="149.74805"
+ gradientTransform="matrix(0.331788,0.000000,0.000000,0.171926,-4.383100,-17.56719)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1585"
+ xlink:href="#light100to0"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="216.48166"
+ x2="144.13652"
+ y1="120.63583"
+ x1="149.74805"
+ gradientTransform="matrix(0.251838,0.000000,0.000000,0.135659,7.587247,-14.29214)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient2877"
+ xlink:href="#light100to0"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="172.01805"
+ x2="88.821419"
+ y1="215.05040"
+ x1="42.080868"
+ gradientTransform="matrix(0.138296,0.000000,0.000000,0.247035,7.587247,-14.29214)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient2880"
+ xlink:href="#light100to0"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="210.46336"
+ x2="84.003502"
+ y1="279.47504"
+ x1="132.72992"
+ gradientTransform="matrix(0.148555,-1.034192e-2,0.000000,0.203839,7.587243,-13.64974)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient2883"
+ xlink:href="#graytoblack"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="250.54321"
+ x2="54.607849"
+ y1="213.43617"
+ x1="136.55682"
+ gradientTransform="matrix(0.148555,-1.034192e-2,0.000000,0.203839,7.587243,-13.64974)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient2885"
+ xlink:href="#light100to0"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="218.74910"
+ x2="198.28532"
+ y1="264.70230"
+ x1="145.42192"
+ gradientTransform="matrix(0.148555,-1.034192e-2,0.000000,0.203839,7.587243,-13.64974)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient2888"
+ xlink:href="#graytoblack"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="234.35374"
+ x2="184.11906"
+ y1="219.68500"
+ x1="159.18221"
+ gradientTransform="matrix(0.137376,-9.563697e-3,0.000000,0.220427,7.587243,-13.64974)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient2890"
+ xlink:href="#light100to0"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="213.05858"
+ x2="189.53893"
+ y1="213.05858"
+ x1="24.253796"
+ gradientTransform="matrix(0.251838,0.000000,0.000000,0.135659,7.587247,-14.29214)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient2893"
+ xlink:href="#light100to0"
+ inkscape:collect="always" />
+ <radialGradient
+ r="83.259750"
+ fy="332.37268"
+ fx="86.514435"
+ cy="332.37268"
+ cx="86.514435"
+ gradientTransform="matrix(0.213776,-1.488243e-2,0.000000,0.141649,7.587243,-13.64974)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient2896"
+ xlink:href="#graytoblack"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="247.07323"
+ x2="73.286217"
+ y1="335.76117"
+ x1="86.514435"
+ gradientTransform="matrix(0.213776,-1.488243e-2,0.000000,0.141649,7.587243,-13.64974)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient2898"
+ xlink:href="#light100to0"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="229.92639"
+ x2="120.08266"
+ y1="203.68118"
+ x1="203.79491"
+ spreadMethod="reflect"
+ gradientTransform="matrix(0.190200,0.000000,0.000000,0.179621,7.587243,-14.29213)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient2901"
+ xlink:href="#orangetoblackorange"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="189.54620"
+ x2="129.06503"
+ y1="179.83293"
+ x1="119.80309"
+ spreadMethod="reflect"
+ gradientTransform="matrix(0.229385,-1.606838e-2,1.314509e-2,0.148017,14.63618,-10.20351)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient2904"
+ xlink:href="#orangetoblackorange"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="189.54620"
+ x2="129.06503"
+ y1="179.83293"
+ x1="119.80309"
+ spreadMethod="reflect"
+ gradientTransform="matrix(0.229385,-1.606838e-2,1.314509e-2,0.148017,10.60571,-12.79916)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient2907"
+ xlink:href="#orangetoblackorange"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="189.54620"
+ x2="129.06503"
+ y1="179.83293"
+ x1="119.80309"
+ spreadMethod="reflect"
+ gradientTransform="matrix(0.229385,-1.606838e-2,1.314509e-2,0.148017,6.523484,-15.47198)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient2910"
+ xlink:href="#orangetoblackorange"
+ inkscape:collect="always" />
+ <radialGradient
+ r="24.113470"
+ fy="265.90030"
+ fx="145.82777"
+ cy="265.90030"
+ cx="145.82777"
+ gradientTransform="matrix(0.214121,-1.490648e-2,0.000000,0.141421,7.587247,-10.30339)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient2913"
+ xlink:href="#light50to25to7"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="301.15750"
+ x2="137.31036"
+ y1="301.15747"
+ x1="163.74318"
+ gradientTransform="matrix(0.207236,-1.442720e-2,0.000000,0.146119,7.587247,-10.30339)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient2916"
+ xlink:href="#shadow100to0"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="224.95407"
+ x2="99.415497"
+ y1="199.20517"
+ x1="124.51332"
+ gradientTransform="matrix(0.207236,-1.442720e-2,0.000000,0.146119,7.587247,-10.30339)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient2919"
+ xlink:href="#shadow100to0"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="224.95407"
+ x2="99.415497"
+ y1="199.20517"
+ x1="124.51332"
+ gradientTransform="matrix(0.207236,-1.442720e-2,0.000000,0.146119,7.587247,-10.30339)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient2922"
+ xlink:href="#shadow100to0"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="574.66980"
+ x2="90.955330"
+ y1="221.05045"
+ x1="138.68466"
+ spreadMethod="reflect"
+ gradientTransform="matrix(0.198922,-1.384834e-2,0.000000,0.171745,7.587243,-14.29213)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient2925"
+ xlink:href="#graytoblack"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="18.127838"
+ x2="40.120766"
+ y1="43.692036"
+ x1="77.830383"
+ gradientTransform="matrix(0.660667,-4.599357e-2,0.000000,0.906535,10.91416,-0.430682)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient2928"
+ xlink:href="#orangemoretoyelow"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="220.31316"
+ x2="269.30646"
+ y1="173.35371"
+ x1="188.09673"
+ gradientTransform="matrix(0.165487,-1.152071e-2,0.000000,0.182982,7.587243,-13.64974)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient2930"
+ xlink:href="#light100to0"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="47.244961"
+ x2="28.653791"
+ y1="4.8842254"
+ x1="36.606781"
+ gradientTransform="matrix(0.966397,-6.727759e-2,0.000000,0.619743,10.91416,-0.430682)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient2933"
+ xlink:href="#orangemoretoyelow"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="189.89319"
+ x2="126.82574"
+ y1="300.55457"
+ x1="134.59328"
+ gradientTransform="matrix(0.217299,-1.512773e-2,0.000000,0.139352,7.587243,-13.64974)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient2935"
+ xlink:href="#light100to0"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="218.74910"
+ x2="198.28532"
+ y1="264.70230"
+ x1="145.42192"
+ gradientTransform="matrix(0.148555,-1.034192e-2,0.000000,0.203839,7.587243,-13.64974)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient2938"
+ xlink:href="#wihitetolightgray"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="234.35374"
+ x2="184.11906"
+ y1="219.68500"
+ x1="159.18221"
+ gradientTransform="matrix(0.137376,-9.563697e-3,0.000000,0.220427,7.587243,-13.64974)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient2940"
+ xlink:href="#light100to0"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="210.46336"
+ x2="84.003502"
+ y1="279.47504"
+ x1="132.72992"
+ gradientTransform="matrix(0.148555,-1.034192e-2,0.000000,0.203839,7.587243,-13.64974)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient2943"
+ xlink:href="#wihitetolightgray"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="250.54321"
+ x2="54.607849"
+ y1="213.43617"
+ x1="136.55682"
+ gradientTransform="matrix(0.148555,-1.034192e-2,0.000000,0.203839,7.587243,-13.64974)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient2945"
+ xlink:href="#light100to0"
+ inkscape:collect="always" />
+ <radialGradient
+ r="83.259750"
+ fy="332.37268"
+ fx="86.514435"
+ cy="332.37268"
+ cx="86.514435"
+ gradientTransform="matrix(0.213776,-1.488243e-2,0.000000,0.141649,7.587243,-13.64974)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient2948"
+ xlink:href="#wihitetolightgray"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="247.07323"
+ x2="73.286217"
+ y1="335.76117"
+ x1="86.514435"
+ gradientTransform="matrix(0.213776,-1.488243e-2,0.000000,0.141649,7.587243,-13.64974)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient2950"
+ xlink:href="#light100to0"
+ inkscape:collect="always" />
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="6.8465874"
+ inkscape:cx="34.331449"
+ inkscape:cy="26.802583"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ inkscape:document-units="px"
+ inkscape:grid-bbox="true"
+ inkscape:window-width="1020"
+ inkscape:window-height="691"
+ inkscape:window-x="0"
+ inkscape:window-y="0" />
+ <metadata
+ id="metadata4">
+ <rdf:RDF
+ id="RDF5">
+ <cc:Work
+ rdf:about=""
+ id="Work6">
+ <dc:format
+ id="format7">image/svg+xml</dc:format>
+ <dc:type
+ id="type9"
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ id="layer1"
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer">
+ <g
+ transform="matrix(1.003380,0.000000,0.000000,0.989340,3.064371e-4,0.621087)"
+ id="g1457">
+ <path
+ style="opacity:0.79446638;fill:#0028c6;fill-opacity:0.18099548;stroke:#000000;stroke-width:0.0000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:0.035294119"
+ d="M 6.1800241,11.752191 L 42.411763,11.752191 C 44.327630,11.752191 45.870008,13.762478 45.870008,16.259562 L 45.870008,51.816406 C 45.870008,54.313489 44.327630,56.323777 42.411763,56.323777 L 6.1800241,56.323777 C 4.2641564,56.323777 2.7217788,54.313489 2.7217788,51.816406 L 2.7217788,16.259562 C 2.7217788,13.762478 4.2641564,11.752191 6.1800241,11.752191 z "
+ id="rect7971" />
+ <path
+ style="opacity:0.79446638;fill:url(#linearGradient1527);fill-opacity:1.0000000;stroke:#000000;stroke-width:0.0000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:0.035294119"
+ d="M 6.7511200,12.690196 L 42.982858,12.690196 C 44.538121,36.490139 20.962529,23.157631 3.2928747,52.754411 L 3.2928747,17.197567 C 3.2928747,14.700483 4.8352523,12.690196 6.7511200,12.690196 z "
+ id="path8746"
+ sodipodi:nodetypes="ccccc" />
+ <path
+ style="opacity:0.97233200;fill:url(#radialGradient1529);fill-opacity:1.0000000;stroke:#000000;stroke-width:0.0000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:0.035294119"
+ d="M 6.1800241,11.752191 L 42.411763,11.752191 C 44.327630,11.752191 45.870008,13.762478 45.870008,16.259562 L 45.870008,51.816406 C 45.870008,54.313489 44.327630,56.323777 42.411763,56.323777 L 6.1800241,56.323777 C 4.2641564,56.323777 2.7217788,54.313489 2.7217788,51.816406 L 2.7217788,16.259562 C 2.7217788,13.762478 4.2641564,11.752191 6.1800241,11.752191 z "
+ id="path9514" />
+ <path
+ style="fill:#343435;fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:5.5999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000"
+ d="M 2.1039429,9.7820744 C 1.5251775,9.7663881 0.96486589,9.9894898 0.55099632,10.400419 C 0.13712749,10.811346 -0.094946223,11.374999 -0.092213059,11.962626 L -0.092213059,18.867704 C -0.092213059,20.071990 0.86966429,21.048255 2.0562004,21.048255 C 3.2427364,21.048255 4.2046137,20.071990 4.2046137,18.867704 L 4.2046137,14.167405 L 5.8278594,14.191633 C 6.6127969,14.244543 7.3630068,13.855899 7.7812725,13.179676 C 8.1995375,12.503453 8.2183549,11.648784 7.8302686,10.954272 C 7.4421830,10.259761 6.7098272,9.8374908 5.9233444,9.8547594 L 2.1039429,9.7820744 z "
+ id="path7697" />
+ <path
+ style="fill:#343435;fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:5.5999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000"
+ d="M 31.871403,9.7814365 C 30.684867,9.7680559 29.712302,10.733474 29.699119,11.937759 C 29.685935,13.142045 30.637125,14.129158 31.823661,14.142539 L 40.918611,14.263680 C 41.705975,14.311054 42.455138,13.914810 42.867933,13.232654 C 43.280728,12.550497 43.290167,11.693130 42.892492,11.001782 C 42.494816,10.310436 41.754563,9.8973008 40.966353,9.9268067 L 31.871403,9.7814365 z "
+ id="path7695"
+ sodipodi:nodetypes="cccccccc" />
+ <path
+ style="fill:#343435;fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:5.5999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000"
+ d="M 45.573507,14.722417 C 45.002912,14.726284 44.457490,14.961373 44.058517,15.375414 C 43.659544,15.789455 43.440095,16.348124 43.448965,16.927197 L 43.448965,26.158197 C 43.448965,27.362483 44.410843,28.338748 45.597379,28.338748 C 46.783915,28.338748 47.745792,27.362483 47.745792,26.158197 L 47.745792,16.927197 C 47.754850,16.339683 47.528894,15.773532 47.119532,15.358045 C 46.710170,14.942560 46.152362,14.713224 45.573507,14.722417 L 45.573507,14.722417 z "
+ id="path1937"
+ sodipodi:nodetypes="cccccccccc" />
+ <path
+ style="fill:#343435;fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:5.5999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000"
+ d="M 43.832534,26.692588 C 44.718063,26.866907 45.135153,23.989865 45.069485,19.604618 C 45.015675,16.071244 46.477953,17.496876 46.588198,15.582764 C 46.605189,15.287749 46.213140,15.134351 45.738969,15.149149 C 45.264797,15.163948 44.708503,15.346945 44.397005,15.724716 C 44.219002,15.873843 44.080729,16.087154 43.986898,16.337102 C 43.893069,16.587049 43.843681,16.873633 43.843454,17.169310 C 43.843226,17.464986 43.834354,24.330069 43.832534,26.692588 z "
+ id="path4304"
+ sodipodi:nodetypes="cccccccc" />
+ <path
+ style="opacity:0.79446638;fill:#343435;fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:5.5999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000"
+ d="M 44.855550,25.920267 C 44.847515,26.827450 45.427205,27.571035 46.150325,27.581116 C 46.873444,27.591196 47.466162,26.863950 47.474196,25.956769 L 47.546937,16.848759 C 47.575383,16.246770 47.337455,15.673986 46.927851,15.358378 C 46.518246,15.042772 46.003436,15.035555 45.588312,15.339602 C 45.173189,15.643650 44.925120,16.209621 44.942837,16.812256 L 44.855550,25.920267 z "
+ id="path4306"
+ sodipodi:nodetypes="cccccccc" />
+ <path
+ style="fill:#343435;fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:5.5999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000"
+ d="M 45.573507,46.899901 C 45.002912,46.903768 44.457490,47.138857 44.058517,47.552899 C 43.659544,47.966939 43.440095,48.525608 43.448965,49.104681 L 43.448965,53.901894 L 41.777977,53.901894 C 40.591441,53.901894 39.629564,54.878160 39.629564,56.082445 C 39.629564,57.286731 40.591441,58.262996 41.777977,58.262996 L 45.597379,58.262996 C 46.167934,58.265530 46.715843,58.036607 47.119291,57.627123 C 47.522739,57.217640 47.748288,56.661535 47.745792,56.082445 L 47.745792,49.104681 C 47.754850,48.517167 47.528894,47.951016 47.119532,47.535529 C 46.710170,47.120043 46.152362,46.890708 45.573507,46.899901 z "
+ id="path7691" />
+ <path
+ style="fill:#343435;fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:5.5999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000"
+ d="M 8.4272673,53.827824 C 7.3482262,53.827617 6.4736286,54.803772 6.4737979,56.008130 C 6.4739672,57.212488 7.3488398,58.188981 8.4278808,58.189188 L 16.699054,58.209355 C 17.415475,58.247986 18.092682,57.843449 18.461147,57.156753 C 18.829611,56.470055 18.829537,55.612637 18.460957,54.925746 C 18.092376,54.238857 17.415101,53.833965 16.698686,53.872219 L 8.4272673,53.827824 z "
+ id="path7751"
+ sodipodi:nodetypes="cccccccc" />
+ <path
+ style="fill:#343435;fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:5.5999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000"
+ d="M 2.1056606,23.987353 C 1.5350657,23.990831 0.98964301,24.202266 0.59066982,24.574649 C 0.19169742,24.947031 -0.027751643,25.449489 -0.018881465,25.970300 L -0.018881465,34.272523 C -0.018881465,35.355640 0.94299583,36.233678 2.1295319,36.233678 C 3.3160680,36.233678 4.2779453,35.355640 4.2779453,34.272523 L 4.2779453,25.970300 C 4.2870034,25.441898 4.0610476,24.932710 3.6516857,24.559028 C 3.2423230,24.185346 2.6845154,23.979085 2.1056606,23.987353 L 2.1056606,23.987353 z "
+ id="path7775"
+ sodipodi:nodetypes="cccccccccc" />
+ <path
+ style="fill:#343435;fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:5.5999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000"
+ d="M 2.1056606,40.878909 C 1.5350657,40.882503 0.98964301,41.101035 0.59066982,41.485915 C 0.19169742,41.870795 -0.027751643,42.390117 -0.018881465,42.928405 L -0.018881465,51.509261 C -0.018881465,52.628729 0.94299583,53.536236 2.1295319,53.536236 C 3.3160680,53.536236 4.2779453,52.628729 4.2779453,51.509261 L 4.2779453,42.928405 C 4.2870034,42.382270 4.0610476,41.855993 3.6516857,41.469770 C 3.2423230,41.083547 2.6845154,40.870363 2.1056606,40.878909 L 2.1056606,40.878909 z "
+ id="path7781"
+ sodipodi:nodetypes="cccccccccc" />
+ <path
+ style="fill:#343435;fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:5.5999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000"
+ d="M 45.443435,29.434493 C 44.872840,29.438087 44.327417,29.656619 43.928444,30.041499 C 43.529472,30.426379 43.310023,30.945701 43.318893,31.483989 L 43.318893,40.064845 C 43.318893,41.184313 44.280770,42.091820 45.467306,42.091820 C 46.653842,42.091820 47.615720,41.184313 47.615720,40.064845 L 47.615720,31.483989 C 47.624778,30.937854 47.398822,30.411577 46.989461,30.025353 C 46.580097,29.639131 46.022290,29.425947 45.443435,29.434493 L 45.443435,29.434493 z "
+ id="path20031"
+ sodipodi:nodetypes="cccccccccc" />
+ <path
+ style="fill:#343435;fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:5.5999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000"
+ d="M 25.311357,53.827824 C 24.232316,53.827617 23.357718,54.803772 23.357888,56.008130 C 23.358058,57.212488 24.232930,58.188981 25.311971,58.189188 L 33.583144,58.209355 C 34.299565,58.247986 34.976772,57.843449 35.345237,57.156753 C 35.713701,56.470055 35.713627,55.612637 35.345047,54.925746 C 34.976466,54.238857 34.299191,53.833965 33.582776,53.872219 L 25.311357,53.827824 z "
+ id="path20029"
+ sodipodi:nodetypes="cccccccc" />
+ <path
+ style="fill:#343435;fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:5.5999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000"
+ d="M 14.055297,9.7458205 C 12.976256,9.7456132 12.101658,10.721769 12.101828,11.926126 C 12.101998,13.130484 12.976870,14.106977 14.055911,14.107184 L 22.327084,14.127352 C 23.043505,14.165982 23.720712,13.761445 24.089177,13.074750 C 24.457641,12.388051 24.457567,11.530633 24.088987,10.843742 C 23.720406,10.156853 23.043131,9.7519616 22.326716,9.7902153 L 14.055297,9.7458205 z "
+ id="path20033"
+ sodipodi:nodetypes="cccccccc" />
+ </g>
+ <g
+ id="g12821"
+ transform="matrix(0.696199,0.000000,0.000000,0.708248,21.27651,37.84947)">
+ <path
+ style="fill:none;fill-opacity:0.75000000;fill-rule:evenodd;stroke:#000000;stroke-width:8.4754333;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-opacity:0.036199097"
+ d="M 31.443570,-46.786978 L 51.456857,-35.004551 L 51.479527,-21.252720 L 9.5298710,6.4263662 L -10.332290,-5.2904158 L -10.426366,-19.280855 L 31.443570,-46.786978 z "
+ id="path12039"
+ sodipodi:nodetypes="ccccccc" />
+ <path
+ style="fill:none;fill-opacity:0.75000000;fill-rule:evenodd;stroke:#000000;stroke-width:7.5159512;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-opacity:0.036199097"
+ d="M 31.443570,-46.786978 L 51.456857,-35.004551 L 51.479527,-21.252720 L 9.5298710,6.4263662 L -10.332290,-5.2904158 L -10.426366,-19.280855 L 31.443570,-46.786978 z "
+ id="path12807"
+ sodipodi:nodetypes="ccccccc" />
+ <path
+ style="fill:none;fill-opacity:0.75000000;fill-rule:evenodd;stroke:#000000;stroke-width:6.6630769;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-opacity:0.036199097"
+ d="M 31.443570,-46.786978 L 51.456857,-35.004551 L 51.479527,-21.252720 L 9.5298710,6.4263662 L -10.332290,-5.2904158 L -10.426366,-19.280855 L 31.443570,-46.786978 z "
+ id="path12809"
+ sodipodi:nodetypes="ccccccc" />
+ <path
+ style="fill:none;fill-opacity:0.75000000;fill-rule:evenodd;stroke:#000000;stroke-width:5.7035937;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-opacity:0.036199097"
+ d="M 31.443570,-46.786978 L 51.456857,-35.004551 L 51.479527,-21.252720 L 9.5298710,6.4263662 L -10.332290,-5.2904158 L -10.426366,-19.280855 L 31.443570,-46.786978 z "
+ id="path12811"
+ sodipodi:nodetypes="ccccccc" />
+ <path
+ style="fill:none;fill-opacity:0.75000000;fill-rule:evenodd;stroke:#000000;stroke-width:4.7441106;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-opacity:0.036199097"
+ d="M 31.443570,-46.786978 L 51.456857,-35.004551 L 51.479527,-21.252720 L 9.5298710,6.4263662 L -10.332290,-5.2904158 L -10.426366,-19.280855 L 31.443570,-46.786978 z "
+ id="path12813"
+ sodipodi:nodetypes="ccccccc" />
+ <path
+ style="fill:none;fill-opacity:0.75000000;fill-rule:evenodd;stroke:#000000;stroke-width:3.9978461;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-opacity:0.036199097"
+ d="M 31.443570,-46.786978 L 51.456857,-35.004551 L 51.479527,-21.252720 L 9.5298710,6.4263662 L -10.332290,-5.2904158 L -10.426366,-19.280855 L 31.443570,-46.786978 z "
+ id="path12815"
+ sodipodi:nodetypes="ccccccc" />
+ <path
+ style="fill:none;fill-opacity:0.75000000;fill-rule:evenodd;stroke:#000000;stroke-width:3.1449723;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-opacity:0.036199097"
+ d="M 31.443570,-46.786978 L 51.456857,-35.004551 L 51.479527,-21.252720 L 9.5298710,6.4263662 L -10.332290,-5.2904158 L -10.426366,-19.280855 L 31.443570,-46.786978 z "
+ id="path12817"
+ sodipodi:nodetypes="ccccccc" />
+ <path
+ style="fill:none;fill-opacity:0.75000000;fill-rule:evenodd;stroke:#000000;stroke-width:2.2920985;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-opacity:0.036199097"
+ d="M 31.443570,-46.786978 L 51.456857,-35.004551 L 51.479527,-21.252720 L 9.5298710,6.4263662 L -10.332290,-5.2904158 L -10.426366,-19.280855 L 31.443570,-46.786978 z "
+ id="path12819"
+ sodipodi:nodetypes="ccccccc" />
+ </g>
+ <path
+ style="fill:url(#radialGradient2948);fill-opacity:1.0000000;fill-rule:evenodd;stroke:url(#linearGradient2950);stroke-width:0.64930671;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000"
+ d="M 23.527250,16.908295 L 37.675026,25.667111 L 27.947401,32.409638 L 13.744677,23.705348 L 23.527250,16.908295 z "
+ id="path2646"
+ sodipodi:nodetypes="ccccc" />
+ <path
+ style="fill:url(#linearGradient2943);fill-opacity:1.0000000;fill-rule:evenodd;stroke:url(#linearGradient2945);stroke-width:0.67249632;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000"
+ d="M 13.651327,33.802483 L 27.799102,42.424340 L 27.947401,32.409638 L 13.744677,23.705348 L 13.651327,33.802483 z "
+ id="path3416"
+ sodipodi:nodetypes="ccccc" />
+ <path
+ style="fill:url(#linearGradient2938);fill-opacity:1.0000000;fill-rule:evenodd;stroke:url(#linearGradient2940);stroke-width:0.62611729;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000"
+ d="M 37.600441,35.833072 L 27.799102,42.424340 L 27.947401,32.409638 L 37.693790,25.735937 L 37.600441,35.833072 z "
+ id="path4180"
+ sodipodi:nodetypes="ccccc" />
+ <path
+ style="fill:url(#linearGradient2933);fill-opacity:1.0000000;fill-rule:evenodd;stroke:url(#linearGradient2935);stroke-width:0.62611729;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000"
+ d="M 23.527250,16.908295 L 37.675026,25.667111 L 57.525788,12.226416 L 43.323066,3.5221222 L 23.527250,16.908295 z "
+ id="path4942"
+ sodipodi:nodetypes="ccccc" />
+ <path
+ style="fill:url(#linearGradient2928);fill-opacity:1.0000000;fill-rule:evenodd;stroke:url(#linearGradient2930);stroke-width:0.60292763;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000"
+ d="M 37.600441,35.833072 L 57.476250,22.279894 L 57.624549,12.265192 L 37.693790,25.735937 L 37.600441,35.833072 z "
+ id="path5704"
+ sodipodi:nodetypes="ccccc" />
+ <path
+ style="fill:none;fill-opacity:0.75000000;fill-rule:evenodd;stroke:url(#linearGradient2925);stroke-width:0.88120204;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000"
+ d="M 43.352337,3.4955980 L 57.540512,12.122573 L 57.556584,22.191526 L 27.816887,42.457876 L 13.735851,33.878966 L 13.669157,23.635306 L 43.352337,3.4955980 z "
+ id="path1875"
+ sodipodi:nodetypes="ccccccc" />
+ <path
+ style="fill:url(#linearGradient2922);fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:1.0000000px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000"
+ d="M 23.734387,16.986475 L 37.448802,25.682860 L 36.091459,26.613948 L 22.518028,17.728888 L 23.734387,16.986475 z "
+ id="path7264" />
+ <path
+ style="fill:url(#linearGradient2919);fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:1.0000000px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000"
+ d="M 37.313783,35.763019 L 37.448802,25.682860 L 36.091459,26.613948 L 36.097422,36.505434 L 37.313783,35.763019 z "
+ id="path8032"
+ sodipodi:nodetypes="ccccc" />
+ <path
+ style="fill:url(#linearGradient2916);fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:1.0000000px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000"
+ d="M 37.313783,35.763019 L 37.448802,25.682860 L 36.091459,26.613948 L 36.097422,36.505434 L 37.313783,35.763019 z "
+ id="path8034"
+ sodipodi:nodetypes="ccccc" />
+ <path
+ style="fill:url(#radialGradient2913);fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:1.0000000px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000"
+ d="M 57.115009,12.516946 L 38.579922,24.672607 C 38.009737,24.948138 37.242032,24.872198 36.869365,24.677449 L 24.002836,16.952421 L 36.317683,25.134159 C 36.501577,25.461311 36.339813,26.086440 35.980531,26.314452 L 27.721177,32.425387 L 36.317683,26.807348 C 36.840184,26.432290 36.967650,26.997787 36.996354,27.387550 L 37.420097,35.709968 L 38.005097,26.689873 C 38.025215,26.178869 38.390989,25.598150 38.806146,25.379218 L 57.115009,12.516946 z "
+ id="path8798"
+ sodipodi:nodetypes="ccccccccccccc" />
+ <path
+ style="opacity:0.45059285;fill:url(#linearGradient2910);fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:2.2241998;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000"
+ d="M 28.382239,16.190139 L 30.728363,17.698172 L 45.678574,7.1338998 L 43.297377,5.6640350 L 28.382239,16.190139 z "
+ id="path9568"
+ sodipodi:nodetypes="ccccc" />
+ <path
+ style="opacity:0.45059285;fill:url(#linearGradient2907);fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:2.2241998;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000"
+ d="M 34.354677,17.707185 L 36.700800,19.215217 L 49.760787,9.8067295 L 47.379591,8.3368655 L 34.354677,17.707185 z "
+ id="path9574"
+ sodipodi:nodetypes="ccccc" />
+ <path
+ style="opacity:0.45059285;fill:url(#linearGradient2904);fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:2.2241998;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000"
+ d="M 40.470919,18.807103 L 42.817042,20.315136 L 53.791267,12.402370 L 51.410071,10.932506 L 40.470919,18.807103 z "
+ id="path9578"
+ sodipodi:nodetypes="ccccc" />
+ <path
+ style="fill:none;fill-opacity:0.75000000;fill-rule:evenodd;stroke:url(#linearGradient2901);stroke-width:0.93599498;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000"
+ d="M 23.685829,16.889742 L 43.330622,3.5026466 L 57.587392,12.176218 L 57.457488,22.268067 L 37.675026,35.732929"
+ id="path11173"
+ sodipodi:nodetypes="ccccc" />
+ <path
+ style="opacity:0.090909071;fill:url(#radialGradient2896);fill-opacity:1.0000000;fill-rule:evenodd;stroke:url(#linearGradient2898);stroke-width:0.64930671;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000"
+ d="M 23.527250,16.908295 L 37.675026,25.667111 L 27.947401,32.409638 L 13.744677,23.705348 L 23.527250,16.908295 z "
+ id="path16121"
+ sodipodi:nodetypes="ccccc" />
+ <path
+ style="fill:url(#linearGradient2893);fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:1.0000000px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000"
+ d="M 43.358168,3.5906688 C 47.363022,6.1094789 51.315631,8.4375519 55.320486,10.956360 C 51.791561,13.969140 45.182687,13.437804 38.802332,13.671877 C 32.487156,13.905952 20.599481,19.596563 17.429440,25.822301 C 16.184726,25.035740 15.079683,24.417290 13.834969,23.630728 C 23.705177,16.943161 33.487959,10.278236 43.358168,3.5906688 z "
+ id="path9625"
+ sodipodi:nodetypes="cczccc" />
+ <path
+ style="opacity:0.098814197;fill:url(#linearGradient2888);fill-opacity:1.0000000;fill-rule:evenodd;stroke:url(#linearGradient2890);stroke-width:0.62611729;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000"
+ d="M 37.600441,35.833072 L 27.799102,42.424340 L 27.947401,32.409638 L 37.693790,25.735937 L 37.600441,35.833072 z "
+ id="path18403"
+ sodipodi:nodetypes="ccccc" />
+ <path
+ style="opacity:0.15019758;fill:url(#linearGradient2883);fill-opacity:1.0000000;fill-rule:evenodd;stroke:url(#linearGradient2885);stroke-width:0.67249632;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000"
+ d="M 13.651327,33.802483 L 27.799102,42.424340 L 27.947401,32.409638 L 13.744677,23.705348 L 13.651327,33.802483 z "
+ id="path18399"
+ sodipodi:nodetypes="ccccc" />
+ <path
+ style="fill:url(#linearGradient2880);fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:1.0000000px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000"
+ d="M 13.844539,33.722286 C 17.849394,36.241097 17.487187,36.176390 22.469742,39.239096 C 22.916801,35.725090 17.275299,31.086427 17.429440,25.822301 C 16.184726,25.035740 15.082548,24.407572 13.837834,23.621015 C 13.682491,26.734833 13.858061,32.264076 13.844539,33.722286 z "
+ id="path9627"
+ sodipodi:nodetypes="ccccc" />
+ <path
+ style="fill:url(#linearGradient2877);fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:1.0000000px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000"
+ d="M 43.371100,3.6038926 C 47.375955,6.1227026 51.315631,8.4375519 55.320486,10.956360 C 51.791561,13.969140 45.182687,13.437804 38.802332,13.671877 C 32.487156,13.905952 20.599481,19.596563 17.429440,25.822301 C 16.184726,25.035740 15.396273,24.249184 14.151558,23.462627 C 24.021766,16.775060 33.500892,10.291459 43.371100,3.6038926 z "
+ id="path10395"
+ sodipodi:nodetypes="cczccc" />
+ </g>
+</svg>
diff --git a/chalk/plugins/tools/selectiontools/tool_eraser_selection_cursor.png b/chalk/plugins/tools/selectiontools/tool_eraser_selection_cursor.png
new file mode 100644
index 00000000..e6b01060
--- /dev/null
+++ b/chalk/plugins/tools/selectiontools/tool_eraser_selection_cursor.png
Binary files differ
diff --git a/chalk/plugins/tools/selectiontools/tool_outline_selection.png b/chalk/plugins/tools/selectiontools/tool_outline_selection.png
new file mode 100644
index 00000000..ca1cb1d1
--- /dev/null
+++ b/chalk/plugins/tools/selectiontools/tool_outline_selection.png
Binary files differ
diff --git a/chalk/plugins/tools/selectiontools/tool_outline_selection.svg b/chalk/plugins/tools/selectiontools/tool_outline_selection.svg
new file mode 100644
index 00000000..2795dc86
--- /dev/null
+++ b/chalk/plugins/tools/selectiontools/tool_outline_selection.svg
@@ -0,0 +1,329 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://web.resource.org/cc/"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://inkscape.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ inkscape:export-ydpi="33.000000"
+ inkscape:export-xdpi="33.000000"
+ inkscape:export-filename="/home/cyrille/koffice/chalk/plugins/tools/selectiontools/tool_outline_selection.png"
+ sodipodi:docname="tool_outline_selection.svg"
+ sodipodi:docbase="/home/cyrille/koffice/chalk/plugins/tools/selectiontools"
+ inkscape:version="0.43"
+ sodipodi:version="0.32"
+ id="svg1409"
+ height="48.000000pt"
+ width="48.000000pt">
+ <defs
+ id="defs3">
+ <radialGradient
+ r="31.677956"
+ fy="46.914463"
+ fx="48.488476"
+ cy="46.914463"
+ cx="48.488476"
+ gradientTransform="matrix(1.261963,0.000000,0.000000,1.016360,-7.978266,-0.517425)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient1333"
+ xlink:href="#light90to0"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="36.873619"
+ x2="39.857029"
+ y1="4.5492039"
+ x1="10.878086"
+ gradientTransform="matrix(1.325250,0.000000,0.000000,1.003779,-5.702957,1.287849)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1331"
+ xlink:href="#light90to0"
+ inkscape:collect="always" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#light90to0"
+ id="linearGradient9512"
+ gradientTransform="matrix(1.325250,0.000000,0.000000,1.003779,-5.702957,1.287849)"
+ x1="10.878086"
+ y1="4.5492039"
+ x2="39.857029"
+ y2="36.873619"
+ gradientUnits="userSpaceOnUse" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#light90to0"
+ id="radialGradient10280"
+ gradientTransform="matrix(1.261963,0.000000,0.000000,1.016360,-7.978266,-0.517425)"
+ cx="48.488476"
+ cy="46.914463"
+ fx="48.488476"
+ fy="46.914463"
+ r="31.677956"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ id="light90to0">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.90833336;"
+ offset="0.0000000"
+ id="stop1890" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.0000000;"
+ offset="1.0000000"
+ id="stop1892" />
+ </linearGradient>
+ <radialGradient
+ r="31.677956"
+ fy="46.914463"
+ fx="48.488476"
+ cy="46.914463"
+ cx="48.488476"
+ gradientTransform="matrix(1.181248,0.000000,0.000000,0.943878,-80.46799,5.346100)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient2086"
+ xlink:href="#light90to0"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="36.873619"
+ x2="39.857029"
+ y1="4.5492039"
+ x1="10.878086"
+ gradientTransform="matrix(1.240487,0.000000,0.000000,0.932195,-78.33821,7.022631)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient2089"
+ xlink:href="#light90to0"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="36.873619"
+ x2="39.857029"
+ y1="4.5492039"
+ x1="10.878086"
+ gradientTransform="matrix(1.240487,0.000000,0.000000,0.932195,-78.33821,7.022631)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient3732"
+ xlink:href="#light90to0"
+ inkscape:collect="always" />
+ <radialGradient
+ r="31.677956"
+ fy="46.914463"
+ fx="48.488476"
+ cy="46.914463"
+ cx="48.488476"
+ gradientTransform="matrix(1.181248,0.000000,0.000000,0.943878,-80.46799,5.346100)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient3734"
+ xlink:href="#light90to0"
+ inkscape:collect="always" />
+ <radialGradient
+ r="31.677956"
+ fy="46.914463"
+ fx="48.488476"
+ cy="46.914463"
+ cx="48.488476"
+ gradientTransform="matrix(1.472290,0.000000,0.000000,1.176435,-85.47464,-0.281735)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient3737"
+ xlink:href="#light90to0"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="36.873619"
+ x2="39.857029"
+ y1="4.5492039"
+ x1="10.878086"
+ gradientTransform="matrix(1.546124,0.000000,0.000000,1.161874,-42.82011,1.807868)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient3740"
+ xlink:href="#light90to0"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="36.873619"
+ x2="39.857029"
+ y1="4.5492039"
+ x1="10.878086"
+ gradientTransform="matrix(1.546124,0.000000,0.000000,1.161874,-82.82011,1.807868)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient3748"
+ xlink:href="#light90to0"
+ inkscape:collect="always" />
+ <radialGradient
+ r="31.677956"
+ fy="46.914463"
+ fx="48.488476"
+ cy="46.914463"
+ cx="48.488476"
+ gradientTransform="matrix(1.181248,0.000000,0.000000,0.943878,-86.67547,5.346100)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient3888"
+ xlink:href="#light90to0"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="36.873619"
+ x2="39.857029"
+ y1="4.5492039"
+ x1="10.878086"
+ gradientTransform="matrix(1.240487,0.000000,0.000000,0.932195,-84.54569,7.022631)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient3891"
+ xlink:href="#light90to0"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="36.873619"
+ x2="39.857029"
+ y1="4.5492039"
+ x1="10.878086"
+ gradientTransform="matrix(1.240487,0.000000,0.000000,0.932195,-84.54569,7.022631)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient3899"
+ xlink:href="#light90to0"
+ inkscape:collect="always" />
+ <radialGradient
+ r="31.677956"
+ fy="46.914463"
+ fx="48.488476"
+ cy="46.914463"
+ cx="48.488476"
+ gradientTransform="matrix(1.181248,0.000000,0.000000,0.943878,-86.67547,5.346100)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient3901"
+ xlink:href="#light90to0"
+ inkscape:collect="always" />
+ <radialGradient
+ r="31.677956"
+ fy="46.914463"
+ fx="48.488476"
+ cy="46.914463"
+ cx="48.488476"
+ gradientTransform="matrix(1.842551,0.000000,0.000000,1.472293,-26.91085,-7.897181)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient3904"
+ xlink:href="#light90to0"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="36.873619"
+ x2="39.857029"
+ y1="4.5492039"
+ x1="10.878086"
+ gradientTransform="matrix(1.934954,0.000000,0.000000,1.454069,-43.58874,-5.282071)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient3907"
+ xlink:href="#light90to0"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="36.873619"
+ x2="39.857029"
+ y1="4.5492039"
+ x1="10.878086"
+ gradientTransform="matrix(1.934954,0.000000,0.000000,1.454069,-23.58874,-5.282071)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient3917"
+ xlink:href="#light90to0"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="36.873619"
+ x2="39.857029"
+ y1="4.5492039"
+ x1="10.878086"
+ gradientTransform="matrix(1.934954,0,0,1.454069,-23.58874,-5.282071)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient3939"
+ xlink:href="#light90to0"
+ inkscape:collect="always" />
+ <radialGradient
+ r="31.677956"
+ fy="46.914463"
+ fx="48.488476"
+ cy="46.914463"
+ cx="48.488476"
+ gradientTransform="matrix(1.842551,0,0,1.472293,-26.91085,-7.897181)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient3941"
+ xlink:href="#light90to0"
+ inkscape:collect="always" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#light90to0"
+ id="radialGradient3103"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.843411,0,0,1.546427,-39.13262,-18.20529)"
+ cx="48.488476"
+ cy="46.914463"
+ fx="48.488476"
+ fy="46.914463"
+ r="31.677956" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#light90to0"
+ id="linearGradient3106"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.935858,0,0,1.527286,-33.53707,-3.676156)"
+ x1="10.878086"
+ y1="4.5492039"
+ x2="39.857029"
+ y2="36.873619" />
+ </defs>
+ <sodipodi:namedview
+ inkscape:window-y="29"
+ inkscape:window-x="235"
+ inkscape:window-height="691"
+ inkscape:window-width="1020"
+ inkscape:grid-bbox="true"
+ inkscape:document-units="px"
+ showgrid="false"
+ inkscape:current-layer="layer1"
+ inkscape:cy="22.245206"
+ inkscape:cx="25.345445"
+ inkscape:zoom="9.2345419"
+ inkscape:pageshadow="2"
+ inkscape:pageopacity="0.0000000"
+ borderopacity="1.0"
+ bordercolor="#666666"
+ pagecolor="#ffffff"
+ id="base"
+ showguides="true"
+ inkscape:guide-bbox="true">
+ <sodipodi:guide
+ orientation="horizontal"
+ position="58.042944"
+ id="guide3109" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata4">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:groupmode="layer"
+ inkscape:label="Layer 1"
+ id="layer1">
+ <g
+ id="g3133">
+ <path
+ sodipodi:nodetypes="cccccscccsccccc"
+ id="rect7971"
+ d="M 22.849394,11.112144 C 22.304047,11.141939 15.425943,11.91869 15.047262,12.331768 L 7.3541343,16.763497 C 8.0507357,13.290837 4.6772127,24.044979 4.9093571,24.829128 L 5.095179,32.48237 C 5.3390662,33.315932 10.443581,34.461964 11.265414,34.588229 C 12.087247,34.714496 16.080953,33.975209 17.072452,35.017738 L 21.804787,36.428944 L 28.316569,46.376029 C 28.84139,47.103755 42.100565,47.249663 42.941988,47.01984 C 43.783409,46.790016 50.779969,35.976608 50.900444,35.072628 L 49.143188,21.49569 C 48.929783,20.447666 44.468877,16.786367 43.524906,16.415097 L 31.648489,11.066661 C 32.438942,9.1963879 23.136303,11.096289 22.849394,11.112144 z "
+ style="opacity:0.79446639;fill:#0028c6;fill-opacity:0.18099551;stroke:#000000;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:0.03529412" />
+ <path
+ sodipodi:nodetypes="ccccccccccccc"
+ id="path8746"
+ d="M 12.535381,11.98598 C 11.990034,12.015775 7.4691951,16.810337 7.0905141,17.223415 L 4.8943079,23.826314 C 4.3534721,24.419518 3.8370628,31.013486 4.0692068,31.797635 L 8.0381077,33.802504 C 10.387324,34.191552 8.7498127,36.278559 14.421497,33.730917 L 17.425172,34.425233 L 22.799835,37.595929 C 32.678289,33.702865 38.728935,20.276373 45.811149,17.13009 L 47.192189,19.341024 C 47.332337,18.293 41.129487,15.11757 40.185516,14.7463 C 37.675337,13.581188 31.95859,11.853578 31.247222,10.709517 C 23.829936,10.823588 12.82229,11.970124 12.535381,11.98598 z "
+ style="opacity:0.79446639;fill:url(#linearGradient3106);fill-opacity:1;stroke:#000000;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:0.03529412" />
+ <path
+ sodipodi:nodetypes="cccscccc"
+ id="path9514"
+ d="M 24.746657,37.610946 L 22.950097,38.236511 L 28.386172,46.112853 C 28.910993,46.840579 33.910784,49.437334 34.752207,49.207511 C 35.593628,48.977687 43.373306,47.04937 43.493781,46.14539 L 49.251864,38.854219 C 51.341215,32.716608 49.361638,20.120029 48.417667,19.748759 C 48.417667,19.748759 24.285488,38.336184 24.746657,37.610946 z "
+ style="opacity:0.97233199;fill:url(#radialGradient3103);fill-opacity:1;stroke:none;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:0.98913044;stroke-dasharray:none" />
+ <path
+ id="path2106"
+ d="M 36.009663,49.13383 C 41.863248,48.780277 46.878058,43.635578 48.32345,40.661558 C 51.298229,34.540688 52.312887,27.958104 51.036579,25.168694 C 48.381437,19.365798 42.813441,14.821605 35.697096,12.295739 C 31.314921,10.740336 12.085136,10.662141 9.0276896,14.21912 C 5.2475997,18.616808 3.5467148,30.132245 6.0215885,33.31188 C 7.5774802,35.310838 15.400721,32.394315 20.603527,36.054782 C 27.129005,40.645824 27.079432,49.673211 36.009663,49.13383 z "
+ style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#313436;stroke-width:4.55000019;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:9.10000038, 9.10000038;stroke-dashoffset:0;stroke-opacity:1;marker-start:none" />
+ </g>
+ </g>
+</svg>
diff --git a/chalk/plugins/tools/selectiontools/tool_outline_selection_cursor.png b/chalk/plugins/tools/selectiontools/tool_outline_selection_cursor.png
new file mode 100644
index 00000000..10ef65fe
--- /dev/null
+++ b/chalk/plugins/tools/selectiontools/tool_outline_selection_cursor.png
Binary files differ
diff --git a/chalk/plugins/tools/selectiontools/tool_polygonal_selection.png b/chalk/plugins/tools/selectiontools/tool_polygonal_selection.png
new file mode 100644
index 00000000..eda50984
--- /dev/null
+++ b/chalk/plugins/tools/selectiontools/tool_polygonal_selection.png
Binary files differ
diff --git a/chalk/plugins/tools/selectiontools/tool_polygonal_selection.svg b/chalk/plugins/tools/selectiontools/tool_polygonal_selection.svg
new file mode 100644
index 00000000..441dc125
--- /dev/null
+++ b/chalk/plugins/tools/selectiontools/tool_polygonal_selection.svg
@@ -0,0 +1,364 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://web.resource.org/cc/"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://inkscape.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ inkscape:export-ydpi="33.000000"
+ inkscape:export-xdpi="33.000000"
+ inkscape:export-filename="/home/danny/work/kde/koffice/chalk/chalk/tool_free_form_selection.png"
+ sodipodi:docname="tool_free_form_selection.svg"
+ sodipodi:docbase="/home/danny/work/kde/koffice/chalk/chalk"
+ inkscape:version="0.41"
+ sodipodi:version="0.32"
+ id="svg1409"
+ height="48.000000pt"
+ width="48.000000pt">
+ <defs
+ id="defs3">
+ <radialGradient
+ r="31.677956"
+ fy="46.914463"
+ fx="48.488476"
+ cy="46.914463"
+ cx="48.488476"
+ gradientTransform="matrix(1.261963,0.000000,0.000000,1.016360,-7.978266,-0.517425)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient1333"
+ xlink:href="#light90to0"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="36.873619"
+ x2="39.857029"
+ y1="4.5492039"
+ x1="10.878086"
+ gradientTransform="matrix(1.325250,0.000000,0.000000,1.003779,-5.702957,1.287849)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1331"
+ xlink:href="#light90to0"
+ inkscape:collect="always" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#light90to0"
+ id="linearGradient9512"
+ gradientTransform="matrix(1.325250,0.000000,0.000000,1.003779,-5.702957,1.287849)"
+ x1="10.878086"
+ y1="4.5492039"
+ x2="39.857029"
+ y2="36.873619"
+ gradientUnits="userSpaceOnUse" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#light90to0"
+ id="radialGradient10280"
+ gradientTransform="matrix(1.261963,0.000000,0.000000,1.016360,-7.978266,-0.517425)"
+ cx="48.488476"
+ cy="46.914463"
+ fx="48.488476"
+ fy="46.914463"
+ r="31.677956"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ id="light90to0">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.90833336;"
+ offset="0.0000000"
+ id="stop1890" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.0000000;"
+ offset="1.0000000"
+ id="stop1892" />
+ </linearGradient>
+ <radialGradient
+ r="31.677956"
+ fy="46.914463"
+ fx="48.488476"
+ cy="46.914463"
+ cx="48.488476"
+ gradientTransform="matrix(1.181248,0.000000,0.000000,0.943878,-80.46799,5.346100)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient2086"
+ xlink:href="#light90to0"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="36.873619"
+ x2="39.857029"
+ y1="4.5492039"
+ x1="10.878086"
+ gradientTransform="matrix(1.240487,0.000000,0.000000,0.932195,-78.33821,7.022631)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient2089"
+ xlink:href="#light90to0"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="36.873619"
+ x2="39.857029"
+ y1="4.5492039"
+ x1="10.878086"
+ gradientTransform="matrix(1.240487,0.000000,0.000000,0.932195,-78.33821,7.022631)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient3732"
+ xlink:href="#light90to0"
+ inkscape:collect="always" />
+ <radialGradient
+ r="31.677956"
+ fy="46.914463"
+ fx="48.488476"
+ cy="46.914463"
+ cx="48.488476"
+ gradientTransform="matrix(1.181248,0.000000,0.000000,0.943878,-80.46799,5.346100)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient3734"
+ xlink:href="#light90to0"
+ inkscape:collect="always" />
+ <radialGradient
+ r="31.677956"
+ fy="46.914463"
+ fx="48.488476"
+ cy="46.914463"
+ cx="48.488476"
+ gradientTransform="matrix(1.472290,0.000000,0.000000,1.176435,-85.47464,-0.281735)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient3737"
+ xlink:href="#light90to0"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="36.873619"
+ x2="39.857029"
+ y1="4.5492039"
+ x1="10.878086"
+ gradientTransform="matrix(1.546124,0.000000,0.000000,1.161874,-42.82011,1.807868)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient3740"
+ xlink:href="#light90to0"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="36.873619"
+ x2="39.857029"
+ y1="4.5492039"
+ x1="10.878086"
+ gradientTransform="matrix(1.546124,0.000000,0.000000,1.161874,-82.82011,1.807868)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient3748"
+ xlink:href="#light90to0"
+ inkscape:collect="always" />
+ <radialGradient
+ r="31.677956"
+ fy="46.914463"
+ fx="48.488476"
+ cy="46.914463"
+ cx="48.488476"
+ gradientTransform="matrix(1.181248,0.000000,0.000000,0.943878,-86.67547,5.346100)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient3888"
+ xlink:href="#light90to0"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="36.873619"
+ x2="39.857029"
+ y1="4.5492039"
+ x1="10.878086"
+ gradientTransform="matrix(1.240487,0.000000,0.000000,0.932195,-84.54569,7.022631)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient3891"
+ xlink:href="#light90to0"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="36.873619"
+ x2="39.857029"
+ y1="4.5492039"
+ x1="10.878086"
+ gradientTransform="matrix(1.240487,0.000000,0.000000,0.932195,-84.54569,7.022631)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient3899"
+ xlink:href="#light90to0"
+ inkscape:collect="always" />
+ <radialGradient
+ r="31.677956"
+ fy="46.914463"
+ fx="48.488476"
+ cy="46.914463"
+ cx="48.488476"
+ gradientTransform="matrix(1.181248,0.000000,0.000000,0.943878,-86.67547,5.346100)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient3901"
+ xlink:href="#light90to0"
+ inkscape:collect="always" />
+ <radialGradient
+ r="31.677956"
+ fy="46.914463"
+ fx="48.488476"
+ cy="46.914463"
+ cx="48.488476"
+ gradientTransform="matrix(1.842551,0.000000,0.000000,1.472293,-26.91085,-7.897181)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient3904"
+ xlink:href="#light90to0"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="36.873619"
+ x2="39.857029"
+ y1="4.5492039"
+ x1="10.878086"
+ gradientTransform="matrix(1.934954,0.000000,0.000000,1.454069,-43.58874,-5.282071)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient3907"
+ xlink:href="#light90to0"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="36.873619"
+ x2="39.857029"
+ y1="4.5492039"
+ x1="10.878086"
+ gradientTransform="matrix(1.934954,0.000000,0.000000,1.454069,-23.58874,-5.282071)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient3917"
+ xlink:href="#light90to0"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="36.873619"
+ x2="39.857029"
+ y1="4.5492039"
+ x1="10.878086"
+ gradientTransform="matrix(1.934954,0.000000,0.000000,1.454069,-23.58874,-5.282071)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient3939"
+ xlink:href="#light90to0"
+ inkscape:collect="always" />
+ <radialGradient
+ r="31.677956"
+ fy="46.914463"
+ fx="48.488476"
+ cy="46.914463"
+ cx="48.488476"
+ gradientTransform="matrix(1.842551,0.000000,0.000000,1.472293,-26.91085,-7.897181)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient3941"
+ xlink:href="#light90to0"
+ inkscape:collect="always" />
+ </defs>
+ <sodipodi:namedview
+ inkscape:window-y="0"
+ inkscape:window-x="0"
+ inkscape:window-height="691"
+ inkscape:window-width="1020"
+ inkscape:grid-bbox="true"
+ inkscape:document-units="px"
+ showgrid="false"
+ inkscape:current-layer="layer1"
+ inkscape:cy="27.184176"
+ inkscape:cx="-0.65850022"
+ inkscape:zoom="5.3151547"
+ inkscape:pageshadow="2"
+ inkscape:pageopacity="0.0000000"
+ borderopacity="1.0"
+ bordercolor="#666666"
+ pagecolor="#ffffff"
+ id="base" />
+ <metadata
+ id="metadata4">
+ <rdf:RDF
+ id="RDF5">
+ <cc:Work
+ id="Work6"
+ rdf:about="">
+ <dc:format
+ id="format7">image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage"
+ id="type9" />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:groupmode="layer"
+ inkscape:label="Layer 1"
+ id="layer1">
+ <g
+ transform="matrix(1.000467,0.000000,0.000000,1.050353,-1.379828e-2,-4.173866e-3)"
+ id="g3921">
+ <path
+ id="rect7971"
+ d="M 17.375000,2.0000000 C 16.829907,2.0283668 16.316004,2.2629749 15.937500,2.6562500 L 2.5937500,16.468750 C 2.0531670,17.033516 1.8617140,17.847192 2.0937500,18.593750 L 10.937500,48.937500 C 11.181273,49.731102 11.866051,50.317288 12.687500,50.437500 C 13.508949,50.557713 14.320296,50.190471 14.781250,49.500000 L 29.406250,27.281250 L 49.343750,53.750000 C 49.868326,54.442840 50.752719,54.750055 51.593750,54.531250 C 52.434778,54.312444 53.067082,53.610644 53.187500,52.750000 L 57.968750,18.281250 C 58.108832,17.283468 57.537280,16.322221 56.593750,15.968750 L 18.218750,2.1250000 C 17.948669,2.0274078 17.661775,1.9849050 17.375000,2.0000000 z "
+ style="opacity:0.79446638;fill:#0028c6;fill-opacity:0.18099548;stroke:#000000;stroke-width:0.0000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:0.035294119" />
+ <path
+ id="path8746"
+ d="M 17.375000,2.0000000 C 16.829907,2.0283668 16.316004,2.2629749 15.937500,2.6562500 L 2.5937500,16.468750 C 2.0531670,17.033516 1.8617140,17.847192 2.0937500,18.593750 L 8.8750000,41.843750 C 14.686753,37.780942 20.518465,34.613010 26.187500,32.187500 L 29.406250,27.281250 L 31.531250,30.093750 C 41.405093,26.387316 50.483592,24.120453 57.562500,21.125000 L 57.968750,18.281250 C 58.108832,17.283468 57.537280,16.322221 56.593750,15.968750 L 18.218750,2.1250000 C 17.948669,2.0274078 17.661775,1.9849050 17.375000,2.0000000 z "
+ style="opacity:0.79446638;fill:url(#linearGradient3939);fill-opacity:1.0000000;stroke:#000000;stroke-width:0.0000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:0.035294119" />
+ <path
+ id="path9514"
+ d="M 17.375000,2.0000000 C 16.829907,2.0283668 16.316004,2.2629749 15.937500,2.6562500 L 2.5937500,16.468750 C 2.0531669,17.033516 1.8617138,17.847192 2.0937500,18.593750 L 10.937500,48.937500 C 11.181273,49.731102 11.866051,50.317288 12.687500,50.437500 C 13.508949,50.557713 14.320296,50.190471 14.781250,49.500000 L 29.406250,27.281250 L 49.343750,53.750000 C 49.868326,54.442840 50.752719,54.750055 51.593750,54.531250 C 52.434778,54.312444 53.067082,53.610644 53.187500,52.750000 L 57.968750,18.281250 C 58.108832,17.283468 57.537280,16.322221 56.593750,15.968750 L 18.218750,2.1250000 C 17.948669,2.0274078 17.661775,1.9849050 17.375000,2.0000000 z "
+ style="opacity:0.97233200;fill:url(#radialGradient3941);fill-opacity:1.0000000;stroke:#000000;stroke-width:0.0000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:0.035294119" />
+ <path
+ style="fill:#313436;fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:5.5999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000"
+ d="M 8.6481316,10.370821 C 9.0694886,10.762535 9.6315137,10.971157 10.209233,10.950300 C 10.786951,10.929442 11.332479,10.680836 11.724507,10.259761 L 18.077610,3.6451297 C 18.906443,2.7821760 18.872528,1.4176197 18.001859,0.59730246 C 17.131190,-0.22301475 15.753473,-0.18845315 14.924639,0.67449856 L 8.5715367,7.2891303 C 8.1605414,7.7038582 7.9367018,8.2657613 7.9511347,8.8465013 C 7.9655693,9.4272353 8.2170464,9.9772121 8.6481316,10.370821 L 8.6481316,10.370821 z "
+ id="path2087"
+ sodipodi:nodetypes="cccccccccc" />
+ <path
+ sodipodi:nodetypes="ccccccccccccc"
+ id="path2089"
+ d="M 5.5937500,11.343750 C 5.0368829,11.357720 4.4769170,11.568524 4.0625000,12.000000 C 4.0625000,12.000000 0.50659364,15.741591 0.50000000,15.750000 C 0.10513172,16.257539 -0.082274591,16.897542 0.062500000,17.531250 L 1.1250000,21.562500 C 1.2648167,22.129393 1.6218102,22.615962 2.1250000,22.906250 C 2.6281851,23.196535 3.2206730,23.287838 3.7812500,23.125000 C 4.3351411,22.969478 4.8105180,22.597711 5.0937500,22.093750 C 5.3769801,21.589792 5.4676180,20.991512 5.3125000,20.437500 L 4.5937500,17.718750 L 7.2187500,15.000000 C 8.0475832,14.137046 8.0269190,12.757817 7.1562500,11.937500 C 6.7209155,11.527341 6.1506171,11.329780 5.5937500,11.343750 z "
+ style="fill:#313436;fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:5.5999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000" />
+ <path
+ style="fill:#313436;fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:5.5999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000"
+ d="M 7.8868333,38.699343 C 8.4407237,38.543821 8.9116405,38.172834 9.1948718,37.668873 C 9.4781022,37.164915 9.5501733,36.569759 9.3950554,36.015747 L 7.0598062,27.146594 C 6.7551456,25.989514 5.5728074,25.307429 4.4189752,25.623112 C 3.2651421,25.938795 2.5767516,27.132703 2.8814101,28.289785 L 5.2166600,37.158936 C 5.3564767,37.725829 5.7194324,38.209671 6.2226220,38.499959 C 6.7258074,38.790243 7.3262566,38.862181 7.8868333,38.699343 L 7.8868333,38.699343 z "
+ id="path2093"
+ sodipodi:nodetypes="cccccccccc" />
+ <path
+ style="fill:#313436;fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:5.5999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000"
+ d="M 14.845837,48.569694 C 15.332393,48.876689 15.923312,48.977728 16.487199,48.850345 C 17.051085,48.722962 17.541200,48.377717 17.848556,47.891381 L 22.868183,40.215537 C 23.523050,39.214136 23.237259,37.879413 22.229852,37.234343 C 21.222444,36.589272 19.874906,36.878133 19.220039,37.879532 L 14.200411,45.555378 C 13.873242,46.038985 13.757226,46.632601 13.878855,47.200646 C 14.000483,47.768683 14.349372,48.262637 14.845837,48.569694 L 14.845837,48.569694 z "
+ id="path2097"
+ sodipodi:nodetypes="cccccccccc" />
+ <path
+ style="fill:#313436;fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:5.5999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000"
+ d="M 53.502723,51.490318 C 54.074440,51.554532 54.650310,51.387895 55.102284,51.027459 C 55.554259,50.667026 55.844876,50.142670 55.909511,49.570995 L 57.081400,40.474736 C 57.234286,39.288026 56.395289,38.211345 55.207443,38.069894 C 54.019597,37.928443 52.932720,38.775791 52.779832,39.962498 L 51.607944,49.058758 C 51.524287,49.636614 51.678621,50.221440 52.035689,50.679664 C 52.392753,51.137884 52.922062,51.430367 53.502723,51.490318 L 53.502723,51.490318 z "
+ id="path2107"
+ sodipodi:nodetypes="cccccccccc" />
+ <path
+ style="fill:#313436;fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:5.5999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000"
+ d="M 55.454158,36.325345 C 56.025875,36.389559 56.601745,36.222922 57.053719,35.862486 C 57.505694,35.502053 57.796311,34.977697 57.860946,34.406022 L 59.032835,25.309763 C 59.185721,24.123053 58.346724,23.046372 57.158878,22.904921 C 55.971032,22.763470 54.884155,23.610818 54.731267,24.797525 L 53.559379,33.893785 C 53.475722,34.471641 53.630056,35.056467 53.987124,35.514691 C 54.344188,35.972911 54.873497,36.265394 55.454158,36.325345 L 55.454158,36.325345 z "
+ id="path2109"
+ sodipodi:nodetypes="cccccccccc" />
+ <path
+ sodipodi:nodetypes="cccccccccccccc"
+ id="path2111"
+ d="M 52.125000,12.718750 C 51.578617,12.512884 50.961744,12.530980 50.437500,12.781250 C 49.913260,13.031518 49.527067,13.477034 49.343750,14.031250 C 49.158194,14.575817 49.182597,15.168637 49.437500,15.687500 C 49.692398,16.206364 50.143066,16.626540 50.687500,16.812500 L 55.562500,18.562500 L 55.531250,18.718750 C 55.447594,19.296606 55.580432,19.885526 55.937500,20.343750 C 56.294564,20.801969 56.825589,21.096299 57.406250,21.156250 C 57.977968,21.220463 58.548026,21.047936 59.000000,20.687500 C 59.641312,20.209036 59.634683,19.555393 59.753290,19.028646 L 59.968750,17.312500 C 60.093283,16.325572 59.524592,15.382062 58.593750,15.031250 L 52.125000,12.718750 z "
+ style="fill:#313436;fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:5.5999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000" />
+ <path
+ style="fill:#313436;fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:5.5999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000"
+ d="M 34.876639,8.8113360 C 34.689606,9.3553976 34.726993,9.9537253 34.980487,10.473277 C 35.233979,10.992831 35.682567,11.390545 36.226496,11.577981 L 44.850059,14.700384 C 45.975101,15.107737 47.208498,14.523022 47.604936,13.394384 C 48.001375,12.265747 47.410726,11.020582 46.285688,10.613227 L 37.662124,7.4908252 C 37.116299,7.2834789 36.511906,7.3069090 35.986986,7.5557573 C 35.462070,7.8046027 35.061458,8.2576184 34.876639,8.8113360 L 34.876639,8.8113360 z "
+ id="path2113"
+ sodipodi:nodetypes="cccccccccc" />
+ <path
+ style="fill:#313436;fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:5.5999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000"
+ d="M 20.535381,3.6342430 C 20.347428,4.1779876 20.383803,4.7763777 20.636419,5.2963578 C 20.889032,5.8163388 21.336947,6.2148117 21.880557,6.4031665 L 30.498828,9.5401482 C 31.623180,9.9494029 32.857563,9.3667746 33.255910,8.2388091 C 33.654256,7.1108435 33.065714,5.8646820 31.941366,5.4554254 L 23.323095,2.3184446 C 22.777622,2.1101755 22.173190,2.1325835 21.647849,2.3805438 C 21.122514,2.6285012 20.721136,3.0808388 20.535381,3.6342430 L 20.535381,3.6342430 z "
+ id="path2115"
+ sodipodi:nodetypes="cccccccccc" />
+ <path
+ style="fill:#313436;fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:5.5999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000"
+ d="M 11.883900,54.049469 C 12.437791,53.893947 12.908707,53.522960 13.191939,53.018999 C 13.475169,52.515041 13.547240,51.919885 13.392122,51.365873 L 11.056873,42.496720 C 10.752212,41.339640 9.5698742,40.657555 8.4160420,40.973238 C 7.2622089,41.288921 6.5738184,42.482829 6.8784769,43.639911 L 9.2137268,52.509062 C 9.3535435,53.075955 9.7164992,53.559797 10.219689,53.850085 C 10.722874,54.140369 11.323323,54.212307 11.883900,54.049469 L 11.883900,54.049469 z "
+ id="path2121"
+ sodipodi:nodetypes="cccccccccc" />
+ <path
+ sodipodi:nodetypes="ccccccccccccccc"
+ id="path2099"
+ d="M 29.156250,24.562500 C 28.461523,24.581109 27.825733,24.923573 27.437500,25.500000 L 22.781250,32.593750 C 22.457548,33.079684 22.343061,33.651590 22.468750,34.218750 C 22.594438,34.785901 22.938852,35.290252 23.437500,35.593750 C 23.926238,35.897258 24.530788,36.006413 25.093750,35.875000 C 25.656710,35.743585 26.133631,35.394772 26.437500,34.906250 L 29.312500,30.468750 L 29.906250,31.250000 C 30.255702,31.717759 30.767252,32.022222 31.343750,32.093750 C 31.920244,32.165278 32.515769,31.993198 32.968750,31.625000 C 33.418422,31.266142 33.716522,30.730711 33.781250,30.156250 C 33.845978,29.581791 33.671031,29.012439 33.312500,28.562500 C 33.312500,28.562500 30.865791,25.401380 30.843750,25.375000 C 30.423614,24.870406 29.816399,24.544818 29.156250,24.562500 z "
+ style="fill:#313436;fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:5.5999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000" />
+ <path
+ style="fill:#313436;fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:5.5999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000"
+ d="M 42.423622,44.325356 C 42.878330,43.972902 43.175108,43.452021 43.247964,42.878534 C 43.320822,42.305049 43.163721,41.726493 42.811598,41.271522 L 37.311605,33.932222 C 36.594069,32.974726 35.241996,32.787492 34.291657,33.514020 C 33.341318,34.240548 33.152594,35.605716 33.870127,36.563210 L 39.370120,43.902511 C 39.712913,44.375173 40.231215,44.686948 40.806642,44.766633 C 41.382064,44.846318 41.965473,44.687102 42.423622,44.325356 L 42.423622,44.325356 z "
+ id="path2103"
+ sodipodi:nodetypes="cccccccccc" />
+ <path
+ style="fill:#313436;fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:5.5999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000"
+ d="M 51.816951,56.666238 C 52.271659,56.313784 52.568437,55.792903 52.641293,55.219416 C 52.714151,54.645931 52.557050,54.067375 52.204927,53.612404 L 46.704934,46.273104 C 45.987398,45.315608 44.635325,45.128374 43.684986,45.854902 C 42.734647,46.581430 42.545923,47.946598 43.263456,48.904092 L 48.763449,56.243393 C 49.106242,56.716055 49.624544,57.027830 50.199971,57.107515 C 50.775393,57.187200 51.358802,57.027984 51.816951,56.666238 L 51.816951,56.666238 z "
+ id="path2105"
+ sodipodi:nodetypes="cccccccccc" />
+ </g>
+ </g>
+</svg>
diff --git a/chalk/plugins/tools/selectiontools/tool_polygonal_selection_cursor.png b/chalk/plugins/tools/selectiontools/tool_polygonal_selection_cursor.png
new file mode 100644
index 00000000..6bf000a7
--- /dev/null
+++ b/chalk/plugins/tools/selectiontools/tool_polygonal_selection_cursor.png
Binary files differ
diff --git a/chalk/plugins/tools/selectiontools/tool_rect_selection.png b/chalk/plugins/tools/selectiontools/tool_rect_selection.png
new file mode 100644
index 00000000..7cb658c8
--- /dev/null
+++ b/chalk/plugins/tools/selectiontools/tool_rect_selection.png
Binary files differ
diff --git a/chalk/plugins/tools/selectiontools/tool_rect_selection.svg b/chalk/plugins/tools/selectiontools/tool_rect_selection.svg
new file mode 100644
index 00000000..824bcc78
--- /dev/null
+++ b/chalk/plugins/tools/selectiontools/tool_rect_selection.svg
@@ -0,0 +1,191 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://web.resource.org/cc/"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://inkscape.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="48.000000pt"
+ height="48.000000pt"
+ id="svg1409"
+ sodipodi:version="0.32"
+ inkscape:version="0.41"
+ sodipodi:docbase="/home/danny/work/kde/koffice/chalk/chalk"
+ sodipodi:docname="tool_rect_selection.svg"
+ inkscape:export-filename="/home/danny/work/kde/koffice/chalk/chalk/tool_rect_selection.png"
+ inkscape:export-xdpi="33.000000"
+ inkscape:export-ydpi="33.000000">
+ <defs
+ id="defs3">
+ <linearGradient
+ gradientUnits="userSpaceOnUse"
+ y2="36.873619"
+ x2="39.857029"
+ y1="4.5492039"
+ x1="10.878086"
+ gradientTransform="matrix(1.325250,0.000000,0.000000,1.003779,-5.702957,1.287849)"
+ id="linearGradient9512"
+ xlink:href="#light90to0"
+ inkscape:collect="always" />
+ <radialGradient
+ gradientUnits="userSpaceOnUse"
+ r="31.677956"
+ fy="46.914463"
+ fx="48.488476"
+ cy="46.914463"
+ cx="48.488476"
+ gradientTransform="matrix(1.261963,0.000000,0.000000,1.016360,-7.978266,-0.517425)"
+ id="radialGradient10280"
+ xlink:href="#light90to0"
+ inkscape:collect="always" />
+ <linearGradient
+ id="light90to0">
+ <stop
+ id="stop1890"
+ offset="0.0000000"
+ style="stop-color:#ffffff;stop-opacity:0.90833336;" />
+ <stop
+ id="stop1892"
+ offset="1.0000000"
+ style="stop-color:#ffffff;stop-opacity:0.0000000;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#light90to0"
+ id="linearGradient1331"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.325250,0.000000,0.000000,1.003779,-5.702957,1.287849)"
+ x1="10.878086"
+ y1="4.5492039"
+ x2="39.857029"
+ y2="36.873619" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#light90to0"
+ id="radialGradient1333"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.261963,0.000000,0.000000,1.016360,-7.978266,-0.517425)"
+ cx="48.488476"
+ cy="46.914463"
+ fx="48.488476"
+ fy="46.914463"
+ r="31.677956" />
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="5.5000000"
+ inkscape:cx="32.000000"
+ inkscape:cy="40.678134"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ inkscape:document-units="px"
+ inkscape:grid-bbox="true"
+ inkscape:window-width="1020"
+ inkscape:window-height="691"
+ inkscape:window-x="0"
+ inkscape:window-y="0" />
+ <metadata
+ id="metadata4">
+ <rdf:RDF
+ id="RDF5">
+ <cc:Work
+ rdf:about=""
+ id="Work6">
+ <dc:format
+ id="format7">image/svg+xml</dc:format>
+ <dc:type
+ id="type9"
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ id="layer1"
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer">
+ <g
+ id="g1310"
+ transform="matrix(0.936040,0.000000,0.000000,0.928685,-8.886478e-6,5.826625)">
+ <path
+ id="rect7971"
+ d="M 7.6485855,2.2878450 L 56.351415,2.2878450 C 58.926731,2.2878450 61.000000,4.4309970 61.000000,7.0931190 L 61.000000,45.000000 C 61.000000,47.662122 58.926731,49.805274 56.351415,49.805274 L 7.6485855,49.805274 C 5.0732693,49.805274 3.0000002,47.662122 3.0000002,45.000000 L 3.0000002,7.0931190 C 3.0000002,4.4309970 5.0732693,2.2878450 7.6485855,2.2878450 z "
+ style="opacity:0.79446638;fill:#0028c6;fill-opacity:0.18099548;stroke:#000000;stroke-width:0.0000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:0.035294119" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path8746"
+ d="M 8.5132467,3.2878450 L 59.896282,3.2878450 C 62.101921,28.660784 28.667547,14.447098 3.6088412,46.000000 L 3.6088412,8.0931190 C 3.6088412,5.4309970 5.7962062,3.2878450 8.5132467,3.2878450 z "
+ style="opacity:0.79446638;fill:url(#linearGradient1331);fill-opacity:1.0000000;stroke:#000000;stroke-width:0.0000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:0.035294119" />
+ <path
+ id="path9514"
+ d="M 5.7287330,1.4825710 L 55.271266,1.4825710 C 57.890984,1.4825710 59.999999,3.6257230 59.999999,6.2878450 L 59.999999,44.194726 C 59.999999,46.856848 57.890984,49.000000 55.271266,49.000000 L 5.7287330,49.000000 C 3.1090150,49.000000 1.0000000,46.856848 1.0000000,44.194726 L 1.0000000,6.2878450 C 1.0000000,3.6257230 3.1090150,1.4825710 5.7287330,1.4825710 z "
+ style="opacity:0.97233200;fill:url(#radialGradient1333);fill-opacity:1.0000000;stroke:#000000;stroke-width:0.0000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:0.035294119" />
+ <path
+ id="path7697"
+ d="M 2.3413348,0.18751303 C 1.7243174,0.17079029 1.1269735,0.40863721 0.68575030,0.84672471 C 0.24452789,1.2848122 -0.0028841323,1.8857183 2.9672780e-05,2.5121821 L 2.9672780e-05,9.8736341 C 2.9672780e-05,11.157514 1.0254798,12.198303 2.2904369,12.198303 C 3.5553939,12.198303 4.5808440,11.157514 4.5808440,9.8736341 L 4.5808440,4.8626808 L 6.3113739,4.8885105 C 7.1481898,4.9449167 7.9479829,4.5305867 8.3938928,3.8096698 C 8.8398019,3.0887537 8.8598630,2.1775984 8.4461271,1.4371840 C 8.0323920,0.69677054 7.2516331,0.24659228 6.4131698,0.26500200 L 2.3413348,0.18751303 z "
+ style="fill:#313436;fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:5.5999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000" />
+ <path
+ sodipodi:nodetypes="cccccccc"
+ id="path7695"
+ d="M 47.176002,0.18683303 C 45.911045,0.17256762 44.874201,1.2017931 44.860146,2.4856724 C 44.846091,3.7695518 45.860147,4.8219057 47.125104,4.8361712 L 56.821161,4.9653194 C 57.660564,5.0158241 58.459241,4.5933914 58.899319,3.8661498 C 59.339396,3.1389073 59.349459,2.2248747 58.925501,1.4878344 C 58.501542,0.75079486 57.712364,0.31035500 56.872059,0.34181097 L 47.176002,0.18683303 z "
+ style="fill:#313436;fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:5.5999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000" />
+ <path
+ sodipodi:nodetypes="cccccccccc"
+ id="path1937"
+ d="M 61.783704,5.4543804 C 61.175397,5.4585016 60.593926,5.7091294 60.168584,6.1505355 C 59.743242,6.5919408 59.509289,7.1875338 59.518746,7.8048791 L 59.518746,17.645978 C 59.518746,18.929858 60.544196,19.970647 61.809153,19.970647 C 63.074110,19.970647 64.099560,18.929858 64.099560,17.645978 L 64.099560,7.8048791 C 64.109217,7.1785351 63.868327,6.5749651 63.431909,6.1320183 C 62.995491,5.6890724 62.400817,5.4445792 61.783704,5.4543804 L 61.783704,5.4543804 z "
+ style="fill:#313436;fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:5.5999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000" />
+ <path
+ id="path7691"
+ d="M 61.783704,39.758546 C 61.175397,39.762668 60.593926,40.013295 60.168584,40.454702 C 59.743242,40.896107 59.509289,41.491700 59.518746,42.109045 L 59.518746,47.223317 L 57.737318,47.223317 C 56.472361,47.223317 55.446911,48.264107 55.446911,49.547986 C 55.446911,50.831866 56.472361,51.872655 57.737318,51.872655 L 61.809153,51.872655 C 62.417418,51.875356 63.001539,51.631303 63.431652,51.194756 C 63.861765,50.758209 64.102221,50.165350 64.099560,49.547986 L 64.099560,42.109045 C 64.109217,41.482701 63.868327,40.879131 63.431909,40.436184 C 62.995491,39.993238 62.400817,39.748745 61.783704,39.758546 z "
+ style="fill:#313436;fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:5.5999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000" />
+ <path
+ sodipodi:nodetypes="cccccccc"
+ id="path7735"
+ d="M 14.126001,0.18683303 C 12.861044,0.17256762 11.824200,1.2017931 11.810145,2.4856724 C 11.796090,3.7695518 12.810146,4.8219057 14.075103,4.8361712 L 23.771160,4.9653194 C 24.610563,5.0158241 25.409240,4.5933914 25.849318,3.8661498 C 26.289395,3.1389073 26.299458,2.2248747 25.875500,1.4878344 C 25.451541,0.75079486 24.662363,0.31035500 23.822058,0.34181097 L 14.126001,0.18683303 z "
+ style="fill:#313436;fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:5.5999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000" />
+ <path
+ sodipodi:nodetypes="cccccccc"
+ id="path7745"
+ d="M 24.746000,47.090119 C 23.481043,47.075854 22.444199,48.105079 22.430144,49.388958 C 22.416089,50.672838 23.430145,51.725192 24.695102,51.739457 L 34.391159,51.868605 C 35.230562,51.919110 36.029239,51.496677 36.469317,50.769436 C 36.909395,50.042193 36.919457,49.128161 36.495499,48.391120 C 36.071541,47.654081 35.282363,47.213641 34.442057,47.245097 L 24.746000,47.090119 z "
+ style="fill:#313436;fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:5.5999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000" />
+ <path
+ sodipodi:nodetypes="cccccccc"
+ id="path7751"
+ d="M 7.2160002,47.090119 C 5.9510431,47.075854 4.9141995,48.105079 4.9001443,49.388958 C 4.8860891,50.672838 5.9001452,51.725192 7.1651023,51.739457 L 16.861159,51.868605 C 17.700562,51.919110 18.499239,51.496677 18.939317,50.769436 C 19.379395,50.042193 19.389457,49.128161 18.965499,48.391120 C 18.541541,47.654081 17.752363,47.213641 16.912057,47.245097 L 7.2160002,47.090119 z "
+ style="fill:#313436;fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:5.5999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000" />
+ <path
+ sodipodi:nodetypes="cccccccccc"
+ id="path7765"
+ d="M 61.699014,22.811910 C 61.090707,22.816032 60.509236,23.066659 60.083894,23.508065 C 59.658552,23.949471 59.424599,24.545064 59.434056,25.162409 L 59.434056,35.003508 C 59.434056,36.287388 60.459506,37.328177 61.724463,37.328177 C 62.989420,37.328177 64.014870,36.287388 64.014870,35.003508 L 64.014870,25.162409 C 64.024527,24.536065 63.783637,23.932495 63.347219,23.489548 C 62.910801,23.046602 62.316127,22.802109 61.699014,22.811910 L 61.699014,22.811910 z "
+ style="fill:#313436;fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:5.5999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000" />
+ <path
+ sodipodi:nodetypes="cccccccccc"
+ id="path7775"
+ d="M 2.3431661,15.039565 C 1.7348592,15.043687 1.1533882,15.294314 0.72804592,15.735720 C 0.30270448,16.177126 0.068751498,16.772719 0.078207928,17.390064 L 0.078207928,27.231163 C 0.078207928,28.515043 1.1036580,29.555832 2.3686151,29.555832 C 3.6335722,29.555832 4.6590223,28.515043 4.6590223,27.231163 L 4.6590223,17.390064 C 4.6686791,16.763720 4.4277893,16.160150 3.9913717,15.717203 C 3.5549532,15.274257 2.9602788,15.029764 2.3431661,15.039565 L 2.3431661,15.039565 z "
+ style="fill:#313436;fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:5.5999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000" />
+ <path
+ sodipodi:nodetypes="cccccccccc"
+ id="path7781"
+ d="M 2.3431661,32.317224 C 1.7348592,32.321346 1.1533882,32.571973 0.72804592,33.013379 C 0.30270448,33.454785 0.068751498,34.050378 0.078207928,34.667723 L 0.078207928,44.508822 C 0.078207928,45.792702 1.1036580,46.833491 2.3686151,46.833491 C 3.6335722,46.833491 4.6590223,45.792702 4.6590223,44.508822 L 4.6590223,34.667723 C 4.6686791,34.041379 4.4277893,33.437809 3.9913717,32.994862 C 3.5549532,32.551916 2.9602788,32.307423 2.3431661,32.317224 L 2.3431661,32.317224 z "
+ style="fill:#313436;fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:5.5999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000" />
+ <path
+ sodipodi:nodetypes="cccccccc"
+ id="path1546"
+ d="M 30.725998,0.18683303 C 29.461041,0.17256762 28.424197,1.2017931 28.410142,2.4856724 C 28.396087,3.7695518 29.410143,4.8219057 30.675100,4.8361712 L 40.371157,4.9653194 C 41.210560,5.0158241 42.009237,4.5933914 42.449315,3.8661498 C 42.889392,3.1389073 42.899455,2.2248747 42.475497,1.4878344 C 42.051538,0.75079486 41.262360,0.31035500 40.422055,0.34181097 L 30.725998,0.18683303 z "
+ style="fill:#313436;fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:5.5999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000" />
+ <path
+ sodipodi:nodetypes="cccccccc"
+ id="path1558"
+ d="M 41.645996,47.090119 C 40.381039,47.075854 39.344195,48.105079 39.330140,49.388958 C 39.316085,50.672838 40.330141,51.725192 41.595098,51.739457 L 51.291155,51.868605 C 52.130558,51.919110 52.929235,51.496677 53.369313,50.769436 C 53.809391,50.042193 53.819453,49.128161 53.395495,48.391120 C 52.971537,47.654081 52.182359,47.213641 51.342053,47.245097 L 41.645996,47.090119 z "
+ style="fill:#313436;fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:5.5999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000" />
+ </g>
+ </g>
+</svg>
diff --git a/chalk/plugins/tools/selectiontools/tool_rectangular_selection_cursor.png b/chalk/plugins/tools/selectiontools/tool_rectangular_selection_cursor.png
new file mode 100644
index 00000000..548d8ace
--- /dev/null
+++ b/chalk/plugins/tools/selectiontools/tool_rectangular_selection_cursor.png
Binary files differ
diff --git a/chalk/plugins/tools/tool_crop/Makefile.am b/chalk/plugins/tools/tool_crop/Makefile.am
new file mode 100644
index 00000000..66157332
--- /dev/null
+++ b/chalk/plugins/tools/tool_crop/Makefile.am
@@ -0,0 +1,37 @@
+kde_services_DATA = chalktoolcrop.desktop
+
+# all_includes must remain last!
+INCLUDES = -I$(srcdir)/../../../sdk \
+ -I$(srcdir)/../../../core \
+ -I$(srcdir)/../../../chalkcolor/ \
+ -I$(srcdir)/../../../ui \
+ -I$/../../../ui \
+ $(KOFFICE_INCLUDES) \
+ $(all_includes)
+
+chalktoolcrop_la_SOURCES = \
+ wdg_tool_crop.ui \
+ tool_crop.cc \
+ kis_tool_crop.cc
+
+# Install this plugin in the KDE modules directory
+kde_module_LTLIBRARIES = chalktoolcrop.la
+
+noinst_HEADERS = \
+ tool_crop.h \
+ kis_tool_crop.h
+
+chalktoolcrop_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) $(LIB_QT) -lkdecore -lkdeui -lkjs -lkdefx -lkio -lkparts -L../../../../chalk/chalkcolor/.libs -lchalkcolor -L../../../../chalk/core/.libs -lchalkimage \
+ -L../../../../chalk/ui/.libs -lchalkui
+chalktoolcrop_la_LIBADD = ../../../libchalkcommon.la
+
+chalktoolcrop_la_METASOURCES = AUTO
+
+KDE_OPTIONS = nofinal
+
+chalkpics_DATA = \
+ tool_crop_cursor.png \
+ tool_crop.png
+
+chalkpicsdir = $(kde_datadir)/chalk/pics
+
diff --git a/chalk/plugins/tools/tool_crop/chalktoolcrop.desktop b/chalk/plugins/tools/tool_crop/chalktoolcrop.desktop
new file mode 100644
index 00000000..ef80a5e6
--- /dev/null
+++ b/chalk/plugins/tools/tool_crop/chalktoolcrop.desktop
@@ -0,0 +1,47 @@
+[Desktop Entry]
+Name=Crop Tool
+Name[bg]=Инструмент за изрязване
+Name[br]=Ostilh krennañ
+Name[ca]=Eina de tall
+Name[cy]=Hidlen Docio
+Name[da]=Beskæringsværktøj
+Name[de]=Zuschneidewerkzeug
+Name[el]=Εργαλείο αποκοπής
+Name[eo]=Tondado-ilo
+Name[es]=Herramienta para recortar
+Name[et]=Kärpimistööriist
+Name[eu]=Ebaki tresna
+Name[fa]=ابزار خط برش
+Name[fr]=Outil découpage
+Name[fy]=Bysnei-ark
+Name[ga]=Uirlis Bhearrtha
+Name[gl]=Ferramenta de Recorte
+Name[he]=כלי חיתוך
+Name[hu]=Levágó eszköz
+Name[is]=Sniðtól
+Name[it]=Strumento di taglio
+Name[ja]=切り取りツール
+Name[km]=ឧបករណ៍​ច្រឹប
+Name[ms]=Alat Pangkas
+Name[nb]=Beskjæringsverktøy
+Name[nds]=Tosniedwarktüüch
+Name[ne]=उपकरण काटछाँट गर्नुहोस्
+Name[nl]=Snijgereedschap
+Name[nn]=Beskjæringsverktøy
+Name[pl]=Narzędzie przycinania
+Name[pt]=Ferramenta de Recorte
+Name[pt_BR]=Ferramenta de Recorte
+Name[ru]=Обрезка
+Name[se]=Čuohpanreaiddut
+Name[sk]=Orezávač
+Name[sl]=Orodje za obrezavo
+Name[sr]=Алат за сасецање
+Name[sr@Latn]=Alat za sasecanje
+Name[sv]=Beskärningsverktyg
+Name[uk]=Засіб обрізування
+Name[zh_CN]=裁剪工具
+Name[zh_TW]=剪裁工具
+ServiceTypes=Chalk/Tool
+Type=Service
+X-KDE-Library=chalktoolcrop
+X-Chalk-Version=2
diff --git a/chalk/plugins/tools/tool_crop/kis_tool_crop.cc b/chalk/plugins/tools/tool_crop/kis_tool_crop.cc
new file mode 100644
index 00000000..30709fd7
--- /dev/null
+++ b/chalk/plugins/tools/tool_crop/kis_tool_crop.cc
@@ -0,0 +1,925 @@
+/*
+ * kis_tool_crop.cc -- part of Chalk
+ *
+ * Copyright (c) 2004 Boudewijn Rempt <boud@valdyas.org>
+ * Copyright (c) 2005 Michael Thaler <michael.thaler@physik.tu-muenchen.de>
+ * Copyright (c) 2006 Cyrille Berger <cberger@cberger.net>
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+
+#include <tqcheckbox.h>
+#include <tqcombobox.h>
+#include <tqobject.h>
+#include <tqpainter.h>
+#include <tqpen.h>
+#include <tqpushbutton.h>
+#include <tqrect.h>
+
+#include <kdebug.h>
+#include <kaction.h>
+#include <kcommand.h>
+#include <klocale.h>
+#include <knuminput.h>
+#include <kdebug.h>
+
+#include <kis_global.h>
+#include <kis_painter.h>
+#include <kis_canvas_controller.h>
+#include <kis_canvas_subject.h>
+#include <kis_cursor.h>
+#include <kis_image.h>
+#include <kis_undo_adapter.h>
+#include <kis_button_press_event.h>
+#include <kis_button_release_event.h>
+#include <kis_move_event.h>
+#include <kis_selected_transaction.h>
+#include <kis_selection.h>
+#include <kis_layer.h>
+#include <kis_crop_visitor.h>
+
+#include "kis_tool_crop.h"
+#include "wdg_tool_crop.h"
+
+#include "kis_canvas.h"
+#include "kis_canvas_painter.h"
+
+
+
+KisToolCrop::KisToolCrop()
+ : super(i18n("Crop"))
+{
+ setName("tool_crop");
+ m_cropCursor = KisCursor::load("tool_crop_cursor.png", 6, 6);
+ setCursor(m_cropCursor);
+ m_subject = 0;
+ m_selecting = false;
+ m_rectCrop = TQRect(0, 0, 0, 0);
+ m_handleSize = 13;
+ m_haveCropSelection = false;
+ m_optWidget = 0;
+}
+
+KisToolCrop::~KisToolCrop()
+{
+}
+
+void KisToolCrop::update(KisCanvasSubject *subject)
+{
+ m_subject = subject;
+ super::update(m_subject);
+}
+
+void KisToolCrop::activate()
+{
+ super::activate();
+
+ // No current crop rectangle, try to use the selection of the device to make a rectangle
+ if (m_subject && m_subject->currentImg() && m_subject->currentImg()->activeDevice()) {
+ KisPaintDeviceSP device = m_subject->currentImg()->activeDevice();
+ if (!device->hasSelection()) {
+ //m_rectCrop = m_subject->currentImg()->bounds();
+ //validateSelection();
+ m_haveCropSelection = false;
+ m_selecting = false;
+ }
+ else {
+
+ m_rectCrop = device->selection()->selectedRect();
+ validateSelection();
+ crop();
+ }
+ }
+}
+
+void KisToolCrop::deactivate()
+{
+ clearRect();
+}
+
+
+void KisToolCrop::paint(KisCanvasPainter& gc)
+{
+ paintOutlineWithHandles(gc, TQRect());
+}
+
+void KisToolCrop::paint(KisCanvasPainter& gc, const TQRect& rc)
+{
+ paintOutlineWithHandles(gc, rc);
+}
+
+void KisToolCrop::clearRect()
+{
+ kdDebug() << "Clearing\n";
+ if (m_subject) {
+
+ KisCanvasController *controller = m_subject->canvasController();
+ KisImageSP img = m_subject->currentImg();
+
+ Q_ASSERT(controller);
+
+ controller->kiscanvas()->update();
+
+ m_rectCrop = TQRect(0,0,0,0);
+
+ updateWidgetValues();
+ m_selecting = false;
+ }
+}
+
+void KisToolCrop::buttonPress(KisButtonPressEvent *e)
+{
+ if (m_subject) {
+ KisImageSP img = m_subject->currentImg();
+
+ if (img && img->activeDevice() && e->button() == Qt::LeftButton) {
+
+ TQPoint pos = e->pos().floorTQPoint();
+ TQRect b = img->bounds();
+
+ if (pos.x() < b.x())
+ pos.setX(b.x());
+ else if (pos.x() > b.x() + b.width())
+ pos.setX(b.x() + b.width());
+
+ if (pos.y() < b.y())
+ pos.setY(b.y());
+ else if (pos.y() > b.y() + b.height())
+ pos.setY(b.y() + b.height());
+
+ m_selecting = true;
+
+ if( !m_haveCropSelection ) //if the selection is not set
+ {
+ m_rectCrop = TQRect( pos.x(), pos.y(), 0, 0);
+ paintOutlineWithHandles();
+ }
+ else
+ {
+ KisCanvasController *controller = m_subject->canvasController();
+ m_mouseOnHandleType = mouseOnHandle(controller ->windowToView(pos));
+ m_dragStart = pos;
+ }
+
+ updateWidgetValues();
+ }
+ }
+}
+
+void KisToolCrop::move(KisMoveEvent *e)
+{
+ if ( m_subject && m_subject->currentImg())
+ {
+ if( m_selecting ) //if the user selects
+ {
+ if( !m_haveCropSelection ) //if the cropSelection is not yet set
+ {
+ paintOutlineWithHandles();
+
+ m_rectCrop.setBottomRight( e->pos().floorTQPoint());
+
+ KisImageSP image = m_subject->currentImg();
+
+ m_rectCrop.setRight( TQMIN(m_rectCrop.right(), image->width()));
+ m_rectCrop.setBottom( TQMIN(m_rectCrop.bottom(), image->width()));
+ m_rectCrop = m_rectCrop.normalize();
+
+ paintOutlineWithHandles();
+ }
+ else //if the crop selection is set
+ {
+ m_dragStop = e->pos().floorTQPoint();
+ if (m_mouseOnHandleType != None && m_dragStart != m_dragStop ) {
+
+
+ TQ_INT32 imageWidth = m_subject->currentImg()->width();
+ TQ_INT32 imageHeight = m_subject->currentImg()->height();
+
+ paintOutlineWithHandles();
+
+ TQPoint pos = e->pos().floorTQPoint();
+ if( m_mouseOnHandleType == Inside )
+ {
+ m_rectCrop.moveBy( ( m_dragStop.x() - m_dragStart.x() ), ( m_dragStop.y() - m_dragStart.y() ) );
+ if( m_rectCrop.left() < 0 )
+ {
+ m_rectCrop.moveLeft( 0 );
+ }
+ if( m_rectCrop.right() > imageWidth )
+ {
+ m_rectCrop.moveRight( imageWidth );
+ }
+ if( m_rectCrop.top() < 0 )
+ {
+ m_rectCrop.moveTop( 0 );
+ }
+ if( m_rectCrop.bottom() > imageHeight )
+ {
+ m_rectCrop.moveBottom( imageHeight );
+ }
+ } else if(m_optWidget->boolRatio->isChecked())
+ {
+ TQPoint drag = m_dragStop - m_dragStart;
+ if( ! m_optWidget->boolWidth->isChecked() && !m_optWidget->boolHeight->isChecked() )
+ {
+ switch (m_mouseOnHandleType)
+ {
+ case (UpperLeft):
+ {
+ TQ_INT32 dep = (drag.x() + drag.y()) / 2;
+ m_rectCrop.setTop( m_rectCrop.top() + dep );
+ m_rectCrop.setLeft( (int) ( m_rectCrop.right() - m_optWidget->doubleRatio->value() * m_rectCrop.height() ) );
+ }
+ break;
+ case (LowerRight):
+ {
+ TQ_INT32 dep = (drag.x() + drag.y()) / 2;
+ m_rectCrop.setBottom( m_rectCrop.bottom() + dep );
+ m_rectCrop.setWidth( (int) ( m_optWidget->doubleRatio->value() * m_rectCrop.height() ) );
+ break;
+ }
+ case (UpperRight):
+ {
+ TQ_INT32 dep = (drag.x() - drag.y()) / 2;
+ m_rectCrop.setTop( m_rectCrop.top() - dep );
+ m_rectCrop.setWidth( (int) ( m_optWidget->doubleRatio->value() * m_rectCrop.height() ) );
+ break;
+ }
+ case (LowerLeft):
+ {
+ TQ_INT32 dep = (drag.x() - drag.y()) / 2;
+ m_rectCrop.setBottom( m_rectCrop.bottom() - dep );
+ m_rectCrop.setLeft( (int) ( m_rectCrop.right() - m_optWidget->doubleRatio->value() * m_rectCrop.height() ) );
+ break;
+ }
+ case (Upper):
+ m_rectCrop.setTop( pos.y() + m_dy );
+ m_rectCrop.setWidth( (int) (m_rectCrop.height() * m_optWidget->doubleRatio->value()) );
+ break;
+ case (Lower):
+ m_rectCrop.setBottom( pos.y() + m_dy );
+ m_rectCrop.setWidth( (int) (m_rectCrop.height() * m_optWidget->doubleRatio->value()) );
+ break;
+ case (Left):
+ m_rectCrop.setLeft( pos.x() + m_dx );
+ m_rectCrop.setHeight( (int) (m_rectCrop.width() / m_optWidget->doubleRatio->value()) );
+ break;
+ case (Right):
+ m_rectCrop.setRight( pos.x() + m_dx );
+ m_rectCrop.setHeight( (int) (m_rectCrop.width() / m_optWidget->doubleRatio->value()) );
+ break;
+ case (Inside): // never happen
+ break;
+ }
+ }
+ } else {
+ if( m_optWidget->boolWidth->isChecked() )
+ {
+ m_rectCrop.setWidth( m_optWidget->intWidth->value() + 1 );
+ } else {
+ switch (m_mouseOnHandleType)
+ {
+ case (LowerLeft):
+ case (Left):
+ case (UpperLeft):
+ m_rectCrop.setLeft( pos.x() + m_dx );
+ break;
+ case (Right):
+ case (UpperRight):
+ case (LowerRight):
+ m_rectCrop.setRight( pos.x() + m_dx );
+ break;
+ default:
+ break;
+ }
+ }
+ if( m_optWidget->boolHeight->isChecked() )
+ {
+ m_rectCrop.setHeight( m_optWidget->intHeight->value() + 1 );
+ } else {
+ switch (m_mouseOnHandleType)
+ {
+ case (UpperLeft):
+ case (Upper):
+ case (UpperRight):
+ m_rectCrop.setTop( pos.y() + m_dy );
+ break;
+ case (LowerRight):
+ case (LowerLeft):
+ case (Lower):
+ m_rectCrop.setBottom( pos.y() + m_dy );
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ if( m_rectCrop.height() < 0)
+ {
+ if( m_mouseOnHandleType == Lower)
+ m_mouseOnHandleType = Upper;
+ else if( m_mouseOnHandleType == LowerLeft)
+ m_mouseOnHandleType = UpperLeft;
+ else if( m_mouseOnHandleType == LowerRight)
+ m_mouseOnHandleType = UpperRight;
+ else if( m_mouseOnHandleType == Upper)
+ m_mouseOnHandleType = Lower;
+ else if( m_mouseOnHandleType == UpperLeft)
+ m_mouseOnHandleType = LowerLeft;
+ else if( m_mouseOnHandleType == UpperRight)
+ m_mouseOnHandleType = LowerRight;
+ }
+ if( m_rectCrop.width() < 0)
+ {
+ if( m_mouseOnHandleType == Right)
+ m_mouseOnHandleType = Left;
+ else if( m_mouseOnHandleType == UpperRight)
+ m_mouseOnHandleType = UpperLeft;
+ else if( m_mouseOnHandleType == LowerRight)
+ m_mouseOnHandleType = LowerLeft;
+ else if( m_mouseOnHandleType == Left)
+ m_mouseOnHandleType = Right;
+ else if( m_mouseOnHandleType == UpperLeft)
+ m_mouseOnHandleType = UpperRight;
+ else if( m_mouseOnHandleType == LowerLeft)
+ m_mouseOnHandleType = LowerRight;
+ }
+
+ m_rectCrop = m_rectCrop.normalize();
+ m_rectCrop = m_rectCrop.intersect( TQRect(0,0, imageWidth + 1, imageHeight + 1 ) );
+ m_dragStart = e->pos().floorTQPoint();
+ paintOutlineWithHandles();
+ }
+ }
+ updateWidgetValues();
+ }
+ else //if we are not selecting
+ {
+ if ( m_haveCropSelection ) //if the crop selection is set
+ {
+ KisCanvasController *controller = m_subject->canvasController();
+ TQ_INT32 type = mouseOnHandle(controller->windowToView(e->pos().floorTQPoint()));
+ //set resize cursor if we are on one of the handles
+ setMoveResizeCursor(type);
+ }
+ }
+ }
+}
+
+void KisToolCrop::updateWidgetValues(bool updateratio)
+{
+ TQRect r = realRectCrop();
+ setOptionWidgetX(r.x());
+ setOptionWidgetY(r.y());
+ setOptionWidgetWidth(r.width() );
+ setOptionWidgetHeight(r.height() );
+ if(updateratio && !m_optWidget->boolRatio->isChecked() )
+ setOptionWidgetRatio((double)r.width() / (double)r.height() );
+}
+
+void KisToolCrop::buttonRelease(KisButtonReleaseEvent *e)
+{
+ if (m_subject && m_subject->currentImg() && m_selecting && e->button() == Qt::LeftButton) {
+
+ m_selecting = false;
+ m_haveCropSelection = true;
+
+ paintOutlineWithHandles();
+ validateSelection();
+ paintOutlineWithHandles();
+ }
+}
+
+void KisToolCrop::doubleClick(KisDoubleClickEvent *)
+{
+ if (m_haveCropSelection) crop();
+}
+
+void KisToolCrop::validateSelection(bool updateratio)
+{
+ if (m_subject) {
+ KisImageSP image = m_subject->currentImg();
+
+ if (image) {
+ TQ_INT32 imageWidth = image->width();
+ TQ_INT32 imageHeight = image->height();
+ m_rectCrop.setLeft(TQMAX(0, m_rectCrop.left()));
+ m_rectCrop.setTop(TQMAX(0, m_rectCrop.top()));
+ m_rectCrop.setRight(TQMIN(imageWidth, m_rectCrop.right()));
+ m_rectCrop.setBottom(TQMIN(imageHeight, m_rectCrop.bottom()));
+
+ updateWidgetValues(updateratio);
+ }
+ }
+}
+
+void KisToolCrop::paintOutlineWithHandles()
+{
+ if (m_subject) {
+ KisCanvasController *controller = m_subject->canvasController();
+ KisCanvas *canvas = controller->kiscanvas();
+ KisCanvasPainter gc(canvas);
+ TQRect rc;
+
+ paintOutlineWithHandles(gc, rc);
+ }
+}
+
+void KisToolCrop::paintOutlineWithHandles(KisCanvasPainter& gc, const TQRect&)
+{
+ if (m_subject && (m_selecting || m_haveCropSelection)) {
+ KisCanvasController *controller = m_subject->canvasController();
+ RasterOp op = gc.rasterOp();
+ TQPen old = gc.pen();
+ TQPen pen(TQt::SolidLine);
+ pen.setWidth(1);
+ TQPoint start;
+ TQPoint end;
+
+ Q_ASSERT(controller);
+ start = controller->windowToView(m_rectCrop.topLeft());
+ end = controller->windowToView(m_rectCrop.bottomRight());
+
+ gc.setRasterOp(TQt::NotROP);
+ gc.setPen(pen);
+ //draw handles
+ m_handlesRegion = handles(TQRect(start, end));
+
+ TQ_INT32 startx;
+ TQ_INT32 starty;
+ TQ_INT32 endx;
+ TQ_INT32 endy;
+ if(start.x()<=end.x())
+ {
+ startx=start.x();
+ endx=end.x();
+ }
+ else
+ {
+ startx=end.x();
+ endx=start.x();
+ }
+ if(start.y()<=end.y())
+ {
+ starty=start.y();
+ endy=end.y();
+ }
+ else
+ {
+ starty=end.y();
+ endy=start.y();
+ }
+ //draw upper line of selection
+ gc.drawLine(startx + m_handleSize / 2 + 1, starty, startx + (endx - startx - m_handleSize) / 2 + 1, starty);
+ gc.drawLine(startx + (endx - startx + m_handleSize) / 2 + 1, starty, endx - m_handleSize / 2, starty);
+ //draw lower line of selection
+ gc.drawLine(startx + m_handleSize / 2 + 1, endy, startx + (endx - startx - m_handleSize) / 2 + 1, endy);
+ gc.drawLine(startx + (endx - startx + m_handleSize) / 2 + 1, endy, endx - m_handleSize / 2 , endy);
+ //draw right line of selection
+ gc.drawLine(startx, starty + m_handleSize / 2 + 1, startx, starty + (endy - starty - m_handleSize) / 2 + 1);
+ gc.drawLine(startx, starty + (endy - starty + m_handleSize) / 2 + 1, startx, endy - m_handleSize / 2);
+ //draw left line of selection
+ gc.drawLine(endx, starty + m_handleSize / 2 + 1, endx, starty + (endy - starty - m_handleSize) / 2 + 1);
+ gc.drawLine(endx, starty + (endy - starty + m_handleSize) / 2 + 1, endx, endy - m_handleSize / 2);
+
+ //draw guides
+ gc.drawLine(0,endy,startx - m_handleSize / 2,endy);
+ gc.drawLine(startx,endy + m_handleSize / 2 + 1, startx, controller->kiscanvas()->height());
+ gc.drawLine(endx,0,endx,starty - m_handleSize / 2);
+ gc.drawLine(endx + m_handleSize / 2 + 1,starty, controller->kiscanvas()->width(), starty);
+ TQMemArray <TQRect> rects = m_handlesRegion.tqrects ();
+ for (TQMemArray <TQRect>::ConstIterator it = rects.begin (); it != rects.end (); ++it)
+ {
+ gc.fillRect (*it, TQt::black);
+ }
+
+
+ gc.setRasterOp(op);
+ gc.setPen(old);
+ }
+}
+
+void KisToolCrop::crop() {
+ // XXX: Should cropping be part of KisImage/KisPaintDevice's API?
+
+ m_haveCropSelection = false;
+ setCursor(m_cropCursor);
+
+ KisImageSP img = m_subject->currentImg();
+
+ if (!img)
+ return;
+
+ TQRect rc = realRectCrop().normalize();
+
+ // The visitor adds the undo steps to the macro
+ if (m_optWidget->cmbType->currentItem() == 0) {
+
+ TQRect dirty = img->bounds();
+
+ // The layer(s) under the current layer will take care of adding
+ // undo information to the Crop macro.
+ if (img->undo())
+ img->undoAdapter()->beginMacro(i18n("Crop"));
+
+ KisCropVisitor v(rc, false);
+ KisLayerSP layer = img->activeLayer();
+ layer->accept(v);
+ layer->setDirty( dirty );
+ if (img->undo())
+ img->undoAdapter()->endMacro();
+
+ }
+ else {
+ // Resize creates the undo macro itself
+ img->resize(rc, true);
+ }
+
+ m_rectCrop = TQRect(0,0,0,0);
+
+ updateWidgetValues();
+}
+
+void KisToolCrop::setCropX(int x)
+{
+ if (!m_haveCropSelection) {
+ m_haveCropSelection = true;
+ }
+ else {
+ paintOutlineWithHandles(); // remove outlines
+ }
+
+ m_rectCrop.setX(x);
+
+ validateSelection();
+ paintOutlineWithHandles();
+}
+
+void KisToolCrop::setCropY(int y)
+{
+ if (!m_haveCropSelection) {
+ m_haveCropSelection = true;
+ }
+ else {
+ paintOutlineWithHandles(); // remove outlines
+ }
+
+ m_rectCrop.setY(y);
+
+ validateSelection();
+ paintOutlineWithHandles();
+
+}
+
+void KisToolCrop::setCropWidth(int w)
+{
+ if (!m_haveCropSelection) {
+ m_haveCropSelection = true;
+ }
+ else {
+ paintOutlineWithHandles(); // remove outlines
+ }
+
+ m_rectCrop.setWidth(w + 1);
+
+ if( m_optWidget->boolRatio->isChecked() )
+ {
+ m_rectCrop.setHeight( (int) ( w / m_optWidget->doubleRatio->value() ) );
+ } else {
+ setOptionWidgetRatio((double)m_rectCrop.width() / (double)m_rectCrop.height() );
+ }
+
+ validateSelection();
+ paintOutlineWithHandles();
+
+}
+
+void KisToolCrop::setCropHeight(int h)
+{
+ if (!m_haveCropSelection) {
+ m_haveCropSelection = true;
+ }
+ else {
+ paintOutlineWithHandles(); // remove outlines
+ }
+
+ m_rectCrop.setHeight(h + 1);
+
+ if( m_optWidget->boolRatio->isChecked() )
+ {
+ m_rectCrop.setWidth( (int) ( h * m_optWidget->doubleRatio->value() ) );
+ } else {
+ setOptionWidgetRatio((double)m_rectCrop.width() / (double)m_rectCrop.height() );
+ }
+
+ validateSelection();
+ paintOutlineWithHandles();
+
+}
+
+void KisToolCrop::setRatio(double )
+{
+ if( ! (m_optWidget->boolWidth->isChecked() && m_optWidget->boolHeight->isChecked() ))
+ {
+ if (!m_haveCropSelection) {
+ m_haveCropSelection = true;
+ }
+ else {
+ paintOutlineWithHandles(); // remove outlines
+ }
+ if( m_optWidget->boolWidth->isChecked() )
+ {
+ m_rectCrop.setHeight( (int) ( m_rectCrop.width() / m_optWidget->doubleRatio->value()) );
+ setOptionWidgetHeight( m_rectCrop.height() );
+ } else if(m_optWidget->boolHeight->isChecked()) {
+ m_rectCrop.setWidth( (int) (m_rectCrop.height() * m_optWidget->doubleRatio->value()) );
+ setOptionWidgetWidth( m_rectCrop.width() );
+ } else {
+ int newwidth = (int) (m_optWidget->doubleRatio->value() * m_rectCrop.height());
+ newwidth = (newwidth + m_rectCrop.width()) / 2;
+ m_rectCrop.setWidth( newwidth + 1);
+ setOptionWidgetWidth( newwidth );
+ m_rectCrop.setHeight( (int) (newwidth / m_optWidget->doubleRatio->value()) + 1 );
+ setOptionWidgetHeight( m_rectCrop.height() - 1 );
+ }
+ validateSelection(false);
+ paintOutlineWithHandles();
+ }
+}
+
+void KisToolCrop::setOptionWidgetX(TQ_INT32 x)
+{
+ // Disable signals otherwise we get the valueChanged signal, which we don't want
+ // to go through the logic for setting values that way.
+ m_optWidget->intX->blockSignals(true);
+ m_optWidget->intX->setValue(x);
+ m_optWidget->intX->blockSignals(false);
+}
+
+void KisToolCrop::setOptionWidgetY(TQ_INT32 y)
+{
+ m_optWidget->intY->blockSignals(true);
+ m_optWidget->intY->setValue(y);
+ m_optWidget->intY->blockSignals(false);
+}
+
+void KisToolCrop::setOptionWidgetWidth(TQ_INT32 x)
+{
+ m_optWidget->intWidth->blockSignals(true);
+ m_optWidget->intWidth->setValue(x);
+ m_optWidget->intWidth->blockSignals(false);
+}
+
+void KisToolCrop::setOptionWidgetHeight(TQ_INT32 y)
+{
+ m_optWidget->intHeight->blockSignals(true);
+ m_optWidget->intHeight->setValue(y);
+ m_optWidget->intHeight->blockSignals(false);
+}
+
+void KisToolCrop::setOptionWidgetRatio(double ratio)
+{
+ m_optWidget->doubleRatio->blockSignals(true);
+ m_optWidget->doubleRatio->setValue(ratio);
+ m_optWidget->doubleRatio->blockSignals(false);
+}
+
+
+TQWidget* KisToolCrop::createOptionWidget(TQWidget* tqparent)
+{
+ m_optWidget = new WdgToolCrop(tqparent);
+ Q_CHECK_PTR(m_optWidget);
+
+ connect(m_optWidget->bnCrop, TQT_SIGNAL(clicked()), this, TQT_SLOT(crop()));
+
+ connect(m_optWidget->intX, TQT_SIGNAL(valueChanged(int)), this, TQT_SLOT(setCropX(int)));
+ connect(m_optWidget->intY, TQT_SIGNAL(valueChanged(int)), this, TQT_SLOT(setCropY(int)));
+ connect(m_optWidget->intWidth, TQT_SIGNAL(valueChanged(int)), this, TQT_SLOT(setCropWidth(int)));
+ connect(m_optWidget->intHeight, TQT_SIGNAL(valueChanged(int)), this, TQT_SLOT(setCropHeight(int)));
+ connect(m_optWidget->doubleRatio, TQT_SIGNAL(valueChanged(double)), this, TQT_SLOT(setRatio( double )));
+
+ return m_optWidget;
+}
+
+TQWidget* KisToolCrop::optionWidget()
+{
+ return m_optWidget;
+}
+
+void KisToolCrop::setup(KActionCollection *collection)
+{
+ m_action = static_cast<KRadioAction *>(collection->action(name()));
+
+ if (m_action == 0) {
+ m_action = new KRadioAction(i18n("&Crop"),
+ "tool_crop",
+ 0,
+ this,
+ TQT_SLOT(activate()),
+ collection,
+ name());
+ Q_CHECK_PTR(m_action);
+
+ m_action->setToolTip(i18n("Crop an area"));
+ m_action->setExclusiveGroup("tools");
+
+ m_ownAction = true;
+ }
+}
+
+TQRect toTQRect(double x, double y, int w, int h)
+{
+ return TQRect(int(x), int(y), w, h);
+}
+
+TQRegion KisToolCrop::handles(TQRect rect)
+{
+ TQRegion handlesRegion;
+
+ //add handle at the lower right corner
+ handlesRegion += toTQRect( TQABS( rect.width() ) - m_handleSize / 2.0, TQABS( rect.height() ) - m_handleSize / 2.0, m_handleSize, m_handleSize );
+ //add handle at the upper right corner
+ handlesRegion += toTQRect( TQABS( rect.width() ) - m_handleSize / 2.0 , 0 - m_handleSize / 2.0, m_handleSize, m_handleSize );
+ //add rectangle at the lower left corner
+ handlesRegion += toTQRect( 0 - m_handleSize / 2.0 , TQABS( rect.height() ) - m_handleSize / 2.0, m_handleSize, m_handleSize );
+ //add rectangle at the upper left corner
+ handlesRegion += toTQRect( 0 - m_handleSize / 2.0, 0 - m_handleSize / 2.0, m_handleSize, m_handleSize );
+ //add handle at the lower edge of the rectangle
+ handlesRegion += toTQRect( ( TQABS( rect.width() ) - m_handleSize ) / 2.0 , TQABS( rect.height() ) - m_handleSize / 2.0, m_handleSize, m_handleSize );
+ //add handle at the right edge of the rectangle
+ handlesRegion += toTQRect( TQABS( rect.width() ) - m_handleSize / 2.0 , ( TQABS( rect.height() ) - m_handleSize ) / 2.0, m_handleSize, m_handleSize );
+ //add handle at the upper edge of the rectangle
+ handlesRegion += toTQRect( ( TQABS( rect.width() ) - m_handleSize ) / 2.0 , 0 - m_handleSize / 2.0, m_handleSize, m_handleSize );
+ //add handle at the left edge of the rectangle
+ handlesRegion += toTQRect( 0 - m_handleSize / 2.0, ( TQABS( rect.height() ) - m_handleSize ) / 2.0, m_handleSize, m_handleSize );
+
+ //move the handles to the correct position
+ if( rect.width() >= 0 && rect.height() >= 0)
+ {
+ handlesRegion.translate ( rect.x(), rect.y() );
+ }
+ else if( rect.width() < 0 && rect.height() >= 0)
+ {
+ handlesRegion.translate ( rect.x() - TQABS( rect.width() ), rect.y() );
+ }
+ else if( rect.width() >= 0 && rect.height() < 0)
+ {
+ handlesRegion.translate ( rect.x(), rect.y() - TQABS( rect.height() ) );
+ }
+ else if( rect.width() < 0 && rect.height() < 0)
+ {
+ handlesRegion.translate ( rect.x() - TQABS( rect.width() ), rect.y() - TQABS( rect.height() ) );
+ }
+ return handlesRegion;
+}
+
+TQ_INT32 KisToolCrop::mouseOnHandle(TQPoint currentViewPoint)
+{
+ KisCanvasController *controller = m_subject->canvasController();
+ Q_ASSERT(controller);
+ TQPoint start = controller->windowToView(m_rectCrop.topLeft());
+ TQPoint end = controller->windowToView(m_rectCrop.bottomRight());
+
+ TQ_INT32 startx;
+ TQ_INT32 starty;
+ TQ_INT32 endx;
+ TQ_INT32 endy;
+ if(start.x()<=end.x())
+ {
+ startx=start.x();
+ endx=end.x();
+ }
+ else
+ {
+ startx=end.x();
+ endx=start.x();
+ }
+ if(start.y()<=end.y())
+ {
+ starty=start.y();
+ endy=end.y();
+ }
+ else
+ {
+ starty=end.y();
+ endy=start.y();
+ }
+
+ if ( toTQRect ( startx - m_handleSize / 2.0, starty - m_handleSize / 2.0, m_handleSize, m_handleSize ).tqcontains( currentViewPoint ) )
+ {
+ if( !m_selecting )
+ {
+ m_dx= startx-currentViewPoint.x();
+ m_dy = starty - currentViewPoint.y();
+ }
+ return UpperLeft;
+ }
+ else if ( toTQRect ( startx - m_handleSize / 2.0, endy - m_handleSize / 2.0, m_handleSize, m_handleSize ).tqcontains( currentViewPoint ) )
+ {
+ if( !m_selecting )
+ {
+ m_dx = startx-currentViewPoint.x();
+ m_dy = endy-currentViewPoint.y();
+ }
+ return LowerLeft;
+ }
+ else if ( toTQRect ( endx - m_handleSize / 2.0, starty - m_handleSize / 2.0, m_handleSize, m_handleSize ).tqcontains( currentViewPoint ) )
+ {
+ if( !m_selecting )
+ {
+ m_dx = endx - currentViewPoint.x();
+ m_dy = starty - currentViewPoint.y() ;
+ }
+ return UpperRight;
+ }
+ else if ( toTQRect ( endx - m_handleSize / 2.0, endy - m_handleSize / 2.0, m_handleSize, m_handleSize ).tqcontains( currentViewPoint ) )
+ {
+ if( !m_selecting )
+ {
+ m_dx = endx - currentViewPoint.x();
+ m_dy= endy - currentViewPoint.y();
+ }
+ return LowerRight;
+ }
+ else if ( toTQRect ( startx + ( endx - startx - m_handleSize ) / 2.0, starty - m_handleSize / 2.0, m_handleSize, m_handleSize ).tqcontains( currentViewPoint ) )
+ {
+ if( !m_selecting )
+ {
+ m_dy = starty - currentViewPoint.y() ;
+ }
+ return Upper;
+ }
+ else if ( toTQRect ( startx + ( endx - startx - m_handleSize ) / 2.0, endy - m_handleSize / 2, m_handleSize, m_handleSize ).tqcontains( currentViewPoint ) )
+ {
+ if( !m_selecting )
+ {
+ m_dy = endy - currentViewPoint.y();
+ }
+ return Lower;
+ }
+ else if ( toTQRect ( startx - m_handleSize / 2.0, starty + ( endy - starty - m_handleSize ) / 2.0, m_handleSize, m_handleSize ).tqcontains( currentViewPoint ) )
+ {
+ if( !m_selecting )
+ {
+ m_dx = startx - currentViewPoint.x() ;
+ }
+ return Left;
+ }
+ else if ( toTQRect ( endx - m_handleSize / 2.0 , starty + ( endy - starty - m_handleSize ) / 2.0, m_handleSize, m_handleSize ).tqcontains( currentViewPoint ) )
+ {
+ if( !m_selecting )
+ {
+ m_dx = endx-currentViewPoint.x();
+ }
+ return Right;
+ }
+ else if ( toTQRect ( startx , starty, endx - startx , endy - starty ).tqcontains( currentViewPoint ) )
+ {
+ return Inside;
+ }
+ else return None;
+}
+
+void KisToolCrop::setMoveResizeCursor (TQ_INT32 handle)
+{
+ switch (handle)
+ {
+ case (UpperLeft):
+ case (LowerRight):
+ m_subject->canvasController()->setCanvasCursor(KisCursor::sizeFDiagCursor());
+ return;
+ case (LowerLeft):
+ case (UpperRight):
+ m_subject->canvasController()->setCanvasCursor(KisCursor::sizeBDiagCursor());
+ return;
+ case (Upper):
+ case (Lower):
+ m_subject->canvasController()->setCanvasCursor(KisCursor::sizeVerCursor());
+ return;
+ case (Left):
+ case (Right):
+ m_subject->canvasController()->setCanvasCursor(KisCursor::sizeHorCursor());
+ return;
+ case (Inside):
+ m_subject->canvasController()->setCanvasCursor(KisCursor::sizeAllCursor());
+ return;
+ }
+ m_subject->canvasController()->setCanvasCursor(KisCursor::arrowCursor());
+ return;
+}
+
+
+#include "kis_tool_crop.moc"
diff --git a/chalk/plugins/tools/tool_crop/kis_tool_crop.h b/chalk/plugins/tools/tool_crop/kis_tool_crop.h
new file mode 100644
index 00000000..7ad7c9fd
--- /dev/null
+++ b/chalk/plugins/tools/tool_crop/kis_tool_crop.h
@@ -0,0 +1,149 @@
+/*
+ * kis_tool_crop.h - part of Chalk
+ *
+ * Copyright (c) 2004 Boudewijn Rempt <boud@valdyas.org>
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef KIS_TOOL_CROP_H_
+#define KIS_TOOL_CROP_H_
+
+#include <tqpoint.h>
+#include <tqregion.h>
+#include <kis_tool_non_paint.h>
+#include <kis_tool_factory.h>
+
+class TQRect;
+class TQCursor;
+class WdgToolCrop;
+
+/**
+ * Crop tool
+ *
+ * TODO: - crop from selection -- i.e, set crop outline to the exact bounds of the selection.
+ * - (when moving to TQt 4: replace rectangle with darker, dimmer overlay layer
+ * like we have for selections right now)
+ */
+class KisToolCrop : public KisToolNonPaint {
+
+ typedef KisToolNonPaint super;
+ Q_OBJECT
+ TQ_OBJECT
+
+public:
+
+ KisToolCrop();
+ virtual ~KisToolCrop();
+
+ virtual void update(KisCanvasSubject *subject);
+
+ virtual TQWidget* createOptionWidget(TQWidget* tqparent);
+ virtual TQWidget* optionWidget();
+
+ virtual void setup(KActionCollection *collection);
+ virtual enumToolType toolType() { return TOOL_TRANSFORM; }
+ virtual TQ_UINT32 priority() { return 1; }
+ virtual void paint(KisCanvasPainter& gc);
+ virtual void paint(KisCanvasPainter& gc, const TQRect& rc);
+ virtual void buttonPress(KisButtonPressEvent *e);
+ virtual void move(KisMoveEvent *e);
+ virtual void buttonRelease(KisButtonReleaseEvent *e);
+ virtual void doubleClick(KisDoubleClickEvent *);
+
+public slots:
+
+ virtual void activate();
+ virtual void deactivate();
+
+private:
+
+ void clearRect();
+ TQRegion handles(TQRect rect);
+ void paintOutlineWithHandles();
+ void paintOutlineWithHandles(KisCanvasPainter& gc, const TQRect& rc);
+ TQ_INT32 mouseOnHandle (const TQPoint currentViewPoint);
+ void setMoveResizeCursor (TQ_INT32 handle);
+ void validateSelection(bool updateratio = true);
+ void setOptionWidgetX(TQ_INT32 x);
+ void setOptionWidgetY(TQ_INT32 y);
+ void setOptionWidgetWidth(TQ_INT32 x);
+ void setOptionWidgetHeight(TQ_INT32 y);
+ void setOptionWidgetRatio(double ratio);
+
+private slots:
+
+ void crop();
+ void setCropX(int x);
+ void setCropY(int y);
+ void setCropWidth(int x);
+ void setCropHeight(int y);
+ void setRatio(double ratio);
+
+ inline TQRect realRectCrop() { TQRect r = m_rectCrop; r.setSize(r.size() - TQSize(1,1)); return r; }
+
+private:
+ void updateWidgetValues(bool updateratio = true);
+ KisCanvasSubject *m_subject;
+ TQRect m_rectCrop; // Is the coordinate of the outline rect and not of the region to crop (to get the region to crop you need to remove 1 to width and height
+// TQPoint m_startPos;
+// TQPoint m_endPos;
+ bool m_selecting;
+ TQPoint m_dragStart;
+ TQPoint m_dragStop;
+
+ WdgToolCrop* m_optWidget;
+
+ TQ_INT32 m_handleSize;
+ TQRegion m_handlesRegion;
+ bool m_haveCropSelection;
+ TQ_INT32 m_dx, m_dy;
+ TQ_INT32 m_mouseOnHandleType;
+ TQCursor m_cropCursor;
+
+ enum handleType
+ {
+ None = 0,
+ UpperLeft = 1,
+ UpperRight = 2,
+ LowerLeft = 3,
+ LowerRight = 4,
+ Upper = 5,
+ Lower = 6,
+ Left = 7,
+ Right = 8,
+ Inside = 9
+ };
+};
+
+class KisToolCropFactory : public KisToolFactory {
+ typedef KisToolFactory super;
+public:
+ KisToolCropFactory() : super() {};
+ virtual ~KisToolCropFactory(){};
+
+ virtual KisTool * createTool(KActionCollection * ac) {
+ KisTool * t = new KisToolCrop();
+ Q_CHECK_PTR(t);
+ t->setup(ac);
+ return t;
+ }
+ virtual KisID id() { return KisID("crop", i18n("Crop Tool")); }
+};
+
+
+
+#endif // KIS_TOOL_CROP_H_
+
diff --git a/chalk/plugins/tools/tool_crop/tool_crop.cc b/chalk/plugins/tools/tool_crop/tool_crop.cc
new file mode 100644
index 00000000..599c7562
--- /dev/null
+++ b/chalk/plugins/tools/tool_crop/tool_crop.cc
@@ -0,0 +1,62 @@
+/*
+ * tool_crop.cc -- Part of Chalk
+ *
+ * Copyright (c) 2004 Boudewijn Rempt (boud@valdyas.org)
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+#include <stdlib.h>
+#include <vector>
+
+#include <tqpoint.h>
+
+#include <klocale.h>
+#include <kiconloader.h>
+#include <kinstance.h>
+#include <kmessagebox.h>
+#include <kstandarddirs.h>
+#include <kdebug.h>
+#include <kgenericfactory.h>
+
+#include <kis_global.h>
+#include <kis_types.h>
+#include <kis_tool_registry.h>
+
+#include "tool_crop.h"
+#include "kis_tool_crop.h"
+
+
+typedef KGenericFactory<ToolCrop> ToolCropFactory;
+K_EXPORT_COMPONENT_FACTORY( chalktoolcrop, ToolCropFactory( "chalk" ) )
+
+
+ToolCrop::ToolCrop(TQObject *tqparent, const char *name, const TQStringList &)
+ : KParts::Plugin(tqparent, name)
+{
+ setInstance(ToolCropFactory::instance());
+
+ if ( tqparent->inherits("KisToolRegistry") )
+ {
+ KisToolRegistry * r = dynamic_cast<KisToolRegistry*>(tqparent);
+ r->add(new KisToolCropFactory());
+ }
+
+}
+
+ToolCrop::~ToolCrop()
+{
+}
+
+#include "tool_crop.moc"
diff --git a/chalk/plugins/tools/tool_crop/tool_crop.h b/chalk/plugins/tools/tool_crop/tool_crop.h
new file mode 100644
index 00000000..df5d7c28
--- /dev/null
+++ b/chalk/plugins/tools/tool_crop/tool_crop.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2004 Boudewijn Rempt (boud@valdyas.org)
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef TOOL_CROP_H_
+#define TOOL_CROP_H_
+
+#include <kparts/plugin.h>
+
+class KisView;
+
+/**
+ * A module that provides a crop tool.
+ */
+class ToolCrop : public KParts::Plugin
+{
+ Q_OBJECT
+ TQ_OBJECT
+public:
+ ToolCrop(TQObject *tqparent, const char *name, const TQStringList &);
+ virtual ~ToolCrop();
+
+private:
+
+ KisView * m_view;
+
+};
+
+#endif // TOOL_CROP_H_
diff --git a/chalk/plugins/tools/tool_crop/tool_crop.png b/chalk/plugins/tools/tool_crop/tool_crop.png
new file mode 100644
index 00000000..ce53d708
--- /dev/null
+++ b/chalk/plugins/tools/tool_crop/tool_crop.png
Binary files differ
diff --git a/chalk/plugins/tools/tool_crop/tool_crop_cursor.png b/chalk/plugins/tools/tool_crop/tool_crop_cursor.png
new file mode 100644
index 00000000..325461bb
--- /dev/null
+++ b/chalk/plugins/tools/tool_crop/tool_crop_cursor.png
Binary files differ
diff --git a/chalk/plugins/tools/tool_crop/wdg_tool_crop.ui b/chalk/plugins/tools/tool_crop/wdg_tool_crop.ui
new file mode 100644
index 00000000..4f857cf9
--- /dev/null
+++ b/chalk/plugins/tools/tool_crop/wdg_tool_crop.ui
@@ -0,0 +1,216 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>WdgToolCrop</class>
+<widget class="TQWidget">
+ <property name="name">
+ <cstring>WdgToolCrop</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>346</width>
+ <height>123</height>
+ </rect>
+ </property>
+ <property name="caption">
+ <string>Crop</string>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <widget class="TQLayoutWidget">
+ <property name="name">
+ <cstring>tqlayout3</cstring>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>3</number>
+ </property>
+ <widget class="TQLabel" row="0" column="0">
+ <property name="name">
+ <cstring>textLabel1</cstring>
+ </property>
+ <property name="text">
+ <string>X:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>isbX</cstring>
+ </property>
+ </widget>
+ <widget class="KIntSpinBox" row="0" column="1">
+ <property name="name">
+ <cstring>intX</cstring>
+ </property>
+ <property name="maxValue">
+ <number>1000000000</number>
+ </property>
+ </widget>
+ <widget class="KIntSpinBox" row="1" column="3">
+ <property name="name">
+ <cstring>intHeight</cstring>
+ </property>
+ <property name="maxValue">
+ <number>1000000000</number>
+ </property>
+ </widget>
+ <widget class="TQCheckBox" row="0" column="2">
+ <property name="name">
+ <cstring>boolWidth</cstring>
+ </property>
+ <property name="text">
+ <string>W&amp;idth:</string>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Will keep the width of the crop constant</string>
+ </property>
+ </widget>
+ <widget class="KIntSpinBox" row="0" column="3">
+ <property name="name">
+ <cstring>intWidth</cstring>
+ </property>
+ <property name="maxValue">
+ <number>1000000000</number>
+ </property>
+ </widget>
+ <widget class="KIntSpinBox" row="1" column="1">
+ <property name="name">
+ <cstring>intY</cstring>
+ </property>
+ <property name="maxValue">
+ <number>1000000000</number>
+ </property>
+ </widget>
+ <widget class="TQCheckBox" row="1" column="2">
+ <property name="name">
+ <cstring>boolHeight</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Height:</string>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Will keep the height of the crop constant</string>
+ </property>
+ </widget>
+ <widget class="TQLabel" row="1" column="0">
+ <property name="name">
+ <cstring>textLabel3</cstring>
+ </property>
+ <property name="text">
+ <string>Y:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>isbY</cstring>
+ </property>
+ </widget>
+ <widget class="KDoubleNumInput" row="2" column="3">
+ <property name="name">
+ <cstring>doubleRatio</cstring>
+ </property>
+ <property name="precision">
+ <number>2</number>
+ </property>
+ </widget>
+ <widget class="TQCheckBox" row="2" column="2">
+ <property name="name">
+ <cstring>boolRatio</cstring>
+ </property>
+ <property name="text">
+ <string>R&amp;atio:</string>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Will keep the ratio constant</string>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="TQLayoutWidget">
+ <property name="name">
+ <cstring>tqlayout9</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <widget class="TQComboBox">
+ <item>
+ <property name="text">
+ <string>Layer</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Image</string>
+ </property>
+ </item>
+ <property name="name">
+ <cstring>cmbType</cstring>
+ </property>
+ <property name="currentItem">
+ <number>1</number>
+ </property>
+ </widget>
+ <widget class="TQPushButton">
+ <property name="name">
+ <cstring>bnCrop</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Crop</string>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer2</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="tqsizeHint">
+ <size>
+ <width>20</width>
+ <height>16</height>
+ </size>
+ </property>
+ </spacer>
+ </vbox>
+</widget>
+<customwidgets>
+</customwidgets>
+<tabstops>
+ <tabstop>intX</tabstop>
+ <tabstop>intY</tabstop>
+ <tabstop>intWidth</tabstop>
+ <tabstop>intHeight</tabstop>
+ <tabstop>cmbType</tabstop>
+ <tabstop>bnCrop</tabstop>
+</tabstops>
+<tqlayoutdefaults spacing="6" margin="11"/>
+<includehints>
+ <includehint>knuminput.h</includehint>
+ <includehint>knuminput.h</includehint>
+ <includehint>knuminput.h</includehint>
+ <includehint>knuminput.h</includehint>
+ <includehint>knuminput.h</includehint>
+ <includehint>knuminput.h</includehint>
+</includehints>
+</UI>
diff --git a/chalk/plugins/tools/tool_curves/Makefile.am b/chalk/plugins/tools/tool_curves/Makefile.am
new file mode 100644
index 00000000..5233106a
--- /dev/null
+++ b/chalk/plugins/tools/tool_curves/Makefile.am
@@ -0,0 +1,56 @@
+kde_services_DATA = chalktoolcurves.desktop
+
+# all_includes must remain last!
+INCLUDES = -I$(srcdir)/../../../sdk \
+ -I$(srcdir)/../../../core \
+ -I$(srcdir)/../../../chalkcolor/ \
+ -I$(srcdir)/../../../ui \
+ -I$/../../../ui \
+ $(KOFFICE_INCLUDES) \
+ $(all_includes)
+
+chalktoolcurves_la_SOURCES = \
+ kis_curve_framework.cc \
+ kis_tool_curve.cc \
+ tool_curves.cc \
+ wdg_tool_example.ui \
+ kis_tool_example.cc \
+ kis_tool_bezier.cc \
+ kis_tool_bezier_paint.cc \
+ kis_tool_bezier_select.cc \
+ kis_tool_moutline.cc
+
+# Install this plugin in the KDE modules directory
+kde_module_LTLIBRARIES = chalktoolcurves.la
+
+noinst_HEADERS = \
+ kis_curve_framework.h \
+ kis_tool_curve.h \
+ tool_curves.h \
+ kis_tool_example.h \
+ kis_tool_bezier.h \
+ kis_tool_bezier_paint.h \
+ kis_tool_bezier_select.h \
+ kis_tool_moutline.h
+
+chalktoolcurves_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) $(LIB_QT) -lkdecore -lkdeui -lkjs -lkdefx -lkio -lkparts -L../../../../chalk/chalkcolor/.libs -lchalkcolor -L../../../../chalk/core/.libs -lchalkimage \
+ -L../../../../chalk/ui/.libs -lchalkui
+chalktoolcurves_la_LIBADD = ../../../libchalkcommon.la
+
+chalktoolcurves_la_METASOURCES = AUTO
+
+KDE_OPTIONS = nofinal
+
+chalkpics_DATA = \
+ tool_example.png \
+ tool_example_cursor.png \
+ tool_bezier_paint.png \
+ tool_bezier_select.png \
+ tool_bezier_cursor.png \
+ tool_moutline.png \
+ tool_moutline_cursor.png \
+ tool_curve_dragging.png \
+ tool_moutline_editing.png
+
+chalkpicsdir = $(kde_datadir)/chalk/pics
+
diff --git a/chalk/plugins/tools/tool_curves/chalktoolcurves.desktop b/chalk/plugins/tools/tool_curves/chalktoolcurves.desktop
new file mode 100644
index 00000000..1ab54038
--- /dev/null
+++ b/chalk/plugins/tools/tool_curves/chalktoolcurves.desktop
@@ -0,0 +1,36 @@
+[Desktop Entry]
+Name=Curves Tool
+Name[bg]=Инструмент криви
+Name[ca]=Eina de corbes
+Name[da]=Kurveværktøj
+Name[de]=Kurvenwerkzeug
+Name[el]=Εργαλείο καμπύλων
+Name[eo]=Kurvado-ilo
+Name[es]=Herramienta Curvas
+Name[et]=Kõverate tööriist
+Name[fa]=ابزار منحنیها
+Name[fy]=Krommings-ark
+Name[gl]=Ferramenta de Curvas
+Name[hu]=Görberajzoló
+Name[it]=Strumento curve
+Name[ja]=曲線ツール
+Name[km]=ឧបករណ៍​ខ្សែ​កោង
+Name[nb]=Kurveverktøy
+Name[nds]=Bagenwarktüüch
+Name[ne]=वक्र उपकरण
+Name[nl]=Krommen-gereedschap
+Name[pl]=Narzędzie krzywych
+Name[pt]=Ferramenta de Curvas
+Name[pt_BR]=Ferramenta de Curvas
+Name[ru]=Кривые
+Name[sk]=Krivky
+Name[sl]=Orodje za krivulje
+Name[sr]=Алат за криве
+Name[sr@Latn]=Alat za krive
+Name[sv]=Kurvverktyg
+Name[uk]=Криві
+Name[zh_TW]=曲線工具
+ServiceTypes=Chalk/Tool
+Type=Service
+X-KDE-Library=chalktoolcurves
+X-Chalk-Version=2
diff --git a/chalk/plugins/tools/tool_curves/kis_curve_framework.cc b/chalk/plugins/tools/tool_curves/kis_curve_framework.cc
new file mode 100644
index 00000000..416d3bfd
--- /dev/null
+++ b/chalk/plugins/tools/tool_curves/kis_curve_framework.cc
@@ -0,0 +1,260 @@
+/*
+ * Copyright (c) 2006 Emanuele Tamponi <emanuele@valinor.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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <tqvaluelist.h>
+#include <tqrect.h>
+#include "kis_point.h"
+
+#include "kis_curve_framework.h"
+
+/* **************************** *
+ * KisCurve methods definitions *
+ * **************************** */
+
+KisCurve::iterator KisCurve::addPivot (KisCurve::iterator it, const KisPoint& point)
+{
+ return iterator(*this,m_curve.insert(it.position(), CurvePoint(point,true,false,NOHINTS)));
+}
+
+KisCurve::iterator KisCurve::pushPivot (const KisPoint& point)
+{
+ return selectPivot(iterator(*this,m_curve.append(CurvePoint(point,true,false,NOHINTS))), true);
+}
+
+KisCurve::iterator KisCurve::addPoint (KisCurve::iterator it, const KisPoint& point, bool pivot, bool selected, int hint)
+{
+ return iterator(*this,m_curve.insert(it.position(), CurvePoint(point,pivot,selected, hint)));
+}
+
+KisCurve::iterator KisCurve::addPoint (KisCurve::iterator it, const CurvePoint& point)
+{
+ return iterator(*this,m_curve.insert(it.position(), point));
+}
+
+KisCurve::iterator KisCurve::pushPoint (const KisPoint& point, bool pivot, bool selected,int hint)
+{
+ return iterator(*this,m_curve.append(CurvePoint(point,pivot,selected,hint)));
+}
+
+KisCurve::iterator KisCurve::pushPoint (const CurvePoint& point)
+{
+ return iterator(*this,m_curve.append(point));
+}
+
+KisCurve KisCurve::pivots()
+{
+ KisCurve temp;
+
+ for (iterator it = begin(); it != end(); it = it.nextPivot())
+ temp.pushPoint((*it));
+
+ return temp;
+}
+
+KisCurve KisCurve::selectedPivots(bool selected)
+{
+ KisCurve temp;
+
+ for (iterator it = begin(); it != end(); it = it.nextPivot())
+ if ((*it).isSelected() == selected)
+ temp.pushPoint((*it));
+
+ return temp;
+}
+
+KisCurve KisCurve::subCurve(const KisPoint& tend)
+{
+ return subCurve(tqfind(tend).previousPivot(),tqfind(tend));
+}
+
+KisCurve KisCurve::subCurve(const CurvePoint& tend)
+{
+ return subCurve(tqfind(tend).previousPivot(),tqfind(tend));
+}
+
+KisCurve KisCurve::subCurve(iterator tend)
+{
+ return subCurve(tend.previousPivot(),tend);
+}
+
+KisCurve KisCurve::subCurve(const KisPoint& tstart, const KisPoint& tend)
+{
+ return subCurve(tqfind(tstart),tqfind(tend));
+}
+
+KisCurve KisCurve::subCurve(const CurvePoint& tstart, const CurvePoint& tend)
+{
+ return subCurve(tqfind(tstart),tqfind(tend));
+}
+
+KisCurve KisCurve::subCurve(iterator tstart, iterator tend)
+{
+ KisCurve temp;
+
+ while (tstart != tend && tstart != m_curve.end())
+ temp.pushPoint((*++tstart));
+
+ return temp;
+}
+
+void KisCurve::deleteFirstPivot ()
+{
+ if (!m_curve.isEmpty()) {
+ m_curve.pop_front();
+ while (m_curve.count() > 1 && !first().isPivot())
+ m_curve.pop_front();
+ }
+}
+
+void KisCurve::deleteLastPivot ()
+{
+ if (!m_curve.isEmpty()) {
+ m_curve.pop_back();
+ while (m_curve.count() > 1 && !last().isPivot())
+ m_curve.pop_back();
+ }
+}
+
+KisCurve::iterator KisCurve::deleteCurve (const KisPoint& pos1, const KisPoint& pos2)
+{
+ return deleteCurve (CurvePoint(pos1),CurvePoint(pos2));
+}
+
+KisCurve::iterator KisCurve::deleteCurve (const CurvePoint& pos1, const CurvePoint& pos2)
+{
+ return deleteCurve (tqfind(pos1),tqfind(pos2));
+}
+
+KisCurve::iterator KisCurve::deleteCurve (KisCurve::iterator pos1, KisCurve::iterator pos2)
+{
+ if (pos1 == pos2)
+ return end();
+ iterator pos = pos1;
+ pos++;
+ while (pos != pos2 && pos != end()) {
+ pos = m_curve.erase(pos.position());
+ }
+ return pos;
+}
+
+KisCurve::iterator KisCurve::selectPivot(const KisPoint& pt, bool isSelected)
+{
+ return selectPivot(tqfind(CurvePoint(pt,true)),isSelected);
+}
+
+KisCurve::iterator KisCurve::selectPivot(const CurvePoint& pt, bool isSelected)
+{
+ return selectPivot(tqfind(pt),isSelected);
+}
+
+KisCurve::iterator KisCurve::selectPivot(KisCurve::iterator it, bool isSelected)
+{
+ bool sel = false;
+ if (m_standardkeepselected) {
+ if (m_actionOptions & KEEPSELECTEDOPTION)
+ sel = true;
+ }
+ KisCurve selected = pivots();
+ for (iterator i = selected.begin(); i != selected.end(); i++)
+ (*tqfind((*i))).setSelected(sel);
+ (*it).setSelected(isSelected);
+
+ return it;
+}
+
+KisCurve::iterator KisCurve::movePivot(const KisPoint& oldPt, const KisPoint& newPt)
+{
+ return movePivot(CurvePoint(oldPt,true), newPt);
+}
+
+KisCurve::iterator KisCurve::movePivot(const CurvePoint& oldPt, const KisPoint& newPt)
+{
+ return movePivot(tqfind(oldPt), newPt);
+}
+
+KisCurve::iterator KisCurve::movePivot(KisCurve::iterator it, const KisPoint& newPt)
+{
+ if (!(*it).isPivot())
+ return end();
+
+ (*it).setPoint(newPt);
+
+ if ((*it) != first()) {
+ deleteCurve (it.previousPivot(), it);
+ calculateCurve (it.previousPivot(), it, it);
+ }
+ if ((*it) != last()) {
+ deleteCurve (it, it.nextPivot());
+ calculateCurve (it, it.nextPivot(), it.nextPivot());
+ }
+
+ return it;
+}
+
+void KisCurve::deletePivot (const KisPoint& pt)
+{
+ deletePivot(CurvePoint(pt));
+}
+
+void KisCurve::deletePivot (const CurvePoint& pt)
+{
+ deletePivot(tqfind(pt));
+}
+
+void KisCurve::deletePivot (KisCurve::iterator it)
+{
+ if (!(*it).isPivot())
+ return;
+
+ iterator start = it.previousPivot();
+ iterator end = it.nextPivot();
+
+ if (end == m_curve.end())
+ deleteLastPivot();
+ else if (start == it)
+ deleteFirstPivot();
+ else {
+ deleteCurve(start,end);
+ calculateCurve(start,end,end);
+ }
+}
+
+// Probably it can be optimized - it is smooth though.
+void KisCurve::moveSelected (const KisPoint& trans)
+{
+ KisPoint p;
+ KisCurve sel = selectedPivots();
+
+ for (iterator it = sel.begin(); it != sel.end(); it++) {
+ p = (*it).point() + trans;
+ movePivot((*it),p);
+ }
+}
+
+void KisCurve::deleteSelected ()
+{
+ KisCurve sel = selectedPivots();
+ for (iterator it = sel.begin(); it != sel.end(); it++)
+ deletePivot((*it));
+}
+
+void KisCurve::selectAll(bool sel)
+{
+ for (iterator i = begin(); i != end(); i = i.nextPivot())
+ (*i).setSelected(sel);
+}
diff --git a/chalk/plugins/tools/tool_curves/kis_curve_framework.h b/chalk/plugins/tools/tool_curves/kis_curve_framework.h
new file mode 100644
index 00000000..c27369aa
--- /dev/null
+++ b/chalk/plugins/tools/tool_curves/kis_curve_framework.h
@@ -0,0 +1,354 @@
+/*
+ * Copyright (c) 2006 Emanuele Tamponi <emanuele@valinor.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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef KIS_CURVE_FRAMEWORK_H_
+#define KIS_CURVE_FRAMEWORK_H_
+
+#include "kis_point.h"
+
+const int NOHINTS = 0x0000;
+const int POINTHINT = 0x0001;
+const int LINEHINT = 0x0002;
+
+const int NOOPTIONS = 0x0000;
+const int SHIFTOPTION = 0x0001;
+const int CONTROLOPTION = 0x0002;
+const int ALTOPTION = 0x0004;
+
+const int KEEPSELECTEDOPTION = CONTROLOPTION;
+
+class CurvePoint {
+
+ KisPoint m_point;
+ bool m_pivot;
+ bool m_selected; // Only pivots can be selected
+
+ int m_hint;
+
+public:
+
+ /* Constructors and Destructor */
+
+ CurvePoint ();
+ CurvePoint (const KisPoint&, bool = false, bool = false, int = POINTHINT);
+ CurvePoint (double, double, bool = false, bool = false, int = POINTHINT);
+
+ ~CurvePoint () {}
+
+public:
+
+ /* Generic Functions */
+
+ bool operator!= (KisPoint p2) const { if (p2 != m_point) return true; else return false; }
+ bool operator!= (CurvePoint p2) const { if (p2.point() != m_point ||
+ p2.isPivot() != m_pivot ||
+ p2.hint() != m_hint) return true; else return false; }
+
+ bool operator== (KisPoint p2) const { if (p2 == m_point) return true; else return false; }
+ bool operator== (CurvePoint p2) const { if (p2.point() == m_point &&
+ p2.isPivot() == m_pivot &&
+ p2.hint() == m_hint) return true; else return false; }
+
+ KisPoint point() const {return m_point;}
+
+ void setPoint(const KisPoint&);
+ void setPoint(double, double);
+
+ bool isPivot() const {return m_pivot;}
+ bool isSelected() const {return m_selected;}
+ int hint() const {return m_hint;}
+
+ void setPivot(bool p) {m_pivot = p;}
+ void setSelected(bool s) {m_selected = ((m_pivot) ? s : false);} /* Only pivots can be selected */
+ void setHint(int h) {m_hint = h;}
+};
+
+typedef TQValueList<CurvePoint> PointList;
+typedef TQValueList<CurvePoint>::iterator BaseIterator;
+
+class CurveIterator;
+
+class KisCurve {
+
+public:
+
+ KisCurve () {m_actionOptions = NOOPTIONS; m_standardkeepselected = true;}
+ virtual ~KisCurve () {m_curve.clear();}
+
+ friend class CurveIterator;
+ typedef CurveIterator iterator;
+
+protected:
+ /* I need it to be mutable because my iterator needs to access
+ m_curve's end() and begin() functions using a const KisCurve
+ (see below in CurveIterator) */
+ mutable PointList m_curve;
+ int m_actionOptions;
+
+ bool m_standardkeepselected;
+
+ bool checkIterator (iterator checking) const;
+
+public:
+
+ void setActionOptions (int options) {m_actionOptions = options;}
+ void endActionOptions () {m_actionOptions = NOOPTIONS;}
+
+ CurvePoint& operator[](int i) {return m_curve[i];}
+
+ iterator addPoint(iterator, const CurvePoint&);
+ iterator addPoint(iterator, const KisPoint&, bool = false, bool = false, int = POINTHINT);
+
+ iterator pushPoint(const CurvePoint&);
+ iterator pushPoint(const KisPoint&, bool = false, bool = false, int = POINTHINT);
+
+ virtual iterator addPivot(iterator, const KisPoint&);
+ virtual iterator pushPivot(const KisPoint&);
+
+ int count() const {return m_curve.count();}
+ bool isEmpty() const {return m_curve.isEmpty();}
+ CurvePoint first() {return m_curve.front();}
+ CurvePoint last() {return m_curve.back();}
+ void clear() {m_curve.clear();}
+
+ /* These needs iterators so they are implemented inline after the definition of CurveIterator */
+ iterator begin() const;
+ iterator lastIterator() const;
+ iterator end() const;
+ iterator tqfind(const CurvePoint& pt);
+ iterator tqfind(const KisPoint& pt);
+ iterator tqfind(iterator it, const CurvePoint& pt);
+ iterator tqfind(iterator it, const KisPoint& pt);
+
+ KisCurve pivots();
+ KisCurve selectedPivots(bool = true);
+ KisCurve subCurve(const KisPoint&);
+ KisCurve subCurve(const CurvePoint&);
+ KisCurve subCurve(iterator);
+ KisCurve subCurve(const KisPoint&, const KisPoint&);
+ KisCurve subCurve(const CurvePoint&, const CurvePoint&);
+ KisCurve subCurve(iterator,iterator);
+
+ /* Core virtual functions */
+ virtual void deleteFirstPivot();
+ virtual void deleteLastPivot();
+
+ virtual iterator deleteCurve(const KisPoint&, const KisPoint&);
+ virtual iterator deleteCurve(const CurvePoint&, const CurvePoint&);
+ virtual iterator deleteCurve(iterator, iterator);
+
+ /* Core of the Core, calculateCurve is the only function that *needs* an implementation in the derived curves */
+ virtual void calculateCurve(const KisPoint&, const KisPoint&, iterator);
+ virtual void calculateCurve(const CurvePoint&, const CurvePoint&, iterator);
+ virtual void calculateCurve(iterator, iterator, iterator);
+ virtual void calculateCurve(iterator*);
+ virtual void calculateCurve();
+
+ virtual iterator selectPivot(const CurvePoint&, bool = true);
+ virtual iterator selectPivot(const KisPoint&, bool = true);
+ virtual iterator selectPivot(iterator, bool = true);
+
+ virtual iterator movePivot(const CurvePoint&, const KisPoint&);
+ virtual iterator movePivot(const KisPoint&, const KisPoint&);
+ virtual iterator movePivot(iterator, const KisPoint&);
+
+ virtual void deletePivot(const CurvePoint&);
+ virtual void deletePivot(const KisPoint&);
+ virtual void deletePivot(iterator);
+
+ virtual void moveSelected(const KisPoint&);
+ virtual void deleteSelected();
+ virtual void selectAll(bool = true);
+};
+
+class CurveIterator {
+
+ const KisCurve *m_target;
+
+ BaseIterator m_position;
+
+public:
+
+ CurveIterator () { m_target = 0; m_position = 0;}
+
+ CurveIterator (const KisCurve &target)
+ {m_target = &target;}
+
+ CurveIterator (const CurveIterator &it)
+ {m_position = it.position(); m_target = it.target();}
+
+ CurveIterator (const KisCurve &target, BaseIterator it)
+ {m_position = it; m_target = &target;}
+
+ ~CurveIterator () {}
+
+ bool operator==(BaseIterator it) {return m_position == it;}
+ bool operator==(CurveIterator it) {return m_position == it.position();}
+ bool operator!=(BaseIterator it) {return m_position != it;}
+ bool operator!=(CurveIterator it) {return m_position != it.position();}
+
+ CurveIterator operator++() {++m_position;return *this;}
+ CurveIterator operator++(int) {CurveIterator temp = *this; m_position++; return temp;}
+ CurveIterator operator--() {--m_position;return *this;}
+ CurveIterator operator--(int) {CurveIterator temp = *this; m_position--; return temp;}
+ CurveIterator operator+=(int i) {m_position+=i;return *this;}
+ CurveIterator operator-=(int i) {m_position-=i;return *this;}
+ CurveIterator operator=(const BaseIterator &it) {m_position=it; return *this;}
+ CurvePoint& operator*() {return (*m_position);}
+
+ const KisCurve* target() const {return m_target;}
+ BaseIterator position() const {return m_position;}
+
+ CurveIterator next()
+ {
+ CurveIterator it = *this;
+ return ++it;
+ }
+
+ CurveIterator previous()
+ {
+ CurveIterator it = *this;
+ return --it;
+ }
+
+ CurveIterator previousPivot()
+ {
+ CurveIterator it = *this;
+ while (it != m_target->m_curve.begin()) {
+ it-=1;
+ if ((*it).isPivot())
+ return it;
+ }
+
+ return it;
+ }
+
+ CurveIterator nextPivot()
+ {
+ CurveIterator it = *this;
+ while (it != m_target->m_curve.end()) {
+ it+=1;
+ if ((*it).isPivot())
+ return it;
+ }
+ return it;
+ }
+};
+
+/* ************************************* *
+ * CurvePoint inline methods definitions *
+ * ************************************* */
+
+inline CurvePoint::CurvePoint ()
+ : m_pivot(0), m_selected(0), m_hint(POINTHINT)
+{
+
+}
+
+inline CurvePoint::CurvePoint (const KisPoint& pt, bool p, bool s, int h)
+ : m_pivot(p), m_selected((p) ? s : false), m_hint(h)
+{
+ m_point = pt;
+}
+
+inline CurvePoint::CurvePoint (double x, double y, bool p, bool s, int h)
+ : m_pivot(p), m_selected((p) ? s : false), m_hint(h)
+{
+ KisPoint tmp(x,y);
+ m_point = tmp;
+}
+
+inline void CurvePoint::setPoint(const KisPoint& p)
+{
+ m_point = p;
+}
+
+inline void CurvePoint::setPoint(double x, double y)
+{
+ KisPoint tmp(x,y);
+ m_point = tmp;
+}
+
+
+/* *********************************** *
+ * KisCurve inline methods definitions *
+ * *********************************** */
+
+inline bool KisCurve::checkIterator (KisCurve::iterator checking) const
+{
+ if (checking.target() != this)
+ return false;
+ else
+ return true;
+}
+
+inline KisCurve::iterator KisCurve::begin() const
+{
+ return iterator(*this,m_curve.begin());
+}
+
+inline KisCurve::iterator KisCurve::lastIterator() const
+{
+ return (iterator(*this,--m_curve.end()));
+}
+
+inline KisCurve::iterator KisCurve::end() const
+{
+ return iterator(*this,m_curve.end());
+}
+
+inline KisCurve::iterator KisCurve::tqfind (const CurvePoint& pt)
+{
+ return iterator(*this,m_curve.tqfind(pt));
+}
+
+inline KisCurve::iterator KisCurve::tqfind (const KisPoint& pt)
+{
+ return iterator(*this,m_curve.tqfind(CurvePoint(pt)));
+}
+
+inline KisCurve::iterator KisCurve::tqfind (KisCurve::iterator it, const CurvePoint& pt)
+{
+ return iterator(*this,m_curve.tqfind(it.position(),pt));
+}
+
+inline KisCurve::iterator KisCurve::tqfind (iterator it, const KisPoint& pt)
+{
+ return iterator(*this,m_curve.tqfind(it.position(),CurvePoint(pt)));
+}
+
+inline void KisCurve::calculateCurve(const KisPoint& start, const KisPoint& end, KisCurve::iterator it)
+{
+ calculateCurve(tqfind(CurvePoint(start)),tqfind(CurvePoint(end)),it);
+}
+
+inline void KisCurve::calculateCurve(const CurvePoint& start, const CurvePoint& end, KisCurve::iterator it)
+{
+ calculateCurve(tqfind(start),tqfind(end),it);
+}
+
+inline void KisCurve::calculateCurve(KisCurve::iterator, KisCurve::iterator, KisCurve::iterator)
+{
+ return;
+}
+
+/* Really generic functions, provided if someone _really_ needs them: array of iterators and no iterators. */
+inline void KisCurve::calculateCurve(KisCurve::iterator*) {return;}
+inline void KisCurve::calculateCurve() {return;}
+
+#endif // KIS_CURVE_FRAMEWORK_H_
diff --git a/chalk/plugins/tools/tool_curves/kis_tool_bezier.cc b/chalk/plugins/tools/tool_curves/kis_tool_bezier.cc
new file mode 100644
index 00000000..e3baf49c
--- /dev/null
+++ b/chalk/plugins/tools/tool_curves/kis_tool_bezier.cc
@@ -0,0 +1,366 @@
+/*
+ * kis_tool_bezier.cc -- part of Chalk
+ *
+ * Copyright (c) 2006 Emanuele Tamponi <emanuele@valinor.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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <math.h>
+
+#include <tqpainter.h>
+#include <tqlayout.h>
+#include <tqrect.h>
+
+#include <kaction.h>
+#include <kdebug.h>
+#include <klocale.h>
+#include <kdebug.h>
+#include <knuminput.h>
+
+#include "kis_global.h"
+#include "kis_doc.h"
+#include "kis_painter.h"
+#include "kis_point.h"
+#include "kis_canvas_subject.h"
+#include "kis_canvas_controller.h"
+#include "kis_canvas.h"
+#include "kis_canvas_painter.h"
+#include "kis_cursor.h"
+#include "kis_vec.h"
+
+#include "kis_curve_framework.h"
+#include "kis_tool_bezier.h"
+
+KisCurve::iterator KisCurveBezier::groupEndpoint (KisCurve::iterator it) const
+{
+ iterator temp = it;
+ if ((*it).hint() == BEZIERNEXTCONTROLHINT)
+ temp -= 1;
+ if ((*it).hint() == BEZIERPREVCONTROLHINT)
+ temp += 1;
+ return temp;
+}
+
+KisCurve::iterator KisCurveBezier::groupPrevControl (KisCurve::iterator it) const
+{
+ iterator temp = it;
+ if ((*it).hint() == BEZIERENDHINT)
+ temp -= 1;
+ if ((*it).hint() == BEZIERNEXTCONTROLHINT)
+ temp -= 2;
+ return temp;
+}
+
+KisCurve::iterator KisCurveBezier::groupNextControl (KisCurve::iterator it) const
+{
+ iterator temp = it;
+ if ((*it).hint() == BEZIERENDHINT)
+ temp += 1;
+ if ((*it).hint() == BEZIERPREVCONTROLHINT)
+ temp += 2;
+ return temp;
+}
+
+bool KisCurveBezier::groupSelected (KisCurve::iterator it) const
+{
+ if ((*groupPrevControl(it)).isSelected() || (*groupEndpoint(it)).isSelected() || (*groupNextControl(it)).isSelected())
+ return true;
+ return false;
+}
+
+KisCurve::iterator KisCurveBezier::nextGroupEndpoint (KisCurve::iterator it) const
+{
+ iterator temp = it;
+ if ((*it).hint() == BEZIERPREVCONTROLHINT) {
+ temp += 2;
+ temp = temp.nextPivot();
+ }
+ if ((*it).hint() == BEZIERENDHINT) {
+ temp += 1;
+ temp = temp.nextPivot();
+ }
+ if ((*it).hint() == BEZIERNEXTCONTROLHINT) {
+ temp = temp.nextPivot();
+ }
+ temp = temp.nextPivot();
+ return temp;
+}
+
+KisCurve::iterator KisCurveBezier::prevGroupEndpoint (KisCurve::iterator it) const
+{
+ iterator temp = it;
+ if ((*it).hint() == BEZIERNEXTCONTROLHINT) {
+ temp -= 1;
+ temp = temp.previousPivot().previousPivot();
+ }
+ if ((*it).hint() == BEZIERENDHINT) {
+ temp = temp.previousPivot().previousPivot();
+ }
+ if ((*it).hint() == BEZIERPREVCONTROLHINT) {
+ temp = temp.previousPivot();
+ }
+ temp = temp.previousPivot();
+ return temp;
+}
+
+KisPoint KisCurveBezier::midpoint (const KisPoint& P1, const KisPoint& P2)
+{
+ KisPoint temp;
+ temp.setX((P1.x()+P2.x())/2);
+ temp.setY((P1.y()+P2.y())/2);
+ return temp;
+}
+
+void KisCurveBezier::recursiveCurve (const KisPoint& P1, const KisPoint& P2, const KisPoint& P3,
+ const KisPoint& P4, int level, KisCurve::iterator it)
+{
+ if (level > m_maxLevel) {
+ addPoint(it,midpoint(P1,P4),false,false,LINEHINT);
+ return;
+ }
+
+ KisPoint L1, L2, L3, L4;
+ KisPoint H, R1, R2, R3, R4;
+
+ L1 = P1;
+ L2 = midpoint(P1, P2);
+ H = midpoint(P2, P3);
+ R3 = midpoint(P3, P4);
+ R4 = P4;
+ L3 = midpoint(L2, H);
+ R2 = midpoint(R3, H);
+ L4 = midpoint(L3, R2);
+ R1 = L4;
+ recursiveCurve(L1, L2, L3, L4, level + 1, it);
+ recursiveCurve(R1, R2, R3, R4, level + 1, it);
+}
+
+void KisCurveBezier::calculateCurve(KisCurve::iterator tstart, KisCurve::iterator tend, KisCurve::iterator)
+{
+ if (pivots().count() < 4)
+ return;
+
+ iterator origin, dest, control1, control2;
+
+ if ((*tstart).hint() == BEZIERENDHINT) {
+ origin = tstart;
+ control1 = tstart.nextPivot();
+ } else if ((*tstart).hint() == BEZIERNEXTCONTROLHINT) {
+ origin = tstart.previousPivot();
+ control1 = tstart;
+ } else if ((*tstart).hint() == BEZIERPREVCONTROLHINT) {
+ origin = tstart.nextPivot();
+ control1 = origin.nextPivot();
+ } else
+ return;
+
+ if ((*tend).hint() == BEZIERENDHINT) {
+ dest = tend;
+ control2 = tend.previousPivot();
+ } else if ((*tend).hint() == BEZIERPREVCONTROLHINT) {
+ dest = tend.nextPivot();
+ control2 = tend;
+ } else if ((*tend).hint() == BEZIERNEXTCONTROLHINT) {
+ dest = tend.previousPivot();
+ control2 = dest.previousPivot();
+ } else
+ return;
+
+ deleteCurve(control1,control2);
+ recursiveCurve((*origin).point(),(*control1).point(),(*control2).point(),(*dest).point(),1,control2);
+
+}
+
+KisCurve::iterator KisCurveBezier::pushPivot (const KisPoint& point)
+{
+ iterator it;
+
+ it = pushPoint(point,true,false,BEZIERENDHINT);
+ if (count() > 1)
+ addPoint(it,point,true,false,BEZIERPREVCONTROLHINT);
+
+ it = pushPoint(point,true,false,BEZIERNEXTCONTROLHINT);
+
+ return selectPivot(it);
+}
+
+KisCurve::iterator KisCurveBezier::movePivot(KisCurve::iterator it, const KisPoint& newPt)
+{
+ if (!(*it).isPivot())
+ return end();
+
+ int hint = (*it).hint();
+ iterator thisEnd, prevEnd, nextEnd;
+
+ thisEnd = groupEndpoint(it);
+ prevEnd = prevGroupEndpoint(it);
+ nextEnd = nextGroupEndpoint(it);
+
+ if (hint == BEZIERENDHINT) {
+ KisPoint trans = newPt - (*it).point();
+ (*thisEnd).setPoint((*thisEnd).point()+trans);
+ (*thisEnd.previous()).setPoint((*thisEnd.previous()).point()+trans);
+ (*thisEnd.next()).setPoint((*thisEnd.next()).point()+trans);
+ } else if (!(m_actionOptions & KEEPSELECTEDOPTION))
+ (*it).setPoint(newPt);
+ if (!(m_actionOptions & KEEPSELECTEDOPTION) && hint != BEZIERENDHINT) {
+ if (nextEnd == end() || (m_actionOptions & SYMMETRICALCONTROLSOPTION)) {
+ KisPoint trans = (*it).point() - (*thisEnd).point();
+ trans = KisPoint(-trans.x()*2,-trans.y()*2);
+ if (hint == BEZIERNEXTCONTROLHINT)
+ (*groupPrevControl(it)).setPoint(newPt+trans);
+ else
+ (*groupNextControl(it)).setPoint(newPt+trans);
+ }
+ }
+
+ if (nextEnd != end() && count() > 4)
+ calculateCurve (thisEnd,nextEnd,iterator());
+ if (prevEnd != thisEnd && count() > 4)
+ calculateCurve (prevEnd,thisEnd,iterator());
+
+ return it;
+}
+
+void KisCurveBezier::deletePivot (KisCurve::iterator it)
+{
+ if (!(*it).isPivot())
+ return;
+
+ iterator prevControl,thisEnd,nextControl;
+
+ prevControl = prevGroupEndpoint(it).nextPivot();
+ thisEnd = groupEndpoint(it);
+ nextControl = nextGroupEndpoint(it).previousPivot();
+
+ if ((*thisEnd) == first()) {
+ deleteFirstPivot();
+ deleteFirstPivot();
+ deleteFirstPivot();
+ } else if ((*thisEnd.next()) == last()) {
+ deleteLastPivot();
+ deleteLastPivot();
+ deleteLastPivot();
+ } else {
+ deleteCurve(prevControl,nextControl);
+ calculateCurve(prevControl,nextControl,iterator());
+ }
+}
+
+KisToolBezier::KisToolBezier(const TQString& UIName)
+ : super(UIName)
+{
+ m_derivated = new KisCurveBezier;
+ m_curve = m_derivated;
+
+ m_supportMinimalDraw = false;
+
+ m_transactionMessage = i18n("Bezier Curve");
+}
+
+KisToolBezier::~KisToolBezier()
+{
+
+}
+
+KisCurve::iterator KisToolBezier::handleUnderMouse(const TQPoint& pos)
+{
+ TQPoint qpos;
+ KisCurve pivs = m_curve->pivots(), inHandle;
+ KisCurve::iterator it;
+ int hint;
+ for (it = pivs.begin(); it != pivs.end(); it++) {
+ qpos = m_subject->canvasController()->windowToView((*it).point().toTQPoint());
+ hint = (*it).hint();
+ if (hint != BEZIERENDHINT && !m_derivated->groupSelected(it))
+ continue;
+ if (hint == BEZIERENDHINT && (m_actionOptions & SHIFTOPTION))
+ continue;
+ if (pivotRect(qpos).tqcontains(pos)) {
+ inHandle.pushPoint((*it));
+ if (hint == BEZIERENDHINT && !(m_actionOptions & SHIFTOPTION))
+ break;
+ if (hint != BEZIERENDHINT && (m_actionOptions & SHIFTOPTION))
+ break;
+ }
+ }
+ if (inHandle.isEmpty())
+ return m_curve->end();
+
+ return m_curve->tqfind(inHandle.last());
+}
+
+KisCurve::iterator KisToolBezier::drawPoint (KisCanvasPainter& gc, KisCurve::iterator point)
+{
+ if ((*point).hint() != BEZIERENDHINT)
+ return ++point;
+
+ KisCanvasController *controller = m_subject->canvasController();
+
+ // Now draw the bezier
+
+ KisCurve::iterator origin,control1,control2,destination;
+
+ origin = point;
+ control1 = origin.next();
+ control2 = control1.nextPivot();
+ destination = control2.next();
+
+ if (control2 != m_curve->end()) {
+ point = control2;
+ TQPointArray vec(4);
+ vec[0] = controller->windowToView((*origin).point().toTQPoint());
+ vec[1] = controller->windowToView((*control1).point().toTQPoint());
+ vec[2] = controller->windowToView((*control2).point().toTQPoint());
+ vec[3] = controller->windowToView((*destination).point().toTQPoint());
+ gc.drawCubicBezier(vec);
+ }
+
+ point += 1;
+
+ return point;
+}
+
+void KisToolBezier::drawPivotHandle (KisCanvasPainter& gc, KisCurve::iterator point)
+{
+ if ((*point).hint() != BEZIERENDHINT)
+ return;
+
+ KisCanvasController *controller = m_subject->canvasController();
+
+ TQPoint endpPos = controller->windowToView((*point).point().toTQPoint());
+
+ if (!m_derivated->groupSelected(point)) {
+ gc.setPen(m_pivotPen);
+ gc.drawRoundRect(pivotRect(endpPos),m_pivotRounding,m_pivotRounding);
+ } else {
+ TQPoint nextControlPos = controller->windowToView((*point.next()).point().toTQPoint());
+ TQPoint prevControlPos = controller->windowToView((*point.previousPivot()).point().toTQPoint());
+
+ gc.setPen(m_selectedPivotPen);
+ gc.drawRoundRect(selectedPivotRect(endpPos),m_selectedPivotRounding,m_selectedPivotRounding);
+ if ((prevControlPos != endpPos || nextControlPos != endpPos) && !(m_actionOptions & CONTROLOPTION)) {
+ gc.drawRoundRect(pivotRect(nextControlPos),m_pivotRounding,m_pivotRounding);
+ gc.drawLine(endpPos,nextControlPos);
+ gc.drawRoundRect(pivotRect(prevControlPos),m_pivotRounding,m_pivotRounding);
+ gc.drawLine(prevControlPos,endpPos);
+ }
+ }
+
+ gc.setPen(m_drawingPen);
+}
+
+#include "kis_tool_bezier.moc"
diff --git a/chalk/plugins/tools/tool_curves/kis_tool_bezier.h b/chalk/plugins/tools/tool_curves/kis_tool_bezier.h
new file mode 100644
index 00000000..e1e0521a
--- /dev/null
+++ b/chalk/plugins/tools/tool_curves/kis_tool_bezier.h
@@ -0,0 +1,98 @@
+/*
+ * kis_tool_bezier.h -- part of Chalk
+ *
+ * Copyright (c) 2006 Emanuele Tamponi <emanuele@valinor.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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef KIS_TOOL_BEZIER_H_
+#define KIS_TOOL_BEZIER_H_
+
+#include "kis_tool_factory.h"
+#include "kis_tool_curve.h"
+#include "kis_point.h"
+
+class CurvePoint;
+class KisPoint;
+class KisCanvas;
+class KisCurve;
+class KisPainter;
+class KisPoint;
+
+const int BEZIERENDHINT = 0x0010;
+const int BEZIERPREVCONTROLHINT = 0x0020;
+const int BEZIERNEXTCONTROLHINT = 0x0040;
+
+const int SYMMETRICALCONTROLSOPTION = ALTOPTION;
+const int PREFERCONTROLSOPTION = SHIFTOPTION;
+
+class KisCurveBezier : public KisCurve {
+
+ typedef KisCurve super;
+
+ void recursiveCurve (const KisPoint& P1, const KisPoint& P2, const KisPoint& P3,
+ const KisPoint& P4, int level, iterator it);
+ KisPoint midpoint (const KisPoint&, const KisPoint&);
+
+ int m_maxLevel;
+
+public:
+
+ KisCurveBezier() : super() {m_maxLevel = 5;}
+
+ ~KisCurveBezier() {}
+
+ virtual void calculateCurve(iterator, iterator, iterator);
+ virtual iterator pushPivot(const KisPoint&);
+ virtual iterator movePivot(iterator, const KisPoint&);
+ virtual void deletePivot(iterator);
+
+public:
+
+ iterator groupEndpoint (iterator) const;
+ iterator groupPrevControl (iterator) const;
+ iterator groupNextControl (iterator) const;
+
+ bool groupSelected (iterator) const;
+
+ iterator nextGroupEndpoint (iterator) const;
+ iterator prevGroupEndpoint (iterator) const;
+
+};
+
+class KisToolBezier : public KisToolCurve {
+
+ typedef KisToolCurve super;
+ Q_OBJECT
+ TQ_OBJECT
+
+public:
+ KisToolBezier(const TQString&);
+ virtual ~KisToolBezier();
+
+protected:
+
+ virtual KisCurve::iterator handleUnderMouse(const TQPoint& pos);
+ virtual void drawPivotHandle(KisCanvasPainter& gc, KisCurve::iterator point);
+ virtual KisCurve::iterator drawPoint(KisCanvasPainter& gc, KisCurve::iterator point);
+
+protected:
+
+ KisCurveBezier *m_derivated;
+
+};
+
+#endif //__KIS_TOOL_BEZIER_H__
diff --git a/chalk/plugins/tools/tool_curves/kis_tool_bezier_paint.cc b/chalk/plugins/tools/tool_curves/kis_tool_bezier_paint.cc
new file mode 100644
index 00000000..663e1324
--- /dev/null
+++ b/chalk/plugins/tools/tool_curves/kis_tool_bezier_paint.cc
@@ -0,0 +1,115 @@
+/*
+ * kis_tool_curve.cc -- part of Chalk
+ *
+ * Copyright (c) 2006 Emanuele Tamponi <emanuele@valinor.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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+
+#include <tqpainter.h>
+#include <tqlayout.h>
+#include <tqrect.h>
+#include <tqlabel.h>
+#include <tqpushbutton.h>
+#include <tqwhatsthis.h>
+#include <tqcheckbox.h>
+
+#include <kaction.h>
+#include <kdebug.h>
+#include <klocale.h>
+#include <kiconloader.h>
+
+#include "kis_cmb_composite.h"
+#include "kis_colorspace.h"
+#include "kis_config.h"
+#include "kis_cursor.h"
+#include "kis_doc.h"
+#include "kis_global.h"
+#include "kis_image.h"
+#include "kis_int_spinbox.h"
+#include "kis_paint_device.h"
+#include "kis_painter.h"
+#include "kis_paintop_registry.h"
+#include "kis_point.h"
+#include "kis_tool_controller.h"
+#include "kis_tool_paint.h"
+
+#include "kis_canvas.h"
+#include "kis_canvas_painter.h"
+#include "kis_canvas_subject.h"
+
+#include "kis_curve_framework.h"
+#include "kis_tool_bezier_paint.h"
+
+KisToolBezierPaint::KisToolBezierPaint()
+ : super(i18n("Bezier Painting Tool"))
+{
+ setName("tool_bezier_paint");
+ m_cursor = "tool_bezier_cursor.png";
+ setCursor(KisCursor::load(m_cursor, 6, 6));
+}
+
+KisToolBezierPaint::~KisToolBezierPaint()
+{
+
+}
+
+KisCurve::iterator KisToolBezierPaint::paintPoint (KisPainter& painter, KisCurve::iterator point)
+{
+ KisCurve::iterator origin,destination,control1,control2;
+ switch ((*point).hint()) {
+ case BEZIERENDHINT:
+ origin = point++;
+ control1 = point;
+ control2 = control1.nextPivot();
+ destination = control2.next();
+ if (m_curve->count() > 4 && (*point) != m_curve->last()) {
+ point = point.nextPivot().next();
+ painter.paintAt((*origin).point(),PRESSURE_DEFAULT,0,0);
+ painter.paintBezierCurve((*origin).point(),PRESSURE_DEFAULT,0,0,(*control1).point(),
+ (*control2).point(),(*destination).point(),PRESSURE_DEFAULT,0,0,0);
+ }
+ break;
+ default:
+ point = super::paintPoint(painter,point);
+ }
+
+ return point;
+}
+
+void KisToolBezierPaint::setup(KActionCollection *collection)
+{
+ m_action = static_cast<KRadioAction *>(collection->action(name()));
+
+ if (m_action == 0) {
+ KShortcut shortcut(TQt::Key_Plus);
+ shortcut.append(KShortcut(TQt::Key_F9));
+ m_action = new KRadioAction(i18n("&Bezier"),
+ "tool_bezier_paint",
+ shortcut,
+ this,
+ TQT_SLOT(activate()),
+ collection,
+ name());
+ Q_CHECK_PTR(m_action);
+
+ m_action->setToolTip(i18n("Draw cubic beziers. Keep Alt, Control or Shift pressed for options. Return or double-click to finish."));
+ m_action->setExclusiveGroup("tools");
+ m_ownAction = true;
+ }
+}
+
+#include "kis_tool_bezier_paint.moc"
diff --git a/chalk/plugins/tools/tool_curves/kis_tool_bezier_paint.h b/chalk/plugins/tools/tool_curves/kis_tool_bezier_paint.h
new file mode 100644
index 00000000..c2a3715b
--- /dev/null
+++ b/chalk/plugins/tools/tool_curves/kis_tool_bezier_paint.h
@@ -0,0 +1,63 @@
+/*
+ * kis_tool_curve_paint.h -- part of Chalk
+ *
+ * Copyright (c) 2006 Emanuele Tamponi <emanuele@valinor.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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef KIS_TOOL_BEZIER_PAINT_H_
+#define KIS_TOOL_BEZIER_PAINT_H_
+
+#include "kis_tool_factory.h"
+#include "kis_tool_bezier.h"
+#include "kis_point.h"
+
+class KisToolBezierPaint : public KisToolBezier {
+
+ typedef KisToolBezier super;
+ Q_OBJECT
+ TQ_OBJECT
+
+public:
+ KisToolBezierPaint();
+ virtual ~KisToolBezierPaint();
+
+ virtual void setup(KActionCollection *collection);
+ virtual enumToolType toolType() { return TOOL_SHAPE; }
+ virtual TQ_UINT32 priority() { return 7; }
+
+protected:
+
+ virtual KisCurve::iterator paintPoint(KisPainter& painter, KisCurve::iterator point);
+
+};
+
+class KisToolBezierPaintFactory : public KisToolFactory {
+ typedef KisToolFactory super;
+public:
+ KisToolBezierPaintFactory() : super() {};
+ virtual ~KisToolBezierPaintFactory(){};
+
+ virtual KisTool * createTool(KActionCollection * ac) {
+ KisTool * t = new KisToolBezierPaint();
+ Q_CHECK_PTR(t);
+ t->setup(ac);
+ return t;
+ }
+ virtual KisID id() { return KisID("beziertqshape", i18n("Bezier Painting Tool")); }
+};
+
+#endif //__KIS_TOOL_CURVE_PAINT_H_
diff --git a/chalk/plugins/tools/tool_curves/kis_tool_bezier_select.cc b/chalk/plugins/tools/tool_curves/kis_tool_bezier_select.cc
new file mode 100644
index 00000000..ed1200d4
--- /dev/null
+++ b/chalk/plugins/tools/tool_curves/kis_tool_bezier_select.cc
@@ -0,0 +1,104 @@
+/*
+ * kis_tool_curve.cc -- part of Chalk
+ *
+ * Copyright (c) 2006 Emanuele Tamponi <emanuele@valinor.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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+
+#include <tqpainter.h>
+#include <tqlayout.h>
+#include <tqrect.h>
+#include <tqlabel.h>
+#include <tqpushbutton.h>
+#include <tqwhatsthis.h>
+#include <tqcheckbox.h>
+
+#include <kaction.h>
+#include <kdebug.h>
+#include <klocale.h>
+#include <kiconloader.h>
+
+#include "kis_cmb_composite.h"
+#include "kis_colorspace.h"
+#include "kis_config.h"
+#include "kis_cursor.h"
+#include "kis_doc.h"
+#include "kis_global.h"
+#include "kis_image.h"
+#include "kis_int_spinbox.h"
+#include "kis_paint_device.h"
+#include "kis_painter.h"
+#include "kis_paintop_registry.h"
+#include "kis_point.h"
+#include "kis_tool_controller.h"
+#include "kis_tool_paint.h"
+
+#include "kis_canvas.h"
+#include "kis_canvas_painter.h"
+#include "kis_canvas_subject.h"
+
+#include "kis_curve_framework.h"
+#include "kis_tool_bezier_select.h"
+
+KisToolBezierSelect::KisToolBezierSelect()
+ : super(i18n("Bezier Selection Tool"))
+{
+ setName("tool_bezier_select");
+ m_cursor = "tool_bezier_cursor.png";
+ setCursor(KisCursor::load(m_cursor, 6, 6));
+}
+
+KisToolBezierSelect::~KisToolBezierSelect()
+{
+
+}
+
+TQValueVector<KisPoint> KisToolBezierSelect::convertCurve()
+{
+ TQValueVector<KisPoint> points;
+
+ for (KisCurve::iterator i = m_curve->begin(); i != m_curve->end(); i++) {
+ if (((*i).hint() != BEZIERPREVCONTROLHINT) && ((*i).hint() != BEZIERNEXTCONTROLHINT))
+ points.append((*i).point());
+ }
+
+ return points;
+}
+
+void KisToolBezierSelect::setup(KActionCollection *collection)
+{
+ m_action = static_cast<KRadioAction *>(collection->action(name()));
+
+ if (m_action == 0) {
+ KShortcut shortcut(TQt::Key_Plus);
+ shortcut.append(KShortcut(TQt::Key_F9));
+ m_action = new KRadioAction(i18n("&Bezier"),
+ "tool_bezier_select",
+ shortcut,
+ this,
+ TQT_SLOT(activate()),
+ collection,
+ name());
+ Q_CHECK_PTR(m_action);
+
+ m_action->setToolTip(i18n("Select areas of the image with bezier paths."));
+ m_action->setExclusiveGroup("tools");
+ m_ownAction = true;
+ }
+}
+
+#include "kis_tool_bezier_select.moc"
diff --git a/chalk/plugins/tools/tool_curves/kis_tool_bezier_select.h b/chalk/plugins/tools/tool_curves/kis_tool_bezier_select.h
new file mode 100644
index 00000000..07aecc3a
--- /dev/null
+++ b/chalk/plugins/tools/tool_curves/kis_tool_bezier_select.h
@@ -0,0 +1,63 @@
+/*
+ * kis_tool_curve_paint.h -- part of Chalk
+ *
+ * Copyright (c) 2006 Emanuele Tamponi <emanuele@valinor.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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef KIS_TOOL_BEZIER_SELECT_H_
+#define KIS_TOOL_BEZIER_SELECT_H_
+
+#include "kis_tool_factory.h"
+#include "kis_tool_bezier.h"
+#include "kis_point.h"
+
+class KisToolBezierSelect : public KisToolBezier {
+
+ typedef KisToolBezier super;
+ Q_OBJECT
+ TQ_OBJECT
+
+public:
+ KisToolBezierSelect();
+ virtual ~KisToolBezierSelect();
+
+ virtual void setup(KActionCollection *collection);
+ virtual enumToolType toolType() { return TOOL_SELECT; }
+ virtual TQ_UINT32 priority() { return 10; }
+
+protected:
+
+ virtual TQValueVector<KisPoint> convertCurve();
+
+};
+
+class KisToolBezierSelectFactory : public KisToolFactory {
+ typedef KisToolFactory super;
+public:
+ KisToolBezierSelectFactory() : super() {};
+ virtual ~KisToolBezierSelectFactory(){};
+
+ virtual KisTool * createTool(KActionCollection * ac) {
+ KisTool * t = new KisToolBezierSelect();
+ Q_CHECK_PTR(t);
+ t->setup(ac);
+ return t;
+ }
+ virtual KisID id() { return KisID("bezierselection", i18n("Bezier Selection Tool")); }
+};
+
+#endif //__KIS_TOOL_CURVE_PAINT_H_
diff --git a/chalk/plugins/tools/tool_curves/kis_tool_curve.cc b/chalk/plugins/tools/tool_curves/kis_tool_curve.cc
new file mode 100644
index 00000000..f98d2c72
--- /dev/null
+++ b/chalk/plugins/tools/tool_curves/kis_tool_curve.cc
@@ -0,0 +1,593 @@
+/*
+ * kis_tool_curve.cc -- part of Chalk
+ *
+ * Copyright (c) 2006 Emanuele Tamponi <emanuele@valinor.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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <math.h>
+#include <limits.h>
+
+#include <tqapplication.h>
+#include <tqpainter.h>
+#include <tqlayout.h>
+#include <tqrect.h>
+
+#include <kaction.h>
+#include <kdebug.h>
+#include <klocale.h>
+#include <kdebug.h>
+
+#include "kis_global.h"
+#include "kis_doc.h"
+#include "kis_painter.h"
+#include "kis_point.h"
+#include "kis_canvas_subject.h"
+#include "kis_canvas_controller.h"
+#include "kis_button_press_event.h"
+#include "kis_button_release_event.h"
+#include "kis_move_event.h"
+#include "kis_canvas.h"
+#include "kis_canvas_painter.h"
+#include "kis_cursor.h"
+#include "kis_tool_controller.h"
+#include "kis_vec.h"
+#include "kis_selection.h"
+#include "kis_selection_options.h"
+#include "kis_selected_transaction.h"
+#include "kis_paintop_registry.h"
+
+#include "kis_curve_framework.h"
+#include "kis_tool_curve.h"
+
+TQRect KisToolCurve::pivotRect (const TQPoint& pos)
+{
+ return TQRect (pos-TQPoint(4,4),pos+TQPoint(4,4));
+}
+
+TQRect KisToolCurve::selectedPivotRect (const TQPoint& pos)
+{
+ return TQRect (pos-TQPoint(5,5),pos+TQPoint(5,5));
+}
+
+KisToolCurve::KisToolCurve(const TQString& UIName)
+ : super(UIName)
+{
+ m_UIName = UIName;
+ m_currentImage = 0;
+ m_optWidget = 0;
+
+ m_curve = 0;
+
+ m_dragging = false;
+ m_draggingCursor = false;
+ m_drawPivots = true;
+ m_drawingPen = TQPen(TQt::white, 0, TQt::SolidLine);
+ m_pivotPen = TQPen(TQt::gray, 0, TQt::SolidLine);
+ m_selectedPivotPen = TQPen(TQt::yellow, 0, TQt::SolidLine);
+ m_pivotRounding = m_selectedPivotRounding = 55;
+
+ m_actionOptions = NOOPTIONS;
+ m_supportMinimalDraw = true;
+ m_selectAction = SELECTION_ADD;
+}
+
+KisToolCurve::~KisToolCurve()
+{
+
+}
+
+void KisToolCurve::update (KisCanvasSubject *subject)
+{
+ super::update(subject);
+ if (m_subject)
+ m_currentImage = m_subject->currentImg();
+}
+
+void KisToolCurve::deactivate()
+{
+ draw(false);
+ if (m_curve) {
+ m_curve->clear();
+ m_curve->endActionOptions();
+ }
+
+ m_actionOptions = NOOPTIONS;
+ m_dragging = false;
+ m_drawPivots = true;
+}
+
+void KisToolCurve::buttonPress(KisButtonPressEvent *event)
+{
+ updateOptions(event->state());
+ if (!m_currentImage)
+ return;
+ if (event->button() == Qt::LeftButton) {
+ m_dragging = true;
+ m_currentPoint = event->pos();
+ PointPair temp = pointUnderMouse (m_subject->canvasController()->windowToView(event->pos().toTQPoint()));
+ if (temp.first == m_curve->end() && !(m_actionOptions)) {
+ draw(true, true);
+ m_curve->selectAll(false);
+ draw(true, true);
+ draw(m_curve->end());
+ m_previous = m_curve->tqfind(m_curve->last());
+ m_current = m_curve->pushPivot(event->pos());
+ if (m_curve->pivots().count() > 1)
+ m_curve->calculateCurve(m_previous,m_current,m_current);
+ draw(m_current);
+ } else {
+ draw(true, true);
+ if (temp.second)
+ m_current = m_curve->selectPivot(temp.first);
+ else
+ m_current = selectByMouse(temp.first);
+
+ if (!(*m_current).isSelected())
+ m_dragging = false;
+ draw(true, true);
+ }
+ }
+}
+
+void KisToolCurve::keyPress(TQKeyEvent *event)
+{
+ if (event->key() == TQt::Key_Return) {
+ m_dragging = false;
+ commitCurve();
+ } else
+ if (event->key() == TQt::Key_Escape) {
+ m_dragging = false;
+ draw(false);
+ m_curve->clear();
+ } else
+ if (event->key() == TQt::Key_Delete) {
+ draw(false);
+ m_dragging = false;
+ m_curve->deleteSelected();
+ m_current = m_curve->tqfind(m_curve->last());
+ m_previous = m_curve->selectPivot(m_current);
+ draw(false);
+ }
+}
+
+void KisToolCurve::keyRelease(TQKeyEvent *)
+{
+
+}
+
+void KisToolCurve::buttonRelease(KisButtonReleaseEvent *event)
+{
+ updateOptions(event->state());
+ m_dragging = false;
+}
+
+void KisToolCurve::doubleClick(KisDoubleClickEvent *)
+{
+ commitCurve();
+}
+
+void KisToolCurve::move(KisMoveEvent *event)
+{
+ updateOptions(event->state());
+ PointPair temp = pointUnderMouse(m_subject->canvasController()->windowToView(event->pos().toTQPoint()));
+ if (temp.first == m_curve->end() && !m_dragging) {
+ if (m_draggingCursor) {
+ setCursor(KisCursor::load(m_cursor, 6, 6));
+ m_draggingCursor = false;
+ }
+ } else {
+ setCursor(KisCursor::load("tool_curve_dragging.png", 6, 6));
+ m_draggingCursor = true;
+ }
+ if (m_dragging) {
+ draw();
+ KisPoint trans = event->pos() - m_currentPoint;
+ m_curve->moveSelected(trans);
+ m_currentPoint = event->pos();
+ draw();
+ }
+}
+
+double pointToSegmentDistance(const KisPoint& p, const KisPoint& l0, const KisPoint& l1)
+{
+ double lineLength = sqrt((l1.x() - l0.x()) * (l1.x() - l0.x()) + (l1.y() - l0.y()) * (l1.y() - l0.y()));
+ double distance = 0;
+ KisVector2D v0(l0), v1(l1), v(p), seg(v0-v1), dist0(v0-p), dist1(v1-p);
+
+ if (seg.length() < dist0.length() ||
+ seg.length() < dist1.length()) // the point doesn't perpendicolarly intersecate the segment (or it's too far from the segment)
+ return (double)INT_MAX;
+
+ if (lineLength > DBL_EPSILON) {
+ distance = ((l0.y() - l1.y()) * p.x() + (l1.x() - l0.x()) * p.y() + l0.x() * l1.y() - l1.x() * l0.y()) / lineLength;
+ distance = fabs(distance);
+ }
+
+ return distance;
+}
+
+PointPair KisToolCurve::pointUnderMouse(const TQPoint& pos)
+{
+ KisCurve::iterator it, next;
+ TQPoint pos1, pos2;
+ it = handleUnderMouse(pos);
+ if (it != m_curve->end())
+ return PointPair(it,true);
+
+ for (it = m_curve->begin(); it != m_curve->end(); it++) {
+ next = it.next();
+ if (next == m_curve->end() || it == m_curve->end())
+ return PointPair(m_curve->end(),false);
+ if ((*it).hint() > LINEHINT || (*next).hint() > LINEHINT)
+ continue;
+ pos1 = m_subject->canvasController()->windowToView((*it).point().toTQPoint());
+ pos2 = m_subject->canvasController()->windowToView((*next).point().toTQPoint());
+ if (pos1 == pos2)
+ continue;
+ if (pointToSegmentDistance(pos,pos1,pos2) <= MAXDISTANCE)
+ break;
+ }
+
+ return PointPair(it,false);
+}
+
+KisCurve::iterator KisToolCurve::handleUnderMouse(const TQPoint& pos)
+{
+ KisCurve pivs = m_curve->pivots(), inHandle;
+ KisCurve::iterator it;
+ for (it = pivs.begin(); it != pivs.end(); it++) {
+ if (pivotRect(m_subject->canvasController()->windowToView((*it).point().toTQPoint())).tqcontains(pos))
+ inHandle.pushPoint((*it));
+ }
+ if (inHandle.isEmpty())
+ return m_curve->end();
+ return m_curve->tqfind(inHandle.last());
+}
+
+KisCurve::iterator KisToolCurve::selectByMouse(KisCurve::iterator it)
+{
+ KisCurve::iterator prevPivot, nextPivot;
+
+ if ((*it).isPivot())
+ prevPivot = it;
+ else
+ prevPivot = it.previousPivot();
+ nextPivot = it.nextPivot();
+
+ m_curve->selectPivot(prevPivot);
+ (*nextPivot).setSelected(true);
+
+ return prevPivot;
+}
+
+int KisToolCurve::updateOptions(int key)
+{
+ int options = 0x0000;
+
+ if (key & TQt::ControlButton)
+ options |= CONTROLOPTION;
+
+ if (key & TQt::ShiftButton)
+ options |= SHIFTOPTION;
+
+ if (key & TQt::AltButton)
+ options |= ALTOPTION;
+
+ if (options != m_actionOptions) {
+ draw(false);
+ m_actionOptions = options;
+ m_curve->setActionOptions(m_actionOptions);
+ draw(false);
+ }
+
+ return m_actionOptions;
+}
+
+void KisToolCurve::draw(bool m, bool o)
+{
+ draw(KisCurve::iterator(), o, m);
+}
+
+void KisToolCurve::draw(KisCurve::iterator inf, bool pivotonly, bool minimal)
+{
+ if (m_curve->isEmpty())
+ return;
+ KisCanvasPainter *gc;
+ KisCanvasController *controller;
+ KisCanvas *canvas;
+ if (m_subject && m_currentImage) {
+ controller = m_subject->canvasController();
+ canvas = controller->kiscanvas();
+ gc = new KisCanvasPainter(canvas);
+ } else
+ return;
+
+ gc->setPen(m_drawingPen);
+ gc->setRasterOp(TQt::XorROP);
+
+ KisCurve::iterator it, finish;
+
+ if (minimal && m_supportMinimalDraw) {
+ if (pivotonly) {
+ KisCurve p = m_curve->pivots();
+ for (KisCurve::iterator i = p.begin(); i != p.end(); i++)
+ drawPivotHandle (*gc, i);
+ delete gc;
+ return;
+ }
+ if (inf.target() != 0) {
+ if (inf != m_curve->end()) {
+ it = inf.previousPivot();
+ finish = inf.nextPivot();
+ } else {
+ it = --m_curve->end();
+ finish = m_curve->end();
+ }
+ } else {
+ KisCurve sel = m_curve->selectedPivots();
+ if (sel.isEmpty()) {
+ delete gc;
+ return;
+ }
+ for (KisCurve::iterator i = sel.begin(); i != sel.end(); i++) {
+ it = m_curve->tqfind(*i).previousPivot();
+ finish = m_curve->tqfind(*i).nextPivot();
+ if ((*finish).isSelected())
+ finish = finish.previousPivot();
+ while (it != finish) {
+ if ((*it).isPivot())
+ drawPivotHandle (*gc, it);
+ it = drawPoint (*gc, it);
+ }
+ }
+ delete gc;
+ return;
+ }
+ } else {
+ it = m_curve->begin();
+ finish = m_curve->end();
+ }
+ while (it != finish) {
+ if ((*it).isPivot())
+ drawPivotHandle (*gc, it);
+ it = drawPoint (*gc, it);
+ }
+
+ delete gc;
+}
+
+KisCurve::iterator KisToolCurve::drawPoint(KisCanvasPainter& gc, KisCurve::iterator point)
+{
+ KisCanvasController *controller = m_subject->canvasController();
+
+ TQPoint pos1, pos2;
+ pos1 = controller->windowToView((*point).point().toTQPoint());
+
+ switch ((*point).hint()) {
+ case POINTHINT:
+ gc.drawPoint(pos1);
+ point += 1;
+ break;
+ case LINEHINT:
+ gc.drawPoint(pos1);
+ if (++point != m_curve->end() && (*point).hint() <= LINEHINT) {
+ pos2 = controller->windowToView((*point).point().toTQPoint());
+ gc.drawLine(pos1,pos2);
+ }
+ break;
+ default:
+ point += 1;
+ }
+
+ return point;
+}
+
+void KisToolCurve::drawPivotHandle(KisCanvasPainter& gc, KisCurve::iterator point)
+{
+ KisCanvasController *controller = m_subject->canvasController();
+
+ if (m_drawPivots) {
+ TQPoint pos = controller->windowToView((*point).point().toTQPoint());
+ if ((*point).isSelected()) {
+ gc.setPen(m_selectedPivotPen);
+ gc.drawRoundRect(selectedPivotRect(pos),m_selectedPivotRounding,m_selectedPivotRounding);
+ } else {
+ gc.setPen(m_pivotPen);
+ gc.drawRoundRect(pivotRect(pos),m_pivotRounding,m_pivotRounding);
+ }
+ gc.setPen(m_drawingPen);
+ }
+}
+
+void KisToolCurve::paint(KisCanvasPainter&)
+{
+ draw(false);
+}
+
+void KisToolCurve::paint(KisCanvasPainter&, const TQRect&)
+{
+ draw(false);
+}
+
+void KisToolCurve::commitCurve()
+{
+ if (toolType() == TOOL_SHAPE || toolType() == TOOL_FREEHAND)
+ paintCurve();
+ else if (toolType() == TOOL_SELECT)
+ selectCurve();
+ else
+ kdDebug(0) << "NO SUPPORT FOR THIS TYPE OF TOOL" << endl;
+
+ m_curve->clear();
+ m_curve->endActionOptions();
+}
+
+void KisToolCurve::paintCurve()
+{
+ KisPaintDeviceSP device = m_currentImage->activeDevice ();
+ if (!device) return;
+
+ KisPainter painter (device);
+ if (m_currentImage->undo()) painter.beginTransaction (m_transactionMessage);
+
+ painter.setPaintColor(m_subject->fgColor());
+ painter.setBrush(m_subject->currentBrush());
+ painter.setOpacity(m_opacity);
+ painter.setCompositeOp(m_compositeOp);
+ KisPaintOp * op = KisPaintOpRegistry::instance()->paintOp(m_subject->currentPaintop(), m_subject->currentPaintopSettings(), &painter);
+ painter.setPaintOp(op); // Painter takes ownership
+
+// Call paintPoint
+ KisCurve::iterator it = m_curve->begin();
+ while (it != m_curve->end())
+ it = paintPoint(painter,it);
+// Finish
+
+ device->setDirty( painter.dirtyRect() );
+ notifyModified();
+
+ if (m_currentImage->undo()) {
+ m_currentImage->undoAdapter()->addCommand(painter.endTransaction());
+ }
+
+ draw(false);
+}
+
+KisCurve::iterator KisToolCurve::paintPoint (KisPainter& painter, KisCurve::iterator point)
+{
+ KisCurve::iterator next = point; next+=1;
+ switch ((*point).hint()) {
+ case POINTHINT:
+ painter.paintAt((*point++).point(), PRESSURE_DEFAULT, 0, 0);
+ break;
+ case LINEHINT:
+ if (next != m_curve->end() && (*next).hint() <= LINEHINT)
+ painter.paintLine((*point++).point(), PRESSURE_DEFAULT, 0, 0, (*next).point(), PRESSURE_DEFAULT, 0, 0);
+ else
+ painter.paintAt((*point++).point(), PRESSURE_DEFAULT, 0, 0);
+ break;
+ default:
+ point += 1;
+ }
+
+ return point;
+}
+
+TQValueVector<KisPoint> KisToolCurve::convertCurve()
+{
+ TQValueVector<KisPoint> points;
+
+ for (KisCurve::iterator i = m_curve->begin(); i != m_curve->end(); i++)
+ if ((*i).hint() != NOHINTS)
+ points.append((*i).point());
+
+ return points;
+}
+
+void KisToolCurve::selectCurve()
+{
+ TQApplication::setOverrideCursor(KisCursor::waitCursor());
+ KisPaintDeviceSP dev = m_currentImage->activeDevice();
+ bool hasSelection = dev->hasSelection();
+ KisSelectedTransaction *t = 0;
+ if (m_currentImage->undo()) t = new KisSelectedTransaction(m_transactionMessage, dev);
+ KisSelectionSP selection = dev->selection();
+
+ if (!hasSelection) {
+ selection->clear();
+ }
+
+ KisPainter painter(selection.data());
+
+ painter.setPaintColor(KisColor(TQt::black, selection->colorSpace()));
+ painter.setFillStyle(KisPainter::FillStyleForegroundColor);
+ painter.setStrokeStyle(KisPainter::StrokeStyleNone);
+ painter.setBrush(m_subject->currentBrush());
+ painter.setOpacity(OPACITY_OPAQUE);
+ KisPaintOp * op = KisPaintOpRegistry::instance()->paintOp("paintbrush", 0, &painter);
+ painter.setPaintOp(op); // And now the painter owns the op and will destroy it.
+
+ switch (m_selectAction) {
+ case SELECTION_ADD:
+ painter.setCompositeOp(COMPOSITE_OVER);
+ break;
+ case SELECTION_SUBTRACT:
+ painter.setCompositeOp(COMPOSITE_SUBTRACT);
+ break;
+ default:
+ break;
+ }
+
+ painter.paintPolygon(convertCurve());
+
+
+ if(hasSelection) {
+ TQRect dirty(painter.dirtyRect());
+ dev->setDirty(dirty);
+ dev->emitSelectionChanged(dirty);
+ } else {
+ dev->setDirty();
+ dev->emitSelectionChanged();
+ }
+
+ if (m_currentImage->undo())
+ m_currentImage->undoAdapter()->addCommand(t);
+
+ TQApplication::restoreOverrideCursor();
+
+ draw(false);
+}
+
+TQWidget* KisToolCurve::createOptionWidget(TQWidget* tqparent)
+{
+ if (toolType() == TOOL_SHAPE || toolType() == TOOL_FREEHAND)
+ return super::createOptionWidget(tqparent);
+ else if (toolType() == TOOL_SELECT)
+ return createSelectionOptionWidget(tqparent);
+ else
+ kdDebug(0) << "NO SUPPORT FOR THIS TOOL TYPE" << endl;
+ return 0;
+}
+
+void KisToolCurve::slotSetAction(int action) {
+ if (action >= SELECTION_ADD && action <= SELECTION_SUBTRACT)
+ m_selectAction =(enumSelectionMode)action;
+}
+
+TQWidget* KisToolCurve::createSelectionOptionWidget(TQWidget* tqparent)
+{
+ m_optWidget = new KisSelectionOptions(tqparent, m_subject);
+ Q_CHECK_PTR(m_optWidget);
+ m_optWidget->setCaption(m_UIName);
+
+ connect (m_optWidget, TQT_SIGNAL(actionChanged(int)), this, TQT_SLOT(slotSetAction(int)));
+
+ TQVBoxLayout * l = dynamic_cast<TQVBoxLayout*>(m_optWidget->tqlayout());
+ l->addItem(new TQSpacerItem(1, 1, TQSizePolicy::Fixed, TQSizePolicy::Expanding));
+
+ return m_optWidget;
+}
+
+TQWidget* KisToolCurve::optionWidget()
+{
+ if (toolType() == TOOL_SELECT)
+ return m_optWidget;
+ else
+ return super::optionWidget();
+}
+
+#include "kis_tool_curve.moc"
diff --git a/chalk/plugins/tools/tool_curves/kis_tool_curve.h b/chalk/plugins/tools/tool_curves/kis_tool_curve.h
new file mode 100644
index 00000000..74d1ccda
--- /dev/null
+++ b/chalk/plugins/tools/tool_curves/kis_tool_curve.h
@@ -0,0 +1,205 @@
+/*
+ * kis_tool_curve.h -- part of Chalk
+ *
+ * Copyright (c) 2006 Emanuele Tamponi <emanuele@valinor.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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef KIS_TOOL_CURVE_H_
+#define KIS_TOOL_CURVE_H_
+
+#include <tqpen.h>
+#include <tqcursor.h>
+
+#include "kis_selection.h"
+#include "kis_tool_paint.h"
+#include "kis_canvas_subject.h"
+#include "kis_point.h"
+
+#include "kis_curve_framework.h"
+
+class TQRect;
+class KisPainter;
+class KisSelectionOptions;
+
+typedef TQPair<KisCurve::iterator,bool> PointPair;
+
+const double MAXDISTANCE = 2.5;
+double pointToSegmentDistance(const KisPoint& p, const KisPoint& l0, const KisPoint& l1);
+
+class KisToolCurve : public KisToolPaint {
+
+ typedef KisToolPaint super;
+ Q_OBJECT
+ TQ_OBJECT
+
+public:
+ KisToolCurve(const TQString& UIName);
+ virtual ~KisToolCurve();
+
+ virtual void update (KisCanvasSubject *subject);
+ virtual TQWidget* createOptionWidget(TQWidget* tqparent);
+
+ virtual void buttonPress(KisButtonPressEvent *event);
+ virtual void move(KisMoveEvent *event);
+ virtual void buttonRelease(KisButtonReleaseEvent *event);
+ virtual void doubleClick(KisDoubleClickEvent *event);
+ virtual void keyPress(TQKeyEvent *event);
+ virtual void keyRelease(TQKeyEvent *event);
+
+public slots:
+
+ virtual void deactivate();
+
+protected:
+
+ virtual void paint(KisCanvasPainter&);
+ virtual void paint(KisCanvasPainter&, const TQRect&);
+
+ /* ********************** *
+ * KisToolCurve interface *
+ * ********************** */
+
+ /*
+ * This keep in sync the options of the tool with the options of the curve
+ */
+ virtual int updateOptions(int);
+
+ virtual PointPair pointUnderMouse(const TQPoint& pos);
+ virtual KisCurve::iterator handleUnderMouse(const TQPoint& pos);
+
+ /*
+ * Select the needed points; called after pointUnderMouse
+ */
+ virtual KisCurve::iterator selectByMouse(KisCurve::iterator it);
+
+ /*
+ * draw() initializes the KisCanvasPainter and then loop on the points of the curve for drawing them.
+ */
+ virtual void draw(bool = true, bool = false);
+ virtual void draw(KisCurve::iterator inf, bool = false, bool = true);
+
+ /*
+ * Used by draw() to draw the current point of the curve. Can draw more than one point and then returns the last one
+ */
+ virtual KisCurve::iterator drawPoint(KisCanvasPainter& gc, KisCurve::iterator point);
+
+ /*
+ * Used by draw(), if a point is a pivot, this draw the handle around it (if m_drawPivots is set to true)
+ */
+ virtual void drawPivotHandle(KisCanvasPainter& gc, KisCurve::iterator point);
+
+ /*
+ * Methods for commiting the curve
+ */
+
+ /*
+ * Called by selectCurve(), this convert m_curve to a vector of KisPoint in order to be used by paintPolygon()
+ */
+ virtual TQValueVector<KisPoint> convertCurve();
+
+ /*
+ * Called by paintCurve(), it behaves essentially like drawPoint(), but this uses a KisPainter
+ */
+ virtual KisCurve::iterator paintPoint(KisPainter&, KisCurve::iterator);
+
+ /*
+ * Finish the curve: if the tool is a TOOL_SHAPE or TOOL_FREEHAND, calls paintCurve(), if it's a TOOL_SELECT, then selectCurve()
+ */
+ virtual void commitCurve();
+
+ /*
+ * Used by commitCurve() if the tool is a painting tool
+ */
+ virtual void paintCurve();
+
+ /*
+ * Used by commitCurve() if the tool is a selection tool
+ */
+ virtual void selectCurve();
+
+ /*
+ * Return the rect around a given point, assuming that that point is an unselected pivot
+ */
+ TQRect pivotRect (const TQPoint&);
+
+ /*
+ * Same as above for selected pivots
+ */
+ TQRect selectedPivotRect (const TQPoint&);
+
+protected:
+
+ KisImageSP m_currentImage;
+
+ KisCurve *m_curve;
+ KisCurve::iterator m_current;
+ KisCurve::iterator m_previous;
+ KisPoint m_currentPoint;
+
+ bool m_dragging;
+ bool m_drawPivots;
+ TQPen m_drawingPen;
+ TQPen m_pivotPen;
+ TQPen m_selectedPivotPen;
+ int m_pivotRounding;
+ int m_selectedPivotRounding;
+
+ int m_actionOptions;
+ bool m_supportMinimalDraw;
+ bool m_draggingCursor;
+
+ TQString m_transactionMessage;
+ TQString m_cursor;
+
+private:
+
+ TQString m_UIName;
+
+
+/* ********************************** *
+ * Selection Tools specific functions *
+ * ********************************** */
+
+public:
+
+ /*
+ * This initializes our Option Widget (called by createOptionWidget())
+ */
+ virtual TQWidget* createSelectionOptionWidget(TQWidget* tqparent);
+
+ /*
+ * This return our internal KisSelectionOptions if toolType() returns TOOL_SELECT
+ */
+ virtual TQWidget* optionWidget();
+
+public slots:
+
+ /*
+ * Slot for createSelectionOptionWidget()
+ */
+ virtual void slotSetAction(int);
+
+private:
+
+ /*
+ * Members used by slotSetAction() and selectCurve()
+ */
+ KisSelectionOptions* m_optWidget;
+ enumSelectionMode m_selectAction;
+};
+
+#endif //__KIS_TOOL_CURVE_H_
diff --git a/chalk/plugins/tools/tool_curves/kis_tool_example.cc b/chalk/plugins/tools/tool_curves/kis_tool_example.cc
new file mode 100644
index 00000000..e14abcb5
--- /dev/null
+++ b/chalk/plugins/tools/tool_curves/kis_tool_example.cc
@@ -0,0 +1,108 @@
+/*
+ * kis_tool_example.cc -- part of Chalk
+ *
+ * Copyright (c) 2006 Emanuele Tamponi <emanuele@valinor.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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+
+#include <tqpainter.h>
+#include <tqlayout.h>
+#include <tqrect.h>
+
+#include <kaction.h>
+#include <kdebug.h>
+#include <klocale.h>
+#include <kdebug.h>
+#include <knuminput.h>
+
+#include "kis_global.h"
+#include "kis_doc.h"
+#include "kis_painter.h"
+#include "kis_point.h"
+#include "kis_canvas_subject.h"
+#include "kis_canvas_controller.h"
+#include "kis_button_press_event.h"
+#include "kis_button_release_event.h"
+#include "kis_move_event.h"
+#include "kis_paintop_registry.h"
+#include "kis_canvas.h"
+#include "kis_canvas_painter.h"
+#include "kis_cursor.h"
+#include "kis_vec.h"
+
+#include "kis_curve_framework.h"
+
+#include "kis_tool_example.h"
+
+
+class KisCurveExample : public KisCurve {
+
+ typedef KisCurve super;
+
+public:
+
+ KisCurveExample() : super() {}
+
+ ~KisCurveExample() {}
+
+ virtual iterator pushPivot (const KisPoint&);
+
+};
+
+KisCurve::iterator KisCurveExample::pushPivot (const KisPoint& point)
+{
+ return selectPivot(iterator(*this,m_curve.append(CurvePoint(point,true,false,LINEHINT))), true);
+}
+
+KisToolExample::KisToolExample()
+ : super(i18n("Tool for Curves - Example"))
+{
+ setName("tool_example");
+ m_cursor = "tool_example_cursor.png";
+ setCursor(KisCursor::load(m_cursor, 6, 6));
+
+ m_curve = new KisCurveExample;
+}
+
+KisToolExample::~KisToolExample()
+{
+
+}
+
+void KisToolExample::setup(KActionCollection *collection)
+{
+ m_action = static_cast<KRadioAction *>(collection->action(name()));
+
+ if (m_action == 0) {
+ KShortcut shortcut(TQt::Key_Plus);
+ shortcut.append(KShortcut(TQt::Key_F9));
+ m_action = new KRadioAction(i18n("&Example"),
+ "tool_example",
+ shortcut,
+ this,
+ TQT_SLOT(activate()),
+ collection,
+ name());
+ Q_CHECK_PTR(m_action);
+
+ m_action->setToolTip(i18n("This is a test tool for the Curve Framework."));
+ m_action->setExclusiveGroup("tools");
+ m_ownAction = true;
+ }
+}
+
+#include "kis_tool_example.moc"
diff --git a/chalk/plugins/tools/tool_curves/kis_tool_example.h b/chalk/plugins/tools/tool_curves/kis_tool_example.h
new file mode 100644
index 00000000..e7bfd89e
--- /dev/null
+++ b/chalk/plugins/tools/tool_curves/kis_tool_example.h
@@ -0,0 +1,67 @@
+/*
+ * kis_tool_example.h -- part of Chalk
+ *
+ * Copyright (c) 2006 Emanuele Tamponi <emanuele@valinor.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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef KIS_TOOL_EXAMPLE_H_
+#define KIS_TOOL_EXAMPLE_H_
+
+#include "kis_tool_factory.h"
+#include "kis_tool_curve.h"
+#include "kis_point.h"
+
+class CurvePoint;
+class KisPoint;
+class KisCanvas;
+class KisCurve;
+class KisPainter;
+class KisPoint;
+class WdgToolExample;
+
+class KisToolExample : public KisToolCurve {
+
+ typedef KisToolCurve super;
+ Q_OBJECT
+ TQ_OBJECT
+
+public:
+ KisToolExample();
+ virtual ~KisToolExample();
+
+ virtual void setup(KActionCollection *collection);
+ virtual enumToolType toolType() { return TOOL_SHAPE; }
+
+};
+
+class KisToolExampleFactory : public KisToolFactory {
+ typedef KisToolFactory super;
+public:
+ KisToolExampleFactory() : super() {};
+ virtual ~KisToolExampleFactory(){};
+
+ virtual KisTool * createTool(KActionCollection * ac) {
+ KisTool * t = new KisToolExample();
+ Q_CHECK_PTR(t);
+ t->setup(ac);
+ return t;
+ }
+ virtual KisID id() { return KisID("exampletqshape", i18n("Example Tool")); }
+};
+
+
+#endif //__KIS_TOOL_EXAMPLE_H__
diff --git a/chalk/plugins/tools/tool_curves/kis_tool_moutline.cc b/chalk/plugins/tools/tool_curves/kis_tool_moutline.cc
new file mode 100644
index 00000000..4b7e51d4
--- /dev/null
+++ b/chalk/plugins/tools/tool_curves/kis_tool_moutline.cc
@@ -0,0 +1,809 @@
+/*
+ * kis_tool_moutline.cc -- part of Chalk
+ *
+ * Copyright (c) 2006 Emanuele Tamponi <emanuele@valinor.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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <math.h>
+#include <set>
+
+#include <tqpainter.h>
+#include <tqlayout.h>
+#include <tqrect.h>
+#include <tqlabel.h>
+#include <tqpushbutton.h>
+#include <tqslider.h>
+
+#include <kaction.h>
+#include <kdebug.h>
+#include <klocale.h>
+#include <kdebug.h>
+#include <knuminput.h>
+
+#include "kis_global.h"
+#include "kis_iterators_pixel.h"
+#include "kis_colorspace.h"
+#include "kis_channelinfo.h"
+#include "kis_doc.h"
+#include "kis_painter.h"
+#include "kis_point.h"
+#include "kis_canvas_subject.h"
+#include "kis_canvas_controller.h"
+#include "kis_button_press_event.h"
+#include "kis_button_release_event.h"
+#include "kis_move_event.h"
+#include "kis_canvas.h"
+#include "kis_canvas_painter.h"
+#include "kis_cursor.h"
+#include "kis_tool_controller.h"
+#include "kis_vec.h"
+#include "kis_selection.h"
+#include "kis_selection_options.h"
+#include "kis_selected_transaction.h"
+#include "kis_paintop_registry.h"
+#include "kis_convolution_painter.h"
+
+#include "kis_tool_moutline.h"
+
+using namespace std;
+
+#define RMS(a, b) (sqrt ((a) * (a) + (b) * (b)))
+#define ROUND(x) ((int) ((x) + 0.5))
+
+const int NOEDGE = 0x0000;
+
+const int ORTHOGONAL_COST = 10; // 1*10
+const int DIAGONAL_COST = 14; // sqrt(2)*10
+const int MALUS = 20; // This applies to NOEDGE nodes
+
+const int DEFAULTDIST = 40; // Default distance between two automatic pivots
+const int MAXDIST = 55; // Max distance
+const int MINDIST = 15;
+const int PAGESTEP = 5;
+
+class Node {
+
+ TQPoint m_pos;
+ int m_gCost;
+ int m_hCost;
+ int m_tCost;
+ bool m_malus;
+ TQPoint m_parent;
+
+public:
+
+ Node()
+ {
+ m_pos = m_parent = TQPoint(-1,-1);
+ m_gCost = m_hCost = m_tCost = 0;
+ m_malus = false;
+ }
+
+ Node(const Node& node)
+ {
+ m_pos = node.pos();
+ m_gCost = node.gCost();
+ m_hCost = node.hCost();
+ m_tCost = node.tCost();
+ m_malus = node.malus();
+ m_parent = node.tqparent();
+ }
+
+ Node(const TQPoint& tqparent, const TQPoint& pos, int g, int h, bool malus)
+ : m_pos(pos), m_hCost(h), m_malus(malus)
+ {
+ setGCost(g);
+ m_parent = tqparent;
+ }
+ ~Node ()
+ {
+ }
+
+ int gCost () const {return m_gCost;}
+ int hCost () const {return m_hCost;}
+ int tCost () const {return m_tCost;}
+ bool malus () const {return m_malus;}
+ TQPoint pos () const {return m_pos;}
+ int col () const {return m_pos.x();}
+ int row () const {return m_pos.y();}
+ TQPoint tqparent () const {return m_parent;}
+
+ void setGCost (int g)
+ {
+ m_gCost = g+(m_malus?MALUS:0);
+ m_tCost = m_gCost+m_hCost;
+ }
+ void setHCost (int h)
+ {
+ m_hCost = h;
+ m_tCost = m_gCost+m_hCost;
+ }
+ void setPos (const TQPoint& pos)
+ {
+ m_pos = pos;
+ }
+ void setMalus (bool malus)
+ {
+ m_malus = malus;
+ }
+ void clear ()
+ {
+ m_pos = TQPoint(-1,-1);
+ }
+
+ bool operator== (const Node& n2) const
+ {
+ return m_pos == n2.pos();
+ }
+ bool operator!= (const Node& n2) const
+ {
+ return m_pos != n2.pos();
+ }
+ bool operator== (const TQPoint& n2) const
+ {
+ return m_pos == n2;
+ }
+ bool operator!= (const TQPoint& n2) const
+ {
+ return m_pos != n2;
+ }
+ bool operator< (const Node& n2) const
+ {
+ return m_tCost < n2.tCost();
+ }
+ bool operator> (const Node& n2) const
+ {
+ return m_tCost > n2.tCost();
+ }
+
+ TQValueList<Node> getNeighbor(const GrayMatrix& src, const Node& end)
+ {
+ TQPoint tmpdist;
+ TQValueList<Node> temp;
+ int dcol, drow;
+ int g, h;
+ bool malus;
+ int x[8] = { 1, 1, 0,-1,-1,-1, 0, 1},
+ y[8] = { 0,-1,-1,-1, 0, 1, 1, 1};
+
+ for (int i = 0; i < 8; i++) {
+ dcol = m_pos.x() + x[i];
+ drow = m_pos.y() + y[i];
+ tmpdist = TQPoint(dcol,drow) - end.pos();
+ // I use src[0] here because all cols have same number of rows
+ if (dcol == (int)src.count() || dcol < 0 ||
+ drow == (int)src[0].count() || drow < 0)
+ continue;
+ if (src[dcol][drow])
+ malus = false;
+ else
+ malus = true;
+ if (i%2)
+ g = m_gCost + DIAGONAL_COST;
+ else
+ g = m_gCost + ORTHOGONAL_COST;
+ h = ORTHOGONAL_COST * (abs(tmpdist.x()) + abs(tmpdist.y()));
+ temp.append(Node(m_pos,TQPoint(dcol,drow),g,h,malus));
+ }
+ return temp;
+ }
+
+};
+
+KisKernelSP createKernel( TQ_INT32 i0, TQ_INT32 i1, TQ_INT32 i2,
+ TQ_INT32 i3, TQ_INT32 i4, TQ_INT32 i5,
+ TQ_INT32 i6, TQ_INT32 i7, TQ_INT32 i8,
+ TQ_INT32 factor, TQ_INT32 offset )
+{
+ KisKernelSP kernel = new KisKernel();
+ kernel->width = 3;
+ kernel->height = 3;
+
+ kernel->factor = factor;
+ kernel->offset = offset;
+
+ kernel->data = new TQ_INT32[9];
+ kernel->data[0] = i0;
+ kernel->data[1] = i1;
+ kernel->data[2] = i2;
+ kernel->data[3] = i3;
+ kernel->data[4] = i4;
+ kernel->data[5] = i5;
+ kernel->data[6] = i6;
+ kernel->data[7] = i7;
+ kernel->data[8] = i8;
+
+ return kernel;
+}
+
+KisCurveMagnetic::KisCurveMagnetic (KisToolMagnetic *tqparent)
+ : m_parent(tqparent)
+{
+ m_standardkeepselected = false;
+}
+
+KisCurveMagnetic::~KisCurveMagnetic ()
+{
+
+}
+
+KisCurve::iterator KisCurveMagnetic::addPivot (KisCurve::iterator it, const KisPoint& point)
+{
+ return iterator(*this,m_curve.insert(it.position(), CurvePoint(point,true,false,LINEHINT)));
+}
+
+KisCurve::iterator KisCurveMagnetic::pushPivot (const KisPoint& point)
+{
+ iterator it;
+
+ it = pushPoint(point,true,false,LINEHINT);
+// if (count() == 1 && !m_parent->editingMode())
+// addPoint(it,point,true,false,LINEHINT);
+
+ return selectPivot(it);
+}
+
+void KisCurveMagnetic::calculateCurve (KisCurve::iterator p1, KisCurve::iterator p2, KisCurve::iterator it)
+{
+ if (p1 == m_curve.end() || p2 == m_curve.end()) // It happens sometimes, for example on the first click
+ return;
+ if (m_parent->editingMode())
+ return;
+ TQPoint start = (*p1).point().roundTQPoint();
+ TQPoint end = (*p2).point().roundTQPoint();
+ TQRect rc = TQRect(start,end).normalize();
+ rc.setTopLeft(rc.topLeft()+TQPoint(-8,-8)); // Enlarge the view, so problems with gaussian blur can be removed
+ rc.setBottomRight(rc.bottomRight()+TQPoint(8,8)); // and we are able to find paths that go beyond the rect.
+
+ KisPaintDeviceSP src = m_parent->m_currentImage->activeDevice();
+ GrayMatrix dst = GrayMatrix(rc.width(),GrayCol(rc.height()));
+
+ detectEdges (rc, src, dst);
+ reduceMatrix (rc, dst, 3, 3, 3, 3);
+
+ Node startNode, endNode;
+ multiset<Node> openSet;
+ NodeMatrix openMatrix = NodeMatrix(rc.width(),NodeCol(rc.height()));
+ NodeMatrix closedMatrix = NodeMatrix(rc.width(),NodeCol(rc.height()));
+
+ TQPoint tl(rc.topLeft().x(),rc.topLeft().y());
+ start -= tl; // Relative to the matrix
+ end -= tl; // Relative to the matrix
+
+ findEdge (start.x(), start.y(), dst, startNode);
+ openMatrix[startNode.col()][startNode.row()] = *openSet.insert(startNode);
+ endNode.setPos(end);
+
+ while (!openSet.empty()) {
+ Node current = *openSet.begin();
+
+ openSet.erase(openSet.begin());
+ openMatrix[current.col()][current.row()].clear();
+
+ TQValueList<Node> successors = current.getNeighbor(dst,endNode);
+ for (TQValueList<Node>::iterator i = successors.begin(); i != successors.end(); i++) {
+ int col = (*i).col();
+ int row = (*i).row();
+ if ((*i) == endNode) {
+ while (current.tqparent() != TQPoint(-1,-1)) {
+ it = addPoint(it,KisPoint(tl+current.pos()),false,false,LINEHINT);
+ current = closedMatrix[current.tqparent().x()][current.tqparent().y()];
+ }
+ return;
+ }
+ Node *openNode = &openMatrix[col][row];
+ if (*openNode != TQPoint(-1,-1)) {
+ if (*i > *openNode)
+ continue;
+ else {
+ openSet.erase(tqFind(openSet.begin(),openSet.end(),*openNode));
+ openNode->clear(); // Clear the Node
+ }
+ }
+ Node *closedNode = &closedMatrix[col][row];
+ if (*closedNode != TQPoint(-1,-1)) {
+ if ((*i) > (*closedNode))
+ continue;
+ else {
+ openMatrix[col][row] = *openSet.insert(*closedNode);
+ closedNode->clear(); // Clear the Node
+ continue;
+ }
+ }
+ openMatrix[col][row] = *openSet.insert(*i);
+ }
+ closedMatrix[current.col()][current.row()] = current;
+ }
+}
+
+void KisCurveMagnetic::findEdge (int col, int row, const GrayMatrix& src, Node& node)
+{
+ int x = -1;
+ int y = -1;
+
+ // tmpdist out of range
+ KisVector2D mindist(5.0,5.0), tmpdist(1000.0,1000.0);
+ for (int i = -5; i < 6; i++) {
+ for (int j = -5; j < 6; j++) {
+ if (src[col+i][row+j] != NOEDGE) {
+ tmpdist = KisVector2D(i,j);
+ if (tmpdist.length() < mindist.length())
+ mindist = tmpdist;
+ }
+ }
+ }
+ if (tmpdist.x() == 1000.0)
+ mindist = KisVector2D(0.0,0.0);
+
+ x = (int)(col + mindist.x());
+ y = (int)(row + mindist.y());
+
+ node.setPos(TQPoint(x,y));
+}
+
+void KisCurveMagnetic::reduceMatrix (TQRect& rc, GrayMatrix& m, int top, int right, int bottom, int left)
+{
+ TQPoint topleft(top, left);
+ TQPoint bottomright(bottom, right);
+
+ rc.setTopLeft(rc.topLeft()+topleft);
+ rc.setBottomRight(rc.bottomRight()-bottomright);
+
+ if (left)
+ m.erase(m.begin(),m.begin()+left);
+ if (right)
+ m.erase(m.end()-right,m.end());
+ if (top) {
+ for (uint i = 0; i < m.count(); i++)
+ m[i].erase(m[i].begin(),m[i].begin()+top);
+ }
+ if (bottom) {
+ for (uint i = 0; i < m.count(); i++)
+ m[i].erase(m[i].end()-bottom,m[i].end());
+ }
+}
+
+void KisCurveMagnetic::detectEdges (const TQRect & rect, KisPaintDeviceSP src, GrayMatrix& dst)
+{
+ GrayMatrix graysrc(rect.width(),GrayCol(rect.height()));
+ GrayMatrix xdeltas(rect.width(),GrayCol(rect.height()));
+ GrayMatrix ydeltas(rect.width(),GrayCol(rect.height()));
+ GrayMatrix magnitude(rect.width(),GrayCol(rect.height()));
+ KisPaintDeviceSP smooth = new KisPaintDevice(src->colorSpace());
+
+ gaussianBlur(rect, src, smooth);
+ toGrayScale(rect, smooth, graysrc);
+ getDeltas(graysrc, xdeltas, ydeltas);
+ getMagnitude(xdeltas, ydeltas, magnitude);
+ nonMaxSupp(magnitude, xdeltas, ydeltas, dst);
+}
+
+void KisCurveMagnetic::gaussianBlur (const TQRect& rect, KisPaintDeviceSP src, KisPaintDeviceSP dst)
+{
+ int grectx = rect.x();
+ int grecty = rect.y();
+ int grectw = rect.width();
+ int grecth = rect.height();
+ if (dst != src) {
+ KisPainter gc(dst);
+ gc.bitBlt(grectx, grecty, COMPOSITE_COPY, src, grectx, grecty, grectw, grecth);
+ gc.end();
+ }
+
+ KisConvolutionPainter painter( dst );
+ // FIXME createKernel could create dynamic gaussian kernels having sigma as argument
+ KisKernelSP kernel = createKernel( 1, 1, 1, 1, 24, 1, 1, 1, 1, 32, 0);
+ painter.applyMatrix(kernel, grectx, grecty, grectw, grecth, BORDER_AVOID);
+}
+
+void KisCurveMagnetic::toGrayScale (const TQRect& rect, KisPaintDeviceSP src, GrayMatrix& dst)
+{
+ int grectx = rect.x();
+ int grecty = rect.y();
+ int grectw = rect.width();
+ int grecth = rect.height();
+ TQColor c;
+ KisColorSpace *cs = src->colorSpace();
+
+ for (int row = 0; row < grecth; row++) {
+ KisHLineIteratorPixel srcIt = src->createHLineIterator(grectx, grecty+row, grectw, false);
+ for (int col = 0; col < grectw; col++) {
+ cs->toTQColor(srcIt.rawData(),&c);
+ dst[col][row] = tqGray(c.rgb());
+ ++srcIt;
+ }
+ }
+}
+
+void KisCurveMagnetic::getDeltas (const GrayMatrix& src, GrayMatrix& xdelta, GrayMatrix& ydelta)
+{
+ uint start = 1, xend = src[0].count()-1, yend = src.count()-1;
+ TQ_INT16 deri;
+ for (uint col = 0; col < src.count(); col++) {
+ for (uint row = 0; row < src[col].count(); row++) {
+ if (row >= start && row < xend) {
+ deri = src[col][row+1] - src[col][row-1];
+ xdelta[col][row] = deri;
+ } else
+ xdelta[col][row] = 0;
+ if (col >= start && col < yend) {
+ deri = src[col+1][row] - src[col-1][row];
+ ydelta[col][row] = deri;
+ } else
+ ydelta[col][row] = 0;
+ }
+ }
+}
+
+void KisCurveMagnetic::getMagnitude (const GrayMatrix& xdelta, const GrayMatrix& ydelta, GrayMatrix& gradient)
+{
+ for (uint col = 0; col < xdelta.count(); col++) {
+ for (uint row = 0; row < xdelta[col].count(); row++)
+ gradient[col][row] = (TQ_INT16)(ROUND(RMS(xdelta[col][row],ydelta[col][row])));
+ }
+}
+
+void KisCurveMagnetic::nonMaxSupp (const GrayMatrix& magnitude, const GrayMatrix& xdelta, const GrayMatrix& ydelta, GrayMatrix& nms)
+{
+ // Directions:
+ // 1: 0 - 22.5 degrees
+ // 2: 22.5 - 67.5 degrees
+ // 3: 67.5 - 90 degrees
+ // Second direction is relative to a quadrant. The quadrant is known by looking at x and y derivatives
+ // First quadrant: Gx < 0 & Gy >= 0
+ // Second quadrant: Gx < 0 & Gy < 0
+ // Third quadrant: Gx >= 0 & Gy < 0
+ // Fourth quadrant: Gx >= 0 & Gy >= 0
+ // For this reason: first direction is relative to Gy only and third direction to Gx only
+
+ double theta; // theta = invtan (|Gy| / |Gx|) This give the direction relative to a quadrant
+ TQ_INT16 mag; // Current magnitude
+ TQ_INT16 lmag; // Magnitude at the left (So this pixel is "more internal" than the current
+ TQ_INT16 rmag; // Magnitude at the right (So this pixel is "more external")
+ double xdel; // Current xdelta
+ double ydel; // Current ydelta
+ TQ_INT16 result;
+
+ for (uint col = 0; col < magnitude.count(); col++) {
+ for (uint row = 0; row < magnitude[col].count(); row++) {
+ mag = magnitude[col][row];
+ if (!mag || row == 0 || row == (magnitude[col].count()-1) ||
+ col == 0 || col == (magnitude.count()-1))
+ {
+ result = NOEDGE;
+ } else {
+ xdel = (double)xdelta[col][row];
+ ydel = (double)ydelta[col][row];
+ theta = atan(fabs(ydel)/fabs(xdel));
+ if (theta < 0)
+ theta = fabs(theta)+M_PI_2;
+ theta = (theta * 360.0) / (2.0*M_PI); // Radians -> degrees
+ if (theta >= 0 && theta < 22.5) { // .0 - .3926990816
+ if (ydel >= 0) {
+ lmag = magnitude[col][row-1];
+ rmag = magnitude[col][row+1];
+ } else {
+ lmag = magnitude[col][row+1];
+ rmag = magnitude[col][row-1];
+ }
+ }
+ if (theta >= 22.5 && theta < 67.5) { // .3926990816 - 1.1780972449
+ if (xdel >= 0) {
+ if (ydel >= 0) {
+ lmag = magnitude[col-1][row-1];
+ rmag = magnitude[col+1][row+1];
+ } else {
+ lmag = magnitude[col+1][row-1];
+ rmag = magnitude[col-1][row+1];
+ }
+ } else {
+ if (ydel >= 0) {
+ lmag = magnitude[col-1][row+1];
+ rmag = magnitude[col+1][row-1];
+ } else {
+ lmag = magnitude[col+1][row+1];
+ rmag = magnitude[col-1][row-1];
+ }
+ }
+ }
+ if (theta >= 67.5 && theta <= 90.0) { // 1.1780972449 - 1.5707963266
+ if (xdel >= 0) {
+ lmag = magnitude[col+1][row];
+ rmag = magnitude[col-1][row];
+ } else {
+ lmag = magnitude[col-1][row];
+ rmag = magnitude[col+1][row];
+ }
+ }
+
+ if ((mag < lmag) || (mag < rmag)) {
+ result = NOEDGE;
+ } else {
+ if (rmag == mag) // If the external magnitude is equal to the current, suppress current.
+ result = NOEDGE;
+ else
+ result = (mag > 255) ? 255 : mag;
+ }
+ }
+ nms[col][row] = result;
+ }
+ }
+}
+
+KisToolMagnetic::KisToolMagnetic ()
+ : super("Magnetic Outline Tool")
+{
+ setName("tool_moutline");
+ setCursor(KisCursor::load("tool_moutline_cursor.png", 6, 6));
+
+ m_editingMode = false;
+ m_editingCursor = m_draggingCursor = false;
+
+ m_mode = 0;
+ m_curve = m_derived = 0;
+ m_current = m_previous = 0;
+
+ m_distance = DEFAULTDIST;
+
+ m_transactionMessage = i18n("Magnetic Outline Selection");
+}
+
+KisToolMagnetic::~KisToolMagnetic ()
+{
+ m_curve = 0;
+ delete m_derived;
+}
+
+void KisToolMagnetic::update (KisCanvasSubject *subject)
+{
+ super::update(subject);
+}
+
+void KisToolMagnetic::activate ()
+{
+ super::activate();
+ if (!m_derived) {
+ m_derived = new KisCurveMagnetic(this);
+ m_curve = m_derived;
+ }
+}
+
+void KisToolMagnetic::deactivate ()
+{
+ m_curve->endActionOptions();
+ m_actionOptions = NOOPTIONS;
+ m_dragging = false;
+ m_drawPivots = true;
+}
+
+void KisToolMagnetic::keyPress(TQKeyEvent *event)
+{
+ if (event->key() == TQt::Key_Control) {
+ draw(false);
+ if (m_editingMode) {
+ m_editingMode = false;
+ if (m_current != 0)
+ m_curve->selectPivot(m_current,false);
+ m_mode->setText(i18n("Automatic Mode"));
+ } else {
+ m_editingMode = true;
+ m_mode->setText(i18n("Manual Mode"));
+ }
+ draw(false);
+ } else if (event->key() == TQt::Key_Delete && m_curve->count()) {
+ draw(false);
+ m_dragging = false;
+ if (m_curve->pivots().count() == 2)
+ m_curve->clear();
+ else {
+ if ((*m_current) == m_curve->last() && !(m_editingMode)) {
+ m_curve->deletePivot(m_current.previousPivot());
+ m_previous = m_current.previousPivot();
+ } else {
+ m_editingMode = false;
+ m_curve->deletePivot(m_current);
+ m_previous = m_current = m_curve->selectPivot(m_curve->lastIterator());
+ m_editingMode = true;
+ }
+ }
+ draw(false);
+ } else
+ super::keyPress(event);
+}
+
+void KisToolMagnetic::buttonRelease(KisButtonReleaseEvent *event)
+{
+ if (m_editingMode) {
+ draw(m_current);
+ m_editingMode = false;
+ if (!m_curve->isEmpty())
+ m_curve->movePivot(m_current, m_currentPoint);
+ m_editingMode = true;
+ draw(m_current);
+ }
+ super::buttonRelease(event);
+}
+
+void KisToolMagnetic::buttonPress(KisButtonPressEvent *event)
+{
+ updateOptions(event->state());
+ if (!m_currentImage)
+ return;
+ if (event->button() == Qt::LeftButton) {
+ m_dragging = true;
+ m_currentPoint = event->pos();
+ PointPair temp(m_curve->end(),false);
+ if (m_editingMode)
+ temp = pointUnderMouse (m_subject->canvasController()->windowToView(event->pos().toTQPoint()));
+ if (temp.first == m_curve->end() && !(m_actionOptions)) {
+ if (m_editingMode) {
+ draw(true, true);
+ m_curve->selectAll(false);
+ draw(true, true);
+ }
+ draw(m_curve->end());
+ if (!m_curve->isEmpty()) {
+ m_previous = m_current;
+ m_current = m_curve->pushPivot(event->pos());
+ } else {
+ m_previous = m_current = m_curve->pushPivot(event->pos());
+ }
+ if (m_curve->pivots().count() > 1)
+ m_curve->calculateCurve(m_previous,m_current,m_current);
+ if (m_editingMode)
+ draw();
+ else {
+ if ((*m_previous).point() == (*m_current).point())
+ draw(m_curve->end());
+ else
+ draw();
+ }
+ } else if (temp.first != m_curve->end() && m_editingMode) {
+ if (temp.second) {
+ draw(true, true);
+ m_current = m_curve->selectPivot(temp.first);
+ draw(true, true);
+ } else {
+ draw(false);
+ m_current = selectByMouse(temp.first);
+ draw(false);
+ }
+ if (!(*m_current).isSelected())
+ m_dragging = false;
+ }
+ }
+}
+
+void KisToolMagnetic::move(KisMoveEvent *event)
+{
+ updateOptions(event->state());
+ if (m_currentPoint == event->pos().floorTQPoint())
+ return;
+ if (m_editingMode) {
+ PointPair temp = pointUnderMouse(m_subject->canvasController()->windowToView(event->pos().toTQPoint()));
+ if (temp.first == m_curve->end() && !m_dragging) {
+ if (m_editingCursor || m_draggingCursor) {
+ setCursor(KisCursor::load("tool_moutline_cursor.png", 6, 6));
+ m_editingCursor = m_draggingCursor = false;
+ }
+ } else {
+ if (!m_draggingCursor && temp.second) {
+ setCursor(KisCursor::load("tool_moutline_dragging.png", 6, 6));
+ m_editingCursor = false;
+ m_draggingCursor = true;
+ }
+ if (!m_editingCursor && !temp.second) {
+ setCursor(KisCursor::load("tool_moutline_editing.png", 6, 6));
+ m_editingCursor = true;
+ m_draggingCursor = false;
+ }
+ }
+ if (!m_dragging)
+ return;
+ } else {
+ if (m_editingCursor || m_draggingCursor) {
+ setCursor(KisCursor::load("tool_moutline_cursor.png", 6, 6));
+ m_editingCursor = m_draggingCursor = false;
+ }
+ }
+ if (m_curve->selectedPivots().isEmpty())
+ return;
+
+ KisPoint trans = event->pos() - m_currentPoint;
+ KisPoint dist;
+ dist = (*m_current).point() - (*m_current.previousPivot()).point();
+ if ((m_distance >= MINDIST && (fabs(dist.x()) + fabs(dist.y())) > m_distance && !(m_editingMode))
+ || m_curve->pivots().count() == 1) {
+ draw(m_curve->end());
+ m_previous = m_current;
+ m_current = m_curve->pushPivot(event->pos());
+ } else if ((*m_previous).point() == (*m_current).point() && (*m_previous).point() == m_curve->last().point())
+ draw(m_curve->end());
+ else
+ draw(m_current);
+ m_curve->movePivot(m_current,event->pos());
+ m_currentPoint = event->pos().floorTQPoint();
+ draw(m_current);
+}
+
+KisCurve::iterator KisToolMagnetic::selectByMouse(KisCurve::iterator it)
+{
+ KisCurve::iterator currPivot = m_curve->selectPivot(m_curve->addPivot(it, KisPoint(0,0)));
+ m_curve->movePivot(currPivot,(*it).point());
+
+ return currPivot;
+}
+
+void KisToolMagnetic::slotCommitCurve ()
+{
+ if (!m_curve->isEmpty())
+ commitCurve();
+}
+
+void KisToolMagnetic::slotSetDistance (int dist)
+{
+ m_distance = dist;
+}
+
+TQWidget* KisToolMagnetic::createOptionWidget(TQWidget* tqparent)
+{
+ m_optWidget = super::createOptionWidget(tqparent);
+ TQVBoxLayout * l = dynamic_cast<TQVBoxLayout*>(m_optWidget->tqlayout());
+ TQGridLayout *box = new TQGridLayout(l, 2, 2, 3);
+ box->setColStretch(0, 1);
+ box->setColStretch(1, 1);
+ Q_CHECK_PTR(box);
+
+ m_mode = new TQLabel(i18n("Automatic mode"), m_optWidget);
+ m_lbDistance = new TQLabel(i18n("Distance: "), m_optWidget);
+ TQPushButton *finish = new TQPushButton(i18n("To Selection"), m_optWidget);
+ m_slDistance = new TQSlider(MINDIST, MAXDIST, PAGESTEP, m_distance, Qt::Horizontal, m_optWidget);
+
+ connect(m_slDistance, TQT_SIGNAL(valueChanged(int)), this, TQT_SLOT(slotSetDistance(int)));
+ connect(finish, TQT_SIGNAL(clicked()), this, TQT_SLOT(slotCommitCurve()));
+
+ box->addWidget(m_lbDistance, 0, 0);
+ box->addWidget(m_slDistance, 0, 1);
+ box->addWidget(m_mode, 1, 0);
+ box->addWidget(finish, 1, 1);
+
+ return m_optWidget;
+}
+
+void KisToolMagnetic::setup(KActionCollection *collection)
+{
+ m_action = static_cast<KRadioAction *>(collection->action(name()));
+
+ if (m_action == 0) {
+ KShortcut shortcut(TQt::Key_Plus);
+ shortcut.append(KShortcut(TQt::Key_F9));
+ m_action = new KRadioAction(i18n("Magnetic Outline"),
+ "tool_moutline",
+ shortcut,
+ this,
+ TQT_SLOT(activate()),
+ collection,
+ name());
+ Q_CHECK_PTR(m_action);
+
+ m_action->setToolTip(i18n("Magnetic Selection: move around an edge to select it. Hit Ctrl to enter/quit manual mode, and double click to finish."));
+ m_action->setExclusiveGroup("tools");
+ m_ownAction = true;
+ }
+}
+
+#include "kis_tool_moutline.moc"
diff --git a/chalk/plugins/tools/tool_curves/kis_tool_moutline.h b/chalk/plugins/tools/tool_curves/kis_tool_moutline.h
new file mode 100644
index 00000000..ac7327fe
--- /dev/null
+++ b/chalk/plugins/tools/tool_curves/kis_tool_moutline.h
@@ -0,0 +1,132 @@
+/*
+ * kis_tool_moutline.h -- part of Chalk
+ *
+ * Copyright (c) 2006 Emanuele Tamponi <emanuele@valinor.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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef KIS_TOOL_MOUTLINE_H_
+#define KIS_TOOL_MOUTLINE_H_
+
+#include "kis_tool_factory.h"
+#include "kis_curve_framework.h"
+#include "kis_tool_curve.h"
+
+class TQSlider;
+class KisToolMagnetic;
+class KisVector2D;
+class Node;
+
+typedef TQValueVector<Node> NodeCol;
+typedef TQValueVector<NodeCol> NodeMatrix;
+typedef TQValueVector<TQ_INT16> GrayCol;
+typedef TQValueVector<GrayCol> GrayMatrix;
+
+class KisCurveMagnetic : public KisCurve {
+
+ typedef KisCurve super;
+
+ KisToolMagnetic *m_parent;
+
+ void reduceMatrix (TQRect&, GrayMatrix&, int, int, int, int);
+ void findEdge (int, int, const GrayMatrix&, Node&);
+ void detectEdges (const TQRect&, KisPaintDeviceSP, GrayMatrix&);
+
+ void gaussianBlur (const TQRect&, KisPaintDeviceSP, KisPaintDeviceSP);
+ void toGrayScale (const TQRect&, KisPaintDeviceSP, GrayMatrix&);
+ void getDeltas (const GrayMatrix&, GrayMatrix&, GrayMatrix&);
+ void getMagnitude (const GrayMatrix&, const GrayMatrix&, GrayMatrix&);
+ void nonMaxSupp (const GrayMatrix&, const GrayMatrix&, const GrayMatrix&, GrayMatrix&);
+
+public:
+
+ KisCurveMagnetic (KisToolMagnetic *tqparent);
+ ~KisCurveMagnetic ();
+
+ virtual KisCurve::iterator addPivot (iterator, const KisPoint&);
+ virtual KisCurve::iterator pushPivot (const KisPoint&);
+ virtual void calculateCurve (iterator, iterator, iterator);
+
+};
+
+class KisToolMagnetic : public KisToolCurve {
+
+ typedef KisToolCurve super;
+ Q_OBJECT
+ TQ_OBJECT
+
+ friend class KisCurveMagnetic;
+
+public:
+
+ KisToolMagnetic();
+ ~KisToolMagnetic();
+
+ virtual void update (KisCanvasSubject*);
+ virtual void setup (KActionCollection*);
+ virtual enumToolType toolType() { return TOOL_SELECT; }
+ virtual TQ_UINT32 priority() { return 9; }
+
+ virtual void keyPress(TQKeyEvent*);
+ virtual void buttonPress(KisButtonPressEvent*);
+ virtual void buttonRelease(KisButtonReleaseEvent*);
+ virtual void move(KisMoveEvent*);
+
+ virtual KisCurve::iterator selectByMouse(KisCurve::iterator it);
+
+ bool editingMode() {return m_editingMode;}
+ virtual TQWidget* createOptionWidget(TQWidget* tqparent);
+
+public slots:
+
+ virtual void activate ();
+ virtual void deactivate ();
+
+ void slotCommitCurve ();
+ void slotSetDistance (int);
+
+private:
+
+ KisCurveMagnetic *m_derived;
+ TQWidget* m_optWidget;
+ TQLabel* m_mode;
+ TQLabel* m_lbDistance;
+ TQSlider* m_slDistance;
+ bool m_editingMode;
+ bool m_editingCursor;
+ bool m_draggingCursor;
+ bool m_needNewPivot;
+
+ int m_distance;
+
+};
+
+class KisToolMagneticFactory : public KisToolFactory {
+ typedef KisToolFactory super;
+public:
+ KisToolMagneticFactory() : super() {};
+ virtual ~KisToolMagneticFactory(){};
+
+ virtual KisTool * createTool(KActionCollection * ac) {
+ KisTool * t = new KisToolMagnetic();
+ Q_CHECK_PTR(t);
+ t->setup(ac);
+ return t;
+ }
+ virtual KisID id() { return KisID("magneticoutline", i18n("Magnetic Outline Selection Tool")); }
+};
+
+#endif // KIS_TOOL_MOUTLINE_H_
diff --git a/chalk/plugins/tools/tool_curves/tool_bezier_cursor.png b/chalk/plugins/tools/tool_curves/tool_bezier_cursor.png
new file mode 100644
index 00000000..d25a4ab1
--- /dev/null
+++ b/chalk/plugins/tools/tool_curves/tool_bezier_cursor.png
Binary files differ
diff --git a/chalk/plugins/tools/tool_curves/tool_bezier_paint.png b/chalk/plugins/tools/tool_curves/tool_bezier_paint.png
new file mode 100644
index 00000000..290a1f02
--- /dev/null
+++ b/chalk/plugins/tools/tool_curves/tool_bezier_paint.png
Binary files differ
diff --git a/chalk/plugins/tools/tool_curves/tool_bezier_select.png b/chalk/plugins/tools/tool_curves/tool_bezier_select.png
new file mode 100644
index 00000000..106c47ff
--- /dev/null
+++ b/chalk/plugins/tools/tool_curves/tool_bezier_select.png
Binary files differ
diff --git a/chalk/plugins/tools/tool_curves/tool_curve_dragging.png b/chalk/plugins/tools/tool_curves/tool_curve_dragging.png
new file mode 100644
index 00000000..a7669ef1
--- /dev/null
+++ b/chalk/plugins/tools/tool_curves/tool_curve_dragging.png
Binary files differ
diff --git a/chalk/plugins/tools/tool_curves/tool_curves.cc b/chalk/plugins/tools/tool_curves/tool_curves.cc
new file mode 100644
index 00000000..f9f5be33
--- /dev/null
+++ b/chalk/plugins/tools/tool_curves/tool_curves.cc
@@ -0,0 +1,67 @@
+/*
+ * tool_bezier.cc -- part of Chalk
+ *
+ * Copyright (c) 2006 Emanuele Tamponi <emanuele@valinor.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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <stdlib.h>
+#include <vector>
+
+#include <tqpoint.h>
+
+#include <klocale.h>
+#include <kiconloader.h>
+#include <kinstance.h>
+#include <kmessagebox.h>
+#include <kstandarddirs.h>
+#include <kdebug.h>
+#include <kgenericfactory.h>
+
+#include <kis_global.h>
+#include <kis_types.h>
+#include <kis_tool_registry.h>
+
+#include "tool_curves.h"
+#include "kis_tool_bezier_paint.h"
+#include "kis_tool_bezier_select.h"
+#include "kis_tool_moutline.h"
+
+
+typedef KGenericFactory<ToolCurves> ToolCurvesFactory;
+K_EXPORT_COMPONENT_FACTORY( chalktoolcurves, ToolCurvesFactory( "chalk" ) )
+
+
+ToolCurves::ToolCurves(TQObject *tqparent, const char *name, const TQStringList &)
+ : KParts::Plugin(tqparent, name)
+{
+ setInstance(ToolCurvesFactory::instance());
+
+ if ( tqparent->inherits("KisToolRegistry") )
+ {
+ KisToolRegistry * r = dynamic_cast<KisToolRegistry*>( tqparent );
+ r->add(new KisToolBezierPaintFactory());
+ r->add(new KisToolBezierSelectFactory());
+ r->add(new KisToolMagneticFactory());
+ }
+
+}
+
+ToolCurves::~ToolCurves()
+{
+}
+
+#include "tool_curves.moc"
diff --git a/chalk/plugins/tools/tool_curves/tool_curves.h b/chalk/plugins/tools/tool_curves/tool_curves.h
new file mode 100644
index 00000000..82199e48
--- /dev/null
+++ b/chalk/plugins/tools/tool_curves/tool_curves.h
@@ -0,0 +1,36 @@
+/*
+ * tool_bezier.h -- part of Chalk
+ *
+ * Copyright (c) 2006 Emanuele Tamponi <emanuele@valinor.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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef TOOL_BEZIER_H_
+#define TOOL_BEZIER_H_
+
+#include <kparts/plugin.h>
+
+class ToolCurves : public KParts::Plugin
+{
+ Q_OBJECT
+ TQ_OBJECT
+public:
+ ToolCurves(TQObject *tqparent, const char *name, const TQStringList &);
+ virtual ~ToolCurves();
+
+};
+
+#endif // TOOL_BEZIER_H__
diff --git a/chalk/plugins/tools/tool_curves/tool_example.png b/chalk/plugins/tools/tool_curves/tool_example.png
new file mode 100644
index 00000000..893d2514
--- /dev/null
+++ b/chalk/plugins/tools/tool_curves/tool_example.png
Binary files differ
diff --git a/chalk/plugins/tools/tool_curves/tool_example_cursor.png b/chalk/plugins/tools/tool_curves/tool_example_cursor.png
new file mode 100644
index 00000000..d25a4ab1
--- /dev/null
+++ b/chalk/plugins/tools/tool_curves/tool_example_cursor.png
Binary files differ
diff --git a/chalk/plugins/tools/tool_curves/tool_moutline.png b/chalk/plugins/tools/tool_curves/tool_moutline.png
new file mode 100644
index 00000000..e2670292
--- /dev/null
+++ b/chalk/plugins/tools/tool_curves/tool_moutline.png
Binary files differ
diff --git a/chalk/plugins/tools/tool_curves/tool_moutline_cursor.png b/chalk/plugins/tools/tool_curves/tool_moutline_cursor.png
new file mode 100644
index 00000000..283a86d1
--- /dev/null
+++ b/chalk/plugins/tools/tool_curves/tool_moutline_cursor.png
Binary files differ
diff --git a/chalk/plugins/tools/tool_curves/tool_moutline_editing.png b/chalk/plugins/tools/tool_curves/tool_moutline_editing.png
new file mode 100644
index 00000000..3a308901
--- /dev/null
+++ b/chalk/plugins/tools/tool_curves/tool_moutline_editing.png
Binary files differ
diff --git a/chalk/plugins/tools/tool_curves/wdg_tool_example.ui b/chalk/plugins/tools/tool_curves/wdg_tool_example.ui
new file mode 100644
index 00000000..eac06e2b
--- /dev/null
+++ b/chalk/plugins/tools/tool_curves/wdg_tool_example.ui
@@ -0,0 +1,128 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>WdgToolExample</class>
+<widget class="TQWidget">
+ <property name="name">
+ <cstring>WdgToolExample</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>280</width>
+ <height>50</height>
+ </rect>
+ </property>
+ <property name="caption">
+ <string>Example</string>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <widget class="TQLayoutWidget">
+ <property name="name">
+ <cstring>tqlayout8</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="TQLabel">
+ <property name="name">
+ <cstring>textLabel1</cstring>
+ </property>
+ <property name="text">
+ <string>Vertices:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>isbX</cstring>
+ </property>
+ </widget>
+ <widget class="KIntSpinBox">
+ <property name="name">
+ <cstring>verticesSpinBox</cstring>
+ </property>
+ <property name="maxValue">
+ <number>100</number>
+ </property>
+ <property name="minValue">
+ <number>2</number>
+ </property>
+ <property name="value">
+ <number>5</number>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget class="TQLayoutWidget">
+ <property name="name">
+ <cstring>tqlayout7</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="TQLabel">
+ <property name="name">
+ <cstring>textLabel2</cstring>
+ </property>
+ <property name="text">
+ <string>Ratio:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>isbWidth</cstring>
+ </property>
+ </widget>
+ <widget class="KisIntSpinbox">
+ <property name="name">
+ <cstring>ratioSpinBox</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>0</hsizetype>
+ <vsizetype>5</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ </hbox>
+</widget>
+<tabstops>
+ <tabstop>verticesSpinBox</tabstop>
+ <tabstop>ratioSpinBox</tabstop>
+</tabstops>
+<customwidgets>
+<customwidget>
+ <class>KisIntSpinbox</class>
+ <header location="global">kis_int_spinbox.h</header>
+ <sizehint>
+ <width>-1</width>
+ <height>-1</height>
+ </sizehint>
+ <container>0</container>
+ <sizepolicy>
+ <hordata>5</hordata>
+ <verdata>5</verdata>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ <pixmap>image4</pixmap>
+</customwidget>
+</customwidgets>
+<images>
+ <image name="image4">
+ <data format="PNG" length="1002">89504e470d0a1a0a0000000d4948445200000016000000160806000000c4b46c3b000003b149444154388dad945f4c5b551cc73fe7dc4b7b4bcba0762d45c43114323599ee6192609c51d883892ce083f1718b3ebb185f8dc91e972cf39d2d2a2f1af664b6f1e0fe3863a0718969700eb0c52142da0242a1bd6d696f7bcff101585203ceb8fd9ece39f99dcff9fe7edf939f88c562ec465f5f9fe609442c161362173c3e3eae7b7a7ac8e7f36432196cdbfe4f907c3e4f2291201e8fe338cec3737357e9e8e828aded1e229d650e1f2d51754b082110124c13a4dc5ea341eb9dc284c0558a853f3ce8cb0677ef500fde7d39d2596679e326597b8e9abb85d7a770ab16ab6983ec5a05b487a70e36f0f4e10afe408d6a558310980108478dba4a1e8233990c5d474b64ed39aa3a8fe5f3317fbf81dbd70bccfeb205947632fd74f6589c1c6ea2f70d03a58ba0c1f2c9bdc1b66de3b8256a6e11cbe7e3ee1d181b590124fe2693aeee08d223c82c3a2c24b7b874bec8f26288774f7bd054504aef0dde6e99c0eb83f9fb266323cb80a27fb0958141836044605a2ee5523393371cc646fee2da37195aa35d0c0c5b4859ac03d7e91712dcaac5adab3650a3ff9d08ef7dd8404bb48869e5d958b5b87dadc4c9a1464e9f0d0326df7ebd86bd2e310cb1bf62d384d59441f2d70a070e1c60e09489929b988681bdd9cc97170bcc4c65595f71f8e0e3301337fc24a7732467831875a47f289652b0be5e4151e6d07316c1b0c0340d8ab92023e76d66a6b2840e36d2fb7a13fee632475e6edc367ea98a90fb98b7dd6310ca0328a44761582e1bab41befabcc0ec940d28bc5e93b68e064cab84e1d9beaeb48934eac1f53b01c1b000fca496aa54b61a99fcde61662a4b4b4b23d1680be9d426173e4df3602a48ea411989a4fd590f52a8fd156b05ed9d350e3defe3cfdf4b4c7ce770ea7d3fb9f520afbe1620daeee5c26735d20b9b9cfb6811a754a439e4e5c5639a4caa1e5caf586bfc0197b78702005cb9b4cae4cd3267ce8638fe964bd72b393e39d74928d242617303a756a37f284447770dcdbffc6384a05a85de1306e9a52057c7527c7131c3c42d3f475eb2303c82d4fc3276d6811db37efeb148723082d9b08f79f97c1e5729109a9a28307cc622d2d6cdf52b2b24efe548dedb00142009862cfa879ee1a71f6cec928353511472fbf4389148b0b0e0c108081412458dfe21c9f11351e67e7358595468246d1d1e5e38a6e9e851bc39d84ab502a669331dafec0d8ec7e3e8cb06e1a881d727d1ae40180a434a8c9db129a54126ad48a7358c2b4c5352c8c374bcccdab2bb37d8719cba79fab8211f9df218e0582c261e95f8bfc04f1a1e8bc5c4dfe0a190172af6a9690000000049454e44ae426082</data>
+ </image>
+</images>
+<tqlayoutdefaults spacing="6" margin="11"/>
+<includehints>
+ <includehint>knuminput.h</includehint>
+ <includehint>knuminput.h</includehint>
+</includehints>
+</UI>
diff --git a/chalk/plugins/tools/tool_filter/Makefile.am b/chalk/plugins/tools/tool_filter/Makefile.am
new file mode 100644
index 00000000..e1f6d5b4
--- /dev/null
+++ b/chalk/plugins/tools/tool_filter/Makefile.am
@@ -0,0 +1,38 @@
+kde_services_DATA = chalktoolfilter.desktop
+
+# all_includes must remain last!
+INCLUDES = -I$(srcdir)/../../../sdk \
+ -I$(srcdir)/../../../core \
+ -I$(srcdir)/../../../chalkcolor/ \
+ -I$(srcdir)/../../../ui \
+ -I$/../../../ui \
+ $(KOFFICE_INCLUDES) \
+ $(all_includes)
+
+chalktoolfilter_la_SOURCES = \
+ kis_filterop.cc \
+ kis_tool_filter.cc \
+ tool_filter.cc
+
+# Install this plugin in the KDE modules directory
+kde_module_LTLIBRARIES = chalktoolfilter.la
+
+noinst_HEADERS = \
+ kis_filterop.h \
+ kis_tool_filter.h \
+ tool_filter.h
+
+chalktoolfilter_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) $(LIB_QT) -lkdecore -lkdeui -lkjs -lkdefx -lkio -lkparts -L../../../../chalk/chalkcolor/.libs -lchalkcolor -L../../../../chalk/core/.libs -lchalkimage \
+ -L../../../../chalk/ui/.libs -lchalkui
+chalktoolfilter_la_LIBADD = ../../../libchalkcommon.la
+
+chalktoolfilter_la_METASOURCES = AUTO
+
+KDE_OPTIONS = nofinal
+
+chalkpics_DATA = \
+ tool_filter.png \
+ tool_filter_cursor.png
+
+chalkpicsdir = $(kde_datadir)/chalk/pics
+
diff --git a/chalk/plugins/tools/tool_filter/chalktoolfilter.desktop b/chalk/plugins/tools/tool_filter/chalktoolfilter.desktop
new file mode 100644
index 00000000..d22b19df
--- /dev/null
+++ b/chalk/plugins/tools/tool_filter/chalktoolfilter.desktop
@@ -0,0 +1,92 @@
+[Desktop Entry]
+Name=Filter Tool
+Name[bg]=Инструмент за филтриране
+Name[br]=Ostil ar sil
+Name[ca]=Eina de filtre
+Name[cy]=Erfyn Hidlen
+Name[da]=Filterværktøj
+Name[de]=Filterwerkzeug
+Name[el]=Εργαλείο φίλτρου
+Name[eo]=Filtrado-ilo
+Name[es]=Herramienta para filtrar
+Name[et]=Filtritööriist
+Name[eu]=Iragazkia tresna
+Name[fa]=ابزار پالایه
+Name[fi]=Suodintyökalu
+Name[fr]=Outil filtre
+Name[fy]=Filter-ark
+Name[ga]=Uirlis Scagaire
+Name[gl]=Ferramenta de Filtraxe
+Name[he]=כלי סינון
+Name[hu]=Szűrő eszköz
+Name[is]=Síutól
+Name[it]=Strumento di filtro
+Name[ja]=フィルタツール
+Name[km]=ឧបករណ៍​ត្រង
+Name[lv]=Filtru rīki
+Name[ms]=Alat Penapis
+Name[nb]=Filterverktøy
+Name[nds]=Filterwarktüüch
+Name[ne]=फिल्टर उपकरण
+Name[nl]=Filtergereedschap
+Name[nn]=Filterverktøy
+Name[pl]=Narzędzie filtru
+Name[pt]=Ferramenta de Filtragem
+Name[pt_BR]=Ferramenta de Filtragem
+Name[ru]=Фильтр
+Name[se]=Sillenreaidu
+Name[sk]=Filter
+Name[sl]=Orodje za filtriranje
+Name[sr]=Филтерски алат
+Name[sr@Latn]=Filterski alat
+Name[sv]=Filtreringsverktyg
+Name[uk]=Засіб фільтрування
+Name[uz]=Filter vositasi
+Name[uz@cyrillic]=Филтер воситаси
+Name[zh_CN]=过滤工具
+Name[zh_TW]=濾鏡工具
+Comment=Filter tool and paint operation
+Comment[bg]=Инструмент за филтриране и рисуване
+Comment[ca]=Operació d'eina de filtre i pintura
+Comment[cy]=Erfyn hidlen a gweithrediadau paent
+Comment[da]=Filterværktøj og maleoperation
+Comment[de]=Filterwerkzeug und Maloperation
+Comment[el]=Εργαλείο φίλτρου και λειτουργία ζωγραφικής
+Comment[eo]=Escepto ĉe kalkulado kun realaj nombroj.
+Comment[es]=Herramienta de filtrado y operaciones de pintado
+Comment[et]=Filtritööriist ja joonistamistoiming
+Comment[eu]=Iragazkia tresna eta margotze-eragiketa
+Comment[fa]=ابزار پالایه و عمل رنگ‌آمیزی
+Comment[fi]=Suodintyökalu ja väritystoimepinde
+Comment[fr]=Outil de filtrage et opération de dessin
+Comment[fy]=Filter-ark en skildersaksje
+Comment[gl]=Ferramenta de filtraxe e operación de pintura
+Comment[he]=כלי סינון ופעולת ציור
+Comment[hu]=Szűrő eszköz és festési művelet
+Comment[is]=Síutól og málunaraðgerðir
+Comment[it]=Strumento di filtro e operazione di disegno
+Comment[ja]=フィルタツールと画像操作
+Comment[km]=ដំណើរ​ការ​គូរ និង​ឧបករណ៍​តម្រង
+Comment[ms]=Alat penapis dan operasi warna
+Comment[nb]=Filterverktøy og maleteknikker
+Comment[nds]=Filterwarktüüch un Malen
+Comment[ne]=फिल्टर उपकरण र पेन्ट अपरेसन
+Comment[nl]=Filtergereedschap en schilderoperatie
+Comment[nn]=Filterverktøy og måleoperasjon
+Comment[pl]=Narzędzie filtrat oraz operacje malowania
+Comment[pt]=Ferramenta de filtragem e operação de pintura
+Comment[pt_BR]=Ferramenta de filtragem e operação de pintura
+Comment[ru]=Фильтр обработки изображения
+Comment[se]=Sillenreaidu ja málendoaibma
+Comment[sk]=Nástroj filter a operácie kreslenia
+Comment[sl]=Orodje za filtriranje in operacije za slikanje
+Comment[sr]=Филтерски алат и операција цртања
+Comment[sr@Latn]=Filterski alat i operacija crtanja
+Comment[sv]=Filtreringsverktyg och målningsåtgärd
+Comment[uk]=Засіб фільтрування та дій малювання
+Comment[zh_CN]=过滤器工具和绘图集成
+Comment[zh_TW]=濾鏡工具與繪圖操作
+ServiceTypes=Chalk/Tool
+Type=Service
+X-KDE-Library=chalktoolfilter
+X-Chalk-Version=2
diff --git a/chalk/plugins/tools/tool_filter/kis_filterop.cc b/chalk/plugins/tools/tool_filter/kis_filterop.cc
new file mode 100644
index 00000000..1f2200b3
--- /dev/null
+++ b/chalk/plugins/tools/tool_filter/kis_filterop.cc
@@ -0,0 +1,154 @@
+/*
+ * Copyright (c) 2002 Patrick Julien <freak@codepimps.org>
+ * Copyright (c) 2004 Boudewijn Rempt <boud@valdyas.org>
+ * Copyright (c) 2004 Clarence Dang <dang@kde.org>
+ * Copyright (c) 2004 Adrian Page <adrian@pagenet.plus.com>
+ * Copyright (c) 2004 Cyrille Berger <cberger@cberger.net>
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <tqrect.h>
+
+#include <kdebug.h>
+
+#include "kis_brush.h"
+#include "kis_global.h"
+#include "kis_paint_device.h"
+#include "kis_painter.h"
+#include "kis_types.h"
+#include "kis_iterators_pixel.h"
+#include "kis_paintop.h"
+#include "kis_colorspace.h"
+#include "kis_selection.h"
+#include "kis_filterop.h"
+
+
+KisPaintOp * KisFilterOpFactory::createOp(const KisPaintOpSettings */*settings*/, KisPainter * painter)
+{
+ KisPaintOp * op = new KisFilterOp(painter);
+ return op;
+}
+
+
+KisFilterOp::KisFilterOp(KisPainter * painter)
+ : super(painter)
+{
+ m_filterConfiguration = 0;
+}
+
+KisFilterOp::~KisFilterOp()
+{
+ delete m_filterConfiguration;
+}
+
+void KisFilterOp::paintAt(const KisPoint &pos, const KisPaintInformation& info)
+{
+ if (!m_painter) return;
+
+ KisFilterSP filter = m_painter->filter();
+ if (!filter) return;
+
+ if ( ! m_source ) return;
+
+ KisBrush * brush = m_painter->brush();
+ if (!brush) return;
+
+ KisColorSpace * colorSpace = m_source->colorSpace();
+
+ KisPoint hotSpot = brush->hotSpot(info);
+ KisPoint pt = pos - hotSpot;
+
+ // Split the coordinates into integer plus fractional parts. The integer
+ // is where the dab will be positioned and the fractional part determines
+ // the sub-pixel positioning.
+ TQ_INT32 x;
+ double xFraction;
+ TQ_INT32 y;
+ double yFraction;
+
+ splitCoordinate(pt.x(), &x, &xFraction);
+ splitCoordinate(pt.y(), &y, &yFraction);
+
+ // Filters always work with a tqmask, never with an image; that
+ // wouldn't be useful at all.
+ KisAlphaMaskSP tqmask = brush->tqmask(info, xFraction, yFraction);
+
+ m_painter->setPressure(info.pressure);
+
+ TQ_INT32 tqmaskWidth = tqmask->width();
+ TQ_INT32 tqmaskHeight = tqmask->height();
+
+ // Create a temporary paint device
+ KisPaintDeviceSP tmpDev = new KisPaintDevice(colorSpace, "filterop tmpdev");
+ Q_CHECK_PTR(tmpDev);
+
+ // Copy the layer data onto the new paint device
+
+ KisPainter p( tmpDev );
+ p.bitBlt( 0, 0, COMPOSITE_COPY, m_source, OPACITY_OPAQUE, x, y, tqmaskWidth, tqmaskHeight );
+
+ // Filter the paint device
+ filter->disableProgress();
+ filter->process( tmpDev, tmpDev, m_filterConfiguration, TQRect( 0, 0, tqmaskWidth, tqmaskHeight ));
+ filter->enableProgress();
+
+ // Apply the tqmask on the paint device (filter before tqmask because edge pixels may be important)
+ for (int y = 0; y < tqmaskHeight; y++)
+ {
+ KisHLineIterator hiter = tmpDev->createHLineIterator(0, y, tqmaskWidth, false);
+ int x=0;
+ while(! hiter.isDone())
+ {
+ TQ_UINT8 alpha = tqmask->alphaAt( x++, y );
+ colorSpace->setAlpha(hiter.rawData(), alpha, 1);
+
+ ++hiter;
+ }
+ }
+
+ // Blit the paint device onto the layer
+ TQRect dabRect = TQRect(0, 0, tqmaskWidth, tqmaskHeight);
+ TQRect dstRect = TQRect(x, y, dabRect.width(), dabRect.height());
+
+ KisImage * image = m_painter->device()->image();
+
+ if (image != 0) {
+ dstRect &= image->bounds();
+ }
+
+ if (dstRect.isNull() || dstRect.isEmpty() || !dstRect.isValid()) return;
+
+ TQ_INT32 sx = dstRect.x() - x;
+ TQ_INT32 sy = dstRect.y() - y;
+ TQ_INT32 sw = dstRect.width();
+ TQ_INT32 sh = dstRect.height();
+
+ if (m_source->hasSelection()) {
+ m_painter->bltSelection(dstRect.x(), dstRect.y(), m_painter->compositeOp(), tmpDev.data(),
+ m_source->selection(), m_painter->opacity(), sx, sy, sw, sh);
+ }
+ else {
+ m_painter->bitBlt(dstRect.x(), dstRect.y(), m_painter->compositeOp(), tmpDev.data(), m_painter->opacity(), sx, sy, sw, sh);
+ }
+
+ m_painter->addDirtyRect(dstRect);
+}
+
+void KisFilterOp::setFilterConfiguration(KisFilterConfiguration* filterConfiguration)
+{
+ delete m_filterConfiguration;
+ m_filterConfiguration = filterConfiguration;
+}
diff --git a/chalk/plugins/tools/tool_filter/kis_filterop.h b/chalk/plugins/tools/tool_filter/kis_filterop.h
new file mode 100644
index 00000000..06703b34
--- /dev/null
+++ b/chalk/plugins/tools/tool_filter/kis_filterop.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2002 Patrick Julien <freak@codepimps.org>
+ * Copyright (c) 2004 Boudewijn Rempt <boud@valdyas.org>
+ * Copyright (c) 2004 Clarence Dang <dang@kde.org>
+ * Copyright (c) 2004 Adrian Page <adrian@pagenet.plus.com>
+ * Copyright (c) 2004 Cyrille Berger <cberger@cberger.net>
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef KIS_FILTEROP_H_
+#define KIS_FILTEROP_H_
+
+#include "kis_paintop.h"
+#include <koffice_export.h>
+
+class KisPoint;
+class KisPainter;
+class KisFilterConfiguration;
+
+class KisFilterOpFactory : public KisPaintOpFactory {
+
+public:
+ KisFilterOpFactory() {}
+ virtual ~KisFilterOpFactory() {}
+
+ virtual KisPaintOp * createOp(const KisPaintOpSettings *settings, KisPainter * painter);
+ virtual KisID id() { return KisID(("filter"), i18n("Filter")); }
+ virtual bool userVisible(KisColorSpace * = 0) { return false; }
+};
+
+
+
+class KRITAPAINT_EXPORT KisFilterOp : public KisPaintOp {
+
+ typedef KisPaintOp super;
+
+public:
+
+ KisFilterOp(KisPainter * painter);
+ virtual ~KisFilterOp();
+
+ void paintAt(const KisPoint &pos, const KisPaintInformation& info);
+public:
+ void setFilterConfiguration(KisFilterConfiguration*);
+private:
+ KisFilterConfiguration* m_filterConfiguration;
+};
+
+
+#endif // KIS_FILTEROP_H_
diff --git a/chalk/plugins/tools/tool_filter/kis_tool_filter.cc b/chalk/plugins/tools/tool_filter/kis_tool_filter.cc
new file mode 100644
index 00000000..e9fdad9e
--- /dev/null
+++ b/chalk/plugins/tools/tool_filter/kis_tool_filter.cc
@@ -0,0 +1,154 @@
+/*
+ * kis_tool_filter.cc - part of Chalk
+ *
+ * Copyright (c) 2004 Cyrille Berger <cberger@cberger.net>
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <tqbitmap.h>
+#include <tqpainter.h>
+#include <tqcombobox.h>
+#include <tqlayout.h>
+#include <tqlabel.h>
+
+#include <kaction.h>
+#include <kdebug.h>
+#include <klocale.h>
+
+#include "kis_filter_config_widget.h"
+#include "kis_tool_filter.h"
+#include <kis_brush.h>
+#include <kis_button_press_event.h>
+#include <kis_button_release_event.h>
+#include <kis_canvas_subject.h>
+#include <kis_cmb_idlist.h>
+#include <kis_cursor.h>
+#include <kis_doc.h>
+#include <kis_filter.h>
+#include <kis_filterop.h>
+#include <kis_id.h>
+#include <kis_image.h>
+#include <kis_layer.h>
+#include <kis_move_event.h>
+#include <kis_painter.h>
+#include <kis_paintop.h>
+#include <kis_paintop_registry.h>
+#include <kis_vec.h>
+
+KisToolFilter::KisToolFilter()
+ : super(i18n("Filter Brush")), m_filterConfigurationWidget(0)
+{
+ setName("tool_filter");
+ m_subject = 0;
+ setCursor(KisCursor::load("tool_filter_cursor.png", 5, 5));
+}
+
+KisToolFilter::~KisToolFilter()
+{
+}
+
+void KisToolFilter::setup(KActionCollection *collection)
+{
+ m_action = static_cast<KRadioAction *>(collection->action(name()));
+
+ if (m_action == 0) {
+ m_action = new KRadioAction(i18n("&Filter Brush"),
+ "tool_filter", 0, this,
+ TQT_SLOT(activate()), collection,
+ name());
+ Q_CHECK_PTR(m_action);
+ m_action->setToolTip(i18n("Paint with filters"));
+ m_action->setExclusiveGroup("tools");
+ m_ownAction = true;
+ }
+}
+
+void KisToolFilter::initPaint(KisEvent *e)
+{
+ // Some filters want to paint directly on the current state of
+ // the canvas, others cannot handle that and need a temporary layer
+ // so they can work on the old data before painting started.
+ m_paintIncremental = m_filter->supportsIncrementalPainting();
+
+ super::initPaint(e);
+ KisPaintOp * op = KisPaintOpRegistry::instance()->paintOp("filter", 0, painter());
+ op->setSource ( m_source );
+ painter()->setPaintOp(op); // And now the painter owns the op and will destroy it.
+ painter()->setFilter( m_filter );
+
+ // XXX: Isn't there a better way to set the config? The filter config widget needs to
+ // to go into the tool options widget, and just the data carried over to the filter.
+ // I've got a bit of a problem with core classes having too much GUI about them.
+ // BSAR.
+ dynamic_cast<KisFilterOp *>(op)->setFilterConfiguration( m_filter->configuration( m_filterConfigurationWidget) );
+}
+
+TQWidget* KisToolFilter::createOptionWidget(TQWidget* tqparent)
+{
+ TQWidget *widget = super::createOptionWidget(tqparent);
+
+ m_cbFilter = new KisCmbIDList(widget);
+ Q_CHECK_PTR(m_cbFilter);
+
+ TQLabel* lbFilter = new TQLabel(i18n("Filter:"), widget);
+ Q_CHECK_PTR(lbFilter);
+
+ // Check which filters support painting
+ KisIDList l = KisFilterRegistry::instance()->listKeys();
+ KisIDList l2;
+ KisIDList::iterator it;
+ for (it = l.begin(); it != l.end(); ++it) {
+ KisFilterSP f = KisFilterRegistry::instance()->get(*it);
+ if (f->supportsPainting()) {
+ l2.push_back(*it);
+ }
+ }
+ m_cbFilter ->setIDList( l2 );
+
+ addOptionWidgetOption(m_cbFilter, lbFilter);
+
+ m_optionLayout = new TQGridLayout(widget, 1, 1, 0, 6);
+ Q_CHECK_PTR(m_optionLayout);
+ super::addOptionWidgetLayout(m_optionLayout);
+
+ connect(m_cbFilter, TQT_SIGNAL(activated ( const KisID& )), this, TQT_SLOT( changeFilter( const KisID& ) ) );
+ changeFilter( m_cbFilter->currentItem () );
+
+ return widget;
+}
+
+void KisToolFilter::changeFilter( const KisID & id)
+{
+ m_filter = KisFilterRegistry::instance()->get( id );
+ Q_ASSERT(m_filter != 0);
+ if( m_filterConfigurationWidget != 0 )
+ {
+ m_optionLayout->remove ( m_filterConfigurationWidget );
+ delete m_filterConfigurationWidget;
+ }
+
+ m_source = m_currentImage->activeDevice();
+ if (!m_source) return;
+
+ m_filterConfigurationWidget = m_filter->createConfigurationWidget( optionWidget(), m_source );
+ if( m_filterConfigurationWidget != 0 )
+ {
+ m_optionLayout->addMultiCellWidget ( m_filterConfigurationWidget, 2, 2, 0, 1 );
+ m_filterConfigurationWidget->show();
+ }
+}
+
+#include "kis_tool_filter.moc"
diff --git a/chalk/plugins/tools/tool_filter/kis_tool_filter.h b/chalk/plugins/tools/tool_filter/kis_tool_filter.h
new file mode 100644
index 00000000..e8b5e86b
--- /dev/null
+++ b/chalk/plugins/tools/tool_filter/kis_tool_filter.h
@@ -0,0 +1,81 @@
+/*
+ * kis_tool_filter.h - part of Chalk
+ *
+ * Copyright (c) 2004 Cyrille Berger <cberger@cberger.net>
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __KIS_TOOL_FILTER_H__
+#define __KIS_TOOL_FILTER_H__
+
+#include "kis_tool_freehand.h"
+#include "kis_tool_factory.h"
+
+class TQComboBox;
+class TQGridLayout;
+class KisEvent;
+class KisFilterConfigurationWidget;
+class KisButtonPressEvent;
+class KisView;
+class KisID;
+class KisCmbIDList;
+
+
+class KisToolFilter : public KisToolFreehand {
+ Q_OBJECT
+ TQ_OBJECT
+ typedef KisToolFreehand super;
+
+public:
+ KisToolFilter();
+ virtual ~KisToolFilter();
+
+ virtual void setup(KActionCollection *collection);
+ virtual enumToolType toolType() { return TOOL_FREEHAND; }
+ virtual TQ_UINT32 priority() { return 1; }
+ virtual TQWidget* createOptionWidget(TQWidget* tqparent);
+
+public slots:
+ void changeFilter( const KisID & filter);
+
+protected:
+ virtual void initPaint(KisEvent *e);
+
+private:
+ KisFilterSP m_filter;
+ TQWidget* m_filterConfigurationWidget;
+ TQGridLayout* m_optionLayout;
+ KisCmbIDList * m_cbFilter;
+};
+
+
+class KisToolFilterFactory : public KisToolFactory {
+ typedef KisToolFactory super;
+public:
+ KisToolFilterFactory() : super() {};
+ virtual ~KisToolFilterFactory(){};
+
+ virtual KisTool * createTool(KActionCollection * ac) {
+ KisTool * t = new KisToolFilter();
+ Q_CHECK_PTR(t);
+ t->setup(ac);
+ return t;
+ }
+ virtual KisID id() { return KisID("filter", i18n("Filter Tool")); }
+};
+
+#endif //__KIS_TOOL_FILTER_H__
+
diff --git a/chalk/plugins/tools/tool_filter/tool_filter.cc b/chalk/plugins/tools/tool_filter/tool_filter.cc
new file mode 100644
index 00000000..484ed39a
--- /dev/null
+++ b/chalk/plugins/tools/tool_filter/tool_filter.cc
@@ -0,0 +1,68 @@
+/*
+ * tool_filter.cc -- Part of Chalk
+ *
+ * Copyright (c) 2004 Boudewijn Rempt (boud@valdyas.org)
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+#include <stdlib.h>
+#include <vector>
+
+#include <tqpoint.h>
+
+#include <klocale.h>
+#include <kiconloader.h>
+#include <kinstance.h>
+#include <kmessagebox.h>
+#include <kstandarddirs.h>
+#include <kdebug.h>
+#include <kgenericfactory.h>
+
+#include <kis_debug_areas.h>
+#include <kis_types.h>
+#include <kis_tool_registry.h>
+#include <kis_paintop_registry.h>
+
+#include "tool_filter.h"
+#include "kis_filterop.h"
+#include "kis_tool_filter.h"
+
+
+typedef KGenericFactory<ToolFilter> ToolFilterFactory;
+K_EXPORT_COMPONENT_FACTORY( chalktoolfilter, ToolFilterFactory( "chalk" ) )
+
+
+ToolFilter::ToolFilter(TQObject *tqparent, const char *name, const TQStringList &)
+ : KParts::Plugin(tqparent, name)
+{
+ setInstance(ToolFilterFactory::instance());
+
+ if ( tqparent->inherits("KisToolRegistry") )
+ {
+ KisToolRegistry * r = dynamic_cast<KisToolRegistry*>(tqparent);
+ r->add( new KisToolFilterFactory());
+
+ // XXX: Put this in a separate plugin?
+ KisPaintOpRegistry * pr = KisPaintOpRegistry::instance();
+ pr->add( new KisFilterOpFactory );
+
+ }
+}
+
+ToolFilter::~ToolFilter()
+{
+}
+
+#include "tool_filter.moc"
diff --git a/chalk/plugins/tools/tool_filter/tool_filter.h b/chalk/plugins/tools/tool_filter/tool_filter.h
new file mode 100644
index 00000000..7bf33dca
--- /dev/null
+++ b/chalk/plugins/tools/tool_filter/tool_filter.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2004 Boudewijn Rempt (boud@valdyas.org)
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef TOOL_FILTER_H_
+#define TOOL_FILTER_H_
+
+#include <kparts/plugin.h>
+
+class KisView;
+
+/**
+ * A module that provides a filter tool.
+ */
+class ToolFilter : public KParts::Plugin
+{
+ Q_OBJECT
+ TQ_OBJECT
+public:
+ ToolFilter(TQObject *tqparent, const char *name, const TQStringList &);
+ virtual ~ToolFilter();
+
+private:
+
+ KisView * m_view;
+
+};
+
+#endif // TOOL_FILTER_H_
diff --git a/chalk/plugins/tools/tool_filter/tool_filter.png b/chalk/plugins/tools/tool_filter/tool_filter.png
new file mode 100644
index 00000000..6598d9fc
--- /dev/null
+++ b/chalk/plugins/tools/tool_filter/tool_filter.png
Binary files differ
diff --git a/chalk/plugins/tools/tool_filter/tool_filter.svg b/chalk/plugins/tools/tool_filter/tool_filter.svg
new file mode 100644
index 00000000..eb808919
--- /dev/null
+++ b/chalk/plugins/tools/tool_filter/tool_filter.svg
@@ -0,0 +1,468 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://web.resource.org/cc/"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://inkscape.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="/home/cyrille/koffice/chalk/plugins/tools/tool_filter/tool_filter.png"
+ sodipodi:docname="tool_filter.svg"
+ sodipodi:docbase="/home/cyrille/src/koffice-svn/koffice/chalk/plugins/tools/tool_filter"
+ inkscape:version="0.43"
+ sodipodi:version="0.32"
+ id="svg1409"
+ height="22"
+ width="22"
+ version="1.0">
+ <defs
+ id="defs3">
+ <linearGradient
+ id="linearGradient3264">
+ <stop
+ style="stop-color:#787878;stop-opacity:1;"
+ offset="0"
+ id="stop3266" />
+ <stop
+ style="stop-color:#a0a0a0;stop-opacity:1;"
+ offset="1"
+ id="stop3268" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient3256">
+ <stop
+ style="stop-color:#969696;stop-opacity:1;"
+ offset="0"
+ id="stop3258" />
+ <stop
+ style="stop-color:#969696;stop-opacity:0;"
+ offset="1"
+ id="stop3260" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3208">
+ <stop
+ style="stop-color:#313436;stop-opacity:1;"
+ offset="0"
+ id="stop3210" />
+ <stop
+ id="stop3216"
+ offset="0.76999998"
+ style="stop-color:#373a3c;stop-opacity:1;" />
+ <stop
+ style="stop-color:#313436;stop-opacity:1;"
+ offset="1"
+ id="stop3212" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3136">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.23958333;"
+ offset="0"
+ id="stop3138" />
+ <stop
+ style="stop-color:#ff0909;stop-opacity:0;"
+ offset="1"
+ id="stop3140" />
+ </linearGradient>
+ <radialGradient
+ r="31.677956"
+ fy="46.914463"
+ fx="48.488476"
+ cy="46.914463"
+ cx="48.488476"
+ gradientTransform="matrix(1.261963,0,0,1.01636,-7.978266,-0.517425)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient1333"
+ xlink:href="#light90to0"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="36.873619"
+ x2="39.857029"
+ y1="4.5492039"
+ x1="10.878086"
+ gradientTransform="matrix(1.32525,0,0,1.003779,-5.702957,1.287849)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1331"
+ xlink:href="#light90to0"
+ inkscape:collect="always" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#light90to0"
+ id="linearGradient9512"
+ gradientTransform="matrix(1.32525,0,0,1.003779,-5.702957,1.287849)"
+ x1="10.878086"
+ y1="4.5492039"
+ x2="39.857029"
+ y2="36.873619"
+ gradientUnits="userSpaceOnUse" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#light90to0"
+ id="radialGradient10280"
+ gradientTransform="matrix(1.261963,0,0,1.01636,-7.978266,-0.517425)"
+ cx="48.488476"
+ cy="46.914463"
+ fx="48.488476"
+ fy="46.914463"
+ r="31.677956"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ id="light90to0">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.90833336;"
+ offset="0.0000000"
+ id="stop1890" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.0000000;"
+ offset="1.0000000"
+ id="stop1892" />
+ </linearGradient>
+ <radialGradient
+ r="31.677956"
+ fy="46.914463"
+ fx="48.488476"
+ cy="46.914463"
+ cx="48.488476"
+ gradientTransform="matrix(1.181248,0,0,0.943878,-80.46799,5.3461)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient2086"
+ xlink:href="#light90to0"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="36.873619"
+ x2="39.857029"
+ y1="4.5492039"
+ x1="10.878086"
+ gradientTransform="matrix(1.240487,0,0,0.932195,-78.33821,7.022631)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient2089"
+ xlink:href="#light90to0"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="36.873619"
+ x2="39.857029"
+ y1="4.5492039"
+ x1="10.878086"
+ gradientTransform="matrix(1.240487,0,0,0.932195,-78.33821,7.022631)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient3732"
+ xlink:href="#light90to0"
+ inkscape:collect="always" />
+ <radialGradient
+ r="31.677956"
+ fy="46.914463"
+ fx="48.488476"
+ cy="46.914463"
+ cx="48.488476"
+ gradientTransform="matrix(1.181248,0,0,0.943878,-80.46799,5.3461)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient3734"
+ xlink:href="#light90to0"
+ inkscape:collect="always" />
+ <radialGradient
+ r="31.677956"
+ fy="46.914463"
+ fx="48.488476"
+ cy="46.914463"
+ cx="48.488476"
+ gradientTransform="matrix(1.47229,0,0,1.176435,-85.47464,-0.281735)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient3737"
+ xlink:href="#light90to0"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="36.873619"
+ x2="39.857029"
+ y1="4.5492039"
+ x1="10.878086"
+ gradientTransform="matrix(1.546124,0,0,1.161874,-42.82011,1.807868)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient3740"
+ xlink:href="#light90to0"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="36.873619"
+ x2="39.857029"
+ y1="4.5492039"
+ x1="10.878086"
+ gradientTransform="matrix(1.546124,0,0,1.161874,-82.82011,1.807868)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient3748"
+ xlink:href="#light90to0"
+ inkscape:collect="always" />
+ <radialGradient
+ r="31.677956"
+ fy="46.914463"
+ fx="48.488476"
+ cy="46.914463"
+ cx="48.488476"
+ gradientTransform="matrix(1.181248,0,0,0.943878,-86.67547,5.3461)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient3888"
+ xlink:href="#light90to0"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="36.873619"
+ x2="39.857029"
+ y1="4.5492039"
+ x1="10.878086"
+ gradientTransform="matrix(1.240487,0,0,0.932195,-84.54569,7.022631)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient3891"
+ xlink:href="#light90to0"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="36.873619"
+ x2="39.857029"
+ y1="4.5492039"
+ x1="10.878086"
+ gradientTransform="matrix(1.240487,0,0,0.932195,-84.54569,7.022631)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient3899"
+ xlink:href="#light90to0"
+ inkscape:collect="always" />
+ <radialGradient
+ r="31.677956"
+ fy="46.914463"
+ fx="48.488476"
+ cy="46.914463"
+ cx="48.488476"
+ gradientTransform="matrix(1.181248,0,0,0.943878,-86.67547,5.3461)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient3901"
+ xlink:href="#light90to0"
+ inkscape:collect="always" />
+ <radialGradient
+ r="31.677956"
+ fy="46.914463"
+ fx="48.488476"
+ cy="46.914463"
+ cx="48.488476"
+ gradientTransform="matrix(1.842551,0,0,1.472293,-26.91085,-7.897181)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient3904"
+ xlink:href="#light90to0"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="36.873619"
+ x2="39.857029"
+ y1="4.5492039"
+ x1="10.878086"
+ gradientTransform="matrix(1.934954,0,0,1.454069,-43.58874,-5.282071)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient3907"
+ xlink:href="#light90to0"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="36.873619"
+ x2="39.857029"
+ y1="4.5492039"
+ x1="10.878086"
+ gradientTransform="matrix(1.934954,0,0,1.454069,-23.58874,-5.282071)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient3917"
+ xlink:href="#light90to0"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="36.873619"
+ x2="39.857029"
+ y1="4.5492039"
+ x1="10.878086"
+ gradientTransform="matrix(1.934954,0,0,1.454069,-23.58874,-5.282071)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient3939"
+ xlink:href="#light90to0"
+ inkscape:collect="always" />
+ <radialGradient
+ r="31.677956"
+ fy="46.914463"
+ fx="48.488476"
+ cy="46.914463"
+ cx="48.488476"
+ gradientTransform="matrix(1.842551,0,0,1.472293,-26.91085,-7.897181)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient3941"
+ xlink:href="#light90to0"
+ inkscape:collect="always" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#light90to0"
+ id="radialGradient3103"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.843411,0,0,1.546427,-39.13262,-18.20529)"
+ cx="48.488476"
+ cy="46.914463"
+ fx="48.488476"
+ fy="46.914463"
+ r="31.677956" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#light90to0"
+ id="linearGradient3106"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.935858,0,0,1.527286,-33.53707,-3.676156)"
+ x1="10.878086"
+ y1="4.5492039"
+ x2="39.857029"
+ y2="36.873619" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3136"
+ id="radialGradient3142"
+ cx="25.014776"
+ cy="24.372894"
+ fx="25.014776"
+ fy="24.372894"
+ r="8.1216803"
+ gradientTransform="matrix(1,0,0,0.92,0,1.94983)"
+ gradientUnits="userSpaceOnUse" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3136"
+ id="radialGradient3198"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.92,0,1.94983)"
+ cx="25.014776"
+ cy="24.372894"
+ fx="25.014776"
+ fy="24.372894"
+ r="8.1216803" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3256"
+ id="linearGradient3262"
+ x1="42.718361"
+ y1="28.488203"
+ x2="57.968361"
+ y2="28.488203"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.379522,0,0,0.379522,-3.932923e-16,-3.72157e-3)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3264"
+ id="linearGradient3270"
+ x1="2.2501231"
+ y1="12.139999"
+ x2="21.997738"
+ y2="12.139999"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(2.262e-3,-9.301e-3)" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3136"
+ id="radialGradient3292"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.92,0,1.94983)"
+ cx="25.014776"
+ cy="24.372894"
+ fx="25.014776"
+ fy="24.372894"
+ r="8.1216803" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3256"
+ id="linearGradient3301"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.379522,0,0,0.379522,11.99971,7.621365)"
+ x1="42.718361"
+ y1="28.488203"
+ x2="57.968361"
+ y2="28.488203" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3136"
+ id="radialGradient3303"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.92,0,1.94983)"
+ cx="25.014776"
+ cy="24.372894"
+ fx="25.014776"
+ fy="24.372894"
+ r="8.1216803" />
+ </defs>
+ <sodipodi:namedview
+ inkscape:window-y="29"
+ inkscape:window-x="-6"
+ inkscape:window-height="865"
+ inkscape:window-width="1020"
+ inkscape:grid-bbox="true"
+ inkscape:document-units="px"
+ showgrid="true"
+ inkscape:current-layer="layer1"
+ inkscape:cy="10.948218"
+ inkscape:cx="11.00702"
+ inkscape:zoom="26.673274"
+ inkscape:pageshadow="2"
+ inkscape:pageopacity="0.0000000"
+ borderopacity="1.0"
+ bordercolor="#666666"
+ pagecolor="#ffffff"
+ id="base"
+ showguides="true"
+ inkscape:guide-bbox="true">
+ <sodipodi:guide
+ orientation="horizontal"
+ position="32.270144"
+ id="guide3123" />
+ <sodipodi:guide
+ orientation="vertical"
+ position="27.830292"
+ id="guide3125" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata4">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:groupmode="layer"
+ inkscape:label="Layer 1"
+ id="layer1">
+ <path
+ style="fill:#bebebe;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="M 2.870858,16.882359 C 5.0598873,15.626359 5.4905158,16.595273 5.4905158,16.595273 L 6.2441162,18.281903 L 5.3828589,19.322589"
+ id="path3151"
+ sodipodi:nodetypes="cccc" />
+ <path
+ style="opacity:1;fill:url(#linearGradient3270);fill-opacity:1;stroke:none;stroke-width:5.625;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.98913042"
+ d="M 11.685746,2.2635359 C 6.4415012,2.4956003 2.2523851,6.8307301 2.2523851,12.131768 C 2.2523851,17.581319 6.6821924,22 12.131768,22 C 17.581343,22 22,17.581319 22,12.131768 C 21.999999,6.6822174 17.581343,2.2635359 12.131768,2.2635359 C 12.004043,2.2635359 11.879202,2.2587206 11.752649,2.2635359 C 11.732052,2.2643196 11.706312,2.2626259 11.685746,2.2635359 z M 11.797252,5.2853334 C 11.840148,5.2829026 11.876807,5.2869734 11.919908,5.2853334 C 12.008177,5.281975 12.098433,5.2853334 12.187521,5.2853334 C 15.988577,5.2853334 19.067407,8.364162 19.067407,12.16522 C 19.067407,14.065748 17.766075,15.397225 16.521235,16.642064 C 15.276395,17.886904 14.088049,19.045106 12.187521,19.045106 C 8.386464,19.045106 5.2964839,15.966276 5.2964835,12.16522 C 5.2964835,8.49675 8.179632,5.4903078 11.797252,5.2853334 z "
+ id="path3149"
+ sodipodi:nodetypes="csssssccssssssc" />
+ <path
+ style="fill:#6e6e6e;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="M 4.6829485,14.913971 C 4.3986517,12.248484 4.1732961,10.502726 5.6607092,8.0399772 C 7.9623626,4.2290697 12.792842,4.2762827 15.037384,4.9281667 C 16.297373,5.2941059 13.8014,2.0801252 13.685675,1.8486741 C 13.555694,1.5887131 10.790175,0.65325747 10.315629,0.69792667 C 9.0556677,0.81652736 6.1065158,1.8817743 4.8906765,2.6295384 C 4.1184435,3.1044764 1.5558033,6.5046123 1.2740418,7.0681355 C 1.0820562,7.4521065 0.62128553,11.654096 0.82196244,12.65748 C 0.88790126,12.987174 4.7238226,15.297195 4.6829485,14.913971 z "
+ id="path3130"
+ sodipodi:nodetypes="cssssssss" />
+ <path
+ style="fill:#ff0909;fill-opacity:0.45405406;stroke:none;stroke-width:5.625;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.98913042"
+ d="M 11.28125,3.46875 C 7.0156744,3.8021114 3.65625,7.4758848 3.65625,11.9375 C 3.65625,15.448279 5.7527084,18.462078 8.71875,19.75 C 8.5411163,19.572282 8.2707985,19.260891 8.15625,19.0625 C 8.1432138,19.038406 8.132279,18.989549 8.125,18.96875 C 8.1239941,18.964034 8.1255755,18.941957 8.125,18.9375 C 8.1248707,18.933315 8.1246675,18.910152 8.125,18.90625 C 8.1263033,18.90295 8.1231878,18.877981 8.125,18.875 C 8.1336316,18.868079 8.173723,18.847371 8.1875,18.84375 C 8.1926954,18.842933 8.2129358,18.844164 8.21875,18.84375 C 8.2254977,18.84375 8.2430579,18.844063 8.25,18.84375 C 8.2713908,18.841902 8.3207757,18.848147 8.34375,18.84375 C 8.3672153,18.838563 8.412672,18.819877 8.4375,18.8125 C 8.8330113,18.686414 9.4034506,18.311913 9.78125,18.21875 C 9.8048993,18.213564 9.8528577,18.190227 9.875,18.1875 C 9.8894021,18.186268 9.9238535,18.1875 9.9375,18.1875 C 10.280065,18.173019 12.681854,17.727974 12.96875,17.65625 C 13.197391,17.567298 15.774962,15.915357 16.0625,15.6875 C 16.064368,15.685632 16.091055,15.659527 16.09375,15.65625 C 16.310468,15.368508 18.03202,12.498462 18.125,12.3125 C 18.227335,12.057307 18.750238,9.5088168 18.90625,9.1875 C 18.908686,9.1833497 18.935279,9.1590607 18.9375,9.15625 C 18.950344,9.15625 19.655829,9.2469227 19.75,9.25 C 19.740635,9.2297736 19.745791,9.1655723 19.71875,9.125 C 19.529461,8.8409941 18.943665,8.1429826 18.875,8 C 18.914573,7.9010676 18.989778,7.8045847 19.0625,7.71875 C 19.07058,7.7092128 19.054085,7.6967151 19.0625,7.6875 C 19.059155,7.681599 19.097109,7.662142 19.09375,7.65625 C 17.659524,5.1403638 14.981334,3.46875 11.9375,3.46875 C 11.723647,3.46875 11.491032,3.4523552 11.28125,3.46875 z "
+ id="path3115" />
+ <path
+ sodipodi:type="arc"
+ style="fill:url(#radialGradient3303);fill-opacity:1;stroke:none;stroke-width:5.625;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.98913042"
+ id="path3134"
+ sodipodi:cx="25.014776"
+ sodipodi:cy="24.372894"
+ sodipodi:rx="8.1216803"
+ sodipodi:ry="7.4719462"
+ d="M 33.136456 24.372894 A 8.1216803 7.4719462 0 1 1 16.893096,24.372894 A 8.1216803 7.4719462 0 1 1 33.136456 24.372894 z"
+ transform="matrix(0.607235,0,0,0.660038,-5.151071,-7.62158)" />
+ <path
+ style="opacity:1;fill:#4e4e4e;fill-opacity:1;stroke:none;stroke-width:5.625;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ d="M 9.433361,0.0021401333 C 4.189116,0.23420453 0,4.5693346 0,9.8703729 C 0,15.319923 4.429807,19.738605 9.879383,19.738605 C 15.328958,19.738605 19.747615,15.319923 19.747615,9.8703729 C 19.747614,4.4208218 15.328958,0.0021401333 9.879383,0.0021401333 C 9.751658,0.0021401333 9.626817,-0.0026751667 9.500264,0.0021401333 C 9.479667,0.0029239333 9.453927,0.0012301333 9.433361,0.0021401333 z M 9.544867,3.0239379 C 9.587763,3.0215073 9.624422,3.0255778 9.667523,3.0239379 C 9.755792,3.0205795 9.846048,3.0239379 9.935136,3.0239379 C 13.736192,3.0239379 16.815022,6.1027668 16.815022,9.9038239 C 16.815022,13.704881 13.736192,16.783711 9.935136,16.783711 C 6.134079,16.783711 3.044099,13.704881 3.044099,9.9038239 C 3.044099,6.2353545 5.927246,3.2289124 9.544867,3.0239379 z "
+ id="path1361" />
+ </g>
+</svg>
diff --git a/chalk/plugins/tools/tool_filter/tool_filter_cursor.png b/chalk/plugins/tools/tool_filter/tool_filter_cursor.png
new file mode 100644
index 00000000..d1e7f3d5
--- /dev/null
+++ b/chalk/plugins/tools/tool_filter/tool_filter_cursor.png
Binary files differ
diff --git a/chalk/plugins/tools/tool_perspectivegrid/Makefile.am b/chalk/plugins/tools/tool_perspectivegrid/Makefile.am
new file mode 100644
index 00000000..b3b0f74f
--- /dev/null
+++ b/chalk/plugins/tools/tool_perspectivegrid/Makefile.am
@@ -0,0 +1,35 @@
+kde_services_DATA = chalktoolperspectivegrid.desktop
+
+# all_includes must remain last!
+INCLUDES = -I$(srcdir)/../../../sdk \
+ -I$(srcdir)/../../../core \
+ -I$(srcdir)/../../../chalkcolor/ \
+ -I$(srcdir)/../../../ui \
+ -I$/../../../ui \
+ $(KOFFICE_INCLUDES) \
+ $(all_includes)
+
+chalktoolperspectivegrid_la_SOURCES = \
+ tool_perspectivegrid.cc \
+ kis_tool_perspectivegrid.cc
+
+# Install this plugin in the KDE modules directory
+kde_module_LTLIBRARIES = chalktoolperspectivegrid.la
+
+noinst_HEADERS = \
+ tool_perspectivegrid.h \
+ kis_tool_perspectivegrid.h
+
+chalktoolperspectivegrid_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) $(LIB_QT) -lkdecore -lkdeui -lkjs -lkdefx -lkio -lkparts -L../../../../chalk/chalkcolor/.libs -lchalkcolor -L../../../../chalk/core/.libs -lchalkimage \
+ -L../../../../chalk/ui/.libs -lchalkui
+chalktoolperspectivegrid_la_LIBADD = ../../../libchalkcommon.la
+
+METASOURCES = AUTO
+
+KDE_OPTIONS = nofinal
+
+chalkpics_DATA = \
+ tool_perspectivegrid.png
+
+chalkpicsdir = $(kde_datadir)/chalk/pics
+
diff --git a/chalk/plugins/tools/tool_perspectivegrid/chalktoolperspectivegrid.desktop b/chalk/plugins/tools/tool_perspectivegrid/chalktoolperspectivegrid.desktop
new file mode 100644
index 00000000..70001614
--- /dev/null
+++ b/chalk/plugins/tools/tool_perspectivegrid/chalktoolperspectivegrid.desktop
@@ -0,0 +1,35 @@
+[Desktop Entry]
+Name=Perspective Grid Tool
+Name[bg]=Инструмент мрежа
+Name[ca]=Eina de graella de perspectiva
+Name[da]=Perspektivgitterværktøj
+Name[de]=Perspektive-Raster-Werkzeug
+Name[el]=Εργαλείο προοπτικού πλέγματος
+Name[eo]=Perspektivkrado-ilo
+Name[es]=Herramienta Cuadrícula de perspectiva
+Name[et]=Perspektiivvõrgu tööriist
+Name[fa]=ابزار توری بُعدنما
+Name[fy]=Perspeksjeraster-ark
+Name[hu]=Perspektívarács
+Name[it]=Strumento di reticolo prospettico
+Name[ja]=遠近法グリッドツール
+Name[km]=ឧបករណ៍​ក្រឡា​ចត្រង្គ​យថាទស្សន៍
+Name[nb]=Perspektivnett-verktøy
+Name[nds]=Kiekwinkelgadder-Warktüüch
+Name[ne]=दृश्यात्मक ग्रीड उपकरण
+Name[nl]=Perspectiefraster-gereedschap
+Name[pl]=Narzędzie siatki perspektywy
+Name[pt]=Ferramenta de Grelha em Perspectiva
+Name[pt_BR]=Ferramenta de Grade em Perspectiva
+Name[ru]=Перспектива
+Name[sk]=Perspektívna mriežka
+Name[sl]=Orodja Mreža za perspektivo
+Name[sr]=Алат за мрежу у перспективи
+Name[sr@Latn]=Alat za mrežu u perspektivi
+Name[sv]=Perspektivrutnätsverktyg
+Name[uk]=Засіб ґратки перспективи
+Name[zh_TW]=透視格工具
+ServiceTypes=Chalk/Tool
+Type=Service
+X-KDE-Library=chalktoolperspectivegrid
+X-Chalk-Version=2
diff --git a/chalk/plugins/tools/tool_perspectivegrid/kis_tool_perspectivegrid.cc b/chalk/plugins/tools/tool_perspectivegrid/kis_tool_perspectivegrid.cc
new file mode 100644
index 00000000..3a21e72e
--- /dev/null
+++ b/chalk/plugins/tools/tool_perspectivegrid/kis_tool_perspectivegrid.cc
@@ -0,0 +1,499 @@
+/*
+ * kis_tool_perspectivegrid.cc - part of Chalk
+ *
+ * Copyright (c) 2006 Cyrille Berger <cberger@cberger.net>
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+#include <kis_tool_perspectivegrid.h>
+
+#include <tqapplication.h>
+#include <tqpainter.h>
+#include <tqregion.h>
+#include <tqwidget.h>
+#include <tqlayout.h>
+
+#include <kaction.h>
+#include <kdebug.h>
+#include <kcommand.h>
+#include <klocale.h>
+
+#include <kis_button_press_event.h>
+#include <kis_button_release_event.h>
+#include <kis_canvas_controller.h>
+#include <kis_canvas_painter.h>
+#include <kis_canvas_subject.h>
+#include <kis_cursor.h>
+#include <kis_image.h>
+#include <kis_move_event.h>
+#include <kis_perspective_grid_manager.h>
+#include <kis_selected_transaction.h>
+#include <kis_painter.h>
+#include <kis_paintop_registry.h>
+#include <kis_vec.h>
+
+#include <kis_canvas.h>
+
+KisToolPerspectiveGrid::KisToolPerspectiveGrid()
+ : super(i18n("Perspective Grid")), m_handleSize(13), m_handleHalfSize(6)
+
+{
+ setName("tool_perspectivegrid");
+
+ m_subject = 0;
+ m_dragging = false;
+}
+
+KisToolPerspectiveGrid::~KisToolPerspectiveGrid()
+{
+}
+
+void KisToolPerspectiveGrid::activate()
+{
+ m_subject->perspectiveGridManager()->startEdition();
+ if( ! m_subject->currentImg()->perspectiveGrid()->hasSubGrids() )
+ {
+ m_mode = MODE_CREATION;
+ m_points.clear();
+ } else {
+ m_mode = MODE_EDITING;
+ drawGrid();
+ }
+ super::activate();
+}
+
+void KisToolPerspectiveGrid::deactivate()
+{
+ m_subject->perspectiveGridManager()->stopEdition();
+ m_subject->perspectiveGridManager()->setGridVisible( true);
+ if( m_mode == MODE_CREATION )
+ {
+ drawGridCreation();
+ m_points.clear();
+ m_dragging = false;
+ } else {
+ drawGrid();
+ }
+}
+
+
+void KisToolPerspectiveGrid::update (KisCanvasSubject *subject)
+{
+ m_subject = subject;
+ super::update(m_subject);
+}
+
+bool KisToolPerspectiveGrid::mouseNear(const TQPoint& mousep, const TQPoint point)
+{
+ return (TQRect( (point.x() - m_handleHalfSize), (point.y() - m_handleHalfSize), m_handleSize, m_handleSize).tqcontains(mousep) );
+}
+
+void KisToolPerspectiveGrid::buttonPress(KisButtonPressEvent *event)
+{
+ KisPerspectiveGrid* pGrid = m_subject->currentImg()->perspectiveGrid();
+ if(!pGrid->hasSubGrids() && m_mode != MODE_CREATION)
+ { // it's possible that the perspectiv grid was cleared
+ m_mode = MODE_CREATION;
+ m_points.clear();
+ }
+ if( m_mode == MODE_CREATION && event->button() == Qt::LeftButton)
+ {
+ m_dragging = true;
+
+ if (m_points.isEmpty())
+ {
+ m_dragStart = event->pos();
+ m_dragEnd = event->pos();
+ m_points.append(m_dragStart);
+ } else {
+ m_dragStart = m_dragEnd;
+ m_dragEnd = event->pos();
+ drawGridCreation();
+ }
+ } else if(m_mode == MODE_EDITING && event->button() == Qt::LeftButton){
+ // Look for the handle which was pressed
+ if (!m_subject)
+ return;
+ KisCanvasController *controller = m_subject->canvasController();
+ Q_ASSERT(controller);
+ TQPoint mousep = controller->windowToView( event->pos().roundTQPoint() );
+
+ for( TQValueList<KisSubPerspectiveGrid*>::const_iterator it = pGrid->begin(); it != pGrid->end(); ++it)
+ {
+ KisSubPerspectiveGrid* grid = *it;
+ if( mouseNear( mousep, controller->windowToView(grid->topLeft()->roundTQPoint() ) ) )
+ {
+ kdDebug() << " PRESS TOPLEFT HANDLE " << endl;
+ m_mode = MODE_DRAGING_NODE;
+ m_selectedNode1 = grid->topLeft();
+ break;
+ }
+ else if( mouseNear( mousep, controller->windowToView(grid->topRight()->roundTQPoint() ) ) )
+ {
+ kdDebug() << " PRESS TOPRIGHT HANDLE " << endl;
+ m_mode = MODE_DRAGING_NODE;
+ m_selectedNode1 = grid->topRight();
+ break;
+ }
+ else if( mouseNear( mousep, controller->windowToView(grid->bottomLeft()->roundTQPoint() ) ) )
+ {
+ kdDebug() << " PRESS BOTTOMLEFT HANDLE " << endl;
+ m_mode = MODE_DRAGING_NODE;
+ m_selectedNode1 = grid->bottomLeft();
+ break;
+ }
+ else if( mouseNear( mousep, controller->windowToView(grid->bottomRight()->roundTQPoint() ) ) )
+ {
+ kdDebug() << " PRESS BOTTOMRIGHT HANDLE " << endl;
+ m_mode = MODE_DRAGING_NODE;
+ m_selectedNode1 = grid->bottomRight();
+ break;
+ }
+ else if( !grid->leftGrid() && mouseNear( mousep, controller->windowToView( ((*grid->topLeft() + *grid->bottomLeft() )*0.5) ).roundTQPoint() ) )
+ {
+ kdDebug() << " PRESS LEFT HANDLE " << endl;
+ m_mode = MODE_DRAGING_TRANSLATING_TWONODES;
+ drawGrid();
+ m_selectedNode1 = new KisPerspectiveGridNode( *grid->topLeft() );
+ m_selectedNode2 = new KisPerspectiveGridNode( *grid->bottomLeft() );
+ KisSubPerspectiveGrid* newsubgrid = new KisSubPerspectiveGrid( m_selectedNode1, grid->topLeft() , grid->bottomLeft(), m_selectedNode2);
+ m_dragEnd = event->pos();
+ newsubgrid->setRightGrid( grid);
+ grid->setLeftGrid( newsubgrid);
+ pGrid->addNewSubGrid( newsubgrid);
+ drawGrid();
+ break;
+ }
+ else if( !grid->rightGrid() && mouseNear( mousep, controller->windowToView( ((*grid->topRight() + *grid->bottomRight() )*0.5) ).roundTQPoint() ) )
+ {
+ kdDebug() << " PRESS RIGHT HANDLE " << endl;
+ m_mode = MODE_DRAGING_TRANSLATING_TWONODES;
+ drawGrid();
+ m_selectedNode1 = new KisPerspectiveGridNode( *grid->topRight() );
+ m_selectedNode2 = new KisPerspectiveGridNode( *grid->bottomRight() );
+ KisSubPerspectiveGrid* newsubgrid = new KisSubPerspectiveGrid( grid->topRight(), m_selectedNode1, m_selectedNode2, grid->bottomRight());
+ m_dragEnd = event->pos();
+ newsubgrid->setLeftGrid( grid);
+ grid->setRightGrid( newsubgrid);
+ pGrid->addNewSubGrid( newsubgrid);
+ drawGrid();
+ break;
+ }
+ else if( !grid->topGrid() && mouseNear( mousep, controller->windowToView( ((*grid->topLeft() + *grid->topRight() )*0.5) ).roundTQPoint() ) )
+ {
+ kdDebug() << " PRESS TOP HANDLE " << endl;
+ m_mode = MODE_DRAGING_TRANSLATING_TWONODES;
+ drawGrid();
+ m_selectedNode1 = new KisPerspectiveGridNode( *grid->topLeft() );
+ m_selectedNode2 = new KisPerspectiveGridNode( *grid->topRight() );
+ KisSubPerspectiveGrid* newsubgrid = new KisSubPerspectiveGrid( m_selectedNode1, m_selectedNode2, grid->topRight(), grid->topLeft() );
+ m_dragEnd = event->pos();
+ newsubgrid->setBottomGrid( grid);
+ grid->setTopGrid( newsubgrid);
+ pGrid->addNewSubGrid( newsubgrid);
+ drawGrid();
+ break;
+ }
+ else if( !grid->bottomGrid() && mouseNear( mousep, controller->windowToView( ((*grid->bottomLeft() + *grid->bottomRight() )*0.5) ).roundTQPoint() ) )
+ {
+ kdDebug() << " PRESS BOTTOM HANDLE " << endl;
+ m_mode = MODE_DRAGING_TRANSLATING_TWONODES;
+ drawGrid();
+ m_selectedNode1 = new KisPerspectiveGridNode( *grid->bottomLeft() );
+ m_selectedNode2 = new KisPerspectiveGridNode( *grid->bottomRight() );
+ KisSubPerspectiveGrid* newsubgrid = new KisSubPerspectiveGrid( grid->bottomLeft(), grid->bottomRight(), m_selectedNode2, m_selectedNode1);
+ m_dragEnd = event->pos();
+ newsubgrid->setTopGrid( grid);
+ grid->setBottomGrid( newsubgrid);
+ pGrid->addNewSubGrid( newsubgrid);
+ drawGrid();
+ break;
+ }
+ }
+ }
+}
+
+
+void KisToolPerspectiveGrid::move(KisMoveEvent *event)
+{
+ if( m_mode == MODE_CREATION )
+ {
+ if (m_dragging) {
+ // erase old lines on canvas
+ drawGridCreation();
+ // get current mouse position
+ m_dragEnd = event->pos();
+ // draw new lines on canvas
+ drawGridCreation();
+ }
+ } else {
+ if( m_mode == MODE_DRAGING_NODE)
+ {
+ drawGrid();
+ m_selectedNode1->setX( event->pos().x() );
+ m_selectedNode1->setY( event->pos().y() );
+ drawGrid();
+ }
+ if( m_mode == MODE_DRAGING_TRANSLATING_TWONODES)
+ {
+ drawGrid();
+ KisPoint translate = event->pos() - m_dragEnd;
+ m_dragEnd = event->pos();
+ *m_selectedNode1 += translate;;
+ *m_selectedNode2 += translate;;
+ drawGrid();
+ }
+ }
+}
+
+void KisToolPerspectiveGrid::buttonRelease(KisButtonReleaseEvent *event)
+{
+ if (!m_subject)
+ return;
+
+ if( m_mode == MODE_CREATION )
+ {
+ if (m_dragging && event->button() == Qt::LeftButton) {
+ m_dragging = false;
+ m_points.append (m_dragEnd);
+ if( m_points.size() == 4)
+ { // wow we have a grid, isn't that cool ?
+ drawGridCreation(); // Clean
+ m_subject->currentImg()->perspectiveGrid()->addNewSubGrid( new KisSubPerspectiveGrid( new KisPerspectiveGridNode(m_points[0]), new KisPerspectiveGridNode(m_points[1]), new KisPerspectiveGridNode(m_points[2]), new KisPerspectiveGridNode(m_points[3]) ) );
+ drawGrid();
+ m_mode = MODE_EDITING;
+ }
+ }
+ } else {
+ m_mode = MODE_EDITING;
+ m_selectedNode1 = 0;
+ m_selectedNode2 = 0;
+ }
+
+/* if (m_dragging && event->button() == RightButton) {
+
+ }*/
+}
+
+void KisToolPerspectiveGrid::paint(KisCanvasPainter& gc)
+{
+ if( m_mode == MODE_CREATION )
+ {
+ drawGridCreation(gc);
+ } else {
+ drawGrid(gc);
+ }
+}
+
+void KisToolPerspectiveGrid::paint(KisCanvasPainter& gc, const TQRect&)
+{
+ if( m_mode == MODE_CREATION )
+ {
+ drawGridCreation(gc);
+ } else {
+ drawGrid(gc);
+ }
+}
+
+void KisToolPerspectiveGrid::drawGridCreation()
+{
+ if (m_subject) {
+ KisCanvasController *controller = m_subject->canvasController();
+ KisCanvas *canvas = controller->kiscanvas();
+ KisCanvasPainter gc(canvas);
+
+ drawGridCreation(gc);
+ }
+}
+
+
+void KisToolPerspectiveGrid::drawGridCreation(KisCanvasPainter& gc)
+{
+ if (!m_subject)
+ return;
+
+ TQPen pen(TQt::white);
+
+ gc.setPen(pen);
+ gc.setRasterOp(TQt::XorROP);
+
+ KisCanvasController *controller = m_subject->canvasController();
+ KisPoint start, end;
+ TQPoint startPos;
+ TQPoint endPos;
+
+ if (m_dragging) {
+ startPos = controller->windowToView(m_dragStart.floorTQPoint());
+ endPos = controller->windowToView(m_dragEnd.floorTQPoint());
+ gc.drawLine(startPos, endPos);
+ } else {
+ for (KisPointVector::iterator it = m_points.begin(); it != m_points.end(); ++it) {
+
+ if (it == m_points.begin())
+ {
+ start = (*it);
+ } else {
+ end = (*it);
+
+ startPos = controller->windowToView(start.floorTQPoint());
+ endPos = controller->windowToView(end.floorTQPoint());
+
+ gc.drawLine(startPos, endPos);
+
+ start = end;
+ }
+ }
+ }
+}
+
+void KisToolPerspectiveGrid::drawSmallRectangle(KisCanvasPainter& gc, TQPoint p)
+{
+ gc.drawRect( p.x() - m_handleHalfSize - 1, p.y() - m_handleHalfSize - 1, m_handleSize, m_handleSize);
+}
+
+void KisToolPerspectiveGrid::drawGrid(KisCanvasPainter& gc)
+{
+
+ if (!m_subject)
+ return;
+
+ KisCanvasController *controller = m_subject->canvasController();
+
+ TQPen pen(TQt::white);
+ TQPoint startPos;
+ TQPoint endPos;
+
+ gc.setPen(pen);
+ gc.setRasterOp(TQt::XorROP);
+ KisPerspectiveGrid* pGrid = m_subject->currentImg()->perspectiveGrid();
+
+ for( TQValueList<KisSubPerspectiveGrid*>::const_iterator it = pGrid->begin(); it != pGrid->end(); ++it)
+ {
+ KisSubPerspectiveGrid* grid = *it;
+ int index = grid->index();
+ bool drawLeft = !(grid->leftGrid() && (index > grid->leftGrid()->index() ) );
+ bool drawRight = !(grid->rightGrid() && (index > grid->rightGrid()->index() ) );
+ bool drawTop = !(grid->topGrid() && (index > grid->topGrid()->index() ) );
+ bool drawBottom = !(grid->bottomGrid() && (index > grid->bottomGrid()->index() ) );
+ if(drawTop) {
+ startPos = controller->windowToView(grid->topLeft()->roundTQPoint());
+ endPos = controller->windowToView(grid->topRight()->roundTQPoint());
+ gc.drawLine( startPos, endPos );
+ if( !grid->topGrid() )
+ {
+ drawSmallRectangle(gc, (endPos + startPos) / 2);
+ }
+ if(drawLeft) {
+ drawSmallRectangle(gc, startPos);
+ }
+ if(drawRight) {
+ drawSmallRectangle(gc, endPos);
+ }
+ }
+ if(drawRight) {
+ startPos = controller->windowToView(grid->topRight()->roundTQPoint());
+ endPos = controller->windowToView(grid->bottomRight()->roundTQPoint());
+ gc.drawLine( startPos, endPos );
+ if( !grid->rightGrid() )
+ {
+ drawSmallRectangle(gc, (endPos + startPos) / 2);
+ }
+ }
+ if(drawBottom) {
+ startPos = controller->windowToView(grid->bottomRight()->roundTQPoint());
+ endPos = controller->windowToView(grid->bottomLeft()->roundTQPoint());
+ gc.drawLine( startPos, endPos );
+ if( !grid->bottomGrid() )
+ {
+ drawSmallRectangle(gc, (endPos + startPos) / 2);
+ }
+ if(drawLeft) {
+ drawSmallRectangle(gc, endPos);
+ }
+ if(drawRight) {
+ drawSmallRectangle(gc, startPos);
+ }
+ }
+ if(drawLeft) {
+ startPos = controller->windowToView(grid->bottomLeft()->roundTQPoint());
+ endPos = controller->windowToView(grid->topLeft()->roundTQPoint());
+ gc.drawLine( startPos, endPos );
+ if( !grid->leftGrid() )
+ {
+ drawSmallRectangle(gc, (endPos + startPos) / 2);
+ }
+ }
+ KisPoint tbVpf = grid->topBottomVanishingPoint();
+ if( fabs(tbVpf.x()) < 30000000. && fabs(tbVpf.y()) < 30000000.)
+ {
+ TQPoint tbVp = controller->windowToView(tbVpf.roundTQPoint());
+ gc.drawLine( tbVp.x() - m_handleHalfSize, tbVp.y() - m_handleHalfSize, tbVp.x() + m_handleHalfSize, tbVp.y() + m_handleHalfSize);
+ gc.drawLine( tbVp.x() - m_handleHalfSize, tbVp.y() + m_handleHalfSize, tbVp.x() + m_handleHalfSize, tbVp.y() - m_handleHalfSize);
+ }
+ KisPoint lrVpf = grid->leftRightVanishingPoint();
+ if( fabs(lrVpf.x()) < 30000000. && fabs(lrVpf.y()) < 30000000.)
+ { // Don't display it, if it is too far, or you get funny results
+ TQPoint lrVp = controller->windowToView(lrVpf.roundTQPoint());
+ gc.drawLine( lrVp.x() - m_handleHalfSize, lrVp.y() - m_handleHalfSize, lrVp.x() + m_handleHalfSize, lrVp.y() + m_handleHalfSize);
+ gc.drawLine( lrVp.x() - m_handleHalfSize, lrVp.y() + m_handleHalfSize, lrVp.x() + m_handleHalfSize, lrVp.y() - m_handleHalfSize);
+ }
+ }
+}
+
+void KisToolPerspectiveGrid::drawGrid()
+{
+ if (m_subject) {
+ KisCanvasController *controller = m_subject->canvasController();
+ KisCanvas *canvas = controller->kiscanvas();
+ KisCanvasPainter gc(canvas);
+
+ drawGrid(gc);
+ }
+
+}
+
+
+void KisToolPerspectiveGrid::setup(KActionCollection *collection)
+{
+ m_action = static_cast<KRadioAction *>(collection->action(name()));
+
+ if (m_action == 0) {
+ m_action = new KRadioAction(i18n("&Perspective Grid"),
+ "tool_perspectivegrid" ,
+ 0,
+ this,
+ TQT_SLOT(activate()),
+ collection,
+ name());
+ Q_CHECK_PTR(m_action);
+ m_action->setExclusiveGroup("tools");
+ m_action->setToolTip(i18n("Edit the perspective grid"));
+ m_ownAction = true;
+ }
+}
+
+
+// TQWidget* KisToolPerspectiveGrid::createOptionWidget(TQWidget* tqparent)
+// {
+// return 0;
+// }
+//
+// TQWidget* KisToolPerspectiveGrid::optionWidget()
+// {
+// return 0;
+// }
+
+
+#include "kis_tool_perspectivegrid.moc"
diff --git a/chalk/plugins/tools/tool_perspectivegrid/kis_tool_perspectivegrid.h b/chalk/plugins/tools/tool_perspectivegrid/kis_tool_perspectivegrid.h
new file mode 100644
index 00000000..69f6407a
--- /dev/null
+++ b/chalk/plugins/tools/tool_perspectivegrid/kis_tool_perspectivegrid.h
@@ -0,0 +1,111 @@
+/*
+ * kis_tool_perspectivegrid.h - part of Chalk
+ *
+ * Copyright (c) 2006 Cyrille Berger <cberger@cberger.net>
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef _KIS_TOOL_PERSPECTIVE_GRID_H_
+#define _KIS_TOOL_PERSPECTIVE_GRID_H_
+
+#include <kis_perspective_grid.h>
+#include <kis_point.h>
+#include <kis_tool_non_paint.h>
+#include <kis_tool_factory.h>
+
+class KisToolPerspectiveGrid : public KisToolNonPaint {
+ Q_OBJECT
+ TQ_OBJECT
+ enum PerspectiveGridEditionMode {
+ MODE_CREATION, // This is the mode when there is not yet a perspective grid
+ MODE_EDITING, // This is the mode when the grid has been created, and we are waiting for the user to click on a control box
+ MODE_DRAGING_NODE, // In this mode one node is translated
+ MODE_DRAGING_TRANSLATING_TWONODES // This mode is used when creating a new sub perspective grid
+ };
+ typedef KisToolNonPaint super;
+public:
+ KisToolPerspectiveGrid();
+ virtual ~KisToolPerspectiveGrid();
+ //
+ // KisCanvasObserver interface
+ //
+
+ virtual void update (KisCanvasSubject *subject);
+
+ //
+ // KisToolPaint interface
+ //
+
+ virtual void setup(KActionCollection *collection);
+ virtual TQ_UINT32 priority() { return 3; }
+ virtual enumToolType toolType() { return TOOL_VIEW; }
+ virtual void buttonPress(KisButtonPressEvent *event);
+ virtual void move(KisMoveEvent *event);
+ virtual void buttonRelease(KisButtonReleaseEvent *event);
+
+// TQWidget* createOptionWidget(TQWidget* tqparent);
+// virtual TQWidget* optionWidget();
+
+public slots:
+ virtual void activate();
+ void deactivate();
+
+protected:
+ virtual void paint(KisCanvasPainter& gc);
+ virtual void paint(KisCanvasPainter& gc, const TQRect& rc);
+ void drawGridCreation(KisCanvasPainter& gc);
+ void drawGridCreation();
+ void drawGrid(KisCanvasPainter& gc);
+ void drawGrid();
+
+private:
+ void drawSmallRectangle(KisCanvasPainter& gc, TQPoint p);
+ bool mouseNear(const TQPoint& mousep, const TQPoint point);
+
+protected:
+ KisPoint m_dragStart;
+ KisPoint m_dragEnd;
+
+ bool m_dragging;
+private:
+ typedef TQValueVector<KisPoint> KisPointVector;
+ KisCanvasSubject *m_subject;
+ KisPointVector m_points;
+ PerspectiveGridEditionMode m_mode;
+ TQ_INT32 m_handleSize, m_handleHalfSize;
+ KisPerspectiveGridNodeSP m_selectedNode1, m_selectedNode2;
+
+};
+
+
+class KisToolPerspectiveGridFactory : public KisToolFactory {
+ typedef KisToolFactory super;
+public:
+ KisToolPerspectiveGridFactory() : super() {};
+ virtual ~KisToolPerspectiveGridFactory(){};
+
+ virtual KisTool * createTool(KActionCollection * ac) {
+ KisTool * t = new KisToolPerspectiveGrid();
+ Q_CHECK_PTR(t);
+ t->setup(ac);
+ return t;
+ }
+ virtual KisID id() { return KisID("perspectivegridtool", i18n("Perspective Grid Tool")); }
+};
+
+
+#endif
+
diff --git a/chalk/plugins/tools/tool_perspectivegrid/tool_perspectivegrid.cc b/chalk/plugins/tools/tool_perspectivegrid/tool_perspectivegrid.cc
new file mode 100644
index 00000000..69158e21
--- /dev/null
+++ b/chalk/plugins/tools/tool_perspectivegrid/tool_perspectivegrid.cc
@@ -0,0 +1,62 @@
+/*
+ * tool_perspectivegrid.cc -- Part of Chalk
+ *
+ * Copyright (c) 2006 Cyrille Berger <cberger@cberger.net>
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+#include <stdlib.h>
+#include <vector>
+
+#include <tqpoint.h>
+
+#include <klocale.h>
+#include <kiconloader.h>
+#include <kinstance.h>
+#include <kmessagebox.h>
+#include <kstandarddirs.h>
+#include <kdebug.h>
+#include <kgenericfactory.h>
+
+#include <kis_global.h>
+#include <kis_types.h>
+#include <kis_tool_registry.h>
+
+#include "tool_perspectivegrid.h"
+#include "kis_tool_perspectivegrid.h"
+
+
+typedef KGenericFactory<ToolPerspectiveGrid> ToolPerspectiveGridFactory;
+K_EXPORT_COMPONENT_FACTORY( chalktoolperspectivegrid, ToolPerspectiveGridFactory( "chalk" ) )
+
+
+ToolPerspectiveGrid::ToolPerspectiveGrid(TQObject *tqparent, const char *name, const TQStringList &)
+ : KParts::Plugin(tqparent, name)
+{
+ setInstance(ToolPerspectiveGridFactory::instance());
+
+ if ( tqparent->inherits("KisToolRegistry") )
+ {
+ KisToolRegistry * r = dynamic_cast<KisToolRegistry*>(tqparent);
+ r->add(new KisToolPerspectiveGridFactory());
+ }
+
+}
+
+ToolPerspectiveGrid::~ToolPerspectiveGrid()
+{
+}
+
+#include "tool_perspectivegrid.moc"
diff --git a/chalk/plugins/tools/tool_perspectivegrid/tool_perspectivegrid.h b/chalk/plugins/tools/tool_perspectivegrid/tool_perspectivegrid.h
new file mode 100644
index 00000000..aed4a60c
--- /dev/null
+++ b/chalk/plugins/tools/tool_perspectivegrid/tool_perspectivegrid.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2006 Cyrille Berger <cberger@cberger.net>
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef TOOL_PERSPECTIVE_GRID_H_
+#define TOOL_PERSPECTIVE_GRID_H_
+
+#include <kparts/plugin.h>
+
+class KisView;
+
+/**
+ * A module that provides a tool for editing the perspective grid.
+ */
+class ToolPerspectiveGrid : public KParts::Plugin
+{
+ Q_OBJECT
+ TQ_OBJECT
+public:
+ ToolPerspectiveGrid(TQObject *tqparent, const char *name, const TQStringList &);
+ virtual ~ToolPerspectiveGrid();
+
+private:
+
+ KisView * m_view;
+
+};
+
+#endif // TOOL_PERSPECTIVE_GRID_H_
diff --git a/chalk/plugins/tools/tool_perspectivegrid/tool_perspectivegrid.png b/chalk/plugins/tools/tool_perspectivegrid/tool_perspectivegrid.png
new file mode 100644
index 00000000..ac4efbfa
--- /dev/null
+++ b/chalk/plugins/tools/tool_perspectivegrid/tool_perspectivegrid.png
Binary files differ
diff --git a/chalk/plugins/tools/tool_perspectivegrid/tool_perspectivegrid.svg b/chalk/plugins/tools/tool_perspectivegrid/tool_perspectivegrid.svg
new file mode 100644
index 00000000..3dd79413
--- /dev/null
+++ b/chalk/plugins/tools/tool_perspectivegrid/tool_perspectivegrid.svg
@@ -0,0 +1,87 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://web.resource.org/cc/"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://inkscape.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="22"
+ height="22"
+ id="svg2"
+ sodipodi:version="0.32"
+ inkscape:version="0.43"
+ version="1.0"
+ sodipodi:docbase="/home/cyrille/koffice-1.6/chalk/plugins/tools/tool_perspectivegrid"
+ sodipodi:docname="tool_perspectivegrid.svg"
+ inkscape:export-filename="/home/cyrille/koffice-1.6/chalk/plugins/tools/tool_perspectivegrid/tool_perspectivegrid.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <defs
+ id="defs4" />
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="9.8597476"
+ inkscape:cx="12.855376"
+ inkscape:cy="7.6671075"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ inkscape:window-width="749"
+ inkscape:window-height="540"
+ inkscape:window-x="424"
+ inkscape:window-y="433" />
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1">
+ <path
+ style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#909090;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="M 4.8682788,20.580085 C 6.5924609,1.3098151 6.7953058,1.5126601 6.7953058,1.5126601 L 6.7953058,1.5126601 L 6.7953058,1.5126601"
+ id="path2183" />
+ <path
+ style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#909090;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="M 11.359317,18.551636 C 10.446515,2.3240399 10.446515,2.3240399 10.446515,2.3240399 L 10.446515,2.3240399 L 10.446515,2.3240399"
+ id="path2185" />
+ <path
+ style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#909090;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="M 17.444666,17.131721 C 13.894879,3.1354197 13.894879,3.1354197 13.894879,3.1354197"
+ id="path2187" />
+ <path
+ style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#909090;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="M 2.7384068,4.7581793 C 17.647511,6.5837838 17.546088,6.5837838 17.546088,6.5837838"
+ id="path2191" />
+ <path
+ style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#909090;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="M 2.0284495,10.742105 C 18.256045,9.7278805 18.86458,9.1193456 18.86458,9.1193456"
+ id="path2193"
+ sodipodi:nodetypes="cc" />
+ <path
+ style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#909090;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="M 1.0142247,17.131721 C 20.08165,12.56771 20.08165,12.364865 20.08165,12.364865"
+ id="path2195"
+ sodipodi:nodetypes="cc" />
+ <path
+ style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="M 3.1440967,0.59985768 L 16.531864,3.6425319 L 21.70441,15.813228 L 0.50711235,21.594309 L 3.1440967,0.59985768 z "
+ id="rect1307"
+ sodipodi:nodetypes="ccccc" />
+ </g>
+</svg>
diff --git a/chalk/plugins/tools/tool_perspectivetransform/Makefile.am b/chalk/plugins/tools/tool_perspectivetransform/Makefile.am
new file mode 100644
index 00000000..416bdcc3
--- /dev/null
+++ b/chalk/plugins/tools/tool_perspectivetransform/Makefile.am
@@ -0,0 +1,35 @@
+kde_services_DATA = chalktoolperspectivetransform.desktop
+
+# all_includes must remain last!
+INCLUDES = -I$(srcdir)/../../../sdk \
+ -I$(srcdir)/../../../core \
+ -I$(srcdir)/../../../chalkcolor/ \
+ -I$(srcdir)/../../../ui \
+ -I$/../../../ui \
+ $(KOFFICE_INCLUDES) \
+ $(all_includes)
+
+chalktoolperspectivetransform_la_SOURCES = \
+ tool_perspectivetransform.cc \
+ kis_tool_perspectivetransform.cc
+
+# Install this plugin in the KDE modules directory
+kde_module_LTLIBRARIES = chalktoolperspectivetransform.la
+
+noinst_HEADERS = \
+ tool_perspectivetransform.h \
+ kis_tool_perspectivetransform.h
+
+chalktoolperspectivetransform_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) $(LIB_QT) -lkdecore -lkdeui -lkjs -lkdefx -lkio -lkparts -L../../../../chalk/chalkcolor/.libs -lchalkcolor -L../../../../chalk/core/.libs -lchalkimage \
+ -L../../../../chalk/ui/.libs -lchalkui
+chalktoolperspectivetransform_la_LIBADD = ../../../libchalkcommon.la
+
+chalktoolperspectivetransform_la_METASOURCES = AUTO
+
+KDE_OPTIONS = nofinal
+
+chalkpics_DATA = \
+ tool_perspectivetransform.png
+
+chalkpicsdir = $(kde_datadir)/chalk/pics
+
diff --git a/chalk/plugins/tools/tool_perspectivetransform/chalktoolperspectivetransform.desktop b/chalk/plugins/tools/tool_perspectivetransform/chalktoolperspectivetransform.desktop
new file mode 100644
index 00000000..860efc69
--- /dev/null
+++ b/chalk/plugins/tools/tool_perspectivetransform/chalktoolperspectivetransform.desktop
@@ -0,0 +1,37 @@
+[Desktop Entry]
+Icon=
+Name=Perspective transform Tool
+Name[bg]=Инструмент трансформиране
+Name[ca]=Eina de transformació de perspectiva
+Name[da]=Perspectivetransformeringsværktøj
+Name[de]=Perspektive-Transformationswerkzeug
+Name[el]=Εργαλείο προοπτικού μετασχηματισμού
+Name[eo]=Perspektivŝanĝo-ilo
+Name[es]=Herramienta Transformar perspectiva
+Name[et]=Perspektiivteisenduse tööriist
+Name[fa]=ابزار تبدیل بُعدنما
+Name[fr]=Outils de transformation de perspective
+Name[fy]=Perspeksje oerset ark
+Name[hu]=Perspektívaátalakító eszköz
+Name[it]=Strumento di trasformazione della prospettiva
+Name[ja]=視点変更ツール
+Name[km]=ឧបករណ៍​ប្លែង​យថាទស្សន៍
+Name[nb]=Verktøy for perspektivtransformasjon
+Name[nds]=Warktüüch för't Kiekwinkeltopassen
+Name[ne]=दृश्यात्मक रूपान्तरण उपकरण
+Name[nl]=Perspectiefrooster-gereedschap
+Name[pl]=Narzędzie zmiany perspektywy
+Name[pt]=Ferramenta de Transformação em Perspectiva
+Name[pt_BR]=Ferramentas de Transformação em Perspectiva
+Name[ru]=Перспектива
+Name[sk]=Perspektívna transformácia
+Name[sl]=Orodje za transformacijo perspektive
+Name[sr]=Алати за трансформацију перспективе
+Name[sr@Latn]=Alati za transformaciju perspektive
+Name[sv]=Perspektivtransformverktyg
+Name[uk]=Засіб перспективи
+Name[zh_TW]=透視轉換工具
+ServiceTypes=Chalk/Tool
+Type=Service
+X-KDE-Library=chalktoolperspectivetransform
+X-Chalk-Version=2
diff --git a/chalk/plugins/tools/tool_perspectivetransform/kis_tool_perspectivetransform.cc b/chalk/plugins/tools/tool_perspectivetransform/kis_tool_perspectivetransform.cc
new file mode 100644
index 00000000..809d1a7d
--- /dev/null
+++ b/chalk/plugins/tools/tool_perspectivetransform/kis_tool_perspectivetransform.cc
@@ -0,0 +1,742 @@
+/*
+ * kis_tool_transform.cc -- part of Chalk
+ *
+ * Copyright (c) 2006 Cyrille Berger <cberger@cberger.net>
+ *
+ * Based on the transform tool from :
+ * Copyright (c) 2004 Boudewijn Rempt <boud@valdyas.org>
+ * Copyright (c) 2005 Casper Boemann <cbr@boemann.dk>
+ *
+ * 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; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "kis_tool_perspectivetransform.h"
+
+
+#include <tqpainter.h>
+#include <tqpen.h>
+#include <tqpushbutton.h>
+#include <tqobject.h>
+#include <tqlabel.h>
+#include <tqcombobox.h>
+#include <tqapplication.h>
+
+#include <kdebug.h>
+#include <kaction.h>
+#include <kcommand.h>
+#include <klocale.h>
+#include <knuminput.h>
+
+#include <kis_global.h>
+#include <kis_painter.h>
+#include <kis_canvas_controller.h>
+#include <kis_canvas_subject.h>
+#include <kis_cursor.h>
+#include <kis_image.h>
+#include <kis_undo_adapter.h>
+#include <kis_selected_transaction.h>
+#include <kis_button_press_event.h>
+#include <kis_button_release_event.h>
+#include <kis_move_event.h>
+#include <kis_selection.h>
+#include <kis_filter_strategy.h>
+#include <kis_cmb_idlist.h>
+#include <kis_id.h>
+#include <kis_tool_controller.h>
+#include <kis_perspectivetransform_worker.h>
+
+//#include "wdg_tool_transform.h"
+#include "kis_canvas.h"
+#include "kis_canvas_painter.h"
+
+namespace {
+ class PerspectiveTransformCmd : public KisSelectedTransaction {
+ typedef KisSelectedTransaction super;
+
+ public:
+ PerspectiveTransformCmd(KisToolPerspectiveTransform *tool, KisPaintDeviceSP device, KisPaintDeviceSP origDevice, KisPoint topleft, KisPoint topright, KisPoint bottomleft, KisPoint bottomright, KisSelectionSP origSel, TQRect initialRect);
+ virtual ~PerspectiveTransformCmd();
+
+ public:
+ virtual void execute();
+ virtual void unexecute();
+ void transformArgs(KisPoint &topleft, KisPoint &topright, KisPoint &bottomleft, KisPoint& bottomright) const;
+ KisSelectionSP origSelection(TQRect& initialRect) const;
+ KisPaintDeviceSP theDevice();
+ KisPaintDeviceSP origDevice();
+
+ private:
+ TQRect m_initialRect;
+ KisPoint m_topleft, m_topright, m_bottomleft, m_bottomright;
+ KisToolPerspectiveTransform *m_tool;
+ KisSelectionSP m_origSelection;
+ KisPaintDeviceSP m_device;
+ KisPaintDeviceSP m_origDevice;
+ };
+
+ PerspectiveTransformCmd::PerspectiveTransformCmd(KisToolPerspectiveTransform *tool, KisPaintDeviceSP device, KisPaintDeviceSP origDevice, KisPoint topleft, KisPoint topright, KisPoint bottomleft, KisPoint bottomright, KisSelectionSP origSel, TQRect initialRect) :
+ super(i18n("Perspective Transform"), device), m_initialRect(initialRect)
+ , m_topleft(topleft), m_topright(topright), m_bottomleft(bottomleft), m_bottomright(bottomright)
+ , m_tool(tool), m_origSelection(origSel), m_device(device), m_origDevice(origDevice)
+ {
+ }
+
+ PerspectiveTransformCmd::~PerspectiveTransformCmd()
+ {
+ }
+
+ void PerspectiveTransformCmd::transformArgs(KisPoint &topleft, KisPoint &topright, KisPoint &bottomleft, KisPoint& bottomright) const
+ {
+ topleft = m_topleft;
+ topright = m_topright;
+ bottomleft = m_bottomleft;
+ bottomright = m_bottomright;
+ }
+
+ KisSelectionSP PerspectiveTransformCmd::origSelection(TQRect& initialRect) const
+ {
+ initialRect = m_initialRect;
+ return m_origSelection;
+ }
+
+ void PerspectiveTransformCmd::execute()
+ {
+ super::execute();
+ }
+
+ void PerspectiveTransformCmd::unexecute()
+ {
+ super::unexecute();
+ }
+
+ KisPaintDeviceSP PerspectiveTransformCmd::theDevice()
+ {
+ return m_device;
+ }
+
+ KisPaintDeviceSP PerspectiveTransformCmd::origDevice()
+ {
+ return m_origDevice;
+ }
+}
+
+KisToolPerspectiveTransform::KisToolPerspectiveTransform()
+ : super(i18n("Perspective Transform"))
+{
+ setName("tool_perspectivetransform");
+ setCursor(KisCursor::selectCursor());
+ m_subject = 0;
+ m_origDevice = 0;
+ m_origSelection = 0;
+ m_handleHalfSize = 8;
+ m_handleSize = 2 * m_handleHalfSize;
+ m_handleSelected = NOHANDLE;
+}
+
+KisToolPerspectiveTransform::~KisToolPerspectiveTransform()
+{
+}
+
+void KisToolPerspectiveTransform::deactivate()
+{
+ if (m_subject && m_subject->undoAdapter()) m_subject->undoAdapter()->removeCommandHistoryListener( this );
+
+ KisImageSP img = m_subject->currentImg();
+ if (!img) return;
+
+ paintOutline();
+
+ disconnect(m_subject->currentImg().data(), TQT_SIGNAL(sigLayerActivated(KisLayerSP)), this, TQT_SLOT(slotLayerActivated(KisLayerSP)));
+}
+
+void KisToolPerspectiveTransform::activate()
+{
+ super::activate();
+ m_currentSelectedPoint = 0;
+ if(m_subject && m_subject->currentImg() && m_subject->currentImg()->activeDevice())
+ {
+ //connect(m_subject, commandExecuted(KCommand *c), this, notifyCommandAdded( KCommand * c));
+ m_subject->undoAdapter()->setCommandHistoryListener( this );
+
+// KisToolControllerInterface *controller = m_subject->toolController();
+// if (controller)
+// controller->setCurrentTool(this);
+
+ PerspectiveTransformCmd * cmd=0;
+
+ if(m_subject->currentImg()->undoAdapter()->presentCommand())
+ cmd = dynamic_cast<PerspectiveTransformCmd*>(m_subject->currentImg()->undoAdapter()->presentCommand());
+
+ // One of our commands is on top
+ if(cmd &&cmd->theDevice() == m_subject->currentImg()->activeDevice())
+ {
+ m_interractionMode = EDITRECTINTERRACTION;
+ // and it even has the same device
+ // We should ask for tool args and orig selection
+ m_origDevice = cmd->origDevice();
+ cmd->transformArgs(m_topleft, m_topright, m_bottomleft, m_bottomright);
+ m_origSelection = cmd->origSelection(m_initialRect);
+ paintOutline();
+ }
+ else
+ {
+ m_interractionMode = DRAWRECTINTERRACTION;
+ m_points.clear();
+ initHandles();
+ }
+ }
+ connect(m_subject->currentImg(), TQT_SIGNAL(sigLayerActivated(KisLayerSP)), this, TQT_SLOT(slotLayerActivated(KisLayerSP)));
+}
+
+void KisToolPerspectiveTransform::initHandles()
+{
+// TQ_INT32 x,y,w,h;
+ KisImageSP img = m_subject->currentImg();
+
+ KisPaintDeviceSP dev = img->activeDevice();
+ if (!dev ) return;
+
+ // Create a lazy copy of the current state
+ m_origDevice = new KisPaintDevice(*dev.data());
+ Q_ASSERT(m_origDevice);
+
+ if(dev->hasSelection())
+ {
+ KisSelectionSP sel = dev->selection();
+ m_origSelection = new KisSelection(*sel.data());
+ m_initialRect = sel->selectedExactRect();
+ }
+ else {
+ m_initialRect = dev->exactBounds();
+ }
+ m_topleft = KisPoint(m_initialRect.topLeft());
+ m_topright = KisPoint(m_initialRect.topRight());
+ m_bottomleft = KisPoint(m_initialRect.bottomLeft());
+ m_bottomright = KisPoint(m_initialRect.bottomRight());
+
+ m_subject->canvasController() ->updateCanvas();
+}
+
+void KisToolPerspectiveTransform::paint(KisCanvasPainter& gc)
+{
+ paintOutline(gc, TQRect());
+}
+
+void KisToolPerspectiveTransform::paint(KisCanvasPainter& gc, const TQRect& rc)
+{
+ paintOutline(gc, rc);
+}
+
+bool KisToolPerspectiveTransform::mouseNear(const TQPoint& mousep, const TQPoint point)
+{
+ return (TQRect( (point.x() - m_handleHalfSize), (point.y() - m_handleHalfSize), m_handleSize, m_handleSize).tqcontains(mousep) );
+}
+
+void KisToolPerspectiveTransform::buttonPress(KisButtonPressEvent *event)
+{
+ if (m_subject) {
+ switch(m_interractionMode)
+ {
+ case DRAWRECTINTERRACTION:
+ {
+ if (m_points.isEmpty())
+ {
+ m_dragging = false;
+ m_dragStart = event->pos();
+ m_dragEnd = event->pos();
+ m_points.append(m_dragStart);
+ paintOutline();
+ } else {
+ m_dragging = true;
+ m_dragStart = m_dragEnd;
+ m_dragEnd = event->pos();
+ paintOutline();
+ }
+ }
+ case EDITRECTINTERRACTION:
+ {
+ KisImageSP img = m_subject->currentImg();
+
+ if (img && img->activeDevice() && event->button() == Qt::LeftButton) {
+ m_actualyMoveWhileSelected = false;
+ m_dragEnd = event->pos();
+ KisCanvasController *controller = m_subject->canvasController();
+ TQPoint mousep = controller->windowToView( event->pos().roundTQPoint() );
+ if( mouseNear( mousep, controller->windowToView(m_topleft.roundTQPoint() ) ) )
+ {
+ kdDebug() << " PRESS TOPLEFT HANDLE " << endl;
+ m_currentSelectedPoint = &m_topleft;
+ }
+ else if( mouseNear( mousep, controller->windowToView(m_topright.roundTQPoint() ) ) )
+ {
+ kdDebug() << " PRESS TOPRIGHT HANDLE " << endl;
+ m_currentSelectedPoint = &m_topright;
+ }
+ else if( mouseNear( mousep, controller->windowToView(m_bottomleft.roundTQPoint() ) ) )
+ {
+ kdDebug() << " PRESS BOTTOMLEFT HANDLE " << endl;
+ m_currentSelectedPoint = &m_bottomleft;
+ }
+ else if( mouseNear( mousep, controller->windowToView(m_bottomright.roundTQPoint() ) ) )
+ {
+ kdDebug() << " PRESS BOTTOMRIGHT HANDLE " << endl;
+ m_currentSelectedPoint = &m_bottomright;
+ } else if( mouseNear( mousep, controller->windowToView(KisPoint((m_topleft+m_topright)*0.5).roundTQPoint() ) ) )
+ {
+ kdDebug() << " PRESS TOP HANDLE " << endl;
+ m_handleSelected = TOPHANDLE;
+ }else if( mouseNear( mousep, controller->windowToView(KisPoint((m_topleft+m_bottomleft)*0.5).roundTQPoint() ) ) )
+ {
+ kdDebug() << " PRESS LEFT HANDLE " << endl;
+ m_handleSelected = LEFTHANDLE;
+ }else if( mouseNear( mousep, controller->windowToView(KisPoint((m_bottomleft+m_bottomright)*0.5).roundTQPoint() ) ) )
+ {
+ kdDebug() << " PRESS BOTTOM HANDLE " << endl;
+ m_handleSelected = BOTTOMHANDLE;
+ }else if( mouseNear( mousep, controller->windowToView(KisPoint((m_bottomright+m_topright)*0.5).roundTQPoint() ) ) )
+ {
+ kdDebug() << " PRESS RIGHT HANDLE " << endl;
+ m_handleSelected = RIGHTHANDLE;
+ }else if( mouseNear( mousep, controller->windowToView(KisPoint((m_topleft+m_bottomleft + m_bottomright+m_topright)*0.25).roundTQPoint() ) ) )
+ {
+ kdDebug() << " PRESS MIDDLE HANDLE " << endl;
+ m_handleSelected = MIDDLEHANDLE;
+ }
+ }
+ }
+ }
+ }
+}
+
+void KisToolPerspectiveTransform::move(KisMoveEvent *event)
+{
+ switch(m_interractionMode)
+ {
+ case DRAWRECTINTERRACTION:
+ {
+ if (m_dragging) {
+ // erase old lines on canvas
+ paintOutline();
+ // get current mouse position
+ m_dragEnd = event->pos();
+ // draw new lines on canvas
+ paintOutline();
+ }
+ }
+
+ case EDITRECTINTERRACTION:
+ {
+ if(m_currentSelectedPoint)
+ {
+ paintOutline();
+ KisPoint translate = event->pos() - m_dragEnd;
+ m_dragEnd = event->pos();
+ *m_currentSelectedPoint += translate;;
+ paintOutline();
+ m_actualyMoveWhileSelected = true;
+ }
+ else if(m_handleSelected == TOPHANDLE || m_handleSelected == LEFTHANDLE || m_handleSelected == BOTTOMHANDLE || m_handleSelected == RIGHTHANDLE)
+ {
+ paintOutline();
+
+ KisPoint translate = event->pos() - m_dragEnd;
+ m_dragEnd = event->pos();
+
+ double matrixFrom[3][3];
+ double* b = KisPerspectiveMath::computeMatrixTransfoToPerspective(m_topleft, m_topright, m_bottomleft, m_bottomright, m_initialRect);
+ for(int i = 0; i < 3; i++)
+ {
+ for(int j = 0; j < 3; j++)
+ {
+ matrixFrom[i][j] = b[3*i+j];
+ }
+ }
+ delete b;
+
+ KisPoint topLeft = KisPerspectiveMath::matProd(matrixFrom, KisPoint(m_initialRect.topLeft()) );
+ KisPoint topRight = KisPerspectiveMath::matProd(matrixFrom, KisPoint(m_initialRect.topRight()) );
+ KisPoint bottomLeft = KisPerspectiveMath::matProd(matrixFrom, KisPoint(m_initialRect.bottomLeft()) );
+ KisPoint bottomRight = KisPerspectiveMath::matProd(matrixFrom, KisPoint(m_initialRect.bottomRight()) );
+ TQRect dstRect = m_initialRect;
+ switch(m_handleSelected)
+ {
+ case TOPHANDLE:
+ dstRect.setTop( static_cast<int>( dstRect.top() + translate.y() ) ) ;
+ break;
+ case LEFTHANDLE:
+ dstRect.setLeft( static_cast<int>( dstRect.left() + translate.x() ) );
+ break;
+ case BOTTOMHANDLE:
+ dstRect.setBottom( static_cast<int>( dstRect.bottom() + translate.y() ) );
+ break;
+ case RIGHTHANDLE:
+ dstRect.setRight( static_cast<int>( dstRect.right() + translate.x() ) );
+ break;
+ case MIDDLEHANDLE:
+ case NOHANDLE:
+ kdDebug() << "Should NOT happen" << endl;
+ }
+ double matrixTo[3][3];
+ b = KisPerspectiveMath::computeMatrixTransfoToPerspective(topLeft, topRight, bottomLeft, bottomRight, dstRect );
+ for(int i = 0; i < 3; i++)
+ {
+ for(int j = 0; j < 3; j++)
+ {
+ matrixTo[i][j] = b[3*i+j];
+ }
+ }
+ delete b;
+ m_topleft = KisPerspectiveMath::matProd(matrixTo, KisPoint(m_initialRect.topLeft()));
+ m_topright = KisPerspectiveMath::matProd(matrixTo, KisPoint(m_initialRect.topRight()));
+ m_bottomleft = KisPerspectiveMath::matProd(matrixTo, KisPoint(m_initialRect.bottomLeft()));
+ m_bottomright = KisPerspectiveMath::matProd(matrixTo, KisPoint(m_initialRect.bottomRight()));
+
+ paintOutline();
+ m_actualyMoveWhileSelected = true;
+ } else if (m_handleSelected == MIDDLEHANDLE) {
+ paintOutline();
+ KisPoint translate = event->pos() - m_dragEnd;
+ m_dragEnd = event->pos();
+ m_topleft += translate;
+ m_topright += translate;
+ m_bottomleft += translate;
+ m_bottomright += translate;
+ paintOutline();
+ m_actualyMoveWhileSelected = true;
+ }
+ }
+ };
+}
+
+void KisToolPerspectiveTransform::buttonRelease(KisButtonReleaseEvent * event)
+{
+ KisImageSP img = m_subject->currentImg();
+
+ if (!img)
+ return;
+ if( event->button() == Qt::LeftButton)
+ {
+ switch(m_interractionMode)
+ {
+ case DRAWRECTINTERRACTION:
+ {
+ if (m_dragging && event->button() == Qt::LeftButton) {
+ paintOutline();
+ m_dragging = false;
+ m_points.append (m_dragEnd);
+ if( m_points.size() == 4)
+ {
+ // from the points, select which is topleft ? topright ? bottomright ? and bottomleft ?
+ m_topleft = m_points[0];
+ m_topright = m_points[1];
+ m_bottomleft = m_points[3];
+ m_bottomright = m_points[2];
+ double matrix[3][3];
+ double* b = KisPerspectiveMath::computeMatrixTransfoToPerspective(m_topleft, m_topright, m_bottomleft, m_bottomright, m_initialRect );
+ for(int i = 0; i < 3; i++)
+ {
+ for(int j = 0; j < 3; j++)
+ {
+ kdDebug() << "sol[" << 3*i+j << "]=" << b[3*i+j] << endl;
+ matrix[i][j] = b[3*i+j];
+ }
+ }
+ m_topleft = KisPerspectiveMath::matProd(matrix, KisPoint(m_initialRect.topLeft()));
+ m_topright = KisPerspectiveMath::matProd(matrix, KisPoint(m_initialRect.topRight()));
+ m_bottomleft = KisPerspectiveMath::matProd(matrix, KisPoint(m_initialRect.bottomLeft()));
+ m_bottomright = KisPerspectiveMath::matProd(matrix, KisPoint(m_initialRect.bottomRight()));
+ m_interractionMode = EDITRECTINTERRACTION;
+ paintOutline();
+ TQApplication::setOverrideCursor(KisCursor::waitCursor());
+ transform();
+ TQApplication::restoreOverrideCursor();
+ } else {
+ paintOutline();
+ }
+ }
+ }
+ break;
+ case EDITRECTINTERRACTION:
+ {
+ if(m_currentSelectedPoint )
+ {
+ m_currentSelectedPoint = 0;
+ if(m_actualyMoveWhileSelected)
+ {
+ paintOutline();
+ TQApplication::setOverrideCursor(KisCursor::waitCursor());
+ transform();
+ TQApplication::restoreOverrideCursor();
+ }
+ }
+ if(m_handleSelected != NOHANDLE)
+ {
+ m_handleSelected = NOHANDLE;
+ if(m_actualyMoveWhileSelected)
+ {
+// paintOutline();
+ TQApplication::setOverrideCursor(KisCursor::waitCursor());
+ transform();
+ TQApplication::restoreOverrideCursor();
+ }
+ }
+ }
+ break;
+ }
+ }
+}
+
+void KisToolPerspectiveTransform::paintOutline()
+{
+ if (m_subject) {
+ KisCanvasController *controller = m_subject->canvasController();
+ KisCanvas *canvas = controller->kiscanvas();
+ KisCanvasPainter gc(canvas);
+ TQRect rc;
+
+ paintOutline(gc, rc);
+ }
+}
+
+void KisToolPerspectiveTransform::paintOutline(KisCanvasPainter& gc, const TQRect&)
+{
+ if (m_subject) {
+ KisCanvasController *controller = m_subject->canvasController();
+ RasterOp op = gc.rasterOp();
+ TQPen old = gc.pen();
+ TQPen pen(TQt::SolidLine);
+ pen.setWidth(1);
+ Q_ASSERT(controller);
+
+ switch(m_interractionMode)
+ {
+ case DRAWRECTINTERRACTION:
+ {
+ kdDebug() << "DRAWRECTINTERRACTION paintOutline " << m_points.size() << endl;
+ KisPoint start, end;
+ TQPoint startPos;
+ TQPoint endPos;
+ for (KisPointVector::iterator it = m_points.begin(); it != m_points.end(); ++it) {
+
+ if (it == m_points.begin())
+ {
+ start = (*it);
+ } else {
+ end = (*it);
+
+ startPos = controller->windowToView(start.floorTQPoint());
+ endPos = controller->windowToView(end.floorTQPoint());
+
+ gc.drawLine(startPos, endPos);
+
+ start = end;
+ }
+ }
+ }
+ break;
+ case EDITRECTINTERRACTION:
+ {
+ TQPoint topleft = controller->windowToView(m_topleft ).roundTQPoint();
+ TQPoint topright = controller->windowToView(m_topright).roundTQPoint();
+ TQPoint bottomleft = controller->windowToView(m_bottomleft).roundTQPoint();
+ TQPoint bottomright = controller->windowToView(m_bottomright).roundTQPoint();
+
+ gc.setRasterOp(TQt::NotROP);
+ gc.setPen(pen);
+ gc.drawRect(topleft.x()-4, topleft.y()-4, 8, 8);
+ gc.drawLine(topleft.x(), topleft.y(), (topleft.x()+topright.x())/2, (topleft.y()+topright.y())/2);
+ gc.drawRect((topleft.x()+topright.x())/2-4, (topleft.y()+topright.y())/2-4, 8, 8);
+ gc.drawLine((topleft.x()+topright.x())/2, (topleft.y()+topright.y())/2, topright.x(), topright.y());
+ gc.drawRect(topright.x()-4, topright.y()-4, 8, 8);
+ gc.drawLine(topright.x(), topright.y(), (topright.x()+bottomright.x())/2, (topright.y()+bottomright.y())/2);
+ gc.drawRect((topright.x()+bottomright.x())/2-4, (topright.y()+bottomright.y())/2-4, 8, 8);
+ gc.drawLine((topright.x()+bottomright.x())/2, (topright.y()+bottomright.y())/2,bottomright.x(), bottomright.y());
+ gc.drawRect(bottomright.x()-4, bottomright.y()-4, 8, 8);
+ gc.drawLine(bottomright.x(), bottomright.y(), (bottomleft.x()+bottomright.x())/2, (bottomleft.y()+bottomright.y())/2);
+ gc.drawRect((bottomleft.x()+bottomright.x())/2-4, (bottomleft.y()+bottomright.y())/2-4, 8, 8);
+ gc.drawLine((bottomleft.x()+bottomright.x())/2, (bottomleft.y()+bottomright.y())/2, bottomleft.x(), bottomleft.y());
+ gc.drawRect(bottomleft.x()-4, bottomleft.y()-4, 8, 8);
+ gc.drawLine(bottomleft.x(), bottomleft.y(), (topleft.x()+bottomleft.x())/2, (topleft.y()+bottomleft.y())/2);
+ gc.drawRect((topleft.x()+bottomleft.x())/2-4, (topleft.y()+bottomleft.y())/2-4, 8, 8);
+ gc.drawLine((topleft.x()+bottomleft.x())/2, (topleft.y()+bottomleft.y())/2, topleft.x(), topleft.y());
+ gc.drawRect((bottomleft.x()+bottomright.x()+topleft.x()+topright.x())/4-4, (bottomleft.y()+bottomright.y()+topleft.y()+topright.y())/4-4, 8, 8);
+ }
+ break;
+ }
+ gc.setRasterOp(op);
+ gc.setPen(old);
+ }
+}
+
+void KisToolPerspectiveTransform::transform()
+{
+ KisImageSP img = m_subject->currentImg();
+
+ if (!img || !img->activeDevice())
+ return;
+
+ KisProgressDisplayInterface *progress = m_subject->progressDisplay();
+
+ // This mementoes the current state of the active device.
+ PerspectiveTransformCmd * transaction = new PerspectiveTransformCmd(this, img->activeDevice(), m_origDevice,
+ m_topleft, m_topright, m_bottomleft, m_bottomright, m_origSelection, m_initialRect);
+
+ // Copy the original state back.
+ TQRect rc = m_origDevice->extent();
+ rc = rc.normalize();
+ img->activeDevice()->clear();
+ KisPainter gc(img->activeDevice());
+ gc.bitBlt(rc.x(), rc.y(), COMPOSITE_COPY, m_origDevice, rc.x(), rc.y(), rc.width(), rc.height());
+ gc.end();
+
+ // Also restore the original selection.
+ if(m_origSelection)
+ {
+ TQRect rc = m_origSelection->selectedRect();
+ rc = rc.normalize();
+ img->activeDevice()->selection()->clear();
+ KisPainter sgc(img->activeDevice()->selection().data());
+ sgc.bitBlt(rc.x(), rc.y(), COMPOSITE_COPY, m_origSelection.data(), rc.x(), rc.y(), rc.width(), rc.height());
+ sgc.end();
+ }
+ else
+ if(img->activeDevice()->hasSelection())
+ img->activeDevice()->selection()->clear();
+
+ // Perform the transform. Since we copied the original state back, this doesn't degrade
+ // after many tweaks. Since we started the transaction before the copy back, the memento
+ // has the previous state.
+ KisPerspectiveTransformWorker t(img->activeDevice(),m_topleft, m_topright, m_bottomleft, m_bottomright, progress);
+ t.run();
+
+ // If canceled, go back to the memento
+ if(t.isCanceled())
+ {
+ transaction->unexecute();
+ delete transaction;
+ return;
+ }
+
+ img->activeDevice()->setDirty(rc); // XXX: This is not enough - should union with new extent
+
+ // Else add the command -- this will have the memento from the previous state,
+ // and the transformed state from the original device we cached in our activated()
+ // method.
+ if (transaction) {
+ if (img->undo())
+ img->undoAdapter()->addCommand(transaction);
+ else
+ delete transaction;
+ }
+}
+
+void KisToolPerspectiveTransform::notifyCommandAdded( KCommand * command)
+{
+ PerspectiveTransformCmd * cmd = dynamic_cast<PerspectiveTransformCmd*>(command);
+ if (cmd == 0) {
+ // The last added command wasn't one of ours;
+ // we should reset to the new state of the canvas.
+ // In effect we should treat this as if the tool has been just activated
+ initHandles();
+ }
+}
+
+void KisToolPerspectiveTransform::notifyCommandExecuted( KCommand * command)
+{
+ Q_UNUSED(command);
+ PerspectiveTransformCmd * cmd=0;
+ if(m_subject->currentImg()->undoAdapter()->presentCommand())
+ cmd = dynamic_cast<PerspectiveTransformCmd*>(m_subject->currentImg()->undoAdapter()->presentCommand());
+
+ if (cmd == 0) {
+ // The command now on the top of the stack isn't one of ours
+ // We should treat this as if the tool has been just activated
+ initHandles();
+ }
+ else
+ {
+ // One of our commands is now on top
+ // We should ask for tool args and orig selection
+ m_origDevice = cmd->origDevice();
+ cmd->transformArgs(m_topleft, m_topright, m_bottomleft, m_bottomright);
+ m_origSelection = cmd->origSelection(m_initialRect);
+ m_subject->canvasController() ->updateCanvas();
+ }
+}
+
+void KisToolPerspectiveTransform::slotLayerActivated(KisLayerSP)
+{
+ activate();
+}
+
+
+TQWidget* KisToolPerspectiveTransform::createOptionWidget(TQWidget* /*tqparent*/)
+{
+#if 0
+ m_optWidget = new WdgToolPerspectiveTransform(tqparent);
+ Q_CHECK_PTR(m_optWidget);
+
+ m_optWidget->cmbFilter->clear();
+ m_optWidget->cmbFilter->setIDList(KisFilterStrategyRegistry::instance()->listKeys());
+
+ m_optWidget->cmbFilter->setCurrentText("Mitchell");
+ connect(m_optWidget->cmbFilter, TQT_SIGNAL(activated(const KisID &)),
+ this, TQT_SLOT(slotSetFilter(const KisID &)));
+
+ KisID filterID = m_optWidget->cmbFilter->currentItem();
+ m_filter = KisFilterStrategyRegistry::instance()->get(filterID);
+
+/*
+ connect(m_optWidget->intStartX, TQT_SIGNAL(valueChanged(int)), this, TQT_SLOT(setStartX(int)));
+ connect(m_optWidget->intStartY, TQT_SIGNAL(valueChanged(int)), this, TQT_SLOT(setStartY(int)));
+ connect(m_optWidget->intEndX, TQT_SIGNAL(valueChanged(int)), this, TQT_SLOT(setEndX(int)));
+ connect(m_optWidget->intEndY, TQT_SIGNAL(valueChanged(int)), this, TQT_SLOT(setEndY(int)));
+*/
+ m_optWidget->intStartX->hide();
+ m_optWidget->intStartY->hide();
+ m_optWidget->intEndX->hide();
+ m_optWidget->intEndY->hide();
+ m_optWidget->textLabel1->hide();
+ m_optWidget->textLabel2->hide();
+ m_optWidget->textLabel3->hide();
+ m_optWidget->textLabel4->hide();
+#endif
+ return 0;
+}
+
+TQWidget* KisToolPerspectiveTransform::optionWidget()
+{
+ return 0;
+}
+
+void KisToolPerspectiveTransform::setup(KActionCollection *collection)
+{
+ m_action = static_cast<KRadioAction *>(collection->action(name()));
+
+ if (m_action == 0) {
+ m_action = new KRadioAction(i18n("&Perspective Transform"),
+ "tool_perspectivetransform",
+ 0,
+ this,
+ TQT_SLOT(activate()),
+ collection,
+ name());
+ Q_CHECK_PTR(m_action);
+ m_action->setToolTip(i18n("Perspective transform a layer or a selection"));
+ m_action->setExclusiveGroup("tools");
+ m_ownAction = true;
+ }
+}
+
+#include "kis_tool_perspectivetransform.moc"
diff --git a/chalk/plugins/tools/tool_perspectivetransform/kis_tool_perspectivetransform.h b/chalk/plugins/tools/tool_perspectivetransform/kis_tool_perspectivetransform.h
new file mode 100644
index 00000000..5d637ae5
--- /dev/null
+++ b/chalk/plugins/tools/tool_perspectivetransform/kis_tool_perspectivetransform.h
@@ -0,0 +1,131 @@
+/*
+ * kis_tool_transform.h - part of Chalk
+ *
+ * Copyright (c) 2006 Cyrille Berger <cberger@cberger.net>
+ *
+ * Based on the transform tool from :
+ * Copyright (c) 2004 Boudewijn Rempt <boud@valdyas.org>
+ * Copyright (c) 2005 Casper Boemann <cbr@boemann.dk>
+ *
+ * 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; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef KIS_TOOL_PERSPECTIVETRANSFORM_H_
+#define KIS_TOOL_PERSPECTIVETRANSFORM_H_
+
+#include <tqpoint.h>
+
+#include <kis_layer.h>
+#include <kis_point.h>
+#include <kis_tool_non_paint.h>
+#include <kis_tool_factory.h>
+#include <kis_undo_adapter.h>
+#include <kis_perspective_math.h>
+
+class KisTransaction;
+class WdgToolPerspectiveTransform;
+class KisID;
+class KisFilterStrategy;
+
+/**
+ * PerspectiveTransform tool
+ *
+ */
+class KisToolPerspectiveTransform : public KisToolNonPaint, KisCommandHistoryListener {
+
+ typedef KisToolNonPaint super;
+ Q_OBJECT
+ TQ_OBJECT
+ enum InterractionMode { DRAWRECTINTERRACTION, EDITRECTINTERRACTION };
+ enum HandleSelected { NOHANDLE, TOPHANDLE, BOTTOMHANDLE, RIGHTHANDLE, LEFTHANDLE, MIDDLEHANDLE };
+public:
+ KisToolPerspectiveTransform();
+ virtual ~KisToolPerspectiveTransform();
+
+ virtual TQWidget* createOptionWidget(TQWidget* tqparent);
+ virtual TQWidget* optionWidget();
+
+ virtual void setup(KActionCollection *collection);
+ virtual enumToolType toolType() { return TOOL_TRANSFORM; }
+ virtual TQ_UINT32 priority() { return 4; }
+ virtual void paint(KisCanvasPainter& gc);
+ virtual void paint(KisCanvasPainter& gc, const TQRect& rc);
+ virtual void buttonPress(KisButtonPressEvent *e);
+ virtual void move(KisMoveEvent *e);
+ virtual void buttonRelease(KisButtonReleaseEvent *e);
+ void paintOutline();
+
+public:
+
+ void notifyCommandAdded(KCommand *);
+ void notifyCommandExecuted(KCommand *);
+
+public:
+ virtual void deactivate();
+
+private:
+
+ bool mouseNear(const TQPoint& mousep, const TQPoint point);
+ void paintOutline(KisCanvasPainter& gc, const TQRect& rc);
+ void transform();
+ void initHandles();
+
+private slots:
+ void slotLayerActivated(KisLayerSP);
+
+protected slots:
+ virtual void activate();
+
+private:
+ bool m_dragging;
+ InterractionMode m_interractionMode;
+ TQRect m_initialRect;
+ KisPoint m_dragStart, m_dragEnd;
+ KisPoint m_topleft, m_topright, m_bottomleft, m_bottomright;
+ KisPoint* m_currentSelectedPoint;
+ bool m_actualyMoveWhileSelected;
+
+ WdgToolPerspectiveTransform *m_optWidget;
+
+ KisPaintDeviceSP m_origDevice;
+ KisSelectionSP m_origSelection;
+ int m_handleHalfSize, m_handleSize;
+
+ // The following variables are used in during the draw rect interraction mode
+ typedef TQValueVector<KisPoint> KisPointVector;
+ KisPointVector m_points;
+ // The following variables are used when moving a middle handle
+ HandleSelected m_handleSelected;
+
+};
+
+class KisToolPerspectiveTransformFactory : public KisToolFactory {
+ typedef KisToolFactory super;
+
+public:
+ KisToolPerspectiveTransformFactory() : super() {};
+ virtual ~KisToolPerspectiveTransformFactory(){};
+
+ virtual KisTool * createTool(KActionCollection * ac) {
+ KisTool * t = new KisToolPerspectiveTransform();
+ Q_CHECK_PTR(t);
+ t->setup(ac); return t;
+ }
+ virtual KisID id() { return KisID("perspective transform", i18n("Perspective transform Tool")); }
+};
+
+
+
+#endif // KIS_TOOL_TRANSFORM_H_
+
diff --git a/chalk/plugins/tools/tool_perspectivetransform/tool_perspectivetransform.cc b/chalk/plugins/tools/tool_perspectivetransform/tool_perspectivetransform.cc
new file mode 100644
index 00000000..2c3c85d4
--- /dev/null
+++ b/chalk/plugins/tools/tool_perspectivetransform/tool_perspectivetransform.cc
@@ -0,0 +1,63 @@
+/*
+ * tool_perspectivetransform.cc -- Part of Chalk
+ *
+ * Copyright (c) 2006 Cyrille Berger <cberger@cberger.net>
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+#include <stdlib.h>
+#include <vector>
+
+#include <tqpoint.h>
+
+#include <klocale.h>
+#include <kiconloader.h>
+#include <kinstance.h>
+#include <kmessagebox.h>
+#include <kstandarddirs.h>
+#include <kdebug.h>
+#include <kgenericfactory.h>
+
+#include <kis_global.h>
+#include <kis_types.h>
+#include <kis_tool_registry.h>
+
+#include "tool_perspectivetransform.h"
+#include "kis_tool_perspectivetransform.h"
+
+
+typedef KGenericFactory<ToolPerspectiveTransform> ToolPerspectiveTransformFactory;
+K_EXPORT_COMPONENT_FACTORY( chalktoolperspectivetransform, ToolPerspectiveTransformFactory( "chalk" ) )
+
+
+ToolPerspectiveTransform::ToolPerspectiveTransform(TQObject *tqparent, const char *name, const TQStringList &)
+ : KParts::Plugin(tqparent, name)
+{
+ setInstance(ToolPerspectiveTransformFactory::instance());
+
+ if ( tqparent->inherits("KisToolRegistry") )
+ {
+ kdDebug() << " add perspective transform tool to the registry" << endl;
+ KisToolRegistry * r = dynamic_cast<KisToolRegistry*>(tqparent);
+ r->add(new KisToolPerspectiveTransformFactory());
+ }
+
+}
+
+ToolPerspectiveTransform::~ToolPerspectiveTransform()
+{
+}
+
+#include "tool_perspectivetransform.moc"
diff --git a/chalk/plugins/tools/tool_perspectivetransform/tool_perspectivetransform.h b/chalk/plugins/tools/tool_perspectivetransform/tool_perspectivetransform.h
new file mode 100644
index 00000000..1cbeadee
--- /dev/null
+++ b/chalk/plugins/tools/tool_perspectivetransform/tool_perspectivetransform.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2006 Cyrille Berger <cberger@cberger.net>
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef TOOL_PERSPECTIVE_TRANSFORM_H_
+#define TOOL_PERSPECTIVE_TRANSFORM_H_
+
+#include <kparts/plugin.h>
+
+class KisView;
+
+/**
+ * A module that provides a tool for doinge perspective transformation.
+ */
+class ToolPerspectiveTransform : public KParts::Plugin
+{
+ Q_OBJECT
+ TQ_OBJECT
+public:
+ ToolPerspectiveTransform(TQObject *tqparent, const char *name, const TQStringList &);
+ virtual ~ToolPerspectiveTransform();
+
+private:
+
+ KisView * m_view;
+
+};
+
+#endif // TOOL_PERSPECTIVE_TRANSFORM_H_
diff --git a/chalk/plugins/tools/tool_perspectivetransform/tool_perspectivetransform.png b/chalk/plugins/tools/tool_perspectivetransform/tool_perspectivetransform.png
new file mode 100644
index 00000000..c64d09eb
--- /dev/null
+++ b/chalk/plugins/tools/tool_perspectivetransform/tool_perspectivetransform.png
Binary files differ
diff --git a/chalk/plugins/tools/tool_perspectivetransform/tool_perspectivetransform.svg b/chalk/plugins/tools/tool_perspectivetransform/tool_perspectivetransform.svg
new file mode 100644
index 00000000..3dd79413
--- /dev/null
+++ b/chalk/plugins/tools/tool_perspectivetransform/tool_perspectivetransform.svg
@@ -0,0 +1,87 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://web.resource.org/cc/"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://inkscape.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="22"
+ height="22"
+ id="svg2"
+ sodipodi:version="0.32"
+ inkscape:version="0.43"
+ version="1.0"
+ sodipodi:docbase="/home/cyrille/koffice-1.6/chalk/plugins/tools/tool_perspectivegrid"
+ sodipodi:docname="tool_perspectivegrid.svg"
+ inkscape:export-filename="/home/cyrille/koffice-1.6/chalk/plugins/tools/tool_perspectivegrid/tool_perspectivegrid.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <defs
+ id="defs4" />
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="9.8597476"
+ inkscape:cx="12.855376"
+ inkscape:cy="7.6671075"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ inkscape:window-width="749"
+ inkscape:window-height="540"
+ inkscape:window-x="424"
+ inkscape:window-y="433" />
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1">
+ <path
+ style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#909090;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="M 4.8682788,20.580085 C 6.5924609,1.3098151 6.7953058,1.5126601 6.7953058,1.5126601 L 6.7953058,1.5126601 L 6.7953058,1.5126601"
+ id="path2183" />
+ <path
+ style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#909090;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="M 11.359317,18.551636 C 10.446515,2.3240399 10.446515,2.3240399 10.446515,2.3240399 L 10.446515,2.3240399 L 10.446515,2.3240399"
+ id="path2185" />
+ <path
+ style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#909090;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="M 17.444666,17.131721 C 13.894879,3.1354197 13.894879,3.1354197 13.894879,3.1354197"
+ id="path2187" />
+ <path
+ style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#909090;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="M 2.7384068,4.7581793 C 17.647511,6.5837838 17.546088,6.5837838 17.546088,6.5837838"
+ id="path2191" />
+ <path
+ style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#909090;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="M 2.0284495,10.742105 C 18.256045,9.7278805 18.86458,9.1193456 18.86458,9.1193456"
+ id="path2193"
+ sodipodi:nodetypes="cc" />
+ <path
+ style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#909090;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="M 1.0142247,17.131721 C 20.08165,12.56771 20.08165,12.364865 20.08165,12.364865"
+ id="path2195"
+ sodipodi:nodetypes="cc" />
+ <path
+ style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="M 3.1440967,0.59985768 L 16.531864,3.6425319 L 21.70441,15.813228 L 0.50711235,21.594309 L 3.1440967,0.59985768 z "
+ id="rect1307"
+ sodipodi:nodetypes="ccccc" />
+ </g>
+</svg>
diff --git a/chalk/plugins/tools/tool_polygon/Makefile.am b/chalk/plugins/tools/tool_polygon/Makefile.am
new file mode 100644
index 00000000..66f4d403
--- /dev/null
+++ b/chalk/plugins/tools/tool_polygon/Makefile.am
@@ -0,0 +1,36 @@
+kde_services_DATA = chalktoolpolygon.desktop
+
+# all_includes must remain last!
+INCLUDES = -I$(srcdir)/../../../sdk \
+ -I$(srcdir)/../../../core \
+ -I$(srcdir)/../../../chalkcolor/ \
+ -I$(srcdir)/../../../ui \
+ -I$/../../../ui \
+ $(KOFFICE_INCLUDES) \
+ $(all_includes)
+
+chalktoolpolygon_la_SOURCES = \
+ tool_polygon.cc \
+ kis_tool_polygon.cc
+
+# Install this plugin in the KDE modules directory
+kde_module_LTLIBRARIES = chalktoolpolygon.la
+
+noinst_HEADERS = \
+ tool_polygon.h \
+ kis_tool_polygon.h
+
+chalktoolpolygon_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) $(LIB_QT) -lkdecore -lkdeui -lkjs -lkdefx -lkio -lkparts -L../../../../chalk/chalkcolor/.libs -lchalkcolor -L../../../../chalk/core/.libs -lchalkimage \
+ -L../../../../chalk/ui/.libs -lchalkui
+chalktoolpolygon_la_LIBADD = ../../../libchalkcommon.la
+
+chalktoolpolygon_la_METASOURCES = AUTO
+
+KDE_OPTIONS = nofinal
+
+chalkpics_DATA = \
+ tool_polygon_cursor.png \
+ tool_polygon.png
+
+chalkpicsdir = $(kde_datadir)/chalk/pics
+
diff --git a/chalk/plugins/tools/tool_polygon/chalktoolpolygon.desktop b/chalk/plugins/tools/tool_polygon/chalktoolpolygon.desktop
new file mode 100644
index 00000000..2b981e8f
--- /dev/null
+++ b/chalk/plugins/tools/tool_polygon/chalktoolpolygon.desktop
@@ -0,0 +1,52 @@
+[Desktop Entry]
+Name=Polygon Tool
+Name[bg]=Инструмент многоъгълник
+Name[br]=Ostilh liestueg
+Name[ca]=Eina de polígon
+Name[cy]=Erfyn Polygon
+Name[da]=Polygonværktøj
+Name[de]=Vieleck-Werkzeug
+Name[el]=Εργαλείο πολυγώνου
+Name[eo]=Poligon-ilo
+Name[es]=Herramienta Polígono
+Name[et]=Hulknurga tööriist
+Name[eu]=Poligonoa tresna
+Name[fa]=ابزار چندضلعی
+Name[fi]=Monikulmiotyökalu
+Name[fr]=Outil polygone
+Name[fy]=Meardere-hoek-ark
+Name[ga]=Uirlis Pholagáin
+Name[gl]=Ferramenta de Polígonos
+Name[he]=כלי מצולע
+Name[hu]=Sokszög eszköz
+Name[is]=Marghyrnitól
+Name[it]=Strumento poligono
+Name[ja]=多角形ツール
+Name[km]=ឧបករណ៍​រាង​ពហុកោណ
+Name[lt]=Daugiakampio įrankis
+Name[lv]=Poligonu rīks
+Name[ms]=Alat Poligon
+Name[nb]=Verktøy for mangekanter
+Name[nds]=Veeleck-Warktüüch
+Name[ne]=बहुभुज उपकरण
+Name[nl]=Veelhoeksgereedschap
+Name[nn]=Verktøy for mangekant
+Name[pl]=Narzędzie do rysowania wielokątów
+Name[pt]=Ferramenta de Polígonos
+Name[pt_BR]=Ferramenta Polígono
+Name[ru]=Многоугольник
+Name[se]=Moanáčiegareaidu
+Name[sk]=Mnohouholník
+Name[sl]=Orodje za poligon
+Name[sr]=Алат за полигоне
+Name[sr@Latn]=Alat za poligone
+Name[sv]=Polygonverktyg
+Name[uk]=Засіб багатокутника
+Name[uz]=Pligon vositasi
+Name[uz@cyrillic]=Плигон воситаси
+Name[zh_CN]=多边形工具
+Name[zh_TW]=多邊形工具
+ServiceTypes=Chalk/Tool
+Type=Service
+X-KDE-Library=chalktoolpolygon
+X-Chalk-Version=2
diff --git a/chalk/plugins/tools/tool_polygon/kis_tool_polygon.cc b/chalk/plugins/tools/tool_polygon/kis_tool_polygon.cc
new file mode 100644
index 00000000..dba84042
--- /dev/null
+++ b/chalk/plugins/tools/tool_polygon/kis_tool_polygon.cc
@@ -0,0 +1,252 @@
+/*
+ * kis_tool_polygon.cc -- part of Chalk
+ *
+ * Copyright (c) 2004 Michael Thaler <michael.thaler@physik.tu-muenchen.de>
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+
+#include <math.h>
+
+#include <tqpainter.h>
+#include <tqspinbox.h>
+
+#include <kaction.h>
+#include <kdebug.h>
+#include <klocale.h>
+#include <kdebug.h>
+#include <knuminput.h>
+
+#include "kis_doc.h"
+#include "kis_view.h"
+#include "kis_painter.h"
+#include "kis_canvas_subject.h"
+#include "kis_canvas_controller.h"
+#include "kis_button_press_event.h"
+#include "kis_button_release_event.h"
+#include "kis_move_event.h"
+#include "kis_paintop_registry.h"
+#include "kis_canvas.h"
+#include "kis_canvas_painter.h"
+#include "kis_cursor.h"
+
+#include "kis_tool_polygon.h"
+
+KisToolPolygon::KisToolPolygon()
+ : super(i18n ("Polygon")),
+ m_dragging (false),
+ m_currentImage (0)
+{
+ setName("tool_polygon");
+ setCursor(KisCursor::load("tool_polygon_cursor.png", 6, 6));
+}
+
+KisToolPolygon::~KisToolPolygon()
+{
+}
+
+void KisToolPolygon::update (KisCanvasSubject *subject)
+{
+ super::update (subject);
+ if (m_subject)
+ m_currentImage = m_subject->currentImg ();
+}
+
+void KisToolPolygon::buttonPress(KisButtonPressEvent *event)
+{
+ if (m_currentImage) {
+ if (event->button() == Qt::LeftButton && event->state() != ShiftButton) {
+
+ m_dragging = true;
+
+ if (m_points.isEmpty())
+ {
+ m_dragStart = event->pos();
+ m_dragEnd = event->pos();
+ m_points.append(m_dragStart);
+ } else {
+ m_dragStart = m_dragEnd;
+ m_dragEnd = event->pos();
+ draw();
+ }
+ } else if (event->button() == Qt::LeftButton && event->state() == ShiftButton) {
+ finish();
+ }
+ }
+}
+
+void KisToolPolygon::finish()
+{
+ // erase old lines on canvas
+ draw();
+ m_dragging = false;
+
+ KisPaintDeviceSP device = m_currentImage->activeDevice ();
+ if (!device) return;
+
+ KisPainter painter (device);
+ if (m_currentImage->undo()) painter.beginTransaction (i18n ("Polygon"));
+
+ painter.setPaintColor(m_subject->fgColor());
+ painter.setBackgroundColor(m_subject->bgColor());
+ painter.setFillStyle(fillStyle());
+ painter.setBrush(m_subject->currentBrush());
+ painter.setPattern(m_subject->currentPattern());
+ painter.setOpacity(m_opacity);
+ painter.setCompositeOp(m_compositeOp);
+ KisPaintOp * op = KisPaintOpRegistry::instance()->paintOp(m_subject->currentPaintop(), m_subject->currentPaintopSettings(), &painter);
+ painter.setPaintOp(op); // Painter takes ownership
+
+ painter.paintPolygon(m_points);
+
+ m_points.clear();
+
+ device->setDirty( painter.dirtyRect() );
+ notifyModified();
+
+ if (m_currentImage->undo()) {
+ m_currentImage->undoAdapter()->addCommand(painter.endTransaction());
+ }
+}
+
+void KisToolPolygon::doubleClick( KisDoubleClickEvent * )
+{
+ finish();
+}
+
+void KisToolPolygon::move(KisMoveEvent *event)
+{
+ if (m_dragging) {
+ // erase old lines on canvas
+ draw();
+ // get current mouse position
+ m_dragEnd = event->pos();
+ // draw new lines on canvas
+ draw();
+ }
+}
+
+void KisToolPolygon::buttonRelease(KisButtonReleaseEvent *event)
+{
+ if (!m_subject || !m_currentImage)
+ return;
+
+ if (m_dragging && event->button() == Qt::LeftButton) {
+ m_dragging = false;
+ m_points.append (m_dragEnd);
+ }
+
+ if (m_dragging && event->button() == Qt::RightButton) {
+
+ }
+}
+
+void KisToolPolygon::paint(KisCanvasPainter& gc)
+{
+ draw(gc);
+}
+
+void KisToolPolygon::paint(KisCanvasPainter& gc, const TQRect&)
+{
+ draw(gc);
+}
+
+void KisToolPolygon::draw()
+{
+ if (m_subject) {
+ KisCanvasController *controller = m_subject->canvasController();
+ KisCanvas *canvas = controller->kiscanvas();
+ KisCanvasPainter gc(canvas);
+
+ draw(gc);
+ }
+}
+
+void KisToolPolygon::draw(KisCanvasPainter& gc)
+{
+ if (!m_subject || !m_currentImage)
+ return;
+
+ TQPen pen(TQt::white, 0, TQt::SolidLine);
+
+ gc.setPen(pen);
+ gc.setRasterOp(TQt::XorROP);
+
+ KisCanvasController *controller = m_subject->canvasController();
+ KisPoint start, end;
+ TQPoint startPos;
+ TQPoint endPos;
+
+ if (m_dragging) {
+ startPos = controller->windowToView(m_dragStart.floorTQPoint());
+ endPos = controller->windowToView(m_dragEnd.floorTQPoint());
+ gc.drawLine(startPos, endPos);
+ } else {
+ for (KisPointVector::iterator it = m_points.begin(); it != m_points.end(); ++it) {
+
+ if (it == m_points.begin())
+ {
+ start = (*it);
+ } else {
+ end = (*it);
+
+ startPos = controller->windowToView(start.floorTQPoint());
+ endPos = controller->windowToView(end.floorTQPoint());
+
+ gc.drawLine(startPos, endPos);
+
+ start = end;
+ }
+ }
+ }
+}
+
+
+
+void KisToolPolygon::setup(KActionCollection *collection)
+{
+ m_action = static_cast<KRadioAction *>(collection->action(name()));
+
+ if (m_action == 0) {
+ KShortcut shortcut(TQt::Key_Plus);
+ shortcut.append(KShortcut(TQt::Key_F9));
+ m_action = new KRadioAction(i18n("&Polygon"),
+ "tool_polygon",
+ shortcut,
+ this,
+ TQT_SLOT(activate()),
+ collection,
+ name());
+ Q_CHECK_PTR(m_action);
+
+ m_action->setToolTip(i18n("Draw a polygon. Shift-mouseclick ends the polygon."));
+ m_action->setExclusiveGroup("tools");
+ m_ownAction = true;
+ }
+}
+
+void KisToolPolygon::keyPress(TQKeyEvent *e)
+{
+ if (e->key()==TQt::Key_Escape) {
+ // erase old lines on canvas
+ draw();
+ m_dragging = false;
+ m_points.clear();
+ }
+}
+
+
+#include "kis_tool_polygon.moc"
diff --git a/chalk/plugins/tools/tool_polygon/kis_tool_polygon.h b/chalk/plugins/tools/tool_polygon/kis_tool_polygon.h
new file mode 100644
index 00000000..9be3f324
--- /dev/null
+++ b/chalk/plugins/tools/tool_polygon/kis_tool_polygon.h
@@ -0,0 +1,102 @@
+/*
+ * kis_tool_polygon.h - part of Chalk
+ *
+ * Copyright (c) 2004 Michael Thaler <michael Thaler@physik.tu-muenchen.de>
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef KIS_TOOL_POLYGON_H_
+#define KIS_TOOL_POLYGON_H_
+
+#include <tqvaluevector.h>
+
+#include "kis_tool_shape.h"
+
+class KisCanvas;
+class KisDoc;
+class KisPainter;
+class KisView;
+class KisRect;
+
+class KisToolPolygon : public KisToolShape {
+
+ typedef KisToolShape super;
+ Q_OBJECT
+ TQ_OBJECT
+
+public:
+ KisToolPolygon();
+ virtual ~KisToolPolygon();
+
+ //
+ // KisCanvasObserver interface
+ //
+
+ virtual void update (KisCanvasSubject *subject);
+
+ //
+ // KisToolPaint interface
+ //
+
+ virtual void setup(KActionCollection *collection);
+ virtual enumToolType toolType() { return TOOL_SHAPE; }
+ virtual TQ_UINT32 priority() { return 4; }
+ virtual void buttonPress(KisButtonPressEvent *event);
+ virtual void move(KisMoveEvent *event);
+ virtual void buttonRelease(KisButtonReleaseEvent *event);
+ virtual TQString quickHelp() const {
+ return i18n("Shift-click will end the polygon.");
+ }
+ virtual void doubleClick(KisDoubleClickEvent * event);
+
+protected:
+ virtual void paint(KisCanvasPainter& gc);
+ virtual void paint(KisCanvasPainter& gc, const TQRect& rc);
+ void draw(KisCanvasPainter& gc);
+ void draw();
+ void finish();
+ virtual void keyPress(TQKeyEvent *e);
+protected:
+ KisPoint m_dragStart;
+ KisPoint m_dragEnd;
+
+ bool m_dragging;
+ KisImageSP m_currentImage;
+private:
+ typedef TQValueVector<KisPoint> KisPointVector;
+ KisPointVector m_points;
+};
+
+
+#include "kis_tool_factory.h"
+
+class KisToolPolygonFactory : public KisToolFactory {
+ typedef KisToolFactory super;
+public:
+ KisToolPolygonFactory() : super() {};
+ virtual ~KisToolPolygonFactory(){};
+
+ virtual KisTool * createTool(KActionCollection * ac) {
+ KisTool * t = new KisToolPolygon();
+ Q_CHECK_PTR(t);
+ t->setup(ac);
+ return t;
+ }
+ virtual KisID id() { return KisID("polygon", i18n("Polygon Tool")); }
+};
+
+
+#endif //__KIS_TOOL_POLYGON_H__
diff --git a/chalk/plugins/tools/tool_polygon/tool_polygon.cc b/chalk/plugins/tools/tool_polygon/tool_polygon.cc
new file mode 100644
index 00000000..3dbd15d6
--- /dev/null
+++ b/chalk/plugins/tools/tool_polygon/tool_polygon.cc
@@ -0,0 +1,62 @@
+/*
+ * tool_polygon.cc -- Part of Chalk
+ *
+ * Copyright (c) 2004 Michael Thaler <michael.thaler@physik.tu-muenchen.de>
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+#include <stdlib.h>
+#include <vector>
+
+#include <tqpoint.h>
+
+#include <klocale.h>
+#include <kiconloader.h>
+#include <kinstance.h>
+#include <kmessagebox.h>
+#include <kstandarddirs.h>
+#include <kdebug.h>
+#include <kgenericfactory.h>
+
+#include <kis_global.h>
+#include <kis_types.h>
+#include <kis_tool_registry.h>
+#include "tool_polygon.h"
+#include "tool_polygon.moc"
+#include "kis_tool_polygon.h"
+
+
+typedef KGenericFactory<ToolPolygon> ToolPolygonFactory;
+K_EXPORT_COMPONENT_FACTORY( chalktoolpolygon, ToolPolygonFactory( "chalk" ) )
+
+
+ToolPolygon::ToolPolygon(TQObject *tqparent, const char *name, const TQStringList &)
+ : KParts::Plugin(tqparent, name)
+{
+ setInstance(ToolPolygonFactory::instance());
+
+ if ( tqparent->inherits("KisToolRegistry") )
+ {
+ KisToolRegistry * r = dynamic_cast<KisToolRegistry*>( tqparent );
+ r->add(new KisToolPolygonFactory());
+ }
+
+}
+
+ToolPolygon::~ToolPolygon()
+{
+}
+
+//#include "tool_polygon.moc"
diff --git a/chalk/plugins/tools/tool_polygon/tool_polygon.h b/chalk/plugins/tools/tool_polygon/tool_polygon.h
new file mode 100644
index 00000000..ec816736
--- /dev/null
+++ b/chalk/plugins/tools/tool_polygon/tool_polygon.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2004 Michael Thaler <michael.thaler@physik.tu-muenchen.de>
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef TOOL_POLYGON_H_
+#define TOOL_POLYGON_H_
+
+#include <kparts/plugin.h>
+
+/**
+ * A module that provides a polygon tool.
+ */
+class ToolPolygon : public KParts::Plugin
+{
+ Q_OBJECT
+ TQ_OBJECT
+
+public:
+
+ ToolPolygon(TQObject *tqparent, const char *name, const TQStringList &);
+ virtual ~ToolPolygon();
+
+};
+
+#endif // TOOL_POLYGON_H_
diff --git a/chalk/plugins/tools/tool_polygon/tool_polygon.png b/chalk/plugins/tools/tool_polygon/tool_polygon.png
new file mode 100644
index 00000000..654083c6
--- /dev/null
+++ b/chalk/plugins/tools/tool_polygon/tool_polygon.png
Binary files differ
diff --git a/chalk/plugins/tools/tool_polygon/tool_polygon_cursor.png b/chalk/plugins/tools/tool_polygon/tool_polygon_cursor.png
new file mode 100644
index 00000000..bca4bffd
--- /dev/null
+++ b/chalk/plugins/tools/tool_polygon/tool_polygon_cursor.png
Binary files differ
diff --git a/chalk/plugins/tools/tool_polyline/Makefile.am b/chalk/plugins/tools/tool_polyline/Makefile.am
new file mode 100644
index 00000000..39b9ebf6
--- /dev/null
+++ b/chalk/plugins/tools/tool_polyline/Makefile.am
@@ -0,0 +1,36 @@
+kde_services_DATA = chalktoolpolyline.desktop
+
+# all_includes must remain last!
+INCLUDES = -I$(srcdir)/../../../sdk \
+ -I$(srcdir)/../../../core \
+ -I$(srcdir)/../../../chalkcolor/ \
+ -I$(srcdir)/../../../ui \
+ -I$/../../../ui \
+ $(KOFFICE_INCLUDES) \
+ $(all_includes)
+
+chalktoolpolyline_la_SOURCES = \
+ tool_polyline.cc \
+ kis_tool_polyline.cc
+
+# Install this plugin in the KDE modules directory
+kde_module_LTLIBRARIES = chalktoolpolyline.la
+
+noinst_HEADERS = \
+ tool_polyline.h \
+ kis_tool_polyline.h
+
+chalktoolpolyline_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) $(LIB_QT) -lkdecore -lkdeui -lkjs -lkdefx -lkio -lkparts -L../../../../chalk/chalkcolor/.libs -lchalkcolor -L../../../../chalk/core/.libs -lchalkimage \
+ -L../../../../chalk/ui/.libs -lchalkui
+chalktoolpolyline_la_LIBADD = ../../../libchalkcommon.la
+
+chalktoolpolyline_la_METASOURCES = AUTO
+
+KDE_OPTIONS = nofinal
+
+chalkpics_DATA = \
+ tool_polyline_cursor.png \
+ polyline.png
+
+chalkpicsdir = $(kde_datadir)/chalk/pics
+
diff --git a/chalk/plugins/tools/tool_polyline/chalktoolpolyline.desktop b/chalk/plugins/tools/tool_polyline/chalktoolpolyline.desktop
new file mode 100644
index 00000000..0c9c2be1
--- /dev/null
+++ b/chalk/plugins/tools/tool_polyline/chalktoolpolyline.desktop
@@ -0,0 +1,49 @@
+[Desktop Entry]
+Name=Polyline Tool
+Name[bg]=Инструмент съставна линия
+Name[br]=Ostilh lieslinenn
+Name[ca]=Eina de polilínia
+Name[cy]=Erfyn Polylinell
+Name[da]=Flerlinjeværktøj
+Name[de]=Linienketten-Werkzeug
+Name[el]=Εργαλείο συνεχούς γραμμής
+Name[eo]=Plurlinio-ilo
+Name[es]=Herramienta Polilínea
+Name[et]=Kompleksjoone tööriist
+Name[eu]=Polilerroa tresna
+Name[fa]=ابزار چندخطی
+Name[fr]=Outil lignes multiples
+Name[fy]=Brútsen-streek-ark
+Name[ga]=Uirlis Il-líne
+Name[gl]=Ferramenta de Liñas Poligonais
+Name[he]=כלי קו שבור
+Name[hu]=Sokszögvonal eszköz
+Name[is]=Fjöllínutól
+Name[it]=Strumento polilinea
+Name[ja]=ポリラインツール
+Name[km]=ឧបករណ៍​ពហុបន្ទាត់
+Name[ms]=Alat Poligaris
+Name[nb]=Verktøy for flerstrekslinje
+Name[nds]=Lienenkeden-Warktüüch (Polygon-Tog)
+Name[ne]=बहुरेखा उपकरण
+Name[nl]=Gebroken-lijngereedschap
+Name[nn]=Verktøy for fleirstrekslinje
+Name[pl]=Narzędzie do rysowania łamanej
+Name[pt]=Ferramenta de Linhas Poligonais
+Name[pt_BR]=Ferramenta Poli-linha
+Name[ru]=Ломаная
+Name[se]=Moanálinnjáreaidu
+Name[sk]=Lomená čiara
+Name[sl]=Orodje za lomljeno črto
+Name[sr]=Алат за полилиније
+Name[sr@Latn]=Alat za polilinije
+Name[sv]=Flerlinjesverktyg
+Name[uk]=Засіб ламаної лінії
+Name[uz]=Koʻpburchak asbobi
+Name[uz@cyrillic]=Кўпбурчак асбоби
+Name[zh_CN]=折线工具
+Name[zh_TW]=任意線工具
+ServiceTypes=Chalk/Tool
+Type=Service
+X-KDE-Library=chalktoolpolyline
+X-Chalk-Version=2
diff --git a/chalk/plugins/tools/tool_polyline/kis_tool_polyline.cc b/chalk/plugins/tools/tool_polyline/kis_tool_polyline.cc
new file mode 100644
index 00000000..4fab06e7
--- /dev/null
+++ b/chalk/plugins/tools/tool_polyline/kis_tool_polyline.cc
@@ -0,0 +1,271 @@
+/*
+ * kis_tool_polyline.cc -- part of Chalk
+ *
+ * Copyright (c) 2004 Michael Thaler <michael.thaler@physik.tu-muenchen.de>
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+
+#include <math.h>
+
+#include <tqpainter.h>
+#include <tqspinbox.h>
+
+#include <kaction.h>
+#include <kdebug.h>
+#include <klocale.h>
+#include <kdebug.h>
+#include <knuminput.h>
+
+#include "kis_doc.h"
+#include "kis_view.h"
+#include "kis_painter.h"
+#include "kis_canvas_subject.h"
+#include "kis_canvas_controller.h"
+#include "kis_button_press_event.h"
+#include "kis_button_release_event.h"
+#include "kis_move_event.h"
+#include "kis_paintop_registry.h"
+#include "kis_canvas.h"
+#include "kis_canvas_painter.h"
+#include "kis_cursor.h"
+
+#include "kis_tool_polyline.h"
+
+KisToolPolyline::KisToolPolyline()
+ : super(i18n ("Polyline")),
+ m_dragging (false),
+ m_currentImage (0)
+{
+ setName("tool_polyline");
+ setCursor(KisCursor::load("tool_polyline_cursor.png", 6, 6));
+}
+
+KisToolPolyline::~KisToolPolyline()
+{
+}
+
+void KisToolPolyline::update (KisCanvasSubject *subject)
+{
+ super::update (subject);
+ if (m_subject)
+ m_currentImage = m_subject->currentImg ();
+}
+
+void KisToolPolyline::buttonPress(KisButtonPressEvent *event)
+{
+ if (m_currentImage) {
+ if (event->button() == Qt::LeftButton && event->state() != TQt::ShiftButton ) {
+
+ m_dragging = true;
+
+ if (m_points.isEmpty())
+ {
+ m_dragStart = event->pos();
+ m_dragEnd = event->pos();
+ m_points.append(m_dragStart);
+ } else {
+ m_dragStart = m_dragEnd;
+ m_dragEnd = event->pos();
+ draw();
+ }
+ } else if (event->button() == Qt::LeftButton && event->state() == TQt::ShiftButton ) {
+ finish();
+ }
+ }
+}
+
+void KisToolPolyline::deactivate()
+{
+ draw();
+ m_points.clear();
+ m_dragging = false;
+}
+
+void KisToolPolyline::finish()
+{
+ // erase old lines on canvas
+ draw();
+ m_dragging = false;
+
+ KisPaintDeviceSP device = m_currentImage->activeDevice ();
+ if (!device) return;
+
+ KisPainter painter (device);
+ if (m_currentImage->undo()) painter.beginTransaction (i18n ("Polyline"));
+
+ painter.setPaintColor(m_subject->fgColor());
+ painter.setBrush(m_subject->currentBrush());
+ painter.setOpacity(m_opacity);
+ painter.setCompositeOp(m_compositeOp);
+ KisPaintOp * op = KisPaintOpRegistry::instance()->paintOp(m_subject->currentPaintop(), m_subject->currentPaintopSettings(), &painter);
+ painter.setPaintOp(op); // Painter takes ownership
+
+ KisPoint start,end;
+ KisPointVector::iterator it;
+ for( it = m_points.begin(); it != m_points.end(); ++it )
+ {
+ if( it == m_points.begin() )
+ {
+ start = (*it);
+ } else {
+ end = (*it);
+ painter.paintLine(start, PRESSURE_DEFAULT, 0, 0, end, PRESSURE_DEFAULT, 0, 0);
+ start = end;
+ }
+ }
+ m_points.clear();
+
+ device->setDirty( painter.dirtyRect() );
+ notifyModified();
+
+ if (m_currentImage->undo()) {
+ m_currentImage->undoAdapter()->addCommand(painter.endTransaction());
+ }
+
+}
+void KisToolPolyline::move(KisMoveEvent *event)
+{
+ if (m_dragging) {
+ // erase old lines on canvas
+ draw();
+ // get current mouse position
+ m_dragEnd = event->pos();
+ // draw new lines on canvas
+ draw();
+ }
+}
+
+void KisToolPolyline::buttonRelease(KisButtonReleaseEvent *event)
+{
+ if (!m_subject || !m_currentImage)
+ return;
+
+ if (m_dragging && event->button() == Qt::LeftButton) {
+ m_dragging = false;
+ m_points.append (m_dragEnd);
+ }
+
+ if (m_dragging && event->button() == Qt::RightButton) {
+
+ }
+}
+
+
+void KisToolPolyline::doubleClick(KisDoubleClickEvent *)
+{
+ finish();
+}
+
+
+void KisToolPolyline::paint(KisCanvasPainter& gc)
+{
+ draw(gc);
+}
+
+void KisToolPolyline::paint(KisCanvasPainter& gc, const TQRect&)
+{
+ draw(gc);
+}
+
+void KisToolPolyline::draw()
+{
+ if (m_subject) {
+ KisCanvasController *controller = m_subject->canvasController();
+ KisCanvas *canvas = controller->kiscanvas();
+ KisCanvasPainter gc(canvas);
+
+ draw(gc);
+ }
+}
+
+void KisToolPolyline::draw(KisCanvasPainter& gc)
+{
+ if (!m_subject || !m_currentImage)
+ return;
+
+ TQPen pen(TQt::white, 0, TQt::SolidLine);
+
+ gc.setPen(pen);
+ gc.setRasterOp(TQt::XorROP);
+
+ KisCanvasController *controller = m_subject->canvasController();
+ KisPoint start, end;
+ TQPoint startPos;
+ TQPoint endPos;
+
+ if (m_dragging) {
+ startPos = controller->windowToView(m_dragStart.floorTQPoint());
+ endPos = controller->windowToView(m_dragEnd.floorTQPoint());
+ gc.drawLine(startPos, endPos);
+ } else {
+ for (KisPointVector::iterator it = m_points.begin(); it != m_points.end(); ++it) {
+
+ if (it == m_points.begin())
+ {
+ start = (*it);
+ } else {
+ end = (*it);
+
+ startPos = controller->windowToView(start.floorTQPoint());
+ endPos = controller->windowToView(end.floorTQPoint());
+
+ gc.drawLine(startPos, endPos);
+
+ start = end;
+ }
+ }
+ }
+}
+
+void KisToolPolyline::setup(KActionCollection *collection)
+{
+ m_action = static_cast<KRadioAction *>(collection->action(name()));
+
+ if (m_action == 0) {
+ KShortcut shortcut(TQt::Key_Plus);
+ shortcut.append(KShortcut(TQt::Key_F9));
+ m_action = new KRadioAction(i18n("&Polyline"),
+ "polyline",
+ shortcut,
+ this,
+ TQT_SLOT(activate()),
+ collection,
+ name());
+ Q_CHECK_PTR(m_action);
+
+ m_action->setToolTip(i18n("Draw a polyline. Shift-mouseclick ends the polyline."));
+ m_action->setExclusiveGroup("tools");
+ m_ownAction = true;
+ }
+}
+
+TQString KisToolPolyline::quickHelp() const
+{
+ return i18n("Press shift-mouseclick to end the polyline.");
+}
+
+void KisToolPolyline::keyPress(TQKeyEvent *e)
+{
+ if (e->key()==TQt::Key_Escape) {
+ // erase old lines on canvas
+ draw();
+ m_dragging = false;
+ m_points.clear();
+ }
+}
+
+#include "kis_tool_polyline.moc"
diff --git a/chalk/plugins/tools/tool_polyline/kis_tool_polyline.h b/chalk/plugins/tools/tool_polyline/kis_tool_polyline.h
new file mode 100644
index 00000000..a7cee195
--- /dev/null
+++ b/chalk/plugins/tools/tool_polyline/kis_tool_polyline.h
@@ -0,0 +1,109 @@
+/*
+ * kis_tool_polyline.h - part of Chalk
+ *
+ * Copyright (c) 2004 Michael Thaler <michael Thaler@physik.tu-muenchen.de>
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef KIS_TOOL_POLYLINE_H_
+#define KIS_TOOL_POLYLINE_H_
+
+#include <tqvaluevector.h>
+#include <tqstring.h>
+
+#include "kis_tool_paint.h"
+#include "kis_point.h"
+
+class KisCanvas;
+class KisDoc;
+class KisPainter;
+class KisView;
+class KisRect;
+
+
+class KisToolPolyline : public KisToolPaint {
+
+ typedef KisToolPaint super;
+ Q_OBJECT
+ TQ_OBJECT
+
+public:
+ KisToolPolyline();
+ virtual ~KisToolPolyline();
+
+ //
+ // KisCanvasObserver interface
+ //
+
+ virtual void update (KisCanvasSubject *subject);
+
+ //
+ // KisToolPaint interface
+ //
+
+ virtual void setup(KActionCollection *collection);
+ virtual enumToolType toolType() { return TOOL_SHAPE; }
+ virtual TQ_UINT32 priority() { return 5; }
+
+ virtual void buttonPress(KisButtonPressEvent *event);
+ virtual void doubleClick(KisDoubleClickEvent *e);
+ virtual void move(KisMoveEvent *event);
+ virtual void buttonRelease(KisButtonReleaseEvent *event);
+ virtual TQString quickHelp() const;
+ void finish();
+ virtual void keyPress(TQKeyEvent *e);
+
+public slots:
+
+ void deactivate();
+
+protected:
+ virtual void paint(KisCanvasPainter& gc);
+ virtual void paint(KisCanvasPainter& gc, const TQRect& rc);
+ void draw(KisCanvasPainter& gc);
+ void draw();
+
+protected:
+ KisPoint m_dragStart;
+ KisPoint m_dragEnd;
+
+ bool m_dragging;
+ KisImageSP m_currentImage;
+private:
+ typedef TQValueVector<KisPoint> KisPointVector;
+ KisPointVector m_points;
+};
+
+
+#include "kis_tool_factory.h"
+
+class KisToolPolylineFactory : public KisToolFactory {
+ typedef KisToolFactory super;
+public:
+ KisToolPolylineFactory() : super() {};
+ virtual ~KisToolPolylineFactory(){};
+
+ virtual KisTool * createTool(KActionCollection * ac) {
+ KisTool * t = new KisToolPolyline();
+ Q_CHECK_PTR(t);
+ t->setup(ac);
+ return t;
+ }
+ virtual KisID id() { return KisID("polyline", i18n("Polyline Tool")); }
+};
+
+
+#endif //__KIS_TOOL_POLYLINE_H__
diff --git a/chalk/plugins/tools/tool_polyline/polyline.png b/chalk/plugins/tools/tool_polyline/polyline.png
new file mode 100644
index 00000000..df36313e
--- /dev/null
+++ b/chalk/plugins/tools/tool_polyline/polyline.png
Binary files differ
diff --git a/chalk/plugins/tools/tool_polyline/tool_polyline.cc b/chalk/plugins/tools/tool_polyline/tool_polyline.cc
new file mode 100644
index 00000000..369169c9
--- /dev/null
+++ b/chalk/plugins/tools/tool_polyline/tool_polyline.cc
@@ -0,0 +1,64 @@
+/*
+ * tool_polyline.cc -- Part of Chalk
+ *
+ * Copyright (c) 2004 Michael Thaler <michael.thaler@physik.tu-muenchen.de>
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+#include <stdlib.h>
+#include <vector>
+
+#include <tqpoint.h>
+
+#include <klocale.h>
+#include <kiconloader.h>
+#include <kinstance.h>
+#include <kmessagebox.h>
+#include <kstandarddirs.h>
+#include <kdebug.h>
+#include <kgenericfactory.h>
+
+#include <kis_global.h>
+#include <kis_types.h>
+#include <kis_tool_registry.h>
+#include <kis_view.h>
+
+#include "tool_polyline.h"
+#include "kis_tool_polyline.h"
+
+
+typedef KGenericFactory<ToolPolyline> ToolPolylineFactory;
+K_EXPORT_COMPONENT_FACTORY( chalktoolpolyline, ToolPolylineFactory( "chalk" ) )
+
+
+ToolPolyline::ToolPolyline(TQObject *tqparent, const char *name, const TQStringList &)
+ : KParts::Plugin(tqparent, name)
+{
+ setInstance(ToolPolylineFactory::instance());
+
+ if ( tqparent->inherits("KisToolRegistry") )
+ {
+ KisToolRegistry * r = dynamic_cast<KisToolRegistry*>(tqparent);
+
+ r->add(new KisToolPolylineFactory());
+ }
+
+}
+
+ToolPolyline::~ToolPolyline()
+{
+}
+
+#include "tool_polyline.moc"
diff --git a/chalk/plugins/tools/tool_polyline/tool_polyline.h b/chalk/plugins/tools/tool_polyline/tool_polyline.h
new file mode 100644
index 00000000..9f483363
--- /dev/null
+++ b/chalk/plugins/tools/tool_polyline/tool_polyline.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2004 Michael Thaler <michael.thaler@physik.tu-muenchen.de>
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef TOOL_POLYLINE_H_
+#define TOOL_POLYLINE_H_
+
+#include <kparts/plugin.h>
+
+class KisView;
+
+/**
+ * A module that provides a polyline tool.
+ */
+class ToolPolyline : public KParts::Plugin
+{
+ Q_OBJECT
+ TQ_OBJECT
+public:
+ ToolPolyline(TQObject *tqparent, const char *name, const TQStringList &);
+ virtual ~ToolPolyline();
+
+private:
+
+ KisView * m_view;
+
+};
+
+#endif // TOOL_POLYLINE_H_
diff --git a/chalk/plugins/tools/tool_polyline/tool_polyline_cursor.png b/chalk/plugins/tools/tool_polyline/tool_polyline_cursor.png
new file mode 100644
index 00000000..b60c2db0
--- /dev/null
+++ b/chalk/plugins/tools/tool_polyline/tool_polyline_cursor.png
Binary files differ
diff --git a/chalk/plugins/tools/tool_selectsimilar/Makefile.am b/chalk/plugins/tools/tool_selectsimilar/Makefile.am
new file mode 100644
index 00000000..f57296ba
--- /dev/null
+++ b/chalk/plugins/tools/tool_selectsimilar/Makefile.am
@@ -0,0 +1,32 @@
+kde_services_DATA = chalktoolselectsimilar.desktop
+
+INCLUDES = -I$(srcdir)/../../../sdk \
+ -I$(srcdir)/../../../core \
+ -I$(srcdir)/../../../chalkcolor/ \
+ -I$(srcdir)/../../../ui \
+ -I$/../../../ui \
+ $(KOFFICE_INCLUDES) \
+ $(all_includes)
+
+
+chalktoolselectsimilar_la_SOURCES = selectsimilar.cc kis_tool_selectsimilar.cc
+noinst_HEADERS = selectsimilar.h kis_tool_selectsimilar.h
+
+kde_module_LTLIBRARIES = chalktoolselectsimilar.la
+
+chalktoolselectsimilar_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) $(LIB_QT) -lkdecore -lkdeui -lkjs -lkdefx -lkio -lkparts -L../../../../chalk/chalkcolor/.libs -lchalkcolor -L../../../../chalk/core/.libs -lchalkimage \
+ -L../../../../chalk/ui/.libs -lchalkui
+chalktoolselectsimilar_la_LIBADD = ../../../libchalkcommon.la
+
+chalktoolselectsimilar_la_METASOURCES = AUTO
+
+KDE_OPTIONS = nofinal
+
+# directory for pixmaps
+chalkpics_DATA = \
+ tool_similar_selection.png \
+ tool_similar_selection_plus_cursor.png \
+ tool_similar_selection_minus_cursor.png
+
+chalkpicsdir = $(kde_datadir)/chalk/pics
+
diff --git a/chalk/plugins/tools/tool_selectsimilar/chalktoolselectsimilar.desktop b/chalk/plugins/tools/tool_selectsimilar/chalktoolselectsimilar.desktop
new file mode 100644
index 00000000..408d1c5a
--- /dev/null
+++ b/chalk/plugins/tools/tool_selectsimilar/chalktoolselectsimilar.desktop
@@ -0,0 +1,43 @@
+[Desktop Entry]
+Name=Select Similar Colors Tool
+Name[bg]=Инструмент за маркиране на подобни цветове
+Name[ca]=Selecciona eines de colors similars
+Name[cy]=Offer Detholi Lliwiau Tebyg
+Name[da]=Vælg lignende farve-værktøjer
+Name[de]="Auswahl nach ähnlichen Farben"-Werkzeug
+Name[el]=Εργαλείο επιλογής παρόμοιων χρωμάτων
+Name[en_GB]=Select Similar Colours Tool
+Name[eo]=Similkolorelekto-ilo
+Name[es]=Herramienta de selección de colores similares
+Name[et]=Sarnase värvi valimise tööriist
+Name[fa]=برگزیدن ابزار رنگهای مشابه
+Name[fr]=Outils de sélection des couleurs similaires
+Name[fy]=Lykense kleur seleksje ark
+Name[gl]=Ferramenta de Selección de Cores Semellantes
+Name[he]=בחירת כלי צבעים דומים
+Name[hu]=Hasonló színeket kiválasztó eszköz
+Name[is]=Velja svipaða liti tól
+Name[it]=Strumento per la selezione dei colori simili
+Name[ja]=類似色選択ツール
+Name[km]=ឧបករណ៍​ជ្រើស​ពណ៌​ស្រដៀង​គ្នា
+Name[nb]=Verktøy som velger liknende farger
+Name[nds]=Warktüüch för de Utwahl vun lieke Klören
+Name[ne]=समान रङ उपकरणहरू चयन गर्नुहोस्
+Name[nl]=Gereedschap voor soortgelijke kleuren
+Name[pl]=Narzędzie wyboru podobnych kolorów
+Name[pt]=Ferramenta de Selecção de Cores Semelhantes
+Name[pt_BR]=Ferramenta de Seleção de Cores Semelhantes
+Name[ru]=Выделение по цвету
+Name[se]=Reaidu mii vállje sullosaš ivnniid
+Name[sk]=Výber podobných farieb
+Name[sl]=Orodje za izbiro podobnih barv
+Name[sr]=Алат за избор сличних боја
+Name[sr@Latn]=Alat za izbor sličnih boja
+Name[sv]=Välj liknande färg-verktyg
+Name[uk]=Засіб вибору подібних кольорів
+Name[zh_CN]=选择相似颜色工具
+Name[zh_TW]=選取近似色彩工具
+ServiceTypes=Chalk/Tool
+Type=Service
+X-KDE-Library=chalktoolselectsimilar
+X-Chalk-Version=2
diff --git a/chalk/plugins/tools/tool_selectsimilar/kis_tool_selectsimilar.cc b/chalk/plugins/tools/tool_selectsimilar/kis_tool_selectsimilar.cc
new file mode 100644
index 00000000..2dfe40f1
--- /dev/null
+++ b/chalk/plugins/tools/tool_selectsimilar/kis_tool_selectsimilar.cc
@@ -0,0 +1,271 @@
+/*
+ * Copyright (c) 1999 Matthias Elter <me@kde.org>
+ * Copyright (c) 2002 Patrick Julien <freak@codepimps.org>
+ * Copyright (c) 2005 Boudewijn Rempt <boud@valdyas.org>
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <tqpoint.h>
+#include <tqlayout.h>
+#include <tqcheckbox.h>
+#include <tqlabel.h>
+#include <tqcombobox.h>
+#include <tqtimer.h>
+
+#include <kapplication.h>
+#include <kaction.h>
+#include <klocale.h>
+#include <knuminput.h>
+
+#include <kis_cursor.h>
+#include <kis_selection_manager.h>
+#include <kis_canvas_subject.h>
+#include <kis_image.h>
+#include <kis_layer.h>
+#include <kis_paint_device.h>
+#include <kis_button_press_event.h>
+#include <kis_canvas_subject.h>
+#include <kis_selection_options.h>
+#include <kis_selection.h>
+#include <kis_paint_device.h>
+#include <kis_iterators_pixel.h>
+#include <kis_selected_transaction.h>
+#include <kis_undo_adapter.h>
+
+#include "kis_tool_selectsimilar.h"
+
+void selectByColor(KisPaintDeviceSP dev, KisSelectionSP selection, const TQ_UINT8 * c, int fuzziness, enumSelectionMode mode)
+{
+ // XXX: Multithread this!
+ TQ_INT32 x, y, w, h;
+
+ dev->exactBounds(x, y, w, h);
+
+ KisColorSpace * cs = dev->colorSpace();
+
+ for (int y2 = y; y2 < y + h; ++y2) {
+ KisHLineIterator hiter = dev->createHLineIterator(x, y2, w, false);
+ KisHLineIterator selIter = selection->createHLineIterator(x, y2, w, true);
+ while (!hiter.isDone()) {
+ //if (dev->colorSpace()->hasAlpha())
+ // opacity = dev->colorSpace()->getAlpha(hiter.rawData());
+
+ TQ_UINT8 match = cs->difference(c, hiter.rawData());
+
+ if (mode == SELECTION_ADD) {
+ if (match <= fuzziness) {
+ *(selIter.rawData()) = MAX_SELECTED;
+ }
+ }
+ else if (mode == SELECTION_SUBTRACT) {
+ if (match <= fuzziness) {
+ *(selIter.rawData()) = MIN_SELECTED;
+ }
+ }
+ ++hiter;
+ ++selIter;
+ }
+ }
+
+}
+
+
+
+KisToolSelectSimilar::KisToolSelectSimilar()
+ : super(i18n("Select Similar Colors"))
+{
+ setName("tool_select_similar");
+ m_addCursor = KisCursor::load("tool_similar_selection_plus_cursor.png", 1, 21);
+ m_subtractCursor = KisCursor::load("tool_similar_selection_minus_cursor.png", 1, 21);
+ setCursor(m_addCursor);
+ m_subject = 0;
+ m_optWidget = 0;
+ m_selectionOptionsWidget = 0;
+ m_fuzziness = 20;
+ m_currentSelectAction = m_defaultSelectAction = SELECTION_ADD;
+ m_timer = new TQTimer(this);
+ connect(m_timer, TQT_SIGNAL(timeout()), TQT_SLOT(slotTimer()) );
+}
+
+KisToolSelectSimilar::~KisToolSelectSimilar()
+{
+}
+
+void KisToolSelectSimilar::activate()
+{
+ KisToolNonPaint::activate();
+ m_timer->start(50);
+ setPickerCursor(m_currentSelectAction);
+
+ if (m_selectionOptionsWidget) {
+ m_selectionOptionsWidget->slotActivated();
+ }
+}
+
+void KisToolSelectSimilar::deactivate()
+{
+ m_timer->stop();
+}
+
+void KisToolSelectSimilar::buttonPress(KisButtonPressEvent *e)
+{
+
+ if (m_subject) {
+ TQApplication::setOverrideCursor(KisCursor::waitCursor());
+ KisImageSP img;
+ KisPaintDeviceSP dev;
+ TQPoint pos;
+ TQ_UINT8 opacity = OPACITY_OPAQUE;
+
+ if (e->button() != Qt::LeftButton && e->button() != Qt::RightButton)
+ return;
+
+ if (!(img = m_subject->currentImg()))
+ return;
+
+ dev = img->activeDevice();
+
+ if (!dev || !img->activeLayer()->visible())
+ return;
+
+ pos = TQPoint(e->pos().floorX(), e->pos().floorY());
+ KisSelectedTransaction *t = 0;
+ if (img->undo()) t = new KisSelectedTransaction(i18n("Similar Selection"),dev);
+
+ KisColor c = dev->colorAt(pos.x(), pos.y());
+ opacity = dev->colorSpace()->getAlpha(c.data());
+
+ // XXX we should make this configurable: "allow to select transparent"
+ // if (opacity > OPACITY_TRANSPARENT)
+ selectByColor(dev, dev->selection(), c.data(), m_fuzziness, m_currentSelectAction);
+
+ dev->setDirty();
+ dev->emitSelectionChanged();
+
+ if(img->undo())
+ img->undoAdapter()->addCommand(t);
+ m_subject->canvasController()->updateCanvas();
+
+ TQApplication::restoreOverrideCursor();
+ }
+}
+
+void KisToolSelectSimilar::slotTimer()
+{
+#if KDE_IS_VERSION(3,4,0)
+ int state = kapp->keyboardMouseState() & (TQt::ShiftButton|TQt::ControlButton|TQt::AltButton);
+#else
+ int state = kapp->keyboardModifiers() & (KApplication::ShiftModifier
+ |KApplication::ControlModifier|KApplication::Modifier1);
+#endif
+ enumSelectionMode action;
+
+ if (state == TQt::ShiftButton)
+ action = SELECTION_ADD;
+ else if (state == TQt::ControlButton)
+ action = SELECTION_SUBTRACT;
+ else
+ action = m_defaultSelectAction;
+
+ if (action != m_currentSelectAction) {
+ m_currentSelectAction = action;
+ setPickerCursor(action);
+ }
+}
+
+void KisToolSelectSimilar::setPickerCursor(enumSelectionMode action)
+{
+ switch (action) {
+ case SELECTION_ADD:
+ m_subject->canvasController()->setCanvasCursor(m_addCursor);
+ break;
+ case SELECTION_SUBTRACT:
+ m_subject->canvasController()->setCanvasCursor(m_subtractCursor);
+ }
+}
+
+void KisToolSelectSimilar::setup(KActionCollection *collection)
+{
+ m_action = static_cast<KRadioAction *>(collection->action(name()));
+
+ if (m_action == 0) {
+ m_action = new KRadioAction(i18n("&Similar Selection"), "tool_similar_selection", "Ctrl+E", this, TQT_SLOT(activate()), collection, name());
+ Q_CHECK_PTR(m_action);
+ m_action->setToolTip(i18n("Select similar colors"));
+ m_action->setExclusiveGroup("tools");
+ m_ownAction = true;
+ }
+}
+
+void KisToolSelectSimilar::update(KisCanvasSubject *subject)
+{
+ super::update(subject);
+ m_subject = subject;
+}
+
+void KisToolSelectSimilar::slotSetFuzziness(int fuzziness)
+{
+ m_fuzziness = fuzziness;
+}
+
+void KisToolSelectSimilar::slotSetAction(int action)
+{
+ m_defaultSelectAction = (enumSelectionMode)action;
+}
+
+TQWidget* KisToolSelectSimilar::createOptionWidget(TQWidget* tqparent)
+{
+ m_optWidget = new TQWidget(tqparent);
+ Q_CHECK_PTR(m_optWidget);
+
+ m_optWidget->setCaption(i18n("Similar Selection"));
+
+ TQVBoxLayout * l = new TQVBoxLayout(m_optWidget, 0, 6);
+ Q_CHECK_PTR(l);
+
+ m_selectionOptionsWidget = new KisSelectionOptions(m_optWidget, m_subject);
+ Q_CHECK_PTR(m_selectionOptionsWidget);
+
+ l->addWidget(m_selectionOptionsWidget);
+ connect (m_selectionOptionsWidget, TQT_SIGNAL(actionChanged(int)), this, TQT_SLOT(slotSetAction(int)));
+
+ TQHBoxLayout * hbox = new TQHBoxLayout(l);
+ Q_CHECK_PTR(hbox);
+
+ TQLabel * lbl = new TQLabel(i18n("Fuzziness: "), m_optWidget);
+ Q_CHECK_PTR(lbl);
+
+ hbox->addWidget(lbl);
+
+ KIntNumInput * input = new KIntNumInput(m_optWidget, "fuzziness");
+ Q_CHECK_PTR(input);
+
+ input->setRange(0, 200, 10, true);
+ input->setValue(20);
+ hbox->addWidget(input);
+ connect(input, TQT_SIGNAL(valueChanged(int)), this, TQT_SLOT(slotSetFuzziness(int)));
+
+ l->addItem(new TQSpacerItem(1, 1, TQSizePolicy::Fixed, TQSizePolicy::Expanding));
+
+ return m_optWidget;
+}
+
+TQWidget* KisToolSelectSimilar::optionWidget()
+{
+ return m_optWidget;
+}
+
+#include "kis_tool_selectsimilar.moc"
diff --git a/chalk/plugins/tools/tool_selectsimilar/kis_tool_selectsimilar.h b/chalk/plugins/tools/tool_selectsimilar/kis_tool_selectsimilar.h
new file mode 100644
index 00000000..d98659d0
--- /dev/null
+++ b/chalk/plugins/tools/tool_selectsimilar/kis_tool_selectsimilar.h
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 1999 Matthias Elter
+ * Copyright (c) 2002 Patrick Julien
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+#ifndef KIS_TOOL_SELECT_PICKER_H_
+#define KIS_TOOL_SELECT_PICKER_H_
+
+#include <kis_tool_non_paint.h>
+#include <kis_tool_factory.h>
+#include <kis_selection.h>
+
+class KisCanvasSubject;
+class TQWidget;
+class TQVBoxLayout;
+class TQCheckBox;
+class KisIntSpinbox;
+
+/**
+ * Tool to select colours by pointing at a color on the image.
+ * TODO:
+ * Implement shift/shift-ctrl keyboard shortcuts for
+ * temporary add/subtract selection mode.
+ */
+
+class KisSelectionOptions;
+
+class KisToolSelectSimilar : public KisToolNonPaint {
+
+ Q_OBJECT
+ TQ_OBJECT
+ typedef KisToolNonPaint super;
+
+public:
+ KisToolSelectSimilar();
+ virtual ~KisToolSelectSimilar();
+
+ virtual void update(KisCanvasSubject *subject);
+ virtual void setup(KActionCollection *collection);
+ virtual TQ_UINT32 priority() { return 8; }
+ virtual enumToolType toolType() { return TOOL_SELECT; }
+
+public slots:
+
+ void activate();
+ void deactivate();
+
+ virtual void slotSetFuzziness(int);
+ virtual void slotSetAction(int);
+
+private:
+ virtual TQWidget* createOptionWidget(TQWidget* tqparent);
+ virtual TQWidget* optionWidget();
+
+ virtual void buttonPress(KisButtonPressEvent *e);
+ void setPickerCursor(enumSelectionMode);
+
+ KisCanvasSubject *m_subject;
+ TQWidget *m_optWidget;
+ KisSelectionOptions *m_selectionOptionsWidget;
+
+ int m_fuzziness;
+ enumSelectionMode m_defaultSelectAction;
+ enumSelectionMode m_currentSelectAction;
+ TQTimer *m_timer;
+ TQCursor m_addCursor;
+ TQCursor m_subtractCursor;
+
+private slots:
+ void slotTimer();
+};
+
+class KisToolSelectSimilarFactory : public KisToolFactory {
+ typedef KisToolFactory super;
+public:
+ KisToolSelectSimilarFactory() : super() {};
+ virtual ~KisToolSelectSimilarFactory(){};
+
+ virtual KisTool * createTool(KActionCollection * ac) {
+ KisTool * t = new KisToolSelectSimilar();
+ Q_CHECK_PTR(t);
+ t->setup(ac);
+ return t;
+ }
+ virtual KisID id() { return KisID("selectsimilar", i18n("Select Similar")); }
+};
+
+
+#endif // KIS_TOOL_SELECT_PICKER_H_
+
diff --git a/chalk/plugins/tools/tool_selectsimilar/selectsimilar.cc b/chalk/plugins/tools/tool_selectsimilar/selectsimilar.cc
new file mode 100644
index 00000000..539f534a
--- /dev/null
+++ b/chalk/plugins/tools/tool_selectsimilar/selectsimilar.cc
@@ -0,0 +1,61 @@
+/*
+ * selectsimilar.h -- Part of Chalk
+ *
+ * Copyright (c) 2004 Boudewijn Rempt (boud@valdyas.org)
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+#include <math.h>
+
+#include <stdlib.h>
+
+#include <tqslider.h>
+#include <tqpoint.h>
+
+#include <klocale.h>
+#include <kiconloader.h>
+#include <kinstance.h>
+#include <kmessagebox.h>
+#include <kstandarddirs.h>
+#include <ktempfile.h>
+#include <kdebug.h>
+#include <kgenericfactory.h>
+
+#include <kis_tool_registry.h>
+
+#include "selectsimilar.h"
+#include "kis_tool_selectsimilar.h"
+
+typedef KGenericFactory<SelectSimilar> SelectSimilarFactory;
+K_EXPORT_COMPONENT_FACTORY( chalktoolselectsimilar, SelectSimilarFactory( "chalk" ) )
+
+SelectSimilar::SelectSimilar(TQObject *tqparent, const char *name, const TQStringList &)
+ : KParts::Plugin(tqparent, name)
+{
+ setInstance(SelectSimilarFactory::instance());
+
+ if ( tqparent->inherits("KisToolRegistry") )
+ {
+ KisToolRegistry * r = dynamic_cast<KisToolRegistry*>(tqparent);
+ r->add(new KisToolSelectSimilarFactory());
+ }
+}
+
+SelectSimilar::~SelectSimilar()
+{
+}
+
+#include "selectsimilar.moc"
+
diff --git a/chalk/plugins/tools/tool_selectsimilar/selectsimilar.h b/chalk/plugins/tools/tool_selectsimilar/selectsimilar.h
new file mode 100644
index 00000000..a0588bfb
--- /dev/null
+++ b/chalk/plugins/tools/tool_selectsimilar/selectsimilar.h
@@ -0,0 +1,35 @@
+/*
+ * selectsimilar.h -- Part of Chalk
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef SELECTSIMILAR_H
+#define SELECTSIMILAR_H
+
+#include <kparts/plugin.h>
+
+class SelectSimilar : public KParts::Plugin
+{
+ Q_OBJECT
+ TQ_OBJECT
+ public:
+ SelectSimilar(TQObject *tqparent, const char *name, const TQStringList &);
+ virtual ~SelectSimilar();
+
+
+};
+
+#endif // SELECTSIMILAR_H
diff --git a/chalk/plugins/tools/tool_selectsimilar/tool_similar_selection.png b/chalk/plugins/tools/tool_selectsimilar/tool_similar_selection.png
new file mode 100644
index 00000000..3025b100
--- /dev/null
+++ b/chalk/plugins/tools/tool_selectsimilar/tool_similar_selection.png
Binary files differ
diff --git a/chalk/plugins/tools/tool_selectsimilar/tool_similar_selection.svg b/chalk/plugins/tools/tool_selectsimilar/tool_similar_selection.svg
new file mode 100644
index 00000000..f1e881bc
--- /dev/null
+++ b/chalk/plugins/tools/tool_selectsimilar/tool_similar_selection.svg
@@ -0,0 +1,2118 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://web.resource.org/cc/"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://inkscape.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ inkscape:export-ydpi="33.000000"
+ inkscape:export-xdpi="33.000000"
+ inkscape:export-filename="/home/danny/work/kde/koffice/chalk/chalk/new/tool_picker_selection.png"
+ width="48.000000pt"
+ height="48.000000pt"
+ id="svg17707"
+ sodipodi:version="0.32"
+ inkscape:version="0.41"
+ sodipodi:docbase="/home/danny"
+ sodipodi:docname="co.svg">
+ <defs
+ id="defs3">
+ <linearGradient
+ y2="-88.103630"
+ x2="-2035.2124"
+ y1="-86.329994"
+ x1="-2105.8408"
+ gradientTransform="matrix(0.275772,6.677168e-2,-1.785205,1.778283,15.77866,-194.5809)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient13777"
+ xlink:href="#zerotowhitetozero"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="406.47195"
+ x2="-420.16779"
+ y1="405.99652"
+ x1="-432.85263"
+ gradientTransform="matrix(1.161617,-4.739154e-2,2.691281e-2,0.545879,5.167330,-400.1846)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient13775"
+ xlink:href="#zerotowhitetozero"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="405.64288"
+ x2="-419.48849"
+ y1="403.28021"
+ x1="-435.29645"
+ gradientTransform="matrix(1.161617,-4.739154e-2,2.691281e-2,0.545879,5.167330,-400.1846)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient13773"
+ xlink:href="#sadow75to0w"
+ inkscape:collect="always" />
+ <radialGradient
+ r="14.292608"
+ fy="224.71202"
+ fx="-36.269680"
+ cy="224.72163"
+ cx="-36.280697"
+ spreadMethod="reflect"
+ gradientTransform="matrix(1.289960,-2.934787,-1.254670,-0.687701,-135.1226,-352.8727)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient13771"
+ xlink:href="#zerotowhitetozero"
+ inkscape:collect="always" />
+ <linearGradient
+ id="light100to75to0">
+ <stop
+ id="stop2779"
+ offset="0.0000000"
+ style="stop-color:#ffffff;stop-opacity:1.0000000;" />
+ <stop
+ id="stop2782"
+ offset="0.50000000"
+ style="stop-color:#ffffff;stop-opacity:0.77499998;" />
+ <stop
+ id="stop2780"
+ offset="1.0000000"
+ style="stop-color:#ffffff;stop-opacity:0.0000000;" />
+ </linearGradient>
+ <radialGradient
+ r="20.501772"
+ fy="-238.20859"
+ fx="-580.40790"
+ cy="-238.20859"
+ cx="-580.40790"
+ spreadMethod="pad"
+ gradientTransform="matrix(0.777876,3.246476e-2,2.423728e-2,0.784691,13.97124,-196.1555)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient13769"
+ xlink:href="#light100to75to0"
+ inkscape:collect="always" />
+ <radialGradient
+ r="14.292608"
+ fy="224.71202"
+ fx="-36.269680"
+ cy="224.72163"
+ cx="-36.280697"
+ spreadMethod="reflect"
+ gradientTransform="matrix(1.458853,-2.843975,1.264624,0.666794,-721.3474,-644.7191)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient13767"
+ xlink:href="#zerotowhitetozero"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="235.01132"
+ x2="135.19012"
+ y1="198.13455"
+ x1="111.31033"
+ gradientTransform="matrix(2.980933,-1.623511,0.421337,1.602678,-832.2722,-621.5866)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient13765"
+ xlink:href="#zerotowhitetozero"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="203.17725"
+ x2="159.03880"
+ y1="169.79622"
+ x1="139.84422"
+ spreadMethod="reflect"
+ gradientTransform="matrix(2.501016,-1.261406,3.268214e-2,1.810490,-830.4708,-1463.906)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient13763"
+ xlink:href="#greylighttograyw"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="438.93094"
+ x2="236.60674"
+ y1="441.75595"
+ x1="238.34102"
+ gradientTransform="matrix(-8.083600e-2,-0.768518,-1.314142,-0.122986,-4.770628e-13,8.999746e-14)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient13761"
+ xlink:href="#zerotowhitetozero"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="-295.75092"
+ x2="-417.17459"
+ y1="-417.90485"
+ x1="-492.07742"
+ gradientTransform="matrix(4.666024e-2,4.366770e-3,7.470758e-3,7.102536e-2,-570.7207,-206.9104)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient13759"
+ xlink:href="#zerotowhitetozero"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="123.06261"
+ x2="187.18298"
+ y1="227.44664"
+ x1="184.86623"
+ gradientTransform="matrix(7.470016e-2,6.828522e-2,-2.777414e-2,3.139757e-2,-606.6362,-251.3928)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient13757"
+ xlink:href="#greandarktobgrean"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="-428.42480"
+ x2="-613.35199"
+ y1="-430.20041"
+ x1="-614.11633"
+ gradientTransform="matrix(1.048782,-0.305752,-0.108731,0.985186,-4.770628e-13,8.999746e-14)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient13755"
+ xlink:href="#greandraktoblack"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="-429.79779"
+ x2="-601.16077"
+ y1="-436.17172"
+ x1="-607.02917"
+ spreadMethod="reflect"
+ gradientTransform="matrix(1.063407,-0.310015,-0.107235,0.971636,-4.770628e-13,8.999746e-14)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient13753"
+ xlink:href="#greandarktobgrean"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="118.38348"
+ x2="219.65416"
+ y1="150.76836"
+ x1="239.13113"
+ spreadMethod="reflect"
+ gradientTransform="matrix(0.165829,-5.173052e-2,-1.826319e-2,0.197436,-628.6676,-249.7811)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient13751"
+ xlink:href="#zerotowhitetozero"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="118.38348"
+ x2="219.65416"
+ y1="150.76836"
+ x1="239.13113"
+ spreadMethod="reflect"
+ gradientTransform="matrix(0.165829,-5.173052e-2,-1.826319e-2,0.197436,-628.6676,-249.7811)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient13749"
+ xlink:href="#zerotowhitetozero"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="118.38348"
+ x2="219.65416"
+ y1="150.76836"
+ x1="239.13113"
+ spreadMethod="reflect"
+ gradientTransform="matrix(0.165829,-5.173052e-2,-1.826319e-2,0.197436,-628.6676,-249.7811)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient13747"
+ xlink:href="#zerotowhitetozero"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="163.71248"
+ x2="166.34229"
+ y1="140.82243"
+ x1="165.24026"
+ gradientTransform="matrix(0.224936,-7.016936e-2,-1.346405e-2,0.145555,-629.0715,-249.6400)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient13745"
+ xlink:href="#light100to0"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="118.38348"
+ x2="219.65416"
+ y1="150.76836"
+ x1="239.13113"
+ spreadMethod="reflect"
+ gradientTransform="matrix(0.165829,-5.173052e-2,-1.826319e-2,0.197436,-628.6676,-249.7811)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient13743"
+ xlink:href="#zerotowhitetozero"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="101.48473"
+ x2="186.14693"
+ y1="208.29716"
+ x1="211.31139"
+ gradientTransform="matrix(0.163150,-4.324279e-2,-1.925222e-2,0.147313,-623.7133,-249.0598)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient13741"
+ xlink:href="#greandraktoblack"
+ inkscape:collect="always" />
+ <linearGradient
+ id="greandarktobgrean">
+ <stop
+ id="stop4492"
+ offset="0.0000000"
+ style="stop-color:#00ad01;stop-opacity:1.0000000;" />
+ <stop
+ id="stop4493"
+ offset="1.0000000"
+ style="stop-color:#15720f;stop-opacity:1.0000000;" />
+ </linearGradient>
+ <linearGradient
+ y2="227.49260"
+ x2="198.67084"
+ y1="100.63807"
+ x1="139.79741"
+ spreadMethod="reflect"
+ gradientTransform="matrix(0.165426,-4.384578e-2,-1.898738e-2,0.145287,-614.6689,-246.6268)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient13739"
+ xlink:href="#greandarktobgrean"
+ inkscape:collect="always" />
+ <linearGradient
+ id="greandraktoblack">
+ <stop
+ id="stop7328"
+ offset="0.0000000"
+ style="stop-color:#007c00;stop-opacity:1.0000000;" />
+ <stop
+ id="stop7329"
+ offset="1.0000000"
+ style="stop-color:#025a00;stop-opacity:1.0000000;" />
+ </linearGradient>
+ <linearGradient
+ y2="-643.52313"
+ x2="-303.30316"
+ y1="-852.35785"
+ x1="-406.36154"
+ spreadMethod="reflect"
+ gradientTransform="matrix(1.085489,-0.277106,-0.134433,0.955562,-6.884770e-13,-5.417332e-13)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient13737"
+ xlink:href="#greandraktoblack"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="-351.53336"
+ x2="-279.99734"
+ y1="-529.27637"
+ x1="-426.86380"
+ gradientTransform="scale(1.014829,0.985388)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient13735"
+ xlink:href="#graytoblack"
+ inkscape:collect="always" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#zerotowhitetozero"
+ id="linearGradient17705"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="scale(0.889037,1.124812)"
+ spreadMethod="reflect"
+ x1="239.13113"
+ y1="150.76836"
+ x2="219.65416"
+ y2="118.38348" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#zerotowhitetozero"
+ id="linearGradient17703"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="scale(0.889037,1.124812)"
+ spreadMethod="reflect"
+ x1="239.13113"
+ y1="150.76836"
+ x2="219.65416"
+ y2="118.38348" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#zerotowhitetozero"
+ id="linearGradient17701"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="scale(0.889037,1.124812)"
+ spreadMethod="reflect"
+ x1="239.13113"
+ y1="150.76836"
+ x2="219.65416"
+ y2="118.38348" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#light100to0"
+ id="linearGradient17699"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="scale(1.205925,0.829239)"
+ x1="165.24026"
+ y1="140.82243"
+ x2="166.34229"
+ y2="163.71248" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#zerotowhitetozero"
+ id="linearGradient17697"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="scale(0.889037,1.124812)"
+ spreadMethod="reflect"
+ x1="239.13113"
+ y1="150.76836"
+ x2="219.65416"
+ y2="118.38348" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#zerotowhitetozero"
+ id="radialGradient17695"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.917031,-0.155019,0.179218,1.060181,-23.61859,31.63539)"
+ cx="130.43364"
+ cy="187.24419"
+ fx="130.40277"
+ fy="187.29732"
+ r="13.523715" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#zerotowhitetozero"
+ id="radialGradient17693"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.917031,-0.155019,0.179218,1.060181,-23.61859,31.63539)"
+ cx="130.43364"
+ cy="187.24419"
+ fx="130.40277"
+ fy="187.29732"
+ r="13.523715" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#zerotowhitetozero"
+ id="radialGradient17691"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.917031,-0.155019,0.179218,1.060181,-23.61859,31.63539)"
+ cx="130.43364"
+ cy="187.24419"
+ fx="130.40277"
+ fy="187.29732"
+ r="13.523715" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#zerotowhitetozero"
+ id="radialGradient17689"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.917031,-0.155019,0.179218,1.060181,-23.61859,31.63539)"
+ cx="130.43364"
+ cy="187.24419"
+ fx="130.40277"
+ fy="187.29732"
+ r="13.523715" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#zerotowhitetozero"
+ id="radialGradient17687"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.917031,-0.155019,0.179218,1.060181,-23.61859,31.63539)"
+ cx="130.43364"
+ cy="187.24419"
+ fx="130.40277"
+ fy="187.29732"
+ r="13.523715" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#zerotowhitetozero"
+ id="linearGradient17685"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.919303,-4.587116e-16,-9.003051e-17,1.087781,-31.65752,40.91072)"
+ x1="132.47713"
+ y1="128.17326"
+ x2="138.51009"
+ y2="135.55878" />
+ <linearGradient
+ id="sadow75to0w">
+ <stop
+ style="stop-color:#000000;stop-opacity:0.72941178;"
+ offset="0.0000000"
+ id="stop3429" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.0000000;"
+ offset="1.0000000"
+ id="stop3430" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#sadow75to0w"
+ id="linearGradient17683"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.919303,-4.587116e-16,-9.003051e-17,1.087781,-31.65752,40.91072)"
+ spreadMethod="reflect"
+ x1="131.99300"
+ y1="129.27406"
+ x2="134.97223"
+ y2="132.72443" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#zerotowhitetozero"
+ id="radialGradient17681"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.277707,-1.314622,0.656307,0.494064,-23.61859,31.63539)"
+ spreadMethod="reflect"
+ cx="-36.280697"
+ cy="224.72163"
+ fx="-36.269680"
+ fy="224.71202"
+ r="14.292608" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#zerotowhitetozero"
+ id="radialGradient17679"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.917031,-0.155019,0.179218,1.060181,-23.61859,31.63539)"
+ cx="130.43364"
+ cy="187.24419"
+ fx="130.40277"
+ fy="187.29732"
+ r="13.523715" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#light100to0"
+ id="radialGradient17677"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.952120,-0.160951,0.172613,1.021109,-23.57515,31.60495)"
+ cx="124.97867"
+ cy="166.89621"
+ fx="124.97867"
+ fy="166.89621"
+ r="4.5374427" />
+ <linearGradient
+ id="light100to0">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1.0000000;"
+ offset="0.0000000"
+ id="stop2764" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.0000000;"
+ offset="1.0000000"
+ id="stop2765" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#light100to0"
+ id="radialGradient17675"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.952120,-0.160951,0.172613,1.021109,-23.61859,31.63539)"
+ cx="140.60791"
+ cy="183.52762"
+ fx="140.60791"
+ fy="183.52762"
+ r="8.2203732" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#zerotowhitetozero"
+ id="linearGradient17673"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.068635,-0.180647,0.153793,0.909776,-2.125903e-15,-5.608359e-15)"
+ x1="111.31033"
+ y1="198.13455"
+ x2="135.19012"
+ y2="235.01132" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#zerotowhitetozero"
+ id="linearGradient17671"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.068635,-0.180647,0.153793,0.909776,-23.61859,31.63539)"
+ x1="121.55471"
+ y1="169.77112"
+ x2="130.17465"
+ y2="182.88293" />
+ <linearGradient
+ id="zerotowhitetozero">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.0000000;"
+ offset="0.0000000"
+ id="stop3155" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.0000000;"
+ offset="0.33462518"
+ id="stop3156" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1.0000000;"
+ offset="0.55554277"
+ id="stop3157" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.0000000;"
+ offset="0.74528182"
+ id="stop3158" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.0000000;"
+ offset="1.0000000"
+ id="stop3159" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#zerotowhitetozero"
+ id="linearGradient17669"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.918796,-4.448298e-7,2.186431e-9,1.088383,-31.71369,41.04076)"
+ x1="130.94159"
+ y1="136.24300"
+ x2="141.97820"
+ y2="119.97503" />
+ <linearGradient
+ id="orangetoblackorange">
+ <stop
+ style="stop-color:#ff8b00;stop-opacity:1.0000000;"
+ offset="0.0000000"
+ id="stop4207" />
+ <stop
+ style="stop-color:#4d0200;stop-opacity:1.0000000;"
+ offset="1.0000000"
+ id="stop4209" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#orangetoblackorange"
+ id="linearGradient17667"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="scale(0.994153,1.005881)"
+ x1="211.31139"
+ y1="208.29716"
+ x2="186.14693"
+ y2="101.48473" />
+ <linearGradient
+ id="orangelesstoyelow">
+ <stop
+ style="stop-color:#ff0d00;stop-opacity:1.0000000;"
+ offset="0.0000000"
+ id="stop2689" />
+ <stop
+ style="stop-color:#ff3900;stop-opacity:1.0000000;"
+ offset="0.25358382"
+ id="stop2690" />
+ <stop
+ style="stop-color:#d05521;stop-opacity:1.0000000;"
+ offset="1.0000000"
+ id="stop2691" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#orangelesstoyelow"
+ id="linearGradient17665"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.008016,-3.457641e-17,-7.028912e-17,0.992047,59.09612,34.16495)"
+ spreadMethod="reflect"
+ x1="139.79741"
+ y1="100.63807"
+ x2="198.67084"
+ y2="227.49260" />
+ <linearGradient
+ id="greylighttograyw">
+ <stop
+ style="stop-color:#b5b5b8;stop-opacity:1.0000000;"
+ offset="0.0000000"
+ id="stop575" />
+ <stop
+ style="stop-color:#ebebee;stop-opacity:1.0000000;"
+ offset="1.0000000"
+ id="stop576" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#greylighttograyw"
+ id="linearGradient17663"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.068635,-0.180647,0.153793,0.909776,-23.61859,31.63539)"
+ spreadMethod="reflect"
+ x1="139.84422"
+ y1="169.79622"
+ x2="159.03880"
+ y2="203.17725" />
+ <radialGradient
+ r="5.8189325"
+ fy="9.5002232"
+ fx="8.0907059"
+ cy="9.5002232"
+ cx="8.0907059"
+ gradientTransform="matrix(0.542260,0.000000,0.000000,1.241312,-0.785301,11.64914)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient20026"
+ xlink:href="#light90to0"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="41.545322"
+ x2="22.396454"
+ y1="35.206337"
+ x1="22.425571"
+ gradientTransform="matrix(2.038890,0.000000,0.000000,0.330138,-12.72324,1.327640)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient20022"
+ xlink:href="#light90to0"
+ inkscape:collect="always" />
+ <radialGradient
+ r="14.270030"
+ fy="51.904903"
+ fx="25.923746"
+ cy="52.497688"
+ cx="25.952410"
+ gradientTransform="matrix(2.144567,0.000000,0.000000,0.313870,-12.72324,1.327640)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient20019"
+ xlink:href="#light90to0"
+ inkscape:collect="always" />
+ <radialGradient
+ r="9.9914455"
+ fy="55.457653"
+ fx="92.643608"
+ cy="55.457653"
+ cx="92.643608"
+ gradientTransform="matrix(0.715419,0.000000,0.000000,0.940867,-15.98071,11.24691)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient20008"
+ xlink:href="#light90to0"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="85.112236"
+ x2="-21.621279"
+ y1="81.885979"
+ x1="-16.569721"
+ gradientTransform="matrix(0.000000,-2.069389,0.325272,0.000000,20.75234,15.09638)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient20005"
+ xlink:href="#light90to0"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="41.545322"
+ x2="22.396454"
+ y1="35.206337"
+ x1="22.425571"
+ gradientTransform="matrix(2.038890,0.000000,0.000000,0.330138,-31.37563,1.327640)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient20001"
+ xlink:href="#light90to0"
+ inkscape:collect="always" />
+ <radialGradient
+ r="14.270030"
+ fy="51.904903"
+ fx="25.923746"
+ cy="52.497688"
+ cx="25.952410"
+ gradientTransform="matrix(2.144567,0.000000,0.000000,0.313870,-31.37563,1.327640)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient19998"
+ xlink:href="#light90to0"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="41.545322"
+ x2="22.396454"
+ y1="35.206337"
+ x1="22.425571"
+ gradientTransform="matrix(2.038890,0.000000,0.000000,0.330138,-20.05593,48.23092)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient19994"
+ xlink:href="#light90to0"
+ inkscape:collect="always" />
+ <radialGradient
+ r="14.270030"
+ fy="51.904903"
+ fx="25.923746"
+ cy="52.497688"
+ cx="25.952410"
+ gradientTransform="matrix(2.144567,0.000000,0.000000,0.313870,-20.05593,48.23092)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient19991"
+ xlink:href="#light90to0"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="41.545322"
+ x2="22.396454"
+ y1="35.206337"
+ x1="22.425571"
+ gradientTransform="matrix(2.038890,0.000000,0.000000,0.330138,-38.78637,48.23092)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient19987"
+ xlink:href="#light90to0"
+ inkscape:collect="always" />
+ <radialGradient
+ r="14.270030"
+ fy="51.904903"
+ fx="25.923746"
+ cy="52.497688"
+ cx="25.952410"
+ gradientTransform="matrix(2.144567,0.000000,0.000000,0.313870,-38.78637,48.23092)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient19984"
+ xlink:href="#light90to0"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="85.112236"
+ x2="-21.621279"
+ y1="81.885979"
+ x1="-16.569721"
+ gradientTransform="matrix(0.000000,-2.069389,0.325272,0.000000,20.66765,1.378444)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient19980"
+ xlink:href="#light90to0"
+ inkscape:collect="always" />
+ <radialGradient
+ r="8.5514765"
+ fy="95.221397"
+ fx="-23.859682"
+ cy="95.221397"
+ cx="-23.859682"
+ gradientTransform="matrix(0.000000,-2.142981,0.309244,0.000000,20.66765,1.878457)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient19977"
+ xlink:href="#light90to0"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="85.112236"
+ x2="-21.621279"
+ y1="81.885979"
+ x1="-16.569721"
+ gradientTransform="matrix(0.000000,-2.069389,0.325272,0.000000,-25.58840,-6.393896)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient19973"
+ xlink:href="#light90to0"
+ inkscape:collect="always" />
+ <radialGradient
+ r="8.5514765"
+ fy="95.221397"
+ fx="-23.859682"
+ cy="95.221397"
+ cx="-23.859682"
+ gradientTransform="matrix(0.000000,-2.142981,0.309244,0.000000,-25.58840,-5.893883)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient19970"
+ xlink:href="#light90to0"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="85.112236"
+ x2="-21.621279"
+ y1="81.885979"
+ x1="-16.569721"
+ gradientTransform="matrix(0.000000,-2.069389,0.325272,0.000000,-25.58840,10.88376)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient19966"
+ xlink:href="#light90to0"
+ inkscape:collect="always" />
+ <radialGradient
+ r="8.5514765"
+ fy="95.221397"
+ fx="-23.859682"
+ cy="95.221397"
+ cx="-23.859682"
+ gradientTransform="matrix(0.000000,-2.142981,0.309244,0.000000,-25.58840,11.38378)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient19963"
+ xlink:href="#light90to0"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="218.74910"
+ x2="198.28532"
+ y1="264.70230"
+ x1="145.42192"
+ gradientTransform="matrix(0.195716,-1.310673e-2,0.000000,0.258334,-4.383105,-16.75305)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient19163"
+ xlink:href="#graytoblack"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="210.46336"
+ x2="84.003502"
+ y1="279.47504"
+ x1="132.72992"
+ gradientTransform="matrix(0.195716,-1.310673e-2,0.000000,0.258334,-4.383105,-16.75305)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient18401"
+ xlink:href="#graytoblack"
+ inkscape:collect="always" />
+ <radialGradient
+ r="83.259750"
+ fy="332.37268"
+ fx="86.514435"
+ cy="332.37268"
+ cx="86.514435"
+ gradientTransform="matrix(0.281643,-1.886110e-2,0.000000,0.179517,-4.383105,-16.75305)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient16881"
+ xlink:href="#graytoblack"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="216.48166"
+ x2="144.13652"
+ y1="120.63583"
+ x1="149.74805"
+ gradientTransform="matrix(0.331788,0.000000,0.000000,0.171926,-4.383100,-17.56719)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient13087"
+ xlink:href="#light100to0"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="172.01805"
+ x2="88.821419"
+ y1="215.05040"
+ x1="42.080868"
+ gradientTransform="matrix(0.182201,0.000000,0.000000,0.313078,-4.383100,-17.56719)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient13085"
+ xlink:href="#light100to0"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="213.05858"
+ x2="189.53893"
+ y1="213.05858"
+ x1="24.253796"
+ gradientTransform="matrix(0.331788,0.000000,0.000000,0.171926,-4.383100,-17.56719)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient13083"
+ xlink:href="#light100to0"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="229.92639"
+ x2="120.08266"
+ y1="203.68118"
+ x1="203.79491"
+ spreadMethod="reflect"
+ gradientTransform="matrix(0.250582,0.000000,0.000000,0.227641,-4.383105,-17.56717)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient13081"
+ xlink:href="#orangetoblackorange"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="189.54620"
+ x2="129.06503"
+ y1="179.83293"
+ x1="119.80309"
+ spreadMethod="reflect"
+ gradientTransform="matrix(0.302207,-2.036411e-2,1.731823e-2,0.187588,4.903646,-12.38550)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient13079"
+ xlink:href="#orangetoblackorange"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="189.54620"
+ x2="129.06503"
+ y1="179.83293"
+ x1="119.80309"
+ spreadMethod="reflect"
+ gradientTransform="matrix(0.302207,-2.036411e-2,1.731823e-2,0.187588,-0.406378,-15.67507)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient13077"
+ xlink:href="#orangetoblackorange"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="189.54620"
+ x2="129.06503"
+ y1="179.83293"
+ x1="119.80309"
+ spreadMethod="reflect"
+ gradientTransform="matrix(0.302207,-2.036411e-2,1.731823e-2,0.187588,-5.784573,-19.06245)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient13075"
+ xlink:href="#orangetoblackorange"
+ inkscape:collect="always" />
+ <radialGradient
+ r="24.113470"
+ fy="265.90030"
+ fx="145.82777"
+ cy="265.90030"
+ cx="145.82777"
+ gradientTransform="matrix(0.282097,-1.889158e-2,0.000000,0.179229,-4.383100,-12.51208)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient13073"
+ xlink:href="#light50to25to7"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="301.15750"
+ x2="137.31036"
+ y1="301.15747"
+ x1="163.74318"
+ gradientTransform="matrix(0.273027,-1.828417e-2,0.000000,0.185183,-4.383100,-12.51208)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient13071"
+ xlink:href="#shadow100to0"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="224.95407"
+ x2="99.415497"
+ y1="199.20517"
+ x1="124.51332"
+ gradientTransform="matrix(0.273027,-1.828417e-2,0.000000,0.185183,-4.383100,-12.51208)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient13069"
+ xlink:href="#shadow100to0"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="224.95407"
+ x2="99.415497"
+ y1="199.20517"
+ x1="124.51332"
+ gradientTransform="matrix(0.273027,-1.828417e-2,0.000000,0.185183,-4.383100,-12.51208)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient13067"
+ xlink:href="#shadow100to0"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="574.66980"
+ x2="90.955330"
+ y1="221.05045"
+ x1="138.68466"
+ spreadMethod="reflect"
+ gradientTransform="matrix(0.262073,-1.755056e-2,0.000000,0.217660,-4.383105,-17.56717)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient13065"
+ xlink:href="#graytoblack"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="220.31316"
+ x2="269.30646"
+ y1="173.35371"
+ x1="188.09673"
+ gradientTransform="matrix(0.218024,-1.460066e-2,0.000000,0.231901,-4.383105,-16.75305)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient13063"
+ xlink:href="#light100to0"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="18.127838"
+ x2="40.120766"
+ y1="43.692036"
+ x1="77.830383"
+ gradientTransform="matrix(0.870407,-5.828951e-2,0.000000,1.148888,-2.107689e-16,7.113450e-16)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient13061"
+ xlink:href="#orangemoretoyelow"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="189.89319"
+ x2="126.82574"
+ y1="300.55457"
+ x1="134.59328"
+ gradientTransform="matrix(0.286285,-1.917198e-2,0.000000,0.176607,-4.383105,-16.75305)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient13059"
+ xlink:href="#light100to0"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="47.244961"
+ x2="28.653791"
+ y1="4.8842254"
+ x1="36.606781"
+ gradientTransform="matrix(1.273196,-8.526361e-2,0.000000,0.785425,-2.107689e-16,7.113450e-16)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient13057"
+ xlink:href="#orangemoretoyelow"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="234.35374"
+ x2="184.11906"
+ y1="219.68500"
+ x1="159.18221"
+ gradientTransform="matrix(0.180988,-1.212046e-2,0.000000,0.279356,-4.383105,-16.75305)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient13055"
+ xlink:href="#light100to0"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="218.74910"
+ x2="198.28532"
+ y1="264.70230"
+ x1="145.42192"
+ gradientTransform="matrix(0.195716,-1.310673e-2,0.000000,0.258334,-4.383105,-16.75305)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient13053"
+ xlink:href="#wihitetolightgray"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="250.54321"
+ x2="54.607849"
+ y1="213.43617"
+ x1="136.55682"
+ gradientTransform="matrix(0.195716,-1.310673e-2,0.000000,0.258334,-4.383105,-16.75305)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient13051"
+ xlink:href="#light100to0"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="210.46336"
+ x2="84.003502"
+ y1="279.47504"
+ x1="132.72992"
+ gradientTransform="matrix(0.195716,-1.310673e-2,0.000000,0.258334,-4.383105,-16.75305)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient13049"
+ xlink:href="#wihitetolightgray"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="247.07323"
+ x2="73.286217"
+ y1="335.76117"
+ x1="86.514435"
+ gradientTransform="matrix(0.281643,-1.886110e-2,0.000000,0.179517,-4.383105,-16.75305)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient13047"
+ xlink:href="#light100to0"
+ inkscape:collect="always" />
+ <radialGradient
+ r="83.259750"
+ fy="332.37268"
+ fx="86.514435"
+ cy="332.37268"
+ cx="86.514435"
+ gradientTransform="matrix(0.281643,-1.886110e-2,0.000000,0.179517,-4.383105,-16.75305)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient13045"
+ xlink:href="#wihitetolightgray"
+ inkscape:collect="always" />
+ <linearGradient
+ id="linearGradient18012">
+ <stop
+ id="stop18014"
+ offset="0.0000000"
+ style="stop-color:#ffffff;stop-opacity:1.0000000;" />
+ <stop
+ id="stop18016"
+ offset="1.0000000"
+ style="stop-color:#ffffff;stop-opacity:0.0000000;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient18006">
+ <stop
+ id="stop18008"
+ offset="0.0000000"
+ style="stop-color:#ff8b00;stop-opacity:1.0000000;" />
+ <stop
+ id="stop18010"
+ offset="1.0000000"
+ style="stop-color:#4d0200;stop-opacity:1.0000000;" />
+ </linearGradient>
+ <linearGradient
+ id="light50to25to7">
+ <stop
+ id="stop2791"
+ offset="0.0000000"
+ style="stop-color:#ffffff;stop-opacity:0.47450981;" />
+ <stop
+ id="stop2795"
+ offset="0.50000000"
+ style="stop-color:#ffffff;stop-opacity:0.25833333;" />
+ <stop
+ id="stop2793"
+ offset="1.0000000"
+ style="stop-color:#ffffff;stop-opacity:0.10833333;" />
+ </linearGradient>
+ <linearGradient
+ id="shadow100to0">
+ <stop
+ id="stop3425"
+ offset="0.0000000"
+ style="stop-color:#000000;stop-opacity:1.0000000;" />
+ <stop
+ id="stop3426"
+ offset="1.0000000"
+ style="stop-color:#000000;stop-opacity:0.0000000;" />
+ </linearGradient>
+ <linearGradient
+ id="graytoblack">
+ <stop
+ id="stop5097"
+ offset="0.0000000"
+ style="stop-color:#7d7d7d;stop-opacity:1.0000000;" />
+ <stop
+ id="stop5098"
+ offset="1.0000000"
+ style="stop-color:#000000;stop-opacity:1.0000000;" />
+ </linearGradient>
+ <linearGradient
+ id="orangemoretoyelow">
+ <stop
+ id="stop2671"
+ offset="0.0000000"
+ style="stop-color:#ff7d00;stop-opacity:1.0000000;" />
+ <stop
+ id="stop2679"
+ offset="0.74641621"
+ style="stop-color:#ffbe00;stop-opacity:1.0000000;" />
+ <stop
+ id="stop2672"
+ offset="1.0000000"
+ style="stop-color:#ffff00;stop-opacity:1.0000000;" />
+ </linearGradient>
+ <linearGradient
+ id="wihitetolightgray">
+ <stop
+ id="stop1885"
+ offset="0.0000000"
+ style="stop-color:#ffffff;stop-opacity:1.0000000;" />
+ <stop
+ id="stop1886"
+ offset="1.0000000"
+ style="stop-color:#d5d4d4;stop-opacity:1.0000000;" />
+ </linearGradient>
+ <linearGradient
+ y2="13.431447"
+ x2="14.101834"
+ y1="6.5494914"
+ x1="4.4536543"
+ gradientTransform="matrix(0.791643,0.000000,0.000000,1.263196,-1.626700,-5.630763)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient7931"
+ xlink:href="#light90to0"
+ inkscape:collect="always" />
+ <linearGradient
+ id="light90to0">
+ <stop
+ id="stop1890"
+ offset="0.0000000"
+ style="stop-color:#ffffff;stop-opacity:0.90833336;" />
+ <stop
+ id="stop1892"
+ offset="1.0000000"
+ style="stop-color:#ffffff;stop-opacity:0.0000000;" />
+ </linearGradient>
+ <radialGradient
+ r="5.8189325"
+ fy="9.5002232"
+ fx="8.0907059"
+ cy="9.5002232"
+ cx="8.0907059"
+ gradientTransform="scale(0.665867,1.501801)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient7933"
+ xlink:href="#light90to0"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="41.545322"
+ x2="22.396454"
+ y1="35.206337"
+ x1="22.425571"
+ gradientTransform="matrix(2.503650,0.000000,0.000000,0.399417,-16.65916,-12.48664)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient7935"
+ xlink:href="#light90to0"
+ inkscape:collect="always" />
+ <radialGradient
+ r="14.270030"
+ fy="51.904903"
+ fx="25.923746"
+ cy="52.497688"
+ cx="25.952410"
+ gradientTransform="matrix(2.633416,0.000000,0.000000,0.379735,-16.65916,-12.48664)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient7937"
+ xlink:href="#light90to0"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="85.112236"
+ x2="-21.621279"
+ y1="81.885979"
+ x1="-16.569721"
+ gradientTransform="matrix(0.000000,-2.503650,0.399417,0.000000,26.44710,-31.82936)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient7939"
+ xlink:href="#light90to0"
+ inkscape:collect="always" />
+ <radialGradient
+ r="8.5514765"
+ fy="95.221397"
+ fx="-23.859682"
+ cy="95.221397"
+ cx="-23.859682"
+ gradientTransform="matrix(0.000000,-2.592685,0.379735,0.000000,26.44710,-31.22442)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient7941"
+ xlink:href="#light90to0"
+ inkscape:collect="always" />
+ <radialGradient
+ r="9.9914455"
+ fy="55.457653"
+ fx="92.643608"
+ cy="55.457653"
+ cx="92.643608"
+ gradientTransform="matrix(0.878497,0.000000,0.000000,1.138308,-18.65916,-0.486640)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient7943"
+ xlink:href="#light90to0"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="85.112236"
+ x2="-21.621279"
+ y1="81.885979"
+ x1="-16.569721"
+ gradientTransform="matrix(0.000000,-2.503650,0.399417,0.000000,26.44710,4.170640)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient7945"
+ xlink:href="#light90to0"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="41.545322"
+ x2="22.396454"
+ y1="35.206337"
+ x1="22.425571"
+ gradientTransform="matrix(2.503650,0.000000,0.000000,0.399417,-38.65916,-12.48664)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient7947"
+ xlink:href="#light90to0"
+ inkscape:collect="always" />
+ <radialGradient
+ r="14.270030"
+ fy="51.904903"
+ fx="25.923746"
+ cy="52.497688"
+ cx="25.952410"
+ gradientTransform="matrix(2.633416,0.000000,0.000000,0.379735,-38.65916,-12.48664)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient7949"
+ xlink:href="#light90to0"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="41.545322"
+ x2="22.396454"
+ y1="35.206337"
+ x1="22.425571"
+ gradientTransform="matrix(2.503650,0.000000,0.000000,0.399417,-22.86332,44.21180)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient7951"
+ xlink:href="#light90to0"
+ inkscape:collect="always" />
+ <radialGradient
+ r="14.270030"
+ fy="51.904903"
+ fx="25.923746"
+ cy="52.497688"
+ cx="25.952410"
+ gradientTransform="matrix(2.633416,0.000000,0.000000,0.379735,-22.86332,44.21180)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient7953"
+ xlink:href="#light90to0"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="41.545322"
+ x2="22.396454"
+ y1="35.206337"
+ x1="22.425571"
+ gradientTransform="matrix(2.503650,0.000000,0.000000,0.399417,-44.86332,44.21180)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient7955"
+ xlink:href="#light90to0"
+ inkscape:collect="always" />
+ <radialGradient
+ r="14.270030"
+ fy="51.904903"
+ fx="25.923746"
+ cy="52.497688"
+ cx="25.952410"
+ gradientTransform="matrix(2.633416,0.000000,0.000000,0.379735,-44.86332,44.21180)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient7957"
+ xlink:href="#light90to0"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="85.112236"
+ x2="-21.621279"
+ y1="81.885979"
+ x1="-16.569721"
+ gradientTransform="matrix(0.000000,-2.503650,0.399417,0.000000,26.44710,-11.82936)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient7959"
+ xlink:href="#light90to0"
+ inkscape:collect="always" />
+ <radialGradient
+ r="8.5514765"
+ fy="95.221397"
+ fx="-23.859682"
+ cy="95.221397"
+ cx="-23.859682"
+ gradientTransform="matrix(0.000000,-2.592685,0.379735,0.000000,26.44710,-11.22442)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient7961"
+ xlink:href="#light90to0"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="85.112236"
+ x2="-21.621279"
+ y1="81.885979"
+ x1="-16.569721"
+ gradientTransform="matrix(0.000000,-2.503650,0.399417,0.000000,-30.45690,-21.82936)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient7963"
+ xlink:href="#light90to0"
+ inkscape:collect="always" />
+ <radialGradient
+ r="8.5514765"
+ fy="95.221397"
+ fx="-23.859682"
+ cy="95.221397"
+ cx="-23.859682"
+ gradientTransform="matrix(0.000000,-2.592685,0.379735,0.000000,-30.45690,-21.22442)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient7965"
+ xlink:href="#light90to0"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="85.112236"
+ x2="-21.621279"
+ y1="81.885979"
+ x1="-16.569721"
+ gradientTransform="matrix(0.000000,-2.503650,0.399417,0.000000,-30.45690,-1.829360)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient7967"
+ xlink:href="#light90to0"
+ inkscape:collect="always" />
+ <radialGradient
+ r="8.5514765"
+ fy="95.221397"
+ fx="-23.859682"
+ cy="95.221397"
+ cx="-23.859682"
+ gradientTransform="matrix(0.000000,-2.592685,0.379735,0.000000,-30.45690,-1.224420)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient7969"
+ xlink:href="#light90to0"
+ inkscape:collect="always" />
+ <radialGradient
+ gradientUnits="userSpaceOnUse"
+ r="31.677956"
+ fy="46.914463"
+ fx="48.488476"
+ cy="46.914463"
+ cx="48.488476"
+ gradientTransform="matrix(0.983903,0.000000,0.000000,1.016360,-33.35882,-2.298655)"
+ id="radialGradient10280"
+ xlink:href="#light90to0"
+ inkscape:collect="always" />
+ <linearGradient
+ gradientUnits="userSpaceOnUse"
+ y2="36.873619"
+ x2="39.857029"
+ y1="4.5492039"
+ x1="10.878086"
+ gradientTransform="matrix(0.996235,0.000000,0.000000,1.003779,-32.74998,-1.298655)"
+ id="linearGradient9512"
+ xlink:href="#light90to0"
+ inkscape:collect="always" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#light100to0"
+ id="linearGradient18107"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.281643,-1.886110e-2,0.000000,0.179517,-4.383105,-16.75305)"
+ x1="86.514435"
+ y1="335.76117"
+ x2="73.286217"
+ y2="247.07323" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#light100to0"
+ id="linearGradient18109"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.195716,-1.310673e-2,0.000000,0.258334,-4.383105,-16.75305)"
+ x1="136.55682"
+ y1="213.43617"
+ x2="54.607849"
+ y2="250.54321" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#light100to0"
+ id="linearGradient18111"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.180988,-1.212046e-2,0.000000,0.279356,-4.383105,-16.75305)"
+ x1="159.18221"
+ y1="219.68500"
+ x2="184.11906"
+ y2="234.35374" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#light90to0"
+ id="linearGradient1589"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.996235,0.000000,0.000000,1.003779,-32.74998,-1.298655)"
+ x1="10.878086"
+ y1="4.5492039"
+ x2="39.857029"
+ y2="36.873619" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#greylighttograyw"
+ id="linearGradient1591"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.068635,-0.180647,0.153793,0.909776,-23.61859,31.63539)"
+ spreadMethod="reflect"
+ x1="139.84422"
+ y1="169.79622"
+ x2="159.03880"
+ y2="203.17725" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#orangelesstoyelow"
+ id="linearGradient1593"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.008016,-3.957640e-17,-8.345152e-17,0.992047,59.09612,34.16495)"
+ spreadMethod="reflect"
+ x1="139.79741"
+ y1="100.63807"
+ x2="198.67084"
+ y2="227.49260" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#orangetoblackorange"
+ id="linearGradient1595"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="scale(0.994153,1.005881)"
+ x1="211.31139"
+ y1="208.29716"
+ x2="186.14693"
+ y2="101.48473" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#zerotowhitetozero"
+ id="linearGradient1597"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.918796,-4.448298e-7,2.186431e-9,1.088383,-31.71369,41.04076)"
+ x1="130.94159"
+ y1="136.24300"
+ x2="141.97820"
+ y2="119.97503" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#zerotowhitetozero"
+ id="linearGradient1599"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.068635,-0.180647,0.153793,0.909776,-23.61859,31.63539)"
+ x1="121.55471"
+ y1="169.77112"
+ x2="130.17465"
+ y2="182.88293" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#zerotowhitetozero"
+ id="linearGradient1601"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.068635,-0.180647,0.153793,0.909776,-5.706373e-15,-6.128776e-15)"
+ x1="111.31033"
+ y1="198.13455"
+ x2="135.19012"
+ y2="235.01132" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#light100to0"
+ id="radialGradient1603"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.952120,-0.160951,0.172613,1.021109,-23.61859,31.63539)"
+ cx="140.60791"
+ cy="183.52762"
+ fx="140.60791"
+ fy="183.52762"
+ r="8.2203732" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#light100to0"
+ id="radialGradient1605"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.952120,-0.160951,0.172613,1.021109,-23.57515,31.60495)"
+ cx="124.97867"
+ cy="166.89621"
+ fx="124.97867"
+ fy="166.89621"
+ r="4.5374427" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#zerotowhitetozero"
+ id="radialGradient1607"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.917031,-0.155019,0.179218,1.060181,-23.61859,31.63539)"
+ cx="130.43364"
+ cy="187.24419"
+ fx="130.40277"
+ fy="187.29732"
+ r="13.523715" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#zerotowhitetozero"
+ id="radialGradient1609"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.277707,-1.314622,0.656307,0.494064,-23.61859,31.63539)"
+ spreadMethod="reflect"
+ cx="-36.280697"
+ cy="224.72163"
+ fx="-36.269680"
+ fy="224.71202"
+ r="14.292608" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#sadow75to0w"
+ id="linearGradient1611"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.919303,-5.848951e-16,-9.825667e-17,1.087781,-31.65752,40.91072)"
+ spreadMethod="reflect"
+ x1="131.99300"
+ y1="129.27406"
+ x2="134.97223"
+ y2="132.72443" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#zerotowhitetozero"
+ id="linearGradient1613"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.919303,-5.848951e-16,-9.825667e-17,1.087781,-31.65752,40.91072)"
+ x1="132.47713"
+ y1="128.17326"
+ x2="138.51009"
+ y2="135.55878" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#zerotowhitetozero"
+ id="radialGradient1615"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.917031,-0.155019,0.179218,1.060181,-23.61859,31.63539)"
+ cx="130.43364"
+ cy="187.24419"
+ fx="130.40277"
+ fy="187.29732"
+ r="13.523715" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#zerotowhitetozero"
+ id="radialGradient1617"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.917031,-0.155019,0.179218,1.060181,-23.61859,31.63539)"
+ cx="130.43364"
+ cy="187.24419"
+ fx="130.40277"
+ fy="187.29732"
+ r="13.523715" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#zerotowhitetozero"
+ id="radialGradient1619"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.917031,-0.155019,0.179218,1.060181,-23.61859,31.63539)"
+ cx="130.43364"
+ cy="187.24419"
+ fx="130.40277"
+ fy="187.29732"
+ r="13.523715" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#zerotowhitetozero"
+ id="radialGradient1621"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.917031,-0.155019,0.179218,1.060181,-23.61859,31.63539)"
+ cx="130.43364"
+ cy="187.24419"
+ fx="130.40277"
+ fy="187.29732"
+ r="13.523715" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#zerotowhitetozero"
+ id="radialGradient1623"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.917031,-0.155019,0.179218,1.060181,-23.61859,31.63539)"
+ cx="130.43364"
+ cy="187.24419"
+ fx="130.40277"
+ fy="187.29732"
+ r="13.523715" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#zerotowhitetozero"
+ id="linearGradient1625"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="scale(0.889037,1.124812)"
+ spreadMethod="reflect"
+ x1="239.13113"
+ y1="150.76836"
+ x2="219.65416"
+ y2="118.38348" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#light100to0"
+ id="linearGradient1627"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="scale(1.205925,0.829239)"
+ x1="165.24026"
+ y1="140.82243"
+ x2="166.34229"
+ y2="163.71248" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#zerotowhitetozero"
+ id="linearGradient1629"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="scale(0.889037,1.124812)"
+ spreadMethod="reflect"
+ x1="239.13113"
+ y1="150.76836"
+ x2="219.65416"
+ y2="118.38348" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#zerotowhitetozero"
+ id="linearGradient1631"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="scale(0.889037,1.124812)"
+ spreadMethod="reflect"
+ x1="239.13113"
+ y1="150.76836"
+ x2="219.65416"
+ y2="118.38348" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#zerotowhitetozero"
+ id="linearGradient1633"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="scale(0.889037,1.124812)"
+ spreadMethod="reflect"
+ x1="239.13113"
+ y1="150.76836"
+ x2="219.65416"
+ y2="118.38348" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#light90to0"
+ id="linearGradient1683"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.996235,0.000000,0.000000,1.003779,-32.74998,-1.298655)"
+ x1="10.878086"
+ y1="4.5492039"
+ x2="39.857029"
+ y2="36.873619" />
+ <linearGradient
+ y2="118.38348"
+ x2="219.65416"
+ y1="150.76836"
+ x1="239.13113"
+ spreadMethod="reflect"
+ gradientTransform="matrix(0.319331,-7.293299e-2,9.428053e-2,0.413393,-13.56014,-24.84285)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1521"
+ xlink:href="#zerotowhitetozero"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="118.38348"
+ x2="219.65416"
+ y1="150.76836"
+ x1="239.13113"
+ spreadMethod="reflect"
+ gradientTransform="matrix(0.319331,-7.293299e-2,9.428053e-2,0.413393,-13.56014,-24.84285)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1524"
+ xlink:href="#zerotowhitetozero"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="118.38348"
+ x2="219.65416"
+ y1="150.76836"
+ x1="239.13113"
+ spreadMethod="reflect"
+ gradientTransform="matrix(0.319331,-7.293299e-2,9.428053e-2,0.413393,-13.56014,-24.84285)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1527"
+ xlink:href="#zerotowhitetozero"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="163.71248"
+ x2="166.34229"
+ y1="140.82243"
+ x1="165.24026"
+ gradientTransform="matrix(0.433153,-9.892919e-2,6.950592e-2,0.304764,-13.56014,-24.84285)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1530"
+ xlink:href="#light100to0"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="118.38348"
+ x2="219.65416"
+ y1="150.76836"
+ x1="239.13113"
+ spreadMethod="reflect"
+ gradientTransform="matrix(0.319331,-7.293299e-2,9.428053e-2,0.413393,-13.56014,-24.84285)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1533"
+ xlink:href="#zerotowhitetozero"
+ inkscape:collect="always" />
+ <radialGradient
+ r="13.523715"
+ fy="187.29732"
+ fx="130.40277"
+ cy="187.24419"
+ cx="130.43364"
+ gradientTransform="matrix(0.316392,-0.132202,0.153236,0.374938,-39.39199,-11.27857)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient1538"
+ xlink:href="#zerotowhitetozero"
+ inkscape:collect="always" />
+ <radialGradient
+ r="13.523715"
+ fy="187.29732"
+ fx="130.40277"
+ cy="187.24419"
+ cx="130.43364"
+ gradientTransform="matrix(0.316392,-0.132202,0.153236,0.374938,-39.39199,-11.27857)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient1541"
+ xlink:href="#zerotowhitetozero"
+ inkscape:collect="always" />
+ <radialGradient
+ r="13.523715"
+ fy="187.29732"
+ fx="130.40277"
+ cy="187.24419"
+ cx="130.43364"
+ gradientTransform="matrix(0.316392,-0.132202,0.153236,0.374938,-39.39199,-11.27857)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient1544"
+ xlink:href="#zerotowhitetozero"
+ inkscape:collect="always" />
+ <radialGradient
+ r="13.523715"
+ fy="187.29732"
+ fx="130.40277"
+ cy="187.24419"
+ cx="130.43364"
+ gradientTransform="matrix(0.316392,-0.132202,0.153236,0.374938,-39.39199,-11.27857)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient1547"
+ xlink:href="#zerotowhitetozero"
+ inkscape:collect="always" />
+ <radialGradient
+ r="13.523715"
+ fy="187.29732"
+ fx="130.40277"
+ cy="187.24419"
+ cx="130.43364"
+ gradientTransform="matrix(0.316392,-0.132202,0.153236,0.374938,-39.39199,-11.27857)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient1550"
+ xlink:href="#zerotowhitetozero"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="135.55878"
+ x2="138.51009"
+ y1="128.17326"
+ x1="132.47713"
+ gradientTransform="matrix(0.339274,-2.885214e-16,-7.500068e-18,0.409774,-35.72368,-9.866746)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1553"
+ xlink:href="#zerotowhitetozero"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="132.72443"
+ x2="134.97223"
+ y1="129.27406"
+ x1="131.99300"
+ spreadMethod="reflect"
+ gradientTransform="matrix(0.339274,-2.885214e-16,-7.500068e-18,0.409774,-35.72368,-9.866746)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1556"
+ xlink:href="#sadow75to0w"
+ inkscape:collect="always" />
+ <radialGradient
+ r="14.292608"
+ fy="224.71202"
+ fx="-36.269680"
+ cy="224.72163"
+ cx="-36.280697"
+ spreadMethod="reflect"
+ gradientTransform="matrix(-1.044145e-2,-0.505934,0.277149,0.127739,-39.39199,-11.27857)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient1559"
+ xlink:href="#zerotowhitetozero"
+ inkscape:collect="always" />
+ <radialGradient
+ r="13.523715"
+ fy="187.29732"
+ fx="130.40277"
+ cy="187.24419"
+ cx="130.43364"
+ gradientTransform="matrix(0.316392,-0.132202,0.153236,0.374938,-39.39199,-11.27857)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient1562"
+ xlink:href="#zerotowhitetozero"
+ inkscape:collect="always" />
+ <radialGradient
+ r="4.5374427"
+ fy="166.89621"
+ fx="124.97867"
+ cy="166.89621"
+ cx="124.97867"
+ gradientTransform="matrix(0.328498,-0.137261,0.147589,0.361120,-39.37893,-11.29333)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient1565"
+ xlink:href="#light100to0"
+ inkscape:collect="always" />
+ <radialGradient
+ r="8.2203732"
+ fy="183.52762"
+ fx="140.60791"
+ cy="183.52762"
+ cx="140.60791"
+ gradientTransform="matrix(0.328498,-0.137261,0.147589,0.361120,-39.39199,-11.27857)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient1568"
+ xlink:href="#light100to0"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="235.01132"
+ x2="135.19012"
+ y1="198.13455"
+ x1="111.31033"
+ gradientTransform="matrix(0.368698,-0.154058,0.131497,0.321746,-33.56014,-24.84285)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1571"
+ xlink:href="#zerotowhitetozero"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="182.88293"
+ x2="130.17465"
+ y1="169.77112"
+ x1="121.55471"
+ gradientTransform="matrix(0.368698,-0.154058,0.131497,0.321746,-39.39199,-11.27857)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1574"
+ xlink:href="#zerotowhitetozero"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="119.97503"
+ x2="141.97820"
+ y1="136.24300"
+ x1="130.94159"
+ gradientTransform="matrix(0.339102,-1.675700e-7,8.069510e-10,0.410000,-35.78877,-9.716957)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1577"
+ xlink:href="#zerotowhitetozero"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="227.49260"
+ x2="198.67084"
+ y1="100.63807"
+ x1="139.79741"
+ spreadMethod="reflect"
+ gradientTransform="matrix(0.362066,-8.269354e-2,8.315231e-2,0.364599,-9.469913,-17.13449)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1581"
+ xlink:href="#orangelesstoyelow"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="101.48473"
+ x2="186.14693"
+ y1="208.29716"
+ x1="211.31139"
+ gradientTransform="matrix(0.357087,-8.155628e-2,8.431186e-2,0.369683,-33.56014,-24.84285)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1583"
+ xlink:href="#orangetoblackorange"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="203.17725"
+ x2="159.03880"
+ y1="169.79622"
+ x1="139.84422"
+ spreadMethod="reflect"
+ gradientTransform="matrix(0.368698,-0.154058,0.131497,0.321746,-39.39199,-11.27857)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1587"
+ xlink:href="#greylighttograyw"
+ inkscape:collect="always" />
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="5.6562500"
+ inkscape:cx="32.000000"
+ inkscape:cy="28.069417"
+ inkscape:current-layer="svg17707"
+ showgrid="false"
+ inkscape:document-units="px"
+ inkscape:grid-bbox="true"
+ inkscape:window-width="1020"
+ inkscape:window-height="691"
+ inkscape:window-x="0"
+ inkscape:window-y="0" />
+ <metadata
+ id="metadata4">
+ <rdf:RDF
+ id="RDF5">
+ <cc:Work
+ rdf:about=""
+ id="Work6">
+ <dc:format
+ id="format7">image/svg+xml</dc:format>
+ <dc:type
+ id="type9"
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ id="g1508"
+ transform="matrix(0.941176,0.000000,0.000000,0.928006,27.63182,14.26213)">
+ <path
+ id="rect7971"
+ d="M -22.672010,-0.29866329 L 15.954371,-0.29866329 C 17.996863,-0.29866329 19.641180,1.8444887 19.641180,4.5066107 L 19.641180,42.413492 C 19.641180,45.075614 17.996863,47.218766 15.954371,47.218766 L -22.672010,47.218766 C -24.714502,47.218766 -26.358819,45.075614 -26.358819,42.413492 L -26.358819,4.5066107 C -26.358819,1.8444887 -24.714502,-0.29866329 -22.672010,-0.29866329 z "
+ style="opacity:0.79446638;fill:#0028c6;fill-opacity:0.18099548;stroke:#000000;stroke-width:0.0000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:0.035294119" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path8746"
+ d="M -22.063169,0.70133671 L 16.563212,0.70133671 C 18.221266,26.074276 -6.9124940,11.860590 -25.749978,43.413492 L -25.749978,5.5066107 C -25.749978,2.8444887 -24.105661,0.70133671 -22.063169,0.70133671 z "
+ style="opacity:0.79446638;fill:url(#linearGradient1683);fill-opacity:1.0000000;stroke:#000000;stroke-width:0.0000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:0.035294119" />
+ <path
+ id="path7697"
+ d="M -27.017489,-2.3989893 C -27.634507,-2.4157123 -28.231851,-2.1778653 -28.673074,-1.7397773 C -29.114296,-1.3016903 -29.361708,-0.70078429 -29.358794,-0.074320286 L -29.358794,7.2871317 C -29.358794,8.5710117 -28.333344,9.6118007 -27.068387,9.6118007 C -25.803430,9.6118007 -24.777980,8.5710117 -24.777980,7.2871317 L -24.777980,2.2761787 L -23.047450,2.3020077 C -22.210634,2.3584147 -21.410841,1.9440847 -20.964931,1.2231677 C -20.519022,0.50225171 -20.498961,-0.40890429 -20.912697,-1.1493183 C -21.326432,-1.8897313 -22.107191,-2.3399103 -22.945654,-2.3215003 L -27.017489,-2.3989893 z "
+ style="fill:#343435;fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:5.5999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000" />
+ <path
+ sodipodi:nodetypes="cccccccc"
+ id="path7695"
+ d="M 4.7173740,-2.3996693 C 3.4524170,-2.4139343 2.4155730,-1.3847093 2.4015180,-0.10083029 C 2.3874630,1.1830497 3.4015190,2.2354037 4.6664760,2.2496687 L 14.362533,2.3788167 C 15.201936,2.4293217 16.000613,2.0068887 16.440691,1.2796477 C 16.880768,0.55240471 16.890831,-0.36162729 16.466873,-1.0986683 C 16.042914,-1.8357073 15.253736,-2.2761473 14.413431,-2.2446913 L 4.7173740,-2.3996693 z "
+ style="fill:#343435;fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:5.5999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000" />
+ <path
+ sodipodi:nodetypes="cccccccccc"
+ id="path1937"
+ d="M 19.325083,2.8678727 C 18.716776,2.8719947 18.135305,3.1226217 17.709963,3.5640277 C 17.284621,4.0054337 17.050668,4.6010267 17.060125,5.2183717 L 17.060125,15.059471 C 17.060125,16.343351 18.085575,17.384140 19.350532,17.384140 C 20.615489,17.384140 21.640939,16.343351 21.640939,15.059471 L 21.640939,5.2183717 C 21.650596,4.5920277 21.409706,3.9884577 20.973288,3.5455107 C 20.536870,3.1025647 19.942196,2.8580717 19.325083,2.8678727 L 19.325083,2.8678727 z "
+ style="fill:#343435;fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:5.5999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000" />
+ <path
+ sodipodi:nodetypes="cccccccc"
+ id="path4304"
+ d="M 17.469045,15.629181 C 18.413100,15.815021 18.857757,12.747829 18.787749,8.0727497 C 18.730382,4.3058467 20.289306,5.8257017 20.406837,3.7850817 C 20.424951,3.4705687 20.006991,3.3070317 19.501480,3.3228087 C 18.995969,3.3385857 18.402909,3.5336767 18.070823,3.9364157 C 17.881055,4.0953987 17.733643,4.3228087 17.633611,4.5892757 C 17.533580,4.8557427 17.480928,5.1612677 17.480686,5.4764867 C 17.480443,5.7917047 17.470985,13.110517 17.469045,15.629181 z "
+ style="fill:#343435;fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:5.5999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000" />
+ <path
+ sodipodi:nodetypes="cccccccc"
+ id="path4306"
+ d="M 18.559674,14.805816 C 18.551108,15.772956 19.169111,16.565687 19.940024,16.576434 C 20.710936,16.587180 21.342828,15.811869 21.351393,14.844730 L 21.428941,5.1347497 C 21.459268,4.4929737 21.205614,3.8823327 20.768938,3.5458657 C 20.332262,3.2094007 19.783427,3.2017067 19.340866,3.5258487 C 18.898307,3.8499917 18.633842,4.4533697 18.652730,5.0958337 L 18.559674,14.805816 z "
+ style="opacity:0.79446638;fill:#343435;fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:5.5999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000" />
+ <path
+ id="path7691"
+ d="M 19.325083,37.172044 C 18.716776,37.176166 18.135305,37.426793 17.709963,37.868200 C 17.284621,38.309605 17.050668,38.905198 17.060125,39.522543 L 17.060125,44.636815 L 15.278697,44.636815 C 14.013740,44.636815 12.988290,45.677605 12.988290,46.961484 C 12.988290,48.245364 14.013740,49.286153 15.278697,49.286153 L 19.350532,49.286153 C 19.958797,49.288854 20.542918,49.044801 20.973031,48.608254 C 21.403144,48.171707 21.643600,47.578848 21.640939,46.961484 L 21.640939,39.522543 C 21.650596,38.896199 21.409706,38.292629 20.973288,37.849682 C 20.536870,37.406736 19.942196,37.162243 19.325083,37.172044 z "
+ style="fill:#343435;fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:5.5999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000" />
+ <path
+ sodipodi:nodetypes="cccccccc"
+ id="path7751"
+ d="M -20.276241,44.557850 C -21.426599,44.557629 -22.359001,45.598301 -22.358820,46.882257 C -22.358640,48.166214 -21.425944,49.207246 -20.275587,49.207467 L -11.457752,49.228967 C -10.693981,49.270151 -9.9720160,48.838877 -9.5791980,48.106796 C -9.1863820,47.374712 -9.1864600,46.460625 -9.5794010,45.728336 C -9.9723420,44.996049 -10.694380,44.564397 -11.458145,44.605179 L -20.276241,44.557850 z "
+ style="fill:#343435;fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:5.5999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000" />
+ <path
+ sodipodi:nodetypes="cccccccccc"
+ id="path7775"
+ d="M -27.015658,12.745151 C -27.623965,12.748858 -28.205436,12.974268 -28.630778,13.371262 C -29.056120,13.768256 -29.290073,14.303923 -29.280616,14.859155 L -29.280616,23.710092 C -29.280616,24.864795 -28.255166,25.800865 -26.990209,25.800865 C -25.725252,25.800865 -24.699802,24.864795 -24.699802,23.710092 L -24.699802,14.859155 C -24.690145,14.295830 -24.931035,13.752988 -25.367452,13.354609 C -25.803871,12.956229 -26.398545,12.736336 -27.015658,12.745151 L -27.015658,12.745151 z "
+ style="fill:#343435;fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:5.5999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000" />
+ <path
+ sodipodi:nodetypes="cccccccccc"
+ id="path7781"
+ d="M -27.015658,30.753110 C -27.623965,30.756942 -28.205436,30.989917 -28.630778,31.400235 C -29.056120,31.810552 -29.290073,32.364197 -29.280616,32.938062 L -29.280616,42.086048 C -29.280616,43.279504 -28.255166,44.246990 -26.990209,44.246990 C -25.725252,44.246990 -24.699802,43.279504 -24.699802,42.086048 L -24.699802,32.938062 C -24.690145,32.355832 -24.931035,31.794772 -25.367452,31.383022 C -25.803871,30.971273 -26.398545,30.743999 -27.015658,30.753110 L -27.015658,30.753110 z "
+ style="fill:#343435;fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:5.5999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000" />
+ <path
+ sodipodi:nodetypes="cccccccccc"
+ id="path20031"
+ d="M 19.186414,18.552305 C 18.578107,18.556137 17.996636,18.789112 17.571294,19.199430 C 17.145953,19.609747 16.912000,20.163392 16.921456,20.737257 L 16.921456,29.885243 C 16.921456,31.078699 17.946906,32.046185 19.211863,32.046185 C 20.476820,32.046185 21.502270,31.078699 21.502270,29.885243 L 21.502270,20.737257 C 21.511927,20.155027 21.271037,19.593967 20.834620,19.182217 C 20.398201,18.770468 19.803527,18.543194 19.186414,18.552305 L 19.186414,18.552305 z "
+ style="fill:#343435;fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:5.5999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000" />
+ <path
+ sodipodi:nodetypes="cccccccc"
+ id="path20029"
+ d="M -2.2762410,44.557850 C -3.4265990,44.557629 -4.3590010,45.598301 -4.3588200,46.882257 C -4.3586390,48.166214 -3.4259440,49.207246 -2.2755870,49.207467 L 6.5422480,49.228967 C 7.3060190,49.270151 8.0279840,48.838877 8.4208020,48.106796 C 8.8136180,47.374712 8.8135400,46.460625 8.4205990,45.728336 C 8.0276580,44.996049 7.3056200,44.564397 6.5418550,44.605179 L -2.2762410,44.557850 z "
+ style="fill:#343435;fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:5.5999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000" />
+ <path
+ sodipodi:nodetypes="cccccccc"
+ id="path20033"
+ d="M -14.276241,-2.4376393 C -15.426599,-2.4378603 -16.359001,-1.3971883 -16.358820,-0.11323229 C -16.358639,1.1707247 -15.425944,2.2117567 -14.275587,2.2119777 L -5.4577520,2.2334777 C -4.6939810,2.2746617 -3.9720160,1.8433877 -3.5791980,1.1113067 C -3.1863820,0.37922271 -3.1864600,-0.53486429 -3.5794010,-1.2671533 C -3.9723420,-1.9994403 -4.6943800,-2.4310923 -5.4581450,-2.3903103 L -14.276241,-2.4376393 z "
+ style="fill:#343435;fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:5.5999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000" />
+ </g>
+ <g
+ transform="matrix(0.138177,0.000000,0.000000,0.138257,87.66417,90.01531)"
+ id="g13710">
+ <path
+ id="path11931"
+ d="M -339.87500,-562.53125 C -348.58569,-560.19181 -352.59558,-550.93590 -359.43799,-545.70947 C -400.13675,-505.05011 -440.77483,-464.31985 -480.90625,-423.12500 C -488.18544,-410.84910 -488.57103,-394.62620 -500.21875,-385.09375 C -512.57969,-368.83179 -493.71621,-341.25818 -474.03125,-348.46875 C -462.87531,-352.89885 -454.65140,-363.31654 -442.27737,-364.87405 C -422.26991,-370.77618 -410.50805,-389.32181 -395.67326,-402.58313 C -357.90771,-440.29554 -320.13784,-478.00363 -282.37500,-515.71875 C -304.24739,-521.94254 -323.63528,-537.78263 -331.84375,-559.21875 C -333.74226,-561.73503 -336.74020,-563.06552 -339.87500,-562.53125 z "
+ style="fill:url(#linearGradient13735);fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:0.12500000;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000" />
+ <path
+ id="path9921"
+ d="M -248.21875,-651.00000 C -272.98861,-648.93037 -291.28010,-629.68275 -305.01089,-610.67441 C -309.74512,-604.20687 -315.77838,-598.30024 -323.87075,-596.72703 C -333.71425,-591.10503 -341.85744,-582.42201 -348.40590,-573.28134 C -356.94664,-559.26149 -347.65041,-543.09265 -338.40023,-532.09521 C -325.64008,-517.98152 -310.00267,-502.74422 -289.90668,-501.76041 C -276.01725,-502.20182 -266.41769,-514.40996 -257.37500,-523.56250 C -253.67156,-531.93631 -250.48772,-541.23540 -242.11203,-546.09451 C -225.14025,-560.83248 -205.84726,-576.48649 -201.47173,-599.85041 C -196.42613,-618.96398 -206.88605,-640.92302 -225.80992,-647.67024 C -232.89201,-650.60139 -240.61145,-651.32708 -248.21875,-651.00000 z "
+ style="fill:url(#linearGradient13737);fill-opacity:1.0000000;stroke:none;stroke-width:0.85625488;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000" />
+ <g
+ transform="matrix(12.73027,0.137313,-0.136532,12.81415,7258.558,2532.625)"
+ id="g9797">
+ <path
+ sodipodi:nodetypes="csccccsss"
+ id="path1748"
+ d="M -592.17375,-241.34258 C -593.22346,-241.27560 -593.89434,-240.80940 -594.54434,-240.26028 C -596.02721,-239.00754 -596.59699,-237.07947 -597.79980,-237.13371 C -598.41374,-236.45764 -598.16875,-235.86990 -597.94968,-235.36640 C -597.14476,-234.02668 -596.25974,-233.23302 -595.17964,-232.76588 C -594.79886,-232.65612 -593.80858,-232.70213 -593.38704,-233.02313 C -593.17176,-234.17444 -592.02724,-234.45349 -590.47137,-236.07679 C -589.39077,-237.20372 -589.00732,-238.90820 -589.39094,-239.80855 C -589.72572,-240.59428 -590.59454,-241.44334 -592.17375,-241.34258 z "
+ style="fill:url(#linearGradient13739);fill-opacity:1.0000000;stroke:url(#linearGradient13741);stroke-width:0.033576056;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path1750"
+ d="M -595.92745,-235.45451 C -594.37002,-236.99404 -592.53504,-238.28074 -590.97762,-239.82027 C -589.95578,-239.82640 -589.36868,-238.72428 -589.80124,-237.37356 C -591.48098,-235.57587 -593.09300,-233.31300 -594.77274,-231.51531 C -594.17986,-233.13605 -595.03454,-235.13095 -595.92745,-235.45451 z "
+ style="opacity:0.41897234;fill:url(#linearGradient13743);fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:1.0000000px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000" />
+ <path
+ sodipodi:nodetypes="czzzzzz"
+ id="path1752"
+ d="M -592.10692,-241.16843 C -591.40492,-241.26355 -591.32655,-241.23523 -591.06938,-241.09419 C -590.81221,-240.95314 -591.11699,-240.25114 -591.90772,-239.88474 C -592.67827,-239.52769 -593.36149,-237.64481 -594.74329,-237.47336 C -596.11739,-237.30286 -595.89714,-238.63489 -595.53650,-239.03881 C -595.18712,-239.43012 -594.27429,-240.23331 -593.84394,-240.47127 C -593.41931,-240.70606 -592.82833,-241.07069 -592.10692,-241.16843 z "
+ style="fill:url(#linearGradient13745);fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:1.0000000px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path1754"
+ d="M -595.92745,-235.45451 C -594.37002,-236.99404 -593.56775,-237.21078 -592.01032,-238.75031 C -590.98849,-238.75644 -590.40138,-237.65432 -590.83394,-236.30360 C -592.51368,-234.50591 -593.09300,-233.31300 -594.77274,-231.51531 C -594.17986,-233.13605 -595.03454,-235.13095 -595.92745,-235.45451 z "
+ style="opacity:0.41897234;fill:url(#linearGradient13747);fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:1.0000000px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path1756"
+ d="M -595.92745,-235.45451 C -594.37002,-236.99404 -594.90821,-235.82047 -593.35079,-237.35999 C -592.32895,-237.36613 -591.74185,-236.26401 -592.17441,-234.91328 C -593.85415,-233.11560 -593.09300,-233.31300 -594.77274,-231.51531 C -594.17986,-233.13605 -595.03454,-235.13095 -595.92745,-235.45451 z "
+ style="opacity:0.41897234;fill:url(#linearGradient13749);fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:1.0000000px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path1758"
+ d="M -595.92745,-235.45451 C -594.37002,-236.99404 -595.54420,-235.17339 -593.98678,-236.71291 C -592.96494,-236.71905 -592.37784,-235.61693 -592.81040,-234.26620 C -594.49013,-232.46852 -593.09300,-233.31300 -594.77274,-231.51531 C -594.17986,-233.13605 -595.03454,-235.13095 -595.92745,-235.45451 z "
+ style="opacity:0.41897234;fill:url(#linearGradient13751);fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:1.0000000px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000" />
+ <path
+ sodipodi:nodetypes="ccccccs"
+ id="path6419"
+ d="M -598.04283,-237.04726 C -599.64965,-235.44966 -598.06711,-237.06765 -599.21142,-235.88808 C -599.90549,-235.07201 -599.58991,-234.87256 -599.32823,-234.27747 C -598.37632,-232.69822 -597.34248,-231.77031 -596.09022,-231.23464 C -595.64978,-231.11115 -595.36127,-230.95227 -594.88202,-231.34218 C -594.29993,-231.75702 -593.40557,-232.48954 -593.34014,-232.94032 C -593.48708,-235.38350 -597.20306,-237.88220 -598.04283,-237.04726 z "
+ style="fill:url(#linearGradient13753);fill-opacity:1.0000000;stroke:url(#linearGradient13755);stroke-width:0.28321710;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000" />
+ <path
+ id="path5651"
+ d="M -594.83596,-231.32818 C -595.31283,-230.78909 -596.74079,-231.30312 -598.02337,-232.47555 C -599.30595,-233.64799 -599.95985,-235.03705 -599.48298,-235.57614 C -599.00611,-236.11522 -597.57815,-235.60120 -596.29557,-234.42876 C -595.02037,-233.26307 -594.36566,-231.88358 -594.82825,-231.33709"
+ style="fill:url(#linearGradient13757);fill-opacity:1.0000000;stroke:none;stroke-width:1.0000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path6517"
+ d="M -594.66112,-235.43807 L -595.92818,-234.21440 C -594.94605,-233.30894 -594.45796,-232.19443 -594.62336,-231.63361 C -594.12081,-232.00805 -593.47462,-232.56507 -593.42247,-232.92577 C -593.47512,-233.79970 -593.95290,-234.74821 -594.66112,-235.43807 z "
+ style="opacity:0.73015875;fill:url(#linearGradient13759);fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:0.98446530;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path7315"
+ d="M -595.46050,-236.18333 L -596.78454,-234.92355 C -597.77066,-235.58294 -598.53599,-235.94106 -599.09873,-235.79328 C -598.72302,-236.24221 -597.91973,-237.05870 -597.55778,-237.10530 C -596.68084,-237.05831 -596.19549,-236.74487 -595.46050,-236.18333 z "
+ style="opacity:0.73015875;fill:url(#linearGradient13761);fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:0.98446530;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000" />
+ </g>
+ <path
+ id="path1764"
+ d="M -339.32166,-551.95970 C -382.78973,-508.61018 -426.81257,-464.54870 -470.28066,-421.19906 C -470.43182,-421.04413 -473.78890,-417.69517 -476.55621,-410.43436 C -479.32350,-403.17344 -479.02460,-390.86160 -490.01618,-382.02809 C -497.33019,-374.47909 -495.26066,-368.35934 -491.76389,-363.58610 C -491.36478,-363.04133 -490.65745,-362.46620 -489.99979,-361.88702 C -489.43559,-361.23028 -488.87612,-360.52324 -488.34384,-360.12322 C -483.62117,-356.57401 -477.54940,-354.45043 -469.99067,-361.75167 C -461.12879,-372.74156 -448.88647,-372.35503 -441.64599,-375.08672 C -434.40563,-377.81843 -431.05157,-381.17043 -430.89644,-381.32134 C -387.48067,-424.72396 -343.35307,-468.67938 -299.93744,-512.08199 C -307.05399,-513.84754 -315.89647,-520.64189 -323.38771,-528.24674 C -330.90736,-535.83660 -337.61384,-544.78511 -339.32166,-551.95970 z "
+ style="fill:url(#linearGradient13763);fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:0.12500000;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000" />
+ <path
+ sodipodi:nodetypes="csccscc"
+ id="path1766"
+ d="M -495.37743,-406.53835 C -481.21007,-420.86199 -464.97412,-419.04773 -452.14935,-409.73688 C -441.34327,-401.89166 -430.14316,-385.12729 -443.54787,-372.03886 C -395.77769,-419.56762 -347.79937,-467.20985 -300.02932,-514.73862 C -286.38154,-526.57788 -300.98631,-543.98334 -311.74429,-552.47020 C -324.11576,-562.23008 -342.60016,-558.10199 -355.83435,-545.79655 C -403.15898,-498.53499 -448.05305,-453.79991 -495.37743,-406.53835 z "
+ style="fill:url(#linearGradient13765);fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:1.0000000px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000" />
+ <path
+ sodipodi:nodetypes="cscsssc"
+ id="path1768"
+ d="M -493.10005,-374.87492 C -493.57266,-372.95073 -493.09468,-366.78198 -491.01745,-366.84264 C -489.43933,-366.88872 -479.82570,-377.34365 -477.84450,-379.61428 C -469.44438,-392.18875 -469.36414,-391.96639 -468.53678,-393.70297 C -464.68311,-401.79166 -468.20899,-419.41442 -469.92379,-418.19158 C -476.03754,-413.83136 -477.10397,-398.38072 -480.10969,-392.79552 C -485.20251,-383.33248 -491.06725,-380.00026 -493.10005,-374.87492 z "
+ style="fill:url(#radialGradient13767);fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:0.12500000;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000" />
+ <path
+ sodipodi:nodetypes="cccccccccc"
+ id="path7323"
+ d="M -475.55038,-416.99830 C -477.17707,-414.90674 -476.79082,-415.97951 -477.47661,-412.69167 C -481.95615,-403.22812 -479.93980,-393.13162 -490.93140,-384.29811 C -498.24541,-376.74909 -496.16644,-370.64003 -492.66976,-365.86679 C -489.69675,-361.80861 -480.25137,-355.90923 -475.00373,-360.94411 C -465.14299,-370.02706 -456.51435,-370.70143 -448.09371,-373.67453 C -444.36401,-374.55474 -440.66645,-376.12426 -437.27104,-378.75434 C -436.90023,-379.12276 -436.48786,-379.53630 -436.11640,-379.90549 C -437.60471,-399.57405 -447.70609,-413.03581 -471.63246,-419.51857 L -475.55038,-416.99830 z "
+ style="opacity:0.82010579;fill:url(#radialGradient13769);fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:0.12500000;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000" />
+ <path
+ sodipodi:nodetypes="cscsssc"
+ id="path7348"
+ d="M -474.83322,-388.39078 C -476.01087,-386.84563 -480.96758,-383.59885 -482.15275,-385.41357 C -483.05322,-386.79221 -480.83030,-401.22078 -480.28436,-404.26295 C -475.73657,-418.90872 -475.95245,-418.84558 -475.12727,-420.58325 C -471.28320,-428.67721 -455.84248,-436.10260 -455.75271,-433.90950 C -455.43244,-426.09005 -466.50583,-416.01969 -468.95565,-410.13553 C -473.10646,-400.16598 -472.15504,-393.16913 -474.83322,-388.39078 z "
+ style="fill:url(#radialGradient13771);fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:0.12500000;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000" />
+ <g
+ transform="matrix(0.640718,0.741394,-0.737351,0.644231,-294.5805,92.05109)"
+ id="g11960">
+ <path
+ id="path8110"
+ d="M -471.76248,-159.41569 C -471.64802,-157.09303 -475.56651,-155.04421 -480.50909,-154.84260 C -485.45184,-154.64099 -489.55616,-156.36237 -489.67069,-158.68512 C -489.78530,-161.00777 -485.86674,-163.05651 -480.92408,-163.25821 C -476.00985,-163.45872 -471.92297,-161.76114 -471.76473,-159.45371"
+ style="fill:url(#linearGradient13773);fill-opacity:1.0000000;stroke:none;stroke-width:1.0000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000" />
+ <path
+ id="path8872"
+ d="M -471.76248,-159.41569 C -471.64802,-157.09303 -475.56651,-155.04421 -480.50909,-154.84260 C -485.45184,-154.64099 -489.55616,-156.36237 -489.67069,-158.68512 C -489.78530,-161.00777 -485.86674,-163.05651 -480.92408,-163.25821 C -476.00985,-163.45872 -471.92297,-161.76114 -471.76473,-159.45371"
+ style="opacity:0.82539684;fill:url(#linearGradient13775);fill-opacity:1.0000000;stroke:none;stroke-width:1.0000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000" />
+ </g>
+ <path
+ sodipodi:nodetypes="ccccccc"
+ id="rect8885"
+ d="M -314.54660,-554.44188 L -450.62838,-418.21806 C -451.87637,-416.97490 -454.02554,-416.25114 -455.44711,-416.59531 L -471.72399,-420.53638 C -473.14554,-420.88055 -473.28516,-422.15854 -472.03718,-423.40168 L -337.95342,-556.96545 C -333.51612,-561.13237 -324.94522,-561.52186 -314.54660,-554.44188 z "
+ style="fill:url(#linearGradient13777);fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:1.0000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000" />
+ <path
+ sodipodi:nodetypes="ccccccccccccccccczc"
+ id="path1776"
+ d="M -329.21748,-562.35117 C -330.45222,-561.11966 -340.77595,-550.82916 -342.01159,-549.59663 C -342.14833,-549.47457 -342.30382,-549.39708 -342.43874,-549.27187 C -385.90684,-505.92222 -427.38447,-464.78249 -470.85256,-421.43284 C -470.04383,-422.23842 -469.17510,-422.77969 -468.34027,-423.45742 C -468.64503,-423.15343 -468.95453,-422.84526 -469.25928,-422.54127 C -469.41035,-422.38623 -472.76550,-419.00078 -475.53281,-411.73997 C -478.30010,-404.47915 -480.44060,-391.72189 -488.98829,-383.37089 C -496.30242,-375.82187 -494.22344,-369.71279 -490.72665,-364.93958 C -487.75378,-360.88139 -478.30838,-354.98201 -473.06074,-360.01701 C -463.19987,-369.09987 -454.57054,-369.74971 -446.15001,-372.72280 C -442.92489,-373.48392 -439.76128,-374.92319 -436.75859,-376.95683 C -437.22252,-376.44748 -437.59897,-375.88088 -438.09508,-375.39712 C -437.44655,-376.04153 -436.78692,-376.67809 -436.13839,-377.32249 C -435.87291,-377.51305 -435.58993,-377.62424 -435.32806,-377.82712 C -418.96187,-394.08837 -401.64184,-411.45948 -384.43034,-428.69342 C -358.40110,-454.53113 -292.29459,-520.42324 -293.00855,-520.58372 C -289.12326,-530.07515 -297.52097,-542.53858 -302.91252,-547.54876 C -308.41419,-552.66131 -319.61856,-562.78363 -329.21748,-562.35117 z "
+ style="opacity:0.079051383;fill:#000000;fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:1.0000000px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000" />
+ </g>
+</svg>
diff --git a/chalk/plugins/tools/tool_selectsimilar/tool_similar_selection_minus_cursor.png b/chalk/plugins/tools/tool_selectsimilar/tool_similar_selection_minus_cursor.png
new file mode 100644
index 00000000..e6b2da50
--- /dev/null
+++ b/chalk/plugins/tools/tool_selectsimilar/tool_similar_selection_minus_cursor.png
Binary files differ
diff --git a/chalk/plugins/tools/tool_selectsimilar/tool_similar_selection_plus_cursor.png b/chalk/plugins/tools/tool_selectsimilar/tool_similar_selection_plus_cursor.png
new file mode 100644
index 00000000..d5a5e726
--- /dev/null
+++ b/chalk/plugins/tools/tool_selectsimilar/tool_similar_selection_plus_cursor.png
Binary files differ
diff --git a/chalk/plugins/tools/tool_star/Makefile.am b/chalk/plugins/tools/tool_star/Makefile.am
new file mode 100644
index 00000000..11cab8a3
--- /dev/null
+++ b/chalk/plugins/tools/tool_star/Makefile.am
@@ -0,0 +1,37 @@
+kde_services_DATA = chalktoolstar.desktop
+
+# all_includes must remain last!
+INCLUDES = -I$(srcdir)/../../../sdk \
+ -I$(srcdir)/../../../core \
+ -I$(srcdir)/../../../chalkcolor/ \
+ -I$(srcdir)/../../../ui \
+ -I$/../../../ui \
+ $(KOFFICE_INCLUDES) \
+ $(all_includes)
+
+chalktoolstar_la_SOURCES = \
+ wdg_tool_star.ui \
+ tool_star.cc \
+ kis_tool_star.cc
+
+# Install this plugin in the KDE modules directory
+kde_module_LTLIBRARIES = chalktoolstar.la
+
+noinst_HEADERS = \
+ tool_star.h \
+ kis_tool_star.h
+
+chalktoolstar_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) $(LIB_QT) -lkdecore -lkdeui -lkjs -lkdefx -lkio -lkparts -L../../../../chalk/chalkcolor/.libs -lchalkcolor -L../../../../chalk/core/.libs -lchalkimage \
+ -L../../../../chalk/ui/.libs -lchalkui
+chalktoolstar_la_LIBADD = ../../../libchalkcommon.la
+
+chalktoolstar_la_METASOURCES = AUTO
+
+KDE_OPTIONS = nofinal
+
+chalkpics_DATA = \
+ tool_star.png \
+ tool_star_cursor.png
+
+chalkpicsdir = $(kde_datadir)/chalk/pics
+
diff --git a/chalk/plugins/tools/tool_star/chalktoolstar.desktop b/chalk/plugins/tools/tool_star/chalktoolstar.desktop
new file mode 100644
index 00000000..546c0d97
--- /dev/null
+++ b/chalk/plugins/tools/tool_star/chalktoolstar.desktop
@@ -0,0 +1,52 @@
+[Desktop Entry]
+Name=Star Tool
+Name[bg]=Инструмент звезда
+Name[br]=Ostilh steredenn
+Name[ca]=Eina d'estrella
+Name[cy]=Erfyn Seren
+Name[da]=Stjerneværktøj
+Name[de]=Stern-Werkzeug
+Name[el]=Εργαλείο αστεριού
+Name[eo]=Stelo-ilo
+Name[es]=Herramienta Estrella
+Name[et]=Tähe tööriist
+Name[eu]=Izarra tresna
+Name[fa]=ابزار ستاره
+Name[fi]=Tähtityökalu
+Name[fr]=Outil étoile
+Name[fy]=Sjer-ark
+Name[ga]=Uirlis Réiltín
+Name[gl]=Ferramenta de Estrelas
+Name[he]=כלי כוכב
+Name[hu]=Csillag eszköz
+Name[is]=Stjörnutól
+Name[it]=Strumento stella
+Name[ja]=星型ツール
+Name[km]=ឧបករណ៍​រាង​ផ្កាយ
+Name[lt]=Žvaigždės įrankis
+Name[lv]=Zvaigznes rīks
+Name[ms]=Alat Bintang
+Name[nb]=Stjerneverktøy
+Name[nds]=Steern-Warktüüch
+Name[ne]=तारा उपकरण
+Name[nl]=Stergereedschap
+Name[nn]=Stjerneverktøy
+Name[pl]=Narzędzie do rysowania gwiazdki
+Name[pt]=Ferramenta de Estrelas
+Name[pt_BR]=Ferramenta Estrela
+Name[ru]=Звезда
+Name[se]=Nástereaidu
+Name[sk]=Hviezda
+Name[sl]=Zvezdno orodje
+Name[sr]=Алат за звезде
+Name[sr@Latn]=Alat za zvezde
+Name[sv]=Stjärnverktyg
+Name[uk]=Інструмент зірки
+Name[uz]=Yulduz vositasi
+Name[uz@cyrillic]=Юлдуз воситаси
+Name[zh_CN]=星形工具
+Name[zh_TW]=星形工具
+ServiceTypes=Chalk/Tool
+Type=Service
+X-KDE-Library=chalktoolstar
+X-Chalk-Version=2
diff --git a/chalk/plugins/tools/tool_star/kis_tool_star.cc b/chalk/plugins/tools/tool_star/kis_tool_star.cc
new file mode 100644
index 00000000..3a804f89
--- /dev/null
+++ b/chalk/plugins/tools/tool_star/kis_tool_star.cc
@@ -0,0 +1,245 @@
+/*
+ * kis_tool_star.cc -- part of Chalk
+ *
+ * Copyright (c) 2004 Michael Thaler <michael.thaler@physik.tu-muenchen.de>
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+
+#include <math.h>
+
+#include <tqpainter.h>
+#include <tqspinbox.h>
+#include <tqlayout.h>
+
+#include <kaction.h>
+#include <kdebug.h>
+#include <klocale.h>
+#include <kdebug.h>
+#include <knuminput.h>
+
+#include "kis_doc.h"
+#include "kis_view.h"
+#include "kis_painter.h"
+#include "kis_int_spinbox.h"
+#include "kis_canvas_subject.h"
+#include "kis_canvas_controller.h"
+#include "kis_button_press_event.h"
+#include "kis_button_release_event.h"
+#include "kis_move_event.h"
+#include "kis_paintop_registry.h"
+#include "kis_canvas.h"
+#include "kis_canvas_painter.h"
+#include "kis_cursor.h"
+#include "kis_int_spinbox.h"
+
+#include "kis_tool_star.h"
+#include "wdg_tool_star.h"
+
+KisToolStar::KisToolStar()
+ : super(i18n("Star")),
+ m_dragging (false),
+ m_currentImage (0)
+{
+ setName("tool_star");
+ setCursor(KisCursor::load("tool_star_cursor.png", 6, 6));
+ m_innerOuterRatio=40;
+ m_vertices=5;
+}
+
+KisToolStar::~KisToolStar()
+{
+}
+
+void KisToolStar::update (KisCanvasSubject *subject)
+{
+ super::update (subject);
+ if (m_subject)
+ m_currentImage = m_subject->currentImg ();
+}
+
+void KisToolStar::buttonPress(KisButtonPressEvent *event)
+{
+ if (m_currentImage && event->button() == Qt::LeftButton) {
+ m_dragging = true;
+ m_dragStart = event->pos();
+ m_dragEnd = event->pos();
+ m_vertices = m_optWidget->verticesSpinBox->value();
+ m_innerOuterRatio = m_optWidget->ratioSpinBox->value();
+ }
+}
+
+void KisToolStar::move(KisMoveEvent *event)
+{
+ if (m_dragging) {
+ // erase old lines on canvas
+ draw(m_dragStart, m_dragEnd);
+ // move (alt) or resize star
+ if (event->state() & TQt::AltButton) {
+ KisPoint trans = event->pos() - m_dragEnd;
+ m_dragStart += trans;
+ m_dragEnd += trans;
+ } else {
+ m_dragEnd = event->pos();
+ }
+ // draw new lines on canvas
+ draw(m_dragStart, m_dragEnd);
+ }
+}
+
+void KisToolStar::buttonRelease(KisButtonReleaseEvent *event)
+{
+ if (!m_subject || !m_currentImage)
+ return;
+
+ if (m_dragging && event->button() == Qt::LeftButton) {
+ // erase old lines on canvas
+ draw(m_dragStart, m_dragEnd);
+ m_dragging = false;
+
+ if (m_dragStart == m_dragEnd)
+ return;
+
+ if (!m_currentImage)
+ return;
+
+ if (!m_currentImage->activeDevice())
+ return;
+
+ KisPaintDeviceSP device = m_currentImage->activeDevice ();;
+ KisPainter painter (device);
+ if (m_currentImage->undo()) painter.beginTransaction (i18n("Star"));
+
+ painter.setPaintColor(m_subject->fgColor());
+ painter.setBackgroundColor(m_subject->bgColor());
+ painter.setFillStyle(fillStyle());
+ painter.setBrush(m_subject->currentBrush());
+ painter.setPattern(m_subject->currentPattern());
+ painter.setOpacity(m_opacity);
+ painter.setCompositeOp(m_compositeOp);
+ KisPaintOp * op = KisPaintOpRegistry::instance()->paintOp(m_subject->currentPaintop(), m_subject->currentPaintopSettings(), &painter);
+ painter.setPaintOp(op); // Painter takes ownership
+
+ vKisPoint coord = starCoordinates(m_vertices, m_dragStart.x(), m_dragStart.y(), m_dragEnd.x(), m_dragEnd.y());
+
+ painter.paintPolygon(coord);
+
+ device->setDirty( painter.dirtyRect() );
+ notifyModified();
+
+ if (m_currentImage->undo()) {
+ m_currentImage->undoAdapter()->addCommand(painter.endTransaction());
+ }
+ }
+}
+
+void KisToolStar::draw(const KisPoint& start, const KisPoint& end )
+{
+ if (!m_subject || !m_currentImage)
+ return;
+
+ KisCanvasController *controller = m_subject->canvasController();
+ KisCanvas *canvas = controller->kiscanvas();
+ KisCanvasPainter p (canvas);
+ TQPen pen(TQt::SolidLine);
+
+ KisPoint startPos;
+ KisPoint endPos;
+ startPos = controller->windowToView(start);
+ endPos = controller->windowToView(end);
+
+ p.setRasterOp(TQt::NotROP);
+
+ vKisPoint points = starCoordinates(m_vertices, startPos.x(), startPos.y(), endPos.x(), endPos.y());
+
+ for (uint i = 0; i < points.count() - 1; i++) {
+ p.drawLine(points[i].floorTQPoint(), points[i + 1].floorTQPoint());
+ }
+ p.drawLine(points[points.count() - 1].floorTQPoint(), points[0].floorTQPoint());
+
+ p.end ();
+}
+
+void KisToolStar::setup(KActionCollection *collection)
+{
+ m_action = static_cast<KRadioAction *>(collection->action(name()));
+
+ if (m_action == 0) {
+ KShortcut shortcut(TQt::Key_Plus);
+ shortcut.append(KShortcut(TQt::Key_F9));
+ m_action = new KRadioAction(i18n("&Star"),
+ "tool_star",
+ shortcut,
+ this,
+ TQT_SLOT(activate()),
+ collection,
+ name());
+ Q_CHECK_PTR(m_action);
+
+ m_action->setToolTip(i18n("Draw a star"));
+ m_action->setExclusiveGroup("tools");
+ m_ownAction = true;
+ }
+}
+
+vKisPoint KisToolStar::starCoordinates(int N, double mx, double my, double x, double y)
+{
+ double R=0, r=0;
+ TQ_INT32 n=0;
+ double angle;
+
+ vKisPoint starCoordinatesArray(2*N);
+
+ // the radius of the outer edges
+ R=sqrt((x-mx)*(x-mx)+(y-my)*(y-my));
+
+ // the radius of the inner edges
+ r=R*m_innerOuterRatio/100.0;
+
+ // the angle
+ angle=-atan2((x-mx),(y-my));
+
+ //set outer edges
+ for(n=0;n<N;n++){
+ starCoordinatesArray[2*n] = KisPoint(mx+R*cos(n * 2.0 * M_PI / N + angle),my+R*sin(n *2.0 * M_PI / N+angle));
+ }
+
+ //set inner edges
+ for(n=0;n<N;n++){
+ starCoordinatesArray[2*n+1] = KisPoint(mx+r*cos((n + 0.5) * 2.0 * M_PI / N + angle),my+r*sin((n +0.5) * 2.0 * M_PI / N + angle));
+ }
+
+ return starCoordinatesArray;
+}
+
+TQWidget* KisToolStar::createOptionWidget(TQWidget* tqparent)
+{
+ TQWidget *widget = super::createOptionWidget(tqparent);
+
+ m_optWidget = new WdgToolStar(widget);
+ Q_CHECK_PTR(m_optWidget);
+
+ m_optWidget->ratioSpinBox->setValue(m_innerOuterRatio);
+
+ TQGridLayout *optionLayout = new TQGridLayout(widget, 1, 1);
+ super::addOptionWidgetLayout(optionLayout);
+
+ optionLayout->addWidget(m_optWidget, 0, 0);
+
+ return widget;
+}
+
+#include "kis_tool_star.moc"
diff --git a/chalk/plugins/tools/tool_star/kis_tool_star.h b/chalk/plugins/tools/tool_star/kis_tool_star.h
new file mode 100644
index 00000000..3bd8df2b
--- /dev/null
+++ b/chalk/plugins/tools/tool_star/kis_tool_star.h
@@ -0,0 +1,101 @@
+/*
+ * kis_tool_star.h - part of Chalk
+ *
+ * Copyright (c) 2004 Michael Thaler <michael Thaler@physik.tu-muenchen.de>
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef KIS_TOOL_STAR_H_
+#define KIS_TOOL_STAR_H_
+
+#include "kis_tool_shape.h"
+
+class KisCanvas;
+class KisDoc;
+class KisPainter;
+class KisView;
+class KisRect;
+class WdgToolStar;
+
+class KisToolStar : public KisToolShape {
+
+ typedef KisToolShape super;
+ Q_OBJECT
+ TQ_OBJECT
+
+public:
+ KisToolStar();
+ virtual ~KisToolStar();
+
+ //
+ // KisCanvasObserver interface
+ //
+
+ virtual void update (KisCanvasSubject *subject);
+
+ virtual TQWidget* createOptionWidget(TQWidget* tqparent);
+
+ //
+ // KisToolPaint interface
+ //
+
+ virtual void setup(KActionCollection *collection);
+ virtual enumToolType toolType() { return TOOL_SHAPE; }
+ virtual TQ_UINT32 priority() { return 6; }
+ virtual void buttonPress(KisButtonPressEvent *event);
+ virtual void move(KisMoveEvent *event);
+ virtual void buttonRelease(KisButtonReleaseEvent *event);
+
+protected:
+ virtual void draw(const KisPoint& start, const KisPoint& stop);
+ //virtual void draw(KisPainter *gc, const TQRect& rc);
+
+protected:
+ int m_lineThickness;
+
+ KisPoint m_dragStart;
+ KisPoint m_dragEnd;
+ TQRect m_final_lines;
+
+ bool m_dragging;
+ KisImageSP m_currentImage;
+private:
+ vKisPoint starCoordinates(int N, double mx, double my, double x, double y);
+ TQ_INT32 m_innerOuterRatio;
+ TQ_INT32 m_vertices;
+ WdgToolStar* m_optWidget;
+};
+
+
+#include "kis_tool_factory.h"
+
+class KisToolStarFactory : public KisToolFactory {
+ typedef KisToolFactory super;
+public:
+ KisToolStarFactory() : super() {};
+ virtual ~KisToolStarFactory(){};
+
+ virtual KisTool * createTool(KActionCollection * ac) {
+ KisTool * t = new KisToolStar();
+ Q_CHECK_PTR(t);
+ t->setup(ac);
+ return t;
+ }
+ virtual KisID id() { return KisID("startqshape", i18n("Star Tool")); }
+};
+
+
+#endif //__KIS_TOOL_STAR_H__
diff --git a/chalk/plugins/tools/tool_star/tool_star.cc b/chalk/plugins/tools/tool_star/tool_star.cc
new file mode 100644
index 00000000..e399fafa
--- /dev/null
+++ b/chalk/plugins/tools/tool_star/tool_star.cc
@@ -0,0 +1,62 @@
+/*
+ * tool_star.cc -- Part of Chalk
+ *
+ * Copyright (c) 2004 Michael Thaler <michael.thaler@physik.tu-muenchen.de>
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+#include <stdlib.h>
+#include <vector>
+
+#include <tqpoint.h>
+
+#include <klocale.h>
+#include <kiconloader.h>
+#include <kinstance.h>
+#include <kmessagebox.h>
+#include <kstandarddirs.h>
+#include <kdebug.h>
+#include <kgenericfactory.h>
+
+#include <kis_global.h>
+#include <kis_types.h>
+#include <kis_tool_registry.h>
+
+#include "tool_star.h"
+#include "kis_tool_star.h"
+
+
+typedef KGenericFactory<ToolStar> ToolStarFactory;
+K_EXPORT_COMPONENT_FACTORY( chalktoolstar, ToolStarFactory( "chalk" ) )
+
+
+ToolStar::ToolStar(TQObject *tqparent, const char *name, const TQStringList &)
+ : KParts::Plugin(tqparent, name)
+{
+ setInstance(ToolStarFactory::instance());
+
+ if ( tqparent->inherits("KisToolRegistry") )
+ {
+ KisToolRegistry * r = dynamic_cast<KisToolRegistry*>( tqparent );
+ r->add(new KisToolStarFactory());
+ }
+
+}
+
+ToolStar::~ToolStar()
+{
+}
+
+#include "tool_star.moc"
diff --git a/chalk/plugins/tools/tool_star/tool_star.h b/chalk/plugins/tools/tool_star/tool_star.h
new file mode 100644
index 00000000..36172dd6
--- /dev/null
+++ b/chalk/plugins/tools/tool_star/tool_star.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2004 Michael Thaler <michael.thaler@physik.tu-muenchen.de>
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef TOOL_STAR_H_
+#define TOOL_STAR_H_
+
+#include <kparts/plugin.h>
+
+class KisView;
+
+/**
+ * A module that provides a star tool.
+ */
+class ToolStar : public KParts::Plugin
+{
+ Q_OBJECT
+ TQ_OBJECT
+public:
+ ToolStar(TQObject *tqparent, const char *name, const TQStringList &);
+ virtual ~ToolStar();
+
+private:
+
+ KisView * m_view;
+
+};
+
+#endif // TOOL_STAR_H_
diff --git a/chalk/plugins/tools/tool_star/tool_star.png b/chalk/plugins/tools/tool_star/tool_star.png
new file mode 100644
index 00000000..c7627866
--- /dev/null
+++ b/chalk/plugins/tools/tool_star/tool_star.png
Binary files differ
diff --git a/chalk/plugins/tools/tool_star/tool_star_cursor.png b/chalk/plugins/tools/tool_star/tool_star_cursor.png
new file mode 100644
index 00000000..d3cef598
--- /dev/null
+++ b/chalk/plugins/tools/tool_star/tool_star_cursor.png
Binary files differ
diff --git a/chalk/plugins/tools/tool_star/wdg_tool_star.ui b/chalk/plugins/tools/tool_star/wdg_tool_star.ui
new file mode 100644
index 00000000..b342a927
--- /dev/null
+++ b/chalk/plugins/tools/tool_star/wdg_tool_star.ui
@@ -0,0 +1,128 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>WdgToolStar</class>
+<widget class="TQWidget">
+ <property name="name">
+ <cstring>WdgToolStar</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>280</width>
+ <height>50</height>
+ </rect>
+ </property>
+ <property name="caption">
+ <string>Star</string>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <widget class="TQLayoutWidget">
+ <property name="name">
+ <cstring>tqlayout8</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="TQLabel">
+ <property name="name">
+ <cstring>textLabel1</cstring>
+ </property>
+ <property name="text">
+ <string>Vertices:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>isbX</cstring>
+ </property>
+ </widget>
+ <widget class="KIntSpinBox">
+ <property name="name">
+ <cstring>verticesSpinBox</cstring>
+ </property>
+ <property name="maxValue">
+ <number>100</number>
+ </property>
+ <property name="minValue">
+ <number>2</number>
+ </property>
+ <property name="value">
+ <number>5</number>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget class="TQLayoutWidget">
+ <property name="name">
+ <cstring>tqlayout7</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="TQLabel">
+ <property name="name">
+ <cstring>textLabel2</cstring>
+ </property>
+ <property name="text">
+ <string>Ratio:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>isbWidth</cstring>
+ </property>
+ </widget>
+ <widget class="KisIntSpinbox">
+ <property name="name">
+ <cstring>ratioSpinBox</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>0</hsizetype>
+ <vsizetype>5</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ </hbox>
+</widget>
+<tabstops>
+ <tabstop>verticesSpinBox</tabstop>
+ <tabstop>ratioSpinBox</tabstop>
+</tabstops>
+<customwidgets>
+<customwidget>
+ <class>KisIntSpinbox</class>
+ <header location="global">kis_int_spinbox.h</header>
+ <sizehint>
+ <width>-1</width>
+ <height>-1</height>
+ </sizehint>
+ <container>0</container>
+ <sizepolicy>
+ <hordata>5</hordata>
+ <verdata>5</verdata>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ <pixmap>image4</pixmap>
+</customwidget>
+</customwidgets>
+<images>
+ <image name="image4">
+ <data format="PNG" length="1002">89504e470d0a1a0a0000000d4948445200000016000000160806000000c4b46c3b000003b149444154388dad945f4c5b551cc73fe7dc4b7b4bcba0762d45c43114323599ee6192609c51d883892ce083f1718b3ebb185f8dc91e972cf39d2d2a2f1af664b6f1e0fe3863a0718969700eb0c52142da0242a1bd6d696f7bcff101585203ceb8fd9ece39f99dcff9fe7edf939f88c562ec465f5f9fe609442c161362173c3e3eae7b7a7ac8e7f36432196cdbfe4f907c3e4f2291201e8fe338cec3737357e9e8e828aded1e229d650e1f2d51754b082110124c13a4dc5ea341eb9dc284c0558a853f3ce8cb0677ef500fde7d39d2596679e326597b8e9abb85d7a770ab16ab6983ec5a05b487a70e36f0f4e10afe408d6a558310980108478dba4a1e8233990c5d474b64ed39aa3a8fe5f3317fbf81dbd70bccfeb205947632fd74f6589c1c6ea2f70d03a58ba0c1f2c9bdc1b66de3b8256a6e11cbe7e3ee1d181b590124fe2693aeee08d223c82c3a2c24b7b874bec8f26288774f7bd054504aef0dde6e99c0eb83f9fb266323cb80a27fb0958141836044605a2ee5523393371cc646fee2da37195aa35d0c0c5b4859ac03d7e91712dcaac5adab3650a3ff9d08ef7dd8404bb48869e5d958b5b87dadc4c9a1464e9f0d0326df7ebd86bd2e310cb1bf62d384d59441f2d70a070e1c60e09489929b988681bdd9cc97170bcc4c65595f71f8e0e3301337fc24a7732467831875a47f289652b0be5e4151e6d07316c1b0c0340d8ab92023e76d66a6b2840e36d2fb7a13fee632475e6edc367ea98a90fb98b7dd6310ca0328a44761582e1bab41befabcc0ec940d28bc5e93b68e064cab84e1d9beaeb48934eac1f53b01c1b000fca496aa54b61a99fcde61662a4b4b4b23d1680be9d426173e4df3602a48ea411989a4fd590f52a8fd156b05ed9d350e3defe3cfdf4b4c7ce770ea7d3fb9f520afbe1620daeee5c26735d20b9b9cfb6811a754a439e4e5c5639a4caa1e5caf586bfc0197b78702005cb9b4cae4cd3267ce8638fe964bd72b393e39d74928d242617303a756a37f284447770dcdbffc6384a05a85de1306e9a52057c7527c7131c3c42d3f475eb2303c82d4fc3276d6811db37efeb148723082d9b08f79f97c1e5729109a9a28307cc622d2d6cdf52b2b24efe548dedb00142009862cfa879ee1a71f6cec928353511472fbf4389148b0b0e0c108081412458dfe21c9f11351e67e7358595468246d1d1e5e38a6e9e851bc39d84ab502a669331dafec0d8ec7e3e8cb06e1a881d727d1ae40180a434a8c9db129a54126ad48a7358c2b4c5352c8c374bcccdab2bb37d8719cba79fab8211f9df218e0582c261e95f8bfc04f1a1e8bc5c4dfe0a190172af6a9690000000049454e44ae426082</data>
+ </image>
+</images>
+<tqlayoutdefaults spacing="6" margin="11"/>
+<includehints>
+ <includehint>knuminput.h</includehint>
+ <includehint>knuminput.h</includehint>
+</includehints>
+</UI>
diff --git a/chalk/plugins/tools/tool_transform/Makefile.am b/chalk/plugins/tools/tool_transform/Makefile.am
new file mode 100644
index 00000000..7b088383
--- /dev/null
+++ b/chalk/plugins/tools/tool_transform/Makefile.am
@@ -0,0 +1,37 @@
+kde_services_DATA = chalktooltransform.desktop
+
+# all_includes must remain last!
+INCLUDES = -I$(srcdir)/../../../sdk \
+ -I$(srcdir)/../../../core \
+ -I$(srcdir)/../../../chalkcolor/ \
+ -I$(srcdir)/../../../ui \
+ -I$/../../../ui \
+ $(KOFFICE_INCLUDES) \
+ $(all_includes)
+
+chalktooltransform_la_SOURCES = \
+ wdg_tool_transform.ui \
+ tool_transform.cc \
+ kis_tool_transform.cc
+
+# Install this plugin in the KDE modules directory
+kde_module_LTLIBRARIES = chalktooltransform.la
+
+noinst_HEADERS = \
+ tool_transform.h \
+ kis_tool_transform.h
+
+chalktooltransform_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) $(LIB_QT) -lkdecore -lkdeui -lkjs -lkdefx -lkio -lkparts -L../../../../chalk/chalkcolor/.libs -lchalkcolor -L../../../../chalk/core/.libs -lchalkimage \
+ -L../../../../chalk/ui/.libs -lchalkui
+chalktooltransform_la_LIBADD = ../../../libchalkcommon.la
+
+chalktooltransform_la_METASOURCES = AUTO
+
+KDE_OPTIONS = nofinal
+
+chalkpics_DATA = \
+ rotate_cursor.xpm \
+ tool_transform.png
+
+chalkpicsdir = $(kde_datadir)/chalk/pics
+
diff --git a/chalk/plugins/tools/tool_transform/chalktooltransform.desktop b/chalk/plugins/tools/tool_transform/chalktooltransform.desktop
new file mode 100644
index 00000000..4ea3db98
--- /dev/null
+++ b/chalk/plugins/tools/tool_transform/chalktooltransform.desktop
@@ -0,0 +1,46 @@
+[Desktop Entry]
+Name=Transform Tool
+Name[bg]=Инструмент за трансформиране
+Name[br]=Ostilh treuzfurmiñ
+Name[ca]=Eina de transformació
+Name[cy]=Erfyn Trawsffurfio
+Name[da]=Transformeringsværktøj
+Name[de]=Transformation-Werkzeug
+Name[el]=Εργαλείο μετασχηματισμού
+Name[eo]=Transform-ilo
+Name[es]=Herramienta para transformar
+Name[et]=Transformeermistööriist
+Name[fa]=ابزار تبدیل
+Name[fr]=Outil transformation
+Name[fy]=ferfoarmingsark
+Name[ga]=Uirlis Trasfhoirmithe
+Name[gl]=Ferramenta de Transformación
+Name[hu]=Átalakító eszköz
+Name[is]=Ummyndunartól
+Name[it]=Strumento di trasformazione
+Name[ja]=変換ツール
+Name[km]=ឧបករណ៍​ប្លែង
+Name[lt]=Transformavimo įrankis
+Name[lv]=Transformāciju rīks
+Name[nb]=Transformeringsverktøy
+Name[nds]=Ümwanneln-Warktüüch
+Name[ne]=रूपान्तरण उपकरण
+Name[nl]=Vervormgereedschap
+Name[pl]=Narzędzie przekształcania
+Name[pt]=Ferramenta de Transformação
+Name[pt_BR]=Ferramenta de Transformação
+Name[ru]=Преобразование
+Name[sk]=Transformácia
+Name[sl]=Orodje za pretvorbo
+Name[sr]=Алат за трансформацију
+Name[sr@Latn]=Alat za transformaciju
+Name[sv]=Transformeringsverktyg
+Name[uk]=Засіб перетворення
+Name[uz]=Aylantirish asbobi
+Name[uz@cyrillic]=Айлантириш асбоби
+Name[zh_CN]=变形工具
+Name[zh_TW]=變形工具
+ServiceTypes=Chalk/Tool
+Type=Service
+X-KDE-Library=chalktooltransform
+X-Chalk-Version=2
diff --git a/chalk/plugins/tools/tool_transform/kis_tool_transform.cc b/chalk/plugins/tools/tool_transform/kis_tool_transform.cc
new file mode 100644
index 00000000..5b828122
--- /dev/null
+++ b/chalk/plugins/tools/tool_transform/kis_tool_transform.cc
@@ -0,0 +1,916 @@
+/*
+ * kis_tool_transform.cc -- part of Chalk
+ *
+ * Copyright (c) 2004 Boudewijn Rempt <boud@valdyas.org>
+ * Copyright (c) 2005 Casper Boemann <cbr@boemann.dk>
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+
+#include <tqpainter.h>
+#include <tqpen.h>
+#include <tqpushbutton.h>
+#include <tqobject.h>
+#include <tqlabel.h>
+#include <tqcombobox.h>
+#include <tqapplication.h>
+
+#include <kdebug.h>
+#include <kaction.h>
+#include <kcommand.h>
+#include <klocale.h>
+#include <knuminput.h>
+
+#include <kis_global.h>
+#include <kis_painter.h>
+#include <kis_canvas_controller.h>
+#include <kis_canvas_subject.h>
+#include <kis_cursor.h>
+#include <kis_image.h>
+#include <kis_undo_adapter.h>
+#include <kis_selected_transaction.h>
+#include <kis_button_press_event.h>
+#include <kis_button_release_event.h>
+#include <kis_move_event.h>
+#include <kis_selection.h>
+#include <kis_filter_strategy.h>
+#include <kis_cmb_idlist.h>
+#include <kis_id.h>
+#include <kis_tool_controller.h>
+#include <kis_transform_worker.h>
+
+#include "kis_tool_transform.h"
+#include "wdg_tool_transform.h"
+#include "kis_canvas.h"
+#include "kis_canvas_painter.h"
+
+namespace {
+ class TransformCmd : public KisSelectedTransaction {
+ typedef KisSelectedTransaction super;
+
+ public:
+ TransformCmd(KisToolTransform *tool, KisPaintDeviceSP device, KisPaintDeviceSP origDevice, double scaleX, double scaleY, double tX, double tY, double a, KisSelectionSP origSel, TQPoint startPos, TQPoint endPos);
+ virtual ~TransformCmd();
+
+ public:
+ virtual void execute();
+ virtual void unexecute();
+ void transformArgs(double &sx, double &sy, double &tx, double &ty, double &a);
+ KisSelectionSP origSelection(TQPoint &startPos, TQPoint &endPos);
+ KisPaintDeviceSP theDevice();
+ KisPaintDeviceSP origDevice();
+
+ private:
+ double m_scaleX;
+ double m_scaleY;
+ double m_translateX;
+ double m_translateY;
+ double m_a;
+ KisToolTransform *m_tool;
+ KisSelectionSP m_origSelection;
+ TQPoint m_startPos;
+ TQPoint m_endPos;
+ KisPaintDeviceSP m_device;
+ KisPaintDeviceSP m_origDevice;
+ };
+
+ TransformCmd::TransformCmd(KisToolTransform *tool, KisPaintDeviceSP device, KisPaintDeviceSP origDevice, double scaleX, double scaleY, double tX, double tY, double a, KisSelectionSP origSel, TQPoint startPos, TQPoint endPos) :
+ super(i18n("Transform"), device)
+ , m_scaleX(scaleX)
+ , m_scaleY(scaleY)
+ , m_translateX(tX)
+ , m_translateY(tY)
+ , m_a(a)
+ , m_tool(tool)
+ , m_origSelection(origSel)
+ , m_startPos(startPos)
+ , m_endPos(endPos)
+ , m_device(device)
+ , m_origDevice(origDevice)
+ {
+ }
+
+ TransformCmd::~TransformCmd()
+ {
+ }
+
+ void TransformCmd::transformArgs(double &sx, double &sy, double &tx, double &ty, double &a)
+ {
+ sx = m_scaleX;
+ sy = m_scaleY;
+ tx= m_translateX;
+ ty = m_translateY;
+ a = m_a;
+ }
+
+ KisSelectionSP TransformCmd::origSelection(TQPoint &startPos, TQPoint &endPos)
+ {
+ startPos = m_startPos;
+ endPos = m_endPos;
+ return m_origSelection;
+ }
+
+ void TransformCmd::execute()
+ {
+ super::execute();
+ }
+
+ void TransformCmd::unexecute()
+ {
+ super::unexecute();
+ }
+
+ KisPaintDeviceSP TransformCmd::theDevice()
+ {
+ return m_device;
+ }
+
+ KisPaintDeviceSP TransformCmd::origDevice()
+ {
+ return m_origDevice;
+ }
+}
+
+KisToolTransform::KisToolTransform()
+ : super(i18n("Transform"))
+ , m_wasPressed( false )
+{
+ setName("tool_transform");
+ setCursor(KisCursor::selectCursor());
+ m_subject = 0;
+ m_selecting = false;
+ m_startPos = TQPoint(0, 0);
+ m_endPos = TQPoint(0, 0);
+ m_optWidget = 0;
+ m_sizeCursors[0] = KisCursor::sizeVerCursor();
+ m_sizeCursors[1] = KisCursor::sizeBDiagCursor();
+ m_sizeCursors[2] = KisCursor::sizeHorCursor();
+ m_sizeCursors[3] = KisCursor::sizeFDiagCursor();
+ m_sizeCursors[4] = KisCursor::sizeVerCursor();
+ m_sizeCursors[5] = KisCursor::sizeBDiagCursor();
+ m_sizeCursors[6] = KisCursor::sizeHorCursor();
+ m_sizeCursors[7] = KisCursor::sizeFDiagCursor();
+ m_origDevice = 0;
+ m_origSelection = 0;
+
+}
+
+KisToolTransform::~KisToolTransform()
+{
+}
+
+void KisToolTransform::deactivate()
+{
+ if (m_subject && m_subject->undoAdapter()) m_subject->undoAdapter()->removeCommandHistoryListener( this );
+
+ KisImageSP img = m_subject->currentImg();
+ if (!img) return;
+
+ paintOutline();
+
+ disconnect(m_subject->currentImg().data(), TQT_SIGNAL(sigLayerActivated(KisLayerSP)), this, TQT_SLOT(slotLayerActivated(KisLayerSP)));
+}
+
+void KisToolTransform::activate()
+{
+ if(m_subject && m_subject->currentImg() && m_subject->currentImg()->activeDevice())
+ {
+ //connect(m_subject, commandExecuted(KCommand *c), this, notifyCommandAdded( KCommand * c));
+ m_subject->undoAdapter()->setCommandHistoryListener( this );
+
+ KisToolControllerInterface *controller = m_subject->toolController();
+
+ if (controller)
+ controller->setCurrentTool(this);
+
+ TransformCmd * cmd=0;
+
+ if(m_subject->currentImg()->undoAdapter()->presentCommand())
+ cmd = dynamic_cast<TransformCmd*>(m_subject->currentImg()->undoAdapter()->presentCommand());
+
+ if (cmd == 0) {
+ initHandles();
+ }
+ else
+ {
+ // One of our commands is on top
+ if(cmd->theDevice() == m_subject->currentImg()->activeDevice())
+ {
+ // and it even has the same device
+ // We should ask for tool args and orig selection
+ m_origDevice = cmd->origDevice();
+ cmd->transformArgs(m_scaleX, m_scaleY, m_translateX, m_translateY, m_a);
+ m_origSelection = cmd->origSelection(m_startPos, m_endPos);
+ m_org_cenX = (m_startPos.x() + m_endPos.x()) / 2.0;
+ m_org_cenY = (m_startPos.y() + m_endPos.y()) / 2.0;
+ paintOutline();
+ }
+ else
+ initHandles();
+ }
+ }
+ connect(m_subject->currentImg(), TQT_SIGNAL(sigLayerActivated(KisLayerSP)), this, TQT_SLOT(slotLayerActivated(KisLayerSP)));
+}
+
+void KisToolTransform::initHandles()
+{
+ TQ_INT32 x,y,w,h;
+ KisImageSP img = m_subject->currentImg();
+
+ KisPaintDeviceSP dev = img->activeDevice();
+ if (!dev ) return;
+
+ // Create a lazy copy of the current state
+ m_origDevice = new KisPaintDevice(*dev.data());
+ Q_ASSERT(m_origDevice);
+
+ if(dev->hasSelection())
+ {
+ KisSelectionSP sel = dev->selection();
+ m_origSelection = new KisSelection(*sel.data());
+ TQRect r = sel->selectedExactRect();
+ r.rect(&x, &y, &w, &h);
+ }
+ else {
+ dev->exactBounds(x,y,w,h);
+ m_origSelection = 0;
+ }
+ m_startPos = TQPoint(x, y);
+ m_endPos = TQPoint(x+w-1, y+h-1);
+ m_org_cenX = (m_startPos.x() + m_endPos.x()) / 2.0;
+ m_org_cenY = (m_startPos.y() + m_endPos.y()) / 2.0;
+
+ m_a = 0.0;
+ m_scaleX = 1.0;
+ m_scaleY = 1.0;
+ m_translateX = m_org_cenX;
+ m_translateY = m_org_cenY;
+
+ m_subject->canvasController() ->updateCanvas();
+}
+
+void KisToolTransform::paint(KisCanvasPainter& gc)
+{
+ paintOutline(gc, TQRect());
+}
+
+void KisToolTransform::paint(KisCanvasPainter& gc, const TQRect& rc)
+{
+ paintOutline(gc, rc);
+}
+
+
+void KisToolTransform::buttonPress(KisButtonPressEvent *e)
+{
+ if (m_subject && e->button() == Qt::LeftButton) {
+ m_wasPressed = true;
+ }
+
+ if (m_subject) {
+ KisImageSP img = m_subject->currentImg();
+
+ if (img && img->activeDevice() && e->button() == Qt::LeftButton) {
+ switch(m_function)
+ {
+ case ROTATE:
+ m_clickoffset = e->pos().floorTQPoint()
+ - TQPoint(static_cast<int>(m_translateX),static_cast<int>(m_translateY));
+ m_clickangle = -m_a - atan2(m_clickoffset.x(),m_clickoffset.y());
+ m_clickoffset = TQPoint(0, 0);
+ break;
+ case MOVE:
+ m_clickoffset = e->pos().floorTQPoint()
+ - TQPoint(static_cast<int>(m_translateX),static_cast<int>(m_translateY));
+ break;
+ case TOPSCALE:
+ m_clickoffset = e->pos().floorTQPoint()
+ - TQPoint((m_topleft + m_topright)/2);
+ break;
+ case TOPRIGHTSCALE:
+ m_clickoffset = e->pos().floorTQPoint() - m_topright;
+ break;
+ case RIGHTSCALE:
+ m_clickoffset = e->pos().floorTQPoint()
+ - TQPoint((m_topright + m_bottomright)/2);
+ break;
+ case BOTTOMRIGHTSCALE:
+ m_clickoffset = e->pos().floorTQPoint() - m_bottomright;
+ break;
+ case BOTTOMSCALE:
+ m_clickoffset = e->pos().floorTQPoint()
+ - TQPoint((m_bottomleft + m_bottomright)/2);
+ break;
+ case BOTTOMLEFTSCALE:
+ m_clickoffset = e->pos().floorTQPoint() - m_bottomleft;
+ break;
+ case LEFTSCALE:
+ m_clickoffset = e->pos().floorTQPoint()
+ - TQPoint((m_topleft + m_bottomleft)/2);
+ break;
+ case TOPLEFTSCALE:
+ m_clickoffset = e->pos().floorTQPoint() - m_topleft;
+ break;
+ }
+ m_selecting = true;
+ m_actualyMoveWhileSelected = false;
+ }
+ }
+}
+
+int KisToolTransform::det(TQPoint v,TQPoint w)
+{
+ return v.x()*w.y()-v.y()*w.x();
+}
+int KisToolTransform::distsq(TQPoint v,TQPoint w)
+{
+ v -= w;
+ return v.x()*v.x() + v.y()*v.y();
+}
+
+void KisToolTransform::setFunctionalCursor()
+{
+ int rotOctant = 8 + int(8.5 + m_a* 4 / M_PI);
+
+ int s;
+ if(m_scaleX*m_scaleY<0)
+ s = -1;
+ else
+ s=1;
+
+ switch(m_function)
+ {
+ case MOVE:
+ setCursor(KisCursor::moveCursor());
+ break;
+ case ROTATE:
+ setCursor(KisCursor::rotateCursor());
+ break;
+ case TOPSCALE:
+ setCursor(m_sizeCursors[(0*s +rotOctant)%8]);
+ break;
+ case TOPRIGHTSCALE:
+ setCursor(m_sizeCursors[(1*s +rotOctant)%8]);
+ break;
+ case RIGHTSCALE:
+ setCursor(m_sizeCursors[(2*s +rotOctant)%8]);
+ break;
+ case BOTTOMRIGHTSCALE:
+ setCursor(m_sizeCursors[(3*s +rotOctant)%8]);
+ break;
+ case BOTTOMSCALE:
+ setCursor(m_sizeCursors[(4*s +rotOctant)%8]);
+ break;
+ case BOTTOMLEFTSCALE:
+ setCursor(m_sizeCursors[(5*s +rotOctant)%8]);
+ break;
+ case LEFTSCALE:
+ setCursor(m_sizeCursors[(6*s +rotOctant)%8]);
+ break;
+ case TOPLEFTSCALE:
+ setCursor(m_sizeCursors[(7*s +rotOctant)%8]);
+ break;
+ }
+}
+
+void KisToolTransform::move(KisMoveEvent *e)
+{
+ if (m_subject) {
+ KisCanvasController *controller = m_subject->canvasController();
+
+ Q_ASSERT(controller);
+ TQPoint topleft = m_topleft;
+ TQPoint topright = m_topright;
+ TQPoint bottomleft = m_bottomleft;
+ TQPoint bottomright = m_bottomright;
+
+ TQPoint mousePos = e->pos().floorTQPoint();
+
+ if (m_subject && m_selecting) {
+ paintOutline();
+ m_actualyMoveWhileSelected = true;
+ mousePos -= m_clickoffset;
+
+ // transform mousePos coords, so it seems like it isn't rotated and centered at 0,0
+ double newX = invrotX(mousePos.x() - m_translateX, mousePos.y() - m_translateY);
+ double newY = invrotY(mousePos.x() - m_translateX, mousePos.y() - m_translateY);
+ double dx=0, dy=0;
+ double oldScaleX = m_scaleX;
+ double oldScaleY = m_scaleY;
+
+ if(m_function == MOVE)
+ {
+ m_translateX += mousePos.x() - m_translateX;
+ m_translateY += mousePos.y() - m_translateY;
+ }
+
+ if(m_function == ROTATE)
+ {
+ m_a = -atan2(mousePos.x() - m_translateX, mousePos.y() - m_translateY)
+ - m_clickangle;
+ }
+
+ if(m_function == TOPSCALE)
+ {
+ dy = (newY - m_scaleY * (m_startPos.y() - m_org_cenY)) / 2;
+ m_scaleY = (newY - dy) / (m_startPos.y() - m_org_cenY);
+
+ // enforce same acpect if shift button is pressed
+ if(e->state() & TQt::ShiftButton)
+ {
+ if(m_scaleX>0) // handle the mirrored cases
+ m_scaleX = fabs(m_scaleY);
+ else
+ m_scaleX = -fabs(m_scaleY);
+ }
+ }
+
+ if(m_function == TOPRIGHTSCALE)
+ {
+ dx = (newX - m_scaleX * (m_endPos.x() - m_org_cenX)) / 2;
+ m_scaleX = (newX - dx) / (m_endPos.x() - m_org_cenX);
+
+ dy = (newY - m_scaleY * (m_startPos.y() - m_org_cenY)) / 2;
+ m_scaleY = (newY - dy) / (m_startPos.y() - m_org_cenY);
+
+ // enforce same aspect if shift button is pressed
+ if(e->state() & TQt::ShiftButton)
+ {
+ if(m_scaleX < m_scaleY)
+ {
+ if(m_scaleX>0) // handle the mirrored cases
+ m_scaleX = fabs(m_scaleY);
+ else
+ m_scaleX = -fabs(m_scaleY);
+ dx = (m_scaleX - oldScaleX) * (m_endPos.x() - m_org_cenX);
+ }
+ else
+ {
+ if(m_scaleY>0) // handle the mirrored cases
+ m_scaleY = fabs(m_scaleX);
+ else
+ m_scaleY = -fabs(m_scaleX);
+ dy = (m_scaleY - oldScaleY) * (m_startPos.y() - m_org_cenY);
+ }
+ }
+ }
+
+ if(m_function == RIGHTSCALE)
+ {
+ dx = (newX - m_scaleX * (m_endPos.x() - m_org_cenX)) / 2;
+ m_scaleX = (newX - dx) / (m_endPos.x() - m_org_cenX);
+
+ // enforce same acpect if shift button is pressed
+ if(e->state() & TQt::ShiftButton)
+ {
+ if(m_scaleY>0) // handle the mirrored cases
+ m_scaleY = fabs(m_scaleX);
+ else
+ m_scaleY = -fabs(m_scaleX);
+ }
+ }
+
+ if(m_function == BOTTOMRIGHTSCALE)
+ {
+ dx = (newX - m_scaleX * (m_endPos.x() - m_org_cenX)) / 2;
+ m_scaleX = (newX - dx) / (m_endPos.x() - m_org_cenX);
+
+ dy = (newY - m_scaleY * (m_endPos.y() - m_org_cenY)) / 2;
+ m_scaleY = (newY - dy) / (m_endPos.y() - m_org_cenY);
+
+ // enforce same acpect if shift button is pressed
+ if(e->state() & TQt::ShiftButton)
+ {
+ if(m_scaleX < m_scaleY)
+ {
+ if(m_scaleX>0) // handle the mirrored cases
+ m_scaleX = fabs(m_scaleY);
+ else
+ m_scaleX = -fabs(m_scaleY);
+ dx = (m_scaleX - oldScaleX) * (m_endPos.x() - m_org_cenX);
+ }
+ else
+ {
+ if(m_scaleY>0) // handle the mirrored cases
+ m_scaleY = fabs(m_scaleX);
+ else
+ m_scaleY = -fabs(m_scaleX);
+ dy = (m_scaleY - oldScaleY) * (m_endPos.y() - m_org_cenY);
+ }
+ }
+ }
+
+ if(m_function == BOTTOMSCALE)
+ {
+ dy = (newY - m_scaleY * (m_endPos.y() - m_org_cenY)) / 2;
+ m_scaleY = (newY - dy) / (m_endPos.y() - m_org_cenY);
+
+ // enforce same acpect if shift button is pressed
+ if(e->state() & TQt::ShiftButton)
+ {
+ if(m_scaleX>0) // handle the mirrored cases
+ m_scaleX = fabs(m_scaleY);
+ else
+ m_scaleX = -fabs(m_scaleY);
+ }
+ }
+
+ if(m_function == BOTTOMLEFTSCALE)
+ {
+ dx = (newX - m_scaleX * (m_startPos.x() - m_org_cenX)) / 2;
+ m_scaleX = (newX - dx) / (m_startPos.x() - m_org_cenX);
+
+ dy = (newY - m_scaleY * (m_endPos.y() - m_org_cenY)) / 2;
+ m_scaleY = (newY - dy) / (m_endPos.y() - m_org_cenY);
+
+ // enforce same acpect if shift button is pressed
+ if(e->state() & TQt::ShiftButton)
+ {
+ if(m_scaleX < m_scaleY)
+ {
+ if(m_scaleX>0) // handle the mirrored cases
+ m_scaleX = fabs(m_scaleY);
+ else
+ m_scaleX = -fabs(m_scaleY);
+ dx = (m_scaleX - oldScaleX) * (m_startPos.x() - m_org_cenX);
+ }
+ else
+ {
+ if(m_scaleY>0) // handle the mirrored cases
+ m_scaleY = fabs(m_scaleX);
+ else
+ m_scaleY = -fabs(m_scaleX);
+ dy = (m_scaleY - oldScaleY) * (m_endPos.y() - m_org_cenY);
+ }
+ }
+ }
+
+ if(m_function == LEFTSCALE)
+ {
+ dx = (newX - m_scaleX * (m_startPos.x() - m_org_cenX)) / 2;
+ m_scaleX = (newX - dx) / (m_startPos.x() - m_org_cenX);
+
+ // enforce same acpect if shift button is pressed
+ if(e->state() & TQt::ShiftButton)
+ {
+ if(m_scaleY>0) // handle the mirrored cases
+ m_scaleY = fabs(m_scaleX);
+ else
+ m_scaleY = -fabs(m_scaleX);
+ }
+ }
+
+ if(m_function == TOPLEFTSCALE)
+ {
+ dx = (newX - m_scaleX * (m_startPos.x() - m_org_cenX)) / 2;
+ m_scaleX = (newX - dx) / (m_startPos.x() - m_org_cenX);
+
+ dy = (newY - m_scaleY * (m_startPos.y() - m_org_cenY)) / 2;
+ m_scaleY = (newY - dy) / (m_startPos.y() - m_org_cenY);
+
+ // enforce same acpect if shift button is pressed
+ if(e->state() & TQt::ShiftButton)
+ {
+ if(m_scaleX < m_scaleY)
+ {
+ if(m_scaleX>0) // handle the mirrored cases
+ m_scaleX = fabs(m_scaleY);
+ else
+ m_scaleX = -fabs(m_scaleY);
+ dx = (m_scaleX - oldScaleX) * (m_startPos.x() - m_org_cenX);
+ }
+ else
+ {
+ if(m_scaleY>0) // handle the mirrored cases
+ m_scaleY = fabs(m_scaleX);
+ else
+ m_scaleY = -fabs(m_scaleX);
+ dy = (m_scaleY - oldScaleY) * (m_startPos.y() - m_org_cenY);
+ }
+ }
+ }
+
+ m_translateX += rotX(dx, dy);
+ m_translateY += rotY(dx, dy);
+
+ paintOutline();
+ }
+ else
+ {
+ if(det(mousePos - topleft, topright - topleft)>0)
+ m_function = ROTATE;
+ else if(det(mousePos - topright, bottomright - topright)>0)
+ m_function = ROTATE;
+ else if(det(mousePos - bottomright, bottomleft - bottomright)>0)
+ m_function = ROTATE;
+ else if(det(mousePos - bottomleft, topleft - bottomleft)>0)
+ m_function = ROTATE;
+ else
+ m_function = MOVE;
+
+ int handleradius = int( 25 / (m_subject->zoomFactor() * m_subject->zoomFactor()) );
+
+ if(distsq(mousePos, (m_topleft + m_topright)/2)<=handleradius)
+ m_function = TOPSCALE;
+ if(distsq(mousePos, m_topright)<=handleradius)
+ m_function = TOPRIGHTSCALE;
+ if(distsq(mousePos, (m_topright + m_bottomright)/2)<=handleradius)
+ m_function = RIGHTSCALE;
+ if(distsq(mousePos, m_bottomright)<=handleradius)
+ m_function = BOTTOMRIGHTSCALE;
+ if(distsq(mousePos, (m_bottomleft + m_bottomright)/2)<=handleradius)
+ m_function = BOTTOMSCALE;
+ if(distsq(mousePos, m_bottomleft)<=handleradius)
+ m_function = BOTTOMLEFTSCALE;
+ if(distsq(mousePos, (m_topleft + m_bottomleft)/2)<=handleradius)
+ m_function = LEFTSCALE;
+ if(distsq(mousePos, m_topleft)<=handleradius)
+ m_function = TOPLEFTSCALE;
+
+ setFunctionalCursor();
+ }
+ }
+}
+
+void KisToolTransform::buttonRelease(KisButtonReleaseEvent *e)
+{
+ if (m_subject && e->button() == Qt::LeftButton) {
+ if(!m_wasPressed) return;
+ m_wasPressed = false;
+
+ KisImageSP img = m_subject->currentImg();
+
+ if (!img)
+ return;
+
+ m_selecting = false;
+
+ if(m_actualyMoveWhileSelected)
+ {
+ paintOutline();
+ TQApplication::setOverrideCursor(KisCursor::waitCursor());
+ transform();
+ TQApplication::restoreOverrideCursor();
+ }
+ }
+}
+
+void KisToolTransform::paintOutline()
+{
+ if (m_subject) {
+ KisCanvasController *controller = m_subject->canvasController();
+ KisCanvas *canvas = controller->kiscanvas();
+ KisCanvasPainter gc(canvas);
+ TQRect rc;
+
+ paintOutline(gc, rc);
+ }
+}
+
+void KisToolTransform::recalcOutline()
+{
+ double x,y;
+
+ m_sina = sin(m_a);
+ m_cosa = cos(m_a);
+
+ x = (m_startPos.x() - m_org_cenX) * m_scaleX;
+ y = (m_startPos.y() - m_org_cenY) * m_scaleY;
+ m_topleft = TQPoint(int(rotX(x,y) + m_translateX+0.5), int(rotY(x,y) + m_translateY+0.5));
+
+ x = (m_endPos.x() - m_org_cenX) * m_scaleX;
+ y = (m_startPos.y() - m_org_cenY) * m_scaleY;
+ m_topright = TQPoint(int(rotX(x,y) + m_translateX+0.5), int(rotY(x,y) + m_translateY+0.5));
+
+ x = (m_startPos.x() - m_org_cenX) * m_scaleX;
+ y = (m_endPos.y() - m_org_cenY) * m_scaleY;
+ m_bottomleft = TQPoint(int(rotX(x,y) + m_translateX+0.5), int(rotY(x,y) + m_translateY+0.5));
+
+ x = (m_endPos.x() - m_org_cenX) * m_scaleX;
+ y = (m_endPos.y() - m_org_cenY) * m_scaleY;
+ m_bottomright = TQPoint(int(rotX(x,y) + m_translateX+0.5), int(rotY(x,y) + m_translateY+0.5));
+}
+
+void KisToolTransform::paintOutline(KisCanvasPainter& gc, const TQRect&)
+{
+ if (m_subject) {
+ KisCanvasController *controller = m_subject->canvasController();
+ RasterOp op = gc.rasterOp();
+ TQPen old = gc.pen();
+ TQPen pen(TQt::SolidLine);
+ pen.setWidth(1);
+ Q_ASSERT(controller);
+
+ recalcOutline();
+ TQPoint topleft = controller->windowToView(m_topleft);
+ TQPoint topright = controller->windowToView(m_topright);
+ TQPoint bottomleft = controller->windowToView(m_bottomleft);
+ TQPoint bottomright = controller->windowToView(m_bottomright);
+
+ gc.setRasterOp(TQt::NotROP);
+ gc.setPen(pen);
+ gc.drawRect(topleft.x()-4, topleft.y()-4, 8, 8);
+ gc.drawLine(topleft.x(), topleft.y(), (topleft.x()+topright.x())/2, (topleft.y()+topright.y())/2);
+ gc.drawRect((topleft.x()+topright.x())/2-4, (topleft.y()+topright.y())/2-4, 8, 8);
+ gc.drawLine((topleft.x()+topright.x())/2, (topleft.y()+topright.y())/2, topright.x(), topright.y());
+ gc.drawRect(topright.x()-4, topright.y()-4, 8, 8);
+ gc.drawLine(topright.x(), topright.y(), (topright.x()+bottomright.x())/2, (topright.y()+bottomright.y())/2);
+ gc.drawRect((topright.x()+bottomright.x())/2-4, (topright.y()+bottomright.y())/2-4, 8, 8);
+ gc.drawLine((topright.x()+bottomright.x())/2, (topright.y()+bottomright.y())/2,bottomright.x(), bottomright.y());
+ gc.drawRect(bottomright.x()-4, bottomright.y()-4, 8, 8);
+ gc.drawLine(bottomright.x(), bottomright.y(), (bottomleft.x()+bottomright.x())/2, (bottomleft.y()+bottomright.y())/2);
+ gc.drawRect((bottomleft.x()+bottomright.x())/2-4, (bottomleft.y()+bottomright.y())/2-4, 8, 8);
+ gc.drawLine((bottomleft.x()+bottomright.x())/2, (bottomleft.y()+bottomright.y())/2, bottomleft.x(), bottomleft.y());
+ gc.drawRect(bottomleft.x()-4, bottomleft.y()-4, 8, 8);
+ gc.drawLine(bottomleft.x(), bottomleft.y(), (topleft.x()+bottomleft.x())/2, (topleft.y()+bottomleft.y())/2);
+ gc.drawRect((topleft.x()+bottomleft.x())/2-4, (topleft.y()+bottomleft.y())/2-4, 8, 8);
+ gc.drawLine((topleft.x()+bottomleft.x())/2, (topleft.y()+bottomleft.y())/2, topleft.x(), topleft.y());
+ gc.setRasterOp(op);
+ gc.setPen(old);
+ }
+}
+
+void KisToolTransform::transform()
+{
+
+ KisImageSP img = m_subject->currentImg();
+
+ if (!img || !img->activeDevice())
+ return;
+
+ double tx = m_translateX - rotX(m_org_cenX * m_scaleX, m_org_cenY * m_scaleY);
+ double ty = m_translateY - rotY(m_org_cenX * m_scaleX, m_org_cenY * m_scaleY);
+ KisProgressDisplayInterface *progress = m_subject->progressDisplay();
+
+ // This mementoes the current state of the active device.
+ TransformCmd * transaction = new TransformCmd(this, img->activeDevice(), m_origDevice,
+ m_scaleX, m_scaleY, m_translateX, m_translateY, m_a, m_origSelection, m_startPos, m_endPos);
+
+ // Copy the original state back.
+ TQRect rc = m_origDevice->extent();
+ rc = rc.normalize();
+ img->activeDevice()->clear();
+ KisPainter gc(img->activeDevice());
+ gc.bitBlt(rc.x(), rc.y(), COMPOSITE_COPY, m_origDevice, rc.x(), rc.y(), rc.width(), rc.height());
+ gc.end();
+
+ // Also restore the original selection.
+ if(m_origSelection)
+ {
+ //TQRect rc = m_origSelection->extent();
+ TQRect rc = m_origSelection->selectedRect();
+ rc = rc.normalize();
+ img->activeDevice()->selection()->clear();
+ KisPainter sgc(img->activeDevice()->selection().data());
+ sgc.bitBlt(rc.x(), rc.y(), COMPOSITE_COPY, m_origSelection.data(), rc.x(), rc.y(), rc.width(), rc.height());
+ sgc.end();
+ }
+ else
+ if(img->activeDevice()->hasSelection())
+ img->activeDevice()->selection()->clear();
+
+ // Perform the transform. Since we copied the original state back, this doesn't degrade
+ // after many tweaks. Since we started the transaction before the copy back, the memento
+ // has the previous state.
+ KisTransformWorker t(img->activeDevice(), m_scaleX, m_scaleY, 0, 0, m_a, int(tx), int(ty), progress, m_filter);
+ t.run();
+
+ // If canceled, go back to the memento
+ if(t.isCanceled())
+ {
+ transaction->unexecute();
+ delete transaction;
+ return;
+ }
+
+ img->activeDevice()->setDirty(rc); // XXX: This is not enough - should union with new extent
+
+ // Else add the command -- this will have the memento from the previous state,
+ // and the transformed state from the original device we cached in our activated()
+ // method.
+ if (transaction) {
+ if (img->undo())
+ img->undoAdapter()->addCommand(transaction);
+ else
+ delete transaction;
+ }
+}
+
+void KisToolTransform::notifyCommandAdded( KCommand * command)
+{
+ TransformCmd * cmd = dynamic_cast<TransformCmd*>(command);
+ if (cmd == 0) {
+ // The last added command wasn't one of ours;
+ // we should reset to the new state of the canvas.
+ // In effect we should treat this as if the tool has been just activated
+ initHandles();
+ }
+}
+
+void KisToolTransform::notifyCommandExecuted( KCommand * command)
+{
+ Q_UNUSED(command);
+ TransformCmd * cmd=0;
+
+ if(m_subject->currentImg()->undoAdapter()->presentCommand())
+ cmd = dynamic_cast<TransformCmd*>(m_subject->currentImg()->undoAdapter()->presentCommand());
+
+ if (cmd == 0) {
+ // The command now on the top of the stack isn't one of ours
+ // We should treat this as if the tool has been just activated
+ initHandles();
+ }
+ else
+ {
+ // One of our commands is now on top
+ // We should ask for tool args and orig selection
+ cmd->transformArgs(m_scaleX, m_scaleY, m_translateX, m_translateY, m_a);
+ m_origSelection = cmd->origSelection(m_startPos, m_endPos);
+ m_origDevice = cmd->origDevice();
+ m_org_cenX = (m_startPos.x() + m_endPos.x()) / 2.0;
+ m_org_cenY = (m_startPos.y() + m_endPos.y()) / 2.0;
+ m_subject->canvasController() ->updateCanvas();
+ }
+}
+
+void KisToolTransform::slotSetFilter(const KisID &filterID)
+{
+ m_filter = KisFilterStrategyRegistry::instance()->get(filterID);
+}
+
+void KisToolTransform::slotLayerActivated(KisLayerSP)
+{
+ activate();
+}
+
+
+TQWidget* KisToolTransform::createOptionWidget(TQWidget* tqparent)
+{
+
+ m_optWidget = new WdgToolTransform(tqparent);
+ Q_CHECK_PTR(m_optWidget);
+
+ m_optWidget->cmbFilter->clear();
+ m_optWidget->cmbFilter->setIDList(KisFilterStrategyRegistry::instance()->listKeys());
+
+ m_optWidget->cmbFilter->setCurrentText("Mitchell");
+ connect(m_optWidget->cmbFilter, TQT_SIGNAL(activated(const KisID &)),
+ this, TQT_SLOT(slotSetFilter(const KisID &)));
+
+ KisID filterID = m_optWidget->cmbFilter->currentItem();
+ m_filter = KisFilterStrategyRegistry::instance()->get(filterID);
+
+/*
+ connect(m_optWidget->intStartX, TQT_SIGNAL(valueChanged(int)), this, TQT_SLOT(setStartX(int)));
+ connect(m_optWidget->intStartY, TQT_SIGNAL(valueChanged(int)), this, TQT_SLOT(setStartY(int)));
+ connect(m_optWidget->intEndX, TQT_SIGNAL(valueChanged(int)), this, TQT_SLOT(setEndX(int)));
+ connect(m_optWidget->intEndY, TQT_SIGNAL(valueChanged(int)), this, TQT_SLOT(setEndY(int)));
+*/
+ m_optWidget->intStartX->hide();
+ m_optWidget->intStartY->hide();
+ m_optWidget->intEndX->hide();
+ m_optWidget->intEndY->hide();
+ m_optWidget->textLabel1->hide();
+ m_optWidget->textLabel2->hide();
+ m_optWidget->textLabel3->hide();
+ m_optWidget->textLabel4->hide();
+ return m_optWidget;
+}
+
+TQWidget* KisToolTransform::optionWidget()
+{
+ return m_optWidget;
+}
+
+void KisToolTransform::setup(KActionCollection *collection)
+{
+ m_action = static_cast<KRadioAction *>(collection->action(name()));
+
+ if (m_action == 0) {
+ m_action = new KRadioAction(i18n("&Transform"),
+ "tool_transform",
+ 0,
+ this,
+ TQT_SLOT(activate()),
+ collection,
+ name());
+ Q_CHECK_PTR(m_action);
+ m_action->setToolTip(i18n("Transform a layer or a selection"));
+ m_action->setExclusiveGroup("tools");
+ m_ownAction = true;
+ }
+}
+
+#include "kis_tool_transform.moc"
diff --git a/chalk/plugins/tools/tool_transform/kis_tool_transform.h b/chalk/plugins/tools/tool_transform/kis_tool_transform.h
new file mode 100644
index 00000000..a98cd4f7
--- /dev/null
+++ b/chalk/plugins/tools/tool_transform/kis_tool_transform.h
@@ -0,0 +1,155 @@
+/*
+ * kis_tool_transform.h - part of Chalk
+ *
+ * Copyright (c) 2004 Boudewijn Rempt <boud@valdyas.org>
+ * Copyright (c) 2005 Casper Boemann <cbr@boemann.dk>
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef KIS_TOOL_TRANSFORM_H_
+#define KIS_TOOL_TRANSFORM_H_
+
+#include <tqpoint.h>
+
+#include <kis_tool_non_paint.h>
+#include <kis_tool_factory.h>
+#include <kis_undo_adapter.h>
+#include <kis_layer.h>
+
+class KisTransaction;
+class WdgToolTransform;
+class KisID;
+class KisFilterStrategy;
+
+/**
+ * Transform tool
+ *
+ */
+class KisToolTransform : public KisToolNonPaint, KisCommandHistoryListener {
+
+ typedef KisToolNonPaint super;
+ Q_OBJECT
+ TQ_OBJECT
+
+public:
+ KisToolTransform();
+ virtual ~KisToolTransform();
+
+ virtual TQWidget* createOptionWidget(TQWidget* tqparent);
+ virtual TQWidget* optionWidget();
+
+ virtual void setup(KActionCollection *collection);
+ virtual enumToolType toolType() { return TOOL_TRANSFORM; }
+ virtual TQ_UINT32 priority() { return 3; }
+ virtual void paint(KisCanvasPainter& gc);
+ virtual void paint(KisCanvasPainter& gc, const TQRect& rc);
+ virtual void buttonPress(KisButtonPressEvent *e);
+ virtual void move(KisMoveEvent *e);
+ virtual void buttonRelease(KisButtonReleaseEvent *e);
+ void setScaleX(double sx) { m_scaleX = sx; }
+ void setScaleY(double sy) { m_scaleY = sy; }
+ void setTranslateX(double tx) { m_translateX = tx; }
+ void setTranslateY(double ty) { m_translateY = ty; }
+ void setAngle(double a) { m_a = a; }
+ void paintOutline();
+
+public:
+
+ void notifyCommandAdded(KCommand *);
+ void notifyCommandExecuted(KCommand *);
+
+public:
+ virtual void deactivate();
+
+private:
+
+ void paintOutline(KisCanvasPainter& gc, const TQRect& rc);
+ void transform();
+ void recalcOutline();
+ double rotX(double x, double y) { return m_cosa*x - m_sina*y;};
+ double rotY(double x, double y) { return m_sina*x + m_cosa*y;};
+ double invrotX(double x, double y) { return m_cosa*x + m_sina*y;};
+ double invrotY(double x, double y) { return -m_sina*x + m_cosa*y;};
+ int det(TQPoint v,TQPoint w);
+ int distsq(TQPoint v,TQPoint w);
+ void setFunctionalCursor();
+ void initHandles();
+
+private slots:
+
+ void slotLayerActivated(KisLayerSP);
+ void slotSetFilter(const KisID &);
+ void setStartX(int x) { m_startPos.setX(x); }
+ void setStartY(int y) { m_startPos.setY(y); }
+ void setEndX(int x) { m_endPos.setX(x); }
+ void setEndY(int y) { m_endPos.setY(y); }
+
+protected slots:
+ virtual void activate();
+
+private:
+ enum function {ROTATE,MOVE,TOPLEFTSCALE,TOPSCALE,TOPRIGHTSCALE,RIGHTSCALE,
+ BOTTOMRIGHTSCALE, BOTTOMSCALE,BOTTOMLEFTSCALE, LEFTSCALE};
+ TQCursor m_sizeCursors[8];
+ function m_function;
+ TQPoint m_startPos;
+ TQPoint m_endPos;
+ bool m_selecting;
+ bool m_actualyMoveWhileSelected;
+ TQPoint m_topleft;
+ TQPoint m_topright;
+ TQPoint m_bottomleft;
+ TQPoint m_bottomright;
+ double m_scaleX;
+ double m_scaleY;
+ double m_translateX;
+ double m_translateY;
+ TQPoint m_clickoffset;
+ double m_org_cenX;
+ double m_org_cenY;
+ double m_cosa;
+ double m_sina;
+ double m_a;
+ double m_clickangle;
+ KisFilterStrategy *m_filter;
+
+ WdgToolTransform *m_optWidget;
+
+ KisPaintDeviceSP m_origDevice;
+ KisSelectionSP m_origSelection;
+
+ bool m_wasPressed;
+};
+
+class KisToolTransformFactory : public KisToolFactory {
+ typedef KisToolFactory super;
+
+public:
+ KisToolTransformFactory() : super() {};
+ virtual ~KisToolTransformFactory(){};
+
+ virtual KisTool * createTool(KActionCollection * ac) {
+ KisTool * t = new KisToolTransform();
+ Q_CHECK_PTR(t);
+ t->setup(ac); return t;
+ }
+ virtual KisID id() { return KisID("transform", i18n("Transform Tool")); }
+};
+
+
+
+#endif // KIS_TOOL_TRANSFORM_H_
+
diff --git a/chalk/plugins/tools/tool_transform/rotate_cursor.xpm b/chalk/plugins/tools/tool_transform/rotate_cursor.xpm
new file mode 100644
index 00000000..f3860232
--- /dev/null
+++ b/chalk/plugins/tools/tool_transform/rotate_cursor.xpm
@@ -0,0 +1,29 @@
+/* XPM */
+static char *rotate_cursor[]={
+"22 22 4 1",
+"b c None",
+". c None",
+"a c #000000",
+"# c #ffffff",
+"......................",
+"......................",
+"....##...#####........",
+"....#a###aaaaa##......",
+"....#aaaabbbbbaa#.....",
+"....#aaa#.....bba#....",
+"....#aaaa#......ba#...",
+"....######......bba#..",
+".................ba#..",
+"..bbb.............ba#.",
+"..#ab.............ba#.",
+"..#ab.............ba#.",
+"..#ab.............ba#.",
+"..#ab.............ba#.",
+"...#ab............bbb.",
+"...#ab.......######...",
+"....#ab......#aaaa#...",
+".....#abbb....#aaa#...",
+"......#aabbbb#aaaa#...",
+".......##aaaaa###a#...",
+".........#####...##...",
+"......................"};
diff --git a/chalk/plugins/tools/tool_transform/tool_transform.cc b/chalk/plugins/tools/tool_transform/tool_transform.cc
new file mode 100644
index 00000000..2ee002de
--- /dev/null
+++ b/chalk/plugins/tools/tool_transform/tool_transform.cc
@@ -0,0 +1,64 @@
+/*
+ * tool_transform.cc -- Part of Chalk
+ *
+ * Copyright (c) 2004 Boudewijn Rempt (boud@valdyas.org)
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+#include <stdlib.h>
+#include <vector>
+
+#include <tqpoint.h>
+
+#include <klocale.h>
+#include <kiconloader.h>
+#include <kinstance.h>
+#include <kmessagebox.h>
+#include <kstandarddirs.h>
+#include <kdebug.h>
+#include <kgenericfactory.h>
+
+#include <kis_global.h>
+#include <kis_types.h>
+#include <kis_tool_registry.h>
+
+#include "tool_transform.h"
+#include "kis_tool_transform.h"
+
+
+typedef KGenericFactory<ToolTransform> ToolTransformFactory;
+K_EXPORT_COMPONENT_FACTORY( chalktooltransform, ToolTransformFactory( "chalk" ) )
+
+
+ToolTransform::ToolTransform(TQObject *tqparent, const char *name, const TQStringList &)
+ : KParts::Plugin(tqparent, name)
+{
+ setInstance(ToolTransformFactory::instance());
+
+ if ( tqparent->inherits("KisToolRegistry") )
+ {
+ KisToolRegistry * r = dynamic_cast<KisToolRegistry*>(tqparent);
+ KisToolTransformFactory * f = new KisToolTransformFactory();
+ Q_CHECK_PTR(f);
+ r->add(f);
+ }
+
+}
+
+ToolTransform::~ToolTransform()
+{
+}
+
+#include "tool_transform.moc"
diff --git a/chalk/plugins/tools/tool_transform/tool_transform.h b/chalk/plugins/tools/tool_transform/tool_transform.h
new file mode 100644
index 00000000..04bfbaa9
--- /dev/null
+++ b/chalk/plugins/tools/tool_transform/tool_transform.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2004 Boudewijn Rempt (boud@valdyas.org)
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef TOOL_TRANSFORM_H_
+#define TOOL_TRANSFORM_H_
+
+#include <kparts/plugin.h>
+
+class KisView;
+
+/**
+ * A module that provides a transform tool.
+ */
+class ToolTransform : public KParts::Plugin
+{
+ Q_OBJECT
+ TQ_OBJECT
+public:
+ ToolTransform(TQObject *tqparent, const char *name, const TQStringList &);
+ virtual ~ToolTransform();
+
+private:
+
+ KisView * m_view;
+
+};
+
+#endif // TOOL_TRANSFORM_H_
diff --git a/chalk/plugins/tools/tool_transform/tool_transform.png b/chalk/plugins/tools/tool_transform/tool_transform.png
new file mode 100644
index 00000000..6c601433
--- /dev/null
+++ b/chalk/plugins/tools/tool_transform/tool_transform.png
Binary files differ
diff --git a/chalk/plugins/tools/tool_transform/wdg_tool_transform.ui b/chalk/plugins/tools/tool_transform/wdg_tool_transform.ui
new file mode 100644
index 00000000..2f41e1b3
--- /dev/null
+++ b/chalk/plugins/tools/tool_transform/wdg_tool_transform.ui
@@ -0,0 +1,243 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>WdgToolTransform</class>
+<widget class="TQWidget">
+ <property name="name">
+ <cstring>WdgToolTransform</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>377</width>
+ <height>91</height>
+ </rect>
+ </property>
+ <property name="caption">
+ <string>Transform</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>3</number>
+ </property>
+ <widget class="TQLayoutWidget" row="0" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>tqlayout11</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="TQLayoutWidget">
+ <property name="name">
+ <cstring>tqlayout7</cstring>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="TQLayoutWidget">
+ <property name="name">
+ <cstring>tqlayout1</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="TQLabel">
+ <property name="name">
+ <cstring>textLabel1</cstring>
+ </property>
+ <property name="text">
+ <string>Move X:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>isbX</cstring>
+ </property>
+ </widget>
+ <widget class="KIntSpinBox">
+ <property name="name">
+ <cstring>intStartX</cstring>
+ </property>
+ <property name="maxValue">
+ <number>1000000000</number>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget class="TQLayoutWidget">
+ <property name="name">
+ <cstring>tqlayout2</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="TQLabel">
+ <property name="name">
+ <cstring>textLabel2</cstring>
+ </property>
+ <property name="text">
+ <string>Scale X:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>isbWidth</cstring>
+ </property>
+ </widget>
+ <widget class="KIntSpinBox">
+ <property name="name">
+ <cstring>intEndX</cstring>
+ </property>
+ <property name="maxValue">
+ <number>1000000000</number>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ </vbox>
+ </widget>
+ <widget class="TQLayoutWidget">
+ <property name="name">
+ <cstring>tqlayout8</cstring>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="TQLayoutWidget">
+ <property name="name">
+ <cstring>tqlayout3</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="TQLabel">
+ <property name="name">
+ <cstring>textLabel3</cstring>
+ </property>
+ <property name="text">
+ <string>Move Y:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>isbY</cstring>
+ </property>
+ </widget>
+ <widget class="KIntSpinBox">
+ <property name="name">
+ <cstring>intStartY</cstring>
+ </property>
+ <property name="maxValue">
+ <number>1000000000</number>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget class="TQLayoutWidget">
+ <property name="name">
+ <cstring>tqlayout4</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="TQLabel">
+ <property name="name">
+ <cstring>textLabel4</cstring>
+ </property>
+ <property name="text">
+ <string>Scale Y:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>isbHeight</cstring>
+ </property>
+ </widget>
+ <widget class="KIntSpinBox">
+ <property name="name">
+ <cstring>intEndY</cstring>
+ </property>
+ <property name="maxValue">
+ <number>1000000000</number>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ </vbox>
+ </widget>
+ </hbox>
+ </widget>
+ <widget class="TQLabel" row="1" column="0">
+ <property name="name">
+ <cstring>textLabel1_2</cstring>
+ </property>
+ <property name="text">
+ <string>Filter:</string>
+ </property>
+ <property name="tqalignment">
+ <set>AlignVCenter|AlignRight</set>
+ </property>
+ </widget>
+ <widget class="KisCmbIDList" row="1" column="1">
+ <property name="name">
+ <cstring>cmbFilter</cstring>
+ </property>
+ </widget>
+ <spacer row="2" column="0">
+ <property name="name">
+ <cstring>spacer1</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="tqsizeHint">
+ <size>
+ <width>20</width>
+ <height>21</height>
+ </size>
+ </property>
+ </spacer>
+ </grid>
+</widget>
+<customwidgets>
+ <customwidget>
+ <class>KisCmbIDList</class>
+ <header location="local">kis_cmb_idlist.h</header>
+ <sizehint>
+ <width>1</width>
+ <height>24</height>
+ </sizehint>
+ <container>0</container>
+ <sizepolicy>
+ <hordata>5</hordata>
+ <verdata>5</verdata>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ <pixmap>image0</pixmap>
+ </customwidget>
+</customwidgets>
+<images>
+ <image name="image0">
+ <data format="PNG" length="870">89504e470d0a1a0a0000000d4948445200000016000000160806000000c4b46c3b0000032d49444154388db59531681c4714863f892dde8004b320c32e3870020b74458a6b0f5458e581c016a809a8496b42208454098604d2c4904a6954a410511ae752085b858c1208dc35221244b00119f60ac12ee860062c980719708a95a248f129459cd7cceeccf0edb76fff61a706830197d5ed765ff3166a30184c4d5d829fed3c7bdd5e6ce3bda71a5738ef301802e1d6d179477152303c1842bc822797a64fbf7b4a9a43be00ada817cb0e12011c2611205ccd73755f9c087c6b19bef0d7c100f5b8267d07caf10fe8ab9210156320fc01be16aa5a11043307f30b20a21041019985f48ef2f7fa0becc68e80475fd584e831b396f210f67795c3831a4940a3228925bb27f4d652ba4b01a199b73342f3981be0ca57745042ac30c632d853b6373d44b056c8ef0922508d94d14be59b2f4aeaf58cd5751069e06f3436890114332b9487d0bf80f61e64dc5f813c3790045453f67703fd4d4f7f6b4496b5597e689044af194f5f5e841800210478bee3d1a8f41e64acbe0f69ae6852e1cf0ccf7f74f4d652defbc042226c6f55e8f89f91bb6e9c387c9d521c9558db988a3416fe3c67e32b4779ec7167f0e8939ce19ea7fc5d298a80c875f03563930855ed2081bc05e91d5014ef53363eaf288e3d6285ee520a338e76c7a251a94e41e30470d3631004a262672e3eca59cec6978ef2b889979d11f2bb904af3be92081a416e28dfe831983920b1142345d5b0ff2234a6334276d7321ad53c795c511ca654a5a251996f19b83d158ef602b45a423d52f67703abeb29ee4ce9de4fc93378f218462f6b3efdb042cf3d59666977a0aa6fe9310888d25b13342afd4dcffeaee3d147399da540ab13f8f8b39c2cb3f8710d11ba2b96f9c57fcd7180287497a03ecde86f8dd8fe1a867b9ef6bb1612a84a871f6bd35b94e217a53832589970f2dcd85d9c7d4580d57521cbdaf4bfaf288e95e268d4ec8e60e72ccb0f2dbffea454e71e8d29f57882717152509482a48d8924b0bc12e82ee51445a03a6da079cbd0eec0fc22142b06620e89a3fc8d3783870743d814d2bc8994aa6ff286472e764902e5a96f72bbd3b4c37b280e95aa9e604c84e1cf978b37c74935797d7ae2ca7fac6968fe51ff0bf86dc30783c1d49f0baa9bb819e612310000000049454e44ae426082</data>
+ </image>
+</images>
+<tabstops>
+ <tabstop>intStartX</tabstop>
+ <tabstop>intStartY</tabstop>
+ <tabstop>intEndX</tabstop>
+ <tabstop>intEndY</tabstop>
+</tabstops>
+<tqlayoutdefaults spacing="6" margin="11"/>
+<includehints>
+ <includehint>knuminput.h</includehint>
+ <includehint>kis_cmb_idlist.h</includehint>
+</includehints>
+</UI>