Compare commits
6 Commits
d36724f3e7
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| d4b962769f | |||
| d9c362419b | |||
| bfd8ce841f | |||
| a41e5b79a3 | |||
| 75578b6126 | |||
| 9afc4d1d9c |
3
.idea/misc.xml
generated
3
.idea/misc.xml
generated
@@ -1,7 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="Black">
|
||||
<option name="enabledOnSave" value="true" />
|
||||
<option name="sdkName" value="Python 3.12 (krowlog)" />
|
||||
</component>
|
||||
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.12 (krowlog) (2)" project-jdk-type="Python SDK" />
|
||||
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.12 (krowlog)" project-jdk-type="Python SDK" />
|
||||
</project>
|
||||
2
.idea/ravenlog.iml
generated
2
.idea/ravenlog.iml
generated
@@ -10,7 +10,7 @@
|
||||
<excludeFolder url="file://$MODULE_DIR$/icons-not-used" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/venv312" />
|
||||
</content>
|
||||
<orderEntry type="jdk" jdkName="Python 3.12 (krowlog) (2)" jdkType="Python SDK" />
|
||||
<orderEntry type="jdk" jdkName="Python 3.12 (krowlog)" jdkType="Python SDK" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
||||
@@ -1,6 +1,7 @@
|
||||
import os
|
||||
|
||||
krow_icon = "icons" + os.sep + "krowlog.svg"
|
||||
qt_icon = "icons" + os.sep + "qt-logo.png"
|
||||
license_file = os.path.dirname(os.path.realpath(__file__)) + os.sep + "LICENSE"
|
||||
changelog_file = os.path.dirname(os.path.realpath(__file__)) + os.sep + "changelog.txt"
|
||||
|
||||
|
||||
30
krowlog.py
30
krowlog.py
@@ -1,22 +1,26 @@
|
||||
import argparse
|
||||
import gettext
|
||||
import logging
|
||||
import os
|
||||
import signal
|
||||
from PySide6 import QtCore
|
||||
from PySide6.QtWidgets import QApplication
|
||||
from PySide6.QtCore import QTimer
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
from PySide6 import QtCore
|
||||
from PySide6.QtCore import QTimer
|
||||
from PySide6.QtWidgets import QApplication
|
||||
|
||||
import constants
|
||||
from src import install
|
||||
from src.pluginregistry import PluginRegistry
|
||||
import gettext
|
||||
from src.ui.icon import Icon
|
||||
from pathlib import Path
|
||||
import os
|
||||
|
||||
version_file = Path(os.path.dirname(os.path.realpath(__file__)) + os.sep + "version.txt")
|
||||
version_file = Path(
|
||||
os.path.dirname(os.path.realpath(__file__)) + os.sep + "version.txt"
|
||||
)
|
||||
__version__ = version_file.read_text() if version_file.is_file() else "0.0.0"
|
||||
|
||||
gettext.install('krowlog', 'locale')
|
||||
gettext.install("krowlog", "locale")
|
||||
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
log = logging.getLogger("main")
|
||||
@@ -28,7 +32,7 @@ def register_signal_handler():
|
||||
|
||||
|
||||
def stop_signal(signum, _stackframe):
|
||||
""" Handle terminate signal """
|
||||
"""Handle terminate signal"""
|
||||
try:
|
||||
log.info("Terminate signal received. %s", signum)
|
||||
QtCore.QCoreApplication.quit()
|
||||
@@ -68,7 +72,9 @@ class CmdArgs:
|
||||
|
||||
def parse_command_line_parameters() -> CmdArgs:
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('files', metavar='F', type=str, nargs='*', help='file(s) to open')
|
||||
parser.add_argument(
|
||||
"files", metavar="F", type=str, nargs="*", help="file(s) to open"
|
||||
)
|
||||
namespace = parser.parse_args()
|
||||
return CmdArgs(files=namespace.files)
|
||||
|
||||
@@ -77,7 +83,9 @@ if __name__ == "__main__":
|
||||
cmd_args = parse_command_line_parameters()
|
||||
|
||||
app = QApplication(sys.argv)
|
||||
app.setWindowIcon(Icon(constants.krow_icon)) # works only for Linux (but only X11, not Wayland)
|
||||
app.setWindowIcon(
|
||||
Icon(constants.krow_icon)
|
||||
) # works only for Linux (but only X11, not Wayland)
|
||||
|
||||
# install stuff, e.g. a desktop file, set icon on Windows
|
||||
install.install()
|
||||
|
||||
@@ -2,3 +2,5 @@ pip==25.0.1
|
||||
PySide6_Essentials==6.8.2.1
|
||||
setuptools==77.0.3
|
||||
pyinstaller==6.12.0
|
||||
isort==6.0.1
|
||||
black==25.1.0
|
||||
|
||||
79
src/plugins/krowlog/about_qt_dialog.py
Normal file
79
src/plugins/krowlog/about_qt_dialog.py
Normal file
@@ -0,0 +1,79 @@
|
||||
import textwrap
|
||||
|
||||
import PySide6
|
||||
from PySide6.QtCore import Qt
|
||||
from PySide6.QtGui import QFont, QPalette
|
||||
from PySide6.QtWidgets import *
|
||||
|
||||
import constants
|
||||
|
||||
import krowlog
|
||||
from src.ui.icon import Icon
|
||||
from src.ui.label import Label
|
||||
from src.ui.vbox import VBox
|
||||
from src.i18n import _
|
||||
|
||||
|
||||
class AboutQTDialog(QDialog):
|
||||
"""Dialog for showing info about KrowLog"""
|
||||
|
||||
def __init__(self, parent=None):
|
||||
super(AboutQTDialog, self).__init__(parent)
|
||||
self.setWindowTitle(_("About QT"))
|
||||
self.setModal(True)
|
||||
# self.setMinimumWidth(850)
|
||||
# self.setFixedHeight(400)
|
||||
|
||||
self.layout = QVBoxLayout(self)
|
||||
|
||||
text = f"""
|
||||
<b>About QT</b>
|
||||
<p>This program uses QT version {PySide6.QtCore.__version__}.</p>
|
||||
|
||||
<p>QT is a C++ toolkit for cross-platform application development.</p>
|
||||
|
||||
<p>Qt provides single-source portability across all major desktop
|
||||
operating systems. It is also available for embedded Linux and other
|
||||
embedded and mobile operating systems.</p>
|
||||
|
||||
<p>Qt is available under multiple licensing options designed to accommodate
|
||||
the needs of our various users.</p>
|
||||
|
||||
<p>Qt licensed under our commercial license agreement is appropriate for
|
||||
development of proprietary/commercial software where you do not want to
|
||||
share any source code with third parties or otherwise cannot comply with
|
||||
the terms of GNU (L)GPL.</p>
|
||||
|
||||
<p>Qt licensed under GNU (L)GPL is appropriate for the development of Qt
|
||||
applications provided you can comply with the terms and conditions of the
|
||||
respective licenses.</p>
|
||||
|
||||
Please see <a href="http://qt.io/licensing">qt.io/licensing</a> for an<
|
||||
overview of Qt licensing.
|
||||
|
||||
<p>Copyright (C) 2025 The Qt Company Ltd and other contributors.</p>
|
||||
|
||||
<p>Qt and the Qt logo are trademarks of The Qt Company Ltd.</p>
|
||||
|
||||
<p>Qt is The Qt Company Ltd product developed as an open source project.
|
||||
See <a href="http://qt.io">qt.io</a> for more information.</p>
|
||||
"""
|
||||
label = Label(text)
|
||||
label.setWordWrap(True)
|
||||
|
||||
app_icon = QLabel()
|
||||
app_icon.setPixmap(Icon(constants.qt_icon).pixmap(64, 64))
|
||||
heading = QWidget(self)
|
||||
hbox = QHBoxLayout(heading)
|
||||
hbox.addWidget(app_icon)
|
||||
hbox.addWidget(label)
|
||||
hbox.addSpacerItem(QSpacerItem(1, 1, hData=QSizePolicy.Policy.Expanding))
|
||||
|
||||
heading.layout = hbox
|
||||
self.layout.addWidget(heading)
|
||||
|
||||
buttons = QDialogButtonBox(self)
|
||||
buttons.setStandardButtons(QDialogButtonBox.StandardButton.Close)
|
||||
buttons.rejected.connect(self.close)
|
||||
self.layout.addWidget(buttons)
|
||||
self.setSizePolicy(QSizePolicy.Policy.MinimumExpanding, QSizePolicy.Policy.MinimumExpanding)
|
||||
@@ -5,6 +5,7 @@ from PySide6.QtCore import Qt
|
||||
from PySide6.QtWidgets import QDockWidget, QMessageBox
|
||||
|
||||
import constants
|
||||
from src.plugins.krowlog.about_qt_dialog import AboutQTDialog
|
||||
from src.plugins.krowlog.aboutdialog import AboutDialog
|
||||
from src.mainwindow import MainWindow
|
||||
from src.pluginbase import PluginBase
|
||||
@@ -36,6 +37,7 @@ class KrowLogPlugin(PluginBase):
|
||||
return [
|
||||
MenuContribution("file", action=self._action_close(), action_id="close application", after="<last>"),
|
||||
MenuContribution("help", action=self._action_about(), action_id="open about dialog", after="<last>"),
|
||||
MenuContribution("help", action=self._action_about_qt(), action_id="open about QT dialog", after="<last>"),
|
||||
MenuContribution("settings", menu=self._sub_menu_languages(), action_id="recent files menu"),
|
||||
]
|
||||
|
||||
@@ -108,6 +110,14 @@ class KrowLogPlugin(PluginBase):
|
||||
)
|
||||
return about_action
|
||||
|
||||
def _action_about_qt(self) -> RAction:
|
||||
action = RAction(
|
||||
_("&About QT"),
|
||||
action=lambda: AboutQTDialog().exec(),
|
||||
icon_file=constants.qt_icon
|
||||
)
|
||||
return action
|
||||
|
||||
def _action_close(self) -> RAction:
|
||||
icon = "close" if sys.platform == 'win32' or sys.platform == 'cygwin' else "exit"
|
||||
close_action = RAction(_("E&xit"), action=lambda: self.main_window.destruct(), shortcut='Ctrl+X',
|
||||
|
||||
@@ -479,7 +479,7 @@ class InnerBigText(QWidget):
|
||||
# # print("%s + %s = %s" % (line.byte_offset(), char_in_line, current_byte))
|
||||
else:
|
||||
current_byte = self.model.byte_count()
|
||||
return current_byte
|
||||
return SelectionPos(current_byte, True, 1)
|
||||
|
||||
def elided_text(self, text: str, width: int):
|
||||
w = width + self.font_metric.horizontalAdvance("…")
|
||||
@@ -557,7 +557,6 @@ class InnerBigText(QWidget):
|
||||
|
||||
def _toggle_follow(self):
|
||||
self._follow = not self._follow
|
||||
print(f"follow={self._follow}")
|
||||
self.update()
|
||||
|
||||
def _update_highlight_selected_text(self):
|
||||
|
||||
@@ -15,7 +15,7 @@ class Line:
|
||||
self._cache_char_to_column()
|
||||
|
||||
def get_width_in_px(self, font_metric: QFontMetrics):
|
||||
return font_metric.horizontalAdvance(self._line)
|
||||
return font_metric.horizontalAdvance(self.line_prepared_for_display())
|
||||
|
||||
def byte_offset(self) -> int:
|
||||
return self._byte_offset
|
||||
@@ -43,7 +43,8 @@ class Line:
|
||||
return len(prefix_chars)
|
||||
|
||||
def line_prepared_for_display(self) -> str:
|
||||
line = self._line_tabs_replaced()
|
||||
# line = self._line_tabs_replaced()
|
||||
line = self._line
|
||||
line = self._replace_control_chars_with_pictures(line)
|
||||
return line
|
||||
|
||||
@@ -108,7 +109,7 @@ class Line:
|
||||
if not result in self._column_to_char_cache:
|
||||
self._column_to_char_cache[result] = i
|
||||
current_char = self._line[i]
|
||||
if current_char == "\t":
|
||||
if False and current_char == "\t":
|
||||
result = result + constants.tab_width - result % constants.tab_width
|
||||
else:
|
||||
result = result + 1
|
||||
|
||||
@@ -78,20 +78,6 @@ class MyTestCase(unittest.TestCase):
|
||||
self.assertEqual(2, line.char_to_column(4)) # z̈
|
||||
self.assertEqual(2, line.char_to_column(5)) # z̈
|
||||
|
||||
def test_line_tabs_replaced(self):
|
||||
byte_offset = 123
|
||||
text = "\ta\tb" # will be rendered as: ....abc where . represents a whitespace column
|
||||
expected = " a b"
|
||||
line = Line(byte_offset=byte_offset, byte_end=byte_offset + len(text.encode("utf8")), line=text)
|
||||
self.assertEqual(expected, line.line_prepared_for_display())
|
||||
|
||||
def test_line_tabs_replaced_performance(self):
|
||||
byte_offset = 123
|
||||
text = "a\t" * 10000
|
||||
expected = "a " * 10000
|
||||
line = Line(byte_offset=byte_offset, byte_end=byte_offset + len(text.encode("utf8")), line=text)
|
||||
self.assertEqual(expected, line.line_prepared_for_display())
|
||||
|
||||
def test_byte_index_to_char_index(self):
|
||||
byte_offset = 123
|
||||
text = "x\u0308y\u0308z\u0308\t\u0308a"
|
||||
|
||||
@@ -177,3 +177,7 @@ ä---------ä----------ä---------ä----------ä---------ä----------ä--
|
||||
17
|
||||
18
|
||||
19
|
||||
|
||||
|
||||
アンドレアス
|
||||
アンドレアス
|
||||
Reference in New Issue
Block a user