manqod 1.1505.0
Sign up to get free protection for your applications and to get access to all the features.
- data/bin/manqod +309 -0
- data/doc/HOWTOS +11 -0
- data/doc/INSTALL +6 -0
- data/doc/LICENCE +450 -0
- data/doc/README +33 -0
- data/doc/benchmarkings/ListLoader.rb +177 -0
- data/doc/manqod.png +0 -0
- data/doc/manqod.svg +99 -0
- data/doc/server.conf.example +24 -0
- data/lib/About.rb +93 -0
- data/lib/BarMenu/BarMenuItem.rb +46 -0
- data/lib/BarMenu.rb +76 -0
- data/lib/ButtonMenu/ButtonMenuItem.rb +82 -0
- data/lib/ButtonMenu/EndSeparator.rb +14 -0
- data/lib/ButtonMenu/StartSeparator.rb +14 -0
- data/lib/ButtonMenu.rb +154 -0
- data/lib/Common/Conf.rb +119 -0
- data/lib/Common/Eprint.rb +180 -0
- data/lib/Common/EventCache.rb +41 -0
- data/lib/Common/Fixnum.rb +18 -0
- data/lib/Common/Images.rb +41 -0
- data/lib/Common/ManqodDB.rb +40 -0
- data/lib/Common/MyExec.rb +77 -0
- data/lib/Common/MyImage.rb +47 -0
- data/lib/Common/Nick.rb +25 -0
- data/lib/Common/String.rb +15 -0
- data/lib/FormHolder/Form/InputHolder/Button.rb +133 -0
- data/lib/FormHolder/Form/InputHolder/Calendar.rb +101 -0
- data/lib/FormHolder/Form/InputHolder/CalendarButton.rb +117 -0
- data/lib/FormHolder/Form/InputHolder/ColorButton.rb +54 -0
- data/lib/FormHolder/Form/InputHolder/Combo.rb +82 -0
- data/lib/FormHolder/Form/InputHolder/ComboWithNew.rb +103 -0
- data/lib/FormHolder/Form/InputHolder/Common/Model.rb +337 -0
- data/lib/FormHolder/Form/InputHolder/ConstCombo.rb +18 -0
- data/lib/FormHolder/Form/InputHolder/ConstText.rb +17 -0
- data/lib/FormHolder/Form/InputHolder/Duration.rb +73 -0
- data/lib/FormHolder/Form/InputHolder/EditableList.rb +57 -0
- data/lib/FormHolder/Form/InputHolder/FieldCombo.rb +40 -0
- data/lib/FormHolder/Form/InputHolder/FieldList.rb +40 -0
- data/lib/FormHolder/Form/InputHolder/FileChooser.rb +131 -0
- data/lib/FormHolder/Form/InputHolder/FontButton.rb +37 -0
- data/lib/FormHolder/Form/InputHolder/FormImage.rb +74 -0
- data/lib/FormHolder/Form/InputHolder/HScale.rb +44 -0
- data/lib/FormHolder/Form/InputHolder/Hidden.rb +41 -0
- data/lib/FormHolder/Form/InputHolder/Label.rb +40 -0
- data/lib/FormHolder/Form/InputHolder/List.rb +176 -0
- data/lib/FormHolder/Form/InputHolder/MultiLine.rb +63 -0
- data/lib/FormHolder/Form/InputHolder/Password.rb +41 -0
- data/lib/FormHolder/Form/InputHolder/QBuilder/QObject.rb +269 -0
- data/lib/FormHolder/Form/InputHolder/QBuilder.rb +333 -0
- data/lib/FormHolder/Form/InputHolder/RadioGroup.rb +82 -0
- data/lib/FormHolder/Form/InputHolder/SourceView.rb +100 -0
- data/lib/FormHolder/Form/InputHolder/Spin.rb +49 -0
- data/lib/FormHolder/Form/InputHolder/Text.rb +55 -0
- data/lib/FormHolder/Form/InputHolder/TimeStamp.rb +82 -0
- data/lib/FormHolder/Form/InputHolder/TimeStampButton.rb +93 -0
- data/lib/FormHolder/Form/InputHolder/Toggle.rb +43 -0
- data/lib/FormHolder/Form/InputHolder.rb +458 -0
- data/lib/FormHolder/Form.rb +529 -0
- data/lib/FormHolder.rb +203 -0
- data/lib/Gtk.rb +101 -0
- data/lib/GtkAttributes.rb +76 -0
- data/lib/Kernel.rb +48 -0
- data/lib/ListHolder/EditableList/CellRenderers/Combo.rb +91 -0
- data/lib/ListHolder/EditableList/CellRenderers/ComboText.rb +22 -0
- data/lib/ListHolder/EditableList/CellRenderers/ConstCombo.rb +12 -0
- data/lib/ListHolder/EditableList/CellRenderers/ConstText.rb +23 -0
- data/lib/ListHolder/EditableList/CellRenderers/Pixbuf.rb +18 -0
- data/lib/ListHolder/EditableList/CellRenderers/Progress.rb +36 -0
- data/lib/ListHolder/EditableList/CellRenderers/Text.rb +51 -0
- data/lib/ListHolder/EditableList/CellRenderers/Toggle.rb +35 -0
- data/lib/ListHolder/EditableList/Column.rb +223 -0
- data/lib/ListHolder/EditableList/DrbListModel.rb +809 -0
- data/lib/ListHolder/EditableList/ListPrintOperation/ColumnsHeaderLayout.rb +56 -0
- data/lib/ListHolder/EditableList/ListPrintOperation/CustomPageSetup.rb +100 -0
- data/lib/ListHolder/EditableList/ListPrintOperation/FooterLayout.rb +26 -0
- data/lib/ListHolder/EditableList/ListPrintOperation/HeaderLayout.rb +35 -0
- data/lib/ListHolder/EditableList/ListPrintOperation/IterLayout.rb +89 -0
- data/lib/ListHolder/EditableList/ListPrintOperation.rb +365 -0
- data/lib/ListHolder/EditableList.rb +309 -0
- data/lib/ListHolder/GanttHolder/Gantt/Rectangle.rb +290 -0
- data/lib/ListHolder/GanttHolder/Gantt.rb +317 -0
- data/lib/ListHolder/GanttHolder/GanttFooter.rb +27 -0
- data/lib/ListHolder/GanttHolder/GanttScaler.rb +60 -0
- data/lib/ListHolder/GanttHolder.rb +31 -0
- data/lib/ListHolder/HistoryWindow.rb +63 -0
- data/lib/ListHolder/ListButtonHolder/ArchiveButton.rb +37 -0
- data/lib/ListHolder/ListButtonHolder/ButtonGroup.rb +32 -0
- data/lib/ListHolder/ListButtonHolder/FilterButton.rb +28 -0
- data/lib/ListHolder/ListButtonHolder/ListButton.rb +305 -0
- data/lib/ListHolder/ListButtonHolder/OrderingButton.rb +26 -0
- data/lib/ListHolder/ListButtonHolder/SumPanelButton.rb +23 -0
- data/lib/ListHolder/ListButtonHolder.rb +94 -0
- data/lib/ListHolder/ListPanel/ListFilter/FRenderer/Combo.rb +94 -0
- data/lib/ListHolder/ListPanel/ListFilter/FRenderer/ConstCombo.rb +11 -0
- data/lib/ListHolder/ListPanel/ListFilter/FRenderer/Text.rb +26 -0
- data/lib/ListHolder/ListPanel/ListFilter/FRenderer/Toggle.rb +41 -0
- data/lib/ListHolder/ListPanel/ListFilter/FRenderer.rb +58 -0
- data/lib/ListHolder/ListPanel/ListFilter.rb +42 -0
- data/lib/ListHolder/ListPanel/ListSum/Text.rb +32 -0
- data/lib/ListHolder/ListPanel/ListSum.rb +72 -0
- data/lib/ListHolder/ListPanel.rb +60 -0
- data/lib/ListHolder.rb +241 -0
- data/lib/LoginWindow.rb +77 -0
- data/lib/MainRouter.rb +64 -0
- data/lib/ManqodCommon.rb +295 -0
- data/lib/ManqodHelp/FormatEditor/FormatJustificationWidget.rb +76 -0
- data/lib/ManqodHelp/FormatsEditor.rb +139 -0
- data/lib/ManqodHelp/HelpBrowser/FormatTagTable/FormatTag.rb +84 -0
- data/lib/ManqodHelp/HelpBrowser/FormatTagTable.rb +39 -0
- data/lib/ManqodHelp/HelpBrowser.rb +135 -0
- data/lib/ManqodHelp/HelpIndex.rb +62 -0
- data/lib/ManqodHelp/HelpToolbar.rb +16 -0
- data/lib/ManqodHelp.rb +120 -0
- data/lib/ManqodRPC.rb +37 -0
- data/lib/Memcache.rb +82 -0
- data/lib/MyConfig.rb +93 -0
- data/lib/Print/PrintItem/TextLayout.rb +47 -0
- data/lib/Print/PrintItem.rb +240 -0
- data/lib/Print.rb +199 -0
- data/lib/PrintEditor/ItemInfo/ItemImage.rb +30 -0
- data/lib/PrintEditor/ItemInfo/ItemList.rb +44 -0
- data/lib/PrintEditor/ItemInfo/ItemTextAlignment.rb +27 -0
- data/lib/PrintEditor/ItemInfo.rb +129 -0
- data/lib/PrintEditor/PageLayout.rb +91 -0
- data/lib/PrintEditor/PrintEditorItem.rb +310 -0
- data/lib/PrintEditor.rb +195 -0
- data/lib/RelationBuilder/RTable/RField.rb +91 -0
- data/lib/RelationBuilder/RTable.rb +293 -0
- data/lib/RelationBuilder/Relation/RelationHandle.rb +70 -0
- data/lib/RelationBuilder/Relation.rb +161 -0
- data/lib/RelationBuilder/RunQuery.rb +55 -0
- data/lib/RelationBuilder/SearchWindow.rb +72 -0
- data/lib/RelationBuilder.rb +468 -0
- data/lib/SB/ListProgress.rb +150 -0
- data/lib/SB/Messaging.rb +77 -0
- data/lib/SB.rb +29 -0
- data/lib/mynotebook.rb +131 -0
- data/lib/mytouchwindow.rb +162 -0
- data/lib/mywindow.rb +134 -0
- data/lib/wysiwyg-print-label.rb +57 -0
- 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
|
+
|