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,110 @@
|
|
1
|
+
#encoding: UTF-8
|
2
|
+
|
3
|
+
module Etti
|
4
|
+
class PageDatas < GLib::Object
|
5
|
+
self.type_register
|
6
|
+
self.signal_new :new_page, GLib::Signal::RUN_FIRST, nil, GLib::Type['void'], Array
|
7
|
+
def signal_do_new_page foo; end
|
8
|
+
|
9
|
+
|
10
|
+
include GetText
|
11
|
+
GetText.bindtextdomain 'etti', :path => Etti::LOCALE_PATH
|
12
|
+
|
13
|
+
FIELDS = [:manufacture, :orderNr, :description, :pageSize,
|
14
|
+
:cols, :rows, :size, :borders, :padding]
|
15
|
+
def initialize
|
16
|
+
super()
|
17
|
+
|
18
|
+
@pageDatas = {}
|
19
|
+
@dataFiles = [DATA_PATH + 'page-data.json',
|
20
|
+
File.expand_path('~') + '/.local/share/etti/page-data.json']
|
21
|
+
|
22
|
+
@dataFiles.each_with_index do |filename, idx|
|
23
|
+
next unless File.exist? filename
|
24
|
+
data = File.new(filename).read
|
25
|
+
json = JSON.parse data
|
26
|
+
unless json['Etti'] == 'page data file'
|
27
|
+
warn "the data file \"%s\" is not a valid etti page data file" % filename
|
28
|
+
next
|
29
|
+
end
|
30
|
+
|
31
|
+
@pageDatas.merge! json['Data']
|
32
|
+
@pageDatas.each_pair do |key, val|
|
33
|
+
@pageDatas[key][:source] = idx if val[:source].nil?
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
attr_reader :pageDatas
|
38
|
+
|
39
|
+
|
40
|
+
def get_page_names
|
41
|
+
@pageDatas.keys.sort
|
42
|
+
end
|
43
|
+
|
44
|
+
|
45
|
+
def get_page_data type
|
46
|
+
data = @pageDatas[type]
|
47
|
+
return nil if data.nil?
|
48
|
+
|
49
|
+
hs = {}
|
50
|
+
hs[:name] = type
|
51
|
+
FIELDS.each do |sym|
|
52
|
+
val = data[sym.to_s]
|
53
|
+
next if val.nil?
|
54
|
+
val = val.clone if val.is_a? Array or val.is_a? String
|
55
|
+
hs[sym] = val
|
56
|
+
end
|
57
|
+
hs
|
58
|
+
end
|
59
|
+
|
60
|
+
|
61
|
+
def save_page_data page, &callback
|
62
|
+
FileUtils.mkdir_p File.dirname(@dataFiles.last)
|
63
|
+
if @pageDatas.key? page[:name]
|
64
|
+
message = _("The page description\n\"%s\"\nalready exist.\n\nSould it be replaced?") % page[:name]
|
65
|
+
|
66
|
+
ret = callback.call :warning, :yes_no, message
|
67
|
+
return unless ret == 'yes'
|
68
|
+
end
|
69
|
+
# header
|
70
|
+
json = {'Etti' => 'page data file',
|
71
|
+
'Version' => [1, 0],
|
72
|
+
'Data' => {}}
|
73
|
+
|
74
|
+
# save unchanged pages to the hash
|
75
|
+
@pageDatas.each_pair do |key, val|
|
76
|
+
json['Data'][key] = val if val[:source] == 1
|
77
|
+
end
|
78
|
+
|
79
|
+
hs = nil
|
80
|
+
newPage = !@pageDatas.key?(page[:name])
|
81
|
+
|
82
|
+
# fill the current or new page with the page data from the UI
|
83
|
+
if newPage
|
84
|
+
hs = {}
|
85
|
+
else
|
86
|
+
hs = @pageDatas[page[:name]]
|
87
|
+
end
|
88
|
+
FIELDS.each do |key|
|
89
|
+
hs[key.to_s] = page[key]
|
90
|
+
end
|
91
|
+
|
92
|
+
json['Data'][page[:name]] = hs
|
93
|
+
|
94
|
+
if newPage
|
95
|
+
hs['source'] = 1
|
96
|
+
@pageDatas[page[:name]] = hs
|
97
|
+
signal_emit :new_page, [page[:name], hs]
|
98
|
+
end
|
99
|
+
|
100
|
+
fd = File.new @dataFiles.last, File::CREAT|File::TRUNC|File::RDWR, 0644
|
101
|
+
fd.write JSON.pretty_generate json
|
102
|
+
fd.flush
|
103
|
+
end
|
104
|
+
|
105
|
+
private
|
106
|
+
def warn warning
|
107
|
+
printf "%s:%i: %s\n", __FILE__, __LINE__, warning
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
data/lib/etti/page.rb
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
#encoding: UTF-8
|
2
|
+
|
3
|
+
module Etti
|
4
|
+
class Page
|
5
|
+
# all metrics in mm
|
6
|
+
def initialize *ag
|
7
|
+
args = ag.extract_args!
|
8
|
+
|
9
|
+
@name = args[:name] || ''
|
10
|
+
# the manufacture of the labels
|
11
|
+
@manufacture = args[:manufacture] || ''
|
12
|
+
# the original order number
|
13
|
+
@orderNr = args[:orderNr] || ''
|
14
|
+
# a longer description of the labels
|
15
|
+
@description = args[:description] || ''
|
16
|
+
@pageSize = args[:pageSize] || 'a4'
|
17
|
+
@cols = args[:cols] || 10
|
18
|
+
@rows = args[:rows] || 28
|
19
|
+
# size of a single label
|
20
|
+
# one value = circular labels = diameter
|
21
|
+
# two values = rectangle labels = width x height
|
22
|
+
@size = args[:size] || [20.0, 10.0]
|
23
|
+
# left, top; we asume, that left, right and top, bottom are equal
|
24
|
+
@borders = args[:borders] || [5.0, 7.0]
|
25
|
+
# borders between labels; horizontal, vertical
|
26
|
+
@padding = args[:padding] || [0.0, 0.0]
|
27
|
+
end
|
28
|
+
|
29
|
+
attr_accessor :name, :manufacture, :orderNr, :description
|
30
|
+
attr_accessor :pageSize, :cols, :rows, :size, :borders, :padding
|
31
|
+
|
32
|
+
|
33
|
+
# def margins_valid?
|
34
|
+
# ps = @pageSizes[@pageSize]
|
35
|
+
# raise ArgumentError, 'invalid page size ' + @pageSize.to_s if ps.nil?
|
36
|
+
# ps[0] >= @borders[0] + @cols * @size[0] + (@cols -1) * @padding[0] and
|
37
|
+
# ps[1] >= @borders[1] + @cols * @size[1] + (@cols -1) * @padding[1]
|
38
|
+
# end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
#encoding: UTF-8
|
2
|
+
|
3
|
+
module Etti
|
4
|
+
class PrintView
|
5
|
+
def initialize
|
6
|
+
@scale = 2.8346457
|
7
|
+
@centerX = 0.0
|
8
|
+
@centerY = 0.0
|
9
|
+
@width = 210.0
|
10
|
+
@height = 297.0
|
11
|
+
end
|
12
|
+
attr_reader :scale, :centerX, :centerY
|
13
|
+
|
14
|
+
|
15
|
+
def pos_to_view x=0.0, y=0.0
|
16
|
+
x1 = (x + @centerX) * @scale # + @width / 2.0
|
17
|
+
y1 = (y + @centerY) * @scale # + @height / 2.0
|
18
|
+
[x1, y1]
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,236 @@
|
|
1
|
+
#encoding: UTF-8
|
2
|
+
|
3
|
+
module Etti
|
4
|
+
class DataPage < Gtk::Box
|
5
|
+
self.type_register
|
6
|
+
self.signal_new :data_changed, GLib::Signal::RUN_FIRST, nil, GLib::Type['void'], Array, Array
|
7
|
+
def signal_do_data_changed foo, bla; end
|
8
|
+
|
9
|
+
include GetText
|
10
|
+
GetText.bindtextdomain 'etti', :path => Etti::LOCALE_PATH
|
11
|
+
|
12
|
+
PREVIEW_LABEL_COUNT = 50
|
13
|
+
|
14
|
+
def initialize
|
15
|
+
super(:orientation => :vertical)
|
16
|
+
@dataPageUser = Gtk::Box.new :vertical
|
17
|
+
pack_start @dataPageUser, :expand => false, :fill => false
|
18
|
+
|
19
|
+
@dataFromFile = nil
|
20
|
+
@dataFromFileNumCols = 1
|
21
|
+
|
22
|
+
@previewList = Rgw::BigList.new 1
|
23
|
+
|
24
|
+
@radioRevealer = Rgw::RadioRevealer.new
|
25
|
+
@dataPageUser.pack_start @radioRevealer, :expand => false, :fill => false, :padding => 6
|
26
|
+
@radioRevealer.create_entry _('Enumeration'), create_enumeration_section
|
27
|
+
@radioRevealer.create_entry _('From File'), create_file_section
|
28
|
+
@radioRevealer.signal_connect(:revealed) {|widget, idx| update_data_preview idx}
|
29
|
+
|
30
|
+
label = Gtk::Label.new
|
31
|
+
label.markup = _("<b>data preview</b>")
|
32
|
+
pack_start label, :expand => false, :fill => false
|
33
|
+
pack_start @previewList, :expand => true, :fill => true
|
34
|
+
end
|
35
|
+
|
36
|
+
|
37
|
+
def update_data_preview idx
|
38
|
+
# data from enumeration
|
39
|
+
if idx == 0
|
40
|
+
@previewList.num_cols = 1
|
41
|
+
@previewList.heads = [_('Enumeration')]
|
42
|
+
prefix = @dataEntries[0].text
|
43
|
+
string = @dataEntries[1].text
|
44
|
+
postfix = @dataEntries[2].text
|
45
|
+
@dataRanges = []
|
46
|
+
toc = string.split ','
|
47
|
+
tocClean = []
|
48
|
+
toc.each do |text|
|
49
|
+
textClean = text.strip
|
50
|
+
tocClean << textClean if textClean.length() > 0
|
51
|
+
end
|
52
|
+
# no enumeration entered
|
53
|
+
if tocClean.length == 0
|
54
|
+
if prefix.length() > 0 or postfix.length() > 0
|
55
|
+
@previewList.data = [[prefix + (tocClean[0].nil? ? '' : tocClean[0]) + postfix]]
|
56
|
+
else
|
57
|
+
@previewList.data = []
|
58
|
+
end
|
59
|
+
else
|
60
|
+
labelTexts = []
|
61
|
+
fullLength = 0
|
62
|
+
tocClean.each do |text|
|
63
|
+
# its a range like "1 - 99" or "aa-zz"
|
64
|
+
if text.match /^\w+\s*\-\s*\w+$/
|
65
|
+
rgFrom, rgTo = *text.split('-')
|
66
|
+
rg = Range.new rgFrom.strip, rgTo.strip
|
67
|
+
if rg.count() > 1
|
68
|
+
@dataRanges << rg
|
69
|
+
fullLength += rg.count
|
70
|
+
else
|
71
|
+
@dataRanges << text
|
72
|
+
fullLength += 1
|
73
|
+
end
|
74
|
+
else
|
75
|
+
@dataRanges << text
|
76
|
+
fullLength += 1
|
77
|
+
end
|
78
|
+
end
|
79
|
+
@dataRanges.each do |data|
|
80
|
+
if data.is_a? Range
|
81
|
+
labelTexts += data.to_a
|
82
|
+
else
|
83
|
+
labelTexts << data
|
84
|
+
end
|
85
|
+
end
|
86
|
+
text = []
|
87
|
+
labelTexts.each {|txt| text << [prefix + txt + postfix]}
|
88
|
+
@previewList.data = text
|
89
|
+
end
|
90
|
+
# data from file
|
91
|
+
elsif idx == 1
|
92
|
+
unless @dataFromFile.nil?
|
93
|
+
@previewList.num_cols = @dataFromFileNumCols
|
94
|
+
if @hasHeadCheckButton.active?
|
95
|
+
if @dataFromFile.length() > 0
|
96
|
+
heads = @dataFromFile[0]
|
97
|
+
heads[@previewList.numCols - 1] = nil if heads.length() < @previewList.numCols
|
98
|
+
|
99
|
+
i = 0
|
100
|
+
heads.map! do |a|
|
101
|
+
val = a.nil? ? "col" + i.to_s : a
|
102
|
+
i += 1
|
103
|
+
val
|
104
|
+
end
|
105
|
+
|
106
|
+
@previewList.heads = heads
|
107
|
+
if @dataFromFile.length() > 1
|
108
|
+
@previewList.data = @dataFromFile[1..-1]
|
109
|
+
end
|
110
|
+
else
|
111
|
+
@previewList.heads = Array.new @previewList.numCols, ""
|
112
|
+
end
|
113
|
+
else
|
114
|
+
heads = []
|
115
|
+
1.upto(@previewList.numCols) {|i| heads << 'col' + i.to_s}
|
116
|
+
@previewList.heads = heads
|
117
|
+
@previewList.data = @dataFromFile
|
118
|
+
end
|
119
|
+
else
|
120
|
+
@previewList.heads = nil
|
121
|
+
@previewList.data = []
|
122
|
+
end
|
123
|
+
end
|
124
|
+
signal_emit :data_changed, @previewList.heads, @previewList.data
|
125
|
+
end
|
126
|
+
|
127
|
+
|
128
|
+
private
|
129
|
+
def create_enumeration_section
|
130
|
+
hbox = Gtk::Box.new :horizontal
|
131
|
+
|
132
|
+
@dataBox = Gtk::Box.new :vertical
|
133
|
+
hbox.pack_start @dataBox, :expand => false, :fill => false
|
134
|
+
|
135
|
+
sizeGroup = Gtk::SizeGroup.new :both
|
136
|
+
@dataEntries = []
|
137
|
+
[_('Prefix'), _('Data Row'), _('Postfix')].each {|label| add_data_entry label, sizeGroup}
|
138
|
+
hbox
|
139
|
+
end
|
140
|
+
|
141
|
+
|
142
|
+
def create_file_section
|
143
|
+
vbox = Gtk::Box.new :vertical
|
144
|
+
hbox = Gtk::Box.new :horizontal
|
145
|
+
vbox.pack_start hbox, :expand => false, :fill => false, :padding => 4
|
146
|
+
|
147
|
+
sizeGroup = Gtk::SizeGroup.new :both
|
148
|
+
label = Gtk::Label.new.set_markup _('<b>File: </b>')
|
149
|
+
sizeGroup.add_widget label
|
150
|
+
label.xalign = 0.0
|
151
|
+
hbox.pack_start label, :expand => false, :fill => false
|
152
|
+
|
153
|
+
@fileButton = Gtk::FileChooserButton.new _('Choose file'), :open
|
154
|
+
hbox.pack_start @fileButton, :expand => false, :fill => false
|
155
|
+
|
156
|
+
@fileButton.signal_connect(:file_set) do
|
157
|
+
data, cols = *Etti::FileReader.data_read(@fileButton.filename,
|
158
|
+
@previewList.separator,
|
159
|
+
20) do |type, message, types=nil|
|
160
|
+
answer = nil
|
161
|
+
btn = [:yes, :no]
|
162
|
+
tp = type == Etti::FileReader::WARNING ? :warning : :error
|
163
|
+
dialog = Etti::MessageDialog.new self.toplevel, :buttons => btn,
|
164
|
+
:type => tp, :message => message,
|
165
|
+
:title => _('Question from file reader')
|
166
|
+
case dialog.run
|
167
|
+
when 'yes'
|
168
|
+
Etti::FileReader::YES
|
169
|
+
when 'no'
|
170
|
+
Etti::FileReader::NO
|
171
|
+
end
|
172
|
+
end
|
173
|
+
unless data.nil?
|
174
|
+
@dataFromFile = data
|
175
|
+
@dataFromFileNumCols = cols
|
176
|
+
update_data_preview 1
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
|
181
|
+
hbox = Gtk::Box.new :horizontal
|
182
|
+
vbox.pack_start hbox, :expand => false, :fill => false, :padding => 4
|
183
|
+
|
184
|
+
label = Gtk::Label.new.set_markup _('<b>Column separator: </b>')
|
185
|
+
sizeGroup.add_widget label
|
186
|
+
label.xalign = 0.0
|
187
|
+
hbox.pack_start label, :expand => false, :fill => false
|
188
|
+
|
189
|
+
@fileSeparatorCombo = Gtk::ComboBoxText.new
|
190
|
+
hbox.pack_start @fileSeparatorCombo, :expand => false, :fill => false
|
191
|
+
@separatorNames = [_('tab'), _('space'), ',', '.']
|
192
|
+
@separatorStrings = ["\t", ' ', ',', '.']
|
193
|
+
@separatorNames.each {|sep| @fileSeparatorCombo.append_text sep}
|
194
|
+
@fileSeparatorCombo.signal_connect(:changed) do
|
195
|
+
@previewList.separator = @separatorStrings[@fileSeparatorCombo.active]
|
196
|
+
end
|
197
|
+
@fileSeparatorCombo.active = 0
|
198
|
+
|
199
|
+
hbox = Gtk::Box.new :horizontal
|
200
|
+
@hasHeadCheckButton = Gtk::CheckButton.new
|
201
|
+
label = Gtk::Label.new.set_markup _('<b>Columns have headlines</b>')
|
202
|
+
@hasHeadCheckButton.add label
|
203
|
+
hbox.pack_start @hasHeadCheckButton, :expand => false, :fill => false
|
204
|
+
vbox.pack_start hbox, :expand => false, :fill => false, :padding => 4
|
205
|
+
@hasHeadCheckButton.signal_connect(:toggled) do
|
206
|
+
update_data_preview 1
|
207
|
+
end
|
208
|
+
|
209
|
+
vbox
|
210
|
+
end
|
211
|
+
|
212
|
+
|
213
|
+
def add_data_entry label, sizeGroup
|
214
|
+
hbox = Gtk::Box.new :horizontal
|
215
|
+
@dataBox.pack_start hbox, :expand => false, :fill => false
|
216
|
+
|
217
|
+
label = Gtk::Label.new.set_markup("<b>#{label}</b>: ")
|
218
|
+
hbox.pack_start label, :expand => false, :fill => false
|
219
|
+
sizeGroup.add_widget label
|
220
|
+
label.xalign = 0.0
|
221
|
+
|
222
|
+
entry = Gtk::Entry.new
|
223
|
+
@dataEntries << entry
|
224
|
+
hbox.pack_start entry, :expand => false, :fill => false, :padding => 6
|
225
|
+
entry.signal_connect(:changed) {update_data_preview 0}
|
226
|
+
end
|
227
|
+
|
228
|
+
|
229
|
+
def create_group_label text
|
230
|
+
label = Gtk::Label.new.set_xalign(0.04)
|
231
|
+
label.markup = '<span size="large" weight="bold">' + text + '</span>'
|
232
|
+
label
|
233
|
+
end
|
234
|
+
end
|
235
|
+
end
|
236
|
+
|
@@ -0,0 +1,74 @@
|
|
1
|
+
#encoding: UTF-8
|
2
|
+
|
3
|
+
module Etti
|
4
|
+
class LabelElements < Gtk::Box
|
5
|
+
include GetText
|
6
|
+
GetText.bindtextdomain 'etti', :path => Etti::LOCALE_PATH
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
super :vertical
|
10
|
+
@elements = []
|
11
|
+
|
12
|
+
pack_start Gtk::Label.new.set_markup(_('<b><big> Data </big></b>')), :expand => false, :fill => false
|
13
|
+
|
14
|
+
@eventBox = Gtk::EventBox.new
|
15
|
+
pack_start @eventBox, :expand => true, :fill => true, :padding => 4
|
16
|
+
|
17
|
+
@list = Rgw::BigList.new 1
|
18
|
+
@eventBox.add @list
|
19
|
+
|
20
|
+
@eventBox.add_events Gdk::Event::Mask::BUTTON_PRESS_MASK |
|
21
|
+
Gdk::Event::Mask::BUTTON_RELEASE_MASK
|
22
|
+
@eventBox.signal_connect(:drag_begin) {|widget, context| on_drag_begin context}
|
23
|
+
@eventBox.signal_connect(:button_press_event){|widget, event| on_button_press event}
|
24
|
+
@eventBox.drag_source_set :button1_mask, [['elements2area', :same_app, 123]], :copy
|
25
|
+
end
|
26
|
+
|
27
|
+
|
28
|
+
def elements=(elements)
|
29
|
+
if elements.nil?
|
30
|
+
@list.data = nil
|
31
|
+
else
|
32
|
+
@list.data = elements.map {|e| [e]}
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
|
37
|
+
def on_button_press event
|
38
|
+
@pressX = event.x
|
39
|
+
@pressY = event.y
|
40
|
+
false
|
41
|
+
end
|
42
|
+
|
43
|
+
|
44
|
+
def dnd_data
|
45
|
+
@dnd_data
|
46
|
+
end
|
47
|
+
|
48
|
+
|
49
|
+
def on_drag_begin context
|
50
|
+
# get the text extends from the list element
|
51
|
+
text = @list.row_at_pos(@pressX, @pressY)[0]
|
52
|
+
@eventBox.dnd_data = Etti::DndData.new :data, text
|
53
|
+
@dnd_data = text
|
54
|
+
ct = @list.window.create_cairo_context
|
55
|
+
ct.font_size = 16.0
|
56
|
+
ext = ct.text_extents text
|
57
|
+
|
58
|
+
# create the drag image
|
59
|
+
surface = Cairo::ImageSurface.new Cairo::Format::ARGB32, ext.width, ext.height * 1.5
|
60
|
+
cc = Cairo::Context.new surface
|
61
|
+
cc.set_source_rgba 1.0, 1.0, 1.0, 0.0
|
62
|
+
cc.paint
|
63
|
+
cc.set_source_rgb 0.0, 0.0, 0.0
|
64
|
+
cc.move_to 0, ext.height
|
65
|
+
cc.font_size = 16.0
|
66
|
+
cc.show_text text
|
67
|
+
cc.stroke
|
68
|
+
pixbuf = Gdk::Pixbuf.from_surface surface, 0, 0, ext.width, ext.height * 1.5
|
69
|
+
context.set_icon :pixbuf => pixbuf, :hot_x => ext.width / 2.0, :hot_y => ext.height
|
70
|
+
end
|
71
|
+
|
72
|
+
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,193 @@
|
|
1
|
+
#encoding: UTF-8
|
2
|
+
|
3
|
+
module Etti
|
4
|
+
class LabelLayoutPage < Gtk::Box
|
5
|
+
include GetText
|
6
|
+
GetText.bindtextdomain 'etti', :path => Etti::LOCALE_PATH
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
super :vertical
|
10
|
+
@printPageSetup = nil
|
11
|
+
|
12
|
+
create_toolbar
|
13
|
+
self.pack_start @toolbar, :expand => false, :fill => false, :padding => 6
|
14
|
+
|
15
|
+
hbox = Gtk::Box.new :horizontal
|
16
|
+
self.pack_start hbox, :expand => true, :fill => true
|
17
|
+
|
18
|
+
create_property_view
|
19
|
+
hbox.pack_start @propertyView, :expand => false, :fill => false
|
20
|
+
|
21
|
+
paned = Gtk::Paned.new :horizontal
|
22
|
+
hbox.pack_start paned, :expand => true, :fill => true
|
23
|
+
|
24
|
+
@layoutPreview = Etti::LabelLayout.new @propertyViews
|
25
|
+
paned.pack1 @layoutPreview, :resize => true, :shrink => true
|
26
|
+
|
27
|
+
|
28
|
+
ebox = Gtk::Box.new :horizontal
|
29
|
+
|
30
|
+
paned.pack2 ebox, :resize => false, :shrink => false
|
31
|
+
|
32
|
+
label = Gtk::Label.new _(' Drag the elements over ')
|
33
|
+
label.angle = 90
|
34
|
+
ebox.pack_start label, :expand => false, :fill => false, :padding => 8
|
35
|
+
|
36
|
+
@labelElements = Etti::LabelElements.new
|
37
|
+
ebox.pack_start @labelElements, :expand => true, :fill => true
|
38
|
+
end
|
39
|
+
|
40
|
+
|
41
|
+
def update_page_data pageData
|
42
|
+
@pageData = pageData
|
43
|
+
@layoutPreview.update_page_data pageData
|
44
|
+
end
|
45
|
+
|
46
|
+
|
47
|
+
def set_element_data heads, data
|
48
|
+
@labelElements.elements = data.length == 0 ? nil : heads
|
49
|
+
@layoutPreview.set_element_data heads, data
|
50
|
+
end
|
51
|
+
|
52
|
+
|
53
|
+
def initialize_property_views
|
54
|
+
@propertyViews.each_pair do |key, val|
|
55
|
+
if key == :none
|
56
|
+
val.show
|
57
|
+
else
|
58
|
+
val.hide
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
|
64
|
+
def create_property_view
|
65
|
+
@propertyView = Gtk::Box.new :vertical
|
66
|
+
@propertyViews = {}
|
67
|
+
sizeGroup = Gtk::SizeGroup.new :horizontal
|
68
|
+
|
69
|
+
[[Etti::PropertyEditorData::NONE_PROPS, _('nothing selected'), :none],
|
70
|
+
[Etti::PropertyEditorData::TEXTS_PROPS, _('Text element'), :text],
|
71
|
+
[Etti::PropertyEditorData::DATA_PROPS, _('Data element'), :data]].each_with_index do |pair, i|
|
72
|
+
pv = Rgw::PropertyEditor.new pair[0], pair[1]
|
73
|
+
sizeGroup.add_widget pv
|
74
|
+
@propertyViews[pair[2]] = pv
|
75
|
+
@propertyView.pack_start pv, :expand => false, :fill => false, :padding => 0
|
76
|
+
|
77
|
+
pv.signal_connect(:property_changed) do |widget, name, val|
|
78
|
+
unless pv.selectedElement.nil?
|
79
|
+
pv.selectedElement.set_by_name name, val
|
80
|
+
@layoutPreview.queue_draw
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
|
87
|
+
def create_toolbar
|
88
|
+
@toolbar = Gtk::Box.new :horizontal
|
89
|
+
=begin
|
90
|
+
@fontButton = Gtk::FontButton.new
|
91
|
+
@toolbar.pack_start @fontButton, :expand => false, :fill => false
|
92
|
+
@fontButton.use_font = true
|
93
|
+
|
94
|
+
texts = ['a'..'z', 'A'..'Z']
|
95
|
+
text = ''
|
96
|
+
texts.each {|txt| text += txt.to_a.join}
|
97
|
+
@fontButton.preview_text = text
|
98
|
+
=end
|
99
|
+
|
100
|
+
button = Gtk::Button.new
|
101
|
+
button.signal_connect(:clicked) {@layoutPreview.zoom_in}
|
102
|
+
img = Gtk::Image.new :stock => Gtk::Stock::ZOOM_IN, :size => :small_toolbar
|
103
|
+
button << img
|
104
|
+
@toolbar.pack_start button, :expand => false, :fill => false, :padding => 0
|
105
|
+
|
106
|
+
button = Gtk::Button.new
|
107
|
+
button.signal_connect(:clicked) {@layoutPreview.zoom_out}
|
108
|
+
img = Gtk::Image.new :stock => Gtk::Stock::ZOOM_OUT, :size => :small_toolbar
|
109
|
+
button << img
|
110
|
+
@toolbar.pack_start button, :expand => false, :fill => false, :padding => 0
|
111
|
+
|
112
|
+
button = Gtk::Button.new
|
113
|
+
button.signal_connect(:clicked) {@layoutPreview.zoom_fit}
|
114
|
+
img = Gtk::Image.new :stock => Gtk::Stock::ZOOM_FIT, :size => :small_toolbar
|
115
|
+
button << img
|
116
|
+
@toolbar.pack_start button, :expand => false, :fill => false, :padding => 0
|
117
|
+
|
118
|
+
sep = Gtk::Separator.new :vertical
|
119
|
+
@toolbar.pack_start sep, :expand => false, :fill => false, :padding => 8
|
120
|
+
|
121
|
+
button = Gtk::Button.new
|
122
|
+
button.signal_connect(:clicked) {on_print}
|
123
|
+
img = Gtk::Image.new :stock => Gtk::Stock::PRINT, :size => :small_toolbar
|
124
|
+
button << img
|
125
|
+
@toolbar.pack_start button, :expand => false, :fill => false, :padding => 0
|
126
|
+
end
|
127
|
+
|
128
|
+
|
129
|
+
def on_print
|
130
|
+
# set the borders from the selected label sheet
|
131
|
+
pageSetup = Gtk::PageSetup.new
|
132
|
+
pageSetup.set_left_margin @pageData[:borders][0], :mm
|
133
|
+
pageSetup.set_top_margin @pageData[:borders][1], :mm
|
134
|
+
pageSetup.set_right_margin @pageData[:borders][0], :mm
|
135
|
+
pageSetup.set_bottom_margin @pageData[:borders][1], :mm
|
136
|
+
|
137
|
+
|
138
|
+
printOperation = Gtk::PrintOperation.new
|
139
|
+
printOperation.show_progress = true
|
140
|
+
printOperation.default_page_setup = pageSetup
|
141
|
+
printOperation.n_pages = (@layoutPreview.elementDataData.length().to_f /
|
142
|
+
(@pageData[:cols] * @pageData[:rows]).to_f).ceil
|
143
|
+
|
144
|
+
printOperation.signal_connect('draw-page') do |widget, printContext, pageNumber|
|
145
|
+
cc = printContext.cairo_context
|
146
|
+
@layoutPreview.print_labels cc, pageNumber
|
147
|
+
end
|
148
|
+
|
149
|
+
ret = printOperation.run :print_dialog, self.toplevel
|
150
|
+
|
151
|
+
=begin
|
152
|
+
# only for debugging purpose
|
153
|
+
printOperation.signal_connect('end-print') {print "-=== printing ended\n"}
|
154
|
+
|
155
|
+
printOperation.signal_connect('status-changed') do
|
156
|
+
case printOperation.status
|
157
|
+
when Gtk::PrintOperation::Status::INITIAL
|
158
|
+
p 'initial'
|
159
|
+
when Gtk::PrintOperation::Status::PREPARING
|
160
|
+
p 'preparing'
|
161
|
+
when Gtk::PrintOperation::Status::GENERATING_DATA
|
162
|
+
p 'GENERATING_DATA'
|
163
|
+
when Gtk::PrintOperation::Status::SENDING_DATA
|
164
|
+
p 'SENDING_DATA'
|
165
|
+
when Gtk::PrintOperation::Status::PENDING
|
166
|
+
p 'PENDING'
|
167
|
+
when Gtk::PrintOperation::Status::PRINTING
|
168
|
+
p 'PRINTING'
|
169
|
+
when Gtk::PrintOperation::Status::FINISHED
|
170
|
+
p 'FINISHED'
|
171
|
+
when Gtk::PrintOperation::Status::FINISHED_ABORTED
|
172
|
+
p 'FINISHED_ABORTED'
|
173
|
+
else
|
174
|
+
'p unknown'
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
case ret
|
179
|
+
when Gtk::PrintOperation::Result::ERROR
|
180
|
+
print "error\n"
|
181
|
+
when Gtk::PrintOperation::Result::CANCEL
|
182
|
+
print "cancelled\n"
|
183
|
+
when Gtk::PrintOperation::Result::APPLY
|
184
|
+
print "applied\n"
|
185
|
+
when Gtk::PrintOperation::Result::IN_PROGRESS
|
186
|
+
print "in progress\n"
|
187
|
+
else
|
188
|
+
print "unknown result: ",printr.inspect,"\n"
|
189
|
+
end
|
190
|
+
=end
|
191
|
+
end
|
192
|
+
end
|
193
|
+
end
|