roundabout,
created on Tuesday, 3 December 2024, 19:08:20 (1733252900),
received on Thursday, 12 December 2024, 14:59:12 (1734015552)
Author identity: vlad <vlad.muntoiu@gmail.com>
4800d6fb4f06f37c408ce5d51e0e908caf793928
izvor.ui
@@ -68,12 +68,11 @@
</object>
</child>
</object>
<object class="GtkEntryBuffer" id="search-query-buffer"/>
<object class="GtkApplicationWindow" id="root">
<property name="can-focus">False</property>
<property name="default-width">576</property>
<property name="default-height">640</property>
<property name="icon-name">edit-find</property>
<property name="icon-name">edit-find-symbolic</property>
<child>
<object class="GtkScrolledWindow" id="results-scroll-area">
<property name="visible">True</property>
@@ -172,4 +171,5 @@
</object>
</child>
</object>
<object class="GtkEntryBuffer" id="search-query-buffer"/>
</interface>
main.py
@@ -24,6 +24,8 @@ import gbulb
from pathlib import Path
from typing import AsyncIterable, AsyncIterator, Collection, TypeVar, Iterable, Callable, Any
from twisted.conch.insults.text import attributes
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk, Gdk, Pango, GLib
@@ -95,6 +97,7 @@ class Izvor(Gtk.Application):
SYSTEM_DATA = Path("/usr/share/izvor")
SYSTEM_PROVIDERS = SYSTEM_DATA / "providers"
SYSTEM_PROVIDER_CONFIGS = SYSTEM_CONFIGS / "providers"
ENABLED_PROVIDERS_FILE = USER_CONFIGS / "enabled_providers"
def __init__(self):
super().__init__(application_id="com.roundabout-host.roundabout.izvor")
@@ -105,6 +108,7 @@ class Izvor(Gtk.Application):
self.window = self.builder.get_object("root")
self.window.connect("destroy", self.kill)
self.window.connect("key-press-event", self.check_escape)
self.window.set_title("Izvor")
if not os.getenv("XDG_DATA_HOME"):
print("XDG_DATA_HOME is not set. Using default path.")
@@ -132,7 +136,21 @@ class Izvor(Gtk.Application):
print(f"Available providers: {list(self.available_providers.keys())}")
self.permanently_enabled_providers = self.available_providers.copy()
if not self.ENABLED_PROVIDERS_FILE.exists():
self.ENABLED_PROVIDERS_FILE.touch()
with open(self.ENABLED_PROVIDERS_FILE, "w") as f:
for provider in self.available_providers:
f.write(provider + "\n")
self.permanently_enabled_providers = {}
with open(self.ENABLED_PROVIDERS_FILE, "r") as f:
for line in f:
provider = line.strip()
if provider in self.available_providers:
self.permanently_enabled_providers[provider] = self.available_providers[provider]
self.enabled_providers = self.permanently_enabled_providers.copy()
providers_menu = self.builder.get_object("providers-menu")
@@ -140,7 +158,7 @@ class Izvor(Gtk.Application):
self.providers = []
self.provider_checkboxes = {}
for provider in self.enabled_providers.values():
for provider in self.permanently_enabled_providers.values():
spec = importlib.util.spec_from_file_location(provider.stem, provider / "__init__.py")
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)
@@ -167,6 +185,7 @@ class Izvor(Gtk.Application):
"result-activated": execute_result,
"providers-menu-all-toggled": self.update_enabled_providers_all,
"menu-about": self.about,
"menu-providers": self.provider_menu,
}
)
@@ -203,6 +222,66 @@ class Izvor(Gtk.Application):
about_window.connect("response", lambda _, __: about_window.destroy())
about_window.show_all()
def provider_menu(self, widget):
providers_builder = Gtk.Builder()
providers_builder.add_from_file("providers.ui")
providers_window = providers_builder.get_object("providers-window")
providers_window.connect("destroy", lambda _: providers_window.destroy())
providers_table = providers_builder.get_object("providers-table") # actually Gtk.Grid
rows = 0
for provider in self.available_providers.values():
spec = importlib.util.spec_from_file_location(provider.stem, provider / "__init__.py")
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)
loaded_provider = module.Provider({})
provider_label = Gtk.Label(label=loaded_provider.name)
provider_label.set_halign(Gtk.Align.START)
provider_label.set_valign(Gtk.Align.CENTER)
font_desc = Pango.FontDescription()
font_desc.set_weight(Pango.Weight.BOLD)
provider_label.override_font(font_desc)
provider_label.set_line_wrap(True)
provider_label.set_justify(Gtk.Justification.LEFT)
provider_description = Gtk.Label(label=loaded_provider.description)
provider_description.set_halign(Gtk.Align.START)
provider_description.set_valign(Gtk.Align.CENTER)
provider_description.set_justify(Gtk.Justification.LEFT)
provider_description.set_line_wrap(True)
icon = Gtk.Image.new_from_icon_name(loaded_provider.icon, Gtk.IconSize.LARGE_TOOLBAR)
icon.set_pixel_size(ICON_SIZE)
switch = Gtk.Switch()
switch.set_valign(Gtk.Align.CENTER)
switch.set_active(provider.stem in self.permanently_enabled_providers)
switch.connect("notify::active", self.update_permanently_enabled_providers, provider.stem)
providers_table.attach(icon, 0, rows, 1, 1)
providers_table.attach(provider_label, 1, rows, 1, 1)
providers_table.attach(provider_description, 2, rows, 1, 1)
providers_table.attach(switch, 3, rows, 1, 1)
provider_label.show()
provider_description.show()
rows += 1
providers_window.show_all()
def update_permanently_enabled_providers(self, widget, param, provider):
if widget.get_active():
self.permanently_enabled_providers[provider] = self.available_providers[provider]
else:
self.permanently_enabled_providers.pop(provider, None)
with open(self.ENABLED_PROVIDERS_FILE, "w") as f:
f.write("\n".join(self.permanently_enabled_providers.keys()))
async def update_results(self, widget):
print("Updating results...")
generators = []
providers.ui
@@ -0,0 +1,60 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.38.2 -->
<interface>
<requires lib="gtk+" version="3.24"/>
<object class="GtkWindow" id="providers-window">
<property name="can-focus">False</property>
<property name="title" translatable="yes">Search providers</property>
<property name="default-width">448</property>
<property name="default-height">320</property>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="label" translatable="yes">Changes made here will only apply when the application is restarted.</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkScrolledWindow">
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="hscrollbar-policy">never</property>
<property name="shadow-type">in</property>
<property name="max-content-height">768</property>
<property name="propagate-natural-width">True</property>
<child>
<object class="GtkViewport">
<property name="visible">True</property>
<property name="can-focus">False</property>
<child>
<!-- n-columns=1 n-rows=0 -->
<object class="GtkGrid" id="providers-table">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="row-spacing">4</property>
<property name="column-spacing">4</property>
</object>
</child>
</object>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
</object>
</interface>