Compare commits
6 Commits
69dd5ed1e3
...
8ce0c1bf9e
| Author | SHA1 | Date | |
|---|---|---|---|
| 8ce0c1bf9e | |||
| 04a0310eee | |||
| 3a2aa4f109 | |||
| 9902be0a48 | |||
| 61132d242f | |||
| 21b2da1e69 |
@@ -1,10 +1,10 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" width="512" height="512" viewBox="0 0 16 16">
|
<svg xmlns="http://www.w3.org/2000/svg" width="512" height="512" viewBox="0 0 16 16">
|
||||||
|
|
||||||
<path style="fill: #dddddd; stroke: black; stroke-linejoin:round;"
|
<path style="fill: #dddddd; stroke: black; stroke-linejoin:round;"
|
||||||
d="M8,13
|
d="M8,3
|
||||||
L1,3
|
L1,13
|
||||||
L15,3
|
L15,13
|
||||||
z
|
z
|
||||||
"/>
|
"/>
|
||||||
<line x1="0.5" y1="13.5" x2="15.5" y2="13.5" style="stroke:black;"/>
|
<line x1="0.5" y1="2.5" x2="15.5" y2="2.5" style="stroke:black;"/>
|
||||||
</svg>
|
</svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 287 B After Width: | Height: | Size: 286 B |
@@ -1,10 +1,10 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" width="512" height="512" viewBox="0 0 16 16">
|
<svg xmlns="http://www.w3.org/2000/svg" width="512" height="512" viewBox="0 0 16 16">
|
||||||
|
|
||||||
<path style="fill: #dddddd; stroke: black; stroke-linejoin:round;"
|
<path style="fill: #dddddd; stroke: black; stroke-linejoin:round;"
|
||||||
d="M8,3
|
d="M8,13
|
||||||
L1,13
|
L1,3
|
||||||
L15,13
|
L15,3
|
||||||
z
|
z
|
||||||
"/>
|
"/>
|
||||||
<line x1="0.5" y1="2.5" x2="15.5" y2="2.5" style="stroke:black;"/>
|
<line x1="0.5" y1="13.5" x2="15.5" y2="13.5" style="stroke:black;"/>
|
||||||
</svg>
|
</svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 286 B After Width: | Height: | Size: 287 B |
@@ -10,8 +10,10 @@ from src import install
|
|||||||
from src.pluginregistry import PluginRegistry
|
from src.pluginregistry import PluginRegistry
|
||||||
import gettext
|
import gettext
|
||||||
from src.ui.icon import Icon
|
from src.ui.icon import Icon
|
||||||
|
from pathlib import Path
|
||||||
|
import os
|
||||||
|
|
||||||
__version__ = '0.2.1'
|
__version__ = Path(os.path.dirname(os.path.realpath(__file__)) + os.sep + "version.txt").read_text()
|
||||||
|
|
||||||
gettext.install('krowlog', 'locale')
|
gettext.install('krowlog', 'locale')
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
@@ -5,8 +5,8 @@
|
|||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: RavenLog\n"
|
"Project-Id-Version: RavenLog\n"
|
||||||
"POT-Creation-Date: 2024-03-24 12:00+0100\n"
|
"POT-Creation-Date: 2025-03-24 19:02+0100\n"
|
||||||
"PO-Revision-Date: 2024-03-24 12:02+0100\n"
|
"PO-Revision-Date: 2025-03-24 19:17+0100\n"
|
||||||
"Last-Translator: \n"
|
"Last-Translator: \n"
|
||||||
"Language-Team: \n"
|
"Language-Team: \n"
|
||||||
"Language: de\n"
|
"Language: de\n"
|
||||||
@@ -15,10 +15,10 @@ msgstr ""
|
|||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||||
"Generated-By: pygettext.py 1.5\n"
|
"Generated-By: pygettext.py 1.5\n"
|
||||||
"X-Generator: Poedit 3.0.1\n"
|
"X-Generator: Poedit 3.5\n"
|
||||||
|
|
||||||
#: src/mainwindow.py:32 src/plugins/krowlog/aboutdialog.py:30
|
#: src/mainwindow.py:32 src/new_big_text/bigger_text.py:75
|
||||||
#: src/plugins/krowlogplugin.py:85
|
#: src/plugins/krowlog/aboutdialog.py:30 src/plugins/krowlogplugin.py:85
|
||||||
msgid "KrowLog"
|
msgid "KrowLog"
|
||||||
msgstr "KrowLog"
|
msgstr "KrowLog"
|
||||||
|
|
||||||
@@ -146,31 +146,31 @@ msgstr "&Über KrowLog"
|
|||||||
msgid "E&xit"
|
msgid "E&xit"
|
||||||
msgstr "&Beenden"
|
msgstr "&Beenden"
|
||||||
|
|
||||||
#: src/plugins/logfile/filterwidget.py:181
|
#: src/plugins/logfile/filterwidget.py:192
|
||||||
msgid "Cancel"
|
msgid "Cancel"
|
||||||
msgstr "Abbrechen"
|
msgstr "Abbrechen"
|
||||||
|
|
||||||
#: src/plugins/logfile/filterwidget.py:187
|
#: src/plugins/logfile/filterwidget.py:198
|
||||||
msgid "save query"
|
msgid "save query"
|
||||||
msgstr "suche speichern"
|
msgstr "suche speichern"
|
||||||
|
|
||||||
#: src/plugins/logfile/filterwidget.py:192
|
#: src/plugins/logfile/filterwidget.py:203
|
||||||
msgid "ignore case"
|
msgid "ignore case"
|
||||||
msgstr "Groß-/Kleinschreibung ignorieren"
|
msgstr "Groß-/Kleinschreibung ignorieren"
|
||||||
|
|
||||||
#: src/plugins/logfile/filterwidget.py:196
|
#: src/plugins/logfile/filterwidget.py:207
|
||||||
msgid "regex"
|
msgid "regex"
|
||||||
msgstr "RegExp"
|
msgstr "RegExp"
|
||||||
|
|
||||||
#: src/plugins/logfile/filterwidget.py:206
|
#: src/plugins/logfile/filterwidget.py:217
|
||||||
msgid "only matches"
|
msgid "only matches"
|
||||||
msgstr "nur Treffer"
|
msgstr "nur Treffer"
|
||||||
|
|
||||||
#: src/plugins/logfile/filterwidget.py:298
|
#: src/plugins/logfile/filterwidget.py:309
|
||||||
msgid "({hits} lines)"
|
msgid "({hits} lines)"
|
||||||
msgstr "({hits} Zeilen)"
|
msgstr "({hits} Zeilen)"
|
||||||
|
|
||||||
#: src/plugins/logfileplugin.py:35 src/ui/bigtext/bigtext.py:258
|
#: src/plugins/logfileplugin.py:35 src/ui/bigtext/bigtext.py:263
|
||||||
msgid "&Highlighter"
|
msgid "&Highlighter"
|
||||||
msgstr "&Hervorhebungen"
|
msgstr "&Hervorhebungen"
|
||||||
|
|
||||||
@@ -200,65 +200,69 @@ msgstr "Öffne Datei"
|
|||||||
|
|
||||||
#: src/plugins/timediff/time_diff_menu_widget.py:32
|
#: src/plugins/timediff/time_diff_menu_widget.py:32
|
||||||
msgid "ms"
|
msgid "ms"
|
||||||
msgstr ""
|
msgstr "ms"
|
||||||
|
|
||||||
#: src/plugins/timediff/time_diff_menu_widget.py:33
|
#: src/plugins/timediff/time_diff_menu_widget.py:33
|
||||||
msgid "s"
|
msgid "s"
|
||||||
msgstr ""
|
msgstr "s"
|
||||||
|
|
||||||
#: src/plugins/timediff/time_diff_menu_widget.py:34
|
#: src/plugins/timediff/time_diff_menu_widget.py:34
|
||||||
msgid "m"
|
msgid "m"
|
||||||
msgstr ""
|
msgstr "m"
|
||||||
|
|
||||||
#: src/plugins/timediff/time_diff_menu_widget.py:35
|
#: src/plugins/timediff/time_diff_menu_widget.py:35
|
||||||
msgid "h"
|
msgid "h"
|
||||||
msgstr ""
|
msgstr "h"
|
||||||
|
|
||||||
#: src/ui/bigtext/bigtext.py:238
|
#: src/ui/bigtext/bigtext.py:243
|
||||||
msgid "&Copy to Clipboard"
|
msgid "&Copy to Clipboard"
|
||||||
msgstr "In Zwischenablage &Kopieren"
|
msgstr "In Zwischenablage &Kopieren"
|
||||||
|
|
||||||
#: src/ui/bigtext/bigtext.py:246
|
#: src/ui/bigtext/bigtext.py:251
|
||||||
msgid "Copy to &File"
|
msgid "Copy to &File"
|
||||||
msgstr "In &Datei Kopieren"
|
msgstr "In &Datei Kopieren"
|
||||||
|
|
||||||
#: src/ui/bigtext/bigtext.py:252
|
#: src/ui/bigtext/bigtext.py:257
|
||||||
msgid "Select &All"
|
msgid "Select &All"
|
||||||
msgstr "&Alles Selektieren"
|
msgstr "&Alles Selektieren"
|
||||||
|
|
||||||
#: src/ui/bigtext/bigtext.py:268
|
#: src/ui/bigtext/bigtext.py:270
|
||||||
|
msgid "&Follow"
|
||||||
|
msgstr "&Folgen"
|
||||||
|
|
||||||
|
#: src/ui/bigtext/bigtext.py:280
|
||||||
msgid "Set Range Start"
|
msgid "Set Range Start"
|
||||||
msgstr "Setze Start des Anzeigebereichs"
|
msgstr "Setze Start des Anzeigebereichs"
|
||||||
|
|
||||||
#: src/ui/bigtext/bigtext.py:276
|
#: src/ui/bigtext/bigtext.py:288
|
||||||
msgid "Set Range End"
|
msgid "Set Range End"
|
||||||
msgstr "Setze Ende des Anzeigebereichs"
|
msgstr "Setze Ende des Anzeigebereichs"
|
||||||
|
|
||||||
#: src/ui/bigtext/bigtext.py:283
|
#: src/ui/bigtext/bigtext.py:295
|
||||||
msgid "Reset Range"
|
msgid "Reset Range"
|
||||||
msgstr "Anzeigebereich Zurücksetzen"
|
msgstr "Anzeigebereich Zurücksetzen"
|
||||||
|
|
||||||
#: src/ui/bigtext/bigtext.py:458
|
#: src/ui/bigtext/bigtext.py:526
|
||||||
msgid "warning"
|
msgid "warning"
|
||||||
msgstr "Achtung"
|
msgstr "Achtung"
|
||||||
|
|
||||||
#: src/ui/bigtext/bigtext.py:459
|
#: src/ui/bigtext/bigtext.py:527
|
||||||
msgid "You have selected <b>{0}</b> of data."
|
msgid "You have selected <b>{0}</b> of data."
|
||||||
msgstr "Du hast <b>{0}</b> selektiert."
|
msgstr "Du hast <b>{0}</b> selektiert."
|
||||||
|
|
||||||
#: src/ui/bigtext/bigtext.py:464
|
#: src/ui/bigtext/bigtext.py:532
|
||||||
msgid "Copy {0} to Clipboard"
|
msgid "Copy {0} to Clipboard"
|
||||||
msgstr "Kopiere {0} in die Zwischenablage"
|
msgstr "Kopiere {0} in die Zwischenablage"
|
||||||
|
|
||||||
#: src/ui/bigtext/bigtext.py:468
|
#: src/ui/bigtext/bigtext.py:536
|
||||||
msgid "Write to File"
|
msgid "Write to File"
|
||||||
msgstr "Schreibe in Datei"
|
msgstr "Schreibe in Datei"
|
||||||
|
|
||||||
#: src/ui/bigtext/bigtext.py:492
|
#: src/ui/bigtext/bigtext.py:560
|
||||||
msgid "Save File"
|
msgid "Save File"
|
||||||
msgstr "Speichere Datei"
|
msgstr "Speichere Datei"
|
||||||
|
|
||||||
#: src/ui/bigtext/bigtext.py:529
|
#: src/ui/bigtext/bigtext.py:605
|
||||||
msgid "selected {0} - {1:,.0f}:{2:,.0f}"
|
msgid "selected {0} - {1:,.0f}:{2:,.0f}"
|
||||||
msgstr "selektiert {0} - {1:,.0f}:{2:,.0f}"
|
msgstr "selektiert {0} - {1:,.0f}:{2:,.0f}"
|
||||||
|
|
||||||
@@ -306,6 +310,10 @@ msgstr "Zeilenhintergrund"
|
|||||||
msgid "Regular Expression"
|
msgid "Regular Expression"
|
||||||
msgstr "Regulärer Ausdruck"
|
msgstr "Regulärer Ausdruck"
|
||||||
|
|
||||||
|
#: src/ui/bigtext/newhighlightingdialog.py:185
|
||||||
|
msgid "File Type:"
|
||||||
|
msgstr "Dateityp:"
|
||||||
|
|
||||||
#: src/ui/colorbutton.py:20
|
#: src/ui/colorbutton.py:20
|
||||||
msgid "Strawberry Cream"
|
msgid "Strawberry Cream"
|
||||||
msgstr "Strawberry Cream"
|
msgstr "Strawberry Cream"
|
||||||
@@ -370,7 +378,7 @@ msgstr "Grau"
|
|||||||
msgid "transparent"
|
msgid "transparent"
|
||||||
msgstr "Transparent"
|
msgstr "Transparent"
|
||||||
|
|
||||||
#: src/ui/rangeslider.py:180
|
#: src/ui/rangeslider.py:190
|
||||||
msgid "showing bytes {0} to {1} ({2})"
|
msgid "showing bytes {0} to {1} ({2})"
|
||||||
msgstr "Anzeigebereich: Bytes {0} bis {1} ({2})"
|
msgstr "Anzeigebereich: Bytes {0} bis {1} ({2})"
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: PACKAGE VERSION\n"
|
"Project-Id-Version: PACKAGE VERSION\n"
|
||||||
"POT-Creation-Date: 2024-03-24 12:00+0100\n"
|
"POT-Creation-Date: 2025-03-24 19:02+0100\n"
|
||||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||||
@@ -15,8 +15,8 @@ msgstr ""
|
|||||||
"Generated-By: pygettext.py 1.5\n"
|
"Generated-By: pygettext.py 1.5\n"
|
||||||
|
|
||||||
|
|
||||||
#: src/mainwindow.py:32 src/plugins/krowlog/aboutdialog.py:30
|
#: src/mainwindow.py:32 src/new_big_text/bigger_text.py:75
|
||||||
#: src/plugins/krowlogplugin.py:85
|
#: src/plugins/krowlog/aboutdialog.py:30 src/plugins/krowlogplugin.py:85
|
||||||
msgid "KrowLog"
|
msgid "KrowLog"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -140,31 +140,31 @@ msgstr ""
|
|||||||
msgid "E&xit"
|
msgid "E&xit"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/plugins/logfile/filterwidget.py:181
|
#: src/plugins/logfile/filterwidget.py:192
|
||||||
msgid "Cancel"
|
msgid "Cancel"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/plugins/logfile/filterwidget.py:187
|
#: src/plugins/logfile/filterwidget.py:198
|
||||||
msgid "save query"
|
msgid "save query"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/plugins/logfile/filterwidget.py:192
|
#: src/plugins/logfile/filterwidget.py:203
|
||||||
msgid "ignore case"
|
msgid "ignore case"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/plugins/logfile/filterwidget.py:196
|
#: src/plugins/logfile/filterwidget.py:207
|
||||||
msgid "regex"
|
msgid "regex"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/plugins/logfile/filterwidget.py:206
|
#: src/plugins/logfile/filterwidget.py:217
|
||||||
msgid "only matches"
|
msgid "only matches"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/plugins/logfile/filterwidget.py:298
|
#: src/plugins/logfile/filterwidget.py:309
|
||||||
msgid "({hits} lines)"
|
msgid "({hits} lines)"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/plugins/logfileplugin.py:35 src/ui/bigtext/bigtext.py:258
|
#: src/plugins/logfileplugin.py:35 src/ui/bigtext/bigtext.py:263
|
||||||
msgid "&Highlighter"
|
msgid "&Highlighter"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -208,51 +208,55 @@ msgstr ""
|
|||||||
msgid "h"
|
msgid "h"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/ui/bigtext/bigtext.py:238
|
#: src/ui/bigtext/bigtext.py:243
|
||||||
msgid "&Copy to Clipboard"
|
msgid "&Copy to Clipboard"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/ui/bigtext/bigtext.py:246
|
#: src/ui/bigtext/bigtext.py:251
|
||||||
msgid "Copy to &File"
|
msgid "Copy to &File"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/ui/bigtext/bigtext.py:252
|
#: src/ui/bigtext/bigtext.py:257
|
||||||
msgid "Select &All"
|
msgid "Select &All"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/ui/bigtext/bigtext.py:268
|
#: src/ui/bigtext/bigtext.py:270
|
||||||
|
msgid "&Follow"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/ui/bigtext/bigtext.py:280
|
||||||
msgid "Set Range Start"
|
msgid "Set Range Start"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/ui/bigtext/bigtext.py:276
|
#: src/ui/bigtext/bigtext.py:288
|
||||||
msgid "Set Range End"
|
msgid "Set Range End"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/ui/bigtext/bigtext.py:283
|
#: src/ui/bigtext/bigtext.py:295
|
||||||
msgid "Reset Range"
|
msgid "Reset Range"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/ui/bigtext/bigtext.py:458
|
#: src/ui/bigtext/bigtext.py:526
|
||||||
msgid "warning"
|
msgid "warning"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/ui/bigtext/bigtext.py:459
|
#: src/ui/bigtext/bigtext.py:527
|
||||||
msgid "You have selected <b>{0}</b> of data."
|
msgid "You have selected <b>{0}</b> of data."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/ui/bigtext/bigtext.py:464
|
#: src/ui/bigtext/bigtext.py:532
|
||||||
msgid "Copy {0} to Clipboard"
|
msgid "Copy {0} to Clipboard"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/ui/bigtext/bigtext.py:468
|
#: src/ui/bigtext/bigtext.py:536
|
||||||
msgid "Write to File"
|
msgid "Write to File"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/ui/bigtext/bigtext.py:492
|
#: src/ui/bigtext/bigtext.py:560
|
||||||
msgid "Save File"
|
msgid "Save File"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/ui/bigtext/bigtext.py:529
|
#: src/ui/bigtext/bigtext.py:605
|
||||||
msgid "selected {0} - {1:,.0f}:{2:,.0f}"
|
msgid "selected {0} - {1:,.0f}:{2:,.0f}"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -300,6 +304,10 @@ msgstr ""
|
|||||||
msgid "Regular Expression"
|
msgid "Regular Expression"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/ui/bigtext/newhighlightingdialog.py:185
|
||||||
|
msgid "File Type:"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/ui/colorbutton.py:20
|
#: src/ui/colorbutton.py:20
|
||||||
msgid "Strawberry Cream"
|
msgid "Strawberry Cream"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@@ -364,7 +372,7 @@ msgstr ""
|
|||||||
msgid "transparent"
|
msgid "transparent"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/ui/rangeslider.py:180
|
#: src/ui/rangeslider.py:190
|
||||||
msgid "showing bytes {0} to {1} ({2})"
|
msgid "showing bytes {0} to {1} ({2})"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
import PyInstaller.__main__
|
import PyInstaller.__main__
|
||||||
import os
|
import os
|
||||||
|
|
||||||
|
os.system("git -C . describe --match \"*.*.*\" --tags > version.txt")
|
||||||
|
|
||||||
PyInstaller.__main__.run([
|
PyInstaller.__main__.run([
|
||||||
'krowlog.py',
|
'krowlog.py',
|
||||||
# '--onefile',
|
# '--onefile',
|
||||||
@@ -12,6 +14,7 @@ PyInstaller.__main__.run([
|
|||||||
'--add-binary', 'icons' + os.pathsep + 'icons',
|
'--add-binary', 'icons' + os.pathsep + 'icons',
|
||||||
'--add-binary', 'locales' + os.pathsep + 'locales',
|
'--add-binary', 'locales' + os.pathsep + 'locales',
|
||||||
'--add-binary', 'LICENSE' + os.pathsep + '.',
|
'--add-binary', 'LICENSE' + os.pathsep + '.',
|
||||||
|
'--add-binary', 'version.txt' + os.pathsep + '.',
|
||||||
'--hidden-import=krowlog',
|
'--hidden-import=krowlog',
|
||||||
'--hidden-import=watchdog',
|
'--hidden-import=watchdog',
|
||||||
'--hidden-import=watchdog.observers',
|
'--hidden-import=watchdog.observers',
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
pip==24.0
|
pip==25.0.1
|
||||||
PySide6_Essentials==6.7.0
|
PySide6_Essentials==6.8.2.1
|
||||||
setuptools==69.5.1
|
setuptools==77.0.3
|
||||||
watchdog==4.0.0
|
watchdog==6.0.0
|
||||||
pyinstaller==6.6.0
|
pyinstaller==6.12.0
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ class AboutDialog(QDialog):
|
|||||||
result.layout = QVBoxLayout(result)
|
result.layout = QVBoxLayout(result)
|
||||||
label = Label("{0}<br>{1}<br>{2}".format(
|
label = Label("{0}<br>{1}<br>{2}".format(
|
||||||
_("KrowLog is a viewer for log files of arbitrary size."),
|
_("KrowLog is a viewer for log files of arbitrary size."),
|
||||||
_("(c) 2022-2024 Andreas Huber"),
|
_("(c) 2022-2025 Andreas Huber"),
|
||||||
_("License: LGPL v3")
|
_("License: LGPL v3")
|
||||||
))
|
))
|
||||||
result.layout.addWidget(label)
|
result.layout.addWidget(label)
|
||||||
|
|||||||
@@ -237,7 +237,7 @@ class FilterWidget(QWidget):
|
|||||||
(handle, self.tmp_filename) = tempfile.mkstemp()
|
(handle, self.tmp_filename) = tempfile.mkstemp()
|
||||||
os.close(handle)
|
os.close(handle)
|
||||||
self.filter_model = LogFileModel(self.tmp_filename, self.source_model.settings, source_model.get_file())
|
self.filter_model = LogFileModel(self.tmp_filename, self.source_model.settings, source_model.get_file())
|
||||||
self.hits_view = BigText(self.filter_model, show_range_slider=False)
|
self.hits_view = BigText(self.filter_model, show_range_slider=False, show_follow_action=False)
|
||||||
|
|
||||||
self.layout.addWidget(filter_bar)
|
self.layout.addWidget(filter_bar)
|
||||||
self.layout.addWidget(self.hits_view)
|
self.layout.addWidget(self.hits_view)
|
||||||
|
|||||||
@@ -14,6 +14,9 @@ class BigScrollBar(QWidget):
|
|||||||
code involved. We work around this by converting the python int
|
code involved. We work around this by converting the python int
|
||||||
into a string."""
|
into a string."""
|
||||||
|
|
||||||
|
user_interaction = Signal()
|
||||||
|
"""signals that the user changed a value (the opposite is that some code changed the value) """
|
||||||
|
|
||||||
class ScrollEvent(enum.IntEnum):
|
class ScrollEvent(enum.IntEnum):
|
||||||
PageUp = 1
|
PageUp = 1
|
||||||
PageDown = 2
|
PageDown = 2
|
||||||
@@ -138,21 +141,27 @@ class BigScrollBar(QWidget):
|
|||||||
trigger_repeat_action = True
|
trigger_repeat_action = True
|
||||||
match self.repeat_action_control:
|
match self.repeat_action_control:
|
||||||
case QStyle.SubControl.SC_ScrollBarAddPage:
|
case QStyle.SubControl.SC_ScrollBarAddPage:
|
||||||
|
self.user_interaction.emit()
|
||||||
self.scroll_event.emit(self.ScrollEvent.PageDown)
|
self.scroll_event.emit(self.ScrollEvent.PageDown)
|
||||||
case QStyle.SubControl.SC_ScrollBarSubPage:
|
case QStyle.SubControl.SC_ScrollBarSubPage:
|
||||||
|
self.user_interaction.emit()
|
||||||
self.scroll_event.emit(self.ScrollEvent.PageUp)
|
self.scroll_event.emit(self.ScrollEvent.PageUp)
|
||||||
if self.value <= self.minimum:
|
if self.value <= self.minimum:
|
||||||
trigger_repeat_action = False
|
trigger_repeat_action = False
|
||||||
case QStyle.SubControl.SC_ScrollBarAddLine:
|
case QStyle.SubControl.SC_ScrollBarAddLine:
|
||||||
|
self.user_interaction.emit()
|
||||||
self.scroll_event.emit(self.ScrollEvent.LinesDown)
|
self.scroll_event.emit(self.ScrollEvent.LinesDown)
|
||||||
case QStyle.SubControl.SC_ScrollBarSubLine:
|
case QStyle.SubControl.SC_ScrollBarSubLine:
|
||||||
|
self.user_interaction.emit()
|
||||||
self.scroll_event.emit(self.ScrollEvent.LinesUp)
|
self.scroll_event.emit(self.ScrollEvent.LinesUp)
|
||||||
if self.value <= self.minimum:
|
if self.value <= self.minimum:
|
||||||
trigger_repeat_action = False
|
trigger_repeat_action = False
|
||||||
case QStyle.SubControl.SC_ScrollBarFirst:
|
case QStyle.SubControl.SC_ScrollBarFirst:
|
||||||
|
self.user_interaction.emit()
|
||||||
self.set_value(self.minimum)
|
self.set_value(self.minimum)
|
||||||
trigger_repeat_action = False
|
trigger_repeat_action = False
|
||||||
case QStyle.SubControl.SC_ScrollBarLast:
|
case QStyle.SubControl.SC_ScrollBarLast:
|
||||||
|
self.user_interaction.emit()
|
||||||
self.set_value(self.maximum)
|
self.set_value(self.maximum)
|
||||||
trigger_repeat_action = False
|
trigger_repeat_action = False
|
||||||
case _:
|
case _:
|
||||||
@@ -180,6 +189,7 @@ class BigScrollBar(QWidget):
|
|||||||
if not r.contains(event.position().toPoint()):
|
if not r.contains(event.position().toPoint()):
|
||||||
new_position = self.snap_back_position
|
new_position = self.snap_back_position
|
||||||
|
|
||||||
|
self.user_interaction.emit()
|
||||||
# print(f"move to value: {new_position}")
|
# print(f"move to value: {new_position}")
|
||||||
self.set_value(new_position)
|
self.set_value(new_position)
|
||||||
|
|
||||||
@@ -227,7 +237,10 @@ class BigScrollBar(QWidget):
|
|||||||
self.repeat_action_timer.stop()
|
self.repeat_action_timer.stop()
|
||||||
#self.update()
|
#self.update()
|
||||||
|
|
||||||
def set_value(self, value: int):
|
def set_value(self, value: int, emit_change_event=True):
|
||||||
|
changed = self.value != value
|
||||||
self.value = value
|
self.value = value
|
||||||
self.value_changed.emit(str(self.value))
|
if emit_change_event and changed:
|
||||||
|
# print(f"emitting value changed: {self.value}")
|
||||||
|
self.value_changed.emit(str(self.value))
|
||||||
self.update()
|
self.update()
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ from src.ui.bigtext.highlighted_range import HighlightedRange
|
|||||||
from src.ui.bigtext.line import Line
|
from src.ui.bigtext.line import Line
|
||||||
from src.ui.bigtext.logFileModel import LogFileModel
|
from src.ui.bigtext.logFileModel import LogFileModel
|
||||||
from src.ui.bigtext.newhighlightingdialog import NewHighlightingDialog
|
from src.ui.bigtext.newhighlightingdialog import NewHighlightingDialog
|
||||||
|
from src.ui.bigtext.selectionPos import SelectionPos
|
||||||
from src.ui.icon import Icon
|
from src.ui.icon import Icon
|
||||||
from src.ui.rangeslider import RangeSlider
|
from src.ui.rangeslider import RangeSlider
|
||||||
from src.util.conversion import humanbytes
|
from src.util.conversion import humanbytes
|
||||||
@@ -30,6 +31,7 @@ from src.i18n import _
|
|||||||
|
|
||||||
log = logging.getLogger("bigtext")
|
log = logging.getLogger("bigtext")
|
||||||
|
|
||||||
|
|
||||||
class FileObserver(FileSystemEventHandler):
|
class FileObserver(FileSystemEventHandler):
|
||||||
|
|
||||||
def __init__(self, big_text):
|
def __init__(self, big_text):
|
||||||
@@ -75,10 +77,11 @@ class FileWatchdogThread(QRunnable):
|
|||||||
class BigText(QWidget):
|
class BigText(QWidget):
|
||||||
trigger_update = Signal()
|
trigger_update = Signal()
|
||||||
|
|
||||||
def __init__(self, model: LogFileModel, show_range_slider=True):
|
def __init__(self, model: LogFileModel, show_range_slider=True, show_follow_action=True):
|
||||||
super(BigText, self).__init__()
|
super(BigText, self).__init__()
|
||||||
|
|
||||||
self.show_range_slider = show_range_slider
|
self.show_range_slider = show_range_slider
|
||||||
|
self.show_follow_action = show_follow_action
|
||||||
self.model = model
|
self.model = model
|
||||||
|
|
||||||
self.grid = QGridLayout()
|
self.grid = QGridLayout()
|
||||||
@@ -100,6 +103,7 @@ class BigText(QWidget):
|
|||||||
# self.v_scroll_bar.setPageStep(1)
|
# self.v_scroll_bar.setPageStep(1)
|
||||||
self.v_scroll_bar.value_changed.connect(self.big_text.v_scroll_value_changed)
|
self.v_scroll_bar.value_changed.connect(self.big_text.v_scroll_value_changed)
|
||||||
self.v_scroll_bar.scroll_event.connect(self.big_text.v_scroll_event)
|
self.v_scroll_bar.scroll_event.connect(self.big_text.v_scroll_event)
|
||||||
|
self.v_scroll_bar.user_interaction.connect(self.big_text.user_scroll_interaction)
|
||||||
|
|
||||||
if show_range_slider:
|
if show_range_slider:
|
||||||
self.range_limit = RangeSlider()
|
self.range_limit = RangeSlider()
|
||||||
@@ -145,13 +149,15 @@ class BigText(QWidget):
|
|||||||
# noinspection PyArgumentList,PyTypeChecker
|
# noinspection PyArgumentList,PyTypeChecker
|
||||||
class InnerBigText(QWidget):
|
class InnerBigText(QWidget):
|
||||||
_byte_offset = 0
|
_byte_offset = 0
|
||||||
_left_offset = 0 # number of characters the horizontal scrollbar was moved to the right
|
_left_offset = 0 # number of pixels the horizontal scrollbar was moved to the right
|
||||||
scroll_lines = 0
|
scroll_lines = 0
|
||||||
longest_line = 0
|
longest_line = 0
|
||||||
|
|
||||||
_range_start = 0
|
_range_start = 0
|
||||||
_range_end = -1
|
_range_end = -1
|
||||||
|
|
||||||
|
_follow = False
|
||||||
|
|
||||||
def __init__(self, parent: BigText, model: LogFileModel, v_scaled_scrollbar: ScaledScrollBar):
|
def __init__(self, parent: BigText, model: LogFileModel, v_scaled_scrollbar: ScaledScrollBar):
|
||||||
super(InnerBigText, self).__init__()
|
super(InnerBigText, self).__init__()
|
||||||
self.char_height = None
|
self.char_height = None
|
||||||
@@ -260,6 +266,12 @@ class InnerBigText(QWidget):
|
|||||||
manage_highlighting.setShortcut("CTRL+H")
|
manage_highlighting.setShortcut("CTRL+H")
|
||||||
menu.addAction(manage_highlighting)
|
menu.addAction(manage_highlighting)
|
||||||
|
|
||||||
|
if self.parent.show_follow_action:
|
||||||
|
follow = QAction(_("&Follow"), self, triggered=self._toggle_follow)
|
||||||
|
follow.setCheckable(True)
|
||||||
|
follow.setChecked(self._follow)
|
||||||
|
menu.addAction(follow)
|
||||||
|
|
||||||
if self.parent.show_range_slider:
|
if self.parent.show_range_slider:
|
||||||
menu.addSeparator()
|
menu.addSeparator()
|
||||||
|
|
||||||
@@ -307,8 +319,12 @@ class InnerBigText(QWidget):
|
|||||||
self.parent.range_limit.set_range_start(0)
|
self.parent.range_limit.set_range_start(0)
|
||||||
self.parent.range_limit.set_range_end(self.model.byte_count())
|
self.parent.range_limit.set_range_end(self.model.byte_count())
|
||||||
|
|
||||||
|
def user_scroll_interaction(self):
|
||||||
|
self._follow = False
|
||||||
|
|
||||||
def scroll_by_lines(self, scroll_lines: int):
|
def scroll_by_lines(self, scroll_lines: int):
|
||||||
self.scroll_lines = scroll_lines
|
self.scroll_lines = scroll_lines
|
||||||
|
self._follow = False
|
||||||
self.update()
|
self.update()
|
||||||
self.parent.v_scroll_bar.set_value(self._byte_offset)
|
self.parent.v_scroll_bar.set_value(self._byte_offset)
|
||||||
|
|
||||||
@@ -320,8 +336,8 @@ class InnerBigText(QWidget):
|
|||||||
# noinspection PyTypeChecker
|
# noinspection PyTypeChecker
|
||||||
def mousePressEvent(self, e: QtGui.QMouseEvent) -> None:
|
def mousePressEvent(self, e: QtGui.QMouseEvent) -> None:
|
||||||
if e.buttons() == Qt.MouseButton.LeftButton and e.modifiers() == Qt.KeyboardModifier.ShiftModifier:
|
if e.buttons() == Qt.MouseButton.LeftButton and e.modifiers() == Qt.KeyboardModifier.ShiftModifier:
|
||||||
offset = self.to_byte_offset(e)
|
selection_pos = self.to_byte_offset(e)
|
||||||
self.selection_highlight.set_end_byte(offset)
|
self.selection_highlight.set_end_byte(selection_pos)
|
||||||
self._update_highlight_selected_text()
|
self._update_highlight_selected_text()
|
||||||
self.update()
|
self.update()
|
||||||
return
|
return
|
||||||
@@ -331,16 +347,16 @@ class InnerBigText(QWidget):
|
|||||||
line_number = self.y_pos_to_line(e.pos().y())
|
line_number = self.y_pos_to_line(e.pos().y())
|
||||||
if line_number == self._last_double_click_line_number and line_number < len(self.lines):
|
if line_number == self._last_double_click_line_number and line_number < len(self.lines):
|
||||||
line: Line = self.lines[line_number]
|
line: Line = self.lines[line_number]
|
||||||
self.selection_highlight.set_start(line.byte_offset())
|
self.selection_highlight.set_start(SelectionPos(line.byte_offset(), True, 1))
|
||||||
self.selection_highlight.set_end_byte(line.byte_end())
|
self.selection_highlight.set_end_byte(SelectionPos(line.byte_end() - 1, False, 1))
|
||||||
self._update_highlight_selected_text()
|
self._update_highlight_selected_text()
|
||||||
self.update()
|
self.update()
|
||||||
return
|
return
|
||||||
|
|
||||||
if e.buttons() == Qt.MouseButton.LeftButton and e.modifiers() == Qt.KeyboardModifier.NoModifier:
|
if e.buttons() == Qt.MouseButton.LeftButton and e.modifiers() == Qt.KeyboardModifier.NoModifier:
|
||||||
offset = self.to_byte_offset(e)
|
selection_pos = self.to_byte_offset(e)
|
||||||
self.selection_highlight.set_start(offset)
|
self.selection_highlight.set_start(selection_pos)
|
||||||
self.selection_highlight.set_end_byte(offset)
|
self.selection_highlight.set_end_byte(selection_pos)
|
||||||
self._update_highlight_selected_text()
|
self._update_highlight_selected_text()
|
||||||
self.update()
|
self.update()
|
||||||
|
|
||||||
@@ -355,14 +371,17 @@ class InnerBigText(QWidget):
|
|||||||
self._last_double_click_time = time.time()
|
self._last_double_click_time = time.time()
|
||||||
self._last_double_click_line_number = self.y_pos_to_line(e.pos().y())
|
self._last_double_click_line_number = self.y_pos_to_line(e.pos().y())
|
||||||
|
|
||||||
offset = self.to_byte_offset(e)
|
selection_pos = self.to_byte_offset(e)
|
||||||
(_word, start_byte, end_byte) = self.model.read_word_at(offset)
|
(word, start_byte, end_byte) = self.model.read_word_at(selection_pos.pos())
|
||||||
if start_byte >= 0 and end_byte >= 0:
|
if start_byte >= 0 and end_byte >= 0:
|
||||||
self.selection_highlight.set_start(start_byte)
|
bytes_of_first_char = len(f"{word[0]}".encode("utf8"))
|
||||||
self.selection_highlight.set_end_byte(end_byte)
|
self.selection_highlight.set_start(SelectionPos(start_byte, True, bytes_of_first_char))
|
||||||
|
bytes_of_last_char = len(f"{word[-1]}".encode("utf8"))
|
||||||
|
self.selection_highlight.set_end_byte(
|
||||||
|
SelectionPos(end_byte - bytes_of_last_char, False, bytes_of_last_char))
|
||||||
else:
|
else:
|
||||||
self.selection_highlight.set_start(offset)
|
self.selection_highlight.set_start(selection_pos)
|
||||||
self.selection_highlight.set_end_byte(offset)
|
self.selection_highlight.set_end_byte(selection_pos)
|
||||||
|
|
||||||
self._update_highlight_selected_text()
|
self._update_highlight_selected_text()
|
||||||
self.update()
|
self.update()
|
||||||
@@ -372,10 +391,10 @@ class InnerBigText(QWidget):
|
|||||||
if e.buttons() != Qt.MouseButton.LeftButton:
|
if e.buttons() != Qt.MouseButton.LeftButton:
|
||||||
return
|
return
|
||||||
|
|
||||||
current_byte = self.to_byte_offset(e)
|
selection_pos = self.to_byte_offset(e)
|
||||||
|
|
||||||
if self.selection_highlight.end_byte != current_byte:
|
if self.selection_highlight.max_byte() != selection_pos.pos():
|
||||||
self.selection_highlight.set_end_byte(current_byte)
|
self.selection_highlight.set_end_byte(selection_pos)
|
||||||
self._update_highlight_selected_text()
|
self._update_highlight_selected_text()
|
||||||
self.update()
|
self.update()
|
||||||
# print("-> %s,%s" %(self._selection_start_byte, self._selection_end_byte))
|
# print("-> %s,%s" %(self._selection_start_byte, self._selection_end_byte))
|
||||||
@@ -386,10 +405,16 @@ class InnerBigText(QWidget):
|
|||||||
self.scroll_by_lines(-1)
|
self.scroll_by_lines(-1)
|
||||||
if line_number > int(self.lines_shown()):
|
if line_number > int(self.lines_shown()):
|
||||||
self.scroll_by_lines(1)
|
self.scroll_by_lines(1)
|
||||||
if column_in_line <= 1:
|
# if column_in_line <= 1:
|
||||||
|
# self._left_offset = max(0, self._left_offset - 2)
|
||||||
|
# self.update()
|
||||||
|
if e.pos().x() <= 1:
|
||||||
self._left_offset = max(0, self._left_offset - 2)
|
self._left_offset = max(0, self._left_offset - 2)
|
||||||
self.update()
|
self.update()
|
||||||
if column_in_line + 1 >= self.columns_shown():
|
# if column_in_line + 1 >= self.columns_shown():
|
||||||
|
# self._left_offset = self._left_offset + 2
|
||||||
|
# self.update()
|
||||||
|
if e.pos().x() + 1 >= self.width():
|
||||||
self._left_offset = self._left_offset + 2
|
self._left_offset = self._left_offset + 2
|
||||||
self.update()
|
self.update()
|
||||||
|
|
||||||
@@ -416,12 +441,13 @@ class InnerBigText(QWidget):
|
|||||||
case BigScrollBar.ScrollEvent.PageDown:
|
case BigScrollBar.ScrollEvent.PageDown:
|
||||||
self.scroll_by_lines(int(self.lines_shown()) - 1)
|
self.scroll_by_lines(int(self.lines_shown()) - 1)
|
||||||
|
|
||||||
def update_longest_line(self, length: int):
|
def update_longest_line(self, line: Line):
|
||||||
width_in_chars = self.width() / self.char_width
|
|
||||||
# print("width_in_chars: %d" % width_in_chars)
|
# print("width_in_chars: %d" % width_in_chars)
|
||||||
if self.longest_line < length:
|
text_width_in_px = line.get_width_in_px(self.font_metric);
|
||||||
self.longest_line = length
|
if self.longest_line < text_width_in_px:
|
||||||
maximum = max(0, length - width_in_chars + 1)
|
self.longest_line = text_width_in_px
|
||||||
|
maximum = max(0, text_width_in_px - self.width() + 1)
|
||||||
self.parent.h_scroll_bar.setMaximum(round(maximum))
|
self.parent.h_scroll_bar.setMaximum(round(maximum))
|
||||||
|
|
||||||
def y_pos_to_line(self, y: int) -> int:
|
def y_pos_to_line(self, y: int) -> int:
|
||||||
@@ -436,29 +462,63 @@ class InnerBigText(QWidget):
|
|||||||
def columns_shown(self) -> float:
|
def columns_shown(self) -> float:
|
||||||
return self.width() / float(self.char_width)
|
return self.width() / float(self.char_width)
|
||||||
|
|
||||||
def to_byte_offset(self, e: QMouseEvent) -> int:
|
def to_byte_offset(self, e: QMouseEvent) -> SelectionPos:
|
||||||
|
|
||||||
|
x = e.pos().x() + self._left_offset
|
||||||
line_number = self.y_pos_to_line(e.pos().y())
|
line_number = self.y_pos_to_line(e.pos().y())
|
||||||
|
|
||||||
if line_number < len(self.lines):
|
if line_number < len(self.lines):
|
||||||
line: Line = self.lines[line_number]
|
line: Line = self.lines[line_number]
|
||||||
column_in_line = self.x_pos_to_column(e.pos().x()) + self._left_offset
|
|
||||||
column_in_line = min(column_in_line, line.length_in_columns()) # x was behind the last column of this line
|
text: str = line.line()
|
||||||
char_in_line = line.column_to_char(column_in_line)
|
text = text.replace("\n", "").replace("\r", "")
|
||||||
# print("%s in line %s column_in_line=%s" % (char_in_line, line_number, column_in_line))
|
|
||||||
byte_in_line = line.char_index_to_byte(char_in_line)
|
elided_text: str = self.elided_text(text, x)
|
||||||
current_byte = line.byte_offset() + byte_in_line
|
byte_offset = line.byte_offset() + len(elided_text.encode("utf8"))
|
||||||
# print("%s + %s = %s" % (line.byte_offset(), char_in_line, current_byte))
|
|
||||||
|
left_x_offset = self.font_metric.horizontalAdvance((elided_text))
|
||||||
|
|
||||||
|
next_char = ""
|
||||||
|
pos_is_in_left_half = False
|
||||||
|
bytes_of_char = 0
|
||||||
|
if len(text) > len(elided_text): # has another character
|
||||||
|
next_char = text[len(elided_text)]
|
||||||
|
char_width = self.font_metric.horizontalAdvance(next_char)
|
||||||
|
pos_is_in_left_half = x < (left_x_offset + char_width / 2)
|
||||||
|
bytes_of_char = len(next_char.encode("utf8"))
|
||||||
|
else:
|
||||||
|
# print(f"{x} is after last char, elided_text={elided_text}")
|
||||||
|
# the position is after the last character / behind the end of the line
|
||||||
|
pass
|
||||||
|
|
||||||
|
# print(f"{x} -> {byte_offset} {'left' if pos_is_in_left_half else 'right'} bytes_of_char={bytes_of_char}")
|
||||||
|
return SelectionPos(byte_offset, pos_is_in_left_half, bytes_of_char)
|
||||||
|
|
||||||
|
# column_in_line = self.x_pos_to_column(e.pos().x()) + self._left_offset
|
||||||
|
# column_in_line = min(column_in_line, line.length_in_columns()) # x was behind the last column of this line
|
||||||
|
# char_in_line = line.column_to_char(column_in_line)
|
||||||
|
# # print("%s in line %s column_in_line=%s" % (char_in_line, line_number, column_in_line))
|
||||||
|
# byte_in_line = line.char_index_to_byte(char_in_line)
|
||||||
|
# current_byte = line.byte_offset() + byte_in_line
|
||||||
|
# # print("%s + %s = %s" % (line.byte_offset(), char_in_line, current_byte))
|
||||||
else:
|
else:
|
||||||
current_byte = self.model.byte_count()
|
current_byte = self.model.byte_count()
|
||||||
return current_byte
|
return current_byte
|
||||||
|
|
||||||
|
def elided_text(self, text: str, width: int):
|
||||||
|
w = width + self.font_metric.horizontalAdvance("…")
|
||||||
|
elided_text = self.font_metric.elidedText(text + "…", Qt.TextElideMode.ElideRight, w,
|
||||||
|
Qt.TextFlag.TextWrapAnywhere)
|
||||||
|
elided_text = elided_text[0:-1] if elided_text.endswith('…') else elided_text # remove the trailing '…'
|
||||||
|
return elided_text
|
||||||
|
|
||||||
def _has_selection(self):
|
def _has_selection(self):
|
||||||
return self.selection_highlight.start_byte != self.selection_highlight.end_byte
|
return self.selection_highlight.min_byte() != self.selection_highlight.max_byte()
|
||||||
|
|
||||||
def copy_selection(self):
|
def copy_selection(self):
|
||||||
if self._has_selection():
|
if self._has_selection():
|
||||||
start = min(self.selection_highlight.start_byte, self.selection_highlight.end_byte)
|
start = self.selection_highlight.min_byte()
|
||||||
end = max(self.selection_highlight.start_byte, self.selection_highlight.end_byte)
|
end = self.selection_highlight.max_byte()
|
||||||
bytes_human_readable = humanbytes(end - start)
|
bytes_human_readable = humanbytes(end - start)
|
||||||
if end - start > (1024 ** 2) * 5:
|
if end - start > (1024 ** 2) * 5:
|
||||||
you_sure = QMessageBox(
|
you_sure = QMessageBox(
|
||||||
@@ -492,8 +552,8 @@ class InnerBigText(QWidget):
|
|||||||
|
|
||||||
def _copy_selection_to_file(self):
|
def _copy_selection_to_file(self):
|
||||||
if self._has_selection():
|
if self._has_selection():
|
||||||
start = min(self.selection_highlight.start_byte, self.selection_highlight.end_byte)
|
start = self.selection_highlight.min_byte()
|
||||||
end = max(self.selection_highlight.start_byte, self.selection_highlight.end_byte)
|
end = self.selection_highlight.max_byte()
|
||||||
dialog = QFileDialog(self)
|
dialog = QFileDialog(self)
|
||||||
(selected_file, _filter) = dialog.getSaveFileName(
|
(selected_file, _filter) = dialog.getSaveFileName(
|
||||||
parent=self,
|
parent=self,
|
||||||
@@ -507,18 +567,26 @@ class InnerBigText(QWidget):
|
|||||||
PluginRegistry.execute("open_file", selected_file)
|
PluginRegistry.execute("open_file", selected_file)
|
||||||
|
|
||||||
def _select_all(self):
|
def _select_all(self):
|
||||||
self.selection_highlight.start_byte = self.model.get_line_start_at(self._range_start)
|
start_byte = self.model.get_line_start_at(self._range_start)
|
||||||
if self._range_end < 0 or self.model.byte_count() <= self._range_end:
|
if self._range_end < 0 or self.model.byte_count() <= self._range_end:
|
||||||
self.selection_highlight.end_byte = self.model.byte_count()
|
end_byte = self.model.byte_count()
|
||||||
else:
|
else:
|
||||||
self.selection_highlight.end_byte = self.model.get_line_start_at(self._range_end)
|
end_byte = self.model.get_line_start_at(self._range_end)
|
||||||
|
|
||||||
|
self.selection_highlight.set_start(SelectionPos(start_byte, True, 1))
|
||||||
|
self.selection_highlight.set_end_byte(SelectionPos(end_byte, False, 1))
|
||||||
|
|
||||||
self._update_highlight_selected_text()
|
self._update_highlight_selected_text()
|
||||||
self.update()
|
self.update()
|
||||||
|
|
||||||
|
def _toggle_follow(self):
|
||||||
|
self._follow = not self._follow
|
||||||
|
print(f"follow={self._follow}")
|
||||||
|
self.update()
|
||||||
|
|
||||||
def _update_highlight_selected_text(self):
|
def _update_highlight_selected_text(self):
|
||||||
start_byte = min(self.selection_highlight.start_byte, self.selection_highlight.end_byte)
|
start_byte = self.selection_highlight.min_byte()
|
||||||
end_byte = max(self.selection_highlight.start_byte, self.selection_highlight.end_byte)
|
end_byte = self.selection_highlight.max_byte()
|
||||||
|
|
||||||
self._update_status_bar(start_byte, end_byte)
|
self._update_status_bar(start_byte, end_byte)
|
||||||
|
|
||||||
@@ -545,14 +613,30 @@ class InnerBigText(QWidget):
|
|||||||
def paintEvent(self, event: QPaintEvent) -> None:
|
def paintEvent(self, event: QPaintEvent) -> None:
|
||||||
start_ns = time.process_time_ns()
|
start_ns = time.process_time_ns()
|
||||||
painter = QPainter(self)
|
painter = QPainter(self)
|
||||||
|
|
||||||
# font = "Courier New" if sys.platform == 'win32' or sys.platform == 'cygwin' else "Monospace"
|
# font = "Courier New" if sys.platform == 'win32' or sys.platform == 'cygwin' else "Monospace"
|
||||||
painter.setFont(QFont("Courier New", self.model.settings.getint_session('general', "font_size")))
|
# "Courier New"
|
||||||
|
# "JetBrains Mono"
|
||||||
|
# "Noto Sans Mono"
|
||||||
|
# "Noto Color Emoji"
|
||||||
|
# "Andale Mono"
|
||||||
|
qfont = QFont("Monospace", self.model.settings.getint_session('general', "font_size"))
|
||||||
|
qfont.setStyleHint(QFont.StyleHint.Monospace)
|
||||||
|
painter.setFont(qfont)
|
||||||
|
self.font_metric = painter.fontMetrics()
|
||||||
|
|
||||||
|
|
||||||
painter.setPen(QColor(0, 0, 0))
|
painter.setPen(QColor(0, 0, 0))
|
||||||
self.update_font_metrics(painter)
|
self.update_font_metrics(painter)
|
||||||
|
|
||||||
lines_to_show = math.ceil(self.lines_shown())
|
lines_to_show = math.ceil(self.lines_shown())
|
||||||
# print("%s / %s = %s" %(self.height(), float(self.char_height), lines_to_show))
|
# print("%s / %s = %s" %(self.height(), float(self.char_height), lines_to_show))
|
||||||
|
|
||||||
|
if self._range_end >= 0 and self._follow:
|
||||||
|
self.scroll_lines = 0
|
||||||
|
self._byte_offset = self.model.byte_count() - 1
|
||||||
|
self.parent.v_scroll_bar.set_value(self._byte_offset)
|
||||||
|
|
||||||
self.lines = self.model.data(self._byte_offset, self.scroll_lines, lines_to_show, self._range_start,
|
self.lines = self.model.data(self._byte_offset, self.scroll_lines, lines_to_show, self._range_start,
|
||||||
self._range_end)
|
self._range_end)
|
||||||
# print("lines_to_show: %d returned: %d" % (lines_to_show, len(self.lines)))
|
# print("lines_to_show: %d returned: %d" % (lines_to_show, len(self.lines)))
|
||||||
@@ -567,7 +651,7 @@ class InnerBigText(QWidget):
|
|||||||
self.parent.range_limit.set_maximum(byte_count)
|
self.parent.range_limit.set_maximum(byte_count)
|
||||||
|
|
||||||
for line in self.lines:
|
for line in self.lines:
|
||||||
self.update_longest_line(len(line.line()))
|
self.update_longest_line(line)
|
||||||
|
|
||||||
highlighters = self.model.highlighters()
|
highlighters = self.model.highlighters()
|
||||||
if self.model.get_query_highlight():
|
if self.model.get_query_highlight():
|
||||||
@@ -586,23 +670,24 @@ class InnerBigText(QWidget):
|
|||||||
if optional_highlight_range:
|
if optional_highlight_range:
|
||||||
highlight_ranges = highlight_ranges + optional_highlight_range
|
highlight_ranges = highlight_ranges + optional_highlight_range
|
||||||
|
|
||||||
self.draw_highlights(highlight_ranges, painter, y_line_offset)
|
self.draw_highlights(highlight_ranges, painter, y_line_offset, line)
|
||||||
y_line_offset = y_line_offset + self.char_height
|
y_line_offset = y_line_offset + self.char_height
|
||||||
|
|
||||||
left_offset = int(-1 * self._left_offset * self.char_width)
|
# left_offset = int(-1 * self._left_offset * self.char_width)
|
||||||
|
left_offset = int(-1 * self._left_offset)
|
||||||
y_line_offset = self.char_height
|
y_line_offset = self.char_height
|
||||||
for line in self.lines:
|
for line in self.lines:
|
||||||
text = line.line_prepared_for_display()
|
text = line.line_prepared_for_display()
|
||||||
text = text[self._left_offset:self._left_offset + math.ceil(
|
# text = text[self._left_offset:self._left_offset + math.ceil(
|
||||||
self.columns_shown())] # reduce string to the visible section before drawing
|
# self.columns_shown())] # reduce string to the visible section before drawing
|
||||||
painter.drawText(0, y_line_offset, text)
|
painter.drawText(-self._left_offset, y_line_offset, text)
|
||||||
y_line_offset = y_line_offset + self.char_height
|
y_line_offset = y_line_offset + self.char_height
|
||||||
|
|
||||||
painter.end()
|
painter.end()
|
||||||
end_ns = time.process_time_ns()
|
end_ns = time.process_time_ns()
|
||||||
# print(f"paint took {(end_ns - start_ns) / 1000000.0}")
|
# print(f"paint took {(end_ns - start_ns) / 1000000.0}")
|
||||||
|
|
||||||
def draw_highlights(self, highlights: [HighlightedRange], painter: QPainter, y_line_offset: int):
|
def draw_highlights(self, highlights: [HighlightedRange], painter: QPainter, y_line_offset: int, line: Line):
|
||||||
|
|
||||||
for highlight in highlights:
|
for highlight in highlights:
|
||||||
if highlight.is_highlight_full_line():
|
if highlight.is_highlight_full_line():
|
||||||
@@ -612,15 +697,17 @@ class InnerBigText(QWidget):
|
|||||||
self.highlight_background(painter, rect, highlight.get_brush_full_line())
|
self.highlight_background(painter, rect, highlight.get_brush_full_line())
|
||||||
|
|
||||||
for highlight in highlights:
|
for highlight in highlights:
|
||||||
left_offset = self._left_offset * self.char_width
|
|
||||||
x1 = highlight.get_start() * self.char_width
|
x1 = self.font_metric.horizontalAdvance(
|
||||||
width = highlight.get_width() * self.char_width
|
line.prefix_bytes(highlight.get_start()).decode("utf8", errors="replace"))
|
||||||
|
width = self.font_metric.horizontalAdvance(
|
||||||
|
line.substr_bytes(highlight.get_start(), highlight.get_width()).decode("utf8", errors="replace"))
|
||||||
y1 = y_line_offset - self.char_height + self.char_height / 7
|
y1 = y_line_offset - self.char_height + self.char_height / 7
|
||||||
height = self.char_height
|
height = self.char_height
|
||||||
|
|
||||||
left = round(x1 - left_offset)
|
left = round(x1 - self._left_offset)
|
||||||
if x1 + width < left_offset \
|
if x1 + width < self._left_offset \
|
||||||
or x1 > left_offset + self.width():
|
or x1 > self._left_offset + self.width():
|
||||||
# too far left or too far right
|
# too far left or too far right
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
|||||||
@@ -71,12 +71,15 @@ class HighlightRegex(Highlight):
|
|||||||
# but we only want to highlight the groups
|
# but we only want to highlight the groups
|
||||||
first_group = 1 if len(match.groups()) > 0 else 0
|
first_group = 1 if len(match.groups()) > 0 else 0
|
||||||
for i in range(first_group, len(match.groups()) + 1):
|
for i in range(first_group, len(match.groups()) + 1):
|
||||||
start_column = line.char_to_column(match.start(i))
|
start_char_index = match.start(i)
|
||||||
end_column = line.char_to_column(match.end(i))
|
start_byte_index = len(line.prefix(start_char_index).encode("utf8"))
|
||||||
|
end_char_index = match.end(i)
|
||||||
|
width = len(line.substr(start_char_index, end_char_index - start_char_index).encode("utf8"))
|
||||||
|
|
||||||
# print(f"highlight: {start_column}:{end_column} - {match.group(i)}")
|
# print(f"highlight: {start_column}:{end_column} - {match.group(i)}")
|
||||||
result.append(HighlightedRange(
|
result.append(HighlightedRange(
|
||||||
start_column,
|
start_byte_index,
|
||||||
end_column - start_column,
|
width,
|
||||||
highlight_full_line=True,
|
highlight_full_line=True,
|
||||||
brush=self._brush_hit,
|
brush=self._brush_hit,
|
||||||
brush_full_line=self._brush_line
|
brush_full_line=self._brush_line
|
||||||
|
|||||||
@@ -7,50 +7,45 @@ from PySide6.QtCore import Qt
|
|||||||
from PySide6.QtGui import QBrush, QColor
|
from PySide6.QtGui import QBrush, QColor
|
||||||
|
|
||||||
from src.settings.settings import Settings
|
from src.settings.settings import Settings
|
||||||
|
from src.ui.bigtext.selectionPos import SelectionPos
|
||||||
|
|
||||||
|
|
||||||
class HighlightSelection(Highlight):
|
class HighlightSelection(Highlight):
|
||||||
start_byte = 0
|
start = SelectionPos(0, False, 0)
|
||||||
end_byte = 0
|
end = SelectionPos(0, False, 0)
|
||||||
|
|
||||||
def set_start(self, start_byte):
|
def set_start(self, start: SelectionPos):
|
||||||
self.start_byte = start_byte
|
self.start = start
|
||||||
|
|
||||||
def set_end_byte(self, end_byte):
|
def set_end_byte(self, end: SelectionPos):
|
||||||
self.end_byte = end_byte
|
self.end = end
|
||||||
|
|
||||||
|
def min_byte(self) -> int:
|
||||||
|
return min(self.start.pos(), self.end.pos())
|
||||||
|
|
||||||
|
def max_byte(self) -> int:
|
||||||
|
return max(self.start.pos(), self.end.pos())
|
||||||
|
|
||||||
def compute_highlight(self, line: Line) -> Optional[List[HighlightedRange]]:
|
def compute_highlight(self, line: Line) -> Optional[List[HighlightedRange]]:
|
||||||
begin = min(self.start_byte, self.end_byte)
|
begin = self.min_byte()
|
||||||
end = max(self.start_byte, self.end_byte)
|
end = self.max_byte()
|
||||||
|
|
||||||
if line.intersects(begin, end):
|
if line.intersects(begin, end):
|
||||||
|
|
||||||
if line.includes_byte(begin):
|
if line.includes_byte(begin):
|
||||||
start_byte_in_line = begin - line.byte_offset()
|
start_byte_in_line = begin - line.byte_offset()
|
||||||
else:
|
else:
|
||||||
start_byte_in_line = 0
|
start_byte_in_line = 0
|
||||||
|
|
||||||
start_char = line.byte_index_to_char_index(start_byte_in_line)
|
|
||||||
|
|
||||||
if line.includes_byte(end):
|
if line.includes_byte(end):
|
||||||
length_in_bytes = end - line.byte_offset() - start_byte_in_line
|
length_in_bytes = end - line.byte_offset() - start_byte_in_line
|
||||||
end_char = line.byte_index_to_char_index(start_byte_in_line + length_in_bytes)
|
|
||||||
else:
|
else:
|
||||||
# renders the highlighting to the end of the line
|
# renders the highlighting to the end of the line
|
||||||
# this is how selections usually behave
|
# this is how selections usually behave
|
||||||
length_in_bytes = Settings.max_line_length() - start_byte_in_line
|
length_in_bytes = Settings.max_line_length() - start_byte_in_line
|
||||||
|
|
||||||
# note: this mixes chars and bytes, but that should not matter, because
|
# print(f"compute_highlight: {line.substr_bytes(begin, end)} begin={begin} end={end} start_byte_in_line={start_byte_in_line} length_in_bytes={length_in_bytes}")
|
||||||
# it just means that we render the highlight into the invisible range on the right
|
return [HighlightedRange(start_byte_in_line, length_in_bytes, brush=QBrush(QColor(156, 215, 255, 192)),
|
||||||
end_char = start_char + length_in_bytes
|
|
||||||
|
|
||||||
start_column = line.char_to_column(start_char)
|
|
||||||
end_column = line.char_to_column(end_char)
|
|
||||||
if end_column >= 0:
|
|
||||||
length_in_columns = end_column - start_column
|
|
||||||
else:
|
|
||||||
length_in_columns = 4096
|
|
||||||
|
|
||||||
return [HighlightedRange(start_column, length_in_columns, brush=QBrush(QColor(156, 215, 255, 192)),
|
|
||||||
pen=Qt.PenStyle.NoPen)]
|
pen=Qt.PenStyle.NoPen)]
|
||||||
else:
|
else:
|
||||||
return None
|
return None
|
||||||
|
|||||||
@@ -1,16 +1,22 @@
|
|||||||
import unicodedata
|
import unicodedata
|
||||||
|
|
||||||
|
from PySide6.QtGui import QFontMetrics
|
||||||
|
|
||||||
import constants
|
import constants
|
||||||
|
|
||||||
|
|
||||||
class Line:
|
class Line:
|
||||||
def __init__(self, byte_offset: int, byte_end: int, line: str):
|
def __init__(self, byte_offset: int, byte_end: int, line: str, bytes: str):
|
||||||
self._byte_offset = byte_offset
|
self._byte_offset = byte_offset
|
||||||
self._byte_end = byte_end
|
self._byte_end = byte_end
|
||||||
self._line = line
|
self._line = line
|
||||||
|
self._bytes = bytes
|
||||||
|
|
||||||
self._cache_char_to_column()
|
self._cache_char_to_column()
|
||||||
|
|
||||||
|
def get_width_in_px(self, font_metric: QFontMetrics):
|
||||||
|
return font_metric.horizontalAdvance(self._line)
|
||||||
|
|
||||||
def byte_offset(self) -> int:
|
def byte_offset(self) -> int:
|
||||||
return self._byte_offset
|
return self._byte_offset
|
||||||
|
|
||||||
@@ -131,11 +137,20 @@ class Line:
|
|||||||
def prefix(self, index: int) -> str:
|
def prefix(self, index: int) -> str:
|
||||||
return self._line[0:index]
|
return self._line[0:index]
|
||||||
|
|
||||||
|
def prefix_bytes(self, byte_index: int) -> str:
|
||||||
|
return self._bytes[0:byte_index]
|
||||||
|
|
||||||
def substr(self, offset: int, length: int) -> str:
|
def substr(self, offset: int, length: int) -> str:
|
||||||
return self._line[offset:offset+length]
|
return self._line[offset:offset+length]
|
||||||
|
|
||||||
|
def substr_bytes(self, byte_offset: int, byte_length: int) -> str:
|
||||||
|
return self._bytes[byte_offset:byte_offset + byte_length]
|
||||||
|
|
||||||
def suffix(self, index: int) -> str:
|
def suffix(self, index: int) -> str:
|
||||||
return self._line[index:]
|
return self._line[index:]
|
||||||
|
|
||||||
|
def suffix_bytes(self, byte_index: int) -> str:
|
||||||
|
return self._bytes[byte_index:]
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "%s (%d->%d)" % (self._line, self._byte_offset, self._byte_end)
|
return "%s (%d->%d)" % (self._line, self._byte_offset, self._byte_end)
|
||||||
@@ -136,7 +136,7 @@ class LogFileModel:
|
|||||||
return re.match(r"\w", char) is not None
|
return re.match(r"\w", char) is not None
|
||||||
|
|
||||||
def prune_cache(self, range_start: int, range_end: int):
|
def prune_cache(self, range_start: int, range_end: int):
|
||||||
print(f"cache size: {len(self._line_cache.keys())}")
|
# print(f"cache size: {len(self._line_cache.keys())}")
|
||||||
for key in list(self._line_cache.keys()):
|
for key in list(self._line_cache.keys()):
|
||||||
line = self._line_cache[key]
|
line = self._line_cache[key]
|
||||||
if range_start > line.byte_end() or line.byte_offset() > range_end:
|
if range_start > line.byte_end() or line.byte_offset() > range_end:
|
||||||
@@ -171,7 +171,7 @@ class LogFileModel:
|
|||||||
new_offset = f.tell()
|
new_offset = f.tell()
|
||||||
if 0 <= range_end < new_offset:
|
if 0 <= range_end < new_offset:
|
||||||
break
|
break
|
||||||
line = Line(offset, new_offset, line_bytes.decode("utf8", errors="ignore"))
|
line = Line(offset, new_offset, line_bytes.decode("utf8", errors="ignore"), line_bytes)
|
||||||
if previous_line_is_complete: # only cache lines when we know they are complete
|
if previous_line_is_complete: # only cache lines when we know they are complete
|
||||||
self._line_cache[offset] = line
|
self._line_cache[offset] = line
|
||||||
offset = new_offset
|
offset = new_offset
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ from src.util import conversion
|
|||||||
from src.util.color import to_qcolor
|
from src.util.color import to_qcolor
|
||||||
from src.i18n import _
|
from src.i18n import _
|
||||||
|
|
||||||
|
|
||||||
class RangeSliderHandle():
|
class RangeSliderHandle():
|
||||||
def __init__(self, value: int):
|
def __init__(self, value: int):
|
||||||
self.value = value
|
self.value = value
|
||||||
@@ -74,26 +75,29 @@ class RangeSlider(QWidget):
|
|||||||
painter = QPainter(self)
|
painter = QPainter(self)
|
||||||
self._draw_background(painter)
|
self._draw_background(painter)
|
||||||
self._draw_hits(painter)
|
self._draw_hits(painter)
|
||||||
self._draw_handle(painter, self.lower_value)
|
self._draw_handle(painter, self.lower_value, direction=-1)
|
||||||
self._draw_handle(painter, self.upper_value, direction=-1)
|
self._draw_handle(painter, self.upper_value)
|
||||||
painter.end()
|
painter.end()
|
||||||
|
|
||||||
def _draw_background(self, painter: QPainter) -> None:
|
def _draw_background(self, painter: QPainter) -> None:
|
||||||
painter.setBrush(to_qcolor("50ade8"))
|
painter.setBrush(to_qcolor("50ade8"))
|
||||||
painter.setPen(to_qcolor("dddddd"))
|
painter.setPen(to_qcolor("dddddd"))
|
||||||
|
|
||||||
|
# the 1px wide grey center line
|
||||||
rect = QRect(round(10), self._handle_width, round(1),
|
rect = QRect(round(10), self._handle_width, round(1),
|
||||||
self.height() - 2 * self._handle_width)
|
self.height() - 2 * self._handle_width)
|
||||||
painter.drawRoundedRect(rect, 3.0, 3.0)
|
painter.drawRoundedRect(rect, 3.0, 3.0)
|
||||||
|
|
||||||
|
# the blue line
|
||||||
rect = QRect(round(7),
|
rect = QRect(round(7),
|
||||||
self._value_to_pixel(self.lower_value.value) + self._handle_width,
|
self._value_to_pixel(self.lower_value.value),
|
||||||
round(6),
|
round(6),
|
||||||
self._value_to_pixel(self.upper_value.value - self.lower_value.value) - 2 * self._handle_width)
|
self._value_to_pixel(self.upper_value.value - self.lower_value.value) - 1 * self._handle_width)
|
||||||
painter.drawRoundedRect(rect, 3.0, 3.0)
|
painter.drawRoundedRect(rect, 3.0, 3.0)
|
||||||
|
|
||||||
def _draw_handle(self, painter: QPainter, handle: RangeSliderHandle, direction=1) -> None:
|
def _draw_handle(self, painter: QPainter, handle: RangeSliderHandle, direction=1) -> None:
|
||||||
y_pixel = self._value_to_pixel(handle.value)
|
y_pixel = self._value_to_pixel(handle.value)
|
||||||
|
h = self._handle_width - 1 # height of the handle
|
||||||
|
|
||||||
painter.setBrush(to_qcolor("dddddd"))
|
painter.setBrush(to_qcolor("dddddd"))
|
||||||
painter.setPen(to_qcolor("444444"))
|
painter.setPen(to_qcolor("444444"))
|
||||||
@@ -101,15 +105,7 @@ class RangeSlider(QWidget):
|
|||||||
painter.drawLine(2, y_pixel, 18, y_pixel)
|
painter.drawLine(2, y_pixel, 18, y_pixel)
|
||||||
painter.setRenderHint(PySide6.QtGui.QPainter.RenderHint.Antialiasing, True)
|
painter.setRenderHint(PySide6.QtGui.QPainter.RenderHint.Antialiasing, True)
|
||||||
painter.drawPolygon(
|
painter.drawPolygon(
|
||||||
(QPoint(10, y_pixel), QPoint(18, y_pixel + 12 * direction), QPoint(2, y_pixel + 12 * direction)))
|
(QPoint(10, y_pixel), QPoint(18, y_pixel + h * direction), QPoint(2, y_pixel + h * direction)))
|
||||||
|
|
||||||
def _draw_handle_circle(self, painter: QPainter, handle: RangeSliderHandle) -> None:
|
|
||||||
y_pixel = self._value_to_pixel(handle.value)
|
|
||||||
|
|
||||||
painter.setBrush(to_qcolor("dddddd"))
|
|
||||||
painter.setPen(to_qcolor("444444"))
|
|
||||||
painter.setRenderHint(PySide6.QtGui.QPainter.RenderHint.Antialiasing, True)
|
|
||||||
painter.drawEllipse(QPoint(self._width / 2, y_pixel), self._handle_width / 2 - 1, self._handle_width / 2 - 1)
|
|
||||||
|
|
||||||
def _value_to_pixel(self, value: int) -> int:
|
def _value_to_pixel(self, value: int) -> int:
|
||||||
value_percent = value / self.max_value
|
value_percent = value / self.max_value
|
||||||
@@ -149,11 +145,11 @@ class RangeSlider(QWidget):
|
|||||||
def mousePressEvent(self, e: QtGui.QMouseEvent) -> None:
|
def mousePressEvent(self, e: QtGui.QMouseEvent) -> None:
|
||||||
if e.buttons() == Qt.MouseButton.LeftButton and e.modifiers() == Qt.KeyboardModifier.NoModifier:
|
if e.buttons() == Qt.MouseButton.LeftButton and e.modifiers() == Qt.KeyboardModifier.NoModifier:
|
||||||
pos: QPoint = e.pos()
|
pos: QPoint = e.pos()
|
||||||
if self._is_on_handle(self.lower_value, pos.y(), direction=1):
|
if self._is_on_handle(self.lower_value, pos.y(), direction=-1):
|
||||||
self.selected_handle = self.lower_value
|
self.selected_handle = self.lower_value
|
||||||
self.selection_drag_range = (self.min_value, self.upper_value.value)
|
self.selection_drag_range = (self.min_value, self.upper_value.value)
|
||||||
self.drag_y_offset_in_handle = self.selected_handle.value - self._pixel_to_value(pos.y())
|
self.drag_y_offset_in_handle = self.selected_handle.value - self._pixel_to_value(pos.y())
|
||||||
if self._is_on_handle(self.upper_value, pos.y(), direction=-1):
|
if self._is_on_handle(self.upper_value, pos.y(), direction=1):
|
||||||
self.selected_handle = self.upper_value
|
self.selected_handle = self.upper_value
|
||||||
self.selection_drag_range = (self.lower_value.value, self.max_value)
|
self.selection_drag_range = (self.lower_value.value, self.max_value)
|
||||||
self.drag_y_offset_in_handle = self.selected_handle.value - self._pixel_to_value(pos.y())
|
self.drag_y_offset_in_handle = self.selected_handle.value - self._pixel_to_value(pos.y())
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
01234
|
012345
|
||||||
01234567890123456789
|
01234567890123456789
|
||||||
012345678901234567890123456789012345678901234567890123456789
|
012345678901234567890123456789012345678901234567890123456789
|
||||||
tab indentation:
|
tab indentation:
|
||||||
@@ -22,6 +22,25 @@ x◌᷍◌◌᷍◌x
|
|||||||
Control characters:
|
Control characters:
|
||||||
|
|
||||||
------------------------------
|
------------------------------
|
||||||
|
wide and half width characters:
|
||||||
|
12345678
|
||||||
|
123456789
|
||||||
|
アンドレアス
|
||||||
|
アンドレアス アンドレアス アンドレアス アンドレアス アンドレアス アンドレアス アンドレアス
|
||||||
|
アンドレアス
|
||||||
|
canadian aboriginal:
|
||||||
|
ᑭᓇᑐᐃᓐᓇᑦᑎᐊᖅᒥᒃ
|
||||||
|
simplified chinese:
|
||||||
|
任何人不得使为奴隶或奴
|
||||||
|
Thai:
|
||||||
|
ทุกคนมีสิทธิที่จะได้
|
||||||
|
Nastaliq Urdu (rl):
|
||||||
|
چونکہ یہ تمام
|
||||||
|
Braille:
|
||||||
|
⠑⠧⠑⠗⠽⠕⠝⠑
|
||||||
|
Arabic (rl):
|
||||||
|
ولما كانت
|
||||||
|
------------------------------
|
||||||
👍🏿 dark thumbs up (U+1F44D + U+1F3FF - THUMBS UP SIGN + EMOJI MODIFIER FITZPATRICK TYPE-6)
|
👍🏿 dark thumbs up (U+1F44D + U+1F3FF - THUMBS UP SIGN + EMOJI MODIFIER FITZPATRICK TYPE-6)
|
||||||
ä---------ä----------ä---------ä----------ä---------ä----------ä---------ä----------ä---------ä----------ä---------ä----------ä---------ä----------ä---------ä----------ä---------ä----------ä---------ä----------ä---------ä----------ä---------ä----------ä---------ä----------ä---------ä----------ä---------ä----------ä---------ä----------ä---------ä----------ä---------ä----------ä---------ä----------ä---------ä----------ä---------ä----------ä---------ä----------ä---------ä----------ä---------ä----------ä---------ä----------<
|
ä---------ä----------ä---------ä----------ä---------ä----------ä---------ä----------ä---------ä----------ä---------ä----------ä---------ä----------ä---------ä----------ä---------ä----------ä---------ä----------ä---------ä----------ä---------ä----------ä---------ä----------ä---------ä----------ä---------ä----------ä---------ä----------ä---------ä----------ä---------ä----------ä---------ä----------ä---------ä----------ä---------ä----------ä---------ä----------ä---------ä----------ä---------ä----------ä---------ä----------<
|
||||||
2019-08-07 00:00:10,391 [catalina-exec-40] INFO c.r.c.u.l.PerformancePointcut - Executed HealthCheckController.checkOperativeness in 1 ms successful. [jv3fw7r2.m1u5]
|
2019-08-07 00:00:10,391 [catalina-exec-40] INFO c.r.c.u.l.PerformancePointcut - Executed HealthCheckController.checkOperativeness in 1 ms successful. [jv3fw7r2.m1u5]
|
||||||
|
|||||||
1
version.txt
Normal file
1
version.txt
Normal file
@@ -0,0 +1 @@
|
|||||||
|
0.2.1-36-g9902be0
|
||||||
Reference in New Issue
Block a user