NowFocus 0.2.6__tar.gz → 0.2.8__tar.gz

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.
Files changed (63) hide show
  1. {nowfocus-0.2.6/src/nowfocus.egg-info → nowfocus-0.2.8}/PKG-INFO +16 -18
  2. {nowfocus-0.2.6 → nowfocus-0.2.8}/README.md +15 -17
  3. {nowfocus-0.2.6 → nowfocus-0.2.8}/pyproject.toml +1 -1
  4. {nowfocus-0.2.6 → nowfocus-0.2.8}/src/nowfocus/__main__.py +13 -9
  5. {nowfocus-0.2.6 → nowfocus-0.2.8}/src/nowfocus/connectors/trello.py +6 -6
  6. nowfocus-0.2.8/src/nowfocus/icon/icon-red.svg +101 -0
  7. {nowfocus-0.2.6 → nowfocus-0.2.8}/src/nowfocus/icon/icon.svg +12 -1
  8. {nowfocus-0.2.6 → nowfocus-0.2.8}/src/nowfocus/settings.py +3 -3
  9. {nowfocus-0.2.6 → nowfocus-0.2.8}/src/nowfocus/task_window.py +133 -106
  10. {nowfocus-0.2.6 → nowfocus-0.2.8}/src/nowfocus/utils.py +4 -2
  11. {nowfocus-0.2.6 → nowfocus-0.2.8/src/nowfocus.egg-info}/PKG-INFO +16 -18
  12. {nowfocus-0.2.6 → nowfocus-0.2.8}/src/nowfocus.egg-info/SOURCES.txt +1 -1
  13. nowfocus-0.2.6/src/nowfocus/desktop-extras/set_gsettings_keybinding.sh +0 -51
  14. {nowfocus-0.2.6 → nowfocus-0.2.8}/LICENSE +0 -0
  15. {nowfocus-0.2.6 → nowfocus-0.2.8}/setup.cfg +0 -0
  16. {nowfocus-0.2.6 → nowfocus-0.2.8}/src/nowfocus/__init__.py +0 -0
  17. {nowfocus-0.2.6 → nowfocus-0.2.8}/src/nowfocus/conf.py +0 -0
  18. {nowfocus-0.2.6 → nowfocus-0.2.8}/src/nowfocus/connectors/activitywatch.py +0 -0
  19. {nowfocus-0.2.6 → nowfocus-0.2.8}/src/nowfocus/connectors/caldav.py +0 -0
  20. {nowfocus-0.2.6 → nowfocus-0.2.8}/src/nowfocus/connectors/csv.py +0 -0
  21. {nowfocus-0.2.6 → nowfocus-0.2.8}/src/nowfocus/connectors/psc_timetracker.py +0 -0
  22. {nowfocus-0.2.6 → nowfocus-0.2.8}/src/nowfocus/connectors/taskwarrior.py +0 -0
  23. {nowfocus-0.2.6 → nowfocus-0.2.8}/src/nowfocus/connectors/timewarrior.py +0 -0
  24. {nowfocus-0.2.6 → nowfocus-0.2.8}/src/nowfocus/connectors/todo_template.py +0 -0
  25. {nowfocus-0.2.6 → nowfocus-0.2.8}/src/nowfocus/connectors/todotxt.py +0 -0
  26. {nowfocus-0.2.6 → nowfocus-0.2.8}/src/nowfocus/connectors/txt.py +0 -0
  27. {nowfocus-0.2.6 → nowfocus-0.2.8}/src/nowfocus/connectors/vikunja.py +0 -0
  28. {nowfocus-0.2.6 → nowfocus-0.2.8}/src/nowfocus/desktop-extras/nowfocus.desktop +0 -0
  29. {nowfocus-0.2.6 → nowfocus-0.2.8}/src/nowfocus/desktop-extras/nowfocus.png +0 -0
  30. {nowfocus-0.2.6 → nowfocus-0.2.8}/src/nowfocus/desktop-extras/nowfocus.svg +0 -0
  31. {nowfocus-0.2.6 → nowfocus-0.2.8}/src/nowfocus/example-todo.txt +0 -0
  32. {nowfocus-0.2.6 → nowfocus-0.2.8}/src/nowfocus/icon/cancel.png +0 -0
  33. {nowfocus-0.2.6 → nowfocus-0.2.8}/src/nowfocus/icon/cancel.svg +0 -0
  34. {nowfocus-0.2.6 → nowfocus-0.2.8}/src/nowfocus/icon/edit.png +0 -0
  35. {nowfocus-0.2.6 → nowfocus-0.2.8}/src/nowfocus/icon/edit.svg +0 -0
  36. {nowfocus-0.2.6 → nowfocus-0.2.8}/src/nowfocus/icon/icon-0.svg +0 -0
  37. {nowfocus-0.2.6 → nowfocus-0.2.8}/src/nowfocus/icon/icon-1.svg +0 -0
  38. {nowfocus-0.2.6 → nowfocus-0.2.8}/src/nowfocus/icon/icon-2.svg +0 -0
  39. {nowfocus-0.2.6 → nowfocus-0.2.8}/src/nowfocus/icon/icon-3.svg +0 -0
  40. {nowfocus-0.2.6 → nowfocus-0.2.8}/src/nowfocus/icon/icon-4.svg +0 -0
  41. {nowfocus-0.2.6 → nowfocus-0.2.8}/src/nowfocus/icon/icon-5.svg +0 -0
  42. {nowfocus-0.2.6 → nowfocus-0.2.8}/src/nowfocus/icon/icon-6.svg +0 -0
  43. {nowfocus-0.2.6 → nowfocus-0.2.8}/src/nowfocus/icon/icon-7.svg +0 -0
  44. {nowfocus-0.2.6 → nowfocus-0.2.8}/src/nowfocus/icon/icon-8.svg +0 -0
  45. {nowfocus-0.2.6 → nowfocus-0.2.8}/src/nowfocus/icon/icon-9.svg +0 -0
  46. {nowfocus-0.2.6 → nowfocus-0.2.8}/src/nowfocus/icon/mark-done.png +0 -0
  47. {nowfocus-0.2.6 → nowfocus-0.2.8}/src/nowfocus/icon/mark-done.svg +0 -0
  48. {nowfocus-0.2.6 → nowfocus-0.2.8}/src/nowfocus/icon/pause.png +0 -0
  49. {nowfocus-0.2.6 → nowfocus-0.2.8}/src/nowfocus/icon/pause.svg +0 -0
  50. {nowfocus-0.2.6 → nowfocus-0.2.8}/src/nowfocus/icon/settings.png +0 -0
  51. {nowfocus-0.2.6 → nowfocus-0.2.8}/src/nowfocus/icon/settings.svg +0 -0
  52. {nowfocus-0.2.6 → nowfocus-0.2.8}/src/nowfocus/new_task_dialog.py +0 -0
  53. {nowfocus-0.2.6 → nowfocus-0.2.8}/src/nowfocus/session_edit_dialog.py +0 -0
  54. {nowfocus-0.2.6 → nowfocus-0.2.8}/src/nowfocus/session_options.py +0 -0
  55. {nowfocus-0.2.6 → nowfocus-0.2.8}/src/nowfocus/sessions.csv +0 -0
  56. {nowfocus-0.2.6 → nowfocus-0.2.8}/src/nowfocus/sound/bell-xylophone-g.mp3 +0 -0
  57. {nowfocus-0.2.6 → nowfocus-0.2.8}/src/nowfocus/sound/dinner-bell.mp3 +0 -0
  58. {nowfocus-0.2.6 → nowfocus-0.2.8}/src/nowfocus/sound/xylophone-chord.mp3 +0 -0
  59. {nowfocus-0.2.6 → nowfocus-0.2.8}/src/nowfocus/styles.css +0 -0
  60. {nowfocus-0.2.6 → nowfocus-0.2.8}/src/nowfocus.egg-info/dependency_links.txt +0 -0
  61. {nowfocus-0.2.6 → nowfocus-0.2.8}/src/nowfocus.egg-info/entry_points.txt +0 -0
  62. {nowfocus-0.2.6 → nowfocus-0.2.8}/src/nowfocus.egg-info/requires.txt +0 -0
  63. {nowfocus-0.2.6 → nowfocus-0.2.8}/src/nowfocus.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: nowfocus
