NowFocus 0.2.6__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.
- {nowfocus-0.2.6/src/nowfocus.egg-info → nowfocus-0.2.7}/PKG-INFO +16 -18
- {nowfocus-0.2.6 → nowfocus-0.2.7}/README.md +15 -17
- {nowfocus-0.2.6 → nowfocus-0.2.7}/pyproject.toml +1 -1
- {nowfocus-0.2.6 → nowfocus-0.2.7}/src/nowfocus/__main__.py +6 -5
- {nowfocus-0.2.6 → nowfocus-0.2.7}/src/nowfocus/connectors/trello.py +6 -6
- {nowfocus-0.2.6 → nowfocus-0.2.7}/src/nowfocus/settings.py +3 -3
- {nowfocus-0.2.6 → nowfocus-0.2.7}/src/nowfocus/task_window.py +131 -92
- {nowfocus-0.2.6 → nowfocus-0.2.7}/src/nowfocus/utils.py +4 -2
- {nowfocus-0.2.6 → nowfocus-0.2.7/src/nowfocus.egg-info}/PKG-INFO +16 -18
- {nowfocus-0.2.6 → nowfocus-0.2.7}/LICENSE +0 -0
- {nowfocus-0.2.6 → nowfocus-0.2.7}/setup.cfg +0 -0
- {nowfocus-0.2.6 → nowfocus-0.2.7}/src/nowfocus/__init__.py +0 -0
- {nowfocus-0.2.6 → nowfocus-0.2.7}/src/nowfocus/conf.py +0 -0
- {nowfocus-0.2.6 → nowfocus-0.2.7}/src/nowfocus/connectors/activitywatch.py +0 -0
- {nowfocus-0.2.6 → nowfocus-0.2.7}/src/nowfocus/connectors/caldav.py +0 -0
- {nowfocus-0.2.6 → nowfocus-0.2.7}/src/nowfocus/connectors/csv.py +0 -0
- {nowfocus-0.2.6 → nowfocus-0.2.7}/src/nowfocus/connectors/psc_timetracker.py +0 -0
- {nowfocus-0.2.6 → nowfocus-0.2.7}/src/nowfocus/connectors/taskwarrior.py +0 -0
- {nowfocus-0.2.6 → nowfocus-0.2.7}/src/nowfocus/connectors/timewarrior.py +0 -0
- {nowfocus-0.2.6 → nowfocus-0.2.7}/src/nowfocus/connectors/todo_template.py +0 -0
- {nowfocus-0.2.6 → nowfocus-0.2.7}/src/nowfocus/connectors/todotxt.py +0 -0
- {nowfocus-0.2.6 → nowfocus-0.2.7}/src/nowfocus/connectors/txt.py +0 -0
- {nowfocus-0.2.6 → nowfocus-0.2.7}/src/nowfocus/connectors/vikunja.py +0 -0
- {nowfocus-0.2.6 → nowfocus-0.2.7}/src/nowfocus/desktop-extras/nowfocus.desktop +0 -0
- {nowfocus-0.2.6 → nowfocus-0.2.7}/src/nowfocus/desktop-extras/nowfocus.png +0 -0
- {nowfocus-0.2.6 → nowfocus-0.2.7}/src/nowfocus/desktop-extras/nowfocus.svg +0 -0
- {nowfocus-0.2.6 → nowfocus-0.2.7}/src/nowfocus/desktop-extras/set_gsettings_keybinding.sh +0 -0
- {nowfocus-0.2.6 → nowfocus-0.2.7}/src/nowfocus/example-todo.txt +0 -0
- {nowfocus-0.2.6 → nowfocus-0.2.7}/src/nowfocus/icon/cancel.png +0 -0
- {nowfocus-0.2.6 → nowfocus-0.2.7}/src/nowfocus/icon/cancel.svg +0 -0
- {nowfocus-0.2.6 → nowfocus-0.2.7}/src/nowfocus/icon/edit.png +0 -0
- {nowfocus-0.2.6 → nowfocus-0.2.7}/src/nowfocus/icon/edit.svg +0 -0
- {nowfocus-0.2.6 → nowfocus-0.2.7}/src/nowfocus/icon/icon-0.svg +0 -0
- {nowfocus-0.2.6 → nowfocus-0.2.7}/src/nowfocus/icon/icon-1.svg +0 -0
- {nowfocus-0.2.6 → nowfocus-0.2.7}/src/nowfocus/icon/icon-2.svg +0 -0
- {nowfocus-0.2.6 → nowfocus-0.2.7}/src/nowfocus/icon/icon-3.svg +0 -0
- {nowfocus-0.2.6 → nowfocus-0.2.7}/src/nowfocus/icon/icon-4.svg +0 -0
- {nowfocus-0.2.6 → nowfocus-0.2.7}/src/nowfocus/icon/icon-5.svg +0 -0
- {nowfocus-0.2.6 → nowfocus-0.2.7}/src/nowfocus/icon/icon-6.svg +0 -0
- {nowfocus-0.2.6 → nowfocus-0.2.7}/src/nowfocus/icon/icon-7.svg +0 -0
- {nowfocus-0.2.6 → nowfocus-0.2.7}/src/nowfocus/icon/icon-8.svg +0 -0
- {nowfocus-0.2.6 → nowfocus-0.2.7}/src/nowfocus/icon/icon-9.svg +0 -0
- {nowfocus-0.2.6 → nowfocus-0.2.7}/src/nowfocus/icon/icon.svg +0 -0
- {nowfocus-0.2.6 → nowfocus-0.2.7}/src/nowfocus/icon/mark-done.png +0 -0
- {nowfocus-0.2.6 → nowfocus-0.2.7}/src/nowfocus/icon/mark-done.svg +0 -0
- {nowfocus-0.2.6 → nowfocus-0.2.7}/src/nowfocus/icon/pause.png +0 -0
- {nowfocus-0.2.6 → nowfocus-0.2.7}/src/nowfocus/icon/pause.svg +0 -0
- {nowfocus-0.2.6 → nowfocus-0.2.7}/src/nowfocus/icon/settings.png +0 -0
- {nowfocus-0.2.6 → nowfocus-0.2.7}/src/nowfocus/icon/settings.svg +0 -0
- {nowfocus-0.2.6 → nowfocus-0.2.7}/src/nowfocus/new_task_dialog.py +0 -0
- {nowfocus-0.2.6 → nowfocus-0.2.7}/src/nowfocus/session_edit_dialog.py +0 -0
- {nowfocus-0.2.6 → nowfocus-0.2.7}/src/nowfocus/session_options.py +0 -0
- {nowfocus-0.2.6 → nowfocus-0.2.7}/src/nowfocus/sessions.csv +0 -0
- {nowfocus-0.2.6 → nowfocus-0.2.7}/src/nowfocus/sound/bell-xylophone-g.mp3 +0 -0
- {nowfocus-0.2.6 → nowfocus-0.2.7}/src/nowfocus/sound/dinner-bell.mp3 +0 -0
- {nowfocus-0.2.6 → nowfocus-0.2.7}/src/nowfocus/sound/xylophone-chord.mp3 +0 -0
- {nowfocus-0.2.6 → nowfocus-0.2.7}/src/nowfocus/styles.css +0 -0
- {nowfocus-0.2.6 → nowfocus-0.2.7}/src/nowfocus.egg-info/SOURCES.txt +0 -0
- {nowfocus-0.2.6 → nowfocus-0.2.7}/src/nowfocus.egg-info/dependency_links.txt +0 -0
- {nowfocus-0.2.6 → nowfocus-0.2.7}/src/nowfocus.egg-info/entry_points.txt +0 -0
- {nowfocus-0.2.6 → nowfocus-0.2.7}/src/nowfocus.egg-info/requires.txt +0 -0
- {nowfocus-0.2.6 → nowfocus-0.2.7}/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.
|
|
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,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
|
|
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
|
|
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
|
|
114
|
-
cp
|
|
115
|
-
cp
|
|
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
|
|
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
|
|
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
|
|
68
|
-
cp
|
|
69
|
-
cp
|
|
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
|
|
@@ -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
|
-
|
|
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(
|
|
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,
|
|
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,
|
|
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
|
|
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.
|
|
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
|
-
|
|
476
|
+
# print('event',event)
|
|
477
|
+
print("select_task self.modifyer_keys", self.modifyer_keys)
|
|
477
478
|
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
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
|
-
|
|
484
|
+
popover.foreach(lambda child: child.destroy())
|
|
484
485
|
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
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
|
-
|
|
528
|
+
disabled = ""
|
|
532
529
|
|
|
533
|
-
w.
|
|
534
|
-
|
|
535
|
-
w
|
|
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
|
-
|
|
544
|
-
|
|
545
|
-
|
|
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
|
-
|
|
544
|
+
popover.add(vbox)
|
|
545
|
+
popover.set_position(Gtk.PositionType.BOTTOM)
|
|
546
|
+
popover.show_all()
|
|
548
547
|
|
|
548
|
+
return
|
|
549
549
|
|
|
550
|
-
self.
|
|
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
|
|
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(
|
|
602
|
-
utils.dbg("
|
|
603
|
-
# utils.dbg("
|
|
604
|
-
utils.dbg("
|
|
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"
|
|
615
|
-
# print(
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
self.
|
|
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,
|
|
623
|
-
self.__is_fullscreen = bool(
|
|
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 = '
|
|
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.
|
|
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,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
|
|
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
|
|
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
|
|
114
|
-
cp
|
|
115
|
-
cp
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|