浏览代码

Applications tab in VM settings now reacts to template change and handles missing entries

On template change, qvm-appmenus is queried for changes in available apps.
If something is whitelisted and does not appear in the template, it is shown
in the list as "Application missing".

requires https://github.com/QubesOS/qubes-desktop-linux-common/pull/22
fixes QubesOS/qubes-issues5796
Marta Marczykowska-Górecka 4 年之前
父节点
当前提交
deb9b323f2
共有 3 个文件被更改,包括 69 次插入10 次删除
  1. 36 8
      qubesmanager/appmenu_select.py
  2. 18 0
      qubesmanager/settings.py
  3. 15 2
      ui/settingsdlg.ui

+ 36 - 8
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()
 

+ 18 - 0
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):

+ 15 - 2
ui/settingsdlg.ui

@@ -6,7 +6,7 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>816</width>
+    <width>836</width>
     <height>656</height>
    </rect>
   </property>
@@ -29,7 +29,7 @@
         <locale language="English" country="UnitedStates"/>
        </property>
        <property name="currentIndex">
-        <number>5</number>
+        <number>0</number>
        </property>
        <widget class="QWidget" name="basic_tab">
         <property name="locale">
@@ -399,6 +399,19 @@
               </property>
              </widget>
             </item>
+            <item row="1" column="3">
+             <widget class="QLabel" name="warn_template_missing_apps">
+              <property name="toolTip">
+               <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;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.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+              </property>
+              <property name="text">
+               <string/>
+              </property>
+              <property name="pixmap">
+               <pixmap resource="../resources.qrc">:/warning.png</pixmap>
+              </property>
+             </widget>
+            </item>
            </layout>
           </widget>
          </item>