3
- Version: 0.2.6
3
+ Version: 0.2.8
4
4
  Summary: nowfocus: the open source task-tracking self-control panel.
5
5
  Author: GitFr33
6
6
  Project-URL: Homepage, https://gitlab.com/GitFr33/nowfocus
@@ -92,12 +92,12 @@ nowfocus is a clean, keyboard-driven project time tracker build with python + GT
92
92
  - [TimeWarrior](https://timewarrior.net)
93
93
 
94
94
 
95
- ## Installation (using pipx)
95
+ ## Installation
96
96
 
97
- Run the following in terminal to install and setup:
97
+ 1. Run the following in terminal to install and setup:
98
98
  ```
99
99
  # Install dependencies
100
- sudo apt install pip pipx gir1.2-appindicator3-0.1 meson libdbus-glib-1-dev patchelf libgirepository1.0-dev gcc libcairo2-dev pkg-config python3-dev
100
+ sudo apt install pipx gir1.2-appindicator3-0.1 meson libdbus-glib-1-dev patchelf libgirepository1.0-dev gcc libcairo2-dev pkg-config python3-dev
101
101
 
102
102
  # Set up pipx
103
103
  pipx ensurepath
@@ -108,26 +108,21 @@ pipx ensurepath
108
108
  pipx install nowfocus
109
109
 
110
110
  # Enter application directory
111
- cd ~/.local/share/pipx/venvs/nowfocus/lib/python3.12/site-packages/nowfocus
111
+ cd ~/.local/share/pipx/venvs/nowfocus/lib/python3.12/site-packages/nowfocus/desktop-extras
112
112
 
113
- # Copy .desktop and icon to .local/share
114
- cp src/desktop-extras/nowfocus.desktop ~/.local/share/applications/nowfocus.desktop
115
- cp src/desktop-extras/nowfocus.svg ~/.local/share/icons/nowfocus.png
116
- cp src/desktop-extras/nowfocus.svg ~/.local/share/icons/hicolor/scalable/apps/nowfocus.svg
117
-
118
- # Setup autostart
119
- cp src/desktop-extras/nowfocus.desktop ~/.config/autostart/nowfocus.desktop
120
-
121
- # Set Super space as keybinding to raise task window
122
- chmod +x src/desktop-extras/set_gsettings_keybinding.sh
123
-
124
- src/desktop-extras/set_gsettings_keybinding.sh "Open nowfocus" nowfocus "<Super>space"
113
+ # Copy .desktop and icon to /usr/share
114
+ sudo cp nowfocus.desktop /usr/share/applications/nowfocus.desktop
115
+ sudo cp nowfocus.svg /usr/share/icons/hicolor/scalable/apps/nowfocus.svg
125
116
 
126
117
  # and now Focus!
127
118
  nowfocus
128
119
 
129
120
  ```
130
121
 
122
+ 2. Set up a keybinding (on Ubuntu or Linux Mint), open **Settings > Keyboard > Keyboard Shortcuts > Custom Shortcuts**, set the **command** to `nowfocus`, and pick whatever key combo you'd like.
123
+
124
+ 3. Add the following command to your startup applications: `nowfocus --force`
125
+
131
126
 
132
127
 
133
128
  ## Usage
@@ -140,7 +135,10 @@ Open nowfocus **Settings** from the indicator menu or tasks window and connect y
140
135
 
141
136
  - `F11` Toggle fullscreen
142
137
  - `Esc` Close task window
143
- - `Enter` Start top task (or make a new task with current search phrase if no results)
138
+ - `Enter` Start top/selected task (or make a new task with current search phrase if no results)
139
+ - `Shift Enter` or `Shift Click` Transfer current session time to selected task (or top task if none selected)
140
+ - `Control Enter` or `Control Click` show opetions menu for selected (or top) task
141
+ - `Alt Enter` or `Alt Click` Open todolist for selected (or top) task
144
142
  - `Ctrl + P` **Pause** current task
145
143
  - `Ctrl + D` Pause current task and mark it **Done**
146
144
  - `Ctrl + X` Cancel current task
@@ -46,12 +46,12 @@ nowfocus is a clean, keyboard-driven project time tracker build with python + GT
46
46
  - [TimeWarrior](https://timewarrior.net)
47
47
 
48
48
 
49
- ## Installation (using pipx)
49
+ ## Installation
50
50
 
51
- Run the following in terminal to install and setup:
51
+ 1. Run the following in terminal to install and setup:
52
52
  ```
53
53
  # Install dependencies
54
- sudo apt install pip pipx gir1.2-appindicator3-0.1 meson libdbus-glib-1-dev patchelf libgirepository1.0-dev gcc libcairo2-dev pkg-config python3-dev
54
+ sudo apt install pipx gir1.2-appindicator3-0.1 meson libdbus-glib-1-dev patchelf libgirepository1.0-dev gcc libcairo2-dev pkg-config python3-dev
55
55
 
56
56
  # Set up pipx
57
57
  pipx ensurepath
@@ -62,26 +62,21 @@ pipx ensurepath
62
62
  pipx install nowfocus
63
63
 
64
64
  # Enter application directory
65
- cd ~/.local/share/pipx/venvs/nowfocus/lib/python3.12/site-packages/nowfocus
65
+ cd ~/.local/share/pipx/venvs/nowfocus/lib/python3.12/site-packages/nowfocus/desktop-extras
66
66
 
67
- # Copy .desktop and icon to .local/share
68
- cp src/desktop-extras/nowfocus.desktop ~/.local/share/applications/nowfocus.desktop
69
- cp src/desktop-extras/nowfocus.svg ~/.local/share/icons/nowfocus.png
70
- cp src/desktop-extras/nowfocus.svg ~/.local/share/icons/hicolor/scalable/apps/nowfocus.svg
71
-
72
- # Setup autostart
73
- cp src/desktop-extras/nowfocus.desktop ~/.config/autostart/nowfocus.desktop
74
-
75
- # Set Super space as keybinding to raise task window
76
- chmod +x src/desktop-extras/set_gsettings_keybinding.sh
77
-
78
- src/desktop-extras/set_gsettings_keybinding.sh "Open nowfocus" nowfocus "<Super>space"
67
+ # Copy .desktop and icon to /usr/share
68
+ sudo cp nowfocus.desktop /usr/share/applications/nowfocus.desktop
69
+ sudo cp nowfocus.svg /usr/share/icons/hicolor/scalable/apps/nowfocus.svg
79
70
 
80
71
  # and now Focus!
81
72
  nowfocus
82
73
 
83
74
  ```
84
75
 
76
+ 2. Set up a keybinding (on Ubuntu or Linux Mint), open **Settings > Keyboard > Keyboard Shortcuts > Custom Shortcuts**, set the **command** to `nowfocus`, and pick whatever key combo you'd like.
77
+
78
+ 3. Add the following command to your startup applications: `nowfocus --force`
79
+
85
80
 
86
81
 
87
82
  ## Usage
@@ -94,7 +89,10 @@ Open nowfocus **Settings** from the indicator menu or tasks window and connect y
94
89
 
95
90
  - `F11` Toggle fullscreen
96
91
  - `Esc` Close task window
97
- - `Enter` Start top task (or make a new task with current search phrase if no results)
92
+ - `Enter` Start top/selected task (or make a new task with current search phrase if no results)
93
+ - `Shift Enter` or `Shift Click` Transfer current session time to selected task (or top task if none selected)
94
+ - `Control Enter` or `Control Click` show opetions menu for selected (or top) task
95
+ - `Alt Enter` or `Alt Click` Open todolist for selected (or top) task
98
96
  - `Ctrl + P` **Pause** current task
99
97
  - `Ctrl + D` Pause current task and mark it **Done**
100
98
  - `Ctrl + X` Cancel current task
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "nowfocus"
3
- version = "0.2.6"
3
+ version = "0.2.8"
4
4
  authors = [
5
5
  { name="GitFr33" },
6
6
  ]
@@ -73,7 +73,7 @@ class Application(Gtk.Application):
73
73
  self.menu_tasks = {}
74
74
  self.list_menus = {}
75
75
 
76
- self.indicator = appindicator.Indicator.new(conf.app_name, os.path.abspath('icon/icon-0.svg'), appindicator.IndicatorCategory.APPLICATION_STATUS)
76
+ self.indicator = appindicator.Indicator.new(conf.app_name, os.path.abspath('icon/icon-1.svg'), appindicator.IndicatorCategory.APPLICATION_STATUS)
77
77
 
78
78
  self.indicator.set_status(appindicator.IndicatorStatus.ACTIVE)
79
79
 
@@ -156,8 +156,8 @@ class Application(Gtk.Application):
156
156
 
157
157
  def quit(self, widget_or_signal_source=None, condition=None):
158
158
  print("Adios ", conf.app_name)
159
- print("widget_or_signal_source ", widget_or_signal_source)
160
- print("condition ", condition)
159
+ # print("widget_or_signal_source ", widget_or_signal_source)
160
+ # print("condition ", condition)
161
161
 
162
162
  if self.is_running:
163
163
  print('Caching active session', self.session['label'])
@@ -301,7 +301,7 @@ class Application(Gtk.Application):
301
301
  if(self.is_running == True):
302
302
  self.icon_tick_number = self.icon_tick_number + 1
303
303
 
304
- if self.icon_tick_number > 9:
304
+ if self.icon_tick_number > 8:
305
305
  self.icon_tick_number = 1
306
306
 
307
307
  label = self.session['label'] + ": " + sec_to_time(self.session['duration'])
@@ -312,8 +312,10 @@ class Application(Gtk.Application):
312
312
 
313
313
  # label = random.choice(conf.idle_messages) # Cool but makes menu bounce around #Could be paused when the menu opens
314
314
  label = conf.user['default_text']
315
-
316
- indicator.set_icon_full(os.path.abspath('icon/icon-0.svg'),label)
315
+ if self.session['duration'] > 60 and self.session['duration'] % 2:
316
+ indicator.set_icon_full(os.path.abspath('icon/icon-red.svg'),label)
317
+ else:
318
+ indicator.set_icon_full(os.path.abspath('icon/icon-1.svg'),label)
317
319
 
318
320
  # https://lazka.github.io/pgi-docs/#AyatanaAppIndicator3-0.1/classes/Indicator.html#AyatanaAppIndicator3.Indicator.set_label
319
321
  indicator.set_label(label, "Wide")
@@ -414,6 +416,7 @@ class Application(Gtk.Application):
414
416
 
415
417
  if process:
416
418
  print("waiting for already running command with psutils", command)
419
+ # subprocess.run('wmctrl', '-a', command) # Doesn't work on wayland
417
420
  process.wait()
418
421
  else:
419
422
  print("Launching command with subprocess.run", command)
@@ -484,7 +487,7 @@ class Application(Gtk.Application):
484
487
  self.mark_done(None,task)
485
488
 
486
489
  else:
487
- print("add ",utils.extended_label(task)," to recent tasks")
490
+ # print("add ",utils.extended_label(task)," to recent tasks")
488
491
  i = Gtk.MenuItem.new_with_label(utils.extended_label(task))
489
492
  i.connect('activate',self.start_task,task)
490
493
  list_menus['recent'].prepend(i)
@@ -511,8 +514,9 @@ class Application(Gtk.Application):
511
514
 
512
515
  self.is_running = False
513
516
  # print(utils.get_times(task))
514
-
515
- notify.Notification.new(action.capitalize()+" "+session['label']+" "+sec_to_time(session['duration']),utils.pretty_dict(utils.get_times(task)), None).show()
517
+ if action != 'cancel':
518
+ notify.Notification.new("Focused on "+session['label']+" for "+sec_to_time(session['duration']),utils.pretty_dict(utils.get_times(task)), None).show()
519
+ # notify.Notification.new(action.capitalize()+" "+session['label']+" "+sec_to_time(session['duration']),utils.pretty_dict(utils.get_times(task)), None).show()
516
520
 
517
521
  # Start randomness timer
518
522
  self.session = {
@@ -57,8 +57,8 @@ def get_todos(user_conf):
57
57
 
58
58
  for board in boards:
59
59
 
60
- print("\n\n--- Board --- \n")
61
- pretty_print(board)
60
+ # print("\n\n--- Board --- \n")
61
+ # pretty_print(board)
62
62
 
63
63
  if board['closed']:
64
64
  continue
@@ -80,8 +80,8 @@ def get_todos(user_conf):
80
80
 
81
81
  for bucket in board['lists']:
82
82
 
83
- print("\n\n--- bucket --- \n")
84
- pretty_print(bucket)
83
+ # print("\n\n--- bucket --- \n")
84
+ # pretty_print(bucket)
85
85
 
86
86
  if bucket['closed']:
87
87
  continue
@@ -216,8 +216,8 @@ def mark_task_done(task):
216
216
  params=query
217
217
  )
218
218
 
219
- print("response.text")
220
- print(response.text)
219
+ # print("response.text")
220
+ # print(response.text)
221
221
 
222
222
  return response.text
223
223
 
@@ -0,0 +1,101 @@
1
+ <?xml version="1.0" encoding="UTF-8" standalone="no"?>
2
+ <!-- Created with Inkscape (http://www.inkscape.org/) -->
3
+
4
+ <svg
5
+ width="48"
6
+ height="48"
7
+ viewBox="0 0 12.7 12.7"
8
+ version="1.1"
9
+ id="svg1"
10
+ xmlns="http://www.w3.org/2000/svg"
11
+ xmlns:svg="http://www.w3.org/2000/svg">
12
+ <defs
13
+ id="defs1" />
14
+ <g
15
+ id="layer1"
16
+ transform="matrix(1.0567177,0,0,1.0567177,-0.36015771,-0.36015771)">
17
+ <rect
18
+ style="display:none;opacity:1;fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:0.316;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"
19
+ id="rect1"
20
+ width="9.5708742"
21
+ height="9.5708742"
22
+ x="1.5645629"
23
+ y="1.5645629" />
24
+ <rect
25
+ style="display:none;opacity:1;fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:0.915798;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"
26
+ id="rect38"
27
+ width="9.5708742"
28
+ height="9.5708742"
29
+ x="1.5645629"
30
+ y="1.5645629"
31
+ ry="3.110863" />
32
+ <rect
33
+ style="display:inline;opacity:1;fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:0.915798;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"
34
+ id="rect2"
35
+ width="9.5708742"
36
+ height="9.5708742"
37
+ x="1.5645629"
38
+ y="1.5645629"
39
+ ry="4.7854371"
40
+ rx="4.7854371" />
41
+ </g>
42
+ <g
43
+ id="layer2"
44
+ style="display:inline">
45
+ <path
46
+ style="display:none;fill:none;stroke:#ffffff;stroke-width:1.465;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"
47
+ d="M 6.3410664,6.36546 4.4335013,4.0522236"
48
+ id="path2" />
49
+ <path
50
+ style="display:none;fill:none;stroke:#ffffff;stroke-width:1.465;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"
51
+ d="M 6.37713,6.3615649 11.260009,1.2965066"
52
+ id="use31" />
53
+ <path
54
+ style="display:none;fill:none;stroke:#ffffff;stroke-width:1.465;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"
55
+ d="M 6.3610066,6.3773634 13.39526,6.248543"
56
+ id="use32" />
57
+ <path
58
+ style="display:none;fill:none;stroke:#ffffff;stroke-width:1.465;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"
59
+ d="m 6.338434,6.3771308 5.065058,4.8828782"
60
+ id="use33" />
61
+ <path
62
+ style="display:none;fill:none;stroke:#ffffff;stroke-width:1.465;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"
63
+ d="M 6.322637,6.3610073 6.4514574,13.395261"
64
+ id="use34" />
65
+ <path
66
+ style="display:none;fill:none;stroke:#ffffff;stroke-width:1.465;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"
67
+ d="M 6.322869,6.3384356 1.4399903,11.403494"
68
+ id="use35" />
69
+ <path
70
+ style="display:none;fill:none;stroke:#ffffff;stroke-width:1.465;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"
71
+ d="M 6.3389932,6.3226376 -0.69526049,6.451458"
72
+ id="use36" />
73
+ <path
74
+ style="display:none;fill:none;stroke:#ffffff;stroke-width:1.465;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"
75
+ d="M 6.3615647,6.3228685 1.2965064,1.4399898"
76
+ id="use37" />
77
+ <path
78
+ style="display:none;fill:none;stroke:#ffffff;stroke-width:1.465;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"
79
+ d="M 6.3773615,6.3389927 6.2485411,-0.69526102"
80
+ id="use38" />
81
+ </g>
82
+ <g
83
+ id="layer3"
84
+ style="display:inline">
85
+ <rect
86
+ style="display:inline;opacity:1;fill:#ff0000;fill-opacity:1;stroke:#ff0000;stroke-width:0.915798;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"
87
+ id="rect3"
88
+ width="9.5708742"
89
+ height="9.5708742"
90
+ x="1.5645629"
91
+ y="1.5645629"
92
+ ry="4.7854371"
93
+ rx="4.7854371"
94
+ transform="matrix(1.0567177,0,0,1.0567177,-0.36015771,-0.36015771)" />
95
+ <path
96
+ style="font-weight:bold;font-size:10.4396px;line-height:1.25;font-family:'Besley*';-inkscape-font-specification:'Besley*, Bold';letter-spacing:0px;word-spacing:0px;fill:#ffffff;stroke-width:0.198419"
97
+ d="m 5.2723149,3.6126858 c 0,-0.040213 0.03016,-0.080427 0.1005332,-0.1407465 0.06032,-0.06032 0.1709064,-0.1105865 0.3116529,-0.1507998 0.1407465,-0.040213 0.2915463,-0.070373 0.4624528,-0.070373 0.4121862,0 0.6936791,0.1105865 0.8545323,0.3317595 0.1507998,0.2211731 0.2312264,0.5428794 0.2312264,0.9550655 0,0.4222395 -0.1206399,0.7640524 -0.3518663,1.0254388 -0.2412797,0.2613863 -0.5830926,0.4825594 -1.0254387,0.6434125 -0.03016,0.020106 -0.080427,0.040213 -0.1608531,0.06032 -0.080427,0.020106 -0.1306932,0.040213 -0.1407465,0.050267 -0.020106,0.010054 -0.040213,0.03016 -0.080427,0.070373 -0.040213,0.040213 -0.06032,0.080427 -0.06032,0.1407464 -0.010054,0.06032 -0.010054,0.1306932 -0.010054,0.2211731 v 0.8243723 c 0,0.080427 0.010054,0.1407465 0.050267,0.1608532 0.03016,0.020106 0.1005332,0.03016 0.2211731,0.03016 h 0.9852264 c 0.1608531,0 0.2613863,-0.010054 0.3015996,-0.040213 C 6.991433,7.6943348 7.01154,7.603855 7.01154,7.4430018 V 6.9906026 c 0,-0.070373 0,-0.1306932 0.010054,-0.1809598 0,-0.040213 0.010054,-0.080427 0.020106,-0.1105865 0.010054,-0.020106 0.03016,-0.050267 0.06032,-0.070373 0.03016,-0.020106 0.050267,-0.03016 0.070373,-0.040213 0.020106,0 0.050267,-0.010054 0.1105865,-0.03016 0.06032,-0.010054 0.1005332,-0.020106 0.1407465,-0.040213 C 7.9263916,6.3572424 8.3184711,6.1159627 8.6100174,5.7842031 8.9015637,5.4624969 9.0523635,5.0402574 9.0523635,4.5375913 c 0,-0.6233059 -0.221173,-1.1159186 -0.6635191,-1.4778381 -0.4423462,-0.3518663 -1.1159187,-0.532826 -2.0408242,-0.532826 -0.8042657,0 -1.4376249,0.2111197 -1.8900243,0.6132525 -0.4624528,0.4121862 -0.6836258,0.8746389 -0.6836258,1.3873583 0,0.3418129 0.090479,0.6132526 0.2915463,0.814319 0.2010664,0.2010664 0.4423461,0.3015996 0.7338924,0.3015996 0.2714397,0 0.502666,-0.080427 0.6936791,-0.251333 0.1809598,-0.1709064 0.281493,-0.3920795 0.281493,-0.6534658 0,-0.2010665 -0.050267,-0.3820262 -0.1306931,-0.5428794 C 5.5638612,4.0349253 5.4733813,3.9142854 5.3929547,3.8238056 5.3125282,3.7333257 5.2723149,3.6629524 5.2723149,3.6126858 Z m -0.050267,5.8510328 c 0,0.2814929 0.090479,0.5127198 0.2915463,0.7137864 0.2010664,0.201066 0.4322928,0.291546 0.7137858,0.291546 0.2714396,0 0.502666,-0.09048 0.7037324,-0.291546 C 7.1321792,9.9764384 7.2327125,9.7452115 7.2327125,9.4637186 7.2327125,9.1922789 7.1321792,8.9610525 6.9311128,8.7599861 6.7300464,8.5589197 6.49882,8.4583865 6.2273804,8.4583865 c -0.281493,0 -0.5127194,0.1005332 -0.7137858,0.3015996 C 5.3125282,8.9610525 5.2220483,9.1922789 5.2220479,9.4637186 Z"
98
+ id="text38"
99
+ aria-label="?" />
100
+ </g>
101
+ </svg>
@@ -9,7 +9,7 @@
9
9
  id="svg1"
10
10
  inkscape:version="1.3.2 (1:1.3.2+202404261509+091e20ef0f)"
11
11
  sodipodi:docname="icon.svg"
12
- inkscape:export-filename="icon-0.svg"
12
+ inkscape:export-filename="icon-red.svg"
13
13
  inkscape:export-xdpi="128"
14
14
  inkscape:export-ydpi="128"
15
15
  xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
@@ -185,6 +185,17 @@
185
185
  id="layer3"
186
186
  inkscape:label="?"
187
187
  style="display:inline">
188
+ <rect
189
+ style="display:inline;opacity:1;fill:#ff0000;fill-opacity:1;stroke:#ff0000;stroke-width:0.915798;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"
190
+ id="rect3"
191
+ width="9.5708742"
192
+ height="9.5708742"
193
+ x="1.5645629"
194
+ y="1.5645629"
195
+ inkscape:label="Red"
196
+ ry="4.7854371"
197
+ rx="4.7854371"
198
+ transform="matrix(1.0567177,0,0,1.0567177,-0.36015771,-0.36015771)" />
188
199
  <path
189
200
  style="font-weight:bold;font-size:10.4396px;line-height:1.25;font-family:'Besley*';-inkscape-font-specification:'Besley*, Bold';letter-spacing:0px;word-spacing:0px;fill:#ffffff;stroke-width:0.198419"
190
201
  d="m 5.2723149,3.6126858 c 0,-0.040213 0.03016,-0.080427 0.1005332,-0.1407465 0.06032,-0.06032 0.1709064,-0.1105865 0.3116529,-0.1507998 0.1407465,-0.040213 0.2915463,-0.070373 0.4624528,-0.070373 0.4121862,0 0.6936791,0.1105865 0.8545323,0.3317595 0.1507998,0.2211731 0.2312264,0.5428794 0.2312264,0.9550655 0,0.4222395 -0.1206399,0.7640524 -0.3518663,1.0254388 -0.2412797,0.2613863 -0.5830926,0.4825594 -1.0254387,0.6434125 -0.03016,0.020106 -0.080427,0.040213 -0.1608531,0.06032 -0.080427,0.020106 -0.1306932,0.040213 -0.1407465,0.050267 -0.020106,0.010054 -0.040213,0.03016 -0.080427,0.070373 -0.040213,0.040213 -0.06032,0.080427 -0.06032,0.1407464 -0.010054,0.06032 -0.010054,0.1306932 -0.010054,0.2211731 v 0.8243723 c 0,0.080427 0.010054,0.1407465 0.050267,0.1608532 0.03016,0.020106 0.1005332,0.03016 0.2211731,0.03016 h 0.9852264 c 0.1608531,0 0.2613863,-0.010054 0.3015996,-0.040213 C 6.991433,7.6943348 7.01154,7.603855 7.01154,7.4430018 V 6.9906026 c 0,-0.070373 0,-0.1306932 0.010054,-0.1809598 0,-0.040213 0.010054,-0.080427 0.020106,-0.1105865 0.010054,-0.020106 0.03016,-0.050267 0.06032,-0.070373 0.03016,-0.020106 0.050267,-0.03016 0.070373,-0.040213 0.020106,0 0.050267,-0.010054 0.1105865,-0.03016 0.06032,-0.010054 0.1005332,-0.020106 0.1407465,-0.040213 C 7.9263916,6.3572424 8.3184711,6.1159627 8.6100174,5.7842031 8.9015637,5.4624969 9.0523635,5.0402574 9.0523635,4.5375913 c 0,-0.6233059 -0.221173,-1.1159186 -0.6635191,-1.4778381 -0.4423462,-0.3518663 -1.1159187,-0.532826 -2.0408242,-0.532826 -0.8042657,0 -1.4376249,0.2111197 -1.8900243,0.6132525 -0.4624528,0.4121862 -0.6836258,0.8746389 -0.6836258,1.3873583 0,0.3418129 0.090479,0.6132526 0.2915463,0.814319 0.2010664,0.2010664 0.4423461,0.3015996 0.7338924,0.3015996 0.2714397,0 0.502666,-0.080427 0.6936791,-0.251333 0.1809598,-0.1709064 0.281493,-0.3920795 0.281493,-0.6534658 0,-0.2010665 -0.050267,-0.3820262 -0.1306931,-0.5428794 C 5.5638612,4.0349253 5.4733813,3.9142854 5.3929547,3.8238056 5.3125282,3.7333257 5.2723149,3.6629524 5.2723149,3.6126858 Z m -0.050267,5.8510328 c 0,0.2814929 0.090479,0.5127198 0.2915463,0.7137864 0.2010664,0.201066 0.4322928,0.291546 0.7137858,0.291546 0.2714396,0 0.502666,-0.09048 0.7037324,-0.291546 C 7.1321792,9.9764384 7.2327125,9.7452115 7.2327125,9.4637186 7.2327125,9.1922789 7.1321792,8.9610525 6.9311128,8.7599861 6.7300464,8.5589197 6.49882,8.4583865 6.2273804,8.4583865 c -0.281493,0 -0.5127194,0.1005332 -0.7137858,0.3015996 C 5.3125282,8.9610525 5.2220483,9.1922789 5.2220479,9.4637186 Z"
@@ -105,8 +105,8 @@ class SettingsWindow(Gtk.Window):
105
105
 
106
106
  def scroll_box(self, parent_widget = None, height = 300):
107
107
 
108
- print('parent_widget')
109
- print(parent_widget)
108
+ # print('parent_widget')
109
+ # print(parent_widget)
110
110
 
111
111
  scrolled_window = Gtk.ScrolledWindow()
112
112
  scrolled_window.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)
@@ -744,7 +744,7 @@ class EditAddTargetDialog(Gtk.Dialog):
744
744
 
745
745
  super().__init__(title="Set Time Target", transient_for=parent, flags=0)
746
746
 
747
- self.set_default_size(600,400)
747
+ self.set_default_size(700,850)
748
748
  self.set_border_width(15)
749
749
  box = self.get_content_area()
750
750
  box.set_spacing(15)
@@ -15,7 +15,7 @@ class TaskWindow(Gtk.Window):
15
15
  Gdk.Screen.get_default(), css_provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION
16
16
  )
17
17
  _instance = None
18
-
18
+
19
19
  def __init__(self,app,passed_data=None):
20
20
 
21
21
  if TaskWindow._instance:
@@ -39,7 +39,12 @@ class TaskWindow(Gtk.Window):
39
39
 
40
40
  Gtk.Window.__init__(self, title=conf.app_name)
41
41
 
42
- self.set_default_size(900,400)
42
+ self.set_default_size(900,900)
43
+ self.modifyer_keys = {
44
+ 'control': False,
45
+ 'shift': False,
46
+ 'alt': False,
47
+ }
43
48
 
44
49
  self.search_cache_refresh_time = now().strftime("%Y-%m-%d %H:%M:%S")
45
50
  self.search_cache = {}
@@ -121,15 +126,14 @@ class TaskWindow(Gtk.Window):
121
126
  self.taskEntry.set_text(passed_data['task']['label'])
122
127
 
123
128
 
124
- # box.add(Gtk.Box(border_width=10)) # Spacer
125
129
 
126
130
  self.scrolled_window = Gtk.ScrolledWindow()
127
131
  self.scrolled_window.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)
