openall_time_applet 0.0.16 → 0.0.17
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/glade/win_main.glade +152 -15
- data/glade/win_preferences.glade +120 -0
- data/gui/trayicon.rb +34 -9
- data/gui/win_main.rb +74 -9
- data/gui/win_preferences.rb +19 -0
- data/lib/openall_time_applet.rb +60 -1
- data/openall_time_applet.gemspec +2 -2
- metadata +3 -3
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.17
|
data/classes/connection.rb
CHANGED
@@ -22,7 +22,7 @@ class Openall_time_applet::Connection
|
|
22
22
|
#Verify login by reading dashboard HTML.
|
23
23
|
res = @http.get("index.php?c=Dashboard")
|
24
24
|
|
25
|
-
if !res.body.match(/<ul\s*id="webticker"\s*>/)
|
25
|
+
if !res.body.match(/<ul\s*id="webticker"\s*>/) and !res.body.index("<a href=\"index.php?c=Dashboard&m=editDashboard\">") == nil
|
26
26
|
tmp_path = "#{Knj::Os.tmpdir}/openall_login_debug.txt"
|
27
27
|
File.open(tmp_path, "w") do |fp|
|
28
28
|
fp.write(res.body)
|
data/glade/win_main.glade
CHANGED
@@ -62,6 +62,16 @@
|
|
62
62
|
<signal name="activate" handler="on_imiPreferences_activate" swapped="no"/>
|
63
63
|
</object>
|
64
64
|
</child>
|
65
|
+
<child>
|
66
|
+
<object class="GtkMenuItem" id="miSyncStatic">
|
67
|
+
<property name="visible">True</property>
|
68
|
+
<property name="can_focus">False</property>
|
69
|
+
<property name="use_action_appearance">False</property>
|
70
|
+
<property name="label" translatable="yes">Synchronize static data</property>
|
71
|
+
<property name="use_underline">True</property>
|
72
|
+
<signal name="activate" handler="on_miSyncStatic_activate" swapped="no"/>
|
73
|
+
</object>
|
74
|
+
</child>
|
65
75
|
<child>
|
66
76
|
<object class="GtkSeparatorMenuItem" id="separatormenuitem1">
|
67
77
|
<property name="visible">True</property>
|
@@ -173,7 +183,7 @@
|
|
173
183
|
<object class="GtkExpander" id="expOverview">
|
174
184
|
<property name="visible">True</property>
|
175
185
|
<property name="can_focus">True</property>
|
176
|
-
<signal name="activate" handler="on_expOverview_activate" swapped="no"/>
|
186
|
+
<signal name="activate" handler="on_expOverview_activate" after="yes" swapped="no"/>
|
177
187
|
<child>
|
178
188
|
<object class="GtkVBox" id="vbox2">
|
179
189
|
<property name="visible">True</property>
|
@@ -254,6 +264,34 @@
|
|
254
264
|
<property name="position">1</property>
|
255
265
|
</packing>
|
256
266
|
</child>
|
267
|
+
<child>
|
268
|
+
<object class="GtkHButtonBox" id="hbuttonbox1">
|
269
|
+
<property name="visible">True</property>
|
270
|
+
<property name="can_focus">False</property>
|
271
|
+
<property name="layout_style">end</property>
|
272
|
+
<child>
|
273
|
+
<object class="GtkButton" id="btnSync">
|
274
|
+
<property name="label" translatable="yes">Prepare _sync</property>
|
275
|
+
<property name="visible">True</property>
|
276
|
+
<property name="can_focus">True</property>
|
277
|
+
<property name="receives_default">True</property>
|
278
|
+
<property name="use_action_appearance">False</property>
|
279
|
+
<property name="use_underline">True</property>
|
280
|
+
<signal name="clicked" handler="on_btnSync_clicked" swapped="no"/>
|
281
|
+
</object>
|
282
|
+
<packing>
|
283
|
+
<property name="expand">False</property>
|
284
|
+
<property name="fill">False</property>
|
285
|
+
<property name="position">0</property>
|
286
|
+
</packing>
|
287
|
+
</child>
|
288
|
+
</object>
|
289
|
+
<packing>
|
290
|
+
<property name="expand">False</property>
|
291
|
+
<property name="fill">True</property>
|
292
|
+
<property name="position">2</property>
|
293
|
+
</packing>
|
294
|
+
</child>
|
257
295
|
</object>
|
258
296
|
</child>
|
259
297
|
<child type="label">
|
@@ -271,25 +309,112 @@
|
|
271
309
|
</packing>
|
272
310
|
</child>
|
273
311
|
<child>
|
274
|
-
<object class="
|
312
|
+
<object class="GtkFrame" id="frameTimelogInfo">
|
275
313
|
<property name="visible">True</property>
|
276
314
|
<property name="can_focus">False</property>
|
277
|
-
<property name="
|
315
|
+
<property name="label_xalign">0</property>
|
316
|
+
<property name="shadow_type">none</property>
|
278
317
|
<child>
|
279
|
-
<object class="
|
280
|
-
<property name="label" translatable="yes">_Sync</property>
|
318
|
+
<object class="GtkAlignment" id="alignment3">
|
281
319
|
<property name="visible">True</property>
|
282
|
-
<property name="can_focus">
|
283
|
-
<property name="
|
284
|
-
<
|
285
|
-
|
286
|
-
|
320
|
+
<property name="can_focus">False</property>
|
321
|
+
<property name="left_padding">12</property>
|
322
|
+
<child>
|
323
|
+
<object class="GtkTable" id="table1">
|
324
|
+
<property name="visible">True</property>
|
325
|
+
<property name="can_focus">False</property>
|
326
|
+
<property name="n_rows">3</property>
|
327
|
+
<property name="n_columns">2</property>
|
328
|
+
<property name="column_spacing">3</property>
|
329
|
+
<property name="row_spacing">3</property>
|
330
|
+
<child>
|
331
|
+
<object class="GtkLabel" id="label4">
|
332
|
+
<property name="visible">True</property>
|
333
|
+
<property name="can_focus">False</property>
|
334
|
+
<property name="xalign">0</property>
|
335
|
+
<property name="label" translatable="yes">Description</property>
|
336
|
+
</object>
|
337
|
+
<packing>
|
338
|
+
<property name="x_options">GTK_FILL</property>
|
339
|
+
<property name="y_options">GTK_FILL</property>
|
340
|
+
</packing>
|
341
|
+
</child>
|
342
|
+
<child>
|
343
|
+
<object class="GtkLabel" id="label5">
|
344
|
+
<property name="visible">True</property>
|
345
|
+
<property name="can_focus">False</property>
|
346
|
+
<property name="xalign">0</property>
|
347
|
+
<property name="label" translatable="yes">Task</property>
|
348
|
+
</object>
|
349
|
+
<packing>
|
350
|
+
<property name="top_attach">1</property>
|
351
|
+
<property name="bottom_attach">2</property>
|
352
|
+
<property name="x_options">GTK_FILL</property>
|
353
|
+
<property name="y_options">GTK_FILL</property>
|
354
|
+
</packing>
|
355
|
+
</child>
|
356
|
+
<child>
|
357
|
+
<object class="GtkLabel" id="label6">
|
358
|
+
<property name="visible">True</property>
|
359
|
+
<property name="can_focus">False</property>
|
360
|
+
<property name="xalign">0</property>
|
361
|
+
<property name="label" translatable="yes">Time</property>
|
362
|
+
</object>
|
363
|
+
<packing>
|
364
|
+
<property name="top_attach">2</property>
|
365
|
+
<property name="bottom_attach">3</property>
|
366
|
+
<property name="x_options">GTK_FILL</property>
|
367
|
+
<property name="y_options">GTK_FILL</property>
|
368
|
+
</packing>
|
369
|
+
</child>
|
370
|
+
<child>
|
371
|
+
<object class="GtkLabel" id="labTimelogInfoDescr">
|
372
|
+
<property name="visible">True</property>
|
373
|
+
<property name="can_focus">False</property>
|
374
|
+
<property name="xalign">0</property>
|
375
|
+
</object>
|
376
|
+
<packing>
|
377
|
+
<property name="left_attach">1</property>
|
378
|
+
<property name="right_attach">2</property>
|
379
|
+
</packing>
|
380
|
+
</child>
|
381
|
+
<child>
|
382
|
+
<object class="GtkLabel" id="labTimelogInfoTask">
|
383
|
+
<property name="visible">True</property>
|
384
|
+
<property name="can_focus">False</property>
|
385
|
+
<property name="xalign">0</property>
|
386
|
+
</object>
|
387
|
+
<packing>
|
388
|
+
<property name="left_attach">1</property>
|
389
|
+
<property name="right_attach">2</property>
|
390
|
+
<property name="top_attach">1</property>
|
391
|
+
<property name="bottom_attach">2</property>
|
392
|
+
</packing>
|
393
|
+
</child>
|
394
|
+
<child>
|
395
|
+
<object class="GtkLabel" id="labTimelogInfoTime">
|
396
|
+
<property name="visible">True</property>
|
397
|
+
<property name="can_focus">False</property>
|
398
|
+
<property name="xalign">0</property>
|
399
|
+
</object>
|
400
|
+
<packing>
|
401
|
+
<property name="left_attach">1</property>
|
402
|
+
<property name="right_attach">2</property>
|
403
|
+
<property name="top_attach">2</property>
|
404
|
+
<property name="bottom_attach">3</property>
|
405
|
+
</packing>
|
406
|
+
</child>
|
407
|
+
</object>
|
408
|
+
</child>
|
409
|
+
</object>
|
410
|
+
</child>
|
411
|
+
<child type="label">
|
412
|
+
<object class="GtkLabel" id="label3">
|
413
|
+
<property name="visible">True</property>
|
414
|
+
<property name="can_focus">False</property>
|
415
|
+
<property name="label" translatable="yes"><b>Timelog info</b></property>
|
416
|
+
<property name="use_markup">True</property>
|
287
417
|
</object>
|
288
|
-
<packing>
|
289
|
-
<property name="expand">False</property>
|
290
|
-
<property name="fill">False</property>
|
291
|
-
<property name="position">0</property>
|
292
|
-
</packing>
|
293
418
|
</child>
|
294
419
|
</object>
|
295
420
|
<packing>
|
@@ -298,6 +423,18 @@
|
|
298
423
|
<property name="position">3</property>
|
299
424
|
</packing>
|
300
425
|
</child>
|
426
|
+
<child>
|
427
|
+
<object class="GtkStatusbar" id="statusbar">
|
428
|
+
<property name="visible">True</property>
|
429
|
+
<property name="can_focus">False</property>
|
430
|
+
<property name="spacing">2</property>
|
431
|
+
</object>
|
432
|
+
<packing>
|
433
|
+
<property name="expand">False</property>
|
434
|
+
<property name="fill">True</property>
|
435
|
+
<property name="position">4</property>
|
436
|
+
</packing>
|
437
|
+
</child>
|
301
438
|
</object>
|
302
439
|
</child>
|
303
440
|
</object>
|
data/glade/win_preferences.glade
CHANGED
@@ -482,6 +482,126 @@
|
|
482
482
|
<property name="tab_fill">False</property>
|
483
483
|
</packing>
|
484
484
|
</child>
|
485
|
+
<child>
|
486
|
+
<object class="GtkVBox" id="vbox7">
|
487
|
+
<property name="visible">True</property>
|
488
|
+
<property name="can_focus">False</property>
|
489
|
+
<property name="spacing">3</property>
|
490
|
+
<child>
|
491
|
+
<object class="GtkTable" id="table4">
|
492
|
+
<property name="visible">True</property>
|
493
|
+
<property name="can_focus">False</property>
|
494
|
+
<property name="n_rows">2</property>
|
495
|
+
<property name="n_columns">2</property>
|
496
|
+
<property name="column_spacing">3</property>
|
497
|
+
<property name="row_spacing">3</property>
|
498
|
+
<child>
|
499
|
+
<object class="GtkCheckButton" id="cbAutoSync">
|
500
|
+
<property name="label" translatable="yes">Do automatic syncronization of data from OpenAll</property>
|
501
|
+
<property name="visible">True</property>
|
502
|
+
<property name="can_focus">True</property>
|
503
|
+
<property name="receives_default">False</property>
|
504
|
+
<property name="use_action_appearance">False</property>
|
505
|
+
<property name="draw_indicator">True</property>
|
506
|
+
</object>
|
507
|
+
<packing>
|
508
|
+
<property name="right_attach">2</property>
|
509
|
+
</packing>
|
510
|
+
</child>
|
511
|
+
<child>
|
512
|
+
<object class="GtkLabel" id="label15">
|
513
|
+
<property name="visible">True</property>
|
514
|
+
<property name="can_focus">False</property>
|
515
|
+
<property name="xalign">0</property>
|
516
|
+
<property name="label" translatable="yes">Interval (minutes)</property>
|
517
|
+
</object>
|
518
|
+
<packing>
|
519
|
+
<property name="top_attach">1</property>
|
520
|
+
<property name="bottom_attach">2</property>
|
521
|
+
<property name="x_options">GTK_FILL</property>
|
522
|
+
<property name="y_options">GTK_FILL</property>
|
523
|
+
</packing>
|
524
|
+
</child>
|
525
|
+
<child>
|
526
|
+
<object class="GtkEntry" id="txtAutoSyncInterval">
|
527
|
+
<property name="visible">True</property>
|
528
|
+
<property name="can_focus">True</property>
|
529
|
+
<property name="invisible_char">•</property>
|
530
|
+
<property name="primary_icon_activatable">False</property>
|
531
|
+
<property name="secondary_icon_activatable">False</property>
|
532
|
+
<property name="primary_icon_sensitive">True</property>
|
533
|
+
<property name="secondary_icon_sensitive">True</property>
|
534
|
+
</object>
|
535
|
+
<packing>
|
536
|
+
<property name="left_attach">1</property>
|
537
|
+
<property name="right_attach">2</property>
|
538
|
+
<property name="top_attach">1</property>
|
539
|
+
<property name="bottom_attach">2</property>
|
540
|
+
</packing>
|
541
|
+
</child>
|
542
|
+
</object>
|
543
|
+
<packing>
|
544
|
+
<property name="expand">False</property>
|
545
|
+
<property name="fill">True</property>
|
546
|
+
<property name="position">0</property>
|
547
|
+
</packing>
|
548
|
+
</child>
|
549
|
+
<child>
|
550
|
+
<object class="GtkHButtonBox" id="hbuttonbox4">
|
551
|
+
<property name="visible">True</property>
|
552
|
+
<property name="can_focus">False</property>
|
553
|
+
<property name="spacing">3</property>
|
554
|
+
<property name="layout_style">end</property>
|
555
|
+
<child>
|
556
|
+
<object class="GtkButton" id="btnAutoSyncSave">
|
557
|
+
<property name="label">gtk-save</property>
|
558
|
+
<property name="visible">True</property>
|
559
|
+
<property name="can_focus">True</property>
|
560
|
+
<property name="receives_default">True</property>
|
561
|
+
<property name="use_action_appearance">False</property>
|
562
|
+
<property name="use_stock">True</property>
|
563
|
+
<signal name="clicked" handler="on_btnAutoSyncSave_clicked" swapped="no"/>
|
564
|
+
</object>
|
565
|
+
<packing>
|
566
|
+
<property name="expand">False</property>
|
567
|
+
<property name="fill">False</property>
|
568
|
+
<property name="position">0</property>
|
569
|
+
</packing>
|
570
|
+
</child>
|
571
|
+
</object>
|
572
|
+
<packing>
|
573
|
+
<property name="expand">False</property>
|
574
|
+
<property name="fill">True</property>
|
575
|
+
<property name="position">1</property>
|
576
|
+
</packing>
|
577
|
+
</child>
|
578
|
+
<child>
|
579
|
+
<object class="GtkLabel" id="label14">
|
580
|
+
<property name="visible">True</property>
|
581
|
+
<property name="can_focus">False</property>
|
582
|
+
</object>
|
583
|
+
<packing>
|
584
|
+
<property name="expand">True</property>
|
585
|
+
<property name="fill">True</property>
|
586
|
+
<property name="position">2</property>
|
587
|
+
</packing>
|
588
|
+
</child>
|
589
|
+
</object>
|
590
|
+
<packing>
|
591
|
+
<property name="position">3</property>
|
592
|
+
</packing>
|
593
|
+
</child>
|
594
|
+
<child type="tab">
|
595
|
+
<object class="GtkLabel" id="label13">
|
596
|
+
<property name="visible">True</property>
|
597
|
+
<property name="can_focus">False</property>
|
598
|
+
<property name="label" translatable="yes">Automatic sync.</property>
|
599
|
+
</object>
|
600
|
+
<packing>
|
601
|
+
<property name="position">3</property>
|
602
|
+
<property name="tab_fill">False</property>
|
603
|
+
</packing>
|
604
|
+
</child>
|
485
605
|
</object>
|
486
606
|
</child>
|
487
607
|
</object>
|
data/gui/trayicon.rb
CHANGED
@@ -89,12 +89,16 @@ class Openall_time_applet::Gui::Trayicon
|
|
89
89
|
|
90
90
|
#Make a list of all timelogs in the menu.
|
91
91
|
@args[:oata].ob.list(:Timelog, {"orderby" => "id"}) do |timelog|
|
92
|
-
label =
|
92
|
+
label = timelog.descr_short
|
93
93
|
|
94
94
|
#If this is the active timelog, make the label bold, by getting the label-child and using HTML-markup on it.
|
95
95
|
if @args[:oata].timelog_active and @args[:oata].timelog_active.id == timelog.id
|
96
96
|
mi = Gtk::ImageMenuItem.new(Gtk::Stock::MEDIA_RECORD)
|
97
|
-
|
97
|
+
|
98
|
+
secs = Time.now.to_i - @args[:oata].timelog_active_time.to_i
|
99
|
+
mins = (secs.to_f / 60.0).round(0)
|
100
|
+
|
101
|
+
mi.children[0].markup = "<b>#{Knj::Web.html(label)} (#{mins})</b>"
|
98
102
|
mi.signal_connect("activate", &self.method(:on_stopTracking_activate))
|
99
103
|
else
|
100
104
|
mi = Gtk::MenuItem.new(label)
|
@@ -107,16 +111,37 @@ class Openall_time_applet::Gui::Trayicon
|
|
107
111
|
menu.append(mi)
|
108
112
|
end
|
109
113
|
|
110
|
-
|
111
|
-
|
114
|
+
|
115
|
+
#Start-menu-item. Opens main-window, expands treeview and calls the plus-button which adds a new timelog and focuses treeview.
|
116
|
+
start = Gtk::ImageMenuItem.new(Gtk::Stock::NEW)
|
117
|
+
start.children[0].label = _("New")
|
118
|
+
start.signal_connect(:activate) do
|
119
|
+
#Open main-window and focus it.
|
120
|
+
@args[:oata].show_main
|
121
|
+
|
122
|
+
#Get main-window-object.
|
123
|
+
win_main = Knj::Gtk2::Window.get("main")
|
112
124
|
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
125
|
+
if !win_main.gui["expOverview"].expanded?
|
126
|
+
#If the expander isnt expanded, call the activate and wait a bit before calling the plus-button.
|
127
|
+
win_main.gui["expOverview"].activate
|
128
|
+
|
129
|
+
Gtk.timeout_add(250) do
|
130
|
+
#Make a "plus"-click which adds a new task.
|
131
|
+
win_main.gui["btnPlus"].clicked
|
132
|
+
false
|
133
|
+
end
|
134
|
+
else
|
135
|
+
#If the expander is already expanded, then call the plus-button instantly to prevent the "laggy" feeling that would otherwise have occurred because of the timeout.
|
136
|
+
win_main.gui["btnPlus"].clicked
|
137
|
+
end
|
118
138
|
end
|
119
139
|
|
140
|
+
menu.append(Gtk::SeparatorMenuItem.new)
|
141
|
+
menu.append(start)
|
142
|
+
|
143
|
+
|
144
|
+
#Show the menu and position it correctly (bug with Gnome Shell where popup would be placed under bottom panel, if it isnt done this way by calling 'position_menu').
|
120
145
|
menu.show_all
|
121
146
|
|
122
147
|
menu.popup(nil, nil, button, time) do |menu, x, y|
|
data/gui/win_main.rb
CHANGED
@@ -90,7 +90,7 @@ class Openall_time_applet::Gui::Win_main
|
|
90
90
|
:model_class => :Timelog,
|
91
91
|
:renderers => init_data[:renderers],
|
92
92
|
:change_before => proc{|d|
|
93
|
-
if (d[:col_no] == 3 or d[:col_no] == 2) and @args[:oata].timelog_active and @args[:oata].timelog_active.id == d[:model].id
|
93
|
+
if (d[:col_no] == 11 or d[:col_no] == 3 or d[:col_no] == 2) and @args[:oata].timelog_active and @args[:oata].timelog_active.id == d[:model].id
|
94
94
|
raise _("You cannot edit the time for the active timelog.")
|
95
95
|
end
|
96
96
|
|
@@ -126,29 +126,65 @@ class Openall_time_applet::Gui::Win_main
|
|
126
126
|
}
|
127
127
|
)
|
128
128
|
|
129
|
+
|
130
|
+
#The ID column should not be visible (it is only used to identify which timelog the row represents).
|
129
131
|
@gui["tvTimelogs"].columns[0].visible = false
|
130
132
|
|
133
|
+
|
134
|
+
#Connect certain column renderers to the editingStarted-method, so editing can be canceled, if the user tries to edit forbidden data on the active timelog.
|
135
|
+
init_data[:renderers][1].signal_connect_after("editing-started", :descr, &self.method(:on_cell_editingStarted))
|
136
|
+
init_data[:renderers][2].signal_connect_after("editing-started", :timestamp, &self.method(:on_cell_editingStarted))
|
137
|
+
init_data[:renderers][3].signal_connect_after("editing-started", :time, &self.method(:on_cell_editingStarted))
|
138
|
+
init_data[:renderers][11].signal_connect_after("editing-started", :task, &self.method(:on_cell_editingStarted))
|
139
|
+
|
140
|
+
|
141
|
+
#Fills the timelogs-treeview with data.
|
131
142
|
self.reload_timelogs
|
132
143
|
|
144
|
+
|
133
145
|
#Reload the treeview if something happened to a timelog.
|
134
146
|
@reload_id = @args[:oata].ob.connect("object" => :Timelog, "signals" => ["add", "update", "delete"], &self.method(:reload_timelogs))
|
135
147
|
|
148
|
+
|
136
149
|
#Update switch-button.
|
137
150
|
self.update_switch_button
|
138
151
|
|
152
|
+
|
139
153
|
#Update switch-button when active timelog is changed.
|
140
154
|
@event_timelog_active_changed = @args[:oata].events.connect(:timelog_active_changed) do
|
141
155
|
self.update_switch_button
|
142
156
|
self.check_rows
|
157
|
+
self.timelog_info_trigger
|
143
158
|
end
|
144
159
|
|
160
|
+
|
161
|
+
#This timeout controls the updating of the timelog-info-frame and the time-counter for the active timelog in the treeview.
|
145
162
|
@timeout_id = Gtk.timeout_add(1000) do
|
146
163
|
self.check_rows
|
164
|
+
self.timelog_info_trigger
|
165
|
+
true
|
147
166
|
end
|
148
167
|
|
168
|
+
|
169
|
+
#Show the window.
|
149
170
|
@gui["window"].show_all
|
171
|
+
self.timelog_info_trigger
|
172
|
+
width = @gui["window"].size[0]
|
173
|
+
@gui["window"].resize(width, 1)
|
150
174
|
end
|
151
175
|
|
176
|
+
#This method is called, when editting starts in a description-, time- or task-cell. If it is the active timelog, then editting is canceled.
|
177
|
+
def on_cell_editingStarted(renderer, editable, path, col_title)
|
178
|
+
iter = @gui["tvTimelogs"].model.get_iter(path)
|
179
|
+
timelog_id = @gui["tvTimelogs"].model.get_value(iter, 0).to_i
|
180
|
+
|
181
|
+
if tlog = @args[:oata].timelog_active and tlog.id.to_i == timelog_id
|
182
|
+
renderer.stop_editing(true)
|
183
|
+
Knj::Gtk2.msgbox(_("You cannot edit this on the active timelog."))
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
#This method is used to do stuff without having the treeview reloading. It executes the given block and then makes the treeview reloadable again.
|
152
188
|
def dont_reload
|
153
189
|
@dont_reload = true
|
154
190
|
begin
|
@@ -220,18 +256,45 @@ class Openall_time_applet::Gui::Win_main
|
|
220
256
|
end
|
221
257
|
|
222
258
|
def on_expOverview_activate(expander)
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
@gui["window"].resize(width, 480)
|
259
|
+
if expander.expanded?
|
260
|
+
@gui["window"].resize(@gui["window"].size[0], 480)
|
261
|
+
self.timelog_info_trigger
|
227
262
|
else
|
228
263
|
Gtk.timeout_add(200) do
|
229
|
-
|
264
|
+
self.timelog_info_trigger
|
265
|
+
@gui["window"].resize(@gui["window"].size[0], 1)
|
230
266
|
false
|
231
267
|
end
|
232
268
|
end
|
233
269
|
end
|
234
270
|
|
271
|
+
#This method handles the "Timelog info"-frame. Hides, shows and updates the info in it.
|
272
|
+
def timelog_info_trigger
|
273
|
+
if !@gui["expOverview"].expanded? and tlog = @args[:oata].timelog_active
|
274
|
+
@gui["labTimelogInfoDescr"].markup = "<b>#{Knj::Web.html(tlog[:descr])}</b>"
|
275
|
+
|
276
|
+
task = tlog.task
|
277
|
+
if !task
|
278
|
+
task_text = "[#{_("no task sat on the timelog")}]"
|
279
|
+
else
|
280
|
+
task_text = task.name
|
281
|
+
end
|
282
|
+
|
283
|
+
@gui["labTimelogInfoTask"].markup = "<b>#{Knj::Web.html(task_text)}</b>"
|
284
|
+
|
285
|
+
time_tracked = Knj::Strings.secs_to_human_time_str(@args[:oata].timelog_active_time_tracked + tlog[:time].to_i)
|
286
|
+
@gui["labTimelogInfoTime"].markup = "<b>#{Knj::Web.html(time_tracked)}</b>"
|
287
|
+
|
288
|
+
@gui["frameTimelogInfo"].show_all
|
289
|
+
else
|
290
|
+
visible = @gui["frameTimelogInfo"].visible?
|
291
|
+
@gui["frameTimelogInfo"].hide
|
292
|
+
|
293
|
+
#Resize to minimum height, so a big space isnt left.
|
294
|
+
@gui["window"].resize(@gui["window"].size[0], 1) if visible and !@gui["expOverview"].expanded?
|
295
|
+
end
|
296
|
+
end
|
297
|
+
|
235
298
|
def on_btnSwitch_clicked
|
236
299
|
if @args[:oata].timelog_active
|
237
300
|
@args[:oata].timelog_stop_tracking
|
@@ -306,9 +369,11 @@ class Openall_time_applet::Gui::Win_main
|
|
306
369
|
end
|
307
370
|
|
308
371
|
def on_btnSync_clicked
|
309
|
-
@args[:oata].
|
310
|
-
|
311
|
-
|
372
|
+
@args[:oata].show_prepare_sync
|
373
|
+
end
|
374
|
+
|
375
|
+
def on_miSyncStatic_activate
|
376
|
+
@args[:oata].sync_static("transient_for" => @gui["window"])
|
312
377
|
end
|
313
378
|
|
314
379
|
def on_btnMinus_clicked
|
data/gui/win_preferences.rb
CHANGED
@@ -30,6 +30,10 @@ class Openall_time_applet::Gui::Win_preferences
|
|
30
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
|
+
|
34
|
+
#Autosync settings.
|
35
|
+
@gui["cbAutoSync"].active = Knj::Strings.yn_str(Knj::Opts.get("autosync_enabled"), true, false)
|
36
|
+
@gui["txtAutoSyncInterval"].text = Knj::Opts.get("autosync_interval")
|
33
37
|
end
|
34
38
|
|
35
39
|
#Saves values from widgets into database.
|
@@ -99,4 +103,19 @@ class Openall_time_applet::Gui::Win_preferences
|
|
99
103
|
end
|
100
104
|
end
|
101
105
|
end
|
106
|
+
|
107
|
+
def on_btnAutoSyncSave_clicked
|
108
|
+
interval = @gui["txtAutoSyncInterval"].text
|
109
|
+
if !Knj::Php.is_numeric(interval)
|
110
|
+
Knj::Gtk2.msgbox(_("The interval was not numeric."))
|
111
|
+
return false
|
112
|
+
end
|
113
|
+
|
114
|
+
Knj::Opts.set("autosync_enabled", Knj::Strings.yn_str(@gui["cbAutoSync"].active?, 1, 0))
|
115
|
+
Knj::Opts.set("autosync_interval", interval)
|
116
|
+
|
117
|
+
@args[:oata].restart_autosync
|
118
|
+
|
119
|
+
Knj::Gtk2.msgbox("msg" => _("The auto. sync. preferences was saved."), "type" => "info")
|
120
|
+
end
|
102
121
|
end
|
data/lib/openall_time_applet.rb
CHANGED
@@ -117,6 +117,9 @@ class Openall_time_applet
|
|
117
117
|
|
118
118
|
#Start unix-socket that listens for remote control.
|
119
119
|
@unix_socket = Openall_time_applet::Unix_socket.new(:oata => self)
|
120
|
+
|
121
|
+
#Start autosync-timeout.
|
122
|
+
self.restart_autosync
|
120
123
|
end
|
121
124
|
|
122
125
|
#Creates a runfile or sending a command to the running OpenAll-Time-Applet through the Unix-socket.
|
@@ -306,7 +309,7 @@ class Openall_time_applet
|
|
306
309
|
end
|
307
310
|
|
308
311
|
#Shows the sync overview, which must be seen before the actual sync.
|
309
|
-
def
|
312
|
+
def show_prepare_sync
|
310
313
|
Openall_time_applet::Gui::Win_sync_overview.new(:oata => self)
|
311
314
|
end
|
312
315
|
|
@@ -401,6 +404,62 @@ class Openall_time_applet
|
|
401
404
|
Gtk.main_quit if @quit != true
|
402
405
|
@quit = true
|
403
406
|
end
|
407
|
+
|
408
|
+
#Restarts the auto-syncing timeout.
|
409
|
+
def restart_autosync
|
410
|
+
#Remove current timeout.
|
411
|
+
Gtk.timeout_remove(@autosync_timeout) if @autosync_timeout
|
412
|
+
@autosync_timeout = nil
|
413
|
+
|
414
|
+
#Get various info from db.
|
415
|
+
enabled = Knj::Strings.yn_str(Knj::Opts.get("autosync_enabled"), true, false)
|
416
|
+
interval = Knj::Opts.get("autosync_interval").to_i
|
417
|
+
interval_msecs = interval * 60 * 1000
|
418
|
+
|
419
|
+
if !enabled #dont continue if autosync isnt enabled.
|
420
|
+
self.status = _("Disabled automatic synchronization.")
|
421
|
+
return nil
|
422
|
+
end
|
423
|
+
|
424
|
+
self.status = sprintf(_("Restarted automatic sync. to run every %s minutes."), Knj::Locales.number_out(interval, 1))
|
425
|
+
|
426
|
+
#Start new timeout.
|
427
|
+
@autosync_timeout = Gtk.timeout_add(interval_msecs) do
|
428
|
+
if !@sync_thread
|
429
|
+
@sync_thread = Knj::Thread.new(&self.method(:run_autosync))
|
430
|
+
end
|
431
|
+
|
432
|
+
true
|
433
|
+
end
|
434
|
+
end
|
435
|
+
|
436
|
+
#This method is executing the automatic synchronization.
|
437
|
+
def run_autosync
|
438
|
+
begin
|
439
|
+
self.status = _("Synchronizing organisations.")
|
440
|
+
self.update_organisation_cache
|
441
|
+
|
442
|
+
self.status = _("Synchronizing worktime.")
|
443
|
+
self.update_worktime_cache
|
444
|
+
|
445
|
+
self.status = _("Automatic synchronization done.")
|
446
|
+
rescue => e
|
447
|
+
self.status = sprintf(_("Error while auto-syncing: %s"), e.message)
|
448
|
+
puts Knj::Errors.error_str(e)
|
449
|
+
ensure
|
450
|
+
@sync_thread = nil
|
451
|
+
end
|
452
|
+
end
|
453
|
+
|
454
|
+
#Prints status to the command line and the statusbar in the main window (if the main window is open).
|
455
|
+
def status=(newstatus)
|
456
|
+
puts "Status: '#{newstatus}'."
|
457
|
+
win_main = Knj::Gtk2::Window.get("main")
|
458
|
+
|
459
|
+
if win_main
|
460
|
+
win_main.gui["statusbar"].push(0, newstatus)
|
461
|
+
end
|
462
|
+
end
|
404
463
|
end
|
405
464
|
|
406
465
|
#Gettext support.
|
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.17"
|
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-06-
|
12
|
+
s.date = %q{2012-06-29}
|
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}
|
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.17
|
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-06-
|
13
|
+
date: 2012-06-29 00:00:00 +02:00
|
14
14
|
default_executable: openall_time_applet.rb
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
@@ -196,7 +196,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
196
196
|
requirements:
|
197
197
|
- - ">="
|
198
198
|
- !ruby/object:Gem::Version
|
199
|
-
hash:
|
199
|
+
hash: -398963777850608738
|
200
200
|
segments:
|
201
201
|
- 0
|
202
202
|
version: "0"
|