openall_time_applet 0.0.29 → 0.0.30
Sign up to get free protection for your applications and to get access to all the features.
- data/VERSION +1 -1
- data/glade/win_main.glade +155 -119
- data/gui/trayicon.rb +3 -3
- data/gui/win_main.rb +134 -50
- data/gui/win_worktime_overview.rb +6 -6
- data/models/timelog.rb +3 -2
- data/openall_time_applet.gemspec +2 -2
- metadata +3 -3
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.30
|
data/glade/win_main.glade
CHANGED
@@ -16,7 +16,7 @@
|
|
16
16
|
<property name="can_focus">False</property>
|
17
17
|
<property name="title" translatable="yes">OpenAll Time Applet</property>
|
18
18
|
<property name="window_position">center</property>
|
19
|
-
<property name="default_width">
|
19
|
+
<property name="default_width">880</property>
|
20
20
|
<signal name="destroy" handler="on_window_destroy" swapped="no"/>
|
21
21
|
<child>
|
22
22
|
<object class="GtkVBox" id="vbox1">
|
@@ -113,63 +113,72 @@
|
|
113
113
|
<property name="can_focus">False</property>
|
114
114
|
<property name="left_padding">12</property>
|
115
115
|
<child>
|
116
|
-
<object class="
|
116
|
+
<object class="GtkAlignment" id="alignment6">
|
117
117
|
<property name="visible">True</property>
|
118
118
|
<property name="can_focus">False</property>
|
119
|
-
<property name="
|
119
|
+
<property name="right_padding">9</property>
|
120
120
|
<child>
|
121
|
-
<object class="
|
122
|
-
<property name="visible">True</property>
|
123
|
-
<property name="can_focus">True</property>
|
124
|
-
<property name="invisible_char">•</property>
|
125
|
-
<property name="primary_icon_activatable">False</property>
|
126
|
-
<property name="secondary_icon_activatable">False</property>
|
127
|
-
<property name="primary_icon_sensitive">True</property>
|
128
|
-
<property name="secondary_icon_sensitive">True</property>
|
129
|
-
<signal name="activate" handler="on_txtDescr_activate" swapped="no"/>
|
130
|
-
</object>
|
131
|
-
<packing>
|
132
|
-
<property name="expand">True</property>
|
133
|
-
<property name="fill">True</property>
|
134
|
-
<property name="position">0</property>
|
135
|
-
</packing>
|
136
|
-
</child>
|
137
|
-
<child>
|
138
|
-
<object class="GtkComboBox" id="cbTask">
|
139
|
-
<property name="visible">True</property>
|
140
|
-
<property name="can_focus">False</property>
|
141
|
-
</object>
|
142
|
-
<packing>
|
143
|
-
<property name="expand">False</property>
|
144
|
-
<property name="fill">True</property>
|
145
|
-
<property name="position">1</property>
|
146
|
-
</packing>
|
147
|
-
</child>
|
148
|
-
<child>
|
149
|
-
<object class="GtkHButtonBox" id="hbuttonbox3">
|
121
|
+
<object class="GtkHBox" id="hbox1">
|
150
122
|
<property name="visible">True</property>
|
151
123
|
<property name="can_focus">False</property>
|
124
|
+
<property name="spacing">6</property>
|
152
125
|
<child>
|
153
|
-
<object class="
|
154
|
-
<property name="label" translatable="yes">Switch</property>
|
126
|
+
<object class="GtkEntry" id="txtDescr">
|
155
127
|
<property name="visible">True</property>
|
156
128
|
<property name="can_focus">True</property>
|
157
|
-
<property name="
|
158
|
-
<property name="
|
159
|
-
<
|
129
|
+
<property name="invisible_char">•</property>
|
130
|
+
<property name="invisible_char_set">True</property>
|
131
|
+
<property name="primary_icon_activatable">False</property>
|
132
|
+
<property name="secondary_icon_activatable">False</property>
|
133
|
+
<property name="primary_icon_sensitive">True</property>
|
134
|
+
<property name="secondary_icon_sensitive">True</property>
|
135
|
+
<signal name="activate" handler="on_txtDescr_activate" swapped="no"/>
|
160
136
|
</object>
|
161
137
|
<packing>
|
162
|
-
<property name="expand">
|
138
|
+
<property name="expand">True</property>
|
163
139
|
<property name="fill">True</property>
|
164
140
|
<property name="position">0</property>
|
165
141
|
</packing>
|
166
142
|
</child>
|
143
|
+
<child>
|
144
|
+
<object class="GtkComboBox" id="cbTask">
|
145
|
+
<property name="width_request">145</property>
|
146
|
+
<property name="visible">True</property>
|
147
|
+
<property name="can_focus">False</property>
|
148
|
+
</object>
|
149
|
+
<packing>
|
150
|
+
<property name="expand">False</property>
|
151
|
+
<property name="fill">True</property>
|
152
|
+
<property name="position">1</property>
|
153
|
+
</packing>
|
154
|
+
</child>
|
155
|
+
<child>
|
156
|
+
<object class="GtkHButtonBox" id="hbuttonbox3">
|
157
|
+
<property name="visible">True</property>
|
158
|
+
<property name="can_focus">False</property>
|
159
|
+
<child>
|
160
|
+
<object class="GtkButton" id="btnSwitch">
|
161
|
+
<property name="label" translatable="yes">Switch</property>
|
162
|
+
<property name="visible">True</property>
|
163
|
+
<property name="can_focus">True</property>
|
164
|
+
<property name="receives_default">True</property>
|
165
|
+
<property name="use_action_appearance">False</property>
|
166
|
+
<signal name="clicked" handler="on_btnSwitch_clicked" swapped="no"/>
|
167
|
+
</object>
|
168
|
+
<packing>
|
169
|
+
<property name="expand">False</property>
|
170
|
+
<property name="fill">True</property>
|
171
|
+
<property name="position">0</property>
|
172
|
+
</packing>
|
173
|
+
</child>
|
174
|
+
</object>
|
175
|
+
<packing>
|
176
|
+
<property name="expand">False</property>
|
177
|
+
<property name="fill">True</property>
|
178
|
+
<property name="position">2</property>
|
179
|
+
</packing>
|
180
|
+
</child>
|
167
181
|
</object>
|
168
|
-
<packing>
|
169
|
-
<property name="expand">False</property>
|
170
|
-
<property name="fill">True</property>
|
171
|
-
<property name="position">2</property>
|
172
|
-
</packing>
|
173
182
|
</child>
|
174
183
|
</object>
|
175
184
|
</child>
|
@@ -179,7 +188,7 @@
|
|
179
188
|
<object class="GtkLabel" id="label1">
|
180
189
|
<property name="visible">True</property>
|
181
190
|
<property name="can_focus">False</property>
|
182
|
-
<property name="label" translatable="yes"><b>
|
191
|
+
<property name="label" translatable="yes"><b>Start new acitivity</b></property>
|
183
192
|
<property name="use_markup">True</property>
|
184
193
|
</object>
|
185
194
|
</child>
|
@@ -196,112 +205,138 @@
|
|
196
205
|
<property name="can_focus">True</property>
|
197
206
|
<signal name="activate" handler="on_expOverview_activate" after="yes" swapped="no"/>
|
198
207
|
<child>
|
199
|
-
<object class="
|
208
|
+
<object class="GtkAlignment" id="alignment2">
|
200
209
|
<property name="visible">True</property>
|
201
210
|
<property name="can_focus">False</property>
|
202
|
-
<property name="
|
211
|
+
<property name="right_padding">12</property>
|
203
212
|
<child>
|
204
|
-
<object class="
|
213
|
+
<object class="GtkVBox" id="vbox2">
|
205
214
|
<property name="visible">True</property>
|
206
215
|
<property name="can_focus">False</property>
|
207
|
-
<property name="
|
216
|
+
<property name="spacing">2</property>
|
208
217
|
<child>
|
209
|
-
<object class="
|
218
|
+
<object class="GtkAlignment" id="alignment4">
|
210
219
|
<property name="visible">True</property>
|
211
220
|
<property name="can_focus">False</property>
|
221
|
+
<property name="left_padding">12</property>
|
212
222
|
<child>
|
213
|
-
<object class="
|
223
|
+
<object class="GtkViewport" id="viewport1">
|
214
224
|
<property name="visible">True</property>
|
215
|
-
<property name="can_focus">
|
216
|
-
<property name="hscrollbar_policy">automatic</property>
|
217
|
-
<property name="vscrollbar_policy">automatic</property>
|
225
|
+
<property name="can_focus">False</property>
|
218
226
|
<child>
|
219
|
-
<object class="
|
227
|
+
<object class="GtkScrolledWindow" id="scrolledwindow1">
|
220
228
|
<property name="visible">True</property>
|
221
229
|
<property name="can_focus">True</property>
|
230
|
+
<property name="hscrollbar_policy">automatic</property>
|
231
|
+
<property name="vscrollbar_policy">automatic</property>
|
232
|
+
<child>
|
233
|
+
<object class="GtkTreeView" id="tvTimelogs">
|
234
|
+
<property name="visible">True</property>
|
235
|
+
<property name="can_focus">True</property>
|
236
|
+
</object>
|
237
|
+
</child>
|
222
238
|
</object>
|
223
239
|
</child>
|
224
240
|
</object>
|
225
241
|
</child>
|
226
242
|
</object>
|
227
|
-
</child>
|
228
|
-
</object>
|
229
|
-
<packing>
|
230
|
-
<property name="expand">True</property>
|
231
|
-
<property name="fill">True</property>
|
232
|
-
<property name="position">0</property>
|
233
|
-
</packing>
|
234
|
-
</child>
|
235
|
-
<child>
|
236
|
-
<object class="GtkHButtonBox" id="hbuttonbox2">
|
237
|
-
<property name="visible">True</property>
|
238
|
-
<property name="can_focus">False</property>
|
239
|
-
<property name="spacing">5</property>
|
240
|
-
<property name="layout_style">start</property>
|
241
|
-
<child>
|
242
|
-
<object class="GtkButton" id="btnPlus">
|
243
|
-
<property name="label" translatable="yes">+</property>
|
244
|
-
<property name="visible">True</property>
|
245
|
-
<property name="can_focus">True</property>
|
246
|
-
<property name="receives_default">True</property>
|
247
|
-
<property name="use_action_appearance">False</property>
|
248
|
-
<signal name="clicked" handler="on_btnPlus_clicked" swapped="no"/>
|
249
|
-
</object>
|
250
243
|
<packing>
|
251
|
-
<property name="expand">
|
252
|
-
<property name="fill">
|
244
|
+
<property name="expand">True</property>
|
245
|
+
<property name="fill">True</property>
|
253
246
|
<property name="position">0</property>
|
254
247
|
</packing>
|
255
248
|
</child>
|
256
249
|
<child>
|
257
|
-
<object class="
|
258
|
-
<property name="label" translatable="yes">-</property>
|
250
|
+
<object class="GtkHBox" id="hbox2">
|
259
251
|
<property name="visible">True</property>
|
260
|
-
<property name="can_focus">
|
261
|
-
<property name="
|
262
|
-
<
|
263
|
-
|
252
|
+
<property name="can_focus">False</property>
|
253
|
+
<property name="spacing">4</property>
|
254
|
+
<child>
|
255
|
+
<object class="GtkAlignment" id="alignment5">
|
256
|
+
<property name="visible">True</property>
|
257
|
+
<property name="can_focus">False</property>
|
258
|
+
<property name="left_padding">11</property>
|
259
|
+
<child>
|
260
|
+
<object class="GtkHButtonBox" id="hbuttonbox2">
|
261
|
+
<property name="visible">True</property>
|
262
|
+
<property name="can_focus">False</property>
|
263
|
+
<property name="spacing">5</property>
|
264
|
+
<property name="layout_style">start</property>
|
265
|
+
<child>
|
266
|
+
<object class="GtkButton" id="btnPlus">
|
267
|
+
<property name="label" translatable="yes">+</property>
|
268
|
+
<property name="visible">True</property>
|
269
|
+
<property name="can_focus">True</property>
|
270
|
+
<property name="receives_default">True</property>
|
271
|
+
<property name="use_action_appearance">False</property>
|
272
|
+
<signal name="clicked" handler="on_btnPlus_clicked" swapped="no"/>
|
273
|
+
</object>
|
274
|
+
<packing>
|
275
|
+
<property name="expand">False</property>
|
276
|
+
<property name="fill">False</property>
|
277
|
+
<property name="position">0</property>
|
278
|
+
</packing>
|
279
|
+
</child>
|
280
|
+
<child>
|
281
|
+
<object class="GtkButton" id="btnMinus">
|
282
|
+
<property name="label" translatable="yes">-</property>
|
283
|
+
<property name="visible">True</property>
|
284
|
+
<property name="can_focus">True</property>
|
285
|
+
<property name="receives_default">True</property>
|
286
|
+
<property name="use_action_appearance">False</property>
|
287
|
+
<signal name="clicked" handler="on_btnMinus_clicked" swapped="no"/>
|
288
|
+
</object>
|
289
|
+
<packing>
|
290
|
+
<property name="expand">False</property>
|
291
|
+
<property name="fill">False</property>
|
292
|
+
<property name="position">1</property>
|
293
|
+
</packing>
|
294
|
+
</child>
|
295
|
+
</object>
|
296
|
+
</child>
|
297
|
+
</object>
|
298
|
+
<packing>
|
299
|
+
<property name="expand">True</property>
|
300
|
+
<property name="fill">True</property>
|
301
|
+
<property name="position">0</property>
|
302
|
+
</packing>
|
303
|
+
</child>
|
304
|
+
<child>
|
305
|
+
<object class="GtkHButtonBox" id="hbuttonbox1">
|
306
|
+
<property name="visible">True</property>
|
307
|
+
<property name="can_focus">False</property>
|
308
|
+
<property name="layout_style">end</property>
|
309
|
+
<child>
|
310
|
+
<object class="GtkButton" id="btnSync">
|
311
|
+
<property name="label" translatable="yes">Prepare _sync</property>
|
312
|
+
<property name="visible">True</property>
|
313
|
+
<property name="can_focus">True</property>
|
314
|
+
<property name="receives_default">True</property>
|
315
|
+
<property name="use_action_appearance">False</property>
|
316
|
+
<property name="use_underline">True</property>
|
317
|
+
<signal name="clicked" handler="on_btnSync_clicked" swapped="no"/>
|
318
|
+
</object>
|
319
|
+
<packing>
|
320
|
+
<property name="expand">False</property>
|
321
|
+
<property name="fill">False</property>
|
322
|
+
<property name="position">0</property>
|
323
|
+
</packing>
|
324
|
+
</child>
|
325
|
+
</object>
|
326
|
+
<packing>
|
327
|
+
<property name="expand">True</property>
|
328
|
+
<property name="fill">True</property>
|
329
|
+
<property name="position">1</property>
|
330
|
+
</packing>
|
331
|
+
</child>
|
264
332
|
</object>
|
265
333
|
<packing>
|
266
334
|
<property name="expand">False</property>
|
267
|
-
<property name="fill">
|
335
|
+
<property name="fill">True</property>
|
268
336
|
<property name="position">1</property>
|
269
337
|
</packing>
|
270
338
|
</child>
|
271
339
|
</object>
|
272
|
-
<packing>
|
273
|
-
<property name="expand">False</property>
|
274
|
-
<property name="fill">True</property>
|
275
|
-
<property name="position">1</property>
|
276
|
-
</packing>
|
277
|
-
</child>
|
278
|
-
<child>
|
279
|
-
<object class="GtkHButtonBox" id="hbuttonbox1">
|
280
|
-
<property name="visible">True</property>
|
281
|
-
<property name="can_focus">False</property>
|
282
|
-
<property name="layout_style">end</property>
|
283
|
-
<child>
|
284
|
-
<object class="GtkButton" id="btnSync">
|
285
|
-
<property name="label" translatable="yes">Prepare _sync</property>
|
286
|
-
<property name="visible">True</property>
|
287
|
-
<property name="can_focus">True</property>
|
288
|
-
<property name="receives_default">True</property>
|
289
|
-
<property name="use_action_appearance">False</property>
|
290
|
-
<property name="use_underline">True</property>
|
291
|
-
<signal name="clicked" handler="on_btnSync_clicked" swapped="no"/>
|
292
|
-
</object>
|
293
|
-
<packing>
|
294
|
-
<property name="expand">False</property>
|
295
|
-
<property name="fill">False</property>
|
296
|
-
<property name="position">0</property>
|
297
|
-
</packing>
|
298
|
-
</child>
|
299
|
-
</object>
|
300
|
-
<packing>
|
301
|
-
<property name="expand">False</property>
|
302
|
-
<property name="fill">True</property>
|
303
|
-
<property name="position">2</property>
|
304
|
-
</packing>
|
305
340
|
</child>
|
306
341
|
</object>
|
307
342
|
</child>
|
@@ -334,6 +369,7 @@
|
|
334
369
|
<property name="visible">True</property>
|
335
370
|
<property name="can_focus">False</property>
|
336
371
|
<property name="left_padding">12</property>
|
372
|
+
<property name="right_padding">10</property>
|
337
373
|
<child>
|
338
374
|
<object class="GtkVBox" id="vbox4">
|
339
375
|
<property name="visible">True</property>
|
data/gui/trayicon.rb
CHANGED
@@ -90,13 +90,13 @@ class Openall_time_applet::Gui::Trayicon
|
|
90
90
|
label = timelog.descr_short
|
91
91
|
|
92
92
|
#If this is the active timelog, make the label bold, by getting the label-child and using HTML-markup on it.
|
93
|
-
if @args[:oata].timelog_active and @args[:oata].timelog_active.
|
94
|
-
mi = Gtk::ImageMenuItem.new(Gtk::Stock::
|
93
|
+
if @args[:oata].timelog_active and @args[:oata].timelog_active[:task_id] == timelog[:task_id] and @args[:oata].timelog_active[:descr] == timelog[:descr]
|
94
|
+
mi = Gtk::ImageMenuItem.new(Gtk::Stock::MEDIA_STOP)
|
95
95
|
|
96
96
|
secs = Time.now.to_i - @args[:oata].timelog_active_time.to_i + timelog.time_total
|
97
97
|
mins = (secs.to_f / 60.0).round(0)
|
98
98
|
|
99
|
-
mi.children[0].markup = "<b>#{Knj::Web.html(label)}
|
99
|
+
mi.children[0].markup = "<b>#{_("Stop")}:</b> #{Knj::Web.html(label)}"
|
100
100
|
mi.signal_connect("activate", &self.method(:on_stopTracking_activate))
|
101
101
|
else
|
102
102
|
mi = Gtk::MenuItem.new(label)
|
data/gui/win_main.rb
CHANGED
@@ -47,58 +47,62 @@ class Openall_time_applet::Gui::Win_main
|
|
47
47
|
init_data = @gui["tvTimelogs"].init([
|
48
48
|
_("ID"),
|
49
49
|
{
|
50
|
-
:title => _("
|
50
|
+
:title => _("Timestamp"),
|
51
51
|
:type => :string,
|
52
|
-
:markup => true
|
52
|
+
:markup => true,
|
53
|
+
:expand => false
|
53
54
|
},
|
54
55
|
{
|
55
|
-
:title => _("
|
56
|
+
:title => _("Time"),
|
56
57
|
:type => :string,
|
57
|
-
:markup => true
|
58
|
+
:markup => true,
|
59
|
+
:expand => false
|
58
60
|
},
|
59
61
|
{
|
60
|
-
:title => _("
|
62
|
+
:title => _("Description"),
|
61
63
|
:type => :string,
|
62
|
-
:markup => true
|
64
|
+
:markup => true,
|
65
|
+
:expand => true
|
63
66
|
},
|
64
67
|
{
|
65
|
-
:title => _("
|
68
|
+
:title => _("T-time"),
|
66
69
|
:type => :string,
|
67
|
-
:markup => true
|
70
|
+
:markup => true,
|
71
|
+
:expand => false
|
68
72
|
},
|
69
73
|
{
|
70
|
-
:title => _("
|
74
|
+
:title => _("T-km"),
|
71
75
|
:type => :string,
|
72
76
|
:markup => true
|
73
77
|
},
|
74
78
|
{
|
75
|
-
:title => _("Descr."),
|
79
|
+
:title => _("T-Descr."),
|
76
80
|
:type => :string,
|
77
|
-
:markup => true
|
81
|
+
:markup => true,
|
82
|
+
:expand => true
|
78
83
|
},
|
79
84
|
{
|
80
|
-
:title => _("
|
85
|
+
:title => _("Cost"),
|
81
86
|
:type => :string,
|
82
87
|
:markup => true
|
83
88
|
},
|
84
89
|
{
|
85
90
|
:title => _("Fixed"),
|
86
|
-
:type => :toggle
|
87
|
-
|
88
|
-
{
|
89
|
-
:title => _("Int. work"),
|
90
|
-
:type => :toggle
|
91
|
+
:type => :toggle,
|
92
|
+
:expand => false
|
91
93
|
},
|
92
94
|
{
|
93
|
-
:title => _("
|
94
|
-
:type => :toggle
|
95
|
+
:title => _("Internal"),
|
96
|
+
:type => :toggle,
|
97
|
+
:expand => false
|
95
98
|
},
|
96
99
|
{
|
97
100
|
:title => _("Task"),
|
98
101
|
:type => :combo,
|
99
102
|
:model => task_ls,
|
100
103
|
:has_entry => false,
|
101
|
-
:markup => true
|
104
|
+
:markup => true,
|
105
|
+
:expand => true
|
102
106
|
}
|
103
107
|
])
|
104
108
|
|
@@ -124,17 +128,28 @@ class Openall_time_applet::Gui::Win_main
|
|
124
128
|
@tv_editting = nil
|
125
129
|
},
|
126
130
|
:cols => {
|
127
|
-
1 =>
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
+
1 => {
|
132
|
+
:col => :timestamp,
|
133
|
+
:value_callback => self.method(:tv_editable_timestamp_callback),
|
134
|
+
:value_set_callback => self.method(:tv_editable_timestamp_set_callback)
|
135
|
+
},
|
136
|
+
2 => {
|
137
|
+
:col => :time,
|
138
|
+
:value_callback => proc{ |data| Knj::Strings.human_time_str_to_secs(data[:value]) },
|
139
|
+
:value_set_callback => proc{ |data| Knj::Strings.secs_to_human_time_str(data[:value], :secs => false) }
|
140
|
+
},
|
141
|
+
3 => :descr,
|
142
|
+
4 => {
|
143
|
+
:col => :time_transport,
|
144
|
+
:value_callback => proc{ |data| Knj::Strings.human_time_str_to_secs(data[:value]) },
|
145
|
+
:value_set_callback => proc{ |data| Knj::Strings.secs_to_human_time_str(data[:value], :secs => false) }
|
146
|
+
},
|
131
147
|
5 => {:col => :transportlength, :type => :int},
|
132
148
|
6 => {:col => :transportdescription},
|
133
149
|
7 => {:col => :transportcosts, :type => :human_number, :decimals => 2},
|
134
150
|
8 => {:col => :travelfixed},
|
135
151
|
9 => {:col => :workinternal},
|
136
|
-
10 => {
|
137
|
-
11 => {
|
152
|
+
10 => {
|
138
153
|
:col => :task_id,
|
139
154
|
:value_callback => lambda{|data|
|
140
155
|
task = @args[:oata].ob.get_by(:Task, {"title" => data[:value]})
|
@@ -208,30 +223,39 @@ class Openall_time_applet::Gui::Win_main
|
|
208
223
|
#Initialize timelog treeview.
|
209
224
|
init_data = Knj::Gtk2::Tv.init(@gui["tvTimelogsPrepareTransfer"], [
|
210
225
|
_("ID"),
|
211
|
-
|
226
|
+
{
|
227
|
+
:title => _("Description"),
|
228
|
+
:type => :string,
|
229
|
+
:expand => true
|
230
|
+
},
|
212
231
|
_("Timestamp"),
|
213
232
|
_("Time"),
|
214
|
-
_("
|
215
|
-
_("
|
216
|
-
_("Transport descr."),
|
217
|
-
_("Transport costs"),
|
233
|
+
_("T-time"),
|
234
|
+
_("T-km"),
|
218
235
|
{
|
219
|
-
:title => _("
|
236
|
+
:title => _("T-Descr."),
|
237
|
+
:type => :string,
|
238
|
+
:expand => true
|
239
|
+
},
|
240
|
+
_("Cost"),
|
241
|
+
{
|
242
|
+
:title => _("Fixed"),
|
220
243
|
:type => :toggle
|
221
244
|
},
|
222
245
|
{
|
223
|
-
:title => _("
|
246
|
+
:title => _("Internal"),
|
224
247
|
:type => :toggle
|
225
248
|
},
|
226
249
|
{
|
227
|
-
:title => _("
|
250
|
+
:title => _("Skip"),
|
228
251
|
:type => :toggle
|
229
252
|
},
|
230
253
|
{
|
231
254
|
:title => _("Task"),
|
232
255
|
:type => :combo,
|
233
256
|
:model => task_ls,
|
234
|
-
:has_entry => false
|
257
|
+
:has_entry => false,
|
258
|
+
:expand => true
|
235
259
|
},
|
236
260
|
_("Sync time")
|
237
261
|
])
|
@@ -246,15 +270,27 @@ class Openall_time_applet::Gui::Win_main
|
|
246
270
|
:change_after => proc{ @dont_reload_sync = false; self.update_sync_totals },
|
247
271
|
:cols => {
|
248
272
|
1 => :descr,
|
249
|
-
2 => {
|
250
|
-
|
251
|
-
|
273
|
+
2 => {
|
274
|
+
:col => :timestamp,
|
275
|
+
:value_callback => self.method(:tv_editable_timestamp_callback),
|
276
|
+
:value_set_callback => self.method(:tv_editable_timestamp_set_callback)
|
277
|
+
},
|
278
|
+
3 => {
|
279
|
+
:col => :time,
|
280
|
+
:value_callback => proc{ |data| Knj::Strings.human_time_str_to_secs(data[:value]) },
|
281
|
+
:value_set_callback => proc{ |data| Knj::Strings.secs_to_human_time_str(data[:value], :secs => false) }
|
282
|
+
},
|
283
|
+
4 => {
|
284
|
+
:col => :time_transport,
|
285
|
+
:value_callback => proc{ |data| Knj::Strings.human_time_str_to_secs(data[:value]) },
|
286
|
+
:value_set_callback => proc{ |data| Knj::Strings.secs_to_human_time_str(data[:value], :secs => false) }
|
287
|
+
},
|
252
288
|
5 => {:col => :transportlength, :type => :int},
|
253
289
|
6 => {:col => :transportdescription},
|
254
290
|
7 => {:col => :transportcosts, :type => :human_number, :decimals => 2},
|
255
291
|
8 => {:col => :travelfixed},
|
256
292
|
9 => {:col => :workinternal},
|
257
|
-
10 => {:col => :sync_need},
|
293
|
+
10 => {:col => :sync_need, :type => :toggle_rev},
|
258
294
|
11 => {
|
259
295
|
:col => :task_id,
|
260
296
|
:value_callback => lambda{ |data|
|
@@ -268,7 +304,11 @@ class Openall_time_applet::Gui::Win_main
|
|
268
304
|
},
|
269
305
|
:value_set_callback => proc{ |data| data[:model].task_name }
|
270
306
|
},
|
271
|
-
12 => {
|
307
|
+
12 => {
|
308
|
+
:col => :time_sync,
|
309
|
+
:value_callback => proc{ |data| Knj::Strings.human_time_str_to_secs(data[:value]) },
|
310
|
+
:value_set_callback => proc{ |data| Knj::Strings.secs_to_human_time_str(data[:value], :secs => false) }
|
311
|
+
}
|
272
312
|
}
|
273
313
|
)
|
274
314
|
@gui["tvTimelogsPrepareTransfer"].columns[0].visible = false
|
@@ -284,6 +324,33 @@ class Openall_time_applet::Gui::Win_main
|
|
284
324
|
@gui["window"].resize(width, 1)
|
285
325
|
end
|
286
326
|
|
327
|
+
def tv_editable_timestamp_callback(data)
|
328
|
+
if match = data[:value].match(/^\s*(\d+)\s*:\s*(\d+)\s*$/)
|
329
|
+
date = Datet.new
|
330
|
+
date.hour = match[1].to_i
|
331
|
+
date.min = match[2].to_i
|
332
|
+
return date
|
333
|
+
elsif match = data[:value].match(/^\s*(\d+)\s*\/\s*(\d+)\s*$/)
|
334
|
+
date = data[:model].timestamp
|
335
|
+
date.day = match[1].to_i
|
336
|
+
date.month = match[2].to_i
|
337
|
+
|
338
|
+
return date
|
339
|
+
else
|
340
|
+
return Datet.in(data[:value])
|
341
|
+
end
|
342
|
+
end
|
343
|
+
|
344
|
+
def tv_editable_timestamp_set_callback(data)
|
345
|
+
date = Datet.in(data[:value])
|
346
|
+
|
347
|
+
if date.strftime("%Y %m %d") == Time.now.strftime("%Y %m %d")
|
348
|
+
return date.strftime("%H:%M")
|
349
|
+
else
|
350
|
+
return date.strftime("%d/%m")
|
351
|
+
end
|
352
|
+
end
|
353
|
+
|
287
354
|
#Reloads the suggestions for the description-entry-completion.
|
288
355
|
def reload_descr_completion
|
289
356
|
added = {}
|
@@ -306,8 +373,9 @@ class Openall_time_applet::Gui::Win_main
|
|
306
373
|
return nil if @dont_reload_sync or @gui["tvTimelogsPrepareTransfer"].destroyed?
|
307
374
|
@gui["tvTimelogsPrepareTransfer"].model.clear
|
308
375
|
@timelogs_sync_count = 0
|
376
|
+
tnow_str = Time.now.strftime("%Y %m %d")
|
309
377
|
|
310
|
-
@args[:oata].ob.list(:Timelog, "
|
378
|
+
@args[:oata].ob.list(:Timelog, "task_id_not" => ["", 0], "orderby" => "timestamp") do |timelog|
|
311
379
|
#Read time and transport from timelog.
|
312
380
|
time = timelog[:time].to_i
|
313
381
|
transport = timelog[:time_transport].to_i
|
@@ -329,10 +397,18 @@ class Openall_time_applet::Gui::Win_main
|
|
329
397
|
#Set sync-time on timelog.
|
330
398
|
timelog[:time_sync] = count_rounded_time
|
331
399
|
|
400
|
+
tstamp = timelog.timestamp
|
401
|
+
|
402
|
+
if tstamp.strftime("%Y %m %d") == tnow_str
|
403
|
+
tstamp_str = tstamp.strftime("%H:%M")
|
404
|
+
else
|
405
|
+
tstamp_str = tstamp.strftime("%d/%m")
|
406
|
+
end
|
407
|
+
|
332
408
|
Knj::Gtk2::Tv.append(@gui["tvTimelogsPrepareTransfer"], [
|
333
409
|
timelog.id,
|
334
410
|
timelog[:descr],
|
335
|
-
|
411
|
+
tstamp_str,
|
336
412
|
timelog.time_as_human,
|
337
413
|
timelog.time_transport_as_human,
|
338
414
|
Knj::Locales.number_out(timelog[:transportlength], 0),
|
@@ -340,9 +416,9 @@ class Openall_time_applet::Gui::Win_main
|
|
340
416
|
Knj::Locales.number_out(timelog[:transportcosts], 2),
|
341
417
|
Knj::Strings.yn_str(timelog[:travelfixed], true, false),
|
342
418
|
Knj::Strings.yn_str(timelog[:workinternal], true, false),
|
343
|
-
Knj::Strings.yn_str(timelog[:sync_need],
|
419
|
+
Knj::Strings.yn_str(timelog[:sync_need], false, true),
|
344
420
|
timelog.task_name,
|
345
|
-
Knj::Strings.secs_to_human_time_str(count_rounded_time)
|
421
|
+
Knj::Strings.secs_to_human_time_str(count_rounded_time, :secs => false)
|
346
422
|
])
|
347
423
|
@timelogs_sync_count += 1
|
348
424
|
end
|
@@ -375,7 +451,7 @@ class Openall_time_applet::Gui::Win_main
|
|
375
451
|
end
|
376
452
|
end
|
377
453
|
|
378
|
-
@gui["labTotal"].markup = "<b>#{_("Total hours:")}</b> #{Knj::Strings.secs_to_human_time_str(total_secs)}"
|
454
|
+
@gui["labTotal"].markup = "<b>#{_("Total hours:")}</b> #{Knj::Strings.secs_to_human_time_str(total_secs, :secs => false)}"
|
379
455
|
end
|
380
456
|
|
381
457
|
def on_btnCancelPrepareTransfer_clicked
|
@@ -409,6 +485,8 @@ class Openall_time_applet::Gui::Win_main
|
|
409
485
|
self.reload_descr_completion
|
410
486
|
|
411
487
|
return nil if @dont_reload or @gui["tvTimelogs"].destroyed?
|
488
|
+
tnow_str = Time.now.strftime("%Y %m %d")
|
489
|
+
|
412
490
|
@gui["tvTimelogs"].model.clear
|
413
491
|
@args[:oata].ob.list(:Timelog, "orderby" => ["task_id", "descr", "timestamp"]) do |timelog|
|
414
492
|
begin
|
@@ -417,6 +495,14 @@ class Openall_time_applet::Gui::Win_main
|
|
417
495
|
tstamp_str = "[#{_("error")}: #{e.message}"
|
418
496
|
end
|
419
497
|
|
498
|
+
tstamp = timelog.timestamp
|
499
|
+
|
500
|
+
if tstamp.strftime("%Y %m %d") == tnow_str
|
501
|
+
tstamp_str = tstamp.strftime("%H:%M")
|
502
|
+
else
|
503
|
+
tstamp_str = tstamp.strftime("%d/%m")
|
504
|
+
end
|
505
|
+
|
420
506
|
@gui["tvTimelogs"].append([
|
421
507
|
timelog.id,
|
422
508
|
Knj::Web.html(timelog[:descr]),
|
@@ -428,7 +514,6 @@ class Openall_time_applet::Gui::Win_main
|
|
428
514
|
Knj::Locales.number_out(timelog[:transportcosts], 2),
|
429
515
|
Knj::Strings.yn_str(timelog[:travelfixed], true, false),
|
430
516
|
Knj::Strings.yn_str(timelog[:workinternal], true, false),
|
431
|
-
Knj::Strings.yn_str(timelog[:sync_need], true, false),
|
432
517
|
timelog.task_name
|
433
518
|
])
|
434
519
|
end
|
@@ -492,8 +577,8 @@ class Openall_time_applet::Gui::Win_main
|
|
492
577
|
#This method handles the "Timelog info"-frame. Hides, shows and updates the info in it.
|
493
578
|
def timelog_info_trigger
|
494
579
|
if tlog = @args[:oata].timelog_active
|
495
|
-
time_tracked =
|
496
|
-
@gui["btnSwitch"].label = time_tracked
|
580
|
+
time_tracked = @args[:oata].timelog_active_time_tracked + tlog.time_total
|
581
|
+
@gui["btnSwitch"].label = "#{_("Stop")} #{Knj::Strings.secs_to_human_short_time(time_tracked)}"
|
497
582
|
end
|
498
583
|
end
|
499
584
|
|
@@ -539,7 +624,6 @@ class Openall_time_applet::Gui::Win_main
|
|
539
624
|
|
540
625
|
if tlog_act
|
541
626
|
but.image = Gtk::Image.new(Gtk::Stock::MEDIA_STOP, Gtk::IconSize::BUTTON)
|
542
|
-
but.label = _("Stop")
|
543
627
|
|
544
628
|
@gui["txtDescr"].text = tlog_act[:descr]
|
545
629
|
|
@@ -583,7 +667,7 @@ class Openall_time_applet::Gui::Win_main
|
|
583
667
|
#Update time tracked.
|
584
668
|
if timelog_id == act_timelog_id
|
585
669
|
secs = act_timelog.time_total + @args[:oata].timelog_active_time_tracked
|
586
|
-
iter[3] = "<b>#{Knj::Strings.secs_to_human_time_str(secs)}</b>"
|
670
|
+
iter[3] = "<b>#{Knj::Strings.secs_to_human_time_str(secs, :secs => false)}</b>"
|
587
671
|
bold = true
|
588
672
|
end
|
589
673
|
|
@@ -27,20 +27,20 @@ class Openall_time_applet::Gui::Win_worktime_overview
|
|
27
27
|
|
28
28
|
@gui["labWeek"].label = sprintf(_("Week %s"), date.time.strftime("%W"))
|
29
29
|
|
30
|
-
@args[:oata].ob.list(:Worktime,
|
30
|
+
@args[:oata].ob.list(:Worktime, "timestamp_week" => date) do |wt|
|
31
31
|
task = wt.task
|
32
32
|
date = wt.timestamp
|
33
33
|
|
34
34
|
stats[:task_total][task.id] = {:secs => 0} if !stats[:task_total].key?(task.id)
|
35
35
|
stats[:task_total][task.id][:secs] += wt[:worktime].to_i
|
36
36
|
|
37
|
-
stats[:days_total][date.
|
38
|
-
stats[:days_total][date.
|
39
|
-
stats[:days_total][date.
|
37
|
+
stats[:days_total][date.day] = {:secs => 0, :tasks => {}} if !stats[:days_total].key?(date.day)
|
38
|
+
stats[:days_total][date.day][:secs] += wt[:worktime].to_i
|
39
|
+
stats[:days_total][date.day][:tasks][task.id] = task
|
40
40
|
|
41
41
|
#Generate first worktime of that date.
|
42
|
-
if !stats[:days_total][date.
|
43
|
-
stats[:days_total][date.
|
42
|
+
if !stats[:days_total][date.day].key?(:first_time) or stats[:days_total][date.day][:first_time].to_i > wt.timestamp.to_i
|
43
|
+
stats[:days_total][date.day][:first_time] = wt.timestamp
|
44
44
|
end
|
45
45
|
|
46
46
|
stats[:week_total] += wt[:worktime].to_i
|
data/models/timelog.rb
CHANGED
@@ -22,6 +22,7 @@ class Openall_time_applet::Models::Timelog < Knj::Datarow
|
|
22
22
|
d.data[:time] = 0 if d.data[:time].to_s.strip.length <= 0
|
23
23
|
d.data[:time_transport] = 0 if d.data[:time_transport].to_s.strip.length <= 0
|
24
24
|
d.data[:parent_timelog_id] = 0 if !d.data.key?(:parent_timelog_id)
|
25
|
+
d.data[:sync_need] = 1 if !d.data.key?(:sync_need)
|
25
26
|
end
|
26
27
|
|
27
28
|
#Pushes timelogs and time to OpenAll.
|
@@ -102,12 +103,12 @@ class Openall_time_applet::Models::Timelog < Knj::Datarow
|
|
102
103
|
|
103
104
|
#Returns the time as a human readable format.
|
104
105
|
def time_as_human
|
105
|
-
return Knj::Strings.secs_to_human_time_str(self.time_total)
|
106
|
+
return Knj::Strings.secs_to_human_time_str(self.time_total, :secs => false)
|
106
107
|
end
|
107
108
|
|
108
109
|
#Returns the transport-time as a human readable format.
|
109
110
|
def time_transport_as_human
|
110
|
-
return Knj::Strings.secs_to_human_time_str(self.time_total(:transport => true))
|
111
|
+
return Knj::Strings.secs_to_human_time_str(self.time_total(:transport => true), :secs => false)
|
111
112
|
end
|
112
113
|
|
113
114
|
def delete_empty_children
|
data/openall_time_applet.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{openall_time_applet}
|
8
|
-
s.version = "0.0.
|
8
|
+
s.version = "0.0.30"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Kasper Johansen"]
|
12
|
-
s.date = %q{2012-08-
|
12
|
+
s.date = %q{2012-08-07}
|
13
13
|
s.description = %q{Off-line time-tracking for OpenAll with syncing when online.}
|
14
14
|
s.email = %q{k@spernj.org}
|
15
15
|
s.executables = ["OpenAll Timelogging", "openall_time_applet.rb"]
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: openall_time_applet
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 0.0.
|
5
|
+
version: 0.0.30
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Kasper Johansen
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2012-08-
|
13
|
+
date: 2012-08-07 00:00:00 +02:00
|
14
14
|
default_executable:
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
@@ -209,7 +209,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
209
209
|
requirements:
|
210
210
|
- - ">="
|
211
211
|
- !ruby/object:Gem::Version
|
212
|
-
hash:
|
212
|
+
hash: 2835290429234012908
|
213
213
|
segments:
|
214
214
|
- 0
|
215
215
|
version: "0"
|