Compare commits

...

3 Commits

Author SHA1 Message Date
d9c362419b handle tabs correctly when highlighting text
With the old solution I replaced tabs with four spaces and then did
some calculations to get the correct byte positions for a coordinate.
With the new solution (using FontMetric.horizontalAdvance) this is not
necessary anymore and we can use tha native tab.
But I cannot change the tab width. It is always 8 characters.
You can set tabStopDistance on horizontalAdvance(), but not on
elided_text() and I did not find a way to use it while rendering text.
2025-05-06 20:45:19 +02:00
bfd8ce841f add .envrc so that direnv can set the venv dir to the path 2025-05-06 20:17:10 +02:00
a41e5b79a3 add 'about qt' dialog 2025-05-06 20:14:59 +02:00
6 changed files with 95 additions and 17 deletions

1
.envrc Normal file
View File

@@ -0,0 +1 @@
PATH=$(pwd)/venv312/bin:$PATH

View File

@@ -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"

View 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)

View File

@@ -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',

View File

@@ -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

View File

@@ -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"