manqod 1.1505.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (142) hide show
  1. data/bin/manqod +309 -0
  2. data/doc/HOWTOS +11 -0
  3. data/doc/INSTALL +6 -0
  4. data/doc/LICENCE +450 -0
  5. data/doc/README +33 -0
  6. data/doc/benchmarkings/ListLoader.rb +177 -0
  7. data/doc/manqod.png +0 -0
  8. data/doc/manqod.svg +99 -0
  9. data/doc/server.conf.example +24 -0
  10. data/lib/About.rb +93 -0
  11. data/lib/BarMenu/BarMenuItem.rb +46 -0
  12. data/lib/BarMenu.rb +76 -0
  13. data/lib/ButtonMenu/ButtonMenuItem.rb +82 -0
  14. data/lib/ButtonMenu/EndSeparator.rb +14 -0
  15. data/lib/ButtonMenu/StartSeparator.rb +14 -0
  16. data/lib/ButtonMenu.rb +154 -0
  17. data/lib/Common/Conf.rb +119 -0
  18. data/lib/Common/Eprint.rb +180 -0
  19. data/lib/Common/EventCache.rb +41 -0
  20. data/lib/Common/Fixnum.rb +18 -0
  21. data/lib/Common/Images.rb +41 -0
  22. data/lib/Common/ManqodDB.rb +40 -0
  23. data/lib/Common/MyExec.rb +77 -0
  24. data/lib/Common/MyImage.rb +47 -0
  25. data/lib/Common/Nick.rb +25 -0
  26. data/lib/Common/String.rb +15 -0
  27. data/lib/FormHolder/Form/InputHolder/Button.rb +133 -0
  28. data/lib/FormHolder/Form/InputHolder/Calendar.rb +101 -0
  29. data/lib/FormHolder/Form/InputHolder/CalendarButton.rb +117 -0
  30. data/lib/FormHolder/Form/InputHolder/ColorButton.rb +54 -0
  31. data/lib/FormHolder/Form/InputHolder/Combo.rb +82 -0
  32. data/lib/FormHolder/Form/InputHolder/ComboWithNew.rb +103 -0
  33. data/lib/FormHolder/Form/InputHolder/Common/Model.rb +337 -0
  34. data/lib/FormHolder/Form/InputHolder/ConstCombo.rb +18 -0
  35. data/lib/FormHolder/Form/InputHolder/ConstText.rb +17 -0
  36. data/lib/FormHolder/Form/InputHolder/Duration.rb +73 -0
  37. data/lib/FormHolder/Form/InputHolder/EditableList.rb +57 -0
  38. data/lib/FormHolder/Form/InputHolder/FieldCombo.rb +40 -0
  39. data/lib/FormHolder/Form/InputHolder/FieldList.rb +40 -0
  40. data/lib/FormHolder/Form/InputHolder/FileChooser.rb +131 -0
  41. data/lib/FormHolder/Form/InputHolder/FontButton.rb +37 -0
  42. data/lib/FormHolder/Form/InputHolder/FormImage.rb +74 -0
  43. data/lib/FormHolder/Form/InputHolder/HScale.rb +44 -0
  44. data/lib/FormHolder/Form/InputHolder/Hidden.rb +41 -0
  45. data/lib/FormHolder/Form/InputHolder/Label.rb +40 -0
  46. data/lib/FormHolder/Form/InputHolder/List.rb +176 -0
  47. data/lib/FormHolder/Form/InputHolder/MultiLine.rb +63 -0
  48. data/lib/FormHolder/Form/InputHolder/Password.rb +41 -0
  49. data/lib/FormHolder/Form/InputHolder/QBuilder/QObject.rb +269 -0
  50. data/lib/FormHolder/Form/InputHolder/QBuilder.rb +333 -0
  51. data/lib/FormHolder/Form/InputHolder/RadioGroup.rb +82 -0
  52. data/lib/FormHolder/Form/InputHolder/SourceView.rb +100 -0
  53. data/lib/FormHolder/Form/InputHolder/Spin.rb +49 -0
  54. data/lib/FormHolder/Form/InputHolder/Text.rb +55 -0
  55. data/lib/FormHolder/Form/InputHolder/TimeStamp.rb +82 -0
  56. data/lib/FormHolder/Form/InputHolder/TimeStampButton.rb +93 -0
  57. data/lib/FormHolder/Form/InputHolder/Toggle.rb +43 -0
  58. data/lib/FormHolder/Form/InputHolder.rb +458 -0
  59. data/lib/FormHolder/Form.rb +529 -0
  60. data/lib/FormHolder.rb +203 -0
  61. data/lib/Gtk.rb +101 -0
  62. data/lib/GtkAttributes.rb +76 -0
  63. data/lib/Kernel.rb +48 -0
  64. data/lib/ListHolder/EditableList/CellRenderers/Combo.rb +91 -0
  65. data/lib/ListHolder/EditableList/CellRenderers/ComboText.rb +22 -0
  66. data/lib/ListHolder/EditableList/CellRenderers/ConstCombo.rb +12 -0
  67. data/lib/ListHolder/EditableList/CellRenderers/ConstText.rb +23 -0
  68. data/lib/ListHolder/EditableList/CellRenderers/Pixbuf.rb +18 -0
  69. data/lib/ListHolder/EditableList/CellRenderers/Progress.rb +36 -0
  70. data/lib/ListHolder/EditableList/CellRenderers/Text.rb +51 -0
  71. data/lib/ListHolder/EditableList/CellRenderers/Toggle.rb +35 -0
  72. data/lib/ListHolder/EditableList/Column.rb +223 -0
  73. data/lib/ListHolder/EditableList/DrbListModel.rb +809 -0
  74. data/lib/ListHolder/EditableList/ListPrintOperation/ColumnsHeaderLayout.rb +56 -0
  75. data/lib/ListHolder/EditableList/ListPrintOperation/CustomPageSetup.rb +100 -0
  76. data/lib/ListHolder/EditableList/ListPrintOperation/FooterLayout.rb +26 -0
  77. data/lib/ListHolder/EditableList/ListPrintOperation/HeaderLayout.rb +35 -0
  78. data/lib/ListHolder/EditableList/ListPrintOperation/IterLayout.rb +89 -0
  79. data/lib/ListHolder/EditableList/ListPrintOperation.rb +365 -0
  80. data/lib/ListHolder/EditableList.rb +309 -0
  81. data/lib/ListHolder/GanttHolder/Gantt/Rectangle.rb +290 -0
  82. data/lib/ListHolder/GanttHolder/Gantt.rb +317 -0
  83. data/lib/ListHolder/GanttHolder/GanttFooter.rb +27 -0
  84. data/lib/ListHolder/GanttHolder/GanttScaler.rb +60 -0
  85. data/lib/ListHolder/GanttHolder.rb +31 -0
  86. data/lib/ListHolder/HistoryWindow.rb +63 -0
  87. data/lib/ListHolder/ListButtonHolder/ArchiveButton.rb +37 -0
  88. data/lib/ListHolder/ListButtonHolder/ButtonGroup.rb +32 -0
  89. data/lib/ListHolder/ListButtonHolder/FilterButton.rb +28 -0
  90. data/lib/ListHolder/ListButtonHolder/ListButton.rb +305 -0
  91. data/lib/ListHolder/ListButtonHolder/OrderingButton.rb +26 -0
  92. data/lib/ListHolder/ListButtonHolder/SumPanelButton.rb +23 -0
  93. data/lib/ListHolder/ListButtonHolder.rb +94 -0
  94. data/lib/ListHolder/ListPanel/ListFilter/FRenderer/Combo.rb +94 -0
  95. data/lib/ListHolder/ListPanel/ListFilter/FRenderer/ConstCombo.rb +11 -0
  96. data/lib/ListHolder/ListPanel/ListFilter/FRenderer/Text.rb +26 -0
  97. data/lib/ListHolder/ListPanel/ListFilter/FRenderer/Toggle.rb +41 -0
  98. data/lib/ListHolder/ListPanel/ListFilter/FRenderer.rb +58 -0
  99. data/lib/ListHolder/ListPanel/ListFilter.rb +42 -0
  100. data/lib/ListHolder/ListPanel/ListSum/Text.rb +32 -0
  101. data/lib/ListHolder/ListPanel/ListSum.rb +72 -0
  102. data/lib/ListHolder/ListPanel.rb +60 -0
  103. data/lib/ListHolder.rb +241 -0
  104. data/lib/LoginWindow.rb +77 -0
  105. data/lib/MainRouter.rb +64 -0
  106. data/lib/ManqodCommon.rb +295 -0
  107. data/lib/ManqodHelp/FormatEditor/FormatJustificationWidget.rb +76 -0
  108. data/lib/ManqodHelp/FormatsEditor.rb +139 -0
  109. data/lib/ManqodHelp/HelpBrowser/FormatTagTable/FormatTag.rb +84 -0
  110. data/lib/ManqodHelp/HelpBrowser/FormatTagTable.rb +39 -0
  111. data/lib/ManqodHelp/HelpBrowser.rb +135 -0
  112. data/lib/ManqodHelp/HelpIndex.rb +62 -0
  113. data/lib/ManqodHelp/HelpToolbar.rb +16 -0
  114. data/lib/ManqodHelp.rb +120 -0
  115. data/lib/ManqodRPC.rb +37 -0
  116. data/lib/Memcache.rb +82 -0
  117. data/lib/MyConfig.rb +93 -0
  118. data/lib/Print/PrintItem/TextLayout.rb +47 -0
  119. data/lib/Print/PrintItem.rb +240 -0
  120. data/lib/Print.rb +199 -0
  121. data/lib/PrintEditor/ItemInfo/ItemImage.rb +30 -0
  122. data/lib/PrintEditor/ItemInfo/ItemList.rb +44 -0
  123. data/lib/PrintEditor/ItemInfo/ItemTextAlignment.rb +27 -0
  124. data/lib/PrintEditor/ItemInfo.rb +129 -0
  125. data/lib/PrintEditor/PageLayout.rb +91 -0
  126. data/lib/PrintEditor/PrintEditorItem.rb +310 -0
  127. data/lib/PrintEditor.rb +195 -0
  128. data/lib/RelationBuilder/RTable/RField.rb +91 -0
  129. data/lib/RelationBuilder/RTable.rb +293 -0
  130. data/lib/RelationBuilder/Relation/RelationHandle.rb +70 -0
  131. data/lib/RelationBuilder/Relation.rb +161 -0
  132. data/lib/RelationBuilder/RunQuery.rb +55 -0
  133. data/lib/RelationBuilder/SearchWindow.rb +72 -0
  134. data/lib/RelationBuilder.rb +468 -0
  135. data/lib/SB/ListProgress.rb +150 -0
  136. data/lib/SB/Messaging.rb +77 -0
  137. data/lib/SB.rb +29 -0
  138. data/lib/mynotebook.rb +131 -0
  139. data/lib/mytouchwindow.rb +162 -0
  140. data/lib/mywindow.rb +134 -0
  141. data/lib/wysiwyg-print-label.rb +57 -0
  142. metadata +231 -0
