import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
from .host_item import HostItem
from models import VPNType
class ActiveLocationCard:
def __init__(self, location, customer_name, callbacks):
self.location = location
self.customer_name = customer_name
self.callbacks = callbacks
self.widget = self._create_widget()
def _create_widget(self):
# Clean card layout - just a box with proper spacing
location_vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=8)
# Location header with controls
header_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=12)
location_vbox.pack_start(header_box, False, False, 0)
# Location info
info_vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=2)
header_box.pack_start(info_vbox, True, True, 0)
# Location name with VPN type
location_label = Gtk.Label()
location_label.set_markup(f"📍 {self.location.name}")
location_label.set_halign(Gtk.Align.START)
info_vbox.pack_start(location_label, False, False, 0)
# VPN type
vpn_icons = {
VPNType.OPENVPN: "🔒",
VPNType.WIREGUARD: "⚡",
VPNType.IPSEC: "🛡️"
}
vpn_icon = vpn_icons.get(self.location.vpn_type, "🔑")
type_label = Gtk.Label()
type_label.set_markup(f"{vpn_icon} {self.location.vpn_type.value} VPN")
type_label.set_halign(Gtk.Align.START)
info_vbox.pack_start(type_label, False, False, 0)
# Status and controls
controls_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=8)
header_box.pack_end(controls_box, False, False, 0)
# Status
status_text = "● Connected" if self.location.connected else "○ Disconnected"
status_color = "#4caf50" if self.location.connected else "#999"
status_label = Gtk.Label()
status_label.set_markup(f"{status_text}")
controls_box.pack_start(status_label, False, False, 0)
# Connect/Disconnect button
btn_text = "Disconnect" if self.location.connected else "Connect"
connect_btn = Gtk.Button(label=btn_text)
if self.location.connected:
connect_btn.get_style_context().add_class("destructive-action")
else:
connect_btn.get_style_context().add_class("suggested-action")
connect_btn.connect("clicked", self._on_connect_clicked)
controls_box.pack_start(connect_btn, False, False, 0)
# X button to deactivate (close button style)
close_btn = Gtk.Button(label="✕")
close_btn.set_tooltip_text("Deactivate location")
close_btn.get_style_context().add_class("circular")
close_btn.connect("clicked", self._on_deactivate_clicked)
controls_box.pack_start(close_btn, False, False, 0)
# Hosts section if available
if self.location.hosts:
hosts_label = Gtk.Label()
hosts_label.set_markup("Infrastructure")
hosts_label.set_halign(Gtk.Align.START)
hosts_label.set_margin_top(8)
location_vbox.pack_start(hosts_label, False, False, 0)
# Hosts box with indent
hosts_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=8)
hosts_box.set_margin_start(16)
location_vbox.pack_start(hosts_box, False, False, 0)
for host in self.location.hosts:
host_item = HostItem(host, self.callbacks['open_service'])
hosts_box.pack_start(host_item.widget, False, False, 0)
return location_vbox
def _on_connect_clicked(self, button):
self.callbacks['toggle_connection'](self.location)
def _on_deactivate_clicked(self, button):
self.callbacks['deactivate_location'](self.location, self.customer_name)
class InactiveLocationCard:
def __init__(self, location, customer_name, callbacks):
self.location = location
self.customer_name = customer_name
self.callbacks = callbacks
self.widget = self._create_widget()
def _create_widget(self):
# Clean horizontal layout
location_hbox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=12)
# Location info
info_vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=2)
location_hbox.pack_start(info_vbox, True, True, 0)
# Location name
location_label = Gtk.Label()
location_label.set_markup(f"📍 {self.location.name}")
location_label.set_halign(Gtk.Align.START)
info_vbox.pack_start(location_label, False, False, 0)
# VPN type and host count
vpn_icons = {
VPNType.OPENVPN: "🔒",
VPNType.WIREGUARD: "⚡",
VPNType.IPSEC: "🛡️"
}
vpn_icon = vpn_icons.get(self.location.vpn_type, "🔑")
host_count = len(self.location.hosts)
details_label = Gtk.Label()
details_label.set_markup(f"{vpn_icon} {self.location.vpn_type.value} VPN • {host_count} hosts")
details_label.set_halign(Gtk.Align.START)
info_vbox.pack_start(details_label, False, False, 0)
# Activate button
activate_btn = Gtk.Button(label="Set Active")
activate_btn.get_style_context().add_class("suggested-action")
activate_btn.connect("clicked", self._on_activate_clicked)
location_hbox.pack_end(activate_btn, False, False, 0)
return location_hbox
def _on_activate_clicked(self, button):
self.callbacks['set_location_active'](self.location, self.customer_name)