259 lines
9.1 KiB
Python
259 lines
9.1 KiB
Python
import subprocess
|
|
from typing import Any
|
|
|
|
import gi
|
|
|
|
gi.require_version("Gtk", "3.0")
|
|
from gi.repository import GObject, Gtk
|
|
|
|
from sublime.config import AppConfiguration, ServerConfiguration
|
|
from sublime.server import Server
|
|
from sublime.ui.common import EditFormDialog, IconButton
|
|
|
|
|
|
class EditServerDialog(EditFormDialog):
|
|
entity_name: str = "Server"
|
|
initial_size = (450, 250)
|
|
text_fields = [
|
|
("Name", "name", False),
|
|
("Server address", "server_address", False),
|
|
("Local network address", "local_network_address", False),
|
|
("Local network SSID", "local_network_ssid", False),
|
|
("Username", "username", False),
|
|
("Password", "password", True),
|
|
]
|
|
boolean_fields = [
|
|
("Play queue sync enabled", "sync_enabled"),
|
|
("Do not verify certificate", "disable_cert_verify"),
|
|
]
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
test_server = Gtk.Button(label="Test Connection to Server")
|
|
test_server.connect("clicked", self.on_test_server_clicked)
|
|
|
|
open_in_browser = Gtk.Button(label="Open in Browser")
|
|
open_in_browser.connect("clicked", self.on_open_in_browser_clicked)
|
|
|
|
self.extra_buttons = [(test_server, None), (open_in_browser, None)]
|
|
|
|
super().__init__(*args, **kwargs)
|
|
|
|
def on_test_server_clicked(self, event: Any):
|
|
# Instantiate the server.
|
|
server_address = self.data["server_address"].get_text()
|
|
server = Server(
|
|
name=self.data["name"].get_text(),
|
|
hostname=server_address,
|
|
username=self.data["username"].get_text(),
|
|
password=self.data["password"].get_text(),
|
|
disable_cert_verify=self.data["disable_cert_verify"].get_active(),
|
|
)
|
|
|
|
# Try to ping, and show a message box with whether or not it worked.
|
|
try:
|
|
server.ping()
|
|
dialog = Gtk.MessageDialog(
|
|
transient_for=self,
|
|
message_type=Gtk.MessageType.INFO,
|
|
buttons=Gtk.ButtonsType.OK,
|
|
text="Connection to server successful.",
|
|
)
|
|
dialog.format_secondary_markup(
|
|
f"Connection to {server_address} successful."
|
|
)
|
|
except Exception as err:
|
|
dialog = Gtk.MessageDialog(
|
|
transient_for=self,
|
|
message_type=Gtk.MessageType.ERROR,
|
|
buttons=Gtk.ButtonsType.OK,
|
|
text="Connection to server unsuccessful.",
|
|
)
|
|
dialog.format_secondary_markup(
|
|
f"Connection to {server_address} resulted in the following "
|
|
f"error:\n\n{err}"
|
|
)
|
|
|
|
dialog.run()
|
|
dialog.destroy()
|
|
|
|
def on_open_in_browser_clicked(self, event: Any):
|
|
subprocess.call(["xdg-open", self.data["server_address"].get_text()])
|
|
|
|
|
|
class ConfigureServersDialog(Gtk.Dialog):
|
|
__gsignals__ = {
|
|
"server-list-changed": (
|
|
GObject.SignalFlags.RUN_FIRST,
|
|
GObject.TYPE_NONE,
|
|
(object,),
|
|
),
|
|
"connected-server-changed": (
|
|
GObject.SignalFlags.RUN_FIRST,
|
|
GObject.TYPE_NONE,
|
|
(object,),
|
|
),
|
|
}
|
|
|
|
def __init__(self, parent: Any, config: AppConfiguration):
|
|
Gtk.Dialog.__init__(
|
|
self,
|
|
title="Configure Servers",
|
|
transient_for=parent,
|
|
flags=0,
|
|
add_buttons=(),
|
|
)
|
|
|
|
self.server_configs = config.servers
|
|
self.selected_server_index = config.current_server_index
|
|
self.set_default_size(500, 300)
|
|
|
|
# Flow box to hold the server list and the buttons.
|
|
flowbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
|
|
|
|
# Server List
|
|
self.server_list = Gtk.ListBox(activate_on_single_click=False)
|
|
self.server_list.connect(
|
|
"selected-rows-changed", self.server_list_on_selected_rows_changed
|
|
)
|
|
self.server_list.connect("row-activated", self.on_server_list_activate)
|
|
flowbox.pack_start(self.server_list, True, True, 10)
|
|
|
|
button_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
|
|
# Tuples: (button, action function, pack side, requires_selection)
|
|
# Add all of the buttons to the button box.
|
|
self.buttons = [
|
|
(
|
|
IconButton("document-edit-symbolic", label="Edit...", relief=True,),
|
|
lambda e: self.on_edit_clicked(False),
|
|
"start",
|
|
True,
|
|
),
|
|
(
|
|
IconButton("list-add-symbolic", label="Add...", relief=True,),
|
|
lambda e: self.on_edit_clicked(True),
|
|
"start",
|
|
False,
|
|
),
|
|
(
|
|
IconButton("list-remove-symbolic", label="Remove", relief=True,),
|
|
self.on_remove_clicked,
|
|
"start",
|
|
True,
|
|
),
|
|
(
|
|
IconButton("window-close-symbolic", label="Close", relief=True,),
|
|
lambda _: self.close(),
|
|
"end",
|
|
False,
|
|
),
|
|
(
|
|
IconButton(
|
|
"network-transmit-receive-symbolic", label="Connect", relief=True,
|
|
),
|
|
self.on_connect_clicked,
|
|
"end",
|
|
True,
|
|
),
|
|
]
|
|
for button_cfg in self.buttons:
|
|
btn, action, pack_end, requires_selection = button_cfg
|
|
|
|
if pack_end == "end":
|
|
button_box.pack_end(btn, False, True, 5)
|
|
else:
|
|
button_box.pack_start(btn, False, True, 5)
|
|
|
|
btn.connect("clicked", action)
|
|
|
|
flowbox.pack_end(button_box, False, False, 0)
|
|
|
|
# Add the flowbox to the dialog and show the dialog.
|
|
content_area = self.get_content_area()
|
|
content_area.pack_start(flowbox, True, True, 10)
|
|
|
|
self.show_all()
|
|
self.refresh_server_list()
|
|
self.server_list_on_selected_rows_changed(None)
|
|
|
|
def refresh_server_list(self):
|
|
# Clear out the list.
|
|
for el in self.server_list:
|
|
self.server_list.remove(el)
|
|
|
|
# Add all of the rows for each of the servers.
|
|
for i, config in enumerate(self.server_configs):
|
|
box = Gtk.Box()
|
|
image = Gtk.Image(margin=5)
|
|
if i == self.selected_server_index:
|
|
image.set_from_icon_name(
|
|
"network-transmit-receive-symbolic", Gtk.IconSize.SMALL_TOOLBAR,
|
|
)
|
|
|
|
box.add(image)
|
|
|
|
server_name_label = Gtk.Label(label=config.name)
|
|
server_name_label.set_halign(Gtk.Align.START)
|
|
box.add(server_name_label)
|
|
self.server_list.add(box)
|
|
|
|
# Show them, and select the current server.
|
|
self.show_all()
|
|
if self.selected_server_index is not None and self.selected_server_index >= 0:
|
|
self.server_list.select_row(
|
|
self.server_list.get_row_at_index(self.selected_server_index)
|
|
)
|
|
|
|
def on_remove_clicked(self, event: Any):
|
|
selected = self.server_list.get_selected_row()
|
|
if selected:
|
|
del self.server_configs[selected.get_index()]
|
|
self.refresh_server_list()
|
|
self.emit("server-list-changed", self.server_configs)
|
|
|
|
def on_edit_clicked(self, add: bool):
|
|
if add:
|
|
dialog = EditServerDialog(self)
|
|
else:
|
|
selected_index = self.server_list.get_selected_row().get_index()
|
|
dialog = EditServerDialog(self, self.server_configs[selected_index])
|
|
|
|
result = dialog.run()
|
|
if result == Gtk.ResponseType.OK:
|
|
# Create a new server configuration to use.
|
|
new_config = ServerConfiguration(
|
|
name=dialog.data["name"].get_text(),
|
|
server_address=dialog.data["server_address"].get_text(),
|
|
local_network_address=dialog.data["local_network_address"].get_text(),
|
|
local_network_ssid=dialog.data["local_network_ssid"].get_text(),
|
|
username=dialog.data["username"].get_text(),
|
|
password=dialog.data["password"].get_text(),
|
|
sync_enabled=dialog.data["sync_enabled"].get_active(),
|
|
disable_cert_verify=dialog.data["disable_cert_verify"].get_active(),
|
|
)
|
|
|
|
if add:
|
|
self.server_configs.append(new_config)
|
|
else:
|
|
self.server_configs[selected_index] = new_config
|
|
|
|
self.refresh_server_list()
|
|
self.emit("server-list-changed", self.server_configs)
|
|
|
|
dialog.destroy()
|
|
|
|
def on_server_list_activate(self, *args):
|
|
self.on_connect_clicked(None)
|
|
|
|
def on_connect_clicked(self, event: Any):
|
|
selected_index = self.server_list.get_selected_row().get_index()
|
|
self.emit("connected-server-changed", selected_index)
|
|
self.close()
|
|
|
|
def server_list_on_selected_rows_changed(self, event: Any):
|
|
# Update the state of the buttons depending on whether or not a row is
|
|
# selected in the server list.
|
|
has_selection = self.server_list.get_selected_row()
|
|
|
|
for button, *_, requires_selection in self.buttons:
|
|
button.set_sensitive(bool(not requires_selection or has_selection))
|