📄 folderselector.py
字号:
## The dialog itself#########################################################################import dlgcoreFolderSelector_Parent = dlgcore.TooltipDialogclass FolderSelector(FolderSelector_Parent): def __init__ (self, parent, manager, selected_ids=None, single_select=False, checkbox_state=False, checkbox_text=None, desc_noun="Select", desc_noun_suffix="ed", exclude_prop_ids=(PR_IPM_WASTEBASKET_ENTRYID, PR_IPM_SENTMAIL_ENTRYID, PR_IPM_OUTBOX_ENTRYID) ): FolderSelector_Parent.__init__(self, parent, manager.dialog_parser, "IDD_FOLDER_SELECTOR") assert not single_select or selected_ids is None or len(selected_ids)<=1 self.single_select = single_select self.next_item_id = 1 self.item_map = {} self.timer_id = None self.imageList = None self.select_desc_noun = desc_noun self.select_desc_noun_suffix = desc_noun_suffix self.selected_ids = [sid for sid in selected_ids if sid is not None] self.manager = manager self.checkbox_state = checkbox_state self.checkbox_text = checkbox_text or "Include &subfolders" self.exclude_prop_ids = exclude_prop_ids self.in_label_edit = False self.in_check_selections_valid = False def CompareIDs(self, id1, id2): # Compare the eid of the stores, then the objects CompareEntryIDs = self.manager.message_store.session.CompareEntryIDs try: return CompareEntryIDs(mapi.BinFromHex(id1[0]), mapi.BinFromHex(id2[0])) and \ CompareEntryIDs(mapi.BinFromHex(id1[1]), mapi.BinFromHex(id2[1])) except pythoncom.com_error: # invalid IDs are never the same return False def InIDs(self, id, ids): for id_check in ids: if self.CompareIDs(id_check, id): return True return False def _MakeItemParam(self, item): item_id = self.next_item_id self.next_item_id += 1 self.item_map[item_id] = item return item_id def _InsertFolder(self, hParent, child, selected_ids = None, insert_after=0): text = child.name if child.children is None: # Need to build them! cItems = 1 # Anything > 0 will do else: cItems = len(child.children) if cItems==0: bitmapCol = bitmapSel = 5 # blank doc else: bitmapCol = bitmapSel = 0 # folder if self.single_select: mask = state = 0 else: if (selected_ids and self.InIDs(child.folder_id, selected_ids)): state = INDEXTOSTATEIMAGEMASK(IIL_CHECKED) else: state = INDEXTOSTATEIMAGEMASK(IIL_UNCHECKED) mask = commctrl.TVIS_STATEIMAGEMASK item_id = self._MakeItemParam(child) insert_buf, extras = PackTVINSERTSTRUCT(hParent, insert_after, (None, state, mask, text, bitmapCol, bitmapSel, cItems, item_id)) if verbose: print "Inserting item", repr(insert_buf), "-", hitem = win32gui.SendMessage(self.list, commctrl.TVM_INSERTITEM, 0, insert_buf) if verbose: print "got back handle", hitem return hitem def _InsertSubFolders(self, hParent, folderSpec): for child in folderSpec.children: hitem = self._InsertFolder(hParent, child, self.selected_ids) # If this folder is in the list of ones we need to expand # to show pre-selected items, then force expand now. if self.InIDs(child.folder_id, self.expand_ids): win32gui.SendMessage(self.list, commctrl.TVM_EXPAND, commctrl.TVE_EXPAND, hitem) # If single-select, and this is ours, select it # (multi-select uses check-boxes, not selection) if (self.single_select and self.selected_ids and self.InIDs(child.folder_id, self.selected_ids)): win32gui.SendMessage(self.list, commctrl.TVM_SELECTITEM, commctrl.TVGN_CARET, hitem) def _DetermineFoldersToExpand(self): folders_to_expand = [] for folder_id in self.selected_ids: try: folder = self.manager.message_store.GetFolder(folder_id) except self.manager.message_store.MsgStoreException, details: print "Can't find a folder to expand:", details folder = None while folder is not None: try: parent = folder.GetParent() except self.manager.message_store.MsgStoreException, details: print "Can't find folder's parent:", details parent = None if parent is not None and \ not self.InIDs(parent.GetID(), folders_to_expand): folders_to_expand.append(parent.GetID()) folder = parent return folders_to_expand def _GetTVItem(self, h): buffer, extra = EmptyTVITEM(h) win32gui.SendMessage(self.list, commctrl.TVM_GETITEM, 0, buffer.buffer_info()[0]) return UnpackTVItem(buffer.tostring()) def _YieldChildren(self, h): try: h = win32gui.SendMessage(self.list, commctrl.TVM_GETNEXTITEM, commctrl.TVGN_CHILD, h) except win32gui.error: h = 0 while h: info = self._GetTVItem(h) item_param = info[-1] spec = self.item_map[item_param] yield info, spec # Check children for info, spec in self._YieldChildren(h): yield info, spec try: h = win32gui.SendMessage(self.list, commctrl.TVM_GETNEXTITEM, commctrl.TVGN_NEXT, h) except win32gui.error: h = None def _YieldAllChildren(self): return self._YieldChildren(commctrl.TVI_ROOT) def _YieldCheckedChildren(self): if self.single_select: # If single-select, the checked state is not used, just the # selected state. try: h = win32gui.SendMessage(self.list, commctrl.TVM_GETNEXTITEM, commctrl.TVGN_CARET, 0) except win32gui.error: h = 0 if not h: # nothing selected. return info = self._GetTVItem(h) spec = self.item_map[info[7]] yield info, spec return # single-hit yield. for info, spec in self._YieldAllChildren(): checked = (info[1] >> 12) - 1 if checked: yield info, spec def GetSelectedIDs(self): try: self.GetDlgItem("IDC_LIST_FOLDERS") except win32gui.error: # dialog dead! return self.selected_ids, self.checkbox_state ret = [] for info, spec in self._YieldCheckedChildren(): ret.append(spec.folder_id) check = win32gui.SendMessage(self.GetDlgItem("IDC_BUT_SEARCHSUB"), win32con.BM_GETCHECK, 0, 0) return ret, check != 0 def UnselectItem(self, item): if self.single_select: win32gui.SendMessage(self.list, commctrl.TVM_SELECTITEM, commctrl.TVGN_CARET, 0) else: state = INDEXTOSTATEIMAGEMASK(IIL_UNCHECKED) mask = commctrl.TVIS_STATEIMAGEMASK buf, extra = PackTVITEM(item[0], state, mask, None, None, None, None, None) win32gui.SendMessage(self.list, commctrl.TVM_SETITEM, 0, buf) def _CheckSelectionsValid(self, is_close = False): if self.in_check_selections_valid: return self.in_check_selections_valid = True try: if self.single_select: if is_close: # Make sure one is selected. for ignore in self._YieldCheckedChildren(): break else: self.manager.ReportInformation("You must select a folder") return False else: # In a single-select dialog, we can't stop the user selecting # a 'top-level' folder - we can only stop them closing the # dialog while it is selected. return True # For a multi-select dialog, we simply un-check the existing item. # For single-select, we set no item selected. result_valid = True for info, spec in self._YieldCheckedChildren(): try: folder = self.manager.message_store.GetFolder(spec.folder_id) parent = folder.GetParent() try: # Psts and the main Exchange store have top level # folders with parents (with empty display names), # and no grandparents. Anything below the top # level *does* have a grandparent. This means our # test for "top level folder" can be: does it have # a parent *and* grandparent. However, a # secondary Exchange account doesn't have the # empty-display-name parent, so the top-level # doesn't have a parent, and the top selectable # folder doesn't have a grandparent, and our test # fails. Allow for this by checking for the # "Access denied" exception when getting the # grandparent, and assuming that this means that # this is what is happening. This will only fail # if we get an 'access denied' error for the # empty-display-name parent, which should not be # the case. grandparent = parent.GetParent() except self.manager.message_store.MsgStoreException, details: hr, msg, exc, argErr = details.mapi_exception if hr == winerror.E_ACCESSDENIED: valid = parent is not None else: raise # but only down a couple of lines... else: valid = parent is not None and grandparent is not None except self.manager.message_store.MsgStoreException, details: print "Eeek - couldn't get the folder to check " \
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -