Skip to content

Commit 114c1a4

Browse files
authored
Merge pull request #69 from cirillom/image-preview
Ability to open file or file location using context menu
2 parents 31f4022 + ade1fb1 commit 114c1a4

File tree

1 file changed

+76
-2
lines changed

1 file changed

+76
-2
lines changed

tagstudio/src/qt/ts_qt.py

Lines changed: 76 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2009,6 +2009,46 @@ def save(self):
20092009
if ext and ext.text():
20102010
self.lib.ignored_extensions.append(ext.text())
20112011

2012+
class FileOpenerHelper():
2013+
def __init__(self, filepath:str):
2014+
self.filepath = filepath
2015+
2016+
def set_filepath(self, filepath:str):
2017+
self.filepath = filepath
2018+
2019+
def open_file(self):
2020+
if os.path.exists(self.filepath):
2021+
os.startfile(self.filepath)
2022+
logging.info(f'Opening file: {self.filepath}')
2023+
else:
2024+
logging.error(f'File not found: {self.filepath}')
2025+
2026+
def open_explorer(self):
2027+
if os.path.exists(self.filepath):
2028+
logging.info(f'Opening file: {self.filepath}')
2029+
if os.name == 'nt': # Windows
2030+
command = f'explorer /select,"{self.filepath}"'
2031+
subprocess.run(command, shell=True)
2032+
else: # macOS and Linux
2033+
command = f'nautilus --select "{self.filepath}"' # Adjust for your Linux file manager if different
2034+
if subprocess.run(command, shell=True).returncode == 0:
2035+
file_loc = os.path.dirname(self.filepath)
2036+
file_loc = os.path.normpath(file_loc)
2037+
os.startfile(file_loc)
2038+
else:
2039+
logging.error(f'File not found: {self.filepath}')
2040+
class FileOpenerLabel(QLabel):
2041+
def __init__(self, text, parent=None):
2042+
super().__init__(text, parent)
2043+
2044+
def setFilePath(self, filepath):
2045+
self.filepath = filepath
2046+
2047+
def mousePressEvent(self, event):
2048+
super().mousePressEvent(event)
2049+
opener = FileOpenerHelper(self.filepath)
2050+
opener.open_explorer()
2051+
20122052
class PreviewPanel(QWidget):
20132053
"""The Preview Panel Widget."""
20142054
tags_updated = Signal()
@@ -2044,6 +2084,14 @@ def __init__(self, library: Library, driver:'QtDriver'):
20442084
self.preview_img = QPushButton()
20452085
self.preview_img.setMinimumSize(*self.img_button_size)
20462086
self.preview_img.setFlat(True)
2087+
2088+
self.preview_img.setContextMenuPolicy(Qt.ContextMenuPolicy.ActionsContextMenu)
2089+
self.opener = FileOpenerHelper('')
2090+
self.open_file_action = QAction('Open file', self)
2091+
self.open_explorer_action = QAction('Open file in explorer', self)
2092+
2093+
self.preview_img.addAction(self.open_file_action)
2094+
self.preview_img.addAction(self.open_explorer_action)
20472095
self.tr = ThumbRenderer()
20482096
self.tr.updated.connect(lambda ts, i, s: (self.preview_img.setIcon(i)))
20492097
self.tr.updated_ratio.connect(lambda ratio: (self.set_image_ratio(ratio),
@@ -2055,7 +2103,7 @@ def __init__(self, library: Library, driver:'QtDriver'):
20552103
image_layout.addWidget(self.preview_img)
20562104
image_layout.setAlignment(self.preview_img, Qt.AlignmentFlag.AlignCenter)
20572105

2058-
self.file_label = QLabel('Filename')
2106+
self.file_label = FileOpenerLabel('Filename')
20592107
self.file_label.setWordWrap(True)
20602108
self.file_label.setTextInteractionFlags(
20612109
Qt.TextInteractionFlag.TextSelectableByMouse)
@@ -2262,7 +2310,9 @@ def update_widgets(self):
22622310
if len(self.driver.selected) == 0:
22632311
if len(self.selected) != 0 or not self.initialized:
22642312
self.file_label.setText(f"No Items Selected")
2313+
self.file_label.setFilePath('')
22652314
self.dimensions_label.setText("")
2315+
self.preview_img.setContextMenuPolicy(Qt.ContextMenuPolicy.NoContextMenu)
22662316
ratio: float = self.devicePixelRatio()
22672317
self.tr.render_big(time.time(), '', (512, 512), ratio, True)
22682318
try:
@@ -2285,11 +2335,17 @@ def update_widgets(self):
22852335
if (len(self.selected) == 0
22862336
or self.selected != self.driver.selected):
22872337
filepath = os.path.normpath(f'{self.lib.library_dir}/{item.path}/{item.filename}')
2338+
self.file_label.setFilePath(filepath)
22882339
window_title = filepath
22892340
ratio: float = self.devicePixelRatio()
22902341
self.tr.render_big(time.time(), filepath, (512, 512), ratio)
22912342
self.file_label.setText("\u200b".join(filepath))
22922343

2344+
self.preview_img.setContextMenuPolicy(Qt.ContextMenuPolicy.ActionsContextMenu)
2345+
self.opener = FileOpenerHelper(filepath)
2346+
self.open_file_action.triggered.connect(self.opener.open_file)
2347+
self.open_explorer_action.triggered.connect(self.opener.open_explorer)
2348+
22932349
# TODO: Do this somewhere else, this is just here temporarily.
22942350
extension = os.path.splitext(filepath)[1][1:].lower()
22952351
try:
@@ -2362,7 +2418,9 @@ def update_widgets(self):
23622418
elif len(self.driver.selected) > 1:
23632419
if self.selected != self.driver.selected:
23642420
self.file_label.setText(f"{len(self.driver.selected)} Items Selected")
2421+
self.file_label.setFilePath('')
23652422
self.dimensions_label.setText("")
2423+
self.preview_img.setContextMenuPolicy(Qt.ContextMenuPolicy.NoContextMenu)
23662424
ratio: float = self.devicePixelRatio()
23672425
self.tr.render_big(time.time(), '', (512, 512), ratio, True)
23682426
try:
@@ -2757,7 +2815,6 @@ class ItemThumb(FlowWidget):
27572815
"""
27582816
The thumbnail widget for a library item (Entry, Collation, Tag Group, etc.).
27592817
"""
2760-
27612818
update_cutoff: float = time.time()
27622819

27632820
collation_icon_128: Image.Image = Image.open(os.path.normpath(
@@ -2886,6 +2943,15 @@ def __init__(self, mode: Optional[ItemType], library: Library, panel: PreviewPan
28862943
# self.bg_button.setMinimumSize(*thumb_size)
28872944
# self.bg_button.setMaximumSize(*thumb_size)
28882945

2946+
self.thumb_button.setContextMenuPolicy(Qt.ContextMenuPolicy.ActionsContextMenu)
2947+
self.opener = FileOpenerHelper('')
2948+
open_file_action = QAction('Open file', self)
2949+
open_file_action.triggered.connect(self.opener.open_file)
2950+
open_explorer_action = QAction('Open file in explorer', self)
2951+
open_explorer_action.triggered.connect(self.opener.open_explorer)
2952+
self.thumb_button.addAction(open_file_action)
2953+
self.thumb_button.addAction(open_explorer_action)
2954+
28892955
# Static Badges ========================================================
28902956

28912957
# Item Type Badge ------------------------------------------------------
@@ -3080,7 +3146,15 @@ def update_badges(self):
30803146

30813147

30823148
def set_item_id(self, id: int):
3149+
'''
3150+
also sets the filepath for the file opener
3151+
'''
30833152
self.item_id = id
3153+
if(id == -1):
3154+
return
3155+
entry = self.lib.get_entry(self.item_id)
3156+
filepath = os.path.normpath(f'{self.lib.library_dir}/{entry.path}/{entry.filename}')
3157+
self.opener.set_filepath(filepath)
30843158

30853159
def assign_favorite(self, value: bool):
30863160
# Switching mode to None to bypass mode-specific operations when the

0 commit comments

Comments
 (0)