Appmenu_select window with a multiselect widget instead of a table with checkboxes. Plus a sketch of settings dialog.

This commit is contained in:
Agnieszka Kostrzewa 2012-01-24 15:04:28 +01:00
parent 6b8a2279d1
commit d37c79e2c4
3 changed files with 132 additions and 94 deletions

View File

@ -7,13 +7,13 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>602</width> <width>602</width>
<height>300</height> <height>459</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
<string>Form</string> <string>Form</string>
</property> </property>
<layout class="QHBoxLayout" name="horizontalLayout"> <layout class="QHBoxLayout" name="horizontalLayout_3">
<item> <item>
<spacer name="horizontalSpacer"> <spacer name="horizontalSpacer">
<property name="orientation"> <property name="orientation">
@ -27,9 +27,50 @@
</property> </property>
</spacer> </spacer>
</item> </item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Available</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_4">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item> <item>
<widget class="QListWidget" name="available_list"/> <widget class="QListWidget" name="available_list"/>
</item> </item>
</layout>
</item>
<item> <item>
<layout class="QVBoxLayout" name="verticalLayout"> <layout class="QVBoxLayout" name="verticalLayout">
<item> <item>
@ -74,9 +115,50 @@
</item> </item>
</layout> </layout>
</item> </item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<spacer name="horizontalSpacer_5">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>Selected</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_6">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item> <item>
<widget class="QListWidget" name="selected_list"/> <widget class="QListWidget" name="selected_list"/>
</item> </item>
</layout>
</item>
<item> <item>
<spacer name="horizontalSpacer_2"> <spacer name="horizontalSpacer_2">
<property name="orientation"> <property name="orientation">

View File

