attempt to fix gtk import

This commit is contained in:
Tux 2023-07-24 15:47:26 +02:00
parent 90abed89c1
commit 2fc888c924
9 changed files with 268 additions and 264 deletions

View File

@ -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

View File

@ -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:

View File

@ -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()

View File

@ -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)

View File

@ -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):

View File

@ -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)

View File

@ -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()

View File

@ -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']

View File

@ -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):