Skip to content

add file menu action to clear project cache #65

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all 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
11 changes: 11 additions & 0 deletions src/jabs/project/project.py
Original file line number Diff line number Diff line change
Expand Up @@ -777,6 +777,17 @@ def get_labeled_features(self, behavior=None, progress_callable=None):
'groups': np.concatenate(all_groups),
}, group_mapping

def clear_cache(self):
if self._cache_dir is not None:
for f in self._cache_dir.glob('*'):
try:
if f.is_dir():
shutil.rmtree(f)
else:
f.unlink()
except OSError:
pass

def __update_version(self):
""" update the version number saved in project metadata """
# only update if the version in the metadata is different from current
Expand Down
53 changes: 46 additions & 7 deletions src/jabs/ui/main_window.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,12 +77,12 @@ def __init__(self, app_name: str, app_name_long: str, *args, **kwargs):
app_menu.addAction(exit_action)

# export training data action
self._export_training = QtGui.QAction('Export Training Data', self)
self._export_training.setShortcut(QtGui.QKeySequence(Qt.CTRL | Qt.Key_T))
self._export_training.setStatusTip('Export training data for this classifier')
self._export_training.setEnabled(False)
self._export_training.triggered.connect(self._export_training_data)
file_menu.addAction(self._export_training)
export_training = QtGui.QAction('Export Training Data', self)
export_training.setShortcut(QtGui.QKeySequence(Qt.CTRL | Qt.Key_T))
export_training.setStatusTip('Export training data for this classifier')
export_training.setEnabled(False)
export_training.triggered.connect(export_training_data)
file_menu.addAction(export_training)

# archive behavior action
self._archive_behavior = QtGui.QAction('Archive Behavior', self)
Expand All @@ -91,6 +91,13 @@ def __init__(self, app_name: str, app_name_long: str, *args, **kwargs):
self._archive_behavior.triggered.connect(self._open_archive_behavior_dialog)
file_menu.addAction(self._archive_behavior)

# clear cache action
self._clear_cache = QtGui.QAction('Clear Project Cache', self)
self._clear_cache.setStatusTip('Clear Project Cache')
self._clear_cache.setEnabled(False)
self._clear_cache.triggered.connect(self._clear_cache_action)
file_menu.addAction(self._clear_cache)

# video playlist menu item
self.view_playlist = QtGui.QAction('View Playlist', self)
self.view_playlist.setCheckable(True)
Expand Down Expand Up @@ -176,7 +183,7 @@ def __init__(self, app_name: str, app_name_long: str, *args, **kwargs):

# handle event to set status of File-Export Training Data action
self._central_widget.export_training_status_change.connect(
self._export_training.setEnabled)
export_training.setEnabled)

def keyPressEvent(self, event: QKeyEvent):
"""
Expand Down Expand Up @@ -401,6 +408,7 @@ def _project_loaded_callback(self):

# Update which controls should be available
self._archive_behavior.setEnabled(True)
self._clear_cache.setEnabled(True)
self.enable_cm_units.setEnabled(self._project.is_cm_unit)
self.enable_social_features.setEnabled(self._project.can_use_social_features)
self.enable_segmentation_features.setEnabled(self._project.can_use_segmentation)
Expand All @@ -421,6 +429,37 @@ def _project_load_error_callback(self, error: Exception):
QtWidgets.QMessageBox.critical(
self, "Error loading project", str(error))

def _clear_cache_action(self):
"""
Clear the cache for the current project. Opens a dialog to get user confirmation first.
"""

app = QtWidgets.QApplication.instance()
dont_use_native_dialogs = QtWidgets.QApplication.instance().testAttribute(
Qt.ApplicationAttribute.AA_DontUseNativeDialogs)

# if app is currently set to use native dialogs, we will temporarily set it to use Qt dialogs
# the native style, at least on macOS, is not ideal so we'll force the Qt dialog instead
if dont_use_native_dialogs is False:
app.setAttribute(Qt.ApplicationAttribute.AA_DontUseNativeDialogs, True)

result = QtWidgets.QMessageBox.warning(
self,
"Clear Cache",
"Are you sure you want to clear the project cache?",
QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No,
QtWidgets.QMessageBox.No
)

# restore the original setting
app.setAttribute(Qt.ApplicationAttribute.AA_DontUseNativeDialogs, dont_use_native_dialogs)

if result == QtWidgets.QMessageBox.Yes:
self._project.clear_cache()
# need to reload the current video to force the pose file to reload
self._central_widget.load_video(self._project.video_path(self.video_list.selected_video))
self.display_status_message("Cache cleared", 3000)

def show_license_dialog(self):
dialog = LicenseAgreementDialog(self)
result = dialog.exec_()
Expand Down
7 changes: 7 additions & 0 deletions src/jabs/ui/video_list_widget.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ def __init__(self):
self.setWidget(self.file_list)

self._project = None
self._selected_video = None

# connect to the model selectionChanged signal
self.file_list.currentItemChanged.connect(self._selection_changed)
Expand All @@ -54,6 +55,12 @@ def _selection_changed(self, current, previous):
""" signal main window that use changed selected video """
if current:
self.selectionChanged.emit(current.text())
self._selected_video = current.text()

@property
def selected_video(self):
""" return the currently selected video """
return self._selected_video

def set_project(self, project):
"""
Expand Down