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,309 @@
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 MyEditableList < Gtk::TreeView
6
+ include Observable
7
+ include GtkAttributes
8
+ include ListPrint
9
+ include ManqodCommon
10
+ include Conf
11
+
12
+ def initialize(caller)
13
+ @caller=caller
14
+ @list_id=nil
15
+ @parentM=nil
16
+ @info=caller.info
17
+ @title="list"
18
+ @tip=Gtk::Tooltips.new
19
+ super(nil)
20
+ @list_model=ListModel.new(self)
21
+ set_enable_grid_lines(case get_conf(0,0,"grid")
22
+ when "both" then Gtk::TreeView::GridLines::BOTH
23
+ when "vertical" then Gtk::TreeView::GridLines::VERTICAL
24
+ when "horizontal" then Gtk::TreeView::GridLines::HORIZONTAL
25
+ else Gtk::TreeView::GridLines::NONE
26
+ end
27
+ ) if Gtk.check_version?(2,10,9)
28
+ set_enable_tree_lines(true)
29
+ set_fixed_height_mode(false)
30
+ set_reorderable(false)# drag and drop of rows
31
+ headers_clickable=false
32
+ set_rules_hint(true)
33
+ selection.set_mode(Gtk::SELECTION_MULTIPLE)
34
+ signal_connect('cursor-changed') { |me|
35
+ if !cursor[0].nil? and iter=model.get_iter(cursor[0])
36
+ id_at_cursor=iter[@list_model.column_of_id]
37
+ else
38
+ id_at_cursor=-1
39
+ end
40
+ if id_at_cursor != get_cursor_id
41
+ save_cursor_id(id_at_cursor)
42
+ edebug("#{self} selection changed to #{id_at_cursor}, notifying observers","list","info")
43
+ changed
44
+ begin
45
+ notify_observers(self)
46
+ rescue =>err
47
+ eerror("error notifying observers:#{err}","list")
48
+ end
49
+ end
50
+ }
51
+
52
+ signal_connect("button-press-event"){|me,ev|
53
+ holder.buttonholder.activate_default if ev.event_type == Gdk::Event::BUTTON2_PRESS
54
+ false
55
+ }
56
+ @tmp=Hash.new
57
+ @is_embedded=nil
58
+ end
59
+ attr_accessor :caller, :selected, :list_id, :list_model, :parentM, :headertypes, :headers, :info, :title, :tip, :pop, :tmp, :is_embedded
60
+
61
+ def holder
62
+ @caller
63
+ end
64
+
65
+ def get_model
66
+ @list_model
67
+ end
68
+ def save_config
69
+ set_conf(get_id,0,"search",search_column)
70
+ end
71
+ def parentselected
72
+ @list_model.parentselected
73
+ end
74
+ def moditem
75
+ @list_model.moditem
76
+ end
77
+ def progress
78
+ @caller.progress
79
+ end
80
+
81
+ def is_embedded
82
+ @is_embedded
83
+ end
84
+
85
+ def embedd?
86
+ if @moditem && @moditem['on_embed'].length >0
87
+ eeval(@moditem['on_embed'],self)
88
+ else
89
+ true
90
+ end
91
+ end
92
+
93
+ def get_id
94
+ @list_id
95
+ end
96
+
97
+
98
+ def set_id(newid)
99
+ if newid.to_i != @list_id.to_i
100
+ # save_config
101
+ @list_id=newid.to_i
102
+ @caller.set_id(list_id)
103
+ create_skeleton
104
+ end
105
+ self
106
+ end
107
+
108
+ def set_parentM(parentM)
109
+ @parentM=parentM
110
+ self
111
+ end
112
+
113
+ def my
114
+ @@my
115
+ end
116
+ def headertypes
117
+ @list_model.headertypes
118
+ end
119
+ def load_data(notifier,the_one=nil)
120
+ @list_model.load_data(notifier,the_one=nil)
121
+ end
122
+
123
+ def refilter
124
+ @list_model.refilter
125
+ end
126
+
127
+ def set_cursor_id(id_to_set=get_cursor_id,scroll=true)
128
+ current_id=cursor[0] ? @list_model.sorter.get_iter(cursor[0])[@list_model.column_of_id] : -1
129
+
130
+ if current_id != id_to_set.to_i
131
+ if iter=@list_model.iter_of_id(id_to_set)
132
+ edebug("setting cursor to #{id_to_set.inspect}","list")
133
+ expand_to_path(iter.path)
134
+ scroll_to_cell(iter.path,nil,false,0,0) if scroll
135
+ set_cursor(iter.path,nil,nil)
136
+ save_cursor_id(id_to_set)
137
+ else
138
+ unless cursor[0].nil?
139
+ edebug("setting cursor none#{id_to_set != -1?"insted of #{id_to_set.inspect}":""}","list")
140
+ set_cursor(Gtk::TreePath.new,nil,nil)
141
+ end
142
+ save_cursor_id(-1)
143
+ end
144
+ end
145
+ iter
146
+ end
147
+
148
+ def save_cursor_id(id_to_set)
149
+ edebug("saving cursor to #{id_to_set.inspect}","list")
150
+ set_conf(get_id,0,"cursor",id_to_set)
151
+ end
152
+ def get_cursor_id
153
+ get_conf(get_id,0,"cursor").to_i
154
+ end
155
+
156
+ def scroll_to_cursor(id_to_scroll=get_cursor_id,scroll=true)
157
+ set_cursor_id(id_to_scroll,scroll)
158
+ changed
159
+ notify_observers(self)
160
+ get_cursor_id
161
+ end
162
+
163
+ def set_info(new_info)
164
+ info.set_label(new_info)
165
+ end
166
+
167
+ def update_tip
168
+ case get_conf(0,0,"list-tooltip")
169
+ when "filters" then
170
+ t="filters:"
171
+ @caller.list_filter_panel.list_filter.columns.each_key{|key|
172
+ h=@caller.list_filter_panel.list_filter.columns[key].header
173
+ fl=get_conf(get_id,h['id'],"filter")
174
+ case h['type']
175
+ when 'gtk_combo', 'gtk_const_combo' then fl = (fl=="-1" or fl=="") ? "" : "=#{fl}"
176
+ end
177
+ t+="\n#{h['header']}: #{fl}" if !fl.nil? and fl.length>0
178
+ }
179
+ t="#{t}\nnone" if t=="filters:"
180
+ @tip.set_tip(self,t,'extra hint')
181
+ @tip.enable
182
+ end
183
+ end
184
+
185
+ def create_skeleton
186
+ if get_id.nil?
187
+ edebug(" can't update","list","error")
188
+ return
189
+ end
190
+ set_model(nil)
191
+ @list_model.create_skeleton
192
+ set_info("initializing")
193
+ @title=moditem["display"]
194
+ while c=get_column(0)
195
+ remove_column(c)
196
+ c.wipe
197
+ end
198
+
199
+
200
+ col_num=1;
201
+ @list_model.headers.sort{|a,b| a[1]["oid"].to_f<=>b[1]["oid"].to_f}.each{|hk,header|
202
+ header['editable']="false" if header['writable']=="0"
203
+ column=nil
204
+ if column=MyColumn.new(self,header)
205
+ append_column(column)
206
+ col_num+=1
207
+ end if header['visible']
208
+ }
209
+ edebug("#{self} skeleton created","list","info")
210
+ set_search_column(get_conf(get_id,0,"search").to_i)
211
+
212
+ set_info("loading")
213
+ @caller.list_panel.update(self)
214
+ @caller.advanced_filter.update
215
+ @caller.sum_button.update
216
+ @caller.buttonholder.update(self)
217
+ self
218
+ end
219
+
220
+ def update(notifier)
221
+ @list_model.update(notifier)
222
+ scroll_to_cursor
223
+ update_tip
224
+ self
225
+ end
226
+
227
+ def selected_ids
228
+ ids=Array.new
229
+ selection.selected_each { |model, path, iter| ids.push(iter[@list_model.column_of_id])}
230
+ ids
231
+ end
232
+
233
+ def duplicate_selected(caller)
234
+ ret=nil
235
+ run_events(get_id,'list-OnDuplicate-BeforeSQL')
236
+ selection.selected_each { |model, path, iter| ret=@list_model.duplicate_iter(iter)}
237
+ run_events(get_id,'list-OnDuplicate-AfterSQL')
238
+ ret
239
+ end
240
+
241
+ def remove_selected(caller,ids=nil)
242
+ ids=[get_cursor_id] if ids.nil?
243
+ @removing=ids
244
+ run_events(get_id,'list-OnRemove-BeforeSQL')
245
+ @list_model.remove_iters(ids)
246
+ run_events(get_id,'list-OnRemove-AfterSQL')
247
+ end
248
+
249
+ def add_row(caller, added_id=nil)
250
+ if added_id.nil?
251
+ run_events(get_id,'list-OnInsert-BeforeSQL')
252
+ added_id=@list_model.add_iter
253
+ run_events(get_id,'list-OnInsert-AfterSQL')
254
+ else
255
+ row_modified(added_id)
256
+ end
257
+ # @rowcount=@rowcount+1
258
+ #select insereted
259
+ #scroll_to_cursor(added_id)
260
+ set_conf(get_id,0,"cursor",added_id)
261
+ end
262
+
263
+ def row_modified(modified_id=list.get_cursor_id)
264
+ @list_model.row_modified(modified_id)
265
+ end
266
+
267
+ def child_by_id(mid)
268
+ @caller.notebook.moditem_by_id(mid)
269
+ end
270
+
271
+ def next_editable_column(column)
272
+ next_col=nil
273
+ col_num=nil
274
+ i=0
275
+ columns.each{|col|
276
+ col_num=i if col == column
277
+ if !col_num.nil? and i > col_num and col.header["editable"]=="true" and col.header["type"]!='gtk_toggle'
278
+ next_col=col
279
+ break
280
+ end
281
+ i+=1
282
+ }
283
+ next_col
284
+ end
285
+
286
+ def wipe
287
+ save_config
288
+ set_model(nil)
289
+ if @list_model.thread and @list_model.thread.alive?
290
+ progress.killed(object_id)
291
+ p Thread.kill(@list_model.thread)
292
+ while @list_model.thread.alive? do ecode("waiting for thread"); end
293
+ end
294
+ @list_model.wipe
295
+ while c=get_column(0)
296
+ remove_column(c)
297
+ c.wipe
298
+ end
299
+ destroy
300
+ end
301
+
302
+ def inspect
303
+ "List(#{title})"
304
+ end
305
+ def to_s
306
+ inspect
307
+ end
308
+ end
309
+
@@ -0,0 +1,290 @@
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 Rectangle
6
+ def initialize(gantt,iter)
7
+ @iter=iter
8
+ @gantt=gantt
9
+ @has_child=iter.has_child?
10
+ @level=0
11
+ @iter_id=iter[gantt.list.list_model.column_of_id].to_i
12
+ @parent_r=@gantt.rectangles[iter.parent[gantt.list.list_model.column_of_id].to_i] unless iter.parent.nil?
13
+ @successors=Hash.new
14
+ if gantt.successors_column
15
+ iter[gantt.successors_column].split(',').each{|pid|
16
+ @successors[pid.to_i]=nil
17
+ }
18
+ end
19
+ @group=iter[gantt.group_column] if gantt.group_column
20
+ @partial=if gantt.partial_column then iter[gantt.partial_column].to_i else 100 end
21
+ @percentage=if gantt.percentage_column then iter[gantt.percentage_column].to_i else 0 end
22
+ if gantt.group_color_column
23
+ begin
24
+ @color=Gdk::Color.parse("##{iter[@gantt.group_color_column]}")
25
+ rescue
26
+ @color=nil
27
+ end
28
+ else
29
+ @color=nil
30
+ end
31
+ @color=Gdk::Color.parse("#1782E0") if @color.nil?
32
+ #we assume it's mysql unix_timestamp
33
+ @start=iter[gantt.start_column].to_i
34
+ @dur=iter[gantt.dur_column].to_i
35
+
36
+ @y1=0
37
+ @height=10
38
+ @gantt_min_x=0
39
+ iter_coordinates
40
+ @visible=iter[gantt.list.list_model.column_of_visible]
41
+ end
42
+ attr_reader :iter, :iter_id, :height, :y1, :successors, :start, :dur, :group, :percentage
43
+ attr_accessor :level
44
+
45
+ def finish
46
+ @start+@dur
47
+ end
48
+
49
+ def set_duration(ndur,store=false)
50
+ @dur=ndur
51
+ @gantt.list.list_model.change_value_of_id(iter_id,@gantt.list.gtk_attribute('gantt_duration'),@dur) if store
52
+ end
53
+
54
+ def set_percentage(npercentage,store=false)
55
+ @percentage=npercentage
56
+ @gantt.list.list_model.change_value_of_id(iter_id,@gantt.list.gtk_attribute('gantt_percentage'),@percentage) if store && @gantt.percentage_column
57
+ end
58
+
59
+ def set_height(new_height)
60
+ @height=new_height
61
+ end
62
+
63
+ def iter_coordinates
64
+ r=@gantt.list.get_background_area(@gantt.list.model.convert_child_path_to_path(@gantt.list.model.model.convert_child_path_to_path(iter.path)),nil)
65
+ @y1=r.y+@gantt.vadjustment.value+r.height/3
66
+ @height=r.height*2/3
67
+ end
68
+ def x1
69
+ @start/@gantt.res-@gantt_min_x
70
+ end
71
+ def to_gui(x)
72
+ x.to_f/@gantt.res-@gantt_min_x
73
+ end
74
+ def x2
75
+ x1+width
76
+ end
77
+ def partial_width
78
+ width*@partial.to_f/100.0
79
+ end
80
+ def partial_x2
81
+ x1+partial_width
82
+ end
83
+ def partial_duration
84
+ @dur*@partial.to_f/100.0
85
+ end
86
+ def partial_finish
87
+ @start+@dur*@partial.to_f/100.0
88
+ end
89
+ def y2
90
+ @y1+@height
91
+ end
92
+ def in_area?(x,y)
93
+ x1<=x && x<=x2 && y1<y && y<y2
94
+ end
95
+ def width
96
+ @dur/@gantt.res
97
+ end
98
+ def x
99
+ x1+width/2
100
+ end
101
+ def y
102
+ y1+height/2
103
+ end
104
+ def draw(cr,hilight=false)
105
+ return self unless visible?
106
+ #fill bar
107
+ cr.set_source_rgba(@color.red.to_f/0x10000,@color.green.to_f/0x10000,@color.blue.to_f/0x10000,if @has_child then 0.05 else 0.7 end)
108
+ cr.set_line_width(1).set_dash(100000)
109
+ cr.rounded_rectangle(x1,y1,width,height,4)
110
+ cr.fill
111
+ cr.stroke
112
+ #bar border
113
+ if hilight
114
+ cr.set_source_rgba(0.7,0.1,0.1,0.7)
115
+ else
116
+ cr.set_source_rgba(0,0,0,0.7)
117
+ end
118
+ cr.rounded_rectangle(x1,y1,width,height,4)
119
+ cr.stroke
120
+ #draw collisions
121
+ cr.set_source_rgba(1,0,0,0.1)
122
+ @gantt.collisions(self).each{|coo|
123
+ cr.rectangle(to_gui(coo[0]),0,to_gui(coo[1])-to_gui(coo[0]),@gantt.widget.allocation.height)
124
+ cr.fill
125
+ cr.stroke
126
+ }
127
+ #draw percentage
128
+ if @gantt.percentage_column
129
+ cr.set_source_rgba((1-@color.red.to_f)/0x10000,(1-@color.green.to_f)/0x10000,(1-@color.blue.to_f)/0x10000,if @has_child then 0.05 else 0.3 end)
130
+ cr.rounded_rectangle(x1,y1+1,@percentage*width/100,height-2,3)
131
+ cr.fill
132
+ cr.stroke
133
+ end
134
+ self
135
+ end
136
+
137
+ def draw_arrow(cr)
138
+ #successors arrow
139
+ @successors.each_value{|pred|
140
+ if pred && visible? && pred.visible?
141
+ cr.set_line_width(2).set_source_rgba(0.1,0.1,0.1,0.7).set_dash(100000)
142
+ xx1=[x+10,x2].min
143
+ yy4=if y<pred.y then pred.y1-1 else pred.y2+1 end
144
+ yya=if y<pred.y then -3 else 3 end
145
+ cr.move_to(xx1,y)
146
+ cr.curve_to(pred.x,y,pred.x,y,pred.x,yy4)
147
+ # cr.stroke
148
+ =begin
149
+ cr.set_source_rgba(1,0,0,0.5)
150
+ cr.move_to(pred.x,y)
151
+ cr.line_to(pred.x,yy4)
152
+
153
+ cr.stroke
154
+
155
+ cr.set_source_rgba(1,1,0,0.5)
156
+ cr.move_to(xx1,y)
157
+ cr.line_to(pred.x,y)
158
+ cr.stroke
159
+ =end
160
+ #arrow
161
+ cr.move_to(pred.x,yy4).rel_line_to(-3,yya)
162
+ cr.move_to(pred.x,yy4).rel_line_to(3,yya)
163
+ cr.stroke
164
+ end
165
+ }
166
+ self
167
+ end
168
+ def print_percentage(cr)
169
+ if visible? && @gantt.percentage_column && width >22 && width*Pango::SCALE < 1073741824
170
+ pl=cr.create_pango_layout
171
+ font="Sans 7"
172
+ pl.set_font_description(Pango::FontDescription.new(font))
173
+ pl.set_width(width*Pango::SCALE)
174
+ pl.set_wrap(Pango::Layout::WRAP_WORD_CHAR).set_ellipsize(Pango::Layout::ELLIPSIZE_NONE).set_alignment(Pango::Layout::ALIGN_CENTER)
175
+ cr.set_source_rgba(0,0,1,1)
176
+
177
+ pl.set_text("#{@percentage}%")
178
+ cr.move_to(x1,y1+2)
179
+ cr.show_pango_layout(pl)
180
+
181
+ cr.stroke
182
+ end
183
+ end
184
+ def draw_verticals(cr)
185
+ return self unless visible?
186
+ #verticals
187
+ cr.set_source_rgba(48.0/255,88.0/255,116.0/255,0.4).set_line_width(0.7).set_dash(5)
188
+ cr.move_to(x1,0)
189
+ cr.rel_line_to(0,y1)
190
+ cr.move_to(x2,0)
191
+ cr.rel_line_to(0,y1)
192
+ cr.stroke
193
+ self
194
+ end
195
+ def draw_hilight(cr)
196
+ return self unless visible?
197
+ cr.set_source_rgba(0.5,0.5,0.5,0.3).set_dash(100000).set_line_cap(Cairo::LineCap::BUTT)
198
+ cr.set_line_width(height).move_to(0,y).line_to(x2,y).stroke
199
+ cr.set_line_width(width).move_to(x,0).line_to(x,y2).stroke
200
+ cr.set_line_cap(Cairo::LineCap::ROUND)
201
+ end
202
+
203
+ def set_gantt_min_x(gmin_x)
204
+ @gantt_min_x=gmin_x
205
+ end
206
+
207
+ def move_to(new_x,store=false)
208
+ return unless @gantt.start_editable
209
+ new_start=@gantt.res*(@gantt_min_x+new_x)
210
+ @store_start=true if @start!=new_start
211
+ @start=new_start
212
+ min=@gantt.min_for_rectangle(self)
213
+ new_start=min if new_start<min
214
+ @start=new_start
215
+ @gantt.clear
216
+ push_successors(store)
217
+ set_start(@start,store)
218
+ end
219
+ def move_finished
220
+ set_start(@start,true)
221
+ push_successors(true)
222
+ end
223
+
224
+ def recursion?(starter=nil)
225
+ ret=false
226
+ successors.each_value{|pred|
227
+ next if pred.nil?
228
+ #avoid recursion
229
+ if starter == pred
230
+ ret=true
231
+ ewarn("recursion")
232
+ return ret
233
+ end
234
+ ret=pred.recursion?(if starter.nil? then self else starter end)
235
+ }
236
+ ret
237
+ end
238
+
239
+ def init_successors
240
+ @successors.each_key{|k| @successors[k]=@gantt.rectangles[k]}
241
+ end
242
+
243
+ def toggle_successor(pr)
244
+ return false if pr.nil?
245
+ if ret=((@successors.has_key?(pr.iter_id)) || (pr==self))
246
+ #this successor exists, removing
247
+ @successors.delete(pr.iter_id)
248
+ else
249
+ #adding new successor
250
+ @successors[pr.iter_id]=pr
251
+ @successors.delete(pr.iter_id) if recursion?
252
+ end
253
+
254
+ #pr is successors rectangle, saving here
255
+ pids=""
256
+ @successors.each_key{|k| pids="#{pids}#{k},"}
257
+ @gantt.list.list_model.change_value_of_id(iter_id,@gantt.list.gtk_attribute('gantt_successors'),pids.chomp(","))
258
+ push_successors(true)
259
+ ret
260
+ end
261
+
262
+ def set_start(new_start,store=false)
263
+ #save start
264
+ @start=new_start
265
+ if store
266
+ @gantt.list.list_model.change_value_of_id(iter_id,@gantt.list.gtk_attribute('gantt_start'),@start)
267
+ end
268
+ end
269
+ def push_successors(store=false)
270
+ successors.each_value{|pred|
271
+ next if pred.nil?
272
+ if store then
273
+ pred.move_to(pred.x1,store)
274
+ else
275
+ pred.move_to(partial_x2,store) if pred.start < @start+partial_duration
276
+ end
277
+ pred.push_successors(store)
278
+ }
279
+ end
280
+ def visible?
281
+ @visible && (@parent_r.nil? || y1!=@parent_r.y1)
282
+ end
283
+ def has_child?
284
+ @has_child
285
+ end
286
+ def to_s
287
+ "Rectangle(id:#{iter_id})"
288
+ end
289
+ end
290
+