NowFocus 0.2.5__tar.gz → 0.2.7__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.5/src/nowfocus.egg-info → nowfocus-0.2.7}/PKG-INFO +18 -18
  2. {nowfocus-0.2.5 → nowfocus-0.2.7}/README.md +17 -17
  3. {nowfocus-0.2.5 → nowfocus-0.2.7}/pyproject.toml +1 -1
  4. {nowfocus-0.2.5 → nowfocus-0.2.7}/src/nowfocus/__main__.py +6 -5
  5. {nowfocus-0.2.5 → nowfocus-0.2.7}/src/nowfocus/connectors/trello.py +6 -6
  6. {nowfocus-0.2.5 → nowfocus-0.2.7}/src/nowfocus/settings.py +3 -3
  7. {nowfocus-0.2.5 → nowfocus-0.2.7}/src/nowfocus/task_window.py +131 -92
  8. {nowfocus-0.2.5 → nowfocus-0.2.7}/src/nowfocus/utils.py +5 -3
  9. {nowfocus-0.2.5 → nowfocus-0.2.7/src/nowfocus.egg-info}/PKG-INFO +18 -18
  10. {nowfocus-0.2.5 → nowfocus-0.2.7}/src/nowfocus.egg-info/SOURCES.txt +4 -4
  11. nowfocus-0.2.7/src/nowfocus.egg-info/top_level.txt +1 -0
  12. nowfocus-0.2.5/src/nowfocus.egg-info/top_level.txt +0 -2
  13. {nowfocus-0.2.5 → nowfocus-0.2.7}/LICENSE +0 -0
  14. {nowfocus-0.2.5 → nowfocus-0.2.7}/setup.cfg +0 -0
  15. {nowfocus-0.2.5 → nowfocus-0.2.7}/src/nowfocus/__init__.py +0 -0
  16. {nowfocus-0.2.5 → nowfocus-0.2.7}/src/nowfocus/conf.py +0 -0
  17. {nowfocus-0.2.5 → nowfocus-0.2.7}/src/nowfocus/connectors/activitywatch.py +0 -0
  18. {nowfocus-0.2.5 → nowfocus-0.2.7}/src/nowfocus/connectors/caldav.py +0 -0
  19. {nowfocus-0.2.5 → nowfocus-0.2.7}/src/nowfocus/connectors/csv.py +0 -0
  20. {nowfocus-0.2.5 → nowfocus-0.2.7}/src/nowfocus/connectors/psc_timetracker.py +0 -0
  21. {nowfocus-0.2.5 → nowfocus-0.2.7}/src/nowfocus/connectors/taskwarrior.py +0 -0
  22. {nowfocus-0.2.5 → nowfocus-0.2.7}/src/nowfocus/connectors/timewarrior.py +0 -0
  23. {nowfocus-0.2.5 → nowfocus-0.2.7}/src/nowfocus/connectors/todo_template.py +0 -0
  24. {nowfocus-0.2.5 → nowfocus-0.2.7}/src/nowfocus/connectors/todotxt.py +0 -0
  25. {nowfocus-0.2.5 → nowfocus-0.2.7}/src/nowfocus/connectors/txt.py +0 -0
  26. {nowfocus-0.2.5 → nowfocus-0.2.7}/src/nowfocus/connectors/vikunja.py +0 -0
  27. {nowfocus-0.2.5/src → nowfocus-0.2.7/src/nowfocus}/desktop-extras/nowfocus.desktop +0 -0
  28. {nowfocus-0.2.5/src → nowfocus-0.2.7/src/nowfocus}/desktop-extras/nowfocus.png +0 -0
  29. {nowfocus-0.2.5/src → nowfocus-0.2.7/src/nowfocus}/desktop-extras/nowfocus.svg +0 -0
  30. {nowfocus-0.2.5/src → nowfocus-0.2.7/src/nowfocus}/desktop-extras/set_gsettings_keybinding.sh +0 -0
  31. {nowfocus-0.2.5 → nowfocus-0.2.7}/src/nowfocus/example-todo.txt +0 -0
  32. {nowfocus-0.2.5 → nowfocus-0.2.7}/src/nowfocus/icon/cancel.png +0 -0
  33. {nowfocus-0.2.5 → nowfocus-0.2.7}/src/nowfocus/icon/cancel.svg +0 -0
  34. {nowfocus-0.2.5 → nowfocus-0.2.7}/src/nowfocus/icon/edit.png +0 -0
  35. {nowfocus-0.2.5 → nowfocus-0.2.7}/src/nowfocus/icon/edit.svg +0 -0
  36. {nowfocus-0.2.5 → nowfocus-0.2.7}/src/nowfocus/icon/icon-0.svg +0 -0
  37. {nowfocus-0.2.5 → nowfocus-0.2.7}/src/nowfocus/icon/icon-1.svg +0 -0
  38. {nowfocus-0.2.5 → nowfocus-0.2.7}/src/nowfocus/icon/icon-2.svg +0 -0
  39. {nowfocus-0.2.5 → nowfocus-0.2.7}/src/nowfocus/icon/icon-3.svg +0 -0
  40. {nowfocus-0.2.5 → nowfocus-0.2.7}/src/nowfocus/icon/icon-4.svg +0 -0
  41. {nowfocus-0.2.5 → nowfocus-0.2.7}/src/nowfocus/icon/icon-5.svg +0 -0
  42. {nowfocus-0.2.5 → nowfocus-0.2.7}/src/nowfocus/icon/icon-6.svg +0 -0
  43. {nowfocus-0.2.5 → nowfocus-0.2.7}/src/nowfocus/icon/icon-7.svg +0 -0
  44. {nowfocus-0.2.5 → nowfocus-0.2.7}/src/nowfocus/icon/icon-8.svg +0 -0
  45. {nowfocus-0.2.5 → nowfocus-0.2.7}/src/nowfocus/icon/icon-9.svg +0 -0
  46. {nowfocus-0.2.5 → nowfocus-0.2.7}/src/nowfocus/icon/icon.svg +0 -0
  47. {nowfocus-0.2.5 → nowfocus-0.2.7}/src/nowfocus/icon/mark-done.png +0 -0
  48. {nowfocus-0.2.5 → nowfocus-0.2.7}/src/nowfocus/icon/mark-done.svg +0 -0
  49. {nowfocus-0.2.5 → nowfocus-0.2.7}/src/nowfocus/icon/pause.png +0 -0
  50. {nowfocus-0.2.5 → nowfocus-0.2.7}/src/nowfocus/icon/pause.svg +0 -0
  51. {nowfocus-0.2.5 → nowfocus-0.2.7}/src/nowfocus/icon/settings.png +0 -0
  52. {nowfocus-0.2.5 → nowfocus-0.2.7}/src/nowfocus/icon/settings.svg +0 -0
  53. {nowfocus-0.2.5 → nowfocus-0.2.7}/src/nowfocus/new_task_dialog.py +0 -0
  54. {nowfocus-0.2.5 → nowfocus-0.2.7}/src/nowfocus/session_edit_dialog.py +0 -0
  55. {nowfocus-0.2.5 → nowfocus-0.2.7}/src/nowfocus/session_options.py +0 -0
  56. {nowfocus-0.2.5 → nowfocus-0.2.7}/src/nowfocus/sessions.csv +0 -0
  57. {nowfocus-0.2.5 → nowfocus-0.2.7}/src/nowfocus/sound/bell-xylophone-g.mp3 +0 -0
  58. {nowfocus-0.2.5 → nowfocus-0.2.7}/src/nowfocus/sound/dinner-bell.mp3 +0 -0
  59. {nowfocus-0.2.5 → nowfocus-0.2.7}/src/nowfocus/sound/xylophone-chord.mp3 +0 -0
  60. {nowfocus-0.2.5 → nowfocus-0.2.7}/src/nowfocus/styles.css +0 -0
  61. {nowfocus-0.2.5 → nowfocus-0.2.7}/src/nowfocus.egg-info/dependency_links.txt +0 -0
  62. {nowfocus-0.2.5 → nowfocus-0.2.7}/src/nowfocus.egg-info/entry_points.txt +0 -0
  63. {nowfocus-0.2.5 → nowfocus-0.2.7}/src/nowfocus.egg-info/requires.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: nowfocus
