diff --git a/Furious/Externals/GenTranslation.py b/Furious/Externals/GenTranslation.py index d6932a6..32460c3 100644 --- a/Furious/Externals/GenTranslation.py +++ b/Furious/Externals/GenTranslation.py @@ -191,6 +191,14 @@ TRANSLATION = { "ZH": "从剪贴板导入JSON配置", "isReviewed": "True" }, + "Scan QR Code On The Screen": { + "source": [ + "Furious.TrayActions.Import" + ], + "RU": "Отсканируйте QR-код на экране", + "ZH": "扫描屏幕上的二维码", + "isReviewed": "True" + }, "Set Indent": { "source": [ "Furious.Widget.IndentSpinBox" diff --git a/Furious/Frozenlib/AppResources.py b/Furious/Frozenlib/AppResources.py index 60e4e56..a9a42d5 100644 --- a/Furious/Frozenlib/AppResources.py +++ b/Furious/Frozenlib/AppResources.py @@ -280,7 +280,7 @@ a.5.5 0 0 1-.478\ -.647L9.89 2.41 \ 4.157 8.5z\x22/>\x0d\x0a<\ /svg>\ -\x00\x00\x03\xd7\ +\x00\x00\x03\xd9\ <\ svg xmlns=\x22http:\ //www.w3.org/200\ @@ -290,60 +290,60 @@ ll=\x22currentColor\ \x22 class=\x22bi bi-p\ erson-gear\x22 view\ Box=\x220 0 16 16\x22>\ -\x0a \x0a\ -\ +\x0d\x0a \ +\x0d\x0a\ \x00\x00\x02\x12\ <\ svg xmlns=\x22http:\ @@ -914,7 +914,7 @@ zM3 4a1 1 0 0 1 \ -1 1H4a1 1 0 0 1\ -1-1V4z\x22/>\x0d\x0a\ -\x00\x00\x01\xcc\ +\x00\x00\x01\xce\ <\ svg xmlns=\x22http:\ //www.w3.org/200\ @@ -923,28 +923,28 @@ svg xmlns=\x22http:\ ll=\x22currentColor\ \x22 class=\x22bi bi-f\ older2\x22 viewBox=\ -\x220 0 16 16\x22>\x0a <\ -path d=\x22M1 3.5A1\ -.5 1.5 0 0 1 2.5\ - 2h2.764c.958 0 \ -1.76.56 2.311 1.\ -184C7.985 3.648 \ -8.48 4 9 4h4.5A1\ -.5 1.5 0 0 1 15 \ -5.5v7a1.5 1.5 0 \ -0 1-1.5 1.5h-11A\ -1.5 1.5 0 0 1 1 \ -12.5zM2.5 3a.5.5\ - 0 0 0-.5.5V6h12\ -v-.5a.5.5 0 0 0-\ -.5-.5H9c-.964 0-\ -1.71-.629-2.174-\ -1.154C6.374 3.33\ -4 5.82 3 5.264 3\ -zM14 7H2v5.5a.5.\ -5 0 0 0 .5.5h11a\ -.5.5 0 0 0 .5-.5\ -z\x22/>\x0a\ +\x220 0 16 16\x22>\x0d\x0a \ +\x0d\x0a\ \x00\x00\x02U\ <\ svg xmlns=\x22http:\ @@ -1462,7 +1462,7 @@ A7.568 7.568 0 0\ 96 5.054-1.902Z\x22\ />\x0d\x0a \x0d\x0a\ -\x00\x00\x01]\ +\x00\x00\x01`\ <\ svg xmlns=\x22http:\ //www.w3.org/200\ @@ -1472,20 +1472,20 @@ ll=\x22currentColor\ \x22 class=\x22bi bi-a\ rrow-clockwise\x22 \ viewBox=\x220 0 16 \ -16\x22>\x0a \x0a \x0a\ +16\x22>\x0d\x0a \x0d\x0a \x0d\x0a\ \x00\x00\x02<\ <\ svg xmlns=\x22http:\ @@ -1696,6 +1696,53 @@ c-.625.626-.94 1\ .896 5.054-1.902\ Z\x22 />\x0d\x0a \x0d\x0a<\ /svg>\ +\x00\x00\x02\xc9\ +<\ +svg xmlns=\x22http:\ +//www.w3.org/200\ +0/svg\x22 width=\x2216\ +\x22 height=\x2216\x22 fi\ +ll=\x22currentColor\ +\x22 class=\x22bi bi-q\ +r-code-scan\x22 vie\ +wBox=\x220 0 16 16\x22\ +>\x0a \x0a \ + \x0a \ + \ +\x0a \x0a \x0a\ \x00\x00\x03\x8b\ <\ svg xmlns=\x22http:\ @@ -2674,7 +2721,7 @@ l5.732-6.09H9a.5\ 47L9.89 2.41 4.1\ 57 8.5z\x22/>\x0d\x0a\ -\x00\x00\x03\xe4\ +\x00\x00\x03\xe6\ <\ svg xmlns=\x22http:\ //www.w3.org/200\ @@ -2684,61 +2731,61 @@ ll=\x22currentColor\ \x22 class=\x22bi bi-p\ erson-gear\x22 view\ Box=\x220 0 16 16\x22>\ -\x0a \x0a\ +\x0d\x0a \x0d\x0a<\ +/svg>\ \x00\x00\x02,\ <\ svg xmlns=\x22http:\ @@ -3185,7 +3232,7 @@ h7a1 1 0 0 1 1 1\ v10a1 1 0 0 1-1 \ 1H4a1 1 0 0 1-1-\ 1V4z\x22/>\x0d\x0a\ -\x00\x00\x01\xd9\ +\x00\x00\x01\xdb\ <\ svg xmlns=\x22http:\ //www.w3.org/200\ @@ -3194,29 +3241,29 @@ svg xmlns=\x22http:\ ll=\x22currentColor\ \x22 class=\x22bi bi-f\ older2\x22 viewBox=\ -\x220 0 16 16\x22>\x0a <\ -path fill=\x22white\ -\x22 d=\x22M1 3.5A1.5 \ -1.5 0 0 1 2.5 2h\ -2.764c.958 0 1.7\ -6.56 2.311 1.184\ -C7.985 3.648 8.4\ -8 4 9 4h4.5A1.5 \ -1.5 0 0 1 15 5.5\ -v7a1.5 1.5 0 0 1\ --1.5 1.5h-11A1.5\ - 1.5 0 0 1 1 12.\ -5zM2.5 3a.5.5 0 \ -0 0-.5.5V6h12v-.\ -5a.5.5 0 0 0-.5-\ -.5H9c-.964 0-1.7\ -1-.629-2.174-1.1\ -54C6.374 3.334 5\ -.82 3 5.264 3zM1\ -4 7H2v5.5a.5.5 0\ - 0 0 .5.5h11a.5.\ -5 0 0 0 .5-.5z\x22/\ ->\x0a\ +\x220 0 16 16\x22>\x0d\x0a \ +\x0d\x0a\ \x00\x00\x02\x96\ <\ svg xmlns=\x22http:\ @@ -3485,7 +3532,7 @@ white\x22 d=\x22M7.009\ .126 3.936-.896 \ 5.054-1.902Z\x22/>\x0d\ \x0a\ -\x00\x00\x01w\ +\x00\x00\x01z\ <\ svg xmlns=\x22http:\ //www.w3.org/200\ @@ -3495,22 +3542,22 @@ ll=\x22currentColor\ \x22 class=\x22bi bi-a\ rrow-clockwise\x22 \ viewBox=\x220 0 16 \ -16\x22>\x0a \x0a \x0a\ -\ +16\x22>\x0d\x0a \x0d\x0a \x0d\x0a\ \x00\x00\x02I\ <\ svg xmlns=\x22http:\ @@ -3593,6 +3640,57 @@ white\x22 d=\x22M11 1a\ 4a.5.5 0 0 1-1 0\ V3a2 2 0 0 0-2-2\ z\x22/>\x0d\x0a\ +\x00\x00\x03\x0a\ +<\ +svg xmlns=\x22http:\ +//www.w3.org/200\ +0/svg\x22 width=\x2216\ +\x22 height=\x2216\x22 fi\ +ll=\x22currentColor\ +\x22 class=\x22bi bi-q\ +r-code-scan\x22 vie\ +wBox=\x220 0 16 16\x22\ +>\x0a \x0a \x0a \x0a \x0a \x0a\ \x00\x00\x03\xa5\ <\ svg xmlns=\x22http:\ @@ -4182,6 +4280,10 @@ qt_resource_name = b"\ \x00r\ \x00o\x00c\x00k\x00e\x00t\x00-\x00t\x00a\x00k\x00e\x00o\x00f\x00f\x00-\x00d\x00a\ \x00r\x00k\x00.\x00s\x00v\x00g\ +\x00\x10\ +\x0d\xeaG\x07\ +\x00q\ +\x00r\x00-\x00c\x00o\x00d\x00e\x00-\x00s\x00c\x00a\x00n\x00.\x00s\x00v\x00g\ \x00\x0b\ \x0d\xd7\xadG\ \x00s\ @@ -4251,162 +4353,166 @@ qt_resource_struct = b"\ \x00\x00\x00\x00\x00\x00\x00\x00\ \x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x02\ \x00\x00\x00\x00\x00\x00\x00\x00\ -\x00\x00\x00\x10\x00\x02\x00\x00\x00*\x00\x00\x00\x03\ +\x00\x00\x00\x10\x00\x02\x00\x00\x00+\x00\x00\x00\x03\ \x00\x00\x00\x00\x00\x00\x00\x00\ -\x00\x00\x01\xf0\x00\x00\x00\x00\x00\x01\x00\x00+\xd6\ -\x00\x00\x01\x93\xdal,\x95\ -\x00\x00\x04\xa0\x00\x02\x00\x00\x00#\x00\x00\x00-\ +\x00\x00\x01\xf0\x00\x00\x00\x00\x00\x01\x00\x00+\xd8\ +\x00\x00\x01\x96\xd8gH\x1b\ +\x00\x00\x04\xc6\x00\x02\x00\x00\x00$\x00\x00\x00.\ \x00\x00\x00\x00\x00\x00\x00\x00\ -\x00\x00\x03 \x00\x00\x00\x00\x00\x01\x00\x00I_\ -\x00\x00\x01\x93\xdal,\x96\ -\x00\x00\x03`\x00\x00\x00\x00\x00\x01\x00\x00O\xb4\ -\x00\x00\x01\x93\xdal,\x97\ -\x00\x00\x04:\x00\x00\x00\x00\x00\x01\x00\x00]\xa7\ -\x00\x00\x01\x93\xdal,\x98\ -\x00\x00\x03\xd4\x00\x00\x00\x00\x00\x01\x00\x00Y\x0d\ -\x00\x00\x01\x93\xdal,\x93\ -\x00\x00\x02H\x00\x00\x00\x00\x00\x01\x00\x005\x07\ -\x00\x00\x01\x93\xdal,\x94\ -\x00\x00\x02\xfa\x00\x00\x00\x00\x00\x01\x00\x00F\xe2\ -\x00\x00\x01\x93\xdal,\x94\ +\x00\x00\x03 \x00\x00\x00\x00\x00\x01\x00\x00Ic\ +\x00\x00\x01\x96\xd8gH\x1c\ +\x00\x00\x03`\x00\x00\x00\x00\x00\x01\x00\x00O\xb8\ +\x00\x00\x01\x96\xd8gH\x1e\ +\x00\x00\x04:\x00\x00\x00\x00\x00\x01\x00\x00]\xae\ +\x00\x00\x01\x96\xd8gH\x1e\ +\x00\x00\x03\xd4\x00\x00\x00\x00\x00\x01\x00\x00Y\x14\ +\x00\x00\x01\x96\xd8gH\x19\ +\x00\x00\x02H\x00\x00\x00\x00\x00\x01\x00\x005\x09\ +\x00\x00\x01\x96\xd8gH\x1a\ +\x00\x00\x02\xfa\x00\x00\x00\x00\x00\x01\x00\x00F\xe6\ +\x00\x00\x01\x96\xd8gH\x1a\ \x00\x00\x00\x98\x00\x00\x00\x00\x00\x01\x00\x00\x0a\xea\ -\x00\x00\x01\x93\xdal,\x96\ -\x00\x00\x02&\x00\x00\x00\x00\x00\x01\x00\x003l\ -\x00\x00\x01\x93\xdal,\x93\ -\x00\x00\x04\xf8\x00\x00\x00\x00\x00\x01\x00\x00q\xe1\ -\x00\x00\x01\x93\xdal,\x95\ -\x00\x00\x05\xce\x00\x00\x00\x00\x00\x01\x00\x00\x82\x97\ -\x00\x00\x01\x93\xdal,\x98\ -\x00\x00\x02\x98\x00\x00\x00\x00\x00\x01\x00\x00:\xb7\ -\x00\x00\x01\x93\xdal,\x98\ -\x00\x00\x02|\x00\x00\x00\x00\x00\x01\x00\x008^\ -\x00\x00\x01\x93\xdal,\x96\ -\x00\x00\x01\xd2\x00\x00\x00\x00\x00\x01\x00\x00'\x15\ -\x00\x00\x01\x93\xdal,\x93\ -\x00\x00\x01\xba\x00\x00\x00\x00\x00\x01\x00\x00#u\ -\x00\x00\x01\x93\xdal,\x99\ -\x00\x00\x03\xa8\x00\x00\x00\x00\x00\x01\x00\x00W\xac\ -\x00\x00\x01\x9a\xd9\x08\xa4\xd1\ -\x00\x00\x04\xd0\x00\x00\x00\x00\x00\x01\x00\x00o\x98\ -\x00\x00\x01\x93\xdal,\x96\ +\x00\x00\x01\x96\xd8gH\x1d\ +\x00\x00\x02&\x00\x00\x00\x00\x00\x01\x00\x003n\ +\x00\x00\x01\x96\xd8gH\x18\ +\x00\x00\x05\x1e\x00\x00\x00\x00\x00\x01\x00\x00t\xb5\ +\x00\x00\x01\x96\xd8gH\x1c\ +\x00\x00\x05\xf4\x00\x00\x00\x00\x00\x01\x00\x00\x85k\ +\x00\x00\x01\x96\xd8gH\x1e\ +\x00\x00\x02\x98\x00\x00\x00\x00\x00\x01\x00\x00:\xbb\ +\x00\x00\x01\x96\xd8gH\x1f\ +\x00\x00\x02|\x00\x00\x00\x00\x00\x01\x00\x008b\ +\x00\x00\x01\x96\xd8gH\x1d\ +\x00\x00\x01\xd2\x00\x00\x00\x00\x00\x01\x00\x00'\x17\ +\x00\x00\x01\x96\xd8gH\x19\ +\x00\x00\x01\xba\x00\x00\x00\x00\x00\x01\x00\x00#w\ +\x00\x00\x01\x96\xd8gH \ +\x00\x00\x03\xa8\x00\x00\x00\x00\x00\x01\x00\x00W\xb0\ +\x00\x00\x01\x9a\xdc\xa9\xf2\xb4\ +\x00\x00\x04\xf6\x00\x00\x00\x00\x00\x01\x00\x00rl\ +\x00\x00\x01\x96\xd8gH\x1d\ \x00\x00\x00t\x00\x00\x00\x00\x00\x01\x00\x00\x08\x90\ -\x00\x00\x01\x93\xdal,\x95\ -\x00\x00\x05\x1c\x00\x00\x00\x00\x00\x01\x00\x00s\xb4\ -\x00\x00\x01\x93\xdal,\x94\ +\x00\x00\x01\x96\xd8gH\x1a\ +\x00\x00\x05B\x00\x00\x00\x00\x00\x01\x00\x00v\x88\ +\x00\x00\x01\x96\xd8gH\x19\ \x00\x00\x00Z\x00\x00\x00\x00\x00\x01\x00\x00\x01z\ -\x00\x00\x01\x93\xdal,\x95\ -\x00\x00\x01\x0a\x00\x00\x00\x00\x00\x01\x00\x00\x14?\ -\x00\x00\x01\x93\xdal,\x95\ -\x00\x00\x06\x5c\x00\x00\x00\x00\x00\x01\x00\x00\x8d\xd5\ -\x00\x00\x01\x93\xdal,\x98\ +\x00\x00\x01\x96\xd8gH\x1a\ +\x00\x00\x01\x0a\x00\x00\x00\x00\x00\x01\x00\x00\x14A\ +\x00\x00\x01\x96\xd8gH\x1c\ +\x00\x00\x06\x82\x00\x00\x00\x00\x00\x01\x00\x00\x90\xa9\ +\x00\x00\x01\x96\xd8gH\x1f\ \x00\x00\x00\xe6\x00\x00\x00\x00\x00\x01\x00\x00\x10d\ -\x00\x00\x01\x9a\xd5bh\x19\ -\x00\x00\x03\xf0\x00\x00\x00\x00\x00\x01\x00\x00[M\ -\x00\x00\x01\x93\xdal,\x94\ -\x00\x00\x02\xc2\x00\x00\x00\x00\x00\x01\x00\x00B\xb1\ -\x00\x00\x01\x93\xdal,\x99\ -\x00\x00\x05\x84\x00\x00\x00\x00\x00\x01\x00\x00}a\ -\x00\x00\x01\x93\xdal,\x93\ -\x00\x00\x01N\x00\x00\x00\x00\x00\x01\x00\x00\x16U\ -\x00\x00\x01\x93\xdal,\x98\ -\x00\x00\x04\x8a\x00\x00\x00\x00\x00\x01\x00\x00i0\ -\x00\x00\x01\x93\xdal,\x99\ -\x00\x00\x06<\x00\x00\x00\x00\x00\x01\x00\x00\x8c\xbe\ -\x00\x00\x01\x93\xdal,\x96\ -\x00\x00\x04\x16\x00\x00\x00\x00\x00\x01\x00\x00\x5c\x83\ -\x00\x00\x01\x93\xdal,\x99\ -\x00\x00\x05\xb4\x00\x00\x00\x00\x00\x01\x00\x00~\xdc\ -\x00\x00\x01\x93\xdal,\x98\ -\x00\x00\x06\x0c\x00\x00\x00\x00\x00\x01\x00\x00\x8a\x8f\ -\x00\x00\x01\x93\xdal,\x93\ -\x00\x00\x05:\x00\x00\x00\x00\x00\x01\x00\x00uf\ -\x00\x00\x01\x93\xdal,\x97\ -\x00\x00\x02`\x00\x00\x00\x00\x00\x01\x00\x006\x8e\ -\x00\x00\x01\x9a\xd9\x08\xac.\ -\x00\x00\x02\xe0\x00\x00\x00\x00\x00\x01\x00\x00D`\ -\x00\x00\x01\x93\xdal,\x99\ -\x00\x00\x04n\x00\x00\x00\x00\x00\x01\x00\x00e\xa1\ -\x00\x00\x01\x93\xdal,\x99\ -\x00\x00\x04\xb0\x00\x00\x00\x00\x00\x01\x00\x00k\xb1\ -\x00\x00\x01\x96\xe7\xdc\x22W\ -\x00\x00\x01\x86\x00\x00\x00\x00\x00\x01\x00\x00\x1eO\ -\x00\x00\x01\x93\xdal,\x94\ +\x00\x00\x01\x9a\xdc\xa9\xf2\xb4\ +\x00\x00\x03\xf0\x00\x00\x00\x00\x00\x01\x00\x00[T\ +\x00\x00\x01\x96\xd8gH\x1a\ +\x00\x00\x02\xc2\x00\x00\x00\x00\x00\x01\x00\x00B\xb5\ +\x00\x00\x01\x96\xd8gH\x1f\ +\x00\x00\x05\xaa\x00\x00\x00\x00\x00\x01\x00\x00\x805\ +\x00\x00\x01\x96\xd8gH\x17\ +\x00\x00\x01N\x00\x00\x00\x00\x00\x01\x00\x00\x16W\ +\x00\x00\x01\x96\xd8gH\x1e\ +\x00\x00\x04\xb0\x00\x00\x00\x00\x00\x01\x00\x00l\x04\ +\x00\x00\x01\x96\xd8gH \ +\x00\x00\x06b\x00\x00\x00\x00\x00\x01\x00\x00\x8f\x92\ +\x00\x00\x01\x96\xd8gH\x1c\ +\x00\x00\x04\x16\x00\x00\x00\x00\x00\x01\x00\x00\x5c\x8a\ +\x00\x00\x01\x96\xd8gH!\ +\x00\x00\x05\xda\x00\x00\x00\x00\x00\x01\x00\x00\x81\xb0\ +\x00\x00\x01\x96\xd8gH\x1f\ +\x00\x00\x062\x00\x00\x00\x00\x00\x01\x00\x00\x8dc\ +\x00\x00\x01\x96\xd8gH\x18\ +\x00\x00\x05`\x00\x00\x00\x00\x00\x01\x00\x00x:\ +\x00\x00\x01\x96\xd8gH\x1d\ +\x00\x00\x02`\x00\x00\x00\x00\x00\x01\x00\x006\x90\ +\x00\x00\x01\x9a\xdc\xa9\xf2\xb4\ +\x00\x00\x02\xe0\x00\x00\x00\x00\x00\x01\x00\x00Dd\ +\x00\x00\x01\x96\xd8gH \ +\x00\x00\x04\x94\x00\x00\x00\x00\x00\x01\x00\x00hu\ +\x00\x00\x01\x96\xd8gH \ +\x00\x00\x04n\x00\x00\x00\x00\x00\x01\x00\x00e\xa8\ +\x00\x00\x01\x9a\xe4\x8d\x18\x03\ +\x00\x00\x04\xd6\x00\x00\x00\x00\x00\x01\x00\x00n\x85\ +\x00\x00\x01\x9a\x8f\x9c\xac\x94\ +\x00\x00\x01\x86\x00\x00\x00\x00\x00\x01\x00\x00\x1eQ\ +\x00\x00\x01\x96\xd8gH\x1a\ \x00\x00\x00\xb8\x00\x00\x00\x00\x00\x01\x00\x00\x0e\xca\ -\x00\x00\x01\x93\xdal,\x95\ +\x00\x00\x01\x96\xd8gH\x1c\ \x00\x00\x00(\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\ -\x00\x00\x01\x93\xdal,\x93\ -\x00\x00\x02\x10\x00\x00\x00\x00\x00\x01\x00\x00/\xd6\ -\x00\x00\x01\x93\xdal,\x9f\ -\x00\x00\x01\xf0\x00\x00\x00\x00\x00\x01\x00\x00\xb4\x0a\ -\x00\x00\x01\x93\xdal,\x9c\ -\x00\x00\x03 \x00\x00\x00\x00\x00\x01\x00\x00\xcai\ -\x00\x00\x01\x93\xdal,\x9d\ -\x00\x00\x03\xd4\x00\x00\x00\x00\x00\x01\x00\x00\xd2`\ -\x00\x00\x01\x93\xdal,\x9a\ -\x00\x00\x02H\x00\x00\x00\x00\x00\x01\x00\x00\xbdo\ -\x00\x00\x01\x93\xdal,\x9b\ -\x00\x00\x02\xfa\x00\x00\x00\x00\x00\x01\x00\x00\xc7\xdf\ -\x00\x00\x01\x93\xdal,\x9b\ -\x00\x00\x00\x98\x00\x00\x00\x00\x00\x01\x00\x00\x9a\xb0\ -\x00\x00\x01\x93\xdal,\x9d\ -\x00\x00\x02&\x00\x00\x00\x00\x00\x01\x00\x00\xbb\xc7\ -\x00\x00\x01\x93\xdal,\x9a\ -\x00\x00\x04\xf8\x00\x00\x00\x00\x00\x01\x00\x00\xe3\xaf\ -\x00\x00\x01\x93\xdal,\x9c\ -\x00\x00\x02|\x00\x00\x00\x00\x00\x01\x00\x00\xc0\xe0\ -\x00\x00\x01\x93\xdal,\x9d\ -\x00\x00\x01\xd2\x00\x00\x00\x00\x00\x01\x00\x00\xaf<\ -\x00\x00\x01\x93\xdal,\x9a\ -\x00\x00\x01\xba\x00\x00\x00\x00\x00\x01\x00\x00\xab\x8f\ -\x00\x00\x01\x93\xdal,\x9e\ -\x00\x00\x03\xa8\x00\x00\x00\x00\x00\x01\x00\x00\xd0\xe5\ -\x00\x00\x01\x9a\xd9\x09m\x86\ -\x00\x00\x04\xd0\x00\x00\x00\x00\x00\x01\x00\x00\xe1L\ -\x00\x00\x01\x93\xdal,\x9d\ -\x00\x00\x00t\x00\x00\x00\x00\x00\x01\x00\x00\x98<\ -\x00\x00\x01\x93\xdal,\x9c\ -\x00\x00\x05\x1c\x00\x00\x00\x00\x00\x01\x00\x00\xe5\x9c\ -\x00\x00\x01\x93\xdal,\x9b\ -\x00\x00\x00Z\x00\x00\x00\x00\x00\x01\x00\x00\x91\x19\ -\x00\x00\x01\x93\xdal,\x9b\ -\x00\x00\x01\x0a\x00\x00\x00\x00\x00\x01\x00\x00\xa4,\ -\x00\x00\x01\x93\xdal,\x9c\ -\x00\x00\x06\x5c\x00\x00\x00\x00\x00\x01\x00\x00\xf0L\ -\x00\x00\x01\x93\xdal,\x9d\ -\x00\x00\x00\xe6\x00\x00\x00\x00\x00\x01\x00\x00\xa0D\ -\x00\x00\x01\x9a\xd5c1\xd5\ -\x00\x00\x03\xf0\x00\x00\x00\x00\x00\x01\x00\x00\xd4\xad\ -\x00\x00\x01\x93\xdal,\x9b\ -\x00\x00\x02\xc2\x00\x00\x00\x00\x00\x01\x00\x00\xc3z\ -\x00\x00\x01\x93\xdal,\x9e\ -\x00\x00\x05\x84\x00\x00\x00\x00\x00\x01\x00\x00\xe7h\ -\x00\x00\x01\x93\xdal,\x9a\ -\x00\x00\x04\x8a\x00\x00\x00\x00\x00\x01\x00\x00\xda\xca\ -\x00\x00\x01\x93\xdal,\x9e\ -\x00\x00\x06<\x00\x00\x00\x00\x00\x01\x00\x00\xef(\ -\x00\x00\x01\x93\xdal,\x9d\ -\x00\x00\x04\x16\x00\x00\x00\x00\x00\x01\x00\x00\xd5\xf0\ -\x00\x00\x01\x93\xdal,\x9f\ -\x00\x00\x05\xb4\x00\x00\x00\x00\x00\x01\x00\x00\xe8\xf0\ -\x00\x00\x01\x93\xdal,\x9d\ -\x00\x00\x06\x0c\x00\x00\x00\x00\x00\x01\x00\x00\xec\xdf\ -\x00\x00\x01\x93\xdal,\x9a\ -\x00\x00\x02`\x00\x00\x00\x00\x00\x01\x00\x00\xbf\x03\ -\x00\x00\x01\x9a\xd9\x09\x9e\xcd\ -\x00\x00\x02\xe0\x00\x00\x00\x00\x00\x01\x00\x00\xc56\ -\x00\x00\x01\x93\xdal,\x9e\ -\x00\x00\x04n\x00\x00\x00\x00\x00\x01\x00\x00\xd7!\ -\x00\x00\x01\x93\xdal,\x9e\ -\x00\x00\x04\xb0\x00\x00\x00\x00\x00\x01\x00\x00\xddX\ -\x00\x00\x01\x96\xe7\xdc\x22W\ -\x00\x00\x01\x86\x00\x00\x00\x00\x00\x01\x00\x00\xa6\x5c\ -\x00\x00\x01\x93\xdal,\x9b\ -\x00\x00\x00\xb8\x00\x00\x00\x00\x00\x01\x00\x00\x9e\x9d\ -\x00\x00\x01\x93\xdal,\x9c\ -\x00\x00\x00(\x00\x00\x00\x00\x00\x01\x00\x00\x8f\x92\ -\x00\x00\x01\x93\xdal,\x9a\ -\x00\x00\x02\x10\x00\x00\x00\x00\x00\x01\x00\x00\xb8\x17\ -\x00\x00\x01\x93\xdal,\x9f\ +\x00\x00\x01\x96\xd8gH\x17\ +\x00\x00\x02\x10\x00\x00\x00\x00\x00\x01\x00\x00/\xd8\ +\x00\x00\x01\x96\xd8gH(\ +\x00\x00\x01\xf0\x00\x00\x00\x00\x00\x01\x00\x00\xb6\xe0\ +\x00\x00\x01\x96\xd8gH$\ +\x00\x00\x03 \x00\x00\x00\x00\x00\x01\x00\x00\xcdA\ +\x00\x00\x01\x96\xd8gH%\ +\x00\x00\x03\xd4\x00\x00\x00\x00\x00\x01\x00\x00\xd5;\ +\x00\x00\x01\x96\xd8gH\x22\ +\x00\x00\x02H\x00\x00\x00\x00\x00\x01\x00\x00\xc0E\ +\x00\x00\x01\x96\xd8gH#\ +\x00\x00\x02\xfa\x00\x00\x00\x00\x00\x01\x00\x00\xca\xb7\ +\x00\x00\x01\x96\xd8gH#\ +\x00\x00\x00\x98\x00\x00\x00\x00\x00\x01\x00\x00\x9d\x84\ +\x00\x00\x01\x96\xd8gH%\ +\x00\x00\x02&\x00\x00\x00\x00\x00\x01\x00\x00\xbe\x9d\ +\x00\x00\x01\x96\xd8gH!\ +\x00\x00\x05\x1e\x00\x00\x00\x00\x00\x01\x00\x00\xe9\x98\ +\x00\x00\x01\x96\xd8gH$\ +\x00\x00\x02|\x00\x00\x00\x00\x00\x01\x00\x00\xc3\xb8\ +\x00\x00\x01\x96\xd8gH&\ +\x00\x00\x01\xd2\x00\x00\x00\x00\x00\x01\x00\x00\xb2\x12\ +\x00\x00\x01\x96\xd8gH!\ +\x00\x00\x01\xba\x00\x00\x00\x00\x00\x01\x00\x00\xaee\ +\x00\x00\x01\x96\xd8gH'\ +\x00\x00\x03\xa8\x00\x00\x00\x00\x00\x01\x00\x00\xd3\xbd\ +\x00\x00\x01\x9a\xdc\xa9\xf2\xb4\ +\x00\x00\x04\xf6\x00\x00\x00\x00\x00\x01\x00\x00\xe75\ +\x00\x00\x01\x96\xd8gH%\ +\x00\x00\x00t\x00\x00\x00\x00\x00\x01\x00\x00\x9b\x10\ +\x00\x00\x01\x96\xd8gH$\ +\x00\x00\x05B\x00\x00\x00\x00\x00\x01\x00\x00\xeb\x85\ +\x00\x00\x01\x96\xd8gH\x22\ +\x00\x00\x00Z\x00\x00\x00\x00\x00\x01\x00\x00\x93\xed\ +\x00\x00\x01\x96\xd8gH#\ +\x00\x00\x01\x0a\x00\x00\x00\x00\x00\x01\x00\x00\xa7\x02\ +\x00\x00\x01\x96\xd8gH$\ +\x00\x00\x06\x82\x00\x00\x00\x00\x00\x01\x00\x00\xf65\ +\x00\x00\x01\x96\xd8gH&\ +\x00\x00\x00\xe6\x00\x00\x00\x00\x00\x01\x00\x00\xa3\x18\ +\x00\x00\x01\x9a\xdc\xa9\xf2\xb5\ +\x00\x00\x03\xf0\x00\x00\x00\x00\x00\x01\x00\x00\xd7\x88\ +\x00\x00\x01\x96\xd8gH\x22\ +\x00\x00\x02\xc2\x00\x00\x00\x00\x00\x01\x00\x00\xc6R\ +\x00\x00\x01\x96\xd8gH&\ +\x00\x00\x05\xaa\x00\x00\x00\x00\x00\x01\x00\x00\xedQ\ +\x00\x00\x01\x96\xd8gH!\ +\x00\x00\x04\xb0\x00\x00\x00\x00\x00\x01\x00\x00\xe0\xb3\ +\x00\x00\x01\x96\xd8gH'\ +\x00\x00\x06b\x00\x00\x00\x00\x00\x01\x00\x00\xf5\x11\ +\x00\x00\x01\x96\xd8gH%\ +\x00\x00\x04\x16\x00\x00\x00\x00\x00\x01\x00\x00\xd8\xcb\ +\x00\x00\x01\x96\xd8gH(\ +\x00\x00\x05\xda\x00\x00\x00\x00\x00\x01\x00\x00\xee\xd9\ +\x00\x00\x01\x96\xd8gH&\ +\x00\x00\x062\x00\x00\x00\x00\x00\x01\x00\x00\xf2\xc8\ +\x00\x00\x01\x96\xd8gH!\ +\x00\x00\x02`\x00\x00\x00\x00\x00\x01\x00\x00\xc1\xd9\ +\x00\x00\x01\x9a\xdc\xa9\xf2\xb5\ +\x00\x00\x02\xe0\x00\x00\x00\x00\x00\x01\x00\x00\xc8\x0e\ +\x00\x00\x01\x96\xd8gH'\ +\x00\x00\x04\x94\x00\x00\x00\x00\x00\x01\x00\x00\xdd\x0a\ +\x00\x00\x01\x96\xd8gH'\ +\x00\x00\x04n\x00\x00\x00\x00\x00\x01\x00\x00\xd9\xfc\ +\x00\x00\x01\x9a\xe4\x8e\x91\xcc\ +\x00\x00\x04\xd6\x00\x00\x00\x00\x00\x01\x00\x00\xe3A\ +\x00\x00\x01\x9a\x8f\x9c\xac\x94\ +\x00\x00\x01\x86\x00\x00\x00\x00\x00\x01\x00\x00\xa92\ +\x00\x00\x01\x96\xd8gH#\ +\x00\x00\x00\xb8\x00\x00\x00\x00\x00\x01\x00\x00\xa1q\ +\x00\x00\x01\x96\xd8gH%\ +\x00\x00\x00(\x00\x00\x00\x00\x00\x01\x00\x00\x92f\ +\x00\x00\x01\x96\xd8gH!\ +\x00\x00\x02\x10\x00\x00\x00\x00\x00\x01\x00\x00\xba\xed\ +\x00\x00\x01\x96\xd8gH(\ " def qInitResources(): diff --git a/Furious/TrayActions/Import.py b/Furious/TrayActions/Import.py index b2fcb42..42f0bd0 100644 --- a/Furious/TrayActions/Import.py +++ b/Furious/TrayActions/Import.py @@ -24,13 +24,21 @@ from Furious.Qt import gettext as _ from PySide6.QtWidgets import QApplication, QFileDialog +from PIL import Image + +from typing import Callable, Union + import os +import mss +import zxingcpp import logging +import functools __all__ = [ 'ImportFromFileAction', 'ImportURIFromClipboardAction', 'ImportJSONFromClipboardAction', + 'ImportQRCodeOnTheScreenAction', 'ImportAction', ] @@ -52,7 +60,7 @@ def showMBoxImportError(clipboard: str): mbox.open() -def importItemFromClipboard(clipboard: str): +def importURIFromClipboard(clipboard: str): factory = configFactoryFromAny(clipboard) if not factory.isValid(): @@ -68,6 +76,40 @@ def importItemFromClipboard(clipboard: str): mbox.open() +def importURIs(*uris, failureCallback: Union[Callable[[], None], None] = None): + imported = list() + rowIndex = len(Storage.UserServers()) + + for uri in uris: + factory = configFactoryFromAny(uri) + + if factory.isValid(): + APP().mainWindow.appendNewItemByFactory(factory) + + imported.append(factory.getExtras('remark')) + + if len(imported) == 0: + if callable(failureCallback): + failureCallback() + else: + if len(imported) == 1: + # Fall back to single + mbox = MBoxImportSuccess(icon=AppQMessageBox.Icon.Information) + mbox.remark = imported[0] + mbox.setText(mbox.customText()) + + # Show the MessageBox asynchronously + mbox.open() + else: + mbox = MBoxImportMultiSuccess(icon=AppQMessageBox.Icon.Information) + mbox.imported = imported + mbox.rowIndex = rowIndex + mbox.setText(mbox.customText()) + + # Show the MessageBox asynchronously + mbox.open() + + class MBoxImportError(AppQMessageBox): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) @@ -87,8 +129,8 @@ class MBoxImportMultiSuccess(AppQMessageBox): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) - self.imported = [] - self.rowCount = 0 + self.imported = list() + self.rowIndex = 0 self.setWindowTitle(_('Import')) self.setIcon(AppQMessageBox.Icon.Information) @@ -101,7 +143,7 @@ class MBoxImportMultiSuccess(AppQMessageBox): list( f'{index + 1} - {remark}. ' + _('Imported to row') - + f' {self.rowCount + index + 1}' + + f' {self.rowIndex + index + 1}' for index, remark in enumerate(self.imported) ) ) @@ -204,42 +246,16 @@ class ImportURIFromClipboardAction(AppQAction): clipboard = QApplication.clipboard().text().strip() try: - split = clipboard.split('\n') + uris = clipboard.split('\n') except Exception: # Any non-exit exceptions - importItemFromClipboard(clipboard) + importURIFromClipboard(clipboard) else: - imported = list() - rowCount = len(Storage.UserServers()) - - for uri in split: - factory = configFactoryFromAny(uri) - - if factory.isValid(): - APP().mainWindow.appendNewItemByFactory(factory) - - imported.append(factory.getExtras('remark')) - - if len(imported) == 0: - showMBoxImportError(clipboard) - else: - if len(imported) == 1: - # Fall back to single - mbox = MBoxImportSuccess(icon=AppQMessageBox.Icon.Information) - mbox.remark = imported[0] - mbox.setText(mbox.customText()) - - # Show the MessageBox asynchronously - mbox.open() - else: - mbox = MBoxImportMultiSuccess(icon=AppQMessageBox.Icon.Information) - mbox.imported = imported - mbox.rowCount = rowCount - mbox.setText(mbox.customText()) - - # Show the MessageBox asynchronously - mbox.open() + importURIs( + *uris, + failureCallback=functools.partial(showMBoxImportError, clipboard), + ) class ImportJSONFromClipboardAction(AppQAction): @@ -249,7 +265,39 @@ class ImportJSONFromClipboardAction(AppQAction): def triggeredCallback(self, checked): clipboard = QApplication.clipboard().text().strip() - importItemFromClipboard(clipboard) + importURIFromClipboard(clipboard) + + +class ImportQRCodeOnTheScreenAction(AppQAction): + def __init__(self, **kwargs): + super().__init__( + _('Scan QR Code On The Screen'), + icon=bootstrapIcon('qr-code-scan.svg'), + **kwargs, + ) + + self.sct = mss.mss() + + def triggeredCallback(self, checked): + uris = list() + + for index, monitor in enumerate(self.sct.monitors[1:], start=1): + frame = self.sct.grab(monitor) + # Convert raw BGRA bytes to PIL Image + image = Image.frombytes( + 'RGB', (frame.width, frame.height), frame.bgra, 'raw', 'BGRX' + ) + + barcodes = zxingcpp.read_barcodes(image) + + for barcode in barcodes: + data = barcode.text + + logger.debug(f'found QR code on monitor \'{index}\': {data}') + + uris.append(data) + + importURIs(*uris) class ImportAction(AppQAction): @@ -260,6 +308,8 @@ class ImportAction(AppQAction): menu=AppQMenu( ImportURIFromClipboardAction(), ImportJSONFromClipboardAction(), + AppQSeperator(), + ImportQRCodeOnTheScreenAction(), ), useActionGroup=False, checkable=True, diff --git a/Furious/Widget/UserServersQTableWidget.py b/Furious/Widget/UserServersQTableWidget.py index 9bd2306..13a1caf 100644 --- a/Furious/Widget/UserServersQTableWidget.py +++ b/Furious/Widget/UserServersQTableWidget.py @@ -1006,6 +1006,7 @@ class UserServersQTableWidget(Mixins.QTranslatable, AppQTableWidget): QtCore.Qt.Key.Key_J, ), ), + ImportQRCodeOnTheScreenAction(), AppQSeperator(), AppQAction( _('Export Share Link To Clipboard'), diff --git a/Icons/bootstrap/qr-code-scan.svg b/Icons/bootstrap/qr-code-scan.svg new file mode 100644 index 0000000..3c53387 --- /dev/null +++ b/Icons/bootstrap/qr-code-scan.svg @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/Icons/bootstrap/white/qr-code-scan.svg b/Icons/bootstrap/white/qr-code-scan.svg new file mode 100644 index 0000000..3848743 --- /dev/null +++ b/Icons/bootstrap/white/qr-code-scan.svg @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/Resources.qrc b/Resources.qrc index 93ad760..d99b82d 100644 --- a/Resources.qrc +++ b/Resources.qrc @@ -27,6 +27,7 @@ Icons/bootstrap/person-gear.svg Icons/bootstrap/pin-angle.svg Icons/bootstrap/qr-code.svg + Icons/bootstrap/qr-code-scan.svg Icons/bootstrap/rocket-takeoff.svg Icons/bootstrap/rocket-takeoff-admin-connected.svg Icons/bootstrap/rocket-takeoff-connected.svg @@ -70,6 +71,7 @@ Icons/bootstrap/white/person-gear.svg Icons/bootstrap/white/pin-angle.svg Icons/bootstrap/white/qr-code.svg + Icons/bootstrap/white/qr-code-scan.svg Icons/bootstrap/white/router.svg Icons/bootstrap/white/save.svg Icons/bootstrap/white/scissors.svg diff --git a/requirements.txt b/requirements.txt index 07df7a6..8bdc300 100644 --- a/requirements.txt +++ b/requirements.txt @@ -5,6 +5,9 @@ pybase64 pyqrcode pypng icmplib +mss +zxing-cpp +pillow sysproxy; sys_platform == "win32" win32session; sys_platform == "win32" darkdetect; sys_platform != "darwin"