Skip to content
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions BlocksScreen/helper_methods.py
Original file line number Diff line number Diff line change
Expand Up @@ -324,3 +324,32 @@ def check_file_on_path(
"""Check if file exists on path. Returns true if file exists on that specified directory"""
_filepath = os.path.join(path, filename)
return os.path.exists(_filepath)


def get_file_loc(filename) -> pathlib.Path: ...


def get_file_name(filename: typing.Optional[str]) -> str:
# If filename is None or empty, return empty string instead of None
if not filename:
return ""
# Remove trailing slashes or backslashes
filename = filename.rstrip("/\\")

# Normalize Windows backslashes to forward slashes
filename = filename.replace("\\", "/")

parts = filename.split("/")

# Split and return the last path component
return parts[-1] if filename else ""


# def get_hash(data) -> hashlib._Hash:
# hash = hashlib.sha256()
# hash.update(data.encode())
# hash.digest()
# return hash


def digest_hash() -> None: ...
218 changes: 106 additions & 112 deletions BlocksScreen/lib/panels/widgets/filesPage.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@
import helper_methods
from lib.utils.blocks_Scrollbar import CustomScrollBar
from lib.utils.icon_button import IconButton
from lib.utils.list_button import ListCustomButton
from PyQt6 import QtCore, QtGui, QtWidgets

from lib.utils.list_model import EntryDelegate, EntryListModel, ListItem

logger = logging.getLogger("logs/BlocksScreen.log")


Expand Down Expand Up @@ -35,7 +36,9 @@ class FilesPage(QtWidgets.QWidget):
directories: list = []

def __init__(self, parent) -> None:
super().__init__(parent)
super().__init__()
self.model = EntryListModel()
self.entry_delegate = EntryDelegate()
self._setupUI()
self.setMouseTracking(True)
self.setAttribute(QtCore.Qt.WidgetAttribute.WA_AcceptTouchEvents, True)
Expand All @@ -50,33 +53,45 @@ def __init__(self, parent) -> None:
)
self.back_btn.clicked.connect(self.reset_dir)

self.entry_delegate.item_selected.connect(self._on_item_selected)

@QtCore.pyqtSlot(ListItem, name="on-item-selected")
def _on_item_selected(self, item: ListItem) -> None:
"""Slot called when a list item is selected in the UI.
This method is connected to the `item_selected` signal of the entry delegate.
It handles the selection of a `ListItem` and is intended to be overridden
or customized for each specific item type, allowing different behavior
depending on the item.
Args:
item : ListItem The item that was selected by the user.
"""
logger.debug("Item Selected")

@QtCore.pyqtSlot(name="reset-dir")
def reset_dir(self) -> None:
"""Reset current directory"""
self.curr_dir = ""
self.request_dir_info[str].emit(self.curr_dir)

def showEvent(self, a0: QtGui.QShowEvent) -> None:
"""Re-implemented method, handle widget show event"""
self._build_file_list()
return super().showEvent(a0)

@QtCore.pyqtSlot(list, name="on-file-list")
def on_file_list(self, file_list: list) -> None:
"""Handle receiving files list from websocket"""
self.files_data.clear()
self.file_list = file_list
# if self.isVisible(): # Only build the list when directories come
# self._build_file_list()

@QtCore.pyqtSlot(list, name="on-dirs")
def on_directories(self, directories_data: list) -> None:
"""Handle receiving available directories from websocket"""
self.directories = directories_data
if self.isVisible():
self._build_file_list()

@QtCore.pyqtSlot(dict, name="on-fileinfo")
def on_fileinfo(self, filedata: dict) -> None:
"""Handle receive file information/metadata"""
"""Method called per file to contruct file entry to the list"""
if not filedata or not self.isVisible():
return
filename = filedata.get("filename", "")
Expand Down Expand Up @@ -104,53 +119,53 @@ def on_fileinfo(self, filedata: dict) -> None:
else:
time_str = f"{minutes}m"

list_items = [self.listWidget.item(i) for i in range(self.listWidget.count())]
if not list_items:
return
for list_item in list_items:
item_widget = self.listWidget.itemWidget(list_item)
if item_widget.text() in filename:
item_widget.setRightText(f"{filament_type} - {time_str}")
name = helper_methods.get_file_name(filename)
item = ListItem(
text=name[:-6],
right_text=f"{filament_type} - {time_str}",
right_icon=QtGui.QPixmap(":/arrow_icons/media/btn_icons/right_arrow.svg"),
left_icon=None,
callback=lambda: self._fileItemClicked(filename),
selected=False,
allow_check=False,
_lfontsize=17,
_rfontsize=12,
height=80,
notificate=False,
)

self.model.add_item(item)

