class AddOrManageObjectGroupDialog(QDialog): def __init__(self, parent, object_class_item, db_mngr, *db_maps): """ Args: parent (SpineDBEditor): data store widget object_class_item (ObjectClassItem) db_mngr (SpineDBManager) *db_maps: database mappings """ super().__init__(parent) self.object_class_item = object_class_item self.db_mngr = db_mngr self.db_maps = db_maps self.db_map = db_maps[0] self.db_maps_by_codename = { db_map.codename: db_map for db_map in db_maps } self.db_combo_box = QComboBox(self) self.header_widget = QWidget(self) self.group_name_line_edit = QLineEdit(self) header_layout = QHBoxLayout(self.header_widget) header_layout.addWidget(QLabel(f"Group name: ")) header_layout.addWidget(self.group_name_line_edit) header_layout.addSpacing(32) header_layout.addWidget(QLabel("Database")) header_layout.addWidget(self.db_combo_box) self.non_members_tree = QTreeWidget(self) self.non_members_tree.setHeaderLabel("Non members") self.non_members_tree.setSelectionMode(QTreeWidget.ExtendedSelection) self.non_members_tree.setColumnCount(1) self.non_members_tree.setIndentation(0) self.members_tree = QTreeWidget(self) self.members_tree.setHeaderLabel("Members") self.members_tree.setSelectionMode(QTreeWidget.ExtendedSelection) self.members_tree.setColumnCount(1) self.members_tree.setIndentation(0) self.add_button = QToolButton() self.add_button.setToolTip("<p>Add selected non-members.</p>") self.add_button.setIcon(QIcon(":/icons/menu_icons/cube_plus.svg")) self.add_button.setIconSize(QSize(24, 24)) self.add_button.setToolButtonStyle(Qt.ToolButtonTextBesideIcon) self.add_button.setText(">>") self.remove_button = QToolButton() self.remove_button.setToolTip("<p>Remove selected members.</p>") self.remove_button.setIcon(QIcon(":/icons/menu_icons/cube_minus.svg")) self.remove_button.setIconSize(QSize(24, 24)) self.remove_button.setToolButtonStyle(Qt.ToolButtonTextBesideIcon) self.remove_button.setText("<<") self.vertical_button_widget = QWidget() vertical_button_layout = QVBoxLayout(self.vertical_button_widget) vertical_button_layout.addStretch() vertical_button_layout.addWidget(self.add_button) vertical_button_layout.addWidget(self.remove_button) vertical_button_layout.addStretch() self.button_box = QDialogButtonBox(self) self.button_box.setStandardButtons(QDialogButtonBox.Cancel | QDialogButtonBox.Ok) layout = QGridLayout(self) layout.addWidget(self.header_widget, 0, 0, 1, 3, Qt.AlignHCenter) layout.addWidget(self.non_members_tree, 1, 0) layout.addWidget(self.vertical_button_widget, 1, 1) layout.addWidget(self.members_tree, 1, 2) layout.addWidget(self.button_box, 2, 0, 1, 3) self.setAttribute(Qt.WA_DeleteOnClose) self.db_combo_box.addItems(list(self.db_maps_by_codename)) self.db_map_object_ids = { db_map: { x["name"]: x["id"] for x in self.db_mngr.get_items_by_field( self.db_map, "object", "class_id", self.object_class_item.db_map_id(db_map)) } for db_map in db_maps } self.reset_list_widgets(db_maps[0].codename) self.connect_signals() def connect_signals(self): """Connect signals to slots.""" self.button_box.accepted.connect(self.accept) self.button_box.rejected.connect(self.reject) self.db_combo_box.currentTextChanged.connect(self.reset_list_widgets) self.add_button.clicked.connect(self.add_members) self.remove_button.clicked.connect(self.remove_members) def reset_list_widgets(self, database): self.db_map = self.db_maps_by_codename[database] object_ids = self.db_map_object_ids[self.db_map] members = [] non_members = [] for obj_name, obj_id in object_ids.items(): if obj_id in self.initial_member_ids(): members.append(obj_name) elif obj_id != self.initial_entity_id(): non_members.append(obj_name) member_items = [QTreeWidgetItem([obj_name]) for obj_name in members] non_member_items = [ QTreeWidgetItem([obj_name]) for obj_name in non_members ] self.members_tree.addTopLevelItems(member_items) self.non_members_tree.addTopLevelItems(non_member_items) def initial_member_ids(self): raise NotImplementedError() def initial_entity_id(self): raise NotImplementedError() @Slot(bool) def add_members(self, checked=False): indexes = sorted([ self.non_members_tree.indexOfTopLevelItem(x) for x in self.non_members_tree.selectedItems() ], reverse=True) items = [ self.non_members_tree.takeTopLevelItem(ind) for ind in indexes ] self.members_tree.addTopLevelItems(items) @Slot(bool) def remove_members(self, checked=False): indexes = sorted([ self.members_tree.indexOfTopLevelItem(x) for x in self.members_tree.selectedItems() ], reverse=True) items = [self.members_tree.takeTopLevelItem(ind) for ind in indexes] self.non_members_tree.addTopLevelItems(items) def _check_validity(self): if not self.members_tree.topLevelItemCount(): self.parent().msg_error.emit( "Please select at least one member object.") return False return True
class ShareSelectionPage(QWizardPage): def __init__(self, parent=None, title="Auswahl LB", subtitle="Wählen Sie das Prüfungsmodul aus", button_name="Fertig"): super(ShareSelectionPage, self).__init__(parent) self.setTitle(title) self.setSubTitle(subtitle) self.validSelection = False self.setButtonText(QWizard.FinishButton, button_name) self.setButtonText(QWizard.CancelButton, "Abbrechen") self.setButtonText(QWizard.BackButton, "Zurück") def validatePage(self, *args, **kwargs): ''' test if only one tree view item is selected and if this item matches the naming conventions ''' if len(self.tree.selectedItems()) == 1: item = self.tree.selectedItems()[0] self.wizard().selectedPath = "//" + self.wizard( ).server.serverName + "/" + item.path if self.wizard().type == EcShareWizard.TYPE_LB_SELECTION: if re.compile("^M[1-9][0-9]{2}").match(item.name) == None: self.setSubTitle( "Bitte Prüfungsverzeichnis alá M101 oder M226A auswählen" ) return False else: if re.compile("^(UIFZ|IFZ|ICT)-").match(item.name) == None: self.setSubTitle( "Bitte Klassenverzeichnis alá UIFZ-926-001 oder IFZ-926-001 auswählen" ) return False self.setSubTitle("") return True self.wizard().selectedPath = None return False def initializePage(self): if self.layout() != None: # print("clean up previous entries") while self.layout().count() > 0: self.layout().removeItem(self.layout().itemAt(0)) self.tree = QTreeWidget() if self.wizard().defaultShare != None: self.tree.addTopLevelItem( MyTreeWidgetItem(self.tree, self.wizard().defaultShare)) else: shares = self.wizard().getShares() if shares == None: print("No shares found...") return print(",".join([x.name for x in shares])) for m in shares: if m.name not in [ "ADMIN$", "C$", "IPC$", "NETLOGON", "SYSVOL" ]: self.tree.addTopLevelItem(MyTreeWidgetItem(self.tree, m)) shareListBox = QWidget() shareListBoxLayout = QVBoxLayout() self.tree.setHeaderLabel("Freigaben") self.tree.itemClicked.connect(self.treeViewItemClicked) shareListBoxLayout.addWidget(self.tree) shareListBox.setLayout(shareListBoxLayout) self.folderList = QListWidget() folderListBox = QWidget() folderListBoxLayout = QVBoxLayout() folderListHeaderMessage = "Verzeichnisinhalt" folderListBoxLayout.addWidget(QLabel(folderListHeaderMessage)) folderListBoxLayout.addWidget(self.folderList) folderListBox.setLayout(folderListBoxLayout) layout = QHBoxLayout() layout.addWidget(shareListBox) layout.addWidget(folderListBox) self.setLayout(layout) def treeViewItemClicked(self, item): print("received treeview click on: " + str(item)) self.folderList.clear() self.validSelection = False hasChildren = item.childCount() > 0 # don't add children again try: content = self.wizard().getFolderContent(item.path) content = sorted(content, key=lambda entry: (not (entry.isDirectory), entry.filename)) for x in content: if not (x.filename.startswith(".")): newItemPath = item.path + "/" + x.filename icon = QStyle.SP_DirIcon if x.isDirectory else QStyle.SP_FileIcon self.folderList.addItem( MyListWidgetItem(self.style().standardIcon(icon), newItemPath, x.isDirectory, self.folderList)) if not (hasChildren) and x.isDirectory: item.addChild(MyTreeWidgetItem(self.tree, newItemPath)) except Exception as ex: # smb.smb_structs.OperationFailure ?? print(str(ex)) pass