code review

This commit is contained in:
anwinged 2012-05-01 11:03:38 +00:00
parent 9741fc36e3
commit 360e1de5d9
2 changed files with 204 additions and 177 deletions

View File

@ -120,7 +120,6 @@ class MainFrame (wx.Frame):
self.Layout()
self.Centre(wx.BOTH)
def LoadIcons(self):
icons = Icons()
ilist = wx.ImageList(16, 16)
@ -143,7 +142,7 @@ class MainFrame (wx.Frame):
menu.Append(ID_NEW, "&New\tCtrl+N")
menu.Append(ID_OPEN, "&Open\tCtrl+O")
menu.Append(ID_SAVE, "&Save\tCtrl+S")
menubar.Append(menu, '&Model')
menubar.Append(menu, '&Project')
menu = wx.Menu()
menu.Append(ID_ADD_MODEL_ROOT, 'Add model to root')
@ -154,7 +153,7 @@ class MainFrame (wx.Frame):
menu.Append(ID_DELETE_MODEL, 'Delete\tCtrl+E')
menu.AppendSeparator()
menu.Append(ID_TEST, "&Test\tCtrl+T")
menubar.Append(menu, '&Edit')
menubar.Append(menu, '&Model')
menu = wx.Menu()
menu.Append(ID_PROCESS_MODEL, 'Process\tF5')
@ -253,7 +252,6 @@ class LineSelectDialog(wx.Dialog):
self.Layout()
self.Centre(wx.BOTH)
class PlotFrame(wx.Frame):
def __init__(self, parent, title):
wx.Frame.__init__ (self, parent, -1, title, size = wx.Size(600, 400))

View File