@QtCore.pyqtSlot(QtWidgets.QListWidgetItem, name="file-item-clicked")
def _fileItemClicked(self, item: QtWidgets.QListWidgetItem) -> None:
@QtCore.pyqtSlot(str, name="file-item-clicked")
def _fileItemClicked(self, filename: str) -> None:
"""Slot for List Item clicked

Args:
item (QListWidgetItem): Clicked item
filename (str): Clicked item path
"""
if item:
widget = self.listWidget.itemWidget(item)
for file in self.file_list:
path = (
file.get("path") if "path" in file.keys() else file.get("filename")
)
if not path:
return
if widget.text() in path:
file_path = (
path if not self.curr_dir else str(self.curr_dir + "/" + path)
)
self.file_selected.emit(
str(file_path.removeprefix("/")),
self.files_data.get(
file_path.removeprefix("/")
), # Defaults to Nothing
)

@QtCore.pyqtSlot(QtWidgets.QListWidgetItem, str, name="dir-item-clicked")
def _dirItemClicked(self, item: QtWidgets.QListWidgetItem, directory: str) -> None:
self.file_selected.emit(
str(filename.removeprefix("/")),
self.files_data.get(filename.removeprefix("/")), # Defaults to Nothing
)

def _dirItemClicked(self, directory: str) -> None:
"""Method that changes the current view in the list"""
self.curr_dir = self.curr_dir + directory
self.request_dir_info[str].emit(self.curr_dir)

def _build_file_list(self) -> None:
"""Inserts the currently available gcode files on the QListWidget"""
self.listWidget.blockSignals(True)
self.listWidget.clear()
if not self.file_list and not self.directories:
self.model.clear()
self.entry_delegate.clear()
if (
not self.file_list
and not self.directories
and os.path.islink(self.curr_dir)
):
self._add_placeholder()
return
self.listWidget.setSpacing(35)

if self.directories or self.curr_dir != "":
if self.curr_dir != "" and self.curr_dir != "/":
self._add_back_folder_entry()
Expand All @@ -161,44 +176,49 @@ def _build_file_list(self) -> None:
sorted_list = sorted(self.file_list, key=lambda x: x["modified"], reverse=True)
for item in sorted_list:
self._add_file_list_item(item)
self._add_spacer()

self._setup_scrollbar()
self.listWidget.blockSignals(False)
self.repaint()
self.listWidget.repaint()

def _add_directory_list_item(self, dir_data: dict) -> None:
"""Method that adds directories to the list"""
dir_name = dir_data.get("dirname", "")
if not dir_name:
return
button = ListCustomButton()
button.setText(str(dir_data.get("dirname")))
button.setSecondPixmap(QtGui.QPixmap(":/ui/media/btn_icons/folderIcon.svg"))
button.setMinimumSize(600, 80)
button.setMaximumSize(700, 80)
button.setLeftFontSize(17)
button.setRightFontSize(12)
list_item = QtWidgets.QListWidgetItem()
list_item.setSizeHint(button.sizeHint())
self.listWidget.addItem(list_item)
self.listWidget.setItemWidget(list_item, button)
button.clicked.connect(lambda: self._dirItemClicked(list_item, "/" + dir_name))
item = ListItem(
text=str(dir_name),
left_icon=QtGui.QPixmap(":/ui/media/btn_icons/folderIcon.svg"),
right_text="",
selected=False,
callback=lambda name=dir_name: self._dirItemClicked("/" + str(name)),
allow_check=False,
_lfontsize=17,
_rfontsize=12,
height=80,
)
self.model.add_item(item)

def _add_back_folder_entry(self) -> None:
button = ListCustomButton()
button.setText("Go Back")
button.setSecondPixmap(QtGui.QPixmap(":/ui/media/btn_icons/back_folder.svg"))
button.setMinimumSize(600, 80)
button.setMaximumSize(700, 80)
button.setLeftFontSize(17)
button.setRightFontSize(12)
list_item = QtWidgets.QListWidgetItem()
list_item.setSizeHint(button.sizeHint())
self.listWidget.addItem(list_item)
self.listWidget.setItemWidget(list_item, button)
"""Method to insert in the list the "Go back" item"""
go_back_path = os.path.dirname(self.curr_dir)
if go_back_path == "/":
go_back_path = ""
button.clicked.connect(lambda: (self._on_goback_dir(go_back_path)))

item = ListItem(
text="Go Back",
right_text="",
right_icon=None,
left_icon=QtGui.QPixmap(":/ui/media/btn_icons/back_folder.svg"),
callback=lambda: self._on_goback_dir(go_back_path),
selected=False,
allow_check=False,
_lfontsize=17,
_rfontsize=12,
height=80,
notificate=False,
)
self.model.add_item(item)

