From 79626156bf882d2774bb2d03151e25a7aab7d4ec Mon Sep 17 00:00:00 2001 From: Damon Lu <59256766+WhatDamon@users.noreply.github.com> Date: Tue, 1 Aug 2023 01:00:01 +0800 Subject: [PATCH] Update v4.5p final --- .github/ISSUE_TEMPLATE/Bug-Report.yml | 2 +- .github/ISSUE_TEMPLATE/Feature-Request.yml | 2 +- .github/workflows/build_x86.yml | 70 +++ README.md | 62 ++- lib/basic_info.py | 30 +- lib/config_li.py | 3 +- lib/controls.py | 90 ++++ lib/log.py | 12 + lib/platform_check.py | 11 +- lib/pslo_work.py | 55 ++- lib/update.py | 73 +-- pslo.pyw | 535 +++++++++++++-------- pslo_mini.pyw | 83 +++- requirements.txt | Bin 126 -> 96 bytes 14 files changed, 700 insertions(+), 328 deletions(-) create mode 100644 .github/workflows/build_x86.yml create mode 100644 lib/controls.py create mode 100644 lib/log.py diff --git a/.github/ISSUE_TEMPLATE/Bug-Report.yml b/.github/ISSUE_TEMPLATE/Bug-Report.yml index 306fb95..aac515f 100644 --- a/.github/ISSUE_TEMPLATE/Bug-Report.yml +++ b/.github/ISSUE_TEMPLATE/Bug-Report.yml @@ -1,7 +1,7 @@ name: 🪲报告 BUG description: 报告一个 BUG, 来帮助我们改进该程序。 title: "[Bug]: " -labels: ["bug"] +labels: ["🪲bug"] assignees: - octocat body: diff --git a/.github/ISSUE_TEMPLATE/Feature-Request.yml b/.github/ISSUE_TEMPLATE/Feature-Request.yml index aa0486b..aea6a70 100644 --- a/.github/ISSUE_TEMPLATE/Feature-Request.yml +++ b/.github/ISSUE_TEMPLATE/Feature-Request.yml @@ -1,7 +1,7 @@ name: 📣新功能请求 description: 提交一个新功能, 来帮助我们改进该程序。 title: "[Feature Request]: " -labels: ["enhancement"] +labels: ["📣enhancement"] assignees: - octocat body: diff --git a/.github/workflows/build_x86.yml b/.github/workflows/build_x86.yml new file mode 100644 index 0000000..6a1781e --- /dev/null +++ b/.github/workflows/build_x86.yml @@ -0,0 +1,70 @@ +# This is a workflow for building the kasa_cli executable on all three major platforms. + +name: Build-All-Platforms-x86 + +# Controls when the workflow will run +on: + # Triggers the workflow on push or pull request events but only for the "main" branch + push: + branches: ["main"] + + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + +jobs: + build: + strategy: + matrix: + os: [macos-latest, ubuntu-latest, windows-latest] + + runs-on: ${{ matrix.os }} + + steps: + - name: Check-out repository + uses: actions/checkout@v3 + + - name: Setup Python + uses: actions/setup-python@v4 + with: + python-version: '3.10' # Version range or exact version of a Python version to use, using SemVer's version range syntax + architecture: 'x86' # optional x64 or x86. Defaults to x64 if not specified + cache: 'pip' + cache-dependency-path: | + **/requirements*.txt + + - name: Install Dependencies + run: | + pip install -r requirements.txt + + - name: Build Executable (Standard) - x86 + uses: Nuitka/Nuitka-Action@main + with: + nuitka-version: main + script-name: pslo.pyw + onefile: true + standalone: true + disable-console: true + windows-icon-from-ico: ./icon/pslo_icon.ico + macos-create-app-bundle: true + macos-app-icon: ./icon/pslo_icon_mac.icns + + - name: Build Executable (Mini) - x86 + uses: Nuitka/Nuitka-Action@main + with: + nuitka-version: main + script-name: pslo_mini.pyw + onefile: true + standalone: true + disable-console: true + windows-icon-from-ico: ./icon/pslo_icon_mini.ico + macos-create-app-bundle: true + macos-app-icon: ./icon/pslo_icon_mini_mac.icns + + - name: Upload Artifacts + uses: actions/upload-artifact@v3 + with: + name: ${{ runner.os }} Build + path: | + build/*.exe + build/*.bin + build/*.app/**/* \ No newline at end of file diff --git a/README.md b/README.md index 4303100..34a8f0a 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,6 @@ # 🌐伪本地化演示程序 -新版即将推出,敬请期待~ - -新版截图👇 -![image](https://github.com/suntrise/Pseudo-localization-Demo/assets/89229642/128a04f0-cf92-4408-b74c-17d6ae7d66f8) - +![截图](https://user-images.githubusercontent.com/89229642/255376854-128a04f0-cf92-4408-b74c-17d6ae7d66f8.png) 这是一个伪本地化工具, 可用于某些本地化工作用途, 当然也可以作为一个玩具或者工具~ @@ -21,28 +17,56 @@ 网页版:https://suntrise.github.io/pseudo +> ⚠️ 注意, 早期基于PyQt5的1.x版本将在不久的未来移出仓库! + ## 👇使用 -如果您没有Python环境且比较懒, 可以移步Release下载, tar.gz版本适用于Linux, exe版本适用于Windows, 其他操作系统建议下载源码并执行 +如果您没有Python环境且比较懒, 可以移步[Release](https://github.com/suntrise/Pseudo-localization-Demo/releases)下载, tar.gz版本适用于Linux, exe版本适用于Windows, 其他操作系统建议下载源码并执行 (macOS版用户可以到[Actions页](https://github.com/suntrise/Pseudo-localization-Demo/actions)下载) 注意, 要在本地查看并修改源码, 需要安装Python, 版本最少为3.7以保障兼容性 ### 🚀依赖安装 -运行...[^1] +#### 🧩pip安装 (适用于嵌入式Python及未默认安装pip的Python) + +请先确定是否安装了`pip`, 如果已安装, 可以跳过这一步! + +- 如果已经提前安装了`easy_install`, 运行... + +~~~Bash +easy_inatall pip +~~~ + +- 使用Linux则可以通过自带的包管理器安装`python3-pip` + +- 啥也没有的话则运行...[^1] + +~~~Bash +curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py +python get-pip.py +~~~ + +完成后可以运行`pip`进行测试 + +#### 🗿正式依赖安装 + +运行...[^2] ~~~Bash pip install flet pip install pyperclip +pip install requests ~~~ -若要使用或编辑Mini, 还需额外执行... +特定版本若要使用或编辑Mini, 还需额外执行... ~~~Bash pip install fleter ~~~ -以上如果嫌一个一个来麻烦,可以直接执行.. +如果代码文件为最新版,则**不用执行该命令**! + +以上如果嫌一个一个来麻烦,可以直接执行... ~~~Bash pip install -r requirements.txt @@ -60,6 +84,8 @@ pip install PyQt5 ### 🛠️编译 +注意, Windows平台请先安装好MSVC编译工具或者MinGW, 其他平台也请准备好GCC! + #### Pyinstaller (简单) 运行...... @@ -75,7 +101,7 @@ pip install pyinstaller pyinstaller pslo.pyw -F -w -i ./icon/slo_icon.ico ~~~ -Mini版则执行 +Mini版则执行...... ~~~Bash pyinstaller pslo_mini.pyw -F -w -i ./icon/pslo_icon.ico @@ -93,7 +119,7 @@ pyinstaller pslo_mini.pyw -F -w -i ./icon/pslo_icon.ico pip install nuitka ~~~ -定位到代码根目录, 运行......[^2] +定位到代码根目录, 运行......[^3] ~~~Bash nuitka pslo.pyw --onefile --windows-disable-console --windows-icon-from-ico=./icon/pslo_icon.ico --standalone --show-progress @@ -133,20 +159,24 @@ chmod +x [编译后文件名].bin [flet-dev/flet](https://github.com/flet-dev/flet) +[pypi/fleter](https://pypi.org/project/fleter) (最新版本已弃用) + [asweigart/pyperclip](https://github.com/asweigart/pyperclip) ### 1.x -[Riverbank Computing PyQt5](https://www.riverbankcomputing.com/software/pyqt/) +[pypi/PyQt5](https://pypi.org/project/PyQt5/) ## 📄许可协议 -使用**WTFPL**许可协议开源[^3], 你想干嘛就干嘛 +使用**WTFPL**许可协议开源[^4], 你想干嘛就干嘛 ![WTFPL](http://www.wtfpl.net/wp-content/uploads/2012/12/wtfpl-badge-1.png) -[^1]: 部分系统可能要将`pip`改为`pip3` +[^1]: 部分平台没有`curl`指令, 可以用`wget`或者其他方式获取安装脚本 + +[^2]: 部分系统可能要将`pip`改为`pip3`, 如果有多个Python3, 数字可能需要具体到版本号, 如`pip3.11` -[^2]: 部分系统可能要将`nuitka`改为`nuitka3` +[^3]: 部分系统可能要将`nuitka`改为`nuitka3`, 尚不清楚是否需要和`pip`一样具体到版本号 -[^3]: 或许可以解释为**W**indows **T**iny **F**orm **P**seudo-**L**ocalization +[^4]: 或许可以解释为**W**indows **T**iny **F**orm **P**seudo-**L**ocalization diff --git a/lib/basic_info.py b/lib/basic_info.py index 64620b3..4974b5c 100644 --- a/lib/basic_info.py +++ b/lib/basic_info.py @@ -1,5 +1,7 @@ +from lib import log # 日志输出库 + # 预备输出 -print("\033[0;34m[INFO] Basic Information ready...\033[0m") +log.out(0, "Basic Information ready...") # 基本信息 ver = "v4.5p" @@ -9,11 +11,25 @@ updmd = """ # 更新日志 (详见GitHub Releases) +## v4.5p - 2023.8.1 + +1. UI大改; +2. 优化了部分功能; +3. 检查更新API更换为KGithub; +4. [开发者]控制台日志输出优化; +5. 保存支持自动添加文件后缀; +6. 保存伪本地化内容时允许保留原文; +7. 修复了一些BUG. + +## v4.2.1p - 2023.7.17 + +1. 细节优化. + ## v4.2p - 2023.7.15 1. 修复了一些BUG; 2. 界面更新; -3. 仓库置顶; +3. 新增窗口置顶; 3. 细节优化. ## v4.1.1p - 2023.7.14 @@ -27,14 +43,6 @@ 2. 历史记录页面更新; 3. 新增隐藏控制字符; 4. 细节优化. - -## v4.0.2p - 2023.7.9 - -1. 修复了一些BUG. - -# v4.0.1p - 2023.7.4 - -1. 细节优化. """ # 定义内容 @@ -59,4 +67,4 @@ - https://zhuanlan.zhihu.com/p/613293858 """ -about_text = "伪本地化演示程序 " + ver + "\n开发者: " + author +"\n贡献者、使用到的第三方项目详见 GitHub 项目仓库\n(https://github.com/suntrise/Pseudo-localization-Demo)" +about_text = "伪本地化演示程序 " + ver + "\n开发者: " + author +"\n贡献者、使用到的第三方项目详见 GitHub 项目仓库\n(https://github.com/suntrise/Pseudo-localization-Demo)\nMade with ❤ for YOU!\n使用WTFPL许可协议开源 (不涉及使用到的第三方库)" diff --git a/lib/config_li.py b/lib/config_li.py index 8934911..48545df 100644 --- a/lib/config_li.py +++ b/lib/config_li.py @@ -1,10 +1,11 @@ from config import * +from lib import log # 日志输出库 import json # 尚未完成 WIP # 预备输出 -print("\033[0;34m[INFO] Config Read and Write Module ready...\033[0m") +log.out(0, "Config Read and Write Module ready...") # 读取配置文件 def read_config(): diff --git a/lib/controls.py b/lib/controls.py new file mode 100644 index 0000000..30a81af --- /dev/null +++ b/lib/controls.py @@ -0,0 +1,90 @@ +import flet +from flet import * +from flet import icons +from lib import log # 日志输出库 + +# 预备输出 +log.out(0, "Advanced Controls Module ready...") + +# 窗口顶栏, 基于Fleter库制作, MIT协议 +def CLOSE_ID(page: flet.Page): + page.window_close() + page.close_in_app_web_view() + +def MAXIMIZE_ID(page: flet.Page): + if page.window_maximized: + page.window_maximized = False + elif not page.window_maximized: + page.window_maximized = True + page.update() + +def MINIMIZE_ID(page: flet.Page): + page.window_minimized = True + page.update() + +class CloseButton(IconButton): + __name__ = "controls.CloseButton" + + def __init__(self, + page: flet.Page, + icon = icons.CLOSE_ROUNDED, + on_click=None, + ): + super(CloseButton, self).__init__(icon = icon) + + self._page = page + + if on_click is None: + self.on_click = lambda _: self.close() + + def close(self): + CLOSE_ID(self._page) + + +class MaximizeButton(IconButton): + __name__ = "controls.MaximizeButton" + + def __init__(self, + page: flet.Page, + icon = icons.ZOOM_OUT_MAP_ROUNDED, + icon_max = icons.ZOOM_IN_MAP_ROUNDED, + on_click = None, + ): + super(MaximizeButton, self).__init__(icon = icon, icon_size = 20) + + self._page = page + + self._icon = icon + self._icon_max = icon_max + + if on_click is None: + self.on_click = lambda _: self.maximize() + + def maximize(self): + if self._page.window_maximized: + self.icon = self._icon + elif not self._page.window_maximized: + self.icon = self._icon_max + MAXIMIZE_ID(self._page) + self._page.update() + + +class MinimizeButton(IconButton): + __name__ = "controls.MinimizeButton" + + def __init__(self, + page: flet.Page, + icon = icons.MINIMIZE_ROUNDED, + on_click = None, + ): + super(MinimizeButton, self).__init__(icon = icon) + + self._page = page + + if on_click is None: + self.on_click = lambda _: self.minimize() + + def minimize(self): + self._page.window_minimized = True + MINIMIZE_ID(self._page) + self._page.update() \ No newline at end of file diff --git a/lib/log.py b/lib/log.py new file mode 100644 index 0000000..88d6920 --- /dev/null +++ b/lib/log.py @@ -0,0 +1,12 @@ +import datetime + +# 日志 +def out(cata, info): + if cata == 0: + print("\033[0;34mINFO\033[0m | " + datetime.datetime.now().strftime('%H:%M:%S') + " | " + info) + elif cata == 1: + print("\033[0;32mDONE\033[0m | " + datetime.datetime.now().strftime('%H:%M:%S') + " | " + info) + elif cata == 2: + print("\033[0;31mERROR\033[0m | " + datetime.datetime.now().strftime('%H:%M:%S') + " | " + info) + elif cata == 3: + print("\033[0;33mWARN\033[0m | " + datetime.datetime.now().strftime('%H:%M:%S') + " | " + info) \ No newline at end of file diff --git a/lib/platform_check.py b/lib/platform_check.py index 8e3c1a5..7e75a6e 100644 --- a/lib/platform_check.py +++ b/lib/platform_check.py @@ -1,19 +1,20 @@ import sys +from lib import log # 日志输出库 # 预备输出 -print("\033[0;34m[INFO] OS Platform Module ready...\033[0m") +log.out(0, "OS Platform Module ready...") # 平台检查 def os_platform(): if sys.platform.startswith('linux'): - print("\033[0;34m[INFO] OS is Linux\033[0m") + log.out(0, "Current OS is Linux") return "linux" elif sys.platform.startswith('win'): - print("\033[0;34m[INFO] OS is Windows\033[0m") + log.out(0, "Current OS is Windows") return "windows" elif sys.platform.startswith('darwin'): - print("\033[0;34m[INFO] OS is darwin(macOS)\033[0m") + log.out(0, "Current OS is darwin(macOS)") return "darwin" else: - print("\033[0;34m[INFO] Unknow OS\033[0m") + log.out(0, "Unknow OS") return "unknow" \ No newline at end of file diff --git a/lib/pslo_work.py b/lib/pslo_work.py index b4791b5..b5e6063 100644 --- a/lib/pslo_work.py +++ b/lib/pslo_work.py @@ -1,7 +1,8 @@ import random +from lib import log # 日志输出库 # 预备输出 -print("\033[0;34m[INFO] PSLO Translate Module ready...\033[0m") +log.out(0, "PSLO Translate Module ready...") # 变量初始化 suf = "" @@ -71,6 +72,7 @@ arr0 = ["0", "₀", "⁰"] arral = ["A", "a", "B", "b", "C", "c", "D", "d", "E", "e", "F", "f", "G", "g", "H", "h", "I", "i", "J", "j", "K", "k", "L", "l", "M", "m", "N", "n", "O", "o", "P", "p", "Q", "q", "R", "r", "S", "s", "T", "t", "U", "u", "V", "v", "W", "w", "X", "x", "Y", "y", "Z", "z", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0"] arrba = ["one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen", "twenty"] +arrnum = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "0"] # 伪本地化 def pslo(pstype, xab, num_pslo, vowel_cs, suf_way, cus_pre, cus_suf,cus_re, cus_cs, hash_cb, hash_ws, vis_con_cb): @@ -78,7 +80,7 @@ def pslo(pstype, xab, num_pslo, vowel_cs, suf_way, cus_pre, cus_suf,cus_re, cus_ m = 0 n = 0 v = "" - print("\033[0;34m[INFO] Pseudo-localization initialization completed\033[0m") + log.out(0, "Pseudo-localization initialization completed") pstr = pstype res = '' control_txt = False @@ -86,6 +88,7 @@ def pslo(pstype, xab, num_pslo, vowel_cs, suf_way, cus_pre, cus_suf,cus_re, cus_ if xab != "enxb": xab = "enxa" for l in pstr: + # 基本定义及控制 i += 1 if control_txt == True: control_txt = False @@ -98,40 +101,48 @@ def pslo(pstype, xab, num_pslo, vowel_cs, suf_way, cus_pre, cus_suf,cus_re, cus_ if l == "\\" and pstr[i] == "n": control_txt = True continue + if l == "\\" and pstr[i] == "r": + control_txt = True + continue + # 基本字母伪本地化 + al = l.replace('a',random.choice(arra)).replace('A',random.choice(arraa)).replace('b',random.choice(arrb)).replace('B',random.choice(arrbb)).replace('c',random.choice(arrc)).replace('C',random.choice(arrcc)).replace('d',random.choice(arrd)).replace('D',random.choice(arrdd)).replace('e',random.choice(arre)).replace('E',random.choice(arree)).replace('f',random.choice(arrf)).replace('F',random.choice(arrff)).replace('g',random.choice(arrg)).replace('G',random.choice(arrgg)).replace('h',random.choice(arrh)).replace('H',random.choice(arrhh)).replace('i',random.choice(arri)).replace('I',random.choice(arrii)).replace('j',random.choice(arrj)).replace('J',random.choice(arrjj)).replace('k',random.choice(arrk)).replace('K',random.choice(arrkk)).replace('l',random.choice(arrl)).replace('L',random.choice(arrll)).replace('m',random.choice(arrm)).replace('M',random.choice(arrmm)).replace('n',random.choice(arrn)).replace('N',random.choice(arrnn)).replace('o',random.choice(arro)).replace('O',random.choice(arroo)).replace('p',random.choice(arrp)).replace('P',random.choice(arrpp)).replace('q',random.choice(arrq)).replace('Q',random.choice(arrqq)).replace('r',random.choice(arrr)).replace('R',random.choice(arrrr)).replace('s',random.choice(arrs)).replace('S',random.choice(arrss)).replace('t',random.choice(arrt)).replace('T',random.choice(arrtt)).replace('u',random.choice(arru)).replace('U',random.choice(arruu)).replace('v',random.choice(arrv)).replace('V',random.choice(arrvv)).replace('w',random.choice(arrw)).replace('W',random.choice(arrww)).replace('x',random.choice(arrx)).replace('X',random.choice(arrxx)).replace('y',random.choice(arry)).replace('Y',random.choice(arryy)).replace('z',random.choice(arrz)).replace('Z',random.choice(arrzz)) # 数字伪本地化判断 if num_pslo == "2": - al = l.replace('a',random.choice(arra)).replace('A',random.choice(arraa)).replace('b',random.choice(arrb)).replace('B',random.choice(arrbb)).replace('c',random.choice(arrc)).replace('C',random.choice(arrcc)).replace('d',random.choice(arrd)).replace('D',random.choice(arrdd)).replace('e',random.choice(arre)).replace('E',random.choice(arree)).replace('f',random.choice(arrf)).replace('F',random.choice(arrff)).replace('g',random.choice(arrg)).replace('G',random.choice(arrgg)).replace('h',random.choice(arrh)).replace('H',random.choice(arrhh)).replace('i',random.choice(arri)).replace('I',random.choice(arrii)).replace('j',random.choice(arrj)).replace('J',random.choice(arrjj)).replace('k',random.choice(arrk)).replace('K',random.choice(arrkk)).replace('l',random.choice(arrl)).replace('L',random.choice(arrll)).replace('m',random.choice(arrm)).replace('M',random.choice(arrmm)).replace('n',random.choice(arrn)).replace('N',random.choice(arrnn)).replace('o',random.choice(arro)).replace('O',random.choice(arroo)).replace('p',random.choice(arrp)).replace('P',random.choice(arrpp)).replace('q',random.choice(arrq)).replace('Q',random.choice(arrqq)).replace('r',random.choice(arrr)).replace('R',random.choice(arrrr)).replace('s',random.choice(arrs)).replace('S',random.choice(arrss)).replace('t',random.choice(arrt)).replace('T',random.choice(arrtt)).replace('u',random.choice(arru)).replace('U',random.choice(arruu)).replace('v',random.choice(arrv)).replace('V',random.choice(arrvv)).replace('w',random.choice(arrw)).replace('W',random.choice(arrww)).replace('x',random.choice(arrx)).replace('X',random.choice(arrxx)).replace('y',random.choice(arry)).replace('Y',random.choice(arryy)).replace('z',random.choice(arrz)).replace('Z',random.choice(arrzz)).replace('1',random.choice(arr1)).replace('2',random.choice(arr2)).replace('3',random.choice(arr3)).replace('4',random.choice(arr4)).replace('5',random.choice(arr5)).replace('6',random.choice(arr6)).replace('7',random.choice(arr7)).replace('8',random.choice(arr8)).replace('9',random.choice(arr9)).replace('0',random.choice(arr0)) + al = l.replace('1',random.choice(arr1)).replace('2',random.choice(arr2)).replace('3',random.choice(arr3)).replace('4',random.choice(arr4)).replace('5',random.choice(arr5)).replace('6',random.choice(arr6)).replace('7',random.choice(arr7)).replace('8',random.choice(arr8)).replace('9',random.choice(arr9)).replace('0',random.choice(arr0)) elif num_pslo == "1": - al = l.replace('a',random.choice(arra)).replace('A',random.choice(arraa)).replace('b',random.choice(arrb)).replace('B',random.choice(arrbb)).replace('c',random.choice(arrc)).replace('C',random.choice(arrcc)).replace('d',random.choice(arrd)).replace('D',random.choice(arrdd)).replace('e',random.choice(arre)).replace('E',random.choice(arree)).replace('f',random.choice(arrf)).replace('F',random.choice(arrff)).replace('g',random.choice(arrg)).replace('G',random.choice(arrgg)).replace('h',random.choice(arrh)).replace('H',random.choice(arrhh)).replace('i',random.choice(arri)).replace('I',random.choice(arrii)).replace('j',random.choice(arrj)).replace('J',random.choice(arrjj)).replace('k',random.choice(arrk)).replace('K',random.choice(arrkk)).replace('l',random.choice(arrl)).replace('L',random.choice(arrll)).replace('m',random.choice(arrm)).replace('M',random.choice(arrmm)).replace('n',random.choice(arrn)).replace('N',random.choice(arrnn)).replace('o',random.choice(arro)).replace('O',random.choice(arroo)).replace('p',random.choice(arrp)).replace('P',random.choice(arrpp)).replace('q',random.choice(arrq)).replace('Q',random.choice(arrqq)).replace('r',random.choice(arrr)).replace('R',random.choice(arrrr)).replace('s',random.choice(arrs)).replace('S',random.choice(arrss)).replace('t',random.choice(arrt)).replace('T',random.choice(arrtt)).replace('u',random.choice(arru)).replace('U',random.choice(arruu)).replace('v',random.choice(arrv)).replace('V',random.choice(arrvv)).replace('w',random.choice(arrw)).replace('W',random.choice(arrww)).replace('x',random.choice(arrx)).replace('X',random.choice(arrxx)).replace('y',random.choice(arry)).replace('Y',random.choice(arryy)).replace('z',random.choice(arrz)).replace('Z',random.choice(arrzz)).replace('1','①').replace('2','②').replace('3','③').replace('4','④').replace('5','⑤').replace('6','⑥').replace('7','⑦').replace('8','⑧').replace('9','⑨') - else: - al = l.replace('a',random.choice(arra)).replace('A',random.choice(arraa)).replace('b',random.choice(arrb)).replace('B',random.choice(arrbb)).replace('c',random.choice(arrc)).replace('C',random.choice(arrcc)).replace('d',random.choice(arrd)).replace('D',random.choice(arrdd)).replace('e',random.choice(arre)).replace('E',random.choice(arree)).replace('f',random.choice(arrf)).replace('F',random.choice(arrff)).replace('g',random.choice(arrg)).replace('G',random.choice(arrgg)).replace('h',random.choice(arrh)).replace('H',random.choice(arrhh)).replace('i',random.choice(arri)).replace('I',random.choice(arrii)).replace('j',random.choice(arrj)).replace('J',random.choice(arrjj)).replace('k',random.choice(arrk)).replace('K',random.choice(arrkk)).replace('l',random.choice(arrl)).replace('L',random.choice(arrll)).replace('m',random.choice(arrm)).replace('M',random.choice(arrmm)).replace('n',random.choice(arrn)).replace('N',random.choice(arrnn)).replace('o',random.choice(arro)).replace('O',random.choice(arroo)).replace('p',random.choice(arrp)).replace('P',random.choice(arrpp)).replace('q',random.choice(arrq)).replace('Q',random.choice(arrqq)).replace('r',random.choice(arrr)).replace('R',random.choice(arrrr)).replace('s',random.choice(arrs)).replace('S',random.choice(arrss)).replace('t',random.choice(arrt)).replace('T',random.choice(arrtt)).replace('u',random.choice(arru)).replace('U',random.choice(arruu)).replace('v',random.choice(arrv)).replace('V',random.choice(arrvv)).replace('w',random.choice(arrw)).replace('W',random.choice(arrww)).replace('x',random.choice(arrx)).replace('X',random.choice(arrxx)).replace('y',random.choice(arry)).replace('Y',random.choice(arryy)).replace('z',random.choice(arrz)).replace('Z',random.choice(arrzz)) + al = l.replace('1','①').replace('2','②').replace('3','③').replace('4','④').replace('5','⑤').replace('6','⑥').replace('7','⑦').replace('8','⑧').replace('9','⑨') # 元音复重复 if l.lower() in "aeiou": al = al * (int(vowel_cs) + 1) res += al - print("\033[0;34m[INFO] Number of pseudo-localization work cycles: " + str(i) + "\033[0m") - print("\033[0;34m[INFO] Digital pseudo-localization program: " + str(num_pslo) + "\033[0m") - print("\033[0;34m[INFO] Number of vowel repetitions: " + str(vowel_cs) + "\033[0m") + log.out(0, "Number of pseudo-localization work cycles: " + str(i)) + log.out(0, "Digital pseudo-localization program: " + str(num_pslo)) + log.out(0, "Number of vowel repetitions: " + str(vowel_cs)) if xab == "enxb": # 使用en-XB for l in pstr: i += 1 res = pstr[::-1] - print("\033[0;34m[INFO] Pseudo-localization solutions: " + xab + "\033[0m") + log.out(0, "Pseudo-localization solutions: " + xab) # 前后缀添加 suf = "" if suf_way == "1": - while i > 2 and n < (i/7): - suf = suf+"!" + while i > 2 and n < (i / 7): + suf = suf + "!" n += 1 - if n % 3 == 0 & n != int(i/7+1): + if n % 3 == 0 & n != int(i / 7+1): suf = suf+" " - res = "["+ res +" " +suf +"]"; + res = "[" + res + " " + suf + "]"; elif suf_way == "2": - while n<(i/7): + while n < (i / 7): suf = suf + arrba[n % 20]+" " n += 1 - res = "[" + res + " " + suf + "]"; + res = "[" + res + " " + suf + "]" + elif suf_way == "4": + while n < (i / 3): + suf = suf + arrnum[n % 10] + n += 1 + res = "[" + res + " " + suf + "]" elif suf_way == "3": while n < (i / int(cus_cs)): suf = suf + cus_re + " " @@ -140,23 +151,23 @@ def pslo(pstype, xab, num_pslo, vowel_cs, suf_way, cus_pre, cus_suf,cus_re, cus_ n = 0 suf = "" - print("\033[0;34m[INFO] Prefix & suffix addition scheme: " + str(suf_way) + "\033[0m") + log.out(0, "Prefix & suffix addition scheme: " + str(suf_way)) # 添加Hash ID if hash_cb == True: - print("\033[0;34m[INFO] Add Hash ID: True\033[0m") + log.out(0, "Add Hash ID: True") hash_id = "" while m < int(hash_ws): hash_id = hash_id + random.choice(arral) m += 1 - print("\033[0;34m[INFO] Number of Hash ID bits: " + str(hash_ws) + "\033[0m") + print("\03[\033[0;34mINFO\033[0m] Number of Hash ID bits: " + str(hash_ws)) res = "[" + hash_id + "]" + res hash_id = "" m = 0 else: - print("\033[0;34m[INFO] Add Hash ID: False\033[0m") + log.out(0, "Add Hash ID: False") output = res - print("\033[0;34m[INFO] Result: " + output + "\033[0m") + log.out(0, "Result: " + output) return output - print("\033[0;32m[DONE] Pseudo-localization completed\033[0m") \ No newline at end of file + log.out(1, "Pseudo-localization completed") \ No newline at end of file diff --git a/lib/update.py b/lib/update.py index ac61a55..b392c38 100644 --- a/lib/update.py +++ b/lib/update.py @@ -1,12 +1,14 @@ import requests +from lib import log # 日志输出库 from lib import platform_check # 预备输出 -print("\033[0;34m[INFO] PSLO Update Module ready...\033[0m") +log.out(0, "PSLO Update Module ready...") # 全局化变量 -api = "" -all_info = "" +global api +global all_info +global latest_ver # 获取系统平台 sys_platform = platform_check.os_platform() @@ -15,59 +17,64 @@ def update_api(): # API定义 global api - api = requests.get("https://api.github.com/repos/suntrise/Pseudo-localization-Demo/releases", timeout = 10, verify = False) # SSL禁用 - print("\033[0;34m[INFO] API Update\033[0m") + api = requests.get("https://api.kgithub.com/repos/suntrise/Pseudo-localization-Demo/releases", timeout = 10, verify = False) # SSL禁用 + log.out(0, "API Update") global all_info all_info = api.json() # 获取Json - print("\033[0;34m[INFO] API infomation get\033[0m") + log.out(0, "API infomation get") + +# 版本检查 +def version_check(ver): + update_api() + global latest_ver + latest_ver = all_info[0]['tag_name'] # 获取最新版本 + log.out(0, "Versions in the server" + latest_ver) + log.out(0, "Comparing versions...\033[0m") + if ver == latest_ver: + return False + else: + return True # 更新程序 def update(ver): # 主体 update_api() - print("\033[0;34m[INFO] Testing...\033[0m") + log.out(0, "Testing...") try: response = api.text # 用于是否可以链接Github - print("\033[0;34m[INFO] Get API information\033[0m") - custom_ver = all_info[0]['name'] # 获取最新版本 - print("\033[0;34m[INFO] Versions in the server" + custom_ver + "\033[0m") - print("\033[0;34m[INFO] Comparing versions...\033[0m") - if custom_ver == ver: - print("\033[0;32m[DONE] You are using the latest version\033[0m") + if version_check(ver) == False: + log.out(0, "You are using the latest version") return "NUL" else: - print("\033[0;34m[INFO] Getting the change log...\033[0m") + log.out(0, "Getting the change log...\033[0m") detail = all_info[0]['body'] # 获取更新日志 - print("\033[0;34m[INFO] Change log: " + detail + "\033[0m") - # print("\033[0;34m[INFO] Getting the publish time...\033[0m") - # publish_date_utc = all_info[0]['published_at'] # 获取更新日期 - # print("\033[0;34m[INFO] Publish time: " + publish_date_utc + "\033[0m") - print("\033[0;34m[INFO] Checking if it is a pre-release version...\033[0m") + log.out(0, "Change log: " + detail) + log.out(0, "Checking if it is a pre-release version...") prerelease = all_info[0]['prerelease'] # 获取是否为预览版本 prerelease_content = "" if prerelease == "false": prerelease_content = "\n \r## 注意\n \r 本版本为预发布版本, 可能存在稳定性问题!" # 内容添加 - print("\033[0;34m[INFO] " + custom_ver + "is a pre-release version\033[0m") + log.out(0, "" + latest_ver + "is a pre-release version") sc_content = "" - if sys_platform == "darwin" or sys_platform == "unknow": - sc_content = "\n \r## 源代码须知\n \r 您似乎在使用macOS或其他操作系统, 我们没有给这些系统编译二进制文件, 所以我们为您直接提供源代码" # 内容添加 - # upd_content = "- 当前版本: " + ver + "\n \r- 新版本: " + custom_ver + "\n \r## 详细信息\n \r" + detail + "\n \r## 发布日期\n \r" + publish_date_utc + prerelease_content + sc_content # 弹窗内容 - upd_content = "- 当前版本: " + ver + "\n \r- 新版本: " + custom_ver + "\n \r## 详细信息\n \r" + detail + prerelease_content + sc_content # 弹窗内容 + if sys_platform == "darwin": + sc_content = "\n \r## 兼容性须知\n \r 您似乎在使用macOS, \n \r我们使用了CI/CD编译适用于macOS的版本, 由于没有测试设备, 可能存在稳定性问题" # 内容添加 + elif sys_platform == "unknow": + sc_content = "\n \r## 源代码须知\n \r 您似乎在使用未知的擦偶哦在系统, \n \r我们为您提供了源代码包而非二进制, 注意查收!" # 内容添加 + upd_content = "- 当前版本: " + ver + "\n \r- 新版本: " + latest_ver + "\n \r## 详细信息\n \r" + detail + prerelease_content + sc_content # 弹窗内容 return upd_content except requests.exceptions.RequestException as e: - print("\033[0;31m[ERROR] Check for update failure\033[0m") + log.out(2, "Check for update failure") return "ERR" # 获取下载链接 def get_link(): - assets = all_info[0]['assets'] - print("\033[0;34m[INFO] Getting the download link...\033[0m") - if sys_platform == "windows": - download_url = assets[0]['browser_download_url'] # 获取下载链接 - elif sys_platform == "linux": - download_url = assets[1]['browser_download_url'] + if sys_platform == "windows" or sys_platform == "linux": + download_url = "https://github.com/suntrise/Pseudo-localization-Demo/releases" + elif sys_platform == "darwin": + download_url = "https://github.com/suntrise/Pseudo-localization-Demo/actions" else: + log.out(0, "Getting the download link...") download_url = all_info[0]['tarball_url'] - print("\033[0;34m[INFO] It is seem that you are using macOS or any other OS, so we provide the source code of the program(tar)\033[0m") - print("\033[0;34m[INFO] Link: " + download_url + "\033[0m") + log.out(0, "It is seem that you are using BSD or any other OS, so we provide the source code of the program (tar)") + log.out(0, "Link: " + download_url) return download_url \ No newline at end of file diff --git a/pslo.pyw b/pslo.pyw index 88eaa48..9fa1d43 100644 --- a/pslo.pyw +++ b/pslo.pyw @@ -1,11 +1,12 @@ import flet as ft # 界面库 -import fleter import pyperclip # 复制库 import webbrowser # 浏览器链接库 import sys # 系统库 import datetime # 日期时间库 +from lib import log # 日志输出库 from lib import pslo_work # 工作模块 from lib import update # 更新模块 +from lib import controls # 组件拓展库 from lib import basic_info # 基础信息 # from lib import config_li # 写入配置库, 尚未完成 @@ -13,27 +14,28 @@ from lib import basic_info # 基础信息 # 变量初始化 pshis = "" -print('\033[0;34m[INFO] Python version: {}\033[0m'.format(sys.version)) -print("\033[0;34m[INFO] PSLO version: " + basic_info.ver + "\033[0m") -# 主程序 +# 基本输出 +log.out(0, "Python version: " + sys.version) +log.out(0, "PSLO version: " + basic_info.ver) + # 主程序 def main(page: ft.Page): # 字符相隔位数是否数字确定 def ccs_check(e): if cus_cs.value.isdigit() == False: cus_cs.value = 7; - print("\033[0;34m[INFO] Set the CUS value to 7\033[0m") + log.out(0, "Set the CUS value to 7. Content: " + str(cus_cs.value)) page.update() # 是否显示前后缀配置栏 def psf_check(e): if suf_way.value == "3": cus_ps.visible = True - print("\033[0;34m[INFO] CUS Toolbar visible is true\033[0m") + log.out(0, "CUS Toolbar visible is true") else: cus_ps.visible = False - print("\033[0;34m[INFO] CUS Toolbar visible is false\033[0m") + log.out(0, "CUS Toolbar visible is false") page.update() # 原pslo函数已迁移至lib/pslo_work.py @@ -42,28 +44,28 @@ def main(page: ft.Page): def pslo(e): global pshis page.result.value = pslo_work.pslo(page.pstype.value, xab.value, num_pslo.value, vowel_cs.value, suf_way.value, cus_pre.value, cus_suf.value, cus_re.value, cus_cs.value, hash_cb.value, hash_ws.value, vis_con_cb.value) - pshis += page.pstype.value + " → " + page.result.value +" | " + datetime.datetime.now().strftime('%H:%M:%S') + "\n" # 添加到历史记录 - history.value = pshis - print("\033[0;32m[DONE] Added content to history\033[0m") + pshis += page.pstype.value + " → " + page.result.value + " | " + datetime.datetime.now().strftime('%H:%M:%S') + "\n————————————————————————————————————\n" + history.value = pshis # 添加到历史记录 + log.out(1, "Added content to history") page.update() # 复制文本 def copy_text(e): pyperclip.copy(page.result.value) - print("\033[0;32m[DONE] Added to clipboard\033[0m") + log.out(1, "Added to clipboard") page.snack_bar = ft.SnackBar(ft.Text(f"已复制")) # 提示栏 page.snack_bar.open = True page.update() - print("\033[0;34m[INFO] Snack bar pop-up(CP)\033[0m") + log.out(0, "Snack bar pop-up(CP)\033[0m") # 复制历史记录 def copy_history(e): pyperclip.copy(history.value) - print("\033[0;32m[DONE] Added history to clipboard\033[0m") + print("\033[\033[0;32mDONE\033[0m] Added history to clipboard") page.snack_bar = ft.SnackBar(ft.Text(f"已复制历史记录")) # 提示栏 page.snack_bar.open = True page.update() - print("\033[0;34m[INFO] Snack bar pop-up(CPH)\033[0m") + log.out(0, "Snack bar pop-up(CPH)") # 导入文件 def ps_files(e: ft.FilePickerResultEvent): @@ -72,52 +74,70 @@ def main(page: ft.Page): page.snack_bar = ft.SnackBar(ft.Text("检测到文件: " + psfile)) # 提示栏 page.snack_bar.open = True page.update() - print("\033[0;34m[INFO] Snack bar pop-up(UL)\033[0m") + log.out(0, "Snack bar pop-up(UL)") with open(psfile, encoding = 'utf-8') as psf: page.pstype.value = psf.read() - print("\033[0;32m[DONE] TXT:" + psf.read() + "\033[0m") + log.out(1, "TXT:" + psf.read()) pslo(e) else: page.snack_bar = ft.SnackBar(ft.Text("未检测到文件")) # 提示栏 page.snack_bar.open = True page.update() - print("\033[0;34m[INFO] Snack bar pop-up(UF)\033[0m") + log.out(0, "Snack bar pop-up(UF)") page.update() # 导出文件 def sv_files(e: ft.FilePickerResultEvent): + close_svw(e) svfile = e.path if e.path else "ERR" - if sv_files != "ERR": - page.snack_bar = ft.SnackBar(ft.Text("已保存至: " + svfile)) # 提示栏 + if svfile != "ERR": + svfile_final = "" + if str(svfile)[-4:] != ".txt": + svfile_final = str(svfile) + ".txt" + log.out(0, "Add .txt after filename") + else: + svfile_final = str(svfile) + log.out(0, "No action with the filename") + page.snack_bar = ft.SnackBar(ft.Text("已保存至: " + svfile_final)) # 提示栏 page.snack_bar.open = True page.update() - print("\033[0;34m[INFO] Snack bar pop-up(SV)\033[0m") - with open(svfile, "a", encoding = 'utf-8') as svf: - svf.write(page.result.value) - print("\033[0;32m[DONE] File saved:" + str(svfile) + "\033[0m") + log.out(0, "Snack bar pop-up(SV)") + with open(svfile_final, "a", encoding = 'utf-8') as svf: + if save_way_dd.value == 0: + svf.write(page.result.value) + log.out(0, "Only save pseudo-localized text") + else: + svf.write(page.pstype.value + "\n" + page.result.value) + log.out(0, "Save original text and pseudo-localized text") + log.out(1, "File saved:" + str(svfile_final)) else: page.snack_bar = ft.SnackBar(ft.Text("发生错误, 不是合法的路径")) # 提示栏 page.snack_bar.open = True page.update() - print("\033[0;34m[INFO] Snack bar pop-up(SVE)\033[0m") + log.out(0, "Snack bar pop-up(SVE)") page.update() # 导出历史记录 def sv_his(e: ft.FilePickerResultEvent): svhis = e.path if e.path else "ERR" if svhis != "ERR": - page.snack_bar = ft.SnackBar(ft.Text("已保存至: " + svhis)) # 提示栏 + svhis_final = "" + if str(svhis)[-4:] != ".txt": + svhis_final = str(svhis) + ".txt" + else: + svhis_final = str(svhis) + page.snack_bar = ft.SnackBar(ft.Text("已保存至: " + svhis_final)) # 提示栏 page.snack_bar.open = True page.update() - print("\033[0;34m[INFO] Snack bar pop-up(SVH)\033[0m") - with open(svhis, "a", encoding = 'utf-8') as svh: + log.out(0, "Snack bar pop-up(SVH)") + with open(svhis_final, "a", encoding = 'utf-8') as svh: svh.write(history.value) - print("\033[0;32m[DONE] File saved:" + str(svhis) + "\033[0m") + log.out(0, "File saved:" + str(svhis_final)) else: page.snack_bar = ft.SnackBar(ft.Text("发生错误, 不是合法的路径")) # 提示栏 page.snack_bar.open = True page.update() - print("\033[0;34m[INFO] Snack bar pop-up(SHE)\033[0m") + log.out(0, "Snack bar pop-up(SHE)") page.update() # 清除历史记录 @@ -125,20 +145,20 @@ def main(page: ft.Page): close_chq(e) pshis = "" history.value = "无记录" - print("\033[0;32m[DONE] History is cleared\033[0m") + log.out(1, "History is cleared") page.snack_bar = ft.SnackBar(ft.Text(f"已清空")) # 提示栏 page.snack_bar.open = True page.update() - print("\033[0;34m[INFO] Snack bar pop-up(CH)\033[0m") + log.out(0, "Snack bar pop-up(CH)") # Hash输入框解禁 def hash_check(e): if hash_cb.value == True: hash_ws.disabled = False - print("\033[0;34m[INFO] Hash ID text field is enable\033[0m") + log.out(0, "Hash ID text field is enable") else: hash_ws.disabled = True - print("\033[0;34m[INFO] Hash ID text field is disabled\033[0m") + log.out(0, "Hash ID text field is disabled") page.update() # Hash数值确认 @@ -146,13 +166,13 @@ def main(page: ft.Page): ws = hash_ws.value if str(ws).isdigit() == False: hash_ws.value = 5 - print("\033[0;34m[INFO] Set the Hash ID text field value to 5\033[0m") + log.out(0, "Set the Hash ID text field value to 5. Content: " + str(ws)) elif int(ws) < 3: hash_ws.value = 3 - print("\033[0;34m[INFO] The value is too small, has set the Hash ID text field value to 3\033[0m") + log.out(0, "The value is too small, has set the Hash ID text field value to 3. Content: " + str(ws)) elif int(ws) > 10: hash_ws.value = 10 - print("\033[0;34m[INFO] The value is too big, has set the Hash ID text field value to 10\033[0m") + log.out(0, "The value is too big, has set the Hash ID text field value to 10. Content: " + str(ws)) page.update() # 元音重复次数检测 @@ -160,13 +180,13 @@ def main(page: ft.Page): vcs = vowel_cs.value if str(vcs).isdigit() == False: vowel_cs.value = 0 - print("\033[0;34m[INFO] Set the Vowel repetition text field value to 0\033[0m") + log.out(0, "Set the Vowel repetition text field value to 0") elif int(vcs) < 0: vowel_cs.value = 0 - print("\033[0;34m[INFO] The value is too small, has set the Vowel repetition text field value to 0\033[0m") + log.out(0, "The value is too small, has set the Vowel repetition text field value to 0") elif int(vcs) > 10: vowel_cs.value = 10 - print("\033[0;34m[INFO] The value is too big, has set the Vowel repetition text field value to 10\033[0m") + log.out(0, "The value is too big, has set the Vowel repetition text field value to 10") page.update() # 明暗切换 @@ -175,94 +195,117 @@ def main(page: ft.Page): page.theme_mode = ( ft.ThemeMode.LIGHT # 亮色 ) - print("\033[0;32m[DONE] Switch to LIGHT\033[0m") + log.out(1, "Switch to LIGHT") if theme.value == "1": page.theme_mode = ( ft.ThemeMode.DARK # 暗黑 ) - print("\033[0;32m[DONE] Switch to DARK\033[0m") + log.out(1, "Switch to DARK") if theme.value == "2": page.theme_mode = ( ft.ThemeMode.SYSTEM # 系统 ) - print("\033[0;32m[DONE] Switch to SYSTEM\033[0m") + log.out(1, "Switch to SYSTEM") page.update() # 色彩选择 def sch_changed(e): sch = int(scheme.value) if sch == 0: - page.theme=ft.Theme(font_family = "Microsoft Yahei", + page.theme = ft.Theme(font_family = "Microsoft Yahei", color_scheme_seed = ft.colors.BLUE) # 蓝色 - print("\033[0;32m[DONE] Switch to color BLUE\033[0m") + log.out(1, "Switch to color BLUE") if sch == 1: - page.theme=ft.Theme(font_family = "Microsoft Yahei", + page.theme = ft.Theme(font_family = "Microsoft Yahei", color_scheme_seed = ft.colors.PINK) # 粉色 - print("\033[0;32m[DONE] Switch to color PINK\033[0m") + log.out(1, "Switch to color PINK") if sch == 2: - page.theme=ft.Theme(font_family = "Microsoft Yahei", + page.theme = ft.Theme(font_family = "Microsoft Yahei", color_scheme_seed = ft.colors.GREEN) # 绿色 - print("\033[0;32m[DONE] Switch to color GREEN\033[0m") + log.out(1, "Switch to color GREEN") if sch == 3: - page.theme=ft.Theme(font_family = "Microsoft Yahei", + page.theme = ft.Theme(font_family = "Microsoft Yahei", color_scheme_seed = ft.colors.BROWN) # 巧克力色 - print("\033[0;32m[DONE] Switch to color BROWN\033[0m") + log.out(1, "Switch to color BROWN") if sch == 4: - page.theme=ft.Theme(font_family = "Microsoft Yahei", + page.theme = ft.Theme(font_family = "Microsoft Yahei", color_scheme_seed = ft.colors.DEEP_PURPLE_100) # 紫色 - print("\033[0;32m[DONE] Switch to color DEEP_PURPLE\033[0m") + log.out(1, "Switch to color DEEP_PURPLE") page.update() # 透明度设置 def opacity_slider_changed(e): opac_value = page.opacity_slider.value / 100 page.window_opacity = opac_value - print("\033[0;32m[DONE] Window opacity: " + str(page.window_opacity) + "\033[0m") + log.out(1, "Window opacity: " + str(page.window_opacity)) + if opac_value <= 0.75: + opac_warn_bar.visible = True + else: + opac_warn_bar.visible = False page.update() # 打开网页版 - def open_with_browser(e): + def open_in_browser(e): webbrowser.open_new("https://suntrise.github.io/pseudo/") - print("\033[0;32m[DONE] Website open (OIB)\033[0m") + log.out(1, "Website open (OIB)") # 打开项目仓库 def open_project_repo(e): webbrowser.open_new("https://github.com/suntrise/Pseudo-localization-Demo") - print("\033[0;32m[DONE] Website open (OPR)\033[0m") + log.out(1, "Website open (OPR)") # 打开“什么是伪本地化”窗口 def open_what(e): page.dialog = what_dlg what_dlg.open = True - print("\033[0;32m[DONE] Dialog open(WHT)\033[0m") + log.out(1, "Dialog open(WHT)") page.update() - - # 关闭“什么是伪本地化”窗口 - def close_what(e): - what_dlg.open = False - print("\033[0;32m[DONE] Dialog close(WHT)\033[0m") - page.update() # 打开“确定清除历史记录”窗口 def open_chq(e): page.dialog = chq_dlg chq_dlg.open = True - print("\033[0;32m[DONE] Dialog open(CHQ)\033[0m") + log.out(1, "Dialog open(CHQ)") page.update() - # 关闭“确定清除历史记录”窗口 - def close_chq(e): - chq_dlg.open = False - print("\033[0;32m[DONE] Dialog close(CHQ)\033[0m") - page.update() + # 打开“保存方式”窗口 + def open_svw(e): + page.dialog = svw_dlg + svw_dlg.open = True + log.out(1, "Dialog open(SVW)") + page.update() - # 打开“更新日志”窗口 + # 打开“保存更新日志”窗口 def open_upd(e): page.dialog = upd_dlg upd_dlg.open = True - print("\033[0;32m[DONE] Dialog open(UPH)\033[0m") + log.out(1, "Dialog open(UPD)") page.update() + # 关闭“什么是伪本地化”窗口 + def close_what(e): + what_dlg.open = False + log.out(1, "Dialog close(WHT)") + page.update() + + # 关闭“确定清除历史记录”窗口 + def close_chq(e): + chq_dlg.open = False + log.out(1, "Dialog close(CHQ)") + page.update() + + # 关闭“确定清除历史记录”窗口 + def close_chq(e): + chq_dlg.open = False + log.out(1, "Dialog close(CHQ)") + page.update() + + # 关闭“保存方式”窗口 + def close_svw(e): + svw_dlg.open = False + log.out(1, "Dialog close(SVW)") + page.update + # 原check_for_update函数已迁移至lib/update.py # 检查更新 @@ -271,23 +314,23 @@ def main(page: ft.Page): def close_find_upd_dlg(e): find_upd_dlg.open = False page.update() - print("\033[0;32m[DONE] Dialog close(UPD)\033[0m") + log.out(1, "Dialog close(UPD)") content = update.update(basic_info.ver) if content == "ERR": page.snack_bar = ft.SnackBar(ft.Text(f"检查更新超时, 请检查网络连接")) # 提示栏 page.snack_bar.open = True page.update() - print("\033[0;32m[DONE] Snack Bar pop-up(CUF)\033[0m") + log.out(1, "Snack Bar pop-up(CUF)") elif content == "NUL": page.snack_bar = ft.SnackBar(ft.Text(f"你正在使用最新版本")) # 提示栏 page.snack_bar.open = True - print("\033[0;32m[DONE] Snack Bar pop-up(VLT)\033[0m") + log.out(1, "Snack Bar pop-up(VLT)") page.update() else: download_url = update.get_link() # 定义“发现更新”窗口 find_upd_dlg = ft.AlertDialog( - title = ft.Text("发现更新"), on_dismiss = lambda e: print("\033[0;34m[INFO] Dialog dismissed(UPD)\033[0m"), + title = ft.Text("发现更新"), on_dismiss = lambda e: log.out(0, "Dialog dismissed(UPD)"), content = ft.Markdown(content, selectable = True), actions = [ ft.FilledButton("更新", icon = ft.icons.UPLOAD_OUTLINED, url = download_url), @@ -297,87 +340,100 @@ def main(page: ft.Page): page.dialog = find_upd_dlg # 打开“发现更新”窗口 find_upd_dlg.open = True page.update() - print("\033[0;32m[DONE] Dialog open(UPD)\033[0m") + log.out(1, "Dialog open(UPD)") + + """ + # 启动时检查更新 + def startup_upd(): + if update.version_check(basic_info.ver) == True: + page.snack_bar = ft.SnackBar(ft.Text(f"发现新版本: " + update.latest_ver + ", 到设置取更新吧! ")) # 提示栏 + page.snack_bar.open = True + page.update() + log.out(1, "Snack Bar pop-up(SUU)") + """ - #检测窗口大小 + # 检测窗口大小 def page_resize(e): his_card.width = page.window_width - home_page.height = page.window_height-90 - home_page.width = page.window_width-120 - his_page.height = page.window_height-90 - his_page.width = page.window_width-120 - set_page.height = page.window_height-90 - set_page.width = page.window_width-120 - main_area.width = page.window_width-120 + home_page.height = page.window_height - 90 + home_page.width = page.window_width - 120 + his_page.height = page.window_height - 90 + his_page.width = page.window_width - 120 + set_page.height = page.window_height - 90 + set_page.width = page.window_width - 120 + main_area.width = page.window_width - 120 main_row.width = page.window_width page.update() - print("New page size:",round(page.window_height),round(page.window_width)) + log.out(0, "New page size:" + str(round(page.window_height)) + "," + str(round(page.window_width))) # 置顶 def always_on_top(e): if page.window_always_on_top == False: page.window_always_on_top = True ontop_btn.icon = ft.icons.PUSH_PIN_ROUNDED - print("\033[0;32m[DONE] Set always on top\033[0m") + log.out(1, "Set always on top") page.snack_bar = ft.SnackBar(ft.Text(f"已置顶")) # 提示栏 page.snack_bar.open = True - print("\033[0;32m[DONE] Snack Bar pop-up(AOT)\033[0m") + log.out(1, "Snack Bar pop-up(AOT)") page.update() elif page.window_always_on_top == True: page.window_always_on_top = False ontop_btn.icon = ft.icons.PUSH_PIN_OUTLINED - print("\033[0;32m[DONE] Cancel always on top\033[0m") + log.out(1, "Cancel always on top") page.snack_bar = ft.SnackBar(ft.Text(f"已取消置顶")) # 提示栏 page.snack_bar.open = True - print("\033[0;32m[DONE] Snack Bar pop-up(ATX)\033[0m") + log.out(1, "Snack Bar pop-up(ATX)") page.update() - - #小窗模式 + """ + # 小窗模式 def mini_mode(e): if rail.visible == True: - mini_btn.icon = ft.icons.VERTICAL_ALIGN_TOP_ROUNDED - mini_btn.tooltip = "恢复小窗" + # mini_btn.icon = ft.icons.VERTICAL_ALIGN_TOP_ROUNDED page.window_height = 350 page.window_width = 500 page.window_resizable = False max_btn.visible = False - page.pstype.max_lines = 1 - page.result.max_lines = 1 rail.selected_index=0 rail_ctrl(e) rail.visible = False elif rail.visible == False: - mini_btn.icon = ft.icons.PHOTO_SIZE_SELECT_SMALL_ROUNDED - mini_btn.tooltip = "小窗模式" + # mini_btn.icon = ft.icons.PHOTO_SIZE_SELECT_SMALL_ROUNDED page.window_height = 600 - page.window_width = 900 + page.window_width = 900 page.window_resizable = True max_btn.visible = True - page.pstype.max_lines = 5 - page.result.max_lines = 5 rail.visible = True page.update() + """ - #导航栏控制 + # 主体内容控制 def rail_ctrl(e): if rail.selected_index == 0: home_page.visible = True his_page.visible = False + collection_page.visible = False set_page.visible = False elif rail.selected_index == 1: home_page.visible = False his_page.visible = True + collection_page.visible = False set_page.visible = False elif rail.selected_index == 2: home_page.visible = False his_page.visible = False + collection_page.visible = True + set_page.visible = False + elif rail.selected_index == 3: + home_page.visible = False + his_page.visible = False + collection_page.visible = False set_page.visible = True - print("Navigate to: ",rail.selected_index) + log.out(0, "Rail Selected Index: " + str(rail.selected_index)) page.update() # “什么是伪本地化”窗口定义 what_dlg = ft.AlertDialog( - title = ft.Text("什么是伪本地化?"), on_dismiss = lambda e: print("\033[0;34m[INFO] Dialog dismissed(WHT)\033[0m"), + title = ft.Text("什么是伪本地化?"), on_dismiss = lambda e: log.out(0, "Dialog dismissed(WHT)"), content = ft.Markdown(basic_info.what_text, selectable = True), actions = [ ft.TextButton("我知道啦", icon = ft.icons.DONE, on_click = close_what) @@ -387,7 +443,7 @@ def main(page: ft.Page): # “确定清除历史记录”窗口定义 chq_dlg = ft.AlertDialog( - title = ft.Text("确定删除历史记录?"), on_dismiss = lambda e: print("\033[0;34m[INFO] Dialog dismissed(CHQ)\033[0m"), + title = ft.Text("确定删除历史记录?"), on_dismiss = lambda e: log.out(0, "Dialog dismissed(CHQ)"), content = ft.Text("确定删除所有历史记录,?\n该操作不可逆!"), actions = [ ft.ElevatedButton("确定", icon = ft.icons.DONE, on_click = clear_his, bgcolor = ft.colors.RED, color=ft.colors.WHITE, elevation = 0), @@ -395,7 +451,28 @@ def main(page: ft.Page): ], actions_alignment = ft.MainAxisAlignment.END ) + + # “保存方式”窗口定义 + save_files_dialog = ft.FilePicker(on_result = sv_files) + save_way_dd = ft.Dropdown( + label = "保存方式", + value = 0, + hint_text = "选择一种保存方式", + options = [ + ft.dropdown.Option(key = 0, text = "只保存伪本地化的结果"), + ft.dropdown.Option(key = 1, text = "同时保存原文及伪本地化的结果") + ]) + save_way_dd.value = 0 + svw_dlg = ft.AlertDialog( + title = ft.Text("保存方式"), on_dismiss = lambda e: log.out(0, "Dialog dismissed(SVW)"), + content = ft.Column(controls = [ft.Text("您希望如何保存?"), save_way_dd], height = 100, width = 300), + actions = [ + ft.FilledButton("确定", icon = ft.icons.DONE, on_click = lambda _: save_files_dialog.save_file(allowed_extensions = ["txt"])) + ], + actions_alignment = ft.MainAxisAlignment.END + ) + # “更新日志”窗口定义 upd_dlg = ft.BottomSheet( ft.Container( @@ -407,9 +484,8 @@ def main(page: ft.Page): padding = 20, width = page.window_width, ), - on_dismiss = lambda e: print("\033[0;34m[INFO] Dialog dismissed(UPH)\033[0m") + on_dismiss = lambda e: log.out(0, "Dialog dismissed(UPH)") ) - # 用户界面 # 基本内容定义 @@ -417,8 +493,8 @@ def main(page: ft.Page): page.window_top = 100 page.window_height = 600 page.window_width = 900 - page.window_min_height = 350 - page.window_min_width = 500 + page.window_min_height = 500 + page.window_min_width = 882 page.window_title_bar_hidden = True page.theme = ft.Theme( font_family = "Microsoft Yahei", @@ -426,40 +502,73 @@ def main(page: ft.Page): ) page.on_resize = page_resize - # 主页区 - title_text = ft.Container(ft.Text(basic_info.title,size=20)) - theme_btn = fleter.SwitchThemeButton(page, light_icon = ft.icons.LIGHT_MODE, dark_icon = ft.icons.DARK_MODE, has_system = False), - ontop_btn = ft.IconButton(icon = ft.icons.PUSH_PIN_OUTLINED, on_click = always_on_top) - mini_btn = ft.IconButton(icon = ft.icons.PHOTO_SIZE_SELECT_SMALL_ROUNDED, tooltip = "小窗模式", on_click = mini_mode) - min_btn = fleter.MinimizeButton(page,icon=ft.icons.HORIZONTAL_RULE_ROUNDED) - max_btn = fleter.MaximizeButton(page,icon=ft.icons.SQUARE_OUTLINED) - close_btn = fleter.CloseButton(page) + # 窗口区 + title_text = ft.Container(ft.Text(basic_info.title, size = 20)) + title_icon = ft.Container(ft.Icon(ft.icons.LANGUAGE_OUTLINED), padding = 5) + ontop_btn = ft.IconButton(icon = ft.icons.PUSH_PIN_OUTLINED, on_click = always_on_top, tooltip = "置顶") + # mini_btn = ft.IconButton(icon = ft.icons.PHOTO_SIZE_SELECT_SMALL_ROUNDED, tooltip = "小窗模式", on_click = mini_mode) + more_options = ft.PopupMenuButton( + items = [ + ft.PopupMenuItem( + content = ft.Row( + [ + ft.Icon(ft.icons.OPEN_IN_BROWSER), + ft.Text("打开网页版"), + ] + ), + on_click = open_in_browser + ), + ft.PopupMenuItem( + content = ft.Row( + [ + ft.Icon(ft.icons.COLLECTIONS_BOOKMARK_OUTLINED), + ft.Text("打开项目仓库"), + ] + ), + on_click = open_project_repo + ), + ft.PopupMenuItem(), + ft.PopupMenuItem( + content = ft.Row( + [ + ft.Icon(ft.icons.QUESTION_MARK_OUTLINED), + ft.Text("什么是伪本地化?"), + ] + ), + on_click = open_what + ), + ], + tooltip = "更多选项" + ) + min_btn = controls.MinimizeButton(page, icon = ft.icons.HORIZONTAL_RULE_ROUNDED) + max_btn = controls.MaximizeButton(page, icon = ft.icons.SQUARE_OUTLINED) + close_btn = controls.CloseButton(page) titlebar = ft.WindowDragArea(ft.Row( alignment = ft.MainAxisAlignment.SPACE_BETWEEN, - controls=[ - title_text, - ft.Row(spacing=1,controls=[ontop_btn,mini_btn,min_btn,max_btn,close_btn]) + controls = [ + ft.Row(spacing = 1, controls = [title_icon, title_text]), + ft.Row(spacing = 1,controls = [ontop_btn, more_options, min_btn, max_btn, close_btn]) ])) - xab = ft.RadioGroup(value = "enxa",content=ft.Row([ - ft.Radio(value = "enxa", label = "en-XA (ab→ǻƀ)"), - ft.Radio(value = "enxb", label = "en-XB (ab→ba)")])) - XABrow = ft.Row(spacing = 1, controls = [ft.Text("伪本地化方式:",size=15),xab]) + # 主页区 + xab = ft.RadioGroup(value = "enxa", content = ft.Row([ + ft.Radio(value = "enxa", label = "en-XA (qps-ploc) (e.g. ab→ǻƀ)"), + ft.Radio(value = "enxb", label = "en-XB (qps-plocm) (e.g. ab→ba)")])) + XABrow = ft.Row(spacing = 1, controls = [ft.Text("伪本地化方式:", size = 15), xab]) page.pstype = ft.TextField(hint_text = "在这里输入要翻译的内容~", text_size =15, multiline = True, max_lines = 5) page.result = ft.TextField(hint_text = "结果会显示在这里~", text_size = 15, multiline = True, max_lines = 5, read_only = True) pslo_btn = ft.FilledButton( - "进行伪本地化!", - icon = ft.icons.TRANSLATE_OUTLINED, - tooltip = "将您所填写的内容伪本地化, 每次生成结果都会不一样哦", - on_click = pslo + "进行伪本地化!", + icon = ft.icons.TRANSLATE_OUTLINED, + tooltip = "将您所填写的内容伪本地化, 每次生成结果都会不一样哦", + on_click = pslo ) copy_btn = ft.IconButton( - icon = ft.icons.COPY, - tooltip = "将生成内容添加到设备剪切板", - on_click = copy_text + ft.icons.COPY, + tooltip = "将生成内容添加到设备剪切板", + on_click = copy_text ) # 导入导出文件 pick_files_dialog = ft.FilePicker(on_result = ps_files) - save_files_dialog = ft.FilePicker(on_result = sv_files) page.overlay.append(pick_files_dialog) page.overlay.append(save_files_dialog) lsfile = ft.PopupMenuButton( @@ -480,14 +589,14 @@ def main(page: ft.Page): ft.Icon(ft.icons.SAVE_OUTLINED), ft.Text("保存"), ]), - on_click = lambda _: save_files_dialog.save_file(allowed_extensions = ["txt"]) + on_click = open_svw ) ] ) pslo_row = ft.Row(spacing = 10, controls = [pslo_btn, copy_btn, lsfile]) home_page = ft.Column( - width=page.window_width-120, - controls=[XABrow, page.pstype, page.result,pslo_row]) + width = page.window_width - 120, + controls = [XABrow, page.pstype, page.result, pslo_row]) history = ft.Text("无记录", size = 18, selectable = True) his_card = ft.Card( content = ft.Container( @@ -496,9 +605,10 @@ def main(page: ft.Page): history ] ), - width=page.window_width, + width = page.window_width, padding = 10, - ),elevation = 0.5 + ), + elevation = 0.5 ) save_his_dialog = ft.FilePicker(on_result = sv_his) his_title = ft.Row(controls = [ @@ -527,21 +637,36 @@ def main(page: ft.Page): on_click = open_chq ) ]) - his_bar = ft.Row(alignment = ft.MainAxisAlignment.SPACE_BETWEEN,controls = [ + his_bar = ft.Row(alignment = ft.MainAxisAlignment.SPACE_BETWEEN, controls = [ his_title, his_opts ]) his_col = ft.Column( - width=page.window_width-120, - scroll=ft.ScrollMode.ALWAYS, - controls=[ + width = page.window_width - 120, + scroll = ft.ScrollMode.ALWAYS, + controls = [ his_bar, his_card - ]) - his_page = ft.Container( - content = his_col, - visible=False) - # 设置区 + ] + ) + his_page = ft.Container(content = his_col, visible = False) + + # 集合区 + collection_unav_card = ft.Card( + content = ft.Container( + content = ft.Column( + [ + ft.Icon(ft.icons.ANNOUNCEMENT_OUTLINED, size = 56, tooltip = "这里将来会做一些集成脚本来快速实现某些功能"), + ft.Text("嘿, “集合”还在开发中, 暂时还不可用!", size = 18) + ] + ), + padding = 15 + ), + elevation = 0.5 + ) + collection_page = ft.Container(content = collection_unav_card, visible = False, alignment = ft.alignment.center, margin = page.window_height / 4) + + # 设置区 # 伪本地化设置 opt_pslo = ft.Row( [ @@ -555,11 +680,12 @@ def main(page: ft.Page): label = "前后缀", value = 0, hint_text = "选择前后缀方案,默认为“不添加前后缀”", - options=[ + options = [ ft.dropdown.Option(key = 0, text = "不添加前后缀"), ft.dropdown.Option(key = 1, text = "[中括号+感叹号括起来 (微软式伪本地化)!!!]"), ft.dropdown.Option(key = 2, text = "[中括号+在语段后添加英文基数词 (安卓式伪本地化) one two three]"), - ft.dropdown.Option(key = 3, text = "自定义前后缀") + ft.dropdown.Option(key = 3, text = "[中括号+在语段后添加阿拉伯数字 12345]"), + ft.dropdown.Option(key = 4, text = "自定义前后缀") ], on_change = psf_check) cus_pre = ft.TextField(width = 80, label = "前缀", value = "[") cus_suf = ft.TextField(width = 80, label = "后缀", value = "]") @@ -567,14 +693,14 @@ def main(page: ft.Page): cus_cs = ft.TextField(width = 230, label = "每隔多少个字符重复一次:", value = 7, on_blur = ccs_check) cus_ps = ft.Row(spacing = 5, visible = False, controls = [cus_pre, cus_suf, cus_re, cus_cs]) #----------# - hash_cb = ft.Switch(label = "[Abc12]添加伪 Hash ID (资源标识符)\n(由一定位数的字母+数字所构成的字符串)", value = False, on_change = hash_check) + hash_cb = ft.Switch(label = "[Abc12]添加伪 Hash ID (资源标识符)(由一定位数的字母+数字所构成的字符串)", value = False, on_change = hash_check) hash_ws = ft.TextField(width = 150, label = "位数 (3-10)", value = 5, on_blur = ws_check, disabled = True) row_hash = ft.Row(spacing = 10, controls = [hash_cb, hash_ws]) #----------# num_pslo = ft.Dropdown( label = "数字伪本地化", hint_text = "选择数字伪本地化方案,默认为“无”", - options=[ + options = [ ft.dropdown.Option(key = 0, text = "无"), ft.dropdown.Option(key = 1, text = "使用①-⑨替代1-9"), ft.dropdown.Option(key = 2, text = "使用₀-₉或⁰-⁹交叉替换0-9") @@ -583,7 +709,7 @@ def main(page: ft.Page): num_pslo = ft.Dropdown( label = "数字伪本地化", hint_text = "选择数字伪本地化方案, 默认为“无”", - value = 0, #默认为“无” + value = 0, options = [ ft.dropdown.Option(key = 0, text = "无"), ft.dropdown.Option(key = 1, text = "使用①-⑨替代1-9"), @@ -594,7 +720,7 @@ def main(page: ft.Page): vowel_cs = ft.TextField(width = 150, label = "次数 (0-10)", value = 0, on_blur = vcs_check) row_vow = ft.Row(spacing = 10, controls = [vowel_tx,vowel_cs]) #----------# - vis_con_cb = ft.Switch(label = r"翻译后隐藏%s, \n等控制字符", value = False) + vis_con_cb = ft.Switch(label = r"翻译后隐藏%s, \n, \r等控制字符", value = False) pslo_opt_card = ft.Card( content = ft.Container( @@ -609,7 +735,8 @@ def main(page: ft.Page): ] ), padding = 15 - ) + ), + elevation = 0.5 ) # 外观设置 @@ -623,46 +750,28 @@ def main(page: ft.Page): theme = ft.Dropdown( label = "亮暗模式", hint_text = "亮暗模式", + value = 2, options=[ ft.dropdown.Option(key = 0, text = "亮色"), ft.dropdown.Option(key = 1, text = "暗色"), ft.dropdown.Option(key = 2, text = "跟随系统") ], on_change = theme_changed) - theme.value = 2 #----------# sch_text = ft.Text("配色", size = 20) - scheme = ft.RadioGroup(value = 0, content = ft.Row([ - ft.Radio( - value = 0, - label = "蓝色", - fill_color = ft.colors.BLUE_800, - ), - ft.Radio( - value = 1, - label = "粉色", - fill_color = ft.colors.PINK_700, - ), - ft.Radio( - value = 2, - label = "绿色", - fill_color = ft.colors.GREEN_700, - ), - ft.Radio( - value = 3, - label = "巧克力色", - fill_color = ft.colors.BROWN, - ), - ft.Radio( - value = 4, - label = "紫色", - fill_color = ft.colors.DEEP_PURPLE, - ) - ]), on_change = sch_changed) + scheme = ft.RadioGroup(value = 0, content = ft.Row(controls = [ + ft.Radio(value = 0, label = "蓝色", fill_color = ft.colors.BLUE_800), + ft.Radio(value = 1, label = "粉色", fill_color = ft.colors.PINK_700), + ft.Radio(value = 2, label = "绿色", fill_color = ft.colors.GREEN_700), + ft.Radio(value = 3, label = "巧克力色", fill_color = ft.colors.BROWN), + ft.Radio(value = 4, label = "紫色", fill_color = ft.colors.DEEP_PURPLE) + ]), + on_change = sch_changed) #----------# opacity_text = ft.Text("窗口透明度", size = 20) - page.opacity_slider = ft.Slider(min = 50, max = 100, width=400, divisions = 50, label = "{value}%", on_change = opacity_slider_changed, value = 100) + page.opacity_slider = ft.Slider(min = 50, max = 100, width = 500, divisions = 50, label = "{value}%", on_change = opacity_slider_changed, value = 100) opacity_bar = ft.Row(controls = [opacity_text, ft.Icon(ft.icons.OPACITY), page.opacity_slider, ft.Icon(ft.icons.WATER_DROP)]) + opac_warn_bar = ft.Row(controls = [ft.Icon(ft.icons.WARNING_AMBER_OUTLINED, color = ft.colors.AMBER),ft.Text("透明度似乎太低了!", color = ft.colors.AMBER)], visible = False) look_opt_card = ft.Card( content = ft.Container( @@ -671,11 +780,13 @@ def main(page: ft.Page): theme, sch_text, scheme, - opacity_bar + opacity_bar, + opac_warn_bar ] ), padding = 15 - ) + ), + elevation = 0.5 ) # 关于内容 @@ -689,9 +800,7 @@ def main(page: ft.Page): upd_bar = ft.Row( controls = [ ft.TextButton("更新日志", icon = ft.icons.UPDATE, on_click = open_upd), - ft.TextButton("检查更新", icon = ft.icons.UPLOAD_OUTLINED, on_click = check_for_update), - ft.TextButton("网页版",icon=ft.icons.OPEN_IN_BROWSER_ROUNDED,on_click = open_with_browser), - ft.TextButton("项目仓库",icon=ft.icons.COLLECTIONS_BOOKMARK_OUTLINED,on_click = open_project_repo), + ft.TextButton("检查更新", icon = ft.icons.UPLOAD_OUTLINED, on_click = check_for_update) ] ) @@ -704,46 +813,46 @@ def main(page: ft.Page): ] ), padding = 15 - ) + ), + elevation = 0.5 ) - set_col = ft.Column(scroll=ft.ScrollMode.ALWAYS,controls=[ - opt_pslo,opt_pslo_detail,pslo_opt_card, - opt_look,look_opt_card, - abt,abt_card]) - set_page = ft.Container( - height=page.window_height-90, - content = set_col, - visible=False) - main_area = ft.Column(height= page.window_height-90,controls=[home_page,his_page,set_page]) + set_col = ft.Column(scroll = ft.ScrollMode.ALWAYS, controls = [opt_pslo, opt_pslo_detail, pslo_opt_card, opt_look, look_opt_card, abt, abt_card]) + set_page = ft.Container(height = page.window_height - 90, content = set_col, visible = False) + main_area = ft.Column(height = page.window_height - 90, controls = [home_page, his_page, collection_page, set_page]) - #导航栏 + # 导航栏 rail = ft.NavigationRail( - selected_index=0, - height=page.window_height-90, - label_type=ft.NavigationRailLabelType.ALL, - # extended=True, - min_width=50, - min_extended_width=100, + selected_index = 0, + height = page.window_height - 90, + label_type = ft.NavigationRailLabelType.ALL, + min_width = 50, + min_extended_width = 100, group_alignment = -1.0, - destinations=[ + destinations = [ + ft.NavigationRailDestination( + icon = ft.icons.HOME_OUTLINED, selected_icon = ft.icons.HOME_ROUNDED, label = "主页" + ), ft.NavigationRailDestination( - icon=ft.icons.HOME_OUTLINED, selected_icon=ft.icons.HOME_ROUNDED, label="主页" + icon_content = ft.Icon(ft.icons.HISTORY_OUTLINED), + selected_icon_content = ft.Icon(ft.icons.HISTORY_ROUNDED), + label = "历史记录", ), ft.NavigationRailDestination( - icon_content=ft.Icon(ft.icons.HISTORY_OUTLINED), - selected_icon_content=ft.Icon(ft.icons.HISTORY_ROUNDED), - label="历史记录", + icon = ft.icons.ALL_INBOX_OUTLINED, + selected_icon_content = ft.Icon(ft.icons.ALL_INBOX), + label_content = ft.Text("集合"), ), ft.NavigationRailDestination( - icon=ft.icons.SETTINGS_OUTLINED, - selected_icon_content=ft.Icon(ft.icons.SETTINGS), - label_content=ft.Text("设置"), + icon = ft.icons.SETTINGS_OUTLINED, + selected_icon_content = ft.Icon(ft.icons.SETTINGS), + label_content = ft.Text("设置"), ), ], on_change = rail_ctrl, ) - main_row = ft.Row(height=page.window_height-90, width=page.window_width,controls=[rail,main_area]) + main_row = ft.Row(height = page.window_height - 90, width = page.window_width, controls = [rail, main_area]) page.add(titlebar, main_row) - print("\033[0;34m[INFO] Window initialization completed\033[0m") + # startup_upd() + log.out(0, "Window initialization completed") ft.app(target = main) diff --git a/pslo_mini.pyw b/pslo_mini.pyw index f68d2ff..7b363fc 100644 --- a/pslo_mini.pyw +++ b/pslo_mini.pyw @@ -1,15 +1,17 @@ import flet as ft import sys import pyperclip -import fleter +import time +from lib import log from lib import pslo_work +from lib import controls from lib import basic_info # 基础信息位于lib/basic_info.py -print('\033[0;34m[INFO] Python version: {}\033[0m'.format(sys.version)) -print("\033[0;34m[INFO] PSLO version: " + basic_info.ver + "\033[0m") -print("\033[0;34m[INFO] You are using PSLO Mini\033[0m") +log.out(0, "Python version: " + sys.version) +log.out(0, "PSLO version: " + basic_info.ver) +log.out(0, "You are using PSLO Mini") # 主程序 def main(page: ft.Page): @@ -25,60 +27,91 @@ def main(page: ft.Page): # 复制文本 def copy_text(e): pyperclip.copy(page.result.value) - print("\033[0;32m[DONE] Added to clipboard\033[0m") - page.snack_bar = ft.SnackBar(ft.Text(f"已复制")) # 提示栏 - page.snack_bar.open = True + log.out(1, "Added to clipboard") + copy_notice.visible = True + log.out(1, "Copy notice visable is True") + page.update() + time.sleep(2) + copy_notice.visible = False + log.out(1, "Copy notice visable is False") page.update() - print("\033[0;34m[INFO] Snack bar pop-up(CP)\033[0m") # 置顶 def always_on_top(e): if page.window_always_on_top == False: page.window_always_on_top = True ontop_btn.icon = ft.icons.PUSH_PIN_ROUNDED - print("\033[0;32m[DONE] Set always on top\033[0m") - print("\033[0;32m[DONE] Snack Bar pop-up(AOT)\033[0m") + log.out(1, "Set always on top") page.update() elif page.window_always_on_top == True: page.window_always_on_top = False ontop_btn.icon = ft.icons.PUSH_PIN_OUTLINED - print("\033[0;32m[DONE] Cancel always on top\033[0m") - print("\033[0;32m[DONE] Snack Bar pop-up(ATX)\033[0m") + log.out(1, "Cancel always on top") page.update() + def switch_theme(e): + if page.theme_mode == ft.ThemeMode.DARK: + theme_switch_btn.icon = ft.icons.LIGHT_MODE_OUTLINED + page.theme_mode = ft.ThemeMode.LIGHT + elif page.theme_mode == ft.ThemeMode.LIGHT: + theme_switch_btn.icon = ft.icons.DARK_MODE_OUTLINED + page.theme_mode = ft.ThemeMode.DARK + page.update() + + # 用户界面 # 基本内容定义 page.window_left = 200 page.window_top = 100 - page.window_height = 300 + page.window_height = 263 page.window_width = 400 page.window_opacity = 0.9 page.window_resizable = False + page.window_title_bar_hidden = True page.theme = ft.Theme( - font_family = "Microsoft Yahei", - color_scheme_seed = ft.colors.BLUE - ) + font_family = "Microsoft Yahei", + color_scheme_seed = ft.colors.BLUE + ) + page.theme_mode = ft.ThemeMode.LIGHT # 主页区 - titlebar = fleter.HeaderBar(page, title = "伪本地化演示 mini",title_align = "left") - # titlebar._title_area = ft.Container(padding = 5) - titlebar.controls.insert(1, fleter.SwitchThemeButton(page, light_icon = ft.icons.LIGHT_MODE, dark_icon = ft.icons.DARK_MODE, has_system = False)) - ontop_btn = ft.IconButton(icon = ft.icons.PUSH_PIN_OUTLINED, on_click = always_on_top) - titlebar.controls.insert(2,ontop_btn) + # 窗口区 + title_text = ft.Container(ft.Text("伪本地化演示Mini", size = 18)) + title_icon = ft.Container(ft.Icon(ft.icons.LANGUAGE_OUTLINED, size = 18), padding = 5) + ontop_btn = ft.IconButton(icon = ft.icons.PUSH_PIN_OUTLINED, on_click = always_on_top, tooltip = "置顶") + theme_switch_btn = ft.IconButton(icon = ft.icons.LIGHT_MODE_OUTLINED, on_click = switch_theme, tooltip = "明暗") + min_btn = controls.MinimizeButton(page, icon = ft.icons.HORIZONTAL_RULE_ROUNDED) + close_btn = controls.CloseButton(page) + titlebar = ft.WindowDragArea(ft.Row( + alignment = ft.MainAxisAlignment.SPACE_BETWEEN, + controls = [ + ft.Row(spacing = 1, controls = [title_icon, title_text]), + ft.Row(spacing = 1,controls = [ontop_btn, theme_switch_btn, min_btn, close_btn]) + ])) page.pstype = ft.TextField(hint_text = "在这里输入要翻译的内容~", text_size = 15, multiline = False, max_lines = 5) page.result = ft.TextField(hint_text = "结果会显示在这里~", text_size = 15, multiline = False, max_lines = 5, read_only = True) - pslo_btn = ft.FilledButton( + pslo_btn = ft.FilledTonalButton( "伪本地化!", icon = ft.icons.TRANSLATE_OUTLINED, + style = ft.ButtonStyle( + shape = ft.RoundedRectangleBorder(radius = 5), + ), on_click = pslo ) copy_btn = ft.IconButton( icon = ft.icons.COPY_OUTLINED, on_click = copy_text ) - btns = ft.Row(controls=[pslo_btn, copy_btn]) - row = ft.Row(controls=[btns, ft.Text(basic_info.ver, size = 15, color = ft.colors.GREY)], alignment = ft.MainAxisAlignment.SPACE_BETWEEN) + copy_notice = ft.Row( + controls = [ + ft.Icon(ft.icons.DONE, color = ft.colors.GREEN_600), + ft.Text("已复制", color = ft.colors.GREEN_600) + ], + visible = False + ) + btns = ft.Row(controls = [pslo_btn, copy_btn]) + row = ft.Row(controls = [btns, copy_notice, ft.Text(basic_info.ver, size = 15, color = ft.colors.GREY)], alignment = ft.MainAxisAlignment.SPACE_BETWEEN) page.add(titlebar, page.pstype, page.result, row) - print("\033[0;34m[INFO] Window initialization completed\033[0m") + log.out(0, "Window initialization completed") ft.app(target = main) diff --git a/requirements.txt b/requirements.txt index 43931988ff3cfd1a07fd7028bc964c70e66d9fea..beb64d0a98f0ea24029dbe5fad33842f8d787449 100644 GIT binary patch delta 7 Ocmb@IJ$^`%mWCEH1 delta 33 lcmYeOn;;{Z#*o91%1{EtMGSTfwhRUgdJM)uY%o#W699f527v$o