etti 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/AUTHORS +1 -0
- data/COPYING +340 -0
- data/README.md +57 -0
- data/bin/etti +10 -0
- data/lib/data/locale/de/LC_MESSAGES/etti.mo +0 -0
- data/lib/data/page-data.json +28 -0
- data/lib/data/pixmaps/logo.png +0 -0
- data/lib/data/pixmaps/logo.svg +102 -0
- data/lib/data/pixmaps/win-logo.png +0 -0
- data/lib/data/pixmaps/win-logo.svg +223 -0
- data/lib/etti/colors.rb +15 -0
- data/lib/etti/dnd-data.rb +12 -0
- data/lib/etti/elements/base.rb +14 -0
- data/lib/etti/elements/data.rb +109 -0
- data/lib/etti/elements/text.rb +74 -0
- data/lib/etti/file/data-reader.rb +67 -0
- data/lib/etti/monkeys/array.rb +8 -0
- data/lib/etti/monkeys/cairo-context.rb +94 -0
- data/lib/etti/monkeys/gtk-event-box.rb +7 -0
- data/lib/etti/page-datas.rb +110 -0
- data/lib/etti/page.rb +40 -0
- data/lib/etti/print-view.rb +21 -0
- data/lib/etti/ui/data-page.rb +236 -0
- data/lib/etti/ui/label-elements.rb +74 -0
- data/lib/etti/ui/label-layout-page.rb +193 -0
- data/lib/etti/ui/label-layout.rb +315 -0
- data/lib/etti/ui/label-selection-page.rb +91 -0
- data/lib/etti/ui/message-dialog.rb +103 -0
- data/lib/etti/ui/page-layout.rb +405 -0
- data/lib/etti/ui/property-editor-data.rb +92 -0
- data/lib/etti/ui/window.rb +117 -0
- data/lib/etti/version.rb +3 -0
- data/lib/etti.rb +45 -0
- metadata +184 -0
@@ -0,0 +1,223 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
2
|
+
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
3
|
+
|
4
|
+
<svg
|
5
|
+
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
6
|
+
xmlns:cc="http://creativecommons.org/ns#"
|
7
|
+
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
8
|
+
xmlns:svg="http://www.w3.org/2000/svg"
|
9
|
+
xmlns="http://www.w3.org/2000/svg"
|
10
|
+
xmlns:xlink="http://www.w3.org/1999/xlink"
|
11
|
+
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
12
|
+
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
13
|
+
width="16"
|
14
|
+
height="16.000002"
|
15
|
+
id="svg30198"
|
16
|
+
version="1.1"
|
17
|
+
inkscape:version="0.48.4 r9939"
|
18
|
+
sodipodi:docname="Neues Dokument 29">
|
19
|
+
<defs
|
20
|
+
id="defs30200">
|
21
|
+
<linearGradient
|
22
|
+
id="linearGradient33157">
|
23
|
+
<stop
|
24
|
+
style="stop-color:#999999;stop-opacity:1;"
|
25
|
+
offset="0"
|
26
|
+
id="stop33159" />
|
27
|
+
<stop
|
28
|
+
style="stop-color:#515151;stop-opacity:1;"
|
29
|
+
offset="1"
|
30
|
+
id="stop33161" />
|
31
|
+
</linearGradient>
|
32
|
+
<linearGradient
|
33
|
+
xlink:href="#linearGradient1887"
|
34
|
+
y2="218.54164"
|
35
|
+
x2="173.72397"
|
36
|
+
y1="209.14064"
|
37
|
+
x1="163.85936"
|
38
|
+
gradientTransform="matrix(1.102855,0,0,1.148517,-167.5042,-41.73143)"
|
39
|
+
gradientUnits="userSpaceOnUse"
|
40
|
+
id="linearGradient5795"
|
41
|
+
inkscape:collect="always" />
|
42
|
+
<linearGradient
|
43
|
+
id="linearGradient1887">
|
44
|
+
<stop
|
45
|
+
id="stop1888"
|
46
|
+
offset="0.0000000"
|
47
|
+
style="stop-color:#fffdf8;stop-opacity:1.0000000;" />
|
48
|
+
<stop
|
49
|
+
id="stop1889"
|
50
|
+
offset="1.0000000"
|
51
|
+
style="stop-color:#cdccc7;stop-opacity:1.0000000;" />
|
52
|
+
</linearGradient>
|
53
|
+
<linearGradient
|
54
|
+
xlink:href="#linearGradient3480"
|
55
|
+
y2="217.25519"
|
56
|
+
x2="173.03127"
|
57
|
+
y1="207.75523"
|
58
|
+
x1="161.28645"
|
59
|
+
gradientTransform="matrix(1.102855,0,0,1.148517,-168.0557,-42.30568)"
|
60
|
+
gradientUnits="userSpaceOnUse"
|
61
|
+
id="linearGradient5797"
|
62
|
+
inkscape:collect="always" />
|
63
|
+
<linearGradient
|
64
|
+
id="linearGradient3480">
|
65
|
+
<stop
|
66
|
+
id="stop3482"
|
67
|
+
offset="0.0000000"
|
68
|
+
style="stop-color:#646464;stop-opacity:1.0000000;" />
|
69
|
+
<stop
|
70
|
+
id="stop3484"
|
71
|
+
offset="1.0000000"
|
72
|
+
style="stop-color:#000000;stop-opacity:1.0000000;" />
|
73
|
+
</linearGradient>
|
74
|
+
<linearGradient
|
75
|
+
xlink:href="#linearGradient3480"
|
76
|
+
y2="213"
|
77
|
+
x2="176"
|
78
|
+
y1="213"
|
79
|
+
x1="160"
|
80
|
+
gradientTransform="translate(-150.459,-11.45)"
|
81
|
+
gradientUnits="userSpaceOnUse"
|
82
|
+
id="linearGradient5799"
|
83
|
+
inkscape:collect="always" />
|
84
|
+
<linearGradient
|
85
|
+
id="linearGradient30225">
|
86
|
+
<stop
|
87
|
+
id="stop30227"
|
88
|
+
offset="0.0000000"
|
89
|
+
style="stop-color:#646464;stop-opacity:1.0000000;" />
|
90
|
+
<stop
|
91
|
+
id="stop30229"
|
92
|
+
offset="1.0000000"
|
93
|
+
style="stop-color:#000000;stop-opacity:1.0000000;" />
|
94
|
+
</linearGradient>
|
95
|
+
<linearGradient
|
96
|
+
inkscape:collect="always"
|
97
|
+
xlink:href="#linearGradient1887"
|
98
|
+
id="linearGradient30283"
|
99
|
+
gradientUnits="userSpaceOnUse"
|
100
|
+
gradientTransform="matrix(1.102855,0,0,1.148517,-167.5042,-41.73143)"
|
101
|
+
x1="163.85936"
|
102
|
+
y1="209.14064"
|
103
|
+
x2="173.72397"
|
104
|
+
y2="218.54164" />
|
105
|
+
<linearGradient
|
106
|
+
inkscape:collect="always"
|
107
|
+
xlink:href="#linearGradient3480"
|
108
|
+
id="linearGradient30285"
|
109
|
+
gradientUnits="userSpaceOnUse"
|
110
|
+
gradientTransform="matrix(1.102855,0,0,1.148517,-168.0557,-42.30568)"
|
111
|
+
x1="161.28645"
|
112
|
+
y1="207.75523"
|
113
|
+
x2="173.03127"
|
114
|
+
y2="217.25519" />
|
115
|
+
<linearGradient
|
116
|
+
inkscape:collect="always"
|
117
|
+
xlink:href="#linearGradient3480"
|
118
|
+
id="linearGradient30287"
|
119
|
+
gradientUnits="userSpaceOnUse"
|
120
|
+
gradientTransform="translate(-150.459,-11.45)"
|
121
|
+
x1="160"
|
122
|
+
y1="213"
|
123
|
+
x2="176"
|
124
|
+
y2="213" />
|
125
|
+
<linearGradient
|
126
|
+
inkscape:collect="always"
|
127
|
+
xlink:href="#linearGradient3480"
|
128
|
+
id="linearGradient31074"
|
129
|
+
gradientUnits="userSpaceOnUse"
|
130
|
+
gradientTransform="translate(188.50009,316.86218)"
|
131
|
+
x1="160"
|
132
|
+
y1="213"
|
133
|
+
x2="176"
|
134
|
+
y2="213" />
|
135
|
+
<linearGradient
|
136
|
+
inkscape:collect="always"
|
137
|
+
xlink:href="#linearGradient3480"
|
138
|
+
id="linearGradient31079"
|
139
|
+
gradientUnits="userSpaceOnUse"
|
140
|
+
gradientTransform="matrix(1.102855,0,0,1.148517,170.90339,286.0065)"
|
141
|
+
x1="161.28645"
|
142
|
+
y1="207.75523"
|
143
|
+
x2="173.03127"
|
144
|
+
y2="217.25519" />
|
145
|
+
<linearGradient
|
146
|
+
inkscape:collect="always"
|
147
|
+
xlink:href="#linearGradient33157"
|
148
|
+
id="linearGradient33163"
|
149
|
+
x1="348.78534"
|
150
|
+
y1="524.80157"
|
151
|
+
x2="359.47076"
|
152
|
+
y2="539.90277"
|
153
|
+
gradientUnits="userSpaceOnUse" />
|
154
|
+
</defs>
|
155
|
+
<sodipodi:namedview
|
156
|
+
id="base"
|
157
|
+
pagecolor="#ffffff"
|
158
|
+
bordercolor="#666666"
|
159
|
+
borderopacity="1.0"
|
160
|
+
inkscape:pageopacity="0.0"
|
161
|
+
inkscape:pageshadow="2"
|
162
|
+
inkscape:zoom="41.056383"
|
163
|
+
inkscape:cx="9.4231888"
|
164
|
+
inkscape:cy="5.4834939"
|
165
|
+
inkscape:document-units="px"
|
166
|
+
inkscape:current-layer="layer1"
|
167
|
+
showgrid="false"
|
168
|
+
fit-margin-top="0"
|
169
|
+
fit-margin-left="0"
|
170
|
+
fit-margin-right="0"
|
171
|
+
fit-margin-bottom="0"
|
172
|
+
inkscape:window-width="1920"
|
173
|
+
inkscape:window-height="1145"
|
174
|
+
inkscape:window-x="0"
|
175
|
+
inkscape:window-y="33"
|
176
|
+
inkscape:window-maximized="1" />
|
177
|
+
<metadata
|
178
|
+
id="metadata30203">
|
179
|
+
<rdf:RDF>
|
180
|
+
<cc:Work
|
181
|
+
rdf:about="">
|
182
|
+
<dc:format>image/svg+xml</dc:format>
|
183
|
+
<dc:type
|
184
|
+
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
185
|
+
<dc:title></dc:title>
|
186
|
+
</cc:Work>
|
187
|
+
</rdf:RDF>
|
188
|
+
</metadata>
|
189
|
+
<g
|
190
|
+
inkscape:label="Ebene 1"
|
191
|
+
inkscape:groupmode="layer"
|
192
|
+
id="layer1"
|
193
|
+
transform="translate(-346,-524.36218)">
|
194
|
+
<path
|
195
|
+
transform="translate(346,524.36218)"
|
196
|
+
style="fill:#ffffff;fill-opacity:1;stroke:none"
|
197
|
+
d="m 2.5331018,0.5334664 7.1608842,0 4.018863,4.0432203 0,10.9361803 -11.1797472,0 z"
|
198
|
+
id="rect33165"
|
199
|
+
inkscape:connector-curvature="0"
|
200
|
+
sodipodi:nodetypes="cccccc" />
|
201
|
+
<path
|
202
|
+
id="path33149"
|
203
|
+
style="fill:none;stroke:url(#linearGradient33163);stroke-width:0.75000000000000000;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
204
|
+
d="m 352.14167,539.41271 c 0,-0.11371 0,-14.76117 0,-14.76117 m 3.66666,14.8654 c 0,-0.0821 0,-10.65848 0,-10.65848 m -7.64661,8.02872 c 0.0861,0 11.17761,0 11.17761,0 m -11.03147,-3 c 0.0861,0 11.17761,0 11.17761,0 m -11.17761,-3 c 0.0861,0 11.17761,0 11.17761,0 m -11.30473,-3 c 0.0569,0 7.38862,0 7.38862,0" />
|
205
|
+
<path
|
206
|
+
inkscape:connector-curvature="0"
|
207
|
+
id="path5602"
|
208
|
+
d="m 349.5,538.86218 9,0 0,-9"
|
209
|
+
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:0.29807693" />
|
210
|
+
<path
|
211
|
+
inkscape:connector-curvature="0"
|
212
|
+
sodipodi:nodetypes="cccccc"
|
213
|
+
id="path4679"
|
214
|
+
d="m 348.5,524.86218 7,0 4,4 0,11 -11,0 0,-15 z"
|
215
|
+
style="color:#000000;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient31079);stroke-width:1.00000106999999994;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;marker:none;display:inline" />
|
216
|
+
<path
|
217
|
+
inkscape:connector-curvature="0"
|
218
|
+
sodipodi:nodetypes="cccc"
|
219
|
+
id="path4681"
|
220
|
+
d="m 355.5,524.86218 4,4 -4,0 0,-4 z"
|
221
|
+
style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient31074);stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1" />
|
222
|
+
</g>
|
223
|
+
</svg>
|
data/lib/etti/colors.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
module Etti
|
4
|
+
class Colors
|
5
|
+
def initialize
|
6
|
+
@bg = [0.9, 0.9, 0.9]
|
7
|
+
@border = [0, 0, 0]
|
8
|
+
@selection = [0.5, 0.25, 0.0]
|
9
|
+
@text_normal = [0.0, 0.1, 1.0, 0.4]
|
10
|
+
@text_highlit = [0.1, 0.2, 1.0, 0.4]
|
11
|
+
end
|
12
|
+
attr_reader :bg, :border, :selection
|
13
|
+
attr_reader :text_normal, :text_highlit
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,109 @@
|
|
1
|
+
#encoding: UTF-8
|
2
|
+
|
3
|
+
module Etti
|
4
|
+
module Element
|
5
|
+
class Data < Etti::Element::Text
|
6
|
+
SHOW_AS_TEXT = 0
|
7
|
+
SHOW_AS_QR = 1
|
8
|
+
QR_ERROR_LEVELS = [:low, :medium, :quarter, :high]
|
9
|
+
QR_ENCODING = [:numeric, :alphanumeric, :ascii, :kanji]
|
10
|
+
def initialize dataGroup, text, x=nil, y=nil, size=nil
|
11
|
+
super text, x, y, size
|
12
|
+
@dataGroup = dataGroup
|
13
|
+
@qrWidth = 10.0
|
14
|
+
@qrHeight = 10.0
|
15
|
+
@qrVersion = 1
|
16
|
+
@qrErrorCorrection = :low
|
17
|
+
@qrEncoding = :ascii
|
18
|
+
@showAs = SHOW_AS_TEXT
|
19
|
+
end
|
20
|
+
attr_reader :dataGroup
|
21
|
+
|
22
|
+
|
23
|
+
def set_by_name name, val
|
24
|
+
if name == 'qrWidth' then @qrWidth = val.to_f; return;
|
25
|
+
elsif name == 'qrHeight' then @qrHeight = val.to_f; return;
|
26
|
+
elsif name == 'qrVersion' then @qrVersion = val.to_i; return;
|
27
|
+
elsif name == 'qrErrorCorrection' then @qrErrorCorrection = QR_ERROR_LEVELS[val.to_i]; return;
|
28
|
+
elsif name == 'qrEncoding' then @qrEncoding = QR_ENCODING[val.to_i]; return;
|
29
|
+
elsif name == 'showAs' then @showAs = val; return; end
|
30
|
+
super name, val
|
31
|
+
end
|
32
|
+
|
33
|
+
|
34
|
+
def get_by_name name
|
35
|
+
if name == 'qrWidth' then return @qrWidth;
|
36
|
+
elsif name == 'qrHeight' then return @qrHeight;
|
37
|
+
elsif name == 'qrVersion' then return @qrVersion;
|
38
|
+
elsif name == 'qrErrorCorrection' then return QR_ERROR_LEVELS.index @qrErrorCorrection;
|
39
|
+
elsif name == 'qrEncoding' then return QR_ENCODING.index @qrEncoding;
|
40
|
+
elsif name == 'showAs' then return @showAs; end
|
41
|
+
super name
|
42
|
+
end
|
43
|
+
|
44
|
+
|
45
|
+
def draw_selection view
|
46
|
+
if @showAs == SHOW_AS_TEXT
|
47
|
+
super
|
48
|
+
return
|
49
|
+
end
|
50
|
+
cc = Cairo::Context.new view.backBuffer
|
51
|
+
cc.antialias = :none
|
52
|
+
cc.line_width = 1.0
|
53
|
+
cc.set_dash [6, 6], 0
|
54
|
+
cc.set_source_rgb *$colors.selection
|
55
|
+
|
56
|
+
xd, yd = *view.pos_to_view(@x, @y)
|
57
|
+
|
58
|
+
cc.translate xd, yd
|
59
|
+
cc.rotate @rotation * Math::PI / 180.0 unless @rotation.near 0.0
|
60
|
+
height = @qrHeight * view.scale
|
61
|
+
cc.rectangle 0, -height, @qrWidth * view.scale, @qrHeight * view.scale
|
62
|
+
cc.stroke
|
63
|
+
end
|
64
|
+
|
65
|
+
|
66
|
+
def at_pos view, x, y
|
67
|
+
return super if @showAs == SHOW_AS_TEXT
|
68
|
+
ext = Rectangle.new @x, @y - @qrHeight, @qrWidth, @qrHeight
|
69
|
+
a = -@rotation * Math::PI / 180.0
|
70
|
+
xr = (x - @x) * Math.cos(a) - (y - @y) * Math.sin(a)
|
71
|
+
yr = (y - @y) * Math.cos(a) + (x - @x) * Math.sin(a)
|
72
|
+
ext.in(xr + @x, yr + @y)
|
73
|
+
end
|
74
|
+
|
75
|
+
|
76
|
+
def redraw view, cc
|
77
|
+
return if @text.nil?
|
78
|
+
cc.save
|
79
|
+
cc.set_source_rgba *@color
|
80
|
+
xd, yd = *view.pos_to_view(@x, @y)
|
81
|
+
cc.translate xd, yd
|
82
|
+
cc.rotate @rotation * Math::PI / 180.0
|
83
|
+
cc.antialias = :subpixel
|
84
|
+
|
85
|
+
if @showAs == SHOW_AS_TEXT
|
86
|
+
cc.font_size = @size * view.scale
|
87
|
+
cc.show_text @text
|
88
|
+
else
|
89
|
+
qr = QREncoder.encode @text, :version => @qrVersion,
|
90
|
+
:correction => @qrErrorCorrection,
|
91
|
+
:mode => @qrEncoding
|
92
|
+
width = qr.width
|
93
|
+
height = @qrHeight * view.scale
|
94
|
+
pw = @qrWidth * view.scale / width
|
95
|
+
ph = @qrHeight * view.scale / width
|
96
|
+
qr.pixels.each_with_index do |row_data, row|
|
97
|
+
row_data.each_with_index do |pixel, col|
|
98
|
+
next if pixel == 0
|
99
|
+
cc.rectangle col * pw, row * ph - height, pw, ph
|
100
|
+
cc.fill.stroke
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
cc.stroke
|
105
|
+
cc.restore
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
#encoding: UTF-8
|
2
|
+
|
3
|
+
module Etti
|
4
|
+
module Element
|
5
|
+
class Text < Etti::Element::Base
|
6
|
+
def initialize text, x=nil, y=nil, size=nil
|
7
|
+
super x, y
|
8
|
+
@text = text || ''
|
9
|
+
@size = size || 4.0
|
10
|
+
end
|
11
|
+
|
12
|
+
def set_by_name name, val
|
13
|
+
if name == 'text' then @text = val; return; end
|
14
|
+
if name == 'pos_x' then @x = val.to_f; return; end
|
15
|
+
if name == 'pos_y' then @y = val.to_f; return; end
|
16
|
+
if name == 'size' then @size = val.to_f; return; end
|
17
|
+
if name == 'rotation' then @rotation = val.to_f; return; end
|
18
|
+
if name == 'color' then @color = val; return; end
|
19
|
+
end
|
20
|
+
|
21
|
+
|
22
|
+
def get_by_name name
|
23
|
+
if name == 'text' then return @text;
|
24
|
+
elsif name == 'pos_x' then return @x;
|
25
|
+
elsif name == 'pos_y' then return @y;
|
26
|
+
elsif name == 'size' then return @size;
|
27
|
+
elsif name == 'rotation' then return @rotation;
|
28
|
+
elsif name == 'color' then return @color; end
|
29
|
+
end
|
30
|
+
|
31
|
+
|
32
|
+
def redraw
|
33
|
+
|
34
|
+
end
|
35
|
+
|
36
|
+
|
37
|
+
def draw_selection view
|
38
|
+
cc = Cairo::Context.new view.backBuffer
|
39
|
+
cc.antialias = :none
|
40
|
+
cc.line_width = 1.0
|
41
|
+
cc.set_dash [6, 6], 0
|
42
|
+
cc.set_source_rgb *$colors.selection
|
43
|
+
|
44
|
+
cc.font_size = @size * view.scale
|
45
|
+
ext = cc.text_extents @text
|
46
|
+
xd, yd = *view.pos_to_view(@x, @y)
|
47
|
+
|
48
|
+
cc.translate xd, yd
|
49
|
+
cc.rotate @rotation * Math::PI / 180.0 unless @rotation.near 0.0
|
50
|
+
cc.rectangle 0, ext.y_bearing, ext.width, ext.height
|
51
|
+
cc.stroke
|
52
|
+
end
|
53
|
+
|
54
|
+
|
55
|
+
def at_pos view, x, y
|
56
|
+
ext = get_extent view
|
57
|
+
a = -@rotation * Math::PI / 180.0
|
58
|
+
xr = (x - @x) * Math.cos(a) - (y - @y) * Math.sin(a)
|
59
|
+
yr = (y - @y) * Math.cos(a) + (x - @x) * Math.sin(a)
|
60
|
+
ext.in(xr + @x, yr + @y)
|
61
|
+
end
|
62
|
+
|
63
|
+
|
64
|
+
def get_extent view
|
65
|
+
cc = Cairo::Context.new view.backBuffer
|
66
|
+
cc.font_size = @size * view.scale
|
67
|
+
ext = cc.text_extents @text
|
68
|
+
w = ext.width() / view.scale
|
69
|
+
y = @y + (ext.y_bearing() / view.scale)
|
70
|
+
Rectangle.new @x, y, w, @size
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
#encoding: UTF-8
|
2
|
+
|
3
|
+
module Etti
|
4
|
+
module FileReader
|
5
|
+
|
6
|
+
include GetText
|
7
|
+
GetText.bindtextdomain 'etti', :path => Etti::LOCALE_PATH
|
8
|
+
|
9
|
+
# message codes from the callback
|
10
|
+
OK = 1
|
11
|
+
WARNING = 2
|
12
|
+
ERROR = 4
|
13
|
+
# return values to the callback
|
14
|
+
YES = 1
|
15
|
+
YES_ALLWAYS = 2
|
16
|
+
NO = 4
|
17
|
+
NO_ALLWAYAS = 8
|
18
|
+
|
19
|
+
# path = path to the data file
|
20
|
+
# separator = the separator for the split function to each line
|
21
|
+
# max_slices = the maximum number of slices each line split to
|
22
|
+
# callback {} = block to pass warnings and errors to
|
23
|
+
def data_read path, separator, max_slices, &callback
|
24
|
+
unless File.readable? path
|
25
|
+
callback.call ERROR, _("%s\n is not readable") % path
|
26
|
+
return
|
27
|
+
end
|
28
|
+
|
29
|
+
fm = FileMagic.mime
|
30
|
+
mime = fm.file path
|
31
|
+
unless mime.start_with? 'text/plain;'
|
32
|
+
answer = callback.call(WARNING,
|
33
|
+
_("Files other then plain text are not supported.\n" +
|
34
|
+
"Should the file be loaded anyway?"))
|
35
|
+
return if answer != YES
|
36
|
+
end
|
37
|
+
|
38
|
+
file = File.new path, 'r'
|
39
|
+
|
40
|
+
# warn the user if the file is bigger then 1 MB
|
41
|
+
size = file.size
|
42
|
+
if size > 1_000_000
|
43
|
+
mb = sprintf "%.3f", size.to_f / 1_000_000
|
44
|
+
answer= callback.call(WARNING,
|
45
|
+
_("The selected file is very big (%s MB)\n" +
|
46
|
+
"Do you really want to open it?") % mb)
|
47
|
+
if answer != YES
|
48
|
+
file.close
|
49
|
+
return
|
50
|
+
else
|
51
|
+
if remind
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
lines = []
|
57
|
+
cols = 0
|
58
|
+
file.each do |line|
|
59
|
+
toc = line.strip.split(separator, max_slices)
|
60
|
+
lines << toc
|
61
|
+
cols = cols.max toc.length
|
62
|
+
end
|
63
|
+
[lines, cols]
|
64
|
+
end
|
65
|
+
module_function :data_read
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
# monkey patches
|
2
|
+
|
3
|
+
module Cairo
|
4
|
+
class Context
|
5
|
+
def shadow_mp x, y, width, height, size, sd=nil
|
6
|
+
sides = 0
|
7
|
+
if sd.nil?
|
8
|
+
sides = 15
|
9
|
+
else
|
10
|
+
sides += 1 if sd.include? 'l'
|
11
|
+
sides += 2 if sd.include? 'r'
|
12
|
+
sides += 4 if sd.include? 't'
|
13
|
+
sides += 8 if sd.include? 'b'
|
14
|
+
end
|
15
|
+
|
16
|
+
# borders #
|
17
|
+
# left
|
18
|
+
if sides & 1 > 0
|
19
|
+
pat = Cairo::LinearPattern.new x, y, x - size, y
|
20
|
+
shadow_pattern_add_stopps pat
|
21
|
+
self.rectangle x - size, y, size, height
|
22
|
+
self.set_source pat
|
23
|
+
self.fill
|
24
|
+
end
|
25
|
+
|
26
|
+
# right
|
27
|
+
if sides & 2 > 0
|
28
|
+
pat = Cairo::LinearPattern.new x + width, y, x + width + size, y
|
29
|
+
shadow_pattern_add_stopps pat
|
30
|
+
self.rectangle x + width, y, x + width + size, height
|
31
|
+
self.set_source pat
|
32
|
+
self.fill
|
33
|
+
end
|
34
|
+
|
35
|
+
# top
|
36
|
+
if sides & 4 > 0
|
37
|
+
pat = Cairo::LinearPattern.new x, y, x, y - size
|
38
|
+
shadow_pattern_add_stopps pat
|
39
|
+
self.rectangle x, y - size, width, size
|
40
|
+
self.set_source pat
|
41
|
+
self.fill
|
42
|
+
end
|
43
|
+
|
44
|
+
# bottom
|
45
|
+
if sides & 8 > 0
|
46
|
+
pat = Cairo::LinearPattern.new x, y + height, x, y + height + size
|
47
|
+
shadow_pattern_add_stopps pat
|
48
|
+
self.rectangle x, y + height, width, y + height + size
|
49
|
+
self.set_source pat
|
50
|
+
self.fill
|
51
|
+
end
|
52
|
+
|
53
|
+
# corners #
|
54
|
+
# top left
|
55
|
+
if sides & 5 > 0
|
56
|
+
pat = Cairo::RadialPattern.new x, y, 0, x, y, size
|
57
|
+
shadow_pattern_add_stopps pat
|
58
|
+
self.rectangle x - size, y - size, size, size
|
59
|
+
self.set_source(pat).fill
|
60
|
+
end
|
61
|
+
|
62
|
+
# top right
|
63
|
+
if sides & 6 > 0
|
64
|
+
pat = Cairo::RadialPattern.new x + width, y, 0, x + width, y, size
|
65
|
+
shadow_pattern_add_stopps pat
|
66
|
+
self.rectangle x + width, y - size, size, size
|
67
|
+
self.set_source(pat).fill
|
68
|
+
end
|
69
|
+
|
70
|
+
# bottom left
|
71
|
+
if sides & 9 > 0
|
72
|
+
pat = Cairo::RadialPattern.new x, y + height, 0, x, y + height, size
|
73
|
+
shadow_pattern_add_stopps pat
|
74
|
+
self.rectangle x - size, y + height, size, size
|
75
|
+
self.set_source(pat).fill
|
76
|
+
end
|
77
|
+
|
78
|
+
# bottom right
|
79
|
+
if sides & 10 > 0
|
80
|
+
pat = Cairo::RadialPattern.new x + width, y + height, 0, x + width, y + height, size
|
81
|
+
shadow_pattern_add_stopps pat
|
82
|
+
self.rectangle x + width, y + height, size, size
|
83
|
+
self.set_source(pat).fill
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
private
|
88
|
+
def shadow_pattern_add_stopps pat
|
89
|
+
pat.add_color_stop_rgba 0.0, 0.4, 0.4, 0.4, 0.6
|
90
|
+
pat.add_color_stop_rgba 1.0, 1, 1, 1, 0
|
91
|
+
end
|
92
|
+
|
93
|
+
end
|
94
|
+
end
|