@ -42,21 +42,14 @@ import time
import threading import threading
from operator import itemgetter from operator import itemgetter
from multiselectwidget import *
whitelisted_filename = 'whitelisted-appmenus.list' whitelisted_filename = 'whitelisted-appmenus.list'
class AppRowInTable(object): class AppListWidgetItem(QListWidgetItem):
def __init__(self, filename, name, row_no, table): def __init__(self, name, filename, parent = None):
super(AppListWidgetItem, self).__init__(name, parent)
self.filename = filename self.filename = filename
self.row_no = row_no
table.setRowHeight (row_no, AppmenuSelectWindow.row_height)
self.name_widget = QTableWidgetItem(name)
self.name_widget.setFlags (Qt.ItemIsSelectable | Qt.ItemIsEnabled )
table.setItem(row_no, 0, self.name_widget)
self.appvm_widget = QCheckBox()
table.setCellWidget(row_no, 1, self.appvm_widget)
class ThreadMonitor(QObject): class ThreadMonitor(QObject):
def __init__(self): def __init__(self):
@ -89,23 +82,10 @@ class AppmenuSelectWindow(QDialog):
self.connect(self.buttonBox, SIGNAL("accepted()"), self.save_and_apply) self.connect(self.buttonBox, SIGNAL("accepted()"), self.save_and_apply)
self.connect(self.buttonBox, SIGNAL("rejected()"), self.reject) self.connect(self.buttonBox, SIGNAL("rejected()"), self.reject)
self.table = QTableWidget(self) self.app_list = MultiSelectWidget(self)
self.table.clear()
self.table.setColumnCount(2)
self.table.setColumnWidth (0, 200)
self.table.setColumnWidth (1, 40)
self.table.horizontalHeader().setResizeMode(QHeaderView.Stretch)
self.table.horizontalHeader().setResizeMode(1, QHeaderView.Fixed)
self.table.setAlternatingRowColors(True)
self.table.verticalHeader().hide()
self.table.horizontalHeader().show()
self.table.setGridStyle(Qt.NoPen)
self.table.setSortingEnabled(True)
self.table.setSelectionBehavior(QTableWidget.SelectRows)
self.table.setSelectionMode(QTableWidget.SingleSelection)
self.gridLayout.addWidget(self.table, 0, 0, 1, 1) self.gridLayout.addWidget(self.app_list, 0, 0, 1, 1)
self.gridLayout.addWidget(self.buttonBox, 1, 0, 1, 1) self.gridLayout.addWidget(self.buttonBox, 1, 0, 1, 1)
self.vm = vm self.vm = vm
@ -114,87 +94,58 @@ class AppmenuSelectWindow(QDialog):
else: else:
self.source_vm = self.vm self.source_vm = self.vm
self.setWindowTitle("Qubes Appmenus for %s" % vm.name) self.setWindowTitle("Qubes Appmenus for %s" % vm.name)
self.resize(250,500) self.resize(600,600)
self.fill_table() self.fill_apps_list()
self.load_list_of_selected()
def reject(self): def reject(self):
self.done(0) self.done(0)
def addActions(self, target, actions): def fill_apps_list(self):
for action in actions:
if action is None:
target.addSeparator()
else:
target.addAction(action)
def createAction(self, text, slot=None, shortcut=None, icon=None,
tip=None, checkable=False, signal="triggered()"):
action = QAction(text, self)
if icon is not None:
action.setIcon(QIcon(":/%s.png" % icon))
if shortcut is not None:
action.setShortcut(shortcut)
if tip is not None:
action.setToolTip(tip)
action.setStatusTip(tip)
if slot is not None:
self.connect(action, SIGNAL(signal), slot)
if checkable:
action.setCheckable(True)
return action
def fill_table(self):
template_dir = self.source_vm.appmenus_templates_dir template_dir = self.source_vm.appmenus_templates_dir
template_file_list = os.listdir(template_dir) template_file_list = os.listdir(template_dir)
self.table.clear() whitelisted = []
self.table.setHorizontalHeaderLabels(['Name', 'VM']) if os.path.exists(self.vm.dir_path + '/' + whitelisted_filename):
self.table.setRowCount(len(template_file_list)) f = open(self.vm.dir_path + '/' + whitelisted_filename, 'r')
whitelisted = [item.strip() for item in f]
f.close()
row_no = 0 self.app_list.clear()
appmenus = []
available_appmenus = []
for template_file in template_file_list: for template_file in template_file_list:
desktop_template = open(template_dir + '/' + template_file, 'r') desktop_template = open(template_dir + '/' + template_file, 'r')
for line in desktop_template: for line in desktop_template:
if line.startswith("Name=%VMNAME%: "): if line.startswith("Name=%VMNAME%: "):
desktop_name = line.partition('Name=%VMNAME%: ')[2].strip() desktop_name = line.partition('Name=%VMNAME%: ')[2].strip()
row = AppRowInTable (template_file, desktop_name, row_no, self.table) available_appmenus.append( (template_file, desktop_name) )
appmenus.append(row)
row_no += 1
break break
desktop_template.close() desktop_template.close()
self.table.setRowCount(row_no) whitelisted_appmenus = [a for a in available_appmenus if a[0] in whitelisted]
self.appmenus = appmenus available_appmenus = [a for a in available_appmenus if a[0] not in whitelisted]
self.table.sortItems(0)
def load_list_of_selected(self): for a in available_appmenus:
if not os.path.exists(self.vm.dir_path + '/' + whitelisted_filename): self.app_list.available_list.addItem( AppListWidgetItem(a[1], a[0]))
# select none
for row in self.appmenus:
row.appvm_widget.setCheckState(Qt.Unchecked)
return
f = open(self.vm.dir_path + '/' + whitelisted_filename, 'r') for a in whitelisted_appmenus:
whitelisted = [item.strip() for item in f] self.app_list.selected_list.addItem( AppListWidgetItem(a[1], a[0]))
f.close()
for row in self.appmenus: self.app_list.available_list.sortItems()
if row.filename in whitelisted: self.app_list.selected_list.sortItems()
row.appvm_widget.setCheckState(Qt.Checked)
else:
row.appvm_widget.setCheckState(Qt.Unchecked)
def save_list_of_selected(self): def save_list_of_selected(self):
whitelisted = open(self.vm.dir_path + '/' + whitelisted_filename, 'w') whitelisted = open(self.vm.dir_path + '/' + whitelisted_filename, 'w')
for row in self.appmenus: for i in range(self.app_list.selected_list.count()):
if row.appvm_widget.checkState() == Qt.Checked: item = self.app_list.selected_list.item(i)
whitelisted.write(row.filename + '\n') whitelisted.write(item.filename + '\n')
whitelisted.close() whitelisted.close()
def save_and_apply(self): def save_and_apply(self):
self.save_list_of_selected() self.save_list_of_selected()
subprocess.check_call([qubes_appmenu_remove_cmd, self.vm.name]) subprocess.check_call([qubes_appmenu_remove_cmd, self.vm.name])

View File

@ -10,6 +10,8 @@ class MultiSelectWidget(Ui_MultiSelectWidget, QWidget):
self.setupUi(self); self.setupUi(self);
self.add_selected_button.clicked.connect(self.add_selected) self.add_selected_button.clicked.connect(self.add_selected)
self.remove_selected_button.clicked.connect(self.remove_selected) self.remove_selected_button.clicked.connect(self.remove_selected)
self.available_list.setSelectionMode(QAbstractItemView.ExtendedSelection)
self.selected_list.setSelectionMode(QAbstractItemView.ExtendedSelection)
def switch_selected(self, src, dst): def switch_selected(self, src, dst):
selected = src.selectedItems() selected = src.selectedItems()
@ -19,15 +21,18 @@ class MultiSelectWidget(Ui_MultiSelectWidget, QWidget):
item = src.takeItem(row) item = src.takeItem(row)
dst.addItem(item) dst.addItem(item)
def add_selected(self): def add_selected(self):
print "Add selected triggered!"
self.switch_selected(self.available_list, self.selected_list) self.switch_selected(self.available_list, self.selected_list)
self.selected_list.sortItems()
def remove_selected(self): def remove_selected(self):
print "Remove selected triggered!"
self.switch_selected(self.selected_list, self.available_list) self.switch_selected(self.selected_list, self.available_list)
self.available_list.sortItems()
def clear(self):
self.available_list.clear()
self.selected_list.clear()