128
132
  box.pack_start(self.scrolled_window, True, True, 0)
129
- self.scrolled_window.set_size_request(-1, 600)
133
+ self.scrolled_window.set_size_request(-1, 350)
130
134
 
131
135
  self.scrolled_window.connect('scroll-event', self.on_scroll) # This doesn't catch scrollbar moves
132
- self.scrolled_window.connect('edge-reached', self.on_scroll) # This is a little late
136
+ self.scrolled_window.connect('edge-reached', self.on_scroll) # This is a little late and may not fire if the list is short?
133
137
 
134
138
  self.tasks_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=7)
135
139
  self.tasks_box.set_halign(Gtk.Align.START)
@@ -159,10 +163,6 @@ class TaskWindow(Gtk.Window):
159
163
  self.buttons_box.set_halign(Gtk.Align.CENTER)
160
164
  self.buttons_box.set_name("Footer")
161
165
 
162
-
163
- # box.add(Gtk.Box(border_width=10)) # Spacer
164
-
165
- # box.add(self.buttons_box)
166
166
  box.pack_start(self.buttons_box,False, False, 0)
167
167
 
168
168
  self.settings_button = Gtk.Button(label="Settings")
@@ -175,30 +175,20 @@ class TaskWindow(Gtk.Window):
175
175
  self.buttons_box.add(self.refresh_button)
