move files into a package structure
This commit is contained in:
@@ -13,7 +13,7 @@ from raven.plugins.domain.raction import RAction
|
||||
from raven.plugins.domain.rmenu import RMenu
|
||||
from settingsstore import SettingsStore
|
||||
from highlightingdialog import HighlightingDialog
|
||||
from tabs import Tabs
|
||||
from raven.ui.tabs import Tabs
|
||||
from urlutils import url_is_file
|
||||
from functools import reduce
|
||||
|
||||
|
||||
83
raven/plugins/ravenlog/aboutdialog.py
Normal file
83
raven/plugins/ravenlog/aboutdialog.py
Normal file
@@ -0,0 +1,83 @@
|
||||
import textwrap
|
||||
|
||||
import PySide6
|
||||
from PySide6.QtCore import Qt
|
||||
from PySide6.QtGui import QFont, QPixmap
|
||||
from PySide6.QtWidgets import *
|
||||
|
||||
import constants
|
||||
from label import Label
|
||||
from raven.ui.vbox import VBox
|
||||
from raven.i18n import _
|
||||
|
||||
class AboutDialog(QDialog):
|
||||
"""Dialog for showing info about RavenLog"""
|
||||
|
||||
def __init__(self, parent=None):
|
||||
super(AboutDialog, self).__init__(parent)
|
||||
self.setWindowTitle(_("About RavenLog"))
|
||||
self.setModal(True)
|
||||
|
||||
self.layout = QVBoxLayout(self)
|
||||
|
||||
heading_app_name = QLabel(_("RavenLog"))
|
||||
heading_app_name.setAlignment(Qt.AlignmentFlag.AlignLeft)
|
||||
heading_app_name.setFont(QFont("default", 25))
|
||||
heading_app_name.setTextInteractionFlags(Qt.TextInteractionFlag.TextSelectableByMouse)
|
||||
|
||||
version = QLabel(_("Version: {0}".format(self._version())))
|
||||
version.setAlignment(Qt.AlignmentFlag.AlignLeft)
|
||||
|
||||
app_icon = QLabel()
|
||||
app_icon.setPixmap(QPixmap(constants.raven_icon))
|
||||
heading = QWidget(self)
|
||||
hbox = QHBoxLayout(heading)
|
||||
hbox.addWidget(app_icon)
|
||||
hbox.addWidget(VBox(heading_app_name, version))
|
||||
hbox.addSpacerItem(QSpacerItem(1, 1, hData=QSizePolicy.Policy.Expanding))
|
||||
|
||||
heading.layout = hbox
|
||||
self.layout.addWidget(heading)
|
||||
|
||||
tabs = QTabWidget()
|
||||
tabs.addTab(self._about(), _("About"))
|
||||
tabs.addTab(self._license(), _("License"))
|
||||
|
||||
self.layout.addWidget(tabs)
|
||||
|
||||
buttons = QDialogButtonBox(self)
|
||||
buttons.setStandardButtons(QDialogButtonBox.StandardButton.Close)
|
||||
buttons.rejected.connect(self.close)
|
||||
self.layout.addWidget(buttons)
|
||||
|
||||
def _about(self) -> QWidget:
|
||||
result = QWidget()
|
||||
result.layout = QVBoxLayout(result)
|
||||
label = Label(_(textwrap.dedent("""
|
||||
Log file viewer<br>
|
||||
(c) 2022 Open Text Corporation<br>
|
||||
<a href="https://www.opentext.com/">License: LGPL v3</a>""")))
|
||||
result.layout.addWidget(label)
|
||||
return result
|
||||
|
||||
def _license(self) -> QWidget:
|
||||
dependencies = """
|
||||
<ul>
|
||||
<li>PySide6 {pyside} (LGPL v3) - <a href="https://doc.qt.io/qtforpython-6/">https://doc.qt.io/qtforpython-6/</a></li>
|
||||
<li>Qt6 {qt} (LGPL v3) - <a href="https://code.qt.io/cgit/qt/qtbase.git/">https://code.qt.io/cgit/qt/qtbase.git/</a></li>
|
||||
<li>urllib3 (MIT) - <a href="https://github.com/urllib3/urllib3">https://github.com/urllib3/urllib3</a></li>
|
||||
<li>watchdog 2.16 (Apache 2.0) - <a href="https://github.com/gorakhargosh/watchdog">https://github.com/gorakhargosh/watchdog</a></li>
|
||||
</ul>""".format(pyside=PySide6.__version__, qt=PySide6.QtCore.__version__)
|
||||
label = _(textwrap.dedent(dependencies))
|
||||
|
||||
result = QWidget()
|
||||
result.layout = QVBoxLayout(result)
|
||||
result.layout.addWidget(Label(label))
|
||||
return result
|
||||
|
||||
def _version(self):
|
||||
with open('VERSION.info', "rt") as f:
|
||||
line = f.readline()
|
||||
version = line.strip()
|
||||
return version
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import sys
|
||||
from typing import Optional, Callable, Dict
|
||||
from typing import Optional
|
||||
|
||||
from PySide6.QtCore import Qt
|
||||
from PySide6.QtWidgets import QDockWidget, QMessageBox
|
||||
|
||||
import constants
|
||||
from aboutdialog import AboutDialog
|
||||
from raven.plugins.ravenlog.aboutdialog import AboutDialog
|
||||
from raven.mainwindow import MainWindow
|
||||
from raven.pluginbase import PluginBase
|
||||
from raven.plugins.domain.menucontribution import MenuContribution
|
||||
|
||||
54
raven/ui/ScaledScrollBar.py
Normal file
54
raven/ui/ScaledScrollBar.py
Normal file
@@ -0,0 +1,54 @@
|
||||
import math
|
||||
|
||||
from PySide6.QtWidgets import QScrollBar
|
||||
from PySide6.QtCore import Signal
|
||||
import logging
|
||||
|
||||
log = logging.getLogger("scaledScrollBar")
|
||||
|
||||
|
||||
class ScaledScrollBar(QScrollBar):
|
||||
is_huge = False
|
||||
|
||||
scaledValueChanged = Signal(str)
|
||||
"""Signal emitted when the scroll bar value changes.
|
||||
**Note**: The value is a string and must be parsed into an int.
|
||||
QT's signal api only supports 32bit integers. Ints larger
|
||||
than 2**32-1 will overflow. Probably because there is some C/C++
|
||||
code involved. We work around this by converting the python int
|
||||
into a string."""
|
||||
|
||||
def __init__(self):
|
||||
super(ScaledScrollBar, self).__init__()
|
||||
self.real_maximum = self.maximum()
|
||||
super().valueChanged.connect(self._valueChanged)
|
||||
|
||||
def setValue(self, value: int) -> None:
|
||||
if self.is_huge:
|
||||
real_position = value / self.real_maximum
|
||||
super().setValue(round(self.maximum() * real_position))
|
||||
else:
|
||||
super().setValue(value)
|
||||
|
||||
def setMaximum(self, maximum: int) -> None:
|
||||
if maximum > 2 ** 31:
|
||||
new_maximum = 1000 * math.log2(maximum)
|
||||
super().setMaximum(math.ceil(new_maximum))
|
||||
self.real_maximum = maximum
|
||||
|
||||
if not self.is_huge:
|
||||
old_position = self.value() / self.maximum()
|
||||
self.setValue(round(new_maximum * old_position))
|
||||
|
||||
self.is_huge = True
|
||||
else:
|
||||
self.is_huge = False
|
||||
super().setMaximum(maximum)
|
||||
|
||||
def _valueChanged(self, value: int):
|
||||
if self.is_huge:
|
||||
real_value = (value / self.maximum()) * self.real_maximum
|
||||
# print("scaled value changed: %d -> %d (%f)" % (value, real_value, value / self.maximum()))
|
||||
self.scaledValueChanged.emit(str(int(real_value)))
|
||||
else:
|
||||
self.scaledValueChanged.emit(str(int(value)))
|
||||
0
raven/ui/__init__.py
Normal file
0
raven/ui/__init__.py
Normal file
101
raven/ui/colorbutton.py
Normal file
101
raven/ui/colorbutton.py
Normal file
@@ -0,0 +1,101 @@
|
||||
import re
|
||||
|
||||
from PySide6.QtGui import QColor, QPixmap, QIcon
|
||||
from PySide6.QtWidgets import QWidget, QHBoxLayout, QPushButton, QColorDialog, QSizePolicy, QComboBox
|
||||
from raven.i18n import _
|
||||
|
||||
class ColorButton(QWidget):
|
||||
def __init__(self, color: str, parent=None):
|
||||
super(ColorButton, self).__init__(parent)
|
||||
|
||||
self.setSizePolicy(QSizePolicy(QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Fixed))
|
||||
self.layout = QHBoxLayout(self)
|
||||
|
||||
self.color = color
|
||||
|
||||
colors = {
|
||||
# red
|
||||
_('Strawberry Cream'): 'ff8080',
|
||||
_('Pale Crimson'): 'e61919',
|
||||
# orange
|
||||
_('Broken Buttercup'): 'ffd080',
|
||||
_('Passion Fruit Sugar'): 'ffa200',
|
||||
# yellow
|
||||
_('Sunrise Yellow'): 'fff080',
|
||||
_('Magical Mustard'): 'ccb400',
|
||||
# green
|
||||
_('Trendy Green'): 'aaff80',
|
||||
_('Garden Of Sweden'): '44cc00',
|
||||
# blue
|
||||
_('Light Sky Blue'): '80c6ff',
|
||||
_('True Blue'): '0073d1',
|
||||
# purple
|
||||
_('Fairy Topia'): 'ff80f4',
|
||||
_('Magenta Bachiego'): 'cc00bb',
|
||||
# grey
|
||||
_('Breeze of Mist'): 'eaeaea',
|
||||
_('Light Grey'): 'cccccc',
|
||||
_('Grey'): '999999',
|
||||
}
|
||||
|
||||
self.color_drop_down = QComboBox()
|
||||
self.layout.addWidget(self.color_drop_down)
|
||||
self.color_drop_down.currentIndexChanged.connect(self._color_selected)
|
||||
self.color_drop_down.addItem(QIcon(self._color_pixmap("ffffffff")), _("transparent"), "None")
|
||||
for color_name in colors.keys():
|
||||
color_value = colors[color_name]
|
||||
self.color_drop_down.addItem(QIcon(self._color_pixmap(color_value)), color_name, color_value)
|
||||
if color == color_name or color == color_value:
|
||||
self.color_drop_down.setCurrentIndex(self.color_drop_down.count() - 1)
|
||||
|
||||
self.btn_color_picker = QPushButton(QIcon.fromTheme("color-picker"), _("custom"))
|
||||
self.layout.addWidget(self.btn_color_picker)
|
||||
self.btn_color_picker.pressed.connect(self._update_color)
|
||||
self.btn_color_picker.setSizePolicy(QSizePolicy(QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Fixed))
|
||||
|
||||
def _color_selected(self, index: int):
|
||||
self.color = self.color_drop_down.currentData()
|
||||
|
||||
def set_color(self, color: str):
|
||||
self.color = color
|
||||
for index in range(0, self.color_drop_down.count()):
|
||||
item_value = self.color_drop_down.itemData(index)
|
||||
if item_value == color:
|
||||
self.color_drop_down.setCurrentIndex(index)
|
||||
return
|
||||
|
||||
# color not yet present -> add it
|
||||
self.color_drop_down.addItem(QIcon(self._color_pixmap(color)), color, color)
|
||||
self.color_drop_down.setCurrentIndex(self.color_drop_down.count() - 1)
|
||||
|
||||
def _update_color(self):
|
||||
new_color = QColorDialog.getColor(self._to_qcolor(self.color))
|
||||
if new_color.isValid():
|
||||
color = self._to_hex(new_color)
|
||||
self.set_color(color)
|
||||
|
||||
@staticmethod
|
||||
def _is_hex_color(color: str):
|
||||
return re.match("[0-9a-f]{6}", color, flags=re.IGNORECASE)
|
||||
|
||||
def _color_pixmap(self, color: str) -> QPixmap:
|
||||
pixmap = QPixmap(40, 40)
|
||||
qcolor = self._to_qcolor(color)
|
||||
pixmap.fill((qcolor))
|
||||
return pixmap
|
||||
|
||||
def _to_qcolor(self, color: str):
|
||||
if self._is_hex_color(color):
|
||||
red = int(color[0:2], 16)
|
||||
green = int(color[2:4], 16)
|
||||
blue = int(color[4:6], 16)
|
||||
return QColor(red, green, blue)
|
||||
elif color in QColor().colorNames():
|
||||
return QColor(color)
|
||||
return QColor(255, 255, 255)
|
||||
|
||||
def _to_hex(self, color: QColor) -> str:
|
||||
red = "{0:0{1}x}".format(color.red(), 2)
|
||||
green = "{0:0{1}x}".format(color.green(), 2)
|
||||
blue = "{0:0{1}x}".format(color.blue(), 2)
|
||||
return red + green + blue
|
||||
9
raven/ui/hbox.py
Normal file
9
raven/ui/hbox.py
Normal file
@@ -0,0 +1,9 @@
|
||||
from PySide6.QtWidgets import QWidget, QHBoxLayout
|
||||
|
||||
|
||||
class HBox(QWidget):
|
||||
def __init__(self, *widgets: QWidget):
|
||||
super(HBox, self).__init__()
|
||||
self.layout = QHBoxLayout(self)
|
||||
for widget in widgets:
|
||||
self.layout.addWidget(widget)
|
||||
64
raven/ui/tabs.py
Normal file
64
raven/ui/tabs.py
Normal file
@@ -0,0 +1,64 @@
|
||||
from typing import Optional
|
||||
|
||||
from PySide6.QtWidgets import QWidget, QTabWidget, QVBoxLayout
|
||||
|
||||
from raven.pluginregistry import PluginRegistry
|
||||
from raven.plugins.ravenlog.Tab import Tab
|
||||
from settings import Settings
|
||||
|
||||
|
||||
class Tabs(QWidget):
|
||||
def __init__(self, settings: Settings):
|
||||
super(Tabs, self).__init__()
|
||||
|
||||
self.settings = settings
|
||||
|
||||
self.tabs = QTabWidget()
|
||||
self.tabs.setTabsClosable(True)
|
||||
self.tabs.setMovable(True)
|
||||
self.tabs.tabCloseRequested.connect(self._close_tab)
|
||||
self.tabs.currentChanged.connect(self._current_tab_changed)
|
||||
|
||||
self.layout = QVBoxLayout(self)
|
||||
self.layout.setContentsMargins(0, 0, 0, 0)
|
||||
|
||||
self.layout.addWidget(self.tabs)
|
||||
|
||||
def add_tab(self, tab: Tab):
|
||||
# if tab already exists then open it
|
||||
for tab_index in range(0, self.tabs.count()):
|
||||
widget: Tab = self.tabs.widget(tab_index)
|
||||
if widget.unique_id == tab.unique_id:
|
||||
self.tabs.setCurrentIndex(tab_index)
|
||||
return
|
||||
|
||||
tab_index = self.tabs.addTab(tab, tab.title)
|
||||
self.tabs.setCurrentIndex(tab_index)
|
||||
|
||||
def _current_tab_changed(self, tab_index: int):
|
||||
tab: Tab = self.tabs.widget(tab_index)
|
||||
if tab:
|
||||
PluginRegistry.execute("update_window_title", tab.title)
|
||||
PluginRegistry.execute("update_status_bar", tab.get_status_text())
|
||||
else:
|
||||
PluginRegistry.execute("update_window_title", "")
|
||||
PluginRegistry.execute("update_status_bar", "")
|
||||
|
||||
def _close_tab(self, tab_index: int):
|
||||
full_tab: Tab = self.tabs.widget(tab_index)
|
||||
full_tab.destruct()
|
||||
self.tabs.removeTab(tab_index)
|
||||
|
||||
def destruct(self):
|
||||
while self.tabs.count() > 0:
|
||||
self._close_tab(0)
|
||||
|
||||
def _current_tab(self) -> int:
|
||||
return self.tabs.currentIndex()
|
||||
|
||||
def current_file(self) -> Optional[str]:
|
||||
if self.tabs.currentIndex() < 0:
|
||||
return None
|
||||
|
||||
tab: Tab = self.tabs.widget(self.tabs.currentIndex())
|
||||
return tab.get_file()
|
||||
9
raven/ui/vbox.py
Normal file
9
raven/ui/vbox.py
Normal file
@@ -0,0 +1,9 @@
|
||||
from PySide6.QtWidgets import QWidget, QVBoxLayout
|
||||
|
||||
|
||||
class VBox(QWidget):
|
||||
def __init__(self, *widgets: QWidget):
|
||||
super(VBox, self).__init__()
|
||||
self.layout = QVBoxLayout(self)
|
||||
for widget in widgets:
|
||||
self.layout.addWidget(widget)
|
||||
Reference in New Issue
Block a user