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.
- {nowfocus-0.2.6/src/nowfocus.egg-info → nowfocus-0.2.8}/PKG-INFO +16 -18
- {nowfocus-0.2.6 → nowfocus-0.2.8}/README.md +15 -17
- {nowfocus-0.2.6 → nowfocus-0.2.8}/pyproject.toml +1 -1
- {nowfocus-0.2.6 → nowfocus-0.2.8}/src/nowfocus/__main__.py +13 -9
- {nowfocus-0.2.6 → nowfocus-0.2.8}/src/nowfocus/connectors/trello.py +6 -6
- nowfocus-0.2.8/src/nowfocus/icon/icon-red.svg +101 -0
- {nowfocus-0.2.6 → nowfocus-0.2.8}/src/nowfocus/icon/icon.svg +12 -1
- {nowfocus-0.2.6 → nowfocus-0.2.8}/src/nowfocus/settings.py +3 -3
- {nowfocus-0.2.6 → nowfocus-0.2.8}/src/nowfocus/task_window.py +133 -106
- {nowfocus-0.2.6 → nowfocus-0.2.8}/src/nowfocus/utils.py +4 -2
- {nowfocus-0.2.6 → nowfocus-0.2.8/src/nowfocus.egg-info}/PKG-INFO +16 -18
- {nowfocus-0.2.6 → nowfocus-0.2.8}/src/nowfocus.egg-info/SOURCES.txt +1 -1
- nowfocus-0.2.6/src/nowfocus/desktop-extras/set_gsettings_keybinding.sh +0 -51
- {nowfocus-0.2.6 → nowfocus-0.2.8}/LICENSE +0 -0
- {nowfocus-0.2.6 → nowfocus-0.2.8}/setup.cfg +0 -0
- {nowfocus-0.2.6 → nowfocus-0.2.8}/src/nowfocus/__init__.py +0 -0
- {nowfocus-0.2.6 → nowfocus-0.2.8}/src/nowfocus/conf.py +0 -0
- {nowfocus-0.2.6 → nowfocus-0.2.8}/src/nowfocus/connectors/activitywatch.py +0 -0
- {nowfocus-0.2.6 → nowfocus-0.2.8}/src/nowfocus/connectors/caldav.py +0 -0
- {nowfocus-0.2.6 → nowfocus-0.2.8}/src/nowfocus/connectors/csv.py +0 -0
- {nowfocus-0.2.6 → nowfocus-0.2.8}/src/nowfocus/connectors/psc_timetracker.py +0 -0
- {nowfocus-0.2.6 → nowfocus-0.2.8}/src/nowfocus/connectors/taskwarrior.py +0 -0
- {nowfocus-0.2.6 → nowfocus-0.2.8}/src/nowfocus/connectors/timewarrior.py +0 -0
- {nowfocus-0.2.6 → nowfocus-0.2.8}/src/nowfocus/connectors/todo_template.py +0 -0
- {nowfocus-0.2.6 → nowfocus-0.2.8}/src/nowfocus/connectors/todotxt.py +0 -0
- {nowfocus-0.2.6 → nowfocus-0.2.8}/src/nowfocus/connectors/txt.py +0 -0
- {nowfocus-0.2.6 → nowfocus-0.2.8}/src/nowfocus/connectors/vikunja.py +0 -0
- {nowfocus-0.2.6 → nowfocus-0.2.8}/src/nowfocus/desktop-extras/nowfocus.desktop +0 -0
- {nowfocus-0.2.6 → nowfocus-0.2.8}/src/nowfocus/desktop-extras/nowfocus.png +0 -0
- {nowfocus-0.2.6 → nowfocus-0.2.8}/src/nowfocus/desktop-extras/nowfocus.svg +0 -0
- {nowfocus-0.2.6 → nowfocus-0.2.8}/src/nowfocus/example-todo.txt +0 -0
- {nowfocus-0.2.6 → nowfocus-0.2.8}/src/nowfocus/icon/cancel.png +0 -0
- {nowfocus-0.2.6 → nowfocus-0.2.8}/src/nowfocus/icon/cancel.svg +0 -0
- {nowfocus-0.2.6 → nowfocus-0.2.8}/src/nowfocus/icon/edit.png +0 -0
- {nowfocus-0.2.6 → nowfocus-0.2.8}/src/nowfocus/icon/edit.svg +0 -0
- {nowfocus-0.2.6 → nowfocus-0.2.8}/src/nowfocus/icon/icon-0.svg +0 -0
- {nowfocus-0.2.6 → nowfocus-0.2.8}/src/nowfocus/icon/icon-1.svg +0 -0
- {nowfocus-0.2.6 → nowfocus-0.2.8}/src/nowfocus/icon/icon-2.svg +0 -0
- {nowfocus-0.2.6 → nowfocus-0.2.8}/src/nowfocus/icon/icon-3.svg +0 -0
- {nowfocus-0.2.6 → nowfocus-0.2.8}/src/nowfocus/icon/icon-4.svg +0 -0
- {nowfocus-0.2.6 → nowfocus-0.2.8}/src/nowfocus/icon/icon-5.svg +0 -0
- {nowfocus-0.2.6 → nowfocus-0.2.8}/src/nowfocus/icon/icon-6.svg +0 -0
- {nowfocus-0.2.6 → nowfocus-0.2.8}/src/nowfocus/icon/icon-7.svg +0 -0
- {nowfocus-0.2.6 → nowfocus-0.2.8}/src/nowfocus/icon/icon-8.svg +0 -0
- {nowfocus-0.2.6 → nowfocus-0.2.8}/src/nowfocus/icon/icon-9.svg +0 -0
- {nowfocus-0.2.6 → nowfocus-0.2.8}/src/nowfocus/icon/mark-done.png +0 -0
- {nowfocus-0.2.6 → nowfocus-0.2.8}/src/nowfocus/icon/mark-done.svg +0 -0
- {nowfocus-0.2.6 → nowfocus-0.2.8}/src/nowfocus/icon/pause.png +0 -0
- {nowfocus-0.2.6 → nowfocus-0.2.8}/src/nowfocus/icon/pause.svg +0 -0
- {nowfocus-0.2.6 → nowfocus-0.2.8}/src/nowfocus/icon/settings.png +0 -0
- {nowfocus-0.2.6 → nowfocus-0.2.8}/src/nowfocus/icon/settings.svg +0 -0
- {nowfocus-0.2.6 → nowfocus-0.2.8}/src/nowfocus/new_task_dialog.py +0 -0
- {nowfocus-0.2.6 → nowfocus-0.2.8}/src/nowfocus/session_edit_dialog.py +0 -0
- {nowfocus-0.2.6 → nowfocus-0.2.8}/src/nowfocus/session_options.py +0 -0
- {nowfocus-0.2.6 → nowfocus-0.2.8}/src/nowfocus/sessions.csv +0 -0
- {nowfocus-0.2.6 → nowfocus-0.2.8}/src/nowfocus/sound/bell-xylophone-g.mp3 +0 -0
- {nowfocus-0.2.6 → nowfocus-0.2.8}/src/nowfocus/sound/dinner-bell.mp3 +0 -0
- {nowfocus-0.2.6 → nowfocus-0.2.8}/src/nowfocus/sound/xylophone-chord.mp3 +0 -0
- {nowfocus-0.2.6 → nowfocus-0.2.8}/src/nowfocus/styles.css +0 -0
- {nowfocus-0.2.6 → nowfocus-0.2.8}/src/nowfocus.egg-info/dependency_links.txt +0 -0
- {nowfocus-0.2.6 → nowfocus-0.2.8}/src/nowfocus.egg-info/entry_points.txt +0 -0
- {nowfocus-0.2.6 → nowfocus-0.2.8}/src/nowfocus.egg-info/requires.txt +0 -0
- {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.
|
|
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
|
|
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
|
|
@@ -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-
|
|
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 >
|
|
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
|
-
|
|
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
|
-
|
|
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-
|
|
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(
|
|
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 = {}
|
|
@@ -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,
|
|
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
|
|
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.
|
|
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
|
-
|
|
464
|
+
# print('event',event)
|
|
465
|
+
print("select_task self.modifyer_keys", self.modifyer_keys)
|
|
477
466
|
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
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
|
-
|
|
472
|
+
popover.foreach(lambda child: child.destroy())
|
|
484
473
|
|
|
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+"")
|
|
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
|
-
|
|
516
|
+
disabled = ""
|
|
532
517
|
|
|
533
|
-
w.
|
|
534
|
-
|
|
535
|
-
w
|
|
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
|
-
|
|
544
|
-
|
|
545
|
-
|
|
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
|
-
|
|
532
|
+
popover.add(vbox)
|
|
533
|
+
popover.set_position(Gtk.PositionType.BOTTOM)
|
|
534
|
+
popover.show_all()
|
|
548
535
|
|
|
536
|
+
return
|
|
549
537
|
|
|
550
|
-
self.
|
|
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
|
|
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
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
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"
|
|
615
|
-
# print(
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
self.
|
|
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,
|
|
623
|
-
self.__is_fullscreen = bool(
|
|
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 = '
|
|
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.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
|
|
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
|
|
@@ -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
|
|
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
|