on screen keyboard support, to be improved
This commit is contained in:
parent
3300f55fec
commit
74479e3108
3
open_osk.py
Normal file
3
open_osk.py
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
import src.lib.oskb.cli as oskbcli
|
||||
|
||||
oskbcli.main()
|
||||
3
open_oskb.sh
Executable file
3
open_oskb.sh
Executable file
|
|
@ -0,0 +1,3 @@
|
|||
#!/bin/bash
|
||||
source venv/bin/activat
|
||||
python open_osk.py
|
||||
3
src/lib/oskb/__init__.py
Normal file
3
src/lib/oskb/__init__.py
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
import pkg_resources
|
||||
|
||||
from oskb.oskb import *
|
||||
376
src/lib/oskb/cli.py
Normal file
376
src/lib/oskb/cli.py
Normal file
|
|
@ -0,0 +1,376 @@
|
|||
import argparse, sys, os, psutil, subprocess, re, signal
|
||||
from PyQt5.QtWidgets import QApplication
|
||||
from PyQt5.QtCore import Qt, QTimer
|
||||
import pkg_resources
|
||||
|
||||
import oskb
|
||||
from oskb import im
|
||||
|
||||
linux = sys.platform.startswith("linux")
|
||||
|
||||
if linux:
|
||||
import getpass
|
||||
from ewmh import EWMH, ewmh
|
||||
|
||||
wm = EWMH()
|
||||
moved_windows = []
|
||||
|
||||
|
||||
def command_line_arguments():
|
||||
ap = argparse.ArgumentParser()
|
||||
ap.add_argument(
|
||||
"keyboards",
|
||||
help="""Which keyboard(s) to load. These are either files or names of built-in keyboards. If
|
||||
multiple keyboards are loaded, the user can switch between them with a menu key. If no keyboards are chosen
|
||||
a full keyboard is shown if display is wider than 600 pixels, otherwise a phone-style keyboard is used. If
|
||||
oskb comes with a keyboard for the presently set keyboard layout, that keyboard is used. Otherwise oskb
|
||||
will show a US keyboard layout and switch the system keyboard layout to that.""",
|
||||
metavar="<kbd>",
|
||||
nargs="*",
|
||||
)
|
||||
ap.add_argument("--version", "-v", help="Print version number and exit.", action="store_true")
|
||||
ap.add_argument(
|
||||
"--start",
|
||||
metavar="<kbd>",
|
||||
help="""Normally the first keyboard specified is shown first. This allows you to specify one of the
|
||||
loaded keyboards as the one to start with.""",
|
||||
)
|
||||
ap.add_argument(
|
||||
"--list", action="store_true", help="Lists all built-in keyboards that were shipped with oskb.",
|
||||
)
|
||||
ap.add_argument(
|
||||
"--dump",
|
||||
help="Keyboards are JSON files. This will write the contents of a built-in keyboard to stdout.",
|
||||
action="store_true",
|
||||
)
|
||||
ap.add_argument(
|
||||
"--nomap",
|
||||
help="""Prevent oskb from changing the system keyboard to the keymap specified with the keyboard.""",
|
||||
action="store_true",
|
||||
)
|
||||
ap.add_argument(
|
||||
"--toggle",
|
||||
help="""Will turn the keyboard off if one is already active, otherwise starts the keyboard. This
|
||||
allows one shortcut to be used to turn the keyboard on and off.""",
|
||||
action="store_true",
|
||||
)
|
||||
ap.add_argument("--off", help="Turns off a running keyboard.", action="store_true")
|
||||
ap.add_argument(
|
||||
"--nopushaway",
|
||||
help="Do not attempt to push other windows out of the way when showing the keyboard.",
|
||||
action="store_true",
|
||||
)
|
||||
modmode = ap.add_mutually_exclusive_group()
|
||||
modmode.add_argument(
|
||||
"--flashmod",
|
||||
help="""Only press the modifier keys (Alt, Shift, etc) down briefly during each keypress. This is the
|
||||
default when --float is specified.""",
|
||||
action="store_true",
|
||||
)
|
||||
modmode.add_argument(
|
||||
"--steadymod",
|
||||
help="""Modifier keys are pressed down as shown in interface. This is the default unless --float is
|
||||
specified.""",
|
||||
action="store_true",
|
||||
)
|
||||
ap.add_argument("--justshow", help="Show keyboard, do not send keys to OS.", action="store_true")
|
||||
|
||||
loc = ap.add_argument_group(title="Controlling position on screen")
|
||||
loc.add_argument("-x", help="Absolute position of left side of keyboard", metavar="<x>", type=int)
|
||||
loc.add_argument("-y", help="Absolute position of top of keyboard", metavar="<y>", type=int)
|
||||
loc.add_argument("--width",
|
||||
help="Keyboard width in pixels. The default is to use the full width of the primary display.",
|
||||
metavar="<width>",
|
||||
type=int,
|
||||
)
|
||||
loc.add_argument(
|
||||
"--height",
|
||||
help="Keyboard height in pixels. The default is a third of the height of the primary display.",
|
||||
metavar="<height>",
|
||||
type=int,
|
||||
)
|
||||
hpos = loc.add_mutually_exclusive_group()
|
||||
hpos.add_argument("--left", help="Keyboard docks to the left side of the screen.", action="store_true")
|
||||
hpos.add_argument(
|
||||
"--middle",
|
||||
"--center",
|
||||
help="Keyboard docks in the middle of the screen. This is the default.",
|
||||
action="store_true",
|
||||
)
|
||||
hpos.add_argument("--right", help="Keyboard docks to the right side of the screen.", action="store_true")
|
||||
vpos = loc.add_mutually_exclusive_group()
|
||||
vpos.add_argument(
|
||||
"--top", help="Keyboard docks to the top of the screen. This is the default.", action="store_true"
|
||||
)
|
||||
vpos.add_argument("--bottom", help="Keyboard docks to the bottom of the screen.", action="store_true")
|
||||
loc.add_argument(
|
||||
"--float", help="Floating keyboard window instead of fixed docked position.", action="store_true",
|
||||
)
|
||||
|
||||
return ap
|
||||
|
||||
|
||||
def main():
|
||||
global x, y, w, h
|
||||
|
||||
#
|
||||
# Parse command line arguments
|
||||
#
|
||||
|
||||
ap = command_line_arguments()
|
||||
cmdline = ap.parse_args("")
|
||||
|
||||
if cmdline.version:
|
||||
print(pkg_resources.get_distribution("oskb").version)
|
||||
sys.exit(0)
|
||||
|
||||
if cmdline.list:
|
||||
for k in pkg_resources.resource_listdir("oskb", "keyboards"):
|
||||
if not k.startswith("_"):
|
||||
print(k)
|
||||
sys.exit(0)
|
||||
|
||||
if cmdline.dump:
|
||||
if len(cmdline.keyboards) != 1:
|
||||
sys.stderr.write("Must specify exactly one built-in keyboard to dump.\n")
|
||||
sys.exit(-1)
|
||||
if not pkg_resources.resource_exists("oskb", "keyboards/" + cmdline.keyboards[0]):
|
||||
sys.stderr.write("Built-in keyboard '" + cmdline.keyboards[0] + "' not found.\n")
|
||||
sys.exit(-1)
|
||||
print(pkg_resources.resource_string("oskb", "keyboards/" + cmdline.keyboards[0]).decode("utf-8"))
|
||||
sys.exit(0)
|
||||
|
||||
#
|
||||
# Kill any existing keyboard instances. If we did end up killing existing keyboards
|
||||
# only start up if '--toggle' wasn't specified. It allows the same command line to
|
||||
# be used to turn the keyboard on and off. '--off' just kills keyboard processes.
|
||||
#
|
||||
|
||||
ikilled = False
|
||||
mypid = os.getpid()
|
||||
myparent = os.getppid()
|
||||
myname = "oskb"
|
||||
for proc in psutil.process_iter(attrs=(["pid"])):
|
||||
try:
|
||||
if not proc.pid == mypid and not proc.pid == myparent:
|
||||
itsname = os.path.basename(proc.name())
|
||||
if re.match("^[Pp]ython\d*$", itsname) and len(proc.cmdline()) > 1:
|
||||
itsname = os.path.basename(proc.cmdline()[1])
|
||||
if itsname == myname:
|
||||
proc.send_signal(9)
|
||||
ikilled = True
|
||||
except:
|
||||
pass
|
||||
if (ikilled and cmdline.toggle) or cmdline.off:
|
||||
sys.exit()
|
||||
|
||||
#
|
||||
# Start the Qt context
|
||||
#
|
||||
|
||||
app = QApplication([])
|
||||
|
||||
#
|
||||
# Make sure Ctrl-C can interrupt oskb
|
||||
#
|
||||
|
||||
def sigint_handler(*args):
|
||||
sys.stderr.write("\r")
|
||||
QApplication.quit()
|
||||
|
||||
signal.signal(signal.SIGINT, sigint_handler)
|
||||
timer = QTimer()
|
||||
timer.start(250)
|
||||
timer.timeout.connect(lambda: None)
|
||||
|
||||
#
|
||||
# Get our keyboard widget instance
|
||||
#
|
||||
|
||||
keyboard = oskb.Keyboard()
|
||||
if cmdline.float:
|
||||
keyboard.setWindowTitle("On-Screen Keyboard")
|
||||
keyboard.setWindowFlags(Qt.WindowStaysOnTopHint | Qt.WindowDoesNotAcceptFocus)
|
||||
if not cmdline.steadymod:
|
||||
keyboard.setFlashModifiers(True)
|
||||
else:
|
||||
if linux and not cmdline.nopushaway:
|
||||
keyboard.sendScreenState(receiveScreenState)
|
||||
if not cmdline.flashmod:
|
||||
keyboard.setFlashModifiers(False)
|
||||
# quickly make sure X doesn't make a window frame etc.
|
||||
keyboard.setWindowFlags(Qt.WindowStaysOnTopHint | Qt.X11BypassWindowManagerHint)
|
||||
# Qt.X11BypassWindowManagerHint means no WM border or title, no application focus, not in taskbar
|
||||
|
||||
# also works but creates taskbar entry that will application focus to oskb if pressed
|
||||
# ( Qt.WindowStaysOnTopHint | Qt.WindowDoesNotAcceptFocus | Qt.FramelessWindowHint)
|
||||
|
||||
#
|
||||
# Figure out where and how big we're going to be on the screen
|
||||
#
|
||||
|
||||
# First take the screen dimensions
|
||||
desktop = app.desktop()
|
||||
screen = desktop.screenGeometry()
|
||||
screenleft = 0
|
||||
screentop = 0
|
||||
screenwidth = screen.width()
|
||||
screenheight = screen.height()
|
||||
# On Linux see if we can improve on that by asking windowmanager for workarea (minus taskbar etc).
|
||||
if linux:
|
||||
try:
|
||||
screenleft, screentop, screenwidth, screenheight = list(wm.getWorkArea()[0:4])
|
||||
except:
|
||||
pass
|
||||
# set width and height from arguments, defaulting to screen width and quarter of screen height resp.
|
||||
w = cmdline.width if cmdline.width else screenwidth
|
||||
h = cmdline.height if cmdline.height else max(250, int(screenheight / 3))
|
||||
mw, mh = 70, 70 # Size of minimized keyboard button
|
||||
# Vertical position
|
||||
if cmdline.y:
|
||||
y = cmdline.y
|
||||
else:
|
||||
if cmdline.top:
|
||||
y = screentop
|
||||
my = screentop
|
||||
else:
|
||||
y = screentop + screenheight - h
|
||||
my = screentop + screenheight - mh
|
||||
# Horizontal position
|
||||
if cmdline.x:
|
||||
x = cmdline.x
|
||||
else:
|
||||
if cmdline.left:
|
||||
x = screenleft
|
||||
mx = screenleft
|
||||
elif cmdline.right:
|
||||
x = screenleft + screenwidth - w
|
||||
mx = screenleft + screenwidth - mw
|
||||
else:
|
||||
x = int(screenleft + (screenwidth / 2) - (w / 2))
|
||||
mx = int(screenleft + (screenwidth / 2) - (mw / 2))
|
||||
|
||||
# Set geometry accordingly
|
||||
keyboard.setMinimizer(mx, my, mw, mh)
|
||||
keyboard.setGeometry(x, y, w, h)
|
||||
|
||||
#
|
||||
# Figure out default keyboard if nothing selected
|
||||
#
|
||||
|
||||
# (Has to be done before plugging in virtual keyboard, bc that switches map to 'us')
|
||||
load_keyboards = cmdline.keyboards
|
||||
if load_keyboards == []:
|
||||
kbname = 'paddy' if screenwidth > 600 else 'phoney'
|
||||
tryfirst = kbname + "-" + querySystemKeymap("layout")
|
||||
if pkg_resources.resource_exists("oskb", "keyboards/" + tryfirst):
|
||||
load_keyboards = [tryfirst]
|
||||
else:
|
||||
load_keyboards = [kbname + "-us"]
|
||||
|
||||
#
|
||||
# Tell keyboard to send the keypresses to the default handler for OS
|
||||
#
|
||||
|
||||
if not cmdline.justshow:
|
||||
plugged = False
|
||||
try:
|
||||
plugged = keyboard.sendKeys(im.default().receiveKeys)
|
||||
except:
|
||||
sys.stderr.write("Could not set up the virtual keyboard.\n")
|
||||
|
||||
if not plugged:
|
||||
if linux:
|
||||
user = getpass.getuser()
|
||||
sys.stderr.write(
|
||||
"Try 'sudo setfacl -m m::rw -m u:" + user + ":rw /dev/uinput /dev/input/*'\n"
|
||||
"See the oskb documentation for more information.\n"
|
||||
)
|
||||
else:
|
||||
sys.stderr.write(
|
||||
"Your platform is not yet supported by oskd. Try --justshow if\n"
|
||||
"you just want to see how pretty oskb is.\n"
|
||||
)
|
||||
sys.exit(-1)
|
||||
|
||||
#
|
||||
# Tell oskb where to send keymap changes, so we can call setxkbmap to switch as well
|
||||
#
|
||||
|
||||
if not cmdline.nomap:
|
||||
keyboard.sendMapChanges(receiveMapChanges)
|
||||
|
||||
#
|
||||
# Load the keyboard files
|
||||
#
|
||||
|
||||
for k in load_keyboards:
|
||||
keyboard.readKeyboard(k)
|
||||
|
||||
# Also works if no startup kbd is specified, because None will load first keyboard
|
||||
keyboard.setKeyboard(cmdline.start)
|
||||
|
||||
#
|
||||
# Display the keyboard
|
||||
#
|
||||
|
||||
keyboard.show()
|
||||
|
||||
sys.exit(app.exec_())
|
||||
|
||||
|
||||
|
||||
|
||||
def querySystemKeymap(key, default = None):
|
||||
try:
|
||||
output = subprocess.check_output(['setxkbmap', '-query']).decode("utf-8")
|
||||
match = re.search(key + ":\s+(\w+)", output)
|
||||
if match:
|
||||
return match.group(1)
|
||||
else:
|
||||
return default
|
||||
except:
|
||||
return default
|
||||
|
||||
|
||||
def receiveMapChanges(keymap):
|
||||
try:
|
||||
subprocess.run(["setxkbmap"] + keymap.split(" "))
|
||||
except:
|
||||
pass
|
||||
|
||||
|
||||
def receiveScreenState(maximize):
|
||||
def get_geometry(window):
|
||||
g = window.get_geometry()
|
||||
return g.x, g.y, g.width, g.height
|
||||
|
||||
def frame(window):
|
||||
frame = window
|
||||
while frame.query_tree().parent != wm.root:
|
||||
frame = frame.query_tree().parent
|
||||
return frame
|
||||
|
||||
global moved_windows
|
||||
if maximize:
|
||||
moved_windows = []
|
||||
for window in wm.getClientList():
|
||||
wn = wm.getWmName(window).decode("utf-8")
|
||||
wx, wy, ww, wh = get_geometry(window)
|
||||
fx, fy, fw, fh = get_geometry(frame(window))
|
||||
bottom = fy + fh
|
||||
if bottom > y and bottom < y + h and fy < y + h:
|
||||
need = bottom - y + (fh - wh)
|
||||
moveby = min(fy, need)
|
||||
shrinkby = need - moveby
|
||||
nx, nw = fx, fw
|
||||
ny = fy - moveby
|
||||
nh = bottom - fy - shrinkby
|
||||
wm.setMoveResizeWindow(window, gravity=ewmh.X.SouthWestGravity, x=nx, y=ny, w=nw, h=nh)
|
||||
moved_windows.append((window, (fx, fy, fw - (fw - ww), fh - (fh - wh)), (nx, ny, nw, nh)))
|
||||
else:
|
||||
for w in moved_windows:
|
||||
window = w[0]
|
||||
(nx, ny, nw, nh) = w[1]
|
||||
wm.setMoveResizeWindow(window, gravity=ewmh.X.SouthWestGravity, x=nx, y=ny, w=nw, h=nh)
|
||||
wm.display.flush()
|
||||
33
src/lib/oskb/default.css
Normal file
33
src/lib/oskb/default.css
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
QWidget {
|
||||
background-color: #cccccc;
|
||||
margin:0px;
|
||||
}
|
||||
|
||||
QLabel {
|
||||
font-size: 50%;
|
||||
background: transparent;
|
||||
margin: 2px 5px;
|
||||
qproperty-alignment: 'AlignBottom | AlignLeft';
|
||||
}
|
||||
|
||||
.key {
|
||||
background-color: #eeeeee;
|
||||
border: 1px solid black;
|
||||
font-size: _OSKB_FONTSIZE_px;
|
||||
margin: _OSKB_MARGIN_px;
|
||||
border-radius: _OSKB_RADIUS_px;
|
||||
}
|
||||
|
||||
.spacer, .emptyrow {
|
||||
background-color: #cccccc;
|
||||
border: none;
|
||||
color: #cccccc;
|
||||
}
|
||||
|
||||
.key:not(modifier):pressed, .key.pseudomodifier, .key.held {
|
||||
background-color: #999999;
|
||||
}
|
||||
|
||||
.view .key.pseudomodifier, .key.locked {
|
||||
background-color: #cc9999;
|
||||
}
|
||||
20
src/lib/oskb/im/__init__.py
Normal file
20
src/lib/oskb/im/__init__.py
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
import sys, importlib, pkg_resources
|
||||
from os.path import basename
|
||||
|
||||
# All this does is "from * import *", if python only accepted that
|
||||
# https://stackoverflow.com/questions/43059267/how-to-do-from-module-import-using-importlib
|
||||
for module in pkg_resources.resource_listdir("oskb.im", ""):
|
||||
if module.startswith("_"):
|
||||
continue
|
||||
module = basename(module)[:-3]
|
||||
modhandle = importlib.import_module("oskb.im." + module)
|
||||
names = [x for x in modhandle.__dict__ if not x.startswith("_")]
|
||||
globals().update({k: getattr(modhandle, k) for k in names})
|
||||
|
||||
|
||||
# Return a default handler for a given platform
|
||||
|
||||
|
||||
def default():
|
||||
if sys.platform.startswith("linux"):
|
||||
return UInput()
|
||||
13
src/lib/oskb/im/uinput.py
Normal file
13
src/lib/oskb/im/uinput.py
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
import sys
|
||||
|
||||
if sys.platform.startswith("linux"):
|
||||
|
||||
import evdev
|
||||
|
||||
class UInput:
|
||||
def __init__(self):
|
||||
self.uinput = evdev.UInput(name="oskb")
|
||||
|
||||
def receiveKeys(self, keycode, keyevent):
|
||||
self.uinput.write(evdev.ecodes.EV_KEY, keycode, keyevent)
|
||||
self.uinput.syn()
|
||||
18
src/lib/oskb/keyboards/_new
Executable file
18
src/lib/oskb/keyboards/_new
Executable file
|
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"format": "oskb keyboard",
|
||||
"formatversion": 1,
|
||||
"description": "unnamed keyboard",
|
||||
"views": {
|
||||
"default" : {
|
||||
"columns": [
|
||||
{
|
||||
"rows": [
|
||||
{
|
||||
"keys": []
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
2103
src/lib/oskb/keyboards/paddy-de
Normal file
2103
src/lib/oskb/keyboards/paddy-de
Normal file
File diff suppressed because it is too large
Load Diff
2018
src/lib/oskb/keyboards/paddy-us
Normal file
2018
src/lib/oskb/keyboards/paddy-us
Normal file
File diff suppressed because it is too large
Load Diff
2001
src/lib/oskb/keyboards/phoney-de
Normal file
2001
src/lib/oskb/keyboards/phoney-de
Normal file
File diff suppressed because it is too large
Load Diff
1947
src/lib/oskb/keyboards/phoney-us
Normal file
1947
src/lib/oskb/keyboards/phoney-us
Normal file
File diff suppressed because it is too large
Load Diff
661
src/lib/oskb/oskb.py
Normal file
661
src/lib/oskb/oskb.py
Normal file
|
|
@ -0,0 +1,661 @@
|
|||
import os, sys, re, json, subprocess
|
||||
from functools import partial
|
||||
import pkg_resources
|
||||
|
||||
from PyQt5.QtCore import QTimer, QRect, QSysInfo, QEvent, QSize, Qt
|
||||
from PyQt5.QtWidgets import (
|
||||
QWidget,
|
||||
QPushButton,
|
||||
QMainWindow,
|
||||
QGridLayout,
|
||||
QHBoxLayout,
|
||||
QSizePolicy,
|
||||
QLayout,
|
||||
QStackedLayout,
|
||||
QLabel,
|
||||
)
|
||||
|
||||
|
||||
RELEASED = 0
|
||||
PRESSED = 1
|
||||
|
||||
COLUMN_MARGIN = 0.1
|
||||
|
||||
# key detection timings in milliseconds
|
||||
LONGPRESS_TIMEOUT = 350
|
||||
DOUBLECLICK_TIMEOUT = 200
|
||||
|
||||
# The keyboard file format has its own version numbering
|
||||
KEYBOARDFILE_VERSION = 1
|
||||
|
||||
|
||||
class Keyboard(QWidget):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self._modifiers = {}
|
||||
self._flashmodifiers = True
|
||||
# This is all for the key-detection state-machine
|
||||
self._longpresswait = False
|
||||
self._longtimer = QTimer()
|
||||
self._stopsinglepress = False
|
||||
self._doublebutton = None
|
||||
self._doubletimer = QTimer()
|
||||
self._doubletimer.setSingleShot(True)
|
||||
self._doubletimer.timeout.connect(self._doubleTimeout)
|
||||
|
||||
self._viewindex = None
|
||||
self._kbdname = None
|
||||
|
||||
self._viewuntil = None
|
||||
self._thenview = None
|
||||
|
||||
self._kbds = {}
|
||||
|
||||
# Create the special 'chooser' keyboard that shows all the loaded keyboards
|
||||
self._kbds["_chooser"] = {
|
||||
"views": {"default": {"columns": [{"rows": []}]}},
|
||||
}
|
||||
|
||||
# Create the special 'minimized' keyboard that shows one small button
|
||||
self._kbds["_minimized"] = {
|
||||
"style": "QWidget {background: transparent;}",
|
||||
"views": {
|
||||
"default": {
|
||||
"columns": [
|
||||
{"rows": [{"keys": [{"caption": "⌨", "single": {"keyboard": {"name": "back"}}}]}]}
|
||||
],
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
self._view = None
|
||||
self._viewname = "default"
|
||||
self._kbd = None
|
||||
self._sendkeys = None
|
||||
self._sendmapchanges = None
|
||||
self._sendscreenstate = None
|
||||
self._buttonhandler = self._oskbButtonHandler
|
||||
self._minimizerlocation = QRect(0, 0, 70, 70)
|
||||
|
||||
self._kbdstack = QStackedLayout(self)
|
||||
|
||||
self._stylesheet = pkg_resources.resource_string("oskb", "default.css").decode("utf-8")
|
||||
|
||||
#
|
||||
# Reimplemented Qt methods
|
||||
#
|
||||
|
||||
# Make sure show events also calculate proper sizes and first initialise if that hasn't happened yet.
|
||||
def showEvent(self, event):
|
||||
self.updateKeyboard()
|
||||
QWidget.showEvent(self, event)
|
||||
|
||||
# Recalculate the fontsize and mrgaing and change the stylesheets when resizing
|
||||
def resizeEvent(self, event):
|
||||
QWidget.resizeEvent(self, event)
|
||||
if self._view and self.isVisible():
|
||||
self.updateKeyboard()
|
||||
|
||||
# We just store the stylesheet, and then only do the super().setStyleSheet() when we've
|
||||
# recalculated values in updateKeyboard()
|
||||
def setStyleSheet(self, stylesheet):
|
||||
self._stylesheet = stylesheet
|
||||
|
||||
#
|
||||
# Our own public
|
||||
#
|
||||
|
||||
# specify callback that receives keymap information when user switches keyboards using _chooser
|
||||
def sendMapChanges(self, function):
|
||||
if callable(function):
|
||||
self._sendmapchanges = function
|
||||
return True
|
||||
return False
|
||||
|
||||
def sendScreenState(self, function):
|
||||
if callable(function):
|
||||
self._sendscreenstate = function
|
||||
return True
|
||||
return False
|
||||
|
||||
def sendKeys(self, function):
|
||||
if callable(function):
|
||||
self._sendkeys = function
|
||||
return True
|
||||
return False
|
||||
|
||||
def setButtonHandler(self, handler=None):
|
||||
if not handler:
|
||||
handler = self._oskbButtonHandler
|
||||
self._buttonhandler = handler
|
||||
|
||||
def setMinimizer(self, mx, my, mw, mh):
|
||||
self._minimizerlocation = QRect(mx, my, mw, mh)
|
||||
|
||||
def setFlashModifiers(self, mode):
|
||||
self._flashmodifiers = mode
|
||||
|
||||
def readKeyboard(self, kbdfile):
|
||||
kbd = None
|
||||
if os.access(kbdfile, os.R_OK):
|
||||
with open(kbdfile, "r", encoding="utf-8") as f:
|
||||
kbd = json.load(f)
|
||||
elif kbdfile == os.path.basename(kbdfile) and pkg_resources.resource_exists(
|
||||
"oskb", "keyboards/" + kbdfile
|
||||
):
|
||||
kbd = json.loads(pkg_resources.resource_string("oskb", "keyboards/" + kbdfile))
|
||||
if not kbd:
|
||||
raise FileNotFoundError("Could not find " + kbdfile)
|
||||
if kbd.get("format") != "oskb keyboard":
|
||||
raise RuntimeError("Not an oskb keyboard file")
|
||||
if kbd.get("formatversion") > KEYBOARDFILE_VERSION:
|
||||
raise RuntimeError("oskb keyboard file for newer oskb version. You must upgrade.")
|
||||
kbdname = os.path.basename(kbdfile)
|
||||
self._kbds[kbdname] = kbd
|
||||
self._updateChooser()
|
||||
self.initKeyboards()
|
||||
return os.path.basename(kbdfile)
|
||||
|
||||
def getView(self):
|
||||
return self._viewname
|
||||
|
||||
def getViews(self):
|
||||
return self._kbd["views"].keys()
|
||||
|
||||
def _updateChooser(self):
|
||||
if not self._kbds.get("_chooser"):
|
||||
return
|
||||
therows = self._kbds["_chooser"]["views"]["default"]["columns"][0]["rows"]
|
||||
therows.clear()
|
||||
for kbdname, kbd in self._kbds.items():
|
||||
if kbdname.startswith("_"):
|
||||
continue
|
||||
therows.append(
|
||||
{"keys": [{"caption": kbd.get("description"), "single": {"keyboard": {"name": kbdname}},}]}
|
||||
)
|
||||
|
||||
def setKeyboard(self, kbdname=None):
|
||||
if self._sendscreenstate:
|
||||
self._sendscreenstate(kbdname != "_minimized")
|
||||
newgeometry = None
|
||||
if kbdname == "_minimized":
|
||||
newgeometry = self._minimizerlocation
|
||||
else:
|
||||
if kbdname == "back":
|
||||
kbdname = self._previouskeyboard
|
||||
if self._previousgeometry != self.geometry():
|
||||
newgeometry = self._previousgeometry
|
||||
for n, k in self._kbds.items():
|
||||
if kbdname and kbdname != n:
|
||||
continue
|
||||
if not kbdname and n.startswith("_"):
|
||||
continue
|
||||
self._kbdname = n
|
||||
self._kbd = k
|
||||
# print("setKeybaord picked ", n)
|
||||
self._releaseModifiers()
|
||||
if self._sendmapchanges and k.get("keymap"):
|
||||
self._sendmapchanges(k.get("keymap"))
|
||||
if newgeometry:
|
||||
self.hide()
|
||||
if kbdname != "_minimized":
|
||||
self._previouskeyboard = n
|
||||
self._previousgeometry = self.geometry()
|
||||
self._kbdstack.setCurrentIndex(k.get("_stackindex", 0))
|
||||
if self._kbd["views"].get(self._viewname):
|
||||
self.setView(self._viewname, newgeometry)
|
||||
else:
|
||||
self.setView("default", newgeometry)
|
||||
return True
|
||||
return False
|
||||
|
||||
def setView(self, viewname, newgeometry=None):
|
||||
# print ("setView", viewname)
|
||||
if self._kbd["views"].get(viewname):
|
||||
self._view = self._kbd["views"][viewname]
|
||||
self._viewname = viewname
|
||||
self._kbd["_QWidget"].layout().setCurrentIndex(self._view["_stackindex"])
|
||||
if newgeometry:
|
||||
self.setGeometry(newgeometry)
|
||||
self.show()
|
||||
else:
|
||||
self.updateKeyboard()
|
||||
return True
|
||||
return False
|
||||
|
||||
def getRawKbds(self):
|
||||
return self._kbds
|
||||
|
||||
#
|
||||
# initKeyboards sets up a QStackedLayout holding QWidgets for each keyboard, which in turn have a
|
||||
# QStackedlayout that holds a QWidget for each view within that keyboard. That has a QGridLayout with
|
||||
# QHboxLayouts in it that hold the individual key QPushButton widgets. It also sets the captions and
|
||||
# button actions for each key and figures out how many standard key widths and row vis there are in
|
||||
# all the views, which is used by updateKeyboard() to dynamically figure out how big the fonts, margins
|
||||
# and rounded corners need to be.
|
||||
#
|
||||
|
||||
def initKeyboards(self):
|
||||
|
||||
# Helper to return placeholder "empty row" widget
|
||||
def _makeEmptyRow(row):
|
||||
er = QPushButton(self)
|
||||
er.pressed.connect(partial(self._buttonhandler, er, PRESSED))
|
||||
er.released.connect(partial(self._buttonhandler, er, RELEASED))
|
||||
er.setMinimumSize(1, 1)
|
||||
er.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
|
||||
er.setProperty("class", "emptyrow")
|
||||
row["_QWidget"] = er
|
||||
row["type"] = "emptyrow"
|
||||
er.data = row
|
||||
return er
|
||||
|
||||
# Helper to return a QLayout to go in place of the QPushButton that contains it plus
|
||||
# any extra labels stacked on top
|
||||
def _makeCaptionLayout(k):
|
||||
extracaptions = k.data.get("extracaptions", None)
|
||||
if not extracaptions:
|
||||
return False
|
||||
# ecl = extra captions layout
|
||||
ecl = QStackedLayout()
|
||||
ecl.setStackingMode(QStackedLayout.StackAll)
|
||||
ecl.addWidget(k)
|
||||
for cssclass, txt in extracaptions.items():
|
||||
ql = QLabel(txt)
|
||||
ql.setProperty("class", cssclass)
|
||||
ql.setAttribute(Qt.WA_TransparentForMouseEvents)
|
||||
ecl.addWidget(ql)
|
||||
return ecl
|
||||
|
||||
def _maxRowsInView(view):
|
||||
maxrows = 0
|
||||
for column in view.get("columns", []):
|
||||
maxrows = max(len(column.get("rows")), maxrows)
|
||||
return maxrows
|
||||
|
||||
# This stores the width and height in standard key widths for each view.
|
||||
def _storeWidthsAndHeights(view):
|
||||
total_height = 0
|
||||
# Heights are only stored in first column
|
||||
column = view["columns"][0]
|
||||
for ri, row in enumerate(column.get("rows", [])):
|
||||
total_height += row.get("height", 1)
|
||||
total_width = 0
|
||||
for ci, column in enumerate(view.get("columns", [])):
|
||||
largest_width = 0
|
||||
for ri, row in reversed(list(enumerate(column.get("rows", [])))):
|
||||
if len(row.get("keys", [])):
|
||||
totalweight = 0
|
||||
for keydata in row.get("keys", []):
|
||||
w = keydata.get("width", 1)
|
||||
totalweight += w
|
||||
# Not counting frst row if there are widths already (reversed order)
|
||||
if totalweight > largest_width and (ri != 0 or totalweight == 0):
|
||||
largest_width = totalweight
|
||||
column["_widthInUnits"] = largest_width
|
||||
total_width += largest_width
|
||||
view["_widthInUnits"] = max(total_width, 1)
|
||||
view["_heightInUnits"] = max(total_height, 1)
|
||||
|
||||
# Start of initKeyboards() itself
|
||||
|
||||
if self._kbdstack.itemAt(0):
|
||||
self._clearLayout(self._kbdstack)
|
||||
ki = 0
|
||||
for kbdname, kbd in self._kbds.items():
|
||||
viewstack = QStackedLayout()
|
||||
vi = 0
|
||||
for viewname, view in kbd.get("views", {}).items():
|
||||
_storeWidthsAndHeights(view)
|
||||
grid = QGridLayout()
|
||||
grid.setSpacing(0)
|
||||
grid.setContentsMargins(0, 0, 0, 0)
|
||||
for ci, column in enumerate(view.get("columns", [])):
|
||||
for ri in range(_maxRowsInView(view)):
|
||||
if ri < len(column["rows"]):
|
||||
row = column["rows"][ri]
|
||||
else:
|
||||
row = {"keys": []}
|
||||
column["rows"].append(row)
|
||||
keys = row.get("keys", [])
|
||||
kl = QHBoxLayout()
|
||||
kl.setContentsMargins(0, 0, 0, 0)
|
||||
kl.setSpacing(0)
|
||||
for keydata in keys:
|
||||
stretch = keydata.get("width", 1) * 10
|
||||
type = keydata.get("type", "key")
|
||||
k = QPushButton(self)
|
||||
k.setMinimumSize(1, 1)
|
||||
keydata["_QWidget"] = k
|
||||
keydata["_selected"] = False
|
||||
k.data = keydata
|
||||
k.pressed.connect(partial(self._buttonhandler, k, PRESSED))
|
||||
k.released.connect(partial(self._buttonhandler, k, RELEASED))
|
||||
k.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
|
||||
k.setMinimumSize(1, 1)
|
||||
if type == "key":
|
||||
k.setText(keydata.get("caption", ""))
|
||||
# Multiple captions? Create a QStackedWidget overlays them all
|
||||
ecl = _makeCaptionLayout(k)
|
||||
if ecl:
|
||||
kl.addLayout(ecl, stretch)
|
||||
else:
|
||||
kl.addWidget(k, int(stretch))
|
||||
else:
|
||||
kl.addWidget(k, int(stretch))
|
||||
if not len(keys):
|
||||
er = _makeEmptyRow(row)
|
||||
kl.addWidget(er)
|
||||
else:
|
||||
row["_QWidget"] = None
|
||||
grid.addLayout(kl, ri, ci * 2)
|
||||
if ci == 0:
|
||||
grid.setRowStretch(ri, int(row.get("height", 1) * 10))
|
||||
grid.setColumnStretch(ci * 2, int(column.get("_widthInUnits", 1) * 10))
|
||||
if ci > 0:
|
||||
spacercolumn = QHBoxLayout()
|
||||
spacercolumn.addWidget(QWidget(None))
|
||||
grid.setColumnStretch((ci * 2) - 1, int(COLUMN_MARGIN * 10))
|
||||
grid.addLayout(spacercolumn, 0, (ci * 2) - 1)
|
||||
# Create with self as parent, then reparent to prevent startup flicker
|
||||
view["_QWidget"] = QWidget(self)
|
||||
view["_QWidget"].setLayout(grid)
|
||||
viewstack.addWidget(view["_QWidget"])
|
||||
view["_stackindex"] = vi
|
||||
vi += 1
|
||||
kbd["_QWidget"] = QWidget(self)
|
||||
kbd["_stackindex"] = ki
|
||||
ki += 1
|
||||
kbd["_QWidget"].setLayout(viewstack)
|
||||
self._kbdstack.addWidget(kbd["_QWidget"])
|
||||
self.setKeyboard(self._kbdname)
|
||||
# Qt keeps coming up with minimum sizes that are way too wide
|
||||
# Some sane number will have to go in at some point, I guess
|
||||
self.setMaximumSize(16777215, 16777215)
|
||||
self.setMinimumSize(1, 1)
|
||||
|
||||
def updateKeyboard(self):
|
||||
|
||||
# Helper function to dynamically recalculate some sizes in stylesheets
|
||||
def fixStyle(stylesheet, fontsize, margin, radius):
|
||||
if stylesheet == "":
|
||||
return ""
|
||||
# Replace the main calculated values
|
||||
stylesheet = stylesheet.replace("_OSKB_FONTSIZE_", str(fontsize))
|
||||
stylesheet = stylesheet.replace("_OSKB_MARGIN_", str(margin))
|
||||
stylesheet = stylesheet.replace("_OSKB_RADIUS_", str(radius))
|
||||
# And then all the percentages based thereon (Qt5 doesn't do percentages in fontsizes)
|
||||
r = re.compile(r"font-size\s*:\s*(\d+)\%")
|
||||
i = r.finditer(stylesheet)
|
||||
for m in i:
|
||||
stylesheet = stylesheet.replace(
|
||||
m.group(0), "font-size: " + str(int((fontsize / 100) * int(m.group(1)))) + "px",
|
||||
)
|
||||
return stylesheet
|
||||
|
||||
if not self._view:
|
||||
return False
|
||||
# Calculate the font and margin sizes
|
||||
kw = self.width() / self._view["_widthInUnits"]
|
||||
kh = self.height() / self._view["_heightInUnits"]
|
||||
fontsize = min(max(int(min(kw / 1.5, kh / 2)), 5), 50)
|
||||
margin = int(fontsize / 15)
|
||||
radius = margin * 3
|
||||
# Dynamically change the default and keyboard stylesheets
|
||||
all_sheets = self._stylesheet + "\n\n" + self._kbd.get("style", "")
|
||||
super().setStyleSheet(fixStyle(all_sheets, fontsize, margin, radius))
|
||||
# Then adjust the stylesheets and class properties of all keys
|
||||
for ci, column in enumerate(self._view.get("columns", [])):
|
||||
for ri, row in enumerate(column.get("rows", [])):
|
||||
rowwidget = row.get("_QWidget")
|
||||
if rowwidget:
|
||||
if row.get("_selected", False):
|
||||
rowwidget.setProperty("class", "emptyrow selected")
|
||||
else:
|
||||
rowwidget.setProperty("class", "emptyrow")
|
||||
# It needs .setStyleSheet(""), not .repaint() to show the changes
|
||||
rowwidget.setStyleSheet("")
|
||||
else:
|
||||
for keydata in row.get("keys", []):
|
||||
k = keydata.get("_QWidget")
|
||||
type = keydata.get("type", "key")
|
||||
classes = [type]
|
||||
classes.append(keydata.get("class", ""))
|
||||
if keydata.get("single") and keydata["single"].get("modifier"):
|
||||
modname = keydata["single"]["modifier"].get("name", "")
|
||||
moddata = self._modifiers.get(modname, {})
|
||||
modstate = moddata.get("state")
|
||||
if modstate == 1:
|
||||
classes.append("held")
|
||||
elif modstate == 2:
|
||||
classes.append("locked")
|
||||
else:
|
||||
classes.append("modifier")
|
||||
if keydata.get("_selected", False):
|
||||
classes.append("selected")
|
||||
classes.append("view_" + self._viewname)
|
||||
classes.append("row" + str(ri + 1))
|
||||
classes.append("col" + str(ci + 1))
|
||||
k.setProperty("class", " ".join(classes).strip())
|
||||
keystyle = keydata.get("style", "")
|
||||
k.setStyleSheet(fixStyle(keystyle, fontsize, margin, radius))
|
||||
|
||||
|
||||
#
|
||||
# The part here is the low-level button handling. It takes care of calling _doAction() with PRESSED and
|
||||
# RELEASED with pointers to either the "single", "double" or "long" sub-dictionaries for that button,
|
||||
# handling all the nitty-gritty. Bit involved.., Maybe only touch when wide awake and concentrated.
|
||||
#
|
||||
|
||||
def _oskbButtonHandler(self, button, direction):
|
||||
sng = button.data.get("single")
|
||||
dbl = button.data.get("double")
|
||||
lng = button.data.get("long")
|
||||
if direction == PRESSED:
|
||||
if self._doublebutton and self._doublebutton != button:
|
||||
# Another key was pressed within the doubleclick timeout, so we must
|
||||
# first process the previous key that was held back
|
||||
self._doAction(self._doublebutton.data.get("single"), PRESSED)
|
||||
self._doAction(self._doublebutton.data.get("single"), RELEASED)
|
||||
self._doublebutton = None
|
||||
self._doubletimer.stop()
|
||||
self._stopsinglepress = False
|
||||
if lng or dbl:
|
||||
if lng:
|
||||
self._longtimer = QTimer()
|
||||
self._longtimer.setSingleShot(True)
|
||||
self._longtimer.timeout.connect(partial(self._longPress, lng))
|
||||
self._longtimer.start(LONGPRESS_TIMEOUT)
|
||||
if dbl:
|
||||
self._stopsinglepress = True
|
||||
if self._doubletimer.isActive():
|
||||
self._doubletimer.stop()
|
||||
self._doAction(dbl, PRESSED)
|
||||
self._doAction(dbl, RELEASED)
|
||||
self._doublebutton = None
|
||||
else:
|
||||
self._doublebutton = button
|
||||
self._doubletimer.start(DOUBLECLICK_TIMEOUT)
|
||||
else:
|
||||
self._doAction(sng, PRESSED)
|
||||
else:
|
||||
if not self._stopsinglepress:
|
||||
if self._longtimer.isActive():
|
||||
self._longtimer.stop()
|
||||
self._doAction(sng, PRESSED)
|
||||
self._doAction(sng, RELEASED)
|
||||
else:
|
||||
self._doAction(sng, RELEASED)
|
||||
self._stopsinglepress = False
|
||||
self._longtimer.stop()
|
||||
|
||||
def _longPress(self, lng):
|
||||
self._stopsinglepress = True
|
||||
self._doAction(lng, PRESSED)
|
||||
self._doAction(lng, RELEASED)
|
||||
|
||||
def _doubleTimeout(self):
|
||||
if not self._stopsinglepress:
|
||||
actiondict = self._doublebutton.data.get("single")
|
||||
self._doAction(actiondict, PRESSED)
|
||||
self._doAction(actiondict, RELEASED)
|
||||
self._doublebutton = None
|
||||
|
||||
#
|
||||
# Higher level button handling: parses the actions from the action dictionary
|
||||
#
|
||||
|
||||
def _doAction(self, actiondict, direction):
|
||||
if not actiondict:
|
||||
return
|
||||
for cmd, argdict in actiondict.items():
|
||||
if not argdict:
|
||||
continue
|
||||
|
||||
if cmd == "send":
|
||||
keycode = argdict.get("keycode", "")
|
||||
keycodeplus = keycode
|
||||
keyname = argdict.get("name", "")
|
||||
printable = argdict.get("printable", True)
|
||||
|
||||
for modname, mod in self._modifiers.items():
|
||||
if mod.get("state") > 0:
|
||||
keyname = modname + " " + keyname
|
||||
modkeycode = mod.get("keycode")
|
||||
keycodeplus = modkeycode + "+" + keycode
|
||||
if not mod.get("printable"):
|
||||
printable = False
|
||||
if direction == PRESSED and self._flashmodifiers:
|
||||
self._injectKeys(modkeycode, PRESSED)
|
||||
self._injectKeys(keycode, direction)
|
||||
if direction == RELEASED:
|
||||
self._releaseModifiers()
|
||||
if self._viewuntil and re.fullmatch(self._viewuntil, keyname):
|
||||
self.setView(self._thenview)
|
||||
self.viewuntil, self._thenview = None, None
|
||||
|
||||
if cmd == "view" and direction == RELEASED:
|
||||
viewname = argdict.get("name", "default")
|
||||
self._viewuntil = argdict.get("until")
|
||||
self._thenview = argdict.get("thenview")
|
||||
self.setView(viewname)
|
||||
addclass = "oneview" if self._viewuntil else "view"
|
||||
self.setProperty("class", self._view.get("class", "") + addclass)
|
||||
self.updateKeyboard()
|
||||
|
||||
if cmd == "modifier" and direction == RELEASED:
|
||||
keycode = argdict.get("keycode", "")
|
||||
modifier = argdict.get("name", "")
|
||||
printable = argdict.get("printable", True)
|
||||
modaction = argdict.get("action", "toggle")
|
||||
m = self._modifiers.get(modifier)
|
||||
if modaction == "toggle":
|
||||
if not m or m["state"] == 0:
|
||||
self._modifiers[modifier] = {
|
||||
"state": 1,
|
||||
"keycode": keycode,
|
||||
"printable": printable,
|
||||
}
|
||||
if not self._flashmodifiers:
|
||||
self._injectKeys(keycode, PRESSED)
|
||||
else:
|
||||
self._modifiers[modifier] = {
|
||||
"state": 0,
|
||||
"keycode": keycode,
|
||||
"printable": printable,
|
||||
}
|
||||
if not self._flashmodifiers:
|
||||
self._injectKeys(keycode, RELEASED)
|
||||
if modaction == "lock":
|
||||
if not m:
|
||||
self._modifiers[modifier] = {}
|
||||
s = self._modifiers[modifier].get("state", 0)
|
||||
self._modifiers[modifier] = {
|
||||
"state": 0 if s == 2 else 2,
|
||||
"keycode": keycode,
|
||||
"printable": printable,
|
||||
}
|
||||
if not self._flashmodifiers:
|
||||
self._injectKeys(keycode, PRESSED if s == 0 else RELEASED)
|
||||
self.updateKeyboard()
|
||||
|
||||
if cmd == "keyboard" and direction == RELEASED:
|
||||
kbdname = argdict.get("name", "")
|
||||
self.setKeyboard(kbdname)
|
||||
|
||||
# This is where the strings with keycodes to be pressed or released get turned into actual keypress
|
||||
# events. There's two levels here: "42+2;57" (in the US layout) means we're first pressing and then
|
||||
# releasing shift 2 (an exclamation point) and then a space.
|
||||
|
||||
def _injectKeys(self, keystr, direction):
|
||||
keylist = keystr.split(";")
|
||||
|
||||
# If PRESSED, press and release all the ;-separated keycodes, releasing all but the last
|
||||
if direction == PRESSED:
|
||||
for keycodes in keylist:
|
||||
keycodelist = keycodes.split("+")
|
||||
for keycode in keycodelist:
|
||||
self._sendKey(int(keycode), PRESSED)
|
||||
if keycodes != keylist[-1]:
|
||||
self._sendKey(int(keycode), RELEASED)
|
||||
|
||||
# If RELEASED, only need to release the last (set of) keys
|
||||
if direction == RELEASED:
|
||||
keycodelist = keylist[-1].split("+")
|
||||
for keycode in reversed(keycodelist):
|
||||
self._sendKey(int(keycode), RELEASED)
|
||||
|
||||
def _sendKey(self, keycode, keyevent):
|
||||
if self._sendkeys:
|
||||
self._sendkeys(keycode, keyevent)
|
||||
|
||||
def _releaseModifiers(self):
|
||||
if self._view:
|
||||
donestuff = False
|
||||
for modinfo in self._modifiers.values():
|
||||
if modinfo["state"] == 1:
|
||||
donestuff = True
|
||||
if not self._flashmodifiers:
|
||||
self._injectKeys(modinfo["keycode"], RELEASED)
|
||||
modinfo["state"] = 0
|
||||
if self._flashmodifiers:
|
||||
self._injectKeys(modinfo["keycode"], RELEASED)
|
||||
if donestuff:
|
||||
self.updateKeyboard()
|
||||
|
||||
# Helper
|
||||
|
||||
def _clearLayout(self, layout):
|
||||
if layout != None:
|
||||
while layout.count():
|
||||
child = layout.takeAt(0)
|
||||
if child.widget() is not None:
|
||||
child.widget().deleteLater()
|
||||
elif child.layout() is not None:
|
||||
self._clearLayout(child.layout())
|
||||
|
||||
|
||||
# oskbCopy() copies an oskb data structure (a dict with sub-dicts and sub-lists). If you specify two
|
||||
# variables it will move from one to the other without breaking the reference. If you specify just one,
|
||||
# it will return a new copy.
|
||||
|
||||
def oskbCopy(f, t=None):
|
||||
if t == None:
|
||||
t = {}
|
||||
t.clear()
|
||||
if type(f) == dict:
|
||||
for fk, fv in f.items():
|
||||
if fv != {} and fv != "" and not fk.startswith("_"):
|
||||
if type(fv) == list or type(fv) == dict:
|
||||
t[fk] = oskbCopy(fv)
|
||||
else:
|
||||
t[fk] = fv
|
||||
elif type(f) == list:
|
||||
t = []
|
||||
for fi, fv in enumerate(f):
|
||||
t.append(oskbCopy(fv))
|
||||
return t
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
48
src/lib/oskb/oskbedit.css
Normal file
48
src/lib/oskb/oskbedit.css
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
QWidget {
|
||||
background-color: #cccccc;
|
||||
margin:0px;
|
||||
}
|
||||
|
||||
QLabel {
|
||||
font-size: 50%;
|
||||
background: transparent;
|
||||
margin: 2px 5px;
|
||||
qproperty-alignment: 'AlignBottom | AlignLeft';
|
||||
}
|
||||
|
||||
.key {
|
||||
background-color: #eeeeee;
|
||||
border: 1px solid black;
|
||||
font-size: _OSKB_FONTSIZE_px;
|
||||
margin: _OSKB_MARGIN_px;
|
||||
border-radius: _OSKB_RADIUS_px;
|
||||
}
|
||||
|
||||
.spacer {
|
||||
background-color: #cccccc;
|
||||
border: 2px dotted white;
|
||||
margin: _OSKB_MARGIN_px 0px;
|
||||
border-radius: _OSKB_RADIUS_px;
|
||||
}
|
||||
|
||||
.emptyrow {
|
||||
background-color: #cccccc;
|
||||
border: 2px dotted #aaaaaa;
|
||||
margin: _OSKB_MARGIN_px 0px;
|
||||
border-radius: _OSKB_RADIUS_px;
|
||||
}
|
||||
|
||||
.key:pressed, .key.pseudomodifier, .key.held {
|
||||
background-color: #999999;
|
||||
}
|
||||
|
||||
.view .key.pseudomodifier, .key.locked {
|
||||
background-color: #cc9999;
|
||||
}
|
||||
|
||||
|
||||
/* Below are used by oskbedit */
|
||||
|
||||
.key.selected, .spacer.selected, .emptyrow.selected {
|
||||
background-color: #77bbff !important;
|
||||
}
|
||||
1025
src/lib/oskb/oskbedit.py
Normal file
1025
src/lib/oskb/oskbedit.py
Normal file
File diff suppressed because it is too large
Load Diff
410
src/lib/oskb/ui/EditKey.ui
Normal file
410
src/lib/oskb/ui/EditKey.ui
Normal file
|
|
@ -0,0 +1,410 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>EditKey</class>
|
||||
<widget class="QDialog" name="EditKey">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>632</width>
|
||||
<height>444</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>632</width>
|
||||
<height>444</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>632</width>
|
||||
<height>444</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Edit key properties</string>
|
||||
</property>
|
||||
<property name="modal">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<widget class="QDialogButtonBox" name="cancelsavebuttons">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>330</x>
|
||||
<y>400</y>
|
||||
<width>291</width>
|
||||
<height>41</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Save</set>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QTabWidget" name="maintabs">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>10</y>
|
||||
<width>611</width>
|
||||
<height>381</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>611</width>
|
||||
<height>381</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>611</width>
|
||||
<height>381</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="currentIndex">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="appearance">
|
||||
<attribute name="title">
|
||||
<string>Appearance</string>
|
||||
</attribute>
|
||||
<widget class="QLabel" name="lbl_4">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>300</x>
|
||||
<y>10</y>
|
||||
<width>151</width>
|
||||
<height>16</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Additional captions:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLineEdit" name="caption">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>110</x>
|
||||
<y>20</y>
|
||||
<width>101</width>
|
||||
<height>21</height>
|
||||
</rect>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLineEdit" name="cssclass">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>40</x>
|
||||
<y>130</y>
|
||||
<width>221</width>
|
||||
<height>19</height>
|
||||
</rect>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QTableWidget" name="extracaptions">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>300</x>
|
||||
<y>30</y>
|
||||
<width>261</width>
|
||||
<height>121</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>11</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="showGrid">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="rowCount">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="columnCount">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<attribute name="horizontalHeaderCascadingSectionResizes">
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
<attribute name="horizontalHeaderStretchLastSection">
|
||||
<bool>true</bool>
|
||||
</attribute>
|
||||
<attribute name="verticalHeaderVisible">
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
<attribute name="verticalHeaderStretchLastSection">
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>CSS class</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Caption</string>
|
||||
</property>
|
||||
</column>
|
||||
</widget>
|
||||
<widget class="QLabel" name="lbl_3">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>40</x>
|
||||
<y>90</y>
|
||||
<width>191</width>
|
||||
<height>41</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Additional CSS classes, separated by spaces:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="lbl_1">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>20</x>
|
||||
<y>20</y>
|
||||
<width>81</width>
|
||||
<height>16</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Caption:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QPlainTextEdit" name="style">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>20</x>
|
||||
<y>190</y>
|
||||
<width>541</width>
|
||||
<height>131</height>
|
||||
</rect>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="lbl_5">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>40</x>
|
||||
<y>170</y>
|
||||
<width>291</width>
|
||||
<height>16</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>CSS StyleSheet specific to this key:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="lbl_6">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>20</x>
|
||||
<y>320</y>
|
||||
<width>541</width>
|
||||
<height>16</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>(Better to add CSS class and put style info in the keyboard stylesheet)</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="lbl_2">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>20</x>
|
||||
<y>50</y>
|
||||
<width>81</width>
|
||||
<height>16</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Key width:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QDoubleSpinBox" name="width">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>110</x>
|
||||
<y>50</y>
|
||||
<width>81</width>
|
||||
<height>24</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="decimals">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<double>0.100000000000000</double>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>0.100000000000000</double>
|
||||
</property>
|
||||
<property name="value">
|
||||
<double>1.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="deletecaption">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>530</x>
|
||||
<y>150</y>
|
||||
<width>31</width>
|
||||
<height>21</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>-</string>
|
||||
</property>
|
||||
<property name="default">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="flat">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="addcaption">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>500</x>
|
||||
<y>150</y>
|
||||
<width>31</width>
|
||||
<height>21</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>+</string>
|
||||
</property>
|
||||
<property name="default">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="flat">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
<widget class="QWidget" name="action">
|
||||
<attribute name="title">
|
||||
<string>Action</string>
|
||||
</attribute>
|
||||
<widget class="QTabWidget" name="actiontabs">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>20</x>
|
||||
<y>20</y>
|
||||
<width>571</width>
|
||||
<height>321</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="currentIndex">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="single">
|
||||
<attribute name="title">
|
||||
<string>Single Tap</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
<widget class="QWidget" name="double">
|
||||
<attribute name="title">
|
||||
<string>Double Tap</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
<widget class="QWidget" name="long">
|
||||
<attribute name="title">
|
||||
<string>Press and hold</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
</widget>
|
||||
</widget>
|
||||
</widget>
|
||||
</widget>
|
||||
<tabstops>
|
||||
<tabstop>maintabs</tabstop>
|
||||
<tabstop>caption</tabstop>
|
||||
<tabstop>width</tabstop>
|
||||
<tabstop>cssclass</tabstop>
|
||||
<tabstop>extracaptions</tabstop>
|
||||
<tabstop>addcaption</tabstop>
|
||||
<tabstop>deletecaption</tabstop>
|
||||
<tabstop>style</tabstop>
|
||||
<tabstop>actiontabs</tabstop>
|
||||
</tabstops>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>cancelsavebuttons</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>EditKey</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>488</x>
|
||||
<y>404</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>157</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>cancelsavebuttons</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>EditKey</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>550</x>
|
||||
<y>410</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>286</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
||||
205
src/lib/oskb/ui/KbdProperties.ui
Normal file
205
src/lib/oskb/ui/KbdProperties.ui
Normal file
|
|
@ -0,0 +1,205 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>KbdProperties</class>
|
||||
<widget class="QDialog" name="KbdProperties">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>515</width>
|
||||
<height>401</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>515</width>
|
||||
<height>401</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>515</width>
|
||||
<height>401</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Keyboard Properties</string>
|
||||
</property>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>150</x>
|
||||
<y>360</y>
|
||||
<width>341</width>
|
||||
<height>32</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Save</set>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QTabWidget" name="maintabs">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>20</x>
|
||||
<y>80</y>
|
||||
<width>481</width>
|
||||
<height>271</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="currentIndex">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="tab">
|
||||
<attribute name="title">
|
||||
<string>default.css (readonly)</string>
|
||||
</attribute>
|
||||
<widget class="QTextEdit" name="defaultcss">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>10</y>
|
||||
<width>451</width>
|
||||
<height>221</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="acceptDrops">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="acceptRichText">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tab_2">
|
||||
<attribute name="title">
|
||||
<string>Keyboard Stylesheet</string>
|
||||
</attribute>
|
||||
<widget class="QTextEdit" name="keyboardcss">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>10</y>
|
||||
<width>451</width>
|
||||
<height>221</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="acceptDrops">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="acceptRichText">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
</widget>
|
||||
<widget class="QLineEdit" name="description">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>120</x>
|
||||
<y>10</y>
|
||||
<width>201</width>
|
||||
<height>21</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="maxLength">
|
||||
<number>30</number>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLineEdit" name="layout">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>120</x>
|
||||
<y>40</y>
|
||||
<width>113</width>
|
||||
<height>21</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="maxLength">
|
||||
<number>16</number>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>20</x>
|
||||
<y>10</y>
|
||||
<width>91</width>
|
||||
<height>21</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Description:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>20</x>
|
||||
<y>40</y>
|
||||
<width>91</width>
|
||||
<height>20</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Layout:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>KbdProperties</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>248</x>
|
||||
<y>254</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>157</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>KbdProperties</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>316</x>
|
||||
<y>260</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>286</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
||||
410
src/lib/oskb/ui/KeyActions.ui
Normal file
410
src/lib/oskb/ui/KeyActions.ui
Normal file
|
|
@ -0,0 +1,410 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>KeyActions</class>
|
||||
<widget class="QWidget" name="KeyActions">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>560</width>
|
||||
<height>290</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string/>
|
||||
</property>
|
||||
<widget class="QComboBox" name="view_thenview">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>180</x>
|
||||
<y>220</y>
|
||||
<width>131</width>
|
||||
<height>26</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>10</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="lbl_16">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>330</x>
|
||||
<y>210</y>
|
||||
<width>61</width>
|
||||
<height>20</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>name:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QCheckBox" name="send">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>30</x>
|
||||
<y>20</y>
|
||||
<width>151</width>
|
||||
<height>20</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Send keypress</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QCheckBox" name="send_printable">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>120</x>
|
||||
<y>110</y>
|
||||
<width>101</width>
|
||||
<height>20</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>printable</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLineEdit" name="view_until">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>230</x>
|
||||
<y>250</y>
|
||||
<width>71</width>
|
||||
<height>21</height>
|
||||
</rect>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QCheckBox" name="keyboard">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>310</x>
|
||||
<y>180</y>
|
||||
<width>211</width>
|
||||
<height>20</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Jump to other keyboard</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QComboBox" name="view_name">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>50</x>
|
||||
<y>190</y>
|
||||
<width>131</width>
|
||||
<height>26</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>10</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="lbl_12">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>30</x>
|
||||
<y>250</y>
|
||||
<width>191</width>
|
||||
<height>21</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>After keyname matches:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLineEdit" name="modifier_keycode">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>400</x>
|
||||
<y>50</y>
|
||||
<width>101</width>
|
||||
<height>21</height>
|
||||
</rect>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="lbl_13">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>310</x>
|
||||
<y>50</y>
|
||||
<width>81</width>
|
||||
<height>16</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>keycode:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="lbl_15">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>310</x>
|
||||
<y>110</y>
|
||||
<width>81</width>
|
||||
<height>16</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>action:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="lbl_10">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>30</x>
|
||||
<y>50</y>
|
||||
<width>81</width>
|
||||
<height>16</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>keycode:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLineEdit" name="send_keycode">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>120</x>
|
||||
<y>50</y>
|
||||
<width>101</width>
|
||||
<height>21</height>
|
||||
</rect>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QComboBox" name="modifier_action">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>400</x>
|
||||
<y>110</y>
|
||||
<width>91</width>
|
||||
<height>26</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>10</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>toggle</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>lock</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
<widget class="QCheckBox" name="modifier_printable">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>400</x>
|
||||
<y>140</y>
|
||||
<width>111</width>
|
||||
<height>20</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>printable</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QCheckBox" name="view">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>30</x>
|
||||
<y>160</y>
|
||||
<width>181</width>
|
||||
<height>20</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Jump to other view</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLineEdit" name="keyboard_name">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>400</x>
|
||||
<y>210</y>
|
||||
<width>101</width>
|
||||
<height>21</height>
|
||||
</rect>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLineEdit" name="send_name">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>120</x>
|
||||
<y>80</y>
|
||||
<width>101</width>
|
||||
<height>21</height>
|
||||
</rect>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QCheckBox" name="modifier">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>310</x>
|
||||
<y>20</y>
|
||||
<width>161</width>
|
||||
<height>20</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Be a modifier key</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QCheckBox" name="view_until_checkbox">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>50</x>
|
||||
<y>220</y>
|
||||
<width>131</width>
|
||||
<height>20</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Then jump to</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLineEdit" name="modifier_name">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>400</x>
|
||||
<y>80</y>
|
||||
<width>101</width>
|
||||
<height>21</height>
|
||||
</rect>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="lbl_14">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>310</x>
|
||||
<y>80</y>
|
||||
<width>81</width>
|
||||
<height>16</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>name:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="lbl_11">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>30</x>
|
||||
<y>80</y>
|
||||
<width>81</width>
|
||||
<height>16</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>name:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="send_wiz">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>220</x>
|
||||
<y>50</y>
|
||||
<width>41</width>
|
||||
<height>21</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>wiz</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="modifier_wiz">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>500</x>
|
||||
<y>50</y>
|
||||
<width>41</width>
|
||||
<height>21</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>wiz</string>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
<tabstops>
|
||||
<tabstop>send</tabstop>
|
||||
<tabstop>send_keycode</tabstop>
|
||||
<tabstop>send_wiz</tabstop>
|
||||
<tabstop>send_name</tabstop>
|
||||
<tabstop>send_printable</tabstop>
|
||||
<tabstop>view</tabstop>
|
||||
<tabstop>view_name</tabstop>
|
||||
<tabstop>view_until_checkbox</tabstop>
|
||||
<tabstop>view_thenview</tabstop>
|
||||
<tabstop>view_until</tabstop>
|
||||
<tabstop>modifier</tabstop>
|
||||
<tabstop>modifier_keycode</tabstop>
|
||||
<tabstop>modifier_wiz</tabstop>
|
||||
<tabstop>modifier_name</tabstop>
|
||||
<tabstop>modifier_action</tabstop>
|
||||
<tabstop>modifier_printable</tabstop>
|
||||
<tabstop>keyboard</tabstop>
|
||||
<tabstop>keyboard_name</tabstop>
|
||||
</tabstops>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
69
src/lib/oskb/ui/KeyWizard.ui
Normal file
69
src/lib/oskb/ui/KeyWizard.ui
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>KeyWizard</class>
|
||||
<widget class="QDialog" name="KeyWizard">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>400</width>
|
||||
<height>189</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Key Wizard</string>
|
||||
</property>
|
||||
<property name="modal">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>30</x>
|
||||
<y>20</y>
|
||||
<width>341</width>
|
||||
<height>141</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>This is the Key Wizard. Simply press the key you would like to assign, and the key caption and keycodes will be set automatically. If you want to add functions for long presses or doubleclicks, or if you would like to add more captions, you can always edit the key manually later by doubleclicking it.</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignJustify|Qt::AlignTop</set>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLineEdit" name="lineEdit">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>350</x>
|
||||
<y>160</y>
|
||||
<width>41</width>
|
||||
<height>21</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="cursor">
|
||||
<cursorShape>BlankCursor</cursorShape>
|
||||
</property>
|
||||
<property name="autoFillBackground">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">background-color: transparent; border:none</string>
|
||||
</property>
|
||||
<property name="clearButtonEnabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
5
src/lib/oskb/ui/README.md
Normal file
5
src/lib/oskb/ui/README.md
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
# User Interface design files
|
||||
|
||||
These files hold the types and positions of all the elements in the various dialog windows. These files are edited with a program called "Qt Designer" which is normally part of a much bigger package called QT Creator, which is a complete development environment and several gigabytes in size. You can also download it standalone [here](https://build-system.fman.io/qt-designer-download).
|
||||
|
||||
Once you have edited a file, you can compile it to its corresponding file starting with `ui_` in the directory above this one by entering (for example) `pyuic5 EditKey.ui > ../ui_editkey.py`. (`pyuic5` comes with PyQt5 that was installed when you installed oskb.) Do not edit these `ui_something.py` files manually, as they will be overwritten next time someone compiles `SomeThing.ui`.
|
||||
124
src/lib/oskb/ui/ValueEdit.ui
Normal file
124
src/lib/oskb/ui/ValueEdit.ui
Normal file
|
|
@ -0,0 +1,124 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>ValueEdit</class>
|
||||
<widget class="QDialog" name="ValueEdit">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>247</width>
|
||||
<height>103</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>247</width>
|
||||
<height>103</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>247</width>
|
||||
<height>103</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Enter Value</string>
|
||||
</property>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>60</x>
|
||||
<y>60</y>
|
||||
<width>171</width>
|
||||
<height>32</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Save</set>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QDoubleSpinBox" name="doubleSpinBox">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>130</x>
|
||||
<y>20</y>
|
||||
<width>81</width>
|
||||
<height>24</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="decimals">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<double>0.100000000000000</double>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>0.100000000000000</double>
|
||||
</property>
|
||||
<property name="value">
|
||||
<double>0.500000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>20</y>
|
||||
<width>111</width>
|
||||
<height>21</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Width:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>ValueEdit</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>248</x>
|
||||
<y>254</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>157</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>ValueEdit</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>316</x>
|
||||
<y>260</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>286</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
||||
165
src/lib/oskb/ui_editkey.py
Normal file
165
src/lib/oskb/ui_editkey.py
Normal file
|
|
@ -0,0 +1,165 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Form implementation generated from reading ui file 'EditKey.ui'
|
||||
#
|
||||
# Created by: PyQt5 UI code generator 5.14.0
|
||||
#
|
||||
# WARNING! All changes made in this file will be lost!
|
||||
|
||||
|
||||
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||
|
||||
|
||||
class Ui_EditKey(object):
|
||||
def setupUi(self, EditKey):
|
||||
EditKey.setObjectName("EditKey")
|
||||
EditKey.resize(632, 444)
|
||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(EditKey.sizePolicy().hasHeightForWidth())
|
||||
EditKey.setSizePolicy(sizePolicy)
|
||||
EditKey.setMinimumSize(QtCore.QSize(632, 444))
|
||||
EditKey.setMaximumSize(QtCore.QSize(632, 444))
|
||||
EditKey.setModal(True)
|
||||
self.cancelsavebuttons = QtWidgets.QDialogButtonBox(EditKey)
|
||||
self.cancelsavebuttons.setGeometry(QtCore.QRect(330, 400, 291, 41))
|
||||
self.cancelsavebuttons.setOrientation(QtCore.Qt.Horizontal)
|
||||
self.cancelsavebuttons.setStandardButtons(QtWidgets.QDialogButtonBox.Cancel|QtWidgets.QDialogButtonBox.Save)
|
||||
self.cancelsavebuttons.setObjectName("cancelsavebuttons")
|
||||
self.maintabs = QtWidgets.QTabWidget(EditKey)
|
||||
self.maintabs.setGeometry(QtCore.QRect(10, 10, 611, 381))
|
||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.maintabs.sizePolicy().hasHeightForWidth())
|
||||
self.maintabs.setSizePolicy(sizePolicy)
|
||||
self.maintabs.setMinimumSize(QtCore.QSize(611, 381))
|
||||
self.maintabs.setMaximumSize(QtCore.QSize(611, 381))
|
||||
self.maintabs.setObjectName("maintabs")
|
||||
self.appearance = QtWidgets.QWidget()
|
||||
self.appearance.setObjectName("appearance")
|
||||
self.lbl_4 = QtWidgets.QLabel(self.appearance)
|
||||
self.lbl_4.setGeometry(QtCore.QRect(300, 10, 151, 16))
|
||||
self.lbl_4.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter)
|
||||
self.lbl_4.setObjectName("lbl_4")
|
||||
self.caption = QtWidgets.QLineEdit(self.appearance)
|
||||
self.caption.setGeometry(QtCore.QRect(110, 20, 101, 21))
|
||||
self.caption.setObjectName("caption")
|
||||
self.cssclass = QtWidgets.QLineEdit(self.appearance)
|
||||
self.cssclass.setGeometry(QtCore.QRect(40, 130, 221, 19))
|
||||
self.cssclass.setObjectName("cssclass")
|
||||
self.extracaptions = QtWidgets.QTableWidget(self.appearance)
|
||||
self.extracaptions.setGeometry(QtCore.QRect(300, 30, 261, 121))
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(11)
|
||||
self.extracaptions.setFont(font)
|
||||
self.extracaptions.setShowGrid(True)
|
||||
self.extracaptions.setRowCount(0)
|
||||
self.extracaptions.setColumnCount(2)
|
||||
self.extracaptions.setObjectName("extracaptions")
|
||||
item = QtWidgets.QTableWidgetItem()
|
||||
self.extracaptions.setHorizontalHeaderItem(0, item)
|
||||
item = QtWidgets.QTableWidgetItem()
|
||||
self.extracaptions.setHorizontalHeaderItem(1, item)
|
||||
self.extracaptions.horizontalHeader().setCascadingSectionResizes(False)
|
||||
self.extracaptions.horizontalHeader().setStretchLastSection(True)
|
||||
self.extracaptions.verticalHeader().setVisible(False)
|
||||
self.extracaptions.verticalHeader().setStretchLastSection(False)
|
||||
self.lbl_3 = QtWidgets.QLabel(self.appearance)
|
||||
self.lbl_3.setGeometry(QtCore.QRect(40, 90, 191, 41))
|
||||
self.lbl_3.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter)
|
||||
self.lbl_3.setWordWrap(True)
|
||||
self.lbl_3.setObjectName("lbl_3")
|
||||
self.lbl_1 = QtWidgets.QLabel(self.appearance)
|
||||
self.lbl_1.setGeometry(QtCore.QRect(20, 20, 81, 16))
|
||||
self.lbl_1.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
|
||||
self.lbl_1.setObjectName("lbl_1")
|
||||
self.style = QtWidgets.QPlainTextEdit(self.appearance)
|
||||
self.style.setGeometry(QtCore.QRect(20, 190, 541, 131))
|
||||
self.style.setObjectName("style")
|
||||
self.lbl_5 = QtWidgets.QLabel(self.appearance)
|
||||
self.lbl_5.setGeometry(QtCore.QRect(40, 170, 291, 16))
|
||||
self.lbl_5.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter)
|
||||
self.lbl_5.setObjectName("lbl_5")
|
||||
self.lbl_6 = QtWidgets.QLabel(self.appearance)
|
||||
self.lbl_6.setGeometry(QtCore.QRect(20, 320, 541, 16))
|
||||
self.lbl_6.setAlignment(QtCore.Qt.AlignCenter)
|
||||
self.lbl_6.setObjectName("lbl_6")
|
||||
self.lbl_2 = QtWidgets.QLabel(self.appearance)
|
||||
self.lbl_2.setGeometry(QtCore.QRect(20, 50, 81, 16))
|
||||
self.lbl_2.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
|
||||
self.lbl_2.setObjectName("lbl_2")
|
||||
self.width = QtWidgets.QDoubleSpinBox(self.appearance)
|
||||
self.width.setGeometry(QtCore.QRect(110, 50, 81, 24))
|
||||
self.width.setDecimals(1)
|
||||
self.width.setMinimum(0.1)
|
||||
self.width.setSingleStep(0.1)
|
||||
self.width.setProperty("value", 1.0)
|
||||
self.width.setObjectName("width")
|
||||
self.deletecaption = QtWidgets.QPushButton(self.appearance)
|
||||
self.deletecaption.setGeometry(QtCore.QRect(530, 150, 31, 21))
|
||||
font = QtGui.QFont()
|
||||
font.setBold(True)
|
||||
font.setWeight(75)
|
||||
self.deletecaption.setFont(font)
|
||||
self.deletecaption.setDefault(False)
|
||||
self.deletecaption.setFlat(False)
|
||||
self.deletecaption.setObjectName("deletecaption")
|
||||
self.addcaption = QtWidgets.QPushButton(self.appearance)
|
||||
self.addcaption.setGeometry(QtCore.QRect(500, 150, 31, 21))
|
||||
self.addcaption.setDefault(False)
|
||||
self.addcaption.setFlat(False)
|
||||
self.addcaption.setObjectName("addcaption")
|
||||
self.maintabs.addTab(self.appearance, "")
|
||||
self.action = QtWidgets.QWidget()
|
||||
self.action.setObjectName("action")
|
||||
self.actiontabs = QtWidgets.QTabWidget(self.action)
|
||||
self.actiontabs.setGeometry(QtCore.QRect(20, 20, 571, 321))
|
||||
self.actiontabs.setObjectName("actiontabs")
|
||||
self.single = QtWidgets.QWidget()
|
||||
self.single.setObjectName("single")
|
||||
self.actiontabs.addTab(self.single, "")
|
||||
self.double = QtWidgets.QWidget()
|
||||
self.double.setObjectName("double")
|
||||
self.actiontabs.addTab(self.double, "")
|
||||
self.long = QtWidgets.QWidget()
|
||||
self.long.setObjectName("long")
|
||||
self.actiontabs.addTab(self.long, "")
|
||||
self.maintabs.addTab(self.action, "")
|
||||
|
||||
self.retranslateUi(EditKey)
|
||||
self.maintabs.setCurrentIndex(0)
|
||||
self.actiontabs.setCurrentIndex(0)
|
||||
self.cancelsavebuttons.accepted.connect(EditKey.accept)
|
||||
self.cancelsavebuttons.rejected.connect(EditKey.reject)
|
||||
QtCore.QMetaObject.connectSlotsByName(EditKey)
|
||||
EditKey.setTabOrder(self.maintabs, self.caption)
|
||||
EditKey.setTabOrder(self.caption, self.width)
|
||||
EditKey.setTabOrder(self.width, self.cssclass)
|
||||
EditKey.setTabOrder(self.cssclass, self.extracaptions)
|
||||
EditKey.setTabOrder(self.extracaptions, self.addcaption)
|
||||
EditKey.setTabOrder(self.addcaption, self.deletecaption)
|
||||
EditKey.setTabOrder(self.deletecaption, self.style)
|
||||
EditKey.setTabOrder(self.style, self.actiontabs)
|
||||
|
||||
def retranslateUi(self, EditKey):
|
||||
_translate = QtCore.QCoreApplication.translate
|
||||
EditKey.setWindowTitle(_translate("EditKey", "Edit key properties"))
|
||||
self.lbl_4.setText(_translate("EditKey", "Additional captions:"))
|
||||
item = self.extracaptions.horizontalHeaderItem(0)
|
||||
item.setText(_translate("EditKey", "CSS class"))
|
||||
item = self.extracaptions.horizontalHeaderItem(1)
|
||||
item.setText(_translate("EditKey", "Caption"))
|
||||
self.lbl_3.setText(_translate("EditKey", "Additional CSS classes, separated by spaces:"))
|
||||
self.lbl_1.setText(_translate("EditKey", "Caption:"))
|
||||
self.lbl_5.setText(_translate("EditKey", "CSS StyleSheet specific to this key:"))
|
||||
self.lbl_6.setText(_translate("EditKey", "(Better to add CSS class and put style info in the keyboard stylesheet)"))
|
||||
self.lbl_2.setText(_translate("EditKey", "Key width:"))
|
||||
self.deletecaption.setText(_translate("EditKey", "-"))
|
||||
self.addcaption.setText(_translate("EditKey", "+"))
|
||||
self.maintabs.setTabText(self.maintabs.indexOf(self.appearance), _translate("EditKey", "Appearance"))
|
||||
self.actiontabs.setTabText(self.actiontabs.indexOf(self.single), _translate("EditKey", "Single Tap"))
|
||||
self.actiontabs.setTabText(self.actiontabs.indexOf(self.double), _translate("EditKey", "Double Tap"))
|
||||
self.actiontabs.setTabText(self.actiontabs.indexOf(self.long), _translate("EditKey", "Press and hold"))
|
||||
self.maintabs.setTabText(self.maintabs.indexOf(self.action), _translate("EditKey", "Action"))
|
||||
79
src/lib/oskb/ui_kbdproperties.py
Normal file
79
src/lib/oskb/ui_kbdproperties.py
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Form implementation generated from reading ui file 'KbdProperties.ui'
|
||||
#
|
||||
# Created by: PyQt5 UI code generator 5.14.0
|
||||
#
|
||||
# WARNING! All changes made in this file will be lost!
|
||||
|
||||
|
||||
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||
|
||||
|
||||
class Ui_KbdProperties(object):
|
||||
def setupUi(self, KbdProperties):
|
||||
KbdProperties.setObjectName("KbdProperties")
|
||||
KbdProperties.resize(515, 401)
|
||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(KbdProperties.sizePolicy().hasHeightForWidth())
|
||||
KbdProperties.setSizePolicy(sizePolicy)
|
||||
KbdProperties.setMinimumSize(QtCore.QSize(515, 401))
|
||||
KbdProperties.setMaximumSize(QtCore.QSize(515, 401))
|
||||
self.buttonBox = QtWidgets.QDialogButtonBox(KbdProperties)
|
||||
self.buttonBox.setGeometry(QtCore.QRect(150, 360, 341, 32))
|
||||
self.buttonBox.setOrientation(QtCore.Qt.Horizontal)
|
||||
self.buttonBox.setStandardButtons(QtWidgets.QDialogButtonBox.Cancel|QtWidgets.QDialogButtonBox.Save)
|
||||
self.buttonBox.setObjectName("buttonBox")
|
||||
self.maintabs = QtWidgets.QTabWidget(KbdProperties)
|
||||
self.maintabs.setGeometry(QtCore.QRect(20, 80, 481, 271))
|
||||
self.maintabs.setObjectName("maintabs")
|
||||
self.tab = QtWidgets.QWidget()
|
||||
self.tab.setObjectName("tab")
|
||||
self.defaultcss = QtWidgets.QTextEdit(self.tab)
|
||||
self.defaultcss.setGeometry(QtCore.QRect(10, 10, 451, 221))
|
||||
self.defaultcss.setAcceptDrops(False)
|
||||
self.defaultcss.setReadOnly(True)
|
||||
self.defaultcss.setAcceptRichText(False)
|
||||
self.defaultcss.setObjectName("defaultcss")
|
||||
self.maintabs.addTab(self.tab, "")
|
||||
self.tab_2 = QtWidgets.QWidget()
|
||||
self.tab_2.setObjectName("tab_2")
|
||||
self.keyboardcss = QtWidgets.QTextEdit(self.tab_2)
|
||||
self.keyboardcss.setGeometry(QtCore.QRect(10, 10, 451, 221))
|
||||
self.keyboardcss.setAcceptDrops(False)
|
||||
self.keyboardcss.setReadOnly(False)
|
||||
self.keyboardcss.setAcceptRichText(False)
|
||||
self.keyboardcss.setObjectName("keyboardcss")
|
||||
self.maintabs.addTab(self.tab_2, "")
|
||||
self.description = QtWidgets.QLineEdit(KbdProperties)
|
||||
self.description.setGeometry(QtCore.QRect(120, 10, 201, 21))
|
||||
self.description.setMaxLength(30)
|
||||
self.description.setObjectName("description")
|
||||
self.layout = QtWidgets.QLineEdit(KbdProperties)
|
||||
self.layout.setGeometry(QtCore.QRect(120, 40, 113, 21))
|
||||
self.layout.setMaxLength(16)
|
||||
self.layout.setObjectName("layout")
|
||||
self.label = QtWidgets.QLabel(KbdProperties)
|
||||
self.label.setGeometry(QtCore.QRect(20, 10, 91, 21))
|
||||
self.label.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
|
||||
self.label.setObjectName("label")
|
||||
self.label_2 = QtWidgets.QLabel(KbdProperties)
|
||||
self.label_2.setGeometry(QtCore.QRect(20, 40, 91, 20))
|
||||
self.label_2.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
|
||||
self.label_2.setObjectName("label_2")
|
||||
|
||||
self.retranslateUi(KbdProperties)
|
||||
self.maintabs.setCurrentIndex(1)
|
||||
self.buttonBox.accepted.connect(KbdProperties.accept)
|
||||
self.buttonBox.rejected.connect(KbdProperties.reject)
|
||||
QtCore.QMetaObject.connectSlotsByName(KbdProperties)
|
||||
|
||||
def retranslateUi(self, KbdProperties):
|
||||
_translate = QtCore.QCoreApplication.translate
|
||||
KbdProperties.setWindowTitle(_translate("KbdProperties", "Keyboard Properties"))
|
||||
self.maintabs.setTabText(self.maintabs.indexOf(self.tab), _translate("KbdProperties", "default.css (readonly)"))
|
||||
self.maintabs.setTabText(self.maintabs.indexOf(self.tab_2), _translate("KbdProperties", "Keyboard Stylesheet"))
|
||||
self.label.setText(_translate("KbdProperties", "Description:"))
|
||||
self.label_2.setText(_translate("KbdProperties", "Layout:"))
|
||||
168
src/lib/oskb/ui_keyactions.py
Normal file
168
src/lib/oskb/ui_keyactions.py
Normal file
|
|
@ -0,0 +1,168 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Form implementation generated from reading ui file 'KeyActions.ui'
|
||||
#
|
||||
# Created by: PyQt5 UI code generator 5.14.0
|
||||
#
|
||||
# WARNING! All changes made in this file will be lost!
|
||||
|
||||
|
||||
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||
|
||||
|
||||
class Ui_KeyActions(object):
|
||||
def setupUi(self, KeyActions):
|
||||
KeyActions.setObjectName("KeyActions")
|
||||
KeyActions.resize(560, 290)
|
||||
KeyActions.setWindowTitle("")
|
||||
self.view_thenview = QtWidgets.QComboBox(KeyActions)
|
||||
self.view_thenview.setGeometry(QtCore.QRect(180, 220, 131, 26))
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(10)
|
||||
self.view_thenview.setFont(font)
|
||||
self.view_thenview.setObjectName("view_thenview")
|
||||
self.lbl_16 = QtWidgets.QLabel(KeyActions)
|
||||
self.lbl_16.setGeometry(QtCore.QRect(330, 210, 61, 20))
|
||||
self.lbl_16.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
|
||||
self.lbl_16.setObjectName("lbl_16")
|
||||
self.send = QtWidgets.QCheckBox(KeyActions)
|
||||
self.send.setGeometry(QtCore.QRect(30, 20, 151, 20))
|
||||
font = QtGui.QFont()
|
||||
font.setBold(True)
|
||||
font.setWeight(75)
|
||||
self.send.setFont(font)
|
||||
self.send.setObjectName("send")
|
||||
self.send_printable = QtWidgets.QCheckBox(KeyActions)
|
||||
self.send_printable.setGeometry(QtCore.QRect(120, 110, 101, 20))
|
||||
self.send_printable.setObjectName("send_printable")
|
||||
self.view_until = QtWidgets.QLineEdit(KeyActions)
|
||||
self.view_until.setGeometry(QtCore.QRect(230, 250, 71, 21))
|
||||
self.view_until.setObjectName("view_until")
|
||||
self.keyboard = QtWidgets.QCheckBox(KeyActions)
|
||||
self.keyboard.setGeometry(QtCore.QRect(310, 180, 211, 20))
|
||||
font = QtGui.QFont()
|
||||
font.setBold(True)
|
||||
font.setWeight(75)
|
||||
self.keyboard.setFont(font)
|
||||
self.keyboard.setObjectName("keyboard")
|
||||
self.view_name = QtWidgets.QComboBox(KeyActions)
|
||||
self.view_name.setGeometry(QtCore.QRect(50, 190, 131, 26))
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(10)
|
||||
self.view_name.setFont(font)
|
||||
self.view_name.setObjectName("view_name")
|
||||
self.lbl_12 = QtWidgets.QLabel(KeyActions)
|
||||
self.lbl_12.setGeometry(QtCore.QRect(30, 250, 191, 21))
|
||||
self.lbl_12.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
|
||||
self.lbl_12.setWordWrap(True)
|
||||
self.lbl_12.setObjectName("lbl_12")
|
||||
self.modifier_keycode = QtWidgets.QLineEdit(KeyActions)
|
||||
self.modifier_keycode.setGeometry(QtCore.QRect(400, 50, 101, 21))
|
||||
self.modifier_keycode.setObjectName("modifier_keycode")
|
||||
self.lbl_13 = QtWidgets.QLabel(KeyActions)
|
||||
self.lbl_13.setGeometry(QtCore.QRect(310, 50, 81, 16))
|
||||
self.lbl_13.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
|
||||
self.lbl_13.setObjectName("lbl_13")
|
||||
self.lbl_15 = QtWidgets.QLabel(KeyActions)
|
||||
self.lbl_15.setGeometry(QtCore.QRect(310, 110, 81, 16))
|
||||
self.lbl_15.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
|
||||
self.lbl_15.setObjectName("lbl_15")
|
||||
self.lbl_10 = QtWidgets.QLabel(KeyActions)
|
||||
self.lbl_10.setGeometry(QtCore.QRect(30, 50, 81, 16))
|
||||
self.lbl_10.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
|
||||
self.lbl_10.setObjectName("lbl_10")
|
||||
self.send_keycode = QtWidgets.QLineEdit(KeyActions)
|
||||
self.send_keycode.setGeometry(QtCore.QRect(120, 50, 101, 21))
|
||||
self.send_keycode.setObjectName("send_keycode")
|
||||
self.modifier_action = QtWidgets.QComboBox(KeyActions)
|
||||
self.modifier_action.setGeometry(QtCore.QRect(400, 110, 91, 26))
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(10)
|
||||
self.modifier_action.setFont(font)
|
||||
self.modifier_action.setObjectName("modifier_action")
|
||||
self.modifier_action.addItem("")
|
||||
self.modifier_action.addItem("")
|
||||
self.modifier_printable = QtWidgets.QCheckBox(KeyActions)
|
||||
self.modifier_printable.setGeometry(QtCore.QRect(400, 140, 111, 20))
|
||||
self.modifier_printable.setObjectName("modifier_printable")
|
||||
self.view = QtWidgets.QCheckBox(KeyActions)
|
||||
self.view.setGeometry(QtCore.QRect(30, 160, 181, 20))
|
||||
font = QtGui.QFont()
|
||||
font.setBold(True)
|
||||
font.setWeight(75)
|
||||
self.view.setFont(font)
|
||||
self.view.setObjectName("view")
|
||||
self.keyboard_name = QtWidgets.QLineEdit(KeyActions)
|
||||
self.keyboard_name.setGeometry(QtCore.QRect(400, 210, 101, 21))
|
||||
self.keyboard_name.setObjectName("keyboard_name")
|
||||
self.send_name = QtWidgets.QLineEdit(KeyActions)
|
||||
self.send_name.setGeometry(QtCore.QRect(120, 80, 101, 21))
|
||||
self.send_name.setObjectName("send_name")
|
||||
self.modifier = QtWidgets.QCheckBox(KeyActions)
|
||||
self.modifier.setGeometry(QtCore.QRect(310, 20, 161, 20))
|
||||
font = QtGui.QFont()
|
||||
font.setBold(True)
|
||||
font.setWeight(75)
|
||||
self.modifier.setFont(font)
|
||||
self.modifier.setObjectName("modifier")
|
||||
self.view_until_checkbox = QtWidgets.QCheckBox(KeyActions)
|
||||
self.view_until_checkbox.setGeometry(QtCore.QRect(50, 220, 131, 20))
|
||||
self.view_until_checkbox.setObjectName("view_until_checkbox")
|
||||
self.modifier_name = QtWidgets.QLineEdit(KeyActions)
|
||||
self.modifier_name.setGeometry(QtCore.QRect(400, 80, 101, 21))
|
||||
self.modifier_name.setObjectName("modifier_name")
|
||||
self.lbl_14 = QtWidgets.QLabel(KeyActions)
|
||||
self.lbl_14.setGeometry(QtCore.QRect(310, 80, 81, 16))
|
||||
self.lbl_14.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
|
||||
self.lbl_14.setObjectName("lbl_14")
|
||||
self.lbl_11 = QtWidgets.QLabel(KeyActions)
|
||||
self.lbl_11.setGeometry(QtCore.QRect(30, 80, 81, 16))
|
||||
self.lbl_11.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
|
||||
self.lbl_11.setObjectName("lbl_11")
|
||||
self.send_wiz = QtWidgets.QPushButton(KeyActions)
|
||||
self.send_wiz.setGeometry(QtCore.QRect(220, 50, 41, 21))
|
||||
self.send_wiz.setObjectName("send_wiz")
|
||||
self.modifier_wiz = QtWidgets.QPushButton(KeyActions)
|
||||
self.modifier_wiz.setGeometry(QtCore.QRect(500, 50, 41, 21))
|
||||
self.modifier_wiz.setObjectName("modifier_wiz")
|
||||
|
||||
self.retranslateUi(KeyActions)
|
||||
QtCore.QMetaObject.connectSlotsByName(KeyActions)
|
||||
KeyActions.setTabOrder(self.send, self.send_keycode)
|
||||
KeyActions.setTabOrder(self.send_keycode, self.send_wiz)
|
||||
KeyActions.setTabOrder(self.send_wiz, self.send_name)
|
||||
KeyActions.setTabOrder(self.send_name, self.send_printable)
|
||||
KeyActions.setTabOrder(self.send_printable, self.view)
|
||||
KeyActions.setTabOrder(self.view, self.view_name)
|
||||
KeyActions.setTabOrder(self.view_name, self.view_until_checkbox)
|
||||
KeyActions.setTabOrder(self.view_until_checkbox, self.view_thenview)
|
||||
KeyActions.setTabOrder(self.view_thenview, self.view_until)
|
||||
KeyActions.setTabOrder(self.view_until, self.modifier)
|
||||
KeyActions.setTabOrder(self.modifier, self.modifier_keycode)
|
||||
KeyActions.setTabOrder(self.modifier_keycode, self.modifier_wiz)
|
||||
KeyActions.setTabOrder(self.modifier_wiz, self.modifier_name)
|
||||
KeyActions.setTabOrder(self.modifier_name, self.modifier_action)
|
||||
KeyActions.setTabOrder(self.modifier_action, self.modifier_printable)
|
||||
KeyActions.setTabOrder(self.modifier_printable, self.keyboard)
|
||||
KeyActions.setTabOrder(self.keyboard, self.keyboard_name)
|
||||
|
||||
def retranslateUi(self, KeyActions):
|
||||
_translate = QtCore.QCoreApplication.translate
|
||||
self.lbl_16.setText(_translate("KeyActions", "name:"))
|
||||
self.send.setText(_translate("KeyActions", "Send keypress"))
|
||||
self.send_printable.setText(_translate("KeyActions", "printable"))
|
||||
self.keyboard.setText(_translate("KeyActions", "Jump to other keyboard"))
|
||||
self.lbl_12.setText(_translate("KeyActions", "After keyname matches:"))
|
||||
self.lbl_13.setText(_translate("KeyActions", "keycode:"))
|
||||
self.lbl_15.setText(_translate("KeyActions", "action:"))
|
||||
self.lbl_10.setText(_translate("KeyActions", "keycode:"))
|
||||
self.modifier_action.setItemText(0, _translate("KeyActions", "toggle"))
|
||||
self.modifier_action.setItemText(1, _translate("KeyActions", "lock"))
|
||||
self.modifier_printable.setText(_translate("KeyActions", "printable"))
|
||||
self.view.setText(_translate("KeyActions", "Jump to other view"))
|
||||
self.modifier.setText(_translate("KeyActions", "Be a modifier key"))
|
||||
self.view_until_checkbox.setText(_translate("KeyActions", "Then jump to"))
|
||||
self.lbl_14.setText(_translate("KeyActions", "name:"))
|
||||
self.lbl_11.setText(_translate("KeyActions", "name:"))
|
||||
self.send_wiz.setText(_translate("KeyActions", "wiz"))
|
||||
self.modifier_wiz.setText(_translate("KeyActions", "wiz"))
|
||||
42
src/lib/oskb/ui_keywizard.py
Normal file
42
src/lib/oskb/ui_keywizard.py
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Form implementation generated from reading ui file 'KeyWizard.ui'
|
||||
#
|
||||
# Created by: PyQt5 UI code generator 5.14.0
|
||||
#
|
||||
# WARNING! All changes made in this file will be lost!
|
||||
|
||||
|
||||
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||
|
||||
|
||||
class Ui_KeyWizard(object):
|
||||
def setupUi(self, KeyWizard):
|
||||
KeyWizard.setObjectName("KeyWizard")
|
||||
KeyWizard.resize(400, 189)
|
||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(KeyWizard.sizePolicy().hasHeightForWidth())
|
||||
KeyWizard.setSizePolicy(sizePolicy)
|
||||
KeyWizard.setModal(True)
|
||||
self.label = QtWidgets.QLabel(KeyWizard)
|
||||
self.label.setGeometry(QtCore.QRect(30, 20, 341, 141))
|
||||
self.label.setAlignment(QtCore.Qt.AlignJustify|QtCore.Qt.AlignTop)
|
||||
self.label.setWordWrap(True)
|
||||
self.label.setObjectName("label")
|
||||
self.lineEdit = QtWidgets.QLineEdit(KeyWizard)
|
||||
self.lineEdit.setGeometry(QtCore.QRect(350, 160, 41, 21))
|
||||
self.lineEdit.setCursor(QtGui.QCursor(QtCore.Qt.BlankCursor))
|
||||
self.lineEdit.setAutoFillBackground(False)
|
||||
self.lineEdit.setStyleSheet("background-color: transparent; border:none")
|
||||
self.lineEdit.setClearButtonEnabled(False)
|
||||
self.lineEdit.setObjectName("lineEdit")
|
||||
|
||||
self.retranslateUi(KeyWizard)
|
||||
QtCore.QMetaObject.connectSlotsByName(KeyWizard)
|
||||
|
||||
def retranslateUi(self, KeyWizard):
|
||||
_translate = QtCore.QCoreApplication.translate
|
||||
KeyWizard.setWindowTitle(_translate("KeyWizard", "Key Wizard"))
|
||||
self.label.setText(_translate("KeyWizard", "This is the Key Wizard. Simply press the key you would like to assign, and the key caption and keycodes will be set automatically. If you want to add functions for long presses or doubleclicks, or if you would like to add more captions, you can always edit the key manually later by doubleclicking it."))
|
||||
49
src/lib/oskb/ui_valueedit.py
Normal file
49
src/lib/oskb/ui_valueedit.py
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Form implementation generated from reading ui file 'ValueEdit.ui'
|
||||
#
|
||||
# Created by: PyQt5 UI code generator 5.14.0
|
||||
#
|
||||
# WARNING! All changes made in this file will be lost!
|
||||
|
||||
|
||||
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||
|
||||
|
||||
class Ui_ValueEdit(object):
|
||||
def setupUi(self, ValueEdit):
|
||||
ValueEdit.setObjectName("ValueEdit")
|
||||
ValueEdit.resize(247, 103)
|
||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(ValueEdit.sizePolicy().hasHeightForWidth())
|
||||
ValueEdit.setSizePolicy(sizePolicy)
|
||||
ValueEdit.setMinimumSize(QtCore.QSize(247, 103))
|
||||
ValueEdit.setMaximumSize(QtCore.QSize(247, 103))
|
||||
self.buttonBox = QtWidgets.QDialogButtonBox(ValueEdit)
|
||||
self.buttonBox.setGeometry(QtCore.QRect(60, 60, 171, 32))
|
||||
self.buttonBox.setOrientation(QtCore.Qt.Horizontal)
|
||||
self.buttonBox.setStandardButtons(QtWidgets.QDialogButtonBox.Cancel|QtWidgets.QDialogButtonBox.Save)
|
||||
self.buttonBox.setObjectName("buttonBox")
|
||||
self.doubleSpinBox = QtWidgets.QDoubleSpinBox(ValueEdit)
|
||||
self.doubleSpinBox.setGeometry(QtCore.QRect(130, 20, 81, 24))
|
||||
self.doubleSpinBox.setDecimals(1)
|
||||
self.doubleSpinBox.setMinimum(0.1)
|
||||
self.doubleSpinBox.setSingleStep(0.1)
|
||||
self.doubleSpinBox.setProperty("value", 0.5)
|
||||
self.doubleSpinBox.setObjectName("doubleSpinBox")
|
||||
self.label = QtWidgets.QLabel(ValueEdit)
|
||||
self.label.setGeometry(QtCore.QRect(10, 20, 111, 21))
|
||||
self.label.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
|
||||
self.label.setObjectName("label")
|
||||
|
||||
self.retranslateUi(ValueEdit)
|
||||
self.buttonBox.accepted.connect(ValueEdit.accept)
|
||||
self.buttonBox.rejected.connect(ValueEdit.reject)
|
||||
QtCore.QMetaObject.connectSlotsByName(ValueEdit)
|
||||
|
||||
def retranslateUi(self, ValueEdit):
|
||||
_translate = QtCore.QCoreApplication.translate
|
||||
ValueEdit.setWindowTitle(_translate("ValueEdit", "Enter Value"))
|
||||
self.label.setText(_translate("ValueEdit", "Width:"))
|
||||
|
|
@ -1,6 +1,8 @@
|
|||
import platform
|
||||
import subprocess
|
||||
import sys
|
||||
import time
|
||||
|
||||
from components import ArchiveSynchronizer
|
||||
from lib.db import Session, Users
|
||||
from PyQt5.QtCore import QTimer, pyqtSignal
|
||||
|
|
@ -63,3 +65,6 @@ class Login(Widget):
|
|||
self.password_le.setFocus()
|
||||
if platform.system().lower() == 'windows':
|
||||
subprocess.Popen(["open_osk.bat"]) # OPEN ON SCREEN KEYBOARD
|
||||
else:
|
||||
subprocess.Popen(["./open_oskb.sh"]) # OPEN ON SCREEN KEYBOARD
|
||||
time.sleep(0.5)
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user