@ -79,12 +79,11 @@ class MainFrame(forms.MainFrame):
s = server.LocalServer()
s.LoadModels()
models = s.GetModels()
self.models = models
self.models = s.GetModels()
s.Start()
self.server = s
model = models[0]
# События компонентов
self.m_user_models.Bind(wx.EVT_TREE_SEL_CHANGED,
self.OnModelActivated)
@ -100,7 +99,9 @@ class MainFrame(forms.MainFrame):
self.OnPlotProcess)
self.Bind(wx.EVT_MENU, self.OnNewModel,
# События меню
self.Bind(wx.EVT_MENU, self.OnNewProject,
id = forms.ID_NEW)
self.Bind(wx.EVT_MENU, self.OnTest,
@ -130,6 +131,8 @@ class MainFrame(forms.MainFrame):
self.Bind(wx.EVT_MENU, self.OnAddMarkers,
id = forms.ID_ADD_MARKERS)
# События приложения
self.Bind(wx.EVT_CLOSE, self.OnClose)
self.Bind(wx.EVT_IDLE, self.OnIdle)
@ -145,13 +148,17 @@ class MainFrame(forms.MainFrame):
ov.daemon = True
ov.start()
self.NewProject(model)
self.NewProject(self.models[0])
# Функции приложения и обработки сервера
def OnClose(self, event):
self.server.Stop()
self.Destroy()
def OnIdle(self, event):
pass
def Overseer(self):
"""
Функция-надсмотрщик, которая периодически проверяет состояние
@ -217,6 +224,67 @@ class MainFrame(forms.MainFrame):
except Exception, e:
print 'Error in overseer: ', e
# Функции создания модели, сохранения и загрузки
def BuildSpecs(self, model):
"""
Выстраивает иерархию спецификаций для выбранной модели
"""
def DoItem(item, model):
sp.SetPyData(item, model)
for spec in model.GetSpecs():
child = sp.AppendItem(item, spec.GetTitle())
DoItem(child, spec)
sp = self.m_specs
sp.DeleteAllItems()
root = sp.AddRoot(model.GetTitle())
DoItem(root, model)
sp.ExpandAll()
sp.SortChildren(root)
def NewProject(self, model):
"""
Начать новый проект:
0. Очичтить все компоненты
1. Построить дерево спецификаций
2. Создать одну пользовательскую модель (по умолчанию)
3. Сделать заготовки для графиков/отчетов/прочего
"""
self.m_specs.DeleteAllItems()
self.m_user_models.DeleteAllItems()
self.m_params.ClearPage(0)
self.m_quick_result.ClearPage(0)
self.m_plots.DeleteAllItems()
# Строим спецификации
self.BuildSpecs(model)
# Очищаем окно пользовательских моделей
# и создаем там одну
um = self.m_user_models
um.DeleteAllItems()
um.AddRoot('root')
self.AddModelToRoot(model)
# Создаем корневой элемент для окна с графиками
self.m_plots.AddRoot('root')
self.SetStatusText('Model "{}" selected'.format(model.GetTitle()), 0)
return True # Project(model)
def OnNewProject(self, event):
self.do_nothing = True
f = SelectModelDialog(self, self.models)
if f.ShowModal() == wx.ID_OK:
model = f.GetSelectedModel()
if model:
self.NewProject(model)
self.do_nothing = False
# Функции непосредственной работы с моделями:
# создание, изменение, дублирование и прочее
# Работа с именами моделей
def CheckName(self, name):
"""
Проверяет имя на уникальность в иерархии пользовательских моделей.
@ -242,22 +310,7 @@ class MainFrame(forms.MainFrame):
return name
self.name_id += 1
def BuildSpecs(self, model):
"""
Выстраивает иерархию спецификаций для выбранной модели
"""
def DoItem(item, model):
sp.SetPyData(item, model)
for spec in model.GetSpecs():
child = sp.AppendItem(item, spec.GetTitle())
DoItem(child, spec)
sp = self.m_specs
sp.DeleteAllItems()
root = sp.AddRoot(model.GetTitle())
DoItem(root, model)
sp.ExpandAll()
sp.SortChildren(root)
# Добавление новых моделей
def AddModelToRoot(self, model):
"""
@ -288,130 +341,6 @@ class MainFrame(forms.MainFrame):
if root:
um.Expand(root)
def NewProject(self, model):
"""
Начать новый проект:
1. Построить дерево спецификаций
2. Создать одну пользовательскую модель (по умолчанию)
3. Сделать заготовки для графиков/отчетов/прочего
"""
# Строим спецификации
self.BuildSpecs(model)
# Очищаем окно пользовательских моделей
# и создаем там одну
um = self.m_user_models
um.DeleteAllItems()
um.AddRoot('root')
self.AddModelToRoot(model)
# Создаем корневой элемент для окна с графиками
self.m_plots.AddRoot('root')
return True # Project(model)
def SelectUserModel(self, model_def):
def SelectProperty(param_type):
"""
По указанному имени типа возвращает "свойство" для списка "свойств"
Смотри руководство пользователя для того, чтобы получить полную
информацию о всех типах данных, используемых в Opal.
"""
if param_type == 'bool' or param_type == 'boolean':
return wxpg.BoolProperty
elif param_type == 'int':
return wxpg.IntProperty
elif param_type == 'float' or param_type == 'double':
return wxpg.FloatProperty
elif param_type == 'str' or param_type == 'string':
return wxpg.StringProperty
elif param_type == 'list':
return wxpg.ArrayStringProperty
else:
# очень плохо, если это произошло
raise KeyError()
msg = model_def.PackParams()
pg = self.m_params
pg.ClearPage(0)
for label, value in model_def.params.iteritems():
param = model_def.DD[label]
title = param.GetTitle()
prop = SelectProperty(param.GetType())
pid = pg.Append(prop(title, value = value))
pg.SetPropertyClientData(pid, label)
pg.SetPropertyHelpString(pid, param.GetComment())
self.SetStatusText(model_def.PackParams(), 0)
def ShowQuickResult(self, result):
if not result:
return
pg = self.m_quick_result
pg.ClearPage(0)
for label, param in result.data.iteritems():
pg.Append(wxpg.StringProperty(label, value = str(param.GetValue())))
pg.SetSplitterLeft()
def GetSelectedItem(self, source):
item = source.GetSelection()
if not item.IsOk():
raise ItemError('Invalid item')
return item
def GetSelectedData(self, source):
item = self.GetSelectedItem(source)
data = source.GetPyData(item)
if not data:
raise ItemError('Empty data')
return data
def GetSelectedItemData(self, source):
item = self.GetSelectedItem(source)
data = source.GetPyData(item)
if not data:
raise ItemError('Empty data')
return (item, data)
def OnModelActivated(self, event):
item = event.GetItem()
data = self.m_user_models.GetPyData(item)
if data:
self.SelectUserModel(data.mdef)
self.ShowQuickResult(data.res)
def OnParamChanging(self, event):
#value = event.GetValue()
#print repr(value)
#wx.MessageBox(value, 'changing')
#event.Veto()
pass
def OnParamChanged(self, event):
prop = event.GetProperty()
if not prop:
return
value = prop.GetValue()
param = prop.GetClientData()
item, data = self.GetSelectedItemData(self.m_user_models)
data.mdef[param] = value
self.m_user_models.SetItemImage(item, self.icons.mready)
def OnTest(self, event):
um = self.m_user_models
def OnNewModel(self, event):
self.do_nothing = True
f = SelectModelDialog(self, self.models)
if f.ShowModal() == wx.ID_OK:
model = f.GetSelectedModel()
if model:
print model.GetTitle()
else:
print 'Bad :('
self.do_nothing = False
def OnAddModelToRoot(self, event):
model = self.GetSelectedData(self.m_specs)
self.AddModelToRoot(model)
@ -437,6 +366,103 @@ class MainFrame(forms.MainFrame):
else:
wx.MessageBox('It\'s impossible to append model', 'Error')
# Реакция на выбор модели
def SelectUserModel(self, model_def):
def SelectProperty(param_type):
"""
По указанному имени типа возвращает "свойство" для списка "свойств"
Смотри руководство пользователя для того, чтобы получить полную
информацию о всех типах данных, используемых в Opal.
"""
if param_type == 'bool' or param_type == 'boolean':
return wxpg.BoolProperty
elif param_type == 'int':
return wxpg.IntProperty
elif param_type == 'float' or param_type == 'double':
return wxpg.FloatProperty
elif param_type == 'str' or param_type == 'string':
return wxpg.StringProperty
elif param_type == 'list':
return wxpg.ArrayStringProperty
else:
# очень плохо, если это произошло
raise KeyError()
pg = self.m_params
pg.ClearPage(0)
for label, value in model_def.params.iteritems():
param = model_def.DD[label]
title = param.GetTitle()
prop = SelectProperty(param.GetType())
pid = pg.Append(prop(title, value = value))
pg.SetPropertyClientData(pid, label)
pg.SetPropertyHelpString(pid, param.GetComment())
def ShowQuickResult(self, result):
if not result:
return
pg = self.m_quick_result
pg.ClearPage(0)
for label, param in result.data.iteritems():
pg.Append(wxpg.StringProperty(label, value = str(param.GetValue())))
pg.SetSplitterLeft()
def OnModelActivated(self, event):
item = event.GetItem()
data = self.m_user_models.GetPyData(item)
if data:
self.SelectUserModel(data.mdef)
self.ShowQuickResult(data.res)
# Изменение параметров модели
def OnParamChanging(self, event):
#value = event.GetValue()
#print repr(value)
#wx.MessageBox(value, 'changing')
#event.Veto()
pass
def OnParamChanged(self, event):
prop = event.GetProperty()
if not prop:
return
value = prop.GetValue()
param = prop.GetClientData()
item, data = self.GetSelectedItemData(self.m_user_models)
data.mdef[param] = value
self.m_user_models.SetItemImage(item, self.icons.mready)
def OnTest(self, event):
um = self.m_user_models
# Получение данных выбранной модели
def GetSelectedItem(self, source):
item = source.GetSelection()
if not item.IsOk():
raise ItemError('Invalid item')
return item
def GetSelectedData(self, source):
item = self.GetSelectedItem(source)
data = source.GetPyData(item)
if not data:
raise ItemError('Empty data')
return data
def GetSelectedItemData(self, source):
item = self.GetSelectedItem(source)
data = source.GetPyData(item)
if not data:
raise ItemError('Empty data')
return (item, data)
# Дублирование модели
def OnDuplicate(self, event):
"""
Обработчик события "дублирование модели"
@ -458,17 +484,23 @@ class MainFrame(forms.MainFrame):
def OnDuplicateTree(self, event):
pass
# Удаление модели
def OnDeleteModel(self, event):
item, data = self.GetSelectedItemData(self.m_user_models)
self.server.DeleteJob(data.jid)
self.m_user_models.Delete(item)
# Функции запуска модели на выполнение и управления очередью
def OnModelProcess(self, event):
um = self.m_user_models
for i in um.GetSelections():
data = um.GetItemPyData(i)
self.server.LaunchJob(data.jid, data.mdef)
# Функции управления таблицами и отчетами
def OnShowResult(self, event):
item, data = self.GetSelectedItemData(self.m_user_models)
title = self.m_user_models.GetItemText(item)
@ -476,6 +508,15 @@ class MainFrame(forms.MainFrame):
rframe = ResultFrame(self, title, data.res)
rframe.Show()
# Функции управления графиками
def OnAddPlot(self, event):
root = self.m_plots.GetRootItem()
child = self.m_plots.AppendItem(root, 'New plot')
self.m_plots.SetPyData(child, 'plot')
self.m_plots.SetItemImage(child, self.icons.porg)
self.m_plots.SelectItem(child)
def GetLines(self, line_type):
"""
Возвращает набор линий, которые пользователь указал для
@ -507,30 +548,6 @@ class MainFrame(forms.MainFrame):
return lines
def ShowPlot(self, lines, plot_title = ''):
if lines:
p = PlotFrame(self, 'Plot', lines)
p.Show()
def OnQuickShowPlot(self, event):
lines = self.GetLines(LINE_CURVE)
um = self.m_user_models
item, data = self.GetSelectedItemData(um)
title = um.GetItemText(item)
for line in lines:
colx, coly = line.columns
title_x = data.res.columns[colx].GetTitle()
title_y = data.res.columns[coly].GetTitle()
line.title = "{}: {}({})".format(title, title_y, title_x)
self.ShowPlot(lines, title)
def OnAddPlot(self, event):
root = self.m_plots.GetRootItem()
child = self.m_plots.AppendItem(root, 'New plot')
self.m_plots.SetPyData(child, 'plot')
self.m_plots.SetItemImage(child, self.icons.porg)
self.m_plots.SelectItem(child)
def AddLines(self, line_type):
item, data = self.GetSelectedItemData(self.m_plots)
if data != 'plot':
@ -555,13 +572,28 @@ class MainFrame(forms.MainFrame):
else:
self.m_plots.SetItemImage(child, self.icons.pline)
def OnAddCurves(self, event):
self.AddLines(LINE_CURVE)
def OnAddMarkers(self, event):
self.AddLines(LINE_MARKER)
def ShowPlot(self, lines, plot_title = ''):
p = PlotFrame(self, 'Plot', lines)
p.Show()
def OnQuickShowPlot(self, event):
lines = self.GetLines(LINE_CURVE)
um = self.m_user_models
item, data = self.GetSelectedItemData(um)
title = um.GetItemText(item)
for line in lines:
colx, coly = line.columns
title_x = data.res.columns[colx].GetTitle()
title_y = data.res.columns[coly].GetTitle()
line.title = "{}: {}({})".format(title, title_y, title_x)
self.ShowPlot(lines, title)
def OnPlotProcess(self, event):
item = self.m_plots.GetSelection()
data = self.m_plots.GetItemPyData(item)
@ -581,9 +613,6 @@ class MainFrame(forms.MainFrame):
self.ShowPlot(lines)
def OnIdle(self, event):
pass
#-----------------------------------------------------------------------------
# Форма с выбором модели из представленного списка
#-----------------------------------------------------------------------------