From c610b784a210133ea384439a81a7679bb4060aa3 Mon Sep 17 00:00:00 2001 From: chriskiehl Date: Sun, 9 Nov 2014 18:07:43 -0500 Subject: [PATCH] Chagned from directly running python code, to executing a path via Popen to facilitate using Gooey with other languages. Add additional configration options to GUI (still in progress). First pass at project restructure to make things easier to find. --- gooey/TODO.txt | 12 +++- gooey/argparse_to_json.py | 3 +- gooey/gooey_decorator.py | 35 +++++++---- gooey/gui/chooser_runner.py | 6 +- gooey/gui/client_app.py | 6 -- gooey/gui/componenets2_runner.py | 3 +- gooey/gui/component_builder.py | 10 +-- gooey/gui/components.py | 4 +- gooey/gui/controller.py | 61 +++++++++++-------- gooey/gui/display_main.py | 7 ++- gooey/gui/message_event.py | 5 ++ gooey/gui/message_router.py | 19 ++++++ gooey/gui/widgets/__init__.py | 1 + gooey/gui/{ => widgets}/calender_dialog.py | 2 +- gooey/gui/{ => widgets}/choosers.py | 5 +- gooey/gui/{ => widgets}/components2.py | 34 ++++++----- gooey/gui/{ => widgets}/widget_pack.py | 10 ++- gooey/gui/windows/__init__.py | 1 + gooey/gui/{ => windows}/advanced_config.py | 18 ++++-- gooey/gui/{ => windows}/base_window.py | 42 ++++++++----- gooey/gui/{ => windows}/basic_config_panel.py | 0 gooey/gui/{ => windows}/footer.py | 2 +- gooey/gui/{ => windows}/header.py | 4 +- .../{ => windows}/runtime_display_panel.py | 9 ++- gooey/mockapplications/mockapp.py | 15 +++-- .../module_with_no_argparse.py | 2 +- gooey/tests/__init__.py | 1 + .../{gui => tests}/action_sorter_unittest.py | 0 .../advanced_config_unittest.py | 3 +- .../{ => tests}/argparse_to_json_unittest.py | 1 + gooey/{ => tests}/code_prep_unittest.py | 0 .../component_register_unittest.py | 0 gooey/{gui => tests}/components_unittest.py | 0 gooey/{ => tests}/i18n_unittest.py | 0 gooey/{ => tests}/modules_unittest.py | 0 .../{gui => tests}/option_reader_unittest.py | 0 gooey/{ => tests}/source_parser_unittest.py | 0 37 files changed, 210 insertions(+), 111 deletions(-) create mode 100644 gooey/gui/message_event.py create mode 100644 gooey/gui/message_router.py create mode 100644 gooey/gui/widgets/__init__.py rename gooey/gui/{ => widgets}/calender_dialog.py (94%) rename gooey/gui/{ => widgets}/choosers.py (93%) rename gooey/gui/{ => widgets}/components2.py (87%) rename gooey/gui/{ => widgets}/widget_pack.py (91%) create mode 100644 gooey/gui/windows/__init__.py rename gooey/gui/{ => windows}/advanced_config.py (83%) rename gooey/gui/{ => windows}/base_window.py (70%) rename gooey/gui/{ => windows}/basic_config_panel.py (100%) rename gooey/gui/{ => windows}/footer.py (95%) rename gooey/gui/{ => windows}/header.py (94%) rename gooey/gui/{ => windows}/runtime_display_panel.py (86%) create mode 100644 gooey/tests/__init__.py rename gooey/{gui => tests}/action_sorter_unittest.py (100%) rename gooey/{gui => tests}/advanced_config_unittest.py (89%) rename gooey/{ => tests}/argparse_to_json_unittest.py (97%) rename gooey/{ => tests}/code_prep_unittest.py (100%) rename gooey/{gui => tests}/component_register_unittest.py (100%) rename gooey/{gui => tests}/components_unittest.py (100%) rename gooey/{ => tests}/i18n_unittest.py (100%) rename gooey/{ => tests}/modules_unittest.py (100%) rename gooey/{gui => tests}/option_reader_unittest.py (100%) rename gooey/{ => tests}/source_parser_unittest.py (100%) diff --git a/gooey/TODO.txt b/gooey/TODO.txt index 3ef0b4d..c60df19 100644 --- a/gooey/TODO.txt +++ b/gooey/TODO.txt @@ -15,7 +15,17 @@ Restart Button Change: - add optional cancel button. - allow NoConfig to run without argparse (Issue #43) - display warning when this happens (could be a misfire on Gooey's end) - - add suppress warnings flag + - add suppress warnings flag + + +- Meta Info + - Program Name + - Program Description + - Client Program + - Desired Size + - Desired Columns (required) + - Desired Columns (optional) + diff --git a/gooey/argparse_to_json.py b/gooey/argparse_to_json.py index 270e3c9..5ee5407 100644 --- a/gooey/argparse_to_json.py +++ b/gooey/argparse_to_json.py @@ -142,13 +142,12 @@ def get_counter_style_optionals(actions): for action in actions if isinstance(action, _CountAction)] - _json_options = [as_json(action, default_widget='Dropdown') + _json_options = [as_json(action, default_widget='Counter') for action in filtered_actions] # Counter should show as Dropdowns, so pre-populare with numeric choices for opt in _json_options: opt['choices'] = range(10) - return _json_options diff --git a/gooey/gooey_decorator.py b/gooey/gooey_decorator.py index e8fd174..770536e 100644 --- a/gooey/gooey_decorator.py +++ b/gooey/gooey_decorator.py @@ -45,15 +45,13 @@ done. from functools import partial import wx -from gooey import argparse_to_json -from gooey.gui.component_factory import ComponentFactory +from gooey import argparse_to_json import i18n -import i18n_config import source_parser def Gooey(f=None, advanced=True, - language='english', config=True, + language='english', show_config=True, program_name=None, program_description=None): ''' Decorator for client code's main function. @@ -61,11 +59,13 @@ def Gooey(f=None, advanced=True, Scans the client code for argparse data. If found, extracts it and build the proper - configuration gui window (basic or advanced). + configuration gui windows (basic or advanced). ''' params = locals() + + def build(payload): def inner(): module_path = get_caller_path() @@ -78,15 +78,26 @@ def Gooey(f=None, advanced=True, # load gui components after loading the language pack from gooey.gui.client_app import ClientApp from gooey.gui.client_app import EmptyClientApp - from gooey.gui.base_window import BaseWindow - from gooey.gui.advanced_config import AdvancedConfigPanel - from gooey.gui.basic_config_panel import BasicConfigPanel + from gooey.gui.windows.base_window import BaseWindow + from gooey.gui.windows.advanced_config import AdvancedConfigPanel + from gooey.gui.windows.basic_config_panel import BasicConfigPanel - if config: + if show_config: parser = get_parser(module_path) + + meta = { + 'target': get_caller_path(), + 'program_name': program_name, + 'program_description': program_description or parser.description, + 'show_config': show_config, + 'show_advanced': advanced, + 'default_size': (610, 530), + 'requireds_cols': 1, + 'optionals_cols': 2 + } client_app = ClientApp(parser, payload) - build_spec = argparse_to_json.convert(parser) + build_spec = dict(meta.items() + argparse_to_json.convert(parser).items()) if advanced: BodyPanel = partial(AdvancedConfigPanel, build_spec=build_spec) @@ -98,9 +109,9 @@ def Gooey(f=None, advanced=True, BodyPanel = BasicConfigPanel client_app = EmptyClientApp(payload) - frame = BaseWindow(BodyPanel, client_app, params) + frame = BaseWindow(BodyPanel, build_spec, params) - if not config: + if not show_config: frame.ManualStart() frame.Show(True) app.MainLoop() diff --git a/gooey/gui/chooser_runner.py b/gooey/gui/chooser_runner.py index 3744a63..470512c 100644 --- a/gooey/gui/chooser_runner.py +++ b/gooey/gui/chooser_runner.py @@ -1,9 +1,9 @@ __author__ = 'Chris' - import wx -from wx.lib import wordwrap -from choosers import FileChooser, DirectoryChooser, CalendarChooser + +from gooey.gui.widgets.choosers import CalendarChooser + class MyFrame(wx.Frame): def __init__(self, parent): diff --git a/gooey/gui/client_app.py b/gooey/gui/client_app.py index 4130e8e..447060f 100644 --- a/gooey/gui/client_app.py +++ b/gooey/gui/client_app.py @@ -63,9 +63,3 @@ class EmptyClientApp(object): if __name__ == '__main__': pass - -# print m2 - - - - diff --git a/gooey/gui/componenets2_runner.py b/gooey/gui/componenets2_runner.py index 5ddd100..73f0434 100644 --- a/gooey/gui/componenets2_runner.py +++ b/gooey/gui/componenets2_runner.py @@ -9,12 +9,13 @@ class TestPanel(ScrolledPanel): ScrolledPanel.__init__(self, parent) self.SetupScrolling(scroll_x=False) - self.textctrls = [wx.TextCtrl(self) for _ in range(4)] + self.textctrls = [wx.TextCtrl(self) for _ in range(1)] sizer = wx.BoxSizer(wx.VERTICAL) hsizer = wx.BoxSizer(wx.HORIZONTAL) for textctrl in self.textctrls: hsizer.Add(textctrl, 1, wx.EXPAND) + textctrl.SetMinSize((10,23)) sizer.Add(hsizer, 0, wx.EXPAND) self.SetSizer(sizer) diff --git a/gooey/gui/component_builder.py b/gooey/gui/component_builder.py index 4cb1bbf..45d5daf 100644 --- a/gooey/gui/component_builder.py +++ b/gooey/gui/component_builder.py @@ -1,5 +1,6 @@ import itertools -from gooey.gui import components2 + +from gooey.gui.widgets import components2 class ComponentBuilder(object): @@ -9,6 +10,7 @@ class ComponentBuilder(object): _optional_specs = self.build_spec.get('optional', None) self.required_args = self.build_widget(_required_specs) if _required_specs else None + optionals = self.build_widget(_optional_specs) if _optional_specs else None if _optional_specs: self.flags = [widget for widget in optionals if isinstance(widget, components2.CheckBox)] @@ -32,7 +34,7 @@ class ComponentBuilder(object): ''' return an iterator for all of the contained gui ''' - return itertools.chain(self.required_args, - self.flags, - self.general_options) + return itertools.chain(self.required_args or [], + self.flags or [], + self.general_options or []) diff --git a/gooey/gui/components.py b/gooey/gui/components.py index 8d80e40..ef54999 100644 --- a/gooey/gui/components.py +++ b/gooey/gui/components.py @@ -113,7 +113,7 @@ class AbstractGuiComponent(object): Content area is based on each grid having two equally sized columns, where the content area is defined as 87% of the halved - window width. The wiggle room is the distance +- 10% of the + windows width. The wiggle room is the distance +- 10% of the content_area. Wrap calculation is run only when the size of the help_msg @@ -229,7 +229,7 @@ class AbstractComponent(object): Content area is based on each grid having two equally sized columns, where the content area is defined as 87% of the halved - window width. The wiggle room is the distance +- 10% of the + windows width. The wiggle room is the distance +- 10% of the content_area. Wrap calculation is run only when the size of the help_msg diff --git a/gooey/gui/controller.py b/gooey/gui/controller.py index b712b5c..f01cebc 100644 --- a/gooey/gui/controller.py +++ b/gooey/gui/controller.py @@ -3,6 +3,7 @@ Created on Dec 22, 2013 @author: Chris ''' +import subprocess import wx import sys @@ -31,9 +32,8 @@ class Controller(object): translator = instance of the I18N class ''' - def __init__(self, base_frame, client_app): - self._base = base_frame - self._client_app = client_app + def __init__(self, base_frame): + self.core_gui = base_frame # self._payload_runner = Process(target=self.RunClientCode) def OnCancelButton(self, widget, event): @@ -43,42 +43,55 @@ class Controller(object): print result if result == YES: dlg.Destroy() - self._base.Destroy() + self.core_gui.Destroy() sys.exit() dlg.Destroy() def OnStartButton(self, widget, event): - if len(sys.argv) < 2: - cmd_line_args = self._base.GetOptions() - if not self._client_app.IsValidArgString(cmd_line_args): - error_msg = self._client_app.GetErrorMsg(cmd_line_args) - self.ShowDialog(i18n.translate('error_title'), error_msg, wx.ICON_ERROR) - return - self._client_app.AddToArgv(cmd_line_args) - self._base.NextPage() - Process(target=self.RunClientCode).start() + cmd_line_args = self.core_gui.GetOptions() + + _required = self.core_gui.GetRequiredArgs() + if _required and any(req == '' for req in _required): + self.ShowDialog(i18n.translate('error_title'), "Must fill in all fields in the Required section!", wx.ICON_ERROR) + return + + self.core_gui.NextPage() + self.RunClientCode(None) + + def RunClientCode(self, process): + def doInBackground(process, callback): + while True: + line = process.stdout.readline() + if not line: + break + self.core_gui.PublishConsoleMsg(line) + callback(process) + + p = subprocess.Popen(r'python C:\Users\Chris\Desktop\Untitled\prog.py', bufsize=1, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + _pool = Pool(1) + _pool.apply_async(doInBackground, (p, self.HandleResult)) + + def HandleResult(self, process): + _stdout, _stderr = process.communicate() + if process.returncode == 0: + self.core_gui.NextPage() + self.ShowGoodFinishedDialog() + else: + self.core_gui.NextPage() + self.ShowBadFinishedDialog(_stderr) def OnRestartButton(self, widget, event): self.OnStartButton(self, None, event) def ManualStart(self): - self._base.NextPage() + self.core_gui.NextPage() wx.CallAfter(wx.ActivateEvent) Process(target=self.RunClientCode).start() def OnCloseButton(self, widget, event): - self._base.Destroy() + self.core_gui.Destroy() sys.exit() - def RunClientCode(self): - _pool = Pool(1) - try: - _pool.apply(self._client_app.payload) - self._base.NextPage() - self.ShowGoodFinishedDialog() - except: - self.ShowBadFinishedDialog(traceback.format_exc()) - def ShowGoodFinishedDialog(self): self.ShowDialog(i18n.translate("execution_finished"), i18n.translate('success_message'), diff --git a/gooey/gui/display_main.py b/gooey/gui/display_main.py index 6aaa7a0..4749b2d 100644 --- a/gooey/gui/display_main.py +++ b/gooey/gui/display_main.py @@ -15,6 +15,7 @@ from app.images import image_store from app.dialogs.header import FrameHeader from app.dialogs.basic_config_panel import RuntimeDisplay from app.dialogs.footer import Footer +from gooey.gui.message_event import EVT_MSG class MessagePump(object): @@ -89,6 +90,8 @@ class MainWindow(wx.Frame): sizer.Add(self.foot_panel, 0, wx.EXPAND) self.SetSizer(sizer) + self.Bind(EVT_MSG, self.OnMsg) + def _init_panels(self): self._frame_header = FrameHeader self._basic_config_body = None @@ -100,7 +103,9 @@ class MainWindow(wx.Frame): line = wx.StaticLine(self, -1, style=wx.LI_HORIZONTAL) line.SetSize((10, 10)) sizer.Add(line, 0, wx.EXPAND) - + + + diff --git a/gooey/gui/message_event.py b/gooey/gui/message_event.py new file mode 100644 index 0000000..46493c0 --- /dev/null +++ b/gooey/gui/message_event.py @@ -0,0 +1,5 @@ +import wx +import wx.lib.newevent + +MessageEvent, EVT_MSG = wx.lib.newevent.NewEvent() + diff --git a/gooey/gui/message_router.py b/gooey/gui/message_router.py new file mode 100644 index 0000000..c6ad679 --- /dev/null +++ b/gooey/gui/message_router.py @@ -0,0 +1,19 @@ +import threading + +__author__ = 'Chris' + + +class MessageRouter(threading.Thread): + def __init__(self, textbox, process_to_route): + threading.Thread.__init__(self) + self.textbox = textbox + self.process = process_to_route + + def run(self): + while True: + line = self.process.stdout.readline() + if not line: + break + + + diff --git a/gooey/gui/widgets/__init__.py b/gooey/gui/widgets/__init__.py new file mode 100644 index 0000000..6bca6f6 --- /dev/null +++ b/gooey/gui/widgets/__init__.py @@ -0,0 +1 @@ +__author__ = 'Chris' diff --git a/gooey/gui/calender_dialog.py b/gooey/gui/widgets/calender_dialog.py similarity index 94% rename from gooey/gui/calender_dialog.py rename to gooey/gui/widgets/calender_dialog.py index 9c1f681..b255778 100644 --- a/gooey/gui/calender_dialog.py +++ b/gooey/gui/widgets/calender_dialog.py @@ -1,7 +1,7 @@ __author__ = 'Chris' import wx -import styling +from gooey.gui import styling class CalendarDlg(wx.Dialog): diff --git a/gooey/gui/choosers.py b/gooey/gui/widgets/choosers.py similarity index 93% rename from gooey/gui/choosers.py rename to gooey/gui/widgets/choosers.py index 968fe5a..6bd0f19 100644 --- a/gooey/gui/choosers.py +++ b/gooey/gui/widgets/choosers.py @@ -1,8 +1,9 @@ __author__ = 'Chris' import wx -import styling -from calender_dialog import CalendarDlg + +from gooey.gui import styling +from gooey.gui.widgets.calender_dialog import CalendarDlg class AbstractChooser(object): diff --git a/gooey/gui/components2.py b/gooey/gui/widgets/components2.py similarity index 87% rename from gooey/gui/components2.py rename to gooey/gui/widgets/components2.py index 33ea030..3682db6 100644 --- a/gooey/gui/components2.py +++ b/gooey/gui/widgets/components2.py @@ -1,9 +1,10 @@ +from gooey.gui.widgets import widget_pack + __author__ = 'Chris' import wx -import styling +from gooey.gui import styling -import widget_pack class BaseGuiComponent(object): def __init__(self, data, widget_pack): @@ -27,6 +28,7 @@ class BaseGuiComponent(object): self.title = self.createTitle(self.panel) self.help_msg = self.createHelpMsgWidget(self.panel) + self.help_msg.SetMinSize((0, -1)) core_widget_set = self.widget_pack.build(self.panel, self.data) vertical_container = wx.BoxSizer(wx.VERTICAL) @@ -79,20 +81,20 @@ class BaseGuiComponent(object): if not self.help_msg: return self.panel.Size = evt.GetSize() - print 'Component Panel Size:', self.panel.Size + # print 'Component Panel Size:', self.panel.Size container_width, _ = self.panel.Size # if 'filename' in self.data['display_name']: # print 'Container Width:', container_width, '-', self.data['display_name'] text_width, _ = self.help_msg.Size - print 'container width:', container_width - print 'text width', text_width + # print 'container width:', container_width + # print 'text width', text_width if text_width != container_width: self.help_msg.SetLabel(self.help_msg.GetLabelText().replace('\n', ' ')) self.help_msg.Wrap(container_width) evt.Skip() - def getValue(self): + def GetValue(self): return self.widget_pack.getValue() @@ -101,7 +103,7 @@ class CheckBox(BaseGuiComponent): BaseGuiComponent.__init__(self, data, widget_pack) self.widget = None - print data + # data self.option_strings = data['commands'][0] def build(self, parent): @@ -113,6 +115,7 @@ class CheckBox(BaseGuiComponent): self.widget = wx.CheckBox(self.panel) self.title = self.createTitle(self.panel) self.help_msg = self.createHelpMsgWidget(self.panel) + self.help_msg.SetMinSize((0, -1)) vertical_container = wx.BoxSizer(wx.VERTICAL) vertical_container.Add(self.title) @@ -132,7 +135,6 @@ class CheckBox(BaseGuiComponent): def onResize(self, evt): msg = self.help_msg - print 'thing:', self.data['display_name'] container_width, _ = self.panel.Size text_width, _ = msg.Size @@ -141,8 +143,8 @@ class CheckBox(BaseGuiComponent): msg.Wrap(container_width) evt.Skip() - def getValue(self): - return + def GetValue(self): + return self.option_strings[0] if self.widget.GetValue() else '' class RadioGroup(object): @@ -182,7 +184,7 @@ class RadioGroup(object): vertical_container.Add(help, 1, wx.EXPAND | wx.LEFT, 25) vertical_container.AddSpacer(5) - self.panel.Bind(wx.EVT_RADIOBUTTON, self.onSetter, button) + # self.panel.Bind(wx.EVT_RADIOBUTTON, self.onSetter, button) self.panel.SetSizer(vertical_container) self.panel.Bind(wx.EVT_SIZE, self.onResize) @@ -201,10 +203,14 @@ class RadioGroup(object): msg.Wrap(container_width) evt.Skip() - def getValue(self): + def GetValue(self): vals = [button.GetValue() for button in self.radio_buttons] - print self.option_stings[vals.index(True)] - return self.option_stings[vals.index(True)] + # print self.option_stings[vals.index(True)] + try: + opts = self.option_stings[vals.index(True)][0] + print opts + except: + return '' diff --git a/gooey/gui/widget_pack.py b/gooey/gui/widgets/widget_pack.py similarity index 91% rename from gooey/gui/widget_pack.py rename to gooey/gui/widgets/widget_pack.py index cbb2742..2eabb9c 100644 --- a/gooey/gui/widget_pack.py +++ b/gooey/gui/widgets/widget_pack.py @@ -2,9 +2,11 @@ __author__ = 'Chris' -import wx from abc import ABCMeta, abstractmethod -from calender_dialog import CalendarDlg + +import wx + +from gooey.gui.widgets.calender_dialog import CalendarDlg class WidgetPack(object): @@ -38,6 +40,7 @@ class BaseChooser(WidgetPack): def build(self, parent, data=None): self.parent = parent self.text_box = wx.TextCtrl(self.parent) + self.text_box.SetMinSize((0, -1)) self.button = wx.Button(self.parent, label=self.button_text, size=(73, 23)) widget_sizer = wx.BoxSizer(wx.HORIZONTAL) @@ -100,6 +103,7 @@ class TextInputPayload(WidgetPack): def build(self, parent, data): self.widget = wx.TextCtrl(parent) + self.widget.SetMinSize((0, -1)) return self.widget def getValue(self): @@ -135,7 +139,7 @@ class CounterPayload(WidgetPack): self.widget = None def build(self, parent, data): - self.option_string = data['option_strings'][0] + self.option_string = data['commands'][0] self.widget = wx.ComboBox( parent=parent, id=-1, diff --git a/gooey/gui/windows/__init__.py b/gooey/gui/windows/__init__.py new file mode 100644 index 0000000..6bca6f6 --- /dev/null +++ b/gooey/gui/windows/__init__.py @@ -0,0 +1 @@ +__author__ = 'Chris' diff --git a/gooey/gui/advanced_config.py b/gooey/gui/windows/advanced_config.py similarity index 83% rename from gooey/gui/advanced_config.py rename to gooey/gui/windows/advanced_config.py index 7025212..4c5a2f2 100644 --- a/gooey/gui/advanced_config.py +++ b/gooey/gui/windows/advanced_config.py @@ -3,15 +3,15 @@ Created on Dec 28, 2013 @author: Chris """ +from itertools import chain import wx from wx.lib.scrolledpanel import ScrolledPanel from gooey import i18n from gooey.gui import component_builder -from gooey.gui.component_factory import ComponentFactory from gooey.gui.option_reader import OptionReader -import styling +from gooey.gui import styling PADDING = 10 @@ -22,7 +22,7 @@ class AdvancedConfigPanel(ScrolledPanel, OptionReader): def __init__(self, parent, build_spec=None, **kwargs): ScrolledPanel.__init__(self, parent, **kwargs) - self.SetupScrolling() + self.SetupScrolling(scroll_x=False, scrollToTop=False) self._action_groups = build_spec self._positionals = build_spec.get('required', None) @@ -65,8 +65,8 @@ class AdvancedConfigPanel(ScrolledPanel, OptionReader): container.Add(styling.HorizontalRule(self), *STD_LAYOUT) container.AddSpacer(20) - # self.CreateComponentGrid(container, self.components.flags, cols=3) self.CreateComponentGrid(container, self.components.general_options, cols=2) + self.CreateComponentGrid(container, self.components.flags, cols=3) # container.Add(general_opts_grid, *STD_LAYOUT) # container.AddSpacer(30) # container.Add(flag_grids, 0, wx.LEFT | wx.RIGHT | wx.EXPAND, PADDING) @@ -93,7 +93,7 @@ class AdvancedConfigPanel(ScrolledPanel, OptionReader): def OnResize(self, evt): for component in self.components: component.onResize(evt) - self.SetupScrolling() + self.SetupScrolling(scroll_x=False, scrollToTop=False) evt.Skip() def RegisterController(self, controller): @@ -107,8 +107,16 @@ class AdvancedConfigPanel(ScrolledPanel, OptionReader): values = [c.GetValue() for c in self.components if c.GetValue() is not None] + print values return ' '.join(values) + def GetRequiredArgs(self): + return [arg.GetValue() for arg in self.components.required_args] + + def GetOptionalArgs(self): + return [arg.GetValue() for arg in + chain(self.components.general_options, self.components.flags)] + if __name__ == '__main__': pass diff --git a/gooey/gui/base_window.py b/gooey/gui/windows/base_window.py similarity index 70% rename from gooey/gui/base_window.py rename to gooey/gui/windows/base_window.py index 0c81fdb..e3c0ee3 100644 --- a/gooey/gui/base_window.py +++ b/gooey/gui/windows/base_window.py @@ -4,24 +4,26 @@ Created on Jan 19, 2014 ''' import os -import wx import sys -import header +import wx + +from gooey.gui.message_event import MessageEvent from gooey import i18n -from gooey.gui import footer from gooey import image_repository from gooey.gui.controller import Controller -from gooey.gui.runtime_display_panel import RuntimeDisplay -import styling +from gooey.gui.message_router import MessageRouter +from gooey.gui.windows.runtime_display_panel import RuntimeDisplay +from gooey.gui import styling +from gooey.gui.windows import footer, header class BaseWindow(wx.Frame): - def __init__(self, BodyPanel, client_app, params): + def __init__(self, BodyPanel, build_spec, params): wx.Frame.__init__(self, parent=None, id=-1) self._params = params - self._client_app = client_app + self.build_spec = build_spec self._controller = None @@ -40,21 +42,20 @@ class BaseWindow(wx.Frame): self.registerControllers() self.Bind(wx.EVT_SIZE, self.onResize) - def _init_properties(self): if not self._params['program_name']: title = os.path.basename(sys.argv[0].replace('.py', '')) else: title = self._params['program_name'] self.SetTitle(title) - self.SetSize((610, 530)) + self.SetSize(self.build_spec['default_size']) # self.SetMinSize((400, 300)) self.icon = wx.Icon(image_repository.icon, wx.BITMAP_TYPE_ICO) self.SetIcon(self.icon) def _init_components(self, BodyPanel): # init gui - _desc = self._client_app.description + _desc = self.build_spec['program_description'] self.head_panel = header.FrameHeader( heading=i18n.translate("settings_title"), subheading=_desc if _desc is not None else '', @@ -76,9 +77,7 @@ class BaseWindow(wx.Frame): self.SetSizer(sizer) def _init_controller(self): - self._controller = Controller( - base_frame=self, - client_app=self._client_app) + self._controller = Controller(base_frame=self) def registerControllers(self): for panel in self.panels: @@ -87,6 +86,13 @@ class BaseWindow(wx.Frame): def GetOptions(self): return self.config_panel.GetOptions() + def GetRequiredArgs(self): + return self.config_panel.GetRequiredArgs() + + def GetOptionalArgs(self): + return self.config_panel.GetOptionalArgs() + + def NextPage(self): self.head_panel.NextPage() self.foot_panel.NextPage() @@ -101,8 +107,16 @@ class BaseWindow(wx.Frame): self._controller.ManualStart() def onResize(self, evt): - print self.Size + self.Freeze() + # print self.Size evt.Skip() + self.Thaw() + + def PublishConsoleMsg(self, text): + self.runtime_display.cmd_textbox.AppendText(text) + # evt = MessageEvent(message=text) + # self.GetEventHandler().ProcessEvent(evt) + # wx.PostEvent(self.runtime_display, evt) if __name__ == '__main__': diff --git a/gooey/gui/basic_config_panel.py b/gooey/gui/windows/basic_config_panel.py similarity index 100% rename from gooey/gui/basic_config_panel.py rename to gooey/gui/windows/basic_config_panel.py diff --git a/gooey/gui/footer.py b/gooey/gui/windows/footer.py similarity index 95% rename from gooey/gui/footer.py rename to gooey/gui/windows/footer.py index 7e34ba6..17b40e6 100644 --- a/gooey/gui/footer.py +++ b/gooey/gui/windows/footer.py @@ -128,7 +128,7 @@ class Footer(AbstractFooter): screen of the application args: - parent: wxPython parent window + parent: wxPython parent windows controller: controller class used in delagating all the commands ''' diff --git a/gooey/gui/header.py b/gooey/gui/windows/header.py similarity index 94% rename from gooey/gui/header.py rename to gooey/gui/windows/header.py index 68b4656..998d6c9 100644 --- a/gooey/gui/header.py +++ b/gooey/gui/windows/header.py @@ -10,7 +10,7 @@ import wx from gooey import i18n from gooey.gui import imageutil from gooey import image_repository -import styling +from gooey.gui import styling PAD_SIZE = 10 @@ -101,4 +101,4 @@ class FrameHeader(wx.Panel): next(self._pages)() except: self._init_pages() - next(self._pages)() \ No newline at end of file + next(self._pages)() diff --git a/gooey/gui/runtime_display_panel.py b/gooey/gui/windows/runtime_display_panel.py similarity index 86% rename from gooey/gui/runtime_display_panel.py rename to gooey/gui/windows/runtime_display_panel.py index 8c9d0df..43f8831 100644 --- a/gooey/gui/runtime_display_panel.py +++ b/gooey/gui/windows/runtime_display_panel.py @@ -8,6 +8,7 @@ import sys import wx from gooey import i18n +from gooey.gui.message_event import EVT_MSG class MessagePump(object): @@ -47,6 +48,8 @@ class RuntimeDisplay(wx.Panel): sizer.AddSpacer(20) self.SetSizer(sizer) + self.Bind(EVT_MSG, self.OnMsg) + def _HookStdout(self): _stdout = sys.stdout _stdout_write = _stdout.write @@ -60,5 +63,7 @@ class RuntimeDisplay(wx.Panel): def WriteToDisplayBox(self, txt): if txt is not '': self.AppendText(txt) - - + + def OnMsg(self, evt): + print 'It workded!!' + print locals() diff --git a/gooey/mockapplications/mockapp.py b/gooey/mockapplications/mockapp.py index cefa8aa..d008245 100644 --- a/gooey/mockapplications/mockapp.py +++ b/gooey/mockapplications/mockapp.py @@ -19,17 +19,17 @@ def main(): my_cool_parser = ArgumentParser(description=desc) my_cool_parser.add_argument("filename", help=file_help_msg) # positional my_cool_parser.add_argument("outfile", help="Name of the file where you'll save the output") # positional - my_cool_parser.add_argument('-c', '--countdown', default=10, type=int, help='sets the time to count down from') - # my_cool_parser.add_argument("-s", "--showtime", action="store_true", help="display the countdown timer") - # my_cool_parser.add_argument("-d", "--delay", action="store_true", help="Delay execution for a bit") - my_cool_parser.add_argument('--verbose', '-v', action='count') + my_cool_parser.add_argument('-c', '--countdown', default=10, type=int, help='sets the time to count down from you see its quite simple!') + my_cool_parser.add_argument("-s", "--showtime", action="store_true", help="display the countdown timer") + my_cool_parser.add_argument("-d", "--delay", action="store_true", help="Delay execution for a bit") + my_cool_parser.add_argument('-v', '--verbose', action='count') # my_cool_parser.add_argument("-o", "--obfuscate", action="store_true", help="obfuscate the countdown timer!") my_cool_parser.add_argument('-r', '--recursive', choices=['yes', 'no'], help='Recurse into subfolders') # my_cool_parser.add_argument("-w", "--writelog", default="No, NOT whatevs", help="write log to some file or something") # my_cool_parser.add_argument("-e", "--expandAll", action="store_true", help="expand all processes") - # verbosity = my_cool_parser.add_mutually_exclusive_group() - # verbosity.add_argument('-t', '--verbozze', dest='verbose', action="store_true", help="Show more details") - # verbosity.add_argument('-q', '--quiet', dest='quiet', action="store_true", help="Only output on error") + verbosity = my_cool_parser.add_mutually_exclusive_group() + verbosity.add_argument('-t', '--verbozze', dest='verbose', action="store_true", help="Show more details") + verbosity.add_argument('-q', '--quiet', dest='quiet', action="store_true", help="Only output on error") print 'inside of main(), my_cool_parser =', my_cool_parser args = my_cool_parser.parse_args() @@ -51,7 +51,6 @@ def main(): # raise ValueError("Something has gone wrong! AHHHHHHHHHHH") if __name__ == '__main__': - sys.argv.extend('asdf -c 5 -s'.split()) print sys.argv main() # import inspect diff --git a/gooey/mockapplications/module_with_no_argparse.py b/gooey/mockapplications/module_with_no_argparse.py index 42468e6..6bf5a17 100644 --- a/gooey/mockapplications/module_with_no_argparse.py +++ b/gooey/mockapplications/module_with_no_argparse.py @@ -6,7 +6,7 @@ Created on Feb 2, 2014 import time from gooey import Gooey -@Gooey(config=False) +@Gooey(show_config=False) def main(): end = time.time() + 1 while end > time.time(): diff --git a/gooey/tests/__init__.py b/gooey/tests/__init__.py new file mode 100644 index 0000000..6bca6f6 --- /dev/null +++ b/gooey/tests/__init__.py @@ -0,0 +1 @@ +__author__ = 'Chris' diff --git a/gooey/gui/action_sorter_unittest.py b/gooey/tests/action_sorter_unittest.py similarity index 100% rename from gooey/gui/action_sorter_unittest.py rename to gooey/tests/action_sorter_unittest.py diff --git a/gooey/gui/advanced_config_unittest.py b/gooey/tests/advanced_config_unittest.py similarity index 89% rename from gooey/gui/advanced_config_unittest.py rename to gooey/tests/advanced_config_unittest.py index ca39f7b..04718a7 100644 --- a/gooey/gui/advanced_config_unittest.py +++ b/gooey/tests/advanced_config_unittest.py @@ -10,9 +10,9 @@ import unittest import wx -import advanced_config from gooey.gui.client_app import ClientApp from gooey.gui import argparse_test_data +from gooey.gui.windows import advanced_config class TestAdvancedConfigPanel(unittest.TestCase): @@ -44,4 +44,3 @@ if __name__ == "__main__": - \ No newline at end of file diff --git a/gooey/argparse_to_json_unittest.py b/gooey/tests/argparse_to_json_unittest.py similarity index 97% rename from gooey/argparse_to_json_unittest.py rename to gooey/tests/argparse_to_json_unittest.py index 18ca708..539d3d6 100644 --- a/gooey/argparse_to_json_unittest.py +++ b/gooey/tests/argparse_to_json_unittest.py @@ -44,6 +44,7 @@ class TestArgparseToJson(unittest.TestCase): def test_get_counter_style_optionals(self): target_arg = self.find_arg_by_option(self.base_actions, '--verbose') json_result = get_counter_style_optionals(self.base_actions) + print json_result self._test_parser_to_json_mapping(target_arg, json_result[0], 'Dropdown') def test_get_mutually_exclusive_optionals(self): diff --git a/gooey/code_prep_unittest.py b/gooey/tests/code_prep_unittest.py similarity index 100% rename from gooey/code_prep_unittest.py rename to gooey/tests/code_prep_unittest.py diff --git a/gooey/gui/component_register_unittest.py b/gooey/tests/component_register_unittest.py similarity index 100% rename from gooey/gui/component_register_unittest.py rename to gooey/tests/component_register_unittest.py diff --git a/gooey/gui/components_unittest.py b/gooey/tests/components_unittest.py similarity index 100% rename from gooey/gui/components_unittest.py rename to gooey/tests/components_unittest.py diff --git a/gooey/i18n_unittest.py b/gooey/tests/i18n_unittest.py similarity index 100% rename from gooey/i18n_unittest.py rename to gooey/tests/i18n_unittest.py diff --git a/gooey/modules_unittest.py b/gooey/tests/modules_unittest.py similarity index 100% rename from gooey/modules_unittest.py rename to gooey/tests/modules_unittest.py diff --git a/gooey/gui/option_reader_unittest.py b/gooey/tests/option_reader_unittest.py similarity index 100% rename from gooey/gui/option_reader_unittest.py rename to gooey/tests/option_reader_unittest.py diff --git a/gooey/source_parser_unittest.py b/gooey/tests/source_parser_unittest.py similarity index 100% rename from gooey/source_parser_unittest.py rename to gooey/tests/source_parser_unittest.py