attempt to fix gtk import
This commit is contained in:
parent
90abed89c1
commit
2fc888c924
@ -308,12 +308,12 @@ class ClientConfig:
|
|||||||
port.remove(child)
|
port.remove(child)
|
||||||
|
|
||||||
# Alignment
|
# Alignment
|
||||||
align = gtk.Alignment(0, 0, 1, 1)
|
align = Gtk.Alignment(0, 0, 1, 1)
|
||||||
align.set_padding(4, 4, 4, 4)
|
align.set_padding(4, 4, 4, 4)
|
||||||
port.add(align)
|
port.add(align)
|
||||||
|
|
||||||
# Vertical box
|
# Vertical box
|
||||||
vbox = gtk.VBox()
|
vbox = Gtk.VBox()
|
||||||
align.add(vbox)
|
align.add(vbox)
|
||||||
|
|
||||||
for category in self.info:
|
for category in self.info:
|
||||||
@ -321,18 +321,18 @@ class ClientConfig:
|
|||||||
category = category[1:]
|
category = category[1:]
|
||||||
|
|
||||||
# Frame
|
# Frame
|
||||||
frame = gtk.Frame('<b>%s</b>' % name)
|
frame = Gtk.Frame('<b>%s</b>' % name)
|
||||||
frame.set_shadow_type(gtk.SHADOW_ETCHED_IN)
|
frame.set_shadow_type(Gtk.SHADOW_ETCHED_IN)
|
||||||
frame.get_label_widget().set_use_markup(True)
|
frame.get_label_widget().set_use_markup(True)
|
||||||
vbox.pack_start(frame, False)
|
vbox.pack_start(frame, False)
|
||||||
|
|
||||||
# Alignment
|
# Alignment
|
||||||
align = gtk.Alignment(0, 0, 1, 1)
|
align = Gtk.Alignment(0, 0, 1, 1)
|
||||||
align.set_padding(0, 0, 12, 0)
|
align.set_padding(0, 0, 12, 0)
|
||||||
frame.add(align)
|
frame.add(align)
|
||||||
|
|
||||||
# Table
|
# Table
|
||||||
table = gtk.Table(len(category), 2)
|
table = Gtk.Table(len(category), 2)
|
||||||
table.set_col_spacing(0, 5)
|
table.set_col_spacing(0, 5)
|
||||||
align.add(table)
|
align.add(table)
|
||||||
|
|
||||||
@ -342,23 +342,23 @@ class ClientConfig:
|
|||||||
continue
|
continue
|
||||||
|
|
||||||
# Name
|
# Name
|
||||||
label = gtk.Label('<b>%s</b>' % name)
|
label = Gtk.Label('<b>%s</b>' % name)
|
||||||
label.set_use_markup(True)
|
label.set_use_markup(True)
|
||||||
label.set_alignment(1, 0.5)
|
label.set_alignment(1, 0.5)
|
||||||
table.attach(label, 0, 1, row, row + 1, gtk.FILL, gtk.FILL)
|
table.attach(label, 0, 1, row, row + 1, Gtk.FILL, Gtk.FILL)
|
||||||
|
|
||||||
# Value
|
# Value
|
||||||
if value.startswith('http://'):
|
if value.startswith('http://'):
|
||||||
label = gtk.LinkButton(value, value)
|
label = Gtk.LinkButton(value, value)
|
||||||
label.set_relief(gtk.RELIEF_NONE)
|
label.set_relief(Gtk.RELIEF_NONE)
|
||||||
label.set_property('can-focus', False)
|
label.set_property('can-focus', False)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
label = gtk.Label(value)
|
label = Gtk.Label(value)
|
||||||
|
|
||||||
label.set_alignment(0, 0.5)
|
label.set_alignment(0, 0.5)
|
||||||
label.modify_font(app.mono_font)
|
label.modify_font(app.mono_font)
|
||||||
table.attach(label, 1, 2, row, row + 1, yoptions=gtk.FILL)
|
table.attach(label, 1, 2, row, row + 1, yoptions=Gtk.FILL)
|
||||||
|
|
||||||
row += 1
|
row += 1
|
||||||
|
|
||||||
|
@ -56,7 +56,7 @@ if sys.platform == 'darwin':
|
|||||||
|
|
||||||
def set_tree_view_font(widget, font):
|
def set_tree_view_font(widget, font):
|
||||||
for widget in iterate_container(widget):
|
for widget in iterate_container(widget):
|
||||||
if isinstance(widget, gtk.TreeView):
|
if isinstance(widget, Gtk.TreeView):
|
||||||
widget.modify_font(font)
|
widget.modify_font(font)
|
||||||
|
|
||||||
|
|
||||||
@ -193,10 +193,10 @@ class FAHControl(SingleAppServer):
|
|||||||
osx_add_GtkApplicationDelegate_methods()
|
osx_add_GtkApplicationDelegate_methods()
|
||||||
|
|
||||||
# URI hook
|
# URI hook
|
||||||
gtk.link_button_set_uri_hook(self.on_uri_hook, None)
|
Gtk.link_button_set_uri_hook(self.on_uri_hook, None)
|
||||||
|
|
||||||
# Style
|
# Style
|
||||||
settings = gtk.settings_get_default()
|
settings = Gtk.settings_get_default()
|
||||||
self.system_theme = settings.get_property('gtk-theme-name')
|
self.system_theme = settings.get_property('gtk-theme-name')
|
||||||
if sys.platform == 'darwin':
|
if sys.platform == 'darwin':
|
||||||
# Load standard key bindings for Mac and disable mnemonics
|
# Load standard key bindings for Mac and disable mnemonics
|
||||||
@ -206,12 +206,12 @@ class FAHControl(SingleAppServer):
|
|||||||
gtk.rc_parse(rcfile)
|
gtk.rc_parse(rcfile)
|
||||||
rcfile = os.path.join(os.path.expanduser("~"), '.FAHClient/gtkrc')
|
rcfile = os.path.join(os.path.expanduser("~"), '.FAHClient/gtkrc')
|
||||||
if os.path.exists(rcfile):
|
if os.path.exists(rcfile):
|
||||||
gtk.rc_parse(rcfile)
|
Gtk.rc_parse(rcfile)
|
||||||
self.mono_font = pango.FontDescription('Monospace')
|
self.mono_font = pango.FontDescription('Monospace')
|
||||||
small_font = pango.FontDescription('Sans 8')
|
small_font = pango.FontDescription('Sans 8')
|
||||||
|
|
||||||
# Default icon
|
# Default icon
|
||||||
gtk.window_set_default_icon(get_icon('small'))
|
Gtk.window_set_default_icon(get_icon('small'))
|
||||||
|
|
||||||
# Filter glade
|
# Filter glade
|
||||||
if len(glade) < 1024:
|
if len(glade) < 1024:
|
||||||
@ -226,7 +226,7 @@ class FAHControl(SingleAppServer):
|
|||||||
glade)[0]
|
glade)[0]
|
||||||
|
|
||||||
# Build GUI
|
# Build GUI
|
||||||
self.builder = builder = gtk.Builder()
|
self.builder = builder = Gtk.Builder()
|
||||||
try:
|
try:
|
||||||
builder.add_from_string(glade)
|
builder.add_from_string(glade)
|
||||||
except:
|
except:
|
||||||
@ -340,9 +340,9 @@ class FAHControl(SingleAppServer):
|
|||||||
self.connect_option_view('slot_')
|
self.connect_option_view('slot_')
|
||||||
self.core_option_tree = builder.get_object('core_option_tree_view')
|
self.core_option_tree = builder.get_object('core_option_tree_view')
|
||||||
self.core_option_list = builder.get_object('core_option_list')
|
self.core_option_list = builder.get_object('core_option_list')
|
||||||
self.option_tree.get_selection().set_mode(gtk.SELECTION_MULTIPLE)
|
self.option_tree.get_selection().set_mode(Gtk.SELECTION_MULTIPLE)
|
||||||
self.slot_option_tree.get_selection().set_mode(gtk.SELECTION_MULTIPLE)
|
self.slot_option_tree.get_selection().set_mode(Gtk.SELECTION_MULTIPLE)
|
||||||
self.core_option_tree.get_selection().set_mode(gtk.SELECTION_MULTIPLE)
|
self.core_option_tree.get_selection().set_mode(Gtk.SELECTION_MULTIPLE)
|
||||||
|
|
||||||
# Option dialog
|
# Option dialog
|
||||||
self.option_name_entry = builder.get_object('option_name_entry')
|
self.option_name_entry = builder.get_object('option_name_entry')
|
||||||
@ -357,7 +357,7 @@ class FAHControl(SingleAppServer):
|
|||||||
for i in range(len(self.folding_power_levels)):
|
for i in range(len(self.folding_power_levels)):
|
||||||
level = self.folding_power_levels[i]
|
level = self.folding_power_levels[i]
|
||||||
markup = '<span font_size="small" weight="bold">%s</span>' % level
|
markup = '<span font_size="small" weight="bold">%s</span>' % level
|
||||||
self.folding_power.add_mark(i, gtk.POS_BOTTOM, markup)
|
self.folding_power.add_mark(i, Gtk.POS_BOTTOM, markup)
|
||||||
|
|
||||||
# User info
|
# User info
|
||||||
self.donor_info = builder.get_object('donor_info')
|
self.donor_info = builder.get_object('donor_info')
|
||||||
@ -381,7 +381,7 @@ class FAHControl(SingleAppServer):
|
|||||||
|
|
||||||
# Slot lists
|
# Slot lists
|
||||||
self.slot_status_tree = builder.get_object('slot_status_tree_view')
|
self.slot_status_tree = builder.get_object('slot_status_tree_view')
|
||||||
self.slot_status_tree.get_selection().set_mode(gtk.SELECTION_SINGLE)
|
self.slot_status_tree.get_selection().set_mode(Gtk.SELECTION_SINGLE)
|
||||||
self.slot_status_list = builder.get_object('slot_status_list')
|
self.slot_status_list = builder.get_object('slot_status_list')
|
||||||
self.slot_tree = builder.get_object('slot_tree_view')
|
self.slot_tree = builder.get_object('slot_tree_view')
|
||||||
self.slot_list = builder.get_object('slot_list')
|
self.slot_list = builder.get_object('slot_list')
|
||||||
@ -553,32 +553,32 @@ class FAHControl(SingleAppServer):
|
|||||||
try:
|
try:
|
||||||
# add cmd-w and cmd-m to window
|
# add cmd-w and cmd-m to window
|
||||||
# cmd-w would need to be same as cancel for dialogs
|
# cmd-w would need to be same as cancel for dialogs
|
||||||
ag = gtk.AccelGroup()
|
ag = Gtk.AccelGroup()
|
||||||
self.window_accel_group = ag
|
self.window_accel_group = ag
|
||||||
key, mod = gtk.accelerator_parse("<meta>w")
|
key, mod = Gtk.accelerator_parse("<meta>w")
|
||||||
ag.connect_group(key, mod, gtk.ACCEL_VISIBLE,
|
ag.connect_group(key, mod, Gtk.ACCEL_VISIBLE,
|
||||||
osx_accel_window_close)
|
osx_accel_window_close)
|
||||||
key, mod = gtk.accelerator_parse("<meta>m")
|
key, mod = Gtk.accelerator_parse("<meta>m")
|
||||||
ag.connect_group(key, mod, gtk.ACCEL_VISIBLE,
|
ag.connect_group(key, mod, Gtk.ACCEL_VISIBLE,
|
||||||
osx_accel_window_minimize)
|
osx_accel_window_minimize)
|
||||||
self.window.add_accel_group(ag)
|
self.window.add_accel_group(ag)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(e)
|
print(e)
|
||||||
|
|
||||||
gtk.main()
|
Gtk.main()
|
||||||
|
|
||||||
# Util
|
# Util
|
||||||
def osx_add_to_menu(self, widget):
|
def osx_add_to_menu(self, widget):
|
||||||
if isinstance(widget, gtk.SeparatorMenuItem):
|
if isinstance(widget, Gtk.SeparatorMenuItem):
|
||||||
self.osx_group = self.osx_app.add_app_menu_group()
|
self.osx_group = self.osx_app.add_app_menu_group()
|
||||||
|
|
||||||
elif isinstance(widget, gtk.MenuItem):
|
elif isinstance(widget, Gtk.MenuItem):
|
||||||
name = widget.child.get_text()
|
name = widget.child.get_text()
|
||||||
|
|
||||||
def activate_item(widget, target):
|
def activate_item(widget, target):
|
||||||
target.emit('activate')
|
target.emit('activate')
|
||||||
|
|
||||||
item = gtk.MenuItem(name)
|
item = Gtk.MenuItem(name)
|
||||||
item.show()
|
item.show()
|
||||||
item.connect('activate', activate_item, widget)
|
item.connect('activate', activate_item, widget)
|
||||||
self.osx_app.add_app_menu_item(self.osx_group, item)
|
self.osx_app.add_app_menu_item(self.osx_group, item)
|
||||||
@ -586,26 +586,26 @@ class FAHControl(SingleAppServer):
|
|||||||
def osx_create_app_menu(self, widgets):
|
def osx_create_app_menu(self, widgets):
|
||||||
i = 0
|
i = 0
|
||||||
for widget in widgets:
|
for widget in widgets:
|
||||||
if not isinstance(widget, gtk.SeparatorMenuItem):
|
if not isinstance(widget, Gtk.SeparatorMenuItem):
|
||||||
def activate_item(widget, target):
|
def activate_item(widget, target):
|
||||||
target.emit('activate')
|
target.emit('activate')
|
||||||
label = widget.get_label()
|
label = widget.get_label()
|
||||||
item = gtk.MenuItem(label)
|
item = Gtk.MenuItem(label)
|
||||||
item.show()
|
item.show()
|
||||||
item.connect('activate', activate_item, widget)
|
item.connect('activate', activate_item, widget)
|
||||||
self.osx_app.insert_app_menu_item(widget, i)
|
self.osx_app.insert_app_menu_item(widget, i)
|
||||||
i += 1
|
i += 1
|
||||||
|
|
||||||
def osx_create_dock_menu(self, widgets):
|
def osx_create_dock_menu(self, widgets):
|
||||||
menu = gtk.Menu()
|
menu = Gtk.Menu()
|
||||||
for widget in widgets:
|
for widget in widgets:
|
||||||
if isinstance(widget, gtk.SeparatorMenuItem):
|
if isinstance(widget, Gtk.SeparatorMenuItem):
|
||||||
item = gtk.SeparatorMenuItem()
|
item = Gtk.SeparatorMenuItem()
|
||||||
else:
|
else:
|
||||||
def activate_item(widget, target):
|
def activate_item(widget, target):
|
||||||
target.emit('activate')
|
target.emit('activate')
|
||||||
label = widget.get_label()
|
label = widget.get_label()
|
||||||
item = gtk.MenuItem(label)
|
item = Gtk.MenuItem(label)
|
||||||
item.connect('activate', activate_item, widget)
|
item.connect('activate', activate_item, widget)
|
||||||
menu.append(item)
|
menu.append(item)
|
||||||
menu.show_all()
|
menu.show_all()
|
||||||
@ -721,7 +721,7 @@ class FAHControl(SingleAppServer):
|
|||||||
return
|
return
|
||||||
self.quitting = True
|
self.quitting = True
|
||||||
|
|
||||||
gtk.main_quit()
|
Gtk.main_quit()
|
||||||
|
|
||||||
self.viewer_close()
|
self.viewer_close()
|
||||||
|
|
||||||
@ -762,17 +762,17 @@ class FAHControl(SingleAppServer):
|
|||||||
if theme == name:
|
if theme == name:
|
||||||
print(('Loading theme %r' % theme))
|
print(('Loading theme %r' % theme))
|
||||||
|
|
||||||
settings = gtk.settings_get_default()
|
settings = Gtk.settings_get_default()
|
||||||
|
|
||||||
if rc is None:
|
if rc is None:
|
||||||
settings.set_property('gtk-theme-name', self.system_theme)
|
settings.set_property('gtk-theme-name', self.system_theme)
|
||||||
gtk.rc_set_default_files([])
|
Gtk.rc_set_default_files([])
|
||||||
else:
|
else:
|
||||||
settings.set_property('gtk-theme-name', theme)
|
settings.set_property('gtk-theme-name', theme)
|
||||||
gtk.rc_set_default_files([rc])
|
Gtk.rc_set_default_files([rc])
|
||||||
|
|
||||||
gtk.rc_reparse_all_for_settings(settings, True)
|
Gtk.rc_reparse_all_for_settings(settings, True)
|
||||||
gtk.rc_reset_styles(settings)
|
Gtk.rc_reset_styles(settings)
|
||||||
|
|
||||||
break
|
break
|
||||||
|
|
||||||
@ -1241,7 +1241,7 @@ class FAHControl(SingleAppServer):
|
|||||||
def get_visible_dialogs(self):
|
def get_visible_dialogs(self):
|
||||||
dialogs = []
|
dialogs = []
|
||||||
for dialog in self.dialogs:
|
for dialog in self.dialogs:
|
||||||
if dialog.flags() & gtk.MAPPED:
|
if dialog.flags() & Gtk.MAPPED:
|
||||||
dialogs.append(dialog)
|
dialogs.append(dialog)
|
||||||
|
|
||||||
return dialogs
|
return dialogs
|
||||||
@ -1273,7 +1273,7 @@ class FAHControl(SingleAppServer):
|
|||||||
dialog.destroy()
|
dialog.destroy()
|
||||||
self.error_dialog = None
|
self.error_dialog = None
|
||||||
|
|
||||||
def error(self, message, buttons=gtk.BUTTONS_OK, on_response=None,
|
def error(self, message, buttons=Gtk.BUTTONS_OK, on_response=None,
|
||||||
on_response_data=None):
|
on_response_data=None):
|
||||||
message = str(message)
|
message = str(message)
|
||||||
|
|
||||||
@ -1291,10 +1291,10 @@ class FAHControl(SingleAppServer):
|
|||||||
|
|
||||||
# create an error message dialog and display modally to the user
|
# create an error message dialog and display modally to the user
|
||||||
dialog = \
|
dialog = \
|
||||||
gtk.MessageDialog(None,
|
Gtk.MessageDialog(None,
|
||||||
gtk.DIALOG_MODAL |
|
Gtk.DIALOG_MODAL |
|
||||||
gtk.DIALOG_DESTROY_WITH_PARENT,
|
Gtk.DIALOG_DESTROY_WITH_PARENT,
|
||||||
gtk.MESSAGE_ERROR, buttons, message)
|
Gtk.MESSAGE_ERROR, buttons, message)
|
||||||
|
|
||||||
dialog.connect('close', self.close_error_dialog)
|
dialog.connect('close', self.close_error_dialog)
|
||||||
if on_response is not None:
|
if on_response is not None:
|
||||||
@ -1816,7 +1816,7 @@ class FAHControl(SingleAppServer):
|
|||||||
def on_copy_log_clicked(self, widget, data=None):
|
def on_copy_log_clicked(self, widget, data=None):
|
||||||
log = self.log
|
log = self.log
|
||||||
text = log.get_text(log.get_start_iter(), log.get_end_iter())
|
text = log.get_text(log.get_start_iter(), log.get_end_iter())
|
||||||
gtk.Clipboard().set_text(text)
|
Gtk.Clipboard().set_text(text)
|
||||||
|
|
||||||
def on_clear_log_clicked(self, widget, data=None):
|
def on_clear_log_clicked(self, widget, data=None):
|
||||||
if self.active_client:
|
if self.active_client:
|
||||||
|
@ -26,7 +26,7 @@ viewer_icons = {'tiny': None, 'small': None, 'medium': None, 'large': None}
|
|||||||
|
|
||||||
|
|
||||||
def load_rgba_pixbuf(data, dim):
|
def load_rgba_pixbuf(data, dim):
|
||||||
return gtk.gdk.pixbuf_new_from_data(data, gtk.gdk.COLORSPACE_RGB,
|
return Gtk.gdk.pixbuf_new_from_data(data, Gtk.gdk.COLORSPACE_RGB,
|
||||||
True, 8, dim, dim, dim * 4)
|
True, 8, dim, dim, dim * 4)
|
||||||
|
|
||||||
|
|
||||||
@ -47,7 +47,7 @@ def get_icon(name):
|
|||||||
|
|
||||||
|
|
||||||
def get_icon_image(name):
|
def get_icon_image(name):
|
||||||
image = gtk.Image()
|
image = Gtk.Image()
|
||||||
image.set_from_pixbuf(get_icon(name))
|
image.set_from_pixbuf(get_icon(name))
|
||||||
image.show()
|
image.show()
|
||||||
|
|
||||||
@ -71,7 +71,7 @@ def get_viewer_icon(name):
|
|||||||
|
|
||||||
|
|
||||||
def get_viewer_icon_image(name):
|
def get_viewer_icon_image(name):
|
||||||
image = gtk.Image()
|
image = Gtk.Image()
|
||||||
image.set_from_pixbuf(get_viewer_icon(name))
|
image.set_from_pixbuf(get_viewer_icon(name))
|
||||||
image.show()
|
image.show()
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@ class WidgetMap(dict):
|
|||||||
def add(self, widget):
|
def add(self, widget):
|
||||||
if widget is None:
|
if widget is None:
|
||||||
return
|
return
|
||||||
name = gtk.Buildable.get_name(widget)
|
name = Gtk.Buildable.get_name(widget)
|
||||||
|
|
||||||
if self.suffix is not None:
|
if self.suffix is not None:
|
||||||
name = name[0:-len(self.suffix)]
|
name = name[0:-len(self.suffix)]
|
||||||
@ -47,11 +47,11 @@ class WidgetMap(dict):
|
|||||||
self.list.append(widget)
|
self.list.append(widget)
|
||||||
|
|
||||||
def find(self, widget):
|
def find(self, widget):
|
||||||
name = gtk.Buildable.get_name(widget)
|
name = Gtk.Buildable.get_name(widget)
|
||||||
|
|
||||||
if (name and (self.suffix is None or name.endswith(self.suffix)) and
|
if (name and (self.suffix is None or name.endswith(self.suffix)) and
|
||||||
(self.prefix is None or name.startswith(self.prefix))):
|
(self.prefix is None or name.startswith(self.prefix))):
|
||||||
self.add(widget)
|
self.add(widget)
|
||||||
|
|
||||||
if isinstance(widget, gtk.Container):
|
if isinstance(widget, Gtk.Container):
|
||||||
widget.foreach(self.find)
|
widget.foreach(self.find)
|
||||||
|
@ -1,23 +1,23 @@
|
|||||||
################################################################################
|
###############################################################################
|
||||||
# #
|
# #
|
||||||
# Folding@Home Client Control (FAHControl) #
|
# Folding@Home Client Control (FAHControl) #
|
||||||
# Copyright (C) 2016-2020 foldingathome.org #
|
# Copyright (C) 2016-2020 foldingathome.org #
|
||||||
# Copyright (C) 2010-2016 Stanford University #
|
# Copyright (C) 2010-2016 Stanford University #
|
||||||
# #
|
# #
|
||||||
# This program is free software: you can redistribute it and/or modify #
|
# 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 #
|
# it under the terms of the GNU General Public License as published by #
|
||||||
# the Free Software Foundation, either version 3 of the License, or #
|
# the Free Software Foundation, either version 3 of the License, or #
|
||||||
# (at your option) any later version. #
|
# (at your option) any later version. #
|
||||||
# #
|
# #
|
||||||
# This program is distributed in the hope that it will be useful, #
|
# This program is distributed in the hope that it will be useful, #
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
||||||
# GNU General Public License for more details. #
|
# GNU General Public License for more details. #
|
||||||
# #
|
# #
|
||||||
# You should have received a copy of the GNU General Public License #
|
# You should have received a copy of the GNU General Public License #
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
||||||
# #
|
# #
|
||||||
################################################################################
|
###############################################################################
|
||||||
|
|
||||||
from UserDict import DictMixin
|
from UserDict import DictMixin
|
||||||
|
|
||||||
@ -115,7 +115,8 @@ class OrderedDict(dict, DictMixin):
|
|||||||
|
|
||||||
def __eq__(self, other):
|
def __eq__(self, other):
|
||||||
if isinstance(other, OrderedDict):
|
if isinstance(other, OrderedDict):
|
||||||
return len(self)==len(other) and list(self.items()) == list(other.items())
|
return len(self) == len(other) and \
|
||||||
|
list(self.items()) == list(other.items())
|
||||||
return dict.__eq__(self, other)
|
return dict.__eq__(self, other)
|
||||||
|
|
||||||
def __ne__(self, other):
|
def __ne__(self, other):
|
||||||
|
@ -1,23 +1,23 @@
|
|||||||
################################################################################
|
###############################################################################
|
||||||
# #
|
# #
|
||||||
# Folding@Home Client Control (FAHControl) #
|
# Folding@Home Client Control (FAHControl) #
|
||||||
# Copyright (C) 2016-2020 foldingathome.org #
|
# Copyright (C) 2016-2020 foldingathome.org #
|
||||||
# Copyright (C) 2010-2016 Stanford University #
|
# Copyright (C) 2010-2016 Stanford University #
|
||||||
# #
|
# #
|
||||||
# This program is free software: you can redistribute it and/or modify #
|
# 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 #
|
# it under the terms of the GNU General Public License as published by #
|
||||||
# the Free Software Foundation, either version 3 of the License, or #
|
# the Free Software Foundation, either version 3 of the License, or #
|
||||||
# (at your option) any later version. #
|
# (at your option) any later version. #
|
||||||
# #
|
# #
|
||||||
# This program is distributed in the hope that it will be useful, #
|
# This program is distributed in the hope that it will be useful, #
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
||||||
# GNU General Public License for more details. #
|
# GNU General Public License for more details. #
|
||||||
# #
|
# #
|
||||||
# You should have received a copy of the GNU General Public License #
|
# You should have received a copy of the GNU General Public License #
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
||||||
# #
|
# #
|
||||||
################################################################################
|
###############################################################################
|
||||||
|
|
||||||
import re
|
import re
|
||||||
import json
|
import json
|
||||||
@ -37,180 +37,184 @@ DEFAULT_ENCODING = "utf-8"
|
|||||||
|
|
||||||
|
|
||||||
def linecol(doc, pos):
|
def linecol(doc, pos):
|
||||||
lineno = doc.count('\n', 0, pos) + 1
|
lineno = doc.count('\n', 0, pos) + 1
|
||||||
if lineno == 1:
|
if lineno == 1:
|
||||||
colno = pos + 1
|
colno = pos + 1
|
||||||
else:
|
else:
|
||||||
colno = pos - doc.rindex('\n', 0, pos)
|
colno = pos - doc.rindex('\n', 0, pos)
|
||||||
return lineno, colno
|
return lineno, colno
|
||||||
|
|
||||||
|
|
||||||
def errmsg(msg, doc, pos, end=None):
|
def errmsg(msg, doc, pos, end=None):
|
||||||
# Note that this function is called from _json
|
# Note that this function is called from _json
|
||||||
lineno, colno = linecol(doc, pos)
|
lineno, colno = linecol(doc, pos)
|
||||||
if end is None:
|
if end is None:
|
||||||
fmt = '{0}: line {1} column {2} (char {3})'
|
fmt = '{0}: line {1} column {2} (char {3})'
|
||||||
return fmt.format(msg, lineno, colno, pos)
|
return fmt.format(msg, lineno, colno, pos)
|
||||||
|
|
||||||
endlineno, endcolno = linecol(doc, end)
|
endlineno, endcolno = linecol(doc, end)
|
||||||
fmt = '{0}: line {1} column {2} - line {3} column {4} (char {5} - {6})'
|
fmt = '{0}: line {1} column {2} - line {3} column {4} (char {5} - {6})'
|
||||||
return fmt.format(msg, lineno, colno, endlineno, endcolno, pos, end)
|
return fmt.format(msg, lineno, colno, endlineno, endcolno, pos, end)
|
||||||
|
|
||||||
|
|
||||||
def _decode_uXXXX(s, pos):
|
def _decode_uXXXX(s, pos):
|
||||||
esc = s[pos + 1:pos + 5]
|
esc = s[pos + 1:pos + 5]
|
||||||
|
|
||||||
if len(esc) == 4 and esc[1] not in 'xX':
|
if len(esc) == 4 and esc[1] not in 'xX':
|
||||||
try:
|
try:
|
||||||
return int(esc, 16)
|
return int(esc, 16)
|
||||||
except ValueError: pass
|
except ValueError:
|
||||||
|
pass
|
||||||
|
|
||||||
msg = "Invalid \\uXXXX escape"
|
msg = "Invalid \\uXXXX escape"
|
||||||
raise ValueError(errmsg(msg, s, pos))
|
raise ValueError(errmsg(msg, s, pos))
|
||||||
|
|
||||||
|
|
||||||
def pyon_scanstring(s, end, encoding = None, strict = True,
|
def pyon_scanstring(s, end, encoding=None, strict=True,
|
||||||
_b = BACKSLASH, _m = STRINGCHUNK.match):
|
_b=BACKSLASH, _m=STRINGCHUNK.match):
|
||||||
"""Scan the string s for a JSON string. End is the index of the
|
"""Scan the string s for a JSON string. End is the index of the
|
||||||
character in s after the quote that started the JSON string.
|
character in s after the quote that started the JSON string.
|
||||||
Unescapes all valid JSON string escape sequences and raises ValueError
|
Unescapes all valid JSON string escape sequences and raises ValueError
|
||||||
on attempt to decode an invalid string. If strict is False then literal
|
on attempt to decode an invalid string. If strict is False then literal
|
||||||
control characters are allowed in the string.
|
control characters are allowed in the string.
|
||||||
Returns a tuple of the decoded string and the index of the character in s
|
Returns a tuple of the decoded string and the index of the character in s
|
||||||
after the end quote."""
|
after the end quote."""
|
||||||
if encoding is None: encoding = DEFAULT_ENCODING
|
|
||||||
chunks = []
|
|
||||||
_append = chunks.append
|
|
||||||
begin = end - 1
|
|
||||||
|
|
||||||
while True:
|
if encoding is None:
|
||||||
chunk = _m(s, end)
|
encoding = DEFAULT_ENCODING
|
||||||
if chunk is None:
|
chunks = []
|
||||||
raise ValueError(
|
_append = chunks.append
|
||||||
errmsg("Unterminated string starting at", s, begin))
|
begin = end - 1
|
||||||
|
|
||||||
end = chunk.end()
|
while True:
|
||||||
content, terminator = chunk.groups()
|
chunk = _m(s, end)
|
||||||
|
if chunk is None:
|
||||||
|
raise ValueError(
|
||||||
|
errmsg("Unterminated string starting at", s, begin))
|
||||||
|
|
||||||
# Content is contains zero or more unescaped string characters
|
end = chunk.end()
|
||||||
if content:
|
content, terminator = chunk.groups()
|
||||||
if not isinstance(content, str):
|
|
||||||
content = str(content, encoding)
|
|
||||||
_append(content)
|
|
||||||
|
|
||||||
# Terminator is the end of string, a literal control character,
|
# Content is contains zero or more unescaped string characters
|
||||||
# or a backslash denoting that an escape sequence follows
|
if content:
|
||||||
if terminator == '"': break
|
if not isinstance(content, str):
|
||||||
elif terminator != '\\':
|
content = str(content, encoding)
|
||||||
if strict:
|
_append(content)
|
||||||
msg = "Invalid control character {0!r} at".format(terminator)
|
|
||||||
raise ValueError(errmsg(msg, s, end))
|
# Terminator is the end of string, a literal control character,
|
||||||
else:
|
# or a backslash denoting that an escape sequence follows
|
||||||
_append(terminator)
|
if terminator == '"':
|
||||||
continue
|
break
|
||||||
|
elif terminator != '\\':
|
||||||
|
if strict:
|
||||||
|
msg = "Invalid control character {0!r} at".format(terminator)
|
||||||
|
raise ValueError(errmsg(msg, s, end))
|
||||||
|
else:
|
||||||
|
_append(terminator)
|
||||||
|
continue
|
||||||
|
|
||||||
try:
|
try:
|
||||||
esc = s[end]
|
esc = s[end]
|
||||||
except IndexError:
|
except IndexError:
|
||||||
raise ValueError(errmsg("Unterminated string starting at", s, begin))
|
raise ValueError(errmsg("Unterminated string starting at", s, begin))
|
||||||
|
|
||||||
# If not a unicode escape sequence, must be in the lookup table
|
# If not a unicode escape sequence, must be in the lookup table
|
||||||
if esc != 'u' and esc != 'x':
|
if esc != 'u' and esc != 'x':
|
||||||
try:
|
try:
|
||||||
char = _b[esc]
|
char = _b[esc]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
msg = "Invalid \\escape: " + repr(esc)
|
msg = "Invalid \\escape: " + repr(esc)
|
||||||
raise ValueError(errmsg(msg, s, end))
|
raise ValueError(errmsg(msg, s, end))
|
||||||
end += 1
|
end += 1
|
||||||
|
|
||||||
elif esc == 'x':
|
elif esc == 'x':
|
||||||
# Hex escape sequence
|
# Hex escape sequence
|
||||||
code = s[end + 1: end + 3]
|
code = s[end + 1: end + 3]
|
||||||
try:
|
try:
|
||||||
char = chr(int(code, 16))
|
char = chr(int(code, 16))
|
||||||
except:
|
except:
|
||||||
raise ValueError(errmsg('Invalid \\escape: ' + repr(code), s, end))
|
raise ValueError(errmsg('Invalid \\escape: ' + repr(code), s, end))
|
||||||
|
|
||||||
end += 3
|
end += 3
|
||||||
|
|
||||||
else:
|
else:
|
||||||
# Unicode escape sequence
|
# Unicode escape sequence
|
||||||
uni = _decode_uXXXX(s, end)
|
uni = _decode_uXXXX(s, end)
|
||||||
end += 5
|
end += 5
|
||||||
# Check for surrogate pair on UCS-4 systems
|
# Check for surrogate pair on UCS-4 systems
|
||||||
if sys.maxunicode > 65535 and \
|
if sys.maxunicode > 65535 and \
|
||||||
0xd800 <= uni <= 0xdbff and s[end:end + 2] == '\\u':
|
0xd800 <= uni <= 0xdbff and s[end:end + 2] == '\\u':
|
||||||
uni2 = _decode_uXXXX(s, end + 1)
|
uni2 = _decode_uXXXX(s, end + 1)
|
||||||
if 0xdc00 <= uni2 <= 0xdfff:
|
if 0xdc00 <= uni2 <= 0xdfff:
|
||||||
uni = 0x10000 + (((uni - 0xd800) << 10) | (uni2 - 0xdc00))
|
uni = 0x10000 + (((uni - 0xd800) << 10) | (uni2 - 0xdc00))
|
||||||
end += 6
|
end += 6
|
||||||
char = chr(uni)
|
char = chr(uni)
|
||||||
|
|
||||||
# Append the unescaped character
|
# Append the unescaped character
|
||||||
_append(char)
|
_append(char)
|
||||||
|
|
||||||
return ''.join(chunks), end
|
return ''.join(chunks), end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def make_pyon_scanner(context):
|
def make_pyon_scanner(context):
|
||||||
parse_object = context.parse_object
|
parse_object = context.parse_object
|
||||||
parse_array = context.parse_array
|
parse_array = context.parse_array
|
||||||
parse_string = context.parse_string
|
parse_string = context.parse_string
|
||||||
match_number = NUMBER_RE.match
|
match_number = NUMBER_RE.match
|
||||||
strict = context.strict
|
strict = context.strict
|
||||||
parse_float = context.parse_float
|
parse_float = context.parse_float
|
||||||
parse_int = context.parse_int
|
parse_int = context.parse_int
|
||||||
parse_constant = context.parse_constant
|
parse_constant = context.parse_constant
|
||||||
object_hook = context.object_hook
|
object_hook = context.object_hook
|
||||||
object_pairs_hook = context.object_pairs_hook
|
object_pairs_hook = context.object_pairs_hook
|
||||||
|
|
||||||
|
def scan_once(string, idx):
|
||||||
|
try:
|
||||||
|
nextchar = string[idx]
|
||||||
|
except IndexError:
|
||||||
|
raise StopIteration(idx)
|
||||||
|
|
||||||
def scan_once(string, idx):
|
if nextchar == '"':
|
||||||
try:
|
return parse_string(string, idx + 1, 'utf-8', strict)
|
||||||
nextchar = string[idx]
|
|
||||||
except IndexError:
|
|
||||||
raise StopIteration(idx)
|
|
||||||
|
|
||||||
if nextchar == '"': return parse_string(string, idx + 1, 'utf-8', strict)
|
|
||||||
elif nextchar == '{':
|
elif nextchar == '{':
|
||||||
return parse_object((string, idx + 1), 'utf-8', strict, scan_once,
|
return parse_object((string, idx + 1), 'utf-8', strict, scan_once,
|
||||||
object_hook, object_pairs_hook)
|
object_hook, object_pairs_hook)
|
||||||
elif nextchar == '[':
|
elif nextchar == '[':
|
||||||
return parse_array((string, idx + 1), scan_once)
|
return parse_array((string, idx + 1), scan_once)
|
||||||
elif nextchar == 'N' and string[idx:idx + 4] == 'None':
|
elif nextchar == 'N' and string[idx:idx + 4] == 'None':
|
||||||
return None, idx + 4
|
return None, idx + 4
|
||||||
elif nextchar == 'T' and string[idx:idx + 4] == 'True':
|
elif nextchar == 'T' and string[idx:idx + 4] == 'True':
|
||||||
return True, idx + 4
|
return True, idx + 4
|
||||||
elif nextchar == 'F' and string[idx:idx + 5] == 'False':
|
elif nextchar == 'F' and string[idx:idx + 5] == 'False':
|
||||||
return False, idx + 5
|
return False, idx + 5
|
||||||
|
|
||||||
m = match_number(string, idx)
|
m = match_number(string, idx)
|
||||||
if m is not None:
|
if m is not None:
|
||||||
integer, frac, exp = m.groups()
|
integer, frac, exp = m.groups()
|
||||||
if frac or exp:
|
if frac or exp:
|
||||||
res = parse_float(integer + (frac or '') + (exp or ''))
|
res = parse_float(integer + (frac or '') + (exp or ''))
|
||||||
else: res = parse_int(integer)
|
else:
|
||||||
|
res = parse_int(integer)
|
||||||
|
|
||||||
return res, m.end()
|
return res, m.end()
|
||||||
|
|
||||||
elif nextchar == 'N' and string[idx:idx + 3] == 'NaN':
|
elif nextchar == 'N' and string[idx:idx + 3] == 'NaN':
|
||||||
return parse_constant('NaN'), idx + 3
|
return parse_constant('NaN'), idx + 3
|
||||||
|
|
||||||
elif nextchar == 'I' and string[idx:idx + 8] == 'Infinity':
|
elif nextchar == 'I' and string[idx:idx + 8] == 'Infinity':
|
||||||
return parse_constant('Infinity'), idx + 8
|
return parse_constant('Infinity'), idx + 8
|
||||||
|
|
||||||
elif nextchar == '-' and string[idx:idx + 9] == '-Infinity':
|
elif nextchar == '-' and string[idx:idx + 9] == '-Infinity':
|
||||||
return parse_constant('-Infinity'), idx + 9
|
return parse_constant('-Infinity'), idx + 9
|
||||||
|
|
||||||
else: raise StopIteration(idx)
|
else:
|
||||||
|
raise StopIteration(idx)
|
||||||
|
|
||||||
|
return scan_once
|
||||||
return scan_once
|
|
||||||
|
|
||||||
|
|
||||||
class PYONDecoder(json.JSONDecoder):
|
class PYONDecoder(json.JSONDecoder):
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
json.JSONDecoder.__init__(self, *args, **kwargs)
|
json.JSONDecoder.__init__(self, *args, **kwargs)
|
||||||
self.parse_string = pyon_scanstring
|
self.parse_string = pyon_scanstring
|
||||||
self.scan_once = make_pyon_scanner(self)
|
self.scan_once = make_pyon_scanner(self)
|
||||||
|
@ -1,23 +1,23 @@
|
|||||||
################################################################################
|
###############################################################################
|
||||||
# #
|
# #
|
||||||
# Folding@Home Client Control (FAHControl) #
|
# Folding@Home Client Control (FAHControl) #
|
||||||
# Copyright (C) 2016-2020 foldingathome.org #
|
# Copyright (C) 2016-2020 foldingathome.org #
|
||||||
# Copyright (C) 2010-2016 Stanford University #
|
# Copyright (C) 2010-2016 Stanford University #
|
||||||
# #
|
# #
|
||||||
# This program is free software: you can redistribute it and/or modify #
|
# 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 #
|
# it under the terms of the GNU General Public License as published by #
|
||||||
# the Free Software Foundation, either version 3 of the License, or #
|
# the Free Software Foundation, either version 3 of the License, or #
|
||||||
# (at your option) any later version. #
|
# (at your option) any later version. #
|
||||||
# #
|
# #
|
||||||
# This program is distributed in the hope that it will be useful, #
|
# This program is distributed in the hope that it will be useful, #
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
||||||
# GNU General Public License for more details. #
|
# GNU General Public License for more details. #
|
||||||
# #
|
# #
|
||||||
# You should have received a copy of the GNU General Public License #
|
# You should have received a copy of the GNU General Public License #
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
||||||
# #
|
# #
|
||||||
################################################################################
|
###############################################################################
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
import socket
|
import socket
|
||||||
@ -46,7 +46,6 @@ class SingleAppRequestHandler(socketserver.BaseRequestHandler):
|
|||||||
self.request.send('OK\r\n')
|
self.request.send('OK\r\n')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class SingleAppServer(socketserver.ThreadingMixIn, socketserver.TCPServer):
|
class SingleAppServer(socketserver.ThreadingMixIn, socketserver.TCPServer):
|
||||||
allow_reuse_address = True
|
allow_reuse_address = True
|
||||||
|
|
||||||
@ -60,12 +59,11 @@ class SingleAppServer(socketserver.ThreadingMixIn, socketserver.TCPServer):
|
|||||||
socketserver.TCPServer.__init__(
|
socketserver.TCPServer.__init__(
|
||||||
self, single_app_addr, SingleAppRequestHandler)
|
self, single_app_addr, SingleAppRequestHandler)
|
||||||
|
|
||||||
thread = threading.Thread(target = self.serve_forever)
|
thread = threading.Thread(target=self.serve_forever)
|
||||||
# Exit the server thread when the main thread terminates
|
# Exit the server thread when the main thread terminates
|
||||||
thread.setDaemon(True)
|
thread.setDaemon(True)
|
||||||
thread.start()
|
thread.start()
|
||||||
|
|
||||||
|
|
||||||
def check_for_instance(self):
|
def check_for_instance(self):
|
||||||
sock = None
|
sock = None
|
||||||
try:
|
try:
|
||||||
@ -73,7 +71,7 @@ class SingleAppServer(socketserver.ThreadingMixIn, socketserver.TCPServer):
|
|||||||
sock.connect(single_app_addr)
|
sock.connect(single_app_addr)
|
||||||
sock.send('PING')
|
sock.send('PING')
|
||||||
if sock.recv(1024).strip() == 'OK':
|
if sock.recv(1024).strip() == 'OK':
|
||||||
print ('Already running')
|
print('Already running')
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
except socket.error:
|
except socket.error:
|
||||||
@ -81,4 +79,5 @@ class SingleAppServer(socketserver.ThreadingMixIn, socketserver.TCPServer):
|
|||||||
return
|
return
|
||||||
|
|
||||||
finally:
|
finally:
|
||||||
if sock is not None: sock.close()
|
if sock is not None:
|
||||||
|
sock.close()
|
||||||
|
@ -83,7 +83,7 @@ def get_span_markup(text, bg=None, fg='black'):
|
|||||||
def iterate_container(widget):
|
def iterate_container(widget):
|
||||||
yield widget
|
yield widget
|
||||||
|
|
||||||
if isinstance(widget, gtk.Container):
|
if isinstance(widget, Gtk.Container):
|
||||||
for child in widget.get_children():
|
for child in widget.get_children():
|
||||||
for x in iterate_container(child):
|
for x in iterate_container(child):
|
||||||
yield x
|
yield x
|
||||||
@ -109,7 +109,7 @@ def get_combo_items(widget):
|
|||||||
|
|
||||||
|
|
||||||
def get_widget_str_value(widget):
|
def get_widget_str_value(widget):
|
||||||
if isinstance(widget, (gtk.SpinButton, gtk.Range)):
|
if isinstance(widget, (Gtk.SpinButton, Gtk.Range)):
|
||||||
# Must come before gtk.Entry for gtk.SpinButton
|
# Must come before gtk.Entry for gtk.SpinButton
|
||||||
|
|
||||||
# Clean up float formatting
|
# Clean up float formatting
|
||||||
@ -120,20 +120,20 @@ def get_widget_str_value(widget):
|
|||||||
value = value[0:-2]
|
value = value[0:-2]
|
||||||
return value
|
return value
|
||||||
|
|
||||||
elif isinstance(widget, gtk.Entry):
|
elif isinstance(widget, Gtk.Entry):
|
||||||
return widget.get_text()
|
return widget.get_text()
|
||||||
|
|
||||||
elif isinstance(widget, gtk.RadioButton):
|
elif isinstance(widget, Gtk.RadioButton):
|
||||||
# TODO interpret as a number? or name?
|
# TODO interpret as a number? or name?
|
||||||
pass
|
pass
|
||||||
|
|
||||||
elif isinstance(widget, gtk.ToggleButton):
|
elif isinstance(widget, Gtk.ToggleButton):
|
||||||
if widget.get_active():
|
if widget.get_active():
|
||||||
return 'true'
|
return 'true'
|
||||||
else:
|
else:
|
||||||
return 'false'
|
return 'false'
|
||||||
|
|
||||||
elif isinstance(widget, gtk.ComboBox):
|
elif isinstance(widget, Gtk.ComboBox):
|
||||||
# NOTE This does not always get the displayed text
|
# NOTE This does not always get the displayed text
|
||||||
return widget.get_active_text()
|
return widget.get_active_text()
|
||||||
|
|
||||||
@ -146,7 +146,7 @@ def set_widget_str_value(widget, value):
|
|||||||
value = ''
|
value = ''
|
||||||
value = str(value)
|
value = str(value)
|
||||||
|
|
||||||
if isinstance(widget, (gtk.SpinButton, gtk.Range)):
|
if isinstance(widget, (Gtk.SpinButton, Gtk.Range)):
|
||||||
# Must come before gtk.Entry for gtk.SpinButton
|
# Must come before gtk.Entry for gtk.SpinButton
|
||||||
if value == '':
|
if value == '':
|
||||||
value = 0
|
value = 0
|
||||||
@ -157,20 +157,20 @@ def set_widget_str_value(widget, value):
|
|||||||
value = 0
|
value = 0
|
||||||
widget.set_value(value)
|
widget.set_value(value)
|
||||||
|
|
||||||
elif isinstance(widget, (gtk.Entry, gtk.Label)):
|
elif isinstance(widget, (Gtk.Entry, Gtk.Label)):
|
||||||
if widget.get_text() != value:
|
if widget.get_text() != value:
|
||||||
widget.set_text(value)
|
widget.set_text(value)
|
||||||
elif isinstance(widget, gtk.RadioButton):
|
elif isinstance(widget, Gtk.RadioButton):
|
||||||
pass # Ignore for now
|
pass # Ignore for now
|
||||||
elif isinstance(widget, gtk.ToggleButton):
|
elif isinstance(widget, Gtk.ToggleButton):
|
||||||
widget.set_active(parse_bool(value))
|
widget.set_active(parse_bool(value))
|
||||||
elif isinstance(widget, gtk.Button):
|
elif isinstance(widget, Gtk.Button):
|
||||||
# NOTE: For some reason setting Button labels causes tooltips to hide.
|
# NOTE: For some reason setting Button labels causes tooltips to hide.
|
||||||
# Only set when it has actually changed.
|
# Only set when it has actually changed.
|
||||||
if widget.get_label() != value:
|
if widget.get_label() != value:
|
||||||
widget.set_label(value)
|
widget.set_label(value)
|
||||||
|
|
||||||
elif isinstance(widget, gtk.ComboBox):
|
elif isinstance(widget, Gtk.ComboBox):
|
||||||
items = get_combo_items(widget)
|
items = get_combo_items(widget)
|
||||||
length = len(items)
|
length = len(items)
|
||||||
for i in range(length):
|
for i in range(length):
|
||||||
@ -180,7 +180,7 @@ def set_widget_str_value(widget, value):
|
|||||||
|
|
||||||
print(('ERROR: Invalid value "%s"' % value))
|
print(('ERROR: Invalid value "%s"' % value))
|
||||||
|
|
||||||
elif isinstance(widget, gtk.ProgressBar):
|
elif isinstance(widget, Gtk.ProgressBar):
|
||||||
widget.set_text(value)
|
widget.set_text(value)
|
||||||
|
|
||||||
if value == '':
|
if value == '':
|
||||||
@ -198,16 +198,16 @@ def set_widget_str_value(widget, value):
|
|||||||
|
|
||||||
|
|
||||||
def set_widget_change_action(widget, action):
|
def set_widget_change_action(widget, action):
|
||||||
if isinstance(widget, (gtk.Editable, gtk.ComboBox)):
|
if isinstance(widget, (Gtk.Editable, Gtk.ComboBox)):
|
||||||
widget.connect('changed', action)
|
widget.connect('changed', action)
|
||||||
|
|
||||||
elif isinstance(widget, gtk.Range):
|
elif isinstance(widget, Gtk.Range):
|
||||||
widget.connect('value_changed', action)
|
widget.connect('value_changed', action)
|
||||||
|
|
||||||
elif isinstance(widget, gtk.ToggleButton):
|
elif isinstance(widget, Gtk.ToggleButton):
|
||||||
widget.connect('toggled', action)
|
widget.connect('toggled', action)
|
||||||
|
|
||||||
elif isinstance(widget, gtk.TreeModel):
|
elif isinstance(widget, Gtk.TreeModel):
|
||||||
widget.connect('row_changed', action)
|
widget.connect('row_changed', action)
|
||||||
widget.connect('row_inserted', action)
|
widget.connect('row_inserted', action)
|
||||||
widget.connect('row_deleted', action)
|
widget.connect('row_deleted', action)
|
||||||
@ -240,5 +240,5 @@ def get_theme_dirs():
|
|||||||
resources = quartz_application_get_resource_path()
|
resources = quartz_application_get_resource_path()
|
||||||
path = os.path.join(resources, 'themes')
|
path = os.path.join(resources, 'themes')
|
||||||
return [get_home_dir() + '/themes', path]
|
return [get_home_dir() + '/themes', path]
|
||||||
return [get_home_dir() + '/themes', gtk.rc_get_theme_dir(),
|
return [get_home_dir() + '/themes', Gtk.rc_get_theme_dir(),
|
||||||
'/usr/share/themes']
|
'/usr/share/themes']
|
||||||
|
@ -24,11 +24,11 @@ import gobject
|
|||||||
import pango
|
import pango
|
||||||
|
|
||||||
|
|
||||||
class WrapLabel(gtk.Label):
|
class WrapLabel(Gtk.Label):
|
||||||
__gtype_name__ = 'WrapLabel'
|
__gtype_name__ = 'WrapLabel'
|
||||||
|
|
||||||
def __init__(self, str=None):
|
def __init__(self, str=None):
|
||||||
gtk.Label.__init__(self)
|
Gtk.Label.__init__(self)
|
||||||
|
|
||||||
self.__wrap_width = 0
|
self.__wrap_width = 0
|
||||||
self.layout = self.get_layout()
|
self.layout = self.get_layout()
|
||||||
@ -46,15 +46,15 @@ class WrapLabel(gtk.Label):
|
|||||||
requisition.height = height
|
requisition.height = height
|
||||||
|
|
||||||
def do_size_allocate(self, allocation):
|
def do_size_allocate(self, allocation):
|
||||||
gtk.Label.do_size_allocate(self, allocation)
|
Gtk.Label.do_size_allocate(self, allocation)
|
||||||
self.__set_wrap_width(allocation.width)
|
self.__set_wrap_width(allocation.width)
|
||||||
|
|
||||||
def set_text(self, str):
|
def set_text(self, str):
|
||||||
gtk.Label.set_text(self, str)
|
Gtk.Label.set_text(self, str)
|
||||||
self.__set_wrap_width(self.__wrap_width)
|
self.__set_wrap_width(self.__wrap_width)
|
||||||
|
|
||||||
def set_markup(self, str):
|
def set_markup(self, str):
|
||||||
gtk.Label.set_markup(self, str)
|
Gtk.Label.set_markup(self, str)
|
||||||
self.__set_wrap_width(self.__wrap_width)
|
self.__set_wrap_width(self.__wrap_width)
|
||||||
|
|
||||||
def __set_wrap_width(self, width):
|
def __set_wrap_width(self, width):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user