mirror of
https://github.com/EDCD/EDMarketConnector.git
synced 2025-04-14 08:17:13 +03:00
ttkHyperlinklabel.py: Initial flake8 pass (and some mypy)
This fixes an apparently harmless bug in the `openurl()` function defined in this module (it's not part of the class). 1. On `win32` lookup the user setting for opening HTTPS URLs. 2. If that doesn't look like IE or Edge... 3. Set `cls` to the value for that. 4. Now look up the 'use this command' for *that* ... 5. And if it doesn't have `iexplore` in it... 6. Use `subprocess.Popen()` to invoke that browser with the given URL. The problem is that step 6 still tries to use `buf.value`. But `buf` is no longer present as it was from before 5989acd0d3263e54429ff99769ff73a20476d863 changed over to `winreg`. It should be just `value` from the winreg calls. That exception is then caught and ignored, and it ends up just running `webbrowser.open(url)` anyway. To be honest, this feels like we should just make this an unconditional call to `webbrowser.open(url)` now, given apparently no-one's complained about it always actually using that not working for them. Given Edge is Chrome-based now, and any supported OS should have Edge, Chrome or Firefox (OK, maybe Safari and some others) as the HTTPS browser, I don't see this being an issue.
This commit is contained in:
parent
0dbbb38821
commit
e280d6c283
@ -1,7 +1,23 @@
|
||||
"""
|
||||
A clickable ttk label for HTTP links.
|
||||
|
||||
In addition to standard ttk.Label arguments, takes the following arguments:
|
||||
url: The URL as a string that the user will be sent to on clicking on
|
||||
non-empty label text. If url is a function it will be called on click with
|
||||
the current label text and should return the URL as a string.
|
||||
underline: If True/False the text is always/never underlined. If None (the
|
||||
default) the text is underlined only on hover.
|
||||
popup_copy: Whether right-click on non-empty label text pops up a context
|
||||
menu with a 'Copy' option. Defaults to no context menu. If popup_copy is a
|
||||
function it will be called with the current label text and should return a
|
||||
boolean.
|
||||
|
||||
May be imported by plugins
|
||||
"""
|
||||
import sys
|
||||
import tkinter as tk
|
||||
import webbrowser
|
||||
from tkinter import font as tkFont
|
||||
from tkinter import font as tk_font
|
||||
from tkinter import ttk
|
||||
|
||||
if sys.platform == 'win32':
|
||||
@ -10,15 +26,10 @@ if sys.platform == 'win32':
|
||||
|
||||
# A clickable ttk Label
|
||||
#
|
||||
# In addition to standard ttk.Label arguments, takes the following arguments:
|
||||
# url: The URL as a string that the user will be sent to on clicking on non-empty label text. If url is a function it will be called on click with the current label text and should return the URL as a string.
|
||||
# underline: If True/False the text is always/never underlined. If None (the default) the text is underlined only on hover.
|
||||
# popup_copy: Whether right-click on non-empty label text pops up a context menu with a 'Copy' option. Defaults to no context menu. If popup_copy is a function it will be called with the current label text and should return a boolean.
|
||||
#
|
||||
# May be imported by plugins
|
||||
|
||||
|
||||
class HyperlinkLabel(sys.platform == 'darwin' and tk.Label or ttk.Label, object):
|
||||
"""Clickable label for HTTP links."""
|
||||
|
||||
def __init__(self, master=None, **kw):
|
||||
self.url = 'url' in kw and kw.pop('url') or None
|
||||
@ -51,8 +62,8 @@ class HyperlinkLabel(sys.platform == 'darwin' and tk.Label or ttk.Label, object)
|
||||
text=kw.get('text'),
|
||||
font=kw.get('font', ttk.Style().lookup('TLabel', 'font')))
|
||||
|
||||
# Change cursor and appearance depending on state and text
|
||||
def configure(self, cnf=None, **kw):
|
||||
def configure(self, cnf=None, **kw): # noqa: CCR001
|
||||
"""Change cursor and appearance depending on state and text."""
|
||||
# This class' state
|
||||
for thing in ['url', 'popup_copy', 'underline']:
|
||||
if thing in kw:
|
||||
@ -71,7 +82,7 @@ class HyperlinkLabel(sys.platform == 'darwin' and tk.Label or ttk.Label, object)
|
||||
|
||||
if 'font' in kw:
|
||||
self.font_n = kw['font']
|
||||
self.font_u = tkFont.Font(font=self.font_n)
|
||||
self.font_u = tk_font.Font(font=self.font_n)
|
||||
self.font_u.configure(underline=True)
|
||||
kw['font'] = self.underline is True and self.font_u or self.font_n
|
||||
|
||||
@ -86,7 +97,13 @@ class HyperlinkLabel(sys.platform == 'darwin' and tk.Label or ttk.Label, object)
|
||||
|
||||
super(HyperlinkLabel, self).configure(cnf, **kw)
|
||||
|
||||
def __setitem__(self, key, value):
|
||||
def __setitem__(self, key, value) -> None:
|
||||
"""
|
||||
Allow for dict member style setting of options.
|
||||
|
||||
:param key: option name
|
||||
:param value: option value
|
||||
"""
|
||||
self.configure(None, **{key: value})
|
||||
|
||||
def _enter(self, event):
|
||||
@ -108,17 +125,23 @@ class HyperlinkLabel(sys.platform == 'darwin' and tk.Label or ttk.Label, object)
|
||||
if self['text'] and (self.popup_copy(self['text']) if callable(self.popup_copy) else self.popup_copy):
|
||||
self.menu.post(sys.platform == 'darwin' and event.x_root + 1 or event.x_root, event.y_root)
|
||||
|
||||
def copy(self):
|
||||
def copy(self) -> None:
|
||||
"""Copy the current text to the clipboard."""
|
||||
self.clipboard_clear()
|
||||
self.clipboard_append(self['text'])
|
||||
|
||||
|
||||
def openurl(url):
|
||||
def openurl(url) -> None: # noqa: CCR001
|
||||
"""
|
||||
Open the given URL in appropriate browser.
|
||||
|
||||
:param url: URL to open.
|
||||
"""
|
||||
if sys.platform == 'win32':
|
||||
# FIXME: Is still still true with supported Windows 10 and 11 ?
|
||||
# On Windows webbrowser.open calls os.startfile which calls ShellExecute which can't handle long arguments,
|
||||
# so discover and launch the browser directly.
|
||||
# https://blogs.msdn.microsoft.com/oldnewthing/20031210-00/?p=41553
|
||||
|
||||
try:
|
||||
hkey = OpenKeyEx(HKEY_CURRENT_USER,
|
||||
r'Software\Microsoft\Windows\Shell\Associations\UrlAssociations\https\UserChoice')
|
||||
@ -128,23 +151,28 @@ def openurl(url):
|
||||
# IE and Edge can't handle long arguments so just use webbrowser.open and hope
|
||||
# https://blogs.msdn.microsoft.com/ieinternals/2014/08/13/url-length-limits/
|
||||
cls = None
|
||||
|
||||
else:
|
||||
cls = value
|
||||
except:
|
||||
|
||||
except Exception:
|
||||
cls = 'https'
|
||||
|
||||
if cls:
|
||||
try:
|
||||
hkey = OpenKeyEx(HKEY_CLASSES_ROOT, r'%s\shell\open\command' % cls)
|
||||
hkey = OpenKeyEx(HKEY_CLASSES_ROOT, rf'{cls}\shell\open\command')
|
||||
(value, typ) = QueryValueEx(hkey, None)
|
||||
CloseKey(hkey)
|
||||
if 'iexplore' not in value.lower():
|
||||
if '%1' in value:
|
||||
subprocess.Popen(buf.value.replace('%1', url))
|
||||
subprocess.Popen(value.replace('%1', url))
|
||||
|
||||
else:
|
||||
subprocess.Popen('%s "%s"' % (buf.value, url))
|
||||
subprocess.Popen(f'{value} "{url}"')
|
||||
|
||||
return
|
||||
except:
|
||||
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
webbrowser.open(url)
|
||||
|
Loading…
x
Reference in New Issue
Block a user