176
176
 
177
177
  # Todolist openables
178
- openables = []
179
178
  for id, todo in conf.user['todolists'].items():
180
179
  if todo['status']:
181
180
  try:
182
181
  openable = conf.todo_connectors[todo['type']].launch
183
- # if openable not in openables:
184
-
185
- openables.append(openable)
186
-
187
182
  openable_button = Gtk.Button(label=GLib.markup_escape_text(todo['label']))
188
-
189
- openable_button.connect("clicked", lambda todo: openable(todo))
190
- # openable_button.connect("clicked", openable, todo) # Doesn't work because of passing widget as first argument
183
+ openable_button.connect("clicked", lambda button_widget,todo=todo, openable=openable: openable(todo))
191
184
  openable_button.set_property("tooltip-text","Open (new) "+GLib.markup_escape_text(todo['label']))
192
185
  self.buttons_box.add(openable_button)
193
186
 
194
187
  except Exception as e:
195
188
  dbg("error adding todo connector open() to task window ",e, s='taskwindow')
196
189
 
197
-
198
-
199
-
200
190
  self.new_task_button = Gtk.Button(label="New Task")
201
- self.new_task_button.set_property("tooltip-text","Add a new task to an existing list (Ctrl + N)")
191
+ self.new_task_button.set_property("tooltip-text","Add a new task (Ctrl + N)")
202
192
  self.new_task_button.connect("clicked",self.open_new_task_dialog)
