Merge lp:~valavanisalex/ubuntu/utopic/inkscape/fix-1358863 into lp:ubuntu/utopic/inkscape

Proposed by Alex Valavanis on 2014-08-19
Status: Merged
Merged at revision: 87
Proposed branch: lp:~valavanisalex/ubuntu/utopic/inkscape/fix-1358863
Merge into: lp:ubuntu/utopic/inkscape
Diff against target: 83978 lines (+9530/-59871)
289 files modified
.pc/0001-Fix_Datamatrix_UI_issue.patch/share/extensions/render_barcode_datamatrix.inx (+0/-20)
.pc/0001-Fix_Datamatrix_UI_issue.patch/share/extensions/render_barcode_datamatrix.py (+0/-654)
.pc/0002-Drop_PS_and_PDF_support_in_MimeType.patch/inkscape.desktop.in (+0/-14)
.pc/0003-Fix_LP_-911146.patch/src/extension/implementation/script.cpp (+0/-1034)
.pc/0004-Fix_FTBFS_on_gcc-4.8.patch/src/connector-context.cpp (+0/-2041)
.pc/0004-Fix_FTBFS_on_gcc-4.8.patch/src/extension/effect.cpp (+0/-409)
.pc/0004-Fix_FTBFS_on_gcc-4.8.patch/src/gradient-drag.cpp (+0/-2216)
.pc/0004-Fix_FTBFS_on_gcc-4.8.patch/src/libavoid/vpsc.cpp (+0/-1301)
.pc/0004-Fix_FTBFS_on_gcc-4.8.patch/src/libcola/straightener.cpp (+0/-361)
.pc/0004-Fix_FTBFS_on_gcc-4.8.patch/src/libcroco/cr-parser.c (+0/-4409)
.pc/0004-Fix_FTBFS_on_gcc-4.8.patch/src/libvpsc/block.cpp (+0/-422)
.pc/0004-Fix_FTBFS_on_gcc-4.8.patch/src/widgets/desktop-widget.h (+0/-268)
.pc/0004-Fix_FTBFS_on_gcc-4.8.patch/src/widgets/toolbox.cpp (+0/-8503)
.pc/0005-Fix_FreeType_include.patch/src/libnrtype/FontFactory.h (+0/-163)
.pc/0006-Fix_FTBFS_on_poppler-0.26.patch/configure.ac (+0/-1065)
.pc/0006-Fix_FTBFS_on_poppler-0.26.patch/src/extension/internal/pdfinput/pdf-parser.cpp (+0/-3399)
.pc/0006_add_unity_quicklist_support.patch/inkscape.desktop.in (+0/-14)
.pc/applied-patches (+0/-8)
.pc/librevenge.patch/configure.ac (+0/-1070)
.pc/librevenge.patch/src/extension/internal/wpg-input.cpp (+0/-145)
ChangeLog (+775/-10714)
Info.plist (+3/-3)
Info.plist.in (+1/-1)
Makefile.in (+183/-167)
NEWS (+9/-17)
aclocal.m4 (+406/-348)
build.xml (+1/-1)
compile (+68/-31)
config.guess (+106/-78)
config.h.in (+3/-3)
config.sub (+66/-48)
configure (+520/-358)
configure.ac (+28/-38)
debian/changelog (+55/-0)
debian/control (+3/-3)
debian/patches/0004-Fix_FTBFS_on_gcc-4.8.patch (+10/-139)
debian/patches/0005-Fix_FTBFS_due_to_tests.patch (+482/-0)
debian/patches/0005-Fix_FreeType_include.patch (+0/-23)
debian/patches/0006-Fix_FTBFS_on_poppler-0.26.patch (+0/-150)
debian/patches/0006-Update_to_new_libwpg.patch (+111/-0)
debian/patches/librevenge.patch (+0/-80)
debian/patches/series (+2/-3)
debian/rules (+2/-2)
depcomp (+296/-193)
doc/Makefile.in (+75/-37)
inkscape.1 (+51/-42)
inkscape.desktop.in (+1/-7)
inkscape.el.1 (+74/-65)
inkscape.fr.1 (+63/-54)
inkscape.ja.1 (+33/-24)
inkscape.sk.1 (+58/-49)
inkscape.spec (+1/-1)
inkscape.zh_TW.1 (+31/-22)
install-sh (+7/-7)
missing (+159/-275)
mkinstalldirs (+2/-2)
packaging/macosx/Resources/MenuBar.nib/classes.nib (+0/-4)
packaging/macosx/Resources/MenuBar.nib/info.nib (+0/-23)
packaging/macosx/Resources/MenuBar.nib/objects.xib (+0/-73)
packaging/macosx/Resources/ProgressWindow.nib/classes.nib (+0/-4)
packaging/macosx/Resources/ProgressWindow.nib/info.nib (+0/-18)
packaging/macosx/Resources/ProgressWindow.nib/objects.xib (+0/-53)
packaging/macosx/Resources/bin/getdisplay.sh (+0/-9)
packaging/macosx/Resources/bin/inkscape (+0/-158)
packaging/macosx/Resources/etc/fonts/fonts.conf (+0/-155)
packaging/macosx/Resources/openDoc (+0/-17)
packaging/macosx/Resources/script (+0/-54)
packaging/macosx/Resources/themes/Clearlooks-Quicksilver-OSX/gtk-2.0/Scrollbars_1/copy-slider.sh (+0/-7)
packaging/macosx/Resources/themes/Clearlooks-Quicksilver-OSX/gtk-2.0/Scrollbars_6/copy-slider.sh (+0/-7)
packaging/macosx/Resources/themes/Clearlooks-Quicksilver-OSX/gtk-2.0/pre_gtkrc (+0/-547)
packaging/macosx/ScriptExec/English.lproj/main.nib/classes.nib (+0/-4)
packaging/macosx/ScriptExec/English.lproj/main.nib/info.nib (+0/-19)
packaging/macosx/ScriptExec/English.lproj/main.nib/objects.xib (+0/-271)
packaging/macosx/ScriptExec/Info.plist (+0/-39)
packaging/macosx/ScriptExec/MenuBar.nib/classes.nib (+0/-4)
packaging/macosx/ScriptExec/MenuBar.nib/info.nib (+0/-23)
packaging/macosx/ScriptExec/MenuBar.nib/objects.xib (+0/-73)
packaging/macosx/ScriptExec/ScriptExec.xcode/project.pbxproj (+0/-451)
packaging/macosx/ScriptExec/ScriptExec.xcodeproj/project.pbxproj (+0/-351)
packaging/macosx/ScriptExec/ScriptExec_Prefix.pch (+0/-5)
packaging/macosx/ScriptExec/main.c (+0/-789)
packaging/macosx/ScriptExec/openDoc (+0/-4)
packaging/macosx/ScriptExec/script (+0/-4)
packaging/macosx/ScriptExec/version.plist (+0/-16)
packaging/macosx/osx-app.sh (+0/-499)
packaging/macosx/osx-build.sh (+0/-410)
packaging/macosx/osx-dmg.sh (+0/-178)
packaging/win32/AdvUninstLog.nsh (+0/-437)
packaging/win32/AdvUninstLog.txt (+0/-121)
packaging/win32/MessageBox.txt (+0/-186)
packaging/win32/RequireLatestNSIS.nsh (+0/-9)
packaging/win32/VersionCompleteXXXX.nsh (+0/-47)
packaging/win32/header.svg (+0/-516)
packaging/win32/ifexist.nsh (+0/-21)
packaging/win32/inkscape.nsi (+0/-1032)
packaging/win32/inkscape.nsi.uninstall (+0/-20)
packaging/win32/languages/Breton.nsh (+0/-113)
packaging/win32/languages/Catalan.nsh (+0/-113)
packaging/win32/languages/Czech.nsh (+0/-113)
packaging/win32/languages/Dutch.nsh (+0/-113)
packaging/win32/languages/English.nsh (+0/-113)
packaging/win32/languages/Finnish.nsh (+0/-113)
packaging/win32/languages/French.nsh (+0/-113)
packaging/win32/languages/Galician.nsh (+0/-113)
packaging/win32/languages/German.nsh (+0/-113)
packaging/win32/languages/Indonesian.nsh (+0/-113)
packaging/win32/languages/Italian.nsh (+0/-113)
packaging/win32/languages/Japanese.nsh (+0/-113)
packaging/win32/languages/Polish.nsh (+0/-113)
packaging/win32/languages/Romanian.nsh (+0/-113)
packaging/win32/languages/Russian.nsh (+0/-113)
packaging/win32/languages/SimpChinese.nsh (+0/-113)
packaging/win32/languages/Slovak.nsh (+0/-113)
packaging/win32/languages/Slovenian.nsh (+0/-113)
packaging/win32/languages/Spanish.nsh (+0/-113)
packaging/win32/languages/TradChinese.nsh (+0/-113)
packaging/win32/languages/Ukrainian.nsh (+0/-113)
packaging/win32/md5dll.txt (+0/-68)
packaging/win32/portable/App/AppInfo/appinfo.ini (+0/-26)
packaging/win32/portable/App/AppInfo/installer.ini (+0/-15)
packaging/win32/portable/App/readme.txt (+0/-1)
packaging/win32/portable/Other/Source/InkscapePortable.ini (+0/-6)
packaging/win32/portable/Other/Source/InkscapePortable.nsi (+0/-130)
packaging/win32/portable/Other/Source/License.txt (+0/-344)
packaging/win32/portable/Other/Source/PortableApps.comInstallerCustom.nsh (+0/-12)
packaging/win32/portable/Other/Source/PortableApps.comLauncherLANG_ENGLISH.nsh (+0/-6)
packaging/win32/portable/Other/Source/Readme.txt (+0/-67)
packaging/win32/portable/Other/Source/ReplaceInFileWithTextReplace.nsh (+0/-64)
packaging/win32/portable/help.html (+0/-178)
packaging/win32/portable/readme.packaging.txt (+0/-29)
packaging/win32/welcomefinish.svg (+0/-3510)
po/fi.po (+1866/-2720)
po/nl.po (+2/-2)
share/Makefile.in (+145/-126)
share/clipart/Makefile.am (+0/-1)
share/clipart/Makefile.in (+75/-38)
share/clipart/inkscape.logo.svg (+0/-9)
share/examples/Makefile.in (+75/-37)
share/examples/blend_modes.svg (+12/-12)
share/examples/lighting_filters.svg (+12/-12)
share/extensions/Barcode/Makefile.in (+75/-37)
share/extensions/Makefile.in (+147/-128)
share/extensions/Poly3DObjects/Makefile.in (+76/-39)
share/extensions/alphabet_soup/Makefile.in (+76/-39)
share/extensions/dxf_outlines.py (+6/-1)
share/extensions/inkex.py (+8/-2)
share/extensions/inkscape_help_reportabug.inx (+1/-1)
share/extensions/printing-marks.inx (+5/-5)
share/extensions/render_barcode_datamatrix.inx (+4/-34)
share/extensions/render_barcode_datamatrix.py (+3/-46)
share/extensions/scour.py (+6/-3)
share/extensions/simplestyle.py (+1/-1)
share/extensions/test/Makefile.in (+75/-37)
share/extensions/text_braille.py (+1/-1)
share/extensions/xaml2svg/Makefile.in (+76/-39)
share/extensions/yocto_css.py (+6/-3)
share/filters/Makefile.in (+76/-38)
share/fonts/Makefile.in (+76/-38)
share/gradients/Makefile.in (+76/-38)
share/icons/Makefile.in (+146/-127)
share/icons/application/16x16/Makefile.in (+76/-38)
share/icons/application/22x22/Makefile.in (+76/-38)
share/icons/application/24x24/Makefile.in (+76/-38)
share/icons/application/256x256/Makefile.in (+76/-38)
share/icons/application/32x32/Makefile.in (+76/-38)
share/icons/application/48x48/Makefile.in (+76/-38)
share/icons/application/Makefile.in (+147/-128)
share/icons/inkscape.file.svg (+14/-16)
share/icons/inkscape.svg (+14/-16)
share/keys/Makefile.in (+76/-38)
share/keys/right-handed-illustration.xml (+0/-1)
share/keys/xara.xml (+0/-1)
share/markers/Makefile.in (+76/-38)
share/palettes/Makefile.in (+76/-38)
share/palettes/Tango-Palette.gpl (+2/-0)
share/patterns/Makefile.in (+76/-38)
share/screens/Makefile.in (+76/-38)
share/templates/Makefile.in (+75/-37)
share/tutorials/Makefile.in (+75/-37)
share/ui/Makefile.in (+76/-38)
src/2geom/basic-intersection.cpp (+11/-1)
src/2geom/interval.h (+1/-1)
src/2geom/rect.h (+1/-1)
src/2geom/sbasis.h (+24/-6)
src/2geom/solve-bezier-parametric.cpp (+22/-5)
src/Makefile.am (+1/-5)
src/Makefile.in (+574/-817)
src/box3d-context.cpp (+1/-1)
src/color-profile.cpp (+8/-10)
src/cxxtests.cpp (+62/-62)
src/dialogs/export.cpp (+1/-1)
src/dialogs/spellcheck.cpp (+1/-1)
src/display/canvas-grid.cpp (+5/-0)
src/display/nr-filter-gaussian.cpp (+2/-2)
src/display/sodipodi-ctrl.cpp (+7/-2)
src/display/sp-canvas.cpp (+9/-7)
src/dom/io/uristream.cpp (+24/-25)
src/dom/io/uristream.h (+38/-38)
src/dom/svgimpl.cpp (+3/-3)
src/dropper-context.cpp (+1/-1)
src/extension/effect.cpp (+1/-1)
src/extension/implementation/script.cpp (+1/-8)
src/extension/init.cpp (+1/-1)
src/extension/internal/cairo-renderer.cpp (+1/-1)
src/extension/internal/filter/filter-file.cpp (+1/-1)
src/extension/internal/filter/filter.cpp (+1/-1)
src/extension/internal/pdfinput/svg-builder.cpp (+13/-13)
src/extension/internal/wpg-input.cpp (+17/-10)
src/extension/system.cpp (+2/-1)
src/file.cpp (+1/-1)
src/gc-core.h (+1/-1)
src/gc.cpp (+13/-5)
src/gradient-drag.cpp (+1/-1)
src/helper/pixbuf-ops.cpp (+1/-1)
src/helper/sp-marshal.cpp (+7/-7)
src/helper/sp-marshal.h (+6/-6)
src/inkscape-version.cpp (+1/-1)
src/inkscape.rc (+5/-5)
src/inkview.rc (+5/-5)
src/interface.cpp (+11/-9)
src/io/inkjar.cpp (+17/-9)
src/io/inkjar.h (+4/-2)
src/io/inkscapestream.h (+1/-0)
src/io/uristream.cpp (+29/-31)
src/io/uristream.h (+40/-40)
src/io/xsltstream.cpp (+8/-11)
src/io/xsltstream.h (+19/-21)
src/libavoid/vpsc.cpp (+1/-1)
src/libcola/straightener.cpp (+3/-3)
src/libcroco/cr-parser.c (+1/-1)
src/libcroco/cr-rgb.c (+2/-2)
src/libgdl/gdl-dock-object.c (+1/-1)
src/libgdl/gdl-dock-object.h (+2/-2)
src/libgdl/gdl-tools.h (+1/-1)
src/libnrtype/FontFactory.cpp (+1/-1)
src/libnrtype/Layout-TNG-OutIter.cpp (+26/-5)
src/libvpsc/Makefile_insert (+0/-2)
src/libvpsc/block.cpp (+1/-1)
src/libvpsc/csolve_VPSC.cpp (+0/-126)
src/libvpsc/csolve_VPSC.h (+0/-60)
src/live_effects/lpe-bendpath.cpp (+6/-3)
src/live_effects/lpe-perp_bisector.h (+2/-2)
src/main.cpp (+3/-0)
src/pencil-context.cpp (+16/-9)
src/preferences.cpp (+3/-0)
src/prefix.cpp (+0/-3)
src/registrytool.cpp (+1/-1)
src/remove-last.h (+3/-2)
src/select-context.cpp (+2/-2)
src/selection-chemistry.cpp (+1/-1)
src/selection.cpp (+2/-0)
src/seltrans.cpp (+1/-1)
src/sp-conn-end.cpp (+1/-1)
src/sp-flowregion.cpp (+2/-2)
src/sp-guide.cpp (+4/-4)
src/sp-image.cpp (+4/-6)
src/sp-item-group.cpp (+2/-0)
src/sp-item-rm-unsatisfied-cns.cpp (+2/-2)
src/sp-namedview.cpp (+4/-4)
src/sp-polygon.cpp (+7/-4)
src/splivarot.cpp (+15/-5)
src/spray-context.cpp (+22/-32)
src/trace/imagemap-gdk.cpp (+8/-6)
src/trace/imagemap-gdk.h (+2/-2)
src/trace/siox.cpp (+3/-12)
src/trace/siox.h (+1/-11)
src/trace/trace.cpp (+2/-2)
src/tweak-context.cpp (+1/-1)
src/ui/dialog/filedialogimpl-gtkmm.cpp (+10/-5)
src/ui/dialog/filedialogimpl-win32.cpp (+10/-12)
src/ui/dialog/filedialogimpl-win32.h (+12/-0)
src/ui/dialog/inkscape-preferences.cpp (+5/-2)
src/ui/dialog/layers.cpp (+4/-3)
src/ui/dialog/print.cpp (+4/-3)
src/ui/tool/multi-path-manipulator.cpp (+13/-3)
src/ui/tool/node-tool.cpp (+4/-0)
src/ui/tool/node.h (+8/-0)
src/ui/tool/path-manipulator.cpp (+5/-1)
src/ui/tool/transform-handle-set.cpp (+1/-1)
src/ui/widget/registered-widget.h (+0/-3)
src/verbs.cpp (+5/-0)
src/widgets/desktop-widget.cpp (+12/-14)
src/widgets/eek-preview.cpp (+1/-1)
src/widgets/ege-paint-def.cpp (+1/-1)
src/widgets/sp-color-icc-selector.cpp (+3/-3)
src/widgets/toolbox.cpp (+1/-1)
src/xml/repr-io.cpp (+75/-15)
src/xml/repr-util.cpp (+3/-3)
test-driver (+139/-0)
To merge this branch: bzr merge lp:~valavanisalex/ubuntu/utopic/inkscape/fix-1358863
Reviewer Review Type Date Requested Status
Daniel Holbach 2014-08-19 Approve on 2014-08-22
Review via email: mp+231439@code.launchpad.net

Description of the change

Merge upstream bugfix version 0.48.5 from Debian Unstable/Testing

To post a comment you must log in.
Daniel Holbach (dholbach) wrote :