3
- Version: 0.2.5
3
+ Version: 0.2.7
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,40 +92,37 @@ 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 install gir1.2-appindicator3-0.1 meson libdbus-glib-1-dev patchelf python3.12-venv 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
104
104
 
105
+ # At this point you may need to restart your terminal window
106
+
105
107
  # Install nowfocus
106
108
  pipx install nowfocus
107
109
 
108
110
  # Enter application directory
109
- cd ~/.local/pipx/nowfocus
110
-
111
- # Copy .desktop and icon to .local/share
112
- cp src/desktop-extras/nowfocus.desktop ~/.local/share/applications/nowfocus.desktop
113
- cp src/desktop-extras/nowfocus.svg ~/.local/share/icons/nowfocus.png
114
- cp src/desktop-extras/nowfocus.svg ~/.local/share/icons/hicolor/scalable/apps/nowfocus.svg
115
-
116
- # Setup autostart
117
- cp src/desktop-extras/nowfocus.desktop ~/.config/autostart/nowfocus.desktop
111
+ cd ~/.local/share/pipx/venvs/nowfocus/lib/python3.12/site-packages/nowfocus/desktop-extras
118
112
 
119
- # Set Super space as keybinding to raise task window
120
- chmod +x src/desktop-extras/set_gsettings_keybinding.sh
121
-
122
- 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
123
116
 
