Skip to content
66 changes: 64 additions & 2 deletions plottr/apps/monitr.py
Original file line number Diff line number Diff line change
Expand Up @@ -1968,7 +1968,7 @@ def __init__(
self.refresh_button = QtWidgets.QPushButton("Refresh")
self.expand_button = QtWidgets.QPushButton("Expand")
self.collapse_button = QtWidgets.QPushButton("Collapse")
self.copy_button = QtWidgets.QPushButton("Copy Path")
self.copy_button = QtWidgets.QPushButton("Copy ALL Paths")
self.tag_filter_combobox = QtWidgets.QComboBox()
self.tag_filter_combobox.setSizePolicy(
QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum
Expand Down Expand Up @@ -2487,10 +2487,19 @@ class TextEditWidget(TextViewWidget):

It contains a floating button that allows for editing and saving changes done in the editing phase. Text is not
editable before clicking the button.

If the file name ends with ``.mono.md`` (e.g. ``log.mono.md``), the content is rendered in monospace font
(Courier New, 10pt). Use this convention for files that contain tabular or fixed-width text.
"""

def __init__(self, path: Path, *args: Any, **kwargs: Any):
super().__init__(path, *args, **kwargs)

if path.suffixes[-2:] == [".mono", ".md"]:
monospace_font = QtGui.QFont("Courier New")
monospace_font.setPointSize(10)
self.setFont(monospace_font)

self.floating_button = FloatingButtonWidget(parent=self)
self.floating_button.hide()
self.floating_button.save_activated.connect(self.save_activated)
Expand Down Expand Up @@ -2622,7 +2631,7 @@ def create_md_file(self) -> None:
dialog_text, response = QtWidgets.QInputDialog.getText(
self,
"Input comment name",
"Name:",
"(if the file ends in `.mono.md` it will be rendered in monospace font):",
)

if response:
Expand Down Expand Up @@ -3220,6 +3229,16 @@ def __init__(
self.backend_group.addAction(action)
menu.addAction(action)

sort_menu = menu_bar.addMenu("Sort")
self.sort_group = QtWidgets.QActionGroup(sort_menu)
for label, default in [("Sort by type", True), ("Sort alphabetically", False)]:
action = QtWidgets.QAction(label)
action.setCheckable(True)
action.setChecked(default)
self.sort_group.addAction(action)
sort_menu.addAction(action)
self.sort_group.triggered.connect(lambda _: self.generate_right_side_window())

# Set left side layout
self.left_side_layout = QtWidgets.QVBoxLayout()
self.left_side_dummy_widget = QtWidgets.QWidget()
Expand Down Expand Up @@ -3248,6 +3267,7 @@ def __init__(
self.right_side_dummy_widget.setLayout(self.right_side_layout)

self.data_window: Optional[Collapsible] = None
self.copy_path_widget: Optional[QtWidgets.QWidget] = None
self.text_input: Optional[Collapsible] = None
self.file_windows: List[Collapsible] = []
self.scroll_area: Optional[VerticalScrollArea] = None
Expand Down Expand Up @@ -3451,6 +3471,7 @@ def populate_right_side_window(self, files_meta: dict) -> None:
self.add_folder_header()
self.add_tag_label(files_meta["tag_labels"])
self.add_data_window(files_meta["data_files"])
self.add_copy_path_buttons()
self.add_text_input(self.current_selected_folder)
self.add_all_files(files_meta["extra_files"])

Expand Down Expand Up @@ -3505,6 +3526,11 @@ def clear_right_layout(self) -> None:
self.invalid_data_label.deleteLater()
self.invalid_data_label = None

if self.copy_path_widget is not None:
self.right_side_layout.removeWidget(self.copy_path_widget)
self.copy_path_widget.deleteLater()
self.copy_path_widget = None

if self.text_input is not None:
self.right_side_layout.removeWidget(self.text_input)
self.text_input.deleteLater()
Expand Down Expand Up @@ -3622,13 +3648,49 @@ def add_text_input(self, path: Path) -> None:
self.text_input = Collapsible(TextInput(path), title="Add Comment:")
self.right_side_layout.addWidget(self.text_input)

def add_copy_path_buttons(self) -> None:
self.copy_path_widget = QtWidgets.QWidget()
layout = QtWidgets.QHBoxLayout(self.copy_path_widget)
layout.setContentsMargins(0, 0, 0, 0)

path = str(self.current_selected_folder)
copy_current_btn = QtWidgets.QPushButton("Copy folder path")
copy_current_btn.clicked.connect(
lambda _, p=path: QtWidgets.QApplication.clipboard().setText(p)
)

layout.addWidget(copy_current_btn)
layout.addStretch()

self.right_side_layout.addWidget(self.copy_path_widget)

@staticmethod
def _sort_right_window_files(x: Tuple[Path, str, ContentType]) -> Tuple[int, str]:
file_name, file_type = x[1], x[2]
if file_type == ContentType.image:
return (0, file_name)
elif file_type == ContentType.md:
return (1, file_name)
elif file_type == ContentType.json:
return (2, file_name)
elif file_type == ContentType.py:
return (3, file_name)
else:
return (4, file_name)

def add_all_files(self, files_data: List[Tuple[Path, str, ContentType]]) -> None:
"""
Adds all other md, json or images files on the right side of the screen.

:param file_dict: List containing 3 items Tuples. The first item should always be the Path of the file.
The second item should be the name of the file. The third item should be the ContentType of it.
"""
checked = self.sort_group.checkedAction()
if checked is not None and checked.text() == "Sort alphabetically":
files_data.sort(key=lambda x: str.lower(x[1]), reverse=True)
else:
files_data.sort(key=self._sort_right_window_files)

for file, name, file_type in files_data:
if file_type == ContentType.json:
expand = False
Expand Down