mirror of
https://github.com/morgan9e/warehouse
synced 2026-04-15 00:34:42 +09:00
242 lines
9.1 KiB
Python
242 lines
9.1 KiB
Python
# window.py
|
|
#
|
|
# Copyright 2023 Heliguy
|
|
#
|
|
# This program is free software: you can redistribute it and/or modify
|
|
# it under the terms of the GNU General Public License as published by
|
|
# the Free Software Foundation, version 3 of the License only.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
#
|
|
# SPDX-License-Identifier: GPL-3.0-only
|
|
|
|
import os
|
|
import pathlib
|
|
import subprocess
|
|
import re
|
|
import time
|
|
|
|
from gi.repository import Adw, Gdk, Gio, GLib, Gtk, GObject
|
|
from .host_info import HostInfo
|
|
from .packages_page import PackagesPage
|
|
from .remotes_page import RemotesPage
|
|
from .user_data_page import UserDataPage
|
|
from .snapshot_page import SnapshotPage
|
|
from .install_page import InstallPage
|
|
from .const import Config
|
|
from .error_toast import ErrorToast
|
|
|
|
@Gtk.Template(resource_path="/io/github/flattool/Warehouse/main_window/window.ui")
|
|
class WarehouseWindow(Adw.ApplicationWindow):
|
|
__gtype_name__ = "WarehouseWindow"
|
|
gtc = Gtk.Template.Child
|
|
main_breakpoint = gtc()
|
|
toast_overlay = gtc()
|
|
file_drop_stack = gtc()
|
|
main_split = gtc()
|
|
file_drop_view = gtc()
|
|
stack = gtc()
|
|
refresh_button = gtc()
|
|
navigation_row_listbox = gtc()
|
|
packages_row = gtc()
|
|
remotes_row = gtc()
|
|
user_data_row = gtc()
|
|
snapshots_row = gtc()
|
|
install_row = gtc()
|
|
|
|
def key_handler(self, controller, keyval, keycode, state):
|
|
if keyval == Gdk.KEY_w and state == Gdk.ModifierType.CONTROL_MASK:
|
|
self.close()
|
|
|
|
# if keyval == Gdk.KEY_Escape:
|
|
# self.batch_mode_button.set_active(False)
|
|
|
|
def start_loading(self, *args):
|
|
for _, page in self.pages.items():
|
|
if page.instance:
|
|
page.instance.start_loading()
|
|
|
|
def end_loading(self, *args):
|
|
for _, page in self.pages.items():
|
|
if page.instance:
|
|
page.instance.end_loading()
|
|
|
|
self.refresh_button.set_sensitive(True)
|
|
self.refresh_requested = False
|
|
|
|
def do_refresh(self):
|
|
self.start_loading()
|
|
self.refresh_button.set_sensitive(False)
|
|
HostInfo.get_flatpaks(callback=self.end_loading)
|
|
|
|
def refresh_handler(self, *args):
|
|
if len(self.refresh_lockouts) == 0:
|
|
self.do_refresh()
|
|
else:
|
|
self.refresh_requested = True
|
|
|
|
def add_refresh_lockout(self, reason):
|
|
self.refresh_lockouts.append(reason)
|
|
self.refresh_button.set_sensitive(False)
|
|
|
|
def remove_refresh_lockout(self, reason):
|
|
if reason in self.refresh_lockouts:
|
|
self.refresh_lockouts.remove(reason)
|
|
|
|
if len(self.refresh_lockouts) == 0:
|
|
if self.refresh_requested:
|
|
self.do_refresh()
|
|
else:
|
|
self.refresh_button.set_sensitive(True)
|
|
|
|
def navigation_handler(self, _, row):
|
|
row = row.get_child()
|
|
page = self.pages[row]
|
|
self.stack.set_visible_child(page)
|
|
self.settings.set_string("page-shown", page.page_name)
|
|
if self.main_split.get_collapsed():
|
|
self.main_split.set_show_sidebar(False)
|
|
|
|
def activate_row(self, nav_row):
|
|
idx = 0
|
|
while row := self.navigation_row_listbox.get_row_at_index(idx):
|
|
idx += 1
|
|
if row.get_child() is nav_row:
|
|
row.activate()
|
|
nav_row.grab_focus()
|
|
break
|
|
|
|
def save_sidebar_state(self, *args):
|
|
state = self.main_split.get_show_sidebar()
|
|
self.settings.set_boolean("sidebar-shown", state)
|
|
print(self.settings.get_boolean("sidebar-shown"))
|
|
|
|
def show_saved_page(self):
|
|
page_to_show = self.settings.get_string("page-shown")
|
|
page_found = False
|
|
for row, page in self.pages.items():
|
|
self.stack.add_child(page)
|
|
|
|
if page.page_name == page_to_show:
|
|
page_found = True
|
|
self.activate_row(row)
|
|
|
|
if not page_found:
|
|
self.navigation_row_listbox.get_row_at_index(0).activate()
|
|
|
|
def on_file_drop(self, drop_target, value, x, y):
|
|
try:
|
|
paks = []
|
|
remotes = []
|
|
for file in value:
|
|
path = file.get_path()
|
|
if path.endswith(".flatpak") or path.endswith(".flatpakref"):
|
|
paks.append(Gio.File.new_for_path(path))
|
|
elif path.endswith(".flatpakrepo"):
|
|
remotes.append(path)
|
|
else:
|
|
dialog = Adw.AlertDialog(
|
|
heading=_("Unsupported Filetype"),
|
|
body=_("Only .flatpak, .flatpakref, and .flatpakrepo files are supported."),
|
|
)
|
|
dialog.add_response("continue", _("OK"))
|
|
dialog.present(self)
|
|
return
|
|
|
|
if len(remotes) > 0 and len(paks) > 0:
|
|
dialog = Adw.AlertDialog(
|
|
heading=_("Mixed Filetypes"),
|
|
body=_("Flatpaks and remotes cannot be installed at the same time."),
|
|
)
|
|
dialog.add_css_class("error")
|
|
dialog.add_response("continue", _("OK"))
|
|
dialog.present(self)
|
|
return
|
|
|
|
if len(remotes) > 1:
|
|
dialog = Adw.AlertDialog(
|
|
heading=_("Too Many Remotes"),
|
|
body=_("Only one remote at a time is supported."),
|
|
)
|
|
dialog.add_response("continue", _("OK"))
|
|
dialog.present(self)
|
|
return
|
|
|
|
if len(remotes) == 1:
|
|
# Adding a remote
|
|
self.activate_row(self.remotes_row)
|
|
remotes_page = self.pages[self.remotes_row]
|
|
remotes_page.local_file_handler(remotes[0])
|
|
elif len(paks) > 0:
|
|
# Add packages
|
|
self.activate_row(self.install_row)
|
|
install_page = self.pages[self.install_row]
|
|
install_page.select_page.file_dialog_handler(paks)
|
|
|
|
except Exception as e:
|
|
self.toast_overlay.add_toast(ErrorToast(_("Could not open files"), str(e)).toast)
|
|
|
|
def on_drop_enter(self, *args):
|
|
self.file_drop_stack.set_visible_child(self.file_drop_view)
|
|
return 1
|
|
|
|
def on_drop_leave(self, *args):
|
|
self.file_drop_stack.set_visible_child(self.main_split)
|
|
|
|
def __init__(self, **kwargs):
|
|
super().__init__(**kwargs)
|
|
|
|
# Extra Object Creation
|
|
HostInfo.main_window = self
|
|
ErrorToast.main_window = self
|
|
self.settings = Gio.Settings.new("io.github.flattool.Warehouse")
|
|
self.pages = {
|
|
self.packages_row: PackagesPage(main_window=self),
|
|
self.remotes_row: RemotesPage(main_window=self),
|
|
self.user_data_row: UserDataPage(main_window=self),
|
|
self.snapshots_row: SnapshotPage(main_window=self),
|
|
self.install_row: InstallPage(main_window=self),
|
|
}
|
|
self.navigation_row_listbox.connect("row-activated", self.navigation_handler)
|
|
self.show_saved_page()
|
|
self.refresh_lockouts = []
|
|
self.refresh_requested = False
|
|
file_drop = Gtk.DropTarget.new(Gdk.FileList, Gdk.DragAction.COPY)
|
|
event_controller = Gtk.EventControllerKey()
|
|
|
|
# Apply
|
|
self.add_controller(file_drop)
|
|
self.add_controller(event_controller)
|
|
self.settings.bind("window-width", self, "default-width", Gio.SettingsBindFlags.DEFAULT)
|
|
self.settings.bind("window-height", self, "default-height", Gio.SettingsBindFlags.DEFAULT)
|
|
self.settings.bind("is-maximized", self, "maximized", Gio.SettingsBindFlags.DEFAULT)
|
|
self.settings.bind("is-fullscreen", self, "fullscreened", Gio.SettingsBindFlags.DEFAULT)
|
|
# self.scrolled_window.add_controller(file_drop)
|
|
# self.main_split.set_content(PackagesPage(self))
|
|
if Config.DEVEL:
|
|
self.add_css_class("devel")
|
|
|
|
# Connections
|
|
file_drop.connect("drop", self.on_file_drop)
|
|
file_drop.connect("enter", self.on_drop_enter)
|
|
file_drop.connect("leave", self.on_drop_leave)
|
|
event_controller.connect("key-pressed", self.key_handler)
|
|
# file_drop.connect("drop", self.drop_callback)
|
|
self.refresh_button.connect("clicked", self.refresh_handler)
|
|
|
|
# self.activate_row(self.user_data_row)
|
|
# self.main_split.set_show_sidebar(self.settings.get_boolean("sidebar-shown"))
|
|
# GLib.idle_add(lambda *_: self.main_split.set_show_sidebar(False))
|
|
# print(self.settings.get_boolean("sidebar-shown"))
|
|
# self.main_split.connect("notify::show-sidebar", self.save_sidebar_state)
|
|
|
|
self.start_loading()
|
|
HostInfo.get_flatpaks(callback=self.end_loading)
|
|
# GLib.idle_add(lambda *_: self.main_split.set_show_sidebar(False))
|