diff --git a/qubesmanager/appmenu_select.py b/qubesmanager/appmenu_select.py index d2b1420..fbff257 100755 --- a/qubesmanager/appmenu_select.py +++ b/qubesmanager/appmenu_select.py @@ -37,19 +37,35 @@ class AppListWidgetItem(QtWidgets.QListWidgetItem): ident, name, comment = line.split('|', maxsplit=3) return cls(name=name, ident=ident, tooltip=comment) + @classmethod + def from_ident(cls, ident): + name = 'Application missing in template! ({})'.format(ident) + comment = 'The listed application was available at some point to ' \ + 'this qube, but not any more. The most likely cause is ' \ + 'template change. Install the application in the template ' \ + 'if you want to restore it.' + return cls(name=name, ident=ident, tooltip=comment) + class AppmenuSelectManager: def __init__(self, vm, apps_multiselect): self.vm = vm self.app_list = apps_multiselect # this is a multiselect wiget self.whitelisted = None - self.fill_apps_list() + self.has_missing = False + self.fill_apps_list(template=None) - def fill_apps_list(self): + def fill_apps_list(self, template=None): self.whitelisted = [line for line in subprocess.check_output( ['qvm-appmenus', '--get-whitelist', self.vm.name] ).decode().strip().split('\n') if line] + currently_selected = [ + self.app_list.selected_list.item(i).ident + for i in range(self.app_list.selected_list.count())] + + whitelist = set(self.whitelisted + currently_selected) + # Check if appmenu entry is really installed # whitelisted = [a for a in whitelisted # if os.path.exists('%s/apps/%s-%s' % @@ -57,18 +73,30 @@ class AppmenuSelectManager: self.app_list.clear() - available_appmenus = [AppListWidgetItem.from_line(line) - for line in subprocess.check_output( - ['qvm-appmenus', '--get-available', - '--i-understand-format-is-unstable', '--file-field', - 'Comment', self.vm.name]).decode().splitlines()] + command = ['qvm-appmenus', '--get-available', + '--i-understand-format-is-unstable', '--file-field', + 'Comment'] + if template: + command.extend(['--template', template.name]) + command.append(self.vm.name) + + available_appmenus = [ + AppListWidgetItem.from_line(line) + for line in subprocess.check_output(command).decode().splitlines()] for app in available_appmenus: - if app.ident in self.whitelisted: + if app.ident in whitelist: self.app_list.selected_list.addItem(app) + whitelist.remove(app.ident) else: self.app_list.available_list.addItem(app) + self.has_missing = bool(whitelist) + + for app in whitelist: + item = AppListWidgetItem.from_ident(app) + self.app_list.selected_list.addItem(item) + self.app_list.available_list.sortItems() self.app_list.selected_list.sortItems() diff --git a/qubesmanager/settings.py b/qubesmanager/settings.py index da708d0..a714c9d 100644 --- a/qubesmanager/settings.py +++ b/qubesmanager/settings.py @@ -220,6 +220,14 @@ class VMSettingsWindow(ui_settingsdlg.Ui_SettingsDialog, QtWidgets.QDialog): self.refresh_apps_button.clicked.connect( self.refresh_apps_button_pressed) + # template change + if self.template_name.isEnabled(): + self.template_name.currentIndexChanged.connect( + self.template_apps_change) + self.warn_template_missing_apps.setVisible( + self.app_list_manager.has_missing) + + def setup_application(self): self.qapp.setApplicationName(self.tr("Qube Settings")) self.qapp.setWindowIcon(QtGui.QIcon.fromTheme("qubes-manager")) @@ -452,6 +460,8 @@ class VMSettingsWindow(ui_settingsdlg.Ui_SettingsDialog, QtWidgets.QDialog): "of the underlying template.")) self.root_resize_label.setEnabled(self.root_resize.isEnabled()) + self.warn_template_missing_apps.setVisible(False) + def __apply_basic_tab__(self): msg = [] @@ -1092,6 +1102,14 @@ class VMSettingsWindow(ui_settingsdlg.Ui_SettingsDialog, QtWidgets.QDialog): self.refresh_apps_button.setEnabled(True) self.refresh_apps_button.setText(self.tr('Refresh Applications')) + def template_apps_change(self): + if self.tabWidget.isTabEnabled(self.tabs_indices["applications"]): + self.app_list_manager.fill_apps_list( + template=self.template_list[self.template_name.currentIndex()]) + # add a label to show + self.warn_template_missing_apps.setVisible( + self.app_list_manager.has_missing) + ######## services tab def __init_services_tab__(self): diff --git a/ui/settingsdlg.ui b/ui/settingsdlg.ui index f020ebd..e7b288b 100644 --- a/ui/settingsdlg.ui +++ b/ui/settingsdlg.ui @@ -6,7 +6,7 @@ 0 0 - 816 + 836 656 @@ -29,7 +29,7 @@ - 5 + 0 @@ -399,6 +399,19 @@ + + + + <html><head/><body><p>Some applications enabled in the Applications tab cannot be found in the current template. The most likely cause is a template change - to restore them, install them in the template.</p></body></html> + + + + + + :/warning.png + + +