124
117
  # and now Focus!
125
118
  nowfocus
126
119
 
127
120
  ```
128
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
+
129
126
 
130
127
 
131
128
  ## Usage
@@ -138,7 +135,10 @@ Open nowfocus **Settings** from the indicator menu or tasks window and connect y
138
135
 
139
136
  - `F11` Toggle fullscreen
140
137
  - `Esc` Close task window
141
- - `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
142
142
  - `Ctrl + P` **Pause** current task
143
143
  - `Ctrl + D` Pause current task and mark it **Done**
144
144
  - `Ctrl + X` Cancel current task
@@ -46,40 +46,37 @@ 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 install gir1.2-appindicator3-0.1 meson libdbus-glib-1-dev patchelf python3.12-venv 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
58
58
 
59
+ # At this point you may need to restart your terminal window
60
+
59
61
  # Install nowfocus
60
62
  pipx install nowfocus
61
63
 
62
64
  # Enter application directory
63
- cd ~/.local/pipx/nowfocus
64
-
65
- # Copy .desktop and icon to .local/share
66
- cp src/desktop-extras/nowfocus.desktop ~/.local/share/applications/nowfocus.desktop
67
- cp src/desktop-extras/nowfocus.svg ~/.local/share/icons/nowfocus.png
68
- cp src/desktop-extras/nowfocus.svg ~/.local/share/icons/hicolor/scalable/apps/nowfocus.svg
69
-
70
- # Setup autostart
71
- cp src/desktop-extras/nowfocus.desktop ~/.config/autostart/nowfocus.desktop
65
+ cd ~/.local/share/pipx/venvs/nowfocus/lib/python3.12/site-packages/nowfocus/desktop-extras
72
66
 
73
- # Set Super space as keybinding to raise task window
74
- chmod +x src/desktop-extras/set_gsettings_keybinding.sh
75
-
76
- 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
77
70
 
78
71
  # and now Focus!
79
72
  nowfocus
80
73
 
81
74
  ```
82
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
+
83
80
 
84
81
 
85
82
  ## Usage
@@ -92,7 +89,10 @@ Open nowfocus **Settings** from the indicator menu or tasks window and connect y
92
89
 
93
90
  - `F11` Toggle fullscreen
94
91
  - `Esc` Close task window
95
- - `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
96
96
  - `Ctrl + P` **Pause** current task
97
97
  - `Ctrl + D` Pause current task and mark it **Done**
98
98
  - `Ctrl + X` Cancel current task
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "nowfocus"
3
- version = "0.2.5"
3
+ version = "0.2.7"
4
4
  authors = [
5
5
  { name="GitFr33" },
6
6
  ]
@@ -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'])
@@ -484,7 +484,7 @@ class Application(Gtk.Application):
484
484
  self.mark_done(None,task)
485
485
 
486
486
  else:
487
- print("add ",utils.extended_label(task)," to recent tasks")
487
+ # print("add ",utils.extended_label(task)," to recent tasks")
488
488
  i = Gtk.MenuItem.new_with_label(utils.extended_label(task))
489
489
  i.connect('activate',self.start_task,task)
490
490
  list_menus['recent'].prepend(i)
@@ -511,8 +511,9 @@ class Application(Gtk.Application):
511
511
 
512
512
  self.is_running = False
513
513
  # 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()
514
+ if action != 'cancel':
515
+ notify.Notification.new("Focused on "+session['label']+" for "+sec_to_time(session['duration']),utils.pretty_dict(utils.get_times(task)), None).show()
516
+ # notify.Notification.new(action.capitalize()+" "+session['label']+" "+sec_to_time(session['duration']),utils.pretty_dict(utils.get_times(task)), None).show()
516
517
 
517
518
  # Start randomness timer
518
519
  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
 
@@ -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 = {}
@@ -126,7 +131,7 @@ class TaskWindow(Gtk.Window):
126
131
  self.scrolled_window = Gtk.ScrolledWindow()
127
132
  self.scrolled_window.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)
128
133
  box.pack_start(self.scrolled_window, True, True, 0)
129
- self.scrolled_window.set_size_request(-1, 600)
134
+ self.scrolled_window.set_size_request(-1, 350)
130
135
 
131
136
  self.scrolled_window.connect('scroll-event', self.on_scroll) # This doesn't catch scrollbar moves
132
137
  self.scrolled_window.connect('edge-reached', self.on_scroll) # This is a little late
@@ -194,11 +199,8 @@ class TaskWindow(Gtk.Window):
194
199
  except Exception as e:
195
200
  dbg("error adding todo connector open() to task window ",e, s='taskwindow')
196
201
 
197
-
198
-
199
-
200
202
  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)")
203
+ self.new_task_button.set_property("tooltip-text","Add a new task (Ctrl + N)")
202
204
  self.new_task_button.connect("clicked",self.open_new_task_dialog)
203
205
  self.buttons_box.add(self.new_task_button)
204
206
 
@@ -210,7 +212,8 @@ class TaskWindow(Gtk.Window):
210
212
  key, mod = Gtk.accelerator_parse('<Control>r')
211
213
  self.refresh_button.add_accelerator("clicked", self.accel_group, key, mod, Gtk.AccelFlags.VISIBLE)
212
214
 
213
- self.connect("key-press-event", self.on_win_key_press_event)
215
+ self.connect("key-press-event", self.key_press)
216
+ self.connect('key-release-event', self.key_release)
214
217
  self.connect("window-state-event", self.on_window_state_event)
215
218
 
216
219
  self.taskEntry.connect("changed",self.task_search)
@@ -409,7 +412,6 @@ class TaskWindow(Gtk.Window):
409
412
 
410
413
 
411
414
 
412
-
413
415
  def add_task_to_list(self,t):
414
416
 
415
417
  try:
@@ -423,7 +425,6 @@ class TaskWindow(Gtk.Window):
423
425
 
424
426
  label = Gtk.Label()
425
427
 
426
- # self.shown_tasks[t['id']].set_label(label)
427
428
  # button_context = self.shown_tasks[t['id']].get_style_context().add_class("large")
428
429
  extended_label = GLib.markup_escape_text(t['extended_label'],)
429
430
 
@@ -434,6 +435,7 @@ class TaskWindow(Gtk.Window):
434
435
 
435
436
  extended_label = extended_label.replace(search_str,"<b>"+search_str+"</b>")
436
437
  extended_label = extended_label.replace(search_str.capitalize(),"<b>"+search_str.capitalize()+"</b>") # Cheesy
438
+
437
439
  if "duration" in t and t['duration']:
438
440
  extended_label += " ("+sec_to_time(t['duration'])+")"
439
441
 
@@ -443,14 +445,12 @@ class TaskWindow(Gtk.Window):
443
445
  if t['priority']:
444
446
  extended_label = str(t['priority']) +" "+ extended_label
445
447
 
446
-
447
448
  if not t['status']:
448
- utils.dbg("add strikethrough to done task "+t['extended_label'],l=3,s="taskwindow")
449
+ # utils.dbg("add strikethrough to done task "+t['extended_label'],l=3,s="taskwindow")
449
450
  # button_context.add_class("done")