Thanks. Uploaded.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== removed directory '.pc/0001-Fix_Datamatrix_UI_issue.patch'
2=== removed directory '.pc/0001-Fix_Datamatrix_UI_issue.patch/share'
3=== removed directory '.pc/0001-Fix_Datamatrix_UI_issue.patch/share/extensions'
4=== removed file '.pc/0001-Fix_Datamatrix_UI_issue.patch/share/extensions/render_barcode_datamatrix.inx'
5--- .pc/0001-Fix_Datamatrix_UI_issue.patch/share/extensions/render_barcode_datamatrix.inx 2013-07-02 17:25:52 +0000
6+++ .pc/0001-Fix_Datamatrix_UI_issue.patch/share/extensions/render_barcode_datamatrix.inx 1970-01-01 00:00:00 +0000
7@@ -1,20 +0,0 @@
8-<?xml version="1.0" encoding="UTF-8"?>
9-<inkscape-extension xmlns="http://www.inkscape.org/namespace/inkscape/extension">
10- <_name>Barcode - Datamatrix</_name>
11- <id>il.datamatrix</id>
12- <dependency type="executable" location="extensions">render_barcode_datamatrix.py</dependency>
13- <dependency type="executable" location="extensions">inkex.py</dependency>
14- <param name="text" type="string" _gui-text="Text">Inkscape</param>
15- <param name="rows" type="int" min="8" max="144" _gui-text="Rows">10</param>
16- <param name="cols" type="int" min="10" max="144" _gui-text="Cols">10</param>
17- <param name="size" type="int" min="1" max="1000" _gui-text="Square Size / px">4</param>
18- <effect>
19- <object-type>all</object-type>
20- <effects-menu>
21- <submenu _name="Render"/>
22- </effects-menu>
23- </effect>
24- <script>
25- <command reldir="extensions" interpreter="python">render_barcode_datamatrix.py</command>
26- </script>
27-</inkscape-extension>
28
29=== removed file '.pc/0001-Fix_Datamatrix_UI_issue.patch/share/extensions/render_barcode_datamatrix.py'
30--- .pc/0001-Fix_Datamatrix_UI_issue.patch/share/extensions/render_barcode_datamatrix.py 2013-07-02 17:25:52 +0000
31+++ .pc/0001-Fix_Datamatrix_UI_issue.patch/share/extensions/render_barcode_datamatrix.py 1970-01-01 00:00:00 +0000
32@@ -1,654 +0,0 @@
33-#!/usr/bin/env python
34-# -*- coding: UTF-8 -*-
35-'''
36-Copyright (C) 2009 John Beard john.j.beard@gmail.com
37-
38-######DESCRIPTION######
39-
40-This extension renders a DataMatrix 2D barcode, as specified in
41-BS ISO/IEC 16022:2006. Only ECC200 codes are considered, as these are the only
42-ones recommended for an "open" system.
43-
44-The size of the DataMatrix is variable between 10x10 to 144x144
45-
46-The absolute size of the DataMatrix modules (the little squares) is also
47-variable.
48-
49-If more data is given than can be contained in one DataMatrix,
50-more than one DataMatrices will be produced.
51-
52-Text is encoded as ASCII (the standard provides for other options, but these are
53-not implemented). Consecutive digits are encoded in a compressed form, halving
54-the space required to store them.
55-
56-The basis processing flow is;
57- * Convert input string to codewords (modified ASCII and compressed digits)
58- * Split codewords into blocks of the right size for Reed-Solomon coding
59- * Interleave the blocks if required
60- * Apply Reed-Solomon coding
61- * De-interleave the blocks if required
62- * Place the codewords into the matrix bit by bit
63- * Render the modules in the matrix as squares
64-
65-######LICENCE#######
66-This program is free software; you can redistribute it and/or modify
67-it under the terms of the GNU General Public License as published by
68-the Free Software Foundation; either version 2 of the License, or
69-(at your option) any later version.
70-
71-This program is distributed in the hope that it will be useful,
72-but WITHOUT ANY WARRANTY; without even the implied warranty of
73-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
74-GNU General Public License for more details.
75-
76-You should have received a copy of the GNU General Public License
77-along with this program; if not, write to the Free Software
78-Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
79-
80-######VERSION HISTORY#####
81- Ver. Date Notes
82-
83- 0.50 2009-10-25 Full functionality, up to 144x144.
84- ASCII and compressed digit encoding only.
85-'''
86-
87-import inkex, simplestyle
88-
89-import gettext
90-_ = gettext.gettext
91-
92-#ENCODING ROUTINES ===================================================
93-# Take an input string and convert it to a sequence (or sequences)
94-# of codewords as specified in ISO/IEC 16022:2006 (section 5.2.3)
95-#=====================================================================
96-
97-#create a 2d list corresponding to the 1's and 0s of the DataMatrix
98-def encode(text, (nrow, ncol) ):
99- #retreive the parameters of this size of DataMatrix
100- data_nrow, data_ncol, reg_row, reg_col, nd, nc, inter = get_parameters( nrow, ncol )
101-
102- if not ((nrow == 144) and (ncol == 144)): #we have a regular datamatrix
103- size144 = False
104- else: #special handling will be required by get_codewords()
105- size144 = True
106-
107- #generate the codewords including padding and ECC
108- codewords = get_codewords( text, nd, nc, inter, size144 )
109-
110- # break up into separate arrays if more than one DataMatrix is needed
111- module_arrays = []
112- for codeword_stream in codewords: #for each datamatrix
113- bit_array = place_bits(codeword_stream, (data_nrow*reg_row, data_ncol*reg_col)) #place the codewords' bits across the array as modules
114- module_arrays.append(add_finder_pattern( bit_array, data_nrow, data_ncol, reg_row, reg_col )) #add finder patterns around the modules
115-
116- return module_arrays
117-
118-#return parameters for the selected datamatrix size
119-# data_nrow number of rows in each data region
120-# data_ncol number of cols in each data region
121-# reg_row number of rows of data regions
122-# reg_col number of cols of data regions
123-# nd number of data codewords per reed-solomon block
124-# nc number of ECC codewords per reed-solomon block
125-# inter number of interleaved Reed-Solomon blocks
126-def get_parameters(nrow, ncol):
127-
128- #SQUARE SYMBOLS
129- if ( nrow == 10 and ncol == 10 ):
130- return 8, 8, 1, 1, 3, 5, 1
131- elif ( nrow == 12 and ncol == 12 ):
132- return 10, 10, 1, 1, 5, 7, 1
133- elif ( nrow == 14 and ncol == 14 ):
134- return 12, 12, 1, 1, 8, 10, 1
135- elif ( nrow == 16 and ncol == 16 ):
136- return 14, 14, 1, 1, 12, 12, 1
137- elif ( nrow == 18 and ncol == 18 ):
138- return 16, 16, 1, 1, 18, 14, 1
139- elif ( nrow == 20 and ncol == 20 ):
140- return 18, 18, 1, 1, 22, 18, 1
141- elif ( nrow == 22 and ncol == 22 ):
142- return 18, 18, 1, 1, 30, 20, 1
143- elif ( nrow == 24 and ncol == 24 ):
144- return 22, 22, 1, 1, 36, 24, 1
145- elif ( nrow == 26 and ncol == 26 ):
146- return 24, 24, 1, 1, 44, 28, 1
147- elif ( nrow == 32 and ncol == 32 ):
148- return 14, 14, 2, 2, 62, 36, 1
149- elif ( nrow == 36 and ncol == 36 ):
150- return 16, 16, 2, 2, 86, 42, 1
151- elif ( nrow == 40 and ncol == 40):
152- return 18, 18, 2, 2, 114, 48, 1
153- elif ( nrow == 44 and ncol == 44):
154- return 20, 20, 2, 2, 144, 56, 1
155- elif ( nrow == 48 and ncol == 48 ):
156- return 22, 22, 2, 2, 174, 68, 1
157-
158- elif ( nrow == 52 and ncol == 52 ):
159- return 24, 24, 2, 2, 102, 42, 2
160- elif ( nrow == 64 and ncol == 64 ):
161- return 16, 16, 4, 4, 140, 56, 2
162-
163- elif ( nrow == 72 and ncol == 72 ):
164- return 16, 16, 4, 4, 92, 36, 4
165- elif ( nrow == 80 and ncol == 80 ):
166- return 18, 18, 4, 4, 114, 48, 4
167- elif ( nrow == 88 and ncol == 88 ):
168- return 20, 20, 4, 4, 144, 56, 4
169- elif ( nrow == 96 and ncol == 96 ):
170- return 22, 22, 4, 4, 174, 68, 4
171-
172- elif ( nrow == 104 and ncol == 104 ):
173- return 24, 24, 4, 4, 136, 56, 6
174- elif ( nrow == 120 and ncol == 120):
175- return 18, 18, 6, 6, 175, 68, 6
176-
177- elif ( nrow == 132 and ncol == 132):
178- return 20, 20, 6, 6, 163, 62, 8
179-
180- elif (nrow == 144 and ncol == 144):
181- return 22, 22, 6, 6, 0, 0, 0 #there are two separate sections of the data matrix with
182- #different interleaving and reed-solomon parameters.
183- #this will be handled separately
184-
185- #RECTANGULAR SYMBOLS
186- elif ( nrow == 8 and ncol == 18 ):
187- return 6, 16, 1, 1, 5, 7, 1
188- elif ( nrow == 8 and ncol == 32 ):
189- return 6, 14, 1, 2, 10, 11, 1
190- elif ( nrow == 12 and ncol == 26 ):
191- return 10, 24, 1, 1, 16, 14, 1
192- elif ( nrow == 12 and ncol == 36 ):
193- return 10, 16, 1, 2, 22, 18, 1
194- elif ( nrow == 16 and ncol == 36 ):
195- return 14, 16, 1, 2, 32, 24, 1
196- elif ( nrow == 16 and ncol == 48 ):
197- return 14, 22, 1, 2, 49, 28, 1
198-
199- #RETURN ERROR
200- else:
201- inkex.errormsg(_('Unrecognised DataMatrix size'))
202-
203- return None
204-
205-# CODEWORD STREAM GENERATION =========================================
206-#take the text input and return the codewords,
207-#including the Reed-Solomon error-correcting codes.
208-#=====================================================================
209-
210-def get_codewords( text, nd, nc, inter, size144 ):
211- #convert the data to the codewords
212- data = encode_to_ascii( text )
213-
214- if not size144: #render a "normal" datamatrix
215- data_blocks = partition_data(data, nd*inter) #partition into data blocks of length nd*inter -> inter Reed-Solomon block
216-
217- data_blocks = interleave( data_blocks, inter) # interleave consecutive inter blocks if required
218-
219- data_blocks = reed_solomon(data_blocks, nd, nc) #generate and append the Reed-Solomon codewords
220-
221- data_blocks = combine_interleaved(data_blocks, inter, nd, nc, False) #concatenate Reed-Solomon blocks bound for the same datamatrix
222-
223- else: #we have a 144x144 datamatrix
224- data_blocks = partition_data(data, 1558) #partition the data into datamtrix-sized chunks (1558 =156*8 + 155*2 )
225-
226- for i in range(len(data_blocks)): #for each datamtrix
227-
228-
229- inter = 8
230- nd = 156
231- nc = 62
232- block1 = data_blocks[i][0:156*8]
233- block1 = interleave( [block1], inter) # interleave into 8 blocks
234- block1 = reed_solomon(block1, nd, nc) #generate and append the Reed-Solomon codewords
235-
236- inter = 2
237- nd = 155
238- nc = 62
239- block2 = data_blocks[i][156*8:]
240- block2 = interleave( [block2], inter) # interleave into 2 blocks
241- block2 = reed_solomon(block2, nd, nc) #generate and append the Reed-Solomon codewords
242-
243- blocks = block1
244- blocks.extend(block2)
245-
246- blocks = combine_interleaved(blocks, 10, nd, nc, True)
247-
248- data_blocks[i] = blocks[0]
249-
250-
251- return data_blocks
252-
253-
254-#Takes a codeword stream and splits up into "inter" blocks.
255-#eg interleave( [1,2,3,4,5,6], 2 ) -> [1,3,5], [2,4,6]
256-def interleave( blocks, inter):
257-
258- if inter == 1: # if we don't have to interleave, just return the blocks
259- return blocks
260- else:
261- result = []
262- for block in blocks: #for each codeword block in the stream
263- block_length = len(block)/inter #length of each interleaved block
264- inter_blocks = [[0] * block_length for i in xrange(inter)] #the interleaved blocks
265-
266- for i in range(block_length): #for each element in the interleaved blocks
267- for j in range(inter): #for each interleaved block
268- inter_blocks[j][i] = block[ i*inter + j ]
269-
270- result.extend(inter_blocks) #add the interleaved blocks to the output
271-
272- return result
273-
274-#Combine interleaved blocks into the groups for the same datamatrix
275-#
276-#e.g combine_interleaved( [[d1, d3, d5, e1, e3, e5], [d2, d4, d6, e2, e4, e6]], 2, 3, 3 )
277-# --> [[d1, d2, d3, d4, d5, d6, e1, e2, e3, e4, e5, e6]]
278-def combine_interleaved( blocks, inter, nd, nc, size144):
279- if inter == 1: #the blocks aren't interleaved
280- return blocks
281- else:
282- result = []
283- for i in range( len(blocks) / inter ): #for each group of "inter" blocks -> one full datamatrix
284- data_codewords = [] #interleaved data blocks
285-
286- if size144:
287- nd_range = 1558 #1558 = 156*8 + 155*2
288- nc_range = 620 #620 = 62*8 + 62*2
289- else:
290- nd_range = nd*inter
291- nc_range = nc*inter
292-
293- for j in range(nd_range): #for each codeword in the final list
294- data_codewords.append( blocks[i*inter + j%inter][j/inter] )
295-
296- for j in range(nc_range): #for each block, add the ecc codewords
297- data_codewords.append( blocks[i*inter + j%inter][nd + j/inter] )
298-
299- result.append(data_codewords)
300- return result
301-
302-#checks if an ASCII character is a digit from 0 - 9
303-def is_digit( char ):
304-
305- if ord(char) >= 48 and ord(char) <= 57:
306- return True
307- else:
308- return False
309-
310-def encode_to_ascii( text):
311-
312- ascii = []
313- i = 0
314- while i < len(text):
315- #check for double digits
316- if is_digit( text[i] ) and ( i < len(text)-1) and is_digit( text[i+1] ): #if the next char is also a digit
317-
318- codeword = int( text[i] + text[i+1] ) + 130
319- ascii.append( codeword )
320- i = i + 2 #move on 2 characters
321- else: #encode as a normal ascii,
322- ascii.append( ord(text[i] ) + 1 ) #codeword is ASCII value + 1 (ISO 16022:2006 5.2.3)
323- i = i + 1 #next character
324-
325- return ascii
326-
327-
328-#partition data into blocks of the appropriate size to suit the
329-#Reed-Solomon block being used.
330-#e.g. partition_data([1,2,3,4,5], 3) -> [[1,2,3],[4,5,PAD]]
331-def partition_data( data , rs_data):
332-
333- PAD_VAL = 129 # PAD codeword (ISO 16022:2006 5.2.3)
334- data_blocks = []
335- i = 0
336- while i < len(data):
337- if len(data) >= i+rs_data: #we have a whole block in our data
338- data_blocks.append( data[i:i+rs_data] )
339- i = i + rs_data
340- else: #pad out with the pad codeword
341- data_block = data[i:len(data)] #add any remaining data
342- pad_pos = len(data)
343- padded = False
344- while len(data_block) < rs_data:#and then pad with randomised pad codewords
345- if not padded:
346- data_block.append( PAD_VAL ) #add a normal pad codeword
347- padded = True
348- else:
349- data_block.append( randomise_pad_253( PAD_VAL, pad_pos) )
350- pad_pos = pad_pos + 1
351- data_blocks.append( data_block)
352- break
353-
354- return data_blocks
355-
356-#Pad character randomisation, to prevent regular patterns appearing
357-#in the data matrix
358-def randomise_pad_253(pad_value, pad_position ):
359- pseudo_random_number = ( ( 149 * pad_position ) % 253 )+ 1
360- randomised = pad_value + pseudo_random_number
361- if ( randomised <= 254 ):
362- return randomised
363- else:
364- return randomised - 254
365-
366-# REED-SOLOMON ENCODING ROUTINES =====================================
367-
368-# "prod(x,y,log,alog,gf)" returns the product "x" times "y"
369-def prod(x, y, log, alog, gf):
370-
371- if ( x==0 or y==0):
372- return 0
373- else:
374- result = alog[ ( log[x] + log[y] ) % (gf - 1) ]
375- return result
376-
377-# generate the log & antilog lists:
378-def gen_log_alog(gf, pp):
379- log = [0]*gf
380- alog = [0]*gf
381-
382- log[0] = 1-gf
383- alog[0] = 1
384-
385- for i in range(1,gf):
386- alog[i] = alog[i-1] * 2
387-
388- if (alog[i] >= gf):
389- alog[i] = alog[i] ^ pp
390-
391- log[alog[i]] = i
392-
393- return log, alog
394-
395-# generate the generator polynomial coefficients:
396-def gen_poly_coeffs(nc, log, alog, gf):
397- c = [0] * (nc+1)
398- c[0] = 1
399-
400- for i in range(1,nc+1):
401- c[i] = c[i-1]
402-
403- j = i-1
404- while j >= 1:
405- c[j] = c[j-1] ^ prod(c[j],alog[i],log,alog,gf)
406- j = j - 1
407-
408- c[0] = prod(c[0],alog[i],log,alog,gf)
409-
410- return c
411-
412-# "ReedSolomon(wd,nd,nc)" takes "nd" data codeword values in wd[]
413-# and adds on "nc" check codewords, all within GF(gf) where "gf" is a
414-# power of 2 and "pp" is the value of its prime modulus polynomial */
415-def reed_solomon(data, nd, nc):
416- #parameters of the polynomial arithmetic
417- gf = 256 #operating on 8-bit codewords -> Galois field = 2^8 = 256
418- pp = 301 #prime modulus polynomial for ECC-200 is 0b100101101 = 301 (ISO 16022:2006 5.7.1)
419-
420- log, alog = gen_log_alog(gf,pp)
421- c = gen_poly_coeffs(nc, log, alog, gf)
422-
423- for block in data: #for each block of data codewords
424-
425- block.extend( [0]*(nc+1) ) #extend to make space for the error codewords
426-
427- #generate "nc" checkwords in the list block
428- for i in range(0, nd):
429- k = block[nd] ^ block[i]
430-
431- for j in range(0,nc):
432- block[nd+j] = block[nd+j+1] ^ prod(k,c[nc-j-1],log, alog,gf)
433-
434- block.pop()
435-
436- return data
437-
438-#MODULE PLACEMENT ROUTINES===========================================
439-# These routines take a steam of codewords, and place them into the
440-# DataMatrix in accordance with Annex F of BS ISO/IEC 16022:2006
441-
442-# bit() returns the bit'th bit of the byte
443-def bit(byte, bit):
444- #the MSB is bit 1, LSB is bit 8
445- return ( byte >> (8-bit) ) %2
446-
447-# "module" places a given bit with appropriate wrapping within array
448-def module(array, nrow, ncol, row, col, bit) :
449- if (row < 0) :
450- row = row + nrow
451- col = col + 4 - ((nrow+4)%8)
452-
453- if (col < 0):
454- col = col + ncol
455- row = row + 4 - ((ncol+4)%8)
456-
457- array[row][col] = bit
458-
459-def corner1(array, nrow, ncol, char):
460- module(array, nrow, ncol, nrow-1, 0, bit(char,1));
461- module(array, nrow, ncol, nrow-1, 1, bit(char,2));
462- module(array, nrow, ncol, nrow-1, 2, bit(char,3));
463- module(array, nrow, ncol, 0, ncol-2, bit(char,4));
464- module(array, nrow, ncol, 0, ncol-1, bit(char,5));
465- module(array, nrow, ncol, 1, ncol-1, bit(char,6));
466- module(array, nrow, ncol, 2, ncol-1, bit(char,7));
467- module(array, nrow, ncol, 3, ncol-1, bit(char,8));
468-
469-def corner2(array, nrow, ncol, char):
470- module(array, nrow, ncol, nrow-3, 0, bit(char,1));
471- module(array, nrow, ncol, nrow-2, 0, bit(char,2));
472- module(array, nrow, ncol, nrow-1, 0, bit(char,3));
473- module(array, nrow, ncol, 0, ncol-4, bit(char,4));
474- module(array, nrow, ncol, 0, ncol-3, bit(char,5));
475- module(array, nrow, ncol, 0, ncol-2, bit(char,6));
476- module(array, nrow, ncol, 0, ncol-1, bit(char,7));
477- module(array, nrow, ncol, 1, ncol-1, bit(char,8));
478-
479-def corner3(array, nrow, ncol, char):
480- module(array, nrow, ncol, nrow-3, 0, bit(char,1));
481- module(array, nrow, ncol, nrow-2, 0, bit(char,2));
482- module(array, nrow, ncol, nrow-1, 0, bit(char,3));
483- module(array, nrow, ncol, 0, ncol-2, bit(char,4));
484- module(array, nrow, ncol, 0, ncol-1, bit(char,5));
485- module(array, nrow, ncol, 1, ncol-1, bit(char,6));
486- module(array, nrow, ncol, 2, ncol-1, bit(char,7));
487- module(array, nrow, ncol, 3, ncol-1, bit(char,8));
488-
489-def corner4(array, nrow, ncol, char):
490- module(array, nrow, ncol, nrow-1, 0, bit(char,1));
491- module(array, nrow, ncol, nrow-1, ncol-1, bit(char,2));
492- module(array, nrow, ncol, 0, ncol-3, bit(char,3));
493- module(array, nrow, ncol, 0, ncol-2, bit(char,4));
494- module(array, nrow, ncol, 0, ncol-1, bit(char,5));
495- module(array, nrow, ncol, 1, ncol-3, bit(char,6));
496- module(array, nrow, ncol, 1, ncol-2, bit(char,7));
497- module(array, nrow, ncol, 1, ncol-1, bit(char,8));
498-
499-#"utah" places the 8 bits of a utah-shaped symbol character in ECC200
500-def utah(array, nrow, ncol, row, col, char):
501- module(array, nrow, ncol,row-2, col-2, bit(char,1))
502- module(array, nrow, ncol,row-2, col-1, bit(char,2))
503- module(array, nrow, ncol,row-1, col-2, bit(char,3))
504- module(array, nrow, ncol,row-1, col-1, bit(char,4))
505- module(array, nrow, ncol,row-1, col, bit(char,5))
506- module(array, nrow, ncol,row, col-2, bit(char,6))
507- module(array, nrow, ncol,row, col-1, bit(char,7))
508- module(array, nrow, ncol,row, col, bit(char,8))
509-
510-#"place_bits" fills an nrow x ncol array with the bits from the
511-# codewords in data.
512-def place_bits(data, (nrow, ncol)):
513-# First, fill the array[] with invalid entries */
514- INVALID = 2
515- array = [[INVALID] * ncol for i in xrange(nrow)] #initialise and fill with -1's (invalid value)
516-# Starting in the correct location for character #1, bit 8,...
517- char = 0
518- row = 4
519- col = 0
520- while True:
521-
522- #first check for one of the special corner cases, then...
523- if ((row == nrow) and (col == 0)):
524- corner1(array, nrow, ncol, data[char])
525- char = char + 1
526- if ((row == nrow-2) and (col == 0) and (ncol%4)) :
527- corner2(array, nrow, ncol, data[char])
528- char = char + 1
529- if ((row == nrow-2) and (col == 0) and (ncol%8 == 4)):
530- corner3(array, nrow, ncol, data[char])
531- char = char + 1
532- if ((row == nrow+4) and (col == 2) and ((ncol%8) == 0)):
533- corner4(array, nrow, ncol, data[char])
534- char = char + 1
535-
536- #sweep upward diagonally, inserting successive characters,...
537- while True:
538- if ((row < nrow) and (col >= 0) and (array[row][col] == INVALID)) :
539- utah(array, nrow, ncol,row,col,data[char])
540- char = char+1
541- row = row - 2
542- col = col + 2
543-
544- if not((row >= 0) and (col < ncol)):
545- break
546-
547- row = row + 1
548- col = col + 3
549-
550- # & then sweep downward diagonally, inserting successive characters,...
551- while True:
552- if ((row >= 0) and (col < ncol) and (array[row][col] == INVALID)) :
553- utah(array, nrow, ncol,row,col,data[char])
554- char = char + 1
555- row = row + 2
556- col = col - 2
557-
558- if not((row < nrow) and (col >= 0)):
559- break
560-
561- row = row + 3
562- col = col + 1
563-
564- #... until the entire array is scanned
565- if not((row < nrow) or (col < ncol)):
566- break
567-
568- # Lastly, if the lower righthand corner is untouched, fill in fixed pattern */
569- if (array[nrow-1][ncol-1] == INVALID):
570- array[nrow-1][ncol-2] = 0
571- array[nrow-1][ncol-1] = 1
572- array[nrow-2][ncol-1] = 0
573- array[nrow-2][ncol-2] = 1
574-
575- return array #return the array of 1's and 0's
576-
577-
578-def add_finder_pattern( array, data_nrow, data_ncol, reg_row, reg_col ):
579-
580- #get the total size of the datamatrix
581- nrow = (data_nrow+2) * reg_row
582- ncol = (data_ncol+2) * reg_col
583-
584- datamatrix = [[0] * ncol for i in xrange(nrow)] #initialise and fill with 0's
585-
586- for i in range( reg_col ): #for each column of data regions
587- for j in range(nrow):
588- datamatrix[j][i*(data_ncol+2)] = 1 #vertical black bar on left
589- datamatrix[j][i*(data_ncol+2)+data_ncol+1] = (j)%2 # alternating blocks
590-
591- for i in range( reg_row): # for each row of data regions
592- for j in range(ncol):
593- datamatrix[i*(data_nrow+2)+data_nrow+1][j] = 1 #horizontal black bar at bottom
594- datamatrix[i*(data_nrow+2)][j] = (j+1)%2 # alternating blocks
595-
596- for i in range( data_nrow*reg_row ):
597- for j in range( data_ncol* reg_col ):
598- dest_col = j + 1 + 2*(j/(data_ncol)) #offset by 1, plus two for every addition block
599- dest_row = i + 1 + 2*(i/(data_nrow))
600-
601- datamatrix[dest_row][dest_col] = array[i][j] #transfer from the plain bit array
602-
603- return datamatrix
604-
605-#RENDERING ROUTINES ==================================================
606-# Take the array of 1's and 0's and render as a series of black
607-# squares. A binary 1 is a filled square
608-#=====================================================================
609-
610-#SVG element generation routine
611-def draw_SVG_square((w,h), (x,y), parent):
612-
613- style = { 'stroke' : 'none',
614- 'stroke-width' : '1',
615- 'fill' : '#000000'
616- }
617-
618- attribs = {
619- 'style' :simplestyle.formatStyle(style),
620- 'height' : str(h),
621- 'width' : str(w),
622- 'x' : str(x),
623- 'y' : str(y)
624- }
625- circ = inkex.etree.SubElement(parent, inkex.addNS('rect','svg'), attribs )
626-
627-#turn a 2D array of 1's and 0's into a set of black squares
628-def render_data_matrix( module_arrays, size, spacing, parent):
629-
630- for i in range(len(module_arrays)): #for each data matrix
631-
632- height = len(module_arrays[i])
633- width = len(module_arrays[i][0] )
634-
635- for y in range(height): #loop over all the modules in the datamatrix
636- for x in range(width):
637-
638- if module_arrays[i][y][x] == 1: #A binary 1 is a filled square
639- draw_SVG_square((size,size), (x*size + i*spacing,y*size), parent)
640- elif module_arrays[i][y][x] != 0: #we have an invalid bit value
641- inkex.errormsg(_('Invalid bit value, this is a bug!'))
642-
643-class DataMatrix(inkex.Effect):
644- def __init__(self):
645- inkex.Effect.__init__(self)
646-
647- #PARSE OPTIONS
648- self.OptionParser.add_option("--text",
649- action="store", type="string",
650- dest="TEXT", default='Inkscape')
651- self.OptionParser.add_option("--rows",
652- action="store", type="int",
653- dest="ROWS", default=10)
654- self.OptionParser.add_option("--cols",
655- action="store", type="int",
656- dest="COLS", default=10)
657- self.OptionParser.add_option("--size",
658- action="store", type="int",
659- dest="SIZE", default=4)
660-
661- def effect(self):
662-
663- so = self.options
664-
665- if so.TEXT == '': #abort if converting blank text
666- inkex.errormsg(_('Please enter an input string'))
667- else:
668-
669- #INKSCAPE GROUP TO CONTAIN EVERYTHING
670-
671- centre = self.view_center #Put in in the centre of the current view
672- grp_transform = 'translate' + str( centre )
673- grp_name = 'DataMatrix'
674- grp_attribs = {inkex.addNS('label','inkscape'):grp_name,
675- 'transform':grp_transform }
676- grp = inkex.etree.SubElement(self.current_layer, 'g', grp_attribs)#the group to put everything in
677-
678- #GENERATE THE DATAMATRIX
679- encoded = encode( so.TEXT, (so.ROWS, so.COLS) ) #get the pattern of squares
680- render_data_matrix( encoded, so.SIZE, so.COLS*so.SIZE*1.5, grp ) # generate the SVG elements
681-
682-if __name__ == '__main__':
683- e = DataMatrix()
684- e.affect()
685-
686-# vim: expandtab shiftwidth=4 tabstop=8 softtabstop=4 encoding=utf-8 textwidth=99
687
688=== removed directory '.pc/0002-Drop_PS_and_PDF_support_in_MimeType.patch'
689=== removed file '.pc/0002-Drop_PS_and_PDF_support_in_MimeType.patch/inkscape.desktop.in'
690--- .pc/0002-Drop_PS_and_PDF_support_in_MimeType.patch/inkscape.desktop.in 2013-07-02 17:25:52 +0000
691+++ .pc/0002-Drop_PS_and_PDF_support_in_MimeType.patch/inkscape.desktop.in 1970-01-01 00:00:00 +0000
692@@ -1,14 +0,0 @@
693-[Desktop Entry]
694-Version=1.0
695-_Name=Inkscape
696-_GenericName=Vector Graphics Editor
697-_X-GNOME-FullName=Inkscape Vector Graphics Editor
698-_Comment=Create and edit Scalable Vector Graphics images
699-Type=Application
700-Categories=Graphics;VectorGraphics;GTK;
701-MimeType=image/svg+xml;image/svg+xml-compressed;application/vnd.corel-draw;application/pdf;application/postscript;image/x-eps;application/illustrator;
702-Exec=inkscape %F
703-TryExec=inkscape
704-Terminal=false
705-StartupNotify=true
706-Icon=inkscape
707
708=== removed directory '.pc/0003-Fix_LP_-911146.patch'
709=== removed directory '.pc/0003-Fix_LP_-911146.patch/src'
710=== removed directory '.pc/0003-Fix_LP_-911146.patch/src/extension'
711=== removed directory '.pc/0003-Fix_LP_-911146.patch/src/extension/implementation'
712=== removed file '.pc/0003-Fix_LP_-911146.patch/src/extension/implementation/script.cpp'
713--- .pc/0003-Fix_LP_-911146.patch/src/extension/implementation/script.cpp 2013-07-02 17:25:52 +0000
714+++ .pc/0003-Fix_LP_-911146.patch/src/extension/implementation/script.cpp 1970-01-01 00:00:00 +0000
715@@ -1,1034 +0,0 @@
716-/** \file
717- * Code for handling extensions (i.e.\ scripts).
718- */
719-/*
720- * Authors:
721- * Bryce Harrington <bryce@osdl.org>
722- * Ted Gould <ted@gould.cx>
723- * Jon A. Cruz <jon@joncruz.org>
724- *
725- * Copyright (C) 2002-2005,2007 Authors
726- *
727- * Released under GNU GPL, read the file 'COPYING' for more information
728- */
729-
730-#define __INKSCAPE_EXTENSION_IMPLEMENTATION_SCRIPT_C__
731-
732-#ifdef HAVE_CONFIG_H
733-# include <config.h>
734-#endif
735-
736-#include <unistd.h>
737-
738-#include <errno.h>
739-#include <glib.h>
740-#include <glib/gstdio.h>
741-#include <gtkmm.h>
742-
743-#include "ui/view/view.h"
744-#include "desktop-handles.h"
745-#include "desktop.h"
746-#include "selection.h"
747-#include "sp-namedview.h"
748-#include "io/sys.h"
749-#include "preferences.h"
750-#include "../system.h"
751-#include "extension/effect.h"
752-#include "extension/output.h"
753-#include "extension/input.h"
754-#include "extension/db.h"
755-#include "script.h"
756-#include "dialogs/dialog-events.h"
757-#include "application/application.h"
758-#include "xml/node.h"
759-#include "xml/attribute-record.h"
760-
761-#include "util/glib-list-iterators.h"
762-#include "path-prefix.h"
763-
764-
765-#ifdef WIN32
766-#include <windows.h>
767-#include <sys/stat.h>
768-#include "registrytool.h"
769-#endif
770-
771-
772-
773-/** This is the command buffer that gets allocated from the stack */
774-#define BUFSIZE (255)
775-
776-
777-
778-/* Namespaces */
779-namespace Inkscape {
780-namespace Extension {
781-namespace Implementation {
782-
783-/** \brief Make GTK+ events continue to come through a little bit
784-
785- This just keeps coming the events through so that we'll make the GUI
786- update and look pretty.
787-*/
788-void Script::pump_events (void) {
789- while ( Gtk::Main::events_pending() ) {
790- Gtk::Main::iteration();
791- }
792- return;
793-}
794-
795-
796-/** \brief A table of what interpreters to call for a given language
797-
798- This table is used to keep track of all the programs to execute a
799- given script. It also tracks the preference to use to overwrite
800- the given interpreter to a custom one per user.
801-*/
802-Script::interpreter_t const Script::interpreterTab[] = {
803- {"perl", "perl-interpreter", "perl" },
804-#ifdef WIN32
805- {"python", "python-interpreter", "pythonw" },
806-#else
807- {"python", "python-interpreter", "python" },
808-#endif
809- {"ruby", "ruby-interpreter", "ruby" },
810- {"shell", "shell-interpreter", "sh" },
811- { NULL, NULL, NULL }
812-};
813-
814-
815-
816-/** \brief Look up an interpreter name, and translate to something that
817- is executable
818- \param interpNameArg The name of the interpreter that we're looking
819- for, should be an entry in interpreterTab
820-*/
821-std::string Script::resolveInterpreterExecutable(const Glib::ustring &interpNameArg)
822-{
823- interpreter_t const *interp = 0;
824- bool foundInterp = false;
825- for (interp = interpreterTab ; interp->identity ; interp++ ){
826- if (interpNameArg == interp->identity) {
827- foundInterp = true;
828- break;
829- }
830- }
831-
832- // Do we have a supported interpreter type?
833- if (!foundInterp) {
834- return "";
835- }
836- std::string interpreter_path = Glib::filename_from_utf8(interp->defaultval);
837-
838- // 1. Check preferences for an override.
839- // Note: this must be an absolute path.
840- Inkscape::Preferences *prefs = Inkscape::Preferences::get();
841- Glib::ustring prefInterp = prefs->getString("/extensions/" + Glib::ustring(interp->prefstring));
842-
843- if (!prefInterp.empty()) {
844- interpreter_path = Glib::filename_from_utf8(prefInterp);
845- }
846-
847- // 2. Search the path.
848- // Do this on all systems, for consistency.
849- // PATH is set up to contain the Python and Perl binary directories
850- // on Windows, so no extra code is necessary.
851- if (!Glib::path_is_absolute(interpreter_path)) {
852- interpreter_path = Glib::find_program_in_path(interpreter_path);
853- }
854- return interpreter_path;
855-}
856-
857-/** \brief This function creates a script object and sets up the
858- variables.
859- \return A script object
860-
861- This function just sets the command to NULL. It should get built
862- officially in the load function. This allows for less allocation
863- of memory in the unloaded state.
864-*/
865-Script::Script() :
866- Implementation()
867-{
868-}
869-
870-/**
871- * brief Destructor
872- */
873-Script::~Script()
874-{
875-}
876-
877-
878-
879-/**
880- \return A string with the complete string with the relative directory expanded
881- \brief This function takes in a Repr that contains a reldir entry
882- and returns that data with the relative directory expanded.
883- Mostly it is here so that relative directories all get used
884- the same way.
885- \param reprin The Inkscape::XML::Node with the reldir in it.
886-
887- Basically this function looks at an attribute of the Repr, and makes
888- a decision based on that. Currently, it is only working with the
889- 'extensions' relative directory, but there will be more of them.
890- One thing to notice is that this function always returns an allocated
891- string. This means that the caller of this function can always
892- free what they are given (and should do it too!).
893-*/
894-std::string
895-Script::solve_reldir(Inkscape::XML::Node *reprin) {
896-
897- gchar const *s = reprin->attribute("reldir");
898-
899- // right now the only recognized relative directory is "extensions"
900- if (!s || Glib::ustring(s) != "extensions") {
901- Glib::ustring str = sp_repr_children(reprin)->content();
902- return str;
903- }
904-
905- Glib::ustring reldir = s;
906- for (unsigned int i=0;
907- i < Inkscape::Extension::Extension::search_path.size();
908- i++) {
909-
910- gchar * fname = g_build_filename(
911- Inkscape::Extension::Extension::search_path[i],
912- sp_repr_children(reprin)->content(),
913- NULL);
914- Glib::ustring filename = fname;
915- g_free(fname);
916- //printf("Filename: %s\n", filename.c_str());
917- if ( Inkscape::IO::file_test(filename.c_str(), G_FILE_TEST_EXISTS) ) {
918- return Glib::filename_from_utf8(filename);
919- }
920- }
921-
922- return "";
923-}
924-
925-
926-
927-/**
928- \return Whether the command given exists, including in the path
929- \brief This function is used to find out if something exists for
930- the check command. It can look in the path if required.
931- \param command The command or file that should be looked for
932-
933- The first thing that this function does is check to see if the
934- incoming file name has a directory delimiter in it. This would
935- mean that it wants to control the directories, and should be
936- used directly.
937-
938- If not, the path is used. Each entry in the path is stepped through,
939- attached to the string, and then tested. If the file is found
940- then a TRUE is returned. If we get all the way through the path
941- then a FALSE is returned, the command could not be found.
942-*/
943-bool Script::check_existence(const std::string &command)
944-{
945- // Check the simple case first
946- if (command.empty()) {
947- return false;
948- }
949-
950- //Don't search when it is an absolute path. */
951- if (Glib::path_is_absolute(command)) {
952- if (Glib::file_test(command, Glib::FILE_TEST_EXISTS)) {
953- return true;
954- } else {
955- return false;
956- }
957- }
958-
959- // First search in the current directory
960- std::string path = G_SEARCHPATH_SEPARATOR_S;
961- path.append(";");
962- // And then in the PATH environment variable.
963- path.append(Glib::getenv("PATH"));
964-
965- std::string::size_type pos = 0;
966- std::string::size_type pos2 = 0;
967- while ( pos < path.size() ) {
968-
969- std::string localPath;
970-
971- pos2 = path.find(G_SEARCHPATH_SEPARATOR, pos);
972- if (pos2 == path.npos) {
973- localPath = path.substr(pos);
974- pos = path.size();
975- } else {
976- localPath = path.substr(pos, pos2-pos);
977- pos = pos2+1;
978- }
979-
980- //printf("### %s\n", localPath.c_str());
981- std::string candidatePath =
982- Glib::build_filename(localPath, command);
983-
984- if (Glib::file_test(candidatePath,
985- Glib::FILE_TEST_EXISTS)) {
986- return true;
987- }
988-
989- }
990-
991- return false;
992-}
993-
994-
995-
996-
997-
998-/**
999- \return none
1000- \brief This function 'loads' an extention, basically it determines
1001- the full command for the extention and stores that.
1002- \param module The extention to be loaded.
1003-
1004- The most difficult part about this function is finding the actual
1005- command through all of the Reprs. Basically it is hidden down a
1006- couple of layers, and so the code has to move down too. When
1007- the command is actually found, it has its relative directory
1008- solved.
1009-
1010- At that point all of the loops are exited, and there is an
1011- if statement to make sure they didn't exit because of not finding
1012- the command. If that's the case, the extention doesn't get loaded
1013- and should error out at a higher level.
1014-*/
1015-
1016-bool Script::load(Inkscape::Extension::Extension *module)
1017-{
1018- if (module->loaded()) {
1019- return true;
1020- }
1021-
1022- helper_extension = "";
1023-
1024- /* This should probably check to find the executable... */
1025- Inkscape::XML::Node *child_repr = sp_repr_children(module->get_repr());
1026- while (child_repr != NULL) {
1027- if (!strcmp(child_repr->name(), INKSCAPE_EXTENSION_NS "script")) {
1028- child_repr = sp_repr_children(child_repr);
1029- while (child_repr != NULL) {
1030- if (!strcmp(child_repr->name(), INKSCAPE_EXTENSION_NS "command")) {
1031- const gchar *interpretstr = child_repr->attribute("interpreter");
1032- if (interpretstr != NULL) {
1033- std::string interpString = resolveInterpreterExecutable(interpretstr);
1034- command.insert(command.end(), interpString);
1035- }
1036- command.insert(command.end(), solve_reldir(child_repr));
1037- }
1038- if (!strcmp(child_repr->name(), INKSCAPE_EXTENSION_NS "helper_extension")) {
1039- helper_extension = sp_repr_children(child_repr)->content();
1040- }
1041- child_repr = sp_repr_next(child_repr);
1042- }
1043-
1044- break;
1045- }
1046- child_repr = sp_repr_next(child_repr);
1047- }
1048-
1049- //g_return_val_if_fail(command.length() > 0, false);
1050-
1051- return true;
1052-}
1053-
1054-
1055-/**
1056- \return None.
1057- \brief Unload this puppy!
1058- \param module Extension to be unloaded.
1059-
1060- This function just sets the module to unloaded. It free's the
1061- command if it has been allocated.
1062-*/
1063-void Script::unload(Inkscape::Extension::Extension */*module*/)
1064-{
1065- command.clear();
1066- helper_extension = "";
1067-}
1068-
1069-
1070-
1071-
1072-/**
1073- \return Whether the check passed or not
1074- \brief Check every dependency that was given to make sure we should keep this extension
1075- \param module The Extension in question
1076-
1077-*/
1078-bool
1079-Script::check(Inkscape::Extension::Extension *module)
1080-{
1081- int script_count = 0;
1082- Inkscape::XML::Node *child_repr = sp_repr_children(module->get_repr());
1083- while (child_repr != NULL) {
1084- if (!strcmp(child_repr->name(), INKSCAPE_EXTENSION_NS "script")) {
1085- script_count++;
1086- child_repr = sp_repr_children(child_repr);
1087- while (child_repr != NULL) {
1088- if (!strcmp(child_repr->name(), INKSCAPE_EXTENSION_NS "check")) {
1089- std::string command_text = solve_reldir(child_repr);
1090- if (!command_text.empty()) {
1091- /* I've got the command */
1092- bool existance = check_existence(command_text);
1093- if (!existance) {
1094- return false;
1095- }
1096- } else {
1097- return false;
1098- }
1099- }
1100-
1101- if (!strcmp(child_repr->name(), INKSCAPE_EXTENSION_NS "helper_extension")) {
1102- gchar const *helper = sp_repr_children(child_repr)->content();
1103- if (Inkscape::Extension::db.get(helper) == NULL) {
1104- return false;
1105- }
1106- }
1107-
1108- child_repr = sp_repr_next(child_repr);
1109- }
1110-
1111- break;
1112- }
1113- child_repr = sp_repr_next(child_repr);
1114- }
1115-
1116- if (script_count == 0) {
1117- return false;
1118- }
1119-
1120- return true;
1121-}
1122-
1123-class ScriptDocCache : public ImplementationDocumentCache {
1124- friend class Script;
1125-protected:
1126- std::string _filename;
1127- int _tempfd;
1128-public:
1129- ScriptDocCache (Inkscape::UI::View::View * view);
1130- ~ScriptDocCache ( );
1131-};
1132-
1133-ScriptDocCache::ScriptDocCache (Inkscape::UI::View::View * view) :
1134- ImplementationDocumentCache(view),
1135- _filename(""),
1136- _tempfd(0)
1137-{
1138- try {
1139- _tempfd = Inkscape::IO::file_open_tmp(_filename, "ink_ext_XXXXXX.svg");
1140- } catch (...) {
1141- /// \todo Popup dialog here
1142- return;
1143- }
1144-
1145- SPDesktop *desktop = (SPDesktop *) view;
1146- sp_namedview_document_from_window(desktop);
1147-
1148- Inkscape::Extension::save(
1149- Inkscape::Extension::db.get(SP_MODULE_KEY_OUTPUT_SVG_INKSCAPE),
1150- view->doc(), _filename.c_str(), false, false, false, Inkscape::Extension::FILE_SAVE_METHOD_TEMPORARY);
1151-
1152- return;
1153-}
1154-
1155-ScriptDocCache::~ScriptDocCache ( )
1156-{
1157- close(_tempfd);
1158- unlink(_filename.c_str());
1159-}
1160-
1161-ImplementationDocumentCache *Script::newDocCache( Inkscape::Extension::Extension * /*ext*/, Inkscape::UI::View::View * view ) {
1162- return new ScriptDocCache(view);
1163-}
1164-
1165-
1166-/**
1167- \return A dialog for preferences
1168- \brief A stub funtion right now
1169- \param module Module who's preferences need getting
1170- \param filename Hey, the file you're getting might be important
1171-
1172- This function should really do something, right now it doesn't.
1173-*/
1174-Gtk::Widget *Script::prefs_input(Inkscape::Extension::Input *module,
1175- const gchar */*filename*/)
1176-{
1177- return module->autogui(NULL, NULL);
1178-}
1179-
1180-
1181-
1182-/**
1183- \return A dialog for preferences
1184- \brief A stub funtion right now
1185- \param module Module whose preferences need getting
1186-
1187- This function should really do something, right now it doesn't.
1188-*/
1189-Gtk::Widget *Script::prefs_output(Inkscape::Extension::Output *module)
1190-{
1191- return module->autogui(NULL, NULL);
1192-}
1193-
1194-/**
1195- \return A new document that has been opened
1196- \brief This function uses a filename that is put in, and calls
1197- the extension's command to create an SVG file which is
1198- returned.
1199- \param module Extension to use.
1200- \param filename File to open.
1201-
1202- First things first, this function needs a temporary file name. To
1203- create on of those the function g_file_open_tmp is used with
1204- the header of ink_ext_.
1205-
1206- The extension is then executed using the 'execute' function
1207- with the filname coming in, and the temporary filename. After
1208- That executing, the SVG should be in the temporary file.
1209-
1210- Finally, the temporary file is opened using the SVG input module and
1211- a document is returned. That document has its filename set to
1212- the incoming filename (so that it's not the temporary filename).
1213- That document is then returned from this function.
1214-*/
1215-SPDocument *Script::open(Inkscape::Extension::Input *module,
1216- const gchar *filenameArg)
1217-{
1218- std::list<std::string> params;
1219- module->paramListString(params);
1220-
1221- std::string tempfilename_out;
1222- int tempfd_out = 0;
1223- try {
1224- tempfd_out = Inkscape::IO::file_open_tmp(tempfilename_out, "ink_ext_XXXXXX.svg");
1225- } catch (...) {
1226- /// \todo Popup dialog here
1227- return NULL;
1228- }
1229-
1230- std::string lfilename = Glib::filename_from_utf8(filenameArg);
1231-
1232- file_listener fileout;
1233- int data_read = execute(command, params, lfilename, fileout);
1234- fileout.toFile(tempfilename_out);
1235-
1236- SPDocument * mydoc = NULL;
1237- if (data_read > 10) {
1238- if (helper_extension.size()==0) {
1239- mydoc = Inkscape::Extension::open(
1240- Inkscape::Extension::db.get(SP_MODULE_KEY_INPUT_SVG),
1241- tempfilename_out.c_str());
1242- } else {
1243- mydoc = Inkscape::Extension::open(
1244- Inkscape::Extension::db.get(helper_extension.c_str()),
1245- tempfilename_out.c_str());
1246- }
1247- } // data_read
1248-
1249- if (mydoc != NULL) {
1250- g_free(mydoc->base);
1251- mydoc->base = NULL;
1252- sp_document_change_uri_and_hrefs(mydoc, filenameArg);
1253- }
1254-
1255- // make sure we don't leak file descriptors from g_file_open_tmp
1256- close(tempfd_out);
1257-
1258- unlink(tempfilename_out.c_str());
1259-
1260- return mydoc;
1261-} // open
1262-
1263-
1264-
1265-/**
1266- \return none
1267- \brief This function uses an extention to save a document. It first
1268- creates an SVG file of the document, and then runs it through
1269- the script.
1270- \param module Extention to be used
1271- \param doc Document to be saved
1272- \param filename The name to save the final file as
1273- \return false in case of any failure writing the file, otherwise true
1274-
1275- Well, at some point people need to save - it is really what makes
1276- the entire application useful. And, it is possible that someone
1277- would want to use an extetion for this, so we need a function to
1278- do that eh?
1279-
1280- First things first, the document is saved to a temporary file that
1281- is an SVG file. To get the temporary filename g_file_open_tmp is used with
1282- ink_ext_ as a prefix. Don't worry, this file gets deleted at the
1283- end of the function.
1284-
1285- After we have the SVG file, then extention_execute is called with
1286- the temporary file name and the final output filename. This should
1287- put the output of the script into the final output file. We then
1288- delete the temporary file.
1289-*/
1290-void Script::save(Inkscape::Extension::Output *module,
1291- SPDocument *doc,
1292- const gchar *filenameArg)
1293-{
1294- std::list<std::string> params;
1295- module->paramListString(params);
1296-
1297- std::string tempfilename_in;
1298- int tempfd_in = 0;
1299- try {
1300- tempfd_in = Inkscape::IO::file_open_tmp(tempfilename_in, "ink_ext_XXXXXX.svg");
1301- } catch (...) {
1302- /// \todo Popup dialog here
1303- throw Inkscape::Extension::Output::save_failed();
1304- }
1305-
1306- if (helper_extension.size() == 0) {
1307- Inkscape::Extension::save(
1308- Inkscape::Extension::db.get(SP_MODULE_KEY_OUTPUT_SVG_INKSCAPE),
1309- doc, tempfilename_in.c_str(), false, false, false,
1310- Inkscape::Extension::FILE_SAVE_METHOD_TEMPORARY);
1311- } else {
1312- Inkscape::Extension::save(
1313- Inkscape::Extension::db.get(helper_extension.c_str()),
1314- doc, tempfilename_in.c_str(), false, false, false,
1315- Inkscape::Extension::FILE_SAVE_METHOD_TEMPORARY);
1316- }
1317-
1318-
1319- file_listener fileout;
1320- execute(command, params, tempfilename_in, fileout);
1321-
1322- std::string lfilename = Glib::filename_from_utf8(filenameArg);
1323- bool success = fileout.toFile(lfilename);
1324-
1325- // make sure we don't leak file descriptors from g_file_open_tmp
1326- close(tempfd_in);
1327- // FIXME: convert to utf8 (from "filename encoding") and unlink_utf8name
1328- unlink(tempfilename_in.c_str());
1329-
1330- if (success == false) {
1331- throw Inkscape::Extension::Output::save_failed();
1332- }
1333-
1334- return;
1335-}
1336-
1337-
1338-
1339-/**
1340- \return none
1341- \brief This function uses an extention as a effect on a document.
1342- \param module Extention to effect with.
1343- \param doc Document to run through the effect.
1344-
1345- This function is a little bit trickier than the previous two. It
1346- needs two temporary files to get it's work done. Both of these
1347- files have random names created for them using the g_file_open_temp function
1348- with the ink_ext_ prefix in the temporary directory. Like the other
1349- functions, the temporary files are deleted at the end.
1350-
1351- To save/load the two temporary documents (both are SVG) the internal
1352- modules for SVG load and save are used. They are both used through
1353- the module system function by passing their keys into the functions.
1354-
1355- The command itself is built a little bit differently than in other
1356- functions because the effect support selections. So on the command
1357- line a list of all the ids that are selected is included. Currently,
1358- this only works for a single selected object, but there will be more.
1359- The command string is filled with the data, and then after the execution
1360- it is freed.
1361-
1362- The execute function is used at the core of this function
1363- to execute the Script on the two SVG documents (actually only one
1364- exists at the time, the other is created by that script). At that
1365- point both should be full, and the second one is loaded.
1366-*/
1367-void Script::effect(Inkscape::Extension::Effect *module,
1368- Inkscape::UI::View::View *doc,
1369- ImplementationDocumentCache * docCache)
1370-{
1371- if (docCache == NULL) {
1372- docCache = newDocCache(module, doc);
1373- }
1374- ScriptDocCache * dc = dynamic_cast<ScriptDocCache *>(docCache);
1375- if (dc == NULL) {
1376- printf("TOO BAD TO LIVE!!!");
1377- exit(1);
1378- }
1379-
1380- SPDesktop *desktop = (SPDesktop *)doc;
1381- sp_namedview_document_from_window(desktop);
1382-
1383- std::list<std::string> params;
1384- module->paramListString(params);
1385-
1386- if (module->no_doc) {
1387- // this is a no-doc extension, e.g. a Help menu command;
1388- // just run the command without any files, ignoring errors
1389-
1390- Glib::ustring empty;
1391- file_listener outfile;
1392- execute(command, params, empty, outfile);
1393-
1394- return;
1395- }
1396-
1397- std::string tempfilename_out;
1398- int tempfd_out = 0;
1399- try {
1400- tempfd_out = Inkscape::IO::file_open_tmp(tempfilename_out, "ink_ext_XXXXXX.svg");
1401- } catch (...) {
1402- /// \todo Popup dialog here
1403- return;
1404- }
1405-
1406- if (desktop != NULL) {
1407- Inkscape::Util::GSListConstIterator<SPItem *> selected =
1408- sp_desktop_selection(desktop)->itemList();
1409- while ( selected != NULL ) {
1410- Glib::ustring selected_id;
1411- selected_id += "--id=";
1412- selected_id += (*selected)->getId();
1413- params.insert(params.begin(), selected_id);
1414- ++selected;
1415- }
1416- }
1417-
1418- file_listener fileout;
1419- int data_read = execute(command, params, dc->_filename, fileout);
1420- fileout.toFile(tempfilename_out);
1421-
1422- pump_events();
1423-
1424- SPDocument * mydoc = NULL;
1425- if (data_read > 10) {
1426- mydoc = Inkscape::Extension::open(
1427- Inkscape::Extension::db.get(SP_MODULE_KEY_INPUT_SVG),
1428- tempfilename_out.c_str());
1429- } // data_read
1430-
1431- pump_events();
1432-
1433- // make sure we don't leak file descriptors from g_file_open_tmp
1434- close(tempfd_out);
1435-
1436- g_unlink(tempfilename_out.c_str());
1437-
1438- /* Do something with mydoc.... */
1439- if (mydoc) {
1440- doc->doc()->emitReconstructionStart();
1441- copy_doc(doc->doc()->rroot, mydoc->rroot);
1442- doc->doc()->emitReconstructionFinish();
1443- SPObject *layer = NULL;
1444-
1445- // Getting the named view from the document generated by the extension
1446- SPNamedView *nv = sp_document_namedview(mydoc, NULL);
1447-
1448- //Check if it has a default layer set up
1449- if ( nv != NULL){
1450- if( nv->default_layer_id != 0 ) {
1451- SPDocument *document = desktop->doc();
1452- //If so, get that layer
1453- layer = document->getObjectById(g_quark_to_string(nv->default_layer_id));
1454- }
1455- }
1456-
1457- sp_namedview_update_layers_from_document(desktop);
1458- //If that layer exists,
1459- if (layer) {
1460- //set the current layer
1461- desktop->setCurrentLayer(layer);
1462- }
1463- mydoc->release();
1464- }
1465-
1466- return;
1467-}
1468-
1469-
1470-
1471-/**
1472- \brief A function to take all the svg elements from one document
1473- and put them in another.
1474- \param oldroot The root node of the document to be replaced
1475- \param newroot The root node of the document to replace it with
1476-
1477- This function first deletes all of the data in the old document. It
1478- does this by creating a list of what needs to be deleted, and then
1479- goes through the list. This two pass approach removes issues with
1480- the list being change while parsing through it. Lots of nasty bugs.
1481-
1482- Then, it goes through the new document, duplicating all of the
1483- elements and putting them into the old document. The copy
1484- is then complete.
1485-*/
1486-void Script::copy_doc (Inkscape::XML::Node * oldroot, Inkscape::XML::Node * newroot)
1487-{
1488- std::vector<Inkscape::XML::Node *> delete_list;
1489- Inkscape::XML::Node * oldroot_namedview = NULL;
1490-
1491- for (Inkscape::XML::Node * child = oldroot->firstChild();
1492- child != NULL;
1493- child = child->next()) {
1494- if (!strcmp("sodipodi:namedview", child->name())) {
1495- oldroot_namedview = child;
1496- for (Inkscape::XML::Node * oldroot_namedview_child = child->firstChild();
1497- oldroot_namedview_child != NULL;
1498- oldroot_namedview_child = oldroot_namedview_child->next()) {
1499- delete_list.push_back(oldroot_namedview_child);
1500- }
1501- } else {
1502- delete_list.push_back(child);
1503- }
1504- }
1505- for (unsigned int i = 0; i < delete_list.size(); i++) {
1506- sp_repr_unparent(delete_list[i]);
1507- }
1508-
1509- for (Inkscape::XML::Node * child = newroot->firstChild();
1510- child != NULL;
1511- child = child->next()) {
1512- if (!strcmp("sodipodi:namedview", child->name())) {
1513- if (oldroot_namedview != NULL) {
1514- for (Inkscape::XML::Node * newroot_namedview_child = child->firstChild();
1515- newroot_namedview_child != NULL;
1516- newroot_namedview_child = newroot_namedview_child->next()) {
1517- oldroot_namedview->appendChild(newroot_namedview_child->duplicate(oldroot->document()));
1518- }
1519- }
1520- } else {
1521- oldroot->appendChild(child->duplicate(oldroot->document()));
1522- }
1523- }
1524-
1525- {
1526- using Inkscape::Util::List;
1527- using Inkscape::XML::AttributeRecord;
1528- std::vector<gchar const *> attribs;
1529-
1530- // Make a list of all attributes of the old root node.
1531- for (List<AttributeRecord const> iter = oldroot->attributeList(); iter; ++iter) {
1532- attribs.push_back(g_quark_to_string(iter->key));
1533- }
1534-
1535- // Delete the attributes of the old root nodes.
1536- for (std::vector<gchar const *>::const_iterator it = attribs.begin(); it != attribs.end(); it++) {
1537- oldroot->setAttribute(*it, NULL);
1538- }
1539-
1540- // Set the new attributes.
1541- for (List<AttributeRecord const> iter = newroot->attributeList(); iter; ++iter) {
1542- gchar const *name = g_quark_to_string(iter->key);
1543- oldroot->setAttribute(name, newroot->attribute(name));
1544- }
1545- }
1546-
1547- /** \todo Restore correct layer */
1548- /** \todo Restore correct selection */
1549-}
1550-
1551-/** \brief This function checks the stderr file, and if it has data,
1552- shows it in a warning dialog to the user
1553- \param filename Filename of the stderr file
1554-*/
1555-void Script::checkStderr (const Glib::ustring &data,
1556- Gtk::MessageType type,
1557- const Glib::ustring &message)
1558-{
1559- Gtk::MessageDialog warning(message, false, type, Gtk::BUTTONS_OK, true);
1560- warning.set_resizable(true);
1561- GtkWidget *dlg = GTK_WIDGET(warning.gobj());
1562- sp_transientize(dlg);
1563-
1564- Gtk::VBox * vbox = warning.get_vbox();
1565-
1566- /* Gtk::TextView * textview = new Gtk::TextView(Gtk::TextBuffer::create()); */
1567- Gtk::TextView * textview = new Gtk::TextView();
1568- textview->set_editable(false);
1569- textview->set_wrap_mode(Gtk::WRAP_WORD);
1570- textview->show();
1571-
1572- // Remove the last character
1573- char *errormsg = (char*) data.c_str();
1574- while (*errormsg != '\0') errormsg++;
1575- errormsg -= 1;
1576- *errormsg = '\0';
1577-
1578- textview->get_buffer()->set_text(_(data.c_str()));
1579-
1580- Gtk::ScrolledWindow * scrollwindow = new Gtk::ScrolledWindow();
1581- scrollwindow->add(*textview);
1582- scrollwindow->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
1583- scrollwindow->set_shadow_type(Gtk::SHADOW_IN);
1584- scrollwindow->show();
1585- scrollwindow->set_size_request(0, 60);
1586-
1587- vbox->pack_start(*scrollwindow, true, true, 5 /* fix these */);
1588-
1589- warning.run();
1590-
1591- return;
1592-}
1593-
1594-bool Script::cancelProcessing (void) {
1595- _canceled = true;
1596- _main_loop->quit();
1597- Glib::spawn_close_pid(_pid);
1598-
1599- return true;
1600-}
1601-
1602-
1603-/** \brief This is the core of the extension file as it actually does
1604- the execution of the extension.
1605- \param in_command The command to be executed
1606- \param filein Filename coming in
1607- \param fileout Filename of the out file
1608- \return Number of bytes that were read into the output file.
1609-
1610- The first thing that this function does is build the command to be
1611- executed. This consists of the first string (in_command) and then
1612- the filename for input (filein). This file is put on the command
1613- line.
1614-
1615- The next thing is that this function does is open a pipe to the
1616- command and get the file handle in the ppipe variable. It then
1617- opens the output file with the output file handle. Both of these
1618- operations are checked extensively for errors.
1619-
1620- After both are opened, then the data is copied from the output
1621- of the pipe into the file out using fread and fwrite. These two
1622- functions are used because of their primitive nature they make
1623- no assumptions about the data. A buffer is used in the transfer,
1624- but the output of fread is stored so the exact number of bytes
1625- is handled gracefully.
1626-
1627- At the very end (after the data has been copied) both of the files
1628- are closed, and we return to what we were doing.
1629-*/
1630-int Script::execute (const std::list<std::string> &in_command,
1631- const std::list<std::string> &in_params,
1632- const Glib::ustring &filein,
1633- file_listener &fileout)
1634-{
1635- g_return_val_if_fail(!in_command.empty(), 0);
1636- // printf("Executing\n");
1637-
1638- std::vector<std::string> argv;
1639-
1640- bool interpreted = (in_command.size() == 2);
1641- std::string program = in_command.front();
1642- std::string script = interpreted ? in_command.back() : "";
1643- std::string working_directory = "";
1644-
1645- // Use Glib::find_program_in_path instead of the equivalent
1646- // Glib::spawn_* functionality, because _wspawnp is broken on Windows:
1647- // it doesn't work when PATH contains Unicode directories
1648- if (!Glib::path_is_absolute(program)) {
1649- program = Glib::find_program_in_path(program);
1650- }
1651- argv.push_back(program);
1652-
1653- if (interpreted) {
1654- // On Windows, Python garbles Unicode command line parameters
1655- // in an useless way. This means extensions fail when Inkscape
1656- // is run from an Unicode directory.
1657- // As a workaround, we set the working directory to the one
1658- // containing the script.
1659- working_directory = Glib::path_get_dirname(script);
1660- script = Glib::path_get_basename(script);
1661- #ifdef G_OS_WIN32
1662- // ANNOYING: glibmm does not wrap g_win32_locale_filename_from_utf8
1663- gchar *workdir_s = g_win32_locale_filename_from_utf8(working_directory.data());
1664- working_directory = workdir_s;
1665- g_free(workdir_s);
1666- #endif
1667-
1668- argv.push_back(script);
1669- }
1670-
1671- // assemble the rest of argv
1672- std::copy(in_params.begin(), in_params.end(), std::back_inserter(argv));
1673- if (!filein.empty()) {
1674- argv.push_back(filein);
1675- }
1676-
1677- int stdout_pipe, stderr_pipe;
1678-
1679- try {
1680- Glib::spawn_async_with_pipes(working_directory, // working directory
1681- argv, // arg v
1682- static_cast<Glib::SpawnFlags>(0), // no flags
1683- sigc::slot<void>(),
1684- &_pid, // Pid
1685- NULL, // STDIN
1686- &stdout_pipe, // STDOUT
1687- &stderr_pipe); // STDERR
1688- } catch (Glib::Error e) {
1689- printf("Can't Spawn!!! spawn returns: %s\n", e.what().data());
1690- return 0;
1691- }
1692-
1693- _main_loop = Glib::MainLoop::create(false);
1694-
1695- file_listener fileerr;
1696- fileout.init(stdout_pipe, _main_loop);
1697- fileerr.init(stderr_pipe, _main_loop);
1698-
1699- _canceled = false;
1700- _main_loop->run();
1701-
1702- // Ensure all the data is out of the pipe
1703- while (!fileout.isDead()) {
1704- fileout.read(Glib::IO_IN);
1705- }
1706- while (!fileerr.isDead()) {
1707- fileerr.read(Glib::IO_IN);
1708- }
1709-
1710- if (_canceled) {
1711- // std::cout << "Script Canceled" << std::endl;
1712- return 0;
1713- }
1714-
1715- Glib::ustring stderr_data = fileerr.string();
1716- if (stderr_data.length() != 0 &&
1717- Inkscape::NSApplication::Application::getUseGui()
1718- ) {
1719- checkStderr(stderr_data, Gtk::MESSAGE_INFO,
1720- _("Inkscape has received additional data from the script executed. "
1721- "The script did not return an error, but this may indicate the results will not be as expected."));
1722- }
1723-
1724- Glib::ustring stdout_data = fileout.string();
1725- if (stdout_data.length() == 0) {
1726- return 0;
1727- }
1728-
1729- // std::cout << "Finishing Execution." << std::endl;
1730- return stdout_data.length();
1731-}
1732-
1733-
1734-
1735-
1736-} // namespace Implementation
1737-} // namespace Extension
1738-} // namespace Inkscape
1739-
1740-/*
1741- Local Variables:
1742- mode:c++
1743- c-file-style:"stroustrup"
1744- c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
1745- indent-tabs-mode:nil
1746- fill-column:99
1747- End:
1748-*/
1749-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :
1750
1751=== removed directory '.pc/0004-Fix_FTBFS_on_gcc-4.8.patch'
1752=== removed directory '.pc/0004-Fix_FTBFS_on_gcc-4.8.patch/src'
1753=== removed file '.pc/0004-Fix_FTBFS_on_gcc-4.8.patch/src/connector-context.cpp'
1754--- .pc/0004-Fix_FTBFS_on_gcc-4.8.patch/src/connector-context.cpp 2013-07-02 17:25:52 +0000
1755+++ .pc/0004-Fix_FTBFS_on_gcc-4.8.patch/src/connector-context.cpp 1970-01-01 00:00:00 +0000
1756@@ -1,2041 +0,0 @@
1757-/*
1758- * Connector creation tool
1759- *
1760- * Authors:
1761- * Michael Wybrow <mjwybrow@users.sourceforge.net>
1762- *
1763- * Copyright (C) 2005-2008 Michael Wybrow
1764- * Copyright (C) 2009 Monash University
1765- *
1766- * Released under GNU GPL, read the file 'COPYING' for more information
1767- *
1768- * TODO:
1769- * o Show a visual indicator for objects with the 'avoid' property set.
1770- * o Allow user to change a object between a path and connector through
1771- * the interface.
1772- * o Create an interface for setting markers (arrow heads).
1773- * o Better distinguish between paths and connectors to prevent problems
1774- * in the node tool and paths accidentally being turned into connectors
1775- * in the connector tool. Perhaps have a way to convert between.
1776- * o Only call libavoid's updateEndPoint as required. Currently we do it
1777- * for both endpoints, even if only one is moving.
1778- * o Allow user-placeable connection points.
1779- * o Deal sanely with connectors with both endpoints attached to the
1780- * same connection point, and drawing of connectors attaching
1781- * overlapping shapes (currently tries to adjust connector to be
1782- * outside both bounding boxes).
1783- * o Fix many special cases related to connectors updating,
1784- * e.g., copying a couple of shapes and a connector that are
1785- * attached to each other.
1786- * e.g., detach connector when it is moved or transformed in
1787- * one of the other contexts.
1788- * o Cope with shapes whose ids change when they have attached
1789- * connectors.
1790- * o During dragging motion, gobble up to and use the final motion event.
1791- * Gobbling away all duplicates after the current can occasionally result
1792- * in the path lagging behind the mouse cursor if it is no longer being
1793- * dragged.
1794- * o Fix up libavoid's representation after undo actions. It doesn't see
1795- * any transform signals and hence doesn't know shapes have moved back to
1796- * there earlier positions.
1797- * o Decide whether drawing/editing mode should be an Inkscape preference
1798- * or the connector tool should always start in drawing mode.
1799- * o Correct the problem with switching to the select tool when pressing
1800- * space bar (there are moments when it refuses to do so).
1801- *
1802- * ----------------------------------------------------------------------------
1803- *
1804- * mjwybrow's observations on acracan's Summer of Code connector work:
1805- *
1806- * - GUI comments:
1807- *
1808- * - Buttons for adding and removing user-specified connection
1809- * points should probably have "+" and "-" symbols on them so they
1810- * are consistent with the similar buttons for the node tool.
1811- * - Controls on the connector tool be should be reordered logically,
1812- * possibly as follows:
1813- *
1814- * *Connector*: [Polyline-radio-button] [Orthgonal-radio-button]
1815- * [Curvature-control] | *Shape*: [Avoid-button] [Dont-avoid-button]
1816- * [Spacing-control] | *Connection pts*: [Edit-mode] [Add-pt] [Rm-pt]
1817- *
1818- * I think that the network layout controls be moved to the
1819- * Align and Distribute dialog (there is already the layout button
1820- * there, but no options are exposed).
1821- *
1822- * I think that the style change between polyline and orthogonal
1823- * would be much clearer with two buttons (radio behaviour -- just
1824- * one is true).
1825- *
1826- * The other tools show a label change from "New:" to "Change:"
1827- * depending on whether an object is selected. We could consider
1828- * this but there may not be space.
1829- *
1830- * The Add-pt and Rm-pt buttons should be greyed out (inactive) if
1831- * we are not in connection point editing mode. And probably also
1832- * if there is no shape selected, i.e. at the times they have no
1833- * effect when clicked.
1834- *
1835- * Likewise for the avoid/ignore shapes buttons. These should be
1836- * inactive when a shape is not selected in the connector context.
1837- *
1838- * - When creating/editing connection points:
1839- *
1840- * - Strange things can happen if you have connectors selected, or
1841- * try rerouting connectors by dragging their endpoints when in
1842- * connection point editing mode.
1843- *
1844- * - Possibly the selected shape's connection points should always
1845- * be shown (i.e., have knots) when in editing mode.
1846- *
1847- * - It is a little strange to be able to place connection points
1848- * competely outside shapes. Especially when you later can't draw
1849- * connectors to them since the knots are only visible when you
1850- * are over the shape. I think that you should only be able to
1851- * place connection points inside or on the boundary of the shape
1852- * itself.
1853- *
1854- * - The intended ability to place a new point at the current cursor
1855- * position by pressing RETURN does not seem to work.
1856- *
1857- * - The Status bar tooltip should change to reflect editing mode
1858- * and tell the user about RETURN and how to use the tool.
1859- *
1860- * - Connection points general:
1861- *
1862- * - Connection points that were inside the shape can end up outside
1863- * after a rotation is applied to the shape in the select tool.
1864- * It doesn't seem like the correct transform is being applied to
1865- * these, or it is being applied at the wrong time. I'd expect
1866- * connection points to rotate with the shape, and stay at the
1867- * same position "on the shape"
1868- *
1869- * - I was able to make the connectors attached to a shape fall off
1870- * the shape after scaling it. Not sure the exact cause, but may
1871- * require more investigation/debugging.
1872- *
1873- * - The user-defined connection points should be either absolute
1874- * (as the current ones are) or defined as a percentage of the
1875- * shape. These would be based on a toggle setting on the
1876- * toolbar, and they would be placed in exactly the same way by
1877- * the user. The only difference would be that they would be
1878- * store as percentage positions in the SVG connection-points
1879- * property and that they would update/move automatically if the
1880- * object was resized or scaled.
1881- *
1882- * - Thinking more, I think you always want to store and think about
1883- * the positions of connection points to be pre-transform, but
1884- * obviously the shape transform is applied to them. That way,
1885- * they will rotate and scale automatically with the shape, when
1886- * the shape transform is altered. The Percentage version would
1887- * compute their position from the pre-transform dimensions and
1888- * then have the transform applied to them, for example.
1889- *
1890- * - The connection points in the test_connection_points.svg file
1891- * seem to follow the shape when it is moved, but connection
1892- * points I add to new shapes, do not follow the shape, either
1893- * when the shape is just moved or transformed. There is
1894- * something wrong here. What exactly should the behaviour be
1895- * currently?
1896- *
1897- * - I see that connection points are specified at absolute canvas
1898- * positions. I really think that they should be specified in
1899- * shape coordinated relative to the shapes. There may be
1900- * transforms applied to layers and the canvas which would make
1901- * specifying them quite difficult. I'd expect a position of 0, 0
1902- * to be on the shape in question or very close to it, for example.
1903- *
1904- */
1905-
1906-
1907-
1908-#include <gdk/gdkkeysyms.h>
1909-#include <string>
1910-#include <cstring>
1911-
1912-#include "connector-context.h"
1913-#include "pixmaps/cursor-connector.xpm"
1914-#include "pixmaps/cursor-node.xpm"
1915-//#include "pixmaps/cursor-node-m.xpm"
1916-//#include "pixmaps/cursor-node-d.xpm"
1917-#include "xml/node-event-vector.h"
1918-#include "xml/repr.h"
1919-#include "svg/svg.h"
1920-#include "desktop.h"
1921-#include "desktop-style.h"
1922-#include "desktop-handles.h"
1923-#include "document.h"
1924-#include "message-context.h"
1925-#include "message-stack.h"
1926-#include "selection.h"
1927-#include "inkscape.h"
1928-#include "preferences.h"
1929-#include "sp-path.h"
1930-#include "display/canvas-bpath.h"
1931-#include "display/sodipodi-ctrl.h"
1932-#include <glibmm/i18n.h>
1933-#include <glibmm/stringutils.h>
1934-#include "snap.h"
1935-#include "knot.h"
1936-#include "sp-conn-end.h"
1937-#include "sp-conn-end-pair.h"
1938-#include "conn-avoid-ref.h"
1939-#include "libavoid/vertices.h"
1940-#include "libavoid/router.h"
1941-#include "context-fns.h"
1942-#include "sp-namedview.h"
1943-#include "sp-text.h"
1944-#include "sp-flowtext.h"
1945-#include "display/curve.h"
1946-
1947-static void sp_connector_context_class_init(SPConnectorContextClass *klass);
1948-static void sp_connector_context_init(SPConnectorContext *conn_context);
1949-static void sp_connector_context_dispose(GObject *object);
1950-
1951-static void sp_connector_context_setup(SPEventContext *ec);
1952-static void sp_connector_context_set(SPEventContext *ec, Inkscape::Preferences::Entry *val);
1953-static void sp_connector_context_finish(SPEventContext *ec);
1954-static gint sp_connector_context_root_handler(SPEventContext *ec, GdkEvent *event);
1955-static gint sp_connector_context_item_handler(SPEventContext *event_context, SPItem *item, GdkEvent *event);
1956-
1957-// Stuff borrowed from DrawContext
1958-static void spcc_connector_set_initial_point(SPConnectorContext *cc, Geom::Point const p);
1959-static void spcc_connector_set_subsequent_point(SPConnectorContext *cc, Geom::Point const p);
1960-static void spcc_connector_finish_segment(SPConnectorContext *cc, Geom::Point p);
1961-static void spcc_reset_colors(SPConnectorContext *cc);
1962-static void spcc_connector_finish(SPConnectorContext *cc);
1963-static void spcc_concat_colors_and_flush(SPConnectorContext *cc);
1964-static void spcc_flush_white(SPConnectorContext *cc, SPCurve *gc);
1965-
1966-// Context event handlers
1967-static gint connector_handle_button_press(SPConnectorContext *const cc, GdkEventButton const &bevent);
1968-static gint connector_handle_motion_notify(SPConnectorContext *const cc, GdkEventMotion const &mevent);
1969-static gint connector_handle_button_release(SPConnectorContext *const cc, GdkEventButton const &revent);
1970-static gint connector_handle_key_press(SPConnectorContext *const cc, guint const keyval);
1971-
1972-static void cc_active_shape_add_knot(SPDesktop* desktop, SPItem* item, ConnectionPointMap &cphandles, ConnectionPoint& cp);
1973-static void cc_set_active_shape(SPConnectorContext *cc, SPItem *item);
1974-static void cc_clear_active_shape(SPConnectorContext *cc);
1975-static void cc_set_active_conn(SPConnectorContext *cc, SPItem *item);
1976-static void cc_clear_active_conn(SPConnectorContext *cc);
1977-static bool conn_pt_handle_test(SPConnectorContext *cc, Geom::Point& p, gchar **href, gchar **cpid);
1978-static void cc_select_handle(SPKnot* knot);
1979-static void cc_deselect_handle(SPKnot* knot);
1980-static bool cc_item_is_shape(SPItem *item);
1981-static void cc_selection_changed(Inkscape::Selection *selection, gpointer data);
1982-static void cc_connector_rerouting_finish(SPConnectorContext *const cc,
1983- Geom::Point *const p);
1984-
1985-static void shape_event_attr_deleted(Inkscape::XML::Node *repr,
1986- Inkscape::XML::Node *child, Inkscape::XML::Node *ref, gpointer data);
1987-static void shape_event_attr_changed(Inkscape::XML::Node *repr, gchar const *name,
1988- gchar const *old_value, gchar const *new_value, bool is_interactive,
1989- gpointer data);
1990-
1991-
1992-static char* cc_knot_tips[] = { _("<b>Connection point</b>: click or drag to create a new connector"),
1993- _("<b>Connection point</b>: click to select, drag to move") };
1994-
1995-/*static Geom::Point connector_drag_origin_w(0, 0);
1996-static bool connector_within_tolerance = false;*/
1997-static SPEventContextClass *parent_class;
1998-
1999-
2000-static Inkscape::XML::NodeEventVector shape_repr_events = {
2001- NULL, /* child_added */
2002- NULL, /* child_added */
2003- shape_event_attr_changed,
2004- NULL, /* content_changed */
2005- NULL /* order_changed */
2006-};
2007-
2008-static Inkscape::XML::NodeEventVector layer_repr_events = {
2009- NULL, /* child_added */
2010- shape_event_attr_deleted,
2011- NULL, /* child_added */
2012- NULL, /* content_changed */
2013- NULL /* order_changed */
2014-};
2015-
2016-
2017-GType
2018-sp_connector_context_get_type(void)
2019-{
2020- static GType type = 0;
2021- if (!type) {
2022- GTypeInfo info = {
2023- sizeof(SPConnectorContextClass),
2024- NULL, NULL,
2025- (GClassInitFunc) sp_connector_context_class_init,
2026- NULL, NULL,
2027- sizeof(SPConnectorContext),
2028- 4,
2029- (GInstanceInitFunc) sp_connector_context_init,
2030- NULL, /* value_table */
2031- };
2032- type = g_type_register_static(SP_TYPE_EVENT_CONTEXT, "SPConnectorContext", &info, (GTypeFlags)0);
2033- }
2034- return type;
2035-}
2036-
2037-static void
2038-sp_connector_context_class_init(SPConnectorContextClass *klass)
2039-{
2040- GObjectClass *object_class;
2041- SPEventContextClass *event_context_class;
2042-
2043- object_class = (GObjectClass *) klass;
2044- event_context_class = (SPEventContextClass *) klass;
2045-
2046- parent_class = (SPEventContextClass*)g_type_class_peek_parent(klass);
2047-
2048- object_class->dispose = sp_connector_context_dispose;
2049-
2050- event_context_class->setup = sp_connector_context_setup;
2051- event_context_class->set = sp_connector_context_set;
2052- event_context_class->finish = sp_connector_context_finish;
2053- event_context_class->root_handler = sp_connector_context_root_handler;
2054- event_context_class->item_handler = sp_connector_context_item_handler;
2055-}
2056-
2057-
2058-static void
2059-sp_connector_context_init(SPConnectorContext *cc)
2060-{
2061- SPEventContext *ec = SP_EVENT_CONTEXT(cc);
2062-
2063- ec->cursor_shape = cursor_connector_xpm;
2064- ec->hot_x = 1;
2065- ec->hot_y = 1;
2066- ec->xp = 0;
2067- ec->yp = 0;
2068-
2069- cc->mode = SP_CONNECTOR_CONTEXT_DRAWING_MODE;
2070- cc->knot_tip = 0;
2071-
2072- cc->red_color = 0xff00007f;
2073-
2074- cc->newconn = NULL;
2075- cc->newConnRef = NULL;
2076- cc->curvature = 0.0;
2077-
2078- cc->sel_changed_connection = sigc::connection();
2079-
2080- cc->active_shape = NULL;
2081- cc->active_shape_repr = NULL;
2082- cc->active_shape_layer_repr = NULL;
2083-
2084- cc->active_conn = NULL;
2085- cc->active_conn_repr = NULL;
2086-
2087- cc->active_handle = NULL;
2088-
2089- cc->selected_handle = NULL;
2090-
2091- cc->clickeditem = NULL;
2092- cc->clickedhandle = NULL;
2093-
2094- new (&cc->connpthandles) ConnectionPointMap();
2095-
2096- for (int i = 0; i < 2; ++i) {
2097- cc->endpt_handle[i] = NULL;
2098- cc->endpt_handler_id[i] = 0;
2099- }
2100- cc->shref = NULL;
2101- cc->scpid = NULL;
2102- cc->ehref = NULL;
2103- cc->ecpid = NULL;
2104- cc->npoints = 0;
2105- cc->state = SP_CONNECTOR_CONTEXT_IDLE;
2106-}
2107-
2108-
2109-static void
2110-sp_connector_context_dispose(GObject *object)
2111-{
2112- SPConnectorContext *cc = SP_CONNECTOR_CONTEXT(object);
2113-
2114- cc->sel_changed_connection.disconnect();
2115-
2116- if (!cc->connpthandles.empty()) {
2117- for (ConnectionPointMap::iterator it = cc->connpthandles.begin();
2118- it != cc->connpthandles.end(); ++it) {
2119- g_object_unref(it->first);
2120- }
2121- cc->connpthandles.clear();
2122- }
2123- cc->connpthandles.~ConnectionPointMap();
2124- for (int i = 0; i < 2; ++i) {
2125- if (cc->endpt_handle[1]) {
2126- g_object_unref(cc->endpt_handle[i]);
2127- cc->endpt_handle[i] = NULL;
2128- }
2129- }
2130- if (cc->shref) {
2131- g_free(cc->shref);
2132- cc->shref = NULL;
2133- }
2134- if (cc->scpid) {
2135- g_free(cc->scpid);
2136- cc->scpid = NULL;
2137- }
2138- if (cc->ehref) {
2139- g_free(cc->shref);
2140- cc->shref = NULL;
2141- }
2142- if (cc->ecpid) {
2143- g_free(cc->scpid);
2144- cc->scpid = NULL;
2145- }
2146- g_assert( cc->newConnRef == NULL );
2147-
2148- G_OBJECT_CLASS(parent_class)->dispose(object);
2149-}
2150-
2151-
2152-static void
2153-sp_connector_context_setup(SPEventContext *ec)
2154-{
2155- SPConnectorContext *cc = SP_CONNECTOR_CONTEXT(ec);
2156- SPDesktop *dt = ec->desktop;
2157-
2158- if (((SPEventContextClass *) parent_class)->setup) {
2159- ((SPEventContextClass *) parent_class)->setup(ec);
2160- }
2161-
2162- cc->selection = sp_desktop_selection(dt);
2163-
2164- cc->sel_changed_connection.disconnect();
2165- cc->sel_changed_connection = cc->selection->connectChanged(
2166- sigc::bind(sigc::ptr_fun(&cc_selection_changed),
2167- (gpointer) cc));
2168-
2169- /* Create red bpath */
2170- cc->red_bpath = sp_canvas_bpath_new(sp_desktop_sketch(ec->desktop), NULL);
2171- sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(cc->red_bpath), cc->red_color,
2172- 1.0, SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT);
2173- sp_canvas_bpath_set_fill(SP_CANVAS_BPATH(cc->red_bpath), 0x00000000,
2174- SP_WIND_RULE_NONZERO);
2175- /* Create red curve */
2176- cc->red_curve = new SPCurve();
2177-
2178- /* Create green curve */
2179- cc->green_curve = new SPCurve();
2180-
2181- // Notice the initial selection.
2182- cc_selection_changed(cc->selection, (gpointer) cc);
2183-
2184- cc->within_tolerance = false;
2185-
2186- sp_event_context_read(ec, "curvature");
2187- sp_event_context_read(ec, "orthogonal");
2188- sp_event_context_read(ec, "mode");
2189- cc->knot_tip = cc->mode == SP_CONNECTOR_CONTEXT_DRAWING_MODE ? cc_knot_tips[0] : cc_knot_tips[1];
2190- Inkscape::Preferences *prefs = Inkscape::Preferences::get();
2191- if (prefs->getBool("/tools/connector/selcue", 0)) {
2192- ec->enableSelectionCue();
2193- }
2194-
2195- // Make sure we see all enter events for canvas items,
2196- // even if a mouse button is depressed.
2197- dt->canvas->gen_all_enter_events = true;
2198-}
2199-
2200-
2201-static void
2202-sp_connector_context_set(SPEventContext *ec, Inkscape::Preferences::Entry *val)
2203-{
2204- SPConnectorContext *cc = SP_CONNECTOR_CONTEXT(ec);
2205-
2206- /* fixme: Proper error handling for non-numeric data. Use a locale-independent function like
2207- * g_ascii_strtod (or a thin wrapper that does the right thing for invalid values inf/nan). */
2208- Glib::ustring name = val->getEntryName();
2209- if ( name == "curvature" ) {
2210- cc->curvature = val->getDoubleLimited(); // prevents NaN and +/-Inf from messing up
2211- }
2212- else if ( name == "orthogonal" ) {
2213- cc->isOrthogonal = val->getBool();
2214- }
2215- else if ( name == "mode")
2216- {
2217- sp_connector_context_switch_mode(ec, val->getBool() ? SP_CONNECTOR_CONTEXT_EDITING_MODE : SP_CONNECTOR_CONTEXT_DRAWING_MODE);
2218- }
2219-}
2220-
2221-void sp_connector_context_switch_mode(SPEventContext* ec, unsigned int newMode)
2222-{
2223- SPConnectorContext *cc = SP_CONNECTOR_CONTEXT(ec);
2224-
2225- cc->mode = newMode;
2226- if ( cc->mode == SP_CONNECTOR_CONTEXT_DRAWING_MODE )
2227- {
2228- ec->cursor_shape = cursor_connector_xpm;
2229- cc->knot_tip = cc_knot_tips[0];
2230- if (cc->selected_handle)
2231- cc_deselect_handle( cc->selected_handle );
2232- cc->selected_handle = NULL;
2233- // Show all default connection points
2234-
2235- }
2236- else if ( cc->mode == SP_CONNECTOR_CONTEXT_EDITING_MODE )
2237- {
2238- ec->cursor_shape = cursor_node_xpm;
2239- cc->knot_tip = cc_knot_tips[1];
2240-/* if (cc->active_shape)
2241- {
2242- cc->selection->set( SP_OBJECT( cc->active_shape ) );
2243- }
2244- else
2245- {
2246- SPItem* item = cc->selection->singleItem();
2247- if ( item )
2248- {
2249- cc_set_active_shape(cc, item);
2250- cc->selection->set( SP_OBJECT( item ) );
2251- }
2252- }*/
2253- }
2254- sp_event_context_update_cursor(ec);
2255-
2256-}
2257-
2258-
2259-static void
2260-sp_connector_context_finish(SPEventContext *ec)
2261-{
2262- SPConnectorContext *cc = SP_CONNECTOR_CONTEXT(ec);
2263-
2264- spcc_connector_finish(cc);
2265- cc->state = SP_CONNECTOR_CONTEXT_IDLE;
2266-
2267- if (((SPEventContextClass *) parent_class)->finish) {
2268- ((SPEventContextClass *) parent_class)->finish(ec);
2269- }
2270-
2271- if (cc->selection) {
2272- cc->selection = NULL;
2273- }
2274- cc_clear_active_shape(cc);
2275- cc_clear_active_conn(cc);
2276-
2277- // Restore the default event generating behaviour.
2278- SPDesktop *desktop = SP_EVENT_CONTEXT_DESKTOP(ec);
2279- desktop->canvas->gen_all_enter_events = false;
2280-}
2281-
2282-
2283-//-----------------------------------------------------------------------------
2284-
2285-
2286-static void
2287-cc_clear_active_shape(SPConnectorContext *cc)
2288-{
2289- if (cc->active_shape == NULL) {
2290- return;
2291- }
2292- g_assert( cc->active_shape_repr );
2293- g_assert( cc->active_shape_layer_repr );
2294-
2295- cc->active_shape = NULL;
2296-
2297- if (cc->active_shape_repr) {
2298- sp_repr_remove_listener_by_data(cc->active_shape_repr, cc);
2299- Inkscape::GC::release(cc->active_shape_repr);
2300- cc->active_shape_repr = NULL;
2301-
2302- sp_repr_remove_listener_by_data(cc->active_shape_layer_repr, cc);
2303- Inkscape::GC::release(cc->active_shape_layer_repr);
2304- cc->active_shape_layer_repr = NULL;
2305- }
2306-
2307- // Hide the connection points if they exist.
2308- if (cc->connpthandles.size()) {
2309- for (ConnectionPointMap::iterator it = cc->connpthandles.begin();
2310- it != cc->connpthandles.end(); ++it) {
2311- sp_knot_hide(it->first);
2312- }
2313- }
2314-}
2315-
2316-
2317-static void
2318-cc_clear_active_conn(SPConnectorContext *cc)
2319-{
2320- if (cc->active_conn == NULL) {
2321- return;
2322- }
2323- g_assert( cc->active_conn_repr );
2324-
2325- cc->active_conn = NULL;
2326-
2327- if (cc->active_conn_repr) {
2328- sp_repr_remove_listener_by_data(cc->active_conn_repr, cc);
2329- Inkscape::GC::release(cc->active_conn_repr);
2330- cc->active_conn_repr = NULL;
2331- }
2332-
2333- // Hide the endpoint handles.
2334- for (int i = 0; i < 2; ++i) {
2335- if (cc->endpt_handle[i]) {
2336- sp_knot_hide(cc->endpt_handle[i]);
2337- }
2338- }
2339-}
2340-
2341-
2342-static bool
2343-conn_pt_handle_test(SPConnectorContext *cc, Geom::Point& p, gchar **href, gchar **cpid)
2344-{
2345- // TODO: this will need to change when there are more connection
2346- // points available for each shape.
2347-
2348- if (cc->active_handle && (cc->connpthandles.find(cc->active_handle) != cc->connpthandles.end()))
2349- {
2350- p = cc->active_handle->pos;
2351- const ConnectionPoint& cp = cc->connpthandles[cc->active_handle];
2352- *href = g_strdup_printf("#%s", cc->active_shape->getId());
2353- *cpid = g_strdup_printf("%c%d", cp.type == ConnPointDefault ? 'd' : 'u' , cp.id);
2354- return true;
2355- }
2356- *href = NULL;
2357- *cpid = NULL;
2358- return false;
2359-}
2360-
2361-static void
2362-cc_select_handle(SPKnot* knot)
2363-{
2364- knot->setShape(SP_KNOT_SHAPE_SQUARE);
2365- knot->setSize(10);
2366- knot->setAnchor(GTK_ANCHOR_CENTER);
2367- knot->setFill(0x0000ffff, 0x0000ffff, 0x0000ffff);
2368- sp_knot_update_ctrl(knot);
2369-}
2370-
2371-static void
2372-cc_deselect_handle(SPKnot* knot)
2373-{
2374- knot->setShape(SP_KNOT_SHAPE_SQUARE);
2375- knot->setSize(8);
2376- knot->setAnchor(GTK_ANCHOR_CENTER);
2377- knot->setFill(0xffffff00, 0xff0000ff, 0xff0000ff);
2378- sp_knot_update_ctrl(knot);
2379-}
2380-
2381-static gint
2382-sp_connector_context_item_handler(SPEventContext *event_context, SPItem *item, GdkEvent *event)
2383-{
2384- gint ret = FALSE;
2385-
2386- SPDesktop *desktop = event_context->desktop;
2387-
2388- SPConnectorContext *cc = SP_CONNECTOR_CONTEXT(event_context);
2389-
2390- Geom::Point p(event->button.x, event->button.y);
2391-
2392- switch (event->type) {
2393- case GDK_BUTTON_RELEASE:
2394- if (event->button.button == 1 && !event_context->space_panning) {
2395- if ((cc->state == SP_CONNECTOR_CONTEXT_DRAGGING) &&
2396- (event_context->within_tolerance))
2397- {
2398- spcc_reset_colors(cc);
2399- cc->state = SP_CONNECTOR_CONTEXT_IDLE;
2400- }
2401- if (cc->state != SP_CONNECTOR_CONTEXT_IDLE) {
2402- // Doing something else like rerouting.
2403- break;
2404- }
2405- // find out clicked item, honoring Alt
2406- SPItem *item = sp_event_context_find_item(desktop,
2407- p, event->button.state & GDK_MOD1_MASK, FALSE);
2408-
2409- if (event->button.state & GDK_SHIFT_MASK) {
2410- cc->selection->toggle(item);
2411- } else {
2412- cc->selection->set(item);
2413- if ( cc->mode == SP_CONNECTOR_CONTEXT_EDITING_MODE && cc->selected_handle )
2414- {
2415- cc_deselect_handle( cc->selected_handle );
2416- cc->selected_handle = NULL;
2417- }
2418- /* When selecting a new item,
2419- do not allow showing connection points
2420- on connectors. (yet?)
2421- */
2422- if ( item != cc->active_shape && !cc_item_is_connector( item ) )
2423- cc_set_active_shape( cc, item );
2424- }
2425- ret = TRUE;
2426-
2427- }
2428- break;
2429- case GDK_ENTER_NOTIFY:
2430- {
2431- if (cc->mode == SP_CONNECTOR_CONTEXT_DRAWING_MODE || (cc->mode == SP_CONNECTOR_CONTEXT_EDITING_MODE && !cc->selected_handle))
2432- {
2433- if (cc_item_is_shape(item)) {
2434-
2435- // I don't really understand what the above does,
2436- // so I commented it.
2437- // This is a shape, so show connection point(s).
2438- /* if (!(cc->active_shape)
2439- // Don't show handle for another handle.
2440- // || (cc->connpthandles.find((SPKnot*) item) != cc->connpthandles.end())
2441- )
2442- {
2443- cc_set_active_shape(cc, item);
2444- }*/
2445- cc_set_active_shape(cc, item);
2446- }
2447- ret = TRUE;
2448- }
2449- break;
2450- }
2451- default:
2452- break;
2453- }
2454-
2455- return ret;
2456-}
2457-
2458-
2459-gint
2460-sp_connector_context_root_handler(SPEventContext *ec, GdkEvent *event)
2461-{
2462- SPConnectorContext *const cc = SP_CONNECTOR_CONTEXT(ec);
2463-
2464- gint ret = FALSE;
2465-
2466- switch (event->type) {
2467- case GDK_BUTTON_PRESS:
2468- ret = connector_handle_button_press(cc, event->button);
2469- break;
2470-
2471- case GDK_MOTION_NOTIFY:
2472- ret = connector_handle_motion_notify(cc, event->motion);
2473- break;
2474-
2475- case GDK_BUTTON_RELEASE:
2476- ret = connector_handle_button_release(cc, event->button);
2477- break;
2478- case GDK_KEY_PRESS:
2479- ret = connector_handle_key_press(cc, get_group0_keyval (&event->key));
2480- break;
2481-
2482- default:
2483- break;
2484- }
2485-
2486- if (!ret) {
2487- gint (*const parent_root_handler)(SPEventContext *, GdkEvent *)
2488- = ((SPEventContextClass *) parent_class)->root_handler;
2489- if (parent_root_handler) {
2490- ret = parent_root_handler(ec, event);
2491- }
2492- }
2493-
2494- return ret;
2495-}
2496-
2497-
2498-static gint
2499-connector_handle_button_press(SPConnectorContext *const cc, GdkEventButton const &bevent)
2500-{
2501- Geom::Point const event_w(bevent.x, bevent.y);
2502- /* Find desktop coordinates */
2503- Geom::Point p = cc->desktop->w2d(event_w);
2504- SPEventContext *event_context = SP_EVENT_CONTEXT(cc);
2505-
2506- gint ret = FALSE;
2507- if ( cc->mode == SP_CONNECTOR_CONTEXT_DRAWING_MODE )
2508- {
2509- if ( bevent.button == 1 && !event_context->space_panning ) {
2510-
2511- SPDesktop *desktop = SP_EVENT_CONTEXT_DESKTOP(cc);
2512-
2513- if (Inkscape::have_viable_layer(desktop, cc->_message_context) == false) {
2514- return TRUE;
2515- }
2516-
2517- Geom::Point const event_w(bevent.x,
2518- bevent.y);
2519-// connector_drag_origin_w = event_w;
2520- cc->xp = bevent.x;
2521- cc->yp = bevent.y;
2522- cc->within_tolerance = true;
2523-
2524- Geom::Point const event_dt = cc->desktop->w2d(event_w);
2525-
2526- SnapManager &m = cc->desktop->namedview->snap_manager;
2527- m.setup(cc->desktop);
2528-
2529- switch (cc->state) {
2530- case SP_CONNECTOR_CONTEXT_STOP:
2531- /* This is allowed, if we just canceled curve */
2532- case SP_CONNECTOR_CONTEXT_IDLE:
2533- {
2534- if ( cc->npoints == 0 ) {
2535- cc_clear_active_conn(cc);
2536-
2537- SP_EVENT_CONTEXT_DESKTOP(cc)->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Creating new connector"));
2538-
2539- /* Set start anchor */
2540- /* Create green anchor */
2541- Geom::Point p = event_dt;
2542-
2543- // Test whether we clicked on a connection point
2544- bool found = conn_pt_handle_test(cc, p, &cc->shref, &cc->scpid);
2545-
2546- if (!found) {
2547- // This is the first point, so just snap it to the grid
2548- // as there's no other points to go off.
2549- m.freeSnapReturnByRef(p, Inkscape::SNAPSOURCE_OTHER_HANDLE);
2550- }
2551- spcc_connector_set_initial_point(cc, p);
2552-
2553- }
2554- cc->state = SP_CONNECTOR_CONTEXT_DRAGGING;
2555- ret = TRUE;
2556- break;
2557- }
2558- case SP_CONNECTOR_CONTEXT_DRAGGING:
2559- {
2560- // This is the second click of a connector creation.
2561- m.freeSnapReturnByRef(p, Inkscape::SNAPSOURCE_OTHER_HANDLE);
2562-
2563- spcc_connector_set_subsequent_point(cc, p);
2564- spcc_connector_finish_segment(cc, p);
2565- // Test whether we clicked on a connection point
2566- /*bool found = */conn_pt_handle_test(cc, p, &cc->ehref, &cc->ecpid);
2567- if (cc->npoints != 0) {
2568- spcc_connector_finish(cc);
2569- }
2570- cc_set_active_conn(cc, cc->newconn);
2571- cc->state = SP_CONNECTOR_CONTEXT_IDLE;
2572- ret = TRUE;
2573- break;
2574- }
2575- case SP_CONNECTOR_CONTEXT_CLOSE:
2576- {
2577- g_warning("Button down in CLOSE state");
2578- break;
2579- }
2580- default:
2581- break;
2582- }
2583- } else if (bevent.button == 3) {
2584- if (cc->state == SP_CONNECTOR_CONTEXT_REROUTING) {
2585- // A context menu is going to be triggered here,
2586- // so end the rerouting operation.
2587- cc_connector_rerouting_finish(cc, &p);
2588-
2589- cc->state = SP_CONNECTOR_CONTEXT_IDLE;
2590-
2591- // Don't set ret to TRUE, so we drop through to the
2592- // parent handler which will open the context menu.
2593- }
2594- else if (cc->npoints != 0) {
2595- spcc_connector_finish(cc);
2596- cc->state = SP_CONNECTOR_CONTEXT_IDLE;
2597- ret = TRUE;
2598- }
2599- }
2600- }
2601- else if ( cc->mode == SP_CONNECTOR_CONTEXT_EDITING_MODE )
2602- {
2603- if ( bevent.button == 1 && !event_context->space_panning )
2604- {
2605- // Initialize variables in case of dragging
2606-
2607- SPDesktop *desktop = SP_EVENT_CONTEXT_DESKTOP(cc);
2608-
2609- if (Inkscape::have_viable_layer(desktop, cc->_message_context) == false) {
2610- return TRUE;
2611- }
2612-
2613- cc->xp = bevent.x;
2614- cc->yp = bevent.y;
2615- cc->within_tolerance = true;
2616-
2617- ConnectionPointMap::iterator const& active_knot_it = cc->connpthandles.find( cc->active_handle );
2618-
2619- switch (cc->state)
2620- {
2621- case SP_CONNECTOR_CONTEXT_IDLE:
2622- if ( active_knot_it != cc->connpthandles.end() )
2623- {
2624- // We do not allow selecting and, thereby, moving default knots
2625- if ( active_knot_it->second.type != ConnPointDefault)
2626- {
2627- if (cc->selected_handle != cc->active_handle)
2628- {
2629- if ( cc->selected_handle )
2630- cc_deselect_handle( cc->selected_handle );
2631- cc->selected_handle = cc->active_handle;
2632- cc_select_handle( cc->selected_handle );
2633- }
2634- }
2635- else
2636- // Just ignore the default connection point
2637- return FALSE;
2638- }
2639- else
2640- if ( cc->selected_handle )
2641- {
2642- cc_deselect_handle( cc->selected_handle );
2643- cc->selected_handle = NULL;
2644- }
2645-
2646- if ( cc->selected_handle )
2647- {
2648- cc->state = SP_CONNECTOR_CONTEXT_DRAGGING;
2649- cc->selection->set( SP_OBJECT( cc->active_shape ) );
2650- }
2651-
2652- ret = TRUE;
2653- break;
2654- // Dragging valid because of the way we create
2655- // new connection points.
2656- case SP_CONNECTOR_CONTEXT_DRAGGING:
2657- // Do nothing.
2658- ret = TRUE;
2659- break;
2660- }
2661- }
2662- }
2663- return ret;
2664-}
2665-
2666-
2667-static gint
2668-connector_handle_motion_notify(SPConnectorContext *const cc, GdkEventMotion const &mevent)
2669-{
2670- gint ret = FALSE;
2671- SPEventContext *event_context = SP_EVENT_CONTEXT(cc);
2672- Inkscape::Preferences *prefs = Inkscape::Preferences::get();
2673-
2674- if (event_context->space_panning || mevent.state & GDK_BUTTON2_MASK || mevent.state & GDK_BUTTON3_MASK) {
2675- // allow middle-button scrolling
2676- return FALSE;
2677- }
2678-
2679- Geom::Point const event_w(mevent.x, mevent.y);
2680-
2681- if (cc->within_tolerance) {
2682- cc->tolerance = prefs->getIntLimited("/options/dragtolerance/value", 0, 0, 100);
2683- if ( ( abs( (gint) mevent.x - cc->xp ) < cc->tolerance ) &&
2684- ( abs( (gint) mevent.y - cc->yp ) < cc->tolerance ) ) {
2685- return FALSE; // Do not drag if we're within tolerance from origin.
2686- }
2687- }
2688- // Once the user has moved farther than tolerance from the original location
2689- // (indicating they intend to move the object, not click), then always process
2690- // the motion notify coordinates as given (no snapping back to origin)
2691- cc->within_tolerance = false;
2692-
2693- SPDesktop *const dt = cc->desktop;
2694-
2695- /* Find desktop coordinates */
2696- Geom::Point p = dt->w2d(event_w);
2697-
2698- if ( cc->mode == SP_CONNECTOR_CONTEXT_DRAWING_MODE )
2699- {
2700- SnapManager &m = dt->namedview->snap_manager;
2701- m.setup(dt);
2702-
2703- switch (cc->state) {
2704- case SP_CONNECTOR_CONTEXT_DRAGGING:
2705- {
2706- gobble_motion_events(mevent.state);
2707- // This is movement during a connector creation.
2708- if ( cc->npoints > 0 ) {
2709- m.freeSnapReturnByRef(p, Inkscape::SNAPSOURCE_OTHER_HANDLE);
2710- cc->selection->clear();
2711- spcc_connector_set_subsequent_point(cc, p);
2712- ret = TRUE;
2713- }
2714- break;
2715- }
2716- case SP_CONNECTOR_CONTEXT_REROUTING:
2717- {
2718- gobble_motion_events(GDK_BUTTON1_MASK);
2719- g_assert( SP_IS_PATH(cc->clickeditem));
2720-
2721- m.freeSnapReturnByRef(p, Inkscape::SNAPSOURCE_OTHER_HANDLE);
2722-
2723- // Update the hidden path
2724- Geom::Matrix i2d = sp_item_i2d_affine(cc->clickeditem);
2725- Geom::Matrix d2i = i2d.inverse();
2726- SPPath *path = SP_PATH(cc->clickeditem);
2727- SPCurve *curve = path->original_curve ? path->original_curve : path->curve;
2728- if (cc->clickedhandle == cc->endpt_handle[0]) {
2729- Geom::Point o = cc->endpt_handle[1]->pos;
2730- curve->stretch_endpoints(p * d2i, o * d2i);
2731- }
2732- else {
2733- Geom::Point o = cc->endpt_handle[0]->pos;
2734- curve->stretch_endpoints(o * d2i, p * d2i);
2735- }
2736- sp_conn_reroute_path_immediate(path);
2737-
2738- // Copy this to the temporary visible path
2739- cc->red_curve = path->original_curve ?
2740- path->original_curve->copy() : path->curve->copy();
2741- cc->red_curve->transform(i2d);
2742-
2743- sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(cc->red_bpath), cc->red_curve);
2744- ret = TRUE;
2745- break;
2746- }
2747- case SP_CONNECTOR_CONTEXT_STOP:
2748- /* This is perfectly valid */
2749- break;
2750- default:
2751- if (!sp_event_context_knot_mouseover(cc)) {
2752- m.preSnap(Inkscape::SnapCandidatePoint(p, Inkscape::SNAPSOURCE_OTHER_HANDLE));
2753- }
2754- break;
2755- }
2756- }
2757- else if ( cc->mode == SP_CONNECTOR_CONTEXT_EDITING_MODE )
2758- {
2759- switch ( cc->state )
2760- {
2761- case SP_CONNECTOR_CONTEXT_DRAGGING:
2762- sp_knot_set_position(cc->selected_handle, p, 0);
2763- ret = TRUE;
2764- break;
2765- case SP_CONNECTOR_CONTEXT_NEWCONNPOINT:
2766- sp_knot_set_position(cc->selected_handle, p, 0);
2767- ret = TRUE;
2768- break;
2769- }
2770- }
2771-
2772- return ret;
2773-}
2774-
2775-
2776-static gint
2777-connector_handle_button_release(SPConnectorContext *const cc, GdkEventButton const &revent)
2778-{
2779- gint ret = FALSE;
2780- SPEventContext *event_context = SP_EVENT_CONTEXT(cc);
2781- if ( revent.button == 1 && !event_context->space_panning ) {
2782-
2783- SPDesktop *desktop = SP_EVENT_CONTEXT_DESKTOP(cc);
2784- SPDocument *doc = sp_desktop_document(desktop);
2785-
2786- SnapManager &m = desktop->namedview->snap_manager;
2787- m.setup(desktop);
2788-
2789- Geom::Point const event_w(revent.x, revent.y);
2790-
2791- /* Find desktop coordinates */
2792- Geom::Point p = cc->desktop->w2d(event_w);
2793- if ( cc->mode == SP_CONNECTOR_CONTEXT_DRAWING_MODE )
2794- {
2795- switch (cc->state) {
2796- //case SP_CONNECTOR_CONTEXT_POINT:
2797- case SP_CONNECTOR_CONTEXT_DRAGGING:
2798- {
2799- m.freeSnapReturnByRef(p, Inkscape::SNAPSOURCE_OTHER_HANDLE);
2800-
2801- if (cc->within_tolerance)
2802- {
2803- spcc_connector_finish_segment(cc, p);
2804- return TRUE;
2805- }
2806- // Connector has been created via a drag, end it now.
2807- spcc_connector_set_subsequent_point(cc, p);
2808- spcc_connector_finish_segment(cc, p);
2809- // Test whether we clicked on a connection point
2810- /*bool found = */conn_pt_handle_test(cc, p, &cc->ehref, &cc->ecpid);
2811- if (cc->npoints != 0) {
2812- spcc_connector_finish(cc);
2813- }
2814- cc_set_active_conn(cc, cc->newconn);
2815- cc->state = SP_CONNECTOR_CONTEXT_IDLE;
2816- break;
2817- }
2818- case SP_CONNECTOR_CONTEXT_REROUTING:
2819- {
2820- m.freeSnapReturnByRef(p, Inkscape::SNAPSOURCE_OTHER_HANDLE);
2821- cc_connector_rerouting_finish(cc, &p);
2822-
2823- sp_document_ensure_up_to_date(doc);
2824- cc->state = SP_CONNECTOR_CONTEXT_IDLE;
2825- return TRUE;
2826- break;
2827- }
2828- case SP_CONNECTOR_CONTEXT_STOP:
2829- /* This is allowed, if we just cancelled curve */
2830- break;
2831- default:
2832- break;
2833- }
2834- ret = TRUE;
2835- }
2836- else if ( cc->mode == SP_CONNECTOR_CONTEXT_EDITING_MODE )
2837- {
2838- switch ( cc->state )
2839- {
2840- case SP_CONNECTOR_CONTEXT_DRAGGING:
2841-
2842- if (!cc->within_tolerance)
2843- {
2844- m.freeSnapReturnByRef(p, Inkscape::SNAPSOURCE_OTHER_HANDLE);
2845- sp_knot_set_position(cc->selected_handle, p, 0);
2846- ConnectionPoint& cp = cc->connpthandles[cc->selected_handle];
2847- cp.pos = p * sp_item_dt2i_affine(cc->active_shape);
2848- cc->active_shape->avoidRef->updateConnectionPoint(cp);
2849- }
2850-
2851- cc->state = SP_CONNECTOR_CONTEXT_IDLE;
2852- ret = TRUE;
2853- break;
2854-
2855-
2856- case SP_CONNECTOR_CONTEXT_NEWCONNPOINT:
2857- m.freeSnapReturnByRef(p, Inkscape::SNAPSOURCE_OTHER_HANDLE);
2858-
2859- sp_knot_set_position(cc->selected_handle, p, 0);
2860-
2861- ConnectionPoint cp;
2862- cp.type = ConnPointUserDefined;
2863- cp.pos = p * sp_item_dt2i_affine(cc->active_shape);
2864- cp.dir = Avoid::ConnDirAll;
2865- g_object_unref(cc->selected_handle);
2866- cc->active_shape->avoidRef->addConnectionPoint(cp);
2867- sp_document_ensure_up_to_date(doc);
2868- for (ConnectionPointMap::iterator it = cc->connpthandles.begin(); it != cc->connpthandles.end(); ++it)
2869- if (it->second.type == ConnPointUserDefined && it->second.id == cp.id)
2870- {
2871- cc->selected_handle = it->first;
2872- break;
2873- }
2874- cc_select_handle( cc->selected_handle );
2875- cc->state = SP_CONNECTOR_CONTEXT_IDLE;
2876- ret = TRUE;
2877- break;
2878- }
2879- }
2880- }
2881-
2882-
2883- return ret;
2884-}
2885-
2886-
2887-static gint
2888-connector_handle_key_press(SPConnectorContext *const cc, guint const keyval)
2889-{
2890- gint ret = FALSE;
2891- /* fixme: */
2892- if ( cc->mode == SP_CONNECTOR_CONTEXT_DRAWING_MODE )
2893- {
2894- switch (keyval) {
2895- case GDK_Return:
2896- case GDK_KP_Enter:
2897- if (cc->npoints != 0) {
2898- spcc_connector_finish(cc);
2899- cc->state = SP_CONNECTOR_CONTEXT_IDLE;
2900- ret = TRUE;
2901- }
2902- break;
2903- case GDK_Escape:
2904- if (cc->state == SP_CONNECTOR_CONTEXT_REROUTING) {
2905-
2906- SPDesktop *desktop = SP_EVENT_CONTEXT_DESKTOP(cc);
2907- SPDocument *doc = sp_desktop_document(desktop);
2908-
2909- cc_connector_rerouting_finish(cc, NULL);
2910-
2911- sp_document_undo(doc);
2912-
2913- cc->state = SP_CONNECTOR_CONTEXT_IDLE;
2914- desktop->messageStack()->flash( Inkscape::NORMAL_MESSAGE,
2915- _("Connector endpoint drag cancelled."));
2916- ret = TRUE;
2917- }
2918- else if (cc->npoints != 0) {
2919- // if drawing, cancel, otherwise pass it up for deselecting
2920- cc->state = SP_CONNECTOR_CONTEXT_STOP;
2921- spcc_reset_colors(cc);
2922- ret = TRUE;
2923- }
2924- break;
2925- default:
2926- break;
2927- }
2928- }
2929- else if ( cc->mode == SP_CONNECTOR_CONTEXT_EDITING_MODE )
2930- {
2931- switch ( cc->state )
2932- {
2933- case SP_CONNECTOR_CONTEXT_DRAGGING:
2934- if ( keyval == GDK_Escape )
2935- {
2936- // Cancel connection point dragging
2937-
2938- // Obtain original position
2939- ConnectionPoint const& cp = cc->connpthandles[cc->selected_handle];
2940- SPDesktop *desktop = SP_EVENT_CONTEXT_DESKTOP(cc);
2941- const Geom::Matrix& i2doc = sp_item_i2doc_affine(cc->active_shape);
2942- sp_knot_set_position(cc->selected_handle, cp.pos * i2doc * desktop->doc2dt(), 0);
2943- cc->state = SP_CONNECTOR_CONTEXT_IDLE;
2944- desktop->messageStack()->flash( Inkscape::NORMAL_MESSAGE,
2945- _("Connection point drag cancelled."));
2946- ret = TRUE;
2947- }
2948- else if ( keyval == GDK_Return || keyval == GDK_KP_Enter )
2949- {
2950- // Put connection point at current position
2951-
2952- SPDesktop *desktop = SP_EVENT_CONTEXT_DESKTOP(cc);
2953- SnapManager &m = desktop->namedview->snap_manager;
2954- m.setup(desktop);
2955- Geom::Point p = cc->selected_handle->pos;
2956-// SPEventContext* event_context = SP_EVENT_CONTEXT( cc );
2957-
2958- if (!cc->within_tolerance)
2959- {
2960- m.freeSnapReturnByRef(p, Inkscape::SNAPSOURCE_OTHER_HANDLE);
2961- sp_knot_set_position(cc->selected_handle, p, 0);
2962- ConnectionPoint& cp = cc->connpthandles[cc->selected_handle];
2963- cp.pos = p * sp_item_dt2i_affine(cc->active_shape);
2964- cc->active_shape->avoidRef->updateConnectionPoint(cp);
2965- }
2966-
2967- cc->state = SP_CONNECTOR_CONTEXT_IDLE;
2968- ret = TRUE;
2969- }
2970- break;
2971- case SP_CONNECTOR_CONTEXT_NEWCONNPOINT:
2972- if ( keyval == GDK_Escape )
2973- {
2974- // Just destroy the knot
2975- g_object_unref( cc->selected_handle );
2976- cc->selected_handle = NULL;
2977- cc->state = SP_CONNECTOR_CONTEXT_IDLE;
2978- ret = TRUE;
2979- }
2980- else if ( keyval == GDK_Return || keyval == GDK_KP_Enter )
2981- {
2982- SPDesktop *desktop = SP_EVENT_CONTEXT_DESKTOP(cc);
2983- SPDocument *doc = sp_desktop_document(desktop);
2984- SnapManager &m = desktop->namedview->snap_manager;
2985- m.setup(desktop);
2986- Geom::Point p = cc->selected_handle->pos;
2987-
2988- m.freeSnapReturnByRef(p, Inkscape::SNAPSOURCE_OTHER_HANDLE);
2989-
2990- sp_knot_set_position(cc->selected_handle, p, 0);
2991-
2992- ConnectionPoint cp;
2993- cp.type = ConnPointUserDefined;
2994- cp.pos = p * sp_item_dt2i_affine(cc->active_shape);
2995- cp.dir = Avoid::ConnDirAll;
2996- g_object_unref(cc->selected_handle);
2997- cc->active_shape->avoidRef->addConnectionPoint(cp);
2998- sp_document_ensure_up_to_date(doc);
2999- for (ConnectionPointMap::iterator it = cc->connpthandles.begin(); it != cc->connpthandles.end(); ++it)
3000- if (it->second.type == ConnPointUserDefined && it->second.id == cp.id)
3001- {
3002- cc->selected_handle = it->first;
3003- break;
3004- }
3005- cc_select_handle( cc->selected_handle );
3006- cc->state = SP_CONNECTOR_CONTEXT_IDLE;
3007- ret = TRUE;
3008- }
3009-
3010- break;
3011- case SP_CONNECTOR_CONTEXT_IDLE:
3012- if ( keyval == GDK_Delete && cc->selected_handle )
3013- {
3014- cc->active_shape->avoidRef->deleteConnectionPoint(cc->connpthandles[cc->selected_handle]);
3015- cc->selected_handle = NULL;
3016- ret = TRUE;
3017- }
3018-
3019- break;
3020- }
3021- }
3022-
3023- return ret;
3024-}
3025-
3026-
3027-static void
3028-cc_connector_rerouting_finish(SPConnectorContext *const cc, Geom::Point *const p)
3029-{
3030- SPDesktop *desktop = SP_EVENT_CONTEXT_DESKTOP(cc);
3031- SPDocument *doc = sp_desktop_document(desktop);
3032-
3033- // Clear the temporary path:
3034- cc->red_curve->reset();
3035- sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(cc->red_bpath), NULL);
3036-
3037- if (p != NULL)
3038- {
3039- // Test whether we clicked on a connection point
3040- gchar *shape_label, *cpid;
3041- bool found = conn_pt_handle_test(cc, *p, &shape_label, &cpid);
3042-
3043- if (found) {
3044- if (cc->clickedhandle == cc->endpt_handle[0]) {
3045- sp_object_setAttribute(cc->clickeditem,
3046- "inkscape:connection-start", shape_label, false);
3047- sp_object_setAttribute(cc->clickeditem,
3048- "inkscape:connection-start-point", cpid, false);
3049- }
3050- else {
3051- sp_object_setAttribute(cc->clickeditem,
3052- "inkscape:connection-end", shape_label, false);
3053- sp_object_setAttribute(cc->clickeditem,
3054- "inkscape:connection-end-point", cpid, false);
3055- }
3056- g_free(shape_label);
3057- }
3058- }
3059- cc->clickeditem->setHidden(false);
3060- sp_conn_reroute_path_immediate(SP_PATH(cc->clickeditem));
3061- cc->clickeditem->updateRepr();
3062- sp_document_done(doc, SP_VERB_CONTEXT_CONNECTOR,
3063- _("Reroute connector"));
3064- cc_set_active_conn(cc, cc->clickeditem);
3065-}
3066-
3067-
3068-static void
3069-spcc_reset_colors(SPConnectorContext *cc)
3070-{
3071- /* Red */
3072- cc->red_curve->reset();
3073- sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(cc->red_bpath), NULL);
3074-
3075- cc->green_curve->reset();
3076- cc->npoints = 0;
3077-}
3078-
3079-
3080-static void
3081-spcc_connector_set_initial_point(SPConnectorContext *const cc, Geom::Point const p)
3082-{
3083- g_assert( cc->npoints == 0 );
3084-
3085- cc->p[0] = p;
3086- cc->p[1] = p;
3087- cc->npoints = 2;
3088- sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(cc->red_bpath), NULL);
3089-}
3090-
3091-
3092-static void
3093-spcc_connector_set_subsequent_point(SPConnectorContext *const cc, Geom::Point const p)
3094-{
3095- g_assert( cc->npoints != 0 );
3096-
3097- SPDesktop *dt = cc->desktop;
3098- Geom::Point o = dt->dt2doc(cc->p[0]);
3099- Geom::Point d = dt->dt2doc(p);
3100- Avoid::Point src(o[Geom::X], o[Geom::Y]);
3101- Avoid::Point dst(d[Geom::X], d[Geom::Y]);
3102-
3103- if (!cc->newConnRef) {
3104- Avoid::Router *router = sp_desktop_document(dt)->router;
3105- cc->newConnRef = new Avoid::ConnRef(router);
3106- cc->newConnRef->setEndpoint(Avoid::VertID::src, src);
3107- if (cc->isOrthogonal)
3108- cc->newConnRef->setRoutingType(Avoid::ConnType_Orthogonal);
3109- else
3110- cc->newConnRef->setRoutingType(Avoid::ConnType_PolyLine);
3111- }
3112- // Set new endpoint.
3113- cc->newConnRef->setEndpoint(Avoid::VertID::tar, dst);
3114- // Immediately generate new routes for connector.
3115- cc->newConnRef->makePathInvalid();
3116- cc->newConnRef->router()->processTransaction();
3117- // Recreate curve from libavoid route.
3118- recreateCurve( cc->red_curve, cc->newConnRef, cc->curvature );
3119- cc->red_curve->transform(dt->doc2dt());
3120- sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(cc->red_bpath), cc->red_curve);
3121-}
3122-
3123-
3124-/**
3125- * Concats red, blue and green.
3126- * If any anchors are defined, process these, optionally removing curves from white list
3127- * Invoke _flush_white to write result back to object.
3128- */
3129-static void
3130-spcc_concat_colors_and_flush(SPConnectorContext *cc)
3131-{
3132- SPCurve *c = cc->green_curve;
3133- cc->green_curve = new SPCurve();
3134-
3135- cc->red_curve->reset();
3136- sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(cc->red_bpath), NULL);
3137-
3138- if (c->is_empty()) {
3139- c->unref();
3140- return;
3141- }
3142-
3143- spcc_flush_white(cc, c);
3144-
3145- c->unref();
3146-}
3147-
3148-
3149-/*
3150- * Flushes white curve(s) and additional curve into object
3151- *
3152- * No cleaning of colored curves - this has to be done by caller
3153- * No rereading of white data, so if you cannot rely on ::modified, do it in caller
3154- *
3155- */
3156-
3157-static void
3158-spcc_flush_white(SPConnectorContext *cc, SPCurve *gc)
3159-{
3160- SPCurve *c;
3161-
3162- if (gc) {
3163- c = gc;
3164- c->ref();
3165- } else {
3166- return;
3167- }
3168-
3169- /* Now we have to go back to item coordinates at last */
3170- c->transform(SP_EVENT_CONTEXT_DESKTOP(cc)->dt2doc());
3171-
3172- SPDesktop *desktop = SP_EVENT_CONTEXT_DESKTOP(cc);
3173- SPDocument *doc = sp_desktop_document(desktop);
3174- Inkscape::XML::Document *xml_doc = sp_document_repr_doc(doc);
3175-
3176- if ( c && !c->is_empty() ) {
3177- /* We actually have something to write */
3178-
3179- Inkscape::XML::Node *repr = xml_doc->createElement("svg:path");
3180- /* Set style */
3181- sp_desktop_apply_style_tool(desktop, repr, "/tools/connector", false);
3182-
3183- gchar *str = sp_svg_write_path( c->get_pathvector() );
3184- g_assert( str != NULL );
3185- repr->setAttribute("d", str);
3186- g_free(str);
3187-
3188- /* Attach repr */
3189- cc->newconn = SP_ITEM(desktop->currentLayer()->appendChildRepr(repr));
3190- cc->newconn->transform = sp_item_i2doc_affine(SP_ITEM(desktop->currentLayer())).inverse();
3191-
3192- bool connection = false;
3193- sp_object_setAttribute(cc->newconn, "inkscape:connector-type",
3194- cc->isOrthogonal ? "orthogonal" : "polyline", false);
3195- sp_object_setAttribute(cc->newconn, "inkscape:connector-curvature",
3196- Glib::Ascii::dtostr(cc->curvature).c_str(), false);
3197- if (cc->shref)
3198- {
3199- sp_object_setAttribute(cc->newconn, "inkscape:connection-start",
3200- cc->shref, false);
3201- if (cc->scpid)
3202- sp_object_setAttribute(cc->newconn, "inkscape:connection-start-point",
3203- cc->scpid, false);
3204- connection = true;
3205- }
3206-
3207- if (cc->ehref)
3208- {
3209- sp_object_setAttribute(cc->newconn, "inkscape:connection-end",
3210- cc->ehref, false);
3211- if (cc->ecpid)
3212- sp_object_setAttribute(cc->newconn, "inkscape:connection-end-point",
3213- cc->ecpid, false);
3214- connection = true;
3215- }
3216- // Process pending updates.
3217- cc->newconn->updateRepr();
3218- sp_document_ensure_up_to_date(doc);
3219-
3220- if (connection) {
3221- // Adjust endpoints to shape edge.
3222- sp_conn_reroute_path_immediate(SP_PATH(cc->newconn));
3223- cc->newconn->updateRepr();
3224- }
3225-
3226- // Only set the selection after we are finished with creating the attributes of
3227- // the connector. Otherwise, the selection change may alter the defaults for
3228- // values like curvature in the connector context, preventing subsequent lookup
3229- // of their original values.
3230- cc->selection->set(repr);
3231- Inkscape::GC::release(repr);
3232- }
3233-
3234- c->unref();
3235-
3236- sp_document_done(doc, SP_VERB_CONTEXT_CONNECTOR, _("Create connector"));
3237-}
3238-
3239-
3240-static void
3241-spcc_connector_finish_segment(SPConnectorContext *const cc, Geom::Point const /*p*/)
3242-{
3243- if (!cc->red_curve->is_empty()) {
3244- cc->green_curve->append_continuous(cc->red_curve, 0.0625);
3245-
3246- cc->p[0] = cc->p[3];
3247- cc->p[1] = cc->p[4];
3248- cc->npoints = 2;
3249-
3250- cc->red_curve->reset();
3251- }
3252-}
3253-
3254-
3255-static void
3256-spcc_connector_finish(SPConnectorContext *const cc)
3257-{
3258- SPDesktop *const desktop = cc->desktop;
3259- desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Finishing connector"));
3260-
3261- cc->red_curve->reset();
3262- spcc_concat_colors_and_flush(cc);
3263-
3264- cc->npoints = 0;
3265-
3266- if (cc->newConnRef) {
3267- cc->newConnRef->removeFromGraph();
3268- delete cc->newConnRef;
3269- cc->newConnRef = NULL;
3270- }
3271-}
3272-
3273-
3274-static gboolean
3275-cc_generic_knot_handler(SPCanvasItem *, GdkEvent *event, SPKnot *knot)
3276-{
3277- g_assert (knot != NULL);
3278-
3279- g_object_ref(knot);
3280-
3281- SPConnectorContext *cc = SP_CONNECTOR_CONTEXT(
3282- knot->desktop->event_context);
3283-
3284- gboolean consumed = FALSE;
3285-
3286- gchar* knot_tip = knot->tip ? knot->tip : cc->knot_tip;
3287- switch (event->type) {
3288- case GDK_ENTER_NOTIFY:
3289- sp_knot_set_flag(knot, SP_KNOT_MOUSEOVER, TRUE);
3290-
3291- cc->active_handle = knot;
3292- if (knot_tip)
3293- {
3294- knot->desktop->event_context->defaultMessageContext()->set(
3295- Inkscape::NORMAL_MESSAGE, knot_tip);
3296- }
3297-
3298- consumed = TRUE;
3299- break;
3300- case GDK_LEAVE_NOTIFY:
3301- sp_knot_set_flag(knot, SP_KNOT_MOUSEOVER, FALSE);
3302-
3303- cc->active_handle = NULL;
3304-
3305- if (knot_tip) {
3306- knot->desktop->event_context->defaultMessageContext()->clear();
3307- }
3308-
3309- consumed = TRUE;
3310- break;
3311- default:
3312- break;
3313- }
3314-
3315- g_object_unref(knot);
3316-
3317- return consumed;
3318-}
3319-
3320-
3321-static gboolean
3322-endpt_handler(SPKnot */*knot*/, GdkEvent *event, SPConnectorContext *cc)
3323-{
3324- g_assert( SP_IS_CONNECTOR_CONTEXT(cc) );
3325-
3326- gboolean consumed = FALSE;
3327-
3328- switch (event->type) {
3329- case GDK_BUTTON_PRESS:
3330- g_assert( (cc->active_handle == cc->endpt_handle[0]) ||
3331- (cc->active_handle == cc->endpt_handle[1]) );
3332- if (cc->state == SP_CONNECTOR_CONTEXT_IDLE) {
3333- cc->clickeditem = cc->active_conn;
3334- cc->clickedhandle = cc->active_handle;
3335- cc_clear_active_conn(cc);
3336- cc->state = SP_CONNECTOR_CONTEXT_REROUTING;
3337-
3338- // Disconnect from attached shape
3339- unsigned ind = (cc->active_handle == cc->endpt_handle[0]) ? 0 : 1;
3340- sp_conn_end_detach(cc->clickeditem, ind);
3341-
3342- Geom::Point origin;
3343- if (cc->clickedhandle == cc->endpt_handle[0]) {
3344- origin = cc->endpt_handle[1]->pos;
3345- }
3346- else {
3347- origin = cc->endpt_handle[0]->pos;
3348- }
3349-
3350- // Show the red path for dragging.
3351- cc->red_curve = SP_PATH(cc->clickeditem)->original_curve ? SP_PATH(cc->clickeditem)->original_curve->copy() : SP_PATH(cc->clickeditem)->curve->copy();
3352- Geom::Matrix i2d = sp_item_i2d_affine(cc->clickeditem);
3353- cc->red_curve->transform(i2d);
3354- sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(cc->red_bpath), cc->red_curve);
3355-
3356- cc->clickeditem->setHidden(true);
3357-
3358- // The rest of the interaction rerouting the connector is
3359- // handled by the context root handler.
3360- consumed = TRUE;
3361- }
3362- break;
3363- default:
3364- break;
3365- }
3366-
3367- return consumed;
3368-}
3369-
3370-static void cc_active_shape_add_knot(SPDesktop* desktop, SPItem* item, ConnectionPointMap &cphandles, ConnectionPoint& cp)
3371-{
3372- SPKnot *knot = sp_knot_new(desktop, 0);
3373-
3374- knot->setShape(SP_KNOT_SHAPE_SQUARE);
3375- knot->setSize(8);
3376- knot->setAnchor(GTK_ANCHOR_CENTER);
3377- knot->setFill(0xffffff00, 0xff0000ff, 0xff0000ff);
3378- sp_knot_update_ctrl(knot);
3379-
3380- // We don't want to use the standard knot handler.
3381- g_signal_handler_disconnect(G_OBJECT(knot->item),
3382- knot->_event_handler_id);
3383- knot->_event_handler_id = 0;
3384-
3385- gtk_signal_connect(GTK_OBJECT(knot->item), "event",
3386- GTK_SIGNAL_FUNC(cc_generic_knot_handler), knot);
3387- sp_knot_set_position(knot, item->avoidRef->getConnectionPointPos(cp.type, cp.id) * desktop->doc2dt(), 0);
3388- sp_knot_show(knot);
3389- cphandles[knot] = cp;
3390-}
3391-
3392-static void cc_set_active_shape(SPConnectorContext *cc, SPItem *item)
3393-{
3394- g_assert(item != NULL );
3395-
3396- std::map<int, ConnectionPoint>* connpts = &item->avoidRef->connection_points;
3397-
3398- if (cc->active_shape != item)
3399- {
3400- // The active shape has changed
3401- // Rebuild everything
3402- cc->active_shape = item;
3403- // Remove existing active shape listeners
3404- if (cc->active_shape_repr) {
3405- sp_repr_remove_listener_by_data(cc->active_shape_repr, cc);
3406- Inkscape::GC::release(cc->active_shape_repr);
3407-
3408- sp_repr_remove_listener_by_data(cc->active_shape_layer_repr, cc);
3409- Inkscape::GC::release(cc->active_shape_layer_repr);
3410- }
3411-
3412- // Listen in case the active shape changes
3413- cc->active_shape_repr = SP_OBJECT_REPR(item);
3414- if (cc->active_shape_repr) {
3415- Inkscape::GC::anchor(cc->active_shape_repr);
3416- sp_repr_add_listener(cc->active_shape_repr, &shape_repr_events, cc);
3417-
3418- cc->active_shape_layer_repr = cc->active_shape_repr->parent();
3419- Inkscape::GC::anchor(cc->active_shape_layer_repr);
3420- sp_repr_add_listener(cc->active_shape_layer_repr, &layer_repr_events, cc);
3421- }
3422-
3423-
3424- // Set the connection points.
3425- if ( cc->connpthandles.size() )
3426- // destroy the old list
3427- while (! cc->connpthandles.empty() )
3428- {
3429- g_object_unref(cc->connpthandles.begin()->first);
3430- cc->connpthandles.erase(cc->connpthandles.begin());
3431- }
3432- // build the new one
3433- if ( connpts->size() )
3434- for (std::map<int, ConnectionPoint>::iterator it = connpts->begin(); it != connpts->end(); ++it)
3435- cc_active_shape_add_knot(cc->desktop, item, cc->connpthandles, it->second);
3436-
3437- // Also add default connection points
3438- // For now, only centre default connection point will
3439- // be available
3440- ConnectionPoint centre;
3441- centre.type = ConnPointDefault;
3442- centre.id = ConnPointPosCC;
3443- cc_active_shape_add_knot(cc->desktop, item, cc->connpthandles, centre);
3444- }
3445- else
3446- {
3447- // The active shape didn't change
3448- // Update only the connection point knots
3449-
3450- // Ensure the item's connection_points map
3451- // has been updated
3452- sp_document_ensure_up_to_date(SP_OBJECT_DOCUMENT(item));
3453-
3454- std::set<int> seen;
3455- for ( ConnectionPointMap::iterator it = cc->connpthandles.begin(); it != cc->connpthandles.end() ;)
3456- {
3457- bool removed = false;
3458- if ( it->second.type == ConnPointUserDefined )
3459- {
3460- std::map<int, ConnectionPoint>::iterator p = connpts->find(it->second.id);
3461- if (p != connpts->end())
3462- {
3463- if ( it->second != p->second )
3464- // Connection point position has changed
3465- // Update knot position
3466- sp_knot_set_position(it->first,
3467- item->avoidRef->getConnectionPointPos(it->second.type, it->second.id) * cc->desktop->doc2dt(), 0);
3468- seen.insert(it->second.id);
3469- sp_knot_show(it->first);
3470- }
3471- else
3472- {
3473- // This connection point does no longer exist,
3474- // remove the knot
3475- ConnectionPointMap::iterator curr = it;
3476- ++it;
3477- g_object_unref( curr->first );
3478- cc->connpthandles.erase(curr);
3479- removed = true;
3480- }
3481- }
3482- else
3483- {
3484- // It's a default connection point
3485- // Just make sure it's position is correct
3486- sp_knot_set_position(it->first,
3487- item->avoidRef->getConnectionPointPos(it->second.type, it->second.id) * cc->desktop->doc2dt(), 0);
3488- sp_knot_show(it->first);
3489-
3490- }
3491- if ( !removed )
3492- ++it;
3493- }
3494- // Add knots for new connection points.
3495- if (connpts->size())
3496- for ( std::map<int, ConnectionPoint>::iterator it = connpts->begin(); it != connpts->end(); ++it )
3497- if ( seen.find(it->first) == seen.end() )
3498- // A new connection point has been added
3499- // to the shape. Add a knot for it.
3500- cc_active_shape_add_knot(cc->desktop, item, cc->connpthandles, it->second);
3501- }
3502-}
3503-
3504-
3505-static void
3506-cc_set_active_conn(SPConnectorContext *cc, SPItem *item)
3507-{
3508- g_assert( SP_IS_PATH(item) );
3509-
3510- SPCurve *curve = SP_PATH(item)->original_curve ? SP_PATH(item)->original_curve : SP_PATH(item)->curve;
3511- Geom::Matrix i2d = sp_item_i2d_affine(item);
3512-
3513- if (cc->active_conn == item)
3514- {
3515- if (curve->is_empty())
3516- {
3517- // Connector is invisible because it is clipped to the boundary of
3518- // two overlpapping shapes.
3519- sp_knot_hide(cc->endpt_handle[0]);
3520- sp_knot_hide(cc->endpt_handle[1]);
3521- }
3522- else
3523- {
3524- // Just adjust handle positions.
3525- Geom::Point startpt = *(curve->first_point()) * i2d;
3526- sp_knot_set_position(cc->endpt_handle[0], startpt, 0);
3527-
3528- Geom::Point endpt = *(curve->last_point()) * i2d;
3529- sp_knot_set_position(cc->endpt_handle[1], endpt, 0);
3530- }
3531-
3532- return;
3533- }
3534-
3535- cc->active_conn = item;
3536-
3537- // Remove existing active conn listeners
3538- if (cc->active_conn_repr) {
3539- sp_repr_remove_listener_by_data(cc->active_conn_repr, cc);
3540- Inkscape::GC::release(cc->active_conn_repr);
3541- cc->active_conn_repr = NULL;
3542- }
3543-
3544- // Listen in case the active conn changes
3545- cc->active_conn_repr = SP_OBJECT_REPR(item);
3546- if (cc->active_conn_repr) {
3547- Inkscape::GC::anchor(cc->active_conn_repr);
3548- sp_repr_add_listener(cc->active_conn_repr, &shape_repr_events, cc);
3549- }
3550-
3551- for (int i = 0; i < 2; ++i) {
3552-
3553- // Create the handle if it doesn't exist
3554- if ( cc->endpt_handle[i] == NULL ) {
3555- SPKnot *knot = sp_knot_new(cc->desktop,
3556- _("<b>Connector endpoint</b>: drag to reroute or connect to new shapes"));
3557-
3558- knot->setShape(SP_KNOT_SHAPE_SQUARE);
3559- knot->setSize(7);
3560- knot->setAnchor(GTK_ANCHOR_CENTER);
3561- knot->setFill(0xffffff00, 0xff0000ff, 0xff0000ff);
3562- knot->setStroke(0x000000ff, 0x000000ff, 0x000000ff);
3563- sp_knot_update_ctrl(knot);
3564-
3565- // We don't want to use the standard knot handler,
3566- // since we don't want this knot to be draggable.
3567- g_signal_handler_disconnect(G_OBJECT(knot->item),
3568- knot->_event_handler_id);
3569- knot->_event_handler_id = 0;
3570-
3571- gtk_signal_connect(GTK_OBJECT(knot->item), "event",
3572- GTK_SIGNAL_FUNC(cc_generic_knot_handler), knot);
3573-
3574- cc->endpt_handle[i] = knot;
3575- }
3576-
3577- // Remove any existing handlers
3578- if (cc->endpt_handler_id[i]) {
3579- g_signal_handlers_disconnect_by_func(
3580- G_OBJECT(cc->endpt_handle[i]->item),
3581- (void*)G_CALLBACK(endpt_handler), (gpointer) cc );
3582- cc->endpt_handler_id[i] = 0;
3583- }
3584-
3585- // Setup handlers for connector endpoints, this is
3586- // is as 'after' so that cc_generic_knot_handler is
3587- // triggered first for any endpoint.
3588- cc->endpt_handler_id[i] = g_signal_connect_after(
3589- G_OBJECT(cc->endpt_handle[i]->item), "event",
3590- G_CALLBACK(endpt_handler), cc);
3591- }
3592-
3593- if (curve->is_empty())
3594- {
3595- // Connector is invisible because it is clipped to the boundary
3596- // of two overlpapping shapes. So, it doesn't need endpoints.
3597- return;
3598- }
3599-
3600- Geom::Point startpt = *(curve->first_point()) * i2d;
3601- sp_knot_set_position(cc->endpt_handle[0], startpt, 0);
3602-
3603- Geom::Point endpt = *(curve->last_point()) * i2d;
3604- sp_knot_set_position(cc->endpt_handle[1], endpt, 0);
3605-
3606- sp_knot_show(cc->endpt_handle[0]);
3607- sp_knot_show(cc->endpt_handle[1]);
3608-}
3609-
3610-void cc_create_connection_point(SPConnectorContext* cc)
3611-{
3612- if (cc->active_shape && cc->state == SP_CONNECTOR_CONTEXT_IDLE)
3613- {
3614- if (cc->selected_handle)
3615- {
3616- cc_deselect_handle( cc->selected_handle );
3617- }
3618- SPKnot *knot = sp_knot_new(cc->desktop, 0);
3619- // We do not process events on this knot.
3620- g_signal_handler_disconnect(G_OBJECT(knot->item),
3621- knot->_event_handler_id);
3622- knot->_event_handler_id = 0;
3623-
3624- cc_select_handle( knot );
3625- cc->selected_handle = knot;
3626- sp_knot_show(cc->selected_handle);
3627- cc->state = SP_CONNECTOR_CONTEXT_NEWCONNPOINT;
3628- }
3629-}
3630-
3631-void cc_remove_connection_point(SPConnectorContext* cc)
3632-{
3633- if (cc->selected_handle && cc->state == SP_CONNECTOR_CONTEXT_IDLE )
3634- {
3635- cc->active_shape->avoidRef->deleteConnectionPoint(cc->connpthandles[cc->selected_handle]);
3636- cc->selected_handle = NULL;
3637- }
3638-}
3639-
3640-static bool cc_item_is_shape(SPItem *item)
3641-{
3642- if (SP_IS_PATH(item)) {
3643- SPCurve *curve = (SP_SHAPE(item))->curve;
3644- if ( curve && !(curve->is_closed()) ) {
3645- // Open paths are connectors.
3646- return false;
3647- }
3648- }
3649- else if (SP_IS_TEXT(item) || SP_IS_FLOWTEXT(item)) {
3650- Inkscape::Preferences *prefs = Inkscape::Preferences::get();
3651- if (prefs->getBool("/tools/connector/ignoretext", true)) {
3652- // Don't count text as a shape we can connect connector to.
3653- return false;
3654- }
3655- }
3656- return true;
3657-}
3658-
3659-
3660-bool cc_item_is_connector(SPItem *item)
3661-{
3662- if (SP_IS_PATH(item)) {
3663- bool closed = SP_PATH(item)->original_curve ? SP_PATH(item)->original_curve->is_closed() : SP_PATH(item)->curve->is_closed();
3664- if (SP_PATH(item)->connEndPair.isAutoRoutingConn() && !closed) {
3665- // To be considered a connector, an object must be a non-closed
3666- // path that is marked with a "inkscape:connector-type" attribute.
3667- return true;
3668- }
3669- }
3670- return false;
3671-}
3672-
3673-
3674-void cc_selection_set_avoid(bool const set_avoid)
3675-{
3676- SPDesktop *desktop = inkscape_active_desktop();
3677- if (desktop == NULL) {
3678- return;
3679- }
3680-
3681- SPDocument *document = sp_desktop_document(desktop);
3682-
3683- Inkscape::Selection *selection = sp_desktop_selection(desktop);
3684-
3685- GSList *l = (GSList *) selection->itemList();
3686-
3687- int changes = 0;
3688-
3689- while (l) {
3690- SPItem *item = (SPItem *) l->data;
3691-
3692- char const *value = (set_avoid) ? "true" : NULL;
3693-
3694- if (cc_item_is_shape(item)) {
3695- sp_object_setAttribute(item, "inkscape:connector-avoid",
3696- value, false);
3697- item->avoidRef->handleSettingChange();
3698- changes++;
3699- }
3700-
3701- l = l->next;
3702- }
3703-
3704- if (changes == 0) {
3705- desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE,
3706- _("Select <b>at least one non-connector object</b>."));
3707- return;
3708- }
3709-
3710- char *event_desc = (set_avoid) ?
3711- _("Make connectors avoid selected objects") :
3712- _("Make connectors ignore selected objects");
3713- sp_document_done(document, SP_VERB_CONTEXT_CONNECTOR, event_desc);
3714-}
3715-
3716-
3717-static void
3718-cc_selection_changed(Inkscape::Selection *selection, gpointer data)
3719-{
3720- SPConnectorContext *cc = SP_CONNECTOR_CONTEXT(data);
3721- //SPEventContext *ec = SP_EVENT_CONTEXT(cc);
3722-
3723- SPItem *item = selection->singleItem();
3724-
3725- if (cc->active_conn == item)
3726- {
3727- // Nothing to change.
3728- return;
3729- }
3730- if (item == NULL)
3731- {
3732- cc_clear_active_conn(cc);
3733- return;
3734- }
3735-
3736- if (cc_item_is_connector(item)) {
3737- cc_set_active_conn(cc, item);
3738- }
3739-}
3740-
3741-
3742-static void
3743-shape_event_attr_deleted(Inkscape::XML::Node */*repr*/, Inkscape::XML::Node *child,
3744- Inkscape::XML::Node */*ref*/, gpointer data)
3745-{
3746- g_assert(data);
3747- SPConnectorContext *cc = SP_CONNECTOR_CONTEXT(data);
3748-
3749- if (child == cc->active_shape_repr) {
3750- // The active shape has been deleted. Clear active shape.
3751- cc_clear_active_shape(cc);
3752- }
3753-}
3754-
3755-
3756-static void
3757-shape_event_attr_changed(Inkscape::XML::Node *repr, gchar const *name,
3758- gchar const */*old_value*/, gchar const */*new_value*/,
3759- bool /*is_interactive*/, gpointer data)
3760-{
3761- g_assert(data);
3762- SPConnectorContext *cc = SP_CONNECTOR_CONTEXT(data);
3763-
3764- // Look for changes that result in onscreen movement.
3765- if (!strcmp(name, "d") || !strcmp(name, "x") || !strcmp(name, "y") ||
3766- !strcmp(name, "width") || !strcmp(name, "height") ||
3767- !strcmp(name, "transform"))
3768- {
3769- if (repr == cc->active_shape_repr) {
3770- // Active shape has moved. Clear active shape.
3771- cc_clear_active_shape(cc);
3772- }
3773- else if (repr == cc->active_conn_repr) {
3774- // The active conn has been moved.
3775- // Set it again, which just sets new handle positions.
3776- cc_set_active_conn(cc, cc->active_conn);
3777- }
3778- }
3779- else
3780- if ( !strcmp(name, "inkscape:connection-points") )
3781- if (repr == cc->active_shape_repr)
3782- // The connection points of the active shape
3783- // have changed. Update them.
3784- cc_set_active_shape(cc, cc->active_shape);
3785-}
3786-
3787-
3788-/*
3789- Local Variables:
3790- mode:c++
3791- c-file-style:"stroustrup"
3792- c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
3793- indent-tabs-mode:nil
3794- fill-column:99
3795- End:
3796-*/
3797-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :
3798
3799=== removed directory '.pc/0004-Fix_FTBFS_on_gcc-4.8.patch/src/extension'
3800=== removed file '.pc/0004-Fix_FTBFS_on_gcc-4.8.patch/src/extension/effect.cpp'
3801--- .pc/0004-Fix_FTBFS_on_gcc-4.8.patch/src/extension/effect.cpp 2013-07-02 17:25:52 +0000
3802+++ .pc/0004-Fix_FTBFS_on_gcc-4.8.patch/src/extension/effect.cpp 1970-01-01 00:00:00 +0000
3803@@ -1,409 +0,0 @@
3804-/*
3805- * Authors:
3806- * Ted Gould <ted@gould.cx>
3807- *
3808- * Copyright (C) 2002-2007 Authors
3809- *
3810- * Released under GNU GPL, read the file 'COPYING' for more information
3811- */
3812-
3813-#include "inkscape-private.h"
3814-#include "helper/action.h"
3815-#include "ui/view/view.h"
3816-#include "desktop-handles.h"
3817-#include "selection.h"
3818-#include "sp-namedview.h"
3819-#include "desktop.h"
3820-#include "implementation/implementation.h"
3821-#include "effect.h"
3822-#include "execution-env.h"
3823-#include "timer.h"
3824-
3825-
3826-
3827-/* Inkscape::Extension::Effect */
3828-
3829-namespace Inkscape {
3830-namespace Extension {
3831-
3832-Effect * Effect::_last_effect = NULL;
3833-Inkscape::XML::Node * Effect::_effects_list = NULL;
3834-Inkscape::XML::Node * Effect::_filters_list = NULL;
3835-
3836-#define EFFECTS_LIST "effects-list"
3837-#define FILTERS_LIST "filters-list"
3838-
3839-Effect::Effect (Inkscape::XML::Node * in_repr, Implementation::Implementation * in_imp)
3840- : Extension(in_repr, in_imp),
3841- _id_noprefs(Glib::ustring(get_id()) + ".noprefs"),
3842- _name_noprefs(Glib::ustring(get_name()) + _(" (No preferences)")),
3843- _verb(get_id(), get_name(), NULL, NULL, this, true),
3844- _verb_nopref(_id_noprefs.c_str(), _name_noprefs.c_str(), NULL, NULL, this, false),
3845- _menu_node(NULL), _workingDialog(true),
3846- _prefDialog(NULL)
3847-{
3848- Inkscape::XML::Node * local_effects_menu = NULL;
3849-
3850- // This is a weird hack
3851- if (!strcmp(this->get_id(), "org.inkscape.filter.dropshadow"))
3852- return;
3853-
3854- bool hidden = false;
3855-
3856- no_doc = false;
3857- no_live_preview = false;
3858-
3859- if (repr != NULL) {
3860-
3861- for (Inkscape::XML::Node *child = sp_repr_children(repr); child != NULL; child = child->next()) {
3862- if (!strcmp(child->name(), INKSCAPE_EXTENSION_NS "effect")) {
3863- if (child->attribute("needs-document") && !strcmp(child->attribute("needs-document"), "false")) {
3864- no_doc = true;
3865- }
3866- if (child->attribute("needs-live-preview") && !strcmp(child->attribute("needs-live-preview"), "false")) {
3867- no_live_preview = true;
3868- }
3869- for (Inkscape::XML::Node *effect_child = sp_repr_children(child); effect_child != NULL; effect_child = effect_child->next()) {
3870- if (!strcmp(effect_child->name(), INKSCAPE_EXTENSION_NS "effects-menu")) {
3871- // printf("Found local effects menu in %s\n", this->get_name());
3872- local_effects_menu = sp_repr_children(effect_child);
3873- if (effect_child->attribute("hidden") && !strcmp(effect_child->attribute("hidden"), "true")) {
3874- hidden = true;
3875- }
3876- }
3877- if (!strcmp(effect_child->name(), INKSCAPE_EXTENSION_NS "menu-name") ||
3878- !strcmp(effect_child->name(), INKSCAPE_EXTENSION_NS "_menu-name")) {
3879- // printf("Found local effects menu in %s\n", this->get_name());
3880- _verb.set_name(sp_repr_children(effect_child)->content());
3881- }
3882- if (!strcmp(effect_child->name(), INKSCAPE_EXTENSION_NS "menu-tip") ||
3883- !strcmp(effect_child->name(), INKSCAPE_EXTENSION_NS "_menu-tip")) {
3884- // printf("Found local effects menu in %s\n", this->get_name());
3885- _verb.set_tip(sp_repr_children(effect_child)->content());
3886- }
3887- } // children of "effect"
3888- break; // there can only be one effect
3889- } // find "effect"
3890- } // children of "inkscape-extension"
3891- } // if we have an XML file
3892-
3893- if (INKSCAPE != NULL) {
3894- if (_effects_list == NULL)
3895- _effects_list = find_menu(inkscape_get_menus(INKSCAPE), EFFECTS_LIST);
3896- if (_filters_list == NULL)
3897- _filters_list = find_menu(inkscape_get_menus(INKSCAPE), FILTERS_LIST);
3898- }
3899-
3900- if ((_effects_list != NULL || _filters_list != NULL)) {
3901- Inkscape::XML::Document *xml_doc;
3902- xml_doc = _effects_list->document();
3903- _menu_node = xml_doc->createElement("verb");
3904- _menu_node->setAttribute("verb-id", this->get_id(), false);
3905-
3906- if (!hidden) {
3907- if (_filters_list &&
3908- local_effects_menu &&
3909- local_effects_menu->attribute("name") &&
3910- !strcmp(local_effects_menu->attribute("name"), ("Filters"))) {
3911- merge_menu(_filters_list->parent(), _filters_list, sp_repr_children(local_effects_menu), _menu_node);
3912- } else if (_effects_list) {
3913- merge_menu(_effects_list->parent(), _effects_list, local_effects_menu, _menu_node);
3914- }
3915- }
3916- }
3917-
3918- return;
3919-}
3920-
3921-void
3922-Effect::merge_menu (Inkscape::XML::Node * base,
3923- Inkscape::XML::Node * start,
3924- Inkscape::XML::Node * patern,
3925- Inkscape::XML::Node * mergee) {
3926- Glib::ustring mergename;
3927- Inkscape::XML::Node * tomerge = NULL;
3928- Inkscape::XML::Node * submenu = NULL;
3929-
3930- /* printf("Merge menu with '%s' '%s' '%s'\n",
3931- base != NULL ? base->name() : "NULL",
3932- patern != NULL ? patern->name() : "NULL",
3933- mergee != NULL ? mergee->name() : "NULL"); */
3934-
3935- if (patern == NULL) {
3936- // Merge the verb name
3937- tomerge = mergee;
3938- mergename = _(this->get_name());
3939- } else {
3940- gchar const * menuname = patern->attribute("name");
3941- if (menuname == NULL) menuname = patern->attribute("_name");
3942- if (menuname == NULL) return;
3943-
3944- Inkscape::XML::Document *xml_doc;
3945- xml_doc = base->document();
3946- tomerge = xml_doc->createElement("submenu");
3947- tomerge->setAttribute("name", menuname, false);
3948-
3949- mergename = _(menuname);
3950- }
3951-
3952- int position = -1;
3953-
3954- if (start != NULL) {
3955- Inkscape::XML::Node * menupass;
3956- for (menupass = start; menupass != NULL && strcmp(menupass->name(), "separator"); menupass = menupass->next()) {
3957- gchar const * compare_char = NULL;
3958- if (!strcmp(menupass->name(), "verb")) {
3959- gchar const * verbid = menupass->attribute("verb-id");
3960- Inkscape::Verb * verb = Inkscape::Verb::getbyid(verbid);
3961- if (verb == NULL) {
3962- g_warning("Unable to find verb '%s' which is referred to in the menus.", verbid);
3963- continue;
3964- }
3965- compare_char = verb->get_name();
3966- } else if (!strcmp(menupass->name(), "submenu")) {
3967- compare_char = menupass->attribute("name");
3968- if (compare_char == NULL)
3969- compare_char = menupass->attribute("_name");
3970- }
3971-
3972- position = menupass->position() + 1;
3973-
3974- /* This will cause us to skip tags we don't understand */
3975- if (compare_char == NULL) {
3976- continue;
3977- }
3978-
3979- Glib::ustring compare(_(compare_char));
3980-
3981- if (mergename == compare) {
3982- Inkscape::GC::release(tomerge);
3983- tomerge = NULL;
3984- submenu = menupass;
3985- break;
3986- }
3987-
3988- if (mergename < compare) {
3989- position = menupass->position();
3990- break;
3991- }
3992- } // for menu items
3993- } // start != NULL
3994-
3995- if (tomerge != NULL) {
3996- base->appendChild(tomerge);
3997- Inkscape::GC::release(tomerge);
3998- if (position != -1)
3999- tomerge->setPosition(position);
4000- }
4001-
4002- if (patern != NULL) {
4003- if (submenu == NULL)
4004- submenu = tomerge;
4005- merge_menu(submenu, submenu->firstChild(), patern->firstChild(), mergee);
4006- }
4007-
4008- return;
4009-}
4010-
4011-Effect::~Effect (void)
4012-{
4013- if (get_last_effect() == this)
4014- set_last_effect(NULL);
4015- if (_menu_node)
4016- Inkscape::GC::release(_menu_node);
4017- return;
4018-}
4019-
4020-bool
4021-Effect::check (void)
4022-{
4023- if (!Extension::check()) {
4024- /** \todo Check to see if parent has this as its only child,
4025- if so, delete it too */
4026- if (_menu_node != NULL)
4027- sp_repr_unparent(_menu_node);
4028- _menu_node = NULL;
4029- return false;
4030- }
4031- return true;
4032-}
4033-
4034-bool
4035-Effect::prefs (Inkscape::UI::View::View * doc)
4036-{
4037- if (_prefDialog != NULL) {
4038- _prefDialog->raise();
4039- return true;
4040- }
4041-
4042- if (param_visible_count() == 0) {
4043- effect(doc);
4044- return true;
4045- }
4046-
4047- if (!loaded())
4048- set_state(Extension::STATE_LOADED);
4049- if (!loaded()) return false;
4050-
4051- _prefDialog = new PrefDialog(this->get_name(), this->get_help(), NULL, this);
4052- _prefDialog->show();
4053-
4054- return true;
4055-}
4056-
4057-/**
4058- \brief The function that 'does' the effect itself
4059- \param doc The Inkscape::UI::View::View to do the effect on
4060-
4061- This function first insures that the extension is loaded, and if not,
4062- loads it. It then calls the implemention to do the actual work. It
4063- also resets the last effect pointer to be this effect. Finally, it
4064- executes a \c sp_document_done to commit the changes to the undo
4065- stack.
4066-*/
4067-void
4068-Effect::effect (Inkscape::UI::View::View * doc)
4069-{
4070- //printf("Execute effect\n");
4071- if (!loaded())
4072- set_state(Extension::STATE_LOADED);
4073- if (!loaded()) return;
4074-
4075-
4076- ExecutionEnv executionEnv(this, doc);
4077- timer->lock();
4078- executionEnv.run();
4079- if (executionEnv.wait()) {
4080- executionEnv.commit();
4081- } else {
4082- executionEnv.cancel();
4083- }
4084- timer->unlock();
4085-
4086- return;
4087-}
4088-
4089-/** \brief Sets which effect was called last
4090- \param in_effect The effect that has been called
4091-
4092- This function sets the static variable \c _last_effect and it
4093- ensures that the last effect verb is sensitive.
4094-
4095- If the \c in_effect variable is \c NULL then the last effect
4096- verb is made insesitive.
4097-*/
4098-void
4099-Effect::set_last_effect (Effect * in_effect)
4100-{
4101- gchar const * verb_id = in_effect->get_verb()->get_id();
4102- gchar const * help_id_prefix = "org.inkscape.help.";
4103-
4104- // We don't want these "effects" to register as the last effect,
4105- // this wouldn't be helpful to the user who selects a real effect,
4106- // then goes to the help file (implemented as an effect), then goes
4107- // back to the effect, only to see it written over by the help file
4108- // selection.
4109-
4110- // This snippet should fix this bug:
4111- // https://bugs.launchpad.net/inkscape/+bug/600671
4112- if (strncmp(verb_id, help_id_prefix, strlen(help_id_prefix)) == 0) return;
4113-
4114- if (in_effect == NULL) {
4115- Inkscape::Verb::get(SP_VERB_EFFECT_LAST)->sensitive(NULL, false);
4116- Inkscape::Verb::get(SP_VERB_EFFECT_LAST_PREF)->sensitive(NULL, false);
4117- } else if (_last_effect == NULL) {
4118- Inkscape::Verb::get(SP_VERB_EFFECT_LAST)->sensitive(NULL, true);
4119- Inkscape::Verb::get(SP_VERB_EFFECT_LAST_PREF)->sensitive(NULL, true);
4120- }
4121-
4122- _last_effect = in_effect;
4123- return;
4124-}
4125-
4126-Inkscape::XML::Node *
4127-Effect::find_menu (Inkscape::XML::Node * menustruct, const gchar *name)
4128-{
4129- if (menustruct == NULL) return false;
4130- for (Inkscape::XML::Node * child = menustruct;
4131- child != NULL;
4132- child = child->next()) {
4133- if (!strcmp(child->name(), name)) {
4134- return child;
4135- }
4136- Inkscape::XML::Node * firstchild = child->firstChild();
4137- if (firstchild != NULL) {
4138- Inkscape::XML::Node *found = find_menu (firstchild, name);
4139- if (found)
4140- return found;
4141- }
4142- }
4143- return NULL;
4144-}
4145-
4146-
4147-Gtk::VBox *
4148-Effect::get_info_widget(void)
4149-{
4150- return Extension::get_info_widget();
4151-}
4152-
4153-void
4154-Effect::set_pref_dialog (PrefDialog * prefdialog)
4155-{
4156- _prefDialog = prefdialog;
4157- return;
4158-}
4159-
4160-/** \brief Create an action for a \c EffectVerb
4161- \param view Which view the action should be created for
4162- \return The built action.
4163-
4164- Calls \c make_action_helper with the \c vector.
4165-*/
4166-SPAction *
4167-Effect::EffectVerb::make_action (Inkscape::UI::View::View * view)
4168-{
4169- return make_action_helper(view, &vector, static_cast<void *>(this));
4170-}
4171-
4172-/** \brief Decode the verb code and take appropriate action */
4173-void
4174-Effect::EffectVerb::perform( SPAction *action, void * data, void */*pdata*/ )
4175-{
4176- Inkscape::UI::View::View * current_view = sp_action_get_view(action);
4177-// SPDocument * current_document = current_view->doc;
4178- Effect::EffectVerb * ev = reinterpret_cast<Effect::EffectVerb *>(data);
4179- Effect * effect = ev->_effect;
4180-
4181- if (effect == NULL) return;
4182- if (current_view == NULL) return;
4183-
4184- if (ev->_showPrefs) {
4185- effect->prefs(current_view);
4186- } else {
4187- effect->effect(current_view);
4188- }
4189-
4190- return;
4191-}
4192-
4193-/**
4194- * Action vector to define functions called if a staticly defined file verb
4195- * is called.
4196- */
4197-SPActionEventVector Effect::EffectVerb::vector =
4198- {{NULL}, Effect::EffectVerb::perform, NULL, NULL, NULL, NULL};
4199-
4200-
4201-} } /* namespace Inkscape, Extension */
4202-
4203-/*
4204- Local Variables:
4205- mode:c++
4206- c-file-style:"stroustrup"
4207- c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
4208- indent-tabs-mode:nil
4209- fill-column:99
4210- End:
4211-*/
4212-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :
4213
4214=== removed file '.pc/0004-Fix_FTBFS_on_gcc-4.8.patch/src/gradient-drag.cpp'
4215--- .pc/0004-Fix_FTBFS_on_gcc-4.8.patch/src/gradient-drag.cpp 2013-07-02 17:25:52 +0000
4216+++ .pc/0004-Fix_FTBFS_on_gcc-4.8.patch/src/gradient-drag.cpp 1970-01-01 00:00:00 +0000
4217@@ -1,2216 +0,0 @@
4218-/*
4219- * On-canvas gradient dragging
4220- *
4221- * Authors:
4222- * bulia byak <buliabyak@users.sf.net>
4223- * Johan Engelen <j.b.c.engelen@ewi.utwente.nl>
4224- * Jon A. Cruz <jon@joncruz.org>
4225- *
4226- * Copyright (C) 2007 Johan Engelen
4227- * Copyright (C) 2005,2010 Authors
4228- *
4229- * Released under GNU GPL, read the file 'COPYING' for more information
4230- */
4231-
4232-#ifdef HAVE_CONFIG_H
4233-#include "config.h"
4234-#endif
4235-
4236-#include <glibmm/i18n.h>
4237-#include <cstring>
4238-#include <string>
4239-
4240-#include "desktop-handles.h"
4241-#include "selection.h"
4242-#include "desktop.h"
4243-#include "desktop-style.h"
4244-#include "document.h"
4245-#include "display/sp-ctrlline.h"
4246-#include "display/sp-canvas-util.h"
4247-#include "xml/repr.h"
4248-#include "svg/css-ostringstream.h"
4249-#include "svg/svg.h"
4250-#include "libnr/nr-point-fns.h"
4251-#include "preferences.h"
4252-#include "sp-item.h"
4253-#include "style.h"
4254-#include "knot.h"
4255-#include "sp-linear-gradient.h"
4256-#include "sp-radial-gradient.h"
4257-#include "gradient-chemistry.h"
4258-#include "gradient-drag.h"
4259-#include "sp-stop.h"
4260-#include "snap.h"
4261-#include "sp-namedview.h"
4262-#include "selection-chemistry.h"
4263-
4264-#define GR_KNOT_COLOR_NORMAL 0xffffff00
4265-#define GR_KNOT_COLOR_MOUSEOVER 0xff000000
4266-#define GR_KNOT_COLOR_SELECTED 0x0000ff00
4267-
4268-#define GR_LINE_COLOR_FILL 0x0000ff7f
4269-#define GR_LINE_COLOR_STROKE 0x9999007f
4270-
4271-// screen pixels between knots when they snap:
4272-#define SNAP_DIST 5
4273-
4274-// absolute distance between gradient points for them to become a single dragger when the drag is created:
4275-#define MERGE_DIST 0.1
4276-
4277-// knot shapes corresponding to GrPointType enum
4278-SPKnotShapeType gr_knot_shapes [] = {
4279- SP_KNOT_SHAPE_SQUARE, //POINT_LG_BEGIN
4280- SP_KNOT_SHAPE_CIRCLE, //POINT_LG_END
4281- SP_KNOT_SHAPE_DIAMOND, //POINT_LG_MID
4282- SP_KNOT_SHAPE_SQUARE, // POINT_RG_CENTER
4283- SP_KNOT_SHAPE_CIRCLE, // POINT_RG_R1
4284- SP_KNOT_SHAPE_CIRCLE, // POINT_RG_R2
4285- SP_KNOT_SHAPE_CROSS, // POINT_RG_FOCUS
4286- SP_KNOT_SHAPE_DIAMOND, //POINT_RG_MID1
4287- SP_KNOT_SHAPE_DIAMOND //POINT_RG_MID2
4288-};
4289-
4290-const gchar *gr_knot_descr [] = {
4291- N_("Linear gradient <b>start</b>"), //POINT_LG_BEGIN
4292- N_("Linear gradient <b>end</b>"),
4293- N_("Linear gradient <b>mid stop</b>"),
4294- N_("Radial gradient <b>center</b>"),
4295- N_("Radial gradient <b>radius</b>"),
4296- N_("Radial gradient <b>radius</b>"),
4297- N_("Radial gradient <b>focus</b>"), // POINT_RG_FOCUS
4298- N_("Radial gradient <b>mid stop</b>"),
4299- N_("Radial gradient <b>mid stop</b>")
4300-};
4301-
4302-static void
4303-gr_drag_sel_changed(Inkscape::Selection */*selection*/, gpointer data)
4304-{
4305- GrDrag *drag = (GrDrag *) data;
4306- drag->updateDraggers ();
4307- drag->updateLines ();
4308- drag->updateLevels ();
4309-}
4310-
4311-static void
4312-gr_drag_sel_modified (Inkscape::Selection */*selection*/, guint /*flags*/, gpointer data)
4313-{
4314- GrDrag *drag = (GrDrag *) data;
4315- if (drag->local_change) {
4316- drag->local_change = false;
4317- } else {
4318- drag->updateDraggers ();
4319- }
4320- drag->updateLines ();
4321- drag->updateLevels ();
4322-}
4323-
4324-/**
4325-When a _query_style_signal is received, check that \a property requests fill/stroke/opacity (otherwise
4326-skip), and fill the \a style with the averaged color of all draggables of the selected dragger, if
4327-any.
4328-*/
4329-int
4330-gr_drag_style_query (SPStyle *style, int property, gpointer data)
4331-{
4332- GrDrag *drag = (GrDrag *) data;
4333-
4334- if (property != QUERY_STYLE_PROPERTY_FILL && property != QUERY_STYLE_PROPERTY_STROKE && property != QUERY_STYLE_PROPERTY_MASTEROPACITY) {
4335- return QUERY_STYLE_NOTHING;
4336- }
4337-
4338- if (!drag->selected) {
4339- return QUERY_STYLE_NOTHING;
4340- } else {
4341- int ret = QUERY_STYLE_NOTHING;
4342-
4343- float cf[4];
4344- cf[0] = cf[1] = cf[2] = cf[3] = 0;
4345-
4346- int count = 0;
4347-
4348- for (GList *i = drag->selected; i != NULL; i = i->next) { // for all selected draggers
4349- GrDragger *d = (GrDragger *) i->data;
4350- for (GSList const* j = d->draggables; j != NULL; j = j->next) { // for all draggables of dragger
4351- GrDraggable *draggable = (GrDraggable *) j->data;
4352-
4353- if (ret == QUERY_STYLE_NOTHING) {
4354- ret = QUERY_STYLE_SINGLE;
4355- } else if (ret == QUERY_STYLE_SINGLE) {
4356- ret = QUERY_STYLE_MULTIPLE_AVERAGED;
4357- }
4358-
4359- guint32 c = sp_item_gradient_stop_query_style (draggable->item, draggable->point_type, draggable->point_i, draggable->fill_or_stroke);
4360- cf[0] += SP_RGBA32_R_F (c);
4361- cf[1] += SP_RGBA32_G_F (c);
4362- cf[2] += SP_RGBA32_B_F (c);
4363- cf[3] += SP_RGBA32_A_F (c);
4364-
4365- count ++;
4366- }
4367- }
4368-
4369- if (count) {
4370- cf[0] /= count;
4371- cf[1] /= count;
4372- cf[2] /= count;
4373- cf[3] /= count;
4374-
4375- // set both fill and stroke with our stop-color and stop-opacity
4376- style->fill.clear();
4377- style->fill.setColor( cf[0], cf[1], cf[2] );
4378- style->fill.set = TRUE;
4379- style->stroke.clear();
4380- style->stroke.setColor( cf[0], cf[1], cf[2] );
4381- style->stroke.set = TRUE;
4382-
4383- style->fill_opacity.value = SP_SCALE24_FROM_FLOAT (1.0);
4384- style->fill_opacity.set = TRUE;
4385- style->stroke_opacity.value = SP_SCALE24_FROM_FLOAT (1.0);
4386- style->stroke_opacity.set = TRUE;
4387-
4388- style->opacity.value = SP_SCALE24_FROM_FLOAT (cf[3]);
4389- style->opacity.set = TRUE;
4390- }
4391-
4392- return ret;
4393- }
4394-}
4395-
4396-Glib::ustring GrDrag::makeStopSafeColor( gchar const *str, bool &isNull )
4397-{
4398- Glib::ustring colorStr;
4399- if ( str ) {
4400- isNull = false;
4401- colorStr = str;
4402- Glib::ustring::size_type pos = colorStr.find("url(#");
4403- if ( pos != Glib::ustring::npos ) {
4404- Glib::ustring targetName = colorStr.substr(pos + 5, colorStr.length() - 6);
4405- const GSList *gradients = sp_document_get_resource_list(desktop->doc(), "gradient");
4406- for (const GSList *item = gradients; item; item = item->next) {
4407- SPGradient* grad = SP_GRADIENT(item->data);
4408- if ( targetName == grad->getId() ) {
4409- SPGradient *vect = grad->getVector();
4410- SPStop *firstStop = (vect) ? vect->getFirstStop() : grad->getFirstStop();
4411- if (firstStop) {
4412- Glib::ustring stopColorStr;
4413- if (firstStop->currentColor) {
4414- stopColorStr = sp_object_get_style_property(firstStop, "color", NULL);
4415- } else {
4416- stopColorStr = firstStop->specified_color.toString();
4417- }
4418- if ( !stopColorStr.empty() ) {
4419- colorStr = stopColorStr;
4420- }
4421- }
4422- break;
4423- }
4424- }
4425- }
4426- } else {
4427- isNull = true;
4428- }
4429-
4430- return colorStr;
4431-}
4432-
4433-bool GrDrag::styleSet( const SPCSSAttr *css )
4434-{
4435- if (!selected) {
4436- return false;
4437- }
4438-
4439- SPCSSAttr *stop = sp_repr_css_attr_new();
4440-
4441- // See if the css contains interesting properties, and if so, translate them into the format
4442- // acceptable for gradient stops
4443-
4444- // any of color properties, in order of increasing priority:
4445- if (css->attribute("flood-color")) {
4446- sp_repr_css_set_property (stop, "stop-color", css->attribute("flood-color"));
4447- }
4448-
4449- if (css->attribute("lighting-color")) {
4450- sp_repr_css_set_property (stop, "stop-color", css->attribute("lighting-color"));
4451- }
4452-
4453- if (css->attribute("color")) {
4454- sp_repr_css_set_property (stop, "stop-color", css->attribute("color"));
4455- }
4456-
4457- if (css->attribute("stroke") && strcmp(css->attribute("stroke"), "none")) {
4458- sp_repr_css_set_property (stop, "stop-color", css->attribute("stroke"));
4459- }
4460-
4461- if (css->attribute("fill") && strcmp(css->attribute("fill"), "none")) {
4462- sp_repr_css_set_property (stop, "stop-color", css->attribute("fill"));
4463- }
4464-
4465- if (css->attribute("stop-color")) {
4466- sp_repr_css_set_property (stop, "stop-color", css->attribute("stop-color"));
4467- }
4468-
4469- // Make sure the style is allowed for gradient stops.
4470- if ( !sp_repr_css_property_is_unset( stop, "stop-color") ) {
4471- bool stopIsNull = false;
4472- Glib::ustring tmp = makeStopSafeColor( sp_repr_css_property( stop, "stop-color", "" ), stopIsNull );
4473- if ( !stopIsNull && !tmp.empty() ) {
4474- sp_repr_css_set_property( stop, "stop-color", tmp.c_str() );
4475- }
4476- }
4477-
4478-
4479- if (css->attribute("stop-opacity")) { // direct setting of stop-opacity has priority
4480- sp_repr_css_set_property(stop, "stop-opacity", css->attribute("stop-opacity"));
4481- } else { // multiply all opacity properties:
4482- gdouble accumulated = 1.0;
4483- accumulated *= sp_svg_read_percentage(css->attribute("flood-opacity"), 1.0);
4484- accumulated *= sp_svg_read_percentage(css->attribute("opacity"), 1.0);
4485- accumulated *= sp_svg_read_percentage(css->attribute("stroke-opacity"), 1.0);
4486- accumulated *= sp_svg_read_percentage(css->attribute("fill-opacity"), 1.0);
4487-
4488- Inkscape::CSSOStringStream os;
4489- os << accumulated;
4490- sp_repr_css_set_property(stop, "stop-opacity", os.str().c_str());
4491-
4492- if ((css->attribute("fill") && !css->attribute("stroke") && !strcmp(css->attribute("fill"), "none")) ||
4493- (css->attribute("stroke") && !css->attribute("fill") && !strcmp(css->attribute("stroke"), "none"))) {
4494- sp_repr_css_set_property(stop, "stop-opacity", "0"); // if a single fill/stroke property is set to none, don't change color, set opacity to 0
4495- }
4496- }
4497-
4498- if (!stop->attributeList()) { // nothing for us here, pass it on
4499- sp_repr_css_attr_unref(stop);
4500- return false;
4501- }
4502-
4503- for (GList const* sel = selected; sel != NULL; sel = sel->next) { // for all selected draggers
4504- GrDragger* dragger = reinterpret_cast<GrDragger*>(sel->data);
4505- for (GSList const* i = dragger->draggables; i != NULL; i = i->next) { // for all draggables of dragger
4506- GrDraggable *draggable = reinterpret_cast<GrDraggable *>(i->data);
4507-
4508- local_change = true;
4509- sp_item_gradient_stop_set_style(draggable->item, draggable->point_type, draggable->point_i, draggable->fill_or_stroke, stop);
4510- }
4511- }
4512-
4513- //sp_repr_css_print(stop);
4514- sp_repr_css_attr_unref(stop);
4515- return true;
4516-}
4517-
4518-guint32 GrDrag::getColor()
4519-{
4520- if (!selected) return 0;
4521-
4522- float cf[4];
4523- cf[0] = cf[1] = cf[2] = cf[3] = 0;
4524-
4525- int count = 0;
4526-
4527- for (GList *i = selected; i != NULL; i = i->next) { // for all selected draggers
4528- GrDragger *d = (GrDragger *) i->data;
4529- for (GSList const* j = d->draggables; j != NULL; j = j->next) { // for all draggables of dragger
4530- GrDraggable *draggable = (GrDraggable *) j->data;
4531-
4532- guint32 c = sp_item_gradient_stop_query_style (draggable->item, draggable->point_type, draggable->point_i, draggable->fill_or_stroke);
4533- cf[0] += SP_RGBA32_R_F (c);
4534- cf[1] += SP_RGBA32_G_F (c);
4535- cf[2] += SP_RGBA32_B_F (c);
4536- cf[3] += SP_RGBA32_A_F (c);
4537-
4538- count ++;
4539- }
4540- }
4541-
4542- if (count) {
4543- cf[0] /= count;
4544- cf[1] /= count;
4545- cf[2] /= count;
4546- cf[3] /= count;
4547- }
4548-
4549- return SP_RGBA32_F_COMPOSE(cf[0], cf[1], cf[2], cf[3]);
4550-}
4551-
4552-SPStop *
4553-GrDrag::addStopNearPoint (SPItem *item, Geom::Point mouse_p, double tolerance)
4554-{
4555- gfloat offset; // type of SPStop.offset = gfloat
4556- SPGradient *gradient;
4557- bool fill_or_stroke = true;
4558- bool r1_knot = false;
4559-
4560- bool addknot = false;
4561- do {
4562- gradient = sp_item_gradient (item, fill_or_stroke);
4563- if (SP_IS_LINEARGRADIENT(gradient)) {
4564- Geom::Point begin = sp_item_gradient_get_coords(item, POINT_LG_BEGIN, 0, fill_or_stroke);
4565- Geom::Point end = sp_item_gradient_get_coords(item, POINT_LG_END, 0, fill_or_stroke);
4566-
4567- Geom::Point nearest = snap_vector_midpoint (mouse_p, begin, end, 0);
4568- double dist_screen = Geom::L2 (mouse_p - nearest);
4569- if ( dist_screen < tolerance ) {
4570- // add the knot
4571- offset = get_offset_between_points(nearest, begin, end);
4572- addknot = true;
4573- break; // break out of the while loop: add only one knot
4574- }
4575- } else if (SP_IS_RADIALGRADIENT(gradient)) {
4576- Geom::Point begin = sp_item_gradient_get_coords(item, POINT_RG_CENTER, 0, fill_or_stroke);
4577- Geom::Point end = sp_item_gradient_get_coords(item, POINT_RG_R1, 0, fill_or_stroke);
4578- Geom::Point nearest = snap_vector_midpoint (mouse_p, begin, end, 0);
4579- double dist_screen = Geom::L2 (mouse_p - nearest);
4580- if ( dist_screen < tolerance ) {
4581- offset = get_offset_between_points(nearest, begin, end);
4582- addknot = true;
4583- r1_knot = true;
4584- break; // break out of the while loop: add only one knot
4585- }
4586-
4587- end = sp_item_gradient_get_coords(item, POINT_RG_R2, 0, fill_or_stroke);
4588- nearest = snap_vector_midpoint (mouse_p, begin, end, 0);
4589- dist_screen = Geom::L2 (mouse_p - nearest);
4590- if ( dist_screen < tolerance ) {
4591- offset = get_offset_between_points(nearest, begin, end);
4592- addknot = true;
4593- r1_knot = false;
4594- break; // break out of the while loop: add only one knot
4595- }
4596- }
4597- fill_or_stroke = !fill_or_stroke;
4598- } while (!fill_or_stroke && !addknot) ;
4599-
4600- if (addknot) {
4601- SPGradient *vector = sp_gradient_get_forked_vector_if_necessary (gradient, false);
4602- SPStop* prev_stop = vector->getFirstStop();
4603- SPStop* next_stop = prev_stop->getNextStop();
4604- guint i = 1;
4605- while ( (next_stop) && (next_stop->offset < offset) ) {
4606- prev_stop = next_stop;
4607- next_stop = next_stop->getNextStop();
4608- i++;
4609- }
4610- if (!next_stop) {
4611- // logical error: the endstop should have offset 1 and should always be more than this offset here
4612- return NULL;
4613- }
4614-
4615-
4616- SPStop *newstop = sp_vector_add_stop (vector, prev_stop, next_stop, offset);
4617- gradient->ensureVector();
4618- updateDraggers();
4619-
4620- return newstop;
4621- }
4622-
4623- return NULL;
4624-}
4625-
4626-
4627-bool
4628-GrDrag::dropColor(SPItem */*item*/, gchar const *c, Geom::Point p)
4629-{
4630- // Note: not sure if a null pointer can come in for the style, but handle that just in case
4631- bool stopIsNull = false;
4632- Glib::ustring toUse = makeStopSafeColor( c, stopIsNull );
4633-
4634- // first, see if we can drop onto one of the existing draggers
4635- for (GList *i = draggers; i != NULL; i = i->next) { // for all draggables of dragger
4636- GrDragger *d = (GrDragger *) i->data;
4637-
4638- if (Geom::L2(p - d->point)*desktop->current_zoom() < 5) {
4639- SPCSSAttr *stop = sp_repr_css_attr_new ();
4640- sp_repr_css_set_property( stop, "stop-color", stopIsNull ? 0 : toUse.c_str() );
4641- sp_repr_css_set_property( stop, "stop-opacity", "1" );
4642- for (GSList *j = d->draggables; j != NULL; j = j->next) { // for all draggables of dragger
4643- GrDraggable *draggable = (GrDraggable *) j->data;
4644- local_change = true;
4645- sp_item_gradient_stop_set_style (draggable->item, draggable->point_type, draggable->point_i, draggable->fill_or_stroke, stop);
4646- }
4647- sp_repr_css_attr_unref(stop);
4648- return true;
4649- }
4650- }
4651-
4652- // now see if we're over line and create a new stop
4653- bool over_line = false;
4654- SPCtrlLine *line = NULL;
4655- if (lines) {
4656- for (GSList *l = lines; (l != NULL) && (!over_line); l = l->next) {
4657- line = (SPCtrlLine*) l->data;
4658- Geom::Point nearest = snap_vector_midpoint (p, line->s, line->e, 0);
4659- double dist_screen = Geom::L2 (p - nearest) * desktop->current_zoom();
4660- if (line->item && dist_screen < 5) {
4661- SPStop *stop = addStopNearPoint (line->item, p, 5/desktop->current_zoom());
4662- if (stop) {
4663- SPCSSAttr *css = sp_repr_css_attr_new ();
4664- sp_repr_css_set_property( css, "stop-color", stopIsNull ? 0 : toUse.c_str() );
4665- sp_repr_css_set_property( css, "stop-opacity", "1" );
4666- sp_repr_css_change (SP_OBJECT_REPR (stop), css, "style");
4667- return true;
4668- }
4669- }
4670- }
4671- }
4672-
4673- return false;
4674-}
4675-
4676-
4677-GrDrag::GrDrag(SPDesktop *desktop) :
4678- selected(0),
4679- keep_selection(false),
4680- local_change(false),
4681- desktop(desktop),
4682- hor_levels(),
4683- vert_levels(),
4684- draggers(0),
4685- lines(0),
4686- selection(sp_desktop_selection(desktop)),
4687- sel_changed_connection(),
4688- sel_modified_connection(),
4689- style_set_connection(),
4690- style_query_connection()
4691-{
4692- sel_changed_connection = selection->connectChanged(
4693- sigc::bind(
4694- sigc::ptr_fun(&gr_drag_sel_changed),
4695- (gpointer)this )
4696-
4697- );
4698- sel_modified_connection = selection->connectModified(
4699- sigc::bind(
4700- sigc::ptr_fun(&gr_drag_sel_modified),
4701- (gpointer)this )
4702- );
4703-
4704- style_set_connection = desktop->connectSetStyle( sigc::mem_fun(*this, &GrDrag::styleSet) );
4705-
4706- style_query_connection = desktop->connectQueryStyle(
4707- sigc::bind(
4708- sigc::ptr_fun(&gr_drag_style_query),
4709- (gpointer)this )
4710- );
4711-
4712- updateDraggers();
4713- updateLines();
4714- updateLevels();
4715-
4716- if (desktop->gr_item) {
4717- setSelected(getDraggerFor(desktop->gr_item, desktop->gr_point_type, desktop->gr_point_i, desktop->gr_fill_or_stroke));
4718- }
4719-}
4720-
4721-GrDrag::~GrDrag()
4722-{
4723- this->sel_changed_connection.disconnect();
4724- this->sel_modified_connection.disconnect();
4725- this->style_set_connection.disconnect();
4726- this->style_query_connection.disconnect();
4727-
4728- if (this->selected) {
4729- GrDraggable *draggable = (GrDraggable *) ((GrDragger*)this->selected->data)->draggables->data;
4730- desktop->gr_item = draggable->item;
4731- desktop->gr_point_type = draggable->point_type;
4732- desktop->gr_point_i = draggable->point_i;
4733- desktop->gr_fill_or_stroke = draggable->fill_or_stroke;
4734- } else {
4735- desktop->gr_item = NULL;
4736- desktop->gr_point_type = 0;
4737- desktop->gr_point_i = 0;
4738- desktop->gr_fill_or_stroke = true;
4739- }
4740-
4741- deselect_all();
4742- for (GList *l = this->draggers; l != NULL; l = l->next) {
4743- delete ((GrDragger *) l->data);
4744- }
4745- g_list_free (this->draggers);
4746- this->draggers = NULL;
4747- this->selected = NULL;
4748-
4749- for (GSList *l = this->lines; l != NULL; l = l->next) {
4750- gtk_object_destroy( GTK_OBJECT (l->data));
4751- }
4752- g_slist_free (this->lines);
4753- this->lines = NULL;
4754-}
4755-
4756-GrDraggable::GrDraggable (SPItem *item, guint point_type, guint point_i, bool fill_or_stroke)
4757-{
4758- this->item = item;
4759- this->point_type = point_type;
4760- this->point_i = point_i;
4761- this->fill_or_stroke = fill_or_stroke;
4762-
4763- g_object_ref (G_OBJECT (this->item));
4764-}
4765-
4766-GrDraggable::~GrDraggable ()
4767-{
4768- g_object_unref (G_OBJECT (this->item));
4769-}
4770-
4771-
4772-SPObject *GrDraggable::getServer()
4773-{
4774- if (!item) {
4775- return NULL;
4776- }
4777-
4778- SPObject *server = NULL;
4779- if (fill_or_stroke) {
4780- server = item->style->getFillPaintServer();
4781- }else {
4782- server = item->style->getStrokePaintServer();
4783- }
4784-
4785- return server;
4786-}
4787-
4788-static
4789-boost::optional<Geom::Point>
4790-get_snap_vector (Geom::Point p, Geom::Point o, double snap, double initial)
4791-{
4792- double r = L2 (p - o);
4793- if (r < 1e-3) {
4794- return boost::optional<Geom::Point>();
4795- }
4796-
4797- double angle = atan2 (p - o);
4798- // snap angle to snaps increments, starting from initial:
4799- double a_snapped = initial + floor((angle - initial)/snap + 0.5) * snap;
4800- // calculate the new position and subtract p to get the vector:
4801- return (o + r * Geom::Point(cos(a_snapped), sin(a_snapped)) - p);
4802-}
4803-
4804-static void
4805-gr_knot_moved_handler(SPKnot *knot, Geom::Point const &ppointer, guint state, gpointer data)
4806-{
4807- GrDragger *dragger = (GrDragger *) data;
4808- GrDrag *drag = dragger->parent;
4809-
4810- Geom::Point p = ppointer;
4811-
4812- SPDesktop *desktop = dragger->parent->desktop;
4813- SnapManager &m = desktop->namedview->snap_manager;
4814- double snap_dist = m.snapprefs.getObjectTolerance() / dragger->parent->desktop->current_zoom();
4815-
4816- if (state & GDK_SHIFT_MASK) {
4817- // with Shift; unsnap if we carry more than one draggable
4818- if (dragger->draggables && dragger->draggables->next) {
4819- // create a new dragger
4820- GrDragger *dr_new = new GrDragger (dragger->parent, dragger->point, NULL);
4821- dragger->parent->draggers = g_list_prepend (dragger->parent->draggers, dr_new);
4822- // relink to it all but the first draggable in the list
4823- for (GSList const* i = dragger->draggables->next; i != NULL; i = i->next) {
4824- GrDraggable *draggable = (GrDraggable *) i->data;
4825- dr_new->addDraggable (draggable);
4826- }
4827- dr_new->updateKnotShape();
4828- g_slist_free (dragger->draggables->next);
4829- dragger->draggables->next = NULL;
4830- dragger->updateKnotShape();
4831- dragger->updateTip();
4832- }
4833- } else if (!(state & GDK_CONTROL_MASK)) {
4834- // without Shift or Ctrl; see if we need to snap to another dragger
4835- for (GList *di = dragger->parent->draggers; di != NULL; di = di->next) {
4836- GrDragger *d_new = (GrDragger *) di->data;
4837- if (dragger->mayMerge(d_new) && Geom::L2 (d_new->point - p) < snap_dist) {
4838-
4839- // Merge draggers:
4840- for (GSList const* i = dragger->draggables; i != NULL; i = i->next) { // for all draggables of dragger
4841- GrDraggable *draggable = (GrDraggable *) i->data;
4842- // copy draggable to d_new:
4843- GrDraggable *da_new = new GrDraggable (draggable->item, draggable->point_type, draggable->point_i, draggable->fill_or_stroke);
4844- d_new->addDraggable (da_new);
4845- }
4846-
4847- // unlink and delete this dragger
4848- dragger->parent->draggers = g_list_remove (dragger->parent->draggers, dragger);
4849- delete dragger;
4850-
4851- // update the new merged dragger
4852- d_new->fireDraggables(true, false, true);
4853- d_new->parent->updateLines();
4854- d_new->parent->setSelected (d_new);
4855- d_new->updateKnotShape ();
4856- d_new->updateTip ();
4857- d_new->updateDependencies(true);
4858- sp_document_done (sp_desktop_document (d_new->parent->desktop), SP_VERB_CONTEXT_GRADIENT,
4859- _("Merge gradient handles"));
4860- return;
4861- }
4862- }
4863- }
4864-
4865- m.setup(desktop);
4866- if (!((state & GDK_SHIFT_MASK) || (state & GDK_CONTROL_MASK))) {
4867- Inkscape::SnappedPoint s = m.freeSnap(Inkscape::SnapCandidatePoint(p, Inkscape::SNAPSOURCE_OTHER_HANDLE));
4868- if (s.getSnapped()) {
4869- p = s.getPoint();
4870- sp_knot_moveto (knot, p);
4871- }
4872- } else if (state & GDK_CONTROL_MASK) {
4873- SnappedConstraints sc;
4874- Inkscape::Preferences *prefs = Inkscape::Preferences::get();
4875- unsigned snaps = abs(prefs->getInt("/options/rotationsnapsperpi/value", 12));
4876- /* 0 means no snapping. */
4877-
4878- for (GSList const* i = dragger->draggables; i != NULL; i = i->next) {
4879- GrDraggable *draggable = (GrDraggable *) i->data;
4880-
4881- Geom::Point dr_snap(Geom::infinity(), Geom::infinity());
4882-
4883- if (draggable->point_type == POINT_LG_BEGIN || draggable->point_type == POINT_LG_END) {
4884- for (GList *di = dragger->parent->draggers; di != NULL; di = di->next) {
4885- GrDragger *d_new = (GrDragger *) di->data;
4886- if (d_new == dragger)
4887- continue;
4888- if (d_new->isA (draggable->item,
4889- draggable->point_type == POINT_LG_BEGIN? POINT_LG_END : POINT_LG_BEGIN,
4890- draggable->fill_or_stroke)) {
4891- // found the other end of the linear gradient;
4892- if (state & GDK_SHIFT_MASK) {
4893- // moving linear around center
4894- Geom::Point center = Geom::Point (0.5*(d_new->point + dragger->point));
4895- dr_snap = center;
4896- } else {
4897- // moving linear around the other end
4898- dr_snap = d_new->point;
4899- }
4900- }
4901- }
4902- } else if (draggable->point_type == POINT_RG_R1 || draggable->point_type == POINT_RG_R2 || draggable->point_type == POINT_RG_FOCUS) {
4903- for (GList *di = dragger->parent->draggers; di != NULL; di = di->next) {
4904- GrDragger *d_new = (GrDragger *) di->data;
4905- if (d_new == dragger)
4906- continue;
4907- if (d_new->isA (draggable->item,
4908- POINT_RG_CENTER,
4909- draggable->fill_or_stroke)) {
4910- // found the center of the radial gradient;
4911- dr_snap = d_new->point;
4912- }
4913- }
4914- } else if (draggable->point_type == POINT_RG_CENTER) {
4915- // radial center snaps to hor/vert relative to its original position
4916- dr_snap = dragger->point_original;
4917- }
4918-
4919- boost::optional<Geom::Point> snap_vector;
4920- if (dr_snap.isFinite()) {
4921- if (state & GDK_MOD1_MASK) {
4922- // with Alt, snap to the original angle and its perpendiculars
4923- snap_vector = get_snap_vector (p, dr_snap, M_PI/2, Geom::atan2 (dragger->point_original - dr_snap));
4924- } else {
4925- // with Ctrl, snap to M_PI/snaps
4926- snap_vector = get_snap_vector (p, dr_snap, M_PI/snaps, 0);
4927- }
4928- if (snap_vector) {
4929- Inkscape::Snapper::ConstraintLine cl(dr_snap, p + *snap_vector - dr_snap);
4930- Inkscape::SnappedPoint s = m.constrainedSnap(Inkscape::SnapCandidatePoint(p + *snap_vector, Inkscape::SNAPSOURCE_OTHER_HANDLE), cl);
4931- if (s.getSnapped()) {
4932- s.setTransformation(s.getPoint() - p);
4933- sc.points.push_back(s);
4934- } else {
4935- Inkscape::SnappedPoint dummy(p + *snap_vector, Inkscape::SNAPSOURCE_OTHER_HANDLE, 0, Inkscape::SNAPTARGET_CONSTRAINED_ANGLE, Geom::L2(*snap_vector), 10000, true, true, false);
4936- dummy.setTransformation(*snap_vector);
4937- sc.points.push_back(dummy);
4938- }
4939- }
4940- }
4941- }
4942-
4943- Inkscape::SnappedPoint bsp = m.findBestSnap(Inkscape::SnapCandidatePoint(p, Inkscape::SNAPSOURCE_OTHER_HANDLE), sc, true); // snap indicator will be displayed if needed
4944-
4945- if (bsp.getSnapped()) {
4946- p += bsp.getTransformation();
4947- sp_knot_moveto (knot, p);
4948- }
4949- }
4950-
4951- drag->keep_selection = (bool) g_list_find(drag->selected, dragger);
4952- bool scale_radial = (state & GDK_CONTROL_MASK) && (state & GDK_SHIFT_MASK);
4953-
4954- if (drag->keep_selection) {
4955- Geom::Point diff = p - dragger->point;
4956- drag->selected_move_nowrite (diff[Geom::X], diff[Geom::Y], scale_radial);
4957- } else {
4958- dragger->point = p;
4959- dragger->fireDraggables (false, scale_radial);
4960- dragger->updateDependencies(false);
4961- }
4962-
4963-}
4964-
4965-
4966-static void
4967-gr_midpoint_limits(GrDragger *dragger, SPObject *server, Geom::Point *begin, Geom::Point *end, Geom::Point *low_lim, Geom::Point *high_lim, GSList **moving)
4968-{
4969-
4970- GrDrag *drag = dragger->parent;
4971- // a midpoint dragger can (logically) only contain one GrDraggable
4972- GrDraggable *draggable = (GrDraggable *) dragger->draggables->data;
4973-
4974- // get begin and end points between which dragging is allowed:
4975- // the draglimits are between knot(lowest_i - 1) and knot(highest_i + 1)
4976- *moving = g_slist_append(*moving, dragger);
4977-
4978- guint lowest_i = draggable->point_i;
4979- guint highest_i = draggable->point_i;
4980- GrDragger *lowest_dragger = dragger;
4981- GrDragger *highest_dragger = dragger;
4982- if (dragger->isSelected()) {
4983- GrDragger* d_add;
4984- while ( true )
4985- {
4986- d_add = drag->getDraggerFor(draggable->item, draggable->point_type, lowest_i - 1, draggable->fill_or_stroke);
4987- if ( d_add && g_list_find(drag->selected, d_add) ) {
4988- lowest_i = lowest_i - 1;
4989- *moving = g_slist_prepend(*moving, d_add);
4990- lowest_dragger = d_add;
4991- } else {
4992- break;
4993- }
4994- }
4995-
4996- while ( true )
4997- {
4998- d_add = drag->getDraggerFor(draggable->item, draggable->point_type, highest_i + 1, draggable->fill_or_stroke);
4999- if ( d_add && g_list_find(drag->selected, d_add) ) {
5000- highest_i = highest_i + 1;
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches