openall_time_applet 0.0.7 → 0.0.10
Sign up to get free protection for your applications and to get access to all the features.
- data/VERSION +1 -1
- data/classes/connection.rb +1 -1
- data/conf/db_schema.rb +7 -0
- data/gfx/{icon_time.png → icon_time_black.png} +0 -0
- data/gfx/icon_time_green_casalogic.png +0 -0
- data/gfx/icon_time_white.png +0 -0
- data/glade/win_overview.glade +2 -1
- data/glade/win_timelog_edit.glade +204 -22
- data/gui/trayicon.rb +39 -8
- data/gui/win_overview.rb +123 -2
- data/gui/win_preferences.rb +1 -1
- data/gui/win_timelog_edit.rb +60 -2
- data/gui/win_worktime_overview.rb +3 -0
- data/lib/openall_time_applet.rb +50 -22
- data/locales/da_DK/LC_MESSAGES/default.mo +0 -0
- data/locales/da_DK/LC_MESSAGES/default.po +104 -46
- data/models/timelog.rb +18 -8
- data/openall_time_applet.gemspec +5 -3
- metadata +6 -4
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.10
|
data/classes/connection.rb
CHANGED
data/conf/db_schema.rb
CHANGED
@@ -33,8 +33,15 @@ Openall_time_applet::DB_SCHEMA = {
|
|
33
33
|
"columns" => [
|
34
34
|
{"name" => "id", "type" => "int", "autoincr" => true, "primarykey" => true},
|
35
35
|
{"name" => "task_id", "type" => "int"},
|
36
|
+
{"name" => "timestamp", "type" => "datetime"},
|
36
37
|
{"name" => "time", "type" => "int"},
|
38
|
+
{"name" => "timetype", "type" => "enum", "maxlength" => "'normal','overtime150','overtime200'", "default" => "normal"},
|
37
39
|
{"name" => "time_transport", "type" => "int"},
|
40
|
+
{"name" => "transportlength", "type" => "int"},
|
41
|
+
{"name" => "transportdescription", "type" => "text"},
|
42
|
+
{"name" => "transportcosts", "type" => "int"},
|
43
|
+
{"name" => "travelfixed", "type" => "enum", "maxlength" => "'0','1'", "default" => 0},
|
44
|
+
{"name" => "workinternal", "type" => "enum", "maxlength" => "'0','1'", "default" => 0},
|
38
45
|
{"name" => "descr", "type" => "text"},
|
39
46
|
{"name" => "sync_need", "type" => "enum", "maxlength" => "'0','1'", "default" => 0},
|
40
47
|
{"name" => "sync_last", "type" => "datetime"}
|
File without changes
|
Binary file
|
Binary file
|
data/glade/win_overview.glade
CHANGED
@@ -2,9 +2,10 @@
|
|
2
2
|
<interface>
|
3
3
|
<requires lib="gtk+" version="2.24"/>
|
4
4
|
<!-- interface-naming-policy project-wide -->
|
5
|
+
<object class="GtkListStore" id="liststore1"/>
|
5
6
|
<object class="GtkWindow" id="window">
|
6
7
|
<property name="can_focus">False</property>
|
7
|
-
<property name="title" translatable="yes">
|
8
|
+
<property name="title" translatable="yes">Timelog list</property>
|
8
9
|
<property name="window_position">center</property>
|
9
10
|
<property name="default_width">640</property>
|
10
11
|
<property name="default_height">480</property>
|
@@ -26,7 +26,7 @@
|
|
26
26
|
<object class="GtkTable" id="table1">
|
27
27
|
<property name="visible">True</property>
|
28
28
|
<property name="can_focus">False</property>
|
29
|
-
<property name="n_rows">
|
29
|
+
<property name="n_rows">13</property>
|
30
30
|
<property name="n_columns">2</property>
|
31
31
|
<property name="column_spacing">3</property>
|
32
32
|
<property name="row_spacing">3</property>
|
@@ -56,21 +56,6 @@
|
|
56
56
|
<property name="y_options">GTK_FILL</property>
|
57
57
|
</packing>
|
58
58
|
</child>
|
59
|
-
<child>
|
60
|
-
<object class="GtkEntry" id="txtDescr">
|
61
|
-
<property name="visible">True</property>
|
62
|
-
<property name="can_focus">True</property>
|
63
|
-
<property name="invisible_char">•</property>
|
64
|
-
<property name="primary_icon_activatable">False</property>
|
65
|
-
<property name="secondary_icon_activatable">False</property>
|
66
|
-
<property name="primary_icon_sensitive">True</property>
|
67
|
-
<property name="secondary_icon_sensitive">True</property>
|
68
|
-
</object>
|
69
|
-
<packing>
|
70
|
-
<property name="left_attach">1</property>
|
71
|
-
<property name="right_attach">2</property>
|
72
|
-
</packing>
|
73
|
-
</child>
|
74
59
|
<child>
|
75
60
|
<object class="GtkEntry" id="txtTime">
|
76
61
|
<property name="visible">True</property>
|
@@ -127,8 +112,8 @@
|
|
127
112
|
<property name="label" translatable="yes">Task</property>
|
128
113
|
</object>
|
129
114
|
<packing>
|
130
|
-
<property name="top_attach">
|
131
|
-
<property name="bottom_attach">
|
115
|
+
<property name="top_attach">10</property>
|
116
|
+
<property name="bottom_attach">11</property>
|
132
117
|
<property name="x_options">GTK_FILL</property>
|
133
118
|
<property name="y_options">GTK_FILL</property>
|
134
119
|
</packing>
|
@@ -141,8 +126,8 @@
|
|
141
126
|
<packing>
|
142
127
|
<property name="left_attach">1</property>
|
143
128
|
<property name="right_attach">2</property>
|
144
|
-
<property name="top_attach">
|
145
|
-
<property name="bottom_attach">
|
129
|
+
<property name="top_attach">10</property>
|
130
|
+
<property name="bottom_attach">11</property>
|
146
131
|
</packing>
|
147
132
|
</child>
|
148
133
|
<child>
|
@@ -156,8 +141,8 @@
|
|
156
141
|
</object>
|
157
142
|
<packing>
|
158
143
|
<property name="right_attach">2</property>
|
159
|
-
<property name="top_attach">
|
160
|
-
<property name="bottom_attach">
|
144
|
+
<property name="top_attach">11</property>
|
145
|
+
<property name="bottom_attach">12</property>
|
161
146
|
<property name="x_options">GTK_FILL</property>
|
162
147
|
<property name="y_options">GTK_FILL</property>
|
163
148
|
</packing>
|
@@ -172,11 +157,208 @@
|
|
172
157
|
<property name="draw_indicator">True</property>
|
173
158
|
</object>
|
174
159
|
<packing>
|
160
|
+
<property name="right_attach">2</property>
|
161
|
+
<property name="top_attach">12</property>
|
162
|
+
<property name="bottom_attach">13</property>
|
163
|
+
</packing>
|
164
|
+
</child>
|
165
|
+
<child>
|
166
|
+
<object class="GtkEntry" id="txtDescr">
|
167
|
+
<property name="visible">True</property>
|
168
|
+
<property name="can_focus">True</property>
|
169
|
+
<property name="invisible_char">•</property>
|
170
|
+
<property name="primary_icon_activatable">False</property>
|
171
|
+
<property name="secondary_icon_activatable">False</property>
|
172
|
+
<property name="primary_icon_sensitive">True</property>
|
173
|
+
<property name="secondary_icon_sensitive">True</property>
|
174
|
+
</object>
|
175
|
+
<packing>
|
176
|
+
<property name="left_attach">1</property>
|
177
|
+
<property name="right_attach">2</property>
|
178
|
+
</packing>
|
179
|
+
</child>
|
180
|
+
<child>
|
181
|
+
<object class="GtkLabel" id="label7">
|
182
|
+
<property name="visible">True</property>
|
183
|
+
<property name="can_focus">False</property>
|
184
|
+
<property name="xalign">0</property>
|
185
|
+
<property name="label" translatable="yes">Transport length</property>
|
186
|
+
</object>
|
187
|
+
<packing>
|
188
|
+
<property name="top_attach">3</property>
|
189
|
+
<property name="bottom_attach">4</property>
|
190
|
+
<property name="x_options">GTK_FILL</property>
|
191
|
+
<property name="y_options">GTK_FILL</property>
|
192
|
+
</packing>
|
193
|
+
</child>
|
194
|
+
<child>
|
195
|
+
<object class="GtkLabel" id="label8">
|
196
|
+
<property name="visible">True</property>
|
197
|
+
<property name="can_focus">False</property>
|
198
|
+
<property name="xalign">0</property>
|
199
|
+
<property name="label" translatable="yes">Transport costs</property>
|
200
|
+
</object>
|
201
|
+
<packing>
|
202
|
+
<property name="top_attach">4</property>
|
203
|
+
<property name="bottom_attach">5</property>
|
204
|
+
<property name="x_options">GTK_FILL</property>
|
205
|
+
<property name="y_options">GTK_FILL</property>
|
206
|
+
</packing>
|
207
|
+
</child>
|
208
|
+
<child>
|
209
|
+
<object class="GtkEntry" id="txtTransportLength">
|
210
|
+
<property name="visible">True</property>
|
211
|
+
<property name="can_focus">True</property>
|
212
|
+
<property name="invisible_char">•</property>
|
213
|
+
<property name="primary_icon_activatable">False</property>
|
214
|
+
<property name="secondary_icon_activatable">False</property>
|
215
|
+
<property name="primary_icon_sensitive">True</property>
|
216
|
+
<property name="secondary_icon_sensitive">True</property>
|
217
|
+
</object>
|
218
|
+
<packing>
|
219
|
+
<property name="left_attach">1</property>
|
220
|
+
<property name="right_attach">2</property>
|
221
|
+
<property name="top_attach">3</property>
|
222
|
+
<property name="bottom_attach">4</property>
|
223
|
+
</packing>
|
224
|
+
</child>
|
225
|
+
<child>
|
226
|
+
<object class="GtkEntry" id="txtTransportCosts">
|
227
|
+
<property name="visible">True</property>
|
228
|
+
<property name="can_focus">True</property>
|
229
|
+
<property name="invisible_char">•</property>
|
230
|
+
<property name="primary_icon_activatable">False</property>
|
231
|
+
<property name="secondary_icon_activatable">False</property>
|
232
|
+
<property name="primary_icon_sensitive">True</property>
|
233
|
+
<property name="secondary_icon_sensitive">True</property>
|
234
|
+
</object>
|
235
|
+
<packing>
|
236
|
+
<property name="left_attach">1</property>
|
237
|
+
<property name="right_attach">2</property>
|
238
|
+
<property name="top_attach">4</property>
|
239
|
+
<property name="bottom_attach">5</property>
|
240
|
+
</packing>
|
241
|
+
</child>
|
242
|
+
<child>
|
243
|
+
<object class="GtkLabel" id="label9">
|
244
|
+
<property name="visible">True</property>
|
245
|
+
<property name="can_focus">False</property>
|
246
|
+
<property name="xalign">0</property>
|
247
|
+
<property name="label" translatable="yes">Transport description</property>
|
248
|
+
</object>
|
249
|
+
<packing>
|
250
|
+
<property name="top_attach">5</property>
|
251
|
+
<property name="bottom_attach">6</property>
|
252
|
+
<property name="x_options">GTK_FILL</property>
|
253
|
+
<property name="y_options">GTK_FILL</property>
|
254
|
+
</packing>
|
255
|
+
</child>
|
256
|
+
<child>
|
257
|
+
<object class="GtkEntry" id="txtTransportDescr">
|
258
|
+
<property name="visible">True</property>
|
259
|
+
<property name="can_focus">True</property>
|
260
|
+
<property name="invisible_char">•</property>
|
261
|
+
<property name="primary_icon_activatable">False</property>
|
262
|
+
<property name="secondary_icon_activatable">False</property>
|
263
|
+
<property name="primary_icon_sensitive">True</property>
|
264
|
+
<property name="secondary_icon_sensitive">True</property>
|
265
|
+
</object>
|
266
|
+
<packing>
|
267
|
+
<property name="left_attach">1</property>
|
175
268
|
<property name="right_attach">2</property>
|
176
269
|
<property name="top_attach">5</property>
|
177
270
|
<property name="bottom_attach">6</property>
|
178
271
|
</packing>
|
179
272
|
</child>
|
273
|
+
<child>
|
274
|
+
<object class="GtkCheckButton" id="cbWorkInternal">
|
275
|
+
<property name="label" translatable="yes">Internal work</property>
|
276
|
+
<property name="visible">True</property>
|
277
|
+
<property name="can_focus">True</property>
|
278
|
+
<property name="receives_default">False</property>
|
279
|
+
<property name="use_action_appearance">False</property>
|
280
|
+
<property name="draw_indicator">True</property>
|
281
|
+
</object>
|
282
|
+
<packing>
|
283
|
+
<property name="right_attach">2</property>
|
284
|
+
<property name="top_attach">6</property>
|
285
|
+
<property name="bottom_attach">7</property>
|
286
|
+
</packing>
|
287
|
+
</child>
|
288
|
+
<child>
|
289
|
+
<object class="GtkCheckButton" id="cbTravelFixed">
|
290
|
+
<property name="label" translatable="yes">Fixed travel</property>
|
291
|
+
<property name="visible">True</property>
|
292
|
+
<property name="can_focus">True</property>
|
293
|
+
<property name="receives_default">False</property>
|
294
|
+
<property name="use_action_appearance">False</property>
|
295
|
+
<property name="draw_indicator">True</property>
|
296
|
+
</object>
|
297
|
+
<packing>
|
298
|
+
<property name="right_attach">2</property>
|
299
|
+
<property name="top_attach">7</property>
|
300
|
+
<property name="bottom_attach">8</property>
|
301
|
+
<property name="x_options">GTK_FILL</property>
|
302
|
+
<property name="y_options">GTK_FILL</property>
|
303
|
+
</packing>
|
304
|
+
</child>
|
305
|
+
<child>
|
306
|
+
<object class="GtkLabel" id="label10">
|
307
|
+
<property name="visible">True</property>
|
308
|
+
<property name="can_focus">False</property>
|
309
|
+
<property name="xalign">0</property>
|
310
|
+
<property name="label" translatable="yes">Time type</property>
|
311
|
+
</object>
|
312
|
+
<packing>
|
313
|
+
<property name="top_attach">8</property>
|
314
|
+
<property name="bottom_attach">9</property>
|
315
|
+
<property name="x_options">GTK_FILL</property>
|
316
|
+
<property name="y_options">GTK_FILL</property>
|
317
|
+
</packing>
|
318
|
+
</child>
|
319
|
+
<child>
|
320
|
+
<object class="GtkComboBox" id="cbTimeType">
|
321
|
+
<property name="visible">True</property>
|
322
|
+
<property name="can_focus">False</property>
|
323
|
+
</object>
|
324
|
+
<packing>
|
325
|
+
<property name="left_attach">1</property>
|
326
|
+
<property name="right_attach">2</property>
|
327
|
+
<property name="top_attach">8</property>
|
328
|
+
<property name="bottom_attach">9</property>
|
329
|
+
</packing>
|
330
|
+
</child>
|
331
|
+
<child>
|
332
|
+
<object class="GtkLabel" id="label11">
|
333
|
+
<property name="visible">True</property>
|
334
|
+
<property name="can_focus">False</property>
|
335
|
+
<property name="xalign">0</property>
|
336
|
+
<property name="label" translatable="yes">Timestamp</property>
|
337
|
+
</object>
|
338
|
+
<packing>
|
339
|
+
<property name="top_attach">9</property>
|
340
|
+
<property name="bottom_attach">10</property>
|
341
|
+
<property name="x_options">GTK_FILL</property>
|
342
|
+
<property name="y_options">GTK_FILL</property>
|
343
|
+
</packing>
|
344
|
+
</child>
|
345
|
+
<child>
|
346
|
+
<object class="GtkEntry" id="txtTimestamp">
|
347
|
+
<property name="visible">True</property>
|
348
|
+
<property name="can_focus">True</property>
|
349
|
+
<property name="invisible_char">•</property>
|
350
|
+
<property name="primary_icon_activatable">False</property>
|
351
|
+
<property name="secondary_icon_activatable">False</property>
|
352
|
+
<property name="primary_icon_sensitive">True</property>
|
353
|
+
<property name="secondary_icon_sensitive">True</property>
|
354
|
+
</object>
|
355
|
+
<packing>
|
356
|
+
<property name="left_attach">1</property>
|
357
|
+
<property name="right_attach">2</property>
|
358
|
+
<property name="top_attach">9</property>
|
359
|
+
<property name="bottom_attach">10</property>
|
360
|
+
</packing>
|
361
|
+
</child>
|
180
362
|
</object>
|
181
363
|
</child>
|
182
364
|
</object>
|
data/gui/trayicon.rb
CHANGED
@@ -7,6 +7,7 @@ class Openall_time_applet::Gui::Trayicon
|
|
7
7
|
|
8
8
|
@ti = Gtk::StatusIcon.new
|
9
9
|
@ti.signal_connect("popup-menu", &self.method(:on_statusicon_rightclick))
|
10
|
+
@ti.signal_connect("activate", &self.method(:on_statusicon_leftclick))
|
10
11
|
self.update_icon
|
11
12
|
|
12
13
|
#Start icon-updater-thread.
|
@@ -25,8 +26,11 @@ class Openall_time_applet::Gui::Trayicon
|
|
25
26
|
|
26
27
|
#This updates the icon in the system-tray. It draws seconds on the icon, if a timelog is being tracked.
|
27
28
|
def update_icon
|
29
|
+
color = Knj::Opts.get("tray_text_color")
|
30
|
+
color = "black" if color.to_s.strip.length <= 0
|
31
|
+
|
28
32
|
if !@args[:oata].timelog_active
|
29
|
-
@ti.file = "../gfx/
|
33
|
+
@ti.file = "../gfx/icon_time_#{color}.png"
|
30
34
|
return nil
|
31
35
|
end
|
32
36
|
|
@@ -58,8 +62,7 @@ class Openall_time_applet::Gui::Trayicon
|
|
58
62
|
self.format = "png"
|
59
63
|
}
|
60
64
|
|
61
|
-
color =
|
62
|
-
color = "black" if color.to_s.strip.length <= 0
|
65
|
+
color = "#a1a80a" if color == "green_casalogic"
|
63
66
|
|
64
67
|
gc = Magick::Draw.new
|
65
68
|
gc.fill(color)
|
@@ -85,11 +88,11 @@ class Openall_time_applet::Gui::Trayicon
|
|
85
88
|
timelog_new.signal_connect("activate", &self.method(:on_timelogNew_activate))
|
86
89
|
|
87
90
|
overview = Gtk::ImageMenuItem.new(Gtk::Stock::EDIT)
|
88
|
-
overview.label = _("
|
91
|
+
overview.label = _("Timelog list")
|
89
92
|
overview.signal_connect("activate", &self.method(:on_overview_activate))
|
90
93
|
|
91
94
|
worktime_overview = Gtk::ImageMenuItem.new(Gtk::Stock::HOME)
|
92
|
-
worktime_overview.label = _("
|
95
|
+
worktime_overview.label = _("Week view")
|
93
96
|
worktime_overview.signal_connect("activate", &self.method(:on_worktimeOverview_activate))
|
94
97
|
|
95
98
|
pref = Gtk::ImageMenuItem.new(Gtk::Stock::PREFERENCES)
|
@@ -108,7 +111,11 @@ class Openall_time_applet::Gui::Trayicon
|
|
108
111
|
menu.append(worktime_overview)
|
109
112
|
menu.append(Gtk::SeparatorMenuItem.new)
|
110
113
|
menu.append(pref)
|
111
|
-
|
114
|
+
|
115
|
+
|
116
|
+
#Only add seperator if more than one timelog.
|
117
|
+
timelog_count = @args[:oata].ob.list(:Timelog, {"count" => true})
|
118
|
+
menu.append(Gtk::SeparatorMenuItem.new) if timelog_count > 0
|
112
119
|
|
113
120
|
#Make a list of all timelogs in the menu.
|
114
121
|
@args[:oata].ob.list(:Timelog, {"orderby" => "id"}) do |timelog|
|
@@ -145,7 +152,13 @@ class Openall_time_applet::Gui::Trayicon
|
|
145
152
|
menu.append(quit)
|
146
153
|
menu.show_all
|
147
154
|
|
148
|
-
menu.popup(nil, nil, button, time)
|
155
|
+
menu.popup(nil, nil, button, time) do |menu, x, y|
|
156
|
+
@ti.position_menu(menu)
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
def on_statusicon_leftclick(*args)
|
161
|
+
@args[:oata].show_timelog_new
|
149
162
|
end
|
150
163
|
|
151
164
|
def on_preferences_activate(*args)
|
@@ -165,10 +178,28 @@ class Openall_time_applet::Gui::Trayicon
|
|
165
178
|
end
|
166
179
|
|
167
180
|
def on_quit_activate(*args)
|
168
|
-
|
181
|
+
#Check if a timelog needs to be synced. If so the user needs to confirm he really wants to quit.
|
182
|
+
timelog_found = nil
|
183
|
+
do_destroy = true
|
184
|
+
|
185
|
+
@args[:oata].ob.list(:Timelog) do |timelog|
|
186
|
+
if timelog[:time].to_f > 0 or timelog[:time_transport].to_f > 0 or timelog[:sync_need].to_i == 1
|
187
|
+
timelog_found = timelog
|
188
|
+
break
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
if timelog_found
|
193
|
+
if Knj::Gtk2.msgbox(sprintf(_("The timelog '%s' has not been synced. Are you sure you want to quit?"), timelog_found[:descr]), "yesno") != "yes"
|
194
|
+
do_destroy = false
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
@args[:oata].destroy if do_destroy
|
169
199
|
end
|
170
200
|
|
171
201
|
def on_sync_activate(*args)
|
202
|
+
@args[:oata].sync_static
|
172
203
|
@args[:oata].sync
|
173
204
|
end
|
174
205
|
|
data/gui/win_overview.rb
CHANGED
@@ -8,7 +8,123 @@ class Openall_time_applet::Gui::Win_overview
|
|
8
8
|
@gui.translate
|
9
9
|
@gui.connect_signals{|h| method(h)}
|
10
10
|
|
11
|
-
|
11
|
+
|
12
|
+
#Generate list-store containing tasks for the task-column.
|
13
|
+
task_ls = Gtk::ListStore.new(String, String)
|
14
|
+
iter = task_ls.append
|
15
|
+
iter[0] = _("None")
|
16
|
+
iter[1] = 0.to_s
|
17
|
+
|
18
|
+
task_ls_to_id = []
|
19
|
+
|
20
|
+
@args[:oata].ob.list(:Task, {"orderby" => "title"}) do |task|
|
21
|
+
iter = task_ls.append
|
22
|
+
iter[0] = task[:title]
|
23
|
+
iter[1] = task.id.to_s
|
24
|
+
task_ls_to_id << task.id
|
25
|
+
end
|
26
|
+
|
27
|
+
init_data = @gui["tvTimelogs"].init([
|
28
|
+
_("ID"),
|
29
|
+
_("Description"),
|
30
|
+
_("Time"),
|
31
|
+
_("Transport"),
|
32
|
+
{
|
33
|
+
:title => _("Needs sync"),
|
34
|
+
:type => :toggle
|
35
|
+
},
|
36
|
+
{
|
37
|
+
:title => _("Task"),
|
38
|
+
:type => :combo,
|
39
|
+
:model => task_ls
|
40
|
+
}
|
41
|
+
])
|
42
|
+
|
43
|
+
|
44
|
+
#Set description to be editable.
|
45
|
+
init_data[:renderers][1].editable = true
|
46
|
+
init_data[:renderers][1].signal_connect("edited") do |renderer, row, var|
|
47
|
+
sel = @gui["tvTimelogs"].sel
|
48
|
+
timelog = @args[:oata].ob.get(:Timelog, sel[0])
|
49
|
+
|
50
|
+
begin
|
51
|
+
timelog[:descr] = var
|
52
|
+
rescue => e
|
53
|
+
Knj::Gtk2.msgbox(e.message, "warning")
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
#Set time to be editable.
|
58
|
+
init_data[:renderers][2].editable = true
|
59
|
+
init_data[:renderers][2].signal_connect("edited") do |renderer, row, var|
|
60
|
+
sel = @gui["tvTimelogs"].sel
|
61
|
+
timelog = @args[:oata].ob.get(:Timelog, sel[0])
|
62
|
+
|
63
|
+
begin
|
64
|
+
time_secs = Knj::Strings.human_time_str_to_secs(var)
|
65
|
+
rescue
|
66
|
+
Knj::Gtk2.msgbox(_("Invalid time entered."))
|
67
|
+
return nil
|
68
|
+
end
|
69
|
+
|
70
|
+
begin
|
71
|
+
timelog[:time] = time_secs
|
72
|
+
rescue => e
|
73
|
+
Knj::Gtk2.msgbox(e.message, "warning")
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
#Set transport to be editable.
|
78
|
+
init_data[:renderers][3].editable = true
|
79
|
+
init_data[:renderers][3].signal_connect("edited") do |renderer, row, var|
|
80
|
+
sel = @gui["tvTimelogs"].sel
|
81
|
+
timelog = @args[:oata].ob.get(:Timelog, sel[0])
|
82
|
+
|
83
|
+
begin
|
84
|
+
time_secs = Knj::Strings.human_time_str_to_secs(var)
|
85
|
+
rescue
|
86
|
+
Knj::Gtk2.msgbox(_("Invalid time entered."))
|
87
|
+
return nil
|
88
|
+
end
|
89
|
+
|
90
|
+
begin
|
91
|
+
timelog[:time_transport] = time_secs
|
92
|
+
rescue => e
|
93
|
+
Knj::Gtk2.msgbox(e.message, "warning")
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
#Set sync flag to be activateable.
|
98
|
+
init_data[:renderers][4].activatable = true
|
99
|
+
init_data[:renderers][4].signal_connect("toggled") do |renderer, path, val|
|
100
|
+
iter = @gui["tvTimelogs"].model.get_iter(path)
|
101
|
+
id = @gui["tvTimelogs"].model.get_value(iter, 0)
|
102
|
+
timelog = @args[:oata].ob.get(:Timelog, id)
|
103
|
+
|
104
|
+
if timelog[:sync_need].to_i == 1
|
105
|
+
timelog[:sync_need] = 0
|
106
|
+
else
|
107
|
+
timelog[:sync_need] = 1
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
#Make task select-able.
|
112
|
+
init_data[:renderers][5].editable = true
|
113
|
+
init_data[:renderers][5].has_entry = false
|
114
|
+
init_data[:renderers][5].signal_connect("edited") do |renderer, row_no, val|
|
115
|
+
iter = @gui["tvTimelogs"].model.get_iter(row_no)
|
116
|
+
id = @gui["tvTimelogs"].model.get_value(iter, 0)
|
117
|
+
timelog = @args[:oata].ob.get(:Timelog, id)
|
118
|
+
|
119
|
+
task = @args[:oata].ob.get_by(:Task, {"title" => val})
|
120
|
+
if !task
|
121
|
+
timelog[:task_id] = 0
|
122
|
+
else
|
123
|
+
timelog[:task_id] = task.id
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
|
12
128
|
@gui["tvTimelogs"].columns[0].visible = false
|
13
129
|
self.reload_timelogs
|
14
130
|
|
@@ -18,6 +134,11 @@ class Openall_time_applet::Gui::Win_overview
|
|
18
134
|
@gui["window"].show_all
|
19
135
|
end
|
20
136
|
|
137
|
+
def on_cell_edited(*args)
|
138
|
+
print "Cell edit!\n"
|
139
|
+
Knj::Php.print_r(args)
|
140
|
+
end
|
141
|
+
|
21
142
|
def reload_timelogs
|
22
143
|
@gui["tvTimelogs"].model.clear
|
23
144
|
@args[:oata].ob.list(:Timelog, {"orderby" => "id"}) do |timelog|
|
@@ -26,7 +147,7 @@ class Openall_time_applet::Gui::Win_overview
|
|
26
147
|
timelog.descr_short,
|
27
148
|
timelog.time_as_human,
|
28
149
|
timelog.time_transport_as_human,
|
29
|
-
Knj::Strings.yn_str(timelog[:sync_need],
|
150
|
+
Knj::Strings.yn_str(timelog[:sync_need], true, false),
|
30
151
|
timelog.task_name
|
31
152
|
])
|
32
153
|
end
|
data/gui/win_preferences.rb
CHANGED
@@ -27,7 +27,7 @@ class Openall_time_applet::Gui::Win_preferences
|
|
27
27
|
@gui["txtReminderEveryMinute"].text = Knj::Opts.get("reminder_every_minute")
|
28
28
|
|
29
29
|
#Tray settings.
|
30
|
-
@tray_colors = {"black" => _("Black"), "white" => _("White")}
|
30
|
+
@tray_colors = {"black" => _("Black"), "green_casalogic" => _("Green (Casalogic)"), "white" => _("White")}
|
31
31
|
@gui["cbTrayTextColor"].init(@tray_colors.values)
|
32
32
|
@gui["cbTrayTextColor"].sel = @tray_colors[Knj::Opts.get("tray_text_color")] if Knj::Opts.get("tray_text_color").to_s.strip.length > 0
|
33
33
|
end
|
data/gui/win_timelog_edit.rb
CHANGED
@@ -11,6 +11,42 @@ class Openall_time_applet::Gui::Win_timelog_edit
|
|
11
11
|
tasks_opts = [_("None")] + @args[:oata].ob.list(:Task, {"orderby" => "openall_uid"})
|
12
12
|
@gui["cbTask"].init(tasks_opts)
|
13
13
|
|
14
|
+
Knj::Gtk2::Cb.init(
|
15
|
+
"cb" => @gui["cbTimeType"],
|
16
|
+
"items" => {
|
17
|
+
"normal" => _("Normal"),
|
18
|
+
"overtime150" => sprintf(_("Overtime %s"), 150),
|
19
|
+
"overtime200" => sprintf(_("Overtime %s"), 200)
|
20
|
+
}
|
21
|
+
)
|
22
|
+
|
23
|
+
|
24
|
+
#Set up completion for description entry.
|
25
|
+
ec = Gtk::EntryCompletion.new
|
26
|
+
ec.model = Gtk::ListStore.new(String)
|
27
|
+
ec.text_column = 0
|
28
|
+
@gui["txtDescr"].completion = ec
|
29
|
+
|
30
|
+
added = {}
|
31
|
+
@args[:oata].ob.list(:Worktime, {"orderby" => "timestamp"}) do |worktime|
|
32
|
+
next if added.key?(worktime[:comment])
|
33
|
+
added[worktime[:comment]] = true
|
34
|
+
ec.model.append[0] = worktime[:comment]
|
35
|
+
end
|
36
|
+
|
37
|
+
@args[:oata].ob.list(:Timelog, {"orderby" => "descr"}) do |timelog|
|
38
|
+
next if added.key?(timelog[:descr])
|
39
|
+
added[timelog[:descr]] = true
|
40
|
+
ec.model.append[0] = timelog[:descr]
|
41
|
+
end
|
42
|
+
|
43
|
+
ec.signal_connect("match-selected") do |me, model, iter|
|
44
|
+
text = model.get_value(iter, 0)
|
45
|
+
me.entry.text = text
|
46
|
+
true
|
47
|
+
end
|
48
|
+
|
49
|
+
|
14
50
|
#We are editting a timelog - set widget-values.
|
15
51
|
@timelog = @args[:timelog]
|
16
52
|
|
@@ -18,14 +54,22 @@ class Openall_time_applet::Gui::Win_timelog_edit
|
|
18
54
|
@gui["txtDescr"].text = @timelog[:descr]
|
19
55
|
@gui["txtTime"].text = @timelog.time_as_human
|
20
56
|
@gui["txtTimeTransport"].text = @timelog.time_transport_as_human
|
57
|
+
@gui["txtTransportLength"].text = Knj::Locales.number_out(@timelog[:transportlength], 0)
|
58
|
+
@gui["txtTransportCosts"].text = Knj::Locales.number_out(@timelog[:transportcosts], 0)
|
59
|
+
@gui["txtTransportDescr"].text = @timelog[:transportdescription]
|
21
60
|
@gui["cbTask"].sel = @timelog.task if @timelog.task
|
22
61
|
@gui["cbShouldSync"].active = Knj::Strings.yn_str(@timelog[:sync_need], true, false)
|
62
|
+
@gui["cbTravelFixed"].active = Knj::Strings.yn_str(@timelog[:travelfixed], true, false)
|
63
|
+
@gui["cbWorkInternal"].active = Knj::Strings.yn_str(@timelog[:workinternal], true, false)
|
64
|
+
@gui["cbTimeType"].sel = @timelog[:timetype]
|
65
|
+
@gui["txtTimestamp"].text = Knj::Datet.in(@timelog[:timestamp]).out
|
23
66
|
else
|
24
67
|
@gui["btnRemove"].visible = false
|
68
|
+
@gui["txtTimestamp"].text = Knj::Datet.new.out
|
25
69
|
end
|
26
70
|
|
27
71
|
#Show the window.
|
28
|
-
@gui["window"].
|
72
|
+
@gui["window"].show
|
29
73
|
end
|
30
74
|
|
31
75
|
def on_btnSave_clicked(*args)
|
@@ -60,13 +104,27 @@ class Openall_time_applet::Gui::Win_timelog_edit
|
|
60
104
|
end
|
61
105
|
end
|
62
106
|
|
107
|
+
begin
|
108
|
+
timestamp_dbstr = Knj::Datet.in(@gui["txtTimestamp"].text).dbstr
|
109
|
+
rescue
|
110
|
+
Knj::Gtk2.msgbox(_("You have entered an invalid timestamp."))
|
111
|
+
return nil
|
112
|
+
end
|
113
|
+
|
63
114
|
#Generate hash for updating dataabase.
|
64
115
|
save_hash = {
|
65
116
|
:descr => @gui["txtDescr"].text,
|
117
|
+
:timestamp => timestamp_dbstr,
|
66
118
|
:time => time_secs,
|
119
|
+
:timetype => @gui["cbTimeType"].sel,
|
67
120
|
:time_transport => time_transport_secs,
|
121
|
+
:transportdescription => @gui["txtTransportDescr"].text,
|
122
|
+
:transportlength => Knj::Locales.number_in(@gui["txtTransportLength"].text),
|
123
|
+
:transportcosts => Knj::Locales.number_in(@gui["txtTransportCosts"].text),
|
68
124
|
:task_id => task_id,
|
69
|
-
:sync_need => Knj::Strings.yn_str(@gui["cbShouldSync"].active?, 1, 0)
|
125
|
+
:sync_need => Knj::Strings.yn_str(@gui["cbShouldSync"].active?, 1, 0),
|
126
|
+
:workinternal => Knj::Strings.yn_str(@gui["cbWorkInternal"].active?, 1, 0),
|
127
|
+
:travelfixed => Knj::Strings.yn_str(@gui["cbTravelFixed"].active?, 1, 0)
|
70
128
|
}
|
71
129
|
|
72
130
|
#Update or add the timelog.
|
data/lib/openall_time_applet.rb
CHANGED
@@ -110,6 +110,9 @@ class Openall_time_applet
|
|
110
110
|
#Set crash-operation to save tracked time instead of loosing it.
|
111
111
|
Kernel.at_exit(&self.method(:destroy))
|
112
112
|
|
113
|
+
#Set default-color to "green_casalogic".
|
114
|
+
Knj::Opts.set("tray_text_color", "green_casalogic") if Knj::Opts.get("tray_text_color").to_s.strip.length <= 0
|
115
|
+
|
113
116
|
#Spawn tray-icon.
|
114
117
|
self.spawn_trayicon
|
115
118
|
|
@@ -120,7 +123,7 @@ class Openall_time_applet
|
|
120
123
|
#Updates the database according to the db-schema.
|
121
124
|
def update_db
|
122
125
|
require "../conf/db_schema.rb"
|
123
|
-
Knj::Db::Revision.new.init_db("db" => @db, "schema" => Openall_time_applet::DB_SCHEMA)
|
126
|
+
Knj::Db::Revision.new.init_db("debug" => false, "db" => @db, "schema" => Openall_time_applet::DB_SCHEMA)
|
124
127
|
end
|
125
128
|
|
126
129
|
#This method starts the reminder-thread, that checks if a reminder should be shown.
|
@@ -161,7 +164,8 @@ class Openall_time_applet
|
|
161
164
|
:host => Knj::Opts.get("openall_host"),
|
162
165
|
:port => Knj::Opts.get("openall_port"),
|
163
166
|
:username => Knj::Opts.get("openall_username"),
|
164
|
-
:password => Base64.strict_decode64(Knj::Opts.get("openall_password"))
|
167
|
+
:password => Base64.strict_decode64(Knj::Opts.get("openall_password")),
|
168
|
+
:ssl => Knj::Strings.yn_str(Knj::Opts.get("openall_ssl"), true, false)
|
165
169
|
)
|
166
170
|
yield(conn)
|
167
171
|
ensure
|
@@ -177,23 +181,33 @@ class Openall_time_applet
|
|
177
181
|
|
178
182
|
#Spawns the preference-window.
|
179
183
|
def show_preferences
|
180
|
-
|
184
|
+
Knj::Gtk2::Window.unique!("preferences") do
|
185
|
+
Openall_time_applet::Gui::Win_preferences.new(:oata => self)
|
186
|
+
end
|
181
187
|
end
|
182
188
|
|
183
189
|
def show_timelog_new
|
184
|
-
|
190
|
+
Knj::Gtk2::Window.unique!("timelog_new") do
|
191
|
+
Openall_time_applet::Gui::Win_timelog_edit.new(:oata => self)
|
192
|
+
end
|
185
193
|
end
|
186
194
|
|
187
195
|
def show_timelog_edit(timelog)
|
188
|
-
|
196
|
+
Knj::Gtk2::Window.unique!("timelog_edit_#{timelog.id}") do
|
197
|
+
Openall_time_applet::Gui::Win_timelog_edit.new(:oata => self, :timelog => timelog)
|
198
|
+
end
|
189
199
|
end
|
190
200
|
|
191
201
|
def show_overview
|
192
|
-
|
202
|
+
Knj::Gtk2::Window.unique!("overview") do
|
203
|
+
Openall_time_applet::Gui::Win_overview.new(:oata => self)
|
204
|
+
end
|
193
205
|
end
|
194
206
|
|
195
207
|
def show_worktime_overview
|
196
|
-
|
208
|
+
Knj::Gtk2::Window.unique!("worktime_overview") do
|
209
|
+
Openall_time_applet::Gui::Win_worktime_overview.new(:oata => self)
|
210
|
+
end
|
197
211
|
end
|
198
212
|
|
199
213
|
#Updates the task-cache.
|
@@ -215,6 +229,33 @@ class Openall_time_applet
|
|
215
229
|
@ob.static(:Timelog, :push_time_updates, {:oata => self})
|
216
230
|
end
|
217
231
|
|
232
|
+
#Synchronizes organisations, tasks and worktimes.
|
233
|
+
def sync_static
|
234
|
+
sw = Knj::Gtk2::StatusWindow.new
|
235
|
+
|
236
|
+
Knj::Thread.new do
|
237
|
+
begin
|
238
|
+
sw.label = _("Updating organisation-cache.")
|
239
|
+
self.update_organisation_cache
|
240
|
+
sw.percent = 0.33
|
241
|
+
|
242
|
+
sw.label = _("Updating task-cache.")
|
243
|
+
self.update_task_cache
|
244
|
+
sw.percent = 0.66
|
245
|
+
|
246
|
+
sw.label = _("Updating worktime-cache.")
|
247
|
+
self.update_worktime_cache
|
248
|
+
sw.percent = 1
|
249
|
+
|
250
|
+
sleep 1
|
251
|
+
rescue => e
|
252
|
+
Knj::Gtk2.msgbox("msg" => Knj::Errors.error_str(e), "type" => "warning", "title" => _("Error"), "run" => false)
|
253
|
+
ensure
|
254
|
+
sw.destroy if sw
|
255
|
+
end
|
256
|
+
end
|
257
|
+
end
|
258
|
+
|
218
259
|
#Shows the sync overview, which must be seen before the actual sync.
|
219
260
|
def sync
|
220
261
|
Openall_time_applet::Gui::Win_sync_overview.new(:oata => self)
|
@@ -223,25 +264,13 @@ class Openall_time_applet
|
|
223
264
|
#Refreshes task-cache, create missing worktime from timelogs and push tracked time to timelogs. Shows a status-window while doing so.
|
224
265
|
def sync_real
|
225
266
|
sw = Knj::Gtk2::StatusWindow.new
|
226
|
-
|
227
|
-
if @timelog_active
|
228
|
-
timelog_active = @timelog_active
|
229
|
-
self.timelog_stop_tracking
|
230
|
-
end
|
267
|
+
self.timelog_stop_tracking if @timelog_active
|
231
268
|
|
232
269
|
Knj::Thread.new do
|
233
270
|
begin
|
234
|
-
sw.label = _("Updating organisation-cache.")
|
235
|
-
self.update_organisation_cache
|
236
|
-
sw.percent = 0.25
|
237
|
-
|
238
|
-
sw.label = _("Updating task-cache.")
|
239
|
-
self.update_task_cache
|
240
|
-
sw.percent = 0.5
|
241
|
-
|
242
271
|
sw.label = _("Pushing time-updates.")
|
243
272
|
self.push_time_updates
|
244
|
-
sw.percent = 0.
|
273
|
+
sw.percent = 0.5
|
245
274
|
|
246
275
|
sw.label = _("Updating worktime-cache.")
|
247
276
|
self.update_worktime_cache
|
@@ -254,7 +283,6 @@ class Openall_time_applet
|
|
254
283
|
Knj::Gtk2.msgbox("msg" => Knj::Errors.error_str(e), "type" => "warning", "title" => _("Error"), "run" => false)
|
255
284
|
ensure
|
256
285
|
sw.destroy if sw
|
257
|
-
self.timelog_active = timelog_active if timelog_active
|
258
286
|
end
|
259
287
|
end
|
260
288
|
end
|
Binary file
|
@@ -1,8 +1,8 @@
|
|
1
1
|
msgid ""
|
2
2
|
msgstr ""
|
3
3
|
"Project-Id-Version: Openall_time_applet\n"
|
4
|
-
"POT-Creation-Date: 2012-
|
5
|
-
"PO-Revision-Date: 2012-
|
4
|
+
"POT-Creation-Date: 2012-06-08 15:47+0100\n"
|
5
|
+
"PO-Revision-Date: 2012-06-08 15:48+0100\n"
|
6
6
|
"Last-Translator: Kasper Johansen <k@spernj.org>\n"
|
7
7
|
"Language-Team: Kasper Johansen <k@spernj.org>\n"
|
8
8
|
"Language: \n"
|
@@ -56,66 +56,76 @@ msgstr "Lørday"
|
|
56
56
|
msgid "Sunday"
|
57
57
|
msgstr "Søndag"
|
58
58
|
|
59
|
-
#: gui/trayicon.rb:
|
59
|
+
#: gui/trayicon.rb:87
|
60
60
|
msgid "New timelog"
|
61
61
|
msgstr "Ny tidslog"
|
62
62
|
|
63
|
-
#: gui/trayicon.rb:
|
64
|
-
msgid "
|
65
|
-
msgstr "
|
63
|
+
#: gui/trayicon.rb:91
|
64
|
+
msgid "Timelog list"
|
65
|
+
msgstr "Tidslog liste"
|
66
66
|
|
67
|
-
#: gui/trayicon.rb:
|
68
|
-
msgid "
|
69
|
-
msgstr "
|
67
|
+
#: gui/trayicon.rb:95
|
68
|
+
msgid "Week view"
|
69
|
+
msgstr "Uge oversigt"
|
70
70
|
|
71
|
-
#: gui/trayicon.rb:
|
71
|
+
#: gui/trayicon.rb:105
|
72
72
|
msgid "Synchronize with OpenAll"
|
73
73
|
msgstr "Synkroniserer med OpenAll"
|
74
74
|
|
75
|
-
#: gui/trayicon.rb:
|
75
|
+
#: gui/trayicon.rb:122
|
76
76
|
msgid "Track: %s"
|
77
77
|
msgstr "Følg: %s"
|
78
78
|
|
79
|
-
#: gui/trayicon.rb:
|
79
|
+
#: gui/trayicon.rb:146
|
80
80
|
msgid "%s minutes"
|
81
81
|
msgstr "%s minutter"
|
82
82
|
|
83
|
-
#: gui/
|
83
|
+
#: gui/trayicon.rb:193
|
84
|
+
msgid "The timelog '%s' has not been synced. Are you sure you want to quit?"
|
85
|
+
msgstr "Tidsloggen '%s' er ikke blevet synkroniseret. Er du sikker på, at du vil afslutte?"
|
86
|
+
|
87
|
+
#: gui/win_overview.rb:15
|
88
|
+
#: gui/win_timelog_edit.rb:11
|
89
|
+
msgid "None"
|
90
|
+
msgstr "Ingen"
|
91
|
+
|
92
|
+
#: gui/win_overview.rb:28
|
84
93
|
msgid "ID"
|
85
94
|
msgstr "ID"
|
86
95
|
|
87
|
-
#: gui/win_overview.rb:
|
96
|
+
#: gui/win_overview.rb:29
|
88
97
|
msgid "Description"
|
89
98
|
msgstr "Beskrivelse"
|
90
99
|
|
91
|
-
#: gui/win_overview.rb:
|
100
|
+
#: gui/win_overview.rb:30
|
92
101
|
msgid "Time"
|
93
102
|
msgstr "Tid"
|
94
103
|
|
95
|
-
#: gui/win_overview.rb:
|
104
|
+
#: gui/win_overview.rb:31
|
96
105
|
msgid "Transport"
|
97
106
|
msgstr "Transport"
|
98
107
|
|
99
|
-
#: gui/win_overview.rb:
|
108
|
+
#: gui/win_overview.rb:33
|
100
109
|
msgid "Needs sync"
|
101
110
|
msgstr "Behøver sync"
|
102
111
|
|
103
|
-
#: gui/win_overview.rb:
|
112
|
+
#: gui/win_overview.rb:37
|
104
113
|
msgid "Task"
|
105
114
|
msgstr "Opgave"
|
106
115
|
|
107
|
-
#: gui/win_overview.rb:
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
#: gui/win_overview.rb:29
|
112
|
-
msgid "No"
|
113
|
-
msgstr "Nej"
|
116
|
+
#: gui/win_overview.rb:66
|
117
|
+
#: gui/win_overview.rb:86
|
118
|
+
msgid "Invalid time entered."
|
119
|
+
msgstr "Ugyldig tid indtastet."
|
114
120
|
|
115
121
|
#: gui/win_preferences.rb:30
|
116
122
|
msgid "Black"
|
117
123
|
msgstr "Sort"
|
118
124
|
|
125
|
+
#: gui/win_preferences.rb:30
|
126
|
+
msgid "Green (Casalogic)"
|
127
|
+
msgstr "Grøn (Casalogic)"
|
128
|
+
|
119
129
|
#: gui/win_preferences.rb:30
|
120
130
|
msgid "White"
|
121
131
|
msgstr "Hvid"
|
@@ -149,31 +159,41 @@ msgid "Got %s tasks."
|
|
149
159
|
msgstr "Hentet %s opgaver."
|
150
160
|
|
151
161
|
#: gui/win_preferences.rb:89
|
152
|
-
#: lib/openall_time_applet.rb:
|
162
|
+
#: lib/openall_time_applet.rb:252
|
163
|
+
#: lib/openall_time_applet.rb:283
|
153
164
|
msgid "Error"
|
154
165
|
msgstr "Fejl"
|
155
166
|
|
156
|
-
#: gui/win_worktime_overview.rb:
|
167
|
+
#: gui/win_worktime_overview.rb:27
|
157
168
|
msgid "Week %s"
|
158
169
|
msgstr "Uge %s"
|
159
170
|
|
160
|
-
#: gui/win_worktime_overview.rb:
|
171
|
+
#: gui/win_worktime_overview.rb:118
|
161
172
|
msgid "No worktimes was found that week."
|
162
173
|
msgstr "Der blev ikke fundet nogle arbejdstimer i denne uge."
|
163
174
|
|
164
|
-
#: gui/win_timelog_edit.rb:
|
165
|
-
msgid "
|
166
|
-
msgstr "
|
175
|
+
#: gui/win_timelog_edit.rb:17
|
176
|
+
msgid "Normal"
|
177
|
+
msgstr "Normal"
|
167
178
|
|
168
|
-
#: gui/win_timelog_edit.rb:
|
179
|
+
#: gui/win_timelog_edit.rb:18
|
180
|
+
#: gui/win_timelog_edit.rb:19
|
181
|
+
msgid "Overtime %s"
|
182
|
+
msgstr "Overtid %s"
|
183
|
+
|
184
|
+
#: gui/win_timelog_edit.rb:91
|
169
185
|
msgid "You have entered an invalid time-format."
|
170
186
|
msgstr "Du har indtastet et ugyldigt tids-format."
|
171
187
|
|
172
|
-
#: gui/win_timelog_edit.rb:
|
188
|
+
#: gui/win_timelog_edit.rb:102
|
173
189
|
msgid "You have entered an invalid transport-time-format."
|
174
190
|
msgstr "Du har indtastet et ugyldigt transport-tids-format."
|
175
191
|
|
176
|
-
#: gui/win_timelog_edit.rb:
|
192
|
+
#: gui/win_timelog_edit.rb:110
|
193
|
+
msgid "You have entered an invalid timestamp."
|
194
|
+
msgstr "Du har indtastet et ugyldigt tidsstempel."
|
195
|
+
|
196
|
+
#: gui/win_timelog_edit.rb:146
|
177
197
|
msgid "Do you want to remove this timelog? This will not delete the timelog on OpenAll."
|
178
198
|
msgstr "Vil du fjerne denne tidslogning? Dette vil ikke slette tidslogningen fra OpenAll."
|
179
199
|
|
@@ -193,27 +213,28 @@ msgstr "Tid var ikke numerisk for: '%s'."
|
|
193
213
|
msgid "not set"
|
194
214
|
msgstr "ikke sat"
|
195
215
|
|
196
|
-
#: lib/openall_time_applet.rb:
|
216
|
+
#: lib/openall_time_applet.rb:152
|
197
217
|
msgid "Tracking task: %s"
|
198
218
|
msgstr "Følger opgave: %s"
|
199
219
|
|
200
|
-
#: lib/openall_time_applet.rb:
|
220
|
+
#: lib/openall_time_applet.rb:238
|
201
221
|
msgid "Updating organisation-cache."
|
202
222
|
msgstr "Opdaterer organisations-cache."
|
203
223
|
|
204
|
-
#: lib/openall_time_applet.rb:
|
224
|
+
#: lib/openall_time_applet.rb:242
|
205
225
|
msgid "Updating task-cache."
|
206
226
|
msgstr "Opdaterer opgave-cache."
|
207
227
|
|
208
|
-
#: lib/openall_time_applet.rb:242
|
209
|
-
msgid "Pushing time-updates."
|
210
|
-
msgstr "Sender tids-opdateringer."
|
211
|
-
|
212
228
|
#: lib/openall_time_applet.rb:246
|
229
|
+
#: lib/openall_time_applet.rb:275
|
213
230
|
msgid "Updating worktime-cache."
|
214
231
|
msgstr "Opdaterer arbejdstids-cache."
|
215
232
|
|
216
|
-
#: lib/openall_time_applet.rb:
|
233
|
+
#: lib/openall_time_applet.rb:271
|
234
|
+
msgid "Pushing time-updates."
|
235
|
+
msgstr "Sender tids-opdateringer."
|
236
|
+
|
237
|
+
#: lib/openall_time_applet.rb:279
|
217
238
|
msgid "Done"
|
218
239
|
msgstr "Færdig"
|
219
240
|
|
@@ -229,15 +250,43 @@ msgstr "Uge"
|
|
229
250
|
msgid "Timelog"
|
230
251
|
msgstr "Tidslog"
|
231
252
|
|
232
|
-
#: glade/win_timelog_edit.glade:
|
253
|
+
#: glade/win_timelog_edit.glade:135
|
233
254
|
msgid "Should sync"
|
234
255
|
msgstr "Skal synces"
|
235
256
|
|
236
|
-
#: glade/win_timelog_edit.glade:
|
257
|
+
#: glade/win_timelog_edit.glade:152
|
237
258
|
msgid "Start tracking after saving"
|
238
259
|
msgstr "Starter med at følge efter gem"
|
239
260
|
|
240
|
-
#: glade/win_timelog_edit.glade:
|
261
|
+
#: glade/win_timelog_edit.glade:185
|
262
|
+
msgid "Transport length"
|
263
|
+
msgstr "Transport længde"
|
264
|
+
|
265
|
+
#: glade/win_timelog_edit.glade:199
|
266
|
+
msgid "Transport costs"
|
267
|
+
msgstr "Transport omkostninger"
|
268
|
+
|
269
|
+
#: glade/win_timelog_edit.glade:247
|
270
|
+
msgid "Transport description"
|
271
|
+
msgstr "Transport beskrivelse"
|
272
|
+
|
273
|
+
#: glade/win_timelog_edit.glade:275
|
274
|
+
msgid "Internal work"
|
275
|
+
msgstr "Internt arbejde"
|
276
|
+
|
277
|
+
#: glade/win_timelog_edit.glade:290
|
278
|
+
msgid "Fixed travel"
|
279
|
+
msgstr "Fikset rejse"
|
280
|
+
|
281
|
+
#: glade/win_timelog_edit.glade:310
|
282
|
+
msgid "Time type"
|
283
|
+
msgstr "Tids type"
|
284
|
+
|
285
|
+
#: glade/win_timelog_edit.glade:336
|
286
|
+
msgid "Timestamp"
|
287
|
+
msgstr "Tidsstempel"
|
288
|
+
|
289
|
+
#: glade/win_timelog_edit.glade:370
|
241
290
|
#: glade/win_sync_overview.glade:40
|
242
291
|
msgid "<b>Timelog</b>"
|
243
292
|
msgstr "<b>Tidslog</b>"
|
@@ -310,10 +359,19 @@ msgstr "<b>Synk. som tid</b>"
|
|
310
359
|
msgid "<b>Sync with OpenAll</b>"
|
311
360
|
msgstr "<b>Synk med OpenAll</b>"
|
312
361
|
|
313
|
-
#: glade/win_overview.glade:
|
362
|
+
#: glade/win_overview.glade:55
|
314
363
|
msgid "<b>Timelogs</b>"
|
315
364
|
msgstr "<b>Tidslogs</b>"
|
316
365
|
|
366
|
+
#~ msgid "Time overview"
|
367
|
+
#~ msgstr "Tids oversigt"
|
368
|
+
|
369
|
+
#~ msgid "Yes"
|
370
|
+
#~ msgstr "Ja"
|
371
|
+
|
372
|
+
#~ msgid "No"
|
373
|
+
#~ msgstr "Nej"
|
374
|
+
|
317
375
|
#~ msgid "%s seconds"
|
318
376
|
#~ msgstr "%s sekunder"
|
319
377
|
|
data/models/timelog.rb
CHANGED
@@ -3,6 +3,14 @@ class Openall_time_applet::Models::Timelog < Knj::Datarow
|
|
3
3
|
:Task
|
4
4
|
]
|
5
5
|
|
6
|
+
def initialize(*args, &block)
|
7
|
+
super(*args, &block)
|
8
|
+
|
9
|
+
#Fix default time-type (SQLite3 doesnt support this).
|
10
|
+
self[:timetype] = "normal" if self[:timetype].to_s == ""
|
11
|
+
self[:timestamp] = Knj::Datet.new.dbstr if self[:timestamp].to_s == ""
|
12
|
+
end
|
13
|
+
|
6
14
|
#Treat data before inserting into database.
|
7
15
|
def self.add(d)
|
8
16
|
d.data[:time] = 0 if d.data[:time].to_s.strip.length <= 0
|
@@ -24,17 +32,19 @@ class Openall_time_applet::Models::Timelog < Knj::Datarow
|
|
24
32
|
:task_uid => timelog.task[:openall_uid].to_i,
|
25
33
|
:comment => timelog[:descr],
|
26
34
|
:worktime => Knj::Strings.secs_to_human_time_str(timelog[:time]),
|
27
|
-
:
|
35
|
+
:workinternal => timelog[:workinternal],
|
36
|
+
:timestamp => timelog[:timestamp],
|
37
|
+
:timetype => timelog[:timetype],
|
38
|
+
:transporttime => Knj::Strings.secs_to_human_time_str(timelog[:time_transport]),
|
39
|
+
:transportlength => timelog[:transportlength].to_i,
|
40
|
+
:transportcosts => timelog[:transportcosts].to_i,
|
41
|
+
:transportdescription => timelog[:transportdescription],
|
42
|
+
:travelfixed => timelog[:travelfixed]
|
28
43
|
}
|
29
44
|
)
|
30
45
|
|
31
|
-
#
|
32
|
-
|
33
|
-
:time => 0,
|
34
|
-
:time_transport => 0,
|
35
|
-
:sync_need => 0,
|
36
|
-
:sync_last => Time.now
|
37
|
-
)
|
46
|
+
#Delete timelog.
|
47
|
+
d.ob.delete(timelog)
|
38
48
|
end
|
39
49
|
end
|
40
50
|
end
|
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.10"
|
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-
|
12
|
+
s.date = %q{2012-06-08}
|
13
13
|
s.default_executable = %q{openall_time_applet.rb}
|
14
14
|
s.description = %q{Off-line time-tracking for OpenAll with syncing when online.}
|
15
15
|
s.email = %q{k@spernj.org}
|
@@ -31,8 +31,10 @@ Gem::Specification.new do |s|
|
|
31
31
|
"classes/connection.rb",
|
32
32
|
"classes/translations.rb",
|
33
33
|
"conf/db_schema.rb",
|
34
|
-
"gfx/
|
34
|
+
"gfx/icon_time_black.png",
|
35
|
+
"gfx/icon_time_green_casalogic.png",
|
35
36
|
"gfx/icon_time_orig.png",
|
37
|
+
"gfx/icon_time_white.png",
|
36
38
|
"glade/win_overview.glade",
|
37
39
|
"glade/win_preferences.glade",
|
38
40
|
"glade/win_sync_overview.glade",
|
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.10
|
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-
|
13
|
+
date: 2012-06-08 00:00:00 +02:00
|
14
14
|
default_executable: openall_time_applet.rb
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
@@ -156,8 +156,10 @@ files:
|
|
156
156
|
- classes/connection.rb
|
157
157
|
- classes/translations.rb
|
158
158
|
- conf/db_schema.rb
|
159
|
-
- gfx/
|
159
|
+
- gfx/icon_time_black.png
|
160
|
+
- gfx/icon_time_green_casalogic.png
|
160
161
|
- gfx/icon_time_orig.png
|
162
|
+
- gfx/icon_time_white.png
|
161
163
|
- glade/win_overview.glade
|
162
164
|
- glade/win_preferences.glade
|
163
165
|
- glade/win_sync_overview.glade
|
@@ -193,7 +195,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
193
195
|
requirements:
|
194
196
|
- - ">="
|
195
197
|
- !ruby/object:Gem::Version
|
196
|
-
hash:
|
198
|
+
hash: -2758697315612499860
|
197
199
|
segments:
|
198
200
|
- 0
|
199
201
|
version: "0"
|