org-editor/main.py

158 lines
4.9 KiB
Python
Raw Normal View History

2021-12-22 21:44:34 +00:00
#!/usr/bin/env python3
import sys
2021-12-26 19:57:59 +00:00
import os
import logging
import threading
import task_manager
APP_TITLE = "Org-mob"
DOCS_PATH = os.environ["ORG_PATH"]
2021-12-26 20:09:20 +00:00
STYLE_FILE_PATH = os.path.join(
os.path.dirname(os.path.abspath(__file__)),
"style.css")
2021-12-26 19:57:59 +00:00
2021-12-27 19:28:24 +00:00
MIN_TITLE_WIDTH_CHARS = 10
2021-12-22 21:44:34 +00:00
import gi
gi.require_version("Gtk", "4.0")
gi.require_version('Polkit', '1.0')
2021-12-26 19:57:59 +00:00
gi.require_version(namespace='Adw', version='1')
2021-12-26 20:09:20 +00:00
from gi.repository import Gtk, Polkit, GObject, Gio, Adw, Gdk
2021-12-22 21:44:34 +00:00
class MainWindow(Gtk.Window):
2021-12-27 19:28:24 +00:00
## Setup
def __init__(self, *, title, application, task_manager, with_titlebar=True):
2021-12-22 21:44:34 +00:00
super().__init__(title=title, application=application)
2021-12-26 19:57:59 +00:00
self.application = application
self.task_manager = task_manager
2021-12-27 19:28:24 +00:00
self.loading = 0
if with_titlebar:
self.header_bar = Gtk.HeaderBar()
# self.header_bar.set_show_close_button(True)
# self.header_bar.props.title = APP_TITLE
self.set_titlebar(self.header_bar)
self.progress_spinner = Gtk.Spinner()
self.progress_spinner.start()
self.header_bar.pack_end(self.progress_spinner)
else:
self.header_bar = None
self.progress_spinner = None
# self.main_box = Gtk.Box(name='main-box', vexpand=True, hexpand=True)
self.scrollview = Gtk.ScrolledWindow(vexpand=True, hexpand=True)
2021-12-27 19:28:24 +00:00
self.task_list = Gtk.ListBox(name='task-list')
self.scrollview.set_child(self.task_list)
2021-12-27 19:28:24 +00:00
# self.main_box.props.valign = Gtk.Align.CENTER
# self.main_box.props.halign = Gtk.Align.CENTER
# self.main_box.append(self.scrollview)
# self.set_child(self.main_box)
self.set_child(self.scrollview)
2021-12-27 19:28:24 +00:00
self.loading += 1
2021-12-26 19:57:59 +00:00
self.task_manager.get_task_list(self.on_task_list_ready)
2021-12-22 21:44:34 +00:00
2021-12-27 19:28:24 +00:00
## Rendering
2021-12-26 19:57:59 +00:00
def build_agenda_task_row(self, task):
2021-12-22 21:44:34 +00:00
row = Gtk.ListBoxRow()
2021-12-27 19:28:24 +00:00
hbox = Gtk.Box()
2021-12-22 21:44:34 +00:00
2021-12-26 19:57:59 +00:00
state_button = Gtk.Button.new_with_label(task.state or '')
2021-12-27 19:28:24 +00:00
state_button.props.css_classes = ('state-button',)
state_button.connect("clicked", self.on_status_button_clicked)
2021-12-26 19:57:59 +00:00
hbox.append(state_button)
2021-12-27 19:28:24 +00:00
clock_button = Gtk.Button.new_with_label('C')
clock_button.props.css_classes = ('clock-button',)
clock_button.connect("clicked", self.on_clock_button_clicked)
hbox.append(clock_button)
# task_name_label = Gtk.Entry(text=task.title, width_chars=max(MIN_TITLE_WIDTH_CHARS, len(task.title)))
task_name_label = Gtk.Label()
task_name_label.set_text(task.title)
2021-12-27 19:28:24 +00:00
task_name_label.props.css_classes = ('task-name',)
2021-12-26 19:57:59 +00:00
hbox.append(task_name_label)
row.set_child(hbox)
return row
2021-12-22 21:44:34 +00:00
2021-12-27 19:28:24 +00:00
def on_ready(self):
self.loading -= 1
if self.loading < 0:
self.loading = 0
elif self.loading == 0:
if self.progress_spinner is not None:
self.progress_spinner.stop()
## Callbacks
2021-12-26 19:57:59 +00:00
def on_task_list_ready(self, agenda):
2022-03-25 18:26:53 +00:00
# TODO: Avoid reconstructing the whole list every time
i = 0
child = self.task_list.get_first_child()
while child is not None:
was = child
child = child.get_next_sibling()
i += 1
self.task_list.remove(was)
2021-12-26 19:57:59 +00:00
for item in agenda.with_hour:
self.task_list.append(self.build_agenda_task_row(item))
2021-12-22 21:44:34 +00:00
2021-12-26 19:57:59 +00:00
for item in agenda.no_hour:
self.task_list.append(self.build_agenda_task_row(item))
2021-12-27 19:28:24 +00:00
self.on_ready()
## Reactions
def on_status_button_clicked(self, button):
print('Status button clicked: {}'.format(button))
def on_clock_button_clicked(self, button):
print('Clock button clicked: {}'.format(button))
2021-12-22 21:44:34 +00:00
class Application(Gtk.Application):
""" Main Aplication class """
def __init__(self):
super().__init__(application_id='com.codigoparallevar.gtk4-organizer',
flags=Gio.ApplicationFlags.FLAGS_NONE)
2021-12-26 19:57:59 +00:00
self.task_manager = task_manager.TaskManager(DOCS_PATH)
2021-12-22 21:44:34 +00:00
def do_activate(self):
win = self.props.active_window
if not win:
2021-12-26 20:09:20 +00:00
if os.path.exists(STYLE_FILE_PATH):
style_provider = Gtk.CssProvider()
Gtk.StyleContext.add_provider_for_display(Gdk.Display.get_default(), style_provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION)
style_provider.load_from_path(STYLE_FILE_PATH)
2021-12-26 19:57:59 +00:00
win = MainWindow(
title=APP_TITLE,
application=self,
task_manager=self.task_manager,
)
win.set_default_size(720, 1024) # PinePhone screen is 720x1440
2021-12-26 20:09:20 +00:00
2021-12-22 21:44:34 +00:00
win.present()
def main():
""" Run the main application"""
# GObject.threads_init()
2021-12-26 19:57:59 +00:00
logging.basicConfig(level=logging.INFO, format="%(levelname)-8s %(message)s")
2021-12-22 21:44:34 +00:00
app = Application()
return app.run(sys.argv)
if __name__ == '__main__':
main()