@@ -0,0 +1,269 @@
1
+ #this file is part of manqod
2
+ #manqod is distributed under the CDDL licence
3
+ #the author of manqod is Dobai-Pataky Balint(dpblnt@gmail.com)
4
+
5
+ class QObject < Gtk::HBox
6
+ include ManqodCommon
7
+ =begin
8
+ q - the QueryBuilder
9
+ link_or_fields - link: an object from the RelationBuilder
10
+ - fields: the fields from the table `qobjects`
11
+ =end
12
+ def initialize(q,link_or_fields=nil)
13
+ whsv=false
14
+ begin
15
+ whsv=Gtk::SourceView::BUILD_VERSION
16
+ rescue => err
17
+ einfo("no Gtk::SourceView, falling back")
18
+ end
19
+ super() #("initializing")
20
+ pack_start(Gtk::ScrolledWindow.new.set_policy(Gtk::PolicyType::AUTOMATIC,Gtk::PolicyType::NEVER).set_shadow_type(Gtk::ShadowType::NONE).add(@widget=whsv ? Gtk::SourceView.new : Gtk::TextView.new))
21
+ @rel_reverted=false
22
+ @q=q
23
+ @custom="false"
24
+ case link_or_fields.class.name
25
+ when "Hash" then
26
+ #load
27
+ @my_id=link_or_fields["id"]
28
+ @obj_type=link_or_fields["obj_type"]
29
+ @obj_id=link_or_fields["obj_id"]
30
+ @field=link_or_fields["field"]
31
+ @custom=link_or_fields["custom"]
32
+ @rel_reverted=!@field.nil? && @field.include?("reverted")
33
+ set_link_from_data
34
+ when "RField" then
35
+ @link=link_or_fields
36
+ @my_id=nil
37
+ @obj_type="f"
38
+ @field=link.field_name
39
+ @obj_id=link.table.table_id
40
+ store
41
+ when "RTable" then
42
+ @link=link_or_fields
43
+ @my_id=nil
44
+ @obj_type="b"
45
+ @obj_id=link.table_id
46
+ store
47
+ when "Relation" then
48
+ @link=link_or_fields
49
+ @my_id=nil
50
+ @obj_type="r"
51
+ @obj_id=link.relation_id.to_i
52
+ store
53
+ else edebug("unknown link: #{@link}(#{link_or_fields.class.name})","relation-builder",WARNING)
54
+ end
55
+
56
+ if whsv
57
+ @widget.buffer.set_language(Gtk::SourceLanguageManager.new.get_language("sql"))
58
+ @widget.set_auto_indent(true).
59
+ set_highlight_current_line(true).
60
+ set_indent_on_tab(true).
61
+ set_indent_on_tab(true).
62
+ set_indent_width(4)
63
+ end
64
+ @widget.set_editable(is_custom?)
65
+ @widget.modify_base(Gtk::StateType::NORMAL,Gdk::Color.parse("yellow")) if is_custom?
66
+ @widget.signal_connect("focus-out-event"){|me,ev|
67
+ @field=text
68
+ store
69
+ @q.update(@q)
70
+ false
71
+ }
72
+ @q.qobjects.push(self)
73
+ case @obj_type
74
+ when "b" then @q.from.pack_start(self,false,false)
75
+ when "f" then
76
+ @q.select.pack_start(self,false,false)
77
+ pack_start(rmbutton=Gtk::Button.new.set_image(Gtk::Image.new(Gtk::Stock::CANCEL,Gtk::IconSize::MENU)).set_relief(Gtk::ReliefStyle::NONE),false)
78
+ rmbutton.signal_connect("clicked"){|me| self.delete}
79
+ when "r" then
80
+ @q.from.pack_start(self,false,false)
81
+ pack_start(rotbutton=Gtk::ToggleButton.new.set_image(Gtk::Image.new(Gtk::Stock::REFRESH,Gtk::IconSize::MENU)).set_relief(Gtk::ReliefStyle::NONE),false)
82
+ pack_start(rmbutton=Gtk::Button.new,false)
83
+ rmbutton.set_image(Gtk::Image.new(Gtk::Stock::CANCEL,Gtk::IconSize::MENU)).set_relief(Gtk::ReliefStyle::NONE).signal_connect("clicked"){|me| self.delete}
84
+ rotbutton.set_active(@rel_reverted)
85
+ rotbutton.signal_connect("toggled"){|me|
86
+ @rel_reverted=me.active?
87
+ store
88
+ @q.update(@q)
89
+ }
90
+ end
91
+ show_all
92
+ case @link.class.name
93
+ when "RField","Relation" then @link.set_active(true)
94
+ end
95
+ end
96
+ attr_reader :link, :obj_type, :obj_id
97
+
98
+ def is_custom?
99
+ return false if @custom.nil?
100
+ @custom == "true"
101
+ end
102
+
103
+ def find_base_dir(rel,been_there=nil)
104
+ if been_there.nil?
105
+ been_there=Array.new
106
+ end
107
+ been_there.push(rel.relation_id)
108
+ ret=nil
109
+ ret=rel.rfield1 if rel.rfield1.table.table_id.to_i == @q.base_object.obj_id.to_i
110
+ ret=rel.rfield2 if rel.rfield2.table.table_id.to_i == @q.base_object.obj_id.to_i
111
+ unless ret
112
+ @q.rb.relations.each{|r|
113
+ unless been_there.include?(r.relation_id)
114
+ if r.rfield1.table.table_id == rel.rfield1.table.table_id or r.rfield2.table.table_id == rel.rfield1.table.table_id
115
+ if other_dir=find_base_dir(r,been_there)
116
+ ret=rel.rfield1
117
+ end
118
+ end
119
+ if r.rfield1.table.table_id == rel.rfield2.table.table_id or r.rfield2.table.table_id == rel.rfield2.table.table_id
120
+ if other_dir=find_base_dir(r,been_there)
121
+ ret=rel.rfield2
122
+ end
123
+ end
124
+ break if ret
125
+ end
126
+ }
127
+ end
128
+ ret
129
+ end
130
+
131
+ def gen_text
132
+ ret=""
133
+ if is_custom?
134
+ ret=@field || ""
135
+ else
136
+ begin
137
+ case @obj_type
138
+ when "f" then ret="`#{@link.table.table}`.`#{@link.field_name}`#{"," unless last_field?}"
139
+ when "r" then
140
+ dir=find_base_dir(@link)
141
+ dir=@link.other_field(dir) if @rel_reverted #reverted path
142
+ edebug("field to base: #{dir}","relation-builder",INFO)
143
+ if dir
144
+ other_field=@link.other_field(dir)
145
+ edebug("field to base other_field: #{other_field}","relation-builder",INFO)
146
+ if @link.rel_name == ""
147
+ ret="left join `#{other_field.table.table}` on `#{other_field.table.table}`.`#{other_field.field_name}` = `#{dir.table.table}`.`#{dir.field_name}`"
148
+ else
149
+ ret="left join `#{other_field.table.table}` as #{@link.rel_name} on `#{@link.rel_name}`.`#{other_field.field_name}` = `#{dir.table.table}`.`#{dir.field_name}`"
150
+ end
151
+ unless @link.rel_custom == ""
152
+ ret="#{ret} and #{@link.rel_custom}"
153
+ end
154
+ else
155
+ ret="can't reach base"
156
+ end
157
+ when "b" then
158
+ ret="`#{@link.table}`"
159
+ else ret="unknown object type"
160
+ end
161
+ rescue =>err
162
+ edebug("#{err}, #{backtrace_to_debug(err)}\n","relation-builder","warning")
163
+ ret="unavailable object"
164
+ end
165
+ end
166
+ ret
167
+ end
168
+
169
+ def set_link_from_data
170
+ #if any data changed this should be called. it'll try to link to another object
171
+ unless is_custom?
172
+ @link=case @obj_type
173
+ when "b" then @q.rb.table_by_id(@obj_id)
174
+ when "f" then if table=@q.rb.table_by_id(@obj_id) then table.fields[@field]; end
175
+ when "r" then @q.rb.relation_by_id(@obj_id)
176
+ else
177
+ edebug("unknown type: #{@obj_type}","relation-builder",WARNING)
178
+ nil
179
+ end
180
+ end
181
+ update
182
+ end
183
+
184
+ def update
185
+ @widget.buffer.set_text(gen_text)
186
+ end
187
+ def set_link(new_link)
188
+ @link=new_link
189
+ self
190
+ end
191
+ def set_obj_id(new_obj_id)
192
+ @obj_id=new_obj_id
193
+ set_link_from_data
194
+ store
195
+ end
196
+
197
+ def store
198
+ edebug("storing(#{@my_id})","relation-builder")
199
+ if is_custom?
200
+ isql="`obj_id`='#{@obj_id}', `obj_type`='#{@obj_type}', `field`='#{escape_string(@field)}', `custom`='#{@custom}', `query_id`='#{@q.query_id}'"
201
+ else
202
+ isql=nil
203
+ case @link.class.name
204
+ when "RField" then isql="`obj_id`='#{@obj_id}', `field`='#{@link.field_name}', `obj_type`='#{@obj_type}', `query_id`='#{@q.query_id}'"
205
+ when "RTable" then isql="`obj_id`='#{@obj_id}', `obj_type`='#{@obj_type}', `query_id`='#{@q.query_id}'"
206
+ when "Relation" then isql="`obj_id`='#{@obj_id}', `obj_type`='#{@obj_type}', `query_id`='#{@q.query_id}', `field`='#{"reverted" if @rel_reverted}'"
207
+ else edebug("don't store: #{link.class.name}","relation-builder",INFO)
208
+ end
209
+ end
210
+ if isql
211
+ if @my_id
212
+ sql="update `qobjects` set #{isql} where `id`='#{@my_id}'"
213
+ else
214
+ sql="insert into `qobjects` set #{isql}"
215
+ end
216
+ query(sql)
217
+ @my_id=qrow("select id from `qobjects` order by id desc limit 1")["id"] unless @my_id
218
+ end
219
+ end
220
+
221
+ def delete
222
+ query("delete from `qobjects` where id='#{@my_id}'") if @my_id
223
+ @q.qobjects.delete(self)
224
+ self.destroy
225
+ if is_custom?
226
+ #so all qobjects get updated
227
+ @q.update(@q)
228
+ else
229
+ #update the link, that will also update all qobjects
230
+ case @link.class.name
231
+ when "RField" then @link.set_active(false)
232
+ when "Relation" then @link.set_active(false)
233
+ end
234
+ end
235
+ end
236
+
237
+ def last_field?
238
+ last_field=nil
239
+ @q.qobjects.reverse_each{|qobject|
240
+ if qobject.obj_type == "f"
241
+ last_field = qobject
242
+ break
243
+ end
244
+ }
245
+ last_field == self
246
+ end
247
+
248
+ def set_text(new_text)
249
+ @widget.buffer.set_text(new_text)
250
+ end
251
+
252
+ def text
253
+ @widget.buffer.text
254
+ end
255
+
256
+ def inspect
257
+ "QObject of #{@link}(#{@obj_type} id:#{@my_id})"
258
+ end
259
+
260
+ def to_s
261
+ inspect
262
+ end
263
+
264
+ def center_on_link
265
+ link.center_on_me unless link.nil?
266
+ end
267
+
268
+ end
269
+
@@ -0,0 +1,333 @@
1
+ #this file is part of manqod
2
+ #manqod is distributed under the CDDL licence
3
+ #the author of manqod is Dobai-Pataky Balint(dpblnt@gmail.com)
4
+
5
+ class QBuilder < Gtk::HPaned
6
+ include ManqodCommon
7
+ include Conf
8
+
9
+ def initialize(pc)
10
+ @pc=pc
11
+ @qobjects=Array.new
12
+ super()
13
+
14
+ whsv=false
15
+ begin
16
+ whsv=Gtk::SourceView::BUILD_VERSION
17
+ rescue => err
18
+ einfo("no Gtk::SourceView, falling back")
19
+ end
20
+
21
+ add1(Gtk::VBox.new(false,1).
22
+ pack_start(@info=Gtk::Table.new(2,3),false).
23
+ pack_start(Gtk::ScrolledWindow.new.set_policy(Gtk::PolicyType::AUTOMATIC,Gtk::PolicyType::AUTOMATIC).add_with_viewport(@holder=Gtk::VBox.new(false,0))).
24
+ pack_start(@controls=Gtk::VBox.new,false,true))
25
+ add2(@rb=RelationBuilder.new(true))
26
+
27
+ @info.attach_defaults(Gtk::Label.new("name"),0,1,0,1).attach_defaults(@name=Gtk::Entry.new,1,2,0,1).
28
+ attach_defaults(Gtk::Label.new("base"),0,1,1,2).attach_defaults(Gtk::HBox.new.pack_start(@base=Gtk::ComboBox.new(Gtk::ListStore.new(Integer,String))).pack_end(@goto_button=Gtk::Button.new.set_image(Gtk::Image.new(Gtk::Stock::JUMP_TO,Gtk::IconSize.from_name(get_conf(0,0,"button-size")))),false,false),1,2,1,2).
29
+ attach_defaults(Gtk::Label.new("comment"),0,1,2,3).attach_defaults(@comment=Gtk::Entry.new,1,2,2,3)
30
+ update_base_selector
31
+ @goto_button.signal_connect('clicked'){|me|
32
+ base_object.center_on_link
33
+ }
34
+ @base.pack_start(renderer=Gtk::CellRendererText.new,false).add_attribute(renderer,:text,1).signal_connect("changed"){|me|
35
+ save_query
36
+ if bo=base_object
37
+ bo.set_obj_id(me.active_iter[0]) unless me.active_iter.nil?
38
+ else
39
+ bo=QObject.new(self,rb.table_by_id(me.active_iter[0]))
40
+ end
41
+ update(self)
42
+ # base_object.center_on_link
43
+ @rb.set_base_object(bo.link)
44
+ false
45
+ }
46
+ @name.signal_connect("activate"){|me|save_query;false}
47
+ @comment.signal_connect("activate"){|me|save_query;false}
48
+
49
+ @where=whsv ? Gtk::SourceView.new : Gtk::TextView.new
50
+ @group_by=whsv ? Gtk::SourceView.new : Gtk::TextView.new
51
+
52
+ @holder.pack_start(
53
+ Gtk::Frame.new.
54
+ set_label_widget(Gtk::HBox.new(false,10).pack_start(Gtk::Label.new("SELECT")).pack_end(select_button=Gtk::Button.new)).
55
+ set_shadow_type(Gtk::ShadowType::IN).
56
+ add(@select=Gtk::VBox.new),false,true).
57
+ pack_start(Gtk::Frame.new.
58
+ set_label_widget(Gtk::HBox.new(false,10).pack_start(Gtk::Label.new("FROM")).pack_end(from_button=Gtk::Button.new)).
59
+ set_shadow_type(Gtk::ShadowType::IN).
60
+ add(@from=Gtk::VBox.new),false,true).
61
+ pack_start(Gtk::Frame.new("WHERE").set_shadow_type(Gtk::ShadowType::IN).add(@where),false,true).
62
+ pack_start(Gtk::Frame.new("GROUP BY").set_shadow_type(Gtk::ShadowType::IN).add(@group_by),false,true).
63
+ pack_start(Gtk::Label.new,true,true)
64
+
65
+ @controls.pack_start(Gtk::HBox.new(false).
66
+ pack_start(@autotest=Gtk::ToggleButton.new("auto")).
67
+ pack_start(@test_now=Gtk::Button.new("test")).
68
+ pack_start(@view_sql=Gtk::Button.new("show")).
69
+ pack_start(@save_as_view=Gtk::Button.new("store")),false,true).
70
+ pack_start(Gtk::ScrolledWindow.new.set_policy(Gtk::PolicyType::AUTOMATIC,Gtk::PolicyType::AUTOMATIC).add_with_viewport(@result=Gtk::Button.new),false)
71
+ @where.buffer.set_language(Gtk::SourceLanguageManager.new.get_language("sql")) if whsv
72
+ @where.signal_connect("focus-out-event"){|me,ev|
73
+ if @autotest.active?
74
+ save_query
75
+ test_query
76
+ end
77
+ false
78
+ }
79
+ @group_by.buffer.set_language(Gtk::SourceLanguageManager.new.get_language("sql")) if whsv
80
+ @group_by.signal_connect("focus-out-event"){|me,ev|
81
+ if @autotest.active?
82
+ save_query
83
+ test_query
84
+ end
85
+ false
86
+ }
87
+ @test_now.signal_connect("pressed"){|me|
88
+ save_query
89
+ test_query
90
+ }
91
+ @view_sql.signal_connect("pressed"){|me|
92
+ save_query
93
+ w=Gtk::Dialog.new(@name.text,parentM.get_ancestor(Gtk::Window),Gtk::Dialog::DESTROY_WITH_PARENT ,[ Gtk::Stock::CLOSE, Gtk::Dialog::RESPONSE_NONE ])
94
+ w.vbox.add(Gtk::ScrolledWindow.new.add(sview=Gtk::SourceView.new.set_editable(false))).set_size_request(600,400)
95
+ sview.buffer.set_text(sql).set_language(Gtk::SourceLanguageManager.new.get_language("sql"))
96
+ sview.set_highlight_current_line(true).
97
+ set_show_line_numbers(true)
98
+ w.show_all
99
+ w.run{|response| w.destroy}
100
+ }
101
+ @result.signal_connect("pressed"){|me,ev|
102
+ begin
103
+ w=Gtk::Dialog.new(@name.text,parentM.get_ancestor(Gtk::Window),Gtk::Dialog::DESTROY_WITH_PARENT ,[ Gtk::Stock::CLOSE, Gtk::Dialog::RESPONSE_NONE ])
104
+ res=ManqodDB.instance.manqod_db.client.query(sql)
105
+ htypes=Array.new
106
+ headers=Hash.new
107
+ row=res.fetch_hash(true)
108
+ #build headertypes
109
+ i=0
110
+ row.each_key{|k|
111
+ htypes.push(String)
112
+ headers[i]=k
113
+ i+=1
114
+ }
115
+ model=Gtk::ListStore.new(*htypes)
116
+ sview=Gtk::TreeView.new(model)
117
+ #create and add columns
118
+ headers.sort.each{|k|
119
+ col=Gtk::TreeViewColumn.new(k[1],Gtk::CellRendererText.new, {:text => k[0]}).set_resizable(true).set_sort_column_id(k[0]).set_reorderable(true)
120
+ sview.append_column(col)
121
+ }
122
+ begin
123
+ i=model.append
124
+ row.each{|k,v| i[headers.index(k)]=v}
125
+ end while (row=res.fetch_hash(true))
126
+ sview.set_model(model)
127
+ w.vbox.add(Gtk::ScrolledWindow.new.add(sview).set_policy(Gtk::POLICY_AUTOMATIC,Gtk::POLICY_AUTOMATIC)).set_size_request(600,400)
128
+ w.show_all
129
+ w.run{|response| w.destroy}
130
+ rescue =>err
131
+ warn(err,backtrace_to_debug(err))
132
+ end
133
+ }
134
+ @save_as_view.signal_connect("pressed"){|me|
135
+ store_query
136
+ }
137
+
138
+
139
+ select_button.set_image(Gtk::Image.new(Gtk::Stock::ADD,Gtk::IconSize::MENU)).set_relief(Gtk::ReliefStyle::NONE)
140
+ select_button.signal_connect('clicked'){|me|
141
+ QObject.new(self,{"custom"=>"true", "obj_type"=>"f", "field"=>"*"}).store
142
+ update(self)
143
+ }
144
+
145
+ from_button.set_image(Gtk::Image.new(Gtk::Stock::ADD,Gtk::IconSize::MENU)).set_relief(Gtk::ReliefStyle::NONE)
146
+ from_button.signal_connect('clicked'){|me|
147
+ QObject.new(self,{"custom"=>"true", "field"=>"left join ", "obj_type"=>"r"})
148
+ update(self)
149
+ }
150
+ # holder.pack_end(button_holder,false,false,1)
151
+
152
+ # add(rb_holder)
153
+
154
+ # set_query_id(query_id)
155
+ @rb.add_observer(self)
156
+ signal_connect("destroy"){|me| save_query}
157
+ end
158
+ attr_reader :qobjects, :rb, :pc, :from, :where, :groupby, :select, :query_id
159
+
160
+ def update(new_value=item['default'],notifier=nil)
161
+ =begin
162
+ first argument:
163
+ - new_value - for FormItem compatibility
164
+ - notifier - we are RelationBuilder's observer
165
+ second argument
166
+ subnotifier - if notification comes from RelationBuilder, this will be
167
+ RField Button - pressed, so we create or remove qobject for it
168
+ RTable - added or removed
169
+ =end
170
+ case new_value.class.name
171
+ when "String"
172
+ item['default']=new_value
173
+ run_events(item['id'],'form_item-BeforeUpdate')
174
+ @rb.update(self)
175
+ set_query_id(item['default'].to_i)
176
+ run_events(item['id'],'form_item-AfterUpdate')
177
+ when "RelationBuilder"
178
+ if notifier.class.name == "RTable" || notifier.nil? #if nil then removed table
179
+ #update base combo
180
+ update_base_selector
181
+ else
182
+ qobject=qobject_by_link(notifier)
183
+ if notifier.active?
184
+ QObject.new(self,notifier) unless qobject
185
+ else
186
+ qobject.delete if qobject
187
+ end
188
+ end
189
+ when "QBuilder"
190
+ #we update ourself
191
+ else
192
+ edebug("notifier: #{new_value.class.name}","relation-builder",WARNING)
193
+ end
194
+ @qobjects.each{|qobject| qobject.update}
195
+ test_query if @autotest.active?
196
+ show_all
197
+ end
198
+
199
+ def save_query
200
+ if @query_id == 0 or @query_id == -1
201
+ query("insert into `queries` set `base`='#{base}', name='#{name}', comment='#{comment}', `where_clause` = '#{escape_string(where_clause)}', `group_by` = '#{escape_string(group_by_clause)}', `sql`='#{escape_string(sql)}'")
202
+ @query_id=qrow("select id from queries order by id desc limit 1")["id"]
203
+ edebug("new query created: #{name}(#{@query_id})","relation-builder","debug")
204
+ parentM.parentselected=@query_id.to_i
205
+ parentM.runmode="modify"
206
+ else
207
+ query("update `queries` set `base`='#{base}', name='#{name}', comment='#{comment}', `where_clause` = '#{escape_string(where_clause)}', `group_by` = '#{escape_string(group_by_clause)}', `sql`='#{escape_string(sql)}' where id='#{@query_id}'")
208
+ edebug("query updated: #{name}(#{@query_id})","relation-builder","debug")
209
+ end
210
+ end
211
+ def test_query
212
+ begin
213
+ res=ManqodDB.instance.manqod_db.client.query(sql)
214
+ ret="fields: #{res.num_fields}\nrows: #{res.num_rows}"
215
+ rescue =>err
216
+ ret="#{err}"
217
+ end
218
+ @result.set_label(ret)
219
+ end
220
+ def store_query
221
+ save_query
222
+ vsql="create or replace view #{@name.text} as #{sql}"
223
+ begin
224
+ res=ManqodDB.instance.manqod_db.client.query(vsql)
225
+ ret="stored"
226
+ rescue =>err
227
+ ret="#{err}"
228
+ end
229
+ @result.set_label(ret)
230
+ end
231
+
232
+ def set_query_id(query_id)
233
+ @qobjects.each{|key,qobject| qobject.destroy}
234
+ @qobjects.clear
235
+ @query_id=query_id
236
+ if @query_id and row=qrow("select * from queries where id='#{@query_id}'")
237
+ @name.set_text(row["name"])
238
+ @comment.set_text(row["comment"])
239
+ @where.buffer.set_text(row["where_clause"])
240
+ @group_by.buffer.set_text(row["group_by"])
241
+ found=nil
242
+ rows("select * from qobjects where query_id='#{query_id}' order by id"){|qo|
243
+ #@qobjects[qo["obj_id"]]=
244
+ QObject.new(self,qo)
245
+ # @holder.pack_start_defaults(@qobjects[qo["obj_id"]])
246
+ }
247
+ @base.model.each{|model,path,iter| if iter[0] == row["base"].to_i then found=iter;break;end}
248
+ if found
249
+ @base.set_active_iter(found)
250
+ end
251
+ end
252
+ @qobjects.each{|qobject| qobject.update}
253
+ end
254
+
255
+ def base_object
256
+ found=nil
257
+ @qobjects.each{|qobject|
258
+ found=qobject if qobject.obj_type == "b"
259
+ }
260
+ found
261
+ end
262
+
263
+ def parentM
264
+ pc.parentM
265
+ end
266
+ def item
267
+ pc.item
268
+ end
269
+
270
+ def text
271
+ if @query_id
272
+ "#{@query_id}"
273
+ else
274
+ ""
275
+ end
276
+ end
277
+
278
+ def base
279
+ if @base.active_iter
280
+ @base.active_iter[0]
281
+ else
282
+ 0
283
+ end
284
+ end
285
+ def name
286
+ @name.text
287
+ end
288
+ def comment
289
+ @comment.text
290
+ end
291
+ def qobject_by_link(link)
292
+ found=nil
293
+ @qobjects.each{|qobject|
294
+ found=qobject if qobject.link == link
295
+ }
296
+ found
297
+ end
298
+ def where_clause
299
+ @where.buffer.text
300
+ end
301
+ def group_by_clause
302
+ @group_by.buffer.text
303
+ end
304
+ def sql
305
+ s="select "
306
+ @select.each{|so| s="#{s}\n#{so.text}"}
307
+ s="#{s}\nfrom "
308
+ @from.each{|so| s="#{s}\n#{so.text}"}
309
+ s="#{s}\nwhere #{where_clause}" unless where_clause.length == 0
310
+ s="#{s}\ngroup by #{group_by_clause}" unless group_by_clause.length == 0
311
+ s
312
+ end
313
+
314
+ def update_base_selector
315
+ exval=@base.active_iter[0].to_i unless @base.active_iter.nil?
316
+ @base.model.clear
317
+ rows("select id,name from tables order by name"){|row|
318
+ iter=@base.model.append
319
+ iter[0]=row["id"].to_i
320
+ iter[1]=row["name"]
321
+ @base.set_active_iter(iter) if iter[0].to_i == exval
322
+ }
323
+ end
324
+
325
+ def inspect
326
+ "QBuilder"
327
+ end
328
+
329
+ def to_s
330
+ inspect
331
+ end
332
+ end
333
+
@@ -0,0 +1,82 @@
1
+ #this file is part of manqod
2
+ #manqod is distributed under the CDDL licence
3
+ #the author of manqod is Dobai-Pataky Balint(dpblnt@gmail.com)
4
+
5
+ class MyRendererRadioGroup < Gtk::ScrolledWindow
6
+ include ManqodCommon
7
+ def initialize(pc)
8
+ super()
9
+ set_policy(Gtk::POLICY_AUTOMATIC,Gtk::POLICY_AUTOMATIC)
10
+ add_with_viewport(@widget=Gtk::VBox.new)
11
+ @pc=pc
12
+ @selected="-1"
13
+ @items=Hash.new
14
+ @first=nil
15
+ item['admin']=true
16
+ item['querysql']="select cdata,cdisplay,description from scv where combo='#{item['data']}' order by cdata"
17
+
18
+ end
19
+ attr_accessor :pc
20
+ attr_accessor :items,:first
21
+ attr_accessor :selected
22
+
23
+ def update(new_value=item['default'])
24
+ item['default']=new_value
25
+ run_events(item['id'],'form_item-BeforeUpdate')
26
+ items.each_value{|rb| rb.destroy}
27
+ items.clear
28
+ @selected=item['default']
29
+ if item['admin']
30
+ q=parentM.admin.query(eeval("\"#{item['querysql']}\""))
31
+ else
32
+ q=parentM.query(eeval("\"#{item['querysql']}\""))
33
+ end
34
+
35
+ if q
36
+ while row=q.fetch_hash()
37
+ rb=if items.length==0
38
+ @first=Gtk::RadioButton.new(row['cdisplay'])
39
+ else
40
+ Gtk::RadioButton.new(first,row['cdisplay'])
41
+ end
42
+
43
+ to_activate=rb if row['cdata']==item['default'] #.set_sensitive(item['editable']=="true")
44
+ @selected=row['cdata'] if rb.active?
45
+ rb.signal_connect('toggled',row['cdata']){|me,cdata|
46
+ if me.active?
47
+ @selected=cdata
48
+ edebug("#{self} changed to item #{selected}","form-combo","debug")
49
+ pc.changed
50
+ pc.notify_observers(self)
51
+ run_events(item['id'],'form_item-Action')
52
+ end
53
+ }
54
+
55
+ @widget.pack_start(rb)
56
+ items[row['cdata']]=rb
57
+ end
58
+ end
59
+ show_all
60
+ if to_activate
61
+ to_activate.toggled #emit the action
62
+ to_activate.set_active(true) #set the default
63
+ end
64
+ run_events(item['id'],'form_item-AfterUpdate')
65
+ end
66
+
67
+ def parentM
68
+ pc.parentM
69
+ end
70
+ def item
71
+ pc.item
72
+ end
73
+ def text
74
+ selected
75
+ end
76
+ def inspect
77
+ "RadioGroup(#{item["description"]})"
78
+ end
79
+ def to_s;inspect;end
80
+
81
+ end
82
+