aboutsummaryrefslogtreecommitdiff
path: root/xfce4-panel-profiles
diff options
context:
space:
mode:
authorLibravatar Unit 193 <unit193@unit193.net>2023-08-14 21:10:10 -0400
committerLibravatar Unit 193 <unit193@unit193.net>2023-08-14 21:10:10 -0400
commit72072f740a2f0ff0b3b67c98cf10efb3d29407ac (patch)
tree20dba00135c7b93fc33b0e293bd6587d8b921b29 /xfce4-panel-profiles
parent6f8741acd10ce1a1c85884ecdc0fd32f7f3ba330 (diff)
downloadxfce4-panel-profiles-upstream/latest.tar.gz
xfce4-panel-profiles-upstream/latest.zip
New upstream version 1.0.14.upstream/1.0.14upstream/latest
Diffstat (limited to 'xfce4-panel-profiles')
-rw-r--r--xfce4-panel-profiles/panelconfig.py134
-rw-r--r--xfce4-panel-profiles/xfce4-panel-profiles.glade5
-rw-r--r--xfce4-panel-profiles/xfce4-panel-profiles.py86
3 files changed, 157 insertions, 68 deletions
diff --git a/xfce4-panel-profiles/panelconfig.py b/xfce4-panel-profiles/panelconfig.py
index 8f082b7..43f6313 100644
--- a/xfce4-panel-profiles/panelconfig.py
+++ b/xfce4-panel-profiles/panelconfig.py
@@ -16,11 +16,11 @@ import tarfile
import io
import time
import os
+import psutil
# yes, python 3.2 has exist_ok, but it will still fail if the mode is different
-whiskermenu_file = 'whiskermenu-1.rc'
-whiskermenu_path = os.path.join(GLib.get_home_dir(), '.config/xfce4/panel/', whiskermenu_file)
+config_dir = os.path.join(GLib.get_user_config_dir(), 'xfce4/panel/')
def mkdir_p(path):
try:
@@ -42,8 +42,9 @@ class PanelConfig(object):
def __init__(self):
self.desktops = []
self.properties = {}
- self.whiskermenu_data = ""
+ self.rc_files = []
self.source = None
+ self.errors = []
@classmethod
def from_xfconf(cls, xfconf):
@@ -67,10 +68,8 @@ class PanelConfig(object):
pc.remove_orphans()
pc.find_desktops()
-
- if pc.check_whiskermenu():
- pc.whiskermenu_data = pc.get_whiskermenu_file().read()
-
+ pc.find_rc_files()
+
return pc
@classmethod
@@ -89,12 +88,13 @@ class PanelConfig(object):
pc.remove_orphans()
pc.find_desktops()
+ pc.find_rc_files()
- if pc.check_whiskermenu():
- pc.whiskermenu_data = pc.get_whiskermenu_file().read()
-
return pc
+ def source_not_file(self):
+ return getattr(self, 'source', None) is None
+
def remove_orphans(self):
plugin_ids = set()
rem_keys = []
@@ -128,28 +128,17 @@ class PanelConfig(object):
# Check if binary exists
keyfile = GLib.KeyFile.new()
- decoded = bytes.decode()
- if keyfile.load_from_data(decoded, len(decoded),
- GLib.KeyFileFlags.NONE):
- try:
+ try:
+ if keyfile.load_from_data(bytes.decode(), len(bytes), GLib.KeyFileFlags.NONE):
exec_str = keyfile.get_string("Desktop Entry", "Exec")
if self.check_exec(exec_str):
return True
- except GLib.Error: # pylint: disable=E0712
- pass # https://bugzilla.xfce.org/show_bug.cgi?id=14597
+ except GLib.Error: # pylint: disable=E0712
+ self.errors.append('Error parsing desktop file ' + path)
+ pass # https://bugzilla.xfce.org/show_bug.cgi?id=14597
return False
- def check_whiskermenu(self):
- try:
- f = self.get_whiskermenu_file()
- f.close()
-
- except (KeyError, FileNotFoundError):
- return False
-
- return True
-
def find_desktops(self):
rem_keys = []
@@ -160,8 +149,11 @@ class PanelConfig(object):
number = path[2].split('-')[1]
if pv.get_type_string() == 's' and \
pv.get_string() == 'launcher':
- for d in self.properties['/plugins/plugin-' + number +
- '/items'].unpack():
+ prop_path = '/plugins/plugin-' + number + '/items'
+ if prop_path not in self.properties:
+ rem_keys.append('/plugins/plugin-' + number)
+ continue
+ for d in self.properties[prop_path].unpack():
desktop_path = 'launcher-' + number + '/' + d
if self.check_desktop(desktop_path):
self.desktops.append(desktop_path)
@@ -170,6 +162,41 @@ class PanelConfig(object):
self.remove_keys(rem_keys)
+ def find_rc_files(self):
+ if self.source_not_file():
+ plugin_ids = []
+ filenames = []
+
+ for pp in self.properties:
+ path = pp.split('/')
+ if len(path) == 4 and path[0] == '' and path[1] == 'panels' and path[3] == 'plugin-ids':
+ plugin_ids.extend(self.properties[pp])
+
+ if len(plugin_ids) == 0:
+ return
+
+ for plugin_id in plugin_ids:
+ plugin_id = str(plugin_id)
+ prop_path = '/plugins/plugin-' + plugin_id
+ try:
+ prop = self.properties[prop_path].get_string()
+ except:
+ continue
+
+ if prop == 'launcher':
+ continue
+
+ filename = prop + '-' + plugin_id + '.rc'
+ path = os.path.join(config_dir, filename)
+ if os.path.exists(path):
+ filenames.append(filename)
+ self.rc_files = filenames
+ else:
+ filenames = self.source.getnames()
+ for filename in filenames:
+ if filename.find('.rc') > -1:
+ self.rc_files.append(filename)
+
def remove_keys(self, rem_keys):
keys = list(self.properties.keys())
for param in keys:
@@ -181,19 +208,18 @@ class PanelConfig(object):
pass # https://bugzilla.xfce.org/show_bug.cgi?id=14934
def get_desktop_source_file(self, desktop):
- if getattr(self, 'source', None) is None:
- path = os.path.join(
- GLib.get_home_dir(), '.config/xfce4/panel/', desktop)
+ if self.source_not_file():
+ path = os.path.join(config_dir, desktop)
return open(path, 'rb')
else:
return self.source.extractfile(desktop)
- def get_whiskermenu_file(self):
- if getattr(self, 'source', None) is None:
- return open(whiskermenu_path, 'rb')
-
+ def get_rc_source_file(self, rc):
+ if self.source_not_file():
+ path = os.path.join(config_dir, rc)
+ return open(path, 'rb')
else:
- return self.source.extractfile(whiskermenu_file)
+ return self.source.extractfile(rc)
def to_file(self, filename):
if filename.endswith('.gz'):
@@ -211,10 +237,10 @@ class PanelConfig(object):
for d in self.desktops:
bytes = self.get_desktop_source_file(d).read()
add_to_tar(t, bytes, d)
-
- if self.check_whiskermenu():
- bytes = self.get_whiskermenu_file().read()
- add_to_tar(t, bytes, whiskermenu_file)
+
+ for rc in self.rc_files:
+ bytes = self.get_rc_source_file(rc).read()
+ add_to_tar(t, bytes, rc)
t.close()
@@ -257,21 +283,33 @@ class PanelConfig(object):
xfconf.call_sync('SetProperty', GLib.Variant(
'(ssv)', ('xfce4-panel', pp, pv)), 0, -1, None)
- panel_path = os.path.join(
- GLib.get_home_dir(), '.config/xfce4/panel/')
for d in self.desktops:
bytes = self.get_desktop_source_file(d).read()
- mkdir_p(panel_path + os.path.dirname(d))
- f = open(panel_path + d, 'wb')
+ mkdir_p(config_dir + os.path.dirname(d))
+ f = open(config_dir + d, 'wb')
+ f.write(bytes)
+ f.close()
+
+ for rc in self.rc_files:
+ bytes = self.get_rc_source_file(rc).read()
+ f = open(os.path.join(config_dir, rc), 'wb')
f.write(bytes)
f.close()
+ # Kill the plugin so that it reloads the config we just wrote and does
+ # not overwrite it with its current cache when the panel restarts below.
+ # Some plugins don't save their config when restarting the panel
+ # (e.g. whiskermenu) but others do (e.g. netload)
+ plugin_id = rc.replace('.', '-').split('-')[1]
+ proc_name_prefix = 'panel-' + plugin_id + '-'
+ for proc in psutil.process_iter():
+ if proc.name().startswith(proc_name_prefix):
+ proc.kill()
+
try:
dbus_proxy.call_sync('Terminate', GLib.Variant('(b)', ('xfce4-panel',)), 0, -1, None)
except GLib.GError: # pylint: disable=E0712
pass
- if self.check_whiskermenu():
- f = open(whiskermenu_path, 'wb')
- f.write(self.whiskermenu_data)
- f.close()
+ def has_errors(self):
+ return len(self.errors) > 0
diff --git a/xfce4-panel-profiles/xfce4-panel-profiles.glade b/xfce4-panel-profiles/xfce4-panel-profiles.glade
index fc8f87d..362d9fe 100644
--- a/xfce4-panel-profiles/xfce4-panel-profiles.glade
+++ b/xfce4-panel-profiles/xfce4-panel-profiles.glade
@@ -192,10 +192,11 @@
<property name="margin_top">12</property>
<child>
<object class="GtkButton" id="help">
- <property name="label">Help</property>
+ <property name="label" translatable="yes">_Help</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
+ <property name="use_underline">True</property>
<signal name="clicked" handler="on_help_clicked" swapped="no"/>
</object>
<packing>
@@ -206,7 +207,7 @@
</child>
<child>
<object class="GtkButton" id="close">
- <property name="label">_Close</property>
+ <property name="label" translatable="yes">_Close</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
diff --git a/xfce4-panel-profiles/xfce4-panel-profiles.py b/xfce4-panel-profiles/xfce4-panel-profiles.py
index b24030c..1a897de 100644
--- a/xfce4-panel-profiles/xfce4-panel-profiles.py
+++ b/xfce4-panel-profiles/xfce4-panel-profiles.py
@@ -18,11 +18,7 @@
import tarfile
-import gettext
-gettext.textdomain('xfce4-panel-profiles')
-
-from gettext import gettext as _
-from gettext import ngettext
+from locale import gettext as _
import shlex
import os
@@ -37,9 +33,11 @@ gi.require_version('Gtk', '3.0')
try:
gi.require_version('Libxfce4ui', '2.0')
from gi.repository import Libxfce4ui as libxfce4ui
+ from gi.repository import Libxfce4util as libxfce4util
except ValueError:
gi.require_version('libxfce4ui', '2.0')
from gi.repository import libxfce4ui
+ from gi.repository import libxfce4util
from gi.repository import Gtk, GLib, Gio
@@ -49,8 +47,6 @@ import info
warnings.filterwarnings("ignore")
-homedir = GLib.get_home_dir()
-
class XfcePanelProfiles:
'''XfcePanelProfiles application class.'''
@@ -161,8 +157,8 @@ class XfcePanelProfiles:
for directory in self.get_data_dirs():
for filename in os.listdir(directory):
name, ext = os.path.splitext(filename)
- name = os.path.splitext(name)[0]
- if ext in [".gz", ".bz2"]:
+ name, tar = os.path.splitext(name)
+ if ext in [".gz", ".bz2"] and tar == ".tar":
path = os.path.join(directory, filename)
t = int(os.path.getmtime(path))
results.append((path, name, int(t)))
@@ -193,26 +189,42 @@ class XfcePanelProfiles:
filename = values[0]
return filename
- def copy_configuration(self, row, new_name, append=True):
+ def copy_configuration(self, row, name, append=True):
values = row[2]
filename = values[0]
- old_name = values[1]
created = values[2]
- new_filename = new_name + ".tar.bz2"
+ new_filename = name + ".tar.bz2"
new_filename = os.path.join(self.save_location, new_filename)
self._copy(filename, new_filename)
if append:
- name = _("%s (Copy of %s)") % (new_name, old_name)
self.tree_model.append([new_filename, name, created])
def save_configuration(self, name, append=True):
filename = name + ".tar.bz2"
filename = os.path.join(self.save_location, filename)
- PanelConfig.from_xfconf(self.xfconf).to_file(filename)
+
+ pc = PanelConfig.from_xfconf(self.xfconf)
+ if pc.has_errors():
+ dialog = PanelErrorDialog(self.window, pc.errors)
+ accept = dialog.run()
+ dialog.destroy()
+ if accept != Gtk.ResponseType.ACCEPT:
+ return
+ pc.to_file(filename)
created = int(datetime.datetime.now().strftime('%s'))
if append:
self.tree_model.append([filename, name, created])
+ def make_name_unique(self, name):
+ iter = self.tree_model.get_iter_first()
+ while iter != None:
+ if self.tree_model.get_value(iter, 1) == name:
+ date = datetime.datetime.now().strftime("%x_%X")
+ date = date.replace(":", "-").replace("/", "-")
+ return name + '_' + date
+ iter = self.tree_model.iter_next(iter)
+ return name
+
def on_save_clicked(self, widget):
filename = self.get_selected_filename()
dialog = PanelSaveDialog(self.window)
@@ -220,9 +232,13 @@ class XfcePanelProfiles:
name = dialog.get_save_name()
if len(name) > 0:
if filename == "": # Current configuration.
+ name = self.make_name_unique(name)
self.save_configuration(name)
else:
- self.copy_configuration(self.get_selected(), name)
+ row = self.get_selected()
+ old_name = row[2][1]
+ name = self.make_name_unique(_("%s (Copy of %s)") % (name, old_name))
+ self.copy_configuration(row, name)
dialog.destroy()
def on_export_clicked(self, widget):
@@ -246,7 +262,7 @@ class XfcePanelProfiles:
filename = dialog.get_filename()
savedlg = PanelSaveDialog(self.window)
if savedlg.run() == Gtk.ResponseType.ACCEPT:
- name = savedlg.get_save_name()
+ name = self.make_name_unique(savedlg.get_save_name())
dst = os.path.join(self.save_location, name + ".tar.bz2")
try:
self._copy(filename, dst)
@@ -307,8 +323,7 @@ class XfcePanelProfiles:
apply.set_sensitive(False if filename == '' else True)
def on_window_destroy(self, *args):
- '''Exit the application when the window is closed.'''
- Gtk.main_quit()
+ self.on_close_clicked(args)
def on_close_clicked(self, *args):
'''
@@ -398,11 +413,46 @@ class PanelConfirmDialog(Gtk.MessageDialog):
box.pack_start(self.backup, True, True, 0)
box.show_all()
+class PanelErrorDialog(Gtk.MessageDialog):
+ '''Ask the user if he wants to apply a configuration, because the current
+ configuration will be lost.'''
+
+ def __init__(self, parent=None, messages=[]):
+ message = _("Errors occured while parsing the current configuration.")
+
+ Gtk.MessageDialog.__init__(
+ self, transient_for=parent, modal=True,
+ message_type=Gtk.MessageType.QUESTION,
+ text=message)
+
+ self.add_buttons(
+ _("Cancel"), Gtk.ResponseType.CANCEL,
+ _("Save"), Gtk.ResponseType.ACCEPT
+ )
+
+ self.set_default_icon_name("dialog-information")
+ self.set_default_response(Gtk.ResponseType.ACCEPT)
+
+ box = self.get_message_area()
+ for line in messages:
+ label = Gtk.Label.new(line)
+ box.pack_start(label, True, True, 0)
+
+ label = Gtk.Label.new(_("Do you want to save despite the errors? "
+ "Some configuration information could be missing."))
+ box.pack_start(label, True, True, 0)
+
+ box.show_all()
+
if __name__ == "__main__":
from_panel = False
import sys
+ libxfce4util.textdomain('xfce4-panel-profiles',
+ os.path.join(os.path.dirname(os.path.realpath(__file__)), '../../locale'),
+ 'UTF-8')
+
session_bus = Gio.BusType.SESSION
cancellable = None
connection = Gio.bus_get_sync(session_bus, cancellable)