450
451
  label.set_markup('<s>'+extended_label+'</s>')
451
452
 
452
453
  elif t['priority'] > 0:
453
- # button_context.add_class("bold")
454
454
  label.set_name('priorityTask')
455
455
  label.set_markup(extended_label)
456
456
  else:
@@ -471,83 +471,90 @@ class TaskWindow(Gtk.Window):
471
471
 
472
472
 
473
473
  def select_task(self,widget,event=None,tid=None):
474
+ print("select_task task id",tid)
474
475
  t = utils.db_get_item_by_id(tid)
475
- print('event',event)
476
- if event: # Right-click (button 3)
476
+ # print('event',event)
477
+ print("select_task self.modifyer_keys", self.modifyer_keys)
477
478
 
478
- if event.button == 3: # Right-click (button 3) context menu popover
479
-
480
- popover = self.task_rclick_menu
481
- widget.set_popover(popover)
479
+ if self.modifyer_keys['control'] or event and event.button == 3: # Right-click (button 3) or control click context menu popover
480
+
481
+ popover = self.task_rclick_menu
482
+ widget.set_popover(popover)
482
483
 
483
- popover.foreach(lambda child: child.destroy())
484
+ popover.foreach(lambda child: child.destroy())
484
485
 
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+"")
486
+ vbox = Gtk.Box(spacing=0, orientation=Gtk.Orientation.VERTICAL)
487
+ vbox.set_border_width(5)
488
+
489
+ # Open todo
490
+ w = Gtk.Button(label="Open in "+conf.user['todolists'][t['todolist']]['label'])
491
+ w.set_halign(Gtk.Align.START)
492
+ w.set_relief(Gtk.ReliefStyle.NONE)
493
+ w.connect('clicked',utils.open_todo,t)
494
+ vbox.pack_start(w, True, True, 5)
495
+
496
+ # mark_done
497
+ w = Gtk.Button(label="Mark done")
498
+ w.set_halign(Gtk.Align.START)
499
+ w.set_relief(Gtk.ReliefStyle.NONE)
500
+ w.connect('clicked',self.app.mark_done,t)
501
+ vbox.pack_start(w, True, True, 5)
502
+
503
+ # Reassign session/randomness to be on this task,
504
+ w = Gtk.Button(label="Reassign last "+ str(round((self.app.session['duration'] / 60),1))+" minutes to this task" )
505
+ w.set_halign(Gtk.Align.START)
506
+ w.set_relief(Gtk.ReliefStyle.NONE)
507
+ w.connect('clicked',self.app.start_task,t,True)
508
+ vbox.pack_start(w, True, True, 5)
509
+
510
+ # show/edit targets
511
+ ttt_data = utils.get_time_target_data(t)
512
+ if ttt_data:
513
+ 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)")
514
+ else:
515
+ w = Gtk.Button(label="Set Time Target")
516
+ w.set_halign(Gtk.Align.START)
517
+ w.set_relief(Gtk.ReliefStyle.NONE)
518
+ w.connect('clicked', lambda button_widget: EditAddTargetDialog(self,'tasks', t['id']))
519
+ vbox.pack_start(w, True, True, 5)
520
+
521
+
522
+ # show/edit commands
523
+ if t['id'] in conf.user['task_commands']:
524
+ command_data = conf.user['task_commands'][t['id']]
525
+ if not command_data['status']:
526
+ disabled = "(disabled)"
530
527
  else:
531
- w = Gtk.Button(label="Add Task Command")
528
+ disabled = ""
532
529
 
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)
530
+ w = Gtk.Button(label="Edit Command: '"+command_data['command']+"' "+disabled+"")
531
+ else:
532
+ w = Gtk.Button(label="Add Task Command")
537
533
 
534
+ w.set_halign(Gtk.Align.START)
535
+ w.set_relief(Gtk.ReliefStyle.NONE)
536
+ w.connect('clicked', lambda button_widget: EditTaskCommandDialog(None, self, t['id']))
537
+ vbox.pack_start(w, True, True, 5)
538
538
 
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
539
 