203
193
  self.buttons_box.add(self.new_task_button)
204
194
 
@@ -210,7 +200,8 @@ class TaskWindow(Gtk.Window):
210
200
  key, mod = Gtk.accelerator_parse('<Control>r')
211
201
  self.refresh_button.add_accelerator("clicked", self.accel_group, key, mod, Gtk.AccelFlags.VISIBLE)
212
202
 
213
- self.connect("key-press-event", self.on_win_key_press_event)
203
+ self.connect("key-press-event", self.key_press)
204
+ self.connect('key-release-event', self.key_release)
214
205
  self.connect("window-state-event", self.on_window_state_event)
215
206
 
216
207
  self.taskEntry.connect("changed",self.task_search)
@@ -409,7 +400,6 @@ class TaskWindow(Gtk.Window):
409
400
 
410
401
 
411
402
 
412
-
413
403
  def add_task_to_list(self,t):
414
404
 
415
405
  try:
@@ -423,7 +413,6 @@ class TaskWindow(Gtk.Window):
423
413
 
424
414
  label = Gtk.Label()
425
415
 
426
- # self.shown_tasks[t['id']].set_label(label)
427
416
  # button_context = self.shown_tasks[t['id']].get_style_context().add_class("large")
428
417
  extended_label = GLib.markup_escape_text(t['extended_label'],)
