# -*- coding: utf-8 -*-
# Licensed under the EUPL v1.2
# © 2019-2021 bicobus <bicobus@keemail.me>
"""Contains various Qt Widgets used internally by the application."""
import logging
from typing import Iterable, List, Union
from PyQt5 import QtGui, QtWidgets
from PyQt5.QtCore import QObject, QProcess, QUrl
from PyQt5.QtWidgets import QAction, QMenu, QTreeWidget, QTreeWidgetItem
from qmm.ab.widgets import ABCListRowItem
from qmm.fileutils import FileState
from qmm.bucket import FileMetadata
from qmm.common import command, toolsalias
from qmm.filehandler import ArchiveInstance
from qmm.ui_about import Ui_About # pylint: disable=no-name-in-module
logger = logging.getLogger(__name__)
# NOTE: Investigate QDesktopServices if os.startfile is failing on windows
# def qopenpath(tool):
# toolpath = command(tool, alias=True)
# QtGui.QDesktopServices(QUrl(tool))
[docs]
class QAbout(QtWidgets.QWidget, Ui_About):
"""About window displaying various informations about the software."""
def __init__(self, parent=None):
super().__init__(parent=parent)
self.setupUi(self)
font = QtGui.QFont()
font.setFamily("Unifont")
font.setPointSize(11)
self.text_author.setFont(font)
[docs]
def autoresize_columns(tree_widget: QTreeWidget):
"""Resize all columns of a QTreeWidget to fit content."""
tree_widget.expandAll()
for i in range(0, tree_widget.columnCount() - 1):
tree_widget.resizeColumnToContents(i)
def _create_treewidget(
text: Union[str, List], parent, tooltip: str = None, color=None, icon=None
):
w = QTreeWidgetItem(parent)
if isinstance(text, str):
text = [text]
for idx, string in enumerate(text):
w.setText(idx, string)
if color:
w.setBackground(idx, QtGui.QColor(*color))
if tooltip:
w.setToolTip(0, tooltip)
if icon:
w.setIcon(0, QtGui.QIcon(QtGui.QPixmap(icon)))
return w
def _path_from_list(path, length):
return "/".join(path[i] for i in range(0, length))
[docs]
def build_tree_from_path(item: FileMetadata, parent: QTreeWidget, folders, color=None, **kwargs):
"""Generate a set of related :func:`PyQt5.QtWidgets.QTreeWidgetItem` based
on a file path.
If *extra_column* is specified, it must be a list containing text that will
be used to create new columns after the first one. Useful to add extra
information.
Args:
item: a :obj:`qmm.bucket.FileMetadata` object.
parent: The container widget to anchor the first node to.
folders: A dict containing the parents widgets.
color (Optional[List]): Background color value for the widget.
Keyword Args:
extra_column (List[str]): Extra values to pass down to
:func:`_create_treewidget`
Returns:
dict: A dictionnary containing the folders ancestry.
"""
def _gv(val, extra=None):
x = [val]
if extra:
x.extend(extra)
return x
finder = kwargs.get("finder")
folder, file = item.split()
folder_list = folder.split("/") if folder else ["/"]
key = None
for idx, folder in enumerate(folder_list):
key = _path_from_list(folder_list, idx + 1)
if key not in folders.keys():
if idx > 0:
p = folders[_path_from_list(folder_list, idx)]
else:
p = parent
if finder:
fmd = finder(key)[0]
status = FileState.MATCHED if fmd.exists() else FileState.MISSING
widget = ArchiveFilesTreeRow(
text=_gv(folder, [str(status)]),
parent=p,
item=fmd,
tooltip=fmd.path,
color=color,
icon=":/icons/folder.svg",
filetype="directory",
)
else:
widget = _create_treewidget(_gv(folder), parent=p, icon=":/icons/folder.svg")
folders.setdefault(key, widget)
if file:
pos = file.rfind(".") + 1
icon = None
if file[pos:] == "xml":
icon = ":/icons/file-text.svg"
elif file[pos:] == "svg":
icon = ":/icons/file-code.svg"
ArchiveFilesTreeRow(
text=_gv(file, kwargs.get("extra_column")),
parent=folders[key],
item=item,
tooltip=item.path,
color=color,
icon=icon,
filetype="file",
)
return folders
[docs]
class ArchiveFilesTreeRow(QtWidgets.QTreeWidgetItem):
def __init__(
self,
text: Union[str, List],
parent,
item: FileMetadata,
tooltip: str = None,
color: Union[QtGui.QColor, None] = None,
icon=None,
**extra,
):
super().__init__(parent)
self.filemetadata = item
extra.setdefault("filetype", "directory")
self._extra = extra
if isinstance(text, str):
text = [text]
for idx, string in enumerate(text):
self.setText(idx, string)
if color:
self.setBackground(idx, color)
if tooltip:
self.setToolTip(0, tooltip)
if icon:
self.setIcon(0, QtGui.QIcon(QtGui.QPixmap(icon)))
[docs]
class ListRowItem(ABCListRowItem):
"""ListWidgetItem representing one single archive."""
pass
[docs]
class ListRowVirtualItem(ABCListRowItem):
def __init__(self, archive_manager):
super().__init__(None, archive_manager)
def _post_init(self):
self._filename = self._key = "Virtual_Package"
self.archive_instance = self.am.special
self._stat = None
self._name = None
self._modified = "N/A"
self._hashsum = "N/A"
self.setText(self.name)
[docs]
def set_gradients(self):
logger.error("Gradients shouldn't be set for the virtual package.")
[docs]
def refresh_strings(self):
logger.error("Refresh Strings called on a virtual package, this must not be done.")