@QtCore.pyqtSlot(str, str, name="on-goback-dir")
def _on_goback_dir(self, directory) -> None:
Expand All @@ -217,51 +237,17 @@ def _add_file_list_item(self, file_data_item) -> None:
if not name.endswith(".gcode"):
# Only list .gcode files, all else ignore
return
button = ListCustomButton()
button.setText(name[:-6])
button.setPixmap(QtGui.QPixmap(":/arrow_icons/media/btn_icons/right_arrow.svg"))
button.setMinimumSize(600, 80)
button.setMaximumSize(700, 80)
button.setLeftFontSize(17)
button.setRightFontSize(12)
list_item = QtWidgets.QListWidgetItem()
list_item.setSizeHint(button.sizeHint())
self.listWidget.addItem(list_item)
self.listWidget.setItemWidget(list_item, button)
button.clicked.connect(lambda: self._fileItemClicked(list_item))
file_path = (
name if not self.curr_dir else str(self.curr_dir + "/" + name)
).removeprefix("/")

self.request_file_metadata.emit(file_path.removeprefix("/"))
self.request_file_info.emit(file_path.removeprefix("/"))

def _add_spacer(self) -> None:
spacer_item = QtWidgets.QListWidgetItem()
spacer_widget = QtWidgets.QWidget()
spacer_widget.setFixedHeight(10)
spacer_item.setSizeHint(spacer_widget.sizeHint())
self.listWidget.addItem(spacer_item)

def _add_placeholder(self) -> None:
self.listWidget.setSpacing(-1)
placeholder_label = QtWidgets.QLabel("No Files found")
font = QtGui.QFont()
font.setPointSize(25)
placeholder_label.setFont(font)
placeholder_label.setStyleSheet("color: gray;")
placeholder_label.setAlignment(
QtCore.Qt.AlignmentFlag.AlignHCenter | QtCore.Qt.AlignmentFlag.AlignVCenter
)
placeholder_label.setMinimumSize(
QtCore.QSize(self.listWidget.width(), self.listWidget.height())
)
self.scrollbar.hide()
placeholder_item = QtWidgets.QListWidgetItem()
placeholder_item.setSizeHint(
QtCore.QSize(self.listWidget.width(), self.listWidget.height())
)
self.listWidget.addItem(placeholder_item)
self.listWidget.setItemWidget(placeholder_item, placeholder_label)
self.listWidget.hide()
self.label.show()

def _handle_scrollbar(self, value):
# Block signals to avoid recursion
Expand Down Expand Up @@ -327,15 +313,17 @@ def _setupUI(self):
self.fp_content_layout = QtWidgets.QHBoxLayout()
self.fp_content_layout.setContentsMargins(0, 0, 0, 0)
self.fp_content_layout.setObjectName("fp_content_layout")
self.listWidget = QtWidgets.QListWidget(parent=self)
self.listWidget = QtWidgets.QListView(parent=self)
self.listWidget.setModel(self.model)
self.listWidget.setItemDelegate(self.entry_delegate)
self.listWidget.setSpacing(5)
self.listWidget.setProperty("showDropIndicator", False)
self.listWidget.setProperty("selectionMode", "NoSelection")
self.listWidget.setStyleSheet("background: transparent;")
self.listWidget.setDefaultDropAction(QtCore.Qt.DropAction.IgnoreAction)
self.listWidget.setUniformItemSizes(True)
self.listWidget.setObjectName("listWidget")
self.listWidget.setFocusPolicy(QtCore.Qt.FocusPolicy.NoFocus)
self.listWidget.setDefaultDropAction(QtCore.Qt.DropAction.IgnoreAction)
self.listWidget.setSelectionBehavior(
QtWidgets.QAbstractItemView.SelectionBehavior.SelectItems
)
Expand Down Expand Up @@ -373,17 +361,23 @@ def _setupUI(self):
QtWidgets.QScroller.scroller(self.listWidget).setScrollerProperties(
scroller_props
)

font = QtGui.QFont()
font.setPointSize(25)
placeholder_item = QtWidgets.QListWidgetItem()
placeholder_item.setSizeHint(
self.label = QtWidgets.QLabel("No Files found")
self.label.setFont(font)
self.label.setStyleSheet("color: gray;")
self.label.setMinimumSize(
QtCore.QSize(self.listWidget.width(), self.listWidget.height())
)
self.label.setAlignment(
QtCore.Qt.AlignmentFlag.AlignHCenter | QtCore.Qt.AlignmentFlag.AlignVCenter
)

self.fp_content_layout.addWidget(self.listWidget)
self.fp_content_layout.addWidget(self.label)
self.scrollbar = CustomScrollBar()
self.fp_content_layout.addWidget(self.scrollbar)
self.verticalLayout_5.addLayout(self.fp_content_layout)
self.scrollbar.setAttribute(
QtCore.Qt.WidgetAttribute.WA_TransparentForMouseEvents, True
)
self.scroller = QtWidgets.QScroller.scroller(self.listWidget)
self.scrollbar.show()
self.label.hide()
Loading