543
- popover.add(vbox)
544
- popover.set_position(Gtk.PositionType.BOTTOM)
545
- popover.show_all()
540
+ # get_times, Ugly
541
+ # for key, val in utils.get_times(t).items():
542
+ # vbox.pack_start(Gtk.Label(key+": "+val), True, True, 5)
546
543
 
547
- return
544
+ popover.add(vbox)
545
+ popover.set_position(Gtk.PositionType.BOTTOM)
546
+ popover.show_all()
548
547
 
548
+ return
549
549
 
550
- self.app.start_task(None,t)
550
+ if self.modifyer_keys['shift']:
551
+ print('transfer session')
552
+ self.app.start_task(None,t,True)
553
+ elif self.modifyer_keys['alt']:
554
+ print('open_todo')
555
+ utils.open_todo(None,t)
556
+ else:
557
+ self.app.start_task(None,t)
551
558
 
552
559
  self.destroy()
553
560
 
@@ -596,29 +603,61 @@ class TaskWindow(Gtk.Window):
596
603
  utils.save_user_settings()
597
604
 
598
605
 
599
- def on_win_key_press_event(self, widget, ev):
606
+ def key_release(self, widget, event):
607
+ key = Gdk.keyval_name(event.keyval)
608
+ # utils.dbg("key_release",key,s="taskwindow",l=1)
609
+ # utils.dbg("key_release event.state",event.state,s="taskwindow",l=1)
610
+ if (event.state & Gdk.ModifierType.CONTROL_MASK):
611
+ self.modifyer_keys['control'] = False
612
+ if (event.state & Gdk.ModifierType.SHIFT_MASK):
613
+ self.modifyer_keys['shift'] = False
614
+ if (event.state & Gdk.ModifierType.MOD1_MASK):
615
+ self.modifyer_keys['alt'] = False
616
+
617
+
618
+ # print("modifyer_keys",self.modifyer_keys)
619
+
620
+
621
+ def key_press(self, widget, event):
600
622
 
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)
623
+ key = Gdk.keyval_name(event.keyval)
624
+ # utils.dbg("key_press",key,s="taskwindow",l=1)
625
+ # utils.dbg("key_press event.state",event.state,s="taskwindow",l=1)
626
+ # utils.dbg("key_press_event",event,s="taskwindow",l=1)
627
+ # utils.dbg("ModifierType is CONTROL_MASK",Gdk.ModifierType.CONTROL_MASK,s="taskwindow",l=3)
605
628
 
629
+ if (event.state & Gdk.ModifierType.CONTROL_MASK) or key == 'Control_L':
630
+ self.modifyer_keys['control'] = True
631
+ if (event.state & Gdk.ModifierType.SHIFT_MASK) or key == 'Shift_L':
632
+ self.modifyer_keys['shift'] = True
633
+ if (event.state & Gdk.ModifierType.MOD1_MASK) or key == 'Alt_L':
634
+ self.modifyer_keys['alt'] = True
635
+
636
+ # print("modifyer_keys", self.modifyer_keys)
637
+
606
638
 
607
639
  if key == "F11":
608
640
  self.toggle_fullscreen()
609
641
  elif key == "Escape":
610
642
  self.destroy()
611
- elif key in ['l','f'] and Gdk.ModifierType.CONTROL_MASK and not self.taskEntry.is_focus():
643
+ elif key in ['l','f'] and (event.state & Gdk.ModifierType.CONTROL_MASK) and not self.taskEntry.is_focus():
612
644
  self.taskEntry.grab_focus()
613
645
 
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')
646
+ elif key == "Return":
647
+ # print('self.get_focus()',self.get_focus())
648
+ # print('self.tasks_box.get_children()[1]',self.tasks_box.get_children()[1])
649
+ if self.taskEntry.is_focus():
650
+ # print("self.taskEntry has focus, do the thing")
651
+ if self.shown_tasks:
652
+ self.tasks_box.get_children()[0].emit('activate')
653
+ else:
654
+ self.new_task_button.emit('clicked')
655
+
656
+ elif self.shown_tasks and self.get_focus() in self.tasks_box.get_children():
657
+ # print("Return pressed on shown task select it",self.get_focus())
658
+ self.get_focus().emit('activate')
620
659
 
621
660
 
