openall_time_applet 0.0.29 → 0.0.30
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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"
|