code review
This commit is contained in:
parent
9741fc36e3
commit
360e1de5d9
@ -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))
|
||||
|
375
trunk/opal.py
375
trunk/opal.py
@ -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
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Форма с выбором модели из представленного списка
|
||||
#-----------------------------------------------------------------------------
|
||||
|
Loading…
Reference in New Issue
Block a user