diff --git a/src/vorta/assets/UI/sourcetab.ui b/src/vorta/assets/UI/sourcetab.ui index 7d5850910..b8ffd40b5 100644 --- a/src/vorta/assets/UI/sourcetab.ui +++ b/src/vorta/assets/UI/sourcetab.ui @@ -157,6 +157,33 @@ + + + + + + Exclude If Present (exclude folders with these files): + + + + + + + + 0 + 0 + + + + QAbstractScrollArea::AdjustToContentsOnFirstShow + + + E.g. .nobackup + + + + + diff --git a/src/vorta/borg/create.py b/src/vorta/borg/create.py index 8fbe54ef8..17296dd84 100644 --- a/src/vorta/borg/create.py +++ b/src/vorta/borg/create.py @@ -171,6 +171,11 @@ def prepare(cls, profile): cmd.extend(['--exclude-from', pattern_file.name]) ret['cleanup_files'].append(pattern_file) + if profile.exclude_if_present is not None: + for f in profile.exclude_if_present.split('\n'): + if f.strip(): + cmd.extend(['--exclude-if-present', f.strip()]) + # Add repo url and source dirs. new_archive_name = format_archive_name(profile, profile.new_archive_name) diff --git a/src/vorta/store/models.py b/src/vorta/store/models.py index 6aa92c642..76690cc37 100644 --- a/src/vorta/store/models.py +++ b/src/vorta/store/models.py @@ -77,6 +77,7 @@ class BackupProfileModel(BaseModel): compression = pw.CharField(default='lz4') raw_exclusions = pw.TextField(default='') exclude_patterns = pw.TextField(null=True) + exclude_if_present = pw.TextField(null=True) schedule_mode = pw.CharField(default='off') schedule_interval_count = pw.IntegerField(default=3) schedule_interval_unit = pw.CharField(default='hours') diff --git a/src/vorta/views/exclude_dialog.py b/src/vorta/views/exclude_dialog.py index 9284cdd7b..72c9affac 100644 --- a/src/vorta/views/exclude_dialog.py +++ b/src/vorta/views/exclude_dialog.py @@ -64,18 +64,6 @@ def __init__(self, profile, parent=None): self.customExclusionsList.setSelectionMode(QAbstractItemView.SelectionMode.ExtendedSelection) self.customExclusionsList.setFocusPolicy(Qt.FocusPolicy.NoFocus) self.customExclusionsList.setAlternatingRowColors(True) - self.customExclusionsList.setStyleSheet( - ''' - QListView::item { - padding: 10px 0px; - border-bottom: .5px solid black; - } - QListView::item:selected { - background-color: palette(highlight); - } - - ''' - ) self.customExclusionsListDelegate = QStyledItemDelegate() self.customExclusionsList.setItemDelegate(self.customExclusionsListDelegate) self.customExclusionsListDelegate.closeEditor.connect(self.custom_pattern_editing_finished) @@ -91,20 +79,6 @@ def __init__(self, profile, parent=None): self.exclusionPresetsList.setEditTriggers(QAbstractItemView.EditTrigger.NoEditTriggers) self.exclusionPresetsList.setFocusPolicy(Qt.FocusPolicy.NoFocus) self.exclusionPresetsList.setAlternatingRowColors(True) - self.exclusionPresetsList.setStyleSheet( - ''' - QListView::item { - padding: 10px 0px; - border-bottom: .5px solid black; - } - QListView::item:selected { - background-color: palette(highlight); - } - QListView::item::icon { - padding-right: 10px; - } - ''' - ) self.exclusionsPreviewText.setReadOnly(True) diff --git a/src/vorta/views/source_tab.py b/src/vorta/views/source_tab.py index 12a55d283..471342a8a 100644 --- a/src/vorta/views/source_tab.py +++ b/src/vorta/views/source_tab.py @@ -102,6 +102,7 @@ def __init__(self, parent=None): # Connect signals self.removeButton.clicked.connect(self.source_remove) self.updateButton.clicked.connect(self.sources_update) + self.excludeIfPresentField.textChanged.connect(self.save_exclude_if_present) self.bExclude.clicked.connect(self.show_exclude_dialog) header.sortIndicatorChanged.connect(self.update_sort_order) @@ -251,7 +252,9 @@ def add_source_to_table(self, source, update_data=None): def populate_from_profile(self): profile = self.profile() + self.excludeIfPresentField.textChanged.disconnect() self.sourceFilesWidget.setRowCount(0) # Clear rows + self.excludeIfPresentField.clear() for source in SourceFileModel.select().where(SourceFileModel.profile == profile): self.add_source_to_table(source, False) @@ -263,6 +266,9 @@ def populate_from_profile(self): # Sort items as per settings self.sourceFilesWidget.sortItems(sourcetab_sort_column, Qt.SortOrder(sourcetab_sort_order)) + self.excludeIfPresentField.appendPlainText(profile.exclude_if_present) + self.excludeIfPresentField.textChanged.connect(self.save_exclude_if_present) + def update_sort_order(self, column: int, order: int): """Save selected sort by column and order to settings""" SettingsModel.update({SettingsModel.str_value: str(column)}).where( @@ -347,9 +353,9 @@ def show_exclude_dialog(self): self._window = window # for testing window.show() - def save_exclude_patterns(self): + def save_exclude_if_present(self): profile = self.profile() - profile.exclude_patterns = "" + profile.exclude_if_present = self.excludeIfPresentField.toPlainText() profile.save() def paste_text(self):