def validDel(self, *args, **kwargs): """ Функция валидации при удалении. @return: True/False. """ # Если функция валидации не определена, # то и валидацию производить не надо if not self.isValidDel(): return True else: print('>>>', self.isValidDel(), self.isICAttrValue('valid_del')) context = self.GetContext() context['ARGS'] = args context['OBJ_UUID'] = kwargs.get('obj_uuid', None) context['RECORD'] = kwargs.get('requisite_values', None) context.update(kwargs) result = self.eval_attr('valid_del') if result[0] == coderror.IC_EVAL_OK: return result[1] else: io_prnt.outWarning( u'Ошибка валидации при удалении БИЗНЕС ОБЪЕКТА <%s>.' % self.name) return False
def initLevelChoice(self, level_index, auto_select=True): """ Инициализировать список выбора. @param level_index: Индекс уровня, соответствующий списку выбора @param auto_select: Автоматический выбор первого элемента списка. @return: True/False. """ if self._sprav.isEmpty(): # Если справочник пустой, то не можем # инициализировать по индексу уровня io_prnt.outWarning( u'Пустой справочник. Не возможно инициализировать список выбора' ) return False if level_index < 0: level_index = 0 elif level_index >= len(self._selected_code): level_index = len(self._selected_code) - 1 # Получить контрол выбора кода уровня choice_ctrl = self._choice_ctrl_list[level_index] if choice_ctrl: str_code = ''.join(self._selected_code[:level_index]) level_choices = [ (rec[0][len(str_code):], rec[1]) for rec in self._sprav.getStorage().getLevelTable(str_code) ] for code, name in level_choices: item = choice_ctrl.Append(name) choice_ctrl.SetClientData(item, code) if auto_select: self.selectLevelChoice(level_index, auto_select=auto_select) return True
def getReportDir(self): """ Папка отчетов. Папка отчетов по умолчанию всегда находиться в папке проекта. Например: /defis/NSI/NSI/reports. @return: Полный путь до директории отчетов. """ if self._report_dir is None: prj_dir = ic_user.icGet('PRJ_DIR') self._report_dir = os.path.join( prj_dir, config.get_glob_var('DEFAULT_REPORT_DIRNAME')) # Проверить сразу существует ли папка if not os.path.exists(self._report_dir): try: os.makedirs(self._report_dir) io_prnt.outLog(u'Cоздание папки <%s>' % self._report_dir) description_filename = os.path.join( self._report_dir, 'descript.ion') prj_name = os.path.basename(prj_dir) ic_extend.save_file_text( description_filename, u'Отчеты прикладной системы <%s>' % prj_name) init_filename = os.path.join(self._report_dir, '__init__.py') ic_extend.save_file_text(init_filename, DEFAULT_INIT_PY_FMT % prj_name) except IOError: io_prnt.outWarning(u'Ошибка создания папки <%s>' % self._report_dir) return self._report_dir
def moveFilterDown(self, filter_idx=None): """ Передвинуть фильтр с индексом filter_idx вниз по списку. @param filter_idx: Индекс фильтра. Если None, то берется текущий выбранный. @return: True/False. """ if filter_idx is None: filter_idx = self.filterCheckList.GetSelection() num_filters = len(self._filters) if (filter_idx < 0) or (filter_idx >= num_filters): io_prnt.outWarning(u'Не корректный индекс <%s>' % filter_idx) return False elif filter_idx == num_filters-1: io_prnt.outWarning(u'Не возможно передвинуть фильтр ниже') return False # Меняем фильтры местами selected_filter = self._filters[filter_idx] self._filters[filter_idx] = self._filters[filter_idx + 1] self._filters[filter_idx + 1] = selected_filter self.refreshFilters() # Выделить self.filterCheckList.SetSelection(filter_idx + 1) return True
def delRec(self, Cod_, DateTime_=None): """ Удалить запись по коду. @param Cod_: Код. @param DateTime_: Период актуальности. """ level = self.getLevelByCod(Cod_) if level: # Контроль на уровне del_ctrl_result = level.getDelCtrl(locals()) if del_ctrl_result is None: # Контроля производить не надо return self._delRec(Cod_, DateTime_) elif del_ctrl_result == coderror.IC_CTRL_OK: # Контроль успешный return self._delRec(Cod_, DateTime_) elif del_ctrl_result in (coderror.IC_CTRL_FAILED, coderror.IC_CTRL_FAILED_IGNORE, coderror.IC_CTRL_FAILED_TYPE_SPRAV, coderror.IC_CTRL_FAILED_LOCK): # Контроль не прошел io_prnt.outWarning( u'Не прошел контроль удаления записи в справочник [%s]. Код ошибки: <%d>' % (self.getName(), del_ctrl_result)) return False
def setUUID(self, uuid): """ Установить UUID бизнес объекта/документа как выбранный. @param uuid: UUID бизнес объекта/документа. @return: True/False. """ if uuid is None: # Да пустое значение тоже можно # устанавливать в контроле self._selected_uuid = None self.SetValue(u'') return True if self._ref_obj is not None: self._ref_obj.load_obj(uuid) txt = self._ref_obj.getRequisiteValue('n_obj') if txt: self._selected_uuid = uuid self.SetValue(txt) return True else: io_prnt.outWarning( u'Не определен бизнес объект/документ в контроле icRefObjChoiceComboCtrl' ) return False
def addFilter(self, new_filter=None, auto_select=True): """ Дбавить фильтр. @param new_filter: Структура фильтра. @param auto_select: Автовыбор нового фильтра? @return: True/False. """ if new_filter is None: # Необходимо сначала сконструировать фильтр new_filter = filter_constructor_dlg.icFilterConstructorDlg(self, None, self.environment) if new_filter: filter_id = self._genUUID() filter_description = ic_dlg.icTextEntryDlg(self, u'Фильтр', u'Введите наименование фильтра') new_filter['id'] = filter_id new_filter['description'] = filter_description else: io_prnt.outWarning(u'Не определен фильтр для добавления') return False if new_filter: self._filters.append(new_filter) i = len(self._filters) self.Append(new_filter['description'], new_filter['id']) if auto_select: self.Select(i)
def addRec(self, Cod_, RecDict_, DateTime_=None, ClearCache_=False): """ Добавить запись в справочник по коду. @param Cod_: Код. @param RecDict_: Словарь изменений. @param DateTime_: Период актуальности. @param ClearCache_: Обновить кеш? @return: Возвращает результат выполнения операции. """ level = self.getLevelByCod(Cod_) if level: # Контроль на уровне add_ctrl_result = level.getAddCtrl(locals()) if add_ctrl_result is None: # Контроля производить не надо return self._addRec(Cod_, RecDict_, DateTime_, ClearCache_) elif add_ctrl_result == coderror.IC_CTRL_OK: # Контроль успешный return self._addRec(Cod_, RecDict_, DateTime_, ClearCache_) elif add_ctrl_result in (coderror.IC_CTRL_FAILED, coderror.IC_CTRL_FAILED_IGNORE, coderror.IC_CTRL_FAILED_TYPE_SPRAV, coderror.IC_CTRL_FAILED_LOCK): # Контроль не прошел io_prnt.outWarning( u'Не прошел контроль добавления записи в справочник [%s]. Код ошибки: <%d>' % (self.getName(), add_ctrl_result)) return False
def OnClose(self, event): """ Закрытие. ВНИМАНИЕ! При выходе из программы не надо вызывать <event.Skip()>, чтобы не было повторного вызова процедуры закрытия """ try: if self.isICAttrValue(ic_win.RES_WIN_CLOSE): self.evalSpace['evt'] = event self.evalSpace['event'] = event result = self.eval_attr(ic_win.RES_WIN_CLOSE) if result and not result[1]: # Не нажато подтверждение выхода из главного окна io_prnt.outWarning(u'Условия корректного выхода из программы не подтверждены') return # ВНИМАНИЕ! Для корректного выхода из приложения необходимо # закрыть все внутренние циклы ядра # А затем произвести все остальные действия kernel = ic_user.getKernel() if kernel: kernel.stop() # Остановить основной цикл выполнения приложения app = wx.GetApp() if app: app.ExitMainLoop() except: io_prnt.outErr(u'Ошибка закрытия главного окна')
def _createSelectMenu(self, Items_): """ Создание меню выбора. """ self._menuitem_item_dict = {} menu = wx.Menu() if Items_: for item in Items_: text = item['description'] if item['description'] else item[ 'name'] img = None if 'img' in item: img = item['img'] id = wx.NewId() menu_item = wx.MenuItem(menu, id, text) if img: menu_item.SetBitmap(img) menu.AppendItem(menu_item) self.Bind(wx.EVT_MENU, self.onSelectMenuItem, id=id) self._menuitem_item_dict[id] = item else: io_prnt.outWarning( u'Конструктор фильтров. Не определены пункты для выбора функции' ) return menu
def setDataset(self, dataset): """ Установить данные справочника. """ if dataset: # Удаляем все элемены справочника только # если у нас есть что отобразить self.sprav_list_ctrl.DeleteAllItems() for record in dataset: code = record[0] name = record[1] index = self.sprav_list_ctrl.InsertStringItem(sys.maxint, code) self.sprav_list_ctrl.SetStringItem(index, 1, name) self.sprav_list_ctrl.SetColumnWidth(0, wx.LIST_AUTOSIZE) self.sprav_list_ctrl.SetColumnWidth(1, wx.LIST_AUTOSIZE) # Вкл./Выкл. кнопки перехода на родительский уровень self.dlg_toolbar.EnableTool(self.return_tool.GetId(), not self.isEmptyCode()) else: io_prnt.outWarning( u'Не определен датасет справочника (код <%s>) для выбора' % self._getStrCode())
def choiceSprav(self): """ Вызов выбора из справочника. @return: Выбранный код. """ if self._selected_codes is None: self._selected_codes = list() if self._sprav is not None: result = self._sprav.Hlp(field='name', parentForm=self, view_fields=self._view_fieldnames, search_fields=self._search_fieldnames) if result[0] in (0, coderror.IC_HLP_OK): code = result[1] name = result[2] if code not in self._selected_codes: self._selected_codes.append(code) label = self.GetValue( ) + DEFAULT_LABEL_DELIMETER + name if self.GetValue( ) else name self.SetValue(label) return code else: io_prnt.outWarning( u'Код [%s] уже присутствует в выбранных' % code) else: io_prnt.outErr( u'Ошибка выбора справочника <%s>. Результат %s' % (self._sprav.name, result)) return None
def undo(self): """ Запуск выполнения отмены операции. @return: True/False. """ # Если функция не определена, то и не выполнять if not self.is_do_func(): return True else: io_prnt.outLog(u'Отмена ОПЕРАЦИИ <%s>' % self.name) context = self.GetContext() context['OBJ'] = self.parent context['UUID'] = self.parent.getUUID() # Пред обработка if self.isICAttrValue('prev_undo'): self.eval_attr('prev_undo') result = self.eval_attr('undo_func') # Пост обработка if self.isICAttrValue('post_undo'): self.eval_attr('post_undo') if result[0] == coderror.IC_EVAL_OK: return result[1] else: io_prnt.outWarning(u'Ошибка отмены ОПЕРАЦИИ <%s>.' % self.name) return False
def getSpravChoiceListDlg(parent=None, sprav=None): """ Вызов диалогового окна выбора кода справочника. @param parent: Родительское окно. @param sprav: Справочник. Может задаваться как объектом, так и паспортом справочника. @return: Строковый выбранный код. """ result = None if parent is None: parent = wx.GetApp().GetTopWindow() if sprav: if ic_util.is_pasport(sprav): # Справочник задается паспортом # Надо создать объект sprav = ic.getKernel().Create(sprav) dlg = None try: dlg = icSpravChoiceListDialog(parent) dlg.setSprav(sprav) dlg.ShowModal() result = dlg.getSelectedCode() dlg.Destroy() dlg = None except: if dlg: dlg.Destroy() io_prnt.outErr(u'Ошибка диалогового окна выбора кода справочника.') else: io_prnt.outWarning( u'Не определен справочник диалогового окна выбора кода справочника.' ) return result
def setCodes(self, codes): """ Установить коды справочника как выбранные. @param codes: Коды справочника. Список строк. ВНИМАНИЕ! Коды могут задаваться строкой. Тогда считаем что это список из 1 кода. @return: True/False. """ if codes is None: # Да пустое значение тоже можно # устанавливать в контроле self._selected_codes = None self.SetValue(u'') return True if isinstance(codes, str) or isinstance(codes, unicode): codes = [codes] self._selected_codes = list() if self._sprav is not None and codes: names = list() for code in codes: name = self._sprav.Find(code) if name: self._selected_codes.append(code) names.append(name) label = DEFAULT_LABEL_DELIMETER.join(names) self.SetValue(label) return True else: io_prnt.outWarning( u'Не определен справочник в контроле icSpravMultipleChoiceComboCtrl' ) return False
def Reconstruct(self): """ Переконструирует шапку. """ for obj in self.parAddList: self.sz.Remove(obj) for indx, obj in enumerate(self.parAddList): if obj.size[0] == -1: obj.SetSize((10, obj.size[1])) else: obj.SetSize(obj.size) if obj.position == (-1, -1): pos = (0, indx) else: pos = obj.position try: self.sz.Add(obj, pos, obj.span, obj.add_style) except: io_prnt.outWarning(u'wxGridBagSize cell (%s : %s) is busy' % (pos[0], pos[1])) self.sz.Layout() self.Refresh() if self.grid: vx, vy = self.grid.GetViewStart() dx, dy = self.grid.GetScrollPixelsPerUnit() self.ScrollWindow(-vx * dx, 0) self.scroll_pos = (vx * dx, 0)
def selectCode(self, code): """ Выбрать код и отобразить его в списке. """ code_list = self._sprav.StrCode2ListCode(code) if code_list: code_list = [sub_code for sub_code in code_list if sub_code] self._cur_code = code_list[:-1] else: self._cur_code = (None, ) self.setSelectedCode(code) parent_code = self._getStrCode() dataset = self._sprav.getStorage().getLevelTable(parent_code) self.setDataset(dataset) # Отобразить путь code_path = self.getSpravPath(self._cur_code) self.path_statictext.SetLabel(code_path) try: codes = [rec[0] for rec in dataset] idx = codes.index(code) self.sprav_list_ctrl.Select(idx) self.sprav_list_ctrl.Focus(idx) except ValueError: print(code, self._cur_code, code_list) io_prnt.outWarning( u'Ошибка определения кода справочника <%s> при выборе из <%s>' % (code, parent_code))
def addMainNotebookPage(self, Page_, Title_, Select_=False, Image_=None, not_dublicate=True): """ Добавить страницу. @param Page_: Страница-объект наследник wx.Window. @param Title_: Заголовок страницы. @param Select_: Выбирается по умолчанию эта страница? @param Image_: Файл образа или сам образ в заголовке страницы. @param not_dublicate: Не открывать страницу с таким же именем? """ try: # Объект главного менеджера системных панелей if self._MainNotebook: if Image_ is None: Image_ = wx.NullBitmap if type(Title_) not in (str, unicode): io_prnt.outWarning(u'Не допустимый тип <%s> заголовка страницы нотебука' % type(Title_)) Title_ = str(Title_) # Добавить страницу return self._MainNotebook.addPage(Page_, Title_, Select_, Image_, not_dublicate) except: io_prnt.outErr(u'Ошибка добавления страницы в главное окно.') return None
def getReportResourceFilename(self, report_filename='', report_dir=''): """ Получить полное имя файла шаблона отчета. @param report_filename: Имя файла отчета в кратком виде. @param report_dir: Папка отчетов. @return: Полное имя файла отчета. """ # Проверить расширение if not report_filename.endswith(DEFAULT_REPORT_FILE_EXT): report_filename = os.path.splitext( report_filename)[0] + DEFAULT_REPORT_FILE_EXT if os.path.exists(report_filename): # Проверить может быть задано абсолютное имя файла filename = report_filename else: # Задано скорее всего относительное имя файла # относительно папки отчетов filename = os.path.join(report_dir, report_filename) if not os.path.exists(filename): # Нет такого файла io_prnt.outWarning(u'Файл шаблона отчета <%s> не найден' % filename) filename = None return filename
def saveFilter(self, filter_filename=None): """ Сохранить фильтр. @param filter_filename: Имя файла хранения фильтра. Если не определен, то генерируется по UUID. @return: True/False. """ if filter_filename: filter_filename = os.path.normpath(filter_filename) else: filter_filename = self._filter_filename if filter_filename: if os.path.exists(filter_filename): # Сначала прочитать файл res = ic_res.LoadResource(filter_filename) if res: # Затем расширить своими фильтрами и записать res[self.getUUID()] = self._filter ic_res.SaveResourcePickle(filter_filename, res) else: io_prnt.outWarning(u'Error resource file <%s>' % filter_filename) return False else: # Просто записать в файл res = {self.getUUID(): self._filter} ic_res.SaveResourcePickle(filter_filename, res) else: io_prnt.outWarning(u'Not define save filter file') return False return True
def delFilter(self, filter_name=None): """ Удалить фильтр. @param filter_name: Имя фильтра. @return: True/False. """ if filter_name is None: # Если имя не определено удалить выбранный фильтр i = self.filterCheckList.GetSelection() if i >= 0: do_del = ic_dlg.icAskBox(u'Удаление', u'Удалить фильтр?') if do_del: del self._filters[i] self.filterCheckList.Delete(i) return True return False else: filters_id = [filter_dict['id'] for filter_dict in self._filters] try: i = filters_id.index(filter_name) except IndexError: io_prnt.outWarning(u'Не найден фильтр <%s> среди <%s>' % (filter_name, filters_id)) return False del self._filters[i] self.filterCheckList.Delete(i+1) return True
def _Log(self, Msg_): """ Регистрация сообщения/ошибки. @param Msg_: Текст сообщения. """ if self._CanLog: io_prnt.outWarning(Msg_)
def setIcon(self, Icon_): """ Установить иконку. @param Icon_: Или имя файла *.ico или объект wx.Icon. """ if type(Icon_) in (str, unicode): ico_file_name = ic.utils.ic_file.AbsolutePath(Icon_) # Установить иконку (если файл существует) if os.path.exists(ico_file_name): try: icon = wx.Icon(ico_file_name, wx.BITMAP_TYPE_ICO) except: io_prnt.outErr( u'Ошибка инициализации иконки <%s> главного окна. Файл не ICO формата.' % ico_file_name) return None else: io_prnt.outWarning(u'Иконка главного окна <%s> не найдена' % ico_file_name) return None elif isinstance(Icon_, wx.Icon): icon = Icon_ else: io_prnt.outWarning(u'Не обрабатываемый тип иконки <%s>' % Icon_) return None self.SetIcon(icon) return icon
def getLockDir(): """ Определить папку блокировок. """ lock_dir = ic.engine.ic_user.icGet('LOCK_DIR') if not lock_dir: io_prnt.outWarning(u'NOT DEFINE LOCK_DIR') return lockDir return lock_dir
def createStorage(self, ShowMsg_=True): """ Создать хранилище справочников. @param ShowMsg_: Признак отображения предупреждения о неправильно определенном хранилище. """ db_name = self.getDBName() self._storage = None if db_name: path_res = None db_subsys = self.getDBResSubSysName() if db_subsys: path_res = resource.getSubsysPath(db_subsys) db_res = resource.icGetRes(db_name, ext='src', pathRes=path_res, nameRes=db_name) if db_res: try: if db_res['type'] != storesrc.OBJ_STORAGE_SRC_TYPE: # SQL-ная БД self._storage = icspravstorage.icSpravSQLStorage( self, db_name, self.getTableName(), DBSubSys_=db_subsys, TabSubSys_=self.getTabResSubSysName()) elif db_res['type'] == storesrc.OBJ_STORAGE_SRC_TYPE: # Объектная БД from . import icodb_spravstorage self._storage = icodb_spravstorage.icSpravODBStorage( self, db_name, self.getTableName()) else: io_prnt.outWarning( u'ОШИБКА! Не определенный тип БД %s СПРАВОЧНИКА %s' % (db_res['type'], self.getName())) except: io_prnt.outErr( u'Ошибка создания хранилища справочников %s %s' % (db_name, self.getTableName())) else: # База данных не указана, поэтому считаем что по умолчанию # это SQL БД и таблица сама определяет в какой БД ей храниться # SQL-ная БД self._storage = icspravstorage.icSpravSQLStorage( self, None, self.getTableName()) if ShowMsg_ and not self._storage: ic_dlg.icMsgBox( u'ВНИМАНИЕ!', u'Не определено хранилище справочника: %s БД: %s Таблица: %s' % (self.getName(), db_name, self.getTableName())) return self._storage
def getMenuItem(self): """ Объект пункта меню, к которому привязан инструмент. """ menubar = self.getMenuBar() item_name = self.getMenuItemName() item = None if item_name: item = menubar.findMenuItemByName(item_name) if item is None: io_prnt.outWarning(u'Пункт меню <%s> не найден!' % item_name) return item
def getResourceByPspLink(self, component): """ Собирает ресурсное описание по ссылке. Ресурсное описание собирается по паспорту объекта. @type component: C{dictionary} @param component: Словарь описания ссылки. """ res = None res_query = util.getSpcAttr(component, 'res_query', self.evalSpace).strip() psp_link = component['psp_link'] _query = res_query.split(':') try: link_type = _query[1].split('.')[0] link_name = _query[1].split('.')[1] io_prnt.outLog( u'ICDATASET: point to object resource: type=<%s>, name=<%s>' % (link_type, link_name)) except: link_type = None link_name = None # Получаем ресурсное описание, где в общем случае ищется # описание нужного компонента io_prnt.outLog(u'Связь с ресурсом по паспорту: %s' % psp_link) res = resource.getResByPsp(psp_link) # ---- В ресурсе ищем описание нужного компoнента # (<key_in_fileres>:type.name) if link_name and link_type: ret = getRes(res, link_type, link_name) if not ret: io_prnt.outWarning(u'Не найден объект [%s : %s] в ресурсе' % (link_type, link_name)) res = None # ------------------------------------------------------------- # В полученном ресурсном описании ищем ссылки и заменяем их # на ресурсные описания if res: res = self.doReplacementRes(res, component) else: # Если ресурсное описание не найдено и выражение изменений не # определено, то сообщаем об этом пльзователю ic_dlg.icWarningBox( u'ОШИБКА', u'Описание объекта <%s> в %s не найдено.' % (res_query, psp_link)) return res
def setSpravByPsp(self, sprav_psp): """ Установить дерево справочника по его паспорту. @param sprav_psp: Паспорт справочника. """ if not ic_util.is_pasport(sprav_psp): io_prnt.outWarning(u'Не корректное значение паспорта <%s>' % sprav_psp) return self.Clear() self.init(sprav_psp, self.view_code, self.view_all)
def edit(self): """ Редактирование модуля. """ # Определяем имя модуля py_name = self.getModuleName() py_dir = self.getModulePath() py_file = os.path.join(py_dir, py_name + self.ext) # Определяем IDE ide = self.getRoot().getParent().ide if ide is None: io_prnt.outWarning( u'Не определен IDE для редактрования модуля <%s>' % py_file) io_prnt.outLog(u'Используется внешний редактор модулей Python') ide = ext_python_editor.icExtPythonEditor() if ide: # Сначала разблокировать все модули self.getRoot().unlockAllPyFilesInIDE() if ide.IsOpenedFile(py_file): ide.CloseFile(py_file) else: parent_pack = os.path.basename(py_dir) # Если модуль заблокирован, # тогда открыть его только для просмотра if ic_res.isLockRes(self.name, parent_pack, 'py', self.getRoot().lock_dir): lock_rec = ic_res.getLockResRecord(self.name, parent_pack, 'py', self.getRoot().lock_dir) ic_dlg.icMsgBox( u'ВНИМАНИЕ!', u'Ресурс <%s> заблокирован пользователем <%s>. Компьютер: <%s>.' % (self.name, lock_rec['user'], lock_rec['computer'])) self.readonly = True else: # Заблокировать файл ic_res.lockRes(self.name, parent_pack, 'py', self.getRoot().lock_dir) # Условие открытия в редакторе ресурса if self.isResClass(py_file): self.getRoot().getParent().res_editor.SetResource(self.name, py_dir, self.name, 'py', bEnable=True) return ide.OpenFile(py_file, True, readonly=self.readonly) return False
def DestroyWin(self): """ Обрабатывает закрытие окна. """ # Посылаем всем уведомление о разрущении родительского окна. try: for key in self.evalSpace['_dict_obj']: try: self.evalSpace['_dict_obj'][key].ObjDestroy() except: io_prnt.outWarning(u'Ошибка разрушения фрейма') except: io_prnt.outWarning(u'Ошибка разрушения фрейма')