mcc2 1.5.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.
Files changed (120) hide show
  1. checksums.yaml +7 -0
  2. checksums.yaml.gz.sig +0 -0
  3. data/.autotest +23 -0
  4. data/.gitignore +15 -0
  5. data/.rubocop.yml +3 -0
  6. data/Gemfile +13 -0
  7. data/History.txt +6 -0
  8. data/LICENSE.txt +21 -0
  9. data/README.md +51 -0
  10. data/Rakefile +12 -0
  11. data/config/i18n-tasks.yml +193 -0
  12. data/exe/mcc2 +18 -0
  13. data/exe/mcc2-generate-preview +17 -0
  14. data/exe/mcc2print +6 -0
  15. data/lib/libguib16.rb +1620 -0
  16. data/lib/mcc2/advanced_data_edit_dlg.rb +139 -0
  17. data/lib/mcc2/cc_dialogbox.rb +52 -0
  18. data/lib/mcc2/constants.rb +154 -0
  19. data/lib/mcc2/dataman/base.rb +61 -0
  20. data/lib/mcc2/dataman/csv.rb +49 -0
  21. data/lib/mcc2/dataman/database.rb +8 -0
  22. data/lib/mcc2/dataman/dbf.rb +45 -0
  23. data/lib/mcc2/dataman/none.rb +25 -0
  24. data/lib/mcc2/dataview.rb +348 -0
  25. data/lib/mcc2/dataview_dlg.rb +232 -0
  26. data/lib/mcc2/debug_tools.rb +20 -0
  27. data/lib/mcc2/fx_colored_item.rb +101 -0
  28. data/lib/mcc2/generate_preview.rb +68 -0
  29. data/lib/mcc2/gui/advanced_data_edit_dlg.rbin +0 -0
  30. data/lib/mcc2/gui/dataview_dlg.pp +522 -0
  31. data/lib/mcc2/gui/layoutview_dlg.pp +5115 -0
  32. data/lib/mcc2/gui/mcc2_mainwin.pp +838 -0
  33. data/lib/mcc2/gui/picture_data_edit_dlg.rbin +0 -0
  34. data/lib/mcc2/gui/printerview_dlg.pp +3311 -0
  35. data/lib/mcc2/images/Image-Arrow-Left.gif +0 -0
  36. data/lib/mcc2/images/Image-Arrow-Right.gif +0 -0
  37. data/lib/mcc2/images/Image-FastArrowLeft.gif +0 -0
  38. data/lib/mcc2/images/Image-FastArrowRight.bmp +0 -0
  39. data/lib/mcc2/images/Image-FastArrowRight.gif +0 -0
  40. data/lib/mcc2/images/application-exit.png +0 -0
  41. data/lib/mcc2/images/copy.png +0 -0
  42. data/lib/mcc2/images/country_de.png +0 -0
  43. data/lib/mcc2/images/country_gb.png +0 -0
  44. data/lib/mcc2/images/country_rs.png +0 -0
  45. data/lib/mcc2/images/cut.png +0 -0
  46. data/lib/mcc2/images/distribute-horizontal-baseline.png +0 -0
  47. data/lib/mcc2/images/distribute-vertical-baseline.png +0 -0
  48. data/lib/mcc2/images/document-close.png +0 -0
  49. data/lib/mcc2/images/document-edit.png +0 -0
  50. data/lib/mcc2/images/document-new.png +0 -0
  51. data/lib/mcc2/images/document-open.png +0 -0
  52. data/lib/mcc2/images/document-print-frame.png +0 -0
  53. data/lib/mcc2/images/document-print.png +0 -0
  54. data/lib/mcc2/images/document-save-as.png +0 -0
  55. data/lib/mcc2/images/document-save.png +0 -0
  56. data/lib/mcc2/images/documentation.png +0 -0
  57. data/lib/mcc2/images/draw-rectangle.png +0 -0
  58. data/lib/mcc2/images/dummy.gif +0 -0
  59. data/lib/mcc2/images/exchange-positions.png +0 -0
  60. data/lib/mcc2/images/insert-image.png +0 -0
  61. data/lib/mcc2/images/insert-text.png +0 -0
  62. data/lib/mcc2/images/libreoffice-oasis-master-document.png +0 -0
  63. data/lib/mcc2/images/measure.png +0 -0
  64. data/lib/mcc2/images/messagebox_warning.png +0 -0
  65. data/lib/mcc2/images/paste.png +0 -0
  66. data/lib/mcc2/images/process-stop.png +0 -0
  67. data/lib/mcc2/images/zoom-in.png +0 -0
  68. data/lib/mcc2/layout.rb +323 -0
  69. data/lib/mcc2/layout_file.rb +794 -0
  70. data/lib/mcc2/layout_object/barcode.rb +33 -0
  71. data/lib/mcc2/layout_object/box.rb +18 -0
  72. data/lib/mcc2/layout_object/chip.rb +54 -0
  73. data/lib/mcc2/layout_object/embed.rb +16 -0
  74. data/lib/mcc2/layout_object/go_attribut.rb +16 -0
  75. data/lib/mcc2/layout_object/graphic.rb +59 -0
  76. data/lib/mcc2/layout_object/magstripe.rb +13 -0
  77. data/lib/mcc2/layout_object/picture.rb +22 -0
  78. data/lib/mcc2/layout_object/text.rb +29 -0
  79. data/lib/mcc2/layout_win.rb +2052 -0
  80. data/lib/mcc2/layoutview.rb +845 -0
  81. data/lib/mcc2/layoutview_dlg.rb +2058 -0
  82. data/lib/mcc2/locales.rb +27 -0
  83. data/lib/mcc2/mcc2_mainwin.rb +453 -0
  84. data/lib/mcc2/mcc2gui.rb +295 -0
  85. data/lib/mcc2/mcc2print.rb +54 -0
  86. data/lib/mcc2/picture_data_edit_dlg.rb +139 -0
  87. data/lib/mcc2/print_dlg.rb +520 -0
  88. data/lib/mcc2/printer/base.rb +148 -0
  89. data/lib/mcc2/printer/card_printer.rb +45 -0
  90. data/lib/mcc2/printer/file_printer.rb +135 -0
  91. data/lib/mcc2/printer/gdi_card_printer.rb +14 -0
  92. data/lib/mcc2/printer/gdi_printer.rb +197 -0
  93. data/lib/mcc2/printer/linux_cups_printer.rb +92 -0
  94. data/lib/mcc2/printer/preview.rb +277 -0
  95. data/lib/mcc2/printer/printer_cab.rb +118 -0
  96. data/lib/mcc2/printer/printer_cx320_direct.rb +286 -0
  97. data/lib/mcc2/printer/printer_epl.rb +118 -0
  98. data/lib/mcc2/printer/printer_ttp34x.rb +124 -0
  99. data/lib/mcc2/printer/printer_zebra.rb +324 -0
  100. data/lib/mcc2/printer/svg_drawer.rb +689 -0
  101. data/lib/mcc2/printerview.rb +604 -0
  102. data/lib/mcc2/printerview_dlg.rb +1248 -0
  103. data/lib/mcc2/version.rb +3 -0
  104. data/lib/mcc2.rb +11 -0
  105. data/locales/de.yml +6 -0
  106. data/locales/en.yml +502 -0
  107. data/locales/rs.yml +502 -0
  108. data/mcc2.gemspec +41 -0
  109. data/test/dummy.rb +19 -0
  110. data/test/layouts/bart_simpson.png +0 -0
  111. data/test/layouts/color_test.xml +151 -0
  112. data/test/layouts/ms.xml +67 -0
  113. data/test/ruby_print.rb +380 -0
  114. data/test/test.csv +4 -0
  115. data/test/test.dbf +0 -0
  116. data/test/test.str +4 -0
  117. data/test/test_mcc2.rb +8 -0
  118. data.tar.gz.sig +6 -0
  119. metadata +421 -0
  120. metadata.gz.sig +0 -0
@@ -0,0 +1,845 @@
1
+ module Mcc2
2
+ require "mcc2/layoutview_dlg"
3
+
4
+ class Layoutview
5
+ include Fox
6
+
7
+ JobSetupObjID = -1
8
+ DRAG_TYPE_NAME = "application/x-mcc2+xml"
9
+
10
+ # initialisiert zusätzliche Elemente im Layout-Dialog, die nicht oder schlecht im Fox-GUI-Builder erzeugt werden können
11
+ # setzt Parameter bei Dialog-Elementen
12
+ # definiert die Aktionen, welche bei bestimmten Ereignissen auf bestimmten Elementen des Dialogs ausgeführt werden sollen
13
+ # ==== Parameter
14
+ # +parent+:: ??
15
+ def initialize(parent, layout)
16
+ @layout = layout
17
+ @parent = parent
18
+ @layout_file = nil
19
+ @selected_object_ids = []
20
+
21
+ @lf = Dialogbox_layoutview.new parent
22
+ @lf.splitter_layoutview.reparent parent, nil
23
+ @lf.dialogbox_layoutview.close
24
+ columns = I18n.t(:columns_object_list, default:
25
+ [[["Name", 130],
26
+ ["Typ", 100],
27
+ ]])
28
+ columns.each do |name, width|
29
+ @lf.iconlist_objects.appendHeader(name, nil, width * $gui_scale)
30
+ end
31
+
32
+ @lf.splitter_layoutview.setSplit(0, 250 * $gui_scale)
33
+ @lf.splitter12.setSplit(0, 70 * $gui_scale)
34
+
35
+ # .............................................................................................
36
+ # die Aktionen definieren, die ausgeführt werden, wenn am Layout irgend etwas gearbeitet wird
37
+
38
+ # die Buttons für das Ändern der Objektreihenfolge
39
+ @lf.button_up.connect(SEL_COMMAND) { object_move_up_down(UP) }
40
+ @lf.button_down.connect(SEL_COMMAND) { object_move_up_down(DOWN) }
41
+
42
+ @text_field_trigger = SEL_CHANGED
43
+ # text_field_trigger = SEL_CHANGED # geht sehr langsam und macht bei Barcode und Bild Probleme
44
+
45
+ # Objektliste
46
+ @lf.iconlist_objects.connect(SEL_SELECTED) { object_selected }
47
+ @lf.iconlist_objects.connect(SEL_DESELECTED) { object_selected }
48
+
49
+ # die allgemeinen Objektattribute
50
+ @lf.textfield_name.connect(SEL_COMMAND) { obj_attr_changed(GOA_NAME, @lf.textfield_name.text) }
51
+
52
+ # die Daten-Attribute
53
+ @lf.textfield_data_non_text.connect(@text_field_trigger) { |sender, sel, event| textfield_exit(sender, GOA_DATA) }
54
+ @lf.textfield_data_non_text.connect(SEL_COMMAND) { |sender, sel, event| textfield_exit(sender, GOA_DATA) }
55
+ @lf.textfield_data.connect(SEL_CHANGED) { |sender, sel, event| textfield_exit(sender, GOA_DATA) }
56
+ @lf.textfield_sample_data.connect(SEL_CHANGED) { |sender, sel, event| textfield_exit(sender, GOA_SAMPLE_DATA) }
57
+
58
+ # die Font-Attribute
59
+ @lf.textfield_text_color.connect(SEL_COMMAND) { |sender, sel, event| textfield_exit(sender, GOA_FONT_COLOR) }
60
+ @lf.button_text_color.connect(SEL_COMMAND) { text_color_dialog(@lf.textfield_text_color) }
61
+ @lf.radiomutex_justify.on_event_selected do |r|
62
+ v = if r==@lf.radiobutton_just_l then S_JUST_LEFT
63
+ elsif r==@lf.radiobutton_just_m then S_JUST_MID
64
+ elsif r==@lf.radiobutton_just_r then S_JUST_RIGHT
65
+ end
66
+ obj_attr_changed(GOA_JUSTIFICATION, v)
67
+ end
68
+
69
+ # die Positions-Attribute
70
+ @lf.textfield_x.connect(@text_field_trigger) { |sender, sel, event| textfield_exit(sender, GOA_X) }
71
+ @lf.textfield_y.connect(@text_field_trigger) { |sender, sel, event| textfield_exit(sender, GOA_Y) }
72
+ @lf.textfield_width.connect(@text_field_trigger) { |sender, sel, event| textfield_exit(sender, GOA_WIDTH) }
73
+ @lf.textfield_height.connect(@text_field_trigger) { |sender, sel, event| textfield_exit(sender, GOA_HEIGHT) }
74
+ @lf.textfield_rotation.connect(@text_field_trigger) { |sender, sel, event| textfield_exit(sender, GOA_ROTATION) }
75
+
76
+ # die Checkbox, ob der Inhalt des Feldes in der Liste des Druckdialogs mit angezeigt werden soll
77
+ @lf.checkbutton_printlist.connect(SEL_COMMAND) { obj_attr_changed(GOA_PRINTLIST, @lf.checkbutton_printlist.state) }
78
+
79
+ # die Textfelder für die allgemeine Layoutoptionen
80
+ @lf.textfield_x_offset.connect(@text_field_trigger) { |sender, sel, event| textfield_exit(sender, S_X_OFFSET) }
81
+ @lf.textfield_y_offset.connect(@text_field_trigger) { |sender, sel, event| textfield_exit(sender, S_Y_OFFSET) }
82
+ @lf.textfield_page_width.connect(@text_field_trigger) { |sender, sel, event| textfield_exit(sender, S_WIDTH) }
83
+ @lf.textfield_page_height.connect(@text_field_trigger) { |sender, sel, event| textfield_exit(sender, S_HEIGHT) }
84
+ l = @lf.combobox_datasource_typ
85
+ l.clearItems
86
+ l.appendItem(I18n.t(:datasource_type_none, default: "keine Daten - statisches Layout"), NONE)
87
+ l.appendItem(I18n.t(:datasource_type_csv, default: "CSV-Datei"), CSV)
88
+ l.appendItem(I18n.t(:datasource_type_dbf, default: "DBF-Datei"), DBF)
89
+ l.appendItem(I18n.t(:datasource_type_database, default: "Datenbank"), DATABASE)
90
+ l.connect(SEL_COMMAND) do
91
+ value = @lf.combobox_datasource_typ.getItemData(@lf.combobox_datasource_typ.currentItem)
92
+ attr_changed(S_DATASOURCETYP, value)
93
+ end
94
+
95
+ l = @lf.combobox_datasource_encoding
96
+ l.clearItems
97
+ VALID_ENCODINGS.each { |enc| l.appendItem(enc, enc) }
98
+ l.connect(SEL_COMMAND) do
99
+ value = @lf.combobox_datasource_encoding.getItemData(@lf.combobox_datasource_encoding.currentItem)
100
+ attr_changed(S_DATASOURCEENCODING, value)
101
+ end
102
+
103
+ # die Auswahl auf welche Seite das Objekt soll
104
+ @lf.spinner_seiten_nr.connect(SEL_COMMAND) { obj_attr_changed(GOA_PAGE_NR, @lf.spinner_seiten_nr.value - 1) }
105
+ @lf.spinner_seiten_nr.range = (1..999)
106
+ @lf.spinner_layer.connect(SEL_COMMAND) { obj_attr_changed(GOA_LAYER, @lf.spinner_layer.value) }
107
+ @lf.spinner_image_page.connect(SEL_COMMAND) { obj_attr_changed(GOA_IMAGE_PAGE, @lf.spinner_image_page.value) }
108
+ @lf.spinner_image_page.range = (1..999)
109
+
110
+ # der Checkbutton für die Einstellung Simplex/Duplex
111
+ @lf.checkbutton_duplex.connect(SEL_COMMAND) { |sender, sel, event| change_chkbtn(sender, S_DUPLEX) }
112
+ @lf.checkbutton_flip_front.connect(SEL_COMMAND) { |sender, sel, event| change_chkbtn(sender, S_FRONT_FLIP) }
113
+ @lf.checkbutton_flop_front.connect(SEL_COMMAND) { |sender, sel, event| change_chkbtn(sender, S_FRONT_FLOP) }
114
+ @lf.checkbutton_flip_back.connect(SEL_COMMAND) { |sender, sel, event| change_chkbtn(sender, S_BACK_FLIP) }
115
+ @lf.checkbutton_flop_back.connect(SEL_COMMAND) { |sender, sel, event| change_chkbtn(sender, S_BACK_FLOP) }
116
+
117
+ # der Button auf den Objektattributen, mit dem die Daten erweitert bearbeitet werden können (Variablen aus der Datenquelle verwenden usw.)
118
+ @lf.menubutton_enhanced_data_edit.connect(SEL_LEFTBUTTONPRESS) { enhanced_data_edit(@lf.menubutton_enhanced_data_edit, @lf.textfield_data_non_text) }
119
+ @lf.menubutton_enhanced_data_text_edit.connect(SEL_LEFTBUTTONPRESS) { enhanced_data_edit(@lf.menubutton_enhanced_data_text_edit, @lf.textfield_data) }
120
+
121
+ @lf.menubutton_sample_data.connect(SEL_LEFTBUTTONPRESS) { button_sample_data }
122
+ @layout.add_tipText_to_filedialog_for_textfield(@lf.textfield_sample_data)
123
+
124
+ # die Listbox zum Auswählen der Schriftart
125
+ @lf.listbox_fonts.connect(SEL_COMMAND) { |sender, sel, event| sel_list_box_changed(sender) }
126
+ @lf.textfield_font_file.connect(SEL_COMMAND) { |sender, sel, event| textfield_exit(sender, GOA_FONT_FILE) }
127
+ @layout.connect_filebutton_to_textfield(@lf.button_fontfile_select, @lf.textfield_font_file,
128
+ filepatterns: ["Truetype/Opentype font (*.ttf,*.otf)", "PS-type1 font (*.pfb)", "All Files (*)"])
129
+ @lf.textfield_fontsize.connect(@text_field_trigger) { |sender, sel, event| textfield_exit(sender, GOA_FONT_HEIGHT) }
130
+
131
+ # der Checkbuttons für die Einstellung, ob Magnestreifen, Kontaktchip und Kontaktlos personalisiert werden sollen
132
+ @lf.checkbutton_contactless.connect(SEL_COMMAND) { |sender, sel, event| change_chkbtn(sender, S_CONTACTLESS) }
133
+ @lf.checkbutton_contact.connect(SEL_COMMAND) { |sender, sel, event| change_chkbtn(sender, S_CONTACT) }
134
+ @lf.checkbutton_magstripe.connect(SEL_COMMAND) { |sender, sel, event| change_chkbtn(sender, S_MAGSTRIPE) }
135
+
136
+ @lf.textfield_box_fill_color.connect(SEL_COMMAND) { |sender, sel, event| textfield_exit(sender, GOA_FILL_COLOR) }
137
+ @lf.button_box_fill_color.connect(SEL_COMMAND) { text_color_dialog(@lf.textfield_box_fill_color) }
138
+ @lf.textfield_box_border_color.connect(SEL_COMMAND) { |sender, sel, event| textfield_exit(sender, GOA_BORDER_COLOR) }
139
+ @lf.button_box_border_color.connect(SEL_COMMAND) { text_color_dialog(@lf.textfield_box_border_color) }
140
+ @lf.textfield_box_border_width.connect(@text_field_trigger) { |sender, sel, event| textfield_exit(sender, GOA_BORDER_WIDTH) }
141
+ @lf.textfield_box_corner_radius.connect(@text_field_trigger) { |sender, sel, event| textfield_exit(sender, GOA_CORNER_RADIUS) }
142
+
143
+ # die Checkbuttons für das Löschen und Kopieren von Graphik-Objekten
144
+ @lf.button_copy.enabled = false
145
+ @lf.button_copy.connect(SEL_COMMAND) { manage_objects(COPY) }
146
+ @lf.button_delete.enabled = false
147
+ @lf.button_delete.connect(SEL_COMMAND) { manage_objects(DELETE) }
148
+ @lf.button_move_up.connect(SEL_COMMAND) {|sender, sel, event| move_selected(0, -1) }
149
+ @lf.button_move_down.connect(SEL_COMMAND) {|sender, sel, event| move_selected(0, 1) }
150
+ @lf.button_move_left.connect(SEL_COMMAND) {|sender, sel, event| move_selected(-1, 0) }
151
+ @lf.button_move_right.connect(SEL_COMMAND) {|sender, sel, event| move_selected(1, 0) }
152
+
153
+ # die Textfelder für die Magnetstreifenattribute
154
+ @lf.textfield_spur1.connect(@text_field_trigger) { |sender, sel, event| textfield_exit(sender, S_MSSPUR1) }
155
+ @lf.textfield_spur2.connect(@text_field_trigger) { |sender, sel, event| textfield_exit(sender, S_MSSPUR2) }
156
+ @lf.textfield_spur3.connect(@text_field_trigger) { |sender, sel, event| textfield_exit(sender, S_MSSPUR3) }
157
+
158
+ @barcodes = if Object.const_defined?(:Zint)
159
+ [
160
+ :Aztec,
161
+ :C25inter,
162
+ :C25standard,
163
+ :Codabar,
164
+ :CodablockF,
165
+ :Code11,
166
+ :Code128,
167
+ :Code128AB,
168
+ :Code128B,
169
+ :Code16k,
170
+ :Code32,
171
+ :Code39,
172
+ :Code49,
173
+ :Code93,
174
+ :CodeOne,
175
+ :DataMatrix,
176
+ :DotCode,
177
+ :Ean128,
178
+ :Ean14,
179
+ :Eanx,
180
+ :EanxChk,
181
+ :Excode39,
182
+ :Gs1_128,
183
+ :C25inter,
184
+ :MaxiCode,
185
+ :MicroPdf417,
186
+ :MicroQr,
187
+ :Pdf417,
188
+ :Pdf417comp,
189
+ :Pdf417trunc,
190
+ :Qr,
191
+ :UpcA,
192
+ :UpcAChk,
193
+ :UpcE,
194
+ :UpcEChk
195
+ ]
196
+ else
197
+ []
198
+ end
199
+ @lf.listbox_barcode_typ.connect(SEL_COMMAND) { |sender, sel, event| sel_list_box_changed(sender) }
200
+ [1, 2, 3].each do |optx|
201
+ @lf.send("spinner_barcode_option_#{optx}").connect(SEL_COMMAND) do
202
+ changed_attributes if @layout_file.set_object_by_ids(@selected_object_ids, Mcc2.const_get("GOA_BARCODE_OPTION_#{optx}"), @lf.send("spinner_barcode_option_#{optx}").value)
203
+ end
204
+ end
205
+ @lf.spinner_barcode_height.connect(SEL_COMMAND) do
206
+ changed_attributes if @layout_file.set_object_by_ids(@selected_object_ids, GOA_BARCODE_HEIGHT, @lf.spinner_barcode_height.value)
207
+ end
208
+ @lf.checkbutton_barcode_optimized.connect(SEL_COMMAND) do
209
+ changed_attributes if @layout_file.set_object_by_ids(@selected_object_ids, GOA_BARCODE_OPTIMIZED, @lf.checkbutton_barcode_optimized.checked?)
210
+ end
211
+ @lf.checkbutton_justify.connect(SEL_COMMAND) do
212
+ changed_attributes if @layout_file.set_object_by_ids(@selected_object_ids, GOA_JUSTIFICATION_BLOCK, @lf.checkbutton_justify.checked?)
213
+ end
214
+
215
+ # Register the drag type for copy and paste by the clipboard
216
+ @drag_type = @parent.app.registerDragType(DRAG_TYPE_NAME)
217
+ # Handle request for DND data
218
+ @parent.connect(SEL_CLIPBOARD_REQUEST) do |sender, sel, event|
219
+ @parent.setDNDData(FROM_CLIPBOARD, @drag_type, @clipboard_xml_frag) if event.target == @drag_type
220
+ end
221
+
222
+ create_chipparam_fields
223
+
224
+ fill_objectlist
225
+ object_selection_changed
226
+ end
227
+
228
+ # erzeugt Textfelder für die Eingabe der Chip-Parameter
229
+ # erzeugt so viele Felder, wie in der Methode anz_params der Klasse Chip definiert sind
230
+ # erzeugt ein Array, in welchem alle Felder gespeichert sind
231
+ def create_chipparam_fields
232
+ @chipparam_textfields = []
233
+
234
+ scrl_w = FX::ScrollWindow.new(@lf.verticalframe_chip, LAYOUT_FILL_X | LAYOUT_FILL_Y)
235
+ matrix_chipparams = FX::Matrix.new(scrl_w, LAYOUT_FILL_X | LAYOUT_FILL_Y) do |w|
236
+ @matrix3 = w
237
+ w.wdg_name = "matrix_xyz"
238
+ w.numRows = 4
239
+ w.numColumns = 2
240
+ w.width = 650 * $gui_scale
241
+ w.y = 2
242
+ w.height = 0
243
+ w.matrixStyle = MATRIX_BY_COLUMNS | LAYOUT_FILL_X | LAYOUT_FILL_Y
244
+ w.x = 2
245
+ end
246
+
247
+ (0...CHIPPARAM_FIELD_COUNT).each do |i|
248
+ FX::Label.new(matrix_chipparams) do |w|
249
+ w.wdg_name = "label_chipparam_#{i}"
250
+ w.text = I18n.t(:chipparam_label, default: "Parameter %{i}", i: i+1)
251
+ w.font = FX::Font.new.from_s("Helvetica|80|40|5|0|0|0").to_FXFont
252
+ end
253
+ tf = FX::TextField.new(matrix_chipparams, LAYOUT_FILL_X) do |w|
254
+ w.textFieldTextStyle = LAYOUT_FILL_X
255
+ w.wdg_name = "textfield_chipparam_#{i}"
256
+ w.font = FX::Font.new.from_s("Helvetica|80|40|5|0|0|0").to_FXFont
257
+ w.numColumns = 40
258
+ end
259
+ tf.connect(@text_field_trigger) { |sender, sel, event| textfield_exit(sender, S_CHIPPARAMS) }
260
+ @chipparam_textfields << tf
261
+ end
262
+ end
263
+
264
+ def layoutview_tab_activated(active = true)
265
+ draw_preview if active
266
+ end
267
+
268
+ def layout_file= file
269
+ @layout_file = file
270
+
271
+ # füllt die Liste mit der Übersicht über die graphischen Objekte
272
+ fill_objectlist
273
+
274
+ # die allgemeinen Layout-Attribute
275
+ fill_layout_attr_tab
276
+
277
+ # die Chip-Attribute
278
+ chip = @layout_file.chip_object
279
+ chip.params.each_with_index do |param, idx|
280
+ @chipparam_textfields[idx].text = param
281
+ end
282
+
283
+ # die Magnetstreifenattribute
284
+ mag_attrs = @layout_file.magstripe_object
285
+ @lf.textfield_spur1.text = mag_attrs[S_MSSPUR1]
286
+ @lf.textfield_spur2.text = mag_attrs[S_MSSPUR2]
287
+ @lf.textfield_spur3.text = mag_attrs[S_MSSPUR3]
288
+
289
+ draw_preview(true)
290
+ end
291
+
292
+ def enhanced_data_edit(menubutton, textfield)
293
+ if (dm = @layout.dataman)
294
+ menupane = menubutton.menu
295
+ menupane.each_child { |ch| menupane.removeChild(ch) }
296
+ [dm.data_headers, dm.meta_headers].each_with_index do |headers, idx|
297
+ FXMenuSeparator.new(menupane) if idx > 0
298
+ headers.each do |col|
299
+ FXMenuCommand.new(menupane, col).connect(SEL_COMMAND) do
300
+ text = textfield.text
301
+ text.bytesplice(textfield.cursorPos, 0, "{#{col}[0,999]}")
302
+ textfield.setText(text, true)
303
+ end
304
+ end
305
+ end
306
+ menupane.create
307
+ menupane.resize(menupane.getDefaultWidth, menupane.getDefaultHeight)
308
+ menubutton.handle(menubutton, Fox.FXSEL(Fox::SEL_COMMAND, Fox::FXMenuButton::ID_POST), nil)
309
+ end
310
+ end
311
+
312
+ def button_sample_data
313
+ typ = @layout_file.get_object_by_id(@selected_object_ids.last, GOA_TYP)
314
+ if [PICTUREOBJECT, EMBEDOBJECT].include?(typ)
315
+ @layout.execute_filedialog_for_textfield(@lf.textfield_sample_data, filepatterns: "*")
316
+ end
317
+ end
318
+
319
+ # die Reaktion, wenn der Status eines Checkbuttons geänderrt wurde
320
+ # setzt das changed-Flag
321
+ # ==== Parameter
322
+ # +sender+:: das Objekt, welches das Ereignis gesendet hat
323
+ # +attr_name+:: der Name des Attributs
324
+ def change_chkbtn(sender, attr_name)
325
+ if @layout_file.set_attr_value attr_name, sender.state.to_s
326
+ changed_attributes
327
+ end
328
+ end
329
+ #---------------------------------------------------------------------------------------------------------
330
+
331
+ # mit dieser Methode kann ein Objekt in der Liste der Objekte nach oben oder unten verschoben werden
332
+ # die Position hat einen Einfluss auf das Druckbild, wird zum Beispiel ein Bild gedruckt werden Objekte,
333
+ # die weiter oben stehen, hinter diesem Bild gedruckt
334
+ # ==== Parameter
335
+ # +dest+:: die Richtung (UP, oder DOWN)
336
+ def object_move_up_down(dest)
337
+ # erst einmal eine sortierte Liste aller ID's der Grafikobjekte holen
338
+ obj_arr = @layout_file.sorted_id_list
339
+
340
+ # die Positionen in dieser Liste ermitteln und von oben nach unten abarbeiten
341
+ positions = @selected_object_ids.map do |object_id|
342
+ obj_arr.index(object_id)
343
+ end.sort
344
+ # bzw. von unten nach oben, wenn Objekte nach unten geschoben werden
345
+ positions.reverse! if dest == DOWN
346
+
347
+ positions.each do |pos|
348
+ # dann das entsprechende Objekt mit dem nächstgelegenen tauschen
349
+ if dest == UP
350
+ obj_arr[pos], obj_arr[pos - 1] = obj_arr[pos - 1], obj_arr[pos]
351
+ elsif dest == DOWN
352
+ obj_arr[pos], obj_arr[pos + 1] = obj_arr[pos + 1], obj_arr[pos]
353
+ end
354
+ end
355
+
356
+ # Nun im XML reindexieren
357
+ @layout_file.reorder_id_list(obj_arr)
358
+
359
+ # changed-Flag setzen
360
+ changed_attributes
361
+
362
+ # Objekt-Liste aktualisieren
363
+ currentItem = @lf.iconlist_objects.currentItem
364
+ selected_items = @lf.iconlist_objects.map.with_index.select { |i, x| i.selected? }.map(&:last)
365
+ fill_objectlist
366
+ @selected_object_ids = []
367
+
368
+ # Cursor in Liste setzen
369
+ notify = true
370
+ if currentItem > 1 && dest == UP
371
+ @lf.iconlist_objects.setCurrentItem(currentItem - 1, notify)
372
+ selected_items.each do |idx|
373
+ @lf.iconlist_objects.selectItem(idx - 1, notify)
374
+ end
375
+ elsif currentItem > 0 && currentItem < @lf.iconlist_objects.numItems && dest == DOWN
376
+ @lf.iconlist_objects.setCurrentItem(currentItem + 1, notify)
377
+ selected_items.each do |idx|
378
+ @lf.iconlist_objects.selectItem(idx + 1, notify)
379
+ end
380
+ end
381
+ end
382
+
383
+ # öffnet einen Dialog, mit dem die Textfarbe gewählt werden kann und
384
+ # trägt diese in das Textfeld für die Farbangabe ein
385
+ # zeichnet anschließend die Vorschau neu
386
+ def text_color_dialog(textfield)
387
+ cdlg = FXColorDialog.new(@parent, I18n.t(:text_color_dialog_caption, default: "Textfarbe"))
388
+ if cdlg.execute > 0 && textfield.text != cdlg.rgba
389
+ s = cdlg.rgba.to_i.to_s(16)
390
+ textfield.setText([s[6, 2], s[4, 2], s[2, 2], s[0, 2]].join, true)
391
+ end
392
+ end
393
+
394
+ def attr_changed(attr, value)
395
+ if @layout_file.set_attr_value(attr, value)
396
+ changed_attributes
397
+ end
398
+ end
399
+
400
+ def obj_attr_changed(attr, value)
401
+ if @layout_file.set_object_by_ids(@selected_object_ids, attr, value.to_s)
402
+ changed_attributes
403
+ fill_objectlist if [GOA_NAME, GOA_TYP].include?(attr)
404
+ end
405
+ end
406
+ #---------------------------------------------------------------------------------------------------------
407
+
408
+ # händelt für bestimmte Textfelder das Eintragen des Textes in das jeweilige Attribut in der XML-Struktur
409
+ # setzt das changed-Flag
410
+ # ==== Parameter
411
+ # +sender+:: das Objekt, welches das Ereignis gesendet hat
412
+ # +attr_name+:: der Name des Attributs
413
+ def textfield_exit(sender, attr_name)
414
+ changed = if attr_name == S_CHIPPARAMS
415
+ # aus dem Namen des Textfeldes die ID ermitteln (sind durchnummeriert)
416
+ id = sender.wdg_name.split("_")[-1].to_i
417
+
418
+ # den entsprechenden Parameter suchen
419
+ attr_name = "#{S_PARAM}_#{id + 1}"
420
+ @layout_file.set_attr_value(attr_name, sender.text, S_CHIP)
421
+ elsif [S_X_OFFSET, S_Y_OFFSET, S_WIDTH, S_HEIGHT].include?(attr_name)
422
+ @layout_file.set_attr_value(attr_name, sender.text)
423
+ elsif [S_MSSPUR1, S_MSSPUR2, S_MSSPUR3].include?(attr_name)
424
+ @layout_file.set_attr_value(attr_name, sender.text, S_MAGSTRIPEPARAMS)
425
+ else
426
+ # in diesem Zweig werden alle Graphik-Objekte bearbeitet
427
+ # das Attribut suchen
428
+ @layout_file.set_object_by_ids(@selected_object_ids, attr_name, sender.text)
429
+ end
430
+ changed_attributes if changed
431
+ end
432
+
433
+ # deaktivieren der Anzeige der Objektattribute, wenn kein Objekt selektiert ist
434
+ def activate_object_tabs(on = true)
435
+ @lf.tabitem_object.shown = on
436
+ @lf.tabitem_posit.shown = on
437
+ @lf.tabitem_font.shown = on
438
+ @lf.tabitem_barcode.shown = on
439
+ @lf.tabitem_box.shown = on
440
+ end
441
+
442
+ def activate_job_tabs(on = true)
443
+ @lf.tabitem_allgemein.shown = on
444
+ @lf.tabitem_chip.shown = on
445
+ @lf.tabitem_magstripe.shown = on
446
+ end
447
+
448
+ # deaktiviert die Buttons für das Verschieben der Objekte in der Objektliste (zum Beispiel, wenn kein Objekt selektiert ist)
449
+ def activate_up_down(on = true)
450
+ @lf.button_up.enabled = on
451
+ @lf.button_down.enabled = on
452
+ end
453
+
454
+ def activate_copy_delete(on = true)
455
+ @lf.button_copy.enabled = on
456
+ @lf.button_delete.enabled = on
457
+ @lf.button_move_up.enabled = on
458
+ @lf.button_move_down.enabled = on
459
+ @lf.button_move_left.enabled = on
460
+ @lf.button_move_right.enabled = on
461
+ end
462
+
463
+ def object_selected
464
+ item_ids = @lf.iconlist_objects.select { |i| i.selected? }.map { |i| i.data }
465
+ @layout.selected_object_ids = item_ids
466
+ end
467
+
468
+ attr_reader :selected_object_ids
469
+ def selected_object_ids=(ids)
470
+ @selected_object_ids = ids
471
+ object_selection_changed
472
+ end
473
+
474
+ # wenn in der Objektliste ein anderes Objekt selektiert wird, dann werden mit dieser Methode die Anzeigen aktualisiert,
475
+ # z.Bsp, nur die Tabs aktiviert, die zum Objekttyp passen, usw.
476
+ def object_selection_changed
477
+ if @selected_object_ids.empty?
478
+ # No object selected
479
+ activate_object_tabs(false)
480
+ activate_up_down(false)
481
+ activate_copy_delete(false)
482
+ @lf.iconlist_objects.killSelection
483
+
484
+ elsif @selected_object_ids == [JobSetupObjID]
485
+ # Job-Setup selected
486
+ activate_job_tabs
487
+ @lf.tabbook_objectattributes.current = 0
488
+
489
+ else
490
+ # Graphic object selected
491
+ pos = @lf.iconlist_objects.findItemByData(@selected_object_ids.last)
492
+ @lf.iconlist_objects.setCurrentItem(pos) if @lf.iconlist_objects.currentItem == -1
493
+ @lf.iconlist_objects.makeItemVisible(pos)
494
+ @lf.iconlist_objects.killSelection
495
+ @selected_object_ids.each do |id|
496
+ pos = @lf.iconlist_objects.findItemByData(id)
497
+ @lf.iconlist_objects.selectItem(pos)
498
+ end
499
+
500
+ # erst einmal alle Objekt-Tabs deaktivieren, damit sicher gestellt ist, dass nur die Objekt-typischen angezeigt werden
501
+ activate_object_tabs(false)
502
+ activate_job_tabs(false)
503
+ activate_copy_delete
504
+
505
+ # die Buttons für das Ändern der Reihenfolge aktivieren
506
+ positions = @selected_object_ids.map { |id| @lf.iconlist_objects.findItemByData(id) }
507
+ @lf.button_up.enabled = positions.all? { |po| po > 1 }
508
+ num_objects = @layout_file.sorted_id_list.length
509
+ @lf.button_down.enabled = positions.all? { |po| po < num_objects }
510
+
511
+ obj = @layout_file.find_graphic_object_by_id(@selected_object_ids.last)
512
+
513
+ # allgemeine Attribute auslesen
514
+ @lf.tabitem_object.shown = true
515
+ @lf.tabitem_posit.shown = true
516
+
517
+ # Daten-Attribute
518
+ @lf.textfield_name.text = obj[GOA_NAME]
519
+
520
+ # Positionsattribute
521
+ @lf.textfield_x.text = obj[GOA_X]
522
+ @lf.textfield_y.text = obj[GOA_Y]
523
+ @lf.textfield_width.text = obj[GOA_WIDTH]
524
+ @lf.textfield_height.text = obj[GOA_HEIGHT]
525
+ @lf.textfield_rotation.text = obj[GOA_ROTATION]
526
+ @lf.textfield_rotation.text = obj[GOA_ROTATION]
527
+ @lf.spinner_seiten_nr.value = obj[GOA_PAGE_NR].to_i + 1
528
+ @lf.spinner_layer.value = obj[GOA_LAYER].to_i
529
+ # @lf.iconlist_justify.connect(SEL_CHANGED){iconlist_justify_exit } # todo
530
+
531
+ @lf.checkbutton_printlist.state = !(obj[GOA_PRINTLIST] == "false" || obj[GOA_PRINTLIST] == "0")
532
+
533
+ # Typ-spezifische Attribute auslesen
534
+ if [BARCODEOBJECT, TEXTOBJECT, PICTUREOBJECT, EMBEDOBJECT].include?(obj[GOA_TYP])
535
+ @lf.textfield_sample_data.text = obj[GOA_SAMPLE_DATA]
536
+ @lf.textfield_data.text = obj[GOA_DATA]
537
+ @lf.textfield_data_non_text.text = obj[GOA_DATA]
538
+ end
539
+
540
+ # Attribute, die Barcode und Texte haben
541
+ if obj[GOA_TYP] == TEXTOBJECT || obj[GOA_TYP] == BARCODEOBJECT
542
+ @lf.tabitem_font.shown = true
543
+ @lf.textfield_text_color.text = obj[GOA_FONT_COLOR]
544
+
545
+ fill_font_list
546
+ fill_font_fields(obj)
547
+ end
548
+
549
+ # Attribute, die nur Texte haben
550
+ if obj[GOA_TYP] == TEXTOBJECT
551
+ @lf.horizontalframe_justify.shown = true
552
+ # den Radiobutton der Ausrichtung setzen
553
+ @lf.radiobutton_just_l.state = false
554
+ @lf.radiobutton_just_m.state = false
555
+ @lf.radiobutton_just_r.state = false
556
+ case obj[GOA_JUSTIFICATION]
557
+ when S_JUST_LEFT
558
+ @lf.radiobutton_just_l.state = true
559
+ when S_JUST_MID
560
+ @lf.radiobutton_just_m.state = true
561
+ when S_JUST_RIGHT
562
+ @lf.radiobutton_just_r.state = true
563
+ end
564
+ @lf.checkbutton_justify.setCheck(obj[GOA_JUSTIFICATION_BLOCK] == "true")
565
+
566
+ data_block_shown
567
+ end
568
+
569
+ # Attribute, die nur Barcodes haben
570
+ if obj[GOA_TYP] == BARCODEOBJECT
571
+ @lf.tabitem_barcode.shown = true
572
+ @lf.horizontalframe_justify.shown = false
573
+ [1, 2, 3].each do |optx|
574
+ @lf.send("spinner_barcode_option_#{optx}").value = obj[Mcc2.const_get("GOA_BARCODE_OPTION_#{optx}")].to_i
575
+ end
576
+ @lf.spinner_barcode_height.value = obj[GOA_BARCODE_HEIGHT].to_f
577
+ @lf.checkbutton_barcode_optimized.setCheck(obj[GOA_BARCODE_OPTIMIZED] == "true")
578
+ fill_barcode_typ_list
579
+ fill_barcode_fields(obj)
580
+ data_shown
581
+ end
582
+
583
+ # Attribute, die nur Bilder haben
584
+ if obj[GOA_TYP] == PICTUREOBJECT
585
+ data_shown
586
+ end
587
+
588
+ if obj[GOA_TYP] == BOXOBJECT
589
+ @lf.tabitem_box.shown = true
590
+ @lf.tabitem_box.recalc
591
+ @lf.textfield_box_fill_color.text = obj[GOA_FILL_COLOR]
592
+ @lf.textfield_box_border_color.text = obj[GOA_BORDER_COLOR]
593
+ @lf.textfield_box_border_width.text = obj[GOA_BORDER_WIDTH]
594
+ @lf.textfield_box_corner_radius.text = obj[GOA_CORNER_RADIUS]
595
+ no_data_shown
596
+ end
597
+
598
+ if obj[GOA_TYP] == EMBEDOBJECT
599
+ data_shown
600
+ end
601
+ end
602
+
603
+ draw_preview(true)
604
+ end
605
+ #---------------------------------------------------------------------------------------------------------
606
+
607
+ def sel_list_box_changed(sender)
608
+ # ~ obj[GOA_FONT_HEIGHT] = (fontdesc.size.to_f/10).to_s
609
+
610
+ changed = if sender.wdg_name == "listbox_fonts"
611
+ font = @lf.listbox_fonts.getItemData(@lf.listbox_fonts.currentItem)
612
+ @lf.textfield_font_file.enabled = font == "from_file"
613
+ @layout_file.set_object_by_ids(@selected_object_ids, GOA_FONT_TYP, font)
614
+ elsif sender.wdg_name == "listbox_barcode_typ"
615
+ bc = @lf.listbox_barcode_typ.getItemText(@lf.listbox_barcode_typ.currentItem)
616
+ @layout_file.set_object_by_ids(@selected_object_ids, GOA_BARCODE_TYP, bc)
617
+ else
618
+ raise "unknown sender. Programmers fault. :-("
619
+ end
620
+ changed_attributes if changed
621
+ end
622
+ #---------------------------------------------------------------------------------------------------------
623
+
624
+ # füllt die Barcode-Typ-Auswahlliste mit den möglichen Barcodes
625
+ def fill_barcode_typ_list
626
+ @lf.listbox_barcode_typ.clearItems
627
+ @barcodes.each do |bc|
628
+ @lf.listbox_barcode_typ.appendItem(bc.to_s)
629
+ end
630
+ end
631
+ #---------------------------------------------------------------------------------------------------------
632
+
633
+ # füllt die Barcode-spezifischen Felder mit den gewählten Optionen aus dem Layout
634
+ def fill_barcode_fields(obj)
635
+ # den gewählten Parameter in den entsprechenden Listen markieren
636
+ bc_typ = obj[GOA_BARCODE_TYP]
637
+ bc_id = @barcodes.index(bc_typ.to_sym)
638
+ FXFehlerAuswahlDialog.new(@parent.app, I18n.t(:barcode_is_not_avaliable, default: "Der Barcode-Typ %{bc_typ} existiert nicht in der Liste der verfügbaren Barcodes. Der Wert wird auf 'NONE' gesetzt.", bc_typ: ), [I18n.t(:ok_button, default: "&OK")]) unless bc_id
639
+ @lf.listbox_barcode_typ.currentItem = bc_id if bc_id
640
+ end
641
+
642
+ # füllt die Font-Auswahlliste mit den möglichen Fonts
643
+ def fill_font_list
644
+ # Font-Name
645
+ rmfl = SvgDrawer.builtin_font_names.keys
646
+ rmfl.sort!
647
+ @lf.listbox_fonts.clearItems
648
+ @lf.listbox_fonts.appendItem(I18n.t(:font_selection_please_select_entry, default: "Bitte auswählen"))
649
+ idx = @lf.listbox_fonts.appendItem(I18n.t(:font_selection_from_file, default: "aus Font-Datei")) # humanreadable
650
+ @lf.listbox_fonts.setItemData(idx, "from_file") # font name or file
651
+
652
+ rmfl.each do |rmf|
653
+ idx = @lf.listbox_fonts.appendItem(rmf) # humanreadable
654
+ @lf.listbox_fonts.setItemData(idx, rmf) # font name or file
655
+ end
656
+ end
657
+
658
+ # füllt die Font-spezifischen Felder mit den gewählten Optionen aus dem Layout
659
+ def fill_font_fields(obj)
660
+ # die Schriftgröße zurücklesen
661
+ @lf.textfield_fontsize.text = obj[GOA_FONT_HEIGHT]
662
+
663
+ font_typ = obj[GOA_FONT_TYP]
664
+ # den gewählten Parameter in den entsprechenden Listen markieren
665
+ set_listbox_value(:listbox_fonts, font_typ)
666
+ @lf.textfield_font_file.enabled = font_typ == "from_file"
667
+ @lf.textfield_font_file.text = obj[GOA_FONT_FILE]
668
+ end
669
+
670
+ # selectiert in der über listbox_name angegebenen Listbox den Eintrag, der Value entspricht
671
+ # wird beim Laden benötigt, um aus den Layoutdaten die Einstellungen zu restaurieren
672
+ def set_listbox_value(listbox_name, value)
673
+ ft_idx = nil
674
+ idx = 0
675
+ @lf.send(listbox_name).each do |t, i, d|
676
+ if d == value
677
+ ft_idx = idx
678
+ break
679
+ end
680
+ idx += 1
681
+ end
682
+ if ft_idx
683
+ @lf.send(listbox_name).currentItem = ft_idx
684
+ end
685
+ end
686
+
687
+ # aktiviert ein einzeiliges Textfeld für die Eingabe der Daten (wird für Barcode und Bilder gebraucht)
688
+ def data_shown
689
+ @lf.textfield_data.shown = false
690
+ @lf.label_textblock.shown = false
691
+ @lf.textfield_data_non_text.shown = true
692
+ @lf.label_textfield.shown = true
693
+ @lf.menubutton_enhanced_data_edit.shown = true
694
+ @lf.menubutton_enhanced_data_text_edit.shown = false
695
+ end
696
+
697
+ # deaktiviert die Textfelder für Dateneingabe
698
+ def no_data_shown
699
+ @lf.textfield_data.shown = false
700
+ @lf.label_textblock.shown = false
701
+ @lf.textfield_data_non_text.shown = false
702
+ @lf.label_textfield.shown = false
703
+ @lf.menubutton_enhanced_data_edit.shown = false
704
+ @lf.menubutton_enhanced_data_text_edit.shown = false
705
+ end
706
+
707
+ # aktiviert ein mehrzeiliges Textfeld für die Eingabe der Daten (wird für Text gebraucht)
708
+ def data_block_shown
709
+ @lf.textfield_data.shown = true
710
+ @lf.label_textblock.shown = true
711
+ @lf.textfield_data_non_text.shown = false
712
+ @lf.label_textfield.shown = false
713
+ @lf.menubutton_enhanced_data_edit.shown = false
714
+ @lf.menubutton_enhanced_data_text_edit.shown = true
715
+ end
716
+
717
+ def clipboard_action(action)
718
+ if [:cut, :copy].include?(action)
719
+ if @parent.acquireClipboard([@drag_type])
720
+ @clipboard_xml_frag, changed = @layout_file.send("clipboard_#{action}", @selected_object_ids - [JobSetupObjID])
721
+ @selected_object_ids = [] if action == :cut
722
+ end
723
+
724
+ elsif [:paste].include?(action)
725
+ data = @parent.getDNDData(FROM_CLIPBOARD, @drag_type)
726
+ after_id = @selected_object_ids.last
727
+ new_ids = @layout_file.clipboard_paste(data, after_id: after_id)
728
+ end
729
+ if changed || new_ids&.any?
730
+ changed_attributes
731
+ fill_objectlist
732
+
733
+ self.selected_object_ids = new_ids if new_ids
734
+ end
735
+ end
736
+
737
+ # fügt ein GraphicObjekt zur Objektliste hinzu und zeichnet die Vorschau und die Objektliste neu
738
+ # ==== Parameter
739
+ # +typ+:: der Typ des Objekts (Bild, Text, Barcode)
740
+ def manage_objects(action, typ = nil)
741
+ if action == ADD
742
+ @layout_file.add_object(typ)
743
+ changed_attributes
744
+ num_objs = 1
745
+ elsif action == DELETE
746
+ names = @selected_object_ids.map do |id|
747
+ obj = @layout_file.find_graphic_object_by_id(id)
748
+ "'#{obj[GOA_NAME]}'"
749
+ end
750
+ nn = names.join(", ")
751
+ s = I18n.t(:delete_object_confirmation, default: "Wollen Sie wirklich %{count} %{nameslist} löschen?\nDieser Vorgang lässt sich nicht rückgängig machen!", count: names.size, nameslist: nn)
752
+ error_WahlMessage = FXFehlerAuswahlDialog.new(@parent.app, s, [I18n.t(:delete_button, default: "&Löschen"), I18n.t(:cancel_button, default: "&Abbrechen")])
753
+ error_WahlMessage.execute
754
+ if error_WahlMessage.selection == 0
755
+ @layout_file.delete_objects(@selected_object_ids)
756
+ changed_attributes
757
+ end
758
+ elsif action == COPY
759
+ @layout_file.copy_objects(@selected_object_ids)
760
+ changed_attributes
761
+ num_objs = @selected_object_ids.size
762
+ end
763
+
764
+ @selected_object_ids = []
765
+ fill_objectlist
766
+
767
+ if action == ADD || action == COPY
768
+ # neu hinzugefügtes Objekt aktiv schalten
769
+ notify = true
770
+ @lf.iconlist_objects.setCurrentItem(@lf.iconlist_objects.numItems - 1, notify)
771
+ (@lf.iconlist_objects.numItems - num_objs..@lf.iconlist_objects.numItems - 1).each do |pos|
772
+ @lf.iconlist_objects.selectItem(pos, notify)
773
+ end
774
+ end
775
+
776
+ draw_preview(true)
777
+ end
778
+
779
+ # füllt die Objektliste des Layout-Dialogs mit den Name der graphischen Objekte
780
+ def fill_objectlist
781
+ # Objekt-Liste leeren
782
+ @lf.iconlist_objects.clearItems
783
+ @lf.iconlist_objects.appendItem(["", I18n.t(:objectlist_job_settings, default: "Job-Einstellungen")].join("\t"), nil, nil, JobSetupObjID)
784
+
785
+ if @layout_file
786
+ # Array mit sortierten Objekt-ID's holen
787
+ @layout_file.sorted_id_list.each do |id|
788
+ go = @layout_file.find_graphic_object_by_id(id)
789
+ @lf.iconlist_objects.appendItem([go[GOA_NAME], go[GOA_TYP]].join("\t"), nil, nil, id)
790
+ end
791
+ end
792
+ end
793
+
794
+ # diese Methode liest die allgemeinen Einstellungen des Layouts aus dem XML aus und befüllt damit die Bearbeitungsfelder im Tab 'Allgemein'
795
+ def fill_layout_attr_tab
796
+ @lf.textfield_x_offset.text = @layout_file.get_attr_value(S_X_OFFSET)
797
+ @lf.textfield_y_offset.text = @layout_file.get_attr_value(S_Y_OFFSET)
798
+ @lf.textfield_page_width.text = @layout_file.get_attr_value(S_WIDTH)
799
+ @lf.textfield_page_height.text = @layout_file.get_attr_value(S_HEIGHT)
800
+ Layout.set_combobox_by_data(@lf.combobox_datasource_typ, @layout_file.get_attr_value(S_DATASOURCETYP))
801
+ Layout.set_combobox_by_data(@lf.combobox_datasource_encoding, @layout_file.get_attr_value(S_DATASOURCEENCODING))
802
+ set_check_button("checkbutton_contactless", @layout_file.get_attr_value(S_CONTACTLESS), true)
803
+ set_check_button("checkbutton_contact", @layout_file.get_attr_value(S_CONTACT), true)
804
+ set_check_button("checkbutton_magstripe", @layout_file.get_attr_value(S_MAGSTRIPE), true)
805
+ set_check_button("checkbutton_duplex", @layout_file.get_attr_value(S_DUPLEX), true)
806
+ set_check_button("checkbutton_flip_front", @layout_file.get_attr_value(S_FRONT_FLIP), true)
807
+ set_check_button("checkbutton_flop_front", @layout_file.get_attr_value(S_FRONT_FLOP), true)
808
+ set_check_button("checkbutton_flip_back", @layout_file.get_attr_value(S_BACK_FLIP), true)
809
+ set_check_button("checkbutton_flop_back", @layout_file.get_attr_value(S_BACK_FLOP), true)
810
+ end
811
+
812
+ def set_check_button(objectname, state, enabled)
813
+ @lf.send(objectname).state = state == S_TRUE
814
+ @lf.send(objectname).enabled = enabled
815
+ end
816
+
817
+ def move_selected(x, y, modifier=0)
818
+ step = if modifier & Fox::SHIFTMASK != 0
819
+ 0.1
820
+ elsif modifier & Fox::CONTROLMASK != 0
821
+ 10
822
+ else
823
+ 1
824
+ end
825
+ @selected_object_ids.each do |id|
826
+ next if id < 0
827
+ go = @layout_file.find_graphic_object_by_id(id)
828
+ go[GOA_X] = go[GOA_X].to_f + x * step
829
+ go[GOA_Y] = go[GOA_Y].to_f + y * step
830
+ end
831
+
832
+ changed_attributes if x != 0 || y != 0
833
+ @layout.set_focus(:preview)
834
+ end
835
+
836
+ def draw_preview(immediately = false)
837
+ @layout.draw_preview(immediately)
838
+ end
839
+
840
+ def changed_attributes
841
+ @layout.changed_attributes
842
+ draw_preview
843
+ end
844
+ end
845
+ end