429
418
 
@@ -434,6 +423,7 @@ class TaskWindow(Gtk.Window):
434
423
 
435
424
  extended_label = extended_label.replace(search_str,"<b>"+search_str+"</b>")
436
425
  extended_label = extended_label.replace(search_str.capitalize(),"<b>"+search_str.capitalize()+"</b>") # Cheesy
426
+
437
427
  if "duration" in t and t['duration']:
438
428
  extended_label += " ("+sec_to_time(t['duration'])+")"
439
429
 
@@ -443,14 +433,12 @@ class TaskWindow(Gtk.Window):
443
433
  if t['priority']:
444
434
  extended_label = str(t['priority']) +" "+ extended_label
445
435
 
446
-
447
436
  if not t['status']:
448
- utils.dbg("add strikethrough to done task "+t['extended_label'],l=3,s="taskwindow")
437
+ # utils.dbg("add strikethrough to done task "+t['extended_label'],l=3,s="taskwindow")
449
438
  # button_context.add_class("done")
450
439
  label.set_markup('<s>'+extended_label+'</s>')
451
440
 
452
441
  elif t['priority'] > 0:
453
- # button_context.add_class("bold")
454
442
  label.set_name('priorityTask')
455
443
  label.set_markup(extended_label)
456
444
  else:
@@ -471,83 +459,90 @@ class TaskWindow(Gtk.Window):
471
459
 
472
460
 
473
461
  def select_task(self,widget,event=None,tid=None):
462
+ print("select_task task id",tid)
474
463
  t = utils.db_get_item_by_id(tid)
475
- print('event',event)
476
- if event: # Right-click (button 3)
464
+ # print('event',event)
465
+ print("select_task self.modifyer_keys", self.modifyer_keys)
477
466
 
478
- if event.button == 3: # Right-click (button 3) context menu popover
479
-
480
- popover = self.task_rclick_menu
481
- widget.set_popover(popover)
467
+ if self.modifyer_keys['control'] or event and event.button == 3: # Right-click (button 3) or control click context menu popover
468
+
469
+ popover = self.task_rclick_menu
470
+ widget.set_popover(popover)
482
471
 
483
- popover.foreach(lambda child: child.destroy())
472
+ popover.foreach(lambda child: child.destroy())
484
473
 
485
- vbox = Gtk.Box(spacing=0, orientation=Gtk.Orientation.VERTICAL)
486
- vbox.set_border_width(5)
487
-
488
- # Open todo
489
- w = Gtk.Button(label="Open in "+conf.user['todolists'][t['todolist']]['label'])
490
- w.set_halign(Gtk.Align.START)
491
- w.set_relief(Gtk.ReliefStyle.NONE)
492
- w.connect('clicked',utils.open_todo,t)
493
- vbox.pack_start(w, True, True, 5)
494
-
495
- # mark_done
496
- w = Gtk.Button(label="Mark done")
497
- w.set_halign(Gtk.Align.START)
498
- w.set_relief(Gtk.ReliefStyle.NONE)
499
- w.connect('clicked',self.app.mark_done,t)
500
- vbox.pack_start(w, True, True, 5)
501
-
502
- # Reassign session/randomness to be on this task,
503
- w = Gtk.Button(label="Reassign last "+ str(round((self.app.session['duration'] / 60),1))+" minutes to this task" )
504
- w.set_halign(Gtk.Align.START)
505
- w.set_relief(Gtk.ReliefStyle.NONE)
506
- w.connect('clicked',self.app.start_task,t,True)
507
- vbox.pack_start(w, True, True, 5)
508
-
509
- # show/edit targets
510
- ttt_data = utils.get_time_target_data(t)
511
- if ttt_data:
512
- w = Gtk.Button(label="Edit Target:"+str(ttt_data['type'])+ " "+str(round(ttt_data['value']))+" minutes per "+str(round(ttt_data['within_value']))+" "+str(ttt_data['within_unit'])+" ("+str(round(utils.check_time_target(t)))+" minutes remaining)")
513
- else:
514
- w = Gtk.Button(label="Set Time Target")
515
- w.set_halign(Gtk.Align.START)
516
- w.set_relief(Gtk.ReliefStyle.NONE)
517
- w.connect('clicked', lambda button_widget: EditAddTargetDialog(self,'tasks', t['id']))
518
- vbox.pack_start(w, True, True, 5)
519
-
520
-
521
- # show/edit commands
522
- if t['id'] in conf.user['task_commands']:
523
- command_data = conf.user['task_commands'][t['id']]
524
- if not command_data['status']:
525
- disabled = "(disabled)"
526
- else:
527
- disabled = ""
528
-
529
- w = Gtk.Button(label="Edit Command: '"+command_data['command']+"' "+disabled+"")
474
+ vbox = Gtk.Box(spacing=0, orientation=Gtk.Orientation.VERTICAL)
475
+ vbox.set_border_width(5)
476
+
477
+ # Open todo
478
+ w = Gtk.Button(label="Open in "+conf.user['todolists'][t['todolist']]['label'])
479
+ w.set_halign(Gtk.Align.START)
480
+ w.set_relief(Gtk.ReliefStyle.NONE)
481
+ w.connect('clicked',utils.open_todo,t)
482
+ vbox.pack_start(w, True, True, 5)
483
+
484
+ # mark_done
485
+ w = Gtk.Button(label="Mark done")
486
+ w.set_halign(Gtk.Align.START)
487
+ w.set_relief(Gtk.ReliefStyle.NONE)
488
+ w.connect('clicked',self.app.mark_done,t)
489
+ vbox.pack_start(w, True, True, 5)
490
+
491
+ # Reassign session/randomness to be on this task,
492
+ w = Gtk.Button(label="Reassign last "+ str(round((self.app.session['duration'] / 60),1))+" minutes to this task" )
493
+ w.set_halign(Gtk.Align.START)
494
+ w.set_relief(Gtk.ReliefStyle.NONE)
495
+ w.connect('clicked',self.app.start_task,t,True)
496
+ vbox.pack_start(w, True, True, 5)
497
+
498
+ # show/edit targets
499
+ ttt_data = utils.get_time_target_data(t)
500
+ if ttt_data:
501
+ w = Gtk.Button(label="Edit Target:"+str(ttt_data['type'])+ " "+str(round(ttt_data['value']))+" minutes per "+str(round(ttt_data['within_value']))+" "+str(ttt_data['within_unit'])+" ("+str(round(utils.check_time_target(t)))+" minutes remaining)")
502
+ else:
503
+ w = Gtk.Button(label="Set Time Target")
504
+ w.set_halign(Gtk.Align.START)
505
+ w.set_relief(Gtk.ReliefStyle.NONE)
506
+ w.connect('clicked', lambda button_widget: EditAddTargetDialog(self,'tasks', t['id']))
507
+ vbox.pack_start(w, True, True, 5)
508
+
509
+
510
+ # show/edit commands
511
+ if t['id'] in conf.user['task_commands']:
512
+ command_data = conf.user['task_commands'][t['id']]
513
+ if not command_data['status']:
514
+ disabled = "(disabled)"
530
515
  else:
531
- w = Gtk.Button(label="Add Task Command")
516
+ disabled = ""
532
517
 
533
- w.set_halign(Gtk.Align.START)
534
- w.set_relief(Gtk.ReliefStyle.NONE)
535
- w.connect('clicked', lambda button_widget: EditTaskCommandDialog(None, self, t['id']))
536
- vbox.pack_start(w, True, True, 5)
518
+ w = Gtk.Button(label="Edit Command: '"+command_data['command']+"' "+disabled+"")
519
+ else:
520
+ w = Gtk.Button(label="Add Task Command")
537
521
 
522
+ w.set_halign(Gtk.Align.START)
523
+ w.set_relief(Gtk.ReliefStyle.NONE)
524
+ w.connect('clicked', lambda button_widget: EditTaskCommandDialog(None, self, t['id']))
525
+ vbox.pack_start(w, True, True, 5)
538
526
 
539
- # get_times, Ugly
540
- # for key, val in utils.get_times(t).items():
541
- # vbox.pack_start(Gtk.Label(key+": "+val), True, True, 5)
542
527
 
543
- popover.add(vbox)
544
- popover.set_position(Gtk.PositionType.BOTTOM)
545
- popover.show_all()
528
+ # get_times, Ugly
529
+ # for key, val in utils.get_times(t).items():
530
+ # vbox.pack_start(Gtk.Label(key+": "+val), True, True, 5)
546
531
 
547
- return
532
+ popover.add(vbox)
533
+ popover.set_position(Gtk.PositionType.BOTTOM)
534
+ popover.show_all()
548
535
 
536
+ return
549
537
 
550
- self.app.start_task(None,t)
538
+ if self.modifyer_keys['shift']:
539
+ print('transfer session')
540
+ self.app.start_task(None,t,True)
541
+ elif self.modifyer_keys['alt']:
542
+ print('open_todo')
543
+ utils.open_todo(None,t)
544
+ else:
545
+ self.app.start_task(None,t)
551
546
 
552
547
  self.destroy()
553
548
 
@@ -596,29 +591,61 @@ class TaskWindow(Gtk.Window):
596
591
  utils.save_user_settings()
597
592
 
598
593
 
599
- def on_win_key_press_event(self, widget, ev):
594
+ def key_release(self, widget, event):
595
+ key = Gdk.keyval_name(event.keyval)
596
+ # utils.dbg("key_release",key,s="taskwindow",l=1)
597
+ # utils.dbg("key_release event.state",event.state,s="taskwindow",l=1)
598
+ if (event.state & Gdk.ModifierType.CONTROL_MASK):
599
+ self.modifyer_keys['control'] = False
600
+ if (event.state & Gdk.ModifierType.SHIFT_MASK):
601
+ self.modifyer_keys['shift'] = False
602
+ if (event.state & Gdk.ModifierType.MOD1_MASK):
603
+ self.modifyer_keys['alt'] = False
604
+
605
+
606
+ # print("modifyer_keys",self.modifyer_keys)
600
607
 
601
- key = Gdk.keyval_name(ev.keyval)
602
- utils.dbg("task window key",key,s="taskwindow",l=3)
603
- # utils.dbg("key_press_event",ev,s="taskwindow",l=1)
604
- utils.dbg("ModifierType is CONTROL_MASK",Gdk.ModifierType.CONTROL_MASK,s="taskwindow",l=3)
608
+
609
+ def key_press(self, widget, event):
610
+
611
+ key = Gdk.keyval_name(event.keyval)
612
+ # utils.dbg("key_press",key,s="taskwindow",l=1)
613
+ # utils.dbg("key_press event.state",event.state,s="taskwindow",l=1)
614
+ # utils.dbg("key_press_event",event,s="taskwindow",l=1)
615
+ # utils.dbg("ModifierType is CONTROL_MASK",Gdk.ModifierType.CONTROL_MASK,s="taskwindow",l=3)
605
616
 
617
+ if (event.state & Gdk.ModifierType.CONTROL_MASK) or key == 'Control_L':
618
+ self.modifyer_keys['control'] = True
619
+ if (event.state & Gdk.ModifierType.SHIFT_MASK) or key == 'Shift_L':
620
+ self.modifyer_keys['shift'] = True
621
+ if (event.state & Gdk.ModifierType.MOD1_MASK) or key == 'Alt_L':
622
+ self.modifyer_keys['alt'] = True
623
+
624
+ # print("modifyer_keys", self.modifyer_keys)
625
+
606
626
 
607
627
  if key == "F11":
608
628
  self.toggle_fullscreen()
609
629
  elif key == "Escape":
610
630
  self.destroy()
611
- elif key in ['l','f'] and Gdk.ModifierType.CONTROL_MASK and not self.taskEntry.is_focus():
631
+ elif key in ['l','f'] and (event.state & Gdk.ModifierType.CONTROL_MASK) and not self.taskEntry.is_focus():
612
632
  self.taskEntry.grab_focus()
613
633
 
614
- elif key == "Return" and self.taskEntry.is_focus():
615
- # print("self.taskEntry has focus, do the thing")
616
- if self.shown_tasks:
617
- self.tasks_box.get_children()[0].emit('activate')
618
- else:
619
- self.new_task_button.emit('clicked')
634
+ elif key == "Return":
635
+ # print('self.get_focus()',self.get_focus())
636
+ # print('self.tasks_box.get_children()[1]',self.tasks_box.get_children()[1])
637
+ if self.taskEntry.is_focus():
638
+ # print("self.taskEntry has focus, do the thing")
639
+ if self.shown_tasks:
640
+ self.tasks_box.get_children()[0].emit('activate')
641
+ else:
642
+ self.new_task_button.emit('clicked')
643
+
644
+ elif self.shown_tasks and self.get_focus() in self.tasks_box.get_children():
645
+ # print("Return pressed on shown task select it",self.get_focus())
646
+ self.get_focus().emit('activate')
620
647
 
621
648
 
622
- def on_window_state_event(self, widget, ev):
623
- self.__is_fullscreen = bool(ev.new_window_state & Gdk.WindowState.FULLSCREEN)
649
+ def on_window_state_event(self, widget, event):
650
+ self.__is_fullscreen = bool(event.new_window_state & Gdk.WindowState.FULLSCREEN)
624
651
 
@@ -144,7 +144,7 @@ def validate_start_time_str(start_time_string):
144
144
  error_notice('Incorrect Start Time Format', start_time_string+" does no match %Y-%m-%d %H:%M:%S", e)
145
145
  return False
146
146
 
147
- def open_todo(w=None, i=None, item_type = 'task'):
147
+ def open_todo(w=None, i=None, item_type = 'tasks'):
148
148
  ''' run the launch() function from the todo connector for the provided i(tem) '''
149
149
  if not isinstance(i, dict):
150
150
  i = db_get_item_by_id(i,item_type)
@@ -684,7 +684,9 @@ def db_cleanup(widget = None):
684
684
  # exit()
685
685
 