622
- def on_window_state_event(self, widget, ev):
623
- self.__is_fullscreen = bool(ev.new_window_state & Gdk.WindowState.FULLSCREEN)
661
+ def on_window_state_event(self, widget, event):
662
+ self.__is_fullscreen = bool(event.new_window_state & Gdk.WindowState.FULLSCREEN)
624
663
 
@@ -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)
@@ -414,7 +414,7 @@ def reindex(t=None):
414
414
 
415
415
  def reindex_all():
416
416
 
417
- db_query("DROP TABLE taskindex")
417
+ db_query("DROP TABLE taskindex",None,None,0)
418
418
  db_query("CREATE VIRTUAL TABLE taskindex USING fts5(id, extended_label, priority, status)")
419
419
  db_query("INSERT INTO taskindex(id, extended_label, priority, status) SELECT id, extended_label, priority, status FROM tasks WHERE tasks.status IS NOT '-1' ")
420
420
 
@@ -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.5
3
+ Version: 0.2.7
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,40 +92,37 @@ 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 install gir1.2-appindicator3-0.1 meson libdbus-glib-1-dev patchelf python3.12-venv 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
104
104
 
105
+ # At this point you may need to restart your terminal window
106
+
105
107
  # Install nowfocus
106
108
  pipx install nowfocus
107
109
 
108
110
  # Enter application directory
109
- cd ~/.local/pipx/nowfocus
110
-
111
- # Copy .desktop and icon to .local/share
112
- cp src/desktop-extras/nowfocus.desktop ~/.local/share/applications/nowfocus.desktop
113
- cp src/desktop-extras/nowfocus.svg ~/.local/share/icons/nowfocus.png
114
- cp src/desktop-extras/nowfocus.svg ~/.local/share/icons/hicolor/scalable/apps/nowfocus.svg
115
-
116
- # Setup autostart
117
- cp src/desktop-extras/nowfocus.desktop ~/.config/autostart/nowfocus.desktop
111
+ cd ~/.local/share/pipx/venvs/nowfocus/lib/python3.12/site-packages/nowfocus/desktop-extras
118
112
 
119
- # Set Super space as keybinding to raise task window
120
- chmod +x src/desktop-extras/set_gsettings_keybinding.sh
121
-
122
- 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
123
116
 
124
117
  # and now Focus!
125
118
  nowfocus
126
119
 
127
120
  ```
128
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
+
129
126
 
130
127
 
131
128
  ## Usage
@@ -138,7 +135,10 @@ Open nowfocus **Settings** from the indicator menu or tasks window and connect y
138
135
 
139
136
  - `F11` Toggle fullscreen
140
137
  - `Esc` Close task window
141
- - `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
142
142
  - `Ctrl + P` **Pause** current task
143
143
  - `Ctrl + D` Pause current task and mark it **Done**
144
144
  - `Ctrl + X` Cancel current task
@@ -1,10 +1,6 @@
1
1
  LICENSE
2
2
  README.md
3
3
  pyproject.toml
4
- src/desktop-extras/nowfocus.desktop
5
- src/desktop-extras/nowfocus.png
6
- src/desktop-extras/nowfocus.svg
7
- src/desktop-extras/set_gsettings_keybinding.sh
8
4
  src/nowfocus/__init__.py
9
5
  src/nowfocus/__main__.py
10
6
  src/nowfocus/conf.py
@@ -34,6 +30,10 @@ src/nowfocus/connectors/todotxt.py
34
30
  src/nowfocus/connectors/trello.py
35
31
  src/nowfocus/connectors/txt.py
36
32
  src/nowfocus/connectors/vikunja.py
33
+ src/nowfocus/desktop-extras/nowfocus.desktop
34
+ src/nowfocus/desktop-extras/nowfocus.png
35
+ src/nowfocus/desktop-extras/nowfocus.svg
36
+ src/nowfocus/desktop-extras/set_gsettings_keybinding.sh
37
37
  src/nowfocus/icon/cancel.png
38
38
  src/nowfocus/icon/cancel.svg
39
39
  src/nowfocus/icon/edit.png
@@ -0,0 +1 @@
1
+ nowfocus
@@ -1,2 +0,0 @@
1
- desktop-extras
2
- nowfocus
File without changes
File without changes
File without changes