def RefreshData(self, data=None): """ Функция обновляет данные в таблице. """ self.ClearAll() self.colLabels = [] self.colNames = [] self.exCols = [] self.retInfo = [0, []] i = 0 # Определяем подписи и типы колонок for col in self.cols: bShow = True try: attr_show = '@' + col['show'] bShow = util.getICAttr(attr_show, self.evalSpace, 'Error in getICAttr in iclistdataset <show>=%s' % col['show']) except: pass if col['attr'] != 'UV' and bShow: self.colNames.append(col['name']) self.colLabels.append(col['label']) self.exCols.append(col) self.InsertColumn(i, col['label']) if 'width' in col: try: self.SetColumnWidth(i, col['width']) except: pass i += 1 # Получаем курсор на источник данных if self.dataset is None: log.debug(u'icListDataset RefreshData: %s Source: <%s>' % (data, self.source)) # Если источник данных прописан if self.source: MsgBox(self.grid, _('icListDataset: Data source %s is not defined in the object context.') % self.link_res) # В обратном случае используем стандартный icSimpleDataset else: self.dataset = icsimpledataset.icSimpleDataset(icwidget.icNewId(), {'description': self.exCols}) elif data and not self.source: self.dataset.SetDataBuff(data) # Обновляем данные в буффере try: self.dataset.Refresh() except: msg = _('Refrsh data error. <dataset=%s>') % self.dataset.name MsgBox(None, msg) # Определяем количество строк self.SetItemCount(self.dataset.getRecordCount()) self.Refresh()
def CtrlValue(self, value=None): """ Контроль значения. @rtype: C{bool} @return: Возращает признак, разрещающий или запрещающий установить значение. """ codCtrl = IC_CTRL_OK if value is None: value = self.GetValue() if value is not None: # Проводим контроль, введенного текста, если компонент работает с # классом данных if self.IsModified() and self.dataset is not None: codCtrl = self.UpdateDataDB() # Если компонент не связан с классом данных elif self.IsModified(): codCtrl = self.Ctrl(bAsk=False, value=value) if isinstance(codCtrl, tuple): codCtrl = codCtrl[0] ################################################################ # Добавляем слово в частотный словарь if codCtrl in [ IC_CTRL_OK, IC_CTRL_REPL ] and self._freqDict and self.pictype in (IC_N_STRING_FORMAT, IC_STRING_FORMAT): dct = self._freqDict.AddWordInFreqDict(self.field_name, value) ################################################################ # Если контролем требуется подтверждение if codCtrl == IC_CTRL_REPL: if MsgBox(self.parent, _('Do you really want change value: %s?') % value, style=wx.YES_NO | wx.NO_DEFAULT) != wx.ID_YES: codCtrl = IC_CTRL_FAILED_IGNORE # Если один из контролей не прошел, восстанавливаем старое значение и # сообщаем пользователю if codCtrl in [IC_CTRL_FAILED, IC_CTRL_FAILED_IGNORE]: if codCtrl == IC_CTRL_FAILED: MsgBox( self.parent, _('Invalid field value. value: <%s>, field: <%s>') % (value, self.name)) self.bChanged = True self.SetValue(self._oldValue or '') self.SetFocus() # В случае если не удается востановить значение штатным методом if codCtrl == IC_CTRL_FAILED_IGNORE or not self.UpdateViewFromDB( ): self.SetValue(self._oldValue) self.SetFocus() return False return True
def UpdateDataDB(self, db_name=None, bRestore=False): """ Обновляем данные в базе данных. @type db_name: C{String} @param db_name: Имя источника данных. @type bRestore: C{bool} @param bRestore: Признак обновления представления. Если True, то при неудачной попытки записи программа востановит значение поля по базе @rtype: C{int} @return: Возвращает код контроля на запись. """ # Если класс данных не задан, то считаем, что данные необходимо обновить if db_name is None: db_name = self.dataset.name # Проводим контроль поля ret = self.Ctrl() values = None if isinstance(ret, tuple): codCtrl, values = ret else: codCtrl = int(ret) if self.dataset is not None and self.dataset.name == db_name and codCtrl in [ IC_CTRL_OK, IC_CTRL_REPL ]: # Если контролем требуется подтверждение if codCtrl == IC_CTRL_REPL: if MsgBox( self.parent, _('Do you really want change value: %s?') % self.name, style=wx.YES_NO | wx.NO_DEFAULT) != wx.ID_YES: codCtrl = IC_CTRL_FAILED_IGNORE else: codCtrl = IC_CTRL_OK if codCtrl == IC_CTRL_OK: value = self.GetValue() codCtrl = self.dataset.setNameValue(self.field_name, value) if codCtrl == IC_CTRL_OK and isinstance(values, dict): for fld in values: val = values[fld] ctrlFld = self.dataset.setNameValue(fld, val) if ctrlFld == IC_CTRL_FAILED: MsgBox( self.parent, _('Invalid field value. value: <%s>, field: <%s>') % (val, fld)) codCtrl = ctrlFld break return codCtrl
def OnSetFocus(self, evt): """ Обрабатывает установку фокуса (сообщение EVT_SET_FOCUS). """ if self.bTimeLosefocus: self.bTimeLosefocus = False evt.Skip() return # Формируем пространство имен value = self.GetValue() self.evalSpace['evt'] = evt self.evalSpace['event'] = evt self.evalSpace['value'] = value evt.Skip() # Блокируем запись для редактирования, если позволяет объект данных if self.dataset and not self.evalSpace['__block_lock_rec']: rec = self.dataset.Recno() result = self.dataset.Lock(rec) if not result and rec != self._oldLockReck: self.bkillfocus = False MsgBox( self.parent, _('Record (%d) is locked. <TextField=%s>, err=%s') % (rec, self.name, str(result))) self._oldLockReck = rec self.bkillfocus = True else: io_prnt.outLog('TEXTFIELD LOCK RECORD: %s' % str(rec)) self.eval_attr('setFocus') self.bChanged = False
def OnLoad(self, evt): """ Загружает файл. """ evt.Skip() if self.editor.IsChanged and MsgBox( self, u'Файл %s был изменен. Сохранить?' % self.editor.GetModuleName(), style=wx.YES_NO | wx.NO_DEFAULT) == wx.ID_YES: self.Save() dlg = wx.FileDialog(self, u'Выбери имя файла', '', '', _PyCard, wx.OPEN) if dlg.ShowModal() == wx.ID_OK: path = dlg.GetPaths()[0] f = open(path) txt = f.read() f.close() self.editor.IsFirstLoad = True self.editor.SetText(txt) self.editor.IsFirstLoad = True self.editor.SetModuleName(path) self.SetTitle(u'Редактор (%s)' % path) self.editor.IsChanged = False
def icInputDate(parent, day=None, month=None, year=None): """ Функция позволяет вводить дату. В качестве параметров передается дата, на которую будет установлен календарь. Если параметры даты не передаются, то установится текщая дата. @type parent: C{wx.Windows} @param parent: Родительское окно. @type day: C{integer} @param day: День недели. @type month: C{integer} @param month: Месяц. @type year: C{integer} @param year: Год. @rtype: C{List} @return: Возвращает выбранную дату либо None. """ if parent is None: MsgBox(None, u'Для данного отображения календаря необходимо родительское окно !') return None dlg = icCalendarDialog(parent, day, month, year) dlg.result = [day, month, year] dlg.CenterOnScreen() if dlg.ShowModal() == wx.ID_OK: str_date = dlg.getStrDate() return str_date else: log.warning(u'No Date Selected') return None
def SetFilter(self, clsName, flt=None, isUpdSelf=False): """ Устанавливаем фильтр на нужный объект данных. @type clsName: C{string} @param clsName: Имя класса данных на который устанавливается фильтр. @type filter: C{string | dictionary} @param filter: Фильтр, накладываемый на класс данных. @type isUpdSelf: C{bool} @param isUpdSelf: Признак того, что необходимо обновлять и состояние текущего объекта. """ try: dataset = self.evalSpace['_sources'][clsName] real_name = dataset.name # Если буфер заполнен, то необходимо запросить потверждение на # обновление данных и обновить данные. В противном случае изменения # будут потеряны if not dataset.IsEOF() and dataset.isChangeRowBuff() and MsgBox(None, _('Save changes?'), style=wx.YES_NO | wx.ICON_QUESTION) == wx.ID_YES: dataset.update() if flt: dataset.FilterFields(flt) # Уведомляем другие компоненты формы о том, что состояние объекта данных могло измениться for key in self.evalSpace['_has_source'].keys(): try: if key != self.name or isUpdSelf: self.evalSpace['_has_source'][key].UpdateViewFromDB(real_name) # Обновляем связанные гриды self.evalSpace['_has_source'][key].UpdateDataView(real_name) except: pass except KeyError: MsgBox(None, _('Dataclass %s is not defined in context.') % clsName) except: io_prnt.outErr(u'Error in ic.components.iclistdataset.setFilter')
def SetFilterField(self, clsName, fieldName, row): """ Устанавливаем фильтр на объект группы (связь один ко многим). @type clsName: C{string} @param clsName: Имя класса данных, который фильтруется @type fieldName: C{string} @param fieldName: Поле в классе данных, по которому фильтруем. @type row: C{int} @param row: Текущий номер строки в списке. Будут отобраны те строки класса данных, значения полей <fieldName> которых, будут соответствовать идентификатору текущей записи. """ try: dataset = self.evalSpace['_sources'][clsName] # Если буфер заполнен, то необходимо запросить потверждение на # обновление данных и обновить данные. В противном случае изменения # будут потеряны if dataset.isChangeRowBuff() and MsgBox(None, _('Save changes?'), style=wx.YES_NO | wx.ICON_QUESTION) == wx.ID_YES: dataset.update() id = self.dataset.getId(row, True) dataset.FilterField(fieldName, id) # Уведомляем другие компоненты формы о том, что состояние объекта данных могло измениться for key in self.evalSpace['_has_source'].keys(): try: if key != self.name: self.evalSpace['_has_source'][key].UpdateViewFromDB(clsName) # Обновляем связанные гриды self.evalSpace['_has_source'][key].UpdateDataView(clsName) except: pass except KeyError: MsgBox(None, _('Dataclass %s is not defined in context.') % clsName) except: io_prnt.outErr(u'Error in ic.components.iclistdataset.SetFilterField')
def OnSetFocus(self, evt): """ Обрабатывает установку фокуса. """ # Блокируем запись для редактирования, если позволяет объект данных if self.dataset and not self.evalSpace['__block_lock_rec']: err = self.dataset.Lock() if err in [1, 2] and rec != self._oldLockReck: MsgBox(None, u'Запись (%d) заблокирована err=%s' % (rec, str(err))) self._oldLockReck = rec self.evalSpace['self'] = self self.evalSpace['evt'] = evt self.eval_attr('setFocus') evt.Skip()
def MsgLastError(parent, beg_msg): """ Выводит сообщение о последней ошибке в диалоговое окно. @type parent: C{wxWindow} @param parent: Родительское окно. @type beg_msg: C{string} @param beg_msg: Заголовок сообщения об ошибке. """ trace = traceback.extract_tb(sys.exc_traceback) last = len(trace) - 1 if last >= 0: msg = genTxtLastError(beg_msg) MsgBox(parent, msg) return msg
def OnClose(self, evt): """ Обрабатываем закрытие окна. """ if not self.editor.closed: self.editor.closed = True if self.editor.IsChanged and MsgBox( self, u'Файл %s был изменен. Сохранить?' % self.editor.GetModuleName(), style=wx.YES_NO | wx.NO_DEFAULT) == wx.ID_YES: self.editor.IsChanged = False self.Save() evt.Skip()
def toLog(msg, logType=0): """ Вывод на устройство регистрации специальных сообщений. @type msg: C{string} @param msg: Сообщение об ошибке. @type logType: C{int} @param logType: Тип лога (0 - консоль, 1 - файл, 2 - окно лога, 3 - окно сообщений) """ if logType == IC_FILE_LOGTYPE: pass elif logType == IC_WIN_LOGTYPE: pass elif logType == IC_MSGBOX_LOGTYPE: MsgBox(None, msg) else: try: log.debug(msg) except: pass
def OnSetFocus(self, evt): """ Обрабатывает установку фокуса. Обрабатывается потеря фокуса - используется для контроля значения поля. """ # Блокируем запись для редактирования, если позволяет объект данных try: err = self.dataset.Lock() if err in [1, 2] and rec != self._oldLockReck: MsgBox(None, u'Запись (%d) заблокирована err=%s' % (rec, str(err))) self._oldLockReck = rec except: pass self.evalSpace['evt'] = evt self.evalSpace['self'] = self self.eval_attr('setFocus') evt.Skip()
def OnKeyDown(self, evt): """ Обработка нажатия клавиши (событие EVT_KEY_DOWN). Порядок действий: - обработка выражениия, записанного в аттрибуте keydown - обработка выражениия, записанного в аттрибуте hlp - обработка шаблонов - действия компонента по умолчанию на данное событие (evt.Skip()) """ kcod = evt.m_keyCode if self.GetInsertionPoint() == self.GetLastPosition(): evt.bTabUse = 1 # Формируем пространство имен value = self.GetValue() self.evalSpace['evt'] = evt self.evalSpace['event'] = evt self.evalSpace['value'] = value # --- Запускаем внешний обработчик нажатия клавиш. Если он вернет дальнейшая # обработка будет прекращена result = True if not self.keydown in [None, 'None', '']: ret, result = self.eval_attr('keyDown') if ret and result is not None: result = bool(result) else: result = True if not result: return # Запускаем внешний обработчик нажатия клавиши F1. Контроль ввода временно # отключаем посколку при выполнении выражения фокус может теряться, что будет приводить # к запуску контроля ввода. if evt.m_keyCode == wx.WXK_F1 and self.hlp: self.bkillfocus = False ret, val = self.eval_attr('hlp') # Записываем выбранное значение в поле. Признак изменения устанавливаем. if ret and val is not None: # Если возвращаемое значение картеж, то первый элемент # код выбора, второй значение выбора if isinstance(val, tuple): if len(val) >= 4: codHlp, ret_val, flds_vals, strval = val ret_val = strval.rstrip() else: codHlp, ret_val, flds_vals = val if codHlp == IC_HLP_OK or ( codHlp == IC_HLP_REPL and MsgBox( self.parent, _('Do you really want choose value: %s?') % ret_val, style=wx.YES_NO | wx.ICON_QUESTION) == wx.ID_YES): bChoose = True else: bChoose = False else: ret_val = val flds_vals = {} bChoose = True # Если возвращено значение для заполнения if bChoose: # Если возвращаемое значение картеж, то собираем из # него строку if isinstance(ret_val, tuple): ret_val = ''.join([str(x) for x in ret_val]) else: ret_val = str(ret_val) self.SetValue(ret_val, 1, False) if 1: # Если указан словарь дополнительных значений, то # устанавливаем их if flds_vals and self.dataset: for fld in flds_vals.keys(): self.dataset.setNameValue(fld, flds_vals[fld]) # Фокус надо вернуть в любом случае self.SetFocus() self.bkillfocus = True return # Перемещаемся на следующий компонент в порядке очереди elif evt.m_keyCode == wx.WXK_TAB: self.Navigate() return elif evt.m_keyCode in (wx.WXK_RETURN, wx.WXK_NUMPAD_ENTER ) and not self.style & wx.TE_MULTILINE: self.Navigate() return # --- Обработка шаблона try: text = wx.TextCtrl.GetValue(self) templ = self.pic if evt.ShiftDown() and kcod == wx.WXK_INSERT: self.PostTempl() elif evt.ControlDown() or evt.ShiftDown(): pass elif kcod in (wx.WXK_DELETE, wx.WXK_BACK): self.PostTempl() evt.Skip() return elif kcod not in KEYTEMPLATE: # Проверяем соответствут ли вводимый символ шаблону вывода # При необходимости вставляет символы форматирования if not PrepareTextByTempl(self, self.pictype, templ, text, kcod): return ############################################################ # Генерируем сообщение на автоматическое заполнене тескста event = icEvents.icAutoTextFillEvent(icEvents.icEVT_AUTO_TEXT_FILL, self.GetId()) event.SetData(self.field_name) self.GetEventHandler().AddPendingEvent(event) ############################################################ except: LogLastError('Exception') evt.Skip()