686
686
  def db_get_item_by_id(id,table = 'tasks'):
687
-
687
+
688
+ if table in ['task','list']:
689
+ table = table+'s'
688
690
  if table not in ['tasks','lists']:
689
691
  dbg('bad table "'+str(table)+'" passed to db_get_item_by_id',id,l=0)
690
692
  return {}
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: nowfocus
3
- Version: 0.2.6
3
+ Version: 0.2.8
4
4
  Summary: nowfocus: the open source task-tracking self-control panel.
5
5
  Author: GitFr33
6
6
  Project-URL: Homepage, https://gitlab.com/GitFr33/nowfocus
@@ -92,12 +92,12 @@ nowfocus is a clean, keyboard-driven project time tracker build with python + GT
92
92
  - [TimeWarrior](https://timewarrior.net)
93
93
 
94
94
 
95
- ## Installation (using pipx)
95
+ ## Installation
96
96
 
97
- Run the following in terminal to install and setup:
97
+ 1. Run the following in terminal to install and setup:
98
98
  ```
99
99
  # Install dependencies
100
- sudo apt install pip pipx gir1.2-appindicator3-0.1 meson libdbus-glib-1-dev patchelf libgirepository1.0-dev gcc libcairo2-dev pkg-config python3-dev
100
+ sudo apt install pipx gir1.2-appindicator3-0.1 meson libdbus-glib-1-dev patchelf libgirepository1.0-dev gcc libcairo2-dev pkg-config python3-dev
101
101
 
102
102
  # Set up pipx
103
103
  pipx ensurepath
@@ -108,26 +108,21 @@ pipx ensurepath
108
108
  pipx install nowfocus
109
109
 
110
110
  # Enter application directory
111
- cd ~/.local/share/pipx/venvs/nowfocus/lib/python3.12/site-packages/nowfocus
111
+ cd ~/.local/share/pipx/venvs/nowfocus/lib/python3.12/site-packages/nowfocus/desktop-extras
112
112
 
113
- # Copy .desktop and icon to .local/share
114
- cp src/desktop-extras/nowfocus.desktop ~/.local/share/applications/nowfocus.desktop
115
- cp src/desktop-extras/nowfocus.svg ~/.local/share/icons/nowfocus.png
116
- cp src/desktop-extras/nowfocus.svg ~/.local/share/icons/hicolor/scalable/apps/nowfocus.svg
117
-
118
- # Setup autostart
119
- cp src/desktop-extras/nowfocus.desktop ~/.config/autostart/nowfocus.desktop
120
-
121
- # Set Super space as keybinding to raise task window
122
- chmod +x src/desktop-extras/set_gsettings_keybinding.sh
123
-
124
- src/desktop-extras/set_gsettings_keybinding.sh "Open nowfocus" nowfocus "<Super>space"
113
+ # Copy .desktop and icon to /usr/share
114
+ sudo cp nowfocus.desktop /usr/share/applications/nowfocus.desktop
115
+ sudo cp nowfocus.svg /usr/share/icons/hicolor/scalable/apps/nowfocus.svg
125
116
 
126
117
  # and now Focus!
127
118
  nowfocus
128
119
 
129
120
  ```
130
121
 
122
+ 2. Set up a keybinding (on Ubuntu or Linux Mint), open **Settings > Keyboard > Keyboard Shortcuts > Custom Shortcuts**, set the **command** to `nowfocus`, and pick whatever key combo you'd like.
123
+
124
+ 3. Add the following command to your startup applications: `nowfocus --force`
125
+
131
126
 
132
127
 
133
128
  ## Usage
@@ -140,7 +135,10 @@ Open nowfocus **Settings** from the indicator menu or tasks window and connect y
140
135
 
141
136
  - `F11` Toggle fullscreen
142
137
  - `Esc` Close task window
143
- - `Enter` Start top task (or make a new task with current search phrase if no results)
138
+ - `Enter` Start top/selected task (or make a new task with current search phrase if no results)
139
+ - `Shift Enter` or `Shift Click` Transfer current session time to selected task (or top task if none selected)
140
+ - `Control Enter` or `Control Click` show opetions menu for selected (or top) task
141
+ - `Alt Enter` or `Alt Click` Open todolist for selected (or top) task
144
142
  - `Ctrl + P` **Pause** current task
145
143
  - `Ctrl + D` Pause current task and mark it **Done**
146
144
  - `Ctrl + X` Cancel current task
@@ -33,7 +33,6 @@ src/nowfocus/connectors/vikunja.py
33
33
  src/nowfocus/desktop-extras/nowfocus.desktop
34
34
  src/nowfocus/desktop-extras/nowfocus.png
35
35
  src/nowfocus/desktop-extras/nowfocus.svg
36
- src/nowfocus/desktop-extras/set_gsettings_keybinding.sh
37
36
  src/nowfocus/icon/cancel.png
38
37
  src/nowfocus/icon/cancel.svg
39
38
  src/nowfocus/icon/edit.png
@@ -48,6 +47,7 @@ src/nowfocus/icon/icon-6.svg
48
47
  src/nowfocus/icon/icon-7.svg
49
48
  src/nowfocus/icon/icon-8.svg
50
49
  src/nowfocus/icon/icon-9.svg
50
+ src/nowfocus/icon/icon-red.svg
51
51
  src/nowfocus/icon/icon.svg
52
52
  src/nowfocus/icon/mark-done.png
53
53
  src/nowfocus/icon/mark-done.svg
@@ -1,51 +0,0 @@
1
- #!/bin/bash
2
-
3
- # This function simplifies setting up Gnome 3 shortcuts from terminal
4
-
5
- # $1 name of the shortcut
6
- # $2 command to execute
7
- # $3 keyboard shortcut
8
-
9
- # src: https://askubuntu.com/a/597414/279745 and https://gitlab.com/tukusejssirs/lnx_scripts/-/blob/master/bash/functions/gshort.sh
10
-
11
- # TODO
12
- # - before shortcut creation, check if:
13
- # - the shortcut is not used already in custom shortcuts;
14
- # - the command is not used already in custom shortcuts;
15
- # - sometimes is uses the very same $num multiple times;
16
-
17
-
18
- gshort(){
19
- set -o errexit
20
- local name="$1"
21
- local command="$2"
22
- local shortcut="$3"
23
- local value test value_new
24
- value="$(gsettings get org.gnome.settings-daemon.plugins.media-keys custom-keybindings)"
25
- test="$(sed "s/\['//;s/', '/,/g;s/'\]//" <<< "$value" | tr ',' '\n' | grep -oP ".*/custom\K[0-9]*(?=/$)")"
26
-
27
- if [ "$(echo "$value" | grep -o "@as")" = "@as" ]; then
28
- local num=0
29
- value_new="['/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom${num}/']"
30
- else
31
- local i=1
32
-
33
- until [ "$num" != "" ]; do
34
- if [ "$(grep -o $i <<< "$test")" != "$i" ]; then
35
- local num=$i
36
- fi
37
- i="$(echo 1+$i | bc)";
38
- done
39
-
40
- value_new="$(gsettings get org.gnome.settings-daemon.plugins.media-keys custom-keybindings | sed "s#']\$#', '/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom${num}/']#")"
41
- fi
42
-
43
- echo setting custom-keybinding ${num} to ${command} with ${shortcut}
44
-
45
- gsettings set org.gnome.settings-daemon.plugins.media-keys custom-keybindings "$value_new"
46
- gsettings set org.gnome.settings-daemon.plugins.media-keys.custom-keybinding:/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom${num}/ name "$name"
47
- gsettings set org.gnome.settings-daemon.plugins.media-keys.custom-keybinding:/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom${num}/ command "$command"
48
- gsettings set org.gnome.settings-daemon.plugins.media-keys.custom-keybinding:/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom${num}/ binding "$shortcut"
49
- }
50
-
51
- gshort $1 $2 $3
File without changes
File without changes
File without changes